]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Sync with 2.17.3
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Wed, 4 Dec 2019 21:21:20 +0000 (22:21 +0100)
committerJohannes Schindelin <johannes.schindelin@gmx.de>
Fri, 6 Dec 2019 15:29:15 +0000 (16:29 +0100)
* maint-2.17: (32 commits)
  Git 2.17.3
  Git 2.16.6
  test-drop-caches: use `has_dos_drive_prefix()`
  Git 2.15.4
  Git 2.14.6
  mingw: handle `subst`-ed "DOS drives"
  mingw: refuse to access paths with trailing spaces or periods
  mingw: refuse to access paths with illegal characters
  unpack-trees: let merged_entry() pass through do_add_entry()'s errors
  quote-stress-test: offer to test quoting arguments for MSYS2 sh
  t6130/t9350: prepare for stringent Win32 path validation
  quote-stress-test: allow skipping some trials
  quote-stress-test: accept arguments to test via the command-line
  tests: add a helper to stress test argument quoting
  mingw: fix quoting of arguments
  Disallow dubiously-nested submodule git directories
  protect_ntfs: turn on NTFS protection by default
  path: also guard `.gitmodules` against NTFS Alternate Data Streams
  is_ntfs_dotgit(): speed it up
  mingw: disallow backslash characters in tree objects' file names
  ...

742 files changed:
.gitattributes
.gitignore
.mailmap
.travis.yml
Documentation/Makefile
Documentation/RelNotes/1.7.11.7.txt
Documentation/RelNotes/2.17.0.txt
Documentation/RelNotes/2.18.0.txt [new file with mode: 0644]
Documentation/RelNotes/2.18.1.txt [new file with mode: 0644]
Documentation/SubmittingPatches
Documentation/config.txt
Documentation/diff-config.txt
Documentation/diff-options.txt
Documentation/fetch-options.txt
Documentation/git-add.txt
Documentation/git-annotate.txt
Documentation/git-apply.txt
Documentation/git-bisect.txt
Documentation/git-branch.txt
Documentation/git-bundle.txt
Documentation/git-check-attr.txt
Documentation/git-check-ignore.txt
Documentation/git-check-mailmap.txt
Documentation/git-clone.txt
Documentation/git-commit-graph.txt [new file with mode: 0644]
Documentation/git-config.txt
Documentation/git-credential-cache.txt
Documentation/git-credential-store.txt
Documentation/git-cvsserver.txt
Documentation/git-diff-index.txt
Documentation/git-diff-tree.txt
Documentation/git-diff.txt
Documentation/git-fast-export.txt
Documentation/git-fast-import.txt
Documentation/git-fetch-pack.txt
Documentation/git-filter-branch.txt
Documentation/git-fmt-merge-msg.txt
Documentation/git-for-each-ref.txt
Documentation/git-format-patch.txt
Documentation/git-gc.txt
Documentation/git-grep.txt
Documentation/git-help.txt
Documentation/git-http-fetch.txt
Documentation/git-http-push.txt
Documentation/git-imap-send.txt
Documentation/git-index-pack.txt
Documentation/git-interpret-trailers.txt
Documentation/git-log.txt
Documentation/git-ls-files.txt
Documentation/git-ls-remote.txt
Documentation/git-merge.txt
Documentation/git-mktree.txt
Documentation/git-name-rev.txt
Documentation/git-p4.txt
Documentation/git-pack-objects.txt
Documentation/git-prune.txt
Documentation/git-pull.txt
Documentation/git-push.txt
Documentation/git-read-tree.txt
Documentation/git-rebase.txt
Documentation/git-receive-pack.txt
Documentation/git-remote-ext.txt
Documentation/git-remote.txt
Documentation/git-repack.txt
Documentation/git-replace.txt
Documentation/git-request-pull.txt
Documentation/git-rev-parse.txt
Documentation/git-send-email.txt
Documentation/git-send-pack.txt
Documentation/git-shell.txt
Documentation/git-shortlog.txt
Documentation/git-show-branch.txt
Documentation/git-show-ref.txt
Documentation/git-show.txt
Documentation/git-status.txt
Documentation/git-submodule.txt
Documentation/git-svn.txt
Documentation/git-tag.txt
Documentation/git-update-index.txt
Documentation/git-update-ref.txt
Documentation/git-var.txt
Documentation/git-web--browse.txt
Documentation/git-worktree.txt
Documentation/git.txt
Documentation/gitattributes.txt
Documentation/gitcli.txt
Documentation/githooks.txt
Documentation/gitk.txt
Documentation/gitmodules.txt
Documentation/gitremote-helpers.txt
Documentation/gitrepository-layout.txt
Documentation/gitrevisions.txt
Documentation/gitworkflows.txt
Documentation/glossary-content.txt
Documentation/howto/recover-corrupted-object-harder.txt
Documentation/merge-config.txt
Documentation/merge-strategies.txt
Documentation/revisions.txt
Documentation/technical/api-config.txt
Documentation/technical/api-directory-listing.txt
Documentation/technical/api-object-access.txt
Documentation/technical/api-oid-array.txt
Documentation/technical/api-submodule-config.txt
Documentation/technical/commit-graph-format.txt [new file with mode: 0644]
Documentation/technical/commit-graph.txt [new file with mode: 0644]
Documentation/technical/hash-function-transition.txt
Documentation/technical/pack-format.txt
Documentation/technical/protocol-v2.txt [new file with mode: 0644]
Documentation/technical/shallow.txt
GIT-VERSION-GEN
Makefile
README.md
RelNotes
advice.c
advice.h
alias.c
alias.h [new file with mode: 0644]
alloc.c
apply.c
archive-tar.c
archive-zip.c
archive.c
archive.h
argv-array.c
argv-array.h
attr.c
bisect.c
blame.c
branch.c
builtin.h
builtin/add.c
builtin/am.c
builtin/blame.c
builtin/branch.c
builtin/cat-file.c
builtin/checkout.c
builtin/clone.c
builtin/column.c
builtin/commit-graph.c [new file with mode: 0644]
builtin/commit-tree.c
builtin/commit.c
builtin/config.c
builtin/count-objects.c
builtin/describe.c
builtin/diff.c
builtin/difftool.c
builtin/fast-export.c
builtin/fetch-pack.c
builtin/fetch.c
builtin/fmt-merge-msg.c
builtin/fsck.c
builtin/gc.c
builtin/grep.c
builtin/hash-object.c
builtin/help.c
builtin/index-pack.c
builtin/init-db.c
builtin/log.c
builtin/ls-files.c
builtin/ls-remote.c
builtin/ls-tree.c
builtin/merge-tree.c
builtin/merge.c
builtin/mktag.c
builtin/mktree.c
builtin/mv.c
builtin/name-rev.c
builtin/notes.c
builtin/pack-objects.c
builtin/pack-redundant.c
builtin/pack-refs.c
builtin/prune-packed.c
builtin/prune.c
builtin/pull.c
builtin/push.c
builtin/read-tree.c
builtin/rebase--helper.c
builtin/receive-pack.c
builtin/reflog.c
builtin/remote.c
builtin/repack.c
builtin/replace.c
builtin/reset.c
builtin/rev-list.c
builtin/rev-parse.c
builtin/rm.c
builtin/send-pack.c
builtin/serve.c [new file with mode: 0644]
builtin/shortlog.c
builtin/show-branch.c
builtin/show-ref.c
builtin/submodule--helper.c
builtin/tag.c
builtin/unpack-file.c
builtin/unpack-objects.c
builtin/update-index.c
builtin/upload-pack.c [new file with mode: 0644]
builtin/verify-commit.c
builtin/verify-tag.c
builtin/worktree.c
builtin/write-tree.c
bulk-checkin.c
bulk-checkin.h
bundle.c
cache-tree.c
cache-tree.h
cache.h
chdir-notify.c [new file with mode: 0644]
chdir-notify.h [new file with mode: 0644]
checkout.c
ci/lib-travisci.sh
ci/run-build-and-tests.sh
color.c
color.h
column.c
combine-diff.c
command-list.txt
commit-graph.c [new file with mode: 0644]
commit-graph.h [new file with mode: 0644]
commit.c
commit.h
common-main.c
compat/mingw.c
config.c
config.h
config.mak.dev [new file with mode: 0644]
config.mak.uname
configure.ac
connect.c
connect.h
contrib/coccinelle/commit.cocci [new file with mode: 0644]
contrib/completion/git-completion.bash
contrib/completion/git-completion.zsh
contrib/convert-grafts-to-replace-refs.sh [deleted file]
contrib/credential/netrc/Makefile
contrib/credential/netrc/git-credential-netrc
contrib/credential/netrc/t-git-credential-netrc.sh [new file with mode: 0755]
contrib/credential/netrc/test.command-option-gpg [new file with mode: 0755]
contrib/credential/netrc/test.git-config-gpg [new file with mode: 0755]
contrib/credential/netrc/test.netrc.gpg [new file with mode: 0644]
contrib/credential/netrc/test.pl
contrib/diff-highlight/DiffHighlight.pm
contrib/diff-highlight/t/t9400-diff-highlight.sh
contrib/emacs/.gitignore [deleted file]
contrib/emacs/Makefile [deleted file]
contrib/emacs/README
contrib/emacs/git-blame.el
contrib/emacs/git.el
contrib/examples/README
contrib/examples/builtin-fetch--tool.c [deleted file]
contrib/examples/git-am.sh [deleted file]
contrib/examples/git-checkout.sh [deleted file]
contrib/examples/git-clean.sh [deleted file]
contrib/examples/git-clone.sh [deleted file]
contrib/examples/git-commit.sh [deleted file]
contrib/examples/git-difftool.perl [deleted file]
contrib/examples/git-fetch.sh [deleted file]
contrib/examples/git-gc.sh [deleted file]
contrib/examples/git-log.sh [deleted file]
contrib/examples/git-ls-remote.sh [deleted file]
contrib/examples/git-merge-ours.sh [deleted file]
contrib/examples/git-merge.sh [deleted file]
contrib/examples/git-notes.sh [deleted file]
contrib/examples/git-pull.sh [deleted file]
contrib/examples/git-remote.perl [deleted file]
contrib/examples/git-repack.sh [deleted file]
contrib/examples/git-rerere.perl [deleted file]
contrib/examples/git-reset.sh [deleted file]
contrib/examples/git-resolve.sh [deleted file]
contrib/examples/git-revert.sh [deleted file]
contrib/examples/git-svnimport.perl [deleted file]
contrib/examples/git-svnimport.txt [deleted file]
contrib/examples/git-tag.sh [deleted file]
contrib/examples/git-verify-tag.sh [deleted file]
contrib/examples/git-whatchanged.sh [deleted file]
contrib/fast-import/import-tars.perl
contrib/mw-to-git/Makefile
contrib/update-unicode/README
contrib/update-unicode/update_unicode.sh
convert.c
convert.h
credential.c
csum-file.c
csum-file.h
daemon.c
date.c
detect-compiler [new file with mode: 0755]
diff.c
diff.h
diffcore-pickaxe.c
dir-iterator.c
dir.c
dir.h
entry.c
environment.c
ewah/ewah_io.c
ewah/ewok.h
exec-cmd.c [new file with mode: 0644]
exec-cmd.h [moved from exec_cmd.h with 79% similarity]
exec_cmd.c [deleted file]
fast-import.c
fetch-pack.c
fetch-pack.h
fsck.c
fsmonitor.c
generate-cmdlist.sh
gettext.c
git-add--interactive.perl
git-compat-util.h
git-filter-branch.sh
git-gui/git-gui.sh
git-gui/lib/sshkey.tcl
git-gui/lib/themed.tcl
git-merge-one-file.sh
git-p4.py
git-rebase--am.sh
git-rebase--interactive.sh
git-rebase--merge.sh
git-rebase.sh
git-send-email.perl
git-stash.sh
git-submodule.sh
git-svn.perl
git.c
gpg-interface.c
gpg-interface.h
grep.c
help.c
help.h
http-backend.c
http-fetch.c
http-push.c
http-walker.c
http.c
http.h
imap-send.c
line-log.c
list-objects-filter.c
list-objects.c
lockfile.c
log-tree.c
log-tree.h
ls-refs.c [new file with mode: 0644]
ls-refs.h [new file with mode: 0644]
mailinfo.c
mailmap.c
match-trees.c
mem-pool.c [new file with mode: 0644]
mem-pool.h [new file with mode: 0644]
merge-blobs.c
merge-recursive.c
merge-recursive.h
merge.c
mergetools/guiffy [new file with mode: 0644]
notes-cache.c
notes-merge.c
notes.c
object-store.h [new file with mode: 0644]
object.c
object.h
pack-bitmap-write.c
pack-bitmap.c
pack-bitmap.h
pack-check.c
pack-objects.c
pack-objects.h
pack-revindex.c
pack-write.c
packfile.c
packfile.h
pager.c
parse-options-cb.c
parse-options.c
parse-options.h
path.c
pathspec.c
perl/Git.pm
perl/Git/I18N.pm
perl/Git/SVN.pm
perl/header_templates/fixed_prefix.template.pl [new file with mode: 0644]
perl/header_templates/runtime_prefix.template.pl [new file with mode: 0644]
pkt-line.c
pkt-line.h
po/TEAMS
po/bg.po
po/ca.po
po/de.po
po/es.po
po/fr.po
po/git.pot
po/ko.po
po/sv.po
po/vi.po
po/zh_CN.po
pretty.c
prio-queue.c
protocol.c
protocol.h
reachable.c
read-cache.c
ref-filter.c
ref-filter.h
refs.c
refs.h
refs/files-backend.c
refs/iterator.c
refs/packed-backend.c
refs/ref-cache.c
refspec.c [new file with mode: 0644]
refspec.h [new file with mode: 0644]
remote-curl.c
remote-testsvn.c
remote.c
remote.h
replace-object.c [new file with mode: 0644]
replace-object.h [new file with mode: 0644]
replace_object.c [deleted file]
repository.c
repository.h
rerere.c
resolve-undo.c
resolve-undo.h
revision.c
run-command.c
send-pack.c
sequencer.c
sequencer.h
serve.c [new file with mode: 0644]
serve.h [new file with mode: 0644]
server-info.c
setup.c
sha1-array.c
sha1-array.h
sha1-file.c [moved from sha1_file.c with 85% similarity]
sha1-lookup.c
sha1-name.c [moved from sha1_name.c with 94% similarity]
shallow.c
shell.c
sideband.c
sigchain.c
split-index.c
split-index.h
strbuf.c
strbuf.h
streaming.c
streaming.h
submodule-config.c
submodule-config.h
submodule.c
submodule.h
t/README
t/diff-lib.sh
t/helper/test-chmtime.c
t/helper/test-config.c
t/helper/test-ctype.c
t/helper/test-date.c
t/helper/test-delta.c
t/helper/test-drop-caches.c
t/helper/test-dump-cache-tree.c
t/helper/test-dump-split-index.c
t/helper/test-dump-untracked-cache.c
t/helper/test-example-decorate.c
t/helper/test-genrandom.c
t/helper/test-hashmap.c
t/helper/test-index-version.c
t/helper/test-lazy-init-name-hash.c
t/helper/test-match-trees.c
t/helper/test-mergesort.c
t/helper/test-mktemp.c
t/helper/test-online-cpus.c
t/helper/test-path-utils.c
t/helper/test-pkt-line.c [new file with mode: 0644]
t/helper/test-prio-queue.c
t/helper/test-read-cache.c
t/helper/test-ref-store.c
t/helper/test-regex.c
t/helper/test-revision-walking.c
t/helper/test-run-command.c
t/helper/test-scrap-cache-tree.c
t/helper/test-sha1-array.c
t/helper/test-sha1.c
t/helper/test-sha1.sh
t/helper/test-sigchain.c
t/helper/test-strcmp-offset.c
t/helper/test-string-list.c
t/helper/test-submodule-config.c
t/helper/test-subprocess.c
t/helper/test-tool.c [new file with mode: 0644]
t/helper/test-tool.h [new file with mode: 0644]
t/helper/test-urlmatch-normalization.c
t/helper/test-wildmatch.c
t/helper/test-write-cache.c
t/lib-diff-alternative.sh
t/lib-git-p4.sh
t/lib-git-svn.sh
t/lib-pack.sh
t/lib-t6000.sh
t/perf/aggregate.perl
t/perf/bisect_regression [new file with mode: 0755]
t/perf/bisect_run_script [new file with mode: 0755]
t/perf/p0002-read-cache.sh
t/perf/p0004-lazy-init-name-hash.sh
t/perf/p0007-write-cache.sh
t/perf/p0071-sort.sh
t/perf/p7519-fsmonitor.sh
t/perf/run
t/t0000-basic.sh
t/t0005-signals.sh
t/t0006-date.sh
t/t0009-prio-queue.sh
t/t0011-hashmap.sh
t/t0012-help.sh
t/t0013-sha1dc.sh
t/t0021-conversion.sh
t/t0028-working-tree-encoding.sh [new file with mode: 0755]
t/t0040-parse-options.sh
t/t0041-usage.sh [new file with mode: 0755]
t/t0060-path-utils.sh
t/t0061-run-command.sh
t/t0062-revision-walking.sh
t/t0063-string-list.sh
t/t0064-sha1-array.sh
t/t0065-strcmp-offset.sh
t/t0070-fundamental.sh
t/t0090-cache-tree.sh
t/t0110-urlmatch-normalization.sh
t/t1000-read-tree-m-3way.sh
t/t1001-read-tree-m-2way.sh
t/t1002-read-tree-m-u-2way.sh
t/t1006-cat-file.sh
t/t1007-hash-object.sh
t/t1011-read-tree-sparse-checkout.sh
t/t1012-read-tree-df.sh
t/t1050-large.sh
t/t1300-config.sh [moved from t/t1300-repo-config.sh with 89% similarity]
t/t1304-default-acl.sh
t/t1305-config-include.sh
t/t1307-config-blob.sh
t/t1308-config-set.sh
t/t1309-early-config.sh
t/t1310-config-default.sh [new file with mode: 0755]
t/t1400-update-ref.sh
t/t1401-symbolic-ref.sh
t/t1405-main-ref-store.sh
t/t1406-submodule-ref-store.sh
t/t1407-worktree-ref-store.sh
t/t1411-reflog-show.sh
t/t1450-fsck.sh
t/t1501-work-tree.sh
t/t1507-rev-parse-upstream.sh
t/t1510-repo-setup.sh
t/t1512-rev-parse-disambiguation.sh
t/t1600-index.sh
t/t1601-index-bogus.sh
t/t1700-split-index.sh
t/t2011-checkout-invalid-head.sh
t/t2020-checkout-detach.sh
t/t2022-checkout-paths.sh
t/t2025-worktree-add.sh
t/t2026-worktree-prune.sh
t/t2027-worktree-list.sh
t/t2028-worktree-move.sh
t/t2101-update-index-reupdate.sh
t/t2104-update-index-skip-worktree.sh
t/t2107-update-index-basic.sh
t/t2201-add-update-typechange.sh
t/t2203-add-intent.sh
t/t3008-ls-files-lazy-init-name-hash.sh
t/t3034-merge-recursive-rename-options.sh
t/t3070-wildmatch.sh
t/t3100-ls-tree-restrict.sh
t/t3101-ls-tree-dirname.sh
t/t3103-ls-tree-misc.sh
t/t3200-branch.sh
t/t3306-notes-prune.sh
t/t3404-rebase-interactive.sh
t/t3418-rebase-continue.sh
t/t3421-rebase-topology-linear.sh
t/t3428-rebase-signoff.sh
t/t3430-rebase-merges.sh [new file with mode: 0755]
t/t3501-revert-cherry-pick.sh
t/t3510-cherry-pick-sequence.sh
t/t3600-rm.sh
t/t3700-add.sh
t/t3702-add-edit.sh
t/t3903-stash.sh
t/t3905-stash-include-untracked.sh
t/t4001-diff-rename.sh
t/t4002-diff-basic.sh
t/t4006-diff-mode.sh
t/t4007-rename-3.sh
t/t4008-diff-break-rewrite.sh
t/t4011-diff-symlink.sh
t/t4013-diff-various.sh
t/t4014-format-patch.sh
t/t4020-diff-external.sh
t/t4022-diff-rewrite.sh
t/t4027-diff-submodule.sh
t/t4029-diff-trailing-space.sh
t/t4030-diff-textconv.sh
t/t4035-diff-quiet.sh
t/t4042-diff-textconv-caching.sh
t/t4044-diff-index-unique-abbrev.sh
t/t4045-diff-relative.sh
t/t4046-diff-unmerged.sh
t/t4054-diff-bogus-tree.sh
t/t4058-diff-duplicates.sh
t/t4150-am.sh
t/t4151-am-abort.sh
t/t4200-rerere.sh
t/t4201-shortlog.sh
t/t4205-log-pretty-formats.sh
t/t4208-log-magic-pathspec.sh
t/t5000-tar-tree.sh
t/t5150-request-pull.sh
t/t5300-pack-object.sh
t/t5301-sliding-window.sh
t/t5302-pack-index.sh
t/t5303-pack-corruption-resilience.sh
t/t5304-prune.sh
t/t5308-pack-detect-duplicates.sh
t/t5309-pack-delta-cycles.sh
t/t5310-pack-bitmaps.sh
t/t5313-pack-bounds-checks.sh
t/t5314-pack-cycle-detection.sh
t/t5316-pack-delta-depth.sh
t/t5318-commit-graph.sh [new file with mode: 0755]
t/t5400-send-pack.sh
t/t5404-tracking-branches.sh
t/t5500-fetch-pack.sh
t/t5510-fetch.sh
t/t5512-ls-remote.sh
t/t5516-fetch-push.sh
t/t5527-fetch-odd-refs.sh
t/t5541-http-push-smart.sh
t/t5546-receive-limits.sh
t/t5547-push-quarantine.sh
t/t5550-http-fetch-dumb.sh
t/t5551-http-fetch-smart.sh
t/t5561-http-backend.sh
t/t5571-pre-push-hook.sh
t/t5572-pull-submodule.sh
t/t5608-clone-2gb.sh
t/t5701-git-serve.sh [new file with mode: 0755]
t/t5702-protocol-v2.sh [new file with mode: 0755]
t/t6001-rev-list-graft.sh
t/t6006-rev-list-format.sh
t/t6010-merge-base.sh
t/t6012-rev-list-simplify.sh
t/t6022-merge-rename.sh
t/t6043-merge-rename-directories.sh [new file with mode: 0755]
t/t6046-merge-skip-unneeded-updates.sh [new file with mode: 0755]
t/t6050-replace.sh
t/t6101-rev-parse-parents.sh
t/t6111-rev-list-treesame.sh
t/t6120-describe.sh
t/t6300-for-each-ref.sh
t/t6301-for-each-ref-errors.sh
t/t6500-gc.sh
t/t6501-freshen-objects.sh
t/t7001-mv.sh
t/t7003-filter-branch.sh
t/t7004-tag.sh
t/t7005-editor.sh
t/t7009-filter-branch-null-sha1.sh
t/t7011-skip-worktree-reading.sh
t/t7064-wtstatus-pv2.sh
t/t7201-co.sh
t/t7400-submodule-basic.sh
t/t7406-submodule-update.sh
t/t7408-submodule-reference.sh
t/t7411-submodule-config.sh
t/t7415-submodule-names.sh
t/t7501-commit.sh
t/t7506-status-submodule.sh
t/t7508-status.sh
t/t7525-status-rename.sh [new file with mode: 0755]
t/t7607-merge-overwrite.sh
t/t7700-repack.sh
t/t7701-repack-unpack-unreachable.sh
t/t7812-grep-icase-non-ascii.sh
t/t8012-blame-colors.sh [new file with mode: 0755]
t/t9004-example.sh
t/t9010-svn-fe.sh
t/t9100-git-svn-basic.sh
t/t9104-git-svn-follow-parent.sh
t/t9108-git-svn-glob.sh
t/t9109-git-svn-multi-glob.sh
t/t9110-git-svn-use-svm-props.sh
t/t9111-git-svn-use-svnsync-props.sh
t/t9114-git-svn-dcommit-merge.sh
t/t9130-git-svn-authors-file.sh
t/t9138-git-svn-authors-prog.sh
t/t9153-git-svn-rewrite-uuid.sh
t/t9168-git-svn-partially-globbed-names.sh
t/t9300-fast-import.sh
t/t9350-fast-export.sh
t/t9802-git-p4-filetype.sh
t/t9803-git-p4-shell-metachars.sh
t/t9807-git-p4-submit.sh
t/t9813-git-p4-preserve-users.sh
t/t9818-git-p4-block.sh
t/t9820-git-p4-editor-handling.sh
t/t9832-unshelve.sh [new file with mode: 0755]
t/t9833-errors.sh [new file with mode: 0755]
t/t9902-completion.sh
t/t9903-bash-prompt.sh
t/test-lib-functions.sh
t/test-lib.sh
tag.c
templates/hooks--pre-commit.sample
tmp-objdir.c
trace.c
trace.h
trailer.c
transport-helper.c
transport-internal.h
transport.c
transport.h
tree-walk.c
tree-walk.h
tree.c
tree.h
unicode-width.h [moved from unicode_width.h with 100% similarity]
unpack-trees.c
unpack-trees.h
upload-pack.c
upload-pack.h [new file with mode: 0644]
usage.c
utf8.c
utf8.h
vcs-svn/fast_export.c
walker.c
walker.h
worktree.c
wrap-for-bin.sh
wrapper.c
write-or-die.c [moved from write_or_die.c with 100% similarity]
wt-status.c
wt-status.h
xdiff-interface.c
zlib.c

index 8ce9c6b8888fe6c12949d30e3e8b461cb67bb43f..1bdc91e282c5393c527b3902a208227c19971b84 100644 (file)
@@ -1,8 +1,10 @@
 * whitespace=!indent,trail,space
 *.[ch] whitespace=indent,trail,space diff=cpp
 *.sh whitespace=indent,trail,space eol=lf
-*.perl eol=lf
-*.pm eol=lf
+*.perl eol=lf diff=perl
+*.pl eof=lf diff=perl
+*.pm eol=lf diff=perl
+*.py eol=lf diff=python
 /Documentation/git-*.txt eol=lf
 /command-list.txt eol=lf
 /GIT-VERSION-GEN eol=lf
index 833ef3b0b783b8180d0dad1ce336713bddf09b26..388cc4beee54faf9f06e9cfae75e7a256d368739 100644 (file)
@@ -3,6 +3,7 @@
 /GIT-LDFLAGS
 /GIT-PREFIX
 /GIT-PERL-DEFINES
+/GIT-PERL-HEADER
 /GIT-PYTHON-VARS
 /GIT-SCRIPT-DEFINES
 /GIT-USER-AGENT
@@ -34,6 +35,7 @@
 /git-clone
 /git-column
 /git-commit
+/git-commit-graph
 /git-commit-tree
 /git-config
 /git-count-objects
 /git-rm
 /git-send-email
 /git-send-pack
+/git-serve
 /git-sh-i18n
 /git-sh-i18n--envsubst
 /git-sh-setup
 /gitweb/gitweb.cgi
 /gitweb/static/gitweb.js
 /gitweb/static/gitweb.min.*
-/common-cmds.h
+/command-list.h
 *.tar.gz
 *.dsc
 *.deb
index 7c71e88ea51c52d453b0d6c08a3415f4c03de22b..df7cf6313c7dd0c5c065e448fd7c725ff537a08b 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -25,8 +25,8 @@ Ben Walton <bdwalton@gmail.com> <bwalton@artsci.utoronto.ca>
 Benoit Sigoure <tsunanet@gmail.com> <tsuna@lrde.epita.fr>
 Bernt Hansen <bernt@norang.ca> <bernt@alumni.uwaterloo.ca>
 Brandon Casey <drafnel@gmail.com> <casey@nrlssc.navy.mil>
-brian m. carlson <sandals@crustytoothpaste.ath.cx> Brian M. Carlson <sandals@crustytoothpaste.ath.cx>
-brian m. carlson <sandals@crustytoothpaste.ath.cx> <sandals@crustytoothpaste.net>
+brian m. carlson <sandals@crustytoothpaste.net> Brian M. Carlson <sandals@crustytoothpaste.ath.cx>
+brian m. carlson <sandals@crustytoothpaste.net> <sandals@crustytoothpaste.ath.cx>
 Bryan Larsen <bryan@larsen.st> <bryan.larsen@gmail.com>
 Bryan Larsen <bryan@larsen.st> <bryanlarsen@yahoo.com>
 Cheng Renquan <crquan@gmail.com>
index 5f5ee4f3bd86f3f7d6cfce4e99453f68f0673eab..4d4e26c9df519c7d708e779401b5076878af022d 100644 (file)
@@ -16,10 +16,13 @@ compiler:
 
 addons:
   apt:
+    sources:
+    - ubuntu-toolchain-r-test
     packages:
     - language-pack-is
     - git-svn
     - apache2
+    - gcc-8
 
 matrix:
   include:
index 6232143cb95d105b0c33b81d16c6b7b628fadb97..d079d7c73aca1fd91ac18045aab46b2446f43a16 100644 (file)
@@ -78,6 +78,7 @@ TECH_DOCS += technical/pack-heuristics
 TECH_DOCS += technical/pack-protocol
 TECH_DOCS += technical/protocol-capabilities
 TECH_DOCS += technical/protocol-common
+TECH_DOCS += technical/protocol-v2
 TECH_DOCS += technical/racy-git
 TECH_DOCS += technical/send-pack-pipeline
 TECH_DOCS += technical/shallow
@@ -184,7 +185,7 @@ ASCIIDOC = asciidoctor
 ASCIIDOC_CONF =
 ASCIIDOC_HTML = xhtml5
 ASCIIDOC_DOCBOOK = docbook45
-ASCIIDOC_EXTRA += -acompat-mode
+ASCIIDOC_EXTRA += -acompat-mode -atabsize=8
 ASCIIDOC_EXTRA += -I. -rasciidoctor-extensions
 ASCIIDOC_EXTRA += -alitdd='&\#x2d;&\#x2d;'
 DBLATEX_COMMON =
index e7e79d999bd38b8cc369b50d995a231a563a81ef..e743a2a8e46ebeadaad3d9d21abdb2412c043149 100644 (file)
@@ -25,7 +25,7 @@ Fixes since v1.7.11.6
    references" nor "Reload" did not update what is shown as the
    contents of it, when the user overwrote the tag with "git tag -f".
 
- * "git for-each-ref" did not currectly support more than one --sort
+ * "git for-each-ref" did not correctly support more than one --sort
    option.
 
  * "git log .." errored out saying it is both rev range and a path
index d6db0e19cf17ba10700f7b314ecab3c4c51e675e..c2cf891f71adfe09f7432591333952d8577439c4 100644 (file)
@@ -342,7 +342,7 @@ Fixes since v2.16
    validate the data and connected-ness of objects in the received
    pack; the code to perform this check has been taught about the
    narrow clone's convention that missing objects that are reachable
-   from objects in a pack that came from a promissor remote is OK.
+   from objects in a pack that came from a promisor remote is OK.
 
  * There was an unused file-scope static variable left in http.c when
    building for versions of libCURL that is older than 7.19.4, which
diff --git a/Documentation/RelNotes/2.18.0.txt b/Documentation/RelNotes/2.18.0.txt
new file mode 100644 (file)
index 0000000..3ea280c
--- /dev/null
@@ -0,0 +1,583 @@
+Git 2.18 Release Notes
+======================
+
+Updates since v2.17
+-------------------
+
+UI, Workflows & Features
+
+ * Rename detection logic that is used in "merge" and "cherry-pick" has
+   learned to guess when all of x/a, x/b and x/c have moved to z/a,
+   z/b and z/c, it is likely that x/d added in the meantime would also
+   want to move to z/d by taking the hint that the entire directory
+   'x' moved to 'z'.  A bug causing dirty files involved in a rename
+   to be overwritten during merge has also been fixed as part of this
+   work.  Incidentally, this also avoids updating a file in the
+   working tree after a (non-trivial) merge whose result matches what
+   our side originally had.
+
+ * "git filter-branch" learned to use a different exit code to allow
+   the callers to tell the case where there was no new commits to
+   rewrite from other error cases.
+
+ * When built with more recent cURL, GIT_SSL_VERSION can now specify
+   "tlsv1.3" as its value.
+
+ * "git gui" learned that "~/.ssh/id_ecdsa.pub" and
+   "~/.ssh/id_ed25519.pub" are also possible SSH key files.
+   (merge 2e2f0288ef bb/git-gui-ssh-key-files later to maint).
+
+ * "git gui" performs commit upon CTRL/CMD+ENTER but the
+   CTRL/CMD+KP_ENTER (i.e. enter key on the numpad) did not have the
+   same key binding.  It now does.
+   (merge 28a1d94a06 bp/git-gui-bind-kp-enter later to maint).
+
+ * "git gui" has been taught to work with old versions of tk (like
+   8.5.7) that do not support "ttk::style theme use" as a way to query
+   the current theme.
+   (merge 4891961105 cb/git-gui-ttk-style later to maint).
+
+ * "git rebase" has learned to honor "--signoff" option when using
+   backends other than "am" (but not "--preserve-merges").
+
+ * "git branch --list" during an interrupted "rebase -i" now lets
+   users distinguish the case where a detached HEAD is being rebased
+   and a normal branch is being rebased.
+
+ * "git mergetools" learned talking to guiffy.
+
+ * The scripts in contrib/emacs/ have outlived their usefulness and
+   have been replaced with a stub that errors out and tells the user
+   there are replacements.
+
+ * The new "working-tree-encoding" attribute can ask Git to convert the
+   contents to the specified encoding when checking out to the working
+   tree (and the other way around when checking in).
+
+ * The "git config" command uses separate options e.g. "--int",
+   "--bool", etc. to specify what type the caller wants the value to
+   be interpreted as.  A new "--type=<typename>" option has been
+   introduced, which would make it cleaner to define new types.
+
+ * "git config --get" learned the "--default" option, to help the
+   calling script.  Building on top of the above changes, the
+   "git config" learns "--type=color" type.  Taken together, you can
+   do things like "git config --get foo.color --default blue" and get
+   the ANSI color sequence for the color given to foo.color variable,
+   or "blue" if the variable does not exist.
+
+ * "git ls-remote" learned an option to allow sorting its output based
+   on the refnames being shown.
+
+ * The command line completion (in contrib/) has been taught that "git
+   stash save" has been deprecated ("git stash push" is the preferred
+   spelling in the new world) and does not offer it as a possible
+   completion candidate when "git stash push" can be.
+
+ * "git gc --prune=nonsense" spent long time repacking and then
+   silently failed when underlying "git prune --expire=nonsense"
+   failed to parse its command line.  This has been corrected.
+
+ * Error messages from "git push" can be painted for more visibility.
+
+ * "git http-fetch" (deprecated) had an optional and experimental
+   "feature" to fetch only commits and/or trees, which nobody used.
+   This has been removed.
+
+ * The functionality of "$GIT_DIR/info/grafts" has been superseded by
+   the "refs/replace/" mechanism for some time now, but the internal
+   code had support for it in many places, which has been cleaned up
+   in order to drop support of the "grafts" mechanism.
+
+ * "git worktree add" learned to check out an existing branch.
+
+ * "git --no-pager cmd" did not have short-and-sweet single letter
+   option. Now it does as "-P".
+   (merge 7213c28818 js/no-pager-shorthand later to maint).
+
+ * "git rebase" learned "--rebase-merges" to transplant the whole
+   topology of commit graph elsewhere.
+
+ * "git status" learned to pay attention to UI related diff
+   configuration variables such as diff.renames.
+
+ * The command line completion mechanism (in contrib/) learned to load
+   custom completion file for "git $command" where $command is a
+   custom "git-$command" that the end user has on the $PATH when using
+   newer version of bash-completion.
+
+ * "git send-email" can sometimes offer confirmation dialog "Send this
+   email?" with choices 'Yes', 'No', 'Quit', and 'All'.  A new action
+   'Edit' has been added to this dialog's choice.
+
+ * With merge.renames configuration set to false, the recursive merge
+   strategy can be told not to spend cycles trying to find renamed
+   paths and merge them accordingly.
+
+ * "git status" learned to honor a new status.renames configuration to
+   skip rename detection, which could be useful for those who want to
+   do so without disabling the default rename detection done by the
+   "git diff" command.
+
+ * Command line completion (in contrib/) learned to complete pathnames
+   for various commands better.
+
+ * "git blame" learns to unhighlight uninteresting metadata from the
+   originating commit on lines that are the same as the previous one,
+   and also paint lines in different colors depending on the age of
+   the commit.
+
+ * Transfer protocol v2 learned to support the partial clone.
+
+ * When a short hexadecimal string is used to name an object but there
+   are multiple objects that share the string as the prefix of their
+   names, the code lists these ambiguous candidates in a help message.
+   These object names are now sorted according to their types for
+   easier eyeballing.
+
+ * "git fetch $there $refspec" that talks over protocol v2 can take
+   advantage of server-side ref filtering; the code has been extended
+   so that this mechanism triggers also when fetching with configured
+   refspec.
+
+ * Our HTTP client code used to advertise that we accept gzip encoding
+   from the other side; instead, just let cURL library to advertise
+   and negotiate the best one.
+
+ * "git p4" learned to "unshelve" shelved commit from P4.
+   (merge 123f631761 ld/p4-unshelve later to maint).
+
+
+Performance, Internal Implementation, Development Support etc.
+
+ * A "git fetch" from a repository with insane number of refs into a
+   repository that is already up-to-date still wasted too many cycles
+   making many lstat(2) calls to see if these objects at the tips
+   exist as loose objects locally.  These lstat(2) calls are optimized
+   away by enumerating all loose objects beforehand.
+   It is unknown if the new strategy negatively affects existing use
+   cases, fetching into a repository with many loose objects from a
+   repository with small number of refs.
+
+ * Git can be built to use either v1 or v2 of the PCRE library, and so
+   far, the build-time configuration USE_LIBPCRE=YesPlease instructed
+   the build procedure to use v1, but now it means v2.  USE_LIBPCRE1
+   and USE_LIBPCRE2 can be used to explicitly choose which version to
+   use, as before.
+
+ * The build procedure learned to optionally use symbolic links
+   (instead of hardlinks and copies) to install "git-foo" for built-in
+   commands, whose binaries are all identical.
+
+ * Conversion from uchar[20] to struct object_id continues.
+
+ * The way "git worktree prune" worked internally has been simplified,
+   by assuming how "git worktree move" moves an existing worktree to a
+   different place.
+
+ * Code clean-up for the "repository" abstraction.
+   (merge 00a3da2a13 nd/remove-ignore-env-field later to maint).
+
+ * Code to find the length to uniquely abbreviate object names based
+   on packfile content, which is a relatively recent addtion, has been
+   optimized to use the same fan-out table.
+
+ * The mechanism to use parse-options API to automate the command line
+   completion continues to get extended and polished.
+
+ * Copies of old scripted Porcelain commands in contrib/examples/ have
+   been removed.
+
+ * Some tests that rely on the exact hardcoded values of object names
+   have been updated in preparation for hash function migration.
+
+ * Perf-test update.
+
+ * Test helper update.
+
+ * The effort continues to refactor the internal global data structure
+   to make it possible to open multiple repositories, work with and
+   then close them,
+
+ * Small test-helper programs have been consolidated into a single
+   binary.
+
+ * API clean-up around ref-filter code.
+
+ * Shell completion (in contrib) that gives list of paths have been
+   optimized somewhat.
+
+ * The index file is updated to record the fsmonitor section after a
+   full scan was made, to avoid wasting the effort that has already
+   spent.
+
+ * Performance measuring framework in t/perf learned to help bisecting
+   performance regressions.
+
+ * Some multi-word source filenames are being renamed to separate
+   words with dashes instead of underscores.
+
+ * An reusable "memory pool" implementation has been extracted from
+   fast-import.c, which in turn has become the first user of the
+   mem-pool API.
+
+ * A build-time option has been added to allow Git to be told to refer
+   to its associated files relative to the main binary, in the same
+   way that has been possible on Windows for quite some time, for
+   Linux, BSDs and Darwin.
+
+ * Precompute and store information necessary for ancestry traversal
+   in a separate file to optimize graph walking.
+
+ * The effort to pass the repository in-core structure throughout the
+   API continues.  This round deals with the code that implements the
+   refs/replace/ mechanism.
+
+ * The build procedure "make DEVELOPER=YesPlease" learned to enable a
+   bit more warning options depending on the compiler used to help
+   developers more.  There also is "make DEVOPTS=tokens" knob
+   available now, for those who want to help fixing warnings we
+   usually ignore, for example.
+
+ * A new version of the transport protocol is being worked on.
+
+ * The code to interface to GPG has been restructured somewhat to make
+   it cleaner to integrate with other types of signature systems later.
+
+ * The code has been taught to use the duplicated information stored
+   in the commit-graph file to learn the tree object name for a commit
+   to avoid opening and parsing the commit object when it makes sense
+   to do so.
+
+ * "git gc" in a large repository takes a lot of time as it considers
+   to repack all objects into one pack by default.  The command has
+   been taught to pretend as if the largest existing packfile is
+   marked with ".keep" so that it is left untouched while objects in
+   other packs and loose ones are repacked.
+
+ * The transport protocol v2 is getting updated further.
+
+ * The codepath around object-info API has been taught to take the
+   repository object (which in turn tells the API which object store
+   the objects are to be located).
+
+ * "git pack-objects" needs to allocate tons of "struct object_entry"
+   while doing its work, and shrinking its size helps the performance
+   quite a bit.
+
+ * The implementation of "git rebase -i --root" has been updated to use
+   the sequencer machinery more.
+
+ * Developer support update, by using BUG() macro instead of die() to
+   mark codepaths that should not happen more clearly.
+
+ * Developer support.  Use newer GCC on one of the builds done at
+   TravisCI.org to get more warnings and errors diagnosed.
+
+ * Conversion from uchar[20] to struct object_id continues.
+
+ * By code restructuring of submodule merge in merge-recursive,
+   informational messages from the codepath are now given using the
+   same mechanism as other output, and honor the merge.verbosity
+   configuration.  The code also learned to give a few new messages
+   when a submodule three-way merge resolves cleanly when one side
+   records a descendant of the commit chosen by the other side.
+
+ * Avoid unchecked snprintf() to make future code auditing easier.
+   (merge ac4896f007 jk/snprintf-truncation later to maint).
+
+ * Many tests hardcode the raw object names, which would change once
+   we migrate away from SHA-1.  While some of them must test against
+   exact object names, most of them do not have to use hardcoded
+   constants in the test.  The latter kind of tests have been updated
+   to test the moral equivalent of the original without hardcoding the
+   actual object names.
+
+ * The list of commands with their various attributes were spread
+   across a few places in the build procedure, but it now is getting a
+   bit more consolidated to allow more automation.
+
+ * Quite a many tests assumed that newly created refs are made as
+   loose refs using the files backend, which have been updated to use
+   proper plumbing like rev-parse and update-ref, to avoid breakage
+   once we start using different ref backends.
+
+
+Also contains various documentation updates and code clean-ups.
+
+
+Fixes since v2.17
+-----------------
+
+ * "git shortlog cruft" aborted with a BUG message when run outside a
+   Git repository.  The command has been taught to complain about
+   extra and unwanted arguments on its command line instead in such a
+   case.
+   (merge 4aa0161e83 ma/shortlog-revparse later to maint).
+
+ * "git stash push -u -- <pathspec>" gave an unnecessary and confusing
+   error message when there was no tracked files that match the
+   <pathspec>, which has been fixed.
+   (merge 353278687e tg/stash-untracked-with-pathspec-fix later to maint).
+
+ * "git tag --contains no-such-commit" gave a full list of options
+   after giving an error message.
+   (merge 3bb0923f06 ps/contains-id-error-message later to maint).
+
+ * "diff-highlight" filter (in contrib/) learned to understand "git log
+   --graph" output better.
+   (merge 4551fbba14 jk/diff-highlight-graph-fix later to maint).
+
+ * when refs that do not point at committish are given, "git
+   filter-branch" gave a misleading error messages.  This has been
+   corrected.
+   (merge f78ab355e7 yk/filter-branch-non-committish-refs later to maint).
+
+ * "git submodule status" misbehaved on a submodule that has been
+   removed from the working tree.
+   (merge 74b6bda32f rs/status-with-removed-submodule later to maint).
+
+ * When credential helper exits very quickly without reading its
+   input, it used to cause Git to die with SIGPIPE, which has been
+   fixed.
+   (merge a0d51e8d0e eb/cred-helper-ignore-sigpipe later to maint).
+
+ * "git rebase --keep-empty" still removed an empty commit if the
+   other side contained an empty commit (due to the "does an
+   equivalent patch exist already?" check), which has been corrected.
+   (merge 3d946165e1 pw/rebase-keep-empty-fixes later to maint).
+
+ * Some codepaths, including the refs API, get and keep relative
+   paths, that go out of sync when the process does chdir(2).  The
+   chdir-notify API is introduced to let these codepaths adjust these
+   cached paths to the new current directory.
+   (merge fb9c2d2703 jk/relative-directory-fix later to maint).
+
+ * "cd sub/dir && git commit ../path" ought to record the changes to
+   the file "sub/path", but this regressed long time ago.
+   (merge 86238e07ef bw/commit-partial-from-subdirectory-fix later to maint).
+
+ * Recent introduction of "--log-destination" option to "git daemon"
+   did not work well when the daemon was run under "--inetd" mode.
+   (merge e67d906d73 lw/daemon-log-destination later to maint).
+
+ * Small fix to the autoconf build procedure.
+   (merge 249482daf0 es/fread-reads-dir-autoconf-fix later to maint).
+
+ * Fix an unexploitable (because the oversized contents are not under
+   attacker's control) buffer overflow.
+   (merge d8579accfa bp/fsmonitor-bufsize-fix later to maint).
+
+ * Recent simplification of build procedure forgot a bit of tweak to
+   the build procedure of contrib/mw-to-git/
+   (merge d8698987f3 ab/simplify-perl-makefile later to maint).
+
+ * Moving a submodule that itself has submodule in it with "git mv"
+   forgot to make necessary adjustment to the nested sub-submodules;
+   now the codepath learned to recurse into the submodules.
+
+ * "git config --unset a.b", when "a.b" is the last variable in an
+   otherwise empty section "a", left an empty section "a" behind, and
+   worse yet, a subsequent "git config a.c value" did not reuse that
+   empty shell and instead created a new one.  These have been
+   (partially) corrected.
+   (merge c71d8bb38a js/empty-config-section-fix later to maint).
+
+ * "git worktree remove" learned that "-f" is a shorthand for
+   "--force" option, just like for "git worktree add".
+   (merge d228eea514 sb/worktree-remove-opt-force later to maint).
+
+ * The completion script (in contrib/) learned to clear cached list of
+   command line options upon dot-sourcing it again in a more efficient
+   way.
+   (merge 94408dc71c sg/completion-clear-cached later to maint).
+
+ * "git svn" had a minor thinko/typo which has been fixed.
+   (merge 51db271587 ab/git-svn-get-record-typofix later to maint).
+
+ * During a "rebase -i" session, the code could give older timestamp
+   to commits created by later "pick" than an earlier "reword", which
+   has been corrected.
+   (merge 12f7babd6b js/ident-date-fix later to maint).
+
+ * "git submodule status" did not check the symbolic revision name it
+   computed for the submodule HEAD is not the NULL, and threw it at
+   printf routines, which has been corrected.
+   (merge 0b5e2ea7cf nd/submodule-status-fix later to maint).
+
+ * When fed input that already has In-Reply-To: and/or References:
+   headers and told to add the same information, "git send-email"
+   added these headers separately, instead of appending to an existing
+   one, which is a violation of the RFC.  This has been corrected.
+   (merge 256be1d3f0 sa/send-email-dedup-some-headers later to maint).
+
+ * "git fast-export" had a regression in v2.15.0 era where it skipped
+   some merge commits in certain cases, which has been corrected.
+   (merge be011bbe00 ma/fast-export-skip-merge-fix later to maint).
+
+ * The code did not propagate the terminal width to subprocesses via
+   COLUMNS environment variable, which it now does.  This caused
+   trouble to "git column" helper subprocess when "git tag --column=row"
+   tried to list the existing tags on a display with non-default width.
+   (merge b5d5a567fb nd/term-columns later to maint).
+
+ * We learned that our source files with ".pl" and ".py" extensions
+   are Perl and Python files respectively and changes to them are
+   better viewed as such with appropriate diff drivers.
+   (merge 7818b619e2 ab/perl-python-attrs later to maint).
+
+ * "git rebase -i" sometimes left intermediate "# This is a
+   combination of N commits" message meant for the human consumption
+   inside an editor in the final result in certain corner cases, which
+   has been fixed.
+   (merge 15ef69314d js/rebase-i-clean-msg-after-fixup-continue later to maint).
+
+ * A test to see if the filesystem normalizes UTF-8 filename has been
+   updated to check what we need to know in a more direct way, i.e. a
+   path created in NFC form can be accessed with NFD form (or vice
+   versa) to cope with APFS as well as HFS.
+   (merge 742ae10e35 tb/test-apfs-utf8-normalization later to maint).
+
+ * "git format-patch --cover --attach" created a broken MIME multipart
+   message for the cover letter, which has been fixed by keeping the
+   cover letter as plain text file.
+   (merge 50cd54ef4e bc/format-patch-cover-no-attach later to maint).
+
+ * The split-index feature had a long-standing and dormant bug in
+   certain use of the in-core merge machinery, which has been fixed.
+   (merge 7db118303a en/unpack-trees-split-index-fix later to maint).
+
+ * Asciidoctor gives a reasonable imitation for AsciiDoc, but does not
+   render illustration in a literal block correctly when indented with
+   HT by default. The problem is fixed by forcing 8-space tabs.
+   (merge 379805051d bc/asciidoctor-tab-width later to maint).
+
+ * Code clean-up to adjust to a more recent lockfile API convention that
+   allows lockfile instances kept on the stack.
+   (merge 0fa5a2ed8d ma/lockfile-cleanup later to maint).
+
+ * the_repository->index is not a allocated piece of memory but
+   repo_clear() indiscriminately attempted to free(3) it, which has
+   been corrected.
+   (merge 74373b5f10 nd/repo-clear-keep-the-index later to maint).
+
+ * Code clean-up to avoid non-standard-conformant pointer arithmetic.
+   (merge c112084af9 rs/no-null-ptr-arith-in-fast-export later to maint).
+
+ * Code clean-up to turn history traversal more robust in a
+   semi-corrupt repository.
+   (merge 8702b30fd7 jk/unavailable-can-be-missing later to maint).
+
+ * "git update-ref A B" is supposed to ensure that ref A does not yet
+   exist when B is a NULL OID, but this check was not done correctly
+   for pseudo-refs outside refs/ hierarchy, e.g. MERGE_HEAD.
+
+ * "git submodule update" and "git submodule add" supported the
+   "--reference" option to borrow objects from a neighbouring local
+   repository like "git clone" does, but lacked the more recent
+   invention "--dissociate".  Also "git submodule add" has been taught
+   to take the "--progress" option.
+   (merge a0ef29341a cf/submodule-progress-dissociate later to maint).
+
+ * Update credential-netrc helper (in contrib/) to allow customizing
+   the GPG used to decrypt the encrypted .netrc file.
+   (merge 786ef50a23 lm/credential-netrc later to maint).
+
+ * "git submodule update" attempts two different kinds of "git fetch"
+   against the upstream repository to grab a commit bound at the
+   submodule's path, but it incorrectly gave up if the first kind
+   (i.e. a normal fetch) failed, making the second "last resort" one
+   (i.e. fetching an exact commit object by object name) ineffective.
+   This has been corrected.
+   (merge e30d833671 sb/submodule-update-try-harder later to maint).
+
+ * Error behaviour of "git grep" when it cannot read the index was
+   inconsistent with other commands that uses the index, which has
+   been corrected to error out early.
+   (merge b2aa84c789 sb/grep-die-on-unreadable-index later to maint).
+
+ * We used to call regfree() after regcomp() failed in some codepaths,
+   which have been corrected.
+   (merge 17154b1576 ma/regex-no-regfree-after-comp-fail later to maint).
+
+ * The import-tars script (in contrib/) has been taught to handle
+   tarballs with overly long paths that use PAX extended headers.
+   (merge 12ecea46e3 pa/import-tars-long-names later to maint).
+
+ * "git rev-parse Y..." etc. misbehaved when given endpoints were
+   not committishes.
+   (merge 0ed556d38f en/rev-parse-invalid-range later to maint).
+
+ * "git pull --recurse-submodules --rebase", when the submodule
+   repository's history did not have anything common between ours and
+   the upstream's, failed to execute.  We need to fetch from them to
+   continue even in such a case.
+   (merge 4d36f88be7 jt/submodule-pull-recurse-rebase later to maint).
+
+ * "git remote update" can take both a single remote nickname and a
+   nickname for remote groups, but only one of them was documented.
+   (merge a97447a42a nd/remote-update-doc later to maint).
+
+ * "index-pack --strict" has been taught to make sure that it runs the
+   final object integrity checks after making the freshly indexed
+   packfile available to itself.
+   (merge 3737746120 jk/index-pack-maint later to maint).
+
+ * Make zlib inflate codepath more robust against versions of zlib
+   that clobber unused portion of outbuf.
+   (merge b611396e97 jl/zlib-restore-nul-termination later to maint).
+
+ * Fix old merge glitch in Documentation during v2.13-rc0 era.
+   (merge 28cb06020b mw/doc-merge-enumfix later to maint).
+
+ * The code to read compressed bitmap was not careful to avoid reading
+   past the end of the file, which has been corrected.
+   (merge 1140bf01ec jk/ewah-bounds-check later to maint).
+
+ * "make NO_ICONV=NoThanks" did not override NEEDS_LIBICONV
+   (i.e. linkage of -lintl, -liconv, etc. that are platform-specific
+   tweaks), which has been corrected.
+   (merge fdb1fbbc7d es/make-no-iconv later to maint).
+
+ * Other minor doc, test and build updates and code cleanups.
+   (merge 248f66ed8e nd/trace-with-env later to maint).
+   (merge 14ced5562c ys/bisect-object-id-missing-conversion-fix later to maint).
+   (merge 5988eb631a ab/doc-hash-brokenness later to maint).
+   (merge a4d4e32a70 pk/test-avoid-pipe-hiding-exit-status later to maint).
+   (merge 05e293c1ac jk/flockfile-stdio later to maint).
+   (merge e9184b0789 jk/t5561-missing-curl later to maint).
+   (merge b1801b85a3 nd/worktree-move later to maint).
+   (merge bbd374dd20 ak/bisect-doc-typofix later to maint).
+   (merge 4855f06fb3 mn/send-email-credential-doc later to maint).
+   (merge 8523b1e355 en/doc-typoes later to maint).
+   (merge 43b44ccfe7 js/t5404-path-fix later to maint).
+   (merge decf711fc1 ps/test-chmtime-get later to maint).
+   (merge 22d11a6e8e es/worktree-docs later to maint).
+   (merge 92a5dbbc22 tg/use-git-contacts later to maint).
+   (merge adc887221f tq/t1510 later to maint).
+   (merge bed21a8ad6 sg/doc-gc-quote-mismatch-fix later to maint).
+   (merge 73364e4f10 tz/doc-git-urls-reference later to maint).
+   (merge cd1e606bad bc/mailmap-self later to maint).
+   (merge f7997e3682 ao/config-api-doc later to maint).
+   (merge ee930754d8 jk/apply-p-doc later to maint).
+   (merge 011b648646 nd/pack-format-doc later to maint).
+   (merge 87a6bb701a sg/t5310-jgit-bitmap-test later to maint).
+   (merge f6b82970aa sg/t5516-fixes later to maint).
+   (merge 4362da078e sg/t7005-spaces-in-filenames-cleanup later to maint).
+   (merge 7d0ee47c11 js/test-unset-prereq later to maint).
+   (merge 5356a3c354 ah/misc-doc-updates later to maint).
+   (merge 92c4a7a129 nd/completion-aliasfiletype-typofix later to maint).
+   (merge 58bd77b66a nd/pack-unreachable-objects-doc later to maint).
+   (merge 4ed79d5203 sg/t6500-no-redirect-of-stdin later to maint).
+   (merge 17b8a2d6cd jk/config-blob-sans-repo later to maint).
+   (merge 590551ca2c rd/tag-doc-lightweight later to maint).
+   (merge 44f560fc16 rd/init-typo later to maint).
+   (merge f156a0934a rd/p4-doc-markup-env later to maint).
+   (merge 2a00502b14 tg/doc-sec-list later to maint).
+   (merge 47cc91310a jk/submodule-fsck-loose-fixup later to maint).
+   (merge efde7b725c rd/comment-typofix-in-sha1-file later to maint).
+   (merge 7eedad15df rd/diff-options-typofix later to maint).
+   (merge 58ebd936cc km/doc-workflows-typofix later to maint).
+   (merge 30aa96cdf8 rd/doc-remote-tracking-with-hyphen later to maint).
+   (merge cf317877e3 ks/branch-set-upstream later to maint).
+   (merge 8de19d6be8 sg/t7406-chain-fix later to maint).
diff --git a/Documentation/RelNotes/2.18.1.txt b/Documentation/RelNotes/2.18.1.txt
new file mode 100644 (file)
index 0000000..2098cdd
--- /dev/null
@@ -0,0 +1,6 @@
+Git v2.18.1 Release Notes
+=========================
+
+This release merges up the fixes that appear in v2.14.5 and in
+v2.17.2 to address the recently reported CVE-2018-17456; see the
+release notes for those versions for details.
index a1d0feca36fea36b84b587c1387eab53e3b870c6..24885444078b04cfe70cf9fd0b81c972f72b91bd 100644 (file)
@@ -176,6 +176,12 @@ that is fine, but please mark it as such.
 [[send-patches]]
 === Sending your patches.
 
+:security-ml: footnoteref:[security-ml,The Git Security mailing list: git-security@googlegroups.com]
+
+Before sending any patches, please note that patches that may be
+security relevant should be submitted privately to the Git Security
+mailing list{security-ml}, instead of the public mailing list.
+
 Learn to use format-patch and send-email if possible.  These commands
 are optimized for the workflow of sending patches, avoiding many ways
 your existing e-mail client that is optimized for "multipart/*" mime
@@ -259,17 +265,24 @@ patch, format it as "multipart/signed", not a text/plain message
 that starts with `-----BEGIN PGP SIGNED MESSAGE-----`.  That is
 not a text/plain, it's something else.
 
+:security-ml-ref: footnoteref:[security-ml]
+
+As mentioned at the beginning of the section, patches that may be
+security relevant should not be submitted to the public mailing list
+mentioned below, but should instead be sent privately to the Git
+Security mailing list{security-ml-ref}.
+
 Send your patch with "To:" set to the mailing list, with "cc:" listing
-people who are involved in the area you are touching (the output from
-`git blame $path` and `git shortlog --no-merges $path` would help to
+people who are involved in the area you are touching (the `git
+contacts` command in `contrib/contacts/` can help to
 identify them), to solicit comments and reviews.
 
-:1: footnote:[The current maintainer: gitster@pobox.com]
-:2: footnote:[The mailing list: git@vger.kernel.org]
+:current-maintainer: footnote:[The current maintainer: gitster@pobox.com]
+:git-ml: footnote:[The mailing list: git@vger.kernel.org]
 
 After the list reached a consensus that it is a good idea to apply the
-patch, re-send it with "To:" set to the maintainer{1} and "cc:" the
-list{2} for inclusion.
+patch, re-send it with "To:" set to the maintainer{current-maintainer} and "cc:" the
+list{git-ml} for inclusion.
 
 Do not forget to add trailers such as `Acked-by:`, `Reviewed-by:` and
 `Tested-by:` lines as necessary to credit people who helped your
index 4e0cff87f62f5d5c320e3dcea03f646416604bca..ab641bf5a9984b7ab2dfea787a0db5704f79a448 100644 (file)
@@ -530,6 +530,12 @@ core.autocrlf::
        This variable can be set to 'input',
        in which case no output conversion is performed.
 
+core.checkRoundtripEncoding::
+       A comma and/or whitespace separated list of encodings that Git
+       performs UTF-8 round trip checks on if they are used in an
+       `working-tree-encoding` attribute (see linkgit:gitattributes[5]).
+       The default value is `SHIFT-JIS`.
+
 core.symlinks::
        If false, symbolic links are checked out as small plain files that
        contain the link text. linkgit:git-update-index[1] and
@@ -898,6 +904,10 @@ core.notesRef::
 This setting defaults to "refs/notes/commits", and it can be overridden by
 the `GIT_NOTES_REF` environment variable.  See linkgit:git-notes[1].
 
+core.commitGraph::
+       Enable git commit graph feature. Allows reading from the
+       commit-graph file.
+
 core.sparseCheckout::
        Enable "sparse checkout" feature. See section "Sparse checkout" in
        linkgit:git-read-tree[1] for more information.
@@ -1058,6 +1068,10 @@ branch.<name>.rebase::
        "git pull" is run. See "pull.rebase" for doing this in a non
        branch-specific manner.
 +
+When `merges`, pass the `--rebase-merges` option to 'git rebase'
+so that the local merge commits are included in the rebase (see
+linkgit:git-rebase[1] for details).
++
 When preserve, also pass `--preserve-merges` along to 'git rebase'
 so that locally committed merge commits will not be flattened
 by running 'git pull'.
@@ -1088,6 +1102,16 @@ clean.requireForce::
        A boolean to make git-clean do nothing unless given -f,
        -i or -n.   Defaults to true.
 
+color.advice::
+       A boolean to enable/disable color in hints (e.g. when a push
+       failed, see `advice.*` for a list).  May be set to `always`,
+       `false` (or `never`) or `auto` (or `true`), in which case colors
+       are used only when the error output goes to a terminal. If
+       unset, then the value of `color.ui` is used (`auto` by default).
+
+color.advice.hint::
+       Use customized color for hints.
+
 color.branch::
        A boolean to enable/disable color in the output of
        linkgit:git-branch[1]. May be set to `always`,
@@ -1190,6 +1214,15 @@ color.pager::
        A boolean to enable/disable colored output when the pager is in
        use (default is true).
 
+color.push::
+       A boolean to enable/disable color in push errors. May be set to
+       `always`, `false` (or `never`) or `auto` (or `true`), in which
+       case colors are used only when the error output goes to a terminal.
+       If unset, then the value of `color.ui` is used (`auto` by default).
+
+color.push.error::
+       Use customized color for push errors.
+
 color.showBranch::
        A boolean to enable/disable color in the output of
        linkgit:git-show-branch[1]. May be set to `always`,
@@ -1218,6 +1251,42 @@ color.status.<slot>::
        status short-format), or
        `unmerged` (files which have unmerged changes).
 
+color.blame.repeatedLines::
+       Use the customized color for the part of git-blame output that
+       is repeated meta information per line (such as commit id,
+       author name, date and timezone). Defaults to cyan.
+
+color.blame.highlightRecent::
+       This can be used to color the metadata of a blame line depending
+       on age of the line.
++
+This setting should be set to a comma-separated list of color and date settings,
+starting and ending with a color, the dates should be set from oldest to newest.
+The metadata will be colored given the colors if the the line was introduced
+before the given timestamp, overwriting older timestamped colors.
++
+Instead of an absolute timestamp relative timestamps work as well, e.g.
+2.weeks.ago is valid to address anything older than 2 weeks.
++
+It defaults to 'blue,12 month ago,white,1 month ago,red', which colors
+everything older than one year blue, recent changes between one month and
+one year old are kept white, and lines introduced within the last month are
+colored red.
+
+blame.coloring::
+       This determines the coloring scheme to be applied to blame
+       output. It can be 'repeatedLines', 'highlightRecent',
+       or 'none' which is the default.
+
+color.transport::
+       A boolean to enable/disable color when pushes are rejected. May be
+       set to `always`, `false` (or `never`) or `auto` (or `true`), in which
+       case colors are used only when the error output goes to a terminal.
+       If unset, then the value of `color.ui` is used (`auto` by default).
+
+color.transport.rejected::
+       Use customized color when a push was rejected.
+
 color.ui::
        This variable determines the default value for variables such
        as `color.diff` and `color.grep` that control the use of color
@@ -1343,6 +1412,14 @@ credential.<url>.*::
 credentialCache.ignoreSIGHUP::
        Tell git-credential-cache--daemon to ignore SIGHUP, instead of quitting.
 
+completion.commands::
+       This is only used by git-completion.bash to add or remove
+       commands from the list of completed commands. Normally only
+       porcelain commands and a few select others are completed. You
+       can add more commands, separated by space, in this
+       variable. Prefixing the command with '-' will remove it from
+       the existing list.
+
 include::diff-config.txt[]
 
 difftool.<tool>.path::
@@ -1558,6 +1635,18 @@ gc.autoDetach::
        Make `git gc --auto` return immediately and run in background
        if the system supports it. Default is true.
 
+gc.bigPackThreshold::
+       If non-zero, all packs larger than this limit are kept when
+       `git gc` is run. This is very similar to `--keep-base-pack`
+       except that all packs that meet the threshold are kept, not
+       just the base pack. Defaults to zero. Common unit suffixes of
+       'k', 'm', or 'g' are supported.
++
+Note that if the number of kept packs is more than gc.autoPackLimit,
+this configuration variable is ignored, all packs except the base pack
+will be repacked. After this the number of packs should go below
+gc.autoPackLimit and gc.bigPackThreshold should be respected again.
+
 gc.logExpiry::
        If the file gc.log exists, then `git gc --auto` won't run
        unless that file is more than 'gc.logExpiry' old.  Default is
@@ -1957,6 +2046,7 @@ http.sslVersion::
        - tlsv1.0
        - tlsv1.1
        - tlsv1.2
+       - tlsv1.3
 
 +
 Can be overridden by the `GIT_SSL_VERSION` environment variable.
@@ -2421,6 +2511,7 @@ pack.window::
 pack.depth::
        The maximum delta depth used by linkgit:git-pack-objects[1] when no
        maximum depth is given on the command line. Defaults to 50.
+       Maximum value is 4095.
 
 pack.windowMemory::
        The maximum size of memory that is consumed by each thread
@@ -2457,7 +2548,8 @@ pack.deltaCacheLimit::
        The maximum size of a delta, that is cached in
        linkgit:git-pack-objects[1]. This cache is used to speed up the
        writing object phase by not having to recompute the final delta
-       result once the best match for all objects is found. Defaults to 1000.
+       result once the best match for all objects is found.
+       Defaults to 1000. Maximum value is 65535.
 
 pack.threads::
        Specifies the number of threads to spawn when searching for best
@@ -2616,6 +2708,10 @@ pull.rebase::
        pull" is run. See "branch.<name>.rebase" for setting this on a
        per-branch basis.
 +
+When `merges`, pass the `--rebase-merges` option to 'git rebase'
+so that the local merge commits are included in the rebase (see
+linkgit:git-rebase[1] for details).
++
 When preserve, also pass `--preserve-merges` along to 'git rebase'
 so that locally committed merge commits will not be flattened
 by running 'git pull'.
@@ -3118,6 +3214,18 @@ status.displayCommentPrefix::
        behavior of linkgit:git-status[1] in Git 1.8.4 and previous.
        Defaults to false.
 
+status.renameLimit::
+       The number of files to consider when performing rename detection
+       in linkgit:git-status[1] and linkgit:git-commit[1]. Defaults to
+       the value of diff.renameLimit.
+
+status.renames::
+       Whether and how Git detects renames in linkgit:git-status[1] and
+       linkgit:git-commit[1] .  If set to "false", rename detection is
+       disabled. If set to "true", basic rename detection is enabled.
+       If set to "copies" or "copy", Git will detect copies, as well.
+       Defaults to the value of diff.renames.
+
 status.showStash::
        If set to true, linkgit:git-status[1] will display the number of
        entries currently stashed away.
index 5ca942ab5e2d5dfd67ceb06c5991f446b207de90..77caa66c2f768b6e43322c4662f45b4191a163c0 100644 (file)
@@ -112,7 +112,8 @@ diff.orderFile::
 
 diff.renameLimit::
        The number of files to consider when performing the copy/rename
-       detection; equivalent to the 'git diff' option `-l`.
+       detection; equivalent to the 'git diff' option `-l`. This setting
+       has no effect if rename detection is turned off.
 
 diff.renames::
        Whether and how Git detects renames.  If set to "false",
index e3a44f03cdcee92098287bfccc9801fde042ef2b..41064909ee42bca9a5decd375bc62ad658ae3c81 100644 (file)
@@ -64,7 +64,7 @@ ifndef::git-format-patch[]
 endif::git-format-patch[]
 
 --indent-heuristic::
-       Enable the heuristic that shift diff hunk boundaries to make patches
+       Enable the heuristic that shifts diff hunk boundaries to make patches
        easier to read. This is the default.
 
 --no-indent-heuristic::
@@ -106,7 +106,7 @@ diff" algorithm internally.
        low-occurrence common elements".
 --
 +
-For instance, if you configured diff.algorithm variable to a
+For instance, if you configured the `diff.algorithm` variable to a
 non-default value and want to use the default one, then you
 have to use `--diff-algorithm=default` option.
 
@@ -133,7 +133,7 @@ These parameters can also be set individually with `--stat-width=<width>`,
        as file creations or deletions ("new" or "gone", optionally "+l"
        if it's a symlink) and mode changes ("+x" or "-x" for adding
        or removing executable bit respectively) in diffstat. The
-       information is put betwen the filename part and the graph
+       information is put between the filename part and the graph
        part. Implies `--stat`.
 
 --numstat::
@@ -350,7 +350,7 @@ ifndef::git-format-patch[]
        Warn if changes introduce conflict markers or whitespace errors.
        What are considered whitespace errors is controlled by `core.whitespace`
        configuration.  By default, trailing whitespaces (including
-       lines that solely consist of whitespaces) and a space character
+       lines that consist solely of whitespaces) and a space character
        that is immediately followed by a tab character inside the
        initial indent of the line are considered whitespace errors.
        Exits with non-zero status if problems are found. Not compatible
@@ -364,7 +364,7 @@ ifndef::git-format-patch[]
        this option is not given, and the configuration variable
        `diff.wsErrorHighlight` is not set, only whitespace errors in
        `new` lines are highlighted. The whitespace errors are colored
-       whith `color.diff.whitespace`.
+       with `color.diff.whitespace`.
 
 endif::git-format-patch[]
 
@@ -568,7 +568,7 @@ the normal order.
 --
 +
 Patterns have the same syntax and semantics as patterns used for
-fnmantch(3) without the FNM_PATHNAME flag, except a pathname also
+fnmatch(3) without the FNM_PATHNAME flag, except a pathname also
 matches a pattern if removing any number of the final pathname
 components matches the pattern.  For example, the pattern "`foo*bar`"
 matches "`fooasdfbar`" and "`foo/bar/baz/asdf`" but not "`foobarx`".
@@ -592,7 +592,7 @@ endif::git-format-patch[]
        Treat all files as text.
 
 --ignore-cr-at-eol::
-       Ignore carrige-return at the end of line when doing a comparison.
+       Ignore carriage-return at the end of line when doing a comparison.
 
 --ignore-space-at-eol::
        Ignore changes in whitespace at EOL.
index 8631e365f437fd85058bed3dbd0cebde15756ccc..97d3217df9ac3f048073f62a0d5356c4546354ff 100644 (file)
@@ -188,6 +188,14 @@ endif::git-pull[]
        is specified. This flag forces progress status even if the
        standard error stream is not directed to a terminal.
 
+-o <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.
+       When multiple `--server-option=<option>` are given, they are all
+       sent to the other side in the order listed on the command line.
+
 -4::
 --ipv4::
        Use IPv4 addresses only, ignoring IPv6 addresses.
index d50fa339dcc523158896fda8cdccd1a2784dfdd7..45652fe4a6a51c251f773776576956745701d677 100644 (file)
@@ -193,7 +193,7 @@ for "git add --no-all <pathspec>...", i.e. ignored removed files.
        for command-line options).
 
 
-Configuration
+CONFIGURATION
 -------------
 
 The optional configuration variable `core.excludesFile` indicates a path to a
@@ -226,7 +226,7 @@ Because this example lets the shell expand the asterisk (i.e. you are
 listing the files explicitly), it does not consider
 `subdir/git-foo.sh`.
 
-Interactive mode
+INTERACTIVE MODE
 ----------------
 When the command enters the interactive mode, it shows the
 output of the 'status' subcommand, and then goes into its
index 05fd482b74ed00445613c7cc9b8a0b019ae31550..e44a831339d4a6d7f9ca3d9879dbb5a9b4ffac0a 100644 (file)
@@ -8,7 +8,7 @@ git-annotate - Annotate file lines with commit information
 SYNOPSIS
 --------
 [verse]
-'git annotate' [options] file [revision]
+'git annotate' [<options>] <file> [<revision>]
 
 DESCRIPTION
 -----------
index 4ebc3d32719dfefa988d34b41871f0e9fb969471..67228494c00e1df676723072d0884f7705e532f1 100644 (file)
@@ -113,8 +113,10 @@ explained for the configuration variable `core.quotePath` (see
 linkgit:git-config[1]).
 
 -p<n>::
-       Remove <n> leading slashes from traditional diff paths. The
-       default is 1.
+       Remove <n> leading path components (separated by slashes) from
+       traditional diff paths. E.g., with `-p2`, a patch against
+       `a/dir/file` will be applied directly to `file`. The default is
+       1.
 
 -C<n>::
        Ensure at least <n> lines of surrounding context match before
@@ -240,7 +242,7 @@ When `git apply` is used as a "better GNU patch", the user can pass
 the `--unsafe-paths` option to override this safety check.  This option
 has no effect when `--index` or `--cached` is in use.
 
-Configuration
+CONFIGURATION
 -------------
 
 apply.ignoreWhitespace::
@@ -251,7 +253,7 @@ apply.whitespace::
        When no `--whitespace` flag is given from the command
        line, this configuration item is used as the default.
 
-Submodules
+SUBMODULES
 ----------
 If the patch contains any changes to submodules then 'git apply'
 treats these changes as follows.
index 4a1417bdcd7826d444dbfd4cbc438ec9ec2edf1b..4b45d837a7e7c590fe3aa5f575009c43342b833c 100644 (file)
@@ -165,8 +165,8 @@ To get a reminder of the currently used terms, use
 git bisect terms
 ------------------------------------------------
 
-You can get just the old (respectively new) term with `git bisect term
---term-old` or `git bisect term --term-good`.
+You can get just the old (respectively new) term with `git bisect terms
+--term-old` or `git bisect terms --term-good`.
 
 If you would like to use your own terms instead of "bad"/"good" or
 "new"/"old", you can choose any names you like (except existing bisect
index b3084c99c1cabdccc690e4cec5071b22774bf6c8..02eccbb931eb1ffe6e4c018927eebce8eb98f124 100644 (file)
@@ -287,7 +287,7 @@ CONFIGURATION
 `--list` is used or implied. The default is to use a pager.
 See linkgit:git-config[1].
 
-Examples
+EXAMPLES
 --------
 
 Start development from a known tag::
@@ -318,7 +318,7 @@ See linkgit:git-fetch[1].
 is currently checked out) does not have all commits from the test branch.
 
 
-Notes
+NOTES
 -----
 
 If you are creating a branch that you want to checkout immediately, it is
index 3a8120c3b3795784cb05211bcde959a224f0a867..7d6c9dcd177b6a1fa4a6184b230480aa08e07120 100644 (file)
@@ -92,8 +92,8 @@ It is okay to err on the side of caution, causing the bundle file
 to contain objects already in the destination, as these are ignored
 when unpacking at the destination.
 
-EXAMPLE
--------
+EXAMPLES
+--------
 
 Assume you want to transfer the history from a repository R1 on machine A
 to another repository R2 on machine B.
index aa3b2bf2fcf764ca22f44bcfc081afd4e09328bb..3c0578217ba7f92f823e545021c5c06c31566f0d 100644 (file)
@@ -9,8 +9,8 @@ git-check-attr - Display gitattributes information
 SYNOPSIS
 --------
 [verse]
-'git check-attr' [-a | --all | attr...] [--] pathname...
-'git check-attr' --stdin [-z] [-a | --all | attr...]
+'git check-attr' [-a | --all | <attr>...] [--] <pathname>...
+'git check-attr' --stdin [-z] [-a | --all | <attr>...]
 
 DESCRIPTION
 -----------
index 611754f10bb86d62edcb3265cc29ccdc97c259ae..8b42cb3fb20a78cde2eb4c6a7546a334cc71ec4b 100644 (file)
@@ -9,8 +9,8 @@ git-check-ignore - Debug gitignore / exclude files
 SYNOPSIS
 --------
 [verse]
-'git check-ignore' [options] pathname...
-'git check-ignore' [options] --stdin
+'git check-ignore' [<options>] <pathname>...
+'git check-ignore' [<options>] --stdin
 
 DESCRIPTION
 -----------
index 39028ee1a34e63325d68bb900854b4fe8aa66457..aa2055dbebcd4237e7557db7926700c933f8ac94 100644 (file)
@@ -9,7 +9,7 @@ git-check-mailmap - Show canonical names and email addresses of contacts
 SYNOPSIS
 --------
 [verse]
-'git check-mailmap' [options] <contact>...
+'git check-mailmap' [<options>] <contact>...
 
 
 DESCRIPTION
index 42ca7b50956aa8560b6aa58b5d7741913c145a43..a55536f0bfb2dfa3774e1b952ac4dee1eea6e505 100644 (file)
@@ -260,7 +260,7 @@ or `--mirror` is given)
 
 <repository>::
        The (possibly remote) repository to clone from.  See the
-       <<URLS,URLS>> section below for more information on specifying
+       <<URLS,GIT URLS>> section below for more information on specifying
        repositories.
 
 <directory>::
@@ -273,7 +273,7 @@ or `--mirror` is given)
 :git-clone: 1
 include::urls.txt[]
 
-Examples
+EXAMPLES
 --------
 
 * Clone from upstream:
diff --git a/Documentation/git-commit-graph.txt b/Documentation/git-commit-graph.txt
new file mode 100644 (file)
index 0000000..4c97b55
--- /dev/null
@@ -0,0 +1,94 @@
+git-commit-graph(1)
+===================
+
+NAME
+----
+git-commit-graph - Write and verify Git commit graph files
+
+
+SYNOPSIS
+--------
+[verse]
+'git commit-graph read' [--object-dir <dir>]
+'git commit-graph write' <options> [--object-dir <dir>]
+
+
+DESCRIPTION
+-----------
+
+Manage the serialized commit graph file.
+
+
+OPTIONS
+-------
+--object-dir::
+       Use given directory for the location of packfiles and commit graph
+       file. This parameter exists to specify the location of an alternate
+       that only has the objects directory, not a full .git directory. The
+       commit graph file is expected to be at <dir>/info/commit-graph and
+       the packfiles are expected to be in <dir>/pack.
+
+
+COMMANDS
+--------
+'write'::
+
+Write a commit graph file based on the commits found in packfiles.
++
+With the `--stdin-packs` option, generate the new commit graph by
+walking objects only in the specified pack-indexes. (Cannot be combined
+with --stdin-commits.)
++
+With the `--stdin-commits` option, generate the new commit graph by
+walking commits starting at the commits specified in stdin as a list
+of OIDs in hex, one OID per line. (Cannot be combined with
+--stdin-packs.)
++
+With the `--append` option, include all commits that are present in the
+existing commit-graph file.
+
+'read'::
+
+Read a graph file given by the commit-graph file and output basic
+details about the graph file. Used for debugging purposes.
+
+
+EXAMPLES
+--------
+
+* Write a commit graph file for the packed commits in your local .git folder.
++
+------------------------------------------------
+$ git commit-graph write
+------------------------------------------------
+
+* Write a graph file, extending the current graph file using commits
+* in <pack-index>.
++
+------------------------------------------------
+$ echo <pack-index> | git commit-graph write --stdin-packs
+------------------------------------------------
+
+* Write a graph file containing all reachable commits.
++
+------------------------------------------------
+$ git show-ref -s | git commit-graph write --stdin-commits
+------------------------------------------------
+
+* Write a graph file containing all commits in the current
+* commit-graph file along with those reachable from HEAD.
++
+------------------------------------------------
+$ git rev-parse HEAD | git commit-graph write --stdin-commits --append
+------------------------------------------------
+
+* Read basic information from the commit-graph file.
++
+------------------------------------------------
+$ git commit-graph read
+------------------------------------------------
+
+
+GIT
+---
+Part of the linkgit:git[1] suite
index e09ed5d7d5147d93039c479efc8ab450bf5ca8b4..18ddc78f42d69724cf5a04087a7dbd13c5ebf711 100644 (file)
@@ -9,13 +9,13 @@ git-config - Get and set repository or global options
 SYNOPSIS
 --------
 [verse]
-'git config' [<file-option>] [type] [--show-origin] [-z|--null] name [value [value_regex]]
-'git config' [<file-option>] [type] --add name value
-'git config' [<file-option>] [type] --replace-all name value [value_regex]
-'git config' [<file-option>] [type] [--show-origin] [-z|--null] --get name [value_regex]
-'git config' [<file-option>] [type] [--show-origin] [-z|--null] --get-all name [value_regex]
-'git config' [<file-option>] [type] [--show-origin] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
-'git config' [<file-option>] [type] [-z|--null] --get-urlmatch name URL
+'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] name [value [value_regex]]
+'git config' [<file-option>] [--type=<type>] --add name value
+'git config' [<file-option>] [--type=<type>] --replace-all name value [value_regex]
+'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] --get name [value_regex]
+'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] --get-all name [value_regex]
+'git config' [<file-option>] [--type=<type>] [--show-origin] [-z|--null] [--name-only] --get-regexp name_regex [value_regex]
+'git config' [<file-option>] [--type=<type>] [-z|--null] --get-urlmatch name URL
 'git config' [<file-option>] --unset name [value_regex]
 'git config' [<file-option>] --unset-all name [value_regex]
 'git config' [<file-option>] --rename-section old_name new_name
@@ -38,12 +38,10 @@ existing values that match the regexp are updated or unset.  If
 you want to handle the lines that do *not* match the regex, just
 prepend a single exclamation mark in front (see also <<EXAMPLES>>).
 
-The type specifier can be either `--int` or `--bool`, to make
-'git config' ensure that the variable(s) are of the given type and
-convert the value to the canonical form (simple decimal number for int,
-a "true" or "false" string for bool), or `--path`, which does some
-path expansion (see `--path` below).  If no type specifier is passed, no
-checks or transformations are performed on the value.
+The `--type=<type>` option instructs 'git config' to ensure that incoming and
+outgoing values are canonicalize-able under the given <type>.  If no
+`--type=<type>` is given, no canonicalization will be performed. Callers may
+unset an existing `--type` specifier with `--no-type`.
 
 When reading, the values are read from the system, global and
 repository local configuration files by default, and options
@@ -160,30 +158,43 @@ See also <<FILES>>.
 --list::
        List all variables set in config file, along with their values.
 
---bool::
-       'git config' will ensure that the output is "true" or "false"
+--type <type>::
+  'git config' will ensure that any input or output is valid under the given
+  type constraint(s), and will canonicalize outgoing values in `<type>`'s
+  canonical form.
++
+Valid `<type>`'s include:
++
+- 'bool': canonicalize values as either "true" or "false".
+- 'int': canonicalize values as simple decimal numbers. An optional suffix of
+  'k', 'm', or 'g' will cause the value to be multiplied by 1024, 1048576, or
+  1073741824 upon input.
+- 'bool-or-int': canonicalize according to either 'bool' or 'int', as described
+  above.
+- 'path': canonicalize by adding a leading `~` to the value of `$HOME` and
+  `~user` to the home directory for the specified user. This specifier has no
+  effect when setting the value (but you can use `git config section.variable
+  ~/` from the command line to let your shell do the expansion.)
+- 'expiry-date': canonicalize by converting from a fixed or relative date-string
+  to a timestamp. This specifier has no effect when setting the value.
+- 'color': When getting a value, canonicalize by converting to an ANSI color
+  escape sequence. When setting a value, a sanity-check is performed to ensure
+  that the given value is canonicalize-able as an ANSI color, but it is written
+  as-is.
++
 
+--bool::
 --int::
-       'git config' will ensure that the output is a simple
-       decimal number.  An optional value suffix of 'k', 'm', or 'g'
-       in the config file will cause the value to be multiplied
-       by 1024, 1048576, or 1073741824 prior to output.
-
 --bool-or-int::
-       'git config' will ensure that the output matches the format of
-       either --bool or --int, as described above.
-
 --path::
-       `git config` will expand a leading `~` to the value of
-       `$HOME`, and `~user` to the home directory for the
-       specified user.  This option has no effect when setting the
-       value (but you can use `git config section.variable ~/`
-       from the command line to let your shell do the expansion).
-
 --expiry-date::
-       `git config` will ensure that the output is converted from
-       a fixed or relative date-string to a timestamp. This option
-       has no effect when setting the value.
+  Historical options for selecting a type specifier. Prefer instead `--type`,
+  (see: above).
+
+--no-type::
+  Un-sets the previously set type specifier (if one was previously set). This
+  option requests that 'git config' not canonicalize the retrieved variable.
+  `--no-type` has no effect without `--type=<type>` or `--<type>`.
 
 -z::
 --null::
@@ -221,6 +232,8 @@ See also <<FILES>>.
        output it as the ANSI color escape sequence to the standard
        output.  The optional `default` parameter is used instead, if
        there is no color configured for `name`.
++
+`--type=color [--default=<default>]` is preferred over `--get-color`.
 
 -e::
 --edit::
@@ -233,6 +246,10 @@ See also <<FILES>>.
        using `--file`, `--global`, etc) and `on` when searching all
        config files.
 
+--default <value>::
+  When using `--get`, and the requested variable is not found, behave as if
+  <value> were the value assigned to the that variable.
+
 CONFIGURATION
 -------------
 `pager.config` is only respected when listing configuration, i.e., when
index 2b8582639332acb4d3e81273c6a90163a3a8b378..0216c18ef80c9a9d32095ec3969091aff1c20344 100644 (file)
@@ -8,7 +8,7 @@ git-credential-cache - Helper to temporarily store passwords in memory
 SYNOPSIS
 --------
 -----------------------------
-git config credential.helper 'cache [options]'
+git config credential.helper 'cache [<options>]'
 -----------------------------
 
 DESCRIPTION
index 25fb963f4b06695bb0c5fcf9a1feed97dfc549ed..693dd9d9d760fe2a113d4e15ab7816f34b2cd47d 100644 (file)
@@ -8,7 +8,7 @@ git-credential-store - Helper to store credentials on disk
 SYNOPSIS
 --------
 -------------------
-git config credential.helper 'store [options]'
+git config credential.helper 'store [<options>]'
 -------------------
 
 DESCRIPTION
index ba90066f108cf525eb7781c1607d65358c617b0e..f98b7c6ed7c0fe4df8a0e3211eaa53ea7c95d5d9 100644 (file)
@@ -22,7 +22,7 @@ cvspserver stream tcp nowait nobody /usr/bin/git-cvsserver git-cvsserver pserver
 Usage:
 
 [verse]
-'git-cvsserver' [options] [pserver|server] [<directory> ...]
+'git-cvsserver' [<options>] [pserver|server] [<directory> ...]
 
 OPTIONS
 -------
@@ -207,7 +207,7 @@ allowing access over SSH.
 ------
 
 [[dbbackend]]
-Database Backend
+DATABASE BACKEND
 ----------------
 
 'git-cvsserver' uses one database per Git head (i.e. CVS module) to
@@ -321,7 +321,7 @@ git-cvsserver, as described above.
 When these environment variables are set, the corresponding
 command-line arguments may not be used.
 
-Eclipse CVS Client Notes
+ECLIPSE CVS CLIENT NOTES
 ------------------------
 
 To get a checkout with the Eclipse CVS client:
@@ -346,7 +346,7 @@ offer. In that case CVS_SERVER is ignored, and you will have to replace
 the cvs utility on the server with 'git-cvsserver' or manipulate your `.bashrc`
 so that calling 'cvs' effectively calls 'git-cvsserver'.
 
-Clients known to work
+CLIENTS KNOWN TO WORK
 ---------------------
 
 - CVS 1.12.9 on Debian
@@ -354,7 +354,7 @@ Clients known to work
 - Eclipse 3.0, 3.1.2 on MacOSX (see Eclipse CVS Client Notes)
 - TortoiseCVS
 
-Operations supported
+OPERATIONS SUPPORTED
 --------------------
 
 All the operations required for normal use are supported, including
@@ -424,7 +424,7 @@ For best consistency with 'cvs', it is probably best to override the
 defaults by setting `gitcvs.usecrlfattr` to true,
 and `gitcvs.allBinary` to "guess".
 
-Dependencies
+DEPENDENCIES
 ------------
 'git-cvsserver' depends on DBD::SQLite.
 
index b380677718ae129b4643814d7c1a16351ce4d779..f4bd8155c0a707308162e050d5d59b5dbd5ca7a6 100644 (file)
@@ -37,14 +37,14 @@ include::diff-options.txt[]
 
 include::diff-format.txt[]
 
-Operating Modes
+OPERATING MODES
 ---------------
 You can choose whether you want to trust the index file entirely
 (using the `--cached` flag) or ask the diff logic to show any files
 that don't match the stat state as being "tentatively changed".  Both
 of these operations are very useful indeed.
 
-Cached Mode
+CACHED MODE
 -----------
 If `--cached` is specified, it allows you to ask:
 
@@ -77,7 +77,7 @@ So doing a `git diff-index --cached` is basically very useful when you are
 asking yourself "what have I already marked for being committed, and
 what's the difference to a previous tree".
 
-Non-cached Mode
+NON-CACHED MODE
 ---------------
 The "non-cached" mode takes a different approach, and is potentially
 the more useful of the two in that what it does can't be emulated with
index 7870e175b7683ffcdbdc98d3f669998c615c2ffd..2319b2b19209467bf5796abf8df425c6118dadac 100644 (file)
@@ -116,7 +116,7 @@ include::pretty-options.txt[]
 include::pretty-formats.txt[]
 
 
-Limiting Output
+LIMITING OUTPUT
 ---------------
 If you're only interested in differences in a subset of files, for
 example some architecture-specific files, you might do:
index b0c1bb95c83b8e8e6cf6fa863e74108e3e5fc35f..b180f1fa5bf5599efd8c8fefe29e3249cd387715 100644 (file)
@@ -9,11 +9,11 @@ git-diff - Show changes between commits, commit and working tree, etc
 SYNOPSIS
 --------
 [verse]
-'git diff' [options] [<commit>] [--] [<path>...]
-'git diff' [options] --cached [<commit>] [--] [<path>...]
-'git diff' [options] <commit> <commit> [--] [<path>...]
-'git diff' [options] <blob> <blob>
-'git diff' [options] [--no-index] [--] <path> <path>
+'git diff' [<options>] [<commit>] [--] [<path>...]
+'git diff' [<options>] --cached [<commit>] [--] [<path>...]
+'git diff' [<options>] <commit> <commit> [--] [<path>...]
+'git diff' [<options>] <blob> <blob>
+'git diff' [<options>] --no-index [--] <path> <path>
 
 DESCRIPTION
 -----------
@@ -21,7 +21,7 @@ Show changes between the working tree and the index or a tree, changes
 between the index and a tree, changes between two trees, changes between
 two blob objects, or changes between two files on disk.
 
-'git diff' [--options] [--] [<path>...]::
+'git diff' [<options>] [--] [<path>...]::
 
        This form is to view the changes you made relative to
        the index (staging area for the next commit).  In other
@@ -29,7 +29,7 @@ two blob objects, or changes between two files on disk.
        further add to the index but you still haven't.  You can
        stage these changes by using linkgit:git-add[1].
 
-'git diff' --no-index [--options] [--] [<path>...]::
+'git diff' [<options>] --no-index [--] <path> <path>::
 
        This form is to compare the given two paths on the
        filesystem.  You can omit the `--no-index` option when
@@ -38,7 +38,7 @@ two blob objects, or changes between two files on disk.
        or when running the command outside a working tree
        controlled by Git.
 
-'git diff' [--options] --cached [<commit>] [--] [<path>...]::
+'git diff' [<options>] --cached [<commit>] [--] [<path>...]::
 
        This form is to view the changes you staged for the next
        commit relative to the named <commit>.  Typically you
@@ -48,7 +48,7 @@ two blob objects, or changes between two files on disk.
        <commit> is not given, it shows all staged changes.
        --staged is a synonym of --cached.
 
-'git diff' [--options] <commit> [--] [<path>...]::
+'git diff' [<options>] <commit> [--] [<path>...]::
 
        This form is to view the changes you have in your
        working tree relative to the named <commit>.  You can
@@ -56,18 +56,18 @@ two blob objects, or changes between two files on disk.
        branch name to compare with the tip of a different
        branch.
 
-'git diff' [--options] <commit> <commit> [--] [<path>...]::
+'git diff' [<options>] <commit> <commit> [--] [<path>...]::
 
        This is to view the changes between two arbitrary
        <commit>.
 
-'git diff' [--options] <commit>..<commit> [--] [<path>...]::
+'git diff' [<options>] <commit>..<commit> [--] [<path>...]::
 
        This is synonymous to the previous form.  If <commit> on
        one side is omitted, it will have the same effect as
        using HEAD instead.
 
-'git diff' [--options] <commit>\...<commit> [--] [<path>...]::
+'git diff' [<options>] <commit>\...<commit> [--] [<path>...]::
 
        This form is to view the changes on the branch containing
        and up to the second <commit>, starting at a common ancestor
@@ -87,7 +87,7 @@ and the range notations ("<commit>..<commit>" and
 "<commit>\...<commit>") do not mean a range as defined in the
 "SPECIFYING RANGES" section in linkgit:gitrevisions[7].
 
-'git diff' [options] <blob> <blob>::
+'git diff' [<options>] <blob> <blob>::
 
        This form is to view the differences between the raw
        contents of two blob objects.
index ed57c684dbc82c587ca1cf6b66ae46f3760ecfba..ce954be5321384b55687791acb32562850a5a6fa 100644 (file)
@@ -9,7 +9,7 @@ git-fast-export - Git data exporter
 SYNOPSIS
 --------
 [verse]
-'git fast-export [options]' | 'git fast-import'
+'git fast-export [<options>]' | 'git fast-import'
 
 DESCRIPTION
 -----------
@@ -202,7 +202,7 @@ smaller output, and it is usually easy to quickly confirm that there is
 no private data in the stream.
 
 
-Limitations
+LIMITATIONS
 -----------
 
 Since 'git fast-import' cannot tag trees, you will not be
index ff71fc29626dfc83bf7145520b58dbd30ad4967a..9e3b9581d76d7e7146423d857f27f1067710b580 100644 (file)
@@ -9,7 +9,7 @@ git-fast-import - Backend for fast Git data importers
 SYNOPSIS
 --------
 [verse]
-frontend | 'git fast-import' [options]
+frontend | 'git fast-import' [<options>]
 
 DESCRIPTION
 -----------
@@ -154,7 +154,7 @@ Performance and Compression Tuning
 fastimport.unpackLimit::
        See linkgit:git-config[1]
 
-Performance
+PERFORMANCE
 -----------
 The design of fast-import allows it to import large projects in a minimum
 amount of memory usage and processing time.  Assuming the frontend
@@ -170,7 +170,7 @@ faster if the source data is stored on a different drive than the
 destination Git repository (due to less IO contention).
 
 
-Development Cost
+DEVELOPMENT COST
 ----------------
 A typical frontend for fast-import tends to weigh in at approximately 200
 lines of Perl/Python/Ruby code.  Most developers have been able to
@@ -180,7 +180,7 @@ an ideal situation, given that most conversion tools are throw-away
 (use once, and never look back).
 
 
-Parallel Operation
+PARALLEL OPERATION
 ------------------
 Like 'git push' or 'git fetch', imports handled by fast-import are safe to
 run alongside parallel `git repack -a -d` or `git gc` invocations,
@@ -201,7 +201,7 @@ this only be used on an otherwise quiet repository.  Using --force
 is not necessary for an initial import into an empty repository.
 
 
-Technical Discussion
+TECHNICAL DISCUSSION
 --------------------
 fast-import tracks a set of branches in memory.  Any branch can be created
 or modified at any point during the import process by sending a
@@ -219,7 +219,7 @@ directory also allows fast-import to run very quickly, as it does not
 need to perform any costly file update operations when switching
 between branches.
 
-Input Format
+INPUT FORMAT
 ------------
 With the exception of raw file data (which Git does not interpret)
 the fast-import input format is text (ASCII) based.  This text based
@@ -1146,7 +1146,7 @@ If the `--done` command-line option or `feature done` command is
 in use, the `done` command is mandatory and marks the end of the
 stream.
 
-Responses To Commands
+RESPONSES TO COMMANDS
 ---------------------
 New objects written by fast-import are not available immediately.
 Most fast-import commands have no visible effect until the next
@@ -1175,7 +1175,7 @@ To avoid deadlock, such frontends must completely consume any
 pending output from `progress`, `ls`, `get-mark`, and `cat-blob` before
 performing writes to fast-import that might block.
 
-Crash Reports
+CRASH REPORTS
 -------------
 If fast-import is supplied invalid input it will terminate with a
 non-zero exit status and create a crash report in the top level of
@@ -1262,7 +1262,7 @@ An example crash:
        END OF CRASH REPORT
 ====
 
-Tips and Tricks
+TIPS AND TRICKS
 ---------------
 The following tips and tricks have been collected from various
 users of fast-import, and are offered here as suggestions.
@@ -1364,7 +1364,7 @@ Your users will feel better knowing how much of the data stream
 has been processed.
 
 
-Packfile Optimization
+PACKFILE OPTIMIZATION
 ---------------------
 When packing a blob fast-import always attempts to deltify against the last
 blob written.  Unless specifically arranged for by the frontend,
@@ -1395,7 +1395,7 @@ to force recomputation of all deltas can significantly reduce the
 final packfile size (30-50% smaller can be quite typical).
 
 
-Memory Utilization
+MEMORY UTILIZATION
 ------------------
 There are a number of factors which affect how much memory fast-import
 requires to perform an import.  Like critical sections of core
@@ -1473,7 +1473,7 @@ and lazy loading of subtrees, allows fast-import to efficiently import
 projects with 2,000+ branches and 45,114+ files in a very limited
 memory footprint (less than 2.7 MiB per active branch).
 
-Signals
+SIGNALS
 -------
 Sending *SIGUSR1* to the 'git fast-import' process ends the current
 packfile early, simulating a `checkpoint` command.  The impatient
index f7ebe36a7b2c203e0b2f320309a5ce6250b12471..c9758847937e7db9fb3c4c3a498f5074e9e1f5d9 100644 (file)
@@ -88,7 +88,7 @@ be in a separate packet, and the list must end with a flush packet.
        infinite even if there is an ancestor-chain that long.
 
 --shallow-since=<date>::
-       Deepen or shorten the history of a shallow'repository to
+       Deepen or shorten the history of a shallow repository to
        include all reachable commits after <date>.
 
 --shallow-exclude=<revision>::
index 3a52e4dce39eeaf6eba896ccbf9e0505cebb3ec9..e6f08ab189489ec1631169d0ad0b190428883235 100644 (file)
@@ -222,7 +222,15 @@ this purpose, they are instead rewritten to point at the nearest ancestor that
 was not excluded.
 
 
-Examples
+EXIT STATUS
+-----------
+
+On success, the exit status is `0`.  If the filter can't find any commits to
+rewrite, the exit status is `2`.  On any other error, the exit status may be
+any other non-zero value.
+
+
+EXAMPLES
 --------
 
 Suppose you want to remove a file (containing confidential information
@@ -280,7 +288,7 @@ git filter-branch --parent-filter \
 or even simpler:
 
 -----------------------------------------------
-echo "$commit-id $graft-id" >> .git/info/grafts
+git replace --graft $commit-id $graft-id
 git filter-branch $graft-id..HEAD
 -----------------------------------------------
 
@@ -398,7 +406,7 @@ git filter-branch --index-filter \
 
 
 
-Checklist for Shrinking a Repository
+CHECKLIST FOR SHRINKING A REPOSITORY
 ------------------------------------
 
 git-filter-branch can be used to get rid of a subset of files,
@@ -437,7 +445,7 @@ warned.
   (or if your git-gc is not new enough to support arguments to
   `--prune`, use `git repack -ad; git prune` instead).
 
-Notes
+NOTES
 -----
 
 git-filter-branch allows you to make complex shell-scripted rewrites
index 44892c447e79f1d06435357b30f4ddbbb465e5f1..423b6e033ba512f8a8ed6fe3f0ee6ef158dd5234 100644 (file)
@@ -57,8 +57,8 @@ merge.summary::
        Synonym to `merge.log`; this is deprecated and will be removed in
        the future.
 
-EXAMPLE
--------
+EXAMPLES
+--------
 
 ---------
 $ git fetch origin master
index dffa14a7950e074bbff73ec79defdbbdcc9702be..085d177d976546a0b21891884e490c9ce7530913 100644 (file)
@@ -121,7 +121,7 @@ refname::
        stripping with positive <N>, or it becomes the full refname if
        stripping with negative <N>.  Neither is an error.
 +
-`strip` can be used as a synomym to `lstrip`.
+`strip` can be used as a synonym to `lstrip`.
 
 objecttype::
        The type of the object (`blob`, `tree`, `commit`, `tag`).
index 6cbe462a77467b05561938ff9cf8e9dcebd42efe..b41e1329a7d8439762790e663ac52ec5f487bc8b 100644 (file)
@@ -47,7 +47,7 @@ There are two ways to specify which commits to operate on.
 
 The first rule takes precedence in the case of a single <commit>.  To
 apply the second rule, i.e., format everything since the beginning of
-history up until <commit>, use the '\--root' option: `git format-patch
+history up until <commit>, use the `--root` option: `git format-patch
 --root <commit>`.  If you want to format only <commit> itself, you
 can do this with `git format-patch -1 <commit>`.
 
index 571b5a7e3c9dbc11aafc194b6e08dbbed5b2f7d3..24b2dd44fe445a66121fa957f0af8e2209a85676 100644 (file)
@@ -9,14 +9,15 @@ git-gc - Cleanup unnecessary files and optimize the local repository
 SYNOPSIS
 --------
 [verse]
-'git gc' [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune] [--force]
+'git gc' [--aggressive] [--auto] [--quiet] [--prune=<date> | --no-prune] [--force] [--keep-largest-pack]
 
 DESCRIPTION
 -----------
 Runs a number of housekeeping tasks within the current repository,
 such as compressing file revisions (to reduce disk space and increase
-performance) and removing unreachable objects which may have been
-created from prior invocations of 'git add'.
+performance), removing unreachable objects which may have been
+created from prior invocations of 'git add', packing refs, pruning
+reflog, rerere metadata or stale working trees.
 
 Users are encouraged to run this task on a regular basis within
 each repository to maintain good disk space utilization and good
@@ -45,20 +46,31 @@ OPTIONS
        With this option, 'git gc' checks whether any housekeeping is
        required; if not, it exits without performing any work.
        Some git commands run `git gc --auto` after performing
-       operations that could create many loose objects.
+       operations that could create many loose objects. Housekeeping
+       is required if there are too many loose objects or too many
+       packs in the repository.
 +
-Housekeeping is required if there are too many loose objects or
-too many packs in the repository. If the number of loose objects
-exceeds the value of the `gc.auto` configuration variable, then
-all loose objects are combined into a single pack using
-`git repack -d -l`.  Setting the value of `gc.auto` to 0
-disables automatic packing of loose objects.
+If the number of loose objects exceeds the value of the `gc.auto`
+configuration variable, then all loose objects are combined into a
+single pack using `git repack -d -l`.  Setting the value of `gc.auto`
+to 0 disables automatic packing of loose objects.
 +
 If the number of packs exceeds the value of `gc.autoPackLimit`,
-then existing packs (except those marked with a `.keep` file)
+then existing packs (except those marked with a `.keep` file
+or over `gc.bigPackThreshold` limit)
 are consolidated into a single pack by using the `-A` option of
-'git repack'. Setting `gc.autoPackLimit` to 0 disables
-automatic consolidation of packs.
+'git repack'.
+If the amount of memory is estimated not enough for `git repack` to
+run smoothly and `gc.bigPackThreshold` is not set, the largest
+pack will also be excluded (this is the equivalent of running `git gc`
+with `--keep-base-pack`).
+Setting `gc.autoPackLimit` to 0 disables automatic consolidation of
+packs.
++
+If houskeeping is required due to many loose objects or packs, all
+other housekeeping tasks (e.g. rerere, working trees, reflog...) will
+be performed as well.
+
 
 --prune=<date>::
        Prune loose objects older than date (default is 2 weeks ago,
@@ -78,7 +90,12 @@ automatic consolidation of packs.
        Force `git gc` to run even if there may be another `git gc`
        instance running on this repository.
 
-Configuration
+--keep-largest-pack::
+       All packs except the largest pack and those marked with a
+       `.keep` files are consolidated into a single pack. When this
+       option is used, `gc.bigPackThreshold` is ignored.
+
+CONFIGURATION
 -------------
 
 The optional configuration variable `gc.reflogExpire` can be
@@ -123,7 +140,7 @@ The optional configuration variable `gc.aggressiveWindow` controls how
 much time is spent optimizing the delta compression of the objects in
 the repository when the --aggressive option is specified.  The larger
 the value, the more time is spent optimizing the delta compression.  See
-the documentation for the --window' option in linkgit:git-repack[1] for
+the documentation for the --window option in linkgit:git-repack[1] for
 more details.  This defaults to 250.
 
 Similarly, the optional configuration variable `gc.aggressiveDepth`
@@ -133,8 +150,12 @@ The optional configuration variable `gc.pruneExpire` controls how old
 the unreferenced loose objects have to be before they are pruned.  The
 default is "2 weeks ago".
 
+Optional configuration variable `gc.worktreePruneExpire` controls how
+old a stale working tree should be before `git worktree prune` deletes
+it. Default is "3 months ago".
+
 
-Notes
+NOTES
 -----
 
 'git gc' tries very hard not to delete objects that are referenced
index 18b494731f51145e9d4a4d078264bedfd3beb00f..312409a607231d66bd296c1d955bb62c47ecffcf 100644 (file)
@@ -293,7 +293,7 @@ providing this option will cause it to die.
 For more details about the <pathspec> syntax, see the 'pathspec' entry
 in linkgit:gitglossary[7].
 
-Examples
+EXAMPLES
 --------
 
 `git grep 'time_t' -- '*.[ch]'`::
index 40d328a4b3e7e03720cbefc5100ee8e752f6a586..a40fc38d8b425fae0a1ca074ecc8d603efc80f14 100644 (file)
@@ -8,7 +8,7 @@ git-help - Display help information about Git
 SYNOPSIS
 --------
 [verse]
-'git help' [-a|--all] [-g|--guide]
+'git help' [-a|--all [--verbose]] [-g|--guide]
           [-i|--info|-m|--man|-w|--web] [COMMAND|GUIDE]
 
 DESCRIPTION
@@ -42,6 +42,8 @@ OPTIONS
 --all::
        Prints all the available commands on the standard output. This
        option overrides any given command or guide name.
+       When used with `--verbose` print description for all recognized
+       commands.
 
 -g::
 --guides::
index 21a33d2c414e24eb779669f10beefde58db00f1c..666b042679f405fd1759b42a8d86aafb083e817c 100644 (file)
@@ -15,8 +15,9 @@ DESCRIPTION
 -----------
 Downloads a remote Git repository via HTTP.
 
-*NOTE*: use of this command without -a is deprecated.  The -a
-behaviour will become the default in a future release.
+This command always gets all objects. Historically, there were three options
+`-a`, `-c` and `-t` for choosing which objects to download. They are now
+silently ignored.
 
 OPTIONS
 -------
@@ -24,12 +25,8 @@ commit-id::
         Either the hash or the filename under [URL]/refs/ to
         pull.
 
--c::
-       Get the commit objects.
--t::
-       Get trees associated with the commit objects.
--a::
-       Get all the objects.
+-a, -c, -t::
+       These options are ignored for historical reasons.
 -v::
        Report what is downloaded.
 
index 2aceb6f26da2299d87afe6aeeaf54d18d1487488..ea03a4eeb0fd3124e784553f55c3dccac84a03c7 100644 (file)
@@ -55,7 +55,7 @@ OPTIONS
        The remote refs to update.
 
 
-Specifying the Refs
+SPECIFYING THE REFS
 -------------------
 
 A '<ref>' specification can be either a single pattern, or a pair
index 5d1e4c80cd5d479a43c39ffb12b66a7302e754e7..032613c420cf3cbcf75e82fc89abed6ec8d85355 100644 (file)
@@ -136,8 +136,8 @@ Using direct mode with SSL:
 .........................
 
 
-EXAMPLE
--------
+EXAMPLES
+--------
 To submit patches using GMail's IMAP interface, first, edit your ~/.gitconfig
 to specify your account settings:
 
index 138edb47b6a17ab925ef3206c1aec6336ff380fe..d5b7560bfe2d51370c313ee006a9f0ed4388eda4 100644 (file)
@@ -93,8 +93,8 @@ OPTIONS
 --max-input-size=<size>::
        Die, if the pack is larger than <size>.
 
-Note
-----
+NOTES
+-----
 
 Once the index has been created, the list of object names is sorted
 and the SHA-1 hash of that list is printed to stdout. If --stdin was
index ff446f15f79f270a8979d1a398450a50ba4a4e95..9111c47a1bf2c22466bb74d3b3bca540c4fb0eb2 100644 (file)
@@ -8,8 +8,8 @@ git-interpret-trailers - add or parse structured information in commit messages
 SYNOPSIS
 --------
 [verse]
-'git interpret-trailers' [options] [(--trailer <token>[(=|:)<value>])...] [<file>...]
-'git interpret-trailers' [options] [--parse] [<file>...]
+'git interpret-trailers' [<options>] [(--trailer <token>[(=|:)<value>])...] [<file>...]
+'git interpret-trailers' [<options>] [--parse] [<file>...]
 
 DESCRIPTION
 -----------
index 5437f8b0f0e6699eca662879290d47df85387f0f..90761f169444c165f0e94ebc3b7731cd8d85d3f0 100644 (file)
@@ -9,7 +9,7 @@ git-log - Show commit logs
 SYNOPSIS
 --------
 [verse]
-'git log' [<options>] [<revision range>] [[\--] <path>...]
+'git log' [<options>] [<revision range>] [[--] <path>...]
 
 DESCRIPTION
 -----------
@@ -90,13 +90,13 @@ include::line-range-format.txt[]
        ways to spell <revision range>, see the 'Specifying Ranges'
        section of linkgit:gitrevisions[7].
 
-[\--] <path>...::
+[--] <path>...::
        Show only commits that are enough to explain how the files
        that match the specified paths came to be.  See 'History
        Simplification' below for details and other simplification
        modes.
 +
-Paths may need to be prefixed with ``\-- '' to separate them from
+Paths may need to be prefixed with `--` to separate them from
 options or the revision range, when confusion arises.
 
 include::rev-list-options.txt[]
@@ -125,7 +125,7 @@ EXAMPLES
 `git log --since="2 weeks ago" -- gitk`::
 
        Show the changes during the last two weeks to the file 'gitk'.
-       The ``--'' is necessary to avoid confusion with the *branch* named
+       The `--` is necessary to avoid confusion with the *branch* named
        'gitk'
 
 `git log --name-status release..test`::
index 3ac3e3a77d171d55a2992b263e03350cf4c08b3d..5298f1bc3052f47e390eee780efe665083744309 100644 (file)
@@ -53,7 +53,8 @@ OPTIONS
        Show only ignored files in the output. When showing files in the
        index, print only those matched by an exclude pattern. When
        showing "other" files, show only those matched by an exclude
-       pattern.
+       pattern. Standard ignore rules are not automatically activated,
+       therefore at least one of the `--exclude*` options is required.
 
 -s::
 --stage::
@@ -183,7 +184,7 @@ followed by the  ("attr/<eolattr>").
        Files to show. If no files are given all files which match the other
        specified criteria are shown.
 
-Output
+OUTPUT
 ------
 'git ls-files' just outputs the filenames unless `--stage` is specified in
 which case it outputs:
@@ -208,7 +209,7 @@ quoted as explained for the configuration variable `core.quotePath`
 verbatim and the line is terminated by a NUL byte.
 
 
-Exclude Patterns
+EXCLUDE PATTERNS
 ----------------
 
 'git ls-files' can use a list of "exclude patterns" when
index 5f2628c8f86a65b0bfe8e29995fa2176927a30f0..b9fd3770a6ce19c341c421e07b68985d89d94df5 100644 (file)
@@ -10,7 +10,7 @@ SYNOPSIS
 --------
 [verse]
 'git ls-remote' [--heads] [--tags] [--refs] [--upload-pack=<exec>]
-             [-q | --quiet] [--exit-code] [--get-url]
+             [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]
              [--symref] [<repository> [<refs>...]]
 
 DESCRIPTION
@@ -60,6 +60,24 @@ OPTIONS
        upload-pack only shows the symref HEAD, so it will be the only
        one shown by ls-remote.
 
+--sort=<key>::
+       Sort based on the key given. Prefix `-` to sort in descending order
+       of the value. Supports "version:refname" or "v:refname" (tag names
+       are treated as versions). The "version:refname" sort order can also
+       be affected by the "versionsort.suffix" configuration variable.
+       See linkgit:git-for-each-ref[1] for more sort options, but be aware
+       keys like `committerdate` that require access to the objects
+       themselves will not work for refs whose objects have not yet been
+       fetched from the remote, and will give a `missing object` error.
+
+-o <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.
+       When multiple `--server-option=<option>` are given, they are all
+       sent to the other side in the order listed on the command line.
+
 <repository>::
        The "remote" repository to query.  This parameter can be
        either a URL or the name of a remote (see the GIT URLS and
@@ -90,6 +108,10 @@ EXAMPLES
        c5db5456ae3b0873fc659c19fafdde22313cc441        refs/tags/v0.99.2
        7ceca275d047c90c0c7d5afb13ab97efdf51bd6e        refs/tags/v0.99.3
 
+SEE ALSO
+--------
+linkgit:git-check-ref-format[1].
+
 GIT
 ---
 Part of the linkgit:git[1] suite
index d5dfd8430f3370dc168e42e3991d1d4a9b854617..6a5c00e2c2b5b5201e42e12b74d8ae5128ce9c93 100644 (file)
@@ -57,7 +57,7 @@ reconstruct the original (pre-merge) changes. Therefore:
 discouraged: while possible, it may leave you in a state that is hard to
 back out of in the case of a conflict.
 
-The fourth syntax ("`git merge --continue`") can only be run after the
+The third syntax ("`git merge --continue`") can only be run after the
 merge has resulted in conflicts.
 
 OPTIONS
index c3616e7711aef80ee7e2bd3bb90ea5cee7dd1d4b..27fe2b32e10b2f0c92315483ac4a5e8a9722d3db 100644 (file)
@@ -14,7 +14,7 @@ SYNOPSIS
 DESCRIPTION
 -----------
 Reads standard input in non-recursive `ls-tree` output format, and creates
-a tree object.  The order of the tree entries is normalised by mktree so
+a tree object.  The order of the tree entries is normalized by mktree so
 pre-sorting the input is not required.  The object name of the tree object
 built is written to the standard output.
 
index e8e68f528cf2fa5705e7cedce8d3d807fa20057d..5cb0eb0855fefe582721baeb3295beb610a74891 100644 (file)
@@ -61,8 +61,8 @@ OPTIONS
 --always::
        Show uniquely abbreviated commit object as fallback.
 
-EXAMPLE
--------
+EXAMPLES
+--------
 
 Given a commit, find out where it is relative to the local refs. Say somebody
 wrote you about that fantastic commit 33db5f4d9027a10e477ccf054b2c1ab94f74c85a.
index d8c8f11c9f2dc94a2f4d46445e33c4f1494ab39e..f0de3b891b297bb92ffb0323f5bfec5944b9c3aa 100644 (file)
@@ -29,8 +29,8 @@ Submit Git changes back to p4 using 'git p4 submit'.  The command
 the updated p4 remote branch.
 
 
-EXAMPLE
--------
+EXAMPLES
+--------
 * Clone a repository:
 +
 ------------
@@ -149,6 +149,12 @@ To specify a branch other than the current one, use:
 $ git p4 submit topicbranch
 ------------
 
+To specify a single commit or a range of commits, use:
+------------
+$ git p4 submit --commit <sha1>
+$ git p4 submit --commit <sha1..sha1>
+------------
+
 The upstream reference is generally 'refs/remotes/p4/master', but can
 be overridden using the `--origin=` command-line option.
 
@@ -164,6 +170,31 @@ $ git p4 submit --shelve
 $ git p4 submit --update-shelve 1234 --update-shelve 2345
 ----
 
+
+Unshelve
+~~~~~~~~
+Unshelving will take a shelved P4 changelist, and produce the equivalent git commit
+in the branch refs/remotes/p4/unshelved/<changelist>.
+
+The git commit is created relative to the current origin revision (HEAD by default).
+If the shelved changelist's parent revisions differ, git-p4 will refuse to unshelve;
+you need to be unshelving onto an equivalent tree.
+
+The origin revision can be changed with the "--origin" option.
+
+If the target branch in refs/remotes/p4/unshelved already exists, the old one will
+be renamed.
+
+----
+$ git p4 sync
+$ git p4 unshelve 12345
+$ git show refs/remotes/p4/unshelved/12345
+<submit more changes via p4 to the same files>
+$ git p4 unshelve 12345
+<refuses to unshelve until git is in sync with p4 again>
+
+----
+
 OPTIONS
 -------
 
@@ -330,6 +361,19 @@ These options can be used to modify 'git p4 submit' behavior.
        p4/master.  See the "Sync options" section above for more
        information.
 
+--commit <sha1>|<sha1..sha1>::
+    Submit only the specified commit or range of commits, instead of the full
+    list of changes that are in the current Git branch.
+
+--disable-rebase::
+    Disable the automatic rebase after all commits have been successfully
+    submitted. Can also be set with git-p4.disableRebase.
+
+--disable-p4sync::
+    Disable the automatic sync of p4/master from Perforce after commits have
+    been submitted. Implies --disable-rebase. Can also be set with
+    git-p4.disableP4Sync. Sync with origin/master still goes ahead if possible.
+
 Rebase options
 ~~~~~~~~~~~~~~
 These options can be used to modify 'git p4 rebase' behavior.
@@ -337,6 +381,13 @@ These options can be used to modify 'git p4 rebase' behavior.
 --import-labels::
        Import p4 labels.
 
+Unshelve options
+~~~~~~~~~~~~~~~~
+
+--origin::
+    Sets the git refspec against which the shelved P4 changelist is compared.
+    Defaults to p4/master.
+
 DEPOT PATH SYNTAX
 -----------------
 The p4 depot path argument to 'git p4 sync' and 'git p4 clone' can
@@ -392,7 +443,7 @@ dedicating a client spec just for 'git p4'.
 The name of the client can be given to 'git p4' in multiple ways.  The
 variable 'git-p4.client' takes precedence if it exists.  Otherwise,
 normal p4 mechanisms of determining the client are used:  environment
-variable P4CLIENT, a file referenced by P4CONFIG, or the local host name.
+variable `P4CLIENT`, a file referenced by `P4CONFIG`, or the local host name.
 
 
 BRANCH DETECTION
@@ -461,22 +512,22 @@ General variables
 ~~~~~~~~~~~~~~~~~
 git-p4.user::
        User specified as an option to all p4 commands, with '-u <user>'.
-       The environment variable 'P4USER' can be used instead.
+       The environment variable `P4USER` can be used instead.
 
 git-p4.password::
        Password specified as an option to all p4 commands, with
        '-P <password>'.
-       The environment variable 'P4PASS' can be used instead.
+       The environment variable `P4PASS` can be used instead.
 
 git-p4.port::
        Port specified as an option to all p4 commands, with
        '-p <port>'.
-       The environment variable 'P4PORT' can be used instead.
+       The environment variable `P4PORT` can be used instead.
 
 git-p4.host::
        Host specified as an option to all p4 commands, with
        '-h <host>'.
-       The environment variable 'P4HOST' can be used instead.
+       The environment variable `P4HOST` can be used instead.
 
 git-p4.client::
        Client specified as an option to all p4 commands, with
@@ -644,6 +695,12 @@ git-p4.conflict::
        Specify submit behavior when a conflict with p4 is found, as per
        --conflict.  The default behavior is 'ask'.
 
+git-p4.disableRebase::
+    Do not rebase the tree against p4/master following a submit.
+
+git-p4.disableP4Sync::
+    Do not sync p4/master with Perforce following a submit. Implies git-p4.disableRebase.
+
 IMPLEMENTATION DETAILS
 ----------------------
 * Changesets from p4 are imported using Git fast-import.
index 81bc490ac52eb9414015979d8c244ce063c838b5..d95b472d16828b2bea304727e7c5daaa2b75ae89 100644 (file)
@@ -12,7 +12,7 @@ SYNOPSIS
 'git pack-objects' [-q | --progress | --all-progress] [--all-progress-implied]
        [--no-reuse-delta] [--delta-base-offset] [--non-empty]
        [--local] [--incremental] [--window=<n>] [--depth=<n>]
-       [--revs [--unpacked | --all]]
+       [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]
        [--stdout [--filter=<filter-spec>] | base-name]
        [--shallow] [--keep-true-parents] < object-list
 
@@ -96,7 +96,9 @@ base-name::
        it too deep affects the performance on the unpacker
        side, because delta data needs to be applied that many
        times to get to the necessary object.
-       The default value for --window is 10 and --depth is 50.
++
+The default value for --window is 10 and --depth is 50. The maximum
+depth is 4095.
 
 --window-memory=<n>::
        This option provides an additional limit on top of `--window`;
@@ -126,6 +128,13 @@ base-name::
        has a .keep file to be ignored, even if it would have
        otherwise been packed.
 
+--keep-pack=<pack-name>::
+       This flag causes an object already in the given pack to be
+       ignored, even if it would have otherwise been
+       packed. `<pack-name>` is the the pack file name without
+       leading directory (e.g. `pack-123.pack`). The option could be
+       specified multiple times to keep multiple packs.
+
 --incremental::
        This flag causes an object already in a pack to be ignored
        even if it would have otherwise been packed.
@@ -267,6 +276,19 @@ Unexpected missing object will raise an error.
        locally created objects [without .promisor] and objects from the
        promisor remote [with .promisor].)  This is used with partial clone.
 
+--keep-unreachable::
+       Objects unreachable from the refs in packs named with
+       --unpacked= option are added to the resulting pack, in
+       addition to the reachable objects that are not in packs marked
+       with *.keep files. This implies `--revs`.
+
+--pack-loose-unreachable::
+       Pack unreachable loose objects (and their loose counterparts
+       removed). This implies `--revs`.
+
+--unpack-unreachable::
+       Keep unreachable objects in loose form. This implies `--revs`.
+
 SEE ALSO
 --------
 linkgit:git-rev-list[1]
index a37c0af9313e8e47806c89a584c70c09517244d1..03552dd86fc412b622aff2bcf8feda8e71711b3e 100644 (file)
@@ -56,8 +56,8 @@ OPTIONS
        reachable from any of our references, keep objects
        reachable from listed <head>s.
 
-EXAMPLE
--------
+EXAMPLES
+--------
 
 To prune objects not used by your repository or another that
 borrows from your repository via its
@@ -67,7 +67,7 @@ borrows from your repository via its
 $ git prune $(cd ../another && git rev-parse --all)
 ------------
 
-Notes
+NOTES
 -----
 
 In most cases, users will not need to call 'git prune' directly, but
index ce05b7a5b13eadb6870f16a7168559434d376c20..118d9d86f79427373eb92753abf7e134ed925fe8 100644 (file)
@@ -9,7 +9,7 @@ git-pull - Fetch from and integrate with another repository or a local branch
 SYNOPSIS
 --------
 [verse]
-'git pull' [options] [<repository> [<refspec>...]]
+'git pull' [<options>] [<repository> [<refspec>...]]
 
 
 DESCRIPTION
@@ -101,13 +101,17 @@ Options related to merging
 include::merge-options.txt[]
 
 -r::
---rebase[=false|true|preserve|interactive]::
+--rebase[=false|true|merges|preserve|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
        was rebased since last fetched, the rebase uses that information
        to avoid rebasing non-local changes.
 +
+When set to `merges`, rebase using `git rebase --rebase-merges` so that
+the local merge commits are included in the rebase (see
+linkgit:git-rebase[1] for details).
++
 When set to preserve, rebase with the `--preserve-merges` option passed
 to `git rebase` so that locally created merge commits will not be flattened.
 +
index 5b08302fc2299fe1b42fc0137b50a3bab774ca10..55277a97811fa6933c76c1bd2c96114672f6d5cd 100644 (file)
@@ -11,7 +11,7 @@ SYNOPSIS
 [verse]
 'git push' [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
           [--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
-          [-u | --set-upstream] [--push-option=<string>]
+          [-u | --set-upstream] [-o <string> | --push-option=<string>]
           [--[no-]signed|--signed=(true|false|if-asked)]
           [--force-with-lease[=<refname>[:<expect>]]]
           [--no-verify] [<repository> [<refspec>...]]
@@ -123,6 +123,7 @@ already exists on the remote side.
        will be tab-separated and sent to stdout instead of stderr.  The full
        symbolic names of the refs will be given.
 
+-d::
 --delete::
        All listed refs are deleted from the remote repository. This is
        the same as prefixing all refs with a colon.
@@ -300,7 +301,7 @@ origin +master` to force a push to the `master` branch). See the
        These options are passed to linkgit:git-send-pack[1]. A thin transfer
        significantly reduces the amount of sent data when the sender and
        receiver share many of the same objects in common. The default is
-       \--thin.
+       `--thin`.
 
 -q::
 --quiet::
@@ -423,7 +424,7 @@ reason::
        refs, no explanation is needed. For a failed ref, the reason for
        failure is described.
 
-Note about fast-forwards
+NOTE ABOUT FAST-FORWARDS
 ------------------------
 
 When an update changes a branch (or more in general, a ref) that used to
@@ -510,7 +511,7 @@ overwrite it. In other words, "git push --force" is a method reserved for
 a case where you do mean to lose history.
 
 
-Examples
+EXAMPLES
 --------
 
 `git push`::
index f2a07d54d694b42657aa38e71dc0eeb5fc94e9a0..5c70bc2878fc2f68698b931c6bf951d0097ef813 100644 (file)
@@ -132,7 +132,7 @@ OPTIONS
        The id of the tree object(s) to be read/merged.
 
 
-Merging
+MERGING
 -------
 If `-m` is specified, 'git read-tree' can perform 3 kinds of
 merge, a single tree merge if only 1 tree is given, a
@@ -382,7 +382,7 @@ middle of doing, and when your working tree is ready (i.e. you
 have finished your work-in-progress), attempt the merge again.
 
 
-Sparse checkout
+SPARSE CHECKOUT
 ---------------
 
 "Sparse checkout" allows populating the working directory sparsely.
index 3277ca143273e01f5f4973ed351c8a5cb4b8e0fa..0e20a66e73cf420c83b156d1a0aaa8f60cd4702f 100644 (file)
@@ -8,9 +8,9 @@ git-rebase - Reapply commits on top of another base tip
 SYNOPSIS
 --------
 [verse]
-'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
+'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
        [<upstream> [<branch>]]
-'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
+'git rebase' [-i | --interactive] [<options>] [--exec <cmd>] [--onto <newbase>]
        --root [<branch>]
 'git rebase' --continue | --skip | --abort | --quit | --edit-todo | --show-current-patch
 
@@ -364,9 +364,10 @@ default is `--no-fork-point`, otherwise the default is `--fork-point`.
        Incompatible with the --interactive option.
 
 --signoff::
-       This flag is passed to 'git am' to sign off all the rebased
-       commits (see linkgit:git-am[1]). Incompatible with the
-       --interactive option.
+       Add a Signed-off-by: trailer to all the rebased commits. Note
+       that if `--interactive` is given then only commits marked to be
+       picked, edited or reworded will have the trailer added. Incompatible
+       with the `--preserve-merges` option.
 
 -i::
 --interactive::
@@ -378,6 +379,33 @@ The commit list format can be changed by setting the configuration option
 rebase.instructionFormat.  A customized instruction format will automatically
 have the long commit hash prepended to the format.
 
+-r::
+--rebase-merges[=(rebase-cousins|no-rebase-cousins)]::
+       By default, a rebase will simply drop merge commits from the todo
+       list, and put the rebased commits into a single, linear branch.
+       With `--rebase-merges`, the rebase will instead try to preserve
+       the branching structure within the commits that are to be rebased,
+       by recreating the merge commits. Any resolved merge conflicts or
+       manual amendments in these merge commits will have to be
+       resolved/re-applied manually.
++
+By default, or when `no-rebase-cousins` was specified, commits which do not
+have `<upstream>` as direct ancestor will keep their original branch point,
+i.e. commits that would be excluded by gitlink:git-log[1]'s
+`--ancestry-path` option will keep their original ancestry by default. If
+the `rebase-cousins` mode is turned on, such commits are instead rebased
+onto `<upstream>` (or `<onto>`, if specified).
++
+The `--rebase-merges` mode is similar in spirit to `--preserve-merges`, but
+in contrast to that option works well in interactive rebases: commits can be
+reordered, inserted and dropped at will.
++
+It is currently only possible to recreate the merge commits using the
+`recursive` merge strategy; Different merge strategies can be used only via
+explicit `exec git merge -s <strategy> [...]` commands.
++
+See also REBASING MERGES below.
+
 -p::
 --preserve-merges::
        Recreate merge commits instead of flattening the history by replaying
@@ -775,12 +803,146 @@ The ripple effect of a "hard case" recovery is especially bad:
 'everyone' downstream from 'topic' will now have to perform a "hard
 case" recovery too!
 
+REBASING MERGES
+-----------------
+
+The interactive rebase command was originally designed to handle
+individual patch series. As such, it makes sense to exclude merge
+commits from the todo list, as the developer may have merged the
+then-current `master` while working on the branch, only to rebase
+all the commits onto `master` eventually (skipping the merge
+commits).
+
+However, there are legitimate reasons why a developer may want to
+recreate merge commits: to keep the branch structure (or "commit
+topology") when working on multiple, inter-related branches.
+
+In the following example, the developer works on a topic branch that
+refactors the way buttons are defined, and on another topic branch
+that uses that refactoring to implement a "Report a bug" button. The
+output of `git log --graph --format=%s -5` may look like this:
+
+------------
+*   Merge branch 'report-a-bug'
+|\
+| * Add the feedback button
+* | Merge branch 'refactor-button'
+|\ \
+| |/
+| * Use the Button class for all buttons
+| * Extract a generic Button class from the DownloadButton one
+------------
+
+The developer might want to rebase those commits to a newer `master`
+while keeping the branch topology, for example when the first topic
+branch is expected to be integrated into `master` much earlier than the
+second one, say, to resolve merge conflicts with changes to the
+DownloadButton class that made it into `master`.
+
+This rebase can be performed using the `--rebase-merges` option.
+It will generate a todo list looking like this:
+
+------------
+label onto
+
+# Branch: refactor-button
+reset onto
+pick 123456 Extract a generic Button class from the DownloadButton one
+pick 654321 Use the Button class for all buttons
+label refactor-button
+
+# Branch: report-a-bug
+reset refactor-button # Use the Button class for all buttons
+pick abcdef Add the feedback button
+label report-a-bug
+
+reset onto
+merge -C a1b2c3 refactor-button # Merge 'refactor-button'
+merge -C 6f5e4d report-a-bug # Merge 'report-a-bug'
+------------
+
+In contrast to a regular interactive rebase, there are `label`, `reset`
+and `merge` commands in addition to `pick` ones.
+
+The `label` command associates a label with the current HEAD when that
+command is executed. These labels are created as worktree-local refs
+(`refs/rewritten/<label>`) that will be deleted when the rebase
+finishes. That way, rebase operations in multiple worktrees linked to
+the same repository do not interfere with one another. If the `label`
+command fails, it is rescheduled immediately, with a helpful message how
+to proceed.
+
+The `reset` command resets the HEAD, index and worktree to the specified
+revision. It is isimilar to an `exec git reset --hard <label>`, but
+refuses to overwrite untracked files. If the `reset` command fails, it is
+rescheduled immediately, with a helpful message how to edit the todo list
+(this typically happens when a `reset` command was inserted into the todo
+list manually and contains a typo).
+
+The `merge` command will merge the specified revision into whatever is
+HEAD at that time. With `-C <original-commit>`, the commit message of
+the specified merge commit will be used. When the `-C` is changed to
+a lower-case `-c`, the message will be opened in an editor after a
+successful merge so that the user can edit the message.
+
+If a `merge` command fails for any reason other than merge conflicts (i.e.
+when the merge operation did not even start), it is rescheduled immediately.
+
+At this time, the `merge` command will *always* use the `recursive`
+merge strategy, with no way to choose a different one. To work around
+this, an `exec` command can be used to call `git merge` explicitly,
+using the fact that the labels are worktree-local refs (the ref
+`refs/rewritten/onto` would correspond to the label `onto`, for example).
+
+Note: the first command (`label onto`) labels the revision onto which
+the commits are rebased; The name `onto` is just a convention, as a nod
+to the `--onto` option.
+
+It is also possible to introduce completely new merge commits from scratch
+by adding a command of the form `merge <merge-head>`. This form will
+generate a tentative commit message and always open an editor to let the
+user edit it. This can be useful e.g. when a topic branch turns out to
+address more than a single concern and wants to be split into two or
+even more topic branches. Consider this todo list:
+
+------------
+pick 192837 Switch from GNU Makefiles to CMake
+pick 5a6c7e Document the switch to CMake
+pick 918273 Fix detection of OpenSSL in CMake
+pick afbecd http: add support for TLS v1.3
+pick fdbaec Fix detection of cURL in CMake on Windows
+------------
+
+The one commit in this list that is not related to CMake may very well
+have been motivated by working on fixing all those bugs introduced by
+switching to CMake, but it addresses a different concern. To split this
+branch into two topic branches, the todo list could be edited like this:
+
+------------
+label onto
+
+pick afbecd http: add support for TLS v1.3
+label tlsv1.3
+
+reset onto
+pick 192837 Switch from GNU Makefiles to CMake
+pick 918273 Fix detection of OpenSSL in CMake
+pick fdbaec Fix detection of cURL in CMake on Windows
+pick 5a6c7e Document the switch to CMake
+label cmake
+
+reset onto
+merge tlsv1.3
+merge cmake
+------------
+
 BUGS
 ----
 The todo list presented by `--preserve-merges --interactive` does not
 represent the topology of the revision graph.  Editing commits and
 rewording their commit messages should work fine, but attempts to
-reorder commits tend to produce counterintuitive results.
+reorder commits tend to produce counterintuitive results. Use
+`--rebase-merges` in such scenarios instead.
 
 For example, an attempt to rearrange
 ------------
index 86a4b32f0f1cbb8b69ff8b935edade6f14e7d5e2..dedf97efbb2282a15abfee41926afd893e59955c 100644 (file)
@@ -41,7 +41,7 @@ OPTIONS
 <directory>::
        The repository to sync into.
 
-pre-receive Hook
+PRE-RECEIVE HOOK
 ----------------
 Before any ref is updated, if $GIT_DIR/hooks/pre-receive file exists
 and is executable, it will be invoked once with no parameters.  The
@@ -116,7 +116,7 @@ bail out if the update is not to be supported.
 
 See the notes on the quarantine environment below.
 
-update Hook
+UPDATE HOOK
 -----------
 Before each ref is updated, if $GIT_DIR/hooks/update file exists
 and is executable, it is invoked once per ref, with three parameters:
@@ -138,7 +138,7 @@ ensure the ref will actually be updated, it is only a prerequisite.
 As such it is not a good idea to send notices (e.g. email) from
 this hook.  Consider using the post-receive hook instead.
 
-post-receive Hook
+POST-RECEIVE HOOK
 -----------------
 After all refs were updated (or attempted to be updated), if any
 ref update was successful, and if $GIT_DIR/hooks/post-receive
@@ -198,7 +198,7 @@ after it was updated by 'git-receive-pack', but before the hook was able
 to evaluate it.  It is recommended that hooks rely on sha1-new
 rather than the current value of refname.
 
-post-update Hook
+POST-UPDATE HOOK
 ----------------
 After all other processing, if at least one ref was updated, and
 if $GIT_DIR/hooks/post-update file exists and is executable, then
@@ -216,7 +216,7 @@ if the repository is packed and is served via a dumb transport.
        exec git update-server-info
 
 
-Quarantine Environment
+QUARANTINE ENVIRONMENT
 ----------------------
 
 When `receive-pack` takes in objects, they are placed into a temporary
index b25d0b5996b560837648c13c742bfc5ad09f0310..3fc5d94336f7c706bab12513e14744947a0bcae2 100644 (file)
@@ -55,14 +55,14 @@ some tunnel.
        the vhost field in the git:// service request (to rest of the argument).
        Default is not to send vhost in such request (if sent).
 
-ENVIRONMENT VARIABLES:
-----------------------
+ENVIRONMENT VARIABLES
+---------------------
 
 GIT_TRANSLOOP_DEBUG::
        If set, prints debugging information about various reads/writes.
 
-ENVIRONMENT VARIABLES PASSED TO COMMAND:
-----------------------------------------
+ENVIRONMENT VARIABLES PASSED TO COMMAND
+---------------------------------------
 
 GIT_EXT_SERVICE::
        Set to long name (git-upload-pack, etc...) of service helper needs
@@ -73,8 +73,8 @@ GIT_EXT_SERVICE_NOPREFIX::
        to invoke.
 
 
-EXAMPLES:
----------
+EXAMPLES
+--------
 This remote helper is transparently used by Git when
 you use commands such as "git fetch <URL>", "git clone <URL>",
 , "git push <URL>" or "git remote add <nick> <URL>", where <URL>
index 4feddc0293bd7eb9827ce45f11519335a484f013..0cad37fb81d99c3928f1a763a79350836b8e70e6 100644 (file)
@@ -186,8 +186,8 @@ actually prune them.
 
 'update'::
 
-Fetch updates for a named set of remotes in the repository as defined by
-remotes.<group>.  If a named group is not specified on the command line,
+Fetch updates for remotes or remote groups in the repository as defined by
+remotes.<group>.  If neither group nor remote is specified on the command line,
 the configuration parameter remotes.default will be used; if
 remotes.default is not defined, all remotes which do not have the
 configuration parameter remote.<name>.skipDefaultUpdate set to true will
@@ -203,7 +203,7 @@ The remote configuration is achieved using the `remote.origin.url` and
 `remote.origin.fetch` configuration variables.  (See
 linkgit:git-config[1]).
 
-Examples
+EXAMPLES
 --------
 
 * Add a new remote, fetch, and check out a branch from it
index ae750e9e1149f512dd5889a8081452055ccdb6d7..d90e7907f4843a048caf11a2fae42a973d893d9a 100644 (file)
@@ -9,7 +9,7 @@ git-repack - Pack unpacked objects in a repository
 SYNOPSIS
 --------
 [verse]
-'git repack' [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [--window=<n>] [--depth=<n>] [--threads=<n>]
+'git repack' [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]
 
 DESCRIPTION
 -----------
@@ -90,7 +90,9 @@ other objects in that pack they already have locally.
        space. `--depth` limits the maximum delta depth; making it too deep
        affects the performance on the unpacker side, because delta data needs
        to be applied that many times to get to the necessary object.
-       The default value for --window is 10 and --depth is 50.
++
+The default value for --window is 10 and --depth is 50. The maximum
+depth is 4095.
 
 --threads=<n>::
        This option is passed through to `git pack-objects`.
@@ -133,6 +135,13 @@ other objects in that pack they already have locally.
        with `-b` or `repack.writeBitmaps`, as it ensures that the
        bitmapped packfile has the necessary objects.
 
+--keep-pack=<pack-name>::
+       Exclude the given pack from repacking. This is the equivalent
+       of having `.keep` file on the pack. `<pack-name>` is the the
+       pack file name without leading directory (e.g. `pack-123.pack`).
+       The option could be specified multiple times to keep multiple
+       packs.
+
 --unpack-unreachable=<when>::
        When loosening unreachable objects, do not bother loosening any
        objects older than `<when>`. This can be used to optimize out
index e5c57ae6ef4afd71944e23f895e9a0f354eaf6b1..246dc9943c223d34c72d7b90f40ee8f523b7d77e 100644 (file)
@@ -11,6 +11,7 @@ SYNOPSIS
 'git replace' [-f] <object> <replacement>
 'git replace' [-f] --edit <object>
 'git replace' [-f] --graft <commit> [<parent>...]
+'git replace' [-f] --convert-graft-file
 'git replace' -d <object>...
 'git replace' [--format=<format>] [-l [<pattern>]]
 
@@ -87,9 +88,13 @@ OPTIONS
        content as <commit> except that its parents will be
        [<parent>...] instead of <commit>'s parents. A replacement ref
        is then created to replace <commit> with the newly created
-       commit. See contrib/convert-grafts-to-replace-refs.sh for an
-       example script based on this option that can convert grafts to
-       replace refs.
+       commit. Use `--convert-graft-file` to convert a
+       `$GIT_DIR/info/grafts` file and use replace refs instead.
+
+--convert-graft-file::
+       Creates graft commits for all entries in `$GIT_DIR/info/grafts`
+       and deletes that file upon success. The purpose is to help users
+       with transitioning off of the now-deprecated graft file.
 
 -l <pattern>::
 --list <pattern>::
index c32cb0bea1d6c057dabdd3065417744f5209ba46..4d4392d0f841b7e447b536ef1281fcbe2e49786d 100644 (file)
@@ -46,8 +46,8 @@ ref that is different from the ref you have locally, you can use the
 its remote name.
 
 
-EXAMPLE
--------
+EXAMPLES
+--------
 
 Imagine that you built your work on your `master` branch on top of
 the `v1.0` release, and want it to be integrated to the project.
index 95326b85ff68edbda3a6661816251351029bdfda..e72d332b8316763d40e7bcfe0e32bcaa61842cf8 100644 (file)
@@ -9,7 +9,7 @@ git-rev-parse - Pick out and massage parameters
 SYNOPSIS
 --------
 [verse]
-'git rev-parse' [ --option ] <args>...
+'git rev-parse' [<options>] <args>...
 
 DESCRIPTION
 -----------
@@ -360,7 +360,7 @@ Example
 
 ------------
 OPTS_SPEC="\
-some-command [options] <args>...
+some-command [<options>] <args>...
 
 some-command does foo and bar!
 --
@@ -385,7 +385,7 @@ When `"$@"` is `-h` or `--help` in the above example, the following
 usage text would be shown:
 
 ------------
-usage: some-command [options] <args>...
+usage: some-command [<options>] <args>...
 
     some-command does foo and bar!
 
index 71ef97ba9b22aad996049bd0c1500a835a433350..4f3efde80cd8e4f0b1a5b6699ad3e569f19ca516 100644 (file)
@@ -9,7 +9,7 @@ git-send-email - Send a collection of patches as emails
 SYNOPSIS
 --------
 [verse]
-'git send-email' [options] <file|directory|rev-list options>...
+'git send-email' [<options>] <file|directory|rev-list options>...
 'git send-email' --dump-aliases
 
 
@@ -255,7 +255,7 @@ must be used for each option.
 
 --batch-size=<num>::
        Some email servers (e.g. smtp.163.com) limit the number emails to be
-       sent per session (connection) and this will lead to a faliure when
+       sent per session (connection) and this will lead to a failure when
        sending many messages.  With this option, send-email will disconnect after
        sending $<num> messages and wait for a few seconds (see --relogin-delay)
        and reconnect, to work around such a limit.  You may want to
@@ -458,8 +458,8 @@ sendemail.confirm::
        one of 'always', 'never', 'cc', 'compose', or 'auto'. See `--confirm`
        in the previous section for the meaning of these values.
 
-EXAMPLE
--------
+EXAMPLES
+--------
 Use gmail as the smtp server
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 To use 'git send-email' to send your patches through the GMail SMTP server,
@@ -473,16 +473,7 @@ edit ~/.gitconfig to specify your account settings:
 
 If you have multifactor authentication setup on your gmail account, you will
 need to generate an app-specific password for use with 'git send-email'. Visit
-https://security.google.com/settings/security/apppasswords to setup an
-app-specific password.  Once setup, you can store it with the credentials
-helper:
-
-       $ git credential fill
-       protocol=smtp
-       host=smtp.gmail.com
-       username=youname@gmail.com
-       password=app-password
-
+https://security.google.com/settings/security/apppasswords to create it.
 
 Once your commits are ready to be sent to the mailing list, run the
 following commands:
@@ -491,6 +482,11 @@ following commands:
        $ edit outgoing/0000-*
        $ git send-email outgoing/*
 
+The first time you run it, you will be prompted for your credentials.  Enter the
+app-specific or your regular password as appropriate.  If you have credential
+helper configured (see linkgit:git-credential[1]), the password will be saved in
+the credential store so you won't have to type it the next time.
+
 Note: the following perl modules are required
       Net::SMTP::SSL, MIME::Base64 and Authen::SASL
 
index f51c64939b48b7b082752a294b17aee6d92c4fa0..44fd146b9120305112c59b800c9e989bbc60f450 100644 (file)
@@ -99,7 +99,7 @@ be in a separate packet, and the list must end with a flush packet.
        The remote refs to update.
 
 
-Specifying the Refs
+SPECIFYING THE REFS
 -------------------
 
 There are three ways to specify which refs to update on the
index 54cf2560bebbfc538644c636f696d4e500f1d852..11361f33e93937429a8d1791efaca5e00888f236 100644 (file)
@@ -62,8 +62,8 @@ permissions.
 If a `no-interactive-login` command exists, then it is run and the
 interactive shell is aborted.
 
-EXAMPLE
--------
+EXAMPLES
+--------
 
 To disable interactive logins, displaying a greeting instead:
 
index ee6c5476c1d2bf3b2a708e6152ebaba5882cc4f7..bc80905a8a06b5121e2c33c83844301a8212c28c 100644 (file)
@@ -8,8 +8,8 @@ git-shortlog - Summarize 'git log' output
 SYNOPSIS
 --------
 [verse]
+'git shortlog' [<options>] [<revision range>] [[--] <path>...]
 git log --pretty=short | 'git shortlog' [<options>]
-'git shortlog' [<options>] [<revision range>] [[\--] <path>...]
 
 DESCRIPTION
 -----------
@@ -69,11 +69,11 @@ them.
        ways to spell <revision range>, see the "Specifying Ranges"
        section of linkgit:gitrevisions[7].
 
-[\--] <path>...::
+[--] <path>...::
        Consider only commits that are enough to explain how the files
        that match the specified paths came to be.
 +
-Paths may need to be prefixed with "\-- " to separate them from
+Paths may need to be prefixed with `--` to separate them from
 options or the revision range, when confusion arises.
 
 MAPPING AUTHORS
index 7818e0f09853f9c2a2ad0923d1fc13b698cad065..262db049d772d4249983da5ca0d21d8f6b0f8d92 100644 (file)
@@ -173,8 +173,8 @@ The "fixes" branch adds one commit "Introduce "reset type" flag to
 The current branch is "master".
 
 
-EXAMPLE
--------
+EXAMPLES
+--------
 
 If you keep your primary branches immediately under
 `refs/heads`, and topic branches in subdirectories of
index c0aa871c9e8b06ea297e0a723167767338081453..d28e6154c6863d2d87c52251669e305caf7f995a 100644 (file)
@@ -120,8 +120,8 @@ $ git show-ref --heads --hash
 ...
 -----------------------------------------------------------------------------
 
-EXAMPLE
--------
+EXAMPLES
+--------
 
 To show all references called "master", whether tags or heads or anything
 else, and regardless of how deep in the reference naming hierarchy they are,
index e73ef540176b65f6c049a3b5fcfd7e8faa6a6b58..fcf528c1b30d8045592d117ccc3d5f9248d0edbd 100644 (file)
@@ -9,7 +9,7 @@ git-show - Show various types of objects
 SYNOPSIS
 --------
 [verse]
-'git show' [options] [<object>...]
+'git show' [<options>] [<object>...]
 
 DESCRIPTION
 -----------
@@ -77,7 +77,7 @@ EXAMPLES
        Concatenates the contents of said Makefiles in the head
        of the branch `master`.
 
-Discussion
+DISCUSSION
 ----------
 
 include::i18n.txt[]
index 6c230c0c7200412b988d233352e3411a9fb813a8..c4467ffb98a95fa6bb5dc86a92dee3317be9c0ea 100644 (file)
@@ -113,7 +113,7 @@ The possible options are:
        - 'matching'    - Shows ignored files and directories matching an
                          ignore pattern.
 +
-When 'matching' mode is specified, paths that explicity match an
+When 'matching' mode is specified, paths that explicitly match an
 ignored pattern are shown. If a directory matches an ignore pattern,
 then it is shown, but not paths contained in the ignored directory. If
 a directory does not match an ignore pattern, but all contents are
@@ -135,6 +135,16 @@ ignored, then the directory is not shown, but all contents are shown.
        Display or do not display detailed ahead/behind counts for the
        branch relative to its upstream branch.  Defaults to true.
 
+--renames::
+--no-renames::
+       Turn on/off rename detection regardless of user configuration.
+       See also linkgit:git-diff[1] `--no-renames`.
+
+--find-renames[=<n>]::
+       Turn on rename detection, optionally setting the similarity
+       threshold.
+       See also linkgit:git-diff[1] `--find-renames`.
+
 <pathspec>...::
        See the 'pathspec' entry in linkgit:gitglossary[7].
 
index 71c5618e82aacc8616522a6f498b1172910890e4..ef9d9d28a9cc581574bd700e467c636996432caa 100644 (file)
@@ -42,8 +42,8 @@ have to use '../foo.git' instead of './foo.git' - as one might expect
 when following the rules for relative URLs - because the evaluation
 of relative URLs in Git is identical to that of relative directories).
 +
-The default remote is the remote of the remote tracking branch
-of the current branch. If no such remote tracking branch exists or
+The default remote is the remote of the remote-tracking branch
+of the current branch. If no such remote-tracking branch exists or
 the HEAD is detached, "origin" is assumed to be the default remote.
 If the superproject doesn't have a default remote configured
 the superproject is its own authoritative upstream and the current
@@ -213,8 +213,8 @@ sync [--recursive] [--] [<path>...]::
        submodule URLs change upstream and you need to update your local
        repositories accordingly.
 +
-"git submodule sync" synchronizes all submodules while
-"git submodule sync \-- A" synchronizes submodule "A" only.
+`git submodule sync` synchronizes all submodules while
+`git submodule sync -- A` synchronizes submodule "A" only.
 +
 If `--recursive` is specified, this command will recurse into the
 registered submodules, and sync any nested submodules within.
@@ -239,6 +239,13 @@ OPTIONS
 --quiet::
        Only print error messages.
 
+--progress::
+       This option is only valid for add and update commands.
+       Progress status is reported on the standard error stream
+       by default when it is attached to a terminal, unless -q
+       is specified. This flag forces progress status even if the
+       standard error stream is not directed to a terminal.
+
 --all::
        This option is only valid for the deinit command. Unregister all
        submodules in the working tree.
@@ -362,7 +369,15 @@ the submodule itself.
        this option will be passed to the linkgit:git-clone[1] command.
 +
 *NOTE*: Do *not* use this option unless you have read the note
-for linkgit:git-clone[1]'s `--reference` and `--shared` options carefully.
+for linkgit:git-clone[1]'s `--reference`, `--shared`, and `--dissociate`
+options carefully.
+
+--dissociate::
+       This option is only valid for add and update commands.  These
+       commands sometimes need to clone a remote repository. In this case,
+       this option will be passed to the linkgit:git-clone[1] command.
++
+*NOTE*: see the NOTE for the `--reference` option.
 
 --recursive::
        This option is only valid for foreach, update, status and sync commands.
index 636e09048e8846b813166737ef58eef96eb3a3c4..7ea24fc942c18c032048edc10dfe00b56bff991e 100644 (file)
@@ -8,7 +8,7 @@ git-svn - Bidirectional operation between a Subversion repository and Git
 SYNOPSIS
 --------
 [verse]
-'git svn' <command> [options] [arguments]
+'git svn' <command> [<options>] [<arguments>]
 
 DESCRIPTION
 -----------
@@ -635,7 +635,8 @@ config key: svn.findcopiesharder
 
 -A<filename>::
 --authors-file=<filename>::
-       Syntax is compatible with the file used by 'git cvsimport':
+       Syntax is compatible with the file used by 'git cvsimport' but
+       an empty email address can be supplied with '<>':
 +
 ------------------------------------------------------------------------
        loginname = Joe User <user@example.com>
@@ -654,8 +655,14 @@ config key: svn.authorsfile
        If this option is specified, for each SVN committer name that
        does not exist in the authors file, the given file is executed
        with the committer name as the first argument.  The program is
-       expected to return a single line of the form "Name <email>",
-       which will be treated as if included in the authors file.
+       expected to return a single line of the form "Name <email>" or
+       "Name <>", which will be treated as if included in the authors
+       file.
++
+Due to historical reasons a relative 'filename' is first searched
+relative to the current directory for 'init' and 'clone' and relative
+to the root of the working tree for 'fetch'. If 'filename' is
+not found, it is searched like any other command in '$PATH'.
 +
 [verse]
 config key: svn.authorsProg
@@ -700,7 +707,7 @@ creating the branch or tag.
 config key: svn.useLogAuthor
 
 --add-author-from::
-       When committing to svn from Git (as part of 'commit-diff', 'set-tree' or 'dcommit'
+       When committing to svn from Git (as part of 'set-tree' or 'dcommit'
        operations), if the existing log message doesn't already have a
        `From:` or `Signed-off-by:` line, append a `From:` line based on the
        Git commit's author string.  If you use this, then `--use-log-author`
index 1d17101bac39d64cc3d4aff89cd588955dd00735..87c4288ffc47ddd73162c85a27fe22c161b4a441 100644 (file)
@@ -34,8 +34,8 @@ in the tag message.
 If `-m <msg>` or `-F <file>` is given and `-a`, `-s`, and `-u <keyid>`
 are absent, `-a` is implied.
 
-Otherwise just a tag reference for the SHA-1 object name of the commit object is
-created (i.e. a lightweight tag).
+Otherwise, a tag reference that points directly at the given object
+(i.e., a lightweight tag) is created.
 
 A GnuPG signed tag object will be created when `-s` or `-u
 <keyid>` is used.  When `-u <keyid>` is not used, the
index 3897a59ee94bc424c2c66cb5d05bc0193fb6eaf2..4e8e762e68690cab880460fbe1fef0077c8351e2 100644 (file)
@@ -228,7 +228,7 @@ will remove the intended effect of the option.
        cleaner names.
        The same applies to directories ending '/' and paths with '//'
 
-Using --refresh
+USING --REFRESH
 ---------------
 `--refresh` does not calculate a new sha1 file or bring the index
 up to date for mode/content changes. But what it *does* do is to
@@ -239,7 +239,7 @@ the stat entry is out of date.
 For example, you'd want to do this after doing a 'git read-tree', to link
 up the stat index details with the proper files.
 
-Using --cacheinfo or --info-only
+USING --CACHEINFO OR --INFO-ONLY
 --------------------------------
 `--cacheinfo` is used to register a file that is not in the
 current working directory.  This is useful for minimum-checkout
@@ -261,7 +261,7 @@ useful when the file is available, but you do not wish to update the
 object database.
 
 
-Using --index-info
+USING --INDEX-INFO
 ------------------
 
 `--index-info` is a more powerful mechanism that lets you feed
@@ -317,7 +317,7 @@ $ git ls-files -s
 ------------
 
 
-Using ``assume unchanged'' bit
+USING ``ASSUME UNCHANGED'' BIT
 ------------------------------
 
 Many operations in Git depend on your filesystem to have an
@@ -350,7 +350,7 @@ the index (use `git update-index --really-refresh` if you want
 to mark them as "assume unchanged").
 
 
-Examples
+EXAMPLES
 --------
 To update and refresh only the files already checked out:
 
@@ -387,7 +387,7 @@ M foo.c
 <9> now it checks with lstat(2) and finds it has been changed.
 
 
-Skip-worktree bit
+SKIP-WORKTREE BIT
 -----------------
 
 Skip-worktree bit can be defined in one (long) sentence: When reading
@@ -407,7 +407,7 @@ Although this bit looks similar to assume-unchanged bit, its goal is
 different from assume-unchanged bit's. Skip-worktree also takes
 precedence over assume-unchanged bit when both are set.
 
-Split index
+SPLIT INDEX
 -----------
 
 This mode is designed for repositories with very large indexes, and
@@ -432,7 +432,7 @@ To avoid deleting a shared index file that is still used, its
 modification time is updated to the current time everytime a new split
 index based on the shared index file is either created or read from.
 
-Untracked cache
+UNTRACKED CACHE
 ---------------
 
 This cache is meant to speed up commands that involve determining
@@ -490,7 +490,7 @@ As with the bug described above the solution is to one-off do a "git
 status" run with `core.untrackedCache=false` to flush out the leftover
 bad data.
 
-File System Monitor
+FILE SYSTEM MONITOR
 -------------------
 
 This feature is intended to speed up git operations for repos that have
@@ -518,7 +518,7 @@ file system monitor is added to or removed from the index the next time
 a command reads the index. When `--[no-]fsmonitor` are used, the file
 system monitor is immediately added to or removed from the index.
 
-Configuration
+CONFIGURATION
 -------------
 
 The command honors `core.filemode` configuration variable.  If
index 969bfab2ab422ca8b7bdf2eb3ba45edc92fcd00b..bc8fdfd4691326b44e2cbdea3dc4925cf7440515 100644 (file)
@@ -120,7 +120,7 @@ modifications are performed.  Note that while each individual
 <ref> is updated or deleted atomically, a concurrent reader may
 still see a subset of the modifications.
 
-Logging Updates
+LOGGING UPDATES
 ---------------
 If config parameter "core.logAllRefUpdates" is true and the ref is one under
 "refs/heads/", "refs/remotes/", "refs/notes/", or the symbolic ref HEAD; or
index 44ff9541df1f5dd432d37b5828bfb800f66dfae8..6072f936ab5e3a8b3aeafcaeddd81b7b6d5e0b01 100644 (file)
@@ -23,14 +23,14 @@ OPTIONS
        as well. (However, the configuration variables listing functionality
        is deprecated in favor of `git config -l`.)
 
-EXAMPLE
+EXAMPLES
 --------
        $ git var GIT_AUTHOR_IDENT
        Eric W. Biederman <ebiederm@lnxi.com> 1121223278 -0600
 
 
 VARIABLES
-----------
+---------
 GIT_AUTHOR_IDENT::
     The author of a piece of code.
 
index 2d6b09a43cd63e3ad768f9b49ba67f1deda05111..fd952a5ff92b72e67eac219fdfbbe5d7c708be81 100644 (file)
@@ -8,7 +8,7 @@ git-web--browse - Git helper script to launch a web browser
 SYNOPSIS
 --------
 [verse]
-'git web{litdd}browse' [OPTIONS] URL/FILE ...
+'git web{litdd}browse' [<options>] <url|file>...
 
 DESCRIPTION
 -----------
@@ -84,7 +84,7 @@ variable exists then 'git web{litdd}browse' will treat the specified tool
 as a custom command and will use a shell eval to run the command with
 the URLs passed as arguments.
 
-Note about konqueror
+NOTE ABOUT KONQUEROR
 --------------------
 
 When 'konqueror' is specified by a command-line option or a
index e7eb24ab8528e39aa4e0a75f6feaa46d9cfb39fe..afc6576a14d56ea49e37d1251a5665bf77457f89 100644 (file)
@@ -14,7 +14,7 @@ SYNOPSIS
 'git worktree lock' [--reason <string>] <worktree>
 'git worktree move' <worktree> <new-path>
 'git worktree prune' [-n] [-v] [--expire <expire>]
-'git worktree remove' [--force] <worktree>
+'git worktree remove' [-f] <worktree>
 'git worktree unlock' <worktree>
 
 DESCRIPTION
@@ -27,11 +27,12 @@ out more than one branch at a time.  With `git worktree add` a new working
 tree is associated with the repository.  This new working tree is called a
 "linked working tree" as opposed to the "main working tree" prepared by "git
 init" or "git clone".  A repository has one main working tree (if it's not a
-bare repository) and zero or more linked working trees.
+bare repository) and zero or more linked working trees. When you are done
+with a linked working tree, remove it with `git worktree remove`.
 
-When you are done with a linked working tree you can simply delete it.
-The working tree's administrative files in the repository (see
-"DETAILS" below) will eventually be removed automatically (see
+If a working tree is deleted without using `git worktree remove`, then
+its associated administrative files, which reside in the repository
+(see "DETAILS" below), will eventually be removed automatically (see
 `gc.worktreePruneExpire` in linkgit:git-config[1]), or you can run
 `git worktree prune` in the main or any linked working tree to
 clean up any stale administrative files.
@@ -60,8 +61,13 @@ $ git worktree add --track -b <branch> <path> <remote>/<branch>
 ------------
 +
 If `<commit-ish>` is omitted and neither `-b` nor `-B` nor `--detach` used,
-then, as a convenience, a new branch based at HEAD is created automatically,
-as if `-b $(basename <path>)` was specified.
+then, as a convenience, the new worktree is associated with a branch
+(call it `<branch>`) named after `$(basename <path>)`.  If `<branch>`
+doesn't exist, a new branch based on HEAD is automatically created as
+if `-b <branch>` was given.  If `<branch>` does exist, it will be
+checked out in the new worktree, if it's not checked out anywhere
+else, otherwise the command will refuse to create the worktree (unless
+`--force` is used).
 
 list::
 
@@ -106,7 +112,7 @@ OPTIONS
        By default, `add` refuses to create a new working tree when
        `<commit-ish>` is a branch name and is already checked out by
        another working tree and `remove` refuses to remove an unclean
-       working tree. This option overrides that safeguard.
+       working tree. This option overrides these safeguards.
 
 -b <new-branch>::
 -B <new-branch>::
@@ -232,7 +238,7 @@ The worktree list command has two output formats.  The default format shows the
 details on a single line with columns.  For example:
 
 ------------
-S git worktree list
+$ git worktree list
 /path/to/bare-source            (bare)
 /path/to/linked-worktree        abcd1234 [master]
 /path/to/other-linked-worktree  1234abc  (detached HEAD)
@@ -247,7 +253,7 @@ if the value is true.  An empty line indicates the end of a worktree.  For
 example:
 
 ------------
-S git worktree list --porcelain
+$ git worktree list --porcelain
 worktree /path/to/bare-source
 bare
 
@@ -278,8 +284,7 @@ $ pushd ../temp
 # ... hack hack hack ...
 $ git commit -a -m 'emergency fix for boss'
 $ popd
-$ rm -rf ../temp
-$ git worktree prune
+$ git worktree remove ../temp
 ------------
 
 BUGS
index 4767860e72f46d4e4df883f2fdbb4a46eb8e8eda..dba7f0c18e33e7e26ca100992236e39b3d5b8a91 100644 (file)
@@ -11,7 +11,7 @@ SYNOPSIS
 [verse]
 'git' [--version] [--help] [-C <path>] [-c <name>=<value>]
     [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
-    [-p|--paginate|--no-pager] [--no-replace-objects] [--bare]
+    [-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare]
     [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
     [--super-prefix=<path>]
     <command> [<args>]
@@ -103,6 +103,7 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config
        configuration options (see the "Configuration Mechanism" section
        below).
 
+-P::
 --no-pager::
        Do not pipe Git output into a pager.
 
@@ -163,6 +164,16 @@ foo.bar= ...`) sets `foo.bar` to the empty string which `git config
        Do not perform optional operations that require locks. This is
        equivalent to setting the `GIT_OPTIONAL_LOCKS` to `0`.
 
+--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
+       parse-options), main (all commands in libexec directory),
+       others (all other commands in `$PATH` that have git- prefix),
+       list-<category> (see categories in command-list.txt),
+       nohelpers (exclude helper commands), alias and config
+       (retrieve command list from config variable completion.commands)
+
 GIT COMMANDS
 ------------
 
index 1094fe2b5b0cc97030dc6694364f473999a9f4d3..92010b062e08678fcfb0a143f75bbd4b07bfcf4b 100644 (file)
@@ -3,7 +3,7 @@ gitattributes(5)
 
 NAME
 ----
-gitattributes - defining attributes per path
+gitattributes - Defining attributes per path
 
 SYNOPSIS
 --------
@@ -279,6 +279,94 @@ few exceptions.  Even though...
   catch potential problems early, safety triggers.
 
 
+`working-tree-encoding`
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Git recognizes files encoded in ASCII or one of its supersets (e.g.
+UTF-8, ISO-8859-1, ...) as text files. Files encoded in certain other
+encodings (e.g. UTF-16) are interpreted as binary and consequently
+built-in Git text processing tools (e.g. 'git diff') as well as most Git
+web front ends do not visualize the contents of these files by default.
+
+In these cases you can tell Git the encoding of a file in the working
+directory with the `working-tree-encoding` attribute. If a file with this
+attribute is added to Git, then Git reencodes the content from the
+specified encoding to UTF-8. Finally, Git stores the UTF-8 encoded
+content in its internal data structure (called "the index"). On checkout
+the content is reencoded back to the specified encoding.
+
+Please note that using the `working-tree-encoding` attribute may have a
+number of pitfalls:
+
+- Alternative Git implementations (e.g. JGit or libgit2) and older Git
+  versions (as of March 2018) do not support the `working-tree-encoding`
+  attribute. If you decide to use the `working-tree-encoding` attribute
+  in your repository, then it is strongly recommended to ensure that all
+  clients working with the repository support it.
+
+  For example, Microsoft Visual Studio resources files (`*.rc`) or
+  PowerShell script files (`*.ps1`) are sometimes encoded in UTF-16.
+  If you declare `*.ps1` as files as UTF-16 and you add `foo.ps1` with
+  a `working-tree-encoding` enabled Git client, then `foo.ps1` will be
+  stored as UTF-8 internally. A client without `working-tree-encoding`
+  support will checkout `foo.ps1` as UTF-8 encoded file. This will
+  typically cause trouble for the users of this file.
+
+  If a Git client, that does not support the `working-tree-encoding`
+  attribute, adds a new file `bar.ps1`, then `bar.ps1` will be
+  stored "as-is" internally (in this example probably as UTF-16).
+  A client with `working-tree-encoding` support will interpret the
+  internal contents as UTF-8 and try to convert it to UTF-16 on checkout.
+  That operation will fail and cause an error.
+
+- Reencoding content to non-UTF encodings can cause errors as the
+  conversion might not be UTF-8 round trip safe. If you suspect your
+  encoding to not be round trip safe, then add it to
+  `core.checkRoundtripEncoding` to make Git check the round trip
+  encoding (see linkgit:git-config[1]). SHIFT-JIS (Japanese character
+  set) is known to have round trip issues with UTF-8 and is checked by
+  default.
+
+- Reencoding content requires resources that might slow down certain
+  Git operations (e.g 'git checkout' or 'git add').
+
+Use the `working-tree-encoding` attribute only if you cannot store a file
+in UTF-8 encoding and if you want Git to be able to process the content
+as text.
+
+As an example, use the following attributes if your '*.ps1' files are
+UTF-16 encoded with byte order mark (BOM) and you want Git to perform
+automatic line ending conversion based on your platform.
+
+------------------------
+*.ps1          text working-tree-encoding=UTF-16
+------------------------
+
+Use the following attributes if your '*.ps1' files are UTF-16 little
+endian encoded without BOM and you want Git to use Windows line endings
+in the working directory. Please note, it is highly recommended to
+explicitly define the line endings with `eol` if the `working-tree-encoding`
+attribute is used to avoid ambiguity.
+
+------------------------
+*.ps1          text working-tree-encoding=UTF-16LE eol=CRLF
+------------------------
+
+You can get a list of all available encodings on your platform with the
+following command:
+
+------------------------
+iconv --list
+------------------------
+
+If you do not know the encoding of a file, then you can use the `file`
+command to guess the encoding:
+
+------------------------
+file foo.ps1
+------------------------
+
+
 `ident`
 ^^^^^^^
 
@@ -1141,8 +1229,8 @@ to:
 ------------
 
 
-EXAMPLE
--------
+EXAMPLES
+--------
 
 If you have these three `gitattributes` file:
 
index 9f13266a685176bf142d9e381d7a9d10ea12aa7b..592e06d839d87f28cf6cbbdcf3aa3253da2eb9f0 100644 (file)
@@ -110,8 +110,8 @@ couple of magic command-line options:
 +
 ---------------------------------------------
 $ git describe -h
-usage: git describe [options] <commit-ish>*
-   or: git describe [options] --dirty
+usage: git describe [<options>] <commit-ish>*
+   or: git describe [<options>] --dirty
 
     --contains            find the tag that comes after the commit
     --debug               debug search strategy on stderr
index f877f7b7cd19c3fb1d2ce1263d64c94798c5130d..e3c283a174c46352f26e3e6a957e72b76bf82680 100644 (file)
@@ -31,7 +31,7 @@ Hooks can get their arguments via the environment, command-line
 arguments, and stdin. See the documentation for each hook below for
 details.
 
-'git init' may copy hooks to the new repository, depending on its
+`git init` may copy hooks to the new repository, depending on its
 configuration. See the "TEMPLATE DIRECTORY" section in
 linkgit:git-init[1] for details. When the rest of this document refers
 to "default hooks" it's talking about the default template shipped
@@ -45,9 +45,9 @@ HOOKS
 applypatch-msg
 ~~~~~~~~~~~~~~
 
-This hook is invoked by 'git am'.  It takes a single
+This hook is invoked by linkgit:git-am[1].  It takes a single
 parameter, the name of the file that holds the proposed commit
-log message.  Exiting with a non-zero status causes 'git am' to abort
+log message.  Exiting with a non-zero status causes `git am` to abort
 before applying the patch.
 
 The hook is allowed to edit the message file in place, and can
@@ -61,7 +61,7 @@ The default 'applypatch-msg' hook, when enabled, runs the
 pre-applypatch
 ~~~~~~~~~~~~~~
 
-This hook is invoked by 'git am'.  It takes no parameter, and is
+This hook is invoked by linkgit:git-am[1].  It takes no parameter, and is
 invoked after the patch is applied, but before a commit is made.
 
 If it exits with non-zero status, then the working tree will not be
@@ -76,33 +76,33 @@ The default 'pre-applypatch' hook, when enabled, runs the
 post-applypatch
 ~~~~~~~~~~~~~~~
 
-This hook is invoked by 'git am'.  It takes no parameter,
+This hook is invoked by linkgit:git-am[1].  It takes no parameter,
 and is invoked after the patch is applied and a commit is made.
 
 This hook is meant primarily for notification, and cannot affect
-the outcome of 'git am'.
+the outcome of `git am`.
 
 pre-commit
 ~~~~~~~~~~
 
-This hook is invoked by 'git commit', and can be bypassed
+This hook is invoked by linkgit:git-commit[1], and can be bypassed
 with the `--no-verify` option.  It takes no parameters, and is
 invoked before obtaining the proposed commit log message and
 making a commit.  Exiting with a non-zero status from this script
-causes the 'git commit' command to abort before creating a commit.
+causes the `git commit` command to abort before creating a commit.
 
 The default 'pre-commit' hook, when enabled, catches introduction
 of lines with trailing whitespaces and aborts the commit when
 such a line is found.
 
-All the 'git commit' hooks are invoked with the environment
+All the `git commit` hooks are invoked with the environment
 variable `GIT_EDITOR=:` if the command will not bring up an editor
 to modify the commit message.
 
 prepare-commit-msg
 ~~~~~~~~~~~~~~~~~~
 
-This hook is invoked by 'git commit' right after preparing the
+This hook is invoked by linkgit:git-commit[1] right after preparing the
 default log message, and before the editor is started.
 
 It takes one to three parameters.  The first is the name of the file
@@ -114,7 +114,7 @@ commit is a merge or a `.git/MERGE_MSG` file exists); `squash`
 (if a `.git/SQUASH_MSG` file exists); or `commit`, followed by
 a commit SHA-1 (if a `-c`, `-C` or `--amend` option was given).
 
-If the exit status is non-zero, 'git commit' will abort.
+If the exit status is non-zero, `git commit` will abort.
 
 The purpose of the hook is to edit the message file in place, and
 it is not suppressed by the `--no-verify` option.  A non-zero exit
@@ -127,7 +127,7 @@ help message found in the commented portion of the commit template.
 commit-msg
 ~~~~~~~~~~
 
-This hook is invoked by 'git commit' and 'git merge', and can be
+This hook is invoked by linkgit:git-commit[1] and linkgit:git-merge[1], and can be
 bypassed with the `--no-verify` option.  It takes a single parameter,
 the name of the file that holds the proposed commit log message.
 Exiting with a non-zero status causes the command to abort.
@@ -143,16 +143,16 @@ The default 'commit-msg' hook, when enabled, detects duplicate
 post-commit
 ~~~~~~~~~~~
 
-This hook is invoked by 'git commit'. It takes no parameters, and is
+This hook is invoked by linkgit:git-commit[1]. It takes no parameters, and is
 invoked after a commit is made.
 
 This hook is meant primarily for notification, and cannot affect
-the outcome of 'git commit'.
+the outcome of `git commit`.
 
 pre-rebase
 ~~~~~~~~~~
 
-This hook is called by 'git rebase' and can be used to prevent a
+This hook is called by linkgit:git-rebase[1] and can be used to prevent a
 branch from getting rebased.  The hook may be called with one or
 two parameters.  The first parameter is the upstream from which
 the series was forked.  The second parameter is the branch being
@@ -161,17 +161,17 @@ rebased, and is not set when rebasing the current branch.
 post-checkout
 ~~~~~~~~~~~~~
 
-This hook is invoked when a 'git checkout' is run after having updated the
+This hook is invoked when a linkgit:git-checkout[1] is run after having updated the
 worktree.  The hook is given three parameters: the ref of the previous HEAD,
 the ref of the new HEAD (which may or may not have changed), and a flag
 indicating whether the checkout was a branch checkout (changing branches,
 flag=1) or a file checkout (retrieving a file from the index, flag=0).
-This hook cannot affect the outcome of 'git checkout'.
+This hook cannot affect the outcome of `git checkout`.
 
-It is also run after 'git clone', unless the --no-checkout (-n) option is
+It is also run after linkgit:git-clone[1], unless the `--no-checkout` (`-n`) option is
 used. The first parameter given to the hook is the null-ref, the second the
-ref of the new HEAD and the flag is always 1. Likewise for 'git worktree add'
-unless --no-checkout is used.
+ref of the new HEAD and the flag is always 1. Likewise for `git worktree add`
+unless `--no-checkout` is used.
 
 This hook can be used to perform repository validity checks, auto-display
 differences from the previous HEAD if different, or set working dir metadata
@@ -180,10 +180,10 @@ properties.
 post-merge
 ~~~~~~~~~~
 
-This hook is invoked by 'git merge', which happens when a 'git pull'
+This hook is invoked by linkgit:git-merge[1], which happens when a `git pull`
 is done on a local repository.  The hook takes a single parameter, a status
 flag specifying whether or not the merge being done was a squash merge.
-This hook cannot affect the outcome of 'git merge' and is not executed,
+This hook cannot affect the outcome of `git merge` and is not executed,
 if the merge failed due to conflicts.
 
 This hook can be used in conjunction with a corresponding pre-commit hook to
@@ -194,10 +194,10 @@ for an example of how to do this.
 pre-push
 ~~~~~~~~
 
-This hook is called by 'git push' and can be used to prevent a push from taking
-place.  The hook is called with two parameters which provide the name and
-location of the destination remote, if a named remote is not being used both
-values will be the same.
+This hook is called by linkgit:git-push[1] and can be used to prevent
+a push from taking place.  The hook is called with two parameters
+which provide the name and location of the destination remote, if a
+named remote is not being used both values will be the same.
 
 Information about what is to be pushed is provided on the hook's standard
 input with lines of the form:
@@ -216,7 +216,7 @@ SHA-1>` will be 40 `0`.  If the local commit was specified by something other
 than a name which could be expanded (such as `HEAD~`, or a SHA-1) it will be
 supplied as it was originally given.
 
-If this hook exits with a non-zero status, 'git push' will abort without
+If this hook exits with a non-zero status, `git push` will abort without
 pushing anything.  Information about why the push is rejected may be sent
 to the user by writing to standard error.
 
@@ -224,8 +224,8 @@ to the user by writing to standard error.
 pre-receive
 ~~~~~~~~~~~
 
-This hook is invoked by 'git-receive-pack' when it reacts to
-'git push' and updates reference(s) in its repository.
+This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
+`git push` and updates reference(s) in its repository.
 Just before starting to update refs on the remote repository, the
 pre-receive hook is invoked.  Its exit status determines the success
 or failure of the update.
@@ -246,7 +246,7 @@ updated. If the hook exits with zero, updating of individual refs can
 still be prevented by the <<update,'update'>> hook.
 
 Both standard output and standard error output are forwarded to
-'git send-pack' on the other end, so you can simply `echo` messages
+`git send-pack` on the other end, so you can simply `echo` messages
 for the user.
 
 The number of push options given on the command line of
@@ -265,8 +265,8 @@ linkgit:git-receive-pack[1] for some caveats.
 update
 ~~~~~~
 
-This hook is invoked by 'git-receive-pack' when it reacts to
-'git push' and updates reference(s) in its repository.
+This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
+`git push` and updates reference(s) in its repository.
 Just before updating the ref on the remote repository, the update hook
 is invoked.  Its exit status determines the success or failure of
 the ref update.
@@ -279,7 +279,7 @@ three parameters:
  - and the new object name to be stored in the ref.
 
 A zero exit from the update hook allows the ref to be updated.
-Exiting with a non-zero status prevents 'git-receive-pack'
+Exiting with a non-zero status prevents `git receive-pack`
 from updating that ref.
 
 This hook can be used to prevent 'forced' update on certain refs by
@@ -299,7 +299,7 @@ membership. See linkgit:git-shell[1] for how you might use the login
 shell to restrict the user's access to only git commands.
 
 Both standard output and standard error output are forwarded to
-'git send-pack' on the other end, so you can simply `echo` messages
+`git send-pack` on the other end, so you can simply `echo` messages
 for the user.
 
 The default 'update' hook, when enabled--and with
@@ -310,8 +310,8 @@ unannotated tags to be pushed.
 post-receive
 ~~~~~~~~~~~~
 
-This hook is invoked by 'git-receive-pack' when it reacts to
-'git push' and updates reference(s) in its repository.
+This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
+`git push` and updates reference(s) in its repository.
 It executes on the remote repository once after all the refs have
 been updated.
 
@@ -320,7 +320,7 @@ arguments, but gets the same information as the
 <<pre-receive,'pre-receive'>>
 hook does on its standard input.
 
-This hook does not affect the outcome of 'git-receive-pack', as it
+This hook does not affect the outcome of `git receive-pack`, as it
 is called after the real work is done.
 
 This supersedes the <<post-update,'post-update'>> hook in that it gets
@@ -328,7 +328,7 @@ both old and new values of all the refs in addition to their
 names.
 
 Both standard output and standard error output are forwarded to
-'git send-pack' on the other end, so you can simply `echo` messages
+`git send-pack` on the other end, so you can simply `echo` messages
 for the user.
 
 The default 'post-receive' hook is empty, but there is
@@ -349,8 +349,8 @@ will be set to zero, `GIT_PUSH_OPTION_COUNT=0`.
 post-update
 ~~~~~~~~~~~
 
-This hook is invoked by 'git-receive-pack' when it reacts to
-'git push' and updates reference(s) in its repository.
+This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
+`git push` and updates reference(s) in its repository.
 It executes on the remote repository once after all the refs have
 been updated.
 
@@ -358,7 +358,7 @@ It takes a variable number of parameters, each of which is the
 name of ref that was actually updated.
 
 This hook is meant primarily for notification, and cannot affect
-the outcome of 'git-receive-pack'.
+the outcome of `git receive-pack`.
 
 The 'post-update' hook can tell what are the heads that were pushed,
 but it does not know what their original and updated values are,
@@ -368,20 +368,20 @@ updated values of the refs. You might consider it instead if you need
 them.
 
 When enabled, the default 'post-update' hook runs
-'git update-server-info' to keep the information used by dumb
+`git update-server-info` to keep the information used by dumb
 transports (e.g., HTTP) up to date.  If you are publishing
 a Git repository that is accessible via HTTP, you should
 probably enable this hook.
 
 Both standard output and standard error output are forwarded to
-'git send-pack' on the other end, so you can simply `echo` messages
+`git send-pack` on the other end, so you can simply `echo` messages
 for the user.
 
 push-to-checkout
 ~~~~~~~~~~~~~~~~
 
-This hook is invoked by 'git-receive-pack' when it reacts to
-'git push' and updates reference(s) in its repository, and when
+This hook is invoked by linkgit:git-receive-pack[1] when it reacts to
+`git push` and updates reference(s) in its repository, and when
 the push tries to update the branch that is currently checked out
 and the `receive.denyCurrentBranch` configuration variable is set to
 `updateInstead`.  Such a push by default is refused if the working
@@ -400,8 +400,8 @@ when the tip of the current branch is updated to the new commit, and
 exit with a zero status.
 
 For example, the hook can simply run `git read-tree -u -m HEAD "$1"`
-in order to emulate 'git fetch' that is run in the reverse direction
-with `git push`, as the two-tree form of `read-tree -u -m` is
+in order to emulate `git fetch` that is run in the reverse direction
+with `git push`, as the two-tree form of `git read-tree -u -m` is
 essentially the same as `git checkout` that switches branches while
 keeping the local changes in the working tree that do not interfere
 with the difference between the branches.
@@ -410,15 +410,16 @@ with the difference between the branches.
 pre-auto-gc
 ~~~~~~~~~~~
 
-This hook is invoked by 'git gc --auto'. It takes no parameter, and
-exiting with non-zero status from this script causes the 'git gc --auto'
-to abort.
+This hook is invoked by `git gc --auto` (see linkgit:git-gc[1]). It
+takes no parameter, and exiting with non-zero status from this script
+causes the `git gc --auto` to abort.
 
 post-rewrite
 ~~~~~~~~~~~~
 
-This hook is invoked by commands that rewrite commits (`git commit
---amend`, 'git-rebase'; currently 'git-filter-branch' does 'not' call
+This hook is invoked by commands that rewrite commits
+(linkgit:git-commit[1] when called with `--amend` and
+linkgit:git-rebase[1]; currently `git filter-branch` does 'not' call
 it!).  Its first argument denotes the command it was invoked by:
 currently one of `amend` or `rebase`.  Further command-dependent
 arguments may be passed in the future.
@@ -450,16 +451,16 @@ processed by rebase.
 sendemail-validate
 ~~~~~~~~~~~~~~~~~~
 
-This hook is invoked by 'git send-email'.  It takes a single parameter,
+This hook is invoked by linkgit:git-send-email[1].  It takes a single parameter,
 the name of the file that holds the e-mail to be sent.  Exiting with a
-non-zero status causes 'git send-email' to abort before sending any
+non-zero status causes `git send-email` to abort before sending any
 e-mails.
 
 fsmonitor-watchman
 ~~~~~~~~~~~~~~~~~~
 
-This hook is invoked when the configuration option core.fsmonitor is
-set to .git/hooks/fsmonitor-watchman.  It takes two arguments, a version
+This hook is invoked when the configuration option `core.fsmonitor` is
+set to `.git/hooks/fsmonitor-watchman`.  It takes two arguments, a version
 (currently 1) and the time in elapsed nanoseconds since midnight,
 January 1, 1970.
 
@@ -478,7 +479,7 @@ directories are checked for untracked files based on the path names
 given.
 
 An optimized way to tell git "all files have changed" is to return
-the filename '/'.
+the filename `/`.
 
 The exit status determines whether git will use the data from the
 hook to limit its search.  On error, it will fall back to verifying
index ca96c281d1f3abbf71cdac112a019d2849e7ad0b..244cd01493127035b27fb19416f1f4027a726bba 100644 (file)
@@ -8,7 +8,7 @@ gitk - The Git repository browser
 SYNOPSIS
 --------
 [verse]
-'gitk' [<options>] [<revision range>] [\--] [<path>...]
+'gitk' [<options>] [<revision range>] [--] [<path>...]
 
 DESCRIPTION
 -----------
index ac44a1510ca2cffba668d4d1a4da00bf3122972c..4caf5d8e3f9e00b1f1be507c92b61c82173e03e6 100644 (file)
@@ -3,7 +3,7 @@ gitmodules(5)
 
 NAME
 ----
-gitmodules - defining submodule properties
+gitmodules - Defining submodule properties
 
 SYNOPSIS
 --------
index 4b8c93ec59de3db02b9914aed4955d486be5f875..9d1459aac6d0b12ad1a87ff25a158dca0f2bf470 100644 (file)
@@ -102,6 +102,14 @@ Capabilities for Pushing
 +
 Supported commands: 'connect'.
 
+'stateless-connect'::
+       Experimental; for internal use only.
+       Can attempt to connect to a remote server for communication
+       using git's wire-protocol version 2.  See the documentation
+       for the stateless-connect command for more information.
++
+Supported commands: 'stateless-connect'.
+
 'push'::
        Can discover remote refs and push local commits and the
        history leading up to them to new or existing remote refs.
@@ -136,6 +144,14 @@ Capabilities for Fetching
 +
 Supported commands: 'connect'.
 
+'stateless-connect'::
+       Experimental; for internal use only.
+       Can attempt to connect to a remote server for communication
+       using git's wire-protocol version 2.  See the documentation
+       for the stateless-connect command for more information.
++
+Supported commands: 'stateless-connect'.
+
 'fetch'::
        Can discover remote refs and transfer objects reachable from
        them to the local object store.
@@ -375,6 +391,22 @@ Supported if the helper has the "export" capability.
 +
 Supported if the helper has the "connect" capability.
 
+'stateless-connect' <service>::
+       Experimental; for internal use only.
+       Connects to the given remote service for communication using
+       git's wire-protocol version 2.  Valid replies to this command
+       are empty line (connection established), 'fallback' (no smart
+       transport support, fall back to dumb transports) and just
+       exiting with error message printed (can't connect, don't bother
+       trying to fall back).  After line feed terminating the positive
+       (empty) response, the output of the service starts.  Messages
+       (both request and response) must consist of zero or more
+       PKT-LINEs, terminating in a flush packet. The client must not
+       expect the server to store any state in between request-response
+       pairs.  After the connection ends, the remote helper exits.
++
+Supported if the helper has the "stateless-connect" capability.
+
 If a fatal error occurs, the program writes the error message to
 stderr and exits. The caller should expect that a suitable error
 message has been printed if the child closes the connection without
index c60bcad44aa581b2449a7a638b6487c1c73e8c23..e85148f05eb79a968ad84bac6ce7a88289270c49 100644 (file)
@@ -275,11 +275,6 @@ worktrees/<id>/locked::
        or manually by `git worktree prune`. The file may contain a string
        explaining why the repository is locked.
 
-worktrees/<id>/link::
-       If this file exists, it is a hard link to the linked .git
-       file. It is used to detect if the linked repository is
-       manually removed.
-
 SEE ALSO
 --------
 linkgit:git-init[1],
index 27dec5b91d08bbdb114400dd3c86a8cf515e8774..1f6cceaefb028e5f96d802703a25a16e950a3e17 100644 (file)
@@ -3,7 +3,7 @@ gitrevisions(7)
 
 NAME
 ----
-gitrevisions - specifying revisions and ranges for Git
+gitrevisions - Specifying revisions and ranges for Git
 
 SYNOPSIS
 --------
index 926e044d098bc1399c923c4f204bca5d4a7a37bf..ca11c7bdafb91bc2f6ae71ca18a2f6b45e5f38b0 100644 (file)
@@ -107,7 +107,7 @@ the unstable branch into the stable one.  Hence the following:
 .Merge upwards
 [caption="Rule: "]
 =====================================
-Always commit your fixes to the oldest supported branch that require
+Always commit your fixes to the oldest supported branch that requires
 them.  Then (periodically) merge the integration branches upwards into each
 other.
 =====================================
index 6b8888d123826179ace38660f5043d897eb5ce70..6c2d23dc489474958d39d8053fc799b8616aafee 100644 (file)
@@ -463,7 +463,7 @@ exclude;;
 [[def_push]]push::
        Pushing a <<def_branch,branch>> means to get the branch's
        <<def_head_ref,head ref>> from a remote <<def_repository,repository>>,
-       find out if it is a direct ancestor to the branch's local
+       find out if it is an ancestor to the branch's local
        head ref, and in that case, putting all
        objects, which are <<def_reachable,reachable>> from the local
        head ref, and which are missing from the remote
index 9c4cd0915fe3f3e14879184f3a474e559130bdef..8994e2559eac0c5746ca898b0bad1946a7b83298 100644 (file)
@@ -80,7 +80,7 @@ valid pack like:
     # now add our object data
     cat object >>tmp.pack
     # and then append the pack trailer
-    /path/to/git.git/test-sha1 -b <tmp.pack >trailer
+    /path/to/git.git/t/helper/test-tool sha1 -b <tmp.pack >trailer
     cat trailer >>tmp.pack
 ------------
 
index 12b6bbf591ee801e0723f59db0e0abe7dc88ec73..662c2713cab4b9762dded702897d9e92ee0a0549 100644 (file)
@@ -35,7 +35,13 @@ include::fmt-merge-msg-config.txt[]
 merge.renameLimit::
        The number of files to consider when performing rename detection
        during a merge; if not specified, defaults to the value of
-       diff.renameLimit.
+       diff.renameLimit. This setting has no effect if rename detection
+       is turned off.
+
+merge.renames::
+       Whether and how Git detects renames.  If set to "false",
+       rename detection is disabled. If set to "true", basic rename
+       detection is enabled.  Defaults to the value of diff.renames.
 
 merge.renormalize::
        Tell Git that canonical representation of files in the
index 4a58aad4b83b9e365b57a8afa71f1ab939c47aee..aa66cbe41eaf070a74d98801ba973daeb8d15106 100644 (file)
@@ -23,8 +23,9 @@ recursive::
        causing mismerges by tests done on actual merge commits
        taken from Linux 2.6 kernel development history.
        Additionally this can detect and handle merges involving
-       renames.  This is the default merge strategy when
-       pulling or merging one branch.
+       renames, but currently cannot make use of detected
+       copies.  This is the default merge strategy when pulling
+       or merging one branch.
 +
 The 'recursive' strategy can take the following options:
 
@@ -84,12 +85,14 @@ no-renormalize;;
        `merge.renormalize` configuration variable.
 
 no-renames;;
-       Turn off rename detection.
+       Turn off rename detection. This overrides the `merge.renames`
+       configuration variable.
        See also linkgit:git-diff[1] `--no-renames`.
 
 find-renames[=<n>];;
        Turn on rename detection, optionally setting the similarity
-       threshold.  This is the default.
+       threshold.  This is the default. This overrides the
+       'merge.renames' configuration variable.
        See also linkgit:git-diff[1] `--find-renames`.
 
 rename-threshold=<n>;;
index dfcc49c72c0fe8f90c5e66d8de30d7ad27582c2b..7d1bd440944149bb8de03a9a202e46c85ec646f2 100644 (file)
@@ -7,6 +7,10 @@ syntax.  Here are various ways to spell object names.  The
 ones listed near the end of this list name trees and
 blobs contained in a commit.
 
+NOTE: This document shows the "raw" syntax as seen by git. The shell
+and other UIs might require additional quoting to protect special
+characters and to avoid word splitting.
+
 '<sha1>', e.g. 'dae86e1950b1277e545cee180551750029cfe735', 'dae86e'::
   The full SHA-1 object name (40-byte hexadecimal string), or
   a leading substring that is unique within the repository.
@@ -186,6 +190,8 @@ existing tag object.
   is matched. ':/!-foo' performs a negative match, while ':/!!foo' matches a
   literal '!' character, followed by 'foo'. Any other sequence beginning with
   ':/!' is reserved for now.
+  Depending on the given text, the shell's word splitting rules might
+  require additional quoting.
 
 '<rev>:<path>', e.g. 'HEAD:README', ':README', 'master:./README'::
   A suffix ':' followed by a path names the blob or tree
@@ -345,6 +351,7 @@ Here are a handful of examples using the Loeliger illustration above,
 with each step in the notation's expansion and selection carefully
 spelt out:
 
+....
    Args   Expanded arguments    Selected commits
    D                            G H D
    D F                          G H I J D F
@@ -367,3 +374,4 @@ spelt out:
          = B ^B^1 ^B^2 ^B^3
          = B ^D ^E ^F          B
    F^! D  = F ^I ^J D           G H D F
+....
index 9a778b0cad02faab3ce6bd7f89c24a17de45b777..fa39ac9d719b57e0df33441b11144bede4822621 100644 (file)
@@ -47,21 +47,23 @@ will first feed the user-wide one to the callback, and then the
 repo-specific one; by overwriting, the higher-priority repo-specific
 value is left at the end).
 
-The `git_config_with_options` function lets the caller examine config
+The `config_with_options` function lets the caller examine config
 while adjusting some of the default behavior of `git_config`. It should
 almost never be used by "regular" Git code that is looking up
 configuration variables. It is intended for advanced callers like
 `git-config`, which are intentionally tweaking the normal config-lookup
 process. It takes two extra parameters:
 
-`filename`::
-If this parameter is non-NULL, it specifies the name of a file to
-parse for configuration, rather than looking in the usual files. Regular
-`git_config` defaults to `NULL`.
+`config_source`::
+If this parameter is non-NULL, it specifies the source to parse for
+configuration, rather than looking in the usual files. See `struct
+git_config_source` in `config.h` for details. Regular `git_config` defaults
+to `NULL`.
 
-`respect_includes`::
-Specify whether include directives should be followed in parsed files.
-Regular `git_config` defaults to `1`.
+`opts`::
+Specify options to adjust the behavior of parsing config files. See `struct
+config_options` in `config.h` for details. As an example: regular `git_config`
+sets `opts.respect_includes` to `1` by default.
 
 Reading Specific Files
 ----------------------
index 7fae00f44fe1798da82bfdbb902479a03d583843..4f44ca24f6457e6acf208d7068dfcd02039cf41b 100644 (file)
@@ -53,7 +53,7 @@ The notable options are:
        not be returned even if all of its contents are ignored. In
        this case, the contents are returned as individual entries.
 +
-If this is set, files and directories that explicity match an ignore
+If this is set, files and directories that explicitly match an ignore
 pattern are reported. Implicity ignored directories (directories that
 do not match an ignore pattern, but whose contents are all ignored)
 are not reported, instead all of the contents are reported.
index a1162e5bcd19ba509fff39bceca49e1b33e2add2..5b29622d00ea61808176a27bdc2a86971d297749 100644 (file)
@@ -1,7 +1,7 @@
 object access API
 =================
 
-Talk about <sha1_file.c> and <object.h> family, things like
+Talk about <sha1-file.c> and <object.h> family, things like
 
 * read_sha1_file()
 * read_object_with_reference()
index b0c11f868da3c66ae263ca2755137420ce022b71..9febfb1d528b2764d6d603ea25eae0ac6b048f68 100644 (file)
@@ -35,13 +35,18 @@ Functions
        Free all memory associated with the array and return it to the
        initial, empty state.
 
+`oid_array_for_each`::
+       Iterate over each element of the list, executing the callback
+       function for each one. Does not sort the list, so any custom
+       hash order is retained. If the callback returns a non-zero
+       value, the iteration ends immediately and the callback's
+       return is propagated; otherwise, 0 is returned.
+
 `oid_array_for_each_unique`::
-       Efficiently iterate over each unique element of the list,
-       executing the callback function for each one. If the array is
-       not sorted, this function has the side effect of sorting it. If
-       the callback returns a non-zero value, the iteration ends
-       immediately and the callback's return is propagated; otherwise,
-       0 is returned.
+       Iterate over each unique element of the list in sorted order,
+       but otherwise behave like `oid_array_for_each`. If the array
+       is not sorted, this function has the side effect of sorting
+       it.
 
 Examples
 --------
index ee907c4a82a9127c0abc67b8a5dd215a3b0535d4..fb060893931f2e74c5857c2d03b019e1fa138976 100644 (file)
@@ -38,7 +38,7 @@ Data Structures
 Functions
 ---------
 
-`void submodule_free()`::
+`void submodule_free(struct repository *r)`::
 
        Use these to free the internally cached values.
 
diff --git a/Documentation/technical/commit-graph-format.txt b/Documentation/technical/commit-graph-format.txt
new file mode 100644 (file)
index 0000000..ad6af81
--- /dev/null
@@ -0,0 +1,97 @@
+Git commit graph format
+=======================
+
+The Git commit graph stores a list of commit OIDs and some associated
+metadata, including:
+
+- The generation number of the commit. Commits with no parents have
+  generation number 1; commits with parents have generation number
+  one more than the maximum generation number of its parents. We
+  reserve zero as special, and can be used to mark a generation
+  number invalid or as "not computed".
+
+- The root tree OID.
+
+- The commit date.
+
+- The parents of the commit, stored using positional references within
+  the graph file.
+
+These positional references are stored as unsigned 32-bit integers
+corresponding to the array position withing the list of commit OIDs. We
+use the most-significant bit for special purposes, so we can store at most
+(1 << 31) - 1 (around 2 billion) commits.
+
+== Commit graph files have the following format:
+
+In order to allow extensions that add extra data to the graph, we organize
+the body into "chunks" and provide a binary lookup table at the beginning
+of the body. The header includes certain values, such as number of chunks
+and hash type.
+
+All 4-byte numbers are in network order.
+
+HEADER:
+
+  4-byte signature:
+      The signature is: {'C', 'G', 'P', 'H'}
+
+  1-byte version number:
+      Currently, the only valid version is 1.
+
+  1-byte Hash Version (1 = SHA-1)
+      We infer the hash length (H) from this value.
+
+  1-byte number (C) of "chunks"
+
+  1-byte (reserved for later use)
+     Current clients should ignore this value.
+
+CHUNK LOOKUP:
+
+  (C + 1) * 12 bytes listing the table of contents for the chunks:
+      First 4 bytes describe the chunk id. Value 0 is a terminating label.
+      Other 8 bytes provide the byte-offset in current file for chunk to
+      start. (Chunks are ordered contiguously in the file, so you can infer
+      the length using the next chunk position if necessary.) Each chunk
+      ID appears at most once.
+
+  The remaining data in the body is described one chunk at a time, and
+  these chunks may be given in any order. Chunks are required unless
+  otherwise specified.
+
+CHUNK DATA:
+
+  OID Fanout (ID: {'O', 'I', 'D', 'F'}) (256 * 4 bytes)
+      The ith entry, F[i], stores the number of OIDs with first
+      byte at most i. Thus F[255] stores the total
+      number of commits (N).
+
+  OID Lookup (ID: {'O', 'I', 'D', 'L'}) (N * H bytes)
+      The OIDs for all commits in the graph, sorted in ascending order.
+
+  Commit Data (ID: {'C', 'G', 'E', 'T' }) (N * (H + 16) bytes)
+    * The first H bytes are for the OID of the root tree.
+    * The next 8 bytes are for the positions of the first two parents
+      of the ith commit. Stores value 0xffffffff if no parent in that
+      position. If there are more than two parents, the second value
+      has its most-significant bit on and the other bits store an array
+      position into the Large Edge List chunk.
+    * The next 8 bytes store the generation number of the commit and
+      the commit time in seconds since EPOCH. The generation number
+      uses the higher 30 bits of the first 4 bytes, while the commit
+      time uses the 32 bits of the second 4 bytes, along with the lowest
+      2 bits of the lowest byte, storing the 33rd and 34th bit of the
+      commit time.
+
+  Large Edge List (ID: {'E', 'D', 'G', 'E'}) [Optional]
+      This list of 4-byte values store the second through nth parents for
+      all octopus merges. The second parent value in the commit data stores
+      an array position within this list along with the most-significant bit
+      on. Starting at that array position, iterate through this list of commit
+      positions for the parents until reaching a value with the most-significant
+      bit on. The other bits correspond to the position of the last parent.
+
+TRAILER:
+
+       H-byte HASH-checksum of all of the above.
diff --git a/Documentation/technical/commit-graph.txt b/Documentation/technical/commit-graph.txt
new file mode 100644 (file)
index 0000000..0550c6d
--- /dev/null
@@ -0,0 +1,163 @@
+Git Commit Graph Design Notes
+=============================
+
+Git walks the commit graph for many reasons, including:
+
+1. Listing and filtering commit history.
+2. Computing merge bases.
+
+These operations can become slow as the commit count grows. The merge
+base calculation shows up in many user-facing commands, such as 'merge-base'
+or 'status' and can take minutes to compute depending on history shape.
+
+There are two main costs here:
+
+1. Decompressing and parsing commits.
+2. Walking the entire graph to satisfy topological order constraints.
+
+The commit graph file is a supplemental data structure that accelerates
+commit graph walks. If a user downgrades or disables the 'core.commitGraph'
+config setting, then the existing ODB is sufficient. The file is stored
+as "commit-graph" either in the .git/objects/info directory or in the info
+directory of an alternate.
+
+The commit graph file stores the commit graph structure along with some
+extra metadata to speed up graph walks. By listing commit OIDs in lexi-
+cographic order, we can identify an integer position for each commit and
+refer to the parents of a commit using those integer positions. We use
+binary search to find initial commits and then use the integer positions
+for fast lookups during the walk.
+
+A consumer may load the following info for a commit from the graph:
+
+1. The commit OID.
+2. The list of parents, along with their integer position.
+3. The commit date.
+4. The root tree OID.
+5. The generation number (see definition below).
+
+Values 1-4 satisfy the requirements of parse_commit_gently().
+
+Define the "generation number" of a commit recursively as follows:
+
+ * A commit with no parents (a root commit) has generation number one.
+
+ * A commit with at least one parent has generation number one more than
+   the largest generation number among its parents.
+
+Equivalently, the generation number of a commit A is one more than the
+length of a longest path from A to a root commit. The recursive definition
+is easier to use for computation and observing the following property:
+
+    If A and B are commits with generation numbers N and M, respectively,
+    and N <= M, then A cannot reach B. That is, we know without searching
+    that B is not an ancestor of A because it is further from a root commit
+    than A.
+
+    Conversely, when checking if A is an ancestor of B, then we only need
+    to walk commits until all commits on the walk boundary have generation
+    number at most N. If we walk commits using a priority queue seeded by
+    generation numbers, then we always expand the boundary commit with highest
+    generation number and can easily detect the stopping condition.
+
+This property can be used to significantly reduce the time it takes to
+walk commits and determine topological relationships. Without generation
+numbers, the general heuristic is the following:
+
+    If A and B are commits with commit time X and Y, respectively, and
+    X < Y, then A _probably_ cannot reach B.
+
+This heuristic is currently used whenever the computation is allowed to
+violate topological relationships due to clock skew (such as "git log"
+with default order), but is not used when the topological order is
+required (such as merge base calculations, "git log --graph").
+
+In practice, we expect some commits to be created recently and not stored
+in the commit graph. We can treat these commits as having "infinite"
+generation number and walk until reaching commits with known generation
+number.
+
+Design Details
+--------------
+
+- The commit graph file is stored in a file named 'commit-graph' in the
+  .git/objects/info directory. This could be stored in the info directory
+  of an alternate.
+
+- The core.commitGraph config setting must be on to consume graph files.
+
+- The file format includes parameters for the object ID hash function,
+  so a future change of hash algorithm does not require a change in format.
+
+Future Work
+-----------
+
+- The commit graph feature currently does not honor commit grafts. This can
+  be remedied by duplicating or refactoring the current graft logic.
+
+- The 'commit-graph' subcommand does not have a "verify" mode that is
+  necessary for integration with fsck.
+
+- The file format includes room for precomputed generation numbers. These
+  are not currently computed, so all generation numbers will be marked as
+  0 (or "uncomputed"). A later patch will include this calculation.
+
+- After computing and storing generation numbers, we must make graph
+  walks aware of generation numbers to gain the performance benefits they
+  enable. This will mostly be accomplished by swapping a commit-date-ordered
+  priority queue with one ordered by generation number. The following
+  operations are important candidates:
+
+    - paint_down_to_common()
+    - 'log --topo-order'
+
+- Currently, parse_commit_gently() requires filling in the root tree
+  object for a commit. This passes through lookup_tree() and consequently
+  lookup_object(). Also, it calls lookup_commit() when loading the parents.
+  These method calls check the ODB for object existence, even if the
+  consumer does not need the content. For example, we do not need the
+  tree contents when computing merge bases. Now that commit parsing is
+  removed from the computation time, these lookup operations are the
+  slowest operations keeping graph walks from being fast. Consider
+  loading these objects without verifying their existence in the ODB and
+  only loading them fully when consumers need them. Consider a method
+  such as "ensure_tree_loaded(commit)" that fully loads a tree before
+  using commit->tree.
+
+- The current design uses the 'commit-graph' subcommand to generate the graph.
+  When this feature stabilizes enough to recommend to most users, we should
+  add automatic graph writes to common operations that create many commits.
+  For example, one could compute a graph on 'clone', 'fetch', or 'repack'
+  commands.
+
+- A server could provide a commit graph file as part of the network protocol
+  to avoid extra calculations by clients. This feature is only of benefit if
+  the user is willing to trust the file, because verifying the file is correct
+  is as hard as computing it from scratch.
+
+Related Links
+-------------
+[0] https://bugs.chromium.org/p/git/issues/detail?id=8
+    Chromium work item for: Serialized Commit Graph
+
+[1] https://public-inbox.org/git/20110713070517.GC18566@sigill.intra.peff.net/
+    An abandoned patch that introduced generation numbers.
+
+[2] https://public-inbox.org/git/20170908033403.q7e6dj7benasrjes@sigill.intra.peff.net/
+    Discussion about generation numbers on commits and how they interact
+    with fsck.
+
+[3] https://public-inbox.org/git/20170908034739.4op3w4f2ma5s65ku@sigill.intra.peff.net/
+    More discussion about generation numbers and not storing them inside
+    commit objects. A valuable quote:
+
+    "I think we should be moving more in the direction of keeping
+     repo-local caches for optimizations. Reachability bitmaps have been
+     a big performance win. I think we should be doing the same with our
+     properties of commits. Not just generation numbers, but making it
+     cheap to access the graph structure without zlib-inflating whole
+     commit objects (i.e., packv4 or something like the "metapacks" I
+     proposed a few years ago)."
+
+[4] https://public-inbox.org/git/20180108154822.54829-1-git@jeffhostetler.com/T/#u
+    A patch to remove the ahead-behind calculation from 'status'.
index 417ba491d0f3fa06b60a47623a5f756919adcbd6..4ab6cd1012abae711acf02e6a76ee93eae86a1ad 100644 (file)
@@ -28,11 +28,30 @@ advantages:
   address stored content.
 
 Over time some flaws in SHA-1 have been discovered by security
-researchers. https://shattered.io demonstrated a practical SHA-1 hash
-collision. As a result, SHA-1 cannot be considered cryptographically
-secure any more. This impacts the communication of hash values because
-we cannot trust that a given hash value represents the known good
-version of content that the speaker intended.
+researchers. On 23 February 2017 the SHAttered attack
+(https://shattered.io) demonstrated a practical SHA-1 hash collision.
+
+Git v2.13.0 and later subsequently moved to a hardened SHA-1
+implementation by default, which isn't vulnerable to the SHAttered
+attack.
+
+Thus Git has in effect already migrated to a new hash that isn't SHA-1
+and doesn't share its vulnerabilities, its new hash function just
+happens to produce exactly the same output for all known inputs,
+except two PDFs published by the SHAttered researchers, and the new
+implementation (written by those researchers) claims to detect future
+cryptanalytic collision attacks.
+
+Regardless, it's considered prudent to move past any variant of SHA-1
+to a new hash. There's no guarantee that future attacks on SHA-1 won't
+be published in the future, and those attacks may not have viable
+mitigations.
+
+If SHA-1 and its variants were to be truly broken, Git's hash function
+could not be considered cryptographically secure any more. This would
+impact the communication of hash values because we could not trust
+that a given hash value represented the known good version of content
+that the speaker intended.
 
 SHA-1 still possesses the other properties such as fast object lookup
 and safe error checking, but other hash functions are equally suitable
@@ -116,10 +135,15 @@ Documentation/technical/repository-version.txt) with extensions
                objectFormat = newhash
                compatObjectFormat = sha1
 
-Specifying a repository format extension ensures that versions of Git
-not aware of NewHash do not try to operate on these repositories,
-instead producing an error message:
+The combination of setting `core.repositoryFormatVersion=1` and
+populating `extensions.*` ensures that all versions of Git later than
+`v0.99.9l` will die instead of trying to operate on the NewHash
+repository, instead producing an error message.
 
+       # Between v0.99.9l and v2.7.0
+       $ git status
+       fatal: Expected git repo version <= 0, found 1
+       # After v2.7.0
        $ git status
        fatal: unknown repository extensions found:
                objectformat
index 8e5bf60be3f0689d61feb8ce43cb379b2417fd8f..70a99fd1423894255f5e0e8cdbb345276620ffde 100644 (file)
@@ -36,6 +36,98 @@ Git pack format
 
   - The trailer records 20-byte SHA-1 checksum of all of the above.
 
+=== Object types
+
+Valid object types are:
+
+- OBJ_COMMIT (1)
+- OBJ_TREE (2)
+- OBJ_BLOB (3)
+- OBJ_TAG (4)
+- OBJ_OFS_DELTA (6)
+- OBJ_REF_DELTA (7)
+
+Type 5 is reserved for future expansion. Type 0 is invalid.
+
+=== Deltified representation
+
+Conceptually there are only four object types: commit, tree, tag and
+blob. However to save space, an object could be stored as a "delta" of
+another "base" object. These representations are assigned new types
+ofs-delta and ref-delta, which is only valid in a pack file.
+
+Both ofs-delta and ref-delta store the "delta" to be applied to
+another object (called 'base object') to reconstruct the object. The
+difference between them is, ref-delta directly encodes 20-byte base
+object name. If the base object is in the same pack, ofs-delta encodes
+the offset of the base object in the pack instead.
+
+The base object could also be deltified if it's in the same pack.
+Ref-delta can also refer to an object outside the pack (i.e. the
+so-called "thin pack"). When stored on disk however, the pack should
+be self contained to avoid cyclic dependency.
+
+The delta data is a sequence of instructions to reconstruct an object
+from the base object. If the base object is deltified, it must be
+converted to canonical form first. Each instruction appends more and
+more data to the target object until it's complete. There are two
+supported instructions so far: one for copy a byte range from the
+source object and one for inserting new data embedded in the
+instruction itself.
+
+Each instruction has variable length. Instruction type is determined
+by the seventh bit of the first octet. The following diagrams follow
+the convention in RFC 1951 (Deflate compressed data format).
+
+==== Instruction to copy from base object
+
+  +----------+---------+---------+---------+---------+-------+-------+-------+
+  | 1xxxxxxx | offset1 | offset2 | offset3 | offset4 | size1 | size2 | size3 |
+  +----------+---------+---------+---------+---------+-------+-------+-------+
+
+This is the instruction format to copy a byte range from the source
+object. It encodes the offset to copy from and the number of bytes to
+copy. Offset and size are in little-endian order.
+
+All offset and size bytes are optional. This is to reduce the
+instruction size when encoding small offsets or sizes. The first seven
+bits in the first octet determines which of the next seven octets is
+present. If bit zero is set, offset1 is present. If bit one is set
+offset2 is present and so on.
+
+Note that a more compact instruction does not change offset and size
+encoding. For example, if only offset2 is omitted like below, offset3
+still contains bits 16-23. It does not become offset2 and contains
+bits 8-15 even if it's right next to offset1.
+
+  +----------+---------+---------+
+  | 10000101 | offset1 | offset3 |
+  +----------+---------+---------+
+
+In its most compact form, this instruction only takes up one byte
+(0x80) with both offset and size omitted, which will have default
+values zero. There is another exception: size zero is automatically
+converted to 0x10000.
+
+==== Instruction to add new data
+
+  +----------+============+
+  | 0xxxxxxx |    data    |
+  +----------+============+
+
+This is the instruction to construct target object without the base
+object. The following data is appended to the target object. The first
+seven bits of the first octet determines the size of data in
+bytes. The size must be non-zero.
+
+==== Reserved instruction
+
+  +----------+============
+  | 00000000 |
+  +----------+============
+
+This is the instruction reserved for future expansion.
+
 == Original (version 1) pack-*.idx files have the following format:
 
   - The header consists of 256 4-byte network byte order
diff --git a/Documentation/technical/protocol-v2.txt b/Documentation/technical/protocol-v2.txt
new file mode 100644 (file)
index 0000000..49bda76
--- /dev/null
@@ -0,0 +1,414 @@
+ Git Wire Protocol, Version 2
+==============================
+
+This document presents a specification for a version 2 of Git's wire
+protocol.  Protocol v2 will improve upon v1 in the following ways:
+
+  * Instead of multiple service names, multiple commands will be
+    supported by a single service
+  * Easily extendable as capabilities are moved into their own section
+    of the protocol, no longer being hidden behind a NUL byte and
+    limited by the size of a pkt-line
+  * Separate out other information hidden behind NUL bytes (e.g. agent
+    string as a capability and symrefs can be requested using 'ls-refs')
+  * Reference advertisement will be omitted unless explicitly requested
+  * ls-refs command to explicitly request some refs
+  * Designed with http and stateless-rpc in mind.  With clear flush
+    semantics the http remote helper can simply act as a proxy
+
+In protocol v2 communication is command oriented.  When first contacting a
+server a list of capabilities will advertised.  Some of these capabilities
+will be commands which a client can request be executed.  Once a command
+has completed, a client can reuse the connection and request that other
+commands be executed.
+
+ Packet-Line Framing
+---------------------
+
+All communication is done using packet-line framing, just as in v1.  See
+`Documentation/technical/pack-protocol.txt` and
+`Documentation/technical/protocol-common.txt` for more information.
+
+In protocol v2 these special packets will have the following semantics:
+
+  * '0000' Flush Packet (flush-pkt) - indicates the end of a message
+  * '0001' Delimiter Packet (delim-pkt) - separates sections of a message
+
+ Initial Client Request
+------------------------
+
+In general a client can request to speak protocol v2 by sending
+`version=2` through the respective side-channel for the transport being
+used which inevitably sets `GIT_PROTOCOL`.  More information can be
+found in `pack-protocol.txt` and `http-protocol.txt`.  In all cases the
+response from the server is the capability advertisement.
+
+ Git Transport
+~~~~~~~~~~~~~~~
+
+When using the git:// transport, you can request to use protocol v2 by
+sending "version=2" as an extra parameter:
+
+   003egit-upload-pack /project.git\0host=myserver.com\0\0version=2\0
+
+ SSH and File Transport
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+When using either the ssh:// or file:// transport, the GIT_PROTOCOL
+environment variable must be set explicitly to include "version=2".
+
+ HTTP Transport
+~~~~~~~~~~~~~~~~
+
+When using the http:// or https:// transport a client makes a "smart"
+info/refs request as described in `http-protocol.txt` and requests that
+v2 be used by supplying "version=2" in the `Git-Protocol` header.
+
+   C: Git-Protocol: version=2
+   C:
+   C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0
+
+A v2 server would reply:
+
+   S: 200 OK
+   S: <Some headers>
+   S: ...
+   S:
+   S: 000eversion 2\n
+   S: <capability-advertisement>
+
+Subsequent requests are then made directly to the service
+`$GIT_URL/git-upload-pack`. (This works the same for git-receive-pack).
+
+ Capability Advertisement
+--------------------------
+
+A server which decides to communicate (based on a request from a client)
+using protocol version 2, notifies the client by sending a version string
+in its initial response followed by an advertisement of its capabilities.
+Each capability is a key with an optional value.  Clients must ignore all
+unknown keys.  Semantics of unknown values are left to the definition of
+each key.  Some capabilities will describe commands which can be requested
+to be executed by the client.
+
+    capability-advertisement = protocol-version
+                              capability-list
+                              flush-pkt
+
+    protocol-version = PKT-LINE("version 2" LF)
+    capability-list = *capability
+    capability = PKT-LINE(key[=value] LF)
+
+    key = 1*(ALPHA | DIGIT | "-_")
+    value = 1*(ALPHA | DIGIT | " -_.,?\/{}[]()<>!@#$%^&*+=:;")
+
+ Command Request
+-----------------
+
+After receiving the capability advertisement, a client can then issue a
+request to select the command it wants with any particular capabilities
+or arguments.  There is then an optional section where the client can
+provide any command specific parameters or queries.  Only a single
+command can be requested at a time.
+
+    request = empty-request | command-request
+    empty-request = flush-pkt
+    command-request = command
+                     capability-list
+                     [command-args]
+                     flush-pkt
+    command = PKT-LINE("command=" key LF)
+    command-args = delim-pkt
+                  *command-specific-arg
+
+    command-specific-args are packet line framed arguments defined by
+    each individual command.
+
+The server will then check to ensure that the client's request is
+comprised of a valid command as well as valid capabilities which were
+advertised.  If the request is valid the server will then execute the
+command.  A server MUST wait till it has received the client's entire
+request before issuing a response.  The format of the response is
+determined by the command being executed, but in all cases a flush-pkt
+indicates the end of the response.
+
+When a command has finished, and the client has received the entire
+response from the server, a client can either request that another
+command be executed or can terminate the connection.  A client may
+optionally send an empty request consisting of just a flush-pkt to
+indicate that no more requests will be made.
+
+ Capabilities
+--------------
+
+There are two different types of capabilities: normal capabilities,
+which can be used to to convey information or alter the behavior of a
+request, and commands, which are the core actions that a client wants to
+perform (fetch, push, etc).
+
+Protocol version 2 is stateless by default.  This means that all commands
+must only last a single round and be stateless from the perspective of the
+server side, unless the client has requested a capability indicating that
+state should be maintained by the server.  Clients MUST NOT require state
+management on the server side in order to function correctly.  This
+permits simple round-robin load-balancing on the server side, without
+needing to worry about state management.
+
+ agent
+~~~~~~~
+
+The server can advertise the `agent` capability with a value `X` (in the
+form `agent=X`) to notify the client that the server is running version
+`X`.  The client may optionally send its own agent string by including
+the `agent` capability with a value `Y` (in the form `agent=Y`) in its
+request to the server (but it MUST NOT do so if the server did not
+advertise the agent capability). The `X` and `Y` strings may contain any
+printable ASCII characters except space (i.e., the byte range 32 < x <
+127), and are typically of the form "package/version" (e.g.,
+"git/1.8.3.1"). The agent strings are purely informative for statistics
+and debugging purposes, and MUST NOT be used to programmatically assume
+the presence or absence of particular features.
+
+ ls-refs
+~~~~~~~~~
+
+`ls-refs` is the command used to request a reference advertisement in v2.
+Unlike the current reference advertisement, ls-refs takes in arguments
+which can be used to limit the refs sent from the server.
+
+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>"
+
+ls-refs takes in the following arguments:
+
+    symrefs
+       In addition to the object pointed by it, show the underlying ref
+       pointed by it when showing a symbolic ref.
+    peel
+       Show peeled tags.
+    ref-prefix <prefix>
+       When specified, only references having a prefix matching one of
+       the provided prefixes are displayed.
+
+The output of ls-refs is as follows:
+
+    output = *ref
+            flush-pkt
+    ref = PKT-LINE(obj-id SP refname *(SP ref-attribute) LF)
+    ref-attribute = (symref | peeled)
+    symref = "symref-target:" symref-target
+    peeled = "peeled:" obj-id
+
+ fetch
+~~~~~~~
+
+`fetch` is the command used to fetch a packfile in v2.  It can be looked
+at as a modified version of the v1 fetch where the ref-advertisement is
+stripped out (since the `ls-refs` command fills that role) and the
+message format is tweaked to eliminate redundancies and permit easy
+addition of future extensions.
+
+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>"
+
+A `fetch` request can take the following arguments:
+
+    want <oid>
+       Indicates to the server an object which the client wants to
+       retrieve.  Wants can be anything and are not limited to
+       advertised objects.
+
+    have <oid>
+       Indicates to the server an object which the client has locally.
+       This allows the server to make a packfile which only contains
+       the objects that the client needs. Multiple 'have' lines can be
+       supplied.
+
+    done
+       Indicates to the server that negotiation should terminate (or
+       not even begin if performing a clone) and that the server should
+       use the information supplied in the request to construct the
+       packfile.
+
+    thin-pack
+       Request that a thin pack be sent, which is a pack with deltas
+       which reference base objects not contained within the pack (but
+       are known to exist at the receiving end). This can reduce the
+       network traffic significantly, but it requires the receiving end
+       to know how to "thicken" these packs by adding the missing bases
+       to the pack.
+
+    no-progress
+       Request that progress information that would normally be sent on
+       side-band channel 2, during the packfile transfer, should not be
+       sent.  However, the side-band channel 3 is still used for error
+       responses.
+
+    include-tag
+       Request that annotated tags should be sent if the objects they
+       point to are being sent.
+
+    ofs-delta
+       Indicate that the client understands PACKv2 with delta referring
+       to its base by position in pack rather than by an oid.  That is,
+       they can read OBJ_OFS_DELTA (ake type 6) in a packfile.
+
+If the 'shallow' feature is advertised the following arguments can be
+included in the clients request as well as the potential addition of the
+'shallow-info' section in the server's response as explained below.
+
+    shallow <oid>
+       A client must notify the server of all commits for which it only
+       has shallow copies (meaning that it doesn't have the parents of
+       a commit) by supplying a 'shallow <oid>' line for each such
+       object so that the server is aware of the limitations of the
+       client's history.  This is so that the server is aware that the
+       client may not have all objects reachable from such commits.
+
+    deepen <depth>
+       Requests that the fetch/clone should be shallow having a commit
+       depth of <depth> relative to the remote side.
+
+    deepen-relative
+       Requests that the semantics of the "deepen" command be changed
+       to indicate that the depth requested is relative to the client's
+       current shallow boundary, instead of relative to the requested
+       commits.
+
+    deepen-since <timestamp>
+       Requests that the shallow clone/fetch should be cut at a
+       specific time, instead of depth.  Internally it's equivalent to
+       doing "git rev-list --max-age=<timestamp>". Cannot be used with
+       "deepen".
+
+    deepen-not <rev>
+       Requests that the shallow clone/fetch should be cut at a
+       specific revision specified by '<rev>', instead of a depth.
+       Internally it's equivalent of doing "git rev-list --not <rev>".
+       Cannot be used with "deepen", but can be used with
+       "deepen-since".
+
+If the 'filter' feature is advertised, the following argument can be
+included in the client's request:
+
+    filter <filter-spec>
+       Request that various objects from the packfile be omitted
+       using one of several filtering techniques. These are intended
+       for use with partial clone and partial fetch operations. See
+       `rev-list` for possible "filter-spec" values.
+
+The response of `fetch` is broken into a number of sections separated by
+delimiter packets (0001), with each section beginning with its section
+header.
+
+    output = *section
+    section = (acknowledgments | shallow-info | packfile)
+             (flush-pkt | delim-pkt)
+
+    acknowledgments = PKT-LINE("acknowledgments" LF)
+                     (nak | *ack)
+                     (ready)
+    ready = PKT-LINE("ready" LF)
+    nak = PKT-LINE("NAK" LF)
+    ack = PKT-LINE("ACK" SP obj-id LF)
+
+    shallow-info = PKT-LINE("shallow-info" LF)
+                  *PKT-LINE((shallow | unshallow) LF)
+    shallow = "shallow" SP obj-id
+    unshallow = "unshallow" SP obj-id
+
+    packfile = PKT-LINE("packfile" LF)
+              *PKT-LINE(%x01-03 *%x00-ff)
+
+    acknowledgments section
+       * If the client determines that it is finished with negotiations
+         by sending a "done" line, the acknowledgments sections MUST be
+         omitted from the server's response.
+
+       * Always begins with the section header "acknowledgments"
+
+       * The server will respond with "NAK" if none of the object ids sent
+         as have lines were common.
+
+       * The server will respond with "ACK obj-id" for all of the
+         object ids sent as have lines which are common.
+
+       * A response cannot have both "ACK" lines as well as a "NAK"
+         line.
+
+       * The server will respond with a "ready" line indicating that
+         the server has found an acceptable common base and is ready to
+         make and send a packfile (which will be found in the packfile
+         section of the same response)
+
+       * If the server has found a suitable cut point and has decided
+         to send a "ready" line, then the server can decide to (as an
+         optimization) omit any "ACK" lines it would have sent during
+         its response.  This is because the server will have already
+         determined the objects it plans to send to the client and no
+         further negotiation is needed.
+
+    shallow-info section
+       * If the client has requested a shallow fetch/clone, a shallow
+         client requests a fetch or the server is shallow then the
+         server's response may include a shallow-info section.  The
+         shallow-info section will be included if (due to one of the
+         above conditions) the server needs to inform the client of any
+         shallow boundaries or adjustments to the clients already
+         existing shallow boundaries.
+
+       * Always begins with the section header "shallow-info"
+
+       * If a positive depth is requested, the server will compute the
+         set of commits which are no deeper than the desired depth.
+
+       * The server sends a "shallow obj-id" line for each commit whose
+         parents will not be sent in the following packfile.
+
+       * The server sends an "unshallow obj-id" line for each commit
+         which the client has indicated is shallow, but is no longer
+         shallow as a result of the fetch (due to its parents being
+         sent in the following packfile).
+
+       * The server MUST NOT send any "unshallow" lines for anything
+         which the client has not indicated was shallow as a part of
+         its request.
+
+       * This section is only included if a packfile section is also
+         included in the response.
+
+    packfile section
+       * This section is only included if the client has sent 'want'
+         lines in its request and either requested that no more
+         negotiation be done by sending 'done' or if the server has
+         decided it has found a sufficient cut point to produce a
+         packfile.
+
+       * Always begins with the section header "packfile"
+
+       * The transmission of the packfile begins immediately after the
+         section header
+
+       * The data transfer of the packfile is always multiplexed, using
+         the same semantics of the 'side-band-64k' capability from
+         protocol version 1.  This means that each packet, during the
+         packfile data stream, is made up of a leading 4-byte pkt-line
+         length (typical of the pkt-line format), followed by a 1-byte
+         stream code, followed by the actual data.
+
+         The stream code can be one of:
+               1 - pack data
+               2 - progress messages
+               3 - fatal error message just before stream aborts
+
+ server-option
+~~~~~~~~~~~~~~~
+
+If advertised, indicates that any number of server specific options can be
+included in a request.  This is done by sending each option as a
+"server-option=<option>" capability line in the capability-list section of
+a request.
+
+The provided options must not contain a NUL or LF character.
index 5183b154229d7c25f0feab3d0afcd1d52ca652e0..01dedfe9ffedc28c2c6ac5ef15dbb3c5fe519cc0 100644 (file)
@@ -8,20 +8,22 @@ repo, and therefore grafts are introduced pretending that
 these commits have no parents.
 *********************************************************
 
-The basic idea is to write the SHA-1s of shallow commits into
-$GIT_DIR/shallow, and handle its contents like the contents
-of $GIT_DIR/info/grafts (with the difference that shallow
-cannot contain parent information).
-
-This information is stored in a new file instead of grafts, or
-even the config, since the user should not touch that file
-at all (even throughout development of the shallow clone, it
-was never manually edited!).
+$GIT_DIR/shallow lists commit object names and tells Git to
+pretend as if they are root commits (e.g. "git log" traversal
+stops after showing them; "git fsck" does not complain saying
+the commits listed on their "parent" lines do not exist).
 
 Each line contains exactly one SHA-1. When read, a commit_graft
 will be constructed, which has nr_parent < 0 to make it easier
 to discern from user provided grafts.
 
+Note that the shallow feature could not be changed easily to
+use replace refs: a commit containing a `mergetag` is not allowed
+to be replaced, not even by a root commit. Such a commit can be
+made shallow, though. Also, having a `shallow` file explicitly
+listing all the commits made shallow makes it a *lot* easier to
+do shallow-specific things such as to deepen the history.
+
 Since fsck-objects relies on the library to read the objects,
 it honours shallow commits automatically.
 
index bd6cd16e3d917a8759a1c40845ecc24edc8c8a8c..5998893dd7005f5ce63946ae5ec53bb18a20c3e9 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=v2.17.3
+DEF_VER=v2.18.1
 
 LF='
 '
index a1d8775adb4b38a0340cd7d04184915f0ee65d28..e4b503d259906d60a65204248aeb54962b12c062 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -29,10 +29,10 @@ all::
 # Perl-compatible regular expressions instead of standard or extended
 # POSIX regular expressions.
 #
-# Currently USE_LIBPCRE is a synonym for USE_LIBPCRE1, define
-# USE_LIBPCRE2 instead if you'd like to use version 2 of the PCRE
-# library. The USE_LIBPCRE flag will likely be changed to mean v2 by
-# default in future releases.
+# USE_LIBPCRE is a synonym for USE_LIBPCRE2, define USE_LIBPCRE1
+# instead if you'd like to use the legacy version 1 of the PCRE
+# library. Support for version 1 will likely be removed in some future
+# release of Git, as upstream has all but abandoned it.
 #
 # When using USE_LIBPCRE1, define NO_LIBPCRE1_JIT if the PCRE v1
 # library is compiled without --enable-jit. We will auto-detect
@@ -335,6 +335,13 @@ all::
 # when hardlinking a file to another name and unlinking the original file right
 # away (some NTFS drivers seem to zero the contents in that scenario).
 #
+# Define INSTALL_SYMLINKS if you prefer to have everything that can be
+# symlinked between bin/ and libexec/ to use relative symlinks between
+# the two. This option overrides NO_CROSS_DIRECTORY_HARDLINKS and
+# NO_INSTALL_HARDLINKS which will also use symlinking by indirection
+# within the same directory in some cases, INSTALL_SYMLINKS will
+# always symlink to the final target directly.
+#
 # Define NO_CROSS_DIRECTORY_HARDLINKS if you plan to distribute the installed
 # programs as a tar, where bin/ and libexec/ might be on different file systems.
 #
@@ -434,6 +441,49 @@ all::
 #
 # When cross-compiling, define HOST_CPU as the canonical name of the CPU on
 # which the built Git will run (for instance "x86_64").
+#
+# Define RUNTIME_PREFIX to configure Git to resolve its ancillary tooling and
+# support files relative to the location of the runtime binary, rather than
+# hard-coding them into the binary. Git installations built with RUNTIME_PREFIX
+# can be moved to arbitrary filesystem locations. RUNTIME_PREFIX also causes
+# Perl scripts to use a modified entry point header allowing them to resolve
+# support files at runtime.
+#
+# When using RUNTIME_PREFIX, define HAVE_BSD_KERN_PROC_SYSCTL if your platform
+# supports the KERN_PROC BSD sysctl function.
+#
+# When using RUNTIME_PREFIX, define PROCFS_EXECUTABLE_PATH if your platform
+# mounts a "procfs" filesystem capable of resolving the path of the current
+# executable. If defined, this must be the canonical path for the "procfs"
+# current executable path.
+#
+# When using RUNTIME_PREFIX, define HAVE_NS_GET_EXECUTABLE_PATH if your platform
+# supports calling _NSGetExecutablePath to retrieve the path of the running
+# executable.
+#
+# When using RUNTIME_PREFIX, define HAVE_WPGMPTR if your platform offers
+# the global variable _wpgmptr containing the absolute path of the current
+# executable (this is the case on Windows).
+#
+# Define DEVELOPER to enable more compiler warnings. Compiler version
+# and family are auto detected, but could be overridden by defining
+# COMPILER_FEATURES (see config.mak.dev)
+#
+# When DEVELOPER is set, DEVOPTS can be used to control compiler
+# options.  This variable contains keywords separated by
+# whitespace. The following keywords are are recognized:
+#
+#    no-error:
+#
+#        suppresses the -Werror that implicitly comes with
+#        DEVELOPER=1. Useful for getting the full set of errors
+#        without immediately dying, or for logging them.
+#
+#    extra-all:
+#
+#        The DEVELOPER mode enables -Wextra with a few exceptions. By
+#        setting this flag the exceptions are removed, and all of
+#        -Wextra is used.
 
 GIT-VERSION-FILE: FORCE
        @$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -442,15 +492,6 @@ GIT-VERSION-FILE: FORCE
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
 CFLAGS = -g -O2 -Wall
-DEVELOPER_CFLAGS = -Werror \
-       -Wdeclaration-after-statement \
-       -Wno-format-zero-length \
-       -Wold-style-definition \
-       -Woverflow \
-       -Wpointer-arith \
-       -Wstrict-prototypes \
-       -Wunused \
-       -Wvla
 LDFLAGS =
 ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS)
 ALL_LDFLAGS = $(LDFLAGS)
@@ -471,11 +512,12 @@ ARFLAGS = rcs
 #   mandir
 #   infodir
 #   htmldir
+#   localedir
+#   perllibdir
 # This can help installing the suite in a relocatable way.
 
 prefix = $(HOME)
-bindir_relative = bin
-bindir = $(prefix)/$(bindir_relative)
+bindir = $(prefix)/bin
 mandir = $(prefix)/share/man
 infodir = $(prefix)/share/info
 gitexecdir = libexec/git-core
@@ -492,9 +534,13 @@ lib = lib
 # DESTDIR =
 pathsep = :
 
+bindir_relative = $(patsubst $(prefix)/%,%,$(bindir))
 mandir_relative = $(patsubst $(prefix)/%,%,$(mandir))
 infodir_relative = $(patsubst $(prefix)/%,%,$(infodir))
+gitexecdir_relative = $(patsubst $(prefix)/%,%,$(gitexecdir))
+localedir_relative = $(patsubst $(prefix)/%,%,$(localedir))
 htmldir_relative = $(patsubst $(prefix)/%,%,$(htmldir))
+perllibdir_relative = $(patsubst $(prefix)/%,%,$(perllibdir))
 
 export prefix bindir sharedir sysconfdir gitwebdir perllibdir localedir
 
@@ -546,6 +592,7 @@ SCRIPT_PERL =
 SCRIPT_PYTHON =
 SCRIPT_SH =
 SCRIPT_LIB =
+TEST_BUILTINS_OBJS =
 TEST_PROGRAMS_NEED_X =
 
 # Having this variable in your environment would break pipelines because
@@ -643,7 +690,6 @@ PROGRAM_OBJS += imap-send.o
 PROGRAM_OBJS += sh-i18n--envsubst.o
 PROGRAM_OBJS += shell.o
 PROGRAM_OBJS += show-index.o
-PROGRAM_OBJS += upload-pack.o
 PROGRAM_OBJS += remote-testsvn.o
 
 # Binary suffix, set to .exe for Windows builds
@@ -651,47 +697,50 @@ X =
 
 PROGRAMS += $(patsubst %.o,git-%$X,$(PROGRAM_OBJS))
 
-TEST_PROGRAMS_NEED_X += test-chmtime
-TEST_PROGRAMS_NEED_X += test-ctype
-TEST_PROGRAMS_NEED_X += test-config
-TEST_PROGRAMS_NEED_X += test-date
-TEST_PROGRAMS_NEED_X += test-delta
-TEST_PROGRAMS_NEED_X += test-drop-caches
-TEST_PROGRAMS_NEED_X += test-dump-cache-tree
+TEST_BUILTINS_OBJS += test-chmtime.o
+TEST_BUILTINS_OBJS += test-config.o
+TEST_BUILTINS_OBJS += test-ctype.o
+TEST_BUILTINS_OBJS += test-date.o
+TEST_BUILTINS_OBJS += test-delta.o
+TEST_BUILTINS_OBJS += test-drop-caches.o
+TEST_BUILTINS_OBJS += test-dump-cache-tree.o
+TEST_BUILTINS_OBJS += test-dump-split-index.o
+TEST_BUILTINS_OBJS += test-example-decorate.o
+TEST_BUILTINS_OBJS += test-genrandom.o
+TEST_BUILTINS_OBJS += test-hashmap.o
+TEST_BUILTINS_OBJS += test-index-version.o
+TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o
+TEST_BUILTINS_OBJS += test-match-trees.o
+TEST_BUILTINS_OBJS += test-mergesort.o
+TEST_BUILTINS_OBJS += test-mktemp.o
+TEST_BUILTINS_OBJS += test-online-cpus.o
+TEST_BUILTINS_OBJS += test-path-utils.o
+TEST_BUILTINS_OBJS += test-prio-queue.o
+TEST_BUILTINS_OBJS += test-read-cache.o
+TEST_BUILTINS_OBJS += test-ref-store.o
+TEST_BUILTINS_OBJS += test-regex.o
+TEST_BUILTINS_OBJS += test-revision-walking.o
+TEST_BUILTINS_OBJS += test-run-command.o
+TEST_BUILTINS_OBJS += test-scrap-cache-tree.o
+TEST_BUILTINS_OBJS += test-sha1-array.o
+TEST_BUILTINS_OBJS += test-sha1.o
+TEST_BUILTINS_OBJS += test-sigchain.o
+TEST_BUILTINS_OBJS += test-strcmp-offset.o
+TEST_BUILTINS_OBJS += test-string-list.o
+TEST_BUILTINS_OBJS += test-submodule-config.o
+TEST_BUILTINS_OBJS += test-subprocess.o
+TEST_BUILTINS_OBJS += test-urlmatch-normalization.o
+TEST_BUILTINS_OBJS += test-wildmatch.o
+TEST_BUILTINS_OBJS += test-write-cache.o
+
 TEST_PROGRAMS_NEED_X += test-dump-fsmonitor
-TEST_PROGRAMS_NEED_X += test-dump-split-index
 TEST_PROGRAMS_NEED_X += test-dump-untracked-cache
-TEST_PROGRAMS_NEED_X += test-example-decorate
 TEST_PROGRAMS_NEED_X += test-fake-ssh
-TEST_PROGRAMS_NEED_X += test-genrandom
-TEST_PROGRAMS_NEED_X += test-hashmap
-TEST_PROGRAMS_NEED_X += test-index-version
-TEST_PROGRAMS_NEED_X += test-lazy-init-name-hash
 TEST_PROGRAMS_NEED_X += test-line-buffer
-TEST_PROGRAMS_NEED_X += test-match-trees
-TEST_PROGRAMS_NEED_X += test-mergesort
-TEST_PROGRAMS_NEED_X += test-mktemp
-TEST_PROGRAMS_NEED_X += test-online-cpus
 TEST_PROGRAMS_NEED_X += test-parse-options
-TEST_PROGRAMS_NEED_X += test-path-utils
-TEST_PROGRAMS_NEED_X += test-prio-queue
-TEST_PROGRAMS_NEED_X += test-read-cache
-TEST_PROGRAMS_NEED_X += test-write-cache
-TEST_PROGRAMS_NEED_X += test-ref-store
-TEST_PROGRAMS_NEED_X += test-regex
-TEST_PROGRAMS_NEED_X += test-revision-walking
-TEST_PROGRAMS_NEED_X += test-run-command
-TEST_PROGRAMS_NEED_X += test-scrap-cache-tree
-TEST_PROGRAMS_NEED_X += test-sha1
-TEST_PROGRAMS_NEED_X += test-sha1-array
-TEST_PROGRAMS_NEED_X += test-sigchain
-TEST_PROGRAMS_NEED_X += test-strcmp-offset
-TEST_PROGRAMS_NEED_X += test-string-list
-TEST_PROGRAMS_NEED_X += test-submodule-config
-TEST_PROGRAMS_NEED_X += test-subprocess
+TEST_PROGRAMS_NEED_X += test-pkt-line
 TEST_PROGRAMS_NEED_X += test-svn-fe
-TEST_PROGRAMS_NEED_X += test-urlmatch-normalization
-TEST_PROGRAMS_NEED_X += test-wildmatch
+TEST_PROGRAMS_NEED_X += test-tool
 
 TEST_PROGRAMS = $(patsubst %,t/helper/%$X,$(TEST_PROGRAMS_NEED_X))
 
@@ -746,7 +795,7 @@ LIB_FILE = libgit.a
 XDIFF_LIB = xdiff/lib.a
 VCSSVN_LIB = vcs-svn/lib.a
 
-GENERATED_H += common-cmds.h
+GENERATED_H += command-list.h
 
 LIB_H = $(shell $(FIND) . \
        -name .git -prune -o \
@@ -772,11 +821,13 @@ LIB_OBJS += branch.o
 LIB_OBJS += bulk-checkin.o
 LIB_OBJS += bundle.o
 LIB_OBJS += cache-tree.o
+LIB_OBJS += chdir-notify.o
 LIB_OBJS += checkout.o
 LIB_OBJS += color.o
 LIB_OBJS += column.o
 LIB_OBJS += combine-diff.o
 LIB_OBJS += commit.o
+LIB_OBJS += commit-graph.o
 LIB_OBJS += compat/obstack.o
 LIB_OBJS += compat/terminal.o
 LIB_OBJS += config.o
@@ -807,7 +858,7 @@ LIB_OBJS += ewah/bitmap.o
 LIB_OBJS += ewah/ewah_bitmap.o
 LIB_OBJS += ewah/ewah_io.o
 LIB_OBJS += ewah/ewah_rlw.o
-LIB_OBJS += exec_cmd.o
+LIB_OBJS += exec-cmd.o
 LIB_OBJS += fetch-object.o
 LIB_OBJS += fetch-pack.o
 LIB_OBJS += fsck.o
@@ -830,9 +881,11 @@ LIB_OBJS += list-objects-filter-options.o
 LIB_OBJS += ll-merge.o
 LIB_OBJS += lockfile.o
 LIB_OBJS += log-tree.o
+LIB_OBJS += ls-refs.o
 LIB_OBJS += mailinfo.o
 LIB_OBJS += mailmap.o
 LIB_OBJS += match-trees.o
+LIB_OBJS += mem-pool.o
 LIB_OBJS += merge.o
 LIB_OBJS += merge-blobs.o
 LIB_OBJS += merge-recursive.o
@@ -875,9 +928,10 @@ LIB_OBJS += refs/files-backend.o
 LIB_OBJS += refs/iterator.o
 LIB_OBJS += refs/packed-backend.o
 LIB_OBJS += refs/ref-cache.o
+LIB_OBJS += refspec.o
 LIB_OBJS += ref-filter.o
 LIB_OBJS += remote.o
-LIB_OBJS += replace_object.o
+LIB_OBJS += replace-object.o
 LIB_OBJS += repository.o
 LIB_OBJS += rerere.o
 LIB_OBJS += resolve-undo.o
@@ -885,12 +939,13 @@ LIB_OBJS += revision.o
 LIB_OBJS += run-command.o
 LIB_OBJS += send-pack.o
 LIB_OBJS += sequencer.o
+LIB_OBJS += serve.o
 LIB_OBJS += server-info.o
 LIB_OBJS += setup.o
 LIB_OBJS += sha1-array.o
 LIB_OBJS += sha1-lookup.o
-LIB_OBJS += sha1_file.o
-LIB_OBJS += sha1_name.o
+LIB_OBJS += sha1-file.o
+LIB_OBJS += sha1-name.o
 LIB_OBJS += shallow.o
 LIB_OBJS += sideband.o
 LIB_OBJS += sigchain.o
@@ -913,6 +968,7 @@ LIB_OBJS += tree-diff.o
 LIB_OBJS += tree.o
 LIB_OBJS += tree-walk.o
 LIB_OBJS += unpack-trees.o
+LIB_OBJS += upload-pack.o
 LIB_OBJS += url.o
 LIB_OBJS += urlmatch.o
 LIB_OBJS += usage.o
@@ -925,7 +981,7 @@ LIB_OBJS += walker.o
 LIB_OBJS += wildmatch.o
 LIB_OBJS += worktree.o
 LIB_OBJS += wrapper.o
-LIB_OBJS += write_or_die.o
+LIB_OBJS += write-or-die.o
 LIB_OBJS += ws.o
 LIB_OBJS += wt-status.o
 LIB_OBJS += xdiff-interface.o
@@ -952,6 +1008,7 @@ BUILTIN_OBJS += builtin/clone.o
 BUILTIN_OBJS += builtin/column.o
 BUILTIN_OBJS += builtin/commit-tree.o
 BUILTIN_OBJS += builtin/commit.o
+BUILTIN_OBJS += builtin/commit-graph.o
 BUILTIN_OBJS += builtin/config.o
 BUILTIN_OBJS += builtin/count-objects.o
 BUILTIN_OBJS += builtin/credential.o
@@ -1017,6 +1074,7 @@ BUILTIN_OBJS += builtin/rev-parse.o
 BUILTIN_OBJS += builtin/revert.o
 BUILTIN_OBJS += builtin/rm.o
 BUILTIN_OBJS += builtin/send-pack.o
+BUILTIN_OBJS += builtin/serve.o
 BUILTIN_OBJS += builtin/shortlog.o
 BUILTIN_OBJS += builtin/show-branch.o
 BUILTIN_OBJS += builtin/show-ref.o
@@ -1030,6 +1088,7 @@ BUILTIN_OBJS += builtin/update-index.o
 BUILTIN_OBJS += builtin/update-ref.o
 BUILTIN_OBJS += builtin/update-server-info.o
 BUILTIN_OBJS += builtin/upload-archive.o
+BUILTIN_OBJS += builtin/upload-pack.o
 BUILTIN_OBJS += builtin/var.o
 BUILTIN_OBJS += builtin/verify-commit.o
 BUILTIN_OBJS += builtin/verify-pack.o
@@ -1051,7 +1110,7 @@ include config.mak.uname
 -include config.mak
 
 ifdef DEVELOPER
-CFLAGS += $(DEVELOPER_CFLAGS)
+include config.mak.dev
 endif
 
 comma := ,
@@ -1170,13 +1229,18 @@ ifdef NO_LIBGEN_H
        COMPAT_OBJS += compat/basename.o
 endif
 
-USE_LIBPCRE1 ?= $(USE_LIBPCRE)
+USE_LIBPCRE2 ?= $(USE_LIBPCRE)
 
-ifneq (,$(USE_LIBPCRE1))
-       ifdef USE_LIBPCRE2
-$(error Only set USE_LIBPCRE1 (or its alias USE_LIBPCRE) or USE_LIBPCRE2, not both!)
+ifneq (,$(USE_LIBPCRE2))
+       ifdef USE_LIBPCRE1
+$(error Only set USE_LIBPCRE2 (or its alias USE_LIBPCRE) or USE_LIBPCRE1, not both!)
        endif
 
+       BASIC_CFLAGS += -DUSE_LIBPCRE2
+       EXTLIBS += -lpcre2-8
+endif
+
+ifdef USE_LIBPCRE1
        BASIC_CFLAGS += -DUSE_LIBPCRE1
        EXTLIBS += -lpcre
 
@@ -1185,11 +1249,6 @@ ifdef NO_LIBPCRE1_JIT
 endif
 endif
 
-ifdef USE_LIBPCRE2
-       BASIC_CFLAGS += -DUSE_LIBPCRE2
-       EXTLIBS += -lpcre2-8
-endif
-
 ifdef LIBPCREDIR
        BASIC_CFLAGS += -I$(LIBPCREDIR)/include
        EXTLIBS += -L$(LIBPCREDIR)/$(lib) $(CC_LD_DYNPATH)$(LIBPCREDIR)/$(lib)
@@ -1292,17 +1351,19 @@ ifdef APPLE_COMMON_CRYPTO
        LIB_4_CRYPTO += -framework Security -framework CoreFoundation
 endif
 endif
-ifdef NEEDS_LIBICONV
-       ifdef ICONVDIR
-               BASIC_CFLAGS += -I$(ICONVDIR)/include
-               ICONV_LINK = -L$(ICONVDIR)/$(lib) $(CC_LD_DYNPATH)$(ICONVDIR)/$(lib)
-       else
-               ICONV_LINK =
-       endif
-       ifdef NEEDS_LIBINTL_BEFORE_LIBICONV
-               ICONV_LINK += -lintl
+ifndef NO_ICONV
+       ifdef NEEDS_LIBICONV
+               ifdef ICONVDIR
+                       BASIC_CFLAGS += -I$(ICONVDIR)/include
+                       ICONV_LINK = -L$(ICONVDIR)/$(lib) $(CC_LD_DYNPATH)$(ICONVDIR)/$(lib)
+               else
+                       ICONV_LINK =
+               endif
+               ifdef NEEDS_LIBINTL_BEFORE_LIBICONV
+                       ICONV_LINK += -lintl
+               endif
+               EXTLIBS += $(ICONV_LINK) -liconv
        endif
-       EXTLIBS += $(ICONV_LINK) -liconv
 endif
 ifdef NEEDS_LIBGEN
        EXTLIBS += -lgen
@@ -1652,10 +1713,27 @@ ifdef HAVE_BSD_SYSCTL
        BASIC_CFLAGS += -DHAVE_BSD_SYSCTL
 endif
 
+ifdef HAVE_BSD_KERN_PROC_SYSCTL
+       BASIC_CFLAGS += -DHAVE_BSD_KERN_PROC_SYSCTL
+endif
+
 ifdef HAVE_GETDELIM
        BASIC_CFLAGS += -DHAVE_GETDELIM
 endif
 
+ifneq ($(PROCFS_EXECUTABLE_PATH),)
+       procfs_executable_path_SQ = $(subst ','\'',$(PROCFS_EXECUTABLE_PATH))
+       BASIC_CFLAGS += '-DPROCFS_EXECUTABLE_PATH="$(procfs_executable_path_SQ)"'
+endif
+
+ifdef HAVE_NS_GET_EXECUTABLE_PATH
+       BASIC_CFLAGS += -DHAVE_NS_GET_EXECUTABLE_PATH
+endif
+
+ifdef HAVE_WPGMPTR
+       BASIC_CFLAGS += -DHAVE_WPGMPTR
+endif
+
 ifeq ($(TCLTK_PATH),)
 NO_TCLTK = NoThanks
 endif
@@ -1740,10 +1818,13 @@ mandir_relative_SQ = $(subst ','\'',$(mandir_relative))
 infodir_relative_SQ = $(subst ','\'',$(infodir_relative))
 perllibdir_SQ = $(subst ','\'',$(perllibdir))
 localedir_SQ = $(subst ','\'',$(localedir))
+localedir_relative_SQ = $(subst ','\'',$(localedir_relative))
 gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
+gitexecdir_relative_SQ = $(subst ','\'',$(gitexecdir_relative))
 template_dir_SQ = $(subst ','\'',$(template_dir))
 htmldir_relative_SQ = $(subst ','\'',$(htmldir_relative))
 prefix_SQ = $(subst ','\'',$(prefix))
+perllibdir_relative_SQ = $(subst ','\'',$(perllibdir_relative))
 gitwebdir_SQ = $(subst ','\'',$(gitwebdir))
 
 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
@@ -1754,6 +1835,31 @@ TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
 DIFF_SQ = $(subst ','\'',$(DIFF))
 PERLLIB_EXTRA_SQ = $(subst ','\'',$(PERLLIB_EXTRA))
 
+# RUNTIME_PREFIX's resolution logic requires resource paths to be expressed
+# relative to each other and share an installation path.
+#
+# This is a dependency in:
+# - Git's binary RUNTIME_PREFIX logic in (see "exec_cmd.c").
+# - The runtime prefix Perl header (see
+#   "perl/header_templates/runtime_prefix.template.pl").
+ifdef RUNTIME_PREFIX
+
+ifneq ($(filter /%,$(firstword $(gitexecdir_relative))),)
+$(error RUNTIME_PREFIX requires a relative gitexecdir, not: $(gitexecdir))
+endif
+
+ifneq ($(filter /%,$(firstword $(localedir_relative))),)
+$(error RUNTIME_PREFIX requires a relative localedir, not: $(localedir))
+endif
+
+ifndef NO_PERL
+ifneq ($(filter /%,$(firstword $(perllibdir_relative))),)
+$(error RUNTIME_PREFIX requires a relative perllibdir, not: $(perllibdir))
+endif
+endif
+
+endif
+
 # We must filter out any object files from $(GITLIBS),
 # as it is typically used like:
 #
@@ -1902,9 +2008,9 @@ git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
                $(filter %.o,$^) $(LIBS)
 
-help.sp help.s help.o: common-cmds.h
+help.sp help.s help.o: command-list.h
 
-builtin/help.sp builtin/help.s builtin/help.o: common-cmds.h GIT-PREFIX
+builtin/help.sp builtin/help.s builtin/help.o: command-list.h GIT-PREFIX
 builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \
        '-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \
        '-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \
@@ -1923,9 +2029,9 @@ $(BUILT_INS): git$X
        ln -s $< $@ 2>/dev/null || \
        cp $< $@
 
-common-cmds.h: generate-cmdlist.sh command-list.txt
+command-list.h: generate-cmdlist.sh command-list.txt
 
-common-cmds.h: $(wildcard Documentation/git-*.txt)
+command-list.h: $(wildcard Documentation/git*.txt)
        $(QUIET_GEN)$(SHELL_PATH) ./generate-cmdlist.sh command-list.txt >$@+ && mv $@+ $@
 
 SCRIPT_DEFINES = $(SHELL_PATH_SQ):$(DIFF_SQ):$(GIT_VERSION):\
@@ -1974,27 +2080,44 @@ git.res: git.rc GIT-VERSION-FILE
 # This makes sure we depend on the NO_PERL setting itself.
 $(SCRIPT_PERL_GEN): GIT-BUILD-OPTIONS
 
-ifndef NO_PERL
-$(SCRIPT_PERL_GEN):
+# Used for substitution in Perl modules. Disabled when using RUNTIME_PREFIX
+# since the locale directory is injected.
+perl_localedir_SQ = $(localedir_SQ)
 
+ifndef NO_PERL
+PERL_HEADER_TEMPLATE = perl/header_templates/fixed_prefix.template.pl
 PERL_DEFINES = $(PERL_PATH_SQ):$(PERLLIB_EXTRA_SQ):$(perllibdir_SQ)
-$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-VERSION-FILE
+
+PERL_DEFINES := $(PERL_PATH_SQ) $(PERLLIB_EXTRA_SQ) $(perllibdir_SQ)
+PERL_DEFINES += $(RUNTIME_PREFIX)
+
+# Support Perl runtime prefix. In this mode, a different header is installed
+# into Perl scripts.
+ifdef RUNTIME_PREFIX
+
+PERL_HEADER_TEMPLATE = perl/header_templates/runtime_prefix.template.pl
+
+# Don't export a fixed $(localedir) path; it will be resolved by the Perl header
+# at runtime.
+perl_localedir_SQ =
+
+endif
+
+PERL_DEFINES += $(gitexecdir) $(perllibdir) $(localedir)
+
+$(SCRIPT_PERL_GEN): % : %.perl GIT-PERL-DEFINES GIT-PERL-HEADER GIT-VERSION-FILE
        $(QUIET_GEN)$(RM) $@ $@+ && \
-       INSTLIBDIR='$(perllibdir_SQ)' && \
-       INSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \
-       INSTLIBDIR="$$INSTLIBDIR$${INSTLIBDIR_EXTRA:+:$$INSTLIBDIR_EXTRA}" && \
        sed -e '1{' \
            -e '        s|#!.*perl|#!$(PERL_PATH_SQ)|' \
-           -e '        h' \
-           -e '        s=.*=use lib (split(/$(pathsep)/, $$ENV{GITPERLLIB} || "'"$$INSTLIBDIR"'"));=' \
-           -e '        H' \
-           -e '        x' \
+           -e '        rGIT-PERL-HEADER' \
+           -e '        G' \
            -e '}' \
            -e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
            $< >$@+ && \
        chmod +x $@+ && \
        mv $@+ $@
 
+PERL_DEFINES := $(subst $(space),:,$(PERL_DEFINES))
 GIT-PERL-DEFINES: FORCE
        @FLAGS='$(PERL_DEFINES)'; \
            if test x"$$FLAGS" != x"`cat $@ 2>/dev/null`" ; then \
@@ -2002,6 +2125,22 @@ GIT-PERL-DEFINES: FORCE
                echo "$$FLAGS" >$@; \
            fi
 
+GIT-PERL-HEADER: $(PERL_HEADER_TEMPLATE) GIT-PERL-DEFINES Makefile
+       $(QUIET_GEN)$(RM) $@ && \
+       INSTLIBDIR='$(perllibdir_SQ)' && \
+       INSTLIBDIR_EXTRA='$(PERLLIB_EXTRA_SQ)' && \
+       INSTLIBDIR="$$INSTLIBDIR$${INSTLIBDIR_EXTRA:+:$$INSTLIBDIR_EXTRA}" && \
+       sed -e 's=@@PATHSEP@@=$(pathsep)=g' \
+           -e "s=@@INSTLIBDIR@@=$$INSTLIBDIR=g" \
+           -e 's=@@PERLLIBDIR_REL@@=$(perllibdir_relative_SQ)=g' \
+           -e 's=@@GITEXECDIR_REL@@=$(gitexecdir_relative_SQ)=g' \
+           -e 's=@@LOCALEDIR_REL@@=$(localedir_relative_SQ)=g' \
+           $< >$@+ && \
+       mv $@+ $@
+
+.PHONY: perllibdir
+perllibdir:
+       @echo '$(perllibdir_SQ)'
 
 .PHONY: gitweb
 gitweb:
@@ -2083,7 +2222,7 @@ VCSSVN_OBJS += vcs-svn/fast_export.o
 VCSSVN_OBJS += vcs-svn/svndiff.o
 VCSSVN_OBJS += vcs-svn/svndump.o
 
-TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS))
+TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
 OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \
        $(XDIFF_OBJS) \
        $(VCSSVN_OBJS) \
@@ -2136,18 +2275,19 @@ else
 # Dependencies on header files, for platforms that do not support
 # the gcc -MMD option.
 #
-# Dependencies on automatically generated headers such as common-cmds.h
+# Dependencies on automatically generated headers such as command-list.h
 # should _not_ be included here, since they are necessary even when
 # building an object for the first time.
 
 $(OBJECTS): $(LIB_H)
 endif
 
-exec_cmd.sp exec_cmd.s exec_cmd.o: GIT-PREFIX
-exec_cmd.sp exec_cmd.s exec_cmd.o: EXTRA_CPPFLAGS = \
+exec-cmd.sp exec-cmd.s exec-cmd.o: GIT-PREFIX
+exec-cmd.sp exec-cmd.s exec-cmd.o: EXTRA_CPPFLAGS = \
        '-DGIT_EXEC_PATH="$(gitexecdir_SQ)"' \
+       '-DGIT_LOCALE_PATH="$(localedir_relative_SQ)"' \
        '-DBINDIR="$(bindir_relative_SQ)"' \
-       '-DPREFIX="$(prefix_SQ)"'
+       '-DFALLBACK_RUNTIME_PREFIX="$(prefix_SQ)"'
 
 builtin/init-db.sp builtin/init-db.s builtin/init-db.o: GIT-PREFIX
 builtin/init-db.sp builtin/init-db.s builtin/init-db.o: EXTRA_CPPFLAGS = \
@@ -2163,7 +2303,7 @@ attr.sp attr.s attr.o: EXTRA_CPPFLAGS = \
 
 gettext.sp gettext.s gettext.o: GIT-PREFIX
 gettext.sp gettext.s gettext.o: EXTRA_CPPFLAGS = \
-       -DGIT_LOCALE_PATH='"$(localedir_SQ)"'
+       -DGIT_LOCALE_PATH='"$(localedir_relative_SQ)"'
 
 http-push.sp http.sp http-walker.sp remote-curl.sp imap-send.sp: SPARSE_FLAGS += \
        -DCURL_DISABLE_TYPECHECK
@@ -2323,7 +2463,7 @@ endif
 
 perl/build/lib/%.pm: perl/%.pm
        $(QUIET_GEN)mkdir -p $(dir $@) && \
-       sed -e 's|@@LOCALEDIR@@|$(localedir_SQ)|g' \
+       sed -e 's|@@LOCALEDIR@@|$(perl_localedir_SQ)|g' \
            -e 's|@@NO_PERL_CPAN_FALLBACKS@@|$(NO_PERL_CPAN_FALLBACKS_SQ)|g' \
        < $< > $@
 
@@ -2494,10 +2634,12 @@ t/helper/test-svn-fe$X: $(VCSSVN_LIB)
 
 .PRECIOUS: $(TEST_OBJS)
 
+t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
+
 t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS)
        $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS)
 
-check-sha1:: t/helper/test-sha1$X
+check-sha1:: t/helper/test-tool$X
        t/helper/test-sha1.sh
 
 SP_OBJ = $(patsubst %.o,%.sp,$(C_OBJ))
@@ -2513,7 +2655,7 @@ sparse: $(SP_OBJ)
 style:
        git clang-format --style file --diff --extensions c,h
 
-check: common-cmds.h
+check: command-list.h
        @if sparse; \
        then \
                echo >&2 "Use 'make sparse' instead"; \
@@ -2606,35 +2748,44 @@ endif
 
        bindir=$$(cd '$(DESTDIR_SQ)$(bindir_SQ)' && pwd) && \
        execdir=$$(cd '$(DESTDIR_SQ)$(gitexec_instdir_SQ)' && pwd) && \
+       destdir_from_execdir_SQ=$$(echo '$(gitexecdir_relative_SQ)' | sed -e 's|[^/][^/]*|..|g') && \
        { test "$$bindir/" = "$$execdir/" || \
          for p in git$X $(filter $(install_bindir_programs),$(ALL_PROGRAMS)); do \
                $(RM) "$$execdir/$$p" && \
-               test -z "$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
-               ln "$$bindir/$$p" "$$execdir/$$p" 2>/dev/null || \
-               cp "$$bindir/$$p" "$$execdir/$$p" || exit; \
+               test -n "$(INSTALL_SYMLINKS)" && \
+               ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/$$p" "$$execdir/$$p" || \
+               { test -z "$(NO_INSTALL_HARDLINKS)$(NO_CROSS_DIRECTORY_HARDLINKS)" && \
+                 ln "$$bindir/$$p" "$$execdir/$$p" 2>/dev/null || \
+                 cp "$$bindir/$$p" "$$execdir/$$p" || exit; } \
          done; \
        } && \
        for p in $(filter $(install_bindir_programs),$(BUILT_INS)); do \
                $(RM) "$$bindir/$$p" && \
-               test -z "$(NO_INSTALL_HARDLINKS)" && \
-               ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \
-               ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \
-               cp "$$bindir/git$X" "$$bindir/$$p" || exit; \
+               test -n "$(INSTALL_SYMLINKS)" && \
+               ln -s "git$X" "$$bindir/$$p" || \
+               { test -z "$(NO_INSTALL_HARDLINKS)" && \
+                 ln "$$bindir/git$X" "$$bindir/$$p" 2>/dev/null || \
+                 ln -s "git$X" "$$bindir/$$p" 2>/dev/null || \
+                 cp "$$bindir/git$X" "$$bindir/$$p" || exit; } \
        done && \
        for p in $(BUILT_INS); do \
                $(RM) "$$execdir/$$p" && \
-               test -z "$(NO_INSTALL_HARDLINKS)" && \
-               ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
-               ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \
-               cp "$$execdir/git$X" "$$execdir/$$p" || exit; \
+               test -n "$(INSTALL_SYMLINKS)" && \
+               ln -s "$$destdir_from_execdir_SQ/$(bindir_relative_SQ)/git$X" "$$execdir/$$p" || \
+               { test -z "$(NO_INSTALL_HARDLINKS)" && \
+                 ln "$$execdir/git$X" "$$execdir/$$p" 2>/dev/null || \
+                 ln -s "git$X" "$$execdir/$$p" 2>/dev/null || \
+                 cp "$$execdir/git$X" "$$execdir/$$p" || exit; } \
        done && \
        remote_curl_aliases="$(REMOTE_CURL_ALIASES)" && \
        for p in $$remote_curl_aliases; do \
                $(RM) "$$execdir/$$p" && \
-               test -z "$(NO_INSTALL_HARDLINKS)" && \
-               ln "$$execdir/git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \
-               ln -s "git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \
-               cp "$$execdir/git-remote-http$X" "$$execdir/$$p" || exit; \
+               test -n "$(INSTALL_SYMLINKS)" && \
+               ln -s "git-remote-http$X" "$$execdir/$$p" || \
+               { test -z "$(NO_INSTALL_HARDLINKS)" && \
+                 ln "$$execdir/git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \
+                 ln -s "git-remote-http$X" "$$execdir/$$p" 2>/dev/null || \
+                 cp "$$execdir/git-remote-http$X" "$$execdir/$$p" || exit; } \
        done && \
        ./check_bindir "z$$bindir" "z$$execdir" "$$bindir/git-add$X"
 
@@ -2752,7 +2903,7 @@ clean: profile-clean coverage-clean
        $(RM) $(TEST_PROGRAMS) $(NO_INSTALL)
        $(RM) -r bin-wrappers $(dep_dirs)
        $(RM) -r po/build/
-       $(RM) *.pyc *.pyo */*.pyc */*.pyo common-cmds.h $(ETAGS_TARGET) tags cscope*
+       $(RM) *.pyc *.pyo */*.pyc */*.pyo command-list.h $(ETAGS_TARGET) tags cscope*
        $(RM) -r $(GIT_TARNAME) .doc-tmp-dir
        $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz
        $(RM) $(htmldocs).tar.gz $(manpages).tar.gz
@@ -2770,7 +2921,7 @@ ifndef NO_TCLTK
 endif
        $(RM) GIT-VERSION-FILE GIT-CFLAGS GIT-LDFLAGS GIT-BUILD-OPTIONS
        $(RM) GIT-USER-AGENT GIT-PREFIX
-       $(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PYTHON-VARS
+       $(RM) GIT-SCRIPT-DEFINES GIT-PERL-DEFINES GIT-PERL-HEADER GIT-PYTHON-VARS
 
 .PHONY: all install profile-clean clean strip
 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
index f17af66a97c8097ab91f074478c4a5cb90425725..f920a42fad3423b0b20639afd765b64ac2750d8a 100644 (file)
--- a/README.md
+++ b/README.md
@@ -36,6 +36,9 @@ the body to majordomo@vger.kernel.org. The mailing list archives are
 available at <https://public-inbox.org/git/>,
 <http://marc.info/?l=git> and other archival sites.
 
+Issues which are security relevant should be disclosed privately to
+the Git Security mailing list <git-security@googlegroups.com>.
+
 The maintainer frequently sends the "What's cooking" reports that
 list the current status of various development topics to the mailing
 list.  The discussion following them give a good reference for
index d14bdb5eda2b6c7ea4a73c7355030c994c53251c..392b0b3115c633b169cb003430d7f2ac373bf4b7 120000 (symlink)
--- a/RelNotes
+++ b/RelNotes
@@ -1 +1 @@
-Documentation/RelNotes/2.17.3.txt
\ No newline at end of file
+Documentation/RelNotes/2.18.1.txt
\ No newline at end of file
index 406efc183ba272b94a39d4cc7e97d7483a40a9d4..370a56d0546bb3fc7aa4a62203c600e9a8af2d7a 100644 (file)
--- a/advice.c
+++ b/advice.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "config.h"
+#include "color.h"
 
 int advice_push_update_rejected = 1;
 int advice_push_non_ff_current = 1;
@@ -19,6 +20,34 @@ int advice_rm_hints = 1;
 int advice_add_embedded_repo = 1;
 int advice_ignored_hook = 1;
 int advice_waiting_for_editor = 1;
+int advice_graft_file_deprecated = 1;
+
+static int advice_use_color = -1;
+static char advice_colors[][COLOR_MAXLEN] = {
+       GIT_COLOR_RESET,
+       GIT_COLOR_YELLOW,       /* HINT */
+};
+
+enum color_advice {
+       ADVICE_COLOR_RESET = 0,
+       ADVICE_COLOR_HINT = 1,
+};
+
+static int parse_advise_color_slot(const char *slot)
+{
+       if (!strcasecmp(slot, "reset"))
+               return ADVICE_COLOR_RESET;
+       if (!strcasecmp(slot, "hint"))
+               return ADVICE_COLOR_HINT;
+       return -1;
+}
+
+static const char *advise_get_color(enum color_advice ix)
+{
+       if (want_color_stderr(advice_use_color))
+               return advice_colors[ix];
+       return "";
+}
 
 static struct {
        const char *name;
@@ -42,6 +71,7 @@ static struct {
        { "addembeddedrepo", &advice_add_embedded_repo },
        { "ignoredhook", &advice_ignored_hook },
        { "waitingforeditor", &advice_waiting_for_editor },
+       { "graftfiledeprecated", &advice_graft_file_deprecated },
 
        /* make this an alias for backward compatibility */
        { "pushnonfastforward", &advice_push_update_rejected }
@@ -59,7 +89,10 @@ void advise(const char *advice, ...)
 
        for (cp = buf.buf; *cp; cp = np) {
                np = strchrnul(cp, '\n');
-               fprintf(stderr, _("hint: %.*s\n"), (int)(np - cp), cp);
+               fprintf(stderr, _("%shint: %.*s%s\n"),
+                       advise_get_color(ADVICE_COLOR_HINT),
+                       (int)(np - cp), cp,
+                       advise_get_color(ADVICE_COLOR_RESET));
                if (*np)
                        np++;
        }
@@ -68,9 +101,23 @@ void advise(const char *advice, ...)
 
 int git_default_advice_config(const char *var, const char *value)
 {
-       const char *k;
+       const char *k, *slot_name;
        int i;
 
+       if (!strcmp(var, "color.advice")) {
+               advice_use_color = git_config_colorbool(var, value);
+               return 0;
+       }
+
+       if (skip_prefix(var, "color.advice.", &slot_name)) {
+               int slot = parse_advise_color_slot(slot_name);
+               if (slot < 0)
+                       return 0;
+               if (!value)
+                       return config_error_nonbool(var);
+               return color_parse(value, advice_colors[slot]);
+       }
+
        if (!skip_prefix(var, "advice.", &k))
                return 0;
 
index 70568fa7922d8aea403e415f9b9b554a88ace293..9f5064e82a862e6daaabe3f23ea9ea896aad87e6 100644 (file)
--- a/advice.h
+++ b/advice.h
@@ -21,6 +21,7 @@ extern int advice_rm_hints;
 extern int advice_add_embedded_repo;
 extern int advice_ignored_hook;
 extern int advice_waiting_for_editor;
+extern int advice_graft_file_deprecated;
 
 int git_default_advice_config(const char *var, const char *value);
 __attribute__((format (printf, 1, 2)))
diff --git a/alias.c b/alias.c
index bf146e526329309df360b9f1028ca2f767743efa..a7e4e57130d46188a4a0ee93871375218041344c 100644 (file)
--- a/alias.c
+++ b/alias.c
@@ -1,9 +1,12 @@
 #include "cache.h"
+#include "alias.h"
 #include "config.h"
+#include "string-list.h"
 
 struct config_alias_data {
        const char *alias;
        char *v;
+       struct string_list *list;
 };
 
 static int config_alias_cb(const char *key, const char *value, void *d)
@@ -11,8 +14,16 @@ static int config_alias_cb(const char *key, const char *value, void *d)
        struct config_alias_data *data = d;
        const char *p;
 
-       if (skip_prefix(key, "alias.", &p) && !strcasecmp(p, data->alias))
-               return git_config_string((const char **)&data->v, key, value);
+       if (!skip_prefix(key, "alias.", &p))
+               return 0;
+
+       if (data->alias) {
+               if (!strcasecmp(p, data->alias))
+                       return git_config_string((const char **)&data->v,
+                                                key, value);
+       } else if (data->list) {
+               string_list_append(data->list, p);
+       }
 
        return 0;
 }
@@ -26,6 +37,13 @@ char *alias_lookup(const char *alias)
        return data.v;
 }
 
+void list_aliases(struct string_list *list)
+{
+       struct config_alias_data data = { NULL, NULL, list };
+
+       read_early_config(config_alias_cb, &data);
+}
+
 #define SPLIT_CMDLINE_BAD_ENDING 1
 #define SPLIT_CMDLINE_UNCLOSED_QUOTE 2
 static const char *split_cmdline_errors[] = {
diff --git a/alias.h b/alias.h
new file mode 100644 (file)
index 0000000..79933f2
--- /dev/null
+++ b/alias.h
@@ -0,0 +1,12 @@
+#ifndef __ALIAS_H__
+#define __ALIAS_H__
+
+struct string_list;
+
+char *alias_lookup(const char *alias);
+int split_cmdline(char *cmdline, const char ***argv);
+/* Takes a negative value returned by split_cmdline */
+const char *split_cmdline_strerror(int cmdline_errno);
+void list_aliases(struct string_list *list);
+
+#endif
diff --git a/alloc.c b/alloc.c
index 12afadfacdd6094912a6e18a217a9aa6318b47b2..cf4f8b61e126c0e9992dc34c6cb52b6f896a565d 100644 (file)
--- a/alloc.c
+++ b/alloc.c
@@ -93,6 +93,7 @@ void *alloc_commit_node(void)
        struct commit *c = alloc_node(&commit_state, sizeof(struct commit));
        c->object.type = OBJ_COMMIT;
        c->index = alloc_commit_index();
+       c->graph_pos = COMMIT_NOT_FROM_GRAPH;
        return c;
 }
 
diff --git a/apply.c b/apply.c
index 2d1cfe4dbb563e4601f5fec16d6ae2fe88fee80c..d79e61591b3814339fb8b2a39fb7d1e211d622c6 100644 (file)
--- a/apply.c
+++ b/apply.c
@@ -2375,7 +2375,7 @@ static void update_pre_post_images(struct image *preimage,
        if (postlen
            ? postlen < new_buf - postimage->buf
            : postimage->len < new_buf - postimage->buf)
-               die("BUG: caller miscounted postlen: asked %d, orig = %d, used = %d",
+               BUG("caller miscounted postlen: asked %d, orig = %d, used = %d",
                    (int)postlen, (int) postimage->len, (int)(new_buf - postimage->buf));
 
        /* Fix the length of the whole thing */
@@ -3180,7 +3180,7 @@ static int apply_binary(struct apply_state *state,
                unsigned long size;
                char *result;
 
-               result = read_sha1_file(oid.hash, &type, &size);
+               result = read_object_file(&oid, &type, &size);
                if (!result)
                        return error(_("the necessary postimage %s for "
                                       "'%s' cannot be read"),
@@ -3242,7 +3242,7 @@ static int read_blob_object(struct strbuf *buf, const struct object_id *oid, uns
                unsigned long sz;
                char *result;
 
-               result = read_sha1_file(oid->hash, &type, &sz);
+               result = read_object_file(oid, &type, &sz);
                if (!result)
                        return -1;
                /* XXX read_sha1_file NUL-terminates */
@@ -3509,7 +3509,7 @@ static int load_current(struct apply_state *state,
        unsigned mode = patch->new_mode;
 
        if (!patch->is_new)
-               die("BUG: patch to %s is not a creation", patch->old_name);
+               BUG("patch to %s is not a creation", patch->old_name);
 
        pos = cache_name_pos(name, strlen(name));
        if (pos < 0)
@@ -4058,7 +4058,7 @@ static int build_fake_ancestor(struct apply_state *state, struct patch *list)
 {
        struct patch *patch;
        struct index_state result = { NULL };
-       static struct lock_file lock;
+       struct lock_file lock = LOCK_INIT;
        int res;
 
        /* Once we start supporting the reverse patch, it may be
index c6ed96ee74ec10f5c9ffb6f520193326d4704b6b..b6f58ddf38767d86f866bd9413292e279c6cfa73 100644 (file)
@@ -111,7 +111,7 @@ static void write_trailer(void)
  * queues up writes, so that all our write(2) calls write exactly one
  * full block; pads writes to RECORDSIZE
  */
-static int stream_blocked(const unsigned char *sha1)
+static int stream_blocked(const struct object_id *oid)
 {
        struct git_istream *st;
        enum object_type type;
@@ -119,9 +119,9 @@ static int stream_blocked(const unsigned char *sha1)
        char buf[BLOCKSIZE];
        ssize_t readlen;
 
-       st = open_istream(sha1, &type, &sz, NULL);
+       st = open_istream(oid, &type, &sz, NULL);
        if (!st)
-               return error("cannot stream blob %s", sha1_to_hex(sha1));
+               return error("cannot stream blob %s", oid_to_hex(oid));
        for (;;) {
                readlen = read_istream(st, buf, sizeof(buf));
                if (readlen <= 0)
@@ -218,7 +218,7 @@ static void prepare_header(struct archiver_args *args,
 }
 
 static void write_extended_header(struct archiver_args *args,
-                                 const unsigned char *sha1,
+                                 const struct object_id *oid,
                                  const void *buffer, unsigned long size)
 {
        struct ustar_header header;
@@ -226,14 +226,14 @@ static void write_extended_header(struct archiver_args *args,
        memset(&header, 0, sizeof(header));
        *header.typeflag = TYPEFLAG_EXT_HEADER;
        mode = 0100666;
-       xsnprintf(header.name, sizeof(header.name), "%s.paxheader", sha1_to_hex(sha1));
+       xsnprintf(header.name, sizeof(header.name), "%s.paxheader", oid_to_hex(oid));
        prepare_header(args, &header, mode, size);
        write_blocked(&header, sizeof(header));
        write_blocked(buffer, size);
 }
 
 static int write_tar_entry(struct archiver_args *args,
-                          const unsigned char *sha1,
+                          const struct object_id *oid,
                           const char *path, size_t pathlen,
                           unsigned int mode)
 {
@@ -257,7 +257,7 @@ static int write_tar_entry(struct archiver_args *args,
                mode = (mode | ((mode & 0100) ? 0777 : 0666)) & ~tar_umask;
        } else {
                return error("unsupported file mode: 0%o (SHA1: %s)",
-                            mode, sha1_to_hex(sha1));
+                            mode, oid_to_hex(oid));
        }
        if (pathlen > sizeof(header.name)) {
                size_t plen = get_path_prefix(path, pathlen,
@@ -268,7 +268,7 @@ static int write_tar_entry(struct archiver_args *args,
                        memcpy(header.name, path + plen + 1, rest);
                } else {
                        xsnprintf(header.name, sizeof(header.name), "%s.data",
-                                 sha1_to_hex(sha1));
+                                 oid_to_hex(oid));
                        strbuf_append_ext_header(&ext_header, "path",
                                                 path, pathlen);
                }
@@ -276,14 +276,14 @@ static int write_tar_entry(struct archiver_args *args,
                memcpy(header.name, path, pathlen);
 
        if (S_ISREG(mode) && !args->convert &&
-           sha1_object_info(sha1, &size) == OBJ_BLOB &&
+           oid_object_info(the_repository, oid, &size) == OBJ_BLOB &&
            size > big_file_threshold)
                buffer = NULL;
        else if (S_ISLNK(mode) || S_ISREG(mode)) {
                enum object_type type;
-               buffer = sha1_file_to_archive(args, path, sha1, old_mode, &type, &size);
+               buffer = object_file_to_archive(args, path, oid, old_mode, &type, &size);
                if (!buffer)
-                       return error("cannot read %s", sha1_to_hex(sha1));
+                       return error("cannot read %s", oid_to_hex(oid));
        } else {
                buffer = NULL;
                size = 0;
@@ -292,7 +292,7 @@ static int write_tar_entry(struct archiver_args *args,
        if (S_ISLNK(mode)) {
                if (size > sizeof(header.linkname)) {
                        xsnprintf(header.linkname, sizeof(header.linkname),
-                                 "see %s.paxheader", sha1_to_hex(sha1));
+                                 "see %s.paxheader", oid_to_hex(oid));
                        strbuf_append_ext_header(&ext_header, "linkpath",
                                                 buffer, size);
                } else
@@ -308,7 +308,7 @@ static int write_tar_entry(struct archiver_args *args,
        prepare_header(args, &header, mode, size_in_header);
 
        if (ext_header.len > 0) {
-               write_extended_header(args, sha1, ext_header.buf,
+               write_extended_header(args, oid, ext_header.buf,
                                      ext_header.len);
        }
        strbuf_release(&ext_header);
@@ -317,7 +317,7 @@ static int write_tar_entry(struct archiver_args *args,
                if (buffer)
                        write_blocked(buffer, size);
                else
-                       err = stream_blocked(sha1);
+                       err = stream_blocked(oid);
        }
        free(buffer);
        return err;
@@ -441,7 +441,7 @@ static int write_tar_filter_archive(const struct archiver *ar,
        int r;
 
        if (!ar->data)
-               die("BUG: tar-filter archiver called with no filter defined");
+               BUG("tar-filter archiver called with no filter defined");
 
        strbuf_addstr(&cmd, ar->data);
        if (args->compression_level >= 0)
index e8913e5a26c6e97216c4b79ad96b5e3ddf906c45..74f3fe9103420571c9f22273ae44ebb9d5715c78 100644 (file)
@@ -276,7 +276,7 @@ static int entry_is_binary(const char *path, const void *buffer, size_t size)
 #define STREAM_BUFFER_SIZE (1024 * 16)
 
 static int write_zip_entry(struct archiver_args *args,
-                          const unsigned char *sha1,
+                          const struct object_id *oid,
                           const char *path, size_t pathlen,
                           unsigned int mode)
 {
@@ -314,7 +314,7 @@ static int write_zip_entry(struct archiver_args *args,
 
        if (pathlen > 0xffff) {
                return error("path too long (%d chars, SHA1: %s): %s",
-                               (int)pathlen, sha1_to_hex(sha1), path);
+                               (int)pathlen, oid_to_hex(oid), path);
        }
 
        if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
@@ -325,7 +325,8 @@ static int write_zip_entry(struct archiver_args *args,
                compressed_size = 0;
                buffer = NULL;
        } else if (S_ISREG(mode) || S_ISLNK(mode)) {
-               enum object_type type = sha1_object_info(sha1, &size);
+               enum object_type type = oid_object_info(the_repository, oid,
+                                                       &size);
 
                method = 0;
                attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) :
@@ -337,18 +338,18 @@ static int write_zip_entry(struct archiver_args *args,
 
                if (S_ISREG(mode) && type == OBJ_BLOB && !args->convert &&
                    size > big_file_threshold) {
-                       stream = open_istream(sha1, &type, &size, NULL);
+                       stream = open_istream(oid, &type, &size, NULL);
                        if (!stream)
                                return error("cannot stream blob %s",
-                                            sha1_to_hex(sha1));
+                                            oid_to_hex(oid));
                        flags |= ZIP_STREAM;
                        out = buffer = NULL;
                } else {
-                       buffer = sha1_file_to_archive(args, path, sha1, mode,
-                                                     &type, &size);
+                       buffer = object_file_to_archive(args, path, oid, mode,
+                                                       &type, &size);
                        if (!buffer)
                                return error("cannot read %s",
-                                            sha1_to_hex(sha1));
+                                            oid_to_hex(oid));
                        crc = crc32(crc, buffer, size);
                        is_binary = entry_is_binary(path_without_prefix,
                                                    buffer, size);
@@ -357,7 +358,7 @@ static int write_zip_entry(struct archiver_args *args,
                compressed_size = (method == 0) ? size : 0;
        } else {
                return error("unsupported file mode: 0%o (SHA1: %s)", mode,
-                               sha1_to_hex(sha1));
+                               oid_to_hex(oid));
        }
 
        if (creator_version > max_creator_version)
index 0b7b62af0c3ecee10a26e9bd2d274690604ffcad..4fe7bec60c12b3b1ab27c35b716b23f4535d170c 100644 (file)
--- a/archive.c
+++ b/archive.c
@@ -63,16 +63,16 @@ static void format_subst(const struct commit *commit,
        free(to_free);
 }
 
-void *sha1_file_to_archive(const struct archiver_args *args,
-                          const char *path, const unsigned char *sha1,
-                          unsigned int mode, enum object_type *type,
-                          unsigned long *sizep)
+void *object_file_to_archive(const struct archiver_args *args,
+                            const char *path, const struct object_id *oid,
+                            unsigned int mode, enum object_type *type,
+                            unsigned long *sizep)
 {
        void *buffer;
        const struct commit *commit = args->convert ? args->commit : NULL;
 
        path += args->baselen;
-       buffer = read_sha1_file(sha1, type, sizep);
+       buffer = read_object_file(oid, type, sizep);
        if (buffer && S_ISREG(mode)) {
                struct strbuf buf = STRBUF_INIT;
                size_t size = 0;
@@ -121,7 +121,7 @@ static int check_attr_export_subst(const struct attr_check *check)
        return check && ATTR_TRUE(check->items[1].value);
 }
 
-static int write_archive_entry(const unsigned char *sha1, const char *base,
+static int write_archive_entry(const struct object_id *oid, const char *base,
                int baselen, const char *filename, unsigned mode, int stage,
                void *context)
 {
@@ -153,7 +153,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
        if (S_ISDIR(mode) || S_ISGITLINK(mode)) {
                if (args->verbose)
                        fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
-               err = write_entry(args, sha1, path.buf, path.len, mode);
+               err = write_entry(args, oid, path.buf, path.len, mode);
                if (err)
                        return err;
                return (S_ISDIR(mode) ? READ_TREE_RECURSIVE : 0);
@@ -161,7 +161,7 @@ static int write_archive_entry(const unsigned char *sha1, const char *base,
 
        if (args->verbose)
                fprintf(stderr, "%.*s\n", (int)path.len, path.buf);
-       return write_entry(args, sha1, path.buf, path.len, mode);
+       return write_entry(args, oid, path.buf, path.len, mode);
 }
 
 static void queue_directory(const unsigned char *sha1,
@@ -191,14 +191,14 @@ static int write_directory(struct archiver_context *c)
        d->path[d->len - 1] = '\0'; /* no trailing slash */
        ret =
                write_directory(c) ||
-               write_archive_entry(d->oid.hash, d->path, d->baselen,
+               write_archive_entry(&d->oid, d->path, d->baselen,
                                    d->path + d->baselen, d->mode,
                                    d->stage, c) != READ_TREE_RECURSIVE;
        free(d);
        return ret ? -1 : 0;
 }
 
-static int queue_or_write_archive_entry(const unsigned char *sha1,
+static int queue_or_write_archive_entry(const struct object_id *oid,
                struct strbuf *base, const char *filename,
                unsigned mode, int stage, void *context)
 {
@@ -224,14 +224,14 @@ static int queue_or_write_archive_entry(const unsigned char *sha1,
 
                if (check_attr_export_ignore(check))
                        return 0;
-               queue_directory(sha1, base, filename,
+               queue_directory(oid->hash, base, filename,
                                mode, stage, c);
                return READ_TREE_RECURSIVE;
        }
 
        if (write_directory(c))
                return -1;
-       return write_archive_entry(sha1, base->buf, base->len, filename, mode,
+       return write_archive_entry(oid, base->buf, base->len, filename, mode,
                                   stage, context);
 }
 
@@ -250,7 +250,7 @@ int write_archive_entries(struct archiver_args *args,
                        len--;
                if (args->verbose)
                        fprintf(stderr, "%.*s\n", (int)len, args->base);
-               err = write_entry(args, args->tree->object.oid.hash, args->base,
+               err = write_entry(args, &args->tree->object.oid, args->base,
                                  len, 040777);
                if (err)
                        return err;
@@ -303,7 +303,7 @@ static const struct archiver *lookup_archiver(const char *name)
        return NULL;
 }
 
-static int reject_entry(const unsigned char *sha1, struct strbuf *base,
+static int reject_entry(const struct object_id *oid, struct strbuf *base,
                        const char *filename, unsigned mode,
                        int stage, void *context)
 {
@@ -397,8 +397,8 @@ static void parse_treeish_arg(const char **argv,
                unsigned int mode;
                int err;
 
-               err = get_tree_entry(tree->object.oid.hash, prefix,
-                                    tree_oid.hash, &mode);
+               err = get_tree_entry(&tree->object.oid, prefix, &tree_oid,
+                                    &mode);
                if (err || !S_ISDIR(mode))
                        die("current working directory is untracked");
 
@@ -411,11 +411,9 @@ static void parse_treeish_arg(const char **argv,
 }
 
 #define OPT__COMPR(s, v, h, p) \
-       { OPTION_SET_INT, (s), NULL, (v), NULL, (h), \
-         PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, (p) }
+       OPT_SET_INT_F(s, NULL, v, h, p, PARSE_OPT_NONEG)
 #define OPT__COMPR_HIDDEN(s, v, p) \
-       { OPTION_SET_INT, (s), NULL, (v), NULL, "", \
-         PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN, NULL, (p) }
+       OPT_SET_INT_F(s, NULL, v, "", p, PARSE_OPT_NONEG | PARSE_OPT_HIDDEN)
 
 static int parse_archive_args(int argc, const char **argv,
                const struct archiver **ar, struct archiver_args *args,
index 62d1d82c1af0fa3bf77b32d63e9b4866f3428898..1f9954f7cdc5a1ee8036321e439a65bdfb90e59f 100644 (file)
--- a/archive.h
+++ b/archive.h
@@ -31,7 +31,7 @@ extern void init_tar_archiver(void);
 extern void init_zip_archiver(void);
 
 typedef int (*write_archive_entry_fn_t)(struct archiver_args *args,
-                                       const unsigned char *sha1,
+                                       const struct object_id *oid,
                                        const char *path, size_t pathlen,
                                        unsigned int mode);
 
@@ -39,9 +39,9 @@ extern int write_archive_entries(struct archiver_args *args, write_archive_entry
 extern int write_archive(int argc, const char **argv, const char *prefix, const char *name_hint, int remote);
 
 const char *archive_format_from_filename(const char *filename);
-extern void *sha1_file_to_archive(const struct archiver_args *args,
-                                 const char *path, const unsigned char *sha1,
-                                 unsigned int mode, enum object_type *type,
-                                 unsigned long *sizep);
+extern void *object_file_to_archive(const struct archiver_args *args,
+                                   const char *path, const struct object_id *oid,
+                                   unsigned int mode, enum object_type *type,
+                                   unsigned long *sizep);
 
 #endif /* ARCHIVE_H */
index 5d370fa3366163f8c0c81ca0b6b1a64a7030c696..f352ea9357d90e16c7506af9b5b047ac1e2721ac 100644 (file)
@@ -21,12 +21,13 @@ static void argv_array_push_nodup(struct argv_array *array, const char *value)
        array->argv[array->argc] = NULL;
 }
 
-void argv_array_push(struct argv_array *array, const char *value)
+const char *argv_array_push(struct argv_array *array, const char *value)
 {
        argv_array_push_nodup(array, xstrdup(value));
+       return array->argv[array->argc - 1];
 }
 
-void argv_array_pushf(struct argv_array *array, const char *fmt, ...)
+const char *argv_array_pushf(struct argv_array *array, const char *fmt, ...)
 {
        va_list ap;
        struct strbuf v = STRBUF_INIT;
@@ -36,6 +37,7 @@ void argv_array_pushf(struct argv_array *array, const char *fmt, ...)
        va_end(ap);
 
        argv_array_push_nodup(array, strbuf_detach(&v, NULL));
+       return array->argv[array->argc - 1];
 }
 
 void argv_array_pushl(struct argv_array *array, ...)
@@ -64,6 +66,26 @@ void argv_array_pop(struct argv_array *array)
        array->argc--;
 }
 
+void argv_array_split(struct argv_array *array, const char *to_split)
+{
+       while (isspace(*to_split))
+               to_split++;
+       for (;;) {
+               const char *p = to_split;
+
+               if (!*p)
+                       break;
+
+               while (*p && !isspace(*p))
+                       p++;
+               argv_array_push_nodup(array, xstrndup(to_split, p - to_split));
+
+               while (isspace(*p))
+                       p++;
+               to_split = p;
+       }
+}
+
 void argv_array_clear(struct argv_array *array)
 {
        if (array->argv != empty_argv) {
index 29056e49a1208b5506d0809c7311e4112dc1f7f3..a39ba43f57ce4969ef936646d30e5128ff28214f 100644 (file)
@@ -12,13 +12,15 @@ struct argv_array {
 #define ARGV_ARRAY_INIT { empty_argv, 0, 0 }
 
 void argv_array_init(struct argv_array *);
-void argv_array_push(struct argv_array *, const char *);
+const char *argv_array_push(struct argv_array *, const char *);
 __attribute__((format (printf,2,3)))
-void argv_array_pushf(struct argv_array *, const char *fmt, ...);
+const char *argv_array_pushf(struct argv_array *, const char *fmt, ...);
 LAST_ARG_MUST_BE_NULL
 void argv_array_pushl(struct argv_array *, ...);
 void argv_array_pushv(struct argv_array *, const char **);
 void argv_array_pop(struct argv_array *);
+/* Splits by whitespace; does not handle quoted arguments! */
+void argv_array_split(struct argv_array *, const char *);
 void argv_array_clear(struct argv_array *);
 const char **argv_array_detach(struct argv_array *);
 
diff --git a/attr.c b/attr.c
index dfc3a558d83737921e1f97c96886539ef5fc3acb..067fb9e0c08cefa2ba1a9b1d3444938c9bab6e3d 100644 (file)
--- a/attr.c
+++ b/attr.c
@@ -10,7 +10,7 @@
 #define NO_THE_INDEX_COMPATIBILITY_MACROS
 #include "cache.h"
 #include "config.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "attr.h"
 #include "dir.h"
 #include "utf8.h"
@@ -157,7 +157,7 @@ static void all_attrs_init(struct attr_hashmap *map, struct attr_check *check)
 
        size = hashmap_get_size(&map->map);
        if (size < check->all_attrs_nr)
-               die("BUG: interned attributes shouldn't be deleted");
+               BUG("interned attributes shouldn't be deleted");
 
        /*
         * If the number of attributes in the global dictionary has increased
@@ -541,7 +541,7 @@ static void check_vector_remove(struct attr_check *check)
                        break;
 
        if (i >= check_vector.nr)
-               die("BUG: no entry found");
+               BUG("no entry found");
 
        /* shift entries over */
        for (; i < check_vector.nr - 1; i++)
@@ -599,11 +599,11 @@ struct attr_check *attr_check_initl(const char *one, ...)
                const struct git_attr *attr;
                param = va_arg(params, const char *);
                if (!param)
-                       die("BUG: counted %d != ended at %d",
+                       BUG("counted %d != ended at %d",
                            check->nr, cnt);
                attr = git_attr(param);
                if (!attr)
-                       die("BUG: %s: not a valid attribute name", param);
+                       BUG("%s: not a valid attribute name", param);
                check->items[cnt].attr = attr;
        }
        va_end(params);
@@ -714,7 +714,7 @@ void git_attr_set_direction(enum git_attr_direction new_direction,
                            struct index_state *istate)
 {
        if (is_bare_repository() && new_direction != GIT_ATTR_INDEX)
-               die("BUG: non-INDEX attr direction in a bare repo");
+               BUG("non-INDEX attr direction in a bare repo");
 
        if (new_direction != direction)
                drop_all_attr_stacks();
index f6d05bd66f42bd9874a08f5585ae99337d22dad5..a579b50884f8e6f8ce8390308d39b2664d050583 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -132,7 +132,8 @@ static void show_list(const char *debug, int counted, int nr,
                unsigned flags = commit->object.flags;
                enum object_type type;
                unsigned long size;
-               char *buf = read_sha1_file(commit->object.oid.hash, &type, &size);
+               char *buf = read_object_file(&commit->object.oid, &type,
+                                            &size);
                const char *subject_start;
                int subject_len;
 
@@ -144,10 +145,10 @@ static void show_list(const char *debug, int counted, int nr,
                        fprintf(stderr, "%3d", weight(p));
                else
                        fprintf(stderr, "---");
-               fprintf(stderr, " %.*s", 8, sha1_to_hex(commit->object.oid.hash));
+               fprintf(stderr, " %.*s", 8, oid_to_hex(&commit->object.oid));
                for (pp = commit->parents; pp; pp = pp->next)
                        fprintf(stderr, " %.*s", 8,
-                               sha1_to_hex(pp->item->object.oid.hash));
+                               oid_to_hex(&pp->item->object.oid));
 
                subject_len = find_commit_subject(buf, &subject_start);
                if (subject_len)
diff --git a/blame.c b/blame.c
index 200e0ad9a299adb13982cdc27cb6e9a768560f58..14d0e0b5751c2abaad16dac81a71436ca29ddde4 100644 (file)
--- a/blame.c
+++ b/blame.c
@@ -80,8 +80,8 @@ static void verify_working_tree_path(struct commit *work_tree, const char *path)
                struct object_id blob_oid;
                unsigned mode;
 
-               if (!get_tree_entry(commit_oid->hash, path, blob_oid.hash, &mode) &&
-                   sha1_object_info(blob_oid.hash, NULL) == OBJ_BLOB)
+               if (!get_tree_entry(commit_oid, path, &blob_oid, &mode) &&
+                   oid_object_info(the_repository, &blob_oid, NULL) == OBJ_BLOB)
                        return;
        }
 
@@ -297,8 +297,8 @@ static void fill_origin_blob(struct diff_options *opt,
                    textconv_object(o->path, o->mode, &o->blob_oid, 1, &file->ptr, &file_size))
                        ;
                else
-                       file->ptr = read_sha1_file(o->blob_oid.hash, &type,
-                                                  &file_size);
+                       file->ptr = read_object_file(&o->blob_oid, &type,
+                                                    &file_size);
                file->size = file_size;
 
                if (!file->ptr)
@@ -502,11 +502,9 @@ static int fill_blob_sha1_and_mode(struct blame_origin *origin)
 {
        if (!is_null_oid(&origin->blob_oid))
                return 0;
-       if (get_tree_entry(origin->commit->object.oid.hash,
-                          origin->path,
-                          origin->blob_oid.hash, &origin->mode))
+       if (get_tree_entry(&origin->commit->object.oid, origin->path, &origin->blob_oid, &origin->mode))
                goto error_out;
-       if (sha1_object_info(origin->blob_oid.hash, NULL) != OBJ_BLOB)
+       if (oid_object_info(the_repository, &origin->blob_oid, NULL) != OBJ_BLOB)
                goto error_out;
        return 0;
  error_out:
@@ -553,10 +551,10 @@ static struct blame_origin *find_origin(struct commit *parent,
        diff_setup_done(&diff_opts);
 
        if (is_null_oid(&origin->commit->object.oid))
-               do_diff_cache(&parent->tree->object.oid, &diff_opts);
+               do_diff_cache(get_commit_tree_oid(parent), &diff_opts);
        else
-               diff_tree_oid(&parent->tree->object.oid,
-                             &origin->commit->tree->object.oid,
+               diff_tree_oid(get_commit_tree_oid(parent),
+                             get_commit_tree_oid(origin->commit),
                              "", &diff_opts);
        diffcore_std(&diff_opts);
 
@@ -622,10 +620,10 @@ static struct blame_origin *find_rename(struct commit *parent,
        diff_setup_done(&diff_opts);
 
        if (is_null_oid(&origin->commit->object.oid))
-               do_diff_cache(&parent->tree->object.oid, &diff_opts);
+               do_diff_cache(get_commit_tree_oid(parent), &diff_opts);
        else
-               diff_tree_oid(&parent->tree->object.oid,
-                             &origin->commit->tree->object.oid,
+               diff_tree_oid(get_commit_tree_oid(parent),
+                             get_commit_tree_oid(origin->commit),
                              "", &diff_opts);
        diffcore_std(&diff_opts);
 
@@ -1257,10 +1255,10 @@ static void find_copy_in_parent(struct blame_scoreboard *sb,
                diff_opts.flags.find_copies_harder = 1;
 
        if (is_null_oid(&target->commit->object.oid))
-               do_diff_cache(&parent->tree->object.oid, &diff_opts);
+               do_diff_cache(get_commit_tree_oid(parent), &diff_opts);
        else
-               diff_tree_oid(&parent->tree->object.oid,
-                             &target->commit->tree->object.oid,
+               diff_tree_oid(get_commit_tree_oid(parent),
+                             get_commit_tree_oid(target->commit),
                              "", &diff_opts);
 
        if (!diff_opts.flags.find_copies_harder)
@@ -1808,7 +1806,7 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam
                        l->item = c;
                        if (add_decoration(&sb->revs->children,
                                           &c->parents->item->object, l))
-                               die("BUG: not unique item in first-parent chain");
+                               BUG("not unique item in first-parent chain");
                        c = c->parents->item;
                }
 
@@ -1831,8 +1829,8 @@ void setup_scoreboard(struct blame_scoreboard *sb, const char *path, struct blam
                                    &sb->final_buf_size))
                        ;
                else
-                       sb->final_buf = read_sha1_file(o->blob_oid.hash, &type,
-                                                      &sb->final_buf_size);
+                       sb->final_buf = read_object_file(&o->blob_oid, &type,
+                                                        &sb->final_buf_size);
 
                if (!sb->final_buf)
                        die(_("cannot read blob %s for path %s"),
index 2672054f0b5423cd09010302285935650435f1dc..f967c98f6324c49d9ab7f94f973230512af13707 100644 (file)
--- a/branch.c
+++ b/branch.c
@@ -3,12 +3,13 @@
 #include "config.h"
 #include "branch.h"
 #include "refs.h"
+#include "refspec.h"
 #include "remote.h"
 #include "commit.h"
 #include "worktree.h"
 
 struct tracking {
-       struct refspec spec;
+       struct refspec_item spec;
        char *src;
        const char *remote;
        int matches;
@@ -218,8 +219,8 @@ int validate_new_branchname(const char *name, struct strbuf *ref, int force)
 static int check_tracking_branch(struct remote *remote, void *cb_data)
 {
        char *tracking_branch = cb_data;
-       struct refspec query;
-       memset(&query, 0, sizeof(struct refspec));
+       struct refspec_item query;
+       memset(&query, 0, sizeof(struct refspec_item));
        query.dst = tracking_branch;
        return !remote_find_tracking(remote, &query);
 }
index 42378f3aa471eb79594d96736ad2410b54d6c4dd..4e0f64723ed8dde9c97827cc688535b2dda73025 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -149,6 +149,7 @@ extern int cmd_clone(int argc, const char **argv, const char *prefix);
 extern int cmd_clean(int argc, const char **argv, const char *prefix);
 extern int cmd_column(int argc, const char **argv, const char *prefix);
 extern int cmd_commit(int argc, const char **argv, const char *prefix);
+extern int cmd_commit_graph(int argc, const char **argv, const char *prefix);
 extern int cmd_commit_tree(int argc, const char **argv, const char *prefix);
 extern int cmd_config(int argc, const char **argv, const char *prefix);
 extern int cmd_count_objects(int argc, const char **argv, const char *prefix);
@@ -215,6 +216,7 @@ extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
 extern int cmd_revert(int argc, const char **argv, const char *prefix);
 extern int cmd_rm(int argc, const char **argv, const char *prefix);
 extern int cmd_send_pack(int argc, const char **argv, const char *prefix);
+extern int cmd_serve(int argc, const char **argv, const char *prefix);
 extern int cmd_shortlog(int argc, const char **argv, const char *prefix);
 extern int cmd_show(int argc, const char **argv, const char *prefix);
 extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
@@ -231,6 +233,7 @@ extern int cmd_update_ref(int argc, const char **argv, const char *prefix);
 extern int cmd_update_server_info(int argc, const char **argv, const char *prefix);
 extern int cmd_upload_archive(int argc, const char **argv, const char *prefix);
 extern int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix);
+extern int cmd_upload_pack(int argc, const char **argv, const char *prefix);
 extern int cmd_var(int argc, const char **argv, const char *prefix);
 extern int cmd_verify_commit(int argc, const char **argv, const char *prefix);
 extern int cmd_verify_tag(int argc, const char **argv, const char *prefix);
index 9ef7fb02d56aac94d104b50aed7d7dfda09cfc98..8a155dd41eccd8004a55b1302111293ae59ea542 100644 (file)
@@ -9,7 +9,7 @@
 #include "lockfile.h"
 #include "dir.h"
 #include "pathspec.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "cache-tree.h"
 #include "run-command.h"
 #include "parse-options.h"
@@ -265,8 +265,6 @@ static int edit_patch(int argc, const char **argv, const char *prefix)
        return 0;
 }
 
-static struct lock_file lock_file;
-
 static const char ignore_error[] =
 N_("The following paths are ignored by one of your .gitignore files:\n");
 
@@ -393,6 +391,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
        int add_new_files;
        int require_pathspec;
        char *seen = NULL;
+       struct lock_file lock_file = LOCK_INIT;
 
        git_config(add_config, NULL);
 
index 1151b5c73aec81dbfca36a799cd4049429c75973..2fc2d1e82c5ead598476964329b555e38de9a495 100644 (file)
@@ -6,7 +6,7 @@
 #include "cache.h"
 #include "config.h"
 #include "builtin.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "parse-options.h"
 #include "dir.h"
 #include "run-command.h"
@@ -403,11 +403,11 @@ static void am_load(struct am_state *state)
        struct strbuf sb = STRBUF_INIT;
 
        if (read_state_file(&sb, state, "next", 1) < 0)
-               die("BUG: state file 'next' does not exist");
+               BUG("state file 'next' does not exist");
        state->cur = strtol(sb.buf, NULL, 10);
 
        if (read_state_file(&sb, state, "last", 1) < 0)
-               die("BUG: state file 'last' does not exist");
+               BUG("state file 'last' does not exist");
        state->last = strtol(sb.buf, NULL, 10);
 
        if (read_author_script(state) < 0)
@@ -986,7 +986,7 @@ static int split_mail(struct am_state *state, enum patch_format patch_format,
        case PATCH_FORMAT_MBOXRD:
                return split_mail_mbox(state, paths, keep_cr, 1);
        default:
-               die("BUG: invalid patch_format");
+               BUG("invalid patch_format");
        }
        return -1;
 }
@@ -1041,7 +1041,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
                str = "b";
                break;
        default:
-               die("BUG: invalid value for state->keep");
+               BUG("invalid value for state->keep");
        }
 
        write_state_text(state, "keep", str);
@@ -1058,7 +1058,7 @@ static void am_setup(struct am_state *state, enum patch_format patch_format,
                str = "t";
                break;
        default:
-               die("BUG: invalid value for state->scissors");
+               BUG("invalid value for state->scissors");
        }
        write_state_text(state, "scissors", str);
 
@@ -1216,7 +1216,7 @@ static int parse_mail(struct am_state *state, const char *mail)
                mi.keep_non_patch_brackets_in_subject = 1;
                break;
        default:
-               die("BUG: invalid value for state->keep");
+               BUG("invalid value for state->keep");
        }
 
        if (state->message_id)
@@ -1232,7 +1232,7 @@ static int parse_mail(struct am_state *state, const char *mail)
                mi.use_scissors = 1;
                break;
        default:
-               die("BUG: invalid value for state->scissors");
+               BUG("invalid value for state->scissors");
        }
 
        mi.input = xfopen(mail, "r");
@@ -1463,7 +1463,7 @@ static int run_apply(const struct am_state *state, const char *index_file)
        int options = 0;
 
        if (init_apply_state(&apply_state, NULL))
-               die("BUG: init_apply_state() failed");
+               BUG("init_apply_state() failed");
 
        argv_array_push(&apply_opts, "apply");
        argv_array_pushv(&apply_opts, state->git_apply_opts.argv);
@@ -1489,7 +1489,7 @@ static int run_apply(const struct am_state *state, const char *index_file)
                apply_state.apply_verbosity = verbosity_silent;
 
        if (check_apply_state(&apply_state, force_apply))
-               die("BUG: check_apply_state() failed");
+               BUG("check_apply_state() failed");
 
        argv_array_push(&apply_paths, am_path(state, "patch"));
 
@@ -1542,7 +1542,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
        char *their_tree_name;
 
        if (get_oid("HEAD", &our_tree) < 0)
-               hashcpy(our_tree.hash, EMPTY_TREE_SHA1_BIN);
+               oidcpy(&our_tree, the_hash_algo->empty_tree);
 
        if (build_fake_ancestor(state, index_path))
                return error("could not build fake ancestor");
@@ -1550,7 +1550,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
        discard_cache();
        read_cache_from(index_path);
 
-       if (write_index_as_tree(orig_tree.hash, &the_index, index_path, 0, NULL))
+       if (write_index_as_tree(&orig_tree, &the_index, index_path, 0, NULL))
                return error(_("Repository lacks necessary blobs to fall back on 3-way merge."));
 
        say(state, stdout, _("Using index info to reconstruct a base tree..."));
@@ -1575,7 +1575,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
                return error(_("Did you hand edit your patch?\n"
                                "It does not apply to blobs recorded in its index."));
 
-       if (write_index_as_tree(their_tree.hash, &the_index, index_path, 0, NULL))
+       if (write_index_as_tree(&their_tree, &the_index, index_path, 0, NULL))
                return error("could not write tree");
 
        say(state, stdout, _("Falling back to patching base and 3-way merge..."));
@@ -1626,7 +1626,7 @@ static void do_commit(const struct am_state *state)
        if (run_hook_le(NULL, "pre-applypatch", NULL))
                exit(1);
 
-       if (write_cache_as_tree(tree.hash, 0, NULL))
+       if (write_cache_as_tree(&tree, 0, NULL))
                die(_("git write-tree failed to write a tree"));
 
        if (!get_oid_commit("HEAD", &parent)) {
@@ -1862,7 +1862,7 @@ next:
         */
        if (!state->rebasing) {
                am_destroy(state);
-               close_all_packs();
+               close_all_packs(the_repository->objects);
                run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
        }
 }
@@ -2004,7 +2004,7 @@ static int clean_index(const struct object_id *head, const struct object_id *rem
        if (fast_forward_to(head_tree, head_tree, 1))
                return -1;
 
-       if (write_cache_as_tree(index.hash, 0, NULL))
+       if (write_cache_as_tree(&index, 0, NULL))
                return -1;
 
        index_tree = parse_tree_indirect(&index);
@@ -2042,7 +2042,7 @@ static void am_skip(struct am_state *state)
        am_rerere_clear();
 
        if (get_oid("HEAD", &head))
-               hashcpy(head.hash, EMPTY_TREE_SHA1_BIN);
+               oidcpy(&head, the_hash_algo->empty_tree);
 
        if (clean_index(&head, &head))
                die(_("failed to clean index"));
@@ -2105,11 +2105,11 @@ static void am_abort(struct am_state *state)
        curr_branch = resolve_refdup("HEAD", 0, &curr_head, NULL);
        has_curr_head = curr_branch && !is_null_oid(&curr_head);
        if (!has_curr_head)
-               hashcpy(curr_head.hash, EMPTY_TREE_SHA1_BIN);
+               oidcpy(&curr_head, the_hash_algo->empty_tree);
 
        has_orig_head = !get_oid("ORIG_HEAD", &orig_head);
        if (!has_orig_head)
-               hashcpy(orig_head.hash, EMPTY_TREE_SHA1_BIN);
+               oidcpy(&orig_head, the_hash_algo->empty_tree);
 
        clean_index(&curr_head, &orig_head);
 
@@ -2231,12 +2231,12 @@ int cmd_am(int argc, const char **argv, const char *prefix)
                        N_("pass -b flag to git-mailinfo"), KEEP_NON_PATCH),
                OPT_BOOL('m', "message-id", &state.message_id,
                        N_("pass -m flag to git-mailinfo")),
-               { OPTION_SET_INT, 0, "keep-cr", &keep_cr, NULL,
-                 N_("pass --keep-cr flag to git-mailsplit for mbox format"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1},
-               { OPTION_SET_INT, 0, "no-keep-cr", &keep_cr, NULL,
-                 N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 0},
+               OPT_SET_INT_F(0, "keep-cr", &keep_cr,
+                       N_("pass --keep-cr flag to git-mailsplit for mbox format"),
+                       1, PARSE_OPT_NONEG),
+               OPT_SET_INT_F(0, "no-keep-cr", &keep_cr,
+                       N_("do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"),
+                       0, PARSE_OPT_NONEG),
                OPT_BOOL('c', "scissors", &state.scissors,
                        N_("strip everything before a scissors line")),
                OPT_PASSTHRU_ARGV(0, "whitespace", &state.git_apply_opts, N_("action"),
@@ -2407,7 +2407,7 @@ int cmd_am(int argc, const char **argv, const char *prefix)
                ret = show_patch(&state);
                break;
        default:
-               die("BUG: invalid resume value");
+               BUG("invalid resume value");
        }
 
        am_state_release(&state);
index 9dcb367b90d99fc9ebbbf878f53cd5b4651d7864..3295718841aab1051ee8bdde0b1fc0aa26ae5f00 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "cache.h"
 #include "config.h"
+#include "color.h"
 #include "builtin.h"
 #include "commit.h"
 #include "diff.h"
@@ -23,6 +24,7 @@
 #include "dir.h"
 #include "progress.h"
 #include "blame.h"
+#include "string-list.h"
 
 static char blame_usage[] = N_("git blame [<options>] [<rev-opts>] [<rev>] [--] <file>");
 
@@ -46,6 +48,8 @@ static int xdl_opts;
 static int abbrev = -1;
 static int no_whole_file_rename;
 static int show_progress;
+static char repeated_meta_color[COLOR_MAXLEN];
+static int coloring_mode;
 
 static struct date_mode blame_date_mode = { DATE_ISO8601 };
 static size_t blame_date_width;
@@ -316,10 +320,12 @@ static const char *format_time(timestamp_t time, const char *tz_str,
 #define OUTPUT_PORCELAIN       010
 #define OUTPUT_SHOW_NAME       020
 #define OUTPUT_SHOW_NUMBER     040
-#define OUTPUT_SHOW_SCORE      0100
-#define OUTPUT_NO_AUTHOR       0200
+#define OUTPUT_SHOW_SCORE      0100
+#define OUTPUT_NO_AUTHOR       0200
 #define OUTPUT_SHOW_EMAIL      0400
-#define OUTPUT_LINE_PORCELAIN 01000
+#define OUTPUT_LINE_PORCELAIN  01000
+#define OUTPUT_COLOR_LINE      02000
+#define OUTPUT_SHOW_AGE_WITH_COLOR     04000
 
 static void emit_porcelain_details(struct blame_origin *suspect, int repeat)
 {
@@ -367,6 +373,64 @@ static void emit_porcelain(struct blame_scoreboard *sb, struct blame_entry *ent,
                putchar('\n');
 }
 
+static struct color_field {
+       timestamp_t hop;
+       char col[COLOR_MAXLEN];
+} *colorfield;
+static int colorfield_nr, colorfield_alloc;
+
+static void parse_color_fields(const char *s)
+{
+       struct string_list l = STRING_LIST_INIT_DUP;
+       struct string_list_item *item;
+       enum { EXPECT_DATE, EXPECT_COLOR } next = EXPECT_COLOR;
+
+       colorfield_nr = 0;
+
+       /* Ideally this would be stripped and split at the same time? */
+       string_list_split(&l, s, ',', -1);
+       ALLOC_GROW(colorfield, colorfield_nr + 1, colorfield_alloc);
+
+       for_each_string_list_item(item, &l) {
+               switch (next) {
+               case EXPECT_DATE:
+                       colorfield[colorfield_nr].hop = approxidate(item->string);
+                       next = EXPECT_COLOR;
+                       colorfield_nr++;
+                       ALLOC_GROW(colorfield, colorfield_nr + 1, colorfield_alloc);
+                       break;
+               case EXPECT_COLOR:
+                       if (color_parse(item->string, colorfield[colorfield_nr].col))
+                               die(_("expecting a color: %s"), item->string);
+                       next = EXPECT_DATE;
+                       break;
+               }
+       }
+
+       if (next == EXPECT_COLOR)
+               die (_("must end with a color"));
+
+       colorfield[colorfield_nr].hop = TIME_MAX;
+       string_list_clear(&l, 0);
+}
+
+static void setup_default_color_by_age(void)
+{
+       parse_color_fields("blue,12 month ago,white,1 month ago,red");
+}
+
+static void determine_line_heat(struct blame_entry *ent, const char **dest_color)
+{
+       int i = 0;
+       struct commit_info ci;
+       get_commit_info(ent->suspect->commit, &ci, 1);
+
+       while (i < colorfield_nr && ci.author_time > colorfield[i].hop)
+               i++;
+
+       *dest_color = colorfield[i].col;
+}
+
 static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int opt)
 {
        int cnt;
@@ -375,15 +439,35 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
        struct commit_info ci;
        char hex[GIT_MAX_HEXSZ + 1];
        int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);
+       const char *default_color = NULL, *color = NULL, *reset = NULL;
 
        get_commit_info(suspect->commit, &ci, 1);
        oid_to_hex_r(hex, &suspect->commit->object.oid);
 
        cp = blame_nth_line(sb, ent->lno);
+
+       if (opt & OUTPUT_SHOW_AGE_WITH_COLOR) {
+               determine_line_heat(ent, &default_color);
+               color = default_color;
+               reset = GIT_COLOR_RESET;
+       }
+
        for (cnt = 0; cnt < ent->num_lines; cnt++) {
                char ch;
                int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? GIT_SHA1_HEXSZ : abbrev;
 
+               if (opt & OUTPUT_COLOR_LINE) {
+                       if (cnt > 0) {
+                               color = repeated_meta_color;
+                               reset = GIT_COLOR_RESET;
+                       } else  {
+                               color = default_color ? default_color : NULL;
+                               reset = default_color ? GIT_COLOR_RESET : NULL;
+                       }
+               }
+               if (color)
+                       fputs(color, stdout);
+
                if (suspect->commit->object.flags & UNINTERESTING) {
                        if (blank_boundary)
                                memset(hex, ' ', length);
@@ -433,6 +517,8 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
                        printf(" %*d) ",
                               max_digits, ent->lno + 1 + cnt);
                }
+               if (reset)
+                       fputs(reset, stdout);
                do {
                        ch = *cp++;
                        putchar(ch);
@@ -499,7 +585,7 @@ static int read_ancestry(const char *graft_file)
 
 static int update_auto_abbrev(int auto_abbrev, struct blame_origin *suspect)
 {
-       const char *uniq = find_unique_abbrev(suspect->commit->object.oid.hash,
+       const char *uniq = find_unique_abbrev(&suspect->commit->object.oid,
                                              auto_abbrev);
        int len = strlen(uniq);
        if (auto_abbrev < len)
@@ -607,6 +693,30 @@ static int git_blame_config(const char *var, const char *value, void *cb)
                parse_date_format(value, &blame_date_mode);
                return 0;
        }
+       if (!strcmp(var, "color.blame.repeatedlines")) {
+               if (color_parse_mem(value, strlen(value), repeated_meta_color))
+                       warning(_("invalid color '%s' in color.blame.repeatedLines"),
+                               value);
+               return 0;
+       }
+       if (!strcmp(var, "color.blame.highlightrecent")) {
+               parse_color_fields(value);
+               return 0;
+       }
+
+       if (!strcmp(var, "blame.coloring")) {
+               if (!strcmp(value, "repeatedLines")) {
+                       coloring_mode |= OUTPUT_COLOR_LINE;
+               } else if (!strcmp(value, "highlightRecent")) {
+                       coloring_mode |= OUTPUT_SHOW_AGE_WITH_COLOR;
+               } else if (!strcmp(value, "none")) {
+                       coloring_mode &= ~(OUTPUT_COLOR_LINE |
+                                           OUTPUT_SHOW_AGE_WITH_COLOR);
+               } else {
+                       warning(_("invalid value for blame.coloring"));
+                       return 0;
+               }
+       }
 
        if (git_diff_heuristic_config(var, value, cb) < 0)
                return -1;
@@ -655,7 +765,7 @@ static int is_a_rev(const char *name)
 
        if (get_oid(name, &oid))
                return 0;
-       return OBJ_NONE < sha1_object_info(oid.hash, NULL);
+       return OBJ_NONE < oid_object_info(the_repository, &oid, NULL);
 }
 
 int cmd_blame(int argc, const char **argv, const char *prefix)
@@ -690,6 +800,8 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
                OPT_BIT('s', NULL, &output_option, N_("Suppress author name and timestamp (Default: off)"), OUTPUT_NO_AUTHOR),
                OPT_BIT('e', "show-email", &output_option, N_("Show author email instead of name (Default: off)"), OUTPUT_SHOW_EMAIL),
                OPT_BIT('w', NULL, &xdl_opts, N_("Ignore whitespace differences"), XDF_IGNORE_WHITESPACE),
+               OPT_BIT(0, "color-lines", &output_option, N_("color redundant metadata from previous line differently"), OUTPUT_COLOR_LINE),
+               OPT_BIT(0, "color-by-age", &output_option, N_("color lines by age"), OUTPUT_SHOW_AGE_WITH_COLOR),
 
                /*
                 * The following two options are parsed by parse_revision_opt()
@@ -714,6 +826,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        unsigned int range_i;
        long anchor;
 
+       setup_default_color_by_age();
        git_config(git_blame_config, &output_option);
        init_revisions(&revs, NULL);
        revs.date_mode = blame_date_mode;
@@ -729,6 +842,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
        for (;;) {
                switch (parse_options_step(&ctx, options, blame_opt_usage)) {
                case PARSE_OPT_HELP:
+               case PARSE_OPT_ERROR:
                        exit(129);
                case PARSE_OPT_DONE:
                        if (ctx.argv[0])
@@ -948,8 +1062,17 @@ parse_done:
 
        blame_coalesce(&sb);
 
-       if (!(output_option & OUTPUT_PORCELAIN))
+       if (!(output_option & (OUTPUT_COLOR_LINE | OUTPUT_SHOW_AGE_WITH_COLOR)))
+               output_option |= coloring_mode;
+
+       if (!(output_option & OUTPUT_PORCELAIN)) {
                find_alignment(&sb, &output_option);
+               if (!*repeated_meta_color &&
+                   (output_option & OUTPUT_COLOR_LINE))
+                       strcpy(repeated_meta_color, GIT_COLOR_CYAN);
+       }
+       if (output_option & OUTPUT_ANNOTATE_COMPAT)
+               output_option &= ~(OUTPUT_COLOR_LINE | OUTPUT_SHOW_AGE_WITH_COLOR);
 
        output(&sb, output_option);
        free((void *)sb.final_buf);
index 6d0cea9d4bcc4eb866280d6424a6dec32b5f9c87..5217ba3bdebc2255e95260fdb097166d3617e120 100644 (file)
@@ -273,7 +273,7 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
                               bname.buf,
                               (flags & REF_ISBROKEN) ? "broken"
                               : (flags & REF_ISSYMREF) ? target
-                              : find_unique_abbrev(oid.hash, DEFAULT_ABBREV));
+                              : find_unique_abbrev(&oid, DEFAULT_ABBREV));
                }
                delete_branch_config(bname.buf);
 
@@ -391,7 +391,6 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
        struct ref_array array;
        int maxwidth = 0;
        const char *remote_prefix = "";
-       struct strbuf out = STRBUF_INIT;
        char *to_free = NULL;
 
        /*
@@ -419,7 +418,10 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
        ref_array_sort(sorting, &array);
 
        for (i = 0; i < array.nr; i++) {
-               format_ref_array_item(array.items[i], format, &out);
+               struct strbuf out = STRBUF_INIT;
+               struct strbuf err = STRBUF_INIT;
+               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 */
@@ -428,6 +430,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
                        fwrite(out.buf, 1, out.len, stdout);
                        putchar('\n');
                }
+               strbuf_release(&err);
                strbuf_release(&out);
        }
 
@@ -497,7 +500,7 @@ static void copy_or_rename_branch(const char *oldname, const char *newname, int
 
        if (!skip_prefix(oldref.buf, "refs/heads/", &interpreted_oldname) ||
            !skip_prefix(newref.buf, "refs/heads/", &interpreted_newname)) {
-               die("BUG: expected prefix missing for refs");
+               BUG("expected prefix missing for refs");
        }
 
        if (copy)
@@ -589,8 +592,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                OPT__QUIET(&quiet, N_("suppress informational messages")),
                OPT_SET_INT('t', "track",  &track, N_("set up tracking mode (see git-pull(1))"),
                        BRANCH_TRACK_EXPLICIT),
-               { OPTION_SET_INT, 0, "set-upstream", &track, NULL, N_("do not use"),
-                       PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, BRANCH_TRACK_OVERRIDE },
+               OPT_SET_INT_F(0, "set-upstream", &track, N_("do not use"),
+                       BRANCH_TRACK_OVERRIDE, PARSE_OPT_HIDDEN),
                OPT_STRING('u', "set-upstream-to", &new_upstream, N_("upstream"), N_("change the upstream info")),
                OPT_BOOL(0, "unset-upstream", &unset_upstream, N_("Unset the upstream info")),
                OPT__COLOR(&branch_use_color, N_("use colored output")),
@@ -698,7 +701,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                 * If no sorting parameter is given then we default to sorting
                 * by 'refname'. This would give us an alphabetically sorted
                 * array with the 'HEAD' ref at the beginning followed by
-                * local branches 'refs/heads/...' and finally remote-tacking
+                * local branches 'refs/heads/...' and finally remote-tracking
                 * branches 'refs/remotes/...'.
                 */
                if (!sorting)
index d90170f070f4f6ab7750c31fdcfac462c934b26d..665b5819499b4d56a4f49996125cac919e477309 100644 (file)
@@ -32,7 +32,7 @@ static int filter_object(const char *path, unsigned mode,
 {
        enum object_type type;
 
-       *buf = read_sha1_file(oid->hash, &type, size);
+       *buf = read_object_file(oid, &type, size);
        if (!*buf)
                return error(_("cannot read object %s '%s'"),
                             oid_to_hex(oid), path);
@@ -77,7 +77,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
        switch (opt) {
        case 't':
                oi.type_name = &sb;
-               if (sha1_object_info_extended(oid.hash, &oi, flags) < 0)
+               if (oid_object_info_extended(the_repository, &oid, &oi, flags) < 0)
                        die("git cat-file: could not get object info");
                if (sb.len) {
                        printf("%s\n", sb.buf);
@@ -88,7 +88,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 
        case 's':
                oi.sizep = &size;
-               if (sha1_object_info_extended(oid.hash, &oi, flags) < 0)
+               if (oid_object_info_extended(the_repository, &oid, &oi, flags) < 0)
                        die("git cat-file: could not get object info");
                printf("%lu\n", size);
                return 0;
@@ -116,7 +116,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
                /* else fallthrough */
 
        case 'p':
-               type = sha1_object_info(oid.hash, NULL);
+               type = oid_object_info(the_repository, &oid, NULL);
                if (type < 0)
                        die("Not a valid object name %s", obj_name);
 
@@ -130,7 +130,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
 
                if (type == OBJ_BLOB)
                        return stream_blob_to_fd(1, &oid, NULL, 0);
-               buf = read_sha1_file(oid.hash, &type, &size);
+               buf = read_object_file(&oid, &type, &size);
                if (!buf)
                        die("Cannot read object %s", obj_name);
 
@@ -140,8 +140,9 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
        case 0:
                if (type_from_string(exp_type) == OBJ_BLOB) {
                        struct object_id blob_oid;
-                       if (sha1_object_info(oid.hash, NULL) == OBJ_TAG) {
-                               char *buffer = read_sha1_file(oid.hash, &type, &size);
+                       if (oid_object_info(the_repository, &oid, NULL) == OBJ_TAG) {
+                               char *buffer = read_object_file(&oid, &type,
+                                                               &size);
                                const char *target;
                                if (!skip_prefix(buffer, "object ", &target) ||
                                    get_oid_hex(target, &blob_oid))
@@ -150,7 +151,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
                        } else
                                oidcpy(&blob_oid, &oid);
 
-                       if (sha1_object_info(blob_oid.hash, NULL) == OBJ_BLOB)
+                       if (oid_object_info(the_repository, &blob_oid, NULL) == OBJ_BLOB)
                                return stream_blob_to_fd(1, &blob_oid, NULL, 0);
                        /*
                         * we attempted to dereference a tag to a blob
@@ -159,7 +160,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
                         * fall-back to the usual case.
                         */
                }
-               buf = read_object_with_reference(oid.hash, exp_type, &size, NULL);
+               buf = read_object_with_reference(&oid, exp_type, &size, NULL);
                break;
 
        default:
@@ -304,13 +305,14 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
                                enum object_type type;
                                if (!textconv_object(data->rest, 0100644, oid,
                                                     1, &contents, &size))
-                                       contents = read_sha1_file(oid->hash, &type,
-                                                                 &size);
+                                       contents = read_object_file(oid,
+                                                                   &type,
+                                                                   &size);
                                if (!contents)
                                        die("could not convert '%s' %s",
                                            oid_to_hex(oid), data->rest);
                        } else
-                               die("BUG: invalid cmdmode: %c", opt->cmdmode);
+                               BUG("invalid cmdmode: %c", opt->cmdmode);
                        batch_write(opt, contents, size);
                        free(contents);
                } else if (stream_blob_to_fd(1, oid, NULL, 0) < 0)
@@ -321,7 +323,7 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
                unsigned long size;
                void *contents;
 
-               contents = read_sha1_file(oid->hash, &type, &size);
+               contents = read_object_file(oid, &type, &size);
                if (!contents)
                        die("object %s disappeared", oid_to_hex(oid));
                if (type != data->type)
@@ -340,8 +342,8 @@ static void batch_object_write(const char *obj_name, struct batch_options *opt,
        struct strbuf buf = STRBUF_INIT;
 
        if (!data->skip_object_info &&
-           sha1_object_info_extended(data->oid.hash, &data->info,
-                                     OBJECT_INFO_LOOKUP_REPLACE) < 0) {
+           oid_object_info_extended(the_repository, &data->oid, &data->info,
+                                    OBJECT_INFO_LOOKUP_REPLACE) < 0) {
                printf("%s missing\n",
                       obj_name ? obj_name : oid_to_hex(&data->oid));
                fflush(stdout);
@@ -385,7 +387,7 @@ static void batch_one_object(const char *obj_name, struct batch_options *opt,
                               (uintmax_t)strlen(obj_name), obj_name);
                        break;
                default:
-                       die("BUG: unknown get_sha1_with_context result %d\n",
+                       BUG("unknown get_sha1_with_context result %d\n",
                               result);
                        break;
                }
index d76e13c8524003fcc5c55d706c1177f66520b9d4..2e1d2376d24043a75adb9bbc69724591bcc2d5c3 100644 (file)
@@ -66,7 +66,7 @@ static int post_checkout_hook(struct commit *old_commit, struct commit *new_comm
 
 }
 
-static int update_some(const unsigned char *sha1, struct strbuf *base,
+static int update_some(const struct object_id *oid, struct strbuf *base,
                const char *pathname, unsigned mode, int stage, void *context)
 {
        int len;
@@ -78,7 +78,7 @@ static int update_some(const unsigned char *sha1, struct strbuf *base,
 
        len = base->len + strlen(pathname);
        ce = xcalloc(1, cache_entry_size(len));
-       hashcpy(ce->oid.hash, sha1);
+       oidcpy(&ce->oid, oid);
        memcpy(ce->name, base->buf, base->len);
        memcpy(ce->name + base->len, pathname, len - base->len);
        ce->ce_flags = create_ce_flags(0) | CE_UPDATE;
@@ -405,10 +405,10 @@ static void describe_detached_head(const char *msg, struct commit *commit)
                pp_commit_easy(CMIT_FMT_ONELINE, commit, &sb);
        if (print_sha1_ellipsis()) {
                fprintf(stderr, "%s %s... %s\n", msg,
-                       find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV), sb.buf);
+                       find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV), sb.buf);
        } else {
                fprintf(stderr, "%s %s %s\n", msg,
-                       find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV), sb.buf);
+                       find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV), sb.buf);
        }
        strbuf_release(&sb);
 }
@@ -484,7 +484,8 @@ static int merge_working_tree(const struct checkout_opts *opts,
 
        resolve_undo_clear();
        if (opts->force) {
-               ret = reset_tree(new_branch_info->commit->tree, opts, 1, writeout_error);
+               ret = reset_tree(get_commit_tree(new_branch_info->commit),
+                                opts, 1, writeout_error);
                if (ret)
                        return ret;
        } else {
@@ -526,6 +527,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
                init_tree_desc(&trees[1], tree->buffer, tree->size);
 
                ret = unpack_trees(2, trees, &topts);
+               clear_unpack_trees_porcelain(&topts);
                if (ret == -1) {
                        /*
                         * Unpack couldn't do a trivial merge; either
@@ -570,18 +572,23 @@ static int merge_working_tree(const struct checkout_opts *opts,
                        o.verbosity = 0;
                        work = write_tree_from_memory(&o);
 
-                       ret = reset_tree(new_branch_info->commit->tree, opts, 1,
+                       ret = reset_tree(get_commit_tree(new_branch_info->commit),
+                                        opts, 1,
                                         writeout_error);
                        if (ret)
                                return ret;
                        o.ancestor = old_branch_info->name;
                        o.branch1 = new_branch_info->name;
                        o.branch2 = "local";
-                       ret = merge_trees(&o, new_branch_info->commit->tree, work,
-                               old_branch_info->commit->tree, &result);
+                       ret = merge_trees(&o,
+                                         get_commit_tree(new_branch_info->commit),
+                                         work,
+                                         get_commit_tree(old_branch_info->commit),
+                                         &result);
                        if (ret < 0)
                                exit(128);
-                       ret = reset_tree(new_branch_info->commit->tree, opts, 0,
+                       ret = reset_tree(get_commit_tree(new_branch_info->commit),
+                                        opts, 0,
                                         writeout_error);
                        strbuf_release(&o.obuf);
                        if (ret)
@@ -720,7 +727,7 @@ static int add_pending_uninteresting_ref(const char *refname,
 static void describe_one_orphan(struct strbuf *sb, struct commit *commit)
 {
        strbuf_addstr(sb, "  ");
-       strbuf_add_unique_abbrev(sb, commit->object.oid.hash, DEFAULT_ABBREV);
+       strbuf_add_unique_abbrev(sb, &commit->object.oid, DEFAULT_ABBREV);
        strbuf_addch(sb, ' ');
        if (!parse_commit(commit))
                pp_commit_easy(CMIT_FMT_ONELINE, commit, sb);
@@ -778,7 +785,7 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs)
                        " git branch <new-branch-name> %s\n\n",
                        /* Give ngettext() the count */
                        lost),
-                       find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
+                       find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV));
 }
 
 /*
@@ -1002,7 +1009,7 @@ static int parse_branchname_arg(int argc, const char **argv,
                *source_tree = parse_tree_indirect(rev);
        } else {
                parse_commit_or_die(new_branch_info->commit);
-               *source_tree = new_branch_info->commit->tree;
+               *source_tree = get_commit_tree(new_branch_info->commit);
        }
 
        if (!*source_tree)                   /* case (1): want a tree */
index 09fbca15efe315d652ea5f4ee23d9ddbf672a611..d0e0ff192b47b0709b830434e8c7d0cd10bbc3fe 100644 (file)
@@ -14,6 +14,7 @@
 #include "parse-options.h"
 #include "fetch-pack.h"
 #include "refs.h"
+#include "refspec.h"
 #include "tree.h"
 #include "tree-walk.h"
 #include "unpack-trees.h"
@@ -27,6 +28,7 @@
 #include "connected.h"
 #include "packfile.h"
 #include "list-objects-filter-options.h"
+#include "object-store.h"
 
 /*
  * Overall FIXMEs:
@@ -545,7 +547,7 @@ static struct ref *find_remote_branch(const struct ref *refs, const char *branch
 }
 
 static struct ref *wanted_peer_refs(const struct ref *refs,
-               struct refspec *refspec)
+               struct refspec_item *refspec)
 {
        struct ref *head = copy_ref(find_ref_by_name(refs, "HEAD"));
        struct ref *local_refs = head;
@@ -822,7 +824,7 @@ static void write_refspec_config(const char *src_ref_prefix,
                        } else if (remote_head_points_at) {
                                const char *head = remote_head_points_at->name;
                                if (!skip_prefix(head, "refs/heads/", &head))
-                                       die("BUG: remote HEAD points at non-head?");
+                                       BUG("remote HEAD points at non-head?");
 
                                strbuf_addf(&value, "+%s:%s%s", remote_head_points_at->name,
                                                branch_top->buf, head);
@@ -893,8 +895,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        int err = 0, complete_refs_before_fetch = 1;
        int submodule_progress;
 
-       struct refspec *refspec;
-       const char *fetch_pattern;
+       struct refspec_item refspec;
 
        fetch_if_missing = 0;
 
@@ -1076,8 +1077,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        if (option_required_reference.nr || option_optional_reference.nr)
                setup_reference();
 
-       fetch_pattern = value.buf;
-       refspec = parse_fetch_refspec(1, &fetch_pattern);
+       refspec_item_init(&refspec, value.buf, REFSPEC_FETCH);
 
        strbuf_reset(&value);
 
@@ -1134,10 +1134,10 @@ 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;
 
-       refs = transport_get_remote_refs(transport);
+       refs = transport_get_remote_refs(transport, NULL);
 
        if (refs) {
-               mapped_refs = wanted_peer_refs(refs, refspec);
+               mapped_refs = wanted_peer_refs(refs, &refspec);
                /*
                 * transport_get_remote_refs() may return refs with null sha-1
                 * in mapped_refs (see struct transport->get_refs_list
@@ -1217,7 +1217,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        transport_disconnect(transport);
 
        if (option_dissociate) {
-               close_all_packs();
+               close_all_packs(the_repository->objects);
                dissociate_from_references();
        }
 
@@ -1231,6 +1231,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
        strbuf_release(&value);
        junk_mode = JUNK_LEAVE_ALL;
 
-       free(refspec);
+       refspec_item_clear(&refspec);
        return err;
 }
index 0c3223d64b159580935bf24f8583a35a1ae903ff..5228ccf37a5c8f568091ebef6df86fda40aa93dc 100644 (file)
@@ -42,7 +42,6 @@ int cmd_column(int argc, const char **argv, const char *prefix)
                git_config(column_config, NULL);
 
        memset(&copts, 0, sizeof(copts));
-       copts.width = term_columns();
        copts.padding = 1;
        argc = parse_options(argc, argv, "", options, builtin_column_usage, 0);
        if (argc)
diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c
new file mode 100644 (file)
index 0000000..37420ae
--- /dev/null
@@ -0,0 +1,171 @@
+#include "builtin.h"
+#include "config.h"
+#include "dir.h"
+#include "lockfile.h"
+#include "parse-options.h"
+#include "commit-graph.h"
+
+static char const * const builtin_commit_graph_usage[] = {
+       N_("git commit-graph [--object-dir <objdir>]"),
+       N_("git commit-graph read [--object-dir <objdir>]"),
+       N_("git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--stdin-commits]"),
+       NULL
+};
+
+static const char * const builtin_commit_graph_read_usage[] = {
+       N_("git commit-graph read [--object-dir <objdir>]"),
+       NULL
+};
+
+static const char * const builtin_commit_graph_write_usage[] = {
+       N_("git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--stdin-commits]"),
+       NULL
+};
+
+static struct opts_commit_graph {
+       const char *obj_dir;
+       int stdin_packs;
+       int stdin_commits;
+       int append;
+} opts;
+
+static int graph_read(int argc, const char **argv)
+{
+       struct commit_graph *graph = NULL;
+       char *graph_name;
+
+       static struct option builtin_commit_graph_read_options[] = {
+               OPT_STRING(0, "object-dir", &opts.obj_dir,
+                       N_("dir"),
+                       N_("The object directory to store the graph")),
+               OPT_END(),
+       };
+
+       argc = parse_options(argc, argv, NULL,
+                            builtin_commit_graph_read_options,
+                            builtin_commit_graph_read_usage, 0);
+
+       if (!opts.obj_dir)
+               opts.obj_dir = get_object_directory();
+
+       graph_name = get_commit_graph_filename(opts.obj_dir);
+       graph = load_commit_graph_one(graph_name);
+
+       if (!graph)
+               die("graph file %s does not exist", graph_name);
+       FREE_AND_NULL(graph_name);
+
+       printf("header: %08x %d %d %d %d\n",
+               ntohl(*(uint32_t*)graph->data),
+               *(unsigned char*)(graph->data + 4),
+               *(unsigned char*)(graph->data + 5),
+               *(unsigned char*)(graph->data + 6),
+               *(unsigned char*)(graph->data + 7));
+       printf("num_commits: %u\n", graph->num_commits);
+       printf("chunks:");
+
+       if (graph->chunk_oid_fanout)
+               printf(" oid_fanout");
+       if (graph->chunk_oid_lookup)
+               printf(" oid_lookup");
+       if (graph->chunk_commit_data)
+               printf(" commit_metadata");
+       if (graph->chunk_large_edges)
+               printf(" large_edges");
+       printf("\n");
+
+       return 0;
+}
+
+static int graph_write(int argc, const char **argv)
+{
+       const char **pack_indexes = NULL;
+       int packs_nr = 0;
+       const char **commit_hex = NULL;
+       int commits_nr = 0;
+       const char **lines = NULL;
+       int lines_nr = 0;
+       int lines_alloc = 0;
+
+       static struct option builtin_commit_graph_write_options[] = {
+               OPT_STRING(0, "object-dir", &opts.obj_dir,
+                       N_("dir"),
+                       N_("The object directory to store the graph")),
+               OPT_BOOL(0, "stdin-packs", &opts.stdin_packs,
+                       N_("scan pack-indexes listed by stdin for commits")),
+               OPT_BOOL(0, "stdin-commits", &opts.stdin_commits,
+                       N_("start walk at commits listed by stdin")),
+               OPT_BOOL(0, "append", &opts.append,
+                       N_("include all commits already in the commit-graph file")),
+               OPT_END(),
+       };
+
+       argc = parse_options(argc, argv, NULL,
+                            builtin_commit_graph_write_options,
+                            builtin_commit_graph_write_usage, 0);
+
+       if (opts.stdin_packs && opts.stdin_commits)
+               die(_("cannot use both --stdin-commits and --stdin-packs"));
+       if (!opts.obj_dir)
+               opts.obj_dir = get_object_directory();
+
+       if (opts.stdin_packs || opts.stdin_commits) {
+               struct strbuf buf = STRBUF_INIT;
+               lines_nr = 0;
+               lines_alloc = 128;
+               ALLOC_ARRAY(lines, lines_alloc);
+
+               while (strbuf_getline(&buf, stdin) != EOF) {
+                       ALLOC_GROW(lines, lines_nr + 1, lines_alloc);
+                       lines[lines_nr++] = strbuf_detach(&buf, NULL);
+               }
+
+               if (opts.stdin_packs) {
+                       pack_indexes = lines;
+                       packs_nr = lines_nr;
+               }
+               if (opts.stdin_commits) {
+                       commit_hex = lines;
+                       commits_nr = lines_nr;
+               }
+       }
+
+       write_commit_graph(opts.obj_dir,
+                          pack_indexes,
+                          packs_nr,
+                          commit_hex,
+                          commits_nr,
+                          opts.append);
+
+       return 0;
+}
+
+int cmd_commit_graph(int argc, const char **argv, const char *prefix)
+{
+       static struct option builtin_commit_graph_options[] = {
+               OPT_STRING(0, "object-dir", &opts.obj_dir,
+                       N_("dir"),
+                       N_("The object directory to store the graph")),
+               OPT_END(),
+       };
+
+       if (argc == 2 && !strcmp(argv[1], "-h"))
+               usage_with_options(builtin_commit_graph_usage,
+                                  builtin_commit_graph_options);
+
+       git_config(git_default_config, NULL);
+       argc = parse_options(argc, argv, prefix,
+                            builtin_commit_graph_options,
+                            builtin_commit_graph_usage,
+                            PARSE_OPT_STOP_AT_NON_OPTION);
+
+       if (argc > 0) {
+               if (!strcmp(argv[0], "read"))
+                       return graph_read(argc, argv);
+               if (!strcmp(argv[0], "write"))
+                       return graph_write(argc, argv);
+       }
+
+       usage_with_options(builtin_commit_graph_usage,
+                          builtin_commit_graph_options);
+}
index e5bdf57b1e14cf54916c7eef077e63edddb28901..ecf42191da10cd2e87360f001d5493e792b9682e 100644 (file)
@@ -58,7 +58,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
                                usage(commit_tree_usage);
                        if (get_oid_commit(argv[i], &oid))
                                die("Not a valid object name %s", argv[i]);
-                       assert_sha1_type(oid.hash, OBJ_COMMIT);
+                       assert_oid_type(&oid, OBJ_COMMIT);
                        new_parent(lookup_commit(&oid), &parents);
                        continue;
                }
index 37fcb55ab0a03a5fdabaca1913bc700201fd8e10..a842fea666a33bb2191d10cf452a255754bb44e6 100644 (file)
@@ -143,6 +143,16 @@ static int opt_parse_m(const struct option *opt, const char *arg, int unset)
        return 0;
 }
 
+static int opt_parse_rename_score(const struct option *opt, const char *arg, int unset)
+{
+       const char **value = opt->value;
+       if (arg != NULL && *arg == '=')
+               arg = arg + 1;
+
+       *value = arg;
+       return 0;
+}
+
 static void determine_whence(struct wt_status *s)
 {
        if (file_exists(git_path_merge_head()))
@@ -161,9 +171,9 @@ static void determine_whence(struct wt_status *s)
 static void status_init_config(struct wt_status *s, config_fn_t fn)
 {
        wt_status_prepare(s);
+       init_diff_ui_defaults();
        git_config(fn, s);
        determine_whence(s);
-       init_diff_ui_defaults();
        s->hints = advice_status_hints; /* must come after git_config() */
 }
 
@@ -218,8 +228,7 @@ static int list_paths(struct string_list *list, const char *with_tree,
 
        if (with_tree) {
                char *max_prefix = common_prefix(pattern);
-               overlay_tree_on_index(&the_index, with_tree,
-                                     max_prefix ? max_prefix : prefix);
+               overlay_tree_on_index(&the_index, with_tree, max_prefix);
                free(max_prefix);
        }
 
@@ -496,7 +505,7 @@ static int is_a_merge(const struct commit *current_head)
 static void assert_split_ident(struct ident_split *id, const struct strbuf *buf)
 {
        if (split_ident_line(id, buf->buf, buf->len) || !id->date_begin)
-               die("BUG: unable to parse our own ident: %s", buf->buf);
+               BUG("unable to parse our own ident: %s", buf->buf);
 }
 
 static void export_one(const char *var, const char *s, const char *e, int hack)
@@ -1260,11 +1269,31 @@ static int git_status_config(const char *k, const char *v, void *cb)
                        return error(_("Invalid untracked files mode '%s'"), v);
                return 0;
        }
+       if (!strcmp(k, "diff.renamelimit")) {
+               if (s->rename_limit == -1)
+                       s->rename_limit = git_config_int(k, v);
+               return 0;
+       }
+       if (!strcmp(k, "status.renamelimit")) {
+               s->rename_limit = git_config_int(k, v);
+               return 0;
+       }
+       if (!strcmp(k, "diff.renames")) {
+               if (s->detect_rename == -1)
+                       s->detect_rename = git_config_rename(k, v);
+               return 0;
+       }
+       if (!strcmp(k, "status.renames")) {
+               s->detect_rename = git_config_rename(k, v);
+               return 0;
+       }
        return git_diff_ui_config(k, v, NULL);
 }
 
 int cmd_status(int argc, const char **argv, const char *prefix)
 {
+       static int no_renames = -1;
+       static const char *rename_score_arg = (const char *)-1;
        static struct wt_status s;
        int fd;
        struct object_id oid;
@@ -1298,6 +1327,10 @@ int cmd_status(int argc, const char **argv, const char *prefix)
                  N_("ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"),
                  PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
                OPT_COLUMN(0, "column", &s.colopts, N_("list untracked files in columns")),
+               OPT_BOOL(0, "no-renames", &no_renames, N_("do not detect renames")),
+               { OPTION_CALLBACK, 'M', "find-renames", &rename_score_arg,
+                 N_("n"), N_("detect renames, optionally set similarity index"),
+                 PARSE_OPT_OPTARG, opt_parse_rename_score },
                OPT_END(),
        };
 
@@ -1337,6 +1370,14 @@ int cmd_status(int argc, const char **argv, const char *prefix)
        s.ignore_submodule_arg = ignore_submodule_arg;
        s.status_format = status_format;
        s.verbose = verbose;
+       if (no_renames != -1)
+               s.detect_rename = !no_renames;
+       if ((intptr_t)rename_score_arg != -1) {
+               if (s.detect_rename < DIFF_DETECT_RENAME)
+                       s.detect_rename = DIFF_DETECT_RENAME;
+               if (rename_score_arg)
+                       s.rename_score = parse_rename_score(&rename_score_arg);
+       }
 
        wt_status_collect(&s);
 
index 01169dd628b24a7b5502550a6342ab73cb8154c5..b29d26dede79b9a5c46bdc4f951b22e7b88310b3 100644 (file)
@@ -25,7 +25,8 @@ static char term = '\n';
 
 static int use_global_config, use_system_config, use_local_config;
 static struct git_config_source given_config_source;
-static int actions, types;
+static int actions, type;
+static char *default_value;
 static int end_null;
 static int respect_includes_opt = -1;
 static struct config_options config_options;
@@ -55,11 +56,68 @@ static int show_origin;
 #define PAGING_ACTIONS (ACTION_LIST | ACTION_GET_ALL | \
                        ACTION_GET_REGEXP | ACTION_GET_URLMATCH)
 
-#define TYPE_BOOL (1<<0)
-#define TYPE_INT (1<<1)
-#define TYPE_BOOL_OR_INT (1<<2)
-#define TYPE_PATH (1<<3)
-#define TYPE_EXPIRY_DATE (1<<4)
+#define TYPE_BOOL              1
+#define TYPE_INT               2
+#define TYPE_BOOL_OR_INT       3
+#define TYPE_PATH              4
+#define TYPE_EXPIRY_DATE       5
+#define TYPE_COLOR             6
+
+#define OPT_CALLBACK_VALUE(s, l, v, h, i) \
+       { OPTION_CALLBACK, (s), (l), (v), NULL, (h), PARSE_OPT_NOARG | \
+       PARSE_OPT_NONEG, option_parse_type, (i) }
+
+static struct option builtin_config_options[];
+
+static int option_parse_type(const struct option *opt, const char *arg,
+                            int unset)
+{
+       int new_type, *to_type;
+
+       if (unset) {
+               *((int *) opt->value) = 0;
+               return 0;
+       }
+
+       /*
+        * To support '--<type>' style flags, begin with new_type equal to
+        * opt->defval.
+        */
+       new_type = opt->defval;
+       if (!new_type) {
+               if (!strcmp(arg, "bool"))
+                       new_type = TYPE_BOOL;
+               else if (!strcmp(arg, "int"))
+                       new_type = TYPE_INT;
+               else if (!strcmp(arg, "bool-or-int"))
+                       new_type = TYPE_BOOL_OR_INT;
+               else if (!strcmp(arg, "path"))
+                       new_type = TYPE_PATH;
+               else if (!strcmp(arg, "expiry-date"))
+                       new_type = TYPE_EXPIRY_DATE;
+               else if (!strcmp(arg, "color"))
+                       new_type = TYPE_COLOR;
+               else
+                       die(_("unrecognized --type argument, %s"), arg);
+       }
+
+       to_type = opt->value;
+       if (*to_type && *to_type != new_type) {
+               /*
+                * Complain when there is a new type not equal to the old type.
+                * This allows for combinations like '--int --type=int' and
+                * '--type=int --type=int', but disallows ones like '--type=bool
+                * --int' and '--type=bool
+                * --type=int'.
+                */
+               error("only one type at a time.");
+               usage_with_options(builtin_config_usage,
+                       builtin_config_options);
+       }
+       *to_type = new_type;
+
+       return 0;
+}
 
 static struct option builtin_config_options[] = {
        OPT_GROUP(N_("Config file location")),
@@ -84,16 +142,18 @@ static struct option builtin_config_options[] = {
        OPT_BIT(0, "get-color", &actions, N_("find the color configured: slot [default]"), ACTION_GET_COLOR),
        OPT_BIT(0, "get-colorbool", &actions, N_("find the color setting: slot [stdout-is-tty]"), ACTION_GET_COLORBOOL),
        OPT_GROUP(N_("Type")),
-       OPT_BIT(0, "bool", &types, N_("value is \"true\" or \"false\""), TYPE_BOOL),
-       OPT_BIT(0, "int", &types, N_("value is decimal number"), TYPE_INT),
-       OPT_BIT(0, "bool-or-int", &types, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
-       OPT_BIT(0, "path", &types, N_("value is a path (file or directory name)"), TYPE_PATH),
-       OPT_BIT(0, "expiry-date", &types, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
+       OPT_CALLBACK('t', "type", &type, "", N_("value is given this type"), option_parse_type),
+       OPT_CALLBACK_VALUE(0, "bool", &type, N_("value is \"true\" or \"false\""), TYPE_BOOL),
+       OPT_CALLBACK_VALUE(0, "int", &type, N_("value is decimal number"), TYPE_INT),
+       OPT_CALLBACK_VALUE(0, "bool-or-int", &type, N_("value is --bool or --int"), TYPE_BOOL_OR_INT),
+       OPT_CALLBACK_VALUE(0, "path", &type, N_("value is a path (file or directory name)"), TYPE_PATH),
+       OPT_CALLBACK_VALUE(0, "expiry-date", &type, N_("value is an expiry date"), TYPE_EXPIRY_DATE),
        OPT_GROUP(N_("Other")),
        OPT_BOOL('z', "null", &end_null, N_("terminate values with NUL byte")),
        OPT_BOOL(0, "name-only", &omit_values, N_("show variable names only")),
        OPT_BOOL(0, "includes", &respect_includes_opt, N_("respect include directives on lookup")),
        OPT_BOOL(0, "show-origin", &show_origin, N_("show origin of config (file, standard input, blob, command line)")),
+       OPT_STRING(0, "default", &default_value, N_("value"), N_("with --get, use default value when missing entry")),
        OPT_END(),
 };
 
@@ -149,30 +209,35 @@ static int format_config(struct strbuf *buf, const char *key_, const char *value
                if (show_keys)
                        strbuf_addch(buf, key_delim);
 
-               if (types == TYPE_INT)
+               if (type == TYPE_INT)
                        strbuf_addf(buf, "%"PRId64,
                                    git_config_int64(key_, value_ ? value_ : ""));
-               else if (types == TYPE_BOOL)
+               else if (type == TYPE_BOOL)
                        strbuf_addstr(buf, git_config_bool(key_, value_) ?
                                      "true" : "false");
-               else if (types == TYPE_BOOL_OR_INT) {
+               else if (type == TYPE_BOOL_OR_INT) {
                        int is_bool, v;
                        v = git_config_bool_or_int(key_, value_, &is_bool);
                        if (is_bool)
                                strbuf_addstr(buf, v ? "true" : "false");
                        else
                                strbuf_addf(buf, "%d", v);
-               } else if (types == TYPE_PATH) {
+               } else if (type == TYPE_PATH) {
                        const char *v;
                        if (git_config_pathname(&v, key_, value_) < 0)
                                return -1;
                        strbuf_addstr(buf, v);
                        free((char *)v);
-               } else if (types == TYPE_EXPIRY_DATE) {
+               } else if (type == TYPE_EXPIRY_DATE) {
                        timestamp_t t;
                        if (git_config_expiry_date(&t, key_, value_) < 0)
                                return -1;
                        strbuf_addf(buf, "%"PRItime, t);
+               } else if (type == TYPE_COLOR) {
+                       char v[COLOR_MAXLEN];
+                       if (git_config_color(v, key_, value_) < 0)
+                               return -1;
+                       strbuf_addstr(buf, v);
                } else if (value_) {
                        strbuf_addstr(buf, value_);
                } else {
@@ -258,6 +323,16 @@ static int get_value(const char *key_, const char *regex_)
        config_with_options(collect_config, &values,
                            &given_config_source, &config_options);
 
+       if (!values.nr && default_value) {
+               struct strbuf *item;
+               ALLOC_GROW(values.items, values.nr + 1, values.alloc);
+               item = &values.items[values.nr++];
+               strbuf_init(item, 0);
+               if (format_config(item, key_, default_value) < 0)
+                       die(_("failed to format default config value: %s"),
+                               default_value);
+       }
+
        ret = !values.nr;
 
        for (i = 0; i < values.nr; i++) {
@@ -287,7 +362,7 @@ static char *normalize_value(const char *key, const char *value)
        if (!value)
                return NULL;
 
-       if (types == 0 || types == TYPE_PATH || types == TYPE_EXPIRY_DATE)
+       if (type == 0 || type == TYPE_PATH || type == TYPE_EXPIRY_DATE)
                /*
                 * We don't do normalization for TYPE_PATH here: If
                 * the path is like ~/foobar/, we prefer to store
@@ -296,11 +371,11 @@ static char *normalize_value(const char *key, const char *value)
                 * Also don't do normalization for expiry dates.
                 */
                return xstrdup(value);
-       if (types == TYPE_INT)
+       if (type == TYPE_INT)
                return xstrfmt("%"PRId64, git_config_int64(key, value));
-       if (types == TYPE_BOOL)
+       if (type == TYPE_BOOL)
                return xstrdup(git_config_bool(key, value) ?  "true" : "false");
-       if (types == TYPE_BOOL_OR_INT) {
+       if (type == TYPE_BOOL_OR_INT) {
                int is_bool, v;
                v = git_config_bool_or_int(key, value, &is_bool);
                if (!is_bool)
@@ -308,8 +383,22 @@ static char *normalize_value(const char *key, const char *value)
                else
                        return xstrdup(v ? "true" : "false");
        }
+       if (type == TYPE_COLOR) {
+               char v[COLOR_MAXLEN];
+               if (git_config_color(v, key, value))
+                       die("cannot parse color '%s'", value);
 
-       die("BUG: cannot normalize type %d", types);
+               /*
+                * The contents of `v` now contain an ANSI escape
+                * sequence, not suitable for including within a
+                * configuration file. Treat the above as a
+                * "sanity-check", and return the given value, which we
+                * know is representable as valid color code.
+                */
+               return xstrdup(value);
+       }
+
+       BUG("cannot normalize type %d", type);
 }
 
 static int get_color_found;
@@ -513,6 +602,9 @@ int cmd_config(int argc, const char **argv, const char *prefix)
        if (use_local_config && nongit)
                die(_("--local can only be used inside a git repository"));
 
+       if (given_config_source.blob && nongit)
+               die(_("--blob can only be used inside a git repository"));
+
        if (given_config_source.file &&
                        !strcmp(given_config_source.file, "-")) {
                given_config_source.file = NULL;
@@ -566,12 +658,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                key_delim = '\n';
        }
 
-       if (HAS_MULTI_BITS(types)) {
-               error("only one type at a time.");
-               usage_with_options(builtin_config_usage, builtin_config_options);
-       }
-
-       if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && types) {
+       if ((actions & (ACTION_GET_COLOR|ACTION_GET_COLORBOOL)) && type) {
                error("--get-color and variable type are incoherent");
                usage_with_options(builtin_config_usage, builtin_config_options);
        }
@@ -601,6 +688,12 @@ int cmd_config(int argc, const char **argv, const char *prefix)
                usage_with_options(builtin_config_usage, builtin_config_options);
        }
 
+       if (default_value && !(actions & ACTION_GET)) {
+               error("--default is only applicable to --get");
+               usage_with_options(builtin_config_usage,
+                       builtin_config_options);
+       }
+
        if (actions & PAGING_ACTIONS)
                setup_auto_pager("config", 1);
 
index 33343818c830bf64452640b14b2ce7b876221022..d51e2ce1ec016ab35f1781675ff70793f0b974d5 100644 (file)
@@ -7,10 +7,12 @@
 #include "cache.h"
 #include "config.h"
 #include "dir.h"
+#include "repository.h"
 #include "builtin.h"
 #include "parse-options.h"
 #include "quote.h"
 #include "packfile.h"
+#include "object-store.h"
 
 static unsigned long garbage;
 static off_t size_garbage;
@@ -64,7 +66,7 @@ static int count_loose(const struct object_id *oid, const char *path, void *data
        else {
                loose_size += on_disk_bytes(st);
                loose++;
-               if (verbose && has_sha1_pack(oid->hash))
+               if (verbose && has_object_pack(oid))
                        packed_loose++;
        }
        return 0;
@@ -120,9 +122,8 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
                struct strbuf loose_buf = STRBUF_INIT;
                struct strbuf pack_buf = STRBUF_INIT;
                struct strbuf garbage_buf = STRBUF_INIT;
-               if (!packed_git)
-                       prepare_packed_git();
-               for (p = packed_git; p; p = p->next) {
+
+               for (p = get_packed_git(the_repository); p; p = p->next) {
                        if (!p->pack_local)
                                continue;
                        if (open_pack_index(p))
index e4869df7b434845544dfcc0c37cae6a77cd42dad..cf1ae77d7c705cdfb34bdb5403bad8db4148eccf 100644 (file)
@@ -6,7 +6,7 @@
 #include "blob.h"
 #include "refs.h"
 #include "builtin.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "parse-options.h"
 #include "revision.h"
 #include "diff.h"
@@ -285,7 +285,7 @@ static void append_name(struct commit_name *n, struct strbuf *dst)
 
 static void append_suffix(int depth, const struct object_id *oid, struct strbuf *dst)
 {
-       strbuf_addf(dst, "-%d-g%s", depth, find_unique_abbrev(oid->hash, abbrev));
+       strbuf_addf(dst, "-%d-g%s", depth, find_unique_abbrev(oid, abbrev));
 }
 
 static void describe_commit(struct object_id *oid, struct strbuf *dst)
@@ -383,7 +383,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
        if (!match_cnt) {
                struct object_id *cmit_oid = &cmit->object.oid;
                if (always) {
-                       strbuf_add_unique_abbrev(dst, cmit_oid->hash, abbrev);
+                       strbuf_add_unique_abbrev(dst, cmit_oid, abbrev);
                        if (suffix)
                                strbuf_addstr(dst, suffix);
                        return;
@@ -502,7 +502,7 @@ static void describe(const char *arg, int last_one)
 
        if (cmit)
                describe_commit(&oid, &sb);
-       else if (sha1_object_info(oid.hash, NULL) == OBJ_BLOB)
+       else if (oid_object_info(the_repository, &oid, NULL) == OBJ_BLOB)
                describe_blob(oid, &sb);
        else
                die(_("%s is neither a commit nor blob"), arg);
@@ -612,7 +612,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
                                suffix = broken;
                        }
                } else if (dirty) {
-                       static struct lock_file index_lock;
+                       struct lock_file index_lock = LOCK_INIT;
                        struct rev_info revs;
                        struct argv_array args = ARGV_ARRAY_INIT;
                        int fd, result;
index 16bfb22f7381ee8e6967ab836686c5def7cff892..bfefff3a84896a79fbed42eec1121286edcc86dd 100644 (file)
@@ -398,7 +398,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
                if (!obj)
                        die(_("invalid object '%s' given."), name);
                if (obj->type == OBJ_COMMIT)
-                       obj = &((struct commit *)obj)->tree->object;
+                       obj = &get_commit_tree(((struct commit *)obj))->object;
 
                if (obj->type == OBJ_TREE) {
                        obj->flags |= flags;
index bcc79d1888f2217bcb380ffb1e7178c100a41e8e..bc97d4aef2db2d76e3ffddfc4759e52688f3974e 100644 (file)
@@ -15,7 +15,7 @@
 #include "config.h"
 #include "builtin.h"
 #include "run-command.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "parse-options.h"
 #include "argv-array.h"
 #include "strbuf.h"
@@ -306,7 +306,7 @@ static char *get_symlink(const struct object_id *oid, const char *path)
        } else {
                enum object_type type;
                unsigned long size;
-               data = read_sha1_file(oid->hash, &type, &size);
+               data = read_object_file(oid, &type, &size);
                if (!data)
                        die(_("could not read object %s for symlink %s"),
                                oid_to_hex(oid), path);
@@ -610,7 +610,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
                        continue;
 
                if (!indices_loaded) {
-                       static struct lock_file lock;
+                       struct lock_file lock = LOCK_INIT;
                        strbuf_reset(&buf);
                        strbuf_addf(&buf, "%s/wtindex", tmpdir);
                        if (hold_lock_file_for_update(&lock, buf.buf, 0) < 0 ||
@@ -695,12 +695,11 @@ int cmd_difftool(int argc, const char **argv, const char *prefix)
                         N_("use `diff.guitool` instead of `diff.tool`")),
                OPT_BOOL('d', "dir-diff", &dir_diff,
                         N_("perform a full-directory diff")),
-               { OPTION_SET_INT, 'y', "no-prompt", &prompt, NULL,
+               OPT_SET_INT_F('y', "no-prompt", &prompt,
                        N_("do not prompt before launching a diff tool"),
-                       PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 0},
-               { OPTION_SET_INT, 0, "prompt", &prompt, NULL, NULL,
-                       PARSE_OPT_NOARG | PARSE_OPT_NONEG | PARSE_OPT_HIDDEN,
-                       NULL, 1 },
+                       0, PARSE_OPT_NONEG),
+               OPT_SET_INT_F(0, "prompt", &prompt, NULL,
+                       1, PARSE_OPT_NONEG | PARSE_OPT_HIDDEN),
                OPT_BOOL(0, "symlinks", &symlinks,
                         N_("use symlinks in dir-diff mode")),
                OPT_STRING('t', "tool", &difftool_cmd, N_("<tool>"),
index 27b2cc138e67c013adbee3cbe152ca48c3d82ff5..6c9768742fd4faecb3719e9c87997df3d490502a 100644 (file)
@@ -7,6 +7,7 @@
 #include "cache.h"
 #include "config.h"
 #include "refs.h"
+#include "refspec.h"
 #include "commit.h"
 #include "object.h"
 #include "tag.h"
@@ -35,8 +36,7 @@ static int use_done_feature;
 static int no_data;
 static int full_tree;
 static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
-static struct refspec *refspecs;
-static int refspecs_nr;
+static struct refspec refspecs = REFSPEC_INIT_FETCH;
 static int anonymize;
 
 static int parse_opt_signed_tag_mode(const struct option *opt,
@@ -156,15 +156,14 @@ static void anonymize_path(struct strbuf *out, const char *path,
        }
 }
 
-/* Since intptr_t is C99, we do not use it here */
-static inline uint32_t *mark_to_ptr(uint32_t mark)
+static inline void *mark_to_ptr(uint32_t mark)
 {
-       return ((uint32_t *)NULL) + mark;
+       return (void *)(uintptr_t)mark;
 }
 
 static inline uint32_t ptr_to_mark(void * mark)
 {
-       return (uint32_t *)mark - (uint32_t *)NULL;
+       return (uint32_t)(uintptr_t)mark;
 }
 
 static inline void mark_object(struct object *object, uint32_t mark)
@@ -237,10 +236,10 @@ static void export_blob(const struct object_id *oid)
                object = (struct object *)lookup_blob(oid);
                eaten = 0;
        } else {
-               buf = read_sha1_file(oid->hash, &type, &size);
+               buf = read_object_file(oid, &type, &size);
                if (!buf)
                        die ("Could not read blob %s", oid_to_hex(oid));
-               if (check_sha1_signature(oid->hash, buf, size, type_name(type)) < 0)
+               if (check_object_signature(oid, buf, size, type_name(type)) < 0)
                        die("sha1 mismatch in blob %s", oid_to_hex(oid));
                object = parse_object_buffer(oid, type, size, buf, &eaten);
        }
@@ -517,7 +516,7 @@ static void anonymize_ident_line(const char **beg, const char **end)
        /* skip "committer", "author", "tagger", etc */
        end_of_header = strchr(*beg, ' ');
        if (!end_of_header)
-               die("BUG: malformed line fed to anonymize_ident_line: %.*s",
+               BUG("malformed line fed to anonymize_ident_line: %.*s",
                    (int)(*end - *beg), *beg);
        end_of_header++;
        strbuf_add(out, *beg, end_of_header - *beg);
@@ -578,11 +577,11 @@ static void handle_commit(struct commit *commit, struct rev_info *rev,
            get_object_mark(&commit->parents->item->object) != 0 &&
            !full_tree) {
                parse_commit_or_die(commit->parents->item);
-               diff_tree_oid(&commit->parents->item->tree->object.oid,
-                             &commit->tree->object.oid, "", &rev->diffopt);
+               diff_tree_oid(get_commit_tree_oid(commit->parents->item),
+                             get_commit_tree_oid(commit), "", &rev->diffopt);
        }
        else
-               diff_root_tree_oid(&commit->tree->object.oid,
+               diff_root_tree_oid(get_commit_tree_oid(commit),
                                   "", &rev->diffopt);
 
        /* Export the referenced blobs, and remember the marks. */
@@ -651,8 +650,11 @@ static void handle_tail(struct object_array *commits, struct rev_info *revs,
        struct commit *commit;
        while (commits->nr) {
                commit = (struct commit *)object_array_pop(commits);
-               if (has_unshown_parent(commit))
+               if (has_unshown_parent(commit)) {
+                       /* Queue again, to be handled later */
+                       add_object_array(&commit->object, NULL, commits);
                        return;
+               }
                handle_commit(commit, revs, paths_of_changed_objects);
        }
 }
@@ -682,7 +684,7 @@ static void handle_tag(const char *name, struct tag *tag)
                return;
        }
 
-       buf = read_sha1_file(tag->object.oid.hash, &type, &size);
+       buf = read_object_file(&tag->object.oid, &type, &size);
        if (!buf)
                die ("Could not read tag %s", oid_to_hex(&tag->object.oid));
        message = memmem(buf, size, "\n\n", 2);
@@ -826,9 +828,9 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
                if (dwim_ref(e->name, strlen(e->name), &oid, &full_name) != 1)
                        continue;
 
-               if (refspecs) {
+               if (refspecs.nr) {
                        char *private;
-                       private = apply_refspecs(refspecs, refspecs_nr, full_name);
+                       private = apply_refspecs(&refspecs, full_name);
                        if (private) {
                                free(full_name);
                                full_name = private;
@@ -947,7 +949,7 @@ static void import_marks(char *input_file)
                if (last_idnum < mark)
                        last_idnum = mark;
 
-               type = sha1_object_info(oid.hash, NULL);
+               type = oid_object_info(the_repository, &oid, NULL);
                if (type < 0)
                        die("object not found: %s", oid_to_hex(&oid));
 
@@ -974,8 +976,8 @@ static void import_marks(char *input_file)
 static void handle_deletes(void)
 {
        int i;
-       for (i = 0; i < refspecs_nr; i++) {
-               struct refspec *refspec = &refspecs[i];
+       for (i = 0; i < refspecs.nr; i++) {
+               struct refspec_item *refspec = &refspecs.items[i];
                if (*refspec->src)
                        continue;
 
@@ -1036,18 +1038,12 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
                usage_with_options (fast_export_usage, options);
 
        if (refspecs_list.nr) {
-               const char **refspecs_str;
                int i;
 
-               ALLOC_ARRAY(refspecs_str, refspecs_list.nr);
                for (i = 0; i < refspecs_list.nr; i++)
-                       refspecs_str[i] = refspecs_list.items[i].string;
-
-               refspecs_nr = refspecs_list.nr;
-               refspecs = parse_fetch_refspec(refspecs_nr, refspecs_str);
+                       refspec_append(&refspecs, refspecs_list.items[i].string);
 
                string_list_clear(&refspecs_list, 1);
-               free(refspecs_str);
        }
 
        if (use_done_feature)
@@ -1086,7 +1082,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
        if (use_done_feature)
                printf("done\n");
 
-       free_refspec(refspecs_nr, refspecs);
+       refspec_clear(&refspecs);
 
        return 0;
 }
index a7bc1366ab375765c41014640743ef9d77c84c42..1a1bc63566b44bc83c8429463104615d1b2117ff 100644 (file)
@@ -4,6 +4,7 @@
 #include "remote.h"
 #include "connect.h"
 #include "sha1-array.h"
+#include "protocol.h"
 
 static const char fetch_pack_usage[] =
 "git fetch-pack [--all] [--stdin] [--quiet | -q] [--keep | -k] [--thin] "
@@ -52,6 +53,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
        struct fetch_pack_args args;
        struct oid_array shallow = OID_ARRAY_INIT;
        struct string_list deepen_not = STRING_LIST_INIT_DUP;
+       struct packet_reader reader;
 
        fetch_if_missing = 0;
 
@@ -211,10 +213,24 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix)
                if (!conn)
                        return args.diag_url ? 0 : 1;
        }
-       get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL, &shallow);
+
+       packet_reader_init(&reader, fd[0], NULL, 0,
+                          PACKET_READ_CHOMP_NEWLINE |
+                          PACKET_READ_GENTLE_ON_EOF);
+
+       switch (discover_version(&reader)) {
+       case protocol_v2:
+               die("support for protocol v2 not implemented yet");
+       case protocol_v1:
+       case protocol_v0:
+               get_remote_heads(&reader, &ref, 0, NULL, &shallow);
+               break;
+       case protocol_unknown_version:
+               BUG("unknown protocol version");
+       }
 
        ref = fetch_pack(&args, fd, conn, ref, dest, sought, nr_sought,
-                        &shallow, pack_lockfile_ptr);
+                        &shallow, pack_lockfile_ptr, protocol_v0);
        if (pack_lockfile) {
                printf("lock %s\n", pack_lockfile);
                fflush(stdout);
index 6d73656a486fed1afd031e6cf5e26e1c2039e0cb..ea5b9669ad1f40da56a8565cada56e5991d24206 100644 (file)
@@ -5,6 +5,7 @@
 #include "config.h"
 #include "repository.h"
 #include "refs.h"
+#include "refspec.h"
 #include "commit.h"
 #include "builtin.h"
 #include "string-list.h"
@@ -59,9 +60,9 @@ static const char *submodule_prefix = "";
 static int recurse_submodules = RECURSE_SUBMODULES_DEFAULT;
 static int recurse_submodules_default = RECURSE_SUBMODULES_ON_DEMAND;
 static int shown_url = 0;
-static int refmap_alloc, refmap_nr;
-static const char **refmap_array;
+static struct refspec refmap = REFSPEC_INIT_FETCH;
 static struct list_objects_filter_options filter_options;
+static struct string_list server_options = STRING_LIST_INIT_DUP;
 
 static int git_fetch_config(const char *k, const char *v, void *cb)
 {
@@ -107,14 +108,12 @@ static int gitmodules_fetch_config(const char *var, const char *value, void *cb)
 
 static int parse_refmap_arg(const struct option *opt, const char *arg, int unset)
 {
-       ALLOC_GROW(refmap_array, refmap_nr + 1, refmap_alloc);
-
        /*
         * "git fetch --refmap='' origin foo"
         * can be used to tell the command not to store anywhere
         */
-       if (*arg)
-               refmap_array[refmap_nr++] = arg;
+       refspec_append(&refmap, arg);
+
        return 0;
 }
 
@@ -156,9 +155,9 @@ static struct option builtin_fetch_options[] = {
                        N_("deepen history of shallow clone, excluding rev")),
        OPT_INTEGER(0, "deepen", &deepen_relative,
                    N_("deepen history of shallow clone")),
-       { OPTION_SET_INT, 0, "unshallow", &unshallow, NULL,
-                  N_("convert to a complete repository"),
-                  PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1 },
+       OPT_SET_INT_F(0, "unshallow", &unshallow,
+                     N_("convert to a complete repository"),
+                     1, PARSE_OPT_NONEG),
        { OPTION_STRING, 0, "submodule-prefix", &submodule_prefix, N_("dir"),
                   N_("prepend this to submodule path output"), PARSE_OPT_HIDDEN },
        { OPTION_CALLBACK, 0, "recurse-submodules-default",
@@ -170,6 +169,7 @@ static struct option builtin_fetch_options[] = {
                 N_("accept refs that update .git/shallow")),
        { OPTION_CALLBACK, 0, "refmap", NULL, N_("refmap"),
          N_("specify fetch refmap"), PARSE_OPT_NONEG, parse_refmap_arg },
+       OPT_STRING_LIST('o', "server-option", &server_options, N_("server-specific"), N_("option to transmit")),
        OPT_SET_INT('4', "ipv4", &family, N_("use IPv4 addresses only"),
                        TRANSPORT_FAMILY_IPV4),
        OPT_SET_INT('6', "ipv6", &family, N_("use IPv6 addresses only"),
@@ -202,7 +202,7 @@ static void add_merge_config(struct ref **head,
 
        for (i = 0; i < branch->merge_nr; i++) {
                struct ref *rm, **old_tail = *tail;
-               struct refspec refspec;
+               struct refspec_item refspec;
 
                for (rm = *head; rm; rm = rm->next) {
                        if (branch_merge_matches(branch, i, rm->name)) {
@@ -264,7 +264,7 @@ static void find_non_local_tags(struct transport *transport,
        struct string_list_item *item = NULL;
 
        for_each_ref(add_existing, &existing_refs);
-       for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
+       for (ref = transport_get_remote_refs(transport, NULL); ref; ref = ref->next) {
                if (!starts_with(ref->name, "refs/tags/"))
                        continue;
 
@@ -339,26 +339,40 @@ static void find_non_local_tags(struct transport *transport,
 }
 
 static struct ref *get_ref_map(struct transport *transport,
-                              struct refspec *refspecs, int refspec_count,
+                              struct refspec *rs,
                               int tags, int *autotags)
 {
        int i;
        struct ref *rm;
        struct ref *ref_map = NULL;
        struct ref **tail = &ref_map;
+       struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
 
        /* opportunistically-updated references: */
        struct ref *orefs = NULL, **oref_tail = &orefs;
 
-       const struct ref *remote_refs = transport_get_remote_refs(transport);
+       const struct ref *remote_refs;
+
+       if (rs->nr)
+               refspec_ref_prefixes(rs, &ref_prefixes);
+       else if (transport->remote && transport->remote->fetch.nr)
+               refspec_ref_prefixes(&transport->remote->fetch, &ref_prefixes);
+
+       if (ref_prefixes.argc &&
+           (tags == TAGS_SET || (tags == TAGS_DEFAULT && !rs->nr))) {
+               argv_array_push(&ref_prefixes, "refs/tags/");
+       }
+
+       remote_refs = transport_get_remote_refs(transport, &ref_prefixes);
 
-       if (refspec_count) {
+       argv_array_clear(&ref_prefixes);
+
+       if (rs->nr) {
                struct refspec *fetch_refspec;
-               int fetch_refspec_nr;
 
-               for (i = 0; i < refspec_count; i++) {
-                       get_fetch_map(remote_refs, &refspecs[i], &tail, 0);
-                       if (refspecs[i].dst && refspecs[i].dst[0])
+               for (i = 0; i < rs->nr; i++) {
+                       get_fetch_map(remote_refs, &rs->items[i], &tail, 0);
+                       if (rs->items[i].dst && rs->items[i].dst[0])
                                *autotags = 1;
                }
                /* Merge everything on the command line (but not --tags) */
@@ -385,17 +399,14 @@ static struct ref *get_ref_map(struct transport *transport,
                 * by ref_remove_duplicates() in favor of one of these
                 * opportunistic entries with FETCH_HEAD_IGNORE.
                 */
-               if (refmap_array) {
-                       fetch_refspec = parse_fetch_refspec(refmap_nr, refmap_array);
-                       fetch_refspec_nr = refmap_nr;
-               } else {
-                       fetch_refspec = transport->remote->fetch;
-                       fetch_refspec_nr = transport->remote->fetch_refspec_nr;
-               }
+               if (refmap.nr)
+                       fetch_refspec = &refmap;
+               else
+                       fetch_refspec = &transport->remote->fetch;
 
-               for (i = 0; i < fetch_refspec_nr; i++)
-                       get_fetch_map(ref_map, &fetch_refspec[i], &oref_tail, 1);
-       } else if (refmap_array) {
+               for (i = 0; i < fetch_refspec->nr; i++)
+                       get_fetch_map(ref_map, &fetch_refspec->items[i], &oref_tail, 1);
+       } else if (refmap.nr) {
                die("--refmap option is only meaningful with command-line refspec(s).");
        } else {
                /* Use the defaults */
@@ -403,16 +414,16 @@ static struct ref *get_ref_map(struct transport *transport,
                struct branch *branch = branch_get(NULL);
                int has_merge = branch_has_merge_config(branch);
                if (remote &&
-                   (remote->fetch_refspec_nr ||
+                   (remote->fetch.nr ||
                     /* Note: has_merge implies non-NULL branch->remote_name */
                     (has_merge && !strcmp(branch->remote_name, remote->name)))) {
-                       for (i = 0; i < remote->fetch_refspec_nr; i++) {
-                               get_fetch_map(remote_refs, &remote->fetch[i], &tail, 0);
-                               if (remote->fetch[i].dst &&
-                                   remote->fetch[i].dst[0])
+                       for (i = 0; i < remote->fetch.nr; i++) {
+                               get_fetch_map(remote_refs, &remote->fetch.items[i], &tail, 0);
+                               if (remote->fetch.items[i].dst &&
+                                   remote->fetch.items[i].dst[0])
                                        *autotags = 1;
                                if (!i && !has_merge && ref_map &&
-                                   !remote->fetch[0].pattern)
+                                   !remote->fetch.items[0].pattern)
                                        ref_map->fetch_head_status = FETCH_HEAD_MERGE;
                        }
                        /*
@@ -637,7 +648,7 @@ static int update_local_ref(struct ref *ref,
        struct branch *current_branch = branch_get(NULL);
        const char *pretty_ref = prettify_refname(ref->name);
 
-       type = sha1_object_info(ref->new_oid.hash, NULL);
+       type = oid_object_info(the_repository, &ref->new_oid, NULL);
        if (type < 0)
                die(_("object %s not found"), oid_to_hex(&ref->new_oid));
 
@@ -708,9 +719,9 @@ static int update_local_ref(struct ref *ref,
        if (in_merge_bases(current, updated)) {
                struct strbuf quickref = STRBUF_INIT;
                int r;
-               strbuf_add_unique_abbrev(&quickref, current->object.oid.hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
                strbuf_addstr(&quickref, "..");
-               strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
                if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
                    (recurse_submodules != RECURSE_SUBMODULES_ON))
                        check_for_new_submodule_commits(&ref->new_oid);
@@ -723,9 +734,9 @@ static int update_local_ref(struct ref *ref,
        } else if (force || ref->force) {
                struct strbuf quickref = STRBUF_INIT;
                int r;
-               strbuf_add_unique_abbrev(&quickref, current->object.oid.hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&quickref, &current->object.oid, DEFAULT_ABBREV);
                strbuf_addstr(&quickref, "...");
-               strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&quickref, &ref->new_oid, DEFAULT_ABBREV);
                if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
                    (recurse_submodules != RECURSE_SUBMODULES_ON))
                        check_for_new_submodule_commits(&ref->new_oid);
@@ -947,11 +958,11 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
        return ret;
 }
 
-static int prune_refs(struct refspec *refs, int ref_count, struct ref *ref_map,
-               const char *raw_url)
+static int prune_refs(struct refspec *rs, struct ref *ref_map,
+                     const char *raw_url)
 {
        int url_len, i, result = 0;
-       struct ref *ref, *stale_refs = get_stale_heads(refs, ref_count, ref_map);
+       struct ref *ref, *stale_refs = get_stale_heads(rs, ref_map);
        char *url;
        int summary_width = transport_summary_width(stale_refs);
        const char *dangling_msg = dry_run
@@ -1097,7 +1108,7 @@ static void backfill_tags(struct transport *transport, struct ref *ref_map)
 }
 
 static int do_fetch(struct transport *transport,
-                   struct refspec *refs, int ref_count)
+                   struct refspec *rs)
 {
        struct string_list existing_refs = STRING_LIST_INIT_DUP;
        struct ref *ref_map;
@@ -1121,7 +1132,7 @@ static int do_fetch(struct transport *transport,
                        goto cleanup;
        }
 
-       ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags);
+       ref_map = get_ref_map(transport, rs, tags, &autotags);
        if (!update_head_ok)
                check_not_current_branch(ref_map);
 
@@ -1145,11 +1156,10 @@ static int do_fetch(struct transport *transport,
                 * explicitly (via command line or configuration); we
                 * don't care whether --tags was specified.
                 */
-               if (ref_count) {
-                       prune_refs(refs, ref_count, ref_map, transport->url);
+               if (rs->nr) {
+                       prune_refs(rs, ref_map, transport->url);
                } else {
-                       prune_refs(transport->remote->fetch,
-                                  transport->remote->fetch_refspec_nr,
+                       prune_refs(&transport->remote->fetch,
                                   ref_map,
                                   transport->url);
                }
@@ -1338,10 +1348,8 @@ static inline void fetch_one_setup_partial(struct remote *remote)
 
 static int fetch_one(struct remote *remote, int argc, const char **argv, int prune_tags_ok)
 {
-       static const char **refs = NULL;
-       struct refspec *refspec;
-       int ref_nr = 0;
-       int j = 0;
+       struct refspec rs = REFSPEC_INIT_FETCH;
+       int i;
        int exit_code;
        int maybe_prune_tags;
        int remote_via_config = remote_is_configured(remote, 0);
@@ -1374,37 +1382,34 @@ static int fetch_one(struct remote *remote, int argc, const char **argv, int pru
 
        maybe_prune_tags = prune_tags_ok && prune_tags;
        if (maybe_prune_tags && remote_via_config)
-               add_prune_tags_to_fetch_refspec(remote);
-
-       if (argc > 0 || (maybe_prune_tags && !remote_via_config)) {
-               size_t nr_alloc = st_add3(argc, maybe_prune_tags, 1);
-               refs = xcalloc(nr_alloc, sizeof(const char *));
-               if (maybe_prune_tags) {
-                       refs[j++] = xstrdup("refs/tags/*:refs/tags/*");
-                       ref_nr++;
+               refspec_append(&remote->fetch, TAG_REFSPEC);
+
+       if (maybe_prune_tags && (argc || !remote_via_config))
+               refspec_append(&rs, TAG_REFSPEC);
+
+       for (i = 0; i < argc; i++) {
+               if (!strcmp(argv[i], "tag")) {
+                       char *tag;
+                       i++;
+                       if (i >= argc)
+                               die(_("You need to specify a tag name."));
+
+                       tag = xstrfmt("refs/tags/%s:refs/tags/%s",
+                                     argv[i], argv[i]);
+                       refspec_append(&rs, tag);
+                       free(tag);
+               } else {
+                       refspec_append(&rs, argv[i]);
                }
        }
 
-       if (argc > 0) {
-               int i;
-               for (i = 0; i < argc; i++) {
-                       if (!strcmp(argv[i], "tag")) {
-                               i++;
-                               if (i >= argc)
-                                       die(_("You need to specify a tag name."));
-                               refs[j++] = xstrfmt("refs/tags/%s:refs/tags/%s",
-                                                   argv[i], argv[i]);
-                       } else
-                               refs[j++] = argv[i];
-                       ref_nr++;
-               }
-       }
+       if (server_options.nr)
+               gtransport->server_options = &server_options;
 
        sigchain_push_common(unlock_pack_on_signal);
        atexit(unlock_pack);
-       refspec = parse_fetch_refspec(ref_nr, refs);
-       exit_code = do_fetch(gtransport, refspec, ref_nr);
-       free_refspec(ref_nr, refspec);
+       exit_code = do_fetch(gtransport, &rs);
+       refspec_clear(&rs);
        transport_disconnect(gtransport);
        gtransport = NULL;
        return exit_code;
@@ -1516,7 +1521,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
 
        string_list_clear(&list, 0);
 
-       close_all_packs();
+       close_all_packs(the_repository->objects);
 
        argv_array_pushl(&argv_gc_auto, "gc", "--auto", NULL);
        if (verbosity < 0)
index 8e8a15ea4ad6de2bb73f63d39a0895a263918774..bd680be6874da29cf776c84468a60888beea53fb 100644 (file)
@@ -485,10 +485,10 @@ static void fmt_merge_msg_sigs(struct strbuf *out)
        struct strbuf tagbuf = STRBUF_INIT;
 
        for (i = 0; i < origins.nr; i++) {
-               unsigned char *sha1 = origins.items[i].util;
+               struct object_id *oid = origins.items[i].util;
                enum object_type type;
                unsigned long size, len;
-               char *buf = read_sha1_file(sha1, &type, &size);
+               char *buf = read_object_file(oid, &type, &size);
                struct strbuf sig = STRBUF_INIT;
 
                if (!buf || type != OBJ_TAG)
index 028aba52ebaab764d1f4f91c926e54d66dcaa20f..3ad4f160f9959a30262c81d5c3f85c36649d2895 100644 (file)
@@ -1,5 +1,6 @@
 #include "builtin.h"
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "commit.h"
 #include "tree.h"
@@ -16,6 +17,7 @@
 #include "streaming.h"
 #include "decorate.h"
 #include "packfile.h"
+#include "object-store.h"
 
 #define REACHABLE 0x0001
 #define SEEN      0x0002
@@ -65,7 +67,8 @@ static const char *printable_type(struct object *obj)
        const char *ret;
 
        if (obj->type == OBJ_NONE) {
-               enum object_type type = sha1_object_info(obj->oid.hash, NULL);
+               enum object_type type = oid_object_info(the_repository,
+                                                       &obj->oid, NULL);
                if (type > 0)
                        object_as_type(obj, type, 0);
        }
@@ -225,7 +228,7 @@ static void check_reachable_object(struct object *obj)
        if (!(obj->flags & HAS_OBJ)) {
                if (is_promisor_object(&obj->oid))
                        return;
-               if (has_sha1_pack(obj->oid.hash))
+               if (has_object_pack(&obj->oid))
                        return; /* it is in pack - forget about it */
                printf("missing %s %s\n", printable_type(obj),
                        describe_object(obj));
@@ -512,7 +515,7 @@ static int fsck_loose(const struct object_id *oid, const char *path, void *data)
        void *contents;
        int eaten;
 
-       if (read_loose_object(path, oid->hash, &type, &size, &contents) < 0) {
+       if (read_loose_object(path, oid, &type, &size, &contents) < 0) {
                errors_found |= ERROR_OBJECT;
                error("%s: object corrupt or missing: %s",
                      oid_to_hex(oid), path);
@@ -717,9 +720,12 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
                for_each_loose_object(mark_loose_for_connectivity, NULL, 0);
                for_each_packed_object(mark_packed_for_connectivity, NULL, 0);
        } else {
+               struct alternate_object_database *alt_odb_list;
+
                fsck_object_dir(get_object_directory());
 
-               prepare_alt_odb();
+               prepare_alt_odb(the_repository);
+               alt_odb_list = the_repository->objects->alt_odb_list;
                for (alt = alt_odb_list; alt; alt = alt->next)
                        fsck_object_dir(alt->path);
 
@@ -728,10 +734,9 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
                        uint32_t total = 0, count = 0;
                        struct progress *progress = NULL;
 
-                       prepare_packed_git();
-
                        if (show_progress) {
-                               for (p = packed_git; p; p = p->next) {
+                               for (p = get_packed_git(the_repository); p;
+                                    p = p->next) {
                                        if (open_pack_index(p))
                                                continue;
                                        total += p->num_objects;
@@ -739,7 +744,8 @@ int cmd_fsck(int argc, const char **argv, const char *prefix)
 
                                progress = start_progress(_("Checking objects"), total);
                        }
-                       for (p = packed_git; p; p = p->next) {
+                       for (p = get_packed_git(the_repository); p;
+                            p = p->next) {
                                /* verify gives error messages itself */
                                if (verify_pack(p, fsck_obj_buffer,
                                                progress, count))
index f51e5a6500fc294cb719716671259de42f31bfe7..ccfb1ceaeb3eb9c6a8cbe9297bceac94fa54bcac 100644 (file)
@@ -11,6 +11,7 @@
  */
 
 #include "builtin.h"
+#include "repository.h"
 #include "config.h"
 #include "tempfile.h"
 #include "lockfile.h"
 #include "argv-array.h"
 #include "commit.h"
 #include "packfile.h"
+#include "object-store.h"
+#include "pack.h"
+#include "pack-objects.h"
+#include "blob.h"
+#include "tree.h"
 
 #define FAILED_RUN "failed to run %s"
 
@@ -39,6 +45,8 @@ static timestamp_t gc_log_expire_time;
 static const char *gc_log_expire = "1.day.ago";
 static const char *prune_expire = "2.weeks.ago";
 static const char *prune_worktrees_expire = "3.months.ago";
+static unsigned long big_pack_threshold;
+static unsigned long max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE;
 
 static struct argv_array pack_refs_cmd = ARGV_ARRAY_INIT;
 static struct argv_array reflog = ARGV_ARRAY_INIT;
@@ -126,6 +134,9 @@ static void gc_config(void)
        git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
        git_config_get_expiry("gc.logexpiry", &gc_log_expire);
 
+       git_config_get_ulong("gc.bigpackthreshold", &big_pack_threshold);
+       git_config_get_ulong("pack.deltacachesize", &max_delta_cache_size);
+
        git_config(git_default_config, NULL);
 }
 
@@ -164,6 +175,28 @@ static int too_many_loose_objects(void)
        return needed;
 }
 
+static struct packed_git *find_base_packs(struct string_list *packs,
+                                         unsigned long limit)
+{
+       struct packed_git *p, *base = NULL;
+
+       for (p = get_packed_git(the_repository); p; p = p->next) {
+               if (!p->pack_local)
+                       continue;
+               if (limit) {
+                       if (p->pack_size >= limit)
+                               string_list_append(packs, p->pack_name);
+               } else if (!base || base->pack_size < p->pack_size) {
+                       base = p;
+               }
+       }
+
+       if (base)
+               string_list_append(packs, base->pack_name);
+
+       return base;
+}
+
 static int too_many_packs(void)
 {
        struct packed_git *p;
@@ -172,8 +205,7 @@ static int too_many_packs(void)
        if (gc_auto_pack_limit <= 0)
                return 0;
 
-       prepare_packed_git();
-       for (cnt = 0, p = packed_git; p; p = p->next) {
+       for (cnt = 0, p = get_packed_git(the_repository); p; p = p->next) {
                if (!p->pack_local)
                        continue;
                if (p->pack_keep)
@@ -187,7 +219,86 @@ static int too_many_packs(void)
        return gc_auto_pack_limit < cnt;
 }
 
-static void add_repack_all_option(void)
+static uint64_t total_ram(void)
+{
+#if defined(HAVE_SYSINFO)
+       struct sysinfo si;
+
+       if (!sysinfo(&si))
+               return si.totalram;
+#elif defined(HAVE_BSD_SYSCTL) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM))
+       int64_t physical_memory;
+       int mib[2];
+       size_t length;
+
+       mib[0] = CTL_HW;
+# if defined(HW_MEMSIZE)
+       mib[1] = HW_MEMSIZE;
+# else
+       mib[1] = HW_PHYSMEM;
+# endif
+       length = sizeof(int64_t);
+       if (!sysctl(mib, 2, &physical_memory, &length, NULL, 0))
+               return physical_memory;
+#elif defined(GIT_WINDOWS_NATIVE)
+       MEMORYSTATUSEX memInfo;
+
+       memInfo.dwLength = sizeof(MEMORYSTATUSEX);
+       if (GlobalMemoryStatusEx(&memInfo))
+               return memInfo.ullTotalPhys;
+#endif
+       return 0;
+}
+
+static uint64_t estimate_repack_memory(struct packed_git *pack)
+{
+       unsigned long nr_objects = approximate_object_count();
+       size_t os_cache, heap;
+
+       if (!pack || !nr_objects)
+               return 0;
+
+       /*
+        * First we have to scan through at least one pack.
+        * Assume enough room in OS file cache to keep the entire pack
+        * or we may accidentally evict data of other processes from
+        * the cache.
+        */
+       os_cache = pack->pack_size + pack->index_size;
+       /* then pack-objects needs lots more for book keeping */
+       heap = sizeof(struct object_entry) * nr_objects;
+       /*
+        * internal rev-list --all --objects takes up some memory too,
+        * let's say half of it is for blobs
+        */
+       heap += sizeof(struct blob) * nr_objects / 2;
+       /*
+        * and the other half is for trees (commits and tags are
+        * usually insignificant)
+        */
+       heap += sizeof(struct tree) * nr_objects / 2;
+       /* and then obj_hash[], underestimated in fact */
+       heap += sizeof(struct object *) * nr_objects;
+       /* revindex is used also */
+       heap += sizeof(struct revindex_entry) * nr_objects;
+       /*
+        * read_sha1_file() (either at delta calculation phase, or
+        * writing phase) also fills up the delta base cache
+        */
+       heap += delta_base_cache_limit;
+       /* and of course pack-objects has its own delta cache */
+       heap += max_delta_cache_size;
+
+       return os_cache + heap;
+}
+
+static int keep_one_pack(struct string_list_item *item, void *data)
+{
+       argv_array_pushf(&repack, "--keep-pack=%s", basename(item->string));
+       return 0;
+}
+
+static void add_repack_all_option(struct string_list *keep_pack)
 {
        if (prune_expire && !strcmp(prune_expire, "now"))
                argv_array_push(&repack, "-a");
@@ -196,6 +307,9 @@ static void add_repack_all_option(void)
                if (prune_expire)
                        argv_array_pushf(&repack, "--unpack-unreachable=%s", prune_expire);
        }
+
+       if (keep_pack)
+               for_each_string_list(keep_pack, keep_one_pack, NULL);
 }
 
 static void add_repack_incremental_option(void)
@@ -218,9 +332,35 @@ static int need_to_gc(void)
         * we run "repack -A -d -l".  Otherwise we tell the caller
         * there is no need.
         */
-       if (too_many_packs())
-               add_repack_all_option();
-       else if (too_many_loose_objects())
+       if (too_many_packs()) {
+               struct string_list keep_pack = STRING_LIST_INIT_NODUP;
+
+               if (big_pack_threshold) {
+                       find_base_packs(&keep_pack, big_pack_threshold);
+                       if (keep_pack.nr >= gc_auto_pack_limit) {
+                               big_pack_threshold = 0;
+                               string_list_clear(&keep_pack, 0);
+                               find_base_packs(&keep_pack, 0);
+                       }
+               } else {
+                       struct packed_git *p = find_base_packs(&keep_pack, 0);
+                       uint64_t mem_have, mem_want;
+
+                       mem_have = total_ram();
+                       mem_want = estimate_repack_memory(p);
+
+                       /*
+                        * Only allow 1/2 of memory for pack-objects, leave
+                        * the rest for the OS and other processes in the
+                        * system.
+                        */
+                       if (!mem_have || mem_want < mem_have / 2)
+                               string_list_clear(&keep_pack, 0);
+               }
+
+               add_repack_all_option(&keep_pack);
+               string_list_clear(&keep_pack, 0);
+       } else if (too_many_loose_objects())
                add_repack_incremental_option();
        else
                return 0;
@@ -233,7 +373,7 @@ static int need_to_gc(void)
 /* return NULL on success, else hostname running the gc */
 static const char *lock_repo_for_gc(int force, pid_t* ret_pid)
 {
-       static struct lock_file lock;
+       struct lock_file lock = LOCK_INIT;
        char my_host[HOST_NAME_MAX + 1];
        struct strbuf sb = STRBUF_INIT;
        struct stat st;
@@ -353,6 +493,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
        const char *name;
        pid_t pid;
        int daemonized = 0;
+       int keep_base_pack = -1;
+       timestamp_t dummy;
 
        struct option builtin_gc_options[] = {
                OPT__QUIET(&quiet, N_("suppress progress reporting")),
@@ -365,6 +507,8 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                OPT_BOOL_F(0, "force", &force,
                           N_("force running gc even if there may be another gc running"),
                           PARSE_OPT_NOCOMPLETE),
+               OPT_BOOL(0, "keep-largest-pack", &keep_base_pack,
+                        N_("repack all other packs except the largest pack")),
                OPT_END()
        };
 
@@ -381,7 +525,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
        /* default expiry time, overwritten in gc_config */
        gc_config();
        if (parse_expiry_date(gc_log_expire, &gc_log_expire_time))
-               die(_("Failed to parse gc.logexpiry value %s"), gc_log_expire);
+               die(_("failed to parse gc.logexpiry value %s"), gc_log_expire);
 
        if (pack_refs < 0)
                pack_refs = !is_bare_repository();
@@ -391,6 +535,9 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
        if (argc > 0)
                usage_with_options(builtin_gc_usage, builtin_gc_options);
 
+       if (prune_expire && parse_expiry_date(prune_expire, &dummy))
+               die(_("failed to parse prune expiry value %s"), prune_expire);
+
        if (aggressive) {
                argv_array_push(&repack, "-f");
                if (aggressive_depth > 0)
@@ -430,8 +577,19 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                         */
                        daemonized = !daemonize();
                }
-       } else
-               add_repack_all_option();
+       } else {
+               struct string_list keep_pack = STRING_LIST_INIT_NODUP;
+
+               if (keep_base_pack != -1) {
+                       if (keep_base_pack)
+                               find_base_packs(&keep_pack, 0);
+               } else if (big_pack_threshold) {
+                       find_base_packs(&keep_pack, big_pack_threshold);
+               }
+
+               add_repack_all_option(&keep_pack);
+               string_list_clear(&keep_pack, 0);
+       }
 
        name = lock_repo_for_gc(force, &pid);
        if (name) {
@@ -479,7 +637,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
                return error(FAILED_RUN, rerere.argv[0]);
 
        report_garbage = report_pack_garbage;
-       reprepare_packed_git();
+       reprepare_packed_git(the_repository);
        if (pack_garbage.nr > 0)
                clean_pack_garbage();
 
index 789a89133aca7b8eeb93a936fd2301bd3f37d0c7..ee753a403eba0e9bc25b40a1efd200cafdf31e19 100644 (file)
@@ -22,6 +22,7 @@
 #include "pathspec.h"
 #include "submodule.h"
 #include "submodule-config.h"
+#include "object-store.h"
 
 static char const * const grep_usage[] = {
        N_("git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"),
@@ -306,7 +307,7 @@ static void *lock_and_read_oid_file(const struct object_id *oid, enum object_typ
        void *data;
 
        grep_read_lock();
-       data = read_sha1_file(oid->hash, type, size);
+       data = read_object_file(oid, type, size);
        grep_read_unlock();
        return data;
 }
@@ -439,7 +440,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
         * object.
         */
        grep_read_lock();
-       add_to_alternates_memory(submodule.objectdir);
+       add_to_alternates_memory(submodule.objects->objectdir);
        grep_read_unlock();
 
        if (oid) {
@@ -452,7 +453,7 @@ static int grep_submodule(struct grep_opt *opt, struct repository *superproject,
                object = parse_object_or_die(oid, oid_to_hex(oid));
 
                grep_read_lock();
-               data = read_object_with_reference(object->oid.hash, tree_type,
+               data = read_object_with_reference(&object->oid, tree_type,
                                                  &size, NULL);
                grep_read_unlock();
 
@@ -487,7 +488,8 @@ static int grep_cache(struct grep_opt *opt, struct repository *repo,
                strbuf_addstr(&name, repo->submodule_prefix);
        }
 
-       repo_read_index(repo);
+       if (repo_read_index(repo) < 0)
+               die("index file corrupt");
 
        for (nr = 0; nr < repo->index->cache_nr; nr++) {
                const struct cache_entry *ce = repo->index->cache[nr];
@@ -601,8 +603,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 }
 
 static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
-                      struct object *obj, const char *name, const char *path,
-                      struct repository *repo)
+                      struct object *obj, const char *name, const char *path)
 {
        if (obj->type == OBJ_BLOB)
                return grep_oid(opt, &obj->oid, name, 0, path);
@@ -614,7 +615,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
                int hit, len;
 
                grep_read_lock();
-               data = read_object_with_reference(obj->oid.hash, tree_type,
+               data = read_object_with_reference(&obj->oid, tree_type,
                                                  &size, NULL);
                grep_read_unlock();
 
@@ -629,7 +630,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
                }
                init_tree_desc(&tree, data, size);
                hit = grep_tree(opt, pathspec, &tree, &base, base.len,
-                               obj->type == OBJ_COMMIT, repo);
+                               obj->type == OBJ_COMMIT, the_repository);
                strbuf_release(&base);
                free(data);
                return hit;
@@ -638,7 +639,6 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec,
 }
 
 static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
-                       struct repository *repo,
                        const struct object_array *list)
 {
        unsigned int i;
@@ -651,11 +651,11 @@ static int grep_objects(struct grep_opt *opt, const struct pathspec *pathspec,
 
                /* load the gitmodules file for this rev */
                if (recurse_submodules) {
-                       submodule_free();
+                       submodule_free(the_repository);
                        gitmodules_config_oid(&real_obj->oid);
                }
-               if (grep_object(opt, pathspec, real_obj, list->objects[i].name, list->objects[i].path,
-                               repo)) {
+               if (grep_object(opt, pathspec, real_obj, list->objects[i].name,
+                               list->objects[i].path)) {
                        hit = 1;
                        if (opt->status_only)
                                break;
@@ -886,9 +886,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                           N_("indicate hit with exit status without output")),
                OPT_BOOL(0, "all-match", &opt.all_match,
                        N_("show only matches from files that match all patterns")),
-               { OPTION_SET_INT, 0, "debug", &opt.debug, NULL,
-                 N_("show parse tree for grep expression"),
-                 PARSE_OPT_NOARG | PARSE_OPT_HIDDEN, NULL, 1 },
+               OPT_SET_INT_F(0, "debug", &opt.debug,
+                             N_("show parse tree for grep expression"),
+                             1, PARSE_OPT_HIDDEN),
                OPT_GROUP(""),
                { OPTION_STRING, 'O', "open-files-in-pager", &show_in_pager,
                        N_("pager"), N_("show matching files in the pager"),
@@ -1107,7 +1107,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
                if (cached)
                        die(_("both --cached and trees are given."));
 
-               hit = grep_objects(&opt, &pathspec, the_repository, &list);
+               hit = grep_objects(&opt, &pathspec, &list);
        }
 
        if (num_threads)
index 526da5c1856ed1c387975a767f4d01382d1ea1a9..a9a3a198c3b47197cb847ba32a33177f1a45f428 100644 (file)
@@ -9,7 +9,7 @@
 #include "blob.h"
 #include "quote.h"
 #include "parse-options.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 
 /*
  * This is to create corrupt objects for debugging and as such it
index 598867cfea40c6e0df25111c5484dde5d2cd8b47..58e0a5507f10365b43eaa2698da2c8bba18b12ed 100644 (file)
@@ -4,11 +4,12 @@
 #include "cache.h"
 #include "config.h"
 #include "builtin.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "parse-options.h"
 #include "run-command.h"
 #include "column.h"
 #include "help.h"
+#include "alias.h"
 
 #ifndef DEFAULT_HELP_FORMAT
 #define DEFAULT_HELP_FORMAT "man"
@@ -36,6 +37,7 @@ static const char *html_path;
 
 static int show_all = 0;
 static int show_guides = 0;
+static int verbose;
 static unsigned int colopts;
 static enum help_format help_format = HELP_FORMAT_NONE;
 static int exclude_guides;
@@ -48,6 +50,7 @@ static struct option builtin_help_options[] = {
                        HELP_FORMAT_WEB),
        OPT_SET_INT('i', "info", &help_format, N_("show info page"),
                        HELP_FORMAT_INFO),
+       OPT__VERBOSE(&verbose, N_("print command description")),
        OPT_END(),
 };
 
@@ -400,38 +403,6 @@ static void show_html_page(const char *git_cmd)
        open_html(page_path.buf);
 }
 
-static struct {
-       const char *name;
-       const char *help;
-} common_guides[] = {
-       { "attributes", N_("Defining attributes per path") },
-       { "everyday", N_("Everyday Git With 20 Commands Or So") },
-       { "glossary", N_("A Git glossary") },
-       { "ignore", N_("Specifies intentionally untracked files to ignore") },
-       { "modules", N_("Defining submodule properties") },
-       { "revisions", N_("Specifying revisions and ranges for Git") },
-       { "tutorial", N_("A tutorial introduction to Git (for version 1.5.1 or newer)") },
-       { "workflows", N_("An overview of recommended workflows with Git") },
-};
-
-static void list_common_guides_help(void)
-{
-       int i, longest = 0;
-
-       for (i = 0; i < ARRAY_SIZE(common_guides); i++) {
-               if (longest < strlen(common_guides[i].name))
-                       longest = strlen(common_guides[i].name);
-       }
-
-       puts(_("The common Git guides are:\n"));
-       for (i = 0; i < ARRAY_SIZE(common_guides); i++) {
-               printf("   %s   ", common_guides[i].name);
-               mput_char(' ', longest - strlen(common_guides[i].name));
-               puts(_(common_guides[i].help));
-       }
-       putchar('\n');
-}
-
 static const char *check_git_cmd(const char* cmd)
 {
        char *alias;
@@ -463,6 +434,11 @@ int cmd_help(int argc, const char **argv, const char *prefix)
 
        if (show_all) {
                git_config(git_help_config, NULL);
+               if (verbose) {
+                       setup_pager();
+                       list_all_cmds_help();
+                       return 0;
+               }
                printf(_("usage: %s%s"), _(git_usage_string), "\n\n");
                load_command_list("git-", &main_cmds, &other_cmds);
                list_commands(colopts, &main_cmds, &other_cmds);
index 7b2f7c04703f5eff8a1eda06ae59c0d22a8a1ab5..74fe2973e1256e092652fce28ba2036cc3203af9 100644 (file)
@@ -9,10 +9,11 @@
 #include "tree.h"
 #include "progress.h"
 #include "fsck.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "streaming.h"
 #include "thread-utils.h"
 #include "packfile.h"
+#include "object-store.h"
 
 static const char index_pack_usage[] =
 "git index-pack [-v] [-o <index-file>] [--keep | --keep=<msg>] [--verify] [--strict] (<pack-file> | --stdin [--fix-thin] [<pack-file>])";
@@ -59,7 +60,7 @@ struct ofs_delta_entry {
 };
 
 struct ref_delta_entry {
-       unsigned char sha1[20];
+       struct object_id oid;
        int obj_no;
 };
 
@@ -222,7 +223,7 @@ static unsigned check_object(struct object *obj)
 
        if (!(obj->flags & FLAG_CHECKED)) {
                unsigned long size;
-               int type = sha1_object_info(obj->oid.hash, &size);
+               int type = oid_object_info(the_repository, &obj->oid, &size);
                if (type <= 0)
                        die(_("did not receive expected object %s"),
                              oid_to_hex(&obj->oid));
@@ -672,18 +673,18 @@ static void find_ofs_delta_children(off_t offset,
        *last_index = last;
 }
 
-static int compare_ref_delta_bases(const unsigned char *sha1,
-                                  const unsigned char *sha2,
+static int compare_ref_delta_bases(const struct object_id *oid1,
+                                  const struct object_id *oid2,
                                   enum object_type type1,
                                   enum object_type type2)
 {
        int cmp = type1 - type2;
        if (cmp)
                return cmp;
-       return hashcmp(sha1, sha2);
+       return oidcmp(oid1, oid2);
 }
 
-static int find_ref_delta(const unsigned char *sha1, enum object_type type)
+static int find_ref_delta(const struct object_id *oid, enum object_type type)
 {
        int first = 0, last = nr_ref_deltas;
 
@@ -692,7 +693,7 @@ static int find_ref_delta(const unsigned char *sha1, enum object_type type)
                struct ref_delta_entry *delta = &ref_deltas[next];
                int cmp;
 
-               cmp = compare_ref_delta_bases(sha1, delta->sha1,
+               cmp = compare_ref_delta_bases(oid, &delta->oid,
                                              type, objects[delta->obj_no].type);
                if (!cmp)
                        return next;
@@ -705,11 +706,11 @@ static int find_ref_delta(const unsigned char *sha1, enum object_type type)
        return -first-1;
 }
 
-static void find_ref_delta_children(const unsigned char *sha1,
+static void find_ref_delta_children(const struct object_id *oid,
                                    int *first_index, int *last_index,
                                    enum object_type type)
 {
-       int first = find_ref_delta(sha1, type);
+       int first = find_ref_delta(oid, type);
        int last = first;
        int end = nr_ref_deltas - 1;
 
@@ -718,9 +719,9 @@ static void find_ref_delta_children(const unsigned char *sha1,
                *last_index = -1;
                return;
        }
-       while (first > 0 && !hashcmp(ref_deltas[first - 1].sha1, sha1))
+       while (first > 0 && !oidcmp(&ref_deltas[first - 1].oid, oid))
                --first;
-       while (last < end && !hashcmp(ref_deltas[last + 1].sha1, sha1))
+       while (last < end && !oidcmp(&ref_deltas[last + 1].oid, oid))
                ++last;
        *first_index = first;
        *last_index = last;
@@ -772,7 +773,7 @@ static int check_collison(struct object_entry *entry)
 
        memset(&data, 0, sizeof(data));
        data.entry = entry;
-       data.st = open_istream(entry->idx.oid.hash, &type, &size, NULL);
+       data.st = open_istream(&entry->idx.oid, &type, &size, NULL);
        if (!data.st)
                return -1;
        if (size != entry->size || type != entry->type)
@@ -811,12 +812,12 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                enum object_type has_type;
                unsigned long has_size;
                read_lock();
-               has_type = sha1_object_info(oid->hash, &has_size);
+               has_type = oid_object_info(the_repository, oid, &has_size);
                if (has_type < 0)
                        die(_("cannot read existing object info %s"), oid_to_hex(oid));
                if (has_type != type || has_size != size)
                        die(_("SHA1 COLLISION FOUND WITH %s !"), oid_to_hex(oid));
-               has_data = read_sha1_file(oid->hash, &has_type, &has_size);
+               has_data = read_object_file(oid, &has_type, &has_size);
                read_unlock();
                if (!data)
                        data = new_data = get_data_from_pack(obj_entry);
@@ -868,7 +869,7 @@ static void sha1_object(const void *data, struct object_entry *obj_entry,
                        if (obj->type == OBJ_COMMIT) {
                                struct commit *commit = (struct commit *) obj;
                                if (detach_commit_buffer(commit, NULL) != data)
-                                       die("BUG: parse_object_buffer transmogrified our buffer");
+                                       BUG("parse_object_buffer transmogrified our buffer");
                        }
                        obj->flags |= FLAG_CHECKED;
                }
@@ -995,7 +996,7 @@ static struct base_data *find_unresolved_deltas_1(struct base_data *base,
                                                  struct base_data *prev_base)
 {
        if (base->ref_last == -1 && base->ofs_last == -1) {
-               find_ref_delta_children(base->obj->idx.oid.hash,
+               find_ref_delta_children(&base->obj->idx.oid,
                                        &base->ref_first, &base->ref_last,
                                        OBJ_REF_DELTA);
 
@@ -1017,7 +1018,7 @@ static struct base_data *find_unresolved_deltas_1(struct base_data *base,
 
                if (!compare_and_swap_type(&child->real_type, OBJ_REF_DELTA,
                                           base->obj->real_type))
-                       die("BUG: child->real_type != OBJ_REF_DELTA");
+                       BUG("child->real_type != OBJ_REF_DELTA");
 
                resolve_delta(child, base, result);
                if (base->ref_first == base->ref_last && base->ofs_last == -1)
@@ -1079,7 +1080,7 @@ static int compare_ref_delta_entry(const void *a, const void *b)
        const struct ref_delta_entry *delta_a = a;
        const struct ref_delta_entry *delta_b = b;
 
-       return hashcmp(delta_a->sha1, delta_b->sha1);
+       return oidcmp(&delta_a->oid, &delta_b->oid);
 }
 
 static void resolve_base(struct object_entry *obj)
@@ -1145,7 +1146,7 @@ static void parse_pack_objects(unsigned char *hash)
                        ofs_delta++;
                } else if (obj->type == OBJ_REF_DELTA) {
                        ALLOC_GROW(ref_deltas, nr_ref_deltas + 1, ref_deltas_alloc);
-                       hashcpy(ref_deltas[nr_ref_deltas].sha1, ref_delta_oid.hash);
+                       oidcpy(&ref_deltas[nr_ref_deltas].oid, &ref_delta_oid);
                        ref_deltas[nr_ref_deltas].obj_no = i;
                        nr_ref_deltas++;
                } else if (!data) {
@@ -1273,7 +1274,7 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha
                            nr_objects - nr_objects_initial);
                stop_progress_msg(&progress, msg.buf);
                strbuf_release(&msg);
-               hashclose(f, tail_hash, 0);
+               finalize_hashfile(f, tail_hash, 0);
                hashcpy(read_hash, pack_hash);
                fixup_pack_header_footer(output_fd, pack_hash,
                                         curr_pack, nr_objects,
@@ -1377,14 +1378,15 @@ static void fix_unresolved_deltas(struct hashfile *f)
 
                if (objects[d->obj_no].real_type != OBJ_REF_DELTA)
                        continue;
-               base_obj->data = read_sha1_file(d->sha1, &type, &base_obj->size);
+               base_obj->data = read_object_file(&d->oid, &type,
+                                                 &base_obj->size);
                if (!base_obj->data)
                        continue;
 
-               if (check_sha1_signature(d->sha1, base_obj->data,
+               if (check_object_signature(&d->oid, base_obj->data,
                                base_obj->size, type_name(type)))
-                       die(_("local object %s is corrupt"), sha1_to_hex(d->sha1));
-               base_obj->obj = append_obj_to_pack(f, d->sha1,
+                       die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
+               base_obj->obj = append_obj_to_pack(f, d->oid.hash,
                                        base_obj->data, base_obj->size, type);
                find_unresolved_deltas(base_obj);
                display_progress(progress, nr_resolved_deltas);
@@ -1480,8 +1482,12 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
        } else
                chmod(final_index_name, 0444);
 
-       if (do_fsck_object)
-               add_packed_git(final_index_name, strlen(final_index_name), 0);
+       if (do_fsck_object) {
+               struct packed_git *p;
+               p = add_packed_git(final_index_name, strlen(final_index_name), 0);
+               if (p)
+                       install_packed_git(the_repository, p);
+       }
 
        if (!from_stdin) {
                printf("%s\n", sha1_to_hex(hash));
@@ -1547,12 +1553,13 @@ static void read_v2_anomalous_offsets(struct packed_git *p,
 {
        const uint32_t *idx1, *idx2;
        uint32_t i;
+       const uint32_t hashwords = the_hash_algo->rawsz / sizeof(uint32_t);
 
        /* The address of the 4-byte offset table */
        idx1 = (((const uint32_t *)p->index_data)
                + 2 /* 8-byte header */
                + 256 /* fan out */
-               + 5 * p->num_objects /* 20-byte SHA-1 table */
+               + hashwords * p->num_objects /* object ID table */
                + p->num_objects /* CRC32 table */
                );
 
@@ -1597,7 +1604,7 @@ static void read_idx_option(struct pack_idx_option *opts, const char *pack_name)
        /*
         * Get rid of the idx file as we do not need it anymore.
         * NEEDSWORK: extract this bit from free_pack_by_name() in
-        * sha1_file.c, perhaps?  It shouldn't matter very much as we
+        * sha1-file.c, perhaps?  It shouldn't matter very much as we
         * know we haven't installed this pack (hence we never have
         * read anything from it).
         */
index 68ff4ad75ace6566a233c1343fed93365c5abbe4..4ecf90936822e64998651e4d51d1be9c921dee60 100644 (file)
@@ -7,7 +7,7 @@
 #include "config.h"
 #include "refs.h"
 #include "builtin.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "parse-options.h"
 
 #ifndef DEFAULT_GIT_TEMPLATE_DIR
@@ -117,7 +117,7 @@ static void copy_templates(const char *template_dir)
 
        dir = opendir(template_path.buf);
        if (!dir) {
-               warning(_("templates not found %s"), template_dir);
+               warning(_("templates not found in %s"), template_dir);
                goto free_return;
        }
 
@@ -391,7 +391,7 @@ int init_db(const char *git_dir, const char *real_git_dir,
                else if (get_shared_repository() == PERM_EVERYBODY)
                        xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY);
                else
-                       die("BUG: invalid value for shared_repository");
+                       BUG("invalid value for shared_repository");
                git_config_set("core.sharedrepository", buf);
                git_config_set("receive.denyNonFastforwards", "true");
        }
index 94ee177d56d6ff9c82b02ebfb2d27cf789527974..4686f68594829a85e9d73bcf0b6298c1e61b6852 100644 (file)
@@ -518,7 +518,7 @@ static int show_tag_object(const struct object_id *oid, struct rev_info *rev)
 {
        unsigned long size;
        enum object_type type;
-       char *buf = read_sha1_file(oid->hash, &type, &size);
+       char *buf = read_object_file(oid, &type, &size);
        int offset = 0;
 
        if (!buf)
@@ -541,7 +541,7 @@ static int show_tag_object(const struct object_id *oid, struct rev_info *rev)
        return 0;
 }
 
-static int show_tree_object(const unsigned char *sha1,
+static int show_tree_object(const struct object_id *oid,
                struct strbuf *base,
                const char *pathname, unsigned mode, int stage, void *context)
 {
@@ -1019,7 +1019,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
            open_next_file(NULL, rev->numbered_files ? NULL : "cover-letter", rev, quiet))
                return;
 
-       log_write_email_headers(rev, head, &pp.after_subject, &need_8bit_cte);
+       log_write_email_headers(rev, head, &pp.after_subject, &need_8bit_cte, 0);
 
        for (i = 0; !need_8bit_cte && i < nr; i++) {
                const char *buf = get_commit_buffer(list[i], NULL);
@@ -1067,8 +1067,8 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout,
 
        diff_setup_done(&opts);
 
-       diff_tree_oid(&origin->tree->object.oid,
-                     &head->tree->object.oid,
+       diff_tree_oid(get_commit_tree_oid(origin),
+                     get_commit_tree_oid(head),
                      "", &opts);
        diffcore_std(&opts);
        diff_flush(&opts);
@@ -1474,9 +1474,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
                         N_("output all-zero hash in From header")),
                OPT_BOOL(0, "ignore-if-in-upstream", &ignore_if_in_upstream,
                         N_("don't include a patch matching a commit upstream")),
-               { OPTION_SET_INT, 'p', "no-stat", &use_patch_format, NULL,
-                 N_("show patch format instead of default (patch + stat)"),
-                 PARSE_OPT_NONEG | PARSE_OPT_NOARG, NULL, 1},
+               OPT_SET_INT_F('p', "no-stat", &use_patch_format,
+                             N_("show patch format instead of default (patch + stat)"),
+                             1, PARSE_OPT_NONEG),
                OPT_GROUP(N_("Messaging")),
                { OPTION_CALLBACK, 0, "add-header", NULL, N_("header"),
                            N_("add email header"), 0, header_callback },
@@ -1873,12 +1873,12 @@ static void print_commit(char sign, struct commit *commit, int verbose,
 {
        if (!verbose) {
                fprintf(file, "%c %s\n", sign,
-                      find_unique_abbrev(commit->object.oid.hash, abbrev));
+                      find_unique_abbrev(&commit->object.oid, abbrev));
        } else {
                struct strbuf buf = STRBUF_INIT;
                pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
                fprintf(file, "%c %s %s\n", sign,
-                      find_unique_abbrev(commit->object.oid.hash, abbrev),
+                      find_unique_abbrev(&commit->object.oid, abbrev),
                       buf.buf);
                strbuf_release(&buf);
        }
index 2fc836e33086d5b70b86a3fc746f9e75706ef7ea..88bb2019ad7a52a13373d4c88b127915b219e4a5 100644 (file)
@@ -166,7 +166,7 @@ static void show_killed_files(const struct index_state *istate,
                                 */
                                pos = index_name_pos(istate, ent->name, ent->len);
                                if (0 <= pos)
-                                       die("BUG: killed-file %.*s not found",
+                                       BUG("killed-file %.*s not found",
                                                ent->len, ent->name);
                                pos = -pos - 1;
                                while (pos < istate->cache_nr &&
@@ -240,7 +240,7 @@ static void show_ce(struct repository *repo, struct dir_struct *dir,
                        printf("%s%06o %s %d\t",
                               tag,
                               ce->ce_mode,
-                              find_unique_abbrev(ce->oid.hash, abbrev),
+                              find_unique_abbrev(&ce->oid, abbrev),
                               ce_stage(ce));
                }
                write_eolinfo(repo->index, ce, fullname);
@@ -271,7 +271,7 @@ static void show_ru_info(const struct index_state *istate)
                        if (!ui->mode[i])
                                continue;
                        printf("%s%06o %s %d\t", tag_resolve_undo, ui->mode[i],
-                              find_unique_abbrev(ui->sha1[i], abbrev),
+                              find_unique_abbrev(&ui->oid[i], abbrev),
                               i + 1);
                        write_name(path);
                }
@@ -556,9 +556,9 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
                { OPTION_CALLBACK, 0, "exclude-standard", &dir, NULL,
                        N_("add the standard git exclusions"),
                        PARSE_OPT_NOARG, option_parse_exclude_standard },
-               { OPTION_SET_INT, 0, "full-name", &prefix_len, NULL,
-                       N_("make the output relative to the project top directory"),
-                       PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL },
+               OPT_SET_INT_F(0, "full-name", &prefix_len,
+                             N_("make the output relative to the project top directory"),
+                             0, PARSE_OPT_NONEG),
                OPT_BOOL(0, "recurse-submodules", &recurse_submodules,
                        N_("recurse through submodules")),
                OPT_BOOL(0, "error-unmatch", &error_unmatch,
index 540d56429f5cec4ace8655dd9a870089fc872d2c..1a25df7ee15b45df142679286afdb0e8c55647dc 100644 (file)
@@ -1,7 +1,9 @@
 #include "builtin.h"
 #include "cache.h"
 #include "transport.h"
+#include "ref-filter.h"
 #include "remote.h"
+#include "refs.h"
 
 static const char * const ls_remote_usage[] = {
        N_("git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
@@ -43,10 +45,15 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
        int show_symref_target = 0;
        const char *uploadpack = NULL;
        const char **pattern = NULL;
+       struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
+       int i;
+       struct string_list server_options = STRING_LIST_INIT_DUP;
 
        struct remote *remote;
        struct transport *transport;
        const struct ref *ref;
+       struct ref_array ref_array;
+       static struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;
 
        struct option options[] = {
                OPT__QUIET(&quiet, N_("do not print remote URL")),
@@ -60,14 +67,19 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
                OPT_BIT(0, "refs", &flags, N_("do not show peeled tags"), REF_NORMAL),
                OPT_BOOL(0, "get-url", &get_url,
                         N_("take url.<base>.insteadOf into account")),
+               OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
+                            N_("field name to sort on"), &parse_opt_ref_sorting),
                OPT_SET_INT_F(0, "exit-code", &status,
                              N_("exit with exit code 2 if no matching refs are found"),
                              2, PARSE_OPT_NOCOMPLETE),
                OPT_BOOL(0, "symref", &show_symref_target,
                         N_("show underlying ref in addition to the object pointed by it")),
+               OPT_STRING_LIST('o', "server-option", &server_options, N_("server-specific"), N_("option to transmit")),
                OPT_END()
        };
 
+       memset(&ref_array, 0, sizeof(ref_array));
+
        argc = parse_options(argc, argv, prefix, options, ls_remote_usage,
                             PARSE_OPT_STOP_AT_NON_OPTION);
        dest = argv[0];
@@ -75,8 +87,17 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
        if (argc > 1) {
                int i;
                pattern = xcalloc(argc, sizeof(const char *));
-               for (i = 1; i < argc; i++)
+               for (i = 1; i < argc; i++) {
+                       const char *glob;
                        pattern[i - 1] = xstrfmt("*/%s", argv[i]);
+
+                       glob = strchr(argv[i], '*');
+                       if (glob)
+                               argv_array_pushf(&ref_prefixes, "%.*s",
+                                                (int)(glob - argv[i]), argv[i]);
+                       else
+                               expand_ref_prefix(&ref_prefixes, argv[i]);
+               }
        }
 
        remote = remote_get(dest);
@@ -90,28 +111,46 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)
 
        if (get_url) {
                printf("%s\n", *remote->url);
+               UNLEAK(sorting);
                return 0;
        }
 
        transport = transport_get(remote, NULL);
        if (uploadpack != NULL)
                transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
+       if (server_options.nr)
+               transport->server_options = &server_options;
 
-       ref = transport_get_remote_refs(transport);
-       if (transport_disconnect(transport))
+       ref = transport_get_remote_refs(transport, &ref_prefixes);
+       if (transport_disconnect(transport)) {
+               UNLEAK(sorting);
                return 1;
+       }
 
        if (!dest && !quiet)
                fprintf(stderr, "From %s\n", *remote->url);
        for ( ; ref; ref = ref->next) {
+               struct ref_array_item *item;
                if (!check_ref_type(ref, flags))
                        continue;
                if (!tail_match(pattern, ref->name))
                        continue;
+               item = ref_array_push(&ref_array, ref->name, &ref->old_oid);
+               item->symref = xstrdup_or_null(ref->symref);
+       }
+
+       if (sorting)
+               ref_array_sort(sorting, &ref_array);
+
+       for (i = 0; i < ref_array.nr; i++) {
+               const struct ref_array_item *ref = ref_array.items[i];
                if (show_symref_target && ref->symref)
-                       printf("ref: %s\t%s\n", ref->symref, ref->name);
-               printf("%s\t%s\n", oid_to_hex(&ref->old_oid), ref->name);
+                       printf("ref: %s\t%s\n", ref->symref, ref->refname);
+               printf("%s\t%s\n", oid_to_hex(&ref->objectname), ref->refname);
                status = 0; /* we found something */
        }
+
+       UNLEAK(sorting);
+       UNLEAK(ref_array);
        return status;
 }
index ef965408e8fc5d80fa9e9daf0264a91abccd978c..409da4e8351f6d8719671d3176f0ea34fe9b756c 100644 (file)
@@ -60,7 +60,7 @@ static int show_recursive(const char *base, int baselen, const char *pathname)
        return 0;
 }
 
-static int show_tree(const unsigned char *sha1, struct strbuf *base,
+static int show_tree(const struct object_id *oid, struct strbuf *base,
                const char *pathname, unsigned mode, int stage, void *context)
 {
        int retval = 0;
@@ -94,7 +94,7 @@ static int show_tree(const unsigned char *sha1, struct strbuf *base,
                        char size_text[24];
                        if (!strcmp(type, blob_type)) {
                                unsigned long size;
-                               if (sha1_object_info(sha1, &size) == OBJ_BAD)
+                               if (oid_object_info(the_repository, oid, &size) == OBJ_BAD)
                                        xsnprintf(size_text, sizeof(size_text),
                                                  "BAD");
                                else
@@ -103,11 +103,11 @@ static int show_tree(const unsigned char *sha1, struct strbuf *base,
                        } else
                                xsnprintf(size_text, sizeof(size_text), "-");
                        printf("%06o %s %s %7s\t", mode, type,
-                              find_unique_abbrev(sha1, abbrev),
+                              find_unique_abbrev(oid, abbrev),
                               size_text);
                } else
                        printf("%06o %s %s\t", mode, type,
-                              find_unique_abbrev(sha1, abbrev));
+                              find_unique_abbrev(oid, abbrev));
        }
        baselen = base->len;
        strbuf_addstr(base, pathname);
index d01ddecf6602eabdca97a175e5c2a57bf1257865..bf01e05808313da20ed73c37d0d150c4ddb45587 100644 (file)
@@ -2,7 +2,7 @@
 #include "tree-walk.h"
 #include "xdiff-interface.h"
 #include "blob.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "merge-blobs.h"
 
 static const char merge_tree_usage[] = "git merge-tree <base-tree> <branch1> <branch2>";
@@ -60,7 +60,7 @@ static void *result(struct merge_list *entry, unsigned long *size)
        const char *path = entry->path;
 
        if (!entry->stage)
-               return read_sha1_file(entry->blob->object.oid.hash, &type, size);
+               return read_object_file(&entry->blob->object.oid, &type, size);
        base = NULL;
        if (entry->stage == 1) {
                base = entry->blob;
@@ -82,7 +82,8 @@ static void *origin(struct merge_list *entry, unsigned long *size)
        enum object_type type;
        while (entry) {
                if (entry->stage == 2)
-                       return read_sha1_file(entry->blob->object.oid.hash, &type, size);
+                       return read_object_file(&entry->blob->object.oid,
+                                               &type, size);
                entry = entry->link;
        }
        return NULL;
index ee050a47f34d7394d048f955baabb37a9e716ef8..b00d6f4821e7dc4067997bf515702edcfa413501 100644 (file)
@@ -14,6 +14,7 @@
 #include "run-command.h"
 #include "diff.h"
 #include "refs.h"
+#include "refspec.h"
 #include "commit.h"
 #include "diffcore.h"
 #include "revision.h"
@@ -34,6 +35,7 @@
 #include "string-list.h"
 #include "packfile.h"
 #include "tag.h"
+#include "alias.h"
 
 #define DEFAULT_TWOHEAD (1<<0)
 #define DEFAULT_OCTOPUS (1<<1)
@@ -213,9 +215,9 @@ static struct option builtin_merge_options[] = {
        OPT_BOOL('e', "edit", &option_edit,
                N_("edit message before committing")),
        OPT_SET_INT(0, "ff", &fast_forward, N_("allow fast-forward (default)"), FF_ALLOW),
-       { OPTION_SET_INT, 0, "ff-only", &fast_forward, NULL,
-               N_("abort if fast-forward is not possible"),
-               PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, FF_ONLY },
+       OPT_SET_INT_F(0, "ff-only", &fast_forward,
+                     N_("abort if fast-forward is not possible"),
+                     FF_ONLY, PARSE_OPT_NONEG),
        OPT_RERERE_AUTOUPDATE(&allow_rerere_auto),
        OPT_BOOL(0, "verify-signatures", &verify_signatures,
                N_("verify that the named commit has a valid GPG signature")),
@@ -280,7 +282,7 @@ out:
        return rc;
 }
 
-static void read_empty(unsigned const char *sha1, int verbose)
+static void read_empty(const struct object_id *oid, int verbose)
 {
        int i = 0;
        const char *args[7];
@@ -290,15 +292,15 @@ static void read_empty(unsigned const char *sha1, int verbose)
                args[i++] = "-v";
        args[i++] = "-m";
        args[i++] = "-u";
-       args[i++] = EMPTY_TREE_SHA1_HEX;
-       args[i++] = sha1_to_hex(sha1);
+       args[i++] = empty_tree_oid_hex();
+       args[i++] = oid_to_hex(oid);
        args[i] = NULL;
 
        if (run_command_v_opt(args, RUN_GIT_CMD))
                die(_("read-tree failed"));
 }
 
-static void reset_hard(unsigned const char *sha1, int verbose)
+static void reset_hard(const struct object_id *oid, int verbose)
 {
        int i = 0;
        const char *args[6];
@@ -308,7 +310,7 @@ static void reset_hard(unsigned const char *sha1, int verbose)
                args[i++] = "-v";
        args[i++] = "--reset";
        args[i++] = "-u";
-       args[i++] = sha1_to_hex(sha1);
+       args[i++] = oid_to_hex(oid);
        args[i] = NULL;
 
        if (run_command_v_opt(args, RUN_GIT_CMD))
@@ -324,7 +326,7 @@ static void restore_state(const struct object_id *head,
        if (is_null_oid(stash))
                return;
 
-       reset_hard(head->hash, 1);
+       reset_hard(head, 1);
 
        args[2] = oid_to_hex(stash);
 
@@ -412,7 +414,7 @@ static void finish(struct commit *head_commit,
                         * We ignore errors in 'gc --auto', since the
                         * user should see them.
                         */
-                       close_all_packs();
+                       close_all_packs(the_repository->objects);
                        run_command_v_opt(argv_gc_auto, RUN_GIT_CMD);
                }
        }
@@ -639,7 +641,7 @@ static int read_tree_trivial(struct object_id *common, struct object_id *head,
 
 static void write_tree_trivial(struct object_id *oid)
 {
-       if (write_cache_as_tree(oid->hash, 0, NULL))
+       if (write_cache_as_tree(oid, 0, NULL))
                die(_("git write-tree failed to write a tree"));
 }
 
@@ -647,7 +649,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
                              struct commit_list *remoteheads,
                              struct commit *head)
 {
-       static struct lock_file lock;
+       struct lock_file lock = LOCK_INIT;
        const char *head_arg = "HEAD";
 
        hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
@@ -805,7 +807,7 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads)
 {
        struct object_id result_tree, result_commit;
        struct commit_list *parents, **pptr = &parents;
-       static struct lock_file lock;
+       struct lock_file lock = LOCK_INIT;
 
        hold_locked_index(&lock, LOCK_DIE_ON_ERROR);
        refresh_cache(REFRESH_QUIET);
@@ -1297,7 +1299,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
                if (remoteheads->next)
                        die(_("Can merge only exactly one commit into empty head"));
                remote_head_oid = &remoteheads->item->object.oid;
-               read_empty(remote_head_oid->hash, 0);
+               read_empty(remote_head_oid, 0);
                update_ref("initial pull", "HEAD", remote_head_oid, NULL, 0,
                           UPDATE_REFS_DIE_ON_ERR);
                goto done;
@@ -1324,7 +1326,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 
                        check_commit_signature(commit, &signature_check);
 
-                       find_unique_abbrev_r(hex, commit->object.oid.hash, DEFAULT_ABBREV);
+                       find_unique_abbrev_r(hex, &commit->object.oid, DEFAULT_ABBREV);
                        switch (signature_check.result) {
                        case 'G':
                                break;
@@ -1417,9 +1419,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)
 
                if (verbosity >= 0) {
                        printf(_("Updating %s..%s\n"),
-                              find_unique_abbrev(head_commit->object.oid.hash,
+                              find_unique_abbrev(&head_commit->object.oid,
                                                  DEFAULT_ABBREV),
-                              find_unique_abbrev(remoteheads->item->object.oid.hash,
+                              find_unique_abbrev(&remoteheads->item->object.oid,
                                                  DEFAULT_ABBREV));
                }
                strbuf_addstr(&msg, "Fast-forward");
index beb552847ba1ef36c78d9d10d3ff9e98e6a288bc..82a6e860775f872a9145e32ee9d8f315b70ad2ea 100644 (file)
@@ -1,5 +1,6 @@
 #include "builtin.h"
 #include "tag.h"
+#include "replace-object.h"
 
 /*
  * A signature file has a very simple fixed format: four lines
 /*
  * We refuse to tag something we can't verify. Just because.
  */
-static int verify_object(const unsigned char *sha1, const char *expected_type)
+static int verify_object(const struct object_id *oid, const char *expected_type)
 {
        int ret = -1;
        enum object_type type;
        unsigned long size;
-       void *buffer = read_sha1_file(sha1, &type, &size);
-       const unsigned char *repl = lookup_replace_object(sha1);
+       void *buffer = read_object_file(oid, &type, &size);
+       const struct object_id *repl = lookup_replace_object(the_repository, oid);
 
        if (buffer) {
                if (type == type_from_string(expected_type))
-                       ret = check_sha1_signature(repl, buffer, size, expected_type);
+                       ret = check_object_signature(repl, buffer, size, expected_type);
                free(buffer);
        }
        return ret;
@@ -38,8 +39,8 @@ static int verify_tag(char *buffer, unsigned long size)
 {
        int typelen;
        char type[20];
-       unsigned char sha1[20];
-       const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb;
+       struct object_id oid;
+       const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb, *p;
        size_t len;
 
        if (size < 84)
@@ -52,11 +53,11 @@ static int verify_tag(char *buffer, unsigned long size)
        if (memcmp(object, "object ", 7))
                return error("char%d: does not start with \"object \"", 0);
 
-       if (get_sha1_hex(object + 7, sha1))
+       if (parse_oid_hex(object + 7, &oid, &p))
                return error("char%d: could not get SHA1 hash", 7);
 
        /* Verify type line */
-       type_line = object + 48;
+       type_line = p + 1;
        if (memcmp(type_line - 1, "\ntype ", 6))
                return error("char%d: could not find \"\\ntype \"", 47);
 
@@ -80,8 +81,8 @@ static int verify_tag(char *buffer, unsigned long size)
        type[typelen] = 0;
 
        /* Verify that the object matches */
-       if (verify_object(sha1, type))
-               return error("char%d: could not verify object %s", 7, sha1_to_hex(sha1));
+       if (verify_object(&oid, type))
+               return error("char%d: could not verify object %s", 7, oid_to_hex(&oid));
 
        /* Verify the tag-name: we don't allow control characters or spaces in it */
        tag_line += 4;
index f5f3c0eea1cb6f2f61073e4d81fc0dd9c47dee60..bb76b469fd1f57319f3d202c1e2658d77962d698 100644 (file)
 
 static struct treeent {
        unsigned mode;
-       unsigned char sha1[20];
+       struct object_id oid;
        int len;
        char name[FLEX_ARRAY];
 } **entries;
 static int alloc, used;
 
-static void append_to_tree(unsigned mode, unsigned char *sha1, char *path)
+static void append_to_tree(unsigned mode, struct object_id *oid, char *path)
 {
        struct treeent *ent;
        size_t len = strlen(path);
@@ -26,7 +26,7 @@ static void append_to_tree(unsigned mode, unsigned char *sha1, char *path)
        FLEX_ALLOC_MEM(ent, name, path, len);
        ent->mode = mode;
        ent->len = len;
-       hashcpy(ent->sha1, sha1);
+       oidcpy(&ent->oid, oid);
 
        ALLOC_GROW(entries, used + 1, alloc);
        entries[used++] = ent;
@@ -54,7 +54,7 @@ static void write_tree(struct object_id *oid)
        for (i = 0; i < used; i++) {
                struct treeent *ent = entries[i];
                strbuf_addf(&buf, "%o %s%c", ent->mode, ent->name, '\0');
-               strbuf_add(&buf, ent->sha1, 20);
+               strbuf_add(&buf, ent->oid.hash, the_hash_algo->rawsz);
        }
 
        write_object_file(buf.buf, buf.len, tree_type, oid);
@@ -69,11 +69,12 @@ static const char *mktree_usage[] = {
 static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_missing)
 {
        char *ptr, *ntr;
+       const char *p;
        unsigned mode;
        enum object_type mode_type; /* object type derived from mode */
        enum object_type obj_type; /* object type derived from sha */
        char *path, *to_free = NULL;
-       unsigned char sha1[20];
+       struct object_id oid;
 
        ptr = buf;
        /*
@@ -85,9 +86,8 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss
                die("input format error: %s", buf);
        ptr = ntr + 1; /* type */
        ntr = strchr(ptr, ' ');
-       if (!ntr || buf + len <= ntr + 40 ||
-           ntr[41] != '\t' ||
-           get_sha1_hex(ntr + 1, sha1))
+       if (!ntr || parse_oid_hex(ntr + 1, &oid, &p) ||
+           *p != '\t')
                die("input format error: %s", buf);
 
        /* It is perfectly normal if we do not have a commit from a submodule */
@@ -116,12 +116,12 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss
        }
 
        /* Check the type of object identified by sha1 */
-       obj_type = sha1_object_info(sha1, NULL);
+       obj_type = oid_object_info(the_repository, &oid, NULL);
        if (obj_type < 0) {
                if (allow_missing) {
                        ; /* no problem - missing objects are presumed to be of the right type */
                } else {
-                       die("entry '%s' object %s is unavailable", path, sha1_to_hex(sha1));
+                       die("entry '%s' object %s is unavailable", path, oid_to_hex(&oid));
                }
        } else {
                if (obj_type != mode_type) {
@@ -131,11 +131,11 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss
                         * because the new tree entry will never be correct.
                         */
                        die("entry '%s' object %s is a %s but specified type was (%s)",
-                               path, sha1_to_hex(sha1), type_name(obj_type), type_name(mode_type));
+                               path, oid_to_hex(&oid), type_name(obj_type), type_name(mode_type));
                }
        }
 
-       append_to_tree(mode, sha1, path);
+       append_to_tree(mode, &oid, path);
        free(to_free);
 }
 
index 6d141f7a532c08e52f1f5f82330d046c60073f93..80bb967a63f154eb44ebc1a6dd7f833d01dce83e 100644 (file)
@@ -72,7 +72,6 @@ static const char *add_slash(const char *path)
        return path;
 }
 
-static struct lock_file lock_file;
 #define SUBMODULE_WITH_GITDIR ((const char *)1)
 
 static void prepare_move_submodule(const char *src, int first,
@@ -131,6 +130,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
        enum update_mode { BOTH = 0, WORKING_DIRECTORY, INDEX } *modes;
        struct stat st;
        struct string_list src_for_dst = STRING_LIST_INIT_NODUP;
+       struct lock_file lock_file = LOCK_INIT;
 
        git_config(git_default_config, NULL);
 
@@ -276,10 +276,12 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
                        die_errno(_("renaming '%s' failed"), src);
                }
                if (submodule_gitfile[i]) {
-                       if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR)
-                               connect_work_tree_and_git_dir(dst, submodule_gitfile[i]);
                        if (!update_path_in_gitmodules(src, dst))
                                gitmodules_modified = 1;
+                       if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR)
+                               connect_work_tree_and_git_dir(dst,
+                                                             submodule_gitfile[i],
+                                                             1);
                }
 
                if (mode == WORKING_DIRECTORY)
index 9e088ebd11dced248640df9e17adbbd8b9a73ffb..387ddf85d21a443f060dbb212fe95a983d9e4f58 100644 (file)
@@ -328,7 +328,7 @@ static void show_name(const struct object *obj,
        else if (allow_undefined)
                printf("undefined\n");
        else if (always)
-               printf("%s\n", find_unique_abbrev(oid->hash, DEFAULT_ABBREV));
+               printf("%s\n", find_unique_abbrev(oid, DEFAULT_ABBREV));
        else
                die("cannot describe '%s'", oid_to_hex(oid));
        strbuf_release(&buf);
index 6d2fda4a7d7ba89633f5cfee73f39cacb9f27898..6981e2d906f43b06cac5bd11cb0d627571be09d5 100644 (file)
@@ -14,7 +14,7 @@
 #include "blob.h"
 #include "pretty.h"
 #include "refs.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "run-command.h"
 #include "parse-options.h"
 #include "string-list.h"
@@ -118,11 +118,11 @@ static int list_each_note(const struct object_id *object_oid,
        return 0;
 }
 
-static void copy_obj_to_fd(int fd, const unsigned char *sha1)
+static void copy_obj_to_fd(int fd, const struct object_id *oid)
 {
        unsigned long size;
        enum object_type type;
-       char *buf = read_sha1_file(sha1, &type, &size);
+       char *buf = read_object_file(oid, &type, &size);
        if (buf) {
                if (size)
                        write_or_die(fd, buf, size);
@@ -162,7 +162,7 @@ static void write_commented_object(int fd, const struct object_id *object)
 }
 
 static void prepare_note_data(const struct object_id *object, struct note_data *d,
-               const unsigned char *old_note)
+               const struct object_id *old_note)
 {
        if (d->use_editor || !d->given) {
                int fd;
@@ -253,7 +253,7 @@ static int parse_reuse_arg(const struct option *opt, const char *arg, int unset)
 
        if (get_oid(arg, &object))
                die(_("failed to resolve '%s' as a valid ref."), arg);
-       if (!(buf = read_sha1_file(object.hash, &type, &len))) {
+       if (!(buf = read_object_file(&object, &type, &len))) {
                free(buf);
                die(_("failed to read object '%s'."), arg);
        }
@@ -457,11 +457,11 @@ static int add(int argc, const char **argv, const char *prefix)
                        oid_to_hex(&object));
        }
 
-       prepare_note_data(&object, &d, note ? note->hash : NULL);
+       prepare_note_data(&object, &d, note);
        if (d.buf.len || allow_empty) {
                write_note_data(&d, &new_note);
                if (add_note(t, &object, &new_note, combine_notes_overwrite))
-                       die("BUG: combine_notes_overwrite failed");
+                       BUG("combine_notes_overwrite failed");
                commit_notes(t, "Notes added by 'git notes add'");
        } else {
                fprintf(stderr, _("Removing note for object %s\n"),
@@ -544,7 +544,7 @@ static int copy(int argc, const char **argv, const char *prefix)
        }
 
        if (add_note(t, &object, from_note, combine_notes_overwrite))
-               die("BUG: combine_notes_overwrite failed");
+               BUG("combine_notes_overwrite failed");
        commit_notes(t, "Notes added by 'git notes copy'");
 out:
        free_notes(t);
@@ -602,13 +602,13 @@ static int append_edit(int argc, const char **argv, const char *prefix)
        t = init_notes_check(argv[0], NOTES_INIT_WRITABLE);
        note = get_note(t, &object);
 
-       prepare_note_data(&object, &d, edit && note ? note->hash : NULL);
+       prepare_note_data(&object, &d, edit && note ? note : NULL);
 
        if (note && !edit) {
                /* Append buf to previous note contents */
                unsigned long size;
                enum object_type type;
-               char *prev_buf = read_sha1_file(note->hash, &type, &size);
+               char *prev_buf = read_object_file(note, &type, &size);
 
                strbuf_grow(&d.buf, size + 1);
                if (d.buf.len && prev_buf && size)
@@ -621,7 +621,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
        if (d.buf.len || allow_empty) {
                write_note_data(&d, &new_note);
                if (add_note(t, &object, &new_note, combine_notes_overwrite))
-                       die("BUG: combine_notes_overwrite failed");
+                       BUG("combine_notes_overwrite failed");
                logmsg = xstrfmt("Notes added by 'git notes %s'", argv[0]);
        } else {
                fprintf(stderr, _("Removing note for object %s\n"),
@@ -778,13 +778,13 @@ static int merge(int argc, const char **argv, const char *prefix)
                           N_("resolve notes conflicts using the given strategy "
                              "(manual/ours/theirs/union/cat_sort_uniq)")),
                OPT_GROUP(N_("Committing unmerged notes")),
-               { OPTION_SET_INT, 0, "commit", &do_commit, NULL,
-                       N_("finalize notes merge by committing unmerged notes"),
-                       PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1},
+               OPT_SET_INT_F(0, "commit", &do_commit,
+                             N_("finalize notes merge by committing unmerged notes"),
+                             1, PARSE_OPT_NONEG),
                OPT_GROUP(N_("Aborting notes merge resolution")),
-               { OPTION_SET_INT, 0, "abort", &do_abort, NULL,
-                       N_("abort notes merge"),
-                       PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1},
+               OPT_SET_INT_F(0, "abort", &do_abort,
+                             N_("abort notes merge"),
+                             1, PARSE_OPT_NONEG),
                OPT_END()
        };
 
@@ -831,7 +831,7 @@ static int merge(int argc, const char **argv, const char *prefix)
                const char *short_ref = NULL;
 
                if (!skip_prefix(o.local_ref, "refs/notes/", &short_ref))
-                       die("BUG: local ref %s is outside of refs/notes/",
+                       BUG("local ref %s is outside of refs/notes/",
                            o.local_ref);
 
                strbuf_addf(&merge_key, "notes.%s.mergeStrategy", short_ref);
index e9d3cfb9e33a6b874751ac6acc5aac2361d4a58d..71056d8294d7f4bcfdcbc9bb292a5d17faf49252 100644 (file)
@@ -1,5 +1,6 @@
 #include "builtin.h"
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "attr.h"
 #include "object.h"
 #include "argv-array.h"
 #include "list.h"
 #include "packfile.h"
+#include "object-store.h"
+#include "dir.h"
+
+#define IN_PACK(obj) oe_in_pack(&to_pack, obj)
+#define SIZE(obj) oe_size(&to_pack, obj)
+#define SET_SIZE(obj,size) oe_set_size(&to_pack, obj, size)
+#define DELTA_SIZE(obj) oe_delta_size(&to_pack, obj)
+#define DELTA(obj) oe_delta(&to_pack, obj)
+#define DELTA_CHILD(obj) oe_delta_child(&to_pack, obj)
+#define DELTA_SIBLING(obj) oe_delta_sibling(&to_pack, obj)
+#define SET_DELTA(obj, val) oe_set_delta(&to_pack, obj, val)
+#define SET_DELTA_SIZE(obj, val) oe_set_delta_size(&to_pack, obj, val)
+#define SET_DELTA_CHILD(obj, val) oe_set_delta_child(&to_pack, obj, val)
+#define SET_DELTA_SIBLING(obj, val) oe_set_delta_sibling(&to_pack, obj, val)
 
 static const char *pack_usage[] = {
        N_("git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"),
@@ -43,7 +58,7 @@ static const char *pack_usage[] = {
 static struct packing_data to_pack;
 
 static struct pack_idx_entry **written_list;
-static uint32_t nr_result, nr_written;
+static uint32_t nr_result, nr_written, nr_seen;
 
 static int non_empty;
 static int reuse_delta = 1, reuse_object = 1;
@@ -53,7 +68,8 @@ static int pack_loose_unreachable;
 static int local;
 static int have_non_local_packs;
 static int incremental;
-static int ignore_packed_keep;
+static int ignore_packed_keep_on_disk;
+static int ignore_packed_keep_in_core;
 static int allow_ofs_delta;
 static struct pack_idx_option pack_idx_opts;
 static const char *base_name;
@@ -78,7 +94,7 @@ static uint16_t write_bitmap_options;
 static int exclude_promisor_objects;
 
 static unsigned long delta_cache_size = 0;
-static unsigned long max_delta_cache_size = 256 * 1024 * 1024;
+static unsigned long max_delta_cache_size = DEFAULT_DELTA_CACHE_SIZE;
 static unsigned long cache_max_small_delta_size = 1000;
 
 static unsigned long window_memory_limit = 0;
@@ -122,17 +138,17 @@ static void *get_delta(struct object_entry *entry)
        void *buf, *base_buf, *delta_buf;
        enum object_type type;
 
-       buf = read_sha1_file(entry->idx.oid.hash, &type, &size);
+       buf = read_object_file(&entry->idx.oid, &type, &size);
        if (!buf)
                die("unable to read %s", oid_to_hex(&entry->idx.oid));
-       base_buf = read_sha1_file(entry->delta->idx.oid.hash, &type,
-                                 &base_size);
+       base_buf = read_object_file(&DELTA(entry)->idx.oid, &type,
+                                   &base_size);
        if (!base_buf)
                die("unable to read %s",
-                   oid_to_hex(&entry->delta->idx.oid));
+                   oid_to_hex(&DELTA(entry)->idx.oid));
        delta_buf = diff_delta(base_buf, base_size,
                               buf, size, &delta_size, 0);
-       if (!delta_buf || delta_size != entry->delta_size)
+       if (!delta_buf || delta_size != DELTA_SIZE(entry))
                die("delta size changed");
        free(buf);
        free(base_buf);
@@ -263,15 +279,15 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent
        enum object_type type;
        void *buf;
        struct git_istream *st = NULL;
+       const unsigned hashsz = the_hash_algo->rawsz;
 
        if (!usable_delta) {
-               if (entry->type == OBJ_BLOB &&
-                   entry->size > big_file_threshold &&
-                   (st = open_istream(entry->idx.oid.hash, &type, &size, NULL)) != NULL)
+               if (oe_type(entry) == OBJ_BLOB &&
+                   oe_size_greater_than(&to_pack, entry, big_file_threshold) &&
+                   (st = open_istream(&entry->idx.oid, &type, &size, NULL)) != NULL)
                        buf = NULL;
                else {
-                       buf = read_sha1_file(entry->idx.oid.hash, &type,
-                                            &size);
+                       buf = read_object_file(&entry->idx.oid, &type, &size);
                        if (!buf)
                                die(_("unable to read %s"),
                                    oid_to_hex(&entry->idx.oid));
@@ -283,15 +299,15 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent
                FREE_AND_NULL(entry->delta_data);
                entry->z_delta_size = 0;
        } else if (entry->delta_data) {
-               size = entry->delta_size;
+               size = DELTA_SIZE(entry);
                buf = entry->delta_data;
                entry->delta_data = NULL;
-               type = (allow_ofs_delta && entry->delta->idx.offset) ?
+               type = (allow_ofs_delta && DELTA(entry)->idx.offset) ?
                        OBJ_OFS_DELTA : OBJ_REF_DELTA;
        } else {
                buf = get_delta(entry);
-               size = entry->delta_size;
-               type = (allow_ofs_delta && entry->delta->idx.offset) ?
+               size = DELTA_SIZE(entry);
+               type = (allow_ofs_delta && DELTA(entry)->idx.offset) ?
                        OBJ_OFS_DELTA : OBJ_REF_DELTA;
        }
 
@@ -315,12 +331,12 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent
                 * encoding of the relative offset for the delta
                 * base from this object's position in the pack.
                 */
-               off_t ofs = entry->idx.offset - entry->delta->idx.offset;
+               off_t ofs = entry->idx.offset - DELTA(entry)->idx.offset;
                unsigned pos = sizeof(dheader) - 1;
                dheader[pos] = ofs & 127;
                while (ofs >>= 7)
                        dheader[--pos] = 128 | (--ofs & 127);
-               if (limit && hdrlen + sizeof(dheader) - pos + datalen + 20 >= limit) {
+               if (limit && hdrlen + sizeof(dheader) - pos + datalen + hashsz >= limit) {
                        if (st)
                                close_istream(st);
                        free(buf);
@@ -332,19 +348,19 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent
        } else if (type == OBJ_REF_DELTA) {
                /*
                 * Deltas with a base reference contain
-                * an additional 20 bytes for the base sha1.
+                * additional bytes for the base object ID.
                 */
-               if (limit && hdrlen + 20 + datalen + 20 >= limit) {
+               if (limit && hdrlen + hashsz + datalen + hashsz >= limit) {
                        if (st)
                                close_istream(st);
                        free(buf);
                        return 0;
                }
                hashwrite(f, header, hdrlen);
-               hashwrite(f, entry->delta->idx.oid.hash, 20);
-               hdrlen += 20;
+               hashwrite(f, DELTA(entry)->idx.oid.hash, hashsz);
+               hdrlen += hashsz;
        } else {
-               if (limit && hdrlen + datalen + 20 >= limit) {
+               if (limit && hdrlen + datalen + hashsz >= limit) {
                        if (st)
                                close_istream(st);
                        free(buf);
@@ -367,21 +383,23 @@ static unsigned long write_no_reuse_object(struct hashfile *f, struct object_ent
 static off_t write_reuse_object(struct hashfile *f, struct object_entry *entry,
                                unsigned long limit, int usable_delta)
 {
-       struct packed_git *p = entry->in_pack;
+       struct packed_git *p = IN_PACK(entry);
        struct pack_window *w_curs = NULL;
        struct revindex_entry *revidx;
        off_t offset;
-       enum object_type type = entry->type;
+       enum object_type type = oe_type(entry);
        off_t datalen;
        unsigned char header[MAX_PACK_OBJECT_HEADER],
                      dheader[MAX_PACK_OBJECT_HEADER];
        unsigned hdrlen;
+       const unsigned hashsz = the_hash_algo->rawsz;
+       unsigned long entry_size = SIZE(entry);
 
-       if (entry->delta)
-               type = (allow_ofs_delta && entry->delta->idx.offset) ?
+       if (DELTA(entry))
+               type = (allow_ofs_delta && DELTA(entry)->idx.offset) ?
                        OBJ_OFS_DELTA : OBJ_REF_DELTA;
        hdrlen = encode_in_pack_object_header(header, sizeof(header),
-                                             type, entry->size);
+                                             type, entry_size);
 
        offset = entry->in_pack_offset;
        revidx = find_pack_revindex(p, offset);
@@ -398,7 +416,7 @@ static off_t write_reuse_object(struct hashfile *f, struct object_entry *entry,
        datalen -= entry->in_pack_header_size;
 
        if (!pack_to_stdout && p->index_version == 1 &&
-           check_pack_inflate(p, &w_curs, offset, datalen, entry->size)) {
+           check_pack_inflate(p, &w_curs, offset, datalen, entry_size)) {
                error("corrupt packed object for %s",
                      oid_to_hex(&entry->idx.oid));
                unuse_pack(&w_curs);
@@ -406,12 +424,12 @@ static off_t write_reuse_object(struct hashfile *f, struct object_entry *entry,
        }
 
        if (type == OBJ_OFS_DELTA) {
-               off_t ofs = entry->idx.offset - entry->delta->idx.offset;
+               off_t ofs = entry->idx.offset - DELTA(entry)->idx.offset;
                unsigned pos = sizeof(dheader) - 1;
                dheader[pos] = ofs & 127;
                while (ofs >>= 7)
                        dheader[--pos] = 128 | (--ofs & 127);
-               if (limit && hdrlen + sizeof(dheader) - pos + datalen + 20 >= limit) {
+               if (limit && hdrlen + sizeof(dheader) - pos + datalen + hashsz >= limit) {
                        unuse_pack(&w_curs);
                        return 0;
                }
@@ -420,16 +438,16 @@ static off_t write_reuse_object(struct hashfile *f, struct object_entry *entry,
                hdrlen += sizeof(dheader) - pos;
                reused_delta++;
        } else if (type == OBJ_REF_DELTA) {
-               if (limit && hdrlen + 20 + datalen + 20 >= limit) {
+               if (limit && hdrlen + hashsz + datalen + hashsz >= limit) {
                        unuse_pack(&w_curs);
                        return 0;
                }
                hashwrite(f, header, hdrlen);
-               hashwrite(f, entry->delta->idx.oid.hash, 20);
-               hdrlen += 20;
+               hashwrite(f, DELTA(entry)->idx.oid.hash, hashsz);
+               hdrlen += hashsz;
                reused_delta++;
        } else {
-               if (limit && hdrlen + datalen + 20 >= limit) {
+               if (limit && hdrlen + datalen + hashsz >= limit) {
                        unuse_pack(&w_curs);
                        return 0;
                }
@@ -465,28 +483,29 @@ static off_t write_object(struct hashfile *f,
        else
                limit = pack_size_limit - write_offset;
 
-       if (!entry->delta)
+       if (!DELTA(entry))
                usable_delta = 0;       /* no delta */
        else if (!pack_size_limit)
               usable_delta = 1;        /* unlimited packfile */
-       else if (entry->delta->idx.offset == (off_t)-1)
+       else if (DELTA(entry)->idx.offset == (off_t)-1)
                usable_delta = 0;       /* base was written to another pack */
-       else if (entry->delta->idx.offset)
+       else if (DELTA(entry)->idx.offset)
                usable_delta = 1;       /* base already exists in this pack */
        else
                usable_delta = 0;       /* base could end up in another pack */
 
        if (!reuse_object)
                to_reuse = 0;   /* explicit */
-       else if (!entry->in_pack)
+       else if (!IN_PACK(entry))
                to_reuse = 0;   /* can't reuse what we don't have */
-       else if (entry->type == OBJ_REF_DELTA || entry->type == OBJ_OFS_DELTA)
+       else if (oe_type(entry) == OBJ_REF_DELTA ||
+                oe_type(entry) == OBJ_OFS_DELTA)
                                /* check_object() decided it for us ... */
                to_reuse = usable_delta;
                                /* ... but pack split may override that */
-       else if (entry->type != entry->in_pack_type)
+       else if (oe_type(entry) != entry->in_pack_type)
                to_reuse = 0;   /* pack has delta which is unusable */
-       else if (entry->delta)
+       else if (DELTA(entry))
                to_reuse = 0;   /* we want to pack afresh */
        else
                to_reuse = 1;   /* we have it in-pack undeltified,
@@ -538,12 +557,12 @@ static enum write_one_status write_one(struct hashfile *f,
        }
 
        /* if we are deltified, write out base object first. */
-       if (e->delta) {
+       if (DELTA(e)) {
                e->idx.offset = 1; /* now recurse */
-               switch (write_one(f, e->delta, offset)) {
+               switch (write_one(f, DELTA(e), offset)) {
                case WRITE_ONE_RECURSIVE:
                        /* we cannot depend on this one */
-                       e->delta = NULL;
+                       SET_DELTA(e, NULL);
                        break;
                default:
                        break;
@@ -605,34 +624,34 @@ static void add_descendants_to_write_order(struct object_entry **wo,
                        /* add this node... */
                        add_to_write_order(wo, endp, e);
                        /* all its siblings... */
-                       for (s = e->delta_sibling; s; s = s->delta_sibling) {
+                       for (s = DELTA_SIBLING(e); s; s = DELTA_SIBLING(s)) {
                                add_to_write_order(wo, endp, s);
                        }
                }
                /* drop down a level to add left subtree nodes if possible */
-               if (e->delta_child) {
+               if (DELTA_CHILD(e)) {
                        add_to_order = 1;
-                       e = e->delta_child;
+                       e = DELTA_CHILD(e);
                } else {
                        add_to_order = 0;
                        /* our sibling might have some children, it is next */
-                       if (e->delta_sibling) {
-                               e = e->delta_sibling;
+                       if (DELTA_SIBLING(e)) {
+                               e = DELTA_SIBLING(e);
                                continue;
                        }
                        /* go back to our parent node */
-                       e = e->delta;
-                       while (e && !e->delta_sibling) {
+                       e = DELTA(e);
+                       while (e && !DELTA_SIBLING(e)) {
                                /* we're on the right side of a subtree, keep
                                 * going up until we can go right again */
-                               e = e->delta;
+                               e = DELTA(e);
                        }
                        if (!e) {
                                /* done- we hit our original root node */
                                return;
                        }
                        /* pass it off to sibling at this level */
-                       e = e->delta_sibling;
+                       e = DELTA_SIBLING(e);
                }
        };
 }
@@ -643,7 +662,7 @@ static void add_family_to_write_order(struct object_entry **wo,
 {
        struct object_entry *root;
 
-       for (root = e; root->delta; root = root->delta)
+       for (root = e; DELTA(root); root = DELTA(root))
                ; /* nothing */
        add_descendants_to_write_order(wo, endp, root);
 }
@@ -658,8 +677,8 @@ static struct object_entry **compute_write_order(void)
        for (i = 0; i < to_pack.nr_objects; i++) {
                objects[i].tagged = 0;
                objects[i].filled = 0;
-               objects[i].delta_child = NULL;
-               objects[i].delta_sibling = NULL;
+               SET_DELTA_CHILD(&objects[i], NULL);
+               SET_DELTA_SIBLING(&objects[i], NULL);
        }
 
        /*
@@ -669,11 +688,11 @@ static struct object_entry **compute_write_order(void)
         */
        for (i = to_pack.nr_objects; i > 0;) {
                struct object_entry *e = &objects[--i];
-               if (!e->delta)
+               if (!DELTA(e))
                        continue;
                /* Mark me as the first child */
-               e->delta_sibling = e->delta->delta_child;
-               e->delta->delta_child = e;
+               e->delta_sibling_idx = DELTA(e)->delta_child_idx;
+               SET_DELTA_CHILD(DELTA(e), e);
        }
 
        /*
@@ -705,8 +724,8 @@ static struct object_entry **compute_write_order(void)
         * And then all remaining commits and tags.
         */
        for (i = last_untagged; i < to_pack.nr_objects; i++) {
-               if (objects[i].type != OBJ_COMMIT &&
-                   objects[i].type != OBJ_TAG)
+               if (oe_type(&objects[i]) != OBJ_COMMIT &&
+                   oe_type(&objects[i]) != OBJ_TAG)
                        continue;
                add_to_write_order(wo, &wo_end, &objects[i]);
        }
@@ -715,7 +734,7 @@ static struct object_entry **compute_write_order(void)
         * And then all the trees.
         */
        for (i = last_untagged; i < to_pack.nr_objects; i++) {
-               if (objects[i].type != OBJ_TREE)
+               if (oe_type(&objects[i]) != OBJ_TREE)
                        continue;
                add_to_write_order(wo, &wo_end, &objects[i]);
        }
@@ -752,7 +771,7 @@ static off_t write_reused_pack(struct hashfile *f)
                die_errno("unable to seek in reused packfile");
 
        if (reuse_packfile_offset < 0)
-               reuse_packfile_offset = reuse_packfile->pack_size - 20;
+               reuse_packfile_offset = reuse_packfile->pack_size - the_hash_algo->rawsz;
 
        total = to_write = reuse_packfile_offset - sizeof(struct pack_header);
 
@@ -837,11 +856,11 @@ static void write_pack_file(void)
                 * If so, rewrite it like in fast-import
                 */
                if (pack_to_stdout) {
-                       hashclose(f, oid.hash, CSUM_CLOSE);
+                       finalize_hashfile(f, oid.hash, CSUM_HASH_IN_STREAM | CSUM_CLOSE);
                } else if (nr_written == nr_remaining) {
-                       hashclose(f, oid.hash, CSUM_FSYNC);
+                       finalize_hashfile(f, oid.hash, CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE);
                } else {
-                       int fd = hashclose(f, oid.hash, 0);
+                       int fd = finalize_hashfile(f, oid.hash, 0);
                        fixup_pack_header_footer(fd, oid.hash, pack_tmp_name,
                                                 nr_written, oid.hash, offset);
                        close(fd);
@@ -878,7 +897,8 @@ static void write_pack_file(void)
 
                        if (write_bitmap_index) {
                                bitmap_writer_set_checksum(oid.hash);
-                               bitmap_writer_build_type_index(written_list, nr_written);
+                               bitmap_writer_build_type_index(
+                                       &to_pack, written_list, nr_written);
                        }
 
                        finish_tmp_packfile(&tmpname, pack_tmp_name,
@@ -982,13 +1002,16 @@ static int want_found_object(int exclude, struct packed_git *p)
         * Otherwise, we signal "-1" at the end to tell the caller that we do
         * not know either way, and it needs to check more packs.
         */
-       if (!ignore_packed_keep &&
+       if (!ignore_packed_keep_on_disk &&
+           !ignore_packed_keep_in_core &&
            (!local || !have_non_local_packs))
                return 1;
 
        if (local && !p->pack_local)
                return 0;
-       if (ignore_packed_keep && p->pack_local && p->pack_keep)
+       if (p->pack_local &&
+           ((ignore_packed_keep_on_disk && p->pack_keep) ||
+            (ignore_packed_keep_in_core && p->pack_keep_in_core)))
                return 0;
 
        /* we don't know yet; keep looking for more packs */
@@ -1012,7 +1035,7 @@ static int want_object_in_pack(const struct object_id *oid,
        int want;
        struct list_head *pos;
 
-       if (!exclude && local && has_loose_object_nonlocal(oid->hash))
+       if (!exclude && local && has_loose_object_nonlocal(oid))
                return 0;
 
        /*
@@ -1025,8 +1048,7 @@ static int want_object_in_pack(const struct object_id *oid,
                if (want != -1)
                        return want;
        }
-
-       list_for_each(pos, &packed_git_mru) {
+       list_for_each(pos, get_packed_git_mru(the_repository)) {
                struct packed_git *p = list_entry(pos, struct packed_git, mru);
                off_t offset;
 
@@ -1044,7 +1066,8 @@ static int want_object_in_pack(const struct object_id *oid,
                        }
                        want = want_found_object(exclude, p);
                        if (!exclude && want > 0)
-                               list_move(&p->mru, &packed_git_mru);
+                               list_move(&p->mru,
+                                         get_packed_git_mru(the_repository));
                        if (want != -1)
                                return want;
                }
@@ -1066,14 +1089,13 @@ static void create_object_entry(const struct object_id *oid,
 
        entry = packlist_alloc(&to_pack, oid->hash, index_pos);
        entry->hash = hash;
-       if (type)
-               entry->type = type;
+       oe_set_type(entry, type);
        if (exclude)
                entry->preferred_base = 1;
        else
                nr_result++;
        if (found_pack) {
-               entry->in_pack = found_pack;
+               oe_set_in_pack(&to_pack, entry, found_pack);
                entry->in_pack_offset = found_offset;
        }
 
@@ -1091,6 +1113,8 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,
        off_t found_offset = 0;
        uint32_t index_pos;
 
+       display_progress(progress_state, ++nr_seen);
+
        if (have_duplicate_entry(oid, exclude, &index_pos))
                return 0;
 
@@ -1106,8 +1130,6 @@ static int add_object_entry(const struct object_id *oid, enum object_type type,
        create_object_entry(oid, type, pack_name_hash(name),
                            exclude, name && no_try_delta(name),
                            index_pos, found_pack, found_offset);
-
-       display_progress(progress_state, nr_result);
        return 1;
 }
 
@@ -1118,6 +1140,8 @@ static int add_object_entry_from_bitmap(const struct object_id *oid,
 {
        uint32_t index_pos;
 
+       display_progress(progress_state, ++nr_seen);
+
        if (have_duplicate_entry(oid, 0, &index_pos))
                return 0;
 
@@ -1125,8 +1149,6 @@ static int add_object_entry_from_bitmap(const struct object_id *oid,
                return 0;
 
        create_object_entry(oid, type, name_hash, 0, 0, index_pos, pack, offset);
-
-       display_progress(progress_state, nr_result);
        return 1;
 }
 
@@ -1190,7 +1212,7 @@ static struct pbase_tree_cache *pbase_tree_get(const struct object_id *oid)
        /* Did not find one.  Either we got a bogus request or
         * we need to read and perhaps cache.
         */
-       data = read_sha1_file(oid->hash, &type, &size);
+       data = read_object_file(oid, &type, &size);
        if (!data)
                return NULL;
        if (type != OBJ_TREE) {
@@ -1351,7 +1373,7 @@ static void add_preferred_base(struct object_id *oid)
        if (window <= num_preferred_base++)
                return;
 
-       data = read_object_with_reference(oid->hash, tree_type, &size, tree_oid.hash);
+       data = read_object_with_reference(oid, tree_type, &size, &tree_oid);
        if (!data)
                return;
 
@@ -1398,8 +1420,10 @@ static void cleanup_preferred_base(void)
 
 static void check_object(struct object_entry *entry)
 {
-       if (entry->in_pack) {
-               struct packed_git *p = entry->in_pack;
+       unsigned long canonical_size;
+
+       if (IN_PACK(entry)) {
+               struct packed_git *p = IN_PACK(entry);
                struct pack_window *w_curs = NULL;
                const unsigned char *base_ref = NULL;
                struct object_entry *base_entry;
@@ -1407,6 +1431,8 @@ static void check_object(struct object_entry *entry)
                unsigned long avail;
                off_t ofs;
                unsigned char *buf, c;
+               enum object_type type;
+               unsigned long in_pack_size;
 
                buf = use_pack(p, &w_curs, entry->in_pack_offset, &avail);
 
@@ -1415,11 +1441,15 @@ static void check_object(struct object_entry *entry)
                 * since non-delta representations could still be reused.
                 */
                used = unpack_object_header_buffer(buf, avail,
-                                                  &entry->in_pack_type,
-                                                  &entry->size);
+                                                  &type,
+                                                  &in_pack_size);
                if (used == 0)
                        goto give_up;
 
+               if (type < 0)
+                       BUG("invalid type %d", type);
+               entry->in_pack_type = type;
+
                /*
                 * Determine if this is a delta and if so whether we can
                 * reuse it or not.  Otherwise let's find out as cheaply as
@@ -1428,9 +1458,10 @@ static void check_object(struct object_entry *entry)
                switch (entry->in_pack_type) {
                default:
                        /* Not a delta hence we've already got all we need. */
-                       entry->type = entry->in_pack_type;
+                       oe_set_type(entry, entry->in_pack_type);
+                       SET_SIZE(entry, in_pack_size);
                        entry->in_pack_header_size = used;
-                       if (entry->type < OBJ_COMMIT || entry->type > OBJ_BLOB)
+                       if (oe_type(entry) < OBJ_COMMIT || oe_type(entry) > OBJ_BLOB)
                                goto give_up;
                        unuse_pack(&w_curs);
                        return;
@@ -1438,7 +1469,7 @@ static void check_object(struct object_entry *entry)
                        if (reuse_delta && !entry->preferred_base)
                                base_ref = use_pack(p, &w_curs,
                                                entry->in_pack_offset + used, NULL);
-                       entry->in_pack_header_size = used + 20;
+                       entry->in_pack_header_size = used + the_hash_algo->rawsz;
                        break;
                case OBJ_OFS_DELTA:
                        buf = use_pack(p, &w_curs,
@@ -1484,25 +1515,29 @@ static void check_object(struct object_entry *entry)
                         * deltify other objects against, in order to avoid
                         * circular deltas.
                         */
-                       entry->type = entry->in_pack_type;
-                       entry->delta = base_entry;
-                       entry->delta_size = entry->size;
-                       entry->delta_sibling = base_entry->delta_child;
-                       base_entry->delta_child = entry;
+                       oe_set_type(entry, entry->in_pack_type);
+                       SET_SIZE(entry, in_pack_size); /* delta size */
+                       SET_DELTA(entry, base_entry);
+                       SET_DELTA_SIZE(entry, in_pack_size);
+                       entry->delta_sibling_idx = base_entry->delta_child_idx;
+                       SET_DELTA_CHILD(base_entry, entry);
                        unuse_pack(&w_curs);
                        return;
                }
 
-               if (entry->type) {
+               if (oe_type(entry)) {
+                       off_t delta_pos;
+
                        /*
                         * This must be a delta and we already know what the
                         * final object type is.  Let's extract the actual
                         * object size from the delta header.
                         */
-                       entry->size = get_size_from_delta(p, &w_curs,
-                                       entry->in_pack_offset + entry->in_pack_header_size);
-                       if (entry->size == 0)
+                       delta_pos = entry->in_pack_offset + entry->in_pack_header_size;
+                       canonical_size = get_size_from_delta(p, &w_curs, delta_pos);
+                       if (canonical_size == 0)
                                goto give_up;
+                       SET_SIZE(entry, canonical_size);
                        unuse_pack(&w_curs);
                        return;
                }
@@ -1516,27 +1551,34 @@ static void check_object(struct object_entry *entry)
                unuse_pack(&w_curs);
        }
 
-       entry->type = sha1_object_info(entry->idx.oid.hash, &entry->size);
-       /*
-        * The error condition is checked in prepare_pack().  This is
-        * to permit a missing preferred base object to be ignored
-        * as a preferred base.  Doing so can result in a larger
-        * pack file, but the transfer will still take place.
-        */
+       oe_set_type(entry,
+                   oid_object_info(the_repository, &entry->idx.oid, &canonical_size));
+       if (entry->type_valid) {
+               SET_SIZE(entry, canonical_size);
+       } else {
+               /*
+                * Bad object type is checked in prepare_pack().  This is
+                * to permit a missing preferred base object to be ignored
+                * as a preferred base.  Doing so can result in a larger
+                * pack file, but the transfer will still take place.
+                */
+       }
 }
 
 static int pack_offset_sort(const void *_a, const void *_b)
 {
        const struct object_entry *a = *(struct object_entry **)_a;
        const struct object_entry *b = *(struct object_entry **)_b;
+       const struct packed_git *a_in_pack = IN_PACK(a);
+       const struct packed_git *b_in_pack = IN_PACK(b);
 
        /* avoid filesystem trashing with loose objects */
-       if (!a->in_pack && !b->in_pack)
+       if (!a_in_pack && !b_in_pack)
                return oidcmp(&a->idx.oid, &b->idx.oid);
 
-       if (a->in_pack < b->in_pack)
+       if (a_in_pack < b_in_pack)
                return -1;
-       if (a->in_pack > b->in_pack)
+       if (a_in_pack > b_in_pack)
                return 1;
        return a->in_pack_offset < b->in_pack_offset ? -1 :
                        (a->in_pack_offset > b->in_pack_offset);
@@ -1557,30 +1599,37 @@ static int pack_offset_sort(const void *_a, const void *_b)
  */
 static void drop_reused_delta(struct object_entry *entry)
 {
-       struct object_entry **p = &entry->delta->delta_child;
+       unsigned *idx = &to_pack.objects[entry->delta_idx - 1].delta_child_idx;
        struct object_info oi = OBJECT_INFO_INIT;
+       enum object_type type;
+       unsigned long size;
 
-       while (*p) {
-               if (*p == entry)
-                       *p = (*p)->delta_sibling;
+       while (*idx) {
+               struct object_entry *oe = &to_pack.objects[*idx - 1];
+
+               if (oe == entry)
+                       *idx = oe->delta_sibling_idx;
                else
-                       p = &(*p)->delta_sibling;
+                       idx = &oe->delta_sibling_idx;
        }
-       entry->delta = NULL;
+       SET_DELTA(entry, NULL);
        entry->depth = 0;
 
-       oi.sizep = &entry->size;
-       oi.typep = &entry->type;
-       if (packed_object_info(entry->in_pack, entry->in_pack_offset, &oi) < 0) {
+       oi.sizep = &size;
+       oi.typep = &type;
+       if (packed_object_info(the_repository, IN_PACK(entry), entry->in_pack_offset, &oi) < 0) {
                /*
                 * We failed to get the info from this pack for some reason;
                 * fall back to sha1_object_info, which may find another copy.
-                * And if that fails, the error will be recorded in entry->type
+                * And if that fails, the error will be recorded in oe_type(entry)
                 * and dealt with in prepare_pack().
                 */
-               entry->type = sha1_object_info(entry->idx.oid.hash,
-                                              &entry->size);
+               oe_set_type(entry,
+                           oid_object_info(the_repository, &entry->idx.oid, &size));
+       } else {
+               oe_set_type(entry, type);
        }
+       SET_SIZE(entry, size);
 }
 
 /*
@@ -1604,7 +1653,7 @@ static void break_delta_chains(struct object_entry *entry)
 
        for (cur = entry, total_depth = 0;
             cur;
-            cur = cur->delta, total_depth++) {
+            cur = DELTA(cur), total_depth++) {
                if (cur->dfs_state == DFS_DONE) {
                        /*
                         * We've already seen this object and know it isn't
@@ -1621,7 +1670,7 @@ static void break_delta_chains(struct object_entry *entry)
                 * is a bug.
                 */
                if (cur->dfs_state != DFS_NONE)
-                       die("BUG: confusing delta dfs state in first pass: %d",
+                       BUG("confusing delta dfs state in first pass: %d",
                            cur->dfs_state);
 
                /*
@@ -1629,7 +1678,7 @@ static void break_delta_chains(struct object_entry *entry)
                 * it's not a delta, we're done traversing, but we'll mark it
                 * done to save time on future traversals.
                 */
-               if (!cur->delta) {
+               if (!DELTA(cur)) {
                        cur->dfs_state = DFS_DONE;
                        break;
                }
@@ -1652,7 +1701,7 @@ static void break_delta_chains(struct object_entry *entry)
                 * We keep all commits in the chain that we examined.
                 */
                cur->dfs_state = DFS_ACTIVE;
-               if (cur->delta->dfs_state == DFS_ACTIVE) {
+               if (DELTA(cur)->dfs_state == DFS_ACTIVE) {
                        drop_reused_delta(cur);
                        cur->dfs_state = DFS_DONE;
                        break;
@@ -1667,7 +1716,7 @@ static void break_delta_chains(struct object_entry *entry)
         * an extra "next" pointer to keep going after we reset cur->delta.
         */
        for (cur = entry; cur; cur = next) {
-               next = cur->delta;
+               next = DELTA(cur);
 
                /*
                 * We should have a chain of zero or more ACTIVE states down to
@@ -1678,7 +1727,7 @@ static void break_delta_chains(struct object_entry *entry)
                if (cur->dfs_state == DFS_DONE)
                        break;
                else if (cur->dfs_state != DFS_ACTIVE)
-                       die("BUG: confusing delta dfs state in second pass: %d",
+                       BUG("confusing delta dfs state in second pass: %d",
                            cur->dfs_state);
 
                /*
@@ -1712,6 +1761,10 @@ static void get_object_details(void)
        uint32_t i;
        struct object_entry **sorted_by_offset;
 
+       if (progress)
+               progress_state = start_progress(_("Counting objects"),
+                                               to_pack.nr_objects);
+
        sorted_by_offset = xcalloc(to_pack.nr_objects, sizeof(struct object_entry *));
        for (i = 0; i < to_pack.nr_objects; i++)
                sorted_by_offset[i] = to_pack.objects + i;
@@ -1720,9 +1773,12 @@ static void get_object_details(void)
        for (i = 0; i < to_pack.nr_objects; i++) {
                struct object_entry *entry = sorted_by_offset[i];
                check_object(entry);
-               if (big_file_threshold < entry->size)
+               if (entry->type_valid &&
+                   oe_size_greater_than(&to_pack, entry, big_file_threshold))
                        entry->no_try_delta = 1;
+               display_progress(progress_state, i + 1);
        }
+       stop_progress(&progress_state);
 
        /*
         * This must happen in a second pass, since we rely on the delta
@@ -1747,10 +1803,14 @@ static int type_size_sort(const void *_a, const void *_b)
 {
        const struct object_entry *a = *(struct object_entry **)_a;
        const struct object_entry *b = *(struct object_entry **)_b;
+       enum object_type a_type = oe_type(a);
+       enum object_type b_type = oe_type(b);
+       unsigned long a_size = SIZE(a);
+       unsigned long b_size = SIZE(b);
 
-       if (a->type > b->type)
+       if (a_type > b_type)
                return -1;
-       if (a->type < b->type)
+       if (a_type < b_type)
                return 1;
        if (a->hash > b->hash)
                return -1;
@@ -1760,9 +1820,9 @@ static int type_size_sort(const void *_a, const void *_b)
                return -1;
        if (a->preferred_base < b->preferred_base)
                return 1;
-       if (a->size > b->size)
+       if (a_size > b_size)
                return -1;
-       if (a->size < b->size)
+       if (a_size < b_size)
                return 1;
        return a < b ? -1 : (a > b);  /* newest first */
 }
@@ -1815,6 +1875,46 @@ static pthread_mutex_t progress_mutex;
 
 #endif
 
+/*
+ * Return the size of the object without doing any delta
+ * reconstruction (so non-deltas are true object sizes, but deltas
+ * return the size of the delta data).
+ */
+unsigned long oe_get_size_slow(struct packing_data *pack,
+                              const struct object_entry *e)
+{
+       struct packed_git *p;
+       struct pack_window *w_curs;
+       unsigned char *buf;
+       enum object_type type;
+       unsigned long used, avail, size;
+
+       if (e->type_ != OBJ_OFS_DELTA && e->type_ != OBJ_REF_DELTA) {
+               read_lock();
+               if (oid_object_info(the_repository, &e->idx.oid, &size) < 0)
+                       die(_("unable to get size of %s"),
+                           oid_to_hex(&e->idx.oid));
+               read_unlock();
+               return size;
+       }
+
+       p = oe_in_pack(pack, e);
+       if (!p)
+               BUG("when e->type is a delta, it must belong to a pack");
+
+       read_lock();
+       w_curs = NULL;
+       buf = use_pack(p, &w_curs, e->in_pack_offset, &avail);
+       used = unpack_object_header_buffer(buf, avail, &type, &size);
+       if (used == 0)
+               die(_("unable to parse object header of %s"),
+                   oid_to_hex(&e->idx.oid));
+
+       unuse_pack(&w_curs);
+       read_unlock();
+       return size;
+}
+
 static int try_delta(struct unpacked *trg, struct unpacked *src,
                     unsigned max_depth, unsigned long *mem_usage)
 {
@@ -1826,7 +1926,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
        void *delta_buf;
 
        /* Don't bother doing diffs between different types */
-       if (trg_entry->type != src_entry->type)
+       if (oe_type(trg_entry) != oe_type(src_entry))
                return -1;
 
        /*
@@ -1837,8 +1937,8 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
         * it, we will still save the transfer cost, as we already know
         * the other side has it and we won't send src_entry at all.
         */
-       if (reuse_delta && trg_entry->in_pack &&
-           trg_entry->in_pack == src_entry->in_pack &&
+       if (reuse_delta && IN_PACK(trg_entry) &&
+           IN_PACK(trg_entry) == IN_PACK(src_entry) &&
            !src_entry->preferred_base &&
            trg_entry->in_pack_type != OBJ_REF_DELTA &&
            trg_entry->in_pack_type != OBJ_OFS_DELTA)
@@ -1849,19 +1949,19 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
                return 0;
 
        /* Now some size filtering heuristics. */
-       trg_size = trg_entry->size;
-       if (!trg_entry->delta) {
-               max_size = trg_size/2 - 20;
+       trg_size = SIZE(trg_entry);
+       if (!DELTA(trg_entry)) {
+               max_size = trg_size/2 - the_hash_algo->rawsz;
                ref_depth = 1;
        } else {
-               max_size = trg_entry->delta_size;
+               max_size = DELTA_SIZE(trg_entry);
                ref_depth = trg->depth;
        }
        max_size = (uint64_t)max_size * (max_depth - src->depth) /
                                                (max_depth - ref_depth + 1);
        if (max_size == 0)
                return 0;
-       src_size = src_entry->size;
+       src_size = SIZE(src_entry);
        sizediff = src_size < trg_size ? trg_size - src_size : 0;
        if (sizediff >= max_size)
                return 0;
@@ -1871,8 +1971,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
        /* Load data if not already done */
        if (!trg->data) {
                read_lock();
-               trg->data = read_sha1_file(trg_entry->idx.oid.hash, &type,
-                                          &sz);
+               trg->data = read_object_file(&trg_entry->idx.oid, &type, &sz);
                read_unlock();
                if (!trg->data)
                        die("object %s cannot be read",
@@ -1885,8 +1984,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
        }
        if (!src->data) {
                read_lock();
-               src->data = read_sha1_file(src_entry->idx.oid.hash, &type,
-                                          &sz);
+               src->data = read_object_file(&src_entry->idx.oid, &type, &sz);
                read_unlock();
                if (!src->data) {
                        if (src_entry->preferred_base) {
@@ -1925,10 +2023,14 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
        delta_buf = create_delta(src->index, trg->data, trg_size, &delta_size, max_size);
        if (!delta_buf)
                return 0;
+       if (delta_size >= (1U << OE_DELTA_SIZE_BITS)) {
+               free(delta_buf);
+               return 0;
+       }
 
-       if (trg_entry->delta) {
+       if (DELTA(trg_entry)) {
                /* Prefer only shallower same-sized deltas. */
-               if (delta_size == trg_entry->delta_size &&
+               if (delta_size == DELTA_SIZE(trg_entry) &&
                    src->depth + 1 >= trg->depth) {
                        free(delta_buf);
                        return 0;
@@ -1943,7 +2045,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
        free(trg_entry->delta_data);
        cache_lock();
        if (trg_entry->delta_data) {
-               delta_cache_size -= trg_entry->delta_size;
+               delta_cache_size -= DELTA_SIZE(trg_entry);
                trg_entry->delta_data = NULL;
        }
        if (delta_cacheable(src_size, trg_size, delta_size)) {
@@ -1955,8 +2057,8 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
                free(delta_buf);
        }
 
-       trg_entry->delta = src_entry;
-       trg_entry->delta_size = delta_size;
+       SET_DELTA(trg_entry, src_entry);
+       SET_DELTA_SIZE(trg_entry, delta_size);
        trg->depth = src->depth + 1;
 
        return 1;
@@ -1964,13 +2066,13 @@ static int try_delta(struct unpacked *trg, struct unpacked *src,
 
 static unsigned int check_delta_limit(struct object_entry *me, unsigned int n)
 {
-       struct object_entry *child = me->delta_child;
+       struct object_entry *child = DELTA_CHILD(me);
        unsigned int m = n;
        while (child) {
                unsigned int c = check_delta_limit(child, n + 1);
                if (m < c)
                        m = c;
-               child = child->delta_sibling;
+               child = DELTA_SIBLING(child);
        }
        return m;
 }
@@ -1981,7 +2083,7 @@ static unsigned long free_unpacked(struct unpacked *n)
        free_delta_index(n->index);
        n->index = NULL;
        if (n->data) {
-               freed_mem += n->entry->size;
+               freed_mem += SIZE(n->entry);
                FREE_AND_NULL(n->data);
        }
        n->entry = NULL;
@@ -2039,7 +2141,7 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
                 * otherwise they would become too deep.
                 */
                max_depth = depth;
-               if (entry->delta_child) {
+               if (DELTA_CHILD(entry)) {
                        max_depth -= check_delta_limit(entry, 0);
                        if (max_depth <= 0)
                                goto next;
@@ -2077,19 +2179,26 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
                 * between writes at that moment.
                 */
                if (entry->delta_data && !pack_to_stdout) {
-                       entry->z_delta_size = do_compress(&entry->delta_data,
-                                                         entry->delta_size);
-                       cache_lock();
-                       delta_cache_size -= entry->delta_size;
-                       delta_cache_size += entry->z_delta_size;
-                       cache_unlock();
+                       unsigned long size;
+
+                       size = do_compress(&entry->delta_data, DELTA_SIZE(entry));
+                       if (size < (1U << OE_Z_DELTA_BITS)) {
+                               entry->z_delta_size = size;
+                               cache_lock();
+                               delta_cache_size -= DELTA_SIZE(entry);
+                               delta_cache_size += entry->z_delta_size;
+                               cache_unlock();
+                       } else {
+                               FREE_AND_NULL(entry->delta_data);
+                               entry->z_delta_size = 0;
+                       }
                }
 
                /* if we made n a delta, and if n is already at max
                 * depth, leaving it in the window is pointless.  we
                 * should evict it first.
                 */
-               if (entry->delta && max_depth <= n->depth)
+               if (DELTA(entry) && max_depth <= n->depth)
                        continue;
 
                /*
@@ -2097,7 +2206,7 @@ static void find_deltas(struct object_entry **list, unsigned *list_size,
                 * currently deltified object, to keep it longer.  It will
                 * be the first base object to be attempted next.
                 */
-               if (entry->delta) {
+               if (DELTA(entry)) {
                        struct unpacked swap = array[best_base];
                        int dist = (window + idx - best_base) % window;
                        int dst = best_base;
@@ -2418,13 +2527,14 @@ static void prepare_pack(int window, int depth)
        for (i = 0; i < to_pack.nr_objects; i++) {
                struct object_entry *entry = to_pack.objects + i;
 
-               if (entry->delta)
+               if (DELTA(entry))
                        /* This happens if we decided to reuse existing
                         * delta from a pack.  "reuse_delta &&" is implied.
                         */
                        continue;
 
-               if (entry->size < 50)
+               if (!entry->type_valid ||
+                   oe_size_less_than(&to_pack, entry, 50))
                        continue;
 
                if (entry->no_try_delta)
@@ -2432,11 +2542,11 @@ static void prepare_pack(int window, int depth)
 
                if (!entry->preferred_base) {
                        nr_deltas++;
-                       if (entry->type < 0)
+                       if (oe_type(entry) < 0)
                                die("unable to get type of object %s",
                                    oid_to_hex(&entry->idx.oid));
                } else {
-                       if (entry->type < 0) {
+                       if (oe_type(entry) < 0) {
                                /*
                                 * This object is not found, but we
                                 * don't have to include it anyway.
@@ -2545,7 +2655,7 @@ static void read_object_list_from_stdin(void)
                        die("expected object ID, got garbage:\n %s", line);
 
                add_preferred_base_object(p + 1);
-               add_object_entry(&oid, 0, p + 1, 0);
+               add_object_entry(&oid, OBJ_NONE, p + 1, 0);
        }
 }
 
@@ -2674,11 +2784,11 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
 
        memset(&in_pack, 0, sizeof(in_pack));
 
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                struct object_id oid;
                struct object *o;
 
-               if (!p->pack_local || p->pack_keep)
+               if (!p->pack_local || p->pack_keep || p->pack_keep_in_core)
                        continue;
                if (open_pack_index(p))
                        die("cannot open pack index");
@@ -2709,7 +2819,7 @@ static void add_objects_in_unpacked_packs(struct rev_info *revs)
 static int add_loose_object(const struct object_id *oid, const char *path,
                            void *data)
 {
-       enum object_type type = sha1_object_info(oid->hash, NULL);
+       enum object_type type = oid_object_info(the_repository, oid, NULL);
 
        if (type < 0) {
                warning("loose object at %s could not be examined", path);
@@ -2737,16 +2847,18 @@ static int has_sha1_pack_kept_or_nonlocal(const struct object_id *oid)
        static struct packed_git *last_found = (void *)1;
        struct packed_git *p;
 
-       p = (last_found != (void *)1) ? last_found : packed_git;
+       p = (last_found != (void *)1) ? last_found :
+                                       get_packed_git(the_repository);
 
        while (p) {
-               if ((!p->pack_local || p->pack_keep) &&
+               if ((!p->pack_local || p->pack_keep ||
+                               p->pack_keep_in_core) &&
                        find_pack_entry_one(oid->hash, p)) {
                        last_found = p;
                        return 1;
                }
                if (p == last_found)
-                       p = packed_git;
+                       p = get_packed_git(the_repository);
                else
                        p = p->next;
                if (p == last_found)
@@ -2782,8 +2894,8 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
        uint32_t i;
        struct object_id oid;
 
-       for (p = packed_git; p; p = p->next) {
-               if (!p->pack_local || p->pack_keep)
+       for (p = get_packed_git(the_repository); p; p = p->next) {
+               if (!p->pack_local || p->pack_keep || p->pack_keep_in_core)
                        continue;
 
                if (open_pack_index(p))
@@ -2809,7 +2921,8 @@ static int pack_options_allow_reuse(void)
 {
        return pack_to_stdout &&
               allow_ofs_delta &&
-              !ignore_packed_keep &&
+              !ignore_packed_keep_on_disk &&
+              !ignore_packed_keep_in_core &&
               (!local || !have_non_local_packs) &&
               !incremental;
 }
@@ -2918,6 +3031,32 @@ static void get_object_list(int ac, const char **av)
        oid_array_clear(&recent_objects);
 }
 
+static void add_extra_kept_packs(const struct string_list *names)
+{
+       struct packed_git *p;
+
+       if (!names->nr)
+               return;
+
+       for (p = get_packed_git(the_repository); p; p = p->next) {
+               const char *name = basename(p->pack_name);
+               int i;
+
+               if (!p->pack_local)
+                       continue;
+
+               for (i = 0; i < names->nr; i++)
+                       if (!fspathcmp(name, names->items[i].string))
+                               break;
+
+               if (i < names->nr) {
+                       p->pack_keep_in_core = 1;
+                       ignore_packed_keep_in_core = 1;
+                       continue;
+               }
+       }
+}
+
 static int option_parse_index_version(const struct option *opt,
                                      const char *arg, int unset)
 {
@@ -2957,6 +3096,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        struct argv_array rp = ARGV_ARRAY_INIT;
        int rev_list_unpacked = 0, rev_list_all = 0, rev_list_reflog = 0;
        int rev_list_index = 0;
+       struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
        struct option pack_objects_options[] = {
                OPT_SET_INT('q', "quiet", &progress,
                            N_("do not show progress meter"), 0),
@@ -2994,18 +3134,18 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                         N_("do not create an empty pack output")),
                OPT_BOOL(0, "revs", &use_internal_rev_list,
                         N_("read revision arguments from standard input")),
-               { OPTION_SET_INT, 0, "unpacked", &rev_list_unpacked, NULL,
-                 N_("limit the objects to those that are not yet packed"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
-               { OPTION_SET_INT, 0, "all", &rev_list_all, NULL,
-                 N_("include objects reachable from any reference"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
-               { OPTION_SET_INT, 0, "reflog", &rev_list_reflog, NULL,
-                 N_("include objects referred by reflog entries"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
-               { OPTION_SET_INT, 0, "indexed-objects", &rev_list_index, NULL,
-                 N_("include objects referred to by the index"),
-                 PARSE_OPT_NOARG | PARSE_OPT_NONEG, NULL, 1 },
+               OPT_SET_INT_F(0, "unpacked", &rev_list_unpacked,
+                             N_("limit the objects to those that are not yet packed"),
+                             1, PARSE_OPT_NONEG),
+               OPT_SET_INT_F(0, "all", &rev_list_all,
+                             N_("include objects reachable from any reference"),
+                             1, PARSE_OPT_NONEG),
+               OPT_SET_INT_F(0, "reflog", &rev_list_reflog,
+                             N_("include objects referred by reflog entries"),
+                             1, PARSE_OPT_NONEG),
+               OPT_SET_INT_F(0, "indexed-objects", &rev_list_index,
+                             N_("include objects referred to by the index"),
+                             1, PARSE_OPT_NONEG),
                OPT_BOOL(0, "stdout", &pack_to_stdout,
                         N_("output pack to stdout")),
                OPT_BOOL(0, "include-tag", &include_tag,
@@ -3021,8 +3161,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                         N_("create thin packs")),
                OPT_BOOL(0, "shallow", &shallow,
                         N_("create packs suitable for shallow fetches")),
-               OPT_BOOL(0, "honor-pack-keep", &ignore_packed_keep,
+               OPT_BOOL(0, "honor-pack-keep", &ignore_packed_keep_on_disk,
                         N_("ignore packs that have companion .keep file")),
+               OPT_STRING_LIST(0, "keep-pack", &keep_pack_list, N_("name"),
+                               N_("ignore this pack")),
                OPT_INTEGER(0, "compression", &pack_compression_level,
                            N_("pack compression level")),
                OPT_SET_INT(0, "keep-true-parents", &grafts_replace_parents,
@@ -3040,6 +3182,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                OPT_END(),
        };
 
+       if (DFS_NUM_STATES > (1 << OE_DFS_STATE_BITS))
+               BUG("too many dfs states, increase OE_DFS_STATE_BITS");
+
        check_replace_refs = 0;
 
        reset_pack_idx_option(&pack_idx_opts);
@@ -3056,6 +3201,17 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        if (pack_to_stdout != !base_name || argc)
                usage_with_options(pack_usage, pack_objects_options);
 
+       if (depth >= (1 << OE_DEPTH_BITS)) {
+               warning(_("delta chain depth %d is too deep, forcing %d"),
+                       depth, (1 << OE_DEPTH_BITS) - 1);
+               depth = (1 << OE_DEPTH_BITS) - 1;
+       }
+       if (cache_max_small_delta_size >= (1U << OE_Z_DELTA_BITS)) {
+               warning(_("pack.deltaCacheLimit is too high, forcing %d"),
+                       (1U << OE_Z_DELTA_BITS) - 1);
+               cache_max_small_delta_size = (1U << OE_Z_DELTA_BITS) - 1;
+       }
+
        argv_array_push(&rp, "pack-objects");
        if (thin) {
                use_internal_rev_list = 1;
@@ -3087,6 +3243,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                fetch_if_missing = 0;
                argv_array_push(&rp, "--exclude-promisor-objects");
        }
+       if (unpack_unreachable || keep_unreachable || pack_loose_unreachable)
+               use_internal_rev_list = 1;
 
        if (!reuse_object)
                reuse_delta = 0;
@@ -3150,23 +3308,23 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
        if (progress && all_progress_implied)
                progress = 2;
 
-       prepare_packed_git();
-       if (ignore_packed_keep) {
+       add_extra_kept_packs(&keep_pack_list);
+       if (ignore_packed_keep_on_disk) {
                struct packed_git *p;
-               for (p = packed_git; p; p = p->next)
+               for (p = get_packed_git(the_repository); p; p = p->next)
                        if (p->pack_local && p->pack_keep)
                                break;
                if (!p) /* no keep-able packs found */
-                       ignore_packed_keep = 0;
+                       ignore_packed_keep_on_disk = 0;
        }
        if (local) {
                /*
-                * unlike ignore_packed_keep above, we do not want to
-                * unset "local" based on looking at packs, as it
-                * also covers non-local objects
+                * unlike ignore_packed_keep_on_disk above, we do not
+                * want to unset "local" based on looking at packs, as
+                * it also covers non-local objects
                 */
                struct packed_git *p;
-               for (p = packed_git; p; p = p->next) {
+               for (p = get_packed_git(the_repository); p; p = p->next) {
                        if (!p->pack_local) {
                                have_non_local_packs = 1;
                                break;
@@ -3174,8 +3332,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
                }
        }
 
+       prepare_packing_data(&to_pack);
+
        if (progress)
-               progress_state = start_progress(_("Counting objects"), 0);
+               progress_state = start_progress(_("Enumerating objects"), 0);
        if (!use_internal_rev_list)
                read_object_list_from_stdin();
        else {
index 991e1bb76fd66bb189a3523ea5cddf0cd823e343..0494dceff73d672ee430f1c5bd0ce9f8b70c83f6 100644 (file)
@@ -7,7 +7,9 @@
 */
 
 #include "builtin.h"
+#include "repository.h"
 #include "packfile.h"
+#include "object-store.h"
 
 #define BLKSIZE 512
 
@@ -18,7 +20,7 @@ static int load_all_packs, verbose, alt_odb;
 
 struct llist_item {
        struct llist_item *next;
-       const unsigned char *sha1;
+       const struct object_id *oid;
 };
 static struct llist {
        struct llist_item *front;
@@ -88,14 +90,14 @@ static struct llist * llist_copy(struct llist *list)
                return ret;
 
        new_item = ret->front = llist_item_get();
-       new_item->sha1 = list->front->sha1;
+       new_item->oid = list->front->oid;
 
        old_item = list->front->next;
        while (old_item) {
                prev = new_item;
                new_item = llist_item_get();
                prev->next = new_item;
-               new_item->sha1 = old_item->sha1;
+               new_item->oid = old_item->oid;
                old_item = old_item->next;
        }
        new_item->next = NULL;
@@ -106,10 +108,10 @@ static struct llist * llist_copy(struct llist *list)
 
 static inline struct llist_item *llist_insert(struct llist *list,
                                              struct llist_item *after,
-                                              const unsigned char *sha1)
+                                             const struct object_id *oid)
 {
        struct llist_item *new_item = llist_item_get();
-       new_item->sha1 = sha1;
+       new_item->oid = oid;
        new_item->next = NULL;
 
        if (after != NULL) {
@@ -129,21 +131,21 @@ static inline struct llist_item *llist_insert(struct llist *list,
 }
 
 static inline struct llist_item *llist_insert_back(struct llist *list,
-                                                  const unsigned char *sha1)
+                                                  const struct object_id *oid)
 {
-       return llist_insert(list, list->back, sha1);
+       return llist_insert(list, list->back, oid);
 }
 
 static inline struct llist_item *llist_insert_sorted_unique(struct llist *list,
-                       const unsigned char *sha1, struct llist_item *hint)
+                       const struct object_id *oid, struct llist_item *hint)
 {
        struct llist_item *prev = NULL, *l;
 
        l = (hint == NULL) ? list->front : hint;
        while (l) {
-               int cmp = hashcmp(l->sha1, sha1);
+               int cmp = oidcmp(l->oid, oid);
                if (cmp > 0) { /* we insert before this entry */
-                       return llist_insert(list, prev, sha1);
+                       return llist_insert(list, prev, oid);
                }
                if (!cmp) { /* already exists */
                        return l;
@@ -152,11 +154,11 @@ static inline struct llist_item *llist_insert_sorted_unique(struct llist *list,
                l = l->next;
        }
        /* insert at the end */
-       return llist_insert_back(list, sha1);
+       return llist_insert_back(list, oid);
 }
 
 /* returns a pointer to an item in front of sha1 */
-static inline struct llist_item * llist_sorted_remove(struct llist *list, const unsigned char *sha1, struct llist_item *hint)
+static inline struct llist_item * llist_sorted_remove(struct llist *list, const struct object_id *oid, struct llist_item *hint)
 {
        struct llist_item *prev, *l;
 
@@ -164,7 +166,7 @@ redo_from_start:
        l = (hint == NULL) ? list->front : hint;
        prev = NULL;
        while (l) {
-               int cmp = hashcmp(l->sha1, sha1);
+               int cmp = oidcmp(l->oid, oid);
                if (cmp > 0) /* not in list, since sorted */
                        return prev;
                if (!cmp) { /* found */
@@ -199,7 +201,7 @@ static void llist_sorted_difference_inplace(struct llist *A,
        b = B->front;
 
        while (b) {
-               hint = llist_sorted_remove(A, b->sha1, hint);
+               hint = llist_sorted_remove(A, b->oid, hint);
                b = b->next;
        }
 }
@@ -250,13 +252,14 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
        unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step;
        const unsigned char *p1_base, *p2_base;
        struct llist_item *p1_hint = NULL, *p2_hint = NULL;
+       const unsigned int hashsz = the_hash_algo->rawsz;
 
        p1_base = p1->pack->index_data;
        p2_base = p2->pack->index_data;
        p1_base += 256 * 4 + ((p1->pack->index_version < 2) ? 4 : 8);
        p2_base += 256 * 4 + ((p2->pack->index_version < 2) ? 4 : 8);
-       p1_step = (p1->pack->index_version < 2) ? 24 : 20;
-       p2_step = (p2->pack->index_version < 2) ? 24 : 20;
+       p1_step = hashsz + ((p1->pack->index_version < 2) ? 4 : 0);
+       p2_step = hashsz + ((p2->pack->index_version < 2) ? 4 : 0);
 
        while (p1_off < p1->pack->num_objects * p1_step &&
               p2_off < p2->pack->num_objects * p2_step)
@@ -265,9 +268,11 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2)
                /* cmp ~ p1 - p2 */
                if (cmp == 0) {
                        p1_hint = llist_sorted_remove(p1->unique_objects,
-                                       p1_base + p1_off, p1_hint);
+                                       (const struct object_id *)(p1_base + p1_off),
+                                       p1_hint);
                        p2_hint = llist_sorted_remove(p2->unique_objects,
-                                       p1_base + p1_off, p2_hint);
+                                       (const struct object_id *)(p1_base + p1_off),
+                                       p2_hint);
                        p1_off += p1_step;
                        p2_off += p2_step;
                        continue;
@@ -357,13 +362,14 @@ static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2)
        size_t ret = 0;
        unsigned long p1_off = 0, p2_off = 0, p1_step, p2_step;
        const unsigned char *p1_base, *p2_base;
+       const unsigned int hashsz = the_hash_algo->rawsz;
 
        p1_base = p1->index_data;
        p2_base = p2->index_data;
        p1_base += 256 * 4 + ((p1->index_version < 2) ? 4 : 8);
        p2_base += 256 * 4 + ((p2->index_version < 2) ? 4 : 8);
-       p1_step = (p1->index_version < 2) ? 24 : 20;
-       p2_step = (p2->index_version < 2) ? 24 : 20;
+       p1_step = hashsz + ((p1->index_version < 2) ? 4 : 0);
+       p2_step = hashsz + ((p2->index_version < 2) ? 4 : 0);
 
        while (p1_off < p1->num_objects * p1_step &&
               p2_off < p2->num_objects * p2_step)
@@ -497,7 +503,7 @@ static void load_all_objects(void)
                l = pl->all_objects->front;
                while (l) {
                        hint = llist_insert_sorted_unique(all_objects,
-                                                         l->sha1, hint);
+                                                         l->oid, hint);
                        l = l->next;
                }
                pl = pl->next;
@@ -556,9 +562,9 @@ static struct pack_list * add_pack(struct packed_git *p)
 
        base = p->index_data;
        base += 256 * 4 + ((p->index_version < 2) ? 4 : 8);
-       step = (p->index_version < 2) ? 24 : 20;
+       step = the_hash_algo->rawsz + ((p->index_version < 2) ? 4 : 0);
        while (off < p->num_objects * step) {
-               llist_insert_back(l.all_objects, base + off);
+               llist_insert_back(l.all_objects, (const struct object_id *)(base + off));
                off += step;
        }
        /* this list will be pruned in cmp_two_packs later */
@@ -571,7 +577,7 @@ static struct pack_list * add_pack(struct packed_git *p)
 
 static struct pack_list * add_pack_file(const char *filename)
 {
-       struct packed_git *p = packed_git;
+       struct packed_git *p = get_packed_git(the_repository);
 
        if (strlen(filename) < 40)
                die("Bad pack filename: %s", filename);
@@ -586,7 +592,7 @@ static struct pack_list * add_pack_file(const char *filename)
 
 static void load_all(void)
 {
-       struct packed_git *p = packed_git;
+       struct packed_git *p = get_packed_git(the_repository);
 
        while (p) {
                add_pack(p);
@@ -599,8 +605,8 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)
        int i;
        struct pack_list *min, *red, *pl;
        struct llist *ignore;
-       unsigned char *sha1;
-       char buf[42]; /* 40 byte sha1 + \n + \0 */
+       struct object_id *oid;
+       char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */
 
        if (argc == 2 && !strcmp(argv[1], "-h"))
                usage(pack_redundant_usage);
@@ -629,8 +635,6 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)
                        break;
        }
 
-       prepare_packed_git();
-
        if (load_all_packs)
                load_all();
        else
@@ -650,10 +654,10 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix)
        llist_init(&ignore);
        if (!isatty(0)) {
                while (fgets(buf, sizeof(buf), stdin)) {
-                       sha1 = xmalloc(20);
-                       if (get_sha1_hex(buf, sha1))
-                               die("Bad sha1 on stdin: %s", buf);
-                       llist_insert_sorted_unique(ignore, sha1, NULL);
+                       oid = xmalloc(sizeof(*oid));
+                       if (get_oid_hex(buf, oid))
+                               die("Bad object ID on stdin: %s", buf);
+                       llist_insert_sorted_unique(ignore, oid, NULL);
                }
        }
        llist_sorted_difference_inplace(all_objects, ignore);
index b106a392a481570d4fda5a1116c523cde34557ba..f3353564f99205b278362484abcdf1537058ef29 100644 (file)
@@ -1,6 +1,7 @@
 #include "builtin.h"
 #include "parse-options.h"
 #include "refs.h"
+#include "repository.h"
 
 static char const * const pack_refs_usage[] = {
        N_("git pack-refs [<options>]"),
@@ -17,5 +18,5 @@ int cmd_pack_refs(int argc, const char **argv, const char *prefix)
        };
        if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))
                usage_with_options(pack_refs_usage, opts);
-       return refs_pack_refs(get_main_ref_store(), flags);
+       return refs_pack_refs(get_main_ref_store(the_repository), flags);
 }
index 419238171d7a2159f5e533bab84408aacb4d35e4..4ff525e50fc701392e7ed276ae4bba4a82ddf8a1 100644 (file)
@@ -25,7 +25,7 @@ static int prune_object(const struct object_id *oid, const char *path,
 {
        int *opts = data;
 
-       if (!has_sha1_pack(oid->hash))
+       if (!has_object_pack(oid))
                return 0;
 
        if (*opts & PRUNE_PACKED_DRY_RUN)
index 4394d01c9350ae3e1fa26de034edf1509128469e..518ffbea1397faa35102dc088a3830e40c9b13a6 100644 (file)
@@ -50,7 +50,8 @@ static int prune_object(const struct object_id *oid, const char *fullpath,
        if (st.st_mtime > expire)
                return 0;
        if (show_only || verbose) {
-               enum object_type type = sha1_object_info(oid->hash, NULL);
+               enum object_type type = oid_object_info(the_repository, oid,
+                                                       NULL);
                printf("%s %s\n", oid_to_hex(oid),
                       (type > 0) ? type_name(type) : "unknown");
        }
index e32d6cd5b4c999bc45b961c1387af066c72a823a..49cc3beb4c428a4bd0513d922b59465ab0c5c414 100644 (file)
@@ -9,12 +9,13 @@
 #include "config.h"
 #include "builtin.h"
 #include "parse-options.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "run-command.h"
 #include "sha1-array.h"
 #include "remote.h"
 #include "dir.h"
 #include "refs.h"
+#include "refspec.h"
 #include "revision.h"
 #include "submodule.h"
 #include "submodule-config.h"
@@ -27,14 +28,16 @@ enum rebase_type {
        REBASE_FALSE = 0,
        REBASE_TRUE,
        REBASE_PRESERVE,
+       REBASE_MERGES,
        REBASE_INTERACTIVE
 };
 
 /**
  * Parses the value of --rebase. If value is a false value, returns
  * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is
- * "preserve", returns REBASE_PRESERVE. If value is a invalid value, dies with
- * a fatal error if fatal is true, otherwise returns REBASE_INVALID.
+ * "merges", returns REBASE_MERGES. If value is "preserve", returns
+ * REBASE_PRESERVE. If value is a invalid value, dies with a fatal error if
+ * fatal is true, otherwise returns REBASE_INVALID.
  */
 static enum rebase_type parse_config_rebase(const char *key, const char *value,
                int fatal)
@@ -47,6 +50,8 @@ static enum rebase_type parse_config_rebase(const char *key, const char *value,
                return REBASE_TRUE;
        else if (!strcmp(value, "preserve"))
                return REBASE_PRESERVE;
+       else if (!strcmp(value, "merges"))
+               return REBASE_MERGES;
        else if (!strcmp(value, "interactive"))
                return REBASE_INTERACTIVE;
 
@@ -130,7 +135,7 @@ static struct option pull_options[] = {
        /* Options passed to git-merge or git-rebase */
        OPT_GROUP(N_("Options related to merging")),
        { OPTION_CALLBACK, 'r', "rebase", &opt_rebase,
-         "false|true|preserve|interactive",
+         "false|true|merges|preserve|interactive",
          N_("incorporate changes by rebasing rather than merging"),
          PARSE_OPT_OPTARG, parse_opt_rebase },
        OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
@@ -539,7 +544,7 @@ static int run_fetch(const char *repo, const char **refspecs)
                argv_array_push(&args, repo);
                argv_array_pushv(&args, refspecs);
        } else if (*refspecs)
-               die("BUG: refspecs without repo?");
+               BUG("refspecs without repo?");
        ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
        argv_array_clear(&args);
        return ret;
@@ -668,19 +673,19 @@ static const char *get_upstream_branch(const char *remote)
 }
 
 /**
- * Derives the remote tracking branch from the remote and refspec.
+ * Derives the remote-tracking branch from the remote and refspec.
  *
  * FIXME: The current implementation assumes the default mapping of
  * refs/heads/<branch_name> to refs/remotes/<remote_name>/<branch_name>.
  */
 static const char *get_tracking_branch(const char *remote, const char *refspec)
 {
-       struct refspec *spec;
+       struct refspec_item spec;
        const char *spec_src;
        const char *merge_branch;
 
-       spec = parse_fetch_refspec(1, &refspec);
-       spec_src = spec->src;
+       refspec_item_init(&spec, refspec, REFSPEC_FETCH);
+       spec_src = spec.src;
        if (!*spec_src || !strcmp(spec_src, "HEAD"))
                spec_src = "HEAD";
        else if (skip_prefix(spec_src, "heads/", &spec_src))
@@ -700,13 +705,13 @@ static const char *get_tracking_branch(const char *remote, const char *refspec)
        } else
                merge_branch = NULL;
 
-       free_refspec(1, spec);
+       refspec_item_clear(&spec);
        return merge_branch;
 }
 
 /**
  * Given the repo and refspecs, sets fork_point to the point at which the
- * current branch forked from its remote tracking branch. Returns 0 on success,
+ * current branch forked from its remote-tracking branch. Returns 0 on success,
  * -1 on failure.
  */
 static int get_rebase_fork_point(struct object_id *fork_point, const char *repo,
@@ -800,7 +805,9 @@ static int run_rebase(const struct object_id *curr_head,
        argv_push_verbosity(&args);
 
        /* Options passed to git-rebase */
-       if (opt_rebase == REBASE_PRESERVE)
+       if (opt_rebase == REBASE_MERGES)
+               argv_array_push(&args, "--rebase-merges");
+       else if (opt_rebase == REBASE_PRESERVE)
                argv_array_push(&args, "--preserve-merges");
        else if (opt_rebase == REBASE_INTERACTIVE)
                argv_array_push(&args, "--interactive");
index 013c20d6164f61dc404b89271c0281d28b5069a7..9cd8e8cd5631158e0904826567f2d3c02bca2bda 100644 (file)
@@ -4,6 +4,7 @@
 #include "cache.h"
 #include "config.h"
 #include "refs.h"
+#include "refspec.h"
 #include "run-command.h"
 #include "builtin.h"
 #include "remote.h"
 #include "submodule.h"
 #include "submodule-config.h"
 #include "send-pack.h"
+#include "color.h"
 
 static const char * const push_usage[] = {
        N_("git push [<options>] [<repository> [<refspec>...]]"),
        NULL,
 };
 
+static int push_use_color = -1;
+static char push_colors[][COLOR_MAXLEN] = {
+       GIT_COLOR_RESET,
+       GIT_COLOR_RED,  /* ERROR */
+};
+
+enum color_push {
+       PUSH_COLOR_RESET = 0,
+       PUSH_COLOR_ERROR = 1
+};
+
+static int parse_push_color_slot(const char *slot)
+{
+       if (!strcasecmp(slot, "reset"))
+               return PUSH_COLOR_RESET;
+       if (!strcasecmp(slot, "error"))
+               return PUSH_COLOR_ERROR;
+       return -1;
+}
+
+static const char *push_get_color(enum color_push ix)
+{
+       if (want_color_stderr(push_use_color))
+               return push_colors[ix];
+       return "";
+}
+
 static int thin = 1;
 static int deleterefs;
 static const char *receivepack;
@@ -28,19 +57,10 @@ static enum transport_family family;
 
 static struct push_cas_option cas;
 
-static const char **refspec;
-static int refspec_nr;
-static int refspec_alloc;
+static struct refspec rs = REFSPEC_INIT_PUSH;
 
 static struct string_list push_options_config = STRING_LIST_INIT_DUP;
 
-static void add_refspec(const char *ref)
-{
-       refspec_nr++;
-       ALLOC_GROW(refspec, refspec_nr, refspec_alloc);
-       refspec[refspec_nr-1] = ref;
-}
-
 static const char *map_refspec(const char *ref,
                               struct remote *remote, struct ref *local_refs)
 {
@@ -50,12 +70,11 @@ static const char *map_refspec(const char *ref,
        if (count_refspec_match(ref, local_refs, &matched) != 1)
                return ref;
 
-       if (remote->push) {
-               struct refspec query;
-               memset(&query, 0, sizeof(struct refspec));
+       if (remote->push.nr) {
+               struct refspec_item query;
+               memset(&query, 0, sizeof(struct refspec_item));
                query.src = matched->name;
-               if (!query_refspecs(remote->push, remote->push_refspec_nr, &query) &&
-                   query.dst) {
+               if (!query_refspecs(&remote->push, &query) && query.dst) {
                        struct strbuf buf = STRBUF_INIT;
                        strbuf_addf(&buf, "%s%s:%s",
                                    query.force ? "+" : "",
@@ -110,7 +129,7 @@ static void set_refspecs(const char **refs, int nr, const char *repo)
                        }
                        ref = map_refspec(ref, remote, local_refs);
                }
-               add_refspec(ref);
+               refspec_append(&rs, ref);
        }
 }
 
@@ -198,7 +217,7 @@ static void setup_push_upstream(struct remote *remote, struct branch *branch,
        }
 
        strbuf_addf(&refspec, "%s:%s", branch->refname, branch->merge[0]->src);
-       add_refspec(refspec.buf);
+       refspec_append(&rs, refspec.buf);
 }
 
 static void setup_push_current(struct remote *remote, struct branch *branch)
@@ -208,7 +227,7 @@ static void setup_push_current(struct remote *remote, struct branch *branch)
        if (!branch)
                die(_(message_detached_head_die), remote->name);
        strbuf_addf(&refspec, "%s:%s", branch->refname, branch->refname);
-       add_refspec(refspec.buf);
+       refspec_append(&rs, refspec.buf);
 }
 
 static int is_workflow_triangular(struct remote *remote)
@@ -225,7 +244,7 @@ static void setup_default_push_refspecs(struct remote *remote)
        switch (push_default) {
        default:
        case PUSH_DEFAULT_MATCHING:
-               add_refspec(":");
+               refspec_append(&rs, ":");
                break;
 
        case PUSH_DEFAULT_UNSPECIFIED:
@@ -313,7 +332,8 @@ static void advise_ref_needs_force(void)
        advise(_(message_advice_ref_needs_force));
 }
 
-static int push_with_options(struct transport *transport, int flags)
+static int push_with_options(struct transport *transport, struct refspec *rs,
+                            int flags)
 {
        int err;
        unsigned int reject_reasons;
@@ -335,10 +355,12 @@ static int push_with_options(struct transport *transport, int flags)
 
        if (verbosity > 0)
                fprintf(stderr, _("Pushing to %s\n"), transport->url);
-       err = transport_push(transport, refspec_nr, refspec, flags,
-                            &reject_reasons);
-       if (err != 0)
+       err = transport_push(transport, rs, flags, &reject_reasons);
+       if (err != 0) {
+               fprintf(stderr, "%s", push_get_color(PUSH_COLOR_ERROR));
                error(_("failed to push some refs to '%s'"), transport->url);
+               fprintf(stderr, "%s", push_get_color(PUSH_COLOR_RESET));
+       }
 
        err |= transport_disconnect(transport);
        if (!err)
@@ -366,6 +388,7 @@ static int do_push(const char *repo, int flags,
        struct remote *remote = pushremote_get(repo);
        const char **url;
        int url_nr;
+       struct refspec *push_refspec = &rs;
 
        if (!remote) {
                if (repo)
@@ -386,27 +409,9 @@ static int do_push(const char *repo, int flags,
        if (push_options->nr)
                flags |= TRANSPORT_PUSH_OPTIONS;
 
-       if ((flags & TRANSPORT_PUSH_ALL) && refspec) {
-               if (!strcmp(*refspec, "refs/tags/*"))
-                       return error(_("--all and --tags are incompatible"));
-               return error(_("--all can't be combined with refspecs"));
-       }
-
-       if ((flags & TRANSPORT_PUSH_MIRROR) && refspec) {
-               if (!strcmp(*refspec, "refs/tags/*"))
-                       return error(_("--mirror and --tags are incompatible"));
-               return error(_("--mirror can't be combined with refspecs"));
-       }
-
-       if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
-                               (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
-               return error(_("--all and --mirror are incompatible"));
-       }
-
-       if (!refspec && !(flags & TRANSPORT_PUSH_ALL)) {
-               if (remote->push_refspec_nr) {
-                       refspec = remote->push_refspec;
-                       refspec_nr = remote->push_refspec_nr;
+       if (!push_refspec->nr && !(flags & TRANSPORT_PUSH_ALL)) {
+               if (remote->push.nr) {
+                       push_refspec = &remote->push;
                } else if (!(flags & TRANSPORT_PUSH_MIRROR))
                        setup_default_push_refspecs(remote);
        }
@@ -418,7 +423,7 @@ static int do_push(const char *repo, int flags,
                                transport_get(remote, url[i]);
                        if (flags & TRANSPORT_PUSH_OPTIONS)
                                transport->push_options = push_options;
-                       if (push_with_options(transport, flags))
+                       if (push_with_options(transport, push_refspec, flags))
                                errs++;
                }
        } else {
@@ -426,7 +431,7 @@ static int do_push(const char *repo, int flags,
                        transport_get(remote, NULL);
                if (flags & TRANSPORT_PUSH_OPTIONS)
                        transport->push_options = push_options;
-               if (push_with_options(transport, flags))
+               if (push_with_options(transport, push_refspec, flags))
                        errs++;
        }
        return !!errs;
@@ -467,6 +472,7 @@ static void set_push_cert_flags(int *flags, int v)
 
 static int git_push_config(const char *k, const char *v, void *cb)
 {
+       const char *slot_name;
        int *flags = cb;
        int status;
 
@@ -514,6 +520,16 @@ static int git_push_config(const char *k, const char *v, void *cb)
                        else
                                string_list_append(&push_options_config, v);
                return 0;
+       } else if (!strcmp(k, "color.push")) {
+               push_use_color = git_config_colorbool(k, v);
+               return 0;
+       } else if (skip_prefix(k, "color.push.", &slot_name)) {
+               int slot = parse_push_color_slot(slot_name);
+               if (slot < 0)
+                       return 0;
+               if (!v)
+                       return config_error_nonbool(k);
+               return color_parse(v, push_colors[slot]);
        }
 
        return git_default_config(k, v, NULL);
@@ -583,6 +599,20 @@ int cmd_push(int argc, const char **argv, const char *prefix)
                die(_("--delete is incompatible with --all, --mirror and --tags"));
        if (deleterefs && argc < 2)
                die(_("--delete doesn't make sense without any refs"));
+       if (flags & TRANSPORT_PUSH_ALL) {
+               if (tags)
+                       die(_("--all and --tags are incompatible"));
+               if (argc >= 2)
+                       die(_("--all can't be combined with refspecs"));
+       }
+       if (flags & TRANSPORT_PUSH_MIRROR) {
+               if (tags)
+                       die(_("--mirror and --tags are incompatible"));
+               if (argc >= 2)
+                       die(_("--mirror can't be combined with refspecs"));
+       }
+       if ((flags & TRANSPORT_PUSH_ALL) && (flags & TRANSPORT_PUSH_MIRROR))
+               die(_("--all and --mirror are incompatible"));
 
        if (recurse_submodules == RECURSE_SUBMODULES_CHECK)
                flags |= TRANSPORT_RECURSE_SUBMODULES_CHECK;
@@ -592,7 +622,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
                flags |= TRANSPORT_RECURSE_SUBMODULES_ONLY;
 
        if (tags)
-               add_refspec("refs/tags/*");
+               refspec_append(&rs, "refs/tags/*");
 
        if (argc > 0) {
                repo = argv[0];
index bf87a2710b31fa49b1802ed297c8ae52eede6354..ebc43eb8057dc9c85aad4c608250ed9a6c4d6cd1 100644 (file)
@@ -107,8 +107,6 @@ static int git_read_tree_config(const char *var, const char *value, void *cb)
        return git_default_config(var, value, cb);
 }
 
-static struct lock_file lock_file;
-
 int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
 {
        int i, stage = 0;
@@ -116,6 +114,7 @@ int cmd_read_tree(int argc, const char **argv, const char *unused_prefix)
        struct tree_desc t[MAX_UNPACK_TREES];
        struct unpack_trees_options opts;
        int prefix_set = 0;
+       struct lock_file lock_file = LOCK_INIT;
        const struct option read_tree_options[] = {
                { OPTION_CALLBACK, 0, "index-output", NULL, N_("file"),
                  N_("write resulting index to <file>"),
index ad074705bb51d1de4221b3c5dfaa7229903c0ef0..f7c2a5fdc815a892b99d6561d73d953740bf789a 100644 (file)
@@ -12,8 +12,8 @@ static const char * const builtin_rebase_helper_usage[] = {
 int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
 {
        struct replay_opts opts = REPLAY_OPTS_INIT;
-       unsigned flags = 0, keep_empty = 0;
-       int abbreviate_commands = 0;
+       unsigned flags = 0, keep_empty = 0, rebase_merges = 0;
+       int abbreviate_commands = 0, rebase_cousins = -1;
        enum {
                CONTINUE = 1, ABORT, MAKE_SCRIPT, SHORTEN_OIDS, EXPAND_OIDS,
                CHECK_TODO_LIST, SKIP_UNNECESSARY_PICKS, REARRANGE_SQUASH,
@@ -24,6 +24,9 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
                OPT_BOOL(0, "keep-empty", &keep_empty, N_("keep empty commits")),
                OPT_BOOL(0, "allow-empty-message", &opts.allow_empty_message,
                        N_("allow commits with empty messages")),
+               OPT_BOOL(0, "rebase-merges", &rebase_merges, N_("rebase merge commits")),
+               OPT_BOOL(0, "rebase-cousins", &rebase_cousins,
+                        N_("keep original branch points of cousins")),
                OPT_CMDMODE(0, "continue", &command, N_("continue rebase"),
                                CONTINUE),
                OPT_CMDMODE(0, "abort", &command, N_("abort rebase"),
@@ -57,8 +60,14 @@ int cmd_rebase__helper(int argc, const char **argv, const char *prefix)
 
        flags |= keep_empty ? TODO_LIST_KEEP_EMPTY : 0;
        flags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0;
+       flags |= rebase_merges ? TODO_LIST_REBASE_MERGES : 0;
+       flags |= rebase_cousins > 0 ? TODO_LIST_REBASE_COUSINS : 0;
        flags |= command == SHORTEN_OIDS ? TODO_LIST_SHORTEN_IDS : 0;
 
+       if (rebase_cousins >= 0 && !rebase_merges)
+               warning(_("--[no-]rebase-cousins has no effect without "
+                         "--rebase-merges"));
+
        if (command == CONTINUE && argc == 1)
                return !!sequencer_continue(&opts);
        if (command == ABORT && argc == 1)
index 75e7f18aceffc42b5fdc58296559c67d47203098..68d36e0a56c3c72ad76c07af293d20e8254377d1 100644 (file)
@@ -1,4 +1,5 @@
 #include "builtin.h"
+#include "repository.h"
 #include "config.h"
 #include "lockfile.h"
 #include "pack.h"
@@ -6,7 +7,7 @@
 #include "pkt-line.h"
 #include "sideband.h"
 #include "run-command.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "commit.h"
 #include "object.h"
 #include "remote.h"
@@ -453,21 +454,21 @@ static void hmac_sha1(unsigned char *out,
        /* RFC 2104 2. (6) & (7) */
        git_SHA1_Init(&ctx);
        git_SHA1_Update(&ctx, k_opad, sizeof(k_opad));
-       git_SHA1_Update(&ctx, out, 20);
+       git_SHA1_Update(&ctx, out, GIT_SHA1_RAWSZ);
        git_SHA1_Final(out, &ctx);
 }
 
 static char *prepare_push_cert_nonce(const char *path, timestamp_t stamp)
 {
        struct strbuf buf = STRBUF_INIT;
-       unsigned char sha1[20];
+       unsigned char sha1[GIT_SHA1_RAWSZ];
 
        strbuf_addf(&buf, "%s:%"PRItime, path, stamp);
        hmac_sha1(sha1, buf.buf, buf.len, cert_nonce_seed, strlen(cert_nonce_seed));;
        strbuf_release(&buf);
 
        /* RFC 2104 5. HMAC-SHA1-80 */
-       strbuf_addf(&buf, "%"PRItime"-%.*s", stamp, 20, sha1_to_hex(sha1));
+       strbuf_addf(&buf, "%"PRItime"-%.*s", stamp, GIT_SHA1_HEXSZ, sha1_to_hex(sha1));
        return strbuf_detach(&buf, NULL);
 }
 
@@ -875,7 +876,7 @@ static void refuse_unconfigured_deny_delete_current(void)
 static int command_singleton_iterator(void *cb_data, struct object_id *oid);
 static int update_shallow_ref(struct command *cmd, struct shallow_info *si)
 {
-       static struct lock_file shallow_lock;
+       struct lock_file shallow_lock = LOCK_INIT;
        struct oid_array extra = OID_ARRAY_INIT;
        struct check_connected_options opt = CHECK_CONNECTED_INIT;
        uint32_t mask = 1 << (cmd->index % 32);
@@ -967,7 +968,7 @@ static const char *push_to_deploy(unsigned char *sha1,
                return "Working directory has unstaged changes";
 
        /* diff-index with either HEAD or an empty tree */
-       diff_index[4] = head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX;
+       diff_index[4] = head_has_history() ? "HEAD" : empty_tree_oid_hex();
 
        child_process_init(&child);
        child.argv = diff_index;
@@ -1242,11 +1243,11 @@ static void check_aliased_update(struct command *cmd, struct string_list *list)
        rp_error("refusing inconsistent update between symref '%s' (%s..%s) and"
                 " its target '%s' (%s..%s)",
                 cmd->ref_name,
-                find_unique_abbrev(cmd->old_oid.hash, DEFAULT_ABBREV),
-                find_unique_abbrev(cmd->new_oid.hash, DEFAULT_ABBREV),
+                find_unique_abbrev(&cmd->old_oid, DEFAULT_ABBREV),
+                find_unique_abbrev(&cmd->new_oid, DEFAULT_ABBREV),
                 dst_cmd->ref_name,
-                find_unique_abbrev(dst_cmd->old_oid.hash, DEFAULT_ABBREV),
-                find_unique_abbrev(dst_cmd->new_oid.hash, DEFAULT_ABBREV));
+                find_unique_abbrev(&dst_cmd->old_oid, DEFAULT_ABBREV),
+                find_unique_abbrev(&dst_cmd->new_oid, DEFAULT_ABBREV));
 
        cmd->error_string = dst_cmd->error_string =
                "inconsistent aliased update";
@@ -1377,7 +1378,7 @@ static void warn_if_skipped_connectivity_check(struct command *commands,
                }
        }
        if (!checked_connectivity)
-               die("BUG: connectivity check skipped???");
+               BUG("connectivity check skipped???");
 }
 
 static void execute_commands_non_atomic(struct command *commands,
@@ -1778,7 +1779,7 @@ static const char *unpack(int err_fd, struct shallow_info *si)
                status = finish_command(&child);
                if (status)
                        return "index-pack abnormal exit";
-               reprepare_packed_git();
+               reprepare_packed_git(the_repository);
        }
        return NULL;
 }
@@ -1964,6 +1965,12 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
                unpack_limit = receive_unpack_limit;
 
        switch (determine_protocol_version_server()) {
+       case protocol_v2:
+               /*
+                * push support for protocol v2 has not been implemented yet,
+                * so ignore the request to use v2 and fallback to using v0.
+                */
+               break;
        case protocol_v1:
                /*
                 * v1 is just the original protocol with a version string,
@@ -2027,7 +2034,7 @@ int cmd_receive_pack(int argc, const char **argv, const char *prefix)
                        proc.git_cmd = 1;
                        proc.argv = argv_gc_auto;
 
-                       close_all_packs();
+                       close_all_packs(the_repository->objects);
                        if (!start_command(&proc)) {
                                if (use_sideband)
                                        copy_to_sideband(proc.err, -1, NULL);
index 4719a5354cf182eb91b257a99da97b9b81da5257..a48984d37e4f5f9e1f07a840582f82e202bd09f0 100644 (file)
@@ -75,7 +75,7 @@ static int tree_is_complete(const struct object_id *oid)
        if (!tree->buffer) {
                enum object_type type;
                unsigned long size;
-               void *data = read_sha1_file(oid->hash, &type, &size);
+               void *data = read_object_file(oid, &type, &size);
                if (!data) {
                        tree->object.flags |= INCOMPLETE;
                        return 0;
@@ -154,7 +154,7 @@ static int commit_is_complete(struct commit *commit)
                for (i = 0; i < found.nr; i++) {
                        struct commit *c =
                                (struct commit *)found.objects[i].item;
-                       if (!tree_is_complete(&c->tree->object.oid)) {
+                       if (!tree_is_complete(get_commit_tree_oid(c))) {
                                is_incomplete = 1;
                                c->object.flags |= INCOMPLETE;
                        }
index 805ffc05cdb80e4a69de4134e757f9c71e8033dc..1a82d850a22c3bfc3176eeda3f8b061b6feb7dc4 100644 (file)
@@ -7,6 +7,7 @@
 #include "strbuf.h"
 #include "run-command.h"
 #include "refs.h"
+#include "refspec.h"
 #include "argv-array.h"
 
 static const char * const builtin_remote_usage[] = {
@@ -245,7 +246,9 @@ static int add(int argc, const char **argv)
 struct branch_info {
        char *remote_name;
        struct string_list merge;
-       enum { NO_REBASE, NORMAL_REBASE, INTERACTIVE_REBASE } rebase;
+       enum {
+               NO_REBASE, NORMAL_REBASE, INTERACTIVE_REBASE, REBASE_MERGES
+       } rebase;
 };
 
 static struct string_list branch_list = STRING_LIST_INIT_NODUP;
@@ -306,6 +309,8 @@ static int config_read_branches(const char *key, const char *value, void *cb)
                                info->rebase = v;
                        else if (!strcmp(value, "preserve"))
                                info->rebase = NORMAL_REBASE;
+                       else if (!strcmp(value, "merges"))
+                               info->rebase = REBASE_MERGES;
                        else if (!strcmp(value, "interactive"))
                                info->rebase = INTERACTIVE_REBASE;
                }
@@ -332,10 +337,10 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
        struct ref *ref, *stale_refs;
        int i;
 
-       for (i = 0; i < states->remote->fetch_refspec_nr; i++)
-               if (get_fetch_map(remote_refs, states->remote->fetch + i, &tail, 1))
+       for (i = 0; i < states->remote->fetch.nr; i++)
+               if (get_fetch_map(remote_refs, &states->remote->fetch.items[i], &tail, 1))
                        die(_("Could not get fetch map for refspec %s"),
-                               states->remote->fetch_refspec[i]);
+                               states->remote->fetch.raw[i]);
 
        states->new_refs.strdup_strings = 1;
        states->tracked.strdup_strings = 1;
@@ -346,8 +351,7 @@ static int get_ref_states(const struct ref *remote_refs, struct ref_states *stat
                else
                        string_list_append(&states->tracked, abbrev_branch(ref->name));
        }
-       stale_refs = get_stale_heads(states->remote->fetch,
-                                    states->remote->fetch_refspec_nr, fetch_map);
+       stale_refs = get_stale_heads(&states->remote->fetch, fetch_map);
        for (ref = stale_refs; ref; ref = ref->next) {
                struct string_list_item *item =
                        string_list_append(&states->stale, abbrev_branch(ref->name));
@@ -387,8 +391,7 @@ static int get_push_ref_states(const struct ref *remote_refs,
        local_refs = get_local_heads();
        push_map = copy_ref_list(remote_refs);
 
-       match_push_refs(local_refs, &push_map, remote->push_refspec_nr,
-                       remote->push_refspec, MATCH_REFS_NONE);
+       match_push_refs(local_refs, &push_map, &remote->push, MATCH_REFS_NONE);
 
        states->push.strdup_strings = 1;
        for (ref = push_map; ref; ref = ref->next) {
@@ -434,14 +437,14 @@ static int get_push_ref_states_noquery(struct ref_states *states)
                return 0;
 
        states->push.strdup_strings = 1;
-       if (!remote->push_refspec_nr) {
+       if (!remote->push.nr) {
                item = string_list_append(&states->push, _("(matching)"));
                info = item->util = xcalloc(1, sizeof(struct push_info));
                info->status = PUSH_STATUS_NOTQUERIED;
                info->dest = xstrdup(item->string);
        }
-       for (i = 0; i < remote->push_refspec_nr; i++) {
-               struct refspec *spec = remote->push + i;
+       for (i = 0; i < remote->push.nr; i++) {
+               const struct refspec_item *spec = &remote->push.items[i];
                if (spec->matching)
                        item = string_list_append(&states->push, _("(matching)"));
                else if (strlen(spec->src))
@@ -461,7 +464,7 @@ static int get_head_names(const struct ref *remote_refs, struct ref_states *stat
 {
        struct ref *ref, *matches;
        struct ref *fetch_map = NULL, **fetch_map_tail = &fetch_map;
-       struct refspec refspec;
+       struct refspec_item refspec;
 
        refspec.force = 0;
        refspec.pattern = 1;
@@ -514,7 +517,7 @@ static int add_branch_for_removal(const char *refname,
        const struct object_id *oid, int flags, void *cb_data)
 {
        struct branches_for_remote *branches = cb_data;
-       struct refspec refspec;
+       struct refspec_item refspec;
        struct known_remote *kr;
 
        memset(&refspec, 0, sizeof(refspec));
@@ -585,12 +588,12 @@ static int migrate_file(struct remote *remote)
                git_config_set_multivar(buf.buf, remote->url[i], "^$", 0);
        strbuf_reset(&buf);
        strbuf_addf(&buf, "remote.%s.push", remote->name);
-       for (i = 0; i < remote->push_refspec_nr; i++)
-               git_config_set_multivar(buf.buf, remote->push_refspec[i], "^$", 0);
+       for (i = 0; i < remote->push.raw_nr; i++)
+               git_config_set_multivar(buf.buf, remote->push.raw[i], "^$", 0);
        strbuf_reset(&buf);
        strbuf_addf(&buf, "remote.%s.fetch", remote->name);
-       for (i = 0; i < remote->fetch_refspec_nr; i++)
-               git_config_set_multivar(buf.buf, remote->fetch_refspec[i], "^$", 0);
+       for (i = 0; i < remote->fetch.raw_nr; i++)
+               git_config_set_multivar(buf.buf, remote->fetch.raw[i], "^$", 0);
        if (remote->origin == REMOTE_REMOTES)
                unlink_or_warn(git_path("remotes/%s", remote->name));
        else if (remote->origin == REMOTE_BRANCHES)
@@ -645,11 +648,11 @@ static int mv(int argc, const char **argv)
        strbuf_addf(&buf, "remote.%s.fetch", rename.new_name);
        git_config_set_multivar(buf.buf, NULL, NULL, 1);
        strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name);
-       for (i = 0; i < oldremote->fetch_refspec_nr; i++) {
+       for (i = 0; i < oldremote->fetch.raw_nr; i++) {
                char *ptr;
 
                strbuf_reset(&buf2);
-               strbuf_addstr(&buf2, oldremote->fetch_refspec[i]);
+               strbuf_addstr(&buf2, oldremote->fetch.raw[i]);
                ptr = strstr(buf2.buf, old_remote_context.buf);
                if (ptr) {
                        refspec_updated = 1;
@@ -833,7 +836,7 @@ static int append_ref_to_tracked_list(const char *refname,
        const struct object_id *oid, int flags, void *cb_data)
 {
        struct ref_states *states = cb_data;
-       struct refspec refspec;
+       struct refspec_item refspec;
 
        if (flags & REF_ISSYMREF)
                return 0;
@@ -862,7 +865,7 @@ static int get_remote_ref_states(const char *name,
        if (query) {
                transport = transport_get(states->remote, states->remote->url_nr > 0 ?
                        states->remote->url[0] : NULL);
-               remote_refs = transport_get_remote_refs(transport);
+               remote_refs = transport_get_remote_refs(transport, NULL);
                transport_disconnect(transport);
 
                states->queried = 1;
@@ -963,9 +966,15 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data)
 
        printf("    %-*s ", show_info->width, item->string);
        if (branch_info->rebase) {
-               printf_ln(branch_info->rebase == INTERACTIVE_REBASE
-                         ? _("rebases interactively onto remote %s")
-                         : _("rebases onto remote %s"), merge->items[0].string);
+               const char *msg;
+               if (branch_info->rebase == INTERACTIVE_REBASE)
+                       msg = _("rebases interactively onto remote %s");
+               else if (branch_info->rebase == REBASE_MERGES)
+                       msg = _("rebases interactively (with merges) onto "
+                               "remote %s");
+               else
+                       msg = _("rebases onto remote %s");
+               printf_ln(msg, merge->items[0].string);
                return 0;
        } else if (show_info->any_rebase) {
                printf_ln(_(" merges with remote %s"), merge->items[0].string);
index 7bdb40142f9261dac6514d98ee01dc44e595ec71..6c636e159eaf2d67d617c459aceddd7423e326ab 100644 (file)
@@ -86,7 +86,8 @@ static void remove_pack_on_signal(int signo)
  * have a corresponding .keep or .promisor file. These packs are not to
  * be kept if we are going to pack everything into one file.
  */
-static void get_non_kept_pack_filenames(struct string_list *fname_list)
+static void get_non_kept_pack_filenames(struct string_list *fname_list,
+                                       const struct string_list *extra_keep)
 {
        DIR *dir;
        struct dirent *e;
@@ -97,6 +98,14 @@ static void get_non_kept_pack_filenames(struct string_list *fname_list)
 
        while ((e = readdir(dir)) != NULL) {
                size_t len;
+               int i;
+
+               for (i = 0; i < extra_keep->nr; i++)
+                       if (!fspathcmp(e->d_name, extra_keep->items[i].string))
+                               break;
+               if (extra_keep->nr > 0 && i < extra_keep->nr)
+                       continue;
+
                if (!strip_suffix(e->d_name, ".pack", &len))
                        continue;
 
@@ -148,7 +157,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
        struct string_list rollback = STRING_LIST_INIT_NODUP;
        struct string_list existing_packs = STRING_LIST_INIT_DUP;
        struct strbuf line = STRBUF_INIT;
-       int ext, ret, failed;
+       int i, ext, ret, failed;
        FILE *out;
 
        /* variables to be filled by option parsing */
@@ -160,6 +169,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
        const char *depth = NULL;
        const char *threads = NULL;
        const char *max_pack_size = NULL;
+       struct string_list keep_pack_list = STRING_LIST_INIT_NODUP;
        int no_reuse_delta = 0, no_reuse_object = 0;
        int no_update_server_info = 0;
        int quiet = 0;
@@ -200,6 +210,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
                                N_("maximum size of each packfile")),
                OPT_BOOL(0, "pack-kept-objects", &pack_kept_objects,
                                N_("repack objects in packs marked with .keep")),
+               OPT_STRING_LIST(0, "keep-pack", &keep_pack_list, N_("name"),
+                               N_("do not repack this pack")),
                OPT_END()
        };
 
@@ -230,6 +242,9 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
        argv_array_push(&cmd.args, "--keep-true-parents");
        if (!pack_kept_objects)
                argv_array_push(&cmd.args, "--honor-pack-keep");
+       for (i = 0; i < keep_pack_list.nr; i++)
+               argv_array_pushf(&cmd.args, "--keep-pack=%s",
+                                keep_pack_list.items[i].string);
        argv_array_push(&cmd.args, "--non-empty");
        argv_array_push(&cmd.args, "--all");
        argv_array_push(&cmd.args, "--reflog");
@@ -254,7 +269,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
                argv_array_push(&cmd.args, "--write-bitmap-index");
 
        if (pack_everything & ALL_INTO_ONE) {
-               get_non_kept_pack_filenames(&existing_packs);
+               get_non_kept_pack_filenames(&existing_packs, &keep_pack_list);
 
                if (existing_packs.nr && delete_redundant) {
                        if (unpack_unreachable) {
index 482f12018fa912eeea860721af2acbf5f8a2e87d..6da2411e14b9f94f309671e14124ef32d89ef528 100644 (file)
 #include "refs.h"
 #include "parse-options.h"
 #include "run-command.h"
+#include "object-store.h"
+#include "repository.h"
 #include "tag.h"
 
 static const char * const git_replace_usage[] = {
        N_("git replace [-f] <object> <replacement>"),
        N_("git replace [-f] --edit <object>"),
        N_("git replace [-f] --graft <commit> [<parent>...]"),
+       N_("git replace [-f] --convert-graft-file"),
        N_("git replace -d <object>..."),
        N_("git replace [--format=<format>] [-l [<pattern>]]"),
        NULL
@@ -53,8 +56,9 @@ static int show_reference(const char *refname, const struct object_id *oid,
                        if (get_oid(refname, &object))
                                return error("Failed to resolve '%s' as a valid ref.", refname);
 
-                       obj_type = sha1_object_info(object.hash, NULL);
-                       repl_type = sha1_object_info(oid->hash, NULL);
+                       obj_type = oid_object_info(the_repository, &object,
+                                                  NULL);
+                       repl_type = oid_object_info(the_repository, oid, NULL);
 
                        printf("%s (%s) -> %s (%s)\n", refname, type_name(obj_type),
                               oid_to_hex(oid), type_name(repl_type));
@@ -79,11 +83,11 @@ static int list_replace_refs(const char *pattern, const char *format)
        else if (!strcmp(format, "long"))
                data.format = REPLACE_FORMAT_LONG;
        else
-               die("invalid replace format '%s'\n"
-                   "valid formats are 'short', 'medium' and 'long'\n",
-                   format);
+               return error("invalid replace format '%s'\n"
+                            "valid formats are 'short', 'medium' and 'long'\n",
+                            format);
 
-       for_each_replace_ref(show_reference, (void *)&data);
+       for_each_replace_ref(the_repository, show_reference, (void *)&data);
 
        return 0;
 }
@@ -134,7 +138,7 @@ static int delete_replace_ref(const char *name, const char *ref,
        return 0;
 }
 
-static void check_ref_valid(struct object_id *object,
+static int check_ref_valid(struct object_id *object,
                            struct object_id *prev,
                            struct strbuf *ref,
                            int force)
@@ -142,12 +146,13 @@ static void check_ref_valid(struct object_id *object,
        strbuf_reset(ref);
        strbuf_addf(ref, "%s%s", git_replace_ref_base, oid_to_hex(object));
        if (check_refname_format(ref->buf, 0))
-               die("'%s' is not a valid ref name.", ref->buf);
+               return error("'%s' is not a valid ref name.", ref->buf);
 
        if (read_ref(ref->buf, prev))
                oidclr(prev);
        else if (!force)
-               die("replace ref '%s' already exists", ref->buf);
+               return error("replace ref '%s' already exists", ref->buf);
+       return 0;
 }
 
 static int replace_object_oid(const char *object_ref,
@@ -161,28 +166,33 @@ static int replace_object_oid(const char *object_ref,
        struct strbuf ref = STRBUF_INIT;
        struct ref_transaction *transaction;
        struct strbuf err = STRBUF_INIT;
+       int res = 0;
 
-       obj_type = sha1_object_info(object->hash, NULL);
-       repl_type = sha1_object_info(repl->hash, NULL);
+       obj_type = oid_object_info(the_repository, object, NULL);
+       repl_type = oid_object_info(the_repository, repl, NULL);
        if (!force && obj_type != repl_type)
-               die("Objects must be of the same type.\n"
-                   "'%s' points to a replaced object of type '%s'\n"
-                   "while '%s' points to a replacement object of type '%s'.",
-                   object_ref, type_name(obj_type),
-                   replace_ref, type_name(repl_type));
-
-       check_ref_valid(object, &prev, &ref, force);
+               return error("Objects must be of the same type.\n"
+                            "'%s' points to a replaced object of type '%s'\n"
+                            "while '%s' points to a replacement object of "
+                            "type '%s'.",
+                            object_ref, type_name(obj_type),
+                            replace_ref, type_name(repl_type));
+
+       if (check_ref_valid(object, &prev, &ref, force)) {
+               strbuf_release(&ref);
+               return -1;
+       }
 
        transaction = ref_transaction_begin(&err);
        if (!transaction ||
            ref_transaction_update(transaction, ref.buf, repl, &prev,
                                   0, NULL, &err) ||
            ref_transaction_commit(transaction, &err))
-               die("%s", err.buf);
+               res = error("%s", err.buf);
 
        ref_transaction_free(transaction);
        strbuf_release(&ref);
-       return 0;
+       return res;
 }
 
 static int replace_object(const char *object_ref, const char *replace_ref, int force)
@@ -190,9 +200,11 @@ static int replace_object(const char *object_ref, const char *replace_ref, int f
        struct object_id object, repl;
 
        if (get_oid(object_ref, &object))
-               die("Failed to resolve '%s' as a valid ref.", object_ref);
+               return error("Failed to resolve '%s' as a valid ref.",
+                            object_ref);
        if (get_oid(replace_ref, &repl))
-               die("Failed to resolve '%s' as a valid ref.", replace_ref);
+               return error("Failed to resolve '%s' as a valid ref.",
+                            replace_ref);
 
        return replace_object_oid(object_ref, &object, replace_ref, &repl, force);
 }
@@ -202,7 +214,7 @@ static int replace_object(const char *object_ref, const char *replace_ref, int f
  * If "raw" is true, then the object's raw contents are printed according to
  * "type". Otherwise, we pretty-print the contents for human editing.
  */
-static void export_object(const struct object_id *oid, enum object_type type,
+static int export_object(const struct object_id *oid, enum object_type type,
                          int raw, const char *filename)
 {
        struct child_process cmd = CHILD_PROCESS_INIT;
@@ -210,7 +222,7 @@ static void export_object(const struct object_id *oid, enum object_type type,
 
        fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
        if (fd < 0)
-               die_errno("unable to open %s for writing", filename);
+               return error_errno("unable to open %s for writing", filename);
 
        argv_array_push(&cmd.args, "--no-replace-objects");
        argv_array_push(&cmd.args, "cat-file");
@@ -223,7 +235,8 @@ static void export_object(const struct object_id *oid, enum object_type type,
        cmd.out = fd;
 
        if (run_command(&cmd))
-               die("cat-file reported failure");
+               return error("cat-file reported failure");
+       return 0;
 }
 
 /*
@@ -231,14 +244,14 @@ static void export_object(const struct object_id *oid, enum object_type type,
  * interpreting it as "type", and writing the result to the object database.
  * The sha1 of the written object is returned via sha1.
  */
-static void import_object(struct object_id *oid, enum object_type type,
+static int import_object(struct object_id *oid, enum object_type type,
                          int raw, const char *filename)
 {
        int fd;
 
        fd = open(filename, O_RDONLY);
        if (fd < 0)
-               die_errno("unable to open %s for reading", filename);
+               return error_errno("unable to open %s for reading", filename);
 
        if (!raw && type == OBJ_TREE) {
                const char *argv[] = { "mktree", NULL };
@@ -250,27 +263,40 @@ static void import_object(struct object_id *oid, enum object_type type,
                cmd.in = fd;
                cmd.out = -1;
 
-               if (start_command(&cmd))
-                       die("unable to spawn mktree");
+               if (start_command(&cmd)) {
+                       close(fd);
+                       return error("unable to spawn mktree");
+               }
 
-               if (strbuf_read(&result, cmd.out, 41) < 0)
-                       die_errno("unable to read from mktree");
+               if (strbuf_read(&result, cmd.out, 41) < 0) {
+                       error_errno("unable to read from mktree");
+                       close(fd);
+                       close(cmd.out);
+                       return -1;
+               }
                close(cmd.out);
 
-               if (finish_command(&cmd))
-                       die("mktree reported failure");
-               if (get_oid_hex(result.buf, oid) < 0)
-                       die("mktree did not return an object name");
+               if (finish_command(&cmd)) {
+                       strbuf_release(&result);
+                       return error("mktree reported failure");
+               }
+               if (get_oid_hex(result.buf, oid) < 0) {
+                       strbuf_release(&result);
+                       return error("mktree did not return an object name");
+               }
 
                strbuf_release(&result);
        } else {
                struct stat st;
                int flags = HASH_FORMAT_CHECK | HASH_WRITE_OBJECT;
 
-               if (fstat(fd, &st) < 0)
-                       die_errno("unable to fstat %s", filename);
+               if (fstat(fd, &st) < 0) {
+                       error_errno("unable to fstat %s", filename);
+                       close(fd);
+                       return -1;
+               }
                if (index_fd(oid, fd, &st, type, NULL, flags) < 0)
-                       die("unable to write object to database");
+                       return error("unable to write object to database");
                /* index_fd close()s fd for us */
        }
 
@@ -278,30 +304,43 @@ static void import_object(struct object_id *oid, enum object_type type,
         * No need to close(fd) here; both run-command and index-fd
         * will have done it for us.
         */
+       return 0;
 }
 
 static int edit_and_replace(const char *object_ref, int force, int raw)
 {
-       char *tmpfile = git_pathdup("REPLACE_EDITOBJ");
+       char *tmpfile;
        enum object_type type;
        struct object_id old_oid, new_oid, prev;
        struct strbuf ref = STRBUF_INIT;
 
        if (get_oid(object_ref, &old_oid) < 0)
-               die("Not a valid object name: '%s'", object_ref);
+               return error("Not a valid object name: '%s'", object_ref);
 
-       type = sha1_object_info(old_oid.hash, NULL);
+       type = oid_object_info(the_repository, &old_oid, NULL);
        if (type < 0)
-               die("unable to get object type for %s", oid_to_hex(&old_oid));
+               return error("unable to get object type for %s",
+                            oid_to_hex(&old_oid));
 
-       check_ref_valid(&old_oid, &prev, &ref, force);
+       if (check_ref_valid(&old_oid, &prev, &ref, force)) {
+               strbuf_release(&ref);
+               return -1;
+       }
        strbuf_release(&ref);
 
-       export_object(&old_oid, type, raw, tmpfile);
-       if (launch_editor(tmpfile, NULL, NULL) < 0)
-               die("editing object file failed");
-       import_object(&new_oid, type, raw, tmpfile);
-
+       tmpfile = git_pathdup("REPLACE_EDITOBJ");
+       if (export_object(&old_oid, type, raw, tmpfile)) {
+               free(tmpfile);
+               return -1;
+       }
+       if (launch_editor(tmpfile, NULL, NULL) < 0) {
+               free(tmpfile);
+               return error("editing object file failed");
+       }
+       if (import_object(&new_oid, type, raw, tmpfile)) {
+               free(tmpfile);
+               return -1;
+       }
        free(tmpfile);
 
        if (!oidcmp(&old_oid, &new_oid))
@@ -310,7 +349,7 @@ static int edit_and_replace(const char *object_ref, int force, int raw)
        return replace_object_oid(object_ref, &old_oid, "replacement", &new_oid, force);
 }
 
-static void replace_parents(struct strbuf *buf, int argc, const char **argv)
+static int replace_parents(struct strbuf *buf, int argc, const char **argv)
 {
        struct strbuf new_parents = STRBUF_INIT;
        const char *parent_start, *parent_end;
@@ -327,9 +366,15 @@ static void replace_parents(struct strbuf *buf, int argc, const char **argv)
        /* prepare new parents */
        for (i = 0; i < argc; i++) {
                struct object_id oid;
-               if (get_oid(argv[i], &oid) < 0)
-                       die(_("Not a valid object name: '%s'"), argv[i]);
-               lookup_commit_or_die(&oid, argv[i]);
+               if (get_oid(argv[i], &oid) < 0) {
+                       strbuf_release(&new_parents);
+                       return error(_("Not a valid object name: '%s'"),
+                                    argv[i]);
+               }
+               if (!lookup_commit_reference(&oid)) {
+                       strbuf_release(&new_parents);
+                       return error(_("could not parse %s"), argv[i]);
+               }
                strbuf_addf(&new_parents, "parent %s\n", oid_to_hex(&oid));
        }
 
@@ -338,6 +383,7 @@ static void replace_parents(struct strbuf *buf, int argc, const char **argv)
                      new_parents.buf, new_parents.len);
 
        strbuf_release(&new_parents);
+       return 0;
 }
 
 struct check_mergetag_data {
@@ -345,7 +391,7 @@ struct check_mergetag_data {
        const char **argv;
 };
 
-static void check_one_mergetag(struct commit *commit,
+static int check_one_mergetag(struct commit *commit,
                               struct commit_extra_header *extra,
                               void *data)
 {
@@ -358,33 +404,35 @@ static void check_one_mergetag(struct commit *commit,
        hash_object_file(extra->value, extra->len, type_name(OBJ_TAG), &tag_oid);
        tag = lookup_tag(&tag_oid);
        if (!tag)
-               die(_("bad mergetag in commit '%s'"), ref);
+               return error(_("bad mergetag in commit '%s'"), ref);
        if (parse_tag_buffer(tag, extra->value, extra->len))
-               die(_("malformed mergetag in commit '%s'"), ref);
+               return error(_("malformed mergetag in commit '%s'"), ref);
 
        /* iterate over new parents */
        for (i = 1; i < mergetag_data->argc; i++) {
                struct object_id oid;
                if (get_oid(mergetag_data->argv[i], &oid) < 0)
-                       die(_("Not a valid object name: '%s'"), mergetag_data->argv[i]);
+                       return error(_("Not a valid object name: '%s'"),
+                                    mergetag_data->argv[i]);
                if (!oidcmp(&tag->tagged->oid, &oid))
-                       return; /* found */
+                       return 0; /* found */
        }
 
-       die(_("original commit '%s' contains mergetag '%s' that is discarded; "
-             "use --edit instead of --graft"), ref, oid_to_hex(&tag_oid));
+       return error(_("original commit '%s' contains mergetag '%s' that is "
+                      "discarded; use --edit instead of --graft"), ref,
+                    oid_to_hex(&tag_oid));
 }
 
-static void check_mergetags(struct commit *commit, int argc, const char **argv)
+static int check_mergetags(struct commit *commit, int argc, const char **argv)
 {
        struct check_mergetag_data mergetag_data;
 
        mergetag_data.argc = argc;
        mergetag_data.argv = argv;
-       for_each_mergetag(check_one_mergetag, commit, &mergetag_data);
+       return for_each_mergetag(check_one_mergetag, commit, &mergetag_data);
 }
 
-static int create_graft(int argc, const char **argv, int force)
+static int create_graft(int argc, const char **argv, int force, int gentle)
 {
        struct object_id old_oid, new_oid;
        const char *old_ref = argv[0];
@@ -394,33 +442,81 @@ static int create_graft(int argc, const char **argv, int force)
        unsigned long size;
 
        if (get_oid(old_ref, &old_oid) < 0)
-               die(_("Not a valid object name: '%s'"), old_ref);
-       commit = lookup_commit_or_die(&old_oid, old_ref);
+               return error(_("Not a valid object name: '%s'"), old_ref);
+       commit = lookup_commit_reference(&old_oid);
+       if (!commit)
+               return error(_("could not parse %s"), old_ref);
 
        buffer = get_commit_buffer(commit, &size);
        strbuf_add(&buf, buffer, size);
        unuse_commit_buffer(commit, buffer);
 
-       replace_parents(&buf, argc - 1, &argv[1]);
+       if (replace_parents(&buf, argc - 1, &argv[1]) < 0) {
+               strbuf_release(&buf);
+               return -1;
+       }
 
        if (remove_signature(&buf)) {
                warning(_("the original commit '%s' has a gpg signature."), old_ref);
                warning(_("the signature will be removed in the replacement commit!"));
        }
 
-       check_mergetags(commit, argc, argv);
+       if (check_mergetags(commit, argc, argv)) {
+               strbuf_release(&buf);
+               return -1;
+       }
 
-       if (write_object_file(buf.buf, buf.len, commit_type, &new_oid))
-               die(_("could not write replacement commit for: '%s'"), old_ref);
+       if (write_object_file(buf.buf, buf.len, commit_type, &new_oid)) {
+               strbuf_release(&buf);
+               return error(_("could not write replacement commit for: '%s'"),
+                            old_ref);
+       }
 
        strbuf_release(&buf);
 
-       if (!oidcmp(&old_oid, &new_oid))
+       if (!oidcmp(&old_oid, &new_oid)) {
+               if (gentle) {
+                       warning("graft for '%s' unnecessary", oid_to_hex(&old_oid));
+                       return 0;
+               }
                return error("new commit is the same as the old one: '%s'", oid_to_hex(&old_oid));
+       }
 
        return replace_object_oid(old_ref, &old_oid, "replacement", &new_oid, force);
 }
 
+static int convert_graft_file(int force)
+{
+       const char *graft_file = get_graft_file();
+       FILE *fp = fopen_or_warn(graft_file, "r");
+       struct strbuf buf = STRBUF_INIT, err = STRBUF_INIT;
+       struct argv_array args = ARGV_ARRAY_INIT;
+
+       if (!fp)
+               return -1;
+
+       while (strbuf_getline(&buf, fp) != EOF) {
+               if (*buf.buf == '#')
+                       continue;
+
+               argv_array_split(&args, buf.buf);
+               if (args.argc && create_graft(args.argc, args.argv, force, 1))
+                       strbuf_addf(&err, "\n\t%s", buf.buf);
+               argv_array_clear(&args);
+       }
+       fclose(fp);
+
+       strbuf_release(&buf);
+
+       if (!err.len)
+               return unlink_or_warn(graft_file);
+
+       warning(_("could not convert the following graft(s):\n%s"), err.buf);
+       strbuf_release(&err);
+
+       return -1;
+}
+
 int cmd_replace(int argc, const char **argv, const char *prefix)
 {
        int force = 0;
@@ -432,6 +528,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
                MODE_DELETE,
                MODE_EDIT,
                MODE_GRAFT,
+               MODE_CONVERT_GRAFT_FILE,
                MODE_REPLACE
        } cmdmode = MODE_UNSPECIFIED;
        struct option options[] = {
@@ -439,6 +536,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
                OPT_CMDMODE('d', "delete", &cmdmode, N_("delete replace refs"), MODE_DELETE),
                OPT_CMDMODE('e', "edit", &cmdmode, N_("edit existing object"), MODE_EDIT),
                OPT_CMDMODE('g', "graft", &cmdmode, N_("change a commit's parents"), MODE_GRAFT),
+               OPT_CMDMODE(0, "convert-graft-file", &cmdmode, N_("convert existing graft file"), MODE_CONVERT_GRAFT_FILE),
                OPT_BOOL_F('f', "force", &force, N_("replace the ref if it exists"),
                           PARSE_OPT_NOCOMPLETE),
                OPT_BOOL(0, "raw", &raw, N_("do not pretty-print contents for --edit")),
@@ -461,7 +559,8 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
        if (force &&
            cmdmode != MODE_REPLACE &&
            cmdmode != MODE_EDIT &&
-           cmdmode != MODE_GRAFT)
+           cmdmode != MODE_GRAFT &&
+           cmdmode != MODE_CONVERT_GRAFT_FILE)
                usage_msg_opt("-f only makes sense when writing a replacement",
                              git_replace_usage, options);
 
@@ -492,7 +591,13 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
                if (argc < 1)
                        usage_msg_opt("-g needs at least one argument",
                                      git_replace_usage, options);
-               return create_graft(argc, argv, force);
+               return create_graft(argc, argv, force, 0);
+
+       case MODE_CONVERT_GRAFT_FILE:
+               if (argc != 0)
+                       usage_msg_opt("--convert-graft-file takes no argument",
+                                     git_replace_usage, options);
+               return !!convert_graft_file(force);
 
        case MODE_LIST:
                if (argc > 1)
@@ -501,6 +606,6 @@ int cmd_replace(int argc, const char **argv, const char *prefix)
                return list_replace_refs(argv[0], format);
 
        default:
-               die("BUG: invalid cmdmode %d", (int)cmdmode);
+               BUG("invalid cmdmode %d", (int)cmdmode);
        }
 }
index 5da0f75de95cc9dc19db7d53a5e4df5140845082..a862c70fab99290b5faf3e700e88194589583329 100644 (file)
@@ -109,7 +109,7 @@ static void print_new_head_line(struct commit *commit)
        struct strbuf buf = STRBUF_INIT;
 
        printf(_("HEAD is now at %s"),
-               find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV));
+               find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV));
 
        pp_commit_easy(CMIT_FMT_ONELINE, commit, &buf);
        if (buf.len > 0)
@@ -314,7 +314,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
        unborn = !strcmp(rev, "HEAD") && get_oid("HEAD", &oid);
        if (unborn) {
                /* reset on unborn branch: treat as reset to empty tree */
-               hashcpy(oid.hash, EMPTY_TREE_SHA1_BIN);
+               oidcpy(&oid, the_hash_algo->empty_tree);
        } else if (!pathspec.nr) {
                struct commit *commit;
                if (get_oid_committish(rev, &oid))
index 6f5b9b0847321ca214b4d32719eaeacefffd5ce4..fadd3ec14cbf0469c332a85278e5d1b4932ef788 100644 (file)
@@ -108,7 +108,7 @@ static void show_commit(struct commit *commit, void *data)
        if (!revs->graph)
                fputs(get_revision_mark(revs, commit), stdout);
        if (revs->abbrev_commit && revs->abbrev)
-               fputs(find_unique_abbrev(commit->object.oid.hash, revs->abbrev),
+               fputs(find_unique_abbrev(&commit->object.oid, revs->abbrev),
                      stdout);
        else
                fputs(oid_to_hex(&commit->object.oid), stdout);
index a1e680b5e912beeed183dc271b0ae970a45a4814..4f49e96bfd0166aeb6f9875a688ff0dd83d631b5 100644 (file)
@@ -159,7 +159,7 @@ static void show_rev(int type, const struct object_id *oid, const char *name)
                }
        }
        else if (abbrev)
-               show_with_type(type, find_unique_abbrev(oid->hash, abbrev));
+               show_with_type(type, find_unique_abbrev(oid, abbrev));
        else
                show_with_type(type, oid_to_hex(oid));
 }
@@ -282,6 +282,10 @@ static int try_difference(const char *arg)
                        struct commit *a, *b;
                        a = lookup_commit_reference(&start_oid);
                        b = lookup_commit_reference(&end_oid);
+                       if (!a || !b) {
+                               *dotdot = '.';
+                               return 0;
+                       }
                        exclude = get_merge_bases(a, b);
                        while (exclude) {
                                struct commit *commit = pop_commit(&exclude);
@@ -328,12 +332,12 @@ static int try_parent_shorthands(const char *arg)
                return 0;
 
        *dotdot = 0;
-       if (get_oid_committish(arg, &oid)) {
+       if (get_oid_committish(arg, &oid) ||
+           !(commit = lookup_commit_reference(&oid))) {
                *dotdot = '^';
                return 0;
        }
 
-       commit = lookup_commit_reference(&oid);
        if (exclude_parent &&
            exclude_parent > commit_list_count(commit->parents)) {
                *dotdot = '^';
@@ -887,8 +891,8 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
                                if (read_cache() < 0)
                                        die(_("Could not read the index"));
                                if (the_index.split_index) {
-                                       const unsigned char *sha1 = the_index.split_index->base_sha1;
-                                       const char *path = git_path("sharedindex.%s", sha1_to_hex(sha1));
+                                       const struct object_id *oid = &the_index.split_index->base_oid;
+                                       const char *path = git_path("sharedindex.%s", oid_to_hex(oid));
                                        strbuf_reset(&buf);
                                        puts(relative_path(path, prefix, &buf));
                                }
index 4447bb4d0faf8c34f3fc96361a651eaad396d6d4..65b448ef8ee91079194841762d4b7a2193eec9a9 100644 (file)
@@ -178,7 +178,7 @@ static int check_local_mod(struct object_id *head, int index_only)
                 * way as changed from the HEAD.
                 */
                if (no_head
-                    || get_tree_entry(head->hash, name, oid.hash, &mode)
+                    || get_tree_entry(head, name, &oid, &mode)
                     || ce->ce_mode != create_ce_mode(mode)
                     || oidcmp(&ce->oid, &oid))
                        staged_changes = 1;
@@ -233,8 +233,6 @@ static int check_local_mod(struct object_id *head, int index_only)
        return errs;
 }
 
-static struct lock_file lock_file;
-
 static int show_only = 0, force = 0, index_only = 0, recursive = 0, quiet = 0;
 static int ignore_unmatch = 0;
 
@@ -251,6 +249,7 @@ static struct option builtin_rm_options[] = {
 
 int cmd_rm(int argc, const char **argv, const char *prefix)
 {
+       struct lock_file lock_file = LOCK_INIT;
        int i;
        struct pathspec pathspec;
        char *seen;
index fc4f0bb5fbc033604a13a147094c0d1bc661db17..4923b1058c667bd45282c0930e1089594a3f4731 100644 (file)
@@ -14,6 +14,7 @@
 #include "sha1-array.h"
 #include "gpg-interface.h"
 #include "gettext.h"
+#include "protocol.h"
 
 static const char * const send_pack_usage[] = {
        N_("git send-pack [--all | --mirror] [--dry-run] [--force] "
@@ -125,8 +126,7 @@ static int send_pack_config(const char *k, const char *v, void *cb)
 
 int cmd_send_pack(int argc, const char **argv, const char *prefix)
 {
-       int i, nr_refspecs = 0;
-       const char **refspecs = NULL;
+       struct refspec rs = REFSPEC_INIT_PUSH;
        const char *remote_name = NULL;
        struct remote *remote = NULL;
        const char *dest = NULL;
@@ -154,6 +154,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
        int progress = -1;
        int from_stdin = 0;
        struct push_cas_option cas = {0};
+       struct packet_reader reader;
 
        struct option options[] = {
                OPT__VERBOSITY(&verbose),
@@ -187,8 +188,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
        argc = parse_options(argc, argv, prefix, options, send_pack_usage, 0);
        if (argc > 0) {
                dest = argv[0];
-               refspecs = (const char **)(argv + 1);
-               nr_refspecs = argc - 1;
+               refspec_appendn(&rs, argv + 1, argc - 1);
        }
 
        if (!dest)
@@ -207,31 +207,23 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
        args.push_options = push_options.nr ? &push_options : NULL;
 
        if (from_stdin) {
-               struct argv_array all_refspecs = ARGV_ARRAY_INIT;
-
-               for (i = 0; i < nr_refspecs; i++)
-                       argv_array_push(&all_refspecs, refspecs[i]);
-
                if (args.stateless_rpc) {
                        const char *buf;
                        while ((buf = packet_read_line(0, NULL)))
-                               argv_array_push(&all_refspecs, buf);
+                               refspec_append(&rs, buf);
                } else {
                        struct strbuf line = STRBUF_INIT;
                        while (strbuf_getline(&line, stdin) != EOF)
-                               argv_array_push(&all_refspecs, line.buf);
+                               refspec_append(&rs, line.buf);
                        strbuf_release(&line);
                }
-
-               refspecs = all_refspecs.argv;
-               nr_refspecs = all_refspecs.argc;
        }
 
        /*
         * --all and --mirror are incompatible; neither makes sense
         * with any refspecs.
         */
-       if ((nr_refspecs > 0 && (send_all || args.send_mirror)) ||
+       if ((rs.nr > 0 && (send_all || args.send_mirror)) ||
            (send_all && args.send_mirror))
                usage_with_options(send_pack_usage, options);
 
@@ -256,10 +248,22 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
                        args.verbose ? CONNECT_VERBOSE : 0);
        }
 
-       get_remote_heads(fd[0], NULL, 0, &remote_refs, REF_NORMAL,
-                        &extra_have, &shallow);
-
-       transport_verify_remote_names(nr_refspecs, refspecs);
+       packet_reader_init(&reader, fd[0], NULL, 0,
+                          PACKET_READ_CHOMP_NEWLINE |
+                          PACKET_READ_GENTLE_ON_EOF);
+
+       switch (discover_version(&reader)) {
+       case protocol_v2:
+               die("support for protocol v2 not implemented yet");
+               break;
+       case protocol_v1:
+       case protocol_v0:
+               get_remote_heads(&reader, &remote_refs, REF_NORMAL,
+                                &extra_have, &shallow);
+               break;
+       case protocol_unknown_version:
+               BUG("unknown protocol version");
+       }
 
        local_refs = get_local_heads();
 
@@ -271,7 +275,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
                flags |= MATCH_REFS_MIRROR;
 
        /* match them up */
-       if (match_push_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags))
+       if (match_push_refs(local_refs, &remote_refs, &rs, flags))
                return -1;
 
        if (!is_empty_cas(&cas))
diff --git a/builtin/serve.c b/builtin/serve.c
new file mode 100644 (file)
index 0000000..d3fd240
--- /dev/null
@@ -0,0 +1,30 @@
+#include "cache.h"
+#include "builtin.h"
+#include "parse-options.h"
+#include "serve.h"
+
+static char const * const serve_usage[] = {
+       N_("git serve [<options>]"),
+       NULL
+};
+
+int cmd_serve(int argc, const char **argv, const char *prefix)
+{
+       struct serve_options opts = SERVE_OPTIONS_INIT;
+
+       struct option options[] = {
+               OPT_BOOL(0, "stateless-rpc", &opts.stateless_rpc,
+                        N_("quit after a single request/response exchange")),
+               OPT_BOOL(0, "advertise-capabilities", &opts.advertise_capabilities,
+                        N_("exit immediately after advertising capabilities")),
+               OPT_END()
+       };
+
+       /* ignore all unknown cmdline switches for now */
+       argc = parse_options(argc, argv, prefix, options, serve_usage,
+                            PARSE_OPT_KEEP_DASHDASH |
+                            PARSE_OPT_KEEP_UNKNOWN);
+       serve(&opts);
+
+       return 0;
+}
index e29875b84389b25237e39e0112eafa8ac34599ee..608d6ba77bdfb4673513444651053d0e8e789020 100644 (file)
@@ -11,7 +11,8 @@
 #include "parse-options.h"
 
 static char const * const shortlog_usage[] = {
-       N_("git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"),
+       N_("git shortlog [<options>] [<revision-range>] [[--] <path>...]"),
+       N_("git log --pretty=short | git shortlog [<options>]"),
        NULL
 };
 
@@ -283,6 +284,7 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
        for (;;) {
                switch (parse_options_step(&ctx, options, shortlog_usage)) {
                case PARSE_OPT_HELP:
+               case PARSE_OPT_ERROR:
                        exit(129);
                case PARSE_OPT_DONE:
                        goto parse_done;
@@ -292,6 +294,11 @@ int cmd_shortlog(int argc, const char **argv, const char *prefix)
 parse_done:
        argc = parse_options_end(&ctx);
 
+       if (nongit && argc > 1) {
+               error(_("too many arguments given outside repository"));
+               usage_with_options(shortlog_usage, options);
+       }
+
        if (setup_revisions(argc, argv, &rev, NULL) != 1) {
                error(_("unrecognized argument: %s"), argv[1]);
                usage_with_options(shortlog_usage, options);
index e8a4aa40cb4b6cf8787af3dd35d833a92a85bba3..6c2148b71db593af1a4ef8d2d1bdbdfe16661851 100644 (file)
@@ -292,7 +292,7 @@ static void show_one_commit(struct commit *commit, int no_name)
                }
                else
                        printf("[%s] ",
-                              find_unique_abbrev(commit->object.oid.hash,
+                              find_unique_abbrev(&commit->object.oid,
                                                  DEFAULT_ABBREV));
        }
        puts(pretty_str);
index 41e5e71cad660d26ddc90ffeaa383fd7bf10f79f..f2eb1a7724058bb1db237a6199d16e5ff1ef495a 100644 (file)
@@ -29,7 +29,7 @@ static void show_one(const char *refname, const struct object_id *oid)
        if (quiet)
                return;
 
-       hex = find_unique_abbrev(oid->hash, abbrev);
+       hex = find_unique_abbrev(oid, abbrev);
        if (hash_only)
                printf("%s\n", hex);
        else
@@ -39,7 +39,7 @@ static void show_one(const char *refname, const struct object_id *oid)
                return;
 
        if (!peel_ref(refname, &peeled)) {
-               hex = find_unique_abbrev(peeled.hash, abbrev);
+               hex = find_unique_abbrev(&peeled, abbrev);
                printf("%s %s^{}\n", hex, refname);
        }
 }
index cd75c7f61c874809661a51f138becb1d2a53baaa..05e5ed32b042676dc0ea4264f607584d5d046bff 100644 (file)
 #include "run-command.h"
 #include "remote.h"
 #include "refs.h"
+#include "refspec.h"
 #include "connect.h"
 #include "revision.h"
 #include "diffcore.h"
 #include "diff.h"
+#include "object-store.h"
 #include "dir.h"
 
 #define OPT_QUIET (1 << 0)
@@ -455,7 +457,7 @@ static void init_submodule(const char *path, const char *prefix,
 
        displaypath = get_submodule_displaypath(path, prefix);
 
-       sub = submodule_from_path(&null_oid, path);
+       sub = submodule_from_path(the_repository, &null_oid, path);
 
        if (!sub)
                die(_("No url found for submodule path '%s' in .gitmodules"),
@@ -596,8 +598,12 @@ static void print_status(unsigned int flags, char state, const char *path,
 
        printf("%c%s %s", state, oid_to_hex(oid), displaypath);
 
-       if (state == ' ' || state == '+')
-               printf(" (%s)", compute_rev_name(path, oid_to_hex(oid)));
+       if (state == ' ' || state == '+') {
+               const char *name = compute_rev_name(path, oid_to_hex(oid));
+
+               if (name)
+                       printf(" (%s)", name);
+       }
 
        printf("\n");
 }
@@ -622,7 +628,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
        struct rev_info rev;
        int diff_files_result;
 
-       if (!submodule_from_path(&null_oid, path))
+       if (!submodule_from_path(the_repository, &null_oid, path))
                die(_("no submodule mapping found in .gitmodules for path '%s'"),
                      path);
 
@@ -655,9 +661,13 @@ static void status_submodule(const char *path, const struct object_id *ce_oid,
                             displaypath);
        } else if (!(flags & OPT_CACHED)) {
                struct object_id oid;
+               struct ref_store *refs = get_submodule_ref_store(path);
 
-               if (refs_head_ref(get_submodule_ref_store(path),
-                                 handle_submodule_head_ref, &oid))
+               if (!refs) {
+                       print_status(flags, '-', path, ce_oid, displaypath);
+                       goto cleanup;
+               }
+               if (refs_head_ref(refs, handle_submodule_head_ref, &oid))
                        die(_("could not resolve HEAD ref inside the "
                              "submodule '%s'"), path);
 
@@ -742,7 +752,7 @@ static int module_name(int argc, const char **argv, const char *prefix)
        if (argc != 2)
                usage(_("git submodule--helper name <path>"));
 
-       sub = submodule_from_path(&null_oid, argv[1]);
+       sub = submodule_from_path(the_repository, &null_oid, argv[1]);
 
        if (!sub)
                die(_("no submodule mapping found in .gitmodules for path '%s'"),
@@ -773,7 +783,7 @@ static void sync_submodule(const char *path, const char *prefix,
        if (!is_submodule_active(the_repository, path))
                return;
 
-       sub = submodule_from_path(&null_oid, path);
+       sub = submodule_from_path(the_repository, &null_oid, path);
 
        if (sub && sub->url) {
                if (starts_with_dot_dot_slash(sub->url) ||
@@ -926,7 +936,7 @@ static void deinit_submodule(const char *path, const char *prefix,
        struct strbuf sb_config = STRBUF_INIT;
        char *sub_git_dir = xstrfmt("%s/.git", path);
 
-       sub = submodule_from_path(&null_oid, path);
+       sub = submodule_from_path(the_repository, &null_oid, path);
 
        if (!sub || !sub->name)
                goto cleanup;
@@ -1057,7 +1067,7 @@ static int module_deinit(int argc, const char **argv, const char *prefix)
 }
 
 static int clone_submodule(const char *path, const char *gitdir, const char *url,
-                          const char *depth, struct string_list *reference,
+                          const char *depth, struct string_list *reference, int dissociate,
                           int quiet, int progress)
 {
        struct child_process cp = CHILD_PROCESS_INIT;
@@ -1076,6 +1086,8 @@ static int clone_submodule(const char *path, const char *gitdir, const char *url
                        argv_array_pushl(&cp.args, "--reference",
                                         item->string, NULL);
        }
+       if (dissociate)
+               argv_array_push(&cp.args, "--dissociate");
        if (gitdir && *gitdir)
                argv_array_pushl(&cp.args, "--separate-git-dir", gitdir, NULL);
 
@@ -1192,7 +1204,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
        char *p, *path = NULL, *sm_gitdir;
        struct strbuf sb = STRBUF_INIT;
        struct string_list reference = STRING_LIST_INIT_NODUP;
-       int require_init = 0;
+       int dissociate = 0, require_init = 0;
        char *sm_alternate = NULL, *error_strategy = NULL;
 
        struct option module_clone_options[] = {
@@ -1211,6 +1223,8 @@ static int module_clone(int argc, const char **argv, const char *prefix)
                OPT_STRING_LIST(0, "reference", &reference,
                           N_("repo"),
                           N_("reference repository")),
+               OPT_BOOL(0, "dissociate", &dissociate,
+                          N_("use --reference only while cloning")),
                OPT_STRING(0, "depth", &depth,
                           N_("string"),
                           N_("depth for shallow clones")),
@@ -1256,7 +1270,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
 
                prepare_possible_alternates(name, &reference);
 
-               if (clone_submodule(path, sm_gitdir, url, depth, &reference,
+               if (clone_submodule(path, sm_gitdir, url, depth, &reference, dissociate,
                                    quiet, progress))
                        die(_("clone of '%s' into submodule path '%s' failed"),
                            url, path);
@@ -1270,8 +1284,7 @@ static int module_clone(int argc, const char **argv, const char *prefix)
                strbuf_reset(&sb);
        }
 
-       /* Connect module worktree and git dir */
-       connect_work_tree_and_git_dir(path, sm_gitdir);
+       connect_work_tree_and_git_dir(path, sm_gitdir, 0);
 
        p = git_pathdup_submodule(path, "config");
        if (!p)
@@ -1311,6 +1324,7 @@ struct submodule_update_clone {
        int quiet;
        int recommend_shallow;
        struct string_list references;
+       int dissociate;
        unsigned require_init;
        const char *depth;
        const char *recursive_prefix;
@@ -1327,7 +1341,7 @@ struct submodule_update_clone {
        int failed_clones_nr, failed_clones_alloc;
 };
 #define SUBMODULE_UPDATE_CLONE_INIT {0, MODULE_LIST_INIT, 0, \
-       SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, \
+       SUBMODULE_UPDATE_STRATEGY_INIT, 0, 0, -1, STRING_LIST_INIT_DUP, 0, 0, \
        NULL, NULL, NULL, \
        STRING_LIST_INIT_DUP, 0, NULL, 0, 0}
 
@@ -1379,7 +1393,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
                goto cleanup;
        }
 
-       sub = submodule_from_path(&null_oid, ce->name);
+       sub = submodule_from_path(the_repository, &null_oid, ce->name);
 
        if (suc->recursive_prefix)
                displaypath = relative_path(suc->recursive_prefix,
@@ -1456,6 +1470,8 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
                for_each_string_list_item(item, &suc->references)
                        argv_array_pushl(&child->args, "--reference", item->string, NULL);
        }
+       if (suc->dissociate)
+               argv_array_push(&child->args, "--dissociate");
        if (suc->depth)
                argv_array_push(&child->args, suc->depth);
 
@@ -1589,6 +1605,8 @@ static int update_clone(int argc, const char **argv, const char *prefix)
                           N_("rebase, merge, checkout or none")),
                OPT_STRING_LIST(0, "reference", &suc.references, N_("repo"),
                           N_("reference repository")),
+               OPT_BOOL(0, "dissociate", &suc.dissociate,
+                          N_("use --reference only while cloning")),
                OPT_STRING(0, "depth", &suc.depth, "<depth>",
                           N_("Create a shallow clone truncated to the "
                              "specified number of revisions")),
@@ -1666,7 +1684,7 @@ static const char *remote_submodule_branch(const char *path)
        const char *branch = NULL;
        char *key;
 
-       sub = submodule_from_path(&null_oid, path);
+       sub = submodule_from_path(the_repository, &null_oid, path);
        if (!sub)
                return NULL;
 
@@ -1751,13 +1769,14 @@ static int push_check(int argc, const char **argv, const char *prefix)
 
        /* Check the refspec */
        if (argc > 2) {
-               int i, refspec_nr = argc - 2;
+               int i;
                struct ref *local_refs = get_local_heads();
-               struct refspec *refspec = parse_push_refspec(refspec_nr,
-                                                            argv + 2);
+               struct refspec refspec = REFSPEC_INIT_PUSH;
+
+               refspec_appendn(&refspec, argv + 2, argc - 2);
 
-               for (i = 0; i < refspec_nr; i++) {
-                       struct refspec *rs = refspec + i;
+               for (i = 0; i < refspec.nr; i++) {
+                       const struct refspec_item *rs = &refspec.items[i];
 
                        if (rs->pattern || rs->matching)
                                continue;
@@ -1784,7 +1803,7 @@ static int push_check(int argc, const char **argv, const char *prefix)
                                    rs->src);
                        }
                }
-               free_refspec(refspec_nr, refspec);
+               refspec_clear(&refspec);
        }
        free(head);
 
index da186691ed8853bc5848c4106c752b015756eda3..5d0dd112408419a0090cbe179d69c0ea709f22a7 100644 (file)
@@ -99,7 +99,8 @@ static int delete_tag(const char *name, const char *ref,
 {
        if (delete_ref(NULL, ref, oid, 0))
                return 1;
-       printf(_("Deleted tag '%s' (was %s)\n"), name, find_unique_abbrev(oid->hash, DEFAULT_ABBREV));
+       printf(_("Deleted tag '%s' (was %s)\n"), name,
+              find_unique_abbrev(oid, DEFAULT_ABBREV));
        return 0;
 }
 
@@ -117,7 +118,7 @@ static int verify_tag(const char *name, const char *ref,
                return -1;
 
        if (format->format)
-               pretty_print_ref(name, oid->hash, format);
+               pretty_print_ref(name, oid, format);
 
        return 0;
 }
@@ -167,7 +168,7 @@ static void write_tag_body(int fd, const struct object_id *oid)
        enum object_type type;
        char *buf, *sp;
 
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf)
                return;
        /* skip header */
@@ -211,7 +212,7 @@ static void create_tag(const struct object_id *object, const char *tag,
        struct strbuf header = STRBUF_INIT;
        char *path = NULL;
 
-       type = sha1_object_info(object->hash, NULL);
+       type = oid_object_info(the_repository, object, NULL);
        if (type <= OBJ_NONE)
            die(_("bad object type."));
 
@@ -293,17 +294,17 @@ static void create_reflog_msg(const struct object_id *oid, struct strbuf *sb)
                strbuf_addstr(sb, rla);
        } else {
                strbuf_addstr(sb, "tag: tagging ");
-               strbuf_add_unique_abbrev(sb, oid->hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(sb, oid, DEFAULT_ABBREV);
        }
 
        strbuf_addstr(sb, " (");
-       type = sha1_object_info(oid->hash, NULL);
+       type = oid_object_info(the_repository, oid, NULL);
        switch (type) {
        default:
                strbuf_addstr(sb, "object of unknown type");
                break;
        case OBJ_COMMIT:
-               if ((buf = read_sha1_file(oid->hash, &type, &size)) != NULL) {
+               if ((buf = read_object_file(oid, &type, &size)) != NULL) {
                        subject_len = find_commit_subject(buf, &subject_start);
                        strbuf_insert(sb, sb->len, subject_start, subject_len);
                } else {
@@ -558,7 +559,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                die("%s", err.buf);
        ref_transaction_free(transaction);
        if (force && !is_null_oid(&prev) && oidcmp(&prev, &object))
-               printf(_("Updated tag '%s' (was %s)\n"), tag, find_unique_abbrev(prev.hash, DEFAULT_ABBREV));
+               printf(_("Updated tag '%s' (was %s)\n"), tag,
+                      find_unique_abbrev(&prev, DEFAULT_ABBREV));
 
        UNLEAK(buf);
        UNLEAK(ref);
index 32e01555774c838e489fd33c675488e754c3e8e2..300eb59657e29cace38798029a9170834cac7c9e 100644 (file)
@@ -9,7 +9,7 @@ static char *create_temp_file(struct object_id *oid)
        unsigned long size;
        int fd;
 
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf || type != OBJ_BLOB)
                die("unable to read blob object %s", oid_to_hex(oid));
 
index c8f1406d2340c5cf2c1ac775039e32a244fede33..6e81ca8ca28a67ce3d7bc0d62556fd41eda2ba52 100644 (file)
@@ -199,7 +199,7 @@ static int check_object(struct object *obj, int type, void *data, struct fsck_op
 
        if (!(obj->flags & FLAG_OPEN)) {
                unsigned long size;
-               int type = sha1_object_info(obj->oid.hash, &size);
+               int type = oid_object_info(the_repository, &obj->oid, &size);
                if (type != obj->type || type <= 0)
                        die("object of unexpected type");
                obj->flags |= FLAG_WRITTEN;
@@ -423,7 +423,7 @@ static void unpack_delta_entry(enum object_type type, unsigned long delta_size,
        if (resolve_against_held(nr, &base_oid, delta_data, delta_size))
                return;
 
-       base = read_sha1_file(base_oid.hash, &type, &base_size);
+       base = read_object_file(&base_oid, &type, &base_size);
        if (!base) {
                error("failed to read delta-pack base object %s",
                      oid_to_hex(&base_oid));
index 1af8a00b889c968634389bf61138200d97eb32f9..a8709a26ec4b8bb79cbb20bfa4a7892e063c804d 100644 (file)
@@ -602,7 +602,7 @@ static struct cache_entry *read_one_ent(const char *which,
        int size;
        struct cache_entry *ce;
 
-       if (get_tree_entry(ent->hash, path, oid.hash, &mode)) {
+       if (get_tree_entry(ent, path, &oid, &mode)) {
                if (which)
                        error("%s: not in %s branch.", path, which);
                return NULL;
@@ -1069,6 +1069,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
                        break;
                switch (parseopt_state) {
                case PARSE_OPT_HELP:
+               case PARSE_OPT_ERROR:
                        exit(129);
                case PARSE_OPT_NON_OPTION:
                case PARSE_OPT_DONE:
@@ -1173,7 +1174,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
                report(_("Untracked cache enabled for '%s'"), get_git_work_tree());
                break;
        default:
-               die("BUG: bad untracked_cache value: %d", untracked_cache);
+               BUG("bad untracked_cache value: %d", untracked_cache);
        }
 
        if (fsmonitor > 0) {
diff --git a/builtin/upload-pack.c b/builtin/upload-pack.c
new file mode 100644 (file)
index 0000000..decde5a
--- /dev/null
@@ -0,0 +1,74 @@
+#include "cache.h"
+#include "builtin.h"
+#include "exec-cmd.h"
+#include "pkt-line.h"
+#include "parse-options.h"
+#include "protocol.h"
+#include "upload-pack.h"
+#include "serve.h"
+
+static const char * const upload_pack_usage[] = {
+       N_("git upload-pack [<options>] <dir>"),
+       NULL
+};
+
+int cmd_upload_pack(int argc, const char **argv, const char *prefix)
+{
+       const char *dir;
+       int strict = 0;
+       struct upload_pack_options opts = { 0 };
+       struct serve_options serve_opts = SERVE_OPTIONS_INIT;
+       struct option options[] = {
+               OPT_BOOL(0, "stateless-rpc", &opts.stateless_rpc,
+                        N_("quit after a single request/response exchange")),
+               OPT_BOOL(0, "advertise-refs", &opts.advertise_refs,
+                        N_("exit immediately after initial ref advertisement")),
+               OPT_BOOL(0, "strict", &strict,
+                        N_("do not try <directory>/.git/ if <directory> is no Git directory")),
+               OPT_INTEGER(0, "timeout", &opts.timeout,
+                           N_("interrupt transfer after <n> seconds of inactivity")),
+               OPT_END()
+       };
+
+       packet_trace_identity("upload-pack");
+       check_replace_refs = 0;
+
+       argc = parse_options(argc, argv, NULL, options, upload_pack_usage, 0);
+
+       if (argc != 1)
+               usage_with_options(upload_pack_usage, options);
+
+       if (opts.timeout)
+               opts.daemon_mode = 1;
+
+       setup_path();
+
+       dir = argv[0];
+
+       if (!enter_repo(dir, strict))
+               die("'%s' does not appear to be a git repository", dir);
+
+       switch (determine_protocol_version_server()) {
+       case protocol_v2:
+               serve_opts.advertise_capabilities = opts.advertise_refs;
+               serve_opts.stateless_rpc = opts.stateless_rpc;
+               serve(&serve_opts);
+               break;
+       case protocol_v1:
+               /*
+                * v1 is just the original protocol with a version string,
+                * so just fall through after writing the version string.
+                */
+               if (opts.advertise_refs || !opts.stateless_rpc)
+                       packet_write_fmt(1, "version 1\n");
+
+               /* fallthrough */
+       case protocol_v0:
+               upload_pack(&opts);
+               break;
+       case protocol_unknown_version:
+               BUG("unknown protocol version");
+       }
+
+       return 0;
+}
index 05315ea7c966d3ed5b91e4cbd77eaa9943af253d..dcdaada111071c84b56022d9050ae06ffafbc25f 100644 (file)
@@ -44,7 +44,7 @@ static int verify_commit(const char *name, unsigned flags)
        if (get_oid(name, &oid))
                return error("commit '%s' not found.", name);
 
-       buf = read_sha1_file(oid.hash, &type, &size);
+       buf = read_object_file(&oid, &type, &size);
        if (!buf)
                return error("%s: unable to read file.", name);
        if (type != OBJ_COMMIT)
index ad7b79fa5cd718daf3be5f1a46a1fbb2bed41ad5..6fa04b751ac1d6ae18b8a42e700e2cefa6427a41 100644 (file)
@@ -72,7 +72,7 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix)
                }
 
                if (format.format)
-                       pretty_print_ref(name, oid.hash, &format);
+                       pretty_print_ref(name, &oid, &format);
        }
        return had_error;
 }
index 670555deddaca8ff8050c03ea68c83c7b4e459e6..5c7d2bb1807f942139b3ec41b426320e4b0cfc2a 100644 (file)
@@ -29,8 +29,6 @@ struct add_opts {
        int detach;
        int checkout;
        int keep_locked;
-       const char *new_branch;
-       int force_new_branch;
 };
 
 static int show_only;
@@ -101,16 +99,9 @@ static int prune_worktree(const char *id, struct strbuf *reason)
        }
        path[len] = '\0';
        if (!file_exists(path)) {
-               struct stat st_link;
                free(path);
-               /*
-                * the repo is moved manually and has not been
-                * accessed since?
-                */
-               if (!stat(git_path("worktrees/%s/link", id), &st_link) &&
-                   st_link.st_nlink > 1)
-                       return 0;
-               if (st.st_mtime <= expire) {
+               if (stat(git_path("worktrees/%s/index", id), &st) ||
+                   st.st_mtime <= expire) {
                        strbuf_addf(reason, _("Removing worktrees/%s: gitdir file points to non-existent location"), id);
                        return 1;
                } else {
@@ -305,8 +296,6 @@ static int add_worktree(const char *path, const char *refname,
        strbuf_addf(&sb, "%s/commondir", sb_repo.buf);
        write_file(sb.buf, "../..");
 
-       fprintf_ln(stderr, _("Preparing %s (identifier %s)"), path, name);
-
        argv_array_pushf(&child_env, "%s=%s", GIT_DIR_ENVIRONMENT, sb_git.buf);
        argv_array_pushf(&child_env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, path);
        cp.git_cmd = 1;
@@ -373,18 +362,75 @@ done:
        return ret;
 }
 
+static void print_preparing_worktree_line(int detach,
+                                         const char *branch,
+                                         const char *new_branch,
+                                         int force_new_branch)
+{
+       if (force_new_branch) {
+               struct commit *commit = lookup_commit_reference_by_name(new_branch);
+               if (!commit)
+                       printf_ln(_("Preparing worktree (new branch '%s')"), new_branch);
+               else
+                       printf_ln(_("Preparing worktree (resetting branch '%s'; was at %s)"),
+                                 new_branch,
+                                 find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV));
+       } else if (new_branch) {
+               printf_ln(_("Preparing worktree (new branch '%s')"), new_branch);
+       } else {
+               struct strbuf s = STRBUF_INIT;
+               if (!detach && !strbuf_check_branch_ref(&s, branch) &&
+                   ref_exists(s.buf))
+                       printf_ln(_("Preparing worktree (checking out '%s')"),
+                                 branch);
+               else {
+                       struct commit *commit = lookup_commit_reference_by_name(branch);
+                       if (!commit)
+                               die(_("invalid reference: %s"), branch);
+                       printf_ln(_("Preparing worktree (detached HEAD %s)"),
+                                 find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV));
+               }
+               strbuf_release(&s);
+       }
+}
+
+static const char *dwim_branch(const char *path, const char **new_branch)
+{
+       int n;
+       const char *s = worktree_basename(path, &n);
+       const char *branchname = xstrndup(s, n);
+       struct strbuf ref = STRBUF_INIT;
+
+       UNLEAK(branchname);
+       if (!strbuf_check_branch_ref(&ref, branchname) &&
+           ref_exists(ref.buf)) {
+               strbuf_release(&ref);
+               return branchname;
+       }
+
+       *new_branch = branchname;
+       if (guess_remote) {
+               struct object_id oid;
+               const char *remote =
+                       unique_tracking_name(*new_branch, &oid);
+               return remote;
+       }
+       return NULL;
+}
+
 static int add(int ac, const char **av, const char *prefix)
 {
        struct add_opts opts;
        const char *new_branch_force = NULL;
        char *path;
        const char *branch;
+       const char *new_branch = NULL;
        const char *opt_track = NULL;
        struct option options[] = {
                OPT__FORCE(&opts.force,
                           N_("checkout <branch> even if already checked out in other worktree"),
                           PARSE_OPT_NOCOMPLETE),
-               OPT_STRING('b', NULL, &opts.new_branch, N_("branch"),
+               OPT_STRING('b', NULL, &new_branch, N_("branch"),
                           N_("create a new branch")),
                OPT_STRING('B', NULL, &new_branch_force, N_("branch"),
                           N_("create or reset a branch")),
@@ -402,7 +448,7 @@ static int add(int ac, const char **av, const char *prefix)
        memset(&opts, 0, sizeof(opts));
        opts.checkout = 1;
        ac = parse_options(ac, av, prefix, options, worktree_usage, 0);
-       if (!!opts.detach + !!opts.new_branch + !!new_branch_force > 1)
+       if (!!opts.detach + !!new_branch + !!new_branch_force > 1)
                die(_("-b, -B, and --detach are mutually exclusive"));
        if (ac < 1 || ac > 2)
                usage_with_options(worktree_usage, options);
@@ -413,33 +459,25 @@ static int add(int ac, const char **av, const char *prefix)
        if (!strcmp(branch, "-"))
                branch = "@{-1}";
 
-       opts.force_new_branch = !!new_branch_force;
-       if (opts.force_new_branch) {
+       if (new_branch_force) {
                struct strbuf symref = STRBUF_INIT;
 
-               opts.new_branch = new_branch_force;
+               new_branch = new_branch_force;
 
                if (!opts.force &&
-                   !strbuf_check_branch_ref(&symref, opts.new_branch) &&
+                   !strbuf_check_branch_ref(&symref, new_branch) &&
                    ref_exists(symref.buf))
                        die_if_checked_out(symref.buf, 0);
                strbuf_release(&symref);
        }
 
-       if (ac < 2 && !opts.new_branch && !opts.detach) {
-               int n;
-               const char *s = worktree_basename(path, &n);
-               opts.new_branch = xstrndup(s, n);
-               if (guess_remote) {
-                       struct object_id oid;
-                       const char *remote =
-                               unique_tracking_name(opts.new_branch, &oid);
-                       if (remote)
-                               branch = remote;
-               }
+       if (ac < 2 && !new_branch && !opts.detach) {
+               const char *s = dwim_branch(path, &new_branch);
+               if (s)
+                       branch = s;
        }
 
-       if (ac == 2 && !opts.new_branch && !opts.detach) {
+       if (ac == 2 && !new_branch && !opts.detach) {
                struct object_id oid;
                struct commit *commit;
                const char *remote;
@@ -448,25 +486,27 @@ static int add(int ac, const char **av, const char *prefix)
                if (!commit) {
                        remote = unique_tracking_name(branch, &oid);
                        if (remote) {
-                               opts.new_branch = branch;
+                               new_branch = branch;
                                branch = remote;
                        }
                }
        }
 
-       if (opts.new_branch) {
+       print_preparing_worktree_line(opts.detach, branch, new_branch, !!new_branch_force);
+
+       if (new_branch) {
                struct child_process cp = CHILD_PROCESS_INIT;
                cp.git_cmd = 1;
                argv_array_push(&cp.args, "branch");
-               if (opts.force_new_branch)
+               if (new_branch_force)
                        argv_array_push(&cp.args, "--force");
-               argv_array_push(&cp.args, opts.new_branch);
+               argv_array_push(&cp.args, new_branch);
                argv_array_push(&cp.args, branch);
                if (opt_track)
                        argv_array_push(&cp.args, opt_track);
                if (run_command(&cp))
                        return -1;
-               branch = opts.new_branch;
+               branch = new_branch;
        } else if (opt_track) {
                die(_("--[no-]track can only be used if a new branch is created"));
        }
@@ -502,7 +542,7 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
                strbuf_addstr(&sb, "(bare)");
        else {
                strbuf_addf(&sb, "%-*s ", abbrev_len,
-                               find_unique_abbrev(wt->head_oid.hash, DEFAULT_ABBREV));
+                               find_unique_abbrev(&wt->head_oid, DEFAULT_ABBREV));
                if (wt->is_detached)
                        strbuf_addstr(&sb, "(detached HEAD)");
                else if (wt->head_ref) {
@@ -527,7 +567,7 @@ static void measure_widths(struct worktree **wt, int *abbrev, int *maxlen)
 
                if (path_len > *maxlen)
                        *maxlen = path_len;
-               sha1_len = strlen(find_unique_abbrev(wt[i]->head_oid.hash, *abbrev));
+               sha1_len = strlen(find_unique_abbrev(&wt[i]->head_oid, *abbrev));
                if (sha1_len > *abbrev)
                        *abbrev = sha1_len;
        }
@@ -790,8 +830,9 @@ static int remove_worktree(int ac, const char **av, const char *prefix)
 {
        int force = 0;
        struct option options[] = {
-               OPT_BOOL(0, "force", &force,
-                        N_("force removing even if the worktree is dirty")),
+               OPT__FORCE(&force,
+                        N_("force removing even if the worktree is dirty"),
+                        PARSE_OPT_NOCOMPLETE),
                OPT_END()
        };
        struct worktree **worktrees, *wt;
index bd0a78aa3c56b7e817c7ddf6fcaba703d6d5fecc..c9d3c544e79f46bab9e5fd50079d1bb574b722f2 100644 (file)
@@ -19,7 +19,7 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
 {
        int flags = 0, ret;
        const char *prefix = NULL;
-       unsigned char sha1[20];
+       struct object_id oid;
        const char *me = "git-write-tree";
        struct option write_tree_options[] = {
                OPT_BIT(0, "missing-ok", &flags, N_("allow missing objects"),
@@ -38,10 +38,10 @@ int cmd_write_tree(int argc, const char **argv, const char *unused_prefix)
        argc = parse_options(argc, argv, unused_prefix, write_tree_options,
                             write_tree_usage, 0);
 
-       ret = write_cache_as_tree(sha1, flags, prefix);
+       ret = write_cache_as_tree(&oid, flags, prefix);
        switch (ret) {
        case 0:
-               printf("%s\n", sha1_to_hex(sha1));
+               printf("%s\n", oid_to_hex(&oid));
                break;
        case WRITE_TREE_UNREADABLE_INDEX:
                die("%s: error reading the index", me);
index 9d87eac07ba1d9bf01bfe4a24c8ba784e71dbac4..b7e131c47a62603069185d67e5d2758175bc543f 100644 (file)
@@ -3,6 +3,7 @@
  */
 #include "cache.h"
 #include "bulk-checkin.h"
+#include "repository.h"
 #include "csum-file.h"
 #include "pack.h"
 #include "strbuf.h"
@@ -35,9 +36,9 @@ static void finish_bulk_checkin(struct bulk_checkin_state *state)
                unlink(state->pack_tmp_name);
                goto clear_exit;
        } else if (state->nr_written == 1) {
-               hashclose(state->f, oid.hash, CSUM_FSYNC);
+               finalize_hashfile(state->f, oid.hash, CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE);
        } else {
-               int fd = hashclose(state->f, oid.hash, 0);
+               int fd = finalize_hashfile(state->f, oid.hash, 0);
                fixup_pack_header_footer(fd, oid.hash, state->pack_tmp_name,
                                         state->nr_written, oid.hash,
                                         state->offset);
@@ -57,20 +58,20 @@ clear_exit:
 
        strbuf_release(&packname);
        /* Make objects we just wrote available to ourselves */
-       reprepare_packed_git();
+       reprepare_packed_git(the_repository);
 }
 
-static int already_written(struct bulk_checkin_state *state, unsigned char sha1[])
+static int already_written(struct bulk_checkin_state *state, struct object_id *oid)
 {
        int i;
 
        /* The object may already exist in the repository */
-       if (has_sha1_file(sha1))
+       if (has_sha1_file(oid->hash))
                return 1;
 
        /* Might want to keep the list sorted */
        for (i = 0; i < state->nr_written; i++)
-               if (!hashcmp(state->written[i]->oid.hash, sha1))
+               if (!oidcmp(&state->written[i]->oid, oid))
                        return 1;
 
        /* This is a new object we need to keep */
@@ -186,7 +187,7 @@ static void prepare_to_stream(struct bulk_checkin_state *state,
 }
 
 static int deflate_to_pack(struct bulk_checkin_state *state,
-                          unsigned char result_sha1[],
+                          struct object_id *result_oid,
                           int fd, size_t size,
                           enum object_type type, const char *path,
                           unsigned flags)
@@ -229,24 +230,24 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
                 * pack, and write into it.
                 */
                if (!idx)
-                       die("BUG: should not happen");
+                       BUG("should not happen");
                hashfile_truncate(state->f, &checkpoint);
                state->offset = checkpoint.offset;
                finish_bulk_checkin(state);
                if (lseek(fd, seekback, SEEK_SET) == (off_t) -1)
                        return error("cannot seek back");
        }
-       the_hash_algo->final_fn(result_sha1, &ctx);
+       the_hash_algo->final_fn(result_oid->hash, &ctx);
        if (!idx)
                return 0;
 
        idx->crc32 = crc32_end(state->f);
-       if (already_written(state, result_sha1)) {
+       if (already_written(state, result_oid)) {
                hashfile_truncate(state->f, &checkpoint);
                state->offset = checkpoint.offset;
                free(idx);
        } else {
-               hashcpy(idx->oid.hash, result_sha1);
+               oidcpy(&idx->oid, result_oid);
                ALLOC_GROW(state->written,
                           state->nr_written + 1,
                           state->alloc_written);
@@ -255,11 +256,11 @@ static int deflate_to_pack(struct bulk_checkin_state *state,
        return 0;
 }
 
-int index_bulk_checkin(unsigned char *sha1,
+int index_bulk_checkin(struct object_id *oid,
                       int fd, size_t size, enum object_type type,
                       const char *path, unsigned flags)
 {
-       int status = deflate_to_pack(&state, sha1, fd, size, type,
+       int status = deflate_to_pack(&state, oid, fd, size, type,
                                     path, flags);
        if (!state.plugged)
                finish_bulk_checkin(&state);
index fbd40fc98c955c192a6de698a75b8d56af766f09..a85527318b15b36bb60b0b6b166569b4fcaa9dcf 100644 (file)
@@ -4,7 +4,7 @@
 #ifndef BULK_CHECKIN_H
 #define BULK_CHECKIN_H
 
-extern int index_bulk_checkin(unsigned char sha1[],
+extern int index_bulk_checkin(struct object_id *oid,
                              int fd, size_t size, enum object_type type,
                              const char *path, unsigned flags);
 
index efe547e25fe2a53bd0ef7954cf3bec6d55218365..160bbfdc64ec2876bdc685d253bf537d1c739c1f 100644 (file)
--- a/bundle.c
+++ b/bundle.c
@@ -222,7 +222,7 @@ static int is_tag_in_date_range(struct object *tag, struct rev_info *revs)
        if (revs->max_age == -1 && revs->min_age == -1)
                goto out;
 
-       buf = read_sha1_file(tag->oid.hash, &type, &size);
+       buf = read_object_file(&tag->oid, &type, &size);
        if (!buf)
                goto out;
        line = memmem(buf, size, "\ntagger ", 8);
@@ -409,7 +409,7 @@ static int write_bundle_refs(int bundle_fd, struct rev_info *revs)
 int create_bundle(struct bundle_header *header, const char *path,
                  int argc, const char **argv)
 {
-       static struct lock_file lock;
+       struct lock_file lock = LOCK_INIT;
        int bundle_fd = -1;
        int bundle_to_stdout;
        int ref_count = 0;
index c52e4303dfcbc6a17796f536e8602017b1d951f0..25663825b553b4e4590e3b4aaad54b4f5950aef8 100644 (file)
@@ -320,7 +320,7 @@ static int update_one(struct cache_tree *it,
                struct cache_tree_sub *sub = NULL;
                const char *path, *slash;
                int pathlen, entlen;
-               const unsigned char *sha1;
+               const struct object_id *oid;
                unsigned mode;
                int expected_missing = 0;
                int contains_ita = 0;
@@ -338,7 +338,7 @@ static int update_one(struct cache_tree *it,
                                die("cache-tree.c: '%.*s' in '%s' not found",
                                    entlen, path + baselen, path);
                        i += sub->count;
-                       sha1 = sub->cache_tree->oid.hash;
+                       oid = &sub->cache_tree->oid;
                        mode = S_IFDIR;
                        contains_ita = sub->cache_tree->entry_count < 0;
                        if (contains_ita) {
@@ -347,19 +347,19 @@ static int update_one(struct cache_tree *it,
                        }
                }
                else {
-                       sha1 = ce->oid.hash;
+                       oid = &ce->oid;
                        mode = ce->ce_mode;
                        entlen = pathlen - baselen;
                        i++;
                }
 
-               if (is_null_sha1(sha1) ||
-                   (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1))) {
+               if (is_null_oid(oid) ||
+                   (mode != S_IFGITLINK && !missing_ok && !has_object_file(oid))) {
                        strbuf_release(&buffer);
                        if (expected_missing)
                                return -1;
                        return error("invalid object %06o %s for '%.*s'",
-                               mode, sha1_to_hex(sha1), entlen+baselen, path);
+                               mode, oid_to_hex(oid), entlen+baselen, path);
                }
 
                /*
@@ -385,12 +385,12 @@ static int update_one(struct cache_tree *it,
                /*
                 * "sub" can be an empty tree if all subentries are i-t-a.
                 */
-               if (contains_ita && !hashcmp(sha1, EMPTY_TREE_SHA1_BIN))
+               if (contains_ita && is_empty_tree_oid(oid))
                        continue;
 
                strbuf_grow(&buffer, entlen + 100);
                strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0');
-               strbuf_add(&buffer, sha1, 20);
+               strbuf_add(&buffer, oid->hash, the_hash_algo->rawsz);
 
 #if DEBUG
                fprintf(stderr, "cache-tree update-one %o %.*s\n",
@@ -401,7 +401,7 @@ static int update_one(struct cache_tree *it,
        if (repair) {
                struct object_id oid;
                hash_object_file(buffer.buf, buffer.len, tree_type, &oid);
-               if (has_sha1_file(oid.hash))
+               if (has_object_file(&oid))
                        oidcpy(&it->oid, &oid);
                else
                        to_invalidate = 1;
@@ -465,7 +465,7 @@ static void write_one(struct strbuf *buffer, struct cache_tree *it,
 #endif
 
        if (0 <= it->entry_count) {
-               strbuf_add(buffer, it->oid.hash, 20);
+               strbuf_add(buffer, it->oid.hash, the_hash_algo->rawsz);
        }
        for (i = 0; i < it->subtree_nr; i++) {
                struct cache_tree_sub *down = it->down[i];
@@ -492,6 +492,7 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
        char *ep;
        struct cache_tree *it;
        int i, subtree_nr;
+       const unsigned rawsz = the_hash_algo->rawsz;
 
        it = NULL;
        /* skip name, but make sure name exists */
@@ -520,11 +521,11 @@ static struct cache_tree *read_one(const char **buffer, unsigned long *size_p)
                goto free_return;
        buf++; size--;
        if (0 <= it->entry_count) {
-               if (size < 20)
+               if (size < rawsz)
                        goto free_return;
-               hashcpy(it->oid.hash, (const unsigned char*)buf);
-               buf += 20;
-               size -= 20;
+               oidread(&it->oid, (const unsigned char *)buf);
+               buf += rawsz;
+               size -= rawsz;
        }
 
 #if DEBUG
@@ -599,7 +600,7 @@ static struct cache_tree *cache_tree_find(struct cache_tree *it, const char *pat
        return it;
 }
 
-int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, const char *index_path, int flags, const char *prefix)
+int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix)
 {
        int entries, was_valid;
        struct lock_file lock_file = LOCK_INIT;
@@ -640,19 +641,19 @@ int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, co
                        ret = WRITE_TREE_PREFIX_ERROR;
                        goto out;
                }
-               hashcpy(sha1, subtree->oid.hash);
+               oidcpy(oid, &subtree->oid);
        }
        else
-               hashcpy(sha1, index_state->cache_tree->oid.hash);
+               oidcpy(oid, &index_state->cache_tree->oid);
 
 out:
        rollback_lock_file(&lock_file);
        return ret;
 }
 
-int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix)
+int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix)
 {
-       return write_index_as_tree(sha1, &the_index, get_index_file(), flags, prefix);
+       return write_index_as_tree(oid, &the_index, get_index_file(), flags, prefix);
 }
 
 static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree)
index f7b9cab7ee87dd04cecbd25f34101a58fc002014..cfd5328cc93694e23037e15148241e17bd4f3a04 100644 (file)
@@ -47,8 +47,8 @@ int update_main_cache_tree(int);
 #define WRITE_TREE_UNMERGED_INDEX (-2)
 #define WRITE_TREE_PREFIX_ERROR (-3)
 
-int write_index_as_tree(unsigned char *sha1, struct index_state *index_state, const char *index_path, int flags, const char *prefix);
-int write_cache_as_tree(unsigned char *sha1, int flags, const char *prefix);
+int write_index_as_tree(struct object_id *oid, struct index_state *index_state, const char *index_path, int flags, const char *prefix);
+int write_cache_as_tree(struct object_id *oid, int flags, const char *prefix);
 void prime_cache_tree(struct index_state *, struct tree *);
 
 extern int cache_tree_matches_traversal(struct cache_tree *, struct name_entry *ent, struct traverse_info *info);
diff --git a/cache.h b/cache.h
index 0323853c99e75a1edc2e4415db9490ae36bd2c0f..89a107a7f79175c600eb2a9689982912541ae4e7 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -324,7 +324,7 @@ struct index_state {
                 drop_cache_tree : 1;
        struct hashmap name_hash;
        struct hashmap dir_hash;
-       unsigned char sha1[20];
+       struct object_id oid;
        struct untracked_cache *untracked;
        uint64_t fsmonitor_last_update;
        struct ewah_bitmap *fsmonitor_dirty;
@@ -373,6 +373,13 @@ extern void free_name_hash(struct index_state *istate);
 #define read_blob_data_from_cache(path, sz) read_blob_data_from_index(&the_index, (path), (sz))
 #endif
 
+#define TYPE_BITS 3
+
+/*
+ * Values in this enum (except those outside the 3 bit range) are part
+ * of pack file format. See Documentation/technical/pack-format.txt
+ * for more information.
+ */
 enum object_type {
        OBJ_BAD = -1,
        OBJ_NONE = 0,
@@ -428,6 +435,7 @@ static inline enum object_type object_type(unsigned int mode)
 #define GIT_ICASE_PATHSPECS_ENVIRONMENT "GIT_ICASE_PATHSPECS"
 #define GIT_QUARANTINE_ENVIRONMENT "GIT_QUARANTINE_PATH"
 #define GIT_OPTIONAL_LOCKS_ENVIRONMENT "GIT_OPTIONAL_LOCKS"
+#define GIT_TEXT_DOMAIN_DIR_ENVIRONMENT "GIT_TEXTDOMAINDIR"
 
 /*
  * Environment variable used in handshaking the wire protocol.
@@ -459,7 +467,7 @@ static inline enum object_type object_type(unsigned int mode)
  */
 extern const char * const local_repo_env[];
 
-extern void setup_git_env(void);
+extern void setup_git_env(const char *git_dir);
 
 /*
  * Returns true iff we have a configured git repository (either via
@@ -477,7 +485,7 @@ extern const char *get_git_common_dir(void);
 extern char *get_object_directory(void);
 extern char *get_index_file(void);
 extern char *get_graft_file(void);
-extern int set_git_dir(const char *path);
+extern void set_git_dir(const char *path);
 extern int get_common_dir_noenv(struct strbuf *sb, const char *gitdir);
 extern int get_common_dir(struct strbuf *sb, const char *gitdir);
 extern const char *get_git_namespace(void);
@@ -805,6 +813,7 @@ extern char *git_replace_ref_base;
 
 extern int fsync_object_files;
 extern int core_preload_index;
+extern int core_commit_graph;
 extern int core_apply_sparse_checkout;
 extern int precomposed_unicode;
 extern int protect_hfs;
@@ -940,12 +949,6 @@ extern void check_repository_format(void);
 #define DATA_CHANGED    0x0020
 #define TYPE_CHANGED    0x0040
 
-/*
- * Put in `buf` the name of the file in the local object database that
- * would be used to store a loose object with the specified sha1.
- */
-extern void sha1_file_name(struct strbuf *buf, const unsigned char *sha1);
-
 /*
  * Return an abbreviated sha1 unique within this repository's object database.
  * The result will be at least `len` characters long, and will be NUL
@@ -955,14 +958,14 @@ extern void sha1_file_name(struct strbuf *buf, const unsigned char *sha1);
  * more calls to find_unique_abbrev are made.
  *
  * The `_r` variant writes to a buffer supplied by the caller, which must be at
- * least `GIT_SHA1_HEXSZ + 1` bytes. The return value is the number of bytes
+ * least `GIT_MAX_HEXSZ + 1` bytes. The return value is the number of bytes
  * written (excluding the NUL terminator).
  *
  * Note that while this version avoids the static buffer, it is not fully
  * reentrant, as it calls into other non-reentrant git code.
  */
-extern const char *find_unique_abbrev(const unsigned char *sha1, int len);
-extern int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len);
+extern const char *find_unique_abbrev(const struct object_id *oid, int len);
+extern int find_unique_abbrev_r(char *hex, const struct object_id *oid, int len);
 
 extern const unsigned char null_sha1[GIT_MAX_RAWSZ];
 extern const struct object_id null_oid;
@@ -1014,21 +1017,10 @@ static inline void oidclr(struct object_id *oid)
        memset(oid->hash, 0, GIT_MAX_RAWSZ);
 }
 
-
-#define EMPTY_TREE_SHA1_HEX \
-       "4b825dc642cb6eb9a060e54bf8d69288fbee4904"
-#define EMPTY_TREE_SHA1_BIN_LITERAL \
-        "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
-        "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
-extern const struct object_id empty_tree_oid;
-#define EMPTY_TREE_SHA1_BIN (empty_tree_oid.hash)
-
-#define EMPTY_BLOB_SHA1_HEX \
-       "e69de29bb2d1d6434b8b29ae775ad8c2e48c5391"
-#define EMPTY_BLOB_SHA1_BIN_LITERAL \
-       "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \
-       "\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91"
-extern const struct object_id empty_blob_oid;
+static inline void oidread(struct object_id *oid, const unsigned char *hash)
+{
+       memcpy(oid->hash, hash, the_hash_algo->rawsz);
+}
 
 static inline int is_empty_blob_sha1(const unsigned char *sha1)
 {
@@ -1050,6 +1042,9 @@ static inline int is_empty_tree_oid(const struct object_id *oid)
        return !oidcmp(oid, the_hash_algo->empty_tree);
 }
 
+const char *empty_tree_oid_hex(void);
+const char *empty_blob_oid_hex(void);
+
 /* set default permissions by passing mode arguments to open(2) */
 int git_mkstemps_mode(char *pattern, int suffix_len, int mode);
 int git_mkstemp_mode(char *pattern, int mode);
@@ -1197,35 +1192,16 @@ extern char *xdg_config_home(const char *filename);
  */
 extern char *xdg_cache_home(const char *filename);
 
-extern void *read_sha1_file_extended(const unsigned char *sha1,
-                                    enum object_type *type,
-                                    unsigned long *size, int lookup_replace);
-static inline void *read_sha1_file(const unsigned char *sha1, enum object_type *type, unsigned long *size)
-{
-       return read_sha1_file_extended(sha1, type, size, 1);
-}
-
-/*
- * This internal function is only declared here for the benefit of
- * lookup_replace_object().  Please do not call it directly.
- */
-extern const unsigned char *do_lookup_replace_object(const unsigned char *sha1);
-
-/*
- * If object sha1 should be replaced, return the replacement object's
- * name (replaced recursively, if necessary).  The return value is
- * either sha1 or a pointer to a permanently-allocated value.  When
- * object replacement is suppressed, always return sha1.
- */
-static inline const unsigned char *lookup_replace_object(const unsigned char *sha1)
+extern void *read_object_file_extended(const struct object_id *oid,
+                                      enum object_type *type,
+                                      unsigned long *size, int lookup_replace);
+static inline void *read_object_file(const struct object_id *oid, enum object_type *type, unsigned long *size)
 {
-       if (!check_replace_refs)
-               return sha1;
-       return do_lookup_replace_object(sha1);
+       return read_object_file_extended(oid, type, size, 1);
 }
 
-/* Read and unpack a sha1 file into memory, write memory to a sha1 file */
-extern int sha1_object_info(const unsigned char *, unsigned long *);
+/* Read and unpack an object file into memory, write memory to an object file */
+int oid_object_info(struct repository *r, const struct object_id *, unsigned long *);
 
 extern int hash_object_file(const void *buf, unsigned long len,
                            const char *type, struct object_id *oid);
@@ -1244,23 +1220,22 @@ extern int force_object_loose(const struct object_id *oid, time_t mtime);
 
 extern int git_open_cloexec(const char *name, int flags);
 #define git_open(name) git_open_cloexec(name, O_RDONLY)
-extern void *map_sha1_file(const unsigned char *sha1, unsigned long *size);
 extern int unpack_sha1_header(git_zstream *stream, unsigned char *map, unsigned long mapsize, void *buffer, unsigned long bufsiz);
 extern int parse_sha1_header(const char *hdr, unsigned long *sizep);
 
-extern int check_sha1_signature(const unsigned char *sha1, void *buf, unsigned long size, const char *type);
+extern int check_object_signature(const struct object_id *oid, void *buf, unsigned long size, const char *type);
 
 extern int finalize_object_file(const char *tmpfile, const char *filename);
 
 /*
- * Open the loose object at path, check its sha1, and return the contents,
+ * Open the loose object at path, check its hash, and return the contents,
  * type, and size. If the object is a blob, then "contents" may return NULL,
  * to allow streaming of large blobs.
  *
  * Returns 0 on success, negative on error (details may be written to stderr).
  */
 int read_loose_object(const char *path,
-                     const unsigned char *expected_sha1,
+                     const struct object_id *expected_oid,
                      enum object_type *type,
                      unsigned long *size,
                      void **contents);
@@ -1285,9 +1260,9 @@ extern int has_object_file_with_flags(const struct object_id *oid, int flags);
  * with the specified name.  This function does not respect replace
  * references.
  */
-extern int has_loose_object_nonlocal(const unsigned char *sha1);
+extern int has_loose_object_nonlocal(const struct object_id *oid);
 
-extern void assert_sha1_type(const unsigned char *sha1, enum object_type expect);
+extern void assert_oid_type(const struct object_id *oid, enum object_type expect);
 
 /* Helper to check and "touch" a file */
 extern int check_and_freshen_file(const char *fn, int freshen);
@@ -1316,7 +1291,6 @@ static inline int hex2chr(const char *s)
 #define FALLBACK_DEFAULT_ABBREV 7
 
 struct object_context {
-       unsigned char tree[20];
        unsigned mode;
        /*
         * symlink_path is only used by get_tree_entry_follow_symlinks,
@@ -1443,10 +1417,10 @@ extern int df_name_compare(const char *name1, int len1, int mode1, const char *n
 extern int name_compare(const char *name1, size_t len1, const char *name2, size_t len2);
 extern int cache_name_stage_compare(const char *name1, int len1, int stage1, const char *name2, int len2, int stage2);
 
-extern void *read_object_with_reference(const unsigned char *sha1,
+extern void *read_object_with_reference(const struct object_id *oid,
                                        const char *required_type,
                                        unsigned long *size,
-                                       unsigned char *sha1_ret);
+                                       struct object_id *oid_ret);
 
 extern struct object *peel_to_type(const char *name, int namelen,
                                   struct object *o, enum object_type);
@@ -1572,57 +1546,6 @@ extern int has_dirs_only_path(const char *name, int len, int prefix_len);
 extern void schedule_dir_for_removal(const char *name, int len);
 extern void remove_scheduled_dirs(void);
 
-extern struct alternate_object_database {
-       struct alternate_object_database *next;
-
-       /* see alt_scratch_buf() */
-       struct strbuf scratch;
-       size_t base_len;
-
-       /*
-        * Used to store the results of readdir(3) calls when searching
-        * for unique abbreviated hashes.  This cache is never
-        * invalidated, thus it's racy and not necessarily accurate.
-        * That's fine for its purpose; don't use it for tasks requiring
-        * greater accuracy!
-        */
-       char loose_objects_subdir_seen[256];
-       struct oid_array loose_objects_cache;
-
-       char path[FLEX_ARRAY];
-} *alt_odb_list;
-extern void prepare_alt_odb(void);
-extern char *compute_alternate_path(const char *path, struct strbuf *err);
-typedef int alt_odb_fn(struct alternate_object_database *, void *);
-extern int foreach_alt_odb(alt_odb_fn, void*);
-
-/*
- * Allocate a "struct alternate_object_database" but do _not_ actually
- * add it to the list of alternates.
- */
-struct alternate_object_database *alloc_alt_odb(const char *dir);
-
-/*
- * Add the directory to the on-disk alternates file; the new entry will also
- * take effect in the current process.
- */
-extern void add_to_alternates_file(const char *dir);
-
-/*
- * Add the directory to the in-memory list of alternates (along with any
- * recursive alternates it points to), but do not modify the on-disk alternates
- * file.
- */
-extern void add_to_alternates_memory(const char *dir);
-
-/*
- * Returns a scratch strbuf pre-filled with the alternate object directory,
- * including a trailing slash, which can be used to access paths in the
- * alternate. Always use this over direct access to alt->scratch, as it
- * cleans up any previous use of the scratch buffer.
- */
-extern struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);
-
 struct pack_window {
        struct pack_window *next;
        unsigned char *base;
@@ -1632,38 +1555,8 @@ struct pack_window {
        unsigned int inuse_cnt;
 };
 
-extern struct packed_git {
-       struct packed_git *next;
-       struct list_head mru;
-       struct pack_window *windows;
-       off_t pack_size;
-       const void *index_data;
-       size_t index_size;
-       uint32_t num_objects;
-       uint32_t num_bad_objects;
-       unsigned char *bad_object_sha1;
-       int index_version;
-       time_t mtime;
-       int pack_fd;
-       unsigned pack_local:1,
-                pack_keep:1,
-                freshened:1,
-                do_not_close:1,
-                pack_promisor:1;
-       unsigned char sha1[20];
-       struct revindex_entry *revindex;
-       /* something like ".git/objects/pack/xxxxx.pack" */
-       char pack_name[FLEX_ARRAY]; /* more */
-} *packed_git;
-
-/*
- * A most-recently-used ordered version of the packed_git list.
- */
-extern struct list_head packed_git_mru;
-
 struct pack_entry {
        off_t offset;
-       unsigned char sha1[20];
        struct packed_git *p;
 };
 
@@ -1785,7 +1678,12 @@ struct object_info {
 #define OBJECT_INFO_SKIP_CACHED 4
 /* Do not retry packed storage after checking packed and loose storage */
 #define OBJECT_INFO_QUICK 8
-extern int sha1_object_info_extended(const unsigned char *, struct object_info *, unsigned flags);
+/* Do not check loose object */
+#define OBJECT_INFO_IGNORE_LOOSE 16
+
+int oid_object_info_extended(struct repository *r,
+                            const struct object_id *,
+                            struct object_info *, unsigned flags);
 
 /*
  * Set this to 0 to prevent sha1_object_info_extended() from fetching missing
@@ -1928,11 +1826,6 @@ extern int ws_blank_line(const char *line, int len, unsigned ws_rule);
 void overlay_tree_on_index(struct index_state *istate,
                           const char *tree_name, const char *prefix);
 
-char *alias_lookup(const char *alias);
-int split_cmdline(char *cmdline, const char ***argv);
-/* Takes a negative value returned by split_cmdline */
-const char *split_cmdline_strerror(int cmdline_errno);
-
 /* setup.c */
 struct startup_info {
        int have_repository;
diff --git a/chdir-notify.c b/chdir-notify.c
new file mode 100644 (file)
index 0000000..5f7f2c2
--- /dev/null
@@ -0,0 +1,93 @@
+#include "cache.h"
+#include "chdir-notify.h"
+#include "list.h"
+#include "strbuf.h"
+
+struct chdir_notify_entry {
+       const char *name;
+       chdir_notify_callback cb;
+       void *data;
+       struct list_head list;
+};
+static LIST_HEAD(chdir_notify_entries);
+
+void chdir_notify_register(const char *name,
+                          chdir_notify_callback cb,
+                          void *data)
+{
+       struct chdir_notify_entry *e = xmalloc(sizeof(*e));
+       e->name = name;
+       e->cb = cb;
+       e->data = data;
+       list_add_tail(&e->list, &chdir_notify_entries);
+}
+
+static void reparent_cb(const char *name,
+                       const char *old_cwd,
+                       const char *new_cwd,
+                       void *data)
+{
+       char **path = data;
+       char *tmp = *path;
+
+       if (!tmp)
+               return;
+
+       *path = reparent_relative_path(old_cwd, new_cwd, tmp);
+       free(tmp);
+
+       if (name) {
+               trace_printf_key(&trace_setup_key,
+                                "setup: reparent %s to '%s'",
+                                name, *path);
+       }
+}
+
+void chdir_notify_reparent(const char *name, char **path)
+{
+       chdir_notify_register(name, reparent_cb, path);
+}
+
+int chdir_notify(const char *new_cwd)
+{
+       struct strbuf old_cwd = STRBUF_INIT;
+       struct list_head *pos;
+
+       if (strbuf_getcwd(&old_cwd) < 0)
+               return -1;
+       if (chdir(new_cwd) < 0) {
+               int saved_errno = errno;
+               strbuf_release(&old_cwd);
+               errno = saved_errno;
+               return -1;
+       }
+
+       trace_printf_key(&trace_setup_key,
+                        "setup: chdir from '%s' to '%s'",
+                        old_cwd.buf, new_cwd);
+
+       list_for_each(pos, &chdir_notify_entries) {
+               struct chdir_notify_entry *e =
+                       list_entry(pos, struct chdir_notify_entry, list);
+               e->cb(e->name, old_cwd.buf, new_cwd, e->data);
+       }
+
+       strbuf_release(&old_cwd);
+       return 0;
+}
+
+char *reparent_relative_path(const char *old_cwd,
+                            const char *new_cwd,
+                            const char *path)
+{
+       char *ret, *full;
+
+       if (is_absolute_path(path))
+               return xstrdup(path);
+
+       full = xstrfmt("%s/%s", old_cwd, path);
+       ret = xstrdup(remove_leading_path(full, new_cwd));
+       free(full);
+
+       return ret;
+}
diff --git a/chdir-notify.h b/chdir-notify.h
new file mode 100644 (file)
index 0000000..366e4c1
--- /dev/null
@@ -0,0 +1,73 @@
+#ifndef CHDIR_NOTIFY_H
+#define CHDIR_NOTIFY_H
+
+/*
+ * An API to let code "subscribe" to changes to the current working directory.
+ * The general idea is that some code asks to be notified when the working
+ * directory changes, and other code that calls chdir uses a special wrapper
+ * that notifies everyone.
+ */
+
+/*
+ * Callers who need to know about changes can do:
+ *
+ *   void foo(const char *old_path, const char *new_path, void *data)
+ *   {
+ *     warning("switched from %s to %s!", old_path, new_path);
+ *   }
+ *   ...
+ *   chdir_notify_register("description", foo, data);
+ *
+ * In practice most callers will want to move a relative path to the new root;
+ * they can use the reparent_relative_path() helper for that. If that's all
+ * you're doing, you can also use the convenience function:
+ *
+ *   chdir_notify_reparent("description", &my_path);
+ *
+ * Whenever a chdir event occurs, that will update my_path (if it's relative)
+ * to adjust for the new cwd by freeing any existing string and allocating a
+ * new one.
+ *
+ * Registered functions are called in the order in which they were added. Note
+ * that there's currently no way to remove a function, so make sure that the
+ * data parameter remains valid for the rest of the program.
+ *
+ * The "name" argument is used only for printing trace output from
+ * $GIT_TRACE_SETUP. It may be NULL, but if non-NULL should point to
+ * storage which lasts as long as the registration is active.
+ */
+typedef void (*chdir_notify_callback)(const char *name,
+                                     const char *old_cwd,
+                                     const char *new_cwd,
+                                     void *data);
+void chdir_notify_register(const char *name, chdir_notify_callback cb, void *data);
+void chdir_notify_reparent(const char *name, char **path);
+
+/*
+ *
+ * Callers that want to chdir:
+ *
+ *   chdir_notify(new_path);
+ *
+ * to switch to the new path and notify any callbacks.
+ *
+ * Note that you don't need to chdir_notify() if you're just temporarily moving
+ * to a directory and back, as long as you don't call any subscribed code in
+ * between (but it should be safe to do so if you're unsure).
+ */
+int chdir_notify(const char *new_cwd);
+
+/*
+ * Reparent a relative path from old_root to new_root. For example:
+ *
+ *   reparent_relative_path("/a", "/a/b", "b/rel");
+ *
+ * would return the (newly allocated) string "rel". Note that we may return an
+ * absolute path in some cases (e.g., if the resulting path is not inside
+ * new_cwd).
+ */
+char *reparent_relative_path(const char *old_cwd,
+                            const char *new_cwd,
+                            const char *path);
+
+#endif /* CHDIR_NOTIFY_H */
index ac42630f7483e8c675c31bb7a0c58262e900b5c3..bdefc888bae1516f0ddcf22264807d031af7c991 100644 (file)
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "remote.h"
+#include "refspec.h"
 #include "checkout.h"
 
 struct tracking_name_data {
@@ -12,8 +13,8 @@ struct tracking_name_data {
 static int check_tracking_name(struct remote *remote, void *cb_data)
 {
        struct tracking_name_data *cb = cb_data;
-       struct refspec query;
-       memset(&query, 0, sizeof(struct refspec));
+       struct refspec_item query;
+       memset(&query, 0, sizeof(struct refspec_item));
        query.src = cb->src_ref;
        if (remote_find_tracking(remote, &query) ||
            get_oid(query.dst, cb->dst_oid)) {
index 109ef280da9884027f17fe7f233b6b818bd71393..ceecc889caf9fc3af038ffa4179056291e90b704 100755 (executable)
@@ -99,6 +99,9 @@ export DEFAULT_TEST_TARGET=prove
 export GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save"
 export GIT_TEST_OPTS="--verbose-log -x"
 export GIT_TEST_CLONE_2GB=YesPlease
+if [ "$jobname" = linux-gcc ]; then
+       export CC=gcc-8
+fi
 
 case "$jobname" in
 linux-clang|linux-gcc)
index 3735ce413f1835b3222fab05ba9ff5ab5205c2c0..4b04c75b7f81a749c0d48674b8e2042abe5769eb 100755 (executable)
@@ -11,7 +11,10 @@ make --jobs=2
 make --quiet test
 if test "$jobname" = "linux-gcc"
 then
-       GIT_TEST_SPLIT_INDEX=YesPlease make --quiet test
+       export GIT_TEST_SPLIT_INDEX=yes
+       export GIT_TEST_FULL_IN_PACK_ARRAY=true
+       export GIT_TEST_OE_SIZE=10
+       make --quiet test
 fi
 
 check_unignored_build_artifacts
diff --git a/color.c b/color.c
index f277e72e4ce04815f71c949dfdf7c89c9462c5b7..b1c24c69de652b0b8900e76ebd5b4e6cd24e5203 100644 (file)
--- a/color.c
+++ b/color.c
@@ -174,7 +174,7 @@ static char *color_output(char *out, int len, const struct color *c, char type)
                break;
        case COLOR_ANSI:
                if (len < 2)
-                       die("BUG: color parsing ran out of space");
+                       BUG("color parsing ran out of space");
                *out++ = type;
                *out++ = '0' + c->value;
                break;
@@ -256,7 +256,7 @@ int color_parse_mem(const char *value, int value_len, char *dst)
 #undef OUT
 #define OUT(x) do { \
        if (dst == end) \
-               die("BUG: color parsing ran out of space"); \
+               BUG("color parsing ran out of space"); \
        *dst++ = (x); \
 } while(0)
 
@@ -319,18 +319,20 @@ int git_config_colorbool(const char *var, const char *value)
        return GIT_COLOR_AUTO;
 }
 
-static int check_auto_color(void)
+static int check_auto_color(int fd)
 {
-       if (color_stdout_is_tty < 0)
-               color_stdout_is_tty = isatty(1);
-       if (color_stdout_is_tty || (pager_in_use() && pager_use_color)) {
+       static int color_stderr_is_tty = -1;
+       int *is_tty_p = fd == 1 ? &color_stdout_is_tty : &color_stderr_is_tty;
+       if (*is_tty_p < 0)
+               *is_tty_p = isatty(fd);
+       if (*is_tty_p || (fd == 1 && pager_in_use() && pager_use_color)) {
                if (!is_terminal_dumb())
                        return 1;
        }
        return 0;
 }
 
-int want_color(int var)
+int want_color_fd(int fd, int var)
 {
        /*
         * NEEDSWORK: This function is sometimes used from multiple threads, and
@@ -339,15 +341,15 @@ int want_color(int var)
         * is listed in .tsan-suppressions for the time being.
         */
 
-       static int want_auto = -1;
+       static int want_auto[3] = { -1, -1, -1 };
 
        if (var < 0)
                var = git_use_color_default;
 
        if (var == GIT_COLOR_AUTO) {
-               if (want_auto < 0)
-                       want_auto = check_auto_color();
-               return want_auto;
+               if (want_auto[fd] < 0)
+                       want_auto[fd] = check_auto_color(fd);
+               return want_auto[fd];
        }
        return var;
 }
diff --git a/color.h b/color.h
index cd0bcedd084f3741fad55569b18ec15e12d75cf8..5b744e1bc68617d196bdd864042e738cb4d75ebe 100644 (file)
--- a/color.h
+++ b/color.h
@@ -88,7 +88,9 @@ int git_config_colorbool(const char *var, const char *value);
  * Return a boolean whether to use color, where the argument 'var' is
  * one of GIT_COLOR_UNKNOWN, GIT_COLOR_NEVER, GIT_COLOR_ALWAYS, GIT_COLOR_AUTO.
  */
-int want_color(int var);
+int want_color_fd(int fd, int var);
+#define want_color(colorbool) want_color_fd(1, (colorbool))
+#define want_color_stderr(colorbool) want_color_fd(2, (colorbool))
 
 /*
  * Translate a Git color from 'value' into a string that the terminal can
index 49ab85b76916784d5d5e6d6ef15a9638ef97b59f..2165297608ec92c3f5a9cc9abfba072f9d43be1f 100644 (file)
--- a/column.c
+++ b/column.c
@@ -214,7 +214,7 @@ void print_columns(const struct string_list *list, unsigned int colopts,
                display_table(list, colopts, &nopts);
                break;
        default:
-               die("BUG: invalid layout mode %d", COL_LAYOUT(colopts));
+               BUG("invalid layout mode %d", COL_LAYOUT(colopts));
        }
 }
 
index 1ec9af1f813968830ee153e23a4670014124683f..2ef495963fc1cf2e092778d35f1965912d7eaac0 100644 (file)
@@ -306,7 +306,7 @@ static char *grab_blob(const struct object_id *oid, unsigned int mode,
                *size = fill_textconv(textconv, df, &blob);
                free_filespec(df);
        } else {
-               blob = read_sha1_file(oid->hash, &type, size);
+               blob = read_object_file(oid, &type, size);
                if (type != OBJ_BLOB)
                        die("object '%s' is not a blob!", oid_to_hex(oid));
        }
@@ -915,11 +915,11 @@ static void show_combined_header(struct combine_diff_path *elem,
                         "", elem->path, line_prefix, c_meta, c_reset);
        printf("%s%sindex ", line_prefix, c_meta);
        for (i = 0; i < num_parent; i++) {
-               abb = find_unique_abbrev(elem->parent[i].oid.hash,
+               abb = find_unique_abbrev(&elem->parent[i].oid,
                                         abbrev);
                printf("%s%s", i ? "," : "", abb);
        }
-       abb = find_unique_abbrev(elem->oid.hash, abbrev);
+       abb = find_unique_abbrev(&elem->oid, abbrev);
        printf("..%s%s\n", abb, c_reset);
 
        if (mode_differs) {
index a1fad28fd82da18cc2b8f43e8eb26fed9864411b..e1c26c1bb7e618f6f372d9a568e7cab75612d2db 100644 (file)
@@ -1,23 +1,58 @@
-# common commands are grouped by themes
-# these groups are output by 'git help' in the order declared here.
-# map each common command in the command list to one of these groups.
-### common groups (do not change this line)
-init         start a working area (see also: git help tutorial)
-worktree     work on the current change (see also: git help everyday)
-info         examine the history and state (see also: git help revisions)
-history      grow, mark and tweak your common history
-remote       collaborate (see also: git help workflows)
-
-### command list (do not change this line)
-# command name                          category [deprecated] [common]
+# Command classification list
+# ---------------------------
+# All supported commands, builtin or external, must be described in
+# here. This info is used to list commands in various places. Each
+# command is on one line followed by one or more attributes.
+#
+# The first attribute group is mandatory and indicates the command
+# type. This group includes:
+#
+#   mainporcelain
+#   ancillarymanipulators
+#   ancillaryinterrogators
+#   foreignscminterface
+#   plumbingmanipulators
+#   plumbinginterrogators
+#   synchingrepositories
+#   synchelpers
+#   purehelpers
+#
+# The type names are self explanatory. But if you want to see what
+# command belongs to what group to get a better picture, have a look
+# at "git" man page, "GIT COMMANDS" section.
+#
+# Commands of type mainporcelain can also optionally have one of these
+# attributes:
+#
+#   init
+#   worktree
+#   info
+#   history
+#   remote
+#
+# These commands are considered "common" and will show up in "git
+# help" output in groups. Uncommon porcelain commands must not
+# specify any of these attributes.
+#
+# "complete" attribute is used to mark that the command should be
+# completable by git-completion.bash. Note that by default,
+# mainporcelain commands are completable so you don't need this
+# attribute.
+#
+# As part of the Git man page list, the man(5/7) guides are also
+# specified here, which can only have "guide" attribute and nothing
+# else.
+#
+### command list (do not change this line, also do not change alignment)
+# command name                          category [category] [category]
 git-add                                 mainporcelain           worktree
 git-am                                  mainporcelain
 git-annotate                            ancillaryinterrogators
-git-apply                               plumbingmanipulators
+git-apply                               plumbingmanipulators            complete
 git-archimport                          foreignscminterface
 git-archive                             mainporcelain
 git-bisect                              mainporcelain           info
-git-blame                               ancillaryinterrogators
+git-blame                               ancillaryinterrogators          complete
 git-branch                              mainporcelain           history
 git-bundle                              mainporcelain
 git-cat-file                            plumbinginterrogators
@@ -27,15 +62,16 @@ git-check-mailmap                       purehelpers
 git-checkout                            mainporcelain           history
 git-checkout-index                      plumbingmanipulators
 git-check-ref-format                    purehelpers
-git-cherry                              ancillaryinterrogators
+git-cherry                              ancillaryinterrogators          complete
 git-cherry-pick                         mainporcelain
 git-citool                              mainporcelain
 git-clean                               mainporcelain
 git-clone                               mainporcelain           init
 git-column                              purehelpers
 git-commit                              mainporcelain           history
+git-commit-graph                        plumbingmanipulators
 git-commit-tree                         plumbingmanipulators
-git-config                              ancillarymanipulators
+git-config                              ancillarymanipulators           complete
 git-count-objects                       ancillaryinterrogators
 git-credential                          purehelpers
 git-credential-cache                    purehelpers
@@ -49,7 +85,7 @@ git-diff                                mainporcelain           history
 git-diff-files                          plumbinginterrogators
 git-diff-index                          plumbinginterrogators
 git-diff-tree                           plumbinginterrogators
-git-difftool                            ancillaryinterrogators
+git-difftool                            ancillaryinterrogators          complete
 git-fast-export                         ancillarymanipulators
 git-fast-import                         ancillarymanipulators
 git-fetch                               mainporcelain           remote
@@ -58,20 +94,20 @@ git-filter-branch                       ancillarymanipulators
 git-fmt-merge-msg                       purehelpers
 git-for-each-ref                        plumbinginterrogators
 git-format-patch                        mainporcelain
-git-fsck                                ancillaryinterrogators
+git-fsck                                ancillaryinterrogators          complete
 git-gc                                  mainporcelain
 git-get-tar-commit-id                   ancillaryinterrogators
 git-grep                                mainporcelain           info
 git-gui                                 mainporcelain
 git-hash-object                         plumbingmanipulators
-git-help                                ancillaryinterrogators
+git-help                                ancillaryinterrogators          complete
 git-http-backend                        synchingrepositories
 git-http-fetch                          synchelpers
 git-http-push                           synchelpers
 git-imap-send                           foreignscminterface
 git-index-pack                          plumbingmanipulators
 git-init                                mainporcelain           init
-git-instaweb                            ancillaryinterrogators
+git-instaweb                            ancillaryinterrogators          complete
 git-interpret-trailers                  purehelpers
 gitk                                    mainporcelain
 git-log                                 mainporcelain           info
@@ -85,7 +121,7 @@ git-merge-base                          plumbinginterrogators
 git-merge-file                          plumbingmanipulators
 git-merge-index                         plumbingmanipulators
 git-merge-one-file                      purehelpers
-git-mergetool                           ancillarymanipulators
+git-mergetool                           ancillarymanipulators           complete
 git-merge-tree                          ancillaryinterrogators
 git-mktag                               plumbingmanipulators
 git-mktree                              plumbingmanipulators
@@ -106,28 +142,29 @@ git-quiltimport                         foreignscminterface
 git-read-tree                           plumbingmanipulators
 git-rebase                              mainporcelain           history
 git-receive-pack                        synchelpers
-git-reflog                              ancillarymanipulators
-git-remote                              ancillarymanipulators
-git-repack                              ancillarymanipulators
-git-replace                             ancillarymanipulators
-git-request-pull                        foreignscminterface
+git-reflog                              ancillarymanipulators           complete
+git-remote                              ancillarymanipulators           complete
+git-repack                              ancillarymanipulators           complete
+git-replace                             ancillarymanipulators           complete
+git-request-pull                        foreignscminterface             complete
 git-rerere                              ancillaryinterrogators
 git-reset                               mainporcelain           worktree
 git-revert                              mainporcelain
 git-rev-list                            plumbinginterrogators
 git-rev-parse                           ancillaryinterrogators
 git-rm                                  mainporcelain           worktree
-git-send-email                          foreignscminterface
+git-send-email                          foreignscminterface             complete
 git-send-pack                           synchingrepositories
 git-shell                               synchelpers
 git-shortlog                            mainporcelain
 git-show                                mainporcelain           info
-git-show-branch                         ancillaryinterrogators
+git-show-branch                         ancillaryinterrogators          complete
 git-show-index                          plumbinginterrogators
 git-show-ref                            plumbinginterrogators
 git-sh-i18n                             purehelpers
 git-sh-setup                            purehelpers
 git-stash                               mainporcelain
+git-stage                                                               complete
 git-status                              mainporcelain           info
 git-stripspace                          purehelpers
 git-submodule                           mainporcelain
@@ -146,6 +183,22 @@ git-verify-commit                       ancillaryinterrogators
 git-verify-pack                         plumbinginterrogators
 git-verify-tag                          ancillaryinterrogators
 gitweb                                  ancillaryinterrogators
-git-whatchanged                         ancillaryinterrogators
+git-whatchanged                         ancillaryinterrogators          complete
 git-worktree                            mainporcelain
 git-write-tree                          plumbingmanipulators
+gitattributes                           guide
+gitcli                                  guide
+gitcore-tutorial                        guide
+gitcvs-migration                        guide
+gitdiffcore                             guide
+giteveryday                             guide
+gitglossary                             guide
+githooks                                guide
+gitignore                               guide
+gitmodules                              guide
+gitnamespaces                           guide
+gitrepository-layout                    guide
+gitrevisions                            guide
+gittutorial-2                           guide
+gittutorial                             guide
+gitworkflows                            guide
diff --git a/commit-graph.c b/commit-graph.c
new file mode 100644 (file)
index 0000000..4c61270
--- /dev/null
@@ -0,0 +1,761 @@
+#include "cache.h"
+#include "config.h"
+#include "git-compat-util.h"
+#include "lockfile.h"
+#include "pack.h"
+#include "packfile.h"
+#include "commit.h"
+#include "object.h"
+#include "revision.h"
+#include "sha1-lookup.h"
+#include "commit-graph.h"
+#include "object-store.h"
+
+#define GRAPH_SIGNATURE 0x43475048 /* "CGPH" */
+#define GRAPH_CHUNKID_OIDFANOUT 0x4f494446 /* "OIDF" */
+#define GRAPH_CHUNKID_OIDLOOKUP 0x4f49444c /* "OIDL" */
+#define GRAPH_CHUNKID_DATA 0x43444154 /* "CDAT" */
+#define GRAPH_CHUNKID_LARGEEDGES 0x45444745 /* "EDGE" */
+
+#define GRAPH_DATA_WIDTH 36
+
+#define GRAPH_VERSION_1 0x1
+#define GRAPH_VERSION GRAPH_VERSION_1
+
+#define GRAPH_OID_VERSION_SHA1 1
+#define GRAPH_OID_LEN_SHA1 GIT_SHA1_RAWSZ
+#define GRAPH_OID_VERSION GRAPH_OID_VERSION_SHA1
+#define GRAPH_OID_LEN GRAPH_OID_LEN_SHA1
+
+#define GRAPH_OCTOPUS_EDGES_NEEDED 0x80000000
+#define GRAPH_PARENT_MISSING 0x7fffffff
+#define GRAPH_EDGE_LAST_MASK 0x7fffffff
+#define GRAPH_PARENT_NONE 0x70000000
+
+#define GRAPH_LAST_EDGE 0x80000000
+
+#define GRAPH_FANOUT_SIZE (4 * 256)
+#define GRAPH_CHUNKLOOKUP_WIDTH 12
+#define GRAPH_MIN_SIZE (5 * GRAPH_CHUNKLOOKUP_WIDTH + GRAPH_FANOUT_SIZE + \
+                       GRAPH_OID_LEN + 8)
+
+char *get_commit_graph_filename(const char *obj_dir)
+{
+       return xstrfmt("%s/info/commit-graph", obj_dir);
+}
+
+static struct commit_graph *alloc_commit_graph(void)
+{
+       struct commit_graph *g = xcalloc(1, sizeof(*g));
+       g->graph_fd = -1;
+
+       return g;
+}
+
+struct commit_graph *load_commit_graph_one(const char *graph_file)
+{
+       void *graph_map;
+       const unsigned char *data, *chunk_lookup;
+       size_t graph_size;
+       struct stat st;
+       uint32_t i;
+       struct commit_graph *graph;
+       int fd = git_open(graph_file);
+       uint64_t last_chunk_offset;
+       uint32_t last_chunk_id;
+       uint32_t graph_signature;
+       unsigned char graph_version, hash_version;
+
+       if (fd < 0)
+               return NULL;
+       if (fstat(fd, &st)) {
+               close(fd);
+               return NULL;
+       }
+       graph_size = xsize_t(st.st_size);
+
+       if (graph_size < GRAPH_MIN_SIZE) {
+               close(fd);
+               die("graph file %s is too small", graph_file);
+       }
+       graph_map = xmmap(NULL, graph_size, PROT_READ, MAP_PRIVATE, fd, 0);
+       data = (const unsigned char *)graph_map;
+
+       graph_signature = get_be32(data);
+       if (graph_signature != GRAPH_SIGNATURE) {
+               error("graph signature %X does not match signature %X",
+                     graph_signature, GRAPH_SIGNATURE);
+               goto cleanup_fail;
+       }
+
+       graph_version = *(unsigned char*)(data + 4);
+       if (graph_version != GRAPH_VERSION) {
+               error("graph version %X does not match version %X",
+                     graph_version, GRAPH_VERSION);
+               goto cleanup_fail;
+       }
+
+       hash_version = *(unsigned char*)(data + 5);
+       if (hash_version != GRAPH_OID_VERSION) {
+               error("hash version %X does not match version %X",
+                     hash_version, GRAPH_OID_VERSION);
+               goto cleanup_fail;
+       }
+
+       graph = alloc_commit_graph();
+
+       graph->hash_len = GRAPH_OID_LEN;
+       graph->num_chunks = *(unsigned char*)(data + 6);
+       graph->graph_fd = fd;
+       graph->data = graph_map;
+       graph->data_len = graph_size;
+
+       last_chunk_id = 0;
+       last_chunk_offset = 8;
+       chunk_lookup = data + 8;
+       for (i = 0; i < graph->num_chunks; i++) {
+               uint32_t chunk_id = get_be32(chunk_lookup + 0);
+               uint64_t chunk_offset = get_be64(chunk_lookup + 4);
+               int chunk_repeated = 0;
+
+               chunk_lookup += GRAPH_CHUNKLOOKUP_WIDTH;
+
+               if (chunk_offset > graph_size - GIT_MAX_RAWSZ) {
+                       error("improper chunk offset %08x%08x", (uint32_t)(chunk_offset >> 32),
+                             (uint32_t)chunk_offset);
+                       goto cleanup_fail;
+               }
+
+               switch (chunk_id) {
+               case GRAPH_CHUNKID_OIDFANOUT:
+                       if (graph->chunk_oid_fanout)
+                               chunk_repeated = 1;
+                       else
+                               graph->chunk_oid_fanout = (uint32_t*)(data + chunk_offset);
+                       break;
+
+               case GRAPH_CHUNKID_OIDLOOKUP:
+                       if (graph->chunk_oid_lookup)
+                               chunk_repeated = 1;
+                       else
+                               graph->chunk_oid_lookup = data + chunk_offset;
+                       break;
+
+               case GRAPH_CHUNKID_DATA:
+                       if (graph->chunk_commit_data)
+                               chunk_repeated = 1;
+                       else
+                               graph->chunk_commit_data = data + chunk_offset;
+                       break;
+
+               case GRAPH_CHUNKID_LARGEEDGES:
+                       if (graph->chunk_large_edges)
+                               chunk_repeated = 1;
+                       else
+                               graph->chunk_large_edges = data + chunk_offset;
+                       break;
+               }
+
+               if (chunk_repeated) {
+                       error("chunk id %08x appears multiple times", chunk_id);
+                       goto cleanup_fail;
+               }
+
+               if (last_chunk_id == GRAPH_CHUNKID_OIDLOOKUP)
+               {
+                       graph->num_commits = (chunk_offset - last_chunk_offset)
+                                            / graph->hash_len;
+               }
+
+               last_chunk_id = chunk_id;
+               last_chunk_offset = chunk_offset;
+       }
+
+       return graph;
+
+cleanup_fail:
+       munmap(graph_map, graph_size);
+       close(fd);
+       exit(1);
+}
+
+/* global storage */
+static struct commit_graph *commit_graph = NULL;
+
+static void prepare_commit_graph_one(const char *obj_dir)
+{
+       char *graph_name;
+
+       if (commit_graph)
+               return;
+
+       graph_name = get_commit_graph_filename(obj_dir);
+       commit_graph = load_commit_graph_one(graph_name);
+
+       FREE_AND_NULL(graph_name);
+}
+
+static int prepare_commit_graph_run_once = 0;
+static void prepare_commit_graph(void)
+{
+       struct alternate_object_database *alt;
+       char *obj_dir;
+
+       if (prepare_commit_graph_run_once)
+               return;
+       prepare_commit_graph_run_once = 1;
+
+       obj_dir = get_object_directory();
+       prepare_commit_graph_one(obj_dir);
+       prepare_alt_odb(the_repository);
+       for (alt = the_repository->objects->alt_odb_list;
+            !commit_graph && alt;
+            alt = alt->next)
+               prepare_commit_graph_one(alt->path);
+}
+
+static void close_commit_graph(void)
+{
+       if (!commit_graph)
+               return;
+
+       if (commit_graph->graph_fd >= 0) {
+               munmap((void *)commit_graph->data, commit_graph->data_len);
+               commit_graph->data = NULL;
+               close(commit_graph->graph_fd);
+       }
+
+       FREE_AND_NULL(commit_graph);
+}
+
+static int bsearch_graph(struct commit_graph *g, struct object_id *oid, uint32_t *pos)
+{
+       return bsearch_hash(oid->hash, g->chunk_oid_fanout,
+                           g->chunk_oid_lookup, g->hash_len, pos);
+}
+
+static struct commit_list **insert_parent_or_die(struct commit_graph *g,
+                                                uint64_t pos,
+                                                struct commit_list **pptr)
+{
+       struct commit *c;
+       struct object_id oid;
+       hashcpy(oid.hash, g->chunk_oid_lookup + g->hash_len * pos);
+       c = lookup_commit(&oid);
+       if (!c)
+               die("could not find commit %s", oid_to_hex(&oid));
+       c->graph_pos = pos;
+       return &commit_list_insert(c, pptr)->next;
+}
+
+static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uint32_t pos)
+{
+       uint32_t edge_value;
+       uint32_t *parent_data_ptr;
+       uint64_t date_low, date_high;
+       struct commit_list **pptr;
+       const unsigned char *commit_data = g->chunk_commit_data + (g->hash_len + 16) * pos;
+
+       item->object.parsed = 1;
+       item->graph_pos = pos;
+
+       item->maybe_tree = NULL;
+
+       date_high = get_be32(commit_data + g->hash_len + 8) & 0x3;
+       date_low = get_be32(commit_data + g->hash_len + 12);
+       item->date = (timestamp_t)((date_high << 32) | date_low);
+
+       pptr = &item->parents;
+
+       edge_value = get_be32(commit_data + g->hash_len);
+       if (edge_value == GRAPH_PARENT_NONE)
+               return 1;
+       pptr = insert_parent_or_die(g, edge_value, pptr);
+
+       edge_value = get_be32(commit_data + g->hash_len + 4);
+       if (edge_value == GRAPH_PARENT_NONE)
+               return 1;
+       if (!(edge_value & GRAPH_OCTOPUS_EDGES_NEEDED)) {
+               pptr = insert_parent_or_die(g, edge_value, pptr);
+               return 1;
+       }
+
+       parent_data_ptr = (uint32_t*)(g->chunk_large_edges +
+                         4 * (uint64_t)(edge_value & GRAPH_EDGE_LAST_MASK));
+       do {
+               edge_value = get_be32(parent_data_ptr);
+               pptr = insert_parent_or_die(g,
+                                           edge_value & GRAPH_EDGE_LAST_MASK,
+                                           pptr);
+               parent_data_ptr++;
+       } while (!(edge_value & GRAPH_LAST_EDGE));
+
+       return 1;
+}
+
+int parse_commit_in_graph(struct commit *item)
+{
+       if (!core_commit_graph)
+               return 0;
+       if (item->object.parsed)
+               return 1;
+
+       prepare_commit_graph();
+       if (commit_graph) {
+               uint32_t pos;
+               int found;
+               if (item->graph_pos != COMMIT_NOT_FROM_GRAPH) {
+                       pos = item->graph_pos;
+                       found = 1;
+               } else {
+                       found = bsearch_graph(commit_graph, &(item->object.oid), &pos);
+               }
+
+               if (found)
+                       return fill_commit_in_graph(item, commit_graph, pos);
+       }
+
+       return 0;
+}
+
+static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit *c)
+{
+       struct object_id oid;
+       const unsigned char *commit_data = g->chunk_commit_data +
+                                          GRAPH_DATA_WIDTH * (c->graph_pos);
+
+       hashcpy(oid.hash, commit_data);
+       c->maybe_tree = lookup_tree(&oid);
+
+       return c->maybe_tree;
+}
+
+struct tree *get_commit_tree_in_graph(const struct commit *c)
+{
+       if (c->maybe_tree)
+               return c->maybe_tree;
+       if (c->graph_pos == COMMIT_NOT_FROM_GRAPH)
+               BUG("get_commit_tree_in_graph called from non-commit-graph commit");
+
+       return load_tree_for_commit(commit_graph, (struct commit *)c);
+}
+
+static void write_graph_chunk_fanout(struct hashfile *f,
+                                    struct commit **commits,
+                                    int nr_commits)
+{
+       int i, count = 0;
+       struct commit **list = commits;
+
+       /*
+        * 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++) {
+               while (count < nr_commits) {
+                       if ((*list)->object.oid.hash[0] != i)
+                               break;
+                       count++;
+                       list++;
+               }
+
+               hashwrite_be32(f, count);
+       }
+}
+
+static void write_graph_chunk_oids(struct hashfile *f, int hash_len,
+                                  struct commit **commits, int nr_commits)
+{
+       struct commit **list = commits;
+       int count;
+       for (count = 0; count < nr_commits; count++, list++)
+               hashwrite(f, (*list)->object.oid.hash, (int)hash_len);
+}
+
+static const unsigned char *commit_to_sha1(size_t index, void *table)
+{
+       struct commit **commits = table;
+       return commits[index]->object.oid.hash;
+}
+
+static void write_graph_chunk_data(struct hashfile *f, int hash_len,
+                                  struct commit **commits, int nr_commits)
+{
+       struct commit **list = commits;
+       struct commit **last = commits + nr_commits;
+       uint32_t num_extra_edges = 0;
+
+       while (list < last) {
+               struct commit_list *parent;
+               int edge_value;
+               uint32_t packedDate[2];
+
+               parse_commit(*list);
+               hashwrite(f, get_commit_tree_oid(*list)->hash, hash_len);
+
+               parent = (*list)->parents;
+
+               if (!parent)
+                       edge_value = GRAPH_PARENT_NONE;
+               else {
+                       edge_value = sha1_pos(parent->item->object.oid.hash,
+                                             commits,
+                                             nr_commits,
+                                             commit_to_sha1);
+
+                       if (edge_value < 0)
+                               edge_value = GRAPH_PARENT_MISSING;
+               }
+
+               hashwrite_be32(f, edge_value);
+
+               if (parent)
+                       parent = parent->next;
+
+               if (!parent)
+                       edge_value = GRAPH_PARENT_NONE;
+               else if (parent->next)
+                       edge_value = GRAPH_OCTOPUS_EDGES_NEEDED | num_extra_edges;
+               else {
+                       edge_value = sha1_pos(parent->item->object.oid.hash,
+                                             commits,
+                                             nr_commits,
+                                             commit_to_sha1);
+                       if (edge_value < 0)
+                               edge_value = GRAPH_PARENT_MISSING;
+               }
+
+               hashwrite_be32(f, edge_value);
+
+               if (edge_value & GRAPH_OCTOPUS_EDGES_NEEDED) {
+                       do {
+                               num_extra_edges++;
+                               parent = parent->next;
+                       } while (parent);
+               }
+
+               if (sizeof((*list)->date) > 4)
+                       packedDate[0] = htonl(((*list)->date >> 32) & 0x3);
+               else
+                       packedDate[0] = 0;
+
+               packedDate[1] = htonl((*list)->date);
+               hashwrite(f, packedDate, 8);
+
+               list++;
+       }
+}
+
+static void write_graph_chunk_large_edges(struct hashfile *f,
+                                         struct commit **commits,
+                                         int nr_commits)
+{
+       struct commit **list = commits;
+       struct commit **last = commits + nr_commits;
+       struct commit_list *parent;
+
+       while (list < last) {
+               int num_parents = 0;
+               for (parent = (*list)->parents; num_parents < 3 && parent;
+                    parent = parent->next)
+                       num_parents++;
+
+               if (num_parents <= 2) {
+                       list++;
+                       continue;
+               }
+
+               /* Since num_parents > 2, this initializer is safe. */
+               for (parent = (*list)->parents->next; parent; parent = parent->next) {
+                       int edge_value = sha1_pos(parent->item->object.oid.hash,
+                                                 commits,
+                                                 nr_commits,
+                                                 commit_to_sha1);
+
+                       if (edge_value < 0)
+                               edge_value = GRAPH_PARENT_MISSING;
+                       else if (!parent->next)
+                               edge_value |= GRAPH_LAST_EDGE;
+
+                       hashwrite_be32(f, edge_value);
+               }
+
+               list++;
+       }
+}
+
+static int commit_compare(const void *_a, const void *_b)
+{
+       const struct object_id *a = (const struct object_id *)_a;
+       const struct object_id *b = (const struct object_id *)_b;
+       return oidcmp(a, b);
+}
+
+struct packed_commit_list {
+       struct commit **list;
+       int nr;
+       int alloc;
+};
+
+struct packed_oid_list {
+       struct object_id *list;
+       int nr;
+       int alloc;
+};
+
+static int add_packed_commits(const struct object_id *oid,
+                             struct packed_git *pack,
+                             uint32_t pos,
+                             void *data)
+{
+       struct packed_oid_list *list = (struct packed_oid_list*)data;
+       enum object_type type;
+       off_t offset = nth_packed_object_offset(pack, pos);
+       struct object_info oi = OBJECT_INFO_INIT;
+
+       oi.typep = &type;
+       if (packed_object_info(the_repository, pack, offset, &oi) < 0)
+               die("unable to get type of object %s", oid_to_hex(oid));
+
+       if (type != OBJ_COMMIT)
+               return 0;
+
+       ALLOC_GROW(list->list, list->nr + 1, list->alloc);
+       oidcpy(&(list->list[list->nr]), oid);
+       list->nr++;
+
+       return 0;
+}
+
+static void add_missing_parents(struct packed_oid_list *oids, struct commit *commit)
+{
+       struct commit_list *parent;
+       for (parent = commit->parents; parent; parent = parent->next) {
+               if (!(parent->item->object.flags & UNINTERESTING)) {
+                       ALLOC_GROW(oids->list, oids->nr + 1, oids->alloc);
+                       oidcpy(&oids->list[oids->nr], &(parent->item->object.oid));
+                       oids->nr++;
+                       parent->item->object.flags |= UNINTERESTING;
+               }
+       }
+}
+
+static void close_reachable(struct packed_oid_list *oids)
+{
+       int i;
+       struct commit *commit;
+
+       for (i = 0; i < oids->nr; i++) {
+               commit = lookup_commit(&oids->list[i]);
+               if (commit)
+                       commit->object.flags |= UNINTERESTING;
+       }
+
+       /*
+        * As this loop runs, oids->nr may grow, but not more
+        * than the number of missing commits in the reachable
+        * closure.
+        */
+       for (i = 0; i < oids->nr; i++) {
+               commit = lookup_commit(&oids->list[i]);
+
+               if (commit && !parse_commit(commit))
+                       add_missing_parents(oids, commit);
+       }
+
+       for (i = 0; i < oids->nr; i++) {
+               commit = lookup_commit(&oids->list[i]);
+
+               if (commit)
+                       commit->object.flags &= ~UNINTERESTING;
+       }
+}
+
+void write_commit_graph(const char *obj_dir,
+                       const char **pack_indexes,
+                       int nr_packs,
+                       const char **commit_hex,
+                       int nr_commits,
+                       int append)
+{
+       struct packed_oid_list oids;
+       struct packed_commit_list commits;
+       struct hashfile *f;
+       uint32_t i, count_distinct = 0;
+       char *graph_name;
+       int fd;
+       struct lock_file lk = LOCK_INIT;
+       uint32_t chunk_ids[5];
+       uint64_t chunk_offsets[5];
+       int num_chunks;
+       int num_extra_edges;
+       struct commit_list *parent;
+
+       oids.nr = 0;
+       oids.alloc = approximate_object_count() / 4;
+
+       if (append) {
+               prepare_commit_graph_one(obj_dir);
+               if (commit_graph)
+                       oids.alloc += commit_graph->num_commits;
+       }
+
+       if (oids.alloc < 1024)
+               oids.alloc = 1024;
+       ALLOC_ARRAY(oids.list, oids.alloc);
+
+       if (append && commit_graph) {
+               for (i = 0; i < commit_graph->num_commits; i++) {
+                       const unsigned char *hash = commit_graph->chunk_oid_lookup +
+                               commit_graph->hash_len * i;
+                       hashcpy(oids.list[oids.nr++].hash, hash);
+               }
+       }
+
+       if (pack_indexes) {
+               struct strbuf packname = STRBUF_INIT;
+               int dirlen;
+               strbuf_addf(&packname, "%s/pack/", obj_dir);
+               dirlen = packname.len;
+               for (i = 0; i < nr_packs; i++) {
+                       struct packed_git *p;
+                       strbuf_setlen(&packname, dirlen);
+                       strbuf_addstr(&packname, pack_indexes[i]);
+                       p = add_packed_git(packname.buf, packname.len, 1);
+                       if (!p)
+                               die("error adding pack %s", packname.buf);
+                       if (open_pack_index(p))
+                               die("error opening index for %s", packname.buf);
+                       for_each_object_in_pack(p, add_packed_commits, &oids);
+                       close_pack(p);
+               }
+               strbuf_release(&packname);
+       }
+
+       if (commit_hex) {
+               for (i = 0; i < nr_commits; i++) {
+                       const char *end;
+                       struct object_id oid;
+                       struct commit *result;
+
+                       if (commit_hex[i] && parse_oid_hex(commit_hex[i], &oid, &end))
+                               continue;
+
+                       result = lookup_commit_reference_gently(&oid, 1);
+
+                       if (result) {
+                               ALLOC_GROW(oids.list, oids.nr + 1, oids.alloc);
+                               oidcpy(&oids.list[oids.nr], &(result->object.oid));
+                               oids.nr++;
+                       }
+               }
+       }
+
+       if (!pack_indexes && !commit_hex)
+               for_each_packed_object(add_packed_commits, &oids, 0);
+
+       close_reachable(&oids);
+
+       QSORT(oids.list, oids.nr, commit_compare);
+
+       count_distinct = 1;
+       for (i = 1; i < oids.nr; i++) {
+               if (oidcmp(&oids.list[i-1], &oids.list[i]))
+                       count_distinct++;
+       }
+
+       if (count_distinct >= GRAPH_PARENT_MISSING)
+               die(_("the commit graph format cannot write %d commits"), count_distinct);
+
+       commits.nr = 0;
+       commits.alloc = count_distinct;
+       ALLOC_ARRAY(commits.list, commits.alloc);
+
+       num_extra_edges = 0;
+       for (i = 0; i < oids.nr; i++) {
+               int num_parents = 0;
+               if (i > 0 && !oidcmp(&oids.list[i-1], &oids.list[i]))
+                       continue;
+
+               commits.list[commits.nr] = lookup_commit(&oids.list[i]);
+               parse_commit(commits.list[commits.nr]);
+
+               for (parent = commits.list[commits.nr]->parents;
+                    parent; parent = parent->next)
+                       num_parents++;
+
+               if (num_parents > 2)
+                       num_extra_edges += num_parents - 1;
+
+               commits.nr++;
+       }
+       num_chunks = num_extra_edges ? 4 : 3;
+
+       if (commits.nr >= GRAPH_PARENT_MISSING)
+               die(_("too many commits to write graph"));
+
+       graph_name = get_commit_graph_filename(obj_dir);
+       fd = hold_lock_file_for_update(&lk, graph_name, 0);
+
+       if (fd < 0) {
+               struct strbuf folder = STRBUF_INIT;
+               strbuf_addstr(&folder, graph_name);
+               strbuf_setlen(&folder, strrchr(folder.buf, '/') - folder.buf);
+
+               if (mkdir(folder.buf, 0777) < 0)
+                       die_errno(_("cannot mkdir %s"), folder.buf);
+               strbuf_release(&folder);
+
+               fd = hold_lock_file_for_update(&lk, graph_name, LOCK_DIE_ON_ERROR);
+
+               if (fd < 0)
+                       die_errno("unable to create '%s'", graph_name);
+       }
+
+       f = hashfd(lk.tempfile->fd, lk.tempfile->filename.buf);
+
+       hashwrite_be32(f, GRAPH_SIGNATURE);
+
+       hashwrite_u8(f, GRAPH_VERSION);
+       hashwrite_u8(f, GRAPH_OID_VERSION);
+       hashwrite_u8(f, num_chunks);
+       hashwrite_u8(f, 0); /* unused padding byte */
+
+       chunk_ids[0] = GRAPH_CHUNKID_OIDFANOUT;
+       chunk_ids[1] = GRAPH_CHUNKID_OIDLOOKUP;
+       chunk_ids[2] = GRAPH_CHUNKID_DATA;
+       if (num_extra_edges)
+               chunk_ids[3] = GRAPH_CHUNKID_LARGEEDGES;
+       else
+               chunk_ids[3] = 0;
+       chunk_ids[4] = 0;
+
+       chunk_offsets[0] = 8 + (num_chunks + 1) * GRAPH_CHUNKLOOKUP_WIDTH;
+       chunk_offsets[1] = chunk_offsets[0] + GRAPH_FANOUT_SIZE;
+       chunk_offsets[2] = chunk_offsets[1] + GRAPH_OID_LEN * commits.nr;
+       chunk_offsets[3] = chunk_offsets[2] + (GRAPH_OID_LEN + 16) * commits.nr;
+       chunk_offsets[4] = chunk_offsets[3] + 4 * num_extra_edges;
+
+       for (i = 0; i <= num_chunks; i++) {
+               uint32_t chunk_write[3];
+
+               chunk_write[0] = htonl(chunk_ids[i]);
+               chunk_write[1] = htonl(chunk_offsets[i] >> 32);
+               chunk_write[2] = htonl(chunk_offsets[i] & 0xffffffff);
+               hashwrite(f, chunk_write, 12);
+       }
+
+       write_graph_chunk_fanout(f, commits.list, commits.nr);
+       write_graph_chunk_oids(f, GRAPH_OID_LEN, commits.list, commits.nr);
+       write_graph_chunk_data(f, GRAPH_OID_LEN, commits.list, commits.nr);
+       write_graph_chunk_large_edges(f, commits.list, commits.nr);
+
+       close_commit_graph();
+       finalize_hashfile(f, NULL, CSUM_HASH_IN_STREAM | CSUM_FSYNC);
+       commit_lock_file(&lk);
+
+       free(oids.list);
+       oids.alloc = 0;
+       oids.nr = 0;
+}
diff --git a/commit-graph.h b/commit-graph.h
new file mode 100644 (file)
index 0000000..260a468
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef COMMIT_GRAPH_H
+#define COMMIT_GRAPH_H
+
+#include "git-compat-util.h"
+
+char *get_commit_graph_filename(const char *obj_dir);
+
+/*
+ * Given a commit struct, try to fill the commit struct info, including:
+ *  1. tree object
+ *  2. date
+ *  3. parents.
+ *
+ * Returns 1 if and only if the commit was found in the packed graph.
+ *
+ * See parse_commit_buffer() for the fallback after this call.
+ */
+int parse_commit_in_graph(struct commit *item);
+
+struct tree *get_commit_tree_in_graph(const struct commit *c);
+
+struct commit_graph {
+       int graph_fd;
+
+       const unsigned char *data;
+       size_t data_len;
+
+       unsigned char hash_len;
+       unsigned char num_chunks;
+       uint32_t num_commits;
+       struct object_id oid;
+
+       const uint32_t *chunk_oid_fanout;
+       const unsigned char *chunk_oid_lookup;
+       const unsigned char *chunk_commit_data;
+       const unsigned char *chunk_large_edges;
+};
+
+struct commit_graph *load_commit_graph_one(const char *graph_file);
+
+void write_commit_graph(const char *obj_dir,
+                       const char **pack_indexes,
+                       int nr_packs,
+                       const char **commit_hex,
+                       int nr_commits,
+                       int append);
+
+#endif
index 00c99c7272badc2d5a8f16c29db7d4040f5eb4d3..0030e79940ff8564b5c8c5ebab462eb1bd745174 100644 (file)
--- a/commit.c
+++ b/commit.c
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "tag.h"
 #include "commit.h"
+#include "commit-graph.h"
 #include "pkt-line.h"
 #include "utf8.h"
 #include "diff.h"
@@ -12,6 +13,7 @@
 #include "prio-queue.h"
 #include "sha1-lookup.h"
 #include "wt-status.h"
+#include "advice.h"
 
 static struct commit_extra_header *read_commit_extra_header_lines(const char *buf, size_t len, const char **);
 
@@ -176,6 +178,15 @@ static int read_graft_file(const char *graft_file)
        struct strbuf buf = STRBUF_INIT;
        if (!fp)
                return -1;
+       if (advice_graft_file_deprecated)
+               advise(_("Support for <GIT_DIR>/info/grafts is deprecated\n"
+                        "and will be removed in a future Git version.\n"
+                        "\n"
+                        "Please use \"git replace --convert-graft-file\"\n"
+                        "to convert the grafts into replace refs.\n"
+                        "\n"
+                        "Turn this message off by running\n"
+                        "\"git config advice.graftFileDeprecated false\""));
        while (!strbuf_getwholeline(&buf, fp, '\n')) {
                /* The format is just "Commit Parent1 Parent2 ...\n" */
                struct commit_graft *graft = read_graft_line(&buf);
@@ -196,6 +207,9 @@ static void prepare_commit_graft(void)
 
        if (commit_graft_prepared)
                return;
+       if (!startup_info->have_repository)
+               return;
+
        graft_file = get_graft_file();
        read_graft_file(graft_file);
        /* make sure shallows are read */
@@ -266,7 +280,7 @@ const void *get_commit_buffer(const struct commit *commit, unsigned long *sizep)
        if (!ret) {
                enum object_type type;
                unsigned long size;
-               ret = read_sha1_file(commit->object.oid.hash, &type, &size);
+               ret = read_object_file(&commit->object.oid, &type, &size);
                if (!ret)
                        die("cannot read commit object %s",
                            oid_to_hex(&commit->object.oid));
@@ -295,6 +309,22 @@ void free_commit_buffer(struct commit *commit)
        }
 }
 
+struct tree *get_commit_tree(const struct commit *commit)
+{
+       if (commit->maybe_tree || !commit->object.parsed)
+               return commit->maybe_tree;
+
+       if (commit->graph_pos == COMMIT_NOT_FROM_GRAPH)
+               BUG("commit has NULL tree, but was not loaded from commit-graph");
+
+       return get_commit_tree_in_graph(commit);
+}
+
+struct object_id *get_commit_tree_oid(const struct commit *commit)
+{
+       return &get_commit_tree(commit)->object.oid;
+}
+
 const void *detach_commit_buffer(struct commit *commit, unsigned long *sizep)
 {
        struct commit_buffer *v = buffer_slab_peek(&buffer_slab, commit);
@@ -331,10 +361,10 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s
        if (tail <= bufptr + tree_entry_len + 1 || memcmp(bufptr, "tree ", 5) ||
                        bufptr[tree_entry_len] != '\n')
                return error("bogus commit object %s", oid_to_hex(&item->object.oid));
-       if (get_sha1_hex(bufptr + 5, parent.hash) < 0)
+       if (get_oid_hex(bufptr + 5, &parent) < 0)
                return error("bad tree pointer in commit %s",
                             oid_to_hex(&item->object.oid));
-       item->tree = lookup_tree(&parent);
+       item->maybe_tree = lookup_tree(&parent);
        bufptr += tree_entry_len + 1; /* "tree " + "hex sha1" + "\n" */
        pptr = &item->parents;
 
@@ -343,7 +373,7 @@ int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long s
                struct commit *new_parent;
 
                if (tail <= bufptr + parent_entry_len + 1 ||
-                   get_sha1_hex(bufptr + 7, parent.hash) ||
+                   get_oid_hex(bufptr + 7, &parent) ||
                    bufptr[parent_entry_len] != '\n')
                        return error("bad parents in commit %s", oid_to_hex(&item->object.oid));
                bufptr += parent_entry_len + 1;
@@ -383,7 +413,9 @@ int parse_commit_gently(struct commit *item, int quiet_on_missing)
                return -1;
        if (item->object.parsed)
                return 0;
-       buffer = read_sha1_file(item->object.oid.hash, &type, &size);
+       if (parse_commit_in_graph(item))
+               return 0;
+       buffer = read_object_file(&item->object.oid, &type, &size);
        if (!buffer)
                return quiet_on_missing ? -1 :
                        error("Could not read %s",
@@ -1206,7 +1238,7 @@ static void handle_signed_tag(struct commit *parent, struct commit_extra_header
        desc = merge_remote_util(parent);
        if (!desc || !desc->obj)
                return;
-       buf = read_sha1_file(desc->obj->oid.hash, &type, &size);
+       buf = read_object_file(&desc->obj->oid, &type, &size);
        if (!buf || type != OBJ_TAG)
                goto free_return;
        len = parse_signature(buf, size);
@@ -1288,17 +1320,19 @@ struct commit_extra_header *read_commit_extra_headers(struct commit *commit,
        return extra;
 }
 
-void for_each_mergetag(each_mergetag_fn fn, struct commit *commit, void *data)
+int for_each_mergetag(each_mergetag_fn fn, struct commit *commit, void *data)
 {
        struct commit_extra_header *extra, *to_free;
+       int res = 0;
 
        to_free = read_commit_extra_headers(commit, NULL);
-       for (extra = to_free; extra; extra = extra->next) {
+       for (extra = to_free; !res && extra; extra = extra->next) {
                if (strcmp(extra->key, "mergetag"))
                        continue; /* not a merge tag */
-               fn(commit, extra, data);
+               res = fn(commit, extra, data);
        }
        free_commit_extra_headers(to_free);
+       return res;
 }
 
 static inline int standard_header_field(const char *field, size_t len)
@@ -1517,7 +1551,7 @@ int commit_tree_extended(const char *msg, size_t msg_len,
        int encoding_is_utf8;
        struct strbuf buffer;
 
-       assert_sha1_type(tree->hash, OBJ_TREE);
+       assert_oid_type(tree, OBJ_TREE);
 
        if (memchr(msg, '\0', msg_len))
                return error("a NUL byte in commit log message not allowed.");
index 0fb8271665c6c98ccca803fbe002327bf38fcfb3..c3af512f8b1b90b3963d0921f7ec0d0a43a2fcbe 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -9,6 +9,8 @@
 #include "string-list.h"
 #include "pretty.h"
 
+#define COMMIT_NOT_FROM_GRAPH 0xFFFFFFFF
+
 struct commit_list {
        struct commit *item;
        struct commit_list *next;
@@ -17,10 +19,17 @@ struct commit_list {
 struct commit {
        struct object object;
        void *util;
-       unsigned int index;
        timestamp_t date;
        struct commit_list *parents;
-       struct tree *tree;
+
+       /*
+        * If the commit is loaded from the commit-graph file, then this
+        * member may be NULL. Only access it through get_commit_tree()
+        * or get_commit_tree_oid().
+        */
+       struct tree *maybe_tree;
+       uint32_t graph_pos;
+       unsigned int index;
 };
 
 extern int save_commit_buffer;
@@ -99,6 +108,9 @@ void unuse_commit_buffer(const struct commit *, const void *buffer);
  */
 void free_commit_buffer(struct commit *);
 
+struct tree *get_commit_tree(const struct commit *);
+struct object_id *get_commit_tree_oid(const struct commit *);
+
 /*
  * Disassociate any cached object buffer from the commit, but do not free it.
  * The buffer (or NULL, if none) is returned.
@@ -291,10 +303,10 @@ extern const char *find_commit_header(const char *msg, const char *key,
 /* Find the end of the log message, the right place for a new trailer. */
 extern int ignore_non_trailer(const char *buf, size_t len);
 
-typedef void (*each_mergetag_fn)(struct commit *commit, struct commit_extra_header *extra,
+typedef int (*each_mergetag_fn)(struct commit *commit, struct commit_extra_header *extra,
                                 void *cb_data);
 
-extern void for_each_mergetag(each_mergetag_fn fn, struct commit *commit, void *data);
+extern int for_each_mergetag(each_mergetag_fn fn, struct commit *commit, void *data);
 
 struct merge_remote_desc {
        struct object *obj; /* the named object, could be a tag */
index 6a689007e7ce3fe08f148e8b82c0a1c618c513a5..3728f66b4cce80d298aab0e551a2d3c03e2c4357 100644 (file)
@@ -1,5 +1,5 @@
 #include "cache.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "attr.h"
 
 /*
@@ -32,11 +32,13 @@ int main(int argc, const char **argv)
         */
        sanitize_stdfds();
 
+       git_resolve_executable_dir(argv[0]);
+
        git_setup_gettext();
 
-       attr_start();
+       initialize_the_repository();
 
-       git_extract_argv0_path(argv[0]);
+       attr_start();
 
        restore_sigpipe_to_default();
 
index b047e2166096f134811ea1a451225c07775eb0ce..0c0c47422182822ed06e46284aa2d294de3e96a0 100644 (file)
@@ -2313,7 +2313,7 @@ void mingw_startup(void)
                die_startup();
 
        /* determine size of argv and environ conversion buffer */
-       maxlen = wcslen(_wpgmptr);
+       maxlen = wcslen(wargv[0]);
        for (i = 1; i < argc; i++)
                maxlen = max(maxlen, wcslen(wargv[i]));
        for (i = 0; wenv[i]; i++)
@@ -2333,8 +2333,7 @@ void mingw_startup(void)
        buffer = malloc_startup(maxlen);
 
        /* convert command line arguments and environment to UTF-8 */
-       __argv[0] = wcstoutfdup_startup(buffer, _wpgmptr, maxlen);
-       for (i = 1; i < argc; i++)
+       for (i = 0; i < argc; i++)
                __argv[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen);
        for (i = 0; wenv[i]; i++)
                environ[i] = wcstoutfdup_startup(buffer, wenv[i], maxlen);
index b0c20e6cb8ab1f5dc3cd3b4573b7e9d6dbf8cd2b..fbbf0f8e9f2b2ae0a96769108d8a2773f071aec1 100644 (file)
--- a/config.c
+++ b/config.c
@@ -9,13 +9,14 @@
 #include "config.h"
 #include "repository.h"
 #include "lockfile.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "strbuf.h"
 #include "quote.h"
 #include "hashmap.h"
 #include "string-list.h"
 #include "utf8.h"
 #include "dir.h"
+#include "color.h"
 
 struct config_source {
        struct config_source *prev;
@@ -102,7 +103,7 @@ static int config_buf_ungetc(int c, struct config_source *conf)
        if (conf->u.buf.pos > 0) {
                conf->u.buf.pos--;
                if (conf->u.buf.buf[conf->u.buf.pos] != c)
-                       die("BUG: config_buf can only ungetc the same character");
+                       BUG("config_buf can only ungetc the same character");
                return c;
        }
 
@@ -189,7 +190,7 @@ static int prepare_include_condition_pattern(struct strbuf *pat)
                strbuf_realpath(&path, cf->path, 1);
                slash = find_last_dir_sep(path.buf);
                if (!slash)
-                       die("BUG: how is this possible?");
+                       BUG("how is this possible?");
                strbuf_splice(pat, 0, 1, path.buf, slash - path.buf);
                prefix = slash - path.buf + 1 /* slash */;
        } else if (!is_absolute_path(pat->buf))
@@ -653,7 +654,45 @@ static int get_base_var(struct strbuf *name)
        }
 }
 
-static int git_parse_source(config_fn_t fn, void *data)
+struct parse_event_data {
+       enum config_event_t previous_type;
+       size_t previous_offset;
+       const struct config_options *opts;
+};
+
+static int do_event(enum config_event_t type, struct parse_event_data *data)
+{
+       size_t offset;
+
+       if (!data->opts || !data->opts->event_fn)
+               return 0;
+
+       if (type == CONFIG_EVENT_WHITESPACE &&
+           data->previous_type == type)
+               return 0;
+
+       offset = cf->do_ftell(cf);
+       /*
+        * At EOF, the parser always "inserts" an extra '\n', therefore
+        * the end offset of the event is the current file position, otherwise
+        * we will already have advanced to the next event.
+        */
+       if (type != CONFIG_EVENT_EOF)
+               offset--;
+
+       if (data->previous_type != CONFIG_EVENT_EOF &&
+           data->opts->event_fn(data->previous_type, data->previous_offset,
+                                offset, data->opts->event_fn_data) < 0)
+               return -1;
+
+       data->previous_type = type;
+       data->previous_offset = offset;
+
+       return 0;
+}
+
+static int git_parse_source(config_fn_t fn, void *data,
+                           const struct config_options *opts)
 {
        int comment = 0;
        int baselen = 0;
@@ -664,8 +703,15 @@ static int git_parse_source(config_fn_t fn, void *data)
        /* U+FEFF Byte Order Mark in UTF8 */
        const char *bomptr = utf8_bom;
 
+       /* For the parser event callback */
+       struct parse_event_data event_data = {
+               CONFIG_EVENT_EOF, 0, opts
+       };
+
        for (;;) {
-               int c = get_next_char();
+               int c;
+
+               c = get_next_char();
                if (bomptr && *bomptr) {
                        /* We are at the file beginning; skip UTF8-encoded BOM
                         * if present. Sane editors won't put this in on their
@@ -682,18 +728,33 @@ static int git_parse_source(config_fn_t fn, void *data)
                        }
                }
                if (c == '\n') {
-                       if (cf->eof)
+                       if (cf->eof) {
+                               if (do_event(CONFIG_EVENT_EOF, &event_data) < 0)
+                                       return -1;
                                return 0;
+                       }
+                       if (do_event(CONFIG_EVENT_WHITESPACE, &event_data) < 0)
+                               return -1;
                        comment = 0;
                        continue;
                }
-               if (comment || isspace(c))
+               if (comment)
+                       continue;
+               if (isspace(c)) {
+                       if (do_event(CONFIG_EVENT_WHITESPACE, &event_data) < 0)
+                                       return -1;
                        continue;
+               }
                if (c == '#' || c == ';') {
+                       if (do_event(CONFIG_EVENT_COMMENT, &event_data) < 0)
+                                       return -1;
                        comment = 1;
                        continue;
                }
                if (c == '[') {
+                       if (do_event(CONFIG_EVENT_SECTION, &event_data) < 0)
+                                       return -1;
+
                        /* Reset prior to determining a new stem */
                        strbuf_reset(var);
                        if (get_base_var(var) < 0 || var->len < 1)
@@ -704,6 +765,10 @@ static int git_parse_source(config_fn_t fn, void *data)
                }
                if (!isalpha(c))
                        break;
+
+               if (do_event(CONFIG_EVENT_ENTRY, &event_data) < 0)
+                       return -1;
+
                /*
                 * Truncate the var name back to the section header
                 * stem prior to grabbing the suffix part of the name
@@ -715,6 +780,9 @@ static int git_parse_source(config_fn_t fn, void *data)
                        break;
        }
 
+       if (do_event(CONFIG_EVENT_ERROR, &event_data) < 0)
+               return -1;
+
        switch (cf->origin_type) {
        case CONFIG_ORIGIN_BLOB:
                error_msg = xstrfmt(_("bad config line %d in blob %s"),
@@ -1000,6 +1068,15 @@ int git_config_expiry_date(timestamp_t *timestamp, const char *var, const char *
        return 0;
 }
 
+int git_config_color(char *dest, const char *var, const char *value)
+{
+       if (!value)
+               return config_error_nonbool(var);
+       if (color_parse(value, dest) < 0)
+               return -1;
+       return 0;
+}
+
 static int git_default_core_config(const char *var, const char *value)
 {
        /* This needs a better name */
@@ -1172,6 +1249,11 @@ static int git_default_core_config(const char *var, const char *value)
                return 0;
        }
 
+       if (!strcmp(var, "core.checkroundtripencoding")) {
+               check_roundtrip_encoding = xstrdup(value);
+               return 0;
+       }
+
        if (!strcmp(var, "core.notesref")) {
                notes_ref_name = xstrdup(value);
                return 0;
@@ -1226,6 +1308,11 @@ static int git_default_core_config(const char *var, const char *value)
                return 0;
        }
 
+       if (!strcmp(var, "core.commitgraph")) {
+               core_commit_graph = git_config_bool(var, value);
+               return 0;
+       }
+
        if (!strcmp(var, "core.sparsecheckout")) {
                core_apply_sparse_checkout = git_config_bool(var, value);
                return 0;
@@ -1365,7 +1452,7 @@ int git_default_config(const char *var, const char *value, void *dummy)
        if (starts_with(var, "mailmap."))
                return git_default_mailmap_config(var, value);
 
-       if (starts_with(var, "advice."))
+       if (starts_with(var, "advice.") || starts_with(var, "color.advice"))
                return git_default_advice_config(var, value);
 
        if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) {
@@ -1398,7 +1485,8 @@ int git_default_config(const char *var, const char *value, void *dummy)
  * fgetc, ungetc, ftell of top need to be initialized before calling
  * this function.
  */
-static int do_config_from(struct config_source *top, config_fn_t fn, void *data)
+static int do_config_from(struct config_source *top, config_fn_t fn, void *data,
+                         const struct config_options *opts)
 {
        int ret;
 
@@ -1410,7 +1498,7 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data)
        strbuf_init(&top->var, 1024);
        cf = top;
 
-       ret = git_parse_source(fn, data);
+       ret = git_parse_source(fn, data, opts);
 
        /* pop config-file parsing state stack */
        strbuf_release(&top->value);
@@ -1423,9 +1511,10 @@ static int do_config_from(struct config_source *top, config_fn_t fn, void *data)
 static int do_config_from_file(config_fn_t fn,
                const enum config_origin_type origin_type,
                const char *name, const char *path, FILE *f,
-               void *data)
+               void *data, const struct config_options *opts)
 {
        struct config_source top;
+       int ret;
 
        top.u.file = f;
        top.origin_type = origin_type;
@@ -1436,29 +1525,39 @@ static int do_config_from_file(config_fn_t fn,
        top.do_ungetc = config_file_ungetc;
        top.do_ftell = config_file_ftell;
 
-       return do_config_from(&top, fn, data);
+       flockfile(f);
+       ret = do_config_from(&top, fn, data, opts);
+       funlockfile(f);
+       return ret;
 }
 
 static int git_config_from_stdin(config_fn_t fn, void *data)
 {
-       return do_config_from_file(fn, CONFIG_ORIGIN_STDIN, "", NULL, stdin, data);
+       return do_config_from_file(fn, CONFIG_ORIGIN_STDIN, "", NULL, stdin,
+                                  data, NULL);
 }
 
-int git_config_from_file(config_fn_t fn, const char *filename, void *data)
+int git_config_from_file_with_options(config_fn_t fn, const char *filename,
+                                     void *data,
+                                     const struct config_options *opts)
 {
        int ret = -1;
        FILE *f;
 
        f = fopen_or_warn(filename, "r");
        if (f) {
-               flockfile(f);
-               ret = do_config_from_file(fn, CONFIG_ORIGIN_FILE, filename, filename, f, data);
-               funlockfile(f);
+               ret = do_config_from_file(fn, CONFIG_ORIGIN_FILE, filename,
+                                         filename, f, data, opts);
                fclose(f);
        }
        return ret;
 }
 
+int git_config_from_file(config_fn_t fn, const char *filename, void *data)
+{
+       return git_config_from_file_with_options(fn, filename, data, NULL);
+}
+
 int git_config_from_mem(config_fn_t fn, const enum config_origin_type origin_type,
                        const char *name, const char *buf, size_t len, void *data)
 {
@@ -1475,7 +1574,7 @@ int git_config_from_mem(config_fn_t fn, const enum config_origin_type origin_typ
        top.do_ungetc = config_buf_ungetc;
        top.do_ftell = config_buf_ftell;
 
-       return do_config_from(&top, fn, data);
+       return do_config_from(&top, fn, data, NULL);
 }
 
 int git_config_from_blob_oid(config_fn_t fn,
@@ -1488,7 +1587,7 @@ int git_config_from_blob_oid(config_fn_t fn,
        unsigned long size;
        int ret;
 
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf)
                return error("unable to load config blob object '%s'", name);
        if (type != OBJ_BLOB) {
@@ -1715,7 +1814,7 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
        l_item->value_index = e->value_list.nr - 1;
 
        if (!cf)
-               die("BUG: configset_add_value has no source");
+               BUG("configset_add_value has no source");
        if (cf->name) {
                kv_info->filename = strintern(cf->name);
                kv_info->linenr = cf->linenr;
@@ -2219,96 +2318,111 @@ void git_die_config(const char *key, const char *err, ...)
  * Find all the stuff for git_config_set() below.
  */
 
-static struct {
+struct config_store_data {
        int baselen;
        char *key;
        int do_not_match;
        regex_t *value_regex;
        int multi_replace;
-       size_t *offset;
-       unsigned int offset_alloc;
-       enum { START, SECTION_SEEN, SECTION_END_SEEN, KEY_SEEN } state;
-       unsigned int seen;
-} store;
+       struct {
+               size_t begin, end;
+               enum config_event_t type;
+               int is_keys_section;
+       } *parsed;
+       unsigned int parsed_nr, parsed_alloc, *seen, seen_nr, seen_alloc;
+       unsigned int key_seen:1, section_seen:1, is_keys_section:1;
+};
 
-static int matches(const char *key, const char *value)
+static void config_store_data_clear(struct config_store_data *store)
 {
-       if (strcmp(key, store.key))
+       free(store->key);
+       if (store->value_regex != NULL &&
+           store->value_regex != CONFIG_REGEX_NONE) {
+               regfree(store->value_regex);
+               free(store->value_regex);
+       }
+       free(store->parsed);
+       free(store->seen);
+       memset(store, 0, sizeof(*store));
+}
+
+static int matches(const char *key, const char *value,
+                  const struct config_store_data *store)
+{
+       if (strcmp(key, store->key))
                return 0; /* not ours */
-       if (!store.value_regex)
+       if (!store->value_regex)
                return 1; /* always matches */
-       if (store.value_regex == CONFIG_REGEX_NONE)
+       if (store->value_regex == CONFIG_REGEX_NONE)
                return 0; /* never matches */
 
-       return store.do_not_match ^
-               (value && !regexec(store.value_regex, value, 0, NULL, 0));
+       return store->do_not_match ^
+               (value && !regexec(store->value_regex, value, 0, NULL, 0));
+}
+
+static int store_aux_event(enum config_event_t type,
+                          size_t begin, size_t end, void *data)
+{
+       struct config_store_data *store = data;
+
+       ALLOC_GROW(store->parsed, store->parsed_nr + 1, store->parsed_alloc);
+       store->parsed[store->parsed_nr].begin = begin;
+       store->parsed[store->parsed_nr].end = end;
+       store->parsed[store->parsed_nr].type = type;
+
+       if (type == CONFIG_EVENT_SECTION) {
+               if (cf->var.len < 2 || cf->var.buf[cf->var.len - 1] != '.')
+                       return error("invalid section name '%s'", cf->var.buf);
+
+               /* Is this the section we were looking for? */
+               store->is_keys_section =
+                       store->parsed[store->parsed_nr].is_keys_section =
+                       cf->var.len - 1 == store->baselen &&
+                       !strncasecmp(cf->var.buf, store->key, store->baselen);
+               if (store->is_keys_section) {
+                       store->section_seen = 1;
+                       ALLOC_GROW(store->seen, store->seen_nr + 1,
+                                  store->seen_alloc);
+                       store->seen[store->seen_nr] = store->parsed_nr;
+               }
+       }
+
+       store->parsed_nr++;
+
+       return 0;
 }
 
 static int store_aux(const char *key, const char *value, void *cb)
 {
-       const char *ep;
-       size_t section_len;
+       struct config_store_data *store = cb;
 
-       switch (store.state) {
-       case KEY_SEEN:
-               if (matches(key, value)) {
-                       if (store.seen == 1 && store.multi_replace == 0) {
+       if (store->key_seen) {
+               if (matches(key, value, store)) {
+                       if (store->seen_nr == 1 && store->multi_replace == 0) {
                                warning(_("%s has multiple values"), key);
                        }
 
-                       ALLOC_GROW(store.offset, store.seen + 1,
-                                  store.offset_alloc);
+                       ALLOC_GROW(store->seen, store->seen_nr + 1,
+                                  store->seen_alloc);
 
-                       store.offset[store.seen] = cf->do_ftell(cf);
-                       store.seen++;
+                       store->seen[store->seen_nr] = store->parsed_nr;
+                       store->seen_nr++;
                }
-               break;
-       case SECTION_SEEN:
+       } else if (store->is_keys_section) {
                /*
-                * What we are looking for is in store.key (both
-                * section and var), and its section part is baselen
-                * long.  We found key (again, both section and var).
-                * We would want to know if this key is in the same
-                * section as what we are looking for.  We already
-                * know we are in the same section as what should
-                * hold store.key.
+                * Do not increment matches yet: this may not be a match, but we
+                * are in the desired section.
                 */
-               ep = strrchr(key, '.');
-               section_len = ep - key;
+               ALLOC_GROW(store->seen, store->seen_nr + 1, store->seen_alloc);
+               store->seen[store->seen_nr] = store->parsed_nr;
+               store->section_seen = 1;
 
-               if ((section_len != store.baselen) ||
-                   memcmp(key, store.key, section_len+1)) {
-                       store.state = SECTION_END_SEEN;
-                       break;
-               }
-
-               /*
-                * Do not increment matches: this is no match, but we
-                * just made sure we are in the desired section.
-                */
-               ALLOC_GROW(store.offset, store.seen + 1,
-                          store.offset_alloc);
-               store.offset[store.seen] = cf->do_ftell(cf);
-               /* fallthru */
-       case SECTION_END_SEEN:
-       case START:
-               if (matches(key, value)) {
-                       ALLOC_GROW(store.offset, store.seen + 1,
-                                  store.offset_alloc);
-                       store.offset[store.seen] = cf->do_ftell(cf);
-                       store.state = KEY_SEEN;
-                       store.seen++;
-               } else {
-                       if (strrchr(key, '.') - key == store.baselen &&
-                             !strncmp(key, store.key, store.baselen)) {
-                                       store.state = SECTION_SEEN;
-                                       ALLOC_GROW(store.offset,
-                                                  store.seen + 1,
-                                                  store.offset_alloc);
-                                       store.offset[store.seen] = cf->do_ftell(cf);
-                       }
+               if (matches(key, value, store)) {
+                       store->seen_nr++;
+                       store->key_seen = 1;
                }
        }
+
        return 0;
 }
 
@@ -2320,31 +2434,33 @@ static int write_error(const char *filename)
        return 4;
 }
 
-static struct strbuf store_create_section(const char *key)
+static struct strbuf store_create_section(const char *key,
+                                         const struct config_store_data *store)
 {
        const char *dot;
        int i;
        struct strbuf sb = STRBUF_INIT;
 
-       dot = memchr(key, '.', store.baselen);
+       dot = memchr(key, '.', store->baselen);
        if (dot) {
                strbuf_addf(&sb, "[%.*s \"", (int)(dot - key), key);
-               for (i = dot - key + 1; i < store.baselen; i++) {
+               for (i = dot - key + 1; i < store->baselen; i++) {
                        if (key[i] == '"' || key[i] == '\\')
                                strbuf_addch(&sb, '\\');
                        strbuf_addch(&sb, key[i]);
                }
                strbuf_addstr(&sb, "\"]\n");
        } else {
-               strbuf_addf(&sb, "[%.*s]\n", store.baselen, key);
+               strbuf_addf(&sb, "[%.*s]\n", store->baselen, key);
        }
 
        return sb;
 }
 
-static ssize_t write_section(int fd, const char *key)
+static ssize_t write_section(int fd, const char *key,
+                            const struct config_store_data *store)
 {
-       struct strbuf sb = store_create_section(key);
+       struct strbuf sb = store_create_section(key, store);
        ssize_t ret;
 
        ret = write_in_full(fd, sb.buf, sb.len);
@@ -2353,11 +2469,12 @@ static ssize_t write_section(int fd, const char *key)
        return ret;
 }
 
-static ssize_t write_pair(int fd, const char *key, const char *value)
+static ssize_t write_pair(int fd, const char *key, const char *value,
+                         const struct config_store_data *store)
 {
        int i;
        ssize_t ret;
-       int length = strlen(key + store.baselen + 1);
+       int length = strlen(key + store->baselen + 1);
        const char *quote = "";
        struct strbuf sb = STRBUF_INIT;
 
@@ -2377,7 +2494,7 @@ static ssize_t write_pair(int fd, const char *key, const char *value)
                quote = "\"";
 
        strbuf_addf(&sb, "\t%.*s = %s",
-                   length, key + store.baselen + 1, quote);
+                   length, key + store->baselen + 1, quote);
 
        for (i = 0; value[i]; i++)
                switch (value[i]) {
@@ -2403,30 +2520,85 @@ static ssize_t write_pair(int fd, const char *key, const char *value)
        return ret;
 }
 
-static ssize_t find_beginning_of_line(const char *contents, size_t size,
-       size_t offset_, int *found_bracket)
+/*
+ * If we are about to unset the last key(s) in a section, and if there are
+ * no comments surrounding (or included in) the section, we will want to
+ * extend begin/end to remove the entire section.
+ *
+ * Note: the parameter `seen_ptr` points to the index into the store.seen
+ * array.  * This index may be incremented if a section has more than one
+ * entry (which all are to be removed).
+ */
+static void maybe_remove_section(struct config_store_data *store,
+                                const char *contents,
+                                size_t *begin_offset, size_t *end_offset,
+                                int *seen_ptr)
 {
-       size_t equal_offset = size, bracket_offset = size;
-       ssize_t offset;
+       size_t begin;
+       int i, seen, section_seen = 0;
 
-contline:
-       for (offset = offset_-2; offset > 0
-                       && contents[offset] != '\n'; offset--)
-               switch (contents[offset]) {
-                       case '=': equal_offset = offset; break;
-                       case ']': bracket_offset = offset; break;
+       /*
+        * First, ensure that this is the first key, and that there are no
+        * comments before the entry nor before the section header.
+        */
+       seen = *seen_ptr;
+       for (i = store->seen[seen]; i > 0; i--) {
+               enum config_event_t type = store->parsed[i - 1].type;
+
+               if (type == CONFIG_EVENT_COMMENT)
+                       /* There is a comment before this entry or section */
+                       return;
+               if (type == CONFIG_EVENT_ENTRY) {
+                       if (!section_seen)
+                               /* This is not the section's first entry. */
+                               return;
+                       /* We encountered no comment before the section. */
+                       break;
+               }
+               if (type == CONFIG_EVENT_SECTION) {
+                       if (!store->parsed[i - 1].is_keys_section)
+                               break;
+                       section_seen = 1;
                }
-       if (offset > 0 && contents[offset-1] == '\\') {
-               offset_ = offset;
-               goto contline;
        }
-       if (bracket_offset < equal_offset) {
-               *found_bracket = 1;
-               offset = bracket_offset+1;
-       } else
-               offset++;
+       begin = store->parsed[i].begin;
+
+       /*
+        * Next, make sure that we are removing he last key(s) in the section,
+        * and that there are no comments that are possibly about the current
+        * section.
+        */
+       for (i = store->seen[seen] + 1; i < store->parsed_nr; i++) {
+               enum config_event_t type = store->parsed[i].type;
 
-       return offset;
+               if (type == CONFIG_EVENT_COMMENT)
+                       return;
+               if (type == CONFIG_EVENT_SECTION) {
+                       if (store->parsed[i].is_keys_section)
+                               continue;
+                       break;
+               }
+               if (type == CONFIG_EVENT_ENTRY) {
+                       if (++seen < store->seen_nr &&
+                           i == store->seen[seen])
+                               /* We want to remove this entry, too */
+                               continue;
+                       /* There is another entry in this section. */
+                       return;
+               }
+       }
+
+       /*
+        * We are really removing the last entry/entries from this section, and
+        * there are no enclosed or surrounding comments. Remove the entire,
+        * now-empty section.
+        */
+       *seen_ptr = seen;
+       *begin_offset = begin;
+       if (i < store->parsed_nr)
+               *end_offset = store->parsed[i].begin;
+       else
+               *end_offset = store->parsed[store->parsed_nr - 1].end;
 }
 
 int git_config_set_in_file_gently(const char *config_filename,
@@ -2487,6 +2659,9 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
        char *filename_buf = NULL;
        char *contents = NULL;
        size_t contents_sz;
+       struct config_store_data store;
+
+       memset(&store, 0, sizeof(store));
 
        /* parse-key returns negative; flip the sign to feed exit(3) */
        ret = 0 - git_config_parse_key(key, &store.key, &store.baselen);
@@ -2505,7 +2680,6 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
        fd = hold_lock_file_for_update(&lock, config_filename, 0);
        if (fd < 0) {
                error_errno("could not lock config file %s", config_filename);
-               free(store.key);
                ret = CONFIG_NO_LOCK;
                goto out_free;
        }
@@ -2515,8 +2689,6 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
         */
        in_fd = open(config_filename, O_RDONLY);
        if ( in_fd < 0 ) {
-               free(store.key);
-
                if ( ENOENT != errno ) {
                        error_errno("opening %s", config_filename);
                        ret = CONFIG_INVALID_FILE; /* same as "invalid config file" */
@@ -2528,14 +2700,16 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                        goto out_free;
                }
 
-               store.key = (char *)key;
-               if (write_section(fd, key) < 0 ||
-                   write_pair(fd, key, value) < 0)
+               free(store.key);
+               store.key = xstrdup(key);
+               if (write_section(fd, key, &store) < 0 ||
+                   write_pair(fd, key, value, &store) < 0)
                        goto write_err_out;
        } else {
                struct stat st;
                size_t copy_begin, copy_end;
                int i, new_line = 0;
+               struct config_options opts;
 
                if (value_regex == NULL)
                        store.value_regex = NULL;
@@ -2552,45 +2726,38 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                        if (regcomp(store.value_regex, value_regex,
                                        REG_EXTENDED)) {
                                error("invalid pattern: %s", value_regex);
-                               free(store.value_regex);
+                               FREE_AND_NULL(store.value_regex);
                                ret = CONFIG_INVALID_PATTERN;
                                goto out_free;
                        }
                }
 
-               ALLOC_GROW(store.offset, 1, store.offset_alloc);
-               store.offset[0] = 0;
-               store.state = START;
-               store.seen = 0;
+               ALLOC_GROW(store.parsed, 1, store.parsed_alloc);
+               store.parsed[0].end = 0;
+
+               memset(&opts, 0, sizeof(opts));
+               opts.event_fn = store_aux_event;
+               opts.event_fn_data = &store;
 
                /*
-                * After this, store.offset will contain the *end* offset
-                * of the last match, or remain at 0 if no match was found.
+                * After this, store.parsed will contain offsets of all the
+                * parsed elements, and store.seen will contain a list of
+                * matches, as indices into store.parsed.
+                *
                 * As a side effect, we make sure to transform only a valid
                 * existing config file.
                 */
-               if (git_config_from_file(store_aux, config_filename, NULL)) {
+               if (git_config_from_file_with_options(store_aux,
+                                                     config_filename,
+                                                     &store, &opts)) {
                        error("invalid config file %s", config_filename);
-                       free(store.key);
-                       if (store.value_regex != NULL &&
-                           store.value_regex != CONFIG_REGEX_NONE) {
-                               regfree(store.value_regex);
-                               free(store.value_regex);
-                       }
                        ret = CONFIG_INVALID_FILE;
                        goto out_free;
                }
 
-               free(store.key);
-               if (store.value_regex != NULL &&
-                   store.value_regex != CONFIG_REGEX_NONE) {
-                       regfree(store.value_regex);
-                       free(store.value_regex);
-               }
-
                /* if nothing to unset, or too many matches, error out */
-               if ((store.seen == 0 && value == NULL) ||
-                               (store.seen > 1 && multi_replace == 0)) {
+               if ((store.seen_nr == 0 && value == NULL) ||
+                   (store.seen_nr > 1 && multi_replace == 0)) {
                        ret = CONFIG_NOTHING_SET;
                        goto out_free;
                }
@@ -2621,18 +2788,49 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                        goto out_free;
                }
 
-               if (store.seen == 0)
-                       store.seen = 1;
+               if (store.seen_nr == 0) {
+                       if (!store.seen_alloc) {
+                               /* Did not see key nor section */
+                               ALLOC_GROW(store.seen, 1, store.seen_alloc);
+                               store.seen[0] = store.parsed_nr
+                                       - !!store.parsed_nr;
+                       }
+                       store.seen_nr = 1;
+               }
 
-               for (i = 0, copy_begin = 0; i < store.seen; i++) {
-                       if (store.offset[i] == 0) {
-                               store.offset[i] = copy_end = contents_sz;
-                       } else if (store.state != KEY_SEEN) {
-                               copy_end = store.offset[i];
-                       } else
-                               copy_end = find_beginning_of_line(
-                                       contents, contents_sz,
-                                       store.offset[i]-2, &new_line);
+               for (i = 0, copy_begin = 0; i < store.seen_nr; i++) {
+                       size_t replace_end;
+                       int j = store.seen[i];
+
+                       new_line = 0;
+                       if (!store.key_seen) {
+                               copy_end = store.parsed[j].end;
+                               /* include '\n' when copying section header */
+                               if (copy_end > 0 && copy_end < contents_sz &&
+                                   contents[copy_end - 1] != '\n' &&
+                                   contents[copy_end] == '\n')
+                                       copy_end++;
+                               replace_end = copy_end;
+                       } else {
+                               replace_end = store.parsed[j].end;
+                               copy_end = store.parsed[j].begin;
+                               if (!value)
+                                       maybe_remove_section(&store, contents,
+                                                            &copy_end,
+                                                            &replace_end, &i);
+                               /*
+                                * Swallow preceding white-space on the same
+                                * line.
+                                */
+                               while (copy_end > 0 ) {
+                                       char c = contents[copy_end - 1];
+
+                                       if (isspace(c) && c != '\n')
+                                               copy_end--;
+                                       else
+                                               break;
+                               }
+                       }
 
                        if (copy_end > 0 && contents[copy_end-1] != '\n')
                                new_line = 1;
@@ -2646,16 +2844,16 @@ int git_config_set_multivar_in_file_gently(const char *config_filename,
                                    write_str_in_full(fd, "\n") < 0)
                                        goto write_err_out;
                        }
-                       copy_begin = store.offset[i];
+                       copy_begin = replace_end;
                }
 
                /* write the pair (value == NULL means unset) */
                if (value != NULL) {
-                       if (store.state == START) {
-                               if (write_section(fd, key) < 0)
+                       if (!store.section_seen) {
+                               if (write_section(fd, key, &store) < 0)
                                        goto write_err_out;
                        }
-                       if (write_pair(fd, key, value) < 0)
+                       if (write_pair(fd, key, value, &store) < 0)
                                goto write_err_out;
                }
 
@@ -2687,6 +2885,7 @@ out_free:
                munmap(contents, contents_sz);
        if (in_fd >= 0)
                close(in_fd);
+       config_store_data_clear(&store);
        return ret;
 
 write_err_out:
@@ -2779,7 +2978,8 @@ static int section_name_is_ok(const char *name)
 
 /* if new_name == NULL, the section is removed instead */
 static int git_config_copy_or_rename_section_in_file(const char *config_filename,
-                                     const char *old_name, const char *new_name, int copy)
+                                     const char *old_name,
+                                     const char *new_name, int copy)
 {
        int ret = 0, remove = 0;
        char *filename_buf = NULL;
@@ -2789,6 +2989,9 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
        FILE *config_file = NULL;
        struct stat st;
        struct strbuf copystr = STRBUF_INIT;
+       struct config_store_data store;
+
+       memset(&store, 0, sizeof(store));
 
        if (new_name && !section_name_is_ok(new_name)) {
                ret = error("invalid section name: %s", new_name);
@@ -2858,7 +3061,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
                                }
                                store.baselen = strlen(new_name);
                                if (!copy) {
-                                       if (write_section(out_fd, new_name) < 0) {
+                                       if (write_section(out_fd, new_name, &store) < 0) {
                                                ret = write_error(get_lock_file_path(&lock));
                                                goto out;
                                        }
@@ -2879,7 +3082,7 @@ static int git_config_copy_or_rename_section_in_file(const char *config_filename
                                                output[0] = '\t';
                                        }
                                } else {
-                                       copystr = store_create_section(new_name);
+                                       copystr = store_create_section(new_name, &store);
                                }
                        }
                        remove = 0;
@@ -2923,6 +3126,7 @@ out:
        rollback_lock_file(&lock);
 out_no_rollback:
        free(filename_buf);
+       config_store_data_clear(&store);
        return ret;
 }
 
@@ -3004,7 +3208,7 @@ const char *current_config_origin_type(void)
        else if(cf)
                type = cf->origin_type;
        else
-               die("BUG: current_config_origin_type called outside config callback");
+               BUG("current_config_origin_type called outside config callback");
 
        switch (type) {
        case CONFIG_ORIGIN_BLOB:
@@ -3018,7 +3222,7 @@ const char *current_config_origin_type(void)
        case CONFIG_ORIGIN_CMDLINE:
                return "command line";
        default:
-               die("BUG: unknown config origin type");
+               BUG("unknown config origin type");
        }
 }
 
@@ -3030,7 +3234,7 @@ const char *current_config_name(void)
        else if (cf)
                name = cf->name;
        else
-               die("BUG: current_config_name called outside config callback");
+               BUG("current_config_name called outside config callback");
        return name ? name : "";
 }
 
index ef70a9cac1e6dc67df24d157a4e5de38edd8c984..cdac2fc73e6a2d0bc3230848425557a23e88d0bf 100644 (file)
--- a/config.h
+++ b/config.h
@@ -28,15 +28,40 @@ enum config_origin_type {
        CONFIG_ORIGIN_CMDLINE
 };
 
+enum config_event_t {
+       CONFIG_EVENT_SECTION,
+       CONFIG_EVENT_ENTRY,
+       CONFIG_EVENT_WHITESPACE,
+       CONFIG_EVENT_COMMENT,
+       CONFIG_EVENT_EOF,
+       CONFIG_EVENT_ERROR
+};
+
+/*
+ * The parser event function (if not NULL) is called with the event type and
+ * the begin/end offsets of the parsed elements.
+ *
+ * Note: for CONFIG_EVENT_ENTRY (i.e. config variables), the trailing newline
+ * character is considered part of the element.
+ */
+typedef int (*config_parser_event_fn_t)(enum config_event_t type,
+                                       size_t begin_offset, size_t end_offset,
+                                       void *event_fn_data);
+
 struct config_options {
        unsigned int respect_includes : 1;
        const char *commondir;
        const char *git_dir;
+       config_parser_event_fn_t event_fn;
+       void *event_fn_data;
 };
 
 typedef int (*config_fn_t)(const char *, const char *, void *);
 extern int git_default_config(const char *, const char *, void *);
 extern int git_config_from_file(config_fn_t fn, const char *, void *);
+extern int git_config_from_file_with_options(config_fn_t fn, const char *,
+                                            void *,
+                                            const struct config_options *);
 extern int git_config_from_mem(config_fn_t fn, const enum config_origin_type,
                                        const char *name, const char *buf, size_t len, void *data);
 extern int git_config_from_blob_oid(config_fn_t fn, const char *name,
@@ -59,6 +84,7 @@ extern int git_config_bool(const char *, const char *);
 extern int git_config_string(const char **, const char *, const char *);
 extern int git_config_pathname(const char **, const char *, const char *);
 extern int git_config_expiry_date(timestamp_t *, const char *, const char *);
+extern int git_config_color(char *, const char *, const char *);
 extern int git_config_set_in_file_gently(const char *, const char *, const char *);
 extern void git_config_set_in_file(const char *, const char *, const char *);
 extern int git_config_set_gently(const char *, const char *);
diff --git a/config.mak.dev b/config.mak.dev
new file mode 100644 (file)
index 0000000..2d244ca
--- /dev/null
@@ -0,0 +1,42 @@
+ifeq ($(filter no-error,$(DEVOPTS)),)
+CFLAGS += -Werror
+endif
+CFLAGS += -Wdeclaration-after-statement
+CFLAGS += -Wno-format-zero-length
+CFLAGS += -Wold-style-definition
+CFLAGS += -Woverflow
+CFLAGS += -Wpointer-arith
+CFLAGS += -Wstrict-prototypes
+CFLAGS += -Wunused
+CFLAGS += -Wvla
+
+ifndef COMPILER_FEATURES
+COMPILER_FEATURES := $(shell ./detect-compiler $(CC))
+endif
+
+ifneq ($(filter clang4,$(COMPILER_FEATURES)),)
+CFLAGS += -Wtautological-constant-out-of-range-compare
+endif
+
+ifneq ($(or $(filter gcc6,$(COMPILER_FEATURES)),$(filter clang4,$(COMPILER_FEATURES))),)
+CFLAGS += -Wextra
+# if a function is public, there should be a prototype and the right
+# header file should be included. If not, it should be static.
+CFLAGS += -Wmissing-prototypes
+ifeq ($(filter extra-all,$(DEVOPTS)),)
+# These are disabled because we have these all over the place.
+CFLAGS += -Wno-empty-body
+CFLAGS += -Wno-missing-field-initializers
+CFLAGS += -Wno-sign-compare
+CFLAGS += -Wno-unused-function
+CFLAGS += -Wno-unused-parameter
+endif
+endif
+
+# uninitialized warnings on gcc 4.9.2 in xdiff/xdiffi.c and config.c
+# not worth fixing since newer compilers correctly stop complaining
+ifneq ($(filter gcc4,$(COMPILER_FEATURES)),)
+ifeq ($(filter gcc5,$(COMPILER_FEATURES)),)
+CFLAGS += -Wno-uninitialized
+endif
+endif
index d3524c568186065cf3b25587dc0fd9178b0bf053..c3f2c0fc17a076d280f5fb3cd1426fb32986347d 100644 (file)
@@ -37,6 +37,8 @@ ifeq ($(uname_S),Linux)
        HAVE_GETDELIM = YesPlease
        SANE_TEXT_GREP=-a
        FREAD_READS_DIRECTORIES = UnfortunatelyYes
+       BASIC_CFLAGS += -DHAVE_SYSINFO
+       PROCFS_EXECUTABLE_PATH = /proc/self/exe
 endif
 ifeq ($(uname_S),GNU/kFreeBSD)
        HAVE_ALLOCA_H = YesPlease
@@ -111,6 +113,7 @@ ifeq ($(uname_S),Darwin)
        BASIC_CFLAGS += -DPROTECT_HFS_DEFAULT=1
        HAVE_BSD_SYSCTL = YesPlease
        FREAD_READS_DIRECTORIES = UnfortunatelyYes
+       HAVE_NS_GET_EXECUTABLE_PATH = YesPlease
 endif
 ifeq ($(uname_S),SunOS)
        NEEDS_SOCKET = YesPlease
@@ -205,6 +208,7 @@ ifeq ($(uname_S),FreeBSD)
        HAVE_PATHS_H = YesPlease
        GMTIME_UNRELIABLE_ERRORS = UnfortunatelyYes
        HAVE_BSD_SYSCTL = YesPlease
+       HAVE_BSD_KERN_PROC_SYSCTL = YesPlease
        PAGER_ENV = LESS=FRX LV=-c MORE=FRX
        FREAD_READS_DIRECTORIES = UnfortunatelyYes
 endif
@@ -217,6 +221,8 @@ ifeq ($(uname_S),OpenBSD)
        BASIC_LDFLAGS += -L/usr/local/lib
        HAVE_PATHS_H = YesPlease
        HAVE_BSD_SYSCTL = YesPlease
+       HAVE_BSD_KERN_PROC_SYSCTL = YesPlease
+       PROCFS_EXECUTABLE_PATH = /proc/curproc/file
 endif
 ifeq ($(uname_S),MirBSD)
        NO_STRCASESTR = YesPlease
@@ -235,6 +241,8 @@ ifeq ($(uname_S),NetBSD)
        USE_ST_TIMESPEC = YesPlease
        HAVE_PATHS_H = YesPlease
        HAVE_BSD_SYSCTL = YesPlease
+       HAVE_BSD_KERN_PROC_SYSCTL = YesPlease
+       PROCFS_EXECUTABLE_PATH = /proc/curproc/exe
 endif
 ifeq ($(uname_S),AIX)
        DEFAULT_PAGER = more
@@ -350,6 +358,7 @@ ifeq ($(uname_S),Windows)
        SNPRINTF_RETURNS_BOGUS = YesPlease
        NO_SVN_TESTS = YesPlease
        RUNTIME_PREFIX = YesPlease
+       HAVE_WPGMPTR = YesWeDo
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
        NO_NSEC = YesPlease
        USE_WIN32_MMAP = YesPlease
@@ -498,6 +507,7 @@ ifneq (,$(findstring MINGW,$(uname_S)))
        NO_SVN_TESTS = YesPlease
        NO_PERL_MAKEMAKER = YesPlease
        RUNTIME_PREFIX = YesPlease
+       HAVE_WPGMPTR = YesWeDo
        NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
        NO_NSEC = YesPlease
        USE_WIN32_MMAP = YesPlease
index 7f8415140f309e0522310fac3160b5a01cefc7cd..e11b7976ab1c93d8ccec2e499d0093db42551059 100644 (file)
@@ -254,25 +254,25 @@ GIT_PARSE_WITH([openssl]))
 # Perl-compatible regular expressions instead of standard or extended
 # POSIX regular expressions.
 #
-# Currently USE_LIBPCRE is a synonym for USE_LIBPCRE1, define
-# USE_LIBPCRE2 instead if you'd like to use version 2 of the PCRE
-# library. The USE_LIBPCRE flag will likely be changed to mean v2 by
-# default in future releases.
+# USE_LIBPCRE is a synonym for USE_LIBPCRE2, define USE_LIBPCRE1
+# instead if you'd like to use the legacy version 1 of the PCRE
+# library. Support for version 1 will likely be removed in some future
+# release of Git, as upstream has all but abandoned it.
 #
 # Define LIBPCREDIR=/foo/bar if your PCRE header and library files are in
 # /foo/bar/include and /foo/bar/lib directories.
 #
 AC_ARG_WITH(libpcre,
-AS_HELP_STRING([--with-libpcre],[synonym for --with-libpcre1]),
+AS_HELP_STRING([--with-libpcre],[synonym for --with-libpcre2]),
     if test "$withval" = "no"; then
-       USE_LIBPCRE1=
+       USE_LIBPCRE2=
     elif test "$withval" = "yes"; then
-       USE_LIBPCRE1=YesPlease
+       USE_LIBPCRE2=YesPlease
     else
-       USE_LIBPCRE1=YesPlease
+       USE_LIBPCRE2=YesPlease
        LIBPCREDIR=$withval
        AC_MSG_NOTICE([Setting LIBPCREDIR to $LIBPCREDIR])
-        dnl USE_LIBPCRE1 can still be modified below, so don't substitute
+        dnl USE_LIBPCRE2 can still be modified below, so don't substitute
         dnl it yet.
        GIT_CONF_SUBST([LIBPCREDIR])
     fi)
@@ -296,6 +296,10 @@ AS_HELP_STRING([],           [ARG can be also prefix for libpcre library and hea
 AC_ARG_WITH(libpcre2,
 AS_HELP_STRING([--with-libpcre2],[support Perl-compatible regexes via libpcre2 (default is NO)])
 AS_HELP_STRING([],           [ARG can be also prefix for libpcre library and headers]),
+    if test -n "$USE_LIBPCRE2"; then
+        AC_MSG_ERROR([Only supply one of --with-libpcre or its synonym --with-libpcre2!])
+    fi
+
     if test -n "$USE_LIBPCRE1"; then
         AC_MSG_ERROR([Only supply one of --with-libpcre1 or --with-libpcre2!])
     fi
@@ -549,8 +553,8 @@ if test -n "$USE_LIBPCRE1"; then
 GIT_STASH_FLAGS($LIBPCREDIR)
 
 AC_CHECK_LIB([pcre], [pcre_version],
-[USE_LIBPCRE=YesPlease],
-[USE_LIBPCRE=])
+[USE_LIBPCRE1=YesPlease],
+[USE_LIBPCRE1=])
 
 GIT_UNSTASH_FLAGS($LIBPCREDIR)
 
@@ -923,7 +927,7 @@ AC_RUN_IFELSE(
        [AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT],
                [[
                FILE *f = fopen(".", "r");
-               return f)]])],
+               return f != NULL;]])],
        [ac_cv_fread_reads_directories=no],
        [ac_cv_fread_reads_directories=yes])
 ])
index 9847d8208173b965928aa2019c3841232943d0dc..a347f0ac10d9b7ebc9a942a1dd335ecc72b878c0 100644 (file)
--- a/connect.c
+++ b/connect.c
 #include "sha1-array.h"
 #include "transport.h"
 #include "strbuf.h"
+#include "version.h"
 #include "protocol.h"
+#include "alias.h"
 
-static char *server_capabilities;
+static char *server_capabilities_v1;
+static struct argv_array server_capabilities_v2 = ARGV_ARRAY_INIT;
 static const char *parse_feature_value(const char *, const char *, int *);
 
 static int check_ref(const char *name, unsigned int flags)
@@ -46,8 +49,14 @@ int check_ref_type(const struct ref *ref, int flags)
        return check_ref(ref->name, flags);
 }
 
-static void die_initial_contact(int unexpected)
+static NORETURN void die_initial_contact(int unexpected)
 {
+       /*
+        * A hang-up after seeing some response from the other end
+        * means that it is unexpected, as we know the other end is
+        * willing to talk to us.  A hang-up before seeing any
+        * response does not necessarily mean an ACL problem, though.
+        */
        if (unexpected)
                die(_("The remote end hung up upon initial contact"));
        else
@@ -56,6 +65,92 @@ static void die_initial_contact(int unexpected)
                      "and the repository exists."));
 }
 
+/* Checks if the server supports the capability 'c' */
+int server_supports_v2(const char *c, int die_on_error)
+{
+       int i;
+
+       for (i = 0; i < server_capabilities_v2.argc; i++) {
+               const char *out;
+               if (skip_prefix(server_capabilities_v2.argv[i], c, &out) &&
+                   (!*out || *out == '='))
+                       return 1;
+       }
+
+       if (die_on_error)
+               die("server doesn't support '%s'", c);
+
+       return 0;
+}
+
+int server_supports_feature(const char *c, const char *feature,
+                           int die_on_error)
+{
+       int i;
+
+       for (i = 0; i < server_capabilities_v2.argc; i++) {
+               const char *out;
+               if (skip_prefix(server_capabilities_v2.argv[i], c, &out) &&
+                   (!*out || *(out++) == '=')) {
+                       if (parse_feature_request(out, feature))
+                               return 1;
+                       else
+                               break;
+               }
+       }
+
+       if (die_on_error)
+               die("server doesn't support feature '%s'", feature);
+
+       return 0;
+}
+
+static void process_capabilities_v2(struct packet_reader *reader)
+{
+       while (packet_reader_read(reader) == PACKET_READ_NORMAL)
+               argv_array_push(&server_capabilities_v2, reader->line);
+
+       if (reader->status != PACKET_READ_FLUSH)
+               die("expected flush after capabilities");
+}
+
+enum protocol_version discover_version(struct packet_reader *reader)
+{
+       enum protocol_version version = protocol_unknown_version;
+
+       /*
+        * Peek the first line of the server's response to
+        * determine the protocol version the server is speaking.
+        */
+       switch (packet_reader_peek(reader)) {
+       case PACKET_READ_EOF:
+               die_initial_contact(0);
+       case PACKET_READ_FLUSH:
+       case PACKET_READ_DELIM:
+               version = protocol_v0;
+               break;
+       case PACKET_READ_NORMAL:
+               version = determine_protocol_version_client(reader->line);
+               break;
+       }
+
+       switch (version) {
+       case protocol_v2:
+               process_capabilities_v2(reader);
+               break;
+       case protocol_v1:
+               /* Read the peeked version line */
+               packet_reader_read(reader);
+               break;
+       case protocol_v0:
+               break;
+       case protocol_unknown_version:
+               BUG("unknown protocol version");
+       }
+
+       return version;
+}
+
 static void parse_one_symref_info(struct string_list *symref, const char *val, int len)
 {
        char *sym, *target;
@@ -85,7 +180,7 @@ reject:
 static void annotate_refs_with_symref_info(struct ref *ref)
 {
        struct string_list symref = STRING_LIST_INIT_DUP;
-       const char *feature_list = server_capabilities;
+       const char *feature_list = server_capabilities_v1;
 
        while (feature_list) {
                int len;
@@ -109,60 +204,21 @@ static void annotate_refs_with_symref_info(struct ref *ref)
        string_list_clear(&symref, 0);
 }
 
-/*
- * Read one line of a server's ref advertisement into packet_buffer.
- */
-static int read_remote_ref(int in, char **src_buf, size_t *src_len,
-                          int *responded)
-{
-       int len = packet_read(in, src_buf, src_len,
-                             packet_buffer, sizeof(packet_buffer),
-                             PACKET_READ_GENTLE_ON_EOF |
-                             PACKET_READ_CHOMP_NEWLINE);
-       const char *arg;
-       if (len < 0)
-               die_initial_contact(*responded);
-       if (len > 4 && skip_prefix(packet_buffer, "ERR ", &arg))
-               die("remote error: %s", arg);
-
-       *responded = 1;
-
-       return len;
-}
-
-#define EXPECTING_PROTOCOL_VERSION 0
-#define EXPECTING_FIRST_REF 1
-#define EXPECTING_REF 2
-#define EXPECTING_SHALLOW 3
-
-/* Returns 1 if packet_buffer is a protocol version pkt-line, 0 otherwise. */
-static int process_protocol_version(void)
+static void process_capabilities(const char *line, int *len)
 {
-       switch (determine_protocol_version_client(packet_buffer)) {
-       case protocol_v1:
-               return 1;
-       case protocol_v0:
-               return 0;
-       default:
-               die("server is speaking an unknown protocol");
-       }
-}
-
-static void process_capabilities(int *len)
-{
-       int nul_location = strlen(packet_buffer);
+       int nul_location = strlen(line);
        if (nul_location == *len)
                return;
-       server_capabilities = xstrdup(packet_buffer + nul_location + 1);
+       server_capabilities_v1 = xstrdup(line + nul_location + 1);
        *len = nul_location;
 }
 
-static int process_dummy_ref(void)
+static int process_dummy_ref(const char *line)
 {
        struct object_id oid;
        const char *name;
 
-       if (parse_oid_hex(packet_buffer, &oid, &name))
+       if (parse_oid_hex(line, &oid, &name))
                return 0;
        if (*name != ' ')
                return 0;
@@ -171,20 +227,20 @@ static int process_dummy_ref(void)
        return !oidcmp(&null_oid, &oid) && !strcmp(name, "capabilities^{}");
 }
 
-static void check_no_capabilities(int len)
+static void check_no_capabilities(const char *line, int len)
 {
-       if (strlen(packet_buffer) != len)
+       if (strlen(line) != len)
                warning("Ignoring capabilities after first line '%s'",
-                       packet_buffer + strlen(packet_buffer));
+                       line + strlen(line));
 }
 
-static int process_ref(int len, struct ref ***list, unsigned int flags,
-                      struct oid_array *extra_have)
+static int process_ref(const char *line, int len, struct ref ***list,
+                      unsigned int flags, struct oid_array *extra_have)
 {
        struct object_id old_oid;
        const char *name;
 
-       if (parse_oid_hex(packet_buffer, &old_oid, &name))
+       if (parse_oid_hex(line, &old_oid, &name))
                return 0;
        if (*name != ' ')
                return 0;
@@ -200,16 +256,17 @@ static int process_ref(int len, struct ref ***list, unsigned int flags,
                **list = ref;
                *list = &ref->next;
        }
-       check_no_capabilities(len);
+       check_no_capabilities(line, len);
        return 1;
 }
 
-static int process_shallow(int len, struct oid_array *shallow_points)
+static int process_shallow(const char *line, int len,
+                          struct oid_array *shallow_points)
 {
        const char *arg;
        struct object_id old_oid;
 
-       if (!skip_prefix(packet_buffer, "shallow ", &arg))
+       if (!skip_prefix(line, "shallow ", &arg))
                return 0;
 
        if (get_oid_hex(arg, &old_oid))
@@ -217,60 +274,68 @@ static int process_shallow(int len, struct oid_array *shallow_points)
        if (!shallow_points)
                die("repository on the other end cannot be shallow");
        oid_array_append(shallow_points, &old_oid);
-       check_no_capabilities(len);
+       check_no_capabilities(line, len);
        return 1;
 }
 
+enum get_remote_heads_state {
+       EXPECTING_FIRST_REF = 0,
+       EXPECTING_REF,
+       EXPECTING_SHALLOW,
+       EXPECTING_DONE,
+};
+
 /*
  * Read all the refs from the other end
  */
-struct ref **get_remote_heads(int in, char *src_buf, size_t src_len,
+struct ref **get_remote_heads(struct packet_reader *reader,
                              struct ref **list, unsigned int flags,
                              struct oid_array *extra_have,
                              struct oid_array *shallow_points)
 {
        struct ref **orig_list = list;
-
-       /*
-        * A hang-up after seeing some response from the other end
-        * means that it is unexpected, as we know the other end is
-        * willing to talk to us.  A hang-up before seeing any
-        * response does not necessarily mean an ACL problem, though.
-        */
-       int responded = 0;
-       int len;
-       int state = EXPECTING_PROTOCOL_VERSION;
+       int len = 0;
+       enum get_remote_heads_state state = EXPECTING_FIRST_REF;
+       const char *arg;
 
        *list = NULL;
 
-       while ((len = read_remote_ref(in, &src_buf, &src_len, &responded))) {
+       while (state != EXPECTING_DONE) {
+               switch (packet_reader_read(reader)) {
+               case PACKET_READ_EOF:
+                       die_initial_contact(1);
+               case PACKET_READ_NORMAL:
+                       len = reader->pktlen;
+                       if (len > 4 && skip_prefix(reader->line, "ERR ", &arg))
+                               die("remote error: %s", arg);
+                       break;
+               case PACKET_READ_FLUSH:
+                       state = EXPECTING_DONE;
+                       break;
+               case PACKET_READ_DELIM:
+                       die("invalid packet");
+               }
+
                switch (state) {
-               case EXPECTING_PROTOCOL_VERSION:
-                       if (process_protocol_version()) {
-                               state = EXPECTING_FIRST_REF;
-                               break;
-                       }
-                       state = EXPECTING_FIRST_REF;
-                       /* fallthrough */
                case EXPECTING_FIRST_REF:
-                       process_capabilities(&len);
-                       if (process_dummy_ref()) {
+                       process_capabilities(reader->line, &len);
+                       if (process_dummy_ref(reader->line)) {
                                state = EXPECTING_SHALLOW;
                                break;
                        }
                        state = EXPECTING_REF;
                        /* fallthrough */
                case EXPECTING_REF:
-                       if (process_ref(len, &list, flags, extra_have))
+                       if (process_ref(reader->line, len, &list, flags, extra_have))
                                break;
                        state = EXPECTING_SHALLOW;
                        /* fallthrough */
                case EXPECTING_SHALLOW:
-                       if (process_shallow(len, shallow_points))
+                       if (process_shallow(reader->line, len, shallow_points))
                                break;
-                       die("protocol error: unexpected '%s'", packet_buffer);
-               default:
-                       die("unexpected state %d", state);
+                       die("protocol error: unexpected '%s'", reader->line);
+               case EXPECTING_DONE:
+                       break;
                }
        }
 
@@ -279,6 +344,112 @@ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len,
        return list;
 }
 
+/* Returns 1 when a valid ref has been added to `list`, 0 otherwise */
+static int process_ref_v2(const char *line, struct ref ***list)
+{
+       int ret = 1;
+       int i = 0;
+       struct object_id old_oid;
+       struct ref *ref;
+       struct string_list line_sections = STRING_LIST_INIT_DUP;
+       const char *end;
+
+       /*
+        * Ref lines have a number of fields which are space deliminated.  The
+        * first field is the OID of the ref.  The second field is the ref
+        * name.  Subsequent fields (symref-target and peeled) are optional and
+        * don't have a particular order.
+        */
+       if (string_list_split(&line_sections, line, ' ', -1) < 2) {
+               ret = 0;
+               goto out;
+       }
+
+       if (parse_oid_hex(line_sections.items[i++].string, &old_oid, &end) ||
+           *end) {
+               ret = 0;
+               goto out;
+       }
+
+       ref = alloc_ref(line_sections.items[i++].string);
+
+       oidcpy(&ref->old_oid, &old_oid);
+       **list = ref;
+       *list = &ref->next;
+
+       for (; i < line_sections.nr; i++) {
+               const char *arg = line_sections.items[i].string;
+               if (skip_prefix(arg, "symref-target:", &arg))
+                       ref->symref = xstrdup(arg);
+
+               if (skip_prefix(arg, "peeled:", &arg)) {
+                       struct object_id peeled_oid;
+                       char *peeled_name;
+                       struct ref *peeled;
+                       if (parse_oid_hex(arg, &peeled_oid, &end) || *end) {
+                               ret = 0;
+                               goto out;
+                       }
+
+                       peeled_name = xstrfmt("%s^{}", ref->name);
+                       peeled = alloc_ref(peeled_name);
+
+                       oidcpy(&peeled->old_oid, &peeled_oid);
+                       **list = peeled;
+                       *list = &peeled->next;
+
+                       free(peeled_name);
+               }
+       }
+
+out:
+       string_list_clear(&line_sections, 0);
+       return ret;
+}
+
+struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
+                            struct ref **list, int for_push,
+                            const struct argv_array *ref_prefixes,
+                            const struct string_list *server_options)
+{
+       int i;
+       *list = NULL;
+
+       if (server_supports_v2("ls-refs", 1))
+               packet_write_fmt(fd_out, "command=ls-refs\n");
+
+       if (server_supports_v2("agent", 0))
+               packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
+
+       if (server_options && server_options->nr &&
+           server_supports_v2("server-option", 1))
+               for (i = 0; i < server_options->nr; i++)
+                       packet_write_fmt(fd_out, "server-option=%s",
+                                        server_options->items[i].string);
+
+       packet_delim(fd_out);
+       /* When pushing we don't want to request the peeled tags */
+       if (!for_push)
+               packet_write_fmt(fd_out, "peel\n");
+       packet_write_fmt(fd_out, "symrefs\n");
+       for (i = 0; ref_prefixes && i < ref_prefixes->argc; i++) {
+               packet_write_fmt(fd_out, "ref-prefix %s\n",
+                                ref_prefixes->argv[i]);
+       }
+       packet_flush(fd_out);
+
+       /* Process response from server */
+       while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
+               if (!process_ref_v2(reader->line, &list))
+                       die("invalid ls-refs response: %s", reader->line);
+       }
+
+       if (reader->status != PACKET_READ_FLUSH)
+               die("expected flush after ref listing");
+
+       return list;
+}
+
 static const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp)
 {
        int len;
@@ -323,7 +494,7 @@ int parse_feature_request(const char *feature_list, const char *feature)
 
 const char *server_feature_value(const char *feature, int *len)
 {
-       return parse_feature_value(server_capabilities, feature, len);
+       return parse_feature_value(server_capabilities_v1, feature, len);
 }
 
 int server_supports(const char *feature)
@@ -872,6 +1043,7 @@ static enum ssh_variant determine_ssh_variant(const char *ssh_command,
  */
 static struct child_process *git_connect_git(int fd[2], char *hostandport,
                                             const char *path, const char *prog,
+                                            enum protocol_version version,
                                             int flags)
 {
        struct child_process *conn;
@@ -910,10 +1082,10 @@ static struct child_process *git_connect_git(int fd[2], char *hostandport,
                    target_host, 0);
 
        /* If using a new version put that stuff here after a second null byte */
-       if (get_protocol_version_config() > 0) {
+       if (version > 0) {
                strbuf_addch(&request, '\0');
                strbuf_addf(&request, "version=%d%c",
-                           get_protocol_version_config(), '\0');
+                           version, '\0');
        }
 
        packet_write(fd[1], request.buf, request.len);
@@ -929,14 +1101,14 @@ static struct child_process *git_connect_git(int fd[2], char *hostandport,
  */
 static void push_ssh_options(struct argv_array *args, struct argv_array *env,
                             enum ssh_variant variant, const char *port,
-                            int flags)
+                            enum protocol_version version, int flags)
 {
        if (variant == VARIANT_SSH &&
-           get_protocol_version_config() > 0) {
+           version > 0) {
                argv_array_push(args, "-o");
                argv_array_push(args, "SendEnv=" GIT_PROTOCOL_ENVIRONMENT);
                argv_array_pushf(env, GIT_PROTOCOL_ENVIRONMENT "=version=%d",
-                                get_protocol_version_config());
+                                version);
        }
 
        if (flags & CONNECT_IPV4) {
@@ -989,7 +1161,8 @@ static void push_ssh_options(struct argv_array *args, struct argv_array *env,
 
 /* Prepare a child_process for use by Git's SSH-tunneled transport. */
 static void fill_ssh_args(struct child_process *conn, const char *ssh_host,
-                         const char *port, int flags)
+                         const char *port, enum protocol_version version,
+                         int flags)
 {
        const char *ssh;
        enum ssh_variant variant;
@@ -1023,14 +1196,14 @@ static void fill_ssh_args(struct child_process *conn, const char *ssh_host,
                argv_array_push(&detect.args, ssh);
                argv_array_push(&detect.args, "-G");
                push_ssh_options(&detect.args, &detect.env_array,
-                                VARIANT_SSH, port, flags);
+                                VARIANT_SSH, port, version, flags);
                argv_array_push(&detect.args, ssh_host);
 
                variant = run_command(&detect) ? VARIANT_SIMPLE : VARIANT_SSH;
        }
 
        argv_array_push(&conn->args, ssh);
-       push_ssh_options(&conn->args, &conn->env_array, variant, port, flags);
+       push_ssh_options(&conn->args, &conn->env_array, variant, port, version, flags);
        argv_array_push(&conn->args, ssh_host);
 }
 
@@ -1051,6 +1224,15 @@ struct child_process *git_connect(int fd[2], const char *url,
        char *hostandport, *path;
        struct child_process *conn;
        enum protocol protocol;
+       enum protocol_version version = get_protocol_version_config();
+
+       /*
+        * NEEDSWORK: If we are trying to use protocol v2 and we are planning
+        * to perform a push, then fallback to v0 since the client doesn't know
+        * how to push yet using v2.
+        */
+       if (version == protocol_v2 && !strcmp("git-receive-pack", prog))
+               version = protocol_v0;
 
        /* Without this we cannot rely on waitpid() to tell
         * what happened to our children.
@@ -1065,7 +1247,7 @@ struct child_process *git_connect(int fd[2], const char *url,
                printf("Diag: path=%s\n", path ? path : "NULL");
                conn = NULL;
        } else if (protocol == PROTO_GIT) {
-               conn = git_connect_git(fd, hostandport, path, prog, flags);
+               conn = git_connect_git(fd, hostandport, path, prog, version, flags);
        } else {
                struct strbuf cmd = STRBUF_INIT;
                const char *const *var;
@@ -1108,12 +1290,12 @@ struct child_process *git_connect(int fd[2], const char *url,
                                strbuf_release(&cmd);
                                return NULL;
                        }
-                       fill_ssh_args(conn, ssh_host, port, flags);
+                       fill_ssh_args(conn, ssh_host, port, version, flags);
                } else {
                        transport_check_allowed("file");
-                       if (get_protocol_version_config() > 0) {
+                       if (version > 0) {
                                argv_array_pushf(&conn->env_array, GIT_PROTOCOL_ENVIRONMENT "=version=%d",
-                                                get_protocol_version_config());
+                                                version);
                        }
                }
                argv_array_push(&conn->args, cmd.buf);
index 01f14cdf3fa4e6b6c8cd3b4c9ec3c3d55e7fc04f..0e69c6709c9fdb83b4888443f490d79ef504c8a3 100644 (file)
--- a/connect.h
+++ b/connect.h
@@ -13,4 +13,11 @@ extern int parse_feature_request(const char *features, const char *feature);
 extern const char *server_feature_value(const char *feature, int *len_ret);
 extern int url_is_local_not_ssh(const char *url);
 
+struct packet_reader;
+extern enum protocol_version discover_version(struct packet_reader *reader);
+
+extern int server_supports_v2(const char *c, int die_on_error);
+extern int server_supports_feature(const char *c, const char *feature,
+                                  int die_on_error);
+
 #endif
diff --git a/contrib/coccinelle/commit.cocci b/contrib/coccinelle/commit.cocci
new file mode 100644 (file)
index 0000000..a7e9215
--- /dev/null
@@ -0,0 +1,28 @@
+@@
+expression c;
+@@
+- &c->maybe_tree->object.oid
++ get_commit_tree_oid(c)
+
+@@
+expression c;
+@@
+- c->maybe_tree->object.oid.hash
++ get_commit_tree_oid(c)->hash
+
+// These excluded functions must access c->maybe_tree direcly.
+@@
+identifier f !~ "^(get_commit_tree|get_commit_tree_in_graph|load_tree_for_commit)$";
+expression c;
+@@
+  f(...) {...
+- c->maybe_tree
++ get_commit_tree(c)
+  ...}
+
+@@
+expression c;
+expression s;
+@@
+- get_commit_tree(c) = s
++ c->maybe_tree = s
index b09c8a23626b431a0cb97f6f7f930cccce25bf07..dd3e925843acf53c439e504101d46d8606ea5d69 100644 (file)
@@ -29,6 +29,8 @@
 # tell the completion to use commit completion.  This also works with aliases
 # of form "!sh -c '...'".  For example, "!sh -c ': git commit ; ... '".
 #
+# Compatible with bash 3.2.57.
+#
 # You can set the following environment variables to influence the behavior of
 # the completion routines:
 #
@@ -92,6 +94,70 @@ __git ()
                ${__git_dir:+--git-dir="$__git_dir"} "$@" 2>/dev/null
 }
 
+# Removes backslash escaping, single quotes and double quotes from a word,
+# stores the result in the variable $dequoted_word.
+# 1: The word to dequote.
+__git_dequote ()
+{
+       local rest="$1" len ch
+
+       dequoted_word=""
+
+       while test -n "$rest"; do
+               len=${#dequoted_word}
+               dequoted_word="$dequoted_word${rest%%[\\\'\"]*}"
+               rest="${rest:$((${#dequoted_word}-$len))}"
+
+               case "${rest:0:1}" in
+               \\)
+                       ch="${rest:1:1}"
+                       case "$ch" in
+                       $'\n')
+                               ;;
+                       *)
+                               dequoted_word="$dequoted_word$ch"
+                               ;;
+                       esac
+                       rest="${rest:2}"
+                       ;;
+               \')
+                       rest="${rest:1}"
+                       len=${#dequoted_word}
+                       dequoted_word="$dequoted_word${rest%%\'*}"
+                       rest="${rest:$((${#dequoted_word}-$len+1))}"
+                       ;;
+               \")
+                       rest="${rest:1}"
+                       while test -n "$rest" ; do
+                               len=${#dequoted_word}
+                               dequoted_word="$dequoted_word${rest%%[\\\"]*}"
+                               rest="${rest:$((${#dequoted_word}-$len))}"
+                               case "${rest:0:1}" in
+                               \\)
+                                       ch="${rest:1:1}"
+                                       case "$ch" in
+                                       \"|\\|\$|\`)
+                                               dequoted_word="$dequoted_word$ch"
+                                               ;;
+                                       $'\n')
+                                               ;;
+                                       *)
+                                               dequoted_word="$dequoted_word\\$ch"
+                                               ;;
+                                       esac
+                                       rest="${rest:2}"
+                                       ;;
+                               \")
+                                       rest="${rest:1}"
+                                       break
+                                       ;;
+                               esac
+                       done
+                       ;;
+               esac
+       done
+}
+
 # The following function is based on code from:
 #
 #   bash_completion - programmable completion functions for bash 3.2+
@@ -282,7 +348,11 @@ __gitcomp ()
 
 # Clear the variables caching builtins' options when (re-)sourcing
 # the completion script.
-unset $(set |sed -ne 's/^\(__gitcomp_builtin_[a-zA-Z0-9_][a-zA-Z0-9_]*\)=.*/\1/p') 2>/dev/null
+if [[ -n ${ZSH_VERSION-} ]]; then
+       unset $(set |sed -ne 's/^\(__gitcomp_builtin_[a-zA-Z0-9_][a-zA-Z0-9_]*\)=.*/\1/p') 2>/dev/null
+else
+       unset $(compgen -v __gitcomp_builtin_)
+fi
 
 # This function is equivalent to
 #
@@ -340,6 +410,24 @@ __gitcomp_nl ()
        __gitcomp_nl_append "$@"
 }
 
+# Fills the COMPREPLY array with prefiltered paths without any additional
+# processing.
+# Callers must take care of providing only paths that match the current path
+# to be completed and adding any prefix path components, if necessary.
+# 1: List of newline-separated matching paths, complete with all prefix
+#    path componens.
+__gitcomp_file_direct ()
+{
+       local IFS=$'\n'
+
+       COMPREPLY=($1)
+
+       # use a hack to enable file mode in bash < 4
+       compopt -o filenames +o nospace 2>/dev/null ||
+       compgen -f /non-existing-dir/ >/dev/null ||
+       true
+}
+
 # Generates completion reply with compgen from newline-separated possible
 # completion filenames.
 # It accepts 1 to 3 arguments:
@@ -359,7 +447,8 @@ __gitcomp_file ()
 
        # use a hack to enable file mode in bash < 4
        compopt -o filenames +o nospace 2>/dev/null ||
-       compgen -f /non-existing-dir/ > /dev/null
+       compgen -f /non-existing-dir/ >/dev/null ||
+       true
 }
 
 # Execute 'git ls-files', unless the --committable option is specified, in
@@ -369,10 +458,12 @@ __gitcomp_file ()
 __git_ls_files_helper ()
 {
        if [ "$2" == "--committable" ]; then
-               __git -C "$1" diff-index --name-only --relative HEAD
+               __git -C "$1" -c core.quotePath=false diff-index \
+                       --name-only --relative HEAD -- "${3//\\/\\\\}*"
        else
                # NOTE: $2 is not quoted in order to support multiple options
-               __git -C "$1" ls-files --exclude-standard $2
+               __git -C "$1" -c core.quotePath=false ls-files \
+                       --exclude-standard $2 -- "${3//\\/\\\\}*"
        fi
 }
 
@@ -383,17 +474,103 @@ __git_ls_files_helper ()
 #    If provided, only files within the specified directory are listed.
 #    Sub directories are never recursed.  Path must have a trailing
 #    slash.
+# 3: List only paths matching this path component (optional).
 __git_index_files ()
 {
-       local root="${2-.}" file
+       local root="$2" match="$3"
 
-       __git_ls_files_helper "$root" "$1" |
-       while read -r file; do
-               case "$file" in
-               ?*/*) echo "${file%%/*}" ;;
-               *) echo "$file" ;;
-               esac
-       done | sort | uniq
+       __git_ls_files_helper "$root" "$1" "$match" |
+       awk -F / -v pfx="${2//\\/\\\\}" '{
+               paths[$1] = 1
+       }
+       END {
+               for (p in paths) {
+                       if (substr(p, 1, 1) != "\"") {
+                               # No special characters, easy!
+                               print pfx p
+                               continue
+                       }
+
+                       # The path is quoted.
+                       p = dequote(p)
+                       if (p == "")
+                               continue
+
+                       # Even when a directory name itself does not contain
+                       # any special characters, it will still be quoted if
+                       # any of its (stripped) trailing path components do.
+                       # Because of this we may have seen the same direcory
+                       # both quoted and unquoted.
+                       if (p in paths)
+                               # We have seen the same directory unquoted,
+                               # skip it.
+                               continue
+                       else
+                               print pfx p
+               }
+       }
+       function dequote(p,    bs_idx, out, esc, esc_idx, dec) {
+               # Skip opening double quote.
+               p = substr(p, 2)
+
+               # Interpret backslash escape sequences.
+               while ((bs_idx = index(p, "\\")) != 0) {
+                       out = out substr(p, 1, bs_idx - 1)
+                       esc = substr(p, bs_idx + 1, 1)
+                       p = substr(p, bs_idx + 2)
+
+                       if ((esc_idx = index("abtvfr\"\\", esc)) != 0) {
+                               # C-style one-character escape sequence.
+                               out = out substr("\a\b\t\v\f\r\"\\",
+                                                esc_idx, 1)
+                       } else if (esc == "n") {
+                               # Uh-oh, a newline character.
+                               # We cant reliably put a pathname
+                               # containing a newline into COMPREPLY,
+                               # and the newline would create a mess.
+                               # Skip this path.
+                               return ""
+                       } else {
+                               # Must be a \nnn octal value, then.
+                               dec = esc             * 64 + \
+                                     substr(p, 1, 1) * 8  + \
+                                     substr(p, 2, 1)
+                               out = out sprintf("%c", dec)
+                               p = substr(p, 3)
+                       }
+               }
+               # Drop closing double quote, if there is one.
+               # (There isnt any if this is a directory, as it was
+               # already stripped with the trailing path components.)
+               if (substr(p, length(p), 1) == "\"")
+                       out = out substr(p, 1, length(p) - 1)
+               else
+                       out = out p
+
+               return out
+       }'
+}
+
+# __git_complete_index_file requires 1 argument:
+# 1: the options to pass to ls-file
+#
+# The exception is --committable, which finds the files appropriate commit.
+__git_complete_index_file ()
+{
+       local dequoted_word pfx="" cur_
+
+       __git_dequote "$cur"
+
+       case "$dequoted_word" in
+       ?*/*)
+               pfx="${dequoted_word%/*}/"
+               cur_="${dequoted_word##*/}"
+               ;;
+       *)
+               cur_="$dequoted_word"
+       esac
+
+       __gitcomp_file_direct "$(__git_index_files "$1" "$pfx" "$cur_")"
 }
 
 # Lists branches from the local repository.
@@ -712,26 +889,6 @@ __git_complete_revlist_file ()
        esac
 }
 
-
-# __git_complete_index_file requires 1 argument:
-# 1: the options to pass to ls-file
-#
-# The exception is --committable, which finds the files appropriate commit.
-__git_complete_index_file ()
-{
-       local pfx="" cur_="$cur"
-
-       case "$cur_" in
-       ?*/*)
-               pfx="${cur_%/*}"
-               cur_="${cur_##*/}"
-               pfx="${pfx}/"
-               ;;
-       esac
-
-       __gitcomp_file "$(__git_index_files "$1" ${pfx:+"$pfx"})" "$pfx" "$cur_"
-}
-
 __git_complete_file ()
 {
        __git_complete_revlist_file
@@ -832,126 +989,11 @@ __git_complete_strategy ()
        return 1
 }
 
-__git_commands () {
-       if test -n "${GIT_TESTING_COMMAND_COMPLETION:-}"
-       then
-               printf "%s" "${GIT_TESTING_COMMAND_COMPLETION}"
-       else
-               git help -a|egrep '^  [a-zA-Z0-9]'
-       fi
-}
-
-__git_list_all_commands ()
-{
-       local i IFS=" "$'\n'
-       for i in $(__git_commands)
-       do
-               case $i in
-               *--*)             : helper pattern;;
-               *) echo $i;;
-               esac
-       done
-}
-
 __git_all_commands=
 __git_compute_all_commands ()
 {
        test -n "$__git_all_commands" ||
-       __git_all_commands=$(__git_list_all_commands)
-}
-
-__git_list_porcelain_commands ()
-{
-       local i IFS=" "$'\n'
-       __git_compute_all_commands
-       for i in $__git_all_commands
-       do
-               case $i in
-               *--*)             : helper pattern;;
-               applymbox)        : ask gittus;;
-               applypatch)       : ask gittus;;
-               archimport)       : import;;
-               cat-file)         : plumbing;;
-               check-attr)       : plumbing;;
-               check-ignore)     : plumbing;;
-               check-mailmap)    : plumbing;;
-               check-ref-format) : plumbing;;
-               checkout-index)   : plumbing;;
-               column)           : internal helper;;
-               commit-tree)      : plumbing;;
-               count-objects)    : infrequent;;
-               credential)       : credentials;;
-               credential-*)     : credentials helper;;
-               cvsexportcommit)  : export;;
-               cvsimport)        : import;;
-               cvsserver)        : daemon;;
-               daemon)           : daemon;;
-               diff-files)       : plumbing;;
-               diff-index)       : plumbing;;
-               diff-tree)        : plumbing;;
-               fast-import)      : import;;
-               fast-export)      : export;;
-               fsck-objects)     : plumbing;;
-               fetch-pack)       : plumbing;;
-               fmt-merge-msg)    : plumbing;;
-               for-each-ref)     : plumbing;;
-               hash-object)      : plumbing;;
-               http-*)           : transport;;
-               index-pack)       : plumbing;;
-               init-db)          : deprecated;;
-               local-fetch)      : plumbing;;
-               ls-files)         : plumbing;;
-               ls-remote)        : plumbing;;
-               ls-tree)          : plumbing;;
-               mailinfo)         : plumbing;;
-               mailsplit)        : plumbing;;
-               merge-*)          : plumbing;;
-               mktree)           : plumbing;;
-               mktag)            : plumbing;;
-               pack-objects)     : plumbing;;
-               pack-redundant)   : plumbing;;
-               pack-refs)        : plumbing;;
-               parse-remote)     : plumbing;;
-               patch-id)         : plumbing;;
-               prune)            : plumbing;;
-               prune-packed)     : plumbing;;
-               quiltimport)      : import;;
-               read-tree)        : plumbing;;
-               receive-pack)     : plumbing;;
-               remote-*)         : transport;;
-               rerere)           : plumbing;;
-               rev-list)         : plumbing;;
-               rev-parse)        : plumbing;;
-               runstatus)        : plumbing;;
-               sh-setup)         : internal;;
-               shell)            : daemon;;
-               show-ref)         : plumbing;;
-               send-pack)        : plumbing;;
-               show-index)       : plumbing;;
-               ssh-*)            : transport;;
-               stripspace)       : plumbing;;
-               symbolic-ref)     : plumbing;;
-               unpack-file)      : plumbing;;
-               unpack-objects)   : plumbing;;
-               update-index)     : plumbing;;
-               update-ref)       : plumbing;;
-               update-server-info) : daemon;;
-               upload-archive)   : plumbing;;
-               upload-pack)      : plumbing;;
-               write-tree)       : plumbing;;
-               var)              : infrequent;;
-               verify-pack)      : infrequent;;
-               verify-tag)       : plumbing;;
-               *) echo $i;;
-               esac
-       done
-}
-
-__git_porcelain_commands=
-__git_compute_porcelain_commands ()
-{
-       test -n "$__git_porcelain_commands" ||
-       __git_porcelain_commands=$(__git_list_porcelain_commands)
+       __git_all_commands=$(git --list-cmds=main,others,alias,nohelpers)
 }
 
 # Lists all set config variables starting with the given section prefix,
@@ -969,11 +1011,6 @@ __git_pretty_aliases ()
        __git_get_config_variables "pretty"
 }
 
-__git_aliases ()
-{
-       __git_get_config_variables "alias"
-}
-
 # __git_aliased_command requires 1 argument
 __git_aliased_command ()
 {
@@ -1284,6 +1321,12 @@ _git_checkout ()
 
 _git_cherry ()
 {
+       case "$cur" in
+       --*)
+               __gitcomp_builtin cherry
+               return
+       esac
+
        __git_complete_refs
 }
 
@@ -1503,16 +1546,6 @@ _git_fsck ()
        esac
 }
 
-_git_gc ()
-{
-       case "$cur" in
-       --*)
-               __gitcomp_builtin gc
-               return
-               ;;
-       esac
-}
-
 _git_gitk ()
 {
        _gitk
@@ -1585,13 +1618,12 @@ _git_help ()
                return
                ;;
        esac
-       __git_compute_all_commands
-       __gitcomp "$__git_all_commands $(__git_aliases)
-               attributes cli core-tutorial cvs-migration
-               diffcore everyday gitk glossary hooks ignore modules
-               namespaces repository-layout revisions tutorial tutorial-2
-               workflows
-               "
+       if test -n "$GIT_TESTING_ALL_COMMAND_LIST"
+       then
+               __gitcomp "$GIT_TESTING_ALL_COMMAND_LIST $(git --list-cmds=alias,list-guide) gitk"
+       else
+               __gitcomp "$(git --list-cmds=main,nohelpers,alias,list-guide) gitk"
+       fi
 }
 
 _git_init ()
@@ -1637,6 +1669,13 @@ _git_ls_remote ()
 
 _git_ls_tree ()
 {
+       case "$cur" in
+       --*)
+               __gitcomp_builtin ls-tree
+               return
+               ;;
+       esac
+
        __git_complete_file
 }
 
@@ -1812,11 +1851,6 @@ _git_mv ()
        fi
 }
 
-_git_name_rev ()
-{
-       __gitcomp_builtin name-rev
-}
-
 _git_notes ()
 {
        local subcommands='add append copy edit get-ref list merge prune remove show'
@@ -1949,7 +1983,7 @@ _git_rebase ()
        --*)
                __gitcomp "
                        --onto --merge --strategy --interactive
-                       --preserve-merges --stat --no-stat
+                       --rebase-merges --preserve-merges --stat --no-stat
                        --committer-date-is-author-date --ignore-date
                        --ignore-whitespace --whitespace=
                        --autosquash --no-autosquash
@@ -2120,7 +2154,7 @@ _git_config ()
                return
                ;;
        branch.*.rebase)
-               __gitcomp "false true preserve interactive"
+               __gitcomp "false true merges preserve interactive"
                return
                ;;
        remote.pushdefault)
@@ -2177,7 +2211,7 @@ _git_config ()
                __gitcomp "$__git_log_date_formats"
                return
                ;;
-       sendemail.aliasesfiletype)
+       sendemail.aliasfiletype)
                __gitcomp "mutt mailrc pine elm gnus"
                return
                ;;
@@ -2350,6 +2384,7 @@ _git_config ()
                core.bigFileThreshold
                core.checkStat
                core.commentChar
+               core.commitGraph
                core.compression
                core.createObject
                core.deltaBaseCacheLimit
@@ -2774,13 +2809,21 @@ _git_show_branch ()
 _git_stash ()
 {
        local save_opts='--all --keep-index --no-keep-index --quiet --patch --include-untracked'
-       local subcommands='push save list show apply clear drop pop create branch'
-       local subcommand="$(__git_find_on_cmdline "$subcommands")"
+       local subcommands='push list show apply clear drop pop create branch'
+       local subcommand="$(__git_find_on_cmdline "$subcommands save")"
+       if [ -n "$(__git_find_on_cmdline "-p")" ]; then
+               subcommand="push"
+       fi
        if [ -z "$subcommand" ]; then
                case "$cur" in
                --*)
                        __gitcomp "$save_opts"
                        ;;
+               sa*)
+                       if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
+                               __gitcomp "save"
+                       fi
+                       ;;
                *)
                        if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then
                                __gitcomp "$subcommands"
@@ -3036,6 +3079,52 @@ _git_worktree ()
        fi
 }
 
+__git_complete_common () {
+       local command="$1"
+
+       case "$cur" in
+       --*)
+               __gitcomp_builtin "$command"
+               ;;
+       esac
+}
+
+__git_cmds_with_parseopt_helper=
+__git_support_parseopt_helper () {
+       test -n "$__git_cmds_with_parseopt_helper" ||
+               __git_cmds_with_parseopt_helper="$(__git --list-cmds=parseopt)"
+
+       case " $__git_cmds_with_parseopt_helper " in
+       *" $1 "*)
+               return 0
+               ;;
+       *)
+               return 1
+               ;;
+       esac
+}
+
+__git_complete_command () {
+       local command="$1"
+       local completion_func="_git_${command//-/_}"
+       if ! declare -f $completion_func >/dev/null 2>/dev/null &&
+               declare -f _completion_loader >/dev/null 2>/dev/null
+       then
+               _completion_loader "git-$command"
+       fi
+       if declare -f $completion_func >/dev/null 2>/dev/null
+       then
+               $completion_func
+               return 0
+       elif __git_support_parseopt_helper "$command"
+       then
+               __git_complete_common "$command"
+               return 0
+       else
+               return 1
+       fi
+}
+
 __git_main ()
 {
        local i c=1 command __git_dir __git_repo_path
@@ -3089,20 +3178,24 @@ __git_main ()
                        --help
                        "
                        ;;
-               *)     __git_compute_porcelain_commands
-                      __gitcomp "$__git_porcelain_commands $(__git_aliases)" ;;
+               *)
+                       if test -n "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
+                       then
+                               __gitcomp "$GIT_TESTING_PORCELAIN_COMMAND_LIST"
+                       else
+                               __gitcomp "$(git --list-cmds=list-mainporcelain,others,nohelpers,alias,list-complete,config)"
+                       fi
+                       ;;
                esac
                return
        fi
 
-       local completion_func="_git_${command//-/_}"
-       declare -f $completion_func >/dev/null 2>/dev/null && $completion_func && return
+       __git_complete_command "$command" && return
 
        local expansion=$(__git_aliased_command "$command")
        if [ -n "$expansion" ]; then
                words[1]=$expansion
-               completion_func="_git_${expansion//-/_}"
-               declare -f $completion_func >/dev/null 2>/dev/null && $completion_func
+               __git_complete_command "$expansion"
        fi
 }
 
@@ -3130,7 +3223,10 @@ __gitk_main ()
        __git_complete_revlist
 }
 
-if [[ -n ${ZSH_VERSION-} ]]; then
+if [[ -n ${ZSH_VERSION-} ]] &&
+   # Don't define these functions when sourced from 'git-completion.zsh',
+   # it has its own implementations.
+   [[ -z ${GIT_SOURCING_ZSH_COMPLETION-} ]]; then
        echo "WARNING: this script is deprecated, please see git-completion.zsh" 1>&2
 
        autoload -U +X compinit && compinit
@@ -3179,6 +3275,15 @@ if [[ -n ${ZSH_VERSION-} ]]; then
                compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
        }
 
+       __gitcomp_file_direct ()
+       {
+               emulate -L zsh
+
+               local IFS=$'\n'
+               compset -P '*[=:]'
+               compadd -Q -f -- ${=1} && _ret=0
+       }
+
        __gitcomp_file ()
        {
                emulate -L zsh
index c3521fbfc44fd8db18244bc10d346ee39b1c3c90..049d6b80f650717f20e68568251c21098f598d80 100644 (file)
@@ -39,7 +39,7 @@ if [ -z "$script" ]; then
                test -f $e && script="$e" && break
        done
 fi
-ZSH_VERSION='' . "$script"
+GIT_SOURCING_ZSH_COMPLETION=y . "$script"
 
 __gitcomp ()
 {
@@ -93,6 +93,15 @@ __gitcomp_nl_append ()
        compadd -Q -S "${4- }" -p "${2-}" -- ${=1} && _ret=0
 }
 
+__gitcomp_file_direct ()
+{
+       emulate -L zsh
+
+       local IFS=$'\n'
+       compset -P '*[=:]'
+       compadd -Q -f -- ${=1} && _ret=0
+}
+
 __gitcomp_file ()
 {
        emulate -L zsh
diff --git a/contrib/convert-grafts-to-replace-refs.sh b/contrib/convert-grafts-to-replace-refs.sh
deleted file mode 100755 (executable)
index 0cbc917..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-# You should execute this script in the repository where you
-# want to convert grafts to replace refs.
-
-GRAFTS_FILE="${GIT_DIR:-.git}/info/grafts"
-
-. $(git --exec-path)/git-sh-setup
-
-test -f "$GRAFTS_FILE" || die "Could not find graft file: '$GRAFTS_FILE'"
-
-grep '^[^# ]' "$GRAFTS_FILE" |
-while read definition
-do
-       if test -n "$definition"
-       then
-               echo "Converting: $definition"
-               git replace --graft $definition ||
-                       die "Conversion failed for: $definition"
-       fi
-done
-
-mv "$GRAFTS_FILE" "$GRAFTS_FILE.bak" ||
-       die "Could not rename '$GRAFTS_FILE' to '$GRAFTS_FILE.bak'"
-
-echo "Success!"
-echo "All the grafts in '$GRAFTS_FILE' have been converted to replace refs!"
-echo "The grafts file '$GRAFTS_FILE' has been renamed: '$GRAFTS_FILE.bak'"
index 51b76138a5b14e05f530cd9ec0bb0b2fedff7493..0ffa40719126fe285722cfa8fc7b461d0584cd3a 100644 (file)
@@ -1,5 +1,5 @@
 test:
-       ./test.pl
+       ./t-git-credential-netrc.sh
 
 testverbose:
-       ./test.pl -d -v
+       ./t-git-credential-netrc.sh -d -v
index 1571a7b2693e50ac93828a76a01366da1e8a6983..ebfc123ec641ddfa1bb2aaa83dab268c19083b2a 100755 (executable)
@@ -5,8 +5,9 @@ use warnings;
 
 use Getopt::Long;
 use File::Basename;
+use Git;
 
-my $VERSION = "0.1";
+my $VERSION = "0.2";
 
 my %options = (
               help => 0,
@@ -54,6 +55,7 @@ GetOptions(\%options,
            "insecure|k",
            "verbose|v",
            "file|f=s@",
+           'gpg|g:s',
           );
 
 if ($options{help}) {
@@ -62,27 +64,31 @@ if ($options{help}) {
 
        print <<EOHIPPUS;
 
-$0 [-f AUTHFILE1] [-f AUTHFILEN] [-d] [-v] [-k] get
+$0 [(-f <authfile>)...] [-g <program>] [-d] [-v] [-k] get
 
 Version $VERSION by tzz\@lifelogs.com.  License: BSD.
 
 Options:
 
-  -f|--file AUTHFILE : specify netrc-style files.  Files with the .gpg extension
-                       will be decrypted by GPG before parsing.  Multiple -f
-                       arguments are OK.  They are processed in order, and the
-                       first matching entry found is returned via the credential
-                       helper protocol (see below).
+  -f|--file <authfile>: specify netrc-style files.  Files with the .gpg
+                        extension will be decrypted by GPG before parsing.
+                        Multiple -f arguments are OK.  They are processed in
+                        order, and the first matching entry found is returned
+                        via the credential helper protocol (see below).
 
-                       When no -f option is given, .authinfo.gpg, .netrc.gpg,
-                      .authinfo, and .netrc files in your home directory are used
-                      in this order.
+                        When no -f option is given, .authinfo.gpg, .netrc.gpg,
+                        .authinfo, and .netrc files in your home directory are
+                        used in this order.
 
-  -k|--insecure      : ignore bad file ownership or permissions
+  -g|--gpg <program>  : specify the program for GPG. By default, this is the
+                        value of gpg.program in the git repository or global
+                        option or gpg.
 
-  -d|--debug         : turn on debugging (developer info)
+  -k|--insecure       : ignore bad file ownership or permissions
 
-  -v|--verbose       : be more verbose (show files and information found)
+  -d|--debug          : turn on debugging (developer info)
+
+  -v|--verbose        : be more verbose (show files and information found)
 
 To enable this credential helper:
 
@@ -99,8 +105,9 @@ in the path.)
 
   git config credential.helper '$shortname -f AUTHFILE -v'
 
-Only "get" mode is supported by this credential helper.  It opens every AUTHFILE
-and looks for the first entry that matches the requested search criteria:
+Only "get" mode is supported by this credential helper.  It opens every
+<authfile> and looks for the first entry that matches the requested search
+criteria:
 
  'port|protocol':
    The protocol that will be used (e.g., https). (protocol=X)
@@ -120,7 +127,7 @@ host=github.com
 protocol=https
 username=tzz
 
-this credential helper will look for the first entry in every AUTHFILE that
+this credential helper will look for the first entry in every <authfile> that
 matches
 
 machine github.com port https login tzz
@@ -137,8 +144,8 @@ Then, the helper will print out whatever tokens it got from the entry, including
 back to "protocol".  Any redundant entry tokens (part of the original query) are
 skipped.
 
-Again, note that only the first matching entry from all the AUTHFILEs, processed
-in the sequence given on the command line, is used.
+Again, note that only the first matching entry from all the <authfile>s,
+processed in the sequence given on the command line, is used.
 
 Netrc/authinfo tokens can be quoted as 'STRING' or "STRING".
 
@@ -152,7 +159,7 @@ EOHIPPUS
 my $mode = shift @ARGV;
 
 # Credentials must get a parameter, so die if it's missing.
-die "Syntax: $0 [-f AUTHFILE1] [-f AUTHFILEN] [-d] get" unless defined $mode;
+die "Syntax: $0 [(-f <authfile>)...] [-d] get" unless defined $mode;
 
 # Only support 'get' mode; with any other unsupported ones we just exit.
 exit 0 unless $mode eq 'get';
@@ -172,6 +179,8 @@ unless (scalar @$files) {
        $files = $options{file} = [ map { glob $_ } @candidates ];
 }
 
+load_config(\%options);
+
 my $query = read_credential_data_from_stdin();
 
 FILE:
@@ -233,7 +242,7 @@ sub load_netrc {
 
        my $io;
        if ($gpgmode) {
-               my @cmd = (qw(gpg --decrypt), $file);
+               my @cmd = ($options{'gpg'}, qw(--decrypt), $file);
                log_verbose("Using GPG to open $file: [@cmd]");
                open $io, "-|", @cmd;
        } else {
@@ -410,6 +419,14 @@ sub print_credential_data {
                printf "%s=%s\n", $git_token, $entry->{$git_token};
        }
 }
+sub load_config {
+       # load settings from git config
+       my $options = shift;
+       # set from command argument, gpg.program option, or default to gpg
+       $options->{'gpg'} //= Git->repository()->config('gpg.program')
+                         // 'gpg';
+       log_verbose("using $options{'gpg'} for GPG operations");
+}
 sub log_verbose {
        return unless $options{verbose};
        printf STDERR @_;
diff --git a/contrib/credential/netrc/t-git-credential-netrc.sh b/contrib/credential/netrc/t-git-credential-netrc.sh
new file mode 100755 (executable)
index 0000000..58191a6
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/sh
+(
+       cd ../../../t
+       test_description='git-credential-netrc'
+       . ./test-lib.sh
+
+       if ! test_have_prereq PERL; then
+               skip_all='skipping perl interface tests, perl not available'
+               test_done
+       fi
+
+       perl -MTest::More -e 0 2>/dev/null || {
+               skip_all="Perl Test::More unavailable, skipping test"
+               test_done
+       }
+
+       # set up test repository
+
+       test_expect_success \
+    'set up test repository' \
+    'git config --add gpg.program test.git-config-gpg'
+
+       # The external test will outputs its own plan
+       test_external_has_tap=1
+
+       test_external \
+    'git-credential-netrc' \
+    perl "$TEST_DIRECTORY"/../contrib/credential/netrc/test.pl
+
+       test_done
+)
diff --git a/contrib/credential/netrc/test.command-option-gpg b/contrib/credential/netrc/test.command-option-gpg
new file mode 100755 (executable)
index 0000000..d8f1285
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo machine command-option-gpg login username password password
diff --git a/contrib/credential/netrc/test.git-config-gpg b/contrib/credential/netrc/test.git-config-gpg
new file mode 100755 (executable)
index 0000000..65cf594
--- /dev/null
@@ -0,0 +1,2 @@
+#!/bin/sh
+echo machine git-config-gpg login username password password
diff --git a/contrib/credential/netrc/test.netrc.gpg b/contrib/credential/netrc/test.netrc.gpg
new file mode 100644 (file)
index 0000000..e69de29
index 169b6463c3011fbef721d926396fa20b5d1616f7..1e1001030e7631dd49cbfeb002b429158019f191 100755 (executable)
 #!/usr/bin/perl
+use lib (split(/:/, $ENV{GITPERLLIB}));
 
 use warnings;
 use strict;
-use Test;
+use Test::More qw(no_plan);
+use File::Basename;
+use File::Spec::Functions qw(:DEFAULT rel2abs);
 use IPC::Open2;
 
-BEGIN { plan tests => 15 }
+BEGIN {
+       # t-git-credential-netrc.sh kicks off our testing, so we have to go
+       # from there.
+       Test::More->builder->current_test(1);
+       Test::More->builder->no_ending(1);
+}
 
 my @global_credential_args = @ARGV;
-my $netrc = './test.netrc';
-print "# Testing insecure file, nothing should be found\n";
+my $scriptDir = dirname rel2abs $0;
+my ($netrc, $netrcGpg, $gcNetrc) = map { catfile $scriptDir, $_; }
+                                       qw(test.netrc
+                                          test.netrc.gpg
+                                          git-credential-netrc);
+local $ENV{PATH} = join ':'
+                      , $scriptDir
+                      , $ENV{PATH}
+                      ? $ENV{PATH}
+                      : ();
+
+diag "Testing insecure file, nothing should be found\n";
 chmod 0644, $netrc;
 my $cred = run_credential(['-f', $netrc, 'get'],
                          { host => 'github.com' });
 
-ok(scalar keys %$cred, 0, "Got 0 keys from insecure file");
+ok(scalar keys %$cred == 0, "Got 0 keys from insecure file");
 
-print "# Testing missing file, nothing should be found\n";
+diag "Testing missing file, nothing should be found\n";
 chmod 0644, $netrc;
 $cred = run_credential(['-f', '///nosuchfile///', 'get'],
                       { host => 'github.com' });
 
-ok(scalar keys %$cred, 0, "Got 0 keys from missing file");
+ok(scalar keys %$cred == 0, "Got 0 keys from missing file");
 
 chmod 0600, $netrc;
 
-print "# Testing with invalid data\n";
+diag "Testing with invalid data\n";
 $cred = run_credential(['-f', $netrc, 'get'],
                       "bad data");
-ok(scalar keys %$cred, 4, "Got first found keys with bad data");
+ok(scalar keys %$cred == 4, "Got first found keys with bad data");
 
-print "# Testing netrc file for a missing corovamilkbar entry\n";
+diag "Testing netrc file for a missing corovamilkbar entry\n";
 $cred = run_credential(['-f', $netrc, 'get'],
                       { host => 'corovamilkbar' });
 
-ok(scalar keys %$cred, 0, "Got no corovamilkbar keys");
+ok(scalar keys %$cred == 0, "Got no corovamilkbar keys");
 
-print "# Testing netrc file for a github.com entry\n";
+diag "Testing netrc file for a github.com entry\n";
 $cred = run_credential(['-f', $netrc, 'get'],
                       { host => 'github.com' });
 
-ok(scalar keys %$cred, 2, "Got 2 Github keys");
+ok(scalar keys %$cred == 2, "Got 2 Github keys");
 
-ok($cred->{password}, 'carolknows', "Got correct Github password");
-ok($cred->{username}, 'carol', "Got correct Github username");
+is($cred->{password}, 'carolknows', "Got correct Github password");
+is($cred->{username}, 'carol', "Got correct Github username");
 
-print "# Testing netrc file for a username-specific entry\n";
+diag "Testing netrc file for a username-specific entry\n";
 $cred = run_credential(['-f', $netrc, 'get'],
                       { host => 'imap', username => 'bob' });
 
-ok(scalar keys %$cred, 2, "Got 2 username-specific keys");
+ok(scalar keys %$cred == 2, "Got 2 username-specific keys");
 
-ok($cred->{password}, 'bobwillknow', "Got correct user-specific password");
-ok($cred->{protocol}, 'imaps', "Got correct user-specific protocol");
+is($cred->{password}, 'bobwillknow', "Got correct user-specific password");
+is($cred->{protocol}, 'imaps', "Got correct user-specific protocol");
 
-print "# Testing netrc file for a host:port-specific entry\n";
+diag "Testing netrc file for a host:port-specific entry\n";
 $cred = run_credential(['-f', $netrc, 'get'],
                       { host => 'imap2:1099' });
 
-ok(scalar keys %$cred, 2, "Got 2 host:port-specific keys");
+ok(scalar keys %$cred == 2, "Got 2 host:port-specific keys");
 
-ok($cred->{password}, 'tzzknow', "Got correct host:port-specific password");
-ok($cred->{username}, 'tzz', "Got correct host:port-specific username");
+is($cred->{password}, 'tzzknow', "Got correct host:port-specific password");
+is($cred->{username}, 'tzz', "Got correct host:port-specific username");
 
-print "# Testing netrc file that 'host:port kills host' entry\n";
+diag "Testing netrc file that 'host:port kills host' entry\n";
 $cred = run_credential(['-f', $netrc, 'get'],
                       { host => 'imap2' });
 
-ok(scalar keys %$cred, 2, "Got 2 'host:port kills host' keys");
+ok(scalar keys %$cred == 2, "Got 2 'host:port kills host' keys");
+
+is($cred->{password}, 'bobwillknow', "Got correct 'host:port kills host' password");
+is($cred->{username}, 'bob', "Got correct 'host:port kills host' username");
+
+diag 'Testing netrc file decryption by git config gpg.program setting\n';
+$cred = run_credential( ['-f', $netrcGpg, 'get']
+                      , { host => 'git-config-gpg' }
+                      );
+
+ok(scalar keys %$cred == 2, 'Got keys decrypted by git config option');
+
+diag 'Testing netrc file decryption by gpg option\n';
+$cred = run_credential( ['-f', $netrcGpg, '-g', 'test.command-option-gpg', 'get']
+                      , { host => 'command-option-gpg' }
+                      );
 
-ok($cred->{password}, 'bobwillknow', "Got correct 'host:port kills host' password");
-ok($cred->{username}, 'bob', "Got correct 'host:port kills host' username");
+ok(scalar keys %$cred == 2, 'Got keys decrypted by command option');
 
 sub run_credential
 {
        my $args = shift @_;
        my $data = shift @_;
        my $pid = open2(my $chld_out, my $chld_in,
-                       './git-credential-netrc', @global_credential_args,
+                       $gcNetrc, @global_credential_args,
                        @$args);
 
        die "Couldn't open pipe to netrc credential helper: $!" unless $pid;
index 663992e530c82f891361ccc9b952099aff3d56ec..536754583b59945e984ad487b6e524e5d1de7056 100644 (file)
@@ -21,37 +21,82 @@ my $RESET = "\x1b[m";
 my $COLOR = qr/\x1b\[[0-9;]*m/;
 my $BORING = qr/$COLOR|\s/;
 
-# The patch portion of git log -p --graph should only ever have preceding | and
-# not / or \ as merge history only shows up on the commit line.
-my $GRAPH = qr/$COLOR?\|$COLOR?\s+/;
-
 my @removed;
 my @added;
 my $in_hunk;
+my $graph_indent = 0;
 
 our $line_cb = sub { print @_ };
 our $flush_cb = sub { local $| = 1 };
 
-sub handle_line {
+# Count the visible width of a string, excluding any terminal color sequences.
+sub visible_width {
        local $_ = shift;
+       my $ret = 0;
+       while (length) {
+               if (s/^$COLOR//) {
+                       # skip colors
+               } elsif (s/^.//) {
+                       $ret++;
+               }
+       }
+       return $ret;
+}
+
+# Return a substring of $str, omitting $len visible characters from the
+# beginning, where terminal color sequences do not count as visible.
+sub visible_substr {
+       my ($str, $len) = @_;
+       while ($len > 0) {
+               if ($str =~ s/^$COLOR//) {
+                       next
+               }
+               $str =~ s/^.//;
+               $len--;
+       }
+       return $str;
+}
+
+sub handle_line {
+       my $orig = shift;
+       local $_ = $orig;
+
+       # match a graph line that begins a commit
+       if (/^(?:$COLOR?\|$COLOR?[ ])* # zero or more leading "|" with space
+                $COLOR?\*$COLOR?[ ]   # a "*" with its trailing space
+             (?:$COLOR?\|$COLOR?[ ])* # zero or more trailing "|"
+                                [ ]*  # trailing whitespace for merges
+           /x) {
+               my $graph_prefix = $&;
+
+               # We must flush before setting graph indent, since the
+               # new commit may be indented differently from what we
+               # queued.
+               flush();
+               $graph_indent = visible_width($graph_prefix);
+
+       } elsif ($graph_indent) {
+               if (length($_) < $graph_indent) {
+                       $graph_indent = 0;
+               } else {
+                       $_ = visible_substr($_, $graph_indent);
+               }
+       }
 
        if (!$in_hunk) {
-               $line_cb->($_);
-               $in_hunk = /^$GRAPH*$COLOR*\@\@ /;
+               $line_cb->($orig);
+               $in_hunk = /^$COLOR*\@\@ /;
        }
-       elsif (/^$GRAPH*$COLOR*-/) {
-               push @removed, $_;
+       elsif (/^$COLOR*-/) {
+               push @removed, $orig;
        }
-       elsif (/^$GRAPH*$COLOR*\+/) {
-               push @added, $_;
+       elsif (/^$COLOR*\+/) {
+               push @added, $orig;
        }
        else {
-               show_hunk(\@removed, \@added);
-               @removed = ();
-               @added = ();
-
-               $line_cb->($_);
-               $in_hunk = /^$GRAPH*$COLOR*[\@ ]/;
+               flush();
+               $line_cb->($orig);
+               $in_hunk = /^$COLOR*[\@ ]/;
        }
 
        # Most of the time there is enough output to keep things streaming,
@@ -71,6 +116,8 @@ sub flush {
        # Flush any queued hunk (this can happen when there is no trailing
        # context in the final diff of the input).
        show_hunk(\@removed, \@added);
+       @removed = ();
+       @added = ();
 }
 
 sub highlight_stdin {
@@ -226,8 +273,8 @@ sub is_pair_interesting {
        my $suffix_a = join('', @$a[($sa+1)..$#$a]);
        my $suffix_b = join('', @$b[($sb+1)..$#$b]);
 
-       return $prefix_a !~ /^$GRAPH*$COLOR*-$BORING*$/ ||
-              $prefix_b !~ /^$GRAPH*$COLOR*\+$BORING*$/ ||
+       return visible_substr($prefix_a, $graph_indent) !~ /^$COLOR*-$BORING*$/ ||
+              visible_substr($prefix_b, $graph_indent) !~ /^$COLOR*\+$BORING*$/ ||
               $suffix_a !~ /^$BORING*$/ ||
               $suffix_b !~ /^$BORING*$/;
 }
index 3b43dbed7488c5f4a5f05809725ffd0bcd7e61b5..f6f5195d00f6ca01b0751fc1c1b58055f0ef25ee 100755 (executable)
@@ -52,15 +52,17 @@ test_strip_patch_header () {
 # dh_test_setup_history generates a contrived graph such that we have at least
 # 1 nesting (E) and 2 nestings (F).
 #
-#            A branch
-#           /
-#      D---E---F master
+#        A---B master
+#       /
+#      D---E---F branch
 #
 #      git log --all --graph
 #      * commit
-#      |    A
+#      |    B
 #      | * commit
 #      | |    F
+#      * | commit
+#      | |    A
 #      | * commit
 #      |/
 #      |    E
@@ -68,24 +70,30 @@ test_strip_patch_header () {
 #           D
 #
 dh_test_setup_history () {
-       echo "file1" >file1 &&
-       echo "file2" >file2 &&
-       echo "file3" >file3 &&
-
-       cat file1 >file &&
+       echo file1 >file &&
        git add file &&
+       test_tick &&
        git commit -m "D" &&
 
        git checkout -b branch &&
-       cat file2 >file &&
-       git commit -a -m "A" &&
+       echo file2 >file &&
+       test_tick &&
+       git commit -a -m "E" &&
 
        git checkout master &&
-       cat file2 >file &&
-       git commit -a -m "E" &&
+       echo file2 >file &&
+       test_tick &&
+       git commit -a -m "A" &&
 
-       cat file3 >file &&
-       git commit -a -m "F"
+       git checkout branch &&
+       echo file3 >file &&
+       test_tick &&
+       git commit -a -m "F" &&
+
+       git checkout master &&
+       echo file3 >file &&
+       test_tick &&
+       git commit -a -m "B"
 }
 
 left_trim () {
@@ -246,16 +254,25 @@ test_expect_failure 'diff-highlight treats combining code points as a unit' '
 test_expect_success 'diff-highlight works with the --graph option' '
        dh_test_setup_history &&
 
-       # topo-order so that the order of the commits is the same as with --graph
+       # date-order so that the commits are interleaved for both
        # trim graph elements so we can do a diff
        # trim leading space because our trim_graph is not perfect
-       git log --branches -p --topo-order |
+       git log --branches -p --date-order |
                "$DIFF_HIGHLIGHT" | left_trim >graph.exp &&
-       git log --branches -p --graph |
+       git log --branches -p --date-order --graph |
                "$DIFF_HIGHLIGHT" | trim_graph | left_trim >graph.act &&
        test_cmp graph.exp graph.act
 '
 
+# Just reuse the previous graph test, but with --color.  Our trimming
+# doesn't know about color, so just sanity check that something got
+# highlighted.
+test_expect_success 'diff-highlight works with color graph' '
+       git log --branches -p --date-order --graph --color |
+               "$DIFF_HIGHLIGHT" | trim_graph | left_trim >graph &&
+       grep "\[7m" graph
+'
+
 # Most combined diffs won't meet diff-highlight's line-number filter. So we
 # create one here where one side drops a line and the other modifies it. That
 # should result in a diff like:
@@ -293,4 +310,32 @@ test_expect_success 'diff-highlight ignores combined diffs' '
        test_cmp expect actual
 '
 
+test_expect_success 'diff-highlight handles --graph with leading dash' '
+       cat >file <<-\EOF &&
+       before
+       the old line
+       -leading dash
+       EOF
+       git add file &&
+       git commit -m before &&
+
+       sed s/old/new/ <file >file.tmp &&
+       mv file.tmp file &&
+       git add file &&
+       git commit -m after &&
+
+       cat >expect <<-EOF &&
+       --- a/file
+       +++ b/file
+       @@ -1,3 +1,3 @@
+        before
+       -the ${CW}old${CR} line
+       +the ${CW}new${CR} line
+        -leading dash
+       EOF
+       git log --graph -p -1 | "$DIFF_HIGHLIGHT" >actual.raw &&
+       trim_graph <actual.raw | sed -n "/^---/,\$p" >actual &&
+       test_cmp expect actual
+'
+
 test_done
diff --git a/contrib/emacs/.gitignore b/contrib/emacs/.gitignore
deleted file mode 100644 (file)
index c531d98..0000000
+++ /dev/null
@@ -1 +0,0 @@
-*.elc
diff --git a/contrib/emacs/Makefile b/contrib/emacs/Makefile
deleted file mode 100644 (file)
index 24d9312..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-## Build and install stuff
-
-EMACS = emacs
-
-ELC = git.elc git-blame.elc
-INSTALL ?= install
-INSTALL_ELC = $(INSTALL) -m 644
-prefix ?= $(HOME)
-emacsdir = $(prefix)/share/emacs/site-lisp
-RM ?= rm -f
-
-all: $(ELC)
-
-install: all
-       $(INSTALL) -d $(DESTDIR)$(emacsdir)
-       $(INSTALL_ELC) $(ELC:.elc=.el) $(ELC) $(DESTDIR)$(emacsdir)
-
-%.elc: %.el
-       $(EMACS) -batch -f batch-byte-compile $<
-
-clean:; $(RM) $(ELC)
index 82368bdbfff199465ff8e8cbea49d99e5485e1d7..977a16f1e339faca937dfd1a60bb10395bfd59c4 100644 (file)
@@ -1,30 +1,24 @@
-This directory contains various modules for Emacs support.
+This directory used to contain various modules for Emacs support.
 
-To make the modules available to Emacs, you should add this directory
-to your load-path, and then require the modules you want. This can be
-done by adding to your .emacs something like this:
+These were added shortly after Git was first released. Since then
+Emacs's own support for Git got better than what was offered by these
+modes. There are also popular 3rd-party Git modes such as Magit which
+offer replacements for these.
 
-  (add-to-list 'load-path ".../git/contrib/emacs")
-  (require 'git)
-  (require 'git-blame)
-
-
-The following modules are available:
+The following modules were available, and can be dug up from the Git
+history:
 
 * git.el:
 
-  Status manager that displays the state of all the files of the
-  project, and provides easy access to the most frequently used git
-  commands. The user interface is as far as possible compatible with
-  the pcl-cvs mode. It can be started with `M-x git-status'.
+  Wrapper for "git status" that provided access to other git commands.
+
+  Modern alternatives to this include Magit, and VC mode that ships
+  with Emacs.
 
 * git-blame.el:
 
-  Emacs implementation of incremental git-blame.  When you turn it on
-  while viewing a file, the editor buffer will be updated by setting
-  the background of individual lines to a color that reflects which
-  commit it comes from.  And when you move around the buffer, a
-  one-line summary will be shown in the echo area.
+  A wrapper for "git blame" written before Emacs's own vc-annotate
+  mode learned to invoke git-blame, which can be done via C-x v g.
 
 * vc-git.el:
 
index 510e0f710374cfb06d5875108acdad9e877eaf2d..6a8a2b8ff190842f2dfc2a84f5283de12d2f5f9f 100644 (file)
@@ -1,483 +1,6 @@
-;;; git-blame.el --- Minor mode for incremental blame for Git  -*- coding: utf-8 -*-
-;;
-;; Copyright (C) 2007  David Kågedal
-;;
-;; Authors:    David Kågedal <davidk@lysator.liu.se>
-;; Created:    31 Jan 2007
-;; Message-ID: <87iren2vqx.fsf@morpheus.local>
-;; License:    GPL
-;; Keywords:   git, version control, release management
-;;
-;; Compatibility: Emacs21, Emacs22 and EmacsCVS
-;;                Git 1.5 and up
-
-;; This file is *NOT* part of GNU Emacs.
-;; This file is distributed under the same terms as GNU Emacs.
-
-;; 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 of
-;; the License, 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/>.
-
-;; http://www.fsf.org/copyleft/gpl.html
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Commentary:
-;;
-;; Here is an Emacs implementation of incremental git-blame.  When you
-;; turn it on while viewing a file, the editor buffer will be updated by
-;; setting the background of individual lines to a color that reflects
-;; which commit it comes from.  And when you move around the buffer, a
-;; one-line summary will be shown in the echo area.
-
-;;; Installation:
-;;
-;; To use this package, put it somewhere in `load-path' (or add
-;; directory with git-blame.el to `load-path'), and add the following
-;; line to your .emacs:
-;;
-;;    (require 'git-blame)
-;;
-;; If you do not want to load this package before it is necessary, you
-;; can make use of the `autoload' feature, e.g. by adding to your .emacs
-;; the following lines
-;;
-;;    (autoload 'git-blame-mode "git-blame"
-;;              "Minor mode for incremental blame for Git." t)
-;;
-;; Then first use of `M-x git-blame-mode' would load the package.
-
-;;; Compatibility:
-;;
-;; It requires GNU Emacs 21 or later and Git 1.5.0 and up
-;;
-;; If you'are using Emacs 20, try changing this:
-;;
-;;            (overlay-put ovl 'face (list :background
-;;                                         (cdr (assq 'color (cddddr info)))))
-;;
-;; to
-;;
-;;            (overlay-put ovl 'face (cons 'background-color
-;;                                         (cdr (assq 'color (cddddr info)))))
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;;; Code:
-
-(eval-when-compile (require 'cl))                            ; to use `push', `pop'
-(require 'format-spec)
-
-(defface git-blame-prefix-face
-  '((((background dark)) (:foreground "gray"
-                          :background "black"))
-    (((background light)) (:foreground "gray"
-                           :background "white"))
-    (t (:weight bold)))
-  "The face used for the hash prefix."
-  :group 'git-blame)
-
-(defgroup git-blame nil
-  "A minor mode showing Git blame information."
-  :group 'git
-  :link '(function-link git-blame-mode))
-
-
-(defcustom git-blame-use-colors t
-  "Use colors to indicate commits in `git-blame-mode'."
-  :type 'boolean
-  :group 'git-blame)
-
-(defcustom git-blame-prefix-format
-  "%h %20A:"
-  "The format of the prefix added to each line in `git-blame'
-mode. The format is passed to `format-spec' with the following format keys:
-
-  %h - the abbreviated hash
-  %H - the full hash
-  %a - the author name
-  %A - the author email
-  %c - the committer name
-  %C - the committer email
-  %s - the commit summary
-"
-  :group 'git-blame)
-
-(defcustom git-blame-mouseover-format
-  "%h %a %A: %s"
-  "The format of the description shown when pointing at a line in
-`git-blame' mode. The format string is passed to `format-spec'
-with the following format keys:
-
-  %h - the abbreviated hash
-  %H - the full hash
-  %a - the author name
-  %A - the author email
-  %c - the committer name
-  %C - the committer email
-  %s - the commit summary
-"
-  :group 'git-blame)
-
-
-(defun git-blame-color-scale (&rest elements)
-  "Given a list, returns a list of triples formed with each
-elements of the list.
-
-a b => bbb bba bab baa abb aba aaa aab"
-  (let (result)
-    (dolist (a elements)
-      (dolist (b elements)
-        (dolist (c elements)
-          (setq result (cons (format "#%s%s%s" a b c) result)))))
-    result))
-
-;; (git-blame-color-scale "0c" "04" "24" "1c" "2c" "34" "14" "3c") =>
-;; ("#3c3c3c" "#3c3c14" "#3c3c34" "#3c3c2c" "#3c3c1c" "#3c3c24"
-;; "#3c3c04" "#3c3c0c" "#3c143c" "#3c1414" "#3c1434" "#3c142c" ...)
-
-(defmacro git-blame-random-pop (l)
-  "Select a random element from L and returns it. Also remove
-selected element from l."
-  ;; only works on lists with unique elements
-  `(let ((e (elt ,l (random (length ,l)))))
-     (setq ,l (remove e ,l))
-     e))
-
-(defvar git-blame-log-oneline-format
-  "format:[%cr] %cn: %s"
-  "*Formatting option used for describing current line in the minibuffer.
-
-This option is used to pass to git log --pretty= command-line option,
-and describe which commit the current line was made.")
-
-(defvar git-blame-dark-colors
-  (git-blame-color-scale "0c" "04" "24" "1c" "2c" "34" "14" "3c")
-  "*List of colors (format #RGB) to use in a dark environment.
-
-To check out the list, evaluate (list-colors-display git-blame-dark-colors).")
-
-(defvar git-blame-light-colors
-  (git-blame-color-scale "c4" "d4" "cc" "dc" "f4" "e4" "fc" "ec")
-  "*List of colors (format #RGB) to use in a light environment.
-
-To check out the list, evaluate (list-colors-display git-blame-light-colors).")
-
-(defvar git-blame-colors '()
-  "Colors used by git-blame. The list is built once when activating git-blame
-minor mode.")
-
-(defvar git-blame-ancient-color "dark green"
-  "*Color to be used for ancient commit.")
-
-(defvar git-blame-autoupdate t
-  "*Automatically update the blame display while editing")
-
-(defvar git-blame-proc nil
-  "The running git-blame process")
-(make-variable-buffer-local 'git-blame-proc)
-
-(defvar git-blame-overlays nil
-  "The git-blame overlays used in the current buffer.")
-(make-variable-buffer-local 'git-blame-overlays)
-
-(defvar git-blame-cache nil
-  "A cache of git-blame information for the current buffer")
-(make-variable-buffer-local 'git-blame-cache)
-
-(defvar git-blame-idle-timer nil
-  "An idle timer that updates the blame")
-(make-variable-buffer-local 'git-blame-cache)
-
-(defvar git-blame-update-queue nil
-  "A queue of update requests")
-(make-variable-buffer-local 'git-blame-update-queue)
-
-;; FIXME: docstrings
-(defvar git-blame-file nil)
-(defvar git-blame-current nil)
-
-(defvar git-blame-mode nil)
-(make-variable-buffer-local 'git-blame-mode)
-
-(defvar git-blame-mode-line-string " blame"
-  "String to display on the mode line when git-blame is active.")
-
-(or (assq 'git-blame-mode minor-mode-alist)
-    (setq minor-mode-alist
-         (cons '(git-blame-mode git-blame-mode-line-string) minor-mode-alist)))
-
-;;;###autoload
-(defun git-blame-mode (&optional arg)
-  "Toggle minor mode for displaying Git blame
-
-With prefix ARG, turn the mode on if ARG is positive."
-  (interactive "P")
-  (cond
-   ((null arg)
-    (if git-blame-mode (git-blame-mode-off) (git-blame-mode-on)))
-   ((> (prefix-numeric-value arg) 0) (git-blame-mode-on))
-   (t (git-blame-mode-off))))
-
-(defun git-blame-mode-on ()
-  "Turn on git-blame mode.
-
-See also function `git-blame-mode'."
-  (make-local-variable 'git-blame-colors)
-  (if git-blame-autoupdate
-      (add-hook 'after-change-functions 'git-blame-after-change nil t)
-    (remove-hook 'after-change-functions 'git-blame-after-change t))
-  (git-blame-cleanup)
-  (let ((bgmode (cdr (assoc 'background-mode (frame-parameters)))))
-    (if (eq bgmode 'dark)
-       (setq git-blame-colors git-blame-dark-colors)
-      (setq git-blame-colors git-blame-light-colors)))
-  (setq git-blame-cache (make-hash-table :test 'equal))
-  (setq git-blame-mode t)
-  (git-blame-run))
-
-(defun git-blame-mode-off ()
-  "Turn off git-blame mode.
-
-See also function `git-blame-mode'."
-  (git-blame-cleanup)
-  (if git-blame-idle-timer (cancel-timer git-blame-idle-timer))
-  (setq git-blame-mode nil))
-
-;;;###autoload
-(defun git-reblame ()
-  "Recalculate all blame information in the current buffer"
-  (interactive)
-  (unless git-blame-mode
-    (error "Git-blame is not active"))
-
-  (git-blame-cleanup)
-  (git-blame-run))
-
-(defun git-blame-run (&optional startline endline)
-  (if git-blame-proc
-      ;; Should maybe queue up a new run here
-      (message "Already running git blame")
-    (let ((display-buf (current-buffer))
-          (blame-buf (get-buffer-create
-                      (concat " git blame for " (buffer-name))))
-          (args '("--incremental" "--contents" "-")))
-      (if startline
-          (setq args (append args
-                             (list "-L" (format "%d,%d" startline endline)))))
-      (setq args (append args
-                         (list (file-name-nondirectory buffer-file-name))))
-      (setq git-blame-proc
-            (apply 'start-process
-                   "git-blame" blame-buf
-                   "git" "blame"
-                   args))
-      (with-current-buffer blame-buf
-        (erase-buffer)
-        (make-local-variable 'git-blame-file)
-        (make-local-variable 'git-blame-current)
-        (setq git-blame-file display-buf)
-        (setq git-blame-current nil))
-      (set-process-filter git-blame-proc 'git-blame-filter)
-      (set-process-sentinel git-blame-proc 'git-blame-sentinel)
-      (process-send-region git-blame-proc (point-min) (point-max))
-      (process-send-eof git-blame-proc))))
-
-(defun remove-git-blame-text-properties (start end)
-  (let ((modified (buffer-modified-p))
-        (inhibit-read-only t))
-    (remove-text-properties start end '(point-entered nil))
-    (set-buffer-modified-p modified)))
-
-(defun git-blame-cleanup ()
-  "Remove all blame properties"
-    (mapc 'delete-overlay git-blame-overlays)
-    (setq git-blame-overlays nil)
-    (remove-git-blame-text-properties (point-min) (point-max)))
-
-(defun git-blame-update-region (start end)
-  "Rerun blame to get updates between START and END"
-  (let ((overlays (overlays-in start end)))
-    (while overlays
-      (let ((overlay (pop overlays)))
-        (if (< (overlay-start overlay) start)
-            (setq start (overlay-start overlay)))
-        (if (> (overlay-end overlay) end)
-            (setq end (overlay-end overlay)))
-        (setq git-blame-overlays (delete overlay git-blame-overlays))
-        (delete-overlay overlay))))
-  (remove-git-blame-text-properties start end)
-  ;; We can be sure that start and end are at line breaks
-  (git-blame-run (1+ (count-lines (point-min) start))
-                 (count-lines (point-min) end)))
-
-(defun git-blame-sentinel (proc status)
-  (with-current-buffer (process-buffer proc)
-    (with-current-buffer git-blame-file
-      (setq git-blame-proc nil)
-      (if git-blame-update-queue
-          (git-blame-delayed-update))))
-  ;;(kill-buffer (process-buffer proc))
-  ;;(message "git blame finished")
-  )
-
-(defvar in-blame-filter nil)
-
-(defun git-blame-filter (proc str)
-  (with-current-buffer (process-buffer proc)
-    (save-excursion
-      (goto-char (process-mark proc))
-      (insert-before-markers str)
-      (goto-char (point-min))
-      (unless in-blame-filter
-        (let ((more t)
-              (in-blame-filter t))
-          (while more
-            (setq more (git-blame-parse))))))))
-
-(defun git-blame-parse ()
-  (cond ((looking-at "\\([0-9a-f]\\{40\\}\\) \\([0-9]+\\) \\([0-9]+\\) \\([0-9]+\\)\n")
-         (let ((hash (match-string 1))
-               (src-line (string-to-number (match-string 2)))
-               (res-line (string-to-number (match-string 3)))
-               (num-lines (string-to-number (match-string 4))))
-           (delete-region (point) (match-end 0))
-           (setq git-blame-current (list (git-blame-new-commit hash)
-                                         src-line res-line num-lines)))
-         t)
-        ((looking-at "\\([a-z-]+\\) \\(.+\\)\n")
-         (let ((key (match-string 1))
-               (value (match-string 2)))
-           (delete-region (point) (match-end 0))
-           (git-blame-add-info (car git-blame-current) key value)
-           (when (string= key "filename")
-             (git-blame-create-overlay (car git-blame-current)
-                                       (caddr git-blame-current)
-                                       (cadddr git-blame-current))
-             (setq git-blame-current nil)))
-         t)
-        (t
-         nil)))
-
-(defun git-blame-new-commit (hash)
-  (with-current-buffer git-blame-file
-    (or (gethash hash git-blame-cache)
-        ;; Assign a random color to each new commit info
-        ;; Take care not to select the same color multiple times
-        (let* ((color (if git-blame-colors
-                          (git-blame-random-pop git-blame-colors)
-                        git-blame-ancient-color))
-               (info `(,hash (color . ,color))))
-          (puthash hash info git-blame-cache)
-          info))))
-
-(defun git-blame-create-overlay (info start-line num-lines)
-  (with-current-buffer git-blame-file
-    (save-excursion
-      (let ((inhibit-point-motion-hooks t)
-            (inhibit-modification-hooks t))
-        (goto-char (point-min))
-        (forward-line (1- start-line))
-        (let* ((start (point))
-               (end (progn (forward-line num-lines) (point)))
-               (ovl (make-overlay start end))
-               (hash (car info))
-               (spec `((?h . ,(substring hash 0 6))
-                       (?H . ,hash)
-                       (?a . ,(git-blame-get-info info 'author))
-                       (?A . ,(git-blame-get-info info 'author-mail))
-                       (?c . ,(git-blame-get-info info 'committer))
-                       (?C . ,(git-blame-get-info info 'committer-mail))
-                       (?s . ,(git-blame-get-info info 'summary)))))
-          (push ovl git-blame-overlays)
-          (overlay-put ovl 'git-blame info)
-          (overlay-put ovl 'help-echo
-                       (format-spec git-blame-mouseover-format spec))
-          (if git-blame-use-colors
-              (overlay-put ovl 'face (list :background
-                                           (cdr (assq 'color (cdr info))))))
-          (overlay-put ovl 'line-prefix
-                       (propertize (format-spec git-blame-prefix-format spec)
-                                   'face 'git-blame-prefix-face)))))))
-
-(defun git-blame-add-info (info key value)
-  (nconc info (list (cons (intern key) value))))
-
-(defun git-blame-get-info (info key)
-  (cdr (assq key (cdr info))))
-
-(defun git-blame-current-commit ()
-  (let ((info (get-char-property (point) 'git-blame)))
-    (if info
-        (car info)
-      (error "No commit info"))))
-
-(defun git-describe-commit (hash)
-  (with-temp-buffer
-    (call-process "git" nil t nil
-                  "log" "-1"
-                 (concat "--pretty=" git-blame-log-oneline-format)
-                  hash)
-    (buffer-substring (point-min) (point-max))))
-
-(defvar git-blame-last-identification nil)
-(make-variable-buffer-local 'git-blame-last-identification)
-(defun git-blame-identify (&optional hash)
-  (interactive)
-  (let ((info (gethash (or hash (git-blame-current-commit)) git-blame-cache)))
-    (when (and info (not (eq info git-blame-last-identification)))
-      (message "%s" (nth 4 info))
-      (setq git-blame-last-identification info))))
-
-;; (defun git-blame-after-save ()
-;;   (when git-blame-mode
-;;     (git-blame-cleanup)
-;;     (git-blame-run)))
-;; (add-hook 'after-save-hook 'git-blame-after-save)
-
-(defun git-blame-after-change (start end length)
-  (when git-blame-mode
-    (git-blame-enq-update start end)))
-
-(defvar git-blame-last-update nil)
-(make-variable-buffer-local 'git-blame-last-update)
-(defun git-blame-enq-update (start end)
-  "Mark the region between START and END as needing blame update"
-  ;; Try to be smart and avoid multiple callouts for sequential
-  ;; editing
-  (cond ((and git-blame-last-update
-              (= start (cdr git-blame-last-update)))
-         (setcdr git-blame-last-update end))
-        ((and git-blame-last-update
-              (= end (car git-blame-last-update)))
-         (setcar git-blame-last-update start))
-        (t
-         (setq git-blame-last-update (cons start end))
-         (setq git-blame-update-queue (nconc git-blame-update-queue
-                                             (list git-blame-last-update)))))
-  (unless (or git-blame-proc git-blame-idle-timer)
-    (setq git-blame-idle-timer
-          (run-with-idle-timer 0.5 nil 'git-blame-delayed-update))))
-
-(defun git-blame-delayed-update ()
-  (setq git-blame-idle-timer nil)
-  (if git-blame-update-queue
-      (let ((first (pop git-blame-update-queue))
-            (inhibit-point-motion-hooks t))
-        (git-blame-update-region (car first) (cdr first)))))
-
-(provide 'git-blame)
-
-;;; git-blame.el ends here
+(error "git-blame.el no longer ships with git. It's recommended
+to replace its use with Emacs's own vc-annotate. See
+contrib/emacs/README in git's
+sources (https://github.com/git/git/blob/master/contrib/emacs/README)
+for more info on suggested alternatives and for why this
+happened.")
index 97919f2d73a73d06bf4e23831fddd473ed75022d..03f926281fb16128a68969acdd97f32b7d6a1e03 100644 (file)
-;;; git.el --- A user interface for git
-
-;; Copyright (C) 2005, 2006, 2007, 2008, 2009 Alexandre Julliard <julliard@winehq.org>
-
-;; Version: 1.0
-
-;; 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 of
-;; the License, 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/>.
-
-;;; Commentary:
-
-;; This file contains an interface for the git version control
-;; system. It provides easy access to the most frequently used git
-;; commands. The user interface is as far as possible identical to
-;; that of the PCL-CVS mode.
-;;
-;; To install: put this file on the load-path and place the following
-;; in your .emacs file:
-;;
-;;    (require 'git)
-;;
-;; To start: `M-x git-status'
-;;
-;; TODO
-;;  - diff against other branch
-;;  - renaming files from the status buffer
-;;  - creating tags
-;;  - fetch/pull
-;;  - revlist browser
-;;  - git-show-branch browser
-;;
-
-;;; Compatibility:
-;;
-;; This file works on GNU Emacs 21 or later. It may work on older
-;; versions but this is not guaranteed.
-;;
-;; It may work on XEmacs 21, provided that you first install the ewoc
-;; and log-edit packages.
-;;
-
-(eval-when-compile (require 'cl))
-(require 'ewoc)
-(require 'log-edit)
-(require 'easymenu)
-
-
-;;;; Customizations
-;;;; ------------------------------------------------------------
-
-(defgroup git nil
-  "A user interface for the git versioning system."
-  :group 'tools)
-
-(defcustom git-committer-name nil
-  "User name to use for commits.
-The default is to fall back to the repository config,
-then to `add-log-full-name' and then to `user-full-name'."
-  :group 'git
-  :type '(choice (const :tag "Default" nil)
-                 (string :tag "Name")))
-
-(defcustom git-committer-email nil
-  "Email address to use for commits.
-The default is to fall back to the git repository config,
-then to `add-log-mailing-address' and then to `user-mail-address'."
-  :group 'git
-  :type '(choice (const :tag "Default" nil)
-                 (string :tag "Email")))
-
-(defcustom git-commits-coding-system nil
-  "Default coding system for the log message of git commits."
-  :group 'git
-  :type '(choice (const :tag "From repository config" nil)
-                 (coding-system)))
-
-(defcustom git-append-signed-off-by nil
-  "Whether to append a Signed-off-by line to the commit message before editing."
-  :group 'git
-  :type 'boolean)
-
-(defcustom git-reuse-status-buffer t
-  "Whether `git-status' should try to reuse an existing buffer
-if there is already one that displays the same directory."
-  :group 'git
-  :type 'boolean)
-
-(defcustom git-per-dir-ignore-file ".gitignore"
-  "Name of the per-directory ignore file."
-  :group 'git
-  :type 'string)
-
-(defcustom git-show-uptodate nil
-  "Whether to display up-to-date files."
-  :group 'git
-  :type 'boolean)
-
-(defcustom git-show-ignored nil
-  "Whether to display ignored files."
-  :group 'git
-  :type 'boolean)
-
-(defcustom git-show-unknown t
-  "Whether to display unknown files."
-  :group 'git
-  :type 'boolean)
-
-
-(defface git-status-face
-  '((((class color) (background light)) (:foreground "purple"))
-    (((class color) (background dark)) (:foreground "salmon")))
-  "Git mode face used to highlight added and modified files."
-  :group 'git)
-
-(defface git-unmerged-face
-  '((((class color) (background light)) (:foreground "red" :bold t))
-    (((class color) (background dark)) (:foreground "red" :bold t)))
-  "Git mode face used to highlight unmerged files."
-  :group 'git)
-
-(defface git-unknown-face
-  '((((class color) (background light)) (:foreground "goldenrod" :bold t))
-    (((class color) (background dark)) (:foreground "goldenrod" :bold t)))
-  "Git mode face used to highlight unknown files."
-  :group 'git)
-
-(defface git-uptodate-face
-  '((((class color) (background light)) (:foreground "grey60"))
-    (((class color) (background dark)) (:foreground "grey40")))
-  "Git mode face used to highlight up-to-date files."
-  :group 'git)
-
-(defface git-ignored-face
-  '((((class color) (background light)) (:foreground "grey60"))
-    (((class color) (background dark)) (:foreground "grey40")))
-  "Git mode face used to highlight ignored files."
-  :group 'git)
-
-(defface git-mark-face
-  '((((class color) (background light)) (:foreground "red" :bold t))
-    (((class color) (background dark)) (:foreground "tomato" :bold t)))
-  "Git mode face used for the file marks."
-  :group 'git)
-
-(defface git-header-face
-  '((((class color) (background light)) (:foreground "blue"))
-    (((class color) (background dark)) (:foreground "blue")))
-  "Git mode face used for commit headers."
-  :group 'git)
-
-(defface git-separator-face
-  '((((class color) (background light)) (:foreground "brown"))
-    (((class color) (background dark)) (:foreground "brown")))
-  "Git mode face used for commit separator."
-  :group 'git)
-
-(defface git-permission-face
-  '((((class color) (background light)) (:foreground "green" :bold t))
-    (((class color) (background dark)) (:foreground "green" :bold t)))
-  "Git mode face used for permission changes."
-  :group 'git)
-
-
-;;;; Utilities
-;;;; ------------------------------------------------------------
-
-(defconst git-log-msg-separator "--- log message follows this line ---")
-
-(defvar git-log-edit-font-lock-keywords
-  `(("^\\(Author:\\|Date:\\|Merge:\\|Signed-off-by:\\)\\(.*\\)$"
-     (1 font-lock-keyword-face)
-     (2 font-lock-function-name-face))
-    (,(concat "^\\(" (regexp-quote git-log-msg-separator) "\\)$")
-     (1 font-lock-comment-face))))
-
-(defun git-get-env-strings (env)
-  "Build a list of NAME=VALUE strings from a list of environment strings."
-  (mapcar (lambda (entry) (concat (car entry) "=" (cdr entry))) env))
-
-(defun git-call-process (buffer &rest args)
-  "Wrapper for call-process that sets environment strings."
-  (apply #'call-process "git" nil buffer nil args))
-
-(defun git-call-process-display-error (&rest args)
-  "Wrapper for call-process that displays error messages."
-  (let* ((dir default-directory)
-         (buffer (get-buffer-create "*Git Command Output*"))
-         (ok (with-current-buffer buffer
-               (let ((default-directory dir)
-                     (buffer-read-only nil))
-                 (erase-buffer)
-                 (eq 0 (apply #'git-call-process (list buffer t) args))))))
-    (unless ok (display-message-or-buffer buffer))
-    ok))
-
-(defun git-call-process-string (&rest args)
-  "Wrapper for call-process that returns the process output as a string,
-or nil if the git command failed."
-  (with-temp-buffer
-    (and (eq 0 (apply #'git-call-process t args))
-         (buffer-string))))
-
-(defun git-call-process-string-display-error (&rest args)
-  "Wrapper for call-process that displays error message and returns
-the process output as a string, or nil if the git command failed."
-  (with-temp-buffer
-    (if (eq 0 (apply #'git-call-process (list t t) args))
-        (buffer-string)
-      (display-message-or-buffer (current-buffer))
-      nil)))
-
-(defun git-run-process-region (buffer start end program args)
-  "Run a git process with a buffer region as input."
-  (let ((output-buffer (current-buffer))
-        (dir default-directory))
-    (with-current-buffer buffer
-      (cd dir)
-      (apply #'call-process-region start end program
-             nil (list output-buffer t) nil args))))
-
-(defun git-run-command-buffer (buffer-name &rest args)
-  "Run a git command, sending the output to a buffer named BUFFER-NAME."
-  (let ((dir default-directory)
-        (buffer (get-buffer-create buffer-name)))
-    (message "Running git %s..." (car args))
-    (with-current-buffer buffer
-      (let ((default-directory dir)
-            (buffer-read-only nil))
-        (erase-buffer)
-        (apply #'git-call-process buffer args)))
-    (message "Running git %s...done" (car args))
-    buffer))
-
-(defun git-run-command-region (buffer start end env &rest args)
-  "Run a git command with specified buffer region as input."
-  (with-temp-buffer
-    (if (eq 0 (if env
-                  (git-run-process-region
-                   buffer start end "env"
-                   (append (git-get-env-strings env) (list "git") args))
-                (git-run-process-region buffer start end "git" args)))
-        (buffer-string)
-      (display-message-or-buffer (current-buffer))
-      nil)))
-
-(defun git-run-hook (hook env &rest args)
-  "Run a git hook and display its output if any."
-  (let ((dir default-directory)
-        (hook-name (expand-file-name (concat ".git/hooks/" hook))))
-    (or (not (file-executable-p hook-name))
-        (let (status (buffer (get-buffer-create "*Git Hook Output*")))
-          (with-current-buffer buffer
-            (erase-buffer)
-            (cd dir)
-            (setq status
-                  (if env
-                      (apply #'call-process "env" nil (list buffer t) nil
-                             (append (git-get-env-strings env) (list hook-name) args))
-                    (apply #'call-process hook-name nil (list buffer t) nil args))))
-          (display-message-or-buffer buffer)
-          (eq 0 status)))))
-
-(defun git-get-string-sha1 (string)
-  "Read a SHA1 from the specified string."
-  (and string
-       (string-match "[0-9a-f]\\{40\\}" string)
-       (match-string 0 string)))
-
-(defun git-get-committer-name ()
-  "Return the name to use as GIT_COMMITTER_NAME."
-  ; copied from log-edit
-  (or git-committer-name
-      (git-config "user.name")
-      (and (boundp 'add-log-full-name) add-log-full-name)
-      (and (fboundp 'user-full-name) (user-full-name))
-      (and (boundp 'user-full-name) user-full-name)))
-
-(defun git-get-committer-email ()
-  "Return the email address to use as GIT_COMMITTER_EMAIL."
-  ; copied from log-edit
-  (or git-committer-email
-      (git-config "user.email")
-      (and (boundp 'add-log-mailing-address) add-log-mailing-address)
-      (and (fboundp 'user-mail-address) (user-mail-address))
-      (and (boundp 'user-mail-address) user-mail-address)))
-
-(defun git-get-commits-coding-system ()
-  "Return the coding system to use for commits."
-  (let ((repo-config (git-config "i18n.commitencoding")))
-    (or git-commits-coding-system
-        (and repo-config
-             (fboundp 'locale-charset-to-coding-system)
-             (locale-charset-to-coding-system repo-config))
-      'utf-8)))
-
-(defun git-get-logoutput-coding-system ()
-  "Return the coding system used for git-log output."
-  (let ((repo-config (or (git-config "i18n.logoutputencoding")
-                         (git-config "i18n.commitencoding"))))
-    (or git-commits-coding-system
-        (and repo-config
-             (fboundp 'locale-charset-to-coding-system)
-             (locale-charset-to-coding-system repo-config))
-      'utf-8)))
-
-(defun git-escape-file-name (name)
-  "Escape a file name if necessary."
-  (if (string-match "[\n\t\"\\]" name)
-      (concat "\""
-              (mapconcat (lambda (c)
-                   (case c
-                     (?\n "\\n")
-                     (?\t "\\t")
-                     (?\\ "\\\\")
-                     (?\" "\\\"")
-                     (t (char-to-string c))))
-                 name "")
-              "\"")
-    name))
-
-(defun git-success-message (text files)
-  "Print a success message after having handled FILES."
-  (let ((n (length files)))
-    (if (equal n 1)
-        (message "%s %s" text (car files))
-      (message "%s %d files" text n))))
-
-(defun git-get-top-dir (dir)
-  "Retrieve the top-level directory of a git tree."
-  (let ((cdup (with-output-to-string
-                (with-current-buffer standard-output
-                  (cd dir)
-                  (unless (eq 0 (git-call-process t "rev-parse" "--show-cdup"))
-                    (error "cannot find top-level git tree for %s." dir))))))
-    (expand-file-name (concat (file-name-as-directory dir)
-                              (car (split-string cdup "\n"))))))
-
-;stolen from pcl-cvs
-(defun git-append-to-ignore (file)
-  "Add a file name to the ignore file in its directory."
-  (let* ((fullname (expand-file-name file))
-         (dir (file-name-directory fullname))
-         (name (file-name-nondirectory fullname))
-         (ignore-name (expand-file-name git-per-dir-ignore-file dir))
-         (created (not (file-exists-p ignore-name))))
-  (save-window-excursion
-    (set-buffer (find-file-noselect ignore-name))
-    (goto-char (point-max))
-    (unless (zerop (current-column)) (insert "\n"))
-    (insert "/" name "\n")
-    (sort-lines nil (point-min) (point-max))
-    (save-buffer))
-  (when created
-    (git-call-process nil "update-index" "--add" "--" (file-relative-name ignore-name)))
-  (git-update-status-files (list (file-relative-name ignore-name)))))
-
-; propertize definition for XEmacs, stolen from erc-compat
-(eval-when-compile
-  (unless (fboundp 'propertize)
-    (defun propertize (string &rest props)
-      (let ((string (copy-sequence string)))
-        (while props
-          (put-text-property 0 (length string) (nth 0 props) (nth 1 props) string)
-          (setq props (cddr props)))
-        string))))
-
-;;;; Wrappers for basic git commands
-;;;; ------------------------------------------------------------
-
-(defun git-rev-parse (rev)
-  "Parse a revision name and return its SHA1."
-  (git-get-string-sha1
-   (git-call-process-string "rev-parse" rev)))
-
-(defun git-config (key)
-  "Retrieve the value associated to KEY in the git repository config file."
-  (let ((str (git-call-process-string "config" key)))
-    (and str (car (split-string str "\n")))))
-
-(defun git-symbolic-ref (ref)
-  "Wrapper for the git-symbolic-ref command."
-  (let ((str (git-call-process-string "symbolic-ref" ref)))
-    (and str (car (split-string str "\n")))))
-
-(defun git-update-ref (ref newval &optional oldval reason)
-  "Update a reference by calling git-update-ref."
-  (let ((args (and oldval (list oldval))))
-    (when newval (push newval args))
-    (push ref args)
-    (when reason
-     (push reason args)
-     (push "-m" args))
-    (unless newval (push "-d" args))
-    (apply 'git-call-process-display-error "update-ref" args)))
-
-(defun git-for-each-ref (&rest specs)
-  "Return a list of refs using git-for-each-ref.
-Each entry is a cons of (SHORT-NAME . FULL-NAME)."
-  (let (refs)
-    (with-temp-buffer
-      (apply #'git-call-process t "for-each-ref" "--format=%(refname)" specs)
-      (goto-char (point-min))
-      (while (re-search-forward "^[^/\n]+/[^/\n]+/\\(.+\\)$" nil t)
-       (push (cons (match-string 1) (match-string 0)) refs)))
-    (nreverse refs)))
-
-(defun git-read-tree (tree &optional index-file)
-  "Read a tree into the index file."
-  (let ((process-environment
-         (append (and index-file (list (concat "GIT_INDEX_FILE=" index-file))) process-environment)))
-    (apply 'git-call-process-display-error "read-tree" (if tree (list tree)))))
-
-(defun git-write-tree (&optional index-file)
-  "Call git-write-tree and return the resulting tree SHA1 as a string."
-  (let ((process-environment
-         (append (and index-file (list (concat "GIT_INDEX_FILE=" index-file))) process-environment)))
-    (git-get-string-sha1
-     (git-call-process-string-display-error "write-tree"))))
-
-(defun git-commit-tree (buffer tree parent)
-  "Create a commit and possibly update HEAD.
-Create a commit with the message in BUFFER using the tree with hash TREE.
-Use PARENT as the parent of the new commit. If PARENT is the current \"HEAD\",
-update the \"HEAD\" reference to the new commit."
-  (let ((author-name (git-get-committer-name))
-        (author-email (git-get-committer-email))
-        (subject "commit (initial): ")
-        author-date log-start log-end args coding-system-for-write)
-    (when parent
-      (setq subject "commit: ")
-      (push "-p" args)
-      (push parent args))
-    (with-current-buffer buffer
-      (goto-char (point-min))
-      (if
-          (setq log-start (re-search-forward (concat "^" (regexp-quote git-log-msg-separator) "\n") nil t))
-          (save-restriction
-            (narrow-to-region (point-min) log-start)
-            (goto-char (point-min))
-            (when (re-search-forward "^Author: +\\(.*?\\) *<\\(.*\\)> *$" nil t)
-              (setq author-name (match-string 1)
-                    author-email (match-string 2)))
-            (goto-char (point-min))
-            (when (re-search-forward "^Date: +\\(.*\\)$" nil t)
-              (setq author-date (match-string 1)))
-            (goto-char (point-min))
-            (when (re-search-forward "^Merge: +\\(.*\\)" nil t)
-              (setq subject "commit (merge): ")
-              (dolist (parent (split-string (match-string 1) " +" t))
-                (push "-p" args)
-                (push parent args))))
-        (setq log-start (point-min)))
-      (setq log-end (point-max))
-      (goto-char log-start)
-      (when (re-search-forward ".*$" nil t)
-        (setq subject (concat subject (match-string 0))))
-      (setq coding-system-for-write buffer-file-coding-system))
-    (let ((commit
-           (git-get-string-sha1
-            (let ((env `(("GIT_AUTHOR_NAME" . ,author-name)
-                         ("GIT_AUTHOR_EMAIL" . ,author-email)
-                         ("GIT_COMMITTER_NAME" . ,(git-get-committer-name))
-                         ("GIT_COMMITTER_EMAIL" . ,(git-get-committer-email)))))
-              (when author-date (push `("GIT_AUTHOR_DATE" . ,author-date) env))
-              (apply #'git-run-command-region
-                     buffer log-start log-end env
-                     "commit-tree" tree (nreverse args))))))
-      (when commit (git-update-ref "HEAD" commit parent subject))
-      commit)))
-
-(defun git-empty-db-p ()
-  "Check if the git db is empty (no commit done yet)."
-  (not (eq 0 (git-call-process nil "rev-parse" "--verify" "HEAD"))))
-
-(defun git-get-merge-heads ()
-  "Retrieve the merge heads from the MERGE_HEAD file if present."
-  (let (heads)
-    (when (file-readable-p ".git/MERGE_HEAD")
-      (with-temp-buffer
-        (insert-file-contents ".git/MERGE_HEAD" nil nil nil t)
-        (goto-char (point-min))
-        (while (re-search-forward "[0-9a-f]\\{40\\}" nil t)
-          (push (match-string 0) heads))))
-    (nreverse heads)))
-
-(defun git-get-commit-description (commit)
-  "Get a one-line description of COMMIT."
-  (let ((coding-system-for-read (git-get-logoutput-coding-system)))
-    (let ((descr (git-call-process-string "log" "--max-count=1" "--pretty=oneline" commit)))
-      (if (and descr (string-match "\\`\\([0-9a-f]\\{40\\}\\) *\\(.*\\)$" descr))
-          (concat (substring (match-string 1 descr) 0 10) " - " (match-string 2 descr))
-        descr))))
-
-;;;; File info structure
-;;;; ------------------------------------------------------------
-
-; fileinfo structure stolen from pcl-cvs
-(defstruct (git-fileinfo
-            (:copier nil)
-            (:constructor git-create-fileinfo (state name &optional old-perm new-perm rename-state orig-name marked))
-            (:conc-name git-fileinfo->))
-  marked              ;; t/nil
-  state               ;; current state
-  name                ;; file name
-  old-perm new-perm   ;; permission flags
-  rename-state        ;; rename or copy state
-  orig-name           ;; original name for renames or copies
-  needs-update        ;; whether file needs to be updated
-  needs-refresh)      ;; whether file needs to be refreshed
-
-(defvar git-status nil)
-
-(defun git-set-fileinfo-state (info state)
-  "Set the state of a file info."
-  (unless (eq (git-fileinfo->state info) state)
-    (setf (git-fileinfo->state info) state
-         (git-fileinfo->new-perm info) (git-fileinfo->old-perm info)
-          (git-fileinfo->rename-state info) nil
-          (git-fileinfo->orig-name info) nil
-          (git-fileinfo->needs-update info) nil
-          (git-fileinfo->needs-refresh info) t)))
-
-(defun git-status-filenames-map (status func files &rest args)
-  "Apply FUNC to the status files names in the FILES list.
-The list must be sorted."
-  (when files
-    (let ((file (pop files))
-          (node (ewoc-nth status 0)))
-      (while (and file node)
-        (let* ((info (ewoc-data node))
-               (name (git-fileinfo->name info)))
-          (if (string-lessp name file)
-              (setq node (ewoc-next status node))
-            (if (string-equal name file)
-                (apply func info args))
-            (setq file (pop files))))))))
-
-(defun git-set-filenames-state (status files state)
-  "Set the state of a list of named files. The list must be sorted"
-  (when files
-    (git-status-filenames-map status #'git-set-fileinfo-state files state)
-    (unless state  ;; delete files whose state has been set to nil
-      (ewoc-filter status (lambda (info) (git-fileinfo->state info))))))
-
-(defun git-state-code (code)
-  "Convert from a string to a added/deleted/modified state."
-  (case (string-to-char code)
-    (?M 'modified)
-    (?? 'unknown)
-    (?A 'added)
-    (?D 'deleted)
-    (?U 'unmerged)
-    (?T 'modified)
-    (t nil)))
-
-(defun git-status-code-as-string (code)
-  "Format a git status code as string."
-  (case code
-    ('modified (propertize "Modified" 'face 'git-status-face))
-    ('unknown  (propertize "Unknown " 'face 'git-unknown-face))
-    ('added    (propertize "Added   " 'face 'git-status-face))
-    ('deleted  (propertize "Deleted " 'face 'git-status-face))
-    ('unmerged (propertize "Unmerged" 'face 'git-unmerged-face))
-    ('uptodate (propertize "Uptodate" 'face 'git-uptodate-face))
-    ('ignored  (propertize "Ignored " 'face 'git-ignored-face))
-    (t "?       ")))
-
-(defun git-file-type-as-string (old-perm new-perm)
-  "Return a string describing the file type based on its permissions."
-  (let* ((old-type (lsh (or old-perm 0) -9))
-        (new-type (lsh (or new-perm 0) -9))
-        (str (case new-type
-               (64  ;; file
-                (case old-type
-                  (64 nil)
-                  (80 "   (type change symlink -> file)")
-                  (112 "   (type change subproject -> file)")))
-                (80  ;; symlink
-                 (case old-type
-                   (64 "   (type change file -> symlink)")
-                   (112 "   (type change subproject -> symlink)")
-                   (t "   (symlink)")))
-                 (112  ;; subproject
-                  (case old-type
-                    (64 "   (type change file -> subproject)")
-                    (80 "   (type change symlink -> subproject)")
-                    (t "   (subproject)")))
-                  (72 nil)  ;; directory (internal, not a real git state)
-                 (0  ;; deleted or unknown
-                  (case old-type
-                    (80 "   (symlink)")
-                    (112 "   (subproject)")))
-                 (t (format "   (unknown type %o)" new-type)))))
-    (cond (str (propertize str 'face 'git-status-face))
-          ((eq new-type 72) "/")
-          (t ""))))
-
-(defun git-rename-as-string (info)
-  "Return a string describing the copy or rename associated with INFO, or an empty string if none."
-  (let ((state (git-fileinfo->rename-state info)))
-    (if state
-        (propertize
-         (concat "   ("
-                 (if (eq state 'copy) "copied from "
-                   (if (eq (git-fileinfo->state info) 'added) "renamed from "
-                     "renamed to "))
-                 (git-escape-file-name (git-fileinfo->orig-name info))
-                 ")") 'face 'git-status-face)
-      "")))
-
-(defun git-permissions-as-string (old-perm new-perm)
-  "Format a permission change as string."
-  (propertize
-   (if (or (not old-perm)
-           (not new-perm)
-           (eq 0 (logand ?\111 (logxor old-perm new-perm))))
-       "  "
-     (if (eq 0 (logand ?\111 old-perm)) "+x" "-x"))
-  'face 'git-permission-face))
-
-(defun git-fileinfo-prettyprint (info)
-  "Pretty-printer for the git-fileinfo structure."
-  (let ((old-perm (git-fileinfo->old-perm info))
-       (new-perm (git-fileinfo->new-perm info)))
-    (insert (concat "   " (if (git-fileinfo->marked info) (propertize "*" 'face 'git-mark-face) " ")
-                   " " (git-status-code-as-string (git-fileinfo->state info))
-                   " " (git-permissions-as-string old-perm new-perm)
-                   "  " (git-escape-file-name (git-fileinfo->name info))
-                   (git-file-type-as-string old-perm new-perm)
-                   (git-rename-as-string info)))))
-
-(defun git-update-node-fileinfo (node info)
-  "Update the fileinfo of the specified node. The names are assumed to match already."
-  (let ((data (ewoc-data node)))
-    (setf
-     ;; preserve the marked flag
-     (git-fileinfo->marked info) (git-fileinfo->marked data)
-     (git-fileinfo->needs-update data) nil)
-    (when (not (equal info data))
-      (setf (git-fileinfo->needs-refresh info) t
-            (ewoc-data node) info))))
-
-(defun git-insert-info-list (status infolist files)
-  "Insert a sorted list of file infos in the status buffer, replacing existing ones if any."
-  (let* ((info (pop infolist))
-         (node (ewoc-nth status 0))
-         (name (and info (git-fileinfo->name info)))
-         remaining)
-    (while info
-      (let ((nodename (and node (git-fileinfo->name (ewoc-data node)))))
-        (while (and files (string-lessp (car files) name))
-          (push (pop files) remaining))
-        (when (and files (string-equal (car files) name))
-          (setq files (cdr files)))
-        (cond ((not nodename)
-               (setq node (ewoc-enter-last status info))
-               (setq info (pop infolist))
-               (setq name (and info (git-fileinfo->name info))))
-              ((string-lessp nodename name)
-               (setq node (ewoc-next status node)))
-              ((string-equal nodename name)
-               ;; preserve the marked flag
-               (git-update-node-fileinfo node info)
-               (setq info (pop infolist))
-               (setq name (and info (git-fileinfo->name info))))
-              (t
-               (setq node (ewoc-enter-before status node info))
-               (setq info (pop infolist))
-               (setq name (and info (git-fileinfo->name info)))))))
-    (nconc (nreverse remaining) files)))
-
-(defun git-run-diff-index (status files)
-  "Run git-diff-index on FILES and parse the results into STATUS.
-Return the list of files that haven't been handled."
-  (let (infolist)
-    (with-temp-buffer
-      (apply #'git-call-process t "diff-index" "-z" "-M" "HEAD" "--" files)
-      (goto-char (point-min))
-      (while (re-search-forward
-             ":\\([0-7]\\{6\\}\\) \\([0-7]\\{6\\}\\) [0-9a-f]\\{40\\} [0-9a-f]\\{40\\} \\(\\([ADMUT]\\)\0\\([^\0]+\\)\\|\\([CR]\\)[0-9]*\0\\([^\0]+\\)\0\\([^\0]+\\)\\)\0"
-              nil t 1)
-        (let ((old-perm (string-to-number (match-string 1) 8))
-              (new-perm (string-to-number (match-string 2) 8))
-              (state (or (match-string 4) (match-string 6)))
-              (name (or (match-string 5) (match-string 7)))
-              (new-name (match-string 8)))
-          (if new-name  ; copy or rename
-              (if (eq ?C (string-to-char state))
-                  (push (git-create-fileinfo 'added new-name old-perm new-perm 'copy name) infolist)
-                (push (git-create-fileinfo 'deleted name 0 0 'rename new-name) infolist)
-                (push (git-create-fileinfo 'added new-name old-perm new-perm 'rename name) infolist))
-            (push (git-create-fileinfo (git-state-code state) name old-perm new-perm) infolist)))))
-    (setq infolist (sort (nreverse infolist)
-                         (lambda (info1 info2)
-                           (string-lessp (git-fileinfo->name info1)
-                                         (git-fileinfo->name info2)))))
-    (git-insert-info-list status infolist files)))
-
-(defun git-find-status-file (status file)
-  "Find a given file in the status ewoc and return its node."
-  (let ((node (ewoc-nth status 0)))
-    (while (and node (not (string= file (git-fileinfo->name (ewoc-data node)))))
-      (setq node (ewoc-next status node)))
-    node))
-
-(defun git-run-ls-files (status files default-state &rest options)
-  "Run git-ls-files on FILES and parse the results into STATUS.
-Return the list of files that haven't been handled."
-  (let (infolist)
-    (with-temp-buffer
-      (apply #'git-call-process t "ls-files" "-z" (append options (list "--") files))
-      (goto-char (point-min))
-      (while (re-search-forward "\\([^\0]*?\\)\\(/?\\)\0" nil t 1)
-        (let ((name (match-string 1)))
-          (push (git-create-fileinfo default-state name 0
-                                     (if (string-equal "/" (match-string 2)) (lsh ?\110 9) 0))
-                infolist))))
-    (setq infolist (nreverse infolist))  ;; assume it is sorted already
-    (git-insert-info-list status infolist files)))
-
-(defun git-run-ls-files-cached (status files default-state)
-  "Run git-ls-files -c on FILES and parse the results into STATUS.
-Return the list of files that haven't been handled."
-  (let (infolist)
-    (with-temp-buffer
-      (apply #'git-call-process t "ls-files" "-z" "-s" "-c" "--" files)
-      (goto-char (point-min))
-      (while (re-search-forward "\\([0-7]\\{6\\}\\) [0-9a-f]\\{40\\} 0\t\\([^\0]+\\)\0" nil t)
-       (let* ((new-perm (string-to-number (match-string 1) 8))
-              (old-perm (if (eq default-state 'added) 0 new-perm))
-              (name (match-string 2)))
-         (push (git-create-fileinfo default-state name old-perm new-perm) infolist))))
-    (setq infolist (nreverse infolist))  ;; assume it is sorted already
-    (git-insert-info-list status infolist files)))
-
-(defun git-run-ls-unmerged (status files)
-  "Run git-ls-files -u on FILES and parse the results into STATUS."
-  (with-temp-buffer
-    (apply #'git-call-process t "ls-files" "-z" "-u" "--" files)
-    (goto-char (point-min))
-    (let (unmerged-files)
-      (while (re-search-forward "[0-7]\\{6\\} [0-9a-f]\\{40\\} [123]\t\\([^\0]+\\)\0" nil t)
-        (push (match-string 1) unmerged-files))
-      (setq unmerged-files (nreverse unmerged-files))  ;; assume it is sorted already
-      (git-set-filenames-state status unmerged-files 'unmerged))))
-
-(defun git-get-exclude-files ()
-  "Get the list of exclude files to pass to git-ls-files."
-  (let (files
-        (config (git-config "core.excludesfile")))
-    (when (file-readable-p ".git/info/exclude")
-      (push ".git/info/exclude" files))
-    (when (and config (file-readable-p config))
-      (push config files))
-    files))
-
-(defun git-run-ls-files-with-excludes (status files default-state &rest options)
-  "Run git-ls-files on FILES with appropriate --exclude-from options."
-  (let ((exclude-files (git-get-exclude-files)))
-    (apply #'git-run-ls-files status files default-state "--directory" "--no-empty-directory"
-           (concat "--exclude-per-directory=" git-per-dir-ignore-file)
-           (append options (mapcar (lambda (f) (concat "--exclude-from=" f)) exclude-files)))))
-
-(defun git-update-status-files (&optional files mark-files)
-  "Update the status of FILES from the index.
-The FILES list must be sorted."
-  (unless git-status (error "Not in git-status buffer."))
-  ;; set the needs-update flag on existing files
-  (if files
-      (git-status-filenames-map
-       git-status (lambda (info) (setf (git-fileinfo->needs-update info) t)) files)
-    (ewoc-map (lambda (info) (setf (git-fileinfo->needs-update info) t) nil) git-status)
-    (git-call-process nil "update-index" "--refresh")
-    (when git-show-uptodate
-      (git-run-ls-files-cached git-status nil 'uptodate)))
-  (let ((remaining-files
-          (if (git-empty-db-p) ; we need some special handling for an empty db
-             (git-run-ls-files-cached git-status files 'added)
-            (git-run-diff-index git-status files))))
-    (git-run-ls-unmerged git-status files)
-    (when (or remaining-files (and git-show-unknown (not files)))
-      (setq remaining-files (git-run-ls-files-with-excludes git-status remaining-files 'unknown "-o")))
-    (when (or remaining-files (and git-show-ignored (not files)))
-      (setq remaining-files (git-run-ls-files-with-excludes git-status remaining-files 'ignored "-o" "-i")))
-    (unless files
-      (setq remaining-files (git-get-filenames (ewoc-collect git-status #'git-fileinfo->needs-update))))
-    (when remaining-files
-      (setq remaining-files (git-run-ls-files-cached git-status remaining-files 'uptodate)))
-    (git-set-filenames-state git-status remaining-files nil)
-    (when mark-files (git-mark-files git-status files))
-    (git-refresh-files)
-    (git-refresh-ewoc-hf git-status)))
-
-(defun git-mark-files (status files)
-  "Mark all the specified FILES, and unmark the others."
-  (let ((file (and files (pop files)))
-        (node (ewoc-nth status 0)))
-    (while node
-      (let ((info (ewoc-data node)))
-        (if (and file (string-equal (git-fileinfo->name info) file))
-            (progn
-              (unless (git-fileinfo->marked info)
-                (setf (git-fileinfo->marked info) t)
-                (setf (git-fileinfo->needs-refresh info) t))
-              (setq file (pop files))
-              (setq node (ewoc-next status node)))
-          (when (git-fileinfo->marked info)
-            (setf (git-fileinfo->marked info) nil)
-            (setf (git-fileinfo->needs-refresh info) t))
-          (if (and file (string-lessp file (git-fileinfo->name info)))
-              (setq file (pop files))
-            (setq node (ewoc-next status node))))))))
-
-(defun git-marked-files ()
-  "Return a list of all marked files, or if none a list containing just the file at cursor position."
-  (unless git-status (error "Not in git-status buffer."))
-  (or (ewoc-collect git-status (lambda (info) (git-fileinfo->marked info)))
-      (list (ewoc-data (ewoc-locate git-status)))))
-
-(defun git-marked-files-state (&rest states)
-  "Return a sorted list of marked files that are in the specified states."
-  (let ((files (git-marked-files))
-        result)
-    (dolist (info files)
-      (when (memq (git-fileinfo->state info) states)
-        (push info result)))
-    (nreverse result)))
-
-(defun git-refresh-files ()
-  "Refresh all files that need it and clear the needs-refresh flag."
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-map
-   (lambda (info)
-     (let ((refresh (git-fileinfo->needs-refresh info)))
-       (setf (git-fileinfo->needs-refresh info) nil)
-       refresh))
-   git-status)
-  ; move back to goal column
-  (when goal-column (move-to-column goal-column)))
-
-(defun git-refresh-ewoc-hf (status)
-  "Refresh the ewoc header and footer."
-  (let ((branch (git-symbolic-ref "HEAD"))
-        (head (if (git-empty-db-p) "Nothing committed yet"
-                (git-get-commit-description "HEAD")))
-        (merge-heads (git-get-merge-heads)))
-    (ewoc-set-hf status
-                 (format "Directory:  %s\nBranch:     %s\nHead:       %s%s\n"
-                         default-directory
-                         (if branch
-                             (if (string-match "^refs/heads/" branch)
-                                 (substring branch (match-end 0))
-                               branch)
-                           "none (detached HEAD)")
-                         head
-                         (if merge-heads
-                             (concat "\nMerging:    "
-                                     (mapconcat (lambda (str) (git-get-commit-description str)) merge-heads "\n            "))
-                           ""))
-                 (if (ewoc-nth status 0) "" "    No changes."))))
-
-(defun git-get-filenames (files)
-  (mapcar (lambda (info) (git-fileinfo->name info)) files))
-
-(defun git-update-index (index-file files)
-  "Run git-update-index on a list of files."
-  (let ((process-environment (append (and index-file (list (concat "GIT_INDEX_FILE=" index-file)))
-                                     process-environment))
-        added deleted modified)
-    (dolist (info files)
-      (case (git-fileinfo->state info)
-        ('added (push info added))
-        ('deleted (push info deleted))
-        ('modified (push info modified))))
-    (and
-     (or (not added) (apply #'git-call-process-display-error "update-index" "--add" "--" (git-get-filenames added)))
-     (or (not deleted) (apply #'git-call-process-display-error "update-index" "--remove" "--" (git-get-filenames deleted)))
-     (or (not modified) (apply #'git-call-process-display-error "update-index" "--" (git-get-filenames modified))))))
-
-(defun git-run-pre-commit-hook ()
-  "Run the pre-commit hook if any."
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((files (git-marked-files-state 'added 'deleted 'modified)))
-    (or (not files)
-        (not (file-executable-p ".git/hooks/pre-commit"))
-        (let ((index-file (make-temp-file "gitidx")))
-          (unwind-protect
-            (let ((head-tree (unless (git-empty-db-p) (git-rev-parse "HEAD^{tree}"))))
-              (git-read-tree head-tree index-file)
-              (git-update-index index-file files)
-              (git-run-hook "pre-commit" `(("GIT_INDEX_FILE" . ,index-file))))
-          (delete-file index-file))))))
-
-(defun git-do-commit ()
-  "Perform the actual commit using the current buffer as log message."
-  (interactive)
-  (let ((buffer (current-buffer))
-        (index-file (make-temp-file "gitidx")))
-    (with-current-buffer log-edit-parent-buffer
-      (if (git-marked-files-state 'unmerged)
-          (message "You cannot commit unmerged files, resolve them first.")
-        (unwind-protect
-            (let ((files (git-marked-files-state 'added 'deleted 'modified))
-                  head tree head-tree)
-              (unless (git-empty-db-p)
-                (setq head (git-rev-parse "HEAD")
-                      head-tree (git-rev-parse "HEAD^{tree}")))
-              (message "Running git commit...")
-              (when
-                  (and
-                   (git-read-tree head-tree index-file)
-                   (git-update-index nil files)         ;update both the default index
-                   (git-update-index index-file files)  ;and the temporary one
-                   (setq tree (git-write-tree index-file)))
-                (if (or (not (string-equal tree head-tree))
-                        (yes-or-no-p "The tree was not modified, do you really want to perform an empty commit? "))
-                    (let ((commit (git-commit-tree buffer tree head)))
-                      (when commit
-                        (condition-case nil (delete-file ".git/MERGE_HEAD") (error nil))
-                        (condition-case nil (delete-file ".git/MERGE_MSG") (error nil))
-                        (with-current-buffer buffer (erase-buffer))
-                        (git-update-status-files (git-get-filenames files))
-                        (git-call-process nil "rerere")
-                        (git-call-process nil "gc" "--auto")
-                        (message "Committed %s." commit)
-                        (git-run-hook "post-commit" nil)))
-                  (message "Commit aborted."))))
-          (delete-file index-file))))))
-
-
-;;;; Interactive functions
-;;;; ------------------------------------------------------------
-
-(defun git-mark-file ()
-  "Mark the file that the cursor is on and move to the next one."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let* ((pos (ewoc-locate git-status))
-         (info (ewoc-data pos)))
-    (setf (git-fileinfo->marked info) t)
-    (ewoc-invalidate git-status pos)
-    (ewoc-goto-next git-status 1)))
-
-(defun git-unmark-file ()
-  "Unmark the file that the cursor is on and move to the next one."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let* ((pos (ewoc-locate git-status))
-         (info (ewoc-data pos)))
-    (setf (git-fileinfo->marked info) nil)
-    (ewoc-invalidate git-status pos)
-    (ewoc-goto-next git-status 1)))
-
-(defun git-unmark-file-up ()
-  "Unmark the file that the cursor is on and move to the previous one."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let* ((pos (ewoc-locate git-status))
-         (info (ewoc-data pos)))
-    (setf (git-fileinfo->marked info) nil)
-    (ewoc-invalidate git-status pos)
-    (ewoc-goto-prev git-status 1)))
-
-(defun git-mark-all ()
-  "Mark all files."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-map (lambda (info) (unless (git-fileinfo->marked info)
-                             (setf (git-fileinfo->marked info) t))) git-status)
-  ; move back to goal column after invalidate
-  (when goal-column (move-to-column goal-column)))
-
-(defun git-unmark-all ()
-  "Unmark all files."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-map (lambda (info) (when (git-fileinfo->marked info)
-                             (setf (git-fileinfo->marked info) nil)
-                             t)) git-status)
-  ; move back to goal column after invalidate
-  (when goal-column (move-to-column goal-column)))
-
-(defun git-toggle-all-marks ()
-  "Toggle all file marks."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-map (lambda (info) (setf (git-fileinfo->marked info) (not (git-fileinfo->marked info))) t) git-status)
-  ; move back to goal column after invalidate
-  (when goal-column (move-to-column goal-column)))
-
-(defun git-next-file (&optional n)
-  "Move the selection down N files."
-  (interactive "p")
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-goto-next git-status n))
-
-(defun git-prev-file (&optional n)
-  "Move the selection up N files."
-  (interactive "p")
-  (unless git-status (error "Not in git-status buffer."))
-  (ewoc-goto-prev git-status n))
-
-(defun git-next-unmerged-file (&optional n)
-  "Move the selection down N unmerged files."
-  (interactive "p")
-  (unless git-status (error "Not in git-status buffer."))
-  (let* ((last (ewoc-locate git-status))
-         (node (ewoc-next git-status last)))
-    (while (and node (> n 0))
-      (when (eq 'unmerged (git-fileinfo->state (ewoc-data node)))
-        (setq n (1- n))
-        (setq last node))
-      (setq node (ewoc-next git-status node)))
-    (ewoc-goto-node git-status last)))
-
-(defun git-prev-unmerged-file (&optional n)
-  "Move the selection up N unmerged files."
-  (interactive "p")
-  (unless git-status (error "Not in git-status buffer."))
-  (let* ((last (ewoc-locate git-status))
-         (node (ewoc-prev git-status last)))
-    (while (and node (> n 0))
-      (when (eq 'unmerged (git-fileinfo->state (ewoc-data node)))
-        (setq n (1- n))
-        (setq last node))
-      (setq node (ewoc-prev git-status node)))
-    (ewoc-goto-node git-status last)))
-
-(defun git-insert-file (file)
-  "Insert file(s) into the git-status buffer."
-  (interactive "fInsert file: ")
-  (git-update-status-files (list (file-relative-name file))))
-
-(defun git-add-file ()
-  "Add marked file(s) to the index cache."
-  (interactive)
-  (let ((files (git-get-filenames (git-marked-files-state 'unknown 'ignored 'unmerged))))
-    ;; FIXME: add support for directories
-    (unless files
-      (push (file-relative-name (read-file-name "File to add: " nil nil t)) files))
-    (when (apply 'git-call-process-display-error "update-index" "--add" "--" files)
-      (git-update-status-files files)
-      (git-success-message "Added" files))))
-
-(defun git-ignore-file ()
-  "Add marked file(s) to the ignore list."
-  (interactive)
-  (let ((files (git-get-filenames (git-marked-files-state 'unknown))))
-    (unless files
-      (push (file-relative-name (read-file-name "File to ignore: " nil nil t)) files))
-    (dolist (f files) (git-append-to-ignore f))
-    (git-update-status-files files)
-    (git-success-message "Ignored" files)))
-
-(defun git-remove-file ()
-  "Remove the marked file(s)."
-  (interactive)
-  (let ((files (git-get-filenames (git-marked-files-state 'added 'modified 'unknown 'uptodate 'ignored))))
-    (unless files
-      (push (file-relative-name (read-file-name "File to remove: " nil nil t)) files))
-    (if (yes-or-no-p
-         (if (cdr files)
-             (format "Remove %d files? " (length files))
-           (format "Remove %s? " (car files))))
-        (progn
-          (dolist (name files)
-            (ignore-errors
-              (if (file-directory-p name)
-                  (delete-directory name)
-                (delete-file name))))
-          (when (apply 'git-call-process-display-error "update-index" "--remove" "--" files)
-            (git-update-status-files files)
-            (git-success-message "Removed" files)))
-      (message "Aborting"))))
-
-(defun git-revert-file ()
-  "Revert changes to the marked file(s)."
-  (interactive)
-  (let ((files (git-marked-files-state 'added 'deleted 'modified 'unmerged))
-        added modified)
-    (when (and files
-               (yes-or-no-p
-                (if (cdr files)
-                    (format "Revert %d files? " (length files))
-                  (format "Revert %s? " (git-fileinfo->name (car files))))))
-      (dolist (info files)
-        (case (git-fileinfo->state info)
-          ('added (push (git-fileinfo->name info) added))
-          ('deleted (push (git-fileinfo->name info) modified))
-          ('unmerged (push (git-fileinfo->name info) modified))
-          ('modified (push (git-fileinfo->name info) modified))))
-      ;; check if a buffer contains one of the files and isn't saved
-      (dolist (file modified)
-        (let ((buffer (get-file-buffer file)))
-          (when (and buffer (buffer-modified-p buffer))
-            (error "Buffer %s is modified. Please kill or save modified buffers before reverting." (buffer-name buffer)))))
-      (let ((ok (and
-                 (or (not added)
-                     (apply 'git-call-process-display-error "update-index" "--force-remove" "--" added))
-                 (or (not modified)
-                     (apply 'git-call-process-display-error "checkout" "HEAD" modified))))
-            (names (git-get-filenames files)))
-        (git-update-status-files names)
-        (when ok
-          (dolist (file modified)
-            (let ((buffer (get-file-buffer file)))
-              (when buffer (with-current-buffer buffer (revert-buffer t t t)))))
-          (git-success-message "Reverted" names))))))
-
-(defun git-remove-handled ()
-  "Remove handled files from the status list."
-  (interactive)
-  (ewoc-filter git-status
-               (lambda (info)
-                 (case (git-fileinfo->state info)
-                   ('ignored git-show-ignored)
-                   ('uptodate git-show-uptodate)
-                   ('unknown git-show-unknown)
-                   (t t))))
-  (unless (ewoc-nth git-status 0)  ; refresh header if list is empty
-    (git-refresh-ewoc-hf git-status)))
-
-(defun git-toggle-show-uptodate ()
-  "Toogle the option for showing up-to-date files."
-  (interactive)
-  (if (setq git-show-uptodate (not git-show-uptodate))
-      (git-refresh-status)
-    (git-remove-handled)))
-
-(defun git-toggle-show-ignored ()
-  "Toogle the option for showing ignored files."
-  (interactive)
-  (if (setq git-show-ignored (not git-show-ignored))
-      (progn
-        (message "Inserting ignored files...")
-        (git-run-ls-files-with-excludes git-status nil 'ignored "-o" "-i")
-        (git-refresh-files)
-        (git-refresh-ewoc-hf git-status)
-        (message "Inserting ignored files...done"))
-    (git-remove-handled)))
-
-(defun git-toggle-show-unknown ()
-  "Toogle the option for showing unknown files."
-  (interactive)
-  (if (setq git-show-unknown (not git-show-unknown))
-      (progn
-        (message "Inserting unknown files...")
-        (git-run-ls-files-with-excludes git-status nil 'unknown "-o")
-        (git-refresh-files)
-        (git-refresh-ewoc-hf git-status)
-        (message "Inserting unknown files...done"))
-    (git-remove-handled)))
-
-(defun git-expand-directory (info)
-  "Expand the directory represented by INFO to list its files."
-  (when (eq (lsh (git-fileinfo->new-perm info) -9) ?\110)
-    (let ((dir (git-fileinfo->name info)))
-      (git-set-filenames-state git-status (list dir) nil)
-      (git-run-ls-files-with-excludes git-status (list (concat dir "/")) 'unknown "-o")
-      (git-refresh-files)
-      (git-refresh-ewoc-hf git-status)
-      t)))
-
-(defun git-setup-diff-buffer (buffer)
-  "Setup a buffer for displaying a diff."
-  (let ((dir default-directory))
-    (with-current-buffer buffer
-      (diff-mode)
-      (goto-char (point-min))
-      (setq default-directory dir)
-      (setq buffer-read-only t)))
-  (display-buffer buffer)
-  ; shrink window only if it displays the status buffer
-  (when (eq (window-buffer) (current-buffer))
-    (shrink-window-if-larger-than-buffer)))
-
-(defun git-diff-file ()
-  "Diff the marked file(s) against HEAD."
-  (interactive)
-  (let ((files (git-marked-files)))
-    (git-setup-diff-buffer
-     (apply #'git-run-command-buffer "*git-diff*" "diff-index" "-p" "-M" "HEAD" "--" (git-get-filenames files)))))
-
-(defun git-diff-file-merge-head (arg)
-  "Diff the marked file(s) against the first merge head (or the nth one with a numeric prefix)."
-  (interactive "p")
-  (let ((files (git-marked-files))
-        (merge-heads (git-get-merge-heads)))
-    (unless merge-heads (error "No merge in progress"))
-    (git-setup-diff-buffer
-     (apply #'git-run-command-buffer "*git-diff*" "diff-index" "-p" "-M"
-            (or (nth (1- arg) merge-heads) "HEAD") "--" (git-get-filenames files)))))
-
-(defun git-diff-unmerged-file (stage)
-  "Diff the marked unmerged file(s) against the specified stage."
-  (let ((files (git-marked-files)))
-    (git-setup-diff-buffer
-     (apply #'git-run-command-buffer "*git-diff*" "diff-files" "-p" stage "--" (git-get-filenames files)))))
-
-(defun git-diff-file-base ()
-  "Diff the marked unmerged file(s) against the common base file."
-  (interactive)
-  (git-diff-unmerged-file "-1"))
-
-(defun git-diff-file-mine ()
-  "Diff the marked unmerged file(s) against my pre-merge version."
-  (interactive)
-  (git-diff-unmerged-file "-2"))
-
-(defun git-diff-file-other ()
-  "Diff the marked unmerged file(s) against the other's pre-merge version."
-  (interactive)
-  (git-diff-unmerged-file "-3"))
-
-(defun git-diff-file-combined ()
-  "Do a combined diff of the marked unmerged file(s)."
-  (interactive)
-  (git-diff-unmerged-file "-c"))
-
-(defun git-diff-file-idiff ()
-  "Perform an interactive diff on the current file."
-  (interactive)
-  (let ((files (git-marked-files-state 'added 'deleted 'modified)))
-    (unless (eq 1 (length files))
-      (error "Cannot perform an interactive diff on multiple files."))
-    (let* ((filename (car (git-get-filenames files)))
-           (buff1 (find-file-noselect filename))
-           (buff2 (git-run-command-buffer (concat filename ".~HEAD~") "cat-file" "blob" (concat "HEAD:" filename))))
-      (ediff-buffers buff1 buff2))))
-
-(defun git-log-file ()
-  "Display a log of changes to the marked file(s)."
-  (interactive)
-  (let* ((files (git-marked-files))
-         (coding-system-for-read git-commits-coding-system)
-         (buffer (apply #'git-run-command-buffer "*git-log*" "rev-list" "--pretty" "HEAD" "--" (git-get-filenames files))))
-    (with-current-buffer buffer
-      ; (git-log-mode)  FIXME: implement log mode
-      (goto-char (point-min))
-      (setq buffer-read-only t))
-    (display-buffer buffer)))
-
-(defun git-log-edit-files ()
-  "Return a list of marked files for use in the log-edit buffer."
-  (with-current-buffer log-edit-parent-buffer
-    (git-get-filenames (git-marked-files-state 'added 'deleted 'modified))))
-
-(defun git-log-edit-diff ()
-  "Run a diff of the current files being committed from a log-edit buffer."
-  (with-current-buffer log-edit-parent-buffer
-    (git-diff-file)))
-
-(defun git-append-sign-off (name email)
-  "Append a Signed-off-by entry to the current buffer, avoiding duplicates."
-  (let ((sign-off (format "Signed-off-by: %s <%s>" name email))
-        (case-fold-search t))
-    (goto-char (point-min))
-    (unless (re-search-forward (concat "^" (regexp-quote sign-off)) nil t)
-      (goto-char (point-min))
-      (unless (re-search-forward "^Signed-off-by: " nil t)
-        (setq sign-off (concat "\n" sign-off)))
-      (goto-char (point-max))
-      (insert sign-off "\n"))))
-
-(defun git-setup-log-buffer (buffer &optional merge-heads author-name author-email subject date msg)
-  "Setup the log buffer for a commit."
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((dir default-directory)
-        (committer-name (git-get-committer-name))
-        (committer-email (git-get-committer-email))
-        (sign-off git-append-signed-off-by))
-    (with-current-buffer buffer
-      (cd dir)
-      (erase-buffer)
-      (insert
-       (propertize
-        (format "Author: %s <%s>\n%s%s"
-                (or author-name committer-name)
-                (or author-email committer-email)
-                (if date (format "Date: %s\n" date) "")
-                (if merge-heads
-                    (format "Merge: %s\n"
-                            (mapconcat 'identity merge-heads " "))
-                  ""))
-        'face 'git-header-face)
-       (propertize git-log-msg-separator 'face 'git-separator-face)
-       "\n")
-      (when subject (insert subject "\n\n"))
-      (cond (msg (insert msg "\n"))
-            ((file-readable-p ".git/rebase-apply/msg")
-             (insert-file-contents ".git/rebase-apply/msg"))
-            ((file-readable-p ".git/MERGE_MSG")
-             (insert-file-contents ".git/MERGE_MSG")))
-      ; delete empty lines at end
-      (goto-char (point-min))
-      (when (re-search-forward "\n+\\'" nil t)
-        (replace-match "\n" t t))
-      (when sign-off (git-append-sign-off committer-name committer-email)))
-    buffer))
-
-(define-derived-mode git-log-edit-mode log-edit-mode "Git-Log-Edit"
-  "Major mode for editing git log messages.
-
-Set up git-specific `font-lock-keywords' for `log-edit-mode'."
-  (set (make-local-variable 'font-lock-defaults)
-       '(git-log-edit-font-lock-keywords t t)))
-
-(defun git-commit-file ()
-  "Commit the marked file(s), asking for a commit message."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (when (git-run-pre-commit-hook)
-    (let ((buffer (get-buffer-create "*git-commit*"))
-          (coding-system (git-get-commits-coding-system))
-          author-name author-email subject date)
-      (when (eq 0 (buffer-size buffer))
-        (when (file-readable-p ".git/rebase-apply/info")
-          (with-temp-buffer
-            (insert-file-contents ".git/rebase-apply/info")
-            (goto-char (point-min))
-            (when (re-search-forward "^Author: \\(.*\\)\nEmail: \\(.*\\)$" nil t)
-              (setq author-name (match-string 1))
-              (setq author-email (match-string 2)))
-            (goto-char (point-min))
-            (when (re-search-forward "^Subject: \\(.*\\)$" nil t)
-              (setq subject (match-string 1)))
-            (goto-char (point-min))
-            (when (re-search-forward "^Date: \\(.*\\)$" nil t)
-              (setq date (match-string 1)))))
-        (git-setup-log-buffer buffer (git-get-merge-heads) author-name author-email subject date))
-      (if (boundp 'log-edit-diff-function)
-         (log-edit 'git-do-commit nil '((log-edit-listfun . git-log-edit-files)
-                                        (log-edit-diff-function . git-log-edit-diff)) buffer 'git-log-edit-mode)
-       (log-edit 'git-do-commit nil 'git-log-edit-files buffer
-                  'git-log-edit-mode))
-      (setq paragraph-separate (concat (regexp-quote git-log-msg-separator) "$\\|Author: \\|Date: \\|Merge: \\|Signed-off-by: \\|\f\\|[        ]*$"))
-      (setq buffer-file-coding-system coding-system)
-      (re-search-forward (regexp-quote (concat git-log-msg-separator "\n")) nil t))))
-
-(defun git-setup-commit-buffer (commit)
-  "Setup the commit buffer with the contents of COMMIT."
-  (let (parents author-name author-email subject date msg)
-    (with-temp-buffer
-      (let ((coding-system (git-get-logoutput-coding-system)))
-        (git-call-process t "log" "-1" "--pretty=medium" "--abbrev=40" commit)
-        (goto-char (point-min))
-        (when (re-search-forward "^Merge: *\\(.*\\)$" nil t)
-          (setq parents (cdr (split-string (match-string 1) " +"))))
-        (when (re-search-forward "^Author: *\\(.*\\) <\\(.*\\)>$" nil t)
-          (setq author-name (match-string 1))
-          (setq author-email (match-string 2)))
-        (when (re-search-forward "^Date: *\\(.*\\)$" nil t)
-          (setq date (match-string 1)))
-        (while (re-search-forward "^    \\(.*\\)$" nil t)
-          (push (match-string 1) msg))
-        (setq msg (nreverse msg))
-        (setq subject (pop msg))
-        (while (and msg (zerop (length (car msg))) (pop msg)))))
-    (git-setup-log-buffer (get-buffer-create "*git-commit*")
-                          parents author-name author-email subject date
-                          (mapconcat #'identity msg "\n"))))
-
-(defun git-get-commit-files (commit)
-  "Retrieve a sorted list of files modified by COMMIT."
-  (let (files)
-    (with-temp-buffer
-      (git-call-process t "diff-tree" "-m" "-r" "-z" "--name-only" "--no-commit-id" "--root" commit)
-      (goto-char (point-min))
-      (while (re-search-forward "\\([^\0]*\\)\0" nil t 1)
-        (push (match-string 1) files)))
-    (sort files #'string-lessp)))
-
-(defun git-read-commit-name (prompt &optional default)
-  "Ask for a commit name, with completion for local branch, remote branch and tag."
-  (completing-read prompt
-                   (list* "HEAD" "ORIG_HEAD" "FETCH_HEAD" (mapcar #'car (git-for-each-ref)))
-                  nil nil nil nil default))
-
-(defun git-checkout (branch &optional merge)
-  "Checkout a branch, tag, or any commit.
-Use a prefix arg if git should merge while checking out."
-  (interactive
-   (list (git-read-commit-name "Checkout: ")
-         current-prefix-arg))
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((args (list branch "--")))
-    (when merge (push "-m" args))
-    (when (apply #'git-call-process-display-error "checkout" args)
-      (git-update-status-files))))
-
-(defun git-branch (branch)
-  "Create a branch from the current HEAD and switch to it."
-  (interactive (list (git-read-commit-name "Branch: ")))
-  (unless git-status (error "Not in git-status buffer."))
-  (if (git-rev-parse (concat "refs/heads/" branch))
-      (if (yes-or-no-p (format "Branch %s already exists, replace it? " branch))
-          (and (git-call-process-display-error "branch" "-f" branch)
-               (git-call-process-display-error "checkout" branch))
-        (message "Canceled."))
-    (git-call-process-display-error "checkout" "-b" branch))
-    (git-refresh-ewoc-hf git-status))
-
-(defun git-amend-commit ()
-  "Undo the last commit on HEAD, and set things up to commit an
-amended version of it."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (when (git-empty-db-p) (error "No commit to amend."))
-  (let* ((commit (git-rev-parse "HEAD"))
-         (files (git-get-commit-files commit)))
-    (when (if (git-rev-parse "HEAD^")
-              (git-call-process-display-error "reset" "--soft" "HEAD^")
-            (and (git-update-ref "ORIG_HEAD" commit)
-                 (git-update-ref "HEAD" nil commit)))
-      (git-update-status-files files t)
-      (git-setup-commit-buffer commit)
-      (git-commit-file))))
-
-(defun git-cherry-pick-commit (arg)
-  "Cherry-pick a commit."
-  (interactive (list (git-read-commit-name "Cherry-pick commit: ")))
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((commit (git-rev-parse (concat arg "^0"))))
-    (unless commit (error "Not a valid commit '%s'." arg))
-    (when (git-rev-parse (concat commit "^2"))
-      (error "Cannot cherry-pick a merge commit."))
-    (let ((files (git-get-commit-files commit))
-          (ok (git-call-process-display-error "cherry-pick" "-n" commit)))
-      (git-update-status-files files ok)
-      (with-current-buffer (git-setup-commit-buffer commit)
-        (goto-char (point-min))
-        (if (re-search-forward "^\n*Signed-off-by:" nil t 1)
-            (goto-char (match-beginning 0))
-          (goto-char (point-max)))
-        (insert "(cherry picked from commit " commit ")\n"))
-      (when ok (git-commit-file)))))
-
-(defun git-revert-commit (arg)
-  "Revert a commit."
-  (interactive (list (git-read-commit-name "Revert commit: ")))
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((commit (git-rev-parse (concat arg "^0"))))
-    (unless commit (error "Not a valid commit '%s'." arg))
-    (when (git-rev-parse (concat commit "^2"))
-      (error "Cannot revert a merge commit."))
-    (let ((files (git-get-commit-files commit))
-          (subject (git-get-commit-description commit))
-          (ok (git-call-process-display-error "revert" "-n" commit)))
-      (git-update-status-files files ok)
-      (when (string-match "^[0-9a-f]+ - \\(.*\\)$" subject)
-        (setq subject (match-string 1 subject)))
-      (git-setup-log-buffer (get-buffer-create "*git-commit*")
-                            (git-get-merge-heads) nil nil (format "Revert \"%s\"" subject) nil
-                            (format "This reverts commit %s.\n" commit))
-      (when ok (git-commit-file)))))
-
-(defun git-find-file ()
-  "Visit the current file in its own buffer."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((info (ewoc-data (ewoc-locate git-status))))
-    (unless (git-expand-directory info)
-      (find-file (git-fileinfo->name info))
-      (when (eq 'unmerged (git-fileinfo->state info))
-        (smerge-mode 1)))))
-
-(defun git-find-file-other-window ()
-  "Visit the current file in its own buffer in another window."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((info (ewoc-data (ewoc-locate git-status))))
-    (find-file-other-window (git-fileinfo->name info))
-    (when (eq 'unmerged (git-fileinfo->state info))
-      (smerge-mode))))
-
-(defun git-find-file-imerge ()
-  "Visit the current file in interactive merge mode."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((info (ewoc-data (ewoc-locate git-status))))
-    (find-file (git-fileinfo->name info))
-    (smerge-ediff)))
-
-(defun git-view-file ()
-  "View the current file in its own buffer."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (let ((info (ewoc-data (ewoc-locate git-status))))
-    (view-file (git-fileinfo->name info))))
-
-(defun git-refresh-status ()
-  "Refresh the git status buffer."
-  (interactive)
-  (unless git-status (error "Not in git-status buffer."))
-  (message "Refreshing git status...")
-  (git-update-status-files)
-  (message "Refreshing git status...done"))
-
-(defun git-status-quit ()
-  "Quit git-status mode."
-  (interactive)
-  (bury-buffer))
-
-;;;; Major Mode
-;;;; ------------------------------------------------------------
-
-(defvar git-status-mode-hook nil
-  "Run after `git-status-mode' is setup.")
-
-(defvar git-status-mode-map nil
-  "Keymap for git major mode.")
-
-(defvar git-status nil
-  "List of all files managed by the git-status mode.")
-
-(unless git-status-mode-map
-  (let ((map (make-keymap))
-        (commit-map (make-sparse-keymap))
-        (diff-map (make-sparse-keymap))
-        (toggle-map (make-sparse-keymap)))
-    (suppress-keymap map)
-    (define-key map "?"   'git-help)
-    (define-key map "h"   'git-help)
-    (define-key map " "   'git-next-file)
-    (define-key map "a"   'git-add-file)
-    (define-key map "c"   'git-commit-file)
-    (define-key map "\C-c" commit-map)
-    (define-key map "d"    diff-map)
-    (define-key map "="   'git-diff-file)
-    (define-key map "f"   'git-find-file)
-    (define-key map "\r"  'git-find-file)
-    (define-key map "g"   'git-refresh-status)
-    (define-key map "i"   'git-ignore-file)
-    (define-key map "I"   'git-insert-file)
-    (define-key map "l"   'git-log-file)
-    (define-key map "m"   'git-mark-file)
-    (define-key map "M"   'git-mark-all)
-    (define-key map "n"   'git-next-file)
-    (define-key map "N"   'git-next-unmerged-file)
-    (define-key map "o"   'git-find-file-other-window)
-    (define-key map "p"   'git-prev-file)
-    (define-key map "P"   'git-prev-unmerged-file)
-    (define-key map "q"   'git-status-quit)
-    (define-key map "r"   'git-remove-file)
-    (define-key map "t"    toggle-map)
-    (define-key map "T"   'git-toggle-all-marks)
-    (define-key map "u"   'git-unmark-file)
-    (define-key map "U"   'git-revert-file)
-    (define-key map "v"   'git-view-file)
-    (define-key map "x"   'git-remove-handled)
-    (define-key map "\C-?" 'git-unmark-file-up)
-    (define-key map "\M-\C-?" 'git-unmark-all)
-    ; the commit submap
-    (define-key commit-map "\C-a" 'git-amend-commit)
-    (define-key commit-map "\C-b" 'git-branch)
-    (define-key commit-map "\C-o" 'git-checkout)
-    (define-key commit-map "\C-p" 'git-cherry-pick-commit)
-    (define-key commit-map "\C-v" 'git-revert-commit)
-    ; the diff submap
-    (define-key diff-map "b" 'git-diff-file-base)
-    (define-key diff-map "c" 'git-diff-file-combined)
-    (define-key diff-map "=" 'git-diff-file)
-    (define-key diff-map "e" 'git-diff-file-idiff)
-    (define-key diff-map "E" 'git-find-file-imerge)
-    (define-key diff-map "h" 'git-diff-file-merge-head)
-    (define-key diff-map "m" 'git-diff-file-mine)
-    (define-key diff-map "o" 'git-diff-file-other)
-    ; the toggle submap
-    (define-key toggle-map "u" 'git-toggle-show-uptodate)
-    (define-key toggle-map "i" 'git-toggle-show-ignored)
-    (define-key toggle-map "k" 'git-toggle-show-unknown)
-    (define-key toggle-map "m" 'git-toggle-all-marks)
-    (setq git-status-mode-map map))
-  (easy-menu-define git-menu git-status-mode-map
-    "Git Menu"
-    `("Git"
-      ["Refresh" git-refresh-status t]
-      ["Commit" git-commit-file t]
-      ["Checkout..." git-checkout t]
-      ["New Branch..." git-branch t]
-      ["Cherry-pick Commit..." git-cherry-pick-commit t]
-      ["Revert Commit..." git-revert-commit t]
-      ("Merge"
-       ["Next Unmerged File" git-next-unmerged-file t]
-       ["Prev Unmerged File" git-prev-unmerged-file t]
-       ["Interactive Merge File" git-find-file-imerge t]
-       ["Diff Against Common Base File" git-diff-file-base t]
-       ["Diff Combined" git-diff-file-combined t]
-       ["Diff Against Merge Head" git-diff-file-merge-head t]
-       ["Diff Against Mine" git-diff-file-mine t]
-       ["Diff Against Other" git-diff-file-other t])
-      "--------"
-      ["Add File" git-add-file t]
-      ["Revert File" git-revert-file t]
-      ["Ignore File" git-ignore-file t]
-      ["Remove File" git-remove-file t]
-      ["Insert File" git-insert-file t]
-      "--------"
-      ["Find File" git-find-file t]
-      ["View File" git-view-file t]
-      ["Diff File" git-diff-file t]
-      ["Interactive Diff File" git-diff-file-idiff t]
-      ["Log" git-log-file t]
-      "--------"
-      ["Mark" git-mark-file t]
-      ["Mark All" git-mark-all t]
-      ["Unmark" git-unmark-file t]
-      ["Unmark All" git-unmark-all t]
-      ["Toggle All Marks" git-toggle-all-marks t]
-      ["Hide Handled Files" git-remove-handled t]
-      "--------"
-      ["Show Uptodate Files" git-toggle-show-uptodate :style toggle :selected git-show-uptodate]
-      ["Show Ignored Files" git-toggle-show-ignored :style toggle :selected git-show-ignored]
-      ["Show Unknown Files" git-toggle-show-unknown :style toggle :selected git-show-unknown]
-      "--------"
-      ["Quit" git-status-quit t])))
-
-
-;; git mode should only run in the *git status* buffer
-(put 'git-status-mode 'mode-class 'special)
-
-(defun git-status-mode ()
-  "Major mode for interacting with Git.
-Commands:
-\\{git-status-mode-map}"
-  (kill-all-local-variables)
-  (buffer-disable-undo)
-  (setq mode-name "git status"
-        major-mode 'git-status-mode
-        goal-column 17
-        buffer-read-only t)
-  (use-local-map git-status-mode-map)
-  (let ((buffer-read-only nil))
-    (erase-buffer)
-  (let ((status (ewoc-create 'git-fileinfo-prettyprint "" "")))
-    (set (make-local-variable 'git-status) status))
-  (set (make-local-variable 'list-buffers-directory) default-directory)
-  (make-local-variable 'git-show-uptodate)
-  (make-local-variable 'git-show-ignored)
-  (make-local-variable 'git-show-unknown)
-  (run-hooks 'git-status-mode-hook)))
-
-(defun git-find-status-buffer (dir)
-  "Find the git status buffer handling a specified directory."
-  (let ((list (buffer-list))
-        (fulldir (expand-file-name dir))
-        found)
-    (while (and list (not found))
-      (let ((buffer (car list)))
-        (with-current-buffer buffer
-          (when (and list-buffers-directory
-                     (string-equal fulldir (expand-file-name list-buffers-directory))
-                    (eq major-mode 'git-status-mode))
-            (setq found buffer))))
-      (setq list (cdr list)))
-    found))
-
-(defun git-status (dir)
-  "Entry point into git-status mode."
-  (interactive "DSelect directory: ")
-  (setq dir (git-get-top-dir dir))
-  (if (file-exists-p (concat (file-name-as-directory dir) ".git"))
-      (let ((buffer (or (and git-reuse-status-buffer (git-find-status-buffer dir))
-                        (create-file-buffer (expand-file-name "*git-status*" dir)))))
-        (switch-to-buffer buffer)
-        (cd dir)
-        (git-status-mode)
-        (git-refresh-status)
-        (goto-char (point-min))
-        (add-hook 'after-save-hook 'git-update-saved-file))
-    (message "%s is not a git working tree." dir)))
-
-(defun git-update-saved-file ()
-  "Update the corresponding git-status buffer when a file is saved.
-Meant to be used in `after-save-hook'."
-  (let* ((file (expand-file-name buffer-file-name))
-         (dir (condition-case nil (git-get-top-dir (file-name-directory file)) (error nil)))
-         (buffer (and dir (git-find-status-buffer dir))))
-    (when buffer
-      (with-current-buffer buffer
-        (let ((filename (file-relative-name file dir)))
-          ; skip files located inside the .git directory
-          (unless (string-match "^\\.git/" filename)
-            (git-call-process nil "add" "--refresh" "--" filename)
-            (git-update-status-files (list filename))))))))
-
-(defun git-help ()
-  "Display help for Git mode."
-  (interactive)
-  (describe-function 'git-status-mode))
-
-(provide 'git)
-;;; git.el ends here
+(error "git.el no longer ships with git. It's recommended to
+replace its use with Magit, or simply delete references to git.el
+in your initialization file(s). See contrib/emacs/README in git's
+sources (https://github.com/git/git/blob/master/contrib/emacs/README)
+for suggested alternatives and for why this happened. Emacs's own
+VC mode and Magit are viable alternatives.")
index 6946f3dd2ad924639f03b3779635c759c938c1e4..18bc60b021be00f69d2b5a784996bbc1e98c82c1 100644 (file)
@@ -1,3 +1,20 @@
-These are original scripted implementations, kept primarily for their
-reference value to any aspiring plumbing users who want to learn how
-pieces can be fit together.
+This directory used to contain scripted implementations of builtins
+that have since been rewritten in C.
+
+They have now been removed, but can be retrieved from an older commit
+that removed them from this directory.
+
+They're interesting for their reference value to any aspiring plumbing
+users who want to learn how pieces can be fit together, but in many
+cases have drifted enough from the actual implementations Git uses to
+be instructive.
+
+Other things that can be useful:
+
+ * Some commands such as git-gc wrap other commands, and what they're
+   doing behind the scenes can be seen by running them under
+   GIT_TRACE=1
+
+ * Doing `git log` on paths matching '*--helper.c' will show
+   incremental effort in the direction of moving existing shell
+   scripts to C.
diff --git a/contrib/examples/builtin-fetch--tool.c b/contrib/examples/builtin-fetch--tool.c
deleted file mode 100644 (file)
index 22648c3..0000000
+++ /dev/null
@@ -1,575 +0,0 @@
-#include "builtin.h"
-#include "cache.h"
-#include "refs.h"
-#include "commit.h"
-#include "sigchain.h"
-
-static char *get_stdin(void)
-{
-       struct strbuf buf = STRBUF_INIT;
-       if (strbuf_read(&buf, 0, 1024) < 0) {
-               die_errno("error reading standard input");
-       }
-       return strbuf_detach(&buf, NULL);
-}
-
-static void show_new(enum object_type type, unsigned char *sha1_new)
-{
-       fprintf(stderr, "  %s: %s\n", type_name(type),
-               find_unique_abbrev(sha1_new, DEFAULT_ABBREV));
-}
-
-static int update_ref_env(const char *action,
-                     const char *refname,
-                     unsigned char *sha1,
-                     unsigned char *oldval)
-{
-       char msg[1024];
-       const char *rla = getenv("GIT_REFLOG_ACTION");
-
-       if (!rla)
-               rla = "(reflog update)";
-       if (snprintf(msg, sizeof(msg), "%s: %s", rla, action) >= sizeof(msg))
-               warning("reflog message too long: %.*s...", 50, msg);
-       return update_ref(msg, refname, sha1, oldval, 0,
-                         UPDATE_REFS_QUIET_ON_ERR);
-}
-
-static int update_local_ref(const char *name,
-                           const char *new_head,
-                           const char *note,
-                           int verbose, int force)
-{
-       unsigned char sha1_old[20], sha1_new[20];
-       char oldh[41], newh[41];
-       struct commit *current, *updated;
-       enum object_type type;
-
-       if (get_sha1_hex(new_head, sha1_new))
-               die("malformed object name %s", new_head);
-
-       type = sha1_object_info(sha1_new, NULL);
-       if (type < 0)
-               die("object %s not found", new_head);
-
-       if (!*name) {
-               /* Not storing */
-               if (verbose) {
-                       fprintf(stderr, "* fetched %s\n", note);
-                       show_new(type, sha1_new);
-               }
-               return 0;
-       }
-
-       if (get_sha1(name, sha1_old)) {
-               const char *msg;
-       just_store:
-               /* new ref */
-               if (!strncmp(name, "refs/tags/", 10))
-                       msg = "storing tag";
-               else
-                       msg = "storing head";
-               fprintf(stderr, "* %s: storing %s\n",
-                       name, note);
-               show_new(type, sha1_new);
-               return update_ref_env(msg, name, sha1_new, NULL);
-       }
-
-       if (!hashcmp(sha1_old, sha1_new)) {
-               if (verbose) {
-                       fprintf(stderr, "* %s: same as %s\n", name, note);
-                       show_new(type, sha1_new);
-               }
-               return 0;
-       }
-
-       if (!strncmp(name, "refs/tags/", 10)) {
-               fprintf(stderr, "* %s: updating with %s\n", name, note);
-               show_new(type, sha1_new);
-               return update_ref_env("updating tag", name, sha1_new, NULL);
-       }
-
-       current = lookup_commit_reference(sha1_old);
-       updated = lookup_commit_reference(sha1_new);
-       if (!current || !updated)
-               goto just_store;
-
-       strcpy(oldh, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
-       strcpy(newh, find_unique_abbrev(sha1_new, DEFAULT_ABBREV));
-
-       if (in_merge_bases(current, updated)) {
-               fprintf(stderr, "* %s: fast-forward to %s\n",
-                       name, note);
-               fprintf(stderr, "  old..new: %s..%s\n", oldh, newh);
-               return update_ref_env("fast-forward", name, sha1_new, sha1_old);
-       }
-       if (!force) {
-               fprintf(stderr,
-                       "* %s: not updating to non-fast-forward %s\n",
-                       name, note);
-               fprintf(stderr,
-                       "  old...new: %s...%s\n", oldh, newh);
-               return 1;
-       }
-       fprintf(stderr,
-               "* %s: forcing update to non-fast-forward %s\n",
-               name, note);
-       fprintf(stderr, "  old...new: %s...%s\n", oldh, newh);
-       return update_ref_env("forced-update", name, sha1_new, sha1_old);
-}
-
-static int append_fetch_head(FILE *fp,
-                            const char *head, const char *remote,
-                            const char *remote_name, const char *remote_nick,
-                            const char *local_name, int not_for_merge,
-                            int verbose, int force)
-{
-       struct commit *commit;
-       int remote_len, i, note_len;
-       unsigned char sha1[20];
-       char note[1024];
-       const char *what, *kind;
-
-       if (get_sha1(head, sha1))
-               return error("Not a valid object name: %s", head);
-       commit = lookup_commit_reference_gently(sha1, 1);
-       if (!commit)
-               not_for_merge = 1;
-
-       if (!strcmp(remote_name, "HEAD")) {
-               kind = "";
-               what = "";
-       }
-       else if (!strncmp(remote_name, "refs/heads/", 11)) {
-               kind = "branch";
-               what = remote_name + 11;
-       }
-       else if (!strncmp(remote_name, "refs/tags/", 10)) {
-               kind = "tag";
-               what = remote_name + 10;
-       }
-       else if (!strncmp(remote_name, "refs/remotes/", 13)) {
-               kind = "remote-tracking branch";
-               what = remote_name + 13;
-       }
-       else {
-               kind = "";
-               what = remote_name;
-       }
-
-       remote_len = strlen(remote);
-       for (i = remote_len - 1; remote[i] == '/' && 0 <= i; i--)
-               ;
-       remote_len = i + 1;
-       if (4 < i && !strncmp(".git", remote + i - 3, 4))
-               remote_len = i - 3;
-
-       note_len = 0;
-       if (*what) {
-               if (*kind)
-                       note_len += sprintf(note + note_len, "%s ", kind);
-               note_len += sprintf(note + note_len, "'%s' of ", what);
-       }
-       note_len += sprintf(note + note_len, "%.*s", remote_len, remote);
-       fprintf(fp, "%s\t%s\t%s\n",
-               sha1_to_hex(commit ? commit->object.sha1 : sha1),
-               not_for_merge ? "not-for-merge" : "",
-               note);
-       return update_local_ref(local_name, head, note, verbose, force);
-}
-
-static char *keep;
-static void remove_keep(void)
-{
-       if (keep && *keep)
-               unlink(keep);
-}
-
-static void remove_keep_on_signal(int signo)
-{
-       remove_keep();
-       sigchain_pop(signo);
-       raise(signo);
-}
-
-static char *find_local_name(const char *remote_name, const char *refs,
-                            int *force_p, int *not_for_merge_p)
-{
-       const char *ref = refs;
-       int len = strlen(remote_name);
-
-       while (ref) {
-               const char *next;
-               int single_force, not_for_merge;
-
-               while (*ref == '\n')
-                       ref++;
-               if (!*ref)
-                       break;
-               next = strchr(ref, '\n');
-
-               single_force = not_for_merge = 0;
-               if (*ref == '+') {
-                       single_force = 1;
-                       ref++;
-               }
-               if (*ref == '.') {
-                       not_for_merge = 1;
-                       ref++;
-                       if (*ref == '+') {
-                               single_force = 1;
-                               ref++;
-                       }
-               }
-               if (!strncmp(remote_name, ref, len) && ref[len] == ':') {
-                       const char *local_part = ref + len + 1;
-                       int retlen;
-
-                       if (!next)
-                               retlen = strlen(local_part);
-                       else
-                               retlen = next - local_part;
-                       *force_p = single_force;
-                       *not_for_merge_p = not_for_merge;
-                       return xmemdupz(local_part, retlen);
-               }
-               ref = next;
-       }
-       return NULL;
-}
-
-static int fetch_native_store(FILE *fp,
-                             const char *remote,
-                             const char *remote_nick,
-                             const char *refs,
-                             int verbose, int force)
-{
-       char buffer[1024];
-       int err = 0;
-
-       sigchain_push_common(remove_keep_on_signal);
-       atexit(remove_keep);
-
-       while (fgets(buffer, sizeof(buffer), stdin)) {
-               int len;
-               char *cp;
-               char *local_name;
-               int single_force, not_for_merge;
-
-               for (cp = buffer; *cp && !isspace(*cp); cp++)
-                       ;
-               if (*cp)
-                       *cp++ = 0;
-               len = strlen(cp);
-               if (len && cp[len-1] == '\n')
-                       cp[--len] = 0;
-               if (!strcmp(buffer, "failed"))
-                       die("Fetch failure: %s", remote);
-               if (!strcmp(buffer, "pack"))
-                       continue;
-               if (!strcmp(buffer, "keep")) {
-                       char *od = get_object_directory();
-                       int len = strlen(od) + strlen(cp) + 50;
-                       keep = xmalloc(len);
-                       sprintf(keep, "%s/pack/pack-%s.keep", od, cp);
-                       continue;
-               }
-
-               local_name = find_local_name(cp, refs,
-                                            &single_force, &not_for_merge);
-               if (!local_name)
-                       continue;
-               err |= append_fetch_head(fp,
-                                        buffer, remote, cp, remote_nick,
-                                        local_name, not_for_merge,
-                                        verbose, force || single_force);
-       }
-       return err;
-}
-
-static int parse_reflist(const char *reflist)
-{
-       const char *ref;
-
-       printf("refs='");
-       for (ref = reflist; ref; ) {
-               const char *next;
-               while (*ref && isspace(*ref))
-                       ref++;
-               if (!*ref)
-                       break;
-               for (next = ref; *next && !isspace(*next); next++)
-                       ;
-               printf("\n%.*s", (int)(next - ref), ref);
-               ref = next;
-       }
-       printf("'\n");
-
-       printf("rref='");
-       for (ref = reflist; ref; ) {
-               const char *next, *colon;
-               while (*ref && isspace(*ref))
-                       ref++;
-               if (!*ref)
-                       break;
-               for (next = ref; *next && !isspace(*next); next++)
-                       ;
-               if (*ref == '.')
-                       ref++;
-               if (*ref == '+')
-                       ref++;
-               colon = strchr(ref, ':');
-               putchar('\n');
-               printf("%.*s", (int)((colon ? colon : next) - ref), ref);
-               ref = next;
-       }
-       printf("'\n");
-       return 0;
-}
-
-static int expand_refs_wildcard(const char *ls_remote_result, int numrefs,
-                               const char **refs)
-{
-       int i, matchlen, replacelen;
-       int found_one = 0;
-       const char *remote = *refs++;
-       numrefs--;
-
-       if (numrefs == 0) {
-               fprintf(stderr, "Nothing specified for fetching with remote.%s.fetch\n",
-                       remote);
-               printf("empty\n");
-       }
-
-       for (i = 0; i < numrefs; i++) {
-               const char *ref = refs[i];
-               const char *lref = ref;
-               const char *colon;
-               const char *tail;
-               const char *ls;
-               const char *next;
-
-               if (*lref == '+')
-                       lref++;
-               colon = strchr(lref, ':');
-               tail = lref + strlen(lref);
-               if (!(colon &&
-                     2 < colon - lref &&
-                     colon[-1] == '*' &&
-                     colon[-2] == '/' &&
-                     2 < tail - (colon + 1) &&
-                     tail[-1] == '*' &&
-                     tail[-2] == '/')) {
-                       /* not a glob */
-                       if (!found_one++)
-                               printf("explicit\n");
-                       printf("%s\n", ref);
-                       continue;
-               }
-
-               /* glob */
-               if (!found_one++)
-                       printf("glob\n");
-
-               /* lref to colon-2 is remote hierarchy name;
-                * colon+1 to tail-2 is local.
-                */
-               matchlen = (colon-1) - lref;
-               replacelen = (tail-1) - (colon+1);
-               for (ls = ls_remote_result; ls; ls = next) {
-                       const char *eol;
-                       unsigned char sha1[20];
-                       int namelen;
-
-                       while (*ls && isspace(*ls))
-                               ls++;
-                       next = strchr(ls, '\n');
-                       eol = !next ? (ls + strlen(ls)) : next;
-                       if (!memcmp("^{}", eol-3, 3))
-                               continue;
-                       if (eol - ls < 40)
-                               continue;
-                       if (get_sha1_hex(ls, sha1))
-                               continue;
-                       ls += 40;
-                       while (ls < eol && isspace(*ls))
-                               ls++;
-                       /* ls to next (or eol) is the name.
-                        * is it identical to lref to colon-2?
-                        */
-                       if ((eol - ls) <= matchlen ||
-                           strncmp(ls, lref, matchlen))
-                               continue;
-
-                       /* Yes, it is a match */
-                       namelen = eol - ls;
-                       if (lref != ref)
-                               putchar('+');
-                       printf("%.*s:%.*s%.*s\n",
-                              namelen, ls,
-                              replacelen, colon + 1,
-                              namelen - matchlen, ls + matchlen);
-               }
-       }
-       return 0;
-}
-
-static int pick_rref(int sha1_only, const char *rref, const char *ls_remote_result)
-{
-       int err = 0;
-       int lrr_count = lrr_count, i, pass;
-       const char *cp;
-       struct lrr {
-               const char *line;
-               const char *name;
-               int namelen;
-               int shown;
-       } *lrr_list = lrr_list;
-
-       for (pass = 0; pass < 2; pass++) {
-               /* pass 0 counts and allocates, pass 1 fills... */
-               cp = ls_remote_result;
-               i = 0;
-               while (1) {
-                       const char *np;
-                       while (*cp && isspace(*cp))
-                               cp++;
-                       if (!*cp)
-                               break;
-                       np = strchrnul(cp, '\n');
-                       if (pass) {
-                               lrr_list[i].line = cp;
-                               lrr_list[i].name = cp + 41;
-                               lrr_list[i].namelen = np - (cp + 41);
-                       }
-                       i++;
-                       cp = np;
-               }
-               if (!pass) {
-                       lrr_count = i;
-                       lrr_list = xcalloc(lrr_count, sizeof(*lrr_list));
-               }
-       }
-
-       while (1) {
-               const char *next;
-               int rreflen;
-               int i;
-
-               while (*rref && isspace(*rref))
-                       rref++;
-               if (!*rref)
-                       break;
-               next = strchrnul(rref, '\n');
-               rreflen = next - rref;
-
-               for (i = 0; i < lrr_count; i++) {
-                       struct lrr *lrr = &(lrr_list[i]);
-
-                       if (rreflen == lrr->namelen &&
-                           !memcmp(lrr->name, rref, rreflen)) {
-                               if (!lrr->shown)
-                                       printf("%.*s\n",
-                                              sha1_only ? 40 : lrr->namelen + 41,
-                                              lrr->line);
-                               lrr->shown = 1;
-                               break;
-                       }
-               }
-               if (lrr_count <= i) {
-                       error("pick-rref: %.*s not found", rreflen, rref);
-                       err = 1;
-               }
-               rref = next;
-       }
-       free(lrr_list);
-       return err;
-}
-
-int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
-{
-       int verbose = 0;
-       int force = 0;
-       int sopt = 0;
-
-       while (1 < argc) {
-               const char *arg = argv[1];
-               if (!strcmp("-v", arg))
-                       verbose = 1;
-               else if (!strcmp("-f", arg))
-                       force = 1;
-               else if (!strcmp("-s", arg))
-                       sopt = 1;
-               else
-                       break;
-               argc--;
-               argv++;
-       }
-
-       if (argc <= 1)
-               return error("Missing subcommand");
-
-       if (!strcmp("append-fetch-head", argv[1])) {
-               int result;
-               FILE *fp;
-               char *filename;
-
-               if (argc != 8)
-                       return error("append-fetch-head takes 6 args");
-               filename = git_path_fetch_head();
-               fp = fopen(filename, "a");
-               if (!fp)
-                       return error("cannot open %s: %s", filename, strerror(errno));
-               result = append_fetch_head(fp, argv[2], argv[3],
-                                          argv[4], argv[5],
-                                          argv[6], !!argv[7][0],
-                                          verbose, force);
-               fclose(fp);
-               return result;
-       }
-       if (!strcmp("native-store", argv[1])) {
-               int result;
-               FILE *fp;
-               char *filename;
-
-               if (argc != 5)
-                       return error("fetch-native-store takes 3 args");
-               filename = git_path_fetch_head();
-               fp = fopen(filename, "a");
-               if (!fp)
-                       return error("cannot open %s: %s", filename, strerror(errno));
-               result = fetch_native_store(fp, argv[2], argv[3], argv[4],
-                                           verbose, force);
-               fclose(fp);
-               return result;
-       }
-       if (!strcmp("parse-reflist", argv[1])) {
-               const char *reflist;
-               if (argc != 3)
-                       return error("parse-reflist takes 1 arg");
-               reflist = argv[2];
-               if (!strcmp(reflist, "-"))
-                       reflist = get_stdin();
-               return parse_reflist(reflist);
-       }
-       if (!strcmp("pick-rref", argv[1])) {
-               const char *ls_remote_result;
-               if (argc != 4)
-                       return error("pick-rref takes 2 args");
-               ls_remote_result = argv[3];
-               if (!strcmp(ls_remote_result, "-"))
-                       ls_remote_result = get_stdin();
-               return pick_rref(sopt, argv[2], ls_remote_result);
-       }
-       if (!strcmp("expand-refs-wildcard", argv[1])) {
-               const char *reflist;
-               if (argc < 4)
-                       return error("expand-refs-wildcard takes at least 2 args");
-               reflist = argv[2];
-               if (!strcmp(reflist, "-"))
-                       reflist = get_stdin();
-               return expand_refs_wildcard(reflist, argc - 3, argv + 3);
-       }
-
-       return error("Unknown subcommand: %s", argv[1]);
-}
diff --git a/contrib/examples/git-am.sh b/contrib/examples/git-am.sh
deleted file mode 100755 (executable)
index dd539f1..0000000
+++ /dev/null
@@ -1,975 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005, 2006 Junio C Hamano
-
-SUBDIRECTORY_OK=Yes
-OPTIONS_KEEPDASHDASH=
-OPTIONS_STUCKLONG=t
-OPTIONS_SPEC="\
-git am [options] [(<mbox>|<Maildir>)...]
-git am [options] (--continue | --skip | --abort)
---
-i,interactive   run interactively
-b,binary*       (historical option -- no-op)
-3,3way          allow fall back on 3way merging if needed
-q,quiet         be quiet
-s,signoff       add a Signed-off-by line to the commit message
-u,utf8          recode into utf8 (default)
-k,keep          pass -k flag to git-mailinfo
-keep-non-patch  pass -b flag to git-mailinfo
-m,message-id    pass -m flag to git-mailinfo
-keep-cr         pass --keep-cr flag to git-mailsplit for mbox format
-no-keep-cr      do not pass --keep-cr flag to git-mailsplit independent of am.keepcr
-c,scissors      strip everything before a scissors line
-whitespace=     pass it through git-apply
-ignore-space-change pass it through git-apply
-ignore-whitespace pass it through git-apply
-directory=      pass it through git-apply
-exclude=        pass it through git-apply
-include=        pass it through git-apply
-C=              pass it through git-apply
-p=              pass it through git-apply
-patch-format=   format the patch(es) are in
-reject          pass it through git-apply
-resolvemsg=     override error message when patch failure occurs
-continue        continue applying patches after resolving a conflict
-r,resolved      synonyms for --continue
-skip            skip the current patch
-abort           restore the original branch and abort the patching operation.
-committer-date-is-author-date    lie about committer date
-ignore-date     use current timestamp for author date
-rerere-autoupdate update the index with reused conflict resolution if possible
-S,gpg-sign?     GPG-sign commits
-rebasing*       (internal use for git-rebase)"
-
-. git-sh-setup
-. git-sh-i18n
-prefix=$(git rev-parse --show-prefix)
-set_reflog_action am
-require_work_tree
-cd_to_toplevel
-
-git var GIT_COMMITTER_IDENT >/dev/null ||
-       die "$(gettext "You need to set your committer info first")"
-
-if git rev-parse --verify -q HEAD >/dev/null
-then
-       HAS_HEAD=yes
-else
-       HAS_HEAD=
-fi
-
-cmdline="git am"
-if test '' != "$interactive"
-then
-       cmdline="$cmdline -i"
-fi
-if test '' != "$threeway"
-then
-       cmdline="$cmdline -3"
-fi
-
-empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
-
-sq () {
-       git rev-parse --sq-quote "$@"
-}
-
-stop_here () {
-    echo "$1" >"$dotest/next"
-    git rev-parse --verify -q HEAD >"$dotest/abort-safety"
-    exit 1
-}
-
-safe_to_abort () {
-       if test -f "$dotest/dirtyindex"
-       then
-               return 1
-       fi
-
-       if ! test -f "$dotest/abort-safety"
-       then
-               return 0
-       fi
-
-       abort_safety=$(cat "$dotest/abort-safety")
-       if test "z$(git rev-parse --verify -q HEAD)" = "z$abort_safety"
-       then
-               return 0
-       fi
-       gettextln "You seem to have moved HEAD since the last 'am' failure.
-Not rewinding to ORIG_HEAD" >&2
-       return 1
-}
-
-stop_here_user_resolve () {
-    if [ -n "$resolvemsg" ]; then
-           printf '%s\n' "$resolvemsg"
-           stop_here $1
-    fi
-    eval_gettextln "When you have resolved this problem, run \"\$cmdline --continue\".
-If you prefer to skip this patch, run \"\$cmdline --skip\" instead.
-To restore the original branch and stop patching, run \"\$cmdline --abort\"."
-
-    stop_here $1
-}
-
-go_next () {
-       rm -f "$dotest/$msgnum" "$dotest/msg" "$dotest/msg-clean" \
-               "$dotest/patch" "$dotest/info"
-       echo "$next" >"$dotest/next"
-       this=$next
-}
-
-cannot_fallback () {
-       echo "$1"
-       gettextln "Cannot fall back to three-way merge."
-       exit 1
-}
-
-fall_back_3way () {
-    O_OBJECT=$(cd "$GIT_OBJECT_DIRECTORY" && pwd)
-
-    rm -fr "$dotest"/patch-merge-*
-    mkdir "$dotest/patch-merge-tmp-dir"
-
-    # First see if the patch records the index info that we can use.
-    cmd="git apply $git_apply_opt --build-fake-ancestor" &&
-    cmd="$cmd "'"$dotest/patch-merge-tmp-index" "$dotest/patch"' &&
-    eval "$cmd" &&
-    GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
-    git write-tree >"$dotest/patch-merge-base+" ||
-    cannot_fallback "$(gettext "Repository lacks necessary blobs to fall back on 3-way merge.")"
-
-    say "$(gettext "Using index info to reconstruct a base tree...")"
-
-    cmd='GIT_INDEX_FILE="$dotest/patch-merge-tmp-index"'
-
-    if test -z "$GIT_QUIET"
-    then
-       eval "$cmd git diff-index --cached --diff-filter=AM --name-status HEAD"
-    fi
-
-    cmd="$cmd git apply --cached $git_apply_opt"' <"$dotest/patch"'
-    if eval "$cmd"
-    then
-       mv "$dotest/patch-merge-base+" "$dotest/patch-merge-base"
-       mv "$dotest/patch-merge-tmp-index" "$dotest/patch-merge-index"
-    else
-       cannot_fallback "$(gettext "Did you hand edit your patch?
-It does not apply to blobs recorded in its index.")"
-    fi
-
-    test -f "$dotest/patch-merge-index" &&
-    his_tree=$(GIT_INDEX_FILE="$dotest/patch-merge-index" git write-tree) &&
-    orig_tree=$(cat "$dotest/patch-merge-base") &&
-    rm -fr "$dotest"/patch-merge-* || exit 1
-
-    say "$(gettext "Falling back to patching base and 3-way merge...")"
-
-    # This is not so wrong.  Depending on which base we picked,
-    # orig_tree may be wildly different from ours, but his_tree
-    # has the same set of wildly different changes in parts the
-    # patch did not touch, so recursive ends up canceling them,
-    # saying that we reverted all those changes.
-
-    eval GITHEAD_$his_tree='"$FIRSTLINE"'
-    export GITHEAD_$his_tree
-    if test -n "$GIT_QUIET"
-    then
-           GIT_MERGE_VERBOSITY=0 && export GIT_MERGE_VERBOSITY
-    fi
-    our_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree)
-    git-merge-recursive $orig_tree -- $our_tree $his_tree || {
-           git rerere $allow_rerere_autoupdate
-           die "$(gettext "Failed to merge in the changes.")"
-    }
-    unset GITHEAD_$his_tree
-}
-
-clean_abort () {
-       test $# = 0 || echo >&2 "$@"
-       rm -fr "$dotest"
-       exit 1
-}
-
-patch_format=
-
-check_patch_format () {
-       # early return if patch_format was set from the command line
-       if test -n "$patch_format"
-       then
-               return 0
-       fi
-
-       # we default to mbox format if input is from stdin and for
-       # directories
-       if test $# = 0 || test "x$1" = "x-" || test -d "$1"
-       then
-               patch_format=mbox
-               return 0
-       fi
-
-       # otherwise, check the first few non-blank lines of the first
-       # patch to try to detect its format
-       {
-               # Start from first line containing non-whitespace
-               l1=
-               while test -z "$l1"
-               do
-                       read l1 || break
-               done
-               read l2
-               read l3
-               case "$l1" in
-               "From "* | "From: "*)
-                       patch_format=mbox
-                       ;;
-               '# This series applies on GIT commit'*)
-                       patch_format=stgit-series
-                       ;;
-               "# HG changeset patch")
-                       patch_format=hg
-                       ;;
-               *)
-                       # if the second line is empty and the third is
-                       # a From, Author or Date entry, this is very
-                       # likely an StGIT patch
-                       case "$l2,$l3" in
-                       ,"From: "* | ,"Author: "* | ,"Date: "*)
-                               patch_format=stgit
-                               ;;
-                       *)
-                               ;;
-                       esac
-                       ;;
-               esac
-               if test -z "$patch_format" &&
-                       test -n "$l1" &&
-                       test -n "$l2" &&
-                       test -n "$l3"
-               then
-                       # This begins with three non-empty lines.  Is this a
-                       # piece of e-mail a-la RFC2822?  Grab all the headers,
-                       # discarding the indented remainder of folded lines,
-                       # and see if it looks like that they all begin with the
-                       # header field names...
-                       tr -d '\015' <"$1" |
-                       sed -n -e '/^$/q' -e '/^[       ]/d' -e p |
-                       sane_egrep -v '^[!-9;-~]+:' >/dev/null ||
-                       patch_format=mbox
-               fi
-       } < "$1" || clean_abort
-}
-
-split_patches () {
-       case "$patch_format" in
-       mbox)
-               if test t = "$keepcr"
-               then
-                   keep_cr=--keep-cr
-               else
-                   keep_cr=
-               fi
-               git mailsplit -d"$prec" -o"$dotest" -b $keep_cr -- "$@" > "$dotest/last" ||
-               clean_abort
-               ;;
-       stgit-series)
-               if test $# -ne 1
-               then
-                       clean_abort "$(gettext "Only one StGIT patch series can be applied at once")"
-               fi
-               series_dir=$(dirname "$1")
-               series_file="$1"
-               shift
-               {
-                       set x
-                       while read filename
-                       do
-                               set "$@" "$series_dir/$filename"
-                       done
-                       # remove the safety x
-                       shift
-                       # remove the arg coming from the first-line comment
-                       shift
-               } < "$series_file" || clean_abort
-               # set the patch format appropriately
-               patch_format=stgit
-               # now handle the actual StGIT patches
-               split_patches "$@"
-               ;;
-       stgit)
-               this=0
-               test 0 -eq "$#" && set -- -
-               for stgit in "$@"
-               do
-                       this=$(expr "$this" + 1)
-                       msgnum=$(printf "%0${prec}d" $this)
-                       # Perl version of StGIT parse_patch. The first nonemptyline
-                       # not starting with Author, From or Date is the
-                       # subject, and the body starts with the next nonempty
-                       # line not starting with Author, From or Date
-                       @@PERL@@ -ne 'BEGIN { $subject = 0 }
-                               if ($subject > 1) { print ; }
-                               elsif (/^\s+$/) { next ; }
-                               elsif (/^Author:/) { s/Author/From/ ; print ;}
-                               elsif (/^(From|Date)/) { print ; }
-                               elsif ($subject) {
-                                       $subject = 2 ;
-                                       print "\n" ;
-                                       print ;
-                               } else {
-                                       print "Subject: ", $_ ;
-                                       $subject = 1;
-                               }
-                       ' -- "$stgit" >"$dotest/$msgnum" || clean_abort
-               done
-               echo "$this" > "$dotest/last"
-               this=
-               msgnum=
-               ;;
-       hg)
-               this=0
-               test 0 -eq "$#" && set -- -
-               for hg in "$@"
-               do
-                       this=$(( $this + 1 ))
-                       msgnum=$(printf "%0${prec}d" $this)
-                       # hg stores changeset metadata in #-commented lines preceding
-                       # the commit message and diff(s). The only metadata we care about
-                       # are the User and Date (Node ID and Parent are hashes which are
-                       # only relevant to the hg repository and thus not useful to us)
-                       # Since we cannot guarantee that the commit message is in
-                       # git-friendly format, we put no Subject: line and just consume
-                       # all of the message as the body
-                       LANG=C LC_ALL=C @@PERL@@ -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 }
-                               if ($subject) { print ; }
-                               elsif (/^\# User /) { s/\# User/From:/ ; print ; }
-                               elsif (/^\# Date /) {
-                                       my ($hashsign, $str, $time, $tz) = split ;
-                                       $tz_str = sprintf "%+05d", (0-$tz)/36;
-                                       print "Date: " .
-                                             strftime("%a, %d %b %Y %H:%M:%S ",
-                                                      gmtime($time-$tz))
-                                             . "$tz_str\n";
-                               } elsif (/^\# /) { next ; }
-                               else {
-                                       print "\n", $_ ;
-                                       $subject = 1;
-                               }
-                       ' -- "$hg" >"$dotest/$msgnum" || clean_abort
-               done
-               echo "$this" >"$dotest/last"
-               this=
-               msgnum=
-               ;;
-       *)
-               if test -n "$patch_format"
-               then
-                       clean_abort "$(eval_gettext "Patch format \$patch_format is not supported.")"
-               else
-                       clean_abort "$(gettext "Patch format detection failed.")"
-               fi
-               ;;
-       esac
-}
-
-prec=4
-dotest="$GIT_DIR/rebase-apply"
-sign= utf8=t keep= keepcr= skip= interactive= resolved= rebasing= abort=
-messageid= resolvemsg= resume= scissors= no_inbody_headers=
-git_apply_opt=
-committer_date_is_author_date=
-ignore_date=
-allow_rerere_autoupdate=
-gpg_sign_opt=
-threeway=
-
-if test "$(git config --bool --get am.messageid)" = true
-then
-    messageid=t
-fi
-
-if test "$(git config --bool --get am.keepcr)" = true
-then
-    keepcr=t
-fi
-
-while test $# != 0
-do
-       case "$1" in
-       -i|--interactive)
-               interactive=t ;;
-       -b|--binary)
-               gettextln >&2 "The -b/--binary option has been a no-op for long time, and
-it will be removed. Please do not use it anymore."
-               ;;
-       -3|--3way)
-               threeway=t ;;
-       -s|--signoff)
-               sign=t ;;
-       -u|--utf8)
-               utf8=t ;; # this is now default
-       --no-utf8)
-               utf8= ;;
-       -m|--message-id)
-               messageid=t ;;
-       --no-message-id)
-               messageid=f ;;
-       -k|--keep)
-               keep=t ;;
-       --keep-non-patch)
-               keep=b ;;
-       -c|--scissors)
-               scissors=t ;;
-       --no-scissors)
-               scissors=f ;;
-       -r|--resolved|--continue)
-               resolved=t ;;
-       --skip)
-               skip=t ;;
-       --abort)
-               abort=t ;;
-       --rebasing)
-               rebasing=t threeway=t ;;
-       --resolvemsg=*)
-               resolvemsg="${1#--resolvemsg=}" ;;
-       --whitespace=*|--directory=*|--exclude=*|--include=*)
-               git_apply_opt="$git_apply_opt $(sq "$1")" ;;
-       -C*|-p*)
-               git_apply_opt="$git_apply_opt $(sq "$1")" ;;
-       --patch-format=*)
-               patch_format="${1#--patch-format=}" ;;
-       --reject|--ignore-whitespace|--ignore-space-change)
-               git_apply_opt="$git_apply_opt $1" ;;
-       --committer-date-is-author-date)
-               committer_date_is_author_date=t ;;
-       --ignore-date)
-               ignore_date=t ;;
-       --rerere-autoupdate|--no-rerere-autoupdate)
-               allow_rerere_autoupdate="$1" ;;
-       -q|--quiet)
-               GIT_QUIET=t ;;
-       --keep-cr)
-               keepcr=t ;;
-       --no-keep-cr)
-               keepcr=f ;;
-       --gpg-sign)
-               gpg_sign_opt=-S ;;
-       --gpg-sign=*)
-               gpg_sign_opt="-S${1#--gpg-sign=}" ;;
-       --)
-               shift; break ;;
-       *)
-               usage ;;
-       esac
-       shift
-done
-
-# If the dotest directory exists, but we have finished applying all the
-# patches in them, clear it out.
-if test -d "$dotest" &&
-   test -f "$dotest/last" &&
-   test -f "$dotest/next" &&
-   last=$(cat "$dotest/last") &&
-   next=$(cat "$dotest/next") &&
-   test $# != 0 &&
-   test "$next" -gt "$last"
-then
-   rm -fr "$dotest"
-fi
-
-if test -d "$dotest" && test -f "$dotest/last" && test -f "$dotest/next"
-then
-       case "$#,$skip$resolved$abort" in
-       0,*t*)
-               # Explicit resume command and we do not have file, so
-               # we are happy.
-               : ;;
-       0,)
-               # No file input but without resume parameters; catch
-               # user error to feed us a patch from standard input
-               # when there is already $dotest.  This is somewhat
-               # unreliable -- stdin could be /dev/null for example
-               # and the caller did not intend to feed us a patch but
-               # wanted to continue unattended.
-               test -t 0
-               ;;
-       *)
-               false
-               ;;
-       esac ||
-       die "$(eval_gettext "previous rebase directory \$dotest still exists but mbox given.")"
-       resume=yes
-
-       case "$skip,$abort" in
-       t,t)
-               die "$(gettext "Please make up your mind. --skip or --abort?")"
-               ;;
-       t,)
-               git rerere clear
-               head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) &&
-               git read-tree --reset -u $head_tree $head_tree &&
-               index_tree=$(git write-tree) &&
-               git read-tree -m -u $index_tree $head_tree
-               git read-tree -m $head_tree
-               ;;
-       ,t)
-               if test -f "$dotest/rebasing"
-               then
-                       exec git rebase --abort
-               fi
-               git rerere clear
-               if safe_to_abort
-               then
-                       head_tree=$(git rev-parse --verify -q HEAD || echo $empty_tree) &&
-                       git read-tree --reset -u $head_tree $head_tree &&
-                       index_tree=$(git write-tree) &&
-                       orig_head=$(git rev-parse --verify -q ORIG_HEAD || echo $empty_tree) &&
-                       git read-tree -m -u $index_tree $orig_head
-                       if git rev-parse --verify -q ORIG_HEAD >/dev/null 2>&1
-                       then
-                               git reset ORIG_HEAD
-                       else
-                               git read-tree $empty_tree
-                               curr_branch=$(git symbolic-ref HEAD 2>/dev/null) &&
-                               git update-ref -d $curr_branch
-                       fi
-               fi
-               rm -fr "$dotest"
-               exit ;;
-       esac
-       rm -f "$dotest/dirtyindex"
-else
-       # Possible stray $dotest directory in the independent-run
-       # case; in the --rebasing case, it is upto the caller
-       # (git-rebase--am) to take care of stray directories.
-       if test -d "$dotest" && test -z "$rebasing"
-       then
-               case "$skip,$resolved,$abort" in
-               ,,t)
-                       rm -fr "$dotest"
-                       exit 0
-                       ;;
-               *)
-                       die "$(eval_gettext "Stray \$dotest directory found.
-Use \"git am --abort\" to remove it.")"
-                       ;;
-               esac
-       fi
-
-       # Make sure we are not given --skip, --continue, or --abort
-       test "$skip$resolved$abort" = "" ||
-               die "$(gettext "Resolve operation not in progress, we are not resuming.")"
-
-       # Start afresh.
-       mkdir -p "$dotest" || exit
-
-       if test -n "$prefix" && test $# != 0
-       then
-               first=t
-               for arg
-               do
-                       test -n "$first" && {
-                               set x
-                               first=
-                       }
-                       if is_absolute_path "$arg"
-                       then
-                               set "$@" "$arg"
-                       else
-                               set "$@" "$prefix$arg"
-                       fi
-               done
-               shift
-       fi
-
-       check_patch_format "$@"
-
-       split_patches "$@"
-
-       # -i can and must be given when resuming; everything
-       # else is kept
-       echo " $git_apply_opt" >"$dotest/apply-opt"
-       echo "$threeway" >"$dotest/threeway"
-       echo "$sign" >"$dotest/sign"
-       echo "$utf8" >"$dotest/utf8"
-       echo "$keep" >"$dotest/keep"
-       echo "$messageid" >"$dotest/messageid"
-       echo "$scissors" >"$dotest/scissors"
-       echo "$no_inbody_headers" >"$dotest/no_inbody_headers"
-       echo "$GIT_QUIET" >"$dotest/quiet"
-       echo 1 >"$dotest/next"
-       if test -n "$rebasing"
-       then
-               : >"$dotest/rebasing"
-       else
-               : >"$dotest/applying"
-               if test -n "$HAS_HEAD"
-               then
-                       git update-ref ORIG_HEAD HEAD
-               else
-                       git update-ref -d ORIG_HEAD >/dev/null 2>&1
-               fi
-       fi
-fi
-
-git update-index -q --refresh
-
-case "$resolved" in
-'')
-       case "$HAS_HEAD" in
-       '')
-               files=$(git ls-files) ;;
-       ?*)
-               files=$(git diff-index --cached --name-only HEAD --) ;;
-       esac || exit
-       if test "$files"
-       then
-               test -n "$HAS_HEAD" && : >"$dotest/dirtyindex"
-               die "$(eval_gettext "Dirty index: cannot apply patches (dirty: \$files)")"
-       fi
-esac
-
-# Now, decide what command line options we will give to the git
-# commands we invoke, based on the result of parsing command line
-# options and previous invocation state stored in $dotest/ files.
-
-if test "$(cat "$dotest/utf8")" = t
-then
-       utf8=-u
-else
-       utf8=-n
-fi
-keep=$(cat "$dotest/keep")
-case "$keep" in
-t)
-       keep=-k ;;
-b)
-       keep=-b ;;
-*)
-       keep= ;;
-esac
-case "$(cat "$dotest/messageid")" in
-t)
-       messageid=-m ;;
-f)
-       messageid= ;;
-esac
-case "$(cat "$dotest/scissors")" in
-t)
-       scissors=--scissors ;;
-f)
-       scissors=--no-scissors ;;
-esac
-if test "$(cat "$dotest/no_inbody_headers")" = t
-then
-       no_inbody_headers=--no-inbody-headers
-else
-       no_inbody_headers=
-fi
-if test "$(cat "$dotest/quiet")" = t
-then
-       GIT_QUIET=t
-fi
-if test "$(cat "$dotest/threeway")" = t
-then
-       threeway=t
-fi
-git_apply_opt=$(cat "$dotest/apply-opt")
-if test "$(cat "$dotest/sign")" = t
-then
-       SIGNOFF=$(git var GIT_COMMITTER_IDENT | sed -e '
-                       s/>.*/>/
-                       s/^/Signed-off-by: /'
-               )
-else
-       SIGNOFF=
-fi
-
-last=$(cat "$dotest/last")
-this=$(cat "$dotest/next")
-if test "$skip" = t
-then
-       this=$(expr "$this" + 1)
-       resume=
-fi
-
-while test "$this" -le "$last"
-do
-       msgnum=$(printf "%0${prec}d" $this)
-       next=$(expr "$this" + 1)
-       test -f "$dotest/$msgnum" || {
-               resume=
-               go_next
-               continue
-       }
-
-       # If we are not resuming, parse and extract the patch information
-       # into separate files:
-       #  - info records the authorship and title
-       #  - msg is the rest of commit log message
-       #  - patch is the patch body.
-       #
-       # When we are resuming, these files are either already prepared
-       # by the user, or the user can tell us to do so by --continue flag.
-       case "$resume" in
-       '')
-               if test -f "$dotest/rebasing"
-               then
-                       commit=$(sed -e 's/^From \([0-9a-f]*\) .*/\1/' \
-                               -e q "$dotest/$msgnum") &&
-                       test "$(git cat-file -t "$commit")" = commit ||
-                               stop_here $this
-                       git cat-file commit "$commit" |
-                       sed -e '1,/^$/d' >"$dotest/msg-clean"
-                       echo "$commit" >"$dotest/original-commit"
-                       get_author_ident_from_commit "$commit" >"$dotest/author-script"
-                       git diff-tree --root --binary --full-index "$commit" >"$dotest/patch"
-               else
-                       git mailinfo $keep $no_inbody_headers $messageid $scissors $utf8 "$dotest/msg" "$dotest/patch" \
-                               <"$dotest/$msgnum" >"$dotest/info" ||
-                               stop_here $this
-
-                       # skip pine's internal folder data
-                       sane_grep '^Author: Mail System Internal Data$' \
-                               <"$dotest"/info >/dev/null &&
-                               go_next && continue
-
-                       test -s "$dotest/patch" || {
-                               eval_gettextln "Patch is empty.  Was it split wrong?
-If you would prefer to skip this patch, instead run \"\$cmdline --skip\".
-To restore the original branch and stop patching run \"\$cmdline --abort\"."
-                               stop_here $this
-                       }
-                       rm -f "$dotest/original-commit" "$dotest/author-script"
-                       {
-                               sed -n '/^Subject/ s/Subject: //p' "$dotest/info"
-                               echo
-                               cat "$dotest/msg"
-                       } |
-                       git stripspace > "$dotest/msg-clean"
-               fi
-               ;;
-       esac
-
-       if test -f "$dotest/author-script"
-       then
-               eval $(cat "$dotest/author-script")
-       else
-               GIT_AUTHOR_NAME="$(sed -n '/^Author/ s/Author: //p' "$dotest/info")"
-               GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' "$dotest/info")"
-               GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' "$dotest/info")"
-       fi
-
-       if test -z "$GIT_AUTHOR_EMAIL"
-       then
-               gettextln "Patch does not have a valid e-mail address."
-               stop_here $this
-       fi
-
-       export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
-
-       case "$resume" in
-       '')
-           if test '' != "$SIGNOFF"
-           then
-               LAST_SIGNED_OFF_BY=$(
-                   sed -ne '/^Signed-off-by: /p' \
-                   "$dotest/msg-clean" |
-                   sed -ne '$p'
-               )
-               ADD_SIGNOFF=$(
-                   test "$LAST_SIGNED_OFF_BY" = "$SIGNOFF" || {
-                   test '' = "$LAST_SIGNED_OFF_BY" && echo
-                   echo "$SIGNOFF"
-               })
-           else
-               ADD_SIGNOFF=
-           fi
-           {
-               if test -s "$dotest/msg-clean"
-               then
-                       cat "$dotest/msg-clean"
-               fi
-               if test '' != "$ADD_SIGNOFF"
-               then
-                       echo "$ADD_SIGNOFF"
-               fi
-           } >"$dotest/final-commit"
-           ;;
-       *)
-               case "$resolved$interactive" in
-               tt)
-                       # This is used only for interactive view option.
-                       git diff-index -p --cached HEAD -- >"$dotest/patch"
-                       ;;
-               esac
-       esac
-
-       resume=
-       if test "$interactive" = t
-       then
-           test -t 0 ||
-           die "$(gettext "cannot be interactive without stdin connected to a terminal.")"
-           action=again
-           while test "$action" = again
-           do
-               gettextln "Commit Body is:"
-               echo "--------------------------"
-               cat "$dotest/final-commit"
-               echo "--------------------------"
-               # TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a]
-               # in your translation. The program will only accept English
-               # input at this point.
-               gettext "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all "
-               read reply
-               case "$reply" in
-               [yY]*) action=yes ;;
-               [aA]*) action=yes interactive= ;;
-               [nN]*) action=skip ;;
-               [eE]*) git_editor "$dotest/final-commit"
-                      action=again ;;
-               [vV]*) action=again
-                      git_pager "$dotest/patch" ;;
-               *)     action=again ;;
-               esac
-           done
-       else
-           action=yes
-       fi
-
-       if test $action = skip
-       then
-               go_next
-               continue
-       fi
-
-       hook="$(git rev-parse --git-path hooks/applypatch-msg)"
-       if test -x "$hook"
-       then
-               "$hook" "$dotest/final-commit" || stop_here $this
-       fi
-
-       if test -f "$dotest/final-commit"
-       then
-               FIRSTLINE=$(sed 1q "$dotest/final-commit")
-       else
-               FIRSTLINE=""
-       fi
-
-       say "$(eval_gettext "Applying: \$FIRSTLINE")"
-
-       case "$resolved" in
-       '')
-               # When we are allowed to fall back to 3-way later, don't give
-               # false errors during the initial attempt.
-               squelch=
-               if test "$threeway" = t
-               then
-                       squelch='>/dev/null 2>&1 '
-               fi
-               eval "git apply $squelch$git_apply_opt"' --index "$dotest/patch"'
-               apply_status=$?
-               ;;
-       t)
-               # Resolved means the user did all the hard work, and
-               # we do not have to do any patch application.  Just
-               # trust what the user has in the index file and the
-               # working tree.
-               resolved=
-               git diff-index --quiet --cached HEAD -- && {
-                       gettextln "No changes - did you forget to use 'git add'?
-If there is nothing left to stage, chances are that something else
-already introduced the same changes; you might want to skip this patch."
-                       stop_here_user_resolve $this
-               }
-               unmerged=$(git ls-files -u)
-               if test -n "$unmerged"
-               then
-                       gettextln "You still have unmerged paths in your index
-did you forget to use 'git add'?"
-                       stop_here_user_resolve $this
-               fi
-               apply_status=0
-               git rerere
-               ;;
-       esac
-
-       if test $apply_status != 0 && test "$threeway" = t
-       then
-               if (fall_back_3way)
-               then
-                   # Applying the patch to an earlier tree and merging the
-                   # result may have produced the same tree as ours.
-                   git diff-index --quiet --cached HEAD -- && {
-                       say "$(gettext "No changes -- Patch already applied.")"
-                       go_next
-                       continue
-                   }
-                   # clear apply_status -- we have successfully merged.
-                   apply_status=0
-               fi
-       fi
-       if test $apply_status != 0
-       then
-               eval_gettextln 'Patch failed at $msgnum $FIRSTLINE'
-               if test "$(git config --bool advice.amworkdir)" != false
-               then
-                       eval_gettextln 'The copy of the patch that failed is found in:
-   $dotest/patch'
-               fi
-               stop_here_user_resolve $this
-       fi
-
-       hook="$(git rev-parse --git-path hooks/pre-applypatch)"
-       if test -x "$hook"
-       then
-               "$hook" || stop_here $this
-       fi
-
-       tree=$(git write-tree) &&
-       commit=$(
-               if test -n "$ignore_date"
-               then
-                       GIT_AUTHOR_DATE=
-               fi
-               parent=$(git rev-parse --verify -q HEAD) ||
-               say >&2 "$(gettext "applying to an empty history")"
-
-               if test -n "$committer_date_is_author_date"
-               then
-                       GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-                       export GIT_COMMITTER_DATE
-               fi &&
-               git commit-tree ${parent:+-p} $parent ${gpg_sign_opt:+"$gpg_sign_opt"} $tree  \
-                       <"$dotest/final-commit"
-       ) &&
-       git update-ref -m "$GIT_REFLOG_ACTION: $FIRSTLINE" HEAD $commit $parent ||
-       stop_here $this
-
-       if test -f "$dotest/original-commit"; then
-               echo "$(cat "$dotest/original-commit") $commit" >> "$dotest/rewritten"
-       fi
-
-       hook="$(git rev-parse --git-path hooks/post-applypatch)"
-       test -x "$hook" && "$hook"
-
-       go_next
-done
-
-if test -s "$dotest"/rewritten; then
-    git notes copy --for-rewrite=rebase < "$dotest"/rewritten
-    hook="$(git rev-parse --git-path hooks/post-rewrite)"
-    if test -x "$hook"; then
-       "$hook" rebase < "$dotest"/rewritten
-    fi
-fi
-
-# If am was called with --rebasing (from git-rebase--am), it's up to
-# the caller to take care of housekeeping.
-if ! test -f "$dotest/rebasing"
-then
-       rm -fr "$dotest"
-       git gc --auto
-fi
diff --git a/contrib/examples/git-checkout.sh b/contrib/examples/git-checkout.sh
deleted file mode 100755 (executable)
index 683cae7..0000000
+++ /dev/null
@@ -1,302 +0,0 @@
-#!/bin/sh
-
-OPTIONS_KEEPDASHDASH=t
-OPTIONS_SPEC="\
-git-checkout [options] [<branch>] [<paths>...]
---
-b=          create a new branch started at <branch>
-l           create the new branch's reflog
-track       arrange that the new branch tracks the remote branch
-f           proceed even if the index or working tree is not HEAD
-m           merge local modifications into the new branch
-q,quiet     be quiet
-"
-SUBDIRECTORY_OK=Sometimes
-. git-sh-setup
-require_work_tree
-
-old_name=HEAD
-old=$(git rev-parse --verify $old_name 2>/dev/null)
-oldbranch=$(git symbolic-ref $old_name 2>/dev/null)
-new=
-new_name=
-force=
-branch=
-track=
-newbranch=
-newbranch_log=
-merge=
-quiet=
-v=-v
-LF='
-'
-
-while test $# != 0; do
-       case "$1" in
-       -b)
-               shift
-               newbranch="$1"
-               [ -z "$newbranch" ] &&
-                       die "git checkout: -b needs a branch name"
-               git show-ref --verify --quiet -- "refs/heads/$newbranch" &&
-                       die "git checkout: branch $newbranch already exists"
-               git check-ref-format "heads/$newbranch" ||
-                       die "git checkout: we do not like '$newbranch' as a branch name."
-               ;;
-       -l)
-               newbranch_log=-l
-               ;;
-       --track|--no-track)
-               track="$1"
-               ;;
-       -f)
-               force=1
-               ;;
-       -m)
-               merge=1
-               ;;
-       -q|--quiet)
-               quiet=1
-               v=
-               ;;
-       --)
-               shift
-               break
-               ;;
-       *)
-               usage
-               ;;
-       esac
-       shift
-done
-
-arg="$1"
-rev=$(git rev-parse --verify "$arg" 2>/dev/null)
-if rev=$(git rev-parse --verify "$rev^0" 2>/dev/null)
-then
-       [ -z "$rev" ] && die "unknown flag $arg"
-       new_name="$arg"
-       if git show-ref --verify --quiet -- "refs/heads/$arg"
-       then
-               rev=$(git rev-parse --verify "refs/heads/$arg^0")
-               branch="$arg"
-       fi
-       new="$rev"
-       shift
-elif rev=$(git rev-parse --verify "$rev^{tree}" 2>/dev/null)
-then
-       # checking out selected paths from a tree-ish.
-       new="$rev"
-       new_name="$rev^{tree}"
-       shift
-fi
-[ "$1" = "--" ] && shift
-
-case "$newbranch,$track" in
-,--*)
-       die "git checkout: --track and --no-track require -b"
-esac
-
-case "$force$merge" in
-11)
-       die "git checkout: -f and -m are incompatible"
-esac
-
-# The behaviour of the command with and without explicit path
-# parameters is quite different.
-#
-# Without paths, we are checking out everything in the work tree,
-# possibly switching branches.  This is the traditional behaviour.
-#
-# With paths, we are _never_ switching branch, but checking out
-# the named paths from either index (when no rev is given),
-# or the named tree-ish (when rev is given).
-
-if test "$#" -ge 1
-then
-       hint=
-       if test "$#" -eq 1
-       then
-               hint="
-Did you intend to checkout '$@' which can not be resolved as commit?"
-       fi
-       if test '' != "$newbranch$force$merge"
-       then
-               die "git checkout: updating paths is incompatible with switching branches/forcing$hint"
-       fi
-       if test '' != "$new"
-       then
-               # from a specific tree-ish; note that this is for
-               # rescuing paths and is never meant to remove what
-               # is not in the named tree-ish.
-               git ls-tree --full-name -r "$new" "$@" |
-               git update-index --index-info || exit $?
-       fi
-
-       # Make sure the request is about existing paths.
-       git ls-files --full-name --error-unmatch -- "$@" >/dev/null || exit
-       git ls-files --full-name -- "$@" |
-               (cd_to_toplevel && git checkout-index -f -u --stdin)
-
-       # Run a post-checkout hook -- the HEAD does not change so the
-       # current HEAD is passed in for both args
-       if test -x "$GIT_DIR"/hooks/post-checkout; then
-           "$GIT_DIR"/hooks/post-checkout $old $old 0
-       fi
-
-       exit $?
-else
-       # Make sure we did not fall back on $arg^{tree} codepath
-       # since we are not checking out from an arbitrary tree-ish,
-       # but switching branches.
-       if test '' != "$new"
-       then
-               git rev-parse --verify "$new^{commit}" >/dev/null 2>&1 ||
-               die "Cannot switch branch to a non-commit."
-       fi
-fi
-
-# We are switching branches and checking out trees, so
-# we *NEED* to be at the toplevel.
-cd_to_toplevel
-
-[ -z "$new" ] && new=$old && new_name="$old_name"
-
-# If we don't have an existing branch that we're switching to,
-# and we don't have a new branch name for the target we
-# are switching to, then we are detaching our HEAD from any
-# branch.  However, if "git checkout HEAD" detaches the HEAD
-# from the current branch, even though that may be logically
-# correct, it feels somewhat funny.  More importantly, we do not
-# want "git checkout" or "git checkout -f" to detach HEAD.
-
-detached=
-detach_warn=
-
-describe_detached_head () {
-       test -n "$quiet" || {
-               printf >&2 "$1 "
-               GIT_PAGER= git log >&2 -1 --pretty=oneline --abbrev-commit "$2" --
-       }
-}
-
-if test -z "$branch$newbranch" && test "$new_name" != "$old_name"
-then
-       detached="$new"
-       if test -n "$oldbranch" && test -z "$quiet"
-       then
-               detach_warn="Note: moving to \"$new_name\" which isn't a local branch
-If you want to create a new branch from this checkout, you may do so
-(now or later) by using -b with the checkout command again. Example:
-  git checkout -b <new_branch_name>"
-       fi
-elif test -z "$oldbranch" && test "$new" != "$old"
-then
-       describe_detached_head 'Previous HEAD position was' "$old"
-fi
-
-if [ "X$old" = X ]
-then
-       if test -z "$quiet"
-       then
-               echo >&2 "warning: You appear to be on a branch yet to be born."
-               echo >&2 "warning: Forcing checkout of $new_name."
-       fi
-       force=1
-fi
-
-if [ "$force" ]
-then
-    git read-tree $v --reset -u $new
-else
-    git update-index --refresh >/dev/null
-    git read-tree $v -m -u --exclude-per-directory=.gitignore $old $new || (
-       case "$merge,$v" in
-       ,*)
-               exit 1 ;;
-       1,)
-               ;; # quiet
-       *)
-               echo >&2 "Falling back to 3-way merge..." ;;
-       esac
-
-       # Match the index to the working tree, and do a three-way.
-       git diff-files --name-only | git update-index --remove --stdin &&
-       work=$(git write-tree) &&
-       git read-tree $v --reset -u $new || exit
-
-       eval GITHEAD_$new='${new_name:-${branch:-$new}}' &&
-       eval GITHEAD_$work=local &&
-       export GITHEAD_$new GITHEAD_$work &&
-       git merge-recursive $old -- $new $work
-
-       # Do not register the cleanly merged paths in the index yet.
-       # this is not a real merge before committing, but just carrying
-       # the working tree changes along.
-       unmerged=$(git ls-files -u)
-       git read-tree $v --reset $new
-       case "$unmerged" in
-       '')     ;;
-       *)
-               (
-                       z40=0000000000000000000000000000000000000000
-                       echo "$unmerged" |
-                       sed -e 's/^[0-7]* [0-9a-f]* /'"0 $z40 /"
-                       echo "$unmerged"
-               ) | git update-index --index-info
-               ;;
-       esac
-       exit 0
-    )
-    saved_err=$?
-    if test "$saved_err" = 0 && test -z "$quiet"
-    then
-       git diff-index --name-status "$new"
-    fi
-    (exit $saved_err)
-fi
-
-#
-# Switch the HEAD pointer to the new branch if we
-# checked out a branch head, and remove any potential
-# old MERGE_HEAD's (subsequent commits will clearly not
-# be based on them, since we re-set the index)
-#
-if [ "$?" -eq 0 ]; then
-       if [ "$newbranch" ]; then
-               git branch $track $newbranch_log "$newbranch" "$new_name" || exit
-               branch="$newbranch"
-       fi
-       if test -n "$branch"
-       then
-               old_branch_name=$(expr "z$oldbranch" : 'zrefs/heads/\(.*\)')
-               GIT_DIR="$GIT_DIR" git symbolic-ref -m "checkout: moving from ${old_branch_name:-$old} to $branch" HEAD "refs/heads/$branch"
-               if test -n "$quiet"
-               then
-                       true    # nothing
-               elif test "refs/heads/$branch" = "$oldbranch"
-               then
-                       echo >&2 "Already on branch \"$branch\""
-               else
-                       echo >&2 "Switched to${newbranch:+ a new} branch \"$branch\""
-               fi
-       elif test -n "$detached"
-       then
-               old_branch_name=$(expr "z$oldbranch" : 'zrefs/heads/\(.*\)')
-               git update-ref --no-deref -m "checkout: moving from ${old_branch_name:-$old} to $arg" HEAD "$detached" ||
-                       die "Cannot detach HEAD"
-               if test -n "$detach_warn"
-               then
-                       echo >&2 "$detach_warn"
-               fi
-               describe_detached_head 'HEAD is now at' HEAD
-       fi
-       rm -f "$GIT_DIR/MERGE_HEAD"
-else
-       exit 1
-fi
-
-# Run a post-checkout hook
-if test -x "$GIT_DIR"/hooks/post-checkout; then
-       "$GIT_DIR"/hooks/post-checkout $old $new 1
-fi
diff --git a/contrib/examples/git-clean.sh b/contrib/examples/git-clean.sh
deleted file mode 100755 (executable)
index 01c95e9..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005-2006 Pavel Roskin
-#
-
-OPTIONS_KEEPDASHDASH=
-OPTIONS_SPEC="\
-git-clean [options] <paths>...
-
-Clean untracked files from the working directory
-
-When optional <paths>... arguments are given, the paths
-affected are further limited to those that match them.
---
-d remove directories as well
-f override clean.requireForce and clean anyway
-n don't remove anything, just show what would be done
-q be quiet, only report errors
-x remove ignored files as well
-X remove only ignored files"
-
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-require_work_tree
-
-ignored=
-ignoredonly=
-cleandir=
-rmf="rm -f --"
-rmrf="rm -rf --"
-rm_refuse="echo Not removing"
-echo1="echo"
-
-disabled=$(git config --bool clean.requireForce)
-
-while test $# != 0
-do
-       case "$1" in
-       -d)
-               cleandir=1
-               ;;
-       -f)
-               disabled=false
-               ;;
-       -n)
-               disabled=false
-               rmf="echo Would remove"
-               rmrf="echo Would remove"
-               rm_refuse="echo Would not remove"
-               echo1=":"
-               ;;
-       -q)
-               echo1=":"
-               ;;
-       -x)
-               ignored=1
-               ;;
-       -X)
-               ignoredonly=1
-               ;;
-       --)
-               shift
-               break
-               ;;
-       *)
-               usage # should not happen
-               ;;
-       esac
-       shift
-done
-
-# requireForce used to default to false but now it defaults to true.
-# IOW, lack of explicit "clean.requireForce = false" is taken as
-# "clean.requireForce = true".
-case "$disabled" in
-"")
-       die "clean.requireForce not set and -n or -f not given; refusing to clean"
-       ;;
-"true")
-       die "clean.requireForce set and -n or -f not given; refusing to clean"
-       ;;
-esac
-
-if [ "$ignored,$ignoredonly" = "1,1" ]; then
-       die "-x and -X cannot be set together"
-fi
-
-if [ -z "$ignored" ]; then
-       excl="--exclude-per-directory=.gitignore"
-       excl_info= excludes_file=
-       if [ -f "$GIT_DIR/info/exclude" ]; then
-               excl_info="--exclude-from=$GIT_DIR/info/exclude"
-       fi
-       if cfg_excl=$(git config core.excludesfile) && test -f "$cfg_excl"
-       then
-               excludes_file="--exclude-from=$cfg_excl"
-       fi
-       if [ "$ignoredonly" ]; then
-               excl="$excl --ignored"
-       fi
-fi
-
-git ls-files --others --directory \
-       $excl ${excl_info:+"$excl_info"} ${excludes_file:+"$excludes_file"} \
-       -- "$@" |
-while read -r file; do
-       if [ -d "$file" -a ! -L "$file" ]; then
-               if [ -z "$cleandir" ]; then
-                       $rm_refuse "$file"
-                       continue
-               fi
-               $echo1 "Removing $file"
-               $rmrf "$file"
-       else
-               $echo1 "Removing $file"
-               $rmf "$file"
-       fi
-done
diff --git a/contrib/examples/git-clone.sh b/contrib/examples/git-clone.sh
deleted file mode 100755 (executable)
index 08cf246..0000000
+++ /dev/null
@@ -1,525 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005, Linus Torvalds
-# Copyright (c) 2005, Junio C Hamano
-#
-# Clone a repository into a different directory that does not yet exist.
-
-# See git-sh-setup why.
-unset CDPATH
-
-OPTIONS_SPEC="\
-git-clone [options] [--] <repo> [<dir>]
---
-n,no-checkout        don't create a checkout
-bare                 create a bare repository
-naked                create a bare repository
-l,local              to clone from a local repository
-no-hardlinks         don't use local hardlinks, always copy
-s,shared             setup as a shared repository
-template=            path to the template directory
-q,quiet              be quiet
-reference=           reference repository
-o,origin=            use <name> instead of 'origin' to track upstream
-u,upload-pack=       path to git-upload-pack on the remote
-depth=               create a shallow clone of that depth
-
-use-separate-remote  compatibility, do not use
-no-separate-remote   compatibility, do not use"
-
-die() {
-       echo >&2 "$@"
-       exit 1
-}
-
-usage() {
-       exec "$0" -h
-}
-
-eval "$(echo "$OPTIONS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
-
-get_repo_base() {
-       (
-               cd "$(/bin/pwd)" &&
-               cd "$1" || cd "$1.git" &&
-               {
-                       cd .git
-                       pwd
-               }
-       ) 2>/dev/null
-}
-
-if [ -n "$GIT_SSL_NO_VERIFY" -o \
-       "$(git config --bool http.sslVerify)" = false ]; then
-    curl_extra_args="-k"
-fi
-
-http_fetch () {
-       # $1 = Remote, $2 = Local
-       curl -nsfL $curl_extra_args "$1" >"$2"
-       curl_exit_status=$?
-       case $curl_exit_status in
-       126|127) exit ;;
-       *)       return $curl_exit_status ;;
-       esac
-}
-
-clone_dumb_http () {
-       # $1 - remote, $2 - local
-       cd "$2" &&
-       clone_tmp="$GIT_DIR/clone-tmp" &&
-       mkdir -p "$clone_tmp" || exit 1
-       if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
-               "$(git config --bool http.noEPSV)" = true ]; then
-               curl_extra_args="${curl_extra_args} --disable-epsv"
-       fi
-       http_fetch "$1/info/refs" "$clone_tmp/refs" ||
-               die "Cannot get remote repository information.
-Perhaps git-update-server-info needs to be run there?"
-       test "z$quiet" = z && v=-v || v=
-       while read sha1 refname
-       do
-               name=$(expr "z$refname" : 'zrefs/\(.*\)') &&
-               case "$name" in
-               *^*)    continue;;
-               esac
-               case "$bare,$name" in
-               yes,* | ,heads/* | ,tags/*) ;;
-               *)      continue ;;
-               esac
-               if test -n "$use_separate_remote" &&
-                  branch_name=$(expr "z$name" : 'zheads/\(.*\)')
-               then
-                       tname="remotes/$origin/$branch_name"
-               else
-                       tname=$name
-               fi
-               git-http-fetch $v -a -w "$tname" "$sha1" "$1" || exit 1
-       done <"$clone_tmp/refs"
-       rm -fr "$clone_tmp"
-       http_fetch "$1/HEAD" "$GIT_DIR/REMOTE_HEAD" ||
-       rm -f "$GIT_DIR/REMOTE_HEAD"
-       if test -f "$GIT_DIR/REMOTE_HEAD"; then
-               head_sha1=$(cat "$GIT_DIR/REMOTE_HEAD")
-               case "$head_sha1" in
-               'ref: refs/'*)
-                       ;;
-               *)
-                       git-http-fetch $v -a "$head_sha1" "$1" ||
-                       rm -f "$GIT_DIR/REMOTE_HEAD"
-                       ;;
-               esac
-       fi
-}
-
-quiet=
-local=no
-use_local_hardlink=yes
-local_shared=no
-unset template
-no_checkout=
-upload_pack=
-bare=
-reference=
-origin=
-origin_override=
-use_separate_remote=t
-depth=
-no_progress=
-local_explicitly_asked_for=
-test -t 1 || no_progress=--no-progress
-
-while test $# != 0
-do
-       case "$1" in
-       -n|--no-checkout)
-               no_checkout=yes ;;
-       --naked|--bare)
-               bare=yes ;;
-       -l|--local)
-               local_explicitly_asked_for=yes
-               use_local_hardlink=yes
-               ;;
-       --no-hardlinks)
-               use_local_hardlink=no ;;
-       -s|--shared)
-               local_shared=yes ;;
-       --template)
-               shift; template="--template=$1" ;;
-       -q|--quiet)
-               quiet=-q ;;
-       --use-separate-remote|--no-separate-remote)
-               die "clones are always made with separate-remote layout" ;;
-       --reference)
-               shift; reference="$1" ;;
-       -o|--origin)
-               shift;
-               case "$1" in
-               '')
-                   usage ;;
-               */*)
-                   die "'$1' is not suitable for an origin name"
-               esac
-               git check-ref-format "heads/$1" ||
-                   die "'$1' is not suitable for a branch name"
-               test -z "$origin_override" ||
-                   die "Do not give more than one --origin options."
-               origin_override=yes
-               origin="$1"
-               ;;
-       -u|--upload-pack)
-               shift
-               upload_pack="--upload-pack=$1" ;;
-       --depth)
-               shift
-               depth="--depth=$1" ;;
-       --)
-               shift
-               break ;;
-       *)
-               usage ;;
-       esac
-       shift
-done
-
-repo="$1"
-test -n "$repo" ||
-    die 'you must specify a repository to clone.'
-
-# --bare implies --no-checkout and --no-separate-remote
-if test yes = "$bare"
-then
-       if test yes = "$origin_override"
-       then
-               die '--bare and --origin $origin options are incompatible.'
-       fi
-       no_checkout=yes
-       use_separate_remote=
-fi
-
-if test -z "$origin"
-then
-       origin=origin
-fi
-
-# Turn the source into an absolute path if
-# it is local
-if base=$(get_repo_base "$repo"); then
-       repo="$base"
-       if test -z "$depth"
-       then
-               local=yes
-       fi
-elif test -f "$repo"
-then
-       case "$repo" in /*) ;; *) repo="$PWD/$repo" ;; esac
-fi
-
-# Decide the directory name of the new repository
-if test -n "$2"
-then
-       dir="$2"
-       test $# = 2 || die "excess parameter to git-clone"
-else
-       # Derive one from the repository name
-       # Try using "humanish" part of source repo if user didn't specify one
-       if test -f "$repo"
-       then
-               # Cloning from a bundle
-               dir=$(echo "$repo" | sed -e 's|/*\.bundle$||' -e 's|.*/||g')
-       else
-               dir=$(echo "$repo" |
-                       sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
-       fi
-fi
-
-[ -e "$dir" ] && die "destination directory '$dir' already exists."
-[ yes = "$bare" ] && unset GIT_WORK_TREE
-[ -n "$GIT_WORK_TREE" ] && [ -e "$GIT_WORK_TREE" ] &&
-die "working tree '$GIT_WORK_TREE' already exists."
-D=
-W=
-cleanup() {
-       test -z "$D" && rm -rf "$dir"
-       test -z "$W" && test -n "$GIT_WORK_TREE" && rm -rf "$GIT_WORK_TREE"
-       cd ..
-       test -n "$D" && rm -rf "$D"
-       test -n "$W" && rm -rf "$W"
-       exit $err
-}
-trap 'err=$?; cleanup' 0
-mkdir -p "$dir" && D=$(cd "$dir" && pwd) || usage
-test -n "$GIT_WORK_TREE" && mkdir -p "$GIT_WORK_TREE" &&
-W=$(cd "$GIT_WORK_TREE" && pwd) && GIT_WORK_TREE="$W" && export GIT_WORK_TREE
-if test yes = "$bare" || test -n "$GIT_WORK_TREE"; then
-       GIT_DIR="$D"
-else
-       GIT_DIR="$D/.git"
-fi &&
-export GIT_DIR &&
-GIT_CONFIG="$GIT_DIR/config" git-init $quiet ${template+"$template"} || usage
-
-if test -n "$bare"
-then
-       GIT_CONFIG="$GIT_DIR/config" git config core.bare true
-fi
-
-if test -n "$reference"
-then
-       ref_git=
-       if test -d "$reference"
-       then
-               if test -d "$reference/.git/objects"
-               then
-                       ref_git="$reference/.git"
-               elif test -d "$reference/objects"
-               then
-                       ref_git="$reference"
-               fi
-       fi
-       if test -n "$ref_git"
-       then
-               ref_git=$(cd "$ref_git" && pwd)
-               echo "$ref_git/objects" >"$GIT_DIR/objects/info/alternates"
-               (
-                       GIT_DIR="$ref_git" git for-each-ref \
-                               --format='%(objectname) %(*objectname)'
-               ) |
-               while read a b
-               do
-                       test -z "$a" ||
-                       git update-ref "refs/reference-tmp/$a" "$a"
-                       test -z "$b" ||
-                       git update-ref "refs/reference-tmp/$b" "$b"
-               done
-       else
-               die "reference repository '$reference' is not a local directory."
-       fi
-fi
-
-rm -f "$GIT_DIR/CLONE_HEAD"
-
-# We do local magic only when the user tells us to.
-case "$local" in
-yes)
-       ( cd "$repo/objects" ) ||
-               die "cannot chdir to local '$repo/objects'."
-
-       if test "$local_shared" = yes
-       then
-               mkdir -p "$GIT_DIR/objects/info"
-               echo "$repo/objects" >>"$GIT_DIR/objects/info/alternates"
-       else
-               cpio_quiet_flag=""
-               cpio --help 2>&1 | grep -- --quiet >/dev/null && \
-                       cpio_quiet_flag=--quiet
-               l= &&
-               if test "$use_local_hardlink" = yes
-               then
-                       # See if we can hardlink and drop "l" if not.
-                       sample_file=$(cd "$repo" && \
-                                     find objects -type f -print | sed -e 1q)
-                       # objects directory should not be empty because
-                       # we are cloning!
-                       test -f "$repo/$sample_file" ||
-                               die "fatal: cannot clone empty repository"
-                       if ln "$repo/$sample_file" "$GIT_DIR/objects/sample" 2>/dev/null
-                       then
-                               rm -f "$GIT_DIR/objects/sample"
-                               l=l
-                       elif test -n "$local_explicitly_asked_for"
-                       then
-                               echo >&2 "Warning: -l asked but cannot hardlink to $repo"
-                       fi
-               fi &&
-               cd "$repo" &&
-               # Create dirs using umask and permissions and destination
-               find objects -type d -print | (cd "$GIT_DIR" && xargs mkdir -p) &&
-               # Copy existing 0444 permissions on content
-               find objects ! -type d -print | cpio $cpio_quiet_flag -pumd$l "$GIT_DIR/" || \
-                       exit 1
-       fi
-       git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
-       ;;
-*)
-       case "$repo" in
-       rsync://*)
-               case "$depth" in
-               "") ;;
-               *) die "shallow over rsync not supported" ;;
-               esac
-               rsync $quiet -av --ignore-existing  \
-                       --exclude info "$repo/objects/" "$GIT_DIR/objects/" ||
-               exit
-               # Look at objects/info/alternates for rsync -- http will
-               # support it natively and git native ones will do it on the
-               # remote end.  Not having that file is not a crime.
-               rsync -q "$repo/objects/info/alternates" \
-                       "$GIT_DIR/TMP_ALT" 2>/dev/null ||
-                       rm -f "$GIT_DIR/TMP_ALT"
-               if test -f "$GIT_DIR/TMP_ALT"
-               then
-                   ( cd "$D" &&
-                     . git-parse-remote &&
-                     resolve_alternates "$repo" <"$GIT_DIR/TMP_ALT" ) |
-                   while read alt
-                   do
-                       case "$alt" in 'bad alternate: '*) die "$alt";; esac
-                       case "$quiet" in
-                       '')     echo >&2 "Getting alternate: $alt" ;;
-                       esac
-                       rsync $quiet -av --ignore-existing  \
-                           --exclude info "$alt" "$GIT_DIR/objects" || exit
-                   done
-                   rm -f "$GIT_DIR/TMP_ALT"
-               fi
-               git-ls-remote "$repo" >"$GIT_DIR/CLONE_HEAD" || exit 1
-               ;;
-       https://*|http://*|ftp://*)
-               case "$depth" in
-               "") ;;
-               *) die "shallow over http or ftp not supported" ;;
-               esac
-               if test -z "@@NO_CURL@@"
-               then
-                       clone_dumb_http "$repo" "$D"
-               else
-                       die "http transport not supported, rebuild Git with curl support"
-               fi
-               ;;
-       *)
-               if [ -f "$repo" ] ; then
-                       git bundle unbundle "$repo" > "$GIT_DIR/CLONE_HEAD" ||
-                       die "unbundle from '$repo' failed."
-               else
-                       case "$upload_pack" in
-                       '') git-fetch-pack --all -k $quiet $depth $no_progress "$repo";;
-                       *) git-fetch-pack --all -k \
-                               $quiet "$upload_pack" $depth $no_progress "$repo" ;;
-                       esac >"$GIT_DIR/CLONE_HEAD" ||
-                       die "fetch-pack from '$repo' failed."
-               fi
-               ;;
-       esac
-       ;;
-esac
-test -d "$GIT_DIR/refs/reference-tmp" && rm -fr "$GIT_DIR/refs/reference-tmp"
-
-if test -f "$GIT_DIR/CLONE_HEAD"
-then
-       # Read git-fetch-pack -k output and store the remote branches.
-       if [ -n "$use_separate_remote" ]
-       then
-               branch_top="remotes/$origin"
-       else
-               branch_top="heads"
-       fi
-       tag_top="tags"
-       while read sha1 name
-       do
-               case "$name" in
-               *'^{}')
-                       continue ;;
-               HEAD)
-                       destname="REMOTE_HEAD" ;;
-               refs/heads/*)
-                       destname="refs/$branch_top/${name#refs/heads/}" ;;
-               refs/tags/*)
-                       destname="refs/$tag_top/${name#refs/tags/}" ;;
-               *)
-                       continue ;;
-               esac
-               git update-ref -m "clone: from $repo" "$destname" "$sha1" ""
-       done < "$GIT_DIR/CLONE_HEAD"
-fi
-
-if test -n "$W"; then
-       cd "$W" || exit
-else
-       cd "$D" || exit
-fi
-
-if test -z "$bare"
-then
-       # a non-bare repository is always in separate-remote layout
-       remote_top="refs/remotes/$origin"
-       head_sha1=
-       test ! -r "$GIT_DIR/REMOTE_HEAD" || head_sha1=$(cat "$GIT_DIR/REMOTE_HEAD")
-       case "$head_sha1" in
-       'ref: refs/'*)
-               # Uh-oh, the remote told us (http transport done against
-               # new style repository with a symref HEAD).
-               # Ideally we should skip the guesswork but for now
-               # opt for minimum change.
-               head_sha1=$(expr "z$head_sha1" : 'zref: refs/heads/\(.*\)')
-               head_sha1=$(cat "$GIT_DIR/$remote_top/$head_sha1")
-               ;;
-       esac
-
-       # The name under $remote_top the remote HEAD seems to point at.
-       head_points_at=$(
-               (
-                       test -f "$GIT_DIR/$remote_top/master" && echo "master"
-                       cd "$GIT_DIR/$remote_top" &&
-                       find . -type f -print | sed -e 's/^\.\///'
-               ) | (
-               done=f
-               while read name
-               do
-                       test t = $done && continue
-                       branch_tip=$(cat "$GIT_DIR/$remote_top/$name")
-                       if test "$head_sha1" = "$branch_tip"
-                       then
-                               echo "$name"
-                               done=t
-                       fi
-               done
-               )
-       )
-
-       # Upstream URL
-       git config remote."$origin".url "$repo" &&
-
-       # Set up the mappings to track the remote branches.
-       git config remote."$origin".fetch \
-               "+refs/heads/*:$remote_top/*" '^$' &&
-
-       # Write out remote.$origin config, and update our "$head_points_at".
-       case "$head_points_at" in
-       ?*)
-               # Local default branch
-               git symbolic-ref HEAD "refs/heads/$head_points_at" &&
-
-               # Tracking branch for the primary branch at the remote.
-               git update-ref HEAD "$head_sha1" &&
-
-               rm -f "refs/remotes/$origin/HEAD"
-               git symbolic-ref "refs/remotes/$origin/HEAD" \
-                       "refs/remotes/$origin/$head_points_at" &&
-
-               git config branch."$head_points_at".remote "$origin" &&
-               git config branch."$head_points_at".merge "refs/heads/$head_points_at"
-               ;;
-       '')
-               if test -z "$head_sha1"
-               then
-                       # Source had nonexistent ref in HEAD
-                       echo >&2 "Warning: Remote HEAD refers to nonexistent ref, unable to checkout."
-                       no_checkout=t
-               else
-                       # Source had detached HEAD pointing nowhere
-                       git update-ref --no-deref HEAD "$head_sha1" &&
-                       rm -f "refs/remotes/$origin/HEAD"
-               fi
-               ;;
-       esac
-
-       case "$no_checkout" in
-       '')
-               test "z$quiet" = z && test "z$no_progress" = z && v=-v || v=
-               git read-tree -m -u $v HEAD HEAD
-       esac
-fi
-rm -f "$GIT_DIR/CLONE_HEAD" "$GIT_DIR/REMOTE_HEAD"
-
-trap - 0
diff --git a/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh
deleted file mode 100755 (executable)
index 86c9cfa..0000000
+++ /dev/null
@@ -1,639 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-# Copyright (c) 2006 Junio C Hamano
-
-USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
-SUBDIRECTORY_OK=Yes
-OPTIONS_SPEC=
-. git-sh-setup
-require_work_tree
-
-git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
-
-case "$0" in
-*status)
-       status_only=t
-       ;;
-*commit)
-       status_only=
-       ;;
-esac
-
-refuse_partial () {
-       echo >&2 "$1"
-       echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
-       exit 1
-}
-
-TMP_INDEX=
-THIS_INDEX="${GIT_INDEX_FILE:-$GIT_DIR/index}"
-NEXT_INDEX="$GIT_DIR/next-index$$"
-rm -f "$NEXT_INDEX"
-save_index () {
-       cp -p "$THIS_INDEX" "$NEXT_INDEX"
-}
-
-run_status () {
-       # If TMP_INDEX is defined, that means we are doing
-       # "--only" partial commit, and that index file is used
-       # to build the tree for the commit.  Otherwise, if
-       # NEXT_INDEX exists, that is the index file used to
-       # make the commit.  Otherwise we are using as-is commit
-       # so the regular index file is what we use to compare.
-       if test '' != "$TMP_INDEX"
-       then
-               GIT_INDEX_FILE="$TMP_INDEX"
-               export GIT_INDEX_FILE
-       elif test -f "$NEXT_INDEX"
-       then
-               GIT_INDEX_FILE="$NEXT_INDEX"
-               export GIT_INDEX_FILE
-       fi
-
-       if test "$status_only" = "t" || test "$use_status_color" = "t"; then
-               color=
-       else
-               color=--nocolor
-       fi
-       git runstatus ${color} \
-               ${verbose:+--verbose} \
-               ${amend:+--amend} \
-               ${untracked_files:+--untracked}
-}
-
-trap '
-       test -z "$TMP_INDEX" || {
-               test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
-       }
-       rm -f "$NEXT_INDEX"
-' 0
-
-################################################################
-# Command line argument parsing and sanity checking
-
-all=
-also=
-allow_empty=f
-interactive=
-only=
-logfile=
-use_commit=
-amend=
-edit_flag=
-no_edit=
-log_given=
-log_message=
-verify=t
-quiet=
-verbose=
-signoff=
-force_author=
-only_include_assumed=
-untracked_files=
-templatefile="$(git config commit.template)"
-while test $# != 0
-do
-       case "$1" in
-       -F|--F|-f|--f|--fi|--fil|--file)
-               case "$#" in 1) usage ;; esac
-               shift
-               no_edit=t
-               log_given=t$log_given
-               logfile="$1"
-               ;;
-       -F*|-f*)
-               no_edit=t
-               log_given=t$log_given
-               logfile="${1#-[Ff]}"
-               ;;
-       --F=*|--f=*|--fi=*|--fil=*|--file=*)
-               no_edit=t
-               log_given=t$log_given
-               logfile="${1#*=}"
-               ;;
-       -a|--a|--al|--all)
-               all=t
-               ;;
-       --allo|--allow|--allow-|--allow-e|--allow-em|--allow-emp|\
-       --allow-empt|--allow-empty)
-               allow_empty=t
-               ;;
-       --au=*|--aut=*|--auth=*|--autho=*|--author=*)
-               force_author="${1#*=}"
-               ;;
-       --au|--aut|--auth|--autho|--author)
-               case "$#" in 1) usage ;; esac
-               shift
-               force_author="$1"
-               ;;
-       -e|--e|--ed|--edi|--edit)
-               edit_flag=t
-               ;;
-       -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
-               also=t
-               ;;
-       --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
-       --interactiv|--interactive)
-               interactive=t
-               ;;
-       -o|--o|--on|--onl|--only)
-               only=t
-               ;;
-       -m|--m|--me|--mes|--mess|--messa|--messag|--message)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=m$log_given
-               log_message="${log_message:+${log_message}
-
-}$1"
-               no_edit=t
-               ;;
-       -m*)
-               log_given=m$log_given
-               log_message="${log_message:+${log_message}
-
-}${1#-m}"
-               no_edit=t
-               ;;
-       --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
-               log_given=m$log_given
-               log_message="${log_message:+${log_message}
-
-}${1#*=}"
-               no_edit=t
-               ;;
-       -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
-       --no-verify)
-               verify=
-               ;;
-       --a|--am|--ame|--amen|--amend)
-               amend=t
-               use_commit=HEAD
-               ;;
-       -c)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=
-               ;;
-       --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
-       --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
-       --reedit-messag=*|--reedit-message=*)
-               log_given=t$log_given
-               use_commit="${1#*=}"
-               no_edit=
-               ;;
-       --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
-       --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
-       --reedit-message)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=
-               ;;
-       -C)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=t
-               ;;
-       --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
-       --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
-       --reuse-message=*)
-               log_given=t$log_given
-               use_commit="${1#*=}"
-               no_edit=t
-               ;;
-       --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
-       --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=t
-               ;;
-       -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
-               signoff=t
-               ;;
-       -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
-               case "$#" in 1) usage ;; esac
-               shift
-               templatefile="$1"
-               no_edit=
-               ;;
-       -q|--q|--qu|--qui|--quie|--quiet)
-               quiet=t
-               ;;
-       -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
-               verbose=t
-               ;;
-       -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
-       --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
-       --untracked-file|--untracked-files)
-               untracked_files=t
-               ;;
-       --)
-               shift
-               break
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               break
-               ;;
-       esac
-       shift
-done
-case "$edit_flag" in t) no_edit= ;; esac
-
-################################################################
-# Sanity check options
-
-case "$amend,$initial_commit" in
-t,t)
-       die "You do not have anything to amend." ;;
-t,)
-       if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
-               die "You are in the middle of a merge -- cannot amend."
-       fi ;;
-esac
-
-case "$log_given" in
-tt*)
-       die "Only one of -c/-C/-F can be used." ;;
-*tm*|*mt*)
-       die "Option -m cannot be combined with -c/-C/-F." ;;
-esac
-
-case "$#,$also,$only,$amend" in
-*,t,t,*)
-       die "Only one of --include/--only can be used." ;;
-0,t,,* | 0,,t,)
-       die "No paths with --include/--only does not make sense." ;;
-0,,t,t)
-       only_include_assumed="# Clever... amending the last one with dirty index." ;;
-0,,,*)
-       ;;
-*,,,*)
-       only_include_assumed="# Explicit paths specified without -i or -o; assuming --only paths..."
-       also=
-       ;;
-esac
-unset only
-case "$all,$interactive,$also,$#" in
-*t,*t,*)
-       die "Cannot use -a, --interactive or -i at the same time." ;;
-t,,,[1-9]*)
-       die "Paths with -a does not make sense." ;;
-,t,,[1-9]*)
-       die "Paths with --interactive does not make sense." ;;
-,,t,0)
-       die "No paths with -i does not make sense." ;;
-esac
-
-if test ! -z "$templatefile" && test -z "$log_given"
-then
-       if test ! -f "$templatefile"
-       then
-               die "Commit template file does not exist."
-       fi
-fi
-
-################################################################
-# Prepare index to have a tree to be committed
-
-case "$all,$also" in
-t,)
-       if test ! -f "$THIS_INDEX"
-       then
-               die 'nothing to commit (use "git add file1 file2" to include for commit)'
-       fi
-       save_index &&
-       (
-               cd_to_toplevel &&
-               GIT_INDEX_FILE="$NEXT_INDEX" &&
-               export GIT_INDEX_FILE &&
-               git diff-files --name-only -z |
-               git update-index --remove -z --stdin
-       ) || exit
-       ;;
-,t)
-       save_index &&
-       git ls-files --error-unmatch -- "$@" >/dev/null || exit
-
-       git diff-files --name-only -z -- "$@"  |
-       (
-               cd_to_toplevel &&
-               GIT_INDEX_FILE="$NEXT_INDEX" &&
-               export GIT_INDEX_FILE &&
-               git update-index --remove -z --stdin
-       ) || exit
-       ;;
-,)
-       if test "$interactive" = t; then
-               git add --interactive || exit
-       fi
-       case "$#" in
-       0)
-               ;; # commit as-is
-       *)
-               if test -f "$GIT_DIR/MERGE_HEAD"
-               then
-                       refuse_partial "Cannot do a partial commit during a merge."
-               fi
-
-               TMP_INDEX="$GIT_DIR/tmp-index$$"
-               W=
-               test -z "$initial_commit" && W=--with-tree=HEAD
-               commit_only=$(git ls-files --error-unmatch $W -- "$@") || exit
-
-               # Build a temporary index and update the real index
-               # the same way.
-               if test -z "$initial_commit"
-               then
-                       GIT_INDEX_FILE="$THIS_INDEX" \
-                       git read-tree --index-output="$TMP_INDEX" -i -m HEAD
-               else
-                       rm -f "$TMP_INDEX"
-               fi || exit
-
-               printf '%s\n' "$commit_only" |
-               GIT_INDEX_FILE="$TMP_INDEX" \
-               git update-index --add --remove --stdin &&
-
-               save_index &&
-               printf '%s\n' "$commit_only" |
-               (
-                       GIT_INDEX_FILE="$NEXT_INDEX"
-                       export GIT_INDEX_FILE
-                       git update-index --add --remove --stdin
-               ) || exit
-               ;;
-       esac
-       ;;
-esac
-
-################################################################
-# If we do as-is commit, the index file will be THIS_INDEX,
-# otherwise NEXT_INDEX after we make this commit.  We leave
-# the index as is if we abort.
-
-if test -f "$NEXT_INDEX"
-then
-       USE_INDEX="$NEXT_INDEX"
-else
-       USE_INDEX="$THIS_INDEX"
-fi
-
-case "$status_only" in
-t)
-       # This will silently fail in a read-only repository, which is
-       # what we want.
-       GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
-       run_status
-       exit $?
-       ;;
-'')
-       GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
-       ;;
-esac
-
-################################################################
-# Grab commit message, write out tree and make commit.
-
-if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
-then
-    GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \
-    || exit
-fi
-
-if test "$log_message" != ''
-then
-       printf '%s\n' "$log_message"
-elif test "$logfile" != ""
-then
-       if test "$logfile" = -
-       then
-               test -t 0 &&
-               echo >&2 "(reading log message from standard input)"
-               cat
-       else
-               cat <"$logfile"
-       fi
-elif test "$use_commit" != ""
-then
-       encoding=$(git config i18n.commitencoding || echo UTF-8)
-       git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
-       sed -e '1,/^$/d' -e 's/^    //'
-elif test -f "$GIT_DIR/MERGE_MSG"
-then
-       cat "$GIT_DIR/MERGE_MSG"
-elif test -f "$GIT_DIR/SQUASH_MSG"
-then
-       cat "$GIT_DIR/SQUASH_MSG"
-elif test "$templatefile" != ""
-then
-       cat "$templatefile"
-fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
-
-case "$signoff" in
-t)
-       sign=$(git var GIT_COMMITTER_IDENT | sed -e '
-               s/>.*/>/
-               s/^/Signed-off-by: /
-               ')
-       blank_before_signoff=
-       tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
-       grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
-'
-       tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
-       grep "$sign"$ >/dev/null ||
-       printf '%s%s\n' "$blank_before_signoff" "$sign" \
-               >>"$GIT_DIR"/COMMIT_EDITMSG
-       ;;
-esac
-
-if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
-       echo "#"
-       echo "# It looks like you may be committing a MERGE."
-       echo "# If this is not correct, please remove the file"
-       printf '%s\n' "#        $GIT_DIR/MERGE_HEAD"
-       echo "# and try again"
-       echo "#"
-fi >>"$GIT_DIR"/COMMIT_EDITMSG
-
-# Author
-if test '' != "$use_commit"
-then
-       eval "$(get_author_ident_from_commit "$use_commit")"
-       export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
-fi
-if test '' != "$force_author"
-then
-       GIT_AUTHOR_NAME=$(expr "z$force_author" : 'z\(.*[^ ]\) *<.*') &&
-       GIT_AUTHOR_EMAIL=$(expr "z$force_author" : '.*\(<.*\)') &&
-       test '' != "$GIT_AUTHOR_NAME" &&
-       test '' != "$GIT_AUTHOR_EMAIL" ||
-       die "malformed --author parameter"
-       export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
-fi
-
-PARENTS="-p HEAD"
-if test -z "$initial_commit"
-then
-       rloga='commit'
-       if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
-               rloga='commit (merge)'
-               PARENTS="-p HEAD "$(sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD")
-       elif test -n "$amend"; then
-               rloga='commit (amend)'
-               PARENTS=$(git cat-file commit HEAD |
-                       sed -n -e '/^$/q' -e 's/^parent /-p /p')
-       fi
-       current="$(git rev-parse --verify HEAD)"
-else
-       if [ -z "$(git ls-files)" ]; then
-               echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
-               exit 1
-       fi
-       PARENTS=""
-       rloga='commit (initial)'
-       current=''
-fi
-set_reflog_action "$rloga"
-
-if test -z "$no_edit"
-then
-       {
-               echo ""
-               echo "# Please enter the commit message for your changes."
-               echo "# (Comment lines starting with '#' will not be included)"
-               test -z "$only_include_assumed" || echo "$only_include_assumed"
-               run_status
-       } >>"$GIT_DIR"/COMMIT_EDITMSG
-else
-       # we need to check if there is anything to commit
-       run_status >/dev/null
-fi
-case "$allow_empty,$?,$PARENTS" in
-t,* | ?,0,* | ?,*,-p' '?*-p' '?*)
-       # an explicit --allow-empty, or a merge commit can record the
-       # same tree as its parent.  Otherwise having commitable paths
-       # is required.
-       ;;
-*)
-       rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-       use_status_color=t
-       run_status
-       exit 1
-esac
-
-case "$no_edit" in
-'')
-       git var GIT_AUTHOR_IDENT > /dev/null  || die
-       git var GIT_COMMITTER_IDENT > /dev/null  || die
-       git_editor "$GIT_DIR/COMMIT_EDITMSG"
-       ;;
-esac
-
-case "$verify" in
-t)
-       if test -x "$GIT_DIR"/hooks/commit-msg
-       then
-               "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
-       fi
-esac
-
-if test -z "$no_edit"
-then
-    sed -e '
-        /^diff --git a\/.*/{
-           s///
-           q
-       }
-       /^#/d
-    ' "$GIT_DIR"/COMMIT_EDITMSG
-else
-    cat "$GIT_DIR"/COMMIT_EDITMSG
-fi |
-git stripspace >"$GIT_DIR"/COMMIT_MSG
-
-# Test whether the commit message has any content we didn't supply.
-have_commitmsg=
-grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
-       git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
-
-# Is the commit message totally empty?
-if test -s "$GIT_DIR"/COMMIT_BAREMSG
-then
-       if test "$templatefile" != ""
-       then
-               # Test whether this is just the unaltered template.
-               if cnt=$(sed -e '/^#/d' < "$templatefile" |
-                       git stripspace |
-                       diff "$GIT_DIR"/COMMIT_BAREMSG - |
-                       wc -l) &&
-                  test 0 -lt $cnt
-               then
-                       have_commitmsg=t
-               fi
-       else
-               # No template, so the content in the commit message must
-               # have come from the user.
-               have_commitmsg=t
-       fi
-fi
-
-rm -f "$GIT_DIR"/COMMIT_BAREMSG
-
-if test "$have_commitmsg" = "t"
-then
-       if test -z "$TMP_INDEX"
-       then
-               tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
-       else
-               tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
-               rm -f "$TMP_INDEX"
-       fi &&
-       commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
-       rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
-       git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
-       rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
-       if test -f "$NEXT_INDEX"
-       then
-               mv "$NEXT_INDEX" "$THIS_INDEX"
-       else
-               : ;# happy
-       fi
-else
-       echo >&2 "* no commit message?  aborting commit."
-       false
-fi
-ret="$?"
-rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-
-cd_to_toplevel
-
-git rerere
-
-if test "$ret" = 0
-then
-       git gc --auto
-       if test -x "$GIT_DIR"/hooks/post-commit
-       then
-               "$GIT_DIR"/hooks/post-commit
-       fi
-       if test -z "$quiet"
-       then
-               commit=$(git diff-tree --always --shortstat --pretty="format:%h: %s"\
-                      --abbrev --summary --root HEAD --)
-               echo "Created${initial_commit:+ initial} commit $commit"
-       fi
-fi
-
-exit "$ret"
diff --git a/contrib/examples/git-difftool.perl b/contrib/examples/git-difftool.perl
deleted file mode 100755 (executable)
index b2ea80f..0000000
+++ /dev/null
@@ -1,481 +0,0 @@
-#!/usr/bin/perl
-# Copyright (c) 2009, 2010 David Aguilar
-# Copyright (c) 2012 Tim Henigan
-#
-# This is a wrapper around the GIT_EXTERNAL_DIFF-compatible
-# git-difftool--helper script.
-#
-# This script exports GIT_EXTERNAL_DIFF and GIT_PAGER for use by git.
-# The GIT_DIFF* variables are exported for use by git-difftool--helper.
-#
-# Any arguments that are unknown to this script are forwarded to 'git diff'.
-
-use 5.008;
-use strict;
-use warnings;
-use Git::LoadCPAN::Error qw(:try);
-use File::Basename qw(dirname);
-use File::Copy;
-use File::Find;
-use File::stat;
-use File::Path qw(mkpath rmtree);
-use File::Temp qw(tempdir);
-use Getopt::Long qw(:config pass_through);
-use Git;
-use Git::I18N;
-
-sub usage
-{
-       my $exitcode = shift;
-       print << 'USAGE';
-usage: git difftool [-t|--tool=<tool>] [--tool-help]
-                    [-x|--extcmd=<cmd>]
-                    [-g|--gui] [--no-gui]
-                    [--prompt] [-y|--no-prompt]
-                    [-d|--dir-diff]
-                    ['git diff' options]
-USAGE
-       exit($exitcode);
-}
-
-sub print_tool_help
-{
-       # See the comment at the bottom of file_diff() for the reason behind
-       # using system() followed by exit() instead of exec().
-       my $rc = system(qw(git mergetool --tool-help=diff));
-       exit($rc | ($rc >> 8));
-}
-
-sub exit_cleanup
-{
-       my ($tmpdir, $status) = @_;
-       my $errno = $!;
-       rmtree($tmpdir);
-       if ($status and $errno) {
-               my ($package, $file, $line) = caller();
-               warn "$file line $line: $errno\n";
-       }
-       exit($status | ($status >> 8));
-}
-
-sub use_wt_file
-{
-       my ($file, $sha1) = @_;
-       my $null_sha1 = '0' x 40;
-
-       if (-l $file || ! -e _) {
-               return (0, $null_sha1);
-       }
-
-       my $wt_sha1 = Git::command_oneline('hash-object', $file);
-       my $use = ($sha1 eq $null_sha1) || ($sha1 eq $wt_sha1);
-       return ($use, $wt_sha1);
-}
-
-sub changed_files
-{
-       my ($repo_path, $index, $worktree) = @_;
-       $ENV{GIT_INDEX_FILE} = $index;
-
-       my @gitargs = ('--git-dir', $repo_path, '--work-tree', $worktree);
-       my @refreshargs = (
-               @gitargs, 'update-index',
-               '--really-refresh', '-q', '--unmerged');
-       try {
-               Git::command_oneline(@refreshargs);
-       } catch Git::Error::Command with {};
-
-       my @diffargs = (@gitargs, 'diff-files', '--name-only', '-z');
-       my $line = Git::command_oneline(@diffargs);
-       my @files;
-       if (defined $line) {
-               @files = split('\0', $line);
-       } else {
-               @files = ();
-       }
-
-       delete($ENV{GIT_INDEX_FILE});
-
-       return map { $_ => 1 } @files;
-}
-
-sub setup_dir_diff
-{
-       my ($worktree, $symlinks) = @_;
-       my @gitargs = ('diff', '--raw', '--no-abbrev', '-z', @ARGV);
-       my $diffrtn = Git::command_oneline(@gitargs);
-       exit(0) unless defined($diffrtn);
-
-       # Go to the root of the worktree now that we've captured the list of
-       # changed files.  The paths returned by diff --raw are relative to the
-       # top-level of the repository, but we defer changing directories so
-       # that @ARGV can perform pathspec limiting in the current directory.
-       chdir($worktree);
-
-       # Build index info for left and right sides of the diff
-       my $submodule_mode = '160000';
-       my $symlink_mode = '120000';
-       my $null_mode = '0' x 6;
-       my $null_sha1 = '0' x 40;
-       my $lindex = '';
-       my $rindex = '';
-       my $wtindex = '';
-       my %submodule;
-       my %symlink;
-       my @files = ();
-       my %working_tree_dups = ();
-       my @rawdiff = split('\0', $diffrtn);
-
-       my $i = 0;
-       while ($i < $#rawdiff) {
-               if ($rawdiff[$i] =~ /^::/) {
-                       warn __ <<'EOF';
-Combined diff formats ('-c' and '--cc') are not supported in
-directory diff mode ('-d' and '--dir-diff').
-EOF
-                       exit(1);
-               }
-
-               my ($lmode, $rmode, $lsha1, $rsha1, $status) =
-                       split(' ', substr($rawdiff[$i], 1));
-               my $src_path = $rawdiff[$i + 1];
-               my $dst_path;
-
-               if ($status =~ /^[CR]/) {
-                       $dst_path = $rawdiff[$i + 2];
-                       $i += 3;
-               } else {
-                       $dst_path = $src_path;
-                       $i += 2;
-               }
-
-               if ($lmode eq $submodule_mode or $rmode eq $submodule_mode) {
-                       $submodule{$src_path}{left} = $lsha1;
-                       if ($lsha1 ne $rsha1) {
-                               $submodule{$dst_path}{right} = $rsha1;
-                       } else {
-                               $submodule{$dst_path}{right} = "$rsha1-dirty";
-                       }
-                       next;
-               }
-
-               if ($lmode eq $symlink_mode) {
-                       $symlink{$src_path}{left} =
-                               Git::command_oneline('show', $lsha1);
-               }
-
-               if ($rmode eq $symlink_mode) {
-                       $symlink{$dst_path}{right} =
-                               Git::command_oneline('show', $rsha1);
-               }
-
-               if ($lmode ne $null_mode and $status !~ /^C/) {
-                       $lindex .= "$lmode $lsha1\t$src_path\0";
-               }
-
-               if ($rmode ne $null_mode) {
-                       # Avoid duplicate entries
-                       if ($working_tree_dups{$dst_path}++) {
-                               next;
-                       }
-                       my ($use, $wt_sha1) =
-                               use_wt_file($dst_path, $rsha1);
-                       if ($use) {
-                               push @files, $dst_path;
-                               $wtindex .= "$rmode $wt_sha1\t$dst_path\0";
-                       } else {
-                               $rindex .= "$rmode $rsha1\t$dst_path\0";
-                       }
-               }
-       }
-
-       # Go to the root of the worktree so that the left index files
-       # are properly setup -- the index is toplevel-relative.
-       chdir($worktree);
-
-       # Setup temp directories
-       my $tmpdir = tempdir('git-difftool.XXXXX', CLEANUP => 0, TMPDIR => 1);
-       my $ldir = "$tmpdir/left";
-       my $rdir = "$tmpdir/right";
-       mkpath($ldir) or exit_cleanup($tmpdir, 1);
-       mkpath($rdir) or exit_cleanup($tmpdir, 1);
-
-       # Populate the left and right directories based on each index file
-       my ($inpipe, $ctx);
-       $ENV{GIT_INDEX_FILE} = "$tmpdir/lindex";
-       ($inpipe, $ctx) =
-               Git::command_input_pipe('update-index', '-z', '--index-info');
-       print($inpipe $lindex);
-       Git::command_close_pipe($inpipe, $ctx);
-
-       my $rc = system('git', 'checkout-index', '--all', "--prefix=$ldir/");
-       exit_cleanup($tmpdir, $rc) if $rc != 0;
-
-       $ENV{GIT_INDEX_FILE} = "$tmpdir/rindex";
-       ($inpipe, $ctx) =
-               Git::command_input_pipe('update-index', '-z', '--index-info');
-       print($inpipe $rindex);
-       Git::command_close_pipe($inpipe, $ctx);
-
-       $rc = system('git', 'checkout-index', '--all', "--prefix=$rdir/");
-       exit_cleanup($tmpdir, $rc) if $rc != 0;
-
-       $ENV{GIT_INDEX_FILE} = "$tmpdir/wtindex";
-       ($inpipe, $ctx) =
-               Git::command_input_pipe('update-index', '--info-only', '-z', '--index-info');
-       print($inpipe $wtindex);
-       Git::command_close_pipe($inpipe, $ctx);
-
-       # If $GIT_DIR was explicitly set just for the update/checkout
-       # commands, then it should be unset before continuing.
-       delete($ENV{GIT_INDEX_FILE});
-
-       # Changes in the working tree need special treatment since they are
-       # not part of the index.
-       for my $file (@files) {
-               my $dir = dirname($file);
-               unless (-d "$rdir/$dir") {
-                       mkpath("$rdir/$dir") or
-                       exit_cleanup($tmpdir, 1);
-               }
-               if ($symlinks) {
-                       symlink("$worktree/$file", "$rdir/$file") or
-                       exit_cleanup($tmpdir, 1);
-               } else {
-                       copy($file, "$rdir/$file") or
-                       exit_cleanup($tmpdir, 1);
-
-                       my $mode = stat($file)->mode;
-                       chmod($mode, "$rdir/$file") or
-                       exit_cleanup($tmpdir, 1);
-               }
-       }
-
-       # Changes to submodules require special treatment. This loop writes a
-       # temporary file to both the left and right directories to show the
-       # change in the recorded SHA1 for the submodule.
-       for my $path (keys %submodule) {
-               my $ok = 0;
-               if (defined($submodule{$path}{left})) {
-                       $ok = write_to_file("$ldir/$path",
-                               "Subproject commit $submodule{$path}{left}");
-               }
-               if (defined($submodule{$path}{right})) {
-                       $ok = write_to_file("$rdir/$path",
-                               "Subproject commit $submodule{$path}{right}");
-               }
-               exit_cleanup($tmpdir, 1) if not $ok;
-       }
-
-       # Symbolic links require special treatment. The standard "git diff"
-       # shows only the link itself, not the contents of the link target.
-       # This loop replicates that behavior.
-       for my $path (keys %symlink) {
-               my $ok = 0;
-               if (defined($symlink{$path}{left})) {
-                       $ok = write_to_file("$ldir/$path",
-                                       $symlink{$path}{left});
-               }
-               if (defined($symlink{$path}{right})) {
-                       $ok = write_to_file("$rdir/$path",
-                                       $symlink{$path}{right});
-               }
-               exit_cleanup($tmpdir, 1) if not $ok;
-       }
-
-       return ($ldir, $rdir, $tmpdir, @files);
-}
-
-sub write_to_file
-{
-       my $path = shift;
-       my $value = shift;
-
-       # Make sure the path to the file exists
-       my $dir = dirname($path);
-       unless (-d "$dir") {
-               mkpath("$dir") or return 0;
-       }
-
-       # If the file already exists in that location, delete it.  This
-       # is required in the case of symbolic links.
-       unlink($path);
-
-       open(my $fh, '>', $path) or return 0;
-       print($fh $value);
-       close($fh);
-
-       return 1;
-}
-
-sub main
-{
-       # parse command-line options. all unrecognized options and arguments
-       # are passed through to the 'git diff' command.
-       my %opts = (
-               difftool_cmd => undef,
-               dirdiff => undef,
-               extcmd => undef,
-               gui => undef,
-               help => undef,
-               prompt => undef,
-               symlinks => $^O ne 'cygwin' &&
-                               $^O ne 'MSWin32' && $^O ne 'msys',
-               tool_help => undef,
-               trust_exit_code => undef,
-       );
-       GetOptions('g|gui!' => \$opts{gui},
-               'd|dir-diff' => \$opts{dirdiff},
-               'h' => \$opts{help},
-               'prompt!' => \$opts{prompt},
-               'y' => sub { $opts{prompt} = 0; },
-               'symlinks' => \$opts{symlinks},
-               'no-symlinks' => sub { $opts{symlinks} = 0; },
-               't|tool:s' => \$opts{difftool_cmd},
-               'tool-help' => \$opts{tool_help},
-               'trust-exit-code' => \$opts{trust_exit_code},
-               'no-trust-exit-code' => sub { $opts{trust_exit_code} = 0; },
-               'x|extcmd:s' => \$opts{extcmd});
-
-       if (defined($opts{help})) {
-               usage(0);
-       }
-       if (defined($opts{tool_help})) {
-               print_tool_help();
-       }
-       if (defined($opts{difftool_cmd})) {
-               if (length($opts{difftool_cmd}) > 0) {
-                       $ENV{GIT_DIFF_TOOL} = $opts{difftool_cmd};
-               } else {
-                       print __("No <tool> given for --tool=<tool>\n");
-                       usage(1);
-               }
-       }
-       if (defined($opts{extcmd})) {
-               if (length($opts{extcmd}) > 0) {
-                       $ENV{GIT_DIFFTOOL_EXTCMD} = $opts{extcmd};
-               } else {
-                       print __("No <cmd> given for --extcmd=<cmd>\n");
-                       usage(1);
-               }
-       }
-       if ($opts{gui}) {
-               my $guitool = Git::config('diff.guitool');
-               if (defined($guitool) && length($guitool) > 0) {
-                       $ENV{GIT_DIFF_TOOL} = $guitool;
-               }
-       }
-
-       if (!defined $opts{trust_exit_code}) {
-               $opts{trust_exit_code} = Git::config_bool('difftool.trustExitCode');
-       }
-       if ($opts{trust_exit_code}) {
-               $ENV{GIT_DIFFTOOL_TRUST_EXIT_CODE} = 'true';
-       } else {
-               $ENV{GIT_DIFFTOOL_TRUST_EXIT_CODE} = 'false';
-       }
-
-       # In directory diff mode, 'git-difftool--helper' is called once
-       # to compare the a/b directories.  In file diff mode, 'git diff'
-       # will invoke a separate instance of 'git-difftool--helper' for
-       # each file that changed.
-       if (defined($opts{dirdiff})) {
-               dir_diff($opts{extcmd}, $opts{symlinks});
-       } else {
-               file_diff($opts{prompt});
-       }
-}
-
-sub dir_diff
-{
-       my ($extcmd, $symlinks) = @_;
-       my $rc;
-       my $error = 0;
-       my $repo = Git->repository();
-       my $repo_path = $repo->repo_path();
-       my $worktree = $repo->wc_path();
-       $worktree =~ s|/$||; # Avoid double slashes in symlink targets
-       my ($a, $b, $tmpdir, @files) = setup_dir_diff($worktree, $symlinks);
-
-       if (defined($extcmd)) {
-               $rc = system($extcmd, $a, $b);
-       } else {
-               $ENV{GIT_DIFFTOOL_DIRDIFF} = 'true';
-               $rc = system('git', 'difftool--helper', $a, $b);
-       }
-       # If the diff including working copy files and those
-       # files were modified during the diff, then the changes
-       # should be copied back to the working tree.
-       # Do not copy back files when symlinks are used and the
-       # external tool did not replace the original link with a file.
-       #
-       # These hashes are loaded lazily since they aren't needed
-       # in the common case of --symlinks and the difftool updating
-       # files through the symlink.
-       my %wt_modified;
-       my %tmp_modified;
-       my $indices_loaded = 0;
-
-       for my $file (@files) {
-               next if $symlinks && -l "$b/$file";
-               next if ! -f "$b/$file";
-
-               if (!$indices_loaded) {
-                       %wt_modified = changed_files(
-                               $repo_path, "$tmpdir/wtindex", $worktree);
-                       %tmp_modified = changed_files(
-                               $repo_path, "$tmpdir/wtindex", $b);
-                       $indices_loaded = 1;
-               }
-
-               if (exists $wt_modified{$file} and exists $tmp_modified{$file}) {
-                       warn sprintf(__(
-                               "warning: Both files modified:\n" .
-                               "'%s/%s' and '%s/%s'.\n" .
-                               "warning: Working tree file has been left.\n" .
-                               "warning:\n"), $worktree, $file, $b, $file);
-                       $error = 1;
-               } elsif (exists $tmp_modified{$file}) {
-                       my $mode = stat("$b/$file")->mode;
-                       copy("$b/$file", $file) or
-                       exit_cleanup($tmpdir, 1);
-
-                       chmod($mode, $file) or
-                       exit_cleanup($tmpdir, 1);
-               }
-       }
-       if ($error) {
-               warn sprintf(__(
-                       "warning: Temporary files exist in '%s'.\n" .
-                       "warning: You may want to cleanup or recover these.\n"), $tmpdir);
-               exit(1);
-       } else {
-               exit_cleanup($tmpdir, $rc);
-       }
-}
-
-sub file_diff
-{
-       my ($prompt) = @_;
-
-       if (defined($prompt)) {
-               if ($prompt) {
-                       $ENV{GIT_DIFFTOOL_PROMPT} = 'true';
-               } else {
-                       $ENV{GIT_DIFFTOOL_NO_PROMPT} = 'true';
-               }
-       }
-
-       $ENV{GIT_PAGER} = '';
-       $ENV{GIT_EXTERNAL_DIFF} = 'git-difftool--helper';
-
-       # ActiveState Perl for Win32 does not implement POSIX semantics of
-       # exec* system call. It just spawns the given executable and finishes
-       # the starting program, exiting with code 0.
-       # system will at least catch the errors returned by git diff,
-       # allowing the caller of git difftool better handling of failures.
-       my $rc = system('git', 'diff', @ARGV);
-       exit($rc | ($rc >> 8));
-}
-
-main();
diff --git a/contrib/examples/git-fetch.sh b/contrib/examples/git-fetch.sh
deleted file mode 100755 (executable)
index 57d2e56..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-#!/bin/sh
-#
-
-USAGE='<fetch-options> <repository> <refspec>...'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-set_reflog_action "fetch $*"
-cd_to_toplevel ;# probably unnecessary...
-
-. git-parse-remote
-_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
-_x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40"
-
-LF='
-'
-IFS="$LF"
-
-no_tags=
-tags=
-append=
-force=
-verbose=
-update_head_ok=
-exec=
-keep=
-shallow_depth=
-no_progress=
-test -t 1 || no_progress=--no-progress
-quiet=
-while test $# != 0
-do
-       case "$1" in
-       -a|--a|--ap|--app|--appe|--appen|--append)
-               append=t
-               ;;
-       --upl|--uplo|--uploa|--upload|--upload-|--upload-p|\
-       --upload-pa|--upload-pac|--upload-pack)
-               shift
-               exec="--upload-pack=$1"
-               ;;
-       --upl=*|--uplo=*|--uploa=*|--upload=*|\
-       --upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*)
-               exec=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)')
-               shift
-               ;;
-       -f|--f|--fo|--for|--forc|--force)
-               force=t
-               ;;
-       -t|--t|--ta|--tag|--tags)
-               tags=t
-               ;;
-       -n|--n|--no|--no-|--no-t|--no-ta|--no-tag|--no-tags)
-               no_tags=t
-               ;;
-       -u|--u|--up|--upd|--upda|--updat|--update|--update-|--update-h|\
-       --update-he|--update-hea|--update-head|--update-head-|\
-       --update-head-o|--update-head-ok)
-               update_head_ok=t
-               ;;
-       -q|--q|--qu|--qui|--quie|--quiet)
-               quiet=--quiet
-               ;;
-       -v|--verbose)
-               verbose="$verbose"Yes
-               ;;
-       -k|--k|--ke|--kee|--keep)
-               keep='-k -k'
-               ;;
-       --depth=*)
-               shallow_depth="--depth=$(expr "z$1" : 'z-[^=]*=\(.*\)')"
-               ;;
-       --depth)
-               shift
-               shallow_depth="--depth=$1"
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               break
-               ;;
-       esac
-       shift
-done
-
-case "$#" in
-0)
-       origin=$(get_default_remote)
-       test -n "$(get_remote_url ${origin})" ||
-               die "Where do you want to fetch from today?"
-       set x $origin ; shift ;;
-esac
-
-if test -z "$exec"
-then
-       # No command line override and we have configuration for the remote.
-       exec="--upload-pack=$(get_uploadpack $1)"
-fi
-
-remote_nick="$1"
-remote=$(get_remote_url "$@")
-refs=
-rref=
-rsync_slurped_objects=
-
-if test "" = "$append"
-then
-       : >"$GIT_DIR/FETCH_HEAD"
-fi
-
-# Global that is reused later
-ls_remote_result=$(git ls-remote $exec "$remote") ||
-       die "Cannot get the repository state from $remote"
-
-append_fetch_head () {
-       flags=
-       test -n "$verbose" && flags="$flags$LF-v"
-       test -n "$force$single_force" && flags="$flags$LF-f"
-       GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \
-               git fetch--tool $flags append-fetch-head "$@"
-}
-
-# updating the current HEAD with git-fetch in a bare
-# repository is always fine.
-if test -z "$update_head_ok" && test $(is_bare_repository) = false
-then
-       orig_head=$(git rev-parse --verify HEAD 2>/dev/null)
-fi
-
-# Allow --tags/--notags from remote.$1.tagopt
-case "$tags$no_tags" in
-'')
-       case "$(git config --get "remote.$1.tagopt")" in
-       --tags)
-               tags=t ;;
-       --no-tags)
-               no_tags=t ;;
-       esac
-esac
-
-# If --tags (and later --heads or --all) is specified, then we are
-# not talking about defaults stored in Pull: line of remotes or
-# branches file, and just fetch those and refspecs explicitly given.
-# Otherwise we do what we always did.
-
-reflist=$(get_remote_refs_for_fetch "$@")
-if test "$tags"
-then
-       taglist=$(IFS=' ' &&
-                 echo "$ls_remote_result" |
-                 git show-ref --exclude-existing=refs/tags/ |
-                 while read sha1 name
-                 do
-                       echo ".${name}:${name}"
-                 done) || exit
-       if test "$#" -gt 1
-       then
-               # remote URL plus explicit refspecs; we need to merge them.
-               reflist="$reflist$LF$taglist"
-       else
-               # No explicit refspecs; fetch tags only.
-               reflist=$taglist
-       fi
-fi
-
-fetch_all_at_once () {
-
-  eval=$(echo "$1" | git fetch--tool parse-reflist "-")
-  eval "$eval"
-
-    ( : subshell because we muck with IFS
-      IFS="    $LF"
-      (
-       if test "$remote" = . ; then
-           git show-ref $rref || echo failed "$remote"
-       elif test -f "$remote" ; then
-           test -n "$shallow_depth" &&
-               die "shallow clone with bundle is not supported"
-           git bundle unbundle "$remote" $rref ||
-           echo failed "$remote"
-       else
-               if      test -d "$remote" &&
-
-                       # The remote might be our alternate.  With
-                       # this optimization we will bypass fetch-pack
-                       # altogether, which means we cannot be doing
-                       # the shallow stuff at all.
-                       test ! -f "$GIT_DIR/shallow" &&
-                       test -z "$shallow_depth" &&
-
-                       # See if all of what we are going to fetch are
-                       # connected to our repository's tips, in which
-                       # case we do not have to do any fetch.
-                       theirs=$(echo "$ls_remote_result" | \
-                               git fetch--tool -s pick-rref "$rref" "-") &&
-
-                       # This will barf when $theirs reach an object that
-                       # we do not have in our repository.  Otherwise,
-                       # we already have everything the fetch would bring in.
-                       git rev-list --objects $theirs --not --all \
-                               >/dev/null 2>/dev/null
-               then
-                       echo "$ls_remote_result" | \
-                               git fetch--tool pick-rref "$rref" "-"
-               else
-                       flags=
-                       case $verbose in
-                       YesYes*)
-                           flags="-v"
-                           ;;
-                       esac
-                       git-fetch-pack --thin $exec $keep $shallow_depth \
-                               $quiet $no_progress $flags "$remote" $rref ||
-                       echo failed "$remote"
-               fi
-       fi
-      ) |
-      (
-       flags=
-       test -n "$verbose" && flags="$flags -v"
-       test -n "$force" && flags="$flags -f"
-       GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION" \
-               git fetch--tool $flags native-store \
-                       "$remote" "$remote_nick" "$refs"
-      )
-    ) || exit
-
-}
-
-fetch_per_ref () {
-  reflist="$1"
-  refs=
-  rref=
-
-  for ref in $reflist
-  do
-      refs="$refs$LF$ref"
-
-      # These are relative path from $GIT_DIR, typically starting at refs/
-      # but may be HEAD
-      if expr "z$ref" : 'z\.' >/dev/null
-      then
-         not_for_merge=t
-         ref=$(expr "z$ref" : 'z\.\(.*\)')
-      else
-         not_for_merge=
-      fi
-      if expr "z$ref" : 'z+' >/dev/null
-      then
-         single_force=t
-         ref=$(expr "z$ref" : 'z+\(.*\)')
-      else
-         single_force=
-      fi
-      remote_name=$(expr "z$ref" : 'z\([^:]*\):')
-      local_name=$(expr "z$ref" : 'z[^:]*:\(.*\)')
-
-      rref="$rref$LF$remote_name"
-
-      # There are transports that can fetch only one head at a time...
-      case "$remote" in
-      http://* | https://* | ftp://*)
-         test -n "$shallow_depth" &&
-               die "shallow clone with http not supported"
-         proto=$(expr "$remote" : '\([^:]*\):')
-         if [ -n "$GIT_SSL_NO_VERIFY" ]; then
-             curl_extra_args="-k"
-         fi
-         if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
-               "$(git config --bool http.noEPSV)" = true ]; then
-             noepsv_opt="--disable-epsv"
-         fi
-
-         # Find $remote_name from ls-remote output.
-         head=$(echo "$ls_remote_result" | \
-               git fetch--tool -s pick-rref "$remote_name" "-")
-         expr "z$head" : "z$_x40\$" >/dev/null ||
-               die "No such ref $remote_name at $remote"
-         echo >&2 "Fetching $remote_name from $remote using $proto"
-         case "$quiet" in '') v=-v ;; *) v= ;; esac
-         git-http-fetch $v -a "$head" "$remote" || exit
-         ;;
-      rsync://*)
-         test -n "$shallow_depth" &&
-               die "shallow clone with rsync not supported"
-         TMP_HEAD="$GIT_DIR/TMP_HEAD"
-         rsync -L -q "$remote/$remote_name" "$TMP_HEAD" || exit 1
-         head=$(git rev-parse --verify TMP_HEAD)
-         rm -f "$TMP_HEAD"
-         case "$quiet" in '') v=-v ;; *) v= ;; esac
-         test "$rsync_slurped_objects" || {
-             rsync -a $v --ignore-existing --exclude info \
-                 "$remote/objects/" "$GIT_OBJECT_DIRECTORY/" || exit
-
-             # Look at objects/info/alternates for rsync -- http will
-             # support it natively and git native ones will do it on
-             # the remote end.  Not having that file is not a crime.
-             rsync -q "$remote/objects/info/alternates" \
-                 "$GIT_DIR/TMP_ALT" 2>/dev/null ||
-                 rm -f "$GIT_DIR/TMP_ALT"
-             if test -f "$GIT_DIR/TMP_ALT"
-             then
-                 resolve_alternates "$remote" <"$GIT_DIR/TMP_ALT" |
-                 while read alt
-                 do
-                     case "$alt" in 'bad alternate: '*) die "$alt";; esac
-                     echo >&2 "Getting alternate: $alt"
-                     rsync -av --ignore-existing --exclude info \
-                     "$alt" "$GIT_OBJECT_DIRECTORY/" || exit
-                 done
-                 rm -f "$GIT_DIR/TMP_ALT"
-             fi
-             rsync_slurped_objects=t
-         }
-         ;;
-      esac
-
-      append_fetch_head "$head" "$remote" \
-         "$remote_name" "$remote_nick" "$local_name" "$not_for_merge" || exit
-
-  done
-
-}
-
-fetch_main () {
-       case "$remote" in
-       http://* | https://* | ftp://* | rsync://* )
-               fetch_per_ref "$@"
-               ;;
-       *)
-               fetch_all_at_once "$@"
-               ;;
-       esac
-}
-
-fetch_main "$reflist" || exit
-
-# automated tag following
-case "$no_tags$tags" in
-'')
-       case "$reflist" in
-       *:refs/*)
-               # effective only when we are following remote branch
-               # using local tracking branch.
-               taglist=$(IFS=' ' &&
-               echo "$ls_remote_result" |
-               git show-ref --exclude-existing=refs/tags/ |
-               while read sha1 name
-               do
-                       git cat-file -t "$sha1" >/dev/null 2>&1 || continue
-                       echo >&2 "Auto-following $name"
-                       echo ".${name}:${name}"
-               done)
-       esac
-       case "$taglist" in
-       '') ;;
-       ?*)
-               # do not deepen a shallow tree when following tags
-               shallow_depth=
-               fetch_main "$taglist" || exit ;;
-       esac
-esac
-
-# If the original head was empty (i.e. no "master" yet), or
-# if we were told not to worry, we do not have to check.
-case "$orig_head" in
-'')
-       ;;
-?*)
-       curr_head=$(git rev-parse --verify HEAD 2>/dev/null)
-       if test "$curr_head" != "$orig_head"
-       then
-           git update-ref \
-                       -m "$GIT_REFLOG_ACTION: Undoing incorrectly fetched HEAD." \
-                       HEAD "$orig_head"
-               die "Cannot fetch into the current branch."
-       fi
-       ;;
-esac
diff --git a/contrib/examples/git-gc.sh b/contrib/examples/git-gc.sh
deleted file mode 100755 (executable)
index 1597e9f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2006, Shawn O. Pearce
-#
-# Cleanup unreachable files and optimize the repository.
-
-USAGE='[--prune]'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-
-no_prune=:
-while test $# != 0
-do
-       case "$1" in
-       --prune)
-               no_prune=
-               ;;
-       --)
-               usage
-               ;;
-       esac
-       shift
-done
-
-case "$(git config --get gc.packrefs)" in
-notbare|"")
-       test $(is_bare_repository) = true || pack_refs=true;;
-*)
-       pack_refs=$(git config --bool --get gc.packrefs)
-esac
-
-test "true" != "$pack_refs" ||
-git pack-refs --prune &&
-git reflog expire --all &&
-git-repack -a -d -l &&
-$no_prune git prune &&
-git rerere gc || exit
diff --git a/contrib/examples/git-log.sh b/contrib/examples/git-log.sh
deleted file mode 100755 (executable)
index c2ea71c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-#
-
-USAGE='[--max-count=<n>] [<since>..<limit>] [--pretty=<format>] [git-rev-list options]'
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-revs=$(git-rev-parse --revs-only --no-flags --default HEAD "$@") || exit
-[ "$revs" ] || {
-       die "No HEAD ref"
-}
-git-rev-list --pretty $(git-rev-parse --default HEAD "$@") |
-LESS=-S ${PAGER:-less}
diff --git a/contrib/examples/git-ls-remote.sh b/contrib/examples/git-ls-remote.sh
deleted file mode 100755 (executable)
index 2aa89a7..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/bin/sh
-#
-
-usage () {
-    echo >&2 "usage: $0 [--heads] [--tags] [-u|--upload-pack <upload-pack>]"
-    echo >&2 "          <repository> <refs>..."
-    exit 1;
-}
-
-die () {
-    echo >&2 "$*"
-    exit 1
-}
-
-exec=
-while test $# != 0
-do
-  case "$1" in
-  -h|--h|--he|--hea|--head|--heads)
-  heads=heads; shift ;;
-  -t|--t|--ta|--tag|--tags)
-  tags=tags; shift ;;
-  -u|--u|--up|--upl|--uploa|--upload|--upload-|--upload-p|--upload-pa|\
-  --upload-pac|--upload-pack)
-       shift
-       exec="--upload-pack=$1"
-       shift;;
-  -u=*|--u=*|--up=*|--upl=*|--uplo=*|--uploa=*|--upload=*|\
-  --upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*)
-       exec=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)')
-       shift;;
-  --)
-  shift; break ;;
-  -*)
-  usage ;;
-  *)
-  break ;;
-  esac
-done
-
-case "$#" in 0) usage ;; esac
-
-case ",$heads,$tags," in
-,,,) heads=heads tags=tags other=other ;;
-esac
-
-. git-parse-remote
-peek_repo="$(get_remote_url "$@")"
-shift
-
-tmp=.ls-remote-$$
-trap "rm -fr $tmp-*" 0 1 2 3 15
-tmpdir=$tmp-d
-
-case "$peek_repo" in
-http://* | https://* | ftp://* )
-       if [ -n "$GIT_SSL_NO_VERIFY" -o \
-               "$(git config --bool http.sslVerify)" = false ]; then
-               curl_extra_args="-k"
-       fi
-       if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
-               "$(git config --bool http.noEPSV)" = true ]; then
-               curl_extra_args="${curl_extra_args} --disable-epsv"
-       fi
-       curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" ||
-               echo "failed    slurping"
-       ;;
-
-rsync://* )
-       mkdir $tmpdir &&
-       rsync -rlq "$peek_repo/HEAD" $tmpdir &&
-       rsync -rq "$peek_repo/refs" $tmpdir || {
-               echo "failed    slurping"
-               exit
-       }
-       head=$(cat "$tmpdir/HEAD") &&
-       case "$head" in
-       ref:' '*)
-               head=$(expr "z$head" : 'zref: \(.*\)') &&
-               head=$(cat "$tmpdir/$head") || exit
-       esac &&
-       echo "$head     HEAD"
-       (cd $tmpdir && find refs -type f) |
-       while read path
-       do
-               tr -d '\012' <"$tmpdir/$path"
-               echo "  $path"
-       done &&
-       rm -fr $tmpdir
-       ;;
-
-* )
-       if test -f "$peek_repo" ; then
-               git bundle list-heads "$peek_repo" ||
-               echo "failed    slurping"
-       else
-               git-peek-remote $exec "$peek_repo" ||
-               echo "failed    slurping"
-       fi
-       ;;
-esac |
-sort -t '      ' -k 2 |
-while read sha1 path
-do
-       case "$sha1" in
-       failed)
-               exit 1 ;;
-       esac
-       case "$path" in
-       refs/heads/*)
-               group=heads ;;
-       refs/tags/*)
-               group=tags ;;
-       *)
-               group=other ;;
-       esac
-       case ",$heads,$tags,$other," in
-       *,$group,*)
-               ;;
-       *)
-               continue;;
-       esac
-       case "$#" in
-       0)
-               match=yes ;;
-       *)
-               match=no
-               for pat
-               do
-                       case "/$path" in
-                       */$pat )
-                               match=yes
-                               break ;;
-                       esac
-               done
-       esac
-       case "$match" in
-       no)
-               continue ;;
-       esac
-       echo "$sha1     $path"
-done
diff --git a/contrib/examples/git-merge-ours.sh b/contrib/examples/git-merge-ours.sh
deleted file mode 100755 (executable)
index 29dba4b..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Junio C Hamano
-#
-# Pretend we resolved the heads, but declare our tree trumps everybody else.
-#
-
-# We need to exit with 2 if the index does not match our HEAD tree,
-# because the current index is what we will be committing as the
-# merge result.
-
-git diff-index --quiet --cached HEAD -- || exit 2
-
-exit 0
diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh
deleted file mode 100755 (executable)
index 932e78d..0000000
+++ /dev/null
@@ -1,620 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Junio C Hamano
-#
-
-OPTIONS_KEEPDASHDASH=
-OPTIONS_SPEC="\
-git merge [options] <remote>...
-git merge [options] <msg> HEAD <remote>
---
-stat                 show a diffstat at the end of the merge
-n                    don't show a diffstat at the end of the merge
-summary              (synonym to --stat)
-log                  add list of one-line log to merge commit message
-squash               create a single commit instead of doing a merge
-commit               perform a commit if the merge succeeds (default)
-ff                   allow fast-forward (default)
-ff-only              abort if fast-forward is not possible
-rerere-autoupdate    update index with any reused conflict resolution
-s,strategy=          merge strategy to use
-X=                   option for selected merge strategy
-m,message=           message to be used for the merge commit (if any)
-"
-
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-require_work_tree
-cd_to_toplevel
-
-test -z "$(git ls-files -u)" ||
-       die "Merge is not possible because you have unmerged files."
-
-! test -e "$GIT_DIR/MERGE_HEAD" ||
-       die 'You have not concluded your merge (MERGE_HEAD exists).'
-
-LF='
-'
-
-all_strategies='recur recursive octopus resolve stupid ours subtree'
-all_strategies="$all_strategies recursive-ours recursive-theirs"
-not_strategies='base file index tree'
-default_twohead_strategies='recursive'
-default_octopus_strategies='octopus'
-no_fast_forward_strategies='subtree ours'
-no_trivial_strategies='recursive recur subtree ours recursive-ours recursive-theirs'
-use_strategies=
-xopt=
-
-allow_fast_forward=t
-fast_forward_only=
-allow_trivial_merge=t
-squash= no_commit= log_arg= rr_arg=
-
-dropsave() {
-       rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
-                "$GIT_DIR/MERGE_STASH" "$GIT_DIR/MERGE_MODE" || exit 1
-}
-
-savestate() {
-       # Stash away any local modifications.
-       git stash create >"$GIT_DIR/MERGE_STASH"
-}
-
-restorestate() {
-        if test -f "$GIT_DIR/MERGE_STASH"
-       then
-               git reset --hard $head >/dev/null
-               git stash apply $(cat "$GIT_DIR/MERGE_STASH")
-               git update-index --refresh >/dev/null
-       fi
-}
-
-finish_up_to_date () {
-       case "$squash" in
-       t)
-               echo "$1 (nothing to squash)" ;;
-       '')
-               echo "$1" ;;
-       esac
-       dropsave
-}
-
-squash_message () {
-       echo Squashed commit of the following:
-       echo
-       git log --no-merges --pretty=medium ^"$head" $remoteheads
-}
-
-finish () {
-       if test '' = "$2"
-       then
-               rlogm="$GIT_REFLOG_ACTION"
-       else
-               echo "$2"
-               rlogm="$GIT_REFLOG_ACTION: $2"
-       fi
-       case "$squash" in
-       t)
-               echo "Squash commit -- not updating HEAD"
-               squash_message >"$GIT_DIR/SQUASH_MSG"
-               ;;
-       '')
-               case "$merge_msg" in
-               '')
-                       echo "No merge message -- not updating HEAD"
-                       ;;
-               *)
-                       git update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
-                       git gc --auto
-                       ;;
-               esac
-               ;;
-       esac
-       case "$1" in
-       '')
-               ;;
-       ?*)
-               if test "$show_diffstat" = t
-               then
-                       # We want color (if set), but no pager
-                       GIT_PAGER='' git diff --stat --summary -M "$head" "$1"
-               fi
-               ;;
-       esac
-
-       # Run a post-merge hook
-        if test -x "$GIT_DIR"/hooks/post-merge
-        then
-           case "$squash" in
-           t)
-                "$GIT_DIR"/hooks/post-merge 1
-               ;;
-           '')
-                "$GIT_DIR"/hooks/post-merge 0
-               ;;
-           esac
-        fi
-}
-
-merge_name () {
-       remote="$1"
-       rh=$(git rev-parse --verify "$remote^0" 2>/dev/null) || return
-       if truname=$(expr "$remote" : '\(.*\)~[0-9]*$') &&
-               git show-ref -q --verify "refs/heads/$truname" 2>/dev/null
-       then
-               echo "$rh               branch '$truname' (early part) of ."
-               return
-       fi
-       if found_ref=$(git rev-parse --symbolic-full-name --verify \
-                                                       "$remote" 2>/dev/null)
-       then
-               expanded=$(git check-ref-format --branch "$remote") ||
-                       exit
-               if test "${found_ref#refs/heads/}" != "$found_ref"
-               then
-                       echo "$rh               branch '$expanded' of ."
-                       return
-               elif test "${found_ref#refs/remotes/}" != "$found_ref"
-               then
-                       echo "$rh               remote branch '$expanded' of ."
-                       return
-               fi
-       fi
-       if test "$remote" = "FETCH_HEAD" && test -r "$GIT_DIR/FETCH_HEAD"
-       then
-               sed -e 's/      not-for-merge   /               /' -e 1q \
-                       "$GIT_DIR/FETCH_HEAD"
-               return
-       fi
-       echo "$rh               commit '$remote'"
-}
-
-parse_config () {
-       while test $# != 0; do
-               case "$1" in
-               -n|--no-stat|--no-summary)
-                       show_diffstat=false ;;
-               --stat|--summary)
-                       show_diffstat=t ;;
-               --log|--no-log)
-                       log_arg=$1 ;;
-               --squash)
-                       test "$allow_fast_forward" = t ||
-                               die "You cannot combine --squash with --no-ff."
-                       squash=t no_commit=t ;;
-               --no-squash)
-                       squash= no_commit= ;;
-               --commit)
-                       no_commit= ;;
-               --no-commit)
-                       no_commit=t ;;
-               --ff)
-                       allow_fast_forward=t ;;
-               --no-ff)
-                       test "$squash" != t ||
-                               die "You cannot combine --squash with --no-ff."
-                       test "$fast_forward_only" != t ||
-                               die "You cannot combine --ff-only with --no-ff."
-                       allow_fast_forward=f ;;
-               --ff-only)
-                       test "$allow_fast_forward" != f ||
-                               die "You cannot combine --ff-only with --no-ff."
-                       fast_forward_only=t ;;
-               --rerere-autoupdate|--no-rerere-autoupdate)
-                       rr_arg=$1 ;;
-               -s|--strategy)
-                       shift
-                       case " $all_strategies " in
-                       *" $1 "*)
-                               use_strategies="$use_strategies$1 "
-                               ;;
-                       *)
-                               case " $not_strategies " in
-                               *" $1 "*)
-                                       false
-                               esac &&
-                               type "git-merge-$1" >/dev/null 2>&1 ||
-                                       die "available strategies are: $all_strategies"
-                               use_strategies="$use_strategies$1 "
-                               ;;
-                       esac
-                       ;;
-               -X)
-                       shift
-                       xopt="${xopt:+$xopt }$(git rev-parse --sq-quote "--$1")"
-                       ;;
-               -m|--message)
-                       shift
-                       merge_msg="$1"
-                       have_message=t
-                       ;;
-               --)
-                       shift
-                       break ;;
-               *)      usage ;;
-               esac
-               shift
-       done
-       args_left=$#
-}
-
-test $# != 0 || usage
-
-have_message=
-
-if branch=$(git-symbolic-ref -q HEAD)
-then
-       mergeopts=$(git config "branch.${branch#refs/heads/}.mergeoptions")
-       if test -n "$mergeopts"
-       then
-               parse_config $mergeopts --
-       fi
-fi
-
-parse_config "$@"
-while test $args_left -lt $#; do shift; done
-
-if test -z "$show_diffstat"; then
-    test "$(git config --bool merge.diffstat)" = false && show_diffstat=false
-    test "$(git config --bool merge.stat)" = false && show_diffstat=false
-    test -z "$show_diffstat" && show_diffstat=t
-fi
-
-# This could be traditional "merge <msg> HEAD <commit>..."  and the
-# way we can tell it is to see if the second token is HEAD, but some
-# people might have misused the interface and used a commit-ish that
-# is the same as HEAD there instead.  Traditional format never would
-# have "-m" so it is an additional safety measure to check for it.
-
-if test -z "$have_message" &&
-       second_token=$(git rev-parse --verify "$2^0" 2>/dev/null) &&
-       head_commit=$(git rev-parse --verify "HEAD" 2>/dev/null) &&
-       test "$second_token" = "$head_commit"
-then
-       merge_msg="$1"
-       shift
-       head_arg="$1"
-       shift
-elif ! git rev-parse --verify HEAD >/dev/null 2>&1
-then
-       # If the merged head is a valid one there is no reason to
-       # forbid "git merge" into a branch yet to be born.  We do
-       # the same for "git pull".
-       if test 1 -ne $#
-       then
-               echo >&2 "Can merge only exactly one commit into empty head"
-               exit 1
-       fi
-
-       test "$squash" != t ||
-               die "Squash commit into empty head not supported yet"
-       test "$allow_fast_forward" = t ||
-               die "Non-fast-forward into an empty head does not make sense"
-       rh=$(git rev-parse --verify "$1^0") ||
-               die "$1 - not something we can merge"
-
-       git update-ref -m "initial pull" HEAD "$rh" "" &&
-       git read-tree --reset -u HEAD
-       exit
-
-else
-       # We are invoked directly as the first-class UI.
-       head_arg=HEAD
-
-       # All the rest are the commits being merged; prepare
-       # the standard merge summary message to be appended to
-       # the given message.  If remote is invalid we will die
-       # later in the common codepath so we discard the error
-       # in this loop.
-       merge_msg="$(
-               for remote
-               do
-                       merge_name "$remote"
-               done |
-               if test "$have_message" = t
-               then
-                       git fmt-merge-msg -m "$merge_msg" $log_arg
-               else
-                       git fmt-merge-msg $log_arg
-               fi
-       )"
-fi
-head=$(git rev-parse --verify "$head_arg"^0) || usage
-
-# All the rest are remote heads
-test "$#" = 0 && usage ;# we need at least one remote head.
-set_reflog_action "merge $*"
-
-remoteheads=
-for remote
-do
-       remotehead=$(git rev-parse --verify "$remote"^0 2>/dev/null) ||
-           die "$remote - not something we can merge"
-       remoteheads="${remoteheads}$remotehead "
-       eval GITHEAD_$remotehead='"$remote"'
-       export GITHEAD_$remotehead
-done
-set x $remoteheads ; shift
-
-case "$use_strategies" in
-'')
-       case "$#" in
-       1)
-               var="$(git config --get pull.twohead)"
-               if test -n "$var"
-               then
-                       use_strategies="$var"
-               else
-                       use_strategies="$default_twohead_strategies"
-               fi ;;
-       *)
-               var="$(git config --get pull.octopus)"
-               if test -n "$var"
-               then
-                       use_strategies="$var"
-               else
-                       use_strategies="$default_octopus_strategies"
-               fi ;;
-       esac
-       ;;
-esac
-
-for s in $use_strategies
-do
-       for ss in $no_fast_forward_strategies
-       do
-               case " $s " in
-               *" $ss "*)
-                       allow_fast_forward=f
-                       break
-                       ;;
-               esac
-       done
-       for ss in $no_trivial_strategies
-       do
-               case " $s " in
-               *" $ss "*)
-                       allow_trivial_merge=f
-                       break
-                       ;;
-               esac
-       done
-done
-
-case "$#" in
-1)
-       common=$(git merge-base --all $head "$@")
-       ;;
-*)
-       common=$(git merge-base --all --octopus $head "$@")
-       ;;
-esac
-echo "$head" >"$GIT_DIR/ORIG_HEAD"
-
-case "$allow_fast_forward,$#,$common,$no_commit" in
-?,*,'',*)
-       # No common ancestors found. We need a real merge.
-       ;;
-?,1,"$1",*)
-       # If head can reach all the merge then we are up to date.
-       # but first the most common case of merging one remote.
-       finish_up_to_date "Already up to date."
-       exit 0
-       ;;
-t,1,"$head",*)
-       # Again the most common case of merging one remote.
-       echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $1)"
-       git update-index --refresh 2>/dev/null
-       msg="Fast-forward"
-       if test -n "$have_message"
-       then
-               msg="$msg (no commit created; -m option ignored)"
-       fi
-       new_head=$(git rev-parse --verify "$1^0") &&
-       git read-tree -v -m -u --exclude-per-directory=.gitignore $head "$new_head" &&
-       finish "$new_head" "$msg" || exit
-       dropsave
-       exit 0
-       ;;
-?,1,?*"$LF"?*,*)
-       # We are not doing octopus and not fast-forward.  Need a
-       # real merge.
-       ;;
-?,1,*,)
-       # We are not doing octopus, not fast-forward, and have only
-       # one common.
-       git update-index --refresh 2>/dev/null
-       case "$allow_trivial_merge,$fast_forward_only" in
-       t,)
-               # See if it is really trivial.
-               git var GIT_COMMITTER_IDENT >/dev/null || exit
-               echo "Trying really trivial in-index merge..."
-               if git read-tree --trivial -m -u -v $common $head "$1" &&
-                  result_tree=$(git write-tree)
-               then
-                       echo "Wonderful."
-                       result_commit=$(
-                               printf '%s\n' "$merge_msg" |
-                               git commit-tree $result_tree -p HEAD -p "$1"
-                       ) || exit
-                       finish "$result_commit" "In-index merge"
-                       dropsave
-                       exit 0
-               fi
-               echo "Nope."
-       esac
-       ;;
-*)
-       # An octopus.  If we can reach all the remote we are up to date.
-       up_to_date=t
-       for remote
-       do
-               common_one=$(git merge-base --all $head $remote)
-               if test "$common_one" != "$remote"
-               then
-                       up_to_date=f
-                       break
-               fi
-       done
-       if test "$up_to_date" = t
-       then
-               finish_up_to_date "Already up to date. Yeeah!"
-               exit 0
-       fi
-       ;;
-esac
-
-if test "$fast_forward_only" = t
-then
-       die "Not possible to fast-forward, aborting."
-fi
-
-# We are going to make a new commit.
-git var GIT_COMMITTER_IDENT >/dev/null || exit
-
-# At this point, we need a real merge.  No matter what strategy
-# we use, it would operate on the index, possibly affecting the
-# working tree, and when resolved cleanly, have the desired tree
-# in the index -- this means that the index must be in sync with
-# the $head commit.  The strategies are responsible to ensure this.
-
-case "$use_strategies" in
-?*' '?*)
-    # Stash away the local changes so that we can try more than one.
-    savestate
-    single_strategy=no
-    ;;
-*)
-    rm -f "$GIT_DIR/MERGE_STASH"
-    single_strategy=yes
-    ;;
-esac
-
-result_tree= best_cnt=-1 best_strategy= wt_strategy=
-merge_was_ok=
-for strategy in $use_strategies
-do
-    test "$wt_strategy" = '' || {
-       echo "Rewinding the tree to pristine..."
-       restorestate
-    }
-    case "$single_strategy" in
-    no)
-       echo "Trying merge strategy $strategy..."
-       ;;
-    esac
-
-    # Remember which strategy left the state in the working tree
-    wt_strategy=$strategy
-
-    eval 'git-merge-$strategy '"$xopt"' $common -- "$head_arg" "$@"'
-    exit=$?
-    if test "$no_commit" = t && test "$exit" = 0
-    then
-        merge_was_ok=t
-       exit=1 ;# pretend it left conflicts.
-    fi
-
-    test "$exit" = 0 || {
-
-       # The backend exits with 1 when conflicts are left to be resolved,
-       # with 2 when it does not handle the given merge at all.
-
-       if test "$exit" -eq 1
-       then
-           cnt=$({
-               git diff-files --name-only
-               git ls-files --unmerged
-           } | wc -l)
-           if test $best_cnt -le 0 || test $cnt -le $best_cnt
-           then
-               best_strategy=$strategy
-               best_cnt=$cnt
-           fi
-       fi
-       continue
-    }
-
-    # Automerge succeeded.
-    result_tree=$(git write-tree) && break
-done
-
-# If we have a resulting tree, that means the strategy module
-# auto resolved the merge cleanly.
-if test '' != "$result_tree"
-then
-    if test "$allow_fast_forward" = "t"
-    then
-       parents=$(git merge-base --independent "$head" "$@")
-    else
-       parents=$(git rev-parse "$head" "$@")
-    fi
-    parents=$(echo "$parents" | sed -e 's/^/-p /')
-    result_commit=$(printf '%s\n' "$merge_msg" | git commit-tree $result_tree $parents) || exit
-    finish "$result_commit" "Merge made by $wt_strategy."
-    dropsave
-    exit 0
-fi
-
-# Pick the result from the best strategy and have the user fix it up.
-case "$best_strategy" in
-'')
-       restorestate
-       case "$use_strategies" in
-       ?*' '?*)
-               echo >&2 "No merge strategy handled the merge."
-               ;;
-       *)
-               echo >&2 "Merge with strategy $use_strategies failed."
-               ;;
-       esac
-       exit 2
-       ;;
-"$wt_strategy")
-       # We already have its result in the working tree.
-       ;;
-*)
-       echo "Rewinding the tree to pristine..."
-       restorestate
-       echo "Using the $best_strategy to prepare resolving by hand."
-       git-merge-$best_strategy $common -- "$head_arg" "$@"
-       ;;
-esac
-
-if test "$squash" = t
-then
-       finish
-else
-       for remote
-       do
-               echo $remote
-       done >"$GIT_DIR/MERGE_HEAD"
-       printf '%s\n' "$merge_msg" >"$GIT_DIR/MERGE_MSG" ||
-               die "Could not write to $GIT_DIR/MERGE_MSG"
-       if test "$allow_fast_forward" != t
-       then
-               printf "%s" no-ff
-       else
-               :
-       fi >"$GIT_DIR/MERGE_MODE" ||
-               die "Could not write to $GIT_DIR/MERGE_MODE"
-fi
-
-if test "$merge_was_ok" = t
-then
-       echo >&2 \
-       "Automatic merge went well; stopped before committing as requested"
-       exit 0
-else
-       {
-           echo '
-Conflicts:
-'
-               git ls-files --unmerged |
-               sed -e 's/^[^   ]*      /       /' |
-               uniq
-       } >>"$GIT_DIR/MERGE_MSG"
-       git rerere $rr_arg
-       die "Automatic merge failed; fix conflicts and then commit the result."
-fi
diff --git a/contrib/examples/git-notes.sh b/contrib/examples/git-notes.sh
deleted file mode 100755 (executable)
index e642e47..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/bin/sh
-
-USAGE="(edit [-F <file> | -m <msg>] | show) [commit]"
-. git-sh-setup
-
-test -z "$1" && usage
-ACTION="$1"; shift
-
-test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="$(git config core.notesref)"
-test -z "$GIT_NOTES_REF" && GIT_NOTES_REF="refs/notes/commits"
-
-MESSAGE=
-while test $# != 0
-do
-       case "$1" in
-       -m)
-               test "$ACTION" = "edit" || usage
-               shift
-               if test "$#" = "0"; then
-                       die "error: option -m needs an argument"
-               else
-                       if [ -z "$MESSAGE" ]; then
-                               MESSAGE="$1"
-                       else
-                               MESSAGE="$MESSAGE
-
-$1"
-                       fi
-                       shift
-               fi
-               ;;
-       -F)
-               test "$ACTION" = "edit" || usage
-               shift
-               if test "$#" = "0"; then
-                       die "error: option -F needs an argument"
-               else
-                       if [ -z "$MESSAGE" ]; then
-                               MESSAGE="$(cat "$1")"
-                       else
-                               MESSAGE="$MESSAGE
-
-$(cat "$1")"
-                       fi
-                       shift
-               fi
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               break
-               ;;
-       esac
-done
-
-COMMIT=$(git rev-parse --verify --default HEAD "$@") ||
-die "Invalid commit: $@"
-
-case "$ACTION" in
-edit)
-       if [ "${GIT_NOTES_REF#refs/notes/}" = "$GIT_NOTES_REF" ]; then
-               die "Refusing to edit notes in $GIT_NOTES_REF (outside of refs/notes/)"
-       fi
-
-       MSG_FILE="$GIT_DIR/new-notes-$COMMIT"
-       GIT_INDEX_FILE="$MSG_FILE.idx"
-       export GIT_INDEX_FILE
-
-       trap '
-               test -f "$MSG_FILE" && rm "$MSG_FILE"
-               test -f "$GIT_INDEX_FILE" && rm "$GIT_INDEX_FILE"
-       ' 0
-
-       CURRENT_HEAD=$(git show-ref "$GIT_NOTES_REF" | cut -f 1 -d ' ')
-       if [ -z "$CURRENT_HEAD" ]; then
-               PARENT=
-       else
-               PARENT="-p $CURRENT_HEAD"
-               git read-tree "$GIT_NOTES_REF" || die "Could not read index"
-       fi
-
-       if [ -z "$MESSAGE" ]; then
-               GIT_NOTES_REF= git log -1 $COMMIT | sed "s/^/#/" > "$MSG_FILE"
-               if [ ! -z "$CURRENT_HEAD" ]; then
-                       git cat-file blob :$COMMIT >> "$MSG_FILE" 2> /dev/null
-               fi
-               core_editor="$(git config core.editor)"
-               ${GIT_EDITOR:-${core_editor:-${VISUAL:-${EDITOR:-vi}}}} "$MSG_FILE"
-       else
-               echo "$MESSAGE" > "$MSG_FILE"
-       fi
-
-       grep -v ^# < "$MSG_FILE" | git stripspace > "$MSG_FILE".processed
-       mv "$MSG_FILE".processed "$MSG_FILE"
-       if [ -s "$MSG_FILE" ]; then
-               BLOB=$(git hash-object -w "$MSG_FILE") ||
-                       die "Could not write into object database"
-               git update-index --add --cacheinfo 0644 $BLOB $COMMIT ||
-                       die "Could not write index"
-       else
-               test -z "$CURRENT_HEAD" &&
-                       die "Will not initialise with empty tree"
-               git update-index --force-remove $COMMIT ||
-                       die "Could not update index"
-       fi
-
-       TREE=$(git write-tree) || die "Could not write tree"
-       NEW_HEAD=$(echo Annotate $COMMIT | git commit-tree $TREE $PARENT) ||
-               die "Could not annotate"
-       git update-ref -m "Annotate $COMMIT" \
-               "$GIT_NOTES_REF" $NEW_HEAD $CURRENT_HEAD
-;;
-show)
-       git rev-parse -q --verify "$GIT_NOTES_REF":$COMMIT > /dev/null ||
-               die "No note for commit $COMMIT."
-       git show "$GIT_NOTES_REF":$COMMIT
-;;
-*)
-       usage
-esac
diff --git a/contrib/examples/git-pull.sh b/contrib/examples/git-pull.sh
deleted file mode 100755 (executable)
index 6b3a03f..0000000
+++ /dev/null
@@ -1,381 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Junio C Hamano
-#
-# Fetch one or more remote refs and merge it/them into the current HEAD.
-
-SUBDIRECTORY_OK=Yes
-OPTIONS_KEEPDASHDASH=
-OPTIONS_STUCKLONG=Yes
-OPTIONS_SPEC="\
-git pull [options] [<repository> [<refspec>...]]
-
-Fetch one or more remote refs and integrate it/them with the current HEAD.
---
-v,verbose                  be more verbose
-q,quiet                    be more quiet
-progress                   force progress reporting
-
-  Options related to merging
-r,rebase?false|true|preserve incorporate changes by rebasing rather than merging
-n!                         do not show a diffstat at the end of the merge
-stat                       show a diffstat at the end of the merge
-summary                    (synonym to --stat)
-log?n                      add (at most <n>) entries from shortlog to merge commit message
-squash                     create a single commit instead of doing a merge
-commit                     perform a commit if the merge succeeds (default)
-e,edit                       edit message before committing
-ff                         allow fast-forward
-ff-only!                   abort if fast-forward is not possible
-verify-signatures          verify that the named commit has a valid GPG signature
-s,strategy=strategy        merge strategy to use
-X,strategy-option=option   option for selected merge strategy
-S,gpg-sign?key-id          GPG sign commit
-
-  Options related to fetching
-all                        fetch from all remotes
-a,append                   append to .git/FETCH_HEAD instead of overwriting
-upload-pack=path           path to upload pack on remote end
-f,force                    force overwrite of local branch
-t,tags                     fetch all tags and associated objects
-p,prune                    prune remote-tracking branches no longer on remote
-recurse-submodules?on-demand control recursive fetching of submodules
-dry-run                    dry run
-k,keep                     keep downloaded pack
-depth=depth                deepen history of shallow clone
-unshallow                  convert to a complete repository
-update-shallow             accept refs that update .git/shallow
-refmap=refmap              specify fetch refmap
-"
-test $# -gt 0 && args="$*"
-. git-sh-setup
-. git-sh-i18n
-set_reflog_action "pull${args+ $args}"
-require_work_tree_exists
-cd_to_toplevel
-
-
-die_conflict () {
-    git diff-index --cached --name-status -r --ignore-submodules HEAD --
-    if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
-       die "$(gettext "Pull is not possible because you have unmerged files.
-Please, fix them up in the work tree, and then use 'git add/rm <file>'
-as appropriate to mark resolution and make a commit.")"
-    else
-       die "$(gettext "Pull is not possible because you have unmerged files.")"
-    fi
-}
-
-die_merge () {
-    if [ $(git config --bool --get advice.resolveConflict || echo true) = "true" ]; then
-       die "$(gettext "You have not concluded your merge (MERGE_HEAD exists).
-Please, commit your changes before merging.")"
-    else
-       die "$(gettext "You have not concluded your merge (MERGE_HEAD exists).")"
-    fi
-}
-
-test -z "$(git ls-files -u)" || die_conflict
-test -f "$GIT_DIR/MERGE_HEAD" && die_merge
-
-bool_or_string_config () {
-       git config --bool "$1" 2>/dev/null || git config "$1"
-}
-
-strategy_args= diffstat= no_commit= squash= no_ff= ff_only=
-log_arg= verbosity= progress= recurse_submodules= verify_signatures=
-merge_args= edit= rebase_args= all= append= upload_pack= force= tags= prune=
-keep= depth= unshallow= update_shallow= refmap=
-curr_branch=$(git symbolic-ref -q HEAD)
-curr_branch_short="${curr_branch#refs/heads/}"
-rebase=$(bool_or_string_config branch.$curr_branch_short.rebase)
-if test -z "$rebase"
-then
-       rebase=$(bool_or_string_config pull.rebase)
-fi
-
-# Setup default fast-forward options via `pull.ff`
-pull_ff=$(bool_or_string_config pull.ff)
-case "$pull_ff" in
-true)
-       no_ff=--ff
-       ;;
-false)
-       no_ff=--no-ff
-       ;;
-only)
-       ff_only=--ff-only
-       ;;
-esac
-
-
-dry_run=
-while :
-do
-       case "$1" in
-       -q|--quiet)
-               verbosity="$verbosity -q" ;;
-       -v|--verbose)
-               verbosity="$verbosity -v" ;;
-       --progress)
-               progress=--progress ;;
-       --no-progress)
-               progress=--no-progress ;;
-       -n|--no-stat|--no-summary)
-               diffstat=--no-stat ;;
-       --stat|--summary)
-               diffstat=--stat ;;
-       --log|--log=*|--no-log)
-               log_arg="$1" ;;
-       --no-commit)
-               no_commit=--no-commit ;;
-       --commit)
-               no_commit=--commit ;;
-       -e|--edit)
-               edit=--edit ;;
-       --no-edit)
-               edit=--no-edit ;;
-       --squash)
-               squash=--squash ;;
-       --no-squash)
-               squash=--no-squash ;;
-       --ff)
-               no_ff=--ff ;;
-       --no-ff)
-               no_ff=--no-ff ;;
-       --ff-only)
-               ff_only=--ff-only ;;
-       -s*|--strategy=*)
-               strategy_args="$strategy_args $1"
-               ;;
-       -X*|--strategy-option=*)
-               merge_args="$merge_args $(git rev-parse --sq-quote "$1")"
-               ;;
-       -r*|--rebase=*)
-               rebase="${1#*=}"
-               ;;
-       --rebase)
-               rebase=true
-               ;;
-       --no-rebase)
-               rebase=false
-               ;;
-       --recurse-submodules)
-               recurse_submodules=--recurse-submodules
-               ;;
-       --recurse-submodules=*)
-               recurse_submodules="$1"
-               ;;
-       --no-recurse-submodules)
-               recurse_submodules=--no-recurse-submodules
-               ;;
-       --verify-signatures)
-               verify_signatures=--verify-signatures
-               ;;
-       --no-verify-signatures)
-               verify_signatures=--no-verify-signatures
-               ;;
-       --gpg-sign|-S)
-               gpg_sign_args=-S
-               ;;
-       --gpg-sign=*)
-               gpg_sign_args=$(git rev-parse --sq-quote "-S${1#--gpg-sign=}")
-               ;;
-       -S*)
-               gpg_sign_args=$(git rev-parse --sq-quote "$1")
-               ;;
-       --dry-run)
-               dry_run=--dry-run
-               ;;
-       --all|--no-all)
-               all=$1 ;;
-       -a|--append|--no-append)
-               append=$1 ;;
-       --upload-pack=*|--no-upload-pack)
-               upload_pack=$1 ;;
-       -f|--force|--no-force)
-               force="$force $1" ;;
-       -t|--tags|--no-tags)
-               tags=$1 ;;
-       -p|--prune|--no-prune)
-               prune=$1 ;;
-       -k|--keep|--no-keep)
-               keep=$1 ;;
-       --depth=*|--no-depth)
-               depth=$1 ;;
-       --unshallow|--no-unshallow)
-               unshallow=$1 ;;
-       --update-shallow|--no-update-shallow)
-               update_shallow=$1 ;;
-       --refmap=*|--no-refmap)
-               refmap=$1 ;;
-       -h|--help-all)
-               usage
-               ;;
-       --)
-               shift
-               break
-               ;;
-       *)
-               usage
-               ;;
-       esac
-       shift
-done
-
-case "$rebase" in
-preserve)
-       rebase=true
-       rebase_args=--preserve-merges
-       ;;
-true|false|'')
-       ;;
-*)
-       echo "Invalid value for --rebase, should be true, false, or preserve"
-       usage
-       exit 1
-       ;;
-esac
-
-error_on_no_merge_candidates () {
-       exec >&2
-
-       if test true = "$rebase"
-       then
-               op_type=rebase
-               op_prep=against
-       else
-               op_type=merge
-               op_prep=with
-       fi
-
-       upstream=$(git config "branch.$curr_branch_short.merge")
-       remote=$(git config "branch.$curr_branch_short.remote")
-
-       if [ $# -gt 1 ]; then
-               if [ "$rebase" = true ]; then
-                       printf "There is no candidate for rebasing against "
-               else
-                       printf "There are no candidates for merging "
-               fi
-               echo "among the refs that you just fetched."
-               echo "Generally this means that you provided a wildcard refspec which had no"
-               echo "matches on the remote end."
-       elif [ $# -gt 0 ] && [ "$1" != "$remote" ]; then
-               echo "You asked to pull from the remote '$1', but did not specify"
-               echo "a branch. Because this is not the default configured remote"
-               echo "for your current branch, you must specify a branch on the command line."
-       elif [ -z "$curr_branch" -o -z "$upstream" ]; then
-               . git-parse-remote
-               error_on_missing_default_upstream "pull" $op_type $op_prep \
-                       "git pull <remote> <branch>"
-       else
-               echo "Your configuration specifies to $op_type $op_prep the ref '${upstream#refs/heads/}'"
-               echo "from the remote, but no such ref was fetched."
-       fi
-       exit 1
-}
-
-test true = "$rebase" && {
-       if ! git rev-parse -q --verify HEAD >/dev/null
-       then
-               # On an unborn branch
-               if test -f "$(git rev-parse --git-path index)"
-               then
-                       die "$(gettext "updating an unborn branch with changes added to the index")"
-               fi
-       else
-               require_clean_work_tree "pull with rebase" "Please commit or stash them."
-       fi
-       oldremoteref= &&
-       test -n "$curr_branch" &&
-       . git-parse-remote &&
-       remoteref="$(get_remote_merge_branch "$@" 2>/dev/null)" &&
-       oldremoteref=$(git merge-base --fork-point "$remoteref" $curr_branch 2>/dev/null)
-}
-orig_head=$(git rev-parse -q --verify HEAD)
-git fetch $verbosity $progress $dry_run $recurse_submodules $all $append \
-${upload_pack:+"$upload_pack"} $force $tags $prune $keep $depth $unshallow $update_shallow \
-$refmap --update-head-ok "$@" || exit 1
-test -z "$dry_run" || exit 0
-
-curr_head=$(git rev-parse -q --verify HEAD)
-if test -n "$orig_head" && test "$curr_head" != "$orig_head"
-then
-       # The fetch involved updating the current branch.
-
-       # The working tree and the index file is still based on the
-       # $orig_head commit, but we are merging into $curr_head.
-       # First update the working tree to match $curr_head.
-
-       eval_gettextln "Warning: fetch updated the current branch head.
-Warning: fast-forwarding your working tree from
-Warning: commit \$orig_head." >&2
-       git update-index -q --refresh
-       git read-tree -u -m "$orig_head" "$curr_head" ||
-               die "$(eval_gettext "Cannot fast-forward your working tree.
-After making sure that you saved anything precious from
-$ git diff \$orig_head
-output, run
-$ git reset --hard
-to recover.")"
-
-fi
-
-merge_head=$(sed -e '/ not-for-merge   /d' \
-       -e 's/  .*//' "$GIT_DIR"/FETCH_HEAD | \
-       tr '\012' ' ')
-
-case "$merge_head" in
-'')
-       error_on_no_merge_candidates "$@"
-       ;;
-?*' '?*)
-       if test -z "$orig_head"
-       then
-               die "$(gettext "Cannot merge multiple branches into empty head")"
-       fi
-       if test true = "$rebase"
-       then
-               die "$(gettext "Cannot rebase onto multiple branches")"
-       fi
-       ;;
-esac
-
-# Pulling into unborn branch: a shorthand for branching off
-# FETCH_HEAD, for lazy typers.
-if test -z "$orig_head"
-then
-       # Two-way merge: we claim the index is based on an empty tree,
-       # and try to fast-forward to HEAD.  This ensures we will not
-       # lose index/worktree changes that the user already made on
-       # the unborn branch.
-       empty_tree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
-       git read-tree -m -u $empty_tree $merge_head &&
-       git update-ref -m "initial pull" HEAD $merge_head "$curr_head"
-       exit
-fi
-
-if test true = "$rebase"
-then
-       o=$(git show-branch --merge-base $curr_branch $merge_head $oldremoteref)
-       if test "$oldremoteref" = "$o"
-       then
-               unset oldremoteref
-       fi
-fi
-
-case "$rebase" in
-true)
-       eval="git-rebase $diffstat $strategy_args $merge_args $rebase_args $verbosity"
-       eval="$eval $gpg_sign_args"
-       eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}"
-       ;;
-*)
-       eval="git-merge $diffstat $no_commit $verify_signatures $edit $squash $no_ff $ff_only"
-       eval="$eval $log_arg $strategy_args $merge_args $verbosity $progress"
-       eval="$eval $gpg_sign_args"
-       eval="$eval FETCH_HEAD"
-       ;;
-esac
-eval "exec $eval"
diff --git a/contrib/examples/git-remote.perl b/contrib/examples/git-remote.perl
deleted file mode 100755 (executable)
index d42df7b..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-#!/usr/bin/perl -w
-
-use strict;
-use Git;
-my $git = Git->repository();
-
-sub add_remote_config {
-       my ($hash, $name, $what, $value) = @_;
-       if ($what eq 'url') {
-               # Having more than one is Ok -- it is used for push.
-               if (! exists $hash->{'URL'}) {
-                       $hash->{$name}{'URL'} = $value;
-               }
-       }
-       elsif ($what eq 'fetch') {
-               $hash->{$name}{'FETCH'} ||= [];
-               push @{$hash->{$name}{'FETCH'}}, $value;
-       }
-       elsif ($what eq 'push') {
-               $hash->{$name}{'PUSH'} ||= [];
-               push @{$hash->{$name}{'PUSH'}}, $value;
-       }
-       if (!exists $hash->{$name}{'SOURCE'}) {
-               $hash->{$name}{'SOURCE'} = 'config';
-       }
-}
-
-sub add_remote_remotes {
-       my ($hash, $file, $name) = @_;
-
-       if (exists $hash->{$name}) {
-               $hash->{$name}{'WARNING'} = 'ignored due to config';
-               return;
-       }
-
-       my $fh;
-       if (!open($fh, '<', $file)) {
-               print STDERR "Warning: cannot open $file\n";
-               return;
-       }
-       my $it = { 'SOURCE' => 'remotes' };
-       $hash->{$name} = $it;
-       while (<$fh>) {
-               chomp;
-               if (/^URL:\s*(.*)$/) {
-                       # Having more than one is Ok -- it is used for push.
-                       if (! exists $it->{'URL'}) {
-                               $it->{'URL'} = $1;
-                       }
-               }
-               elsif (/^Push:\s*(.*)$/) {
-                       $it->{'PUSH'} ||= [];
-                       push @{$it->{'PUSH'}}, $1;
-               }
-               elsif (/^Pull:\s*(.*)$/) {
-                       $it->{'FETCH'} ||= [];
-                       push @{$it->{'FETCH'}}, $1;
-               }
-               elsif (/^\#/) {
-                       ; # ignore
-               }
-               else {
-                       print STDERR "Warning: funny line in $file: $_\n";
-               }
-       }
-       close($fh);
-}
-
-sub list_remote {
-       my ($git) = @_;
-       my %seen = ();
-       my @remotes = eval {
-               $git->command(qw(config --get-regexp), '^remote\.');
-       };
-       for (@remotes) {
-               if (/^remote\.(\S+?)\.([^.\s]+)\s+(.*)$/) {
-                       add_remote_config(\%seen, $1, $2, $3);
-               }
-       }
-
-       my $dir = $git->repo_path() . "/remotes";
-       if (opendir(my $dh, $dir)) {
-               local $_;
-               while ($_ = readdir($dh)) {
-                       chomp;
-                       next if (! -f "$dir/$_" || ! -r _);
-                       add_remote_remotes(\%seen, "$dir/$_", $_);
-               }
-       }
-
-       return \%seen;
-}
-
-sub add_branch_config {
-       my ($hash, $name, $what, $value) = @_;
-       if ($what eq 'remote') {
-               if (exists $hash->{$name}{'REMOTE'}) {
-                       print STDERR "Warning: more than one branch.$name.remote\n";
-               }
-               $hash->{$name}{'REMOTE'} = $value;
-       }
-       elsif ($what eq 'merge') {
-               $hash->{$name}{'MERGE'} ||= [];
-               push @{$hash->{$name}{'MERGE'}}, $value;
-       }
-}
-
-sub list_branch {
-       my ($git) = @_;
-       my %seen = ();
-       my @branches = eval {
-               $git->command(qw(config --get-regexp), '^branch\.');
-       };
-       for (@branches) {
-               if (/^branch\.([^.]*)\.(\S*)\s+(.*)$/) {
-                       add_branch_config(\%seen, $1, $2, $3);
-               }
-       }
-
-       return \%seen;
-}
-
-my $remote = list_remote($git);
-my $branch = list_branch($git);
-
-sub update_ls_remote {
-       my ($harder, $info) = @_;
-
-       return if (($harder == 0) ||
-                  (($harder == 1) && exists $info->{'LS_REMOTE'}));
-
-       my @ref = map { s|refs/heads/||; $_; } keys %{$git->remote_refs($info->{'URL'}, [ 'heads' ])};
-       $info->{'LS_REMOTE'} = \@ref;
-}
-
-sub list_wildcard_mapping {
-       my ($forced, $ours, $ls) = @_;
-       my %refs;
-       for (@$ls) {
-               $refs{$_} = 01; # bit #0 to say "they have"
-       }
-       for ($git->command('for-each-ref', "refs/remotes/$ours")) {
-               chomp;
-               next unless (s|^[0-9a-f]{40}\s[a-z]+\srefs/remotes/$ours/||);
-               next if ($_ eq 'HEAD');
-               $refs{$_} ||= 0;
-               $refs{$_} |= 02; # bit #1 to say "we have"
-       }
-       my (@new, @stale, @tracked);
-       for (sort keys %refs) {
-               my $have = $refs{$_};
-               if ($have == 1) {
-                       push @new, $_;
-               }
-               elsif ($have == 2) {
-                       push @stale, $_;
-               }
-               elsif ($have == 3) {
-                       push @tracked, $_;
-               }
-       }
-       return \@new, \@stale, \@tracked;
-}
-
-sub list_mapping {
-       my ($name, $info) = @_;
-       my $fetch = $info->{'FETCH'};
-       my $ls = $info->{'LS_REMOTE'};
-       my (@new, @stale, @tracked);
-
-       for (@$fetch) {
-               next unless (/(\+)?([^:]+):(.*)/);
-               my ($forced, $theirs, $ours) = ($1, $2, $3);
-               if ($theirs eq 'refs/heads/*' &&
-                   $ours =~ /^refs\/remotes\/(.*)\/\*$/) {
-                       # wildcard mapping
-                       my ($w_new, $w_stale, $w_tracked)
-                               = list_wildcard_mapping($forced, $1, $ls);
-                       push @new, @$w_new;
-                       push @stale, @$w_stale;
-                       push @tracked, @$w_tracked;
-               }
-               elsif ($theirs =~ /\*/ || $ours =~ /\*/) {
-                       print STDERR "Warning: unrecognized mapping in remotes.$name.fetch: $_\n";
-               }
-               elsif ($theirs =~ s|^refs/heads/||) {
-                       if (!grep { $_ eq $theirs } @$ls) {
-                               push @stale, $theirs;
-                       }
-                       elsif ($ours ne '') {
-                               push @tracked, $theirs;
-                       }
-               }
-       }
-       return \@new, \@stale, \@tracked;
-}
-
-sub show_mapping {
-       my ($name, $info) = @_;
-       my ($new, $stale, $tracked) = list_mapping($name, $info);
-       if (@$new) {
-               print "  New remote branches (next fetch will store in remotes/$name)\n";
-               print "    @$new\n";
-       }
-       if (@$stale) {
-               print "  Stale tracking branches in remotes/$name (use 'git remote prune')\n";
-               print "    @$stale\n";
-       }
-       if (@$tracked) {
-               print "  Tracked remote branches\n";
-               print "    @$tracked\n";
-       }
-}
-
-sub prune_remote {
-       my ($name, $ls_remote) = @_;
-       if (!exists $remote->{$name}) {
-               print STDERR "No such remote $name\n";
-               return 1;
-       }
-       my $info = $remote->{$name};
-       update_ls_remote($ls_remote, $info);
-
-       my ($new, $stale, $tracked) = list_mapping($name, $info);
-       my $prefix = "refs/remotes/$name";
-       foreach my $to_prune (@$stale) {
-               my @v = $git->command(qw(rev-parse --verify), "$prefix/$to_prune");
-               $git->command(qw(update-ref -d), "$prefix/$to_prune", $v[0]);
-       }
-       return 0;
-}
-
-sub show_remote {
-       my ($name, $ls_remote) = @_;
-       if (!exists $remote->{$name}) {
-               print STDERR "No such remote $name\n";
-               return 1;
-       }
-       my $info = $remote->{$name};
-       update_ls_remote($ls_remote, $info);
-
-       print "* remote $name\n";
-       print "  URL: $info->{'URL'}\n";
-       for my $branchname (sort keys %$branch) {
-               next unless (defined $branch->{$branchname}{'REMOTE'} &&
-                            $branch->{$branchname}{'REMOTE'} eq $name);
-               my @merged = map {
-                       s|^refs/heads/||;
-                       $_;
-               } split(' ',"@{$branch->{$branchname}{'MERGE'}}");
-               next unless (@merged);
-               print "  Remote branch(es) merged with 'git pull' while on branch $branchname\n";
-               print "    @merged\n";
-       }
-       if ($info->{'LS_REMOTE'}) {
-               show_mapping($name, $info);
-       }
-       if ($info->{'PUSH'}) {
-               my @pushed = map {
-                       s|^refs/heads/||;
-                       s|^\+refs/heads/|+|;
-                       s|:refs/heads/|:|;
-                       $_;
-               } @{$info->{'PUSH'}};
-               print "  Local branch(es) pushed with 'git push'\n";
-               print "    @pushed\n";
-       }
-       return 0;
-}
-
-sub add_remote {
-       my ($name, $url, $opts) = @_;
-       if (exists $remote->{$name}) {
-               print STDERR "remote $name already exists.\n";
-               exit(1);
-       }
-       $git->command('config', "remote.$name.url", $url);
-       my $track = $opts->{'track'} || ["*"];
-
-       for (@$track) {
-               $git->command('config', '--add', "remote.$name.fetch",
-                               $opts->{'mirror'} ?
-                               "+refs/$_:refs/$_" :
-                               "+refs/heads/$_:refs/remotes/$name/$_");
-       }
-       if ($opts->{'fetch'}) {
-               $git->command('fetch', $name);
-       }
-       if (exists $opts->{'master'}) {
-               $git->command('symbolic-ref', "refs/remotes/$name/HEAD",
-                             "refs/remotes/$name/$opts->{'master'}");
-       }
-}
-
-sub update_remote {
-       my ($name) = @_;
-       my @remotes;
-
-        my $conf = $git->config("remotes." . $name);
-       if (defined($conf)) {
-               @remotes = split(' ', $conf);
-       } elsif ($name eq 'default') {
-               @remotes = ();
-               for (sort keys %$remote) {
-                       my $do_fetch = $git->config_bool("remote." . $_ .
-                                                   ".skipDefaultUpdate");
-                       unless ($do_fetch) {
-                               push @remotes, $_;
-                       }
-               }
-       } else {
-               print STDERR "Remote group $name does not exist.\n";
-               exit(1);
-       }
-       for (@remotes) {
-               print "Updating $_\n";
-               $git->command('fetch', "$_");
-       }
-}
-
-sub rm_remote {
-       my ($name) = @_;
-       if (!exists $remote->{$name}) {
-               print STDERR "No such remote $name\n";
-               return 1;
-       }
-
-       $git->command('config', '--remove-section', "remote.$name");
-
-       eval {
-           my @trackers = $git->command('config', '--get-regexp',
-                       'branch.*.remote', $name);
-               for (@trackers) {
-                       /^branch\.(.*)?\.remote/;
-                       $git->config('--unset', "branch.$1.remote");
-                       $git->config('--unset', "branch.$1.merge");
-               }
-       };
-
-       my @refs = $git->command('for-each-ref',
-               '--format=%(refname) %(objectname)', "refs/remotes/$name");
-       for (@refs) {
-               my ($ref, $object) = split;
-               $git->command(qw(update-ref -d), $ref, $object);
-       }
-       return 0;
-}
-
-sub add_usage {
-       print STDERR "usage: git remote add [-f] [-t track]* [-m master] <name> <url>\n";
-       exit(1);
-}
-
-my $VERBOSE = 0;
-@ARGV = grep {
-       if ($_ eq '-v' or $_ eq '--verbose') {
-               $VERBOSE=1;
-               0
-       } else {
-               1
-       }
-} @ARGV;
-
-if (!@ARGV) {
-       for (sort keys %$remote) {
-               print "$_";
-               print "\t$remote->{$_}->{URL}" if $VERBOSE;
-               print "\n";
-       }
-}
-elsif ($ARGV[0] eq 'show') {
-       my $ls_remote = 1;
-       my $i;
-       for ($i = 1; $i < @ARGV; $i++) {
-               if ($ARGV[$i] eq '-n') {
-                       $ls_remote = 0;
-               }
-               else {
-                       last;
-               }
-       }
-       if ($i >= @ARGV) {
-               print STDERR "usage: git remote show <remote>\n";
-               exit(1);
-       }
-       my $status = 0;
-       for (; $i < @ARGV; $i++) {
-               $status |= show_remote($ARGV[$i], $ls_remote);
-       }
-       exit($status);
-}
-elsif ($ARGV[0] eq 'update') {
-       if (@ARGV <= 1) {
-               update_remote("default");
-               exit(1);
-       }
-       for (my $i = 1; $i < @ARGV; $i++) {
-               update_remote($ARGV[$i]);
-       }
-}
-elsif ($ARGV[0] eq 'prune') {
-       my $ls_remote = 1;
-       my $i;
-       for ($i = 1; $i < @ARGV; $i++) {
-               if ($ARGV[$i] eq '-n') {
-                       $ls_remote = 0;
-               }
-               else {
-                       last;
-               }
-       }
-       if ($i >= @ARGV) {
-               print STDERR "usage: git remote prune <remote>\n";
-               exit(1);
-       }
-       my $status = 0;
-       for (; $i < @ARGV; $i++) {
-               $status |= prune_remote($ARGV[$i], $ls_remote);
-       }
-        exit($status);
-}
-elsif ($ARGV[0] eq 'add') {
-       my %opts = ();
-       while (1 < @ARGV && $ARGV[1] =~ /^-/) {
-               my $opt = $ARGV[1];
-               shift @ARGV;
-               if ($opt eq '-f' || $opt eq '--fetch') {
-                       $opts{'fetch'} = 1;
-                       next;
-               }
-               if ($opt eq '-t' || $opt eq '--track') {
-                       if (@ARGV < 1) {
-                               add_usage();
-                       }
-                       $opts{'track'} ||= [];
-                       push @{$opts{'track'}}, $ARGV[1];
-                       shift @ARGV;
-                       next;
-               }
-               if ($opt eq '-m' || $opt eq '--master') {
-                       if ((@ARGV < 1) || exists $opts{'master'}) {
-                               add_usage();
-                       }
-                       $opts{'master'} = $ARGV[1];
-                       shift @ARGV;
-                       next;
-               }
-               if ($opt eq '--mirror') {
-                       $opts{'mirror'} = 1;
-                       next;
-               }
-               add_usage();
-       }
-       if (@ARGV != 3) {
-               add_usage();
-       }
-       add_remote($ARGV[1], $ARGV[2], \%opts);
-}
-elsif ($ARGV[0] eq 'rm') {
-       if (@ARGV <= 1) {
-               print STDERR "usage: git remote rm <remote>\n";
-               exit(1);
-       }
-       exit(rm_remote($ARGV[1]));
-}
-else {
-       print STDERR "usage: git remote\n";
-       print STDERR "       git remote add <name> <url>\n";
-       print STDERR "       git remote rm <name>\n";
-       print STDERR "       git remote show <name>\n";
-       print STDERR "       git remote prune <name>\n";
-       print STDERR "       git remote update [group]\n";
-       exit(1);
-}
diff --git a/contrib/examples/git-repack.sh b/contrib/examples/git-repack.sh
deleted file mode 100755 (executable)
index 672af93..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-#
-
-OPTIONS_KEEPDASHDASH=
-OPTIONS_SPEC="\
-git repack [options]
---
-a               pack everything in a single pack
-A               same as -a, and turn unreachable objects loose
-d               remove redundant packs, and run git-prune-packed
-f               pass --no-reuse-delta to git-pack-objects
-F               pass --no-reuse-object to git-pack-objects
-n               do not run git-update-server-info
-q,quiet         be quiet
-l               pass --local to git-pack-objects
-unpack-unreachable=  with -A, do not loosen objects older than this
- Packing constraints
-window=         size of the window used for delta compression
-window-memory=  same as the above, but limit memory size instead of entries count
-depth=          limits the maximum delta depth
-max-pack-size=  maximum size of each packfile
-"
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-no_update_info= all_into_one= remove_redundant= unpack_unreachable=
-local= no_reuse= extra=
-while test $# != 0
-do
-       case "$1" in
-       -n)     no_update_info=t ;;
-       -a)     all_into_one=t ;;
-       -A)     all_into_one=t
-               unpack_unreachable=--unpack-unreachable ;;
-       --unpack-unreachable)
-               unpack_unreachable="--unpack-unreachable=$2"; shift ;;
-       -d)     remove_redundant=t ;;
-       -q)     GIT_QUIET=t ;;
-       -f)     no_reuse=--no-reuse-delta ;;
-       -F)     no_reuse=--no-reuse-object ;;
-       -l)     local=--local ;;
-       --max-pack-size|--window|--window-memory|--depth)
-               extra="$extra $1=$2"; shift ;;
-       --) shift; break;;
-       *)      usage ;;
-       esac
-       shift
-done
-
-case "$(git config --bool repack.usedeltabaseoffset || echo true)" in
-true)
-       extra="$extra --delta-base-offset" ;;
-esac
-
-PACKDIR="$GIT_OBJECT_DIRECTORY/pack"
-PACKTMP="$PACKDIR/.tmp-$$-pack"
-rm -f "$PACKTMP"-*
-trap 'rm -f "$PACKTMP"-*' 0 1 2 3 15
-
-# There will be more repacking strategies to come...
-case ",$all_into_one," in
-,,)
-       args='--unpacked --incremental'
-       ;;
-,t,)
-       args= existing=
-       if [ -d "$PACKDIR" ]; then
-               for e in $(cd "$PACKDIR" && find . -type f -name '*.pack' \
-                       | sed -e 's/^\.\///' -e 's/\.pack$//')
-               do
-                       if [ -e "$PACKDIR/$e.keep" ]; then
-                               : keep
-                       else
-                               existing="$existing $e"
-                       fi
-               done
-               if test -n "$existing" && test -n "$unpack_unreachable" && \
-                       test -n "$remove_redundant"
-               then
-                       # This may have arbitrary user arguments, so we
-                       # have to protect it against whitespace splitting
-                       # when it gets run as "pack-objects $args" later.
-                       # Fortunately, we know it's an approxidate, so we
-                       # can just use dots instead.
-                       args="$args $(echo "$unpack_unreachable" | tr ' ' .)"
-               fi
-       fi
-       ;;
-esac
-
-mkdir -p "$PACKDIR" || exit
-
-args="$args $local ${GIT_QUIET:+-q} $no_reuse$extra"
-names=$(git pack-objects --keep-true-parents --honor-pack-keep --non-empty --all --reflog $args </dev/null "$PACKTMP") ||
-       exit 1
-if [ -z "$names" ]; then
-       say Nothing new to pack.
-fi
-
-# Ok we have prepared all new packfiles.
-
-# First see if there are packs of the same name and if so
-# if we can move them out of the way (this can happen if we
-# repacked immediately after packing fully.
-rollback=
-failed=
-for name in $names
-do
-       for sfx in pack idx
-       do
-               file=pack-$name.$sfx
-               test -f "$PACKDIR/$file" || continue
-               rm -f "$PACKDIR/old-$file" &&
-               mv "$PACKDIR/$file" "$PACKDIR/old-$file" || {
-                       failed=t
-                       break
-               }
-               rollback="$rollback $file"
-       done
-       test -z "$failed" || break
-done
-
-# If renaming failed for any of them, roll the ones we have
-# already renamed back to their original names.
-if test -n "$failed"
-then
-       rollback_failure=
-       for file in $rollback
-       do
-               mv "$PACKDIR/old-$file" "$PACKDIR/$file" ||
-               rollback_failure="$rollback_failure $file"
-       done
-       if test -n "$rollback_failure"
-       then
-               echo >&2 "WARNING: Some packs in use have been renamed by"
-               echo >&2 "WARNING: prefixing old- to their name, in order to"
-               echo >&2 "WARNING: replace them with the new version of the"
-               echo >&2 "WARNING: file.  But the operation failed, and"
-               echo >&2 "WARNING: attempt to rename them back to their"
-               echo >&2 "WARNING: original names also failed."
-               echo >&2 "WARNING: Please rename them in $PACKDIR manually:"
-               for file in $rollback_failure
-               do
-                       echo >&2 "WARNING:   old-$file -> $file"
-               done
-       fi
-       exit 1
-fi
-
-# Now the ones with the same name are out of the way...
-fullbases=
-for name in $names
-do
-       fullbases="$fullbases pack-$name"
-       chmod a-w "$PACKTMP-$name.pack"
-       chmod a-w "$PACKTMP-$name.idx"
-       mv -f "$PACKTMP-$name.pack" "$PACKDIR/pack-$name.pack" &&
-       mv -f "$PACKTMP-$name.idx"  "$PACKDIR/pack-$name.idx" ||
-       exit
-done
-
-# Remove the "old-" files
-for name in $names
-do
-       rm -f "$PACKDIR/old-pack-$name.idx"
-       rm -f "$PACKDIR/old-pack-$name.pack"
-done
-
-# End of pack replacement.
-
-if test "$remove_redundant" = t
-then
-       # We know $existing are all redundant.
-       if [ -n "$existing" ]
-       then
-               ( cd "$PACKDIR" &&
-                 for e in $existing
-                 do
-                       case " $fullbases " in
-                       *" $e "*) ;;
-                       *)      rm -f "$e.pack" "$e.idx" "$e.keep" ;;
-                       esac
-                 done
-               )
-       fi
-       git prune-packed ${GIT_QUIET:+-q}
-fi
-
-case "$no_update_info" in
-t) : ;;
-*) git update-server-info ;;
-esac
diff --git a/contrib/examples/git-rerere.perl b/contrib/examples/git-rerere.perl
deleted file mode 100755 (executable)
index 4f69209..0000000
+++ /dev/null
@@ -1,284 +0,0 @@
-#!/usr/bin/perl
-#
-# REuse REcorded REsolve.  This tool records a conflicted automerge
-# result and its hand resolution, and helps to resolve future
-# automerge that results in the same conflict.
-#
-# To enable this feature, create a directory 'rr-cache' under your
-# .git/ directory.
-
-use Digest;
-use File::Path;
-use File::Copy;
-
-my $git_dir = $::ENV{GIT_DIR} || ".git";
-my $rr_dir = "$git_dir/rr-cache";
-my $merge_rr = "$git_dir/rr-cache/MERGE_RR";
-
-my %merge_rr = ();
-
-sub read_rr {
-       if (!-f $merge_rr) {
-               %merge_rr = ();
-               return;
-       }
-       my $in;
-       local $/ = "\0";
-       open $in, "<$merge_rr" or die "$!: $merge_rr";
-       while (<$in>) {
-               chomp;
-               my ($name, $path) = /^([0-9a-f]{40})\t(.*)$/s;
-               $merge_rr{$path} = $name;
-       }
-       close $in;
-}
-
-sub write_rr {
-       my $out;
-       open $out, ">$merge_rr" or die "$!: $merge_rr";
-       for my $path (sort keys %merge_rr) {
-               my $name = $merge_rr{$path};
-               print $out "$name\t$path\0";
-       }
-       close $out;
-}
-
-sub compute_conflict_name {
-       my ($path) = @_;
-       my @side = ();
-       my $in;
-       open $in, "<$path"  or die "$!: $path";
-
-       my $sha1 = Digest->new("SHA-1");
-       my $hunk = 0;
-       while (<$in>) {
-               if (/^<<<<<<< .*/) {
-                       $hunk++;
-                       @side = ([], undef);
-               }
-               elsif (/^=======$/) {
-                       $side[1] = [];
-               }
-               elsif (/^>>>>>>> .*/) {
-                       my ($one, $two);
-                       $one = join('', @{$side[0]});
-                       $two = join('', @{$side[1]});
-                       if ($two le $one) {
-                               ($one, $two) = ($two, $one);
-                       }
-                       $sha1->add($one);
-                       $sha1->add("\0");
-                       $sha1->add($two);
-                       $sha1->add("\0");
-                       @side = ();
-               }
-               elsif (@side == 0) {
-                       next;
-               }
-               elsif (defined $side[1]) {
-                       push @{$side[1]}, $_;
-               }
-               else {
-                       push @{$side[0]}, $_;
-               }
-       }
-       close $in;
-       return ($sha1->hexdigest, $hunk);
-}
-
-sub record_preimage {
-       my ($path, $name) = @_;
-       my @side = ();
-       my ($in, $out);
-       open $in, "<$path"  or die "$!: $path";
-       open $out, ">$name" or die "$!: $name";
-
-       while (<$in>) {
-               if (/^<<<<<<< .*/) {
-                       @side = ([], undef);
-               }
-               elsif (/^=======$/) {
-                       $side[1] = [];
-               }
-               elsif (/^>>>>>>> .*/) {
-                       my ($one, $two);
-                       $one = join('', @{$side[0]});
-                       $two = join('', @{$side[1]});
-                       if ($two le $one) {
-                               ($one, $two) = ($two, $one);
-                       }
-                       print $out "<<<<<<<\n";
-                       print $out $one;
-                       print $out "=======\n";
-                       print $out $two;
-                       print $out ">>>>>>>\n";
-                       @side = ();
-               }
-               elsif (@side == 0) {
-                       print $out $_;
-               }
-               elsif (defined $side[1]) {
-                       push @{$side[1]}, $_;
-               }
-               else {
-                       push @{$side[0]}, $_;
-               }
-       }
-       close $out;
-       close $in;
-}
-
-sub find_conflict {
-       my $in;
-       local $/ = "\0";
-       my $pid = open($in, '-|');
-       die "$!" unless defined $pid;
-       if (!$pid) {
-               exec(qw(git ls-files -z -u)) or die "$!: ls-files";
-       }
-       my %path = ();
-       my @path = ();
-       while (<$in>) {
-               chomp;
-               my ($mode, $sha1, $stage, $path) =
-                   /^([0-7]+) ([0-9a-f]{40}) ([123])\t(.*)$/s;
-               $path{$path} |= (1 << $stage);
-       }
-       close $in;
-       while (my ($path, $status) = each %path) {
-               if ($status == 14) { push @path, $path; }
-       }
-       return @path;
-}
-
-sub merge {
-       my ($name, $path) = @_;
-       record_preimage($path, "$rr_dir/$name/thisimage");
-       unless (system('git', 'merge-file', map { "$rr_dir/$name/${_}image" }
-                      qw(this pre post))) {
-               my $in;
-               open $in, "<$rr_dir/$name/thisimage" or
-                   die "$!: $name/thisimage";
-               my $out;
-               open $out, ">$path" or die "$!: $path";
-               while (<$in>) { print $out $_; }
-               close $in;
-               close $out;
-               return 1;
-       }
-       return 0;
-}
-
-sub garbage_collect_rerere {
-       # We should allow specifying these from the command line and
-       # that is why the caller gives @ARGV to us, but I am lazy.
-
-       my $cutoff_noresolve = 15; # two weeks
-       my $cutoff_resolve = 60; # two months
-       my @to_remove;
-       while (<$rr_dir/*/preimage>) {
-               my ($dir) = /^(.*)\/preimage$/;
-               my $cutoff = ((-f "$dir/postimage")
-                             ? $cutoff_resolve
-                             : $cutoff_noresolve);
-               my $age = -M "$_";
-               if ($cutoff <= $age) {
-                       push @to_remove, $dir;
-               }
-       }
-       if (@to_remove) {
-               rmtree(\@to_remove);
-       }
-}
-
--d "$rr_dir" || exit(0);
-
-read_rr();
-
-if (@ARGV) {
-       my $arg = shift @ARGV;
-       if ($arg eq 'clear') {
-               for my $path (keys %merge_rr) {
-                       my $name = $merge_rr{$path};
-                       if (-d "$rr_dir/$name" &&
-                           ! -f "$rr_dir/$name/postimage") {
-                               rmtree(["$rr_dir/$name"]);
-                       }
-               }
-               unlink $merge_rr;
-       }
-       elsif ($arg eq 'status') {
-               for my $path (keys %merge_rr) {
-                       print $path, "\n";
-               }
-       }
-       elsif ($arg eq 'diff') {
-               for my $path (keys %merge_rr) {
-                       my $name = $merge_rr{$path};
-                       system('diff', ((@ARGV == 0) ? ('-u') : @ARGV),
-                               '-L', "a/$path", '-L', "b/$path",
-                               "$rr_dir/$name/preimage", $path);
-               }
-       }
-       elsif ($arg eq 'gc') {
-               garbage_collect_rerere(@ARGV);
-       }
-       else {
-               die "$0 unknown command: $arg\n";
-       }
-       exit 0;
-}
-
-my %conflict = map { $_ => 1 } find_conflict();
-
-# MERGE_RR records paths with conflicts immediately after merge
-# failed.  Some of the conflicted paths might have been hand resolved
-# in the working tree since then, but the initial run would catch all
-# and register their preimages.
-
-for my $path (keys %conflict) {
-       # This path has conflict.  If it is not recorded yet,
-       # record the pre-image.
-       if (!exists $merge_rr{$path}) {
-               my ($name, $hunk) = compute_conflict_name($path);
-               next unless ($hunk);
-               $merge_rr{$path} = $name;
-               if (! -d "$rr_dir/$name") {
-                       mkpath("$rr_dir/$name", 0, 0777);
-                       print STDERR "Recorded preimage for '$path'\n";
-                       record_preimage($path, "$rr_dir/$name/preimage");
-               }
-       }
-}
-
-# Now some of the paths that had conflicts earlier might have been
-# hand resolved.  Others may be similar to a conflict already that
-# was resolved before.
-
-for my $path (keys %merge_rr) {
-       my $name = $merge_rr{$path};
-
-       # We could resolve this automatically if we have images.
-       if (-f "$rr_dir/$name/preimage" &&
-           -f "$rr_dir/$name/postimage") {
-               if (merge($name, $path)) {
-                       print STDERR "Resolved '$path' using previous resolution.\n";
-                       # Then we do not have to worry about this path
-                       # anymore.
-                       delete $merge_rr{$path};
-                       next;
-               }
-       }
-
-       # Let's see if we have resolved it.
-       (undef, my $hunk) = compute_conflict_name($path);
-       next if ($hunk);
-
-       print STDERR "Recorded resolution for '$path'.\n";
-       copy($path, "$rr_dir/$name/postimage");
-       # And we do not have to worry about this path anymore.
-       delete $merge_rr{$path};
-}
-
-# Write out the rest.
-write_rr();
diff --git a/contrib/examples/git-reset.sh b/contrib/examples/git-reset.sh
deleted file mode 100755 (executable)
index cb1bbf3..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005, 2006 Linus Torvalds and Junio C Hamano
-#
-USAGE='[--mixed | --soft | --hard]  [<commit-ish>] [ [--] <paths>...]'
-SUBDIRECTORY_OK=Yes
-. git-sh-setup
-set_reflog_action "reset $*"
-require_work_tree
-
-update= reset_type=--mixed
-unset rev
-
-while test $# != 0
-do
-       case "$1" in
-       --mixed | --soft | --hard)
-               reset_type="$1"
-               ;;
-       --)
-               break
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               rev=$(git rev-parse --verify "$1") || exit
-               shift
-               break
-               ;;
-       esac
-       shift
-done
-
-: ${rev=HEAD}
-rev=$(git rev-parse --verify $rev^0) || exit
-
-# Skip -- in "git reset HEAD -- foo" and "git reset -- foo".
-case "$1" in --) shift ;; esac
-
-# git reset --mixed tree [--] paths... can be used to
-# load chosen paths from the tree into the index without
-# affecting the working tree or HEAD.
-if test $# != 0
-then
-       test "$reset_type" = "--mixed" ||
-               die "Cannot do partial $reset_type reset."
-
-       git diff-index --cached $rev -- "$@" |
-       sed -e 's/^:\([0-7][0-7]*\) [0-7][0-7]* \([0-9a-f][0-9a-f]*\) [0-9a-f][0-9a-f]* [A-Z]   \(.*\)$/\1 \2   \3/' |
-       git update-index --add --remove --index-info || exit
-       git update-index --refresh
-       exit
-fi
-
-cd_to_toplevel
-
-if test "$reset_type" = "--hard"
-then
-       update=-u
-fi
-
-# Soft reset does not touch the index file or the working tree
-# at all, but requires them in a good order.  Other resets reset
-# the index file to the tree object we are switching to.
-if test "$reset_type" = "--soft"
-then
-       if test -f "$GIT_DIR/MERGE_HEAD" ||
-          test "" != "$(git ls-files --unmerged)"
-       then
-               die "Cannot do a soft reset in the middle of a merge."
-       fi
-else
-       git read-tree -v --reset $update "$rev" || exit
-fi
-
-# Any resets update HEAD to the head being switched to.
-if orig=$(git rev-parse --verify HEAD 2>/dev/null)
-then
-       echo "$orig" >"$GIT_DIR/ORIG_HEAD"
-else
-       rm -f "$GIT_DIR/ORIG_HEAD"
-fi
-git update-ref -m "$GIT_REFLOG_ACTION" HEAD "$rev"
-update_ref_status=$?
-
-case "$reset_type" in
---hard )
-       test $update_ref_status = 0 && {
-               printf "HEAD is now at "
-               GIT_PAGER= git log --max-count=1 --pretty=oneline \
-                       --abbrev-commit HEAD
-       }
-       ;;
---soft )
-       ;; # Nothing else to do
---mixed )
-       # Report what has not been updated.
-       git update-index --refresh
-       ;;
-esac
-
-rm -f "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/rr-cache/MERGE_RR" \
-       "$GIT_DIR/SQUASH_MSG" "$GIT_DIR/MERGE_MSG"
-
-exit $update_ref_status
diff --git a/contrib/examples/git-resolve.sh b/contrib/examples/git-resolve.sh
deleted file mode 100755 (executable)
index 3099dc8..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-#
-# Resolve two trees.
-#
-
-echo 'WARNING: This command is DEPRECATED and will be removed very soon.' >&2
-echo 'WARNING: Please use git-merge or git-pull instead.' >&2
-sleep 2
-
-USAGE='<head> <remote> <merge-message>'
-. git-sh-setup
-
-dropheads() {
-       rm -f -- "$GIT_DIR/MERGE_HEAD" \
-               "$GIT_DIR/LAST_MERGE" || exit 1
-}
-
-head=$(git rev-parse --verify "$1"^0) &&
-merge=$(git rev-parse --verify "$2"^0) &&
-merge_name="$2" &&
-merge_msg="$3" || usage
-
-#
-# The remote name is just used for the message,
-# but we do want it.
-#
-if [ -z "$head" -o -z "$merge" -o -z "$merge_msg" ]; then
-       usage
-fi
-
-dropheads
-echo $head > "$GIT_DIR"/ORIG_HEAD
-echo $merge > "$GIT_DIR"/LAST_MERGE
-
-common=$(git merge-base $head $merge)
-if [ -z "$common" ]; then
-       die "Unable to find common commit between" $merge $head
-fi
-
-case "$common" in
-"$merge")
-       echo "Already up to date. Yeeah!"
-       dropheads
-       exit 0
-       ;;
-"$head")
-       echo "Updating $(git rev-parse --short $head)..$(git rev-parse --short $merge)"
-       git read-tree -u -m $head $merge || exit 1
-       git update-ref -m "resolve $merge_name: Fast-forward" \
-               HEAD "$merge" "$head"
-       git diff-tree -p $head $merge | git apply --stat
-       dropheads
-       exit 0
-       ;;
-esac
-
-# We are going to make a new commit.
-git var GIT_COMMITTER_IDENT >/dev/null || exit
-
-# Find an optimum merge base if there are more than one candidates.
-LF='
-'
-common=$(git merge-base -a $head $merge)
-case "$common" in
-?*"$LF"?*)
-       echo "Trying to find the optimum merge base."
-       G=.tmp-index$$
-       best=
-       best_cnt=-1
-       for c in $common
-       do
-               rm -f $G
-               GIT_INDEX_FILE=$G git read-tree -m $c $head $merge \
-                       2>/dev/null || continue
-               # Count the paths that are unmerged.
-               cnt=$(GIT_INDEX_FILE=$G git ls-files --unmerged | wc -l)
-               if test $best_cnt -le 0 || test $cnt -le $best_cnt
-               then
-                       best=$c
-                       best_cnt=$cnt
-                       if test "$best_cnt" -eq 0
-                       then
-                               # Cannot do any better than all trivial merge.
-                               break
-                       fi
-               fi
-       done
-       rm -f $G
-       common="$best"
-esac
-
-echo "Trying to merge $merge into $head using $common."
-git update-index --refresh 2>/dev/null
-git read-tree -u -m $common $head $merge || exit 1
-result_tree=$(git write-tree  2> /dev/null)
-if [ $? -ne 0 ]; then
-       echo "Simple merge failed, trying Automatic merge"
-       git-merge-index -o git-merge-one-file -a
-       if [ $? -ne 0 ]; then
-               echo $merge > "$GIT_DIR"/MERGE_HEAD
-               die "Automatic merge failed, fix up by hand"
-       fi
-       result_tree=$(git write-tree) || exit 1
-fi
-result_commit=$(echo "$merge_msg" | git commit-tree $result_tree -p $head -p $merge)
-echo "Committed merge $result_commit"
-git update-ref -m "resolve $merge_name: In-index merge" \
-       HEAD "$result_commit" "$head"
-git diff-tree -p $head $result_commit | git apply --stat
-dropheads
diff --git a/contrib/examples/git-revert.sh b/contrib/examples/git-revert.sh
deleted file mode 100755 (executable)
index 197838d..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-# Copyright (c) 2005 Junio C Hamano
-#
-
-case "$0" in
-*-revert* )
-       test -t 0 && edit=-e
-       replay=
-       me=revert
-       USAGE='[--edit | --no-edit] [-n] <commit-ish>' ;;
-*-cherry-pick* )
-       replay=t
-       edit=
-       me=cherry-pick
-       USAGE='[--edit] [-n] [-r] [-x] <commit-ish>'  ;;
-* )
-       echo >&2 "What are you talking about?"
-       exit 1 ;;
-esac
-
-SUBDIRECTORY_OK=Yes ;# we will cd up
-. git-sh-setup
-require_work_tree
-cd_to_toplevel
-
-no_commit=
-xopt=
-while case "$#" in 0) break ;; esac
-do
-       case "$1" in
-       -n|--n|--no|--no-|--no-c|--no-co|--no-com|--no-comm|\
-           --no-commi|--no-commit)
-               no_commit=t
-               ;;
-       -e|--e|--ed|--edi|--edit)
-               edit=-e
-               ;;
-       --n|--no|--no-|--no-e|--no-ed|--no-edi|--no-edit)
-               edit=
-               ;;
-       -r)
-               : no-op ;;
-       -x|--i-really-want-to-expose-my-private-commit-object-name)
-               replay=
-               ;;
-       -X?*)
-               xopt="$xopt$(git rev-parse --sq-quote "--${1#-X}")"
-               ;;
-       --strategy-option=*)
-               xopt="$xopt$(git rev-parse --sq-quote "--${1#--strategy-option=}")"
-               ;;
-       -X|--strategy-option)
-               shift
-               xopt="$xopt$(git rev-parse --sq-quote "--$1")"
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               break
-               ;;
-       esac
-       shift
-done
-
-set_reflog_action "$me"
-
-test "$me,$replay" = "revert,t" && usage
-
-case "$no_commit" in
-t)
-       # We do not intend to commit immediately.  We just want to
-       # merge the differences in.
-       head=$(git-write-tree) ||
-               die "Your index file is unmerged."
-       ;;
-*)
-       head=$(git-rev-parse --verify HEAD) ||
-               die "You do not have a valid HEAD"
-       files=$(git-diff-index --cached --name-only $head) || exit
-       if [ "$files" ]; then
-               die "Dirty index: cannot $me (dirty: $files)"
-       fi
-       ;;
-esac
-
-rev=$(git-rev-parse --verify "$@") &&
-commit=$(git-rev-parse --verify "$rev^0") ||
-       die "Not a single commit $@"
-prev=$(git-rev-parse --verify "$commit^1" 2>/dev/null) ||
-       die "Cannot run $me a root commit"
-git-rev-parse --verify "$commit^2" >/dev/null 2>&1 &&
-       die "Cannot run $me a multi-parent commit."
-
-encoding=$(git config i18n.commitencoding || echo UTF-8)
-
-# "commit" is an existing commit.  We would want to apply
-# the difference it introduces since its first parent "prev"
-# on top of the current HEAD if we are cherry-pick.  Or the
-# reverse of it if we are revert.
-
-case "$me" in
-revert)
-       git show -s --pretty=oneline --encoding="$encoding" $commit |
-       sed -e '
-               s/^[^ ]* /Revert "/
-               s/$/"/
-       '
-       echo
-       echo "This reverts commit $commit."
-       test "$rev" = "$commit" ||
-       echo "(original 'git revert' arguments: $@)"
-       base=$commit next=$prev
-       ;;
-
-cherry-pick)
-       pick_author_script='
-       /^author /{
-               s/'\''/'\''\\'\'\''/g
-               h
-               s/^author \([^<]*\) <[^>]*> .*$/\1/
-               s/'\''/'\''\'\'\''/g
-               s/.*/GIT_AUTHOR_NAME='\''&'\''/p
-
-               g
-               s/^author [^<]* <\([^>]*\)> .*$/\1/
-               s/'\''/'\''\'\'\''/g
-               s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p
-
-               g
-               s/^author [^<]* <[^>]*> \(.*\)$/\1/
-               s/'\''/'\''\'\'\''/g
-               s/.*/GIT_AUTHOR_DATE='\''&'\''/p
-
-               q
-       }'
-
-       logmsg=$(git show -s --pretty=raw --encoding="$encoding" "$commit")
-       set_author_env=$(echo "$logmsg" |
-       LANG=C LC_ALL=C sed -ne "$pick_author_script")
-       eval "$set_author_env"
-       export GIT_AUTHOR_NAME
-       export GIT_AUTHOR_EMAIL
-       export GIT_AUTHOR_DATE
-
-       echo "$logmsg" |
-       sed -e '1,/^$/d' -e 's/^    //'
-       case "$replay" in
-       '')
-               echo "(cherry picked from commit $commit)"
-               test "$rev" = "$commit" ||
-               echo "(original 'git cherry-pick' arguments: $@)"
-               ;;
-       esac
-       base=$prev next=$commit
-       ;;
-
-esac >.msg
-
-eval GITHEAD_$head=HEAD
-eval GITHEAD_$next='$(git show -s \
-       --pretty=oneline --encoding="$encoding" "$commit" |
-       sed -e "s/^[^ ]* //")'
-export GITHEAD_$head GITHEAD_$next
-
-# This three way merge is an interesting one.  We are at
-# $head, and would want to apply the change between $commit
-# and $prev on top of us (when reverting), or the change between
-# $prev and $commit on top of us (when cherry-picking or replaying).
-
-eval "git merge-recursive $xopt $base -- $head $next" &&
-result=$(git-write-tree 2>/dev/null) || {
-       mv -f .msg "$GIT_DIR/MERGE_MSG"
-       {
-           echo '
-Conflicts:
-'
-               git ls-files --unmerged |
-               sed -e 's/^[^   ]*      /       /' |
-               uniq
-       } >>"$GIT_DIR/MERGE_MSG"
-       echo >&2 "Automatic $me failed.  After resolving the conflicts,"
-       echo >&2 "mark the corrected paths with 'git-add <paths>'"
-       echo >&2 "and commit the result."
-       case "$me" in
-       cherry-pick)
-               echo >&2 "You may choose to use the following when making"
-               echo >&2 "the commit:"
-               echo >&2 "$set_author_env"
-       esac
-       exit 1
-}
-
-# If we are cherry-pick, and if the merge did not result in
-# hand-editing, we will hit this commit and inherit the original
-# author date and name.
-# If we are revert, or if our cherry-pick results in a hand merge,
-# we had better say that the current user is responsible for that.
-
-case "$no_commit" in
-'')
-       git-commit -n -F .msg $edit
-       rm -f .msg
-       ;;
-esac
diff --git a/contrib/examples/git-svnimport.perl b/contrib/examples/git-svnimport.perl
deleted file mode 100755 (executable)
index 75a43e2..0000000
+++ /dev/null
@@ -1,976 +0,0 @@
-#!/usr/bin/perl
-
-# This tool is copyright (c) 2005, Matthias Urlichs.
-# It is released under the Gnu Public License, version 2.
-#
-# The basic idea is to pull and analyze SVN changes.
-#
-# Checking out the files is done by a single long-running SVN connection.
-#
-# The head revision is on branch "origin" by default.
-# You can change that with the '-o' option.
-
-use strict;
-use warnings;
-use Getopt::Std;
-use File::Copy;
-use File::Spec;
-use File::Temp qw(tempfile);
-use File::Path qw(mkpath);
-use File::Basename qw(basename dirname);
-use Time::Local;
-use IO::Pipe;
-use POSIX qw(strftime dup2);
-use IPC::Open2;
-use SVN::Core;
-use SVN::Ra;
-
-die "Need SVN:Core 1.2.1 or better" if $SVN::Core::VERSION lt "1.2.1";
-
-$SIG{'PIPE'}="IGNORE";
-$ENV{'TZ'}="UTC";
-
-our($opt_h,$opt_o,$opt_v,$opt_u,$opt_C,$opt_i,$opt_m,$opt_M,$opt_t,$opt_T,
-    $opt_b,$opt_r,$opt_I,$opt_A,$opt_s,$opt_l,$opt_d,$opt_D,$opt_S,$opt_F,
-    $opt_P,$opt_R);
-
-sub usage() {
-       print STDERR <<END;
-usage: ${\basename $0}     # fetch/update GIT from SVN
-       [-o branch-for-HEAD] [-h] [-v] [-l max_rev] [-R repack_each_revs]
-       [-C GIT_repository] [-t tagname] [-T trunkname] [-b branchname]
-       [-d|-D] [-i] [-u] [-r] [-I ignorefilename] [-s start_chg]
-       [-m] [-M regex] [-A author_file] [-S] [-F] [-P project_name] [SVN_URL]
-END
-       exit(1);
-}
-
-getopts("A:b:C:dDFhiI:l:mM:o:rs:t:T:SP:R:uv") or usage();
-usage if $opt_h;
-
-my $tag_name = $opt_t || "tags";
-my $trunk_name = defined $opt_T ? $opt_T : "trunk";
-my $branch_name = $opt_b || "branches";
-my $project_name = $opt_P || "";
-$project_name = "/" . $project_name if ($project_name);
-my $repack_after = $opt_R || 1000;
-my $root_pool = SVN::Pool->new_default;
-
-@ARGV == 1 or @ARGV == 2 or usage();
-
-$opt_o ||= "origin";
-$opt_s ||= 1;
-my $git_tree = $opt_C;
-$git_tree ||= ".";
-
-my $svn_url = $ARGV[0];
-my $svn_dir = $ARGV[1];
-
-our @mergerx = ();
-if ($opt_m) {
-       my $branch_esc = quotemeta ($branch_name);
-       my $trunk_esc  = quotemeta ($trunk_name);
-       @mergerx =
-       (
-               qr!\b(?:merg(?:ed?|ing))\b.*?\b((?:(?<=$branch_esc/)[\w\.\-]+)|(?:$trunk_esc))\b!i,
-               qr!\b(?:from|of)\W+((?:(?<=$branch_esc/)[\w\.\-]+)|(?:$trunk_esc))\b!i,
-               qr!\b(?:from|of)\W+(?:the )?([\w\.\-]+)[-\s]branch\b!i
-       );
-}
-if ($opt_M) {
-       unshift (@mergerx, qr/$opt_M/);
-}
-
-# Absolutize filename now, since we will have chdir'ed by the time we
-# get around to opening it.
-$opt_A = File::Spec->rel2abs($opt_A) if $opt_A;
-
-our %users = ();
-our $users_file = undef;
-sub read_users($) {
-       $users_file = File::Spec->rel2abs(@_);
-       die "Cannot open $users_file\n" unless -f $users_file;
-       open(my $authors,$users_file);
-       while(<$authors>) {
-               chomp;
-               next unless /^(\S+?)\s*=\s*(.+?)\s*<(.+)>\s*$/;
-               (my $user,my $name,my $email) = ($1,$2,$3);
-               $users{$user} = [$name,$email];
-       }
-       close($authors);
-}
-
-select(STDERR); $|=1; select(STDOUT);
-
-
-package SVNconn;
-# Basic SVN connection.
-# We're only interested in connecting and downloading, so ...
-
-use File::Spec;
-use File::Temp qw(tempfile);
-use POSIX qw(strftime dup2);
-use Fcntl qw(SEEK_SET);
-
-sub new {
-       my($what,$repo) = @_;
-       $what=ref($what) if ref($what);
-
-       my $self = {};
-       $self->{'buffer'} = "";
-       bless($self,$what);
-
-       $repo =~ s#/+$##;
-       $self->{'fullrep'} = $repo;
-       $self->conn();
-
-       return $self;
-}
-
-sub conn {
-       my $self = shift;
-       my $repo = $self->{'fullrep'};
-       my $auth = SVN::Core::auth_open ([SVN::Client::get_simple_provider,
-                         SVN::Client::get_ssl_server_trust_file_provider,
-                         SVN::Client::get_username_provider]);
-       my $s = SVN::Ra->new(url => $repo, auth => $auth, pool => $root_pool);
-       die "SVN connection to $repo: $!\n" unless defined $s;
-       $self->{'svn'} = $s;
-       $self->{'repo'} = $repo;
-       $self->{'maxrev'} = $s->get_latest_revnum();
-}
-
-sub file {
-       my($self,$path,$rev) = @_;
-
-       my ($fh, $name) = tempfile('gitsvn.XXXXXX',
-                   DIR => File::Spec->tmpdir(), UNLINK => 1);
-
-       print "... $rev $path ...\n" if $opt_v;
-       my (undef, $properties);
-       $path =~ s#^/*##;
-       my $subpool = SVN::Pool::new_default_sub;
-       eval { (undef, $properties)
-                  = $self->{'svn'}->get_file($path,$rev,$fh); };
-       if($@) {
-               return undef if $@ =~ /Attempted to get checksum/;
-               die $@;
-       }
-       my $mode;
-       if (exists $properties->{'svn:executable'}) {
-               $mode = '100755';
-       } elsif (exists $properties->{'svn:special'}) {
-               my ($special_content, $filesize);
-               $filesize = tell $fh;
-               seek $fh, 0, SEEK_SET;
-               read $fh, $special_content, $filesize;
-               if ($special_content =~ s/^link //) {
-                       $mode = '120000';
-                       seek $fh, 0, SEEK_SET;
-                       truncate $fh, 0;
-                       print $fh $special_content;
-               } else {
-                       die "unexpected svn:special file encountered";
-               }
-       } else {
-               $mode = '100644';
-       }
-       close ($fh);
-
-       return ($name, $mode);
-}
-
-sub ignore {
-       my($self,$path,$rev) = @_;
-
-       print "... $rev $path ...\n" if $opt_v;
-       $path =~ s#^/*##;
-       my $subpool = SVN::Pool::new_default_sub;
-       my (undef,undef,$properties)
-           = $self->{'svn'}->get_dir($path,$rev,undef);
-       if (exists $properties->{'svn:ignore'}) {
-               my ($fh, $name) = tempfile('gitsvn.XXXXXX',
-                                          DIR => File::Spec->tmpdir(),
-                                          UNLINK => 1);
-               print $fh $properties->{'svn:ignore'};
-               close($fh);
-               return $name;
-       } else {
-               return undef;
-       }
-}
-
-sub dir_list {
-       my($self,$path,$rev) = @_;
-       $path =~ s#^/*##;
-       my $subpool = SVN::Pool::new_default_sub;
-       my ($dirents,undef,$properties)
-           = $self->{'svn'}->get_dir($path,$rev,undef);
-       return $dirents;
-}
-
-package main;
-use URI;
-
-our $svn = $svn_url;
-$svn .= "/$svn_dir" if defined $svn_dir;
-my $svn2 = SVNconn->new($svn);
-$svn = SVNconn->new($svn);
-
-my $lwp_ua;
-if($opt_d or $opt_D) {
-       $svn_url = URI->new($svn_url)->canonical;
-       if($opt_D) {
-               $svn_dir =~ s#/*$#/#;
-       } else {
-               $svn_dir = "";
-       }
-       if ($svn_url->scheme eq "http") {
-               use LWP::UserAgent;
-               $lwp_ua = LWP::UserAgent->new(keep_alive => 1, requests_redirectable => []);
-       } else {
-               print STDERR "Warning: not HTTP; turning off direct file access\n";
-               $opt_d=0;
-       }
-}
-
-sub pdate($) {
-       my($d) = @_;
-       $d =~ m#(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)#
-               or die "Unparseable date: $d\n";
-       my $y=$1; $y+=1900 if $y<1000;
-       return timegm($6||0,$5,$4,$3,$2-1,$y);
-}
-
-sub getwd() {
-       my $pwd = `pwd`;
-       chomp $pwd;
-       return $pwd;
-}
-
-
-sub get_headref($$) {
-    my $name    = shift;
-    my $git_dir = shift;
-    my $sha;
-
-    if (open(C,"$git_dir/refs/heads/$name")) {
-       chomp($sha = <C>);
-       close(C);
-       length($sha) == 40
-           or die "Cannot get head id for $name ($sha): $!\n";
-    }
-    return $sha;
-}
-
-
--d $git_tree
-       or mkdir($git_tree,0777)
-       or die "Could not create $git_tree: $!";
-chdir($git_tree);
-
-my $orig_branch = "";
-my $forward_master = 0;
-my %branches;
-
-my $git_dir = $ENV{"GIT_DIR"} || ".git";
-$git_dir = getwd()."/".$git_dir unless $git_dir =~ m#^/#;
-$ENV{"GIT_DIR"} = $git_dir;
-my $orig_git_index;
-$orig_git_index = $ENV{GIT_INDEX_FILE} if exists $ENV{GIT_INDEX_FILE};
-my ($git_ih, $git_index) = tempfile('gitXXXXXX', SUFFIX => '.idx',
-                                   DIR => File::Spec->tmpdir());
-close ($git_ih);
-$ENV{GIT_INDEX_FILE} = $git_index;
-my $maxnum = 0;
-my $last_rev = "";
-my $last_branch;
-my $current_rev = $opt_s || 1;
-unless(-d $git_dir) {
-       system("git init");
-       die "Cannot init the GIT db at $git_tree: $?\n" if $?;
-       system("git read-tree --empty");
-       die "Cannot init an empty tree: $?\n" if $?;
-
-       $last_branch = $opt_o;
-       $orig_branch = "";
-} else {
-       -f "$git_dir/refs/heads/$opt_o"
-               or die "Branch '$opt_o' does not exist.\n".
-                      "Either use the correct '-o branch' option,\n".
-                      "or import to a new repository.\n";
-
-       -f "$git_dir/svn2git"
-               or die "'$git_dir/svn2git' does not exist.\n".
-                      "You need that file for incremental imports.\n";
-       open(F, "git symbolic-ref HEAD |") or
-               die "Cannot run git-symbolic-ref: $!\n";
-       chomp ($last_branch = <F>);
-       $last_branch = basename($last_branch);
-       close(F);
-       unless($last_branch) {
-               warn "Cannot read the last branch name: $! -- assuming 'master'\n";
-               $last_branch = "master";
-       }
-       $orig_branch = $last_branch;
-       $last_rev = get_headref($orig_branch, $git_dir);
-       if (-f "$git_dir/SVN2GIT_HEAD") {
-               die <<EOM;
-SVN2GIT_HEAD exists.
-Make sure your working directory corresponds to HEAD and remove SVN2GIT_HEAD.
-You may need to run
-
-    git-read-tree -m -u SVN2GIT_HEAD HEAD
-EOM
-       }
-       system('cp', "$git_dir/HEAD", "$git_dir/SVN2GIT_HEAD");
-
-       $forward_master =
-           $opt_o ne 'master' && -f "$git_dir/refs/heads/master" &&
-           system('cmp', '-s', "$git_dir/refs/heads/master",
-                               "$git_dir/refs/heads/$opt_o") == 0;
-
-       # populate index
-       system('git', 'read-tree', $last_rev);
-       die "read-tree failed: $?\n" if $?;
-
-       # Get the last import timestamps
-       open my $B,"<", "$git_dir/svn2git";
-       while(<$B>) {
-               chomp;
-               my($num,$branch,$ref) = split;
-               $branches{$branch}{$num} = $ref;
-               $branches{$branch}{"LAST"} = $ref;
-               $current_rev = $num+1 if $current_rev <= $num;
-       }
-       close($B);
-}
--d $git_dir
-       or die "Could not create git subdir ($git_dir).\n";
-
-my $default_authors = "$git_dir/svn-authors";
-if ($opt_A) {
-       read_users($opt_A);
-       copy($opt_A,$default_authors) or die "Copy failed: $!";
-} else {
-       read_users($default_authors) if -f $default_authors;
-}
-
-open BRANCHES,">>", "$git_dir/svn2git";
-
-sub node_kind($$) {
-       my ($svnpath, $revision) = @_;
-       $svnpath =~ s#^/*##;
-       my $subpool = SVN::Pool::new_default_sub;
-       my $kind = $svn->{'svn'}->check_path($svnpath,$revision);
-       return $kind;
-}
-
-sub get_file($$$) {
-       my($svnpath,$rev,$path) = @_;
-
-       # now get it
-       my ($name,$mode);
-       if($opt_d) {
-               my($req,$res);
-
-               # /svn/!svn/bc/2/django/trunk/django-docs/build.py
-               my $url=$svn_url->clone();
-               $url->path($url->path."/!svn/bc/$rev/$svn_dir$svnpath");
-               print "... $path...\n" if $opt_v;
-               $req = HTTP::Request->new(GET => $url);
-               $res = $lwp_ua->request($req);
-               if ($res->is_success) {
-                       my $fh;
-                       ($fh, $name) = tempfile('gitsvn.XXXXXX',
-                       DIR => File::Spec->tmpdir(), UNLINK => 1);
-                       print $fh $res->content;
-                       close($fh) or die "Could not write $name: $!\n";
-               } else {
-                       return undef if $res->code == 301; # directory?
-                       die $res->status_line." at $url\n";
-               }
-               $mode = '0644'; # can't obtain mode via direct http request?
-       } else {
-               ($name,$mode) = $svn->file("$svnpath",$rev);
-               return undef unless defined $name;
-       }
-
-       my $pid = open(my $F, '-|');
-       die $! unless defined $pid;
-       if (!$pid) {
-           exec("git", "hash-object", "-w", $name)
-               or die "Cannot create object: $!\n";
-       }
-       my $sha = <$F>;
-       chomp $sha;
-       close $F;
-       unlink $name;
-       return [$mode, $sha, $path];
-}
-
-sub get_ignore($$$$$) {
-       my($new,$old,$rev,$path,$svnpath) = @_;
-
-       return unless $opt_I;
-       my $name = $svn->ignore("$svnpath",$rev);
-       if ($path eq '/') {
-               $path = $opt_I;
-       } else {
-               $path = File::Spec->catfile($path,$opt_I);
-       }
-       if (defined $name) {
-               my $pid = open(my $F, '-|');
-               die $! unless defined $pid;
-               if (!$pid) {
-                       exec("git", "hash-object", "-w", $name)
-                           or die "Cannot create object: $!\n";
-               }
-               my $sha = <$F>;
-               chomp $sha;
-               close $F;
-               unlink $name;
-               push(@$new,['0644',$sha,$path]);
-       } elsif (defined $old) {
-               push(@$old,$path);
-       }
-}
-
-sub project_path($$)
-{
-       my ($path, $project) = @_;
-
-       $path = "/".$path unless ($path =~ m#^\/#) ;
-       return $1 if ($path =~ m#^$project\/(.*)$#);
-
-       $path =~ s#\.#\\\.#g;
-       $path =~ s#\+#\\\+#g;
-       return "/" if ($project =~ m#^$path.*$#);
-
-       return undef;
-}
-
-sub split_path($$) {
-       my($rev,$path) = @_;
-       my $branch;
-
-       if($path =~ s#^/\Q$tag_name\E/([^/]+)/?##) {
-               $branch = "/$1";
-       } elsif($path =~ s#^/\Q$trunk_name\E/?##) {
-               $branch = "/";
-       } elsif($path =~ s#^/\Q$branch_name\E/([^/]+)/?##) {
-               $branch = $1;
-       } else {
-               my %no_error = (
-                       "/" => 1,
-                       "/$tag_name" => 1,
-                       "/$branch_name" => 1
-               );
-               print STDERR "$rev: Unrecognized path: $path\n" unless (defined $no_error{$path});
-               return ()
-       }
-       if ($path eq "") {
-               $path = "/";
-       } elsif ($project_name) {
-               $path = project_path($path, $project_name);
-       }
-       return ($branch,$path);
-}
-
-sub branch_rev($$) {
-
-       my ($srcbranch,$uptorev) = @_;
-
-       my $bbranches = $branches{$srcbranch};
-       my @revs = reverse sort { ($a eq 'LAST' ? 0 : $a) <=> ($b eq 'LAST' ? 0 : $b) } keys %$bbranches;
-       my $therev;
-       foreach my $arev(@revs) {
-               next if  ($arev eq 'LAST');
-               if ($arev <= $uptorev) {
-                       $therev = $arev;
-                       last;
-               }
-       }
-       return $therev;
-}
-
-sub expand_svndir($$$);
-
-sub expand_svndir($$$)
-{
-       my ($svnpath, $rev, $path) = @_;
-       my @list;
-       get_ignore(\@list, undef, $rev, $path, $svnpath);
-       my $dirents = $svn->dir_list($svnpath, $rev);
-       foreach my $p(keys %$dirents) {
-               my $kind = node_kind($svnpath.'/'.$p, $rev);
-               if ($kind eq $SVN::Node::file) {
-                       my $f = get_file($svnpath.'/'.$p, $rev, $path.'/'.$p);
-                       push(@list, $f) if $f;
-               } elsif ($kind eq $SVN::Node::dir) {
-                       push(@list,
-                            expand_svndir($svnpath.'/'.$p, $rev, $path.'/'.$p));
-               }
-       }
-       return @list;
-}
-
-sub copy_path($$$$$$$$) {
-       # Somebody copied a whole subdirectory.
-       # We need to find the index entries from the old version which the
-       # SVN log entry points to, and add them to the new place.
-
-       my($newrev,$newbranch,$path,$oldpath,$rev,$node_kind,$new,$parents) = @_;
-
-       my($srcbranch,$srcpath) = split_path($rev,$oldpath);
-       unless(defined $srcbranch && defined $srcpath) {
-               print "Path not found when copying from $oldpath @ $rev.\n".
-                       "Will try to copy from original SVN location...\n"
-                       if $opt_v;
-               push (@$new, expand_svndir($oldpath, $rev, $path));
-               return;
-       }
-       my $therev = branch_rev($srcbranch, $rev);
-       my $gitrev = $branches{$srcbranch}{$therev};
-       unless($gitrev) {
-               print STDERR "$newrev:$newbranch: could not find $oldpath \@ $rev\n";
-               return;
-       }
-       if ($srcbranch ne $newbranch) {
-               push(@$parents, $branches{$srcbranch}{'LAST'});
-       }
-       print "$newrev:$newbranch:$path: copying from $srcbranch:$srcpath @ $rev\n" if $opt_v;
-       if ($node_kind eq $SVN::Node::dir) {
-               $srcpath =~ s#/*$#/#;
-       }
-
-       my $pid = open my $f,'-|';
-       die $! unless defined $pid;
-       if (!$pid) {
-               exec("git","ls-tree","-r","-z",$gitrev,$srcpath)
-                       or die $!;
-       }
-       local $/ = "\0";
-       while(<$f>) {
-               chomp;
-               my($m,$p) = split(/\t/,$_,2);
-               my($mode,$type,$sha1) = split(/ /,$m);
-               next if $type ne "blob";
-               if ($node_kind eq $SVN::Node::dir) {
-                       $p = $path . substr($p,length($srcpath)-1);
-               } else {
-                       $p = $path;
-               }
-               push(@$new,[$mode,$sha1,$p]);
-       }
-       close($f) or
-               print STDERR "$newrev:$newbranch: could not list files in $oldpath \@ $rev\n";
-}
-
-sub commit {
-       my($branch, $changed_paths, $revision, $author, $date, $message) = @_;
-       my($committer_name,$committer_email,$dest);
-       my($author_name,$author_email);
-       my(@old,@new,@parents);
-
-       if (not defined $author or $author eq "") {
-               $committer_name = $committer_email = "unknown";
-       } elsif (defined $users_file) {
-               die "User $author is not listed in $users_file\n"
-                   unless exists $users{$author};
-               ($committer_name,$committer_email) = @{$users{$author}};
-       } elsif ($author =~ /^(.*?)\s+<(.*)>$/) {
-               ($committer_name, $committer_email) = ($1, $2);
-       } else {
-               $author =~ s/^<(.*)>$/$1/;
-               $committer_name = $committer_email = $author;
-       }
-
-       if ($opt_F && $message =~ /From:\s+(.*?)\s+<(.*)>\s*\n/) {
-               ($author_name, $author_email) = ($1, $2);
-               print "Author from From: $1 <$2>\n" if ($opt_v);;
-       } elsif ($opt_S && $message =~ /Signed-off-by:\s+(.*?)\s+<(.*)>\s*\n/) {
-               ($author_name, $author_email) = ($1, $2);
-               print "Author from Signed-off-by: $1 <$2>\n" if ($opt_v);;
-       } else {
-               $author_name = $committer_name;
-               $author_email = $committer_email;
-       }
-
-       $date = pdate($date);
-
-       my $tag;
-       my $parent;
-       if($branch eq "/") { # trunk
-               $parent = $opt_o;
-       } elsif($branch =~ m#^/(.+)#) { # tag
-               $tag = 1;
-               $parent = $1;
-       } else { # "normal" branch
-               # nothing to do
-               $parent = $branch;
-       }
-       $dest = $parent;
-
-       my $prev = $changed_paths->{"/"};
-       if($prev and $prev->[0] eq "A") {
-               delete $changed_paths->{"/"};
-               my $oldpath = $prev->[1];
-               my $rev;
-               if(defined $oldpath) {
-                       my $p;
-                       ($parent,$p) = split_path($revision,$oldpath);
-                       if(defined $parent) {
-                               if($parent eq "/") {
-                                       $parent = $opt_o;
-                               } else {
-                                       $parent =~ s#^/##; # if it's a tag
-                               }
-                       }
-               } else {
-                       $parent = undef;
-               }
-       }
-
-       my $rev;
-       if($revision > $opt_s and defined $parent) {
-               open(H,'-|',"git","rev-parse","--verify",$parent);
-               $rev = <H>;
-               close(H) or do {
-                       print STDERR "$revision: cannot find commit '$parent'!\n";
-                       return;
-               };
-               chop $rev;
-               if(length($rev) != 40) {
-                       print STDERR "$revision: cannot find commit '$parent'!\n";
-                       return;
-               }
-               $rev = $branches{($parent eq $opt_o) ? "/" : $parent}{"LAST"};
-               if($revision != $opt_s and not $rev) {
-                       print STDERR "$revision: do not know ancestor for '$parent'!\n";
-                       return;
-               }
-       } else {
-               $rev = undef;
-       }
-
-#      if($prev and $prev->[0] eq "A") {
-#              if(not $tag) {
-#                      unless(open(H,"> $git_dir/refs/heads/$branch")) {
-#                              print STDERR "$revision: Could not create branch $branch: $!\n";
-#                              $state=11;
-#                              next;
-#                      }
-#                      print H "$rev\n"
-#                              or die "Could not write branch $branch: $!";
-#                      close(H)
-#                              or die "Could not write branch $branch: $!";
-#              }
-#      }
-       if(not defined $rev) {
-               unlink($git_index);
-       } elsif ($rev ne $last_rev) {
-               print "Switching from $last_rev to $rev ($branch)\n" if $opt_v;
-               system("git", "read-tree", $rev);
-               die "read-tree failed for $rev: $?\n" if $?;
-               $last_rev = $rev;
-       }
-
-       push (@parents, $rev) if defined $rev;
-
-       my $cid;
-       if($tag and not %$changed_paths) {
-               $cid = $rev;
-       } else {
-               my @paths = sort keys %$changed_paths;
-               foreach my $path(@paths) {
-                       my $action = $changed_paths->{$path};
-
-                       if ($action->[0] eq "R") {
-                               # refer to a file/tree in an earlier commit
-                               push(@old,$path); # remove any old stuff
-                       }
-                       if(($action->[0] eq "A") || ($action->[0] eq "R")) {
-                               my $node_kind = node_kind($action->[3], $revision);
-                               if ($node_kind eq $SVN::Node::file) {
-                                       my $f = get_file($action->[3],
-                                                        $revision, $path);
-                                       if ($f) {
-                                               push(@new,$f) if $f;
-                                       } else {
-                                               my $opath = $action->[3];
-                                               print STDERR "$revision: $branch: could not fetch '$opath'\n";
-                                       }
-                               } elsif ($node_kind eq $SVN::Node::dir) {
-                                       if($action->[1]) {
-                                               copy_path($revision, $branch,
-                                                         $path, $action->[1],
-                                                         $action->[2], $node_kind,
-                                                         \@new, \@parents);
-                                       } else {
-                                               get_ignore(\@new, \@old, $revision,
-                                                          $path, $action->[3]);
-                                       }
-                               }
-                       } elsif ($action->[0] eq "D") {
-                               push(@old,$path);
-                       } elsif ($action->[0] eq "M") {
-                               my $node_kind = node_kind($action->[3], $revision);
-                               if ($node_kind eq $SVN::Node::file) {
-                                       my $f = get_file($action->[3],
-                                                        $revision, $path);
-                                       push(@new,$f) if $f;
-                               } elsif ($node_kind eq $SVN::Node::dir) {
-                                       get_ignore(\@new, \@old, $revision,
-                                                  $path, $action->[3]);
-                               }
-                       } else {
-                               die "$revision: unknown action '".$action->[0]."' for $path\n";
-                       }
-               }
-
-               while(@old) {
-                       my @o1;
-                       if(@old > 55) {
-                               @o1 = splice(@old,0,50);
-                       } else {
-                               @o1 = @old;
-                               @old = ();
-                       }
-                       my $pid = open my $F, "-|";
-                       die "$!" unless defined $pid;
-                       if (!$pid) {
-                               exec("git", "ls-files", "-z", @o1) or die $!;
-                       }
-                       @o1 = ();
-                       local $/ = "\0";
-                       while(<$F>) {
-                               chomp;
-                               push(@o1,$_);
-                       }
-                       close($F);
-
-                       while(@o1) {
-                               my @o2;
-                               if(@o1 > 55) {
-                                       @o2 = splice(@o1,0,50);
-                               } else {
-                                       @o2 = @o1;
-                                       @o1 = ();
-                               }
-                               system("git","update-index","--force-remove","--",@o2);
-                               die "Cannot remove files: $?\n" if $?;
-                       }
-               }
-               while(@new) {
-                       my @n2;
-                       if(@new > 12) {
-                               @n2 = splice(@new,0,10);
-                       } else {
-                               @n2 = @new;
-                               @new = ();
-                       }
-                       system("git","update-index","--add",
-                               (map { ('--cacheinfo', @$_) } @n2));
-                       die "Cannot add files: $?\n" if $?;
-               }
-
-               my $pid = open(C,"-|");
-               die "Cannot fork: $!" unless defined $pid;
-               unless($pid) {
-                       exec("git","write-tree");
-                       die "Cannot exec git-write-tree: $!\n";
-               }
-               chomp(my $tree = <C>);
-               length($tree) == 40
-                       or die "Cannot get tree id ($tree): $!\n";
-               close(C)
-                       or die "Error running git-write-tree: $?\n";
-               print "Tree ID $tree\n" if $opt_v;
-
-               my $pr = IO::Pipe->new() or die "Cannot open pipe: $!\n";
-               my $pw = IO::Pipe->new() or die "Cannot open pipe: $!\n";
-               $pid = fork();
-               die "Fork: $!\n" unless defined $pid;
-               unless($pid) {
-                       $pr->writer();
-                       $pw->reader();
-                       open(OUT,">&STDOUT");
-                       dup2($pw->fileno(),0);
-                       dup2($pr->fileno(),1);
-                       $pr->close();
-                       $pw->close();
-
-                       my @par = ();
-
-                       # loose detection of merges
-                       # based on the commit msg
-                       foreach my $rx (@mergerx) {
-                               if ($message =~ $rx) {
-                                       my $mparent = $1;
-                                       if ($mparent eq 'HEAD') { $mparent = $opt_o };
-                                       if ( -e "$git_dir/refs/heads/$mparent") {
-                                               $mparent = get_headref($mparent, $git_dir);
-                                               push (@parents, $mparent);
-                                               print OUT "Merge parent branch: $mparent\n" if $opt_v;
-                                       }
-                               }
-                       }
-                       my %seen_parents = ();
-                       my @unique_parents = grep { ! $seen_parents{$_} ++ } @parents;
-                       foreach my $bparent (@unique_parents) {
-                               push @par, '-p', $bparent;
-                               print OUT "Merge parent branch: $bparent\n" if $opt_v;
-                       }
-
-                       exec("env",
-                               "GIT_AUTHOR_NAME=$author_name",
-                               "GIT_AUTHOR_EMAIL=$author_email",
-                               "GIT_AUTHOR_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)),
-                               "GIT_COMMITTER_NAME=$committer_name",
-                               "GIT_COMMITTER_EMAIL=$committer_email",
-                               "GIT_COMMITTER_DATE=".strftime("+0000 %Y-%m-%d %H:%M:%S",gmtime($date)),
-                               "git", "commit-tree", $tree,@par);
-                       die "Cannot exec git-commit-tree: $!\n";
-               }
-               $pw->writer();
-               $pr->reader();
-
-               $message =~ s/[\s\n]+\z//;
-               $message = "r$revision: $message" if $opt_r;
-
-               print $pw "$message\n"
-                       or die "Error writing to git-commit-tree: $!\n";
-               $pw->close();
-
-               print "Committed change $revision:$branch ".strftime("%Y-%m-%d %H:%M:%S",gmtime($date)).")\n" if $opt_v;
-               chomp($cid = <$pr>);
-               length($cid) == 40
-                       or die "Cannot get commit id ($cid): $!\n";
-               print "Commit ID $cid\n" if $opt_v;
-               $pr->close();
-
-               waitpid($pid,0);
-               die "Error running git-commit-tree: $?\n" if $?;
-       }
-
-       if (not defined $cid) {
-               $cid = $branches{"/"}{"LAST"};
-       }
-
-       if(not defined $dest) {
-               print "... no known parent\n" if $opt_v;
-       } elsif(not $tag) {
-               print "Writing to refs/heads/$dest\n" if $opt_v;
-               open(C,">$git_dir/refs/heads/$dest") and
-               print C ("$cid\n") and
-               close(C)
-                       or die "Cannot write branch $dest for update: $!\n";
-       }
-
-       if ($tag) {
-               $last_rev = "-" if %$changed_paths;
-               # the tag was 'complex', i.e. did not refer to a "real" revision
-
-               $dest =~ tr/_/\./ if $opt_u;
-
-               system('git', 'tag', '-f', $dest, $cid) == 0
-                       or die "Cannot create tag $dest: $!\n";
-
-               print "Created tag '$dest' on '$branch'\n" if $opt_v;
-       }
-       $branches{$branch}{"LAST"} = $cid;
-       $branches{$branch}{$revision} = $cid;
-       $last_rev = $cid;
-       print BRANCHES "$revision $branch $cid\n";
-       print "DONE: $revision $dest $cid\n" if $opt_v;
-}
-
-sub commit_all {
-       # Recursive use of the SVN connection does not work
-       local $svn = $svn2;
-
-       my ($changed_paths, $revision, $author, $date, $message) = @_;
-       my %p;
-       while(my($path,$action) = each %$changed_paths) {
-               $p{$path} = [ $action->action,$action->copyfrom_path, $action->copyfrom_rev, $path ];
-       }
-       $changed_paths = \%p;
-
-       my %done;
-       my @col;
-       my $pref;
-       my $branch;
-
-       while(my($path,$action) = each %$changed_paths) {
-               ($branch,$path) = split_path($revision,$path);
-               next if not defined $branch;
-               next if not defined $path;
-               $done{$branch}{$path} = $action;
-       }
-       while(($branch,$changed_paths) = each %done) {
-               commit($branch, $changed_paths, $revision, $author, $date, $message);
-       }
-}
-
-$opt_l = $svn->{'maxrev'} if not defined $opt_l or $opt_l > $svn->{'maxrev'};
-
-if ($opt_l < $current_rev) {
-    print "Up to date: no new revisions to fetch!\n" if $opt_v;
-    unlink("$git_dir/SVN2GIT_HEAD");
-    exit;
-}
-
-print "Processing from $current_rev to $opt_l ...\n" if $opt_v;
-
-my $from_rev;
-my $to_rev = $current_rev - 1;
-
-my $subpool = SVN::Pool::new_default_sub;
-while ($to_rev < $opt_l) {
-       $subpool->clear;
-       $from_rev = $to_rev + 1;
-       $to_rev = $from_rev + $repack_after;
-       $to_rev = $opt_l if $opt_l < $to_rev;
-       print "Fetching from $from_rev to $to_rev ...\n" if $opt_v;
-       $svn->{'svn'}->get_log("",$from_rev,$to_rev,0,1,1,\&commit_all);
-       my $pid = fork();
-       die "Fork: $!\n" unless defined $pid;
-       unless($pid) {
-               exec("git", "repack", "-d")
-                       or die "Cannot repack: $!\n";
-       }
-       waitpid($pid, 0);
-}
-
-
-unlink($git_index);
-
-if (defined $orig_git_index) {
-       $ENV{GIT_INDEX_FILE} = $orig_git_index;
-} else {
-       delete $ENV{GIT_INDEX_FILE};
-}
-
-# Now switch back to the branch we were in before all of this happened
-if($orig_branch) {
-       print "DONE\n" if $opt_v and (not defined $opt_l or $opt_l > 0);
-       system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master")
-               if $forward_master;
-       unless ($opt_i) {
-               system('git', 'read-tree', '-m', '-u', 'SVN2GIT_HEAD', 'HEAD');
-               die "read-tree failed: $?\n" if $?;
-       }
-} else {
-       $orig_branch = "master";
-       print "DONE; creating $orig_branch branch\n" if $opt_v and (not defined $opt_l or $opt_l > 0);
-       system("cp","$git_dir/refs/heads/$opt_o","$git_dir/refs/heads/master")
-               unless -f "$git_dir/refs/heads/master";
-       system('git', 'update-ref', 'HEAD', "$orig_branch");
-       unless ($opt_i) {
-               system('git checkout');
-               die "checkout failed: $?\n" if $?;
-       }
-}
-unlink("$git_dir/SVN2GIT_HEAD");
-close(BRANCHES);
diff --git a/contrib/examples/git-svnimport.txt b/contrib/examples/git-svnimport.txt
deleted file mode 100644 (file)
index 3f0a9c3..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-git-svnimport(1)
-================
-v0.1, July 2005
-
-NAME
-----
-git-svnimport - Import a SVN repository into git
-
-
-SYNOPSIS
---------
-[verse]
-'git-svnimport' [ -o <branch-for-HEAD> ] [ -h ] [ -v ] [ -d | -D ]
-               [ -C <GIT_repository> ] [ -i ] [ -u ] [-l limit_rev]
-               [ -b branch_subdir ] [ -T trunk_subdir ] [ -t tag_subdir ]
-               [ -s start_chg ] [ -m ] [ -r ] [ -M regex ]
-               [ -I <ignorefile_name> ] [ -A <author_file> ]
-               [ -R <repack_each_revs>] [ -P <path_from_trunk> ]
-               <SVN_repository_URL> [ <path> ]
-
-
-DESCRIPTION
------------
-Imports a SVN repository into git. It will either create a new
-repository, or incrementally import into an existing one.
-
-SVN access is done by the SVN::Perl module.
-
-git-svnimport assumes that SVN repositories are organized into one
-"trunk" directory where the main development happens, "branches/FOO"
-directories for branches, and "/tags/FOO" directories for tags.
-Other subdirectories are ignored.
-
-git-svnimport creates a file ".git/svn2git", which is required for
-incremental SVN imports.
-
-OPTIONS
--------
--C <target-dir>::
-        The GIT repository to import to.  If the directory doesn't
-        exist, it will be created.  Default is the current directory.
-
--s <start_rev>::
-        Start importing at this SVN change number. The  default is 1.
-+
-When importing incrementally, you might need to edit the .git/svn2git file.
-
--i::
-       Import-only: don't perform a checkout after importing.  This option
-       ensures the working directory and index remain untouched and will
-       not create them if they do not exist.
-
--T <trunk_subdir>::
-       Name the SVN trunk. Default "trunk".
-
--t <tag_subdir>::
-       Name the SVN subdirectory for tags. Default "tags".
-
--b <branch_subdir>::
-       Name the SVN subdirectory for branches. Default "branches".
-
--o <branch-for-HEAD>::
-       The 'trunk' branch from SVN is imported to the 'origin' branch within
-       the git repository. Use this option if you want to import into a
-       different branch.
-
--r::
-       Prepend 'rX: ' to commit messages, where X is the imported
-       subversion revision.
-
--u::
-       Replace underscores in tag names with periods.
-
--I <ignorefile_name>::
-       Import the svn:ignore directory property to files with this
-       name in each directory. (The Subversion and GIT ignore
-       syntaxes are similar enough that using the Subversion patterns
-       directly with "-I .gitignore" will almost always just work.)
-
--A <author_file>::
-       Read a file with lines on the form
-+
-------
-       username = User's Full Name <email@addr.es>
-
-------
-+
-and use "User's Full Name <email@addr.es>" as the GIT
-author and committer for Subversion commits made by
-"username". If encountering a commit made by a user not in the
-list, abort.
-+
-For convenience, this data is saved to $GIT_DIR/svn-authors
-each time the -A option is provided, and read from that same
-file each time git-svnimport is run with an existing GIT
-repository without -A.
-
--m::
-       Attempt to detect merges based on the commit message. This option
-       will enable default regexes that try to capture the name source
-       branch name from the commit message.
-
--M <regex>::
-       Attempt to detect merges based on the commit message with a custom
-       regex. It can be used with -m to also see the default regexes.
-       You must escape forward slashes.
-
--l <max_rev>::
-       Specify a maximum revision number to pull.
-+
-Formerly, this option controlled how many revisions to pull,
-due to SVN memory leaks. (These have been worked around.)
-
--R <repack_each_revs>::
-       Specify how often git repository should be repacked.
-+
-The default value is 1000. git-svnimport will do imports in chunks of 1000
-revisions, after each chunk the git repository will be repacked. To disable
-this behavior specify some large value here which is greater than the number of
-revisions to import.
-
--P <path_from_trunk>::
-       Partial import of the SVN tree.
-+
-By default, the whole tree on the SVN trunk (/trunk) is imported.
-'-P my/proj' will import starting only from '/trunk/my/proj'.
-This option is useful when you want to import one project from a
-svn repo which hosts multiple projects under the same trunk.
-
--v::
-       Verbosity: let 'svnimport' report what it is doing.
-
--d::
-       Use direct HTTP requests if possible. The "<path>" argument is used
-       only for retrieving the SVN logs; the path to the contents is
-       included in the SVN log.
-
--D::
-       Use direct HTTP requests if possible. The "<path>" argument is used
-       for retrieving the logs, as well as for the contents.
-+
-There's no safe way to automatically find out which of these options to
-use, so you need to try both. Usually, the one that's wrong will die
-with a 40x error pretty quickly.
-
-<SVN_repository_URL>::
-       The URL of the SVN module you want to import. For local
-       repositories, use "file:///absolute/path".
-+
-If you're using the "-d" or "-D" option, this is the URL of the SVN
-repository itself; it usually ends in "/svn".
-
-<path>::
-       The path to the module you want to check out.
-
--h::
-       Print a short usage message and exit.
-
-OUTPUT
-------
-If '-v' is specified, the script reports what it is doing.
-
-Otherwise, success is indicated the Unix way, i.e. by simply exiting with
-a zero exit status.
-
-Author
-------
-Written by Matthias Urlichs <smurf@smurf.noris.de>, with help from
-various participants of the git-list <git@vger.kernel.org>.
-
-Based on a cvs2git script by the same author.
-
-Documentation
---------------
-Documentation by Matthias Urlichs <smurf@smurf.noris.de>.
-
-GIT
----
-Part of the linkgit:git[7] suite
diff --git a/contrib/examples/git-tag.sh b/contrib/examples/git-tag.sh
deleted file mode 100755 (executable)
index 1bd8f3c..0000000
+++ /dev/null
@@ -1,205 +0,0 @@
-#!/bin/sh
-# Copyright (c) 2005 Linus Torvalds
-
-USAGE='[-n [<num>]] -l [<pattern>] | [-a | -s | -u <key-id>] [-f | -d | -v] [-m <msg>] <tagname> [<head>]'
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-message_given=
-annotate=
-signed=
-force=
-message=
-username=
-list=
-verify=
-LINES=0
-while test $# != 0
-do
-    case "$1" in
-    -a)
-       annotate=1
-       shift
-       ;;
-    -s)
-       annotate=1
-       signed=1
-       shift
-       ;;
-    -f)
-       force=1
-       shift
-       ;;
-    -n)
-        case "$#,$2" in
-       1,* | *,-*)
-               LINES=1         # no argument
-               ;;
-       *)      shift
-               LINES=$(expr "$1" : '\([0-9]*\)')
-               [ -z "$LINES" ] && LINES=1 # 1 line is default when -n is used
-               ;;
-       esac
-       shift
-       ;;
-    -l)
-       list=1
-       shift
-       case $# in
-       0)      PATTERN=
-               ;;
-       *)
-               PATTERN="$1"    # select tags by shell pattern, not re
-               shift
-               ;;
-       esac
-       git rev-parse --symbolic --tags | sort |
-           while read TAG
-           do
-               case "$TAG" in
-               *$PATTERN*) ;;
-               *)          continue ;;
-               esac
-               [ "$LINES" -le 0 ] && { echo "$TAG"; continue ;}
-               OBJTYPE=$(git cat-file -t "$TAG")
-               case $OBJTYPE in
-               tag)
-                       ANNOTATION=$(git cat-file tag "$TAG" |
-                               sed -e '1,/^$/d' |
-                               sed -n -e "
-                                       /^-----BEGIN PGP SIGNATURE-----\$/q
-                                       2,\$s/^/    /
-                                       p
-                                       ${LINES}q
-                               ")
-                       printf "%-15s %s\n" "$TAG" "$ANNOTATION"
-                       ;;
-               *)      echo "$TAG"
-                       ;;
-               esac
-           done
-       ;;
-    -m)
-       annotate=1
-       shift
-       message="$1"
-       if test "$#" = "0"; then
-           die "error: option -m needs an argument"
-       else
-           message="$1"
-           message_given=1
-           shift
-       fi
-       ;;
-    -F)
-       annotate=1
-       shift
-       if test "$#" = "0"; then
-           die "error: option -F needs an argument"
-       else
-           message="$(cat "$1")"
-           message_given=1
-           shift
-       fi
-       ;;
-    -u)
-       annotate=1
-       signed=1
-       shift
-       if test "$#" = "0"; then
-           die "error: option -u needs an argument"
-       else
-           username="$1"
-           shift
-       fi
-       ;;
-    -d)
-       shift
-       had_error=0
-       for tag
-       do
-               cur=$(git show-ref --verify --hash -- "refs/tags/$tag") || {
-                       echo >&2 "Seriously, what tag are you talking about?"
-                       had_error=1
-                       continue
-               }
-               git update-ref -m 'tag: delete' -d "refs/tags/$tag" "$cur" || {
-                       had_error=1
-                       continue
-               }
-               echo "Deleted tag $tag."
-       done
-       exit $had_error
-       ;;
-    -v)
-       shift
-       tag_name="$1"
-       tag=$(git show-ref --verify --hash -- "refs/tags/$tag_name") ||
-               die "Seriously, what tag are you talking about?"
-       git-verify-tag -v "$tag"
-       exit $?
-       ;;
-    -*)
-        usage
-       ;;
-    *)
-       break
-       ;;
-    esac
-done
-
-[ -n "$list" ] && exit 0
-
-name="$1"
-[ "$name" ] || usage
-prev=0000000000000000000000000000000000000000
-if git show-ref --verify --quiet -- "refs/tags/$name"
-then
-    test -n "$force" || die "tag '$name' already exists"
-    prev=$(git rev-parse "refs/tags/$name")
-fi
-shift
-git check-ref-format "tags/$name" ||
-       die "we do not like '$name' as a tag name."
-
-object=$(git rev-parse --verify --default HEAD "$@") || exit 1
-type=$(git cat-file -t $object) || exit 1
-tagger=$(git var GIT_COMMITTER_IDENT) || exit 1
-
-test -n "$username" ||
-       username=$(git config user.signingkey) ||
-       username=$(expr "z$tagger" : 'z\(.*>\)')
-
-trap 'rm -f "$GIT_DIR"/TAG_TMP* "$GIT_DIR"/TAG_FINALMSG "$GIT_DIR"/TAG_EDITMSG' 0
-
-if [ "$annotate" ]; then
-    if [ -z "$message_given" ]; then
-        ( echo "#"
-          echo "# Write a tag message"
-          echo "#" ) > "$GIT_DIR"/TAG_EDITMSG
-        git_editor "$GIT_DIR"/TAG_EDITMSG || exit
-    else
-        printf '%s\n' "$message" >"$GIT_DIR"/TAG_EDITMSG
-    fi
-
-    grep -v '^#' <"$GIT_DIR"/TAG_EDITMSG |
-    git stripspace >"$GIT_DIR"/TAG_FINALMSG
-
-    [ -s "$GIT_DIR"/TAG_FINALMSG -o -n "$message_given" ] || {
-       echo >&2 "No tag message?"
-       exit 1
-    }
-
-    ( printf 'object %s\ntype %s\ntag %s\ntagger %s\n\n' \
-       "$object" "$type" "$name" "$tagger";
-      cat "$GIT_DIR"/TAG_FINALMSG ) >"$GIT_DIR"/TAG_TMP
-    rm -f "$GIT_DIR"/TAG_TMP.asc "$GIT_DIR"/TAG_FINALMSG
-    if [ "$signed" ]; then
-       gpg -bsa -u "$username" "$GIT_DIR"/TAG_TMP &&
-       cat "$GIT_DIR"/TAG_TMP.asc >>"$GIT_DIR"/TAG_TMP ||
-       die "failed to sign the tag with GPG."
-    fi
-    object=$(git-mktag < "$GIT_DIR"/TAG_TMP)
-fi
-
-git update-ref "refs/tags/$name" "$object" "$prev"
diff --git a/contrib/examples/git-verify-tag.sh b/contrib/examples/git-verify-tag.sh
deleted file mode 100755 (executable)
index 0902a5c..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/bin/sh
-
-USAGE='<tag>'
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-verbose=
-while test $# != 0
-do
-       case "$1" in
-       -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
-               verbose=t ;;
-       *)
-               break ;;
-       esac
-       shift
-done
-
-if [ "$#" != "1" ]
-then
-       usage
-fi
-
-type="$(git cat-file -t "$1" 2>/dev/null)" ||
-       die "$1: no such object."
-
-test "$type" = tag ||
-       die "$1: cannot verify a non-tag object of type $type."
-
-case "$verbose" in
-t)
-       git cat-file -p "$1" |
-       sed -n -e '/^-----BEGIN PGP SIGNATURE-----/q' -e p
-       ;;
-esac
-
-trap 'rm -f "$GIT_DIR/.tmp-vtag"' 0
-
-git cat-file tag "$1" >"$GIT_DIR/.tmp-vtag" || exit 1
-sed -n -e '
-       /^-----BEGIN PGP SIGNATURE-----$/q
-       p
-' <"$GIT_DIR/.tmp-vtag" |
-gpg --verify "$GIT_DIR/.tmp-vtag" - || exit 1
-rm -f "$GIT_DIR/.tmp-vtag"
diff --git a/contrib/examples/git-whatchanged.sh b/contrib/examples/git-whatchanged.sh
deleted file mode 100755 (executable)
index 2edbdc6..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-USAGE='[-p] [--max-count=<n>] [<since>..<limit>] [--pretty=<format>] [-m] [git-diff-tree options] [git-rev-list options]'
-SUBDIRECTORY_OK='Yes'
-. git-sh-setup
-
-diff_tree_flags=$(git-rev-parse --sq --no-revs --flags "$@") || exit
-case "$0" in
-*whatchanged)
-       count=
-       test -z "$diff_tree_flags" &&
-               diff_tree_flags=$(git config --get whatchanged.difftree)
-       diff_tree_default_flags='-c -M --abbrev' ;;
-*show)
-       count=-n1
-       test -z "$diff_tree_flags" &&
-               diff_tree_flags=$(git config --get show.difftree)
-       diff_tree_default_flags='--cc --always' ;;
-esac
-test -z "$diff_tree_flags" &&
-       diff_tree_flags="$diff_tree_default_flags"
-
-rev_list_args=$(git-rev-parse --sq --default HEAD --revs-only "$@") &&
-diff_tree_args=$(git-rev-parse --sq --no-revs --no-flags "$@") &&
-
-eval "git-rev-list $count $rev_list_args" |
-eval "git-diff-tree --stdin --pretty -r $diff_tree_flags $diff_tree_args" |
-LESS="$LESS -S" ${PAGER:-less}
index d60b4315ed60ad10e849408c6986d1ea5b47b32b..e800d9f5c9cf25e1aae3a0b87ad35f46b2a973c3 100755 (executable)
@@ -63,6 +63,8 @@ foreach my $tar_file (@ARGV)
        my $have_top_dir = 1;
        my ($top_dir, %files);
 
+       my $next_path = '';
+
        while (read(I, $_, 512) == 512) {
                my ($name, $mode, $uid, $gid, $size, $mtime,
                        $chksum, $typeflag, $linkname, $magic,
@@ -70,6 +72,13 @@ foreach my $tar_file (@ARGV)
                        $prefix) = unpack 'Z100 Z8 Z8 Z8 Z12 Z12
                        Z8 Z1 Z100 Z6
                        Z2 Z32 Z32 Z8 Z8 Z*', $_;
+
+               unless ($next_path eq '') {
+                       # Recover name from previous extended header
+                       $name = $next_path;
+                       $next_path = '';
+               }
+
                last unless length($name);
                if ($name eq '././@LongLink') {
                        # GNU tar extension
@@ -90,13 +99,31 @@ foreach my $tar_file (@ARGV)
                        Z8 Z1 Z100 Z6
                        Z2 Z32 Z32 Z8 Z8 Z*', $_;
                }
-               next if $name =~ m{/\z};
                $mode = oct $mode;
                $size = oct $size;
                $mtime = oct $mtime;
                next if $typeflag == 5; # directory
 
-               if ($typeflag != 1) { # handle hard links later
+               if ($typeflag eq 'x') { # extended header
+                       # If extended header, check for path
+                       my $pax_header = '';
+                       while ($size > 0 && read(I, $_, 512) == 512) {
+                               $pax_header = $pax_header . substr($_, 0, $size);
+                               $size -= 512;
+                       }
+
+                       my @lines = split /\n/, $pax_header;
+                       foreach my $line (@lines) {
+                               my ($len, $entry) = split / /, $line;
+                               my ($key, $value) = split /=/, $entry;
+                               if ($key eq 'path') {
+                                       $next_path = $value;
+                               }
+                       }
+                       next;
+               } elsif ($name =~ m{/\z}) { # directory
+                       next;
+               } elsif ($typeflag != 1) { # handle hard links later
                        print FI "blob\n", "mark :$next_mark\n";
                        if ($typeflag == 2) { # symbolic link
                                print FI "data ", length($linkname), "\n",
index a4b6f7a2cd4122adbb74a565b34270578b7b6aed..4e603512a39fe209b537cdc47c344c99f7cc38f1 100644 (file)
@@ -21,8 +21,9 @@ HERE=contrib/mw-to-git/
 INSTALL = install
 
 SCRIPT_PERL_FULL=$(patsubst %,$(HERE)/%,$(SCRIPT_PERL))
-INSTLIBDIR=$(shell $(MAKE) -C $(GIT_ROOT_DIR)/perl \
-                -s --no-print-directory instlibdir)
+INSTLIBDIR=$(shell $(MAKE) -C $(GIT_ROOT_DIR)/ \
+                -s --no-print-directory prefix=$(prefix) \
+                perllibdir=$(perllibdir) perllibdir)
 DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
 INSTLIBDIR_SQ = $(subst ','\'',$(INSTLIBDIR))
 
index b9e2fc8540d5a8c6f7ceb05fc97a7c502732d8f2..151a1970419fd042466932331b3ab216e40d2560 100644 (file)
@@ -1,10 +1,10 @@
 TL;DR: Run update_unicode.sh after the publication of a new Unicode
-standard and commit the resulting unicode_widths.h file.
+standard and commit the resulting unicode-widths.h file.
 
 The long version
 ================
 
-The Git source code ships the file unicode_widths.h which contains
+The Git source code ships the file unicode-widths.h which contains
 tables of zero and double width Unicode code points, respectively.
 These tables are generated using update_unicode.sh in this directory.
 update_unicode.sh itself uses a third-party tool, uniset, to query two
@@ -16,5 +16,5 @@ This requires a current-ish version of autoconf (2.69 works per December
 
 On each run, update_unicode.sh checks whether more recent Unicode data
 files are available from the Unicode consortium, and rebuilds the header
-unicode_widths.h with the new data. The new header can then be
+unicode-widths.h with the new data. The new header can then be
 committed.
index e05db92d3fb255d09a1844ceb6428b6279e8eea9..aa90865befa428e0b0972197bc0e79d008fd7053 100755 (executable)
@@ -6,7 +6,7 @@
 #Cf Format          a format control character
 #
 cd "$(dirname "$0")"
-UNICODEWIDTH_H=$(git rev-parse --show-toplevel)/unicode_width.h
+UNICODEWIDTH_H=$(git rev-parse --show-toplevel)/unicode-width.h
 
 wget -N http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt \
        http://www.unicode.org/Public/UCD/latest/ucd/EastAsianWidth.txt &&
index cc562f65094cd696466f86c3184f61cd025c2117..64d0d30e08de4acd496bf955d9ce64afa0ff5b8b 100644 (file)
--- a/convert.c
+++ b/convert.c
@@ -7,6 +7,7 @@
 #include "sigchain.h"
 #include "pkt-line.h"
 #include "sub-process.h"
+#include "utf8.h"
 
 /*
  * convert.c - convert a file when checking it out and checking it in.
@@ -265,6 +266,241 @@ static int will_convert_lf_to_crlf(size_t len, struct text_stat *stats,
 
 }
 
+static int validate_encoding(const char *path, const char *enc,
+                     const char *data, size_t len, int die_on_error)
+{
+       /* We only check for UTF here as UTF?? can be an alias for UTF-?? */
+       if (istarts_with(enc, "UTF")) {
+               /*
+                * Check for detectable errors in UTF encodings
+                */
+               if (has_prohibited_utf_bom(enc, data, len)) {
+                       const char *error_msg = _(
+                               "BOM is prohibited in '%s' if encoded as %s");
+                       /*
+                        * This advice is shown for UTF-??BE and UTF-??LE encodings.
+                        * We cut off the last two characters of the encoding name
+                        * to generate the encoding name suitable for BOMs.
+                        */
+                       const char *advise_msg = _(
+                               "The file '%s' contains a byte order "
+                               "mark (BOM). Please use UTF-%s as "
+                               "working-tree-encoding.");
+                       const char *stripped = NULL;
+                       char *upper = xstrdup_toupper(enc);
+                       upper[strlen(upper)-2] = '\0';
+                       if (!skip_prefix(upper, "UTF-", &stripped))
+                               skip_prefix(stripped, "UTF", &stripped);
+                       advise(advise_msg, path, stripped);
+                       free(upper);
+                       if (die_on_error)
+                               die(error_msg, path, enc);
+                       else {
+                               return error(error_msg, path, enc);
+                       }
+
+               } else if (is_missing_required_utf_bom(enc, data, len)) {
+                       const char *error_msg = _(
+                               "BOM is required in '%s' if encoded as %s");
+                       const char *advise_msg = _(
+                               "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.");
+                       const char *stripped = NULL;
+                       char *upper = xstrdup_toupper(enc);
+                       if (!skip_prefix(upper, "UTF-", &stripped))
+                               skip_prefix(stripped, "UTF", &stripped);
+                       advise(advise_msg, path, stripped, stripped);
+                       free(upper);
+                       if (die_on_error)
+                               die(error_msg, path, enc);
+                       else {
+                               return error(error_msg, path, enc);
+                       }
+               }
+
+       }
+       return 0;
+}
+
+static void trace_encoding(const char *context, const char *path,
+                          const char *encoding, const char *buf, size_t len)
+{
+       static struct trace_key coe = TRACE_KEY_INIT(WORKING_TREE_ENCODING);
+       struct strbuf trace = STRBUF_INIT;
+       int i;
+
+       strbuf_addf(&trace, "%s (%s, considered %s):\n", context, path, encoding);
+       for (i = 0; i < len && buf; ++i) {
+               strbuf_addf(
+                       &trace,"| \e[2m%2i:\e[0m %2x \e[2m%c\e[0m%c",
+                       i,
+                       (unsigned char) buf[i],
+                       (buf[i] > 32 && buf[i] < 127 ? buf[i] : ' '),
+                       ((i+1) % 8 && (i+1) < len ? ' ' : '\n')
+               );
+       }
+       strbuf_addchars(&trace, '\n', 1);
+
+       trace_strbuf(&coe, &trace);
+       strbuf_release(&trace);
+}
+
+static int check_roundtrip(const char *enc_name)
+{
+       /*
+        * check_roundtrip_encoding contains a string of comma and/or
+        * space separated encodings (eg. "UTF-16, ASCII, CP1125").
+        * Search for the given encoding in that string.
+        */
+       const char *found = strcasestr(check_roundtrip_encoding, enc_name);
+       const char *next;
+       int len;
+       if (!found)
+               return 0;
+       next = found + strlen(enc_name);
+       len = strlen(check_roundtrip_encoding);
+       return (found && (
+                       /*
+                        * check that the found encoding is at the
+                        * beginning of check_roundtrip_encoding or
+                        * that it is prefixed with a space or comma
+                        */
+                       found == check_roundtrip_encoding || (
+                               (isspace(found[-1]) || found[-1] == ',')
+                       )
+               ) && (
+                       /*
+                        * check that the found encoding is at the
+                        * end of check_roundtrip_encoding or
+                        * that it is suffixed with a space or comma
+                        */
+                       next == check_roundtrip_encoding + len || (
+                               next < check_roundtrip_encoding + len &&
+                               (isspace(next[0]) || next[0] == ',')
+                       )
+               ));
+}
+
+static const char *default_encoding = "UTF-8";
+
+static int encode_to_git(const char *path, const char *src, size_t src_len,
+                        struct strbuf *buf, const char *enc, int conv_flags)
+{
+       char *dst;
+       int dst_len;
+       int die_on_error = conv_flags & CONV_WRITE_OBJECT;
+
+       /*
+        * No encoding is specified or there is nothing to encode.
+        * Tell the caller that the content was not modified.
+        */
+       if (!enc || (src && !src_len))
+               return 0;
+
+       /*
+        * Looks like we got called from "would_convert_to_git()".
+        * This means Git wants to know if it would encode (= modify!)
+        * the content. Let's answer with "yes", since an encoding was
+        * specified.
+        */
+       if (!buf && !src)
+               return 1;
+
+       if (validate_encoding(path, enc, src, src_len, die_on_error))
+               return 0;
+
+       trace_encoding("source", path, enc, src, src_len);
+       dst = reencode_string_len(src, src_len, default_encoding, enc,
+                                 &dst_len);
+       if (!dst) {
+               /*
+                * We could add the blob "as-is" to Git. However, on checkout
+                * we would try to reencode to the original encoding. This
+                * would fail and we would leave the user with a messed-up
+                * working tree. Let's try to avoid this by screaming loud.
+                */
+               const char* msg = _("failed to encode '%s' from %s to %s");
+               if (die_on_error)
+                       die(msg, path, enc, default_encoding);
+               else {
+                       error(msg, path, enc, default_encoding);
+                       return 0;
+               }
+       }
+       trace_encoding("destination", path, default_encoding, dst, dst_len);
+
+       /*
+        * UTF supports lossless conversion round tripping [1] and conversions
+        * between UTF and other encodings are mostly round trip safe as
+        * Unicode aims to be a superset of all other character encodings.
+        * However, certain encodings (e.g. SHIFT-JIS) are known to have round
+        * trip issues [2]. Check the round trip conversion for all encodings
+        * listed in core.checkRoundtripEncoding.
+        *
+        * The round trip check is only performed if content is written to Git.
+        * This ensures that no information is lost during conversion to/from
+        * the internal UTF-8 representation.
+        *
+        * Please note, the code below is not tested because I was not able to
+        * generate a faulty round trip without an iconv error. Iconv errors
+        * are already caught above.
+        *
+        * [1] http://unicode.org/faq/utf_bom.html#gen2
+        * [2] https://support.microsoft.com/en-us/help/170559/prb-conversion-problem-between-shift-jis-and-unicode
+        */
+       if (die_on_error && check_roundtrip(enc)) {
+               char *re_src;
+               int re_src_len;
+
+               re_src = reencode_string_len(dst, dst_len,
+                                            enc, default_encoding,
+                                            &re_src_len);
+
+               trace_printf("Checking roundtrip encoding for %s...\n", enc);
+               trace_encoding("reencoded source", path, enc,
+                              re_src, re_src_len);
+
+               if (!re_src || src_len != re_src_len ||
+                   memcmp(src, re_src, src_len)) {
+                       const char* msg = _("encoding '%s' from %s to %s and "
+                                           "back is not the same");
+                       die(msg, path, enc, default_encoding);
+               }
+
+               free(re_src);
+       }
+
+       strbuf_attach(buf, dst, dst_len, dst_len + 1);
+       return 1;
+}
+
+static int encode_to_worktree(const char *path, const char *src, size_t src_len,
+                             struct strbuf *buf, const char *enc)
+{
+       char *dst;
+       int dst_len;
+
+       /*
+        * No encoding is specified or there is nothing to encode.
+        * Tell the caller that the content was not modified.
+        */
+       if (!enc || (src && !src_len))
+               return 0;
+
+       dst = reencode_string_len(src, src_len, enc, default_encoding,
+                                 &dst_len);
+       if (!dst) {
+               error("failed to encode '%s' from %s to %s",
+                       path, default_encoding, enc);
+               return 0;
+       }
+
+       strbuf_attach(buf, dst, dst_len, dst_len + 1);
+       return 1;
+}
+
 static int crlf_to_git(const struct index_state *istate,
                       const char *path, const char *src, size_t len,
                       struct strbuf *buf,
@@ -914,7 +1150,7 @@ static int ident_to_worktree(const char *path, const char *src, size_t len,
                to_free = strbuf_detach(buf, NULL);
        hash_object_file(src, len, "blob", &oid);
 
-       strbuf_grow(buf, len + cnt * 43);
+       strbuf_grow(buf, len + cnt * (the_hash_algo->hexsz + 3));
        for (;;) {
                /* step 1: run to the next '$' */
                dollar = memchr(src, '$', len);
@@ -978,6 +1214,24 @@ static int ident_to_worktree(const char *path, const char *src, size_t len,
        return 1;
 }
 
+static const char *git_path_check_encoding(struct attr_check_item *check)
+{
+       const char *value = check->value;
+
+       if (ATTR_UNSET(value) || !strlen(value))
+               return NULL;
+
+       if (ATTR_TRUE(value) || ATTR_FALSE(value)) {
+               die(_("true/false are no valid working-tree-encodings"));
+       }
+
+       /* Don't encode to the default encoding */
+       if (same_encoding(value, default_encoding))
+               return NULL;
+
+       return value;
+}
+
 static enum crlf_action git_path_check_crlf(struct attr_check_item *check)
 {
        const char *value = check->value;
@@ -1033,6 +1287,7 @@ struct conv_attrs {
        enum crlf_action attr_action; /* What attr says */
        enum crlf_action crlf_action; /* When no attr is set, use core.autocrlf */
        int ident;
+       const char *working_tree_encoding; /* Supported encoding or default encoding if NULL */
 };
 
 static void convert_attrs(struct conv_attrs *ca, const char *path)
@@ -1041,7 +1296,8 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)
 
        if (!check) {
                check = attr_check_initl("crlf", "ident", "filter",
-                                        "eol", "text", NULL);
+                                        "eol", "text", "working-tree-encoding",
+                                        NULL);
                user_convert_tail = &user_convert;
                git_config(read_convert_config, NULL);
        }
@@ -1064,6 +1320,7 @@ static void convert_attrs(struct conv_attrs *ca, const char *path)
                        else if (eol_attr == EOL_CRLF)
                                ca->crlf_action = CRLF_TEXT_CRLF;
                }
+               ca->working_tree_encoding = git_path_check_encoding(ccheck + 5);
        } else {
                ca->drv = NULL;
                ca->crlf_action = CRLF_UNDEFINED;
@@ -1144,6 +1401,13 @@ int convert_to_git(const struct index_state *istate,
                src = dst->buf;
                len = dst->len;
        }
+
+       ret |= encode_to_git(path, src, len, dst, ca.working_tree_encoding, conv_flags);
+       if (ret && dst) {
+               src = dst->buf;
+               len = dst->len;
+       }
+
        if (!(conv_flags & CONV_EOL_KEEP_CRLF)) {
                ret |= crlf_to_git(istate, path, src, len, dst, ca.crlf_action, conv_flags);
                if (ret && dst) {
@@ -1167,6 +1431,7 @@ void convert_to_git_filter_fd(const struct index_state *istate,
        if (!apply_filter(path, NULL, 0, fd, dst, ca.drv, CAP_CLEAN, NULL))
                die("%s: clean filter '%s' failed", path, ca.drv->name);
 
+       encode_to_git(path, dst->buf, dst->len, dst, ca.working_tree_encoding, conv_flags);
        crlf_to_git(istate, path, dst->buf, dst->len, dst, ca.crlf_action, conv_flags);
        ident_to_git(path, dst->buf, dst->len, dst, ca.ident);
 }
@@ -1198,6 +1463,12 @@ static int convert_to_working_tree_internal(const char *path, const char *src,
                }
        }
 
+       ret |= encode_to_worktree(path, src, len, dst, ca.working_tree_encoding);
+       if (ret) {
+               src = dst->buf;
+               len = dst->len;
+       }
+
        ret_filter = apply_filter(
                path, src, len, -1, dst, ca.drv, CAP_SMUDGE, dco);
        if (!ret_filter && ca.drv && ca.drv->required)
@@ -1510,7 +1781,7 @@ struct ident_filter {
        struct stream_filter filter;
        struct strbuf left;
        int state;
-       char ident[45]; /* ": x40 $" */
+       char ident[GIT_MAX_HEXSZ + 5]; /* ": x40 $" */
 };
 
 static int is_foreign_ident(const char *str)
@@ -1635,12 +1906,12 @@ static struct stream_filter_vtbl ident_vtbl = {
        ident_free_fn,
 };
 
-static struct stream_filter *ident_filter(const unsigned char *sha1)
+static struct stream_filter *ident_filter(const struct object_id *oid)
 {
        struct ident_filter *ident = xmalloc(sizeof(*ident));
 
        xsnprintf(ident->ident, sizeof(ident->ident),
-                 ": %s $", sha1_to_hex(sha1));
+                 ": %s $", oid_to_hex(oid));
        strbuf_init(&ident->left, 0);
        ident->filter.vtbl = &ident_vtbl;
        ident->state = 0;
@@ -1655,7 +1926,7 @@ static struct stream_filter *ident_filter(const unsigned char *sha1)
  * Note that you would be crazy to set CRLF, smuge/clean or ident to a
  * large binary blob you would want us not to slurp into the memory!
  */
-struct stream_filter *get_stream_filter(const char *path, const unsigned char *sha1)
+struct stream_filter *get_stream_filter(const char *path, const struct object_id *oid)
 {
        struct conv_attrs ca;
        struct stream_filter *filter = NULL;
@@ -1664,11 +1935,14 @@ struct stream_filter *get_stream_filter(const char *path, const unsigned char *s
        if (ca.drv && (ca.drv->process || ca.drv->smudge || ca.drv->clean))
                return NULL;
 
+       if (ca.working_tree_encoding)
+               return NULL;
+
        if (ca.crlf_action == CRLF_AUTO || ca.crlf_action == CRLF_AUTO_CRLF)
                return NULL;
 
        if (ca.ident)
-               filter = ident_filter(sha1);
+               filter = ident_filter(oid);
 
        if (output_eol(ca.crlf_action) == EOL_CRLF)
                filter = cascade_filter(filter, lf_to_crlf_filter());
index 65ab3e516745775b52f36a370ba7880a34c8b2a5..01385d92886223ab7b1d951d12c5de9b07612401 100644 (file)
--- a/convert.h
+++ b/convert.h
@@ -12,6 +12,7 @@ struct index_state;
 #define CONV_EOL_RNDTRP_WARN  (1<<1) /* Warn if CRLF to LF to CRLF is different */
 #define CONV_EOL_RENORMALIZE  (1<<2) /* Convert CRLF to LF */
 #define CONV_EOL_KEEP_CRLF    (1<<3) /* Keep CRLF line endings as is */
+#define CONV_WRITE_OBJECT     (1<<4) /* Content is written to the index */
 
 extern int global_conv_flags_eol;
 
@@ -55,6 +56,7 @@ struct delayed_checkout {
 };
 
 extern enum eol core_eol;
+extern char *check_roundtrip_encoding;
 extern const char *get_cached_convert_stats_ascii(const struct index_state *istate,
                                                  const char *path);
 extern const char *get_wt_convert_stats_ascii(const char *path);
@@ -93,7 +95,7 @@ extern int would_convert_to_git_filter_fd(const char *path);
 
 struct stream_filter; /* opaque */
 
-extern struct stream_filter *get_stream_filter(const char *path, const unsigned char *);
+extern struct stream_filter *get_stream_filter(const char *path, const struct object_id *);
 extern void free_stream_filter(struct stream_filter *);
 extern int is_null_stream_filter(struct stream_filter *);
 
index 9747f47b18bf2e622f11f41889faaa4b1845ac8d..62be651b03b55ee4d478706e51ea8606b10739f0 100644 (file)
@@ -5,6 +5,7 @@
 #include "run-command.h"
 #include "url.h"
 #include "prompt.h"
+#include "sigchain.h"
 
 void credential_init(struct credential *c)
 {
@@ -227,8 +228,10 @@ static int run_credential_helper(struct credential *c,
                return -1;
 
        fp = xfdopen(helper.in, "w");
+       sigchain_push(SIGPIPE, SIG_IGN);
        credential_write(c, fp);
        fclose(fp);
+       sigchain_pop(SIGPIPE);
 
        if (want_output) {
                int r;
index 5eda7fb6af673ae82989dab871aaac74ec9ff629..53ce37f7ca42996dbfb4cf80e2127ea43496734d 100644 (file)
@@ -53,7 +53,7 @@ void hashflush(struct hashfile *f)
        }
 }
 
-int hashclose(struct hashfile *f, unsigned char *result, unsigned int flags)
+int finalize_hashfile(struct hashfile *f, unsigned char *result, unsigned int flags)
 {
        int fd;
 
@@ -61,11 +61,11 @@ int hashclose(struct hashfile *f, unsigned char *result, unsigned int flags)
        the_hash_algo->final_fn(f->buffer, &f->ctx);
        if (result)
                hashcpy(result, f->buffer);
-       if (flags & (CSUM_CLOSE | CSUM_FSYNC)) {
-               /* write checksum and close fd */
+       if (flags & CSUM_HASH_IN_STREAM)
                flush(f, f->buffer, the_hash_algo->rawsz);
-               if (flags & CSUM_FSYNC)
-                       fsync_or_die(f->fd, f->name);
+       if (flags & CSUM_FSYNC)
+               fsync_or_die(f->fd, f->name);
+       if (flags & CSUM_CLOSE) {
                if (close(f->fd))
                        die_errno("%s: sha1 file error on close", f->name);
                fd = 0;
index 992e5c014122d8fed3ee782d400e61de78e55271..c5a2e335e7e063528da8386cc95fba4f7bb5bfe8 100644 (file)
@@ -26,14 +26,15 @@ struct hashfile_checkpoint {
 extern void hashfile_checkpoint(struct hashfile *, struct hashfile_checkpoint *);
 extern int hashfile_truncate(struct hashfile *, struct hashfile_checkpoint *);
 
-/* hashclose flags */
-#define CSUM_CLOSE     1
-#define CSUM_FSYNC     2
+/* finalize_hashfile flags */
+#define CSUM_CLOSE             1
+#define CSUM_FSYNC             2
+#define CSUM_HASH_IN_STREAM    4
 
 extern struct hashfile *hashfd(int fd, const char *name);
 extern struct hashfile *hashfd_check(const char *name);
 extern struct hashfile *hashfd_throughput(int fd, const char *name, struct progress *tp);
-extern int hashclose(struct hashfile *, unsigned char *, unsigned int);
+extern int finalize_hashfile(struct hashfile *, unsigned char *, unsigned int);
 extern void hashwrite(struct hashfile *, const void *, unsigned int);
 extern void hashflush(struct hashfile *f);
 extern void crc32_begin(struct hashfile *);
index fe833ea7de7685968915c93950bb54768dd04586..9d2e0d20ef302aaeac02aaeba791509dd43a2712 100644 (file)
--- a/daemon.c
+++ b/daemon.c
@@ -1459,7 +1459,7 @@ int cmd_main(int argc, const char **argv)
                die("base-path '%s' does not exist or is not a directory",
                    base_path);
 
-       if (inetd_mode) {
+       if (log_destination != LOG_DESTINATION_STDERR) {
                if (!freopen("/dev/null", "w", stderr))
                        die_errno("failed to redirect stderr to /dev/null");
        }
diff --git a/date.c b/date.c
index c3e673fd04221bb444e357ac01a1fe5984375daf..49f943e25b5dc4f288963077f5eabaf24f651aab 100644 (file)
--- a/date.c
+++ b/date.c
@@ -185,7 +185,7 @@ struct date_mode *date_mode_from_type(enum date_mode_type type)
 {
        static struct date_mode mode;
        if (type == DATE_STRFTIME)
-               die("BUG: cannot create anonymous strftime date_mode struct");
+               BUG("cannot create anonymous strftime date_mode struct");
        mode.type = type;
        mode.local = 0;
        return &mode;
diff --git a/detect-compiler b/detect-compiler
new file mode 100755 (executable)
index 0000000..70b7544
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/sh
+#
+# Probe the compiler for vintage, version, etc. This is used for setting
+# optional make knobs under the DEVELOPER knob.
+
+CC="$*"
+
+# we get something like (this is at least true for gcc and clang)
+#
+# FreeBSD clang version 3.4.1 (tags/RELEASE...)
+get_version_line() {
+       $CC -v 2>&1 | grep ' version '
+}
+
+get_family() {
+       get_version_line | sed 's/^\(.*\) version [0-9][^ ]* .*/\1/'
+}
+
+get_version() {
+       get_version_line | sed 's/^.* version \([0-9][^ ]*\) .*/\1/'
+}
+
+print_flags() {
+       family=$1
+       version=$(get_version | cut -f 1 -d .)
+
+       # Print a feature flag not only for the current version, but also
+       # for any prior versions we encompass. This avoids needing to do
+       # numeric comparisons in make, which are awkward.
+       while test "$version" -gt 0
+       do
+               echo $family$version
+               version=$((version - 1))
+       done
+}
+
+case "$(get_family)" in
+gcc)
+       print_flags gcc
+       ;;
+clang)
+       print_flags clang
+       ;;
+"FreeBSD clang")
+       print_flags clang
+       ;;
+"Apple LLVM")
+       print_flags clang
+       ;;
+*)
+       : unknown compiler family
+       ;;
+esac
diff --git a/diff.c b/diff.c
index 4c59f5f5d3d32286daefbeeb25ed5291070fe762..136d44b45560d5c9db7e88a1ff22aa6b086108e8 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -177,7 +177,7 @@ static int parse_submodule_params(struct diff_options *options, const char *valu
        return 0;
 }
 
-static int git_config_rename(const char *var, const char *value)
+int git_config_rename(const char *var, const char *value)
 {
        if (!value)
                return DIFF_DETECT_RENAME;
@@ -1184,7 +1184,7 @@ static void emit_diff_symbol_from_struct(struct diff_options *o,
                fputs(o->stat_sep, o->file);
                break;
        default:
-               die("BUG: unknown diff symbol");
+               BUG("unknown diff symbol");
        }
        strbuf_release(&sb);
 }
@@ -1343,7 +1343,7 @@ static struct diff_tempfile *claim_diff_tempfile(void) {
        for (i = 0; i < ARRAY_SIZE(diff_temp); i++)
                if (!diff_temp[i].name)
                        return diff_temp + i;
-       die("BUG: diff is failing to clean up its tempfiles");
+       BUG("diff is failing to clean up its tempfiles");
 }
 
 static void remove_tempfile(void)
@@ -3472,7 +3472,7 @@ static int reuse_worktree_file(const char *name, const struct object_id *oid, in
         * objects however would tend to be slower as they need
         * to be individually opened and inflated.
         */
-       if (!FAST_WORKING_DIRECTORY && !want_file && has_sha1_pack(oid->hash))
+       if (!FAST_WORKING_DIRECTORY && !want_file && has_object_pack(oid))
                return 0;
 
        /*
@@ -3638,7 +3638,8 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
        else {
                enum object_type type;
                if (size_only || (flags & CHECK_BINARY)) {
-                       type = sha1_object_info(s->oid.hash, &s->size);
+                       type = oid_object_info(the_repository, &s->oid,
+                                              &s->size);
                        if (type < 0)
                                die("unable to read %s",
                                    oid_to_hex(&s->oid));
@@ -3649,7 +3650,7 @@ int diff_populate_filespec(struct diff_filespec *s, unsigned int flags)
                                return 0;
                        }
                }
-               s->data = read_sha1_file(s->oid.hash, &type, &s->size);
+               s->data = read_object_file(&s->oid, &type, &s->size);
                if (!s->data)
                        die("unable to read %s", oid_to_hex(&s->oid));
                s->should_free = 1;
@@ -3834,13 +3835,13 @@ static int similarity_index(struct diff_filepair *p)
 static const char *diff_abbrev_oid(const struct object_id *oid, int abbrev)
 {
        if (startup_info->have_repository)
-               return find_unique_abbrev(oid->hash, abbrev);
+               return find_unique_abbrev(oid, abbrev);
        else {
                char *hex = oid_to_hex(oid);
                if (abbrev < 0)
                        abbrev = FALLBACK_DEFAULT_ABBREV;
                if (abbrev > GIT_SHA1_HEXSZ)
-                       die("BUG: oid abbreviation out of range: %d", abbrev);
+                       BUG("oid abbreviation out of range: %d", abbrev);
                if (abbrev)
                        hex[abbrev] = '\0';
                return hex;
@@ -3897,13 +3898,14 @@ static void fill_metainfo(struct strbuf *msg,
                *must_show_header = 0;
        }
        if (one && two && oidcmp(&one->oid, &two->oid)) {
-               int abbrev = o->flags.full_index ? 40 : DEFAULT_ABBREV;
+               const unsigned hexsz = the_hash_algo->hexsz;
+               int abbrev = o->flags.full_index ? hexsz : DEFAULT_ABBREV;
 
                if (o->flags.binary) {
                        mmfile_t mf;
                        if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) ||
                            (!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
-                               abbrev = 40;
+                               abbrev = hexsz;
                }
                strbuf_addf(msg, "%s%sindex %s..%s", line_prefix, set,
                            diff_abbrev_oid(&one->oid, abbrev),
@@ -4138,6 +4140,11 @@ void diff_setup_done(struct diff_options *options)
                              DIFF_FORMAT_NAME_STATUS |
                              DIFF_FORMAT_CHECKDIFF |
                              DIFF_FORMAT_NO_OUTPUT;
+       /*
+        * This must be signed because we're comparing against a potentially
+        * negative value.
+        */
+       const int hexsz = the_hash_algo->hexsz;
 
        if (options->set_default)
                options->set_default(options);
@@ -4218,8 +4225,8 @@ void diff_setup_done(struct diff_options *options)
                         */
                        read_cache();
        }
-       if (40 < options->abbrev)
-               options->abbrev = 40; /* full */
+       if (hexsz < options->abbrev)
+               options->abbrev = hexsz; /* full */
 
        /*
         * It does not make sense to show the first hit we happened
@@ -4334,7 +4341,7 @@ static int stat_opt(struct diff_options *options, const char **av)
        int argcount = 1;
 
        if (!skip_prefix(arg, "--stat", &arg))
-               die("BUG: stat option does not begin with --stat: %s", arg);
+               BUG("stat option does not begin with --stat: %s", arg);
        end = (char *)arg;
 
        switch (*arg) {
@@ -4797,8 +4804,8 @@ int diff_opt_parse(struct diff_options *options,
                options->abbrev = strtoul(arg, NULL, 10);
                if (options->abbrev < MINIMUM_ABBREV)
                        options->abbrev = MINIMUM_ABBREV;
-               else if (40 < options->abbrev)
-                       options->abbrev = 40;
+               else if (the_hash_algo->hexsz < options->abbrev)
+                       options->abbrev = the_hash_algo->hexsz;
        }
        else if ((argcount = parse_long_opt("src-prefix", av, &optarg))) {
                options->a_prefix = optarg;
@@ -5519,7 +5526,7 @@ static void diff_flush_patch_all_file_pairs(struct diff_options *o)
        struct diff_queue_struct *q = &diff_queued_diff;
 
        if (WSEH_NEW & WS_RULE_MASK)
-               die("BUG: WS rules bit mask overlaps with diff symbol flags");
+               BUG("WS rules bit mask overlaps with diff symbol flags");
 
        if (o->color_moved)
                o->emitted_symbols = &esm;
@@ -6053,7 +6060,7 @@ size_t fill_textconv(struct userdiff_driver *driver,
        }
 
        if (!driver->textconv)
-               die("BUG: fill_textconv called with non-textconv driver");
+               BUG("fill_textconv called with non-textconv driver");
 
        if (driver->textconv_cache && df->oid_valid) {
                *outbuf = notes_cache_get(driver->textconv_cache,
diff --git a/diff.h b/diff.h
index d29560f822ca0ee4738f769e2feb3939851d7ff1..dedac472ca5959bb5ff17888a54042ac75678631 100644 (file)
--- a/diff.h
+++ b/diff.h
@@ -324,6 +324,7 @@ extern int git_diff_ui_config(const char *var, const char *value, void *cb);
 extern void diff_setup(struct diff_options *);
 extern int diff_opt_parse(struct diff_options *, const char **, int, const char *);
 extern void diff_setup_done(struct diff_options *);
+extern int git_config_rename(const char *var, const char *value);
 
 #define DIFF_DETECT_RENAME     1
 #define DIFF_DETECT_COPY       2
index 239ce5122b3a45bec211e0c20113385c0e37805d..800a899c8621eaeba7f4246139df0f289ceb6ee2 100644 (file)
@@ -215,7 +215,6 @@ static void regcomp_or_die(regex_t *regex, const char *needle, int cflags)
                /* The POSIX.2 people are surely sick */
                char errbuf[1024];
                regerror(err, regex, errbuf, 1024);
-               regfree(regex);
                die("invalid regex: %s", errbuf);
        }
 }
index 34182a9a1c10244126e03a2b117bd8bc75bd9871..f2dcd82fde9723be1e53770ad25af42ec547869a 100644 (file)
@@ -188,7 +188,7 @@ struct dir_iterator *dir_iterator_begin(const char *path)
        struct dir_iterator *dir_iterator = &iter->base;
 
        if (!path || !*path)
-               die("BUG: empty path passed to dir_iterator_begin()");
+               BUG("empty path passed to dir_iterator_begin()");
 
        strbuf_init(&iter->base.path, PATH_MAX);
        strbuf_addstr(&iter->base.path, path);
diff --git a/dir.c b/dir.c
index 41aac3b7b38e76bb790da4c21c362d7d0f1d1a07..fe9bf58e4c72790dca5492de4bd98df06798d27a 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -19,6 +19,7 @@
 #include "varint.h"
 #include "ewah/ewok.h"
 #include "fsmonitor.h"
+#include "submodule-config.h"
 
 /*
  * Tells read_directory_recursive how a file or directory should be treated.
@@ -243,7 +244,7 @@ static int do_read_blob(const struct object_id *oid, struct oid_stat *oid_stat,
        *size_out = 0;
        *data_out = NULL;
 
-       data = read_sha1_file(oid->hash, &type, &sz);
+       data = read_object_file(oid, &type, &sz);
        if (!data || type != OBJ_BLOB) {
                free(data);
                return -1;
@@ -828,7 +829,7 @@ static int add_excludes(const char *fname, const char *base, int baselen,
                if (size == 0) {
                        if (oid_stat) {
                                fill_stat_data(&oid_stat->stat, &st);
-                               oidcpy(&oid_stat->oid, &empty_blob_oid);
+                               oidcpy(&oid_stat->oid, the_hash_algo->empty_blob);
                                oid_stat->valid = 1;
                        }
                        close(fd);
@@ -1240,11 +1241,11 @@ static void prep_exclude(struct dir_struct *dir,
                    (!untracked || !untracked->valid ||
                     /*
                      * .. and .gitignore does not exist before
-                     * (i.e. null exclude_sha1). Then we can skip
+                     * (i.e. null exclude_oid). Then we can skip
                      * loading .gitignore, which would result in
                      * ENOENT anyway.
                      */
-                    !is_null_sha1(untracked->exclude_sha1))) {
+                    !is_null_oid(&untracked->exclude_oid))) {
                        /*
                         * dir->basebuf gets reused by the traversal, but we
                         * need fname to remain unchanged to ensure the src
@@ -1275,9 +1276,9 @@ static void prep_exclude(struct dir_struct *dir,
                 * order, though, if you do that.
                 */
                if (untracked &&
-                   hashcmp(oid_stat.oid.hash, untracked->exclude_sha1)) {
+                   oidcmp(&oid_stat.oid, &untracked->exclude_oid)) {
                        invalidate_gitignore(dir->untracked, untracked);
-                       hashcpy(untracked->exclude_sha1, oid_stat.oid.hash);
+                       oidcpy(&untracked->exclude_oid, &oid_stat.oid);
                }
                dir->exclude_stack = stk;
                current = stk->baselen;
@@ -2622,9 +2623,10 @@ static void write_one_dir(struct untracked_cache_dir *untracked,
                stat_data_to_disk(&stat_data, &untracked->stat_data);
                strbuf_add(&wd->sb_stat, &stat_data, sizeof(stat_data));
        }
-       if (!is_null_sha1(untracked->exclude_sha1)) {
+       if (!is_null_oid(&untracked->exclude_oid)) {
                ewah_set(wd->sha1_valid, i);
-               strbuf_add(&wd->sb_sha1, untracked->exclude_sha1, 20);
+               strbuf_add(&wd->sb_sha1, untracked->exclude_oid.hash,
+                          the_hash_algo->rawsz);
        }
 
        intlen = encode_varint(untracked->untracked_nr, intbuf);
@@ -2825,16 +2827,16 @@ static void read_stat(size_t pos, void *cb)
        ud->valid = 1;
 }
 
-static void read_sha1(size_t pos, void *cb)
+static void read_oid(size_t pos, void *cb)
 {
        struct read_data *rd = cb;
        struct untracked_cache_dir *ud = rd->ucd[pos];
-       if (rd->data + 20 > rd->end) {
+       if (rd->data + the_hash_algo->rawsz > rd->end) {
                rd->data = rd->end + 1;
                return;
        }
-       hashcpy(ud->exclude_sha1, rd->data);
-       rd->data += 20;
+       hashcpy(ud->exclude_oid.hash, rd->data);
+       rd->data += the_hash_algo->rawsz;
 }
 
 static void load_oid_stat(struct oid_stat *oid_stat, const unsigned char *data,
@@ -2851,7 +2853,8 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
        struct read_data rd;
        const unsigned char *next = data, *end = (const unsigned char *)data + sz;
        const char *ident;
-       int ident_len, len;
+       int ident_len;
+       ssize_t len;
        const char *exclude_per_dir;
 
        if (sz <= 1 || end[-1] != '\0')
@@ -2917,7 +2920,7 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
        ewah_each_bit(rd.check_only, set_check_only, &rd);
        rd.data = next + len;
        ewah_each_bit(rd.valid, read_stat, &rd);
-       ewah_each_bit(rd.sha1_valid, read_sha1, &rd);
+       ewah_each_bit(rd.sha1_valid, read_oid, &rd);
        next = rd.data;
 
 done:
@@ -3010,8 +3013,57 @@ void untracked_cache_add_to_index(struct index_state *istate,
        untracked_cache_invalidate_path(istate, path, 1);
 }
 
-/* Update gitfile and core.worktree setting to connect work tree and git dir */
-void connect_work_tree_and_git_dir(const char *work_tree_, const char *git_dir_)
+static void connect_wt_gitdir_in_nested(const char *sub_worktree,
+                                       const char *sub_gitdir)
+{
+       int i;
+       struct repository subrepo;
+       struct strbuf sub_wt = STRBUF_INIT;
+       struct strbuf sub_gd = STRBUF_INIT;
+
+       const struct submodule *sub;
+
+       /* If the submodule has no working tree, we can ignore it. */
+       if (repo_init(&subrepo, sub_gitdir, sub_worktree))
+               return;
+
+       if (repo_read_index(&subrepo) < 0)
+               die("index file corrupt in repo %s", subrepo.gitdir);
+
+       for (i = 0; i < subrepo.index->cache_nr; i++) {
+               const struct cache_entry *ce = subrepo.index->cache[i];
+
+               if (!S_ISGITLINK(ce->ce_mode))
+                       continue;
+
+               while (i + 1 < subrepo.index->cache_nr &&
+                      !strcmp(ce->name, subrepo.index->cache[i + 1]->name))
+                       /*
+                        * Skip entries with the same name in different stages
+                        * to make sure an entry is returned only once.
+                        */
+                       i++;
+
+               sub = submodule_from_path(&subrepo, &null_oid, ce->name);
+               if (!sub || !is_submodule_active(&subrepo, ce->name))
+                       /* .gitmodules broken or inactive sub */
+                       continue;
+
+               strbuf_reset(&sub_wt);
+               strbuf_reset(&sub_gd);
+               strbuf_addf(&sub_wt, "%s/%s", sub_worktree, sub->path);
+               strbuf_addf(&sub_gd, "%s/modules/%s", sub_gitdir, sub->name);
+
+               connect_work_tree_and_git_dir(sub_wt.buf, sub_gd.buf, 1);
+       }
+       strbuf_release(&sub_wt);
+       strbuf_release(&sub_gd);
+       repo_clear(&subrepo);
+}
+
+void connect_work_tree_and_git_dir(const char *work_tree_,
+                                  const char *git_dir_,
+                                  int recurse_into_nested)
 {
        struct strbuf gitfile_sb = STRBUF_INIT;
        struct strbuf cfg_sb = STRBUF_INIT;
@@ -3041,6 +3093,10 @@ void connect_work_tree_and_git_dir(const char *work_tree_, const char *git_dir_)
        strbuf_release(&gitfile_sb);
        strbuf_release(&cfg_sb);
        strbuf_release(&rel_path);
+
+       if (recurse_into_nested)
+               connect_wt_gitdir_in_nested(work_tree, git_dir);
+
        free(work_tree);
        free(git_dir);
 }
@@ -3054,5 +3110,5 @@ void relocate_gitdir(const char *path, const char *old_git_dir, const char *new_
                die_errno(_("could not migrate git directory from '%s' to '%s'"),
                        old_git_dir, new_git_dir);
 
-       connect_work_tree_and_git_dir(path, new_git_dir);
+       connect_work_tree_and_git_dir(path, new_git_dir, 0);
 }
diff --git a/dir.h b/dir.h
index b0758b82a20017dd3ce29c54454678f026718078..f5fdedbab2520547f8de2e7c827f5f9c85c932ac 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -3,6 +3,7 @@
 
 /* See Documentation/technical/api-directory-listing.txt */
 
+#include "cache.h"
 #include "strbuf.h"
 
 struct dir_entry {
@@ -118,8 +119,8 @@ struct untracked_cache_dir {
        /* all data except 'dirs' in this struct are good */
        unsigned int valid : 1;
        unsigned int recurse : 1;
-       /* null SHA-1 means this directory does not have .gitignore */
-       unsigned char exclude_sha1[20];
+       /* null object ID means this directory does not have .gitignore */
+       struct object_id exclude_oid;
        char name[FLEX_ARRAY];
 };
 
@@ -359,7 +360,17 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
 void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked);
 void add_untracked_cache(struct index_state *istate);
 void remove_untracked_cache(struct index_state *istate);
-extern void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir);
+
+/*
+ * Connect a worktree to a git directory by creating (or overwriting) a
+ * '.git' file containing the location of the git directory. In the git
+ * directory set the core.worktree setting to indicate where the worktree is.
+ * When `recurse_into_nested` is set, recurse into any nested submodules,
+ * connecting them as well.
+ */
+extern void connect_work_tree_and_git_dir(const char *work_tree,
+                                         const char *git_dir,
+                                         int recurse_into_nested);
 extern void relocate_gitdir(const char *path,
                            const char *old_git_dir,
                            const char *new_git_dir);
diff --git a/entry.c b/entry.c
index 6c33112aea7dc8e584678bcb5e5ea292d29265a9..2101201a111785f449a65e785e9ed5b57b7aa196 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -85,7 +85,7 @@ static int create_file(const char *path, unsigned int mode)
 static void *read_blob_entry(const struct cache_entry *ce, unsigned long *size)
 {
        enum object_type type;
-       void *blob_data = read_sha1_file(ce->oid.hash, &type, size);
+       void *blob_data = read_object_file(&ce->oid, &type, size);
 
        if (blob_data) {
                if (type == OBJ_BLOB)
@@ -266,7 +266,7 @@ static int write_entry(struct cache_entry *ce,
 
        if (ce_mode_s_ifmt == S_IFREG) {
                struct stream_filter *filter = get_stream_filter(ce->name,
-                                                                ce->oid.hash);
+                                                                &ce->oid);
                if (filter &&
                    !streaming_write_entry(ce, path, filter,
                                           state, to_tempfile,
index af8e07f551e6870600bb3f6b1ccb36d777f22b12..8964b407a9880771e7cb386a1c7f6089756d5551 100644 (file)
@@ -13,6 +13,9 @@
 #include "refs.h"
 #include "fmt-merge-msg.h"
 #include "commit.h"
+#include "argv-array.h"
+#include "object-store.h"
+#include "chdir-notify.h"
 
 int trust_executable_bit = 1;
 int trust_ctime = 1;
@@ -48,10 +51,11 @@ const char *editor_program;
 const char *askpass_program;
 const char *excludes_file;
 enum auto_crlf auto_crlf = AUTO_CRLF_FALSE;
-int check_replace_refs = 1;
+int check_replace_refs = 1; /* NEEDSWORK: rename to read_replace_refs */
 char *git_replace_ref_base;
 enum eol core_eol = EOL_UNSET;
 int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN;
+char *check_roundtrip_encoding = "SHIFT-JIS";
 unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
 enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
 enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
@@ -62,6 +66,7 @@ enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
 enum object_creation_mode object_creation_mode = OBJECT_CREATION_MODE;
 char *notes_ref_name;
 int grafts_replace_parents = 1;
+int core_commit_graph;
 int core_apply_sparse_checkout;
 int merge_log_config = -1;
 int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */
@@ -147,10 +152,35 @@ static char *expand_namespace(const char *raw_namespace)
        return strbuf_detach(&buf, NULL);
 }
 
-void setup_git_env(void)
+/*
+ * Wrapper of getenv() that returns a strdup value. This value is kept
+ * in argv to be freed later.
+ */
+static const char *getenv_safe(struct argv_array *argv, const char *name)
+{
+       const char *value = getenv(name);
+
+       if (!value)
+               return NULL;
+
+       argv_array_push(argv, value);
+       return argv->argv[argv->argc - 1];
+}
+
+void setup_git_env(const char *git_dir)
 {
        const char *shallow_file;
        const char *replace_ref_base;
+       struct set_gitdir_args args = { NULL };
+       struct argv_array to_free = ARGV_ARRAY_INIT;
+
+       args.commondir = getenv_safe(&to_free, GIT_COMMON_DIR_ENVIRONMENT);
+       args.object_dir = getenv_safe(&to_free, DB_ENVIRONMENT);
+       args.graft_file = getenv_safe(&to_free, GRAFT_ENVIRONMENT);
+       args.index_file = getenv_safe(&to_free, INDEX_ENVIRONMENT);
+       args.alternate_db = getenv_safe(&to_free, ALTERNATE_DB_ENVIRONMENT);
+       repo_set_gitdir(the_repository, git_dir, &args);
+       argv_array_clear(&to_free);
 
        if (getenv(NO_REPLACE_OBJECTS_ENVIRONMENT))
                check_replace_refs = 0;
@@ -244,9 +274,9 @@ const char *get_git_work_tree(void)
 
 char *get_object_directory(void)
 {
-       if (!the_repository->objectdir)
+       if (!the_repository->objects->objectdir)
                BUG("git environment hasn't been setup");
-       return the_repository->objectdir;
+       return the_repository->objects->objectdir;
 }
 
 int odb_mkstemp(struct strbuf *temp_filename, const char *pattern)
@@ -296,13 +326,31 @@ char *get_graft_file(void)
        return the_repository->graft_file;
 }
 
-int set_git_dir(const char *path)
+static void set_git_dir_1(const char *path)
 {
        if (setenv(GIT_DIR_ENVIRONMENT, path, 1))
-               return error("Could not set GIT_DIR to '%s'", path);
-       repo_set_gitdir(the_repository, path);
-       setup_git_env();
-       return 0;
+               die("could not set GIT_DIR to '%s'", path);
+       setup_git_env(path);
+}
+
+static void update_relative_gitdir(const char *name,
+                                  const char *old_cwd,
+                                  const char *new_cwd,
+                                  void *data)
+{
+       char *path = reparent_relative_path(old_cwd, new_cwd, get_git_dir());
+       trace_printf_key(&trace_setup_key,
+                        "setup: move $GIT_DIR to '%s'",
+                        path);
+       set_git_dir_1(path);
+       free(path);
+}
+
+void set_git_dir(const char *path)
+{
+       set_git_dir_1(path);
+       if (!is_absolute_path(path))
+               chdir_notify_register(NULL, update_relative_gitdir, NULL);
 }
 
 const char *get_log_output_encoding(void)
index bed1994551cd03532fe56913b0e27343834c805f..33c08c40f896f32d9a1c251c1456755e949d91bd 100644 (file)
@@ -122,16 +122,23 @@ int ewah_serialize_strbuf(struct ewah_bitmap *self, struct strbuf *sb)
        return ewah_serialize_to(self, write_strbuf, sb);
 }
 
-int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len)
+ssize_t ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len)
 {
        const uint8_t *ptr = map;
+       size_t data_len;
        size_t i;
 
+       if (len < sizeof(uint32_t))
+               return error("corrupt ewah bitmap: eof before bit size");
        self->bit_size = get_be32(ptr);
        ptr += sizeof(uint32_t);
+       len -= sizeof(uint32_t);
 
+       if (len < sizeof(uint32_t))
+               return error("corrupt ewah bitmap: eof before length");
        self->buffer_size = self->alloc_size = get_be32(ptr);
        ptr += sizeof(uint32_t);
+       len -= sizeof(uint32_t);
 
        REALLOC_ARRAY(self->buffer, self->alloc_size);
 
@@ -141,15 +148,25 @@ int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len)
         * the endianness conversion in a separate pass to ensure
         * we're loading 8-byte aligned words.
         */
-       memcpy(self->buffer, ptr, self->buffer_size * sizeof(eword_t));
-       ptr += self->buffer_size * sizeof(eword_t);
+       data_len = st_mult(self->buffer_size, sizeof(eword_t));
+       if (len < data_len)
+               return error("corrupt ewah bitmap: eof in data "
+                            "(%"PRIuMAX" bytes short)",
+                            (uintmax_t)(data_len - len));
+       memcpy(self->buffer, ptr, data_len);
+       ptr += data_len;
+       len -= data_len;
 
        for (i = 0; i < self->buffer_size; ++i)
                self->buffer[i] = ntohll(self->buffer[i]);
 
+       if (len < sizeof(uint32_t))
+               return error("corrupt ewah bitmap: eof before rlw");
        self->rlw = self->buffer + get_be32(ptr);
+       ptr += sizeof(uint32_t);
+       len -= sizeof(uint32_t);
 
-       return (3 * 4) + (self->buffer_size * 8);
+       return ptr - (const uint8_t *)map;
 }
 
 int ewah_deserialize(struct ewah_bitmap *self, int fd)
index dc43d05b644af07a86bb64dbc6790ea0897d2f43..357fd93c84edbe79f9bcb10e2947ed935ac9f0df 100644 (file)
@@ -91,7 +91,7 @@ int ewah_serialize_native(struct ewah_bitmap *self, int fd);
 int ewah_serialize_strbuf(struct ewah_bitmap *self, struct strbuf *);
 
 int ewah_deserialize(struct ewah_bitmap *self, int fd);
-int ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len);
+ssize_t ewah_read_mmap(struct ewah_bitmap *self, const void *map, size_t len);
 
 uint32_t ewah_checksum(struct ewah_bitmap *self);
 
diff --git a/exec-cmd.c b/exec-cmd.c
new file mode 100644 (file)
index 0000000..02d31ee
--- /dev/null
@@ -0,0 +1,365 @@
+#include "cache.h"
+#include "exec-cmd.h"
+#include "quote.h"
+#include "argv-array.h"
+
+#if defined(RUNTIME_PREFIX)
+
+#if defined(HAVE_NS_GET_EXECUTABLE_PATH)
+#include <mach-o/dyld.h>
+#endif
+
+#if defined(HAVE_BSD_KERN_PROC_SYSCTL)
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+
+#endif /* RUNTIME_PREFIX */
+
+#define MAX_ARGS 32
+
+static const char *system_prefix(void);
+
+#ifdef RUNTIME_PREFIX
+
+/**
+ * When using a runtime prefix, Git dynamically resolves paths relative to its
+ * executable.
+ *
+ * The method for determining the path of the executable is highly
+ * platform-specific.
+ */
+
+/**
+ * Path to the current Git executable. Resolved on startup by
+ * 'git_resolve_executable_dir'.
+ */
+static const char *executable_dirname;
+
+static const char *system_prefix(void)
+{
+       static const char *prefix;
+
+       assert(executable_dirname);
+       assert(is_absolute_path(executable_dirname));
+
+       if (!prefix &&
+           !(prefix = strip_path_suffix(executable_dirname, GIT_EXEC_PATH)) &&
+           !(prefix = strip_path_suffix(executable_dirname, BINDIR)) &&
+           !(prefix = strip_path_suffix(executable_dirname, "git"))) {
+               prefix = FALLBACK_RUNTIME_PREFIX;
+               trace_printf("RUNTIME_PREFIX requested, "
+                               "but prefix computation failed.  "
+                               "Using static fallback '%s'.\n", prefix);
+       }
+       return prefix;
+}
+
+/*
+ * Resolves the executable path from argv[0], only if it is absolute.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int git_get_exec_path_from_argv0(struct strbuf *buf, const char *argv0)
+{
+       const char *slash;
+
+       if (!argv0 || !*argv0)
+               return -1;
+
+       slash = find_last_dir_sep(argv0);
+       if (slash) {
+               trace_printf("trace: resolved executable path from argv0: %s\n",
+                            argv0);
+               strbuf_add_absolute_path(buf, argv0);
+               return 0;
+       }
+       return -1;
+}
+
+#ifdef PROCFS_EXECUTABLE_PATH
+/*
+ * Resolves the executable path by examining a procfs symlink.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int git_get_exec_path_procfs(struct strbuf *buf)
+{
+       if (strbuf_realpath(buf, PROCFS_EXECUTABLE_PATH, 0)) {
+               trace_printf(
+                       "trace: resolved executable path from procfs: %s\n",
+                       buf->buf);
+               return 0;
+       }
+       return -1;
+}
+#endif /* PROCFS_EXECUTABLE_PATH */
+
+#ifdef HAVE_BSD_KERN_PROC_SYSCTL
+/*
+ * Resolves the executable path using KERN_PROC_PATHNAME BSD sysctl.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int git_get_exec_path_bsd_sysctl(struct strbuf *buf)
+{
+       int mib[4];
+       char path[MAXPATHLEN];
+       size_t cb = sizeof(path);
+
+       mib[0] = CTL_KERN;
+       mib[1] = KERN_PROC;
+       mib[2] = KERN_PROC_PATHNAME;
+       mib[3] = -1;
+       if (!sysctl(mib, 4, path, &cb, NULL, 0)) {
+               trace_printf(
+                       "trace: resolved executable path from sysctl: %s\n",
+                       path);
+               strbuf_addstr(buf, path);
+               return 0;
+       }
+       return -1;
+}
+#endif /* HAVE_BSD_KERN_PROC_SYSCTL */
+
+#ifdef HAVE_NS_GET_EXECUTABLE_PATH
+/*
+ * Resolves the executable path by querying Darwin application stack.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int git_get_exec_path_darwin(struct strbuf *buf)
+{
+       char path[PATH_MAX];
+       uint32_t size = sizeof(path);
+       if (!_NSGetExecutablePath(path, &size)) {
+               trace_printf(
+                       "trace: resolved executable path from Darwin stack: %s\n",
+                       path);
+               strbuf_addstr(buf, path);
+               return 0;
+       }
+       return -1;
+}
+#endif /* HAVE_NS_GET_EXECUTABLE_PATH */
+
+#ifdef HAVE_WPGMPTR
+/*
+ * Resolves the executable path by using the global variable _wpgmptr.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int git_get_exec_path_wpgmptr(struct strbuf *buf)
+{
+       int len = wcslen(_wpgmptr) * 3 + 1;
+       strbuf_grow(buf, len);
+       len = xwcstoutf(buf->buf, _wpgmptr, len);
+       if (len < 0)
+               return -1;
+       buf->len += len;
+       return 0;
+}
+#endif /* HAVE_WPGMPTR */
+
+/*
+ * Resolves the absolute path of the current executable.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int git_get_exec_path(struct strbuf *buf, const char *argv0)
+{
+       /*
+        * Identifying the executable path is operating system specific.
+        * Selectively employ all available methods in order of preference,
+        * preferring highly-available authoritative methods over
+        * selectively-available or non-authoritative methods.
+        *
+        * All cases fall back on resolving against argv[0] if there isn't a
+        * better functional method. However, note that argv[0] can be
+        * used-supplied on many operating systems, and is not authoritative
+        * in those cases.
+        *
+        * Each of these functions returns 0 on success, so evaluation will stop
+        * after the first successful method.
+        */
+       if (
+#ifdef HAVE_BSD_KERN_PROC_SYSCTL
+               git_get_exec_path_bsd_sysctl(buf) &&
+#endif /* HAVE_BSD_KERN_PROC_SYSCTL */
+
+#ifdef HAVE_NS_GET_EXECUTABLE_PATH
+               git_get_exec_path_darwin(buf) &&
+#endif /* HAVE_NS_GET_EXECUTABLE_PATH */
+
+#ifdef PROCFS_EXECUTABLE_PATH
+               git_get_exec_path_procfs(buf) &&
+#endif /* PROCFS_EXECUTABLE_PATH */
+
+#ifdef HAVE_WPGMPTR
+               git_get_exec_path_wpgmptr(buf) &&
+#endif /* HAVE_WPGMPTR */
+
+               git_get_exec_path_from_argv0(buf, argv0)) {
+               return -1;
+       }
+
+       if (strbuf_normalize_path(buf)) {
+               trace_printf("trace: could not normalize path: %s\n", buf->buf);
+               return -1;
+       }
+
+       return 0;
+}
+
+void git_resolve_executable_dir(const char *argv0)
+{
+       struct strbuf buf = STRBUF_INIT;
+       char *resolved;
+       const char *slash;
+
+       if (git_get_exec_path(&buf, argv0)) {
+               trace_printf(
+                       "trace: could not determine executable path from: %s\n",
+                       argv0);
+               strbuf_release(&buf);
+               return;
+       }
+
+       resolved = strbuf_detach(&buf, NULL);
+       slash = find_last_dir_sep(resolved);
+       if (slash)
+               resolved[slash - resolved] = '\0';
+
+       executable_dirname = resolved;
+       trace_printf("trace: resolved executable dir: %s\n",
+                    executable_dirname);
+}
+
+#else
+
+/*
+ * When not using a runtime prefix, Git uses a hard-coded path.
+ */
+static const char *system_prefix(void)
+{
+       return FALLBACK_RUNTIME_PREFIX;
+}
+
+/*
+ * This is called during initialization, but No work needs to be done here when
+ * runtime prefix is not being used.
+ */
+void git_resolve_executable_dir(const char *argv0)
+{
+}
+
+#endif /* RUNTIME_PREFIX */
+
+char *system_path(const char *path)
+{
+       struct strbuf d = STRBUF_INIT;
+
+       if (is_absolute_path(path))
+               return xstrdup(path);
+
+       strbuf_addf(&d, "%s/%s", system_prefix(), path);
+       return strbuf_detach(&d, NULL);
+}
+
+static const char *exec_path_value;
+
+void git_set_exec_path(const char *exec_path)
+{
+       exec_path_value = exec_path;
+       /*
+        * Propagate this setting to external programs.
+        */
+       setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);
+}
+
+/* Returns the highest-priority location to look for git programs. */
+const char *git_exec_path(void)
+{
+       if (!exec_path_value) {
+               const char *env = getenv(EXEC_PATH_ENVIRONMENT);
+               if (env && *env)
+                       exec_path_value = xstrdup(env);
+               else
+                       exec_path_value = system_path(GIT_EXEC_PATH);
+       }
+       return exec_path_value;
+}
+
+static void add_path(struct strbuf *out, const char *path)
+{
+       if (path && *path) {
+               strbuf_add_absolute_path(out, path);
+               strbuf_addch(out, PATH_SEP);
+       }
+}
+
+void setup_path(void)
+{
+       const char *exec_path = git_exec_path();
+       const char *old_path = getenv("PATH");
+       struct strbuf new_path = STRBUF_INIT;
+
+       git_set_exec_path(exec_path);
+       add_path(&new_path, exec_path);
+
+       if (old_path)
+               strbuf_addstr(&new_path, old_path);
+       else
+               strbuf_addstr(&new_path, _PATH_DEFPATH);
+
+       setenv("PATH", new_path.buf, 1);
+
+       strbuf_release(&new_path);
+}
+
+const char **prepare_git_cmd(struct argv_array *out, const char **argv)
+{
+       argv_array_push(out, "git");
+       argv_array_pushv(out, argv);
+       return out->argv;
+}
+
+int execv_git_cmd(const char **argv)
+{
+       struct argv_array nargv = ARGV_ARRAY_INIT;
+
+       prepare_git_cmd(&nargv, argv);
+       trace_argv_printf(nargv.argv, "trace: exec:");
+
+       /* execvp() can only ever return if it fails */
+       sane_execvp("git", (char **)nargv.argv);
+
+       trace_printf("trace: exec failed: %s\n", strerror(errno));
+
+       argv_array_clear(&nargv);
+       return -1;
+}
+
+int execl_git_cmd(const char *cmd, ...)
+{
+       int argc;
+       const char *argv[MAX_ARGS + 1];
+       const char *arg;
+       va_list param;
+
+       va_start(param, cmd);
+       argv[0] = cmd;
+       argc = 1;
+       while (argc < MAX_ARGS) {
+               arg = argv[argc++] = va_arg(param, char *);
+               if (!arg)
+                       break;
+       }
+       va_end(param);
+       if (MAX_ARGS <= argc)
+               return error("too many args to run %s", cmd);
+
+       argv[argc] = NULL;
+       return execv_git_cmd(argv);
+}
similarity index 79%
rename from exec_cmd.h
rename to exec-cmd.h
index ff0b48048a6ba82827b4d441654c34c21cfb7b9a..2522453cdaa74d9e9d806f20036518a394dd32e2 100644 (file)
@@ -3,8 +3,8 @@
 
 struct argv_array;
 
-extern void git_set_argv_exec_path(const char *exec_path);
-extern void git_extract_argv0_path(const char *path);
+extern void git_set_exec_path(const char *exec_path);
+extern void git_resolve_executable_dir(const char *path);
 extern const char *git_exec_path(void);
 extern void setup_path(void);
 extern const char **prepare_git_cmd(struct argv_array *out, const char **argv);
diff --git a/exec_cmd.c b/exec_cmd.c
deleted file mode 100644 (file)
index ce192a2..0000000
+++ /dev/null
@@ -1,165 +0,0 @@
-#include "cache.h"
-#include "exec_cmd.h"
-#include "quote.h"
-#include "argv-array.h"
-#define MAX_ARGS       32
-
-static const char *argv_exec_path;
-
-#ifdef RUNTIME_PREFIX
-static const char *argv0_path;
-
-static const char *system_prefix(void)
-{
-       static const char *prefix;
-
-       assert(argv0_path);
-       assert(is_absolute_path(argv0_path));
-
-       if (!prefix &&
-           !(prefix = strip_path_suffix(argv0_path, GIT_EXEC_PATH)) &&
-           !(prefix = strip_path_suffix(argv0_path, BINDIR)) &&
-           !(prefix = strip_path_suffix(argv0_path, "git"))) {
-               prefix = PREFIX;
-               trace_printf("RUNTIME_PREFIX requested, "
-                               "but prefix computation failed.  "
-                               "Using static fallback '%s'.\n", prefix);
-       }
-       return prefix;
-}
-
-void git_extract_argv0_path(const char *argv0)
-{
-       const char *slash;
-
-       if (!argv0 || !*argv0)
-               return;
-
-       slash = find_last_dir_sep(argv0);
-
-       if (slash)
-               argv0_path = xstrndup(argv0, slash - argv0);
-}
-
-#else
-
-static const char *system_prefix(void)
-{
-       return PREFIX;
-}
-
-void git_extract_argv0_path(const char *argv0)
-{
-}
-
-#endif /* RUNTIME_PREFIX */
-
-char *system_path(const char *path)
-{
-       struct strbuf d = STRBUF_INIT;
-
-       if (is_absolute_path(path))
-               return xstrdup(path);
-
-       strbuf_addf(&d, "%s/%s", system_prefix(), path);
-       return strbuf_detach(&d, NULL);
-}
-
-void git_set_argv_exec_path(const char *exec_path)
-{
-       argv_exec_path = exec_path;
-       /*
-        * Propagate this setting to external programs.
-        */
-       setenv(EXEC_PATH_ENVIRONMENT, exec_path, 1);
-}
-
-
-/* Returns the highest-priority, location to look for git programs. */
-const char *git_exec_path(void)
-{
-       static char *cached_exec_path;
-
-       if (argv_exec_path)
-               return argv_exec_path;
-
-       if (!cached_exec_path) {
-               const char *env = getenv(EXEC_PATH_ENVIRONMENT);
-               if (env && *env)
-                       cached_exec_path = xstrdup(env);
-               else
-                       cached_exec_path = system_path(GIT_EXEC_PATH);
-       }
-       return cached_exec_path;
-}
-
-static void add_path(struct strbuf *out, const char *path)
-{
-       if (path && *path) {
-               strbuf_add_absolute_path(out, path);
-               strbuf_addch(out, PATH_SEP);
-       }
-}
-
-void setup_path(void)
-{
-       const char *old_path = getenv("PATH");
-       struct strbuf new_path = STRBUF_INIT;
-
-       add_path(&new_path, git_exec_path());
-
-       if (old_path)
-               strbuf_addstr(&new_path, old_path);
-       else
-               strbuf_addstr(&new_path, _PATH_DEFPATH);
-
-       setenv("PATH", new_path.buf, 1);
-
-       strbuf_release(&new_path);
-}
-
-const char **prepare_git_cmd(struct argv_array *out, const char **argv)
-{
-       argv_array_push(out, "git");
-       argv_array_pushv(out, argv);
-       return out->argv;
-}
-
-int execv_git_cmd(const char **argv) {
-       struct argv_array nargv = ARGV_ARRAY_INIT;
-
-       prepare_git_cmd(&nargv, argv);
-       trace_argv_printf(nargv.argv, "trace: exec:");
-
-       /* execvp() can only ever return if it fails */
-       sane_execvp("git", (char **)nargv.argv);
-
-       trace_printf("trace: exec failed: %s\n", strerror(errno));
-
-       argv_array_clear(&nargv);
-       return -1;
-}
-
-
-int execl_git_cmd(const char *cmd,...)
-{
-       int argc;
-       const char *argv[MAX_ARGS + 1];
-       const char *arg;
-       va_list param;
-
-       va_start(param, cmd);
-       argv[0] = cmd;
-       argc = 1;
-       while (argc < MAX_ARGS) {
-               arg = argv[argc++] = va_arg(param, char *);
-               if (!arg)
-                       break;
-       }
-       va_end(param);
-       if (MAX_ARGS <= argc)
-               return error("too many args to run %s", cmd);
-
-       argv[argc] = NULL;
-       return execv_git_cmd(argv);
-}
index 35119c7a5dfe380c18f71f435fe44581701121e9..82a289d7a5a0acebedd18497eadefb46ff61dd68 100644 (file)
@@ -154,6 +154,7 @@ Format of STDIN stream:
 
 #include "builtin.h"
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "lockfile.h"
 #include "object.h"
@@ -168,6 +169,8 @@ Format of STDIN stream:
 #include "dir.h"
 #include "run-command.h"
 #include "packfile.h"
+#include "object-store.h"
+#include "mem-pool.h"
 
 #define PACK_ID_BITS 16
 #define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
@@ -209,13 +212,6 @@ struct last_object {
        unsigned no_swap : 1;
 };
 
-struct mem_pool {
-       struct mem_pool *next_pool;
-       char *next_free;
-       char *end;
-       uintmax_t space[FLEX_ARRAY]; /* more */
-};
-
 struct atom_str {
        struct atom_str *next_atom;
        unsigned short str_len;
@@ -304,9 +300,8 @@ static int global_argc;
 static const char **global_argv;
 
 /* Memory pools */
-static size_t mem_pool_alloc = 2*1024*1024 - sizeof(struct mem_pool);
-static size_t total_allocd;
-static struct mem_pool *mem_pool;
+static struct mem_pool fi_mem_pool =  {NULL, 2*1024*1024 -
+                                      sizeof(struct mp_block), 0 };
 
 /* Atom management */
 static unsigned int atom_table_sz = 4451;
@@ -341,6 +336,7 @@ static unsigned int tree_entry_alloc = 1000;
 static void *avail_tree_entry;
 static unsigned int avail_tree_table_sz = 100;
 static struct avail_tree_content **avail_tree_table;
+static size_t tree_entry_allocd;
 static struct strbuf old_tree = STRBUF_INIT;
 static struct strbuf new_tree = STRBUF_INIT;
 
@@ -635,49 +631,10 @@ static unsigned int hc_str(const char *s, size_t len)
        return r;
 }
 
-static void *pool_alloc(size_t len)
-{
-       struct mem_pool *p;
-       void *r;
-
-       /* round up to a 'uintmax_t' alignment */
-       if (len & (sizeof(uintmax_t) - 1))
-               len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));
-
-       for (p = mem_pool; p; p = p->next_pool)
-               if ((p->end - p->next_free >= len))
-                       break;
-
-       if (!p) {
-               if (len >= (mem_pool_alloc/2)) {
-                       total_allocd += len;
-                       return xmalloc(len);
-               }
-               total_allocd += sizeof(struct mem_pool) + mem_pool_alloc;
-               p = xmalloc(st_add(sizeof(struct mem_pool), mem_pool_alloc));
-               p->next_pool = mem_pool;
-               p->next_free = (char *) p->space;
-               p->end = p->next_free + mem_pool_alloc;
-               mem_pool = p;
-       }
-
-       r = p->next_free;
-       p->next_free += len;
-       return r;
-}
-
-static void *pool_calloc(size_t count, size_t size)
-{
-       size_t len = count * size;
-       void *r = pool_alloc(len);
-       memset(r, 0, len);
-       return r;
-}
-
 static char *pool_strdup(const char *s)
 {
        size_t len = strlen(s) + 1;
-       char *r = pool_alloc(len);
+       char *r = mem_pool_alloc(&fi_mem_pool, len);
        memcpy(r, s, len);
        return r;
 }
@@ -686,7 +643,7 @@ static void insert_mark(uintmax_t idnum, struct object_entry *oe)
 {
        struct mark_set *s = marks;
        while ((idnum >> s->shift) >= 1024) {
-               s = pool_calloc(1, sizeof(struct mark_set));
+               s = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct mark_set));
                s->shift = marks->shift + 10;
                s->data.sets[0] = marks;
                marks = s;
@@ -695,7 +652,7 @@ static void insert_mark(uintmax_t idnum, struct object_entry *oe)
                uintmax_t i = idnum >> s->shift;
                idnum -= i << s->shift;
                if (!s->data.sets[i]) {
-                       s->data.sets[i] = pool_calloc(1, sizeof(struct mark_set));
+                       s->data.sets[i] = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct mark_set));
                        s->data.sets[i]->shift = s->shift - 10;
                }
                s = s->data.sets[i];
@@ -733,7 +690,7 @@ static struct atom_str *to_atom(const char *s, unsigned short len)
                if (c->str_len == len && !strncmp(s, c->str_dat, len))
                        return c;
 
-       c = pool_alloc(sizeof(struct atom_str) + len + 1);
+       c = mem_pool_alloc(&fi_mem_pool, sizeof(struct atom_str) + len + 1);
        c->str_len = len;
        memcpy(c->str_dat, s, len);
        c->str_dat[len] = 0;
@@ -764,7 +721,7 @@ static struct branch *new_branch(const char *name)
        if (check_refname_format(name, REFNAME_ALLOW_ONELEVEL))
                die("Branch name doesn't conform to GIT standards: %s", name);
 
-       b = pool_calloc(1, sizeof(struct branch));
+       b = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct branch));
        b->name = pool_strdup(name);
        b->table_next_branch = branch_table[hc];
        b->branch_tree.versions[0].mode = S_IFDIR;
@@ -800,7 +757,7 @@ static struct tree_content *new_tree_content(unsigned int cnt)
                        avail_tree_table[hc] = f->next_avail;
        } else {
                cnt = cnt & 7 ? ((cnt / 8) + 1) * 8 : cnt;
-               f = pool_alloc(sizeof(*t) + sizeof(t->entries[0]) * cnt);
+               f = mem_pool_alloc(&fi_mem_pool, sizeof(*t) + sizeof(t->entries[0]) * cnt);
                f->entry_capacity = cnt;
        }
 
@@ -845,7 +802,7 @@ static struct tree_entry *new_tree_entry(void)
 
        if (!avail_tree_entry) {
                unsigned int n = tree_entry_alloc;
-               total_allocd += n * sizeof(struct tree_entry);
+               tree_entry_allocd += n * sizeof(struct tree_entry);
                ALLOC_ARRAY(e, n);
                avail_tree_entry = e;
                while (n-- > 1) {
@@ -1017,7 +974,7 @@ static void end_packfile(void)
                struct tag *t;
 
                close_pack_windows(pack_data);
-               hashclose(pack_file, cur_pack_oid.hash, 0);
+               finalize_hashfile(pack_file, cur_pack_oid.hash, 0);
                fixup_pack_header_footer(pack_data->pack_fd, pack_data->sha1,
                                    pack_data->pack_name, object_count,
                                    cur_pack_oid.hash, pack_size);
@@ -1037,7 +994,7 @@ static void end_packfile(void)
                if (!new_p)
                        die("core git rejected index %s", idx_name);
                all_packs[pack_id] = new_p;
-               install_packed_git(new_p);
+               install_packed_git(the_repository, new_p);
                free(idx_name);
 
                /* Print the boundary */
@@ -1111,7 +1068,8 @@ static int store_object(
        if (e->idx.offset) {
                duplicate_count_by_type[type]++;
                return 1;
-       } else if (find_sha1_pack(oid.hash, packed_git)) {
+       } else if (find_sha1_pack(oid.hash,
+                                 get_packed_git(the_repository))) {
                e->type = type;
                e->pack_id = MAX_PACK_ID;
                e->idx.offset = 1; /* just not zero! */
@@ -1308,7 +1266,8 @@ static void stream_blob(uintmax_t len, struct object_id *oidout, uintmax_t mark)
                duplicate_count_by_type[OBJ_BLOB]++;
                truncate_pack(&checkpoint);
 
-       } else if (find_sha1_pack(oid.hash, packed_git)) {
+       } else if (find_sha1_pack(oid.hash,
+                                 get_packed_git(the_repository))) {
                e->type = OBJ_BLOB;
                e->pack_id = MAX_PACK_ID;
                e->idx.offset = 1; /* just not zero! */
@@ -1373,7 +1332,7 @@ static void *gfi_unpack_entry(
                 */
                p->pack_size = pack_size + the_hash_algo->rawsz;
        }
-       return unpack_entry(p, oe->idx.offset, &type, sizep);
+       return unpack_entry(the_repository, p, oe->idx.offset, &type, sizep);
 }
 
 static const char *get_mode(const char *str, uint16_t *modep)
@@ -1413,7 +1372,7 @@ static void load_tree(struct tree_entry *root)
                        die("Can't load tree %s", oid_to_hex(oid));
        } else {
                enum object_type type;
-               buf = read_sha1_file(oid->hash, &type, &size);
+               buf = read_object_file(oid, &type, &size);
                if (!buf || type != OBJ_TREE)
                        die("Can't load tree %s", oid_to_hex(oid));
        }
@@ -1859,7 +1818,7 @@ static void dump_marks_helper(FILE *f,
 
 static void dump_marks(void)
 {
-       static struct lock_file mark_lock;
+       struct lock_file mark_lock = LOCK_INIT;
        FILE *f;
 
        if (!export_marks_file || (import_marks_file && !import_marks_file_done))
@@ -1920,7 +1879,8 @@ static void read_marks(void)
                        die("corrupt mark line: %s", line);
                e = find_object(&oid);
                if (!e) {
-                       enum object_type type = sha1_object_info(oid.hash, NULL);
+                       enum object_type type = oid_object_info(the_repository,
+                                                               &oid, NULL);
                        if (type < 0)
                                die("object not found: %s", oid_to_hex(&oid));
                        e = insert_object(&oid);
@@ -2450,7 +2410,8 @@ static void file_change_m(const char *p, struct branch *b)
                enum object_type expected = S_ISDIR(mode) ?
                                                OBJ_TREE: OBJ_BLOB;
                enum object_type type = oe ? oe->type :
-                                       sha1_object_info(oid.hash, NULL);
+                                       oid_object_info(the_repository, &oid,
+                                                       NULL);
                if (type < 0)
                        die("%s not found: %s",
                                        S_ISDIR(mode) ?  "Tree" : "Blob",
@@ -2590,8 +2551,9 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
                oidcpy(&commit_oid, &commit_oe->idx.oid);
        } else if (!get_oid(p, &commit_oid)) {
                unsigned long size;
-               char *buf = read_object_with_reference(commit_oid.hash,
-                       commit_type, &size, commit_oid.hash);
+               char *buf = read_object_with_reference(&commit_oid,
+                                                      commit_type, &size,
+                                                      &commit_oid);
                if (!buf || size < 46)
                        die("Not a valid commit: %s", p);
                free(buf);
@@ -2610,7 +2572,8 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa
                        die("Not a blob (actually a %s): %s",
                                type_name(oe->type), command_buf.buf);
        } else if (!is_null_oid(&oid)) {
-               enum object_type type = sha1_object_info(oid.hash, NULL);
+               enum object_type type = oid_object_info(the_repository, &oid,
+                                                       NULL);
                if (type < 0)
                        die("Blob not found: %s", command_buf.buf);
                if (type != OBJ_BLOB)
@@ -2660,9 +2623,8 @@ static void parse_from_existing(struct branch *b)
                unsigned long size;
                char *buf;
 
-               buf = read_object_with_reference(b->oid.hash,
-                                                commit_type, &size,
-                                                b->oid.hash);
+               buf = read_object_with_reference(&b->oid, commit_type, &size,
+                                                &b->oid);
                parse_from_commit(b, buf, size);
                free(buf);
        }
@@ -2739,8 +2701,9 @@ static struct hash_list *parse_merge(unsigned int *count)
                        oidcpy(&n->oid, &oe->idx.oid);
                } else if (!get_oid(from, &n->oid)) {
                        unsigned long size;
-                       char *buf = read_object_with_reference(n->oid.hash,
-                               commit_type, &size, n->oid.hash);
+                       char *buf = read_object_with_reference(&n->oid,
+                                                              commit_type,
+                                                              &size, &n->oid);
                        if (!buf || size < 46)
                                die("Not a valid commit: %s", from);
                        free(buf);
@@ -2869,7 +2832,7 @@ static void parse_new_tag(const char *arg)
        enum object_type type;
        const char *v;
 
-       t = pool_alloc(sizeof(struct tag));
+       t = mem_pool_alloc(&fi_mem_pool, sizeof(struct tag));
        memset(t, 0, sizeof(struct tag));
        t->name = pool_strdup(arg);
        if (last_tag)
@@ -2897,7 +2860,7 @@ static void parse_new_tag(const char *arg)
        } else if (!get_oid(from, &oid)) {
                struct object_entry *oe = find_object(&oid);
                if (!oe) {
-                       type = sha1_object_info(oid.hash, NULL);
+                       type = oid_object_info(the_repository, &oid, NULL);
                        if (type < 0)
                                die("Not a valid object: %s", from);
                } else
@@ -2973,7 +2936,7 @@ static void cat_blob(struct object_entry *oe, struct object_id *oid)
        char *buf;
 
        if (!oe || oe->pack_id == MAX_PACK_ID) {
-               buf = read_sha1_file(oid->hash, &type, &size);
+               buf = read_object_file(oid, &type, &size);
        } else {
                type = oe->type;
                buf = gfi_unpack_entry(oe, &size);
@@ -3055,7 +3018,8 @@ static struct object_entry *dereference(struct object_entry *oe,
        unsigned long size;
        char *buf = NULL;
        if (!oe) {
-               enum object_type type = sha1_object_info(oid->hash, NULL);
+               enum object_type type = oid_object_info(the_repository, oid,
+                                                       NULL);
                if (type < 0)
                        die("object not found: %s", oid_to_hex(oid));
                /* cache it! */
@@ -3078,7 +3042,7 @@ static struct object_entry *dereference(struct object_entry *oe,
                buf = gfi_unpack_entry(oe, &size);
        } else {
                enum object_type unused;
-               buf = read_sha1_file(oid->hash, &unused, &size);
+               buf = read_object_file(oid, &unused, &size);
        }
        if (!buf)
                die("Can't load object %s", oid_to_hex(oid));
@@ -3478,7 +3442,7 @@ int cmd_main(int argc, const char **argv)
        atom_table = xcalloc(atom_table_sz, sizeof(struct atom_str*));
        branch_table = xcalloc(branch_table_sz, sizeof(struct branch*));
        avail_tree_table = xcalloc(avail_tree_table_sz, sizeof(struct avail_tree_content*));
-       marks = pool_calloc(1, sizeof(struct mark_set));
+       marks = mem_pool_calloc(&fi_mem_pool, 1, sizeof(struct mark_set));
 
        /*
         * We don't parse most options until after we've seen the set of
@@ -3497,12 +3461,11 @@ int cmd_main(int argc, const char **argv)
        global_argc = argc;
        global_argv = argv;
 
-       rc_free = pool_alloc(cmd_save * sizeof(*rc_free));
+       rc_free = mem_pool_alloc(&fi_mem_pool, cmd_save * sizeof(*rc_free));
        for (i = 0; i < (cmd_save - 1); i++)
                rc_free[i].next = &rc_free[i + 1];
        rc_free[cmd_save - 1].next = NULL;
 
-       prepare_packed_git();
        start_packfile();
        set_die_routine(die_nicely);
        set_checkpoint_signal();
@@ -3572,8 +3535,8 @@ int cmd_main(int argc, const char **argv)
                fprintf(stderr, "Total branches:  %10lu (%10lu loads     )\n", branch_count, branch_load_count);
                fprintf(stderr, "      marks:     %10" PRIuMAX " (%10" PRIuMAX " unique    )\n", (((uintmax_t)1) << marks->shift) * 1024, marks_set_count);
                fprintf(stderr, "      atoms:     %10u\n", atom_cnt);
-               fprintf(stderr, "Memory total:    %10" PRIuMAX " KiB\n", (total_allocd + alloc_count*sizeof(struct object_entry))/1024);
-               fprintf(stderr, "       pools:    %10lu KiB\n", (unsigned long)(total_allocd/1024));
+               fprintf(stderr, "Memory total:    %10" PRIuMAX " KiB\n", (tree_entry_allocd + fi_mem_pool.pool_alloc + alloc_count*sizeof(struct object_entry))/1024);
+               fprintf(stderr, "       pools:    %10lu KiB\n", (unsigned long)((tree_entry_allocd + fi_mem_pool.pool_alloc) /1024));
                fprintf(stderr, "     objects:    %10" PRIuMAX " KiB\n", (alloc_count*sizeof(struct object_entry))/1024);
                fprintf(stderr, "---------------------------------------------------------------------\n");
                pack_report();
index 1d6117565c2067460efc50aa4e6ca2ecb167a976..a320ce9872b5e752aeb592a16cc9108ae87e9d71 100644 (file)
@@ -1,11 +1,12 @@
 #include "cache.h"
+#include "repository.h"
 #include "config.h"
 #include "lockfile.h"
 #include "refs.h"
 #include "pkt-line.h"
 #include "commit.h"
 #include "tag.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "pack.h"
 #include "sideband.h"
 #include "fetch-pack.h"
@@ -304,9 +305,9 @@ static void insert_one_alternate_object(struct object *obj)
 #define PIPESAFE_FLUSH 32
 #define LARGE_FLUSH 16384
 
-static int next_flush(struct fetch_pack_args *args, int count)
+static int next_flush(int stateless_rpc, int count)
 {
-       if (args->stateless_rpc) {
+       if (stateless_rpc) {
                if (count < LARGE_FLUSH)
                        count <<= 1;
                else
@@ -469,7 +470,7 @@ static int find_common(struct fetch_pack_args *args,
                        send_request(args, fd[1], &req_buf);
                        strbuf_setlen(&req_buf, state_len);
                        flushes++;
-                       flush_at = next_flush(args, count);
+                       flush_at = next_flush(args->stateless_rpc, count);
 
                        /*
                         * We keep one window "ahead" of the other side, and
@@ -711,6 +712,28 @@ static void mark_alternate_complete(struct object *obj)
        mark_complete(&obj->oid);
 }
 
+struct loose_object_iter {
+       struct oidset *loose_object_set;
+       struct ref *refs;
+};
+
+/*
+ *  If the number of refs is not larger than the number of loose objects,
+ *  this function stops inserting.
+ */
+static int add_loose_objects_to_set(const struct object_id *oid,
+                                   const char *path,
+                                   void *data)
+{
+       struct loose_object_iter *iter = data;
+       oidset_insert(iter->loose_object_set, oid);
+       if (iter->refs == NULL)
+               return 1;
+
+       iter->refs = iter->refs->next;
+       return 0;
+}
+
 static int everything_local(struct fetch_pack_args *args,
                            struct ref **refs,
                            struct ref **sought, int nr_sought)
@@ -719,16 +742,31 @@ static int everything_local(struct fetch_pack_args *args,
        int retval;
        int old_save_commit_buffer = save_commit_buffer;
        timestamp_t cutoff = 0;
+       struct oidset loose_oid_set = OIDSET_INIT;
+       int use_oidset = 0;
+       struct loose_object_iter iter = {&loose_oid_set, *refs};
+
+       /* Enumerate all loose objects or know refs are not so many. */
+       use_oidset = !for_each_loose_object(add_loose_objects_to_set,
+                                           &iter, 0);
 
        save_commit_buffer = 0;
 
        for (ref = *refs; ref; ref = ref->next) {
                struct object *o;
+               unsigned int flags = OBJECT_INFO_QUICK;
 
-               if (!has_object_file_with_flags(&ref->old_oid,
-                                               OBJECT_INFO_QUICK))
-                       continue;
+               if (use_oidset &&
+                   !oidset_contains(&loose_oid_set, &ref->old_oid)) {
+                       /*
+                        * I know this does not exist in the loose form,
+                        * so check if it exists in a non-loose form.
+                        */
+                       flags |= OBJECT_INFO_IGNORE_LOOSE;
+               }
 
+               if (!has_object_file_with_flags(&ref->old_oid, flags))
+                       continue;
                o = parse_object(&ref->old_oid);
                if (!o)
                        continue;
@@ -744,6 +782,8 @@ static int everything_local(struct fetch_pack_args *args,
                }
        }
 
+       oidset_clear(&loose_oid_set);
+
        if (!args->no_dependents) {
                if (!args->deepen) {
                        for_each_ref(mark_complete_oid, NULL);
@@ -1040,6 +1080,350 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args,
        return ref;
 }
 
+static void add_shallow_requests(struct strbuf *req_buf,
+                                const struct fetch_pack_args *args)
+{
+       if (is_repository_shallow())
+               write_shallow_commits(req_buf, 1, NULL);
+       if (args->depth > 0)
+               packet_buf_write(req_buf, "deepen %d", args->depth);
+       if (args->deepen_since) {
+               timestamp_t max_age = approxidate(args->deepen_since);
+               packet_buf_write(req_buf, "deepen-since %"PRItime, max_age);
+       }
+       if (args->deepen_not) {
+               int i;
+               for (i = 0; i < args->deepen_not->nr; i++) {
+                       struct string_list_item *s = args->deepen_not->items + i;
+                       packet_buf_write(req_buf, "deepen-not %s", s->string);
+               }
+       }
+}
+
+static void add_wants(const struct ref *wants, struct strbuf *req_buf)
+{
+       for ( ; wants ; wants = wants->next) {
+               const struct object_id *remote = &wants->old_oid;
+               const char *remote_hex;
+               struct object *o;
+
+               /*
+                * If that object is complete (i.e. it is an ancestor of a
+                * local ref), we tell them we have it but do not have to
+                * tell them about its ancestors, which they already know
+                * about.
+                *
+                * We use lookup_object here because we are only
+                * interested in the case we *know* the object is
+                * reachable and we have already scanned it.
+                */
+               if (((o = lookup_object(remote->hash)) != NULL) &&
+                   (o->flags & COMPLETE)) {
+                       continue;
+               }
+
+               remote_hex = oid_to_hex(remote);
+               packet_buf_write(req_buf, "want %s\n", remote_hex);
+       }
+}
+
+static void add_common(struct strbuf *req_buf, struct oidset *common)
+{
+       struct oidset_iter iter;
+       const struct object_id *oid;
+       oidset_iter_init(common, &iter);
+
+       while ((oid = oidset_iter_next(&iter))) {
+               packet_buf_write(req_buf, "have %s\n", oid_to_hex(oid));
+       }
+}
+
+static int add_haves(struct strbuf *req_buf, int *haves_to_send, int *in_vain)
+{
+       int ret = 0;
+       int haves_added = 0;
+       const struct object_id *oid;
+
+       while ((oid = get_rev())) {
+               packet_buf_write(req_buf, "have %s\n", oid_to_hex(oid));
+               if (++haves_added >= *haves_to_send)
+                       break;
+       }
+
+       *in_vain += haves_added;
+       if (!haves_added || *in_vain >= MAX_IN_VAIN) {
+               /* Send Done */
+               packet_buf_write(req_buf, "done\n");
+               ret = 1;
+       }
+
+       /* Increase haves to send on next round */
+       *haves_to_send = next_flush(1, *haves_to_send);
+
+       return ret;
+}
+
+static int send_fetch_request(int fd_out, const struct fetch_pack_args *args,
+                             const struct ref *wants, struct oidset *common,
+                             int *haves_to_send, int *in_vain)
+{
+       int ret = 0;
+       struct strbuf req_buf = STRBUF_INIT;
+
+       if (server_supports_v2("fetch", 1))
+               packet_buf_write(&req_buf, "command=fetch");
+       if (server_supports_v2("agent", 0))
+               packet_buf_write(&req_buf, "agent=%s", git_user_agent_sanitized());
+       if (args->server_options && args->server_options->nr &&
+           server_supports_v2("server-option", 1)) {
+               int i;
+               for (i = 0; i < args->server_options->nr; i++)
+                       packet_write_fmt(fd_out, "server-option=%s",
+                                        args->server_options->items[i].string);
+       }
+
+       packet_buf_delim(&req_buf);
+       if (args->use_thin_pack)
+               packet_buf_write(&req_buf, "thin-pack");
+       if (args->no_progress)
+               packet_buf_write(&req_buf, "no-progress");
+       if (args->include_tag)
+               packet_buf_write(&req_buf, "include-tag");
+       if (prefer_ofs_delta)
+               packet_buf_write(&req_buf, "ofs-delta");
+
+       /* Add shallow-info and deepen request */
+       if (server_supports_feature("fetch", "shallow", 0))
+               add_shallow_requests(&req_buf, args);
+       else if (is_repository_shallow() || args->deepen)
+               die(_("Server does not support shallow requests"));
+
+       /* Add filter */
+       if (server_supports_feature("fetch", "filter", 0) &&
+           args->filter_options.choice) {
+               print_verbose(args, _("Server supports filter"));
+               packet_buf_write(&req_buf, "filter %s",
+                                args->filter_options.filter_spec);
+       } else if (args->filter_options.choice) {
+               warning("filtering not recognized by server, ignoring");
+       }
+
+       /* add wants */
+       add_wants(wants, &req_buf);
+
+       if (args->no_dependents) {
+               packet_buf_write(&req_buf, "done");
+               ret = 1;
+       } else {
+               /* Add all of the common commits we've found in previous rounds */
+               add_common(&req_buf, common);
+
+               /* Add initial haves */
+               ret = add_haves(&req_buf, haves_to_send, in_vain);
+       }
+
+       /* Send request */
+       packet_buf_flush(&req_buf);
+       write_or_die(fd_out, req_buf.buf, req_buf.len);
+
+       strbuf_release(&req_buf);
+       return ret;
+}
+
+/*
+ * Processes a section header in a server's response and checks if it matches
+ * `section`.  If the value of `peek` is 1, the header line will be peeked (and
+ * not consumed); if 0, the line will be consumed and the function will die if
+ * the section header doesn't match what was expected.
+ */
+static int process_section_header(struct packet_reader *reader,
+                                 const char *section, int peek)
+{
+       int ret;
+
+       if (packet_reader_peek(reader) != PACKET_READ_NORMAL)
+               die("error reading section header '%s'", section);
+
+       ret = !strcmp(reader->line, section);
+
+       if (!peek) {
+               if (!ret)
+                       die("expected '%s', received '%s'",
+                           section, reader->line);
+               packet_reader_read(reader);
+       }
+
+       return ret;
+}
+
+static int process_acks(struct packet_reader *reader, struct oidset *common)
+{
+       /* received */
+       int received_ready = 0;
+       int received_ack = 0;
+
+       process_section_header(reader, "acknowledgments", 0);
+       while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
+               const char *arg;
+
+               if (!strcmp(reader->line, "NAK"))
+                       continue;
+
+               if (skip_prefix(reader->line, "ACK ", &arg)) {
+                       struct object_id oid;
+                       if (!get_oid_hex(arg, &oid)) {
+                               struct commit *commit;
+                               oidset_insert(common, &oid);
+                               commit = lookup_commit(&oid);
+                               mark_common(commit, 0, 1);
+                       }
+                       continue;
+               }
+
+               if (!strcmp(reader->line, "ready")) {
+                       clear_prio_queue(&rev_list);
+                       received_ready = 1;
+                       continue;
+               }
+
+               die("unexpected acknowledgment line: '%s'", reader->line);
+       }
+
+       if (reader->status != PACKET_READ_FLUSH &&
+           reader->status != PACKET_READ_DELIM)
+               die("error processing acks: %d", reader->status);
+
+       /* return 0 if no common, 1 if there are common, or 2 if ready */
+       return received_ready ? 2 : (received_ack ? 1 : 0);
+}
+
+static void receive_shallow_info(struct fetch_pack_args *args,
+                                struct packet_reader *reader)
+{
+       process_section_header(reader, "shallow-info", 0);
+       while (packet_reader_read(reader) == PACKET_READ_NORMAL) {
+               const char *arg;
+               struct object_id oid;
+
+               if (skip_prefix(reader->line, "shallow ", &arg)) {
+                       if (get_oid_hex(arg, &oid))
+                               die(_("invalid shallow line: %s"), reader->line);
+                       register_shallow(&oid);
+                       continue;
+               }
+               if (skip_prefix(reader->line, "unshallow ", &arg)) {
+                       if (get_oid_hex(arg, &oid))
+                               die(_("invalid unshallow line: %s"), reader->line);
+                       if (!lookup_object(oid.hash))
+                               die(_("object not found: %s"), reader->line);
+                       /* make sure that it is parsed as shallow */
+                       if (!parse_object(&oid))
+                               die(_("error in object: %s"), reader->line);
+                       if (unregister_shallow(&oid))
+                               die(_("no shallow found: %s"), reader->line);
+                       continue;
+               }
+               die(_("expected shallow/unshallow, got %s"), reader->line);
+       }
+
+       if (reader->status != PACKET_READ_FLUSH &&
+           reader->status != PACKET_READ_DELIM)
+               die("error processing shallow info: %d", reader->status);
+
+       setup_alternate_shallow(&shallow_lock, &alternate_shallow_file, NULL);
+       args->deepen = 1;
+}
+
+enum fetch_state {
+       FETCH_CHECK_LOCAL = 0,
+       FETCH_SEND_REQUEST,
+       FETCH_PROCESS_ACKS,
+       FETCH_GET_PACK,
+       FETCH_DONE,
+};
+
+static struct ref *do_fetch_pack_v2(struct fetch_pack_args *args,
+                                   int fd[2],
+                                   const struct ref *orig_ref,
+                                   struct ref **sought, int nr_sought,
+                                   char **pack_lockfile)
+{
+       struct ref *ref = copy_ref_list(orig_ref);
+       enum fetch_state state = FETCH_CHECK_LOCAL;
+       struct oidset common = OIDSET_INIT;
+       struct packet_reader reader;
+       int in_vain = 0;
+       int haves_to_send = INITIAL_FLUSH;
+       packet_reader_init(&reader, fd[0], NULL, 0,
+                          PACKET_READ_CHOMP_NEWLINE);
+
+       while (state != FETCH_DONE) {
+               switch (state) {
+               case FETCH_CHECK_LOCAL:
+                       sort_ref_list(&ref, ref_compare_name);
+                       QSORT(sought, nr_sought, cmp_ref_by_name);
+
+                       /* v2 supports these by default */
+                       allow_unadvertised_object_request |= ALLOW_REACHABLE_SHA1;
+                       use_sideband = 2;
+                       if (args->depth > 0 || args->deepen_since || args->deepen_not)
+                               args->deepen = 1;
+
+                       if (marked)
+                               for_each_ref(clear_marks, NULL);
+                       marked = 1;
+
+                       for_each_ref(rev_list_insert_ref_oid, NULL);
+                       for_each_cached_alternate(insert_one_alternate_object);
+
+                       /* Filter 'ref' by 'sought' and those that aren't local */
+                       if (everything_local(args, &ref, sought, nr_sought))
+                               state = FETCH_DONE;
+                       else
+                               state = FETCH_SEND_REQUEST;
+                       break;
+               case FETCH_SEND_REQUEST:
+                       if (send_fetch_request(fd[1], args, ref, &common,
+                                              &haves_to_send, &in_vain))
+                               state = FETCH_GET_PACK;
+                       else
+                               state = FETCH_PROCESS_ACKS;
+                       break;
+               case FETCH_PROCESS_ACKS:
+                       /* Process ACKs/NAKs */
+                       switch (process_acks(&reader, &common)) {
+                       case 2:
+                               state = FETCH_GET_PACK;
+                               break;
+                       case 1:
+                               in_vain = 0;
+                               /* fallthrough */
+                       default:
+                               state = FETCH_SEND_REQUEST;
+                               break;
+                       }
+                       break;
+               case FETCH_GET_PACK:
+                       /* Check for shallow-info section */
+                       if (process_section_header(&reader, "shallow-info", 1))
+                               receive_shallow_info(args, &reader);
+
+                       /* get the pack */
+                       process_section_header(&reader, "packfile", 0);
+                       if (get_pack(args, fd, pack_lockfile))
+                               die(_("git fetch-pack: fetch failed."));
+
+                       state = FETCH_DONE;
+                       break;
+               case FETCH_DONE:
+                       continue;
+               }
+       }
+
+       oidset_clear(&common);
+       return ref;
+}
+
 static void fetch_pack_config(void)
 {
        git_config_get_int("fetch.unpacklimit", &fetch_unpack_limit);
@@ -1185,7 +1569,8 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
                       const char *dest,
                       struct ref **sought, int nr_sought,
                       struct oid_array *shallow,
-                      char **pack_lockfile)
+                      char **pack_lockfile,
+                      enum protocol_version version)
 {
        struct ref *ref_cpy;
        struct shallow_info si;
@@ -1199,9 +1584,13 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
                die(_("no matching remote head"));
        }
        prepare_shallow_info(&si, shallow);
-       ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
-                               &si, pack_lockfile);
-       reprepare_packed_git();
+       if (version == protocol_v2)
+               ref_cpy = do_fetch_pack_v2(args, fd, ref, sought, nr_sought,
+                                          pack_lockfile);
+       else
+               ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought,
+                                       &si, pack_lockfile);
+       reprepare_packed_git(the_repository);
        update_shallow(args, sought, nr_sought, &si);
        clear_shallow_info(&si);
        return ref_cpy;
index 3e224a18226ec6219b09387704baf178821c4c23..bb45a366a82a4a7dae2524e0845ac33128076c57 100644 (file)
@@ -3,6 +3,7 @@
 
 #include "string-list.h"
 #include "run-command.h"
+#include "protocol.h"
 #include "list-objects-filter-options.h"
 
 struct oid_array;
@@ -14,6 +15,7 @@ struct fetch_pack_args {
        const char *deepen_since;
        const struct string_list *deepen_not;
        struct list_objects_filter_options filter_options;
+       const struct string_list *server_options;
        unsigned deepen_relative:1;
        unsigned quiet:1;
        unsigned keep_pack:1;
@@ -53,7 +55,8 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
                       struct ref **sought,
                       int nr_sought,
                       struct oid_array *shallow,
-                      char **pack_lockfile);
+                      char **pack_lockfile,
+                      enum protocol_version version);
 
 /*
  * Print an appropriate error message for each sought ref that wasn't
diff --git a/fsck.c b/fsck.c
index 0741e625860e38c15b2cd5c55e598f687511ca92..6ccc6388fa8f1b01b3c9ea8eb066aa6bc258666a 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -412,9 +412,11 @@ static int fsck_walk_commit(struct commit *commit, void *data, struct fsck_optio
 
        name = get_object_name(options, &commit->object);
        if (name)
-               put_object_name(options, &commit->tree->object, "%s:", name);
+               put_object_name(options, &get_commit_tree(commit)->object,
+                               "%s:", name);
 
-       result = options->walk((struct object *)commit->tree, OBJ_TREE, data, options);
+       result = options->walk((struct object *)get_commit_tree(commit),
+                              OBJ_TREE, data, options);
        if (result < 0)
                return result;
        res = result;
@@ -751,30 +753,31 @@ static int fsck_ident(const char **ident, struct object *obj, struct fsck_option
 static int fsck_commit_buffer(struct commit *commit, const char *buffer,
        unsigned long size, struct fsck_options *options)
 {
-       unsigned char tree_sha1[20], sha1[20];
+       struct object_id tree_oid, oid;
        struct commit_graft *graft;
        unsigned parent_count, parent_line_count = 0, author_count;
        int err;
        const char *buffer_begin = buffer;
+       const char *p;
 
        if (verify_headers(buffer, size, &commit->object, options))
                return -1;
 
        if (!skip_prefix(buffer, "tree ", &buffer))
                return report(options, &commit->object, FSCK_MSG_MISSING_TREE, "invalid format - expected 'tree' line");
-       if (get_sha1_hex(buffer, tree_sha1) || buffer[40] != '\n') {
+       if (parse_oid_hex(buffer, &tree_oid, &p) || *p != '\n') {
                err = report(options, &commit->object, FSCK_MSG_BAD_TREE_SHA1, "invalid 'tree' line format - bad sha1");
                if (err)
                        return err;
        }
-       buffer += 41;
+       buffer = p + 1;
        while (skip_prefix(buffer, "parent ", &buffer)) {
-               if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') {
+               if (parse_oid_hex(buffer, &oid, &p) || *p != '\n') {
                        err = report(options, &commit->object, FSCK_MSG_BAD_PARENT_SHA1, "invalid 'parent' line format - bad sha1");
                        if (err)
                                return err;
                }
-               buffer += 41;
+               buffer = p + 1;
                parent_line_count++;
        }
        graft = lookup_commit_graft(&commit->object.oid);
@@ -812,8 +815,8 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer,
        err = fsck_ident(&buffer, &commit->object, options);
        if (err)
                return err;
-       if (!commit->tree) {
-               err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1));
+       if (!get_commit_tree(commit)) {
+               err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", oid_to_hex(&tree_oid));
                if (err)
                        return err;
        }
@@ -839,11 +842,12 @@ static int fsck_commit(struct commit *commit, const char *data,
 static int fsck_tag_buffer(struct tag *tag, const char *data,
        unsigned long size, struct fsck_options *options)
 {
-       unsigned char sha1[20];
+       struct object_id oid;
        int ret = 0;
        const char *buffer;
        char *to_free = NULL, *eol;
        struct strbuf sb = STRBUF_INIT;
+       const char *p;
 
        if (data)
                buffer = data;
@@ -851,7 +855,7 @@ static int fsck_tag_buffer(struct tag *tag, const char *data,
                enum object_type type;
 
                buffer = to_free =
-                       read_sha1_file(tag->object.oid.hash, &type, &size);
+                       read_object_file(&tag->object.oid, &type, &size);
                if (!buffer)
                        return report(options, &tag->object,
                                FSCK_MSG_MISSING_TAG_OBJECT,
@@ -874,12 +878,12 @@ static int fsck_tag_buffer(struct tag *tag, const char *data,
                ret = report(options, &tag->object, FSCK_MSG_MISSING_OBJECT, "invalid format - expected 'object' line");
                goto done;
        }
-       if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') {
+       if (parse_oid_hex(buffer, &oid, &p) || *p != '\n') {
                ret = report(options, &tag->object, FSCK_MSG_BAD_OBJECT_SHA1, "invalid 'object' line format - bad sha1");
                if (ret)
                        goto done;
        }
-       buffer += 41;
+       buffer = p + 1;
 
        if (!skip_prefix(buffer, "type ", &buffer)) {
                ret = report(options, &tag->object, FSCK_MSG_MISSING_TYPE_ENTRY, "invalid format - expected 'type' line");
@@ -1069,13 +1073,14 @@ int fsck_finish(struct fsck_options *options)
 
                blob = lookup_blob(oid);
                if (!blob) {
-                       ret |= report(options, &blob->object,
+                       struct object *obj = lookup_unknown_object(oid->hash);
+                       ret |= report(options, obj,
                                      FSCK_MSG_GITMODULES_BLOB,
                                      "non-blob found at .gitmodules");
                        continue;
                }
 
-               buf = read_sha1_file(oid->hash, &type, &size);
+               buf = read_object_file(oid, &type, &size);
                if (!buf) {
                        if (is_promisor_object(&blob->object.oid))
                                continue;
index 6d7bcd5d0ed8f2d3f5abdea2f26c6be72909b657..665bd2d4254b12edf38e94cb0e8b2200ae3bf34a 100644 (file)
@@ -97,19 +97,13 @@ void write_fsmonitor_extension(struct strbuf *sb, struct index_state *istate)
 static int query_fsmonitor(int version, uint64_t last_update, struct strbuf *query_result)
 {
        struct child_process cp = CHILD_PROCESS_INIT;
-       char ver[64];
-       char date[64];
-       const char *argv[4];
 
-       if (!(argv[0] = core_fsmonitor))
+       if (!core_fsmonitor)
                return -1;
 
-       snprintf(ver, sizeof(version), "%d", version);
-       snprintf(date, sizeof(date), "%" PRIuMAX, (uintmax_t)last_update);
-       argv[1] = ver;
-       argv[2] = date;
-       argv[3] = NULL;
-       cp.argv = argv;
+       argv_array_push(&cp.args, core_fsmonitor);
+       argv_array_pushf(&cp.args, "%d", version);
+       argv_array_pushf(&cp.args, "%" PRIuMAX, (uintmax_t)last_update);
        cp.use_shell = 1;
        cp.dir = get_git_work_tree();
 
@@ -185,6 +179,9 @@ void refresh_fsmonitor(struct index_state *istate)
                for (i = 0; i < istate->cache_nr; i++)
                        istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID;
 
+               /* If we're going to check every file, ensure we save the results */
+               istate->cache_changed |= FSMONITOR_CHANGED;
+
                if (istate->untracked)
                        istate->untracked->use_fsmonitor = 0;
        }
index eeea4b67ea7f1ccee1770c18a36d018b5f3b32b0..8d6d8b45ceb0138797eb7e54b15f7546925598ed 100755 (executable)
@@ -1,50 +1,90 @@
 #!/bin/sh
 
-echo "/* Automatically generated by generate-cmdlist.sh */
-struct cmdname_help {
-       char name[16];
-       char help[80];
-       unsigned char group;
-};
+die () {
+       echo "$@" >&2
+       exit 1
+}
+
+command_list () {
+       grep -v '^#' "$1"
+}
 
-static const char *common_cmd_groups[] = {"
-
-grps=grps$$.tmp
-match=match$$.tmp
-trap "rm -f '$grps' '$match'" 0 1 2 3 15
-
-sed -n '
-       1,/^### common groups/b
-       /^### command list/q
-       /^#/b
-       /^[     ]*$/b
-       h;s/^[^         ][^     ]*[     ][      ]*\(.*\)/       N_("\1"),/p
-       g;s/^\([^       ][^     ]*\)[   ].*/\1/w '$grps'
-       ' "$1"
-printf '};\n\n'
-
-n=0
-substnum=
-while read grp
-do
-       echo "^git-..*[         ]$grp"
-       substnum="$substnum${substnum:+;}s/[    ]$grp/$n/"
-       n=$(($n+1))
-done <"$grps" >"$match"
-
-printf 'static struct cmdname_help common_cmds[] = {\n'
-grep -f "$match" "$1" |
-sed 's/^git-//' |
-sort |
-while read cmd tags
-do
-       tag=$(echo "$tags" | sed "$substnum; s/[^0-9]//g")
+get_categories () {
+       tr ' ' '\n'|
+       grep -v '^$' |
+       sort |
+       uniq
+}
+
+category_list () {
+       command_list "$1" |
+       cut -c 40- |
+       get_categories
+}
+
+get_synopsis () {
        sed -n '
-               /^NAME/,/git-'"$cmd"'/H
+               /^NAME/,/'"$1"'/H
                ${
                        x
-                       s/.*git-'"$cmd"' - \(.*\)/      {"'"$cmd"'", N_("\1"), '$tag'},/
+                       s/.*'"$1"' - \(.*\)/N_("\1")/
                        p
-               }' "Documentation/git-$cmd.txt"
-done
-echo "};"
+               }' "Documentation/$1.txt"
+}
+
+define_categories () {
+       echo
+       echo "/* Command categories */"
+       bit=0
+       category_list "$1" |
+       while read cat
+       do
+               echo "#define CAT_$cat (1UL << $bit)"
+               bit=$(($bit+1))
+       done
+       test "$bit" -gt 32 && die "Urgh.. too many categories?"
+}
+
+define_category_names () {
+       echo
+       echo "/* Category names */"
+       echo "static const char *category_names[] = {"
+       bit=0
+       category_list "$1" |
+       while read cat
+       do
+               echo "  \"$cat\", /* (1UL << $bit) */"
+               bit=$(($bit+1))
+       done
+       echo "  NULL"
+       echo "};"
+}
+
+print_command_list () {
+       echo "static struct cmdname_help command_list[] = {"
+
+       command_list "$1" |
+       while read cmd rest
+       do
+               printf "        { \"$cmd\", $(get_synopsis $cmd), 0"
+               for cat in $(echo "$rest" | get_categories)
+               do
+                       printf " | CAT_$cat"
+               done
+               echo " },"
+       done
+       echo "};"
+}
+
+echo "/* Automatically generated by generate-cmdlist.sh */
+struct cmdname_help {
+       const char *name;
+       const char *help;
+       uint32_t category;
+};
+"
+define_categories "$1"
+echo
+define_category_names "$1"
+echo
+print_command_list "$1"
index db727ea0204aa13acea0f189ea03e59b5cdb918f..7272771c8e445da194ea608443d8bc9c891b6b33 100644 (file)
--- a/gettext.c
+++ b/gettext.c
@@ -2,7 +2,8 @@
  * Copyright (c) 2010 Ævar Arnfjörð Bjarmason
  */
 
-#include "git-compat-util.h"
+#include "cache.h"
+#include "exec-cmd.h"
 #include "gettext.h"
 #include "strbuf.h"
 #include "utf8.h"
@@ -157,15 +158,24 @@ static void init_gettext_charset(const char *domain)
 
 void git_setup_gettext(void)
 {
-       const char *podir = getenv("GIT_TEXTDOMAINDIR");
+       const char *podir = getenv(GIT_TEXT_DOMAIN_DIR_ENVIRONMENT);
+       char *p = NULL;
 
        if (!podir)
-               podir = GIT_LOCALE_PATH;
+               podir = p = system_path(GIT_LOCALE_PATH);
+
+       if (!is_directory(podir)) {
+               free(p);
+               return;
+       }
+
        bindtextdomain("git", podir);
        setlocale(LC_MESSAGES, "");
        setlocale(LC_TIME, "");
        init_gettext_charset("git");
        textdomain("git");
+
+       free(p);
 }
 
 /* return the number of columns of string 's' in current locale */
index c1f52e457f6c5b03947766555e10fba33e7e1b38..36f38ced902e1902a626933bdcda09819acf39a7 100755 (executable)
@@ -205,8 +205,15 @@ my $status_head = sprintf($status_fmt, __('staged'), __('unstaged'), __('path'))
        }
 }
 
-sub get_empty_tree {
-       return '4b825dc642cb6eb9a060e54bf8d69288fbee4904';
+{
+       my $empty_tree;
+       sub get_empty_tree {
+               return $empty_tree if defined $empty_tree;
+
+               $empty_tree = run_cmd_pipe(qw(git hash-object -t tree /dev/null));
+               chomp $empty_tree;
+               return $empty_tree;
+       }
 }
 
 sub get_diff_reference {
index 37277494f9bbe97fb2a6a553c6dcdf429cf1bcf8..f5bc4e09769b5e719dc5cffd4710d5e705d7e8d2 100644 (file)
@@ -284,6 +284,10 @@ extern char *gitdirname(char *);
 #include <openssl/err.h>
 #endif
 
+#ifdef HAVE_SYSINFO
+# include <sys/sysinfo.h>
+#endif
+
 /* On most systems <netdb.h> would have given us this, but
  * not on some systems (e.g. z/OS).
  */
@@ -459,6 +463,7 @@ extern void (*get_warn_routine(void))(const char *warn, va_list params);
 extern void set_die_is_recursing_routine(int (*routine)(void));
 
 extern int starts_with(const char *str, const char *prefix);
+extern int istarts_with(const char *str, const char *prefix);
 
 /*
  * If the string "str" begins with the string found in "prefix", return 1.
@@ -1073,7 +1078,7 @@ int git_qsort_s(void *base, size_t nmemb, size_t size,
 
 #define QSORT_S(base, n, compar, ctx) do {                     \
        if (qsort_s((base), (n), sizeof(*(base)), compar, ctx)) \
-               die("BUG: qsort_s() failed");                   \
+               BUG("qsort_s() failed");                        \
 } while (0)
 
 #ifndef REG_STARTEND
@@ -1132,6 +1137,9 @@ static inline int regexec_buf(const regex_t *preg, const char *buf, size_t size,
 #define HAVE_VARIADIC_MACROS 1
 #endif
 
+/* usage.c: only to be used for testing BUG() implementation (see test-tool) */
+extern int BUG_exit_code;
+
 #ifdef HAVE_VARIADIC_MACROS
 __attribute__((format (printf, 3, 4))) NORETURN
 void BUG_fl(const char *file, int line, const char *fmt, ...);
index 98c76ec589b053c112ddc86b6821f2acf17b7ab0..ccceaf19a74373bb23b2a2b1aa71b7f0bb909d54 100755 (executable)
@@ -11,6 +11,8 @@
 # The following functions will also be available in the commit filter:
 
 functions=$(cat << \EOF
+EMPTY_TREE=$(git hash-object -t tree /dev/null)
+
 warn () {
        echo "$*" >&2
 }
@@ -46,7 +48,7 @@ git_commit_non_empty_tree()
 {
        if test $# = 3 && test "$1" = $(git rev-parse "$3^{tree}"); then
                map "$3"
-       elif test $# = 1 && test "$1" = 4b825dc642cb6eb9a060e54bf8d69288fbee4904; then
+       elif test $# = 1 && test "$1" = $EMPTY_TREE; then
                :
        else
                git commit-tree "$@"
@@ -251,8 +253,18 @@ done < "$tempdir"/backup-refs
 
 # The refs should be updated if their heads were rewritten
 git rev-parse --no-flags --revs-only --symbolic-full-name \
-       --default HEAD "$@" > "$tempdir"/raw-heads || exit
-sed -e '/^^/d' "$tempdir"/raw-heads >"$tempdir"/heads
+       --default HEAD "$@" > "$tempdir"/raw-refs || exit
+while read ref
+do
+       case "$ref" in ^?*) continue ;; esac
+
+       if git rev-parse --verify "$ref"^0 >/dev/null 2>&1
+       then
+               echo "$ref"
+       else
+               warn "WARNING: not rewriting '$ref' (not a committish)"
+       fi
+done >"$tempdir"/heads <"$tempdir"/raw-refs
 
 test -s "$tempdir"/heads ||
        die "You must specify a ref to rewrite."
@@ -310,7 +322,7 @@ git rev-list --reverse --topo-order --default HEAD \
        die "Could not get the commits"
 commits=$(wc -l <../revs | tr -d " ")
 
-test $commits -eq 0 && die "Found nothing to rewrite"
+test $commits -eq 0 && die_with_status 2 "Found nothing to rewrite"
 
 # Rewrite the commits
 report_progress ()
index 91c00e6489305a56faed6d4e89150709ba7f2aeb..6de74ce639cec90fcf7ba1797825526df675547a 100755 (executable)
@@ -3867,6 +3867,7 @@ bind .   <$M1B-Key-equal> {show_more_context;break}
 bind .   <$M1B-Key-plus> {show_more_context;break}
 bind .   <$M1B-Key-KP_Add> {show_more_context;break}
 bind .   <$M1B-Key-Return> do_commit
+bind .   <$M1B-Key-KP_Enter> do_commit
 foreach i [list $ui_index $ui_workdir] {
        bind $i <Button-1>       { toggle_or_diff click %W %x %y; break }
        bind $i <$M1B-Button-1>  { add_one_to_selection %W %x %y; break }
index aa6457bbb5f1b0d64d6e04f27394912483250117..589ff8f78aba8273651b33005c6f6abd1db2fa27 100644 (file)
@@ -2,7 +2,10 @@
 # Copyright (C) 2006, 2007 Shawn Pearce
 
 proc find_ssh_key {} {
-       foreach name {~/.ssh/id_dsa.pub ~/.ssh/id_rsa.pub ~/.ssh/identity.pub} {
+       foreach name {
+               ~/.ssh/id_dsa.pub ~/.ssh/id_ecdsa.pub ~/.ssh/id_ed25519.pub
+               ~/.ssh/id_rsa.pub ~/.ssh/identity.pub
+       } {
                if {[file exists $name]} {
                        set fh    [open $name r]
                        set cont  [read $fh]
index 351a712c8c503eb5a04466afb8aa5acd7f0259f5..88b3119a75068763cfee6d79ad4d53a83ad20a67 100644 (file)
@@ -1,6 +1,14 @@
 # Functions for supporting the use of themed Tk widgets in git-gui.
 # Copyright (C) 2009 Pat Thoyts <patthoyts@users.sourceforge.net>
 
+proc ttk_get_current_theme {} {
+       # Handle either current Tk or older versions of 8.5
+       if {[catch {set theme [ttk::style theme use]}]} {
+               set theme  $::ttk::currentTheme
+       }
+       return $theme
+}
+
 proc InitTheme {} {
        # Create a color label style (bg can be overridden by widget option)
        ttk::style layout Color.TLabel {
@@ -28,10 +36,7 @@ proc InitTheme {} {
                }
        }
 
-       # Handle either current Tk or older versions of 8.5
-       if {[catch {set theme [ttk::style theme use]}]} {
-               set theme  $::ttk::currentTheme
-       }
+       set theme [ttk_get_current_theme]
 
        if {[lsearch -exact {default alt classic clam} $theme] != -1} {
                # Simple override of standard ttk::entry to change the field
@@ -248,7 +253,7 @@ proc tspinbox {w args} {
 proc ttext {w args} {
        global use_ttk
        if {$use_ttk} {
-               switch -- [ttk::style theme use] {
+               switch -- [ttk_get_current_theme] {
                        "vista" - "xpnative" {
                                lappend args -highlightthickness 0 -borderwidth 0
                        }
index 9879c59395edff1a02e390397fc623bc60724c57..f6d9852d2f618393412016cc81c73b1e8362a59d 100755 (executable)
@@ -120,7 +120,7 @@ case "${1:-.}${2:-.}${3:-.}" in
        case "$1" in
        '')
                echo "Added $4 in both, but differently."
-               orig=$(git unpack-file e69de29bb2d1d6434b8b29ae775ad8c2e48c5391)
+               orig=$(git unpack-file $(git hash-object /dev/null))
                ;;
        *)
                echo "Auto-merging $4"
index 7bb9cadc69738a4348bb54ccce50d6bd35a0753f..0354d4df5cadd5145245d755a8868608b849719f 100755 (executable)
--- a/git-p4.py
+++ b/git-p4.py
@@ -47,8 +47,10 @@ verbose = False
 # Only labels/tags matching this will be imported/exported
 defaultLabelRegexp = r'[a-zA-Z0-9_\-.]+$'
 
-# Grab changes in blocks of this many revisions, unless otherwise requested
-defaultBlockSize = 512
+# The block size is reduced automatically if required
+defaultBlockSize = 1<<20
+
+p4_access_checked = False
 
 def p4_build_cmd(cmd):
     """Build a suitable p4 command line.
@@ -91,6 +93,13 @@ def p4_build_cmd(cmd):
         real_cmd = ' '.join(real_cmd) + ' ' + cmd
     else:
         real_cmd += cmd
+
+    # now check that we can actually talk to the server
+    global p4_access_checked
+    if not p4_access_checked:
+        p4_access_checked = True    # suppress access checks in p4_check_access itself
+        p4_check_access()
+
     return real_cmd
 
 def git_dir(path):
@@ -264,6 +273,52 @@ def p4_system(cmd):
     if retcode:
         raise CalledProcessError(retcode, real_cmd)
 
+def die_bad_access(s):
+    die("failure accessing depot: {0}".format(s.rstrip()))
+
+def p4_check_access(min_expiration=1):
+    """ Check if we can access Perforce - account still logged in
+    """
+    results = p4CmdList(["login", "-s"])
+
+    if len(results) == 0:
+        # should never get here: always get either some results, or a p4ExitCode
+        assert("could not parse response from perforce")
+
+    result = results[0]
+
+    if 'p4ExitCode' in result:
+        # p4 returned non-zero status, e.g. P4PORT invalid, or p4 not in path
+        die_bad_access("could not run p4")
+
+    code = result.get("code")
+    if not code:
+        # we get here if we couldn't connect and there was nothing to unmarshal
+        die_bad_access("could not connect")
+
+    elif code == "stat":
+        expiry = result.get("TicketExpiration")
+        if expiry:
+            expiry = int(expiry)
+            if expiry > min_expiration:
+                # ok to carry on
+                return
+            else:
+                die_bad_access("perforce ticket expires in {0} seconds".format(expiry))
+
+        else:
+            # account without a timeout - all ok
+            return
+
+    elif code == "error":
+        data = result.get("data")
+        if data:
+            die_bad_access("p4 error: {0}".format(data))
+        else:
+            die_bad_access("unknown error")
+    else:
+        die_bad_access("unknown error code {0}".format(code))
+
 _p4_version_string = None
 def p4_version_string():
     """Read the version string, showing just the last line, which
@@ -316,12 +371,17 @@ def p4_last_change():
     results = p4CmdList(["changes", "-m", "1"], skip_info=True)
     return int(results[0]['change'])
 
-def p4_describe(change):
+def p4_describe(change, shelved=False):
     """Make sure it returns a valid result by checking for
        the presence of field "time".  Return a dict of the
        results."""
 
-    ds = p4CmdList(["describe", "-s", str(change)], skip_info=True)
+    cmd = ["describe", "-s"]
+    if shelved:
+        cmd += ["-S"]
+    cmd += [str(change)]
+
+    ds = p4CmdList(cmd, skip_info=True)
     if len(ds) != 1:
         die("p4 describe -s %d did not return 1 result: %s" % (change, str(ds)))
 
@@ -506,10 +566,30 @@ def isModeExec(mode):
     # otherwise False.
     return mode[-3:] == "755"
 
+class P4Exception(Exception):
+    """ Base class for exceptions from the p4 client """
+    def __init__(self, exit_code):
+        self.p4ExitCode = exit_code
+
+class P4ServerException(P4Exception):
+    """ Base class for exceptions where we get some kind of marshalled up result from the server """
+    def __init__(self, exit_code, p4_result):
+        super(P4ServerException, self).__init__(exit_code)
+        self.p4_result = p4_result
+        self.code = p4_result[0]['code']
+        self.data = p4_result[0]['data']
+
+class P4RequestSizeException(P4ServerException):
+    """ One of the maxresults or maxscanrows errors """
+    def __init__(self, exit_code, p4_result, limit):
+        super(P4RequestSizeException, self).__init__(exit_code, p4_result)
+        self.limit = limit
+
 def isModeExecChanged(src_mode, dst_mode):
     return isModeExec(src_mode) != isModeExec(dst_mode)
 
-def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False):
+def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False,
+        errors_as_exceptions=False):
 
     if isinstance(cmd,basestring):
         cmd = "-G " + cmd
@@ -556,9 +636,25 @@ def p4CmdList(cmd, stdin=None, stdin_mode='w+b', cb=None, skip_info=False):
         pass
     exitCode = p4.wait()
     if exitCode != 0:
-        entry = {}
-        entry["p4ExitCode"] = exitCode
-        result.append(entry)
+        if errors_as_exceptions:
+            if len(result) > 0:
+                data = result[0].get('data')
+                if data:
+                    m = re.search('Too many rows scanned \(over (\d+)\)', data)
+                    if not m:
+                        m = re.search('Request too large \(over (\d+)\)', data)
+
+                    if m:
+                        limit = int(m.group(1))
+                        raise P4RequestSizeException(exitCode, result, limit)
+
+                raise P4ServerException(exitCode, result)
+            else:
+                raise P4Exception(exitCode)
+        else:
+            entry = {}
+            entry["p4ExitCode"] = exitCode
+            result.append(entry)
 
     return result
 
@@ -662,6 +758,12 @@ def gitBranchExists(branch):
                             stderr=subprocess.PIPE, stdout=subprocess.PIPE);
     return proc.wait() == 0;
 
+def gitUpdateRef(ref, newvalue):
+    subprocess.check_call(["git", "update-ref", ref, newvalue])
+
+def gitDeleteRef(ref):
+    subprocess.check_call(["git", "update-ref", "-d", ref])
+
 _gitConfig = {}
 
 def gitConfig(key, typeSpecifier=None):
@@ -857,7 +959,7 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
         try:
             (changeStart, changeEnd) = p4ParseNumericChangeRange(parts)
             block_size = chooseBlockSize(requestedBlockSize)
-        except:
+        except ValueError:
             changeStart = parts[0][1:]
             changeEnd = parts[1]
             if requestedBlockSize:
@@ -867,7 +969,8 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
     changes = set()
 
     # Retrieve changes a block at a time, to prevent running
-    # into a MaxResults/MaxScanRows error from the server.
+    # into a MaxResults/MaxScanRows error from the server. If
+    # we _do_ hit one of those errors, turn down the block size
 
     while True:
         cmd = ['changes']
@@ -881,10 +984,24 @@ def p4ChangesForPaths(depotPaths, changeRange, requestedBlockSize):
         for p in depotPaths:
             cmd += ["%s...@%s" % (p, revisionRange)]
 
+        # fetch the changes
+        try:
+            result = p4CmdList(cmd, errors_as_exceptions=True)
+        except P4RequestSizeException as e:
+            if not block_size:
+                block_size = e.limit
+            elif block_size > e.limit:
+                block_size = e.limit
+            else:
+                block_size = max(2, block_size // 2)
+
+            if verbose: print("block size error, retrying with block size {0}".format(block_size))
+            continue
+        except P4Exception as e:
+            die('Error retrieving changes description ({0})'.format(e.p4ExitCode))
+
         # Insert changes in chronological order
-        for entry in reversed(p4CmdList(cmd)):
-            if entry.has_key('p4ExitCode'):
-                die('Error retrieving changes descriptions ({})'.format(entry['p4ExitCode']))
+        for entry in reversed(result):
             if not entry.has_key('change'):
                 continue
             changes.add(int(entry['change']))
@@ -1352,7 +1469,14 @@ class P4Submit(Command, P4UserMap):
                 optparse.make_option("--update-shelve", dest="update_shelve", action="append", type="int",
                                      metavar="CHANGELIST",
                                      help="update an existing shelved changelist, implies --shelve, "
-                                           "repeat in-order for multiple shelved changelists")
+                                           "repeat in-order for multiple shelved changelists"),
+                optparse.make_option("--commit", dest="commit", metavar="COMMIT",
+                                     help="submit only the specified commit(s), one commit or xxx..xxx"),
+                optparse.make_option("--disable-rebase", dest="disable_rebase", action="store_true",
+                                     help="Disable rebase after submit is completed. Can be useful if you "
+                                     "work from a local git branch that is not master"),
+                optparse.make_option("--disable-p4sync", dest="disable_p4sync", action="store_true",
+                                     help="Skip Perforce sync of p4/master after submit or shelve"),
         ]
         self.description = "Submit changes from git to the perforce depot."
         self.usage += " [name of git branch to submit into perforce depot]"
@@ -1362,6 +1486,9 @@ class P4Submit(Command, P4UserMap):
         self.dry_run = False
         self.shelve = False
         self.update_shelve = list()
+        self.commit = ""
+        self.disable_rebase = gitConfigBool("git-p4.disableRebase")
+        self.disable_p4sync = gitConfigBool("git-p4.disableP4Sync")
         self.prepare_p4_only = False
         self.conflict_behavior = None
         self.isWindows = (platform.system() == "Windows")
@@ -2099,13 +2226,22 @@ class P4Submit(Command, P4UserMap):
 
         commits = []
         if self.master:
-            commitish = self.master
+            committish = self.master
         else:
-            commitish = 'HEAD'
-
-        for line in read_pipe_lines(["git", "rev-list", "--no-merges", "%s..%s" % (self.origin, commitish)]):
-            commits.append(line.strip())
-        commits.reverse()
+            committish = 'HEAD'
+
+        if self.commit != "":
+            if self.commit.find("..") != -1:
+                limits_ish = self.commit.split("..")
+                for line in read_pipe_lines(["git", "rev-list", "--no-merges", "%s..%s" % (limits_ish[0], limits_ish[1])]):
+                    commits.append(line.strip())
+                commits.reverse()
+            else:
+                commits.append(self.commit)
+        else:
+            for line in read_pipe_lines(["git", "rev-list", "--no-merges", "%s..%s" % (self.origin, committish)]):
+                commits.append(line.strip())
+            commits.reverse()
 
         if self.preserveUser or gitConfigBool("git-p4.skipUserNameCheck"):
             self.checkAuthorship = False
@@ -2213,10 +2349,14 @@ class P4Submit(Command, P4UserMap):
             sync = P4Sync()
             if self.branch:
                 sync.branch = self.branch
-            sync.run([])
+            if self.disable_p4sync:
+                sync.sync_origin_only()
+            else:
+                sync.run([])
 
-            rebase = P4Rebase()
-            rebase.rebase()
+                if not self.disable_rebase:
+                    rebase = P4Rebase()
+                    rebase.rebase()
 
         else:
             if len(applied) == 0:
@@ -2411,6 +2551,7 @@ class P4Sync(Command, P4UserMap):
         self.tempBranches = []
         self.tempBranchLocation = "refs/git-p4-tmp"
         self.largeFileSystem = None
+        self.suppress_meta_comment = False
 
         if gitConfig('git-p4.largeFileSystem'):
             largeFileSystemConstructor = globals()[gitConfig('git-p4.largeFileSystem')]
@@ -2421,6 +2562,18 @@ class P4Sync(Command, P4UserMap):
         if gitConfig("git-p4.syncFromOrigin") == "false":
             self.syncWithOrigin = False
 
+        self.depotPaths = []
+        self.changeRange = ""
+        self.previousDepotPaths = []
+        self.hasOrigin = False
+
+        # map from branch depot path to parent branch
+        self.knownBranches = {}
+        self.initialParents = {}
+
+        self.tz = "%+03d%02d" % (- time.timezone / 3600, ((- time.timezone % 3600) / 60))
+        self.labels = {}
+
     # Force a checkpoint in fast-import and wait for it to finish
     def checkpoint(self):
         self.gitStream.write("checkpoint\n\n")
@@ -2429,7 +2582,20 @@ class P4Sync(Command, P4UserMap):
         if self.verbose:
             print "checkpoint finished: " + out
 
-    def extractFilesFromCommit(self, commit):
+    def cmp_shelved(self, path, filerev, revision):
+        """ Determine if a path at revision #filerev is the same as the file
+            at revision @revision for a shelved changelist. If they don't match,
+            unshelving won't be safe (we will get other changes mixed in).
+
+            This is comparing the revision that the shelved changelist is *based* on, not
+            the shelved changelist itself.
+        """
+        ret = p4Cmd(["diff2", "{0}#{1}".format(path, filerev), "{0}@{1}".format(path, revision)])
+        if verbose:
+            print("p4 diff2 path %s filerev %s revision %s => %s" % (path, filerev, revision, ret))
+        return ret["status"] == "identical"
+
+    def extractFilesFromCommit(self, commit, shelved=False, shelved_cl = 0, origin_revision = 0):
         self.cloneExclude = [re.sub(r"\.\.\.$", "", path)
                              for path in self.cloneExclude]
         files = []
@@ -2452,6 +2618,19 @@ class P4Sync(Command, P4UserMap):
             file["rev"] = commit["rev%s" % fnum]
             file["action"] = commit["action%s" % fnum]
             file["type"] = commit["type%s" % fnum]
+            if shelved:
+                file["shelved_cl"] = int(shelved_cl)
+
+                # For shelved changelists, check that the revision of each file that the
+                # shelve was based on matches the revision that we are using for the
+                # starting point for git-fast-import (self.initialParent). Otherwise
+                # the resulting diff will contain deltas from multiple commits.
+
+                if file["action"] != "add" and \
+                    not self.cmp_shelved(path, file["rev"], origin_revision):
+                    sys.exit("change {0} not based on {1} for {2}, cannot unshelve".format(
+                        commit["change"], self.initialParent, path))
+
             files.append(file)
             fnum = fnum + 1
         return files
@@ -2743,7 +2922,16 @@ class P4Sync(Command, P4UserMap):
             def streamP4FilesCbSelf(entry):
                 self.streamP4FilesCb(entry)
 
-            fileArgs = ['%s#%s' % (f['path'], f['rev']) for f in filesToRead]
+            fileArgs = []
+            for f in filesToRead:
+                if 'shelved_cl' in f:
+                    # Handle shelved CLs using the "p4 print file@=N" syntax to print
+                    # the contents
+                    fileArg = '%s@=%d' % (f['path'], f['shelved_cl'])
+                else:
+                    fileArg = '%s#%s' % (f['path'], f['rev'])
+
+                fileArgs.append(fileArg)
 
             p4CmdList(["-x", "-", "print"],
                       stdin=fileArgs,
@@ -2844,11 +3032,15 @@ class P4Sync(Command, P4UserMap):
         self.gitStream.write(details["desc"])
         if len(jobs) > 0:
             self.gitStream.write("\nJobs: %s" % (' '.join(jobs)))
-        self.gitStream.write("\n[git-p4: depot-paths = \"%s\": change = %s" %
-                             (','.join(self.branchPrefixes), details["change"]))
-        if len(details['options']) > 0:
-            self.gitStream.write(": options = %s" % details['options'])
-        self.gitStream.write("]\nEOT\n\n")
+
+        if not self.suppress_meta_comment:
+            self.gitStream.write("\n[git-p4: depot-paths = \"%s\": change = %s" %
+                                (','.join(self.branchPrefixes), details["change"]))
+            if len(details['options']) > 0:
+                self.gitStream.write(": options = %s" % details['options'])
+            self.gitStream.write("]\n")
+
+        self.gitStream.write("EOT\n\n")
 
         if len(parent) > 0:
             if self.verbose:
@@ -3162,10 +3354,10 @@ class P4Sync(Command, P4UserMap):
         else:
             return None
 
-    def importChanges(self, changes):
+    def importChanges(self, changes, shelved=False, origin_revision=0):
         cnt = 1
         for change in changes:
-            description = p4_describe(change)
+            description = p4_describe(change, shelved)
             self.updateOptionDict(description)
 
             if not self.silent:
@@ -3235,7 +3427,7 @@ class P4Sync(Command, P4UserMap):
                                 print "Parent of %s not found. Committing into head of %s" % (branch, parent)
                             self.commit(description, filesForCommit, branch, parent)
                 else:
-                    files = self.extractFilesFromCommit(description)
+                    files = self.extractFilesFromCommit(description, shelved, change, origin_revision)
                     self.commit(description, files, self.branch,
                                 self.initialParent)
                     # only needed once, to connect to the previous commit
@@ -3244,6 +3436,14 @@ class P4Sync(Command, P4UserMap):
                 print self.gitError.read()
                 sys.exit(1)
 
+    def sync_origin_only(self):
+        if self.syncWithOrigin:
+            self.hasOrigin = originP4BranchesExist()
+            if self.hasOrigin:
+                if not self.silent:
+                    print 'Syncing with origin first, using "git fetch origin"'
+                system("git fetch origin")
+
     def importHeadRevision(self, revision):
         print "Doing initial import of %s from revision %s into %s" % (' '.join(self.depotPaths), revision, self.branch)
 
@@ -3300,28 +3500,29 @@ class P4Sync(Command, P4UserMap):
             print "IO error with git fast-import. Is your git version recent enough?"
             print self.gitError.read()
 
+    def openStreams(self):
+        self.importProcess = subprocess.Popen(["git", "fast-import"],
+                                              stdin=subprocess.PIPE,
+                                              stdout=subprocess.PIPE,
+                                              stderr=subprocess.PIPE);
+        self.gitOutput = self.importProcess.stdout
+        self.gitStream = self.importProcess.stdin
+        self.gitError = self.importProcess.stderr
 
-    def run(self, args):
-        self.depotPaths = []
-        self.changeRange = ""
-        self.previousDepotPaths = []
-        self.hasOrigin = False
-
-        # map from branch depot path to parent branch
-        self.knownBranches = {}
-        self.initialParents = {}
+    def closeStreams(self):
+        self.gitStream.close()
+        if self.importProcess.wait() != 0:
+            die("fast-import failed: %s" % self.gitError.read())
+        self.gitOutput.close()
+        self.gitError.close()
 
+    def run(self, args):
         if self.importIntoRemotes:
             self.refPrefix = "refs/remotes/p4/"
         else:
             self.refPrefix = "refs/heads/p4/"
 
-        if self.syncWithOrigin:
-            self.hasOrigin = originP4BranchesExist()
-            if self.hasOrigin:
-                if not self.silent:
-                    print 'Syncing with origin first, using "git fetch origin"'
-                system("git fetch origin")
+        self.sync_origin_only()
 
         branch_arg_given = bool(self.branch)
         if len(self.branch) == 0:
@@ -3497,15 +3698,7 @@ class P4Sync(Command, P4UserMap):
                     b = b[len(self.projectName):]
                 self.createdBranches.add(b)
 
-        self.tz = "%+03d%02d" % (- time.timezone / 3600, ((- time.timezone % 3600) / 60))
-
-        self.importProcess = subprocess.Popen(["git", "fast-import"],
-                                              stdin=subprocess.PIPE,
-                                              stdout=subprocess.PIPE,
-                                              stderr=subprocess.PIPE);
-        self.gitOutput = self.importProcess.stdout
-        self.gitStream = self.importProcess.stdin
-        self.gitError = self.importProcess.stderr
+        self.openStreams()
 
         if revision:
             self.importHeadRevision(revision)
@@ -3585,11 +3778,7 @@ class P4Sync(Command, P4UserMap):
             missingP4Labels = p4Labels - gitTags
             self.importP4Labels(self.gitStream, missingP4Labels)
 
-        self.gitStream.close()
-        if self.importProcess.wait() != 0:
-            die("fast-import failed: %s" % self.gitError.read())
-        self.gitOutput.close()
-        self.gitError.close()
+        self.closeStreams()
 
         # Cleanup temporary branches created during import
         if self.tempBranches != []:
@@ -3721,6 +3910,89 @@ class P4Clone(P4Sync):
 
         return True
 
+class P4Unshelve(Command):
+    def __init__(self):
+        Command.__init__(self)
+        self.options = []
+        self.origin = "HEAD"
+        self.description = "Unshelve a P4 changelist into a git commit"
+        self.usage = "usage: %prog [options] changelist"
+        self.options += [
+                optparse.make_option("--origin", dest="origin",
+                    help="Use this base revision instead of the default (%s)" % self.origin),
+        ]
+        self.verbose = False
+        self.noCommit = False
+        self.destbranch = "refs/remotes/p4/unshelved"
+
+    def renameBranch(self, branch_name):
+        """ Rename the existing branch to branch_name.N
+        """
+
+        found = True
+        for i in range(0,1000):
+            backup_branch_name = "{0}.{1}".format(branch_name, i)
+            if not gitBranchExists(backup_branch_name):
+                gitUpdateRef(backup_branch_name, branch_name) # copy ref to backup
+                gitDeleteRef(branch_name)
+                found = True
+                print("renamed old unshelve branch to {0}".format(backup_branch_name))
+                break
+
+        if not found:
+            sys.exit("gave up trying to rename existing branch {0}".format(sync.branch))
+
+    def findLastP4Revision(self, starting_point):
+        """ Look back from starting_point for the first commit created by git-p4
+            to find the P4 commit we are based on, and the depot-paths.
+        """
+
+        for parent in (range(65535)):
+            log = extractLogMessageFromGitCommit("{0}^{1}".format(starting_point, parent))
+            settings = extractSettingsGitLog(log)
+            if settings.has_key('change'):
+                return settings
+
+        sys.exit("could not find git-p4 commits in {0}".format(self.origin))
+
+    def run(self, args):
+        if len(args) != 1:
+            return False
+
+        if not gitBranchExists(self.origin):
+            sys.exit("origin branch {0} does not exist".format(self.origin))
+
+        sync = P4Sync()
+        changes = args
+        sync.initialParent = self.origin
+
+        # use the first change in the list to construct the branch to unshelve into
+        change = changes[0]
+
+        # if the target branch already exists, rename it
+        branch_name = "{0}/{1}".format(self.destbranch, change)
+        if gitBranchExists(branch_name):
+            self.renameBranch(branch_name)
+        sync.branch = branch_name
+
+        sync.verbose = self.verbose
+        sync.suppress_meta_comment = True
+
+        settings = self.findLastP4Revision(self.origin)
+        origin_revision = settings['change']
+        sync.depotPaths = settings['depot-paths']
+        sync.branchPrefixes = sync.depotPaths
+
+        sync.openStreams()
+        sync.loadUserMapFromCache()
+        sync.silent = True
+        sync.importChanges(changes, shelved=True, origin_revision=origin_revision)
+        sync.closeStreams()
+
+        print("unshelved changelist {0} into {1}".format(change, branch_name))
+
+        return True
+
 class P4Branches(Command):
     def __init__(self):
         Command.__init__(self)
@@ -3775,7 +4047,8 @@ commands = {
     "rebase" : P4Rebase,
     "clone" : P4Clone,
     "rollback" : P4RollBack,
-    "branches" : P4Branches
+    "branches" : P4Branches,
+    "unshelve" : P4Unshelve,
 }
 
 
index be3f068922c5a3ba0d1112f3b8b1cf1228567d2e..99b8c177875a7f26ae6c7f70be42c9d97231f7b9 100644 (file)
@@ -4,15 +4,6 @@
 # Copyright (c) 2010 Junio C Hamano.
 #
 
-# The whole contents of this file is run by dot-sourcing it from
-# inside a shell function.  It used to be that "return"s we see
-# below were not inside any function, and expected to return
-# to the function that dot-sourced us.
-#
-# However, older (9.x) versions of FreeBSD /bin/sh misbehave on such a
-# construct and continue to run the statements that follow such a "return".
-# As a work-around, we introduce an extra layer of a function
-# here, and immediately call it after defining it.
 git_rebase__am () {
 
 case "$action" in
@@ -41,60 +32,47 @@ else
 fi
 
 ret=0
-if test -n "$keep_empty"
-then
-       # we have to do this the hard way.  git format-patch completely squashes
-       # empty commits and even if it didn't the format doesn't really lend
-       # itself well to recording empty patches.  fortunately, cherry-pick
-       # makes this easy
-       git cherry-pick ${gpg_sign_opt:+"$gpg_sign_opt"} --allow-empty \
-               $allow_rerere_autoupdate --right-only "$revisions" \
-               $allow_empty_message \
-               ${restrict_revision+^$restrict_revision}
-       ret=$?
-else
-       rm -f "$GIT_DIR/rebased-patches"
+rm -f "$GIT_DIR/rebased-patches"
 
-       git format-patch -k --stdout --full-index --cherry-pick --right-only \
-               --src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \
-               --pretty=mboxrd \
-               $git_format_patch_opt \
-               "$revisions" ${restrict_revision+^$restrict_revision} \
-               >"$GIT_DIR/rebased-patches"
-       ret=$?
+git format-patch -k --stdout --full-index --cherry-pick --right-only \
+       --src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \
+       --pretty=mboxrd \
+       $git_format_patch_opt \
+       "$revisions" ${restrict_revision+^$restrict_revision} \
+       >"$GIT_DIR/rebased-patches"
+ret=$?
 
-       if test 0 != $ret
-       then
-               rm -f "$GIT_DIR/rebased-patches"
-               case "$head_name" in
-               refs/heads/*)
-                       git checkout -q "$head_name"
-                       ;;
-               *)
-                       git checkout -q "$orig_head"
-                       ;;
-               esac
+if test 0 != $ret
+then
+       rm -f "$GIT_DIR/rebased-patches"
+       case "$head_name" in
+       refs/heads/*)
+               git checkout -q "$head_name"
+               ;;
+       *)
+               git checkout -q "$orig_head"
+               ;;
+       esac
 
-               cat >&2 <<-EOF
+       cat >&2 <<-EOF
 
-               git encountered an error while preparing the patches to replay
-               these revisions:
+       git encountered an error while preparing the patches to replay
+       these revisions:
 
-                   $revisions
+           $revisions
 
-               As a result, git cannot rebase them.
-               EOF
-               return $ret
-       fi
+       As a result, git cannot rebase them.
+       EOF
+       return $ret
+fi
 
-       git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" \
-               --patch-format=mboxrd \
-               $allow_rerere_autoupdate \
-               ${gpg_sign_opt:+"$gpg_sign_opt"} <"$GIT_DIR/rebased-patches"
-       ret=$?
+git am $git_am_opt --rebasing --resolvemsg="$resolvemsg" \
+       --patch-format=mboxrd \
+       $allow_rerere_autoupdate \
+       ${gpg_sign_opt:+"$gpg_sign_opt"} <"$GIT_DIR/rebased-patches"
+ret=$?
 
-       rm -f "$GIT_DIR/rebased-patches"
-fi
+rm -f "$GIT_DIR/rebased-patches"
 
 if test 0 != $ret
 then
@@ -105,5 +83,3 @@ fi
 move_to_original_branch
 
 }
-# ... and then we call the whole thing.
-git_rebase__am
index 331c8dfeac3cac2fd2d9d9287d5c487669fe80a0..06a7b793075d7701b5dafa69b3576d13ba7c9de6 100644 (file)
@@ -81,6 +81,8 @@ rewritten_pending="$state_dir"/rewritten-pending
 # and leaves CR at the end instead.
 cr=$(printf "\015")
 
+empty_tree=$(git hash-object -t tree /dev/null)
+
 strategy_args=${strategy:+--strategy=$strategy}
 test -n "$strategy_opts" &&
 eval '
@@ -155,13 +157,19 @@ reschedule_last_action () {
 append_todo_help () {
        gettext "
 Commands:
-p, pick = use commit
-r, reword = use commit, but edit the commit message
-e, edit = use commit, but stop for amending
-s, squash = use commit, but meld into previous commit
-f, fixup = like \"squash\", but discard this commit's log message
-x, exec = run command (the rest of the line) using shell
-d, drop = remove commit
+p, pick <commit> = use commit
+r, reword <commit> = use commit, but edit the commit message
+e, edit <commit> = use commit, but stop for amending
+s, squash <commit> = use commit, but meld into previous commit
+f, fixup <commit> = like \"squash\", but discard this commit's log message
+x, exec <command> = run command (the rest of the line) using shell
+d, drop <commit> = remove commit
+l, label <label> = label current HEAD with a name
+t, reset <label> = reset HEAD to a label
+m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
+.       create a merge commit using the original merge commit's
+.       message (or the oneline, if no original merge commit was
+.       specified). Use -c <commit> to reword the commit message.
 
 These lines can be re-ordered; they are executed from top to bottom.
 " | git stripspace --comment-lines >>"$todo"
@@ -238,7 +246,7 @@ is_empty_commit() {
                die "$(eval_gettext "\$sha1: not a commit that can be picked")"
        }
        ptree=$(git rev-parse -q --verify "$1"^^{tree} 2>/dev/null) ||
-               ptree=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+               ptree=$empty_tree
        test "$tree" = "$ptree"
 }
 
@@ -285,7 +293,7 @@ pick_one () {
                pick_one_preserving_merges "$@" && return
        output eval git cherry-pick $allow_rerere_autoupdate $allow_empty_message \
                        ${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
-                       "$strategy_args" $empty_args $ff "$@"
+                       $signoff "$strategy_args" $empty_args $ff "$@"
 
        # If cherry-pick dies it leaves the to-be-picked commit unrecorded. Reschedule
        # previous task so this commit is not lost.
@@ -307,17 +315,14 @@ pick_one_preserving_merges () {
        esac
        sha1=$(git rev-parse $sha1)
 
-       if test -f "$state_dir"/current-commit
+       if test -f "$state_dir"/current-commit && test "$fast_forward" = t
        then
-               if test "$fast_forward" = t
-               then
-                       while read current_commit
-                       do
-                               git rev-parse HEAD > "$rewritten"/$current_commit
-                       done <"$state_dir"/current-commit
-                       rm "$state_dir"/current-commit ||
-                               die "$(gettext "Cannot write current commit's replacement sha1")"
-               fi
+               while read current_commit
+               do
+                       git rev-parse HEAD > "$rewritten"/$current_commit
+               done <"$state_dir"/current-commit
+               rm "$state_dir"/current-commit ||
+                       die "$(gettext "Cannot write current commit's replacement sha1")"
        fi
 
        echo $sha1 >> "$state_dir"/current-commit
@@ -527,10 +532,10 @@ do_pick () {
                # resolve before manually running git commit --amend then git
                # rebase --continue.
                git commit --allow-empty --allow-empty-message --amend \
-                          --no-post-rewrite -n -q -C $sha1 &&
+                          --no-post-rewrite -n -q -C $sha1 $signoff &&
                        pick_one -n $sha1 &&
                        git commit --allow-empty --allow-empty-message \
-                                  --amend --no-post-rewrite -n -q -C $sha1 \
+                                  --amend --no-post-rewrite -n -q -C $sha1 $signoff \
                                   ${gpg_sign_opt:+"$gpg_sign_opt"} ||
                                   die_with_patch $sha1 "$(eval_gettext "Could not apply \$sha1... \$rest")"
        else
@@ -743,37 +748,39 @@ get_missing_commit_check_level () {
        printf '%s' "$check_level" | tr 'A-Z' 'a-z'
 }
 
-# The whole contents of this file is run by dot-sourcing it from
-# inside a shell function.  It used to be that "return"s we see
-# below were not inside any function, and expected to return
-# to the function that dot-sourced us.
+# Initiate an action. If the cannot be any
+# further action it  may exec a command
+# or exit and not return.
 #
-# However, older (9.x) versions of FreeBSD /bin/sh misbehave on such a
-# construct and continue to run the statements that follow such a "return".
-# As a work-around, we introduce an extra layer of a function
-# here, and immediately call it after defining it.
-git_rebase__interactive () {
-
-case "$action" in
-continue)
-       if test ! -d "$rewritten"
-       then
-               exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
-                       --continue
-       fi
-       # do we have anything to commit?
-       if git diff-index --cached --quiet HEAD --
-       then
-               # Nothing to commit -- skip this commit
-
-               test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD ||
-               rm "$GIT_DIR"/CHERRY_PICK_HEAD ||
-               die "$(gettext "Could not remove CHERRY_PICK_HEAD")"
-       else
-               if ! test -f "$author_script"
+# TODO: Consider a cleaner return model so it
+# never exits and always return 0 if process
+# is complete.
+#
+# Parameter 1 is the action to initiate.
+#
+# Returns 0 if the action was able to complete
+# and if 1 if further processing is required.
+initiate_action () {
+       case "$1" in
+       continue)
+               if test ! -d "$rewritten"
+               then
+                       exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
+                               --continue
+               fi
+               # do we have anything to commit?
+               if git diff-index --cached --quiet HEAD --
                then
-                       gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
-                       die "$(eval_gettext "\
+                       # Nothing to commit -- skip this commit
+
+                       test ! -f "$GIT_DIR"/CHERRY_PICK_HEAD ||
+                       rm "$GIT_DIR"/CHERRY_PICK_HEAD ||
+                       die "$(gettext "Could not remove CHERRY_PICK_HEAD")"
+               else
+                       if ! test -f "$author_script"
+                       then
+                               gpg_sign_opt_quoted=${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")}
+                               die "$(eval_gettext "\
 You have staged changes in your working tree.
 If these changes are meant to be
 squashed into the previous commit, run:
@@ -788,88 +795,203 @@ In both cases, once you're done, continue with:
 
   git rebase --continue
 ")"
-               fi
-               . "$author_script" ||
-                       die "$(gettext "Error trying to find the author identity to amend commit")"
-               if test -f "$amend"
-               then
-                       current_head=$(git rev-parse --verify HEAD)
-                       test "$current_head" = $(cat "$amend") ||
-                       die "$(gettext "\
+                       fi
+                       . "$author_script" ||
+                               die "$(gettext "Error trying to find the author identity to amend commit")"
+                       if test -f "$amend"
+                       then
+                               current_head=$(git rev-parse --verify HEAD)
+                               test "$current_head" = $(cat "$amend") ||
+                               die "$(gettext "\
 You have uncommitted changes in your working tree. Please commit them
 first and then run 'git rebase --continue' again.")"
-                       do_with_author git commit --amend --no-verify -F "$msg" -e \
-                               ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
-                               die "$(gettext "Could not commit staged changes.")"
-               else
-                       do_with_author git commit --no-verify -F "$msg" -e \
-                               ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
-                               die "$(gettext "Could not commit staged changes.")"
+                               do_with_author git commit --amend --no-verify -F "$msg" -e \
+                                       ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
+                                       die "$(gettext "Could not commit staged changes.")"
+                       else
+                               do_with_author git commit --no-verify -F "$msg" -e \
+                                       ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message ||
+                                       die "$(gettext "Could not commit staged changes.")"
+                       fi
                fi
+
+               if test -r "$state_dir"/stopped-sha
+               then
+                       record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
+               fi
+
+               require_clean_work_tree "rebase"
+               do_rest
+               return 0
+               ;;
+       skip)
+               git rerere clear
+
+               if test ! -d "$rewritten"
+               then
+                       exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
+                               --continue
+               fi
+               do_rest
+               return 0
+               ;;
+       edit-todo)
+               git stripspace --strip-comments <"$todo" >"$todo".new
+               mv -f "$todo".new "$todo"
+               collapse_todo_ids
+               append_todo_help
+               gettext "
+You are editing the todo file of an ongoing interactive rebase.
+To continue rebase after editing, run:
+    git rebase --continue
+
+" | git stripspace --comment-lines >>"$todo"
+
+               git_sequence_editor "$todo" ||
+                       die "$(gettext "Could not execute editor")"
+               expand_todo_ids
+
+               exit
+               ;;
+       show-current-patch)
+               exec git show REBASE_HEAD --
+               ;;
+       *)
+               return 1 # continue
+               ;;
+       esac
+}
+
+setup_reflog_action () {
+       comment_for_reflog start
+
+       if test ! -z "$switch_to"
+       then
+               GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to"
+               output git checkout "$switch_to" -- ||
+                       die "$(eval_gettext "Could not checkout \$switch_to")"
+
+               comment_for_reflog start
        fi
+}
 
-       if test -r "$state_dir"/stopped-sha
+init_basic_state () {
+       orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")"
+       mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")"
+       rm -f "$(git rev-parse --git-path REBASE_HEAD)"
+
+       : > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")"
+       write_basic_state
+}
+
+init_revisions_and_shortrevisions () {
+       shorthead=$(git rev-parse --short $orig_head)
+       shortonto=$(git rev-parse --short $onto)
+       if test -z "$rebase_root"
+               # this is now equivalent to ! -z "$upstream"
        then
-               record_in_rewritten "$(cat "$state_dir"/stopped-sha)"
+               shortupstream=$(git rev-parse --short $upstream)
+               revisions=$upstream...$orig_head
+               shortrevisions=$shortupstream..$shorthead
+       else
+               revisions=$onto...$orig_head
+               shortrevisions=$shorthead
+               test -z "$squash_onto" ||
+               echo "$squash_onto" >"$state_dir"/squash-onto
        fi
+}
 
-       require_clean_work_tree "rebase"
-       do_rest
-       return 0
-       ;;
-skip)
-       git rerere clear
+complete_action() {
+       test -s "$todo" || echo noop >> "$todo"
+       test -z "$autosquash" || git rebase--helper --rearrange-squash || exit
+       test -n "$cmd" && git rebase--helper --add-exec-commands "$cmd"
 
+       todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
+       todocount=${todocount##* }
+
+cat >>"$todo" <<EOF
+
+$comment_char $(eval_ngettext \
+       "Rebase \$shortrevisions onto \$shortonto (\$todocount command)" \
+       "Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \
+       "$todocount")
+EOF
+       append_todo_help
+       gettext "
+       However, if you remove everything, the rebase will be aborted.
+
+       " | git stripspace --comment-lines >>"$todo"
+
+       if test -z "$keep_empty"
+       then
+               printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo"
+       fi
+
+
+       has_action "$todo" ||
+               return 2
+
+       cp "$todo" "$todo".backup
+       collapse_todo_ids
+       git_sequence_editor "$todo" ||
+               die_abort "$(gettext "Could not execute editor")"
+
+       has_action "$todo" ||
+               return 2
+
+       git rebase--helper --check-todo-list || {
+               ret=$?
+               checkout_onto
+               exit $ret
+       }
+
+       expand_todo_ids
+
+       test -d "$rewritten" || test -n "$force_rebase" ||
+       onto="$(git rebase--helper --skip-unnecessary-picks)" ||
+       die "Could not skip unnecessary pick commands"
+
+       checkout_onto
        if test ! -d "$rewritten"
        then
+               require_clean_work_tree "rebase"
                exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
                        --continue
        fi
        do_rest
-       return 0
-       ;;
-edit-todo)
-       git stripspace --strip-comments <"$todo" >"$todo".new
-       mv -f "$todo".new "$todo"
-       collapse_todo_ids
-       append_todo_help
-       gettext "
-You are editing the todo file of an ongoing interactive rebase.
-To continue rebase after editing, run:
-    git rebase --continue
+}
 
-" | git stripspace --comment-lines >>"$todo"
+git_rebase__interactive () {
+       initiate_action "$action"
+       ret=$?
+       if test $ret = 0; then
+               return 0
+       fi
 
-       git_sequence_editor "$todo" ||
-               die "$(gettext "Could not execute editor")"
-       expand_todo_ids
+       setup_reflog_action
+       init_basic_state
 
-       exit
-       ;;
-show-current-patch)
-       exec git show REBASE_HEAD --
-       ;;
-esac
+       init_revisions_and_shortrevisions
 
-comment_for_reflog start
+       git rebase--helper --make-script ${keep_empty:+--keep-empty} \
+               ${rebase_merges:+--rebase-merges} \
+               ${rebase_cousins:+--rebase-cousins} \
+               $revisions ${restrict_revision+^$restrict_revision} >"$todo" ||
+       die "$(gettext "Could not generate todo list")"
 
-if test ! -z "$switch_to"
-then
-       GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: checkout $switch_to"
-       output git checkout "$switch_to" -- ||
-               die "$(eval_gettext "Could not checkout \$switch_to")"
+       complete_action
+}
 
-       comment_for_reflog start
-fi
+git_rebase__interactive__preserve_merges () {
+       initiate_action "$action"
+       ret=$?
+       if test $ret = 0; then
+               return 0
+       fi
 
-orig_head=$(git rev-parse --verify HEAD) || die "$(gettext "No HEAD?")"
-mkdir -p "$state_dir" || die "$(eval_gettext "Could not create temporary \$state_dir")"
-rm -f "$(git rev-parse --git-path REBASE_HEAD)"
+       setup_reflog_action
+       init_basic_state
 
-: > "$state_dir"/interactive || die "$(gettext "Could not mark as interactive")"
-write_basic_state
-if test t = "$preserve_merges"
-then
        if test -z "$rebase_root"
        then
                mkdir "$rewritten" &&
@@ -883,41 +1005,17 @@ then
                echo $onto > "$rewritten"/root ||
                        die "$(gettext "Could not init rewritten commits")"
        fi
-       # No cherry-pick because our first pass is to determine
-       # parents to rewrite and skipping dropped commits would
-       # prematurely end our probe
-       merges_option=
-else
-       merges_option="--no-merges --cherry-pick"
-fi
-
-shorthead=$(git rev-parse --short $orig_head)
-shortonto=$(git rev-parse --short $onto)
-if test -z "$rebase_root"
-       # this is now equivalent to ! -z "$upstream"
-then
-       shortupstream=$(git rev-parse --short $upstream)
-       revisions=$upstream...$orig_head
-       shortrevisions=$shortupstream..$shorthead
-else
-       revisions=$onto...$orig_head
-       shortrevisions=$shorthead
-fi
-if test t != "$preserve_merges"
-then
-       git rebase--helper --make-script ${keep_empty:+--keep-empty} \
-               $revisions ${restrict_revision+^$restrict_revision} >"$todo" ||
-       die "$(gettext "Could not generate todo list")"
-else
+
+       init_revisions_and_shortrevisions
+
        format=$(git config --get rebase.instructionFormat)
        # the 'rev-list .. | sed' requires %m to parse; the instruction requires %H to parse
-       git rev-list $merges_option --format="%m%H ${format:-%s}" \
+       git rev-list --format="%m%H ${format:-%s}" \
                --reverse --left-right --topo-order \
                $revisions ${restrict_revision+^$restrict_revision} | \
                sed -n "s/^>//p" |
        while read -r sha1 rest
        do
-
                if test -z "$keep_empty" && is_empty_commit $sha1 && ! is_merge_commit $sha1
                then
                        comment_out="$comment_char "
@@ -944,11 +1042,8 @@ else
                        printf '%s\n' "${comment_out}pick $sha1 $rest" >>"$todo"
                fi
        done
-fi
 
-# Watch for commits that been dropped by --cherry-pick
-if test t = "$preserve_merges"
-then
+       # Watch for commits that been dropped by --cherry-pick
        mkdir "$dropped"
        # Save all non-cherry-picked changes
        git rev-list $revisions --left-right --cherry-pick | \
@@ -971,66 +1066,6 @@ then
                        rm "$rewritten"/$rev
                fi
        done
-fi
-
-test -s "$todo" || echo noop >> "$todo"
-test -z "$autosquash" || git rebase--helper --rearrange-squash || exit
-test -n "$cmd" && git rebase--helper --add-exec-commands "$cmd"
-
-todocount=$(git stripspace --strip-comments <"$todo" | wc -l)
-todocount=${todocount##* }
-
-cat >>"$todo" <<EOF
-
-$comment_char $(eval_ngettext \
-       "Rebase \$shortrevisions onto \$shortonto (\$todocount command)" \
-       "Rebase \$shortrevisions onto \$shortonto (\$todocount commands)" \
-       "$todocount")
-EOF
-append_todo_help
-gettext "
-However, if you remove everything, the rebase will be aborted.
-
-" | git stripspace --comment-lines >>"$todo"
-
-if test -z "$keep_empty"
-then
-       printf '%s\n' "$comment_char $(gettext "Note that empty commits are commented out")" >>"$todo"
-fi
-
-
-has_action "$todo" ||
-       return 2
-
-cp "$todo" "$todo".backup
-collapse_todo_ids
-git_sequence_editor "$todo" ||
-       die_abort "$(gettext "Could not execute editor")"
-
-has_action "$todo" ||
-       return 2
-
-git rebase--helper --check-todo-list || {
-       ret=$?
-       checkout_onto
-       exit $ret
-}
-
-expand_todo_ids
-
-test -d "$rewritten" || test -n "$force_rebase" ||
-onto="$(git rebase--helper --skip-unnecessary-picks)" ||
-die "Could not skip unnecessary pick commands"
-
-checkout_onto
-if test -z "$rebase_root" && test ! -d "$rewritten"
-then
-       require_clean_work_tree "rebase"
-       exec git rebase--helper ${force_rebase:+--no-ff} $allow_empty_message \
-               --continue
-fi
-do_rest
 
+       complete_action
 }
-# ... and then we call the whole thing.
-git_rebase__interactive
index ceb715453cc9eba0b6e91abfd2ea3863e74f3e05..cf4c0422148935906ad939c5351652a1531e5f0d 100644 (file)
@@ -27,7 +27,7 @@ continue_merge () {
        cmt=$(cat "$state_dir/current")
        if ! git diff-index --quiet --ignore-submodules HEAD --
        then
-               if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} $allow_empty_message \
+               if ! git commit ${gpg_sign_opt:+"$gpg_sign_opt"} $signoff $allow_empty_message \
                        --no-verify -C "$cmt"
                then
                        echo "Commit failed, please do not call \"git commit\""
@@ -104,15 +104,6 @@ finish_rb_merge () {
        say All done.
 }
 
-# The whole contents of this file is run by dot-sourcing it from
-# inside a shell function.  It used to be that "return"s we see
-# below were not inside any function, and expected to return
-# to the function that dot-sourced us.
-#
-# However, older (9.x) versions of FreeBSD /bin/sh misbehave on such a
-# construct and continue to run the statements that follow such a "return".
-# As a work-around, we introduce an extra layer of a function
-# here, and immediately call it after defining it.
 git_rebase__merge () {
 
 case "$action" in
@@ -171,5 +162,3 @@ done
 finish_rb_merge
 
 }
-# ... and then we call the whole thing.
-git_rebase__merge
index a1f6e5de6a3ed1fe9a6217a136611682f3db6582..40be59ecc4704da05a0e153f1709d4af2c62cd18 100755 (executable)
@@ -17,6 +17,7 @@ q,quiet!           be quiet. implies --no-stat
 autostash          automatically stash/stash pop before and after
 fork-point         use 'merge-base --fork-point' to refine upstream
 onto=!             rebase onto given branch instead of upstream
+r,rebase-merges?   try to rebase merges instead of skipping them
 p,preserve-merges! try to recreate merges instead of ignoring them
 s,strategy=!       use the given merge strategy
 no-ff!             cherry-pick all commits, even if unchanged
@@ -62,6 +63,7 @@ $(gettext 'Resolve all conflicts manually, mark them as resolved with
 You can instead skip this commit: run "git rebase --skip".
 To abort and get back to the state before "git rebase", run "git rebase --abort".')
 "
+squash_onto=
 unset onto
 unset restrict_revision
 cmd=
@@ -88,10 +90,13 @@ type=
 state_dir=
 # One of {'', continue, skip, abort}, as parsed from command line
 action=
+rebase_merges=
+rebase_cousins=
 preserve_merges=
 autosquash=
 keep_empty=
 allow_empty_message=
+signoff=
 test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
 case "$(git config --bool commit.gpgsign)" in
 true)  gpg_sign_opt=-S ;;
@@ -121,6 +126,10 @@ read_basic_state () {
                allow_rerere_autoupdate="$(cat "$state_dir"/allow_rerere_autoupdate)"
        test -f "$state_dir"/gpg_sign_opt &&
                gpg_sign_opt="$(cat "$state_dir"/gpg_sign_opt)"
+       test -f "$state_dir"/signoff && {
+               signoff="$(cat "$state_dir"/signoff)"
+               force_rebase=t
+       }
 }
 
 write_basic_state () {
@@ -135,6 +144,7 @@ write_basic_state () {
        test -n "$allow_rerere_autoupdate" && echo "$allow_rerere_autoupdate" > \
                "$state_dir"/allow_rerere_autoupdate
        test -n "$gpg_sign_opt" && echo "$gpg_sign_opt" > "$state_dir"/gpg_sign_opt
+       test -n "$signoff" && echo "$signoff" >"$state_dir"/signoff
 }
 
 output () {
@@ -197,6 +207,7 @@ run_specific_rebase () {
                autosquash=
        fi
        . git-rebase--$type
+       git_rebase__$type${preserve_merges:+__preserve_merges}
        ret=$?
        if test $ret -eq 0
        then
@@ -269,6 +280,22 @@ do
        --allow-empty-message)
                allow_empty_message=--allow-empty-message
                ;;
+       --no-keep-empty)
+               keep_empty=
+               ;;
+       --rebase-merges)
+               rebase_merges=t
+               test -z "$interactive_rebase" && interactive_rebase=implied
+               ;;
+       --rebase-merges=*)
+               rebase_merges=t
+               case "${1#*=}" in
+               rebase-cousins) rebase_cousins=t;;
+               no-rebase-cousins) rebase_cousins=;;
+               *) die "Unknown mode: $1";;
+               esac
+               test -z "$interactive_rebase" && interactive_rebase=implied
+               ;;
        --preserve-merges)
                preserve_merges=t
                test -z "$interactive_rebase" && interactive_rebase=implied
@@ -331,7 +358,13 @@ do
        --ignore-whitespace)
                git_am_opt="$git_am_opt $1"
                ;;
-       --committer-date-is-author-date|--ignore-date|--signoff|--no-signoff)
+       --signoff)
+               signoff=--signoff
+               ;;
+       --no-signoff)
+               signoff=
+               ;;
+       --committer-date-is-author-date|--ignore-date)
                git_am_opt="$git_am_opt $1"
                force_rebase=t
                ;;
@@ -447,6 +480,11 @@ then
        test -z "$interactive_rebase" && interactive_rebase=implied
 fi
 
+if test -n "$keep_empty"
+then
+       test -z "$interactive_rebase" && interactive_rebase=implied
+fi
+
 if test -n "$interactive_rebase"
 then
        type=interactive
@@ -465,6 +503,14 @@ then
        git_format_patch_opt="$git_format_patch_opt --progress"
 fi
 
+if test -n "$signoff"
+then
+       test -n "$preserve_merges" &&
+               die "$(gettext "error: cannot combine '--signoff' with '--preserve-merges'")"
+       git_am_opt="$git_am_opt $signoff"
+       force_rebase=t
+fi
+
 if test -z "$rebase_root"
 then
        case "$#" in
index 2fa7818ca9a8ac7363d17aef17b864f7361b3eb8..8ec70e58ed5c4caace7701549038b63f9a3e9aad 100755 (executable)
@@ -1330,9 +1330,14 @@ sub file_name_is_absolute {
        return File::Spec::Functions::file_name_is_absolute($path);
 }
 
-# Returns 1 if the message was sent, and 0 otherwise.
-# In actuality, the whole program dies when there
-# is an error sending a message.
+# Prepares the email, then asks the user what to do.
+#
+# If the user chooses to send the email, it's sent and 1 is returned.
+# If the user chooses not to send the email, 0 is returned.
+# If the user decides they want to make further edits, -1 is returned and the
+# caller is expected to call send_message again after the edits are performed.
+#
+# If an error occurs sending the email, this just dies.
 
 sub send_message {
        my @recipients = unique_email_list(@to);
@@ -1404,15 +1409,17 @@ Message-Id: $message_id
 
 EOF
                }
-               # TRANSLATORS: Make sure to include [y] [n] [q] [a] in your
+               # TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
                # translation. The program will only accept English input
                # at this point.
-               $_ = ask(__("Send this email? ([y]es|[n]o|[q]uit|[a]ll): "),
-                        valid_re => qr/^(?:yes|y|no|n|quit|q|all|a)/i,
+               $_ = ask(__("Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "),
+                        valid_re => qr/^(?:yes|y|no|n|edit|e|quit|q|all|a)/i,
                         default => $ask_default);
                die __("Send this email reply required") unless defined $_;
                if (/^n/i) {
                        return 0;
+               } elsif (/^e/i) {
+                       return -1;
                } elsif (/^q/i) {
                        cleanup_compose_files();
                        exit(0);
@@ -1552,7 +1559,12 @@ $references = $initial_in_reply_to || '';
 $subject = $initial_subject;
 $message_num = 0;
 
-foreach my $t (@files) {
+# Prepares the email, prompts the user, sends it out
+# Returns 0 if an edit was done and the function should be called again, or 1
+# otherwise.
+sub process_file {
+       my ($t) = @_;
+
        open my $fh, "<", $t or die sprintf(__("can't open file %s"), $t);
 
        my $author = undef;
@@ -1642,10 +1654,15 @@ foreach my $t (@files) {
                        elsif (/^Content-Transfer-Encoding: (.*)/i) {
                                $xfer_encoding = $1 if not defined $xfer_encoding;
                        }
+                       elsif (/^In-Reply-To: (.*)/i) {
+                               $in_reply_to = $1;
+                       }
+                       elsif (/^References: (.*)/i) {
+                               $references = $1;
+                       }
                        elsif (!/^Date:\s/i && /^[-A-Za-z]+:\s+\S/) {
                                push @xh, $_;
                        }
-
                } else {
                        # In the traditional
                        # "send lots of email" format,
@@ -1755,6 +1772,10 @@ foreach my $t (@files) {
        }
 
        my $message_was_sent = send_message();
+       if ($message_was_sent == -1) {
+               do_edit($t);
+               return 0;
+       }
 
        # set up for the next message
        if ($thread && $message_was_sent &&
@@ -1776,6 +1797,14 @@ foreach my $t (@files) {
                undef $auth;
                sleep($relogin_delay) if defined $relogin_delay;
        }
+
+       return 1;
+}
+
+foreach my $t (@files) {
+       while (!process_file($t)) {
+               # user edited the file
+       }
 }
 
 # Execute a command (e.g. $to_cmd) to get a list of email addresses
index fc8f8ae6401dddcceaa82f9e9c748f5c185536d6..94793c1a913abf569ff9101d935c355b9eb27648 100755 (executable)
@@ -39,7 +39,7 @@ fi
 no_changes () {
        git diff-index --quiet --cached HEAD --ignore-submodules -- "$@" &&
        git diff-files --quiet --ignore-submodules -- "$@" &&
-       (test -z "$untracked" || test -z "$(untracked_files)")
+       (test -z "$untracked" || test -z "$(untracked_files "$@")")
 }
 
 untracked_files () {
@@ -315,16 +315,18 @@ push_stash () {
        if test -z "$patch_mode"
        then
                test "$untracked" = "all" && CLEAN_X_OPTION=-x || CLEAN_X_OPTION=
-               if test -n "$untracked"
+               if test -n "$untracked" && test $# = 0
                then
-                       git clean --force --quiet -d $CLEAN_X_OPTION -- "$@"
+                       git clean --force --quiet -d $CLEAN_X_OPTION
                fi
 
                if test $# != 0
                then
-                       git add -u -- "$@" |
-                       git checkout-index -z --force --stdin
-                       git diff-index -p --cached --binary HEAD -- "$@" | git apply --index -R
+                       test -z "$untracked" && UPDATE_OPTION="-u" || UPDATE_OPTION=
+                       test "$untracked" = "all" && FORCE_OPTION="--force" || FORCE_OPTION=
+                       git add $UPDATE_OPTION $FORCE_OPTION -- "$@"
+                       git diff-index -p --cached --binary HEAD -- "$@" |
+                       git apply --index -R
                else
                        git reset --hard -q
                fi
index 73594e0e35d094a329fecbe3e59e2aac6630ad6c..74f5fe6a86e02550aa227d6121edd0486f894d18 100755 (executable)
@@ -43,6 +43,7 @@ prefix=
 custom_name=
 depth=
 progress=
+dissociate=
 
 die_if_unmatched ()
 {
@@ -118,6 +119,9 @@ cmd_add()
                -q|--quiet)
                        GIT_QUIET=1
                        ;;
+               --progress)
+                       progress=1
+                       ;;
                --reference)
                        case "$2" in '') usage ;; esac
                        reference_path=$2
@@ -126,6 +130,9 @@ cmd_add()
                --reference=*)
                        reference_path="${1#--reference=}"
                        ;;
+               --dissociate)
+                       dissociate=1
+                       ;;
                --name)
                        case "$2" in '') usage ;; esac
                        custom_name=$2
@@ -261,7 +268,7 @@ or you are unsure what this means choose another name with the '--name' option."
                                eval_gettextln "Reactivating local git directory for submodule '\$sm_name'."
                        fi
                fi
-               git submodule--helper clone ${GIT_QUIET:+--quiet} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${depth:+"$depth"} || exit
+               git submodule--helper clone ${GIT_QUIET:+--quiet} ${progress:+"--progress"} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${dissociate:+"--dissociate"} ${depth:+"$depth"} || exit
                (
                        sanitize_submodule_env
                        cd "$sm_path" &&
@@ -471,7 +478,7 @@ cmd_update()
                        GIT_QUIET=1
                        ;;
                --progress)
-                       progress="--progress"
+                       progress=1
                        ;;
                -i|--init)
                        init=1
@@ -500,6 +507,9 @@ cmd_update()
                --reference=*)
                        reference="$1"
                        ;;
+               --dissociate)
+                       dissociate=1
+                       ;;
                -m|--merge)
                        update="merge"
                        ;;
@@ -552,15 +562,16 @@ cmd_update()
 
        {
        git submodule--helper update-clone ${GIT_QUIET:+--quiet} \
-               ${progress:+"$progress"} \
+               ${progress:+"--progress"} \
                ${wt_prefix:+--prefix "$wt_prefix"} \
                ${prefix:+--recursive-prefix "$prefix"} \
                ${update:+--update "$update"} \
                ${reference:+"$reference"} \
+               ${dissociate:+"--dissociate"} \
                ${depth:+--depth "$depth"} \
                ${require_init:+--require-init} \
-               ${recommend_shallow:+"$recommend_shallow"} \
-               ${jobs:+$jobs} \
+               $recommend_shallow \
+               $jobs \
                "$@" || echo "#unmatched" $?
        } | {
        err=
@@ -625,7 +636,7 @@ cmd_update()
                                # is not reachable from a ref.
                                is_tip_reachable "$sm_path" "$sha1" ||
                                fetch_in_submodule "$sm_path" $depth ||
-                               die "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'")"
+                               say "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'")"
 
                                # Now we tried the usual fetch, but $sha1 may
                                # not be reachable from any of the refs
index a6b6c3e40c180e58186f9ef8af5c6fd6fc654080..050f2a36f414f147f3bde3cc9f69639d5a36a975 100755 (executable)
@@ -374,7 +374,8 @@ version() if $_version;
 usage(1) unless defined $cmd;
 load_authors() if $_authors;
 if (defined $_authors_prog) {
-       $_authors_prog = "'" . File::Spec->rel2abs($_authors_prog) . "'";
+       my $abs_file = File::Spec->rel2abs($_authors_prog);
+       $_authors_prog = "'" . $abs_file . "'" if -x $abs_file;
 }
 
 unless ($cmd =~ /^(?:clone|init|multi-init|commit-diff)$/) {
diff --git a/git.c b/git.c
index ceaa58ef40e536f1290cce3ad1223004063e41a6..c2f48d53dd4aaba0752aa5f2e6633242d320b248 100644 (file)
--- a/git.c
+++ b/git.c
@@ -1,13 +1,32 @@
 #include "builtin.h"
 #include "config.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "help.h"
 #include "run-command.h"
+#include "alias.h"
+
+#define RUN_SETUP              (1<<0)
+#define RUN_SETUP_GENTLY       (1<<1)
+#define USE_PAGER              (1<<2)
+/*
+ * require working tree to be present -- anything uses this needs
+ * RUN_SETUP for reading from the configuration file.
+ */
+#define NEED_WORK_TREE         (1<<3)
+#define SUPPORT_SUPER_PREFIX   (1<<4)
+#define DELAY_PAGER_CONFIG     (1<<5)
+#define NO_PARSEOPT            (1<<6) /* parse-options is not used */
+
+struct cmd_struct {
+       const char *cmd;
+       int (*fn)(int, const char **, const char *);
+       unsigned int option;
+};
 
 const char git_usage_string[] =
        N_("git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
           "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-          "           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+          "           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n"
           "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
           "           <command> [<args>]");
 
@@ -18,7 +37,66 @@ const char git_more_info_string[] =
 
 static int use_pager = -1;
 
-static void list_builtins(void);
+static void list_builtins(struct string_list *list, unsigned int exclude_option);
+
+static void exclude_helpers_from_list(struct string_list *list)
+{
+       int i = 0;
+
+       while (i < list->nr) {
+               if (strstr(list->items[i].string, "--"))
+                       unsorted_string_list_delete_item(list, i, 0);
+               else
+                       i++;
+       }
+}
+
+static int match_token(const char *spec, int len, const char *token)
+{
+       int token_len = strlen(token);
+
+       return len == token_len && !strncmp(spec, token, token_len);
+}
+
+static int list_cmds(const char *spec)
+{
+       struct string_list list = STRING_LIST_INIT_DUP;
+       int i;
+
+       while (*spec) {
+               const char *sep = strchrnul(spec, ',');
+               int len = sep - spec;
+
+               if (match_token(spec, len, "builtins"))
+                       list_builtins(&list, 0);
+               else if (match_token(spec, len, "main"))
+                       list_all_main_cmds(&list);
+               else if (match_token(spec, len, "others"))
+                       list_all_other_cmds(&list);
+               else if (match_token(spec, len, "nohelpers"))
+                       exclude_helpers_from_list(&list);
+               else if (match_token(spec, len, "alias"))
+                       list_aliases(&list);
+               else if (match_token(spec, len, "config"))
+                       list_cmds_by_config(&list);
+               else if (len > 5 && !strncmp(spec, "list-", 5)) {
+                       struct strbuf sb = STRBUF_INIT;
+
+                       strbuf_add(&sb, spec + 5, len - 5);
+                       list_cmds_by_category(&list, sb.buf);
+                       strbuf_release(&sb);
+               }
+               else
+                       die(_("unsupported command listing type '%s'"), spec);
+               spec += len;
+               if (*spec == ',')
+                       spec++;
+       }
+       for (i = 0; i < list.nr; i++)
+               puts(list.items[i].string);
+       string_list_clear(&list, 0);
+       return 0;
+}
 
 static void commit_pager_choice(void) {
        switch (use_pager) {
@@ -65,7 +143,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
                 */
                if (skip_prefix(cmd, "--exec-path", &cmd)) {
                        if (*cmd == '=')
-                               git_set_argv_exec_path(cmd + 1);
+                               git_set_exec_path(cmd + 1);
                        else {
                                puts(git_exec_path());
                                exit(0);
@@ -81,7 +159,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
                        exit(0);
                } else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) {
                        use_pager = 1;
-               } else if (!strcmp(cmd, "--no-pager")) {
+               } else if (!strcmp(cmd, "-P") || !strcmp(cmd, "--no-pager")) {
                        use_pager = 0;
                        if (envchanged)
                                *envchanged = 1;
@@ -205,9 +283,19 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
                        }
                        (*argv)++;
                        (*argc)--;
-               } else if (!strcmp(cmd, "--list-builtins")) {
-                       list_builtins();
-                       exit(0);
+               } else if (skip_prefix(cmd, "--list-cmds=", &cmd)) {
+                       if (!strcmp(cmd, "parseopt")) {
+                               struct string_list list = STRING_LIST_INIT_DUP;
+                               int i;
+
+                               list_builtins(&list, NO_PARSEOPT);
+                               for (i = 0; i < list.nr; i++)
+                                       printf("%s ", list.items[i].string);
+                               string_list_clear(&list, 0);
+                               exit(0);
+                       } else {
+                               exit(list_cmds(cmd));
+                       }
                } else {
                        fprintf(stderr, _("unknown option: %s\n"), cmd);
                        usage(git_usage_string);
@@ -288,23 +376,6 @@ static int handle_alias(int *argcp, const char ***argv)
        return ret;
 }
 
-#define RUN_SETUP              (1<<0)
-#define RUN_SETUP_GENTLY       (1<<1)
-#define USE_PAGER              (1<<2)
-/*
- * require working tree to be present -- anything uses this needs
- * RUN_SETUP for reading from the configuration file.
- */
-#define NEED_WORK_TREE         (1<<3)
-#define SUPPORT_SUPER_PREFIX   (1<<4)
-#define DELAY_PAGER_CONFIG     (1<<5)
-
-struct cmd_struct {
-       const char *cmd;
-       int (*fn)(int, const char **, const char *);
-       int option;
-};
-
 static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 {
        int status, help;
@@ -367,18 +438,18 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv)
 static struct cmd_struct commands[] = {
        { "add", cmd_add, RUN_SETUP | NEED_WORK_TREE },
        { "am", cmd_am, RUN_SETUP | NEED_WORK_TREE },
-       { "annotate", cmd_annotate, RUN_SETUP },
+       { "annotate", cmd_annotate, RUN_SETUP | NO_PARSEOPT },
        { "apply", cmd_apply, RUN_SETUP_GENTLY },
        { "archive", cmd_archive, RUN_SETUP_GENTLY },
        { "bisect--helper", cmd_bisect__helper, RUN_SETUP },
        { "blame", cmd_blame, RUN_SETUP },
        { "branch", cmd_branch, RUN_SETUP | DELAY_PAGER_CONFIG },
-       { "bundle", cmd_bundle, RUN_SETUP_GENTLY },
+       { "bundle", cmd_bundle, RUN_SETUP_GENTLY | NO_PARSEOPT },
        { "cat-file", cmd_cat_file, RUN_SETUP },
        { "check-attr", cmd_check_attr, RUN_SETUP },
        { "check-ignore", cmd_check_ignore, RUN_SETUP | NEED_WORK_TREE },
        { "check-mailmap", cmd_check_mailmap, RUN_SETUP },
-       { "check-ref-format", cmd_check_ref_format },
+       { "check-ref-format", cmd_check_ref_format, NO_PARSEOPT  },
        { "checkout", cmd_checkout, RUN_SETUP | NEED_WORK_TREE },
        { "checkout-index", cmd_checkout_index,
                RUN_SETUP | NEED_WORK_TREE},
@@ -388,30 +459,31 @@ static struct cmd_struct commands[] = {
        { "clone", cmd_clone },
        { "column", cmd_column, RUN_SETUP_GENTLY },
        { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE },
-       { "commit-tree", cmd_commit_tree, RUN_SETUP },
+       { "commit-graph", cmd_commit_graph, RUN_SETUP },
+       { "commit-tree", cmd_commit_tree, RUN_SETUP | NO_PARSEOPT },
        { "config", cmd_config, RUN_SETUP_GENTLY | DELAY_PAGER_CONFIG },
        { "count-objects", cmd_count_objects, RUN_SETUP },
-       { "credential", cmd_credential, RUN_SETUP_GENTLY },
+       { "credential", cmd_credential, RUN_SETUP_GENTLY | NO_PARSEOPT },
        { "describe", cmd_describe, RUN_SETUP },
-       { "diff", cmd_diff },
-       { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE },
-       { "diff-index", cmd_diff_index, RUN_SETUP },
-       { "diff-tree", cmd_diff_tree, RUN_SETUP },
+       { "diff", cmd_diff, NO_PARSEOPT },
+       { "diff-files", cmd_diff_files, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
+       { "diff-index", cmd_diff_index, RUN_SETUP | NO_PARSEOPT },
+       { "diff-tree", cmd_diff_tree, RUN_SETUP | NO_PARSEOPT },
        { "difftool", cmd_difftool, RUN_SETUP | NEED_WORK_TREE },
        { "fast-export", cmd_fast_export, RUN_SETUP },
        { "fetch", cmd_fetch, RUN_SETUP },
-       { "fetch-pack", cmd_fetch_pack, RUN_SETUP },
+       { "fetch-pack", cmd_fetch_pack, RUN_SETUP | NO_PARSEOPT },
        { "fmt-merge-msg", cmd_fmt_merge_msg, RUN_SETUP },
        { "for-each-ref", cmd_for_each_ref, RUN_SETUP },
        { "format-patch", cmd_format_patch, RUN_SETUP },
        { "fsck", cmd_fsck, RUN_SETUP },
        { "fsck-objects", cmd_fsck, RUN_SETUP },
        { "gc", cmd_gc, RUN_SETUP },
-       { "get-tar-commit-id", cmd_get_tar_commit_id },
+       { "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT },
        { "grep", cmd_grep, RUN_SETUP_GENTLY },
        { "hash-object", cmd_hash_object },
        { "help", cmd_help },
-       { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY },
+       { "index-pack", cmd_index_pack, RUN_SETUP_GENTLY | NO_PARSEOPT },
        { "init", cmd_init_db },
        { "init-db", cmd_init_db },
        { "interpret-trailers", cmd_interpret_trailers, RUN_SETUP_GENTLY },
@@ -419,27 +491,27 @@ static struct cmd_struct commands[] = {
        { "ls-files", cmd_ls_files, RUN_SETUP },
        { "ls-remote", cmd_ls_remote, RUN_SETUP_GENTLY },
        { "ls-tree", cmd_ls_tree, RUN_SETUP },
-       { "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY },
-       { "mailsplit", cmd_mailsplit },
+       { "mailinfo", cmd_mailinfo, RUN_SETUP_GENTLY | NO_PARSEOPT },
+       { "mailsplit", cmd_mailsplit, NO_PARSEOPT },
        { "merge", cmd_merge, RUN_SETUP | NEED_WORK_TREE },
        { "merge-base", cmd_merge_base, RUN_SETUP },
        { "merge-file", cmd_merge_file, RUN_SETUP_GENTLY },
-       { "merge-index", cmd_merge_index, RUN_SETUP },
-       { "merge-ours", cmd_merge_ours, RUN_SETUP },
-       { "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-       { "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-       { "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-       { "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE },
-       { "merge-tree", cmd_merge_tree, RUN_SETUP },
-       { "mktag", cmd_mktag, RUN_SETUP },
+       { "merge-index", cmd_merge_index, RUN_SETUP | NO_PARSEOPT },
+       { "merge-ours", cmd_merge_ours, RUN_SETUP | NO_PARSEOPT },
+       { "merge-recursive", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
+       { "merge-recursive-ours", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
+       { "merge-recursive-theirs", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
+       { "merge-subtree", cmd_merge_recursive, RUN_SETUP | NEED_WORK_TREE | NO_PARSEOPT },
+       { "merge-tree", cmd_merge_tree, RUN_SETUP | NO_PARSEOPT },
+       { "mktag", cmd_mktag, RUN_SETUP | NO_PARSEOPT },
        { "mktree", cmd_mktree, RUN_SETUP },
        { "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
        { "name-rev", cmd_name_rev, RUN_SETUP },
        { "notes", cmd_notes, RUN_SETUP },
        { "pack-objects", cmd_pack_objects, RUN_SETUP },
-       { "pack-redundant", cmd_pack_redundant, RUN_SETUP },
+       { "pack-redundant", cmd_pack_redundant, RUN_SETUP | NO_PARSEOPT },
        { "pack-refs", cmd_pack_refs, RUN_SETUP },
-       { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY },
+       { "patch-id", cmd_patch_id, RUN_SETUP_GENTLY | NO_PARSEOPT },
        { "pickaxe", cmd_blame, RUN_SETUP },
        { "prune", cmd_prune, RUN_SETUP },
        { "prune-packed", cmd_prune_packed, RUN_SETUP },
@@ -450,17 +522,18 @@ static struct cmd_struct commands[] = {
        { "receive-pack", cmd_receive_pack },
        { "reflog", cmd_reflog, RUN_SETUP },
        { "remote", cmd_remote, RUN_SETUP },
-       { "remote-ext", cmd_remote_ext },
-       { "remote-fd", cmd_remote_fd },
+       { "remote-ext", cmd_remote_ext, NO_PARSEOPT },
+       { "remote-fd", cmd_remote_fd, NO_PARSEOPT },
        { "repack", cmd_repack, RUN_SETUP },
        { "replace", cmd_replace, RUN_SETUP },
        { "rerere", cmd_rerere, RUN_SETUP },
        { "reset", cmd_reset, RUN_SETUP },
-       { "rev-list", cmd_rev_list, RUN_SETUP },
-       { "rev-parse", cmd_rev_parse },
+       { "rev-list", cmd_rev_list, RUN_SETUP | NO_PARSEOPT },
+       { "rev-parse", cmd_rev_parse, NO_PARSEOPT },
        { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
        { "rm", cmd_rm, RUN_SETUP },
        { "send-pack", cmd_send_pack, RUN_SETUP },
+       { "serve", cmd_serve, RUN_SETUP },
        { "shortlog", cmd_shortlog, RUN_SETUP_GENTLY | USE_PAGER },
        { "show", cmd_show, RUN_SETUP },
        { "show-branch", cmd_show_branch, RUN_SETUP },
@@ -468,23 +541,24 @@ static struct cmd_struct commands[] = {
        { "stage", cmd_add, RUN_SETUP | NEED_WORK_TREE },
        { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE },
        { "stripspace", cmd_stripspace },
-       { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX},
+       { "submodule--helper", cmd_submodule__helper, RUN_SETUP | SUPPORT_SUPER_PREFIX | NO_PARSEOPT },
        { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP },
        { "tag", cmd_tag, RUN_SETUP | DELAY_PAGER_CONFIG },
-       { "unpack-file", cmd_unpack_file, RUN_SETUP },
-       { "unpack-objects", cmd_unpack_objects, RUN_SETUP },
+       { "unpack-file", cmd_unpack_file, RUN_SETUP | NO_PARSEOPT },
+       { "unpack-objects", cmd_unpack_objects, RUN_SETUP | NO_PARSEOPT },
        { "update-index", cmd_update_index, RUN_SETUP },
        { "update-ref", cmd_update_ref, RUN_SETUP },
        { "update-server-info", cmd_update_server_info, RUN_SETUP },
-       { "upload-archive", cmd_upload_archive },
-       { "upload-archive--writer", cmd_upload_archive_writer },
-       { "var", cmd_var, RUN_SETUP_GENTLY },
+       { "upload-archive", cmd_upload_archive, NO_PARSEOPT },
+       { "upload-archive--writer", cmd_upload_archive_writer, NO_PARSEOPT },
+       { "upload-pack", cmd_upload_pack },
+       { "var", cmd_var, RUN_SETUP_GENTLY | NO_PARSEOPT },
        { "verify-commit", cmd_verify_commit, RUN_SETUP },
        { "verify-pack", cmd_verify_pack },
        { "verify-tag", cmd_verify_tag, RUN_SETUP },
        { "version", cmd_version },
        { "whatchanged", cmd_whatchanged, RUN_SETUP },
-       { "worktree", cmd_worktree, RUN_SETUP },
+       { "worktree", cmd_worktree, RUN_SETUP | NO_PARSEOPT },
        { "write-tree", cmd_write_tree, RUN_SETUP },
 };
 
@@ -504,11 +578,15 @@ int is_builtin(const char *s)
        return !!get_builtin(s);
 }
 
-static void list_builtins(void)
+static void list_builtins(struct string_list *out, unsigned int exclude_option)
 {
        int i;
-       for (i = 0; i < ARRAY_SIZE(commands); i++)
-               printf("%s\n", commands[i].cmd);
+       for (i = 0; i < ARRAY_SIZE(commands); i++) {
+               if (exclude_option &&
+                   (commands[i].option & exclude_option))
+                       continue;
+               string_list_append(out, commands[i].cmd);
+       }
 }
 
 #ifdef STRIP_EXTENSION
index 4feacf16e5bcd93dcde4a2ea769f6b61ca369593..0647bd6348cdedd0e32f30ed23934d390eae4122 100644 (file)
@@ -101,22 +101,26 @@ void print_signature_buffer(const struct signature_check *sigc, unsigned flags)
                fputs(output, stderr);
 }
 
-/*
- * Look at GPG signed content (e.g. a signed tag object), whose
- * payload is followed by a detached signature on it.  Return the
- * offset where the embedded detached signature begins, or the end of
- * the data when there is no such signature.
- */
-size_t parse_signature(const char *buf, unsigned long size)
+static int is_gpg_start(const char *line)
+{
+       return starts_with(line, PGP_SIGNATURE) ||
+               starts_with(line, PGP_MESSAGE);
+}
+
+size_t parse_signature(const char *buf, size_t size)
 {
-       char *eol;
        size_t len = 0;
-       while (len < size && !starts_with(buf + len, PGP_SIGNATURE) &&
-                       !starts_with(buf + len, PGP_MESSAGE)) {
+       size_t match = size;
+       while (len < size) {
+               const char *eol;
+
+               if (is_gpg_start(buf + len))
+                       match = len;
+
                eol = memchr(buf + len, '\n', size - len);
                len += eol ? eol - (buf + len) + 1 : size - len;
        }
-       return len;
+       return match;
 }
 
 void set_signing_key(const char *key)
@@ -128,13 +132,19 @@ void set_signing_key(const char *key)
 int git_gpg_config(const char *var, const char *value, void *cb)
 {
        if (!strcmp(var, "user.signingkey")) {
+               if (!value)
+                       return config_error_nonbool(var);
                set_signing_key(value);
+               return 0;
        }
+
        if (!strcmp(var, "gpg.program")) {
                if (!value)
                        return config_error_nonbool(var);
                gpg_program = xstrdup(value);
+               return 0;
        }
+
        return 0;
 }
 
@@ -145,12 +155,6 @@ const char *get_signing_key(void)
        return git_committer_info(IDENT_STRICT|IDENT_NO_DATE);
 }
 
-/*
- * Create a detached signature for the contents of "buffer" and append
- * it after "signature"; "buffer" and "signature" can be the same
- * strbuf instance, which would cause the detached signature appended
- * at the end.
- */
 int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key)
 {
        struct child_process gpg = CHILD_PROCESS_INIT;
@@ -192,11 +196,6 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig
        return 0;
 }
 
-/*
- * Run "gpg" to see if the payload matches the detached signature.
- * gpg_output, when set, receives the diagnostic output from GPG.
- * gpg_status, when set, receives the status output from GPG.
- */
 int verify_signed_buffer(const char *payload, size_t payload_size,
                         const char *signature, size_t signature_size,
                         struct strbuf *gpg_output, struct strbuf *gpg_status)
index d2d4fd3a656e3f4953aea5eda3eea435f37f237e..a5e6517ae67ea5fa3f79265517381d58d99fba18 100644 (file)
@@ -23,16 +23,43 @@ struct signature_check {
        char *key;
 };
 
-extern void signature_check_clear(struct signature_check *sigc);
-extern size_t parse_signature(const char *buf, unsigned long size);
-extern void parse_gpg_output(struct signature_check *);
-extern int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key);
-extern int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output, struct strbuf *gpg_status);
-extern int git_gpg_config(const char *, const char *, void *);
-extern void set_signing_key(const char *);
-extern const char *get_signing_key(void);
-extern int check_signature(const char *payload, size_t plen,
-       const char *signature, size_t slen, struct signature_check *sigc);
-void print_signature_buffer(const struct signature_check *sigc, unsigned flags);
+void signature_check_clear(struct signature_check *sigc);
+
+/*
+ * Look at GPG signed content (e.g. a signed tag object), whose
+ * payload is followed by a detached signature on it.  Return the
+ * offset where the embedded detached signature begins, or the end of
+ * the data when there is no such signature.
+ */
+size_t parse_signature(const char *buf, size_t size);
+
+void parse_gpg_output(struct signature_check *);
+
+/*
+ * Create a detached signature for the contents of "buffer" and append
+ * it after "signature"; "buffer" and "signature" can be the same
+ * strbuf instance, which would cause the detached signature appended
+ * at the end.
+ */
+int sign_buffer(struct strbuf *buffer, struct strbuf *signature,
+               const char *signing_key);
+
+/*
+ * Run "gpg" to see if the payload matches the detached signature.
+ * gpg_output, when set, receives the diagnostic output from GPG.
+ * gpg_status, when set, receives the status output from GPG.
+ */
+int verify_signed_buffer(const char *payload, size_t payload_size,
+                        const char *signature, size_t signature_size,
+                        struct strbuf *gpg_output, struct strbuf *gpg_status);
+
+int git_gpg_config(const char *, const char *, void *);
+void set_signing_key(const char *);
+const char *get_signing_key(void);
+int check_signature(const char *payload, size_t plen,
+                   const char *signature, size_t slen,
+                   struct signature_check *sigc);
+void print_signature_buffer(const struct signature_check *sigc,
+                           unsigned flags);
 
 #endif
diff --git a/grep.c b/grep.c
index 834b8eb439297ff5af4a3da8b946a40ca68057f1..45ec7e636c004dbd35d4e0d05c243bc1d1479d19 100644 (file)
--- a/grep.c
+++ b/grep.c
@@ -404,7 +404,7 @@ static void compile_pcre1_regexp(struct grep_pat *p, const struct grep_opt *opt)
                        die("Couldn't allocate PCRE JIT stack");
                pcre_assign_jit_stack(p->pcre1_extra_info, NULL, p->pcre1_jit_stack);
        } else if (p->pcre1_jit_on != 0) {
-               die("BUG: The pcre1_jit_on variable should be 0 or 1, not %d",
+               BUG("The pcre1_jit_on variable should be 0 or 1, not %d",
                    p->pcre1_jit_on);
        }
 #endif
@@ -550,7 +550,7 @@ static void compile_pcre2_pattern(struct grep_pat *p, const struct grep_opt *opt
                        die("Couldn't allocate PCRE2 match context");
                pcre2_jit_stack_assign(p->pcre2_match_context, NULL, p->pcre2_jit_stack);
        } else if (p->pcre2_jit_on != 0) {
-               die("BUG: The pcre2_jit_on variable should be 0 or 1, not %d",
+               BUG("The pcre2_jit_on variable should be 0 or 1, not %d",
                    p->pcre1_jit_on);
        }
 }
@@ -636,7 +636,6 @@ static void compile_fixed_regexp(struct grep_pat *p, struct grep_opt *opt)
        if (err) {
                char errbuf[1024];
                regerror(err, &p->regexp, errbuf, sizeof(errbuf));
-               regfree(&p->regexp);
                compile_regexp_failed(p, errbuf);
        }
 }
@@ -701,7 +700,6 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
        if (err) {
                char errbuf[1024];
                regerror(err, &p->regexp, errbuf, 1024);
-               regfree(&p->regexp);
                compile_regexp_failed(p, errbuf);
        }
 }
@@ -917,10 +915,10 @@ static struct grep_expr *prep_header_patterns(struct grep_opt *opt)
 
        for (p = opt->header_list; p; p = p->next) {
                if (p->token != GREP_PATTERN_HEAD)
-                       die("BUG: a non-header pattern in grep header list.");
+                       BUG("a non-header pattern in grep header list.");
                if (p->field < GREP_HEADER_FIELD_MIN ||
                    GREP_HEADER_FIELD_MAX <= p->field)
-                       die("BUG: unknown header field %d", p->field);
+                       BUG("unknown header field %d", p->field);
                compile_regexp(p, opt);
        }
 
@@ -933,7 +931,7 @@ static struct grep_expr *prep_header_patterns(struct grep_opt *opt)
 
                h = compile_pattern_atom(&pp);
                if (!h || pp != p->next)
-                       die("BUG: malformed header expr");
+                       BUG("malformed header expr");
                if (!header_group[p->field]) {
                        header_group[p->field] = h;
                        continue;
@@ -1652,7 +1650,7 @@ static int fill_textconv_grep(struct userdiff_driver *driver,
                fill_filespec(df, &null_oid, 0, 0100644);
                break;
        default:
-               die("BUG: attempt to textconv something without a path?");
+               BUG("attempt to textconv something without a path?");
        }
 
        /*
@@ -1748,7 +1746,7 @@ static int grep_source_1(struct grep_opt *opt, struct grep_source *gs, int colle
                case GREP_BINARY_TEXT:
                        break;
                default:
-                       die("BUG: unknown binary handling mode");
+                       BUG("unknown binary handling mode");
                }
        }
 
@@ -2015,7 +2013,7 @@ static int grep_source_load_oid(struct grep_source *gs)
        enum object_type type;
 
        grep_read_lock();
-       gs->buf = read_sha1_file(gs->identifier, &type, &gs->size);
+       gs->buf = read_object_file(gs->identifier, &type, &gs->size);
        grep_read_unlock();
 
        if (!gs->buf)
@@ -2072,7 +2070,7 @@ static int grep_source_load(struct grep_source *gs)
        case GREP_SOURCE_BUF:
                return gs->buf ? 0 : -1;
        }
-       die("BUG: invalid grep_source type to load");
+       BUG("invalid grep_source type to load");
 }
 
 void grep_source_load_driver(struct grep_source *gs)
diff --git a/help.c b/help.c
index 60071a9beaaedf45730385b7fc1443b402c50156..dd35fcc133094e4dc89898463868e89162637076 100644 (file)
--- a/help.c
+++ b/help.c
 #include "cache.h"
 #include "config.h"
 #include "builtin.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "run-command.h"
 #include "levenshtein.h"
 #include "help.h"
-#include "common-cmds.h"
+#include "command-list.h"
 #include "string-list.h"
 #include "column.h"
 #include "version.h"
 #include "refs.h"
 #include "parse-options.h"
 
+struct category_description {
+       uint32_t category;
+       const char *desc;
+};
+static uint32_t common_mask =
+       CAT_init | CAT_worktree | CAT_info |
+       CAT_history | CAT_remote;
+static struct category_description common_categories[] = {
+       { CAT_init, N_("start a working area (see also: git help tutorial)") },
+       { CAT_worktree, N_("work on the current change (see also: git help everyday)") },
+       { CAT_info, N_("examine the history and state (see also: git help revisions)") },
+       { CAT_history, N_("grow, mark and tweak your common history") },
+       { CAT_remote, N_("collaborate (see also: git help workflows)") },
+       { 0, NULL }
+};
+static struct category_description main_categories[] = {
+       { CAT_mainporcelain, N_("Main Porcelain Commands") },
+       { CAT_ancillarymanipulators, N_("Ancillary Commands / Manipulators") },
+       { CAT_ancillaryinterrogators, N_("Ancillary Commands / Interrogators") },
+       { CAT_foreignscminterface, N_("Interacting with Others") },
+       { CAT_plumbingmanipulators, N_("Low-level Commands / Manipulators") },
+       { CAT_plumbinginterrogators, N_("Low-level Commands / Interrogators") },
+       { CAT_synchingrepositories, N_("Low-level Commands / Synching Repositories") },
+       { CAT_purehelpers, N_("Low-level Commands / Internal Helpers") },
+       { 0, NULL }
+};
+
+static const char *drop_prefix(const char *name, uint32_t category)
+{
+       const char *new_name;
+
+       if (skip_prefix(name, "git-", &new_name))
+               return new_name;
+       if (category == CAT_guide && skip_prefix(name, "git", &new_name))
+               return new_name;
+       return name;
+
+}
+
+static void extract_cmds(struct cmdname_help **p_cmds, uint32_t mask)
+{
+       int i, nr = 0;
+       struct cmdname_help *cmds;
+
+       if (ARRAY_SIZE(command_list) == 0)
+               BUG("empty command_list[] is a sign of broken generate-cmdlist.sh");
+
+       ALLOC_ARRAY(cmds, ARRAY_SIZE(command_list) + 1);
+
+       for (i = 0; i < ARRAY_SIZE(command_list); i++) {
+               const struct cmdname_help *cmd = command_list + i;
+
+               if (!(cmd->category & mask))
+                       continue;
+
+               cmds[nr] = *cmd;
+               cmds[nr].name = drop_prefix(cmd->name, cmd->category);
+
+               nr++;
+       }
+       cmds[nr].name = NULL;
+       *p_cmds = cmds;
+}
+
+static void print_command_list(const struct cmdname_help *cmds,
+                              uint32_t mask, int longest)
+{
+       int i;
+
+       for (i = 0; cmds[i].name; i++) {
+               if (cmds[i].category & mask) {
+                       printf("   %s   ", cmds[i].name);
+                       mput_char(' ', longest - strlen(cmds[i].name));
+                       puts(_(cmds[i].help));
+               }
+       }
+}
+
+static int cmd_name_cmp(const void *elem1, const void *elem2)
+{
+       const struct cmdname_help *e1 = elem1;
+       const struct cmdname_help *e2 = elem2;
+
+       return strcmp(e1->name, e2->name);
+}
+
+static void print_cmd_by_category(const struct category_description *catdesc)
+{
+       struct cmdname_help *cmds;
+       int longest = 0;
+       int i, nr = 0;
+       uint32_t mask = 0;
+
+       for (i = 0; catdesc[i].desc; i++)
+               mask |= catdesc[i].category;
+
+       extract_cmds(&cmds, mask);
+
+       for (i = 0; cmds[i].name; i++, nr++) {
+               if (longest < strlen(cmds[i].name))
+                       longest = strlen(cmds[i].name);
+       }
+       QSORT(cmds, nr, cmd_name_cmp);
+
+       for (i = 0; catdesc[i].desc; i++) {
+               uint32_t mask = catdesc[i].category;
+               const char *desc = catdesc[i].desc;
+
+               printf("\n%s\n", _(desc));
+               print_command_list(cmds, mask, longest);
+       }
+       free(cmds);
+}
+
 void add_cmdname(struct cmdnames *cmds, const char *name, int len)
 {
        struct cmdname *ent;
@@ -190,44 +304,116 @@ void list_commands(unsigned int colopts,
        }
 }
 
-static int cmd_group_cmp(const void *elem1, const void *elem2)
+void list_common_cmds_help(void)
 {
-       const struct cmdname_help *e1 = elem1;
-       const struct cmdname_help *e2 = elem2;
+       puts(_("These are common Git commands used in various situations:"));
+       print_cmd_by_category(common_categories);
+}
 
-       if (e1->group < e2->group)
-               return -1;
-       if (e1->group > e2->group)
-               return 1;
-       return strcmp(e1->name, e2->name);
+void list_all_main_cmds(struct string_list *list)
+{
+       struct cmdnames main_cmds, other_cmds;
+       int i;
+
+       memset(&main_cmds, 0, sizeof(main_cmds));
+       memset(&other_cmds, 0, sizeof(other_cmds));
+       load_command_list("git-", &main_cmds, &other_cmds);
+
+       for (i = 0; i < main_cmds.cnt; i++)
+               string_list_append(list, main_cmds.names[i]->name);
+
+       clean_cmdnames(&main_cmds);
+       clean_cmdnames(&other_cmds);
 }
 
-void list_common_cmds_help(void)
+void list_all_other_cmds(struct string_list *list)
 {
-       int i, longest = 0;
-       int current_grp = -1;
+       struct cmdnames main_cmds, other_cmds;
+       int i;
 
-       for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
-               if (longest < strlen(common_cmds[i].name))
-                       longest = strlen(common_cmds[i].name);
-       }
+       memset(&main_cmds, 0, sizeof(main_cmds));
+       memset(&other_cmds, 0, sizeof(other_cmds));
+       load_command_list("git-", &main_cmds, &other_cmds);
 
-       QSORT(common_cmds, ARRAY_SIZE(common_cmds), cmd_group_cmp);
+       for (i = 0; i < other_cmds.cnt; i++)
+               string_list_append(list, other_cmds.names[i]->name);
 
-       puts(_("These are common Git commands used in various situations:"));
+       clean_cmdnames(&main_cmds);
+       clean_cmdnames(&other_cmds);
+}
+
+void list_cmds_by_category(struct string_list *list,
+                          const char *cat)
+{
+       int i, n = ARRAY_SIZE(command_list);
+       uint32_t cat_id = 0;
 
-       for (i = 0; i < ARRAY_SIZE(common_cmds); i++) {
-               if (common_cmds[i].group != current_grp) {
-                       printf("\n%s\n", _(common_cmd_groups[common_cmds[i].group]));
-                       current_grp = common_cmds[i].group;
+       for (i = 0; category_names[i]; i++) {
+               if (!strcmp(cat, category_names[i])) {
+                       cat_id = 1UL << i;
+                       break;
                }
+       }
+       if (!cat_id)
+               die(_("unsupported command listing type '%s'"), cat);
+
+       for (i = 0; i < n; i++) {
+               struct cmdname_help *cmd = command_list + i;
 
-               printf("   %s   ", common_cmds[i].name);
-               mput_char(' ', longest - strlen(common_cmds[i].name));
-               puts(_(common_cmds[i].help));
+               if (!(cmd->category & cat_id))
+                       continue;
+               string_list_append(list, drop_prefix(cmd->name, cmd->category));
        }
 }
 
+void list_cmds_by_config(struct string_list *list)
+{
+       const char *cmd_list;
+
+       /*
+        * There's no actual repository setup at this point (and even
+        * if there is, we don't really care; only global config
+        * matters). If we accidentally set up a repository, it's ok
+        * too since the caller (git --list-cmds=) should exit shortly
+        * anyway.
+        */
+       if (git_config_get_string_const("completion.commands", &cmd_list))
+               return;
+
+       string_list_sort(list);
+       string_list_remove_duplicates(list, 0);
+
+       while (*cmd_list) {
+               struct strbuf sb = STRBUF_INIT;
+               const char *p = strchrnul(cmd_list, ' ');
+
+               strbuf_add(&sb, cmd_list, p - cmd_list);
+               if (*cmd_list == '-')
+                       string_list_remove(list, cmd_list + 1, 0);
+               else
+                       string_list_insert(list, sb.buf);
+               strbuf_release(&sb);
+               while (*p == ' ')
+                       p++;
+               cmd_list = p;
+       }
+}
+
+void list_common_guides_help(void)
+{
+       struct category_description catdesc[] = {
+               { CAT_guide, N_("The common Git guides are:") },
+               { 0, NULL }
+       };
+       print_cmd_by_category(catdesc);
+       putchar('\n');
+}
+
+void list_all_cmds_help(void)
+{
+       print_cmd_by_category(main_categories);
+}
+
 int is_in_cmdlist(struct cmdnames *c, const char *s)
 {
        int i;
@@ -285,6 +471,7 @@ const char *help_unknown_cmd(const char *cmd)
 {
        int i, n, best_similarity = 0;
        struct cmdnames main_cmds, other_cmds;
+       struct cmdname_help *common_cmds;
 
        memset(&main_cmds, 0, sizeof(main_cmds));
        memset(&other_cmds, 0, sizeof(other_cmds));
@@ -299,6 +486,8 @@ const char *help_unknown_cmd(const char *cmd)
        QSORT(main_cmds.names, main_cmds.cnt, cmdname_compare);
        uniq(&main_cmds);
 
+       extract_cmds(&common_cmds, common_mask);
+
        /* This abuses cmdname->len for levenshtein distance */
        for (i = 0, n = 0; i < main_cmds.cnt; i++) {
                int cmp = 0; /* avoid compiler stupidity */
@@ -313,10 +502,10 @@ const char *help_unknown_cmd(const char *cmd)
                        die(_(bad_interpreter_advice), cmd, cmd);
 
                /* Does the candidate appear in common_cmds list? */
-               while (n < ARRAY_SIZE(common_cmds) &&
+               while (common_cmds[n].name &&
                       (cmp = strcmp(common_cmds[n].name, candidate)) < 0)
                        n++;
-               if ((n < ARRAY_SIZE(common_cmds)) && !cmp) {
+               if (common_cmds[n].name && !cmp) {
                        /* Yes, this is one of the common commands */
                        n++; /* use the entry from common_cmds[] */
                        if (starts_with(candidate, cmd)) {
@@ -329,6 +518,7 @@ const char *help_unknown_cmd(const char *cmd)
                main_cmds.names[i]->len =
                        levenshtein(cmd, candidate, 0, 2, 1, 3) + 1;
        }
+       FREE_AND_NULL(common_cmds);
 
        QSORT(main_cmds.names, main_cmds.cnt, levenshtein_compare);
 
diff --git a/help.h b/help.h
index b21d7c94e8ce429ac1f58bd566c69e154d84d6a0..3b38292a1b317ba32d934be6006cb86e0e7d0d94 100644 (file)
--- a/help.h
+++ b/help.h
@@ -1,6 +1,8 @@
 #ifndef HELP_H
 #define HELP_H
 
+struct string_list;
+
 struct cmdnames {
        int alloc;
        int cnt;
@@ -17,6 +19,14 @@ static inline void mput_char(char c, unsigned int num)
 }
 
 extern void list_common_cmds_help(void);
+extern void list_all_cmds_help(void);
+extern void list_common_guides_help(void);
+
+extern void list_all_main_cmds(struct string_list *list);
+extern void list_all_other_cmds(struct string_list *list);
+extern void list_cmds_by_category(struct string_list *list,
+                                 const char *category);
+extern void list_cmds_by_config(struct string_list *list);
 extern const char *help_unknown_cmd(const char *cmd);
 extern void load_command_list(const char *prefix,
                              struct cmdnames *main_cmds,
index f3dc218b2a3d2662efda56fb6c8878a37a4e67a4..adaef16fadfd03f34b8ac5bb496bd51aab292b20 100644 (file)
@@ -1,15 +1,18 @@
 #include "cache.h"
 #include "config.h"
+#include "repository.h"
 #include "refs.h"
 #include "pkt-line.h"
 #include "object.h"
 #include "tag.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "run-command.h"
 #include "string-list.h"
 #include "url.h"
 #include "argv-array.h"
 #include "packfile.h"
+#include "object-store.h"
+#include "protocol.h"
 
 static const char content_type[] = "Content-Type";
 static const char content_length[] = "Content-Length";
@@ -466,8 +469,11 @@ static void get_info_refs(struct strbuf *hdr, char *arg)
                hdr_str(hdr, content_type, buf.buf);
                end_headers(hdr);
 
-               packet_write_fmt(1, "# service=git-%s\n", svc->name);
-               packet_flush(1);
+
+               if (determine_protocol_version_server() != protocol_v2) {
+                       packet_write_fmt(1, "# service=git-%s\n", svc->name);
+                       packet_flush(1);
+               }
 
                argv[0] = svc->name;
                run_service(argv, 0);
@@ -517,14 +523,13 @@ static void get_info_packs(struct strbuf *hdr, char *arg)
        size_t cnt = 0;
 
        select_getanyfile(hdr);
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                if (p->pack_local)
                        cnt++;
        }
 
        strbuf_grow(&buf, cnt * 53 + 2);
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                if (p->pack_local)
                        strbuf_addf(&buf, "P %s\n", p->pack_name + objdirlen + 6);
        }
index 8af380050ce6a43a6764ad871f0de141c316421a..a32ac118d90ca6141a72d31f47497116870f6803 100644 (file)
@@ -1,6 +1,6 @@
 #include "cache.h"
 #include "config.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "http.h"
 #include "walker.h"
 
@@ -17,21 +17,13 @@ int cmd_main(int argc, const char **argv)
        char *url = NULL;
        int arg = 1;
        int rc = 0;
-       int get_tree = 0;
-       int get_history = 0;
-       int get_all = 0;
        int get_verbosely = 0;
        int get_recover = 0;
 
        while (arg < argc && argv[arg][0] == '-') {
                if (argv[arg][1] == 't') {
-                       get_tree = 1;
                } else if (argv[arg][1] == 'c') {
-                       get_history = 1;
                } else if (argv[arg][1] == 'a') {
-                       get_all = 1;
-                       get_tree = 1;
-                       get_history = 1;
                } else if (argv[arg][1] == 'v') {
                        get_verbosely = 1;
                } else if (argv[arg][1] == 'w') {
@@ -55,10 +47,6 @@ int cmd_main(int argc, const char **argv)
                commits = 1;
        }
 
-       if (get_all == 0)
-               warning("http-fetch: use without -a is deprecated.\n"
-                       "In a future release, -a will become the default.");
-
        if (argv[arg])
                str_end_url_with_slash(argv[arg], &url);
 
@@ -68,9 +56,6 @@ int cmd_main(int argc, const char **argv)
 
        http_init(NULL, url, 0);
        walker = get_http_walker(url);
-       walker->get_tree = get_tree;
-       walker->get_history = get_history;
-       walker->get_all = get_all;
        walker->get_verbosely = get_verbosely;
        walker->get_recover = get_recover;
 
index 7dcd9daf62cf07e1cc43022fde17607cef6dc147..7e38522098bf91c144adaee7f9f5476f8bc72cd2 100644 (file)
@@ -6,12 +6,13 @@
 #include "refs.h"
 #include "diff.h"
 #include "revision.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "remote.h"
 #include "list-objects.h"
 #include "sigchain.h"
 #include "argv-array.h"
 #include "packfile.h"
+#include "object-store.h"
 
 #ifdef EXPAT_NEEDS_XMLPARSE_H
 #include <xmlparse.h>
@@ -361,7 +362,7 @@ static void start_put(struct transfer_request *request)
        ssize_t size;
        git_zstream stream;
 
-       unpacked = read_sha1_file(request->obj->oid.hash, &type, &len);
+       unpacked = read_object_file(&request->obj->oid, &type, &len);
        hdrlen = xsnprintf(hdr, sizeof(hdr), "%s %lu", type_name(type), len) + 1;
 
        /* Set it up */
@@ -1330,7 +1331,7 @@ static int get_delta(struct rev_info *revs, struct remote_lock *lock)
        int count = 0;
 
        while ((commit = get_revision(revs)) != NULL) {
-               p = process_tree(commit->tree, p);
+               p = process_tree(get_commit_tree(commit), p);
                commit->object.flags |= LOCAL;
                if (!(commit->object.flags & UNINTERESTING))
                        count += add_send_request(&commit->object, lock);
@@ -1691,8 +1692,7 @@ int cmd_main(int argc, const char **argv)
 {
        struct transfer_request *request;
        struct transfer_request *next_request;
-       int nr_refspec = 0;
-       const char **refspec = NULL;
+       struct refspec rs = REFSPEC_INIT_PUSH;
        struct remote_lock *ref_lock = NULL;
        struct remote_lock *info_ref_lock = NULL;
        struct rev_info revs;
@@ -1755,8 +1755,7 @@ int cmd_main(int argc, const char **argv)
                        }
                        continue;
                }
-               refspec = argv;
-               nr_refspec = argc - i;
+               refspec_appendn(&rs, argv, argc - i);
                break;
        }
 
@@ -1767,7 +1766,7 @@ int cmd_main(int argc, const char **argv)
        if (!repo->url)
                usage(http_push_usage);
 
-       if (delete_branch && nr_refspec != 1)
+       if (delete_branch && rs.nr != 1)
                die("You must specify only one branch name when deleting a remote branch");
 
        setup_git_directory();
@@ -1813,18 +1812,18 @@ int cmd_main(int argc, const char **argv)
 
        /* Remove a remote branch if -d or -D was specified */
        if (delete_branch) {
-               if (delete_remote_branch(refspec[0], force_delete) == -1) {
+               const char *branch = rs.items[i].src;
+               if (delete_remote_branch(branch, force_delete) == -1) {
                        fprintf(stderr, "Unable to delete remote branch %s\n",
-                               refspec[0]);
+                               branch);
                        if (helper_status)
-                               printf("error %s cannot remove\n", refspec[0]);
+                               printf("error %s cannot remove\n", branch);
                }
                goto cleanup;
        }
 
        /* match them up */
-       if (match_push_refs(local_refs, &remote_refs,
-                           nr_refspec, (const char **) refspec, push_all)) {
+       if (match_push_refs(local_refs, &remote_refs, &rs, push_all)) {
                rc = -1;
                goto cleanup;
        }
index 07c2b1af826d3e24e2568e5bdef17806f355048f..7cdfb2f24c76d2f09b39ae2fa97685ecec2d1630 100644 (file)
@@ -1,10 +1,12 @@
 #include "cache.h"
+#include "repository.h"
 #include "commit.h"
 #include "walker.h"
 #include "http.h"
 #include "list.h"
 #include "transport.h"
 #include "packfile.h"
+#include "object-store.h"
 
 struct alt_base {
        char *base;
@@ -22,7 +24,7 @@ enum object_request_state {
 
 struct object_request {
        struct walker *walker;
-       unsigned char sha1[20];
+       struct object_id oid;
        struct alt_base *repo;
        enum object_request_state state;
        struct http_object_request *req;
@@ -56,7 +58,7 @@ static void start_object_request(struct walker *walker,
        struct active_request_slot *slot;
        struct http_object_request *req;
 
-       req = new_http_object_request(obj_req->repo->base, obj_req->sha1);
+       req = new_http_object_request(obj_req->repo->base, obj_req->oid.hash);
        if (req == NULL) {
                obj_req->state = ABORTED;
                return;
@@ -82,7 +84,7 @@ static void finish_object_request(struct object_request *obj_req)
                return;
 
        if (obj_req->req->rename == 0)
-               walker_say(obj_req->walker, "got %s\n", sha1_to_hex(obj_req->sha1));
+               walker_say(obj_req->walker, "got %s\n", oid_to_hex(&obj_req->oid));
 }
 
 static void process_object_response(void *callback_data)
@@ -129,7 +131,7 @@ static int fill_active_slot(struct walker *walker)
        list_for_each_safe(pos, tmp, head) {
                obj_req = list_entry(pos, struct object_request, node);
                if (obj_req->state == WAITING) {
-                       if (has_sha1_file(obj_req->sha1))
+                       if (has_sha1_file(obj_req->oid.hash))
                                obj_req->state = COMPLETE;
                        else {
                                start_object_request(walker, obj_req);
@@ -148,7 +150,7 @@ static void prefetch(struct walker *walker, unsigned char *sha1)
 
        newreq = xmalloc(sizeof(*newreq));
        newreq->walker = walker;
-       hashcpy(newreq->sha1, sha1);
+       hashcpy(newreq->oid.hash, sha1);
        newreq->repo = data->alt;
        newreq->state = WAITING;
        newreq->req = NULL;
@@ -481,13 +483,13 @@ static int fetch_object(struct walker *walker, unsigned char *sha1)
 
        list_for_each(pos, head) {
                obj_req = list_entry(pos, struct object_request, node);
-               if (!hashcmp(obj_req->sha1, sha1))
+               if (!hashcmp(obj_req->oid.hash, sha1))
                        break;
        }
        if (obj_req == NULL)
                return error("Couldn't find request for %s in the queue", hex);
 
-       if (has_sha1_file(obj_req->sha1)) {
+       if (has_sha1_file(obj_req->oid.hash)) {
                if (obj_req->req != NULL)
                        abort_http_object_request(obj_req->req);
                abort_object_request(obj_req);
@@ -541,11 +543,11 @@ static int fetch_object(struct walker *walker, unsigned char *sha1)
        } else if (req->zret != Z_STREAM_END) {
                walker->corrupt_object_found++;
                ret = error("File %s (%s) corrupt", hex, req->url);
-       } else if (hashcmp(obj_req->sha1, req->real_sha1)) {
+       } else if (hashcmp(obj_req->oid.hash, req->real_sha1)) {
                ret = error("File %s has bad hash", hex);
        } else if (req->rename < 0) {
                struct strbuf buf = STRBUF_INIT;
-               sha1_file_name(&buf, req->sha1);
+               sha1_file_name(the_repository, &buf, req->sha1);
                ret = error("unable to write sha1 filename %s", buf.buf);
                strbuf_release(&buf);
        }
diff --git a/http.c b/http.c
index a5bd5d62c22c054f82b9971fc1f320c643f1d6fb..b4bfbceaeb7e58e79cac17f8768a7e36cff3405e 100644 (file)
--- a/http.c
+++ b/http.c
@@ -14,6 +14,7 @@
 #include "packfile.h"
 #include "protocol.h"
 #include "string-list.h"
+#include "object-store.h"
 
 static struct trace_key trace_curl = TRACE_KEY_INIT(CURL);
 static int trace_curl_data = 1;
@@ -62,6 +63,9 @@ static struct {
        { "tlsv1.1", CURL_SSLVERSION_TLSv1_1 },
        { "tlsv1.2", CURL_SSLVERSION_TLSv1_2 },
 #endif
+#if LIBCURL_VERSION_NUM >= 0x073400
+       { "tlsv1.3", CURL_SSLVERSION_TLSv1_3 },
+#endif
 };
 #if LIBCURL_VERSION_NUM >= 0x070903
 static const char *ssl_key;
@@ -972,21 +976,6 @@ static void set_from_env(const char **var, const char *envname)
                *var = val;
 }
 
-static void protocol_http_header(void)
-{
-       if (get_protocol_version_config() > 0) {
-               struct strbuf protocol_header = STRBUF_INIT;
-
-               strbuf_addf(&protocol_header, GIT_PROTOCOL_HEADER ": version=%d",
-                           get_protocol_version_config());
-
-
-               extra_http_headers = curl_slist_append(extra_http_headers,
-                                                      protocol_header.buf);
-               strbuf_release(&protocol_header);
-       }
-}
-
 void http_init(struct remote *remote, const char *url, int proactive_auth)
 {
        char *low_speed_limit;
@@ -1017,8 +1006,6 @@ void http_init(struct remote *remote, const char *url, int proactive_auth)
        if (remote)
                var_override(&http_proxy_authmethod, remote->http_proxy_authmethod);
 
-       protocol_http_header();
-
        pragma_header = curl_slist_append(http_copy_default_headers(),
                "Pragma: no-cache");
        no_pragma_header = curl_slist_append(http_copy_default_headers(),
@@ -1791,9 +1778,17 @@ static int http_request(const char *url,
 
        headers = curl_slist_append(headers, buf.buf);
 
+       /* Add additional headers here */
+       if (options && options->extra_headers) {
+               const struct string_list_item *item;
+               for_each_string_list_item(item, options->extra_headers) {
+                       headers = curl_slist_append(headers, item->string);
+               }
+       }
+
        curl_easy_setopt(slot->curl, CURLOPT_URL, url);
        curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, headers);
-       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
+       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
 
        ret = run_one_slot(slot, &results);
 
@@ -1851,7 +1846,7 @@ static int update_url_from_redirect(struct strbuf *base,
                return 0;
 
        if (!skip_prefix(asked, base->buf, &tail))
-               die("BUG: update_url_from_redirect: %s is not a superset of %s",
+               BUG("update_url_from_redirect: %s is not a superset of %s",
                    asked, base->buf);
 
        new_len = got->len;
@@ -1899,7 +1894,7 @@ static int http_request_reauth(const char *url,
                        strbuf_reset(result);
                        break;
                default:
-                       die("BUG: HTTP_KEEP_ERROR is only supported with strbufs");
+                       BUG("HTTP_KEEP_ERROR is only supported with strbufs");
                }
        }
 
@@ -2043,7 +2038,8 @@ int http_get_info_packs(const char *base_url, struct packed_git **packs_head)
        int ret = 0, i = 0;
        char *url, *data;
        struct strbuf buf = STRBUF_INIT;
-       unsigned char sha1[20];
+       unsigned char hash[GIT_MAX_RAWSZ];
+       const unsigned hexsz = the_hash_algo->hexsz;
 
        end_url_with_slash(&buf, base_url);
        strbuf_addstr(&buf, "objects/info/packs");
@@ -2059,13 +2055,13 @@ int http_get_info_packs(const char *base_url, struct packed_git **packs_head)
                switch (data[i]) {
                case 'P':
                        i++;
-                       if (i + 52 <= buf.len &&
+                       if (i + hexsz + 12 <= buf.len &&
                            starts_with(data + i, " pack-") &&
-                           starts_with(data + i + 46, ".pack\n")) {
-                               get_sha1_hex(data + i + 6, sha1);
-                               fetch_and_setup_pack_index(packs_head, sha1,
+                           starts_with(data + i + hexsz + 6, ".pack\n")) {
+                               get_sha1_hex(data + i + 6, hash);
+                               fetch_and_setup_pack_index(packs_head, hash,
                                                      base_url);
-                               i += 51;
+                               i += hexsz + 11;
                                break;
                        }
                default:
@@ -2087,6 +2083,7 @@ void release_http_pack_request(struct http_pack_request *preq)
                preq->packfile = NULL;
        }
        preq->slot = NULL;
+       strbuf_release(&preq->tmpfile);
        free(preq->url);
        free(preq);
 }
@@ -2109,19 +2106,19 @@ int finish_http_pack_request(struct http_pack_request *preq)
                lst = &((*lst)->next);
        *lst = (*lst)->next;
 
-       if (!strip_suffix(preq->tmpfile, ".pack.temp", &len))
-               die("BUG: pack tmpfile does not end in .pack.temp?");
-       tmp_idx = xstrfmt("%.*s.idx.temp", (int)len, preq->tmpfile);
+       if (!strip_suffix(preq->tmpfile.buf, ".pack.temp", &len))
+               BUG("pack tmpfile does not end in .pack.temp?");
+       tmp_idx = xstrfmt("%.*s.idx.temp", (int)len, preq->tmpfile.buf);
 
        argv_array_push(&ip.args, "index-pack");
        argv_array_pushl(&ip.args, "-o", tmp_idx, NULL);
-       argv_array_push(&ip.args, preq->tmpfile);
+       argv_array_push(&ip.args, preq->tmpfile.buf);
        ip.git_cmd = 1;
        ip.no_stdin = 1;
        ip.no_stdout = 1;
 
        if (run_command(&ip)) {
-               unlink(preq->tmpfile);
+               unlink(preq->tmpfile.buf);
                unlink(tmp_idx);
                free(tmp_idx);
                return -1;
@@ -2129,13 +2126,13 @@ int finish_http_pack_request(struct http_pack_request *preq)
 
        unlink(sha1_pack_index_name(p->sha1));
 
-       if (finalize_object_file(preq->tmpfile, sha1_pack_name(p->sha1))
+       if (finalize_object_file(preq->tmpfile.buf, sha1_pack_name(p->sha1))
         || finalize_object_file(tmp_idx, sha1_pack_index_name(p->sha1))) {
                free(tmp_idx);
                return -1;
        }
 
-       install_packed_git(p);
+       install_packed_git(the_repository, p);
        free(tmp_idx);
        return 0;
 }
@@ -2148,6 +2145,7 @@ struct http_pack_request *new_http_pack_request(
        struct http_pack_request *preq;
 
        preq = xcalloc(1, sizeof(*preq));
+       strbuf_init(&preq->tmpfile, 0);
        preq->target = target;
 
        end_url_with_slash(&buf, base_url);
@@ -2155,12 +2153,11 @@ struct http_pack_request *new_http_pack_request(
                sha1_to_hex(target->sha1));
        preq->url = strbuf_detach(&buf, NULL);
 
-       snprintf(preq->tmpfile, sizeof(preq->tmpfile), "%s.temp",
-               sha1_pack_name(target->sha1));
-       preq->packfile = fopen(preq->tmpfile, "a");
+       strbuf_addf(&preq->tmpfile, "%s.temp", sha1_pack_name(target->sha1));
+       preq->packfile = fopen(preq->tmpfile.buf, "a");
        if (!preq->packfile) {
                error("Unable to open local file %s for pack",
-                     preq->tmpfile);
+                     preq->tmpfile.buf);
                goto abort;
        }
 
@@ -2187,6 +2184,7 @@ struct http_pack_request *new_http_pack_request(
        return preq;
 
 abort:
+       strbuf_release(&preq->tmpfile);
        free(preq->url);
        free(preq);
        return NULL;
@@ -2206,7 +2204,7 @@ static size_t fwrite_sha1_file(char *ptr, size_t eltsize, size_t nmemb,
                CURLcode c = curl_easy_getinfo(slot->curl, CURLINFO_HTTP_CODE,
                                                &slot->http_code);
                if (c != CURLE_OK)
-                       die("BUG: curl_easy_getinfo for HTTP code failed: %s",
+                       BUG("curl_easy_getinfo for HTTP code failed: %s",
                                curl_easy_strerror(c));
                if (slot->http_code >= 300)
                        return size;
@@ -2237,7 +2235,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
 {
        char *hex = sha1_to_hex(sha1);
        struct strbuf filename = STRBUF_INIT;
-       char prevfile[PATH_MAX];
+       struct strbuf prevfile = STRBUF_INIT;
        int prevlocal;
        char prev_buf[PREV_BUF_SIZE];
        ssize_t prev_read = 0;
@@ -2245,40 +2243,41 @@ struct http_object_request *new_http_object_request(const char *base_url,
        struct http_object_request *freq;
 
        freq = xcalloc(1, sizeof(*freq));
+       strbuf_init(&freq->tmpfile, 0);
        hashcpy(freq->sha1, sha1);
        freq->localfile = -1;
 
-       sha1_file_name(&filename, sha1);
-       snprintf(freq->tmpfile, sizeof(freq->tmpfile),
-                "%s.temp", filename.buf);
+       sha1_file_name(the_repository, &filename, sha1);
+       strbuf_addf(&freq->tmpfile, "%s.temp", filename.buf);
 
-       snprintf(prevfile, sizeof(prevfile), "%s.prev", filename.buf);
-       unlink_or_warn(prevfile);
-       rename(freq->tmpfile, prevfile);
-       unlink_or_warn(freq->tmpfile);
+       strbuf_addf(&prevfile, "%s.prev", filename.buf);
+       unlink_or_warn(prevfile.buf);
+       rename(freq->tmpfile.buf, prevfile.buf);
+       unlink_or_warn(freq->tmpfile.buf);
        strbuf_release(&filename);
 
        if (freq->localfile != -1)
                error("fd leakage in start: %d", freq->localfile);
-       freq->localfile = open(freq->tmpfile,
+       freq->localfile = open(freq->tmpfile.buf,
                               O_WRONLY | O_CREAT | O_EXCL, 0666);
        /*
         * This could have failed due to the "lazy directory creation";
         * try to mkdir the last path component.
         */
        if (freq->localfile < 0 && errno == ENOENT) {
-               char *dir = strrchr(freq->tmpfile, '/');
+               char *dir = strrchr(freq->tmpfile.buf, '/');
                if (dir) {
                        *dir = 0;
-                       mkdir(freq->tmpfile, 0777);
+                       mkdir(freq->tmpfile.buf, 0777);
                        *dir = '/';
                }
-               freq->localfile = open(freq->tmpfile,
+               freq->localfile = open(freq->tmpfile.buf,
                                       O_WRONLY | O_CREAT | O_EXCL, 0666);
        }
 
        if (freq->localfile < 0) {
-               error_errno("Couldn't create temporary file %s", freq->tmpfile);
+               error_errno("Couldn't create temporary file %s",
+                           freq->tmpfile.buf);
                goto abort;
        }
 
@@ -2292,7 +2291,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
         * If a previous temp file is present, process what was already
         * fetched.
         */
-       prevlocal = open(prevfile, O_RDONLY);
+       prevlocal = open(prevfile.buf, O_RDONLY);
        if (prevlocal != -1) {
                do {
                        prev_read = xread(prevlocal, prev_buf, PREV_BUF_SIZE);
@@ -2309,7 +2308,8 @@ struct http_object_request *new_http_object_request(const char *base_url,
                } while (prev_read > 0);
                close(prevlocal);
        }
-       unlink_or_warn(prevfile);
+       unlink_or_warn(prevfile.buf);
+       strbuf_release(&prevfile);
 
        /*
         * Reset inflate/SHA1 if there was an error reading the previous temp
@@ -2324,7 +2324,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
                        lseek(freq->localfile, 0, SEEK_SET);
                        if (ftruncate(freq->localfile, 0) < 0) {
                                error_errno("Couldn't truncate temporary file %s",
-                                           freq->tmpfile);
+                                           freq->tmpfile.buf);
                                goto abort;
                        }
                }
@@ -2354,6 +2354,7 @@ struct http_object_request *new_http_object_request(const char *base_url,
        return freq;
 
 abort:
+       strbuf_release(&prevfile);
        free(freq->url);
        free(freq);
        return NULL;
@@ -2381,25 +2382,24 @@ int finish_http_object_request(struct http_object_request *freq)
        if (freq->http_code == 416) {
                warning("requested range invalid; we may already have all the data.");
        } else if (freq->curl_result != CURLE_OK) {
-               if (stat(freq->tmpfile, &st) == 0)
+               if (stat(freq->tmpfile.buf, &st) == 0)
                        if (st.st_size == 0)
-                               unlink_or_warn(freq->tmpfile);
+                               unlink_or_warn(freq->tmpfile.buf);
                return -1;
        }
 
        git_inflate_end(&freq->stream);
        git_SHA1_Final(freq->real_sha1, &freq->c);
        if (freq->zret != Z_STREAM_END) {
-               unlink_or_warn(freq->tmpfile);
+               unlink_or_warn(freq->tmpfile.buf);
                return -1;
        }
        if (hashcmp(freq->sha1, freq->real_sha1)) {
-               unlink_or_warn(freq->tmpfile);
+               unlink_or_warn(freq->tmpfile.buf);
                return -1;
        }
-
-       sha1_file_name(&filename, freq->sha1);
-       freq->rename = finalize_object_file(freq->tmpfile, filename.buf);
+       sha1_file_name(the_repository, &filename, freq->sha1);
+       freq->rename = finalize_object_file(freq->tmpfile.buf, filename.buf);
        strbuf_release(&filename);
 
        return freq->rename;
@@ -2407,7 +2407,7 @@ int finish_http_object_request(struct http_object_request *freq)
 
 void abort_http_object_request(struct http_object_request *freq)
 {
-       unlink_or_warn(freq->tmpfile);
+       unlink_or_warn(freq->tmpfile.buf);
 
        release_http_object_request(freq);
 }
@@ -2427,4 +2427,5 @@ void release_http_object_request(struct http_object_request *freq)
                release_active_slot(freq->slot);
                freq->slot = NULL;
        }
+       strbuf_release(&freq->tmpfile);
 }
diff --git a/http.h b/http.h
index f7bd3b26b0da70e44402579e4912a1b20dcef16e..d305ca1dc7a3f931a81353c56060e98f4039c692 100644 (file)
--- a/http.h
+++ b/http.h
@@ -172,6 +172,13 @@ struct http_get_options {
         * for details.
         */
        struct strbuf *base_url;
+
+       /*
+        * If not NULL, contains additional HTTP headers to be sent with the
+        * request. The strings in the list must not be freed until after the
+        * request has completed.
+        */
+       struct string_list *extra_headers;
 };
 
 /* Return values for http_get_*() */
@@ -200,7 +207,7 @@ struct http_pack_request {
        struct packed_git *target;
        struct packed_git **lst;
        FILE *packfile;
-       char tmpfile[PATH_MAX];
+       struct strbuf tmpfile;
        struct active_request_slot *slot;
 };
 
@@ -212,7 +219,7 @@ extern void release_http_pack_request(struct http_pack_request *preq);
 /* Helpers for fetching object */
 struct http_object_request {
        char *url;
-       char tmpfile[PATH_MAX];
+       struct strbuf tmpfile;
        int localfile;
        CURLcode curl_result;
        char errorstr[CURL_ERROR_SIZE];
index ffb0a6eca8ce632dc448883a47987bf48adea31b..b4eb886e2a6a40bce1e478d8d24f43f64ed2e3aa 100644 (file)
@@ -24,7 +24,7 @@
 #include "cache.h"
 #include "config.h"
 #include "credential.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "run-command.h"
 #include "parse-options.h"
 #ifdef NO_OPENSSL
@@ -511,7 +511,7 @@ static int nfsnprintf(char *buf, int blen, const char *fmt, ...)
 
        va_start(va, fmt);
        if (blen <= 0 || (unsigned)(ret = vsnprintf(buf, blen, fmt, va)) >= (unsigned)blen)
-               die("BUG: buffer too small. Please report a bug.");
+               BUG("buffer too small. Please report a bug.");
        va_end(va);
        return ret;
 }
index cdc2257db56f7d68412bb456e91854a9e9aa5cd5..fa9cfd5bdbb5dfe4a1ca5c7f7711435caf091805 100644 (file)
@@ -501,8 +501,7 @@ static void fill_blob_sha1(struct commit *commit, struct diff_filespec *spec)
        unsigned mode;
        struct object_id oid;
 
-       if (get_tree_entry(commit->object.oid.hash, spec->path,
-                          oid.hash, &mode))
+       if (get_tree_entry(&commit->object.oid, spec->path, &oid, &mode))
                die("There is no path %s in the commit", spec->path);
        fill_filespec(spec, &oid, 1, mode);
 
@@ -817,8 +816,8 @@ static void queue_diffs(struct line_log_data *range,
        assert(commit);
 
        DIFF_QUEUE_CLEAR(&diff_queued_diff);
-       diff_tree_oid(parent ? &parent->tree->object.oid : NULL,
-                     &commit->tree->object.oid, "", opt);
+       diff_tree_oid(parent ? get_commit_tree_oid(parent) : NULL,
+                     get_commit_tree_oid(commit), "", opt);
        if (opt->detect_rename) {
                filter_diffs_for_paths(range, 1);
                if (diff_might_be_rename())
index 4356c45368e10bd7f41e15f91130dbfd3e4e9281..5b14d2711ad3791169f5d8cbc03836b4254bd55c 100644 (file)
@@ -19,7 +19,7 @@
  * in the traversal (until we mark it SEEN).  This is a way to
  * let us silently de-dup calls to show() in the caller.  This
  * is subtly different from the "revision.h:SHOWN" and the
- * "sha1_name.c:ONELINE_SEEN" bits.  And also different from
+ * "sha1-name.c:ONELINE_SEEN" bits.  And also different from
  * the non-de-dup usage in pack-bitmap.c
  */
 #define FILTER_SHOWN_BUT_REVISIT (1<<21)
@@ -117,7 +117,7 @@ static enum list_objects_filter_result filter_blobs_limit(
                assert(obj->type == OBJ_BLOB);
                assert((obj->flags & SEEN) == 0);
 
-               t = sha1_object_info(obj->oid.hash, &object_length);
+               t = oid_object_info(the_repository, &obj->oid, &object_length);
                if (t != OBJ_BLOB) { /* probably OBJ_NONE */
                        /*
                         * We DO NOT have the blob locally, so we cannot
index 168bef688a89489a9d88d3e1f773483dbc1c8860..3eec510357337f5e33eea08a05faa22373d98c07 100644 (file)
@@ -195,7 +195,7 @@ static void mark_edge_parents_uninteresting(struct commit *commit,
                struct commit *parent = parents->item;
                if (!(parent->object.flags & UNINTERESTING))
                        continue;
-               mark_tree_uninteresting(parent->tree);
+               mark_tree_uninteresting(get_commit_tree(parent));
                if (revs->edge_hint && !(parent->object.flags & SHOWN)) {
                        parent->object.flags |= SHOWN;
                        show_edge(parent);
@@ -212,7 +212,7 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge)
                struct commit *commit = list->item;
 
                if (commit->object.flags & UNINTERESTING) {
-                       mark_tree_uninteresting(commit->tree);
+                       mark_tree_uninteresting(get_commit_tree(commit));
                        if (revs->edge_hint_aggressive && !(commit->object.flags & SHOWN)) {
                                commit->object.flags |= SHOWN;
                                show_edge(commit);
@@ -227,7 +227,7 @@ void mark_edges_uninteresting(struct rev_info *revs, show_edge_fn show_edge)
                        struct commit *commit = (struct commit *)obj;
                        if (obj->type != OBJ_COMMIT || !(obj->flags & UNINTERESTING))
                                continue;
-                       mark_tree_uninteresting(commit->tree);
+                       mark_tree_uninteresting(get_commit_tree(commit));
                        if (!(obj->flags & SHOWN)) {
                                obj->flags |= SHOWN;
                                show_edge(commit);
@@ -300,8 +300,8 @@ static void do_traverse(struct rev_info *revs,
                 * an uninteresting boundary commit may not have its tree
                 * parsed yet, but we are not going to show them anyway
                 */
-               if (commit->tree)
-                       add_pending_tree(revs, commit->tree);
+               if (get_commit_tree(commit))
+                       add_pending_tree(revs, get_commit_tree(commit));
                show_commit(commit, show_data);
 
                if (revs->tree_blobs_in_commit_order)
index efcb7d7dfe30a2fbad03244ba4ca9e536a3649e4..8e8ab4f29f3eaf05f056211042b5fd2f01727363 100644 (file)
@@ -193,7 +193,7 @@ char *get_locked_file_path(struct lock_file *lk)
        strbuf_addstr(&ret, get_tempfile_path(lk->tempfile));
        if (ret.len <= LOCK_SUFFIX_LEN ||
            strcmp(ret.buf + ret.len - LOCK_SUFFIX_LEN, LOCK_SUFFIX))
-               die("BUG: get_locked_file_path() called for malformed lock object");
+               BUG("get_locked_file_path() called for malformed lock object");
        /* remove ".lock": */
        strbuf_setlen(&ret, ret.len - LOCK_SUFFIX_LEN);
        return strbuf_detach(&ret, NULL);
index bdf23c5f7b89eda2997057285d1fff64acb0d30c..4aef85331e0b696d0373cf1bdb0743a7e6b58c36 100644 (file)
@@ -177,7 +177,7 @@ static void show_parents(struct commit *commit, int abbrev, FILE *file)
        struct commit_list *p;
        for (p = commit->parents; p ; p = p->next) {
                struct commit *parent = p->item;
-               fprintf(file, " %s", find_unique_abbrev(parent->object.oid.hash, abbrev));
+               fprintf(file, " %s", find_unique_abbrev(&parent->object.oid, abbrev));
        }
 }
 
@@ -185,7 +185,7 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre
 {
        struct commit_list *p = lookup_decoration(&opt->children, &commit->object);
        for ( ; p; p = p->next) {
-               fprintf(opt->diffopt.file, " %s", find_unique_abbrev(p->item->object.oid.hash, abbrev));
+               fprintf(opt->diffopt.file, " %s", find_unique_abbrev(&p->item->object.oid, abbrev));
        }
 }
 
@@ -362,7 +362,8 @@ 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,
-                            int *need_8bit_cte_p)
+                            int *need_8bit_cte_p,
+                            int maybe_multipart)
 {
        const char *extra_headers = opt->extra_headers;
        const char *name = oid_to_hex(opt->zero_commit ?
@@ -385,12 +386,16 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
                               opt->ref_message_ids->items[i].string);
                graph_show_oneline(opt->graph);
        }
-       if (opt->mime_boundary) {
-               static char subject_buffer[1024];
-               static char buffer[1024];
+       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 */
-               snprintf(subject_buffer, sizeof(subject_buffer) - 1,
+
+               strbuf_reset(&subject_buffer);
+               strbuf_reset(&buffer);
+
+               strbuf_addf(&subject_buffer,
                         "%s"
                         "MIME-Version: 1.0\n"
                         "Content-Type: multipart/mixed;"
@@ -405,13 +410,13 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
                         extra_headers ? extra_headers : "",
                         mime_boundary_leader, opt->mime_boundary,
                         mime_boundary_leader, opt->mime_boundary);
-               extra_headers = subject_buffer;
+               extra_headers = subject_buffer.buf;
 
                if (opt->numbered_files)
                        strbuf_addf(&filename, "%d", opt->nr);
                else
                        fmt_output_commit(&filename, commit, opt);
-               snprintf(buffer, sizeof(buffer) - 1,
+               strbuf_addf(&buffer,
                         "\n--%s%s\n"
                         "Content-Type: text/x-patch;"
                         " name=\"%s\"\n"
@@ -422,7 +427,7 @@ void log_write_email_headers(struct rev_info *opt, struct commit *commit,
                         filename.buf,
                         opt->no_inline ? "attachment" : "inline",
                         filename.buf);
-               opt->diffopt.stat_sep = buffer;
+               opt->diffopt.stat_sep = buffer.buf;
                strbuf_release(&filename);
        }
        *extra_headers_p = extra_headers;
@@ -488,9 +493,9 @@ static int is_common_merge(const struct commit *commit)
                && !commit->parents->next->next);
 }
 
-static void show_one_mergetag(struct commit *commit,
-                             struct commit_extra_header *extra,
-                             void *data)
+static int show_one_mergetag(struct commit *commit,
+                            struct commit_extra_header *extra,
+                            void *data)
 {
        struct rev_info *opt = (struct rev_info *)data;
        struct object_id oid;
@@ -502,7 +507,7 @@ static void show_one_mergetag(struct commit *commit,
        hash_object_file(extra->value, extra->len, type_name(OBJ_TAG), &oid);
        tag = lookup_tag(&oid);
        if (!tag)
-               return; /* error message already given */
+               return -1; /* error message already given */
 
        strbuf_init(&verify_message, 256);
        if (parse_tag_buffer(tag, extra->value, extra->len))
@@ -536,11 +541,12 @@ static void show_one_mergetag(struct commit *commit,
 
        show_sig_lines(opt, status, verify_message.buf);
        strbuf_release(&verify_message);
+       return 0;
 }
 
-static void show_mergetag(struct rev_info *opt, struct commit *commit)
+static int show_mergetag(struct rev_info *opt, struct commit *commit)
 {
-       for_each_mergetag(show_one_mergetag, commit, opt);
+       return for_each_mergetag(show_one_mergetag, commit, opt);
 }
 
 void show_log(struct rev_info *opt)
@@ -558,7 +564,7 @@ void show_log(struct rev_info *opt)
 
                if (!opt->graph)
                        put_revision_mark(opt, commit);
-               fputs(find_unique_abbrev(commit->object.oid.hash, abbrev_commit), opt->diffopt.file);
+               fputs(find_unique_abbrev(&commit->object.oid, abbrev_commit), opt->diffopt.file);
                if (opt->print_parents)
                        show_parents(commit, abbrev_commit, opt->diffopt.file);
                if (opt->children.name)
@@ -610,7 +616,7 @@ void show_log(struct rev_info *opt)
 
        if (cmit_fmt_is_mail(opt->commit_format)) {
                log_write_email_headers(opt, commit, &extra_headers,
-                                       &ctx.need_8bit_cte);
+                                       &ctx.need_8bit_cte, 1);
                ctx.rev = opt;
                ctx.print_email_subject = 1;
        } else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
@@ -620,7 +626,8 @@ void show_log(struct rev_info *opt)
 
                if (!opt->graph)
                        put_revision_mark(opt, commit);
-               fputs(find_unique_abbrev(commit->object.oid.hash, abbrev_commit),
+               fputs(find_unique_abbrev(&commit->object.oid,
+                                        abbrev_commit),
                      opt->diffopt.file);
                if (opt->print_parents)
                        show_parents(commit, abbrev_commit, opt->diffopt.file);
@@ -628,8 +635,7 @@ void show_log(struct rev_info *opt)
                        show_children(opt, commit, abbrev_commit);
                if (parent)
                        fprintf(opt->diffopt.file, " (from %s)",
-                              find_unique_abbrev(parent->object.oid.hash,
-                                                 abbrev_commit));
+                              find_unique_abbrev(&parent->object.oid, abbrev_commit));
                fputs(diff_get_color_opt(&opt->diffopt, DIFF_RESET), opt->diffopt.file);
                show_decorations(opt, commit);
                if (opt->commit_format == CMIT_FMT_ONELINE) {
@@ -806,7 +812,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
                return 0;
 
        parse_commit_or_die(commit);
-       oid = &commit->tree->object.oid;
+       oid = get_commit_tree_oid(commit);
 
        /* Root commit? */
        parents = get_saved_parents(opt, commit);
@@ -831,7 +837,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
                         * we merged _in_.
                         */
                        parse_commit_or_die(parents->item);
-                       diff_tree_oid(&parents->item->tree->object.oid,
+                       diff_tree_oid(get_commit_tree_oid(parents->item),
                                      oid, "", &opt->diffopt);
                        log_tree_diff_flush(opt);
                        return !opt->loginfo;
@@ -846,7 +852,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
                struct commit *parent = parents->item;
 
                parse_commit_or_die(parent);
-               diff_tree_oid(&parent->tree->object.oid,
+               diff_tree_oid(get_commit_tree_oid(parent),
                              oid, "", &opt->diffopt);
                log_tree_diff_flush(opt);
 
index deba035187185bc28a83520b47480c3141d8398e..e66862807463a12e28573be04cbcfcf2d200e6f3 100644 (file)
@@ -27,7 +27,8 @@ void format_decorations_extended(struct strbuf *sb, const struct commit *commit,
 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,
-                            int *need_8bit_cte_p);
+                            int *need_8bit_cte_p,
+                            int maybe_multipart);
 void load_ref_decorations(struct decoration_filter *filter, int flags);
 
 #define FORMAT_PATCH_NAME_MAX 64
diff --git a/ls-refs.c b/ls-refs.c
new file mode 100644 (file)
index 0000000..a06f12e
--- /dev/null
+++ b/ls-refs.c
@@ -0,0 +1,96 @@
+#include "cache.h"
+#include "repository.h"
+#include "refs.h"
+#include "remote.h"
+#include "argv-array.h"
+#include "ls-refs.h"
+#include "pkt-line.h"
+
+/*
+ * Check if one of the prefixes is a prefix of the ref.
+ * If no prefixes were provided, all refs match.
+ */
+static int ref_match(const struct argv_array *prefixes, const char *refname)
+{
+       int i;
+
+       if (!prefixes->argc)
+               return 1; /* no restriction */
+
+       for (i = 0; i < prefixes->argc; i++) {
+               const char *prefix = prefixes->argv[i];
+
+               if (starts_with(refname, prefix))
+                       return 1;
+       }
+
+       return 0;
+}
+
+struct ls_refs_data {
+       unsigned peel;
+       unsigned symrefs;
+       struct argv_array prefixes;
+};
+
+static int send_ref(const char *refname, const struct object_id *oid,
+                   int flag, void *cb_data)
+{
+       struct ls_refs_data *data = cb_data;
+       const char *refname_nons = strip_namespace(refname);
+       struct strbuf refline = STRBUF_INIT;
+
+       if (!ref_match(&data->prefixes, refname))
+               return 0;
+
+       strbuf_addf(&refline, "%s %s", oid_to_hex(oid), refname_nons);
+       if (data->symrefs && flag & REF_ISSYMREF) {
+               struct object_id unused;
+               const char *symref_target = resolve_ref_unsafe(refname, 0,
+                                                              &unused,
+                                                              &flag);
+
+               if (!symref_target)
+                       die("'%s' is a symref but it is not?", refname);
+
+               strbuf_addf(&refline, " symref-target:%s", symref_target);
+       }
+
+       if (data->peel) {
+               struct object_id peeled;
+               if (!peel_ref(refname, &peeled))
+                       strbuf_addf(&refline, " peeled:%s", oid_to_hex(&peeled));
+       }
+
+       strbuf_addch(&refline, '\n');
+       packet_write(1, refline.buf, refline.len);
+
+       strbuf_release(&refline);
+       return 0;
+}
+
+int ls_refs(struct repository *r, struct argv_array *keys,
+           struct packet_reader *request)
+{
+       struct ls_refs_data data;
+
+       memset(&data, 0, sizeof(data));
+
+       while (packet_reader_read(request) != PACKET_READ_FLUSH) {
+               const char *arg = request->line;
+               const char *out;
+
+               if (!strcmp("peel", arg))
+                       data.peel = 1;
+               else if (!strcmp("symrefs", arg))
+                       data.symrefs = 1;
+               else if (skip_prefix(arg, "ref-prefix ", &out))
+                       argv_array_push(&data.prefixes, out);
+       }
+
+       head_ref_namespaced(send_ref, &data);
+       for_each_namespaced_ref(send_ref, &data);
+       packet_flush(1);
+       argv_array_clear(&data.prefixes);
+       return 0;
+}
diff --git a/ls-refs.h b/ls-refs.h
new file mode 100644 (file)
index 0000000..b62877e
--- /dev/null
+++ b/ls-refs.h
@@ -0,0 +1,10 @@
+#ifndef LS_REFS_H
+#define LS_REFS_H
+
+struct repository;
+struct argv_array;
+struct packet_reader;
+extern int ls_refs(struct repository *r, struct argv_array *keys,
+                  struct packet_reader *request);
+
+#endif /* LS_REFS_H */
index d04142ccc76067e83f1839b6315b292268e90c58..3281a37d51830a60e864c78dff16dbf4eba9d800 100644 (file)
@@ -716,7 +716,7 @@ static void flush_inbody_header_accum(struct mailinfo *mi)
        if (!mi->inbody_header_accum.len)
                return;
        if (!check_header(mi, &mi->inbody_header_accum, mi->s_hdr_data, 0))
-               die("BUG: inbody_header_accum, if not empty, must always contain a valid in-body header");
+               BUG("inbody_header_accum, if not empty, must always contain a valid in-body header");
        strbuf_reset(&mi->inbody_header_accum);
 }
 
index cb921b4db676e3db918ee16f419cd2b78e0bf57e..13f0d2884e25edef3fde5bdf72b89a770111e472 100644 (file)
--- a/mailmap.c
+++ b/mailmap.c
@@ -224,7 +224,7 @@ static int read_mailmap_blob(struct string_list *map,
        if (get_oid(name, &oid) < 0)
                return 0;
 
-       buf = read_sha1_file(oid.hash, &type, &size);
+       buf = read_object_file(&oid, &type, &size);
        if (!buf)
                return error("unable to read mailmap object at %s", name);
        if (type != OBJ_BLOB)
index 0ca99d51626f49b5d4a88b9edc43c533c970dd0e..72cc2baa3f96b2cbfa296335c7f0ff1094b6e96c 100644 (file)
@@ -54,7 +54,7 @@ static void *fill_tree_desc_strict(struct tree_desc *desc,
        enum object_type type;
        unsigned long size;
 
-       buffer = read_sha1_file(hash->hash, &type, &size);
+       buffer = read_object_file(hash, &type, &size);
        if (!buffer)
                die("unable to read tree (%s)", oid_to_hex(hash));
        if (type != OBJ_TREE)
@@ -180,7 +180,7 @@ static int splice_tree(const struct object_id *oid1, const char *prefix,
        if (*subpath)
                subpath++;
 
-       buf = read_sha1_file(oid1->hash, &type, &sz);
+       buf = read_object_file(oid1, &type, &sz);
        if (!buf)
                die("cannot read tree %s", oid_to_hex(oid1));
        init_tree_desc(&desc, buf, sz);
@@ -269,7 +269,7 @@ void shift_tree(const struct object_id *hash1,
                if (!*del_prefix)
                        return;
 
-               if (get_tree_entry(hash2->hash, del_prefix, shifted->hash, &mode))
+               if (get_tree_entry(hash2, del_prefix, shifted, &mode))
                        die("cannot find path %s in tree %s",
                            del_prefix, oid_to_hex(hash2));
                return;
@@ -296,12 +296,12 @@ void shift_tree_by(const struct object_id *hash1,
        unsigned candidate = 0;
 
        /* Can hash2 be a tree at shift_prefix in tree hash1? */
-       if (!get_tree_entry(hash1->hash, shift_prefix, sub1.hash, &mode1) &&
+       if (!get_tree_entry(hash1, shift_prefix, &sub1, &mode1) &&
            S_ISDIR(mode1))
                candidate |= 1;
 
        /* Can hash1 be a tree at shift_prefix in tree hash2? */
-       if (!get_tree_entry(hash2->hash, shift_prefix, sub2.hash, &mode2) &&
+       if (!get_tree_entry(hash2, shift_prefix, &sub2, &mode2) &&
            S_ISDIR(mode2))
                candidate |= 2;
 
diff --git a/mem-pool.c b/mem-pool.c
new file mode 100644 (file)
index 0000000..389d7af
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Memory Pool implementation logic.
+ */
+
+#include "cache.h"
+#include "mem-pool.h"
+
+static struct mp_block *mem_pool_alloc_block(struct mem_pool *mem_pool, size_t block_alloc)
+{
+       struct mp_block *p;
+
+       mem_pool->pool_alloc += sizeof(struct mp_block) + block_alloc;
+       p = xmalloc(st_add(sizeof(struct mp_block), block_alloc));
+       p->next_block = mem_pool->mp_block;
+       p->next_free = (char *)p->space;
+       p->end = p->next_free + block_alloc;
+       mem_pool->mp_block = p;
+
+       return p;
+}
+
+void *mem_pool_alloc(struct mem_pool *mem_pool, size_t len)
+{
+       struct mp_block *p;
+       void *r;
+
+       /* round up to a 'uintmax_t' alignment */
+       if (len & (sizeof(uintmax_t) - 1))
+               len += sizeof(uintmax_t) - (len & (sizeof(uintmax_t) - 1));
+
+       for (p = mem_pool->mp_block; p; p = p->next_block)
+               if (p->end - p->next_free >= len)
+                       break;
+
+       if (!p) {
+               if (len >= (mem_pool->block_alloc / 2)) {
+                       mem_pool->pool_alloc += len;
+                       return xmalloc(len);
+               }
+
+               p = mem_pool_alloc_block(mem_pool, mem_pool->block_alloc);
+       }
+
+       r = p->next_free;
+       p->next_free += len;
+       return r;
+}
+
+void *mem_pool_calloc(struct mem_pool *mem_pool, size_t count, size_t size)
+{
+       size_t len = st_mult(count, size);
+       void *r = mem_pool_alloc(mem_pool, len);
+       memset(r, 0, len);
+       return r;
+}
diff --git a/mem-pool.h b/mem-pool.h
new file mode 100644 (file)
index 0000000..829ad58
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef MEM_POOL_H
+#define MEM_POOL_H
+
+struct mp_block {
+       struct mp_block *next_block;
+       char *next_free;
+       char *end;
+       uintmax_t space[FLEX_ARRAY]; /* more */
+};
+
+struct mem_pool {
+       struct mp_block *mp_block;
+
+       /*
+        * The amount of available memory to grow the pool by.
+        * This size does not include the overhead for the mp_block.
+        */
+       size_t block_alloc;
+
+       /* The total amount of memory allocated by the pool. */
+       size_t pool_alloc;
+};
+
+/*
+ * Alloc memory from the mem_pool.
+ */
+void *mem_pool_alloc(struct mem_pool *pool, size_t len);
+
+/*
+ * Allocate and zero memory from the memory pool.
+ */
+void *mem_pool_calloc(struct mem_pool *pool, size_t count, size_t size);
+
+#endif
index 9b6eac22e4256d8f2bf82961b6e4f320d89fdeba..fa49c17287f4120b4bbb75acc6b92b3d339710cd 100644 (file)
@@ -11,7 +11,7 @@ static int fill_mmfile_blob(mmfile_t *f, struct blob *obj)
        unsigned long size;
        enum object_type type;
 
-       buf = read_sha1_file(obj->object.oid.hash, &type, &size);
+       buf = read_object_file(&obj->object.oid, &type, &size);
        if (!buf)
                return -1;
        if (type != OBJ_BLOB) {
@@ -66,7 +66,7 @@ void *merge_blobs(const char *path, struct blob *base, struct blob *our, struct
                        return NULL;
                if (!our)
                        our = their;
-               return read_sha1_file(our->object.oid.hash, &type, size);
+               return read_object_file(&our->object.oid, &type, size);
        }
 
        if (fill_mmfile_blob(&f1, our) < 0)
index 869092f7b9bc0ce1104a1c43c7201acdee2eb4f8..f110e1c5ecbd6254b25785ecb49f29cb7bb75ed2 100644 (file)
@@ -23,6 +23,7 @@
 #include "merge-recursive.h"
 #include "dir.h"
 #include "submodule.h"
+#include "revision.h"
 
 struct path_hashmap_entry {
        struct hashmap_entry e;
@@ -49,6 +50,67 @@ static unsigned int path_hash(const char *path)
        return ignore_case ? strihash(path) : strhash(path);
 }
 
+static struct dir_rename_entry *dir_rename_find_entry(struct hashmap *hashmap,
+                                                     char *dir)
+{
+       struct dir_rename_entry key;
+
+       if (dir == NULL)
+               return NULL;
+       hashmap_entry_init(&key, strhash(dir));
+       key.dir = dir;
+       return hashmap_get(hashmap, &key, NULL);
+}
+
+static int dir_rename_cmp(const void *unused_cmp_data,
+                         const void *entry,
+                         const void *entry_or_key,
+                         const void *unused_keydata)
+{
+       const struct dir_rename_entry *e1 = entry;
+       const struct dir_rename_entry *e2 = entry_or_key;
+
+       return strcmp(e1->dir, e2->dir);
+}
+
+static void dir_rename_init(struct hashmap *map)
+{
+       hashmap_init(map, dir_rename_cmp, NULL, 0);
+}
+
+static void dir_rename_entry_init(struct dir_rename_entry *entry,
+                                 char *directory)
+{
+       hashmap_entry_init(entry, strhash(directory));
+       entry->dir = directory;
+       entry->non_unique_new_dir = 0;
+       strbuf_init(&entry->new_dir, 0);
+       string_list_init(&entry->possible_new_dirs, 0);
+}
+
+static struct collision_entry *collision_find_entry(struct hashmap *hashmap,
+                                                   char *target_file)
+{
+       struct collision_entry key;
+
+       hashmap_entry_init(&key, strhash(target_file));
+       key.target_file = target_file;
+       return hashmap_get(hashmap, &key, NULL);
+}
+
+static int collision_cmp(void *unused_cmp_data,
+                        const struct collision_entry *e1,
+                        const struct collision_entry *e2,
+                        const void *unused_keydata)
+{
+       return strcmp(e1->target_file, e2->target_file);
+}
+
+static void collision_init(struct hashmap *map)
+{
+       hashmap_init(map, (hashmap_cmp_fn) collision_cmp, NULL, 0);
+}
+
 static void flush_output(struct merge_options *o)
 {
        if (o->buffer_output < 2 && o->obuf.len) {
@@ -101,7 +163,7 @@ static struct commit *make_virtual_commit(struct tree *tree, const char *comment
        struct commit *commit = alloc_commit_node();
 
        set_merge_remote_desc(commit, comment, (struct object *)commit);
-       commit->tree = tree;
+       commit->maybe_tree = tree;
        commit->object.parsed = 1;
        return commit;
 }
@@ -119,6 +181,7 @@ static int oid_eq(const struct object_id *a, const struct object_id *b)
 
 enum rename_type {
        RENAME_NORMAL = 0,
+       RENAME_DIR,
        RENAME_DELETE,
        RENAME_ONE_FILE_TO_ONE,
        RENAME_ONE_FILE_TO_TWO,
@@ -228,7 +291,7 @@ static void output_commit_title(struct merge_options *o, struct commit *commit)
                strbuf_addf(&o->obuf, "virtual %s\n",
                        merge_remote_util(commit)->name);
        else {
-               strbuf_add_unique_abbrev(&o->obuf, commit->object.oid.hash,
+               strbuf_add_unique_abbrev(&o->obuf, &commit->object.oid,
                                         DEFAULT_ABBREV);
                strbuf_addch(&o->obuf, ' ');
                if (parse_commit(commit) != 0)
@@ -254,7 +317,7 @@ static int add_cacheinfo(struct merge_options *o,
 
        ce = make_cache_entry(mode, oid ? oid->hash : null_sha1, path, stage, 0);
        if (!ce)
-               return err(o, _("addinfo_cache failed for path '%s'"), path);
+               return err(o, _("add_cacheinfo failed for path '%s'; merge aborting."), path);
 
        ret = add_cache_entry(ce, options);
        if (refresh) {
@@ -262,7 +325,7 @@ static int add_cacheinfo(struct merge_options *o,
 
                nce = refresh_cache_entry(ce, CE_MATCH_REFRESH | CE_MATCH_IGNORE_MISSING);
                if (!nce)
-                       return err(o, _("addinfo_cache failed for path '%s'"), path);
+                       return err(o, _("add_cacheinfo failed to refresh for path '%s'; merge aborting."), path);
                if (nce != ce)
                        ret = add_cache_entry(nce, options);
        }
@@ -275,36 +338,54 @@ static void init_tree_desc_from_tree(struct tree_desc *desc, struct tree *tree)
        init_tree_desc(desc, tree->buffer, tree->size);
 }
 
-static int git_merge_trees(int index_only,
-                          struct tree *common,
-                          struct tree *head,
-                          struct tree *merge)
+static int unpack_trees_start(struct merge_options *o,
+                             struct tree *common,
+                             struct tree *head,
+                             struct tree *merge)
 {
        int rc;
        struct tree_desc t[3];
-       struct unpack_trees_options opts;
+       struct index_state tmp_index = { NULL };
 
-       memset(&opts, 0, sizeof(opts));
-       if (index_only)
-               opts.index_only = 1;
+       memset(&o->unpack_opts, 0, sizeof(o->unpack_opts));
+       if (o->call_depth)
+               o->unpack_opts.index_only = 1;
        else
-               opts.update = 1;
-       opts.merge = 1;
-       opts.head_idx = 2;
-       opts.fn = threeway_merge;
-       opts.src_index = &the_index;
-       opts.dst_index = &the_index;
-       setup_unpack_trees_porcelain(&opts, "merge");
+               o->unpack_opts.update = 1;
+       o->unpack_opts.merge = 1;
+       o->unpack_opts.head_idx = 2;
+       o->unpack_opts.fn = threeway_merge;
+       o->unpack_opts.src_index = &the_index;
+       o->unpack_opts.dst_index = &tmp_index;
+       o->unpack_opts.aggressive = !merge_detect_rename(o);
+       setup_unpack_trees_porcelain(&o->unpack_opts, "merge");
 
        init_tree_desc_from_tree(t+0, common);
        init_tree_desc_from_tree(t+1, head);
        init_tree_desc_from_tree(t+2, merge);
 
-       rc = unpack_trees(3, t, &opts);
+       rc = unpack_trees(3, t, &o->unpack_opts);
        cache_tree_free(&active_cache_tree);
+
+       /*
+        * Update the_index to match the new results, AFTER saving a copy
+        * in o->orig_index.  Update src_index to point to the saved copy.
+        * (verify_uptodate() checks src_index, and the original index is
+        * the one that had the necessary modification timestamps.)
+        */
+       o->orig_index = the_index;
+       the_index = tmp_index;
+       o->unpack_opts.src_index = &o->orig_index;
+
        return rc;
 }
 
+static void unpack_trees_finish(struct merge_options *o)
+{
+       discard_index(&o->orig_index);
+       clear_unpack_trees_porcelain(&o->unpack_opts);
+}
+
 struct tree *write_tree_from_memory(struct merge_options *o)
 {
        struct tree *result = NULL;
@@ -318,7 +399,7 @@ struct tree *write_tree_from_memory(struct merge_options *o)
                                fprintf(stderr, "BUG: %d %.*s\n", ce_stage(ce),
                                        (int)ce_namelen(ce), ce->name);
                }
-               die("BUG: unmerged index entries in merge-recursive.c");
+               BUG("unmerged index entries in merge-recursive.c");
        }
 
        if (!active_cache_tree)
@@ -335,7 +416,7 @@ struct tree *write_tree_from_memory(struct merge_options *o)
        return result;
 }
 
-static int save_files_dirs(const unsigned char *sha1,
+static int save_files_dirs(const struct object_id *oid,
                struct strbuf *base, const char *path,
                unsigned int mode, int stage, void *context)
 {
@@ -360,6 +441,21 @@ static void get_files_dirs(struct merge_options *o, struct tree *tree)
        read_tree_recursive(tree, "", 0, 0, &match_all, save_files_dirs, o);
 }
 
+static int get_tree_entry_if_blob(const struct object_id *tree,
+                                 const char *path,
+                                 struct object_id *hashy,
+                                 unsigned int *mode_o)
+{
+       int ret;
+
+       ret = get_tree_entry(tree, path, hashy, mode_o);
+       if (S_ISDIR(*mode_o)) {
+               oidcpy(hashy, &null_oid);
+               *mode_o = 0;
+       }
+       return ret;
+}
+
 /*
  * Returns an index_entry instance which doesn't have to correspond to
  * a real cache entry in Git's index.
@@ -370,12 +466,12 @@ static struct stage_data *insert_stage_data(const char *path,
 {
        struct string_list_item *item;
        struct stage_data *e = xcalloc(1, sizeof(struct stage_data));
-       get_tree_entry(o->object.oid.hash, path,
-                       e->stages[1].oid.hash, &e->stages[1].mode);
-       get_tree_entry(a->object.oid.hash, path,
-                       e->stages[2].oid.hash, &e->stages[2].mode);
-       get_tree_entry(b->object.oid.hash, path,
-                       e->stages[3].oid.hash, &e->stages[3].mode);
+       get_tree_entry_if_blob(&o->object.oid, path,
+                              &e->stages[1].oid, &e->stages[1].mode);
+       get_tree_entry_if_blob(&a->object.oid, path,
+                              &e->stages[2].oid, &e->stages[2].mode);
+       get_tree_entry_if_blob(&b->object.oid, path,
+                              &e->stages[3].oid, &e->stages[3].mode);
        item = string_list_insert(entries, path);
        item->util = e;
        return e;
@@ -534,78 +630,10 @@ struct rename {
         */
        struct stage_data *src_entry;
        struct stage_data *dst_entry;
+       unsigned add_turned_into_rename:1;
        unsigned processed:1;
 };
 
-/*
- * Get information of all renames which occurred between 'o_tree' and
- * 'tree'. We need the three trees in the merge ('o_tree', 'a_tree' and
- * 'b_tree') to be able to associate the correct cache entries with
- * the rename information. 'tree' is always equal to either a_tree or b_tree.
- */
-static struct string_list *get_renames(struct merge_options *o,
-                                      struct tree *tree,
-                                      struct tree *o_tree,
-                                      struct tree *a_tree,
-                                      struct tree *b_tree,
-                                      struct string_list *entries)
-{
-       int i;
-       struct string_list *renames;
-       struct diff_options opts;
-
-       renames = xcalloc(1, sizeof(struct string_list));
-       if (!o->detect_rename)
-               return renames;
-
-       diff_setup(&opts);
-       opts.flags.recursive = 1;
-       opts.flags.rename_empty = 0;
-       opts.detect_rename = DIFF_DETECT_RENAME;
-       opts.rename_limit = o->merge_rename_limit >= 0 ? o->merge_rename_limit :
-                           o->diff_rename_limit >= 0 ? o->diff_rename_limit :
-                           1000;
-       opts.rename_score = o->rename_score;
-       opts.show_rename_progress = o->show_rename_progress;
-       opts.output_format = DIFF_FORMAT_NO_OUTPUT;
-       diff_setup_done(&opts);
-       diff_tree_oid(&o_tree->object.oid, &tree->object.oid, "", &opts);
-       diffcore_std(&opts);
-       if (opts.needed_rename_limit > o->needed_rename_limit)
-               o->needed_rename_limit = opts.needed_rename_limit;
-       for (i = 0; i < diff_queued_diff.nr; ++i) {
-               struct string_list_item *item;
-               struct rename *re;
-               struct diff_filepair *pair = diff_queued_diff.queue[i];
-               if (pair->status != 'R') {
-                       diff_free_filepair(pair);
-                       continue;
-               }
-               re = xmalloc(sizeof(*re));
-               re->processed = 0;
-               re->pair = pair;
-               item = string_list_lookup(entries, re->pair->one->path);
-               if (!item)
-                       re->src_entry = insert_stage_data(re->pair->one->path,
-                                       o_tree, a_tree, b_tree, entries);
-               else
-                       re->src_entry = item->util;
-
-               item = string_list_lookup(entries, re->pair->two->path);
-               if (!item)
-                       re->dst_entry = insert_stage_data(re->pair->two->path,
-                                       o_tree, a_tree, b_tree, entries);
-               else
-                       re->dst_entry = item->util;
-               item = string_list_insert(renames, pair->one->path);
-               item->util = re;
-       }
-       opts.output_format = DIFF_FORMAT_NO_OUTPUT;
-       diff_queued_diff.nr = 0;
-       diff_flush(&opts);
-       return renames;
-}
-
 static int update_stages(struct merge_options *opt, const char *path,
                         const struct diff_filespec *o,
                         const struct diff_filespec *a,
@@ -637,6 +665,27 @@ static int update_stages(struct merge_options *opt, const char *path,
        return 0;
 }
 
+static int update_stages_for_stage_data(struct merge_options *opt,
+                                       const char *path,
+                                       const struct stage_data *stage_data)
+{
+       struct diff_filespec o, a, b;
+
+       o.mode = stage_data->stages[1].mode;
+       oidcpy(&o.oid, &stage_data->stages[1].oid);
+
+       a.mode = stage_data->stages[2].mode;
+       oidcpy(&a.oid, &stage_data->stages[2].oid);
+
+       b.mode = stage_data->stages[3].mode;
+       oidcpy(&b.oid, &stage_data->stages[3].oid);
+
+       return update_stages(opt, path,
+                            is_null_oid(&o.oid) ? NULL : &o,
+                            is_null_oid(&a.oid) ? NULL : &a,
+                            is_null_oid(&b.oid) ? NULL : &b);
+}
+
 static void update_entry(struct stage_data *entry,
                         struct diff_filespec *o,
                         struct diff_filespec *a,
@@ -738,31 +787,92 @@ static int dir_in_way(const char *path, int check_working_copy, int empty_ok)
                !(empty_ok && is_empty_dir(path));
 }
 
-static int was_tracked(const char *path)
+/*
+ * Returns whether path was tracked in the index before the merge started,
+ * and its oid and mode match the specified values
+ */
+static int was_tracked_and_matches(struct merge_options *o, const char *path,
+                                  const struct object_id *oid, unsigned mode)
 {
-       int pos = cache_name_pos(path, strlen(path));
+       int pos = index_name_pos(&o->orig_index, path, strlen(path));
+       struct cache_entry *ce;
+
+       if (0 > pos)
+               /* we were not tracking this path before the merge */
+               return 0;
+
+       /* See if the file we were tracking before matches */
+       ce = o->orig_index.cache[pos];
+       return (oid_eq(&ce->oid, oid) && ce->ce_mode == mode);
+}
+
+/*
+ * Returns whether path was tracked in the index before the merge started
+ */
+static int was_tracked(struct merge_options *o, const char *path)
+{
+       int pos = index_name_pos(&o->orig_index, path, strlen(path));
 
        if (0 <= pos)
-               /* we have been tracking this path */
+               /* we were tracking this path before the merge */
                return 1;
 
-       /*
-        * Look for an unmerged entry for the path,
-        * specifically stage #2, which would indicate
-        * that "our" side before the merge started
-        * had the path tracked (and resulted in a conflict).
-        */
-       for (pos = -1 - pos;
-            pos < active_nr && !strcmp(path, active_cache[pos]->name);
-            pos++)
-               if (ce_stage(active_cache[pos]) == 2)
-                       return 1;
        return 0;
 }
 
 static int would_lose_untracked(const char *path)
 {
-       return !was_tracked(path) && file_exists(path);
+       /*
+        * This may look like it can be simplified to:
+        *   return !was_tracked(o, path) && file_exists(path)
+        * but it can't.  This function needs to know whether path was in
+        * the working tree due to EITHER having been tracked in the index
+        * before the merge OR having been put into the working copy and
+        * index by unpack_trees().  Due to that either-or requirement, we
+        * check the current index instead of the original one.
+        *
+        * Note that we do not need to worry about merge-recursive itself
+        * updating the index after unpack_trees() and before calling this
+        * function, because we strictly require all code paths in
+        * merge-recursive to update the working tree first and the index
+        * second.  Doing otherwise would break
+        * update_file()/would_lose_untracked(); see every comment in this
+        * file which mentions "update_stages".
+        */
+       int pos = cache_name_pos(path, strlen(path));
+
+       if (pos < 0)
+               pos = -1 - pos;
+       while (pos < active_nr &&
+              !strcmp(path, active_cache[pos]->name)) {
+               /*
+                * If stage #0, it is definitely tracked.
+                * If it has stage #2 then it was tracked
+                * before this merge started.  All other
+                * cases the path was not tracked.
+                */
+               switch (ce_stage(active_cache[pos])) {
+               case 0:
+               case 2:
+                       return 0;
+               }
+               pos++;
+       }
+       return file_exists(path);
+}
+
+static int was_dirty(struct merge_options *o, const char *path)
+{
+       struct cache_entry *ce;
+       int dirty = 1;
+
+       if (o->call_depth || !was_tracked(o, path))
+               return !dirty;
+
+       ce = index_file_exists(o->unpack_opts.src_index,
+                              path, strlen(path), ignore_case);
+       dirty = verify_uptodate(ce, &o->unpack_opts) != 0;
+       return dirty;
 }
 
 static int make_room_for_path(struct merge_options *o, const char *path)
@@ -842,7 +952,7 @@ static int update_file_flags(struct merge_options *o,
                        goto update_index;
                }
 
-               buf = read_sha1_file(oid->hash, &type, &size);
+               buf = read_object_file(oid, &type, &size);
                if (!buf)
                        return err(o, _("cannot read object %s '%s'"), oid_to_hex(oid), path);
                if (type != OBJ_BLOB) {
@@ -893,7 +1003,9 @@ static int update_file_flags(struct merge_options *o,
        }
  update_index:
        if (!ret && update_cache)
-               add_cacheinfo(o, mode, oid, path, 0, update_wd, ADD_CACHE_OK_TO_ADD);
+               if (add_cacheinfo(o, mode, oid, path, 0, update_wd,
+                                 ADD_CACHE_OK_TO_ADD))
+                       return -1;
        return ret;
 }
 
@@ -977,13 +1089,193 @@ static int merge_3way(struct merge_options *o,
        return merge_status;
 }
 
+static int find_first_merges(struct object_array *result, const char *path,
+               struct commit *a, struct commit *b)
+{
+       int i, j;
+       struct object_array merges = OBJECT_ARRAY_INIT;
+       struct commit *commit;
+       int contains_another;
+
+       char merged_revision[42];
+       const char *rev_args[] = { "rev-list", "--merges", "--ancestry-path",
+                                  "--all", merged_revision, NULL };
+       struct rev_info revs;
+       struct setup_revision_opt rev_opts;
+
+       memset(result, 0, sizeof(struct object_array));
+       memset(&rev_opts, 0, sizeof(rev_opts));
+
+       /* get all revisions that merge commit a */
+       xsnprintf(merged_revision, sizeof(merged_revision), "^%s",
+                       oid_to_hex(&a->object.oid));
+       init_revisions(&revs, NULL);
+       rev_opts.submodule = path;
+       /* FIXME: can't handle linked worktrees in submodules yet */
+       revs.single_worktree = path != NULL;
+       setup_revisions(ARRAY_SIZE(rev_args)-1, rev_args, &revs, &rev_opts);
+
+       /* save all revisions from the above list that contain b */
+       if (prepare_revision_walk(&revs))
+               die("revision walk setup failed");
+       while ((commit = get_revision(&revs)) != NULL) {
+               struct object *o = &(commit->object);
+               if (in_merge_bases(b, commit))
+                       add_object_array(o, NULL, &merges);
+       }
+       reset_revision_walk();
+
+       /* Now we've got all merges that contain a and b. Prune all
+        * merges that contain another found merge and save them in
+        * result.
+        */
+       for (i = 0; i < merges.nr; i++) {
+               struct commit *m1 = (struct commit *) merges.objects[i].item;
+
+               contains_another = 0;
+               for (j = 0; j < merges.nr; j++) {
+                       struct commit *m2 = (struct commit *) merges.objects[j].item;
+                       if (i != j && in_merge_bases(m2, m1)) {
+                               contains_another = 1;
+                               break;
+                       }
+               }
+
+               if (!contains_another)
+                       add_object_array(merges.objects[i].item, NULL, result);
+       }
+
+       object_array_clear(&merges);
+       return result->nr;
+}
+
+static void print_commit(struct commit *commit)
+{
+       struct strbuf sb = STRBUF_INIT;
+       struct pretty_print_context ctx = {0};
+       ctx.date_mode.type = DATE_NORMAL;
+       format_commit_message(commit, " %h: %m %s", &sb, &ctx);
+       fprintf(stderr, "%s\n", sb.buf);
+       strbuf_release(&sb);
+}
+
+static int merge_submodule(struct merge_options *o,
+                          struct object_id *result, const char *path,
+                          const struct object_id *base, const struct object_id *a,
+                          const struct object_id *b)
+{
+       struct commit *commit_base, *commit_a, *commit_b;
+       int parent_count;
+       struct object_array merges;
+
+       int i;
+       int search = !o->call_depth;
+
+       /* store a in result in case we fail */
+       oidcpy(result, a);
+
+       /* we can not handle deletion conflicts */
+       if (is_null_oid(base))
+               return 0;
+       if (is_null_oid(a))
+               return 0;
+       if (is_null_oid(b))
+               return 0;
+
+       if (add_submodule_odb(path)) {
+               output(o, 1, _("Failed to merge submodule %s (not checked out)"), path);
+               return 0;
+       }
+
+       if (!(commit_base = lookup_commit_reference(base)) ||
+           !(commit_a = lookup_commit_reference(a)) ||
+           !(commit_b = lookup_commit_reference(b))) {
+               output(o, 1, _("Failed to merge submodule %s (commits not present)"), path);
+               return 0;
+       }
+
+       /* check whether both changes are forward */
+       if (!in_merge_bases(commit_base, commit_a) ||
+           !in_merge_bases(commit_base, commit_b)) {
+               output(o, 1, _("Failed to merge submodule %s (commits don't follow merge-base)"), path);
+               return 0;
+       }
+
+       /* Case #1: a is contained in b or vice versa */
+       if (in_merge_bases(commit_a, commit_b)) {
+               oidcpy(result, b);
+               if (show(o, 3)) {
+                       output(o, 3, _("Fast-forwarding submodule %s to the following commit:"), path);
+                       output_commit_title(o, commit_b);
+               } else if (show(o, 2))
+                       output(o, 2, _("Fast-forwarding submodule %s"), path);
+               else
+                       ; /* no output */
+
+               return 1;
+       }
+       if (in_merge_bases(commit_b, commit_a)) {
+               oidcpy(result, a);
+               if (show(o, 3)) {
+                       output(o, 3, _("Fast-forwarding submodule %s to the following commit:"), path);
+                       output_commit_title(o, commit_a);
+               } else if (show(o, 2))
+                       output(o, 2, _("Fast-forwarding submodule %s"), path);
+               else
+                       ; /* no output */
+
+               return 1;
+       }
+
+       /*
+        * Case #2: There are one or more merges that contain a and b in
+        * the submodule. If there is only one, then present it as a
+        * suggestion to the user, but leave it marked unmerged so the
+        * user needs to confirm the resolution.
+        */
+
+       /* Skip the search if makes no sense to the calling context.  */
+       if (!search)
+               return 0;
+
+       /* find commit which merges them */
+       parent_count = find_first_merges(&merges, path, commit_a, commit_b);
+       switch (parent_count) {
+       case 0:
+               output(o, 1, _("Failed to merge submodule %s (merge following commits not found)"), path);
+               break;
+
+       case 1:
+               output(o, 1, _("Failed to merge submodule %s (not fast-forward)"), path);
+               output(o, 2, _("Found a possible merge resolution for the submodule:\n"));
+               print_commit((struct commit *) merges.objects[0].item);
+               output(o, 2, _(
+                       "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"),
+                       oid_to_hex(&merges.objects[0].item->oid), path);
+               break;
+
+       default:
+               output(o, 1, _("Failed to merge submodule %s (multiple merges found)"), path);
+               for (i = 0; i < merges.nr; i++)
+                       print_commit((struct commit *) merges.objects[i].item);
+       }
+
+       object_array_clear(&merges);
+       return 0;
+}
+
 static int merge_file_1(struct merge_options *o,
-                                          const struct diff_filespec *one,
-                                          const struct diff_filespec *a,
-                                          const struct diff_filespec *b,
-                                          const char *branch1,
-                                          const char *branch2,
-                                          struct merge_file_info *result)
+                       const struct diff_filespec *one,
+                       const struct diff_filespec *a,
+                       const struct diff_filespec *b,
+                       const char *filename,
+                       const char *branch1,
+                       const char *branch2,
+                       struct merge_file_info *result)
 {
        result->merge = 0;
        result->clean = 1;
@@ -1039,12 +1331,11 @@ static int merge_file_1(struct merge_options *o,
                                return ret;
                        result->clean = (merge_status == 0);
                } else if (S_ISGITLINK(a->mode)) {
-                       result->clean = merge_submodule(&result->oid,
+                       result->clean = merge_submodule(o, &result->oid,
                                                       one->path,
                                                       &one->oid,
                                                       &a->oid,
-                                                      &b->oid,
-                                                      !o->call_depth);
+                                                      &b->oid);
                } else if (S_ISLNK(a->mode)) {
                        switch (o->recursive_variant) {
                        case MERGE_RECURSIVE_NORMAL:
@@ -1060,21 +1351,25 @@ static int merge_file_1(struct merge_options *o,
                                break;
                        }
                } else
-                       die("BUG: unsupported object type in the tree");
+                       BUG("unsupported object type in the tree");
        }
 
+       if (result->merge)
+               output(o, 2, _("Auto-merging %s"), filename);
+
        return 0;
 }
 
 static int merge_file_special_markers(struct merge_options *o,
-                          const struct diff_filespec *one,
-                          const struct diff_filespec *a,
-                          const struct diff_filespec *b,
-                          const char *branch1,
-                          const char *filename1,
-                          const char *branch2,
-                          const char *filename2,
-                          struct merge_file_info *mfi)
+                                     const struct diff_filespec *one,
+                                     const struct diff_filespec *a,
+                                     const struct diff_filespec *b,
+                                     const char *target_filename,
+                                     const char *branch1,
+                                     const char *filename1,
+                                     const char *branch2,
+                                     const char *filename2,
+                                     struct merge_file_info *mfi)
 {
        char *side1 = NULL;
        char *side2 = NULL;
@@ -1085,22 +1380,23 @@ static int merge_file_special_markers(struct merge_options *o,
        if (filename2)
                side2 = xstrfmt("%s:%s", branch2, filename2);
 
-       ret = merge_file_1(o, one, a, b,
+       ret = merge_file_1(o, one, a, b, target_filename,
                           side1 ? side1 : branch1,
                           side2 ? side2 : branch2, mfi);
+
        free(side1);
        free(side2);
        return ret;
 }
 
 static int merge_file_one(struct merge_options *o,
-                                        const char *path,
-                                        const struct object_id *o_oid, int o_mode,
-                                        const struct object_id *a_oid, int a_mode,
-                                        const struct object_id *b_oid, int b_mode,
-                                        const char *branch1,
-                                        const char *branch2,
-                                        struct merge_file_info *mfi)
+                         const char *path,
+                         const struct object_id *o_oid, int o_mode,
+                         const struct object_id *a_oid, int a_mode,
+                         const struct object_id *b_oid, int b_mode,
+                         const char *branch1,
+                         const char *branch2,
+                         struct merge_file_info *mfi)
 {
        struct diff_filespec one, a, b;
 
@@ -1111,7 +1407,39 @@ static int merge_file_one(struct merge_options *o,
        a.mode = a_mode;
        oidcpy(&b.oid, b_oid);
        b.mode = b_mode;
-       return merge_file_1(o, &one, &a, &b, branch1, branch2, mfi);
+       return merge_file_1(o, &one, &a, &b, path, branch1, branch2, mfi);
+}
+
+static int conflict_rename_dir(struct merge_options *o,
+                              struct diff_filepair *pair,
+                              const char *rename_branch,
+                              const char *other_branch)
+{
+       const struct diff_filespec *dest = pair->two;
+
+       if (!o->call_depth && would_lose_untracked(dest->path)) {
+               char *alt_path = unique_path(o, dest->path, rename_branch);
+
+               output(o, 1, _("Error: Refusing to lose untracked file at %s; "
+                              "writing to %s instead."),
+                      dest->path, alt_path);
+               /*
+                * Write the file in worktree at alt_path, but not in the
+                * index.  Instead, write to dest->path for the index but
+                * only at the higher appropriate stage.
+                */
+               if (update_file(o, 0, &dest->oid, dest->mode, alt_path))
+                       return -1;
+               free(alt_path);
+               return update_stages(o, dest->path, NULL,
+                                    rename_branch == o->branch1 ? dest : NULL,
+                                    rename_branch == o->branch1 ? NULL : dest);
+       }
+
+       /* Update dest->path both in index and in worktree */
+       if (update_file(o, 1, &dest->oid, dest->mode, dest->path))
+               return -1;
+       return 0;
 }
 
 static int handle_change_delete(struct merge_options *o,
@@ -1127,7 +1455,8 @@ static int handle_change_delete(struct merge_options *o,
        const char *update_path = path;
        int ret = 0;
 
-       if (dir_in_way(path, !o->call_depth, 0)) {
+       if (dir_in_way(path, !o->call_depth, 0) ||
+           (!o->call_depth && would_lose_untracked(path))) {
                update_path = alt_path = unique_path(o, path, change_branch);
        }
 
@@ -1242,17 +1571,34 @@ static int handle_file(struct merge_options *o,
 
        add = filespec_from_entry(&other, dst_entry, stage ^ 1);
        if (add) {
+               int ren_src_was_dirty = was_dirty(o, rename->path);
                char *add_name = unique_path(o, rename->path, other_branch);
                if (update_file(o, 0, &add->oid, add->mode, add_name))
                        return -1;
 
-               remove_file(o, 0, rename->path, 0);
+               if (ren_src_was_dirty) {
+                       output(o, 1, _("Refusing to lose dirty file at %s"),
+                              rename->path);
+               }
+               /*
+                * Because the double negatives somehow keep confusing me...
+                *    1) update_wd iff !ren_src_was_dirty.
+                *    2) no_wd iff !update_wd
+                *    3) so, no_wd == !!ren_src_was_dirty == ren_src_was_dirty
+                */
+               remove_file(o, 0, rename->path, ren_src_was_dirty);
                dst_name = unique_path(o, rename->path, cur_branch);
        } else {
                if (dir_in_way(rename->path, !o->call_depth, 0)) {
                        dst_name = unique_path(o, rename->path, cur_branch);
                        output(o, 1, _("%s is a directory in %s adding as %s instead"),
                               rename->path, other_branch, dst_name);
+               } else if (!o->call_depth &&
+                          would_lose_untracked(rename->path)) {
+                       dst_name = unique_path(o, rename->path, cur_branch);
+                       output(o, 1, _("Refusing to lose untracked file at %s; "
+                                      "adding as %s instead"),
+                              rename->path, dst_name);
                }
        }
        if ((ret = update_file(o, 0, &rename->oid, rename->mode, dst_name)))
@@ -1339,6 +1685,8 @@ static int conflict_rename_rename_2to1(struct merge_options *o,
        struct diff_filespec *c1 = ci->pair1->two;
        struct diff_filespec *c2 = ci->pair2->two;
        char *path = c1->path; /* == c2->path */
+       char *path_side_1_desc;
+       char *path_side_2_desc;
        struct merge_file_info mfi_c1;
        struct merge_file_info mfi_c2;
        int ret;
@@ -1352,13 +1700,19 @@ static int conflict_rename_rename_2to1(struct merge_options *o,
        remove_file(o, 1, a->path, o->call_depth || would_lose_untracked(a->path));
        remove_file(o, 1, b->path, o->call_depth || would_lose_untracked(b->path));
 
+       path_side_1_desc = xstrfmt("%s (was %s)", path, a->path);
+       path_side_2_desc = xstrfmt("%s (was %s)", path, b->path);
        if (merge_file_special_markers(o, a, c1, &ci->ren1_other,
+                                      path_side_1_desc,
                                       o->branch1, c1->path,
                                       o->branch2, ci->ren1_other.path, &mfi_c1) ||
            merge_file_special_markers(o, b, &ci->ren2_other, c2,
+                                      path_side_2_desc,
                                       o->branch1, ci->ren2_other.path,
                                       o->branch2, c2->path, &mfi_c2))
                return -1;
+       free(path_side_1_desc);
+       free(path_side_2_desc);
 
        if (o->call_depth) {
                /*
@@ -1378,11 +1732,43 @@ static int conflict_rename_rename_2to1(struct merge_options *o,
                char *new_path2 = unique_path(o, path, ci->branch2);
                output(o, 1, _("Renaming %s to %s and %s to %s instead"),
                       a->path, new_path1, b->path, new_path2);
-               remove_file(o, 0, path, 0);
+               if (was_dirty(o, path))
+                       output(o, 1, _("Refusing to lose dirty file at %s"),
+                              path);
+               else if (would_lose_untracked(path))
+                       /*
+                        * Only way we get here is if both renames were from
+                        * a directory rename AND user had an untracked file
+                        * at the location where both files end up after the
+                        * two directory renames.  See testcase 10d of t6043.
+                        */
+                       output(o, 1, _("Refusing to lose untracked file at "
+                                      "%s, even though it's in the way."),
+                              path);
+               else
+                       remove_file(o, 0, path, 0);
                ret = update_file(o, 0, &mfi_c1.oid, mfi_c1.mode, new_path1);
                if (!ret)
                        ret = update_file(o, 0, &mfi_c2.oid, mfi_c2.mode,
                                          new_path2);
+               /*
+                * unpack_trees() actually populates the index for us for
+                * "normal" rename/rename(2to1) situtations so that the
+                * correct entries are at the higher stages, which would
+                * make the call below to update_stages_for_stage_data
+                * unnecessary.  However, if either of the renames came
+                * from a directory rename, then unpack_trees() will not
+                * have gotten the right data loaded into the index, so we
+                * need to do so now.  (While it'd be tempting to move this
+                * call to update_stages_for_stage_data() to
+                * apply_directory_rename_modifications(), that would break
+                * our intermediate calls to would_lose_untracked() since
+                * those rely on the current in-memory index.  See also the
+                * big "NOTE" in update_stages()).
+                */
+               if (update_stages_for_stage_data(o, path, ci->dst_entry1))
+                       ret = -1;
+
                free(new_path2);
                free(new_path1);
        }
@@ -1390,25 +1776,781 @@ static int conflict_rename_rename_2to1(struct merge_options *o,
        return ret;
 }
 
-static int process_renames(struct merge_options *o,
-                          struct string_list *a_renames,
-                          struct string_list *b_renames)
+/*
+ * Get the diff_filepairs changed between o_tree and tree.
+ */
+static struct diff_queue_struct *get_diffpairs(struct merge_options *o,
+                                              struct tree *o_tree,
+                                              struct tree *tree)
 {
-       int clean_merge = 1, i, j;
-       struct string_list a_by_dst = STRING_LIST_INIT_NODUP;
-       struct string_list b_by_dst = STRING_LIST_INIT_NODUP;
-       const struct rename *sre;
+       struct diff_queue_struct *ret;
+       struct diff_options opts;
 
-       for (i = 0; i < a_renames->nr; i++) {
-               sre = a_renames->items[i].util;
-               string_list_insert(&a_by_dst, sre->pair->two->path)->util
-                       = (void *)sre;
-       }
-       for (i = 0; i < b_renames->nr; i++) {
-               sre = b_renames->items[i].util;
-               string_list_insert(&b_by_dst, sre->pair->two->path)->util
-                       = (void *)sre;
-       }
+       diff_setup(&opts);
+       opts.flags.recursive = 1;
+       opts.flags.rename_empty = 0;
+       opts.detect_rename = merge_detect_rename(o);
+       /*
+        * We do not have logic to handle the detection of copies.  In
+        * fact, it may not even make sense to add such logic: would we
+        * really want a change to a base file to be propagated through
+        * multiple other files by a merge?
+        */
+       if (opts.detect_rename > DIFF_DETECT_RENAME)
+               opts.detect_rename = DIFF_DETECT_RENAME;
+       opts.rename_limit = o->merge_rename_limit >= 0 ? o->merge_rename_limit :
+                           o->diff_rename_limit >= 0 ? o->diff_rename_limit :
+                           1000;
+       opts.rename_score = o->rename_score;
+       opts.show_rename_progress = o->show_rename_progress;
+       opts.output_format = DIFF_FORMAT_NO_OUTPUT;
+       diff_setup_done(&opts);
+       diff_tree_oid(&o_tree->object.oid, &tree->object.oid, "", &opts);
+       diffcore_std(&opts);
+       if (opts.needed_rename_limit > o->needed_rename_limit)
+               o->needed_rename_limit = opts.needed_rename_limit;
+
+       ret = xmalloc(sizeof(*ret));
+       *ret = diff_queued_diff;
+
+       opts.output_format = DIFF_FORMAT_NO_OUTPUT;
+       diff_queued_diff.nr = 0;
+       diff_queued_diff.queue = NULL;
+       diff_flush(&opts);
+       return ret;
+}
+
+static int tree_has_path(struct tree *tree, const char *path)
+{
+       struct object_id hashy;
+       unsigned int mode_o;
+
+       return !get_tree_entry(&tree->object.oid, path,
+                              &hashy, &mode_o);
+}
+
+/*
+ * Return a new string that replaces the beginning portion (which matches
+ * entry->dir), with entry->new_dir.  In perl-speak:
+ *   new_path_name = (old_path =~ s/entry->dir/entry->new_dir/);
+ * NOTE:
+ *   Caller must ensure that old_path starts with entry->dir + '/'.
+ */
+static char *apply_dir_rename(struct dir_rename_entry *entry,
+                             const char *old_path)
+{
+       struct strbuf new_path = STRBUF_INIT;
+       int oldlen, newlen;
+
+       if (entry->non_unique_new_dir)
+               return NULL;
+
+       oldlen = strlen(entry->dir);
+       newlen = entry->new_dir.len + (strlen(old_path) - oldlen) + 1;
+       strbuf_grow(&new_path, newlen);
+       strbuf_addbuf(&new_path, &entry->new_dir);
+       strbuf_addstr(&new_path, &old_path[oldlen]);
+
+       return strbuf_detach(&new_path, NULL);
+}
+
+static void get_renamed_dir_portion(const char *old_path, const char *new_path,
+                                   char **old_dir, char **new_dir)
+{
+       char *end_of_old, *end_of_new;
+       int old_len, new_len;
+
+       *old_dir = NULL;
+       *new_dir = NULL;
+
+       /*
+        * For
+        *    "a/b/c/d/e/foo.c" -> "a/b/some/thing/else/e/foo.c"
+        * the "e/foo.c" part is the same, we just want to know that
+        *    "a/b/c/d" was renamed to "a/b/some/thing/else"
+        * so, for this example, this function returns "a/b/c/d" in
+        * *old_dir and "a/b/some/thing/else" in *new_dir.
+        *
+        * Also, if the basename of the file changed, we don't care.  We
+        * want to know which portion of the directory, if any, changed.
+        */
+       end_of_old = strrchr(old_path, '/');
+       end_of_new = strrchr(new_path, '/');
+
+       if (end_of_old == NULL || end_of_new == NULL)
+               return;
+       while (*--end_of_new == *--end_of_old &&
+              end_of_old != old_path &&
+              end_of_new != new_path)
+               ; /* Do nothing; all in the while loop */
+       /*
+        * We've found the first non-matching character in the directory
+        * paths.  That means the current directory we were comparing
+        * represents the rename.  Move end_of_old and end_of_new back
+        * to the full directory name.
+        */
+       if (*end_of_old == '/')
+               end_of_old++;
+       if (*end_of_old != '/')
+               end_of_new++;
+       end_of_old = strchr(end_of_old, '/');
+       end_of_new = strchr(end_of_new, '/');
+
+       /*
+        * It may have been the case that old_path and new_path were the same
+        * directory all along.  Don't claim a rename if they're the same.
+        */
+       old_len = end_of_old - old_path;
+       new_len = end_of_new - new_path;
+
+       if (old_len != new_len || strncmp(old_path, new_path, old_len)) {
+               *old_dir = xstrndup(old_path, old_len);
+               *new_dir = xstrndup(new_path, new_len);
+       }
+}
+
+static void remove_hashmap_entries(struct hashmap *dir_renames,
+                                  struct string_list *items_to_remove)
+{
+       int i;
+       struct dir_rename_entry *entry;
+
+       for (i = 0; i < items_to_remove->nr; i++) {
+               entry = items_to_remove->items[i].util;
+               hashmap_remove(dir_renames, entry, NULL);
+       }
+       string_list_clear(items_to_remove, 0);
+}
+
+/*
+ * See if there is a directory rename for path, and if there are any file
+ * level conflicts for the renamed location.  If there is a rename and
+ * there are no conflicts, return the new name.  Otherwise, return NULL.
+ */
+static char *handle_path_level_conflicts(struct merge_options *o,
+                                        const char *path,
+                                        struct dir_rename_entry *entry,
+                                        struct hashmap *collisions,
+                                        struct tree *tree)
+{
+       char *new_path = NULL;
+       struct collision_entry *collision_ent;
+       int clean = 1;
+       struct strbuf collision_paths = STRBUF_INIT;
+
+       /*
+        * entry has the mapping of old directory name to new directory name
+        * that we want to apply to path.
+        */
+       new_path = apply_dir_rename(entry, path);
+
+       if (!new_path) {
+               /* This should only happen when entry->non_unique_new_dir set */
+               if (!entry->non_unique_new_dir)
+                       BUG("entry->non_unqiue_dir not set and !new_path");
+               output(o, 1, _("CONFLICT (directory rename split): "
+                              "Unclear where to place %s because directory "
+                              "%s was renamed to multiple other directories, "
+                              "with no destination getting a majority of the "
+                              "files."),
+                      path, entry->dir);
+               clean = 0;
+               return NULL;
+       }
+
+       /*
+        * The caller needs to have ensured that it has pre-populated
+        * collisions with all paths that map to new_path.  Do a quick check
+        * to ensure that's the case.
+        */
+       collision_ent = collision_find_entry(collisions, new_path);
+       if (collision_ent == NULL)
+               BUG("collision_ent is NULL");
+
+       /*
+        * Check for one-sided add/add/.../add conflicts, i.e.
+        * where implicit renames from the other side doing
+        * directory rename(s) can affect this side of history
+        * to put multiple paths into the same location.  Warn
+        * and bail on directory renames for such paths.
+        */
+       if (collision_ent->reported_already) {
+               clean = 0;
+       } else if (tree_has_path(tree, new_path)) {
+               collision_ent->reported_already = 1;
+               strbuf_add_separated_string_list(&collision_paths, ", ",
+                                                &collision_ent->source_files);
+               output(o, 1, _("CONFLICT (implicit dir rename): Existing "
+                              "file/dir at %s in the way of implicit "
+                              "directory rename(s) putting the following "
+                              "path(s) there: %s."),
+                      new_path, collision_paths.buf);
+               clean = 0;
+       } else if (collision_ent->source_files.nr > 1) {
+               collision_ent->reported_already = 1;
+               strbuf_add_separated_string_list(&collision_paths, ", ",
+                                                &collision_ent->source_files);
+               output(o, 1, _("CONFLICT (implicit dir rename): Cannot map "
+                              "more than one path to %s; implicit directory "
+                              "renames tried to put these paths there: %s"),
+                      new_path, collision_paths.buf);
+               clean = 0;
+       }
+
+       /* Free memory we no longer need */
+       strbuf_release(&collision_paths);
+       if (!clean && new_path) {
+               free(new_path);
+               return NULL;
+       }
+
+       return new_path;
+}
+
+/*
+ * There are a couple things we want to do at the directory level:
+ *   1. Check for both sides renaming to the same thing, in order to avoid
+ *      implicit renaming of files that should be left in place.  (See
+ *      testcase 6b in t6043 for details.)
+ *   2. Prune directory renames if there are still files left in the
+ *      the original directory.  These represent a partial directory rename,
+ *      i.e. a rename where only some of the files within the directory
+ *      were renamed elsewhere.  (Technically, this could be done earlier
+ *      in get_directory_renames(), except that would prevent us from
+ *      doing the previous check and thus failing testcase 6b.)
+ *   3. Check for rename/rename(1to2) conflicts (at the directory level).
+ *      In the future, we could potentially record this info as well and
+ *      omit reporting rename/rename(1to2) conflicts for each path within
+ *      the affected directories, thus cleaning up the merge output.
+ *   NOTE: We do NOT check for rename/rename(2to1) conflicts at the
+ *         directory level, because merging directories is fine.  If it
+ *         causes conflicts for files within those merged directories, then
+ *         that should be detected at the individual path level.
+ */
+static void handle_directory_level_conflicts(struct merge_options *o,
+                                            struct hashmap *dir_re_head,
+                                            struct tree *head,
+                                            struct hashmap *dir_re_merge,
+                                            struct tree *merge)
+{
+       struct hashmap_iter iter;
+       struct dir_rename_entry *head_ent;
+       struct dir_rename_entry *merge_ent;
+
+       struct string_list remove_from_head = STRING_LIST_INIT_NODUP;
+       struct string_list remove_from_merge = STRING_LIST_INIT_NODUP;
+
+       hashmap_iter_init(dir_re_head, &iter);
+       while ((head_ent = hashmap_iter_next(&iter))) {
+               merge_ent = dir_rename_find_entry(dir_re_merge, head_ent->dir);
+               if (merge_ent &&
+                   !head_ent->non_unique_new_dir &&
+                   !merge_ent->non_unique_new_dir &&
+                   !strbuf_cmp(&head_ent->new_dir, &merge_ent->new_dir)) {
+                       /* 1. Renamed identically; remove it from both sides */
+                       string_list_append(&remove_from_head,
+                                          head_ent->dir)->util = head_ent;
+                       strbuf_release(&head_ent->new_dir);
+                       string_list_append(&remove_from_merge,
+                                          merge_ent->dir)->util = merge_ent;
+                       strbuf_release(&merge_ent->new_dir);
+               } else if (tree_has_path(head, head_ent->dir)) {
+                       /* 2. This wasn't a directory rename after all */
+                       string_list_append(&remove_from_head,
+                                          head_ent->dir)->util = head_ent;
+                       strbuf_release(&head_ent->new_dir);
+               }
+       }
+
+       remove_hashmap_entries(dir_re_head, &remove_from_head);
+       remove_hashmap_entries(dir_re_merge, &remove_from_merge);
+
+       hashmap_iter_init(dir_re_merge, &iter);
+       while ((merge_ent = hashmap_iter_next(&iter))) {
+               head_ent = dir_rename_find_entry(dir_re_head, merge_ent->dir);
+               if (tree_has_path(merge, merge_ent->dir)) {
+                       /* 2. This wasn't a directory rename after all */
+                       string_list_append(&remove_from_merge,
+                                          merge_ent->dir)->util = merge_ent;
+               } else if (head_ent &&
+                          !head_ent->non_unique_new_dir &&
+                          !merge_ent->non_unique_new_dir) {
+                       /* 3. rename/rename(1to2) */
+                       /*
+                        * We can assume it's not rename/rename(1to1) because
+                        * that was case (1), already checked above.  So we
+                        * know that head_ent->new_dir and merge_ent->new_dir
+                        * are different strings.
+                        */
+                       output(o, 1, _("CONFLICT (rename/rename): "
+                                      "Rename directory %s->%s in %s. "
+                                      "Rename directory %s->%s in %s"),
+                              head_ent->dir, head_ent->new_dir.buf, o->branch1,
+                              head_ent->dir, merge_ent->new_dir.buf, o->branch2);
+                       string_list_append(&remove_from_head,
+                                          head_ent->dir)->util = head_ent;
+                       strbuf_release(&head_ent->new_dir);
+                       string_list_append(&remove_from_merge,
+                                          merge_ent->dir)->util = merge_ent;
+                       strbuf_release(&merge_ent->new_dir);
+               }
+       }
+
+       remove_hashmap_entries(dir_re_head, &remove_from_head);
+       remove_hashmap_entries(dir_re_merge, &remove_from_merge);
+}
+
+static struct hashmap *get_directory_renames(struct diff_queue_struct *pairs,
+                                            struct tree *tree)
+{
+       struct hashmap *dir_renames;
+       struct hashmap_iter iter;
+       struct dir_rename_entry *entry;
+       int i;
+
+       /*
+        * Typically, we think of a directory rename as all files from a
+        * certain directory being moved to a target directory.  However,
+        * what if someone first moved two files from the original
+        * directory in one commit, and then renamed the directory
+        * somewhere else in a later commit?  At merge time, we just know
+        * that files from the original directory went to two different
+        * places, and that the bulk of them ended up in the same place.
+        * We want each directory rename to represent where the bulk of the
+        * files from that directory end up; this function exists to find
+        * where the bulk of the files went.
+        *
+        * The first loop below simply iterates through the list of file
+        * renames, finding out how often each directory rename pair
+        * possibility occurs.
+        */
+       dir_renames = xmalloc(sizeof(*dir_renames));
+       dir_rename_init(dir_renames);
+       for (i = 0; i < pairs->nr; ++i) {
+               struct string_list_item *item;
+               int *count;
+               struct diff_filepair *pair = pairs->queue[i];
+               char *old_dir, *new_dir;
+
+               /* File not part of directory rename if it wasn't renamed */
+               if (pair->status != 'R')
+                       continue;
+
+               get_renamed_dir_portion(pair->one->path, pair->two->path,
+                                       &old_dir,        &new_dir);
+               if (!old_dir)
+                       /* Directory didn't change at all; ignore this one. */
+                       continue;
+
+               entry = dir_rename_find_entry(dir_renames, old_dir);
+               if (!entry) {
+                       entry = xmalloc(sizeof(*entry));
+                       dir_rename_entry_init(entry, old_dir);
+                       hashmap_put(dir_renames, entry);
+               } else {
+                       free(old_dir);
+               }
+               item = string_list_lookup(&entry->possible_new_dirs, new_dir);
+               if (!item) {
+                       item = string_list_insert(&entry->possible_new_dirs,
+                                                 new_dir);
+                       item->util = xcalloc(1, sizeof(int));
+               } else {
+                       free(new_dir);
+               }
+               count = item->util;
+               *count += 1;
+       }
+
+       /*
+        * For each directory with files moved out of it, we find out which
+        * target directory received the most files so we can declare it to
+        * be the "winning" target location for the directory rename.  This
+        * winner gets recorded in new_dir.  If there is no winner
+        * (multiple target directories received the same number of files),
+        * we set non_unique_new_dir.  Once we've determined the winner (or
+        * that there is no winner), we no longer need possible_new_dirs.
+        */
+       hashmap_iter_init(dir_renames, &iter);
+       while ((entry = hashmap_iter_next(&iter))) {
+               int max = 0;
+               int bad_max = 0;
+               char *best = NULL;
+
+               for (i = 0; i < entry->possible_new_dirs.nr; i++) {
+                       int *count = entry->possible_new_dirs.items[i].util;
+
+                       if (*count == max)
+                               bad_max = max;
+                       else if (*count > max) {
+                               max = *count;
+                               best = entry->possible_new_dirs.items[i].string;
+                       }
+               }
+               if (bad_max == max)
+                       entry->non_unique_new_dir = 1;
+               else {
+                       assert(entry->new_dir.len == 0);
+                       strbuf_addstr(&entry->new_dir, best);
+               }
+               /*
+                * The relevant directory sub-portion of the original full
+                * filepaths were xstrndup'ed before inserting into
+                * possible_new_dirs, and instead of manually iterating the
+                * list and free'ing each, just lie and tell
+                * possible_new_dirs that it did the strdup'ing so that it
+                * will free them for us.
+                */
+               entry->possible_new_dirs.strdup_strings = 1;
+               string_list_clear(&entry->possible_new_dirs, 1);
+       }
+
+       return dir_renames;
+}
+
+static struct dir_rename_entry *check_dir_renamed(const char *path,
+                                                 struct hashmap *dir_renames)
+{
+       char *temp = xstrdup(path);
+       char *end;
+       struct dir_rename_entry *entry = NULL;;
+
+       while ((end = strrchr(temp, '/'))) {
+               *end = '\0';
+               entry = dir_rename_find_entry(dir_renames, temp);
+               if (entry)
+                       break;
+       }
+       free(temp);
+       return entry;
+}
+
+static void compute_collisions(struct hashmap *collisions,
+                              struct hashmap *dir_renames,
+                              struct diff_queue_struct *pairs)
+{
+       int i;
+
+       /*
+        * Multiple files can be mapped to the same path due to directory
+        * renames done by the other side of history.  Since that other
+        * side of history could have merged multiple directories into one,
+        * if our side of history added the same file basename to each of
+        * those directories, then all N of them would get implicitly
+        * renamed by the directory rename detection into the same path,
+        * and we'd get an add/add/.../add conflict, and all those adds
+        * from *this* side of history.  This is not representable in the
+        * index, and users aren't going to easily be able to make sense of
+        * it.  So we need to provide a good warning about what's
+        * happening, and fall back to no-directory-rename detection
+        * behavior for those paths.
+        *
+        * See testcases 9e and all of section 5 from t6043 for examples.
+        */
+       collision_init(collisions);
+
+       for (i = 0; i < pairs->nr; ++i) {
+               struct dir_rename_entry *dir_rename_ent;
+               struct collision_entry *collision_ent;
+               char *new_path;
+               struct diff_filepair *pair = pairs->queue[i];
+
+               if (pair->status != 'A' && pair->status != 'R')
+                       continue;
+               dir_rename_ent = check_dir_renamed(pair->two->path,
+                                                  dir_renames);
+               if (!dir_rename_ent)
+                       continue;
+
+               new_path = apply_dir_rename(dir_rename_ent, pair->two->path);
+               if (!new_path)
+                       /*
+                        * dir_rename_ent->non_unique_new_path is true, which
+                        * means there is no directory rename for us to use,
+                        * which means it won't cause us any additional
+                        * collisions.
+                        */
+                       continue;
+               collision_ent = collision_find_entry(collisions, new_path);
+               if (!collision_ent) {
+                       collision_ent = xcalloc(1,
+                                               sizeof(struct collision_entry));
+                       hashmap_entry_init(collision_ent, strhash(new_path));
+                       hashmap_put(collisions, collision_ent);
+                       collision_ent->target_file = new_path;
+               } else {
+                       free(new_path);
+               }
+               string_list_insert(&collision_ent->source_files,
+                                  pair->two->path);
+       }
+}
+
+static char *check_for_directory_rename(struct merge_options *o,
+                                       const char *path,
+                                       struct tree *tree,
+                                       struct hashmap *dir_renames,
+                                       struct hashmap *dir_rename_exclusions,
+                                       struct hashmap *collisions,
+                                       int *clean_merge)
+{
+       char *new_path = NULL;
+       struct dir_rename_entry *entry = check_dir_renamed(path, dir_renames);
+       struct dir_rename_entry *oentry = NULL;
+
+       if (!entry)
+               return new_path;
+
+       /*
+        * This next part is a little weird.  We do not want to do an
+        * implicit rename into a directory we renamed on our side, because
+        * that will result in a spurious rename/rename(1to2) conflict.  An
+        * example:
+        *   Base commit: dumbdir/afile, otherdir/bfile
+        *   Side 1:      smrtdir/afile, otherdir/bfile
+        *   Side 2:      dumbdir/afile, dumbdir/bfile
+        * Here, while working on Side 1, we could notice that otherdir was
+        * renamed/merged to dumbdir, and change the diff_filepair for
+        * otherdir/bfile into a rename into dumbdir/bfile.  However, Side
+        * 2 will notice the rename from dumbdir to smrtdir, and do the
+        * transitive rename to move it from dumbdir/bfile to
+        * smrtdir/bfile.  That gives us bfile in dumbdir vs being in
+        * smrtdir, a rename/rename(1to2) conflict.  We really just want
+        * the file to end up in smrtdir.  And the way to achieve that is
+        * to not let Side1 do the rename to dumbdir, since we know that is
+        * the source of one of our directory renames.
+        *
+        * That's why oentry and dir_rename_exclusions is here.
+        *
+        * As it turns out, this also prevents N-way transient rename
+        * confusion; See testcases 9c and 9d of t6043.
+        */
+       oentry = dir_rename_find_entry(dir_rename_exclusions, entry->new_dir.buf);
+       if (oentry) {
+               output(o, 1, _("WARNING: Avoiding applying %s -> %s rename "
+                              "to %s, because %s itself was renamed."),
+                      entry->dir, entry->new_dir.buf, path, entry->new_dir.buf);
+       } else {
+               new_path = handle_path_level_conflicts(o, path, entry,
+                                                      collisions, tree);
+               *clean_merge &= (new_path != NULL);
+       }
+
+       return new_path;
+}
+
+static void apply_directory_rename_modifications(struct merge_options *o,
+                                                struct diff_filepair *pair,
+                                                char *new_path,
+                                                struct rename *re,
+                                                struct tree *tree,
+                                                struct tree *o_tree,
+                                                struct tree *a_tree,
+                                                struct tree *b_tree,
+                                                struct string_list *entries,
+                                                int *clean)
+{
+       struct string_list_item *item;
+       int stage = (tree == a_tree ? 2 : 3);
+       int update_wd;
+
+       /*
+        * In all cases where we can do directory rename detection,
+        * unpack_trees() will have read pair->two->path into the
+        * index and the working copy.  We need to remove it so that
+        * we can instead place it at new_path.  It is guaranteed to
+        * not be untracked (unpack_trees() would have errored out
+        * saying the file would have been overwritten), but it might
+        * be dirty, though.
+        */
+       update_wd = !was_dirty(o, pair->two->path);
+       if (!update_wd)
+               output(o, 1, _("Refusing to lose dirty file at %s"),
+                      pair->two->path);
+       remove_file(o, 1, pair->two->path, !update_wd);
+
+       /* Find or create a new re->dst_entry */
+       item = string_list_lookup(entries, new_path);
+       if (item) {
+               /*
+                * Since we're renaming on this side of history, and it's
+                * due to a directory rename on the other side of history
+                * (which we only allow when the directory in question no
+                * longer exists on the other side of history), the
+                * original entry for re->dst_entry is no longer
+                * necessary...
+                */
+               re->dst_entry->processed = 1;
+
+               /*
+                * ...because we'll be using this new one.
+                */
+               re->dst_entry = item->util;
+       } else {
+               /*
+                * re->dst_entry is for the before-dir-rename path, and we
+                * need it to hold information for the after-dir-rename
+                * path.  Before creating a new entry, we need to mark the
+                * old one as unnecessary (...unless it is shared by
+                * src_entry, i.e. this didn't use to be a rename, in which
+                * case we can just allow the normal processing to happen
+                * for it).
+                */
+               if (pair->status == 'R')
+                       re->dst_entry->processed = 1;
+
+               re->dst_entry = insert_stage_data(new_path,
+                                                 o_tree, a_tree, b_tree,
+                                                 entries);
+               item = string_list_insert(entries, new_path);
+               item->util = re->dst_entry;
+       }
+
+       /*
+        * Update the stage_data with the information about the path we are
+        * moving into place.  That slot will be empty and available for us
+        * to write to because of the collision checks in
+        * handle_path_level_conflicts().  In other words,
+        * re->dst_entry->stages[stage].oid will be the null_oid, so it's
+        * open for us to write to.
+        *
+        * It may be tempting to actually update the index at this point as
+        * well, using update_stages_for_stage_data(), but as per the big
+        * "NOTE" in update_stages(), doing so will modify the current
+        * in-memory index which will break calls to would_lose_untracked()
+        * that we need to make.  Instead, we need to just make sure that
+        * the various conflict_rename_*() functions update the index
+        * explicitly rather than relying on unpack_trees() to have done it.
+        */
+       get_tree_entry(&tree->object.oid,
+                      pair->two->path,
+                      &re->dst_entry->stages[stage].oid,
+                      &re->dst_entry->stages[stage].mode);
+
+       /* Update pair status */
+       if (pair->status == 'A') {
+               /*
+                * Recording rename information for this add makes it look
+                * like a rename/delete conflict.  Make sure we can
+                * correctly handle this as an add that was moved to a new
+                * directory instead of reporting a rename/delete conflict.
+                */
+               re->add_turned_into_rename = 1;
+       }
+       /*
+        * We don't actually look at pair->status again, but it seems
+        * pedagogically correct to adjust it.
+        */
+       pair->status = 'R';
+
+       /*
+        * Finally, record the new location.
+        */
+       pair->two->path = new_path;
+}
+
+/*
+ * Get information of all renames which occurred in 'pairs', making use of
+ * any implicit directory renames inferred from the other side of history.
+ * We need the three trees in the merge ('o_tree', 'a_tree' and 'b_tree')
+ * to be able to associate the correct cache entries with the rename
+ * information; tree is always equal to either a_tree or b_tree.
+ */
+static struct string_list *get_renames(struct merge_options *o,
+                                      struct diff_queue_struct *pairs,
+                                      struct hashmap *dir_renames,
+                                      struct hashmap *dir_rename_exclusions,
+                                      struct tree *tree,
+                                      struct tree *o_tree,
+                                      struct tree *a_tree,
+                                      struct tree *b_tree,
+                                      struct string_list *entries,
+                                      int *clean_merge)
+{
+       int i;
+       struct hashmap collisions;
+       struct hashmap_iter iter;
+       struct collision_entry *e;
+       struct string_list *renames;
+
+       compute_collisions(&collisions, dir_renames, pairs);
+       renames = xcalloc(1, sizeof(struct string_list));
+
+       for (i = 0; i < pairs->nr; ++i) {
+               struct string_list_item *item;
+               struct rename *re;
+               struct diff_filepair *pair = pairs->queue[i];
+               char *new_path; /* non-NULL only with directory renames */
+
+               if (pair->status != 'A' && pair->status != 'R') {
+                       diff_free_filepair(pair);
+                       continue;
+               }
+               new_path = check_for_directory_rename(o, pair->two->path, tree,
+                                                     dir_renames,
+                                                     dir_rename_exclusions,
+                                                     &collisions,
+                                                     clean_merge);
+               if (pair->status != 'R' && !new_path) {
+                       diff_free_filepair(pair);
+                       continue;
+               }
+
+               re = xmalloc(sizeof(*re));
+               re->processed = 0;
+               re->add_turned_into_rename = 0;
+               re->pair = pair;
+               item = string_list_lookup(entries, re->pair->one->path);
+               if (!item)
+                       re->src_entry = insert_stage_data(re->pair->one->path,
+                                       o_tree, a_tree, b_tree, entries);
+               else
+                       re->src_entry = item->util;
+
+               item = string_list_lookup(entries, re->pair->two->path);
+               if (!item)
+                       re->dst_entry = insert_stage_data(re->pair->two->path,
+                                       o_tree, a_tree, b_tree, entries);
+               else
+                       re->dst_entry = item->util;
+               item = string_list_insert(renames, pair->one->path);
+               item->util = re;
+               if (new_path)
+                       apply_directory_rename_modifications(o, pair, new_path,
+                                                            re, tree, o_tree,
+                                                            a_tree, b_tree,
+                                                            entries,
+                                                            clean_merge);
+       }
+
+       hashmap_iter_init(&collisions, &iter);
+       while ((e = hashmap_iter_next(&iter))) {
+               free(e->target_file);
+               string_list_clear(&e->source_files, 0);
+       }
+       hashmap_free(&collisions, 1);
+       return renames;
+}
+
+static int process_renames(struct merge_options *o,
+                          struct string_list *a_renames,
+                          struct string_list *b_renames)
+{
+       int clean_merge = 1, i, j;
+       struct string_list a_by_dst = STRING_LIST_INIT_NODUP;
+       struct string_list b_by_dst = STRING_LIST_INIT_NODUP;
+       const struct rename *sre;
+
+       for (i = 0; i < a_renames->nr; i++) {
+               sre = a_renames->items[i].util;
+               string_list_insert(&a_by_dst, sre->pair->two->path)->util
+                       = (void *)sre;
+       }
+       for (i = 0; i < b_renames->nr; i++) {
+               sre = b_renames->items[i].util;
+               string_list_insert(&b_by_dst, sre->pair->two->path)->util
+                       = (void *)sre;
+       }
 
        for (i = 0, j = 0; i < a_renames->nr || j < b_renames->nr;) {
                struct string_list *renames1, *renames2Dst;
@@ -1462,7 +2604,7 @@ static int process_renames(struct merge_options *o,
                        const char *ren2_dst = ren2->pair->two->path;
                        enum rename_type rename_type;
                        if (strcmp(ren1_src, ren2_src) != 0)
-                               die("BUG: ren1_src != ren2_src");
+                               BUG("ren1_src != ren2_src");
                        ren2->dst_entry->processed = 1;
                        ren2->processed = 1;
                        if (strcmp(ren1_dst, ren2_dst) != 0) {
@@ -1496,7 +2638,7 @@ static int process_renames(struct merge_options *o,
                        ren2 = lookup->util;
                        ren2_dst = ren2->pair->two->path;
                        if (strcmp(ren1_dst, ren2_dst) != 0)
-                               die("BUG: ren1_dst != ren2_dst");
+                               BUG("ren1_dst != ren2_dst");
 
                        clean_merge = 0;
                        ren2->processed = 1;
@@ -1538,7 +2680,7 @@ static int process_renames(struct merge_options *o,
                         * add-source case).
                         */
                        remove_file(o, 1, ren1_src,
-                                   renamed_stage == 2 || !was_tracked(ren1_src));
+                                   renamed_stage == 2 || !was_tracked(o, ren1_src));
 
                        oidcpy(&src_other.oid,
                               &ren1->src_entry->stages[other_stage].oid);
@@ -1548,7 +2690,19 @@ static int process_renames(struct merge_options *o,
                        dst_other.mode = ren1->dst_entry->stages[other_stage].mode;
                        try_merge = 0;
 
-                       if (oid_eq(&src_other.oid, &null_oid)) {
+                       if (oid_eq(&src_other.oid, &null_oid) &&
+                           ren1->add_turned_into_rename) {
+                               setup_rename_conflict_info(RENAME_DIR,
+                                                          ren1->pair,
+                                                          NULL,
+                                                          branch1,
+                                                          branch2,
+                                                          ren1->dst_entry,
+                                                          NULL,
+                                                          o,
+                                                          NULL,
+                                                          NULL);
+                       } else if (oid_eq(&src_other.oid, &null_oid)) {
                                setup_rename_conflict_info(RENAME_DELETE,
                                                           ren1->pair,
                                                           NULL,
@@ -1645,6 +2799,105 @@ cleanup_and_return:
        return clean_merge;
 }
 
+struct rename_info {
+       struct string_list *head_renames;
+       struct string_list *merge_renames;
+};
+
+static void initial_cleanup_rename(struct diff_queue_struct *pairs,
+                                  struct hashmap *dir_renames)
+{
+       struct hashmap_iter iter;
+       struct dir_rename_entry *e;
+
+       hashmap_iter_init(dir_renames, &iter);
+       while ((e = hashmap_iter_next(&iter))) {
+               free(e->dir);
+               strbuf_release(&e->new_dir);
+               /* possible_new_dirs already cleared in get_directory_renames */
+       }
+       hashmap_free(dir_renames, 1);
+       free(dir_renames);
+
+       free(pairs->queue);
+       free(pairs);
+}
+
+static int handle_renames(struct merge_options *o,
+                         struct tree *common,
+                         struct tree *head,
+                         struct tree *merge,
+                         struct string_list *entries,
+                         struct rename_info *ri)
+{
+       struct diff_queue_struct *head_pairs, *merge_pairs;
+       struct hashmap *dir_re_head, *dir_re_merge;
+       int clean = 1;
+
+       ri->head_renames = NULL;
+       ri->merge_renames = NULL;
+
+       if (!merge_detect_rename(o))
+               return 1;
+
+       head_pairs = get_diffpairs(o, common, head);
+       merge_pairs = get_diffpairs(o, common, merge);
+
+       dir_re_head = get_directory_renames(head_pairs, head);
+       dir_re_merge = get_directory_renames(merge_pairs, merge);
+
+       handle_directory_level_conflicts(o,
+                                        dir_re_head, head,
+                                        dir_re_merge, merge);
+
+       ri->head_renames  = get_renames(o, head_pairs,
+                                       dir_re_merge, dir_re_head, head,
+                                       common, head, merge, entries,
+                                       &clean);
+       if (clean < 0)
+               goto cleanup;
+       ri->merge_renames = get_renames(o, merge_pairs,
+                                       dir_re_head, dir_re_merge, merge,
+                                       common, head, merge, entries,
+                                       &clean);
+       if (clean < 0)
+               goto cleanup;
+       clean &= process_renames(o, ri->head_renames, ri->merge_renames);
+
+cleanup:
+       /*
+        * Some cleanup is deferred until cleanup_renames() because the
+        * data structures are still needed and referenced in
+        * process_entry().  But there are a few things we can free now.
+        */
+       initial_cleanup_rename(head_pairs, dir_re_head);
+       initial_cleanup_rename(merge_pairs, dir_re_merge);
+
+       return clean;
+}
+
+static void final_cleanup_rename(struct string_list *rename)
+{
+       const struct rename *re;
+       int i;
+
+       if (rename == NULL)
+               return;
+
+       for (i = 0; i < rename->nr; i++) {
+               re = rename->items[i].util;
+               diff_free_filepair(re->pair);
+       }
+       string_list_clear(rename, 1);
+       free(rename);
+}
+
+static void final_cleanup_renames(struct rename_info *re_info)
+{
+       final_cleanup_rename(re_info->head_renames);
+       final_cleanup_rename(re_info->merge_renames);
+}
+
 static struct object_id *stage_oid(const struct object_id *oid, unsigned mode)
 {
        return (is_null_oid(oid) || mode == 0) ? NULL: (struct object_id *)oid;
@@ -1656,7 +2909,7 @@ static int read_oid_strbuf(struct merge_options *o,
        void *buf;
        enum object_type type;
        unsigned long size;
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf)
                return err(o, _("cannot read object %s"), oid_to_hex(oid));
        if (type != OBJ_BLOB) {
@@ -1735,6 +2988,7 @@ static int handle_modify_delete(struct merge_options *o,
 
 static int merge_content(struct merge_options *o,
                         const char *path,
+                        int is_dirty,
                         struct object_id *o_oid, int o_mode,
                         struct object_id *a_oid, int a_mode,
                         struct object_id *b_oid, int b_mode,
@@ -1775,29 +3029,26 @@ static int merge_content(struct merge_options *o,
                               S_ISGITLINK(pair1->two->mode)))
                        df_conflict_remains = 1;
        }
-       if (merge_file_special_markers(o, &one, &a, &b,
+       if (merge_file_special_markers(o, &one, &a, &b, path,
                                       o->branch1, path1,
                                       o->branch2, path2, &mfi))
                return -1;
 
-       if (mfi.clean && !df_conflict_remains &&
-           oid_eq(&mfi.oid, a_oid) && mfi.mode == a_mode) {
-               int path_renamed_outside_HEAD;
+       /*
+        * We can skip updating the working tree file iff:
+        *   a) The merge is clean
+        *   b) The merge matches what was in HEAD (content, mode, pathname)
+        *   c) The target path is usable (i.e. not involved in D/F conflict)
+        */
+       if (mfi.clean &&
+           was_tracked_and_matches(o, path, &mfi.oid, mfi.mode) &&
+           !df_conflict_remains) {
                output(o, 3, _("Skipped %s (merged same as existing)"), path);
-               /*
-                * The content merge resulted in the same file contents we
-                * already had.  We can return early if those file contents
-                * are recorded at the correct path (which may not be true
-                * if the merge involves a rename).
-                */
-               path_renamed_outside_HEAD = !path2 || !strcmp(path, path2);
-               if (!path_renamed_outside_HEAD) {
-                       add_cacheinfo(o, mfi.mode, &mfi.oid, path,
-                                     0, (!o->call_depth), 0);
-                       return mfi.clean;
-               }
-       } else
-               output(o, 2, _("Auto-merging %s"), path);
+               if (add_cacheinfo(o, mfi.mode, &mfi.oid, path,
+                                 0, (!o->call_depth && !is_dirty), 0))
+                       return -1;
+               return mfi.clean;
+       }
 
        if (!mfi.clean) {
                if (S_ISGITLINK(mfi.mode))
@@ -1809,7 +3060,7 @@ static int merge_content(struct merge_options *o,
                                return -1;
        }
 
-       if (df_conflict_remains) {
+       if (df_conflict_remains || is_dirty) {
                char *new_path;
                if (o->call_depth) {
                        remove_file_from_cache(path);
@@ -1818,7 +3069,7 @@ static int merge_content(struct merge_options *o,
                                if (update_stages(o, path, &one, &a, &b))
                                        return -1;
                        } else {
-                               int file_from_stage2 = was_tracked(path);
+                               int file_from_stage2 = was_tracked(o, path);
                                struct diff_filespec merged;
                                oidcpy(&merged.oid, &mfi.oid);
                                merged.mode = mfi.mode;
@@ -1831,6 +3082,10 @@ static int merge_content(struct merge_options *o,
 
                }
                new_path = unique_path(o, path, rename_conflict_info->branch1);
+               if (is_dirty) {
+                       output(o, 1, _("Refusing to lose dirty file at %s"),
+                              path);
+               }
                output(o, 1, _("Adding as %s instead"), new_path);
                if (update_file(o, 0, &mfi.oid, mfi.mode, new_path)) {
                        free(new_path);
@@ -1840,7 +3095,20 @@ static int merge_content(struct merge_options *o,
                mfi.clean = 0;
        } else if (update_file(o, mfi.clean, &mfi.oid, mfi.mode, path))
                return -1;
-       return mfi.clean;
+       return !is_dirty && mfi.clean;
+}
+
+static int conflict_rename_normal(struct merge_options *o,
+                                 const char *path,
+                                 struct object_id *o_oid, unsigned int o_mode,
+                                 struct object_id *a_oid, unsigned int a_mode,
+                                 struct object_id *b_oid, unsigned int b_mode,
+                                 struct rename_conflict_info *ci)
+{
+       /* Merge the content and write it out */
+       return merge_content(o, path, was_dirty(o, path),
+                            o_oid, o_mode, a_oid, a_mode, b_oid, b_mode,
+                            ci);
 }
 
 /* Per entry merge function */
@@ -1862,9 +3130,20 @@ static int process_entry(struct merge_options *o,
                switch (conflict_info->rename_type) {
                case RENAME_NORMAL:
                case RENAME_ONE_FILE_TO_ONE:
-                       clean_merge = merge_content(o, path,
-                                                   o_oid, o_mode, a_oid, a_mode, b_oid, b_mode,
-                                                   conflict_info);
+                       clean_merge = conflict_rename_normal(o,
+                                                            path,
+                                                            o_oid, o_mode,
+                                                            a_oid, a_mode,
+                                                            b_oid, b_mode,
+                                                            conflict_info);
+                       break;
+               case RENAME_DIR:
+                       clean_merge = 1;
+                       if (conflict_rename_dir(o,
+                                               conflict_info->pair1,
+                                               conflict_info->branch1,
+                                               conflict_info->branch2))
+                               clean_merge = -1;
                        break;
                case RENAME_DELETE:
                        clean_merge = 0;
@@ -1952,7 +3231,8 @@ static int process_entry(struct merge_options *o,
        } else if (a_oid && b_oid) {
                /* Case C: Added in both (check for same permissions) and */
                /* case D: Modified in both, but differently. */
-               clean_merge = merge_content(o, path,
+               int is_dirty = 0; /* unpack_trees would have bailed if dirty */
+               clean_merge = merge_content(o, path, is_dirty,
                                            o_oid, o_mode, a_oid, a_mode, b_oid, b_mode,
                                            NULL);
        } else if (!o_oid && !a_oid && !b_oid) {
@@ -1962,7 +3242,7 @@ static int process_entry(struct merge_options *o,
                 */
                remove_file(o, 1, path, !a_mode);
        } else
-               die("BUG: fatal merge failure, shouldn't happen.");
+               BUG("fatal merge failure, shouldn't happen.");
 
        return clean_merge;
 }
@@ -1993,18 +3273,20 @@ int merge_trees(struct merge_options *o,
                return 1;
        }
 
-       code = git_merge_trees(o->call_depth, common, head, merge);
+       code = unpack_trees_start(o, common, head, merge);
 
        if (code != 0) {
                if (show(o, 4) || o->call_depth)
                        err(o, _("merging of trees %s and %s failed"),
                            oid_to_hex(&head->object.oid),
                            oid_to_hex(&merge->object.oid));
+               unpack_trees_finish(o);
                return -1;
        }
 
        if (unmerged_cache()) {
-               struct string_list *entries, *re_head, *re_merge;
+               struct string_list *entries;
+               struct rename_info re_info;
                int i;
                /*
                 * Only need the hashmap while processing entries, so
@@ -2018,9 +3300,8 @@ int merge_trees(struct merge_options *o,
                get_files_dirs(o, merge);
 
                entries = get_unmerged();
-               re_head  = get_renames(o, head, common, head, merge, entries);
-               re_merge = get_renames(o, merge, common, head, merge, entries);
-               clean = process_renames(o, re_head, re_merge);
+               clean = handle_renames(o, common, head, merge, entries,
+                                      &re_info);
                record_df_conflict_files(o, entries);
                if (clean < 0)
                        goto cleanup;
@@ -2040,27 +3321,28 @@ int merge_trees(struct merge_options *o,
                for (i = 0; i < entries->nr; i++) {
                        struct stage_data *e = entries->items[i].util;
                        if (!e->processed)
-                               die("BUG: unprocessed path??? %s",
+                               BUG("unprocessed path??? %s",
                                    entries->items[i].string);
                }
 
 cleanup:
-               string_list_clear(re_merge, 0);
-               string_list_clear(re_head, 0);
+               final_cleanup_renames(&re_info);
+
                string_list_clear(entries, 1);
+               free(entries);
 
                hashmap_free(&o->current_file_dir_set, 1);
 
-               free(re_merge);
-               free(re_head);
-               free(entries);
-
-               if (clean < 0)
+               if (clean < 0) {
+                       unpack_trees_finish(o);
                        return clean;
+               }
        }
        else
                clean = 1;
 
+       unpack_trees_finish(o);
+
        if (o->call_depth && !(*result = write_tree_from_memory(o)))
                return -1;
 
@@ -2154,7 +3436,8 @@ int merge_recursive(struct merge_options *o,
                read_cache();
 
        o->ancestor = "merged common ancestors";
-       clean = merge_trees(o, h1->tree, h2->tree, merged_common_ancestors->tree,
+       clean = merge_trees(o, get_commit_tree(h1), get_commit_tree(h2),
+                           get_commit_tree(merged_common_ancestors),
                            &mrtree);
        if (clean < 0) {
                flush_output(o);
@@ -2232,9 +3515,18 @@ int merge_recursive_generic(struct merge_options *o,
 
 static void merge_recursive_config(struct merge_options *o)
 {
+       char *value = NULL;
        git_config_get_int("merge.verbosity", &o->verbosity);
        git_config_get_int("diff.renamelimit", &o->diff_rename_limit);
        git_config_get_int("merge.renamelimit", &o->merge_rename_limit);
+       if (!git_config_get_string("diff.renames", &value)) {
+               o->diff_detect_rename = git_config_rename("diff.renames", value);
+               free(value);
+       }
+       if (!git_config_get_string("merge.renames", &value)) {
+               o->merge_detect_rename = git_config_rename("merge.renames", value);
+               free(value);
+       }
        git_config(git_xmerge_config, NULL);
 }
 
@@ -2247,7 +3539,8 @@ void init_merge_options(struct merge_options *o)
        o->diff_rename_limit = -1;
        o->merge_rename_limit = -1;
        o->renormalize = 0;
-       o->detect_rename = 1;
+       o->diff_detect_rename = -1;
+       o->merge_detect_rename = -1;
        merge_recursive_config(o);
        merge_verbosity = getenv("GIT_MERGE_VERBOSITY");
        if (merge_verbosity)
@@ -2298,16 +3591,16 @@ int parse_merge_opt(struct merge_options *o, const char *s)
        else if (!strcmp(s, "no-renormalize"))
                o->renormalize = 0;
        else if (!strcmp(s, "no-renames"))
-               o->detect_rename = 0;
+               o->merge_detect_rename = 0;
        else if (!strcmp(s, "find-renames")) {
-               o->detect_rename = 1;
+               o->merge_detect_rename = 1;
                o->rename_score = 0;
        }
        else if (skip_prefix(s, "find-renames=", &arg) ||
                 skip_prefix(s, "rename-threshold=", &arg)) {
                if ((o->rename_score = parse_rename_score(&arg)) == -1 || *arg != 0)
                        return -1;
-               o->detect_rename = 1;
+               o->merge_detect_rename = 1;
        }
        else
                return -1;
index 80d69d140195cc3ba1054050569e56bfc0277b56..fa7bc6b6836f99ab9c417e2865cd5a544488d025 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef MERGE_RECURSIVE_H
 #define MERGE_RECURSIVE_H
 
+#include "unpack-trees.h"
 #include "string-list.h"
 
 struct merge_options {
@@ -17,7 +18,8 @@ struct merge_options {
        unsigned renormalize : 1;
        long xdl_opts;
        int verbosity;
-       int detect_rename;
+       int diff_detect_rename;
+       int merge_detect_rename;
        int diff_rename_limit;
        int merge_rename_limit;
        int rename_score;
@@ -27,8 +29,41 @@ struct merge_options {
        struct strbuf obuf;
        struct hashmap current_file_dir_set;
        struct string_list df_conflict_file_set;
+       struct unpack_trees_options unpack_opts;
+       struct index_state orig_index;
 };
 
+/*
+ * For dir_rename_entry, directory names are stored as a full path from the
+ * toplevel of the repository and do not include a trailing '/'.  Also:
+ *
+ *   dir:                original name of directory being renamed
+ *   non_unique_new_dir: if true, could not determine new_dir
+ *   new_dir:            final name of directory being renamed
+ *   possible_new_dirs:  temporary used to help determine new_dir; see comments
+ *                       in get_directory_renames() for details
+ */
+struct dir_rename_entry {
+       struct hashmap_entry ent; /* must be the first member! */
+       char *dir;
+       unsigned non_unique_new_dir:1;
+       struct strbuf new_dir;
+       struct string_list possible_new_dirs;
+};
+
+struct collision_entry {
+       struct hashmap_entry ent; /* must be the first member! */
+       char *target_file;
+       struct string_list source_files;
+       unsigned reported_already:1;
+};
+
+static inline int merge_detect_rename(struct merge_options *o)
+{
+       return o->merge_detect_rename >= 0 ? o->merge_detect_rename :
+               o->diff_detect_rename >= 0 ? o->diff_detect_rename : 1;
+}
+
 /* merge_trees() but with recursive ancestor consolidation */
 int merge_recursive(struct merge_options *o,
                    struct commit *h1,
diff --git a/merge.c b/merge.c
index f06a4773d4f4093d700c652accc79ae17f161a59..0783858739f84028df6eef85d3673c944fabb912 100644 (file)
--- a/merge.c
+++ b/merge.c
 
 static const char *merge_argument(struct commit *commit)
 {
-       if (commit)
-               return oid_to_hex(&commit->object.oid);
-       else
-               return EMPTY_TREE_SHA1_HEX;
+       return oid_to_hex(commit ? &commit->object.oid : the_hash_algo->empty_tree);
 }
 
 int index_has_changes(struct strbuf *sb)
@@ -94,8 +91,24 @@ int checkout_fast_forward(const struct object_id *head,
                return -1;
 
        memset(&trees, 0, sizeof(trees));
-       memset(&opts, 0, sizeof(opts));
        memset(&t, 0, sizeof(t));
+
+       trees[nr_trees] = parse_tree_indirect(head);
+       if (!trees[nr_trees++]) {
+               rollback_lock_file(&lock_file);
+               return -1;
+       }
+       trees[nr_trees] = parse_tree_indirect(remote);
+       if (!trees[nr_trees++]) {
+               rollback_lock_file(&lock_file);
+               return -1;
+       }
+       for (i = 0; i < nr_trees; i++) {
+               parse_tree(trees[i]);
+               init_tree_desc(t+i, trees[i]->buffer, trees[i]->size);
+       }
+
+       memset(&opts, 0, sizeof(opts));
        if (overwrite_ignore) {
                memset(&dir, 0, sizeof(dir));
                dir.flags |= DIR_SHOW_IGNORED;
@@ -112,24 +125,13 @@ int checkout_fast_forward(const struct object_id *head,
        opts.fn = twoway_merge;
        setup_unpack_trees_porcelain(&opts, "merge");
 
-       trees[nr_trees] = parse_tree_indirect(head);
-       if (!trees[nr_trees++]) {
-               rollback_lock_file(&lock_file);
-               return -1;
-       }
-       trees[nr_trees] = parse_tree_indirect(remote);
-       if (!trees[nr_trees++]) {
-               rollback_lock_file(&lock_file);
-               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 (unpack_trees(nr_trees, t, &opts)) {
                rollback_lock_file(&lock_file);
+               clear_unpack_trees_porcelain(&opts);
                return -1;
        }
+       clear_unpack_trees_porcelain(&opts);
+
        if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
                return error(_("unable to write new index file"));
        return 0;
diff --git a/mergetools/guiffy b/mergetools/guiffy
new file mode 100644 (file)
index 0000000..8b23a13
--- /dev/null
@@ -0,0 +1,18 @@
+diff_cmd () {
+       "$merge_tool_path" "$LOCAL" "$REMOTE"
+}
+
+merge_cmd () {
+       if $base_present
+       then
+               "$merge_tool_path" -s "$LOCAL" \
+               "$REMOTE" "$BASE" "$MERGED"
+       else
+               "$merge_tool_path" -m "$LOCAL" \
+               "$REMOTE" "$MERGED"
+       fi
+}
+
+exit_code_trustable () {
+       true
+}
index 398e61d5e943b1e6e143f159739f83fc0df9b6b8..e61988e503b0b2097afeb6716123d88429c0717d 100644 (file)
@@ -77,7 +77,7 @@ char *notes_cache_get(struct notes_cache *c, struct object_id *key_oid,
        value_oid = get_note(&c->tree, key_oid);
        if (!value_oid)
                return NULL;
-       value = read_sha1_file(value_oid->hash, &type, &size);
+       value = read_object_file(value_oid, &type, &size);
 
        *outsize = size;
        return value;
index c09c5e0e474a30b0a8bf3d91063c8bbc61e63557..d613e06574aec31e0ecaf083b489b0465e5c27f1 100644 (file)
@@ -322,7 +322,7 @@ static void write_note_to_worktree(const struct object_id *obj,
 {
        enum object_type type;
        unsigned long size;
-       void *buf = read_sha1_file(note->hash, &type, &size);
+       void *buf = read_object_file(note, &type, &size);
 
        if (!buf)
                die("cannot read note %s for object %s",
@@ -442,7 +442,7 @@ static int merge_one_change(struct notes_merge_options *o,
                        printf("Using remote notes for %s\n",
                                                oid_to_hex(&p->obj));
                if (add_note(t, &p->obj, &p->remote, combine_notes_overwrite))
-                       die("BUG: combine_notes_overwrite failed");
+                       BUG("combine_notes_overwrite failed");
                return 0;
        case NOTES_MERGE_RESOLVE_UNION:
                if (o->verbosity >= 2)
@@ -490,7 +490,7 @@ static int merge_changes(struct notes_merge_options *o,
                        trace_printf("\t\t\tno local change, adopted remote\n");
                        if (add_note(t, &p->obj, &p->remote,
                                     combine_notes_overwrite))
-                               die("BUG: combine_notes_overwrite failed");
+                               BUG("combine_notes_overwrite failed");
                } else {
                        /* need file-level merge between local and remote */
                        trace_printf("\t\t\tneed content-level merge\n");
@@ -600,14 +600,14 @@ int notes_merge(struct notes_merge_options *o,
                        printf("No merge base found; doing history-less merge\n");
        } else if (!bases->next) {
                base_oid = &bases->item->object.oid;
-               base_tree_oid = &bases->item->tree->object.oid;
+               base_tree_oid = get_commit_tree_oid(bases->item);
                if (o->verbosity >= 4)
                        printf("One merge base found (%.7s)\n",
                               oid_to_hex(base_oid));
        } else {
                /* TODO: How to handle multiple merge-bases? */
                base_oid = &bases->item->object.oid;
-               base_tree_oid = &bases->item->tree->object.oid;
+               base_tree_oid = get_commit_tree_oid(bases->item);
                if (o->verbosity >= 3)
                        printf("Multiple merge bases found. Using the first "
                                "(%.7s)\n", oid_to_hex(base_oid));
@@ -634,8 +634,9 @@ int notes_merge(struct notes_merge_options *o,
                goto found_result;
        }
 
-       result = merge_from_diffs(o, base_tree_oid, &local->tree->object.oid,
-                                 &remote->tree->object.oid, local_tree);
+       result = merge_from_diffs(o, base_tree_oid,
+                                 get_commit_tree_oid(local),
+                                 get_commit_tree_oid(remote), local_tree);
 
        if (result != 0) { /* non-trivial merge (with or without conflicts) */
                /* Commit (partial) result */
diff --git a/notes.c b/notes.c
index ce9a8f53f8668bbbf790f3b2d20f641fc034c301..a386d450c4c812ef30d0fc661fe2c03e1d062a83 100644 (file)
--- a/notes.c
+++ b/notes.c
@@ -796,13 +796,13 @@ int combine_notes_concatenate(struct object_id *cur_oid,
 
        /* read in both note blob objects */
        if (!is_null_oid(new_oid))
-               new_msg = read_sha1_file(new_oid->hash, &new_type, &new_len);
+               new_msg = read_object_file(new_oid, &new_type, &new_len);
        if (!new_msg || !new_len || new_type != OBJ_BLOB) {
                free(new_msg);
                return 0;
        }
        if (!is_null_oid(cur_oid))
-               cur_msg = read_sha1_file(cur_oid->hash, &cur_type, &cur_len);
+               cur_msg = read_object_file(cur_oid, &cur_type, &cur_len);
        if (!cur_msg || !cur_len || cur_type != OBJ_BLOB) {
                free(cur_msg);
                free(new_msg);
@@ -858,7 +858,7 @@ static int string_list_add_note_lines(struct string_list *list,
                return 0;
 
        /* read_sha1_file NUL-terminates */
-       data = read_sha1_file(oid->hash, &t, &len);
+       data = read_object_file(oid, &t, &len);
        if (t != OBJ_BLOB || !data || !len) {
                free(data);
                return t != OBJ_BLOB || !data;
@@ -1012,7 +1012,7 @@ void init_notes(struct notes_tree *t, const char *notes_ref,
                return;
        if (flags & NOTES_INIT_WRITABLE && read_ref(notes_ref, &object_oid))
                die("Cannot use notes ref %s", notes_ref);
-       if (get_tree_entry(object_oid.hash, "", oid.hash, &mode))
+       if (get_tree_entry(&object_oid, "", &oid, &mode))
                die("Failed to read notes tree referenced by %s (%s)",
                    notes_ref, oid_to_hex(&object_oid));
 
@@ -1217,7 +1217,7 @@ static void format_note(struct notes_tree *t, const struct object_id *object_oid
        if (!oid)
                return;
 
-       if (!(msg = read_sha1_file(oid->hash, &type, &msglen)) || type != OBJ_BLOB) {
+       if (!(msg = read_object_file(oid, &type, &msglen)) || type != OBJ_BLOB) {
                free(msg);
                return;
        }
diff --git a/object-store.h b/object-store.h
new file mode 100644 (file)
index 0000000..d683112
--- /dev/null
@@ -0,0 +1,142 @@
+#ifndef OBJECT_STORE_H
+#define OBJECT_STORE_H
+
+#include "oidmap.h"
+
+struct alternate_object_database {
+       struct alternate_object_database *next;
+
+       /* see alt_scratch_buf() */
+       struct strbuf scratch;
+       size_t base_len;
+
+       /*
+        * Used to store the results of readdir(3) calls when searching
+        * for unique abbreviated hashes.  This cache is never
+        * invalidated, thus it's racy and not necessarily accurate.
+        * That's fine for its purpose; don't use it for tasks requiring
+        * greater accuracy!
+        */
+       char loose_objects_subdir_seen[256];
+       struct oid_array loose_objects_cache;
+
+       /*
+        * Path to the alternative object store. If this is a relative path,
+        * it is relative to the current working directory.
+        */
+       char path[FLEX_ARRAY];
+};
+void prepare_alt_odb(struct repository *r);
+char *compute_alternate_path(const char *path, struct strbuf *err);
+typedef int alt_odb_fn(struct alternate_object_database *, void *);
+int foreach_alt_odb(alt_odb_fn, void*);
+
+/*
+ * Allocate a "struct alternate_object_database" but do _not_ actually
+ * add it to the list of alternates.
+ */
+struct alternate_object_database *alloc_alt_odb(const char *dir);
+
+/*
+ * Add the directory to the on-disk alternates file; the new entry will also
+ * take effect in the current process.
+ */
+void add_to_alternates_file(const char *dir);
+
+/*
+ * Add the directory to the in-memory list of alternates (along with any
+ * recursive alternates it points to), but do not modify the on-disk alternates
+ * file.
+ */
+void add_to_alternates_memory(const char *dir);
+
+/*
+ * Returns a scratch strbuf pre-filled with the alternate object directory,
+ * including a trailing slash, which can be used to access paths in the
+ * alternate. Always use this over direct access to alt->scratch, as it
+ * cleans up any previous use of the scratch buffer.
+ */
+struct strbuf *alt_scratch_buf(struct alternate_object_database *alt);
+
+struct packed_git {
+       struct packed_git *next;
+       struct list_head mru;
+       struct pack_window *windows;
+       off_t pack_size;
+       const void *index_data;
+       size_t index_size;
+       uint32_t num_objects;
+       uint32_t num_bad_objects;
+       unsigned char *bad_object_sha1;
+       int index_version;
+       time_t mtime;
+       int pack_fd;
+       int index;              /* for builtin/pack-objects.c */
+       unsigned pack_local:1,
+                pack_keep:1,
+                pack_keep_in_core:1,
+                freshened:1,
+                do_not_close:1,
+                pack_promisor:1;
+       unsigned char sha1[20];
+       struct revindex_entry *revindex;
+       /* something like ".git/objects/pack/xxxxx.pack" */
+       char pack_name[FLEX_ARRAY]; /* more */
+};
+
+struct raw_object_store {
+       /*
+        * Path to the repository's object store.
+        * Cannot be NULL after initialization.
+        */
+       char *objectdir;
+
+       /* Path to extra alternate object database if not NULL */
+       char *alternate_db;
+
+       struct alternate_object_database *alt_odb_list;
+       struct alternate_object_database **alt_odb_tail;
+
+       /*
+        * Objects that should be substituted by other objects
+        * (see git-replace(1)).
+        */
+       struct oidmap *replace_map;
+
+       /*
+        * private data
+        *
+        * should only be accessed directly by packfile.c
+        */
+
+       struct packed_git *packed_git;
+       /* A most-recently-used ordered version of the packed_git list. */
+       struct list_head packed_git_mru;
+
+       /*
+        * A fast, rough count of the number of objects in the repository.
+        * These two fields are not meant for direct access. Use
+        * approximate_object_count() instead.
+        */
+       unsigned long approximate_object_count;
+       unsigned approximate_object_count_valid : 1;
+
+       /*
+        * Whether packed_git has already been populated with this repository's
+        * packs.
+        */
+       unsigned packed_git_initialized : 1;
+};
+
+struct raw_object_store *raw_object_store_new(void);
+void raw_object_store_clear(struct raw_object_store *o);
+
+/*
+ * Put in `buf` the name of the file in the local object database that
+ * would be used to store a loose object with the specified sha1.
+ */
+void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1);
+
+void *map_sha1_file(struct repository *r, const unsigned char *sha1, unsigned long *size);
+
+#endif /* OBJECT_STORE_H */
index e6ad3f61f03a98aa82dd901d96cbc230381c2e90..f7f4de3aaf6d42a6dde5811b37aa8239ac183754 100644 (file)
--- a/object.c
+++ b/object.c
@@ -1,9 +1,12 @@
 #include "cache.h"
 #include "object.h"
+#include "replace-object.h"
 #include "blob.h"
 #include "tree.h"
 #include "commit.h"
 #include "tag.h"
+#include "object-store.h"
+#include "packfile.h"
 
 static struct object **obj_hash;
 static int nr_objs, obj_hash_size;
@@ -244,7 +247,7 @@ struct object *parse_object(const struct object_id *oid)
        unsigned long size;
        enum object_type type;
        int eaten;
-       const unsigned char *repl = lookup_replace_object(oid->hash);
+       const struct object_id *repl = lookup_replace_object(the_repository, oid);
        void *buffer;
        struct object *obj;
 
@@ -254,8 +257,8 @@ struct object *parse_object(const struct object_id *oid)
 
        if ((obj && obj->type == OBJ_BLOB && has_object_file(oid)) ||
            (!obj && has_object_file(oid) &&
-            sha1_object_info(oid->hash, NULL) == OBJ_BLOB)) {
-               if (check_sha1_signature(repl, NULL, 0, NULL) < 0) {
+            oid_object_info(the_repository, oid, NULL) == OBJ_BLOB)) {
+               if (check_object_signature(repl, NULL, 0, NULL) < 0) {
                        error("sha1 mismatch %s", oid_to_hex(oid));
                        return NULL;
                }
@@ -263,11 +266,11 @@ struct object *parse_object(const struct object_id *oid)
                return lookup_object(oid->hash);
        }
 
-       buffer = read_sha1_file(oid->hash, &type, &size);
+       buffer = read_object_file(oid, &type, &size);
        if (buffer) {
-               if (check_sha1_signature(repl, buffer, size, type_name(type)) < 0) {
+               if (check_object_signature(repl, buffer, size, type_name(type)) < 0) {
                        free(buffer);
-                       error("sha1 mismatch %s", sha1_to_hex(repl));
+                       error("sha1 mismatch %s", oid_to_hex(repl));
                        return NULL;
                }
 
@@ -445,3 +448,46 @@ void clear_commit_marks_all(unsigned int flags)
                        obj->flags &= ~flags;
        }
 }
+
+struct raw_object_store *raw_object_store_new(void)
+{
+       struct raw_object_store *o = xmalloc(sizeof(*o));
+
+       memset(o, 0, sizeof(*o));
+       INIT_LIST_HEAD(&o->packed_git_mru);
+       return o;
+}
+
+static void free_alt_odb(struct alternate_object_database *alt)
+{
+       strbuf_release(&alt->scratch);
+       oid_array_clear(&alt->loose_objects_cache);
+       free(alt);
+}
+
+static void free_alt_odbs(struct raw_object_store *o)
+{
+       while (o->alt_odb_list) {
+               struct alternate_object_database *next;
+
+               next = o->alt_odb_list->next;
+               free_alt_odb(o->alt_odb_list);
+               o->alt_odb_list = next;
+       }
+}
+
+void raw_object_store_clear(struct raw_object_store *o)
+{
+       FREE_AND_NULL(o->objectdir);
+       FREE_AND_NULL(o->alternate_db);
+
+       oidmap_free(o->replace_map, 1);
+       FREE_AND_NULL(o->replace_map);
+
+       free_alt_odbs(o);
+       o->alt_odb_tail = NULL;
+
+       INIT_LIST_HEAD(&o->packed_git_mru);
+       close_all_packs(o);
+       o->packed_git = NULL;
+}
index f13f85b2a94e3afc15debfbaf89416b5cda45acb..5c13955000cdaec252f29a3b93599560c35deb8a 100644 (file)
--- a/object.h
+++ b/object.h
@@ -25,7 +25,6 @@ struct object_array {
 
 #define OBJECT_ARRAY_INIT { 0, 0, NULL }
 
-#define TYPE_BITS   3
 /*
  * object flag allocation:
  * revision.h:               0---------10                                26
@@ -37,7 +36,7 @@ struct object_array {
  * bundle.c:                                        16
  * http-push.c:                                     16-----19
  * commit.c:                                        16-----19
- * sha1_name.c:                                              20
+ * sha1-name.c:                                              20
  * list-objects-filter.c:                                      21
  * builtin/fsck.c:           0--3
  * builtin/index-pack.c:                                     2021
index e01f9928840488b85db2ebc62527d8e4aab81ffc..7b2dc3e7dc768a2d2405a9ae3b1d13f86069a93d 100644 (file)
@@ -48,7 +48,8 @@ void bitmap_writer_show_progress(int show)
 /**
  * Build the initial type index for the packfile
  */
-void bitmap_writer_build_type_index(struct pack_idx_entry **index,
+void bitmap_writer_build_type_index(struct packing_data *to_pack,
+                                   struct pack_idx_entry **index,
                                    uint32_t index_nr)
 {
        uint32_t i;
@@ -57,24 +58,25 @@ void bitmap_writer_build_type_index(struct pack_idx_entry **index,
        writer.trees = ewah_new();
        writer.blobs = ewah_new();
        writer.tags = ewah_new();
+       ALLOC_ARRAY(to_pack->in_pack_pos, to_pack->nr_objects);
 
        for (i = 0; i < index_nr; ++i) {
                struct object_entry *entry = (struct object_entry *)index[i];
                enum object_type real_type;
 
-               entry->in_pack_pos = i;
+               oe_set_in_pack_pos(to_pack, entry, i);
 
-               switch (entry->type) {
+               switch (oe_type(entry)) {
                case OBJ_COMMIT:
                case OBJ_TREE:
                case OBJ_BLOB:
                case OBJ_TAG:
-                       real_type = entry->type;
+                       real_type = oe_type(entry);
                        break;
 
                default:
-                       real_type = sha1_object_info(entry->idx.oid.hash,
-                                                    NULL);
+                       real_type = oid_object_info(the_repository,
+                                                   &entry->idx.oid, NULL);
                        break;
                }
 
@@ -98,7 +100,7 @@ void bitmap_writer_build_type_index(struct pack_idx_entry **index,
                default:
                        die("Missing type information for %s (%d/%d)",
                            oid_to_hex(&entry->idx.oid), real_type,
-                           entry->type);
+                           oe_type(entry));
                }
        }
 }
@@ -147,7 +149,7 @@ static uint32_t find_object_pos(const unsigned char *sha1)
                        "(object %s is missing)", sha1_to_hex(sha1));
        }
 
-       return entry->in_pack_pos;
+       return oe_in_pack_pos(writer.to_pack, entry);
 }
 
 static void show_object(struct object *object, const char *name, void *data)
@@ -475,7 +477,7 @@ static void write_selected_commits_v1(struct hashfile *f,
                        sha1_pos(stored->commit->object.oid.hash, index, index_nr, sha1_access);
 
                if (commit_pos < 0)
-                       die("BUG: trying to write commit not in index");
+                       BUG("trying to write commit not in index");
 
                hashwrite_be32(f, commit_pos);
                hashwrite_u8(f, stored->xor_offset);
@@ -535,7 +537,7 @@ void bitmap_writer_finish(struct pack_idx_entry **index,
        if (options & BITMAP_OPT_HASH_CACHE)
                write_hash_cache(f, index, index_nr);
 
-       hashclose(f, NULL, CSUM_FSYNC);
+       finalize_hashfile(f, NULL, CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE);
 
        if (adjust_shared_perm(tmp_file.buf))
                die_errno("unable to make temporary bitmap file readable");
index 9270983e5f581e40f894a8885396e43d13e71015..18f8b22aeb422bb81999e1e564006daf8b64f637 100644 (file)
@@ -10,6 +10,8 @@
 #include "pack-revindex.h"
 #include "pack-objects.h"
 #include "packfile.h"
+#include "repository.h"
+#include "object-store.h"
 
 /*
  * An entry on the bitmap index, representing the bitmap for a given
@@ -118,7 +120,7 @@ static struct ewah_bitmap *read_bitmap_1(struct bitmap_index *index)
 {
        struct ewah_bitmap *b = ewah_pool_new();
 
-       int bitmap_size = ewah_read_mmap(b,
+       ssize_t bitmap_size = ewah_read_mmap(b,
                index->map + index->map_pos,
                index->map_size - index->map_pos);
 
@@ -253,7 +255,7 @@ static char *pack_bitmap_filename(struct packed_git *p)
        size_t len;
 
        if (!strip_suffix(p->pack_name, ".pack", &len))
-               die("BUG: pack_name does not end in .pack");
+               BUG("pack_name does not end in .pack");
        return xstrfmt("%.*s.bitmap", (int)len, p->pack_name);
 }
 
@@ -334,8 +336,7 @@ static int open_pack_bitmap(void)
 
        assert(!bitmap_git.map && !bitmap_git.loaded);
 
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                if (open_pack_bitmap_1(p) == 0)
                        ret = 0;
        }
@@ -722,13 +723,13 @@ int prepare_bitmap_walk(struct rev_info *revs)
                revs->ignore_missing_links = 0;
 
                if (haves_bitmap == NULL)
-                       die("BUG: failed to perform bitmap walk");
+                       BUG("failed to perform bitmap walk");
        }
 
        wants_bitmap = find_objects(revs, wants, haves_bitmap);
 
        if (!wants_bitmap)
-               die("BUG: failed to perform bitmap walk");
+               BUG("failed to perform bitmap walk");
 
        if (haves_bitmap)
                bitmap_and_not(wants_bitmap, haves_bitmap);
@@ -1032,7 +1033,7 @@ int rebuild_existing_bitmaps(struct packing_data *mapping,
                oe = packlist_find(mapping, sha1, NULL);
 
                if (oe)
-                       reposition[i] = oe->in_pack_pos + 1;
+                       reposition[i] = oe_in_pack_pos(mapping, oe) + 1;
        }
 
        rebuild = bitmap_new();
index 3742a00e14a0d4da335253b2a76f978edb499d35..5ded2f139a6ccdab725ed5e568b1100906f4b736 100644 (file)
@@ -44,7 +44,9 @@ int rebuild_existing_bitmaps(struct packing_data *mapping, khash_sha1 *reused_bi
 
 void bitmap_writer_show_progress(int show);
 void bitmap_writer_set_checksum(unsigned char *sha1);
-void bitmap_writer_build_type_index(struct pack_idx_entry **index, uint32_t index_nr);
+void bitmap_writer_build_type_index(struct packing_data *to_pack,
+                                   struct pack_idx_entry **index,
+                                   uint32_t index_nr);
 void bitmap_writer_reuse_bitmaps(struct packing_data *to_pack);
 void bitmap_writer_select_commits(struct commit **indexed_commits,
                unsigned int indexed_commits_nr, int max_bitmaps);
index 8fc7dd1694cf1a67da69bc010879e0c54ee403be..d3a57df34f2d2bf0ef9935a51f171f24d8ed6a72 100644 (file)
@@ -1,8 +1,10 @@
 #include "cache.h"
+#include "repository.h"
 #include "pack.h"
 #include "pack-revindex.h"
 #include "progress.h"
 #include "packfile.h"
+#include "object-store.h"
 
 struct idx_entry {
        off_t                offset;
@@ -126,14 +128,14 @@ static int verify_packfile(struct packed_git *p,
 
                if (type == OBJ_BLOB && big_file_threshold <= size) {
                        /*
-                        * Let check_sha1_signature() check it with
+                        * Let check_object_signature() check it with
                         * the streaming interface; no point slurping
                         * the data in-core only to discard.
                         */
                        data = NULL;
                        data_valid = 0;
                } else {
-                       data = unpack_entry(p, entries[i].offset, &type, &size);
+                       data = unpack_entry(the_repository, p, entries[i].offset, &type, &size);
                        data_valid = 1;
                }
 
@@ -141,7 +143,7 @@ static int verify_packfile(struct packed_git *p,
                        err = error("cannot unpack %s from %s at offset %"PRIuMAX"",
                                    oid_to_hex(entries[i].oid.oid), p->pack_name,
                                    (uintmax_t)entries[i].offset);
-               else if (check_sha1_signature(entries[i].oid.hash, data, size, type_name(type)))
+               else if (check_object_signature(entries[i].oid.oid, data, size, type_name(type)))
                        err = error("packed %s from %s is corrupt",
                                    oid_to_hex(entries[i].oid.oid), p->pack_name);
                else if (fn) {
index 9558d13834e2842d32fa4015f2e3c00538d52dcd..92708522e76b4565882177f899612d72a3f6d75a 100644 (file)
@@ -2,6 +2,8 @@
 #include "object.h"
 #include "pack.h"
 #include "pack-objects.h"
+#include "packfile.h"
+#include "config.h"
 
 static uint32_t locate_object_entry_hash(struct packing_data *pdata,
                                         const unsigned char *sha1,
@@ -58,7 +60,7 @@ static void rehash_objects(struct packing_data *pdata)
                                                       &found);
 
                if (found)
-                       die("BUG: Duplicate object in hash");
+                       BUG("Duplicate object in hash");
 
                pdata->index[ix] = i + 1;
                entry++;
@@ -86,6 +88,66 @@ struct object_entry *packlist_find(struct packing_data *pdata,
        return &pdata->objects[pdata->index[i] - 1];
 }
 
+static void prepare_in_pack_by_idx(struct packing_data *pdata)
+{
+       struct packed_git **mapping, *p;
+       int cnt = 0, nr = 1U << OE_IN_PACK_BITS;
+
+       ALLOC_ARRAY(mapping, nr);
+       /*
+        * oe_in_pack() on an all-zero'd object_entry
+        * (i.e. in_pack_idx also zero) should return NULL.
+        */
+       mapping[cnt++] = NULL;
+       for (p = get_packed_git(the_repository); p; p = p->next, cnt++) {
+               if (cnt == nr) {
+                       free(mapping);
+                       return;
+               }
+               p->index = cnt;
+               mapping[cnt] = p;
+       }
+       pdata->in_pack_by_idx = mapping;
+}
+
+/*
+ * A new pack appears after prepare_in_pack_by_idx() has been
+ * run. This is likely a race.
+ *
+ * We could map this new pack to in_pack_by_idx[] array, but then we
+ * have to deal with full array anyway. And since it's hard to test
+ * this fall back code, just stay simple and fall back to using
+ * in_pack[] array.
+ */
+void oe_map_new_pack(struct packing_data *pack,
+                    struct packed_git *p)
+{
+       uint32_t i;
+
+       REALLOC_ARRAY(pack->in_pack, pack->nr_alloc);
+
+       for (i = 0; i < pack->nr_objects; i++)
+               pack->in_pack[i] = oe_in_pack(pack, pack->objects + i);
+
+       FREE_AND_NULL(pack->in_pack_by_idx);
+}
+
+/* assume pdata is already zero'd by caller */
+void prepare_packing_data(struct packing_data *pdata)
+{
+       if (git_env_bool("GIT_TEST_FULL_IN_PACK_ARRAY", 0)) {
+               /*
+                * do not initialize in_pack_by_idx[] to force the
+                * slow path in oe_in_pack()
+                */
+       } else {
+               prepare_in_pack_by_idx(pdata);
+       }
+
+       pdata->oe_size_limit = git_env_ulong("GIT_TEST_OE_SIZE",
+                                            1U << OE_SIZE_BITS);
+}
+
 struct object_entry *packlist_alloc(struct packing_data *pdata,
                                    const unsigned char *sha1,
                                    uint32_t index_pos)
@@ -95,6 +157,9 @@ struct object_entry *packlist_alloc(struct packing_data *pdata,
        if (pdata->nr_objects >= pdata->nr_alloc) {
                pdata->nr_alloc = (pdata->nr_alloc  + 1024) * 3 / 2;
                REALLOC_ARRAY(pdata->objects, pdata->nr_alloc);
+
+               if (!pdata->in_pack_by_idx)
+                       REALLOC_ARRAY(pdata->in_pack, pdata->nr_alloc);
        }
 
        new_entry = pdata->objects + pdata->nr_objects++;
@@ -107,5 +172,8 @@ struct object_entry *packlist_alloc(struct packing_data *pdata,
        else
                pdata->index[index_pos] = pdata->nr_objects;
 
+       if (pdata->in_pack)
+               pdata->in_pack[pdata->nr_objects - 1] = NULL;
+
        return new_entry;
 }
index 03f1191659dab55b2c4c440c347101a3cdbd4650..edf74dabddfdb2b67bad803d1c898e93a3af4d8b 100644 (file)
 #ifndef PACK_OBJECTS_H
 #define PACK_OBJECTS_H
 
+#include "object-store.h"
+
+#define DEFAULT_DELTA_CACHE_SIZE (256 * 1024 * 1024)
+
+#define OE_DFS_STATE_BITS      2
+#define OE_DEPTH_BITS          12
+#define OE_IN_PACK_BITS                10
+#define OE_Z_DELTA_BITS                20
+/*
+ * Note that oe_set_size() becomes expensive when the given size is
+ * above this limit. Don't lower it too much.
+ */
+#define OE_SIZE_BITS           31
+#define OE_DELTA_SIZE_BITS     20
+
+/*
+ * State flags for depth-first search used for analyzing delta cycles.
+ *
+ * The depth is measured in delta-links to the base (so if A is a delta
+ * against B, then A has a depth of 1, and B a depth of 0).
+ */
+enum dfs_state {
+       DFS_NONE = 0,
+       DFS_ACTIVE,
+       DFS_DONE,
+       DFS_NUM_STATES
+};
+
+/*
+ * The size of struct nearly determines pack-objects's memory
+ * consumption. This struct is packed tight for that reason. When you
+ * add or reorder something in this struct, think a bit about this.
+ *
+ * basic object info
+ * -----------------
+ * idx.oid is filled up before delta searching starts. idx.crc32 is
+ * only valid after the object is written out and will be used for
+ * generating the index. idx.offset will be both gradually set and
+ * used in writing phase (base objects get offset first, then deltas
+ * refer to them)
+ *
+ * "size" is the uncompressed object size. Compressed size of the raw
+ * data for an object in a pack is not stored anywhere but is computed
+ * and made available when reverse .idx is made. Note that when a
+ * delta is reused, "size" is the uncompressed _delta_ size, not the
+ * canonical one after the delta has been applied.
+ *
+ * "hash" contains a path name hash which is used for sorting the
+ * delta list and also during delta searching. Once prepare_pack()
+ * returns it's no longer needed.
+ *
+ * source pack info
+ * ----------------
+ * The (in_pack, in_pack_offset) tuple contains the location of the
+ * object in the source pack. in_pack_header_size allows quickly
+ * skipping the header and going straight to the zlib stream.
+ *
+ * "type" and "in_pack_type" both describe object type. in_pack_type
+ * may contain a delta type, while type is always the canonical type.
+ *
+ * deltas
+ * ------
+ * Delta links (delta, delta_child and delta_sibling) are created to
+ * reflect that delta graph from the source pack then updated or added
+ * during delta searching phase when we find better deltas.
+ *
+ * delta_child and delta_sibling are last needed in
+ * compute_write_order(). "delta" and "delta_size" must remain valid
+ * at object writing phase in case the delta is not cached.
+ *
+ * If a delta is cached in memory and is compressed, delta_data points
+ * to the data and z_delta_size contains the compressed size. If it's
+ * uncompressed [1], z_delta_size must be zero. delta_size is always
+ * the uncompressed size and must be valid even if the delta is not
+ * cached.
+ *
+ * [1] during try_delta phase we don't bother with compressing because
+ * the delta could be quickly replaced with a better one.
+ */
 struct object_entry {
        struct pack_idx_entry idx;
-       unsigned long size;     /* uncompressed size */
-       struct packed_git *in_pack;     /* already in pack */
-       off_t in_pack_offset;
-       struct object_entry *delta;     /* delta base object */
-       struct object_entry *delta_child; /* deltified objects who bases me */
-       struct object_entry *delta_sibling; /* other deltified objects who
-                                            * uses the same base as me
-                                            */
        void *delta_data;       /* cached delta (uncompressed) */
-       unsigned long delta_size;       /* delta data size (uncompressed) */
-       unsigned long z_delta_size;     /* delta data size (compressed) */
-       enum object_type type;
-       enum object_type in_pack_type;  /* could be delta */
+       off_t in_pack_offset;
        uint32_t hash;                  /* name hint hash */
-       unsigned int in_pack_pos;
-       unsigned char in_pack_header_size;
+       unsigned size_:OE_SIZE_BITS;
+       unsigned size_valid:1;
+       uint32_t delta_idx;     /* delta base object */
+       uint32_t delta_child_idx; /* deltified objects who bases me */
+       uint32_t delta_sibling_idx; /* other deltified objects who
+                                    * uses the same base as me
+                                    */
+       unsigned delta_size_:OE_DELTA_SIZE_BITS; /* delta data size (uncompressed) */
+       unsigned delta_size_valid:1;
+       unsigned in_pack_idx:OE_IN_PACK_BITS;   /* already in pack */
+       unsigned z_delta_size:OE_Z_DELTA_BITS;
+       unsigned type_valid:1;
+       unsigned type_:TYPE_BITS;
+       unsigned no_try_delta:1;
+       unsigned in_pack_type:TYPE_BITS; /* could be delta */
        unsigned preferred_base:1; /*
                                    * we do not pack this, but is available
                                    * to be used as the base object to delta
                                    * objects against.
                                    */
-       unsigned no_try_delta:1;
        unsigned tagged:1; /* near the very tip of refs */
        unsigned filled:1; /* assigned write-order */
+       unsigned dfs_state:OE_DFS_STATE_BITS;
+       unsigned char in_pack_header_size;
+       unsigned depth:OE_DEPTH_BITS;
 
        /*
-        * State flags for depth-first search used for analyzing delta cycles.
+        * pahole results on 64-bit linux (gcc and clang)
+        *
+        *   size: 80, bit_padding: 20 bits, holes: 8 bits
+        *
+        * and on 32-bit (gcc)
         *
-        * The depth is measured in delta-links to the base (so if A is a delta
-        * against B, then A has a depth of 1, and B a depth of 0).
+        *   size: 76, bit_padding: 20 bits, holes: 8 bits
         */
-       enum {
-               DFS_NONE = 0,
-               DFS_ACTIVE,
-               DFS_DONE
-       } dfs_state;
-       int depth;
 };
 
 struct packing_data {
@@ -48,8 +128,22 @@ struct packing_data {
 
        int32_t *index;
        uint32_t index_size;
+
+       unsigned int *in_pack_pos;
+
+       /*
+        * Only one of these can be non-NULL and they have different
+        * sizes. if in_pack_by_idx is allocated, oe_in_pack() returns
+        * the pack of an object using in_pack_idx field. If not,
+        * in_pack[] array is used the same way as in_pack_pos[]
+        */
+       struct packed_git **in_pack_by_idx;
+       struct packed_git **in_pack;
+
+       uintmax_t oe_size_limit;
 };
 
+void prepare_packing_data(struct packing_data *pdata);
 struct object_entry *packlist_alloc(struct packing_data *pdata,
                                    const unsigned char *sha1,
                                    uint32_t index_pos);
@@ -78,4 +172,178 @@ static inline uint32_t pack_name_hash(const char *name)
        return hash;
 }
 
+static inline enum object_type oe_type(const struct object_entry *e)
+{
+       return e->type_valid ? e->type_ : OBJ_BAD;
+}
+
+static inline void oe_set_type(struct object_entry *e,
+                              enum object_type type)
+{
+       if (type >= OBJ_ANY)
+               BUG("OBJ_ANY cannot be set in pack-objects code");
+
+       e->type_valid = type >= OBJ_NONE;
+       e->type_ = (unsigned)type;
+}
+
+static inline unsigned int oe_in_pack_pos(const struct packing_data *pack,
+                                         const struct object_entry *e)
+{
+       return pack->in_pack_pos[e - pack->objects];
+}
+
+static inline void oe_set_in_pack_pos(const struct packing_data *pack,
+                                     const struct object_entry *e,
+                                     unsigned int pos)
+{
+       pack->in_pack_pos[e - pack->objects] = pos;
+}
+
+static inline struct packed_git *oe_in_pack(const struct packing_data *pack,
+                                           const struct object_entry *e)
+{
+       if (pack->in_pack_by_idx)
+               return pack->in_pack_by_idx[e->in_pack_idx];
+       else
+               return pack->in_pack[e - pack->objects];
+}
+
+void oe_map_new_pack(struct packing_data *pack,
+                    struct packed_git *p);
+static inline void oe_set_in_pack(struct packing_data *pack,
+                                 struct object_entry *e,
+                                 struct packed_git *p)
+{
+       if (!p->index)
+               oe_map_new_pack(pack, p);
+       if (pack->in_pack_by_idx)
+               e->in_pack_idx = p->index;
+       else
+               pack->in_pack[e - pack->objects] = p;
+}
+
+static inline struct object_entry *oe_delta(
+               const struct packing_data *pack,
+               const struct object_entry *e)
+{
+       if (e->delta_idx)
+               return &pack->objects[e->delta_idx - 1];
+       return NULL;
+}
+
+static inline void oe_set_delta(struct packing_data *pack,
+                               struct object_entry *e,
+                               struct object_entry *delta)
+{
+       if (delta)
+               e->delta_idx = (delta - pack->objects) + 1;
+       else
+               e->delta_idx = 0;
+}
+
+static inline struct object_entry *oe_delta_child(
+               const struct packing_data *pack,
+               const struct object_entry *e)
+{
+       if (e->delta_child_idx)
+               return &pack->objects[e->delta_child_idx - 1];
+       return NULL;
+}
+
+static inline void oe_set_delta_child(struct packing_data *pack,
+                                     struct object_entry *e,
+                                     struct object_entry *delta)
+{
+       if (delta)
+               e->delta_child_idx = (delta - pack->objects) + 1;
+       else
+               e->delta_child_idx = 0;
+}
+
+static inline struct object_entry *oe_delta_sibling(
+               const struct packing_data *pack,
+               const struct object_entry *e)
+{
+       if (e->delta_sibling_idx)
+               return &pack->objects[e->delta_sibling_idx - 1];
+       return NULL;
+}
+
+static inline void oe_set_delta_sibling(struct packing_data *pack,
+                                       struct object_entry *e,
+                                       struct object_entry *delta)
+{
+       if (delta)
+               e->delta_sibling_idx = (delta - pack->objects) + 1;
+       else
+               e->delta_sibling_idx = 0;
+}
+
+unsigned long oe_get_size_slow(struct packing_data *pack,
+                              const struct object_entry *e);
+static inline unsigned long oe_size(struct packing_data *pack,
+                                   const struct object_entry *e)
+{
+       if (e->size_valid)
+               return e->size_;
+
+       return oe_get_size_slow(pack, e);
+}
+
+static inline int oe_size_less_than(struct packing_data *pack,
+                                   const struct object_entry *lhs,
+                                   unsigned long rhs)
+{
+       if (lhs->size_valid)
+               return lhs->size_ < rhs;
+       if (rhs < pack->oe_size_limit) /* rhs < 2^x <= lhs ? */
+               return 0;
+       return oe_get_size_slow(pack, lhs) < rhs;
+}
+
+static inline int oe_size_greater_than(struct packing_data *pack,
+                                      const struct object_entry *lhs,
+                                      unsigned long rhs)
+{
+       if (lhs->size_valid)
+               return lhs->size_ > rhs;
+       if (rhs < pack->oe_size_limit) /* rhs < 2^x <= lhs ? */
+               return 1;
+       return oe_get_size_slow(pack, lhs) > rhs;
+}
+
+static inline void oe_set_size(struct packing_data *pack,
+                              struct object_entry *e,
+                              unsigned long size)
+{
+       if (size < pack->oe_size_limit) {
+               e->size_ = size;
+               e->size_valid = 1;
+       } else {
+               e->size_valid = 0;
+               if (oe_get_size_slow(pack, e) != size)
+                       BUG("'size' is supposed to be the object size!");
+       }
+}
+
+static inline unsigned long oe_delta_size(struct packing_data *pack,
+                                         const struct object_entry *e)
+{
+       if (e->delta_size_valid)
+               return e->delta_size_;
+       return oe_size(pack, e);
+}
+
+static inline void oe_set_delta_size(struct packing_data *pack,
+                                    struct object_entry *e,
+                                    unsigned long size)
+{
+       e->delta_size_ = size;
+       e->delta_size_valid = e->delta_size_ == size;
+       if (!e->delta_size_valid && size != oe_size(pack, e))
+               BUG("this can only happen in check_object() "
+                   "where delta size is the same as entry size");
+}
+
 #endif
index ff5f62c03326a7f01926c72a19be5029ae4c1a8b..bb521cf7fb2911bc2d3653f46224880f8540f9ab 100644 (file)
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "pack-revindex.h"
+#include "object-store.h"
 
 /*
  * Pack index for existing packs give us easy access to the offsets into
index d775c7406dd5a869a1ce4d28f6ef872e08476b77..a9d46bc03f63b27ff85cceecb763d4e39f47898f 100644 (file)
@@ -170,8 +170,9 @@ const char *write_idx_file(const char *index_name, struct pack_idx_entry **objec
        }
 
        hashwrite(f, sha1, the_hash_algo->rawsz);
-       hashclose(f, NULL, ((opts->flags & WRITE_IDX_VERIFY)
-                           ? CSUM_CLOSE : CSUM_FSYNC));
+       finalize_hashfile(f, NULL, CSUM_HASH_IN_STREAM | CSUM_CLOSE |
+                                   ((opts->flags & WRITE_IDX_VERIFY)
+                                   ? 0 : CSUM_FSYNC));
        return index_name;
 }
 
index 7c1a2519fcb9c45aacf5481811bc26f44736de59..7cd45aa4b2a0e098d597e4dea633d9b097b9b94c 100644 (file)
@@ -1,6 +1,7 @@
 #include "cache.h"
 #include "list.h"
 #include "pack.h"
+#include "repository.h"
 #include "dir.h"
 #include "mergesort.h"
 #include "packfile.h"
@@ -13,6 +14,7 @@
 #include "tag.h"
 #include "tree-walk.h"
 #include "tree.h"
+#include "object-store.h"
 
 char *odb_pack_name(struct strbuf *buf,
                    const unsigned char *sha1,
@@ -44,8 +46,6 @@ static unsigned int pack_open_fds;
 static unsigned int pack_max_fds;
 static size_t peak_pack_mapped;
 static size_t pack_mapped;
-struct packed_git *packed_git;
-LIST_HEAD(packed_git_mru);
 
 #define SZ_FMT PRIuMAX
 static inline uintmax_t sz_fmt(size_t s) { return s; }
@@ -84,6 +84,7 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
        uint32_t version, nr, i, *index;
        int fd = git_open(path);
        struct stat st;
+       const unsigned int hashsz = the_hash_algo->rawsz;
 
        if (fd < 0)
                return -1;
@@ -92,7 +93,7 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
                return -1;
        }
        idx_size = xsize_t(st.st_size);
-       if (idx_size < 4 * 256 + 20 + 20) {
+       if (idx_size < 4 * 256 + hashsz + hashsz) {
                close(fd);
                return error("index file %s is too small", path);
        }
@@ -129,11 +130,11 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
                /*
                 * Total size:
                 *  - 256 index entries 4 bytes each
-                *  - 24-byte entries * nr (20-byte sha1 + 4-byte offset)
-                *  - 20-byte SHA1 of the packfile
-                *  - 20-byte SHA1 file checksum
+                *  - 24-byte entries * nr (object ID + 4-byte offset)
+                *  - hash of the packfile
+                *  - file checksum
                 */
-               if (idx_size != 4*256 + nr * 24 + 20 + 20) {
+               if (idx_size != 4*256 + nr * (hashsz + 4) + hashsz + hashsz) {
                        munmap(idx_map, idx_size);
                        return error("wrong index v1 file size in %s", path);
                }
@@ -142,16 +143,16 @@ static int check_packed_git_idx(const char *path, struct packed_git *p)
                 * Minimum size:
                 *  - 8 bytes of header
                 *  - 256 index entries 4 bytes each
-                *  - 20-byte sha1 entry * nr
+                *  - object ID entry * nr
                 *  - 4-byte crc entry * nr
                 *  - 4-byte offset entry * nr
-                *  - 20-byte SHA1 of the packfile
-                *  - 20-byte SHA1 file checksum
+                *  - hash of the packfile
+                *  - file checksum
                 * And after the 4-byte offset table might be a
                 * variable sized table containing 8-byte entries
                 * for offsets larger than 2^31.
                 */
-               unsigned long min_size = 8 + 4*256 + nr*(20 + 4 + 4) + 20 + 20;
+               unsigned long min_size = 8 + 4*256 + nr*(hashsz + 4 + 4) + hashsz + hashsz;
                unsigned long max_size = min_size;
                if (nr)
                        max_size += (nr - 1)*8;
@@ -188,7 +189,7 @@ int open_pack_index(struct packed_git *p)
                return 0;
 
        if (!strip_suffix(p->pack_name, ".pack", &len))
-               die("BUG: pack_name does not end in .pack");
+               BUG("pack_name does not end in .pack");
        idx_name = xstrfmt("%.*s.idx", (int)len, p->pack_name);
        ret = check_packed_git_idx(idx_name, p);
        free(idx_name);
@@ -245,7 +246,7 @@ static int unuse_one_window(struct packed_git *current)
 
        if (current)
                scan_windows(current, &lru_p, &lru_w, &lru_l);
-       for (p = packed_git; p; p = p->next)
+       for (p = the_repository->objects->packed_git; p; p = p->next)
                scan_windows(p, &lru_p, &lru_w, &lru_l);
        if (lru_p) {
                munmap(lru_w->base, lru_w->len);
@@ -304,20 +305,20 @@ void close_pack_index(struct packed_git *p)
        }
 }
 
-static void close_pack(struct packed_git *p)
+void close_pack(struct packed_git *p)
 {
        close_pack_windows(p);
        close_pack_fd(p);
        close_pack_index(p);
 }
 
-void close_all_packs(void)
+void close_all_packs(struct raw_object_store *o)
 {
        struct packed_git *p;
 
-       for (p = packed_git; p; p = p->next)
+       for (p = o->packed_git; p; p = p->next)
                if (p->do_not_close)
-                       die("BUG: want to close pack marked 'do-not-close'");
+                       BUG("want to close pack marked 'do-not-close'");
                else
                        close_pack(p);
 }
@@ -383,7 +384,7 @@ static int close_one_pack(void)
        struct pack_window *mru_w = NULL;
        int accept_windows_inuse = 1;
 
-       for (p = packed_git; p; p = p->next) {
+       for (p = the_repository->objects->packed_git; p; p = p->next) {
                if (p->pack_fd == -1)
                        continue;
                find_lru_pack(p, &lru_p, &mru_w, &accept_windows_inuse);
@@ -444,10 +445,11 @@ static int open_packed_git_1(struct packed_git *p)
 {
        struct stat st;
        struct pack_header hdr;
-       unsigned char sha1[20];
-       unsigned char *idx_sha1;
+       unsigned char hash[GIT_MAX_RAWSZ];
+       unsigned char *idx_hash;
        long fd_flag;
        ssize_t read_result;
+       const unsigned hashsz = the_hash_algo->rawsz;
 
        if (!p->index_data && open_pack_index(p))
                return error("packfile %s index unavailable", p->pack_name);
@@ -507,15 +509,15 @@ static int open_packed_git_1(struct packed_git *p)
                             " while index indicates %"PRIu32" objects",
                             p->pack_name, ntohl(hdr.hdr_entries),
                             p->num_objects);
-       if (lseek(p->pack_fd, p->pack_size - sizeof(sha1), SEEK_SET) == -1)
+       if (lseek(p->pack_fd, p->pack_size - hashsz, SEEK_SET) == -1)
                return error("end of packfile %s is unavailable", p->pack_name);
-       read_result = read_in_full(p->pack_fd, sha1, sizeof(sha1));
+       read_result = read_in_full(p->pack_fd, hash, hashsz);
        if (read_result < 0)
                return error_errno("error reading from %s", p->pack_name);
-       if (read_result != sizeof(sha1))
+       if (read_result != hashsz)
                return error("packfile %s signature is unavailable", p->pack_name);
-       idx_sha1 = ((unsigned char *)p->index_data) + p->index_size - 40;
-       if (hashcmp(sha1, idx_sha1))
+       idx_hash = ((unsigned char *)p->index_data) + p->index_size - hashsz * 2;
+       if (hashcmp(hash, idx_hash))
                return error("packfile %s does not match index", p->pack_name);
        return 0;
 }
@@ -530,7 +532,7 @@ static int open_packed_git(struct packed_git *p)
 
 static int in_window(struct pack_window *win, off_t offset)
 {
-       /* We must promise at least 20 bytes (one hash) after the
+       /* We must promise at least one full hash after the
         * offset is available from this window, otherwise the offset
         * is not actually in this window and a different window (which
         * has that one hash excess) must be used.  This is to support
@@ -538,7 +540,7 @@ static int in_window(struct pack_window *win, off_t offset)
         */
        off_t win_off = win->offset;
        return win_off <= offset
-               && (offset + 20) <= (win_off + win->len);
+               && (offset + the_hash_algo->rawsz) <= (win_off + win->len);
 }
 
 unsigned char *use_pack(struct packed_git *p,
@@ -555,7 +557,7 @@ unsigned char *use_pack(struct packed_git *p,
         */
        if (!p->pack_size && p->pack_fd == -1 && open_packed_git(p))
                die("packfile %s cannot be accessed", p->pack_name);
-       if (offset > (p->pack_size - 20))
+       if (offset > (p->pack_size - the_hash_algo->rawsz))
                die("offset beyond end of packfile (truncated pack?)");
        if (offset < 0)
                die(_("offset before end of packfile (broken .idx?)"));
@@ -675,18 +677,19 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local)
        p->pack_size = st.st_size;
        p->pack_local = local;
        p->mtime = st.st_mtime;
-       if (path_len < 40 || get_sha1_hex(path + path_len - 40, p->sha1))
+       if (path_len < the_hash_algo->hexsz ||
+           get_sha1_hex(path + path_len - the_hash_algo->hexsz, p->sha1))
                hashclr(p->sha1);
        return p;
 }
 
-void install_packed_git(struct packed_git *pack)
+void install_packed_git(struct repository *r, struct packed_git *pack)
 {
        if (pack->pack_fd != -1)
                pack_open_fds++;
 
-       pack->next = packed_git;
-       packed_git = pack;
+       pack->next = r->objects->packed_git;
+       r->objects->packed_git = pack;
 }
 
 void (*report_garbage)(unsigned seen_bits, const char *path);
@@ -735,7 +738,7 @@ static void report_pack_garbage(struct string_list *list)
        report_helper(list, seen_bits, first, list->nr);
 }
 
-static void prepare_packed_git_one(char *objdir, int local)
+static void prepare_packed_git_one(struct repository *r, char *objdir, int local)
 {
        struct strbuf path = STRBUF_INIT;
        size_t dirnamelen;
@@ -768,7 +771,8 @@ static void prepare_packed_git_one(char *objdir, int local)
                base_len = path.len;
                if (strip_suffix_mem(path.buf, &base_len, ".idx")) {
                        /* Don't reopen a pack we already have. */
-                       for (p = packed_git; p; p = p->next) {
+                       for (p = r->objects->packed_git; p;
+                            p = p->next) {
                                size_t len;
                                if (strip_suffix(p->pack_name, ".pack", &len) &&
                                    len == base_len &&
@@ -781,7 +785,7 @@ static void prepare_packed_git_one(char *objdir, int local)
                             * corresponding .pack file that we can map.
                             */
                            (p = add_packed_git(path.buf, path.len, local)) != NULL)
-                               install_packed_git(p);
+                               install_packed_git(r, p);
                }
 
                if (!report_garbage)
@@ -802,8 +806,7 @@ static void prepare_packed_git_one(char *objdir, int local)
        strbuf_release(&path);
 }
 
-static int approximate_object_count_valid;
-
+static void prepare_packed_git(struct repository *r);
 /*
  * Give a fast, rough count of the number of objects in the repository. This
  * ignores loose objects completely. If you have a lot of them, then either
@@ -813,19 +816,20 @@ static int approximate_object_count_valid;
  */
 unsigned long approximate_object_count(void)
 {
-       static unsigned long count;
-       if (!approximate_object_count_valid) {
+       if (!the_repository->objects->approximate_object_count_valid) {
+               unsigned long count;
                struct packed_git *p;
 
-               prepare_packed_git();
+               prepare_packed_git(the_repository);
                count = 0;
-               for (p = packed_git; p; p = p->next) {
+               for (p = the_repository->objects->packed_git; p; p = p->next) {
                        if (open_pack_index(p))
                                continue;
                        count += p->num_objects;
                }
+               the_repository->objects->approximate_object_count = count;
        }
-       return count;
+       return the_repository->objects->approximate_object_count;
 }
 
 static void *get_next_packed_git(const void *p)
@@ -866,43 +870,55 @@ static int sort_pack(const void *a_, const void *b_)
        return -1;
 }
 
-static void rearrange_packed_git(void)
+static void rearrange_packed_git(struct repository *r)
 {
-       packed_git = llist_mergesort(packed_git, get_next_packed_git,
-                                    set_next_packed_git, sort_pack);
+       r->objects->packed_git = llist_mergesort(
+               r->objects->packed_git, get_next_packed_git,
+               set_next_packed_git, sort_pack);
 }
 
-static void prepare_packed_git_mru(void)
+static void prepare_packed_git_mru(struct repository *r)
 {
        struct packed_git *p;
 
-       INIT_LIST_HEAD(&packed_git_mru);
+       INIT_LIST_HEAD(&r->objects->packed_git_mru);
 
-       for (p = packed_git; p; p = p->next)
-               list_add_tail(&p->mru, &packed_git_mru);
+       for (p = r->objects->packed_git; p; p = p->next)
+               list_add_tail(&p->mru, &r->objects->packed_git_mru);
 }
 
-static int prepare_packed_git_run_once = 0;
-void prepare_packed_git(void)
+static void prepare_packed_git(struct repository *r)
 {
        struct alternate_object_database *alt;
 
-       if (prepare_packed_git_run_once)
+       if (r->objects->packed_git_initialized)
                return;
-       prepare_packed_git_one(get_object_directory(), 1);
-       prepare_alt_odb();
-       for (alt = alt_odb_list; alt; alt = alt->next)
-               prepare_packed_git_one(alt->path, 0);
-       rearrange_packed_git();
-       prepare_packed_git_mru();
-       prepare_packed_git_run_once = 1;
+       prepare_packed_git_one(r, r->objects->objectdir, 1);
+       prepare_alt_odb(r);
+       for (alt = r->objects->alt_odb_list; alt; alt = alt->next)
+               prepare_packed_git_one(r, alt->path, 0);
+       rearrange_packed_git(r);
+       prepare_packed_git_mru(r);
+       r->objects->packed_git_initialized = 1;
+}
+
+void reprepare_packed_git(struct repository *r)
+{
+       r->objects->approximate_object_count_valid = 0;
+       r->objects->packed_git_initialized = 0;
+       prepare_packed_git(r);
+}
+
+struct packed_git *get_packed_git(struct repository *r)
+{
+       prepare_packed_git(r);
+       return r->objects->packed_git;
 }
 
-void reprepare_packed_git(void)
+struct list_head *get_packed_git_mru(struct repository *r)
 {
-       approximate_object_count_valid = 0;
-       prepare_packed_git_run_once = 0;
-       prepare_packed_git();
+       prepare_packed_git(r);
+       return &r->objects->packed_git_mru;
 }
 
 unsigned long unpack_object_header_buffer(const unsigned char *buf,
@@ -1013,9 +1029,10 @@ const struct packed_git *has_packed_and_bad(const unsigned char *sha1)
        struct packed_git *p;
        unsigned i;
 
-       for (p = packed_git; p; p = p->next)
+       for (p = the_repository->objects->packed_git; p; p = p->next)
                for (i = 0; i < p->num_bad_objects; i++)
-                       if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
+                       if (!hashcmp(sha1,
+                                    p->bad_object_sha1 + the_hash_algo->rawsz * i))
                                return p;
        return NULL;
 }
@@ -1053,7 +1070,7 @@ static off_t get_delta_base(struct packed_git *p,
        } else if (type == OBJ_REF_DELTA) {
                /* The base entry _must_ be in the same pack */
                base_offset = find_pack_entry_one(base_info, p);
-               *curpos += 20;
+               *curpos += the_hash_algo->rawsz;
        } else
                die("I am totally screwed");
        return base_offset;
@@ -1091,17 +1108,19 @@ static const unsigned char *get_delta_base_sha1(struct packed_git *p,
                return NULL;
 }
 
-static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset)
+static int retry_bad_packed_offset(struct repository *r,
+                                  struct packed_git *p,
+                                  off_t obj_offset)
 {
        int type;
        struct revindex_entry *revidx;
-       const unsigned char *sha1;
+       struct object_id oid;
        revidx = find_pack_revindex(p, obj_offset);
        if (!revidx)
                return OBJ_BAD;
-       sha1 = nth_packed_object_sha1(p, revidx->nr);
-       mark_bad_packed_object(p, sha1);
-       type = sha1_object_info(sha1, NULL);
+       nth_packed_object_oid(&oid, p, revidx->nr);
+       mark_bad_packed_object(p, oid.hash);
+       type = oid_object_info(r, &oid, NULL);
        if (type <= OBJ_NONE)
                return OBJ_BAD;
        return type;
@@ -1109,7 +1128,8 @@ static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset)
 
 #define POI_STACK_PREALLOC 64
 
-static enum object_type packed_to_object_type(struct packed_git *p,
+static enum object_type packed_to_object_type(struct repository *r,
+                                             struct packed_git *p,
                                              off_t obj_offset,
                                              enum object_type type,
                                              struct pack_window **w_curs,
@@ -1140,7 +1160,7 @@ static enum object_type packed_to_object_type(struct packed_git *p,
                if (type <= OBJ_NONE) {
                        /* If getting the base itself fails, we first
                         * retry the base, otherwise unwind */
-                       type = retry_bad_packed_offset(p, base_offset);
+                       type = retry_bad_packed_offset(r, p, base_offset);
                        if (type > OBJ_NONE)
                                goto out;
                        goto unwind;
@@ -1168,7 +1188,7 @@ out:
 unwind:
        while (poi_stack_nr) {
                obj_offset = poi_stack[--poi_stack_nr];
-               type = retry_bad_packed_offset(p, obj_offset);
+               type = retry_bad_packed_offset(r, p, obj_offset);
                if (type > OBJ_NONE)
                        goto out;
        }
@@ -1255,14 +1275,15 @@ static void detach_delta_base_cache_entry(struct delta_base_cache_entry *ent)
        free(ent);
 }
 
-static void *cache_or_unpack_entry(struct packed_git *p, off_t base_offset,
-       unsigned long *base_size, enum object_type *type)
+static void *cache_or_unpack_entry(struct repository *r, struct packed_git *p,
+                                  off_t base_offset, unsigned long *base_size,
+                                  enum object_type *type)
 {
        struct delta_base_cache_entry *ent;
 
        ent = get_delta_base_cache_entry(p, base_offset);
        if (!ent)
-               return unpack_entry(p, base_offset, type, base_size);
+               return unpack_entry(r, p, base_offset, type, base_size);
 
        if (type)
                *type = ent->type;
@@ -1316,8 +1337,8 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
        hashmap_add(&delta_base_cache, ent);
 }
 
-int packed_object_info(struct packed_git *p, off_t obj_offset,
-                      struct object_info *oi)
+int packed_object_info(struct repository *r, struct packed_git *p,
+                      off_t obj_offset, struct object_info *oi)
 {
        struct pack_window *w_curs = NULL;
        unsigned long size;
@@ -1329,7 +1350,7 @@ int packed_object_info(struct packed_git *p, off_t obj_offset,
         * a "real" type later if the caller is interested.
         */
        if (oi->contentp) {
-               *oi->contentp = cache_or_unpack_entry(p, obj_offset, oi->sizep,
+               *oi->contentp = cache_or_unpack_entry(r, p, obj_offset, oi->sizep,
                                                      &type);
                if (!*oi->contentp)
                        type = OBJ_BAD;
@@ -1363,8 +1384,8 @@ int packed_object_info(struct packed_git *p, off_t obj_offset,
 
        if (oi->typep || oi->type_name) {
                enum object_type ptot;
-               ptot = packed_to_object_type(p, obj_offset, type, &w_curs,
-                                            curpos);
+               ptot = packed_to_object_type(r, p, obj_offset,
+                                            type, &w_curs, curpos);
                if (oi->typep)
                        *oi->typep = ptot;
                if (oi->type_name) {
@@ -1433,6 +1454,9 @@ static void *unpack_compressed_entry(struct packed_git *p,
                return NULL;
        }
 
+       /* versions of zlib can clobber unconsumed portion of outbuf */
+       buffer[size] = '\0';
+
        return buffer;
 }
 
@@ -1452,7 +1476,9 @@ struct unpack_entry_stack_ent {
        unsigned long size;
 };
 
-static void *read_object(const unsigned char *sha1, enum object_type *type,
+static void *read_object(struct repository *r,
+                        const struct object_id *oid,
+                        enum object_type *type,
                         unsigned long *size)
 {
        struct object_info oi = OBJECT_INFO_INIT;
@@ -1461,12 +1487,12 @@ static void *read_object(const unsigned char *sha1, enum object_type *type,
        oi.sizep = size;
        oi.contentp = &content;
 
-       if (sha1_object_info_extended(sha1, &oi, 0) < 0)
+       if (oid_object_info_extended(r, oid, &oi, 0) < 0)
                return NULL;
        return content;
 }
 
-void *unpack_entry(struct packed_git *p, off_t obj_offset,
+void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
                   enum object_type *final_type, unsigned long *final_size)
 {
        struct pack_window *w_curs = NULL;
@@ -1501,11 +1527,11 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
                        struct revindex_entry *revidx = find_pack_revindex(p, obj_offset);
                        off_t len = revidx[1].offset - obj_offset;
                        if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) {
-                               const unsigned char *sha1 =
-                                       nth_packed_object_sha1(p, revidx->nr);
+                               struct object_id oid;
+                               nth_packed_object_oid(&oid, p, revidx->nr);
                                error("bad packed object CRC for %s",
-                                     sha1_to_hex(sha1));
-                               mark_bad_packed_object(p, sha1);
+                                     oid_to_hex(&oid));
+                               mark_bad_packed_object(p, oid.hash);
                                data = NULL;
                                goto out;
                        }
@@ -1548,7 +1574,7 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
        case OBJ_OFS_DELTA:
        case OBJ_REF_DELTA:
                if (data)
-                       die("BUG: unpack_entry: left loop at a valid delta");
+                       BUG("unpack_entry: left loop at a valid delta");
                break;
        case OBJ_COMMIT:
        case OBJ_TREE:
@@ -1588,16 +1614,16 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
                         * of a corrupted pack, and is better than failing outright.
                         */
                        struct revindex_entry *revidx;
-                       const unsigned char *base_sha1;
+                       struct object_id base_oid;
                        revidx = find_pack_revindex(p, obj_offset);
                        if (revidx) {
-                               base_sha1 = nth_packed_object_sha1(p, revidx->nr);
+                               nth_packed_object_oid(&base_oid, p, revidx->nr);
                                error("failed to read delta base object %s"
                                      " at offset %"PRIuMAX" from %s",
-                                     sha1_to_hex(base_sha1), (uintmax_t)obj_offset,
+                                     oid_to_hex(&base_oid), (uintmax_t)obj_offset,
                                      p->pack_name);
-                               mark_bad_packed_object(p, base_sha1);
-                               base = read_object(base_sha1, &type, &base_size);
+                               mark_bad_packed_object(p, base_oid.hash);
+                               base = read_object(r, &base_oid, &type, &base_size);
                                external_base = base;
                        }
                }
@@ -1654,10 +1680,35 @@ out:
        return data;
 }
 
+int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result)
+{
+       const unsigned char *index_fanout = p->index_data;
+       const unsigned char *index_lookup;
+       const unsigned int hashsz = the_hash_algo->rawsz;
+       int index_lookup_width;
+
+       if (!index_fanout)
+               BUG("bsearch_pack called without a valid pack-index");
+
+       index_lookup = index_fanout + 4 * 256;
+       if (p->index_version == 1) {
+               index_lookup_width = hashsz + 4;
+               index_lookup += 4;
+       } else {
+               index_lookup_width = hashsz;
+               index_fanout += 8;
+               index_lookup += 8;
+       }
+
+       return bsearch_hash(oid->hash, (const uint32_t*)index_fanout,
+                           index_lookup, index_lookup_width, result);
+}
+
 const unsigned char *nth_packed_object_sha1(struct packed_git *p,
                                            uint32_t n)
 {
        const unsigned char *index = p->index_data;
+       const unsigned int hashsz = the_hash_algo->rawsz;
        if (!index) {
                if (open_pack_index(p))
                        return NULL;
@@ -1667,10 +1718,10 @@ const unsigned char *nth_packed_object_sha1(struct packed_git *p,
                return NULL;
        index += 4 * 256;
        if (p->index_version == 1) {
-               return index + 24 * n + 4;
+               return index + (hashsz + 4) * n + 4;
        } else {
                index += 8;
-               return index + 20 * n;
+               return index + hashsz * n;
        }
 }
 
@@ -1702,12 +1753,13 @@ void check_pack_index_ptr(const struct packed_git *p, const void *vptr)
 off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
 {
        const unsigned char *index = p->index_data;
+       const unsigned int hashsz = the_hash_algo->rawsz;
        index += 4 * 256;
        if (p->index_version == 1) {
-               return ntohl(*((uint32_t *)(index + 24 * n)));
+               return ntohl(*((uint32_t *)(index + (hashsz + 4) * n)));
        } else {
                uint32_t off;
-               index += 8 + p->num_objects * (20 + 4);
+               index += 8 + p->num_objects * (hashsz + 4);
                off = ntohl(*((uint32_t *)(index + 4 * n)));
                if (!(off & 0x80000000))
                        return off;
@@ -1720,30 +1772,17 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
 off_t find_pack_entry_one(const unsigned char *sha1,
                                  struct packed_git *p)
 {
-       const uint32_t *level1_ofs = p->index_data;
        const unsigned char *index = p->index_data;
-       unsigned stride;
+       struct object_id oid;
        uint32_t result;
 
        if (!index) {
                if (open_pack_index(p))
                        return 0;
-               level1_ofs = p->index_data;
-               index = p->index_data;
-       }
-       if (p->index_version > 1) {
-               level1_ofs += 2;
-               index += 8;
-       }
-       index += 4 * 256;
-       if (p->index_version > 1) {
-               stride = 20;
-       } else {
-               stride = 24;
-               index += 4;
        }
 
-       if (bsearch_hash(sha1, level1_ofs, index, stride, &result))
+       hashcpy(oid.hash, sha1);
+       if (bsearch_pack(&oid, p, &result))
                return nth_packed_object_offset(p, result);
        return 0;
 }
@@ -1782,7 +1821,7 @@ struct packed_git *find_sha1_pack(const unsigned char *sha1,
 
 }
 
-static int fill_pack_entry(const unsigned char *sha1,
+static int fill_pack_entry(const struct object_id *oid,
                           struct pack_entry *e,
                           struct packed_git *p)
 {
@@ -1791,11 +1830,12 @@ static int fill_pack_entry(const unsigned char *sha1,
        if (p->num_bad_objects) {
                unsigned i;
                for (i = 0; i < p->num_bad_objects; i++)
-                       if (!hashcmp(sha1, p->bad_object_sha1 + 20 * i))
+                       if (!hashcmp(oid->hash,
+                                    p->bad_object_sha1 + the_hash_algo->rawsz * i))
                                return 0;
        }
 
-       offset = find_pack_entry_one(sha1, p);
+       offset = find_pack_entry_one(oid->hash, p);
        if (!offset)
                return 0;
 
@@ -1810,36 +1850,31 @@ static int fill_pack_entry(const unsigned char *sha1,
                return 0;
        e->offset = offset;
        e->p = p;
-       hashcpy(e->sha1, sha1);
        return 1;
 }
 
-/*
- * Iff a pack file contains the object named by sha1, return true and
- * store its location to e.
- */
-int find_pack_entry(const unsigned char *sha1, struct pack_entry *e)
+int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e)
 {
        struct list_head *pos;
 
-       prepare_packed_git();
-       if (!packed_git)
+       prepare_packed_git(r);
+       if (!r->objects->packed_git)
                return 0;
 
-       list_for_each(pos, &packed_git_mru) {
+       list_for_each(pos, &r->objects->packed_git_mru) {
                struct packed_git *p = list_entry(pos, struct packed_git, mru);
-               if (fill_pack_entry(sha1, e, p)) {
-                       list_move(&p->mru, &packed_git_mru);
+               if (fill_pack_entry(oid, e, p)) {
+                       list_move(&p->mru, &r->objects->packed_git_mru);
                        return 1;
                }
        }
        return 0;
 }
 
-int has_sha1_pack(const unsigned char *sha1)
+int has_object_pack(const struct object_id *oid)
 {
        struct pack_entry e;
-       return find_pack_entry(sha1, &e);
+       return find_pack_entry(the_repository, oid, &e);
 }
 
 int has_pack_index(const unsigned char *sha1)
@@ -1850,7 +1885,7 @@ int has_pack_index(const unsigned char *sha1)
        return 1;
 }
 
-static int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn cb, void *data)
+int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn cb, void *data)
 {
        uint32_t i;
        int r = 0;
@@ -1875,8 +1910,8 @@ int for_each_packed_object(each_packed_object_fn cb, void *data, unsigned flags)
        int r = 0;
        int pack_errors = 0;
 
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next) {
+       prepare_packed_git(the_repository);
+       for (p = the_repository->objects->packed_git; p; p = p->next) {
                if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
                        continue;
                if ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&
@@ -1907,7 +1942,7 @@ static int add_promisor_object(const struct object_id *oid,
 
        /*
         * If this is a tree, commit, or tag, the objects it refers
-        * to are also promisor objects. (Blobs refer to no objects.)
+        * to are also promisor objects. (Blobs refer to no objects->)
         */
        if (obj->type == OBJ_TREE) {
                struct tree *tree = (struct tree *)obj;
@@ -1925,7 +1960,7 @@ static int add_promisor_object(const struct object_id *oid,
                struct commit *commit = (struct commit *) obj;
                struct commit_list *parents = commit->parents;
 
-               oidset_insert(set, &commit->tree->object.oid);
+               oidset_insert(set, get_commit_tree_oid(commit));
                for (; parents; parents = parents->next)
                        oidset_insert(set, &parents->item->object.oid);
        } else if (obj->type == OBJ_TAG) {
index a7fca598d672b73010a5fb99e4507da4634002ff..e0a38aba9321deae1d64aea7cd87067fde240b10 100644 (file)
@@ -34,9 +34,11 @@ extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_
 #define PACKDIR_FILE_GARBAGE 4
 extern void (*report_garbage)(unsigned seen_bits, const char *path);
 
-extern void prepare_packed_git(void);
-extern void reprepare_packed_git(void);
-extern void install_packed_git(struct packed_git *pack);
+extern void reprepare_packed_git(struct repository *r);
+extern void install_packed_git(struct repository *r, struct packed_git *pack);
+
+struct packed_git *get_packed_git(struct repository *r);
+struct list_head *get_packed_git_mru(struct repository *r);
 
 /*
  * Give a rough count of objects in the repository. This sacrifices accuracy
@@ -63,7 +65,8 @@ extern void close_pack_index(struct packed_git *);
 
 extern unsigned char *use_pack(struct packed_git *, struct pack_window **, off_t, unsigned long *);
 extern void close_pack_windows(struct packed_git *);
-extern void close_all_packs(void);
+extern void close_pack(struct packed_git *);
+extern void close_all_packs(struct raw_object_store *o);
 extern void unuse_pack(struct pack_window **);
 extern void clear_delta_base_cache(void);
 extern struct packed_git *add_packed_git(const char *path, size_t path_len, int local);
@@ -78,6 +81,14 @@ extern struct packed_git *add_packed_git(const char *path, size_t path_len, int
  */
 extern void check_pack_index_ptr(const struct packed_git *p, const void *ptr);
 
+/*
+ * Perform binary search on a pack-index for a given oid. Packfile is expected to
+ * have a valid pack-index.
+ *
+ * See 'bsearch_hash' for more information.
+ */
+int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result);
+
 /*
  * Return the SHA-1 of the nth object within the specified packfile.
  * Open the index if it is not already open.  The return value points
@@ -105,7 +116,7 @@ extern off_t nth_packed_object_offset(const struct packed_git *, uint32_t n);
 extern off_t find_pack_entry_one(const unsigned char *sha1, struct packed_git *);
 
 extern int is_pack_valid(struct packed_git *);
-extern void *unpack_entry(struct packed_git *, off_t, enum object_type *, unsigned long *);
+extern void *unpack_entry(struct repository *r, struct packed_git *, off_t, enum object_type *, unsigned long *);
 extern unsigned long unpack_object_header_buffer(const unsigned char *buf, unsigned long len, enum object_type *type, unsigned long *sizep);
 extern unsigned long get_size_from_delta(struct packed_git *, struct pack_window **, off_t);
 extern int unpack_object_header(struct packed_git *, struct pack_window **, off_t *, unsigned long *);
@@ -115,14 +126,20 @@ extern void release_pack_memory(size_t);
 /* global flag to enable extra checks when accessing packed objects */
 extern int do_check_packed_object_crc;
 
-extern int packed_object_info(struct packed_git *pack, off_t offset, struct object_info *);
+extern int packed_object_info(struct repository *r,
+                             struct packed_git *pack,
+                             off_t offset, struct object_info *);
 
 extern void mark_bad_packed_object(struct packed_git *p, const unsigned char *sha1);
 extern const struct packed_git *has_packed_and_bad(const unsigned char *sha1);
 
-extern int find_pack_entry(const unsigned char *sha1, struct pack_entry *e);
+/*
+ * Iff a pack file in the given repository contains the object named by sha1,
+ * return true and store its location to e.
+ */
+extern int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e);
 
-extern int has_sha1_pack(const unsigned char *sha1);
+extern int has_object_pack(const struct object_id *oid);
 
 extern int has_pack_index(const unsigned char *sha1);
 
@@ -140,6 +157,7 @@ typedef int each_packed_object_fn(const struct object_id *oid,
                                  struct packed_git *pack,
                                  uint32_t pos,
                                  void *data);
+extern int for_each_object_in_pack(struct packed_git *p, each_packed_object_fn, void *data);
 extern int for_each_packed_object(each_packed_object_fn, void *, unsigned flags);
 
 /*
diff --git a/pager.c b/pager.c
index 92b23e6cd1d44a26c86afeeb748ddc0aee3f9154..a768797fcfcc44de4dbe4d983a45ade8c81b2e1c 100644 (file)
--- a/pager.c
+++ b/pager.c
@@ -2,6 +2,7 @@
 #include "config.h"
 #include "run-command.h"
 #include "sigchain.h"
+#include "alias.h"
 
 #ifndef DEFAULT_PAGER
 #define DEFAULT_PAGER "less"
@@ -109,10 +110,15 @@ void setup_pager(void)
                return;
 
        /*
-        * force computing the width of the terminal before we redirect
-        * the standard output to the pager.
+        * After we redirect standard output, we won't be able to use an ioctl
+        * to get the terminal size. Let's grab it now, and then set $COLUMNS
+        * to communicate it to any sub-processes.
         */
-       (void) term_columns();
+       {
+               char buf[64];
+               xsnprintf(buf, sizeof(buf), "%d", term_columns());
+               setenv("COLUMNS", buf, 0);
+       }
 
        setenv("GIT_PAGER_IN_USE", "true", 1);
 
index c6679cb2cdee15981ee9ef31c402c358a3727d1e..0f9f311a7a93350a584125c90da643fce96c34e7 100644 (file)
@@ -38,7 +38,11 @@ int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
 int parse_opt_expiry_date_cb(const struct option *opt, const char *arg,
                             int unset)
 {
-       return parse_expiry_date(arg, (timestamp_t *)opt->value);
+       if (unset)
+               arg = "never";
+       if (parse_expiry_date(arg, (timestamp_t *)opt->value))
+               die(_("malformed expiration date '%s'"), arg);
+       return 0;
 }
 
 int parse_opt_color_flag_cb(const struct option *opt, const char *arg,
index 125e84f98451b4eb12e9d8a6cb4da58b2d8db51e..0f7059a8ab32a624775026d7dc2289245c87c192 100644 (file)
@@ -317,14 +317,16 @@ is_abbreviated:
                return get_value(p, options, all_opts, flags ^ opt_flags);
        }
 
-       if (ambiguous_option)
-               return error("Ambiguous option: %s "
+       if (ambiguous_option) {
+               error("Ambiguous option: %s "
                        "(could be --%s%s or --%s%s)",
                        arg,
                        (ambiguous_flags & OPT_UNSET) ?  "no-" : "",
                        ambiguous_option->long_name,
                        (abbrev_flags & OPT_UNSET) ?  "no-" : "",
                        abbrev_option->long_name);
+               return -3;
+       }
        if (abbrev_option)
                return get_value(p, abbrev_option, all_opts, abbrev_flags);
        return -2;
@@ -476,7 +478,6 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                       const char * const usagestr[])
 {
        int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
-       int err = 0;
 
        /* we must reset ->opt, unknown short option leave it dangling */
        ctx->opt = NULL;
@@ -505,7 +506,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                        ctx->opt = arg + 1;
                        switch (parse_short_opt(ctx, options)) {
                        case -1:
-                               goto show_usage_error;
+                               return PARSE_OPT_ERROR;
                        case -2:
                                if (ctx->opt)
                                        check_typos(arg + 1, options);
@@ -518,7 +519,7 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                        while (ctx->opt) {
                                switch (parse_short_opt(ctx, options)) {
                                case -1:
-                                       goto show_usage_error;
+                                       return PARSE_OPT_ERROR;
                                case -2:
                                        if (internal_help && *ctx->opt == 'h')
                                                goto show_usage;
@@ -550,9 +551,11 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
                        goto show_usage;
                switch (parse_long_opt(ctx, arg + 2, options)) {
                case -1:
-                       goto show_usage_error;
+                       return PARSE_OPT_ERROR;
                case -2:
                        goto unknown;
+               case -3:
+                       goto show_usage;
                }
                continue;
 unknown:
@@ -563,10 +566,8 @@ unknown:
        }
        return PARSE_OPT_DONE;
 
- show_usage_error:
-       err = 1;
  show_usage:
-       return usage_with_options_internal(ctx, usagestr, options, 0, err);
+       return usage_with_options_internal(ctx, usagestr, options, 0, 0);
 }
 
 int parse_options_end(struct parse_opt_ctx_t *ctx)
@@ -585,6 +586,7 @@ int parse_options(int argc, const char **argv, const char *prefix,
        parse_options_start(&ctx, argc, argv, prefix, options, flags);
        switch (parse_options_step(&ctx, options, usagestr)) {
        case PARSE_OPT_HELP:
+       case PARSE_OPT_ERROR:
                exit(129);
        case PARSE_OPT_NON_OPTION:
        case PARSE_OPT_DONE:
index ab1cc362bf2918c28a14dd851c1b1a13dfa0c863..dd14911a297a5b10705ecb31243c55a7dc2f193c 100644 (file)
@@ -200,6 +200,7 @@ enum {
        PARSE_OPT_HELP = -1,
        PARSE_OPT_DONE,
        PARSE_OPT_NON_OPTION,
+       PARSE_OPT_ERROR,
        PARSE_OPT_UNKNOWN
 };
 
diff --git a/path.c b/path.c
index 84e88243a9a2f7de14e02217df247a78fe68fc91..9a4b9e7d0ec6aac56ce16fd9a2b8a41e087e4653 100644 (file)
--- a/path.c
+++ b/path.c
@@ -10,6 +10,7 @@
 #include "submodule-config.h"
 #include "path.h"
 #include "packfile.h"
+#include "object-store.h"
 
 static int get_st_mode_bits(const char *path, int *mode)
 {
@@ -382,7 +383,7 @@ static void adjust_git_path(const struct repository *repo,
                strbuf_splice(buf, 0, buf->len,
                              repo->index_file, strlen(repo->index_file));
        else if (dir_prefix(base, "objects"))
-               replace_dir(buf, git_dir_len + 7, repo->objectdir);
+               replace_dir(buf, git_dir_len + 7, repo->objects->objectdir);
        else if (git_hooks_path && dir_prefix(base, "hooks"))
                replace_dir(buf, git_dir_len + 5, git_hooks_path);
        else if (repo->different_commondir)
index 82eb39cd679ffbce82abac691c6f4343335b9924..27cd6067860d4fdb0b48b6bcf7c84d5903efd71b 100644 (file)
@@ -198,7 +198,7 @@ static void parse_pathspec_attr_match(struct pathspec_item *item, const char *va
        }
 
        if (item->attr_check->nr != item->attr_match_nr)
-               die("BUG: should have same number of entries");
+               BUG("should have same number of entries");
 
        string_list_clear(&list, 0);
 }
@@ -422,7 +422,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
 
        if (pathspec_prefix >= 0 &&
            (prefixlen || (prefix && *prefix)))
-               die("BUG: 'prefix' magic is supposed to be used at worktree's root");
+               BUG("'prefix' magic is supposed to be used at worktree's root");
 
        if ((magic & PATHSPEC_LITERAL) && (magic & PATHSPEC_GLOB))
                die(_("%s: 'literal' and 'glob' are incompatible"), elt);
@@ -486,7 +486,7 @@ static void init_pathspec_item(struct pathspec_item *item, unsigned flags,
        /* sanity checks, pathspec matchers assume these are sane */
        if (item->nowildcard_len > item->len ||
            item->prefix         > item->len) {
-               die ("BUG: error initializing pathspec_item");
+               BUG("error initializing pathspec_item");
        }
 }
 
@@ -545,7 +545,7 @@ void parse_pathspec(struct pathspec *pathspec,
 
        if ((flags & PATHSPEC_PREFER_CWD) &&
            (flags & PATHSPEC_PREFER_FULL))
-               die("BUG: PATHSPEC_PREFER_CWD and PATHSPEC_PREFER_FULL are incompatible");
+               BUG("PATHSPEC_PREFER_CWD and PATHSPEC_PREFER_FULL are incompatible");
 
        /* No arguments with prefix -> prefix pathspec */
        if (!entry) {
@@ -553,7 +553,7 @@ void parse_pathspec(struct pathspec *pathspec,
                        return;
 
                if (!(flags & PATHSPEC_PREFER_CWD))
-                       die("BUG: PATHSPEC_PREFER_CWD requires arguments");
+                       BUG("PATHSPEC_PREFER_CWD requires arguments");
 
                pathspec->items = item = xcalloc(1, sizeof(*item));
                item->match = xstrdup(prefix);
@@ -609,7 +609,7 @@ void parse_pathspec(struct pathspec *pathspec,
 
        if (pathspec->magic & PATHSPEC_MAXDEPTH) {
                if (flags & PATHSPEC_KEEP_ORDER)
-                       die("BUG: PATHSPEC_MAXDEPTH_VALID and PATHSPEC_KEEP_ORDER are incompatible");
+                       BUG("PATHSPEC_MAXDEPTH_VALID and PATHSPEC_KEEP_ORDER are incompatible");
                QSORT(pathspec->items, pathspec->nr, pathspec_item_cmp);
        }
 }
index 16ebcc612ce4acb4fba6511d5b388184934cb22a..d856930b2e5f31bb7b1e7aef46e8e056068bb431 100644 (file)
@@ -554,7 +554,7 @@ sub get_record {
        my ($fh, $rs) = @_;
        local $/ = $rs;
        my $rec = <$fh>;
-       chomp $rec if defined $rs;
+       chomp $rec if defined $rec;
        $rec;
 }
 
index dba96fff0aecef6eac83aacdaa54b46806cdb0a4..bfb4fb67a13f4530aae2d974e579b9ba45e20cdb 100644 (file)
@@ -18,7 +18,7 @@ our @EXPORT_OK = @EXPORT;
 
 sub __bootstrap_locale_messages {
        our $TEXTDOMAIN = 'git';
-       our $TEXTDOMAINDIR = $ENV{GIT_TEXTDOMAINDIR} || '@@LOCALEDIR@@';
+       our $TEXTDOMAINDIR ||= $ENV{GIT_TEXTDOMAINDIR} || '@@LOCALEDIR@@';
 
        require POSIX;
        POSIX->import(qw(setlocale));
index 991a5885e9230b1f55bd6f3b7f7b53321bf9e562..76b29659057d329670ce07b102de37caf133e97f 100644 (file)
@@ -1482,7 +1482,6 @@ sub call_authors_prog {
        }
        if ($author =~ /^\s*(.+?)\s*<(.*)>\s*$/) {
                my ($name, $email) = ($1, $2);
-               $email = undef if length $2 == 0;
                return [$name, $email];
        } else {
                die "Author: $orig_author: $::_authors_prog returned "
@@ -2020,8 +2019,8 @@ sub make_log_entry {
                remove_username($full_url);
                $log_entry{metadata} = "$full_url\@$r $uuid";
                $log_entry{svm_revision} = $r;
-               $email ||= "$author\@$uuid";
-               $commit_email ||= "$author\@$uuid";
+               $email = "$author\@$uuid" unless defined $email;
+               $commit_email = "$author\@$uuid" unless defined $commit_email;
        } elsif ($self->use_svnsync_props) {
                my $full_url = canonicalize_url(
                        add_path_to_url( $self->svnsync->{url}, $self->path )
@@ -2029,15 +2028,15 @@ sub make_log_entry {
                remove_username($full_url);
                my $uuid = $self->svnsync->{uuid};
                $log_entry{metadata} = "$full_url\@$rev $uuid";
-               $email ||= "$author\@$uuid";
-               $commit_email ||= "$author\@$uuid";
+               $email = "$author\@$uuid" unless defined $email;
+               $commit_email = "$author\@$uuid" unless defined $commit_email;
        } else {
                my $url = $self->metadata_url;
                remove_username($url);
                my $uuid = $self->rewrite_uuid || $self->ra->get_uuid;
                $log_entry{metadata} = "$url\@$rev " . $uuid;
-               $email ||= "$author\@" . $uuid;
-               $commit_email ||= "$author\@" . $uuid;
+               $email = "$author\@$uuid" unless defined $email;
+               $commit_email = "$author\@$uuid" unless defined $commit_email;
        }
        $log_entry{name} = $name;
        $log_entry{email} = $email;
diff --git a/perl/header_templates/fixed_prefix.template.pl b/perl/header_templates/fixed_prefix.template.pl
new file mode 100644 (file)
index 0000000..857b439
--- /dev/null
@@ -0,0 +1 @@
+use lib (split(/@@PATHSEP@@/, $ENV{GITPERLLIB} || '@@INSTLIBDIR@@'));
diff --git a/perl/header_templates/runtime_prefix.template.pl b/perl/header_templates/runtime_prefix.template.pl
new file mode 100644 (file)
index 0000000..9d28b3d
--- /dev/null
@@ -0,0 +1,42 @@
+# BEGIN RUNTIME_PREFIX generated code.
+#
+# This finds our Git::* libraries relative to the script's runtime path.
+sub __git_system_path {
+       my ($relpath) = @_;
+       my $gitexecdir_relative = '@@GITEXECDIR_REL@@';
+
+       # GIT_EXEC_PATH is supplied by `git` or the test suite.
+       my $exec_path;
+       if (exists $ENV{GIT_EXEC_PATH}) {
+               $exec_path = $ENV{GIT_EXEC_PATH};
+       } else {
+               # This can happen if this script is being directly invoked instead of run
+               # by "git".
+               require FindBin;
+               $exec_path = $FindBin::Bin;
+       }
+
+       # Trim off the relative gitexecdir path to get the system path.
+       (my $prefix = $exec_path) =~ s/\Q$gitexecdir_relative\E$//;
+
+       require File::Spec;
+       return File::Spec->catdir($prefix, $relpath);
+}
+
+BEGIN {
+       use lib split /@@PATHSEP@@/,
+       (
+               $ENV{GITPERLLIB} ||
+               do {
+                       my $perllibdir = __git_system_path('@@PERLLIBDIR_REL@@');
+                       (-e $perllibdir) || die("Invalid system path ($relpath): $path");
+                       $perllibdir;
+               }
+       );
+
+       # Export the system locale directory to the I18N module. The locale directory
+       # is only installed if NO_GETTEXT is set.
+       $Git::I18N::TEXTDOMAINDIR = __git_system_path('@@LOCALEDIR_REL@@');
+}
+
+# END RUNTIME_PREFIX generated code.
index 2827ca772a3703f71bc588d0f6cacd5caa318fe7..a593c08aad814ca015198936158219f44cbd0226 100644 (file)
@@ -91,6 +91,12 @@ void packet_flush(int fd)
        write_or_die(fd, "0000", 4);
 }
 
+void packet_delim(int fd)
+{
+       packet_trace("0001", 4, 1);
+       write_or_die(fd, "0001", 4);
+}
+
 int packet_flush_gently(int fd)
 {
        packet_trace("0000", 4, 1);
@@ -105,6 +111,12 @@ void packet_buf_flush(struct strbuf *buf)
        strbuf_add(buf, "0000", 4);
 }
 
+void packet_buf_delim(struct strbuf *buf)
+{
+       packet_trace("0001", 4, 1);
+       strbuf_add(buf, "0001", 4);
+}
+
 static void set_packet_header(char *buf, const int size)
 {
        static char hexchar[] = "0123456789abcdef";
@@ -203,6 +215,22 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...)
        va_end(args);
 }
 
+void packet_buf_write_len(struct strbuf *buf, const char *data, size_t len)
+{
+       size_t orig_len, n;
+
+       orig_len = buf->len;
+       strbuf_addstr(buf, "0000");
+       strbuf_add(buf, data, len);
+       n = buf->len - orig_len;
+
+       if (n > LARGE_PACKET_MAX)
+               die("protocol error: impossibly long line");
+
+       set_packet_header(&buf->buf[orig_len], n);
+       packet_trace(data, len, 1);
+}
+
 int write_packetized_from_fd(int fd_in, int fd_out)
 {
        static char buf[LARGE_PACKET_DATA_MAX];
@@ -249,7 +277,7 @@ static int get_packet_data(int fd, char **src_buf, size_t *src_size,
        ssize_t ret;
 
        if (fd >= 0 && src_buf && *src_buf)
-               die("BUG: multiple sources given to packet_read");
+               BUG("multiple sources given to packet_read");
 
        /* Read up to "size" bytes from our source, whatever it is. */
        if (src_buf && *src_buf) {
@@ -280,28 +308,43 @@ static int packet_length(const char *linelen)
        return (val < 0) ? val : (val << 8) | hex2chr(linelen + 2);
 }
 
-int packet_read(int fd, char **src_buf, size_t *src_len,
-               char *buffer, unsigned size, int options)
+enum packet_read_status packet_read_with_status(int fd, char **src_buffer,
+                                               size_t *src_len, char *buffer,
+                                               unsigned size, int *pktlen,
+                                               int options)
 {
-       int len, ret;
+       int len;
        char linelen[4];
 
-       ret = get_packet_data(fd, src_buf, src_len, linelen, 4, options);
-       if (ret < 0)
-               return ret;
+       if (get_packet_data(fd, src_buffer, src_len, linelen, 4, options) < 0) {
+               *pktlen = -1;
+               return PACKET_READ_EOF;
+       }
+
        len = packet_length(linelen);
-       if (len < 0)
+
+       if (len < 0) {
                die("protocol error: bad line length character: %.4s", linelen);
-       if (!len) {
+       } else if (!len) {
                packet_trace("0000", 4, 0);
-               return 0;
+               *pktlen = 0;
+               return PACKET_READ_FLUSH;
+       } else if (len == 1) {
+               packet_trace("0001", 4, 0);
+               *pktlen = 0;
+               return PACKET_READ_DELIM;
+       } else if (len < 4) {
+               die("protocol error: bad line length %d", len);
        }
+
        len -= 4;
-       if (len >= size)
+       if ((unsigned)len >= size)
                die("protocol error: bad line length %d", len);
-       ret = get_packet_data(fd, src_buf, src_len, buffer, len, options);
-       if (ret < 0)
-               return ret;
+
+       if (get_packet_data(fd, src_buffer, src_len, buffer, len, options) < 0) {
+               *pktlen = -1;
+               return PACKET_READ_EOF;
+       }
 
        if ((options & PACKET_READ_CHOMP_NEWLINE) &&
            len && buffer[len-1] == '\n')
@@ -309,7 +352,19 @@ int packet_read(int fd, char **src_buf, size_t *src_len,
 
        buffer[len] = 0;
        packet_trace(buffer, len, 0);
-       return len;
+       *pktlen = len;
+       return PACKET_READ_NORMAL;
+}
+
+int packet_read(int fd, char **src_buffer, size_t *src_len,
+               char *buffer, unsigned size, int options)
+{
+       int pktlen = -1;
+
+       packet_read_with_status(fd, src_buffer, src_len, buffer, size,
+                               &pktlen, options);
+
+       return pktlen;
 }
 
 static char *packet_read_line_generic(int fd,
@@ -377,3 +432,53 @@ ssize_t read_packetized_to_strbuf(int fd_in, struct strbuf *sb_out)
        }
        return sb_out->len - orig_len;
 }
+
+/* Packet Reader Functions */
+void packet_reader_init(struct packet_reader *reader, int fd,
+                       char *src_buffer, size_t src_len,
+                       int options)
+{
+       memset(reader, 0, sizeof(*reader));
+
+       reader->fd = fd;
+       reader->src_buffer = src_buffer;
+       reader->src_len = src_len;
+       reader->buffer = packet_buffer;
+       reader->buffer_size = sizeof(packet_buffer);
+       reader->options = options;
+}
+
+enum packet_read_status packet_reader_read(struct packet_reader *reader)
+{
+       if (reader->line_peeked) {
+               reader->line_peeked = 0;
+               return reader->status;
+       }
+
+       reader->status = packet_read_with_status(reader->fd,
+                                                &reader->src_buffer,
+                                                &reader->src_len,
+                                                reader->buffer,
+                                                reader->buffer_size,
+                                                &reader->pktlen,
+                                                reader->options);
+
+       if (reader->status == PACKET_READ_NORMAL)
+               reader->line = reader->buffer;
+       else
+               reader->line = NULL;
+
+       return reader->status;
+}
+
+enum packet_read_status packet_reader_peek(struct packet_reader *reader)
+{
+       /* Only allow peeking a single line */
+       if (reader->line_peeked)
+               return reader->status;
+
+       /* Peek a line by reading it and setting peeked flag */
+       packet_reader_read(reader);
+       reader->line_peeked = 1;
+       return reader->status;
+}
index 3dad583e2d02264c4a831c939ae0e13a54de2ff6..5b28d43472db41a59f0a44845953f163748593b0 100644 (file)
  * side can't, we stay with pure read/write interfaces.
  */
 void packet_flush(int fd);
+void packet_delim(int fd);
 void packet_write_fmt(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
 void packet_buf_flush(struct strbuf *buf);
+void packet_buf_delim(struct strbuf *buf);
 void packet_write(int fd_out, const char *buf, size_t size);
 void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
+void packet_buf_write_len(struct strbuf *buf, const char *data, size_t len);
 int packet_flush_gently(int fd);
 int packet_write_fmt_gently(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3)));
 int write_packetized_from_fd(int fd_in, int fd_out);
@@ -65,6 +68,23 @@ int write_packetized_from_buf(const char *src_in, size_t len, int fd_out);
 int packet_read(int fd, char **src_buffer, size_t *src_len, char
                *buffer, unsigned size, int options);
 
+/*
+ * Read a packetized line into a buffer like the 'packet_read()' function but
+ * returns an 'enum packet_read_status' which indicates the status of the read.
+ * The number of bytes read will be assigined to *pktlen if the status of the
+ * read was 'PACKET_READ_NORMAL'.
+ */
+enum packet_read_status {
+       PACKET_READ_EOF,
+       PACKET_READ_NORMAL,
+       PACKET_READ_FLUSH,
+       PACKET_READ_DELIM,
+};
+enum packet_read_status packet_read_with_status(int fd, char **src_buffer,
+                                               size_t *src_len, char *buffer,
+                                               unsigned size, int *pktlen,
+                                               int options);
+
 /*
  * Convenience wrapper for packet_read that is not gentle, and sets the
  * CHOMP_NEWLINE option. The return value is NULL for a flush packet,
@@ -96,6 +116,64 @@ char *packet_read_line_buf(char **src_buf, size_t *src_len, int *size);
  */
 ssize_t read_packetized_to_strbuf(int fd_in, struct strbuf *sb_out);
 
+struct packet_reader {
+       /* source file descriptor */
+       int fd;
+
+       /* source buffer and its size */
+       char *src_buffer;
+       size_t src_len;
+
+       /* buffer that pkt-lines are read into and its size */
+       char *buffer;
+       unsigned buffer_size;
+
+       /* options to be used during reads */
+       int options;
+
+       /* status of the last read */
+       enum packet_read_status status;
+
+       /* length of data read during the last read */
+       int pktlen;
+
+       /* the last line read */
+       const char *line;
+
+       /* indicates if a line has been peeked */
+       int line_peeked;
+};
+
+/*
+ * Initialize a 'struct packet_reader' object which is an
+ * abstraction around the 'packet_read_with_status()' function.
+ */
+extern void packet_reader_init(struct packet_reader *reader, int fd,
+                              char *src_buffer, size_t src_len,
+                              int options);
+
+/*
+ * Perform a packet read and return the status of the read.
+ * The values of 'pktlen' and 'line' are updated based on the status of the
+ * read as follows:
+ *
+ * PACKET_READ_ERROR: 'pktlen' is set to '-1' and 'line' is set to NULL
+ * PACKET_READ_NORMAL: 'pktlen' is set to the number of bytes read
+ *                    'line' is set to point at the read line
+ * PACKET_READ_FLUSH: 'pktlen' is set to '0' and 'line' is set to NULL
+ */
+extern enum packet_read_status packet_reader_read(struct packet_reader *reader);
+
+/*
+ * Peek the next packet line without consuming it and return the status.
+ * The next call to 'packet_reader_read()' will perform a read of the same line
+ * that was peeked, consuming the line.
+ *
+ * Peeking multiple times without calling 'packet_reader_read()' will return
+ * the same result.
+ */
+extern enum packet_read_status packet_reader_peek(struct packet_reader *reader);
+
 #define DEFAULT_PACKET_MAX 1000
 #define LARGE_PACKET_MAX 65520
 #define LARGE_PACKET_DATA_MAX (LARGE_PACKET_MAX - 4)
index 065771cfe6b5208503f3b9d768792ff8206a2b06..d8f7a2ba38d9520e6f4b62d187bfd4f9fe9ba4b3 100644 (file)
--- a/po/TEAMS
+++ b/po/TEAMS
@@ -13,12 +13,8 @@ Members:     Alex Henrie <alexhenrie24@gmail.com>
 Language:      de (German)
 Repository:    https://github.com/ralfth/git-po-de
 Leader:                Ralf Thielow <ralf.thielow@gmail.com>
-Members:       Thomas Rast <tr@thomasrast.ch>
-               Jan Krüger <jk@jk.gs>
-               Christian Stimming <stimming@tuhh.de>
+Members:       Matthias Rüster <matthias.ruester@gmail.com>
                Phillip Szelat <phillip.szelat@gmail.com>
-               Matthias Rüster <matthias.ruester@gmail.com>
-               Magnus Görlitz <magnus.goerlitz@googlemail.com>
 
 Language:      es (Spanish)
 Repository:    https://github.com/ChrisADR/git-po
@@ -39,8 +35,8 @@ Members:      Stefano Lattarini <stefano.lattarini AT gmail.com>
 
 Language:      ko (Korean)
 Repository:    https://github.com/git-l10n-ko/git-l10n-ko/
-Leader:                Changwoo Ryu <cwryu@debian.org>
-Members:       Gwan-gyeong Mun <elongbug@gmail.com>
+Leader:                Gwan-gyeong Mun <elongbug@gmail.com>
+Members:       Changwoo Ryu <cwryu@debian.org>
                Sihyeon Jang <uneedsihyeon@gmail.com>
 
 Language:      pt_PT (Portuguese - Portugal)
index 48fe3158e591f4782183e338dc453495eb6ba1d0..036918f44d1a5fb872f0b9a9e56b47f1a6e4c806 100644 (file)
--- a/po/bg.po
+++ b/po/bg.po
 # octopus merge множествено сливане
 # stale remote старо хранилище
 # rebase пребазирам
+# merge base база за сливане
 # force (push) принудително изтласквам
 # stash/index индекс
-# squash commits смачкване на подавания
+# squash commit вкарвам подаване в преднходното
+# fixup commit вкарвам подаване в предходното без следа
 # root commit начално подаване
-# fixup вкарвам подаване в предното без следа
 # remote-tracking branch следящ клон
 # git bundle пратка на git
 # bisect двоично търсене
@@ -32,7 +33,9 @@
 # revision range диапазон на версиите
 # cover letter придружаващо писмо
 # reference repository еталонно хранилище
+# graft присадка
 # grafted repository хранилище с присаждане
+# replace refs заместващи указатели
 # embedded repository вградено/вътрешно хранилище (добавянето му е грешка)
 # thin pack съкратен пакет
 # stat (a file) получавам информация чрез „stat“ (за файл)
@@ -81,6 +84,7 @@
 # binary patch двоична кръпка
 # reverse-apply прилагам в обратна посока
 # todo file файл с команди
+# todo command запланувава команда
 # alternate алтернативен източник
 # superproject обхващащ проект
 # split index разделяне на индекса
 # manual, man page ръководство
 # guide въведение
 # partial clone непълно хранилище
+# cousins сестрински клони
+# expiration date дата на срок
+# is well formed е по правилата
+# namespace пространство от имена
+# repository layout устройство на хранилището
+# collection/series of patches поредица от кръпки
+# recieve получавам
+# BOM маркер за поредността на байтовете
 # ------------------------
 # „$var“ - може да не сработва за shell има gettext и eval_gettext - проверка - намират се лесно по „$
 # ------------------------
 # HEAD as a reference vs head of a branch
 # git update-index -h извежда само един ред, а не цялата помощ за опциите
 # git fetch --al работи подобно на --all
-#
 msgid ""
 msgstr ""
 "Project-Id-Version: git master\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2018-03-16 07:29+0800\n"
-"PO-Revision-Date: 2018-03-16 09:53+0100\n"
+"POT-Creation-Date: 2018-06-16 22:06+0800\n"
+"PO-Revision-Date: 2018-06-17 13:16+0200\n"
 "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
 "Language-Team: Bulgarian <dict@fsa-bg.org>\n"
 "Language: bg\n"
@@ -113,37 +124,37 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: advice.c:62
+#: advice.c:92
 #, c-format
-msgid "hint: %.*s\n"
-msgstr "Подсказка: %.*s\n"
+msgid "%shint: %.*s%s\n"
+msgstr "%sподсказка: %.*s%s\n"
 
-#: advice.c:90
+#: advice.c:137
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr "Отбирането на подавания е блокирано от неслети файлове."
 
-#: advice.c:92
+#: advice.c:139
 msgid "Committing is not possible because you have unmerged files."
 msgstr "Подаването е блокирано от неслети файлове."
 
-#: advice.c:94
+#: advice.c:141
 msgid "Merging is not possible because you have unmerged files."
 msgstr "Сливането е блокирано от неслети файлове."
 
-#: advice.c:96
+#: advice.c:143
 msgid "Pulling is not possible because you have unmerged files."
 msgstr "Издърпването е блокирано от неслети файлове."
 
-#: advice.c:98
+#: advice.c:145
 msgid "Reverting is not possible because you have unmerged files."
 msgstr "Отмяната е блокирана от неслети файлове."
 
-#: advice.c:100
+#: advice.c:147
 #, c-format
 msgid "It is not possible to %s because you have unmerged files."
 msgstr "Действието „%s“ е блокирано от неслети файлове."
 
-#: advice.c:108
+#: advice.c:155
 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."
@@ -151,23 +162,23 @@ msgstr ""
 "Редактирайте ги в работното дърво, и тогава ползвайте „git add/rm ФАЙЛ“,\n"
 "за да отбележите коригирането им.  След това извършете подаването."
 
-#: advice.c:116
+#: advice.c:163
 msgid "Exiting because of an unresolved conflict."
 msgstr "Изход от програмата заради некоригиран конфликт."
 
-#: advice.c:121 builtin/merge.c:1251
+#: advice.c:168 builtin/merge.c:1250
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
 msgstr "Не сте завършили сливане.  (Указателят „MERGE_HEAD“ съществува)."
 
-#: advice.c:123
+#: advice.c:170
 msgid "Please, commit your changes before merging."
 msgstr "Промените трябва да се подадат преди сливане."
 
-#: advice.c:124
+#: advice.c:171
 msgid "Exiting because of unfinished merge."
 msgstr "Изход от програмата заради незавършено сливане."
 
-#: advice.c:130
+#: advice.c:177
 #, c-format
 msgid ""
 "Note: checking out '%s'.\n"
@@ -449,7 +460,7 @@ msgstr "неуспешно прилагане на кръпка: „%s:%ld“"
 msgid "cannot checkout %s"
 msgstr "„%s“ не може да се изтегли"
 
-#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:277
+#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:278
 #, c-format
 msgid "failed to read %s"
 msgstr "файлът „%s“ не може да бъде прочетен"
@@ -477,7 +488,7 @@ msgstr "„%s“ не съответства на индекса"
 #: apply.c:3560
 msgid "repository lacks the necessary blob to fall back on 3-way merge."
 msgstr ""
-"в хранилището липсват необходимите обекти BLOB, за да се премине към тройно "
+"в хранилището липсват необходимите обекти-BLOB, за да се премине към тройно "
 "сливане."
 
 #: apply.c:3563
@@ -654,7 +665,7 @@ msgstr[1] "Прилагане на кръпката „%%s“ с %d отхвър
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "съкращаване на името на файла с отхвърлените парчета на „ %.*s.rej“"
 
-#: apply.c:4545 builtin/fetch.c:775 builtin/fetch.c:1025
+#: apply.c:4545 builtin/fetch.c:786 builtin/fetch.c:1036
 #, c-format
 msgid "cannot open %s"
 msgstr "„%s“ не може да бъде отворен"
@@ -710,15 +721,15 @@ msgstr[0] ""
 msgstr[1] ""
 "Добавени са %d реда след корекцията на грешките в знаците за интервали."
 
-#: apply.c:4894 builtin/add.c:539 builtin/mv.c:298 builtin/rm.c:390
+#: apply.c:4894 builtin/add.c:538 builtin/mv.c:300 builtin/rm.c:389
 msgid "Unable to write new index file"
 msgstr "Новият индекс не може да бъде записан"
 
 #: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257
-#: builtin/clone.c:118 builtin/fetch.c:127 builtin/pull.c:193
-#: builtin/submodule--helper.c:403 builtin/submodule--helper.c:1197
-#: builtin/submodule--helper.c:1200 builtin/submodule--helper.c:1567
-#: builtin/submodule--helper.c:1570 builtin/submodule--helper.c:1787
+#: builtin/clone.c:120 builtin/fetch.c:126 builtin/pull.c:198
+#: builtin/submodule--helper.c:405 builtin/submodule--helper.c:1210
+#: builtin/submodule--helper.c:1213 builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1587 builtin/submodule--helper.c:1807
 #: git-add--interactive.perl:197
 msgid "path"
 msgstr "път"
@@ -796,7 +807,7 @@ msgstr "да се осигури контекст от поне такъв БР
 
 #: apply.c:4960 builtin/am.c:2242 builtin/interpret-trailers.c:95
 #: builtin/interpret-trailers.c:97 builtin/interpret-trailers.c:99
-#: builtin/pack-objects.c:3035
+#: builtin/pack-objects.c:3177
 msgid "action"
 msgstr "действие"
 
@@ -825,9 +836,9 @@ msgstr "оставяне на отхвърлените парчета във ф
 msgid "allow overlapping hunks"
 msgstr "позволяване на застъпващи се парчета"
 
-#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21
-#: builtin/commit.c:1276 builtin/count-objects.c:96 builtin/fsck.c:665
-#: builtin/log.c:1901 builtin/mv.c:123 builtin/read-tree.c:125
+#: apply.c:4977 builtin/add.c:290 builtin/check-ignore.c:21
+#: builtin/commit.c:1301 builtin/count-objects.c:98 builtin/fsck.c:666
+#: builtin/log.c:1901 builtin/mv.c:122 builtin/read-tree.c:124
 msgid "be verbose"
 msgstr "повече подробности"
 
@@ -866,98 +877,98 @@ msgstr ""
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote ХРАНИЛИЩЕ [--exec КОМАНДА] --list"
 
-#: archive.c:351 builtin/add.c:176 builtin/add.c:515 builtin/rm.c:299
+#: archive.c:351 builtin/add.c:176 builtin/add.c:514 builtin/rm.c:298
 #, c-format
 msgid "pathspec '%s' did not match any files"
 msgstr "пътят „%s“ не съвпада с никой файл"
 
-#: archive.c:436
+#: archive.c:434
 msgid "fmt"
 msgstr "ФОРМАТ"
 
-#: archive.c:436
+#: archive.c:434
 msgid "archive format"
 msgstr "ФОРМАТ на архива"
 
-#: archive.c:437 builtin/log.c:1462
+#: archive.c:435 builtin/log.c:1462
 msgid "prefix"
 msgstr "ПРЕФИКС"
 
-#: archive.c:438
+#: archive.c:436
 msgid "prepend prefix to each pathname in the archive"
 msgstr "добавяне на този ПРЕФИКС към всеки път в архива"
 
-#: archive.c:439 builtin/blame.c:702 builtin/blame.c:703 builtin/config.c:62
-#: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:869
+#: archive.c:437 builtin/blame.c:813 builtin/blame.c:814 builtin/config.c:127
+#: builtin/fast-export.c:1007 builtin/fast-export.c:1009 builtin/grep.c:869
 #: builtin/hash-object.c:103 builtin/ls-files.c:551 builtin/ls-files.c:554
-#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120
+#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:119
 #: parse-options.h:165
 msgid "file"
 msgstr "ФАЙЛ"
 
-#: archive.c:440 builtin/archive.c:89
+#: archive.c:438 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "запазване на архива в този ФАЙЛ"
 
-#: archive.c:442
+#: archive.c:440
 msgid "read .gitattributes in working directory"
 msgstr "изчитане на „.gitattributes“ в работната директория"
 
-#: archive.c:443
+#: archive.c:441
 msgid "report archived files on stderr"
 msgstr "извеждане на архивираните файлове на стандартната грешка"
 
-#: archive.c:444
+#: archive.c:442
 msgid "store only"
 msgstr "само съхранение без компресиране"
 
-#: archive.c:445
+#: archive.c:443
 msgid "compress faster"
 msgstr "бързо компресиране"
 
-#: archive.c:453
+#: archive.c:451
 msgid "compress better"
 msgstr "добро компресиране"
 
-#: archive.c:456
+#: archive.c:454
 msgid "list supported archive formats"
 msgstr "извеждане на списъка с поддържаните формати"
 
-#: archive.c:458 builtin/archive.c:90 builtin/clone.c:108 builtin/clone.c:111
-#: builtin/submodule--helper.c:1209 builtin/submodule--helper.c:1576
+#: archive.c:456 builtin/archive.c:90 builtin/clone.c:110 builtin/clone.c:113
+#: builtin/submodule--helper.c:1222 builtin/submodule--helper.c:1593
 msgid "repo"
 msgstr "хранилище"
 
-#: archive.c:459 builtin/archive.c:91
+#: archive.c:457 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "изтегляне на архива от отдалеченото ХРАНИЛИЩЕ"
 
-#: archive.c:460 builtin/archive.c:92 builtin/notes.c:489
+#: archive.c:458 builtin/archive.c:92 builtin/notes.c:489
 msgid "command"
 msgstr "команда"
 
-#: archive.c:461 builtin/archive.c:93
+#: archive.c:459 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "път към отдалечената команда „git-upload-archive“"
 
-#: archive.c:468
+#: archive.c:466
 msgid "Unexpected option --remote"
 msgstr "Неочаквана опция „--remote“"
 
-#: archive.c:470
+#: archive.c:468
 msgid "Option --exec can only be used together with --remote"
 msgstr "Опцията „--exec“ изисква „--remote“"
 
-#: archive.c:472
+#: archive.c:470
 msgid "Unexpected option --output"
 msgstr "Неочаквана опция „--output“"
 
-#: archive.c:494
+#: archive.c:492
 #, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Непознат формат на архив: „%s“"
 
-#: archive.c:501
+#: archive.c:499
 #, c-format
 msgid "Argument not supported for format '%s': -%d"
 msgstr "Аргументът не се поддържа за форма̀та „%s“: -%d"
@@ -975,22 +986,22 @@ msgstr ""
 "Отрицателните шаблони се игнорират в атрибутите на git.\n"
 "Ако ви трябва начална удивителна, ползвайте „\\!“."
 
-#: bisect.c:460
+#: bisect.c:461
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Неправилно цитирано съдържание във файла „%s“: %s"
 
-#: bisect.c:668
+#: bisect.c:669
 #, c-format
 msgid "We cannot bisect more!\n"
 msgstr "Повече не може да се търси двоично!\n"
 
-#: bisect.c:722
+#: bisect.c:723
 #, c-format
 msgid "Not a valid commit name %s"
 msgstr "Неправилно име на подаване „%s“"
 
-#: bisect.c:746
+#: bisect.c:747
 #, c-format
 msgid ""
 "The merge base %s is bad.\n"
@@ -999,7 +1010,7 @@ msgstr ""
 "Неправилна база за сливане: %s.\n"
 "Следователно грешката е коригирана между „%s“ и [%s].\n"
 
-#: bisect.c:751
+#: bisect.c:752
 #, c-format
 msgid ""
 "The merge base %s is new.\n"
@@ -1008,7 +1019,7 @@ msgstr ""
 "Нова база за сливане: %s.\n"
 "Свойството е променено между „%s“ и [%s].\n"
 
-#: bisect.c:756
+#: bisect.c:757
 #, c-format
 msgid ""
 "The merge base %s is %s.\n"
@@ -1017,7 +1028,7 @@ msgstr ""
 "Базата за сливане „%s“ е %s.\n"
 "Следователно първото %s подаване е между „%s“ и [%s].\n"
 
-#: bisect.c:764
+#: bisect.c:765
 #, c-format
 msgid ""
 "Some %s revs are not ancestors of the %s rev.\n"
@@ -1028,7 +1039,7 @@ msgstr ""
 "Двоичното търсене с git bisect няма да работи правилно.\n"
 "Дали не сте объркали указателите „%s“ и „%s“?\n"
 
-#: bisect.c:777
+#: bisect.c:778
 #, c-format
 msgid ""
 "the merge base between %s and [%s] must be skipped.\n"
@@ -1039,36 +1050,36 @@ msgstr ""
 "Не може да сме сигурни, че първото %s подаване е между „%s“ и „%s“.\n"
 "Двоичното търсене продължава."
 
-#: bisect.c:810
+#: bisect.c:811
 #, c-format
 msgid "Bisecting: a merge base must be tested\n"
 msgstr "Двоично търсене: трябва да се провери база за сливане\n"
 
-#: bisect.c:850
+#: bisect.c:851
 #, c-format
 msgid "a %s revision is needed"
 msgstr "необходима е версия „%s“"
 
-#: bisect.c:869 builtin/notes.c:175 builtin/tag.c:235
+#: bisect.c:870 builtin/notes.c:175 builtin/tag.c:236
 #, c-format
 msgid "could not create file '%s'"
 msgstr "файлът „%s“ не може да бъде създаден"
 
-#: bisect.c:920
+#: bisect.c:921
 #, c-format
 msgid "could not read file '%s'"
 msgstr "файлът „%s“ не може да бъде прочетен"
 
-#: bisect.c:950
+#: bisect.c:951
 msgid "reading bisect refs failed"
 msgstr "неуспешно прочитане на указателите за двоично търсене"
 
-#: bisect.c:969
+#: bisect.c:970
 #, c-format
 msgid "%s was both %s and %s\n"
 msgstr "„%s“ e както „%s“, така и „%s“\n"
 
-#: bisect.c:977
+#: bisect.c:978
 #, c-format
 msgid ""
 "No testable commit found.\n"
@@ -1077,7 +1088,7 @@ msgstr ""
 "Липсва подходящо за тестване подаване.\n"
 "Проверете параметрите за пътищата.\n"
 
-#: bisect.c:996
+#: bisect.c:997
 #, c-format
 msgid "(roughly %d step)"
 msgid_plural "(roughly %d steps)"
@@ -1087,52 +1098,52 @@ msgstr[1] "(приблизително %d стъпки)"
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
 #.
-#: bisect.c:1002
+#: bisect.c:1003
 #, c-format
 msgid "Bisecting: %d revision left to test after this %s\n"
 msgid_plural "Bisecting: %d revisions left to test after this %s\n"
 msgstr[0] "Двоично търсене: остава %d версия след тази %s\n"
 msgstr[1] "Двоично търсене: остават %d версии след тази %s\n"
 
-#: blame.c:1758
+#: blame.c:1756
 msgid "--contents and --reverse do not blend well."
 msgstr "Опциите „--contents“ и „--reverse“ са несъвместими"
 
-#: blame.c:1769
+#: blame.c:1767
 msgid "cannot use --contents with final commit object name"
 msgstr "Опцията „--contents“ е несъвместима с име на обект от крайно подаване"
 
-#: blame.c:1789
+#: blame.c:1787
 msgid "--reverse and --first-parent together require specified latest commit"
 msgstr ""
 "Едновременното задаване на опциите „--reverse“ и „--first-parent“ изисква "
 "указването на крайно подаване"
 
-#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699
-#: sequencer.c:2901 builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920
-#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370
-#: builtin/shortlog.c:191
+#: blame.c:1796 bundle.c:160 ref-filter.c:2075 sequencer.c:1861
+#: sequencer.c:3632 builtin/commit.c:981 builtin/log.c:366 builtin/log.c:920
+#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:372
+#: builtin/shortlog.c:192
 msgid "revision walk setup failed"
 msgstr "неуспешно настройване на обхождането на версиите"
 
-#: blame.c:1816
+#: blame.c:1814
 msgid ""
 "--reverse --first-parent together require range along first-parent chain"
 msgstr ""
 "Едновременното задаване на опциите „--reverse“ и „--first-parent“ изисква "
 "указването на диапазон по веригата на първите наследници"
 
-#: blame.c:1827
+#: blame.c:1825
 #, c-format
 msgid "no such path %s in %s"
 msgstr "няма път на име „%s“ в „%s“"
 
-#: blame.c:1838
+#: blame.c:1836
 #, c-format
 msgid "cannot read blob %s for path %s"
-msgstr "обектът BLOB „%s“ в пътя %s не може да бъде прочетен"
+msgstr "обектът-BLOB „%s“ в пътя %s не може да бъде прочетен"
 
-#: branch.c:53
+#: branch.c:54
 #, c-format
 msgid ""
 "\n"
@@ -1145,88 +1156,88 @@ msgstr ""
 "информацията за следения клон чрез:\n"
 "git branch --set-upstream-to=%s%s%s"
 
-#: branch.c:67
+#: branch.c:68
 #, c-format
 msgid "Not setting branch %s as its own upstream."
 msgstr ""
 "Клонът „%s“ не може да служи като източник за собствената си синхронизация."
 
-#: branch.c:93
+#: branch.c:94
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s' by rebasing."
 msgstr ""
 "Клонът „%s“ ще следи отдалечения клон „%s“ от хранилището „%s“ чрез "
 "пребазиране."
 
-#: branch.c:94
+#: branch.c:95
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s'."
 msgstr "Клонът „%s“ ще следи отдалечения клон „%s“ от хранилището „%s“."
 
-#: branch.c:98
+#: branch.c:99
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s' by rebasing."
 msgstr "Клонът „%s“ ще следи локалния клон „%s“ чрез пребазиране."
 
-#: branch.c:99
+#: branch.c:100
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s'."
 msgstr "Клонът „%s“ ще следи локалния клон „%s“."
 
-#: branch.c:104
+#: branch.c:105
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s' by rebasing."
 msgstr "Клонът „%s“ ще следи отдалечения указател „%s“ чрез пребазиране."
 
-#: branch.c:105
+#: branch.c:106
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s'."
 msgstr "Клонът „%s“ ще следи отдалечения указател „%s“."
 
-#: branch.c:109
+#: branch.c:110
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s' by rebasing."
 msgstr "Клонът „%s“ ще следи локалния указател „%s“ чрез пребазиране."
 
-#: branch.c:110
+#: branch.c:111
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s'."
 msgstr "Клонът „%s“ ще следи локалния указател „%s“."
 
-#: branch.c:119
+#: branch.c:120
 msgid "Unable to write upstream branch configuration"
 msgstr "Настройките за следения клон не могат да бъдат записани"
 
-#: branch.c:156
+#: branch.c:157
 #, c-format
 msgid "Not tracking: ambiguous information for ref %s"
 msgstr "Няма следене: информацията за указателя „%s“ не е еднозначна"
 
-#: branch.c:189
+#: branch.c:190
 #, c-format
 msgid "'%s' is not a valid branch name."
 msgstr "„%s“ не е позволено име за клон."
 
-#: branch.c:208
+#: branch.c:209
 #, c-format
 msgid "A branch named '%s' already exists."
 msgstr "Вече съществува клон с име „%s“."
 
-#: branch.c:213
+#: branch.c:214
 msgid "Cannot force update the current branch."
 msgstr "Текущият клон не може да бъде принудително обновен."
 
-#: branch.c:233
+#: branch.c:234
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr "Зададените настройки за следенето са грешни — началото „%s“ не е клон."
 
-#: branch.c:235
+#: branch.c:236
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr "заявеният отдалечен клон „%s“ не съществува"
 
-#: branch.c:237
+#: branch.c:238
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -1245,27 +1256,27 @@ msgstr ""
 "може да използвате „git push -u“, за да настроите към кой клон да се "
 "изтласква."
 
-#: branch.c:280
+#: branch.c:281
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "Неправилно име на обект: „%s“"
 
-#: branch.c:300
+#: branch.c:301
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "Името на обект не е еднозначно: „%s“"
 
-#: branch.c:305
+#: branch.c:306
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "Неправилно място за начало на клон: „%s“"
 
-#: branch.c:359
+#: branch.c:360
 #, c-format
 msgid "'%s' is already checked out at '%s'"
 msgstr "„%s“ вече е изтеглен в „%s“"
 
-#: branch.c:382
+#: branch.c:383
 #, c-format
 msgid "HEAD of working tree %s is not updated"
 msgstr "Указателят „HEAD“ на работното дърво „%s“ не е обновен"
@@ -1280,7 +1291,7 @@ msgstr "Файлът „%s“ не изглежда да е пратка на gi
 msgid "unrecognized header: %s%s (%d)"
 msgstr "непозната заглавна част: %s%s (%d)"
 
-#: bundle.c:88 sequencer.c:1879 sequencer.c:2337 builtin/commit.c:750
+#: bundle.c:88 sequencer.c:2081 sequencer.c:2558 builtin/commit.c:755
 #, c-format
 msgid "could not open '%s'"
 msgstr "„%s“ не може да се отвори"
@@ -1325,7 +1336,7 @@ msgid "ref '%s' is excluded by the rev-list options"
 msgstr ""
 "указателят „%s“ не е бил включен поради опциите зададени на „git rev-list“"
 
-#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:296
+#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:303
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "непознат аргумент: %s"
@@ -1348,18 +1359,42 @@ msgstr "Командата „git index-pack“ не завърши успешн
 msgid "invalid color value: %.*s"
 msgstr "неправилна стойност за цвят: %.*s"
 
-#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465
-#: builtin/am.c:1436 builtin/am.c:2072
+#: commit.c:43 sequencer.c:2364 builtin/am.c:421 builtin/am.c:465
+#: builtin/am.c:1436 builtin/am.c:2072 builtin/replace.c:376
+#: builtin/replace.c:448
 #, c-format
 msgid "could not parse %s"
 msgstr "„%s“ не може да се анализира"
 
-#: commit.c:43
+#: commit.c:45
 #, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s не е подаване!"
 
-#: commit.c:1506
+#: commit.c:182
+msgid ""
+"Support for <GIT_DIR>/info/grafts is deprecated\n"
+"and will be removed in a future Git version.\n"
+"\n"
+"Please use \"git replace --convert-graft-file\"\n"
+"to convert the grafts into replace refs.\n"
+"\n"
+"Turn this message off by running\n"
+"\"git config advice.graftFileDeprecated false\""
+msgstr ""
+"Поддръжката на „<GIT_DIR>/info/grafts“ е остаряла.\n"
+"В бъдеща версия на Git ще бъде премахната.\n"
+"\n"
+"Може да преобразувате присадките в заместващи\n"
+"указатели с командата:\n"
+"\n"
+"    git replace --convert-graft-file\n"
+"\n"
+"За да изключите това съобщение, ползвайте командата:\n"
+"\n"
+"    git config advice.graftFileDeprecated false"
+
+#: commit.c:1540
 msgid ""
 "Warning: commit message did not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
@@ -1369,174 +1404,188 @@ msgstr ""
 "Може да поправите подаването заедно със съобщението или може да\n"
 "зададете ползваното кодиране в настройката „i18n.commitencoding“.\n"
 
+#: commit-graph.c:669
+#, c-format
+msgid "the commit graph format cannot write %d commits"
+msgstr "форматът на гра̀фа с подаванията не може да запише %d подавания"
+
+#: commit-graph.c:696
+msgid "too many commits to write graph"
+msgstr "прекалено много подавания за записване на гра̀фа"
+
+#: commit-graph.c:707 builtin/init-db.c:516 builtin/init-db.c:521
+#, c-format
+msgid "cannot mkdir %s"
+msgstr "директорията „%s“ не може да бъде създадена"
+
 #: compat/obstack.c:405 compat/obstack.c:407
 msgid "memory exhausted"
 msgstr "паметта свърши"
 
-#: config.c:186
+#: config.c:187
 msgid "relative config include conditionals must come from files"
 msgstr "относителните условни изрази за вмъкване трябва да идват от файлове"
 
-#: config.c:720
+#: config.c:788
 #, c-format
 msgid "bad config line %d in blob %s"
 msgstr "неправилен ред за настройки %d в BLOB „%s“"
 
-#: config.c:724
+#: config.c:792
 #, c-format
 msgid "bad config line %d in file %s"
 msgstr "неправилен ред за настройки %d във файла „%s“"
 
-#: config.c:728
+#: config.c:796
 #, c-format
 msgid "bad config line %d in standard input"
 msgstr "неправилен ред за настройки %d на стандартния вход"
 
-#: config.c:732
+#: config.c:800
 #, c-format
 msgid "bad config line %d in submodule-blob %s"
 msgstr "неправилен ред за настройки %d в BLOB за подмодул „%s“"
 
-#: config.c:736
+#: config.c:804
 #, c-format
 msgid "bad config line %d in command line %s"
 msgstr "неправилен ред за настройки %d на командния ред „%s“"
 
-#: config.c:740
+#: config.c:808
 #, c-format
 msgid "bad config line %d in %s"
 msgstr "неправилен ред за настройки %d в „%s“"
 
-#: config.c:868
+#: config.c:936
 msgid "out of range"
 msgstr "извън диапазона"
 
-#: config.c:868
+#: config.c:936
 msgid "invalid unit"
 msgstr "неправилна мерна единица"
 
-#: config.c:874
+#: config.c:942
 #, c-format
 msgid "bad numeric config value '%s' for '%s': %s"
 msgstr "неправилна числова стойност „%s“ за „%s“: %s"
 
-#: config.c:879
+#: config.c:947
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
 msgstr "неправилна числова стойност „%s“ за „%s“ в BLOB „%s“: %s"
 
-#: config.c:882
+#: config.c:950
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in file %s: %s"
 msgstr "неправилна числова стойност „%s“ за „%s“ във файла „%s“: %s"
 
-#: config.c:885
+#: config.c:953
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in standard input: %s"
 msgstr "неправилна числова стойност „%s“ за „%s“ на стандартния вход: %s"
 
-#: config.c:888
+#: config.c:956
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
 msgstr "неправилна числова стойност „%s“ за „%s“ в BLOB от подмодул „%s“: %s"
 
-#: config.c:891
+#: config.c:959
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
 msgstr "неправилна числова стойност „%s“ за „%s“ на командния ред „%s“: %s"
 
-#: config.c:894
+#: config.c:962
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in %s: %s"
 msgstr "неправилна числова стойност „%s“ за „%s“ в %s: %s"
 
-#: config.c:989
+#: config.c:1057
 #, c-format
 msgid "failed to expand user dir in: '%s'"
 msgstr "домашната папка на потребителя не може да бъде открита: „%s“"
 
-#: config.c:998
+#: config.c:1066
 #, c-format
 msgid "'%s' for '%s' is not a valid timestamp"
 msgstr "„%s“ не е правилна стойност за време за „%s“"
 
-#: config.c:1094 config.c:1105
+#: config.c:1171 config.c:1182
 #, c-format
 msgid "bad zlib compression level %d"
 msgstr "неправилно ниво на компресиране: %d"
 
-#: config.c:1225
+#: config.c:1307
 #, c-format
 msgid "invalid mode for object creation: %s"
 msgstr "неправилен режим за създаването на обекти: %s"
 
-#: config.c:1386
+#: config.c:1473
 #, c-format
 msgid "bad pack compression level %d"
 msgstr "неправилно ниво на компресиране при пакетиране: %d"
 
-#: config.c:1582
+#: config.c:1681
 msgid "unable to parse command-line config"
 msgstr "неправилни настройки от командния ред"
 
-#: config.c:1914
+#: config.c:2013
 msgid "unknown error occurred while reading the configuration files"
 msgstr "неочаквана грешка при изчитането на конфигурационните файлове"
 
-#: config.c:2101
+#: config.c:2200
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "Неправилен %s: „%s“"
 
-#: config.c:2144
+#: config.c:2243
 #, c-format
 msgid "unknown core.untrackedCache value '%s'; using 'keep' default value"
 msgstr ""
 "непозната стойност „%s“ за настройката „core.untrackedCache“.  Ще се ползва "
 "стандартната стойност „keep“ (запазване)"
 
-#: config.c:2170
+#: config.c:2269
 #, c-format
 msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100"
 msgstr ""
 "стойността на „splitIndex.maxPercentChange“ трябва да е между 1 и 100, а не "
 "%d"
 
-#: config.c:2195
+#: config.c:2294
 #, c-format
 msgid "unable to parse '%s' from command-line config"
 msgstr "неразпозната стойност „%s“ от командния ред"
 
-#: config.c:2197
+#: config.c:2296
 #, c-format
 msgid "bad config variable '%s' in file '%s' at line %d"
 msgstr "неправилна настройка „%s“ във файла „%s“ на ред №%d"
 
-#: config.c:2256
+#: config.c:2402
 #, c-format
 msgid "%s has multiple values"
 msgstr "зададени са няколко стойности за „%s“"
 
-#: config.c:2599 config.c:2816
+#: config.c:2766 config.c:3019
 #, c-format
 msgid "fstat on %s failed"
 msgstr "неуспешно изпълнение на „fstat“ върху „%s“"
 
-#: config.c:2706
+#: config.c:2905
 #, c-format
 msgid "could not set '%s' to '%s'"
 msgstr "„%s“ не може да се зададе да е „%s“"
 
-#: config.c:2708 builtin/remote.c:776
+#: config.c:2907 builtin/remote.c:779
 #, c-format
 msgid "could not unset '%s'"
 msgstr "„%s“ не може да се премахне"
 
-#: connect.c:52
+#: connect.c:61
 msgid "The remote end hung up upon initial contact"
 msgstr "Отдалеченото хранилище прекъсна връзката веднага след отварянето ѝ"
 
-#: connect.c:54
+#: connect.c:63
 msgid ""
 "Could not read from remote repository.\n"
 "\n"
@@ -1548,7 +1597,7 @@ msgstr ""
 "Проверете дали то съществува и дали имате права\n"
 "за достъп."
 
-#: connected.c:66 builtin/fsck.c:198 builtin/prune.c:144
+#: connected.c:66 builtin/fsck.c:201 builtin/prune.c:145
 msgid "Checking connectivity"
 msgstr "Проверка на връзката"
 
@@ -1564,12 +1613,12 @@ msgstr "неуспешен запис на списъка с версиите"
 msgid "failed to close rev-list's stdin"
 msgstr "стандартният вход на списъка с версиите не може да бъде затворен"
 
-#: convert.c:205
+#: convert.c:206
 #, c-format
 msgid "CRLF would be replaced by LF in %s."
 msgstr "Всяка последователност от знаци „CRLF“ ще бъдe заменена с „LF“ в „%s“."
 
-#: convert.c:207
+#: convert.c:208
 #, c-format
 msgid ""
 "CRLF will be replaced by LF in %s.\n"
@@ -1579,13 +1628,13 @@ msgstr ""
 "Файлът ще остане с първоначалните знаци за край на ред в работната ви "
 "директория."
 
-#: convert.c:215
+#: convert.c:216
 #, c-format
 msgid "LF would be replaced by CRLF in %s"
 msgstr ""
 "Всеки знак „LF“ ще бъдe заменен с последователността от знаци „CRLF“ в „%s“."
 
-#: convert.c:217
+#: convert.c:218
 #, c-format
 msgid ""
 "LF will be replaced by CRLF in %s.\n"
@@ -1596,6 +1645,53 @@ msgstr ""
 "Файлът ще остане с първоначалните знаци за край на ред в работната ви "
 "директория."
 
+#: convert.c:279
+#, c-format
+msgid "BOM is prohibited in '%s' if encoded as %s"
+msgstr ""
+"„%s“ не трябва да съдържа маркер за поредността на байтовете (BOM) при "
+"кодиране „%s“"
+
+#: convert.c:286
+#, c-format
+msgid ""
+"The file '%s' contains a byte order mark (BOM). Please use UTF-%s as working-"
+"tree-encoding."
+msgstr ""
+"Файлът „%s“ съдържа маркер за поредността на байтовете (BOM).  Използвайте "
+"„UTF-%s“ като кодиране за работното дърво."
+
+#: convert.c:304
+#, c-format
+msgid "BOM is required in '%s' if encoded as %s"
+msgstr ""
+"„%s“ трябва да съдържа маркер за поредността на байтовете (BOM) при кодиране "
+"„%s“"
+
+#: convert.c:306
+#, 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 ""
+"Във файла „%s“ липсва маркер за поредността на байтовете (BOM).  За кодиране "
+"на работното дърво използвайте UTF-%sBE или UTF-%sLE (в зависимост от "
+"поредността на байтовете)."
+
+#: convert.c:424
+#, c-format
+msgid "failed to encode '%s' from %s to %s"
+msgstr "неуспешно прекодиране на „%s“ от „%s“ към „%s“"
+
+#: convert.c:467
+#, c-format
+msgid "encoding '%s' from %s to %s and back is not the same"
+msgstr "Прекодирането на „%s“ от „%s“ към „%s“ и обратно променя файла"
+
+#: convert.c:1225
+msgid "true/false are no valid working-tree-encodings"
+msgstr "„true“/„false“ не може да са кодирания на работното дърво"
+
 #: date.c:116
 msgid "in the future"
 msgstr "в бъдещето"
@@ -1713,27 +1809,27 @@ msgstr ""
 "Грешки в настройката „diff.dirstat“:\n"
 "%s"
 
-#: diff.c:3822
+#: diff.c:3823
 #, c-format
 msgid "external diff died, stopping at %s"
 msgstr ""
 "външната програма за разлики завърши неуспешно.  Спиране на работата при „%s“"
 
-#: diff.c:4146
+#: diff.c:4153
 msgid "--name-only, --name-status, --check and -s are mutually exclusive"
 msgstr ""
 "Опциите „--name-only“, „--name-status“, „--check“ и „-s“ са несъвместими "
 "една с друга"
 
-#: diff.c:4149
+#: diff.c:4156
 msgid "-G, -S and --find-object are mutually exclusive"
 msgstr "Опциите „-G“, „-S“ и „--find-object“ са несъвместими една с друга"
 
-#: diff.c:4237
+#: diff.c:4244
 msgid "--follow requires exactly one pathspec"
 msgstr "Опцията „--follow“ изисква точно един път"
 
-#: diff.c:4403
+#: diff.c:4410
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -1742,48 +1838,48 @@ msgstr ""
 "Неразпознат параметър към опцията „--dirstat/-X“:\n"
 "%s"
 
-#: diff.c:4417
+#: diff.c:4424
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "Неразпознат параметър към опцията „--submodule“: „%s“"
 
-#: diff.c:5493
+#: diff.c:5500
 msgid "inexact rename detection was skipped due to too many files."
 msgstr ""
 "търсенето на преименувания на обекти съчетани с промени се прескача поради "
 "многото файлове."
 
-#: diff.c:5496
+#: diff.c:5503
 msgid "only found copies from modified paths due to too many files."
 msgstr ""
 "установени са точните копия на променените пътища поради многото файлове."
 
-#: diff.c:5499
+#: diff.c:5506
 #, c-format
 msgid ""
 "you may want to set your %s variable to at least %d and retry the command."
 msgstr "задайте променливата „%s“ да е поне %d и отново изпълнете командата."
 
-#: dir.c:1866
+#: dir.c:1867
 #, c-format
 msgid "could not open directory '%s'"
 msgstr "директорията „%s“ не може да бъде отворена"
 
-#: dir.c:2108
+#: dir.c:2109
 msgid "failed to get kernel name and information"
 msgstr "името и версията на ядрото не бяха получени"
 
-#: dir.c:2232
+#: dir.c:2233
 msgid "Untracked cache is disabled on this system or location."
 msgstr ""
 "Кеша за неследените файлове е изключен на тази система или местоположение."
 
-#: dir.c:3024 dir.c:3029
+#: dir.c:3075 dir.c:3080
 #, c-format
 msgid "could not create directories for %s"
 msgstr "директориите за „%s“ не може да бъдат създадени"
 
-#: dir.c:3054
+#: dir.c:3109
 #, c-format
 msgid "could not migrate git directory from '%s' to '%s'"
 msgstr "директорията на git не може да се мигрира от „%s“ до „%s“"
@@ -1806,202 +1902,206 @@ msgstr "неуспешно изпълнение на „stat“ върху фа
 msgid "Remote with no URL"
 msgstr "Липсва адрес за отдалеченото хранилище"
 
-#: fetch-pack.c:253
+#: fetch-pack.c:254
 msgid "git fetch-pack: expected shallow list"
 msgstr "git fetch-pack: очаква се плитък списък"
 
-#: fetch-pack.c:265
+#: fetch-pack.c:266
 msgid "git fetch-pack: expected ACK/NAK, got a flush packet"
 msgstr ""
 "git fetch-pack: очакваше се „ACK“/„NAK“, а бе получен изчистващ пакет „flush“"
 
-#: fetch-pack.c:284 builtin/archive.c:63
+#: fetch-pack.c:285 builtin/archive.c:63
 #, c-format
 msgid "remote error: %s"
 msgstr "отдалечена грешка: %s"
 
-#: fetch-pack.c:285
+#: fetch-pack.c:286
 #, c-format
 msgid "git fetch-pack: expected ACK/NAK, got '%s'"
 msgstr "git fetch-pack: очакваше се „ACK“/„NAK“, а бе получен „%s“"
 
-#: fetch-pack.c:337
+#: fetch-pack.c:338
 msgid "--stateless-rpc requires multi_ack_detailed"
 msgstr "опцията „--stateless-rpc“ изисква  „multi_ack_detailed“"
 
-#: fetch-pack.c:428
+#: fetch-pack.c:429 fetch-pack.c:1310
 #, c-format
 msgid "invalid shallow line: %s"
 msgstr "неправилен плитък ред: „%s“"
 
-#: fetch-pack.c:434
+#: fetch-pack.c:435 fetch-pack.c:1316
 #, c-format
 msgid "invalid unshallow line: %s"
 msgstr "неправилен неплитък ред: „%s“"
 
-#: fetch-pack.c:436
+#: fetch-pack.c:437 fetch-pack.c:1318
 #, c-format
 msgid "object not found: %s"
 msgstr "обектът „%s“ липсва"
 
-#: fetch-pack.c:439
+#: fetch-pack.c:440 fetch-pack.c:1321
 #, c-format
 msgid "error in object: %s"
 msgstr "грешка в обекта: „%s“"
 
-#: fetch-pack.c:441
+#: fetch-pack.c:442 fetch-pack.c:1323
 #, c-format
 msgid "no shallow found: %s"
 msgstr "не е открит плитък обект: %s"
 
-#: fetch-pack.c:444
+#: fetch-pack.c:445 fetch-pack.c:1326
 #, c-format
 msgid "expected shallow/unshallow, got %s"
 msgstr "очаква се плитък или не обект, а бе получено: %s"
 
-#: fetch-pack.c:485
+#: fetch-pack.c:486
 #, c-format
 msgid "got %s %d %s"
 msgstr "получено бе %s %d %s"
 
-#: fetch-pack.c:499
+#: fetch-pack.c:500
 #, c-format
 msgid "invalid commit %s"
 msgstr "неправилно подаване: „%s“"
 
-#: fetch-pack.c:532
+#: fetch-pack.c:533
 msgid "giving up"
 msgstr "преустановяване"
 
-#: fetch-pack.c:542 progress.c:229
+#: fetch-pack.c:543 progress.c:229
 msgid "done"
 msgstr "действието завърши"
 
-#: fetch-pack.c:554
+#: fetch-pack.c:555
 #, c-format
 msgid "got %s (%d) %s"
 msgstr "получено бе %s (%d) %s"
 
-#: fetch-pack.c:600
+#: fetch-pack.c:601
 #, c-format
 msgid "Marking %s as complete"
 msgstr "Отбелязване на „%s“ като пълно"
 
-#: fetch-pack.c:788
+#: fetch-pack.c:828
 #, c-format
 msgid "already have %s (%s)"
 msgstr "вече има „%s“ (%s)"
 
-#: fetch-pack.c:829
+#: fetch-pack.c:869
 msgid "fetch-pack: unable to fork off sideband demultiplexer"
 msgstr "fetch-pack: не може да се създаде процес за демултиплексора"
 
-#: fetch-pack.c:837
+#: fetch-pack.c:877
 msgid "protocol error: bad pack header"
 msgstr "протоколна грешка: неправилна заглавна част на пакет"
 
-#: fetch-pack.c:895
+#: fetch-pack.c:944
 #, c-format
 msgid "fetch-pack: unable to fork off %s"
 msgstr "fetch-pack: не може да се създаде процес за „%s“"
 
-#: fetch-pack.c:911
+#: fetch-pack.c:960
 #, c-format
 msgid "%s failed"
 msgstr "неуспешно изпълнение на „%s“"
 
-#: fetch-pack.c:913
+#: fetch-pack.c:962
 msgid "error in sideband demultiplexer"
 msgstr "грешка в демултиплексора"
 
-#: fetch-pack.c:940
+#: fetch-pack.c:989
 msgid "Server does not support shallow clients"
 msgstr "Сървърът не поддържа плитки клиенти"
 
-#: fetch-pack.c:944
+#: fetch-pack.c:993
 msgid "Server supports multi_ack_detailed"
 msgstr "Сървърът поддържа „multi_ack_detailed“"
 
-#: fetch-pack.c:947
+#: fetch-pack.c:996
 msgid "Server supports no-done"
 msgstr "Сървърът поддържа „no-done“"
 
-#: fetch-pack.c:953
+#: fetch-pack.c:1002
 msgid "Server supports multi_ack"
 msgstr "Сървърът поддържа „multi_ack“"
 
-#: fetch-pack.c:957
+#: fetch-pack.c:1006
 msgid "Server supports side-band-64k"
 msgstr "Сървърът поддържа „side-band-64k“"
 
-#: fetch-pack.c:961
+#: fetch-pack.c:1010
 msgid "Server supports side-band"
 msgstr "Сървърът поддържа „side-band“"
 
-#: fetch-pack.c:965
+#: fetch-pack.c:1014
 msgid "Server supports allow-tip-sha1-in-want"
 msgstr "Сървърът поддържа „allow-tip-sha1-in-want“"
 
-#: fetch-pack.c:969
+#: fetch-pack.c:1018
 msgid "Server supports allow-reachable-sha1-in-want"
 msgstr "Сървърът поддържа „allow-reachable-sha1-in-want“"
 
-#: fetch-pack.c:979
+#: fetch-pack.c:1028
 msgid "Server supports ofs-delta"
 msgstr "Сървърът поддържа „ofs-delta“"
 
-#: fetch-pack.c:985
+#: fetch-pack.c:1034 fetch-pack.c:1204
 msgid "Server supports filter"
 msgstr "Сървърът поддържа филтри"
 
-#: fetch-pack.c:993
+#: fetch-pack.c:1042
 #, c-format
 msgid "Server version is %.*s"
 msgstr "Версията на сървъра е: %.*s"
 
-#: fetch-pack.c:999
+#: fetch-pack.c:1048
 msgid "Server does not support --shallow-since"
 msgstr "Сървърът не поддържа опцията „--shallow-since“"
 
-#: fetch-pack.c:1003
+#: fetch-pack.c:1052
 msgid "Server does not support --shallow-exclude"
 msgstr "Сървърът не поддържа опцията „--shallow-exclude“"
 
-#: fetch-pack.c:1005
+#: fetch-pack.c:1054
 msgid "Server does not support --deepen"
 msgstr "Сървърът не поддържа опцията „--deepen“"
 
-#: fetch-pack.c:1016
+#: fetch-pack.c:1065
 msgid "no common commits"
 msgstr "няма общи подавания"
 
-#: fetch-pack.c:1028
+#: fetch-pack.c:1077 fetch-pack.c:1414
 msgid "git fetch-pack: fetch failed."
 msgstr "git fetch-pack: неуспешно доставяне."
 
-#: fetch-pack.c:1190
+#: fetch-pack.c:1199
+msgid "Server does not support shallow requests"
+msgstr "Сървърът не поддържа плитки заявки"
+
+#: fetch-pack.c:1584
 msgid "no matching remote head"
 msgstr "не може да бъде открит подходящ връх от отдалеченото хранилище"
 
-#: fetch-pack.c:1212
+#: fetch-pack.c:1610
 #, c-format
 msgid "no such remote ref %s"
 msgstr "такъв отдалечен указател няма: %s"
 
-#: fetch-pack.c:1215
+#: fetch-pack.c:1613
 #, c-format
 msgid "Server does not allow request for unadvertised object %s"
 msgstr "Сървърът не позволява заявка за необявен „%s“"
 
-#: gpg-interface.c:181
+#: gpg-interface.c:185
 msgid "gpg failed to sign the data"
 msgstr "Програмата „gpg“ не подписа данните."
 
-#: gpg-interface.c:211
+#: gpg-interface.c:210
 msgid "could not create temporary file"
 msgstr "не може да се създаде временен файл"
 
-#: gpg-interface.c:214
+#: gpg-interface.c:213
 #, c-format
 msgid "failed writing detached signature to '%s'"
 msgstr "Програмата не успя да запише самостоятелния подпис в „%s“"
@@ -2011,36 +2111,97 @@ msgstr "Програмата не успя да запише самостоят
 msgid "ignore invalid color '%.*s' in log.graphColors"
 msgstr "прескачане на неправилния цвят „%.*s“ в „log.graphColors“"
 
-#: grep.c:2022
+#: grep.c:2020
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "„%s“: файлът сочен от „%s“ не може да бъде прочетен"
 
-#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81
+#: grep.c:2037 setup.c:164 builtin/clone.c:409 builtin/diff.c:81
 #: builtin/rm.c:134
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "не може да бъде получена информация чрез „stat“ за „%s“"
 
-#: grep.c:2050
+#: grep.c:2048
 #, c-format
 msgid "'%s': short read"
 msgstr "„%s“: изчитането върна по-малко байтове от очакваното"
 
-#: help.c:179
+#: help.c:23
+msgid "start a working area (see also: git help tutorial)"
+msgstr "създаване на работно дърво (погледнете: „git help tutorial“)"
+
+#: help.c:24
+msgid "work on the current change (see also: git help everyday)"
+msgstr "работа по текущата промяна (погледнете: „git help everyday“)"
+
+#: help.c:25
+msgid "examine the history and state (see also: git help revisions)"
+msgstr "преглед на историята и състоянието (погледнете: „git help revisions“)"
+
+#: help.c:26
+msgid "grow, mark and tweak your common history"
+msgstr "увеличаване, отбелязване и промяна на общата история"
+
+#: help.c:27
+msgid "collaborate (see also: git help workflows)"
+msgstr "съвместна работа (погледнете: „git help workflows“)"
+
+#: help.c:31
+msgid "Main Porcelain Commands"
+msgstr "Основни команди от потребителско ниво"
+
+#: help.c:32
+msgid "Ancillary Commands / Manipulators"
+msgstr "Помощни команди/Променящи"
+
+#: help.c:33
+msgid "Ancillary Commands / Interrogators"
+msgstr "Помощни команди/Запитващи"
+
+#: help.c:34
+msgid "Interacting with Others"
+msgstr "Съвместна работа с други хора"
+
+#: help.c:35
+msgid "Low-level Commands / Manipulators"
+msgstr "Команди от ниско ниво/Променящи"
+
+#: help.c:36
+msgid "Low-level Commands / Interrogators"
+msgstr "Команди от ниско ниво/Запитващи"
+
+#: help.c:37
+msgid "Low-level Commands / Synching Repositories"
+msgstr "Команди от ниско ниво/Синхронизация на хранилища"
+
+#: help.c:38
+msgid "Low-level Commands / Internal Helpers"
+msgstr "Команди от ниско ниво/Допълнителни инструменти"
+
+#: help.c:293
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "налични команди на git от „%s“"
 
-#: help.c:186
+#: help.c:300
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "команди на git от други директории от „$PATH“"
 
-#: help.c:217
+#: help.c:309
 msgid "These are common Git commands used in various situations:"
 msgstr "Това са най-често използваните команди на Git:"
 
-#: help.c:281
+#: help.c:358 git.c:90
+#, c-format
+msgid "unsupported command listing type '%s'"
+msgstr "неподдържан списък от команди „%s“"
+
+#: help.c:405
+msgid "The common Git guides are:"
+msgstr "Популярните въведения в Git са:"
+
+#: help.c:467
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -2049,36 +2210,36 @@ msgstr ""
 "Изглежда, че „%s“ е команда на git, но тя не може да\n"
 "бъде изпълнена.  Вероятно пакетът „git-%s“ е повреден."
 
-#: help.c:336
+#: help.c:526
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Странно, изглежда, че на системата ви няма нито една команда на git."
 
-#: help.c:358
+#: help.c:548
 #, c-format
 msgid "WARNING: You called a Git command named '%s', which does not exist."
 msgstr ""
 "ПРЕДУПРЕЖДЕНИЕ: Пробвахте да изпълните команда на Git на име „%s“, а такава "
 "не съществува."
 
-#: help.c:363
+#: help.c:553
 #, c-format
 msgid "Continuing under the assumption that you meant '%s'."
 msgstr ""
 "Изпълнението автоматично продължава, като се счита, че имате предвид „%s“."
 
-#: help.c:368
+#: help.c:558
 #, c-format
 msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
 msgstr ""
 "Изпълнението автоматично ще продължи след %0.1f сек., като се счита, че "
 "имате предвид „%s“."
 
-#: help.c:376
+#: help.c:566
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git: „%s“ не е команда на git.  Погледнете изхода от „git --help“."
 
-#: help.c:380
+#: help.c:570
 msgid ""
 "\n"
 "The most similar command is"
@@ -2092,16 +2253,16 @@ msgstr[1] ""
 "\n"
 "Най-близките команди са"
 
-#: help.c:395
+#: help.c:585
 msgid "git version [<options>]"
 msgstr "git version [ОПЦИЯ…]"
 
-#: help.c:462
+#: help.c:652
 #, c-format
 msgid "%s: %s - %s"
 msgstr "%s: %s — %s"
 
-#: help.c:466
+#: help.c:656
 msgid ""
 "\n"
 "Did you mean this?"
@@ -2172,7 +2333,7 @@ msgstr "не може да се ползва празно име като иде
 msgid "name consists only of disallowed characters: %s"
 msgstr "името съдържа само непозволени знаци: „%s“"
 
-#: ident.c:416 builtin/commit.c:582
+#: ident.c:416 builtin/commit.c:587
 #, c-format
 msgid "invalid date format: %s"
 msgstr "неправилен формат на дата: %s"
@@ -2209,84 +2370,169 @@ msgstr ""
 msgid "Unable to create '%s.lock': %s"
 msgstr "Файлът-ключалка „%s.lock“ не може да бъде създаден: %s"
 
-#: merge.c:74
+#: merge.c:71
 msgid "failed to read the cache"
 msgstr "кешът не може да бъде прочетен"
 
-#: merge.c:134 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
-#: builtin/checkout.c:599 builtin/clone.c:759
+#: merge.c:136 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
+#: builtin/checkout.c:606 builtin/clone.c:761
 msgid "unable to write new index file"
 msgstr "неуспешно записване на новия индекс"
 
-#: merge-recursive.c:235
+#: merge-recursive.c:298
 msgid "(bad commit)\n"
 msgstr "(лошо подаване)\n"
 
-#: merge-recursive.c:257 merge-recursive.c:265
+#: merge-recursive.c:320
+#, c-format
+msgid "add_cacheinfo failed for path '%s'; merge aborting."
+msgstr ""
+"неуспешно изпълнение на „add_cacheinfo“ за пътя „%s“.  Сливането е "
+"преустановено."
+
+#: merge-recursive.c:328
 #, c-format
-msgid "addinfo_cache failed for path '%s'"
-msgstr "неуспешно изпълнение на „addinfo_cache“ за пътя „%s“"
+msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
+msgstr ""
+"неуспешно изпълнение на „add_cacheinfo“ за обновяването на пътя „%s“.  "
+"Сливането е преустановено."
 
-#: merge-recursive.c:329
+#: merge-recursive.c:410
 msgid "error building trees"
 msgstr "грешка при изграждане на дърветата"
 
-#: merge-recursive.c:771
+#: merge-recursive.c:881
 #, c-format
 msgid "failed to create path '%s'%s"
 msgstr "грешка при създаването на пътя „%s“%s"
 
-#: merge-recursive.c:782
+#: merge-recursive.c:892
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr "Изтриване на „%s“, за да се освободи място за поддиректория\n"
 
-#: merge-recursive.c:796 merge-recursive.c:815
+#: merge-recursive.c:906 merge-recursive.c:925
 msgid ": perhaps a D/F conflict?"
 msgstr ": възможно е да има конфликт директория/файл."
 
-#: merge-recursive.c:805
+#: merge-recursive.c:915
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
 msgstr ""
 "преустановяване на действието, за да не се изтрие неследеният файл „%s“"
 
-#: merge-recursive.c:847 builtin/cat-file.c:37
+#: merge-recursive.c:957 builtin/cat-file.c:37
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr "обектът „%s“ (%s) не може да бъде прочетен"
 
-#: merge-recursive.c:849
+#: merge-recursive.c:959
 #, c-format
 msgid "blob expected for %s '%s'"
 msgstr "обектът „%s“ (%s) се очакваше да е BLOB, а не е"
 
-#: merge-recursive.c:873
+#: merge-recursive.c:983
 #, c-format
 msgid "failed to open '%s': %s"
 msgstr "„%s“ не може да се отвори: %s"
 
-#: merge-recursive.c:884
+#: merge-recursive.c:994
 #, c-format
 msgid "failed to symlink '%s': %s"
 msgstr "неуспешно създаване на символната връзка „%s“: %s"
 
-#: merge-recursive.c:889
+#: merge-recursive.c:999
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
 msgstr ""
 "не е ясно какво да се прави с обекта „%2$s“ (%3$s) с права за достъп „%1$06o“"
 
-#: merge-recursive.c:1029
+#: merge-recursive.c:1186
+#, c-format
+msgid "Failed to merge submodule %s (not checked out)"
+msgstr "Неуспешно сливане на подмодула „%s“ (не е изтеглен)"
+
+#: merge-recursive.c:1193
+#, c-format
+msgid "Failed to merge submodule %s (commits not present)"
+msgstr "Неуспешно сливане на подмодула „%s“ (няма подавания)"
+
+#: merge-recursive.c:1200
+#, c-format
+msgid "Failed to merge submodule %s (commits don't follow merge-base)"
+msgstr ""
+"Подмодулът „%s“ не може да бъде слят (базата за сливане не предшества "
+"подаванията)"
+
+#: merge-recursive.c:1208 merge-recursive.c:1220
+#, c-format
+msgid "Fast-forwarding submodule %s to the following commit:"
+msgstr "Превъртане на подмодула „%s“ до следното подаване:"
+
+#: merge-recursive.c:1211 merge-recursive.c:1223
+#, c-format
+msgid "Fast-forwarding submodule %s"
+msgstr "Превъртане на подмодула „%s“"
+
+#: merge-recursive.c:1245
+#, c-format
+msgid "Failed to merge submodule %s (merge following commits not found)"
+msgstr ""
+"Неуспешно сливане на подмодула „%s“ (липсва сливането, което се предшества "
+"от подаванията)"
+
+#: merge-recursive.c:1249
+#, c-format
+msgid "Failed to merge submodule %s (not fast-forward)"
+msgstr "Неуспешно сливане на подмодула „%s“ (не е превъртане)"
+
+#: merge-recursive.c:1250
+msgid "Found a possible merge resolution for the submodule:\n"
+msgstr ""
+"Открито е сливане, което може да решава проблема със сливането на "
+"подмодула:\n"
+
+#: merge-recursive.c:1253
+#, 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"
+"\n"
+"    git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"Това приема предложеното.\n"
+
+#: merge-recursive.c:1262
+#, c-format
+msgid "Failed to merge submodule %s (multiple merges found)"
+msgstr "Неуспешно сливане на подмодула „%s“ (открити са множество сливания)"
+
+#: merge-recursive.c:1321
 msgid "Failed to execute internal merge"
 msgstr "Неуспешно вътрешно сливане"
 
-#: merge-recursive.c:1034
+#: merge-recursive.c:1326
 #, c-format
 msgid "Unable to add %s to database"
 msgstr "„%s“ не може да се добави в базата с данни"
 
-#: merge-recursive.c:1146
+#: merge-recursive.c:1358
+#, c-format
+msgid "Auto-merging %s"
+msgstr "Автоматично сливане на „%s“"
+
+#: merge-recursive.c:1423
+#, c-format
+msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
+msgstr "Грешка: за да не се изтрие неследеният файл „%s“, се записва в „%s“."
+
+#: merge-recursive.c:1475
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2295,7 +2541,7 @@ msgstr ""
 "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ в %s.  Версия %s на „%s“ "
 "е оставена в дървото."
 
-#: merge-recursive.c:1151
+#: merge-recursive.c:1480
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2304,7 +2550,7 @@ msgstr ""
 "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ е преименуван на „%s“ в "
 "%s.  Версия %s на „%s“ е оставена в дървото."
 
-#: merge-recursive.c:1158
+#: merge-recursive.c:1487
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2313,7 +2559,7 @@ msgstr ""
 "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ в %s.  Версия %s на „%s“ "
 "е оставена в дървото: %s."
 
-#: merge-recursive.c:1163
+#: merge-recursive.c:1492
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2322,20 +2568,33 @@ msgstr ""
 "КОНФЛИКТ (%s/изтриване): „%s“ е изтрит в %s, а „%s“ е преименуван на „%s“ в "
 "%s.  Версия %s на „%s“ е оставена в дървото: %s."
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "rename"
 msgstr "преименуване"
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "renamed"
 msgstr "преименуван"
 
-#: merge-recursive.c:1254
+#: merge-recursive.c:1580 merge-recursive.c:1736 merge-recursive.c:2368
+#: merge-recursive.c:3086
+#, c-format
+msgid "Refusing to lose dirty file at %s"
+msgstr "Преустановяване на действието, за да не се изгуби промененият „%s“"
+
+#: merge-recursive.c:1594
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr "„%s“ е директория в „%s“, затова се добавя като „%s“"
 
-#: merge-recursive.c:1279
+#: merge-recursive.c:1599
+#, c-format
+msgid "Refusing to lose untracked file at %s; adding as %s instead"
+msgstr ""
+"Преустановяване на действието, за да не се изгуби неследеният файл „%s“.  "
+"Вместо него се добавя „%s“"
+
+#: merge-recursive.c:1625
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
@@ -2344,145 +2603,194 @@ msgstr ""
 "КОНФЛИКТ (преименуване/преименуване): „%s“ е преименуван на „%s“ в клон "
 "„%s“, а „%s“ е преименуван на „%s“ в „%s“/%s."
 
-#: merge-recursive.c:1284
+#: merge-recursive.c:1630
 msgid " (left unresolved)"
 msgstr " (некоригиран конфликт)"
 
-#: merge-recursive.c:1346
+#: merge-recursive.c:1694
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
 "КОНФЛИКТ (преименуване/преименуване): „%s“ е преименуван на „%s“ в клон "
 "„%s“, а „%s“ е преименуван на „%s“ в „%s“"
 
-#: merge-recursive.c:1379
+#: merge-recursive.c:1733
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr "Преименуване на „%s“ на „%s“, а „%s“ на „%s“"
 
-#: merge-recursive.c:1582
+#: merge-recursive.c:1745
+#, c-format
+msgid "Refusing to lose untracked file at %s, even though it's in the way."
+msgstr ""
+"Отказ да се загуби неследеният файл „%s“, защото е на място, където пречи."
+
+#: merge-recursive.c:1951
+#, c-format
+msgid ""
+"CONFLICT (directory rename split): Unclear where to place %s because "
+"directory %s was renamed to multiple other directories, with no destination "
+"getting a majority of the files."
+msgstr ""
+"КОНФЛИКТ (раздвояване при преименуване на директория): Не е ясно къде да се "
+"постави „%s“, защото няколко нови директории поделят съдържанието на "
+"директория „%s“, като никоя не съдържа мнозинство от файловете ѝ."
+
+#: merge-recursive.c:1983
+#, c-format
+msgid ""
+"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 ""
+"КОНФЛИКТ (косвено преименуване на директория): следният файл или директория "
+"„%s“ не позволяват косвеното преименуване на следния път/ища: %s."
+
+#: merge-recursive.c:1993
+#, 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 ""
+"КОНФЛИКТ (косвено преименуване на директория): повече от един път "
+"съответства на „%s“.  Косвено преименуване на директория води до поставянето "
+"на тези пътища там: %s."
+
+#: merge-recursive.c:2085
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-"
+">%s in %s"
+msgstr ""
+"КОНФЛИКТ (преименуване/преименуване): „%s“ е преименуван на „%s“ в клон "
+"„%s“, а „%s“ е преименуван на „%s“ в „%s“"
+
+#: merge-recursive.c:2330
+#, c-format
+msgid ""
+"WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
+"renamed."
+msgstr ""
+"ПРЕДУПРЕЖДЕНИЕ: прескачане на преименуването на „%s“ на „%s“ в „%s“, защото "
+"„%s“ също е с променено име."
+
+#: merge-recursive.c:2736
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
 msgstr ""
 "КОНФЛИКТ (преименуване/добавяне): „%s“ е преименуван на „%s“ в клон „%s“, а "
 "„%s“ е добавен в „%s“"
 
-#: merge-recursive.c:1597
+#: merge-recursive.c:2751
 #, c-format
 msgid "Adding merged %s"
 msgstr "Добавяне на слетия „%s“"
 
-#: merge-recursive.c:1604 merge-recursive.c:1834
+#: merge-recursive.c:2758 merge-recursive.c:3089
 #, c-format
 msgid "Adding as %s instead"
 msgstr "Добавяне като „%s“"
 
-#: merge-recursive.c:1661
+#: merge-recursive.c:2914
 #, c-format
 msgid "cannot read object %s"
 msgstr "обектът „%s“ не може да се прочете"
 
-#: merge-recursive.c:1664
+#: merge-recursive.c:2917
 #, c-format
 msgid "object %s is not a blob"
 msgstr "обектът „%s“ не е BLOB"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modify"
 msgstr "промяна"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modified"
 msgstr "променен"
 
-#: merge-recursive.c:1743
+#: merge-recursive.c:2997
 msgid "content"
 msgstr "съдържание"
 
-#: merge-recursive.c:1750
+#: merge-recursive.c:3004
 msgid "add/add"
 msgstr "добавяне/добавяне"
 
-#: merge-recursive.c:1786
+#: merge-recursive.c:3046
 #, c-format
 msgid "Skipped %s (merged same as existing)"
 msgstr "Прескачане на „%s“ (слетият резултат е идентичен със сегашния)"
 
-#: merge-recursive.c:1800
-#, c-format
-msgid "Auto-merging %s"
-msgstr "Автоматично сливане на „%s“"
-
-#: merge-recursive.c:1804 git-submodule.sh:879
+#: merge-recursive.c:3055 git-submodule.sh:895
 msgid "submodule"
 msgstr "ПОДМОДУЛ"
 
-#: merge-recursive.c:1805
+#: merge-recursive.c:3056
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
 msgstr "КОНФЛИКТ (%s): Конфликт при сливане на „%s“"
 
-#: merge-recursive.c:1899
+#: merge-recursive.c:3178
 #, c-format
 msgid "Removing %s"
 msgstr "Изтриване на „%s“"
 
-#: merge-recursive.c:1925
+#: merge-recursive.c:3204
 msgid "file/directory"
 msgstr "файл/директория"
 
-#: merge-recursive.c:1931
+#: merge-recursive.c:3210
 msgid "directory/file"
 msgstr "директория/файл"
 
-#: merge-recursive.c:1938
+#: merge-recursive.c:3217
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
 msgstr ""
 "КОНФЛИКТ (%s): Съществува директория на име „%s“ в „%s“.  Добавяне на „%s“ "
 "като „%s“"
 
-#: merge-recursive.c:1947
+#: merge-recursive.c:3226
 #, c-format
 msgid "Adding %s"
 msgstr "Добавяне на „%s“"
 
-#: merge-recursive.c:1987
+#: merge-recursive.c:3267
 #, c-format
 msgid "Dirty index: cannot merge (dirty: %s)"
 msgstr ""
 "Индексът не е чист: кръпките не могат да бъдат приложени (замърсени са: %s)"
 
-#: merge-recursive.c:1991
+#: merge-recursive.c:3271
 msgid "Already up to date!"
 msgstr "Вече е обновено!"
 
-#: merge-recursive.c:2000
+#: merge-recursive.c:3280
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr "неуспешно сливане на дърветата „%s“ и „%s“"
 
-#: merge-recursive.c:2097
+#: merge-recursive.c:3379
 msgid "Merging:"
 msgstr "Сливане:"
 
-#: merge-recursive.c:2110
+#: merge-recursive.c:3392
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] "открит е %u общ предшественик:"
 msgstr[1] "открити са %u общи предшественици:"
 
-#: merge-recursive.c:2149
+#: merge-recursive.c:3431
 msgid "merge returned no commit"
 msgstr "сливането не върна подаване"
 
-#: merge-recursive.c:2212
+#: merge-recursive.c:3495
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr "Неуспешен анализ на обекта „%s“"
 
-#: merge-recursive.c:2228 builtin/merge.c:657 builtin/merge.c:816
+#: merge-recursive.c:3511 builtin/merge.c:659 builtin/merge.c:816
 msgid "Unable to write index."
 msgstr "Индексът не може да бъде прочетен"
 
@@ -2534,35 +2842,35 @@ msgstr ""
 msgid "Bad %s value: '%s'"
 msgstr "Зададена е лоша стойност на променливата „%s“: „%s“"
 
-#: object.c:239
+#: object.c:242
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "обектът „%s“ не може да бъде анализиран"
 
-#: packfile.c:561
+#: packfile.c:563
 msgid "offset before end of packfile (broken .idx?)"
 msgstr ""
 "отместване преди края на пакетния файл (възможно е индексът да е повреден)"
 
-#: packfile.c:1694
+#: packfile.c:1742
 #, c-format
 msgid "offset before start of pack index for %s (corrupt index?)"
 msgstr ""
 "отместване преди началото на индекса на пакетния файл „%s“ (възможно е "
 "индексът да е повреден)"
 
-#: packfile.c:1698
+#: packfile.c:1746
 #, c-format
 msgid "offset beyond end of pack index for %s (truncated index?)"
 msgstr ""
 "отместване преди края на индекса на пакетния файл „%s“ (възможно е индексът "
 "да е отрязан)"
 
-#: parse-options.c:619
+#: parse-options.c:621
 msgid "..."
 msgstr "…"
 
-#: parse-options.c:638
+#: parse-options.c:640
 #, c-format
 msgid "usage: %s"
 msgstr "употреба: %s"
@@ -2570,26 +2878,31 @@ msgstr "употреба: %s"
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation.
 #.
-#: parse-options.c:644
+#: parse-options.c:646
 #, c-format
 msgid "   or: %s"
 msgstr "     или: %s"
 
-#: parse-options.c:647
+#: parse-options.c:649
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:686
+#: parse-options.c:688
 msgid "-NUM"
 msgstr "-ЧИСЛО"
 
-#: parse-options-cb.c:108
+#: parse-options-cb.c:44
+#, c-format
+msgid "malformed expiration date '%s'"
+msgstr "неправилна дата на срок: „%s“"
+
+#: parse-options-cb.c:112
 #, c-format
 msgid "malformed object name '%s'"
 msgstr "неправилно име на обект „%s“"
 
-#: path.c:891
+#: path.c:892
 #, c-format
 msgid "Could not make %s writable by group"
 msgstr "Не могат да се дадат права за запис в директорията „%s“ на групата"
@@ -2672,7 +2985,7 @@ msgstr "пътят „%s“ е след символна връзка"
 msgid "unable to parse --pretty format"
 msgstr "аргументът към опцията „--pretty“ не може да се анализира"
 
-#: read-cache.c:1473
+#: read-cache.c:1500
 #, c-format
 msgid ""
 "index.version set, but the value is invalid.\n"
@@ -2681,7 +2994,7 @@ msgstr ""
 "Зададена е неправилна стойност на настройката „index.version“.\n"
 "Ще се ползва версия %i"
 
-#: read-cache.c:1483
+#: read-cache.c:1510
 #, c-format
 msgid ""
 "GIT_INDEX_VERSION set, but the value is invalid.\n"
@@ -2691,52 +3004,53 @@ msgstr ""
 "„GIT_INDEX_VERSION“.\n"
 "Ще се ползва версия %i"
 
-#: read-cache.c:2375 sequencer.c:3248 wrapper.c:658 builtin/merge.c:1049
+#: read-cache.c:2404 sequencer.c:4338 wrapper.c:658 builtin/merge.c:1048
 #, c-format
 msgid "could not close '%s'"
 msgstr "„%s“ не може да се затвори"
 
-#: read-cache.c:2448 sequencer.c:1900 sequencer.c:2627
+#: read-cache.c:2477 sequencer.c:2102 sequencer.c:3234
 #, c-format
 msgid "could not stat '%s'"
 msgstr "неуспешно изпълнение на „stat“ върху „%s“"
 
-#: read-cache.c:2461
+#: read-cache.c:2490
 #, c-format
 msgid "unable to open git dir: %s"
 msgstr "не може да се отвори директорията на git: %s"
 
-#: read-cache.c:2473
+#: read-cache.c:2502
 #, c-format
 msgid "unable to unlink: %s"
 msgstr "неуспешно изтриване на „%s“"
 
-#: refs.c:706
+#: refs.c:732 sequencer.c:4334 sequencer.c:4393 wrapper.c:225 wrapper.c:395
+#: builtin/am.c:779
 #, c-format
-msgid "Could not open '%s' for writing"
+msgid "could not open '%s' for writing"
 msgstr "„%s“ не може да бъде отворен за запис"
 
-#: refs.c:1850
+#: refs.c:1880
 msgid "ref updates forbidden inside quarantine environment"
 msgstr "обновяванията на указатели са забранени в среди под карантина"
 
-#: refs/files-backend.c:1189
+#: refs/files-backend.c:1191
 #, c-format
 msgid "could not remove reference %s"
 msgstr "Указателят „%s“ не може да бъде изтрит"
 
-#: refs/files-backend.c:1203 refs/packed-backend.c:1528
-#: refs/packed-backend.c:1538
+#: refs/files-backend.c:1205 refs/packed-backend.c:1531
+#: refs/packed-backend.c:1541
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "Указателят „%s“ не може да бъде изтрит: %s"
 
-#: refs/files-backend.c:1206 refs/packed-backend.c:1541
+#: refs/files-backend.c:1208 refs/packed-backend.c:1544
 #, c-format
 msgid "could not delete references: %s"
 msgstr "Указателите не може да бъдат изтрити: %s"
 
-#: ref-filter.c:35 wt-status.c:1842
+#: ref-filter.c:35 wt-status.c:1850
 msgid "gone"
 msgstr "изтрит"
 
@@ -2755,157 +3069,162 @@ msgstr "назад с %d"
 msgid "ahead %d, behind %d"
 msgstr "напред с %d, назад с %d"
 
-#: ref-filter.c:107
+#: ref-filter.c:121
 #, c-format
 msgid "expected format: %%(color:<color>)"
 msgstr "очакван формат: %%(color:ЦВЯТ)"
 
-#: ref-filter.c:109
+#: ref-filter.c:123
 #, c-format
 msgid "unrecognized color: %%(color:%s)"
 msgstr "непознат цвят: %%(color:%s)"
 
-#: ref-filter.c:129
+#: ref-filter.c:145
 #, c-format
 msgid "Integer value expected refname:lstrip=%s"
 msgstr "очаква се цяло число за „refname:lstrip=%s“"
 
-#: ref-filter.c:133
+#: ref-filter.c:149
 #, c-format
 msgid "Integer value expected refname:rstrip=%s"
 msgstr "очаква се цяло число за „refname:rstrip=%s“"
 
-#: ref-filter.c:135
+#: ref-filter.c:151
 #, c-format
 msgid "unrecognized %%(%s) argument: %s"
 msgstr "непознат аргумент за „%%(%s)“: %s"
 
-#: ref-filter.c:184
+#: ref-filter.c:206
 #, c-format
 msgid "%%(body) does not take arguments"
 msgstr "%%(body) не приема аргументи"
 
-#: ref-filter.c:191
+#: ref-filter.c:215
 #, c-format
 msgid "%%(subject) does not take arguments"
 msgstr "%%(subject) не приема аргументи"
 
-#: ref-filter.c:209
+#: ref-filter.c:235
 #, c-format
 msgid "unknown %%(trailers) argument: %s"
 msgstr "непознат аргумент „%%(trailers)“: %s"
 
-#: ref-filter.c:232
+#: ref-filter.c:264
 #, c-format
 msgid "positive value expected contents:lines=%s"
 msgstr "очаква се положителна стойност за „contents:lines=%s“"
 
-#: ref-filter.c:234
+#: ref-filter.c:266
 #, c-format
 msgid "unrecognized %%(contents) argument: %s"
 msgstr "непознат аргумент за %%(contents): %s"
 
-#: ref-filter.c:247
+#: ref-filter.c:281
 #, c-format
 msgid "positive value expected objectname:short=%s"
 msgstr "очаква се положителна стойност за „objectname:short=%s“"
 
-#: ref-filter.c:251
+#: ref-filter.c:285
 #, c-format
 msgid "unrecognized %%(objectname) argument: %s"
 msgstr "непознат аргумент за %%(objectname): %s"
 
-#: ref-filter.c:278
+#: ref-filter.c:315
 #, c-format
 msgid "expected format: %%(align:<width>,<position>)"
 msgstr "очакван формат: %%(align:ШИРОЧИНА,ПОЗИЦИЯ)"
 
-#: ref-filter.c:290
+#: ref-filter.c:327
 #, c-format
 msgid "unrecognized position:%s"
 msgstr "непозната позиция: %s"
 
-#: ref-filter.c:294
+#: ref-filter.c:334
 #, c-format
 msgid "unrecognized width:%s"
 msgstr "непозната широчина: %s"
 
-#: ref-filter.c:300
+#: ref-filter.c:343
 #, c-format
 msgid "unrecognized %%(align) argument: %s"
 msgstr "непознат аргумент за %%(align): %s"
 
-#: ref-filter.c:304
+#: ref-filter.c:351
 #, c-format
 msgid "positive width expected with the %%(align) atom"
 msgstr "очаква се положителна широчина с лексемата „%%(align)“"
 
-#: ref-filter.c:319
+#: ref-filter.c:369
 #, c-format
 msgid "unrecognized %%(if) argument: %s"
 msgstr "непознат аргумент за „%%(if)“: %s"
 
-#: ref-filter.c:409
+#: ref-filter.c:464
 #, c-format
 msgid "malformed field name: %.*s"
 msgstr "неправилно име на обект: „%.*s“"
 
-#: ref-filter.c:435
+#: ref-filter.c:491
 #, c-format
 msgid "unknown field name: %.*s"
 msgstr "непознато име на обект: „%.*s“"
 
-#: ref-filter.c:547
+#: ref-filter.c:608
 #, c-format
 msgid "format: %%(if) atom used without a %%(then) atom"
 msgstr "формат: лексемата %%(if) е използвана без съответната ѝ %%(then)"
 
-#: ref-filter.c:607
+#: ref-filter.c:671
 #, c-format
 msgid "format: %%(then) atom used without an %%(if) atom"
 msgstr "формат: лексемата %%(then) е използвана без съответната ѝ %%(if)"
 
-#: ref-filter.c:609
+#: ref-filter.c:673
 #, c-format
 msgid "format: %%(then) atom used more than once"
 msgstr "формат: лексемата %%(then) е използвана повече от един път"
 
-#: ref-filter.c:611
+#: ref-filter.c:675
 #, c-format
 msgid "format: %%(then) atom used after %%(else)"
 msgstr "формат: лексемата %%(then) е използвана след %%(else)"
 
-#: ref-filter.c:637
+#: ref-filter.c:703
 #, c-format
 msgid "format: %%(else) atom used without an %%(if) atom"
 msgstr "формат: лексемата %%(else) е използвана без съответната ѝ %%(if)"
 
-#: ref-filter.c:639
+#: ref-filter.c:705
 #, c-format
 msgid "format: %%(else) atom used without a %%(then) atom"
 msgstr "формат: лексемата %%(else) е използвана без съответната ѝ %%(then)"
 
-#: ref-filter.c:641
+#: ref-filter.c:707
 #, c-format
 msgid "format: %%(else) atom used more than once"
 msgstr "формат: лексемата %%(else) е използвана повече от един път"
 
-#: ref-filter.c:654
+#: ref-filter.c:722
 #, c-format
 msgid "format: %%(end) atom used without corresponding atom"
 msgstr "формат: лексемата %%(end) е използвана без съответната ѝ"
 
-#: ref-filter.c:709
+#: ref-filter.c:779
 #, c-format
 msgid "malformed format string %s"
 msgstr "неправилен форматиращ низ „%s“"
 
-#: ref-filter.c:1313
+#: ref-filter.c:1387
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(извън клон, пребазиране на „%s“)"
 
-#: ref-filter.c:1316
+#: ref-filter.c:1390
+#, c-format
+msgid "(no branch, rebasing detached HEAD %s)"
+msgstr "(извън клон, пребазиране на несвързан указател „HEAD“ при „%s“)"
+
+#: ref-filter.c:1393
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(извън клон, двоично търсене от „%s“)"
@@ -2913,7 +3232,7 @@ msgstr "(извън клон, двоично търсене от „%s“)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached at " in wt-status.c
 #.
-#: ref-filter.c:1324
+#: ref-filter.c:1401
 #, c-format
 msgid "(HEAD detached at %s)"
 msgstr "(Указателят „HEAD“ не е свързан и е при „%s“)"
@@ -2921,149 +3240,149 @@ msgstr "(Указателят „HEAD“ не е свързан и е при „
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached from " in wt-status.c
 #.
-#: ref-filter.c:1331
+#: ref-filter.c:1408
 #, c-format
 msgid "(HEAD detached from %s)"
 msgstr "Указателят „HEAD“ не е свързан и е отделѐн от „%s“"
 
-#: ref-filter.c:1335
+#: ref-filter.c:1412
 msgid "(no branch)"
 msgstr "(извън клон)"
 
-#: ref-filter.c:1364
+#: ref-filter.c:1442
 #, c-format
 msgid "missing object %s for %s"
 msgstr "обектът „%s“ липсва за „%s“"
 
-#: ref-filter.c:1367
+#: ref-filter.c:1445
 #, c-format
 msgid "parse_object_buffer failed on %s for %s"
 msgstr "неуспешно анализиране чрез „parse_object_buffer“ на „%s“ за „%s“"
 
-#: ref-filter.c:1819
+#: ref-filter.c:1902
 #, c-format
 msgid "malformed object at '%s'"
 msgstr "обект със сгрешен формат при „%s“"
 
-#: ref-filter.c:1886
+#: ref-filter.c:1984
 #, c-format
 msgid "ignoring ref with broken name %s"
 msgstr "игнориране на указателя с грешно име „%s“"
 
-#: ref-filter.c:1891
+#: ref-filter.c:1989
 #, c-format
 msgid "ignoring broken ref %s"
 msgstr "игнориране на повредения указател „%s“"
 
-#: ref-filter.c:2152
+#: ref-filter.c:2261
 #, c-format
 msgid "format: %%(end) atom missing"
 msgstr "грешка във форма̀та: липсва лексемата %%(end)"
 
-#: ref-filter.c:2246
+#: ref-filter.c:2365
 #, c-format
 msgid "malformed object name %s"
 msgstr "неправилно име на обект „%s“"
 
-#: remote.c:795
+#: remote.c:605
 #, c-format
 msgid "Cannot fetch both %s and %s to %s"
 msgstr "Невъзможно е да се доставят едновременно и „%s“, и „%s“ към „%s“"
 
-#: remote.c:799
+#: remote.c:609
 #, c-format
 msgid "%s usually tracks %s, not %s"
 msgstr "„%s“ обикновено следи „%s“, а не „%s“"
 
-#: remote.c:803
+#: remote.c:613
 #, c-format
 msgid "%s tracks both %s and %s"
 msgstr "„%s“ следи както „%s“, така и „%s“"
 
-#: remote.c:811
+#: remote.c:621
 msgid "Internal error"
 msgstr "Вътрешна грешка"
 
-#: remote.c:1726 remote.c:1828
+#: remote.c:1534 remote.c:1635
 msgid "HEAD does not point to a branch"
 msgstr "Указателят „HEAD“ не сочи към клон"
 
-#: remote.c:1735
+#: remote.c:1543
 #, c-format
 msgid "no such branch: '%s'"
 msgstr "няма клон на име „%s“"
 
-#: remote.c:1738
+#: remote.c:1546
 #, c-format
 msgid "no upstream configured for branch '%s'"
 msgstr "не е зададен клон-източник за клона „%s“"
 
-#: remote.c:1744
+#: remote.c:1552
 #, c-format
 msgid "upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "клонът-източник „%s“ не е съхранен като следящ клон"
 
-#: remote.c:1759
+#: remote.c:1567
 #, c-format
 msgid "push destination '%s' on remote '%s' has no local tracking branch"
 msgstr ""
 "липсва локален следящ клон за местоположението за изтласкване „%s“ в "
 "хранилището „%s“"
 
-#: remote.c:1771
+#: remote.c:1579
 #, c-format
 msgid "branch '%s' has no remote for pushing"
 msgstr "няма информация клонът „%s“ да следи някой друг"
 
-#: remote.c:1782
+#: remote.c:1589
 #, c-format
 msgid "push refspecs for '%s' do not include '%s'"
 msgstr "указателят за изтласкване на „%s“ не включва „%s“"
 
-#: remote.c:1795
+#: remote.c:1602
 msgid "push has no destination (push.default is 'nothing')"
 msgstr "указателят за изтласкване не включва цел („push.default“ е „nothing“)"
 
-#: remote.c:1817
+#: remote.c:1624
 msgid "cannot resolve 'simple' push to a single destination"
 msgstr "простото (simple) изтласкване не съответства на една цел"
 
-#: remote.c:2132
+#: remote.c:1939
 #, c-format
 msgid "Your branch is based on '%s', but the upstream is gone.\n"
 msgstr "Този клон следи „%s“, но следеният клон е изтрит.\n"
 
-#: remote.c:2136
+#: remote.c:1943
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
 msgstr "  (за да коригирате това, използвайте „git branch --unset-upstream“)\n"
 
-#: remote.c:2139
+#: remote.c:1946
 #, c-format
 msgid "Your branch is up to date with '%s'.\n"
 msgstr "Клонът е актуализиран към „%s“.\n"
 
-#: remote.c:2143
+#: remote.c:1950
 #, c-format
 msgid "Your branch and '%s' refer to different commits.\n"
 msgstr "Клонът ви и „%s“ сочат към различни подавания.\n"
 
-#: remote.c:2146
+#: remote.c:1953
 #, c-format
 msgid "  (use \"%s\" for details)\n"
 msgstr "  (за повече информация ползвайте „%s“)\n"
 
-#: remote.c:2150
+#: remote.c:1957
 #, c-format
 msgid "Your branch is ahead of '%s' by %d commit.\n"
 msgid_plural "Your branch is ahead of '%s' by %d commits.\n"
 msgstr[0] "Клонът ви е с %2$d подаване пред „%1$s“.\n"
 msgstr[1] "Клонът ви е с %2$d подавания пред „%1$s“.\n"
 
-#: remote.c:2156
+#: remote.c:1963
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (публикувайте локалните си промени чрез „git push“)\n"
 
-#: remote.c:2159
+#: remote.c:1966
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -3071,11 +3390,11 @@ msgid_plural ""
 msgstr[0] "Клонът ви е с %2$d подаване зад „%1$s“ и може да бъде превъртян.\n"
 msgstr[1] "Клонът ви е с %2$d подавания зад „%1$s“ и може да бъде превъртян.\n"
 
-#: remote.c:2167
+#: remote.c:1974
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (обновете локалния си клон чрез „git pull“)\n"
 
-#: remote.c:2170
+#: remote.c:1977
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -3090,28 +3409,28 @@ msgstr[1] ""
 "Текущият клон се е отделил от „%s“,\n"
 "двата имат съответно по %d и %d несъвпадащи подавания.\n"
 
-#: remote.c:2180
+#: remote.c:1987
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr "  (слейте отдалечения клон в локалния чрез „git pull“)\n"
 
-#: revision.c:2277
+#: revision.c:2289
 msgid "your current branch appears to be broken"
 msgstr "Текущият клон е повреден"
 
-#: revision.c:2280
+#: revision.c:2292
 #, c-format
 msgid "your current branch '%s' does not have any commits yet"
 msgstr "Текущият клон „%s“ е без подавания "
 
-#: revision.c:2477
+#: revision.c:2489
 msgid "--first-parent is incompatible with --bisect"
 msgstr "опциите „--first-parent“ и „--bisect“ са несъвместими"
 
-#: run-command.c:731
+#: run-command.c:728
 msgid "open /dev/null failed"
 msgstr "неуспешно отваряне на „/dev/null“"
 
-#: run-command.c:1274
+#: run-command.c:1271
 #, c-format
 msgid ""
 "The '%s' hook was ignored because it's not set as executable.\n"
@@ -3162,29 +3481,34 @@ msgstr "получаващата страна не поддържа изтлас
 msgid "the receiving end does not support push options"
 msgstr "отсрещната страна не поддържа опции при изтласкване"
 
-#: sequencer.c:158
+#: sequencer.c:175
 #, c-format
 msgid "invalid commit message cleanup mode '%s'"
 msgstr "несъществуващ режим на изчистване „%s“ на съобщение при подаване"
 
-#: sequencer.c:267
+#: sequencer.c:275
+#, c-format
+msgid "could not delete '%s'"
+msgstr "„%s“ не може да бъде изтрит"
+
+#: sequencer.c:301
 msgid "revert"
 msgstr "отмяна"
 
-#: sequencer.c:269
+#: sequencer.c:303
 msgid "cherry-pick"
 msgstr "отбиране"
 
-#: sequencer.c:271
+#: sequencer.c:305
 msgid "rebase -i"
 msgstr "rebase -i"
 
-#: sequencer.c:273
+#: sequencer.c:307
 #, c-format
 msgid "Unknown action: %d"
 msgstr "Неизвестно действие: %d"
 
-#: sequencer.c:330
+#: sequencer.c:364
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
@@ -3192,7 +3516,7 @@ msgstr ""
 "след коригирането на конфликтите, отбележете съответните\n"
 "пътища с „git add ПЪТ…“ или „git rm ПЪТ…“."
 
-#: sequencer.c:333
+#: sequencer.c:367
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'\n"
@@ -3202,43 +3526,45 @@ msgstr ""
 "пътища с „git add ПЪТ…“ или „git rm ПЪТ…“, след което\n"
 "подайте резултата с командата „git commit'“."
 
-#: sequencer.c:346 sequencer.c:2245
+#: sequencer.c:380 sequencer.c:2468
 #, c-format
 msgid "could not lock '%s'"
 msgstr "„%s“ не може да се заключи"
 
-#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264
-#: sequencer.c:3246 sequencer.c:3310 wrapper.c:656
+#: sequencer.c:382 sequencer.c:2346 sequencer.c:2472 sequencer.c:2486
+#: sequencer.c:2694 sequencer.c:4336 sequencer.c:4399 wrapper.c:656
 #, c-format
 msgid "could not write to '%s'"
 msgstr "в „%s“ не може да се пише"
 
-#: sequencer.c:353
+#: sequencer.c:387
 #, c-format
 msgid "could not write eol to '%s'"
 msgstr "краят на ред не може да се запише в „%s“"
 
-#: sequencer.c:356 sequencer.c:2128 sequencer.c:2252
+#: sequencer.c:392 sequencer.c:2351 sequencer.c:2474 sequencer.c:2488
+#: sequencer.c:2702
 #, c-format
 msgid "failed to finalize '%s'"
 msgstr "„%s“ не може да се завърши"
 
-#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259
-#: builtin/commit.c:722 builtin/merge.c:1047
+#: sequencer.c:415 sequencer.c:804 sequencer.c:1493 sequencer.c:2371
+#: sequencer.c:2684 sequencer.c:2788 builtin/am.c:259 builtin/commit.c:727
+#: builtin/merge.c:1046
 #, c-format
 msgid "could not read '%s'"
 msgstr "файлът „%s“ не може да бъде прочетен"
 
-#: sequencer.c:405
+#: sequencer.c:441
 #, c-format
 msgid "your local changes would be overwritten by %s."
 msgstr "локалните ви промени ще бъдат презаписани при %s."
 
-#: sequencer.c:409
+#: sequencer.c:445
 msgid "commit your changes or stash them to proceed."
 msgstr "подайте или скатайте промените, за да продължите"
 
-#: sequencer.c:438
+#: sequencer.c:474
 #, c-format
 msgid "%s: fast-forward"
 msgstr "%s: превъртане"
@@ -3246,20 +3572,20 @@ msgstr "%s: превъртане"
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase -i".
 #.
-#: sequencer.c:526
+#: sequencer.c:563
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: новият индекс не може да бъде запазен"
 
-#: sequencer.c:542
-msgid "could not resolve HEAD commit"
-msgstr "подаването, сочено от указателя „HEAD“, не може да бъде открито"
-
-#: sequencer.c:562
+#: sequencer.c:579
 msgid "unable to update cache tree"
 msgstr "дървото на кеша не може да бъде обновено"
 
-#: sequencer.c:658
+#: sequencer.c:592
+msgid "could not resolve HEAD commit"
+msgstr "подаването, сочено от указателя „HEAD“, не може да бъде открито"
+
+#: sequencer.c:749
 #, c-format
 msgid ""
 "you have staged changes in your working tree\n"
@@ -3276,7 +3602,7 @@ msgid ""
 "  git rebase --continue\n"
 msgstr ""
 "в това работно дърво има скатани промени.\n"
-"Ако искате да ги слеете с предишното подаване, изпълнете:\n"
+"Ако искате да ги вкарате в предишното подаване, изпълнете:\n"
 "\n"
 "    git commit --amend %s\n"
 "\n"
@@ -3288,13 +3614,17 @@ msgstr ""
 "\n"
 "    git rebase --continue\n"
 
-#: sequencer.c:915
+#: sequencer.c:818
+msgid "writing root commit"
+msgstr "запазване на начално подаване"
+
+#: sequencer.c:1043
 msgid "'prepare-commit-msg' hook failed"
 msgstr ""
 "неуспешно изпълнение на куката при промяна на съобщението при подаване "
 "(prepare-commit-msg)"
 
-#: sequencer.c:922
+#: sequencer.c:1050
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3323,7 +3653,7 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:935
+#: sequencer.c:1063
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3349,339 +3679,325 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:975
+#: sequencer.c:1103
 msgid "couldn't look up newly created commit"
 msgstr "току що създаденото подаване не може да бъде открито"
 
-#: sequencer.c:977
+#: sequencer.c:1105
 msgid "could not parse newly created commit"
 msgstr "току що създаденото подаване не може да бъде анализирано"
 
-#: sequencer.c:1023
+#: sequencer.c:1151
 msgid "unable to resolve HEAD after creating commit"
 msgstr ""
 "състоянието сочено от указателя „HEAD“ не може да бъде открито след "
 "подаването"
 
-#: sequencer.c:1025
+#: sequencer.c:1153
 msgid "detached HEAD"
 msgstr "несвързан връх „HEAD“"
 
-#: sequencer.c:1029
+#: sequencer.c:1157
 msgid " (root-commit)"
 msgstr " (начално подаване)"
 
-#: sequencer.c:1050
+#: sequencer.c:1178
 msgid "could not parse HEAD"
 msgstr "указателят „HEAD“ не може да бъде анализиран"
 
-#: sequencer.c:1052
+#: sequencer.c:1180
 #, c-format
 msgid "HEAD %s is not a commit!"
 msgstr "указателят „HEAD“ „%s“ сочи към нещо, което не е подаване!"
 
-#: sequencer.c:1056 builtin/commit.c:1491
+#: sequencer.c:1184 builtin/commit.c:1528
 msgid "could not parse HEAD commit"
 msgstr "върховото подаване „HEAD“ не може да бъде прочетено"
 
-#: sequencer.c:1107 sequencer.c:1673
+#: sequencer.c:1235 sequencer.c:1832
 msgid "unable to parse commit author"
 msgstr "авторът на подаването не може да бъде анализиран"
 
-#: sequencer.c:1117 builtin/am.c:1630 builtin/merge.c:643
+#: sequencer.c:1245 builtin/am.c:1630 builtin/merge.c:645
 msgid "git write-tree failed to write a tree"
 msgstr "Командата „git write-tree“ не успя да запише обект-дърво"
 
-#: sequencer.c:1134 sequencer.c:1186
+#: sequencer.c:1262 sequencer.c:1317
 #, c-format
 msgid "unable to read commit message from '%s'"
 msgstr "съобщението за подаване не може да бъде прочетено от „%s“"
 
-#: sequencer.c:1154 builtin/am.c:1650 builtin/commit.c:1594 builtin/merge.c:826
-#: builtin/merge.c:851
+#: sequencer.c:1284 builtin/am.c:1650 builtin/commit.c:1631 builtin/merge.c:825
+#: builtin/merge.c:850
 msgid "failed to write commit object"
 msgstr "обектът за подаването не може да бъде записан"
 
-#: sequencer.c:1213
+#: sequencer.c:1344
 #, c-format
 msgid "could not parse commit %s"
 msgstr "подаването „%s“ не може да бъде анализирано"
 
-#: sequencer.c:1218
+#: sequencer.c:1349
 #, c-format
 msgid "could not parse parent commit %s"
 msgstr "родителското подаване „%s“ не може да бъде анализирано"
 
-#: sequencer.c:1347
-#, c-format
-msgid ""
-"unexpected 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"неочакван първи ред на съобщението при смачкване:\n"
-"\n"
-"    %.*s"
-
-#: sequencer.c:1353
-#, c-format
-msgid ""
-"invalid 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"неправилен първи ред на съобщението при смачкване:\n"
-"\n"
-"    %.*s"
-
-#: sequencer.c:1359 sequencer.c:1384
+#: sequencer.c:1500 sequencer.c:1525
 #, c-format
 msgid "This is a combination of %d commits."
 msgstr "Това е обединение от %d подавания"
 
-#: sequencer.c:1368 sequencer.c:3265
+#: sequencer.c:1510 sequencer.c:4355
 msgid "need a HEAD to fixup"
-msgstr "За смачкване ви трябва указател „HEAD“"
+msgstr "За вкарване в предходното подаване ви трябва указател „HEAD“"
 
-#: sequencer.c:1370
+#: sequencer.c:1512 sequencer.c:2729
 msgid "could not read HEAD"
 msgstr "указателят „HEAD“ не може да се прочете"
 
-#: sequencer.c:1372
+#: sequencer.c:1514
 msgid "could not read HEAD's commit message"
 msgstr ""
 "съобщението за подаване към указателя „HEAD“ не може да бъде прочетено: %s"
 
-#: sequencer.c:1378
+#: sequencer.c:1520
 #, c-format
 msgid "cannot write '%s'"
 msgstr "„%s“ не може да се запази"
 
-#: sequencer.c:1387 git-rebase--interactive.sh:452
+#: sequencer.c:1527 git-rebase--interactive.sh:457
 msgid "This is the 1st commit message:"
 msgstr "Това е 1-то съобщение при подаване:"
 
-#: sequencer.c:1395
+#: sequencer.c:1535
 #, c-format
 msgid "could not read commit message of %s"
 msgstr "съобщението за подаване към „%s“ не може да бъде прочетено"
 
-#: sequencer.c:1402
+#: sequencer.c:1542
 #, c-format
 msgid "This is the commit message #%d:"
 msgstr "Това е съобщение при подаване №%d:"
 
-#: sequencer.c:1407
+#: sequencer.c:1548
 #, c-format
 msgid "The commit message #%d will be skipped:"
 msgstr "Съобщение при подаване №%d ще бъде прескочено:"
 
-#: sequencer.c:1412
+#: sequencer.c:1553
 #, c-format
 msgid "unknown command: %d"
 msgstr "непозната команда: %d"
 
-#: sequencer.c:1479
+#: sequencer.c:1631
 msgid "your index file is unmerged."
 msgstr "индексът не е слят."
 
-#: sequencer.c:1498
+#: sequencer.c:1638
+msgid "cannot fixup root commit"
+msgstr "началното подаване не може да се вкара в предходното му"
+
+#: sequencer.c:1657
 #, c-format
 msgid "commit %s is a merge but no -m option was given."
 msgstr "подаването „%s“ е сливане, но не е дадена опцията „-m“"
 
-#: sequencer.c:1506
+#: sequencer.c:1665
 #, c-format
 msgid "commit %s does not have parent %d"
 msgstr "подаването „%s“ няма родител %d"
 
-#: sequencer.c:1510
+#: sequencer.c:1669
 #, c-format
 msgid "mainline was specified but commit %s is not a merge."
 msgstr "указано е базово подаване, но подаването „%s“ не е сливане."
 
-#: sequencer.c:1516
+#: sequencer.c:1675
 #, c-format
 msgid "cannot get commit message for %s"
 msgstr "неуспешно извличане на съобщението за подаване на „%s“"
 
 #. TRANSLATORS: The first %s will be a "todo" command like
 #. "revert" or "pick", the second %s a SHA1.
-#: sequencer.c:1535
+#: sequencer.c:1694
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s: неразпозната стойност за родителското подаване „%s“"
 
-#: sequencer.c:1600 sequencer.c:2397
+#: sequencer.c:1759
 #, c-format
 msgid "could not rename '%s' to '%s'"
 msgstr "„%s“ не може да се преименува на „%s“"
 
-#: sequencer.c:1654
+#: sequencer.c:1813
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "подаването „%s“… не може да бъде отменено: „%s“"
 
-#: sequencer.c:1655
+#: sequencer.c:1814
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "подаването „%s“… не може да бъде приложено: „%s“"
 
-#: sequencer.c:1702
+#: sequencer.c:1864
 msgid "empty commit set passed"
 msgstr "зададено е празно множество от подавания"
 
-#: sequencer.c:1712
+#: sequencer.c:1874
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s: неуспешно изчитане на индекса"
 
-#: sequencer.c:1718
+#: sequencer.c:1881
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr "git %s: неуспешно обновяване на индекса"
 
-#: sequencer.c:1792
+#: sequencer.c:1961
 #, c-format
 msgid "%s does not accept arguments: '%s'"
 msgstr "„%s“ не приема аргументи: „%s“"
 
-#: sequencer.c:1801
+#: sequencer.c:1970
 #, c-format
 msgid "missing arguments for %s"
 msgstr "„%s“ изисква аргументи"
 
-#: sequencer.c:1844
+#: sequencer.c:2029
 #, c-format
 msgid "invalid line %d: %.*s"
 msgstr "неправилен ред %d: %.*s"
 
-#: sequencer.c:1852
+#: sequencer.c:2037
 #, c-format
 msgid "cannot '%s' without a previous commit"
 msgstr "Без предишно подаване не може да се изпълни „%s“"
 
-#: sequencer.c:1883 sequencer.c:3056 sequencer.c:3091
+#: sequencer.c:2085 sequencer.c:4138 sequencer.c:4173
 #, c-format
 msgid "could not read '%s'."
 msgstr "от „%s“ не може да се чете."
 
-#: sequencer.c:1906
+#: sequencer.c:2108
 msgid "please fix this using 'git rebase --edit-todo'."
 msgstr "коригирайте това чрез „git rebase --edit-todo“."
 
-#: sequencer.c:1908
+#: sequencer.c:2110
 #, c-format
 msgid "unusable instruction sheet: '%s'"
 msgstr "неизползваем файл с описание на предстоящите действия: „%s“"
 
-#: sequencer.c:1913
+#: sequencer.c:2115
 msgid "no commits parsed."
 msgstr "никое от подаванията не може да се разпознае."
 
-#: sequencer.c:1924
+#: sequencer.c:2126
 msgid "cannot cherry-pick during a revert."
 msgstr ""
 "по време на отмяна на подаване не може да се извърши отбиране на подаване."
 
-#: sequencer.c:1926
+#: sequencer.c:2128
 msgid "cannot revert during a cherry-pick."
 msgstr "по време на отбиране не може да се извърши отмяна на подаване."
 
-#: sequencer.c:1993
+#: sequencer.c:2195
 #, c-format
 msgid "invalid key: %s"
 msgstr "неправилен ключ: „%s“"
 
-#: sequencer.c:1996
+#: sequencer.c:2198
 #, c-format
 msgid "invalid value for %s: %s"
 msgstr "неправилна стойност за „%s“: „%s“"
 
-#: sequencer.c:2062
+#: sequencer.c:2269
+msgid "unusable squash-onto"
+msgstr "подаването, в което другите да се вкарат, не може да се използва"
+
+#: sequencer.c:2285
 #, c-format
 msgid "malformed options sheet: '%s'"
 msgstr "неправилен файл с опции: „%s“"
 
-#: sequencer.c:2100
+#: sequencer.c:2323
 msgid "a cherry-pick or revert is already in progress"
 msgstr ""
 "в момента вече се извършва отбиране на подавания или пребазиране на клона"
 
-#: sequencer.c:2101
+#: sequencer.c:2324
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "използвайте „git cherry-pick (--continue | --quit | --abort)“"
 
-#: sequencer.c:2104
+#: sequencer.c:2327
 #, c-format
 msgid "could not create sequencer directory '%s'"
 msgstr "директорията за секвенсора „%s“ не може да бъде създадена"
 
-#: sequencer.c:2118
+#: sequencer.c:2341
 msgid "could not lock HEAD"
 msgstr "указателят „HEAD“ не може да се заключи"
 
-#: sequencer.c:2173 sequencer.c:2761
+#: sequencer.c:2396 sequencer.c:3403
 msgid "no cherry-pick or revert in progress"
 msgstr ""
 "в момента не се извършва отбиране на подавания или пребазиране на клона"
 
-#: sequencer.c:2175
+#: sequencer.c:2398
 msgid "cannot resolve HEAD"
 msgstr "Подаването сочено от указателя „HEAD“ не може да бъде открито"
 
-#: sequencer.c:2177 sequencer.c:2212
+#: sequencer.c:2400 sequencer.c:2435
 msgid "cannot abort from a branch yet to be born"
 msgstr ""
 "действието не може да бъде преустановено, когато сте на клон, който тепърва "
 "предстои да бъде създаден"
 
-#: sequencer.c:2198 builtin/grep.c:720
+#: sequencer.c:2421 builtin/grep.c:720
 #, c-format
 msgid "cannot open '%s'"
 msgstr "„%s“ не може да бъде отворен"
 
-#: sequencer.c:2200
+#: sequencer.c:2423
 #, c-format
 msgid "cannot read '%s': %s"
 msgstr "„%s“ не може да бъде прочетен: %s"
 
-#: sequencer.c:2201
+#: sequencer.c:2424
 msgid "unexpected end of file"
 msgstr "неочакван край на файл"
 
-#: sequencer.c:2207
+#: sequencer.c:2430
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr ""
 "запазеният преди започването на отбирането файл за указателя „HEAD“ — „%s“ е "
 "повреден"
 
-#: sequencer.c:2218
+#: sequencer.c:2441
 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
 msgstr ""
 "Изглежда указателят „HEAD“ е променен.  Проверете към какво сочи.\n"
 "Не се правят промени."
 
-#: sequencer.c:2324 sequencer.c:2679
+#: sequencer.c:2545 sequencer.c:3321
 #, c-format
 msgid "could not update %s"
 msgstr "„%s“ не може да се обнови"
 
-#: sequencer.c:2362 sequencer.c:2659
+#: sequencer.c:2583 sequencer.c:3301
 msgid "cannot read HEAD"
 msgstr "указателят „HEAD“ не може да бъде прочетен"
 
-#: sequencer.c:2402 builtin/difftool.c:639
+#: sequencer.c:2618 sequencer.c:2622 builtin/difftool.c:639
 #, c-format
 msgid "could not copy '%s' to '%s'"
 msgstr "„%s“ не може да се копира като „%s“"
 
-#: sequencer.c:2421
+#: sequencer.c:2641
 msgid "could not read index"
 msgstr "индексът не може да бъде прочетен"
 
-#: sequencer.c:2426
+#: sequencer.c:2646
 #, c-format
 msgid ""
 "execution failed: %s\n"
@@ -3696,11 +4012,11 @@ msgstr ""
 "    git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2432
+#: sequencer.c:2652
 msgid "and made changes to the index and/or the working tree\n"
 msgstr "и промени индекса и/или работното дърво\n"
 
-#: sequencer.c:2438
+#: sequencer.c:2658
 #, c-format
 msgid ""
 "execution succeeded: %s\n"
@@ -3717,17 +4033,62 @@ msgstr ""
 "    git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2497
+#: sequencer.c:2771
+msgid "writing fake root commit"
+msgstr "запазване на фалшиво начално подаване"
+
+#: sequencer.c:2776
+msgid "writing squash-onto"
+msgstr "запазване на подаването, в което другите да се вкарат"
+
+#: sequencer.c:2811
+#, c-format
+msgid "failed to find tree of %s"
+msgstr "дървото, сочено от „%s“, не може да бъде открито"
+
+#: sequencer.c:2829
+msgid "could not write index"
+msgstr "индексът не може да бъде записан"
+
+#: sequencer.c:2861
+msgid "cannot merge without a current revision"
+msgstr "без текущо подаване не може да се слива"
+
+#: sequencer.c:2884
+#, c-format
+msgid "could not resolve '%s'"
+msgstr "„%s“ не може да бъде открит"
+
+#: sequencer.c:2906
+#, c-format
+msgid "could not get commit message of '%s'"
+msgstr "съобщението за подаване към „%s“ не може да бъде получено"
+
+#: sequencer.c:2916 sequencer.c:2941
+#, c-format
+msgid "could not write '%s'"
+msgstr "„%s“ не може да се запише"
+
+#: sequencer.c:3005
+#, c-format
+msgid "could not even attempt to merge '%.*s'"
+msgstr "сливането на „%.*s“ не може даже да започне"
+
+#: sequencer.c:3021
+msgid "merge: Unable to write new index file"
+msgstr "сливане: новият индекс не може да бъде запазен"
+
+#: sequencer.c:3088
 #, c-format
 msgid "Applied autostash.\n"
 msgstr "Автоматично скатаното е приложено.\n"
 
-#: sequencer.c:2509
+#: sequencer.c:3100
 #, c-format
 msgid "cannot store %s"
 msgstr "„%s“ не може да бъде запазен"
 
-#: sequencer.c:2512 git-rebase.sh:178
+#: sequencer.c:3103 git-rebase.sh:188
 #, c-format
 msgid ""
 "Applying autostash resulted in conflicts.\n"
@@ -3738,52 +4099,71 @@ msgstr ""
 "надеждно скатани.  Можете да пробвате да ги приложите чрез „git stash pop“\n"
 "или да ги изхвърлите чрез „git stash drop“, когато поискате.\n"
 
-#: sequencer.c:2595
+#: sequencer.c:3134
+#, c-format
+msgid ""
+"Could not execute the todo command\n"
+"\n"
+"    %.*s\n"
+"It has been rescheduled; To edit the command before continuing, please\n"
+"edit the todo list first:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+msgstr ""
+"Следната запланувана команда не може да бъде изпълнена:\n"
+"\n"
+"    %.*s\n"
+"\n"
+"Тя е запланувана за по-късно.  За да редактирате командата преди "
+"изпълнение,\n"
+"редактирайте списъка за изпълнение:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+
+#: sequencer.c:3202
 #, c-format
 msgid "Stopped at %s...  %.*s\n"
 msgstr "Спиране при „%s“…  %.*s\n"
 
-#: sequencer.c:2637
+#: sequencer.c:3264
 #, c-format
 msgid "unknown command %d"
 msgstr "непозната команда %d"
 
-#: sequencer.c:2667
+#: sequencer.c:3309
 msgid "could not read orig-head"
 msgstr "указателят за „orig-head“ не може да се прочете"
 
-#: sequencer.c:2672 sequencer.c:3262
+#: sequencer.c:3314 sequencer.c:4352
 msgid "could not read 'onto'"
 msgstr "указателят за „onto“ не може да се прочете"
 
-#: sequencer.c:2686
+#: sequencer.c:3328
 #, c-format
 msgid "could not update HEAD to %s"
 msgstr "„HEAD“ не може да бъде обновен до „%s“"
 
-#: sequencer.c:2770
+#: sequencer.c:3414
 msgid "cannot rebase: You have unstaged changes."
 msgstr "не може да пребазирате, защото има промени, които не са в индекса."
 
-#: sequencer.c:2775
-msgid "could not remove CHERRY_PICK_HEAD"
-msgstr "указателят „CHERRY_PICK_HEAD“ не може да бъде изтрит"
-
-#: sequencer.c:2784
+#: sequencer.c:3423
 msgid "cannot amend non-existing commit"
 msgstr "несъществуващо подаване не може да се поправи"
 
-#: sequencer.c:2786
+#: sequencer.c:3425
 #, c-format
 msgid "invalid file: '%s'"
 msgstr "неправилен файл: „%s“"
 
-#: sequencer.c:2788
+#: sequencer.c:3427
 #, c-format
 msgid "invalid contents: '%s'"
 msgstr "неправилно съдържание: „%s“"
 
-#: sequencer.c:2791
+#: sequencer.c:3430
 msgid ""
 "\n"
 "You have uncommitted changes in your working tree. Please, commit them\n"
@@ -3793,38 +4173,47 @@ msgstr ""
 "В работното дърво има неподадени промени.  Първо ги подайте, а след това\n"
 "отново изпълнете „git rebase --continue“."
 
-#: sequencer.c:2801
+#: sequencer.c:3455 sequencer.c:3493
+#, c-format
+msgid "could not write file: '%s'"
+msgstr "файлът „%s“ не може да бъде записан"
+
+#: sequencer.c:3508
+msgid "could not remove CHERRY_PICK_HEAD"
+msgstr "указателят „CHERRY_PICK_HEAD“ не може да бъде изтрит"
+
+#: sequencer.c:3515
 msgid "could not commit staged changes."
 msgstr "промените в индекса не могат да бъдат подадени."
 
-#: sequencer.c:2881
+#: sequencer.c:3612
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s: не може да се отбере „%s“"
 
-#: sequencer.c:2885
+#: sequencer.c:3616
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s: неправилна версия"
 
-#: sequencer.c:2918
+#: sequencer.c:3649
 msgid "can't revert as initial commit"
 msgstr "първоначалното подаване не може да бъде отменено"
 
-#: sequencer.c:3023
+#: sequencer.c:4098
 msgid "make_script: unhandled options"
 msgstr "make_script: неподдържани опции"
 
-#: sequencer.c:3026
+#: sequencer.c:4101
 msgid "make_script: error preparing revisions"
 msgstr "make_script: грешка при подготовката на версии"
 
-#: sequencer.c:3060 sequencer.c:3095
+#: sequencer.c:4142 sequencer.c:4177
 #, c-format
 msgid "unusable todo list: '%s'"
 msgstr "неуспешно изтриване на списъка за изпълнение: „%s“"
 
-#: sequencer.c:3146
+#: sequencer.c:4236
 #, c-format
 msgid ""
 "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
@@ -3832,7 +4221,7 @@ msgstr ""
 "Непозната стойност „%s“ за настройката „rebase.missingCommitsCheck“.  "
 "Настройката се прескача."
 
-#: sequencer.c:3212
+#: sequencer.c:4302
 #, c-format
 msgid ""
 "Warning: some commits may have been dropped accidentally.\n"
@@ -3841,7 +4230,7 @@ msgstr ""
 "Предупреждение: някои подавания може да са пропуснати.\n"
 "Пропуснати подавания (новите са най-отгоре):\n"
 
-#: sequencer.c:3219
+#: sequencer.c:4309
 #, c-format
 msgid ""
 "To avoid this message, use \"drop\" to explicitly remove a commit.\n"
@@ -3858,7 +4247,7 @@ msgstr ""
 "предупреждение)\n"
 "или „error“ (считане за грешка).\n"
 
-#: sequencer.c:3231
+#: sequencer.c:4321
 #, c-format
 msgid ""
 "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
@@ -3869,27 +4258,21 @@ msgstr ""
 "continue“ след това.\n"
 "Може и да преустановите пребазирането с командата „git rebase --abort“.\n"
 
-#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395
-#: builtin/am.c:779
-#, c-format
-msgid "could not open '%s' for writing"
-msgstr "„%s“ не може да бъде отворен за запис"
-
-#: sequencer.c:3285
+#: sequencer.c:4375
 #, c-format
 msgid "could not parse commit '%s'"
 msgstr "подаването „%s“ не може да бъде анализирано"
 
-#: sequencer.c:3401
+#: sequencer.c:4490
 msgid "the script was already rearranged."
 msgstr "скриптът вече е преподреден."
 
-#: setup.c:122
+#: setup.c:123
 #, c-format
 msgid "'%s' is outside repository"
 msgstr "„%s“ е извън хранилището"
 
-#: setup.c:171
+#: setup.c:172
 #, c-format
 msgid ""
 "%s: no such path in the working tree.\n"
@@ -3900,7 +4283,7 @@ msgstr ""
 "\n"
 "    git КОМАНДА -- ПЪТ…"
 
-#: setup.c:184
+#: setup.c:185
 #, c-format
 msgid ""
 "ambiguous argument '%s': unknown revision or path not in the working tree.\n"
@@ -3913,12 +4296,12 @@ msgstr ""
 "\n"
 "    git КОМАНДА [ВЕРСИЯ…] -- [ФАЙЛ…]"
 
-#: setup.c:233
+#: setup.c:234
 #, c-format
 msgid "option '%s' must come before non-option arguments"
 msgstr "опцията „%s“ трябва да е преди първия аргумент, който не е опция"
 
-#: setup.c:252
+#: setup.c:253
 #, c-format
 msgid ""
 "ambiguous argument '%s': both revision and filename\n"
@@ -3930,95 +4313,95 @@ msgstr ""
 "\n"
 "    git КОМАНДА [ВЕРСИЯ…] -- [ФАЙЛ…]"
 
-#: setup.c:388
+#: setup.c:389
 msgid "unable to set up work tree using invalid config"
 msgstr ""
 "не може да се зададе текуща работна директория при неправилни настройки"
 
-#: setup.c:395
+#: setup.c:393
 msgid "this operation must be run in a work tree"
 msgstr "тази команда трябва да се изпълни в работно дърво"
 
-#: setup.c:506
+#: setup.c:503
 #, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Очаква се версия на хранилището на git <= %d, а не %d"
 
-#: setup.c:514
+#: setup.c:511
 msgid "unknown repository extensions found:"
 msgstr "открити са непознати разширения в хранилището:"
 
-#: setup.c:533
+#: setup.c:530
 #, c-format
 msgid "error opening '%s'"
 msgstr "„%s“ не може да се отвори"
 
-#: setup.c:535
+#: setup.c:532
 #, c-format
 msgid "too large to be a .git file: '%s'"
 msgstr "прекалено голям файл „.git“: „%s“"
 
-#: setup.c:537
+#: setup.c:534
 #, c-format
 msgid "error reading %s"
 msgstr "грешка при прочитане на „%s“"
 
-#: setup.c:539
+#: setup.c:536
 #, c-format
 msgid "invalid gitfile format: %s"
 msgstr "неправилен формат на gitfile: %s"
 
-#: setup.c:541
+#: setup.c:538
 #, c-format
 msgid "no path in gitfile: %s"
 msgstr "липсва път в gitfile: „%s“"
 
-#: setup.c:543
+#: setup.c:540
 #, c-format
 msgid "not a git repository: %s"
 msgstr "не е хранилище на Git: %s"
 
-#: setup.c:642
+#: setup.c:639
 #, c-format
 msgid "'$%s' too big"
 msgstr "„%s“ е прекалено голям"
 
-#: setup.c:656
+#: setup.c:653
 #, c-format
 msgid "not a git repository: '%s'"
 msgstr "не е хранилище на git: „%s“"
 
-#: setup.c:685 setup.c:687 setup.c:718
+#: setup.c:682 setup.c:684 setup.c:715
 #, c-format
 msgid "cannot chdir to '%s'"
 msgstr "не може да се влезе в директорията „%s“"
 
-#: setup.c:690 setup.c:746 setup.c:756 setup.c:795 setup.c:803 setup.c:818
+#: setup.c:687 setup.c:743 setup.c:753 setup.c:792 setup.c:800 setup.c:815
 msgid "cannot come back to cwd"
 msgstr "процесът не може да се върне към предишната работна директория"
 
-#: setup.c:816
+#: setup.c:813
 #, c-format
 msgid "not a git repository (or any of the parent directories): %s"
 msgstr ""
 "нито тази, нито която и да е от по-горните директории, не е хранилище на "
 "git: %s"
 
-#: setup.c:827
+#: setup.c:824
 #, c-format
 msgid "failed to stat '%*s%s%s'"
 msgstr "не може да бъде получена информация чрез „stat“ за „%*s%s%s“"
 
-#: setup.c:1057
+#: setup.c:1054
 msgid "Unable to read current working directory"
 msgstr "Текущата работна директория не може да бъде прочетена"
 
-#: setup.c:1069 setup.c:1075
+#: setup.c:1066 setup.c:1072
 #, c-format
 msgid "cannot change to '%s'"
 msgstr "не може да се влезе в директорията „%s“"
 
-#: setup.c:1088
+#: setup.c:1085
 #, c-format
 msgid ""
 "not a git repository (or any parent up to mount point %s)\n"
@@ -4029,7 +4412,7 @@ msgstr ""
 "Git работи в рамките на една файлова система, защото променливата на средата "
 "„GIT_DISCOVERY_ACROSS_FILESYSTEM“ не е зададена."
 
-#: setup.c:1172
+#: setup.c:1168
 #, c-format
 msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
@@ -4039,53 +4422,53 @@ msgstr ""
 "(0%.3o).\n"
 "Собственикът на файла трябва да има права за писане и четене."
 
-#: setup.c:1215
+#: setup.c:1211
 msgid "open /dev/null or dup failed"
 msgstr "неуспешно изпълнение на „open“ или „dup“ върху „/dev/null“"
 
-#: setup.c:1230
+#: setup.c:1226
 msgid "fork failed"
 msgstr "неуспешно изпълнение на „fork“"
 
-#: setup.c:1235
+#: setup.c:1231
 msgid "setsid failed"
 msgstr "неуспешно изпълнение на „setsid“"
 
-#: sha1_file.c:592
+#: sha1-file.c:625
 #, c-format
 msgid "path '%s' does not exist"
 msgstr "пътят „%s“ не съществува."
 
-#: sha1_file.c:618
+#: sha1-file.c:651
 #, c-format
 msgid "reference repository '%s' as a linked checkout is not supported yet."
 msgstr "все още не се поддържа еталонно хранилище „%s“ като свързано."
 
-#: sha1_file.c:624
+#: sha1-file.c:657
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "еталонното хранилище „%s“ не е локално"
 
-#: sha1_file.c:630
+#: sha1-file.c:663
 #, c-format
 msgid "reference repository '%s' is shallow"
 msgstr "еталонното хранилище „%s“ е плитко"
 
-#: sha1_file.c:638
+#: sha1-file.c:671
 #, c-format
 msgid "reference repository '%s' is grafted"
 msgstr "еталонното хранилище „%s“ е с присаждане"
 
-#: sha1_name.c:422
+#: sha1-name.c:442
 #, c-format
 msgid "short SHA1 %s is ambiguous"
 msgstr "късият SHA1 „%s“ не е еднозначен"
 
-#: sha1_name.c:433
+#: sha1-name.c:453
 msgid "The candidates are:"
 msgstr "Възможностите са:"
 
-#: sha1_name.c:693
+#: sha1-name.c:695
 msgid ""
 "Git normally never creates a ref that ends with 40 hex characters\n"
 "because it will be ignored when you just specify 40-hex. These refs\n"
@@ -4109,71 +4492,71 @@ msgstr ""
 "спрете това съобщение като изпълните командата:\n"
 "„git config advice.objectNameWarning false“"
 
-#: submodule.c:96 submodule.c:130
+#: submodule.c:97 submodule.c:131
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr ""
 "Неслетите файлове „.gitmodules“ не могат да бъдат променяни.  Първо "
 "коригирайте конфликтите"
 
-#: submodule.c:100 submodule.c:134
+#: submodule.c:101 submodule.c:135
 #, c-format
 msgid "Could not find section in .gitmodules where path=%s"
 msgstr "Във файла „.gitmodules“ липсва раздел за директория „path=%s“"
 
-#: submodule.c:108
+#: submodule.c:109
 #, c-format
 msgid "Could not update .gitmodules entry %s"
 msgstr "Записът „%s“ във файла „.gitmodules“ не може да бъде променен"
 
-#: submodule.c:141
+#: submodule.c:142
 #, c-format
 msgid "Could not remove .gitmodules entry for %s"
 msgstr "Записът „%s“ във файла „.gitmodules“ не може да бъде изтрит"
 
-#: submodule.c:152
+#: submodule.c:153
 msgid "staging updated .gitmodules failed"
 msgstr "неуспешно добавяне на променения файл „.gitmodules“ в индекса"
 
-#: submodule.c:312
+#: submodule.c:315
 #, c-format
 msgid "in unpopulated submodule '%s'"
 msgstr "в неподготвения подмодул „%s“"
 
-#: submodule.c:343
+#: submodule.c:346
 #, c-format
 msgid "Pathspec '%s' is in submodule '%.*s'"
 msgstr "Пътят „%s“ е в подмодула „%.*s“"
 
-#: submodule.c:833
+#: submodule.c:837
 #, c-format
 msgid "submodule entry '%s' (%s) is a %s, not a commit"
 msgstr "записът за подмодула „%s“ (%s) е %s, а не подаване!"
 
-#: submodule.c:1065 builtin/branch.c:648 builtin/submodule--helper.c:1724
+#: submodule.c:1069 builtin/branch.c:651 builtin/submodule--helper.c:1743
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "Не може да се открие към какво сочи указателят „HEAD“"
 
-#: submodule.c:1370
+#: submodule.c:1375
 #, c-format
 msgid "'%s' not recognized as a git repository"
 msgstr "„%s“ не е хранилище на git"
 
-#: submodule.c:1508
+#: submodule.c:1513
 #, c-format
 msgid "could not start 'git status' in submodule '%s'"
 msgstr "командата „git status“ не може да се изпълни в подмодула „%s“"
 
-#: submodule.c:1521
+#: submodule.c:1526
 #, c-format
 msgid "could not run 'git status' in submodule '%s'"
 msgstr "командата „git status“ не може да се изпълни в подмодула „%s“"
 
-#: submodule.c:1614
+#: submodule.c:1619
 #, c-format
 msgid "submodule '%s' has dirty index"
 msgstr "индексът на подмодула „%s“ не е чист"
 
-#: submodule.c:1878
+#: submodule.c:1718
 #, c-format
 msgid ""
 "relocate_gitdir for submodule '%s' with more than one worktree not supported"
@@ -4181,18 +4564,18 @@ msgstr ""
 "не се поддържа „relocate_gitdir“ за подмодула „%s“, който има повече от едно "
 "работно дърво"
 
-#: submodule.c:1890 submodule.c:1946
+#: submodule.c:1730 submodule.c:1786
 #, c-format
 msgid "could not lookup name for submodule '%s'"
 msgstr "името на подмодула „%s“ не може да бъде намерено"
 
-#: submodule.c:1894 builtin/submodule--helper.c:1246
-#: builtin/submodule--helper.c:1256
+#: submodule.c:1734 builtin/submodule--helper.c:1261
+#: builtin/submodule--helper.c:1271
 #, c-format
 msgid "could not create directory '%s'"
 msgstr "Директорията „%s“ не може да бъде създадена"
 
-#: submodule.c:1897
+#: submodule.c:1737
 #, c-format
 msgid ""
 "Migrating git directory of '%s%s' from\n"
@@ -4203,29 +4586,30 @@ msgstr ""
 "„%s“ към\n"
 "„%s“\n"
 
-#: submodule.c:1981
+#: submodule.c:1821
 #, c-format
 msgid "could not recurse into submodule '%s'"
 msgstr "неуспешна обработка на поддиректориите в подмодула „%s“"
 
-#: submodule.c:2025
+#: submodule.c:1865
 msgid "could not start ls-files in .."
 msgstr "„ls-stat“ не може да се стартира в „..“"
 
-#: submodule.c:2045
-msgid "BUG: returned path string doesn't match cwd?"
-msgstr "ГРЕШКА: полученият низ за пътя не съвпада с върнатото от „cwd“"
-
-#: submodule.c:2064
+#: submodule.c:1904
 #, c-format
 msgid "ls-tree returned unexpected return code %d"
 msgstr "„ls-tree“ завърши с неочакван изходен код: %d"
 
-#: submodule-config.c:263
+#: submodule-config.c:230
+#, c-format
+msgid "ignoring suspicious submodule name: %s"
+msgstr "игнориране на подозрително име на подмодул: „%s“"
+
+#: submodule-config.c:294
 msgid "negative values not allowed for submodule.fetchjobs"
 msgstr "настройката „submodule.fetchjobs“ не приема отрицателни стойности"
 
-#: submodule-config.c:436
+#: submodule-config.c:467
 #, c-format
 msgid "invalid value for %s"
 msgstr "Неправилна стойност за „%s“"
@@ -4241,7 +4625,7 @@ msgstr "неуспешно изпълнение на завършващата к
 msgid "unknown value '%s' for key '%s'"
 msgstr "непозната стойност „%s“ за настройката „%s“"
 
-#: trailer.c:539 trailer.c:544 builtin/remote.c:290
+#: trailer.c:539 trailer.c:544 builtin/remote.c:293
 #, c-format
 msgid "more than one %s"
 msgstr "стойността „%s“ се повтаря в настройките"
@@ -4284,17 +4668,21 @@ msgstr "временният файл не може да се отвори"
 msgid "could not rename temporary file to %s"
 msgstr "временният файл не може да се преименува на „%s“"
 
-#: transport.c:63
+#: transport.c:116
 #, c-format
 msgid "Would set upstream of '%s' to '%s' of '%s'\n"
 msgstr "Клонът „%s“ ще следи „%s“ от „%s“\n"
 
-#: transport.c:152
+#: transport.c:208
 #, c-format
 msgid "transport: invalid depth option '%s'"
 msgstr "transport: неправилна опция за дълбочина: %s"
 
-#: transport.c:916
+#: transport.c:584
+msgid "could not parse transport.color.* config"
+msgstr "стойността на настройката „transport.color.*“ не може да се разпознае"
+
+#: transport.c:996
 #, c-format
 msgid ""
 "The following submodule paths contain changes that can\n"
@@ -4303,7 +4691,7 @@ msgstr ""
 "Следните пътища за подмодули съдържат промени,\n"
 "които липсват от всички отдалечени хранилища:\n"
 
-#: transport.c:920
+#: transport.c:1000
 #, c-format
 msgid ""
 "\n"
@@ -4328,11 +4716,11 @@ msgstr ""
 "    git push\n"
 "\n"
 
-#: transport.c:928
+#: transport.c:1008
 msgid "Aborting."
 msgstr "Преустановяване на действието."
 
-#: transport-helper.c:1079
+#: transport-helper.c:1087
 #, c-format
 msgid "Could not read ref %s"
 msgstr "Указателят „%s“ не може да се прочете."
@@ -4349,11 +4737,11 @@ msgstr "неправилни права за достъп в запис в дъ
 msgid "empty filename in tree entry"
 msgstr "празно име на файл в запис в дърво"
 
-#: tree-walk.c:114
+#: tree-walk.c:113
 msgid "too-short tree file"
 msgstr "прекалено кратък файл-дърво"
 
-#: unpack-trees.c:108
+#: unpack-trees.c:111
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4362,7 +4750,7 @@ msgstr ""
 "Изтеглянето ще презапише локалните промени на тези файлове:\n"
 "%%sПодайте или скатайте промените, за да преминете към нов клон."
 
-#: unpack-trees.c:110
+#: unpack-trees.c:113
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4371,7 +4759,7 @@ msgstr ""
 "Изтеглянето ще презапише локалните промени на тези файлове:\n"
 "%%s"
 
-#: unpack-trees.c:113
+#: unpack-trees.c:116
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4380,7 +4768,7 @@ msgstr ""
 "Сливането ще презапише локалните промени на тези файлове:\n"
 "%%sПодайте или скатайте промените, за да слеете."
 
-#: unpack-trees.c:115
+#: unpack-trees.c:118
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4389,7 +4777,7 @@ msgstr ""
 "Сливането ще презапише локалните промени на тези файлове:\n"
 "%%s"
 
-#: unpack-trees.c:118
+#: unpack-trees.c:121
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4398,7 +4786,7 @@ msgstr ""
 "„%s“ ще презапише локалните промени на тези файлове:\n"
 "%%sПодайте или скатайте промените, за да извършите „%s“."
 
-#: unpack-trees.c:120
+#: unpack-trees.c:123
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4407,7 +4795,7 @@ msgstr ""
 "„%s“ ще презапише локалните промени на тези файлове:\n"
 "%%s"
 
-#: unpack-trees.c:125
+#: unpack-trees.c:128
 #, c-format
 msgid ""
 "Updating the following directories would lose untracked files in them:\n"
@@ -4416,7 +4804,7 @@ msgstr ""
 "Обновяването на следните директории ще изтрие неследените файлове в тях:\n"
 "%s"
 
-#: unpack-trees.c:129
+#: unpack-trees.c:132
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4425,7 +4813,7 @@ msgstr ""
 "Изтеглянето ще изтрие тези неследени файлове в работното дърво:\n"
 "%%sПреместете ги или ги изтрийте, за да преминете на друг клон."
 
-#: unpack-trees.c:131
+#: unpack-trees.c:134
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4434,7 +4822,7 @@ msgstr ""
 "Изтеглянето ще изтрие тези неследени файлове в работното дърво:\n"
 "%%s"
 
-#: unpack-trees.c:134
+#: unpack-trees.c:137
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4443,7 +4831,7 @@ msgstr ""
 "Сливането ще изтрие тези неследени файлове в работното дърво:\n"
 "%%sПреместете ги или ги изтрийте, за да слеете."
 
-#: unpack-trees.c:136
+#: unpack-trees.c:139
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4452,7 +4840,7 @@ msgstr ""
 "Сливането ще изтрие тези неследени файлове в работното дърво:\n"
 "%%s"
 
-#: unpack-trees.c:139
+#: unpack-trees.c:142
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4461,7 +4849,7 @@ msgstr ""
 "„%s“ ще изтрие тези неследени файлове в работното дърво:\n"
 "%%sПреместете ги или ги изтрийте, за да извършите „%s“."
 
-#: unpack-trees.c:141
+#: unpack-trees.c:144
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4470,7 +4858,7 @@ msgstr ""
 "„%s“ ще изтрие тези неследени файлове в работното дърво:\n"
 "%%s"
 
-#: unpack-trees.c:146
+#: unpack-trees.c:150
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4480,7 +4868,7 @@ msgstr ""
 "Изтеглянето ще презапише тези неследени файлове в работното дърво:\n"
 "%%sПреместете ги или ги изтрийте, за да смените клон."
 
-#: unpack-trees.c:148
+#: unpack-trees.c:152
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4490,7 +4878,7 @@ msgstr ""
 "Изтеглянето ще презапише тези неследени файлове в работното дърво:\n"
 "%%s"
 
-#: unpack-trees.c:151
+#: unpack-trees.c:155
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4499,7 +4887,7 @@ msgstr ""
 "Сливането ще презапише тези неследени файлове в работното дърво:\n"
 "%%sПреместете ги или ги изтрийте, за да слеете."
 
-#: unpack-trees.c:153
+#: unpack-trees.c:157
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4508,7 +4896,7 @@ msgstr ""
 "Сливането ще презапише тези неследени файлове в работното дърво:\n"
 "%%s"
 
-#: unpack-trees.c:156
+#: unpack-trees.c:160
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4517,7 +4905,7 @@ msgstr ""
 "„%s“ ще презапише тези неследени файлове в работното дърво:\n"
 "%%sПреместете ги или ги изтрийте, за да извършите „%s“."
 
-#: unpack-trees.c:158
+#: unpack-trees.c:162
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4526,12 +4914,12 @@ msgstr ""
 "„%s“ ще презапише тези неследени файлове в работното дърво:\n"
 "%%s"
 
-#: unpack-trees.c:165
+#: unpack-trees.c:170
 #, c-format
 msgid "Entry '%s' overlaps with '%s'.  Cannot bind."
 msgstr "Записът за „%s“ съвпада с този за „%s“.  Не може да се присвои."
 
-#: unpack-trees.c:168
+#: unpack-trees.c:173
 #, c-format
 msgid ""
 "Cannot update sparse checkout: the following entries are not up to date:\n"
@@ -4541,7 +4929,7 @@ msgstr ""
 "актуални:\n"
 "%s"
 
-#: unpack-trees.c:170
+#: unpack-trees.c:175
 #, c-format
 msgid ""
 "The following working tree files would be overwritten by sparse checkout "
@@ -4552,7 +4940,7 @@ msgstr ""
 "дърво:\n"
 "%s"
 
-#: unpack-trees.c:172
+#: unpack-trees.c:177
 #, c-format
 msgid ""
 "The following working tree files would be removed by sparse checkout "
@@ -4563,7 +4951,7 @@ msgstr ""
 "дърво:\n"
 "%s"
 
-#: unpack-trees.c:174
+#: unpack-trees.c:179
 #, c-format
 msgid ""
 "Cannot update submodule:\n"
@@ -4572,12 +4960,12 @@ msgstr ""
 "Подмодулът не може да бъде обновен:\n"
 "„%s“"
 
-#: unpack-trees.c:251
+#: unpack-trees.c:262
 #, c-format
 msgid "Aborting\n"
 msgstr "Преустановяване на действието\n"
 
-#: unpack-trees.c:333
+#: unpack-trees.c:344
 msgid "Checking out files"
 msgstr "Изтегляне на файлове"
 
@@ -4647,7 +5035,7 @@ msgid "could not open '%s' for reading and writing"
 msgstr "„%s“ не може да бъде отворен и за четене, и за запис"
 
 #: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770
-#: builtin/am.c:862 builtin/merge.c:1044
+#: builtin/am.c:862 builtin/merge.c:1043
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "файлът не може да бъде прочетен: „%s“"
@@ -4661,161 +5049,161 @@ msgstr "няма достъп до „%s“"
 msgid "unable to get current working directory"
 msgstr "текущата работна директория е недостъпна"
 
-#: wt-status.c:151
+#: wt-status.c:154
 msgid "Unmerged paths:"
 msgstr "Неслети пътища:"
 
-#: wt-status.c:178 wt-status.c:205
+#: wt-status.c:181 wt-status.c:208
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (използвайте „git reset %s ФАЙЛ…“, за да извадите ФАЙЛа от индекса)"
 
-#: wt-status.c:180 wt-status.c:207
+#: wt-status.c:183 wt-status.c:210
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr ""
 "  (използвайте „git rm --cached %s ФАЙЛ…“, за да извадите ФАЙЛа от индекса)"
 
-#: wt-status.c:184
+#: wt-status.c:187
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr ""
 "  (използвайте „git add ФАЙЛ…“, за да укажете разрешаването на конфликта)"
 
-#: wt-status.c:186 wt-status.c:190
+#: wt-status.c:189 wt-status.c:193
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
 "  (използвайте „git add/rm ФАЙЛ…“, според решението, което избирате за "
 "конфликта)"
 
-#: wt-status.c:188
+#: wt-status.c:191
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr ""
 "  (използвайте „git rm ФАЙЛ…“, за да укажете разрешаването на конфликта)"
 
-#: wt-status.c:199 wt-status.c:1007
+#: wt-status.c:202 wt-status.c:1015
 msgid "Changes to be committed:"
 msgstr "Промени, които ще бъдат подадени:"
 
-#: wt-status.c:217 wt-status.c:1016
+#: wt-status.c:220 wt-status.c:1024
 msgid "Changes not staged for commit:"
 msgstr "Промени, които не са в индекса за подаване:"
 
-#: wt-status.c:221
+#: wt-status.c:224
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
 "  (използвайте „git add ФАЙЛ…“, за да обновите съдържанието за подаване)"
 
-#: wt-status.c:223
+#: wt-status.c:226
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
 "  (използвайте „git add/rm ФАЙЛ…“, за да обновите съдържанието за подаване)"
 
-#: wt-status.c:224
+#: wt-status.c:227
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 "  (използвайте „git checkout -- ФАЙЛ…“, за да отхвърлите промените в "
 "работното дърво)"
 
-#: wt-status.c:226
+#: wt-status.c:229
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 "  (подайте или отхвърлете неследеното или промененото съдържание в "
 "подмодулите)"
 
-#: wt-status.c:238
+#: wt-status.c:241
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
 "  (използвайте „git %s ФАЙЛ…“, за да определите какво включвате в подаването)"
 
-#: wt-status.c:253
+#: wt-status.c:256
 msgid "both deleted:"
 msgstr "изтрити в двата случая:"
 
-#: wt-status.c:255
+#: wt-status.c:258
 msgid "added by us:"
 msgstr "добавени от вас:"
 
-#: wt-status.c:257
+#: wt-status.c:260
 msgid "deleted by them:"
 msgstr "изтрити от тях:"
 
-#: wt-status.c:259
+#: wt-status.c:262
 msgid "added by them:"
 msgstr "добавени от тях:"
 
-#: wt-status.c:261
+#: wt-status.c:264
 msgid "deleted by us:"
 msgstr "изтрити от вас:"
 
-#: wt-status.c:263
+#: wt-status.c:266
 msgid "both added:"
 msgstr "добавени и в двата случая:"
 
-#: wt-status.c:265
+#: wt-status.c:268
 msgid "both modified:"
 msgstr "променени и в двата случая:"
 
-#: wt-status.c:275
+#: wt-status.c:278
 msgid "new file:"
 msgstr "нов файл:"
 
-#: wt-status.c:277
+#: wt-status.c:280
 msgid "copied:"
 msgstr "копиран:"
 
-#: wt-status.c:279
+#: wt-status.c:282
 msgid "deleted:"
 msgstr "изтрит:"
 
-#: wt-status.c:281
+#: wt-status.c:284
 msgid "modified:"
 msgstr "променен:"
 
-#: wt-status.c:283
+#: wt-status.c:286
 msgid "renamed:"
 msgstr "преименуван:"
 
-#: wt-status.c:285
+#: wt-status.c:288
 msgid "typechange:"
 msgstr "смяна на вида:"
 
-#: wt-status.c:287
+#: wt-status.c:290
 msgid "unknown:"
 msgstr "непозната промяна:"
 
-#: wt-status.c:289
+#: wt-status.c:292
 msgid "unmerged:"
 msgstr "неслят:"
 
-#: wt-status.c:369
+#: wt-status.c:372
 msgid "new commits, "
 msgstr "нови подавания, "
 
-#: wt-status.c:371
+#: wt-status.c:374
 msgid "modified content, "
 msgstr "променено съдържание, "
 
-#: wt-status.c:373
+#: wt-status.c:376
 msgid "untracked content, "
 msgstr "неследено съдържание, "
 
-#: wt-status.c:847
+#: wt-status.c:853
 #, c-format
 msgid "Your stash currently has %d entry"
 msgid_plural "Your stash currently has %d entries"
 msgstr[0] "Има %d скатаване."
 msgstr[1] "Има %d скатавания."
 
-#: wt-status.c:879
+#: wt-status.c:885
 msgid "Submodules changed but not updated:"
 msgstr "Подмодулите са променени, но не са обновени:"
 
-#: wt-status.c:881
+#: wt-status.c:887
 msgid "Submodule changes to be committed:"
 msgstr "Промени в подмодулите за подаване:"
 
-#: wt-status.c:963
+#: wt-status.c:969
 msgid ""
 "Do not modify or remove the line above.\n"
 "Everything below it will be ignored."
@@ -4823,241 +5211,241 @@ msgstr ""
 "Не променяйте и не изтривайте горния ред.\n"
 "Всичко отдолу ще бъде изтрито."
 
-#: wt-status.c:1076
+#: wt-status.c:1084
 msgid "You have unmerged paths."
 msgstr "Някои пътища не са слети."
 
-#: wt-status.c:1079
+#: wt-status.c:1087
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (коригирайте конфликтите и изпълнете „git commit“)"
 
-#: wt-status.c:1081
+#: wt-status.c:1089
 msgid "  (use \"git merge --abort\" to abort the merge)"
 msgstr "  (използвайте „git merge --abort“, за да преустановите сливането)"
 
-#: wt-status.c:1086
+#: wt-status.c:1094
 msgid "All conflicts fixed but you are still merging."
 msgstr "Всички конфликти са решени, но продължавате сливането."
 
-#: wt-status.c:1089
+#: wt-status.c:1097
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (използвайте „git commit“, за да завършите сливането)"
 
-#: wt-status.c:1099
+#: wt-status.c:1107
 msgid "You are in the middle of an am session."
 msgstr "В момента прилагате поредица от кръпки чрез „git am“."
 
-#: wt-status.c:1102
+#: wt-status.c:1110
 msgid "The current patch is empty."
 msgstr "Текущата кръпка е празна."
 
-#: wt-status.c:1106
+#: wt-status.c:1114
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr "  (коригирайте конфликтите и изпълнете „git am --continue“)"
 
-#: wt-status.c:1108
+#: wt-status.c:1116
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (използвайте „git am --skip“, за да пропуснете тази кръпка)"
 
-#: wt-status.c:1110
+#: wt-status.c:1118
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr ""
 "  (използвайте „git am --abort“, за да възстановите първоначалния клон)"
 
-#: wt-status.c:1242
+#: wt-status.c:1250
 msgid "git-rebase-todo is missing."
 msgstr "„git-rebase-todo“ липсва."
 
-#: wt-status.c:1244
+#: wt-status.c:1252
 msgid "No commands done."
 msgstr "Не са изпълнени команди."
 
-#: wt-status.c:1247
+#: wt-status.c:1255
 #, c-format
 msgid "Last command done (%d command done):"
 msgid_plural "Last commands done (%d commands done):"
 msgstr[0] "Последна изпълнена команда (изпълнена е общо %d команда):"
 msgstr[1] "Последна изпълнена команда (изпълнени са общо %d команди):"
 
-#: wt-status.c:1258
+#: wt-status.c:1266
 #, c-format
 msgid "  (see more in file %s)"
 msgstr "  повече информация има във файла „%s“)"
 
-#: wt-status.c:1263
+#: wt-status.c:1271
 msgid "No commands remaining."
 msgstr "Не остават повече команди."
 
-#: wt-status.c:1266
+#: wt-status.c:1274
 #, c-format
 msgid "Next command to do (%d remaining command):"
 msgid_plural "Next commands to do (%d remaining commands):"
 msgstr[0] "Следваща команда за изпълнение (остава още %d команда):"
 msgstr[1] "Следваща команда за изпълнение (остават още %d команди):"
 
-#: wt-status.c:1274
+#: wt-status.c:1282
 msgid "  (use \"git rebase --edit-todo\" to view and edit)"
 msgstr ""
 "  (използвайте „git rebase --edit-todo“, за да разгледате и редактирате)"
 
-#: wt-status.c:1287
+#: wt-status.c:1295
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "В момента пребазирате клона „%s“ върху „%s“."
 
-#: wt-status.c:1292
+#: wt-status.c:1300
 msgid "You are currently rebasing."
 msgstr "В момента пребазирате."
 
-#: wt-status.c:1306
+#: wt-status.c:1314
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (коригирайте конфликтите и използвайте „git rebase --continue“)"
 
-#: wt-status.c:1308
+#: wt-status.c:1316
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (използвайте „git rebase --skip“, за да пропуснете тази кръпка)"
 
-#: wt-status.c:1310
+#: wt-status.c:1318
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr ""
 "  (използвайте „git rebase --abort“, за да възстановите първоначалния клон)"
 
-#: wt-status.c:1316
+#: wt-status.c:1324
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (всички конфликти са коригирани: изпълнете „git rebase --continue“)"
 
-#: wt-status.c:1320
+#: wt-status.c:1328
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
 msgstr "В момента разделяте подаване докато пребазирате клона „%s“ върху „%s“."
 
-#: wt-status.c:1325
+#: wt-status.c:1333
 msgid "You are currently splitting a commit during a rebase."
 msgstr "В момента разделяте подаване докато пребазирате."
 
-#: wt-status.c:1328
+#: wt-status.c:1336
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr ""
 "  (След като работното ви дърво стане чисто, използвайте „git rebase --"
 "continue“)"
 
-#: wt-status.c:1332
+#: wt-status.c:1340
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 "В момента редактирате подаване докато пребазирате клона „%s“ върху „%s“."
 
-#: wt-status.c:1337
+#: wt-status.c:1345
 msgid "You are currently editing a commit during a rebase."
 msgstr "В момента редактирате подаване докато пребазирате."
 
-#: wt-status.c:1340
+#: wt-status.c:1348
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr ""
 "  (използвайте „git commit --amend“, за да редактирате текущото подаване)"
 
-#: wt-status.c:1342
+#: wt-status.c:1350
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
 "  (използвайте „git rebase --continue“, след като завършите промените си)"
 
-#: wt-status.c:1352
+#: wt-status.c:1360
 #, c-format
 msgid "You are currently cherry-picking commit %s."
 msgstr "В момента отбирате подаването „%s“."
 
-#: wt-status.c:1357
+#: wt-status.c:1365
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr "  (коригирайте конфликтите и изпълнете „git cherry-pick --continue“)"
 
-#: wt-status.c:1360
+#: wt-status.c:1368
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr ""
 "  (всички конфликти са коригирани, изпълнете „git cherry-pick --continue“)"
 
-#: wt-status.c:1362
+#: wt-status.c:1370
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr ""
 "  (използвайте „git cherry-pick --abort“, за да отмените всички действия с "
 "отбиране)"
 
-#: wt-status.c:1371
+#: wt-status.c:1379
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "В момента отменяте подаване „%s“."
 
-#: wt-status.c:1376
+#: wt-status.c:1384
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (коригирайте конфликтите и изпълнете „git revert --continue“)"
 
-#: wt-status.c:1379
+#: wt-status.c:1387
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr "  (всички конфликти са коригирани, изпълнете „git revert --continue“)"
 
-#: wt-status.c:1381
+#: wt-status.c:1389
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr ""
 "  (използвайте „git revert --abort“, за да преустановите отмяната на "
 "подаване)"
 
-#: wt-status.c:1392
+#: wt-status.c:1400
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr "В момента търсите двоично, като сте стартирали от клон „%s“."
 
-#: wt-status.c:1396
+#: wt-status.c:1404
 msgid "You are currently bisecting."
 msgstr "В момента търсите двоично."
 
-#: wt-status.c:1399
+#: wt-status.c:1407
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr ""
 "  (използвайте „git bisect reset“, за да се върнете към първоначалното "
 "състояние и клон)"
 
-#: wt-status.c:1596
+#: wt-status.c:1604
 msgid "On branch "
 msgstr "На клон "
 
-#: wt-status.c:1602
+#: wt-status.c:1610
 msgid "interactive rebase in progress; onto "
 msgstr "извършвате интерактивно пребазиране върху "
 
-#: wt-status.c:1604
+#: wt-status.c:1612
 msgid "rebase in progress; onto "
 msgstr "извършвате пребазиране върху "
 
-#: wt-status.c:1609
+#: wt-status.c:1617
 msgid "HEAD detached at "
 msgstr "Указателят „HEAD“ не е свързан и е при "
 
-#: wt-status.c:1611
+#: wt-status.c:1619
 msgid "HEAD detached from "
 msgstr "Указателят „HEAD“ не е свързан и е отделѐн от "
 
-#: wt-status.c:1614
+#: wt-status.c:1622
 msgid "Not currently on any branch."
 msgstr "Извън всички клони."
 
-#: wt-status.c:1634
+#: wt-status.c:1642
 msgid "Initial commit"
 msgstr "Първоначално подаване"
 
-#: wt-status.c:1635
+#: wt-status.c:1643
 msgid "No commits yet"
 msgstr "Все още липсват подавания"
 
-#: wt-status.c:1649
+#: wt-status.c:1657
 msgid "Untracked files"
 msgstr "Неследени файлове"
 
-#: wt-status.c:1651
+#: wt-status.c:1659
 msgid "Ignored files"
 msgstr "Игнорирани файлове"
 
-#: wt-status.c:1655
+#: wt-status.c:1663
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -5069,32 +5457,32 @@ msgstr ""
 "изпълнението, но не трябва да забравяте ръчно да добавяте новите файлове.\n"
 "За повече подробности погледнете „git status help“."
 
-#: wt-status.c:1661
+#: wt-status.c:1669
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "Неследените файлове не са изведени%s"
 
-#: wt-status.c:1663
+#: wt-status.c:1671
 msgid " (use -u option to show untracked files)"
 msgstr " (използвайте опцията „-u“, за да изведете неследените файлове)"
 
-#: wt-status.c:1669
+#: wt-status.c:1677
 msgid "No changes"
 msgstr "Няма промени"
 
-#: wt-status.c:1674
+#: wt-status.c:1682
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
 "към индекса за подаване не са добавени промени (използвайте „git add“ и/или "
 "„git commit -a“)\n"
 
-#: wt-status.c:1677
+#: wt-status.c:1685
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "към индекса за подаване не са добавени промени\n"
 
-#: wt-status.c:1680
+#: wt-status.c:1688
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
@@ -5103,71 +5491,71 @@ msgstr ""
 "към индекса за подаване не са добавени промени, но има нови файлове "
 "(използвайте „git add“, за да започне тяхното следене)\n"
 
-#: wt-status.c:1683
+#: wt-status.c:1691
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr "към индекса за подаване не са добавени промени, но има нови файлове\n"
 
-#: wt-status.c:1686
+#: wt-status.c:1694
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
 "липсват каквито и да е промени (създайте или копирайте файлове и използвайте "
 "„git add“, за да започне тяхното следене)\n"
 
-#: wt-status.c:1689 wt-status.c:1694
+#: wt-status.c:1697 wt-status.c:1702
 #, c-format
 msgid "nothing to commit\n"
 msgstr "липсват каквито и да е промени\n"
 
-#: wt-status.c:1692
+#: wt-status.c:1700
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr ""
 "липсват каквито и да е промени (използвайте опцията „-u“, за да се изведат и "
 "неследените файлове)\n"
 
-#: wt-status.c:1696
+#: wt-status.c:1704
 #, c-format
 msgid "nothing to commit, working tree clean\n"
 msgstr "липсват каквито и да е промени, работното дърво е чисто\n"
 
-#: wt-status.c:1809
+#: wt-status.c:1817
 msgid "No commits yet on "
 msgstr "Все още липсват подавания в "
 
-#: wt-status.c:1813
+#: wt-status.c:1821
 msgid "HEAD (no branch)"
 msgstr "HEAD (извън клон)"
 
-#: wt-status.c:1844
+#: wt-status.c:1852
 msgid "different"
 msgstr "различен"
 
-#: wt-status.c:1846 wt-status.c:1854
+#: wt-status.c:1854 wt-status.c:1862
 msgid "behind "
 msgstr "назад с "
 
-#: wt-status.c:1849 wt-status.c:1852
+#: wt-status.c:1857 wt-status.c:1860
 msgid "ahead "
 msgstr "напред с "
 
 #. TRANSLATORS: the action is e.g. "pull with rebase"
-#: wt-status.c:2358
+#: wt-status.c:2366
 #, c-format
 msgid "cannot %s: You have unstaged changes."
 msgstr "не може да извършите „%s“, защото има промени, които не са в индекса."
 
-#: wt-status.c:2364
+#: wt-status.c:2372
 msgid "additionally, your index contains uncommitted changes."
 msgstr "освен това в индекса има неподадени промени."
 
-#: wt-status.c:2366
+#: wt-status.c:2374
 #, c-format
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "не може да извършите „%s“, защото в индекса има неподадени промени."
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:440
+#: compat/precompose_utf8.c:58 builtin/clone.c:442
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr "неуспешно изтриване на „%s“"
@@ -5181,7 +5569,7 @@ msgstr "git add [ОПЦИЯ…] [--] ПЪТ…"
 msgid "unexpected diff status %c"
 msgstr "неочакван изходен код при генериране на разлика: %c"
 
-#: builtin/add.c:88 builtin/commit.c:257
+#: builtin/add.c:88 builtin/commit.c:266
 msgid "updating files failed"
 msgstr "неуспешно обновяване на файловете"
 
@@ -5194,7 +5582,7 @@ msgstr "изтриване на „%s“\n"
 msgid "Unstaged changes after refreshing the index:"
 msgstr "Промени, които и след обновяването на индекса не са добавени към него:"
 
-#: builtin/add.c:233 builtin/rev-parse.c:888
+#: builtin/add.c:233 builtin/rev-parse.c:892
 msgid "Could not read the index"
 msgstr "Индексът не може да бъде прочетен"
 
@@ -5225,83 +5613,83 @@ msgstr "Празна кръпка, преустановяване на дейс
 msgid "Could not apply '%s'"
 msgstr "Кръпката „%s“ не може да бъде приложена"
 
-#: builtin/add.c:271
+#: builtin/add.c:269
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr ""
 "Следните пътища ще бъдат игнорирани според някой от файловете „.gitignore“:\n"
 
-#: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:146 builtin/mv.c:124
-#: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541
-#: builtin/remote.c:1333 builtin/rm.c:242 builtin/send-pack.c:164
+#: builtin/add.c:289 builtin/clean.c:911 builtin/fetch.c:145 builtin/mv.c:123
+#: builtin/prune-packed.c:55 builtin/pull.c:212 builtin/push.c:557
+#: builtin/remote.c:1342 builtin/rm.c:240 builtin/send-pack.c:165
 msgid "dry run"
 msgstr "пробно изпълнение"
 
-#: builtin/add.c:294
+#: builtin/add.c:292
 msgid "interactive picking"
 msgstr "интерактивно отбиране на промени"
 
-#: builtin/add.c:295 builtin/checkout.c:1128 builtin/reset.c:302
+#: builtin/add.c:293 builtin/checkout.c:1135 builtin/reset.c:302
 msgid "select hunks interactively"
 msgstr "интерактивен избор на парчета код"
 
-#: builtin/add.c:296
+#: builtin/add.c:294
 msgid "edit current diff and apply"
 msgstr "редактиране на текущата разлика и прилагане"
 
-#: builtin/add.c:297
+#: builtin/add.c:295
 msgid "allow adding otherwise ignored files"
 msgstr "добавяне и на иначе игнорираните файлове"
 
-#: builtin/add.c:298
+#: builtin/add.c:296
 msgid "update tracked files"
 msgstr "обновяване на следените файлове"
 
-#: builtin/add.c:299
+#: builtin/add.c:297
 msgid "renormalize EOL of tracked files (implies -u)"
 msgstr "уеднаквяване на знаците за край на файл (включва опцията „-u“)"
 
-#: builtin/add.c:300
+#: builtin/add.c:298
 msgid "record only the fact that the path will be added later"
 msgstr "отбелязване само на факта, че пътят ще бъде добавен по-късно"
 
-#: builtin/add.c:301
+#: builtin/add.c:299
 msgid "add changes from all tracked and untracked files"
 msgstr "добавяне на всички промени в следените и неследените файлове"
 
-#: builtin/add.c:304
+#: builtin/add.c:302
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr ""
 "игнориране на пътищата, които са изтрити от работното дърво (същото като „--"
 "no-all“)"
 
-#: builtin/add.c:306
+#: builtin/add.c:304
 msgid "don't add, only refresh the index"
 msgstr "без добавяне на нови файлове, само обновяване на индекса"
 
-#: builtin/add.c:307
+#: builtin/add.c:305
 msgid "just skip files which cannot be added because of errors"
 msgstr ""
 "прескачане на файловете, които не могат да бъдат добавени поради грешки"
 
-#: builtin/add.c:308
+#: builtin/add.c:306
 msgid "check if - even missing - files are ignored in dry run"
 msgstr ""
 "проверка, че при пробно изпълнение всички файлове, дори и изтритите, се "
 "игнорират"
 
-#: builtin/add.c:309 builtin/update-index.c:964
+#: builtin/add.c:307 builtin/update-index.c:974
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/add.c:309 builtin/update-index.c:965
+#: builtin/add.c:307 builtin/update-index.c:975
 msgid "override the executable bit of the listed files"
 msgstr "изрично задаване на стойността на флага дали файлът е изпълним"
 
-#: builtin/add.c:311
+#: builtin/add.c:309
 msgid "warn when adding an embedded repository"
 msgstr "предупреждаване при добавяне на вградено хранилище"
 
-#: builtin/add.c:326
+#: builtin/add.c:324
 #, c-format
 msgid ""
 "You've added another git repository inside your current repository.\n"
@@ -5332,47 +5720,47 @@ msgstr ""
 "\n"
 "За повече информация погледнете „git help submodule“."
 
-#: builtin/add.c:354
+#: builtin/add.c:352
 #, c-format
 msgid "adding embedded git repository: %s"
 msgstr "добавяне на вградено хранилище: %s"
 
-#: builtin/add.c:372
+#: builtin/add.c:370
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "Използвайте опцията „-f“, за да ги добавите наистина.\n"
 
-#: builtin/add.c:380
+#: builtin/add.c:378
 msgid "adding files failed"
 msgstr "неуспешно добавяне на файлове"
 
-#: builtin/add.c:417
+#: builtin/add.c:416
 msgid "-A and -u are mutually incompatible"
 msgstr "опциите „-A“ и „-u“ са несъвместими"
 
-#: builtin/add.c:424
+#: builtin/add.c:423
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr "Опцията „--ignore-missing“ е съвместима само с „--dry-run“"
 
-#: builtin/add.c:428
+#: builtin/add.c:427
 #, c-format
 msgid "--chmod param '%s' must be either -x or +x"
 msgstr "параметърът към „--chmod“ — „%s“ може да е или „-x“, или „+x“"
 
-#: builtin/add.c:443
+#: builtin/add.c:442
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "Нищо не е зададено и нищо не е добавено.\n"
 
-#: builtin/add.c:444
+#: builtin/add.c:443
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Вероятно искахте да използвате „git add .“?\n"
 
-#: builtin/add.c:449 builtin/check-ignore.c:177 builtin/checkout.c:280
-#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316
+#: builtin/add.c:448 builtin/check-ignore.c:177 builtin/checkout.c:280
+#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:325
 #: builtin/diff-tree.c:114 builtin/mv.c:144 builtin/reset.c:241
-#: builtin/rm.c:271 builtin/submodule--helper.c:326
+#: builtin/rm.c:270 builtin/submodule--helper.c:328
 msgid "index file corrupt"
 msgstr "файлът с индекса е повреден"
 
@@ -5407,7 +5795,7 @@ msgstr "кръпката „%s“ не може да се анализира"
 #: builtin/am.c:855
 msgid "Only one StGIT patch series can be applied at once"
 msgstr ""
-"Само една серия кръпки от „StGIT“ може да бъде прилагана в даден момент"
+"Само една поредица от кръпки от „StGIT“ може да бъде прилагана в даден момент"
 
 #: builtin/am.c:903
 msgid "invalid timestamp"
@@ -5425,7 +5813,7 @@ msgstr "неправилно отместване на часовия пояс"
 msgid "Patch format detection failed."
 msgstr "Форматът на кръпката не може да бъде определен."
 
-#: builtin/am.c:1013 builtin/clone.c:405
+#: builtin/am.c:1013 builtin/clone.c:407
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "директорията „%s“ не може да бъде създадена"
@@ -5434,7 +5822,7 @@ msgstr "директорията „%s“ не може да бъде създа
 msgid "Failed to split patches."
 msgstr "Кръпките не могат да бъдат разделени."
 
-#: builtin/am.c:1148 builtin/commit.c:342
+#: builtin/am.c:1148 builtin/commit.c:351
 msgid "unable to write index file"
 msgstr "индексът не може да бъде записан"
 
@@ -5470,7 +5858,7 @@ msgstr "подаването не може да бъде анализирано:
 #: builtin/am.c:1554
 msgid "Repository lacks necessary blobs to fall back on 3-way merge."
 msgstr ""
-"В хранилището липсват необходимите обекти BLOB, за да се премине към тройно "
+"В хранилището липсват необходимите обекти-BLOB, за да се премине към тройно "
 "сливане."
 
 #: builtin/am.c:1556
@@ -5482,7 +5870,7 @@ msgid ""
 "Did you hand edit your patch?\n"
 "It does not apply to blobs recorded in its index."
 msgstr ""
-"Кръпката не може да се приложи към обектите BLOB в индекса.\n"
+"Кръпката не може да се приложи към обектите-BLOB в индекса.\n"
 "Да не би да сте я редактирали на ръка?"
 
 #: builtin/am.c:1581
@@ -5616,7 +6004,7 @@ msgid "allow fall back on 3way merging if needed"
 msgstr "да се преминава към тройно сливане при нужда."
 
 #: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57
-#: builtin/repack.c:182
+#: builtin/repack.c:192
 msgid "be quiet"
 msgstr "без извеждане на информация"
 
@@ -5661,16 +6049,17 @@ msgstr "пропускане на всичко преди реда за отря
 msgid "pass it through git-apply"
 msgstr "прекарване през „git-apply“"
 
-#: builtin/am.c:2260 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668
-#: builtin/grep.c:853 builtin/merge.c:206 builtin/pull.c:145 builtin/pull.c:203
-#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197
-#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:382
-#: parse-options.h:144 parse-options.h:146 parse-options.h:257
+#: builtin/am.c:2260 builtin/commit.c:1332 builtin/fmt-merge-msg.c:665
+#: builtin/fmt-merge-msg.c:668 builtin/grep.c:853 builtin/merge.c:208
+#: builtin/pull.c:150 builtin/pull.c:208 builtin/repack.c:201
+#: builtin/repack.c:205 builtin/repack.c:207 builtin/show-branch.c:631
+#: builtin/show-ref.c:169 builtin/tag.c:383 parse-options.h:144
+#: parse-options.h:146 parse-options.h:258
 msgid "n"
 msgstr "БРОЙ"
 
-#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38
-#: builtin/replace.c:445 builtin/tag.c:418 builtin/verify-tag.c:39
+#: builtin/am.c:2266 builtin/branch.c:632 builtin/for-each-ref.c:38
+#: builtin/replace.c:543 builtin/tag.c:419 builtin/verify-tag.c:39
 msgid "format"
 msgstr "ФОРМАТ"
 
@@ -5717,8 +6106,8 @@ msgstr "дата за подаване различна от първонача
 msgid "use current timestamp for author date"
 msgstr "използване на текущото време като това за автор"
 
-#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237
-#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:398
+#: builtin/am.c:2298 builtin/commit.c:1468 builtin/merge.c:239
+#: builtin/pull.c:183 builtin/revert.c:112 builtin/tag.c:399
 msgid "key-id"
 msgstr "ИДЕНТИФИКАТОР_НА_КЛЮЧ"
 
@@ -5861,133 +6250,160 @@ msgstr "опцията „--write-terms“ изисква точно два ар
 msgid "--bisect-clean-state requires no arguments"
 msgstr "опцията „--bisect-clean-state“ не приема аргументи"
 
-#: builtin/blame.c:27
+#: builtin/blame.c:29
 msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
 msgstr "git blame [ОПЦИЯ…] [ОПЦИЯ_ЗА_ВЕРСИЯТА…] [ВЕРСИЯ] [--] ФАЙЛ"
 
-#: builtin/blame.c:32
+#: builtin/blame.c:34
 msgid "<rev-opts> are documented in git-rev-list(1)"
 msgstr "ОПЦИИте_ЗА_ВЕРСИЯТА са документирани в ръководството git-rev-list(1)"
 
-#: builtin/blame.c:677
+#: builtin/blame.c:404
+#, c-format
+msgid "expecting a color: %s"
+msgstr "трябва да е цвят: %s"
+
+#: builtin/blame.c:411
+msgid "must end with a color"
+msgstr "трябва да завършва с цвят"
+
+#: builtin/blame.c:697
+#, c-format
+msgid "invalid color '%s' in color.blame.repeatedLines"
+msgstr "неправилен цвят „%s“ в „color.blame.repeatedLines“"
+
+#: builtin/blame.c:715
+msgid "invalid value for blame.coloring"
+msgstr "неправилна стойност за „blame.coloring“"
+
+#: builtin/blame.c:786
 msgid "Show blame entries as we find them, incrementally"
 msgstr "Извеждане на анотациите с намирането им, последователно"
 
-#: builtin/blame.c:678
+#: builtin/blame.c:787
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr ""
 "Извеждане на празни суми по SHA1 за граничните подавания (стандартно опцията "
 "е изключена)"
 
-#: builtin/blame.c:679
+#: builtin/blame.c:788
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr ""
 "Началните подавания да не се считат за гранични (стандартно опцията е "
 "изключена)"
 
-#: builtin/blame.c:680
+#: builtin/blame.c:789
 msgid "Show work cost statistics"
 msgstr "Извеждане на статистика за извършените действия"
 
-#: builtin/blame.c:681
+#: builtin/blame.c:790
 msgid "Force progress reporting"
 msgstr "Принудително извеждане на напредъка"
 
-#: builtin/blame.c:682
+#: builtin/blame.c:791
 msgid "Show output score for blame entries"
 msgstr "Извеждане на допълнителна информация за определянето на анотациите"
 
-#: builtin/blame.c:683
+#: builtin/blame.c:792
 msgid "Show original filename (Default: auto)"
 msgstr ""
 "Извеждане на първоначалното име на файл (стандартно това е автоматично)"
 
-#: builtin/blame.c:684
+#: builtin/blame.c:793
 msgid "Show original linenumber (Default: off)"
 msgstr ""
 "Извеждане на първоначалният номер на ред (стандартно опцията е изключена)"
 
-#: builtin/blame.c:685
+#: builtin/blame.c:794
 msgid "Show in a format designed for machine consumption"
 msgstr "Извеждане във формат за по-нататъшна обработка"
 
-#: builtin/blame.c:686
+#: builtin/blame.c:795
 msgid "Show porcelain format with per-line commit information"
 msgstr ""
 "Извеждане във формат за команди от потребителско ниво с информация на всеки "
 "ред"
 
-#: builtin/blame.c:687
+#: builtin/blame.c:796
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr ""
 "Използване на същия формат като „git-annotate“ (стандартно опцията е "
 "изключена)"
 
-#: builtin/blame.c:688
+#: builtin/blame.c:797
 msgid "Show raw timestamp (Default: off)"
 msgstr "Извеждане на неформатирани времена (стандартно опцията е изключена)"
 
-#: builtin/blame.c:689
+#: builtin/blame.c:798
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "Извеждане на пълните суми по SHA1 (стандартно опцията е изключена)"
 
-#: builtin/blame.c:690
+#: builtin/blame.c:799
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "Без име на автор и време на промяна (стандартно опцията е изключена)"
 
-#: builtin/blame.c:691
+#: builtin/blame.c:800
 msgid "Show author email instead of name (Default: off)"
 msgstr ""
 "Извеждане на е-пощата на автора, а не името му (стандартно опцията е "
 "изключена)"
 
-#: builtin/blame.c:692
+#: builtin/blame.c:801
 msgid "Ignore whitespace differences"
 msgstr "Без разлики в знаците за интервали"
 
-#: builtin/blame.c:699
+#: builtin/blame.c:802
+msgid "color redundant metadata from previous line differently"
+msgstr ""
+"оцветяване на повтарящите се метаданни от предишния ред в различен цвят"
+
+#: builtin/blame.c:803
+msgid "color lines by age"
+msgstr "оцветяване на редовете по възраст"
+
+#: builtin/blame.c:810
 msgid "Use an experimental heuristic to improve diffs"
 msgstr "Подобряване на разликите чрез експериментална евристика"
 
-#: builtin/blame.c:701
+#: builtin/blame.c:812
 msgid "Spend extra cycles to find better match"
 msgstr "Допълнителни изчисления за по-добри резултати"
 
-#: builtin/blame.c:702
+#: builtin/blame.c:813
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr "Изчитане на версиите от ФАЙЛ, а не чрез изпълнение на „git-rev-list“"
 
-#: builtin/blame.c:703
+#: builtin/blame.c:814
 msgid "Use <file>'s contents as the final image"
 msgstr "Използване на съдържанието на ФАЙЛа като крайно положение"
 
-#: builtin/blame.c:704 builtin/blame.c:705
+#: builtin/blame.c:815 builtin/blame.c:816
 msgid "score"
 msgstr "напасване на редовете"
 
-#: builtin/blame.c:704
+#: builtin/blame.c:815
 msgid "Find line copies within and across files"
 msgstr ""
 "Търсене на копирани редове както в рамките на един файл, така и от един файл "
 "към друг"
 
-#: builtin/blame.c:705
+#: builtin/blame.c:816
 msgid "Find line movements within and across files"
 msgstr ""
 "Търсене на преместени редове както в рамките на един файл, така и от един "
 "файл към друг"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "Process only line range n,m, counting from 1"
 msgstr ""
 "Информация само за редовете в диапазона от n до m включително.  Броенето "
 "започва от 1"
 
-#: builtin/blame.c:753
+#: builtin/blame.c:866
 msgid "--progress can't be used with --incremental or porcelain formats"
 msgstr ""
 "опцията „--progress“ е несъвместима с „--incremental“ и форма̀та на командите "
@@ -6001,18 +6417,18 @@ msgstr ""
 #. your language may need more or fewer display
 #. columns.
 #.
-#: builtin/blame.c:804
+#: builtin/blame.c:917
 msgid "4 years, 11 months ago"
 msgstr "преди 4 години и 11 месеца"
 
-#: builtin/blame.c:890
+#: builtin/blame.c:1003
 #, c-format
 msgid "file %s has only %lu line"
 msgid_plural "file %s has only %lu lines"
 msgstr[0] "има само %2$lu ред във файла „%1$s“"
 msgstr[1] "има само %2$lu реда във файла „%1$s“"
 
-#: builtin/blame.c:936
+#: builtin/blame.c:1049
 msgid "Blaming lines"
 msgstr "Анотирани редове"
 
@@ -6123,66 +6539,66 @@ msgstr "Изтрит следящ клон „%s“ (той сочеше към
 msgid "Deleted branch %s (was %s).\n"
 msgstr "Изтрит клон „%s“ (той сочеше към „%s“).\n"
 
-#: builtin/branch.c:417 builtin/tag.c:58
+#: builtin/branch.c:416 builtin/tag.c:58
 msgid "unable to parse format string"
 msgstr "форматиращият низ не може да бъде анализиран: %s"
 
-#: builtin/branch.c:450
+#: builtin/branch.c:453
 #, c-format
 msgid "Branch %s is being rebased at %s"
 msgstr "Клонът „%s“ се пребазира върху „%s“"
 
-#: builtin/branch.c:454
+#: builtin/branch.c:457
 #, c-format
 msgid "Branch %s is being bisected at %s"
 msgstr "Търси се двоично в клона „%s“ при „%s“"
 
-#: builtin/branch.c:471
+#: builtin/branch.c:474
 msgid "cannot copy the current branch while not on any."
 msgstr "не можете да копирате текущия клон, защото сте извън който и да е клон"
 
-#: builtin/branch.c:473
+#: builtin/branch.c:476
 msgid "cannot rename the current branch while not on any."
 msgstr ""
 "не можете да преименувате текущия клон, защото сте извън който и да е клон"
 
-#: builtin/branch.c:484
+#: builtin/branch.c:487
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "Неправилно име на клон: „%s“"
 
-#: builtin/branch.c:511
+#: builtin/branch.c:514
 msgid "Branch rename failed"
 msgstr "Неуспешно преименуване на клон"
 
-#: builtin/branch.c:513
+#: builtin/branch.c:516
 msgid "Branch copy failed"
 msgstr "Неуспешно копиране на клон"
 
-#: builtin/branch.c:517
+#: builtin/branch.c:520
 #, c-format
 msgid "Created a copy of a misnamed branch '%s'"
 msgstr "Клонът с неправилно име „%s“ е копиран"
 
-#: builtin/branch.c:520
+#: builtin/branch.c:523
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "Клонът с неправилно име „%s“ е преименуван"
 
-#: builtin/branch.c:526
+#: builtin/branch.c:529
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "Клонът е преименуван на „%s“, но указателят „HEAD“ не е обновен"
 
-#: builtin/branch.c:535
+#: builtin/branch.c:538
 msgid "Branch is renamed, but update of config-file failed"
 msgstr "Клонът е преименуван, но конфигурационният файл не е обновен"
 
-#: builtin/branch.c:537
+#: builtin/branch.c:540
 msgid "Branch is copied, but update of config-file failed"
 msgstr "Клонът е копиран, но конфигурационният файл не е обновен"
 
-#: builtin/branch.c:553
+#: builtin/branch.c:556
 #, c-format
 msgid ""
 "Please edit the description for the branch\n"
@@ -6193,187 +6609,189 @@ msgstr ""
 "    %s\n"
 "Редовете, които започват с „%c“, ще бъдат пропуснати.\n"
 
-#: builtin/branch.c:586
+#: builtin/branch.c:589
 msgid "Generic options"
 msgstr "Общи настройки"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:591
 msgid "show hash and subject, give twice for upstream branch"
 msgstr ""
 "извеждане на хеша и темата.  Повтарянето на опцията прибавя отдалечените "
 "клони"
 
-#: builtin/branch.c:589
+#: builtin/branch.c:592
 msgid "suppress informational messages"
 msgstr "без информационни съобщения"
 
-#: builtin/branch.c:590
+#: builtin/branch.c:593
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "задаване на режима на следене (виж git-pull(1))"
 
-#: builtin/branch.c:592
+#: builtin/branch.c:595
 msgid "do not use"
 msgstr "да не се ползва"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "upstream"
 msgstr "клон-източник"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "change the upstream info"
 msgstr "смяна на клона-източник"
 
-#: builtin/branch.c:595
+#: builtin/branch.c:598
 msgid "Unset the upstream info"
 msgstr "без клон-източник"
 
-#: builtin/branch.c:596
+#: builtin/branch.c:599
 msgid "use colored output"
 msgstr "цветен изход"
 
-#: builtin/branch.c:597
+#: builtin/branch.c:600
 msgid "act on remote-tracking branches"
 msgstr "действие върху следящите клони"
 
-#: builtin/branch.c:599 builtin/branch.c:601
+#: builtin/branch.c:602 builtin/branch.c:604
 msgid "print only branches that contain the commit"
 msgstr "извеждане само на клоните, които съдържат това ПОДАВАНЕ"
 
-#: builtin/branch.c:600 builtin/branch.c:602
+#: builtin/branch.c:603 builtin/branch.c:605
 msgid "print only branches that don't contain the commit"
 msgstr "извеждане само на клоните, които не съдържат това ПОДАВАНЕ"
 
-#: builtin/branch.c:605
+#: builtin/branch.c:608
 msgid "Specific git-branch actions:"
 msgstr "Специални действия на „git-branch“:"
 
-#: builtin/branch.c:606
+#: builtin/branch.c:609
 msgid "list both remote-tracking and local branches"
 msgstr "извеждане както на следящите, така и на локалните клони"
 
-#: builtin/branch.c:608
+#: builtin/branch.c:611
 msgid "delete fully merged branch"
 msgstr "изтриване на клони, които са напълно слети"
 
-#: builtin/branch.c:609
+#: builtin/branch.c:612
 msgid "delete branch (even if not merged)"
 msgstr "изтриване и на клони, които не са напълно слети"
 
-#: builtin/branch.c:610
+#: builtin/branch.c:613
 msgid "move/rename a branch and its reflog"
 msgstr ""
 "преместване/преименуване на клон и принадлежащият му журнал на указателите"
 
-#: builtin/branch.c:611
+#: builtin/branch.c:614
 msgid "move/rename a branch, even if target exists"
 msgstr "преместване/преименуване на клон, дори ако има вече клон с такова име"
 
-#: builtin/branch.c:612
+#: builtin/branch.c:615
 msgid "copy a branch and its reflog"
 msgstr "копиране на клон и принадлежащия му журнал на указателите"
 
-#: builtin/branch.c:613
+#: builtin/branch.c:616
 msgid "copy a branch, even if target exists"
 msgstr "копиране на клон, дори ако има вече клон с такова име"
 
-#: builtin/branch.c:614
+#: builtin/branch.c:617
 msgid "list branch names"
 msgstr "извеждане на имената на клоните"
 
-#: builtin/branch.c:615
+#: builtin/branch.c:618
 msgid "create the branch's reflog"
 msgstr "създаване на журнала на указателите на клона"
 
-#: builtin/branch.c:617
+#: builtin/branch.c:620
 msgid "edit the description for the branch"
 msgstr "редактиране на описанието на клона"
 
-#: builtin/branch.c:618
+#: builtin/branch.c:621
 msgid "force creation, move/rename, deletion"
 msgstr "принудително създаване, преместване, преименуване, изтриване"
 
-#: builtin/branch.c:619
+#: builtin/branch.c:622
 msgid "print only branches that are merged"
 msgstr "извеждане само на слетите клони"
 
-#: builtin/branch.c:620
+#: builtin/branch.c:623
 msgid "print only branches that are not merged"
 msgstr "извеждане само на неслетите клони"
 
-#: builtin/branch.c:621
+#: builtin/branch.c:624
 msgid "list branches in columns"
 msgstr "извеждане по колони"
 
-#: builtin/branch.c:622 builtin/for-each-ref.c:40 builtin/tag.c:411
+#: builtin/branch.c:625 builtin/for-each-ref.c:40 builtin/ls-remote.c:70
+#: builtin/tag.c:412
 msgid "key"
 msgstr "КЛЮЧ"
 
-#: builtin/branch.c:623 builtin/for-each-ref.c:41 builtin/tag.c:412
+#: builtin/branch.c:626 builtin/for-each-ref.c:41 builtin/ls-remote.c:71
+#: builtin/tag.c:413
 msgid "field name to sort on"
 msgstr "име на полето, по което да е подредбата"
 
-#: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408
+#: builtin/branch.c:628 builtin/for-each-ref.c:43 builtin/notes.c:408
 #: builtin/notes.c:411 builtin/notes.c:571 builtin/notes.c:574
-#: builtin/tag.c:414
+#: builtin/tag.c:415
 msgid "object"
 msgstr "ОБЕКТ"
 
-#: builtin/branch.c:626
+#: builtin/branch.c:629
 msgid "print only branches of the object"
 msgstr "извеждане само на клоните на ОБЕКТА"
 
-#: builtin/branch.c:628 builtin/for-each-ref.c:49 builtin/tag.c:421
+#: builtin/branch.c:631 builtin/for-each-ref.c:49 builtin/tag.c:422
 msgid "sorting and filtering are case insensitive"
 msgstr "подредбата и филтрирането третират еднакво малките и главните букви"
 
-#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419
+#: builtin/branch.c:632 builtin/for-each-ref.c:38 builtin/tag.c:420
 #: builtin/verify-tag.c:39
 msgid "format to use for the output"
 msgstr "ФОРМАТ за изхода"
 
-#: builtin/branch.c:652 builtin/clone.c:735
+#: builtin/branch.c:655 builtin/clone.c:737
 msgid "HEAD not found below refs/heads!"
 msgstr "В директорията „refs/heads“ липсва файл „HEAD“"
 
-#: builtin/branch.c:675
+#: builtin/branch.c:678
 msgid "--column and --verbose are incompatible"
 msgstr "Опциите „--column“ и „--verbose“ са несъвместими"
 
-#: builtin/branch.c:690 builtin/branch.c:742 builtin/branch.c:751
+#: builtin/branch.c:693 builtin/branch.c:745 builtin/branch.c:754
 msgid "branch name required"
 msgstr "Необходимо е име на клон"
 
-#: builtin/branch.c:718
+#: builtin/branch.c:721
 msgid "Cannot give description to detached HEAD"
 msgstr "Не може да зададете описание на несвързан „HEAD“"
 
-#: builtin/branch.c:723
+#: builtin/branch.c:726
 msgid "cannot edit description of more than one branch"
 msgstr "Не може да редактирате описанието на повече от един клон едновременно"
 
-#: builtin/branch.c:730
+#: builtin/branch.c:733
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "В клона „%s“ все още няма подавания."
 
-#: builtin/branch.c:733
+#: builtin/branch.c:736
 #, c-format
 msgid "No branch named '%s'."
 msgstr "Липсва клон на име „%s“."
 
-#: builtin/branch.c:748
+#: builtin/branch.c:751
 msgid "too many branches for a copy operation"
 msgstr "прекалено много клони за копиране"
 
-#: builtin/branch.c:757
+#: builtin/branch.c:760
 msgid "too many arguments for a rename operation"
 msgstr "прекалено много аргументи към командата за преименуване"
 
-#: builtin/branch.c:762
+#: builtin/branch.c:765
 msgid "too many arguments to set new upstream"
 msgstr "прекалено много аргументи към командата за следене"
 
-#: builtin/branch.c:766
+#: builtin/branch.c:769
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
@@ -6381,35 +6799,35 @@ msgstr ""
 "Следеното от „HEAD“ не може да се зададе да е „%s“, защото то не сочи към "
 "никой клон."
 
-#: builtin/branch.c:769 builtin/branch.c:791 builtin/branch.c:807
+#: builtin/branch.c:772 builtin/branch.c:794 builtin/branch.c:810
 #, c-format
 msgid "no such branch '%s'"
 msgstr "Няма клон на име „%s“."
 
-#: builtin/branch.c:773
+#: builtin/branch.c:776
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "Не съществува клон на име „%s“."
 
-#: builtin/branch.c:785
+#: builtin/branch.c:788
 msgid "too many arguments to unset upstream"
 msgstr "прекалено много аргументи към командата за спиране на следене"
 
-#: builtin/branch.c:789
+#: builtin/branch.c:792
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
 "Следеното от „HEAD“ не може да махне, защото то не сочи към никой клон."
 
-#: builtin/branch.c:795
+#: builtin/branch.c:798
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "Няма информация клонът „%s“ да следи някой друг"
 
-#: builtin/branch.c:810
+#: builtin/branch.c:813
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr "Опциите „-a“ и „-r“ на „git branch“ са несъвместими с име на клон"
 
-#: builtin/branch.c:813
+#: builtin/branch.c:816
 msgid ""
 "the '--set-upstream' option is no longer supported. Please use '--track' or "
 "'--set-upstream-to' instead."
@@ -6430,7 +6848,7 @@ msgstr "За създаването на пратка е необходимо х
 msgid "Need a repository to unbundle."
 msgstr "За приемането на пратка е необходимо хранилище."
 
-#: builtin/cat-file.c:523
+#: builtin/cat-file.c:525
 msgid ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <type> | --textconv | --filters) [--path=<path>] <object>"
@@ -6438,7 +6856,7 @@ msgstr ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | ВИД | --textconv --filters) [--path=ПЪТ] ОБЕКТ"
 
-#: builtin/cat-file.c:524
+#: builtin/cat-file.c:526
 msgid ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
@@ -6446,71 +6864,71 @@ msgstr ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
 
-#: builtin/cat-file.c:561
+#: builtin/cat-file.c:563
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr ""
-"ВИДът може да е: „blob“ (обект BLOB), „tree“ (дърво), „commit“ (подаване), "
+"ВИДът може да е: „blob“ (BLOB), „tree“ (дърво), „commit“ (подаване), "
 "„tag“ (етикет)"
 
-#: builtin/cat-file.c:562
+#: builtin/cat-file.c:564
 msgid "show object type"
 msgstr "извеждане на вида на обект"
 
-#: builtin/cat-file.c:563
+#: builtin/cat-file.c:565
 msgid "show object size"
 msgstr "извеждане на размера на обект"
 
-#: builtin/cat-file.c:565
+#: builtin/cat-file.c:567
 msgid "exit with zero when there's no error"
 msgstr "изход с 0, когато няма грешка"
 
-#: builtin/cat-file.c:566
+#: builtin/cat-file.c:568
 msgid "pretty-print object's content"
 msgstr "форматирано извеждане на съдържанието на обекта"
 
-#: builtin/cat-file.c:568
+#: builtin/cat-file.c:570
 msgid "for blob objects, run textconv on object's content"
 msgstr ""
 "да се стартира програмата зададена в настройката „textconv“ за преобразуване "
-"на съдържанието на обекта BLOB"
+"на съдържанието на обекта-BLOB"
 
-#: builtin/cat-file.c:570
+#: builtin/cat-file.c:572
 msgid "for blob objects, run filters on object's content"
 msgstr ""
-"да се стартират програмите за преобразуване на съдържанието на обектите BLOB"
+"да се стартират програмите за преобразуване на съдържанието на обектите-BLOB"
 
-#: builtin/cat-file.c:571 git-submodule.sh:878
+#: builtin/cat-file.c:573 git-submodule.sh:894
 msgid "blob"
-msgstr "обект BLOB"
+msgstr "обект-BLOB"
 
-#: builtin/cat-file.c:572
+#: builtin/cat-file.c:574
 msgid "use a specific path for --textconv/--filters"
 msgstr "опциите „--textconv“/„--filters“ изискват път"
 
-#: builtin/cat-file.c:574
+#: builtin/cat-file.c:576
 msgid "allow -s and -t to work with broken/corrupt objects"
 msgstr "позволяване на опциите „-s“ и „-t“ да работят с повредени обекти"
 
-#: builtin/cat-file.c:575
+#: builtin/cat-file.c:577
 msgid "buffer --batch output"
 msgstr "буфериране на изхода от „--batch“"
 
-#: builtin/cat-file.c:577
+#: builtin/cat-file.c:579
 msgid "show info and content of objects fed from the standard input"
 msgstr ""
 "извеждане на информация и съдържание на обектите подадени на стандартния вход"
 
-#: builtin/cat-file.c:580
+#: builtin/cat-file.c:582
 msgid "show info about objects fed from the standard input"
 msgstr "извеждане на информация за обектите подадени на стандартния вход"
 
-#: builtin/cat-file.c:583
+#: builtin/cat-file.c:585
 msgid "follow in-tree symlinks (used with --batch or --batch-check)"
 msgstr ""
 "следване на символните връзки сочещи в дървото (ползва се с „--batch“ или „--"
 "batch-check“)"
 
-#: builtin/cat-file.c:585
+#: builtin/cat-file.c:587
 msgid "show all objects with --batch or --batch-check"
 msgstr "извеждане на всички обекти с „--batch“ или „--batch-check“"
 
@@ -6538,7 +6956,7 @@ msgstr "изчитане на имената на файловете от ста
 msgid "terminate input and output records by a NUL character"
 msgstr "разделяне на входните и изходните записи с нулевия знак „NUL“"
 
-#: builtin/check-ignore.c:20 builtin/checkout.c:1106 builtin/gc.c:358
+#: builtin/check-ignore.c:20 builtin/checkout.c:1113 builtin/gc.c:500
 msgid "suppress progress reporting"
 msgstr "без показване на напредъка"
 
@@ -6628,9 +7046,9 @@ msgid "write the content to temporary files"
 msgstr "записване на съдържанието във временни файлове"
 
 #: builtin/checkout-index.c:173 builtin/column.c:31
-#: builtin/submodule--helper.c:1203 builtin/submodule--helper.c:1206
-#: builtin/submodule--helper.c:1212 builtin/submodule--helper.c:1574
-#: builtin/worktree.c:570
+#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1219
+#: builtin/submodule--helper.c:1227 builtin/submodule--helper.c:1591
+#: builtin/worktree.c:610
 msgid "string"
 msgstr "НИЗ"
 
@@ -6702,54 +7120,54 @@ msgstr ""
 msgid "path '%s' is unmerged"
 msgstr "пътят „%s“ не е слят"
 
-#: builtin/checkout.c:505
+#: builtin/checkout.c:506
 msgid "you need to resolve your current index first"
 msgstr "първо трябва да коригирате индекса си"
 
-#: builtin/checkout.c:636
+#: builtin/checkout.c:643
 #, c-format
 msgid "Can not do reflog for '%s': %s\n"
 msgstr "Журналът на указателите за „%s“ не може да се проследи: %s\n"
 
-#: builtin/checkout.c:677
+#: builtin/checkout.c:684
 msgid "HEAD is now at"
 msgstr "Указателят „HEAD“ в момента сочи към"
 
-#: builtin/checkout.c:681 builtin/clone.c:689
+#: builtin/checkout.c:688 builtin/clone.c:691
 msgid "unable to update HEAD"
 msgstr "Указателят „HEAD“ не може да бъде обновен"
 
-#: builtin/checkout.c:685
+#: builtin/checkout.c:692
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Зануляване на клона „%s“\n"
 
-#: builtin/checkout.c:688
+#: builtin/checkout.c:695
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Вече сте на „%s“\n"
 
-#: builtin/checkout.c:692
+#: builtin/checkout.c:699
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Преминаване към клона „%s“ и зануляване на промените\n"
 
-#: builtin/checkout.c:694 builtin/checkout.c:1039
+#: builtin/checkout.c:701 builtin/checkout.c:1046
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Преминахте към новия клон „%s“\n"
 
-#: builtin/checkout.c:696
+#: builtin/checkout.c:703
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Преминахте към клона „%s“\n"
 
-#: builtin/checkout.c:747
+#: builtin/checkout.c:754
 #, c-format
 msgid " ... and %d more.\n"
 msgstr "… и още %d.\n"
 
-#: builtin/checkout.c:753
+#: builtin/checkout.c:760
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -6771,7 +7189,7 @@ msgstr[1] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:772
+#: builtin/checkout.c:779
 #, c-format
 msgid ""
 "If you want to keep it by creating a new branch, this may be a good time\n"
@@ -6798,164 +7216,164 @@ msgstr[1] ""
 " git branch ИМЕ_НА_НОВИЯ_КЛОН %s\n"
 "\n"
 
-#: builtin/checkout.c:804
+#: builtin/checkout.c:811
 msgid "internal error in revision walk"
 msgstr "вътрешна грешка при обхождането на версиите"
 
-#: builtin/checkout.c:808
+#: builtin/checkout.c:815
 msgid "Previous HEAD position was"
 msgstr "Преди това „HEAD“ сочеше към"
 
-#: builtin/checkout.c:836 builtin/checkout.c:1034
+#: builtin/checkout.c:843 builtin/checkout.c:1041
 msgid "You are on a branch yet to be born"
 msgstr "В момента сте на клон, който предстои да бъде създаден"
 
-#: builtin/checkout.c:940
+#: builtin/checkout.c:947
 #, c-format
 msgid "only one reference expected, %d given."
 msgstr "очакваше се един указател, а сте подали %d."
 
-#: builtin/checkout.c:980 builtin/worktree.c:249
+#: builtin/checkout.c:987 builtin/worktree.c:240 builtin/worktree.c:389
 #, c-format
 msgid "invalid reference: %s"
 msgstr "неправилен указател: %s"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1016
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "указателят не сочи към обект-дърво: %s"
 
-#: builtin/checkout.c:1048
+#: builtin/checkout.c:1055
 msgid "paths cannot be used with switching branches"
 msgstr "задаването на път е несъвместимо с преминаването от един клон към друг"
 
-#: builtin/checkout.c:1051 builtin/checkout.c:1055
+#: builtin/checkout.c:1058 builtin/checkout.c:1062
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "опцията „%s“ е несъвместима с преминаването от един клон към друг"
 
-#: builtin/checkout.c:1059 builtin/checkout.c:1062 builtin/checkout.c:1067
-#: builtin/checkout.c:1070
+#: builtin/checkout.c:1066 builtin/checkout.c:1069 builtin/checkout.c:1074
+#: builtin/checkout.c:1077
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "опцията „%s“ е несъвместима с „%s“"
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1082
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr ""
 "За да преминете към клон, подайте указател, който сочи към подаване.  „%s“ "
 "не е такъв"
 
-#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116
-#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:387
-#: builtin/worktree.c:389
+#: builtin/checkout.c:1114 builtin/checkout.c:1116 builtin/clone.c:118
+#: builtin/remote.c:167 builtin/remote.c:169 builtin/worktree.c:433
+#: builtin/worktree.c:435
 msgid "branch"
 msgstr "клон"
 
-#: builtin/checkout.c:1108
+#: builtin/checkout.c:1115
 msgid "create and checkout a new branch"
 msgstr "създаване и преминаване към нов клон"
 
-#: builtin/checkout.c:1110
+#: builtin/checkout.c:1117
 msgid "create/reset and checkout a branch"
 msgstr "създаване/зануляване на клон и преминаване към него"
 
-#: builtin/checkout.c:1111
+#: builtin/checkout.c:1118
 msgid "create reflog for new branch"
 msgstr "създаване на журнал на указателите за нов клон"
 
-#: builtin/checkout.c:1112 builtin/worktree.c:391
+#: builtin/checkout.c:1119 builtin/worktree.c:437
 msgid "detach HEAD at named commit"
 msgstr "отделяне на указателя „HEAD“ към указаното подаване"
 
-#: builtin/checkout.c:1113
+#: builtin/checkout.c:1120
 msgid "set upstream info for new branch"
 msgstr "задаване на кой клон бива следен при създаването на новия клон"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new-branch"
 msgstr "НОВ_КЛОН"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new unparented branch"
 msgstr "нов клон без родител"
 
-#: builtin/checkout.c:1116
+#: builtin/checkout.c:1123
 msgid "checkout our version for unmerged files"
 msgstr "изтегляне на вашата версия на неслетите файлове"
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1125
 msgid "checkout their version for unmerged files"
 msgstr "изтегляне на чуждата версия на неслетите файлове"
 
-#: builtin/checkout.c:1120
+#: builtin/checkout.c:1127
 msgid "force checkout (throw away local modifications)"
 msgstr "принудително изтегляне (вашите промени ще бъдат занулени)"
 
-#: builtin/checkout.c:1122
+#: builtin/checkout.c:1129
 msgid "perform a 3-way merge with the new branch"
 msgstr "извършване на тройно сливане с новия клон"
 
-#: builtin/checkout.c:1124 builtin/merge.c:239
+#: builtin/checkout.c:1131 builtin/merge.c:241
 msgid "update ignored files (default)"
 msgstr "обновяване на игнорираните файлове (стандартно)"
 
-#: builtin/checkout.c:1126 builtin/log.c:1499 parse-options.h:263
+#: builtin/checkout.c:1133 builtin/log.c:1499 parse-options.h:264
 msgid "style"
 msgstr "СТИЛ"
 
-#: builtin/checkout.c:1127
+#: builtin/checkout.c:1134
 msgid "conflict style (merge or diff3)"
 msgstr "действие при конфликт (сливане или тройна разлика)"
 
-#: builtin/checkout.c:1130
+#: builtin/checkout.c:1137
 msgid "do not limit pathspecs to sparse entries only"
 msgstr "без ограничаване на изброените пътища само до частично изтеглените"
 
-#: builtin/checkout.c:1132
+#: builtin/checkout.c:1139
 msgid "second guess 'git checkout <no-such-branch>'"
 msgstr ""
 "опит за отгатване на име на клон след неуспешен опит с „git checkout "
 "НЕСЪЩЕСТВУВАЩ_КЛОН“"
 
-#: builtin/checkout.c:1134
+#: builtin/checkout.c:1141
 msgid "do not check if another worktree is holding the given ref"
 msgstr "без проверка дали друго работно дърво държи указателя"
 
-#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150
-#: builtin/merge.c:236 builtin/pull.c:123 builtin/push.c:556
-#: builtin/send-pack.c:173
+#: builtin/checkout.c:1145 builtin/clone.c:85 builtin/fetch.c:149
+#: builtin/merge.c:238 builtin/pull.c:128 builtin/push.c:572
+#: builtin/send-pack.c:174
 msgid "force progress reporting"
 msgstr "извеждане на напредъка"
 
-#: builtin/checkout.c:1168
+#: builtin/checkout.c:1175
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "Опциите „-b“, „-B“ и „--orphan“ са несъвместими една с друга"
 
-#: builtin/checkout.c:1185
+#: builtin/checkout.c:1192
 msgid "--track needs a branch name"
 msgstr "опцията „--track“ изисква име на клон"
 
-#: builtin/checkout.c:1190
+#: builtin/checkout.c:1197
 msgid "Missing branch name; try -b"
 msgstr "Липсва име на клон, използвайте опцията „-b“"
 
-#: builtin/checkout.c:1226
+#: builtin/checkout.c:1233
 msgid "invalid path specification"
 msgstr "указан е неправилен път"
 
-#: builtin/checkout.c:1233
+#: builtin/checkout.c:1240
 #, c-format
 msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
 msgstr "„%s“ не е подаване, затова от него не може да се създаде клон „%s“"
 
-#: builtin/checkout.c:1237
+#: builtin/checkout.c:1244
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout: опцията „--detach“ не приема аргумент-път „%s“"
 
-#: builtin/checkout.c:1241
+#: builtin/checkout.c:1248
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -6993,7 +7411,7 @@ msgstr "Хранилището „%s“ ще бъде прескочено\n"
 msgid "failed to remove %s"
 msgstr "файлът „%s“ не може да бъде изтрит"
 
-#: builtin/clean.c:302 git-add--interactive.perl:572
+#: builtin/clean.c:302 git-add--interactive.perl:579
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -7006,7 +7424,7 @@ msgstr ""
 "ПРЕФИКС    — избор на единствен обект по този уникален префикс\n"
 "           — (празно) нищо да не се избира\n"
 
-#: builtin/clean.c:306 git-add--interactive.perl:581
+#: builtin/clean.c:306 git-add--interactive.perl:588
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -7027,8 +7445,8 @@ msgstr ""
 "*          — избиране на всички обекти\n"
 "           — (празно) завършване на избирането\n"
 
-#: builtin/clean.c:522 git-add--interactive.perl:547
-#: git-add--interactive.perl:552
+#: builtin/clean.c:522 git-add--interactive.perl:554
+#: git-add--interactive.perl:559
 #, c-format, perl-format
 msgid "Huh (%s)?\n"
 msgstr "Неправилен избор (%s).\n"
@@ -7054,7 +7472,7 @@ msgid "Remove %s [y/N]? "
 msgstr "Да се изтрие ли „%s“? „y“ —  да, „N“ — НЕ"
 
 #
-#: builtin/clean.c:788 git-add--interactive.perl:1710
+#: builtin/clean.c:788 git-add--interactive.perl:1717
 #, c-format
 msgid "Bye.\n"
 msgstr "Изход.\n"
@@ -7077,11 +7495,11 @@ msgstr ""
 "help                — този край\n"
 "?                   — подсказка за шаблоните"
 
-#: builtin/clean.c:823 git-add--interactive.perl:1786
+#: builtin/clean.c:823 git-add--interactive.perl:1793
 msgid "*** Commands ***"
 msgstr "●●● Команди ●●●"
 
-#: builtin/clean.c:824 git-add--interactive.perl:1783
+#: builtin/clean.c:824 git-add--interactive.perl:1790
 msgid "What now"
 msgstr "Избор на следващо действие"
 
@@ -7151,148 +7569,150 @@ msgstr ""
 "което изисква някоя от опциите „-i“, „-n“ или „-f“.  Няма да се извърши "
 "изчистване"
 
-#: builtin/clone.c:40
+#: builtin/clone.c:42
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [ОПЦИЯ…] [--] ХРАНИЛИЩЕ [ДИРЕКТОРИЯ]"
 
-#: builtin/clone.c:85
+#: builtin/clone.c:87
 msgid "don't create a checkout"
 msgstr "без създаване на работно дърво"
 
-#: builtin/clone.c:86 builtin/clone.c:88 builtin/init-db.c:479
+#: builtin/clone.c:88 builtin/clone.c:90 builtin/init-db.c:479
 msgid "create a bare repository"
 msgstr "създаване на голо хранилище"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:92
 msgid "create a mirror repository (implies bare)"
 msgstr ""
 "създаване на хранилище-огледало (включва опцията „--bare“ за голо хранилище)"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:94
 msgid "to clone from a local repository"
 msgstr "клониране от локално хранилище"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:96
 msgid "don't use local hardlinks, always copy"
 msgstr "без твърди връзки, файловете винаги да се копират"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:98
 msgid "setup as shared repository"
 msgstr "настройване за споделено хранилище"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "pathspec"
 msgstr "път"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "initialize submodules in the clone"
 msgstr "инициализиране на подмодулите при това клониране"
 
-#: builtin/clone.c:105
+#: builtin/clone.c:107
 msgid "number of submodules cloned in parallel"
 msgstr "брой подмодули, клонирани паралелно"
 
-#: builtin/clone.c:106 builtin/init-db.c:476
+#: builtin/clone.c:108 builtin/init-db.c:476
 msgid "template-directory"
 msgstr "директория с шаблони"
 
-#: builtin/clone.c:107 builtin/init-db.c:477
+#: builtin/clone.c:109 builtin/init-db.c:477
 msgid "directory from which templates will be used"
 msgstr "директория, която съдържа шаблоните, които да се ползват"
 
-#: builtin/clone.c:109 builtin/clone.c:111 builtin/submodule--helper.c:1210
-#: builtin/submodule--helper.c:1577
+#: builtin/clone.c:111 builtin/clone.c:113 builtin/submodule--helper.c:1223
+#: builtin/submodule--helper.c:1594
 msgid "reference repository"
 msgstr "еталонно хранилище"
 
-#: builtin/clone.c:113
+#: builtin/clone.c:115 builtin/submodule--helper.c:1225
+#: builtin/submodule--helper.c:1596
 msgid "use --reference only while cloning"
 msgstr "опцията „--reference“ може да се използва само при клониране"
 
-#: builtin/clone.c:114 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/clone.c:116 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/pack-objects.c:3166 builtin/repack.c:213
 msgid "name"
 msgstr "ИМЕ"
 
-#: builtin/clone.c:115
+#: builtin/clone.c:117
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "използване на това ИМЕ вместо „origin“ при проследяване на клони"
 
-#: builtin/clone.c:117
+#: builtin/clone.c:119
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "изтегляне на този КЛОН, а не соченият от отдалечения указател „HEAD“"
 
-#: builtin/clone.c:119
+#: builtin/clone.c:121
 msgid "path to git-upload-pack on the remote"
 msgstr "път към командата „git-upload-pack“ на отдалеченото хранилище"
 
-#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813
-#: builtin/pull.c:211
+#: builtin/clone.c:122 builtin/fetch.c:150 builtin/grep.c:813
+#: builtin/pull.c:216
 msgid "depth"
 msgstr "ДЪЛБОЧИНА"
 
-#: builtin/clone.c:121
+#: builtin/clone.c:123
 msgid "create a shallow clone of that depth"
 msgstr "плитко клониране до тази ДЪЛБОЧИНА"
 
-#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017
+#: builtin/clone.c:124 builtin/fetch.c:152 builtin/pack-objects.c:3157
 #: parse-options.h:154
 msgid "time"
 msgstr "ВРЕМЕ"
 
-#: builtin/clone.c:123
+#: builtin/clone.c:125
 msgid "create a shallow clone since a specific time"
 msgstr "плитко клониране до момент във времето"
 
-#: builtin/clone.c:124 builtin/fetch.c:155
+#: builtin/clone.c:126 builtin/fetch.c:154
 msgid "revision"
 msgstr "версия"
 
-#: builtin/clone.c:125 builtin/fetch.c:156
+#: builtin/clone.c:127 builtin/fetch.c:155
 msgid "deepen history of shallow clone, excluding rev"
 msgstr "задълбочаване на историята на плитко хранилище до изключващ указател"
 
-#: builtin/clone.c:127
+#: builtin/clone.c:129
 msgid "clone only one branch, HEAD or --branch"
 msgstr ""
 "клониране само на един клон — или сочения от отдалечения „HEAD“, или изрично "
 "зададения с „--branch“"
 
-#: builtin/clone.c:129
+#: builtin/clone.c:131
 msgid "don't clone any tags, and make later fetches not to follow them"
 msgstr ""
 "без клониране на етикети, като последващите доставяния няма да ги следят"
 
-#: builtin/clone.c:131
+#: builtin/clone.c:133
 msgid "any cloned submodules will be shallow"
 msgstr "всички клонирани подмодули ще са плитки"
 
-#: builtin/clone.c:132 builtin/init-db.c:485
+#: builtin/clone.c:134 builtin/init-db.c:485
 msgid "gitdir"
 msgstr "СЛУЖЕБНА_ДИРЕКТОРИЯ"
 
-#: builtin/clone.c:133 builtin/init-db.c:486
+#: builtin/clone.c:135 builtin/init-db.c:486
 msgid "separate git dir from working tree"
 msgstr "отделна СЛУЖЕБНА_ДИРЕКТОРИЯ за git извън работното дърво"
 
-#: builtin/clone.c:134
+#: builtin/clone.c:136
 msgid "key=value"
 msgstr "КЛЮЧ=СТОЙНОСТ"
 
-#: builtin/clone.c:135
+#: builtin/clone.c:137
 msgid "set config inside the new repository"
 msgstr "задаване на настройките на новото хранилище"
 
-#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224
-#: builtin/push.c:567
+#: builtin/clone.c:138 builtin/fetch.c:173 builtin/pull.c:229
+#: builtin/push.c:583
 msgid "use IPv4 addresses only"
 msgstr "само адреси IPv4"
 
-#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227
-#: builtin/push.c:569
+#: builtin/clone.c:140 builtin/fetch.c:175 builtin/pull.c:232
+#: builtin/push.c:585
 msgid "use IPv6 addresses only"
 msgstr "само адреси IPv6"
 
-#: builtin/clone.c:276
+#: builtin/clone.c:278
 msgid ""
 "No directory name could be guessed.\n"
 "Please specify a directory on the command line"
@@ -7300,43 +7720,43 @@ msgstr ""
 "Името на директорията не може да бъде отгатнато.\n"
 "Задайте директорията изрично на командния ред"
 
-#: builtin/clone.c:329
+#: builtin/clone.c:331
 #, c-format
 msgid "info: Could not add alternate for '%s': %s\n"
 msgstr ""
 "ПРЕДУПРЕЖДЕНИЕ: не може да се добави алтернативен източник на „%s“: %s\n"
 
-#: builtin/clone.c:401
+#: builtin/clone.c:403
 #, c-format
 msgid "failed to open '%s'"
 msgstr "директорията „%s“ не може да бъде отворена"
 
-#: builtin/clone.c:409
+#: builtin/clone.c:411
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "„%s“ съществува и не е директория"
 
-#: builtin/clone.c:423
+#: builtin/clone.c:425
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "не може да бъде получена информация чрез „stat“ за „%s“\n"
 
-#: builtin/clone.c:445
+#: builtin/clone.c:447
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "връзката „%s“ не може да бъде създадена"
 
-#: builtin/clone.c:449
+#: builtin/clone.c:451
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "файлът не може да бъде копиран като „%s“"
 
-#: builtin/clone.c:475
+#: builtin/clone.c:477
 #, c-format
 msgid "done.\n"
 msgstr "действието завърши.\n"
 
-#: builtin/clone.c:489
+#: builtin/clone.c:491
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -7347,103 +7767,103 @@ msgstr ""
 "клон в момента са изтеглени с командата „git status“.  Можете да\n"
 "завършите изтеглянето на клона с командата „git checkout -f HEAD“.\n"
 
-#: builtin/clone.c:566
+#: builtin/clone.c:568
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr ""
 "Клонът „%s“ от отдалеченото хранилище, което клонирате,\n"
 "и който следва да бъде изтеглен, не съществува."
 
-#: builtin/clone.c:661
+#: builtin/clone.c:663
 msgid "remote did not send all necessary objects"
 msgstr "отдалеченото хранилище не изпрати всички необходими обекти."
 
-#: builtin/clone.c:677
+#: builtin/clone.c:679
 #, c-format
 msgid "unable to update %s"
 msgstr "обектът „%s“ не може да бъде обновен"
 
-#: builtin/clone.c:726
+#: builtin/clone.c:728
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
 "указателят „HEAD“ от отдалеченото хранилище сочи към нещо,\n"
 "което не съществува.  Не може да се изтегли определен клон.\n"
 
-#: builtin/clone.c:756
+#: builtin/clone.c:758
 msgid "unable to checkout working tree"
 msgstr "работното дърво не може да бъде подготвено"
 
-#: builtin/clone.c:801
+#: builtin/clone.c:803
 msgid "unable to write parameters to config file"
 msgstr "настройките не могат да бъдат записани в конфигурационния файл"
 
-#: builtin/clone.c:864
+#: builtin/clone.c:866
 msgid "cannot repack to clean up"
 msgstr "не може да се извърши пакетиране за изчистване на файловете"
 
-#: builtin/clone.c:866
+#: builtin/clone.c:868
 msgid "cannot unlink temporary alternates file"
 msgstr "временният файл за алтернативни обекти не може да бъде изтрит"
 
-#: builtin/clone.c:906 builtin/receive-pack.c:1946
+#: builtin/clone.c:907 builtin/receive-pack.c:1947
 msgid "Too many arguments."
 msgstr "Прекалено много аргументи."
 
-#: builtin/clone.c:910
+#: builtin/clone.c:911
 msgid "You must specify a repository to clone."
 msgstr "Трябва да укажете кое хранилище искате да клонирате."
 
-#: builtin/clone.c:923
+#: builtin/clone.c:924
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "опциите „--bare“ и „--origin %s“ са несъвместими."
 
-#: builtin/clone.c:926
+#: builtin/clone.c:927
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "опциите „--bare“ и „--separate-git-dir“ са несъвместими."
 
-#: builtin/clone.c:939
+#: builtin/clone.c:940
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "не съществува хранилище „%s“"
 
-#: builtin/clone.c:945 builtin/fetch.c:1455
+#: builtin/clone.c:946 builtin/fetch.c:1460
 #, c-format
 msgid "depth %s is not a positive number"
 msgstr "дълбочината трябва да е положително цяло число, а не „%s“"
 
-#: builtin/clone.c:955
+#: builtin/clone.c:956
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr "целевият път „%s“ съществува и не е празна директория."
 
-#: builtin/clone.c:965
+#: builtin/clone.c:966
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "в „%s“ вече съществува работно дърво."
 
-#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270
-#: builtin/worktree.c:255 builtin/worktree.c:285
+#: builtin/clone.c:981 builtin/clone.c:1002 builtin/difftool.c:270
+#: builtin/worktree.c:246 builtin/worktree.c:276
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "родителските директории на „%s“ не могат да бъдат създадени"
 
-#: builtin/clone.c:985
+#: builtin/clone.c:986
 #, c-format
 msgid "could not create work tree dir '%s'"
 msgstr "работното дърво в „%s“ не може да бъде създадено."
 
-#: builtin/clone.c:1005
+#: builtin/clone.c:1006
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Клониране и създаване на голо хранилище в „%s“…\n"
 
-#: builtin/clone.c:1007
+#: builtin/clone.c:1008
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Клониране и създаване на хранилище в „%s“…\n"
 
-#: builtin/clone.c:1031
+#: builtin/clone.c:1032
 msgid ""
 "clone --recursive is not compatible with both --reference and --reference-if-"
 "able"
@@ -7520,7 +7940,7 @@ msgstr "Поле в знаци отдясно"
 msgid "Padding space between columns"
 msgstr "Поле в знаци между колоните"
 
-#: builtin/column.c:52
+#: builtin/column.c:51
 msgid "--command must be the first argument"
 msgstr "опцията „--command“ трябва да е първият аргумент"
 
@@ -7579,61 +7999,61 @@ msgstr ""
 "Чрез командата „git cherry-pick --continue“ ще продължите отбирането на\n"
 "останалите подавания.\n"
 
-#: builtin/commit.c:284
+#: builtin/commit.c:293
 msgid "failed to unpack HEAD tree object"
 msgstr "върховото дърво (HEAD tree object) не може да бъде извадено от пакет"
 
-#: builtin/commit.c:325
+#: builtin/commit.c:334
 msgid "unable to create temporary index"
 msgstr "временният индекс не може да бъде създаден"
 
-#: builtin/commit.c:331
+#: builtin/commit.c:340
 msgid "interactive add failed"
 msgstr "неуспешно интерактивно добавяне"
 
-#: builtin/commit.c:344
+#: builtin/commit.c:353
 msgid "unable to update temporary index"
 msgstr "временният индекс не може да бъде обновен"
 
-#: builtin/commit.c:346
+#: builtin/commit.c:355
 msgid "Failed to update main cache tree"
 msgstr "Дървото на основния кеш не може да бъде обновено"
 
-#: builtin/commit.c:371 builtin/commit.c:395 builtin/commit.c:444
+#: builtin/commit.c:380 builtin/commit.c:403 builtin/commit.c:449
 msgid "unable to write new_index file"
 msgstr "новият индекс не може да бъде записан"
 
-#: builtin/commit.c:427
+#: builtin/commit.c:432
 msgid "cannot do a partial commit during a merge."
 msgstr "по време на сливане не може да се извърши частично подаване."
 
-#: builtin/commit.c:429
+#: builtin/commit.c:434
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "по време на отбиране не може да се извърши частично подаване."
 
-#: builtin/commit.c:437
+#: builtin/commit.c:442
 msgid "cannot read the index"
 msgstr "индексът не може да бъде прочетен"
 
-#: builtin/commit.c:456
+#: builtin/commit.c:461
 msgid "unable to write temporary index file"
 msgstr "временният индекс не може да бъде записан"
 
-#: builtin/commit.c:553
+#: builtin/commit.c:558
 #, c-format
 msgid "commit '%s' lacks author header"
 msgstr "заглавната част за автор в подаването „%s“ липсва"
 
-#: builtin/commit.c:555
+#: builtin/commit.c:560
 #, c-format
 msgid "commit '%s' has malformed author line"
 msgstr "заглавната част за автор в подаването „%s“ е неправилна"
 
-#: builtin/commit.c:574
+#: builtin/commit.c:579
 msgid "malformed --author parameter"
 msgstr "неправилен параметър към опцията „--author“"
 
-#: builtin/commit.c:626
+#: builtin/commit.c:631
 msgid ""
 "unable to select a comment character that is not used\n"
 "in the current commit message"
@@ -7641,38 +8061,38 @@ msgstr ""
 "не може да се избере знак за коментар — в текущото съобщение за подаване са "
 "използвани всички подобни знаци"
 
-#: builtin/commit.c:663 builtin/commit.c:696 builtin/commit.c:1024
+#: builtin/commit.c:668 builtin/commit.c:701 builtin/commit.c:1029
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "следното подаване не може да бъде открито: %s"
 
-#: builtin/commit.c:675 builtin/shortlog.c:309
+#: builtin/commit.c:680 builtin/shortlog.c:316
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(изчитане на съобщението за подаване от стандартния вход)\n"
 
-#: builtin/commit.c:677
+#: builtin/commit.c:682
 msgid "could not read log from standard input"
 msgstr "съобщението за подаване не бе прочетено стандартния вход"
 
-#: builtin/commit.c:681
+#: builtin/commit.c:686
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "файлът със съобщението за подаване „%s“ не може да бъде прочетен"
 
-#: builtin/commit.c:710 builtin/commit.c:718
+#: builtin/commit.c:715 builtin/commit.c:723
 msgid "could not read SQUASH_MSG"
-msgstr "съобщението за смачкване SQUASH_MSG не може да бъде прочетено"
+msgstr "съобщението за вкарване SQUASH_MSG не може да бъде прочетено"
 
-#: builtin/commit.c:715
+#: builtin/commit.c:720
 msgid "could not read MERGE_MSG"
 msgstr "съобщението за сливане MERGE_MSG не може да бъде прочетено"
 
-#: builtin/commit.c:769
+#: builtin/commit.c:774
 msgid "could not write commit template"
 msgstr "шаблонът за подаване не може да бъде запазен"
 
-#: builtin/commit.c:787
+#: builtin/commit.c:792
 #, c-format
 msgid ""
 "\n"
@@ -7687,7 +8107,7 @@ msgstr ""
 "  %s\n"
 "и опитайте отново.\n"
 
-#: builtin/commit.c:792
+#: builtin/commit.c:797
 #, c-format
 msgid ""
 "\n"
@@ -7703,7 +8123,7 @@ msgstr ""
 "  %s\n"
 "и опитайте отново.\n"
 
-#: builtin/commit.c:805
+#: builtin/commit.c:810
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7712,7 +8132,7 @@ msgstr ""
 "Въведете съобщението за подаване на промените.  Редовете, които започват\n"
 "с „%c“, ще бъдат пропуснати, а празно съобщение преустановява подаването.\n"
 
-#: builtin/commit.c:813
+#: builtin/commit.c:818
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7723,154 +8143,154 @@ msgstr ""
 "с „%c“, също ще бъдат включени — може да ги изтриете вие.  Празно \n"
 "съобщение преустановява подаването.\n"
 
-#: builtin/commit.c:830
+#: builtin/commit.c:835
 #, c-format
 msgid "%sAuthor:    %.*s <%.*s>"
 msgstr "%sАвтор:   %.*s <%.*s>"
 
-#: builtin/commit.c:838
+#: builtin/commit.c:843
 #, c-format
 msgid "%sDate:      %s"
 msgstr "%sДата:    %s"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:850
 #, c-format
 msgid "%sCommitter: %.*s <%.*s>"
 msgstr "%sПодаващ: %.*s <%.*s>"
 
-#: builtin/commit.c:862
+#: builtin/commit.c:867
 msgid "Cannot read index"
 msgstr "Индексът не може да бъде прочетен"
 
-#: builtin/commit.c:928
+#: builtin/commit.c:933
 msgid "Error building trees"
 msgstr "Грешка при изграждане на дърветата"
 
-#: builtin/commit.c:942 builtin/tag.c:256
+#: builtin/commit.c:947 builtin/tag.c:257
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "Подайте съобщението с някоя от опциите „-m“ или „-F“.\n"
 
-#: builtin/commit.c:986
+#: builtin/commit.c:991
 #, c-format
 msgid "--author '%s' is not 'Name <email>' and matches no existing author"
 msgstr ""
 "Опцията „--author '%s'“ не отговаря на форма̀та „Име <е-поща>“ и не съвпада с "
 "никой автор"
 
-#: builtin/commit.c:1000
+#: builtin/commit.c:1005
 #, c-format
 msgid "Invalid ignored mode '%s'"
 msgstr "Неправилен режим за игнорираните файлове: „%s“"
 
-#: builtin/commit.c:1014 builtin/commit.c:1264
+#: builtin/commit.c:1019 builtin/commit.c:1269
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "Неправилен режим за неследените файлове: „%s“"
 
-#: builtin/commit.c:1052
+#: builtin/commit.c:1057
 msgid "--long and -z are incompatible"
 msgstr "Опциите „--long“ и „-z“ са несъвместими."
 
-#: builtin/commit.c:1085
+#: builtin/commit.c:1090
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "Опциите „--reset-author“ и „--author“ са несъвместими."
 
-#: builtin/commit.c:1094
+#: builtin/commit.c:1099
 msgid "You have nothing to amend."
 msgstr "Няма какво да бъде поправено."
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1102
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "В момента се извършва сливане, не можете да поправяте."
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1104
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "В момента се извършва отбиране на подаване, не можете да поправяте."
 
-#: builtin/commit.c:1102
+#: builtin/commit.c:1107
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "Опциите „--squash“ и „--fixup“ са несъвместими."
 
-#: builtin/commit.c:1112
+#: builtin/commit.c:1117
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "Опциите „-c“, „-C“, „-F“ и „--fixup““ са несъвместими."
 
-#: builtin/commit.c:1114
+#: builtin/commit.c:1119
 msgid "Option -m cannot be combined with -c/-C/-F."
 msgstr "Опцията „-m“ е несъвместима с „-c“, „-C“ и „-F“."
 
-#: builtin/commit.c:1122
+#: builtin/commit.c:1127
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr ""
 "Опцията „--reset-author“ може да се използва само заедно с „-C“, „-c“ или\n"
 "„--amend“."
 
-#: builtin/commit.c:1139
+#: builtin/commit.c:1144
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 "Опциите „--include“, „--only“, „--all“, „--interactive“ и „--patch“ са\n"
 "несъвместими."
 
-#: builtin/commit.c:1141
+#: builtin/commit.c:1146
 msgid "No paths with --include/--only does not make sense."
 msgstr "Опциите „--include“ и „--only“ изискват аргументи."
 
-#: builtin/commit.c:1155 builtin/tag.c:542
+#: builtin/commit.c:1160 builtin/tag.c:543
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Несъществуващ режим на изчистване „%s“"
 
-#: builtin/commit.c:1160
+#: builtin/commit.c:1165
 msgid "Paths with -a does not make sense."
 msgstr "Опцията „-a“ е несъвместима със задаването на пътища."
 
-#: builtin/commit.c:1278 builtin/commit.c:1443
+#: builtin/commit.c:1303 builtin/commit.c:1480
 msgid "show status concisely"
 msgstr "кратка информация за състоянието"
 
-#: builtin/commit.c:1280 builtin/commit.c:1445
+#: builtin/commit.c:1305 builtin/commit.c:1482
 msgid "show branch information"
 msgstr "информация за клоните"
 
-#: builtin/commit.c:1282
+#: builtin/commit.c:1307
 msgid "show stash information"
 msgstr "информация за скатаното"
 
-#: builtin/commit.c:1284 builtin/commit.c:1447
+#: builtin/commit.c:1309 builtin/commit.c:1484
 msgid "compute full ahead/behind values"
 msgstr "изчисляване на точните стойности напред/назад"
 
-#: builtin/commit.c:1286
+#: builtin/commit.c:1311
 msgid "version"
 msgstr "версия"
 
-#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542
-#: builtin/worktree.c:541
+#: builtin/commit.c:1311 builtin/commit.c:1486 builtin/push.c:558
+#: builtin/worktree.c:581
 msgid "machine-readable output"
 msgstr "формат на изхода за четене от програма"
 
-#: builtin/commit.c:1289 builtin/commit.c:1451
+#: builtin/commit.c:1314 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "подробна информация за състоянието (стандартно)"
 
-#: builtin/commit.c:1292 builtin/commit.c:1454
+#: builtin/commit.c:1317 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "разделяне на елементите с нулевия знак „NUL“"
 
-#: builtin/commit.c:1294 builtin/commit.c:1298 builtin/commit.c:1457
-#: builtin/fast-export.c:999 builtin/fast-export.c:1002 builtin/tag.c:396
+#: builtin/commit.c:1319 builtin/commit.c:1323 builtin/commit.c:1494
+#: builtin/fast-export.c:1001 builtin/fast-export.c:1004 builtin/tag.c:397
 msgid "mode"
 msgstr "РЕЖИМ"
 
-#: builtin/commit.c:1295 builtin/commit.c:1457
+#: builtin/commit.c:1320 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
 "извеждане на неследените файлове.  Възможните РЕЖИМи са „all“ (подробна "
 "информация), „normal“ (кратка информация), „no“ (без неследените файлове).  "
 "Стандартният РЕЖИМ е: „all“."
 
-#: builtin/commit.c:1299
+#: builtin/commit.c:1324
 msgid ""
 "show ignored files, optional modes: traditional, matching, no. (Default: "
 "traditional)"
@@ -7879,11 +8299,11 @@ msgstr ""
 "„traditional“ (традиционен), „matching“ (напасващи), „no“ (без игнорираните "
 "файлове).  Стандартният РЕЖИМ е: „traditional“."
 
-#: builtin/commit.c:1301 parse-options.h:167
+#: builtin/commit.c:1326 parse-options.h:167
 msgid "when"
 msgstr "КОГА"
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1327
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
@@ -7892,190 +8312,198 @@ msgstr ""
 "една от „all“ (всички), „dirty“ (тези с неподадени промени), "
 "„untracked“ (неследени)"
 
-#: builtin/commit.c:1304
+#: builtin/commit.c:1329
 msgid "list untracked files in columns"
 msgstr "извеждане на неследените файлове в колони"
 
-#: builtin/commit.c:1323
+#: builtin/commit.c:1330
+msgid "do not detect renames"
+msgstr "без засичане на преименуванията"
+
+#: builtin/commit.c:1332
+msgid "detect renames, optionally set similarity index"
+msgstr "засичане на преименуванията, може да се зададе коефициент на прилика"
+
+#: builtin/commit.c:1352
 msgid "Unsupported combination of ignored and untracked-files arguments"
 msgstr "Неподдържана комбинация от аргументи за игнорирани и неследени файлове"
 
-#: builtin/commit.c:1413
+#: builtin/commit.c:1450
 msgid "suppress summary after successful commit"
 msgstr "без информация след успешно подаване"
 
-#: builtin/commit.c:1414
+#: builtin/commit.c:1451
 msgid "show diff in commit message template"
 msgstr "добавяне на разликата към шаблона за съобщението при подаване"
 
-#: builtin/commit.c:1416
+#: builtin/commit.c:1453
 msgid "Commit message options"
 msgstr "Опции за съобщението при подаване"
 
-#: builtin/commit.c:1417 builtin/tag.c:393
+#: builtin/commit.c:1454 builtin/tag.c:394
 msgid "read message from file"
 msgstr "взимане на съобщението от ФАЙЛ"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "author"
 msgstr "АВТОР"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "override author for commit"
 msgstr "задаване на АВТОР за подаването"
 
-#: builtin/commit.c:1419 builtin/gc.c:359
+#: builtin/commit.c:1456 builtin/gc.c:501
 msgid "date"
 msgstr "ДАТА"
 
-#: builtin/commit.c:1419
+#: builtin/commit.c:1456
 msgid "override date for commit"
 msgstr "задаване на ДАТА за подаването"
 
-#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402
-#: builtin/notes.c:565 builtin/tag.c:391
+#: builtin/commit.c:1457 builtin/merge.c:228 builtin/notes.c:402
+#: builtin/notes.c:565 builtin/tag.c:392
 msgid "message"
 msgstr "СЪОБЩЕНИЕ"
 
-#: builtin/commit.c:1420
+#: builtin/commit.c:1457
 msgid "commit message"
 msgstr "СЪОБЩЕНИЕ при подаване"
 
-#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423
-#: builtin/commit.c:1424 parse-options.h:269 ref-filter.h:92
+#: builtin/commit.c:1458 builtin/commit.c:1459 builtin/commit.c:1460
+#: builtin/commit.c:1461 parse-options.h:270 ref-filter.h:92
 msgid "commit"
 msgstr "ПОДАВАНЕ"
 
-#: builtin/commit.c:1421
+#: builtin/commit.c:1458
 msgid "reuse and edit message from specified commit"
 msgstr "преизползване и редактиране на съобщението от указаното ПОДАВАНЕ"
 
-#: builtin/commit.c:1422
+#: builtin/commit.c:1459
 msgid "reuse message from specified commit"
 msgstr "преизползване на съобщението от указаното ПОДАВАНЕ"
 
-#: builtin/commit.c:1423
+#: builtin/commit.c:1460
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
-"използване Ð½Ð° Ð°Ð²Ñ\82омаÑ\82иÑ\87ноÑ\82о Ñ\81Ñ\8aобÑ\89ение Ð¿Ñ\80и Ñ\81маÑ\87кване Ð·Ð° Ð²ÐºÐ°Ñ\80ване Ð½Ð° Ñ\83казаноÑ\82о "
-"Ð\9fÐ\9eÐ\94Ð\90Ð\92Ð\90Ð\9dÐ\95 Ð² Ð¿Ñ\80едното без следа"
+"използване Ð½Ð° Ð°Ð²Ñ\82омаÑ\82иÑ\87ноÑ\82о Ñ\81Ñ\8aобÑ\89ение Ð·Ð° Ð²ÐºÐ°Ñ\80ване Ð½Ð° Ñ\83казаноÑ\82о Ð\9fÐ\9eÐ\94Ð\90Ð\92Ð\90Ð\9dÐ\95 Ð² "
+"пÑ\80едÑ\85одното без следа"
 
-#: builtin/commit.c:1424
+#: builtin/commit.c:1461
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
-"използване Ð½Ð° Ð°Ð²Ñ\82омаÑ\82иÑ\87ноÑ\82о Ñ\81Ñ\8aобÑ\89ение Ð¿Ñ\80и Ñ\81маÑ\87кване Ð·Ð° Ñ\81маÑ\87кване Ð½Ð° "
-"указаното ПОДАВАНЕ в предното"
+"използване Ð½Ð° Ð°Ð²Ñ\82омаÑ\82иÑ\87ноÑ\82о Ñ\81Ñ\8aобÑ\89ение Ð·Ð° Ð²ÐºÐ°Ñ\80ване Ð½Ð° Ñ\83казаноÑ\82о Ð\9fÐ\9eÐ\94Ð\90Ð\92Ð\90Ð\9dÐ\95 Ð² "
+"предното"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1462
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr ""
 "смяна на автора да съвпада с подаващия (използва се с „-C“/„-c“/„--amend“)"
 
-#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240
-#: builtin/pull.c:149 builtin/revert.c:105
+#: builtin/commit.c:1463 builtin/log.c:1446 builtin/merge.c:242
+#: builtin/pull.c:154 builtin/revert.c:105
 msgid "add Signed-off-by:"
 msgstr "добавяне на поле за подпис — „Signed-off-by:“"
 
-#: builtin/commit.c:1427
+#: builtin/commit.c:1464
 msgid "use specified template file"
 msgstr "използване на указания шаблонен ФАЙЛ"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1465
 msgid "force edit of commit"
 msgstr "редактиране на подаване"
 
-#: builtin/commit.c:1429
+#: builtin/commit.c:1466
 msgid "default"
 msgstr "стандартно"
 
-#: builtin/commit.c:1429 builtin/tag.c:397
+#: builtin/commit.c:1466 builtin/tag.c:398
 msgid "how to strip spaces and #comments from message"
 msgstr "кои празни знаци и #коментари да се махат от съобщенията"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1467
 msgid "include status in commit message template"
 msgstr "вмъкване на състоянието в шаблона за съобщението при подаване"
 
-#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179
+#: builtin/commit.c:1469 builtin/merge.c:240 builtin/pull.c:184
 #: builtin/revert.c:113
 msgid "GPG sign commit"
 msgstr "подписване на подаването с GPG"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1472
 msgid "Commit contents options"
 msgstr "Опции за избор на файлове при подаване"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1473
 msgid "commit all changed files"
 msgstr "подаване на всички променени файлове"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1474
 msgid "add specified files to index for commit"
 msgstr "добавяне на указаните файлове към индекса за подаване"
 
-#: builtin/commit.c:1438
+#: builtin/commit.c:1475
 msgid "interactively add files"
 msgstr "интерактивно добавяне на файлове"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1476
 msgid "interactively add changes"
 msgstr "интерактивно добавяне на промени"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1477
 msgid "commit only specified files"
 msgstr "подаване само на указаните файлове"
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1478
 msgid "bypass pre-commit and commit-msg hooks"
 msgstr ""
 "без изпълнение на куките преди подаване и при промяна на съобщението за "
 "подаване (pre-commit и commit-msg)"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1479
 msgid "show what would be committed"
 msgstr "отпечатване на това, което би било подадено"
 
-#: builtin/commit.c:1455
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "поправяне на предишното подаване"
 
-#: builtin/commit.c:1456
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "без изпълнение на куката след презаписване (post-rewrite)"
 
-#: builtin/commit.c:1461
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "позволяване на празни подавания"
 
-#: builtin/commit.c:1463
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "позволяване на подавания с празни съобщения"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1573
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Повреден файл за върха за сливането „MERGE_HEAD“ (%s)"
 
-#: builtin/commit.c:1543
+#: builtin/commit.c:1580
 msgid "could not read MERGE_MODE"
 msgstr "режимът на сливане „MERGE_MODE“ не може да бъде прочетен"
 
-#: builtin/commit.c:1562
+#: builtin/commit.c:1599
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "съобщението за подаване не може да бъде прочетено: %s"
 
-#: builtin/commit.c:1573
+#: builtin/commit.c:1610
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "Неизвършване на подаване поради празно съобщение.\n"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1615
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "Неизвършване на подаване поради нередактирано съобщение.\n"
 
-#: builtin/commit.c:1613
+#: builtin/commit.c:1650
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full and quota is\n"
@@ -8085,154 +8513,220 @@ msgstr ""
 "не е записан.  Проверете дали дискът не е препълнен или не сте\n"
 "превишили дисковата си квота.  След това изпълнете „git reset HEAD“."
 
+#: builtin/commit-graph.c:9
+msgid "git commit-graph [--object-dir <objdir>]"
+msgstr "git commit-graph [--object-dir ДИР_ОБЕКТИ]"
+
+#: builtin/commit-graph.c:10 builtin/commit-graph.c:16
+msgid "git commit-graph read [--object-dir <objdir>]"
+msgstr "git commit-graph read [--object-dir ДИР_ОБЕКТИ]"
+
+#: builtin/commit-graph.c:11 builtin/commit-graph.c:21
+msgid ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+msgstr ""
+"git commit-graph write [--object-dir ДИР_ОБЕКТИ] [--append] [--stdin-packs|--"
+"stdin-commits]"
+
+#: builtin/commit-graph.c:39 builtin/commit-graph.c:92
+#: builtin/commit-graph.c:147 builtin/fetch.c:161 builtin/log.c:1466
+msgid "dir"
+msgstr "директория"
+
+#: builtin/commit-graph.c:40 builtin/commit-graph.c:93
+#: builtin/commit-graph.c:148
+msgid "The object directory to store the graph"
+msgstr "ДИРекторията_с_ОБЕКТИ за запазване на гра̀фа"
+
+#: builtin/commit-graph.c:95
+msgid "scan pack-indexes listed by stdin for commits"
+msgstr ""
+"проверка на подаванията за индексите на пакетите изброени на командния ред"
+
+#: builtin/commit-graph.c:97
+msgid "start walk at commits listed by stdin"
+msgstr "започване на обхождането при подаванията подадени на стандартния вход"
+
+#: builtin/commit-graph.c:99
+msgid "include all commits already in the commit-graph file"
+msgstr ""
+"включване на всички подавания, които вече са във файла с гра̀фа на подаванията"
+
+#: builtin/commit-graph.c:108
+msgid "cannot use both --stdin-commits and --stdin-packs"
+msgstr "опциите „--stdin-commits“ и „--stdin-packs“ са несъвместими"
+
 #: builtin/config.c:10
 msgid "git config [<options>]"
 msgstr "git config [ОПЦИЯ…]"
 
-#: builtin/config.c:58
+#: builtin/config.c:101
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "непознат аргумент „--type“: %s"
+
+#: builtin/config.c:123
 msgid "Config file location"
 msgstr "Местоположение на конфигурационния файл"
 
-#: builtin/config.c:59
+#: builtin/config.c:124
 msgid "use global config file"
 msgstr "използване на глобалния конфигурационен файл"
 
-#: builtin/config.c:60
+#: builtin/config.c:125
 msgid "use system config file"
 msgstr "използване на системния конфигурационен файл"
 
-#: builtin/config.c:61
+#: builtin/config.c:126
 msgid "use repository config file"
 msgstr "използване на конфигурационния файл на хранилището"
 
-#: builtin/config.c:62
+#: builtin/config.c:127
 msgid "use given config file"
 msgstr "използване на зададения конфигурационен ФАЙЛ"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "blob-id"
 msgstr "ИДЕНТИФИКАТОР"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "read config from given blob object"
 msgstr ""
 "изчитане на конфигурацията от BLOB с този ИДЕНТИФИКАТОР на съдържанието"
 
-#: builtin/config.c:64
+#: builtin/config.c:129
 msgid "Action"
 msgstr "Действие"
 
-#: builtin/config.c:65
+#: builtin/config.c:130
 msgid "get value: name [value-regex]"
 msgstr "извеждане на стойност: ИМЕ [РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:66
+#: builtin/config.c:131
 msgid "get all values: key [value-regex]"
 msgstr "извеждане на всички стойности: ключ [РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:67
+#: builtin/config.c:132
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr ""
 "извеждане на стойностите за РЕГУЛЯРНия_ИЗРАЗ: РЕГУЛЯРЕН_ИЗРАЗ_ЗА_ИМЕТО "
 "[РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:68
+#: builtin/config.c:133
 msgid "get value specific for the URL: section[.var] URL"
 msgstr "извеждане на стойността за указания адрес: РАЗДЕЛ[.ПРОМЕНЛИВА] АДРЕС"
 
-#: builtin/config.c:69
+#: builtin/config.c:134
 msgid "replace all matching variables: name value [value_regex]"
 msgstr ""
 "замяна на всички съвпадащи променливи: ИМЕ СТОЙНОСТ "
 "[РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:70
+#: builtin/config.c:135
 msgid "add a new variable: name value"
 msgstr "добавяне на нова променлива: ИМЕ СТОЙНОСТ"
 
-#: builtin/config.c:71
+#: builtin/config.c:136
 msgid "remove a variable: name [value-regex]"
 msgstr "изтриване на променлива: ИМЕ [РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:72
+#: builtin/config.c:137
 msgid "remove all matches: name [value-regex]"
 msgstr "изтриване на всички съвпадащи: ИМЕ [РЕГУЛЯРЕН_ИЗРАЗ_ЗА_СТОЙНОСТТА]"
 
-#: builtin/config.c:73
+#: builtin/config.c:138
 msgid "rename section: old-name new-name"
 msgstr "преименуване на раздел: СТАРО_ИМЕ НОВО_ИМЕ"
 
-#: builtin/config.c:74
+#: builtin/config.c:139
 msgid "remove a section: name"
 msgstr "изтриване на раздел: ИМЕ"
 
-#: builtin/config.c:75
+#: builtin/config.c:140
 msgid "list all"
 msgstr "изброяване на всички"
 
-#: builtin/config.c:76
+#: builtin/config.c:141
 msgid "open an editor"
 msgstr "отваряне на редактор"
 
-#: builtin/config.c:77
+#: builtin/config.c:142
 msgid "find the color configured: slot [default]"
 msgstr "извеждане на зададения цвят: номер [стандартно]"
 
-#: builtin/config.c:78
+#: builtin/config.c:143
 msgid "find the color setting: slot [stdout-is-tty]"
 msgstr "извеждане на зададения цвят: номер (стандартният изход е терминал)"
 
-#: builtin/config.c:79
+#: builtin/config.c:144
 msgid "Type"
 msgstr "Вид"
 
-#: builtin/config.c:80
+#: builtin/config.c:145
+msgid "value is given this type"
+msgstr "стойността е от този вид"
+
+#: builtin/config.c:146
 msgid "value is \"true\" or \"false\""
 msgstr "СТОЙНОСТТА е „true“ (истина) или „false“ (лъжа)"
 
-#: builtin/config.c:81
+#: builtin/config.c:147
 msgid "value is decimal number"
 msgstr "СТОЙНОСТТА е цяло, десетично число"
 
-#: builtin/config.c:82
+#: builtin/config.c:148
 msgid "value is --bool or --int"
 msgstr "СТОЙНОСТТА е „--bool“ (булева) или „--int“ (десетично цяло число)"
 
-#: builtin/config.c:83
+#: builtin/config.c:149
 msgid "value is a path (file or directory name)"
 msgstr "СТОЙНОСТТА е път (до файл или директория)"
 
-#: builtin/config.c:84
+#: builtin/config.c:150
 msgid "value is an expiry date"
 msgstr "стойността е период на валидност/запазване"
 
-#: builtin/config.c:85
+#: builtin/config.c:151
 msgid "Other"
 msgstr "Други"
 
-#: builtin/config.c:86
+#: builtin/config.c:152
 msgid "terminate values with NUL byte"
 msgstr "разделяне на стойностите с нулевия знак „NUL“"
 
-#: builtin/config.c:87
+#: builtin/config.c:153
 msgid "show variable names only"
 msgstr "извеждане на имената на променливите"
 
-#: builtin/config.c:88
+#: builtin/config.c:154
 msgid "respect include directives on lookup"
 msgstr "при търсене да се уважат и директивите за включване"
 
-#: builtin/config.c:89
+#: builtin/config.c:155
 msgid "show origin of config (file, standard input, blob, command line)"
 msgstr ""
 "извеждане на мястото на задаване на настройката (файл, стандартен вход, "
-"обект BLOB, команден ред)"
+"обект-BLOB, команден ред)"
+
+#: builtin/config.c:156
+msgid "value"
+msgstr "СТОЙНОСТ"
 
-#: builtin/config.c:335
+#: builtin/config.c:156
+msgid "with --get, use default value when missing entry"
+msgstr "с „--get“ се използва стандартна СТОЙНОСТ при липсваща"
+
+#: builtin/config.c:332
+#, c-format
+msgid "failed to format default config value: %s"
+msgstr "неуспешно форматиране на стандартната стойност на настройка: %s"
+
+#: builtin/config.c:431
 msgid "unable to parse default color value"
 msgstr "неразпозната стойност на стандартния цвят"
 
-#: builtin/config.c:479
+#: builtin/config.c:575
 #, c-format
 msgid ""
 "# This is Git's per-user configuration file.\n"
@@ -8247,16 +8741,20 @@ msgstr ""
 "#\tname = %s\n"
 "#\temail = %s\n"
 
-#: builtin/config.c:507
+#: builtin/config.c:603
 msgid "--local can only be used inside a git repository"
 msgstr "„--local“ може да се използва само в хранилище"
 
-#: builtin/config.c:632
+#: builtin/config.c:606
+msgid "--blob can only be used inside a git repository"
+msgstr "„--blob“ може да се използва само в хранилище"
+
+#: builtin/config.c:735
 #, c-format
 msgid "cannot create configuration file %s"
 msgstr "конфигурационният файл „%s“ не може да бъде създаден"
 
-#: builtin/config.c:645
+#: builtin/config.c:748
 #, c-format
 msgid ""
 "cannot overwrite multiple values with a single value\n"
@@ -8266,11 +8764,11 @@ msgstr ""
 "За да промените „%s“, ползвайте регулярен израз или опциите „--add“ и „--"
 "replace-all“."
 
-#: builtin/count-objects.c:88
+#: builtin/count-objects.c:90
 msgid "git count-objects [-v] [-H | --human-readable]"
 msgstr "git count-objects [-v] [-H | --human-readable]"
 
-#: builtin/count-objects.c:98
+#: builtin/count-objects.c:100
 msgid "print sizes in human readable format"
 msgstr "извеждане на размерите на обектите във формат лесно четим от хора"
 
@@ -8369,7 +8867,7 @@ msgstr "Неправилно име на обект „%s“"
 #: builtin/describe.c:508
 #, c-format
 msgid "%s is neither a commit nor blob"
-msgstr "„%s“ не е нито подаване, нито обект BLOB"
+msgstr "„%s“ не е нито подаване, нито обект-BLOB"
 
 #: builtin/describe.c:522
 msgid "find the tag that comes after the commit"
@@ -8468,7 +8966,7 @@ msgstr "зададен е неправилен обект „%s“."
 #: builtin/diff.c:408
 #, c-format
 msgid "more than two blobs given: '%s'"
-msgstr "зададени са повече от 2 обекта BLOB: „%s“"
+msgstr "зададени са повече от 2 обекта-BLOB: „%s“"
 
 #: builtin/diff.c:413
 #, c-format
@@ -8537,25 +9035,25 @@ msgstr "разлика по директории"
 msgid "do not prompt before launching a diff tool"
 msgstr "стартиране на ПРОГРАМАта за разлики без предупреждение"
 
-#: builtin/difftool.c:705
+#: builtin/difftool.c:704
 msgid "use symlinks in dir-diff mode"
 msgstr "следване на символните връзки при разлика по директории"
 
-#: builtin/difftool.c:706
+#: builtin/difftool.c:705
 msgid "<tool>"
 msgstr "ПРОГРАМА"
 
-#: builtin/difftool.c:707
+#: builtin/difftool.c:706
 msgid "use the specified diff tool"
 msgstr "използване на указаната ПРОГРАМА"
 
-#: builtin/difftool.c:709
+#: builtin/difftool.c:708
 msgid "print a list of diff tools that may be used with `--tool`"
 msgstr ""
 "извеждане на списък с всички ПРОГРАМи, които може да се ползват с опцията „--"
 "tool“"
 
-#: builtin/difftool.c:712
+#: builtin/difftool.c:711
 msgid ""
 "make 'git-difftool' exit when an invoked diff tool returns a non - zero exit "
 "code"
@@ -8563,169 +9061,165 @@ msgstr ""
 "„git-difftool“ да спре работа, когато стартираната ПРОГРАМА завърши с "
 "ненулев код"
 
-#: builtin/difftool.c:714
+#: builtin/difftool.c:713
 msgid "<command>"
 msgstr "КОМАНДА"
 
-#: builtin/difftool.c:715
+#: builtin/difftool.c:714
 msgid "specify a custom command for viewing diffs"
 msgstr "команда за разглеждане на разлики"
 
-#: builtin/difftool.c:739
+#: builtin/difftool.c:738
 msgid "no <tool> given for --tool=<tool>"
 msgstr "не е зададена програма за „--tool=ПРОГРАМА“"
 
-#: builtin/difftool.c:746
+#: builtin/difftool.c:745
 msgid "no <cmd> given for --extcmd=<cmd>"
 msgstr "не е зададена команда за „--extcmd=КОМАНДА“"
 
-#: builtin/fast-export.c:26
+#: builtin/fast-export.c:27
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [ОПЦИИ_ЗА_СПИСЪКА_С_ВЕРСИИ]"
 
-#: builtin/fast-export.c:998
+#: builtin/fast-export.c:1000
 msgid "show progress after <n> objects"
 msgstr "Съобщение за напредъка на всеки такъв БРОЙ обекта"
 
-#: builtin/fast-export.c:1000
+#: builtin/fast-export.c:1002
 msgid "select handling of signed tags"
 msgstr "Как да се обработват подписаните етикети"
 
-#: builtin/fast-export.c:1003
+#: builtin/fast-export.c:1005
 msgid "select handling of tags that tag filtered objects"
 msgstr "Как да се обработват етикетите на филтрираните обекти"
 
-#: builtin/fast-export.c:1006
+#: builtin/fast-export.c:1008
 msgid "Dump marks to this file"
 msgstr "Запазване на маркерите в този ФАЙЛ"
 
-#: builtin/fast-export.c:1008
+#: builtin/fast-export.c:1010
 msgid "Import marks from this file"
 msgstr "Внасяне на маркерите от този ФАЙЛ"
 
-#: builtin/fast-export.c:1010
+#: builtin/fast-export.c:1012
 msgid "Fake a tagger when tags lack one"
 msgstr "Да се използва изкуствено име на човек при липса на задаващ етикета"
 
-#: builtin/fast-export.c:1012
+#: builtin/fast-export.c:1014
 msgid "Output full tree for each commit"
 msgstr "Извеждане на цялото дърво за всяко подаване"
 
-#: builtin/fast-export.c:1014
+#: builtin/fast-export.c:1016
 msgid "Use the done feature to terminate the stream"
 msgstr "Използване на маркер за завършване на потока"
 
-#: builtin/fast-export.c:1015
+#: builtin/fast-export.c:1017
 msgid "Skip output of blob data"
-msgstr "Без извеждане на съдържанието на обектите BLOB"
+msgstr "Без извеждане на съдържанието на обектите-BLOB"
 
-#: builtin/fast-export.c:1016
+#: builtin/fast-export.c:1018
 msgid "refspec"
 msgstr "УКАЗАТЕЛ_НА_ВЕРСИЯ"
 
-#: builtin/fast-export.c:1017
+#: builtin/fast-export.c:1019
 msgid "Apply refspec to exported refs"
 msgstr "Прилагане на УКАЗАТЕЛя_НА_ВЕРСИЯ към изнесените указатели"
 
-#: builtin/fast-export.c:1018
+#: builtin/fast-export.c:1020
 msgid "anonymize output"
 msgstr "анонимизиране на извежданата информация"
 
-#: builtin/fetch.c:25
+#: builtin/fetch.c:26
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
 msgstr "git fetch [ОПЦИЯ…] [ХРАНИЛИЩЕ [УКАЗАТЕЛ…]]"
 
-#: builtin/fetch.c:26
+#: builtin/fetch.c:27
 msgid "git fetch [<options>] <group>"
 msgstr "git fetch [ОПЦИЯ…] ГРУПА"
 
-#: builtin/fetch.c:27
+#: builtin/fetch.c:28
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
 msgstr "git fetch --multiple [ОПЦИЯ…] [(ХРАНИЛИЩЕ | ГРУПА)…]"
 
-#: builtin/fetch.c:28
+#: builtin/fetch.c:29
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [ОПЦИЯ…]"
 
-#: builtin/fetch.c:124 builtin/pull.c:188
+#: builtin/fetch.c:123 builtin/pull.c:193
 msgid "fetch from all remotes"
 msgstr "доставяне от всички отдалечени хранилища"
 
-#: builtin/fetch.c:126 builtin/pull.c:191
+#: builtin/fetch.c:125 builtin/pull.c:196
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "добавяне към „.git/FETCH_HEAD“ вместо замяна"
 
-#: builtin/fetch.c:128 builtin/pull.c:194
+#: builtin/fetch.c:127 builtin/pull.c:199
 msgid "path to upload pack on remote end"
 msgstr "отдалечен път, където да се качи пакетът"
 
-#: builtin/fetch.c:129 builtin/pull.c:196
+#: builtin/fetch.c:128 builtin/pull.c:201
 msgid "force overwrite of local branch"
 msgstr "принудително презаписване на локалния клон"
 
-#: builtin/fetch.c:131
+#: builtin/fetch.c:130
 msgid "fetch from multiple remotes"
 msgstr "доставяне от множество отдалечени хранилища"
 
-#: builtin/fetch.c:133 builtin/pull.c:198
+#: builtin/fetch.c:132 builtin/pull.c:203
 msgid "fetch all tags and associated objects"
 msgstr "доставяне на всички етикети и принадлежащи обекти"
 
-#: builtin/fetch.c:135
+#: builtin/fetch.c:134
 msgid "do not fetch all tags (--no-tags)"
 msgstr "без доставянето на всички етикети „--no-tags“"
 
-#: builtin/fetch.c:137
+#: builtin/fetch.c:136
 msgid "number of submodules fetched in parallel"
 msgstr "брой подмодули доставени паралелно"
 
-#: builtin/fetch.c:139 builtin/pull.c:201
+#: builtin/fetch.c:138 builtin/pull.c:206
 msgid "prune remote-tracking branches no longer on remote"
 msgstr "окастряне на клоните следящи вече несъществуващи отдалечени клони"
 
-#: builtin/fetch.c:141
+#: builtin/fetch.c:140
 msgid "prune local tags no longer on remote and clobber changed tags"
 msgstr ""
 "окастряне на локалните етикети, които вече не съществуват в отдалеченото "
 "хранилище и махане на променените"
 
-#: builtin/fetch.c:142 builtin/fetch.c:165 builtin/pull.c:126
+#: builtin/fetch.c:141 builtin/fetch.c:164 builtin/pull.c:131
 msgid "on-demand"
 msgstr "ПРИ НУЖДА"
 
-#: builtin/fetch.c:143
+#: builtin/fetch.c:142
 msgid "control recursive fetching of submodules"
 msgstr "управление на рекурсивното доставяне на подмодулите"
 
-#: builtin/fetch.c:147 builtin/pull.c:209
+#: builtin/fetch.c:146 builtin/pull.c:214
 msgid "keep downloaded pack"
 msgstr "запазване на изтеглените пакети с обекти"
 
-#: builtin/fetch.c:149
+#: builtin/fetch.c:148
 msgid "allow updating of HEAD ref"
 msgstr "позволяване на обновяването на указателя „HEAD“"
 
-#: builtin/fetch.c:152 builtin/fetch.c:158 builtin/pull.c:212
+#: builtin/fetch.c:151 builtin/fetch.c:157 builtin/pull.c:217
 msgid "deepen history of shallow clone"
 msgstr "задълбочаване на историята на плитко хранилище"
 
-#: builtin/fetch.c:154
+#: builtin/fetch.c:153
 msgid "deepen history of shallow repository based on time"
 msgstr "задълбочаване на историята на плитко хранилище до определено време"
 
-#: builtin/fetch.c:160 builtin/pull.c:215
+#: builtin/fetch.c:159 builtin/pull.c:220
 msgid "convert to a complete repository"
 msgstr "превръщане в пълно хранилище"
 
-#: builtin/fetch.c:162 builtin/log.c:1466
-msgid "dir"
-msgstr "директория"
-
-#: builtin/fetch.c:163
+#: builtin/fetch.c:162
 msgid "prepend this to submodule path output"
 msgstr "добавяне на това пред пътя на подмодула"
 
-#: builtin/fetch.c:166
+#: builtin/fetch.c:165
 msgid ""
 "default for recursive fetching of submodules (lower priority than config "
 "files)"
@@ -8733,91 +9227,101 @@ msgstr ""
 "стандартно рекурсивно изтегляне на подмодулите (файловете с настройки са с "
 "приоритет)"
 
-#: builtin/fetch.c:170 builtin/pull.c:218
+#: builtin/fetch.c:169 builtin/pull.c:223
 msgid "accept refs that update .git/shallow"
 msgstr "приемане на указатели, които обновяват „.git/shallow“"
 
-#: builtin/fetch.c:171 builtin/pull.c:220
+#: builtin/fetch.c:170 builtin/pull.c:225
 msgid "refmap"
 msgstr "КАРТА_С_УКАЗАТЕЛИ"
 
-#: builtin/fetch.c:172 builtin/pull.c:221
+#: builtin/fetch.c:171 builtin/pull.c:226
 msgid "specify fetch refmap"
 msgstr "указване на КАРТАта_С_УКАЗАТЕЛИ за доставяне"
 
-#: builtin/fetch.c:431
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:172
+msgid "server-specific"
+msgstr "специфични за сървъра"
+
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:173
+msgid "option to transmit"
+msgstr "опция за пренос"
+
+#: builtin/fetch.c:442
 msgid "Couldn't find remote ref HEAD"
 msgstr "Указателят „HEAD“ в отдалеченото хранилище не може да бъде открит"
 
-#: builtin/fetch.c:549
+#: builtin/fetch.c:560
 #, c-format
 msgid "configuration fetch.output contains invalid value %s"
 msgstr "настройката „fetch.output“ е с неправилна стойност „%s“"
 
-#: builtin/fetch.c:642
+#: builtin/fetch.c:653
 #, c-format
 msgid "object %s not found"
 msgstr "обектът „%s“ липсва"
 
-#: builtin/fetch.c:646
+#: builtin/fetch.c:657
 msgid "[up to date]"
 msgstr "[актуализиран]"
 
-#: builtin/fetch.c:659 builtin/fetch.c:739
+#: builtin/fetch.c:670 builtin/fetch.c:750
 msgid "[rejected]"
 msgstr "[отхвърлен]"
 
-#: builtin/fetch.c:660
+#: builtin/fetch.c:671
 msgid "can't fetch in current branch"
 msgstr "в текущия клон не може да се доставя"
 
-#: builtin/fetch.c:669
+#: builtin/fetch.c:680
 msgid "[tag update]"
 msgstr "[обновяване на етикетите]"
 
-#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719
-#: builtin/fetch.c:734
+#: builtin/fetch.c:681 builtin/fetch.c:714 builtin/fetch.c:730
+#: builtin/fetch.c:745
 msgid "unable to update local ref"
 msgstr "локален указател не може да бъде обновен"
 
-#: builtin/fetch.c:689
+#: builtin/fetch.c:700
 msgid "[new tag]"
 msgstr "[нов етикет]"
 
-#: builtin/fetch.c:692
+#: builtin/fetch.c:703
 msgid "[new branch]"
 msgstr "[нов клон]"
 
-#: builtin/fetch.c:695
+#: builtin/fetch.c:706
 msgid "[new ref]"
 msgstr "[нов указател]"
 
-#: builtin/fetch.c:734
+#: builtin/fetch.c:745
 msgid "forced update"
 msgstr "принудително обновяване"
 
-#: builtin/fetch.c:739
+#: builtin/fetch.c:750
 msgid "non-fast-forward"
 msgstr "същинско сливане"
 
-#: builtin/fetch.c:784
+#: builtin/fetch.c:795
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "хранилището „%s“ не изпрати всички необходими обекти\n"
 
-#: builtin/fetch.c:804
+#: builtin/fetch.c:815
 #, c-format
 msgid "reject %s because shallow roots are not allowed to be updated"
 msgstr ""
 "отхвърляне на върха „%s“, защото плитките хранилища не могат да бъдат "
 "обновявани"
 
-#: builtin/fetch.c:892 builtin/fetch.c:988
+#: builtin/fetch.c:903 builtin/fetch.c:999
 #, c-format
 msgid "From %.*s\n"
 msgstr "От %.*s\n"
 
-#: builtin/fetch.c:903
+#: builtin/fetch.c:914
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -8827,57 +9331,57 @@ msgstr ""
 "„git remote prune %s“, за да премахнете остарелите клони, които\n"
 "предизвикват конфликта"
 
-#: builtin/fetch.c:958
+#: builtin/fetch.c:969
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (обектът „%s“ ще се окаже извън клон)"
 
-#: builtin/fetch.c:959
+#: builtin/fetch.c:970
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (обектът „%s“ вече е извън клон)"
 
-#: builtin/fetch.c:991
+#: builtin/fetch.c:1002
 msgid "[deleted]"
 msgstr "[изтрит]"
 
-#: builtin/fetch.c:992 builtin/remote.c:1024
+#: builtin/fetch.c:1003 builtin/remote.c:1033
 msgid "(none)"
 msgstr "(нищо)"
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1026
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr "Не може да доставите в текущия клон „%s“ на хранилище, което не е голо"
 
-#: builtin/fetch.c:1034
+#: builtin/fetch.c:1045
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr "Стойността „%2$s“ за опцията „%1$s“ не е съвместима с „%3$s“"
 
-#: builtin/fetch.c:1037
+#: builtin/fetch.c:1048
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "Опцията „%s“ се прескача при „%s“\n"
 
-#: builtin/fetch.c:1277
+#: builtin/fetch.c:1287
 #, c-format
 msgid "Fetching %s\n"
 msgstr "Доставяне на „%s“\n"
 
-#: builtin/fetch.c:1279 builtin/remote.c:97
+#: builtin/fetch.c:1289 builtin/remote.c:98
 #, c-format
 msgid "Could not fetch %s"
 msgstr "„%s“ не може да се достави"
 
-#: builtin/fetch.c:1325 builtin/fetch.c:1498
+#: builtin/fetch.c:1335 builtin/fetch.c:1503
 msgid ""
 "--filter can only be used with the remote configured in core.partialClone"
 msgstr ""
 "опцията „--filter“ може да се ползва само с отдалеченото хранилище указано в "
 "настройката „core.partialClone“"
 
-#: builtin/fetch.c:1350
+#: builtin/fetch.c:1358
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
@@ -8885,41 +9389,41 @@ msgstr ""
 "Не сте указали отдалечено хранилище.  Задайте или адрес, или име\n"
 "на отдалечено хранилище, откъдето да се доставят новите версии."
 
-#: builtin/fetch.c:1394
+#: builtin/fetch.c:1395
 msgid "You need to specify a tag name."
 msgstr "Трябва да укажете име на етикет."
 
-#: builtin/fetch.c:1439
+#: builtin/fetch.c:1444
 msgid "Negative depth in --deepen is not supported"
 msgstr "Отрицателна дълбочина като аргумент на „--deepen“ не се поддържа"
 
-#: builtin/fetch.c:1441
+#: builtin/fetch.c:1446
 msgid "--deepen and --depth are mutually exclusive"
 msgstr "Опциите „--deepen“ и „--depth“ са несъвместими една с друга"
 
-#: builtin/fetch.c:1446
+#: builtin/fetch.c:1451
 msgid "--depth and --unshallow cannot be used together"
 msgstr "опциите „--depth“ и „--unshallow“ са несъвместими"
 
-#: builtin/fetch.c:1448
+#: builtin/fetch.c:1453
 msgid "--unshallow on a complete repository does not make sense"
 msgstr "не можете да използвате опцията „--unshallow“ върху пълно хранилище"
 
-#: builtin/fetch.c:1464
+#: builtin/fetch.c:1469
 msgid "fetch --all does not take a repository argument"
 msgstr "към „git fetch --all“ не можете да добавите аргумент — хранилище"
 
-#: builtin/fetch.c:1466
+#: builtin/fetch.c:1471
 msgid "fetch --all does not make sense with refspecs"
 msgstr ""
 "към „git fetch --all“ не можете да добавите аргумент — указател на версия"
 
-#: builtin/fetch.c:1475
+#: builtin/fetch.c:1480
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "Няма нито отдалечено хранилище, нито група от хранилища на име „%s“"
 
-#: builtin/fetch.c:1482
+#: builtin/fetch.c:1487
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr "Указването на група и указването на версия са несъвместими"
 
@@ -8987,7 +9491,7 @@ msgstr "цитиране подходящо за tcl"
 msgid "show only <n> matched refs"
 msgstr "извеждане само на този БРОЙ напаснати указатели"
 
-#: builtin/for-each-ref.c:39 builtin/tag.c:420
+#: builtin/for-each-ref.c:39 builtin/tag.c:421
 msgid "respect format colors"
 msgstr "спазване на цветовете на форма̀та"
 
@@ -9011,82 +9515,82 @@ msgstr "извеждане само на указателите, които съ
 msgid "print only refs which don't contain the commit"
 msgstr "извеждане само на указателите, които не съдържат това ПОДАВАНЕ"
 
-#: builtin/fsck.c:568
+#: builtin/fsck.c:569
 msgid "Checking object directories"
 msgstr "Проверка на директориите с обекти"
 
-#: builtin/fsck.c:660
+#: builtin/fsck.c:661
 msgid "git fsck [<options>] [<object>...]"
 msgstr "git fsck [ОПЦИЯ…] [ОБЕКТ…]"
 
-#: builtin/fsck.c:666
+#: builtin/fsck.c:667
 msgid "show unreachable objects"
 msgstr "показване на недостижимите обекти"
 
-#: builtin/fsck.c:667
+#: builtin/fsck.c:668
 msgid "show dangling objects"
 msgstr "показване на обектите извън клоните"
 
-#: builtin/fsck.c:668
+#: builtin/fsck.c:669
 msgid "report tags"
 msgstr "показване на етикетите"
 
-#: builtin/fsck.c:669
+#: builtin/fsck.c:670
 msgid "report root nodes"
 msgstr "показване на кореновите възли"
 
-#: builtin/fsck.c:670
+#: builtin/fsck.c:671
 msgid "make index objects head nodes"
 msgstr "задаване на обекти от индекса да са коренови"
 
 # FIXME bad message
-#: builtin/fsck.c:671
+#: builtin/fsck.c:672
 msgid "make reflogs head nodes (default)"
 msgstr "проследяване на указателите от журнала като глави (стандартно)"
 
-#: builtin/fsck.c:672
+#: builtin/fsck.c:673
 msgid "also consider packs and alternate objects"
 msgstr "допълнително да се проверяват пакетите и алтернативните обекти"
 
-#: builtin/fsck.c:673
+#: builtin/fsck.c:674
 msgid "check only connectivity"
 msgstr "проверка само на връзката"
 
-#: builtin/fsck.c:674
+#: builtin/fsck.c:675
 msgid "enable more strict checking"
 msgstr "по-строги проверки"
 
-#: builtin/fsck.c:676
+#: builtin/fsck.c:677
 msgid "write dangling objects in .git/lost-found"
 msgstr "запазване на обектите извън клоните в директорията „.git/lost-found“"
 
-#: builtin/fsck.c:677 builtin/prune.c:108
+#: builtin/fsck.c:678 builtin/prune.c:109
 msgid "show progress"
 msgstr "показване на напредъка"
 
-#: builtin/fsck.c:678
+#: builtin/fsck.c:679
 msgid "show verbose names for reachable objects"
 msgstr "показване на подробни имена на достижимите обекти"
 
-#: builtin/fsck.c:742
+#: builtin/fsck.c:745
 msgid "Checking objects"
 msgstr "Проверка на обектите"
 
-#: builtin/gc.c:27
+#: builtin/gc.c:33
 msgid "git gc [<options>]"
 msgstr "git gc [ОПЦИЯ…]"
 
-#: builtin/gc.c:80
+#: builtin/gc.c:88
 #, c-format
 msgid "Failed to fstat %s: %s"
 msgstr "Неуспешно изпълнение на „fstat“ върху „%s“: %s"
 
-#: builtin/gc.c:312
+#: builtin/gc.c:452
 #, c-format
 msgid "Can't stat %s"
 msgstr "Неуспешно изпълнение на „stat“ върху „%s“"
 
-#: builtin/gc.c:321
+#: builtin/gc.c:461
 #, c-format
 msgid ""
 "The last gc run reported the following. Please correct the root cause\n"
@@ -9103,49 +9607,58 @@ msgstr ""
 "\n"
 "%s"
 
-#: builtin/gc.c:360
+#: builtin/gc.c:502
 msgid "prune unreferenced objects"
 msgstr "окастряне на обектите, към които нищо не сочи"
 
-#: builtin/gc.c:362
+#: builtin/gc.c:504
 msgid "be more thorough (increased runtime)"
 msgstr "изчерпателно търсене на боклука (за сметка на повече време работа)"
 
-#: builtin/gc.c:363
+#: builtin/gc.c:505
 msgid "enable auto-gc mode"
 msgstr "включване на автоматичното събиране на боклука (auto-gc)"
 
-#: builtin/gc.c:366
+#: builtin/gc.c:508
 msgid "force running gc even if there may be another gc running"
 msgstr ""
 "изрично стартиране на събирането на боклука, дори и ако вече работи друго "
 "събиране"
 
-#: builtin/gc.c:384
+#: builtin/gc.c:511
+msgid "repack all other packs except the largest pack"
+msgstr "препакетиране на всичко без най-големия пакет"
+
+#: builtin/gc.c:528
+#, c-format
+msgid "failed to parse gc.logexpiry value %s"
+msgstr "неразпозната стойност на „gc.logexpiry“ %s"
+
+#: builtin/gc.c:539
 #, c-format
-msgid "Failed to parse gc.logexpiry value %s"
-msgstr "Ð\9dеÑ\80азпознаÑ\82а Ñ\81Ñ\82ойноÑ\81Ñ\82 Ð½Ð° â\80\9egc.logexpiryâ\80\9c: %s"
+msgid "failed to parse prune expiry value %s"
+msgstr "неÑ\80азпознаÑ\82а Ñ\81Ñ\82ойноÑ\81Ñ\82 Ð½Ð° Ð¿ÐµÑ\80иода Ð·Ð° Ð¾ÐºÐ°Ñ\81Ñ\82Ñ\80Ñ\8fне: %s"
 
-#: builtin/gc.c:412
+#: builtin/gc.c:559
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
 msgstr ""
 "Автоматично пакетиране на заден фон на хранилището за по-добра "
 "производителност.\n"
 
-#: builtin/gc.c:414
+#: builtin/gc.c:561
 #, c-format
 msgid "Auto packing the repository for optimum performance.\n"
 msgstr "Автоматично пакетиране на хранилището за по-добра производителност.\n"
 
-#: builtin/gc.c:415
+#: builtin/gc.c:562
 #, c-format
 msgid "See \"git help gc\" for manual housekeeping.\n"
 msgstr ""
 "Погледнете ръководството за повече информация как да изпълните „git help "
 "gc“.\n"
 
-#: builtin/gc.c:440
+#: builtin/gc.c:598
 #, c-format
 msgid ""
 "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
@@ -9154,23 +9667,23 @@ msgstr ""
 "процеса: %<PRIuMAX> (ако сте сигурни, че това не е вярно, това използвайте\n"
 "опцията „--force“)"
 
-#: builtin/gc.c:487
+#: builtin/gc.c:645
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
 "Има прекалено много недостижими, непакетирани обекти.\n"
 "Използвайте „git prune“, за да ги окастрите."
 
-#: builtin/grep.c:27
+#: builtin/grep.c:28
 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [ОПЦИЯ…] [-e] ШАБЛОН [ВЕРСИЯ…] [[--] ПЪТ…]"
 
-#: builtin/grep.c:225
+#: builtin/grep.c:226
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep: неуспешно създаване на нишка: %s"
 
-#: builtin/grep.c:283
+#: builtin/grep.c:284
 #, c-format
 msgid "invalid number of threads specified (%d) for %s"
 msgstr "зададен е неправилен брой нишки (%d) за %s"
@@ -9179,17 +9692,17 @@ msgstr "зададен е неправилен брой нишки (%d) за %s"
 #. variable for tweaking threads, currently
 #. grep.threads
 #.
-#: builtin/grep.c:292 builtin/index-pack.c:1523 builtin/index-pack.c:1712
+#: builtin/grep.c:293 builtin/index-pack.c:1535 builtin/index-pack.c:1727
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "липсва поддръжка за нишки.  „%s“ ще се пренебрегне"
 
-#: builtin/grep.c:460 builtin/grep.c:580 builtin/grep.c:622
+#: builtin/grep.c:461 builtin/grep.c:582 builtin/grep.c:623
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "дървото не може да бъде прочетено (%s)"
 
-#: builtin/grep.c:637
+#: builtin/grep.c:638
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "не може да се изпълни „grep“ от обект от вида %s"
@@ -9399,7 +9912,7 @@ msgstr "опциите „--cached“ и „--untracked“ са несъвмес
 msgid "unable to resolve revision: %s"
 msgstr "версията „%s“ не може бъде открита"
 
-#: builtin/grep.c:1036 builtin/index-pack.c:1519
+#: builtin/grep.c:1036 builtin/index-pack.c:1531
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "зададен е неправилен брой нишки: %d"
@@ -9474,58 +9987,62 @@ msgstr ""
 msgid "process file as it were from this path"
 msgstr "обработване на ФАЙЛа все едно е с този път"
 
-#: builtin/help.c:43
+#: builtin/help.c:45
 msgid "print all available commands"
 msgstr "показване на всички налични команди"
 
-#: builtin/help.c:44
+#: builtin/help.c:46
 msgid "exclude guides"
 msgstr "без въведения"
 
-#: builtin/help.c:45
+#: builtin/help.c:47
 msgid "print list of useful guides"
 msgstr "показване на списък с въведения"
 
-#: builtin/help.c:46
+#: builtin/help.c:48
 msgid "show man page"
 msgstr "показване на страница от ръководството"
 
-#: builtin/help.c:47
+#: builtin/help.c:49
 msgid "show manual in web browser"
 msgstr "показване на страница от ръководството в уеб браузър"
 
-#: builtin/help.c:49
+#: builtin/help.c:51
 msgid "show info page"
 msgstr "показване на информационна страница"
 
-#: builtin/help.c:55
+#: builtin/help.c:53
+msgid "print command description"
+msgstr "извеждане на описанието на команда"
+
+#: builtin/help.c:58
 msgid "git help [--all] [--guides] [--man | --web | --info] [<command>]"
 msgstr "git help [--all] [--guides] [--man | --web | --info] [КОМАНДА]"
 
-#: builtin/help.c:67
+#: builtin/help.c:70
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "непознат формат на помощта „%s“"
 
-#: builtin/help.c:94
+#: builtin/help.c:97
 msgid "Failed to start emacsclient."
 msgstr "Неуспешно стартиране на „emacsclient“."
 
-#: builtin/help.c:107
+#: builtin/help.c:110
 msgid "Failed to parse emacsclient version."
 msgstr "Версията на „emacsclient“ не може да се анализира."
 
-#: builtin/help.c:115
+#: builtin/help.c:118
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "Прекалено стара версия на „emacsclient“ — %d (< 22)."
 
-#: builtin/help.c:133 builtin/help.c:155 builtin/help.c:165 builtin/help.c:173
+#: builtin/help.c:136 builtin/help.c:158 builtin/help.c:168 builtin/help.c:176
 #, c-format
 msgid "failed to exec '%s'"
 msgstr "неуспешно изпълнение на „%s“"
 
-#: builtin/help.c:211
+#: builtin/help.c:214
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -9534,7 +10051,7 @@ msgstr ""
 "„%s“: път към неподдържана програма за преглед на\n"
 " ръководството.  Вместо нея пробвайте „man.<tool>.cmd“."
 
-#: builtin/help.c:223
+#: builtin/help.c:226
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -9543,370 +10060,338 @@ msgstr ""
 "„%s“: команда за поддържана програма за преглед на\n"
 " ръководството.  Вместо нея пробвайте „man.<tool>.path“."
 
-#: builtin/help.c:340
+#: builtin/help.c:343
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "„%s“: непозната програма за преглед на ръководството."
 
-#: builtin/help.c:357
+#: builtin/help.c:360
 msgid "no man viewer handled the request"
 msgstr "никоя програма за преглед на ръководство не успя да обработи заявката"
 
-#: builtin/help.c:365
+#: builtin/help.c:368
 msgid "no info viewer handled the request"
 msgstr ""
 "никоя програма за преглед на информационните страници не успя да обработи "
 "заявката"
 
-#: builtin/help.c:407
-msgid "Defining attributes per path"
-msgstr "Указване на атрибути към път"
-
-#: builtin/help.c:408
-msgid "Everyday Git With 20 Commands Or So"
-msgstr "Ежедневието в Git в рамките на двайсетина команди"
-
-#: builtin/help.c:409
-msgid "A Git glossary"
-msgstr "Речник с термините на Git"
-
-#: builtin/help.c:410
-msgid "Specifies intentionally untracked files to ignore"
-msgstr "Указване на неследени файлове, които да бъдат нарочно пренебрегвани"
-
-#: builtin/help.c:411
-msgid "Defining submodule properties"
-msgstr "Дефиниране на свойствата на подмодулите"
-
-#: builtin/help.c:412
-msgid "Specifying revisions and ranges for Git"
-msgstr "Указване на версии и диапазони в Git"
-
-#: builtin/help.c:413
-msgid "A tutorial introduction to Git (for version 1.5.1 or newer)"
-msgstr "Въвеждащ урок за Git (версии поне 1.5.1)"
-
-#: builtin/help.c:414
-msgid "An overview of recommended workflows with Git"
-msgstr "Общ преглед на препоръчваните начини за работа с Git"
-
-#: builtin/help.c:426
-msgid "The common Git guides are:\n"
-msgstr "Популярните въведения в Git са:\n"
-
-#: builtin/help.c:444
+#: builtin/help.c:415
 #, c-format
 msgid "'%s' is aliased to '%s'"
 msgstr "„%s“ е синоним на „%s“"
 
-#: builtin/help.c:466 builtin/help.c:483
+#: builtin/help.c:442 builtin/help.c:459
 #, c-format
 msgid "usage: %s%s"
 msgstr "употреба: %s%s"
 
-#: builtin/index-pack.c:157
+#: builtin/index-pack.c:158
 #, c-format
 msgid "unable to open %s"
 msgstr "обектът „%s“ не може да бъде отворен"
 
-#: builtin/index-pack.c:207
+#: builtin/index-pack.c:208
 #, c-format
 msgid "object type mismatch at %s"
 msgstr "неправилен вид на обекта „%s“"
 
-#: builtin/index-pack.c:227
+#: builtin/index-pack.c:228
 #, c-format
 msgid "did not receive expected object %s"
 msgstr "очакваният обект „%s“ не бе получен"
 
-#: builtin/index-pack.c:230
+#: builtin/index-pack.c:231
 #, c-format
 msgid "object %s: expected type %s, found %s"
 msgstr "неправилен вид на обекта „%s“: очакваше се „%s“, а бе получен „%s“"
 
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
 #, c-format
 msgid "cannot fill %d byte"
 msgid_plural "cannot fill %d bytes"
 msgstr[0] "не може да се запълни %d байт"
 msgstr[1] "не може да се запълнят %d байта"
 
-#: builtin/index-pack.c:282
+#: builtin/index-pack.c:283
 msgid "early EOF"
 msgstr "неочакван край на файл"
 
-#: builtin/index-pack.c:283
+#: builtin/index-pack.c:284
 msgid "read error on input"
 msgstr "грешка при четене на входните данни"
 
-#: builtin/index-pack.c:295
+#: builtin/index-pack.c:296
 msgid "used more bytes than were available"
 msgstr "използвани са повече от наличните байтове"
 
-#: builtin/index-pack.c:302
+#: builtin/index-pack.c:303
 msgid "pack too large for current definition of off_t"
 msgstr "пакетният файл е прекалено голям за текущата стойност на типа „off_t“"
 
-#: builtin/index-pack.c:305 builtin/unpack-objects.c:93
+#: builtin/index-pack.c:306 builtin/unpack-objects.c:93
 msgid "pack exceeds maximum allowed size"
 msgstr "пакетният файл надвишава максималния възможен размер"
 
-#: builtin/index-pack.c:320
+#: builtin/index-pack.c:321
 #, c-format
 msgid "unable to create '%s'"
 msgstr "пакетният файл „%s“ не може да бъде създаден"
 
-#: builtin/index-pack.c:326
+#: builtin/index-pack.c:327
 #, c-format
 msgid "cannot open packfile '%s'"
 msgstr "пакетният файл „%s“ не може да бъде отворен"
 
-#: builtin/index-pack.c:340
+#: builtin/index-pack.c:341
 msgid "pack signature mismatch"
 msgstr "несъответствие в подписа към пакетния файл"
 
-#: builtin/index-pack.c:342
+#: builtin/index-pack.c:343
 #, c-format
 msgid "pack version %<PRIu32> unsupported"
 msgstr "не се поддържа пакетиране вeрсия „%<PRIu32>“"
 
-#: builtin/index-pack.c:360
+#: builtin/index-pack.c:361
 #, c-format
 msgid "pack has bad object at offset %<PRIuMAX>: %s"
 msgstr "повреден обект в пакетния файл при отместване %<PRIuMAX>: %s"
 
-#: builtin/index-pack.c:481
+#: builtin/index-pack.c:482
 #, c-format
 msgid "inflate returned %d"
 msgstr "декомпресирането с „inflate“ върна %d"
 
-#: builtin/index-pack.c:530
+#: builtin/index-pack.c:531
 msgid "offset value overflow for delta base object"
 msgstr "стойността на отместването за обекта-разлика води до препълване"
 
-#: builtin/index-pack.c:538
+#: builtin/index-pack.c:539
 msgid "delta base offset is out of bound"
 msgstr "стойността на отместването за обекта-разлика е извън диапазона"
 
-#: builtin/index-pack.c:546
+#: builtin/index-pack.c:547
 #, c-format
 msgid "unknown object type %d"
 msgstr "непознат вид обект %d"
 
-#: builtin/index-pack.c:577
+#: builtin/index-pack.c:578
 msgid "cannot pread pack file"
 msgstr "пакетният файл не може да бъде прочетен"
 
-#: builtin/index-pack.c:579
+#: builtin/index-pack.c:580
 #, c-format
 msgid "premature end of pack file, %<PRIuMAX> byte missing"
 msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
 msgstr[0] "неочакван край на файл, липсва %<PRIuMAX> байт"
 msgstr[1] "неочакван край на файл, липсват %<PRIuMAX> байта"
 
-#: builtin/index-pack.c:605
+#: builtin/index-pack.c:606
 msgid "serious inflate inconsistency"
 msgstr "сериозна грешка при декомпресиране с „inflate“"
 
-#: builtin/index-pack.c:750 builtin/index-pack.c:756 builtin/index-pack.c:779
-#: builtin/index-pack.c:818 builtin/index-pack.c:827
+#: builtin/index-pack.c:751 builtin/index-pack.c:757 builtin/index-pack.c:780
+#: builtin/index-pack.c:819 builtin/index-pack.c:828
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr ""
 "СЪВПАДЕНИЕ НА СТОЙНОСТИТЕ ЗА СУМИТЕ ЗА SHA1: „%s“ НА ДВА РАЗЛИЧНИ ОБЕКТА!"
 
-#: builtin/index-pack.c:753 builtin/pack-objects.c:182
-#: builtin/pack-objects.c:276
+#: builtin/index-pack.c:754 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:292
 #, c-format
 msgid "unable to read %s"
 msgstr "обектът „%s“ не може да бъде прочетен"
 
-#: builtin/index-pack.c:816
+#: builtin/index-pack.c:817
 #, c-format
 msgid "cannot read existing object info %s"
 msgstr "съществуващият обект в „%s“ не може да бъде прочетен"
 
-#: builtin/index-pack.c:824
+#: builtin/index-pack.c:825
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "съществуващият обект „%s“ не може да бъде прочетен"
 
-#: builtin/index-pack.c:838
+#: builtin/index-pack.c:839
 #, c-format
 msgid "invalid blob object %s"
-msgstr "неправилен обект BLOB „%s“"
+msgstr "неправилен обект-BLOB „%s“"
 
-# FIXME perhaps invalid object
-#: builtin/index-pack.c:853
+#: builtin/index-pack.c:842 builtin/index-pack.c:860
+msgid "fsck error in packed object"
+msgstr "грешка при проверката на пакетирани обекти"
+
+# FIXME perhaps invalid object or pack
+#: builtin/index-pack.c:857
 #, c-format
 msgid "invalid %s"
 msgstr "неправилен обект „%s“"
 
-#: builtin/index-pack.c:856
-msgid "Error in object"
-msgstr "Грешка в обекта"
-
-#: builtin/index-pack.c:858
+#: builtin/index-pack.c:862
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "Някои обекти, наследници на „%s“, не могат да бъдат достигнати"
 
-#: builtin/index-pack.c:930 builtin/index-pack.c:961
+#: builtin/index-pack.c:934 builtin/index-pack.c:965
 msgid "failed to apply delta"
 msgstr "разликата не може да бъде приложена"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Receiving objects"
 msgstr "Получаване на обекти"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Indexing objects"
 msgstr "Индексиране на обекти"
 
-#: builtin/index-pack.c:1165
+#: builtin/index-pack.c:1169
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "пакетният файл е повреден (нееднакви суми по SHA1)"
 
-#: builtin/index-pack.c:1170
+#: builtin/index-pack.c:1174
 msgid "cannot fstat packfile"
 msgstr "не може да се получи информация за пакетния файл с „fstat“"
 
-#: builtin/index-pack.c:1173
+#: builtin/index-pack.c:1177
 msgid "pack has junk at the end"
 msgstr "в края на пакетния файл има повредени данни"
 
-#: builtin/index-pack.c:1185
+#: builtin/index-pack.c:1189
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr ""
 "фатална грешка във функцията „parse_pack_objects“.  Това е грешка в Git, "
 "докладвайте я на разработчиците, като пратите е-писмо на адрес: „git@vger."
 "kernel.org“."
 
-#: builtin/index-pack.c:1208
+#: builtin/index-pack.c:1212
 msgid "Resolving deltas"
 msgstr "Откриване на съответните разлики"
 
-#: builtin/index-pack.c:1219
+#: builtin/index-pack.c:1223
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "не може да се създаде нишка: %s"
 
-#: builtin/index-pack.c:1261
+#: builtin/index-pack.c:1265
 msgid "confusion beyond insanity"
 msgstr ""
 "фатална грешка във функцията „conclude_pack“.  Това е грешка в Git, "
 "докладвайте я на разработчиците, като пратите е-писмо на адрес: „git@vger."
 "kernel.org“."
 
-#: builtin/index-pack.c:1267
+#: builtin/index-pack.c:1271
 #, c-format
 msgid "completed with %d local object"
 msgid_plural "completed with %d local objects"
 msgstr[0] "действието завърши с %d локален обект"
 msgstr[1] "действието завърши с %d локални обекта"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1283
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr ""
 "Неочаквана последваща сума за грешки за „%s“ (причината може да е грешка в "
 "диска)"
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1287
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "в пакета има %d ненапасваща разлика"
 msgstr[1] "в пакета има %d ненапасващи разлики"
 
-#: builtin/index-pack.c:1307
+#: builtin/index-pack.c:1311
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "добавеният обект не може да се компресира с „deflate“: %d"
 
-#: builtin/index-pack.c:1383
+#: builtin/index-pack.c:1388
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "локалният обект „%s“ е повреден"
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1402
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "името на пакетния файл „%s“ не завършва на „.pack“"
 
-#: builtin/index-pack.c:1422
+#: builtin/index-pack.c:1427
 #, c-format
 msgid "cannot write %s file '%s'"
 msgstr "грешка при запис на файла „%s“ „%s“"
 
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1435
 #, c-format
 msgid "cannot close written %s file '%s'"
 msgstr "грешка при затварянето на записания файл „%s“ „%s“"
 
-#: builtin/index-pack.c:1454
+#: builtin/index-pack.c:1459
 msgid "error while closing pack file"
 msgstr "грешка при затварянето на пакетния файл"
 
-#: builtin/index-pack.c:1468
+#: builtin/index-pack.c:1473
 msgid "cannot store pack file"
 msgstr "пакетният файл не може да бъде запазен"
 
-#: builtin/index-pack.c:1476
+#: builtin/index-pack.c:1481
 msgid "cannot store index file"
 msgstr "файлът за индекса не може да бъде съхранен"
 
-#: builtin/index-pack.c:1513
+#: builtin/index-pack.c:1525
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "зададена е неправилна версия пакетиране: „pack.indexversion=%<PRIu32>“"
 
-#: builtin/index-pack.c:1581
+#: builtin/index-pack.c:1594
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "Съществуващият пакетен файл „%s“ не може да бъде отворен"
 
-#: builtin/index-pack.c:1583
+#: builtin/index-pack.c:1596
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "Съществуващият индекс за пакетния файл „%s“ не може да бъде отворен"
 
-#: builtin/index-pack.c:1631
+#: builtin/index-pack.c:1644
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "%d обект не е разлика"
 msgstr[1] "%d обекта не са разлика"
 
-#: builtin/index-pack.c:1638
+#: builtin/index-pack.c:1651
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] "дължината на веригата е %d: %lu обект"
 msgstr[1] "дължината на веригата е %d: %lu обекта"
 
-#: builtin/index-pack.c:1675
+#: builtin/index-pack.c:1688
 msgid "Cannot come back to cwd"
 msgstr "Процесът не може да се върне към предишната работна директория"
 
-#: builtin/index-pack.c:1724 builtin/index-pack.c:1727
-#: builtin/index-pack.c:1743 builtin/index-pack.c:1747
+#: builtin/index-pack.c:1739 builtin/index-pack.c:1742
+#: builtin/index-pack.c:1758 builtin/index-pack.c:1762
 #, c-format
 msgid "bad %s"
 msgstr "неправилна стойност „%s“"
 
-#: builtin/index-pack.c:1763
+#: builtin/index-pack.c:1778
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "опцията „--fix-thin“ изисква „--stdin“"
 
-#: builtin/index-pack.c:1765
+#: builtin/index-pack.c:1780
 msgid "--stdin requires a git repository"
 msgstr "„--stdin“ изисква хранилище на git"
 
-#: builtin/index-pack.c:1771
+#: builtin/index-pack.c:1786
 msgid "--verify with no packfile name given"
 msgstr "опцията „--verify“ изисква име на пакетен файл"
 
+#: builtin/index-pack.c:1836 builtin/unpack-objects.c:578
+msgid "fsck error in pack objects"
+msgstr "грешка при проверка с „fsck“ на пакетните обекти"
+
 #: builtin/init-db.c:55
 #, c-format
 msgid "cannot stat '%s'"
@@ -9944,8 +10429,8 @@ msgstr "игнориране на шаблона „%s“"
 
 #: builtin/init-db.c:120
 #, c-format
-msgid "templates not found %s"
-msgstr "диÑ\80екÑ\82оÑ\80иÑ\8fÑ\82а Ñ\81 Ñ\88аблониÑ\82е Ð½Ðµ Ðµ Ð¾Ñ\82кÑ\80иÑ\82а: „%s“"
+msgid "templates not found in %s"
+msgstr "нÑ\8fма Ñ\88аблони Ð² „%s“"
 
 #: builtin/init-db.c:135
 #, c-format
@@ -10006,11 +10491,6 @@ msgstr ""
 "указване, че хранилището на Git ще бъде споделено от повече от един "
 "потребител"
 
-#: builtin/init-db.c:516 builtin/init-db.c:521
-#, c-format
-msgid "cannot mkdir %s"
-msgstr "директорията „%s“ не може да бъде създадена"
-
 #: builtin/init-db.c:525
 #, c-format
 msgid "cannot chdir to %s"
@@ -10198,7 +10678,7 @@ msgstr "Можете да укажете максимум една директ
 msgid "Unknown commit %s"
 msgstr "Непознато подаване „%s“"
 
-#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:522
+#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:523
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr "Не може да се открие към какво сочи „%s“."
@@ -10378,7 +10858,7 @@ msgstr "БАЗОВО_ПОДАВАНЕ"
 
 #: builtin/log.c:1505
 msgid "add prerequisite tree info to the patch series"
-msgstr "добавяне на необходимото БАЗово дърво към серията кръпки"
+msgstr "добавяне на необходимото БАЗово дърво към поредицата от кръпки"
 
 #: builtin/log.c:1507
 msgid "add a signature from a file"
@@ -10558,7 +11038,7 @@ msgstr ""
 msgid "show debugging data"
 msgstr "извеждане на информацията за изчистване на грешки"
 
-#: builtin/ls-remote.c:7
+#: builtin/ls-remote.c:9
 msgid ""
 "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
@@ -10568,39 +11048,39 @@ msgstr ""
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
 "                     [--symref] [ХРАНИЛИЩЕ [УКАЗАТЕЛ…]]"
 
-#: builtin/ls-remote.c:52
+#: builtin/ls-remote.c:59
 msgid "do not print remote URL"
 msgstr "без извеждане на адресите на отдалечените хранилища"
 
-#: builtin/ls-remote.c:53 builtin/ls-remote.c:55
+#: builtin/ls-remote.c:60 builtin/ls-remote.c:62
 msgid "exec"
 msgstr "КОМАНДА"
 
-#: builtin/ls-remote.c:54 builtin/ls-remote.c:56
+#: builtin/ls-remote.c:61 builtin/ls-remote.c:63
 msgid "path of git-upload-pack on the remote host"
 msgstr "път към командата „git-upload-pack“ на отдалечената машина"
 
-#: builtin/ls-remote.c:58
+#: builtin/ls-remote.c:65
 msgid "limit to tags"
 msgstr "само етикетите"
 
-#: builtin/ls-remote.c:59
+#: builtin/ls-remote.c:66
 msgid "limit to heads"
 msgstr "само върховете"
 
-#: builtin/ls-remote.c:60
+#: builtin/ls-remote.c:67
 msgid "do not show peeled tags"
 msgstr "без извеждане на проследените етикети"
 
-#: builtin/ls-remote.c:62
+#: builtin/ls-remote.c:69
 msgid "take url.<base>.insteadOf into account"
 msgstr "взимане предвид на „url.БАЗА.insteadOf“"
 
-#: builtin/ls-remote.c:64
+#: builtin/ls-remote.c:73
 msgid "exit with exit code 2 if no matching refs are found"
 msgstr "изход с код 2, ако не се открият съвпадащи указатели"
 
-#: builtin/ls-remote.c:67
+#: builtin/ls-remote.c:76
 msgid "show underlying ref in addition to the object pointed by it"
 msgstr "извеждане на указателя заедно с обекта сочен от него"
 
@@ -10647,169 +11127,169 @@ msgstr ""
 msgid "empty mbox: '%s'"
 msgstr "празна пощенска кутия mbox: „%s“"
 
-#: builtin/merge.c:49
+#: builtin/merge.c:51
 msgid "git merge [<options>] [<commit>...]"
 msgstr "git merge [ОПЦИЯ…] [ПОДАВАНЕ…]"
 
-#: builtin/merge.c:50
+#: builtin/merge.c:52
 msgid "git merge --abort"
 msgstr "git merge --abort"
 
-#: builtin/merge.c:51
+#: builtin/merge.c:53
 msgid "git merge --continue"
 msgstr "git merge --continue"
 
-#: builtin/merge.c:108
+#: builtin/merge.c:110
 msgid "switch `m' requires a value"
 msgstr "опцията „-m“ изисква стойност"
 
-#: builtin/merge.c:145
+#: builtin/merge.c:147
 #, c-format
 msgid "Could not find merge strategy '%s'.\n"
 msgstr "Няма такава стратегия за сливане: „%s“.\n"
 
-#: builtin/merge.c:146
+#: builtin/merge.c:148
 #, c-format
 msgid "Available strategies are:"
 msgstr "Наличните стратегии са:"
 
-#: builtin/merge.c:151
+#: builtin/merge.c:153
 #, c-format
 msgid "Available custom strategies are:"
 msgstr "Допълнителните стратегии са:"
 
-#: builtin/merge.c:201 builtin/pull.c:137
+#: builtin/merge.c:203 builtin/pull.c:142
 msgid "do not show a diffstat at the end of the merge"
 msgstr "без извеждане на статистиката след завършване на сливане"
 
-#: builtin/merge.c:204 builtin/pull.c:140
+#: builtin/merge.c:206 builtin/pull.c:145
 msgid "show a diffstat at the end of the merge"
 msgstr "извеждане на статистиката след завършване на сливане"
 
-#: builtin/merge.c:205 builtin/pull.c:143
+#: builtin/merge.c:207 builtin/pull.c:148
 msgid "(synonym to --stat)"
 msgstr "(синоним на „--stat“)"
 
-#: builtin/merge.c:207 builtin/pull.c:146
+#: builtin/merge.c:209 builtin/pull.c:151
 msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr ""
 "добавяне (на максимум такъв БРОЙ) записи от съкратения журнал в съобщението "
 "за подаване"
 
-#: builtin/merge.c:210 builtin/pull.c:152
+#: builtin/merge.c:212 builtin/pull.c:157
 msgid "create a single commit instead of doing a merge"
 msgstr "създаване на едно подаване вместо извършване на сливане"
 
-#: builtin/merge.c:212 builtin/pull.c:155
+#: builtin/merge.c:214 builtin/pull.c:160
 msgid "perform a commit if the merge succeeds (default)"
 msgstr "извършване на подаване при успешно сливане (стандартно действие)"
 
-#: builtin/merge.c:214 builtin/pull.c:158
+#: builtin/merge.c:216 builtin/pull.c:163
 msgid "edit message before committing"
 msgstr "редактиране на съобщението преди подаване"
 
-#: builtin/merge.c:215
+#: builtin/merge.c:217
 msgid "allow fast-forward (default)"
 msgstr "позволяване на превъртане (стандартно действие)"
 
-#: builtin/merge.c:217 builtin/pull.c:164
+#: builtin/merge.c:219 builtin/pull.c:169
 msgid "abort if fast-forward is not possible"
 msgstr "преустановяване, ако превъртането е невъзможно"
 
-#: builtin/merge.c:221 builtin/pull.c:167
+#: builtin/merge.c:223 builtin/pull.c:172
 msgid "verify that the named commit has a valid GPG signature"
 msgstr "проверка, че указаното подаване е с правилен подпис на GPG"
 
-#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171
+#: builtin/merge.c:224 builtin/notes.c:777 builtin/pull.c:176
 #: builtin/revert.c:109
 msgid "strategy"
 msgstr "СТРАТЕГИЯ"
 
-#: builtin/merge.c:223 builtin/pull.c:172
+#: builtin/merge.c:225 builtin/pull.c:177
 msgid "merge strategy to use"
 msgstr "СТРАТЕГИЯ за сливане, която да се ползва"
 
-#: builtin/merge.c:224 builtin/pull.c:175
+#: builtin/merge.c:226 builtin/pull.c:180
 msgid "option=value"
 msgstr "ОПЦИЯ=СТОЙНОСТ"
 
-#: builtin/merge.c:225 builtin/pull.c:176
+#: builtin/merge.c:227 builtin/pull.c:181
 msgid "option for selected merge strategy"
 msgstr "ОПЦИЯ за избраната стратегия за сливане"
 
-#: builtin/merge.c:227
+#: builtin/merge.c:229
 msgid "merge commit message (for a non-fast-forward merge)"
 msgstr "СЪОБЩЕНИЕ при подаването със сливане (при същински сливания)"
 
-#: builtin/merge.c:231
+#: builtin/merge.c:233
 msgid "abort the current in-progress merge"
 msgstr "преустановяване на текущото сливане"
 
-#: builtin/merge.c:233
+#: builtin/merge.c:235
 msgid "continue the current in-progress merge"
 msgstr "продължаване на текущото сливане"
 
-#: builtin/merge.c:235 builtin/pull.c:183
+#: builtin/merge.c:237 builtin/pull.c:188
 msgid "allow merging unrelated histories"
 msgstr "позволяване на сливане на независими истории"
 
-#: builtin/merge.c:241
+#: builtin/merge.c:243
 msgid "verify commit-msg hook"
 msgstr ""
 "проверка на куката при промяна на съобщението при подаване (commit-msg)"
 
-#: builtin/merge.c:266
+#: builtin/merge.c:268
 msgid "could not run stash."
 msgstr "не може да се извърши скатаване"
 
-#: builtin/merge.c:271
+#: builtin/merge.c:273
 msgid "stash failed"
 msgstr "неуспешно скатаване"
 
-#: builtin/merge.c:276
+#: builtin/merge.c:278
 #, c-format
 msgid "not a valid object: %s"
 msgstr "неправилен обект: „%s“"
 
-#: builtin/merge.c:298 builtin/merge.c:315
+#: builtin/merge.c:300 builtin/merge.c:317
 msgid "read-tree failed"
 msgstr "неуспешно прочитане на обект-дърво"
 
-#: builtin/merge.c:345
+#: builtin/merge.c:347
 msgid " (nothing to squash)"
-msgstr " (няма какво да се смачка)"
+msgstr " (няма какво да се вкара)"
 
-#: builtin/merge.c:356
+#: builtin/merge.c:358
 #, c-format
 msgid "Squash commit -- not updating HEAD\n"
-msgstr "Ð\9fодаване Ñ\81Ñ\8aÑ\81 Ñ\81маÑ\87кване — указателят „HEAD“ няма да бъде обновен\n"
+msgstr "Ð\92каÑ\80ано Ð¿Ð¾Ð´Ð°ване — указателят „HEAD“ няма да бъде обновен\n"
 
-#: builtin/merge.c:406
+#: builtin/merge.c:408
 #, c-format
 msgid "No merge message -- not updating HEAD\n"
 msgstr ""
 "Липсва съобщение при подаване — указателят „HEAD“ няма да бъде обновен\n"
 
-#: builtin/merge.c:456
+#: builtin/merge.c:458
 #, c-format
 msgid "'%s' does not point to a commit"
 msgstr "„%s“ не сочи към подаване"
 
-#: builtin/merge.c:546
+#: builtin/merge.c:548
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "Неправилен низ за настройката „branch.%s.mergeoptions“: „%s“"
 
-#: builtin/merge.c:668
+#: builtin/merge.c:669
 msgid "Not handling anything other than two heads merge."
 msgstr "Поддържа се само сливане на точно две истории."
 
-#: builtin/merge.c:682
+#: builtin/merge.c:683
 #, c-format
 msgid "Unknown option for merge-recursive: -X%s"
 msgstr "Непозната опция за рекурсивното сливане „merge-recursive“: „-X%s“"
 
-#: builtin/merge.c:697
+#: builtin/merge.c:698
 #, c-format
 msgid "unable to write %s"
 msgstr "„%s“ не може да бъде записан"
@@ -10845,68 +11325,68 @@ msgstr ""
 msgid "Empty commit message."
 msgstr "Празно съобщение при подаване."
 
-#: builtin/merge.c:820
+#: builtin/merge.c:819
 #, c-format
 msgid "Wonderful.\n"
 msgstr "Първият етап на сливането завърши.\n"
 
-#: builtin/merge.c:873
+#: builtin/merge.c:872
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr ""
 "Неуспешно автоматично сливане — коригирайте конфликтите и подайте "
 "резултата.\n"
 
-#: builtin/merge.c:912
+#: builtin/merge.c:911
 msgid "No current branch."
 msgstr "Няма текущ клон."
 
-#: builtin/merge.c:914
+#: builtin/merge.c:913
 msgid "No remote for the current branch."
 msgstr "Текущият клон не следи никой."
 
-#: builtin/merge.c:916
+#: builtin/merge.c:915
 msgid "No default upstream defined for the current branch."
 msgstr "Текущият клон не следи никой клон."
 
-#: builtin/merge.c:921
+#: builtin/merge.c:920
 #, c-format
 msgid "No remote-tracking branch for %s from %s"
 msgstr "Никой клон не следи клона „%s“ от хранилището „%s“"
 
-#: builtin/merge.c:974
+#: builtin/merge.c:973
 #, c-format
 msgid "Bad value '%s' in environment '%s'"
 msgstr "Неправилна стойност „%s“ в средата „%s“"
 
-#: builtin/merge.c:1076
+#: builtin/merge.c:1075
 #, c-format
 msgid "not something we can merge in %s: %s"
 msgstr "не може да се слее в „%s“: %s"
 
-#: builtin/merge.c:1110
+#: builtin/merge.c:1109
 msgid "not something we can merge"
 msgstr "не може да се слее"
 
-#: builtin/merge.c:1212
+#: builtin/merge.c:1211
 msgid "--abort expects no arguments"
 msgstr "опцията „--abort“ не приема аргументи"
 
-#: builtin/merge.c:1216
+#: builtin/merge.c:1215
 msgid "There is no merge to abort (MERGE_HEAD missing)."
 msgstr ""
 "Не може да преустановите сливане, защото в момента не се извършва такова "
 "(липсва указател „MERGE_HEAD“)."
 
-#: builtin/merge.c:1228
+#: builtin/merge.c:1227
 msgid "--continue expects no arguments"
 msgstr "опцията „--continue“ не приема аргументи"
 
-#: builtin/merge.c:1232
+#: builtin/merge.c:1231
 msgid "There is no merge in progress (MERGE_HEAD missing)."
 msgstr "В момента не се извършва сливане (липсва указател „MERGE_HEAD“)."
 
-#: builtin/merge.c:1248
+#: builtin/merge.c:1247
 msgid ""
 "You have not concluded your merge (MERGE_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10914,7 +11394,7 @@ msgstr ""
 "Не сте завършили сливане.  (Указателят „MERGE_HEAD“ съществува).\n"
 "Подайте промените си, преди да започнете ново сливане."
 
-#: builtin/merge.c:1255
+#: builtin/merge.c:1254
 msgid ""
 "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10922,121 +11402,121 @@ msgstr ""
 "Не сте завършили отбиране на подаване (указателят „CHERRY_PICK_HEAD“\n"
 "съществува).  Подайте промените си, преди да започнете ново сливане."
 
-#: builtin/merge.c:1258
+#: builtin/merge.c:1257
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
 msgstr ""
 "Не сте завършили отбиране на подаване (указателят „CHERRY_PICK_HEAD“\n"
 "съществува)."
 
-#: builtin/merge.c:1267
+#: builtin/merge.c:1266
 msgid "You cannot combine --squash with --no-ff."
 msgstr "Опцията „--squash“ е несъвместима с „--no-ff“."
 
-#: builtin/merge.c:1275
+#: builtin/merge.c:1274
 msgid "No commit specified and merge.defaultToUpstream not set."
 msgstr ""
 "Не е указано подаване и настройката „merge.defaultToUpstream“ не е зададена."
 
-#: builtin/merge.c:1292
+#: builtin/merge.c:1291
 msgid "Squash commit into empty head not supported yet"
-msgstr "Ð\9fодаване Ñ\81Ñ\8aÑ\81 Ñ\81маÑ\87кване във връх без история все още не се поддържа"
+msgstr "Ð\92каÑ\80ване Ð½Ð° Ð¿Ð¾Ð´Ð°ване във връх без история все още не се поддържа"
 
-#: builtin/merge.c:1294
+#: builtin/merge.c:1293
 msgid "Non-fast-forward commit does not make sense into an empty head"
 msgstr ""
 "Понеже върхът е без история, всички сливания са превъртания, не може да се "
 "извърши същинско сливане изисквано от опцията „--no-ff“"
 
-#: builtin/merge.c:1299
+#: builtin/merge.c:1298
 #, c-format
 msgid "%s - not something we can merge"
 msgstr "„%s“ — не е нещо, което може да се слее"
 
-#: builtin/merge.c:1301
+#: builtin/merge.c:1300
 msgid "Can merge only exactly one commit into empty head"
 msgstr "Можете да слеете точно едно подаване във връх без история"
 
-#: builtin/merge.c:1335
+#: builtin/merge.c:1334
 #, c-format
 msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
 msgstr ""
 "Подаването „%s“ е с недоверен подпис от GPG, който твърди, че е на „%s“."
 
-#: builtin/merge.c:1338
+#: builtin/merge.c:1337
 #, c-format
 msgid "Commit %s has a bad GPG signature allegedly by %s."
 msgstr ""
 "Подаването „%s“ е с неправилен подпис от GPG, който твърди, че е на „%s“."
 
-#: builtin/merge.c:1341
+#: builtin/merge.c:1340
 #, c-format
 msgid "Commit %s does not have a GPG signature."
 msgstr "Подаването „%s“ е без подпис от GPG."
 
-#: builtin/merge.c:1344
+#: builtin/merge.c:1343
 #, c-format
 msgid "Commit %s has a good GPG signature by %s\n"
 msgstr "Подаването „%s“ е с коректен подпис от GPG на „%s“.\n"
 
-#: builtin/merge.c:1403
+#: builtin/merge.c:1402
 msgid "refusing to merge unrelated histories"
 msgstr "независими истории не може да се слеят"
 
-#: builtin/merge.c:1412
+#: builtin/merge.c:1411
 msgid "Already up to date."
 msgstr "Вече е обновено."
 
-#: builtin/merge.c:1422
+#: builtin/merge.c:1421
 #, c-format
 msgid "Updating %s..%s\n"
 msgstr "Обновяване „%s..%s“\n"
 
-#: builtin/merge.c:1463
+#: builtin/merge.c:1462
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
 msgstr "Проба със сливане в рамките на индекса…\n"
 
-#: builtin/merge.c:1470
+#: builtin/merge.c:1469
 #, c-format
 msgid "Nope.\n"
 msgstr "Неуспешно сливане.\n"
 
-#: builtin/merge.c:1495
+#: builtin/merge.c:1494
 msgid "Already up to date. Yeeah!"
 msgstr "Вече е обновено!"
 
-#: builtin/merge.c:1501
+#: builtin/merge.c:1500
 msgid "Not possible to fast-forward, aborting."
 msgstr "Не може да се извърши превъртане, преустановяване на действието."
 
-#: builtin/merge.c:1524 builtin/merge.c:1603
+#: builtin/merge.c:1523 builtin/merge.c:1602
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
 msgstr "Привеждане на дървото към първоначалното…\n"
 
-#: builtin/merge.c:1528
+#: builtin/merge.c:1527
 #, c-format
 msgid "Trying merge strategy %s...\n"
 msgstr "Пробване със стратегията за сливане „%s“…\n"
 
-#: builtin/merge.c:1594
+#: builtin/merge.c:1593
 #, c-format
 msgid "No merge strategy handled the merge.\n"
 msgstr "Никоя стратегия за сливане не може да извърши сливането.\n"
 
-#: builtin/merge.c:1596
+#: builtin/merge.c:1595
 #, c-format
 msgid "Merge with strategy %s failed.\n"
 msgstr "Неуспешно сливане със стратегия „%s“.\n"
 
-#: builtin/merge.c:1605
+#: builtin/merge.c:1604
 #, c-format
 msgid "Using the %s to prepare resolving by hand.\n"
 msgstr ""
 "Ползва се стратегията „%s“, която ще подготви дървото за коригиране на "
 "ръка.\n"
 
-#: builtin/merge.c:1617
+#: builtin/merge.c:1616
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr ""
@@ -11175,27 +11655,27 @@ msgstr "разрешаване на създаването на повече о
 msgid "git mv [<options>] <source>... <destination>"
 msgstr "git mv [ОПЦИЯ…] ОБЕКТ… ЦЕЛ"
 
-#: builtin/mv.c:83
+#: builtin/mv.c:82
 #, c-format
 msgid "Directory %s is in index and no submodule?"
 msgstr "Директорията „%s“ е в индекса, но не е подмодул"
 
-#: builtin/mv.c:85 builtin/rm.c:289
+#: builtin/mv.c:84 builtin/rm.c:288
 msgid "Please stage your changes to .gitmodules or stash them to proceed"
 msgstr ""
 "За да продължите, или вкарайте промените по файла „.gitmodules“ в индекса,\n"
 "или ги скатайте"
 
-#: builtin/mv.c:103
+#: builtin/mv.c:102
 #, c-format
 msgid "%.*s is in index"
 msgstr "„%.*s“ вече е в индекса"
 
-#: builtin/mv.c:125
+#: builtin/mv.c:124
 msgid "force move/rename even if target exists"
 msgstr "принудително преместване/преименуване дори целта да съществува"
 
-#: builtin/mv.c:127
+#: builtin/mv.c:126
 msgid "skip move/rename errors"
 msgstr "прескачане на грешките при преместване/преименуване"
 
@@ -11260,7 +11740,7 @@ msgstr "%s, обект: „%s“, цел: „%s“"
 msgid "Renaming %s to %s\n"
 msgstr "Преименуване на „%s“ на „%s“\n"
 
-#: builtin/mv.c:276 builtin/remote.c:712 builtin/repack.c:394
+#: builtin/mv.c:276 builtin/remote.c:715 builtin/repack.c:409
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "неуспешно преименуване на „%s“"
@@ -11454,12 +11934,12 @@ msgstr "обектът-бележка не може да бъде записан
 msgid "the note contents have been left in %s"
 msgstr "съдържанието на бележката е във файла „%s“"
 
-#: builtin/notes.c:234 builtin/tag.c:506
+#: builtin/notes.c:234 builtin/tag.c:507
 #, c-format
 msgid "cannot read '%s'"
 msgstr "файлът „%s“ не може да бъде прочетен"
 
-#: builtin/notes.c:236 builtin/tag.c:509
+#: builtin/notes.c:236 builtin/tag.c:510
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "файлът „%s“ не може да бъде отворен или прочетен"
@@ -11713,7 +12193,7 @@ msgstr "опитът за изтриването на несъществуващ
 msgid "read object names from the standard input"
 msgstr "изчитане на имената на обектите от стандартния вход"
 
-#: builtin/notes.c:943 builtin/prune.c:106 builtin/worktree.c:160
+#: builtin/notes.c:943 builtin/prune.c:107 builtin/worktree.c:151
 msgid "do not remove, show only"
 msgstr "само извеждане без действително окастряне"
 
@@ -11734,229 +12214,259 @@ msgstr "да се използва бележката сочена от този
 msgid "unknown subcommand: %s"
 msgstr "непозната подкоманда: %s"
 
-#: builtin/pack-objects.c:33
+#: builtin/pack-objects.c:48
 msgid ""
 "git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
 msgstr ""
 "git pack-objects --stdout [ОПЦИЯ…] [< СПИСЪК_С_УКАЗАТЕЛИ | < СПИСЪК_С_ОБЕКТИ]"
 
-#: builtin/pack-objects.c:34
+#: builtin/pack-objects.c:49
 msgid ""
 "git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
 msgstr ""
 "git pack-objects [ОПЦИЯ…] ПРЕФИКС_НА_ИМЕТО [< СПИСЪК_С_УКАЗАТЕЛИ | < "
 "СПИСЪК_С_ОБЕКТИ]"
 
-#: builtin/pack-objects.c:195 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:211 builtin/pack-objects.c:214
 #, c-format
 msgid "deflate error (%d)"
 msgstr "грешка при декомпресиране с „deflate“ (%d)"
 
-#: builtin/pack-objects.c:791
+#: builtin/pack-objects.c:810
 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
 msgstr ""
 "изключване на записването на битовата маска, пакетите са разделени поради "
 "стойността на „pack.packSizeLimit“"
 
-#: builtin/pack-objects.c:804
+#: builtin/pack-objects.c:823
 msgid "Writing objects"
 msgstr "Записване на обектите"
 
-#: builtin/pack-objects.c:1084
+#: builtin/pack-objects.c:1106
 msgid "disabling bitmap writing, as some objects are not being packed"
 msgstr ""
 "изключване на записването на битовата маска, защото някои обекти няма да се "
 "пакетират"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:1765
+msgid "Counting objects"
+msgstr "Преброяване на обектите"
+
+#: builtin/pack-objects.c:1895
+#, c-format
+msgid "unable to get size of %s"
+msgstr "размерът на „%s“ не може да бъде получен"
+
+#: builtin/pack-objects.c:1910
+#, c-format
+msgid "unable to parse object header of %s"
+msgstr "заглавната част на „%s“ не може да бъде анализирана"
+
+#: builtin/pack-objects.c:2564
 msgid "Compressing objects"
 msgstr "Компресиране на обектите"
 
-#: builtin/pack-objects.c:2625
+#: builtin/pack-objects.c:2735
 msgid "invalid value for --missing"
 msgstr "неправилна стойност за „--missing“"
 
-#: builtin/pack-objects.c:2928
+#: builtin/pack-objects.c:3067
 #, c-format
 msgid "unsupported index version %s"
 msgstr "неподдържана версия на индекса „%s“"
 
-#: builtin/pack-objects.c:2932
+#: builtin/pack-objects.c:3071
 #, c-format
 msgid "bad index version '%s'"
 msgstr "неправилна версия на индекса „%s“"
 
-#: builtin/pack-objects.c:2962
+#: builtin/pack-objects.c:3102
 msgid "do not show progress meter"
 msgstr "без извеждане на напредъка"
 
-#: builtin/pack-objects.c:2964
+#: builtin/pack-objects.c:3104
 msgid "show progress meter"
 msgstr "извеждане на напредъка"
 
-#: builtin/pack-objects.c:2966
+#: builtin/pack-objects.c:3106
 msgid "show progress meter during object writing phase"
 msgstr "извеждане на напредъка във фазата на запазване на обектите"
 
-#: builtin/pack-objects.c:2969
+#: builtin/pack-objects.c:3109
 msgid "similar to --all-progress when progress meter is shown"
 msgstr ""
 "същото действие като опцията „--all-progress“ при извеждането на напредъка"
 
-#: builtin/pack-objects.c:2970
+#: builtin/pack-objects.c:3110
 msgid "version[,offset]"
 msgstr "ВЕРСИЯ[,ОТМЕСТВАНЕ]"
 
-#: builtin/pack-objects.c:2971
+#: builtin/pack-objects.c:3111
 msgid "write the pack index file in the specified idx format version"
 msgstr ""
 "запазване на индекса на пакетните файлове във форма̀та с указаната версия"
 
-#: builtin/pack-objects.c:2974
+#: builtin/pack-objects.c:3114
 msgid "maximum size of each output pack file"
 msgstr "максимален размер на всеки пакетен файл"
 
-#: builtin/pack-objects.c:2976
+#: builtin/pack-objects.c:3116
 msgid "ignore borrowed objects from alternate object store"
 msgstr "игнориране на обектите заети от други хранилища на обекти"
 
-#: builtin/pack-objects.c:2978
+#: builtin/pack-objects.c:3118
 msgid "ignore packed objects"
 msgstr "игнориране на пакетираните обекти"
 
-#: builtin/pack-objects.c:2980
+#: builtin/pack-objects.c:3120
 msgid "limit pack window by objects"
 msgstr "ограничаване на прозореца за пакетиране по брой обекти"
 
-#: builtin/pack-objects.c:2982
+#: builtin/pack-objects.c:3122
 msgid "limit pack window by memory in addition to object limit"
 msgstr ""
 "ограничаване на прозореца за пакетиране и по памет освен по брой обекти"
 
-#: builtin/pack-objects.c:2984
+#: builtin/pack-objects.c:3124
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr ""
 "максимална дължина на веригата от разлики, която е позволена в пакетния файл"
 
-#: builtin/pack-objects.c:2986
+#: builtin/pack-objects.c:3126
 msgid "reuse existing deltas"
 msgstr "преизползване на съществуващите разлики"
 
-#: builtin/pack-objects.c:2988
+#: builtin/pack-objects.c:3128
 msgid "reuse existing objects"
 msgstr "преизползване на съществуващите обекти"
 
-#: builtin/pack-objects.c:2990
+#: builtin/pack-objects.c:3130
 msgid "use OFS_DELTA objects"
 msgstr "използване на обекти „OFS_DELTA“"
 
-#: builtin/pack-objects.c:2992
+#: builtin/pack-objects.c:3132
 msgid "use threads when searching for best delta matches"
 msgstr ""
 "стартиране на нишки за претърсване на най-добрите съвпадения на разликите"
 
-#: builtin/pack-objects.c:2994
+#: builtin/pack-objects.c:3134
 msgid "do not create an empty pack output"
 msgstr "без създаване на празен пакетен файл"
 
-#: builtin/pack-objects.c:2996
+#: builtin/pack-objects.c:3136
 msgid "read revision arguments from standard input"
 msgstr "изчитане на версиите от стандартния вход"
 
-#: builtin/pack-objects.c:2998
+#: builtin/pack-objects.c:3138
 msgid "limit the objects to those that are not yet packed"
 msgstr "ограничаване до все още непакетираните обекти"
 
-#: builtin/pack-objects.c:3001
+#: builtin/pack-objects.c:3141
 msgid "include objects reachable from any reference"
 msgstr ""
 "включване на всички обекти, които могат да се достигнат от произволен "
 "указател"
 
-#: builtin/pack-objects.c:3004
+#: builtin/pack-objects.c:3144
 msgid "include objects referred by reflog entries"
 msgstr "включване и на обектите сочени от записите в журнала на указателите"
 
-#: builtin/pack-objects.c:3007
+#: builtin/pack-objects.c:3147
 msgid "include objects referred to by the index"
 msgstr "включване и на обектите сочени от индекса"
 
-#: builtin/pack-objects.c:3010
+#: builtin/pack-objects.c:3150
 msgid "output pack to stdout"
 msgstr "извеждане на пакета на стандартния изход"
 
-#: builtin/pack-objects.c:3012
+#: builtin/pack-objects.c:3152
 msgid "include tag objects that refer to objects to be packed"
 msgstr ""
 "включване и на обектите-етикети, които сочат към обектите, които ще бъдат "
 "пакетирани"
 
-#: builtin/pack-objects.c:3014
+#: builtin/pack-objects.c:3154
 msgid "keep unreachable objects"
 msgstr "запазване на недостижимите обекти"
 
-#: builtin/pack-objects.c:3016
+#: builtin/pack-objects.c:3156
 msgid "pack loose unreachable objects"
 msgstr "пакетиране и на недостижимите обекти"
 
-#: builtin/pack-objects.c:3018
+#: builtin/pack-objects.c:3158
 msgid "unpack unreachable objects newer than <time>"
 msgstr "разпакетиране на недостижимите обекти, които са по-нови от това ВРЕМЕ"
 
-#: builtin/pack-objects.c:3021
+#: builtin/pack-objects.c:3161
 msgid "create thin packs"
 msgstr "създаване на съкратени пакети"
 
-#: builtin/pack-objects.c:3023
+#: builtin/pack-objects.c:3163
 msgid "create packs suitable for shallow fetches"
 msgstr "пакетиране подходящо за плитко доставяне"
 
-#: builtin/pack-objects.c:3025
+#: builtin/pack-objects.c:3165
 msgid "ignore packs that have companion .keep file"
 msgstr "игнориране на пакетите, които са придружени от файл „.keep“"
 
-#: builtin/pack-objects.c:3027
+#: builtin/pack-objects.c:3167
+msgid "ignore this pack"
+msgstr "пропускане на този пакет"
+
+#: builtin/pack-objects.c:3169
 msgid "pack compression level"
 msgstr "ниво на компресиране при пакетиране"
 
-#: builtin/pack-objects.c:3029
+#: builtin/pack-objects.c:3171
 msgid "do not hide commits by grafts"
 msgstr ""
 "извеждане на всички родители — дори и тези, които нормално са скрити при "
 "присажданията"
 
-#: builtin/pack-objects.c:3031
+#: builtin/pack-objects.c:3173
 msgid "use a bitmap index if available to speed up counting objects"
 msgstr ""
 "използване на съществуващи индекси на база битови маски за ускоряване на "
 "преброяването на обектите"
 
-#: builtin/pack-objects.c:3033
+#: builtin/pack-objects.c:3175
 msgid "write a bitmap index together with the pack index"
 msgstr ""
 "запазване и на индекс на база побитова маска, заедно с индекса за пакета"
 
-#: builtin/pack-objects.c:3036
+#: builtin/pack-objects.c:3178
 msgid "handling for missing objects"
 msgstr "как да се обработват липсващите обекти"
 
-#: builtin/pack-objects.c:3039
+#: builtin/pack-objects.c:3181
 msgid "do not pack objects in promisor packfiles"
 msgstr "без пакетиране на обекти в гарантиращи пакети"
 
-#: builtin/pack-objects.c:3178
-msgid "Counting objects"
-msgstr "Преброяване на обектите"
+#: builtin/pack-objects.c:3205
+#, c-format
+msgid "delta chain depth %d is too deep, forcing %d"
+msgstr "веригата с разлики е прекалено дълбока — %d, ще се ползва %d"
+
+#: builtin/pack-objects.c:3210
+#, c-format
+msgid "pack.deltaCacheLimit is too high, forcing %d"
+msgstr ""
+"Стойността на настройката „pack.deltaCacheLimit“ е прекалено голяма.  Ще се "
+"ползва %d"
+
+#: builtin/pack-objects.c:3338
+msgid "Enumerating objects"
+msgstr "Изброяване на обектите"
 
-#: builtin/pack-refs.c:6
+#: builtin/pack-refs.c:7
 msgid "git pack-refs [<options>]"
 msgstr "git pack-refs [ОПЦИЯ…]"
 
-#: builtin/pack-refs.c:14
+#: builtin/pack-refs.c:15
 msgid "pack everything"
 msgstr "пакетиране на всичко"
 
-#: builtin/pack-refs.c:15
+#: builtin/pack-refs.c:16
 msgid "prune loose refs (default)"
 msgstr "окастряне на недостижимите указатели (стандартно)"
 
@@ -11972,65 +12482,65 @@ msgstr "Изтриване на повтарящите се обекти"
 msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]"
 msgstr "git prune [-n] [-v] [--progress] [--expire ВРЕМЕ] [--] [ВРЪХ…]"
 
-#: builtin/prune.c:107
+#: builtin/prune.c:108
 msgid "report pruned objects"
 msgstr "информация за окастрените обекти"
 
-#: builtin/prune.c:110
+#: builtin/prune.c:111
 msgid "expire objects older than <time>"
 msgstr "окастряне на обектите по-стари от това ВРЕМЕ"
 
-#: builtin/prune.c:112
+#: builtin/prune.c:113
 msgid "limit traversal to objects outside promisor packfiles"
 msgstr "ограничаване на обхождането до обекти извън гарантиращи пакети"
 
-#: builtin/prune.c:126
+#: builtin/prune.c:127
 msgid "cannot prune in a precious-objects repo"
 msgstr "хранилище с важни обекти не може да се окастря"
 
-#: builtin/pull.c:54 builtin/pull.c:56
+#: builtin/pull.c:59 builtin/pull.c:61
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "Неправилна стойност за „%s“: „%s“"
 
-#: builtin/pull.c:76
+#: builtin/pull.c:81
 msgid "git pull [<options>] [<repository> [<refspec>...]]"
 msgstr "git push [ОПЦИЯ…] [ХРАНИЛИЩЕ [УКАЗАТЕЛ_НА_ВЕРСИЯ…]]"
 
-#: builtin/pull.c:127
+#: builtin/pull.c:132
 msgid "control for recursive fetching of submodules"
 msgstr "управление на рекурсивното доставяне на подмодулите"
 
-#: builtin/pull.c:131
+#: builtin/pull.c:136
 msgid "Options related to merging"
 msgstr "Опции при сливане"
 
-#: builtin/pull.c:134
+#: builtin/pull.c:139
 msgid "incorporate changes by rebasing rather than merging"
 msgstr "внасяне на промените чрез пребазиране, а не чрез сливане"
 
-#: builtin/pull.c:161 builtin/rebase--helper.c:23 builtin/revert.c:121
+#: builtin/pull.c:166 builtin/rebase--helper.c:23 builtin/revert.c:121
 msgid "allow fast-forward"
 msgstr "позволяване на превъртания"
 
-#: builtin/pull.c:170
+#: builtin/pull.c:175
 msgid "automatically stash/stash pop before and after rebase"
 msgstr "автоматично скатаване/прилагане на скатаното преди и след пребазиране"
 
-#: builtin/pull.c:186
+#: builtin/pull.c:191
 msgid "Options related to fetching"
 msgstr "Опции при доставяне"
 
-#: builtin/pull.c:204
+#: builtin/pull.c:209
 msgid "number of submodules pulled in parallel"
 msgstr "брой подмодули издърпани паралелно"
 
-#: builtin/pull.c:299
+#: builtin/pull.c:304
 #, c-format
 msgid "Invalid value for pull.ff: %s"
 msgstr "Неправилна стойност за „pull.ff“: „%s“"
 
-#: builtin/pull.c:415
+#: builtin/pull.c:420
 msgid ""
 "There is no candidate for rebasing against among the refs that you just "
 "fetched."
@@ -12038,14 +12548,14 @@ msgstr ""
 "Между указателите, които току що доставихте, няма подходящ кандидат, върху "
 "който да пребазирате."
 
-#: builtin/pull.c:417
+#: builtin/pull.c:422
 msgid ""
 "There are no candidates for merging among the refs that you just fetched."
 msgstr ""
 "Между указателите, които току що доставихте, няма подходящ кандидат, който "
 "да слеете."
 
-#: builtin/pull.c:418
+#: builtin/pull.c:423
 msgid ""
 "Generally this means that you provided a wildcard refspec which had no\n"
 "matches on the remote end."
@@ -12053,7 +12563,7 @@ msgstr ""
 "Най вероятно сте подали шаблон за указатели, който не е напаснал с нищо в "
 "отдалеченото хранилище."
 
-#: builtin/pull.c:421
+#: builtin/pull.c:426
 #, c-format
 msgid ""
 "You asked to pull from the remote '%s', but did not specify\n"
@@ -12064,44 +12574,44 @@ msgstr ""
 "Понеже това не е хранилището по подразбиране на текущия клон, трябва\n"
 "да укажете отдалечения клон на командния ред."
 
-#: builtin/pull.c:426 git-parse-remote.sh:73
+#: builtin/pull.c:431 git-parse-remote.sh:73
 msgid "You are not currently on a branch."
 msgstr "Извън всички клони."
 
-#: builtin/pull.c:428 builtin/pull.c:443 git-parse-remote.sh:79
+#: builtin/pull.c:433 builtin/pull.c:448 git-parse-remote.sh:79
 msgid "Please specify which branch you want to rebase against."
 msgstr "Укажете върху кой клон искате да пребазирате."
 
-#: builtin/pull.c:430 builtin/pull.c:445 git-parse-remote.sh:82
+#: builtin/pull.c:435 builtin/pull.c:450 git-parse-remote.sh:82
 msgid "Please specify which branch you want to merge with."
 msgstr "Укажете кой клон искате да слеете."
 
-#: builtin/pull.c:431 builtin/pull.c:446
+#: builtin/pull.c:436 builtin/pull.c:451
 msgid "See git-pull(1) for details."
 msgstr "За повече информация погледнете ръководството „git-pull(1)“"
 
-#: builtin/pull.c:433 builtin/pull.c:439 builtin/pull.c:448
+#: builtin/pull.c:438 builtin/pull.c:444 builtin/pull.c:453
 #: git-parse-remote.sh:64
 msgid "<remote>"
 msgstr "ОТДАЛЕЧЕНО_ХРАНИЛИЩЕ"
 
-#: builtin/pull.c:433 builtin/pull.c:448 builtin/pull.c:453 git-rebase.sh:477
+#: builtin/pull.c:438 builtin/pull.c:453 builtin/pull.c:458 git-rebase.sh:523
 #: git-parse-remote.sh:65
 msgid "<branch>"
 msgstr "КЛОН"
 
-#: builtin/pull.c:441 git-parse-remote.sh:75
+#: builtin/pull.c:446 git-parse-remote.sh:75
 msgid "There is no tracking information for the current branch."
 msgstr "Текущият клон не следи никой."
 
-#: builtin/pull.c:450 git-parse-remote.sh:95
+#: builtin/pull.c:455 git-parse-remote.sh:95
 msgid ""
 "If you wish to set tracking information for this branch you can do so with:"
 msgstr ""
 "Ако искате да зададете информация за следен клон, можете да направите това с "
 "командата:"
 
-#: builtin/pull.c:455
+#: builtin/pull.c:460
 #, c-format
 msgid ""
 "Your configuration specifies to merge with the ref '%s'\n"
@@ -12110,27 +12620,27 @@ msgstr ""
 "За сливане е указан отдалеченият указател „%s“,\n"
 "но такъв не е доставен."
 
-#: builtin/pull.c:819
+#: builtin/pull.c:826
 msgid "ignoring --verify-signatures for rebase"
 msgstr "без „--verify-signatures“ при пребазиране"
 
-#: builtin/pull.c:867
+#: builtin/pull.c:874
 msgid "--[no-]autostash option is only valid with --rebase."
 msgstr "опцията „--[no-]autostash“ изисква „--rebase“"
 
-#: builtin/pull.c:875
+#: builtin/pull.c:882
 msgid "Updating an unborn branch with changes added to the index."
 msgstr "Обновяване на все още несъздаден клон с промените от индекса"
 
-#: builtin/pull.c:878
+#: builtin/pull.c:885
 msgid "pull with rebase"
 msgstr "издърпване с пребазиране"
 
-#: builtin/pull.c:879
+#: builtin/pull.c:886
 msgid "please commit or stash them."
 msgstr "трябва да подадете или скатаете промените."
 
-#: builtin/pull.c:904
+#: builtin/pull.c:911
 #, c-format
 msgid ""
 "fetch updated the current branch head.\n"
@@ -12140,7 +12650,7 @@ msgstr ""
 "доставянето обнови върха на текущия клон.  Работното\n"
 "ви копие бе превъртяно от подаване „%s“."
 
-#: builtin/pull.c:909
+#: builtin/pull.c:916
 #, c-format
 msgid ""
 "Cannot fast-forward your working tree.\n"
@@ -12157,32 +12667,32 @@ msgstr ""
 "  $ git reset --hard\n"
 "за връщане към нормално състояние."
 
-#: builtin/pull.c:924
+#: builtin/pull.c:931
 msgid "Cannot merge multiple branches into empty head."
 msgstr "Не може да сливате множество клони в празен върхов указател."
 
-#: builtin/pull.c:928
+#: builtin/pull.c:935
 msgid "Cannot rebase onto multiple branches."
 msgstr "Не може да пребазирате върху повече от един клон."
 
-#: builtin/pull.c:935
+#: builtin/pull.c:942
 msgid "cannot rebase with locally recorded submodule modifications"
 msgstr ""
 "пребазирането е невъзможно заради локално записаните промени по подмодулите"
 
-#: builtin/push.c:17
+#: builtin/push.c:19
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr "git push [ОПЦИЯ…] [ХРАНИЛИЩЕ [УКАЗАТЕЛ_НА_ВЕРСИЯ…]]"
 
-#: builtin/push.c:92
+#: builtin/push.c:111
 msgid "tag shorthand without <tag>"
 msgstr "съкращение за етикет без ЕТИКЕТ"
 
-#: builtin/push.c:102
+#: builtin/push.c:121
 msgid "--delete only accepts plain target ref names"
 msgstr "опцията „--delete“ приема за цел само прости имена на указатели"
 
-#: builtin/push.c:146
+#: builtin/push.c:165
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -12191,7 +12701,7 @@ msgstr ""
 "За да включите тази опция за постоянно, погледнете документацията за "
 "настройката „push.default“ в „git help config“."
 
-#: builtin/push.c:149
+#: builtin/push.c:168
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -12216,7 +12726,7 @@ msgstr ""
 "    git push %s %s\n"
 "%s"
 
-#: builtin/push.c:164
+#: builtin/push.c:183
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -12230,7 +12740,7 @@ msgstr ""
 "\n"
 "    git push %s HEAD:ИМЕ_НА_ОТДАЛЕЧЕНИЯ_КЛОН\n"
 
-#: builtin/push.c:178
+#: builtin/push.c:197
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -12244,14 +12754,14 @@ msgstr ""
 "\n"
 "    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:186
+#: builtin/push.c:205
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr ""
 "Текущият клон „%s“ следи няколко отдалечени клона, не можете просто да "
 "изтласкате."
 
-#: builtin/push.c:189
+#: builtin/push.c:208
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -12263,14 +12773,14 @@ msgstr ""
 "Трябва да укажете коя версия да се изтласка, за обновяване на отдалечения "
 "клон."
 
-#: builtin/push.c:248
+#: builtin/push.c:267
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
 "Не сте указали версия за подаване, а настройката „push.default“ е "
 "„nothing“ (нищо без изрично указана версия да не се изтласква)"
 
-#: builtin/push.c:255
+#: builtin/push.c:274
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -12284,7 +12794,7 @@ msgstr ""
 "преди отново да изтласкате промените.  За повече информация вижте раздела\n"
 "„Note about fast-forwards“ в страницата от ръководството „git push --help“."
 
-#: builtin/push.c:261
+#: builtin/push.c:280
 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"
@@ -12298,7 +12808,7 @@ msgstr ""
 "информация погледнете раздела „Note about fast-forwards“ в страницата от\n"
 "ръководството „git push --help“."
 
-#: builtin/push.c:267
+#: builtin/push.c:286
 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"
@@ -12317,14 +12827,14 @@ msgstr ""
 "страницата\n"
 "от ръководството „git push --help“."
 
-#: builtin/push.c:274
+#: builtin/push.c:293
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr ""
 "Изтласкването е отхвърлено, защото в отдалеченото хранилище съществува "
 "етикет,\n"
 "който ще припокриете с етикет от вашето хранилище."
 
-#: builtin/push.c:277
+#: builtin/push.c:296
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -12334,22 +12844,22 @@ msgstr ""
 "указател, който вече сочи към обект, който не е подаване, както и тепърва\n"
 "да го промените да сочи към подобен обект.\n"
 
-#: builtin/push.c:337
+#: builtin/push.c:357
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "Изтласкване към „%s“\n"
 
-#: builtin/push.c:341
+#: builtin/push.c:361
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr "част от указателите не бяха изтласкани към „%s“"
 
-#: builtin/push.c:372
+#: builtin/push.c:395
 #, c-format
 msgid "bad repository '%s'"
 msgstr "неправилно указано хранилище „%s“"
 
-#: builtin/push.c:373
+#: builtin/push.c:396
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -12371,115 +12881,107 @@ msgstr ""
 "\n"
 "    git push ИМЕ\n"
 
-#: builtin/push.c:391
-msgid "--all and --tags are incompatible"
-msgstr "опциите „--all“ и „--tags“ са несъвместими"
-
-#: builtin/push.c:392
-msgid "--all can't be combined with refspecs"
-msgstr "опцията „--all“ е несъвместима с указването на версия"
-
-#: builtin/push.c:397
-msgid "--mirror and --tags are incompatible"
-msgstr "опциите „--mirror“ и „--tags“ са несъвместими"
-
-#: builtin/push.c:398
-msgid "--mirror can't be combined with refspecs"
-msgstr "опцията „--mirror“ е несъвместима с указването на версия"
-
-#: builtin/push.c:403
-msgid "--all and --mirror are incompatible"
-msgstr "опциите „--all“ и „--mirror“ са несъвместими"
-
-#: builtin/push.c:535
+#: builtin/push.c:551
 msgid "repository"
 msgstr "хранилище"
 
-#: builtin/push.c:536 builtin/send-pack.c:163
+#: builtin/push.c:552 builtin/send-pack.c:164
 msgid "push all refs"
 msgstr "изтласкване на всички указатели"
 
-#: builtin/push.c:537 builtin/send-pack.c:165
+#: builtin/push.c:553 builtin/send-pack.c:166
 msgid "mirror all refs"
 msgstr "огледално копие на всички указатели"
 
-#: builtin/push.c:539
+#: builtin/push.c:555
 msgid "delete refs"
 msgstr "изтриване на указателите"
 
-#: builtin/push.c:540
+#: builtin/push.c:556
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr "изтласкване на етикетите (несъвместимо с опциите „--all“ и „--mirror“)"
 
-#: builtin/push.c:543 builtin/send-pack.c:166
+#: builtin/push.c:559 builtin/send-pack.c:167
 msgid "force updates"
 msgstr "принудително обновяване"
 
-#: builtin/push.c:545 builtin/send-pack.c:180
+#: builtin/push.c:561 builtin/send-pack.c:181
 msgid "refname>:<expect"
 msgstr "УКАЗАТЕЛ>:<ОЧАКВАНА_СТОЙНОСТ"
 
-#: builtin/push.c:546 builtin/send-pack.c:181
+#: builtin/push.c:562 builtin/send-pack.c:182
 msgid "require old value of ref to be at this value"
 msgstr "УКАЗАТЕЛят трябва първоначално да е с тази ОЧАКВАНА_СТОЙНОСТ"
 
-#: builtin/push.c:549
+#: builtin/push.c:565
 msgid "control recursive pushing of submodules"
 msgstr "управление на рекурсивното изтласкване на подмодулите"
 
-#: builtin/push.c:551 builtin/send-pack.c:174
+#: builtin/push.c:567 builtin/send-pack.c:175
 msgid "use thin pack"
 msgstr "използване на съкратени пакети"
 
-#: builtin/push.c:552 builtin/push.c:553 builtin/send-pack.c:160
-#: builtin/send-pack.c:161
+#: builtin/push.c:568 builtin/push.c:569 builtin/send-pack.c:161
+#: builtin/send-pack.c:162
 msgid "receive pack program"
 msgstr "програма за получаването на пакети"
 
-#: builtin/push.c:554
+#: builtin/push.c:570
 msgid "set upstream for git pull/status"
 msgstr "задаване на отдалеченото хранилище за командите „git pull/status“"
 
-#: builtin/push.c:557
+#: builtin/push.c:573
 msgid "prune locally removed refs"
 msgstr "окастряне на указателите, които са премахнати от локалното хранилище"
 
-#: builtin/push.c:559
+#: builtin/push.c:575
 msgid "bypass pre-push hook"
 msgstr "без изпълнение на куката преди изтласкване (pre-push)"
 
-#: builtin/push.c:560
+#: builtin/push.c:576
 msgid "push missing but relevant tags"
 msgstr ""
 "изтласкване на липсващите в отдалеченото хранилище, но свързани с текущото "
 "изтласкване, етикети"
 
-#: builtin/push.c:563 builtin/send-pack.c:168
+#: builtin/push.c:579 builtin/send-pack.c:169
 msgid "GPG sign the push"
 msgstr "подписване на изтласкването с GPG"
 
-#: builtin/push.c:565 builtin/send-pack.c:175
+#: builtin/push.c:581 builtin/send-pack.c:176
 msgid "request atomic transaction on remote side"
 msgstr "изискване на атомарни операции от отсрещната страна"
 
-#: builtin/push.c:566 builtin/send-pack.c:171
-msgid "server-specific"
-msgstr "специфични за сървъра"
-
-#: builtin/push.c:566 builtin/send-pack.c:172
-msgid "option to transmit"
-msgstr "опция за пренос"
-
-#: builtin/push.c:583
+#: builtin/push.c:599
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr ""
 "опцията „--delete“ е несъвместима с опциите  „--all“, „--mirror“ и „--tags“"
 
-#: builtin/push.c:585
+#: builtin/push.c:601
 msgid "--delete doesn't make sense without any refs"
 msgstr "опцията „--delete“ изисква поне един указател на версия"
 
 #: builtin/push.c:604
+msgid "--all and --tags are incompatible"
+msgstr "опциите „--all“ и „--tags“ са несъвместими"
+
+#: builtin/push.c:606
+msgid "--all can't be combined with refspecs"
+msgstr "опцията „--all“ е несъвместима с указването на версия"
+
+#: builtin/push.c:610
+msgid "--mirror and --tags are incompatible"
+msgstr "опциите „--mirror“ и „--tags“ са несъвместими"
+
+#: builtin/push.c:612
+msgid "--mirror can't be combined with refspecs"
+msgstr "опцията „--mirror“ е несъвместима с указването на версия"
+
+#: builtin/push.c:615
+msgid "--all and --mirror are incompatible"
+msgstr "опциите „--all“ и „--mirror“ са несъвместими"
+
+#: builtin/push.c:634
 msgid "push options must not have new line characters"
 msgstr "опциите за изтласкване не трябва да съдържат знак за нов ред"
 
@@ -12494,67 +12996,67 @@ msgstr ""
 "checkout] [--index-output=ФАЙЛ] (--empty | УКАЗАТЕЛ_КЪМ_ДЪРВО_1 "
 "[УКАЗАТЕЛ_КЪМ_ДЪРВО_2 [УКАЗАТЕЛ_КЪМ_ДЪРВО_3]])"
 
-#: builtin/read-tree.c:121
+#: builtin/read-tree.c:120
 msgid "write resulting index to <file>"
 msgstr "запазване на индекса в този ФАЙЛ"
 
-#: builtin/read-tree.c:124
+#: builtin/read-tree.c:123
 msgid "only empty the index"
 msgstr "само зануляване на индекса"
 
-#: builtin/read-tree.c:126
+#: builtin/read-tree.c:125
 msgid "Merging"
 msgstr "Сливане"
 
-#: builtin/read-tree.c:128
+#: builtin/read-tree.c:127
 msgid "perform a merge in addition to a read"
 msgstr "да се извърши и сливане след освен изчитането"
 
-#: builtin/read-tree.c:130
+#: builtin/read-tree.c:129
 msgid "3-way merge if no file level merging required"
 msgstr "тройно сливане, ако не се налага пофайлово сливане"
 
-#: builtin/read-tree.c:132
+#: builtin/read-tree.c:131
 msgid "3-way merge in presence of adds and removes"
 msgstr "тройно сливане при добавяне на добавяне и изтриване на файлове"
 
-#: builtin/read-tree.c:134
+#: builtin/read-tree.c:133
 msgid "same as -m, but discard unmerged entries"
 msgstr "същото като опцията „-m“, но неслетите обекти се пренебрегват"
 
-#: builtin/read-tree.c:135
+#: builtin/read-tree.c:134
 msgid "<subdirectory>/"
 msgstr "ПОДДИРЕКТОРИЯ/"
 
-#: builtin/read-tree.c:136
+#: builtin/read-tree.c:135
 msgid "read the tree into the index under <subdirectory>/"
 msgstr "изчитане на дървото към индекса като да е в тази ПОДДИРЕКТОРИЯ/"
 
-#: builtin/read-tree.c:139
+#: builtin/read-tree.c:138
 msgid "update working tree with merge result"
 msgstr "обновяване на работното дърво с резултата от сливането"
 
-#: builtin/read-tree.c:141
+#: builtin/read-tree.c:140
 msgid "gitignore"
 msgstr "ФАЙЛ_С_ИЗКЛЮЧЕНИЯ"
 
-#: builtin/read-tree.c:142
+#: builtin/read-tree.c:141
 msgid "allow explicitly ignored files to be overwritten"
 msgstr "позволяване на презаписването на изрично пренебрегваните файлове"
 
-#: builtin/read-tree.c:145
+#: builtin/read-tree.c:144
 msgid "don't check the working tree after merging"
 msgstr "без проверка на работното дърво след сливането"
 
-#: builtin/read-tree.c:146
+#: builtin/read-tree.c:145
 msgid "don't update the index or the work tree"
 msgstr "без обновяване и на индекса, и на работното дърво"
 
-#: builtin/read-tree.c:148
+#: builtin/read-tree.c:147
 msgid "skip applying sparse checkout filter"
 msgstr "без прилагане на филтъра за частично изтегляне"
 
-#: builtin/read-tree.c:150
+#: builtin/read-tree.c:149
 msgid "debug unpack-trees"
 msgstr "изчистване на грешки в командата „unpack-trees“"
 
@@ -12571,48 +13073,61 @@ msgid "allow commits with empty messages"
 msgstr "позволяване на празни съобщения при подаване"
 
 #: builtin/rebase--helper.c:27
+msgid "rebase merge commits"
+msgstr "пребазиране на подаванията със сливания"
+
+#: builtin/rebase--helper.c:29
+msgid "keep original branch points of cousins"
+msgstr ""
+"запазване на първоначалните точки на разклоняване на сестринските клони"
+
+#: builtin/rebase--helper.c:30
 msgid "continue rebase"
 msgstr "продължаване на пребазирането"
 
-#: builtin/rebase--helper.c:29
+#: builtin/rebase--helper.c:32
 msgid "abort rebase"
 msgstr "преустановяване на пребазирането"
 
-#: builtin/rebase--helper.c:32
+#: builtin/rebase--helper.c:35
 msgid "make rebase script"
 msgstr "създаване на скрипт за пребазиране"
 
-#: builtin/rebase--helper.c:34
+#: builtin/rebase--helper.c:37
 msgid "shorten commit ids in the todo list"
 msgstr "съкратени идентификатори в списъка за изпълнение"
 
-#: builtin/rebase--helper.c:36
+#: builtin/rebase--helper.c:39
 msgid "expand commit ids in the todo list"
 msgstr "пълни идентификатори в списъка за изпълнение"
 
-#: builtin/rebase--helper.c:38
+#: builtin/rebase--helper.c:41
 msgid "check the todo list"
 msgstr "проверка на списъка за изпълнение"
 
-#: builtin/rebase--helper.c:40
+#: builtin/rebase--helper.c:43
 msgid "skip unnecessary picks"
 msgstr "прескачане на излишните команди за отбиране"
 
-#: builtin/rebase--helper.c:42
+#: builtin/rebase--helper.c:45
 msgid "rearrange fixup/squash lines"
 msgstr ""
-"преподреждане на редовете за сливане на подаванията със и без смени на "
-"съобщението"
+"преподреждане на редовете за вкарване на подаванията подаванията в "
+"предходните им със и без смени на съобщението"
 
-#: builtin/rebase--helper.c:44
+#: builtin/rebase--helper.c:47
 msgid "insert exec commands in todo list"
 msgstr "вмъкване на командите за изпълнение в списъка за изпълнение"
 
-#: builtin/receive-pack.c:30
+#: builtin/rebase--helper.c:68
+msgid "--[no-]rebase-cousins has no effect without --rebase-merges"
+msgstr "опциите „--[no-]rebase-cousins“ изискват опцията „--rebase-merges“"
+
+#: builtin/receive-pack.c:31
 msgid "git receive-pack <git-dir>"
 msgstr "git receive-pack ДИРЕКТОРИЯ_НА_GIT"
 
-#: builtin/receive-pack.c:841
+#: builtin/receive-pack.c:842
 msgid ""
 "By default, updating the current branch in a non-bare repository\n"
 "is denied, because it will make the index and work tree inconsistent\n"
@@ -12645,7 +13160,7 @@ msgstr ""
 "За да заглушите това съобщение, като запазите стандартното поведение,\n"
 "задайте настройката „receive.denyCurrentBranch“ да е „refuse“ (отказ)."
 
-#: builtin/receive-pack.c:861
+#: builtin/receive-pack.c:862
 msgid ""
 "By default, deleting the current branch is denied, because the next\n"
 "'git clone' won't result in any file checked out, causing confusion.\n"
@@ -12666,11 +13181,11 @@ msgstr ""
 "За да заглушите това съобщение, задайте настройката\n"
 "„receive.denyDeleteCurrent“ да е „refuse“ (отказ)."
 
-#: builtin/receive-pack.c:1934
+#: builtin/receive-pack.c:1935
 msgid "quiet"
 msgstr "без извеждане на информация"
 
-#: builtin/receive-pack.c:1948
+#: builtin/receive-pack.c:1949
 msgid "You must specify a directory."
 msgstr "Трябва да укажете директория."
 
@@ -12679,11 +13194,11 @@ msgstr "Трябва да укажете директория."
 msgid "'%s' is not a valid timestamp"
 msgstr "„%s“ не е правилна стойност за време"
 
-#: builtin/remote.c:13
+#: builtin/remote.c:14
 msgid "git remote [-v | --verbose]"
 msgstr "git remote [-v | --verbose]"
 
-#: builtin/remote.c:14
+#: builtin/remote.c:15
 msgid ""
 "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <name> <url>"
@@ -12691,83 +13206,83 @@ msgstr ""
 "git remote add [-t КЛОН] [-m ОСНОВЕН_КЛОН] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] ИМЕ АДРЕС"
 
-#: builtin/remote.c:15 builtin/remote.c:35
+#: builtin/remote.c:16 builtin/remote.c:36
 msgid "git remote rename <old> <new>"
 msgstr "git remote rename СТАРО_ИМЕ НОВО_ИМЕ"
 
-#: builtin/remote.c:16 builtin/remote.c:40
+#: builtin/remote.c:17 builtin/remote.c:41
 msgid "git remote remove <name>"
 msgstr "git remote remove ИМЕ"
 
-#: builtin/remote.c:17 builtin/remote.c:45
+#: builtin/remote.c:18 builtin/remote.c:46
 msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
 msgstr "git remote set-head ИМЕ (-a | --auto | -d | --delete | КЛОН)"
 
-#: builtin/remote.c:18
+#: builtin/remote.c:19
 msgid "git remote [-v | --verbose] show [-n] <name>"
 msgstr "git remote [-v | --verbose] show [-n] ИМЕ"
 
-#: builtin/remote.c:19
+#: builtin/remote.c:20
 msgid "git remote prune [-n | --dry-run] <name>"
 msgstr "git remote prune [-n | --dry-run] ИМЕ"
 
-#: builtin/remote.c:20
+#: builtin/remote.c:21
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
 msgstr ""
 "git remote [-v | --verbose] update [-p | --prune] [(ГРУПА | "
 "ОТДАЛЕЧЕНО_ХРАНИЛИЩЕ)…]"
 
-#: builtin/remote.c:21
+#: builtin/remote.c:22
 msgid "git remote set-branches [--add] <name> <branch>..."
 msgstr "git remote set-branches [--add] ИМЕ КЛОН…"
 
-#: builtin/remote.c:22 builtin/remote.c:71
+#: builtin/remote.c:23 builtin/remote.c:72
 msgid "git remote get-url [--push] [--all] <name>"
 msgstr "git remote get-url [--push] [--all] ИМЕ"
 
-#: builtin/remote.c:23 builtin/remote.c:76
+#: builtin/remote.c:24 builtin/remote.c:77
 msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]"
 msgstr "git remote set-url [--push] ИМЕ НОВ_АДРЕС [СТАР_АДРЕС]"
 
-#: builtin/remote.c:24 builtin/remote.c:77
+#: builtin/remote.c:25 builtin/remote.c:78
 msgid "git remote set-url --add <name> <newurl>"
 msgstr "git remote set-url --add ИМЕ НОВ_АДРЕС"
 
-#: builtin/remote.c:25 builtin/remote.c:78
+#: builtin/remote.c:26 builtin/remote.c:79
 msgid "git remote set-url --delete <name> <url>"
 msgstr "git remote set-url --delete ИМЕ АДРЕС"
 
-#: builtin/remote.c:30
+#: builtin/remote.c:31
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [ОПЦИЯ…] ИМЕ АДРЕС"
 
-#: builtin/remote.c:50
+#: builtin/remote.c:51
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches ИМЕ КЛОН…"
 
-#: builtin/remote.c:51
+#: builtin/remote.c:52
 msgid "git remote set-branches --add <name> <branch>..."
 msgstr "git remote set-branches --add ИМЕ КЛОН…"
 
-#: builtin/remote.c:56
+#: builtin/remote.c:57
 msgid "git remote show [<options>] <name>"
 msgstr "git remote show [ОПЦИЯ…] ИМЕ"
 
-#: builtin/remote.c:61
+#: builtin/remote.c:62
 msgid "git remote prune [<options>] <name>"
 msgstr "git remote prune [ОПЦИЯ…] ИМЕ"
 
-#: builtin/remote.c:66
+#: builtin/remote.c:67
 msgid "git remote update [<options>] [<group> | <remote>]..."
 msgstr "git remote update [ОПЦИЯ…] [ГРУПА | ОТДАЛЕЧЕНО_ХРАНИЛИЩЕ…]"
 
-#: builtin/remote.c:95
+#: builtin/remote.c:96
 #, c-format
 msgid "Updating %s"
 msgstr "Обновяване на „%s“"
 
-#: builtin/remote.c:127
+#: builtin/remote.c:128
 msgid ""
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
@@ -12775,90 +13290,90 @@ msgstr ""
 "Използването само на „--mirror“ е опасно.  Вместо това\n"
 "ползвайте „--mirror=fetch“ или „--mirror=push“"
 
-#: builtin/remote.c:144
+#: builtin/remote.c:145
 #, c-format
 msgid "unknown mirror argument: %s"
 msgstr "неправилна стойност за „--mirror“: %s"
 
-#: builtin/remote.c:160
+#: builtin/remote.c:161
 msgid "fetch the remote branches"
 msgstr "отдалечените клони не могат да бъдат доставени"
 
-#: builtin/remote.c:162
+#: builtin/remote.c:163
 msgid "import all tags and associated objects when fetching"
 msgstr "внасяне на всички етикети и принадлежащите им обекти при доставяне"
 
-#: builtin/remote.c:165
+#: builtin/remote.c:166
 msgid "or do not fetch any tag at all (--no-tags)"
 msgstr "може и да не се доставят никакви етикети (чрез опцията „--no-tags“)"
 
-#: builtin/remote.c:167
+#: builtin/remote.c:168
 msgid "branch(es) to track"
 msgstr "клон/и за следене"
 
-#: builtin/remote.c:168
+#: builtin/remote.c:169
 msgid "master branch"
 msgstr "основен клон"
 
-#: builtin/remote.c:169
+#: builtin/remote.c:170
 msgid "push|fetch"
 msgstr "издърпване|доставяне"
 
-#: builtin/remote.c:170
+#: builtin/remote.c:171
 msgid "set up remote as a mirror to push to or fetch from"
 msgstr ""
 "настройване на отдалечено хранилище, от което да се издърпва или доставя"
 
-#: builtin/remote.c:182
+#: builtin/remote.c:183
 msgid "specifying a master branch makes no sense with --mirror"
 msgstr ""
 "няма смисъл да се указва основен клон при използване на опцията „--mirror“"
 
-#: builtin/remote.c:184
+#: builtin/remote.c:185
 msgid "specifying branches to track makes sense only with fetch mirrors"
 msgstr ""
 "указването на следени клони е смислено само за отдалечени хранилища, от "
 "които се доставя"
 
-#: builtin/remote.c:191 builtin/remote.c:631
+#: builtin/remote.c:192 builtin/remote.c:634
 #, c-format
 msgid "remote %s already exists."
 msgstr "вече съществува отдалечено хранилище с име „%s“."
 
-#: builtin/remote.c:195 builtin/remote.c:635
+#: builtin/remote.c:196 builtin/remote.c:638
 #, c-format
 msgid "'%s' is not a valid remote name"
 msgstr "„%s“ е неправилно име за отдалечено хранилище"
 
-#: builtin/remote.c:235
+#: builtin/remote.c:236
 #, c-format
 msgid "Could not setup master '%s'"
 msgstr "Основният клон „%s“ не може да бъде настроен"
 
-#: builtin/remote.c:337
+#: builtin/remote.c:342
 #, c-format
 msgid "Could not get fetch map for refspec %s"
 msgstr "Обектите за доставяне за указателя „%s“ не могат да бъдат получени"
 
-#: builtin/remote.c:438 builtin/remote.c:446
+#: builtin/remote.c:441 builtin/remote.c:449
 msgid "(matching)"
 msgstr "(съвпадащи)"
 
-#: builtin/remote.c:450
+#: builtin/remote.c:453
 msgid "(delete)"
 msgstr "(за изтриване)"
 
-#: builtin/remote.c:624 builtin/remote.c:759 builtin/remote.c:858
+#: builtin/remote.c:627 builtin/remote.c:762 builtin/remote.c:861
 #, c-format
 msgid "No such remote: %s"
 msgstr "Такова отдалечено хранилище няма: %s"
 
-#: builtin/remote.c:641
+#: builtin/remote.c:644
 #, c-format
 msgid "Could not rename config section '%s' to '%s'"
 msgstr "Разделът „%s“ в настройките не може да бъде преименуван на „%s“"
 
-#: builtin/remote.c:661
+#: builtin/remote.c:664
 #, c-format
 msgid ""
 "Not updating non-default fetch refspec\n"
@@ -12869,17 +13384,17 @@ msgstr ""
 "    %s\n"
 "  Променете настройките ръчно, ако е необходимо."
 
-#: builtin/remote.c:697
+#: builtin/remote.c:700
 #, c-format
 msgid "deleting '%s' failed"
 msgstr "неуспешно изтриване на „%s“"
 
-#: builtin/remote.c:731
+#: builtin/remote.c:734
 #, c-format
 msgid "creating '%s' failed"
 msgstr "неуспешно създаване на „%s“"
 
-#: builtin/remote.c:796
+#: builtin/remote.c:799
 msgid ""
 "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
 "to delete it, use:"
@@ -12893,116 +13408,121 @@ msgstr[1] ""
 "Бележка: Няколко клона извън йерархията „refs/remotes/“ не бяха изтрити.\n"
 "Изтрийте ги чрез командата:"
 
-#: builtin/remote.c:810
+#: builtin/remote.c:813
 #, c-format
 msgid "Could not remove config section '%s'"
 msgstr "Разделът „%s“ в настройките не може да бъде изтрит"
 
-#: builtin/remote.c:911
+#: builtin/remote.c:914
 #, c-format
 msgid " new (next fetch will store in remotes/%s)"
 msgstr " нов (следващото доставяне ще го разположи в „remotes/%s“)"
 
-#: builtin/remote.c:914
+#: builtin/remote.c:917
 msgid " tracked"
 msgstr " следен"
 
-#: builtin/remote.c:916
+#: builtin/remote.c:919
 msgid " stale (use 'git remote prune' to remove)"
 msgstr " стар (изтрийте чрез „git remote prune“)"
 
-#: builtin/remote.c:918
+#: builtin/remote.c:921
 msgid " ???"
 msgstr " неясно състояние"
 
 # CHECK
-#: builtin/remote.c:959
+#: builtin/remote.c:962
 #, c-format
 msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
 msgstr ""
 "неправилен клон за сливане „%s“.  Невъзможно е да пребазирате върху повече "
 "от 1 клон"
 
-#: builtin/remote.c:967
+#: builtin/remote.c:971
 #, c-format
 msgid "rebases interactively onto remote %s"
 msgstr "интерактивно пребазиране върху отдалечения клон „%s“"
 
-#: builtin/remote.c:968
+#: builtin/remote.c:973
+#, c-format
+msgid "rebases interactively (with merges) onto remote %s"
+msgstr "интерактивно пребазиране (със сливания) върху отдалечения клон „%s“"
+
+#: builtin/remote.c:976
 #, c-format
 msgid "rebases onto remote %s"
 msgstr "пребазиране върху отдалечения клон „%s“"
 
-#: builtin/remote.c:971
+#: builtin/remote.c:980
 #, c-format
 msgid " merges with remote %s"
 msgstr " сливане с отдалечения клон „%s“"
 
-#: builtin/remote.c:974
+#: builtin/remote.c:983
 #, c-format
 msgid "merges with remote %s"
 msgstr "сливане с отдалечения клон „%s“"
 
-#: builtin/remote.c:977
+#: builtin/remote.c:986
 #, c-format
 msgid "%-*s    and with remote %s\n"
 msgstr "%-*s    и с отдалечения клон „%s“\n"
 
-#: builtin/remote.c:1020
+#: builtin/remote.c:1029
 msgid "create"
 msgstr "създаден"
 
-#: builtin/remote.c:1023
+#: builtin/remote.c:1032
 msgid "delete"
 msgstr "изтрит"
 
-#: builtin/remote.c:1027
+#: builtin/remote.c:1036
 msgid "up to date"
 msgstr "актуален"
 
-#: builtin/remote.c:1030
+#: builtin/remote.c:1039
 msgid "fast-forwardable"
 msgstr "може да се превърти"
 
-#: builtin/remote.c:1033
+#: builtin/remote.c:1042
 msgid "local out of date"
 msgstr "локалният е изостанал"
 
-#: builtin/remote.c:1040
+#: builtin/remote.c:1049
 #, c-format
 msgid "    %-*s forces to %-*s (%s)"
 msgstr "    %-*s принудително изтласква към %-*s (%s)"
 
-#: builtin/remote.c:1043
+#: builtin/remote.c:1052
 #, c-format
 msgid "    %-*s pushes to %-*s (%s)"
 msgstr "    %-*s изтласква към %-*s (%s)"
 
-#: builtin/remote.c:1047
+#: builtin/remote.c:1056
 #, c-format
 msgid "    %-*s forces to %s"
 msgstr "    %-*s принудително изтласква към %s"
 
-#: builtin/remote.c:1050
+#: builtin/remote.c:1059
 #, c-format
 msgid "    %-*s pushes to %s"
 msgstr "    %-*s изтласква към %s"
 
-#: builtin/remote.c:1118
+#: builtin/remote.c:1127
 msgid "do not query remotes"
 msgstr "без заявки към отдалечените хранилища"
 
-#: builtin/remote.c:1145
+#: builtin/remote.c:1154
 #, c-format
 msgid "* remote %s"
 msgstr "● отдалечено хранилище „%s“"
 
-#: builtin/remote.c:1146
+#: builtin/remote.c:1155
 #, c-format
 msgid "  Fetch URL: %s"
 msgstr "  Адрес за доставяне: %s"
 
-#: builtin/remote.c:1147 builtin/remote.c:1163 builtin/remote.c:1302
+#: builtin/remote.c:1156 builtin/remote.c:1172 builtin/remote.c:1311
 msgid "(no URL)"
 msgstr "(без адрес)"
 
@@ -13010,25 +13530,25 @@ msgstr "(без адрес)"
 #. with the one in " Fetch URL: %s"
 #. translation.
 #.
-#: builtin/remote.c:1161 builtin/remote.c:1163
+#: builtin/remote.c:1170 builtin/remote.c:1172
 #, c-format
 msgid "  Push  URL: %s"
 msgstr "  Адрес за изтласкване: %s"
 
-#: builtin/remote.c:1165 builtin/remote.c:1167 builtin/remote.c:1169
+#: builtin/remote.c:1174 builtin/remote.c:1176 builtin/remote.c:1178
 #, c-format
 msgid "  HEAD branch: %s"
 msgstr "  клон сочен от HEAD: %s"
 
-#: builtin/remote.c:1165
+#: builtin/remote.c:1174
 msgid "(not queried)"
 msgstr "(без проверка)"
 
-#: builtin/remote.c:1167
+#: builtin/remote.c:1176
 msgid "(unknown)"
 msgstr "(непознат)"
 
-#: builtin/remote.c:1171
+#: builtin/remote.c:1180
 #, c-format
 msgid ""
 "  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
@@ -13037,161 +13557,161 @@ msgstr ""
 "хранилище\n"
 "  не е еднозначен и е някой от следните):\n"
 
-#: builtin/remote.c:1183
+#: builtin/remote.c:1192
 #, c-format
 msgid "  Remote branch:%s"
 msgid_plural "  Remote branches:%s"
 msgstr[0] "  Отдалечен клон:%s"
 msgstr[1] "  Отдалечени клони:%s"
 
-#: builtin/remote.c:1186 builtin/remote.c:1212
+#: builtin/remote.c:1195 builtin/remote.c:1221
 msgid " (status not queried)"
 msgstr " (състоянието не бе проверено)"
 
-#: builtin/remote.c:1195
+#: builtin/remote.c:1204
 msgid "  Local branch configured for 'git pull':"
 msgid_plural "  Local branches configured for 'git pull':"
 msgstr[0] "  Локален клон настроен за издърпване чрез „git pull“:"
 msgstr[1] "  Локални клони настроени за издърпване чрез „git pull“:"
 
-#: builtin/remote.c:1203
+#: builtin/remote.c:1212
 msgid "  Local refs will be mirrored by 'git push'"
 msgstr "  Локалните указатели ще бъдат пренесени чрез „ push“"
 
-#: builtin/remote.c:1209
+#: builtin/remote.c:1218
 #, c-format
 msgid "  Local ref configured for 'git push'%s:"
 msgid_plural "  Local refs configured for 'git push'%s:"
 msgstr[0] "  Локалният указател, настроен за „git push“%s:"
 msgstr[1] "  Локалните указатели, настроени за „git push“%s:"
 
-#: builtin/remote.c:1230
+#: builtin/remote.c:1239
 msgid "set refs/remotes/<name>/HEAD according to remote"
 msgstr "задаване на refs/remotes/ИМЕ/HEAD според отдалеченото хранилище"
 
-#: builtin/remote.c:1232
+#: builtin/remote.c:1241
 msgid "delete refs/remotes/<name>/HEAD"
 msgstr "изтриване на refs/remotes/ИМЕ/HEAD"
 
-#: builtin/remote.c:1247
+#: builtin/remote.c:1256
 msgid "Cannot determine remote HEAD"
 msgstr "Не може да се установи отдалеченият връх"
 
-#: builtin/remote.c:1249
+#: builtin/remote.c:1258
 msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
 msgstr ""
 "Множество клони с върхове.  Изберете изрично някой от тях чрез командата:"
 
-#: builtin/remote.c:1259
+#: builtin/remote.c:1268
 #, c-format
 msgid "Could not delete %s"
 msgstr "„%s“ не може да бъде изтрит"
 
-#: builtin/remote.c:1267
+#: builtin/remote.c:1276
 #, c-format
 msgid "Not a valid ref: %s"
 msgstr "Неправилен указател: %s"
 
-#: builtin/remote.c:1269
+#: builtin/remote.c:1278
 #, c-format
 msgid "Could not setup %s"
 msgstr "„%s“ не може да се настрои"
 
-#: builtin/remote.c:1287
+#: builtin/remote.c:1296
 #, c-format
 msgid " %s will become dangling!"
 msgstr "„%s“ ще се превърне в обект извън клоните!"
 
-#: builtin/remote.c:1288
+#: builtin/remote.c:1297
 #, c-format
 msgid " %s has become dangling!"
 msgstr "„%s“ се превърна в обект извън клоните!"
 
-#: builtin/remote.c:1298
+#: builtin/remote.c:1307
 #, c-format
 msgid "Pruning %s"
 msgstr "Окастряне на „%s“"
 
-#: builtin/remote.c:1299
+#: builtin/remote.c:1308
 #, c-format
 msgid "URL: %s"
 msgstr "адрес: %s"
 
-#: builtin/remote.c:1315
+#: builtin/remote.c:1324
 #, c-format
 msgid " * [would prune] %s"
 msgstr " ● [ще бъде окастрено] %s"
 
-#: builtin/remote.c:1318
+#: builtin/remote.c:1327
 #, c-format
 msgid " * [pruned] %s"
 msgstr " ● [окастрено] %s"
 
-#: builtin/remote.c:1363
+#: builtin/remote.c:1372
 msgid "prune remotes after fetching"
 msgstr "окастряне на огледалата на отдалечените хранилища след доставяне"
 
-#: builtin/remote.c:1426 builtin/remote.c:1480 builtin/remote.c:1548
+#: builtin/remote.c:1435 builtin/remote.c:1489 builtin/remote.c:1557
 #, c-format
 msgid "No such remote '%s'"
 msgstr "Няма отдалечено хранилище на име „%s“"
 
-#: builtin/remote.c:1442
+#: builtin/remote.c:1451
 msgid "add branch"
 msgstr "добавяне на клон"
 
-#: builtin/remote.c:1449
+#: builtin/remote.c:1458
 msgid "no remote specified"
 msgstr "не е указано отдалечено хранилище"
 
-#: builtin/remote.c:1466
+#: builtin/remote.c:1475
 msgid "query push URLs rather than fetch URLs"
 msgstr "запитване към адресите за изтласкване, а не за доставяне"
 
-#: builtin/remote.c:1468
+#: builtin/remote.c:1477
 msgid "return all URLs"
 msgstr "извеждане на всички адреси"
 
-#: builtin/remote.c:1496
+#: builtin/remote.c:1505
 #, c-format
 msgid "no URLs configured for remote '%s'"
 msgstr "не е зададен адрес за отдалеченото хранилище „%s“"
 
-#: builtin/remote.c:1522
+#: builtin/remote.c:1531
 msgid "manipulate push URLs"
 msgstr "промяна на адресите за изтласкване"
 
-#: builtin/remote.c:1524
+#: builtin/remote.c:1533
 msgid "add URL"
 msgstr "добавяне на адреси"
 
-#: builtin/remote.c:1526
+#: builtin/remote.c:1535
 msgid "delete URLs"
 msgstr "изтриване на адреси"
 
-#: builtin/remote.c:1533
+#: builtin/remote.c:1542
 msgid "--add --delete doesn't make sense"
 msgstr "опциите „--add“ и „--delete“ са несъвместими"
 
-#: builtin/remote.c:1572
+#: builtin/remote.c:1581
 #, c-format
 msgid "Invalid old URL pattern: %s"
 msgstr "Неправилен (стар) формат за адрес: %s"
 
-#: builtin/remote.c:1580
+#: builtin/remote.c:1589
 #, c-format
 msgid "No such URL found: %s"
 msgstr "Такъв адрес не е открит: %s"
 
-#: builtin/remote.c:1582
+#: builtin/remote.c:1591
 msgid "Will not delete all non-push URLs"
 msgstr "Никой от адресите, които не са за изтласкване, няма да се изтрие"
 
-#: builtin/remote.c:1598
+#: builtin/remote.c:1607
 msgid "be verbose; must be placed before a subcommand"
 msgstr "повече подробности.  Поставя се пред подкоманда"
 
-#: builtin/remote.c:1629
+#: builtin/remote.c:1638
 #, c-format
 msgid "Unknown subcommand: %s"
 msgstr "Непозната подкоманда: %s"
@@ -13209,136 +13729,144 @@ msgstr ""
 "Ползвайте опцията --no-write-bitmap-index или изключете настройката\n"
 "„pack.writebitmaps“."
 
-#: builtin/repack.c:170
+#: builtin/repack.c:180
 msgid "pack everything in a single pack"
 msgstr "пакетиране на всичко в пакет"
 
-#: builtin/repack.c:172
+#: builtin/repack.c:182
 msgid "same as -a, and turn unreachable objects loose"
 msgstr ""
 "същото като опцията „-a“.  Допълнително — недостижимите обекти да станат "
 "непакетирани"
 
-#: builtin/repack.c:175
+#: builtin/repack.c:185
 msgid "remove redundant packs, and run git-prune-packed"
 msgstr ""
 "премахване на ненужните пакетирани файлове и изпълнение на командата „git-"
 "prune-packed“"
 
-#: builtin/repack.c:177
+#: builtin/repack.c:187
 msgid "pass --no-reuse-delta to git-pack-objects"
 msgstr "подаване на опцията „--no-reuse-delta“ на командата „git-pack-objects“"
 
-#: builtin/repack.c:179
+#: builtin/repack.c:189
 msgid "pass --no-reuse-object to git-pack-objects"
 msgstr ""
 "подаване на опцията „--no-reuse-object“ на командата „git-pack-objects“"
 
-#: builtin/repack.c:181
+#: builtin/repack.c:191
 msgid "do not run git-update-server-info"
 msgstr "без изпълнение на командата „git-update-server-info“"
 
-#: builtin/repack.c:184
+#: builtin/repack.c:194
 msgid "pass --local to git-pack-objects"
 msgstr "подаване на опцията „--local“ на командата „git-pack-objects“"
 
-#: builtin/repack.c:186
+#: builtin/repack.c:196
 msgid "write bitmap index"
 msgstr "създаване и записване на индекси на база битови маски"
 
-#: builtin/repack.c:187
+#: builtin/repack.c:197
 msgid "approxidate"
 msgstr "евристична дата"
 
-#: builtin/repack.c:188
+#: builtin/repack.c:198
 msgid "with -A, do not loosen objects older than this"
 msgstr ""
 "при комбинирането с опцията „-A“ — без разпакетиране на обектите по стари от "
 "това"
 
-#: builtin/repack.c:190
+#: builtin/repack.c:200
 msgid "with -a, repack unreachable objects"
 msgstr "с „-a“ — препакетиране на недостижимите обекти"
 
-#: builtin/repack.c:192
+#: builtin/repack.c:202
 msgid "size of the window used for delta compression"
 msgstr "размер на прозореца за делта компресията"
 
-#: builtin/repack.c:193 builtin/repack.c:199
+#: builtin/repack.c:203 builtin/repack.c:209
 msgid "bytes"
 msgstr "байтове"
 
-#: builtin/repack.c:194
+#: builtin/repack.c:204
 msgid "same as the above, but limit memory size instead of entries count"
 msgstr ""
 "същото като горната опция, но ограничението да е по размер на паметта, а не "
 "по броя на обектите"
 
-#: builtin/repack.c:196
+#: builtin/repack.c:206
 msgid "limits the maximum delta depth"
 msgstr "ограничаване на максималната дълбочина на делтата"
 
-#: builtin/repack.c:198
+#: builtin/repack.c:208
 msgid "limits the maximum number of threads"
 msgstr "ограничаване на максималния брой нишки"
 
-#: builtin/repack.c:200
+#: builtin/repack.c:210
 msgid "maximum size of each packfile"
 msgstr "максимален размер на всеки пакет"
 
-#: builtin/repack.c:202
+#: builtin/repack.c:212
 msgid "repack objects in packs marked with .keep"
 msgstr "препакетиране на обектите в пакети белязани с „.keep“"
 
-#: builtin/repack.c:212
+#: builtin/repack.c:214
+msgid "do not repack this pack"
+msgstr "без препакетиране на този пакет"
+
+#: builtin/repack.c:224
 msgid "cannot delete packs in a precious-objects repo"
 msgstr "пакетите в хранилище с важни обекти не може да се трият"
 
-#: builtin/repack.c:216
+#: builtin/repack.c:228
 msgid "--keep-unreachable and -A are incompatible"
 msgstr "Опциите „--keep-unreachable“ и „-A“ са несъвместими"
 
-#: builtin/repack.c:410 builtin/worktree.c:148
+#: builtin/repack.c:425 builtin/worktree.c:139
 #, c-format
 msgid "failed to remove '%s'"
 msgstr "директорията „%s“ не може да бъде изтрита"
 
-#: builtin/replace.c:20
+#: builtin/replace.c:22
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] ОБЕКТ ЗАМЯНА"
 
-#: builtin/replace.c:21
+#: builtin/replace.c:23
 msgid "git replace [-f] --edit <object>"
 msgstr "git replace [-f] --edit ОБЕКТ"
 
-#: builtin/replace.c:22
+#: builtin/replace.c:24
 msgid "git replace [-f] --graft <commit> [<parent>...]"
 msgstr "git replace [-f] --graft ПОДАВАНЕ [РОДИТЕЛ…]"
 
-#: builtin/replace.c:23
+#: builtin/replace.c:25
+msgid "git replace [-f] --convert-graft-file"
+msgstr "git replace [-f] --convert-graft-file"
+
+#: builtin/replace.c:26
 msgid "git replace -d <object>..."
 msgstr "git replace -d ОБЕКТ…"
 
-#: builtin/replace.c:24
+#: builtin/replace.c:27
 msgid "git replace [--format=<format>] [-l [<pattern>]]"
 msgstr "git replace [--format=ФОРМАТ] [-l [ШАБЛОН]]"
 
-#: builtin/replace.c:331 builtin/replace.c:369 builtin/replace.c:397
+#: builtin/replace.c:371 builtin/replace.c:415 builtin/replace.c:445
 #, c-format
 msgid "Not a valid object name: '%s'"
 msgstr "Неправилно име на обект: „%s“"
 
-#: builtin/replace.c:361
+#: builtin/replace.c:407
 #, c-format
 msgid "bad mergetag in commit '%s'"
 msgstr "етикетът при сливане в подаването „%s“ e неправилен"
 
-#: builtin/replace.c:363
+#: builtin/replace.c:409
 #, c-format
 msgid "malformed mergetag in commit '%s'"
 msgstr "етикетът при сливане в подаването „%s“ e неправилен"
 
-#: builtin/replace.c:374
+#: builtin/replace.c:421
 #, c-format
 msgid ""
 "original commit '%s' contains mergetag '%s' that is discarded; use --edit "
@@ -13347,45 +13875,58 @@ msgstr ""
 "Първоначалното подаване „%s“ съдържа етикета при сливане „%s“, който е "
 "изхвърлен, затова използвайте опцията „--edit“, а не „--graft“."
 
-#: builtin/replace.c:407
+#: builtin/replace.c:460
 #, c-format
 msgid "the original commit '%s' has a gpg signature."
 msgstr "Първоначалното подаване „%s“ е с подпис на GPG."
 
-#: builtin/replace.c:408
+#: builtin/replace.c:461
 msgid "the signature will be removed in the replacement commit!"
 msgstr "Подписът ще бъде премахнат в заменящото подаване!"
 
-#: builtin/replace.c:414
+#: builtin/replace.c:471
 #, c-format
 msgid "could not write replacement commit for: '%s'"
 msgstr "заменящото подаване за „%s“ не може да бъде записано"
 
-#: builtin/replace.c:438
+#: builtin/replace.c:514
+#, c-format
+msgid ""
+"could not convert the following graft(s):\n"
+"%s"
+msgstr ""
+"следните присадки не могат да се преобразуват:\n"
+"%s"
+
+#: builtin/replace.c:535
 msgid "list replace refs"
 msgstr "извеждане на списъка с указателите за замяна"
 
-#: builtin/replace.c:439
+#: builtin/replace.c:536
 msgid "delete replace refs"
 msgstr "изтриване на указателите за замяна"
 
-#: builtin/replace.c:440
+#: builtin/replace.c:537
 msgid "edit existing object"
 msgstr "редактиране на съществуващ обект"
 
-#: builtin/replace.c:441
+#: builtin/replace.c:538
 msgid "change a commit's parents"
 msgstr "смяна на родителите на подаване"
 
-#: builtin/replace.c:442
+#: builtin/replace.c:539
+msgid "convert existing graft file"
+msgstr "преобразуване на файла за присадките"
+
+#: builtin/replace.c:540
 msgid "replace the ref if it exists"
 msgstr "замяна на указателя, ако съществува"
 
-#: builtin/replace.c:444
+#: builtin/replace.c:542
 msgid "do not pretty-print contents for --edit"
 msgstr "без форматирано извеждане на съдържанието — за опцията „--edit“"
 
-#: builtin/replace.c:445
+#: builtin/replace.c:543
 msgid "use this format"
 msgstr "използване на този ФОРМАТ"
 
@@ -13548,23 +14089,23 @@ msgstr "командата „rev-list“ не поддържа извеждан
 msgid "cannot combine --use-bitmap-index with object filtering"
 msgstr "опцията „--use-bitmap-index“ е несъвместима с филтриране на обектите"
 
-#: builtin/rev-parse.c:402
+#: builtin/rev-parse.c:406
 msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
 msgstr "git rev-parse --parseopt [ОПЦИЯ…] -- [АРГУМЕНТ…]"
 
-#: builtin/rev-parse.c:407
+#: builtin/rev-parse.c:411
 msgid "keep the `--` passed as an arg"
 msgstr "зададеният низ „--“ да се тълкува като аргумент"
 
-#: builtin/rev-parse.c:409
+#: builtin/rev-parse.c:413
 msgid "stop parsing after the first non-option argument"
 msgstr "спиране на анализа след първия аргумент, който не е опция"
 
-#: builtin/rev-parse.c:412
+#: builtin/rev-parse.c:416
 msgid "output in stuck long form"
 msgstr "изход в дългия формат"
 
-#: builtin/rev-parse.c:545
+#: builtin/rev-parse.c:549
 msgid ""
 "git rev-parse --parseopt [<options>] -- [<args>...]\n"
 "   or: git rev-parse --sq-quote [<arg>...]\n"
@@ -13709,44 +14250,44 @@ msgid_plural "the following files have local modifications:"
 msgstr[0] "следният файл е с променено съдържание"
 msgstr[1] "следните файлове са с променено съдържание"
 
-#: builtin/rm.c:243
+#: builtin/rm.c:241
 msgid "do not list removed files"
 msgstr "да не се извеждат изтритите файлове"
 
-#: builtin/rm.c:244
+#: builtin/rm.c:242
 msgid "only remove from the index"
 msgstr "изтриване само от индекса"
 
-#: builtin/rm.c:245
+#: builtin/rm.c:243
 msgid "override the up-to-date check"
 msgstr "въпреки проверката за актуалността на съдържанието"
 
-#: builtin/rm.c:246
+#: builtin/rm.c:244
 msgid "allow recursive removal"
 msgstr "рекурсивно изтриване"
 
-#: builtin/rm.c:248
+#: builtin/rm.c:246
 msgid "exit with a zero status even if nothing matched"
 msgstr ""
 "изходният код да е 0, дори ако никой файл нe e напаснал с шаблона за "
 "изтриване"
 
-#: builtin/rm.c:307
+#: builtin/rm.c:306
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "без използването на опцията „-r“ „%s“ няма да се изтрие рекурсивно"
 
-#: builtin/rm.c:346
+#: builtin/rm.c:345
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm: „%s“ не може да се изтрие"
 
-#: builtin/rm.c:369
+#: builtin/rm.c:368
 #, c-format
 msgid "could not remove '%s'"
 msgstr "„%s“ не може да бъде изтрит"
 
-#: builtin/send-pack.c:19
+#: builtin/send-pack.c:20
 msgid ""
 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-"
 "receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> "
@@ -13757,52 +14298,72 @@ msgstr ""
 "pack=ПАКЕТ] [--verbose] [--thin] [--atomic] [ХОСТ:]ДИРЕКТОРИЯ [УКАЗАТЕЛ…]\n"
 "  опцията „--all“ и изричното посочване на УКАЗАТЕЛ са взаимно несъвместими."
 
-#: builtin/send-pack.c:162
+#: builtin/send-pack.c:163
 msgid "remote name"
 msgstr "име на отдалечено хранилище"
 
-#: builtin/send-pack.c:176
+#: builtin/send-pack.c:177
 msgid "use stateless RPC protocol"
 msgstr "използване на протокол без запазване на състоянието за RPC"
 
-#: builtin/send-pack.c:177
+#: builtin/send-pack.c:178
 msgid "read refs from stdin"
 msgstr "четене на указателите от стандартния вход"
 
-#: builtin/send-pack.c:178
+#: builtin/send-pack.c:179
 msgid "print status from remote helper"
 msgstr "извеждане на състоянието от отдалечената помощна функция"
 
+#: builtin/serve.c:7
+msgid "git serve [<options>]"
+msgstr "git serve [ОПЦИЯ…]"
+
+#: builtin/serve.c:17 builtin/upload-pack.c:23
+msgid "quit after a single request/response exchange"
+msgstr "изход след първоначалната размяна на заявка и отговор"
+
+#: builtin/serve.c:19
+msgid "exit immediately after advertising capabilities"
+msgstr "изход след първоначалната обява на възможностите"
+
 #: builtin/shortlog.c:14
-msgid "git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"
+msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]"
 msgstr "git shortlog [ОПЦИЯ…] [ДИАПАЗОН_НА_ВЕРСИИТЕ] [[--] [ПЪТ…]]"
 
-#: builtin/shortlog.c:263
+#: builtin/shortlog.c:15
+msgid "git log --pretty=short | git shortlog [<options>]"
+msgstr "git log --pretty=short | git shortlog [ОПЦИЯ…]"
+
+#: builtin/shortlog.c:264
 msgid "Group by committer rather than author"
 msgstr "Групиране по подаващ, а не по автор"
 
-#: builtin/shortlog.c:265
+#: builtin/shortlog.c:266
 msgid "sort output according to the number of commits per author"
 msgstr "подредба на подаванията по броя подавания от автор"
 
-#: builtin/shortlog.c:267
+#: builtin/shortlog.c:268
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr "Без описания на подаванията — да се показва само броя подавания"
 
-#: builtin/shortlog.c:269
+#: builtin/shortlog.c:270
 msgid "Show the email address of each author"
 msgstr "Извеждане на адреса на е-поща за всеки автор"
 
-#: builtin/shortlog.c:270
+#: builtin/shortlog.c:271
 msgid "w[,i1[,i2]]"
 msgstr "ШИРОЧИНА[,ОТСТЪП_1[,ОТСТЪП_2]]"
 
-#: builtin/shortlog.c:271
+#: builtin/shortlog.c:272
 msgid "Linewrap output"
 msgstr ""
 "Пренасяне на редовете до тази обща ШИРОЧИНА (76), с ОТСТЪП_1 (6) за първия "
 "ред и ОТСТЪП_2 (9) за останалите"
 
+#: builtin/shortlog.c:298
+msgid "too many arguments given outside repository"
+msgstr "прекалено много аргументи извън хранилище"
+
 #: builtin/show-branch.c:12
 msgid ""
 "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
@@ -14005,40 +14566,40 @@ msgstr "пропускане на всички редове, които запо
 msgid "prepend comment character and space to each line"
 msgstr "добавяне на „# “ в началото на всеки ред"
 
-#: builtin/submodule--helper.c:35 builtin/submodule--helper.c:1669
+#: builtin/submodule--helper.c:37 builtin/submodule--helper.c:1688
 #, c-format
 msgid "No such ref: %s"
 msgstr "Такъв указател няма: %s"
 
-#: builtin/submodule--helper.c:42 builtin/submodule--helper.c:1678
+#: builtin/submodule--helper.c:44 builtin/submodule--helper.c:1697
 #, c-format
 msgid "Expecting a full ref name, got %s"
 msgstr "Очаква се пълно име на указател, а не „%s“"
 
-#: builtin/submodule--helper.c:59
+#: builtin/submodule--helper.c:61
 msgid "submodule--helper print-default-remote takes no arguments"
 msgstr ""
 "командата „print-default-remote“ на „submodule--helper“ не приема аргументи"
 
-#: builtin/submodule--helper.c:96
+#: builtin/submodule--helper.c:98
 #, c-format
 msgid "cannot strip one component off url '%s'"
 msgstr "не може да се махне компонент от адреса „%s“"
 
-#: builtin/submodule--helper.c:404 builtin/submodule--helper.c:1198
+#: builtin/submodule--helper.c:406 builtin/submodule--helper.c:1211
 msgid "alternative anchor for relative paths"
 msgstr "директория за определянето на относителните пътища"
 
-#: builtin/submodule--helper.c:409
+#: builtin/submodule--helper.c:411
 msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper list [--prefix=ПЪТ] [ПЪТ…]"
 
-#: builtin/submodule--helper.c:460 builtin/submodule--helper.c:483
+#: builtin/submodule--helper.c:462 builtin/submodule--helper.c:485
 #, c-format
 msgid "No url found for submodule path '%s' in .gitmodules"
 msgstr "Във файла „.gitmodules“ не е открит адрес за пътя към подмодул „%s“"
 
-#: builtin/submodule--helper.c:498
+#: builtin/submodule--helper.c:500
 #, c-format
 msgid ""
 "could not lookup configuration '%s'. Assuming this repository is its own "
@@ -14047,55 +14608,55 @@ msgstr ""
 "настройката „%s“ липсва.  Приема се, че това хранилище е правилният източник "
 "за себе си."
 
-#: builtin/submodule--helper.c:509
+#: builtin/submodule--helper.c:511
 #, c-format
 msgid "Failed to register url for submodule path '%s'"
 msgstr "Неуспешно регистриране на адрес за пътя към подмодул „%s“"
 
-#: builtin/submodule--helper.c:513
+#: builtin/submodule--helper.c:515
 #, c-format
 msgid "Submodule '%s' (%s) registered for path '%s'\n"
 msgstr "Регистриран е подмодул „%s“ (%s) за пътя към подмодул „%s“\n"
 
-#: builtin/submodule--helper.c:523
+#: builtin/submodule--helper.c:525
 #, c-format
 msgid "warning: command update mode suggested for submodule '%s'\n"
 msgstr "ПРЕДУПРЕЖДЕНИЕ: препоръчва се режим на обновяване за подмодула „%s“\n"
 
-#: builtin/submodule--helper.c:530
+#: builtin/submodule--helper.c:532
 #, c-format
 msgid "Failed to register update mode for submodule path '%s'"
 msgstr ""
 "Неуспешно регистриране на режима на обновяване за пътя към подмодул „%s“"
 
-#: builtin/submodule--helper.c:552
+#: builtin/submodule--helper.c:554
 msgid "Suppress output for initializing a submodule"
 msgstr "Без извеждане на информация при инициализирането на подмодул"
 
-#: builtin/submodule--helper.c:557
+#: builtin/submodule--helper.c:559
 msgid "git submodule--helper init [<path>]"
 msgstr "git submodule--helper name [ПЪТ]"
 
-#: builtin/submodule--helper.c:625 builtin/submodule--helper.c:747
+#: builtin/submodule--helper.c:631 builtin/submodule--helper.c:757
 #, c-format
 msgid "no submodule mapping found in .gitmodules for path '%s'"
 msgstr "Във файла „.gitmodules“ липсва информация за пътя „%s“"
 
-#: builtin/submodule--helper.c:660
+#: builtin/submodule--helper.c:670
 #, c-format
 msgid "could not resolve HEAD ref inside the submodule '%s'"
 msgstr "указателят сочен от „HEAD“ в подмодула „%s“ не може да бъде открит"
 
-#: builtin/submodule--helper.c:687 builtin/submodule--helper.c:856
+#: builtin/submodule--helper.c:697 builtin/submodule--helper.c:866
 #, c-format
 msgid "failed to recurse into submodule '%s'"
 msgstr "неуспешно рекурсивно обхождане на подмодула „%s“"
 
-#: builtin/submodule--helper.c:711 builtin/submodule--helper.c:1021
+#: builtin/submodule--helper.c:721 builtin/submodule--helper.c:1031
 msgid "Suppress submodule status output"
 msgstr "Заглушаване на изхода за състоянието на подмодула"
 
-#: builtin/submodule--helper.c:712
+#: builtin/submodule--helper.c:722
 msgid ""
 "Use commit stored in the index instead of the one stored in the submodule "
 "HEAD"
@@ -14103,51 +14664,51 @@ msgstr ""
 "Използване на подаването указано в индекса, а не това от указателя „HEAD“ на "
 "подмодула"
 
-#: builtin/submodule--helper.c:713
+#: builtin/submodule--helper.c:723
 msgid "recurse into nested submodules"
 msgstr "рекурсивно обхождане на подмодулите"
 
-#: builtin/submodule--helper.c:718
+#: builtin/submodule--helper.c:728
 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
 msgstr "git submodule status [--quiet] [--cached] [--recursive] [ПЪТ…]"
 
-#: builtin/submodule--helper.c:742
+#: builtin/submodule--helper.c:752
 msgid "git submodule--helper name <path>"
 msgstr "git submodule--helper name ПЪТ"
 
-#: builtin/submodule--helper.c:806
+#: builtin/submodule--helper.c:816
 #, c-format
 msgid "Synchronizing submodule url for '%s'\n"
 msgstr "Синхронизиране на адреса на подмодул за „%s“\n"
 
-#: builtin/submodule--helper.c:812
+#: builtin/submodule--helper.c:822
 #, c-format
 msgid "failed to register url for submodule path '%s'"
 msgstr "неуспешно регистриране на адрес за пътя към подмодул „%s“"
 
-#: builtin/submodule--helper.c:826
+#: builtin/submodule--helper.c:836
 #, c-format
 msgid "failed to get the default remote for submodule '%s'"
 msgstr "отдалеченият адрес на подмодула „%s“ не може да бъде получен"
 
-#: builtin/submodule--helper.c:837
+#: builtin/submodule--helper.c:847
 #, c-format
 msgid "failed to update remote for submodule '%s'"
 msgstr "отдалеченият адрес на подмодула „%s“ не може да бъде променен"
 
-#: builtin/submodule--helper.c:885
+#: builtin/submodule--helper.c:895
 msgid "Suppress output of synchronizing submodule url"
 msgstr "Без извеждане на информация при синхронизирането на подмодул"
 
-#: builtin/submodule--helper.c:887
+#: builtin/submodule--helper.c:897
 msgid "Recurse into nested submodules"
 msgstr "Рекурсивно обхождане на подмодулите"
 
-#: builtin/submodule--helper.c:892
+#: builtin/submodule--helper.c:902
 msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
 msgstr "git submodule--helper sync [--quiet] [--recursive] [ПЪТ]"
 
-#: builtin/submodule--helper.c:946
+#: builtin/submodule--helper.c:956
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you "
@@ -14156,7 +14717,7 @@ msgstr ""
 "Работното дърво на подмодул „%s“ съдържа директория „.git“.\n"
 "(ако искате да ги изтриете заедно с цялата им история, използвайте „rm -rf“)"
 
-#: builtin/submodule--helper.c:958
+#: builtin/submodule--helper.c:968
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains local modifications; use '-f' to discard "
@@ -14165,83 +14726,83 @@ msgstr ""
 "Работното дърво на подмодул „%s“ съдържа локални промени.  Можете да ги "
 "отхвърлите с опцията „-f“"
 
-#: builtin/submodule--helper.c:966
+#: builtin/submodule--helper.c:976
 #, c-format
 msgid "Cleared directory '%s'\n"
 msgstr "Директорията „%s“ е изчистена\n"
 
-#: builtin/submodule--helper.c:968
+#: builtin/submodule--helper.c:978
 #, c-format
 msgid "Could not remove submodule work tree '%s'\n"
 msgstr ""
 "Директорията към работното дърво на подмодула „%s“ не може да бъде изтрита\n"
 
-#: builtin/submodule--helper.c:977
+#: builtin/submodule--helper.c:987
 #, c-format
 msgid "could not create empty submodule directory %s"
 msgstr "празната директория за подмодула „%s“ не може да бъде създадена"
 
-#: builtin/submodule--helper.c:993
+#: builtin/submodule--helper.c:1003
 #, c-format
 msgid "Submodule '%s' (%s) unregistered for path '%s'\n"
 msgstr "Регистрацията на подмодула „%s“ (%s) за пътя „%s“ е премахната\n"
 
-#: builtin/submodule--helper.c:1022
+#: builtin/submodule--helper.c:1032
 msgid "Remove submodule working trees even if they contain local changes"
 msgstr ""
 "Изтриване на работните дървета на подмодулите, дори когато те съдържат "
 "локални промени"
 
-#: builtin/submodule--helper.c:1023
+#: builtin/submodule--helper.c:1033
 msgid "Unregister all submodules"
 msgstr "Премахване на регистрациите на всички подмодули"
 
-#: builtin/submodule--helper.c:1028
+#: builtin/submodule--helper.c:1038
 msgid ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
 msgstr "git submodule deinit [--quiet] [-f | --force] [--all | [--] [ПЪТ…]]"
 
-#: builtin/submodule--helper.c:1042
+#: builtin/submodule--helper.c:1052
 msgid "Use '--all' if you really want to deinitialize all submodules"
 msgstr "Използвайте „--all“, за да премахнете всички подмодули"
 
-#: builtin/submodule--helper.c:1133 builtin/submodule--helper.c:1136
+#: builtin/submodule--helper.c:1145 builtin/submodule--helper.c:1148
 #, c-format
 msgid "submodule '%s' cannot add alternate: %s"
 msgstr "към подмодула „%s“ не може да се добави алтернативен източник: %s"
 
-#: builtin/submodule--helper.c:1172
+#: builtin/submodule--helper.c:1184
 #, c-format
 msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized"
 msgstr ""
 "Непозната стойност „%s“ за настройката „submodule.alternateErrorStrategy“"
 
-#: builtin/submodule--helper.c:1179
+#: builtin/submodule--helper.c:1191
 #, c-format
 msgid "Value '%s' for submodule.alternateLocation is not recognized"
 msgstr "Непозната стойност „%s“ за настройката „submodule.alternateLocation“"
 
-#: builtin/submodule--helper.c:1201
+#: builtin/submodule--helper.c:1214
 msgid "where the new submodule will be cloned to"
 msgstr "къде да се клонира новият подмодул"
 
-#: builtin/submodule--helper.c:1204
+#: builtin/submodule--helper.c:1217
 msgid "name of the new submodule"
 msgstr "име на новия подмодул"
 
-#: builtin/submodule--helper.c:1207
+#: builtin/submodule--helper.c:1220
 msgid "url where to clone the submodule from"
 msgstr "адрес, от който да се клонира новият подмодул"
 
-#: builtin/submodule--helper.c:1213
+#: builtin/submodule--helper.c:1228
 msgid "depth for shallow clones"
 msgstr "дълбочина на плитките хранилища"
 
-#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1587
+#: builtin/submodule--helper.c:1231 builtin/submodule--helper.c:1606
 msgid "force cloning progress"
 msgstr "извеждане на напредъка на клонирането"
 
-#: builtin/submodule--helper.c:1221
+#: builtin/submodule--helper.c:1236
 msgid ""
 "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
 "<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>"
@@ -14249,85 +14810,85 @@ msgstr ""
 "git submodule--helper clone [--prefix=ПЪТ] [--quiet] [--reference ХРАНИЛИЩЕ] "
 "[--name ИМЕ] [--depth ДЪЛБОЧИНА] --url АДРЕС --path ПЪТ…"
 
-#: builtin/submodule--helper.c:1252
+#: builtin/submodule--helper.c:1267
 #, c-format
 msgid "clone of '%s' into submodule path '%s' failed"
 msgstr "Неуспешно клониране на адреса „%s“ в пътя „%s“ като подмодул"
 
-#: builtin/submodule--helper.c:1267
+#: builtin/submodule--helper.c:1281
 #, c-format
 msgid "could not get submodule directory for '%s'"
 msgstr "директорията на подмодула „%s“ не може да бъде получена"
 
-#: builtin/submodule--helper.c:1332
+#: builtin/submodule--helper.c:1347
 #, c-format
 msgid "Submodule path '%s' not initialized"
 msgstr "Пътят на подмодула „%s“ не е инициализиран"
 
-#: builtin/submodule--helper.c:1336
+#: builtin/submodule--helper.c:1351
 msgid "Maybe you want to use 'update --init'?"
 msgstr "Вероятно искахте да използвате „update --init“?"
 
-#: builtin/submodule--helper.c:1365
+#: builtin/submodule--helper.c:1380
 #, c-format
 msgid "Skipping unmerged submodule %s"
 msgstr "Прескачане на неслетия подмодул „%s“"
 
-#: builtin/submodule--helper.c:1394
+#: builtin/submodule--helper.c:1409
 #, c-format
 msgid "Skipping submodule '%s'"
 msgstr "Прескачане на подмодула „%s“"
 
-#: builtin/submodule--helper.c:1527
+#: builtin/submodule--helper.c:1544
 #, c-format
 msgid "Failed to clone '%s'. Retry scheduled"
 msgstr "Неуспешен опит за клониране на „%s“.  Насрочен е втори опит"
 
-#: builtin/submodule--helper.c:1538
+#: builtin/submodule--helper.c:1555
 #, c-format
 msgid "Failed to clone '%s' a second time, aborting"
 msgstr ""
 "Втори неуспешен опит за клониране на „%s“.  Действието се преустановява"
 
-#: builtin/submodule--helper.c:1568 builtin/submodule--helper.c:1788
+#: builtin/submodule--helper.c:1585 builtin/submodule--helper.c:1808
 msgid "path into the working tree"
 msgstr "път към работното дърво"
 
-#: builtin/submodule--helper.c:1571
+#: builtin/submodule--helper.c:1588
 msgid "path into the working tree, across nested submodule boundaries"
 msgstr "път към работното дърво, през границите на вложените подмодули"
 
-#: builtin/submodule--helper.c:1575
+#: builtin/submodule--helper.c:1592
 msgid "rebase, merge, checkout or none"
 msgstr ""
 "„rebase“ (пребазиране), „merge“ (сливане), „checkout“ (изтегляне) или "
 "„none“ (нищо да не се прави)"
 
-#: builtin/submodule--helper.c:1579
+#: builtin/submodule--helper.c:1598
 msgid "Create a shallow clone truncated to the specified number of revisions"
 msgstr "Плитко клониране, отрязано до указания брой версии"
 
-#: builtin/submodule--helper.c:1582
+#: builtin/submodule--helper.c:1601
 msgid "parallel jobs"
 msgstr "брой паралелни процеси"
 
-#: builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1603
 msgid "whether the initial clone should follow the shallow recommendation"
 msgstr "дали първоначалното клониране да е плитко, както се препоръчва"
 
-#: builtin/submodule--helper.c:1585
+#: builtin/submodule--helper.c:1604
 msgid "don't print cloning progress"
 msgstr "без извеждане на напредъка на клонирането"
 
-#: builtin/submodule--helper.c:1592
+#: builtin/submodule--helper.c:1611
 msgid "git submodule--helper update_clone [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper update_clone [--prefix=ПЪТ] [ПЪТ…]"
 
-#: builtin/submodule--helper.c:1605
+#: builtin/submodule--helper.c:1624
 msgid "bad value for update parameter"
 msgstr "неправилен параметър към опцията „--update“"
 
-#: builtin/submodule--helper.c:1673
+#: builtin/submodule--helper.c:1692
 #, c-format
 msgid ""
 "Submodule (%s) branch configured to inherit branch from superproject, but "
@@ -14336,20 +14897,20 @@ msgstr ""
 "Клонът на подмодула „%s“ е настроен да наследява клона от обхващащия проект, "
 "но той не е на никой клон"
 
-#: builtin/submodule--helper.c:1789
+#: builtin/submodule--helper.c:1809
 msgid "recurse into submodules"
 msgstr "рекурсивно обхождане подмодулите"
 
-#: builtin/submodule--helper.c:1795
+#: builtin/submodule--helper.c:1815
 msgid "git submodule--helper embed-git-dir [<path>...]"
 msgstr "git submodule--helper name embed-git-dir [ПЪТ…]"
 
-#: builtin/submodule--helper.c:1857
+#: builtin/submodule--helper.c:1901
 #, c-format
 msgid "%s doesn't support --super-prefix"
 msgstr "„%s“ не поддържа опцията „--super-prefix“"
 
-#: builtin/submodule--helper.c:1863
+#: builtin/submodule--helper.c:1907
 #, c-format
 msgid "'%s' is not a valid submodule--helper subcommand"
 msgstr "„%s“ не е подкоманда на „submodule--helper“"
@@ -14417,7 +14978,7 @@ msgstr "етикетът „%s“ не е открит."
 msgid "Deleted tag '%s' (was %s)\n"
 msgstr "Изтрит е етикетът „%s“ (бе „%s“)\n"
 
-#: builtin/tag.c:131
+#: builtin/tag.c:132
 #, c-format
 msgid ""
 "\n"
@@ -14430,7 +14991,7 @@ msgstr ""
 "  %s\n"
 "Редовете, които започват с „%c“, ще бъдат пропуснати.\n"
 
-#: builtin/tag.c:135
+#: builtin/tag.c:136
 #, c-format
 msgid ""
 "\n"
@@ -14445,146 +15006,146 @@ msgstr ""
 "Редовете, които започват с „%c“, също ще бъдат включени — може да ги "
 "изтриете вие.\n"
 
-#: builtin/tag.c:189
+#: builtin/tag.c:190
 msgid "unable to sign the tag"
 msgstr "етикетът не може да бъде подписан"
 
-#: builtin/tag.c:191
+#: builtin/tag.c:192
 msgid "unable to write tag file"
 msgstr "файлът за етикета не може да бъде запазен"
 
-#: builtin/tag.c:216
+#: builtin/tag.c:217
 msgid "bad object type."
 msgstr "неправилен вид обект."
 
-#: builtin/tag.c:265
+#: builtin/tag.c:266
 msgid "no tag message?"
 msgstr "липсва съобщение за етикета"
 
-#: builtin/tag.c:272
+#: builtin/tag.c:273
 #, c-format
 msgid "The tag message has been left in %s\n"
 msgstr "Съобщението за етикета е запазено във файла „%s“\n"
 
-#: builtin/tag.c:381
+#: builtin/tag.c:382
 msgid "list tag names"
 msgstr "извеждане на имената на етикетите"
 
-#: builtin/tag.c:383
+#: builtin/tag.c:384
 msgid "print <n> lines of each tag message"
 msgstr "извеждане на този БРОЙ редове от всяко съобщение за етикет"
 
-#: builtin/tag.c:385
+#: builtin/tag.c:386
 msgid "delete tags"
 msgstr "изтриване на етикети"
 
-#: builtin/tag.c:386
+#: builtin/tag.c:387
 msgid "verify tags"
 msgstr "проверка на етикети"
 
-#: builtin/tag.c:388
+#: builtin/tag.c:389
 msgid "Tag creation options"
 msgstr "Опции при създаването на етикети"
 
-#: builtin/tag.c:390
+#: builtin/tag.c:391
 msgid "annotated tag, needs a message"
 msgstr "анотирането на етикети изисква съобщение"
 
-#: builtin/tag.c:392
+#: builtin/tag.c:393
 msgid "tag message"
 msgstr "СЪОБЩЕНИЕ за етикет"
 
-#: builtin/tag.c:394
+#: builtin/tag.c:395
 msgid "force edit of tag message"
 msgstr "принудително редактиране на съобщение за етикет"
 
-#: builtin/tag.c:395
+#: builtin/tag.c:396
 msgid "annotated and GPG-signed tag"
 msgstr "анотиран етикет с подпис по GPG"
 
-#: builtin/tag.c:399
+#: builtin/tag.c:400
 msgid "use another key to sign the tag"
 msgstr "използване на друг ключ за подписването на етикет"
 
-#: builtin/tag.c:400
+#: builtin/tag.c:401
 msgid "replace the tag if exists"
 msgstr "замяна на етикета, ако съществува"
 
-#: builtin/tag.c:401 builtin/update-ref.c:368
+#: builtin/tag.c:402 builtin/update-ref.c:368
 msgid "create a reflog"
 msgstr "създаване на журнал на указателите"
 
-#: builtin/tag.c:403
+#: builtin/tag.c:404
 msgid "Tag listing options"
 msgstr "Опции за извеждането на етикети"
 
-#: builtin/tag.c:404
+#: builtin/tag.c:405
 msgid "show tag list in columns"
 msgstr "извеждане на списъка на етикетите по колони"
 
-#: builtin/tag.c:405 builtin/tag.c:407
+#: builtin/tag.c:406 builtin/tag.c:408
 msgid "print only tags that contain the commit"
 msgstr "извеждане само на етикетите, които съдържат подаването"
 
-#: builtin/tag.c:406 builtin/tag.c:408
+#: builtin/tag.c:407 builtin/tag.c:409
 msgid "print only tags that don't contain the commit"
 msgstr "извеждане само на етикетите, които не съдържат подаването"
 
-#: builtin/tag.c:409
+#: builtin/tag.c:410
 msgid "print only tags that are merged"
 msgstr "извеждане само на слетите етикети"
 
-#: builtin/tag.c:410
+#: builtin/tag.c:411
 msgid "print only tags that are not merged"
 msgstr "извеждане само на неслетите етикети"
 
-#: builtin/tag.c:415
+#: builtin/tag.c:416
 msgid "print only tags of the object"
 msgstr "извеждане само на етикетите на ОБЕКТА"
 
-#: builtin/tag.c:459
+#: builtin/tag.c:460
 msgid "--column and -n are incompatible"
 msgstr "Опциите „--column“ и „-n“ са несъвместими"
 
-#: builtin/tag.c:481
+#: builtin/tag.c:482
 msgid "-n option is only allowed in list mode"
 msgstr "Опцията „-n“ изисква режим на списък."
 
-#: builtin/tag.c:483
+#: builtin/tag.c:484
 msgid "--contains option is only allowed in list mode"
 msgstr "Опцията „-contains“ изисква режим на списък."
 
-#: builtin/tag.c:485
+#: builtin/tag.c:486
 msgid "--no-contains option is only allowed in list mode"
 msgstr "Опцията „-contains“ изисква  режим на списък."
 
-#: builtin/tag.c:487
+#: builtin/tag.c:488
 msgid "--points-at option is only allowed in list mode"
 msgstr "Опцията „-points-at“ изисква режим на списък."
 
-#: builtin/tag.c:489
+#: builtin/tag.c:490
 msgid "--merged and --no-merged options are only allowed in list mode"
 msgstr "Опциите „--merged“ и „--no-merged“ изискват режим на списък."
 
-#: builtin/tag.c:500
+#: builtin/tag.c:501
 msgid "only one -F or -m option is allowed."
 msgstr "Опциите „-F“ и „-m“ са несъвместими."
 
-#: builtin/tag.c:519
+#: builtin/tag.c:520
 msgid "too many params"
 msgstr "Прекалено много аргументи"
 
-#: builtin/tag.c:525
+#: builtin/tag.c:526
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "„%s“ е неправилно име за етикет."
 
-#: builtin/tag.c:530
+#: builtin/tag.c:531
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "етикетът „%s“ вече съществува"
 
-#: builtin/tag.c:561
+#: builtin/tag.c:562
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "Обновен етикет „%s“ (бе „%s“)\n"
@@ -14663,153 +15224,153 @@ msgstr ""
 msgid " OK"
 msgstr " Добре"
 
-#: builtin/update-index.c:579
+#: builtin/update-index.c:589
 msgid "git update-index [<options>] [--] [<file>...]"
 msgstr "git update-index [ОПЦИЯ…] [--] [ФАЙЛ…]"
 
-#: builtin/update-index.c:936
+#: builtin/update-index.c:946
 msgid "continue refresh even when index needs update"
 msgstr ""
 "продължаване с обновяването, дори когато индексът трябва да бъде обновен"
 
-#: builtin/update-index.c:939
+#: builtin/update-index.c:949
 msgid "refresh: ignore submodules"
 msgstr "подмодулите да се игнорират при обновяването"
 
-#: builtin/update-index.c:942
+#: builtin/update-index.c:952
 msgid "do not ignore new files"
 msgstr "новите файлове да не се игнорират"
 
-#: builtin/update-index.c:944
+#: builtin/update-index.c:954
 msgid "let files replace directories and vice-versa"
 msgstr "файлове да могат да заменят директории и обратно"
 
-#: builtin/update-index.c:946
+#: builtin/update-index.c:956
 msgid "notice files missing from worktree"
 msgstr "предупреждаване при липсващи в работното дърво файлове"
 
-#: builtin/update-index.c:948
+#: builtin/update-index.c:958
 msgid "refresh even if index contains unmerged entries"
 msgstr "обновяване дори и индексът да съдържа неслети обекти"
 
-#: builtin/update-index.c:951
+#: builtin/update-index.c:961
 msgid "refresh stat information"
 msgstr "обновяване на информацията от функцията „stat“"
 
-#: builtin/update-index.c:955
+#: builtin/update-index.c:965
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr ""
 "като опцията „--refresh“, но да се проверят и обектите, които са били приети "
 "за непроменени"
 
-#: builtin/update-index.c:959
+#: builtin/update-index.c:969
 msgid "<mode>,<object>,<path>"
 msgstr "РЕЖИМ,ОБЕКТ,ПЪТ"
 
-#: builtin/update-index.c:960
+#: builtin/update-index.c:970
 msgid "add the specified entry to the index"
 msgstr "добавяне на изброените обекти към индекса"
 
-#: builtin/update-index.c:969
+#: builtin/update-index.c:979
 msgid "mark files as \"not changing\""
 msgstr "задаване на флаг, че файлът не се променя"
 
-#: builtin/update-index.c:972
+#: builtin/update-index.c:982
 msgid "clear assumed-unchanged bit"
 msgstr "изчистване на флага, че файлът не се променя"
 
-#: builtin/update-index.c:975
+#: builtin/update-index.c:985
 msgid "mark files as \"index-only\""
 msgstr "задаване на флаг, че файловете са само за индекса"
 
-#: builtin/update-index.c:978
+#: builtin/update-index.c:988
 msgid "clear skip-worktree bit"
 msgstr "изчистване на флага,  че файловете са само за индекса"
 
-#: builtin/update-index.c:981
+#: builtin/update-index.c:991
 msgid "add to index only; do not add content to object database"
 msgstr "добавяне само към индекса без добавяне към базата от данни за обектите"
 
-#: builtin/update-index.c:983
+#: builtin/update-index.c:993
 msgid "remove named paths even if present in worktree"
 msgstr "изтриване на указаните пътища, дори и да съществуват в работното дърво"
 
-#: builtin/update-index.c:985
+#: builtin/update-index.c:995
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr ""
 "при комбиниране с опцията „--stdin“ — входните редове са разделени с нулевия "
 "байт"
 
-#: builtin/update-index.c:987
+#: builtin/update-index.c:997
 msgid "read list of paths to be updated from standard input"
 msgstr "изчитане на списъка с пътища за обновяване от стандартния вход"
 
-#: builtin/update-index.c:991
+#: builtin/update-index.c:1001
 msgid "add entries from standard input to the index"
 msgstr "добавяне на елементите от стандартния вход към индекса"
 
-#: builtin/update-index.c:995
+#: builtin/update-index.c:1005
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr ""
 "възстановяване на състоянието преди сливане или нужда от обновяване за "
 "изброените пътища"
 
-#: builtin/update-index.c:999
+#: builtin/update-index.c:1009
 msgid "only update entries that differ from HEAD"
 msgstr "добавяне само на съдържанието, което се различава от това в „HEAD“"
 
-#: builtin/update-index.c:1003
+#: builtin/update-index.c:1013
 msgid "ignore files missing from worktree"
 msgstr "игнориране на файловете, които липсват в работното дърво"
 
-#: builtin/update-index.c:1006
+#: builtin/update-index.c:1016
 msgid "report actions to standard output"
 msgstr "извеждане на действията на стандартния изход"
 
-#: builtin/update-index.c:1008
+#: builtin/update-index.c:1018
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr ""
 "забравяне на записаната информация за неразрешени конфликти — за командите "
 "от потребителско ниво"
 
-#: builtin/update-index.c:1012
+#: builtin/update-index.c:1022
 msgid "write index in this format"
 msgstr "записване на индекса в този формат"
 
-#: builtin/update-index.c:1014
+#: builtin/update-index.c:1024
 msgid "enable or disable split index"
 msgstr "включване или изключване на разделянето на индекса"
 
-#: builtin/update-index.c:1016
+#: builtin/update-index.c:1026
 msgid "enable/disable untracked cache"
 msgstr "включване/изключване на кеша за неследените файлове"
 
-#: builtin/update-index.c:1018
+#: builtin/update-index.c:1028
 msgid "test if the filesystem supports untracked cache"
 msgstr "проверка дали файловата система поддържа кеш за неследени файлове"
 
-#: builtin/update-index.c:1020
+#: builtin/update-index.c:1030
 msgid "enable untracked cache without testing the filesystem"
 msgstr ""
 "включване на кеша за неследените файлове без проверка на файловата система"
 
-#: builtin/update-index.c:1022
+#: builtin/update-index.c:1032
 msgid "write out the index even if is not flagged as changed"
 msgstr "запис на индекса, дори да не е отбелязан като променен"
 
-#: builtin/update-index.c:1024
+#: builtin/update-index.c:1034
 msgid "enable or disable file system monitor"
 msgstr "включване или изключване на наблюдението на файловата система"
 
-#: builtin/update-index.c:1026
+#: builtin/update-index.c:1036
 msgid "mark files as fsmonitor valid"
 msgstr "отбелязване на файловете, че могат да се следят чрез файловата система"
 
-#: builtin/update-index.c:1029
+#: builtin/update-index.c:1039
 msgid "clear fsmonitor valid bit"
 msgstr "изчистване на флага за следенето чрез файловата система"
 
-#: builtin/update-index.c:1127
+#: builtin/update-index.c:1138
 msgid ""
 "core.splitIndex is set to false; remove or change it, if you really want to "
 "enable split index"
@@ -14817,7 +15378,7 @@ msgstr ""
 "Настройката „core.splitIndex“ е зададена на „false“ (лъжа).  Сменете я или я "
 "изтрийте, за да включите разделянето на индекса"
 
-#: builtin/update-index.c:1136
+#: builtin/update-index.c:1147
 msgid ""
 "core.splitIndex is set to true; remove or change it, if you really want to "
 "disable split index"
@@ -14825,7 +15386,7 @@ msgstr ""
 "Настройката „core.splitIndex“ е зададена на „true“ (истина).  Сменете я или "
 "я изтрийте, за да изключите разделянето на индекса."
 
-#: builtin/update-index.c:1147
+#: builtin/update-index.c:1158
 msgid ""
 "core.untrackedCache is set to true; remove or change it, if you really want "
 "to disable the untracked cache"
@@ -14833,11 +15394,11 @@ msgstr ""
 "Настройката „core.untrackedCache“ е зададена на „true“ (истина).  Сменете я "
 "или я изтрийте, за да изключите кеша за неследените файлове"
 
-#: builtin/update-index.c:1151
+#: builtin/update-index.c:1162
 msgid "Untracked cache disabled"
 msgstr "Кешът за неследените файлове е изключен"
 
-#: builtin/update-index.c:1159
+#: builtin/update-index.c:1170
 msgid ""
 "core.untrackedCache is set to false; remove or change it, if you really want "
 "to enable the untracked cache"
@@ -14845,29 +15406,29 @@ msgstr ""
 "Настройката „core.untrackedCache“ е зададена на „false“ (лъжа).  Сменете я "
 "или я изтрийте, за да включите кеша за неследените файлове"
 
-#: builtin/update-index.c:1163
+#: builtin/update-index.c:1174
 #, c-format
 msgid "Untracked cache enabled for '%s'"
 msgstr "Кешът за неследените файлове е включен за „%s“"
 
-#: builtin/update-index.c:1171
+#: builtin/update-index.c:1182
 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
 msgstr ""
 "Настройката „core.fsmonitor“ не е зададена.  Задайте я, за да включите "
 "следенето чрез файловата система."
 
-#: builtin/update-index.c:1175
+#: builtin/update-index.c:1186
 msgid "fsmonitor enabled"
 msgstr "следенето чрез файловата система е включено"
 
-#: builtin/update-index.c:1178
+#: builtin/update-index.c:1189
 msgid ""
 "core.fsmonitor is set; remove it if you really want to disable fsmonitor"
 msgstr ""
 "Настройката „core.fsmonitor“ е зададена.  Изтрийте я, за да изключите "
 "следенето чрез файловата система."
 
-#: builtin/update-index.c:1182
+#: builtin/update-index.c:1193
 msgid "fsmonitor disabled"
 msgstr "следенето чрез файловата система е изключено"
 
@@ -14909,9 +15470,26 @@ msgstr "git update-server-info [--force]"
 msgid "update the info files from scratch"
 msgstr "обновяване на информационните файлове от нулата"
 
-#: builtin/verify-commit.c:18
-msgid "git verify-commit [-v | --verbose] <commit>..."
-msgstr "git verify-tag [-v | --verbose] ПОДАВАНЕ…"
+#: builtin/upload-pack.c:11
+msgid "git upload-pack [<options>] <dir>"
+msgstr "git upload-repack [ОПЦИЯ…] ДИРЕКТОРИЯ"
+
+#: builtin/upload-pack.c:25
+msgid "exit immediately after initial ref advertisement"
+msgstr "изход след първоначалната обява на указатели"
+
+#: builtin/upload-pack.c:27
+msgid "do not try <directory>/.git/ if <directory> is no Git directory"
+msgstr ""
+"да не се търси „ДИРЕКТОРИЯ/.git/“, ако ДИРЕКТОРИЯта не е под контрола на Git"
+
+#: builtin/upload-pack.c:29
+msgid "interrupt transfer after <n> seconds of inactivity"
+msgstr "трансферът да се преустанови след този БРОЙ секунди"
+
+#: builtin/verify-commit.c:18
+msgid "git verify-commit [-v | --verbose] <commit>..."
+msgstr "git verify-tag [-v | --verbose] ПОДАВАНЕ…"
 
 #: builtin/verify-commit.c:73
 msgid "print commit contents"
@@ -14969,23 +15547,23 @@ msgstr "git worktree remove [ОПЦИЯ…] [ДЪРВО]"
 msgid "git worktree unlock <path>"
 msgstr "git worktree unlock [ПЪТ]"
 
-#: builtin/worktree.c:60
+#: builtin/worktree.c:58
 #, c-format
 msgid "Removing worktrees/%s: not a valid directory"
 msgstr "Изтриване на „worktrees/%s“: не е правилна поддиректория"
 
-#: builtin/worktree.c:66
+#: builtin/worktree.c:64
 #, c-format
 msgid "Removing worktrees/%s: gitdir file does not exist"
 msgstr "Изтриване на „worktrees/%s“: файлът „gitdir“ не съществува"
 
-#: builtin/worktree.c:71 builtin/worktree.c:80
+#: builtin/worktree.c:69 builtin/worktree.c:78
 #, c-format
 msgid "Removing worktrees/%s: unable to read gitdir file (%s)"
 msgstr ""
 "Изтриване на „worktrees/%s“: файлът „gitdir“ (%s) не може да бъде прочетен"
 
-#: builtin/worktree.c:90
+#: builtin/worktree.c:88
 #, c-format
 msgid ""
 "Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read "
@@ -14994,185 +15572,202 @@ msgstr ""
 "Изтриване на „worktrees/%s“: изчитането върна по-малко байтове от очакваното "
 "(очаквани: %<PRIuMAX> байта, получени: %<PRIuMAX>)"
 
-#: builtin/worktree.c:98
+#: builtin/worktree.c:96
 #, c-format
 msgid "Removing worktrees/%s: invalid gitdir file"
 msgstr "Изтриване на „worktrees/%s“: неправилен файл „gitdir“"
 
-#: builtin/worktree.c:114
+#: builtin/worktree.c:105
 #, c-format
 msgid "Removing worktrees/%s: gitdir file points to non-existent location"
 msgstr ""
 "Изтриване на „worktrees/%s“: файлът „gitdir“ сочи несъществуващо "
 "местоположение"
 
-#: builtin/worktree.c:161
+#: builtin/worktree.c:152
 msgid "report pruned working trees"
 msgstr "докладване на окастрените работни дървета"
 
-#: builtin/worktree.c:163
+#: builtin/worktree.c:154
 msgid "expire working trees older than <time>"
 msgstr "обявяване на работните копия по-стари от това ВРЕМЕ за остарели"
 
-#: builtin/worktree.c:238
+#: builtin/worktree.c:229
 #, c-format
 msgid "'%s' already exists"
 msgstr "„%s“ вече съществува"
 
-#: builtin/worktree.c:269
+#: builtin/worktree.c:260
 #, c-format
 msgid "could not create directory of '%s'"
 msgstr "директорията „%s“ не може да бъде създадена"
 
-#: builtin/worktree.c:308
+#: builtin/worktree.c:373 builtin/worktree.c:379
+#, c-format
+msgid "Preparing worktree (new branch '%s')"
+msgstr "Приготвяне на работното дърво (нов клон „%s“)"
+
+#: builtin/worktree.c:375
+#, c-format
+msgid "Preparing worktree (resetting branch '%s'; was at %s)"
+msgstr ""
+"Приготвяне на работното дърво (зануляване на клона „%s“, който сочеше към "
+"„%s“)"
+
+#: builtin/worktree.c:384
 #, c-format
-msgid "Preparing %s (identifier %s)"
-msgstr "Подготвяне на %s (идентификатор %s)"
+msgid "Preparing worktree (checking out '%s')"
+msgstr "Приготвяне на работното дърво (изтегляне на „%s“)"
 
-#: builtin/worktree.c:385
+#: builtin/worktree.c:390
+#, c-format
+msgid "Preparing worktree (detached HEAD %s)"
+msgstr "Подготвяне на работно дърво (указателят „HEAD“ не свързан: %s)"
+
+#: builtin/worktree.c:431
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr "Изтегляне КЛОНа, дори и да е изтеглен в друго работно дърво"
 
-#: builtin/worktree.c:388
+#: builtin/worktree.c:434
 msgid "create a new branch"
 msgstr "създаване на нов клон"
 
-#: builtin/worktree.c:390
+#: builtin/worktree.c:436
 msgid "create or reset a branch"
 msgstr "създаване или зануляване на клони"
 
-#: builtin/worktree.c:392
+#: builtin/worktree.c:438
 msgid "populate the new working tree"
 msgstr "подготвяне на новото работно дърво"
 
-#: builtin/worktree.c:393
+#: builtin/worktree.c:439
 msgid "keep the new working tree locked"
 msgstr "новото работно дърво да остане заключено"
 
-#: builtin/worktree.c:395
+#: builtin/worktree.c:441
 msgid "set up tracking mode (see git-branch(1))"
 msgstr "задаване на режима на следене (виж git-branch(1))"
 
-#: builtin/worktree.c:398
+#: builtin/worktree.c:444
 msgid "try to match the new branch name with a remote-tracking branch"
 msgstr "опит за напасване на името на новия клон с това на следящ клон"
 
-#: builtin/worktree.c:406
+#: builtin/worktree.c:452
 msgid "-b, -B, and --detach are mutually exclusive"
 msgstr "Опциите „-b“, „-B“ и „--detach“ са несъвместими една с друга"
 
-#: builtin/worktree.c:471
+#: builtin/worktree.c:511
 msgid "--[no-]track can only be used if a new branch is created"
 msgstr "„--[no-]track“ може да се използва само при създаването на нов клон"
 
-#: builtin/worktree.c:571
+#: builtin/worktree.c:611
 msgid "reason for locking"
 msgstr "причина за заключване"
 
-#: builtin/worktree.c:583 builtin/worktree.c:616 builtin/worktree.c:670
-#: builtin/worktree.c:809
+#: builtin/worktree.c:623 builtin/worktree.c:656 builtin/worktree.c:710
+#: builtin/worktree.c:850
 #, c-format
 msgid "'%s' is not a working tree"
 msgstr "„%s“ не е работно дърво"
 
-#: builtin/worktree.c:585 builtin/worktree.c:618
+#: builtin/worktree.c:625 builtin/worktree.c:658
 msgid "The main working tree cannot be locked or unlocked"
 msgstr "Основното дърво не може да се отключи или заключи"
 
-#: builtin/worktree.c:590
+#: builtin/worktree.c:630
 #, c-format
 msgid "'%s' is already locked, reason: %s"
 msgstr "„%s“ вече е заключено, защото „%s“"
 
-#: builtin/worktree.c:592
+#: builtin/worktree.c:632
 #, c-format
 msgid "'%s' is already locked"
 msgstr "„%s“ вече е заключено"
 
-#: builtin/worktree.c:620
+#: builtin/worktree.c:660
 #, c-format
 msgid "'%s' is not locked"
 msgstr "„%s“ не е заключено"
 
-#: builtin/worktree.c:645
+#: builtin/worktree.c:685
 msgid "working trees containing submodules cannot be moved or removed"
 msgstr ""
 "не може да местите или изтривате работни дървета, в които има подмодули"
 
-#: builtin/worktree.c:672 builtin/worktree.c:811
+#: builtin/worktree.c:712 builtin/worktree.c:852
 #, c-format
 msgid "'%s' is a main working tree"
 msgstr "„%s“ е основно работно дърво"
 
-#: builtin/worktree.c:677
+#: builtin/worktree.c:717
 #, c-format
 msgid "could not figure out destination name from '%s'"
 msgstr "името на целта не може да се определи от „%s“"
 
-#: builtin/worktree.c:683
+#: builtin/worktree.c:723
 #, c-format
 msgid "target '%s' already exists"
 msgstr "целта „%s“ вече съществува"
 
-#: builtin/worktree.c:690
+#: builtin/worktree.c:730
 #, c-format
 msgid "cannot move a locked working tree, lock reason: %s"
 msgstr ""
 "не може да преместите заключено работно дърво, причина за заключването: %s"
 
-#: builtin/worktree.c:692
+#: builtin/worktree.c:732
 msgid "cannot move a locked working tree"
 msgstr "не може да местите заключено работно дърво"
 
-#: builtin/worktree.c:695
+#: builtin/worktree.c:735
 #, c-format
 msgid "validation failed, cannot move working tree: %s"
 msgstr ""
 "проверките са неуспешни, работното дърво не може да бъде преместено: %s"
 
-#: builtin/worktree.c:700
+#: builtin/worktree.c:740
 #, c-format
 msgid "failed to move '%s' to '%s'"
 msgstr "„%s“ не може да се премести в „%s“"
 
-#: builtin/worktree.c:748
+#: builtin/worktree.c:788
 #, c-format
 msgid "failed to run 'git status' on '%s'"
 msgstr "не може да изпълни „git status“ върху „%s“"
 
-#: builtin/worktree.c:752
+#: builtin/worktree.c:792
 #, c-format
 msgid "'%s' is dirty, use --force to delete it"
 msgstr ""
 "работното дърво „%s“ не е чисто, за принудително изтриване е необходима "
 "опцията „--force“ "
 
-#: builtin/worktree.c:757
+#: builtin/worktree.c:797
 #, c-format
 msgid "failed to run 'git status' on '%s', code %d"
 msgstr ""
 "командата „git status“ не може да се изпълни за „%s“, код за грешка: %d"
 
-#: builtin/worktree.c:768 builtin/worktree.c:782
+#: builtin/worktree.c:808 builtin/worktree.c:822
 #, c-format
 msgid "failed to delete '%s'"
 msgstr "неуспешно изтриване на „%s“"
 
-#: builtin/worktree.c:794
+#: builtin/worktree.c:834
 msgid "force removing even if the worktree is dirty"
 msgstr "принудително изтриване, дори работното дърво да не е чисто"
 
-#: builtin/worktree.c:815
+#: builtin/worktree.c:856
 #, c-format
 msgid "cannot remove a locked working tree, lock reason: %s"
 msgstr ""
 "не може да изтриете заключено работно дърво, причина за заключването: %s"
 
-#: builtin/worktree.c:817
+#: builtin/worktree.c:858
 msgid "cannot remove a locked working tree"
 msgstr "не може да изтриете заключено работно дърво"
 
-#: builtin/worktree.c:820
+#: builtin/worktree.c:861
 #, c-format
 msgid "validation failed, cannot remove working tree: %s"
 msgstr "проверките са неуспешни, работното дърво не може да бъде изтрито: %s"
@@ -15193,27 +15788,6 @@ msgstr "запис на обект-дърво за поддиректорият
 msgid "only useful for debugging"
 msgstr "само за изчистване на грешки"
 
-#: upload-pack.c:27
-msgid "git upload-pack [<options>] <dir>"
-msgstr "git upload-repack [ОПЦИЯ…] ДИРЕКТОРИЯ"
-
-#: upload-pack.c:1070
-msgid "quit after a single request/response exchange"
-msgstr "изход след първоначалната размяна на заявка и отговор"
-
-#: upload-pack.c:1072
-msgid "exit immediately after initial ref advertisement"
-msgstr "изход след първоначалната обява на указатели"
-
-#: upload-pack.c:1074
-msgid "do not try <directory>/.git/ if <directory> is no Git directory"
-msgstr ""
-"да не се търси „ДИРЕКТОРИЯ/.git/“, ако ДИРЕКТОРИЯта не е под контрола на Git"
-
-#: upload-pack.c:1076
-msgid "interrupt transfer after <n> seconds of inactivity"
-msgstr "трансферът да се преустанови след този БРОЙ секунди"
-
 #: credential-cache--daemon.c:222
 #, c-format
 msgid ""
@@ -15233,11 +15807,12 @@ msgstr ""
 msgid "print debugging messages to stderr"
 msgstr "извеждане на съобщенията за трасиране на стандартната грешка"
 
-#: git.c:8
+#: git.c:27
 msgid ""
 "git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
 "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
 "           <command> [<args>]"
 msgstr ""
@@ -15247,7 +15822,7 @@ msgstr ""
 "           [--git-dir=ПЪТ] [--work-tree=ПЪТ] [--namespace=ИМЕ]\n"
 "           КОМАНДА [АРГ…]"
 
-#: git.c:15
+#: git.c:34
 msgid ""
 "'git help -a' and 'git help -g' list available subcommands and some\n"
 "concept guides. See 'git help <command>' or 'git help <concept>'\n"
@@ -15262,67 +15837,67 @@ msgstr ""
 "Български превод на книгата „Pro Git“ от Чакън и Страуб:\n"
 "http://i-can.eu/progit2-bg/progit.html"
 
-#: git.c:95
+#: git.c:173
 #, c-format
 msgid "no directory given for --git-dir\n"
 msgstr "опцията „--git-dir“ изисква директория\n"
 
-#: git.c:109
+#: git.c:187
 #, c-format
 msgid "no namespace given for --namespace\n"
 msgstr "опцията „--namespace“ изисква име\n"
 
-#: git.c:123
+#: git.c:201
 #, c-format
 msgid "no directory given for --work-tree\n"
 msgstr "опцията „--work-tree“ изисква директория\n"
 
-#: git.c:137
+#: git.c:215
 #, c-format
 msgid "no prefix given for --super-prefix\n"
 msgstr "опцията „--super-prefix“ изисква префикс\n"
 
-#: git.c:159
+#: git.c:237
 #, c-format
 msgid "-c expects a configuration string\n"
 msgstr "опцията „-c“ изисква низ за настройка\n"
 
-#: git.c:197
+#: git.c:275
 #, c-format
 msgid "no directory given for -C\n"
 msgstr "опцията „-C“ изисква директория\n"
 
-#: git.c:212
+#: git.c:300
 #, c-format
 msgid "unknown option: %s\n"
 msgstr "непозната опция: „%s“\n"
 
-#: git.c:687
+#: git.c:765
 #, c-format
 msgid "expansion of alias '%s' failed; '%s' is not a git command\n"
 msgstr ""
 "неуспешно заместване на синонима „%s“ — резултатът „%s“ не е команда на git\n"
 
-#: git.c:699
+#: git.c:777
 #, c-format
 msgid "failed to run command '%s': %s\n"
 msgstr "командата „%s“ не може да се изпълни: %s\n"
 
-#: http.c:342
+#: http.c:348
 #, c-format
 msgid "negative value for http.postbuffer; defaulting to %d"
 msgstr ""
 "отрицателна стойност за „http.postbuffer“.  Ще се ползва стандартната: %d"
 
-#: http.c:363
+#: http.c:369
 msgid "Delegation control is not supported with cURL < 7.22.0"
 msgstr "Управлението на делегирането не се поддържа от cURL < 7.22.0"
 
-#: http.c:372
+#: http.c:378
 msgid "Public key pinning not supported with cURL < 7.44.0"
 msgstr "Задаването на постоянен публичен ключ не се поддържа от cURL < 7.44.0"
 
-#: http.c:1857
+#: http.c:1854
 #, c-format
 msgid ""
 "unable to update url base from redirection:\n"
@@ -15333,7 +15908,7 @@ msgstr ""
 "    ● заявен адрес: %s\n"
 "    ● пренасочване: %s"
 
-#: remote-curl.c:345
+#: remote-curl.c:401
 #, c-format
 msgid "redirecting to %s"
 msgstr "пренасочване към „%s“"
@@ -15346,130 +15921,671 @@ msgstr "АРГУМЕНТИ"
 msgid "object filtering"
 msgstr "филтриране по вид на обекта"
 
-#: common-cmds.h:9
-msgid "start a working area (see also: git help tutorial)"
-msgstr "създаване на работно дърво (погледнете: „git help tutorial“)"
+#: parse-options.h:157
+msgid "expiry-date"
+msgstr "период на валидност/запазване"
 
-#: common-cmds.h:10
-msgid "work on the current change (see also: git help everyday)"
-msgstr "работа по текущата промяна (погледнете: „git help everyday“)"
+#: parse-options.h:172
+msgid "no-op (backward compatibility)"
+msgstr "нулева операция (за съвместимост с предишни версии)"
 
-#: common-cmds.h:11
-msgid "examine the history and state (see also: git help revisions)"
-msgstr "преглед на историята и състоянието (погледнете: „git help revisions“)"
+#: parse-options.h:251
+msgid "be more verbose"
+msgstr "повече подробности"
 
-#: common-cmds.h:12
-msgid "grow, mark and tweak your common history"
-msgstr "увеличаване, отбелязване и промяна на общата история"
+#: parse-options.h:253
+msgid "be more quiet"
+msgstr "по-малко подробности"
 
-#: common-cmds.h:13
-msgid "collaborate (see also: git help workflows)"
-msgstr "съвместна работа (погледнете: „git help workflows“)"
+#: parse-options.h:259
+msgid "use <n> digits to display SHA-1s"
+msgstr "да се показват такъв БРОЙ цифри от сумите по SHA1"
 
-#: common-cmds.h:17
+#: command-list.h:50
 msgid "Add file contents to the index"
 msgstr "Добавяне на съдържанието на файла към индекса"
 
-#: common-cmds.h:18
+#: command-list.h:51
+msgid "Apply a series of patches from a mailbox"
+msgstr "Прилагане на поредица от кръпки от пощенска кутия"
+
+#: command-list.h:52
+msgid "Annotate file lines with commit information"
+msgstr "Анотиране на редовете на файловете с информация за подаванията"
+
+#: command-list.h:53
+msgid "Apply a patch to files and/or to the index"
+msgstr "Прилагане на кръпка към файловете и/или индекса"
+
+#: command-list.h:54
+msgid "Import an Arch repository into Git"
+msgstr "Внасяне на хранилище на Arch в Git"
+
+#: command-list.h:55
+msgid "Create an archive of files from a named tree"
+msgstr "Създаване на архив с файловете от именовано дърво"
+
+#: command-list.h:56
 msgid "Use binary search to find the commit that introduced a bug"
 msgstr "Двоично търсене на промяната, която е причинила грешка"
 
-#: common-cmds.h:19
+#: command-list.h:57
+msgid "Show what revision and author last modified each line of a file"
+msgstr ""
+"Извеждане на версията и автора на последната промяна на всеки от редовете на "
+"файл"
+
+#: command-list.h:58
 msgid "List, create, or delete branches"
 msgstr "Извеждане, създаване, изтриване на клони"
 
-#: common-cmds.h:20
+#: command-list.h:59
+msgid "Move objects and refs by archive"
+msgstr "Местене на обекти и указатели по архиви"
+
+#: command-list.h:60
+msgid "Provide content or type and size information for repository objects"
+msgstr ""
+"Предоставяне на съдържанието или вида и размерите на обекти от хранилище"
+
+#: command-list.h:61
+msgid "Display gitattributes information"
+msgstr "Извеждане на информацията за атрибутите на git (gitattributes)"
+
+#: command-list.h:62
+msgid "Debug gitignore / exclude files"
+msgstr "Изчистване на грешки в игнорираните файлове (gitignore)"
+
+#: command-list.h:63
+msgid "Show canonical names and email addresses of contacts"
+msgstr "Извеждане на каноничните име и адрес на е-поща на контактите"
+
+#: command-list.h:64
 msgid "Switch branches or restore working tree files"
 msgstr ""
 "Преминаване към друг клон или възстановяване на файловете в работното дърво"
 
-#: common-cmds.h:21
+#: command-list.h:65
+msgid "Copy files from the index to the working tree"
+msgstr "Копиране на файлове от индекса към работното дърво"
+
+#: command-list.h:66
+msgid "Ensures that a reference name is well formed"
+msgstr "Проверка дали името на указателя е по правилата"
+
+#: command-list.h:67
+msgid "Find commits yet to be applied to upstream"
+msgstr ""
+"Откриване на подавания, които още не са подадени към отдалеченото хранилище"
+
+#: command-list.h:68
+msgid "Apply the changes introduced by some existing commits"
+msgstr "Прилагане на промените от съществуващи подавания"
+
+#: command-list.h:69
+msgid "Graphical alternative to git-commit"
+msgstr "Графична алтернатива на „git-commit“"
+
+#: command-list.h:70
+msgid "Remove untracked files from the working tree"
+msgstr "Изтриване на неследените файлове от работното дърво"
+
+#: command-list.h:71
 msgid "Clone a repository into a new directory"
 msgstr "Клониране на хранилище в нова директория"
 
-#: common-cmds.h:22
+#: command-list.h:72
+msgid "Display data in columns"
+msgstr "Извеждане по колони"
+
+#: command-list.h:73
 msgid "Record changes to the repository"
 msgstr "Подаване на промени в хранилището"
 
-#: common-cmds.h:23
+#: command-list.h:74
+msgid "Write and verify Git commit graph files"
+msgstr "Запис и проверка на файловете с гра̀фа на подаванията на Git"
+
+#: command-list.h:75
+msgid "Create a new commit object"
+msgstr "Създаване на нов обект-подаване"
+
+#: command-list.h:76
+msgid "Get and set repository or global options"
+msgstr ""
+"Извеждане и задаване на глобални настройки или настройки на определено "
+"хранилище"
+
+#: command-list.h:77
+msgid "Count unpacked number of objects and their disk consumption"
+msgstr ""
+"Преброяване на непакетираните обекти и колко дисково пространство заемат"
+
+#: command-list.h:78
+msgid "Retrieve and store user credentials"
+msgstr "Получаване и запазване на идентификацията на потребител"
+
+#: command-list.h:79
+msgid "Helper to temporarily store passwords in memory"
+msgstr "Помощна програма за временно запазване на пароли в паметта"
+
+#: command-list.h:80
+msgid "Helper to store credentials on disk"
+msgstr ""
+"Помощна програма за запазване на идентификацията на потребител на диска"
+
+#: command-list.h:81
+msgid "Export a single commit to a CVS checkout"
+msgstr "Изнасяне на едно подаване като изтегляне в CVS"
+
+#: command-list.h:82
+msgid "Salvage your data out of another SCM people love to hate"
+msgstr "Изнасяне на данните ви от друга система за контрол на версиите"
+
+#: command-list.h:83
+msgid "A CVS server emulator for Git"
+msgstr "Емулация на сървър за CVS за Git"
+
+#: command-list.h:84
+msgid "A really simple server for Git repositories"
+msgstr "Силно опростен сървър за хранилища на Git"
+
+#: command-list.h:85
+msgid "Give an object a human readable name based on an available ref"
+msgstr ""
+"Задаване на име удобно за потребителите на обект въз основа на наличен "
+"указател"
+
+#: command-list.h:86
 msgid "Show changes between commits, commit and working tree, etc"
 msgstr "Извеждане на разликите между подаванията, версиите, работното дърво"
 
-#: common-cmds.h:24
+#: command-list.h:87
+msgid "Compares files in the working tree and the index"
+msgstr "Сравняване на файлове от работното дърво и индекса"
+
+#: command-list.h:88
+msgid "Compare a tree to the working tree or index"
+msgstr "Сравняване на обекти-дърво с работното дърво и индекса"
+
+#: command-list.h:89
+msgid "Compares the content and mode of blobs found via two tree objects"
+msgstr ""
+"Сравняване на съдържанието и правата за достъп на обектите-BLOB чрез два "
+"обекта-дърво"
+
+#: command-list.h:90
+msgid "Show changes using common diff tools"
+msgstr "Извеждане на промените чрез стандартните инструменти за това"
+
+#: command-list.h:91
+msgid "Git data exporter"
+msgstr "Разглеждане на данните от Git"
+
+#: command-list.h:92
+msgid "Backend for fast Git data importers"
+msgstr "Ядро за бързо внасяне на данни в Git"
+
+#: command-list.h:93
 msgid "Download objects and refs from another repository"
 msgstr "Изтегляне на обекти и указатели от друго хранилище"
 
-#: common-cmds.h:25
+#: command-list.h:94
+msgid "Receive missing objects from another repository"
+msgstr "Получаване на липсващи обекти от друго хранилище"
+
+#: command-list.h:95
+msgid "Rewrite branches"
+msgstr "Презаписване на клони"
+
+#: command-list.h:96
+msgid "Produce a merge commit message"
+msgstr "Създаване на съобщение при подаване със сливане"
+
+#: command-list.h:97
+msgid "Output information on each ref"
+msgstr "Извеждане на информацията за всеки указател"
+
+#: command-list.h:98
+msgid "Prepare patches for e-mail submission"
+msgstr "Подготвяне на кръпки за изпращане по е-поща"
+
+#: command-list.h:99
+msgid "Verifies the connectivity and validity of the objects in the database"
+msgstr "Проверка на обектите и връзките тях в базата от данни за обектите"
+
+#: command-list.h:100
+msgid "Cleanup unnecessary files and optimize the local repository"
+msgstr "Изчистване на ненужните файлове и оптимизиране на локалното хранилище"
+
+#: command-list.h:101
+msgid "Extract commit ID from an archive created using git-archive"
+msgstr "Извеждане на идентификатора на подаване от архив на „git-archive“"
+
+#: command-list.h:102
 msgid "Print lines matching a pattern"
 msgstr "Извеждане на редовете напасващи на шаблон"
 
-#: common-cmds.h:26
+#: command-list.h:103
+msgid "A portable graphical interface to Git"
+msgstr "Графичен интерфейс към Git"
+
+#: command-list.h:104
+msgid "Compute object ID and optionally creates a blob from a file"
+msgstr ""
+"Изчисляване на идентификатор на обект и евентуално създаване на обект-BLOB "
+"от файл"
+
+#: command-list.h:105
+msgid "Display help information about Git"
+msgstr "Извеждане на помощта за Git"
+
+#: command-list.h:106
+msgid "Server side implementation of Git over HTTP"
+msgstr "Сървърна реализация на Git по HTTP"
+
+#: command-list.h:107
+msgid "Download from a remote Git repository via HTTP"
+msgstr "Изтегляне на отдалечено хранилище по HTTP"
+
+#: command-list.h:108
+msgid "Push objects over HTTP/DAV to another repository"
+msgstr "Изтласкване на обекти по HTTP/DAV към друго хранилище"
+
+#: command-list.h:109
+msgid "Send a collection of patches from stdin to an IMAP folder"
+msgstr "Изпращане на поредица от кръпки на стандартния вход към папка по IMAP"
+
+#: command-list.h:110
+msgid "Build pack index file for an existing packed archive"
+msgstr "Създаване на пакетен индекс за съществуващ пакетиран архив"
+
+#: command-list.h:111
 msgid "Create an empty Git repository or reinitialize an existing one"
 msgstr "Създаване на празно хранилище на Git или зануляване на съществуващо"
 
-#: common-cmds.h:27
+#: command-list.h:112
+msgid "Instantly browse your working repository in gitweb"
+msgstr "Незабавно разглеждане на работното ви хранилище чрез „gitweb“"
+
+#: command-list.h:113
+msgid "add or parse structured information in commit messages"
+msgstr ""
+"добавяне или обработка на структурирана информация в съобщенията при подаване"
+
+#: command-list.h:114
+msgid "The Git repository browser"
+msgstr "Разглеждане на хранилище на Git"
+
+#: command-list.h:115
 msgid "Show commit logs"
 msgstr "Извеждане на журнала с подаванията"
 
-#: common-cmds.h:28
+#: command-list.h:116
+msgid "Show information about files in the index and the working tree"
+msgstr "Извеждане на информация за файловете в индекса и работното дърво"
+
+#: command-list.h:117
+msgid "List references in a remote repository"
+msgstr "Извеждане на указателите в отдалечено хранилище"
+
+#: command-list.h:118
+msgid "List the contents of a tree object"
+msgstr "Извеждане на съдържанието на обект-дърво"
+
+#: command-list.h:119
+msgid "Extracts patch and authorship from a single e-mail message"
+msgstr "Изваждане на кръпка и авторството от е-писмо"
+
+#: command-list.h:120
+msgid "Simple UNIX mbox splitter program"
+msgstr "Проста програма за разделяне на файлове във формат UNIX mbox"
+
+#: command-list.h:121
 msgid "Join two or more development histories together"
 msgstr "Сливане на две или повече поредици/истории от промени"
 
-#: common-cmds.h:29
+#: command-list.h:122
+msgid "Find as good common ancestors as possible for a merge"
+msgstr "Откриване на най-подходящите общи предшественици за сливане"
+
+#: command-list.h:123
+msgid "Run a three-way file merge"
+msgstr "Изпълнение на тройно сливане"
+
+#: command-list.h:124
+msgid "Run a merge for files needing merging"
+msgstr "Сливане на файловете, които се нуждаят от това"
+
+#: command-list.h:125
+msgid "The standard helper program to use with git-merge-index"
+msgstr "Стандартната помощна програма за „git-merge-index“"
+
+#: command-list.h:126
+msgid "Run merge conflict resolution tools to resolve merge conflicts"
+msgstr "Изпълнение на програмите за коригиране на конфликтите при сливане"
+
+#: command-list.h:127
+msgid "Show three-way merge without touching index"
+msgstr "Извеждане на тройно сливане без промяна на индекса"
+
+#: command-list.h:128
+msgid "Creates a tag object"
+msgstr "Създаване на обект-етикет"
+
+#: command-list.h:129
+msgid "Build a tree-object from ls-tree formatted text"
+msgstr "Създаване на обект-дърво от текст във формат „ls-tree“"
+
+#: command-list.h:130
 msgid "Move or rename a file, a directory, or a symlink"
 msgstr "Преместване или преименуване на файл, директория или символна връзка"
 
-#: common-cmds.h:30
+#: command-list.h:131
+msgid "Find symbolic names for given revs"
+msgstr "Откриване на имената дадени на версия"
+
+#: command-list.h:132
+msgid "Add or inspect object notes"
+msgstr "Добавяне или преглед на бележки към обект"
+
+#: command-list.h:133
+msgid "Import from and submit to Perforce repositories"
+msgstr "Внасяне и подаване към хранилища на Perforce"
+
+#: command-list.h:134
+msgid "Create a packed archive of objects"
+msgstr "Създаване на пакетиран архив от обекти"
+
+#: command-list.h:135
+msgid "Find redundant pack files"
+msgstr "Намиране на повтарящи се пакетни файлове"
+
+#: command-list.h:136
+msgid "Pack heads and tags for efficient repository access"
+msgstr "Пакетиране на върховете и етикетите за бърз достъп до хранилище"
+
+#: command-list.h:137
+msgid "Routines to help parsing remote repository access parameters"
+msgstr ""
+"Помощни програми за анализа на параметрите за достъп до отдалечено хранилище"
+
+#: command-list.h:138
+msgid "Compute unique ID for a patch"
+msgstr "Генериране на уникален идентификатор на кръпка"
+
+#: command-list.h:139
+msgid "Prune all unreachable objects from the object database"
+msgstr "Окастряне на всички недостижими обекти в базата от данни за обектите"
+
+#: command-list.h:140
+msgid "Remove extra objects that are already in pack files"
+msgstr "Изтриване на допълнителните обекти, които вече са в пакетни файлове"
+
+#: command-list.h:141
 msgid "Fetch from and integrate with another repository or a local branch"
 msgstr "Доставяне и внасяне на промените от друго хранилище или клон"
 
-#: common-cmds.h:31
+#: command-list.h:142
 msgid "Update remote refs along with associated objects"
 msgstr "Обновяване на отдалечените указатели и свързаните с тях обекти"
 
-#: common-cmds.h:32
+#: command-list.h:143
+msgid "Applies a quilt patchset onto the current branch"
+msgstr "Прилагане на поредица от кръпки от quilt към текущия клон"
+
+#: command-list.h:144
+msgid "Reads tree information into the index"
+msgstr "Изчитане на информация за обект-дърво в индекса"
+
+#: command-list.h:145
 msgid "Reapply commits on top of another base tip"
 msgstr "Прилагане на подаванията върху друг връх"
 
-#: common-cmds.h:33
+#: command-list.h:146
+msgid "Receive what is pushed into the repository"
+msgstr "Получаване на изтласканото в хранилището"
+
+#: command-list.h:147
+msgid "Manage reflog information"
+msgstr "Управление на информацията в журнала на указателите"
+
+#: command-list.h:148
+msgid "Manage set of tracked repositories"
+msgstr "Управление на набор от следени хранилища"
+
+#: command-list.h:149
+msgid "Pack unpacked objects in a repository"
+msgstr "Пакетиране на непакетираните обекти в хранилище"
+
+#: command-list.h:150
+msgid "Create, list, delete refs to replace objects"
+msgstr "Създаване, извеждане, изтриване на указатели за замяна на обекти"
+
+#: command-list.h:151
+msgid "Generates a summary of pending changes"
+msgstr "Обобщение на предстоящите промени"
+
+#: command-list.h:152
+msgid "Reuse recorded resolution of conflicted merges"
+msgstr "Преизползване на вече запазено коригиране на конфликт при сливане"
+
+#: command-list.h:153
 msgid "Reset current HEAD to the specified state"
 msgstr "Привеждане на указателя „HEAD“ към зададеното състояние"
 
-#: common-cmds.h:34
+#: command-list.h:154
+msgid "Revert some existing commits"
+msgstr "Отменяне на съществуващи подавания"
+
+#: command-list.h:155
+msgid "Lists commit objects in reverse chronological order"
+msgstr "Извеждане на подаванията в обратна хронологическа подредба"
+
+#: command-list.h:156
+msgid "Pick out and massage parameters"
+msgstr "Избор и промяна на параметри"
+
+#: command-list.h:157
 msgid "Remove files from the working tree and from the index"
 msgstr "Изтриване на файлове от работното дърво и индекса"
 
-#: common-cmds.h:35
+#: command-list.h:158
+msgid "Send a collection of patches as emails"
+msgstr "Изпращане на поредица от кръпки по е-поща"
+
+#: command-list.h:159
+msgid "Push objects over Git protocol to another repository"
+msgstr "Изтласкване на обекти по протокола на Git към друго хранилище"
+
+#: command-list.h:160
+msgid "Restricted login shell for Git-only SSH access"
+msgstr "Ограничена входна обвивка за достъп през SSH само до Git"
+
+#: command-list.h:161
+msgid "Summarize 'git log' output"
+msgstr "Обобщен изход от „git log“"
+
+#: command-list.h:162
 msgid "Show various types of objects"
 msgstr "Извеждане на различните видове обекти в Git"
 
-#: common-cmds.h:36
+#: command-list.h:163
+msgid "Show branches and their commits"
+msgstr "Извеждане на клоните и подаванията в тях"
+
+#: command-list.h:164
+msgid "Show packed archive index"
+msgstr "Извеждане на индекса на пакетирания архив"
+
+#: command-list.h:165
+msgid "List references in a local repository"
+msgstr "Извеждане на указателите в локално хранилище"
+
+#: command-list.h:166
+msgid "Git's i18n setup code for shell scripts"
+msgstr "Настройки на Git за интернационализация на скриптовете на обвивката"
+
+#: command-list.h:167
+msgid "Common Git shell script setup code"
+msgstr "Настройки на Git за скриптовете на обвивката"
+
+#: command-list.h:168
+msgid "Stash the changes in a dirty working directory away"
+msgstr "Скатаване на неподадените промени в работното дърво"
+
+#: command-list.h:169
+msgid "Add file contents to the staging area"
+msgstr "Добавяне на съдържанието на файла към индекса"
+
+#: command-list.h:170
 msgid "Show the working tree status"
 msgstr "Извеждане на състоянието на работното дърво"
 
-#: common-cmds.h:37
+#: command-list.h:171
+msgid "Remove unnecessary whitespace"
+msgstr "Премахване на излишните знаци за интервали"
+
+#: command-list.h:172
+msgid "Initialize, update or inspect submodules"
+msgstr "Инициализиране, обновяване или разглеждане на подмодули"
+
+#: command-list.h:173
+msgid "Bidirectional operation between a Subversion repository and Git"
+msgstr "Двупосочна работа между хранилища под Subversion и Git"
+
+#: command-list.h:174
+msgid "Read, modify and delete symbolic refs"
+msgstr "Извеждане, промяна и изтриване на символни указатели"
+
+#: command-list.h:175
 msgid "Create, list, delete or verify a tag object signed with GPG"
 msgstr "Извеждане, създаване, изтриване, проверка на етикети подписани с GPG"
 
-#: parse-options.h:157
-msgid "expiry-date"
-msgstr "пеÑ\80иод Ð½Ð° Ð²Ð°Ð»Ð¸Ð´Ð½Ð¾Ñ\81Ñ\82/запазване"
+#: command-list.h:176
+msgid "Creates a temporary file with a blob's contents"
+msgstr "СÑ\8aздаване Ð½Ð° Ð²Ñ\80еменен Ñ\84айл Ñ\81Ñ\8aÑ\81 Ñ\81Ñ\8aÑ\89оÑ\82о Ñ\81Ñ\8aдÑ\8aÑ\80жание ÐºÐ°Ñ\82о Ð¾Ð±ÐµÐºÑ\82Ñ\8aÑ\82-BLOB"
 
-#: parse-options.h:172
-msgid "no-op (backward compatibility)"
-msgstr "нÑ\83лева Ð¾Ð¿ÐµÑ\80аÑ\86иÑ\8f (за Ñ\81Ñ\8aвмеÑ\81Ñ\82имоÑ\81Ñ\82 Ñ\81 Ð¿Ñ\80едиÑ\88ни Ð²ÐµÑ\80Ñ\81ии)"
+#: command-list.h:177
+msgid "Unpack objects from a packed archive"
+msgstr "РазпакеÑ\82иÑ\80ане Ð½Ð° Ð¾Ð±ÐµÐºÑ\82и Ð¾Ñ\82 Ð¿Ð°ÐºÐµÑ\82иÑ\80ан Ð°Ñ\80Ñ\85ив"
 
-#: parse-options.h:250
-msgid "be more verbose"
-msgstr "повеÑ\87е Ð¿Ð¾Ð´Ñ\80обноÑ\81Ñ\82и"
+#: command-list.h:178
+msgid "Register file contents in the working tree to the index"
+msgstr "РегиÑ\81Ñ\82Ñ\80иÑ\80ане Ð½Ð° Ñ\81Ñ\8aдÑ\8aÑ\80жаниеÑ\82о Ð½Ð° Ñ\84айловеÑ\82е Ð¾Ñ\82 Ñ\80абоÑ\82ноÑ\82о Ð´Ñ\8aÑ\80во Ð² Ð¸Ð½Ð´ÐµÐºÑ\81а"
 
-#: parse-options.h:252
-msgid "be more quiet"
-msgstr "по-малко Ð¿Ð¾Ð´Ñ\80обноÑ\81Ñ\82и"
+#: command-list.h:179
+msgid "Update the object name stored in a ref safely"
+msgstr "Ð\91езопаÑ\81но Ð¾Ð±Ð½Ð¾Ð²Ñ\8fване Ð½Ð° Ð¸Ð¼ÐµÑ\82о Ð½Ð° Ð¾Ð±ÐµÐºÑ\82 Ð² Ñ\83казаÑ\82ел"
 
-#: parse-options.h:258
-msgid "use <n> digits to display SHA-1s"
-msgstr "да се показват такъв БРОЙ цифри от сумите по SHA1"
+#: command-list.h:180
+msgid "Update auxiliary info file to help dumb servers"
+msgstr ""
+"Обновяване на файла с допълнителна информация в помощ на опростените сървъри"
+
+#: command-list.h:181
+msgid "Send archive back to git-archive"
+msgstr "Изпращане на архива обратно към „git-archive“"
+
+#: command-list.h:182
+msgid "Send objects packed back to git-fetch-pack"
+msgstr "Изпращане на пакетираните обекти обратно към „git-fetch-pack“"
+
+#: command-list.h:183
+msgid "Show a Git logical variable"
+msgstr "Извеждане на логическа променлива на Git"
+
+#: command-list.h:184
+msgid "Check the GPG signature of commits"
+msgstr "Проверка на подписите GPG върху подаванията"
+
+#: command-list.h:185
+msgid "Validate packed Git archive files"
+msgstr "Проверка на пакетираните архивни файлове на Git"
+
+#: command-list.h:186
+msgid "Check the GPG signature of tags"
+msgstr "Проверка на подписите GPG върху етикетите"
+
+#: command-list.h:187
+msgid "Git web interface (web frontend to Git repositories)"
+msgstr "Уеб интерфейс на Git"
+
+#: command-list.h:188
+msgid "Show logs with difference each commit introduces"
+msgstr "Извеждане на журнал с разликите, въведени с всяко подаване"
+
+#: command-list.h:189
+msgid "Manage multiple working trees"
+msgstr "Управление на множество работни дървета"
+
+#: command-list.h:190
+msgid "Create a tree object from the current index"
+msgstr "Създаване на обект-дърво от текущия индекс"
+
+#: command-list.h:191
+msgid "Defining attributes per path"
+msgstr "Указване на атрибути към път"
+
+#: command-list.h:192
+msgid "Git command-line interface and conventions"
+msgstr "Команден ред и конвенции на Git"
+
+#: command-list.h:193
+msgid "A Git core tutorial for developers"
+msgstr "Въвеждащ урок в Git за разработчици"
+
+#: command-list.h:194
+msgid "Git for CVS users"
+msgstr "Git за потребители на CVS"
+
+#: command-list.h:195
+msgid "Tweaking diff output"
+msgstr "Настройване на изгледа на разликите"
+
+#: command-list.h:196
+msgid "A useful minimum set of commands for Everyday Git"
+msgstr "Полезен минимален набор от команди за ежедневната работа с Git"
+
+#: command-list.h:197
+msgid "A Git Glossary"
+msgstr "Речник с термините на Git"
+
+#: command-list.h:198
+msgid "Hooks used by Git"
+msgstr "Куки на Git"
+
+#: command-list.h:199
+msgid "Specifies intentionally untracked files to ignore"
+msgstr "Указване на неследени файлове, които да бъдат нарочно пренебрегвани"
+
+#: command-list.h:200
+msgid "Defining submodule properties"
+msgstr "Дефиниране на свойствата на подмодулите"
+
+#: command-list.h:201
+msgid "Git namespaces"
+msgstr "Пространства от имена на Git"
+
+#: command-list.h:202
+msgid "Git Repository Layout"
+msgstr "Устройство на хранилището на Git"
+
+#: command-list.h:203
+msgid "Specifying revisions and ranges for Git"
+msgstr "Указване на версии и диапазони в Git"
+
+#: command-list.h:204
+msgid "A tutorial introduction to Git: part two"
+msgstr "Въвеждащ урок за Git: втора част"
+
+#: command-list.h:205
+msgid "A tutorial introduction to Git"
+msgstr "Въвеждащ урок за Git"
+
+#: command-list.h:206
+msgid "An overview of recommended workflows with Git"
+msgstr "Общ преглед на препоръчваните начини за работа с Git"
 
 #: rerere.h:40
 msgid "update the index with reused conflict resolution if possible"
@@ -15708,7 +16824,7 @@ msgstr "Опит за просто сливане с „$pretty_name“"
 msgid "Simple merge did not work, trying automatic merge."
 msgstr "Простото сливане не сработи, пробва се автоматично сливане."
 
-#: git-rebase.sh:60
+#: git-rebase.sh:61
 msgid ""
 "Resolve all conflicts manually, mark them as resolved with\n"
 "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
@@ -15722,44 +16838,44 @@ msgstr ""
 "За да откажете пребазирането и да се върнете към първоначалното състояние,\n"
 "изпълнете „git rebase --abort“."
 
-#: git-rebase.sh:163 git-rebase.sh:409
+#: git-rebase.sh:173 git-rebase.sh:442
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "Връщането към „${head_name}“ е невъзможно"
 
-#: git-rebase.sh:174
+#: git-rebase.sh:184
 msgid "Applied autostash."
 msgstr "Автоматично скатаното е приложено."
 
-#: git-rebase.sh:177
+#: git-rebase.sh:187
 #, sh-format
 msgid "Cannot store $stash_sha1"
 msgstr "„${stash_sha1}“ не може да бъде запазен"
 
-#: git-rebase.sh:218
+#: git-rebase.sh:229
 msgid "The pre-rebase hook refused to rebase."
 msgstr "Куката за изпълнение преди пребазиране отхвърли пребазирането."
 
-#: git-rebase.sh:223
+#: git-rebase.sh:234
 msgid "It looks like 'git am' is in progress. Cannot rebase."
 msgstr ""
 "Изглежда, че сега се прилагат кръпки чрез командата „git-am“.  Не може да "
 "пребазирате в момента."
 
-#: git-rebase.sh:370
+#: git-rebase.sh:403
 msgid "No rebase in progress?"
 msgstr "Изглежда в момента не тече пребазиране"
 
-#: git-rebase.sh:381
+#: git-rebase.sh:414
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
 "Опцията „--edit-todo“ е достъпна само по време на интерактивно пребазиране."
 
-#: git-rebase.sh:388
+#: git-rebase.sh:421
 msgid "Cannot read HEAD"
 msgstr "Указателят „HEAD“ не може да бъде прочетен"
 
-#: git-rebase.sh:391
+#: git-rebase.sh:424
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -15767,7 +16883,7 @@ msgstr ""
 "Трябва да редактирате всички конфликти при сливането.  След това\n"
 "отбележете коригирането им чрез командата „git add“"
 
-#: git-rebase.sh:435
+#: git-rebase.sh:468
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -15788,79 +16904,83 @@ msgstr ""
 "за\n"
 "да не загубите случайно промени."
 
-#: git-rebase.sh:491
+#: git-rebase.sh:509
+msgid "error: cannot combine '--signoff' with '--preserve-merges'"
+msgstr "грешка: опциите „--signoff“ и „--preserve-merges“ са несъвместими"
+
+#: git-rebase.sh:537
 #, sh-format
 msgid "invalid upstream '$upstream_name'"
 msgstr "неправилна основа за сравнение „${upstream_name}“"
 
-#: git-rebase.sh:515
+#: git-rebase.sh:561
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr ""
 "указателят „${onto_name}“ може да сочи към повече от една основа за "
 "пребазирането"
 
-#: git-rebase.sh:518 git-rebase.sh:522
+#: git-rebase.sh:564 git-rebase.sh:568
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "указателят „${onto_name}“ не сочи към никаква основа за пребазирането"
 
-#: git-rebase.sh:527
+#: git-rebase.sh:573
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "Указателят „${onto_name}“ не сочи към подаване"
 
-#: git-rebase.sh:553
+#: git-rebase.sh:599
 #, sh-format
 msgid "fatal: no such branch/commit '$branch_name'"
 msgstr "ФАТАЛНА ГРЕШКА: не съществува клон „${branch_name}“"
 
-#: git-rebase.sh:586
+#: git-rebase.sh:632
 msgid "Cannot autostash"
 msgstr "Не може да се скатае автоматично"
 
-#: git-rebase.sh:591
+#: git-rebase.sh:637
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "Автоматично скатано: „${stash_abbrev}“"
 
-#: git-rebase.sh:595
+#: git-rebase.sh:641
 msgid "Please commit or stash them."
 msgstr "Промените трябва или да се подадат, или да се скатаят."
 
-#: git-rebase.sh:618
+#: git-rebase.sh:664
 #, sh-format
 msgid "HEAD is up to date."
 msgstr "Указателят „HEAD“ е напълно актуален"
 
-#: git-rebase.sh:620
+#: git-rebase.sh:666
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "Текущият клон „${branch_name}“ е напълно актуален."
 
-#: git-rebase.sh:628
+#: git-rebase.sh:674
 #, sh-format
 msgid "HEAD is up to date, rebase forced."
 msgstr "Указателят „HEAD“ е напълно актуален.  Пребазирането е принудително."
 
-#: git-rebase.sh:630
+#: git-rebase.sh:676
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr ""
 "Текущият клон „${branch_name}“ е напълно актуален.  Пребазирането е "
 "принудително."
 
-#: git-rebase.sh:642
+#: git-rebase.sh:688
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "Промените от „${mb}“ към „${onto}“:"
 
-#: git-rebase.sh:651
+#: git-rebase.sh:697
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr ""
 "Първо, указателят „HEAD“ започва да сочи към базата, върху която пребазирате…"
 
-#: git-rebase.sh:661
+#: git-rebase.sh:707
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "Превъртане на „${branch_name}“ върху „${onto_name}“."
@@ -15930,115 +17050,115 @@ msgid "Saved working directory and index state $stash_msg"
 msgstr ""
 "Състоянието на работната директория и индекса са запазени: „$stash_msg“"
 
-#: git-stash.sh:340
+#: git-stash.sh:342
 msgid "Cannot remove worktree changes"
 msgstr "Промените в работното дърво не могат да бъдат занулени"
 
-#: git-stash.sh:488
+#: git-stash.sh:490
 #, sh-format
 msgid "unknown option: $opt"
 msgstr "непозната опция: ${opt}"
 
-#: git-stash.sh:501
+#: git-stash.sh:503
 msgid "No stash entries found."
 msgstr "Не е открито нищо скатано."
 
-#: git-stash.sh:508
+#: git-stash.sh:510
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "Указани са прекалено много версии: „${REV}“"
 
-#: git-stash.sh:523
+#: git-stash.sh:525
 #, sh-format
 msgid "$reference is not a valid reference"
 msgstr "Указателят „${reference}“ е грешен"
 
-#: git-stash.sh:551
+#: git-stash.sh:553
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "„${args}“ не е подаване, приличащо на нещо скатано"
 
-#: git-stash.sh:562
+#: git-stash.sh:564
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "„${args}“ не е указател към нещо скатано"
 
-#: git-stash.sh:570
+#: git-stash.sh:572
 msgid "unable to refresh index"
 msgstr "индексът не може да бъде обновен"
 
-#: git-stash.sh:574
+#: git-stash.sh:576
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "По време на сливане не може да приложите нещо скатано"
 
-#: git-stash.sh:582
+#: git-stash.sh:584
 msgid "Conflicts in index. Try without --index."
 msgstr ""
 "В индекса има конфликти.  Пробвайте да изпълните командата без опцията „--"
 "index“."
 
-#: git-stash.sh:584
+#: git-stash.sh:586
 msgid "Could not save index tree"
 msgstr "Дървото сочено от индекса не може да бъде запазено"
 
-#: git-stash.sh:593
+#: git-stash.sh:595
 msgid "Could not restore untracked files from stash entry"
 msgstr "Неследени файлове не могат да се възстановят от скатаното"
 
-#: git-stash.sh:618
+#: git-stash.sh:620
 msgid "Cannot unstage modified files"
 msgstr "Променените файлове не могат да бъдат извадени от индекса"
 
-#: git-stash.sh:633
+#: git-stash.sh:635
 msgid "Index was not unstashed."
 msgstr "Индексът не е скатан."
 
-#: git-stash.sh:647
+#: git-stash.sh:649
 msgid "The stash entry is kept in case you need it again."
 msgstr "Скатаното е запазено в случай, че ви потрябва отново"
 
-#: git-stash.sh:656
+#: git-stash.sh:658
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "Изтрито е скатаното „${REV}“ ($s)"
 
-#: git-stash.sh:657
+#: git-stash.sh:659
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "Скатаното „${REV}“ не може да бъде изтрито"
 
-#: git-stash.sh:665
+#: git-stash.sh:667
 msgid "No branch name specified"
 msgstr "Не е указано име на клон"
 
-#: git-stash.sh:744
+#: git-stash.sh:746
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(За да ги възстановите, изпълнете командата „git stash apply“)"
 
-#: git-submodule.sh:181
+#: git-submodule.sh:188
 msgid "Relative path can only be used from the toplevel of the working tree"
 msgstr ""
 "Относителен път може да се ползва само от основната директория на работното "
 "дърво"
 
-#: git-submodule.sh:191
+#: git-submodule.sh:198
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr ""
 "адрес на хранилище: „${repo}“ трябва или да е абсолютен, или да започва с "
 "„./“ или „../“"
 
-#: git-submodule.sh:210
+#: git-submodule.sh:217
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "„${sm_path}“ вече съществува в индекса"
 
-#: git-submodule.sh:213
+#: git-submodule.sh:220
 #, sh-format
 msgid "'$sm_path' already exists in the index and is not a submodule"
 msgstr "„${sm_path}“ вече съществува в индекса и не е подмодул"
 
-#: git-submodule.sh:219
+#: git-submodule.sh:226
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -16049,24 +17169,24 @@ msgstr ""
 "${sm_path}\n"
 "Използвайте опцията „-f“, ако за да го добавите наистина."
 
-#: git-submodule.sh:237
+#: git-submodule.sh:249
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "Добавяне на съществуващото хранилище в „${sm_path}“ към индекса"
 
-#: git-submodule.sh:239
+#: git-submodule.sh:251
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "„${sm_path}“ съществува, а не е хранилище на Git"
 
-#: git-submodule.sh:247
+#: git-submodule.sh:259
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
 msgstr ""
 "Открита е локална директория на Git — „${sm_name}“, която сочи към "
 "отдалечените хранилища:"
 
-#: git-submodule.sh:249
+#: git-submodule.sh:261
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from\n"
@@ -16083,48 +17203,48 @@ msgstr ""
 "правилното хранилище или ако не знаете какво означава това, използвайте\n"
 "друго име като аргумент към опцията „--name“."
 
-#: git-submodule.sh:255
+#: git-submodule.sh:267
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
 msgstr "Активиране на локалното хранилище за подмодула „${sm_name}“ наново."
 
-#: git-submodule.sh:267
+#: git-submodule.sh:279
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "Подмодулът „${sm_path}“ не може да бъде изтеглен"
 
-#: git-submodule.sh:272
+#: git-submodule.sh:284
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "Неуспешно добавяне на подмодула „${sm_path}“"
 
-#: git-submodule.sh:281
+#: git-submodule.sh:293
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "Неуспешно регистриране на подмодула „${sm_path}“"
 
-#: git-submodule.sh:342
+#: git-submodule.sh:354
 #, sh-format
 msgid "Entering '$displaypath'"
 msgstr "Влизане в „${displaypath}“"
 
-#: git-submodule.sh:362
+#: git-submodule.sh:374
 #, sh-format
 msgid "Stopping at '$displaypath'; script returned non-zero status."
 msgstr ""
 "Спиране при „${displaypath}“ — изходният код от скрипта бе различен от 0."
 
-#: git-submodule.sh:584
+#: git-submodule.sh:600
 #, sh-format
 msgid "Unable to find current revision in submodule path '$displaypath'"
 msgstr "Текущата версия за подмодула в „${displaypath}“ липсва"
 
-#: git-submodule.sh:594
+#: git-submodule.sh:610
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "Неуспешно доставяне в пътя към подмодул „${sm_path}“"
 
-#: git-submodule.sh:599
+#: git-submodule.sh:615
 #, sh-format
 msgid ""
 "Unable to find current ${remote_name}/${branch} revision in submodule path "
@@ -16133,12 +17253,12 @@ msgstr ""
 "Текущата версия „${remote_name}/${branch}“ в пътя към подмодул „${sm_path}“ "
 "липсва"
 
-#: git-submodule.sh:617
+#: git-submodule.sh:633
 #, sh-format
 msgid "Unable to fetch in submodule path '$displaypath'"
 msgstr "Неуспешно доставяне в пътя към подмодул „${displaypath}“"
 
-#: git-submodule.sh:623
+#: git-submodule.sh:639
 #, sh-format
 msgid ""
 "Fetched in submodule path '$displaypath', but it did not contain $sha1. "
@@ -16147,80 +17267,80 @@ msgstr ""
 "Подмодулът в пътя „$displaypath“ е доставен, но не съдържа обекта със сума\n"
 "„$sha1“.  Директното доставяне на това подаване е неуспешно."
 
-#: git-submodule.sh:630
+#: git-submodule.sh:646
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
 msgstr ""
 "Неуспешно изтегляне на версия „${sha1}“ в пътя към подмодул „${displaypath}“'"
 
-#: git-submodule.sh:631
+#: git-submodule.sh:647
 #, sh-format
 msgid "Submodule path '$displaypath': checked out '$sha1'"
 msgstr "Път към подмодул „${displaypath}“: изтеглена е версия „${sha1}“"
 
-#: git-submodule.sh:635
+#: git-submodule.sh:651
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
 msgstr ""
 "Неуспешно пребазиране на версия „${sha1}“ в пътя към подмодул "
 "„${displaypath}“"
 
-#: git-submodule.sh:636
+#: git-submodule.sh:652
 #, sh-format
 msgid "Submodule path '$displaypath': rebased into '$sha1'"
 msgstr "Път към подмодул „${displaypath}“: пребазиране върху версия „${sha1}“"
 
-#: git-submodule.sh:641
+#: git-submodule.sh:657
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$displaypath'"
 msgstr ""
 "Неуспешно сливане на версия „${sha1}“ в пътя към подмодул „${displaypath}“"
 
-#: git-submodule.sh:642
+#: git-submodule.sh:658
 #, sh-format
 msgid "Submodule path '$displaypath': merged in '$sha1'"
 msgstr "Път към подмодул „${displaypath}“: сливане с версия „${sha1}“"
 
-#: git-submodule.sh:647
+#: git-submodule.sh:663
 #, sh-format
 msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'"
 msgstr ""
 "Неуспешно изпълнение на командата „${command} ${sha1}“ в пътя към подмодул "
 "„${displaypath}“"
 
-#: git-submodule.sh:648
+#: git-submodule.sh:664
 #, sh-format
 msgid "Submodule path '$displaypath': '$command $sha1'"
 msgstr "Път към подмодул „${displaypath}“: „${command} ${sha1}“"
 
-#: git-submodule.sh:679
+#: git-submodule.sh:695
 #, sh-format
 msgid "Failed to recurse into submodule path '$displaypath'"
 msgstr ""
 "Неуспешна обработка на поддиректориите в пътя към подмодул „${displaypath}“"
 
-#: git-submodule.sh:775
+#: git-submodule.sh:791
 msgid "The --cached option cannot be used with the --files option"
 msgstr "Опциите „--cached“ и „--files“ са несъвместими"
 
-#: git-submodule.sh:827
+#: git-submodule.sh:843
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "неочакван режим „${mod_dst}“"
 
-#: git-submodule.sh:847
+#: git-submodule.sh:863
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr ""
 "  ПРЕДУПРЕЖДЕНИЕ: „${display_name}“ не съдържа подаването „${sha1_src}“"
 
-#: git-submodule.sh:850
+#: git-submodule.sh:866
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr ""
 "  ПРЕДУПРЕЖДЕНИЕ: „${display_name}“ не съдържа подаването „${sha1_dst}“"
 
-#: git-submodule.sh:853
+#: git-submodule.sh:869
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
@@ -16232,22 +17352,28 @@ msgstr ""
 msgid "See git-${cmd}(1) for details."
 msgstr "За повече информация погледнете ръководството на „git-${cmd}(1)“"
 
-#: git-rebase--interactive.sh:140
+#: git-rebase--interactive.sh:142
 #, sh-format
 msgid "Rebasing ($new_count/$total)"
 msgstr "Пребазиране ($new_count/$total)"
 
-#: git-rebase--interactive.sh:156
+#: git-rebase--interactive.sh:158
 msgid ""
 "\n"
 "Commands:\n"
-"p, pick = use commit\n"
-"r, reword = use commit, but edit the commit message\n"
-"e, edit = use commit, but stop for amending\n"
-"s, squash = use commit, but meld into previous commit\n"
-"f, fixup = like \"squash\", but discard this commit's log message\n"
-"x, exec = run command (the rest of the line) using shell\n"
-"d, drop = remove commit\n"
+"p, pick <commit> = use commit\n"
+"r, reword <commit> = use commit, but edit the commit message\n"
+"e, edit <commit> = use commit, but stop for amending\n"
+"s, squash <commit> = use commit, but meld into previous commit\n"
+"f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
+"x, exec <command> = run command (the rest of the line) using shell\n"
+"d, drop <commit> = remove commit\n"
+"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"
 "\n"
 "These lines can be re-ordered; they are executed from top to bottom.\n"
 msgstr ""
@@ -16256,16 +17382,22 @@ msgstr ""
 " p, pick — прилагане на подаването\n"
 " r, reword — прилагане на подаването, но смяна на съобщението му\n"
 " e, edit — прилагане на подаването и спиране при него за още промени\n"
-" s, squash — сливане на подаването към предходното му\n"
-" f, fixup —  сливане на подаването към предходното му, без смяна на "
+" s, squash — вкарване на подаването в предходното му\n"
+" f, fixup —  вкарване на подаването в предходното му, без смяна на "
 "съобщението\n"
 " x, exec — изпълнение на команда към обвивката: останалата част на реда\n"
 " d, drop — прескачане на подаването\n"
+" l, label ЕТИКЕТ — задаване на етикет на указаното от HEAD\n"
+" t, reset ЕТИКЕТ — занулявяне на HEAD към ЕТИКЕТа\n"
+" m, merge [-C ПОДАВАНЕ | -c ПОДАВАНЕ] ЕТИКЕТ [# ЕДИН_РЕД]\n"
+"        създаване на подаване със сливане със съобщението от първоначалното\n"
+"        подаване (или съобщението от ЕДИН_РЕД,  ако не е зададено подаване\n"
+"        със сливане.  С опцията „-c ПОДАВАНЕ“, може да смените съобщението.\n"
 "\n"
 "Може да променяте последователността на редовете — те се изпълняват\n"
 "последователно отгоре-надолу.\n"
 
-#: git-rebase--interactive.sh:171
+#: git-rebase--interactive.sh:179
 msgid ""
 "\n"
 "Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
@@ -16274,7 +17406,7 @@ msgstr ""
 "Не изтривайте редове.  Подаванията могат да се прескачат с командата "
 "„drop“.\n"
 
-#: git-rebase--interactive.sh:175
+#: git-rebase--interactive.sh:183
 msgid ""
 "\n"
 "If you remove a line here THAT COMMIT WILL BE LOST.\n"
@@ -16282,7 +17414,7 @@ msgstr ""
 "\n"
 "Ако изтриете ред, съответстващото му подаване ще бъде ИЗТРИТО.\n"
 
-#: git-rebase--interactive.sh:213
+#: git-rebase--interactive.sh:221
 #, sh-format
 msgid ""
 "You can amend the commit now, with\n"
@@ -16301,84 +17433,84 @@ msgstr ""
 "\n"
 "    git rebase --continue"
 
-#: git-rebase--interactive.sh:238
+#: git-rebase--interactive.sh:246
 #, sh-format
 msgid "$sha1: not a commit that can be picked"
 msgstr "$sha1: това не е подаване, което може да бъде отбрано"
 
-#: git-rebase--interactive.sh:277
+#: git-rebase--interactive.sh:285
 #, sh-format
 msgid "Invalid commit name: $sha1"
 msgstr "Неправилно име на подаване: „$sha1“"
 
-#: git-rebase--interactive.sh:319
+#: git-rebase--interactive.sh:325
 msgid "Cannot write current commit's replacement sha1"
 msgstr ""
 "Заместващата сума по SHA1 за текущото подаване не може да бъде запазена"
 
-#: git-rebase--interactive.sh:371
+#: git-rebase--interactive.sh:376
 #, sh-format
 msgid "Fast-forward to $sha1"
 msgstr "Превъртане до „$sha1“"
 
-#: git-rebase--interactive.sh:373
+#: git-rebase--interactive.sh:378
 #, sh-format
 msgid "Cannot fast-forward to $sha1"
 msgstr "Не може да се превърти до „$sha1“"
 
-#: git-rebase--interactive.sh:382
+#: git-rebase--interactive.sh:387
 #, sh-format
 msgid "Cannot move HEAD to $first_parent"
 msgstr "Указателят „HEAD“ не може да се насочи към „$first_parent“"
 
-#: git-rebase--interactive.sh:387
+#: git-rebase--interactive.sh:392
 #, sh-format
 msgid "Refusing to squash a merge: $sha1"
 msgstr "Подаването не може да се смачка: „$sha1“"
 
-#: git-rebase--interactive.sh:405
+#: git-rebase--interactive.sh:410
 #, sh-format
 msgid "Error redoing merge $sha1"
 msgstr "Грешка при повтарянето на сливането на „$sha1“"
 
-#: git-rebase--interactive.sh:414
+#: git-rebase--interactive.sh:419
 #, sh-format
 msgid "Could not pick $sha1"
 msgstr "„$sha1“ не може да се отбере."
 
-#: git-rebase--interactive.sh:423
+#: git-rebase--interactive.sh:428
 #, sh-format
 msgid "This is the commit message #${n}:"
 msgstr "Това е съобщение при подаване №${n}:"
 
-#: git-rebase--interactive.sh:428
+#: git-rebase--interactive.sh:433
 #, sh-format
 msgid "The commit message #${n} will be skipped:"
 msgstr "Съобщение при подаване №${n} ще бъде прескочено."
 
-#: git-rebase--interactive.sh:439
+#: git-rebase--interactive.sh:444
 #, sh-format
 msgid "This is a combination of $count commit."
 msgid_plural "This is a combination of $count commits."
 msgstr[0] "Това е обединение от $count подаване."
 msgstr[1] "Това е обединение от $count подавания."
 
-#: git-rebase--interactive.sh:448
+#: git-rebase--interactive.sh:453
 #, sh-format
 msgid "Cannot write $fixup_msg"
 msgstr "Новото съобщение при подаване „$fixup_msg“ не може да бъде запазено"
 
-#: git-rebase--interactive.sh:451
+#: git-rebase--interactive.sh:456
 msgid "This is a combination of 2 commits."
 msgstr "Това е обединение от 2 подавания"
 
-#: git-rebase--interactive.sh:492 git-rebase--interactive.sh:535
-#: git-rebase--interactive.sh:538
+#: git-rebase--interactive.sh:497 git-rebase--interactive.sh:540
+#: git-rebase--interactive.sh:543
 #, sh-format
 msgid "Could not apply $sha1... $rest"
 msgstr "Не може да се подаде $sha1… $rest"
 
-#: git-rebase--interactive.sh:567
+#: git-rebase--interactive.sh:572
 #, sh-format
 msgid ""
 "Could not amend commit after successfully picking $sha1... $rest\n"
@@ -16394,31 +17526,31 @@ msgstr ""
 "коригирате,\n"
 "преди да можете да промените подаването."
 
-#: git-rebase--interactive.sh:582
+#: git-rebase--interactive.sh:587
 #, sh-format
 msgid "Stopped at $sha1_abbrev... $rest"
 msgstr "Спиране при „$sha1_abbrev…“ $rest"
 
-#: git-rebase--interactive.sh:597
+#: git-rebase--interactive.sh:602
 #, sh-format
 msgid "Cannot '$squash_style' without a previous commit"
-msgstr "Без предишно подаване не може да се изпълни „$squash_style“"
+msgstr "Без предходно подаване не може да се изпълни „$squash_style“"
 
-#: git-rebase--interactive.sh:639
+#: git-rebase--interactive.sh:644
 #, sh-format
 msgid "Executing: $rest"
 msgstr "В момента се изпълнява: $rest"
 
-#: git-rebase--interactive.sh:647
+#: git-rebase--interactive.sh:652
 #, sh-format
 msgid "Execution failed: $rest"
 msgstr "Неуспешно изпълнение: $rest"
 
-#: git-rebase--interactive.sh:649
+#: git-rebase--interactive.sh:654
 msgid "and made changes to the index and/or the working tree"
 msgstr "и промени индекса и/или работното дърво"
 
-#: git-rebase--interactive.sh:651
+#: git-rebase--interactive.sh:656
 msgid ""
 "You can fix the problem, and then run\n"
 "\n"
@@ -16429,7 +17561,7 @@ msgstr ""
 "    git rebase --continue"
 
 #. TRANSLATORS: after these lines is a command to be issued by the user
-#: git-rebase--interactive.sh:664
+#: git-rebase--interactive.sh:669
 #, sh-format
 msgid ""
 "Execution succeeded: $rest\n"
@@ -16444,29 +17576,29 @@ msgstr ""
 "\n"
 "    git rebase --continue"
 
-#: git-rebase--interactive.sh:675
+#: git-rebase--interactive.sh:680
 #, sh-format
 msgid "Unknown command: $command $sha1 $rest"
 msgstr "Непозната команда: $command $sha1 $rest"
 
-#: git-rebase--interactive.sh:676
+#: git-rebase--interactive.sh:681
 msgid "Please fix this using 'git rebase --edit-todo'."
 msgstr "Коригирайте това чрез „git rebase --edit-todo“."
 
-#: git-rebase--interactive.sh:711
+#: git-rebase--interactive.sh:716
 #, sh-format
 msgid "Successfully rebased and updated $head_name."
 msgstr "Успешно пребазиране и обновяване на „$head_name“."
 
-#: git-rebase--interactive.sh:735
+#: git-rebase--interactive.sh:740
 msgid "could not detach HEAD"
 msgstr "указателят „HEAD“ не може да се отдели"
 
-#: git-rebase--interactive.sh:771
+#: git-rebase--interactive.sh:778
 msgid "Could not remove CHERRY_PICK_HEAD"
 msgstr "Указателят „CHERRY_PICK_HEAD“ не може да бъде изтрит"
 
-#: git-rebase--interactive.sh:776
+#: git-rebase--interactive.sh:783
 #, sh-format
 msgid ""
 "You have staged changes in your working tree.\n"
@@ -16483,7 +17615,7 @@ msgid ""
 "\n"
 "  git rebase --continue\n"
 msgstr ""
-"Ð\92 Ð¸Ð½Ð´ÐµÐºÑ\81а Ð¸Ð¼Ð° Ð¿Ñ\80омени.  Ð\90ко Ð¸Ñ\81каÑ\82е Ð´Ð° Ð³Ð¸ Ð¿Ñ\80ибавиÑ\82е ÐºÑ\8aм\n"
+"Ð\92 Ð¸Ð½Ð´ÐµÐºÑ\81а Ð¸Ð¼Ð° Ð¿Ñ\80омени.  Ð\90ко Ð¸Ñ\81каÑ\82е Ð´Ð° Ð³Ð¸ Ð²ÐºÐ°Ñ\80аÑ\82е Ð²\n"
 "предишното подаване, изпълнете:\n"
 "\n"
 "    git commit --amend $gpg_sign_opt_quoted\n"
@@ -16496,11 +17628,11 @@ msgstr ""
 "\n"
 "    git rebase --continue\n"
 
-#: git-rebase--interactive.sh:793
+#: git-rebase--interactive.sh:800
 msgid "Error trying to find the author identity to amend commit"
 msgstr "Не може да бъде открит автор за поправянето на подаването"
 
-#: git-rebase--interactive.sh:798
+#: git-rebase--interactive.sh:805
 msgid ""
 "You have uncommitted changes in your working tree. Please commit them\n"
 "first and then run 'git rebase --continue' again."
@@ -16508,11 +17640,11 @@ msgstr ""
 "В работното дърво има неподадени промени.  Първо ги подайте, а след това\n"
 "отново изпълнете „git rebase --continue“."
 
-#: git-rebase--interactive.sh:803 git-rebase--interactive.sh:807
+#: git-rebase--interactive.sh:810 git-rebase--interactive.sh:814
 msgid "Could not commit staged changes."
 msgstr "Промените в индекса не могат да бъдат подадени."
 
-#: git-rebase--interactive.sh:836
+#: git-rebase--interactive.sh:843
 msgid ""
 "\n"
 "You are editing the todo file of an ongoing interactive rebase.\n"
@@ -16527,37 +17659,29 @@ msgstr ""
 "    git rebase --continue\n"
 "\n"
 
-#: git-rebase--interactive.sh:844 git-rebase--interactive.sh:1008
+#: git-rebase--interactive.sh:851 git-rebase--interactive.sh:937
 msgid "Could not execute editor"
 msgstr "Текстовият редактор не може да бъде стартиран"
 
-#: git-rebase--interactive.sh:860
+#: git-rebase--interactive.sh:872
 #, sh-format
 msgid "Could not checkout $switch_to"
 msgstr "„$switch_to“ не може да се изтегли"
 
-#: git-rebase--interactive.sh:865
+#: git-rebase--interactive.sh:879
 msgid "No HEAD?"
 msgstr "Липсва указател „HEAD“"
 
-#: git-rebase--interactive.sh:866
+#: git-rebase--interactive.sh:880
 #, sh-format
 msgid "Could not create temporary $state_dir"
 msgstr "Временната директория „$state_dir“ не може да бъде създадена"
 
-#: git-rebase--interactive.sh:869
+#: git-rebase--interactive.sh:883
 msgid "Could not mark as interactive"
 msgstr "Пребазирането не е интерактивно"
 
-#: git-rebase--interactive.sh:879 git-rebase--interactive.sh:884
-msgid "Could not init rewritten commits"
-msgstr "Списъкът с презаписаните подавания не може да бъде създаден"
-
-#: git-rebase--interactive.sh:910
-msgid "Could not generate todo list"
-msgstr "Файлът с командите не може да се генерира"
-
-#: git-rebase--interactive.sh:986
+#: git-rebase--interactive.sh:915
 #, sh-format
 msgid "Rebase $shortrevisions onto $shortonto ($todocount command)"
 msgid_plural "Rebase $shortrevisions onto $shortonto ($todocount commands)"
@@ -16566,20 +17690,30 @@ msgstr[0] ""
 msgstr[1] ""
 "Пребазиране на $shortrevisions върху $shortonto ($todocount команди)"
 
-#: git-rebase--interactive.sh:991
+#: git-rebase--interactive.sh:920
 msgid ""
 "\n"
-"However, if you remove everything, the rebase will be aborted.\n"
+"\tHowever, if you remove everything, the rebase will be aborted.\n"
 "\n"
+"\t"
 msgstr ""
 "\n"
-"Ако изтриете всичко, пребазирането ще бъде преустановено.\n"
+"    Ако изтриете всичко, пребазирането ще бъде преустановено.\n"
 "\n"
+"    "
 
-#: git-rebase--interactive.sh:998
+#: git-rebase--interactive.sh:927
 msgid "Note that empty commits are commented out"
 msgstr "Празните подавания са коментирани"
 
+#: git-rebase--interactive.sh:980
+msgid "Could not generate todo list"
+msgstr "Файлът с командите не може да се генерира"
+
+#: git-rebase--interactive.sh:1001 git-rebase--interactive.sh:1006
+msgid "Could not init rewritten commits"
+msgstr "Списъкът с презаписаните подавания не може да бъде създаден"
+
 #: git-sh-setup.sh:89 git-sh-setup.sh:94
 #, sh-format
 msgid "usage: $dashless $USAGE"
@@ -16661,68 +17795,68 @@ msgstr "в индекса"
 msgid "unstaged"
 msgstr "извън индекса"
 
-#: git-add--interactive.perl:246 git-add--interactive.perl:271
+#: git-add--interactive.perl:253 git-add--interactive.perl:278
 msgid "binary"
 msgstr "двоично"
 
-#: git-add--interactive.perl:255 git-add--interactive.perl:309
+#: git-add--interactive.perl:262 git-add--interactive.perl:316
 msgid "nothing"
 msgstr "нищо"
 
-#: git-add--interactive.perl:291 git-add--interactive.perl:306
+#: git-add--interactive.perl:298 git-add--interactive.perl:313
 msgid "unchanged"
 msgstr "няма промени"
 
-#: git-add--interactive.perl:602
+#: git-add--interactive.perl:609
 #, perl-format
 msgid "added %d path\n"
 msgid_plural "added %d paths\n"
 msgstr[0] "%d файл добавен\n"
 msgstr[1] "%d файла добавени\n"
 
-#: git-add--interactive.perl:605
+#: git-add--interactive.perl:612
 #, perl-format
 msgid "updated %d path\n"
 msgid_plural "updated %d paths\n"
 msgstr[0] "%d файл обновен\n"
 msgstr[1] "%d файла обновени\n"
 
-#: git-add--interactive.perl:608
+#: git-add--interactive.perl:615
 #, perl-format
 msgid "reverted %d path\n"
 msgid_plural "reverted %d paths\n"
 msgstr[0] "%d файл с отменени промени\n"
 msgstr[1] "%d файла с отменени промени\n"
 
-#: git-add--interactive.perl:611
+#: git-add--interactive.perl:618
 #, perl-format
 msgid "touched %d path\n"
 msgid_plural "touched %d paths\n"
 msgstr[0] "%d файл засегнат\n"
 msgstr[1] "%d файла засегнати\n"
 
-#: git-add--interactive.perl:620
+#: git-add--interactive.perl:627
 msgid "Update"
 msgstr "Обновяване"
 
-#: git-add--interactive.perl:632
+#: git-add--interactive.perl:639
 msgid "Revert"
 msgstr "Отмяна"
 
-#: git-add--interactive.perl:655
+#: git-add--interactive.perl:662
 #, perl-format
 msgid "note: %s is untracked now.\n"
 msgstr "БЕЛЕЖКА: „%s“ вече не се следи.\n"
 
-#: git-add--interactive.perl:666
+#: git-add--interactive.perl:673
 msgid "Add untracked"
 msgstr "Добавяне на неследени"
 
-#: git-add--interactive.perl:672
+#: git-add--interactive.perl:679
 msgid "No untracked files.\n"
 msgstr "Няма неследени файлове.\n"
 
-#: git-add--interactive.perl:1026
+#: git-add--interactive.perl:1033
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for staging."
@@ -16731,7 +17865,7 @@ msgstr ""
 "незабавно\n"
 "добавено към индекса"
 
-#: git-add--interactive.perl:1029
+#: git-add--interactive.perl:1036
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for stashing."
@@ -16740,7 +17874,7 @@ msgstr ""
 "незабавно\n"
 "скътано"
 
-#: git-add--interactive.perl:1032
+#: git-add--interactive.perl:1039
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for unstaging."
@@ -16749,7 +17883,7 @@ msgstr ""
 "незабавно\n"
 "извадено от индекса."
 
-#: git-add--interactive.perl:1035 git-add--interactive.perl:1044
+#: git-add--interactive.perl:1042 git-add--interactive.perl:1051
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for applying."
@@ -16758,7 +17892,7 @@ msgstr ""
 "незабавно\n"
 "набелязано за прилагане."
 
-#: git-add--interactive.perl:1038 git-add--interactive.perl:1041
+#: git-add--interactive.perl:1045 git-add--interactive.perl:1048
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for discarding."
@@ -16767,16 +17901,16 @@ msgstr ""
 "незабавно\n"
 "набелязано за зануляване."
 
-#: git-add--interactive.perl:1078
+#: git-add--interactive.perl:1085
 #, perl-format
 msgid "failed to open hunk edit file for writing: %s"
 msgstr "файлът за редактиране на парчето код не може да бъде отворен: „%s“"
 
-#: git-add--interactive.perl:1079
+#: git-add--interactive.perl:1086
 msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
 msgstr "Ръчно редактиране на парчета код — отдолу има подсказка.\n"
 
-#: git-add--interactive.perl:1085
+#: git-add--interactive.perl:1092
 #, perl-format
 msgid ""
 "---\n"
@@ -16791,7 +17925,7 @@ msgstr ""
 "Редовете, които започват с „%s“ ще бъдат пропуснати.\n"
 
 #. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
-#: git-add--interactive.perl:1093
+#: git-add--interactive.perl:1100
 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"
@@ -16801,7 +17935,7 @@ msgstr ""
 "изтриете всички редове от парчето код, то ще бъде оставено непроменено, а\n"
 "редактирането — отказано.\n"
 
-#: git-add--interactive.perl:1107
+#: git-add--interactive.perl:1114
 #, perl-format
 msgid "failed to open hunk edit file for reading: %s"
 msgstr ""
@@ -16813,7 +17947,7 @@ msgstr ""
 #. 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:1206
+#: git-add--interactive.perl:1213
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
@@ -16821,7 +17955,7 @@ msgstr ""
 "редактирането? (текущите редакции ще се отменят при отказ!): „y“ (да)/ "
 "„n“ (не)? "
 
-#: git-add--interactive.perl:1215
+#: git-add--interactive.perl:1222
 msgid ""
 "y - stage this hunk\n"
 "n - do not stage this hunk\n"
@@ -16835,7 +17969,7 @@ msgstr ""
 "a — добавяне на това и всички следващи парчета от файла в индекса\n"
 "d — без добавяне на това и всички следващи парчета от файла в индекса"
 
-#: git-add--interactive.perl:1221
+#: git-add--interactive.perl:1228
 msgid ""
 "y - stash this hunk\n"
 "n - do not stash this hunk\n"
@@ -16849,7 +17983,7 @@ msgstr ""
 "a — скатаване на това и всички следващи парчета от файла\n"
 "d — без скатаване на това и всички следващи парчета от файла"
 
-#: git-add--interactive.perl:1227
+#: git-add--interactive.perl:1234
 msgid ""
 "y - unstage this hunk\n"
 "n - do not unstage this hunk\n"
@@ -16863,7 +17997,7 @@ msgstr ""
 "a — изваждане на това и всички следващи парчета от файла от индекса\n"
 "d — без изваждане на това и всички следващи парчета от файла от индекса"
 
-#: git-add--interactive.perl:1233
+#: git-add--interactive.perl:1240
 msgid ""
 "y - apply this hunk to index\n"
 "n - do not apply this hunk to index\n"
@@ -16877,7 +18011,7 @@ msgstr ""
 "a — прилагане на това и всички следващи парчета от файла към индекса\n"
 "d — без прилагане на това и всички следващи парчета от файла към индекса"
 
-#: git-add--interactive.perl:1239
+#: git-add--interactive.perl:1246
 msgid ""
 "y - discard this hunk from worktree\n"
 "n - do not discard this hunk from worktree\n"
@@ -16894,7 +18028,7 @@ msgstr ""
 "d — без премахване на това и всички следващи парчета от файла от работното "
 "дърво"
 
-#: git-add--interactive.perl:1245
+#: git-add--interactive.perl:1252
 msgid ""
 "y - discard this hunk from index and worktree\n"
 "n - do not discard this hunk from index and worktree\n"
@@ -16911,7 +18045,7 @@ msgstr ""
 "d — без премахване на това и всички следващи парчета от файла от индекса и "
 "работното дърво"
 
-#: git-add--interactive.perl:1251
+#: git-add--interactive.perl:1258
 msgid ""
 "y - apply this hunk to index and worktree\n"
 "n - do not apply this hunk to index and worktree\n"
@@ -16928,7 +18062,7 @@ msgstr ""
 "d — без прилагане на това и всички следващи парчета от файла от индекса и "
 "работното дърво"
 
-#: git-add--interactive.perl:1266
+#: git-add--interactive.perl:1273
 msgid ""
 "g - select a hunk to go to\n"
 "/ - search for a hunk matching the given regex\n"
@@ -16950,220 +18084,220 @@ msgstr ""
 "e — ръчно редактиране на текущото парче\n"
 "? — извеждане не помощта\n"
 
-#: git-add--interactive.perl:1297
+#: git-add--interactive.perl:1304
 msgid "The selected hunks do not apply to the index!\n"
 msgstr "Избраните парчета не могат да се добавят в индекса!\n"
 
-#: git-add--interactive.perl:1298
+#: git-add--interactive.perl:1305
 msgid "Apply them to the worktree anyway? "
 msgstr "Да се приложат ли към работното дърво? "
 
-#: git-add--interactive.perl:1301
+#: git-add--interactive.perl:1308
 msgid "Nothing was applied.\n"
 msgstr "Нищо не е приложено.\n"
 
-#: git-add--interactive.perl:1312
+#: git-add--interactive.perl:1319
 #, perl-format
 msgid "ignoring unmerged: %s\n"
 msgstr "пренебрегване на неслятото: „%s“\n"
 
-#: git-add--interactive.perl:1321
+#: git-add--interactive.perl:1328
 msgid "Only binary files changed.\n"
 msgstr "Само двоични файлове са променени.\n"
 
-#: git-add--interactive.perl:1323
+#: git-add--interactive.perl:1330
 msgid "No changes.\n"
 msgstr "Няма промени.\n"
 
-#: git-add--interactive.perl:1331
+#: git-add--interactive.perl:1338
 msgid "Patch update"
 msgstr "Обновяване на кръпка"
 
-#: git-add--interactive.perl:1383
+#: git-add--interactive.perl:1390
 #, perl-format
 msgid "Stage mode change [y,n,q,a,d%s,?]? "
 msgstr "Добавяне на промяната на правата за достъп [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1384
+#: git-add--interactive.perl:1391
 #, perl-format
 msgid "Stage deletion [y,n,q,a,d%s,?]? "
 msgstr "Добавяне на изтриването [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1385
+#: git-add--interactive.perl:1392
 #, perl-format
 msgid "Stage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Добавяне на това парче [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1388
+#: git-add--interactive.perl:1395
 #, perl-format
 msgid "Stash mode change [y,n,q,a,d%s,?]? "
 msgstr "Скатаване на промяната на правата за достъп [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1389
+#: git-add--interactive.perl:1396
 #, perl-format
 msgid "Stash deletion [y,n,q,a,d%s,?]? "
 msgstr "Скатаване на изтриването [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1390
+#: git-add--interactive.perl:1397
 #, perl-format
 msgid "Stash this hunk [y,n,q,a,d%s,?]? "
 msgstr "Скатаване на това парче [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1393
+#: git-add--interactive.perl:1400
 #, perl-format
 msgid "Unstage mode change [y,n,q,a,d%s,?]? "
 msgstr "Изваждане на промяната на правата за достъп [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1394
+#: git-add--interactive.perl:1401
 #, perl-format
 msgid "Unstage deletion [y,n,q,a,d%s,?]? "
 msgstr "Изваждане на изтриването [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1395
+#: git-add--interactive.perl:1402
 #, perl-format
 msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Изваждане на това парче [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1398
+#: git-add--interactive.perl:1405
 #, perl-format
 msgid "Apply mode change to index [y,n,q,a,d%s,?]? "
 msgstr ""
 "Прилагане на промяната на правата за достъп към индекса [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1399
+#: git-add--interactive.perl:1406
 #, perl-format
 msgid "Apply deletion to index [y,n,q,a,d%s,?]? "
 msgstr "Прилагане на изтриването към индекса [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1400
+#: git-add--interactive.perl:1407
 #, perl-format
 msgid "Apply this hunk to index [y,n,q,a,d%s,?]? "
 msgstr "Прилагане на това парче към индекса [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1403
+#: git-add--interactive.perl:1410
 #, perl-format
 msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 "Премахване на промяната в правата за достъп от работното дърво [y,n,q,a,d"
 "%s,?]? "
 
-#: git-add--interactive.perl:1404
+#: git-add--interactive.perl:1411
 #, perl-format
 msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? "
 msgstr "Премахване на изтриването от работното дърво [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1405
+#: git-add--interactive.perl:1412
 #, perl-format
 msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
 msgstr "Премахване на парчето от работното дърво [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1408
+#: git-add--interactive.perl:1415
 #, perl-format
 msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 "Премахване на промяната в правата за достъп от индекса и работното дърво [y,"
 "n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1409
+#: git-add--interactive.perl:1416
 #, perl-format
 msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 "Премахване на изтриването от индекса и работното дърво [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1410
+#: git-add--interactive.perl:1417
 #, perl-format
 msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Премахване на парчето от индекса и работното дърво [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1413
+#: git-add--interactive.perl:1420
 #, perl-format
 msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 "Прилагане на промяната в правата за достъп от индекса и работното дърво [y,n,"
 "q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1414
+#: git-add--interactive.perl:1421
 #, perl-format
 msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 "Прилагане на изтриването от индекса и работното дърво [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1415
+#: git-add--interactive.perl:1422
 #, perl-format
 msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Прилагане на парчето от индекса и работното дърво [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1515
+#: git-add--interactive.perl:1522
 msgid "No other hunks to goto\n"
 msgstr "Няма други парчета\n"
 
-#: git-add--interactive.perl:1522
+#: git-add--interactive.perl:1529
 msgid "go to which hunk (<ret> to see more)? "
 msgstr "към кое парче да се придвижи (за повече варианти натиснете „enter“)? "
 
-#: git-add--interactive.perl:1524
+#: git-add--interactive.perl:1531
 msgid "go to which hunk? "
 msgstr "към кое парче да се придвижи? "
 
-#: git-add--interactive.perl:1533
+#: git-add--interactive.perl:1540
 #, perl-format
 msgid "Invalid number: '%s'\n"
 msgstr "Неправилен номер: „%s“\n"
 
-#: git-add--interactive.perl:1538
+#: git-add--interactive.perl:1545
 #, perl-format
 msgid "Sorry, only %d hunk available.\n"
 msgid_plural "Sorry, only %d hunks available.\n"
 msgstr[0] "Има само %d парче.\n"
 msgstr[1] "Има само %d парчета.\n"
 
-#: git-add--interactive.perl:1564
+#: git-add--interactive.perl:1571
 msgid "No other hunks to search\n"
 msgstr "Няма други парчета за търсене\n"
 
-#: git-add--interactive.perl:1568
+#: git-add--interactive.perl:1575
 msgid "search for regex? "
 msgstr "да се търси с регулярен израз? "
 
-#: git-add--interactive.perl:1581
+#: git-add--interactive.perl:1588
 #, perl-format
 msgid "Malformed search regexp %s: %s\n"
 msgstr "Сгрешен регулярен израз „%s“: %s\n"
 
-#: git-add--interactive.perl:1591
+#: git-add--interactive.perl:1598
 msgid "No hunk matches the given pattern\n"
 msgstr "Никое парче не напасва на регулярния израз\n"
 
-#: git-add--interactive.perl:1603 git-add--interactive.perl:1625
+#: git-add--interactive.perl:1610 git-add--interactive.perl:1632
 msgid "No previous hunk\n"
 msgstr "Няма друго парче преди това\n"
 
-#: git-add--interactive.perl:1612 git-add--interactive.perl:1631
+#: git-add--interactive.perl:1619 git-add--interactive.perl:1638
 msgid "No next hunk\n"
 msgstr "Няма друго парче след това\n"
 
-#: git-add--interactive.perl:1637
+#: git-add--interactive.perl:1644
 msgid "Sorry, cannot split this hunk\n"
 msgstr "Това парче не може да бъде разделено\n"
 
-#: git-add--interactive.perl:1643
+#: git-add--interactive.perl:1650
 #, perl-format
 msgid "Split into %d hunk.\n"
 msgid_plural "Split into %d hunks.\n"
 msgstr[0] "Разделяне на %d парче.\n"
 msgstr[1] "Разделяне на %d парчета.\n"
 
-#: git-add--interactive.perl:1653
+#: git-add--interactive.perl:1660
 msgid "Sorry, cannot edit this hunk\n"
 msgstr "Това парче не може да бъде редактирано\n"
 
-#: git-add--interactive.perl:1699
+#: git-add--interactive.perl:1706
 msgid "Review diff"
 msgstr "Преглед на разликата"
 
 #. TRANSLATORS: please do not translate the command names
 #. 'status', 'update', 'revert', etc.
-#: git-add--interactive.perl:1718
+#: git-add--interactive.perl:1725
 msgid ""
 "status        - show paths with changes\n"
 "update        - add working tree state to the staged set of changes\n"
@@ -17184,18 +18318,18 @@ msgstr ""
 "                и индекса\n"
 "add untracked — добавяне на неследените файлове към промените в индекса\n"
 
-#: git-add--interactive.perl:1735 git-add--interactive.perl:1740
-#: git-add--interactive.perl:1743 git-add--interactive.perl:1750
-#: git-add--interactive.perl:1754 git-add--interactive.perl:1760
+#: git-add--interactive.perl:1742 git-add--interactive.perl:1747
+#: git-add--interactive.perl:1750 git-add--interactive.perl:1757
+#: git-add--interactive.perl:1761 git-add--interactive.perl:1767
 msgid "missing --"
 msgstr "„--“ липсва"
 
-#: git-add--interactive.perl:1756
+#: git-add--interactive.perl:1763
 #, perl-format
 msgid "unknown --patch mode: %s"
 msgstr "неизвестна стратегия за прилагане на кръпка: „%s“"
 
-#: git-add--interactive.perl:1762 git-add--interactive.perl:1768
+#: git-add--interactive.perl:1769 git-add--interactive.perl:1775
 #, perl-format
 msgid "invalid argument %s, expecting --"
 msgstr "указан е неправилен аргумент „%s“, а се очаква „--“."
@@ -17418,7 +18552,7 @@ msgstr ""
 msgid "CA path \"%s\" does not exist"
 msgstr "Пътят към сертификат „%s“ не съществува."
 
-#: git-send-email.perl:1395
+#: git-send-email.perl:1400
 msgid ""
 "    The Cc list above has been expanded by additional\n"
 "    addresses found in the patch commit message. By default\n"
@@ -17443,134 +18577,135 @@ msgstr ""
 "    „git config --global sendemail.confirm auto“.\n"
 "\n"
 
-#. TRANSLATORS: Make sure to include [y] [n] [q] [a] in your
+#. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
 #. translation. The program will only accept English input
 #. at this point.
-#: git-send-email.perl:1410
-msgid "Send this email? ([y]es|[n]o|[q]uit|[a]ll): "
+#: git-send-email.perl:1415
+msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
 msgstr ""
-"Изпращане на е-писмото? „y“ (да), „n“ (не), „q“ (изход), „a“ (всичко): "
+"Изпращане на е-писмото? „y“ (да), „n“ (не), „e“ (редактиране), „q“ (изход), "
+"„a“ (всичко): "
 
-#: git-send-email.perl:1413
+#: git-send-email.perl:1418
 msgid "Send this email reply required"
 msgstr "Изискване на отговор към това е-писмо"
 
-#: git-send-email.perl:1439
+#: git-send-email.perl:1446
 msgid "The required SMTP server is not properly defined."
 msgstr "Сървърът за SMTP не е настроен правилно."
 
-#: git-send-email.perl:1486
+#: git-send-email.perl:1493
 #, perl-format
 msgid "Server does not support STARTTLS! %s"
 msgstr "Сървърът не поддържа „STARTTLS“! %s"
 
-#: git-send-email.perl:1491 git-send-email.perl:1495
+#: git-send-email.perl:1498 git-send-email.perl:1502
 #, perl-format
 msgid "STARTTLS failed! %s"
 msgstr "Неуспешно изпълнение на STARTTLS! %s"
 
-#: git-send-email.perl:1505
+#: git-send-email.perl:1512
 msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug."
 msgstr ""
 "Подсистемата за SMTP не може да се инициализира.  Проверете настройките и "
 "използвайте опцията: „--smtp-debug“."
 
-#: git-send-email.perl:1523
+#: git-send-email.perl:1530
 #, perl-format
 msgid "Failed to send %s\n"
 msgstr "„%s“ не може да бъде изпратен\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Dry-Sent %s\n"
 msgstr "Проба за изпращане на „%s“\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Sent %s\n"
 msgstr "Изпращане на „%s“\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "Dry-OK. Log says:\n"
 msgstr "Успех при пробата.  От журнала:\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "OK. Log says:\n"
 msgstr "Успех.  От журнала:\n"
 
-#: git-send-email.perl:1540
+#: git-send-email.perl:1547
 msgid "Result: "
 msgstr "Резултат: "
 
-#: git-send-email.perl:1543
+#: git-send-email.perl:1550
 msgid "Result: OK\n"
 msgstr "Резултат: успех\n"
 
-#: git-send-email.perl:1556
+#: git-send-email.perl:1568
 #, perl-format
 msgid "can't open file %s"
 msgstr "файлът „%s“ не може да бъде отворен"
 
-#: git-send-email.perl:1603 git-send-email.perl:1623
+#: git-send-email.perl:1615 git-send-email.perl:1635
 #, perl-format
 msgid "(mbox) Adding cc: %s from line '%s'\n"
 msgstr "(mbox) Добавяне на „як: %s“ от ред „%s“\n"
 
-#: git-send-email.perl:1609
+#: git-send-email.perl:1621
 #, perl-format
 msgid "(mbox) Adding to: %s from line '%s'\n"
 msgstr "(mbox) Добавяне на „до: %s“ от ред „%s“\n"
 
-#: git-send-email.perl:1657
+#: git-send-email.perl:1674
 #, perl-format
 msgid "(non-mbox) Adding cc: %s from line '%s'\n"
 msgstr "(не-mbox) Добавяне на „як: %s“ от ред „%s“\n"
 
-#: git-send-email.perl:1682
+#: git-send-email.perl:1699
 #, perl-format
 msgid "(body) Adding cc: %s from line '%s'\n"
 msgstr "(тяло) Добавяне на „як: %s“ от ред „%s“\n"
 
-#: git-send-email.perl:1788
+#: git-send-email.perl:1817
 #, perl-format
 msgid "(%s) Could not execute '%s'"
 msgstr "(%s) Не може да бъде се изпълни „%s“"
 
-#: git-send-email.perl:1795
+#: git-send-email.perl:1824
 #, perl-format
 msgid "(%s) Adding %s: %s from: '%s'\n"
 msgstr "(%s) Добавяне на „%s: %s“ от: „%s“\n"
 
-#: git-send-email.perl:1799
+#: git-send-email.perl:1828
 #, perl-format
 msgid "(%s) failed to close pipe to '%s'"
 msgstr "(%s) програмният канал не може да се затвори за изпълнението на „%s“"
 
-#: git-send-email.perl:1826
+#: git-send-email.perl:1855
 msgid "cannot send message as 7bit"
 msgstr "съобщението не може да се изпрати чрез 7 битови знаци"
 
-#: git-send-email.perl:1834
+#: git-send-email.perl:1863
 msgid "invalid transfer encoding"
 msgstr "неправилно кодиране за пренос"
 
-#: git-send-email.perl:1872 git-send-email.perl:1923 git-send-email.perl:1933
+#: git-send-email.perl:1901 git-send-email.perl:1952 git-send-email.perl:1962
 #, perl-format
 msgid "unable to open %s: %s\n"
 msgstr "„%s“ не може да се отвори: %s\n"
 
-#: git-send-email.perl:1875
+#: git-send-email.perl:1904
 #, perl-format
 msgid "%s: patch contains a line longer than 998 characters"
 msgstr "„%s“: кръпката съдържа ред с над 988 знака"
 
-#: git-send-email.perl:1891
+#: git-send-email.perl:1920
 #, perl-format
 msgid "Skipping %s with backup suffix '%s'.\n"
 msgstr "„%s“ се пропуска, защото е с разширение за архивен файл: „%s“.\n"
 
 #. TRANSLATORS: please keep "[y|N]" as is.
-#: git-send-email.perl:1895
+#: git-send-email.perl:1924
 #, perl-format
 msgid "Do you really want to send %s? [y|N]: "
 msgstr "Наистина ли искате да изпратите „%s“? [y|N]: "
index 6bba189a0b8aa27c0af3fde2547a040e2a3a100a..495a6260644c187acf49fa09b3e8ae490243d34c 100644 (file)
--- a/po/ca.po
+++ b/po/ca.po
@@ -48,7 +48,7 @@ msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
 "POT-Creation-Date: 2018-03-16 07:29+0800\n"
-"PO-Revision-Date: 2018-03-18 15:48+0100\n"
+"PO-Revision-Date: 2018-03-29 15:32+0200\n"
 "Last-Translator: Jordi Mas <jmas@softcatala.org>\n"
 "Language-Team: Catalan\n"
 "Language: ca\n"
@@ -189,17 +189,22 @@ msgstr "no s'ha pogut trobar el nom de fitxer en el pedaç a la línia %d"
 #, c-format
 msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d"
 msgstr ""
-"git apply: git-diff incorrecte - s'esperava /dev/null, s'ha rebut %s en la línia %d"
+"git apply: git-diff incorrecte - s'esperava /dev/null, s'ha rebut %s en la "
+"línia %d"
 
 #: apply.c:948
 #, c-format
 msgid "git apply: bad git-diff - inconsistent new filename on line %d"
-msgstr "git apply: git-diff incorrecte - nom de fitxer nou inconsistent en la línia %d"
+msgstr ""
+"git apply: git-diff incorrecte - nom de fitxer nou inconsistent en la línia "
+"%d"
 
 #: apply.c:949
 #, c-format
 msgid "git apply: bad git-diff - inconsistent old filename on line %d"
-msgstr "git apply: git-diff incorrecte - nom de fitxer antic inconsistent en la línia %d"
+msgstr ""
+"git apply: git-diff incorrecte - nom de fitxer antic inconsistent en la "
+"línia %d"
 
 #: apply.c:954
 #, c-format
@@ -229,22 +234,23 @@ msgstr "fragment de pedaç sense capçalera a la línia %d: %.*s"
 #: apply.c:1562
 #, c-format
 msgid ""
-"git diff header lacks filename information when removing %d leading pathname component "
-"(line %d)"
+"git diff header lacks filename information when removing %d leading pathname "
+"component (line %d)"
 msgid_plural ""
-"git diff header lacks filename information when removing %d leading pathname components "
-"(line %d)"
+"git diff header lacks filename information when removing %d leading pathname "
+"components (line %d)"
 msgstr[0] ""
-"a la capçalera de git diff li manca informació de nom de fitxer en eliminar %d component "
-"de nom de camí inicial (línia %d)"
+"a la capçalera de git diff li manca informació de nom de fitxer en eliminar "
+"%d component de nom de camí inicial (línia %d)"
 msgstr[1] ""
-"a la capçalera de git diff li manca informació de nom de fitxer en eliminar %d "
-"components de nom de camí inicial (línia %d)"
+"a la capçalera de git diff li manca informació de nom de fitxer en eliminar "
+"%d components de nom de camí inicial (línia %d)"
 
 #: apply.c:1575
 #, c-format
 msgid "git diff header lacks filename information (line %d)"
-msgstr "a la capçalera de git diff li manca informació de nom de fitxer (línia %d)"
+msgstr ""
+"a la capçalera de git diff li manca informació de nom de fitxer (línia %d)"
 
 #: apply.c:1763
 msgid "new file depends on old contents"
@@ -338,12 +344,16 @@ msgstr "no es pot aplicar al revés un pedaç binari sense el tros revés a «%s
 #: apply.c:3149
 #, c-format
 msgid "cannot apply binary patch to '%s' without full index line"
-msgstr "no es pot aplicar un pedaç binari a «%s» sense la línia d'índex completa"
+msgstr ""
+"no es pot aplicar un pedaç binari a «%s» sense la línia d'índex completa"
 
 #: apply.c:3159
 #, c-format
-msgid "the patch applies to '%s' (%s), which does not match the current contents."
-msgstr "el pedaç s'aplica a «%s» (%s), el qual no coincideix amb els continguts actuals."
+msgid ""
+"the patch applies to '%s' (%s), which does not match the current contents."
+msgstr ""
+"el pedaç s'aplica a «%s» (%s), el qual no coincideix amb els continguts "
+"actuals."
 
 #: apply.c:3167
 #, c-format
@@ -363,7 +373,9 @@ msgstr "el pedaç binari no s'aplica a «%s»"
 #: apply.c:3204
 #, c-format
 msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)"
-msgstr "el pedaç binari a «%s» crea un resultat incorrecte (s'esperava %s, s'ha rebut %s)"
+msgstr ""
+"el pedaç binari a «%s» crea un resultat incorrecte (s'esperava %s, s'ha "
+"rebut %s)"
 
 #: apply.c:3225
 #, c-format
@@ -402,7 +414,8 @@ msgstr "%s: no coincideix amb l'índex"
 
 #: apply.c:3560
 msgid "repository lacks the necessary blob to fall back on 3-way merge."
-msgstr "al dipòsit li manca el blob necessari per a retrocedir a una fusió de 3 vies."
+msgstr ""
+"al dipòsit li manca el blob necessari per a retrocedir a una fusió de 3 vies."
 
 #: apply.c:3563
 #, c-format
@@ -491,7 +504,7 @@ msgstr "falta la informació sha1 o és inútil per al submòdul %s"
 #: apply.c:4087
 #, c-format
 msgid "mode change for %s, which is not in current HEAD"
-msgstr "canvi de mode per a %s, el qual no està en el HEAD actual"
+msgstr "canvi de mode per a %s, el qual no està en la HEAD actual"
 
 #: apply.c:4090
 #, c-format
@@ -531,7 +544,9 @@ msgstr "no s'ha pogut fer stat al fitxer novament creat «%s»"
 #: apply.c:4296
 #, c-format
 msgid "unable to create backing store for newly created file %s"
-msgstr "no s'ha pogut crear un magatzem de recolzament per al fitxer novament creat %s"
+msgstr ""
+"no s'ha pogut crear un magatzem de recolzament per al fitxer novament creat "
+"%s"
 
 #: apply.c:4302 apply.c:4446
 #, c-format
@@ -625,18 +640,21 @@ msgstr[1] "%d línies afegeixen errors d'espai en blanc."
 #, c-format
 msgid "%d line applied after fixing whitespace errors."
 msgid_plural "%d lines applied after fixing whitespace errors."
-msgstr[0] "S'ha aplicat %d línia després d'arreglar els errors d'espai en blanc."
-msgstr[1] "S'han aplicat %d línies després d'arreglar els errors d'espai en blanc."
+msgstr[0] ""
+"S'ha aplicat %d línia després d'arreglar els errors d'espai en blanc."
+msgstr[1] ""
+"S'han aplicat %d línies després d'arreglar els errors d'espai en blanc."
 
 #: apply.c:4894 builtin/add.c:539 builtin/mv.c:298 builtin/rm.c:390
 msgid "Unable to write new index file"
 msgstr "No s'ha pogut escriure un fitxer d'índex nou"
 
-#: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257 builtin/clone.c:118
-#: builtin/fetch.c:127 builtin/pull.c:193 builtin/submodule--helper.c:403
-#: builtin/submodule--helper.c:1197 builtin/submodule--helper.c:1200
-#: builtin/submodule--helper.c:1567 builtin/submodule--helper.c:1570
-#: builtin/submodule--helper.c:1787 git-add--interactive.perl:197
+#: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257
+#: builtin/clone.c:118 builtin/fetch.c:127 builtin/pull.c:193
+#: builtin/submodule--helper.c:403 builtin/submodule--helper.c:1197
+#: builtin/submodule--helper.c:1200 builtin/submodule--helper.c:1567
+#: builtin/submodule--helper.c:1570 builtin/submodule--helper.c:1787
+#: git-add--interactive.perl:197
 msgid "path"
 msgstr "camí"
 
@@ -654,7 +672,9 @@ msgstr "número"
 
 #: apply.c:4928
 msgid "remove <num> leading slashes from traditional diff paths"
-msgstr "elimina <nombre> barres obliqües inicials dels camins de diferència tradicionals"
+msgstr ""
+"elimina <nombre> barres obliqües inicials dels camins de diferència "
+"tradicionals"
 
 #: apply.c:4931
 msgid "ignore additions made by the patch"
@@ -662,7 +682,8 @@ msgstr "ignora afegiments fets pel pedaç"
 
 #: apply.c:4933
 msgid "instead of applying the patch, output diffstat for the input"
-msgstr "en lloc d'aplicar el pedaç, emet les estadístiques de diferència de l'entrada"
+msgstr ""
+"en lloc d'aplicar el pedaç, emet les estadístiques de diferència de l'entrada"
 
 #: apply.c:4937
 msgid "show number of added and deleted lines in decimal notation"
@@ -716,7 +737,8 @@ msgstr "acció"
 
 #: apply.c:4961
 msgid "detect new or modified lines that have whitespace errors"
-msgstr "detecta les línies noves o modificades que tinguin errors d'espai en blanc"
+msgstr ""
+"detecta les línies noves o modificades que tinguin errors d'espai en blanc"
 
 #: apply.c:4964 apply.c:4967
 msgid "ignore changes in whitespace when finding context"
@@ -738,9 +760,9 @@ msgstr "deixa els trossos rebutjats en fitxers *.rej corresponents"
 msgid "allow overlapping hunks"
 msgstr "permet trossos encavalcants"
 
-#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21 builtin/commit.c:1276
-#: builtin/count-objects.c:96 builtin/fsck.c:665 builtin/log.c:1901 builtin/mv.c:123
-#: builtin/read-tree.c:125
+#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21
+#: builtin/commit.c:1276 builtin/count-objects.c:96 builtin/fsck.c:665
+#: builtin/log.c:1901 builtin/mv.c:123 builtin/read-tree.c:125
 msgid "be verbose"
 msgstr "sigues detallat"
 
@@ -769,8 +791,11 @@ msgid "git archive --list"
 msgstr "git archive --list"
 
 #: archive.c:15
-msgid "git archive --remote <repo> [--exec <cmd>] [<options>] <tree-ish> [<path>...]"
-msgstr "git archive --remote <dipòsit> [--exec <ordre>] [<opcions>] <arbre> [<camí>...]"
+msgid ""
+"git archive --remote <repo> [--exec <cmd>] [<options>] <tree-ish> [<path>...]"
+msgstr ""
+"git archive --remote <dipòsit> [--exec <ordre>] [<opcions>] <arbre> "
+"[<camí>...]"
 
 #: archive.c:16
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
@@ -800,7 +825,8 @@ msgstr "anteposa el prefix a cada nom de camí en l'arxiu"
 #: archive.c:439 builtin/blame.c:702 builtin/blame.c:703 builtin/config.c:62
 #: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:869
 #: builtin/hash-object.c:103 builtin/ls-files.c:551 builtin/ls-files.c:554
-#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120 parse-options.h:165
+#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120
+#: parse-options.h:165
 msgid "file"
 msgstr "fitxer"
 
@@ -945,7 +971,8 @@ msgid ""
 "We continue anyway."
 msgstr ""
 "s'ha d'ometre la base de fusió entre %s i [%s].\n"
-"Llavors, no podem estar segurs que la primera comissió %s sigui entre %s i %s.\n"
+"Llavors, no podem estar segurs que la primera comissió %s sigui entre %s i "
+"%s.\n"
 "Continuem de totes maneres."
 
 #: bisect.c:810
@@ -1013,17 +1040,23 @@ msgstr "no es pot usar --contents amb el nom d'objecte de la comissió final"
 
 #: blame.c:1789
 msgid "--reverse and --first-parent together require specified latest commit"
-msgstr "--reverse i --first-parent-together requereixen una última comissió especificada"
+msgstr ""
+"--reverse i --first-parent-together requereixen una última comissió "
+"especificada"
 
-#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699 sequencer.c:2901
-#: builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920 builtin/log.c:1371
-#: builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370 builtin/shortlog.c:191
+#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699
+#: sequencer.c:2901 builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920
+#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370
+#: builtin/shortlog.c:191
 msgid "revision walk setup failed"
 msgstr "la configuració del passeig per revisions ha fallat"
 
 #: blame.c:1816
-msgid "--reverse --first-parent together require range along first-parent chain"
-msgstr "--reverse --first-parent junts requereixen un rang de la cadena de mares primeres"
+msgid ""
+"--reverse --first-parent together require range along first-parent chain"
+msgstr ""
+"--reverse --first-parent junts requereixen un rang de la cadena de mares "
+"primeres"
 
 #: blame.c:1827
 #, c-format
@@ -1057,17 +1090,21 @@ msgstr "No s'està establint la branca %s com a la seva pròpia font."
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s' by rebasing."
 msgstr ""
-"La branca «%s» està configurada per a seguir la branca remota «%s» de «%s» fent «rebase»."
+"La branca «%s» està configurada per a seguir la branca remota «%s» de «%s» "
+"fent «rebase»."
 
 #: branch.c:94
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s'."
-msgstr "La branca «%s» està configurada per a seguir la branca remota «%s» de «%s»."
+msgstr ""
+"La branca «%s» està configurada per a seguir la branca remota «%s» de «%s»."
 
 #: branch.c:98
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s' by rebasing."
-msgstr "La branca «%s» està configurada per a seguir la branca local «%s» fent «rebase»."
+msgstr ""
+"La branca «%s» està configurada per a seguir la branca local «%s» fent "
+"«rebase»."
 
 #: branch.c:99
 #, c-format
@@ -1078,18 +1115,21 @@ msgstr "La branca «%s» està configurada per a seguir la branca local «%s»."
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s' by rebasing."
 msgstr ""
-"La branca «%s» està configurada per a seguir la referència remota «%s» fent «rebase»."
+"La branca «%s» està configurada per a seguir la referència remota «%s» fent "
+"«rebase»."
 
 #: branch.c:105
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s'."
-msgstr "La branca «%s» està configurada per a seguir la referència remota «%s»."
+msgstr ""
+"La branca «%s» està configurada per a seguir la referència remota «%s»."
 
 #: branch.c:109
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s' by rebasing."
 msgstr ""
-"La branca «%s» està configurada per a seguir la referència local «%s» fent «rebase»."
+"La branca «%s» està configurada per a seguir la referència local «%s» fent "
+"«rebase»."
 
 #: branch.c:110
 #, c-format
@@ -1123,7 +1163,8 @@ msgstr "No es pot actualitzar la branca actual a la força."
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr ""
-"No es pot configurar la informació de seguiment; el punt inicial «%s» no és una branca."
+"No es pot configurar la informació de seguiment; el punt inicial «%s» no és "
+"una branca."
 
 #: branch.c:235
 #, c-format
@@ -1253,8 +1294,8 @@ msgstr "L'index-pack s'ha mort"
 msgid "invalid color value: %.*s"
 msgstr "valor de color no vàlid: %.*s"
 
-#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465 builtin/am.c:1436
-#: builtin/am.c:2072
+#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465
+#: builtin/am.c:1436 builtin/am.c:2072
 #, c-format
 msgid "could not parse %s"
 msgstr "no s'ha pogut analitzar %s"
@@ -1281,7 +1322,8 @@ msgstr "memòria esgotada"
 
 #: config.c:186
 msgid "relative config include conditionals must come from files"
-msgstr "els condicionals d'inclusió de configuració relatius han de venir de fitxers"
+msgstr ""
+"els condicionals d'inclusió de configuració relatius han de venir de fitxers"
 
 #: config.c:720
 #, c-format
@@ -1339,17 +1381,22 @@ msgstr "valor de configuració numèric «%s» erroni per «%s» en el fitxer %s
 #: config.c:885
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in standard input: %s"
-msgstr "valor de configuració numèric «%s» erroni per «%s» en l'entrada estàndard: %s"
+msgstr ""
+"valor de configuració numèric «%s» erroni per «%s» en l'entrada estàndard: %s"
 
 #: config.c:888
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
-msgstr "valor de configuració numèric «%s» erroni' per «%s» en el blob de submòdul %s: %s"
+msgstr ""
+"valor de configuració numèric «%s» erroni' per «%s» en el blob de submòdul "
+"%s: %s"
 
 #: config.c:891
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
-msgstr "valor de configuració numèric «%s» erroni per «%s» en la línia d'ordres %s: %s"
+msgstr ""
+"valor de configuració numèric «%s» erroni per «%s» en la línia d'ordres %s: "
+"%s"
 
 #: config.c:894
 #, c-format
@@ -1398,7 +1445,8 @@ msgstr "%s no vàlid: «%s»"
 #, c-format
 msgid "unknown core.untrackedCache value '%s'; using 'keep' default value"
 msgstr ""
-"valor «%s» a core.untrackedCache desconegut; utilitzant el valor per defecte «keep»"
+"valor «%s» a core.untrackedCache desconegut; utilitzant el valor per defecte "
+"«keep»"
 
 #: config.c:2170
 #, c-format
@@ -1479,8 +1527,8 @@ msgid ""
 "The file will have its original line endings in your working directory."
 msgstr ""
 "LF reemplaçarà CRLF en %s.\n"
-"El fitxer tindrà els seus terminadors de línia originals en el vostre directori de "
-"treball."
+"El fitxer tindrà els seus terminadors de línia originals en el vostre "
+"directori de treball."
 
 #: convert.c:215
 #, c-format
@@ -1494,8 +1542,8 @@ msgid ""
 "The file will have its original line endings in your working directory."
 msgstr ""
 "CRLF reemplaçarà LF en %s.\n"
-"El fitxer tindrà els seus terminadors de línia originals en el vostre directori de "
-"treball."
+"El fitxer tindrà els seus terminadors de línia originals en el vostre "
+"directori de treball."
 
 #: date.c:116
 msgid "in the future"
@@ -1582,7 +1630,9 @@ msgstr "l'opció «%s» requereix un valor"
 #: diff.c:152
 #, c-format
 msgid "  Failed to parse dirstat cut-off percentage '%s'\n"
-msgstr "  S'ha produït un error en analitzar el percentatge limitant de dirstat «%s»\n"
+msgstr ""
+"  S'ha produït un error en analitzar el percentatge limitant de dirstat "
+"«%s»\n"
 
 #: diff.c:157
 #, c-format
@@ -1591,15 +1641,17 @@ msgstr "  Paràmetre de dirstat desconegut «%s»\n"
 
 #: diff.c:281
 msgid ""
-"color moved setting must be one of 'no', 'default', 'zebra', 'dimmed_zebra', 'plain'"
+"color moved setting must be one of 'no', 'default', 'zebra', 'dimmed_zebra', "
+"'plain'"
 msgstr ""
-"el paràmetre de color en moviment ha de ser «no», «default», «zebra», «dimmed_zebra» o "
-"«plain»"
+"el paràmetre de color en moviment ha de ser «no», «default», «zebra», "
+"«dimmed_zebra» o «plain»"
 
 #: diff.c:341
 #, c-format
 msgid "Unknown value for 'diff.submodule' config variable: '%s'"
-msgstr "Valor desconegut de la variable de configuració de 'diff.submodule': «%s»"
+msgstr ""
+"Valor desconegut de la variable de configuració de 'diff.submodule': «%s»"
 
 #: diff.c:401
 #, c-format
@@ -1639,7 +1691,8 @@ msgstr ""
 #: diff.c:4417
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
-msgstr "S'ha produït un error en analitzar el paràmetre d'opció de --submodule: «%s»"
+msgstr ""
+"S'ha produït un error en analitzar el paràmetre d'opció de --submodule: «%s»"
 
 #: diff.c:5493
 msgid "inexact rename detection was skipped due to too many files."
@@ -1647,13 +1700,16 @@ msgstr "s'ha omès la detecció de canvi de nom a causa de massa fitxers."
 
 #: diff.c:5496
 msgid "only found copies from modified paths due to too many files."
-msgstr "només s'han trobat còpies des de camins modificats a causa de massa fitxers."
+msgstr ""
+"només s'han trobat còpies des de camins modificats a causa de massa fitxers."
 
 #: diff.c:5499
 #, c-format
-msgid "you may want to set your %s variable to at least %d and retry the command."
+msgid ""
+"you may want to set your %s variable to at least %d and retry the command."
 msgstr ""
-"potser voleu establir la vostra variable %s a almenys %d i tornar a intentar l'ordre."
+"potser voleu establir la vostra variable %s a almenys %d i tornar a intentar "
+"l'ordre."
 
 #: dir.c:1866
 #, c-format
@@ -1666,7 +1722,8 @@ msgstr "s'ha produït un error en obtenir el nombre i la informació del nucli"
 
 #: dir.c:2232
 msgid "Untracked cache is disabled on this system or location."
-msgstr "La memòria cau no seguida està inhabilitada en aquest sistema o ubicació."
+msgstr ""
+"La memòria cau no seguida està inhabilitada en aquest sistema o ubicació."
 
 #: dir.c:3024 dir.c:3029
 #, c-format
@@ -1905,7 +1962,8 @@ msgstr "ignora el color no vàlid «%.*s» en log.graphColors"
 msgid "'%s': unable to read %s"
 msgstr "«%s»: no s'ha pogut llegir %s"
 
-#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81 builtin/rm.c:134
+#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81
+#: builtin/rm.c:134
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "s'ha produït un error en fer stat a «%s»"
@@ -1926,7 +1984,8 @@ msgstr "ordres de git disponibles d'altres llocs en el vostre $PATH"
 
 #: help.c:217
 msgid "These are common Git commands used in various situations:"
-msgstr "Aquestes són ordres del Git habitualment usades en diverses situacions:"
+msgstr ""
+"Aquestes són ordres del Git habitualment usades en diverses situacions:"
 
 #: help.c:281
 #, c-format
@@ -1944,7 +2003,8 @@ msgstr "Ai. El vostre sistema no informa de cap ordre de Git."
 #: help.c:358
 #, c-format
 msgid "WARNING: You called a Git command named '%s', which does not exist."
-msgstr "ADVERTÈNCIA: Heu invocat una ordre de Git amb nom «%s», la qual no existeix."
+msgstr ""
+"ADVERTÈNCIA: Heu invocat una ordre de Git amb nom «%s», la qual no existeix."
 
 #: help.c:363
 #, c-format
@@ -1954,7 +2014,8 @@ msgstr "El procés continuarà, pressuposant que volíeu dir «%s»."
 #: help.c:368
 #, c-format
 msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
-msgstr "El procés continuarà en %0.1f segons, pressuposant que volíeu dir «%s»."
+msgstr ""
+"El procés continuarà en %0.1f segons, pressuposant que volíeu dir «%s»."
 
 #: help.c:376
 #, c-format
@@ -2026,17 +2087,20 @@ msgstr ""
 #: ident.c:366
 msgid "no email was given and auto-detection is disabled"
 msgstr ""
-"no s'ha proporcionat cap adreça electrònica i la detecció automàtica està inhabilitada"
+"no s'ha proporcionat cap adreça electrònica i la detecció automàtica està "
+"inhabilitada"
 
 #: ident.c:371
 #, c-format
 msgid "unable to auto-detect email address (got '%s')"
 msgstr ""
-"no s'ha pogut detectar automàticament una adreça electrònica vàlida (s'ha rebut «%s»)"
+"no s'ha pogut detectar automàticament una adreça electrònica vàlida (s'ha "
+"rebut «%s»)"
 
 #: ident.c:381
 msgid "no name was given and auto-detection is disabled"
-msgstr "no s'ha proporcionat cap nom i la detecció automàtica està inhabilitada"
+msgstr ""
+"no s'ha proporcionat cap nom i la detecció automàtica està inhabilitada"
 
 #: ident.c:387
 #, c-format
@@ -2168,35 +2232,39 @@ msgstr "No s'ha pogut afegir %s a la base de dades"
 
 #: merge-recursive.c:1146
 #, c-format
-msgid "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left in tree."
+msgid ""
+"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
+"in tree."
 msgstr ""
-"CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de %s s'ha deixat "
-"en l'arbre."
+"CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de %s "
+"s'ha deixat en l'arbre."
 
 #: merge-recursive.c:1151
 #, c-format
 msgid ""
-"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s left in tree."
+"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
+"left in tree."
 msgstr ""
-"CONFLICTE: (%s/supressió): %s suprimit en %s i %s a %s en %s. La versió %s de %s s'ha "
-"deixat en l'arbre."
+"CONFLICTE: (%s/supressió): %s suprimit en %s i %s a %s en %s. La versió %s "
+"de %s s'ha deixat en l'arbre."
 
 #: merge-recursive.c:1158
 #, c-format
 msgid ""
-"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left in tree at %s."
+"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
+"in tree at %s."
 msgstr ""
-"CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de %s s'ha deixat "
-"en l'arbre a %s."
+"CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de %s "
+"s'ha deixat en l'arbre a %s."
 
 #: merge-recursive.c:1163
 #, c-format
 msgid ""
-"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s left in tree "
-"at %s."
+"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
+"left in tree at %s."
 msgstr ""
-"CONFLICTE: (%s/supressió): %s suprimit en %s i %s a %s en %s. La versió %s de %s s'ha "
-"deixat en l'arbre a %s."
+"CONFLICTE: (%s/supressió): %s suprimit en %s i %s a %s en %s. La versió %s "
+"de %s s'ha deixat en l'arbre a %s."
 
 #: merge-recursive.c:1197
 msgid "rename"
@@ -2214,11 +2282,11 @@ msgstr "%s és un directori en %s; s'està afegint com a %s en lloc d'això"
 #: merge-recursive.c:1279
 #, 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 ""
-"CONFLICTE (canvi de nom/canvi de nom): Canvi de nom \"%s\"->\"%s\" en la branca \"%s\" "
-"canvi de nom \"%s\"->\"%s\" en \"%s\"%s"
+"CONFLICTE (canvi de nom/canvi de nom): Canvi de nom \"%s\"->\"%s\" en la "
+"branca \"%s\" canvi de nom \"%s\"->\"%s\" en \"%s\"%s"
 
 #: merge-recursive.c:1284
 msgid " (left unresolved)"
@@ -2228,8 +2296,8 @@ msgstr " (deixat sense resolució)"
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
-"CONFLICTE (canvi de nom/canvi de nom): Canvi de nom %s->%s en %s. Canvi de nom %s->%s en "
-"%s"
+"CONFLICTE (canvi de nom/canvi de nom): Canvi de nom %s->%s en %s. Canvi de "
+"nom %s->%s en %s"
 
 #: merge-recursive.c:1379
 #, c-format
@@ -2239,7 +2307,9 @@ msgstr "S'està canviant el nom de %s a %s i %s a %s en lloc d'això"
 #: merge-recursive.c:1582
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
-msgstr "CONFLICTE (canvi de nom/afegiment): Canvi de nom %s->%s en %s. %s afegit en %s"
+msgstr ""
+"CONFLICTE (canvi de nom/afegiment): Canvi de nom %s->%s en %s. %s afegit en "
+"%s"
 
 #: merge-recursive.c:1597
 #, c-format
@@ -2312,7 +2382,9 @@ msgstr "directori/fitxer"
 #: merge-recursive.c:1938
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
-msgstr "CONFLICTE (%s): Hi ha un directori amb nom %s en %s. S'està afegint %s com a %s"
+msgstr ""
+"CONFLICTE (%s): Hi ha un directori amb nom %s en %s. S'està afegint %s com a "
+"%s"
 
 #: merge-recursive.c:1947
 #, c-format
@@ -2361,12 +2433,12 @@ msgstr "No s'ha pogut escriure l'índex."
 #, c-format
 msgid ""
 "You have not concluded your previous notes merge (%s exists).\n"
-"Please, use 'git notes merge --commit' or 'git notes merge --abort' to commit/abort the "
-"previous merge before you start a new notes merge."
+"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 ""
 "No heu acabat la vostra fusió de notes prèvia (%s existeix).\n"
-"Useu «git notes merge --commit» o «git notes merge --abort» per a cometre/avortar la "
-"fusió prèvia abans de començar una fusió de notes nova."
+"Useu «git notes merge --commit» o «git notes merge --abort» per a cometre/"
+"avortar la fusió prèvia abans de començar una fusió de notes nova."
 
 #: notes-merge.c:279
 #, c-format
@@ -2408,12 +2480,14 @@ msgstr "desplaçament abans de la fi del fitxer de paquet (.idx trencat?)"
 #: packfile.c:1694
 #, c-format
 msgid "offset before start of pack index for %s (corrupt index?)"
-msgstr "desplaçament abans d'inici d'índex de paquet per a %s (índex corromput?)"
+msgstr ""
+"desplaçament abans d'inici d'índex de paquet per a %s (índex corromput?)"
 
 #: packfile.c:1698
 #, c-format
 msgid "offset beyond end of pack index for %s (truncated index?)"
-msgstr "desplaçament més enllà de la fi d'índex de paquet per a %s (índex truncat?)"
+msgstr ""
+"desplaçament més enllà de la fi d'índex de paquet per a %s (índex truncat?)"
 
 #: parse-options.c:619
 msgid "..."
@@ -2454,8 +2528,8 @@ msgstr "No s'ha pogut fer %s escrivible pel grup"
 #: pathspec.c:129
 msgid "Escape character '\\' not allowed as last character in attr value"
 msgstr ""
-"El caràcter d'escapament '\\' no està permès com a últim caràcter en un valor d'un "
-"atribut"
+"El caràcter d'escapament '\\' no està permès com a últim caràcter en un "
+"valor d'un atribut"
 
 #: pathspec.c:147
 msgid "Only one 'attr:' specification is allowed."
@@ -2472,14 +2546,17 @@ msgstr "nom d'atribut no vàlid %s"
 
 #: pathspec.c:258
 msgid "global 'glob' and 'noglob' pathspec settings are incompatible"
-msgstr "els paràmetres d'especificació de camí 'glob' i 'noglob' globals són incompatibles"
+msgstr ""
+"els paràmetres d'especificació de camí 'glob' i 'noglob' globals són "
+"incompatibles"
 
 #: pathspec.c:265
 msgid ""
-"global 'literal' pathspec setting is incompatible with all other global pathspec settings"
+"global 'literal' pathspec setting is incompatible with all other global "
+"pathspec settings"
 msgstr ""
-"el paràmetre d'especificació de camí 'literal' global és incompatible amb tots els "
-"altres paràmetres d'especificació de camí globals"
+"el paràmetre d'especificació de camí 'literal' global és incompatible amb "
+"tots els altres paràmetres d'especificació de camí globals"
 
 #: pathspec.c:305
 msgid "invalid parameter for pathspec magic 'prefix'"
@@ -2518,7 +2595,8 @@ msgstr "«%s» (mnemònic: '%c')"
 #: pathspec.c:525
 #, c-format
 msgid "%s: pathspec magic not supported by this command: %s"
-msgstr "%s: aquesta ordre no està admesa amb la màgia d'especificació de camí: %s"
+msgstr ""
+"%s: aquesta ordre no està admesa amb la màgia d'especificació de camí: %s"
 
 #: pathspec.c:592
 #, c-format
@@ -2581,7 +2659,8 @@ msgstr "no està permès actualitzar les referències en un entorn de quarantena
 msgid "could not remove reference %s"
 msgstr "no s'ha pogut eliminar la referència %s"
 
-#: refs/files-backend.c:1203 refs/packed-backend.c:1528 refs/packed-backend.c:1538
+#: refs/files-backend.c:1203 refs/packed-backend.c:1528
+#: refs/packed-backend.c:1538
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "no s'ha pogut suprimir la referència %s: %s"
@@ -2861,7 +2940,8 @@ msgstr "la branca font «%s» no s'emmagatzema com a branca amb seguiment remot"
 #: remote.c:1759
 #, c-format
 msgid "push destination '%s' on remote '%s' has no local tracking branch"
-msgstr "el destí de pujada «%s» en el remot «%s» no té cap branca amb seguiment remot"
+msgstr ""
+"el destí de pujada «%s» en el remot «%s» no té cap branca amb seguiment remot"
 
 #: remote.c:1771
 #, c-format
@@ -2919,11 +2999,14 @@ msgstr "  (useu \"git push\" per a publicar les vostres comissions locals)\n"
 #: remote.c:2159
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
-msgid_plural "Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n"
+msgid_plural ""
+"Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n"
 msgstr[0] ""
-"La vostra branca està darrere de «%s» per %d comissió, i pot avançar-se ràpidament.\n"
+"La vostra branca està darrere de «%s» per %d comissió, i pot avançar-se "
+"ràpidament.\n"
 msgstr[1] ""
-"La vostra branca està darrere de «%s» per %d comissions, i pot avançar-se ràpidament.\n"
+"La vostra branca està darrere de «%s» per %d comissions, i pot avançar-se "
+"ràpidament.\n"
 
 #: remote.c:2167
 msgid "  (use \"git pull\" to update your local branch)\n"
@@ -2974,7 +3057,9 @@ msgstr ""
 
 #: send-pack.c:141
 msgid "unexpected flush packet while reading remote unpack status"
-msgstr "paquet de neteja no esperat quan estava llegint l'estat del desempaquetament remot"
+msgstr ""
+"paquet de neteja no esperat quan estava llegint l'estat del desempaquetament "
+"remot"
 
 #: send-pack.c:143
 #, c-format
@@ -2996,10 +3081,11 @@ msgstr "el destí receptor no admet pujar --signed"
 
 #: send-pack.c:423
 msgid ""
-"not sending a push certificate since the receiving end does not support --signed push"
+"not sending a push certificate since the receiving end does not support --"
+"signed push"
 msgstr ""
-"no s'està enviant una certificació de pujada perquè el destí receptor no admet pujar --"
-"signed"
+"no s'està enviant una certificació de pujada perquè el destí receptor no "
+"admet pujar --signed"
 
 #: send-pack.c:435
 msgid "the receiving end does not support --atomic push"
@@ -3054,8 +3140,8 @@ msgstr ""
 msgid "could not lock '%s'"
 msgstr "no s'ha pogut bloquejar «%s»"
 
-#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264 sequencer.c:3246
-#: sequencer.c:3310 wrapper.c:656
+#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264
+#: sequencer.c:3246 sequencer.c:3310 wrapper.c:656
 #, c-format
 msgid "could not write to '%s'"
 msgstr "no s'ha pogut escriure a «%s»"
@@ -3070,8 +3156,8 @@ msgstr "no s'ha pogut escriure el terminador de línia a «%s»"
 msgid "failed to finalize '%s'"
 msgstr "s'ha produït un error en finalitzar «%s»"
 
-#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259 builtin/commit.c:722
-#: builtin/merge.c:1047
+#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259
+#: builtin/commit.c:722 builtin/merge.c:1047
 #, c-format
 msgid "could not read '%s'"
 msgstr "no s'ha pogut llegir «%s»"
@@ -3123,7 +3209,8 @@ msgid ""
 "  git rebase --continue\n"
 msgstr ""
 "teniu canvis «staged» en el vostre arbre de treball\n"
-"Si aquests canvis estan pensats per fer «squash» a la comissió prèvia, executeu:\n"
+"Si aquests canvis estan pensats per fer «squash» a la comissió prèvia, "
+"executeu:\n"
 "\n"
 "  git commit --amend %s\n"
 "\n"
@@ -3338,7 +3425,8 @@ msgstr "la comissió %s no té pare %d"
 #: sequencer.c:1510
 #, c-format
 msgid "mainline was specified but commit %s is not a merge."
-msgstr "s'ha especificat la línia principal però la comissió %s no és una fusió."
+msgstr ""
+"s'ha especificat la línia principal però la comissió %s no és una fusió."
 
 #: sequencer.c:1516
 #, c-format
@@ -3656,8 +3744,11 @@ msgstr "llista per a fer inestable: «%s»"
 
 #: sequencer.c:3146
 #, c-format
-msgid "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
-msgstr "No s'ha reconegut el paràmetre %s per rebase.missingCommitsCheck. S'està ignorant."
+msgid ""
+"unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
+msgstr ""
+"No s'ha reconegut el paràmetre %s per rebase.missingCommitsCheck. S'està "
+"ignorant."
 
 #: sequencer.c:3212
 #, c-format
@@ -3665,7 +3756,8 @@ msgid ""
 "Warning: some commits may have been dropped accidentally.\n"
 "Dropped commits (newer to older):\n"
 msgstr ""
-"Advertència: pot ser que algunes comissions s'hagin descartat accidentalment.\n"
+"Advertència: pot ser que algunes comissions s'hagin descartat "
+"accidentalment.\n"
 "Les comissions descartades (més nova a més vella):\n"
 
 #: sequencer.c:3219
@@ -3673,24 +3765,30 @@ msgstr ""
 msgid ""
 "To avoid this message, use \"drop\" to explicitly remove a commit.\n"
 "\n"
-"Use 'git config rebase.missingCommitsCheck' to change the level of warnings.\n"
+"Use 'git config rebase.missingCommitsCheck' to change the level of "
+"warnings.\n"
 "The possible behaviours are: ignore, warn, error.\n"
 "\n"
 msgstr ""
-"Per a evitar aquest missatge, useu \"drop\" per a eliminar explícitament una comissió.\n"
+"Per a evitar aquest missatge, useu \"drop\" per a eliminar explícitament una "
+"comissió.\n"
 "\n"
-"Useu 'git config rebase.missingCommitsCheck' per a canviar el nivell d'advertències.\n"
+"Useu 'git config rebase.missingCommitsCheck' per a canviar el nivell "
+"d'advertències.\n"
 "Els comportaments possibles són: ignore, warn, error.\n"
 
 #: sequencer.c:3231
 #, c-format
 msgid ""
-"You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'.\n"
+"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 ""
-"Podeu arreglar això amb 'git rebase --edit-todo' i després 'git rebase --continue'.\n"
+"Podeu arreglar això amb 'git rebase --edit-todo' i després 'git rebase --"
+"continue'.\n"
 
-#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395 builtin/am.c:779
+#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395
+#: builtin/am.c:779
 #, c-format
 msgid "could not open '%s' for writing"
 msgstr "no s'ha pogut obrir «%s» per a escriptura"
@@ -3716,7 +3814,8 @@ msgid ""
 "Use 'git <command> -- <path>...' to specify paths that do not exist locally."
 msgstr ""
 "%s: no hi ha tal camí en l'arbre de treball.\n"
-"Useu 'git <ordre> -- <camí>...' per a especificar camins que no existeixin localment."
+"Useu 'git <ordre> -- <camí>...' per a especificar camins que no existeixin "
+"localment."
 
 #: setup.c:184
 #, c-format
@@ -3747,7 +3846,8 @@ msgstr ""
 
 #: setup.c:388
 msgid "unable to set up work tree using invalid config"
-msgstr "no s'ha configurar un arbre de treball utilitzant una configuració no vàlida"
+msgstr ""
+"no s'ha configurar un arbre de treball utilitzant una configuració no vàlida"
 
 #: setup.c:395
 msgid "this operation must be run in a work tree"
@@ -3837,8 +3937,8 @@ msgid ""
 "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."
 msgstr ""
 "no un dipòsit de git (ni 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)."
+"S'atura a la frontera de sistema de fitxers (GIT_DISCOVERY_ACROSS_FILESYSTEM "
+"no està establert)."
 
 #: setup.c:1172
 #, c-format
@@ -3846,8 +3946,10 @@ msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
 "The owner of files must always have read and write permissions."
 msgstr ""
-"hi ha un problema amb el valor de mode de fitxer core.sharedRepository (0%.3o).\n"
-"El propietari dels fitxers sempre ha de tenir permisos de lectura i escriptura."
+"hi ha un problema amb el valor de mode de fitxer core.sharedRepository "
+"(0%.3o).\n"
+"El propietari dels fitxers sempre ha de tenir permisos de lectura i "
+"escriptura."
 
 #: setup.c:1215
 msgid "open /dev/null or dup failed"
@@ -3869,7 +3971,8 @@ msgstr "el camí «%s» no existeix"
 #: sha1_file.c:618
 #, c-format
 msgid "reference repository '%s' as a linked checkout is not supported yet."
-msgstr "Encara no se suporta el dipòsit de referència «%s» com a agafament enllaçat."
+msgstr ""
+"Encara no se suporta el dipòsit de referència «%s» com a agafament enllaçat."
 
 #: sha1_file.c:624
 #, c-format
@@ -3922,7 +4025,8 @@ msgstr ""
 #: submodule.c:96 submodule.c:130
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr ""
-"No es pot canviar un .gitmodules no fusionat, primer resoleu els conflictes de fusió"
+"No es pot canviar un .gitmodules no fusionat, primer resoleu els conflictes "
+"de fusió"
 
 #: submodule.c:100 submodule.c:134
 #, c-format
@@ -3984,15 +4088,19 @@ msgstr "el submòdul «%s» té l'índex brut"
 
 #: submodule.c:1878
 #, c-format
-msgid "relocate_gitdir for submodule '%s' with more than one worktree not supported"
-msgstr "no està admès relocate_gitdir per al submòdul «%s» amb més d'un arbre de treball"
+msgid ""
+"relocate_gitdir for submodule '%s' with more than one worktree not supported"
+msgstr ""
+"no està admès relocate_gitdir per al submòdul «%s» amb més d'un arbre de "
+"treball"
 
 #: submodule.c:1890 submodule.c:1946
 #, c-format
 msgid "could not lookup name for submodule '%s'"
 msgstr "no s'ha trobat el nom pel submòdul «%s»"
 
-#: submodule.c:1894 builtin/submodule--helper.c:1246 builtin/submodule--helper.c:1256
+#: submodule.c:1894 builtin/submodule--helper.c:1246
+#: builtin/submodule--helper.c:1256
 #, c-format
 msgid "could not create directory '%s'"
 msgstr "no s'ha pogut crear el directori «%s»"
@@ -4040,7 +4148,8 @@ msgstr "valor no vàlid per a %s"
 msgid "running trailer command '%s' failed"
 msgstr "l'execució de l'ordre de remolc «%s» ha fallat"
 
-#: trailer.c:485 trailer.c:490 trailer.c:495 trailer.c:549 trailer.c:553 trailer.c:557
+#: trailer.c:485 trailer.c:490 trailer.c:495 trailer.c:549 trailer.c:553
+#: trailer.c:557
 #, c-format
 msgid "unknown value '%s' for key '%s'"
 msgstr "valor desconegut «%s» per a la clau «%s»"
@@ -4164,7 +4273,8 @@ msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
 "%%sPlease commit your changes or stash them before you switch branches."
 msgstr ""
-"Els vostres canvis locals als fitxers següents se sobreescriurien per agafar:\n"
+"Els vostres canvis locals als fitxers següents se sobreescriurien per "
+"agafar:\n"
 "%%sCometeu els vostres canvis o feu «stash» abans de canviar de branca."
 
 #: unpack-trees.c:110
@@ -4173,7 +4283,8 @@ msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
 "%%s"
 msgstr ""
-"Els vostres canvis locals als fitxers següents se sobreescriurien per agafar:\n"
+"Els vostres canvis locals als fitxers següents se sobreescriurien per "
+"agafar:\n"
 "%%s"
 
 #: unpack-trees.c:113
@@ -4182,7 +4293,8 @@ msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
 "%%sPlease commit your changes or stash them before you merge."
 msgstr ""
-"Els vostres canvis locals als fitxers següents se sobreescriurien per fusionar:\n"
+"Els vostres canvis locals als fitxers següents se sobreescriurien per "
+"fusionar:\n"
 "%%sCometeu els vostres canvis o feu «stash» abans de fusionar."
 
 #: unpack-trees.c:115
@@ -4191,7 +4303,8 @@ msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
 "%%s"
 msgstr ""
-"Els vostres canvis locals als fitxers següents se sobreescriurien per fusionar:\n"
+"Els vostres canvis locals als fitxers següents se sobreescriurien per "
+"fusionar:\n"
 "%%s"
 
 #: unpack-trees.c:118
@@ -4227,7 +4340,8 @@ msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
 "%%sPlease move or remove them before you switch branches."
 msgstr ""
-"Els següents fitxers no seguits en l'arbre de treball s'eliminarien per agafar:\n"
+"Els següents fitxers no seguits en l'arbre de treball s'eliminarien per "
+"agafar:\n"
 "%%sMoveu-los o elimineu-los abans de canviar de branca."
 
 #: unpack-trees.c:131
@@ -4236,7 +4350,8 @@ msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
 "%%s"
 msgstr ""
-"Els següents fitxers no seguits en l'arbre de treball s'eliminarien per agafar:\n"
+"Els següents fitxers no seguits en l'arbre de treball s'eliminarien per "
+"agafar:\n"
 "%%s"
 
 #: unpack-trees.c:134
@@ -4245,7 +4360,8 @@ msgid ""
 "The following untracked working tree files would be removed by merge:\n"
 "%%sPlease move or remove them before you merge."
 msgstr ""
-"Els següents fitxers no seguits en l'arbre de treball s'eliminarien per fusionar:\n"
+"Els següents fitxers no seguits en l'arbre de treball s'eliminarien per "
+"fusionar:\n"
 "%%sMoveu-los o elimineu-los abans de fusionar."
 
 #: unpack-trees.c:136
@@ -4254,7 +4370,8 @@ msgid ""
 "The following untracked working tree files would be removed by merge:\n"
 "%%s"
 msgstr ""
-"Els següents fitxers no seguits en l'arbre de treball s'eliminarien per fusionar:\n"
+"Els següents fitxers no seguits en l'arbre de treball s'eliminarien per "
+"fusionar:\n"
 "%%s"
 
 #: unpack-trees.c:139
@@ -4278,19 +4395,23 @@ msgstr ""
 #: unpack-trees.c:146
 #, c-format
 msgid ""
-"The following untracked working tree files would be overwritten by checkout:\n"
+"The following untracked working tree files would be overwritten by "
+"checkout:\n"
 "%%sPlease move or remove them before you switch branches."
 msgstr ""
-"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per agafar:\n"
+"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per "
+"agafar:\n"
 "%%sMoveu-los o elimineu-los abans de canviar de branca."
 
 #: unpack-trees.c:148
 #, c-format
 msgid ""
-"The following untracked working tree files would be overwritten by checkout:\n"
+"The following untracked working tree files would be overwritten by "
+"checkout:\n"
 "%%s"
 msgstr ""
-"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per agafar:\n"
+"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per "
+"agafar:\n"
 "%%s"
 
 #: unpack-trees.c:151
@@ -4299,7 +4420,8 @@ msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
 "%%sPlease move or remove them before you merge."
 msgstr ""
-"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per fusionar:\n"
+"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per "
+"fusionar:\n"
 "%%sMoveu-los o elimineu-los abans de fusionar."
 
 #: unpack-trees.c:153
@@ -4308,7 +4430,8 @@ msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
 "%%s"
 msgstr ""
-"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per fusionar:\n"
+"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per "
+"fusionar:\n"
 "%%s"
 
 #: unpack-trees.c:156
@@ -4317,7 +4440,8 @@ msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
 "%%sPlease move or remove them before you %s."
 msgstr ""
-"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per %s:\n"
+"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per "
+"%s:\n"
 "%%sMoveu-los o elimineu-los abans de %s."
 
 #: unpack-trees.c:158
@@ -4326,7 +4450,8 @@ msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
 "%%s"
 msgstr ""
-"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per %s:\n"
+"Els següents fitxers no seguits en l'arbre de treball se sobreescriurien per "
+"%s:\n"
 "%%s"
 
 #: unpack-trees.c:165
@@ -4340,27 +4465,30 @@ msgid ""
 "Cannot update sparse checkout: the following entries are not up to date:\n"
 "%s"
 msgstr ""
-"No es pot actualitzar l'agafament parcial: les entrades següents no estan al dia:\n"
+"No es pot actualitzar l'agafament parcial: les entrades següents no estan al "
+"dia:\n"
 "%s"
 
 #: unpack-trees.c:170
 #, c-format
 msgid ""
-"The following working tree files would be overwritten by sparse checkout update:\n"
+"The following working tree files would be overwritten by sparse checkout "
+"update:\n"
 "%s"
 msgstr ""
-"Els fitxers següents en l'arbre de treball se sobreescriurien per actualitzar "
-"l'agafament parcial:\n"
+"Els fitxers següents en l'arbre de treball se sobreescriurien per "
+"actualitzar l'agafament parcial:\n"
 "%s"
 
 #: unpack-trees.c:172
 #, c-format
 msgid ""
-"The following working tree files would be removed by sparse checkout update:\n"
+"The following working tree files would be removed by sparse checkout "
+"update:\n"
 "%s"
 msgstr ""
-"Els fitxers següents en l'arbre de treball s'eliminarien per actualitzar l'agafament "
-"parcial:\n"
+"Els fitxers següents en l'arbre de treball s'eliminarien per actualitzar "
+"l'agafament parcial:\n"
 "%s"
 
 #: unpack-trees.c:174
@@ -4445,8 +4573,8 @@ msgstr "«%s» no assenyala de tornada a «%s»"
 msgid "could not open '%s' for reading and writing"
 msgstr "no s'ha pogut obrir «%s» per a lectura i escriptura"
 
-#: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770 builtin/am.c:862
-#: builtin/merge.c:1044
+#: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770
+#: builtin/am.c:862 builtin/merge.c:1044
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "no s'ha pogut obrir «%s» per a lectura"
@@ -4479,7 +4607,9 @@ msgstr "  (useu \"git add <fitxer>...\" per a senyalar resolució)"
 
 #: wt-status.c:186 wt-status.c:190
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
-msgstr "  (useu \"git add/rm <fitxer>...\" segons sigui apropiat per a senyalar resolució)"
+msgstr ""
+"  (useu \"git add/rm <fitxer>...\" segons sigui apropiat per a senyalar "
+"resolució)"
 
 #: wt-status.c:188
 msgid "  (use \"git rm <file>...\" to mark resolution)"
@@ -4502,19 +4632,22 @@ msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr "  (useu \"git add/rm <fitxer>...\" per a actualitzar què es cometrà)"
 
 #: wt-status.c:224
-msgid "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
+msgid ""
+"  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
-"  (useu \"git checkout -- <fitxer>...\" per a descartar els canvis en el directori de "
-"treball)"
+"  (useu \"git checkout -- <fitxer>...\" per a descartar els canvis en el "
+"directori de treball)"
 
 #: wt-status.c:226
 msgid "  (commit or discard the untracked or modified content in submodules)"
-msgstr "  (cometeu o descarteu el contingut modificat o no seguit en els submòduls)"
+msgstr ""
+"  (cometeu o descarteu el contingut modificat o no seguit en els submòduls)"
 
 #: wt-status.c:238
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
-msgstr "  (useu \"git %s <fitxer>...\" per a incloure-ho en el qual es cometrà)"
+msgstr ""
+"  (useu \"git %s <fitxer>...\" per a incloure-ho en el qual es cometrà)"
 
 #: wt-status.c:253
 msgid "both deleted:"
@@ -4697,7 +4830,8 @@ msgstr "Actualment esteu fent «rebase»."
 
 #: wt-status.c:1306
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
-msgstr "  (arregleu els conflictes i després executeu \"git rebase --continue\")"
+msgstr ""
+"  (arregleu els conflictes i després executeu \"git rebase --continue\")"
 
 #: wt-status.c:1308
 msgid "  (use \"git rebase --skip\" to skip this patch)"
@@ -4709,13 +4843,16 @@ msgstr "  (useu \"git rebase --abort\" per a agafar la branca original)"
 
 #: wt-status.c:1316
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
-msgstr "  (tots els conflictes estan arreglats: executeu \"git rebase --continue\")"
+msgstr ""
+"  (tots els conflictes estan arreglats: executeu \"git rebase --continue\")"
 
 #: wt-status.c:1320
 #, c-format
-msgid "You are currently splitting a commit while rebasing branch '%s' on '%s'."
+msgid ""
+"You are currently splitting a commit while rebasing branch '%s' on '%s'."
 msgstr ""
-"Actualment esteu dividint una comissió mentre es fa «rebase» de la branca «%s» en «%s»."
+"Actualment esteu dividint una comissió mentre es fa «rebase» de la branca "
+"«%s» en «%s»."
 
 #: wt-status.c:1325
 msgid "You are currently splitting a commit during a rebase."
@@ -4724,14 +4861,15 @@ msgstr "Actualment esteu dividint una comissió durant un «rebase»."
 #: wt-status.c:1328
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr ""
-"  (Una vegada que el vostre directori de treball sigui net, executeu \"git rebase --"
-"continue\")"
+"  (Una vegada que el vostre directori de treball sigui net, executeu \"git "
+"rebase --continue\")"
 
 #: wt-status.c:1332
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
-"Actualment esteu editant una comissió mentre es fa «rebase» de la branca «%s» en «%s»."
+"Actualment esteu editant una comissió mentre es fa «rebase» de la branca "
+"«%s» en «%s»."
 
 #: wt-status.c:1337
 msgid "You are currently editing a commit during a rebase."
@@ -4742,10 +4880,11 @@ msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr "  (useu \"git commit --amend\" per a esmenar la comissió actual)"
 
 #: wt-status.c:1342
-msgid "  (use \"git rebase --continue\" once you are satisfied with your changes)"
+msgid ""
+"  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
-"  (useu \"git rebase --continue\" una vegada que estigueu satisfet amb els vostres "
-"canvis)"
+"  (useu \"git rebase --continue\" una vegada que estigueu satisfet amb els "
+"vostres canvis)"
 
 #: wt-status.c:1352
 #, c-format
@@ -4758,11 +4897,15 @@ msgstr "  (arregleu els conflictes i executeu \"git cherry-pick --continue\")"
 
 #: wt-status.c:1360
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
-msgstr "  (tots els conflictes estan arreglats: executeu \"git cherry-pick --continue\")"
+msgstr ""
+"  (tots els conflictes estan arreglats: executeu \"git cherry-pick --continue"
+"\")"
 
 #: wt-status.c:1362
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
-msgstr "  (useu \"git cherry-pick --abort\" per a cancel·lar l'operació de «cherry pick»)"
+msgstr ""
+"  (useu \"git cherry-pick --abort\" per a cancel·lar l'operació de «cherry "
+"pick»)"
 
 #: wt-status.c:1371
 #, c-format
@@ -4775,11 +4918,13 @@ msgstr "  (arregleu els conflictes i executeu \"git revert --continue\")"
 
 #: wt-status.c:1379
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
-msgstr "  (tots els conflictes estan arreglats: executeu \"git revert --continue\")"
+msgstr ""
+"  (tots els conflictes estan arreglats: executeu \"git revert --continue\")"
 
 #: wt-status.c:1381
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
-msgstr "  (useu \"git revert --abort\" per a cancel·lar l'operació de reversió)"
+msgstr ""
+"  (useu \"git revert --abort\" per a cancel·lar l'operació de reversió)"
 
 #: wt-status.c:1392
 #, c-format
@@ -4862,7 +5007,8 @@ msgstr "Sense canvis"
 #: wt-status.c:1674
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
-msgstr "no hi ha canvis afegits a cometre (useu \"git add\" o \"git commit -a\")\n"
+msgstr ""
+"no hi ha canvis afegits a cometre (useu \"git add\" o \"git commit -a\")\n"
 
 #: wt-status.c:1677
 #, c-format
@@ -4871,10 +5017,12 @@ msgstr "no hi ha canvis afegits a cometre\n"
 
 #: wt-status.c:1680
 #, c-format
-msgid "nothing added to commit but untracked files present (use \"git add\" to track)\n"
+msgid ""
+"nothing added to commit but untracked files present (use \"git add\" to "
+"track)\n"
 msgstr ""
-"no hi ha res afegit a cometre però hi ha fitxers no seguits (useu \"git add\" per a "
-"seguir-los)\n"
+"no hi ha res afegit a cometre però hi ha fitxers no seguits (useu \"git add"
+"\" per a seguir-los)\n"
 
 #: wt-status.c:1683
 #, c-format
@@ -4885,7 +5033,8 @@ msgstr "no hi ha res afegit a cometre però hi ha fitxers no seguits\n"
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
-"no hi ha res a cometre (creeu/copieu fitxers i useu \"git add\" per a seguir-los)\n"
+"no hi ha res a cometre (creeu/copieu fitxers i useu \"git add\" per a seguir-"
+"los)\n"
 
 #: wt-status.c:1689 wt-status.c:1694
 #, c-format
@@ -4895,7 +5044,8 @@ msgstr "no hi ha res a cometre\n"
 #: wt-status.c:1692
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
-msgstr "no hi ha res a cometre (useu -u per a mostrar els fitxers no seguits)\n"
+msgstr ""
+"no hi ha res a cometre (useu -u per a mostrar els fitxers no seguits)\n"
 
 #: wt-status.c:1696
 #, c-format
@@ -4997,11 +5147,12 @@ msgstr "No s'ha pogut aplicar «%s»"
 
 #: builtin/add.c:271
 msgid "The following paths are ignored by one of your .gitignore files:\n"
-msgstr "Els camins següents s'ignoren per un dels vostres fitxers .gitignore:\n"
+msgstr ""
+"Els camins següents s'ignoren per un dels vostres fitxers .gitignore:\n"
 
 #: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:146 builtin/mv.c:124
-#: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541 builtin/remote.c:1333
-#: builtin/rm.c:242 builtin/send-pack.c:164
+#: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541
+#: builtin/remote.c:1333 builtin/rm.c:242 builtin/send-pack.c:164
 msgid "dry run"
 msgstr "marxa en sec"
 
@@ -5039,7 +5190,8 @@ msgstr "afegeix els canvis de tots els fitxers seguits i no seguits"
 
 #: builtin/add.c:304
 msgid "ignore paths removed in the working tree (same as --no-all)"
-msgstr "ignora els camins eliminats en l'arbre de treball (el mateix que --no-all)"
+msgstr ""
+"ignora els camins eliminats en l'arbre de treball (el mateix que --no-all)"
 
 #: builtin/add.c:306
 msgid "don't add, only refresh the index"
@@ -5051,7 +5203,8 @@ msgstr "només omet els fitxers que no es poden afegir a causa d'errors"
 
 #: builtin/add.c:308
 msgid "check if - even missing - files are ignored in dry run"
-msgstr "comproveu si els fitxers - fins i tot els absents - s'ignoren en marxa en sec"
+msgstr ""
+"comproveu si els fitxers - fins i tot els absents - s'ignoren en marxa en sec"
 
 #: builtin/add.c:309 builtin/update-index.c:964
 msgid "(+/-)x"
@@ -5134,8 +5287,9 @@ msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Potser volíeu dir «git add .»?\n"
 
 #: builtin/add.c:449 builtin/check-ignore.c:177 builtin/checkout.c:280
-#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316 builtin/diff-tree.c:114
-#: builtin/mv.c:144 builtin/reset.c:241 builtin/rm.c:271 builtin/submodule--helper.c:326
+#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316
+#: builtin/diff-tree.c:114 builtin/mv.c:144 builtin/reset.c:241
+#: builtin/rm.c:271 builtin/submodule--helper.c:326
 msgid "index file corrupt"
 msgstr "fitxer d'índex malmès"
 
@@ -5208,12 +5362,15 @@ msgstr "Quan hàgiu resolt aquest problema, executeu \"%s --continue\"."
 #: builtin/am.c:1163
 #, c-format
 msgid "If you prefer to skip this patch, run \"%s --skip\" instead."
-msgstr "Si preferiu ometre aquest pedaç, executeu \"%s --skip\" en lloc d'això."
+msgstr ""
+"Si preferiu ometre aquest pedaç, executeu \"%s --skip\" en lloc d'això."
 
 #: builtin/am.c:1164
 #, c-format
 msgid "To restore the original branch and stop patching, run \"%s --abort\"."
-msgstr "Per a restaurar la branca original i deixar d'apedaçar, executeu \"%s --abort\"."
+msgstr ""
+"Per a restaurar la branca original i deixar d'apedaçar, executeu \"%s --abort"
+"\"."
 
 #: builtin/am.c:1271
 msgid "Patch is empty."
@@ -5231,7 +5388,9 @@ msgstr "no s'ha pogut analitzar la comissió %s"
 
 #: builtin/am.c:1554
 msgid "Repository lacks necessary blobs to fall back on 3-way merge."
-msgstr "Al dipòsit li manquen els blobs necessaris per a retrocedir a una fusió de 3 vies."
+msgstr ""
+"Al dipòsit li manquen els blobs necessaris per a retrocedir a una fusió de 3 "
+"vies."
 
 #: builtin/am.c:1556
 msgid "Using index info to reconstruct a base tree..."
@@ -5264,7 +5423,8 @@ msgstr "no es pot reprendre: %s no existeix."
 
 #: builtin/am.c:1703
 msgid "cannot be interactive without stdin connected to a terminal."
-msgstr "no es pot ser interactiu sense que stdin estigui connectada a un terminal."
+msgstr ""
+"no es pot ser interactiu sense que stdin estigui connectada a un terminal."
 
 #: builtin/am.c:1708
 msgid "Commit Body is:"
@@ -5276,7 +5436,9 @@ msgstr "El cos de la comissió és:"
 #.
 #: builtin/am.c:1718
 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: "
-msgstr "Voleu aplicar-lo? [y]es/[n]o/[e]dita/[v]isualitza el pedaç/[a]ccepta'ls tots: "
+msgstr ""
+"Voleu aplicar-lo? [y]es/[n]o/[e]dita/[v]isualitza el pedaç/[a]ccepta'ls "
+"tots: "
 
 #: builtin/am.c:1768
 #, c-format
@@ -5314,12 +5476,15 @@ msgstr ""
 #: builtin/am.c:1889
 msgid ""
 "You still have unmerged paths in your index.\n"
-"You should 'git add' each file with resolved conflicts to mark them as such.\n"
+"You should 'git add' each file with resolved conflicts to mark them as "
+"such.\n"
 "You might run `git rm` on a file to accept \"deleted by them\" for it."
 msgstr ""
 "Encara teniu camins sense fusionar a l'índex.\n"
-"Heu de fer 'git add' a cada fitxer amb conflictes resolts per marcar-los com a tal.\n"
-"Podeu executar `git rm` en un fitxer per acceptar \"suprimit per ells\" pel fitxer."
+"Heu de fer 'git add' a cada fitxer amb conflictes resolts per marcar-los com "
+"a tal.\n"
+"Podeu executar `git rm` en un fitxer per acceptar \"suprimit per ells\" pel "
+"fitxer."
 
 #: builtin/am.c:1996 builtin/am.c:2000 builtin/am.c:2012 builtin/reset.c:324
 #: builtin/reset.c:332
@@ -5364,7 +5529,8 @@ msgstr "opció històrica -- no-op"
 msgid "allow fall back on 3way merging if needed"
 msgstr "permet retrocedir a una fusió de 3 vies si és necessari"
 
-#: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57 builtin/repack.c:182
+#: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57
+#: builtin/repack.c:182
 msgid "be quiet"
 msgstr "silenciós"
 
@@ -5394,7 +5560,8 @@ msgstr "passa l'indicador --keep-cr a git-mailsplit per al format mbox"
 
 #: builtin/am.c:2238
 msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr"
-msgstr "no passis l'indicador --keep-cr a git-mailsplit independent d'am.keepcr"
+msgstr ""
+"no passis l'indicador --keep-cr a git-mailsplit independent d'am.keepcr"
 
 #: builtin/am.c:2241
 msgid "strip everything before a scissors line"
@@ -5408,14 +5575,14 @@ msgstr "passa-ho a través de git-apply"
 
 #: builtin/am.c:2260 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668
 #: builtin/grep.c:853 builtin/merge.c:206 builtin/pull.c:145 builtin/pull.c:203
-#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197 builtin/show-branch.c:631
-#: builtin/show-ref.c:169 builtin/tag.c:382 parse-options.h:144 parse-options.h:146
-#: parse-options.h:257
+#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197
+#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:382
+#: parse-options.h:144 parse-options.h:146 parse-options.h:257
 msgid "n"
 msgstr "n"
 
-#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/replace.c:445
-#: builtin/tag.c:418 builtin/verify-tag.c:39
+#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38
+#: builtin/replace.c:445 builtin/tag.c:418 builtin/verify-tag.c:39
 msgid "format"
 msgstr "format"
 
@@ -5459,8 +5626,8 @@ msgstr "menteix sobre la data del comitent"
 msgid "use current timestamp for author date"
 msgstr "usa el marc de temps actual per la data d'autor"
 
-#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237 builtin/pull.c:178
-#: builtin/revert.c:112 builtin/tag.c:398
+#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237
+#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:398
 msgid "key-id"
 msgstr "ID de clau"
 
@@ -5487,7 +5654,9 @@ msgstr "S'ha produït un error en llegir l'índex"
 #: builtin/am.c:2342
 #, c-format
 msgid "previous rebase directory %s still exists but mbox given."
-msgstr "un directori de «rebase» anterior %s encara existeix però s'ha donat una bústia."
+msgstr ""
+"un directori de «rebase» anterior %s encara existeix però s'ha donat una "
+"bústia."
 
 #: builtin/am.c:2366
 #, c-format
@@ -5613,11 +5782,14 @@ msgstr "Mostra les entrades «blame» mentre les trobem, incrementalment"
 
 #: builtin/blame.c:678
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
-msgstr "Mostra un SHA-1 en blanc per les comissions de frontera (Per defecte: desactivat)"
+msgstr ""
+"Mostra un SHA-1 en blanc per les comissions de frontera (Per defecte: "
+"desactivat)"
 
 #: builtin/blame.c:679
 msgid "Do not treat root commits as boundaries (Default: off)"
-msgstr "No tractis les comissions d'arrel com a límits (Per defecte: desactivat)"
+msgstr ""
+"No tractis les comissions d'arrel com a límits (Per defecte: desactivat)"
 
 #: builtin/blame.c:680
 msgid "Show work cost statistics"
@@ -5649,7 +5821,8 @@ msgstr "Mostra el format de porcellana amb informació de comissió per línia"
 
 #: builtin/blame.c:687
 msgid "Use the same output mode as git-annotate (Default: off)"
-msgstr "Usa el mateix mode de sortida que git-annotate (Per defecte: desactivat)"
+msgstr ""
+"Usa el mateix mode de sortida que git-annotate (Per defecte: desactivat)"
 
 #: builtin/blame.c:688
 msgid "Show raw timestamp (Default: off)"
@@ -5665,7 +5838,9 @@ msgstr "Omet el nom d'autor i la marca de temps (Per defecte: desactivat)"
 
 #: builtin/blame.c:691
 msgid "Show author email instead of name (Default: off)"
-msgstr "Mostra l'adreça electrònica de l'autor en lloc del nom (Per defecte: desactivat)"
+msgstr ""
+"Mostra l'adreça electrònica de l'autor en lloc del nom (Per defecte: "
+"desactivat)"
 
 #: builtin/blame.c:692
 msgid "Ignore whitespace differences"
@@ -5709,7 +5884,8 @@ msgstr "Processa només el rang de línies n,m, comptant des d'1"
 
 #: builtin/blame.c:753
 msgid "--progress can't be used with --incremental or porcelain formats"
-msgstr "no es pot usar --progress amb els formats --incremental o de porcellana"
+msgstr ""
+"no es pot usar --progress amb els formats --incremental o de porcellana"
 
 #. TRANSLATORS: This string is used to tell us the
 #. maximum display width for a relative timestamp in
@@ -5880,7 +6056,7 @@ msgstr "La còpia de la branca ha fallat"
 
 #: builtin/branch.c:517
 #, c-format
-msgid "created a copy of a misnamed branch '%s'"
+msgid "Created a copy of a misnamed branch '%s'"
 msgstr "S'ha creat una còpia d'una branca mal anomenada «%s»"
 
 #: builtin/branch.c:520
@@ -5896,11 +6072,14 @@ msgstr "S'ha canviat el nom de la branca a %s, però HEAD no està actualitzat!"
 #: builtin/branch.c:535
 msgid "Branch is renamed, but update of config-file failed"
 msgstr ""
-"La branca està canviada de nom, però l'actualització del fitxer de configuració ha fallat"
+"La branca està canviada de nom, però l'actualització del fitxer de "
+"configuració ha fallat"
 
 #: builtin/branch.c:537
 msgid "Branch is copied, but update of config-file failed"
-msgstr "La branca està copiada, però l'actualització del fitxer de configuració ha fallat"
+msgstr ""
+"La branca està copiada, però l'actualització del fitxer de configuració ha "
+"fallat"
 
 #: builtin/branch.c:553
 #, c-format
@@ -6029,8 +6208,9 @@ msgstr "clau"
 msgid "field name to sort on"
 msgstr "nom del camp en el qual ordenar"
 
-#: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408 builtin/notes.c:411
-#: builtin/notes.c:571 builtin/notes.c:574 builtin/tag.c:414
+#: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408
+#: builtin/notes.c:411 builtin/notes.c:571 builtin/notes.c:574
+#: builtin/tag.c:414
 msgid "object"
 msgstr "objecte"
 
@@ -6042,7 +6222,8 @@ msgstr "imprimeix només les branques de l'objecte"
 msgid "sorting and filtering are case insensitive"
 msgstr "l'ordenació i el filtratge distingeixen entre majúscules i minúscules"
 
-#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419 builtin/verify-tag.c:39
+#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419
+#: builtin/verify-tag.c:39
 msgid "format to use for the output"
 msgstr "format a usar en la sortida"
 
@@ -6090,8 +6271,10 @@ msgstr "hi ha massa arguments per a establir una nova font"
 
 #: builtin/branch.c:766
 #, c-format
-msgid "could not set upstream of HEAD to %s when it does not point to any branch."
-msgstr "no s'ha pogut establir la font de HEAD com a %s quan no assenyala cap branca."
+msgid ""
+"could not set upstream of HEAD to %s when it does not point to any branch."
+msgstr ""
+"no s'ha pogut establir la font de HEAD com a %s quan no assenyala cap branca."
 
 #: builtin/branch.c:769 builtin/branch.c:791 builtin/branch.c:807
 #, c-format
@@ -6109,7 +6292,8 @@ msgstr "hi ha massa arguments per a desassignar la font"
 
 #: builtin/branch.c:789
 msgid "could not unset upstream of HEAD when it does not point to any branch."
-msgstr "no s'ha pogut desassignar la font de HEAD perquè no assenyala cap branca."
+msgstr ""
+"no s'ha pogut desassignar la font de HEAD perquè no assenyala cap branca."
 
 #: builtin/branch.c:795
 #, c-format
@@ -6118,14 +6302,16 @@ msgstr "La branca «%s» no té informació de font"
 
 #: builtin/branch.c:810
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
-msgstr "les opcions -a i -r a 'git branch' no tenen sentit amb un nom de branca"
+msgstr ""
+"les opcions -a i -r a 'git branch' no tenen sentit amb un nom de branca"
 
 #: builtin/branch.c:813
 msgid ""
-"the '--set-upstream' option is no longer supported. Please use '--track' or '--set-"
-"upstream-to' instead."
+"the '--set-upstream' option is no longer supported. Please use '--track' or "
+"'--set-upstream-to' instead."
 msgstr ""
-"L'opció --set-upstream ja no està suportada. Useu en comptes --track o --set-upstream-to."
+"L'opció --set-upstream ja no està suportada. Useu en comptes --track o --set-"
+"upstream-to."
 
 #: builtin/bundle.c:45
 #, c-format
@@ -6142,16 +6328,19 @@ msgstr "Cal un dipòsit per a desfer un farcell."
 
 #: builtin/cat-file.c:523
 msgid ""
-"git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -p | <type> | "
-"--textconv | --filters) [--path=<path>] <object>"
+"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 | <tipus> "
-"| --textconv | --filters [--path=<camí>]) <objecte>"
+"git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
+"p | <tipus> | --textconv | --filters [--path=<camí>]) <objecte>"
 
 #: builtin/cat-file.c:524
-msgid "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --filters]"
+msgid ""
+"git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
+"filters]"
 msgstr ""
-"git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --filters]"
+"git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
+"filters]"
 
 #: builtin/cat-file.c:561
 msgid "<type> can be one of: blob, tree, commit, tag"
@@ -6179,7 +6368,8 @@ msgstr "en els objectes de blob, executa textconv en el contingut de l'objecte"
 
 #: builtin/cat-file.c:570
 msgid "for blob objects, run filters on object's content"
-msgstr "en els objectes de blob, executa els filtres en el contingut de l'objecte"
+msgstr ""
+"en els objectes de blob, executa els filtres en el contingut de l'objecte"
 
 #: builtin/cat-file.c:571 git-submodule.sh:878
 msgid "blob"
@@ -6199,7 +6389,8 @@ msgstr "posa la sortida de --batch en memòria intermèdia"
 
 #: builtin/cat-file.c:577
 msgid "show info and content of objects fed from the standard input"
-msgstr "mostra la informació i contingut dels objectes rebuts de l'entrada estàndard"
+msgstr ""
+"mostra la informació i contingut dels objectes rebuts de l'entrada estàndard"
 
 #: builtin/cat-file.c:580
 msgid "show info about objects fed from the standard input"
@@ -6207,7 +6398,8 @@ msgstr "mostra informació sobre els objectes rebuts de l'entrada estàndard"
 
 #: builtin/cat-file.c:583
 msgid "follow in-tree symlinks (used with --batch or --batch-check)"
-msgstr "segueix els enllaços simbòlics en l'arbre (s'usa amb --batch o --batch-check)"
+msgstr ""
+"segueix els enllaços simbòlics en l'arbre (s'usa amb --batch o --batch-check)"
 
 #: builtin/cat-file.c:585
 msgid "show all objects with --batch or --batch-check"
@@ -6308,7 +6500,8 @@ msgstr "força la sobreescriptura de fitxers existents"
 
 #: builtin/checkout-index.c:162
 msgid "no warning for existing files and files not in index"
-msgstr "cap advertència per a fitxers existents i fitxers que no siguin a l'índex"
+msgstr ""
+"cap advertència per a fitxers existents i fitxers que no siguin a l'índex"
 
 #: builtin/checkout-index.c:164
 msgid "don't checkout new files"
@@ -6326,9 +6519,10 @@ msgstr "llegeix la llista de camins des de l'entrada estàndard"
 msgid "write the content to temporary files"
 msgstr "escriu el contingut a fitxers temporals"
 
-#: builtin/checkout-index.c:173 builtin/column.c:31 builtin/submodule--helper.c:1203
-#: builtin/submodule--helper.c:1206 builtin/submodule--helper.c:1212
-#: builtin/submodule--helper.c:1574 builtin/worktree.c:570
+#: builtin/checkout-index.c:173 builtin/column.c:31
+#: builtin/submodule--helper.c:1203 builtin/submodule--helper.c:1206
+#: builtin/submodule--helper.c:1212 builtin/submodule--helper.c:1574
+#: builtin/worktree.c:570
 msgid "string"
 msgstr "cadena"
 
@@ -6392,7 +6586,8 @@ msgstr "«%s» no es pot usar amb %s"
 #: builtin/checkout.c:271
 #, c-format
 msgid "Cannot update paths and switch to branch '%s' at the same time."
-msgstr "No es poden actualitzar els camins i canviar a la branca «%s» a la vegada."
+msgstr ""
+"No es poden actualitzar els camins i canviar a la branca «%s» a la vegada."
 
 #: builtin/checkout.c:340 builtin/checkout.c:347
 #, c-format
@@ -6543,8 +6738,9 @@ msgstr "«%s» no es pot usar amb «%s»"
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "No es pot canviar la branca a la no comissió «%s»"
 
-#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116 builtin/remote.c:166
-#: builtin/remote.c:168 builtin/worktree.c:387 builtin/worktree.c:389
+#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116
+#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:387
+#: builtin/worktree.c:389
 msgid "branch"
 msgstr "branca"
 
@@ -6616,8 +6812,9 @@ msgstr "dubta 'git checkout <cap-branca-així>'"
 msgid "do not check if another worktree is holding the given ref"
 msgstr "no comprovis si altre arbre de treball té la referència donada"
 
-#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150 builtin/merge.c:236
-#: builtin/pull.c:123 builtin/push.c:556 builtin/send-pack.c:173
+#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150
+#: builtin/merge.c:236 builtin/pull.c:123 builtin/push.c:556
+#: builtin/send-pack.c:173
 msgid "force progress reporting"
 msgstr "força l'informe de progrés"
 
@@ -6641,7 +6838,8 @@ msgstr "especificació de camí no vàlida"
 #, c-format
 msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
 msgstr ""
-"«%s» no és una comissió i la branca «%s» no es pot crear a partir d'aquesta comissió"
+"«%s» no és una comissió i la branca «%s» no es pot crear a partir d'aquesta "
+"comissió"
 
 #: builtin/checkout.c:1237
 #, c-format
@@ -6657,8 +6855,10 @@ msgstr ""
 "agafar de l'índex."
 
 #: builtin/clean.c:26
-msgid "git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
-msgstr "git clean [-d] [-f] [-i] [-n] [-q] [-e <patró>] [-x | -X] [--] <camins>..."
+msgid ""
+"git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..."
+msgstr ""
+"git clean [-d] [-f] [-i] [-n] [-q] [-e <patró>] [-x | -X] [--] <camins>..."
 
 #: builtin/clean.c:30
 #, c-format
@@ -6719,7 +6919,8 @@ msgstr ""
 "*          - tria tots els ítems\n"
 "           - (buit) finalitza la selecció\n"
 
-#: builtin/clean.c:522 git-add--interactive.perl:547 git-add--interactive.perl:552
+#: builtin/clean.c:522 git-add--interactive.perl:547
+#: git-add--interactive.perl:552
 #, c-format, perl-format
 msgid "Huh (%s)?\n"
 msgstr "Perdó (%s)?\n"
@@ -6801,9 +7002,10 @@ msgstr "neteja interactiva"
 msgid "remove whole directories"
 msgstr "elimina directoris sencers"
 
-#: builtin/clean.c:916 builtin/describe.c:533 builtin/describe.c:535 builtin/grep.c:871
-#: builtin/log.c:157 builtin/log.c:159 builtin/ls-files.c:548 builtin/name-rev.c:397
-#: builtin/name-rev.c:399 builtin/show-ref.c:176
+#: builtin/clean.c:916 builtin/describe.c:533 builtin/describe.c:535
+#: builtin/grep.c:871 builtin/log.c:157 builtin/log.c:159
+#: builtin/ls-files.c:548 builtin/name-rev.c:397 builtin/name-rev.c:399
+#: builtin/show-ref.c:176
 msgid "pattern"
 msgstr "patró"
 
@@ -6824,16 +7026,20 @@ msgid "-x and -X cannot be used together"
 msgstr "-x i -X no es poden usar junts"
 
 #: builtin/clean.c:942
-msgid "clean.requireForce set to true and neither -i, -n, nor -f given; refusing to clean"
+msgid ""
+"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to "
+"clean"
 msgstr ""
-"clean.requireForce està establerta en cert i ni -i, -n ni -f s'han indicat; refusant "
-"netejar"
+"clean.requireForce està establerta en cert i ni -i, -n ni -f s'han indicat; "
+"refusant netejar"
 
 #: builtin/clean.c:945
 msgid ""
-"clean.requireForce defaults to true and neither -i, -n, nor -f given; refusing to clean"
+"clean.requireForce defaults to true and neither -i, -n, nor -f given; "
+"refusing to clean"
 msgstr ""
-"clean.requireForce és per defecte cert i ni -i, -n ni -f s'han indicat; refusant netejar"
+"clean.requireForce és per defecte cert i ni -i, -n ni -f s'han indicat; "
+"refusant netejar"
 
 #: builtin/clone.c:40
 msgid "git clone [<options>] [--] <repo> [<dir>]"
@@ -6902,13 +7108,14 @@ msgstr "usa <nom> en lloc de 'origin' per a seguir la font"
 
 #: builtin/clone.c:117
 msgid "checkout <branch> instead of the remote's HEAD"
-msgstr "agafa <branca> en lloc del HEAD del remot"
+msgstr "agafa <branca> en lloc de la HEAD del remot"
 
 #: builtin/clone.c:119
 msgid "path to git-upload-pack on the remote"
 msgstr "camí a git-upload-pack en el remot"
 
-#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813 builtin/pull.c:211
+#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813
+#: builtin/pull.c:211
 msgid "depth"
 msgstr "profunditat"
 
@@ -6916,7 +7123,8 @@ msgstr "profunditat"
 msgid "create a shallow clone of that depth"
 msgstr "crea un clon superficial de tal profunditat"
 
-#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017 parse-options.h:154
+#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017
+#: parse-options.h:154
 msgid "time"
 msgstr "hora"
 
@@ -6938,7 +7146,8 @@ msgstr "clona només una branca, HEAD o --branch"
 
 #: builtin/clone.c:129
 msgid "don't clone any tags, and make later fetches not to follow them"
-msgstr "no cloneu cap etiqueta, i feu que els «fetch» següents no els segueixen"
+msgstr ""
+"no cloneu cap etiqueta, i feu que els «fetch» següents no els segueixen"
 
 #: builtin/clone.c:131
 msgid "any cloned submodules will be shallow"
@@ -6960,11 +7169,13 @@ msgstr "clau=valor"
 msgid "set config inside the new repository"
 msgstr "estableix la configuració dins del dipòsit nou"
 
-#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224 builtin/push.c:567
+#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224
+#: builtin/push.c:567
 msgid "use IPv4 addresses only"
 msgstr "usa només adreces IPv4"
 
-#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227 builtin/push.c:569
+#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227
+#: builtin/push.c:569
 msgid "use IPv6 addresses only"
 msgstr "usa només adreces IPv6"
 
@@ -7039,7 +7250,8 @@ msgstr "no s'ha pogut actualitzar %s"
 #: builtin/clone.c:726
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
-"el HEAD remot es refereix a una referència que no existeix; no s'ha pogut agafar.\n"
+"la HEAD remot es refereix a una referència que no existeix; no s'ha pogut "
+"agafar.\n"
 
 #: builtin/clone.c:756
 msgid "unable to checkout working tree"
@@ -7094,8 +7306,8 @@ msgstr "el camí destí «%s» ja existeix i no és un directori buit."
 msgid "working tree '%s' already exists."
 msgstr "l'arbre de treball «%s» ja existeix."
 
-#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270 builtin/worktree.c:255
-#: builtin/worktree.c:285
+#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270
+#: builtin/worktree.c:255 builtin/worktree.c:285
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "no s'han pogut crear els directoris inicials de «%s»"
@@ -7116,8 +7328,12 @@ msgid "Cloning into '%s'...\n"
 msgstr "S'està clonant a «%s»...\n"
 
 #: builtin/clone.c:1031
-msgid "clone --recursive is not compatible with both --reference and --reference-if-able"
-msgstr "clone --recursive no és compatible amb ambdós --reference i --reference-if-able"
+msgid ""
+"clone --recursive is not compatible with both --reference and --reference-if-"
+"able"
+msgstr ""
+"clone --recursive no és compatible amb ambdós --reference i --reference-if-"
+"able"
 
 #: builtin/clone.c:1093
 msgid "--depth is ignored in local clones; use file:// instead."
@@ -7125,11 +7341,13 @@ msgstr "--depth s'ignora en els clons locals; useu file:// en lloc d'això."
 
 #: builtin/clone.c:1095
 msgid "--shallow-since is ignored in local clones; use file:// instead."
-msgstr "--shallow-since s'ignora en els clons locals; useu file:// en lloc d'això."
+msgstr ""
+"--shallow-since s'ignora en els clons locals; useu file:// en lloc d'això."
 
 #: builtin/clone.c:1097
 msgid "--shallow-exclude is ignored in local clones; use file:// instead."
-msgstr "--shallow-exclude s'ignora en els clons locals; useu file:// en lloc d'això."
+msgstr ""
+"--shallow-exclude s'ignora en els clons locals; useu file:// en lloc d'això."
 
 #: builtin/clone.c:1099
 msgid "--filter is ignored in local clones; use file:// instead."
@@ -7210,7 +7428,8 @@ msgid ""
 "    git commit --allow-empty\n"
 "\n"
 msgstr ""
-"El «cherry pick» previ ja està buit, possiblement a causa de resolució de conflicte.\n"
+"El «cherry pick» previ ja està buit, possiblement a causa de resolució de "
+"conflicte.\n"
 "Si el voleu cometre de totes maneres, useu:\n"
 "\n"
 "    git commit --allow-empty\n"
@@ -7377,7 +7596,8 @@ msgid ""
 "An empty message aborts the commit.\n"
 msgstr ""
 "Introduïu el missatge de comissió dels vostres canvis.\n"
-"Es mantindran les línies que comencin amb '%c'; podeu eliminar-les vosaltres\n"
+"Es mantindran les línies que comencin amb '%c'; podeu eliminar-les "
+"vosaltres\n"
 "mateixos si voleu. Un missatge buit avorta la comissió.\n"
 
 #: builtin/commit.c:830
@@ -7498,7 +7718,8 @@ msgstr ""
 msgid "version"
 msgstr "versió"
 
-#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542 builtin/worktree.c:541
+#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542
+#: builtin/worktree.c:541
 msgid "machine-readable output"
 msgstr "sortida llegible per màquina"
 
@@ -7518,23 +7739,28 @@ msgstr "mode"
 #: builtin/commit.c:1295 builtin/commit.c:1457
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
-"mostra els fitxers no seguits, modes opcionals: all, normal, no. (Per defecte: all)"
+"mostra els fitxers no seguits, modes opcionals: all, normal, no. (Per "
+"defecte: all)"
 
 #: builtin/commit.c:1299
 msgid ""
-"show ignored files, optional modes: traditional, matching, no. (Default: traditional)"
+"show ignored files, optional modes: traditional, matching, no. (Default: "
+"traditional)"
 msgstr ""
-"mostra els fitxers ignorats, modes opcionals: traditional, matching, no. (Per defecte: "
-"traditional, matching, no.)"
+"mostra els fitxers ignorats, modes opcionals: traditional, matching, no. "
+"(Per defecte: traditional, matching, no.)"
 
 #: builtin/commit.c:1301 parse-options.h:167
 msgid "when"
 msgstr "quan"
 
 #: builtin/commit.c:1302
-msgid "ignore changes to submodules, optional when: all, dirty, untracked. (Default: all)"
+msgid ""
+"ignore changes to submodules, optional when: all, dirty, untracked. "
+"(Default: all)"
 msgstr ""
-"ignora els canvis als submòduls, opcional quan: all, dirty, untracked. (Per defecte: all)"
+"ignora els canvis als submòduls, opcional quan: all, dirty, untracked. (Per "
+"defecte: all)"
 
 #: builtin/commit.c:1304
 msgid "list untracked files in columns"
@@ -7576,8 +7802,8 @@ msgstr "data"
 msgid "override date for commit"
 msgstr "data corregida de la comissió"
 
-#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402 builtin/notes.c:565
-#: builtin/tag.c:391
+#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402
+#: builtin/notes.c:565 builtin/tag.c:391
 msgid "message"
 msgstr "missatge"
 
@@ -7585,8 +7811,8 @@ msgstr "missatge"
 msgid "commit message"
 msgstr "missatge de comissió"
 
-#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423 builtin/commit.c:1424
-#: parse-options.h:269 ref-filter.h:92
+#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423
+#: builtin/commit.c:1424 parse-options.h:269 ref-filter.h:92
 msgid "commit"
 msgstr "comissió"
 
@@ -7601,19 +7827,21 @@ msgstr "reusa el missatge de la comissió especificada"
 #: builtin/commit.c:1423
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
-"usa el missatge formatat de «squash» automàtic per a corregir la comissió especificada"
+"usa el missatge formatat de «squash» automàtic per a corregir la comissió "
+"especificada"
 
 #: builtin/commit.c:1424
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
-"usa el missatge formatat de «squash» automàtic per a «squash» a la comissió especificada"
+"usa el missatge formatat de «squash» automàtic per a «squash» a la comissió "
+"especificada"
 
 #: builtin/commit.c:1425
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr "l'autor de la comissió ja soc jo (s'usa amb -C/-c/--amend)"
 
-#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240 builtin/pull.c:149
-#: builtin/revert.c:105
+#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240
+#: builtin/pull.c:149 builtin/revert.c:105
 msgid "add Signed-off-by:"
 msgstr "afegeix Signed-off-by:"
 
@@ -7637,7 +7865,8 @@ msgstr "com suprimir els espais i #comentaris del missatge"
 msgid "include status in commit message template"
 msgstr "inclou l'estat en la plantilla de missatge de comissió"
 
-#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179 builtin/revert.c:113
+#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179
+#: builtin/revert.c:113
 msgid "GPG sign commit"
 msgstr "signa la comissió amb GPG"
 
@@ -7778,7 +8007,8 @@ msgstr "obtén el valor específic per a l'URL: secció[.variable] URL"
 
 #: builtin/config.c:69
 msgid "replace all matching variables: name value [value_regex]"
-msgstr "reemplaça totes les variables que coincideixen: nom valor [regex_de_valors]"
+msgstr ""
+"reemplaça totes les variables que coincideixen: nom valor [regex_de_valors]"
 
 #: builtin/config.c:70
 msgid "add a new variable: name value"
@@ -7859,7 +8089,8 @@ msgstr "respecta les directives d'inclusió en cercar"
 #: builtin/config.c:89
 msgid "show origin of config (file, standard input, blob, command line)"
 msgstr ""
-"mostra l'origen de la configuració (fitxer, entrada estàndard, blob, línia d'ordres)"
+"mostra l'origen de la configuració (fitxer, entrada estàndard, blob, línia "
+"d'ordres)"
 
 #: builtin/config.c:335
 msgid "unable to parse default color value"
@@ -8180,13 +8411,16 @@ msgstr "utilitza l'eina de diff especificada"
 
 #: builtin/difftool.c:709
 msgid "print a list of diff tools that may be used with `--tool`"
-msgstr "imprimeix una llista de totes les eines diff que podeu usar amb `--tool`"
+msgstr ""
+"imprimeix una llista de totes les eines diff que podeu usar amb `--tool`"
 
 #: builtin/difftool.c:712
-msgid "make 'git-difftool' exit when an invoked diff tool returns a non - zero exit code"
+msgid ""
+"make 'git-difftool' exit when an invoked diff tool returns a non - zero exit "
+"code"
 msgstr ""
-"fes que 'git-difftool' surti quan l'eina de diff invocada torna un codi de sortida "
-"diferent de zero"
+"fes que 'git-difftool' surti quan l'eina de diff invocada torna un codi de "
+"sortida diferent de zero"
 
 #: builtin/difftool.c:714
 msgid "<command>"
@@ -8349,10 +8583,12 @@ msgid "prepend this to submodule path output"
 msgstr "anteposa això a la sortida de camí del submòdul"
 
 #: builtin/fetch.c:166
-msgid "default for recursive fetching of submodules (lower priority than config files)"
+msgid ""
+"default for recursive fetching of submodules (lower priority than config "
+"files)"
 msgstr ""
-"per defecte per a l'obtenció recursiva de submòduls (prioritat més baixa que els fitxers "
-"de configuració)"
+"per defecte per a l'obtenció recursiva de submòduls (prioritat més baixa que "
+"els fitxers de configuració)"
 
 #: builtin/fetch.c:170 builtin/pull.c:218
 msgid "accept refs that update .git/shallow"
@@ -8396,7 +8632,8 @@ msgstr "no es pot obtenir en la branca actual"
 msgid "[tag update]"
 msgstr "[actualització d'etiqueta]"
 
-#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719 builtin/fetch.c:734
+#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719
+#: builtin/fetch.c:734
 msgid "unable to update local ref"
 msgstr "no s'ha pogut actualitzar la referència local"
 
@@ -8428,7 +8665,8 @@ msgstr "%s no ha enviat tots els objectes necessaris\n"
 #: builtin/fetch.c:804
 #, c-format
 msgid "reject %s because shallow roots are not allowed to be updated"
-msgstr "rebutja %s perquè no es permet que les arrels superficials s'actualitzin"
+msgstr ""
+"rebutja %s perquè no es permet que les arrels superficials s'actualitzin"
 
 #: builtin/fetch.c:892 builtin/fetch.c:988
 #, c-format
@@ -8489,7 +8727,8 @@ msgid "Could not fetch %s"
 msgstr "No s'ha pogut obtenir %s"
 
 #: builtin/fetch.c:1325 builtin/fetch.c:1498
-msgid "--filter can only be used with the remote configured in core.partialClone"
+msgid ""
+"--filter can only be used with the remote configured in core.partialClone"
 msgstr ""
 
 #: builtin/fetch.c:1350
@@ -8538,8 +8777,10 @@ msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr "Obtenir un grup i especificar referències no té sentit"
 
 #: builtin/fmt-merge-msg.c:15
-msgid "git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]"
-msgstr "git fmt-merge-msg [-m <missatge>] [--log[=<n>] | --no-log] [--file <fitxer>]"
+msgid ""
+"git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]"
+msgstr ""
+"git fmt-merge-msg [-m <missatge>] [--log[=<n>] | --no-log] [--file <fitxer>]"
 
 #: builtin/fmt-merge-msg.c:666
 msgid "populate log with at most <n> entries from shortlog"
@@ -8575,11 +8816,13 @@ msgstr "git for-each-ref [(--merged | --no-merged) [<comissió>]]"
 
 #: builtin/for-each-ref.c:13
 msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]"
-msgstr "git for-each-ref [--contains [<comissió>]] [--no-contains [<comissió>]]"
+msgstr ""
+"git for-each-ref [--contains [<comissió>]] [--no-contains [<comissió>]]"
 
 #: builtin/for-each-ref.c:28
 msgid "quote placeholders suitably for shells"
-msgstr "posa els marcadors de posició de forma adequada per a intèrprets d'ordres"
+msgstr ""
+"posa els marcadors de posició de forma adequada per a intèrprets d'ordres"
 
 #: builtin/for-each-ref.c:30
 msgid "quote placeholders suitably for perl"
@@ -8734,7 +8977,9 @@ msgstr "No s'ha pogut analitzar el valor gc.logexpiry %s"
 #: builtin/gc.c:412
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
-msgstr "S'està empaquetant el dipòsit automàticament en el fons per rendiment òptim.\n"
+msgstr ""
+"S'està empaquetant el dipòsit automàticament en el fons per rendiment "
+"òptim.\n"
 
 #: builtin/gc.c:414
 #, c-format
@@ -8748,12 +8993,17 @@ msgstr "Vegeu \"git help gc\" per neteja manual.\n"
 
 #: builtin/gc.c:440
 #, c-format
-msgid "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
-msgstr "gc ja s'està executant en la màquina «%s» pid %<PRIuMAX> (useu --force si no)"
+msgid ""
+"gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
+msgstr ""
+"gc ja s'està executant en la màquina «%s» pid %<PRIuMAX> (useu --force si no)"
 
 #: builtin/gc.c:487
-msgid "There are too many unreachable loose objects; run 'git prune' to remove them."
-msgstr "Hi ha massa objectes solts inabastables; executeu 'git prune' per a eliminar-los."
+msgid ""
+"There are too many unreachable loose objects; run 'git prune' to remove them."
+msgstr ""
+"Hi ha massa objectes solts inabastables; executeu 'git prune' per a eliminar-"
+"los."
 
 #: builtin/grep.c:27
 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
@@ -8904,7 +9154,8 @@ msgstr "imprimeix una línia buida entre coincidències de fitxers distints"
 #: builtin/grep.c:851
 msgid "show filename only once above matches from same file"
 msgstr ""
-"mostra el nom de fitxer només una vegada a dalt de les coincidències del mateix fitxer"
+"mostra el nom de fitxer només una vegada a dalt de les coincidències del "
+"mateix fitxer"
 
 #: builtin/grep.c:854
 msgid "show <n> context lines before and after matches"
@@ -8952,7 +9203,9 @@ msgstr "indica coincidència amb estat de sortida sense sortida textual"
 
 #: builtin/grep.c:888
 msgid "show only matches from files that match all patterns"
-msgstr "mostra només les coincidències dels fitxers que coincideixin amb tots els patrons"
+msgstr ""
+"mostra només les coincidències dels fitxers que coincideixin amb tots els "
+"patrons"
 
 #: builtin/grep.c:890
 msgid "show parse tree for grep expression"
@@ -9014,10 +9267,11 @@ msgstr "s'han donat ambdós --caches i arbres."
 
 #: builtin/hash-object.c:83
 msgid ""
-"git hash-object [-t <type>] [-w] [--path=<file> | --no-filters] [--stdin] [--] <file>..."
+"git hash-object [-t <type>] [-w] [--path=<file> | --no-filters] [--stdin] "
+"[--] <file>..."
 msgstr ""
-"git hash-object [-t <tipus>] [-w] [--path=<fitxer> | --no-filters] [--stdin] [--] "
-"<fitxer>..."
+"git hash-object [-t <tipus>] [-w] [--path=<fitxer> | --no-filters] [--stdin] "
+"[--] <fitxer>..."
 
 #: builtin/hash-object.c:84
 msgid "git hash-object  --stdin-paths"
@@ -9044,9 +9298,11 @@ msgid "store file as is without filters"
 msgstr "emmagatzema el fitxer tal com és sense filtres"
 
 #: builtin/hash-object.c:102
-msgid "just hash any random garbage to create corrupt objects for debugging Git"
+msgid ""
+"just hash any random garbage to create corrupt objects for debugging Git"
 msgstr ""
-"només suma qualsevol brossa aleatòria per a crear objectes malmesos per a depurar al Git"
+"només suma qualsevol brossa aleatòria per a crear objectes malmesos per a "
+"depurar al Git"
 
 #: builtin/hash-object.c:103
 msgid "process file as it were from this path"
@@ -9258,7 +9514,8 @@ msgstr "la inflació ha retornat %d"
 
 #: builtin/index-pack.c:530
 msgid "offset value overflow for delta base object"
-msgstr "desbordament de valor de desplaçament per a l'objecte base de diferències"
+msgstr ""
+"desbordament de valor de desplaçament per a l'objecte base de diferències"
 
 #: builtin/index-pack.c:538
 msgid "delta base offset is out of bound"
@@ -9278,7 +9535,8 @@ msgstr "no es pot fer pread en el fitxer de paquet"
 msgid "premature end of pack file, %<PRIuMAX> byte missing"
 msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
 msgstr[0] "el final del fitxer de paquet és prematur, manca %<PRIuMAX> octet"
-msgstr[1] "el final del fitxer de paquet és prematur, manquen %<PRIuMAX> octets"
+msgstr[1] ""
+"el final del fitxer de paquet és prematur, manquen %<PRIuMAX> octets"
 
 #: builtin/index-pack.c:605
 msgid "serious inflate inconsistency"
@@ -9290,7 +9548,8 @@ msgstr "hi ha una inconsistència seriosa d'inflació"
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "S'HA TROBAT UNA COL·LISIÓ SHA1 AMB %s !"
 
-#: builtin/index-pack.c:753 builtin/pack-objects.c:182 builtin/pack-objects.c:276
+#: builtin/index-pack.c:753 builtin/pack-objects.c:182
+#: builtin/pack-objects.c:276
 #, c-format
 msgid "unable to read %s"
 msgstr "no s'ha pogut llegir %s"
@@ -9454,8 +9713,8 @@ msgstr[1] "longitud de cadena = %d: %lu objectes"
 msgid "Cannot come back to cwd"
 msgstr "No es pot tornar al directori de treball actual"
 
-#: builtin/index-pack.c:1724 builtin/index-pack.c:1727 builtin/index-pack.c:1743
-#: builtin/index-pack.c:1747
+#: builtin/index-pack.c:1724 builtin/index-pack.c:1727
+#: builtin/index-pack.c:1743 builtin/index-pack.c:1747
 #, c-format
 msgid "bad %s"
 msgstr "%s incorrecte"
@@ -9771,7 +10030,8 @@ msgid ""
 "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 ""
-"S'ha produït un error en obtenir la font. Si voleu registrar la comissió base\n"
+"S'ha produït un error en obtenir la font. Si voleu registrar la comissió "
+"base\n"
 "automàticament, useu git branch --set-upstream-to per a\n"
 "seguir una branca remota. O podeu especificar la comissió base manualment\n"
 "amb --base=<id-de-comissió-base>."
@@ -9858,7 +10118,8 @@ msgstr "no incloguis pedaços que coincideixin amb comissions a la font"
 
 #: builtin/log.c:1478
 msgid "show patch format instead of default (patch + stat)"
-msgstr "mostra el format de pedaç en lloc del per defecte (pedaç + estadístiques)"
+msgstr ""
+"mostra el format de pedaç en lloc del per defecte (pedaç + estadístiques)"
 
 #: builtin/log.c:1480
 msgid "Messaging"
@@ -9890,7 +10151,8 @@ msgstr "identitat"
 
 #: builtin/log.c:1488
 msgid "set From address to <ident> (or committer ident if absent)"
-msgstr "estableix l'adreça From a <identitat> (o la identitat del comitent si manca)"
+msgstr ""
+"estableix l'adreça From a <identitat> (o la identitat del comitent si manca)"
 
 #: builtin/log.c:1490
 msgid "message-id"
@@ -9997,8 +10259,11 @@ msgstr "git cherry [-v] [<font> [<cap> [<límit>]]]"
 
 #: builtin/log.c:1921
 #, c-format
-msgid "Could not find a tracked remote branch, please specify <upstream> manually.\n"
-msgstr "No s'ha pogut trobar una branca remota seguida. Especifiqueu <font> manualment.\n"
+msgid ""
+"Could not find a tracked remote branch, please specify <upstream> manually.\n"
+msgstr ""
+"No s'ha pogut trobar una branca remota seguida. Especifiqueu <font> "
+"manualment.\n"
 
 #: builtin/ls-files.c:468
 msgid "git ls-files [<options>] [<file>...]"
@@ -10018,7 +10283,8 @@ msgstr "usa lletres minúscules per als fitxers 'fsmonitor clean'"
 
 #: builtin/ls-files.c:523
 msgid "show cached files in the output (default)"
-msgstr "mostra en la sortida els fitxers desats en la memòria cau (per defecte)"
+msgstr ""
+"mostra en la sortida els fitxers desats en la memòria cau (per defecte)"
 
 #: builtin/ls-files.c:525
 msgid "show deleted files in the output"
@@ -10098,7 +10364,8 @@ msgstr "arbre"
 
 #: builtin/ls-files.c:567
 msgid "pretend that paths removed since <tree-ish> are still present"
-msgstr "pretén que els camins eliminats després de <arbre> encara siguin presents"
+msgstr ""
+"pretén que els camins eliminats després de <arbre> encara siguin presents"
 
 #: builtin/ls-files.c:569
 msgid "show debugging data"
@@ -10185,7 +10452,8 @@ msgstr "usa els noms de camí complets"
 
 #: builtin/ls-tree.c:144
 msgid "list entire tree; not just current directory (implies --full-name)"
-msgstr "llista l'arbre sencer; no només el directori actual (implica --full-name)"
+msgstr ""
+"llista l'arbre sencer; no només el directori actual (implica --full-name)"
 
 #: builtin/mailsplit.c:241
 #, c-format
@@ -10238,7 +10506,8 @@ msgstr "(sinònim de --stat)"
 #: builtin/merge.c:207 builtin/pull.c:146
 msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr ""
-"afegeix (com a màxim <n>) entrades del registre curt al missatge de comissió de fusió"
+"afegeix (com a màxim <n>) entrades del registre curt al missatge de comissió "
+"de fusió"
 
 #: builtin/merge.c:210 builtin/pull.c:152
 msgid "create a single commit instead of doing a merge"
@@ -10264,7 +10533,8 @@ msgstr "avorta si l'avanç ràpid no és possible"
 msgid "verify that the named commit has a valid GPG signature"
 msgstr "verifica que la comissió anomenada tingui una signatura GPG vàlida"
 
-#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171 builtin/revert.c:109
+#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171
+#: builtin/revert.c:109
 msgid "strategy"
 msgstr "estratègia"
 
@@ -10363,7 +10633,8 @@ msgstr "No s'ha pogut llegir de «%s»"
 #: builtin/merge.c:758
 #, c-format
 msgid "Not committing merge; use 'git commit' to complete the merge.\n"
-msgstr "No s'està cometent la fusió; useu 'git commit' per a completar la fusió.\n"
+msgstr ""
+"No s'està cometent la fusió; useu 'git commit' per a completar la fusió.\n"
 
 #: builtin/merge.c:764
 #, c-format
@@ -10394,7 +10665,8 @@ msgstr "Meravellós.\n"
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr ""
-"La fusió automàtica ha fallat; arregleu els conflictes i després cometeu el resultat.\n"
+"La fusió automàtica ha fallat; arregleu els conflictes i després cometeu el "
+"resultat.\n"
 
 #: builtin/merge.c:912
 msgid "No current branch."
@@ -10469,7 +10741,9 @@ msgstr "No podeu combinar --squash amb --no-ff."
 
 #: builtin/merge.c:1275
 msgid "No commit specified and merge.defaultToUpstream not set."
-msgstr "No hi ha una comissió especificada i merge.defaultToUpstream no està establert."
+msgstr ""
+"No hi ha una comissió especificada i merge.defaultToUpstream no està "
+"establert."
 
 #: builtin/merge.c:1292
 msgid "Squash commit into empty head not supported yet"
@@ -10568,7 +10842,8 @@ msgstr "S'està usant el %s per a preparar la resolució a mà.\n"
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr ""
-"La fusió automàtica ha sortit bé; s'ha aturat abans de cometre com s'havia demanat\n"
+"La fusió automàtica ha sortit bé; s'ha aturat abans de cometre com s'havia "
+"demanat\n"
 
 #: builtin/merge-base.c:30
 msgid "git merge-base [-a | --all] <commit> <commit>..."
@@ -10608,15 +10883,16 @@ msgstr "és la primera un avantpassat de l'altre?"
 
 #: builtin/merge-base.c:228
 msgid "find where <commit> forked from reflog of <ref>"
-msgstr "troba on <comissió> s'ha bifurcat del registre de referències de <referència>"
+msgstr ""
+"troba on <comissió> s'ha bifurcat del registre de referències de <referència>"
 
 #: builtin/merge-file.c:9
 msgid ""
-"git merge-file [<options>] [-L <name1> [-L <orig> [-L <name2>]]] <file1> <orig-file> "
-"<file2>"
+"git merge-file [<options>] [-L <name1> [-L <orig> [-L <name2>]]] <file1> "
+"<orig-file> <file2>"
 msgstr ""
-"git merge-file [<opcions>] [-L <nom1> [-L <original> [-L <nom2>]]] <fitxer1> <fitxer-"
-"original> <fitxer2>"
+"git merge-file [<opcions>] [-L <nom1> [-L <original> [-L <nom2>]]] <fitxer1> "
+"<fitxer-original> <fitxer2>"
 
 #: builtin/merge-file.c:33
 msgid "send results to standard output"
@@ -10709,7 +10985,8 @@ msgstr "El directori %s és en l'índex i no hi ha cap submòdul?"
 #: builtin/mv.c:85 builtin/rm.c:289
 msgid "Please stage your changes to .gitmodules or stash them to proceed"
 msgstr ""
-"Feu «stage» dels vostres canvis a .gitmodules o feu «stash» dels mateixos per a procedir"
+"Feu «stage» dels vostres canvis a .gitmodules o feu «stash» dels mateixos "
+"per a procedir"
 
 #: builtin/mv.c:103
 #, c-format
@@ -10840,37 +11117,40 @@ msgstr "git notes [--ref <referència-de-notes>] [llista [<objecte>]]"
 
 #: builtin/notes.c:27
 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] [-m <msg> | -F <file> "
+"| (-c | -C) <object>] [<object>]"
 msgstr ""
-"git notes [--ref <referència-de-notes>] add [-f] [--allow-empty] [-m <missatge> | -F "
-"<fitxer> | (-c | -C) <objecte>] [<objecte>]"
+"git notes [--ref <referència-de-notes>] add [-f] [--allow-empty] [-m "
+"<missatge> | -F <fitxer> | (-c | -C) <objecte>] [<objecte>]"
 
 #: builtin/notes.c:28
 msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>"
-msgstr "git notes [--ref <referència-de-notes>] copy [-f] <d'objecte> <a-objecte>"
+msgstr ""
+"git notes [--ref <referència-de-notes>] copy [-f] <d'objecte> <a-objecte>"
 
 #: builtin/notes.c:29
 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] [-m <msg> | -F <file> | "
+"(-c | -C) <object>] [<object>]"
 msgstr ""
-"git notes [--ref <referència-de-notes>] append [--allow-empty] [-m <missatge> | -F "
-"<fitxer> | (-c | -C) <objecte>] [<objecte>]"
+"git notes [--ref <referència-de-notes>] append [--allow-empty] [-m "
+"<missatge> | -F <fitxer> | (-c | -C) <objecte>] [<objecte>]"
 
 #: builtin/notes.c:30
 msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]"
-msgstr "git notes [--ref <referència-de-notes>] edit [--allow-empty] [<objecte>]"
+msgstr ""
+"git notes [--ref <referència-de-notes>] edit [--allow-empty] [<objecte>]"
 
 #: builtin/notes.c:31
 msgid "git notes [--ref <notes-ref>] show [<object>]"
 msgstr "git notes [--ref <referència-de-notes>] show [<objecte>]"
 
 #: builtin/notes.c:32
-msgid "git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>"
+msgid ""
+"git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>"
 msgstr ""
-"git notes [--ref <referència-de-notes>] merge [-v | -q] [-s <estratègia>] <referència-de-"
-"notes>"
+"git notes [--ref <referència-de-notes>] merge [-v | -q] [-s <estratègia>] "
+"<referència-de-notes>"
 
 #: builtin/notes.c:33
 msgid "git notes merge --commit [-v | -q]"
@@ -10964,7 +11244,8 @@ msgstr "S'ha produït un error en finalitzar 'show' per a l'objecte «%s»"
 
 #: builtin/notes.c:195
 msgid "please supply the note contents using either -m or -F option"
-msgstr "especifiqueu el contingut de la nota fent servir l'opció -m o l'opció -F"
+msgstr ""
+"especifiqueu el contingut de la nota fent servir l'opció -m o l'opció -F"
 
 #: builtin/notes.c:204
 msgid "unable to write note object"
@@ -10985,9 +11266,9 @@ msgstr "no es pot llegir «%s»"
 msgid "could not open or read '%s'"
 msgstr "no s'ha pogut obrir o llegir «%s»"
 
-#: builtin/notes.c:255 builtin/notes.c:306 builtin/notes.c:308 builtin/notes.c:376
-#: builtin/notes.c:431 builtin/notes.c:517 builtin/notes.c:522 builtin/notes.c:600
-#: builtin/notes.c:662
+#: builtin/notes.c:255 builtin/notes.c:306 builtin/notes.c:308
+#: builtin/notes.c:376 builtin/notes.c:431 builtin/notes.c:517
+#: builtin/notes.c:522 builtin/notes.c:600 builtin/notes.c:662
 #, c-format
 msgid "failed to resolve '%s' as a valid ref."
 msgstr "s'ha produït un error en resoldre «%s» com a referència vàlida."
@@ -11020,9 +11301,9 @@ msgstr "s'ha produït un error en copiar les notes de «%s» a «%s»"
 msgid "refusing to %s notes in %s (outside of refs/notes/)"
 msgstr "s'està refusant %s les notes en %s (fora de refs/notes/)"
 
-#: builtin/notes.c:369 builtin/notes.c:424 builtin/notes.c:500 builtin/notes.c:512
-#: builtin/notes.c:588 builtin/notes.c:655 builtin/notes.c:805 builtin/notes.c:952
-#: builtin/notes.c:973
+#: builtin/notes.c:369 builtin/notes.c:424 builtin/notes.c:500
+#: builtin/notes.c:512 builtin/notes.c:588 builtin/notes.c:655
+#: builtin/notes.c:805 builtin/notes.c:952 builtin/notes.c:973
 msgid "too many parameters"
 msgstr "massa paràmetres"
 
@@ -11058,11 +11339,11 @@ msgstr "reemplaça les notes existents"
 #: builtin/notes.c:441
 #, c-format
 msgid ""
-"Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite existing "
-"notes"
+"Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite "
+"existing notes"
 msgstr ""
-"No es poden afegir les notes. S'han trobat notes existents de l'objecte %s. Useu '-f' "
-"per a sobreescriure les notes existents."
+"No es poden afegir les notes. S'han trobat notes existents de l'objecte %s. "
+"Useu '-f' per a sobreescriure les notes existents."
 
 #: builtin/notes.c:456 builtin/notes.c:535
 #, c-format
@@ -11080,7 +11361,8 @@ msgstr "llegeix els objectes des de stdin"
 
 #: builtin/notes.c:490
 msgid "load rewriting config for <command> (implies --stdin)"
-msgstr "carrega la configuració de reescriptura per a <ordre> (implica --stdin)"
+msgstr ""
+"carrega la configuració de reescriptura per a <ordre> (implica --stdin)"
 
 #: builtin/notes.c:508
 msgid "too few parameters"
@@ -11089,11 +11371,11 @@ msgstr "hi ha massa pocs paràmetres"
 #: builtin/notes.c:529
 #, c-format
 msgid ""
-"Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite existing "
-"notes"
+"Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite "
+"existing notes"
 msgstr ""
-"No es poden copiar les notes. S'han trobat notes existents de l'objecte %s. Useu '-f' "
-"per a sobreescriure les notes existents."
+"No es poden copiar les notes. S'han trobat notes existents de l'objecte %s. "
+"Useu '-f' per a sobreescriure les notes existents."
 
 #: builtin/notes.c:541
 #, c-format
@@ -11119,7 +11401,8 @@ msgstr "s'ha produït un error en suprimir la referència NOTES_MERGE_REF"
 
 #: builtin/notes.c:692
 msgid "failed to remove 'git notes merge' worktree"
-msgstr "s'ha produït un error en eliminar l'arbre de treball de 'git notes merge'"
+msgstr ""
+"s'ha produït un error en eliminar l'arbre de treball de 'git notes merge'"
 
 #: builtin/notes.c:712
 msgid "failed to read ref NOTES_MERGE_PARTIAL"
@@ -11156,10 +11439,11 @@ msgstr "Opcions de fusió"
 
 #: builtin/notes.c:778
 msgid ""
-"resolve notes conflicts using the given strategy (manual/ours/theirs/union/cat_sort_uniq)"
-msgstr ""
-"resol els conflictes de nota usant l'estratègia donada (manual/ours/theirs/union/"
+"resolve notes conflicts using the given strategy (manual/ours/theirs/union/"
 "cat_sort_uniq)"
+msgstr ""
+"resol els conflictes de nota usant l'estratègia donada (manual/ours/theirs/"
+"union/cat_sort_uniq)"
 
 #: builtin/notes.c:780
 msgid "Committing unmerged notes"
@@ -11199,17 +11483,19 @@ msgstr "una fusió de notes a %s ja està en curs a %s"
 #, c-format
 msgid "failed to store link to current notes ref (%s)"
 msgstr ""
-"s'ha produït un error en emmagatzemar l'enllaç a la referència de notes actual (%s)"
+"s'ha produït un error en emmagatzemar l'enllaç a la referència de notes "
+"actual (%s)"
 
 #: builtin/notes.c:868
 #, c-format
 msgid ""
-"Automatic notes merge failed. Fix conflicts in %s and commit the result with 'git notes "
-"merge --commit', or abort the merge with 'git notes merge --abort'.\n"
-msgstr ""
-"La fusió de notes automàtica ha fallat. Arregleu els conflictes en %s i cometeu el "
-"resultat amb 'git notes merge --commit', o avorteu la fusió amb 'git notes merge --"
+"Automatic notes merge failed. Fix conflicts in %s and commit the result with "
+"'git notes merge --commit', or abort the merge with 'git notes merge --"
 "abort'.\n"
+msgstr ""
+"La fusió de notes automàtica ha fallat. Arregleu els conflictes en %s i "
+"cometeu el resultat amb 'git notes merge --commit', o avorteu la fusió amb "
+"'git notes merge --abort'.\n"
 
 #: builtin/notes.c:890
 #, c-format
@@ -11246,16 +11532,18 @@ msgid "unknown subcommand: %s"
 msgstr "subordre desconeguda: %s"
 
 #: builtin/pack-objects.c:33
-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 [<opcions>...] [< <llista-de-referències> | < <llista-de-"
-"objectes>]"
+"git pack-objects --stdout [<opcions>...] [< <llista-de-referències> | < "
+"<llista-de-objectes>]"
 
 #: builtin/pack-objects.c:34
-msgid "git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
+msgid ""
+"git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
 msgstr ""
-"git pack-objects [<opcions>...] <nom-base> [< <llista-de-referències> | < <llista-de-"
-"objectes>]"
+"git pack-objects [<opcions>...] <nom-base> [< <llista-de-referències> | < "
+"<llista-de-objectes>]"
 
 #: builtin/pack-objects.c:195 builtin/pack-objects.c:198
 #, c-format
@@ -11265,8 +11553,8 @@ msgstr "error de deflació (%d)"
 #: builtin/pack-objects.c:791
 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
 msgstr ""
-"s'està inhabilitant l'escriptura de mapes de bits, es divideixen els paquets a causa de "
-"pack.packSizeLimit"
+"s'està inhabilitant l'escriptura de mapes de bits, es divideixen els paquets "
+"a causa de pack.packSizeLimit"
 
 #: builtin/pack-objects.c:804
 msgid "Writing objects"
@@ -11275,11 +11563,12 @@ msgstr "S'estan escrivint els objectes"
 #: builtin/pack-objects.c:1084
 msgid "disabling bitmap writing, as some objects are not being packed"
 msgstr ""
-"s'està inhabilitant l'escriptura de mapes de bits, perquè alguns objectes no s'empaqueten"
+"s'està inhabilitant l'escriptura de mapes de bits, perquè alguns objectes no "
+"s'empaqueten"
 
 #: builtin/pack-objects.c:2454
 msgid "Compressing objects"
-msgstr "S'estan comprimint objectes"
+msgstr "S'estan comprimint els objectes"
 
 #: builtin/pack-objects.c:2625
 msgid "invalid value for --missing"
@@ -11317,7 +11606,9 @@ msgstr "versió[,desplaçament]"
 
 #: builtin/pack-objects.c:2971
 msgid "write the pack index file in the specified idx format version"
-msgstr "escriu el fitxer d'índex de paquet en la versió de format d'índex especificada"
+msgstr ""
+"escriu el fitxer d'índex de paquet en la versió de format d'índex "
+"especificada"
 
 #: builtin/pack-objects.c:2974
 msgid "maximum size of each output pack file"
@@ -11337,11 +11628,13 @@ msgstr "limita la finestra d'empaquetament per objectes"
 
 #: builtin/pack-objects.c:2982
 msgid "limit pack window by memory in addition to object limit"
-msgstr "limita la finestra d'empaquetament per memòria a més del límit d'objectes"
+msgstr ""
+"limita la finestra d'empaquetament per memòria a més del límit d'objectes"
 
 #: builtin/pack-objects.c:2984
 msgid "maximum length of delta chain allowed in the resulting pack"
-msgstr "longitud màxima de la cadena de diferències permesa en el paquet resultant"
+msgstr ""
+"longitud màxima de la cadena de diferències permesa en el paquet resultant"
 
 #: builtin/pack-objects.c:2986
 msgid "reuse existing deltas"
@@ -11378,7 +11671,8 @@ msgstr "inclou els objectes abastables de qualsevol referència"
 #: builtin/pack-objects.c:3004
 msgid "include objects referred by reflog entries"
 msgstr ""
-"inclou els objectes als quals facin referència les entrades del registre de referències"
+"inclou els objectes als quals facin referència les entrades del registre de "
+"referències"
 
 #: builtin/pack-objects.c:3007
 msgid "include objects referred to by the index"
@@ -11390,7 +11684,8 @@ msgstr "emet el paquet a stdout"
 
 #: builtin/pack-objects.c:3012
 msgid "include tag objects that refer to objects to be packed"
-msgstr "inclou els objectes d'etiqueta que facin referència als objectes a empaquetar"
+msgstr ""
+"inclou els objectes d'etiqueta que facin referència als objectes a empaquetar"
 
 #: builtin/pack-objects.c:3014
 msgid "keep unreachable objects"
@@ -11427,7 +11722,8 @@ msgstr "no amaguis les comissions per empelt"
 #: builtin/pack-objects.c:3031
 msgid "use a bitmap index if available to speed up counting objects"
 msgstr ""
-"usa un índex de mapa de bits, si està disponible, per a accelerar el recompte d'objectes"
+"usa un índex de mapa de bits, si està disponible, per a accelerar el "
+"recompte d'objectes"
 
 #: builtin/pack-objects.c:3033
 msgid "write a bitmap index together with the pack index"
@@ -11512,7 +11808,8 @@ msgstr "permet l'avanç ràpid"
 
 #: builtin/pull.c:170
 msgid "automatically stash/stash pop before and after rebase"
-msgstr "fes «stash» i «stash pop» automàticament abans i després de fer «rebase»"
+msgstr ""
+"fes «stash» i «stash pop» automàticament abans i després de fer «rebase»"
 
 #: builtin/pull.c:186
 msgid "Options related to fetching"
@@ -11528,14 +11825,18 @@ msgid "Invalid value for pull.ff: %s"
 msgstr "Valor no vàlid per a pull.ff: %s"
 
 #: builtin/pull.c:415
-msgid "There is no candidate for rebasing against among the refs that you just fetched."
+msgid ""
+"There is no candidate for rebasing against among the refs that you just "
+"fetched."
 msgstr ""
-"No hi ha cap candidat sobre el qual fer «rebase» entre les referències que acabeu "
-"d'obtenir."
+"No hi ha cap candidat sobre el qual fer «rebase» entre les referències que "
+"acabeu d'obtenir."
 
 #: builtin/pull.c:417
-msgid "There are no candidates for merging among the refs that you just fetched."
-msgstr "No hi ha candidats per a fusionar entre les referències que acabeu d'obtenir."
+msgid ""
+"There are no candidates for merging among the refs that you just fetched."
+msgstr ""
+"No hi ha candidats per a fusionar entre les referències que acabeu d'obtenir."
 
 #: builtin/pull.c:418
 msgid ""
@@ -11572,7 +11873,8 @@ msgstr "Especifiqueu amb quina branca voleu fusionar."
 msgid "See git-pull(1) for details."
 msgstr "Vegeu git-pull(1) per detalls."
 
-#: builtin/pull.c:433 builtin/pull.c:439 builtin/pull.c:448 git-parse-remote.sh:64
+#: builtin/pull.c:433 builtin/pull.c:439 builtin/pull.c:448
+#: git-parse-remote.sh:64
 msgid "<remote>"
 msgstr "<remot>"
 
@@ -11586,8 +11888,11 @@ msgid "There is no tracking information for the current branch."
 msgstr "No hi ha cap informació de seguiment per a la branca actual."
 
 #: builtin/pull.c:450 git-parse-remote.sh:95
-msgid "If you wish to set tracking information for this branch you can do so with:"
-msgstr "Si voleu establir informació de seguiment per a aquesta branca, podeu fer-ho amb:"
+msgid ""
+"If you wish to set tracking information for this branch you can do so with:"
+msgstr ""
+"Si voleu establir informació de seguiment per a aquesta branca, podeu fer-ho "
+"amb:"
 
 #: builtin/pull.c:455
 #, c-format
@@ -11608,7 +11913,8 @@ msgstr "l'opció --[no-]-autostash és vàlid només amb --rebase."
 
 #: builtin/pull.c:875
 msgid "Updating an unborn branch with changes added to the index."
-msgstr "S'està actualitzant una branca no nascuda amb canvis afegits a l'índex."
+msgstr ""
+"S'està actualitzant una branca no nascuda amb canvis afegits a l'índex."
 
 #: builtin/pull.c:878
 msgid "pull with rebase"
@@ -11640,7 +11946,8 @@ msgid ""
 "to recover."
 msgstr ""
 "No es pot avançar ràpidament el vostre arbre de treball.\n"
-"Després d'assegurar que hàgiu desat qualsevol cosa preciosa de la sortida de\n"
+"Després d'assegurar que hàgiu desat qualsevol cosa preciosa de la sortida "
+"de\n"
 "$ git diff %s\n"
 "executeu\n"
 "$ git reset --hard\n"
@@ -11656,7 +11963,9 @@ msgstr "No es pot fer «rebase» sobre múltiples branques."
 
 #: builtin/pull.c:935
 msgid "cannot rebase with locally recorded submodule modifications"
-msgstr "no es pot fer «rebase» amb modificacions als submòduls enregistrades localment"
+msgstr ""
+"no es pot fer «rebase» amb modificacions als submòduls enregistrades "
+"localment"
 
 #: builtin/push.c:17
 msgid "git push [<options>] [<repository> [<refspec>...]]"
@@ -11676,7 +11985,8 @@ msgid ""
 "To choose either option permanently, see push.default in 'git help config'."
 msgstr ""
 "\n"
-"Per a triar qualsevol opció permanentment, vegeu push.default a 'git help config'."
+"Per a triar qualsevol opció permanentment, vegeu push.default a 'git help "
+"config'."
 
 #: builtin/push.c:149
 #, c-format
@@ -11734,7 +12044,8 @@ msgstr ""
 #: builtin/push.c:186
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
-msgstr "La branca actual %s té múltiples branques fonts, s'està refusant pujar."
+msgstr ""
+"La branca actual %s té múltiples branques fonts, s'està refusant pujar."
 
 #: builtin/push.c:189
 #, c-format
@@ -11748,10 +12059,11 @@ msgstr ""
 "quina branca remota."
 
 #: builtin/push.c:248
-msgid "You didn't specify any refspecs to push, and push.default is \"nothing\"."
+msgid ""
+"You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
-"No heu especificat cap especificació de referència a pujar, i push.default és \"nothing"
-"\"."
+"No heu especificat cap especificació de referència a pujar, i push.default "
+"és \"nothing\"."
 
 #: builtin/push.c:255
 msgid ""
@@ -11786,8 +12098,8 @@ msgid ""
 "(e.g., 'git pull ...') before pushing again.\n"
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
-"S'han rebutjat les actualitzacions perquè el remot conté treball\n"
-"que no teniu localment. Això acostumar a ser causat per un altre dipòsit\n"
+"S'han rebutjat les actualitzacions perquè el remot conté canvis\n"
+"que no teniu localment. Això acostuma a ser causat per un altre dipòsit\n"
 "que ha pujat a la mateixa referència. Pot ser que primer vulgueu\n"
 "integrar els canvis remots (per exemple, 'git pull ...') abans de\n"
 "pujar de nou.\n"
@@ -11795,7 +12107,8 @@ msgstr ""
 
 #: builtin/push.c:274
 msgid "Updates were rejected because the tag already exists in the remote."
-msgstr "S'han rebutjat les actualitzacions perquè l'etiqueta ja existeix en el remot."
+msgstr ""
+"S'han rebutjat les actualitzacions perquè l'etiqueta ja existeix en el remot."
 
 #: builtin/push.c:277
 msgid ""
@@ -11826,7 +12139,8 @@ msgstr "dipòsit incorrecte «%s»"
 #: builtin/push.c:373
 msgid ""
 "No configured push destination.\n"
-"Either specify the URL from the command-line or configure a remote repository using\n"
+"Either specify the URL from the command-line or configure a remote "
+"repository using\n"
 "\n"
 "    git remote add <name> <url>\n"
 "\n"
@@ -11835,8 +12149,8 @@ msgid ""
 "    git push <name>\n"
 msgstr ""
 "No hi ha cap destí de pujada configurat.\n"
-"Especifiqueu l'URL des de la línia d'ordres o bé configureu un dipòsit remot fent "
-"servir\n"
+"Especifiqueu l'URL des de la línia d'ordres o bé configureu un dipòsit remot "
+"fent servir\n"
 "\n"
 "    git remote add <nom> <url>\n"
 "\n"
@@ -11904,7 +12218,8 @@ msgstr "controla la pujada recursiva dels submòduls"
 msgid "use thin pack"
 msgstr "usa el paquet prim"
 
-#: builtin/push.c:552 builtin/push.c:553 builtin/send-pack.c:160 builtin/send-pack.c:161
+#: builtin/push.c:552 builtin/push.c:553 builtin/send-pack.c:160
+#: builtin/send-pack.c:161
 msgid "receive pack program"
 msgstr "programa que rep els paquets"
 
@@ -11954,13 +12269,13 @@ msgstr "les opcions de pujada no han de tenir caràcters de línia nova"
 
 #: builtin/read-tree.c:40
 msgid ""
-"git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>) [-u [--"
-"exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--index-output=<file>] "
-"(--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"
+"git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>) "
+"[-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--"
+"index-output=<file>] (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"
 msgstr ""
-"git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>) [-u [--"
-"exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--index-"
-"output=<fitxer>] (--empty | <arbre1> [<arbre2> [<arbre3>]])"
+"git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>) "
+"[-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--"
+"index-output=<fitxer>] (--empty | <arbre1> [<arbre2> [<arbre3>]])"
 
 #: builtin/read-tree.c:121
 msgid "write resulting index to <file>"
@@ -12150,11 +12465,11 @@ msgstr "git remote [-v | --verbose]"
 
 #: builtin/remote.c:14
 msgid ""
-"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--mirror=<fetch|"
-"push>] <name> <url>"
+"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
+"mirror=<fetch|push>] <name> <url>"
 msgstr ""
-"git remote add [-t <branca>] [-m <mestra>] [-f] [--tags | --no-tags] [--mirror=<fetch|"
-"push>] <nom> <url>"
+"git remote add [-t <branca>] [-m <mestra>] [-f] [--tags | --no-tags] [--"
+"mirror=<fetch|push>] <nom> <url>"
 
 #: builtin/remote.c:15 builtin/remote.c:35
 msgid "git remote rename <old> <new>"
@@ -12177,8 +12492,10 @@ msgid "git remote prune [-n | --dry-run] <name>"
 msgstr "git remote prune [-n | --dry-run] <nom>"
 
 #: builtin/remote.c:20
-msgid "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
-msgstr "git remote [-v | --verbose] update [-p | --prune] [(<grup> | <remot>)...]"
+msgid ""
+"git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
+msgstr ""
+"git remote [-v | --verbose] update [-p | --prune] [(<grup> | <remot>)...]"
 
 #: builtin/remote.c:21
 msgid "git remote set-branches [--add] <name> <branch>..."
@@ -12277,7 +12594,8 @@ msgstr "especificar una branca mestra no té sentit amb --mirror"
 
 #: builtin/remote.c:184
 msgid "specifying branches to track makes sense only with fetch mirrors"
-msgstr "especificar les branques a seguir té sentit només amb miralls d'obtenció"
+msgstr ""
+"especificar les branques a seguir té sentit només amb miralls d'obtenció"
 
 #: builtin/remote.c:191 builtin/remote.c:631
 #, c-format
@@ -12297,7 +12615,8 @@ msgstr "No s'ha pogut configurar la mestra «%s»"
 #: builtin/remote.c:337
 #, c-format
 msgid "Could not get fetch map for refspec %s"
-msgstr "No s'ha pogut obtenir el mapa d'obtenció de l'especificació de referència %s"
+msgstr ""
+"No s'ha pogut obtenir el mapa d'obtenció de l'especificació de referència %s"
 
 #: builtin/remote.c:438 builtin/remote.c:446
 msgid "(matching)"
@@ -12324,7 +12643,8 @@ msgid ""
 "\t%s\n"
 "\tPlease update the configuration manually if necessary."
 msgstr ""
-"No s'està actualitzant l'especificació de referències d'obtenció no per defecte\n"
+"No s'està actualitzant l'especificació de referències d'obtenció no per "
+"defecte\n"
 "\t%s\n"
 "\tActualitzeu la configuració manualment si és necessari."
 
@@ -12349,7 +12669,8 @@ msgstr[0] ""
 "Nota: Una branca fora de la jerarquia refs/remotes/ no s'ha eliminat;\n"
 "per a suprimir-la, useu:"
 msgstr[1] ""
-"Nota: Algunes branques fora de la jerarquia refs/remotes/ no s'han eliminat;\n"
+"Nota: Algunes branques fora de la jerarquia refs/remotes/ no s'han "
+"eliminat;\n"
 "per a suprimir-les, useu:"
 
 #: builtin/remote.c:810
@@ -12486,8 +12807,10 @@ msgstr "(desconegut)"
 
 #: builtin/remote.c:1171
 #, c-format
-msgid "  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
-msgstr "  Branca de HEAD (el HEAD remot és ambigu, pot ser un dels següents):\n"
+msgid ""
+"  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
+msgstr ""
+"  Branca de HEAD (la HEAD remot és ambigua, pot ser un dels següents):\n"
 
 #: builtin/remote.c:1183
 #, c-format
@@ -12527,7 +12850,7 @@ msgstr "suprimeix refs/remotes/<name>/HEAD"
 
 #: builtin/remote.c:1247
 msgid "Cannot determine remote HEAD"
-msgstr "No es pot determinar el HEAD remot"
+msgstr "No es pot determinar la HEAD remota"
 
 #: builtin/remote.c:1249
 msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
@@ -12656,8 +12979,10 @@ msgid ""
 "Incremental repacks are incompatible with bitmap indexes.  Use\n"
 "--no-write-bitmap-index or disable the pack.writebitmaps configuration."
 msgstr ""
-"Els reempaquetaments incrementals són incompatibles amb els índexs de bitmaps.  Useu\n"
-"--no-write-bitmap-index o inhabiliteu el paràmetre de configuració pack.writebitmaps."
+"Els reempaquetaments incrementals són incompatibles amb els índexs de "
+"bitmaps.  Useu\n"
+"--no-write-bitmap-index o inhabiliteu el paràmetre de configuració pack."
+"writebitmaps."
 
 #: builtin/repack.c:170
 msgid "pack everything in a single pack"
@@ -12714,7 +13039,8 @@ msgstr "octets"
 #: builtin/repack.c:194
 msgid "same as the above, but limit memory size instead of entries count"
 msgstr ""
-"el mateix que l'anterior, però limita la mida de memòria en lloc del nombre d'entrades"
+"el mateix que l'anterior, però limita la mida de memòria en lloc del nombre "
+"d'entrades"
 
 #: builtin/repack.c:196
 msgid "limits the maximum delta depth"
@@ -12783,11 +13109,11 @@ msgstr "etiqueta de fusió mal formada en la comissió «%s»"
 #: builtin/replace.c:374
 #, c-format
 msgid ""
-"original commit '%s' contains mergetag '%s' that is discarded; use --edit instead of --"
-"graft"
+"original commit '%s' contains mergetag '%s' that is discarded; use --edit "
+"instead of --graft"
 msgstr ""
-"la comissió original «%s» conté l'etiqueta de fusió «%s» que es descarta; useu --edit en "
-"lloc de --graft"
+"la comissió original «%s» conté l'etiqueta de fusió «%s» que es descarta; "
+"useu --edit en lloc de --graft"
 
 #: builtin/replace.c:407
 #, c-format
@@ -12840,8 +13166,10 @@ msgid "register clean resolutions in index"
 msgstr "registra les resolucions netes en l'índex"
 
 #: builtin/reset.c:29
-msgid "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
-msgstr "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<comissió>]"
+msgid ""
+"git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]"
+msgstr ""
+"git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<comissió>]"
 
 #: builtin/reset.c:30
 msgid "git reset [-q] [<tree-ish>] [--] <paths>..."
@@ -12934,7 +13262,9 @@ msgstr "--patch és incompatible amb --{hard,mixed,soft}"
 
 #: builtin/reset.c:347
 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead."
-msgstr "--mixed amb camins està en desús; useu 'git reset -- <camins>' en lloc d'això."
+msgstr ""
+"--mixed amb camins està en desús; useu 'git reset -- <camins>' en lloc "
+"d'això."
 
 #: builtin/reset.c:349
 #, c-format
@@ -13012,7 +13342,8 @@ msgstr ""
 "   or: git rev-parse --sq-quote [<paràmetre>...]\n"
 "   or: git rev-parse [<opcions>] [<paràmetre>...]\n"
 "\n"
-"Executeu \"git rev-parse --parseopt -h\" per més informació sobre l'ús inicial."
+"Executeu \"git rev-parse --parseopt -h\" per més informació sobre l'ús "
+"inicial."
 
 #: builtin/revert.c:23
 msgid "git revert [<options>] <commit-ish>..."
@@ -13108,10 +13439,10 @@ msgid_plural ""
 "file and the HEAD:"
 msgstr[0] ""
 "el fitxer següent té contingut «stage» diferent d'ambdós el\n"
-"fitxer i el HEAD:"
+"fitxer i la HEAD:"
 msgstr[1] ""
 "els fitxers següents tenen contingut «stage» diferent d'ambdós\n"
-"el fitxer i el HEAD:"
+"el fitxer i la HEAD:"
 
 #: builtin/rm.c:211
 msgid ""
@@ -13178,12 +13509,14 @@ msgstr "no s'ha pogut suprimir «%s»"
 
 #: builtin/send-pack.c:19
 msgid ""
-"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-"
-"pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> [<ref>...]\n"
+"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-"
+"receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> "
+"[<ref>...]\n"
 "  --all and explicit <ref> specification are mutually exclusive."
 msgstr ""
-"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<paquet-del-git-"
-"receive>] [--verbose] [--thin] [--atomic] [<màquina>:]<directori> [<referència>...]\n"
+"git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-"
+"pack=<paquet-del-git-receive>] [--verbose] [--thin] [--atomic] "
+"[<màquina>:]<directori> [<referència>...]\n"
 "  --all i especificació <referència> explícita són mútuament excloents."
 
 #: builtin/send-pack.c:162
@@ -13216,7 +13549,8 @@ msgstr "ordena la sortida segons el nombre de comissions per autor"
 
 #: builtin/shortlog.c:267
 msgid "Suppress commit descriptions, only provides commit count"
-msgstr "Omet les descripcions de comissió, només proveeix el recompte de comissions"
+msgstr ""
+"Omet les descripcions de comissió, només proveeix el recompte de comissions"
 
 #: builtin/shortlog.c:269
 msgid "Show the email address of each author"
@@ -13323,8 +13657,10 @@ msgid "show <n> most recent ref-log entries starting at base"
 msgstr "mostra les <n> entrades més recents començant a la base"
 
 #: builtin/show-branch.c:690
-msgid "--reflog is incompatible with --all, --remotes, --independent or --merge-base"
-msgstr "--reflog és incompatible amb --all, --remotes, --independent o --merge-base"
+msgid ""
+"--reflog is incompatible with --all, --remotes, --independent or --merge-base"
+msgstr ""
+"--reflog és incompatible amb --all, --remotes, --independent o --merge-base"
 
 #: builtin/show-branch.c:714
 msgid "no branches given, and HEAD is not valid"
@@ -13365,11 +13701,11 @@ msgstr "no es pot trobar la comissió %s (%s)"
 
 #: builtin/show-ref.c:10
 msgid ""
-"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --hash[=<n>]] "
-"[--abbrev[=<n>]] [--tags] [--heads] [--] [<pattern>...]"
+"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --"
+"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<pattern>...]"
 msgstr ""
-"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --hash[=<n>]] "
-"[--abbrev[=<n>]] [--tags] [--heads] [--] [<patró>...]"
+"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --"
+"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<patró>...]"
 
 #: builtin/show-ref.c:11
 msgid "git show-ref --exclude-existing[=<pattern>]"
@@ -13385,7 +13721,9 @@ msgstr "mostra només els caps (es pot combinar amb tags)"
 
 #: builtin/show-ref.c:161
 msgid "stricter reference checking, requires exact ref path"
-msgstr "comprovació de referència més estricta, requereix el camí de referència exacte"
+msgstr ""
+"comprovació de referència més estricta, requereix el camí de referència "
+"exacte"
 
 #: builtin/show-ref.c:164 builtin/show-ref.c:166
 msgid "show the HEAD reference, even if it would be filtered out"
@@ -13417,7 +13755,8 @@ msgstr "git stripspace [-c | --comment-lines]"
 
 #: builtin/stripspace.c:36
 msgid "skip and remove all lines starting with comment character"
-msgstr "omet i elimina totes les línies que comencin amb el caràcter de comentari"
+msgstr ""
+"omet i elimina totes les línies que comencin amb el caràcter de comentari"
 
 #: builtin/stripspace.c:39
 msgid "prepend comment character and space to each line"
@@ -13458,11 +13797,11 @@ msgstr "No s'ha trobat cap url per al camí de submòdul «%s» a .gitmodules"
 #: builtin/submodule--helper.c:498
 #, c-format
 msgid ""
-"could not lookup configuration '%s'. Assuming this repository is its own authoritative "
-"upstream."
+"could not lookup configuration '%s'. Assuming this repository is its own "
+"authoritative upstream."
 msgstr ""
-"no s'ha pogut trobar la configuració «%s». S'assumeix que aquest dipòsit és el seu "
-"dipòsit font autoritzat."
+"no s'ha pogut trobar la configuració «%s». S'assumeix que aquest dipòsit és "
+"el seu dipòsit font autoritzat."
 
 #: builtin/submodule--helper.c:509
 #, c-format
@@ -13477,13 +13816,16 @@ msgstr "S'ha registrat el submòdul «%s» (%s) per al camí «%s»\n"
 #: builtin/submodule--helper.c:523
 #, c-format
 msgid "warning: command update mode suggested for submodule '%s'\n"
-msgstr "advertència: se suggereix el mode d'actualització per ordre per al submòdul «%s»\n"
+msgstr ""
+"advertència: se suggereix el mode d'actualització per ordre per al submòdul "
+"«%s»\n"
 
 #: builtin/submodule--helper.c:530
 #, c-format
 msgid "Failed to register update mode for submodule path '%s'"
 msgstr ""
-"S'ha produït un error en registrar el mode d'actualització per al camí de submòdul «%s»"
+"S'ha produït un error en registrar el mode d'actualització per al camí de "
+"submòdul «%s»"
 
 #: builtin/submodule--helper.c:552
 msgid "Suppress output for initializing a submodule"
@@ -13513,7 +13855,9 @@ msgid "Suppress submodule status output"
 msgstr "Suprimeix la sortida de l'estat del submòdul"
 
 #: builtin/submodule--helper.c:712
-msgid "Use commit stored in the index instead of the one stored in the submodule HEAD"
+msgid ""
+"Use commit stored in the index instead of the one stored in the submodule "
+"HEAD"
 msgstr ""
 
 #: builtin/submodule--helper.c:713
@@ -13522,7 +13866,7 @@ msgstr "inclou recursivament els submòduls imbrincats"
 
 #: builtin/submodule--helper.c:718
 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
-msgstr  "git submodule status [--quiet] [--cached] [--recursive] [<camí>...]"
+msgstr "git submodule status [--quiet] [--cached] [--recursive] [<camí>...]"
 
 #: builtin/submodule--helper.c:742
 msgid "git submodule--helper name <path>"
@@ -13539,9 +13883,10 @@ msgid "failed to register url for submodule path '%s'"
 msgstr "s'ha produït un error en registrar l'url per al camí del submòdul «%s»"
 
 #: builtin/submodule--helper.c:826
-#,  c-format
+#, c-format
 msgid "failed to get the default remote for submodule '%s'"
-msgstr "s'ha produït un error en obtenir el remot per defecte pel submòdul «%s»"
+msgstr ""
+"s'ha produït un error en obtenir el remot per defecte pel submòdul «%s»"
 
 #: builtin/submodule--helper.c:837
 #, c-format
@@ -13563,18 +13908,20 @@ msgstr "git submodule--helper sync [--quiet] [--recursive] [<camí>]"
 #: builtin/submodule--helper.c:946
 #, c-format
 msgid ""
-"Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you really want to "
-"remove it including all of its history)"
+"Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you "
+"really want to remove it including all of its history)"
 msgstr ""
 "L'arbre de treball de submòdul «%s» conté un directori .git\n"
 "(useu 'rm -rf' si realment voleu eliminar-lo, incloent tota la seva història)"
 
 #: builtin/submodule--helper.c:958
 #, c-format
-msgid "Submodule work tree '%s' contains local modifications; use '-f' to discard them"
+msgid ""
+"Submodule work tree '%s' contains local modifications; use '-f' to discard "
+"them"
 msgstr ""
-"L'arbre de treball del submòdul «%s» conté modificacions locals; useu '-f' per "
-"a descartar-les"
+"L'arbre de treball del submòdul «%s» conté modificacions locals; useu '-f' "
+"per a descartar-les"
 
 #: builtin/submodule--helper.c:966
 #, c-format
@@ -13592,22 +13939,25 @@ msgid "could not create empty submodule directory %s"
 msgstr "no s'ha pogut crear el directori de submòdul buit %s"
 
 #: builtin/submodule--helper.c:993
-#, fuzzy, c-format
+#, c-format
 msgid "Submodule '%s' (%s) unregistered for path '%s'\n"
-msgstr "S'ha registrat el submòdul «%s» (%s) per al camí «%s»\n"
+msgstr "S'ha desregistrat el submòdul «%s» (%s) per al camí «%s»\n"
 
 #: builtin/submodule--helper.c:1022
 msgid "Remove submodule working trees even if they contain local changes"
-msgstr "Suprimeix els arbres de treball dels submòduls fins i tot si contenen canvis locals"
+msgstr ""
+"Suprimeix els arbres de treball dels submòduls fins i tot si contenen canvis "
+"locals"
 
 #: builtin/submodule--helper.c:1023
-#, fuzzy
 msgid "Unregister all submodules"
-msgstr "inclou recursivament als submòduls"
+msgstr "Desregistra recursivament tots els submòduls"
 
 #: builtin/submodule--helper.c:1028
-msgid "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
-msgstr  "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<camí>...]]"
+msgid ""
+"git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
+msgstr ""
+"git submodule deinit [--quiet] [-f | --force] [--all | [--] [<camí>...]]"
 
 #: builtin/submodule--helper.c:1042
 msgid "Use '--all' if you really want to deinitialize all submodules"
@@ -13650,11 +14000,11 @@ msgstr "força el progrés del clonatge"
 
 #: builtin/submodule--helper.c:1221
 msgid ""
-"git submodule--helper clone [--prefix=<path>] [--quiet] [--reference <repository>] [--"
-"name <name>] [--depth <depth>] --url <url> --path <path>"
+"git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
+"<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>"
 msgstr ""
-"git submodule--helper clone [--prefix=<camí>] [--quiet] [--reference <dipòsit>] [--name "
-"<nom>] [--depth <profunditat>] --url <url> --path <camí>"
+"git submodule--helper clone [--prefix=<camí>] [--quiet] [--reference "
+"<dipòsit>] [--name <nom>] [--depth <profunditat>] --url <url> --path <camí>"
 
 #: builtin/submodule--helper.c:1252
 #, c-format
@@ -13734,11 +14084,11 @@ msgstr "valor incorrecte per al paràmetre update"
 #: builtin/submodule--helper.c:1673
 #, c-format
 msgid ""
-"Submodule (%s) branch configured to inherit branch from superproject, but the "
-"superproject is not on any branch"
+"Submodule (%s) branch configured to inherit branch from superproject, but "
+"the superproject is not on any branch"
 msgstr ""
-"La branca de submòdul (%s) està configurada per a heretar la branca del superprojecte, "
-"però el superprojecte no és en cap branca"
+"La branca de submòdul (%s) està configurada per a heretar la branca del "
+"superprojecte, però el superprojecte no és en cap branca"
 
 #: builtin/submodule--helper.c:1789
 msgid "recurse into submodules"
@@ -13787,10 +14137,12 @@ msgid "reason of the update"
 msgstr "raó de l'actualització"
 
 #: builtin/tag.c:24
-msgid "git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <tagname> [<head>]"
+msgid ""
+"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <tagname> "
+"[<head>]"
 msgstr ""
-"git tag [-a | -s | -u <id-de-clau>] [-f] [-m <missatge> | -F <fitxer>] <nom-d'etiqueta> "
-"[<cap>]"
+"git tag [-a | -s | -u <id-de-clau>] [-f] [-m <missatge> | -F <fitxer>] <nom-"
+"d'etiqueta> [<cap>]"
 
 #: builtin/tag.c:25
 msgid "git tag -d <tagname>..."
@@ -13798,12 +14150,12 @@ msgstr "git tag -d <nom-d'etiqueta>..."
 
 #: builtin/tag.c:26
 msgid ""
-"git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--points-at "
-"<object>]\n"
+"git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--"
+"points-at <object>]\n"
 "\t\t[--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]"
 msgstr ""
-"git tag -l [-n[<nombre>]] [--contains <comissió>] [--no-contains <comissió>] [--points-"
-"at <objecte>]\n"
+"git tag -l [-n[<nombre>]] [--contains <comissió>] [--no-contains <comissió>] "
+"[--points-at <objecte>]\n"
 "\t\t[--format=<format>] [--[no-]merged [<comissió>]] [<patró>...]"
 
 #: builtin/tag.c:28
@@ -13839,13 +14191,14 @@ msgid ""
 "\n"
 "Write a message for tag:\n"
 "  %s\n"
-"Lines starting with '%c' will be kept; you may remove them yourself if you want to.\n"
+"Lines starting with '%c' will be kept; you may remove them yourself if you "
+"want to.\n"
 msgstr ""
 "\n"
 "Escriviu el missatge de l'etiqueta:\n"
 "  %s\n"
-"Les línies que comencin amb '%c' es retindran; podeu eliminar-les per vós mateix si "
-"voleu.\n"
+"Les línies que comencin amb '%c' es retindran; podeu eliminar-les per vós "
+"mateix si voleu.\n"
 
 #: builtin/tag.c:189
 msgid "unable to sign the tag"
@@ -14027,29 +14380,34 @@ msgstr "S'està provant mtime en «%s» "
 
 #: builtin/update-index.c:152
 msgid "directory stat info does not change after adding a new file"
-msgstr "la informació d'stat de directori no canvia després d'afegir un fitxer nou"
+msgstr ""
+"la informació d'stat de directori no canvia després d'afegir un fitxer nou"
 
 #: builtin/update-index.c:165
 msgid "directory stat info does not change after adding a new directory"
-msgstr "la informació d'stat de directori no canvia després d'afegir un directori nou"
+msgstr ""
+"la informació d'stat de directori no canvia després d'afegir un directori nou"
 
 #: builtin/update-index.c:178
 msgid "directory stat info changes after updating a file"
-msgstr "la informació d'stat de directori canvia després d'actualitzar un fitxer"
+msgstr ""
+"la informació d'stat de directori canvia després d'actualitzar un fitxer"
 
 #: builtin/update-index.c:189
 msgid "directory stat info changes after adding a file inside subdirectory"
 msgstr ""
-"la informació d'stat de directori canvia després d'afegir un fitxer dins d'un "
-"subdirectori"
+"la informació d'stat de directori canvia després d'afegir un fitxer dins "
+"d'un subdirectori"
 
 #: builtin/update-index.c:200
 msgid "directory stat info does not change after deleting a file"
-msgstr "la informació d'stat de directori no canvia després de suprimir un fitxer"
+msgstr ""
+"la informació d'stat de directori no canvia després de suprimir un fitxer"
 
 #: builtin/update-index.c:213
 msgid "directory stat info does not change after deleting a directory"
-msgstr "la informació d'stat de directori no canvia després de suprimir un directori"
+msgstr ""
+"la informació d'stat de directori no canvia després de suprimir un directori"
 
 #: builtin/update-index.c:220
 msgid " OK"
@@ -14061,7 +14419,8 @@ msgstr "git update-index [<opcions>] [--] [<fitxer>...]"
 
 #: builtin/update-index.c:936
 msgid "continue refresh even when index needs update"
-msgstr "continua l'actualització encara que l'índex necessiti una actualització"
+msgstr ""
+"continua l'actualització encara que l'índex necessiti una actualització"
 
 #: builtin/update-index.c:939
 msgid "refresh: ignore submodules"
@@ -14117,11 +14476,15 @@ msgstr "neteja el bit skip-worktree"
 
 #: builtin/update-index.c:981
 msgid "add to index only; do not add content to object database"
-msgstr "només afegeix a l'índex; no afegeixis el contingut a la base de dades d'objectes"
+msgstr ""
+"només afegeix a l'índex; no afegeixis el contingut a la base de dades "
+"d'objectes"
 
 #: builtin/update-index.c:983
 msgid "remove named paths even if present in worktree"
-msgstr "elimina els camins anomenats encara que estiguin presents en l'arbre de treball"
+msgstr ""
+"elimina els camins anomenats encara que estiguin presents en l'arbre de "
+"treball"
 
 #: builtin/update-index.c:985
 msgid "with --stdin: input lines are terminated by null bytes"
@@ -14193,27 +14556,27 @@ msgstr "neteja el bit de validesa del fsmonitor"
 
 #: builtin/update-index.c:1127
 msgid ""
-"core.splitIndex is set to false; remove or change it, if you really want to enable split "
-"index"
+"core.splitIndex is set to false; remove or change it, if you really want to "
+"enable split index"
 msgstr ""
-"core.splitIndex està establert a fals; elimineu-lo o canviar-lo, si realment voleu "
-"habilitar l'índex dividit"
+"core.splitIndex està establert a fals; elimineu-lo o canviar-lo, si realment "
+"voleu habilitar l'índex dividit"
 
 #: builtin/update-index.c:1136
 msgid ""
-"core.splitIndex is set to true; remove or change it, if you really want to disable split "
-"index"
+"core.splitIndex is set to true; remove or change it, if you really want to "
+"disable split index"
 msgstr ""
-"core.splitIndex està establert a cert; elimineu-lo o canvieu-lo, si realment voleu "
-"inhabilitar l'índex dividit"
+"core.splitIndex està establert a cert; elimineu-lo o canvieu-lo, si realment "
+"voleu inhabilitar l'índex dividit"
 
 #: builtin/update-index.c:1147
 msgid ""
-"core.untrackedCache is set to true; remove or change it, if you really want to disable "
-"the untracked cache"
+"core.untrackedCache is set to true; remove or change it, if you really want "
+"to disable the untracked cache"
 msgstr ""
-"core.untrackedCache està establert a cert; elimineu-lo o canvieu-lo, si realment voleu "
-"inhabilitar el cau no seguit"
+"core.untrackedCache està establert a cert; elimineu-lo o canvieu-lo, si "
+"realment voleu inhabilitar el cau no seguit"
 
 #: builtin/update-index.c:1151
 msgid "Untracked cache disabled"
@@ -14221,11 +14584,11 @@ msgstr "La memòria cau no seguida està inhabilitada"
 
 #: builtin/update-index.c:1159
 msgid ""
-"core.untrackedCache is set to false; remove or change it, if you really want to enable "
-"the untracked cache"
+"core.untrackedCache is set to false; remove or change it, if you really want "
+"to enable the untracked cache"
 msgstr ""
-"core.untrackedCache està establert a fals; elimineu-lo o canviar-lo, si realment voleu "
-"habilitar el cau no seguit"
+"core.untrackedCache està establert a fals; elimineu-lo o canviar-lo, si "
+"realment voleu habilitar el cau no seguit"
 
 #: builtin/update-index.c:1163
 #, c-format
@@ -14233,26 +14596,25 @@ msgid "Untracked cache enabled for '%s'"
 msgstr "La memòria cau no seguida està habilitada per a «%s»"
 
 #: builtin/update-index.c:1171
-#, fuzzy
 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
 msgstr ""
-"core.splitIndex està establert a fals; elimineu-lo o canviar-lo, si realment voleu "
-"habilitar l'índex dividit"
+"core.fsmonitor està establert a fals; establiu-lo a cert si realment voleu "
+"habilitar fsmonitor"
 
 #: builtin/update-index.c:1175
 msgid "fsmonitor enabled"
-msgstr ""
+msgstr "fsmonitor habilitat"
 
 #: builtin/update-index.c:1178
-#, fuzzy
-msgid "core.fsmonitor is set; remove it if you really want to disable fsmonitor"
+msgid ""
+"core.fsmonitor is set; remove it if you really want to disable fsmonitor"
 msgstr ""
-"core.splitIndex està establert a cert; elimineu-lo o canvieu-lo, si realment voleu "
-"inhabilitar l'índex dividit"
+"core.fsmonitor està establert a cert; elimineu-lo si realment voleu "
+"inhabilitar fsmonitor"
 
 #: builtin/update-index.c:1182
 msgid "fsmonitor disabled"
-msgstr ""
+msgstr "fsmonitor inhabilitat"
 
 #: builtin/update-ref.c:10
 msgid "git update-ref [<options>] -d <refname> [<old-val>]"
@@ -14260,7 +14622,8 @@ msgstr "git update-ref [<opcions>] -d <nom-de-referència> [<valor-antic>]"
 
 #: builtin/update-ref.c:11
 msgid "git update-ref [<options>]    <refname> <new-val> [<old-val>]"
-msgstr "git update-ref [<opcions>]    <nom-de-referència> <valor-nou> [<valor-antic>]"
+msgstr ""
+"git update-ref [<opcions>]    <nom-de-referència> <valor-nou> [<valor-antic>]"
 
 #: builtin/update-ref.c:12
 msgid "git update-ref [<options>] --stdin [-z]"
@@ -14336,16 +14699,15 @@ msgstr "git worktree lock [<opcions>] <camí>"
 
 #: builtin/worktree.c:20
 msgid "git worktree move <worktree> <new-path>"
-msgstr "git worktree move <worktree> <camí-nou>"
+msgstr "git worktree move <arbre de treball> <camí-nou>"
 
 #: builtin/worktree.c:21
 msgid "git worktree prune [<options>]"
 msgstr "git worktree prune [<opcions>]"
 
 #: builtin/worktree.c:22
-#, fuzzy
 msgid "git worktree remove [<options>] <worktree>"
-msgstr "git worktree lock [<opcions>] <camí>"
+msgstr "git worktree lock [<opcions>] <arbre de treball>"
 
 #: builtin/worktree.c:23
 msgid "git worktree unlock <path>"
@@ -14368,10 +14730,12 @@ msgstr "Eliminació de worktrees/%s: no s'ha pogut llegir el fitxer gitdir (%s)"
 
 #: builtin/worktree.c:90
 #, c-format
-msgid "Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read %<PRIuMAX>)"
+msgid ""
+"Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read "
+"%<PRIuMAX>)"
 msgstr ""
-"S'estan suprimint els arbres de treball/%s: lectura curta (s'esperaven %<PRIuMAX> bytes, "
-"llegits %<PRIuMAX>)"
+"S'estan suprimint els arbres de treball/%s: lectura curta (s'esperaven "
+"%<PRIuMAX> bytes, llegits %<PRIuMAX>)"
 
 #: builtin/worktree.c:98
 #, c-format
@@ -14382,7 +14746,8 @@ msgstr "Eliminació de worktrees/%s: fitxer gitdir no vàlid"
 #, c-format
 msgid "Removing worktrees/%s: gitdir file points to non-existent location"
 msgstr ""
-"Eliminació de worktrees/%s: el fitxer gitdir es refereix a una ubicació no existent"
+"Eliminació de worktrees/%s: el fitxer gitdir es refereix a una ubicació no "
+"existent"
 
 #: builtin/worktree.c:161
 msgid "report pruned working trees"
@@ -14583,7 +14948,8 @@ msgstr "surt immediatament després de l'anunci inicial de referència"
 
 #: upload-pack.c:1074
 msgid "do not try <directory>/.git/ if <directory> is no Git directory"
-msgstr "no intentis <directori>/.git/ si <directori> no és cap directori del Git"
+msgstr ""
+"no intentis <directori>/.git/ si <directori> no és cap directori del Git"
 
 #: upload-pack.c:1076
 msgid "interrupt transfer after <n> seconds of inactivity"
@@ -14629,17 +14995,17 @@ msgstr ""
 #: git.c:95
 #, c-format
 msgid "no directory given for --git-dir\n"
-msgstr ""
+msgstr "no s'ha especificat un directori per --git-dir\n"
 
 #: git.c:109
 #, c-format
 msgid "no namespace given for --namespace\n"
-msgstr ""
+msgstr "no s'ha especificat un nom d'espai per --namespace\n"
 
 #: git.c:123
 #, c-format
 msgid "no directory given for --work-tree\n"
-msgstr ""
+msgstr "no s'ha especificat un directori per --work-tree\n"
 
 #: git.c:137
 #, fuzzy, c-format
@@ -14649,12 +15015,12 @@ msgstr "%s no admet --super-prefix"
 #: git.c:159
 #, c-format
 msgid "-c expects a configuration string\n"
-msgstr ""
+msgstr "-c espera una cadena de configuració\n"
 
 #: git.c:197
 #, c-format
 msgid "no directory given for -C\n"
-msgstr ""
+msgstr "no s'ha especificat un directori per -C\n"
 
 #: git.c:212
 #, c-format
@@ -14755,7 +15121,8 @@ msgstr "Registra els canvis al dipòsit"
 
 #: common-cmds.h:23
 msgid "Show changes between commits, commit and working tree, etc"
-msgstr "Mostra els canvis entre comissions, la comissió i l'arbre de treball, etc."
+msgstr ""
+"Mostra els canvis entre comissions, la comissió i l'arbre de treball, etc."
 
 #: common-cmds.h:24
 msgid "Download objects and refs from another repository"
@@ -14787,7 +15154,8 @@ msgstr "Obtén i integra amb un altre dipòsit o una branca local"
 
 #: common-cmds.h:31
 msgid "Update remote refs along with associated objects"
-msgstr "Actualitza les referències remotes juntament amb els objectes associats"
+msgstr ""
+"Actualitza les referències remotes juntament amb els objectes associats"
 
 #: common-cmds.h:32
 msgid "Reapply commits on top of another base tip"
@@ -14795,7 +15163,7 @@ msgstr "Reaplica les comissions sobre un altre punt de basament"
 
 #: common-cmds.h:33
 msgid "Reset current HEAD to the specified state"
-msgstr "Restableix el HEAD actual a l'estat especificat"
+msgstr "Restableix la HEAD actual a l'estat especificat"
 
 #: common-cmds.h:34
 msgid "Remove files from the working tree and from the index"
@@ -14811,7 +15179,8 @@ msgstr "Mostra l'estat de l'arbre de treball"
 
 #: common-cmds.h:37
 msgid "Create, list, delete or verify a tag object signed with GPG"
-msgstr "Crea, llista, suprimeix o verifica un objecte d'etiqueta signat amb GPG"
+msgstr ""
+"Crea, llista, suprimeix o verifica un objecte d'etiqueta signat amb GPG"
 
 #: parse-options.h:157
 msgid "expiry-date"
@@ -14835,7 +15204,8 @@ msgstr "usa <n> xifres per presentar els SHA-1"
 
 #: rerere.h:40
 msgid "update the index with reused conflict resolution if possible"
-msgstr "actualitza l'índex amb la resolució de conflicte reusada si és possible"
+msgstr ""
+"actualitza l'índex amb la resolució de conflicte reusada si és possible"
 
 #: git-bisect.sh:54
 msgid "You need to start by \"git bisect start\""
@@ -14864,8 +15234,11 @@ msgstr "HEAD incorrecte - Cal un HEAD"
 
 #: git-bisect.sh:167
 #, sh-format
-msgid "Checking out '$start_head' failed. Try 'git bisect reset <valid-branch>'."
-msgstr "L'agafament de '$start_head' ha fallat. Proveu 'git bisect reset <branca-vàlida>'."
+msgid ""
+"Checking out '$start_head' failed. Try 'git bisect reset <valid-branch>'."
+msgstr ""
+"L'agafament de '$start_head' ha fallat. Proveu 'git bisect reset <branca-"
+"vàlida>'."
 
 #: git-bisect.sh:177
 msgid "won't bisect on cg-seek'ed tree"
@@ -14947,7 +15320,7 @@ msgid ""
 "Could not check out original HEAD '$branch'.\n"
 "Try 'git bisect reset <commit>'."
 msgstr ""
-"No s'ha pogut agafar el HEAD original '$branch'.\n"
+"No s'ha pogut agafar la HEAD original '$branch'.\n"
 "Proveu 'git bisect reset <comissió>'."
 
 #: git-bisect.sh:422
@@ -15001,7 +15374,8 @@ msgstr "pas de bisecció reeixit"
 #: git-bisect.sh:533
 #, sh-format
 msgid "Invalid command: you're currently in a $TERM_BAD/$TERM_GOOD bisect."
-msgstr "Ordre no vàlida: actualment esteu en una bisecció $TERM_BAD/$TERM_GOOD."
+msgstr ""
+"Ordre no vàlida: actualment esteu en una bisecció $TERM_BAD/$TERM_GOOD."
 
 #: git-bisect.sh:567
 msgid "no terms defined"
@@ -15017,9 +15391,12 @@ msgstr ""
 "Les opcions admeses són: --term-good|--term-old i --term-bad|--term-new."
 
 #: git-merge-octopus.sh:46
-msgid "Error: Your local changes to the following files would be overwritten by merge"
+msgid ""
+"Error: Your local changes to the following files would be overwritten by "
+"merge"
 msgstr ""
-"Error: Els vostres canvis locals als fitxers següents se sobreescriurien per fusionar"
+"Error: Els vostres canvis locals als fitxers següents se sobreescriurien per "
+"fusionar"
 
 #: git-merge-octopus.sh:61
 msgid "Automated merge did not work."
@@ -15051,20 +15428,23 @@ msgstr "S'està intentant una fusió simple amb $pretty_name"
 
 #: git-merge-octopus.sh:102
 msgid "Simple merge did not work, trying automatic merge."
-msgstr "La fusió simple no ha funcionat, s'està intentant una fusió automàtica."
+msgstr ""
+"La fusió simple no ha funcionat, s'està intentant una fusió automàtica."
 
 #: git-rebase.sh:60
 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\"."
+"To abort and get back to the state before \"git rebase\", run \"git rebase --"
+"abort\"."
 msgstr ""
 "Resolgueu tots els conflictes manualment, marqueu-los com a resolts amb\n"
-"«git add/rm <fitxers amb conflicte>», llavors executeu «git rebase --continue».\n"
+"«git add/rm <fitxers amb conflicte>», llavors executeu «git rebase --"
+"continue».\n"
 "Podeu en comptes ometre aquesta comissió: executeu «git rebase --skip».\n"
-"Per a avortar i tornar a l'estat anterior abans de l'ordre «git rebase», executeu «git "
-"rebase --abort»."
+"Per a avortar i tornar a l'estat anterior abans de l'ordre «git rebase», "
+"executeu «git rebase --abort»."
 
 #: git-rebase.sh:163 git-rebase.sh:409
 #, sh-format
@@ -15195,7 +15575,8 @@ msgstr "Canvis de $mb a $onto:"
 
 #: git-rebase.sh:651
 msgid "First, rewinding head to replay your work on top of it..."
-msgstr "Primer, s'està rebobinant HEAD per a reproduir el vostre treball al damunt..."
+msgstr ""
+"Primer, s'està rebobinant HEAD per a reproduir el vostre treball al damunt..."
 
 #: git-rebase.sh:661
 #, sh-format
@@ -15350,7 +15731,9 @@ msgstr "(Per restaurar-les teclegeu \"git stash apply\")"
 
 #: git-submodule.sh:181
 msgid "Relative path can only be used from the toplevel of the working tree"
-msgstr "El camí relatiu només es pot usar des del nivell superior de l'arbre de treball"
+msgstr ""
+"El camí relatiu només es pot usar des del nivell superior de l'arbre de "
+"treball"
 
 #: git-submodule.sh:191
 #, sh-format
@@ -15391,25 +15774,31 @@ msgstr "'$sm_path' ja existeix i no és un dipòsit de git vàlid"
 #: git-submodule.sh:247
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
-msgstr "Es troba un directori de git per a '$sm_name' localment amb els remots:"
+msgstr ""
+"Es troba un directori de git per a '$sm_name' localment amb els remots:"
 
 #: git-submodule.sh:249
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from\n"
 "  $realrepo\n"
-"use the '--force' option. If the local git directory is not the correct repo\n"
-"or you are unsure what this means choose another name with the '--name' option."
+"use the '--force' option. If the local git directory is not the correct "
+"repo\n"
+"or you are unsure what this means choose another name with the '--name' "
+"option."
 msgstr ""
 "Si voleu reusar aquest directori de git local en lloc de clonar de nou de\n"
 "  $realrepo\n"
-"useu l'opció '--force'. Si el directori de git local no és el dipòsit correcte\n"
-"o no esteu segur de què vol dir això, trieu un altre nom amb l'opció '--name'."
+"useu l'opció '--force'. Si el directori de git local no és el dipòsit "
+"correcte\n"
+"o no esteu segur de què vol dir això, trieu un altre nom amb l'opció '--"
+"name'."
 
 #: git-submodule.sh:255
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
-msgstr "S'està reactivant el directori de git local per al submòdul '$sm_name'."
+msgstr ""
+"S'està reactivant el directori de git local per al submòdul '$sm_name'."
 
 #: git-submodule.sh:267
 #, sh-format
@@ -15434,12 +15823,14 @@ msgstr "S'està entrant '$displaypath'"
 #: git-submodule.sh:362
 #, sh-format
 msgid "Stopping at '$displaypath'; script returned non-zero status."
-msgstr "S'està aturant a '$displaypath'; l'script ha retornat un estat no zero."
+msgstr ""
+"S'està aturant a '$displaypath'; l'script ha retornat un estat no zero."
 
 #: git-submodule.sh:584
 #, sh-format
 msgid "Unable to find current revision in submodule path '$displaypath'"
-msgstr "No s'ha pogut trobar la revisió actual en el camí de submòdul '$displaypath'"
+msgstr ""
+"No s'ha pogut trobar la revisió actual en el camí de submòdul '$displaypath'"
 
 #: git-submodule.sh:594
 #, sh-format
@@ -15449,10 +15840,11 @@ msgstr "No s'ha pogut obtenir en el camí de submòdul '$sm_path'"
 #: git-submodule.sh:599
 #, sh-format
 msgid ""
-"Unable to find current ${remote_name}/${branch} revision in submodule path '$sm_path'"
+"Unable to find current ${remote_name}/${branch} revision in submodule path "
+"'$sm_path'"
 msgstr ""
-"No s'ha pogut trobar la revisió actual de ${remote_name}/${branch} en el camí de "
-"submòdul '$sm_path'"
+"No s'ha pogut trobar la revisió actual de ${remote_name}/${branch} en el "
+"camí de submòdul '$sm_path'"
 
 #: git-submodule.sh:617
 #, sh-format
@@ -15462,11 +15854,11 @@ msgstr "No s'ha pogut obtenir en el camí de submòdul '$displaypath'"
 #: git-submodule.sh:623
 #, sh-format
 msgid ""
-"Fetched in submodule path '$displaypath', but it did not contain $sha1. Direct fetching "
-"of that commit failed."
+"Fetched in submodule path '$displaypath', but it did not contain $sha1. "
+"Direct fetching of that commit failed."
 msgstr ""
-"S'ha obtingut en el camí de submòdul '$displaypath', però no contenia $sha1. L'obtenció "
-"directa d'aquella comissió ha fallat."
+"S'ha obtingut en el camí de submòdul '$displaypath', però no contenia $sha1. "
+"L'obtenció directa d'aquella comissió ha fallat."
 
 #: git-submodule.sh:630
 #, sh-format
@@ -15481,7 +15873,8 @@ msgstr "Camí de submòdul '$displaypath': s'ha agafat '$sha1'"
 #: git-submodule.sh:635
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
-msgstr "No s'ha pogut fer «rebase» '$sha1' en el camí de submòdul '$displaypath'"
+msgstr ""
+"No s'ha pogut fer «rebase» '$sha1' en el camí de submòdul '$displaypath'"
 
 #: git-submodule.sh:636
 #, sh-format
@@ -15501,7 +15894,9 @@ msgstr "Camí de submòdul '$displaypath': s'ha fusionat en '$sha1'"
 #: git-submodule.sh:647
 #, sh-format
 msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'"
-msgstr "L'execució de '$command $sha1' ha fallat en el camí de submòdul '$displaypath'"
+msgstr ""
+"L'execució de '$command $sha1' ha fallat en el camí de submòdul "
+"'$displaypath'"
 
 #: git-submodule.sh:648
 #, sh-format
@@ -15512,7 +15907,8 @@ msgstr "Camí de submòdul '$displaypath': '$command $sha1'"
 #, sh-format
 msgid "Failed to recurse into submodule path '$displaypath'"
 msgstr ""
-"S'ha produït un error en recorre recursivament dins del camí de submòdul '$displaypath'"
+"S'ha produït un error en recorre recursivament dins del camí de submòdul "
+"'$displaypath'"
 
 #: git-submodule.sh:775
 msgid "The --cached option cannot be used with the --files option"
@@ -15568,8 +15964,10 @@ msgstr ""
 " r, reword = usa la comissió, però edita el missatge de comissió\n"
 " e, edit = usa la comissió, però atura't per a esmenar\n"
 " s, squash = usa la comissió, però fusiona'l a la comissió prèvia\n"
-" f, fixup = com \"squash\", però descarta el missatge de registre d'aquesta comissió\n"
-" x, exec = executa l'ordre (la resta de la línia) usant l'intèrpret d'ordres\n"
+" f, fixup = com \"squash\", però descarta el missatge de registre d'aquesta "
+"comissió\n"
+" x, exec = executa l'ordre (la resta de la línia) usant l'intèrpret "
+"d'ordres\n"
 " d, drop = elimina la comissió\n"
 "\n"
 "Es pot canviar l'ordre d'aquestes línies; s'executen de dalt a baix.\n"
@@ -15580,7 +15978,8 @@ msgid ""
 "Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
 msgstr ""
 "\n"
-"No elimineu cap línia. Useu 'drop' explícitament per a eliminar una comissió.\n"
+"No elimineu cap línia. Useu 'drop' explícitament per a eliminar una "
+"comissió.\n"
 
 #: git-rebase--interactive.sh:175
 msgid ""
@@ -15690,10 +16089,12 @@ msgstr "No s'ha pogut aplicar $sha1... $rest"
 msgid ""
 "Could not amend commit after successfully picking $sha1... $rest\n"
 "This is most likely due to an empty commit message, or the pre-commit hook\n"
-"failed. If the pre-commit hook failed, you may need to resolve the issue before\n"
+"failed. If the pre-commit hook failed, you may need to resolve the issue "
+"before\n"
 "you are able to reword the commit."
 msgstr ""
-"No s'ha pogut esmenar la comissió després d'escollir amb èxit $sha1... $rest\n"
+"No s'ha pogut esmenar la comissió després d'escollir amb èxit $sha1... "
+"$rest\n"
 "Això és probablement a causa d'un missatge de comissió buit, o el lligam de\n"
 "precomissió ha fallat. Si el lligam de precomissió ha fallat, pot ser que\n"
 "necessiteu resoldre el problema abans que pugueu canviar el missatge de\n"
@@ -15805,7 +16206,8 @@ msgstr ""
 #: git-rebase--interactive.sh:793
 msgid "Error trying to find the author identity to amend commit"
 msgstr ""
-"Hi ha hagut un error en intentar trobar la identitat d'autor per a esmenar la comissió"
+"Hi ha hagut un error en intentar trobar la identitat d'autor per a esmenar "
+"la comissió"
 
 #: git-rebase--interactive.sh:798
 msgid ""
@@ -15892,7 +16294,9 @@ msgstr "ús: $dashless $USAGE"
 #: git-sh-setup.sh:190
 #, sh-format
 msgid "Cannot chdir to $cdup, the toplevel of the working tree"
-msgstr "No es pot canviar de directori a $cdup, el nivell superior de l'arbre de treball"
+msgstr ""
+"No es pot canviar de directori a $cdup, el nivell superior de l'arbre de "
+"treball"
 
 #: git-sh-setup.sh:199 git-sh-setup.sh:206
 #, sh-format
@@ -15922,7 +16326,8 @@ msgstr "No es pot fer «rebase»: El vostre índex conté canvis sense cometre."
 
 #: git-sh-setup.sh:245
 msgid "Cannot pull with rebase: Your index contains uncommitted changes."
-msgstr "No es pot baixar fent «rebase»: El vostre índex conté canvis sense cometre."
+msgstr ""
+"No es pot baixar fent «rebase»: El vostre índex conté canvis sense cometre."
 
 #: git-sh-setup.sh:248
 #, sh-format
@@ -15935,7 +16340,8 @@ msgstr "Addicionalment, el vostre índex conté canvis sense cometre."
 
 #: git-sh-setup.sh:372
 msgid "You need to run this command from the toplevel of the working tree."
-msgstr "Heu d'executar aquesta ordre des del nivell superior de l'arbre de treball."
+msgstr ""
+"Heu d'executar aquesta ordre des del nivell superior de l'arbre de treball."
 
 #: git-sh-setup.sh:377
 msgid "Unable to determine absolute path of git directory"
@@ -16063,7 +16469,8 @@ msgstr "s'ha produït un error en escriure al fitxer d'edició del tros: %s"
 
 #: git-add--interactive.perl:1079
 msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
-msgstr "Mode d'edició de trossos manual - vegeu més avall per una guia ràpida.\n"
+msgstr ""
+"Mode d'edició de trossos manual - vegeu més avall per una guia ràpida.\n"
 
 #: git-add--interactive.perl:1085
 #, perl-format
@@ -16086,7 +16493,8 @@ msgid ""
 "aborted and the hunk is left unchanged.\n"
 msgstr ""
 "Si no s'aplica correctament, tindreu una oportunitat per editar-lo\n"
-"de nou. Si totes les línies del tros se suprimeixen, llavors l'edició s'avorta\n"
+"de nou. Si totes les línies del tros se suprimeixen, llavors l'edició "
+"s'avorta\n"
 "i el tros es deixa sense cap canvi.\n"
 
 #: git-add--interactive.perl:1107
@@ -16101,9 +16509,11 @@ msgstr "s'ha produït un error en llegir al fitxer d'edició del tros: %s"
 #. (saying "n" for "no" discards!) if the translation
 #. of the word "no" does not start with n.
 #: git-add--interactive.perl:1206
-msgid "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
+msgid ""
+"Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
-"El tros editat no s'aplica. Editeu-lo de nou (si responeu \"no\" es descartarà) [y/n]? "
+"El tros editat no s'aplica. Editeu-lo de nou (si responeu \"no\" es "
+"descartarà) [y/n]? "
 
 #: git-add--interactive.perl:1215
 msgid ""
@@ -16332,22 +16742,27 @@ msgstr "Descarta aquest tros des de l'arbre de treball  [y,n,q,a,d%s,?]? "
 #: git-add--interactive.perl:1408
 #, perl-format
 msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Descarta el canvi de mode des de l'índex i l'arbre de treball [y,n,q,a,d%s,?]? "
+msgstr ""
+"Descarta el canvi de mode des de l'índex i l'arbre de treball [y,n,q,a,d"
+"%s,?]? "
 
 #: git-add--interactive.perl:1409
 #, perl-format
 msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Descarta la supressió des de l'índex i l'arbre de treball [y,n,q,a,d%s,?]? "
+msgstr ""
+"Descarta la supressió des de l'índex i l'arbre de treball [y,n,q,a,d%s,?]? "
 
 #: git-add--interactive.perl:1410
 #, perl-format
 msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Descarta aquest tros des de l'índex i l'arbre de treball [y,n,q,a,d%s,?]? "
+msgstr ""
+"Descarta aquest tros des de l'índex i l'arbre de treball [y,n,q,a,d%s,?]? "
 
 #: git-add--interactive.perl:1413
 #, perl-format
 msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Aplica el canvi de mode a l'índex i l'arbre de treball [y,n,q,a,d%s,?]? "
+msgstr ""
+"Aplica el canvi de mode a l'índex i l'arbre de treball [y,n,q,a,d%s,?]? "
 
 #: git-add--interactive.perl:1414
 #, perl-format
@@ -16385,7 +16800,7 @@ msgstr[1] "Només %d trossos disponibles.\n"
 
 #: git-add--interactive.perl:1564
 msgid "No other hunks to search\n"
-msgstr ""
+msgstr "No hi ha cap altre tros a cercar\n"
 
 #: git-add--interactive.perl:1568
 msgid "search for regex? "
@@ -16410,7 +16825,7 @@ msgstr "No hi ha tros següent\n"
 
 #: git-add--interactive.perl:1637
 msgid "Sorry, cannot split this hunk\n"
-msgstr ""
+msgstr "No es pot dividir aquest tros\n"
 
 #: git-add--interactive.perl:1643
 #, perl-format
@@ -16421,7 +16836,7 @@ msgstr[1] "Divideix en %d trossos.\n"
 
 #: git-add--interactive.perl:1653
 msgid "Sorry, cannot edit this hunk\n"
-msgstr ""
+msgstr "No es pot editar aquest tros\n"
 
 #: git-add--interactive.perl:1699
 msgid "Review diff"
@@ -16436,15 +16851,17 @@ msgid ""
 "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"
+"add untracked - add contents of untracked files to the staged set of "
+"changes\n"
 msgstr ""
 "status        - mostra els camins amb canvis\n"
-"update        - afegeix l'estat de l'arbre de treball al conjunt de canvis «staged»\n"
+"update        - afegeix l'estat de l'arbre de treball al conjunt de canvis "
+"«staged»\n"
 "revert        - reverteix el conjunt de canvis de «staged» a la versió HEAD\n"
 "patch         - selecciona trossos i actualitza'ls selectivament\n"
 "diff          - mostra la diferència entre HEAD i l'índex\n"
-"add untracked - afegeix el contingut dels fitxers no seguits al conjunt de canvis "
-"«staged»\n"
+"add untracked - afegeix el contingut dels fitxers no seguits al conjunt de "
+"canvis «staged»\n"
 
 #: git-add--interactive.perl:1735 git-add--interactive.perl:1740
 #: git-add--interactive.perl:1743 git-add--interactive.perl:1750
@@ -16476,7 +16893,8 @@ msgstr "l'editor no ha sortit correctament, avortant-ho tot"
 
 #: git-send-email.perl:294
 #, perl-format
-msgid "'%s' contains an intermediate version of the email you were composing.\n"
+msgid ""
+"'%s' contains an intermediate version of the email you were composing.\n"
 msgstr "«%s» conté una versió intermèdia del correu que estàveu redactant.\n"
 
 #: git-send-email.perl:299
@@ -16494,8 +16912,8 @@ msgstr "No es pot executar git format-patch des de fora del dipòsit\n"
 
 #: git-send-email.perl:386
 msgid ""
-"`batch-size` and `relogin` must be specified together (via command-line or configuration "
-"option)\n"
+"`batch-size` and `relogin` must be specified together (via command-line or "
+"configuration option)\n"
 msgstr ""
 
 #: git-send-email.perl:456
@@ -16612,8 +17030,12 @@ msgid "Are you sure you want to use <%s> [y/N]? "
 msgstr "Esteu segur que voleu usar <%s> [y/N]? "
 
 #: git-send-email.perl:868
-msgid "The following files are 8bit, but do not declare a Content-Transfer-Encoding.\n"
-msgstr "Els fitxers següents són 8bit, però no declaren un Content-Transfer-Encoding.\n"
+msgid ""
+"The following files are 8bit, but do not declare a Content-Transfer-"
+"Encoding.\n"
+msgstr ""
+"Els fitxers següents són 8bit, però no declaren un Content-Transfer-"
+"Encoding.\n"
 
 #: git-send-email.perl:873
 msgid "Which 8bit encoding should I declare [UTF-8]? "
@@ -16624,17 +17046,18 @@ msgstr "Quina codificació de 8 bits hauria de declarar [UTF-8]? "
 msgid ""
 "Refusing to send because the patch\n"
 "\t%s\n"
-"has the template subject '*** SUBJECT HERE ***'. Pass --force if you really want to "
-"send.\n"
+"has the template subject '*** SUBJECT HERE ***'. Pass --force if you really "
+"want to send.\n"
 msgstr ""
 "S'ha refusat a enviar perquè el pedaç\n"
 "\t%s\n"
-"perquè la plantilla té l'assumpte '*** SUBJECT HERE ***'. Passeu --force si realment "
-"voleu enviar-lo.\n"
+"perquè la plantilla té l'assumpte '*** SUBJECT HERE ***'. Passeu --force si "
+"realment voleu enviar-lo.\n"
 
 #: git-send-email.perl:900
 msgid "To whom should the emails be sent (if anyone)?"
-msgstr "A qui s'haurien d'enviar els correus electrònics (si s'han d'enviar a algú)?"
+msgstr ""
+"A qui s'haurien d'enviar els correus electrònics (si s'han d'enviar a algú)?"
 
 #: git-send-email.perl:918
 #, perl-format
@@ -16643,7 +17066,9 @@ msgstr "fatal: l'àlies «%s» s'expandeix a si mateix\n"
 
 #: git-send-email.perl:930
 msgid "Message-ID to be used as In-Reply-To for the first email (if any)? "
-msgstr "S'ha d'usar el Message-ID com a In-Reply-To pel primer correu (si n'hi ha cap)? "
+msgstr ""
+"S'ha d'usar el Message-ID com a In-Reply-To pel primer correu (si n'hi ha "
+"cap)? "
 
 #: git-send-email.perl:988 git-send-email.perl:996
 #, perl-format
@@ -16714,8 +17139,8 @@ msgstr "STARTTLS ha fallat! %s"
 #: git-send-email.perl:1505
 msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug."
 msgstr ""
-"No s'ha pogut inicialitzar SMTP correctament. Comproveu-ho la configuració i useu --smtp-"
-"debug."
+"No s'ha pogut inicialitzar SMTP correctament. Comproveu-ho la configuració i "
+"useu --smtp-debug."
 
 #: git-send-email.perl:1523
 #, perl-format
@@ -16816,71 +17241,3 @@ msgstr "S'està ometent %s amb el sufix de còpia de seguretat «%s».\n"
 #, perl-format
 msgid "Do you really want to send %s? [y|N]: "
 msgstr "Esteu segur que voleu enviar %s? [y|N]: "
-
-#~ msgid "git fetch-pack: expected ACK/NAK, got EOF"
-#~ msgstr "git fetch-pack: s'esperava ACK/NAK, s'ha rebut EOF"
-
-#~ msgid ""
-#~ "empty strings as pathspecs will be made invalid in upcoming releases. please use . "
-#~ "instead if you meant to match all paths"
-#~ msgstr ""
-#~ "es faran no vàlides les cadenes buides com especificacions de camí en versions "
-#~ "futures. Useu . en lloc d'això si volíeu coincidir amb tots els camins"
-
-#~ msgid "unable to open '%s' for writing"
-#~ msgstr "no s'ha pogut obrir «%s» per a escriptura"
-
-#~ msgid "could not truncate '%s'"
-#~ msgstr "no s'ha pogut truncar a «%s»"
-
-#~ msgid "could not finish '%s'"
-#~ msgstr "no s'ha pogut finalitzar «%s»"
-
-#~ msgid "could not close %s"
-#~ msgstr "no s'ha pogut tancar %s"
-
-#~ msgid "The copy of the patch that failed is found in: %s"
-#~ msgstr "La còpia del pedaç que ha fallat es troba en: %s"
-
-#~ msgid "Copied a misnamed branch '%s' away"
-#~ msgstr "S'ha copiat el nom de la branca mal anomenada «%s»"
-
-#~ msgid "it does not make sense to create 'HEAD' manually"
-#~ msgstr "no té sentit crear 'HEAD' manualment"
-
-#~ msgid "Don't know how to clone %s"
-#~ msgstr "No se sap com clonar %s"
-
-#~ msgid "show ignored files"
-#~ msgstr "mostra els fitxers ignorats"
-
-#~ msgid "%s is not a valid '%s' object"
-#~ msgstr "%s no és un objecte de «%s» vàlid"
-
-#~ msgid "Don't know how to fetch from %s"
-#~ msgstr "No se sap com obtenir de %s"
-
-#~ msgid "'$term' is not a valid term"
-#~ msgstr "'$term' no és un terme vàlid"
-
-#~ msgid ""
-#~ "error: unknown option for 'stash save': $option\n"
-#~ "       To provide a message, use git stash save -- '$option'"
-#~ msgstr ""
-#~ "error: opció desconeguda de 'stash save': $option\n"
-#~ "       Per a proveir un missatge, useu git stash save -- '$option'"
-
-#~ msgid "pathspec and --all are incompatible"
-#~ msgstr "--pathspec i --all són incompatibles"
-
-#~ msgid "Submodule '$name' ($url) unregistered for path '$displaypath'"
-#~ msgstr "Submòdul '$name' ($url) no registrat per al camí '$displaypath'"
-
-#~ msgid "Failed to recurse into submodule path '$sm_path'"
-#~ msgstr "S'ha produït un error en cercar recursivament al camí de submòdul '$sm_path'"
-
-#~ msgid "To/Cc/Bcc fields are not interpreted yet, they have been ignored\n"
-#~ msgstr "Els camps A/Cc/Bcc no s'interpreten encara, s'ignoraran\n"
-
-#~ msgid "%%(trailers) does not take arguments"
-#~ msgstr "%%(trailers) no accepta paràmetres"
index 793bd2a803b9d7c9d759faf665e43db84e1cd066..7df1cfcd49fb9f7bbc466393a59dc8d0c04c0aa5 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -15052,7 +15052,7 @@ msgstr "Kann gesperrtes Arbeitsverzeichnis nicht verschieben, Sperrgrund: %s"
 
 #: builtin/worktree.c:692
 msgid "cannot move a locked working tree"
-msgstr "Kann gesperrtes Arbeitsverzeichnisses nicht verschieben."
+msgstr "Kann gesperrtes Arbeitsverzeichnis nicht verschieben."
 
 #: builtin/worktree.c:695
 #, c-format
@@ -16991,7 +16991,7 @@ msgstr "Löschung im Arbeitsverzeichnis verwerfen [y,n,q,a,d%s,?]? "
 #: git-add--interactive.perl:1405
 #, perl-format
 msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
-msgstr "diesen Patch-Block im Arbeitsverzeichnis verwerfen [y,n,q,a,d%s,?]? "
+msgstr "Diesen Patch-Block im Arbeitsverzeichnis verwerfen [y,n,q,a,d%s,?]? "
 
 #: git-add--interactive.perl:1408
 #, perl-format
index 4e9949673ccadd0399d3b2ec39cd7656a6df63d3..a68bcd999154320e8f81a228d5e75d0768ed2b60 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -7,8 +7,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2018-03-16 07:29+0800\n"
-"PO-Revision-Date: 2018-03-15 21:31-0500\n"
+"POT-Creation-Date: 2018-06-16 22:06+0800\n"
+"PO-Revision-Date: 2018-06-16 09:57-0500\n"
 "Last-Translator: christopher.diaz.riv@gmail.com\n"
 "Language-Team: CodeLabora <codelabora@gmail.com>\n"
 "Language: es\n"
@@ -16,40 +16,40 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.0.6\n"
+"X-Generator: Poedit 2.0.7\n"
 
-#: advice.c:62
+#: advice.c:92
 #, c-format
-msgid "hint: %.*s\n"
-msgstr "ayuda: %.*s\n"
+msgid "%shint: %.*s%s\n"
+msgstr "%sayuda: %.*s%s\n"
 
-#: advice.c:90
+#: advice.c:137
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr ""
 "No es posible ejecutar cherry-picking porque tienes archivos sin fusionar."
 
-#: advice.c:92
+#: advice.c:139
 msgid "Committing is not possible because you have unmerged files."
 msgstr "No es posible realizar un commit porque tienes archivos sin fusionar."
 
-#: advice.c:94
+#: advice.c:141
 msgid "Merging is not possible because you have unmerged files."
 msgstr "No es posible hacer merge porque tienes archivos sin fusionar."
 
-#: advice.c:96
+#: advice.c:143
 msgid "Pulling is not possible because you have unmerged files."
 msgstr "No es posible hacer pull porque tienes archivos sin fusionar."
 
-#: advice.c:98
+#: advice.c:145
 msgid "Reverting is not possible because you have unmerged files."
 msgstr "No es posible revertir porque tienes archivos sin fusionar."
 
-#: advice.c:100
+#: advice.c:147
 #, c-format
 msgid "It is not possible to %s because you have unmerged files."
 msgstr "No es posible %s porque tienes archivos sin fusionar."
 
-#: advice.c:108
+#: advice.c:155
 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."
@@ -57,23 +57,23 @@ msgstr ""
 "Corrígelos en el árbol de trabajo y entonces usa 'git add/rm <archivo>',\n"
 "como sea apropiado, para marcar la resolución y realizar un commit."
 
-#: advice.c:116
+#: advice.c:163
 msgid "Exiting because of an unresolved conflict."
 msgstr "Saliendo porque existe un conflicto sin resolver."
 
-#: advice.c:121 builtin/merge.c:1251
+#: advice.c:168 builtin/merge.c:1250
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
 msgstr "No has concluido tu fusión (MERGE_HEAD existe)."
 
-#: advice.c:123
+#: advice.c:170
 msgid "Please, commit your changes before merging."
 msgstr "Por favor, realiza un commit antes de fusionar."
 
-#: advice.c:124
+#: advice.c:171
 msgid "Exiting because of unfinished merge."
 msgstr "Saliendo por una fusión inconclusa."
 
-#: advice.c:130
+#: advice.c:177
 #, c-format
 msgid ""
 "Note: checking out '%s'.\n"
@@ -343,14 +343,14 @@ msgstr ""
 #: apply.c:3225
 #, c-format
 msgid "patch failed: %s:%ld"
-msgstr "el parche fallo: %s:%ld"
+msgstr "el parche falló: %s:%ld"
 
 #: apply.c:3347
 #, c-format
 msgid "cannot checkout %s"
 msgstr "no se puede hacer checkout a %s"
 
-#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:277
+#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:278
 #, c-format
 msgid "failed to read %s"
 msgstr "no se pudo leer %s"
@@ -394,7 +394,7 @@ msgstr "no se pueden leer los contenidos actuales de '%s'"
 #: apply.c:3595
 #, c-format
 msgid "Failed to fall back on three-way merge...\n"
-msgstr "Fallo el merge en retroceso de tres-vías...\n"
+msgstr "Falló el merge en retroceso de tres-vías...\n"
 
 #: apply.c:3609
 #, c-format
@@ -478,7 +478,7 @@ msgstr "falta información sha1 o es inútil (%s)."
 #: apply.c:4095 builtin/checkout.c:235 builtin/reset.c:140
 #, c-format
 msgid "make_cache_entry failed for path '%s'"
-msgstr "make_cache_entry fallo para la ruta '%s'"
+msgstr "make_cache_entry falló para la ruta '%s'"
 
 #: apply.c:4099
 #, c-format
@@ -519,7 +519,7 @@ msgstr "no es posible agregar una entrada en el cache para %s"
 #: apply.c:4343
 #, c-format
 msgid "failed to write to '%s'"
-msgstr "fallo escribir para '%s'"
+msgstr "falló escribir para '%s'"
 
 #: apply.c:4347
 #, c-format
@@ -552,7 +552,7 @@ msgstr[1] "Aplicando parche %%s con %d rechazos..."
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "truncando el nombre de archivo .rej a %.*s.rej"
 
-#: apply.c:4545 builtin/fetch.c:775 builtin/fetch.c:1025
+#: apply.c:4545 builtin/fetch.c:786 builtin/fetch.c:1036
 #, c-format
 msgid "cannot open %s"
 msgstr "no se puede abrir %s"
@@ -608,15 +608,15 @@ msgstr[0] ""
 msgstr[1] ""
 "%d líneas aplicadas después de arreglar los errores de espacios en blanco."
 
-#: apply.c:4894 builtin/add.c:539 builtin/mv.c:298 builtin/rm.c:390
+#: apply.c:4894 builtin/add.c:538 builtin/mv.c:300 builtin/rm.c:389
 msgid "Unable to write new index file"
 msgstr "No es posible escribir el archivo índice"
 
 #: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257
-#: builtin/clone.c:118 builtin/fetch.c:127 builtin/pull.c:193
-#: builtin/submodule--helper.c:403 builtin/submodule--helper.c:1197
-#: builtin/submodule--helper.c:1200 builtin/submodule--helper.c:1567
-#: builtin/submodule--helper.c:1570 builtin/submodule--helper.c:1787
+#: builtin/clone.c:120 builtin/fetch.c:126 builtin/pull.c:198
+#: builtin/submodule--helper.c:405 builtin/submodule--helper.c:1210
+#: builtin/submodule--helper.c:1213 builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1587 builtin/submodule--helper.c:1807
 #: git-add--interactive.perl:197
 msgid "path"
 msgstr "ruta"
@@ -692,7 +692,7 @@ msgstr "asegure que por lo menos <n> líneas del contexto concuerden"
 
 #: apply.c:4960 builtin/am.c:2242 builtin/interpret-trailers.c:95
 #: builtin/interpret-trailers.c:97 builtin/interpret-trailers.c:99
-#: builtin/pack-objects.c:3035
+#: builtin/pack-objects.c:3177
 msgid "action"
 msgstr "acción"
 
@@ -723,9 +723,9 @@ msgstr "dejar los hunks rechazados en los archivos *.rej correspontientes"
 msgid "allow overlapping hunks"
 msgstr "permitir solapamiento de hunks"
 
-#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21
-#: builtin/commit.c:1276 builtin/count-objects.c:96 builtin/fsck.c:665
-#: builtin/log.c:1901 builtin/mv.c:123 builtin/read-tree.c:125
+#: apply.c:4977 builtin/add.c:290 builtin/check-ignore.c:21
+#: builtin/commit.c:1301 builtin/count-objects.c:98 builtin/fsck.c:666
+#: builtin/log.c:1901 builtin/mv.c:122 builtin/read-tree.c:124
 msgid "be verbose"
 msgstr "ser verboso"
 
@@ -766,98 +766,98 @@ msgstr ""
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <repo> [--exec <comando>] --list"
 
-#: archive.c:351 builtin/add.c:176 builtin/add.c:515 builtin/rm.c:299
+#: archive.c:351 builtin/add.c:176 builtin/add.c:514 builtin/rm.c:298
 #, c-format
 msgid "pathspec '%s' did not match any files"
 msgstr "ruta especificada '%s' no concordó con ninguna carpeta"
 
-#: archive.c:436
+#: archive.c:434
 msgid "fmt"
 msgstr "fmt"
 
-#: archive.c:436
+#: archive.c:434
 msgid "archive format"
 msgstr "formato del archivo"
 
-#: archive.c:437 builtin/log.c:1462
+#: archive.c:435 builtin/log.c:1462
 msgid "prefix"
 msgstr "prefijo"
 
-#: archive.c:438
+#: archive.c:436
 msgid "prepend prefix to each pathname in the archive"
 msgstr "anteponer prefijo a cada ruta en el archivo"
 
-#: archive.c:439 builtin/blame.c:702 builtin/blame.c:703 builtin/config.c:62
-#: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:869
+#: archive.c:437 builtin/blame.c:813 builtin/blame.c:814 builtin/config.c:127
+#: builtin/fast-export.c:1007 builtin/fast-export.c:1009 builtin/grep.c:869
 #: builtin/hash-object.c:103 builtin/ls-files.c:551 builtin/ls-files.c:554
-#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120
+#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:119
 #: parse-options.h:165
 msgid "file"
 msgstr "carpeta"
 
-#: archive.c:440 builtin/archive.c:89
+#: archive.c:438 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "escribe el archivo en esta carpeta"
 
-#: archive.c:442
+#: archive.c:440
 msgid "read .gitattributes in working directory"
 msgstr "leer .gitattributes en el directorio de trabajo"
 
-#: archive.c:443
+#: archive.c:441
 msgid "report archived files on stderr"
 msgstr "reportar archivos archivados por stderr"
 
-#: archive.c:444
+#: archive.c:442
 msgid "store only"
 msgstr "solo guardar"
 
-#: archive.c:445
+#: archive.c:443
 msgid "compress faster"
 msgstr "comprimir mas rápido"
 
-#: archive.c:453
+#: archive.c:451
 msgid "compress better"
 msgstr "comprimir mejor"
 
-#: archive.c:456
+#: archive.c:454
 msgid "list supported archive formats"
 msgstr "listar los formatos de carpeta soportados"
 
-#: archive.c:458 builtin/archive.c:90 builtin/clone.c:108 builtin/clone.c:111
-#: builtin/submodule--helper.c:1209 builtin/submodule--helper.c:1576
+#: archive.c:456 builtin/archive.c:90 builtin/clone.c:110 builtin/clone.c:113
+#: builtin/submodule--helper.c:1222 builtin/submodule--helper.c:1593
 msgid "repo"
 msgstr "repo"
 
-#: archive.c:459 builtin/archive.c:91
+#: archive.c:457 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "obtener la carpeta del repositorio remoto <repo>"
 
-#: archive.c:460 builtin/archive.c:92 builtin/notes.c:489
+#: archive.c:458 builtin/archive.c:92 builtin/notes.c:489
 msgid "command"
 msgstr "comando"
 
-#: archive.c:461 builtin/archive.c:93
+#: archive.c:459 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "ruta para el comando git-upload-archivo remoto"
 
-#: archive.c:468
+#: archive.c:466
 msgid "Unexpected option --remote"
 msgstr "Opción inesperada --remote"
 
-#: archive.c:470
+#: archive.c:468
 msgid "Option --exec can only be used together with --remote"
 msgstr "Opción --exec solo puede ser utilizada con --remote"
 
-#: archive.c:472
+#: archive.c:470
 msgid "Unexpected option --output"
 msgstr "Opción inesperada --output"
 
-#: archive.c:494
+#: archive.c:492
 #, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Formato de carpeta desconocido '%s'"
 
-#: archive.c:501
+#: archive.c:499
 #, c-format
 msgid "Argument not supported for format '%s': -%d"
 msgstr "Argumento no soportado para formato '%s': -%d"
@@ -875,22 +875,22 @@ msgstr ""
 "Los patrones negativos son ignorados en los atributos de git\n"
 "Usa '\\!' para comenzar literalmente con exclamación."
 
-#: bisect.c:460
+#: bisect.c:461
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Revisa las comillas en el archivo '%s': %s"
 
-#: bisect.c:668
+#: bisect.c:669
 #, c-format
 msgid "We cannot bisect more!\n"
 msgstr "No podemos bisecar mas!\n"
 
-#: bisect.c:722
+#: bisect.c:723
 #, c-format
 msgid "Not a valid commit name %s"
 msgstr "No es un nombre de commit valido %s"
 
-#: bisect.c:746
+#: bisect.c:747
 #, c-format
 msgid ""
 "The merge base %s is bad.\n"
@@ -899,7 +899,7 @@ msgstr ""
 "La base de fisión %s esta mal.\n"
 "Esto quiere decir que el bug ha sido arreglado entre %s y [%s].\n"
 
-#: bisect.c:751
+#: bisect.c:752
 #, c-format
 msgid ""
 "The merge base %s is new.\n"
@@ -908,7 +908,7 @@ msgstr ""
 "La base de fisión %s es nueva.\n"
 "Esta propiedad ha cambiado entre %s y [%s].\n"
 
-#: bisect.c:756
+#: bisect.c:757
 #, c-format
 msgid ""
 "The merge base %s is %s.\n"
@@ -917,7 +917,7 @@ msgstr ""
 "La base de fisión %s es %s.\n"
 "Esto quiere decir que el primer '%s' commit esta entre %s y [%s].\n"
 
-#: bisect.c:764
+#: bisect.c:765
 #, c-format
 msgid ""
 "Some %s revs are not ancestors of the %s rev.\n"
@@ -928,7 +928,7 @@ msgstr ""
 "git bisect no puede trabajar bien en este caso.\n"
 "Tal vez confundió la revisión %s y %s?\n"
 
-#: bisect.c:777
+#: bisect.c:778
 #, c-format
 msgid ""
 "the merge base between %s and [%s] must be skipped.\n"
@@ -939,36 +939,36 @@ msgstr ""
 "Así que no podemos estar seguros que el primer %s commit esta entre%s y %s.\n"
 "Vamos a continuar de todas maneras."
 
-#: bisect.c:810
+#: bisect.c:811
 #, c-format
 msgid "Bisecting: a merge base must be tested\n"
 msgstr "Bisectando: una base de fisión debe ser probada\n"
 
-#: bisect.c:850
+#: bisect.c:851
 #, c-format
 msgid "a %s revision is needed"
 msgstr "una %s revisión es necesaria"
 
-#: bisect.c:869 builtin/notes.c:175 builtin/tag.c:235
+#: bisect.c:870 builtin/notes.c:175 builtin/tag.c:236
 #, c-format
 msgid "could not create file '%s'"
 msgstr "no se pudo crear el archivo '%s'"
 
-#: bisect.c:920
+#: bisect.c:921
 #, c-format
 msgid "could not read file '%s'"
 msgstr "no se pudo leer el archivo '%s'"
 
-#: bisect.c:950
+#: bisect.c:951
 msgid "reading bisect refs failed"
-msgstr "fallo leer las refs de bisect"
+msgstr "falló leer las refs de bisect"
 
-#: bisect.c:969
+#: bisect.c:970
 #, c-format
 msgid "%s was both %s and %s\n"
 msgstr "%s fue tanto %s como %s\n"
 
-#: bisect.c:977
+#: bisect.c:978
 #, c-format
 msgid ""
 "No testable commit found.\n"
@@ -977,7 +977,7 @@ msgstr ""
 "No se encontró commit que se pueda probar.\n"
 "¿Quizás iniciaste con parámetros de rutas incorrectos?\n"
 
-#: bisect.c:996
+#: bisect.c:997
 #, c-format
 msgid "(roughly %d step)"
 msgid_plural "(roughly %d steps)"
@@ -987,51 +987,51 @@ msgstr[1] "(aproximadamente %d pasos)"
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
 #.
-#: bisect.c:1002
+#: bisect.c:1003
 #, 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] "Bisectando: falta %d revisión por probar después de esto %s\n"
 msgstr[1] "Bisectando: faltan %d revisiones por probar después de esto %s\n"
 
-#: blame.c:1758
+#: blame.c:1756
 msgid "--contents and --reverse do not blend well."
 msgstr "--contents y --reverse no se mezclan bien."
 
-#: blame.c:1769
+#: blame.c:1767
 msgid "cannot use --contents with final commit object name"
 msgstr "no se puede usar --contents con el nombre de objeto commit final"
 
-#: blame.c:1789
+#: blame.c:1787
 msgid "--reverse and --first-parent together require specified latest commit"
 msgstr ""
 "--reverse y --first-parent juntos requieren especificar el último commit"
 
-#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699
-#: sequencer.c:2901 builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920
-#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370
-#: builtin/shortlog.c:191
+#: blame.c:1796 bundle.c:160 ref-filter.c:2075 sequencer.c:1861
+#: sequencer.c:3632 builtin/commit.c:981 builtin/log.c:366 builtin/log.c:920
+#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:372
+#: builtin/shortlog.c:192
 msgid "revision walk setup failed"
-msgstr "fallo la configuración del camino de revisión"
+msgstr "falló la configuración del camino de revisión"
 
-#: blame.c:1816
+#: blame.c:1814
 msgid ""
 "--reverse --first-parent together require range along first-parent chain"
 msgstr ""
 "--reverse --first-parent juntos requieren un rango a lo largo de la cadena "
 "del primer padre"
 
-#: blame.c:1827
+#: blame.c:1825
 #, c-format
 msgid "no such path %s in %s"
 msgstr "no hay una ruta %s en %s"
 
-#: blame.c:1838
+#: blame.c:1836
 #, c-format
 msgid "cannot read blob %s for path %s"
 msgstr "no se puede leer el blob %s para la ruta %s"
 
-#: branch.c:53
+#: branch.c:54
 #, c-format
 msgid ""
 "\n"
@@ -1044,97 +1044,97 @@ msgstr ""
 "la infamación del rastreo remoto invocando\n"
 "\"git branch --set-upstream-to=%s%s%s\"."
 
-#: branch.c:67
+#: branch.c:68
 #, c-format
 msgid "Not setting branch %s as its own upstream."
 msgstr "La rama %s no se configura como su propio upstream."
 
-#: branch.c:93
+#: branch.c:94
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s' by rebasing."
 msgstr ""
 "Rama '%s' configurada para hacer seguimiento a la rama remota '%s' de '%s' "
 "por rebase."
 
-#: branch.c:94
+#: branch.c:95
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s'."
 msgstr ""
 "Rama '%s' configurada para hacer seguimiento a la rama remota '%s' de '%s'."
 
-#: branch.c:98
+#: branch.c:99
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s' by rebasing."
 msgstr ""
 "Rama '%s' configurada para hacer seguimiento a la rama local '%s' por rebase."
 
-#: branch.c:99
+#: branch.c:100
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s'."
 msgstr "Rama '%s' configurada para hacer seguimiento a la rama local '%s'."
 
-#: branch.c:104
+#: branch.c:105
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s' by rebasing."
 msgstr ""
 "Rama '%s' configurada para hacer seguimiento a la referencia remota '%s' por "
 "rebase."
 
-#: branch.c:105
+#: branch.c:106
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s'."
 msgstr ""
 "Rama '%s' configurada para hacer seguimiento a la referencia remota '%s'."
 
-#: branch.c:109
+#: branch.c:110
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s' by rebasing."
 msgstr ""
 "Rama '%s' configurada para hacer seguimiento a la referencia local '%s' por "
 "rebase."
 
-#: branch.c:110
+#: branch.c:111
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s'."
 msgstr ""
 "Rama '%s' configurada para hacer seguimiento a la referencia local '%s'."
 
-#: branch.c:119
+#: branch.c:120
 msgid "Unable to write upstream branch configuration"
 msgstr "No es posible escribir la configuración de la rama upstream"
 
-#: branch.c:156
+#: branch.c:157
 #, c-format
 msgid "Not tracking: ambiguous information for ref %s"
 msgstr "No rastreando: información ambigua para la referencia %s"
 
-#: branch.c:189
+#: branch.c:190
 #, c-format
 msgid "'%s' is not a valid branch name."
 msgstr "'%s' no es un nombre valido de rama."
 
-#: branch.c:208
+#: branch.c:209
 #, c-format
 msgid "A branch named '%s' already exists."
 msgstr "Una rama llamada '%s' ya existe."
 
-#: branch.c:213
+#: branch.c:214
 msgid "Cannot force update the current branch."
 msgstr "No se puede forzar la actualización de la rama actual."
 
-#: branch.c:233
+#: branch.c:234
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr ""
 "No se puede configurar el rastreo de información; el punto de partida '%s' "
 "no es una rama."
 
-#: branch.c:235
+#: branch.c:236
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr "la rama de upstream solicitada '%s' no existe"
 
-#: branch.c:237
+#: branch.c:238
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -1155,27 +1155,27 @@ msgstr ""
 "\"git push -u\" para configurar tu upstream predeterminado cuando realizas "
 "el push."
 
-#: branch.c:280
+#: branch.c:281
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "Nombre de objeto no valido: '%s'."
 
-#: branch.c:300
+#: branch.c:301
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "Nombre de objeto ambiguo: '%s'."
 
-#: branch.c:305
+#: branch.c:306
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "Punto de rama no valido: '%s'."
 
-#: branch.c:359
+#: branch.c:360
 #, c-format
 msgid "'%s' is already checked out at '%s'"
 msgstr "'%s' ya ha sido marcado en '%s'"
 
-#: branch.c:382
+#: branch.c:383
 #, c-format
 msgid "HEAD of working tree %s is not updated"
 msgstr "HEAD del árbol de trabajo %s no esta actualizada"
@@ -1190,7 +1190,7 @@ msgstr "'%s' no se ve como un archivo bundle v2"
 msgid "unrecognized header: %s%s (%d)"
 msgstr "header no reconocido %s%s (%d)"
 
-#: bundle.c:88 sequencer.c:1879 sequencer.c:2337 builtin/commit.c:750
+#: bundle.c:88 sequencer.c:2081 sequencer.c:2558 builtin/commit.c:755
 #, c-format
 msgid "could not open '%s'"
 msgstr "no se pudo abrir '%s'"
@@ -1234,7 +1234,7 @@ msgstr "rev-list murió"
 msgid "ref '%s' is excluded by the rev-list options"
 msgstr "referencia '%s' es excluida por las opciones de rev-list"
 
-#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:296
+#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:303
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "argumento no reconocido: %s"
@@ -1257,18 +1257,39 @@ msgstr "index-pack murió"
 msgid "invalid color value: %.*s"
 msgstr "color inválido: %.*s"
 
-#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465
-#: builtin/am.c:1436 builtin/am.c:2072
+#: commit.c:43 sequencer.c:2364 builtin/am.c:421 builtin/am.c:465
+#: builtin/am.c:1436 builtin/am.c:2072 builtin/replace.c:376
+#: builtin/replace.c:448
 #, c-format
 msgid "could not parse %s"
 msgstr "no se puede analizar %s"
 
-#: commit.c:43
+#: commit.c:45
 #, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s no es un commit!"
 
-#: commit.c:1506
+#: commit.c:182
+msgid ""
+"Support for <GIT_DIR>/info/grafts is deprecated\n"
+"and will be removed in a future Git version.\n"
+"\n"
+"Please use \"git replace --convert-graft-file\"\n"
+"to convert the grafts into replace refs.\n"
+"\n"
+"Turn this message off by running\n"
+"\"git config advice.graftFileDeprecated false\""
+msgstr ""
+"El soporte para <GIT_DIR>/info/grafts ha sido deprecado\n"
+"y será removido en una versión futura de Git.\n"
+"\n"
+"Por favor use \"git replace --convert-graft-file\"\n"
+"para convertir los grafts en refs.\n"
+"\n"
+"Apapa este mensaje ejecutando\n"
+"\"git config advice.graftFileDeprecated false\""
+
+#: commit.c:1540
 msgid ""
 "Warning: commit message did not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
@@ -1279,176 +1300,190 @@ msgstr ""
 "variable de configuración i18n.commitencoding para la codificación que usa "
 "su proyecto.\n"
 
+#: commit-graph.c:669
+#, c-format
+msgid "the commit graph format cannot write %d commits"
+msgstr "el formato de gráficos de commit no pudede escribir %d commits"
+
+#: commit-graph.c:696
+msgid "too many commits to write graph"
+msgstr "demasiados commits para escribir el gráfico"
+
+#: commit-graph.c:707 builtin/init-db.c:516 builtin/init-db.c:521
+#, c-format
+msgid "cannot mkdir %s"
+msgstr "no se pude crear directorio %s"
+
 #: compat/obstack.c:405 compat/obstack.c:407
 msgid "memory exhausted"
 msgstr "memoria agotada"
 
-#: config.c:186
+#: config.c:187
 msgid "relative config include conditionals must come from files"
 msgstr ""
 "la configuración relativa incluye condicionales que deben venir de archivos"
 
-#: config.c:720
+#: config.c:788
 #, c-format
 msgid "bad config line %d in blob %s"
 msgstr "mala línea de config %d en el blob %s"
 
-#: config.c:724
+#: config.c:792
 #, c-format
 msgid "bad config line %d in file %s"
 msgstr "mala línea de config %d en el archivo %s"
 
-#: config.c:728
+#: config.c:796
 #, c-format
 msgid "bad config line %d in standard input"
 msgstr "mala línea de config %d en la entrada standard"
 
-#: config.c:732
+#: config.c:800
 #, c-format
 msgid "bad config line %d in submodule-blob %s"
 msgstr "mala línea de config %d en el submódulo-blob %s"
 
-#: config.c:736
+#: config.c:804
 #, c-format
 msgid "bad config line %d in command line %s"
 msgstr "mala línea de config %d en la línea de comando %s"
 
-#: config.c:740
+#: config.c:808
 #, c-format
 msgid "bad config line %d in %s"
 msgstr "mala línea de config %d en %s"
 
-#: config.c:868
+#: config.c:936
 msgid "out of range"
 msgstr "fuera de rango"
 
-#: config.c:868
+#: config.c:936
 msgid "invalid unit"
 msgstr "unidad invalida"
 
-#: config.c:874
+#: config.c:942
 #, c-format
 msgid "bad numeric config value '%s' for '%s': %s"
 msgstr "mal valor de config numérica '%s' para '%s': %s"
 
-#: config.c:879
+#: config.c:947
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
 msgstr "mal valor de config numérica '%s' para '%s' en el blob %s: %s"
 
-#: config.c:882
+#: config.c:950
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in file %s: %s"
 msgstr "mal valor de config numérica '%s' para '%s' en el archivo %s: %s"
 
-#: config.c:885
+#: config.c:953
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in standard input: %s"
 msgstr "mal valor de config numérica '%s' para '%s' en la entrada standard: %s"
 
-#: config.c:888
+#: config.c:956
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
 msgstr ""
 "mal valor de config numérica '%s' para '%s' en el submódulo-blob %s: %s"
 
-#: config.c:891
+#: config.c:959
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
 msgstr ""
 "mal valor de config numérica '%s' para '%s' en la línea de comando %s: %s"
 
-#: config.c:894
+#: config.c:962
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in %s: %s"
 msgstr "mal valor de config numérica '%s' para '%s' en %s: %s"
 
-#: config.c:989
+#: config.c:1057
 #, c-format
 msgid "failed to expand user dir in: '%s'"
-msgstr "fallo al expandir el directorio de usuario en: '%s'"
+msgstr "falló al expandir el directorio de usuario en: '%s'"
 
-#: config.c:998
+#: config.c:1066
 #, c-format
 msgid "'%s' for '%s' is not a valid timestamp"
 msgstr "'%s' para '%s' no es una marca de tiempo válida"
 
-#: config.c:1094 config.c:1105
+#: config.c:1171 config.c:1182
 #, c-format
 msgid "bad zlib compression level %d"
 msgstr "mala compresión zlib en nivel %d"
 
-#: config.c:1225
+#: config.c:1307
 #, c-format
 msgid "invalid mode for object creation: %s"
 msgstr "modo invalido de creación de objetos: %s"
 
-#: config.c:1386
+#: config.c:1473
 #, c-format
 msgid "bad pack compression level %d"
 msgstr "mala compresión pack en el nivel %d"
 
-#: config.c:1582
+#: config.c:1681
 msgid "unable to parse command-line config"
 msgstr "no es posible analizar la configuración de la línea de comando"
 
-#: config.c:1914
+#: config.c:2013
 msgid "unknown error occurred while reading the configuration files"
 msgstr ""
 "error desconocido ocurrió mientras se leían los archivos de configuración"
 
-#: config.c:2101
+#: config.c:2200
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "Invalido %s: '%s'"
 
-#: config.c:2144
+#: config.c:2243
 #, c-format
 msgid "unknown core.untrackedCache value '%s'; using 'keep' default value"
 msgstr ""
 "valor core.untrackedCache '%s' desconocido; usando 'keep' como valor por "
 "defecto"
 
-#: config.c:2170
+#: config.c:2269
 #, c-format
 msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100"
 msgstr "valor splitIndex.maxPercentChange '%d' debe estar entre 0 y 100"
 
-#: config.c:2195
+#: config.c:2294
 #, c-format
 msgid "unable to parse '%s' from command-line config"
 msgstr "no es posible analizar '%s' de la configuración de la línea de comando"
 
-#: config.c:2197
+#: config.c:2296
 #, c-format
 msgid "bad config variable '%s' in file '%s' at line %d"
 msgstr "mala variable de config '%s' en el archivo '%s' en la línea %d"
 
-#: config.c:2256
+#: config.c:2402
 #, c-format
 msgid "%s has multiple values"
 msgstr "%s tiene múltiples valores"
 
-#: config.c:2599 config.c:2816
+#: config.c:2766 config.c:3019
 #, c-format
 msgid "fstat on %s failed"
-msgstr "fstat en %s fallo"
+msgstr "fstat en %s falló"
 
-#: config.c:2706
+#: config.c:2905
 #, c-format
 msgid "could not set '%s' to '%s'"
 msgstr "no se pudo configurar '%s' a '%s'"
 
-#: config.c:2708 builtin/remote.c:776
+#: config.c:2907 builtin/remote.c:779
 #, c-format
 msgid "could not unset '%s'"
 msgstr "no se pudo desactivar '%s'"
 
-#: connect.c:52
+#: connect.c:61
 msgid "The remote end hung up upon initial contact"
 msgstr "El remoto se colgó en el contacto inicial"
 
-#: connect.c:54
+#: connect.c:63
 msgid ""
 "Could not read from remote repository.\n"
 "\n"
@@ -1460,7 +1495,7 @@ msgstr ""
 "Por favor asegúrese que tiene los permisos de acceso correctos\n"
 "y que el repositorio existe."
 
-#: connected.c:66 builtin/fsck.c:198 builtin/prune.c:144
+#: connected.c:66 builtin/fsck.c:201 builtin/prune.c:145
 msgid "Checking connectivity"
 msgstr "Verificando conectividad"
 
@@ -1470,18 +1505,18 @@ msgstr "No se pudo correr 'git rev-list'"
 
 #: connected.c:98
 msgid "failed write to rev-list"
-msgstr "fallo escribir a rev-list"
+msgstr "falló escribir a rev-list"
 
 #: connected.c:105
 msgid "failed to close rev-list's stdin"
-msgstr "fallo al cerrar la entrada standard de rev-list"
+msgstr "falló al cerrar la entrada standard de rev-list"
 
-#: convert.c:205
+#: convert.c:206
 #, c-format
 msgid "CRLF would be replaced by LF in %s."
 msgstr "CRLF será reemplazado por LF en %s."
 
-#: convert.c:207
+#: convert.c:208
 #, c-format
 msgid ""
 "CRLF will be replaced by LF in %s.\n"
@@ -1491,12 +1526,12 @@ msgstr ""
 "El archivo tendrá sus finales de línea originales en tu directorio de "
 "trabajo."
 
-#: convert.c:215
+#: convert.c:216
 #, c-format
 msgid "LF would be replaced by CRLF in %s"
 msgstr "LF será reemplazado por CRLF en %s"
 
-#: convert.c:217
+#: convert.c:218
 #, c-format
 msgid ""
 "LF will be replaced by CRLF in %s.\n"
@@ -1506,6 +1541,48 @@ msgstr ""
 "El archivo tendrá sus finales de línea originales en tu directorio de "
 "trabajo."
 
+#: convert.c:279
+#, c-format
+msgid "BOM is prohibited in '%s' if encoded as %s"
+msgstr "BOM está prohibido en '%s' si es codificado como %s"
+
+#: convert.c:286
+#, c-format
+msgid ""
+"The file '%s' contains a byte order mark (BOM). Please use UTF-%s as working-"
+"tree-encoding."
+msgstr ""
+"El archivo '%s' contiene una marca de byte (BOM). Por favor usa UTF-%s como "
+"working-tree-encoding."
+
+#: convert.c:304
+#, c-format
+msgid "BOM is required in '%s' if encoded as %s"
+msgstr "BOM es requerido en '%s' si es codificado como %s"
+
+#: convert.c:306
+#, 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 ""
+"Al archivo '%s' le falta una marca de byte (BOM). Por favor usa UTF-%sBE o "
+"UTF-%sLE (dependiendo en el orden de byte) como working-tree-encoding."
+
+#: convert.c:424
+#, c-format
+msgid "failed to encode '%s' from %s to %s"
+msgstr "falló al codificar '%s' de %s a %s"
+
+#: convert.c:467
+#, c-format
+msgid "encoding '%s' from %s to %s and back is not the same"
+msgstr "codificación '%s' de %s a %s y de vuelta no son iguales"
+
+#: convert.c:1225
+msgid "true/false are no valid working-tree-encodings"
+msgstr "true/false no son working-tree-encodings válidos"
+
 #: date.c:116
 msgid "in the future"
 msgstr "en el futuro"
@@ -1577,7 +1654,7 @@ msgstr[1] "hace %<PRIuMAX> años"
 #: diffcore-order.c:24
 #, c-format
 msgid "failed to read orderfile '%s'"
-msgstr "fallo al leer orden de archivos '%s'"
+msgstr "falló al leer orden de archivos '%s'"
 
 #: diffcore-rename.c:535
 msgid "Performing inexact rename detection"
@@ -1591,7 +1668,7 @@ msgstr "opción '%s' requiere un valor"
 #: diff.c:152
 #, c-format
 msgid "  Failed to parse dirstat cut-off percentage '%s'\n"
-msgstr "  Fallo al analizar dirstat porcentaje de corte '%s'\n"
+msgstr "  Falló al analizar dirstat porcentaje de corte '%s'\n"
 
 #: diff.c:157
 #, c-format
@@ -1621,48 +1698,48 @@ msgstr ""
 "Errores en la variable de config 'diff.dirstat' encontrados:\n"
 "%s"
 
-#: diff.c:3822
+#: diff.c:3823
 #, c-format
 msgid "external diff died, stopping at %s"
 msgstr "diff externo murió, deteniendo en %s"
 
-#: diff.c:4146
+#: diff.c:4153
 msgid "--name-only, --name-status, --check and -s are mutually exclusive"
 msgstr "--name-only, --name-status, --check y -s son mutuamente exclusivas"
 
-#: diff.c:4149
+#: diff.c:4156
 msgid "-G, -S and --find-object are mutually exclusive"
 msgstr "-G, -S y --find-object son mutuamente exclusivas"
 
-#: diff.c:4237
+#: diff.c:4244
 msgid "--follow requires exactly one pathspec"
 msgstr "--follow requiere exactamente un pathspec"
 
-#: diff.c:4403
+#: diff.c:4410
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
 "%s"
 msgstr ""
-"Fallo al analizar parámetro de opción --dirstat/-X:\n"
+"Falló al analizar parámetro de opción --dirstat/-X:\n"
 "%s"
 
-#: diff.c:4417
+#: diff.c:4424
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
-msgstr "Fallo al analizar parámetro de opción --submodule: '%s'"
+msgstr "Falló al analizar parámetro de opción --submodule: '%s'"
 
-#: diff.c:5493
+#: diff.c:5500
 msgid "inexact rename detection was skipped due to too many files."
 msgstr ""
 "detección de cambio de nombre inexacta fue saltada por haber muchos archivos."
 
-#: diff.c:5496
+#: diff.c:5503
 msgid "only found copies from modified paths due to too many files."
 msgstr ""
 "solo se encontraron copias de rutas modificadas por haber muchos archivos."
 
-#: diff.c:5499
+#: diff.c:5506
 #, c-format
 msgid ""
 "you may want to set your %s variable to at least %d and retry the command."
@@ -1670,25 +1747,25 @@ msgstr ""
 "tal vez quiera configurar la variable %s para por lo menos %d y volver a "
 "intentar el comando."
 
-#: dir.c:1866
+#: dir.c:1867
 #, c-format
 msgid "could not open directory '%s'"
 msgstr "no se pudo abrir el directorio '%s'"
 
-#: dir.c:2108
+#: dir.c:2109
 msgid "failed to get kernel name and information"
-msgstr "fallo al conseguir la información y nombre del kernel"
+msgstr "falló al conseguir la información y nombre del kernel"
 
-#: dir.c:2232
+#: dir.c:2233
 msgid "Untracked cache is disabled on this system or location."
 msgstr "Untracked cache esta desactivado en este sistema o ubicación."
 
-#: dir.c:3024 dir.c:3029
+#: dir.c:3075 dir.c:3080
 #, c-format
 msgid "could not create directories for %s"
 msgstr "no se pudo crear directorios para %s"
 
-#: dir.c:3054
+#: dir.c:3109
 #, c-format
 msgid "could not migrate git directory from '%s' to '%s'"
 msgstr "no se pudo migrar el directorio git de '%s' a '%s'"
@@ -1711,240 +1788,305 @@ msgstr "no se pudo establecer el archivo '%s'"
 msgid "Remote with no URL"
 msgstr "Remoto sin URL"
 
-#: fetch-pack.c:253
+#: fetch-pack.c:254
 msgid "git fetch-pack: expected shallow list"
 msgstr "git fetch-pack: lista poco profunda esperada"
 
-#: fetch-pack.c:265
+#: fetch-pack.c:266
 msgid "git fetch-pack: expected ACK/NAK, got a flush packet"
 msgstr "git fetch-pack: se esperaba ACK/NAK, se obtuvo un flush packet"
 
-#: fetch-pack.c:284 builtin/archive.c:63
+#: fetch-pack.c:285 builtin/archive.c:63
 #, c-format
 msgid "remote error: %s"
 msgstr "error remoto: %s"
 
-#: fetch-pack.c:285
+#: fetch-pack.c:286
 #, c-format
 msgid "git fetch-pack: expected ACK/NAK, got '%s'"
 msgstr "git fetch-pack: se esperaba ACK/NAK, se obtuvo '%s'"
 
-#: fetch-pack.c:337
+#: fetch-pack.c:338
 msgid "--stateless-rpc requires multi_ack_detailed"
 msgstr "--stateless-rpc requiere multi_ack_detailed"
 
-#: fetch-pack.c:428
+#: fetch-pack.c:429 fetch-pack.c:1310
 #, c-format
 msgid "invalid shallow line: %s"
 msgstr "línea poco profunda invalida: %s"
 
-#: fetch-pack.c:434
+#: fetch-pack.c:435 fetch-pack.c:1316
 #, c-format
 msgid "invalid unshallow line: %s"
 msgstr "línea superficial inválida: %s"
 
-#: fetch-pack.c:436
+#: fetch-pack.c:437 fetch-pack.c:1318
 #, c-format
 msgid "object not found: %s"
 msgstr "objeto no encontrado: %s"
 
-#: fetch-pack.c:439
+#: fetch-pack.c:440 fetch-pack.c:1321
 #, c-format
 msgid "error in object: %s"
 msgstr "error en objeto: %s"
 
-#: fetch-pack.c:441
+#: fetch-pack.c:442 fetch-pack.c:1323
 #, c-format
 msgid "no shallow found: %s"
 msgstr "superficie no encontrada: %s"
 
-#: fetch-pack.c:444
+#: fetch-pack.c:445 fetch-pack.c:1326
 #, c-format
 msgid "expected shallow/unshallow, got %s"
 msgstr "se esperaba shallow/unshallow, se obtuvo %s"
 
-#: fetch-pack.c:485
+#: fetch-pack.c:486
 #, c-format
 msgid "got %s %d %s"
 msgstr "se obtuvo %s %d %s"
 
-#: fetch-pack.c:499
+#: fetch-pack.c:500
 #, c-format
 msgid "invalid commit %s"
 msgstr "commit inválido %s"
 
-#: fetch-pack.c:532
+#: fetch-pack.c:533
 msgid "giving up"
 msgstr "rindiéndose"
 
-#: fetch-pack.c:542 progress.c:229
+#: fetch-pack.c:543 progress.c:229
 msgid "done"
 msgstr "listo"
 
-#: fetch-pack.c:554
+#: fetch-pack.c:555
 #, c-format
 msgid "got %s (%d) %s"
 msgstr "se obtuvo %s (%d) %s"
 
-#: fetch-pack.c:600
+#: fetch-pack.c:601
 #, c-format
 msgid "Marking %s as complete"
 msgstr "Marcando %s como completa"
 
-#: fetch-pack.c:788
+#: fetch-pack.c:828
 #, c-format
 msgid "already have %s (%s)"
 msgstr "ya se tiene %s (%s)"
 
-#: fetch-pack.c:829
+#: fetch-pack.c:869
 msgid "fetch-pack: unable to fork off sideband demultiplexer"
 msgstr "fetch-pack: no se puede extraer un demultiplexor de banda lateral"
 
-#: fetch-pack.c:837
+#: fetch-pack.c:877
 msgid "protocol error: bad pack header"
 msgstr "error de protocolo: mal paquete de header"
 
-#: fetch-pack.c:895
+#: fetch-pack.c:944
 #, c-format
 msgid "fetch-pack: unable to fork off %s"
 msgstr "fetch-pack: no se puede quitar %s"
 
-#: fetch-pack.c:911
+#: fetch-pack.c:960
 #, c-format
 msgid "%s failed"
-msgstr "%s fallo"
+msgstr "%s falló"
 
-#: fetch-pack.c:913
+#: fetch-pack.c:962
 msgid "error in sideband demultiplexer"
 msgstr "error en demultiplexor de banda lateral"
 
-#: fetch-pack.c:940
+#: fetch-pack.c:989
 msgid "Server does not support shallow clients"
 msgstr "Servidor no soporta clientes superficiales"
 
-#: fetch-pack.c:944
+#: fetch-pack.c:993
 msgid "Server supports multi_ack_detailed"
 msgstr "Servidor soporta ulti_ack_detailed"
 
-#: fetch-pack.c:947
+#: fetch-pack.c:996
 msgid "Server supports no-done"
 msgstr "Servidor soporta no-done"
 
-#: fetch-pack.c:953
+#: fetch-pack.c:1002
 msgid "Server supports multi_ack"
 msgstr "Servidor soporta multi_ack"
 
-#: fetch-pack.c:957
+#: fetch-pack.c:1006
 msgid "Server supports side-band-64k"
 msgstr "Servidor soporta side-band-64k"
 
-#: fetch-pack.c:961
+#: fetch-pack.c:1010
 msgid "Server supports side-band"
 msgstr "Servidor soporta side-band"
 
-#: fetch-pack.c:965
+#: fetch-pack.c:1014
 msgid "Server supports allow-tip-sha1-in-want"
 msgstr "Servidor soporta allow-tip-sha1-in-want"
 
-#: fetch-pack.c:969
+#: fetch-pack.c:1018
 msgid "Server supports allow-reachable-sha1-in-want"
 msgstr "Servidor soporta allow-reachable-sha1-in-want"
 
-#: fetch-pack.c:979
+#: fetch-pack.c:1028
 msgid "Server supports ofs-delta"
 msgstr "Servidor soporta ofs-delta"
 
-#: fetch-pack.c:985
+#: fetch-pack.c:1034 fetch-pack.c:1204
 msgid "Server supports filter"
 msgstr "Servidor soporta filtro"
 
-#: fetch-pack.c:993
+#: fetch-pack.c:1042
 #, c-format
 msgid "Server version is %.*s"
 msgstr "Versión de servidor es %.*s"
 
-#: fetch-pack.c:999
+#: fetch-pack.c:1048
 msgid "Server does not support --shallow-since"
 msgstr "Servidor no soporta --shalow-since"
 
-#: fetch-pack.c:1003
+#: fetch-pack.c:1052
 msgid "Server does not support --shallow-exclude"
 msgstr "Servidor no soporta --shalow-exclude"
 
-#: fetch-pack.c:1005
+#: fetch-pack.c:1054
 msgid "Server does not support --deepen"
 msgstr "Servidor no soporta --deepen"
 
-#: fetch-pack.c:1016
+#: fetch-pack.c:1065
 msgid "no common commits"
 msgstr "no hay commits comunes"
 
-#: fetch-pack.c:1028
+#: fetch-pack.c:1077 fetch-pack.c:1414
 msgid "git fetch-pack: fetch failed."
-msgstr "git fetch-pack: fetch fallo."
+msgstr "git fetch-pack: fetch falló."
 
-#: fetch-pack.c:1190
+#: fetch-pack.c:1199
+msgid "Server does not support shallow requests"
+msgstr "Servidor no soporta peticiones superficiales"
+
+#: fetch-pack.c:1584
 msgid "no matching remote head"
 msgstr "no concuerda el head remoto"
 
-#: fetch-pack.c:1212
+#: fetch-pack.c:1610
 #, c-format
 msgid "no such remote ref %s"
 msgstr "no existe ref remota %s"
 
-#: fetch-pack.c:1215
+#: fetch-pack.c:1613
 #, c-format
 msgid "Server does not allow request for unadvertised object %s"
 msgstr "Servidor no permite solicitudes de objetos inadvertidos %s"
 
-#: gpg-interface.c:181
+#: gpg-interface.c:185
 msgid "gpg failed to sign the data"
-msgstr "gpg fallo al firmar la data"
+msgstr "gpg falló al firmar la data"
 
-#: gpg-interface.c:211
+#: gpg-interface.c:210
 msgid "could not create temporary file"
 msgstr "no se pudo crear archivo temporal"
 
-#: gpg-interface.c:214
+#: gpg-interface.c:213
 #, c-format
 msgid "failed writing detached signature to '%s'"
-msgstr "fallo al escribir la firma separada para '%s'"
+msgstr "falló al escribir la firma separada para '%s'"
 
 #: graph.c:97
 #, c-format
 msgid "ignore invalid color '%.*s' in log.graphColors"
 msgstr "ignora color invalido '%.*s' en log.graphColors"
 
-#: grep.c:2022
+#: grep.c:2020
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "'%s': no es posible leer %s"
 
-#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81
+#: grep.c:2037 setup.c:164 builtin/clone.c:409 builtin/diff.c:81
 #: builtin/rm.c:134
 #, c-format
 msgid "failed to stat '%s'"
-msgstr "fallo al marcar '%s'"
+msgstr "falló al marcar '%s'"
 
-#: grep.c:2050
+#: grep.c:2048
 #, c-format
 msgid "'%s': short read"
 msgstr "'%s': lectura corta"
 
-#: help.c:179
+#: help.c:23
+msgid "start a working area (see also: git help tutorial)"
+msgstr "comienza un área de trabajo (ver también: git help tutorial)"
+
+#: help.c:24
+msgid "work on the current change (see also: git help everyday)"
+msgstr "trabaja en los cambios actuales (ver también: git help everyday)"
+
+#: help.c:25
+msgid "examine the history and state (see also: git help revisions)"
+msgstr "examina el historial y el estado (ver también: git help revisions)"
+
+#: help.c:26
+msgid "grow, mark and tweak your common history"
+msgstr "crece, marca y ajusta tu historial común"
+
+#: help.c:27
+msgid "collaborate (see also: git help workflows)"
+msgstr "colabora (mira también: git help workflows)"
+
+#: help.c:31
+msgid "Main Porcelain Commands"
+msgstr "Comandos de Porcelana principales"
+
+#: help.c:32
+msgid "Ancillary Commands / Manipulators"
+msgstr "Comandos auxiliares / Manipuladores"
+
+#: help.c:33
+msgid "Ancillary Commands / Interrogators"
+msgstr "Comandos auxiliares / Interrogadores"
+
+#: help.c:34
+msgid "Interacting with Others"
+msgstr "Interactuando con Otros"
+
+#: help.c:35
+msgid "Low-level Commands / Manipulators"
+msgstr "Comandos de bajo nivel / Manipuladores"
+
+#: help.c:36
+msgid "Low-level Commands / Interrogators"
+msgstr "Comandos de bajo nivel / Interrogadores"
+
+#: help.c:37
+msgid "Low-level Commands / Synching Repositories"
+msgstr "Comandos de bajo nivel / Sincronización de repositorios"
+
+#: help.c:38
+msgid "Low-level Commands / Internal Helpers"
+msgstr "Comandos de bajo nivel / Auxiliares internos"
+
+#: help.c:293
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "comandos disponibles de git en '%s'"
 
-#: help.c:186
+#: help.c:300
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "comandos disponibles de git desde otro lugar en tu $PATH"
 
-#: help.c:217
+#: help.c:309
 msgid "These are common Git commands used in various situations:"
 msgstr "Estos son comandos comunes de Git usados en varias situaciones:"
 
-#: help.c:281
+#: help.c:358 git.c:90
+#, c-format
+msgid "unsupported command listing type '%s'"
+msgstr "comando de listado de tipos no soportado '%s'"
+
+#: help.c:405
+msgid "The common Git guides are:"
+msgstr "Las guías comunes de Git son:"
+
+#: help.c:467
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -1953,31 +2095,31 @@ msgstr ""
 "'%s' parece ser un comando de git, pero no hemos\n"
 "podido ejecutarlo. Tal vez git-%s se ha roto?"
 
-#: help.c:336
+#: help.c:526
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Oh oh. Tu sistema no reporta ningún comando de Git."
 
-#: help.c:358
+#: help.c:548
 #, c-format
 msgid "WARNING: You called a Git command named '%s', which does not exist."
 msgstr "PELIGRO: Has llamado a un comando de Git '%s', el cual no existe."
 
-#: help.c:363
+#: help.c:553
 #, c-format
 msgid "Continuing under the assumption that you meant '%s'."
 msgstr "Continuando asumiendo que quisiste decir '%s'."
 
-#: help.c:368
+#: help.c:558
 #, c-format
 msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
 msgstr "Continuando en %0.1f segundos, asumiendo que tu dijiste '%s'."
 
-#: help.c:376
+#: help.c:566
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git: '%s'no es un comando de git. Mira 'git --help'."
 
-#: help.c:380
+#: help.c:570
 msgid ""
 "\n"
 "The most similar command is"
@@ -1991,16 +2133,16 @@ msgstr[1] ""
 "\n"
 "Los comandos mas similares son"
 
-#: help.c:395
+#: help.c:585
 msgid "git version [<options>]"
 msgstr "git versión [<opciones>]"
 
-#: help.c:462
+#: help.c:652
 #, c-format
 msgid "%s: %s - %s"
 msgstr "%s: %s - %s"
 
-#: help.c:466
+#: help.c:656
 msgid ""
 "\n"
 "Did you mean this?"
@@ -2068,7 +2210,7 @@ msgstr "no se puede tener un nombre vacío (para <%s>)"
 msgid "name consists only of disallowed characters: %s"
 msgstr "el nombre consiste solo de caracteres no permitidos: %s"
 
-#: ident.c:416 builtin/commit.c:582
+#: ident.c:416 builtin/commit.c:587
 #, c-format
 msgid "invalid date format: %s"
 msgstr "formato de fecha invalido: %s"
@@ -2106,82 +2248,161 @@ msgstr ""
 msgid "Unable to create '%s.lock': %s"
 msgstr "No se pudo crear '%s.lock': %s"
 
-#: merge.c:74
+#: merge.c:71
 msgid "failed to read the cache"
-msgstr "fallo al leer la cache"
+msgstr "falló al leer la cache"
 
-#: merge.c:134 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
-#: builtin/checkout.c:599 builtin/clone.c:759
+#: merge.c:136 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
+#: builtin/checkout.c:606 builtin/clone.c:761
 msgid "unable to write new index file"
 msgstr "no es posible escribir el archivo índice"
 
-#: merge-recursive.c:235
+#: merge-recursive.c:298
 msgid "(bad commit)\n"
 msgstr "(mal commit)\n"
 
-#: merge-recursive.c:257 merge-recursive.c:265
+#: merge-recursive.c:320
+#, c-format
+msgid "add_cacheinfo failed for path '%s'; merge aborting."
+msgstr "add_cacheinfo falló para la ruta '%s'; abortando fusión."
+
+#: merge-recursive.c:328
 #, c-format
-msgid "addinfo_cache failed for path '%s'"
-msgstr "addinfo_cache fallo para la ruta '%s'"
+msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
+msgstr "add_cacheinfo falló para refrescar la ruta '%s'; abortando fusión."
 
-#: merge-recursive.c:329
+#: merge-recursive.c:410
 msgid "error building trees"
 msgstr "error construyendo árboles"
 
-#: merge-recursive.c:771
+#: merge-recursive.c:881
 #, c-format
 msgid "failed to create path '%s'%s"
-msgstr "fallo al crear la ruta '%s'%s"
+msgstr "falló al crear la ruta '%s'%s"
 
-#: merge-recursive.c:782
+#: merge-recursive.c:892
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr "Removiendo %s para hacer espacio para un subdirectorio\n"
 
-#: merge-recursive.c:796 merge-recursive.c:815
+#: merge-recursive.c:906 merge-recursive.c:925
 msgid ": perhaps a D/F conflict?"
 msgstr ": tal vez un conflicto D/F?"
 
-#: merge-recursive.c:805
+#: merge-recursive.c:915
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
 msgstr "rehusando perder el archivo rastreado en '%s'"
 
-#: merge-recursive.c:847 builtin/cat-file.c:37
+#: merge-recursive.c:957 builtin/cat-file.c:37
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr "no se puede leer el objeto %s '%s'"
 
-#: merge-recursive.c:849
+#: merge-recursive.c:959
 #, c-format
 msgid "blob expected for %s '%s'"
 msgstr "se esperaba blob para %s '%s'"
 
-#: merge-recursive.c:873
+#: merge-recursive.c:983
 #, c-format
 msgid "failed to open '%s': %s"
-msgstr "fallo al abrir '%s': %s"
+msgstr "falló al abrir '%s': %s"
 
-#: merge-recursive.c:884
+#: merge-recursive.c:994
 #, c-format
 msgid "failed to symlink '%s': %s"
-msgstr "fallo al crear el enlace simbólico '%s': %s"
+msgstr "falló al crear el enlace simbólico '%s': %s"
 
-#: merge-recursive.c:889
+#: merge-recursive.c:999
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
 msgstr "no se que hacer con %06o %s '%s'"
 
-#: merge-recursive.c:1029
+#: merge-recursive.c:1186
+#, c-format
+msgid "Failed to merge submodule %s (not checked out)"
+msgstr "Falló al fusionar el submódulo %s (no revisado)"
+
+#: merge-recursive.c:1193
+#, c-format
+msgid "Failed to merge submodule %s (commits not present)"
+msgstr "Falló al fusionar el submódulo %s (commits no presentes)"
+
+#: merge-recursive.c:1200
+#, c-format
+msgid "Failed to merge submodule %s (commits don't follow merge-base)"
+msgstr "Falló el fusionar submódulo %s (commits no siguen la fusión base)"
+
+#: merge-recursive.c:1208 merge-recursive.c:1220
+#, c-format
+msgid "Fast-forwarding submodule %s to the following commit:"
+msgstr "Haciendo fast-forward a submódulo %s para el siguiente commit:"
+
+#: merge-recursive.c:1211 merge-recursive.c:1223
+#, c-format
+msgid "Fast-forwarding submodule %s"
+msgstr "Avance rápido en submódulo %s"
+
+#: merge-recursive.c:1245
+#, c-format
+msgid "Failed to merge submodule %s (merge following commits not found)"
+msgstr ""
+"Falló al fusionar submódulo %s (los siguentes commits no fueron encontrados)"
+
+#: merge-recursive.c:1249
+#, c-format
+msgid "Failed to merge submodule %s (not fast-forward)"
+msgstr "Falló al fusionar el submódulo %s (no es posible avance rápido)"
+
+#: merge-recursive.c:1250
+msgid "Found a possible merge resolution for the submodule:\n"
+msgstr "Se encontró una posible solución de fusión para el submódulo:\n"
+
+#: merge-recursive.c:1253
+#, 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 ""
+"Si esto es correcto simplemente agrégalo al índice por ejemplo\n"
+"usando:\n"
+"\n"
+"  git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"el cual aceptará esta sugerencia.\n"
+
+#: merge-recursive.c:1262
+#, c-format
+msgid "Failed to merge submodule %s (multiple merges found)"
+msgstr "Falló al fusionar el submódulo %s (fusiones múltiples encontradas)"
+
+#: merge-recursive.c:1321
 msgid "Failed to execute internal merge"
-msgstr "Fallo al ejecutar la fusión interna"
+msgstr "Falló al ejecutar la fusión interna"
 
-#: merge-recursive.c:1034
+#: merge-recursive.c:1326
 #, c-format
 msgid "Unable to add %s to database"
 msgstr "No es posible agregar %s a la base de datos"
 
-#: merge-recursive.c:1146
+#: merge-recursive.c:1358
+#, c-format
+msgid "Auto-merging %s"
+msgstr "Auto-fusionando %s"
+
+#: merge-recursive.c:1423
+#, c-format
+msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
+msgstr ""
+"Error: Rehusando perder el archivo no rastreado en %s; escribiéndolo a %s en "
+"cambio."
+
+#: merge-recursive.c:1475
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2190,7 +2411,7 @@ msgstr ""
 "CONFLICTO (%s/borrar): %s borrado en %s y %s en %s. Falta versión %s de %s "
 "en el árbol."
 
-#: merge-recursive.c:1151
+#: merge-recursive.c:1480
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2199,7 +2420,7 @@ msgstr ""
 "CONFLICTO (%s/borrar): %s borrado en %s y %s para %s en %s. Versión %s de %s "
 "permanece en el árbol."
 
-#: merge-recursive.c:1158
+#: merge-recursive.c:1487
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2208,7 +2429,7 @@ msgstr ""
 "CONFLICTO (%s/eliminar): %s eliminado en %s y %s en %s. Versión %s de %s "
 "dejada en el árbol, en %s."
 
-#: merge-recursive.c:1163
+#: merge-recursive.c:1492
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2217,20 +2438,32 @@ msgstr ""
 "CONFLICTO (%s/borrar): %s borrado en %s y %s para %s en %s. Versión %s de %s "
 "permanece en el árbol en %s."
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "rename"
 msgstr "renombrar"
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "renamed"
 msgstr "renombrado"
 
-#: merge-recursive.c:1254
+#: merge-recursive.c:1580 merge-recursive.c:1736 merge-recursive.c:2368
+#: merge-recursive.c:3086
+#, c-format
+msgid "Refusing to lose dirty file at %s"
+msgstr "Rehusando perder el archivo sucio en %s"
+
+#: merge-recursive.c:1594
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr "%s es un directorio en %s agregando como %s más bien"
 
-#: merge-recursive.c:1279
+#: merge-recursive.c:1599
+#, c-format
+msgid "Refusing to lose untracked file at %s; adding as %s instead"
+msgstr ""
+"Rehusando perder el archivo no rastreado en %s; agregándolo como %s en cambio"
+
+#: merge-recursive.c:1625
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
@@ -2239,143 +2472,193 @@ msgstr ""
 "CONFLICTO (renombrar/renombrar): Renombrar \"%s\"->\"%s\" en la rama \"%s\" "
 "renombrar \"%s\"->\"%s\" en \"%s\"%s"
 
-#: merge-recursive.c:1284
+#: merge-recursive.c:1630
 msgid " (left unresolved)"
 msgstr " (dejado sin resolver)"
 
-#: merge-recursive.c:1346
+#: merge-recursive.c:1694
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
 "CONFLICTO (renombrar/renombrar): Renombrar %s->%s en %s. Renombrar %s->%s en "
 "%s"
 
-#: merge-recursive.c:1379
+#: merge-recursive.c:1733
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr "Renombrando %s a %s y %s a %s más bien"
 
-#: merge-recursive.c:1582
+#: merge-recursive.c:1745
+#, c-format
+msgid "Refusing to lose untracked file at %s, even though it's in the way."
+msgstr ""
+"Rehusando perder el archivo no rastreado en %s, incluso aunque se está "
+"interponiendo."
+
+#: merge-recursive.c:1951
+#, c-format
+msgid ""
+"CONFLICT (directory rename split): Unclear where to place %s because "
+"directory %s was renamed to multiple other directories, with no destination "
+"getting a majority of the files."
+msgstr ""
+"CONFLICTO (división de cambio de nombre de directorio): No es claro dónde "
+"colocar %s porque el directorio %s fue renombrado a otros múltiples "
+"directorios, sin ningún que contenga la mayoría de archivos."
+
+#: merge-recursive.c:1983
+#, c-format
+msgid ""
+"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 ""
+"CONFLICTO (cambio de nombre de directorio implícito): Archivo/directorio "
+"existente en %s se interpone con el cambio de nombres implícito, poniendo "
+"la(s) siguiente(s) ruta(s) aquí: %s."
+
+#: merge-recursive.c:1993
+#, 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 ""
+"CONFLICTO (cambio de nombre implícito): No se puede mapear más de una ruta "
+"para %s; cambio de nombre implícito intentó poner estas rutas: %s"
+
+#: merge-recursive.c:2085
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-"
+">%s in %s"
+msgstr ""
+"CONFLICTO (renombrar/renombrar): Renombrar directorio %s->%s en %s. "
+"Renombrar directorio %s->%s en %s"
+
+#: merge-recursive.c:2330
+#, c-format
+msgid ""
+"WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
+"renamed."
+msgstr ""
+"PELIGRO: Evitando aplicar %s -> %s renombrado a %s, porque %s mismo fue "
+"renombrado."
+
+#: merge-recursive.c:2736
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
 msgstr ""
 "CONFLICTO (renombrar/agregar): Renombrar %s->%s en %s. %s agregado en %s"
 
-#: merge-recursive.c:1597
+#: merge-recursive.c:2751
 #, c-format
 msgid "Adding merged %s"
 msgstr "Agregar %s fusionado"
 
-#: merge-recursive.c:1604 merge-recursive.c:1834
+#: merge-recursive.c:2758 merge-recursive.c:3089
 #, c-format
 msgid "Adding as %s instead"
 msgstr "Agregando más bien como %s"
 
-#: merge-recursive.c:1661
+#: merge-recursive.c:2914
 #, c-format
 msgid "cannot read object %s"
 msgstr "no se pudo leer el objeto %s"
 
-#: merge-recursive.c:1664
+#: merge-recursive.c:2917
 #, c-format
 msgid "object %s is not a blob"
 msgstr "objeto %s no es un blob"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modify"
 msgstr "modificar"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modified"
 msgstr "modificado"
 
-#: merge-recursive.c:1743
+#: merge-recursive.c:2997
 msgid "content"
 msgstr "contenido"
 
-#: merge-recursive.c:1750
+#: merge-recursive.c:3004
 msgid "add/add"
 msgstr "agregar/agregar"
 
-#: merge-recursive.c:1786
+#: merge-recursive.c:3046
 #, c-format
 msgid "Skipped %s (merged same as existing)"
 msgstr "Saltado %s (fusionado como existente)"
 
-#: merge-recursive.c:1800
-#, c-format
-msgid "Auto-merging %s"
-msgstr "Auto-fusionando %s"
-
-#: merge-recursive.c:1804 git-submodule.sh:879
+#: merge-recursive.c:3055 git-submodule.sh:895
 msgid "submodule"
 msgstr "submódulo"
 
-#: merge-recursive.c:1805
+#: merge-recursive.c:3056
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
 msgstr "CONFLICTO (%s): Conflicto de fusión en %s"
 
-#: merge-recursive.c:1899
+#: merge-recursive.c:3178
 #, c-format
 msgid "Removing %s"
 msgstr "Eliminando %s"
 
-#: merge-recursive.c:1925
+#: merge-recursive.c:3204
 msgid "file/directory"
 msgstr "archivo/directorio"
 
-#: merge-recursive.c:1931
+#: merge-recursive.c:3210
 msgid "directory/file"
 msgstr "directorio/archivo"
 
-#: merge-recursive.c:1938
+#: merge-recursive.c:3217
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
 msgstr ""
 "CONFLICTO (%s): Hay un directorio con el nombre %s en %s. Agregando %s como "
 "%s"
 
-#: merge-recursive.c:1947
+#: merge-recursive.c:3226
 #, c-format
 msgid "Adding %s"
 msgstr "Agregando %s"
 
-#: merge-recursive.c:1987
+#: merge-recursive.c:3267
 #, c-format
 msgid "Dirty index: cannot merge (dirty: %s)"
 msgstr "Índice sucio: no se puede fusionar (sucio: %s)"
 
-#: merge-recursive.c:1991
+#: merge-recursive.c:3271
 msgid "Already up to date!"
 msgstr "¡Ya está actualizado!"
 
-#: merge-recursive.c:2000
+#: merge-recursive.c:3280
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr "falló la fusión de los árboles %s y %s"
 
-#: merge-recursive.c:2097
+#: merge-recursive.c:3379
 msgid "Merging:"
 msgstr "Fusionando:"
 
-#: merge-recursive.c:2110
+#: merge-recursive.c:3392
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] "se encontró %u ancestro común:"
 msgstr[1] "se encontraron %u ancestros comunes:"
 
-#: merge-recursive.c:2149
+#: merge-recursive.c:3431
 msgid "merge returned no commit"
 msgstr "la fusión no devolvió ningún commit"
 
-#: merge-recursive.c:2212
+#: merge-recursive.c:3495
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr "No se pudo analizar el objeto '%s'"
 
-#: merge-recursive.c:2228 builtin/merge.c:657 builtin/merge.c:816
+#: merge-recursive.c:3511 builtin/merge.c:659 builtin/merge.c:816
 msgid "Unable to write index."
 msgstr "Incapaz de escribir el índice."
 
@@ -2421,32 +2704,32 @@ msgstr "Rehusando reescribir notas en %s (fuera de refs/notes/)"
 msgid "Bad %s value: '%s'"
 msgstr "Mal valor para %s: '%s'"
 
-#: object.c:239
+#: object.c:242
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "incapaz de analizar objeto: %s"
 
-#: packfile.c:561
+#: packfile.c:563
 msgid "offset before end of packfile (broken .idx?)"
 msgstr "offset antes del final del paquete (broken .idx?)"
 
-#: packfile.c:1694
+#: packfile.c:1742
 #, c-format
 msgid "offset before start of pack index for %s (corrupt index?)"
 msgstr ""
 "offset antes del comienzo del índice del paquete para %s (índice corrupto?)"
 
-#: packfile.c:1698
+#: packfile.c:1746
 #, c-format
 msgid "offset beyond end of pack index for %s (truncated index?)"
 msgstr ""
 "offset más allá del índice de fin de paquete para %s (índice truncado?)"
 
-#: parse-options.c:619
+#: parse-options.c:621
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:638
+#: parse-options.c:640
 #, c-format
 msgid "usage: %s"
 msgstr "uso: %s"
@@ -2454,26 +2737,31 @@ msgstr "uso: %s"
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation.
 #.
-#: parse-options.c:644
+#: parse-options.c:646
 #, c-format
 msgid "   or: %s"
 msgstr "   o: %s"
 
-#: parse-options.c:647
+#: parse-options.c:649
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:686
+#: parse-options.c:688
 msgid "-NUM"
 msgstr "-NUM"
 
-#: parse-options-cb.c:108
+#: parse-options-cb.c:44
+#, c-format
+msgid "malformed expiration date '%s'"
+msgstr "fecha de expiración mal formada: '%s'"
+
+#: parse-options-cb.c:112
 #, c-format
 msgid "malformed object name '%s'"
 msgstr "nombre de objeto mal formado '%s'"
 
-#: path.c:891
+#: path.c:892
 #, c-format
 msgid "Could not make %s writable by group"
 msgstr "No se pudo hacer que %s fuera escribible por el grupo"
@@ -2557,7 +2845,7 @@ msgstr "el patrón de ruta '%s' está detrás de un enlace simbólico"
 msgid "unable to parse --pretty format"
 msgstr "incapaz de analizar el formato --pretty"
 
-#: read-cache.c:1473
+#: read-cache.c:1500
 #, c-format
 msgid ""
 "index.version set, but the value is invalid.\n"
@@ -2566,7 +2854,7 @@ msgstr ""
 "index.version configurado, pero el valor no es válido.\n"
 "Usando versión %i"
 
-#: read-cache.c:1483
+#: read-cache.c:1510
 #, c-format
 msgid ""
 "GIT_INDEX_VERSION set, but the value is invalid.\n"
@@ -2575,52 +2863,53 @@ msgstr ""
 "GIT_INDEX_VERSION configurado, pero el valor no es válido.\n"
 "Usando versión %i"
 
-#: read-cache.c:2375 sequencer.c:3248 wrapper.c:658 builtin/merge.c:1049
+#: read-cache.c:2404 sequencer.c:4338 wrapper.c:658 builtin/merge.c:1048
 #, c-format
 msgid "could not close '%s'"
 msgstr "no se pudo cerrar '%s'"
 
-#: read-cache.c:2448 sequencer.c:1900 sequencer.c:2627
+#: read-cache.c:2477 sequencer.c:2102 sequencer.c:3234
 #, c-format
 msgid "could not stat '%s'"
 msgstr "no se pudo definir '%s'"
 
-#: read-cache.c:2461
+#: read-cache.c:2490
 #, c-format
 msgid "unable to open git dir: %s"
 msgstr "no es posible abrir el directorio de git: %s"
 
-#: read-cache.c:2473
+#: read-cache.c:2502
 #, c-format
 msgid "unable to unlink: %s"
 msgstr "no es posible remover el vinculo: %s"
 
-#: refs.c:706
+#: refs.c:732 sequencer.c:4334 sequencer.c:4393 wrapper.c:225 wrapper.c:395
+#: builtin/am.c:779
 #, c-format
-msgid "Could not open '%s' for writing"
-msgstr "No se pudo abrir '%s' para escritura"
+msgid "could not open '%s' for writing"
+msgstr "no se pudo abrir '%s' para escritura"
 
-#: refs.c:1850
+#: refs.c:1880
 msgid "ref updates forbidden inside quarantine environment"
 msgstr "actualizaciones de ref prohibidas dentro de ambiente de cuarentena"
 
-#: refs/files-backend.c:1189
+#: refs/files-backend.c:1191
 #, c-format
 msgid "could not remove reference %s"
 msgstr "no se pudo remover la referencia %s"
 
-#: refs/files-backend.c:1203 refs/packed-backend.c:1528
-#: refs/packed-backend.c:1538
+#: refs/files-backend.c:1205 refs/packed-backend.c:1531
+#: refs/packed-backend.c:1541
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "no se pudo eliminar la referencia %s: %s"
 
-#: refs/files-backend.c:1206 refs/packed-backend.c:1541
+#: refs/files-backend.c:1208 refs/packed-backend.c:1544
 #, c-format
 msgid "could not delete references: %s"
 msgstr "no se pudo eliminar la referencia: %s"
 
-#: ref-filter.c:35 wt-status.c:1842
+#: ref-filter.c:35 wt-status.c:1850
 msgid "gone"
 msgstr "desaparecido"
 
@@ -2639,157 +2928,162 @@ msgstr "detrás %d"
 msgid "ahead %d, behind %d"
 msgstr "delante %d, detrás %d"
 
-#: ref-filter.c:107
+#: ref-filter.c:121
 #, c-format
 msgid "expected format: %%(color:<color>)"
 msgstr "formato esperado: %%(color:<color>)"
 
-#: ref-filter.c:109
+#: ref-filter.c:123
 #, c-format
 msgid "unrecognized color: %%(color:%s)"
 msgstr "color no reconocido: %%(color:%s)"
 
-#: ref-filter.c:129
+#: ref-filter.c:145
 #, c-format
 msgid "Integer value expected refname:lstrip=%s"
 msgstr "Valor entero esperado refname:lstrip=%s"
 
-#: ref-filter.c:133
+#: ref-filter.c:149
 #, c-format
 msgid "Integer value expected refname:rstrip=%s"
 msgstr "Valor entero esperado refname:rstrip=%s"
 
-#: ref-filter.c:135
+#: ref-filter.c:151
 #, c-format
 msgid "unrecognized %%(%s) argument: %s"
 msgstr "argumento: %s no reconocido %%(%s)"
 
-#: ref-filter.c:184
+#: ref-filter.c:206
 #, c-format
 msgid "%%(body) does not take arguments"
 msgstr "%%(body) no toma ningún argumento"
 
-#: ref-filter.c:191
+#: ref-filter.c:215
 #, c-format
 msgid "%%(subject) does not take arguments"
 msgstr "%%(subject) no toma ningún argumento"
 
-#: ref-filter.c:209
+#: ref-filter.c:235
 #, c-format
 msgid "unknown %%(trailers) argument: %s"
 msgstr "%%(trailers) desconocidos, argumento: %s"
 
-#: ref-filter.c:232
+#: ref-filter.c:264
 #, c-format
 msgid "positive value expected contents:lines=%s"
 msgstr "valor positivo esperado contents:lines=%s"
 
-#: ref-filter.c:234
+#: ref-filter.c:266
 #, c-format
 msgid "unrecognized %%(contents) argument: %s"
 msgstr "argumento %s no reconocido %%(contents)"
 
-#: ref-filter.c:247
+#: ref-filter.c:281
 #, c-format
 msgid "positive value expected objectname:short=%s"
 msgstr "valor positivo esperado objectname:short=%s"
 
-#: ref-filter.c:251
+#: ref-filter.c:285
 #, c-format
 msgid "unrecognized %%(objectname) argument: %s"
 msgstr "argumento: %s no reconocido %%(objectname)"
 
-#: ref-filter.c:278
+#: ref-filter.c:315
 #, c-format
 msgid "expected format: %%(align:<width>,<position>)"
 msgstr "formato esperado: %%(align:<ancho>,<posición>)"
 
-#: ref-filter.c:290
+#: ref-filter.c:327
 #, c-format
 msgid "unrecognized position:%s"
 msgstr "posición desconocida: %s"
 
-#: ref-filter.c:294
+#: ref-filter.c:334
 #, c-format
 msgid "unrecognized width:%s"
 msgstr "ancho desconocido: %s"
 
-#: ref-filter.c:300
+#: ref-filter.c:343
 #, c-format
 msgid "unrecognized %%(align) argument: %s"
 msgstr "argumento no reconocido para %%(align): %s"
 
-#: ref-filter.c:304
+#: ref-filter.c:351
 #, c-format
 msgid "positive width expected with the %%(align) atom"
 msgstr "se esperaba un ancho positivo con el átomo %%(align)"
 
-#: ref-filter.c:319
+#: ref-filter.c:369
 #, c-format
 msgid "unrecognized %%(if) argument: %s"
 msgstr "argumento: %s no reconocido %%(if)"
 
-#: ref-filter.c:409
+#: ref-filter.c:464
 #, c-format
 msgid "malformed field name: %.*s"
 msgstr "nombre mal formado de campo: %.*s"
 
-#: ref-filter.c:435
+#: ref-filter.c:491
 #, c-format
 msgid "unknown field name: %.*s"
 msgstr "nombre de campo desconocido: %.*s"
 
-#: ref-filter.c:547
+#: ref-filter.c:608
 #, c-format
 msgid "format: %%(if) atom used without a %%(then) atom"
 msgstr "formato: átomo %%(if) usado sin un átomo %%(then)"
 
-#: ref-filter.c:607
+#: ref-filter.c:671
 #, c-format
 msgid "format: %%(then) atom used without an %%(if) atom"
 msgstr "formato: átomo %%(then) usado sin átomo %%(if)"
 
-#: ref-filter.c:609
+#: ref-filter.c:673
 #, c-format
 msgid "format: %%(then) atom used more than once"
 msgstr "formato: átomo %%(then) usado mas de una vez"
 
-#: ref-filter.c:611
+#: ref-filter.c:675
 #, c-format
 msgid "format: %%(then) atom used after %%(else)"
 msgstr "formato: átomo %%(then) usado después de %%(else)"
 
-#: ref-filter.c:637
+#: ref-filter.c:703
 #, c-format
 msgid "format: %%(else) atom used without an %%(if) atom"
 msgstr "formato: átomo %%(else) usado sin un átomo %%(if)"
 
-#: ref-filter.c:639
+#: ref-filter.c:705
 #, c-format
 msgid "format: %%(else) atom used without a %%(then) atom"
 msgstr "formato: átomo %%(else) usado sin un átomo %%(then)"
 
-#: ref-filter.c:641
+#: ref-filter.c:707
 #, c-format
 msgid "format: %%(else) atom used more than once"
 msgstr "formato: átomo %%(else) usado mas de una vez"
 
-#: ref-filter.c:654
+#: ref-filter.c:722
 #, c-format
 msgid "format: %%(end) atom used without corresponding atom"
 msgstr "formato: átomo %%(end) usado sin átomo correspondiente"
 
-#: ref-filter.c:709
+#: ref-filter.c:779
 #, c-format
 msgid "malformed format string %s"
 msgstr "formato de cadena mal formado %s"
 
-#: ref-filter.c:1313
+#: ref-filter.c:1387
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(no hay rama, rebasando %s)"
 
-#: ref-filter.c:1316
+#: ref-filter.c:1390
+#, c-format
+msgid "(no branch, rebasing detached HEAD %s)"
+msgstr "(no hay rama, rebasando con HEAD desacoplado %s)"
+
+#: ref-filter.c:1393
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(no hay rama, comenzando bisecado en %s)"
@@ -2797,7 +3091,7 @@ msgstr "(no hay rama, comenzando bisecado en %s)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached at " in wt-status.c
 #.
-#: ref-filter.c:1324
+#: ref-filter.c:1401
 #, c-format
 msgid "(HEAD detached at %s)"
 msgstr "(HEAD desacoplado en %s)"
@@ -2805,148 +3099,148 @@ msgstr "(HEAD desacoplado en %s)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached from " in wt-status.c
 #.
-#: ref-filter.c:1331
+#: ref-filter.c:1408
 #, c-format
 msgid "(HEAD detached from %s)"
 msgstr "(HEAD desacoplado de %s)"
 
-#: ref-filter.c:1335
+#: ref-filter.c:1412
 msgid "(no branch)"
 msgstr "(sin rama)"
 
-#: ref-filter.c:1364
+#: ref-filter.c:1442
 #, c-format
 msgid "missing object %s for %s"
 msgstr "falta objeto %s para %s"
 
-#: ref-filter.c:1367
+#: ref-filter.c:1445
 #, c-format
 msgid "parse_object_buffer failed on %s for %s"
 msgstr "parse_object_buffer falló en %s para %s"
 
-#: ref-filter.c:1819
+#: ref-filter.c:1902
 #, c-format
 msgid "malformed object at '%s'"
 msgstr "objeto mal formado en '%s'"
 
-#: ref-filter.c:1886
+#: ref-filter.c:1984
 #, c-format
 msgid "ignoring ref with broken name %s"
 msgstr "ignorando referencia con nombre roto %s"
 
-#: ref-filter.c:1891
+#: ref-filter.c:1989
 #, c-format
 msgid "ignoring broken ref %s"
 msgstr "ignorando referencia rota %s"
 
-#: ref-filter.c:2152
+#: ref-filter.c:2261
 #, c-format
 msgid "format: %%(end) atom missing"
 msgstr "formato: falta átomo %%(end)"
 
-#: ref-filter.c:2246
+#: ref-filter.c:2365
 #, c-format
 msgid "malformed object name %s"
 msgstr "nombre de objeto mal formado %s"
 
-#: remote.c:795
+#: remote.c:605
 #, c-format
 msgid "Cannot fetch both %s and %s to %s"
 msgstr "No se pueden traer ambos %s y %s a %s"
 
-#: remote.c:799
+#: remote.c:609
 #, c-format
 msgid "%s usually tracks %s, not %s"
 msgstr "%s por lo general hace seguimiento a %s, no a %s"
 
-#: remote.c:803
+#: remote.c:613
 #, c-format
 msgid "%s tracks both %s and %s"
 msgstr "%s hace seguimiento tanto a %s como a %s"
 
-#: remote.c:811
+#: remote.c:621
 msgid "Internal error"
 msgstr "Error interno"
 
-#: remote.c:1726 remote.c:1828
+#: remote.c:1534 remote.c:1635
 msgid "HEAD does not point to a branch"
 msgstr "HEAD no apunta a ninguna rama"
 
-#: remote.c:1735
+#: remote.c:1543
 #, c-format
 msgid "no such branch: '%s'"
 msgstr "no existe tal rama: '%s'"
 
-#: remote.c:1738
+#: remote.c:1546
 #, c-format
 msgid "no upstream configured for branch '%s'"
 msgstr "no se ha configurado upstream para la rama '%s'"
 
-#: remote.c:1744
+#: remote.c:1552
 #, c-format
 msgid "upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "la rama '%s' de upstream no es guardad como rama de rastreo remoto"
 
-#: remote.c:1759
+#: remote.c:1567
 #, c-format
 msgid "push destination '%s' on remote '%s' has no local tracking branch"
 msgstr ""
 "destino de push '%s' en el remoto '%s' no tiene una rama de rastreo local"
 
-#: remote.c:1771
+#: remote.c:1579
 #, c-format
 msgid "branch '%s' has no remote for pushing"
 msgstr "la rama '%s' no tiene remoto para enviar"
 
-#: remote.c:1782
+#: remote.c:1589
 #, c-format
 msgid "push refspecs for '%s' do not include '%s'"
 msgstr "refspecs del push para '%s' no incluyen '%s'"
 
-#: remote.c:1795
+#: remote.c:1602
 msgid "push has no destination (push.default is 'nothing')"
 msgstr "push no tiene destino (push.default es 'nada')"
 
-#: remote.c:1817
+#: remote.c:1624
 msgid "cannot resolve 'simple' push to a single destination"
 msgstr "no se puede resolver push 'simple' para un destino único"
 
-#: remote.c:2132
+#: remote.c:1939
 #, c-format
 msgid "Your branch is based on '%s', but the upstream is gone.\n"
 msgstr "Tu rama esta basada en '%s', pero upstream ha desaparecido.\n"
 
-#: remote.c:2136
+#: remote.c:1943
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
 msgstr "  (usa \"git branch --unset-upstream\" para arreglar)\n"
 
-#: remote.c:2139
+#: remote.c:1946
 #, c-format
 msgid "Your branch is up to date with '%s'.\n"
 msgstr "Tu rama está actualizada con '%s'.\n"
 
-#: remote.c:2143
+#: remote.c:1950
 #, c-format
 msgid "Your branch and '%s' refer to different commits.\n"
 msgstr "Tu rama y '%s' refieren a commits diferentes.\n"
 
-#: remote.c:2146
+#: remote.c:1953
 #, c-format
 msgid "  (use \"%s\" for details)\n"
 msgstr "  (usa \"%s\" para detalles)\n"
 
-#: remote.c:2150
+#: remote.c:1957
 #, 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] "Tu rama está adelantada a '%s' por %d commit.\n"
 msgstr[1] "Tu rama está adelantada a '%s' por %d commits.\n"
 
-#: remote.c:2156
+#: remote.c:1963
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (usa \"git push\" para publicar tus commits locales)\n"
 
-#: remote.c:2159
+#: remote.c:1966
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -2956,11 +3250,11 @@ msgstr[0] ""
 msgstr[1] ""
 "Tu rama está detrás de '%s' por %d commits, y puede ser avanzada rápido.\n"
 
-#: remote.c:2167
+#: remote.c:1974
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (usa \"git pull\" para actualizar tu rama local)\n"
 
-#: remote.c:2170
+#: remote.c:1977
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -2975,28 +3269,28 @@ msgstr[1] ""
 "Tu rama y '%s' han divergido,\n"
 "y tienen %d y %d commits diferentes cada una respectivamente.\n"
 
-#: remote.c:2180
+#: remote.c:1987
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr "  (usa \"git pull\" para fusionar la rama remota en la tuya)\n"
 
-#: revision.c:2277
+#: revision.c:2289
 msgid "your current branch appears to be broken"
 msgstr "tu rama actual parece estar rota"
 
-#: revision.c:2280
+#: revision.c:2292
 #, c-format
 msgid "your current branch '%s' does not have any commits yet"
 msgstr "tu rama actual '%s' no tiene ningún commit todavía"
 
-#: revision.c:2477
+#: revision.c:2489
 msgid "--first-parent is incompatible with --bisect"
 msgstr "--first-parent es incompatible con --bisect"
 
-#: run-command.c:731
+#: run-command.c:728
 msgid "open /dev/null failed"
 msgstr "falló al abrir /dev/null"
 
-#: run-command.c:1274
+#: run-command.c:1271
 #, c-format
 msgid ""
 "The '%s' hook was ignored because it's not set as executable.\n"
@@ -3045,29 +3339,34 @@ msgstr "el destino no soporta push atómicos (--atomic)"
 msgid "the receiving end does not support push options"
 msgstr "el destino no soporta opciones de push"
 
-#: sequencer.c:158
+#: sequencer.c:175
 #, c-format
 msgid "invalid commit message cleanup mode '%s'"
 msgstr "mensaje de commit inválido, modo cleanup '%s'"
 
-#: sequencer.c:267
+#: sequencer.c:275
+#, c-format
+msgid "could not delete '%s'"
+msgstr "no se pudo borrar '%s'"
+
+#: sequencer.c:301
 msgid "revert"
 msgstr "revertir"
 
-#: sequencer.c:269
+#: sequencer.c:303
 msgid "cherry-pick"
 msgstr "cherry-pick"
 
-#: sequencer.c:271
+#: sequencer.c:305
 msgid "rebase -i"
 msgstr "rebase -i"
 
-#: sequencer.c:273
+#: sequencer.c:307
 #, c-format
 msgid "Unknown action: %d"
 msgstr "Acción desconocida: %d"
 
-#: sequencer.c:330
+#: sequencer.c:364
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
@@ -3075,7 +3374,7 @@ msgstr ""
 "después de resolver los conflictos, marca las rutas corregidas\n"
 "con 'git add <rutas>' o 'git rm <rutas>'"
 
-#: sequencer.c:333
+#: sequencer.c:367
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'\n"
@@ -3085,43 +3384,45 @@ msgstr ""
 "con 'git add <rutas>' o 'git rm <rutas>'\n"
 "y haz un commit del resultado con 'git commit'"
 
-#: sequencer.c:346 sequencer.c:2245
+#: sequencer.c:380 sequencer.c:2468
 #, c-format
 msgid "could not lock '%s'"
 msgstr "no se pudo bloquear '%s'"
 
-#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264
-#: sequencer.c:3246 sequencer.c:3310 wrapper.c:656
+#: sequencer.c:382 sequencer.c:2346 sequencer.c:2472 sequencer.c:2486
+#: sequencer.c:2694 sequencer.c:4336 sequencer.c:4399 wrapper.c:656
 #, c-format
 msgid "could not write to '%s'"
 msgstr "no se pudo escribir en '%s'"
 
-#: sequencer.c:353
+#: sequencer.c:387
 #, c-format
 msgid "could not write eol to '%s'"
 msgstr "no se pudo escribir EOL en '%s'"
 
-#: sequencer.c:356 sequencer.c:2128 sequencer.c:2252
+#: sequencer.c:392 sequencer.c:2351 sequencer.c:2474 sequencer.c:2488
+#: sequencer.c:2702
 #, c-format
 msgid "failed to finalize '%s'"
 msgstr "falló al finalizar '%s'"
 
-#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259
-#: builtin/commit.c:722 builtin/merge.c:1047
+#: sequencer.c:415 sequencer.c:804 sequencer.c:1493 sequencer.c:2371
+#: sequencer.c:2684 sequencer.c:2788 builtin/am.c:259 builtin/commit.c:727
+#: builtin/merge.c:1046
 #, c-format
 msgid "could not read '%s'"
 msgstr "no se pudo leer '%s'"
 
-#: sequencer.c:405
+#: sequencer.c:441
 #, c-format
 msgid "your local changes would be overwritten by %s."
 msgstr "tus cambios locales serán sobreescritos por %s."
 
-#: sequencer.c:409
+#: sequencer.c:445
 msgid "commit your changes or stash them to proceed."
 msgstr "realiza un commit con tus cambios o aplica un stash para proceder."
 
-#: sequencer.c:438
+#: sequencer.c:474
 #, c-format
 msgid "%s: fast-forward"
 msgstr "%s: avance rápido"
@@ -3129,20 +3430,20 @@ msgstr "%s: avance rápido"
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase -i".
 #.
-#: sequencer.c:526
+#: sequencer.c:563
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: Incapaz de escribir el nuevo archivo índice"
 
-#: sequencer.c:542
-msgid "could not resolve HEAD commit"
-msgstr "no se pudo resolver el commit de HEAD"
-
-#: sequencer.c:562
+#: sequencer.c:579
 msgid "unable to update cache tree"
 msgstr "no es posible actualizar el árbol de la caché"
 
-#: sequencer.c:658
+#: sequencer.c:592
+msgid "could not resolve HEAD commit"
+msgstr "no se pudo resolver el commit de HEAD"
+
+#: sequencer.c:749
 #, c-format
 msgid ""
 "you have staged changes in your working tree\n"
@@ -3172,11 +3473,15 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: sequencer.c:915
+#: sequencer.c:818
+msgid "writing root commit"
+msgstr "escribiendo commit raíz"
+
+#: sequencer.c:1043
 msgid "'prepare-commit-msg' hook failed"
 msgstr "hook 'prepare-commit-msg' falló"
 
-#: sequencer.c:922
+#: sequencer.c:1050
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3203,7 +3508,7 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:935
+#: sequencer.c:1063
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3227,327 +3532,313 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:975
+#: sequencer.c:1103
 msgid "couldn't look up newly created commit"
 msgstr "no se pudo revisar el commit recién creado"
 
-#: sequencer.c:977
+#: sequencer.c:1105
 msgid "could not parse newly created commit"
 msgstr "no se pudo analizar el commit recién creado"
 
-#: sequencer.c:1023
+#: sequencer.c:1151
 msgid "unable to resolve HEAD after creating commit"
 msgstr "no se pudo resolver HEAD tras crear el commit"
 
-#: sequencer.c:1025
+#: sequencer.c:1153
 msgid "detached HEAD"
 msgstr "HEAD desacoplado"
 
-#: sequencer.c:1029
+#: sequencer.c:1157
 msgid " (root-commit)"
 msgstr " (commit-raíz)"
 
-#: sequencer.c:1050
+#: sequencer.c:1178
 msgid "could not parse HEAD"
 msgstr "no se pudo analizar HEAD"
 
-#: sequencer.c:1052
+#: sequencer.c:1180
 #, c-format
 msgid "HEAD %s is not a commit!"
 msgstr "HEAD %s no es un commit!"
 
-#: sequencer.c:1056 builtin/commit.c:1491
+#: sequencer.c:1184 builtin/commit.c:1528
 msgid "could not parse HEAD commit"
 msgstr "no se pudo analizar el commit de HEAD"
 
-#: sequencer.c:1107 sequencer.c:1673
+#: sequencer.c:1235 sequencer.c:1832
 msgid "unable to parse commit author"
 msgstr "no es posible analizar el autor del commit"
 
-#: sequencer.c:1117 builtin/am.c:1630 builtin/merge.c:643
+#: sequencer.c:1245 builtin/am.c:1630 builtin/merge.c:645
 msgid "git write-tree failed to write a tree"
 msgstr "git write-tree falló al escribir el árbol"
 
-#: sequencer.c:1134 sequencer.c:1186
+#: sequencer.c:1262 sequencer.c:1317
 #, c-format
 msgid "unable to read commit message from '%s'"
 msgstr "no se puede leer el mensaje del commit de '%s'"
 
-#: sequencer.c:1154 builtin/am.c:1650 builtin/commit.c:1594 builtin/merge.c:826
-#: builtin/merge.c:851
+#: sequencer.c:1284 builtin/am.c:1650 builtin/commit.c:1631 builtin/merge.c:825
+#: builtin/merge.c:850
 msgid "failed to write commit object"
-msgstr "fallo al escribir el objeto commit"
+msgstr "falló al escribir el objeto commit"
 
-#: sequencer.c:1213
+#: sequencer.c:1344
 #, c-format
 msgid "could not parse commit %s"
 msgstr "no se pudo analizar commit %s"
 
-#: sequencer.c:1218
+#: sequencer.c:1349
 #, c-format
 msgid "could not parse parent commit %s"
 msgstr "no se pudo analizar el commit padre %s"
 
-#: sequencer.c:1347
-#, c-format
-msgid ""
-"unexpected 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"1ra línea del mensaje squash no esperada:\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1353
-#, c-format
-msgid ""
-"invalid 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"1ra línea del mensaje squash inválida:\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1359 sequencer.c:1384
+#: sequencer.c:1500 sequencer.c:1525
 #, c-format
 msgid "This is a combination of %d commits."
 msgstr "Esta es una combinación de %d commits."
 
-#: sequencer.c:1368 sequencer.c:3265
+#: sequencer.c:1510 sequencer.c:4355
 msgid "need a HEAD to fixup"
 msgstr "se necesita un HEAD para arreglar"
 
-#: sequencer.c:1370
+#: sequencer.c:1512 sequencer.c:2729
 msgid "could not read HEAD"
 msgstr "no se pudo leer HEAD"
 
-#: sequencer.c:1372
+#: sequencer.c:1514
 msgid "could not read HEAD's commit message"
 msgstr "no se pudo leer el mensaje de commit de HEAD"
 
-#: sequencer.c:1378
+#: sequencer.c:1520
 #, c-format
 msgid "cannot write '%s'"
 msgstr "no se puede escribir '%s'"
 
-#: sequencer.c:1387 git-rebase--interactive.sh:452
+#: sequencer.c:1527 git-rebase--interactive.sh:457
 msgid "This is the 1st commit message:"
 msgstr "Este es el mensaje del 1er commit:"
 
-#: sequencer.c:1395
+#: sequencer.c:1535
 #, c-format
 msgid "could not read commit message of %s"
 msgstr "no se puede leer el mensaje del commit de %s"
 
-#: sequencer.c:1402
+#: sequencer.c:1542
 #, c-format
 msgid "This is the commit message #%d:"
 msgstr "Este es el mensaje del commit #%d:"
 
-#: sequencer.c:1407
+#: sequencer.c:1548
 #, c-format
 msgid "The commit message #%d will be skipped:"
 msgstr "El mensaje del commit #%d será saltado:"
 
-#: sequencer.c:1412
+#: sequencer.c:1553
 #, c-format
 msgid "unknown command: %d"
 msgstr "comando desconocido: %d"
 
-#: sequencer.c:1479
+#: sequencer.c:1631
 msgid "your index file is unmerged."
 msgstr "tu archivo índice no esta fusionado."
 
-#: sequencer.c:1498
+#: sequencer.c:1638
+msgid "cannot fixup root commit"
+msgstr "no se puede arreglar el commit raíz"
+
+#: sequencer.c:1657
 #, c-format
 msgid "commit %s is a merge but no -m option was given."
 msgstr "el commit %s es una fusión pero no se entrego la opción -m."
 
-#: sequencer.c:1506
+#: sequencer.c:1665
 #, c-format
 msgid "commit %s does not have parent %d"
 msgstr "el commit %s no tiene un padre %d"
 
-#: sequencer.c:1510
+#: sequencer.c:1669
 #, c-format
 msgid "mainline was specified but commit %s is not a merge."
 msgstr "línea principal especificada pero el commit %s no es una fusión."
 
-#: sequencer.c:1516
+#: sequencer.c:1675
 #, c-format
 msgid "cannot get commit message for %s"
 msgstr "no se puede obtener el mensaje de commit para %s"
 
 #. TRANSLATORS: The first %s will be a "todo" command like
 #. "revert" or "pick", the second %s a SHA1.
-#: sequencer.c:1535
+#: sequencer.c:1694
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s: no se puede analizar el commit padre %s"
 
-#: sequencer.c:1600 sequencer.c:2397
+#: sequencer.c:1759
 #, c-format
 msgid "could not rename '%s' to '%s'"
 msgstr "no se puede renombrar '%s' a '%s'"
 
-#: sequencer.c:1654
+#: sequencer.c:1813
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "no se pudo revertir %s... %s"
 
-#: sequencer.c:1655
+#: sequencer.c:1814
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "no se pudo aplicar %s... %s"
 
-#: sequencer.c:1702
+#: sequencer.c:1864
 msgid "empty commit set passed"
 msgstr "conjunto de commits vacío entregado"
 
-#: sequencer.c:1712
+#: sequencer.c:1874
 #, c-format
 msgid "git %s: failed to read the index"
-msgstr "git %s: fallo al leer el índice"
+msgstr "git %s: falló al leer el índice"
 
-#: sequencer.c:1718
+#: sequencer.c:1881
 #, c-format
 msgid "git %s: failed to refresh the index"
-msgstr "git %s: fallo al refrescar el índice"
+msgstr "git %s: falló al refrescar el índice"
 
-#: sequencer.c:1792
+#: sequencer.c:1961
 #, c-format
 msgid "%s does not accept arguments: '%s'"
 msgstr "%s no acepta los argumentos: '%s'"
 
-#: sequencer.c:1801
+#: sequencer.c:1970
 #, c-format
 msgid "missing arguments for %s"
 msgstr "faltan argumentos para para %s"
 
-#: sequencer.c:1844
+#: sequencer.c:2029
 #, c-format
 msgid "invalid line %d: %.*s"
 msgstr "línea inválida %d: %.*s"
 
-#: sequencer.c:1852
+#: sequencer.c:2037
 #, c-format
 msgid "cannot '%s' without a previous commit"
 msgstr "no se puede  '%s' sin un commit previo"
 
-#: sequencer.c:1883 sequencer.c:3056 sequencer.c:3091
+#: sequencer.c:2085 sequencer.c:4138 sequencer.c:4173
 #, c-format
 msgid "could not read '%s'."
 msgstr "no se puede leer '%s'."
 
-#: sequencer.c:1906
+#: sequencer.c:2108
 msgid "please fix this using 'git rebase --edit-todo'."
 msgstr "por favor arregle esto usando 'git rebase --edit-todo'."
 
-#: sequencer.c:1908
+#: sequencer.c:2110
 #, c-format
 msgid "unusable instruction sheet: '%s'"
 msgstr "hoja de instrucciones inutilizable: '%s'"
 
-#: sequencer.c:1913
+#: sequencer.c:2115
 msgid "no commits parsed."
 msgstr "ningún commit analizado."
 
-#: sequencer.c:1924
+#: sequencer.c:2126
 msgid "cannot cherry-pick during a revert."
 msgstr "no se puede realizar cherry-pick durante un revert."
 
-#: sequencer.c:1926
+#: sequencer.c:2128
 msgid "cannot revert during a cherry-pick."
 msgstr "no se puede realizar un revert durante un cherry-pick."
 
-#: sequencer.c:1993
+#: sequencer.c:2195
 #, c-format
 msgid "invalid key: %s"
 msgstr "llave invalida: %s"
 
-#: sequencer.c:1996
+#: sequencer.c:2198
 #, c-format
 msgid "invalid value for %s: %s"
 msgstr "valor invalido para %s: %s"
 
-#: sequencer.c:2062
+#: sequencer.c:2269
+msgid "unusable squash-onto"
+msgstr "squash-onto inservible"
+
+#: sequencer.c:2285
 #, c-format
 msgid "malformed options sheet: '%s'"
 msgstr "hoja de opciones mal formada: '%s'"
 
-#: sequencer.c:2100
+#: sequencer.c:2323
 msgid "a cherry-pick or revert is already in progress"
 msgstr "un cherry-pick o revert ya esta en progreso"
 
-#: sequencer.c:2101
+#: sequencer.c:2324
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "intenta \"git cherry-pick (--continue | --quit | --abort)\""
 
-#: sequencer.c:2104
+#: sequencer.c:2327
 #, c-format
 msgid "could not create sequencer directory '%s'"
 msgstr "no se pudo crear un directorio secuenciador '%s'"
 
-#: sequencer.c:2118
+#: sequencer.c:2341
 msgid "could not lock HEAD"
 msgstr "no se pudo bloquear HEAD"
 
-#: sequencer.c:2173 sequencer.c:2761
+#: sequencer.c:2396 sequencer.c:3403
 msgid "no cherry-pick or revert in progress"
 msgstr "ningún cherry-pick o revert en progreso"
 
-#: sequencer.c:2175
+#: sequencer.c:2398
 msgid "cannot resolve HEAD"
 msgstr "no se puede resolver HEAD"
 
-#: sequencer.c:2177 sequencer.c:2212
+#: sequencer.c:2400 sequencer.c:2435
 msgid "cannot abort from a branch yet to be born"
 msgstr "no se puede abortar de una rama por nacer"
 
-#: sequencer.c:2198 builtin/grep.c:720
+#: sequencer.c:2421 builtin/grep.c:720
 #, c-format
 msgid "cannot open '%s'"
 msgstr "no se puede abrir '%s'"
 
-#: sequencer.c:2200
+#: sequencer.c:2423
 #, c-format
 msgid "cannot read '%s': %s"
 msgstr "no se puede leer '%s': %s"
 
-#: sequencer.c:2201
+#: sequencer.c:2424
 msgid "unexpected end of file"
 msgstr "final de archivo inesperado"
 
-#: sequencer.c:2207
+#: sequencer.c:2430
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr "archivo HEAD de pre-cherry-pick guardado '%s' esta corrupto"
 
-#: sequencer.c:2218
+#: sequencer.c:2441
 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
 msgstr "Parece que se ha movido HEAD. No se hace rebobinado, revise su HEAD!"
 
-#: sequencer.c:2324 sequencer.c:2679
+#: sequencer.c:2545 sequencer.c:3321
 #, c-format
 msgid "could not update %s"
 msgstr "no se puede actualizar %s"
 
-#: sequencer.c:2362 sequencer.c:2659
+#: sequencer.c:2583 sequencer.c:3301
 msgid "cannot read HEAD"
 msgstr "no se puede leer HEAD"
 
-#: sequencer.c:2402 builtin/difftool.c:639
+#: sequencer.c:2618 sequencer.c:2622 builtin/difftool.c:639
 #, c-format
 msgid "could not copy '%s' to '%s'"
 msgstr "no se pudo copiar '%s' a '%s'"
 
-#: sequencer.c:2421
+#: sequencer.c:2641
 msgid "could not read index"
 msgstr "no se pudo leer índice"
 
-#: sequencer.c:2426
+#: sequencer.c:2646
 #, c-format
 msgid ""
 "execution failed: %s\n"
@@ -3562,11 +3853,11 @@ msgstr ""
 "  git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2432
+#: sequencer.c:2652
 msgid "and made changes to the index and/or the working tree\n"
 msgstr "y se hicieron cambios al índice y/o árbol de trabajo\n"
 
-#: sequencer.c:2438
+#: sequencer.c:2658
 #, c-format
 msgid ""
 "execution succeeded: %s\n"
@@ -3583,17 +3874,62 @@ msgstr ""
 "  git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2497
+#: sequencer.c:2771
+msgid "writing fake root commit"
+msgstr "escribiendo commit raíz falso"
+
+#: sequencer.c:2776
+msgid "writing squash-onto"
+msgstr "escribiendo squash-onto"
+
+#: sequencer.c:2811
+#, c-format
+msgid "failed to find tree of %s"
+msgstr "falló al encontrar árbol de %s"
+
+#: sequencer.c:2829
+msgid "could not write index"
+msgstr "no se pudo escribir índice"
+
+#: sequencer.c:2861
+msgid "cannot merge without a current revision"
+msgstr "no se puede fusionar sin una versión actual"
+
+#: sequencer.c:2884
+#, c-format
+msgid "could not resolve '%s'"
+msgstr "no se pudo resolver '%s'"
+
+#: sequencer.c:2906
+#, c-format
+msgid "could not get commit message of '%s'"
+msgstr "no se puede leer el mensaje del commit '%s'"
+
+#: sequencer.c:2916 sequencer.c:2941
+#, c-format
+msgid "could not write '%s'"
+msgstr "no se pudo escribir '%s'"
+
+#: sequencer.c:3005
+#, c-format
+msgid "could not even attempt to merge '%.*s'"
+msgstr "no se pudo intentar fusionar '%.*s'"
+
+#: sequencer.c:3021
+msgid "merge: Unable to write new index file"
+msgstr "fusión: No se puede escribir el nuevo archivo índice"
+
+#: sequencer.c:3088
 #, c-format
 msgid "Applied autostash.\n"
 msgstr "Autostash aplicado.\n"
 
-#: sequencer.c:2509
+#: sequencer.c:3100
 #, c-format
 msgid "cannot store %s"
 msgstr "no se puede guardar %s"
 
-#: sequencer.c:2512 git-rebase.sh:178
+#: sequencer.c:3103 git-rebase.sh:188
 #, c-format
 msgid ""
 "Applying autostash resulted in conflicts.\n"
@@ -3605,52 +3941,69 @@ msgstr ""
 "Puedes ejecutar \"git stash pop\" o \"git stash drop\" en cualquier "
 "momento.\n"
 
-#: sequencer.c:2595
+#: sequencer.c:3134
+#, c-format
+msgid ""
+"Could not execute the todo command\n"
+"\n"
+"    %.*s\n"
+"It has been rescheduled; To edit the command before continuing, please\n"
+"edit the todo list first:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+msgstr ""
+"No se pudo ejecutar el comando \"todo\"\n"
+"\n"
+"    %.*s\n"
+"Ha sido reprogramado; Para editar el comando antes de continuar, por favor\n"
+"edite la lista de \"todo\" primero:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+
+#: sequencer.c:3202
 #, c-format
 msgid "Stopped at %s...  %.*s\n"
 msgstr "Detenido en %s...  %.*s\n"
 
-#: sequencer.c:2637
+#: sequencer.c:3264
 #, c-format
 msgid "unknown command %d"
 msgstr "comando desconocido %d"
 
-#: sequencer.c:2667
+#: sequencer.c:3309
 msgid "could not read orig-head"
 msgstr "no se puede leer orig-head"
 
-#: sequencer.c:2672 sequencer.c:3262
+#: sequencer.c:3314 sequencer.c:4352
 msgid "could not read 'onto'"
 msgstr "no se puede leer 'onto'"
 
-#: sequencer.c:2686
+#: sequencer.c:3328
 #, c-format
 msgid "could not update HEAD to %s"
 msgstr "no se puede actualizar HEAD a %s"
 
-#: sequencer.c:2770
+#: sequencer.c:3414
 msgid "cannot rebase: You have unstaged changes."
 msgstr "no se puede realizar rebase: Tienes cambios fuera del área de stage."
 
-#: sequencer.c:2775
-msgid "could not remove CHERRY_PICK_HEAD"
-msgstr "no se puede remover CHERRY_PICK_HEAD"
-
-#: sequencer.c:2784
+#: sequencer.c:3423
 msgid "cannot amend non-existing commit"
 msgstr "no se puede arreglar un commit no existente"
 
-#: sequencer.c:2786
+#: sequencer.c:3425
 #, c-format
 msgid "invalid file: '%s'"
 msgstr "archivo invalido: '%s'"
 
-#: sequencer.c:2788
+#: sequencer.c:3427
 #, c-format
 msgid "invalid contents: '%s'"
 msgstr "contenido inválido: '%s'"
 
-#: sequencer.c:2791
+#: sequencer.c:3430
 msgid ""
 "\n"
 "You have uncommitted changes in your working tree. Please, commit them\n"
@@ -3661,45 +4014,54 @@ msgstr ""
 "un commit con estos\n"
 "primero y luego ejecuta 'git rebase --continue' de nuevo."
 
-#: sequencer.c:2801
+#: sequencer.c:3455 sequencer.c:3493
+#, c-format
+msgid "could not write file: '%s'"
+msgstr "no se pudo escribir el archivo: '%s'"
+
+#: sequencer.c:3508
+msgid "could not remove CHERRY_PICK_HEAD"
+msgstr "no se puede remover CHERRY_PICK_HEAD"
+
+#: sequencer.c:3515
 msgid "could not commit staged changes."
 msgstr "no se pudo realizar el commit con los cambios en el área de stage."
 
-#: sequencer.c:2881
+#: sequencer.c:3612
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s: no se puede aplicar cherry-pick a un %s"
 
-#: sequencer.c:2885
+#: sequencer.c:3616
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s: mala revision"
 
-#: sequencer.c:2918
+#: sequencer.c:3649
 msgid "can't revert as initial commit"
 msgstr "no se puede revertir como commit inicial"
 
-#: sequencer.c:3023
+#: sequencer.c:4098
 msgid "make_script: unhandled options"
 msgstr "make_script: opciones desconocidas"
 
-#: sequencer.c:3026
+#: sequencer.c:4101
 msgid "make_script: error preparing revisions"
 msgstr "make_script: error preparando revisiones"
 
-#: sequencer.c:3060 sequencer.c:3095
+#: sequencer.c:4142 sequencer.c:4177
 #, c-format
 msgid "unusable todo list: '%s'"
 msgstr "lista de pendientes inutilizable: '%s'"
 
-#: sequencer.c:3146
+#: sequencer.c:4236
 #, c-format
 msgid ""
 "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
 msgstr ""
 "opción %s no reconocida para la opción rebase.missingCommitsCheck. Ignorando."
 
-#: sequencer.c:3212
+#: sequencer.c:4302
 #, c-format
 msgid ""
 "Warning: some commits may have been dropped accidentally.\n"
@@ -3708,7 +4070,7 @@ msgstr ""
 "Peligro: algunos commits pueden haber sido botados de forma accidental.\n"
 "Commits botados (empezando con el mas nuevo):\n"
 
-#: sequencer.c:3219
+#: sequencer.c:4309
 #, c-format
 msgid ""
 "To avoid this message, use \"drop\" to explicitly remove a commit.\n"
@@ -3726,7 +4088,7 @@ msgstr ""
 "Los posibles comportamientos son: ignore,warn,error.\n"
 "\n"
 
-#: sequencer.c:3231
+#: sequencer.c:4321
 #, c-format
 msgid ""
 "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
@@ -3737,27 +4099,21 @@ msgstr ""
 "rebase --continue'.\n"
 "O se puede abortar el rebase con 'git rebase --abort'.\n"
 
-#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395
-#: builtin/am.c:779
-#, c-format
-msgid "could not open '%s' for writing"
-msgstr "no se pudo abrir '%s' para escritura"
-
-#: sequencer.c:3285
+#: sequencer.c:4375
 #, c-format
 msgid "could not parse commit '%s'"
 msgstr "no se pudo analizar commit '%s'"
 
-#: sequencer.c:3401
+#: sequencer.c:4490
 msgid "the script was already rearranged."
 msgstr "este script ya fue reorganizado."
 
-#: setup.c:122
+#: setup.c:123
 #, c-format
 msgid "'%s' is outside repository"
 msgstr "'%s' está fuera del repositorio"
 
-#: setup.c:171
+#: setup.c:172
 #, c-format
 msgid ""
 "%s: no such path in the working tree.\n"
@@ -3767,7 +4123,7 @@ msgstr ""
 "Use 'git <comando> -- <ruta>...' para especificar rutas que no existen "
 "localmente."
 
-#: setup.c:184
+#: setup.c:185
 #, c-format
 msgid ""
 "ambiguous argument '%s': unknown revision or path not in the working tree.\n"
@@ -3779,12 +4135,12 @@ msgstr ""
 "Use '--' para separar las rutas de las revisiones, de esta manera:\n"
 "'git <comando> [<revisión>...] -- [<archivo>...]'"
 
-#: setup.c:233
+#: setup.c:234
 #, c-format
 msgid "option '%s' must come before non-option arguments"
 msgstr "opción '%s' debe venir antes de argumentos no opcionales"
 
-#: setup.c:252
+#: setup.c:253
 #, c-format
 msgid ""
 "ambiguous argument '%s': both revision and filename\n"
@@ -3795,95 +4151,95 @@ msgstr ""
 "Use '--' para separar rutas de revisiones, de esta manera:\n"
 "'git <comando> [<revisión>...] -- [<archivo>...]'"
 
-#: setup.c:388
+#: setup.c:389
 msgid "unable to set up work tree using invalid config"
 msgstr ""
 "no es posible configurar el directorio de trabajo usando una configuración "
 "inválida"
 
-#: setup.c:395
+#: setup.c:393
 msgid "this operation must be run in a work tree"
 msgstr "esta operación debe ser realizada en un árbol de trabajo"
 
-#: setup.c:506
+#: setup.c:503
 #, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Se esperaba versión de git repo  <= %d, encontrada %d"
 
-#: setup.c:514
+#: setup.c:511
 msgid "unknown repository extensions found:"
 msgstr "se encontró extensión de repositorio desconocida:"
 
-#: setup.c:533
+#: setup.c:530
 #, c-format
 msgid "error opening '%s'"
 msgstr "error abriendo '%s'"
 
-#: setup.c:535
+#: setup.c:532
 #, c-format
 msgid "too large to be a .git file: '%s'"
 msgstr "muy grande para ser un archivo .git: '%s'"
 
-#: setup.c:537
+#: setup.c:534
 #, c-format
 msgid "error reading %s"
 msgstr "error leyendo %s"
 
-#: setup.c:539
+#: setup.c:536
 #, c-format
 msgid "invalid gitfile format: %s"
 msgstr "formato gitfile inválido: %s"
 
-#: setup.c:541
+#: setup.c:538
 #, c-format
 msgid "no path in gitfile: %s"
 msgstr "no hay ruta en gitfile: %s"
 
-#: setup.c:543
+#: setup.c:540
 #, c-format
 msgid "not a git repository: %s"
 msgstr "no es un repositorio git: %s"
 
-#: setup.c:642
+#: setup.c:639
 #, c-format
 msgid "'$%s' too big"
 msgstr "'$%s' muy grande"
 
-#: setup.c:656
+#: setup.c:653
 #, c-format
 msgid "not a git repository: '%s'"
 msgstr "no es un repositorio git: '%s'"
 
-#: setup.c:685 setup.c:687 setup.c:718
+#: setup.c:682 setup.c:684 setup.c:715
 #, c-format
 msgid "cannot chdir to '%s'"
 msgstr "no se puede aplicar chdir a '%s'"
 
-#: setup.c:690 setup.c:746 setup.c:756 setup.c:795 setup.c:803 setup.c:818
+#: setup.c:687 setup.c:743 setup.c:753 setup.c:792 setup.c:800 setup.c:815
 msgid "cannot come back to cwd"
 msgstr "no se puede volver a cwd"
 
-#: setup.c:816
+#: setup.c:813
 #, c-format
 msgid "not a git repository (or any of the parent directories): %s"
 msgstr ""
 "no es un repositorio git (ni ninguno de los directorios superiores): %s"
 
-#: setup.c:827
+#: setup.c:824
 #, c-format
 msgid "failed to stat '%*s%s%s'"
-msgstr "fallo al determinar '%*s%s%s'"
+msgstr "falló al determinar '%*s%s%s'"
 
-#: setup.c:1057
+#: setup.c:1054
 msgid "Unable to read current working directory"
 msgstr "Incapaz de leer el directorio de trabajo actual"
 
-#: setup.c:1069 setup.c:1075
+#: setup.c:1066 setup.c:1072
 #, c-format
 msgid "cannot change to '%s'"
 msgstr "no se puede cambiar a '%s'"
 
-#: setup.c:1088
+#: setup.c:1085
 #, c-format
 msgid ""
 "not a git repository (or any parent up to mount point %s)\n"
@@ -3893,7 +4249,7 @@ msgstr ""
 "Parando en el límite del sistema de archivos "
 "(GIT_DISCOVERY_ACROSS_FILESYSTEM no establecido)."
 
-#: setup.c:1172
+#: setup.c:1168
 #, c-format
 msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
@@ -3902,55 +4258,55 @@ msgstr ""
 "problema con el valor del modo de archivo core.sharedRepository (0%.3o).\n"
 "El dueño de los archivos tiene que tener permisos de lectura y escritura."
 
-#: setup.c:1215
+#: setup.c:1211
 msgid "open /dev/null or dup failed"
 msgstr "falló al abrir /dev/null o dup"
 
-#: setup.c:1230
+#: setup.c:1226
 msgid "fork failed"
 msgstr "falló fork"
 
-#: setup.c:1235
+#: setup.c:1231
 msgid "setsid failed"
 msgstr "falló setsid"
 
-#: sha1_file.c:592
+#: sha1-file.c:625
 #, c-format
 msgid "path '%s' does not exist"
 msgstr "ruta '%s' no existe"
 
-#: sha1_file.c:618
+#: sha1-file.c:651
 #, c-format
 msgid "reference repository '%s' as a linked checkout is not supported yet."
 msgstr ""
 "repositorio de referencia '%s' como un checkout vinculado no es soportado "
 "todavía."
 
-#: sha1_file.c:624
+#: sha1-file.c:657
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "repositorio de referencia '%s' no es un repositorio local."
 
-#: sha1_file.c:630
+#: sha1-file.c:663
 #, c-format
 msgid "reference repository '%s' is shallow"
 msgstr "repositorio de referencia '%s' es superficial (shallow)"
 
-#: sha1_file.c:638
+#: sha1-file.c:671
 #, c-format
 msgid "reference repository '%s' is grafted"
 msgstr "repositorio de referencia '% s' está injertado"
 
-#: sha1_name.c:422
+#: sha1-name.c:442
 #, c-format
 msgid "short SHA1 %s is ambiguous"
 msgstr "SHA1 %s corto es ambiguao"
 
-#: sha1_name.c:433
+#: sha1-name.c:453
 msgid "The candidates are:"
 msgstr "Los candidatos son:"
 
-#: sha1_name.c:693
+#: sha1-name.c:695
 msgid ""
 "Git normally never creates a ref that ends with 40 hex characters\n"
 "because it will be ignored when you just specify 40-hex. These refs\n"
@@ -3973,70 +4329,70 @@ msgstr ""
 "examine estas refs y tal vez bórrelas. Silencie este mensaje \n"
 "ejecutando \"git config advice.objectNameWarning false\""
 
-#: submodule.c:96 submodule.c:130
+#: submodule.c:97 submodule.c:131
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr ""
 "No se puede cambiar .gitmodules no fusionados, resuelva este problema primero"
 
-#: submodule.c:100 submodule.c:134
+#: submodule.c:101 submodule.c:135
 #, c-format
 msgid "Could not find section in .gitmodules where path=%s"
 msgstr "No se pudo encontrar la sección en .gitmodules donde path=%s"
 
-#: submodule.c:108
+#: submodule.c:109
 #, c-format
 msgid "Could not update .gitmodules entry %s"
 msgstr "No se pudo actualizar la entrada %s de .gitmodules"
 
-#: submodule.c:141
+#: submodule.c:142
 #, c-format
 msgid "Could not remove .gitmodules entry for %s"
 msgstr "No se pudo remover la entrada %s de .gitmodules"
 
-#: submodule.c:152
+#: submodule.c:153
 msgid "staging updated .gitmodules failed"
 msgstr "falló realizar stage a los .gitmodules actualizados"
 
-#: submodule.c:312
+#: submodule.c:315
 #, c-format
 msgid "in unpopulated submodule '%s'"
 msgstr "en el submódulo no poblado '%s'"
 
-#: submodule.c:343
+#: submodule.c:346
 #, c-format
 msgid "Pathspec '%s' is in submodule '%.*s'"
 msgstr "El patrón de ruta '%s' está en el submódulo '%.*s'"
 
-#: submodule.c:833
+#: submodule.c:837
 #, c-format
 msgid "submodule entry '%s' (%s) is a %s, not a commit"
 msgstr "entrada de submódulo '%s' (%s) es un %s, no un commit"
 
-#: submodule.c:1065 builtin/branch.c:648 builtin/submodule--helper.c:1724
+#: submodule.c:1069 builtin/branch.c:651 builtin/submodule--helper.c:1743
 msgid "Failed to resolve HEAD as a valid ref."
-msgstr "Fallo al resolver HEAD como un ref valido."
+msgstr "Falló al resolver HEAD como un ref valido."
 
-#: submodule.c:1370
+#: submodule.c:1375
 #, c-format
 msgid "'%s' not recognized as a git repository"
 msgstr "'%s' no reconocido como un repositorio git"
 
-#: submodule.c:1508
+#: submodule.c:1513
 #, c-format
 msgid "could not start 'git status' in submodule '%s'"
 msgstr "no se pudo comenzar 'git status' en el submódulo '%s'"
 
-#: submodule.c:1521
+#: submodule.c:1526
 #, c-format
 msgid "could not run 'git status' in submodule '%s'"
 msgstr "no se pudo ejecutar 'git status' en el submódulo '%s'"
 
-#: submodule.c:1614
+#: submodule.c:1619
 #, c-format
 msgid "submodule '%s' has dirty index"
 msgstr "submódulo '%s' tiene un índice corrupto"
 
-#: submodule.c:1878
+#: submodule.c:1718
 #, c-format
 msgid ""
 "relocate_gitdir for submodule '%s' with more than one worktree not supported"
@@ -4044,18 +4400,18 @@ msgstr ""
 "relocate_gitdir para el submódulo '%s' con más de un árbol de trabajo no "
 "soportado"
 
-#: submodule.c:1890 submodule.c:1946
+#: submodule.c:1730 submodule.c:1786
 #, c-format
 msgid "could not lookup name for submodule '%s'"
 msgstr "no se pudo resolver el nombre para el submódulo '%s'"
 
-#: submodule.c:1894 builtin/submodule--helper.c:1246
-#: builtin/submodule--helper.c:1256
+#: submodule.c:1734 builtin/submodule--helper.c:1261
+#: builtin/submodule--helper.c:1271
 #, c-format
 msgid "could not create directory '%s'"
 msgstr "no se pudo crear el directorio '%s'"
 
-#: submodule.c:1897
+#: submodule.c:1737
 #, c-format
 msgid ""
 "Migrating git directory of '%s%s' from\n"
@@ -4066,29 +4422,30 @@ msgstr ""
 "'%s' hacia\n"
 "'%s'\n"
 
-#: submodule.c:1981
+#: submodule.c:1821
 #, c-format
 msgid "could not recurse into submodule '%s'"
 msgstr "no pudo recursar en el submódulo '%s'"
 
-#: submodule.c:2025
+#: submodule.c:1865
 msgid "could not start ls-files in .."
 msgstr "no se pudo comenzar ls-files en .."
 
-#: submodule.c:2045
-msgid "BUG: returned path string doesn't match cwd?"
-msgstr "BUG: string de ruta recibido no concuerda con cwd?"
-
-#: submodule.c:2064
+#: submodule.c:1904
 #, c-format
 msgid "ls-tree returned unexpected return code %d"
 msgstr "ls-tree retornó un código %d inesperado"
 
-#: submodule-config.c:263
+#: submodule-config.c:230
+#, c-format
+msgid "ignoring suspicious submodule name: %s"
+msgstr "ignorando submódulo sospechoso: %s"
+
+#: submodule-config.c:294
 msgid "negative values not allowed for submodule.fetchjobs"
 msgstr "no se permiten valores negativos para submodule.fetchjobs"
 
-#: submodule-config.c:436
+#: submodule-config.c:467
 #, c-format
 msgid "invalid value for %s"
 msgstr "valor inválido para %s"
@@ -4104,7 +4461,7 @@ msgstr "ejecución del comando de remolque '%s' falló"
 msgid "unknown value '%s' for key '%s'"
 msgstr "valor '%s' desconocido para la clave '%s'"
 
-#: trailer.c:539 trailer.c:544 builtin/remote.c:290
+#: trailer.c:539 trailer.c:544 builtin/remote.c:293
 #, c-format
 msgid "more than one %s"
 msgstr "más de un %s"
@@ -4147,17 +4504,21 @@ msgstr "no se pudo abrir el archivo temporal"
 msgid "could not rename temporary file to %s"
 msgstr "no se pudo renombrar el archivo temporal a %s"
 
-#: transport.c:63
+#: transport.c:116
 #, c-format
 msgid "Would set upstream of '%s' to '%s' of '%s'\n"
 msgstr "Configurará upstream de '%s' a '%s' de '%s'\n"
 
-#: transport.c:152
+#: transport.c:208
 #, c-format
 msgid "transport: invalid depth option '%s'"
 msgstr "transport: opción inválida '%s'"
 
-#: transport.c:916
+#: transport.c:584
+msgid "could not parse transport.color.* config"
+msgstr "no se pudo analizar valor de configuración transport.color.*"
+
+#: transport.c:996
 #, c-format
 msgid ""
 "The following submodule paths contain changes that can\n"
@@ -4166,7 +4527,7 @@ msgstr ""
 "La siguiente ruta de submódulo contiene cambios que no\n"
 "pueden ser encontrados en ningún remoto:\n"
 
-#: transport.c:920
+#: transport.c:1000
 #, c-format
 msgid ""
 "\n"
@@ -4193,11 +4554,11 @@ msgstr ""
 "para hacer un push al remoto.\n"
 "\n"
 
-#: transport.c:928
+#: transport.c:1008
 msgid "Aborting."
 msgstr "Abortando."
 
-#: transport-helper.c:1079
+#: transport-helper.c:1087
 #, c-format
 msgid "Could not read ref %s"
 msgstr "No se pudo leer la referencia %s"
@@ -4214,22 +4575,22 @@ msgstr "modo mal formado en la entrada de árbol"
 msgid "empty filename in tree entry"
 msgstr "nombre de archivo vacío en la entrada de árbol"
 
-#: tree-walk.c:114
+#: tree-walk.c:113
 msgid "too-short tree file"
 msgstr "archivo de árbol muy corto"
 
-#: unpack-trees.c:108
+#: unpack-trees.c:111
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
 "%%sPlease commit your changes or stash them before you switch branches."
 msgstr ""
 "Los cambios locales de los siguientes archivos serán sobrescritos por "
-"checkuot:\n"
+"checkout:\n"
 "%%sPor favor realiza un commit con los cambios o un stash antes de cambiar "
 "ramas."
 
-#: unpack-trees.c:110
+#: unpack-trees.c:113
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4239,7 +4600,7 @@ msgstr ""
 "checkout:\n"
 "%%s"
 
-#: unpack-trees.c:113
+#: unpack-trees.c:116
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4249,7 +4610,7 @@ msgstr ""
 "fusionar:\n"
 "%%sPor favor, confirma tus cambios o aguárdalos antes de fusionar."
 
-#: unpack-trees.c:115
+#: unpack-trees.c:118
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4259,7 +4620,7 @@ msgstr ""
 "merge:\n"
 "%%s"
 
-#: unpack-trees.c:118
+#: unpack-trees.c:121
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4268,7 +4629,7 @@ msgstr ""
 "Los cambios locales de los siguientes archivos serán sobrescritos al %s:\n"
 "%%sPor favor, confirma tus cambios o guárdalos antes de %s."
 
-#: unpack-trees.c:120
+#: unpack-trees.c:123
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4277,7 +4638,7 @@ msgstr ""
 "Los cambios locales de los siguientes archivos serán sobreescritos por %s:\n"
 "%%s"
 
-#: unpack-trees.c:125
+#: unpack-trees.c:128
 #, c-format
 msgid ""
 "Updating the following directories would lose untracked files in them:\n"
@@ -4287,7 +4648,7 @@ msgstr ""
 "seguimiento en ellos:\n"
 "%s"
 
-#: unpack-trees.c:129
+#: unpack-trees.c:132
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4297,7 +4658,7 @@ msgstr ""
 "removidos al actualizar el árbol de trabajo:\n"
 "%%sPor favor, muévelos o elimínalos antes de intercambiar ramas."
 
-#: unpack-trees.c:131
+#: unpack-trees.c:134
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4307,7 +4668,7 @@ msgstr ""
 "al actualizar el árbol de trabajo:\n"
 "%%s"
 
-#: unpack-trees.c:134
+#: unpack-trees.c:137
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4317,7 +4678,7 @@ msgstr ""
 "removidos al fusionar:\n"
 "%%sPor favor, muévelos o elimínalos antes de fusionar."
 
-#: unpack-trees.c:136
+#: unpack-trees.c:139
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4327,7 +4688,7 @@ msgstr ""
 "al fusionar:\n"
 "%%s"
 
-#: unpack-trees.c:139
+#: unpack-trees.c:142
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4337,7 +4698,7 @@ msgstr ""
 "removidos al %s:\n"
 "%%sPor favor, muévelos o elimínalos antes de %s."
 
-#: unpack-trees.c:141
+#: unpack-trees.c:144
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4347,7 +4708,7 @@ msgstr ""
 "removidos al ejecutar %s:\n"
 "%%s"
 
-#: unpack-trees.c:146
+#: unpack-trees.c:150
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4358,7 +4719,7 @@ msgstr ""
 "sobrescritos al actualizar el árbol de trabajo:\n"
 "%%sPor favor, muévelos o elimínalos antes de intercambiar ramas."
 
-#: unpack-trees.c:148
+#: unpack-trees.c:152
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4369,7 +4730,7 @@ msgstr ""
 "sobrescritos al actualizar el árbol de trabajo:\n"
 "%%s"
 
-#: unpack-trees.c:151
+#: unpack-trees.c:155
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4379,7 +4740,7 @@ msgstr ""
 "sobrescritos al fusionar:\n"
 "%%sPor favor, muévelos o elimínalos antes de fusionar."
 
-#: unpack-trees.c:153
+#: unpack-trees.c:157
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4389,7 +4750,7 @@ msgstr ""
 "sobrescritos al fusionar:\n"
 "%%s"
 
-#: unpack-trees.c:156
+#: unpack-trees.c:160
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4399,7 +4760,7 @@ msgstr ""
 "sobrescritos al %s:\n"
 "%%sPor favor, muévelos o elimínalos antes de %s."
 
-#: unpack-trees.c:158
+#: unpack-trees.c:162
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4409,12 +4770,12 @@ msgstr ""
 "por %s:\n"
 "%%s"
 
-#: unpack-trees.c:165
+#: unpack-trees.c:170
 #, c-format
 msgid "Entry '%s' overlaps with '%s'.  Cannot bind."
 msgstr "Entrada '%s' se superpone con '%s'.  No se pueden unir."
 
-#: unpack-trees.c:168
+#: unpack-trees.c:173
 #, c-format
 msgid ""
 "Cannot update sparse checkout: the following entries are not up to date:\n"
@@ -4424,7 +4785,7 @@ msgstr ""
 "actualizadas:\n"
 "%s"
 
-#: unpack-trees.c:170
+#: unpack-trees.c:175
 #, c-format
 msgid ""
 "The following working tree files would be overwritten by sparse checkout "
@@ -4435,7 +4796,7 @@ msgstr ""
 "actualización sparse checkout:\n"
 "%s"
 
-#: unpack-trees.c:172
+#: unpack-trees.c:177
 #, c-format
 msgid ""
 "The following working tree files would be removed by sparse checkout "
@@ -4446,7 +4807,7 @@ msgstr ""
 "actualización sparse checkout:\n"
 "%s"
 
-#: unpack-trees.c:174
+#: unpack-trees.c:179
 #, c-format
 msgid ""
 "Cannot update submodule:\n"
@@ -4455,12 +4816,12 @@ msgstr ""
 "No se puede actualizar le submódulo:\n"
 "%s"
 
-#: unpack-trees.c:251
+#: unpack-trees.c:262
 #, c-format
 msgid "Aborting\n"
 msgstr "Abortando\n"
 
-#: unpack-trees.c:333
+#: unpack-trees.c:344
 msgid "Checking out files"
 msgstr "Revisando archivos"
 
@@ -4496,7 +4857,7 @@ msgstr "segmento de ruta '..' invalido"
 #: worktree.c:245 builtin/am.c:2147
 #, c-format
 msgid "failed to read '%s'"
-msgstr "fallo al leer '%s'"
+msgstr "falló al leer '%s'"
 
 #: worktree.c:291
 #, c-format
@@ -4532,7 +4893,7 @@ msgid "could not open '%s' for reading and writing"
 msgstr "no se pudo abrir '%s' para lectura y escritura"
 
 #: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770
-#: builtin/am.c:862 builtin/merge.c:1044
+#: builtin/am.c:862 builtin/merge.c:1043
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "no se pudo abrir '%s' para lectura"
@@ -4546,159 +4907,159 @@ msgstr "no es posible acceder '%s'"
 msgid "unable to get current working directory"
 msgstr "no es posible obtener el directorio de trabajo actual"
 
-#: wt-status.c:151
+#: wt-status.c:154
 msgid "Unmerged paths:"
 msgstr "Rutas no fusionadas:"
 
-#: wt-status.c:178 wt-status.c:205
+#: wt-status.c:181 wt-status.c:208
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (usa \"git reset %s <archivo>...\" para sacar del área de stage)"
 
-#: wt-status.c:180 wt-status.c:207
+#: wt-status.c:183 wt-status.c:210
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (usa \"git rm --cached <archivo>...\" para sacar del área de stage)"
 
-#: wt-status.c:184
+#: wt-status.c:187
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (usa \"git add <archivo>...\" para marcar una resolución)"
 
-#: wt-status.c:186 wt-status.c:190
+#: wt-status.c:189 wt-status.c:193
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
 "  (usa \"git add/rm <archivo>...\" como una forma apropiada de marcar la "
 "resolución)"
 
-#: wt-status.c:188
+#: wt-status.c:191
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (usa \"git rm <file>...\" para marcar la resolución)"
 
-#: wt-status.c:199 wt-status.c:1007
+#: wt-status.c:202 wt-status.c:1015
 msgid "Changes to be committed:"
 msgstr "Cambios a ser confirmados:"
 
-#: wt-status.c:217 wt-status.c:1016
+#: wt-status.c:220 wt-status.c:1024
 msgid "Changes not staged for commit:"
 msgstr "Cambios no rastreados para el commit:"
 
-#: wt-status.c:221
+#: wt-status.c:224
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
 "  (usa \"git add <archivo>...\" para actualizar lo que será confirmado)"
 
-#: wt-status.c:223
+#: wt-status.c:226
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
 "  (usa \"git add/rm <archivo>...\" para actualizar a lo que se le va a hacer "
 "commit)"
 
-#: wt-status.c:224
+#: wt-status.c:227
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 "  (usa \"git checkout -- <archivo>...\" para descartar los cambios en el "
 "directorio de trabajo)"
 
-#: wt-status.c:226
+#: wt-status.c:229
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 "  (confirmar o descartar el contenido sin seguimiento o modificado en los "
 "sub-módulos)"
 
-#: wt-status.c:238
+#: wt-status.c:241
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
 "  (usa \"git %s <archivo>...\" para incluirlo a lo que se será confirmado)"
 
-#: wt-status.c:253
+#: wt-status.c:256
 msgid "both deleted:"
 msgstr "ambos borrados:"
 
-#: wt-status.c:255
+#: wt-status.c:258
 msgid "added by us:"
 msgstr "agregado por nosotros:"
 
-#: wt-status.c:257
+#: wt-status.c:260
 msgid "deleted by them:"
 msgstr "borrados por ellos:"
 
-#: wt-status.c:259
+#: wt-status.c:262
 msgid "added by them:"
 msgstr "agregado por ellos:"
 
-#: wt-status.c:261
+#: wt-status.c:264
 msgid "deleted by us:"
 msgstr "borrado por nosotros:"
 
-#: wt-status.c:263
+#: wt-status.c:266
 msgid "both added:"
 msgstr "ambos agregados:"
 
-#: wt-status.c:265
+#: wt-status.c:268
 msgid "both modified:"
 msgstr "ambos modificados:"
 
-#: wt-status.c:275
+#: wt-status.c:278
 msgid "new file:"
 msgstr "nuevo archivo:"
 
-#: wt-status.c:277
+#: wt-status.c:280
 msgid "copied:"
 msgstr "copiado:"
 
-#: wt-status.c:279
+#: wt-status.c:282
 msgid "deleted:"
 msgstr "borrado:"
 
-#: wt-status.c:281
+#: wt-status.c:284
 msgid "modified:"
 msgstr "modificado:"
 
-#: wt-status.c:283
+#: wt-status.c:286
 msgid "renamed:"
 msgstr "renombrado:"
 
-#: wt-status.c:285
+#: wt-status.c:288
 msgid "typechange:"
 msgstr "cambio de tipo:"
 
-#: wt-status.c:287
+#: wt-status.c:290
 msgid "unknown:"
 msgstr "desconocido:"
 
-#: wt-status.c:289
+#: wt-status.c:292
 msgid "unmerged:"
 msgstr "des-fusionado:"
 
-#: wt-status.c:369
+#: wt-status.c:372
 msgid "new commits, "
 msgstr "nuevos commits, "
 
-#: wt-status.c:371
+#: wt-status.c:374
 msgid "modified content, "
 msgstr "contenido modificado, "
 
-#: wt-status.c:373
+#: wt-status.c:376
 msgid "untracked content, "
 msgstr "contenido no rastreado, "
 
-#: wt-status.c:847
+#: wt-status.c:853
 #, c-format
 msgid "Your stash currently has %d entry"
 msgid_plural "Your stash currently has %d entries"
 msgstr[0] "Tu stash actualmente tiene %d entrada"
 msgstr[1] "Tu stash actualmente tiene %d entradas"
 
-#: wt-status.c:879
+#: wt-status.c:885
 msgid "Submodules changed but not updated:"
 msgstr "Submodulos cambiados pero no actualizados:"
 
-#: wt-status.c:881
+#: wt-status.c:887
 msgid "Submodule changes to be committed:"
 msgstr "Submodulos cambiados listos para realizar commit:"
 
-#: wt-status.c:963
+#: wt-status.c:969
 msgid ""
 "Do not modify or remove the line above.\n"
 "Everything below it will be ignored."
@@ -4706,107 +5067,107 @@ msgstr ""
 "No modifique o borre la línea de encima.\n"
 "Todo lo que este por abajo será removido."
 
-#: wt-status.c:1076
+#: wt-status.c:1084
 msgid "You have unmerged paths."
 msgstr "Tienes rutas no fusionadas."
 
-#: wt-status.c:1079
+#: wt-status.c:1087
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (arregla los conflictos y corre \"git commit\""
 
-#: wt-status.c:1081
+#: wt-status.c:1089
 msgid "  (use \"git merge --abort\" to abort the merge)"
 msgstr "  (usa \"git merge --abort\" para abortar la fusion)"
 
-#: wt-status.c:1086
+#: wt-status.c:1094
 msgid "All conflicts fixed but you are still merging."
 msgstr "Todos los conflictos resueltos pero sigues fusionando."
 
-#: wt-status.c:1089
+#: wt-status.c:1097
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (usa \"git commit\" para concluir la fusión)"
 
-#: wt-status.c:1099
+#: wt-status.c:1107
 msgid "You are in the middle of an am session."
 msgstr "Estás en medio de una sesión am."
 
-#: wt-status.c:1102
+#: wt-status.c:1110
 msgid "The current patch is empty."
 msgstr "El parche actual esta vacío."
 
-#: wt-status.c:1106
+#: wt-status.c:1114
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr "  (arregla los conflictos y luego corre \"git am --continue\""
 
-#: wt-status.c:1108
+#: wt-status.c:1116
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (usa \"git am --skip\" para saltar este parche)"
 
-#: wt-status.c:1110
+#: wt-status.c:1118
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (usa \"git am --abort\" para restaurar la rama original)"
 
-#: wt-status.c:1242
+#: wt-status.c:1250
 msgid "git-rebase-todo is missing."
 msgstr "git-rebase-todo no esta presente."
 
-#: wt-status.c:1244
+#: wt-status.c:1252
 msgid "No commands done."
 msgstr "No se realizaron los comandos."
 
-#: wt-status.c:1247
+#: wt-status.c:1255
 #, c-format
 msgid "Last command done (%d command done):"
 msgid_plural "Last commands done (%d commands done):"
 msgstr[0] "El último comando realizado (%d comando realizado):"
 msgstr[1] "Los últimos comandos realizados (%d comandos realizados):"
 
-#: wt-status.c:1258
+#: wt-status.c:1266
 #, c-format
 msgid "  (see more in file %s)"
 msgstr "  (ver mas en el archivo %s)"
 
-#: wt-status.c:1263
+#: wt-status.c:1271
 msgid "No commands remaining."
 msgstr "No quedan mas comandos."
 
-#: wt-status.c:1266
+#: wt-status.c:1274
 #, c-format
 msgid "Next command to do (%d remaining command):"
 msgid_plural "Next commands to do (%d remaining commands):"
 msgstr[0] "Siguiente comando a realizar (%d comando restante):"
 msgstr[1] "Siguiente comandos a realizar (%d comandos faltantes):"
 
-#: wt-status.c:1274
+#: wt-status.c:1282
 msgid "  (use \"git rebase --edit-todo\" to view and edit)"
 msgstr "  (usa \"git rebase --edit-todo\" para ver y editar)"
 
-#: wt-status.c:1287
+#: wt-status.c:1295
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "Estás aplicando un rebase de la rama '%s' en '%s."
 
-#: wt-status.c:1292
+#: wt-status.c:1300
 msgid "You are currently rebasing."
 msgstr "Estás aplicando un rebase."
 
-#: wt-status.c:1306
+#: wt-status.c:1314
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (corrige los conflictos y ejecuta \"git rebase --continue\")"
 
-#: wt-status.c:1308
+#: wt-status.c:1316
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (usa \"git rebase --skip\" para omitir este parche)"
 
-#: wt-status.c:1310
+#: wt-status.c:1318
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (usa \"git rebase --abort\" para volver a tu rama original)"
 
-#: wt-status.c:1316
+#: wt-status.c:1324
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (todos los conflictos corregidos: ejecuta \"git rebase --continue\")"
 
-#: wt-status.c:1320
+#: wt-status.c:1328
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
@@ -4814,128 +5175,128 @@ msgstr ""
 "Estás dividiendo un commit mientras aplicas un rebase de la rama '%s' en "
 "'%s'."
 
-#: wt-status.c:1325
+#: wt-status.c:1333
 msgid "You are currently splitting a commit during a rebase."
 msgstr "Estás dividiendo un commit durante un rebase."
 
-#: wt-status.c:1328
+#: wt-status.c:1336
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr ""
 "  (Una vez que tu directorio de trabajo esté limpio, ejecuta \"git rebase --"
 "continue\")"
 
-#: wt-status.c:1332
+#: wt-status.c:1340
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 "Estás editando un commit mientras se aplica un rebase de la rama '%s' en "
 "'%s'."
 
-#: wt-status.c:1337
+#: wt-status.c:1345
 msgid "You are currently editing a commit during a rebase."
 msgstr "Estás editando un commit durante un rebase."
 
-#: wt-status.c:1340
+#: wt-status.c:1348
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr "  (usa \"git commit --amend\" para enmendar el commit actual)"
 
-#: wt-status.c:1342
+#: wt-status.c:1350
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
 "  (usa \"git rebase --continue\" una vez que estés satisfecho con tus "
 "cambios)"
 
-#: wt-status.c:1352
+#: wt-status.c:1360
 #, c-format
 msgid "You are currently cherry-picking commit %s."
 msgstr "Estás realizando un cherry-picking en el commit %s."
 
-#: wt-status.c:1357
+#: wt-status.c:1365
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr "  (corrige los conflictos y ejecuta \"git cherry-pick --continue\")"
 
-#: wt-status.c:1360
+#: wt-status.c:1368
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr ""
 "  (todos los conflictos corregidos: ejecuta \"git cherry-pick --continue\")"
 
-#: wt-status.c:1362
+#: wt-status.c:1370
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr ""
 "  (use \"git cherry-pick --abort\" para cancelar la operación cherry-pick)"
 
-#: wt-status.c:1371
+#: wt-status.c:1379
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "Estás revirtiendo el commit %s."
 
-#: wt-status.c:1376
+#: wt-status.c:1384
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (corrige los conflictos y ejecuta \"git revert --continue\")"
 
-#: wt-status.c:1379
+#: wt-status.c:1387
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr "  (todos los conflictos corregidos: ejecuta \"git revert --continue\")"
 
-#: wt-status.c:1381
+#: wt-status.c:1389
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr "  (usa \"git revert --abort\" para cancelar la operación de revertir)"
 
-#: wt-status.c:1392
+#: wt-status.c:1400
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr "Estás aplicando un bisect, comenzando en la rama '%s'."
 
-#: wt-status.c:1396
+#: wt-status.c:1404
 msgid "You are currently bisecting."
 msgstr "Estás aplicando un bisect."
 
-#: wt-status.c:1399
+#: wt-status.c:1407
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr "  (usa \"git bisect reset\" para volver a la rama original)"
 
-#: wt-status.c:1596
+#: wt-status.c:1604
 msgid "On branch "
 msgstr "En la rama "
 
-#: wt-status.c:1602
+#: wt-status.c:1610
 msgid "interactive rebase in progress; onto "
 msgstr "rebase interactivo en progreso; en "
 
-#: wt-status.c:1604
+#: wt-status.c:1612
 msgid "rebase in progress; onto "
 msgstr "rebase en progreso; en "
 
-#: wt-status.c:1609
+#: wt-status.c:1617
 msgid "HEAD detached at "
 msgstr "HEAD desacoplada en "
 
-#: wt-status.c:1611
+#: wt-status.c:1619
 msgid "HEAD detached from "
 msgstr "HEAD desacoplada de "
 
-#: wt-status.c:1614
+#: wt-status.c:1622
 msgid "Not currently on any branch."
 msgstr "Actualmente no estás en ninguna rama."
 
-#: wt-status.c:1634
+#: wt-status.c:1642
 msgid "Initial commit"
 msgstr "Confirmación inicial"
 
-#: wt-status.c:1635
+#: wt-status.c:1643
 msgid "No commits yet"
 msgstr "No hay commits todavía"
 
-#: wt-status.c:1649
+#: wt-status.c:1657
 msgid "Untracked files"
 msgstr "Archivos sin seguimiento"
 
-#: wt-status.c:1651
+#: wt-status.c:1659
 msgid "Ignored files"
 msgstr "Archivos ignorados"
 
-#: wt-status.c:1655
+#: wt-status.c:1663
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -4946,31 +5307,31 @@ msgstr ""
 "puede acelerarlo, pero tiene que ser cuidadoso de no olvidar agregar\n"
 "nuevos archivos usted mismo (vea 'git help status')."
 
-#: wt-status.c:1661
+#: wt-status.c:1669
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "Archivos no rastreados no son mostrados %s"
 
-#: wt-status.c:1663
+#: wt-status.c:1671
 msgid " (use -u option to show untracked files)"
 msgstr " (usa la opción -u para mostrar los archivos sin seguimiento)"
 
-#: wt-status.c:1669
+#: wt-status.c:1677
 msgid "No changes"
 msgstr "Sin cambios"
 
-#: wt-status.c:1674
+#: wt-status.c:1682
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
 "sin cambios agregados al commit (usa \"git add\" y/o \"git commit -a\")\n"
 
-#: wt-status.c:1677
+#: wt-status.c:1685
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "no se agregaron cambios al commit\n"
 
-#: wt-status.c:1680
+#: wt-status.c:1688
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
@@ -4979,75 +5340,75 @@ msgstr ""
 "no hay nada agregado al commit pero hay archivos sin seguimiento presentes "
 "(usa \"git add\" para hacerles seguimiento)\n"
 
-#: wt-status.c:1683
+#: wt-status.c:1691
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr ""
 "no hay nada agregado para confirmar, pero hay archivos sin seguimiento "
 "presentes\n"
 
-#: wt-status.c:1686
+#: wt-status.c:1694
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
 "no hay nada para confirmar (crea/copia archivos y usa \"git add\" para "
 "hacerles seguimiento)\n"
 
-#: wt-status.c:1689 wt-status.c:1694
+#: wt-status.c:1697 wt-status.c:1702
 #, c-format
 msgid "nothing to commit\n"
 msgstr "nada para hacer commit\n"
 
-#: wt-status.c:1692
+#: wt-status.c:1700
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr ""
 "nada para hacer commit (usa -u para mostrar los archivos no rastreados)\n"
 
-#: wt-status.c:1696
+#: wt-status.c:1704
 #, c-format
 msgid "nothing to commit, working tree clean\n"
 msgstr "nada para hacer commit, el árbol de trabajo esta limpio\n"
 
-#: wt-status.c:1809
+#: wt-status.c:1817
 msgid "No commits yet on "
 msgstr "No hay commits todavía en "
 
-#: wt-status.c:1813
+#: wt-status.c:1821
 msgid "HEAD (no branch)"
 msgstr "HEAD (sin rama)"
 
-#: wt-status.c:1844
+#: wt-status.c:1852
 msgid "different"
 msgstr "diferente"
 
-#: wt-status.c:1846 wt-status.c:1854
+#: wt-status.c:1854 wt-status.c:1862
 msgid "behind "
 msgstr "detrás "
 
-#: wt-status.c:1849 wt-status.c:1852
+#: wt-status.c:1857 wt-status.c:1860
 msgid "ahead "
 msgstr "adelante "
 
 #. TRANSLATORS: the action is e.g. "pull with rebase"
-#: wt-status.c:2358
+#: wt-status.c:2366
 #, c-format
 msgid "cannot %s: You have unstaged changes."
 msgstr "no se puede %s: Tienes cambios sin marcar."
 
-#: wt-status.c:2364
+#: wt-status.c:2372
 msgid "additionally, your index contains uncommitted changes."
 msgstr "adicionalmente, tu índice contiene cambios que no están en un commit."
 
-#: wt-status.c:2366
+#: wt-status.c:2374
 #, c-format
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "no se puede %s: Tu índice contiene cambios que no están en un commit."
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:440
+#: compat/precompose_utf8.c:58 builtin/clone.c:442
 #, c-format
 msgid "failed to unlink '%s'"
-msgstr "fallo al desvincular '%s'"
+msgstr "falló al desvincular '%s'"
 
 #: builtin/add.c:24
 msgid "git add [<options>] [--] <pathspec>..."
@@ -5058,9 +5419,9 @@ msgstr "git add [<opción>] [--] <especificación-de-ruta>..."
 msgid "unexpected diff status %c"
 msgstr "diff status inesperado %c"
 
-#: builtin/add.c:88 builtin/commit.c:257
+#: builtin/add.c:88 builtin/commit.c:266
 msgid "updating files failed"
-msgstr "fallo la actualización de carpetas"
+msgstr "falló la actualización de carpetas"
 
 #: builtin/add.c:98
 #, c-format
@@ -5071,7 +5432,7 @@ msgstr "remover '%s'\n"
 msgid "Unstaged changes after refreshing the index:"
 msgstr "Cambios fuera del área de stage tras refrescar el índice:"
 
-#: builtin/add.c:233 builtin/rev-parse.c:888
+#: builtin/add.c:233 builtin/rev-parse.c:892
 msgid "Could not read the index"
 msgstr "No se pudo leer el índice"
 
@@ -5086,7 +5447,7 @@ msgstr "No se puede escribir el parche"
 
 #: builtin/add.c:251
 msgid "editing patch failed"
-msgstr "fallo la edición del parche"
+msgstr "falló la edición del parche"
 
 #: builtin/add.c:254
 #, c-format
@@ -5102,78 +5463,78 @@ msgstr "Parche vacío. Abortado."
 msgid "Could not apply '%s'"
 msgstr "No se pudo aplicar '%s'"
 
-#: builtin/add.c:271
+#: builtin/add.c:269
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr ""
 "Las siguientes rutas son ignoradas por uno de tus archivos .gitignore:\n"
 
-#: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:146 builtin/mv.c:124
-#: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541
-#: builtin/remote.c:1333 builtin/rm.c:242 builtin/send-pack.c:164
+#: builtin/add.c:289 builtin/clean.c:911 builtin/fetch.c:145 builtin/mv.c:123
+#: builtin/prune-packed.c:55 builtin/pull.c:212 builtin/push.c:557
+#: builtin/remote.c:1342 builtin/rm.c:240 builtin/send-pack.c:165
 msgid "dry run"
 msgstr "dry run ( ejecución en seco)"
 
-#: builtin/add.c:294
+#: builtin/add.c:292
 msgid "interactive picking"
 msgstr "selección interactiva"
 
-#: builtin/add.c:295 builtin/checkout.c:1128 builtin/reset.c:302
+#: builtin/add.c:293 builtin/checkout.c:1135 builtin/reset.c:302
 msgid "select hunks interactively"
 msgstr "elegir hunks de forma interactiva"
 
-#: builtin/add.c:296
+#: builtin/add.c:294
 msgid "edit current diff and apply"
 msgstr "editar diff actual y aplicar"
 
-#: builtin/add.c:297
+#: builtin/add.c:295
 msgid "allow adding otherwise ignored files"
 msgstr "permitir agregar caso contrario ignorar archivos"
 
-#: builtin/add.c:298
+#: builtin/add.c:296
 msgid "update tracked files"
 msgstr "actualizado las carpetas rastreadas"
 
-#: builtin/add.c:299
+#: builtin/add.c:297
 msgid "renormalize EOL of tracked files (implies -u)"
 msgstr "renormalizar EOL de los archivos rastreados (implica -u)"
 
-#: builtin/add.c:300
+#: builtin/add.c:298
 msgid "record only the fact that the path will be added later"
 msgstr "grabar solo el hecho de que la ruta será agregada después"
 
-#: builtin/add.c:301
+#: builtin/add.c:299
 msgid "add changes from all tracked and untracked files"
 msgstr "agregar los cambios de todas las carpetas con y sin seguimiento"
 
-#: builtin/add.c:304
+#: builtin/add.c:302
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr "ignorar rutas removidas en el árbol de trabajo (lo mismo que --no-all)"
 
-#: builtin/add.c:306
+#: builtin/add.c:304
 msgid "don't add, only refresh the index"
 msgstr "no agregar, solo actualizar el índice"
 
-#: builtin/add.c:307
+#: builtin/add.c:305
 msgid "just skip files which cannot be added because of errors"
 msgstr "saltar las carpetas que no pueden ser agregadas a causa de errores"
 
-#: builtin/add.c:308
+#: builtin/add.c:306
 msgid "check if - even missing - files are ignored in dry run"
 msgstr "comprobar si - incluso los archivos que faltan - se ignoran en dry run"
 
-#: builtin/add.c:309 builtin/update-index.c:964
+#: builtin/add.c:307 builtin/update-index.c:974
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/add.c:309 builtin/update-index.c:965
+#: builtin/add.c:307 builtin/update-index.c:975
 msgid "override the executable bit of the listed files"
 msgstr "sobrescribir el bit ejecutable de los archivos listados"
 
-#: builtin/add.c:311
+#: builtin/add.c:309
 msgid "warn when adding an embedded repository"
 msgstr "avisar cuando se agrega un repositorio incrustado"
 
-#: builtin/add.c:326
+#: builtin/add.c:324
 #, c-format
 msgid ""
 "You've added another git repository inside your current repository.\n"
@@ -5204,47 +5565,47 @@ msgstr ""
 "\n"
 "Vea \"git help submodule\" para mas información."
 
-#: builtin/add.c:354
+#: builtin/add.c:352
 #, c-format
 msgid "adding embedded git repository: %s"
 msgstr "agregando repositorio embebido: %s"
 
-#: builtin/add.c:372
+#: builtin/add.c:370
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "Use -f si realmente quiere agregarlos.\n"
 
-#: builtin/add.c:380
+#: builtin/add.c:378
 msgid "adding files failed"
-msgstr "fallo al agregar archivos"
+msgstr "falló al agregar archivos"
 
-#: builtin/add.c:417
+#: builtin/add.c:416
 msgid "-A and -u are mutually incompatible"
 msgstr "-A y -u son mutuamente incompatibles"
 
-#: builtin/add.c:424
+#: builtin/add.c:423
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr "Opción --ignore-missing solo puede ser usada junto a --dry-run"
 
-#: builtin/add.c:428
+#: builtin/add.c:427
 #, c-format
 msgid "--chmod param '%s' must be either -x or +x"
 msgstr "El parámetro '%s' para --chmod debe ser -x ó +x"
 
-#: builtin/add.c:443
+#: builtin/add.c:442
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "Nada especificado, nada agregado.\n"
 
-#: builtin/add.c:444
+#: builtin/add.c:443
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Tal vez quiso decir 'git add .'?\n"
 
-#: builtin/add.c:449 builtin/check-ignore.c:177 builtin/checkout.c:280
-#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316
+#: builtin/add.c:448 builtin/check-ignore.c:177 builtin/checkout.c:280
+#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:325
 #: builtin/diff-tree.c:114 builtin/mv.c:144 builtin/reset.c:241
-#: builtin/rm.c:271 builtin/submodule--helper.c:326
+#: builtin/rm.c:270 builtin/submodule--helper.c:328
 msgid "index file corrupt"
 msgstr "archivo índice corrompido"
 
@@ -5265,7 +5626,7 @@ msgstr "Línea mal formada: '%s'."
 #: builtin/am.c:576
 #, c-format
 msgid "Failed to copy notes from '%s' to '%s'"
-msgstr "Fallo al copiar notas de '%s' a '%s'"
+msgstr "Falló al copiar notas de '%s' a '%s'"
 
 #: builtin/am.c:602
 msgid "fseek failed"
@@ -5296,16 +5657,16 @@ msgstr "offset de zona horaria inválido"
 msgid "Patch format detection failed."
 msgstr "Falló al detectar el formato del parche."
 
-#: builtin/am.c:1013 builtin/clone.c:405
+#: builtin/am.c:1013 builtin/clone.c:407
 #, c-format
 msgid "failed to create directory '%s'"
-msgstr "fallo al crear el directorio '%s'"
+msgstr "falló al crear el directorio '%s'"
 
 #: builtin/am.c:1018
 msgid "Failed to split patches."
-msgstr "Fallo al dividir parches."
+msgstr "Falló al dividir parches."
 
-#: builtin/am.c:1148 builtin/commit.c:342
+#: builtin/am.c:1148 builtin/commit.c:351
 msgid "unable to write index file"
 msgstr "no es posible escribir en el archivo índice"
 
@@ -5408,7 +5769,7 @@ msgstr "Sin cambios -- parche ya aplicado."
 #: builtin/am.c:1832
 #, c-format
 msgid "Patch failed at %s %.*s"
-msgstr "El parche fallo en %s %.*s"
+msgstr "El parche falló en %s %.*s"
 
 #: builtin/am.c:1838
 msgid "Use 'git am --show-current-patch' to see the failed patch"
@@ -5445,14 +5806,14 @@ msgstr "No se pudo analizar el objeto '%s'."
 
 #: builtin/am.c:2048
 msgid "failed to clean index"
-msgstr "fallo al limpiar el índice"
+msgstr "falló al limpiar el índice"
 
 #: builtin/am.c:2083
 msgid ""
 "You seem to have moved HEAD since the last 'am' failure.\n"
 "Not rewinding to ORIG_HEAD"
 msgstr ""
-"Parece haber movido HEAD desde el último fallo 'am'.\n"
+"Parece haber movido HEAD desde el último falló 'am'.\n"
 "No rebobinando a ORIG_HEAD"
 
 #: builtin/am.c:2174
@@ -5481,7 +5842,7 @@ msgid "allow fall back on 3way merging if needed"
 msgstr "permitir retroceso en fusión de 3-vías si es necesario"
 
 #: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57
-#: builtin/repack.c:182
+#: builtin/repack.c:192
 msgid "be quiet"
 msgstr "ser silencioso"
 
@@ -5524,16 +5885,17 @@ msgstr "descubrir todo antes de una línea de tijeras"
 msgid "pass it through git-apply"
 msgstr "pasarlo a través de git-apply"
 
-#: builtin/am.c:2260 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668
-#: builtin/grep.c:853 builtin/merge.c:206 builtin/pull.c:145 builtin/pull.c:203
-#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197
-#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:382
-#: parse-options.h:144 parse-options.h:146 parse-options.h:257
+#: builtin/am.c:2260 builtin/commit.c:1332 builtin/fmt-merge-msg.c:665
+#: builtin/fmt-merge-msg.c:668 builtin/grep.c:853 builtin/merge.c:208
+#: builtin/pull.c:150 builtin/pull.c:208 builtin/repack.c:201
+#: builtin/repack.c:205 builtin/repack.c:207 builtin/show-branch.c:631
+#: builtin/show-ref.c:169 builtin/tag.c:383 parse-options.h:144
+#: parse-options.h:146 parse-options.h:258
 msgid "n"
 msgstr "n"
 
-#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38
-#: builtin/replace.c:445 builtin/tag.c:418 builtin/verify-tag.c:39
+#: builtin/am.c:2266 builtin/branch.c:632 builtin/for-each-ref.c:38
+#: builtin/replace.c:543 builtin/tag.c:419 builtin/verify-tag.c:39
 msgid "format"
 msgstr "formato"
 
@@ -5577,8 +5939,8 @@ msgstr "mentir sobre la fecha del committer"
 msgid "use current timestamp for author date"
 msgstr "usar el timestamp actual para la fecha del autor"
 
-#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237
-#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:398
+#: builtin/am.c:2298 builtin/commit.c:1468 builtin/merge.c:239
+#: builtin/pull.c:183 builtin/revert.c:112 builtin/tag.c:399
 msgid "key-id"
 msgstr "key-id"
 
@@ -5600,7 +5962,7 @@ msgstr ""
 
 #: builtin/am.c:2327
 msgid "failed to read the index"
-msgstr "fallo al leer el índice"
+msgstr "falló al leer el índice"
 
 #: builtin/am.c:2342
 #, c-format
@@ -5717,115 +6079,141 @@ msgstr "--write-terms requiere dos argumentos"
 msgid "--bisect-clean-state requires no arguments"
 msgstr "--bisect-clean-state no requiere argumentos"
 
-#: builtin/blame.c:27
+#: builtin/blame.c:29
 msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
 msgstr "git blame [<opciones>] [<opciones-rev>] [<revision>] [--] <archivo>"
 
-#: builtin/blame.c:32
+#: builtin/blame.c:34
 msgid "<rev-opts> are documented in git-rev-list(1)"
 msgstr "<rev-opts> están documentadas en git-rev-list(1)"
 
-#: builtin/blame.c:677
+#: builtin/blame.c:404
+#, c-format
+msgid "expecting a color: %s"
+msgstr "esperando un color: %s"
+
+#: builtin/blame.c:411
+msgid "must end with a color"
+msgstr "tiene que terminar con un color"
+
+#: builtin/blame.c:697
+#, c-format
+msgid "invalid color '%s' in color.blame.repeatedLines"
+msgstr "color invalido '%s' en color.blame.repeatedLines"
+
+#: builtin/blame.c:715
+msgid "invalid value for blame.coloring"
+msgstr "valor inválido para blame.coloring"
+
+#: builtin/blame.c:786
 msgid "Show blame entries as we find them, incrementally"
 msgstr "Mostrar las entradas blame como las encontramos, incrementalmente"
 
-#: builtin/blame.c:678
+#: builtin/blame.c:787
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr "Mostrar SHA-1 en blanco para commits extremos (Default: off)"
 
-#: builtin/blame.c:679
+#: builtin/blame.c:788
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr "No tratar commits raíces como extremos (Default: off)"
 
-#: builtin/blame.c:680
+#: builtin/blame.c:789
 msgid "Show work cost statistics"
 msgstr "Mostrar estadísticas de costo de trabajo"
 
-#: builtin/blame.c:681
+#: builtin/blame.c:790
 msgid "Force progress reporting"
 msgstr "Forzar el reporte de progreso"
 
-#: builtin/blame.c:682
+#: builtin/blame.c:791
 msgid "Show output score for blame entries"
 msgstr "Mostrar la puntuación de salida de las entradas de blame"
 
-#: builtin/blame.c:683
+#: builtin/blame.c:792
 msgid "Show original filename (Default: auto)"
 msgstr "Mostrar nombre original del archivo (Default: auto)"
 
-#: builtin/blame.c:684
+#: builtin/blame.c:793
 msgid "Show original linenumber (Default: off)"
 msgstr "Mostrar número de línea original (Default: off)"
 
-#: builtin/blame.c:685
+#: builtin/blame.c:794
 msgid "Show in a format designed for machine consumption"
 msgstr "Mostrar en un formato diseñado para consumo de máquina"
 
-#: builtin/blame.c:686
+#: builtin/blame.c:795
 msgid "Show porcelain format with per-line commit information"
 msgstr "Mostrar en formato porcelana con información de commit por línea"
 
-#: builtin/blame.c:687
+#: builtin/blame.c:796
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr "Usar el mismo modo salida como git-annotate (Default: off)"
 
-#: builtin/blame.c:688
+#: builtin/blame.c:797
 msgid "Show raw timestamp (Default: off)"
 msgstr "Mostrar timestamp en formato raw (Default: off)"
 
-#: builtin/blame.c:689
+#: builtin/blame.c:798
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "Mostrar SHA1 del commit en formato largo (Default: off)"
 
-#: builtin/blame.c:690
+#: builtin/blame.c:799
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "Suprimir nombre del autor y timestamp (Default: off)"
 
-#: builtin/blame.c:691
+#: builtin/blame.c:800
 msgid "Show author email instead of name (Default: off)"
 msgstr "Mostrar en cambio el email del autor (Default: off)"
 
-#: builtin/blame.c:692
+#: builtin/blame.c:801
 msgid "Ignore whitespace differences"
 msgstr "Ignorar diferencias de espacios en blanco"
 
-#: builtin/blame.c:699
+#: builtin/blame.c:802
+msgid "color redundant metadata from previous line differently"
+msgstr "colorear metadata redundante de lineas previas de manera diferente"
+
+#: builtin/blame.c:803
+msgid "color lines by age"
+msgstr "colorear lineas por edad"
+
+#: builtin/blame.c:810
 msgid "Use an experimental heuristic to improve diffs"
 msgstr "Usar un heurístico experimental para mejorar los diffs"
 
-#: builtin/blame.c:701
+#: builtin/blame.c:812
 msgid "Spend extra cycles to find better match"
 msgstr "Ocupo más ciclos para encontrar mejoras resultados"
 
-#: builtin/blame.c:702
+#: builtin/blame.c:813
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr "Use revisiones desde <archivo> en lugar de llamar git-rev-list"
 
-#: builtin/blame.c:703
+#: builtin/blame.c:814
 msgid "Use <file>'s contents as the final image"
 msgstr "Usar contenido de <archivo> como imagen final"
 
-#: builtin/blame.c:704 builtin/blame.c:705
+#: builtin/blame.c:815 builtin/blame.c:816
 msgid "score"
 msgstr "puntaje"
 
-#: builtin/blame.c:704
+#: builtin/blame.c:815
 msgid "Find line copies within and across files"
 msgstr "Encontrar copias de líneas entre y a través de archivos"
 
-#: builtin/blame.c:705
+#: builtin/blame.c:816
 msgid "Find line movements within and across files"
 msgstr "Encontrar movimientos de líneas entre y a través de archivos"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "Process only line range n,m, counting from 1"
 msgstr "Procesar solo el rango de líneas n,m, contando desde 1"
 
-#: builtin/blame.c:753
+#: builtin/blame.c:866
 msgid "--progress can't be used with --incremental or porcelain formats"
 msgstr "--progress no puede ser usado con --incremental o formatos porcelana"
 
@@ -5837,18 +6225,18 @@ msgstr "--progress no puede ser usado con --incremental o formatos porcelana"
 #. your language may need more or fewer display
 #. columns.
 #.
-#: builtin/blame.c:804
+#: builtin/blame.c:917
 msgid "4 years, 11 months ago"
 msgstr "hace 4 años, 11 meses"
 
-#: builtin/blame.c:890
+#: builtin/blame.c:1003
 #, c-format
 msgid "file %s has only %lu line"
 msgid_plural "file %s has only %lu lines"
 msgstr[0] "archivo %s tiene solo %lu línea"
 msgstr[1] "archivo %s tiene solo %lu líneas"
 
-#: builtin/blame.c:936
+#: builtin/blame.c:1049
 msgid "Blaming lines"
 msgstr "Blaming a líneas"
 
@@ -5914,7 +6302,7 @@ msgstr ""
 
 #: builtin/branch.c:181
 msgid "Update of config-file failed"
-msgstr "Fallo de actualización de config-file"
+msgstr "Falló de actualización de config-file"
 
 #: builtin/branch.c:212
 msgid "cannot use -a with -d"
@@ -5959,69 +6347,69 @@ msgstr "Eliminada la rama de rastreo remota %s (era %s).\n"
 msgid "Deleted branch %s (was %s).\n"
 msgstr "Eliminada la rama %s (era %s)..\n"
 
-#: builtin/branch.c:417 builtin/tag.c:58
+#: builtin/branch.c:416 builtin/tag.c:58
 msgid "unable to parse format string"
 msgstr "no es posible analizar el string de formato"
 
-#: builtin/branch.c:450
+#: builtin/branch.c:453
 #, c-format
 msgid "Branch %s is being rebased at %s"
 msgstr "Rama %s está siendo rebasada en %s"
 
-#: builtin/branch.c:454
+#: builtin/branch.c:457
 #, c-format
 msgid "Branch %s is being bisected at %s"
 msgstr "Rama %s está siendo bisecada en %s"
 
-#: builtin/branch.c:471
+#: builtin/branch.c:474
 msgid "cannot copy the current branch while not on any."
 msgstr "no se puede copiar la rama actual mientras no se está en ninguna."
 
-#: builtin/branch.c:473
+#: builtin/branch.c:476
 msgid "cannot rename the current branch while not on any."
 msgstr "no se puede renombrar la rama actual mientras no se está en ninguna."
 
-#: builtin/branch.c:484
+#: builtin/branch.c:487
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "Nombre de rama invalido: '%s'"
 
-#: builtin/branch.c:511
+#: builtin/branch.c:514
 msgid "Branch rename failed"
 msgstr "Cambio de nombre de rama fallido"
 
-#: builtin/branch.c:513
+#: builtin/branch.c:516
 msgid "Branch copy failed"
 msgstr "Copiado de rama fallido"
 
-#: builtin/branch.c:517
+#: builtin/branch.c:520
 #, c-format
 msgid "Created a copy of a misnamed branch '%s'"
 msgstr "Copia creada de la rama malnombrada '%s'"
 
-#: builtin/branch.c:520
+#: builtin/branch.c:523
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "Rama mal llamada '%s' renombrada"
 
-#: builtin/branch.c:526
+#: builtin/branch.c:529
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "¡Rama renombrada a %s, pero HEAD no está actualizado!"
 
-#: builtin/branch.c:535
+#: builtin/branch.c:538
 msgid "Branch is renamed, but update of config-file failed"
 msgstr ""
 "La rama está renombrada, pero falló la actualización del archivo de "
 "configuración"
 
-#: builtin/branch.c:537
+#: builtin/branch.c:540
 msgid "Branch is copied, but update of config-file failed"
 msgstr ""
 "La rama está copiada, pero falló la actualización del archivo de "
 "configuración"
 
-#: builtin/branch.c:553
+#: builtin/branch.c:556
 #, c-format
 msgid ""
 "Please edit the description for the branch\n"
@@ -6032,184 +6420,186 @@ msgstr ""
 "%s\n"
 "Las líneas que comiencen con '%c' serán removidas.\n"
 
-#: builtin/branch.c:586
+#: builtin/branch.c:589
 msgid "Generic options"
 msgstr "Opciones genéricas"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:591
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "mostrar hash y tema, dar dos veces para rama upstream"
 
-#: builtin/branch.c:589
+#: builtin/branch.c:592
 msgid "suppress informational messages"
 msgstr "suprimir mensajes informativos"
 
-#: builtin/branch.c:590
+#: builtin/branch.c:593
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "configurando modo tracking (mirar git-pull(1))"
 
-#: builtin/branch.c:592
+#: builtin/branch.c:595
 msgid "do not use"
 msgstr "no usar"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "upstream"
 msgstr "upstream"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "change the upstream info"
 msgstr "cambiar info de upstream"
 
-#: builtin/branch.c:595
+#: builtin/branch.c:598
 msgid "Unset the upstream info"
 msgstr "Desconfigurando la info de upstream"
 
-#: builtin/branch.c:596
+#: builtin/branch.c:599
 msgid "use colored output"
 msgstr "usar salida con colores"
 
-#: builtin/branch.c:597
+#: builtin/branch.c:600
 msgid "act on remote-tracking branches"
 msgstr "actuar en ramas de traqueo remoto"
 
-#: builtin/branch.c:599 builtin/branch.c:601
+#: builtin/branch.c:602 builtin/branch.c:604
 msgid "print only branches that contain the commit"
 msgstr "mostrar solo ramas que contienen el commit"
 
-#: builtin/branch.c:600 builtin/branch.c:602
+#: builtin/branch.c:603 builtin/branch.c:605
 msgid "print only branches that don't contain the commit"
 msgstr "mostrar solo ramas que no contienen el commit"
 
-#: builtin/branch.c:605
+#: builtin/branch.c:608
 msgid "Specific git-branch actions:"
 msgstr "Acciones específicas de git-branch:"
 
-#: builtin/branch.c:606
+#: builtin/branch.c:609
 msgid "list both remote-tracking and local branches"
 msgstr "listar ramas de remote-tracking y locales"
 
-#: builtin/branch.c:608
+#: builtin/branch.c:611
 msgid "delete fully merged branch"
 msgstr "borrar ramas totalmente fusionadas"
 
-#: builtin/branch.c:609
+#: builtin/branch.c:612
 msgid "delete branch (even if not merged)"
 msgstr "borrar rama (incluso si no esta fusionada)"
 
-#: builtin/branch.c:610
+#: builtin/branch.c:613
 msgid "move/rename a branch and its reflog"
 msgstr "mover/renombrar una rama y su reflog"
 
-#: builtin/branch.c:611
+#: builtin/branch.c:614
 msgid "move/rename a branch, even if target exists"
 msgstr "mover/renombrar una rama, incluso si el destino existe"
 
-#: builtin/branch.c:612
+#: builtin/branch.c:615
 msgid "copy a branch and its reflog"
 msgstr "copiar una rama y su reflog"
 
-#: builtin/branch.c:613
+#: builtin/branch.c:616
 msgid "copy a branch, even if target exists"
 msgstr "copiar una rama, incluso si el objetivo existe"
 
-#: builtin/branch.c:614
+#: builtin/branch.c:617
 msgid "list branch names"
 msgstr "listar nombres de ramas"
 
-#: builtin/branch.c:615
+#: builtin/branch.c:618
 msgid "create the branch's reflog"
 msgstr "crea el reflog de la rama"
 
-#: builtin/branch.c:617
+#: builtin/branch.c:620
 msgid "edit the description for the branch"
 msgstr "edita la descripción de la rama"
 
-#: builtin/branch.c:618
+#: builtin/branch.c:621
 msgid "force creation, move/rename, deletion"
 msgstr "fuerza la creación,movimiento/renombrado,borrado"
 
-#: builtin/branch.c:619
+#: builtin/branch.c:622
 msgid "print only branches that are merged"
 msgstr "muestra solo ramas que han sido fusionadas"
 
-#: builtin/branch.c:620
+#: builtin/branch.c:623
 msgid "print only branches that are not merged"
 msgstr "muestra solo ramas que no han sido fusionadas"
 
-#: builtin/branch.c:621
+#: builtin/branch.c:624
 msgid "list branches in columns"
 msgstr "muestra las ramas en columnas"
 
-#: builtin/branch.c:622 builtin/for-each-ref.c:40 builtin/tag.c:411
+#: builtin/branch.c:625 builtin/for-each-ref.c:40 builtin/ls-remote.c:70
+#: builtin/tag.c:412
 msgid "key"
 msgstr "clave"
 
-#: builtin/branch.c:623 builtin/for-each-ref.c:41 builtin/tag.c:412
+#: builtin/branch.c:626 builtin/for-each-ref.c:41 builtin/ls-remote.c:71
+#: builtin/tag.c:413
 msgid "field name to sort on"
 msgstr "nombre del campo por el cuál ordenar"
 
-#: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408
+#: builtin/branch.c:628 builtin/for-each-ref.c:43 builtin/notes.c:408
 #: builtin/notes.c:411 builtin/notes.c:571 builtin/notes.c:574
-#: builtin/tag.c:414
+#: builtin/tag.c:415
 msgid "object"
 msgstr "objeto"
 
-#: builtin/branch.c:626
+#: builtin/branch.c:629
 msgid "print only branches of the object"
 msgstr "imprimir sólo las ramas del objeto"
 
-#: builtin/branch.c:628 builtin/for-each-ref.c:49 builtin/tag.c:421
+#: builtin/branch.c:631 builtin/for-each-ref.c:49 builtin/tag.c:422
 msgid "sorting and filtering are case insensitive"
 msgstr "ordenamiento y filtrado son case-insensitive"
 
-#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419
+#: builtin/branch.c:632 builtin/for-each-ref.c:38 builtin/tag.c:420
 #: builtin/verify-tag.c:39
 msgid "format to use for the output"
 msgstr "formato para usar para el output"
 
-#: builtin/branch.c:652 builtin/clone.c:735
+#: builtin/branch.c:655 builtin/clone.c:737
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD no encontrado abajo de refs/heads!"
 
-#: builtin/branch.c:675
+#: builtin/branch.c:678
 msgid "--column and --verbose are incompatible"
 msgstr "--column y --verbose son incompatibles"
 
-#: builtin/branch.c:690 builtin/branch.c:742 builtin/branch.c:751
+#: builtin/branch.c:693 builtin/branch.c:745 builtin/branch.c:754
 msgid "branch name required"
 msgstr "se necesita el nombre de la rama"
 
-#: builtin/branch.c:718
+#: builtin/branch.c:721
 msgid "Cannot give description to detached HEAD"
 msgstr "No se puede dar descripción al HEAD desacoplado"
 
-#: builtin/branch.c:723
+#: builtin/branch.c:726
 msgid "cannot edit description of more than one branch"
 msgstr "no se puede editar la descripción de más de una rama"
 
-#: builtin/branch.c:730
+#: builtin/branch.c:733
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "Aún no hay commits en la rama '%s'."
 
-#: builtin/branch.c:733
+#: builtin/branch.c:736
 #, c-format
 msgid "No branch named '%s'."
 msgstr "No hay ninguna rama llamada '%s'."
 
-#: builtin/branch.c:748
+#: builtin/branch.c:751
 msgid "too many branches for a copy operation"
 msgstr "demasiadas ramas para una operación de copiado"
 
-#: builtin/branch.c:757
+#: builtin/branch.c:760
 msgid "too many arguments for a rename operation"
 msgstr "demasiados argumentos para una operación de renombrado"
 
-#: builtin/branch.c:762
+#: builtin/branch.c:765
 msgid "too many arguments to set new upstream"
 msgstr "demasiados argumentos para configurar un nuevo upstream"
 
-#: builtin/branch.c:766
+#: builtin/branch.c:769
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
@@ -6217,37 +6607,37 @@ msgstr ""
 "no se pudo configurar upstream de HEAD a %s cuando este no apunta a ninguna "
 "rama."
 
-#: builtin/branch.c:769 builtin/branch.c:791 builtin/branch.c:807
+#: builtin/branch.c:772 builtin/branch.c:794 builtin/branch.c:810
 #, c-format
 msgid "no such branch '%s'"
 msgstr "no hay tal rama '%s'"
 
-#: builtin/branch.c:773
+#: builtin/branch.c:776
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "la rama '%s' no existe"
 
-#: builtin/branch.c:785
+#: builtin/branch.c:788
 msgid "too many arguments to unset upstream"
 msgstr "demasiados argumentos para desconfigurar upstream"
 
-#: builtin/branch.c:789
+#: builtin/branch.c:792
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
 "no se puede desconfigurar upstream de HEAD cuando este no apunta a ninguna "
 "rama."
 
-#: builtin/branch.c:795
+#: builtin/branch.c:798
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "Rama '%s' no tiene información de upstream"
 
-#: builtin/branch.c:810
+#: builtin/branch.c:813
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr ""
 "opciones -a y -r para 'git branch' no tienen sentido con un nombre de rama"
 
-#: builtin/branch.c:813
+#: builtin/branch.c:816
 msgid ""
 "the '--set-upstream' option is no longer supported. Please use '--track' or "
 "'--set-upstream-to' instead."
@@ -6268,7 +6658,7 @@ msgstr "Se necesita un repositorio para agrupar."
 msgid "Need a repository to unbundle."
 msgstr "Se necesita un repositorio para desagrupar."
 
-#: builtin/cat-file.c:523
+#: builtin/cat-file.c:525
 msgid ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <type> | --textconv | --filters) [--path=<path>] <object>"
@@ -6276,7 +6666,7 @@ msgstr ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <tipo> | --textconv | --filters) [--path=<ruta>] <objeto>"
 
-#: builtin/cat-file.c:524
+#: builtin/cat-file.c:526
 msgid ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
@@ -6284,64 +6674,64 @@ msgstr ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
 
-#: builtin/cat-file.c:561
+#: builtin/cat-file.c:563
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<tipo> puede ser: blob, tree, commit, tag"
 
-#: builtin/cat-file.c:562
+#: builtin/cat-file.c:564
 msgid "show object type"
 msgstr "mostrar el tipo del objeto"
 
-#: builtin/cat-file.c:563
+#: builtin/cat-file.c:565
 msgid "show object size"
 msgstr "mostrar el tamaño del objeto"
 
-#: builtin/cat-file.c:565
+#: builtin/cat-file.c:567
 msgid "exit with zero when there's no error"
 msgstr "salir con cero cuando no haya error"
 
-#: builtin/cat-file.c:566
+#: builtin/cat-file.c:568
 msgid "pretty-print object's content"
 msgstr "realizar pretty-print del contenido del objeto"
 
-#: builtin/cat-file.c:568
+#: builtin/cat-file.c:570
 msgid "for blob objects, run textconv on object's content"
 msgstr "para objetos blob, ejecuta textconv en el contenido del objeto"
 
-#: builtin/cat-file.c:570
+#: builtin/cat-file.c:572
 msgid "for blob objects, run filters on object's content"
 msgstr "para objetos blob, ejecuta filters en el contenido del objeto"
 
-#: builtin/cat-file.c:571 git-submodule.sh:878
+#: builtin/cat-file.c:573 git-submodule.sh:894
 msgid "blob"
 msgstr "blob"
 
-#: builtin/cat-file.c:572
+#: builtin/cat-file.c:574
 msgid "use a specific path for --textconv/--filters"
 msgstr "use una ruta específica para --textconv/--filters"
 
-#: builtin/cat-file.c:574
+#: builtin/cat-file.c:576
 msgid "allow -s and -t to work with broken/corrupt objects"
 msgstr "permita -s y -t para trabajar con objetos rotos o corruptos"
 
-#: builtin/cat-file.c:575
+#: builtin/cat-file.c:577
 msgid "buffer --batch output"
 msgstr "salida buffer --batch"
 
-#: builtin/cat-file.c:577
+#: builtin/cat-file.c:579
 msgid "show info and content of objects fed from the standard input"
 msgstr "mostrar info y content de los objetos alimentados por standard input"
 
-#: builtin/cat-file.c:580
+#: builtin/cat-file.c:582
 msgid "show info about objects fed from the standard input"
 msgstr "mostrar info de los objetos alimentados por standard input"
 
-#: builtin/cat-file.c:583
+#: builtin/cat-file.c:585
 msgid "follow in-tree symlinks (used with --batch or --batch-check)"
 msgstr ""
 "seguir los enlaces simbólicos en el árbol (usado con --batch o --batch-check)"
 
-#: builtin/cat-file.c:585
+#: builtin/cat-file.c:587
 msgid "show all objects with --batch or --batch-check"
 msgstr "mostrar todos los objetos con --batch o --batch-check"
 
@@ -6369,7 +6759,7 @@ msgstr "leer nombres de archivos de stdin"
 msgid "terminate input and output records by a NUL character"
 msgstr "terminar registros de entrada y salida con un carácter NUL"
 
-#: builtin/check-ignore.c:20 builtin/checkout.c:1106 builtin/gc.c:358
+#: builtin/check-ignore.c:20 builtin/checkout.c:1113 builtin/gc.c:500
 msgid "suppress progress reporting"
 msgstr "suprimir el reporte de progreso"
 
@@ -6461,9 +6851,9 @@ msgid "write the content to temporary files"
 msgstr "escribir el contenido en un archivo temporal"
 
 #: builtin/checkout-index.c:173 builtin/column.c:31
-#: builtin/submodule--helper.c:1203 builtin/submodule--helper.c:1206
-#: builtin/submodule--helper.c:1212 builtin/submodule--helper.c:1574
-#: builtin/worktree.c:570
+#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1219
+#: builtin/submodule--helper.c:1227 builtin/submodule--helper.c:1591
+#: builtin/worktree.c:610
 msgid "string"
 msgstr "string"
 
@@ -6534,54 +6924,54 @@ msgstr "No se puede actualizar rutas y cambiar a la rama '%s' al mismo tiempo."
 msgid "path '%s' is unmerged"
 msgstr "ruta '%s' no esta fusionada"
 
-#: builtin/checkout.c:505
+#: builtin/checkout.c:506
 msgid "you need to resolve your current index first"
 msgstr "necesita resolver su índice actual primero"
 
-#: builtin/checkout.c:636
+#: builtin/checkout.c:643
 #, c-format
 msgid "Can not do reflog for '%s': %s\n"
 msgstr "No se puede hacer reflog para '%s': %s\n"
 
-#: builtin/checkout.c:677
+#: builtin/checkout.c:684
 msgid "HEAD is now at"
 msgstr "HEAD está ahora en"
 
-#: builtin/checkout.c:681 builtin/clone.c:689
+#: builtin/checkout.c:688 builtin/clone.c:691
 msgid "unable to update HEAD"
 msgstr "no es posible actualizar  HEAD"
 
-#: builtin/checkout.c:685
+#: builtin/checkout.c:692
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Reiniciar rama '%s'\n"
 
-#: builtin/checkout.c:688
+#: builtin/checkout.c:695
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Ya en '%s'\n"
 
-#: builtin/checkout.c:692
+#: builtin/checkout.c:699
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Rama reiniciada y cambiada a '%s'\n"
 
-#: builtin/checkout.c:694 builtin/checkout.c:1039
+#: builtin/checkout.c:701 builtin/checkout.c:1046
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Cambiado a nueva rama '%s'\n"
 
-#: builtin/checkout.c:696
+#: builtin/checkout.c:703
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Cambiado a rama '%s'\n"
 
-#: builtin/checkout.c:747
+#: builtin/checkout.c:754
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... y %d más.\n"
 
-#: builtin/checkout.c:753
+#: builtin/checkout.c:760
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -6604,7 +6994,7 @@ msgstr[1] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:772
+#: builtin/checkout.c:779
 #, c-format
 msgid ""
 "If you want to keep it by creating a new branch, this may be a good time\n"
@@ -6631,160 +7021,160 @@ msgstr[1] ""
 " git branch <nombre-de-rama> %s\n"
 "\n"
 
-#: builtin/checkout.c:804
+#: builtin/checkout.c:811
 msgid "internal error in revision walk"
 msgstr "error interno en camino de revisión"
 
-#: builtin/checkout.c:808
+#: builtin/checkout.c:815
 msgid "Previous HEAD position was"
 msgstr "La posición previa de HEAD era"
 
-#: builtin/checkout.c:836 builtin/checkout.c:1034
+#: builtin/checkout.c:843 builtin/checkout.c:1041
 msgid "You are on a branch yet to be born"
 msgstr "Estás en una rama por nacer"
 
-#: builtin/checkout.c:940
+#: builtin/checkout.c:947
 #, c-format
 msgid "only one reference expected, %d given."
 msgstr "solo una referencia esperada, %d entregadas."
 
-#: builtin/checkout.c:980 builtin/worktree.c:249
+#: builtin/checkout.c:987 builtin/worktree.c:240 builtin/worktree.c:389
 #, c-format
 msgid "invalid reference: %s"
 msgstr "referencia invalida: %s"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1016
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "la referencia no es n árbol: %s"
 
-#: builtin/checkout.c:1048
+#: builtin/checkout.c:1055
 msgid "paths cannot be used with switching branches"
 msgstr "rutas no pueden ser usadas con cambios de rama"
 
-#: builtin/checkout.c:1051 builtin/checkout.c:1055
+#: builtin/checkout.c:1058 builtin/checkout.c:1062
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "'%s' no puede ser usado con cambios de ramas"
 
-#: builtin/checkout.c:1059 builtin/checkout.c:1062 builtin/checkout.c:1067
-#: builtin/checkout.c:1070
+#: builtin/checkout.c:1066 builtin/checkout.c:1069 builtin/checkout.c:1074
+#: builtin/checkout.c:1077
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "'%s' no puede ser usado con '%s'"
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1082
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "No se puede cambiar rama a un '%s' sin commits"
 
-#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116
-#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:387
-#: builtin/worktree.c:389
+#: builtin/checkout.c:1114 builtin/checkout.c:1116 builtin/clone.c:118
+#: builtin/remote.c:167 builtin/remote.c:169 builtin/worktree.c:433
+#: builtin/worktree.c:435
 msgid "branch"
 msgstr "rama"
 
-#: builtin/checkout.c:1108
+#: builtin/checkout.c:1115
 msgid "create and checkout a new branch"
 msgstr "crear y hacer checkout a una nueva rama"
 
-#: builtin/checkout.c:1110
+#: builtin/checkout.c:1117
 msgid "create/reset and checkout a branch"
 msgstr "crear/reiniciar y hacer checkout a una rama"
 
-#: builtin/checkout.c:1111
+#: builtin/checkout.c:1118
 msgid "create reflog for new branch"
 msgstr "crear un reflog para una nueva rama"
 
-#: builtin/checkout.c:1112 builtin/worktree.c:391
+#: builtin/checkout.c:1119 builtin/worktree.c:437
 msgid "detach HEAD at named commit"
 msgstr "desacoplar HEAD en el commit nombrado"
 
-#: builtin/checkout.c:1113
+#: builtin/checkout.c:1120
 msgid "set upstream info for new branch"
 msgstr "configurar info de upstream para una rama nueva"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new-branch"
 msgstr "nueva-rama"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new unparented branch"
 msgstr "nueva rama no emparentada"
 
-#: builtin/checkout.c:1116
+#: builtin/checkout.c:1123
 msgid "checkout our version for unmerged files"
 msgstr "hacer checkout a  nuestra versión para archivos sin fusionar"
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1125
 msgid "checkout their version for unmerged files"
 msgstr "hacer checkout a su versión para los archivos sin fusionar"
 
-#: builtin/checkout.c:1120
+#: builtin/checkout.c:1127
 msgid "force checkout (throw away local modifications)"
 msgstr "forzar el checkout (descartar modificaciones locales)"
 
-#: builtin/checkout.c:1122
+#: builtin/checkout.c:1129
 msgid "perform a 3-way merge with the new branch"
 msgstr "realizar una fusión de tres vías con la rama nueva"
 
-#: builtin/checkout.c:1124 builtin/merge.c:239
+#: builtin/checkout.c:1131 builtin/merge.c:241
 msgid "update ignored files (default)"
 msgstr "actualizar archivos ignorados (default)"
 
-#: builtin/checkout.c:1126 builtin/log.c:1499 parse-options.h:263
+#: builtin/checkout.c:1133 builtin/log.c:1499 parse-options.h:264
 msgid "style"
 msgstr "estilo"
 
-#: builtin/checkout.c:1127
+#: builtin/checkout.c:1134
 msgid "conflict style (merge or diff3)"
 msgstr "conflicto de estilos (merge o diff3)"
 
-#: builtin/checkout.c:1130
+#: builtin/checkout.c:1137
 msgid "do not limit pathspecs to sparse entries only"
 msgstr "no limitar pathspecs a dispersar entradas solamente"
 
-#: builtin/checkout.c:1132
+#: builtin/checkout.c:1139
 msgid "second guess 'git checkout <no-such-branch>'"
 msgstr "segunda opción 'git checkout <no-hay-tal-rama>'"
 
-#: builtin/checkout.c:1134
+#: builtin/checkout.c:1141
 msgid "do not check if another worktree is holding the given ref"
 msgstr "no revise si otro árbol de trabajo contiene la ref entregada"
 
-#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150
-#: builtin/merge.c:236 builtin/pull.c:123 builtin/push.c:556
-#: builtin/send-pack.c:173
+#: builtin/checkout.c:1145 builtin/clone.c:85 builtin/fetch.c:149
+#: builtin/merge.c:238 builtin/pull.c:128 builtin/push.c:572
+#: builtin/send-pack.c:174
 msgid "force progress reporting"
 msgstr "forzar el reporte de progreso"
 
-#: builtin/checkout.c:1168
+#: builtin/checkout.c:1175
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "-b, -B y --orphan son mutuamente exclusivas"
 
-#: builtin/checkout.c:1185
+#: builtin/checkout.c:1192
 msgid "--track needs a branch name"
 msgstr "--track necesita el nombre de una rama"
 
-#: builtin/checkout.c:1190
+#: builtin/checkout.c:1197
 msgid "Missing branch name; try -b"
 msgstr "Falta nombre de rama; prueba -b"
 
-#: builtin/checkout.c:1226
+#: builtin/checkout.c:1233
 msgid "invalid path specification"
 msgstr "especificación de ruta invalida"
 
-#: builtin/checkout.c:1233
+#: builtin/checkout.c:1240
 #, c-format
 msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
 msgstr "'%s' no es un commit y una rama '%s' no puede ser creada desde este"
 
-#: builtin/checkout.c:1237
+#: builtin/checkout.c:1244
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout: --detach no toma un argumento de ruta '%s'"
 
-#: builtin/checkout.c:1241
+#: builtin/checkout.c:1248
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -6821,9 +7211,9 @@ msgstr "Se saltara repositorio %s\n"
 #: builtin/clean.c:34
 #, c-format
 msgid "failed to remove %s"
-msgstr "fallo al borrar %s"
+msgstr "falló al borrar %s"
 
-#: builtin/clean.c:302 git-add--interactive.perl:572
+#: builtin/clean.c:302 git-add--interactive.perl:579
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6836,7 +7226,7 @@ msgstr ""
 "foo        - selecciona un objeto basado en un prefijo único\n"
 "           - (vacío) no elegir nada\n"
 
-#: builtin/clean.c:306 git-add--interactive.perl:581
+#: builtin/clean.c:306 git-add--interactive.perl:588
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6857,8 +7247,8 @@ msgstr ""
 "*          - escoger todos los objetos\n"
 "           - (vacío) terminar selección\n"
 
-#: builtin/clean.c:522 git-add--interactive.perl:547
-#: git-add--interactive.perl:552
+#: builtin/clean.c:522 git-add--interactive.perl:554
+#: git-add--interactive.perl:559
 #, c-format, perl-format
 msgid "Huh (%s)?\n"
 msgstr "Ahh (%s)?\n"
@@ -6883,7 +7273,7 @@ msgstr "Seleccionar objetos para borrar"
 msgid "Remove %s [y/N]? "
 msgstr "Borrar %s [y/N]? "
 
-#: builtin/clean.c:788 git-add--interactive.perl:1710
+#: builtin/clean.c:788 git-add--interactive.perl:1717
 #, c-format
 msgid "Bye.\n"
 msgstr "Adiós.\n"
@@ -6906,11 +7296,11 @@ msgstr ""
 "help                - esta ventana\n"
 "?                   - ayuda para selección de opciones"
 
-#: builtin/clean.c:823 git-add--interactive.perl:1786
+#: builtin/clean.c:823 git-add--interactive.perl:1793
 msgid "*** Commands ***"
 msgstr "*** Comandos ***"
 
-#: builtin/clean.c:824 git-add--interactive.perl:1783
+#: builtin/clean.c:824 git-add--interactive.perl:1790
 msgid "What now"
 msgstr "Ahora que"
 
@@ -6979,144 +7369,146 @@ msgstr ""
 "clean.requireForce default en true y ninguno -i, -n, ni -f entregados; "
 "rehusando el clean"
 
-#: builtin/clone.c:40
+#: builtin/clone.c:42
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<opciones>] [--] <repo> [<directorio>]"
 
-#: builtin/clone.c:85
+#: builtin/clone.c:87
 msgid "don't create a checkout"
 msgstr "no crear checkout"
 
-#: builtin/clone.c:86 builtin/clone.c:88 builtin/init-db.c:479
+#: builtin/clone.c:88 builtin/clone.c:90 builtin/init-db.c:479
 msgid "create a bare repository"
 msgstr "crear un repositorio vacío"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:92
 msgid "create a mirror repository (implies bare)"
 msgstr "crear un repositorio espejo (implica vacío)"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:94
 msgid "to clone from a local repository"
 msgstr "clonar de un repositorio local"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:96
 msgid "don't use local hardlinks, always copy"
 msgstr "no usar hardlinks, siempre copiar"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:98
 msgid "setup as shared repository"
 msgstr "configurar como repositorio compartido"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "pathspec"
 msgstr "pathspec"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "initialize submodules in the clone"
 msgstr "inicializar submódulos en el clonado"
 
-#: builtin/clone.c:105
+#: builtin/clone.c:107
 msgid "number of submodules cloned in parallel"
 msgstr "numero de submódulos clonados en paralelo"
 
-#: builtin/clone.c:106 builtin/init-db.c:476
+#: builtin/clone.c:108 builtin/init-db.c:476
 msgid "template-directory"
 msgstr "directorio-template"
 
-#: builtin/clone.c:107 builtin/init-db.c:477
+#: builtin/clone.c:109 builtin/init-db.c:477
 msgid "directory from which templates will be used"
 msgstr "directorio del cual los templates serán usados"
 
-#: builtin/clone.c:109 builtin/clone.c:111 builtin/submodule--helper.c:1210
-#: builtin/submodule--helper.c:1577
+#: builtin/clone.c:111 builtin/clone.c:113 builtin/submodule--helper.c:1223
+#: builtin/submodule--helper.c:1594
 msgid "reference repository"
 msgstr "repositorio de referencia"
 
-#: builtin/clone.c:113
+#: builtin/clone.c:115 builtin/submodule--helper.c:1225
+#: builtin/submodule--helper.c:1596
 msgid "use --reference only while cloning"
 msgstr "usa--reference  solamente si estas clonado"
 
-#: builtin/clone.c:114 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/clone.c:116 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/pack-objects.c:3166 builtin/repack.c:213
 msgid "name"
 msgstr "nombre"
 
-#: builtin/clone.c:115
+#: builtin/clone.c:117
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "use <nombre> en lugar de 'origin' para rastrear upstream"
 
-#: builtin/clone.c:117
+#: builtin/clone.c:119
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "checkout <rama> en lugar de HEAD remota"
 
-#: builtin/clone.c:119
+#: builtin/clone.c:121
 msgid "path to git-upload-pack on the remote"
 msgstr "ruta para git-upload-pack en el remoto"
 
-#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813
-#: builtin/pull.c:211
+#: builtin/clone.c:122 builtin/fetch.c:150 builtin/grep.c:813
+#: builtin/pull.c:216
 msgid "depth"
 msgstr "profundidad"
 
-#: builtin/clone.c:121
+#: builtin/clone.c:123
 msgid "create a shallow clone of that depth"
 msgstr "crear un clon superficial para esa profundidad"
 
-#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017
+#: builtin/clone.c:124 builtin/fetch.c:152 builtin/pack-objects.c:3157
 #: parse-options.h:154
 msgid "time"
 msgstr "tiempo"
 
-#: builtin/clone.c:123
+#: builtin/clone.c:125
 msgid "create a shallow clone since a specific time"
 msgstr "crear un clon superficial desde el tiempo específico"
 
-#: builtin/clone.c:124 builtin/fetch.c:155
+#: builtin/clone.c:126 builtin/fetch.c:154
 msgid "revision"
 msgstr "revision"
 
-#: builtin/clone.c:125 builtin/fetch.c:156
+#: builtin/clone.c:127 builtin/fetch.c:155
 msgid "deepen history of shallow clone, excluding rev"
 msgstr "ahondando historia de clon superficial, excluyendo rev"
 
-#: builtin/clone.c:127
+#: builtin/clone.c:129
 msgid "clone only one branch, HEAD or --branch"
 msgstr "clonar solo una rama,HEAD o --branch"
 
-#: builtin/clone.c:129
+#: builtin/clone.c:131
 msgid "don't clone any tags, and make later fetches not to follow them"
 msgstr "no clonar ningún tag, y hacer que los subsiguientes fetch no los sigan"
 
-#: builtin/clone.c:131
+#: builtin/clone.c:133
 msgid "any cloned submodules will be shallow"
 msgstr "cualquier submódulo clonado será superficial"
 
-#: builtin/clone.c:132 builtin/init-db.c:485
+#: builtin/clone.c:134 builtin/init-db.c:485
 msgid "gitdir"
 msgstr "gitdir"
 
-#: builtin/clone.c:133 builtin/init-db.c:486
+#: builtin/clone.c:135 builtin/init-db.c:486
 msgid "separate git dir from working tree"
 msgstr "separa git dir del árbol de trabajo"
 
-#: builtin/clone.c:134
+#: builtin/clone.c:136
 msgid "key=value"
 msgstr "llave=valor"
 
-#: builtin/clone.c:135
+#: builtin/clone.c:137
 msgid "set config inside the new repository"
 msgstr "configurar config dentro del nuevo repositorio"
 
-#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224
-#: builtin/push.c:567
+#: builtin/clone.c:138 builtin/fetch.c:173 builtin/pull.c:229
+#: builtin/push.c:583
 msgid "use IPv4 addresses only"
 msgstr "solo usar direcciones IPv4"
 
-#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227
-#: builtin/push.c:569
+#: builtin/clone.c:140 builtin/fetch.c:175 builtin/pull.c:232
+#: builtin/push.c:585
 msgid "use IPv6 addresses only"
 msgstr "solo usar direcciones IPv6"
 
-#: builtin/clone.c:276
+#: builtin/clone.c:278
 msgid ""
 "No directory name could be guessed.\n"
 "Please specify a directory on the command line"
@@ -7124,42 +7516,42 @@ msgstr ""
 "No se pudo adivinar ningún nombre de directorio.\n"
 "Por favor especifique un directorio en la línea de comando"
 
-#: builtin/clone.c:329
+#: builtin/clone.c:331
 #, c-format
 msgid "info: Could not add alternate for '%s': %s\n"
 msgstr "info: No se pudo agregar un alterno para '%s': %s\n"
 
-#: builtin/clone.c:401
+#: builtin/clone.c:403
 #, c-format
 msgid "failed to open '%s'"
-msgstr "fallo al abrir '%s'"
+msgstr "falló al abrir '%s'"
 
-#: builtin/clone.c:409
+#: builtin/clone.c:411
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "%s existe pero no es un directorio"
 
-#: builtin/clone.c:423
+#: builtin/clone.c:425
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "falló al analizar %s\n"
 
-#: builtin/clone.c:445
+#: builtin/clone.c:447
 #, c-format
 msgid "failed to create link '%s'"
-msgstr "fallo al crear link '%s'"
+msgstr "falló al crear link '%s'"
 
-#: builtin/clone.c:449
+#: builtin/clone.c:451
 #, c-format
 msgid "failed to copy file to '%s'"
-msgstr "fallo al copiar archivo a '%s'"
+msgstr "falló al copiar archivo a '%s'"
 
-#: builtin/clone.c:475
+#: builtin/clone.c:477
 #, c-format
 msgid "done.\n"
 msgstr "hecho.\n"
 
-#: builtin/clone.c:489
+#: builtin/clone.c:491
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -7169,100 +7561,100 @@ msgstr ""
 "Puede inspeccionar a qué se hizo checkout con 'git status'\n"
 "y volver a intentarlo con 'git checkout -f HEAD'\n"
 
-#: builtin/clone.c:566
+#: builtin/clone.c:568
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "No se pudo encontrar la rama remota %s para clonar."
 
-#: builtin/clone.c:661
+#: builtin/clone.c:663
 msgid "remote did not send all necessary objects"
 msgstr "remoto no mando todos los objetos necesarios"
 
-#: builtin/clone.c:677
+#: builtin/clone.c:679
 #, c-format
 msgid "unable to update %s"
 msgstr "incapaz de actualizar %s"
 
-#: builtin/clone.c:726
+#: builtin/clone.c:728
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
 "remoto HEAD refiere a un ref inexistente, no se puede hacer checkout.\n"
 
-#: builtin/clone.c:756
+#: builtin/clone.c:758
 msgid "unable to checkout working tree"
 msgstr "no es posible realizar checkout en el árbol de trabajo"
 
-#: builtin/clone.c:801
+#: builtin/clone.c:803
 msgid "unable to write parameters to config file"
 msgstr "no es posible escribir parámetros al archivo config"
 
-#: builtin/clone.c:864
+#: builtin/clone.c:866
 msgid "cannot repack to clean up"
 msgstr "no se puede reempaquetar para limpiar"
 
-#: builtin/clone.c:866
+#: builtin/clone.c:868
 msgid "cannot unlink temporary alternates file"
 msgstr "no se puede desvincular archivos alternos temporales"
 
-#: builtin/clone.c:906 builtin/receive-pack.c:1946
+#: builtin/clone.c:907 builtin/receive-pack.c:1947
 msgid "Too many arguments."
 msgstr "Muchos argumentos."
 
-#: builtin/clone.c:910
+#: builtin/clone.c:911
 msgid "You must specify a repository to clone."
 msgstr "Tienes que especificar un repositorio para clonar."
 
-#: builtin/clone.c:923
+#: builtin/clone.c:924
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "Las opciones --bare y --origin %s son incompatibles."
 
-#: builtin/clone.c:926
+#: builtin/clone.c:927
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "--bare y --separate-git-dir son incompatibles."
 
-#: builtin/clone.c:939
+#: builtin/clone.c:940
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "repositorio '%s' no existe"
 
-#: builtin/clone.c:945 builtin/fetch.c:1455
+#: builtin/clone.c:946 builtin/fetch.c:1460
 #, c-format
 msgid "depth %s is not a positive number"
 msgstr "profundidad %s no es un numero positivo"
 
-#: builtin/clone.c:955
+#: builtin/clone.c:956
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr "la ruta de destino '%s' ya existe y no es un directorio vacío."
 
-#: builtin/clone.c:965
+#: builtin/clone.c:966
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "directorio de trabajo '%s' ya existe."
 
-#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270
-#: builtin/worktree.c:255 builtin/worktree.c:285
+#: builtin/clone.c:981 builtin/clone.c:1002 builtin/difftool.c:270
+#: builtin/worktree.c:246 builtin/worktree.c:276
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "no se pudo crear directorios principales de '%s'"
 
-#: builtin/clone.c:985
+#: builtin/clone.c:986
 #, c-format
 msgid "could not create work tree dir '%s'"
 msgstr "no se pudo crear un árbol de trabajo '%s'"
 
-#: builtin/clone.c:1005
+#: builtin/clone.c:1006
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Clonando en un repositorio vacío '%s'...\n"
 
-#: builtin/clone.c:1007
+#: builtin/clone.c:1008
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Clonando en '%s'...\n"
 
-#: builtin/clone.c:1031
+#: builtin/clone.c:1032
 msgid ""
 "clone --recursive is not compatible with both --reference and --reference-if-"
 "able"
@@ -7331,7 +7723,7 @@ msgstr "Realizando padding en el borde derecho"
 msgid "Padding space between columns"
 msgstr "Realizando padding entre columnas"
 
-#: builtin/column.c:52
+#: builtin/column.c:51
 msgid "--command must be the first argument"
 msgstr "--command debe ser el primer argumento"
 
@@ -7388,61 +7780,61 @@ msgstr ""
 "Luego \"git cherry-pick --continue\" continuara el cherry-picking\n"
 "para los commits restantes.\n"
 
-#: builtin/commit.c:284
+#: builtin/commit.c:293
 msgid "failed to unpack HEAD tree object"
-msgstr "fallo al desempaquetar objeto del árbol HEAD"
+msgstr "falló al desempaquetar objeto del árbol HEAD"
 
-#: builtin/commit.c:325
+#: builtin/commit.c:334
 msgid "unable to create temporary index"
 msgstr "no es posible crear un índice temporal"
 
-#: builtin/commit.c:331
+#: builtin/commit.c:340
 msgid "interactive add failed"
 msgstr "adición interactiva fallida"
 
-#: builtin/commit.c:344
+#: builtin/commit.c:353
 msgid "unable to update temporary index"
 msgstr "no es posible actualizar el índice temporal"
 
-#: builtin/commit.c:346
+#: builtin/commit.c:355
 msgid "Failed to update main cache tree"
-msgstr "Fallo al actualizar el cache principal del árbol"
+msgstr "Falló al actualizar el cache principal del árbol"
 
-#: builtin/commit.c:371 builtin/commit.c:395 builtin/commit.c:444
+#: builtin/commit.c:380 builtin/commit.c:403 builtin/commit.c:449
 msgid "unable to write new_index file"
 msgstr "no es posible escribir archivo new_index"
 
-#: builtin/commit.c:427
+#: builtin/commit.c:432
 msgid "cannot do a partial commit during a merge."
 msgstr "no se puede realizar un commit parcial durante una fusión."
 
-#: builtin/commit.c:429
+#: builtin/commit.c:434
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "no se puede realizar un commit parcial durante un cherry-pick."
 
-#: builtin/commit.c:437
+#: builtin/commit.c:442
 msgid "cannot read the index"
 msgstr "no se puede leer el índice"
 
-#: builtin/commit.c:456
+#: builtin/commit.c:461
 msgid "unable to write temporary index file"
 msgstr "no es posible escribir el índice temporal"
 
-#: builtin/commit.c:553
+#: builtin/commit.c:558
 #, c-format
 msgid "commit '%s' lacks author header"
 msgstr "commit '%s' requiere cabecera de autor"
 
-#: builtin/commit.c:555
+#: builtin/commit.c:560
 #, c-format
 msgid "commit '%s' has malformed author line"
 msgstr "el commit '%s' tiene una línea de autor mal formada"
 
-#: builtin/commit.c:574
+#: builtin/commit.c:579
 msgid "malformed --author parameter"
 msgstr "parámetro --author mal formado"
 
-#: builtin/commit.c:626
+#: builtin/commit.c:631
 msgid ""
 "unable to select a comment character that is not used\n"
 "in the current commit message"
@@ -7450,38 +7842,38 @@ msgstr ""
 "no es posible seleccionar un carácter de comentario que no es usado\n"
 "en el mensaje de commit actual"
 
-#: builtin/commit.c:663 builtin/commit.c:696 builtin/commit.c:1024
+#: builtin/commit.c:668 builtin/commit.c:701 builtin/commit.c:1029
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "no se pudo revisar el commit %s"
 
-#: builtin/commit.c:675 builtin/shortlog.c:309
+#: builtin/commit.c:680 builtin/shortlog.c:316
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(leyendo mensajes de logs desde standard input)\n"
 
-#: builtin/commit.c:677
+#: builtin/commit.c:682
 msgid "could not read log from standard input"
 msgstr "no se pudo leer log desde standard input"
 
-#: builtin/commit.c:681
+#: builtin/commit.c:686
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "no se pudo leer el log '%s'"
 
-#: builtin/commit.c:710 builtin/commit.c:718
+#: builtin/commit.c:715 builtin/commit.c:723
 msgid "could not read SQUASH_MSG"
 msgstr "no se pudo leer SQUASH_MSG"
 
-#: builtin/commit.c:715
+#: builtin/commit.c:720
 msgid "could not read MERGE_MSG"
 msgstr "no se pudo leer MERGE_MSG"
 
-#: builtin/commit.c:769
+#: builtin/commit.c:774
 msgid "could not write commit template"
 msgstr "no se pudo escribir el template del commit"
 
-#: builtin/commit.c:787
+#: builtin/commit.c:792
 #, c-format
 msgid ""
 "\n"
@@ -7496,7 +7888,7 @@ msgstr ""
 "\t%s\n"
 "y vuelve a intentar.\n"
 
-#: builtin/commit.c:792
+#: builtin/commit.c:797
 #, c-format
 msgid ""
 "\n"
@@ -7511,7 +7903,7 @@ msgstr ""
 "\t%s\n"
 "y vuelva a intentar.\n"
 
-#: builtin/commit.c:805
+#: builtin/commit.c:810
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7521,7 +7913,7 @@ msgstr ""
 "comiencen\n"
 "con '%c' serán ignoradas, y un mensaje vacío aborta el commit.\n"
 
-#: builtin/commit.c:813
+#: builtin/commit.c:818
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7533,150 +7925,150 @@ msgstr ""
 "con '%c' serán guardadas; puede removerlas usted mismo si desea.\n"
 "Un mensaje vacío aborta el commit.\n"
 
-#: builtin/commit.c:830
+#: builtin/commit.c:835
 #, c-format
 msgid "%sAuthor:    %.*s <%.*s>"
 msgstr "%sAutor:     %.*s <%.*s>"
 
-#: builtin/commit.c:838
+#: builtin/commit.c:843
 #, c-format
 msgid "%sDate:      %s"
 msgstr "%sFecha:     %s"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:850
 #, c-format
 msgid "%sCommitter: %.*s <%.*s>"
 msgstr "%sCommitter: %.*s <%.*s>"
 
-#: builtin/commit.c:862
+#: builtin/commit.c:867
 msgid "Cannot read index"
 msgstr "No se puede leer el índice"
 
-#: builtin/commit.c:928
+#: builtin/commit.c:933
 msgid "Error building trees"
 msgstr "Error al construir los árboles"
 
-#: builtin/commit.c:942 builtin/tag.c:256
+#: builtin/commit.c:947 builtin/tag.c:257
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "Por favor suministra el mensaje usando las opciones -m o -F.\n"
 
-#: builtin/commit.c:986
+#: builtin/commit.c:991
 #, c-format
 msgid "--author '%s' is not 'Name <email>' and matches no existing author"
 msgstr ""
 "--author '%s' no está en el formato 'Name <email>' y no concuerda con ningún "
 "autor existente"
 
-#: builtin/commit.c:1000
+#: builtin/commit.c:1005
 #, c-format
 msgid "Invalid ignored mode '%s'"
 msgstr "Modo ignorado inválido '%s'"
 
-#: builtin/commit.c:1014 builtin/commit.c:1264
+#: builtin/commit.c:1019 builtin/commit.c:1269
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "Modo inválido de los archivos no rastreados '%s'"
 
-#: builtin/commit.c:1052
+#: builtin/commit.c:1057
 msgid "--long and -z are incompatible"
 msgstr "--long y -z son incompatibles"
 
-#: builtin/commit.c:1085
+#: builtin/commit.c:1090
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "Usar ambos --reset-author y --author no tiene sentido"
 
-#: builtin/commit.c:1094
+#: builtin/commit.c:1099
 msgid "You have nothing to amend."
 msgstr "No tienes nada que enmendar."
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1102
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "Estás en medio de una fusión -- no puedes enmendar."
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1104
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "Está en medio de un cherry-pick -- no se puede enmendar."
 
-#: builtin/commit.c:1102
+#: builtin/commit.c:1107
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "Opciones --squash y --fixup no pueden ser usadas juntas"
 
-#: builtin/commit.c:1112
+#: builtin/commit.c:1117
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "Solo uno de -c/-C/-F/--fixup puede ser usado."
 
-#: builtin/commit.c:1114
+#: builtin/commit.c:1119
 msgid "Option -m cannot be combined with -c/-C/-F."
 msgstr "La opción -m no puede ser combinada con -c/-C/-F."
 
-#: builtin/commit.c:1122
+#: builtin/commit.c:1127
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr "--reset-author sólo puede ser usada con -C, -c o --amend."
 
-#: builtin/commit.c:1139
+#: builtin/commit.c:1144
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 "Solo uno de --include/--only/--all/--interactive/--patch puede ser usado."
 
-#: builtin/commit.c:1141
+#: builtin/commit.c:1146
 msgid "No paths with --include/--only does not make sense."
 msgstr "No hay rutas con --include/--only no tiene sentido."
 
-#: builtin/commit.c:1155 builtin/tag.c:542
+#: builtin/commit.c:1160 builtin/tag.c:543
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Modo cleanup invalido %s"
 
-#: builtin/commit.c:1160
+#: builtin/commit.c:1165
 msgid "Paths with -a does not make sense."
 msgstr "Rutas con -a no tiene sentido."
 
-#: builtin/commit.c:1278 builtin/commit.c:1443
+#: builtin/commit.c:1303 builtin/commit.c:1480
 msgid "show status concisely"
 msgstr "mostrar status de manera concisa"
 
-#: builtin/commit.c:1280 builtin/commit.c:1445
+#: builtin/commit.c:1305 builtin/commit.c:1482
 msgid "show branch information"
 msgstr "mostrar información de la rama"
 
-#: builtin/commit.c:1282
+#: builtin/commit.c:1307
 msgid "show stash information"
 msgstr "mostrar información del stash"
 
-#: builtin/commit.c:1284 builtin/commit.c:1447
+#: builtin/commit.c:1309 builtin/commit.c:1484
 msgid "compute full ahead/behind values"
 msgstr "calcular todos los valores delante/atrás"
 
-#: builtin/commit.c:1286
+#: builtin/commit.c:1311
 msgid "version"
 msgstr "version"
 
-#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542
-#: builtin/worktree.c:541
+#: builtin/commit.c:1311 builtin/commit.c:1486 builtin/push.c:558
+#: builtin/worktree.c:581
 msgid "machine-readable output"
 msgstr "output formato-maquina"
 
-#: builtin/commit.c:1289 builtin/commit.c:1451
+#: builtin/commit.c:1314 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "mostrar status en formato largo (default)"
 
-#: builtin/commit.c:1292 builtin/commit.c:1454
+#: builtin/commit.c:1317 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "terminar entradas con NUL"
 
-#: builtin/commit.c:1294 builtin/commit.c:1298 builtin/commit.c:1457
-#: builtin/fast-export.c:999 builtin/fast-export.c:1002 builtin/tag.c:396
+#: builtin/commit.c:1319 builtin/commit.c:1323 builtin/commit.c:1494
+#: builtin/fast-export.c:1001 builtin/fast-export.c:1004 builtin/tag.c:397
 msgid "mode"
 msgstr "modo"
 
-#: builtin/commit.c:1295 builtin/commit.c:1457
+#: builtin/commit.c:1320 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
 "mostrar archivos sin seguimiento, modos opcionales: all, normal, no. "
 "(Predeterminado: all)"
 
-#: builtin/commit.c:1299
+#: builtin/commit.c:1324
 msgid ""
 "show ignored files, optional modes: traditional, matching, no. (Default: "
 "traditional)"
@@ -7684,11 +8076,11 @@ msgstr ""
 "mostrar archivos ignorados, modos opcionales: traditional, matching, no. "
 "(Predeterminado: traditional)"
 
-#: builtin/commit.c:1301 parse-options.h:167
+#: builtin/commit.c:1326 parse-options.h:167
 msgid "when"
 msgstr "cuando"
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1327
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
@@ -7696,187 +8088,195 @@ msgstr ""
 "ignorar cambios en submódulos, opcional cuando: all,dirty,untracked. "
 "(Default: all)"
 
-#: builtin/commit.c:1304
+#: builtin/commit.c:1329
 msgid "list untracked files in columns"
 msgstr "listar en columnas los archivos sin seguimiento"
 
-#: builtin/commit.c:1323
+#: builtin/commit.c:1330
+msgid "do not detect renames"
+msgstr "no detectar renombrados"
+
+#: builtin/commit.c:1332
+msgid "detect renames, optionally set similarity index"
+msgstr "detectar renombres, opcionalmente configurar similaridad de índice"
+
+#: builtin/commit.c:1352
 msgid "Unsupported combination of ignored and untracked-files arguments"
 msgstr ""
 "Combinación de argumentos de archivos ignorados y no rastreados no soportada"
 
-#: builtin/commit.c:1413
+#: builtin/commit.c:1450
 msgid "suppress summary after successful commit"
 msgstr "suprime summary tras un commit exitoso"
 
-#: builtin/commit.c:1414
+#: builtin/commit.c:1451
 msgid "show diff in commit message template"
 msgstr "mostrar diff en el template del mensaje de commit"
 
-#: builtin/commit.c:1416
+#: builtin/commit.c:1453
 msgid "Commit message options"
 msgstr "Opciones para el mensaje del commit"
 
-#: builtin/commit.c:1417 builtin/tag.c:393
+#: builtin/commit.c:1454 builtin/tag.c:394
 msgid "read message from file"
 msgstr "leer mensaje desde un archivo"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "author"
 msgstr "autor"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "override author for commit"
 msgstr "sobrescribe el autor del commit"
 
-#: builtin/commit.c:1419 builtin/gc.c:359
+#: builtin/commit.c:1456 builtin/gc.c:501
 msgid "date"
 msgstr "fecha"
 
-#: builtin/commit.c:1419
+#: builtin/commit.c:1456
 msgid "override date for commit"
 msgstr "sobrescribe la fecha del commit"
 
-#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402
-#: builtin/notes.c:565 builtin/tag.c:391
+#: builtin/commit.c:1457 builtin/merge.c:228 builtin/notes.c:402
+#: builtin/notes.c:565 builtin/tag.c:392
 msgid "message"
 msgstr "mensaje"
 
-#: builtin/commit.c:1420
+#: builtin/commit.c:1457
 msgid "commit message"
 msgstr "mensaje del commit"
 
-#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423
-#: builtin/commit.c:1424 parse-options.h:269 ref-filter.h:92
+#: builtin/commit.c:1458 builtin/commit.c:1459 builtin/commit.c:1460
+#: builtin/commit.c:1461 parse-options.h:270 ref-filter.h:92
 msgid "commit"
 msgstr "confirmar"
 
-#: builtin/commit.c:1421
+#: builtin/commit.c:1458
 msgid "reuse and edit message from specified commit"
 msgstr "reusar y editar el mensaje de un commit especifico"
 
-#: builtin/commit.c:1422
+#: builtin/commit.c:1459
 msgid "reuse message from specified commit"
 msgstr "reusar el mensaje de un commit especifico"
 
-#: builtin/commit.c:1423
+#: builtin/commit.c:1460
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
 "usar mensaje de formato autosquash para arreglar el commit especificado"
 
-#: builtin/commit.c:1424
+#: builtin/commit.c:1461
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
 "usar el mensaje de formato autosquash para realizar squash  al commit "
 "especificado"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1462
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr "el autor del commit soy yo ahora (usado con -C/-c/--amend)"
 
-#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240
-#: builtin/pull.c:149 builtin/revert.c:105
+#: builtin/commit.c:1463 builtin/log.c:1446 builtin/merge.c:242
+#: builtin/pull.c:154 builtin/revert.c:105
 msgid "add Signed-off-by:"
 msgstr "agregar Signed-off-by: (firmado por)"
 
-#: builtin/commit.c:1427
+#: builtin/commit.c:1464
 msgid "use specified template file"
 msgstr "usar archivo de template especificado"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1465
 msgid "force edit of commit"
 msgstr "forzar la edición del commit"
 
-#: builtin/commit.c:1429
+#: builtin/commit.c:1466
 msgid "default"
 msgstr "default"
 
-#: builtin/commit.c:1429 builtin/tag.c:397
+#: builtin/commit.c:1466 builtin/tag.c:398
 msgid "how to strip spaces and #comments from message"
 msgstr "cómo quitar espacios y #comentarios de mensajes"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1467
 msgid "include status in commit message template"
 msgstr "incluir status en el template del mensaje de commit"
 
-#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179
+#: builtin/commit.c:1469 builtin/merge.c:240 builtin/pull.c:184
 #: builtin/revert.c:113
 msgid "GPG sign commit"
 msgstr "Firmar commit con GPG"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1472
 msgid "Commit contents options"
 msgstr "Opciones para el contenido del commit"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1473
 msgid "commit all changed files"
 msgstr "confirmar todos los archivos cambiados"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1474
 msgid "add specified files to index for commit"
 msgstr "agregar archivos específicos al índice para confirmar"
 
-#: builtin/commit.c:1438
+#: builtin/commit.c:1475
 msgid "interactively add files"
 msgstr "agregar archivos interactivamente"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1476
 msgid "interactively add changes"
 msgstr "agregar cambios interactivamente"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1477
 msgid "commit only specified files"
 msgstr "sólo confirmar archivos específicos"
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1478
 msgid "bypass pre-commit and commit-msg hooks"
 msgstr "evitar los capturadores (hooks) de pre-commit y commit-msg"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1479
 msgid "show what would be committed"
 msgstr "mostrar lo que sería incluido en el commit"
 
-#: builtin/commit.c:1455
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "enmendar commit previo"
 
-#: builtin/commit.c:1456
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "gancho bypass post reescritura"
 
-#: builtin/commit.c:1461
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "ok al grabar un cambio vacío"
 
-#: builtin/commit.c:1463
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "ok al grabar un cambio con un mensaje vacío"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1573
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Archivo MERGE_HEAD (%s) corrupto"
 
-#: builtin/commit.c:1543
+#: builtin/commit.c:1580
 msgid "could not read MERGE_MODE"
 msgstr "no se pudo leer MERGE_MODE"
 
-#: builtin/commit.c:1562
+#: builtin/commit.c:1599
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "no se pudo leer el mensaje de commit: %s"
 
-#: builtin/commit.c:1573
+#: builtin/commit.c:1610
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "Abortando commit debido que el mensaje está en blanco.\n"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1615
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "Abortando commit; no se ha editado el mensaje\n"
 
-#: builtin/commit.c:1613
+#: builtin/commit.c:1650
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full and quota is\n"
@@ -7886,148 +8286,212 @@ msgstr ""
 "new_index. Verifique que el disco no este lleno y la quota no ha\n"
 "sido superada, y luego \"git reset HEAD\" para recuperar."
 
+#: builtin/commit-graph.c:9
+msgid "git commit-graph [--object-dir <objdir>]"
+msgstr "git commit-graph [--object-dir <objdir>]"
+
+#: builtin/commit-graph.c:10 builtin/commit-graph.c:16
+msgid "git commit-graph read [--object-dir <objdir>]"
+msgstr "git commit-graph read [--object-dir <objdir>]"
+
+#: builtin/commit-graph.c:11 builtin/commit-graph.c:21
+msgid ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+msgstr ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+
+#: builtin/commit-graph.c:39 builtin/commit-graph.c:92
+#: builtin/commit-graph.c:147 builtin/fetch.c:161 builtin/log.c:1466
+msgid "dir"
+msgstr "dir"
+
+#: builtin/commit-graph.c:40 builtin/commit-graph.c:93
+#: builtin/commit-graph.c:148
+msgid "The object directory to store the graph"
+msgstr "El directorio de objetos para guardar el gráfico"
+
+#: builtin/commit-graph.c:95
+msgid "scan pack-indexes listed by stdin for commits"
+msgstr "escanear paquete de índices por stdin por commits"
+
+#: builtin/commit-graph.c:97
+msgid "start walk at commits listed by stdin"
+msgstr "comenzar a caminar a los commits listados por stdin"
+
+#: builtin/commit-graph.c:99
+msgid "include all commits already in the commit-graph file"
+msgstr "inclye todos los commits que ya están en el archivo commit-graph"
+
+#: builtin/commit-graph.c:108
+msgid "cannot use both --stdin-commits and --stdin-packs"
+msgstr "no se pueden usar ambos --stdin-commits y --stdin-packs"
+
 #: builtin/config.c:10
 msgid "git config [<options>]"
 msgstr "git config [<opciones>]"
 
-#: builtin/config.c:58
+#: builtin/config.c:101
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "argumento --type no reconocido, %s"
+
+#: builtin/config.c:123
 msgid "Config file location"
 msgstr "Ubicación del archivo configuración"
 
-#: builtin/config.c:59
+#: builtin/config.c:124
 msgid "use global config file"
 msgstr "usar archivo de config global"
 
-#: builtin/config.c:60
+#: builtin/config.c:125
 msgid "use system config file"
 msgstr "usar archivo de config del sistema"
 
-#: builtin/config.c:61
+#: builtin/config.c:126
 msgid "use repository config file"
 msgstr "usar archivo de config del repositorio"
 
-#: builtin/config.c:62
+#: builtin/config.c:127
 msgid "use given config file"
 msgstr "usar archivo config especificado"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "blob-id"
 msgstr "blob-id"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "read config from given blob object"
 msgstr "leer config del objeto blob suministrado"
 
-#: builtin/config.c:64
+#: builtin/config.c:129
 msgid "Action"
 msgstr "Acción"
 
-#: builtin/config.c:65
+#: builtin/config.c:130
 msgid "get value: name [value-regex]"
 msgstr "obtener valor: nombre [valor-regex]"
 
-#: builtin/config.c:66
+#: builtin/config.c:131
 msgid "get all values: key [value-regex]"
 msgstr "obtener todos los valores: llave [valores-regex]"
 
-#: builtin/config.c:67
+#: builtin/config.c:132
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr "obtener valores para una regexp: nombre-regex [valor-regex]"
 
-#: builtin/config.c:68
+#: builtin/config.c:133
 msgid "get value specific for the URL: section[.var] URL"
 msgstr "obtener valor especifico para el URL: sección[.var] URL"
 
-#: builtin/config.c:69
+#: builtin/config.c:134
 msgid "replace all matching variables: name value [value_regex]"
 msgstr ""
 "remplazar todas las variables que concuerden: nombre valor [valor_regex]"
 
-#: builtin/config.c:70
+#: builtin/config.c:135
 msgid "add a new variable: name value"
 msgstr "agregar nueva variable: nombre valor"
 
-#: builtin/config.c:71
+#: builtin/config.c:136
 msgid "remove a variable: name [value-regex]"
 msgstr "borrar una variable. nombre [valor-regex]"
 
-#: builtin/config.c:72
+#: builtin/config.c:137
 msgid "remove all matches: name [value-regex]"
 msgstr "borrar todas las concurrencias: nombre [valor-regex]"
 
-#: builtin/config.c:73
+#: builtin/config.c:138
 msgid "rename section: old-name new-name"
 msgstr "renombrar sección: nombre-viejo nombre-nuevo"
 
-#: builtin/config.c:74
+#: builtin/config.c:139
 msgid "remove a section: name"
 msgstr "borrar una sección: nombre"
 
-#: builtin/config.c:75
+#: builtin/config.c:140
 msgid "list all"
 msgstr "listar todo"
 
-#: builtin/config.c:76
+#: builtin/config.c:141
 msgid "open an editor"
 msgstr "abrir el editor"
 
-#: builtin/config.c:77
+#: builtin/config.c:142
 msgid "find the color configured: slot [default]"
 msgstr "encontrar el color configurado: slot [default]"
 
-#: builtin/config.c:78
+#: builtin/config.c:143
 msgid "find the color setting: slot [stdout-is-tty]"
 msgstr "encontrar las opciones del color: slot [stdout-es-tty]"
 
-#: builtin/config.c:79
+#: builtin/config.c:144
 msgid "Type"
 msgstr "Tipo"
 
-#: builtin/config.c:80
+#: builtin/config.c:145
+msgid "value is given this type"
+msgstr "al valor se ha dado este tipo"
+
+#: builtin/config.c:146
 msgid "value is \"true\" or \"false\""
 msgstr "valor es \"true\" o \"false\""
 
-#: builtin/config.c:81
+#: builtin/config.c:147
 msgid "value is decimal number"
 msgstr "valor es un numero decimal"
 
-#: builtin/config.c:82
+#: builtin/config.c:148
 msgid "value is --bool or --int"
 msgstr "valor es --bool o --int"
 
-#: builtin/config.c:83
+#: builtin/config.c:149
 msgid "value is a path (file or directory name)"
 msgstr "valor es una ruta (archivo o nombre de directorio)"
 
-#: builtin/config.c:84
+#: builtin/config.c:150
 msgid "value is an expiry date"
 msgstr "valor es una fecha de expiración"
 
-#: builtin/config.c:85
+#: builtin/config.c:151
 msgid "Other"
 msgstr "Otro"
 
-#: builtin/config.c:86
+#: builtin/config.c:152
 msgid "terminate values with NUL byte"
 msgstr "terminar valores con un byte NULL"
 
-#: builtin/config.c:87
+#: builtin/config.c:153
 msgid "show variable names only"
 msgstr "mostrar solo nombres de variables"
 
-#: builtin/config.c:88
+#: builtin/config.c:154
 msgid "respect include directives on lookup"
 msgstr "respetar directivas include en la búsqueda"
 
-#: builtin/config.c:89
+#: builtin/config.c:155
 msgid "show origin of config (file, standard input, blob, command line)"
 msgstr "mostrar el origen de configuración (archivo, stdin, blob, comando)"
 
-#: builtin/config.c:335
+#: builtin/config.c:156
+msgid "value"
+msgstr "valor"
+
+#: builtin/config.c:156
+msgid "with --get, use default value when missing entry"
+msgstr "con --get, usa el valor por defecto cuando falta una entrada"
+
+#: builtin/config.c:332
+#, c-format
+msgid "failed to format default config value: %s"
+msgstr "falló al formatear el valor por defecto de configuración: %s"
+
+#: builtin/config.c:431
 msgid "unable to parse default color value"
 msgstr "no es posible analizar el valor por defecto de color"
 
-#: builtin/config.c:479
+#: builtin/config.c:575
 #, c-format
 msgid ""
 "# This is Git's per-user configuration file.\n"
@@ -8042,16 +8506,20 @@ msgstr ""
 "#\tname = %s\n"
 "#\temail = %s\n"
 
-#: builtin/config.c:507
+#: builtin/config.c:603
 msgid "--local can only be used inside a git repository"
 msgstr "--local solo puedo ser usado dentro de un repositorio"
 
-#: builtin/config.c:632
+#: builtin/config.c:606
+msgid "--blob can only be used inside a git repository"
+msgstr "--blob solo puede ser usado dentro de un repositorio"
+
+#: builtin/config.c:735
 #, c-format
 msgid "cannot create configuration file %s"
 msgstr "no se puede crear el archivo de configuración %s"
 
-#: builtin/config.c:645
+#: builtin/config.c:748
 #, c-format
 msgid ""
 "cannot overwrite multiple values with a single value\n"
@@ -8060,11 +8528,11 @@ msgstr ""
 "no se puede sobrescribir múltiples valores con un único valor\n"
 "\tUse una regexp, --add o --replace-all para cambiar %s."
 
-#: builtin/count-objects.c:88
+#: builtin/count-objects.c:90
 msgid "git count-objects [-v] [-H | --human-readable]"
 msgstr "git count-objects [-v] [-H | --human-readable]"
 
-#: builtin/count-objects.c:98
+#: builtin/count-objects.c:100
 msgid "print sizes in human readable format"
 msgstr "mostrar tamaños en formato legible para humano"
 
@@ -8328,24 +8796,24 @@ msgstr "realizar un diff de todo el directorio"
 msgid "do not prompt before launching a diff tool"
 msgstr "no mostrar antes de lanzar una herramienta de diff"
 
-#: builtin/difftool.c:705
+#: builtin/difftool.c:704
 msgid "use symlinks in dir-diff mode"
 msgstr "usar enlaces simbólicos en modo dir-diff"
 
-#: builtin/difftool.c:706
+#: builtin/difftool.c:705
 msgid "<tool>"
 msgstr "<herramienta>"
 
-#: builtin/difftool.c:707
+#: builtin/difftool.c:706
 msgid "use the specified diff tool"
 msgstr "usar la herramienta de diff especificada"
 
-#: builtin/difftool.c:709
+#: builtin/difftool.c:708
 msgid "print a list of diff tools that may be used with `--tool`"
 msgstr ""
 "mostrar una lista de herramientas de diff que pueden ser usadas con `--tool`"
 
-#: builtin/difftool.c:712
+#: builtin/difftool.c:711
 msgid ""
 "make 'git-difftool' exit when an invoked diff tool returns a non - zero exit "
 "code"
@@ -8353,169 +8821,165 @@ msgstr ""
 "hacer que 'git-difftool' salga cuando una herramienta de diff retorne un "
 "código de salida distinto de cero"
 
-#: builtin/difftool.c:714
+#: builtin/difftool.c:713
 msgid "<command>"
 msgstr "<comando>"
 
-#: builtin/difftool.c:715
+#: builtin/difftool.c:714
 msgid "specify a custom command for viewing diffs"
 msgstr "especificar un comando personalizado para ver diffs"
 
-#: builtin/difftool.c:739
+#: builtin/difftool.c:738
 msgid "no <tool> given for --tool=<tool>"
 msgstr "no se ha proporcionado <herramienta> para --tool=<herramienta>"
 
-#: builtin/difftool.c:746
+#: builtin/difftool.c:745
 msgid "no <cmd> given for --extcmd=<cmd>"
 msgstr "no se ha entregado <comando> para --extcmd=<comando>"
 
-#: builtin/fast-export.c:26
+#: builtin/fast-export.c:27
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [rev-list-opts]"
 
-#: builtin/fast-export.c:998
+#: builtin/fast-export.c:1000
 msgid "show progress after <n> objects"
 msgstr "mostrar progreso después de <n> objetos"
 
-#: builtin/fast-export.c:1000
+#: builtin/fast-export.c:1002
 msgid "select handling of signed tags"
 msgstr "seleccionar el manejo de tags firmados"
 
-#: builtin/fast-export.c:1003
+#: builtin/fast-export.c:1005
 msgid "select handling of tags that tag filtered objects"
 msgstr "seleccionar el manejo de tags que son tags de objetos filtrados"
 
-#: builtin/fast-export.c:1006
+#: builtin/fast-export.c:1008
 msgid "Dump marks to this file"
 msgstr "Volcar marcas a este archivo"
 
-#: builtin/fast-export.c:1008
+#: builtin/fast-export.c:1010
 msgid "Import marks from this file"
 msgstr "Importar marcas de este archivo"
 
-#: builtin/fast-export.c:1010
+#: builtin/fast-export.c:1012
 msgid "Fake a tagger when tags lack one"
 msgstr "Falsificar un tagger cuando les falta uno"
 
-#: builtin/fast-export.c:1012
+#: builtin/fast-export.c:1014
 msgid "Output full tree for each commit"
 msgstr "Mostrar todo el árbol para cada commit"
 
-#: builtin/fast-export.c:1014
+#: builtin/fast-export.c:1016
 msgid "Use the done feature to terminate the stream"
 msgstr "Use el feature done para terminar el stream"
 
-#: builtin/fast-export.c:1015
+#: builtin/fast-export.c:1017
 msgid "Skip output of blob data"
 msgstr "Saltar el output de data blob"
 
-#: builtin/fast-export.c:1016
+#: builtin/fast-export.c:1018
 msgid "refspec"
 msgstr "refspec"
 
-#: builtin/fast-export.c:1017
+#: builtin/fast-export.c:1019
 msgid "Apply refspec to exported refs"
 msgstr "Aplicar refspec para los refs exportados"
 
-#: builtin/fast-export.c:1018
+#: builtin/fast-export.c:1020
 msgid "anonymize output"
 msgstr "anonimizar la salida"
 
-#: builtin/fetch.c:25
+#: builtin/fetch.c:26
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
 msgstr "git fetch [<opciones>] [<repositorio> [<refspec>...]]"
 
-#: builtin/fetch.c:26
+#: builtin/fetch.c:27
 msgid "git fetch [<options>] <group>"
 msgstr "git fetch [<opciones>] <grupo>"
 
-#: builtin/fetch.c:27
+#: builtin/fetch.c:28
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
 msgstr "git fetch --multiple [<opciones>] [(<repositorio> | <grupo>)...]"
 
-#: builtin/fetch.c:28
+#: builtin/fetch.c:29
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<opciones>]"
 
-#: builtin/fetch.c:124 builtin/pull.c:188
+#: builtin/fetch.c:123 builtin/pull.c:193
 msgid "fetch from all remotes"
 msgstr "extraer de todos los remotos"
 
-#: builtin/fetch.c:126 builtin/pull.c:191
+#: builtin/fetch.c:125 builtin/pull.c:196
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "adjuntar a .git/FETCH_HEAD en lugar de sobrescribir"
 
-#: builtin/fetch.c:128 builtin/pull.c:194
+#: builtin/fetch.c:127 builtin/pull.c:199
 msgid "path to upload pack on remote end"
 msgstr "ruta para cargar el paquete al final del remoto"
 
-#: builtin/fetch.c:129 builtin/pull.c:196
+#: builtin/fetch.c:128 builtin/pull.c:201
 msgid "force overwrite of local branch"
 msgstr "forzar sobrescritura de la rama local"
 
-#: builtin/fetch.c:131
+#: builtin/fetch.c:130
 msgid "fetch from multiple remotes"
 msgstr "extraer de múltiples remotos"
 
-#: builtin/fetch.c:133 builtin/pull.c:198
+#: builtin/fetch.c:132 builtin/pull.c:203
 msgid "fetch all tags and associated objects"
 msgstr "extraer todos los tags y objetos asociados"
 
-#: builtin/fetch.c:135
+#: builtin/fetch.c:134
 msgid "do not fetch all tags (--no-tags)"
 msgstr "no extraer todos los tags (--no-tags)"
 
-#: builtin/fetch.c:137
+#: builtin/fetch.c:136
 msgid "number of submodules fetched in parallel"
 msgstr "número de submódulos extraídos en paralelo"
 
-#: builtin/fetch.c:139 builtin/pull.c:201
+#: builtin/fetch.c:138 builtin/pull.c:206
 msgid "prune remote-tracking branches no longer on remote"
 msgstr "limpiar ramas remotas rastreadas que ya no están en el remoto"
 
-#: builtin/fetch.c:141
+#: builtin/fetch.c:140
 msgid "prune local tags no longer on remote and clobber changed tags"
 msgstr ""
 "limpiar tags locales que no se encuentran en el remoto y eliminar tags "
 "cambiados"
 
-#: builtin/fetch.c:142 builtin/fetch.c:165 builtin/pull.c:126
+#: builtin/fetch.c:141 builtin/fetch.c:164 builtin/pull.c:131
 msgid "on-demand"
 msgstr "en demanda"
 
-#: builtin/fetch.c:143
+#: builtin/fetch.c:142
 msgid "control recursive fetching of submodules"
 msgstr "controlar extracción recursiva de submódulos"
 
-#: builtin/fetch.c:147 builtin/pull.c:209
+#: builtin/fetch.c:146 builtin/pull.c:214
 msgid "keep downloaded pack"
 msgstr "mantener el paquete descargado"
 
-#: builtin/fetch.c:149
+#: builtin/fetch.c:148
 msgid "allow updating of HEAD ref"
 msgstr "permitir actualizar la ref HEAD"
 
-#: builtin/fetch.c:152 builtin/fetch.c:158 builtin/pull.c:212
+#: builtin/fetch.c:151 builtin/fetch.c:157 builtin/pull.c:217
 msgid "deepen history of shallow clone"
 msgstr "historia profunda de un clon superficial"
 
-#: builtin/fetch.c:154
+#: builtin/fetch.c:153
 msgid "deepen history of shallow repository based on time"
 msgstr "historia profunda de un repositorio superficial basado en tiempo"
 
-#: builtin/fetch.c:160 builtin/pull.c:215
+#: builtin/fetch.c:159 builtin/pull.c:220
 msgid "convert to a complete repository"
 msgstr "convertir a un repositorio completo"
 
-#: builtin/fetch.c:162 builtin/log.c:1466
-msgid "dir"
-msgstr "dir"
-
-#: builtin/fetch.c:163
+#: builtin/fetch.c:162
 msgid "prepend this to submodule path output"
 msgstr "anteponer esto a salida de la ruta del submódulo"
 
-#: builtin/fetch.c:166
+#: builtin/fetch.c:165
 msgid ""
 "default for recursive fetching of submodules (lower priority than config "
 "files)"
@@ -8523,89 +8987,99 @@ msgstr ""
 "default para extracción recursiva de submódulos (menor prioridad que "
 "archivos de configuración)"
 
-#: builtin/fetch.c:170 builtin/pull.c:218
+#: builtin/fetch.c:169 builtin/pull.c:223
 msgid "accept refs that update .git/shallow"
 msgstr "aceptar refs que actualicen .git/shallow"
 
-#: builtin/fetch.c:171 builtin/pull.c:220
+#: builtin/fetch.c:170 builtin/pull.c:225
 msgid "refmap"
 msgstr "refmap"
 
-#: builtin/fetch.c:172 builtin/pull.c:221
+#: builtin/fetch.c:171 builtin/pull.c:226
 msgid "specify fetch refmap"
 msgstr "especificar extracción de refmap"
 
-#: builtin/fetch.c:431
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:172
+msgid "server-specific"
+msgstr "especifico-de-servidor"
+
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:173
+msgid "option to transmit"
+msgstr "opción para trasmitir"
+
+#: builtin/fetch.c:442
 msgid "Couldn't find remote ref HEAD"
 msgstr "No se puedo encontrar ref remota HEAD"
 
-#: builtin/fetch.c:549
+#: builtin/fetch.c:560
 #, c-format
 msgid "configuration fetch.output contains invalid value %s"
 msgstr "la configuración fetch.output contiene el valor inválido %s"
 
-#: builtin/fetch.c:642
+#: builtin/fetch.c:653
 #, c-format
 msgid "object %s not found"
 msgstr "objeto %s no encontrado"
 
-#: builtin/fetch.c:646
+#: builtin/fetch.c:657
 msgid "[up to date]"
 msgstr "[actualizado]"
 
-#: builtin/fetch.c:659 builtin/fetch.c:739
+#: builtin/fetch.c:670 builtin/fetch.c:750
 msgid "[rejected]"
 msgstr "[rechazado]"
 
-#: builtin/fetch.c:660
+#: builtin/fetch.c:671
 msgid "can't fetch in current branch"
 msgstr "no se puede traer en la rama actual"
 
-#: builtin/fetch.c:669
+#: builtin/fetch.c:680
 msgid "[tag update]"
 msgstr "[actualización de tag]"
 
-#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719
-#: builtin/fetch.c:734
+#: builtin/fetch.c:681 builtin/fetch.c:714 builtin/fetch.c:730
+#: builtin/fetch.c:745
 msgid "unable to update local ref"
 msgstr "no se posible actualizar el ref local"
 
-#: builtin/fetch.c:689
+#: builtin/fetch.c:700
 msgid "[new tag]"
 msgstr "[nuevo tag]"
 
-#: builtin/fetch.c:692
+#: builtin/fetch.c:703
 msgid "[new branch]"
 msgstr "[nueva rama]"
 
-#: builtin/fetch.c:695
+#: builtin/fetch.c:706
 msgid "[new ref]"
 msgstr "[nueva referencia]"
 
-#: builtin/fetch.c:734
+#: builtin/fetch.c:745
 msgid "forced update"
 msgstr "actualización forzada"
 
-#: builtin/fetch.c:739
+#: builtin/fetch.c:750
 msgid "non-fast-forward"
 msgstr "avance lento"
 
-#: builtin/fetch.c:784
+#: builtin/fetch.c:795
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "%s no envió todos los objetos necesarios\n"
 
-#: builtin/fetch.c:804
+#: builtin/fetch.c:815
 #, c-format
 msgid "reject %s because shallow roots are not allowed to be updated"
 msgstr "rechazado %s porque raíces superficiales no pueden ser actualizadas"
 
-#: builtin/fetch.c:892 builtin/fetch.c:988
+#: builtin/fetch.c:903 builtin/fetch.c:999
 #, c-format
 msgid "From %.*s\n"
 msgstr "Desde %.*s\n"
 
-#: builtin/fetch.c:903
+#: builtin/fetch.c:914
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -8614,56 +9088,56 @@ msgstr ""
 "algunos refs locales no pudieron ser actualizados; intente ejecutar\n"
 " 'git remote prune %s' para remover cualquier rama vieja o conflictiva"
 
-#: builtin/fetch.c:958
+#: builtin/fetch.c:969
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (%s se pondrá colgado)"
 
-#: builtin/fetch.c:959
+#: builtin/fetch.c:970
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (%s se ha colgado)"
 
-#: builtin/fetch.c:991
+#: builtin/fetch.c:1002
 msgid "[deleted]"
 msgstr "[eliminado]"
 
-#: builtin/fetch.c:992 builtin/remote.c:1024
+#: builtin/fetch.c:1003 builtin/remote.c:1033
 msgid "(none)"
 msgstr "(nada)"
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1026
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr "Rehusando extraer en la rama actual %s de un repositorio no vacío"
 
-#: builtin/fetch.c:1034
+#: builtin/fetch.c:1045
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr "Opción \"%s\" valor \"%s\" no es válido para %s"
 
-#: builtin/fetch.c:1037
+#: builtin/fetch.c:1048
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "Opción \"%s\" es ignorada por %s\n"
 
-#: builtin/fetch.c:1277
+#: builtin/fetch.c:1287
 #, c-format
 msgid "Fetching %s\n"
 msgstr "Extrayendo %s\n"
 
-#: builtin/fetch.c:1279 builtin/remote.c:97
+#: builtin/fetch.c:1289 builtin/remote.c:98
 #, c-format
 msgid "Could not fetch %s"
 msgstr "No se pudo extraer %s"
 
-#: builtin/fetch.c:1325 builtin/fetch.c:1498
+#: builtin/fetch.c:1335 builtin/fetch.c:1503
 msgid ""
 "--filter can only be used with the remote configured in core.partialClone"
 msgstr ""
 "--filter solo puede ser usado con el remoto configurado en core.partialClone"
 
-#: builtin/fetch.c:1350
+#: builtin/fetch.c:1358
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
@@ -8671,40 +9145,40 @@ msgstr ""
 "No hay repositorio remoto especificado. Por favor, especifique un URL o un\n"
 "nombre remoto del cual las nuevas revisiones deben ser extraídas."
 
-#: builtin/fetch.c:1394
+#: builtin/fetch.c:1395
 msgid "You need to specify a tag name."
 msgstr "Tiene que especificar un nombre de tag."
 
-#: builtin/fetch.c:1439
+#: builtin/fetch.c:1444
 msgid "Negative depth in --deepen is not supported"
 msgstr "Profundidad negativa en --deepen no soportada"
 
-#: builtin/fetch.c:1441
+#: builtin/fetch.c:1446
 msgid "--deepen and --depth are mutually exclusive"
 msgstr "--deepen y --depth son mutuamente exclusivas"
 
-#: builtin/fetch.c:1446
+#: builtin/fetch.c:1451
 msgid "--depth and --unshallow cannot be used together"
 msgstr "--depth y --unshallow no pueden ser usadas juntas"
 
-#: builtin/fetch.c:1448
+#: builtin/fetch.c:1453
 msgid "--unshallow on a complete repository does not make sense"
 msgstr "--unshallow no tiene sentido en un repositorio completo"
 
-#: builtin/fetch.c:1464
+#: builtin/fetch.c:1469
 msgid "fetch --all does not take a repository argument"
 msgstr "fetch --all no toma un argumento de repositorio"
 
-#: builtin/fetch.c:1466
+#: builtin/fetch.c:1471
 msgid "fetch --all does not make sense with refspecs"
 msgstr "fetch --all no tiene sentido con refspecs"
 
-#: builtin/fetch.c:1475
+#: builtin/fetch.c:1480
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "No existe el remoto o grupo remoto: %s"
 
-#: builtin/fetch.c:1482
+#: builtin/fetch.c:1487
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr "Extraer un grupo y especificar un refspecs no tiene sentido"
 
@@ -8770,7 +9244,7 @@ msgstr "cite los marcadores de posición adecuadamente para Tcl"
 msgid "show only <n> matched refs"
 msgstr "mostrar solo <n> refs encontradas"
 
-#: builtin/for-each-ref.c:39 builtin/tag.c:420
+#: builtin/for-each-ref.c:39 builtin/tag.c:421
 msgid "respect format colors"
 msgstr "respetar el formato de colores"
 
@@ -8794,81 +9268,81 @@ msgstr "mostrar solo refs que contienen el commit"
 msgid "print only refs which don't contain the commit"
 msgstr "mostrar solo refs que no contienen el commit"
 
-#: builtin/fsck.c:568
+#: builtin/fsck.c:569
 msgid "Checking object directories"
 msgstr "Revisando objetos directorios"
 
-#: builtin/fsck.c:660
+#: builtin/fsck.c:661
 msgid "git fsck [<options>] [<object>...]"
 msgstr "git fsck [<opciones>] [<objeto>...]"
 
-#: builtin/fsck.c:666
+#: builtin/fsck.c:667
 msgid "show unreachable objects"
 msgstr "mostrar objetos ilegibles"
 
-#: builtin/fsck.c:667
+#: builtin/fsck.c:668
 msgid "show dangling objects"
 msgstr "mostrar objetos colgados"
 
-#: builtin/fsck.c:668
+#: builtin/fsck.c:669
 msgid "report tags"
 msgstr "reportar tags"
 
-#: builtin/fsck.c:669
+#: builtin/fsck.c:670
 msgid "report root nodes"
 msgstr "reportar nodos raíz"
 
-#: builtin/fsck.c:670
+#: builtin/fsck.c:671
 msgid "make index objects head nodes"
 msgstr "hacer objetos índices cabezas de nodos"
 
-#: builtin/fsck.c:671
+#: builtin/fsck.c:672
 msgid "make reflogs head nodes (default)"
 msgstr "hacer reflogs cabeza de nodos (default)"
 
-#: builtin/fsck.c:672
+#: builtin/fsck.c:673
 msgid "also consider packs and alternate objects"
 msgstr "también considerar paquetes y objetos alternos"
 
-#: builtin/fsck.c:673
+#: builtin/fsck.c:674
 msgid "check only connectivity"
 msgstr "revisar solo conectividad"
 
-#: builtin/fsck.c:674
+#: builtin/fsck.c:675
 msgid "enable more strict checking"
 msgstr "habilitar revisión más estricta"
 
-#: builtin/fsck.c:676
+#: builtin/fsck.c:677
 msgid "write dangling objects in .git/lost-found"
 msgstr "escribir objetos colgados en .git/lost-found"
 
-#: builtin/fsck.c:677 builtin/prune.c:108
+#: builtin/fsck.c:678 builtin/prune.c:109
 msgid "show progress"
 msgstr "mostrar progreso"
 
-#: builtin/fsck.c:678
+#: builtin/fsck.c:679
 msgid "show verbose names for reachable objects"
 msgstr "mostrar nombres verboso para objetos alcanzables"
 
-#: builtin/fsck.c:742
+#: builtin/fsck.c:745
 msgid "Checking objects"
 msgstr "Revisando objetos"
 
-#: builtin/gc.c:27
+#: builtin/gc.c:33
 msgid "git gc [<options>]"
 msgstr "git gc [<opciones>]"
 
-#: builtin/gc.c:80
+#: builtin/gc.c:88
 #, c-format
 msgid "Failed to fstat %s: %s"
 msgstr "Falló el fstat %s: %s"
 
-#: builtin/gc.c:312
+#: builtin/gc.c:452
 #, c-format
 msgid "Can't stat %s"
 msgstr "No se puede definir %s"
 
-#: builtin/gc.c:321
+#: builtin/gc.c:461
 #, c-format
 msgid ""
 "The last gc run reported the following. Please correct the root cause\n"
@@ -8883,45 +9357,54 @@ msgstr ""
 "\n"
 "%s"
 
-#: builtin/gc.c:360
+#: builtin/gc.c:502
 msgid "prune unreferenced objects"
 msgstr "limpiar objetos no referenciados"
 
-#: builtin/gc.c:362
+#: builtin/gc.c:504
 msgid "be more thorough (increased runtime)"
 msgstr "ser más exhaustivo (aumentar runtime)"
 
-#: builtin/gc.c:363
+#: builtin/gc.c:505
 msgid "enable auto-gc mode"
 msgstr "habilitar modo auto-gc"
 
-#: builtin/gc.c:366
+#: builtin/gc.c:508
 msgid "force running gc even if there may be another gc running"
 msgstr "forzar la ejecución de gc incluso si puede haber otro gc ejecutándose"
 
-#: builtin/gc.c:384
+#: builtin/gc.c:511
+msgid "repack all other packs except the largest pack"
+msgstr "reempaquetar todos los otros paquetes excepto el paquete más grande"
+
+#: builtin/gc.c:528
+#, c-format
+msgid "failed to parse gc.logexpiry value %s"
+msgstr "falló al analizar valor %s de gc.logexpirity"
+
+#: builtin/gc.c:539
 #, c-format
-msgid "Failed to parse gc.logexpiry value %s"
-msgstr "Falló al analizar valor %s de gc.logexpirity"
+msgid "failed to parse prune expiry value %s"
+msgstr "falló al analizar valor %s de prune expiry"
 
-#: builtin/gc.c:412
+#: builtin/gc.c:559
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
 msgstr ""
 "Auto empaquetado del repositorio en segundo plano para un performance "
 "óptimo.\n"
 
-#: builtin/gc.c:414
+#: builtin/gc.c:561
 #, c-format
 msgid "Auto packing the repository for optimum performance.\n"
 msgstr "Auto empaquetado del repositorio para performance óptimo.\n"
 
-#: builtin/gc.c:415
+#: builtin/gc.c:562
 #, c-format
 msgid "See \"git help gc\" for manual housekeeping.\n"
 msgstr "Vea \"git help gc\" para limpieza manual.\n"
 
-#: builtin/gc.c:440
+#: builtin/gc.c:598
 #, c-format
 msgid ""
 "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
@@ -8929,23 +9412,23 @@ msgstr ""
 "gc ya está ejecutándose en la máquina '%s' pid %<PRIuMAX> (use --force so no "
 "es así)"
 
-#: builtin/gc.c:487
+#: builtin/gc.c:645
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
 "Hay muchos objetos sueltos inalcanzables; ejecute 'git prune' para "
 "removerlos."
 
-#: builtin/grep.c:27
+#: builtin/grep.c:28
 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [<opciones>] [-e] <patrón> [<rev>...] [[--] <ruta>...]"
 
-#: builtin/grep.c:225
+#: builtin/grep.c:226
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep: falló al crear el hilo: %s"
 
-#: builtin/grep.c:283
+#: builtin/grep.c:284
 #, c-format
 msgid "invalid number of threads specified (%d) for %s"
 msgstr "número inválido de hilos especificado (%d) para %s"
@@ -8954,17 +9437,17 @@ msgstr "número inválido de hilos especificado (%d) para %s"
 #. variable for tweaking threads, currently
 #. grep.threads
 #.
-#: builtin/grep.c:292 builtin/index-pack.c:1523 builtin/index-pack.c:1712
+#: builtin/grep.c:293 builtin/index-pack.c:1535 builtin/index-pack.c:1727
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "no hay soporte para hilos, ignorando %s"
 
-#: builtin/grep.c:460 builtin/grep.c:580 builtin/grep.c:622
+#: builtin/grep.c:461 builtin/grep.c:582 builtin/grep.c:623
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "no es posible leer el  árbol (%s)"
 
-#: builtin/grep.c:637
+#: builtin/grep.c:638
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "no es posible realizar grep del objeto de tipo %s"
@@ -9167,7 +9650,7 @@ msgstr "--no-index o --untracked no se puede usar con revs"
 msgid "unable to resolve revision: %s"
 msgstr "no se posible resolver revisión: %s"
 
-#: builtin/grep.c:1036 builtin/index-pack.c:1519
+#: builtin/grep.c:1036 builtin/index-pack.c:1531
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "número inválido de hilos especificado (%d)"
@@ -9239,58 +9722,62 @@ msgstr ""
 msgid "process file as it were from this path"
 msgstr "procesar el archivo como si fuera de esta ruta"
 
-#: builtin/help.c:43
+#: builtin/help.c:45
 msgid "print all available commands"
 msgstr "mostrar todos los comandos disponibles"
 
-#: builtin/help.c:44
+#: builtin/help.c:46
 msgid "exclude guides"
 msgstr "excluir las guias"
 
-#: builtin/help.c:45
+#: builtin/help.c:47
 msgid "print list of useful guides"
 msgstr "mostrar una lista de nociones utiles"
 
-#: builtin/help.c:46
+#: builtin/help.c:48
 msgid "show man page"
 msgstr "mostrar la pagina del manual"
 
-#: builtin/help.c:47
+#: builtin/help.c:49
 msgid "show manual in web browser"
 msgstr "mostrar la pagina del manual en un navegador web"
 
-#: builtin/help.c:49
+#: builtin/help.c:51
 msgid "show info page"
 msgstr "mostrar la pagina de info"
 
-#: builtin/help.c:55
+#: builtin/help.c:53
+msgid "print command description"
+msgstr "imprimir descripción del comando"
+
+#: builtin/help.c:58
 msgid "git help [--all] [--guides] [--man | --web | --info] [<command>]"
 msgstr "git help [--all] [--guides] [--man | --web | --info] [<comando>]"
 
-#: builtin/help.c:67
+#: builtin/help.c:70
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "formato help no reconocido '%s'"
 
-#: builtin/help.c:94
+#: builtin/help.c:97
 msgid "Failed to start emacsclient."
-msgstr "Fallo al iniciar emacsclient."
+msgstr "Falló al iniciar emacsclient."
 
-#: builtin/help.c:107
+#: builtin/help.c:110
 msgid "Failed to parse emacsclient version."
-msgstr "Fallo al analizar la versión de emacsclient."
+msgstr "Falló al analizar la versión de emacsclient."
 
-#: builtin/help.c:115
+#: builtin/help.c:118
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "la versión '%d' de emacsclient es muy antigua (<22)."
 
-#: builtin/help.c:133 builtin/help.c:155 builtin/help.c:165 builtin/help.c:173
+#: builtin/help.c:136 builtin/help.c:158 builtin/help.c:168 builtin/help.c:176
 #, c-format
 msgid "failed to exec '%s'"
-msgstr "fallo al ejecutar '%s'"
+msgstr "falló al ejecutar '%s'"
 
-#: builtin/help.c:211
+#: builtin/help.c:214
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -9299,7 +9786,7 @@ msgstr ""
 "'%s': ruta para el visualizador del manual no soportada.\n"
 "Por favor considere usar 'man.<herramienta.cmd'."
 
-#: builtin/help.c:223
+#: builtin/help.c:226
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -9308,358 +9795,326 @@ msgstr ""
 "'%s': comando no soportado para man viewer.\n"
 "Por favor considere usar 'man.<herramienta>.path."
 
-#: builtin/help.c:340
+#: builtin/help.c:343
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "'%s': visualizador de man desconocido."
 
-#: builtin/help.c:357
+#: builtin/help.c:360
 msgid "no man viewer handled the request"
 msgstr "ningún visualizador de manual proceso la petición"
 
-#: builtin/help.c:365
+#: builtin/help.c:368
 msgid "no info viewer handled the request"
 msgstr "ningún visor de info manejo la petición"
 
-#: builtin/help.c:407
-msgid "Defining attributes per path"
-msgstr "Definiendo atributos por ruta"
-
-#: builtin/help.c:408
-msgid "Everyday Git With 20 Commands Or So"
-msgstr "Git diario con 20 comandos o algo así"
+#: builtin/help.c:415
+#, c-format
+msgid "'%s' is aliased to '%s'"
+msgstr "'%s' tiene el alias '%s'"
 
-#: builtin/help.c:409
-msgid "A Git glossary"
-msgstr "Un glosario de Git"
+#: builtin/help.c:442 builtin/help.c:459
+#, c-format
+msgid "usage: %s%s"
+msgstr "uso: %s%s"
 
-#: builtin/help.c:410
-msgid "Specifies intentionally untracked files to ignore"
-msgstr "Especifica de forma intencional archivos sin seguimiento a ignorar"
-
-#: builtin/help.c:411
-msgid "Defining submodule properties"
-msgstr "Definiendo las propiedades del submódulo"
-
-#: builtin/help.c:412
-msgid "Specifying revisions and ranges for Git"
-msgstr "Especificando revisiones y rangos para Git"
-
-#: builtin/help.c:413
-msgid "A tutorial introduction to Git (for version 1.5.1 or newer)"
-msgstr "Un tutorial de introducción para Git ( para versiones 1.5.1 o mayores)"
-
-#: builtin/help.c:414
-msgid "An overview of recommended workflows with Git"
-msgstr "Una visión general de flujos de trabajo recomendados con Git"
-
-#: builtin/help.c:426
-msgid "The common Git guides are:\n"
-msgstr "Las guías comunes de Git son:\n"
-
-#: builtin/help.c:444
-#, c-format
-msgid "'%s' is aliased to '%s'"
-msgstr "'%s' tiene el alias '%s'"
-
-#: builtin/help.c:466 builtin/help.c:483
-#, c-format
-msgid "usage: %s%s"
-msgstr "uso: %s%s"
-
-#: builtin/index-pack.c:157
+#: builtin/index-pack.c:158
 #, c-format
 msgid "unable to open %s"
 msgstr "no es posible abrir %s"
 
-#: builtin/index-pack.c:207
+#: builtin/index-pack.c:208
 #, c-format
 msgid "object type mismatch at %s"
 msgstr "el tipo del objeto no concuerda en %s"
 
-#: builtin/index-pack.c:227
+#: builtin/index-pack.c:228
 #, c-format
 msgid "did not receive expected object %s"
 msgstr "no se recibió el objeto esperado %s"
 
-#: builtin/index-pack.c:230
+#: builtin/index-pack.c:231
 #, c-format
 msgid "object %s: expected type %s, found %s"
 msgstr "objeto %s: tipo esperado %s, encontrado %s"
 
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
 #, c-format
 msgid "cannot fill %d byte"
 msgid_plural "cannot fill %d bytes"
 msgstr[0] "no se puede llenar %d byte"
 msgstr[1] "no se pueden llenar %d bytes"
 
-#: builtin/index-pack.c:282
+#: builtin/index-pack.c:283
 msgid "early EOF"
 msgstr "EOF temprano"
 
-#: builtin/index-pack.c:283
+#: builtin/index-pack.c:284
 msgid "read error on input"
 msgstr "leer error en input"
 
-#: builtin/index-pack.c:295
+#: builtin/index-pack.c:296
 msgid "used more bytes than were available"
 msgstr "se usaron más bytes de los disponibles"
 
-#: builtin/index-pack.c:302
+#: builtin/index-pack.c:303
 msgid "pack too large for current definition of off_t"
 msgstr "paquete muy grande para la definición actual de off_t"
 
-#: builtin/index-pack.c:305 builtin/unpack-objects.c:93
+#: builtin/index-pack.c:306 builtin/unpack-objects.c:93
 msgid "pack exceeds maximum allowed size"
 msgstr "paquete excede el máximo tamaño permitido"
 
-#: builtin/index-pack.c:320
+#: builtin/index-pack.c:321
 #, c-format
 msgid "unable to create '%s'"
 msgstr "no se puede crear '%s'"
 
-#: builtin/index-pack.c:326
+#: builtin/index-pack.c:327
 #, c-format
 msgid "cannot open packfile '%s'"
 msgstr "no se puede abrir el archivo de paquete '%s'"
 
-#: builtin/index-pack.c:340
+#: builtin/index-pack.c:341
 msgid "pack signature mismatch"
 msgstr "firma del paquete no concuerda"
 
-#: builtin/index-pack.c:342
+#: builtin/index-pack.c:343
 #, c-format
 msgid "pack version %<PRIu32> unsupported"
 msgstr "versión de paquete %<PRIu32> no soportada"
 
-#: builtin/index-pack.c:360
+#: builtin/index-pack.c:361
 #, c-format
 msgid "pack has bad object at offset %<PRIuMAX>: %s"
 msgstr "paquete tiene un mal objeto en el offset %<PRIuMAX>: %s"
 
-#: builtin/index-pack.c:481
+#: builtin/index-pack.c:482
 #, c-format
 msgid "inflate returned %d"
 msgstr "inflate retornó %d"
 
-#: builtin/index-pack.c:530
+#: builtin/index-pack.c:531
 msgid "offset value overflow for delta base object"
 msgstr "valor de offset desbordado para el objeto base delta"
 
-#: builtin/index-pack.c:538
+#: builtin/index-pack.c:539
 msgid "delta base offset is out of bound"
 msgstr "offset de base delta está fuera de límites"
 
-#: builtin/index-pack.c:546
+#: builtin/index-pack.c:547
 #, c-format
 msgid "unknown object type %d"
 msgstr "tipo de objeto %d desconocido"
 
-#: builtin/index-pack.c:577
+#: builtin/index-pack.c:578
 msgid "cannot pread pack file"
 msgstr "no se puede propagar el paquete"
 
-#: builtin/index-pack.c:579
+#: builtin/index-pack.c:580
 #, c-format
 msgid "premature end of pack file, %<PRIuMAX> byte missing"
 msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
 msgstr[0] "final prematuro de archivo de paquete, %<PRIuMAX> byte faltante"
 msgstr[1] "final prematuro de archivo de paquete, %<PRIuMAX> bytes faltantes"
 
-#: builtin/index-pack.c:605
+#: builtin/index-pack.c:606
 msgid "serious inflate inconsistency"
 msgstr "inconsistencia seria en inflate"
 
-#: builtin/index-pack.c:750 builtin/index-pack.c:756 builtin/index-pack.c:779
-#: builtin/index-pack.c:818 builtin/index-pack.c:827
+#: builtin/index-pack.c:751 builtin/index-pack.c:757 builtin/index-pack.c:780
+#: builtin/index-pack.c:819 builtin/index-pack.c:828
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "COLISIÓN DE TIPO SHA1 ENCONTRADA CON %s !"
 
-#: builtin/index-pack.c:753 builtin/pack-objects.c:182
-#: builtin/pack-objects.c:276
+#: builtin/index-pack.c:754 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:292
 #, c-format
 msgid "unable to read %s"
 msgstr "no se posible leer %s"
 
-#: builtin/index-pack.c:816
+#: builtin/index-pack.c:817
 #, c-format
 msgid "cannot read existing object info %s"
 msgstr "no se puede leer la información existente del objeto %s"
 
-#: builtin/index-pack.c:824
+#: builtin/index-pack.c:825
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "no se puede leer el objeto existente %s"
 
-#: builtin/index-pack.c:838
+#: builtin/index-pack.c:839
 #, c-format
 msgid "invalid blob object %s"
 msgstr "objeto blob %s inválido"
 
-#: builtin/index-pack.c:853
+#: builtin/index-pack.c:842 builtin/index-pack.c:860
+msgid "fsck error in packed object"
+msgstr "error de fsck en el objeto empaquetado"
+
+#: builtin/index-pack.c:857
 #, c-format
 msgid "invalid %s"
 msgstr "%s inválido"
 
-#: builtin/index-pack.c:856
-msgid "Error in object"
-msgstr "Error en el objeto"
-
-#: builtin/index-pack.c:858
+#: builtin/index-pack.c:862
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "No todos los objetos hijos de %s son alcanzables"
 
-#: builtin/index-pack.c:930 builtin/index-pack.c:961
+#: builtin/index-pack.c:934 builtin/index-pack.c:965
 msgid "failed to apply delta"
 msgstr "falló al aplicar delta"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Receiving objects"
 msgstr "Recibiendo objetos"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Indexing objects"
 msgstr "Indexando objetos"
 
-#: builtin/index-pack.c:1165
+#: builtin/index-pack.c:1169
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "paquete está corrompido (SHA1 no concuerda)"
 
-#: builtin/index-pack.c:1170
+#: builtin/index-pack.c:1174
 msgid "cannot fstat packfile"
 msgstr "no se puede fstat al archivo de paquete"
 
-#: builtin/index-pack.c:1173
+#: builtin/index-pack.c:1177
 msgid "pack has junk at the end"
 msgstr "el paquete tiene basura al final"
 
-#: builtin/index-pack.c:1185
+#: builtin/index-pack.c:1189
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "confusión más allá de la locura en parse_pack_objects()"
 
-#: builtin/index-pack.c:1208
+#: builtin/index-pack.c:1212
 msgid "Resolving deltas"
 msgstr "Resolviendo deltas"
 
-#: builtin/index-pack.c:1219
+#: builtin/index-pack.c:1223
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "no es posible crear hilo: %s"
 
-#: builtin/index-pack.c:1261
+#: builtin/index-pack.c:1265
 msgid "confusion beyond insanity"
 msgstr "confusión más allá de la locura"
 
-#: builtin/index-pack.c:1267
+#: builtin/index-pack.c:1271
 #, c-format
 msgid "completed with %d local object"
 msgid_plural "completed with %d local objects"
 msgstr[0] "completado con %d objeto local"
 msgstr[1] "completado con %d objetos locales"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1283
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr "Tail checksum para %s inesperada (corrupción de disco?)"
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1287
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "paquete tiene %d delta sin resolver"
 msgstr[1] "paquete tiene %d deltas sin resolver"
 
-#: builtin/index-pack.c:1307
+#: builtin/index-pack.c:1311
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "no es posible desinflar el objeto adjunto (%d)"
 
-#: builtin/index-pack.c:1383
+#: builtin/index-pack.c:1388
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "objeto local %s está corrompido"
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1402
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "nombre '%s' de archivo de paquete no termina con '.pack'"
 
-#: builtin/index-pack.c:1422
+#: builtin/index-pack.c:1427
 #, c-format
 msgid "cannot write %s file '%s'"
 msgstr "no se puede escribir %s en el archivo '%s'"
 
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1435
 #, c-format
 msgid "cannot close written %s file '%s'"
 msgstr "no se puede cerrar escrito %s en archivo '%s'"
 
-#: builtin/index-pack.c:1454
+#: builtin/index-pack.c:1459
 msgid "error while closing pack file"
 msgstr "error mientras se cierra el archivo paquete"
 
-#: builtin/index-pack.c:1468
+#: builtin/index-pack.c:1473
 msgid "cannot store pack file"
 msgstr "no se puede guardar el archivo paquete"
 
-#: builtin/index-pack.c:1476
+#: builtin/index-pack.c:1481
 msgid "cannot store index file"
 msgstr "no se puede guardar el archivo índice"
 
-#: builtin/index-pack.c:1513
+#: builtin/index-pack.c:1525
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "mal pack.indexversion=%<PRIu32>"
 
-#: builtin/index-pack.c:1581
+#: builtin/index-pack.c:1594
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "No se puede abrir el archivo paquete existente '%s'"
 
-#: builtin/index-pack.c:1583
+#: builtin/index-pack.c:1596
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "No se puede abrir el índice del archivo paquete para '%s'"
 
-#: builtin/index-pack.c:1631
+#: builtin/index-pack.c:1644
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "no delta: %d objeto"
 msgstr[1] "no delta: %d objetos"
 
-#: builtin/index-pack.c:1638
+#: builtin/index-pack.c:1651
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] "largo de cadena = %d: %lu objeto"
 msgstr[1] "largo de cadena = %d: %lu objetos"
 
-#: builtin/index-pack.c:1675
+#: builtin/index-pack.c:1688
 msgid "Cannot come back to cwd"
 msgstr "No se puede regresar a cwd"
 
-#: builtin/index-pack.c:1724 builtin/index-pack.c:1727
-#: builtin/index-pack.c:1743 builtin/index-pack.c:1747
+#: builtin/index-pack.c:1739 builtin/index-pack.c:1742
+#: builtin/index-pack.c:1758 builtin/index-pack.c:1762
 #, c-format
 msgid "bad %s"
 msgstr "mal %s"
 
-#: builtin/index-pack.c:1763
+#: builtin/index-pack.c:1778
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin no puede ser usada sin --stdin"
 
-#: builtin/index-pack.c:1765
+#: builtin/index-pack.c:1780
 msgid "--stdin requires a git repository"
 msgstr "--stdin requiere un repositorio git"
 
-#: builtin/index-pack.c:1771
+#: builtin/index-pack.c:1786
 msgid "--verify with no packfile name given"
 msgstr "--verify no recibió ningún nombre de archivo de paquete"
 
+#: builtin/index-pack.c:1836 builtin/unpack-objects.c:578
+msgid "fsck error in pack objects"
+msgstr "error de fsck en objetos paquete"
+
 #: builtin/init-db.c:55
 #, c-format
 msgid "cannot stat '%s'"
@@ -9697,8 +10152,8 @@ msgstr "ignorando template %s"
 
 #: builtin/init-db.c:120
 #, c-format
-msgid "templates not found %s"
-msgstr "no se encontraron templates %s"
+msgid "templates not found in %s"
+msgstr "template no encontrado en %s"
 
 #: builtin/init-db.c:135
 #, c-format
@@ -9757,11 +10212,6 @@ msgid "specify that the git repository is to be shared amongst several users"
 msgstr ""
 "especifica que el repositorio de git será compartido entre varios usuarios"
 
-#: builtin/init-db.c:516 builtin/init-db.c:521
-#, c-format
-msgid "cannot mkdir %s"
-msgstr "no se pude crear directorio %s"
-
 #: builtin/init-db.c:525
 #, c-format
 msgid "cannot chdir to %s"
@@ -9945,7 +10395,7 @@ msgstr "Dos directorios de salida?"
 msgid "Unknown commit %s"
 msgstr "Commit desconocido %s"
 
-#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:522
+#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:523
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr "Falló al resolver '%s' como una ref válida."
@@ -9968,7 +10418,7 @@ msgstr ""
 
 #: builtin/log.c:1318
 msgid "Failed to find exact merge base"
-msgstr "Fallo al encontrar una base de fusión exacta"
+msgstr "Falló al encontrar una base de fusión exacta"
 
 #: builtin/log.c:1329
 msgid "base commit should be the ancestor of revision list"
@@ -10305,7 +10755,7 @@ msgstr ""
 msgid "show debugging data"
 msgstr "mostrar data de debug"
 
-#: builtin/ls-remote.c:7
+#: builtin/ls-remote.c:9
 msgid ""
 "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
@@ -10315,39 +10765,39 @@ msgstr ""
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
 "                     [--symref] [<repositorio> [<refs>...]]"
 
-#: builtin/ls-remote.c:52
+#: builtin/ls-remote.c:59
 msgid "do not print remote URL"
 msgstr "no mostrar el URL remoto"
 
-#: builtin/ls-remote.c:53 builtin/ls-remote.c:55
+#: builtin/ls-remote.c:60 builtin/ls-remote.c:62
 msgid "exec"
 msgstr "ejecutar"
 
-#: builtin/ls-remote.c:54 builtin/ls-remote.c:56
+#: builtin/ls-remote.c:61 builtin/ls-remote.c:63
 msgid "path of git-upload-pack on the remote host"
 msgstr "ruta de git-upload-pack en el host remoto"
 
-#: builtin/ls-remote.c:58
+#: builtin/ls-remote.c:65
 msgid "limit to tags"
 msgstr "limitar a tags"
 
-#: builtin/ls-remote.c:59
+#: builtin/ls-remote.c:66
 msgid "limit to heads"
 msgstr "limitar a heads"
 
-#: builtin/ls-remote.c:60
+#: builtin/ls-remote.c:67
 msgid "do not show peeled tags"
 msgstr "no mostrar tags pelados"
 
-#: builtin/ls-remote.c:62
+#: builtin/ls-remote.c:69
 msgid "take url.<base>.insteadOf into account"
 msgstr "tomar url.<base>.insteadOf en cuenta"
 
-#: builtin/ls-remote.c:64
+#: builtin/ls-remote.c:73
 msgid "exit with exit code 2 if no matching refs are found"
 msgstr "salir con código de salida 2 si no se encuentran refs que concuerden"
 
-#: builtin/ls-remote.c:67
+#: builtin/ls-remote.c:76
 msgid "show underlying ref in addition to the object pointed by it"
 msgstr "mostrar ref subyacente en adición al objeto apuntado por él"
 
@@ -10393,167 +10843,167 @@ msgstr ""
 msgid "empty mbox: '%s'"
 msgstr "mbox vacío: '%s'"
 
-#: builtin/merge.c:49
+#: builtin/merge.c:51
 msgid "git merge [<options>] [<commit>...]"
 msgstr "git merge [<opciones>] [<commit>...]"
 
-#: builtin/merge.c:50
+#: builtin/merge.c:52
 msgid "git merge --abort"
 msgstr "git merge --abort"
 
-#: builtin/merge.c:51
+#: builtin/merge.c:53
 msgid "git merge --continue"
 msgstr "git merge --continue"
 
-#: builtin/merge.c:108
+#: builtin/merge.c:110
 msgid "switch `m' requires a value"
 msgstr "cambiar `m' requiere un valor"
 
-#: builtin/merge.c:145
+#: builtin/merge.c:147
 #, c-format
 msgid "Could not find merge strategy '%s'.\n"
 msgstr "No se pudo encontrar estrategia de fusión '%s'.\n"
 
-#: builtin/merge.c:146
+#: builtin/merge.c:148
 #, c-format
 msgid "Available strategies are:"
 msgstr "Estrategias disponibles son:"
 
-#: builtin/merge.c:151
+#: builtin/merge.c:153
 #, c-format
 msgid "Available custom strategies are:"
 msgstr "Estrategias personalizadas disponibles son:"
 
-#: builtin/merge.c:201 builtin/pull.c:137
+#: builtin/merge.c:203 builtin/pull.c:142
 msgid "do not show a diffstat at the end of the merge"
 msgstr "no mostrar un diffstat al final de la fusión"
 
-#: builtin/merge.c:204 builtin/pull.c:140
+#: builtin/merge.c:206 builtin/pull.c:145
 msgid "show a diffstat at the end of the merge"
 msgstr "mostrar un diffstat al final de la fusión"
 
-#: builtin/merge.c:205 builtin/pull.c:143
+#: builtin/merge.c:207 builtin/pull.c:148
 msgid "(synonym to --stat)"
 msgstr "(sinónimo para --stat)"
 
-#: builtin/merge.c:207 builtin/pull.c:146
+#: builtin/merge.c:209 builtin/pull.c:151
 msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr ""
 "agregar (como máximo <n>) entradas del shortlog al mensaje del commit de "
 "fusión"
 
-#: builtin/merge.c:210 builtin/pull.c:152
+#: builtin/merge.c:212 builtin/pull.c:157
 msgid "create a single commit instead of doing a merge"
 msgstr "crear un commit único en lugar de hacer una fusión"
 
-#: builtin/merge.c:212 builtin/pull.c:155
+#: builtin/merge.c:214 builtin/pull.c:160
 msgid "perform a commit if the merge succeeds (default)"
 msgstr "realizar un commit si la fusión es exitosa (default)"
 
-#: builtin/merge.c:214 builtin/pull.c:158
+#: builtin/merge.c:216 builtin/pull.c:163
 msgid "edit message before committing"
 msgstr "editar mensaje antes de realizar commit"
 
-#: builtin/merge.c:215
+#: builtin/merge.c:217
 msgid "allow fast-forward (default)"
 msgstr "permitir fast-forwars (default)"
 
-#: builtin/merge.c:217 builtin/pull.c:164
+#: builtin/merge.c:219 builtin/pull.c:169
 msgid "abort if fast-forward is not possible"
 msgstr "abortar si fast-forward no es posible"
 
-#: builtin/merge.c:221 builtin/pull.c:167
+#: builtin/merge.c:223 builtin/pull.c:172
 msgid "verify that the named commit has a valid GPG signature"
 msgstr "verificar que el commit nombrado tiene una firma GPG válida"
 
-#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171
+#: builtin/merge.c:224 builtin/notes.c:777 builtin/pull.c:176
 #: builtin/revert.c:109
 msgid "strategy"
 msgstr "estrategia"
 
-#: builtin/merge.c:223 builtin/pull.c:172
+#: builtin/merge.c:225 builtin/pull.c:177
 msgid "merge strategy to use"
 msgstr "estrategia de fusión para usar"
 
-#: builtin/merge.c:224 builtin/pull.c:175
+#: builtin/merge.c:226 builtin/pull.c:180
 msgid "option=value"
 msgstr "opción=valor"
 
-#: builtin/merge.c:225 builtin/pull.c:176
+#: builtin/merge.c:227 builtin/pull.c:181
 msgid "option for selected merge strategy"
 msgstr "opción para la estrategia de fusión seleccionada"
 
-#: builtin/merge.c:227
+#: builtin/merge.c:229
 msgid "merge commit message (for a non-fast-forward merge)"
 msgstr "fusionar mensaje de commit (para una fusión no fast-forward)"
 
-#: builtin/merge.c:231
+#: builtin/merge.c:233
 msgid "abort the current in-progress merge"
 msgstr "abortar la fusión en progreso actual"
 
-#: builtin/merge.c:233
+#: builtin/merge.c:235
 msgid "continue the current in-progress merge"
 msgstr "continuar la fusión en progreso actual"
 
-#: builtin/merge.c:235 builtin/pull.c:183
+#: builtin/merge.c:237 builtin/pull.c:188
 msgid "allow merging unrelated histories"
 msgstr "permitir fusionar historias no relacionadas"
 
-#: builtin/merge.c:241
+#: builtin/merge.c:243
 msgid "verify commit-msg hook"
 msgstr "verificar el hook commit-msg"
 
-#: builtin/merge.c:266
+#: builtin/merge.c:268
 msgid "could not run stash."
 msgstr "no se pudo ejecutar stash."
 
-#: builtin/merge.c:271
+#: builtin/merge.c:273
 msgid "stash failed"
 msgstr "stash falló"
 
-#: builtin/merge.c:276
+#: builtin/merge.c:278
 #, c-format
 msgid "not a valid object: %s"
 msgstr "no es un objeto válido: %s"
 
-#: builtin/merge.c:298 builtin/merge.c:315
+#: builtin/merge.c:300 builtin/merge.c:317
 msgid "read-tree failed"
 msgstr "lectura de árbol falló"
 
-#: builtin/merge.c:345
+#: builtin/merge.c:347
 msgid " (nothing to squash)"
 msgstr " (nada para hacer squash)"
 
-#: builtin/merge.c:356
+#: builtin/merge.c:358
 #, c-format
 msgid "Squash commit -- not updating HEAD\n"
 msgstr "Commit de squash -- no actualizando HEAD\n"
 
-#: builtin/merge.c:406
+#: builtin/merge.c:408
 #, c-format
 msgid "No merge message -- not updating HEAD\n"
 msgstr "No hay mensaje de fusión -- no actualizando HEAD\n"
 
-#: builtin/merge.c:456
+#: builtin/merge.c:458
 #, c-format
 msgid "'%s' does not point to a commit"
 msgstr "'%s' no apunta a ningún commit"
 
-#: builtin/merge.c:546
+#: builtin/merge.c:548
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "Mal string branch.%s.mergeoptions: %s"
 
-#: builtin/merge.c:668
+#: builtin/merge.c:669
 msgid "Not handling anything other than two heads merge."
 msgstr "No manejando nada más que fusión de dos heads."
 
-#: builtin/merge.c:682
+#: builtin/merge.c:683
 #, c-format
 msgid "Unknown option for merge-recursive: -X%s"
 msgstr "Opción desconocida para merge-recursive: -X%s"
 
-#: builtin/merge.c:697
+#: builtin/merge.c:698
 #, c-format
 msgid "unable to write %s"
 msgstr "no es posible escribir %s"
@@ -10591,66 +11041,66 @@ msgstr ""
 msgid "Empty commit message."
 msgstr "Mensaje de commit vacío."
 
-#: builtin/merge.c:820
+#: builtin/merge.c:819
 #, c-format
 msgid "Wonderful.\n"
 msgstr "Maravilloso.\n"
 
-#: builtin/merge.c:873
+#: builtin/merge.c:872
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr ""
 "Fusión automática falló; arregle los conflictos y luego realice un commit "
 "con el resultado.\n"
 
-#: builtin/merge.c:912
+#: builtin/merge.c:911
 msgid "No current branch."
 msgstr "No rama actual."
 
-#: builtin/merge.c:914
+#: builtin/merge.c:913
 msgid "No remote for the current branch."
 msgstr "No hay remoto para la rama actual."
 
-#: builtin/merge.c:916
+#: builtin/merge.c:915
 msgid "No default upstream defined for the current branch."
 msgstr "Por defecto, no hay un upstream  definido para la rama actual."
 
-#: builtin/merge.c:921
+#: builtin/merge.c:920
 #, c-format
 msgid "No remote-tracking branch for %s from %s"
 msgstr "No hay rama de rastreo remoto para %s de %s"
 
-#: builtin/merge.c:974
+#: builtin/merge.c:973
 #, c-format
 msgid "Bad value '%s' in environment '%s'"
 msgstr "Mal valor '%s' en el entorno '%s'"
 
-#: builtin/merge.c:1076
+#: builtin/merge.c:1075
 #, c-format
 msgid "not something we can merge in %s: %s"
 msgstr "nada que podamos fusionar en %s: %s"
 
-#: builtin/merge.c:1110
+#: builtin/merge.c:1109
 msgid "not something we can merge"
 msgstr "nada que podamos fusionar"
 
-#: builtin/merge.c:1212
+#: builtin/merge.c:1211
 msgid "--abort expects no arguments"
 msgstr "--abort no espera argumentos"
 
-#: builtin/merge.c:1216
+#: builtin/merge.c:1215
 msgid "There is no merge to abort (MERGE_HEAD missing)."
 msgstr "No hay una fusión para abortar (falta MERGE_HEAD)"
 
-#: builtin/merge.c:1228
+#: builtin/merge.c:1227
 msgid "--continue expects no arguments"
 msgstr "--continue no espera argumentos"
 
-#: builtin/merge.c:1232
+#: builtin/merge.c:1231
 msgid "There is no merge in progress (MERGE_HEAD missing)."
 msgstr "No hay fusión en progreso (falta MERGE_HEAD)."
 
-#: builtin/merge.c:1248
+#: builtin/merge.c:1247
 msgid ""
 "You have not concluded your merge (MERGE_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10658,7 +11108,7 @@ msgstr ""
 "No ha concluido la fusión (existe MERGE_HEAD).\n"
 "Por favor, realice un commit con los cambios antes de fusionar."
 
-#: builtin/merge.c:1255
+#: builtin/merge.c:1254
 msgid ""
 "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10666,113 +11116,113 @@ msgstr ""
 "No ha concluido el cherry-pick (existe CHERRY_PICK_HEAD).\n"
 "Por favor, realice un commit con los cambios antes de fusionar."
 
-#: builtin/merge.c:1258
+#: builtin/merge.c:1257
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
 msgstr "No ha concluido el cherry-pick (existe CHERRY_PICK_HEAD)."
 
-#: builtin/merge.c:1267
+#: builtin/merge.c:1266
 msgid "You cannot combine --squash with --no-ff."
 msgstr "No se puede combinar --squash con --no-ff."
 
-#: builtin/merge.c:1275
+#: builtin/merge.c:1274
 msgid "No commit specified and merge.defaultToUpstream not set."
 msgstr ""
 "No hay commit especificado y merge.defaultToUpstream no está configurado."
 
-#: builtin/merge.c:1292
+#: builtin/merge.c:1291
 msgid "Squash commit into empty head not supported yet"
 msgstr "Commit aplastado dentro de un head vacío no es soportado todavía"
 
-#: builtin/merge.c:1294
+#: builtin/merge.c:1293
 msgid "Non-fast-forward commit does not make sense into an empty head"
 msgstr "Commit no fast-forward no tiene sentido dentro de un head vacío"
 
-#: builtin/merge.c:1299
+#: builtin/merge.c:1298
 #, c-format
 msgid "%s - not something we can merge"
 msgstr "%s - nada que podamos fusionar"
 
-#: builtin/merge.c:1301
+#: builtin/merge.c:1300
 msgid "Can merge only exactly one commit into empty head"
 msgstr "Solo se puede fusionar exactamente un commit en un head vacío"
 
-#: builtin/merge.c:1335
+#: builtin/merge.c:1334
 #, c-format
 msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
 msgstr "Commit %s tiene una firma GPG no confiable, pretendidamente por %s."
 
-#: builtin/merge.c:1338
+#: builtin/merge.c:1337
 #, c-format
 msgid "Commit %s has a bad GPG signature allegedly by %s."
 msgstr "Commit %s tiene una mala firma GPG pretendidamente por %s."
 
-#: builtin/merge.c:1341
+#: builtin/merge.c:1340
 #, c-format
 msgid "Commit %s does not have a GPG signature."
 msgstr "Commit %s no tiene una firma GPG."
 
-#: builtin/merge.c:1344
+#: builtin/merge.c:1343
 #, c-format
 msgid "Commit %s has a good GPG signature by %s\n"
 msgstr "El Commit %s tiene una buena firma GPG por %s\n"
 
-#: builtin/merge.c:1403
+#: builtin/merge.c:1402
 msgid "refusing to merge unrelated histories"
 msgstr "rehusando fusionar historias no relacionadas"
 
-#: builtin/merge.c:1412
+#: builtin/merge.c:1411
 msgid "Already up to date."
 msgstr "Ya está actualizado."
 
-#: builtin/merge.c:1422
+#: builtin/merge.c:1421
 #, c-format
 msgid "Updating %s..%s\n"
 msgstr "Actualizando %s..%s\n"
 
-#: builtin/merge.c:1463
+#: builtin/merge.c:1462
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
 msgstr "Intentando fusión en índice realmente trivial...\n"
 
-#: builtin/merge.c:1470
+#: builtin/merge.c:1469
 #, c-format
 msgid "Nope.\n"
 msgstr "Nop.\n"
 
-#: builtin/merge.c:1495
+#: builtin/merge.c:1494
 msgid "Already up to date. Yeeah!"
 msgstr "Ya está actualizado. ¡Oh, yeaahh!"
 
-#: builtin/merge.c:1501
+#: builtin/merge.c:1500
 msgid "Not possible to fast-forward, aborting."
 msgstr "No es posible hacer fast-forward, abortando."
 
-#: builtin/merge.c:1524 builtin/merge.c:1603
+#: builtin/merge.c:1523 builtin/merge.c:1602
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
 msgstr "Rebobinando el árbol a original...\n"
 
-#: builtin/merge.c:1528
+#: builtin/merge.c:1527
 #, c-format
 msgid "Trying merge strategy %s...\n"
 msgstr "Intentando estrategia de fusión %s...\n"
 
-#: builtin/merge.c:1594
+#: builtin/merge.c:1593
 #, c-format
 msgid "No merge strategy handled the merge.\n"
 msgstr "Ninguna estrategia de fusión manejó la fusión.\n"
 
-#: builtin/merge.c:1596
+#: builtin/merge.c:1595
 #, c-format
 msgid "Merge with strategy %s failed.\n"
 msgstr "Fusionar con estrategia %s falló.\n"
 
-#: builtin/merge.c:1605
+#: builtin/merge.c:1604
 #, c-format
 msgid "Using the %s to prepare resolving by hand.\n"
 msgstr "Usando el %s para preparar resolución a mano.\n"
 
-#: builtin/merge.c:1617
+#: builtin/merge.c:1616
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr ""
@@ -10909,27 +11359,27 @@ msgstr "permitir la creación de más de un árbol"
 msgid "git mv [<options>] <source>... <destination>"
 msgstr "git mv [<opciones>] <fuente>... <destino>"
 
-#: builtin/mv.c:83
+#: builtin/mv.c:82
 #, c-format
 msgid "Directory %s is in index and no submodule?"
 msgstr "Directorio %s está en el índice y no hay submódulo?"
 
-#: builtin/mv.c:85 builtin/rm.c:289
+#: builtin/mv.c:84 builtin/rm.c:288
 msgid "Please stage your changes to .gitmodules or stash them to proceed"
 msgstr ""
 "Por favor agrega el stage de tus cambios a .gitmodules o realiza un stash "
 "para proceder"
 
-#: builtin/mv.c:103
+#: builtin/mv.c:102
 #, c-format
 msgid "%.*s is in index"
 msgstr "%.*s está en el índice"
 
-#: builtin/mv.c:125
+#: builtin/mv.c:124
 msgid "force move/rename even if target exists"
 msgstr "forzar mover/renombrar incluso si el objetivo existe"
 
-#: builtin/mv.c:127
+#: builtin/mv.c:126
 msgid "skip move/rename errors"
 msgstr "saltar errores de mover/renombrar"
 
@@ -10994,7 +11444,7 @@ msgstr "%s, fuente=%s, destino=%s"
 msgid "Renaming %s to %s\n"
 msgstr "Renombrando %s a %s\n"
 
-#: builtin/mv.c:276 builtin/remote.c:712 builtin/repack.c:394
+#: builtin/mv.c:276 builtin/remote.c:715 builtin/repack.c:409
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "renombrando '%s' falló"
@@ -11188,12 +11638,12 @@ msgstr "incapaz de escribir el objeto de nota"
 msgid "the note contents have been left in %s"
 msgstr "los contenidos de nota han sido dejados en %s"
 
-#: builtin/notes.c:234 builtin/tag.c:506
+#: builtin/notes.c:234 builtin/tag.c:507
 #, c-format
 msgid "cannot read '%s'"
 msgstr "no se puede leer '%s'"
 
-#: builtin/notes.c:236 builtin/tag.c:509
+#: builtin/notes.c:236 builtin/tag.c:510
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "no se pudo abrir o leer '%s'"
@@ -11439,7 +11889,7 @@ msgstr "intentar remover una nota no existente no es un error"
 msgid "read object names from the standard input"
 msgstr "leer nombres de objetos de standard input"
 
-#: builtin/notes.c:943 builtin/prune.c:106 builtin/worktree.c:160
+#: builtin/notes.c:943 builtin/prune.c:107 builtin/worktree.c:151
 msgid "do not remove, show only"
 msgstr "no remover, solo mostrar"
 
@@ -11460,218 +11910,246 @@ msgstr "usar notas desde <referencia-de-notas>"
 msgid "unknown subcommand: %s"
 msgstr "subcomando desconocido: %s"
 
-#: builtin/pack-objects.c:33
+#: builtin/pack-objects.c:48
 msgid ""
 "git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
 msgstr ""
 "git pack-objects --stdout [<opciones>...] [< <lista-de-ref> | < <lista-de-"
 "objetos>]"
 
-#: builtin/pack-objects.c:34
+#: builtin/pack-objects.c:49
 msgid ""
 "git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
 msgstr ""
 "git pack-objects [<opciones>...] <nombre-base> [< <lista-de-refs> | < <lista-"
 "de-objetos>]"
 
-#: builtin/pack-objects.c:195 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:211 builtin/pack-objects.c:214
 #, c-format
 msgid "deflate error (%d)"
 msgstr "error al desinflar (%d)"
 
-#: builtin/pack-objects.c:791
+#: builtin/pack-objects.c:810
 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
 msgstr ""
 "deshabilitando escritura bitmap, paquetes son divididos debido a pack."
 "packSizeLimit"
 
-#: builtin/pack-objects.c:804
+#: builtin/pack-objects.c:823
 msgid "Writing objects"
 msgstr "Escribiendo objetos"
 
-#: builtin/pack-objects.c:1084
+#: builtin/pack-objects.c:1106
 msgid "disabling bitmap writing, as some objects are not being packed"
 msgstr ""
 "deshabilitando escritura bitmap, ya que algunos objetos no están siendo "
 "empaquetados"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:1765
+msgid "Counting objects"
+msgstr "Contando objetos"
+
+#: builtin/pack-objects.c:1895
+#, c-format
+msgid "unable to get size of %s"
+msgstr "no se pudo obtener el tamaño de %s"
+
+#: builtin/pack-objects.c:1910
+#, c-format
+msgid "unable to parse object header of %s"
+msgstr "incapaz de analizar header del objeto %s"
+
+#: builtin/pack-objects.c:2564
 msgid "Compressing objects"
 msgstr "Comprimiendo objetos"
 
-#: builtin/pack-objects.c:2625
+#: builtin/pack-objects.c:2735
 msgid "invalid value for --missing"
 msgstr "valor inválido para --missing"
 
-#: builtin/pack-objects.c:2928
+#: builtin/pack-objects.c:3067
 #, c-format
 msgid "unsupported index version %s"
 msgstr "versión de índice no soportada %s"
 
-#: builtin/pack-objects.c:2932
+#: builtin/pack-objects.c:3071
 #, c-format
 msgid "bad index version '%s'"
 msgstr "mala versión del índice '%s'"
 
-#: builtin/pack-objects.c:2962
+#: builtin/pack-objects.c:3102
 msgid "do not show progress meter"
 msgstr "no mostrar medidor de progreso"
 
-#: builtin/pack-objects.c:2964
+#: builtin/pack-objects.c:3104
 msgid "show progress meter"
 msgstr "mostrar medidor de progreso"
 
-#: builtin/pack-objects.c:2966
+#: builtin/pack-objects.c:3106
 msgid "show progress meter during object writing phase"
 msgstr "mostrar medidor de progreso durante la fase de escritura de objeto"
 
-#: builtin/pack-objects.c:2969
+#: builtin/pack-objects.c:3109
 msgid "similar to --all-progress when progress meter is shown"
 msgstr "similar a --all-progress cuando medidor de progreso es mostrado"
 
-#: builtin/pack-objects.c:2970
+#: builtin/pack-objects.c:3110
 msgid "version[,offset]"
 msgstr "versión[,offset]"
 
-#: builtin/pack-objects.c:2971
+#: builtin/pack-objects.c:3111
 msgid "write the pack index file in the specified idx format version"
 msgstr ""
 "escribir el índice de paquete en la versión de formato idx especificado"
 
-#: builtin/pack-objects.c:2974
+#: builtin/pack-objects.c:3114
 msgid "maximum size of each output pack file"
 msgstr "tamaño máximo de cada paquete resultante"
 
-#: builtin/pack-objects.c:2976
+#: builtin/pack-objects.c:3116
 msgid "ignore borrowed objects from alternate object store"
 msgstr "ignorar objetos prestados de otros almacenes de objetos"
 
-#: builtin/pack-objects.c:2978
+#: builtin/pack-objects.c:3118
 msgid "ignore packed objects"
 msgstr "ignorar objetos paquete"
 
-#: builtin/pack-objects.c:2980
+#: builtin/pack-objects.c:3120
 msgid "limit pack window by objects"
 msgstr "limitar ventana de paquete por objetos"
 
-#: builtin/pack-objects.c:2982
+#: builtin/pack-objects.c:3122
 msgid "limit pack window by memory in addition to object limit"
 msgstr "limitar ventana de paquete por memoria en adición a límite de objetos"
 
-#: builtin/pack-objects.c:2984
+#: builtin/pack-objects.c:3124
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr "longitud máxima de cadena delta permitida en el paquete resultante"
 
-#: builtin/pack-objects.c:2986
+#: builtin/pack-objects.c:3126
 msgid "reuse existing deltas"
 msgstr "reusar deltas existentes"
 
-#: builtin/pack-objects.c:2988
+#: builtin/pack-objects.c:3128
 msgid "reuse existing objects"
 msgstr "reutilizar objetos existentes"
 
-#: builtin/pack-objects.c:2990
+#: builtin/pack-objects.c:3130
 msgid "use OFS_DELTA objects"
 msgstr "usar objetos OFS_DELTA"
 
-#: builtin/pack-objects.c:2992
+#: builtin/pack-objects.c:3132
 msgid "use threads when searching for best delta matches"
 msgstr "usar hilos cuando se busque para mejores concordancias de delta"
 
-#: builtin/pack-objects.c:2994
+#: builtin/pack-objects.c:3134
 msgid "do not create an empty pack output"
 msgstr "no crear un paquete resultante vacío"
 
-#: builtin/pack-objects.c:2996
+#: builtin/pack-objects.c:3136
 msgid "read revision arguments from standard input"
 msgstr "leer argumentos de revisión de standard input"
 
-#: builtin/pack-objects.c:2998
+#: builtin/pack-objects.c:3138
 msgid "limit the objects to those that are not yet packed"
 msgstr "limitar los objetos a aquellos que no han sido empaquetados todavía"
 
-#: builtin/pack-objects.c:3001
+#: builtin/pack-objects.c:3141
 msgid "include objects reachable from any reference"
 msgstr "incluir objetos alcanzables por cualquier referencia"
 
-#: builtin/pack-objects.c:3004
+#: builtin/pack-objects.c:3144
 msgid "include objects referred by reflog entries"
 msgstr "incluir objetos referidos por entradas de reflog"
 
-#: builtin/pack-objects.c:3007
+#: builtin/pack-objects.c:3147
 msgid "include objects referred to by the index"
 msgstr "incluir objetos referidos por el índice"
 
-#: builtin/pack-objects.c:3010
+#: builtin/pack-objects.c:3150
 msgid "output pack to stdout"
 msgstr "mostrar paquete en stdout"
 
-#: builtin/pack-objects.c:3012
+#: builtin/pack-objects.c:3152
 msgid "include tag objects that refer to objects to be packed"
 msgstr "incluir objetos tag que refieren a objetos a ser empaquetados"
 
-#: builtin/pack-objects.c:3014
+#: builtin/pack-objects.c:3154
 msgid "keep unreachable objects"
 msgstr "mantener objetos inalcanzables"
 
-#: builtin/pack-objects.c:3016
+#: builtin/pack-objects.c:3156
 msgid "pack loose unreachable objects"
 msgstr "empaquetar objetos sueltos inalcanzables"
 
-#: builtin/pack-objects.c:3018
+#: builtin/pack-objects.c:3158
 msgid "unpack unreachable objects newer than <time>"
 msgstr "desempaquetar objetos inalcanzables más nuevos que <tiempo>"
 
-#: builtin/pack-objects.c:3021
+#: builtin/pack-objects.c:3161
 msgid "create thin packs"
 msgstr "crear paquetes delgados"
 
-#: builtin/pack-objects.c:3023
+#: builtin/pack-objects.c:3163
 msgid "create packs suitable for shallow fetches"
 msgstr "crear paquetes adecuados para fetches superficiales"
 
-#: builtin/pack-objects.c:3025
+#: builtin/pack-objects.c:3165
 msgid "ignore packs that have companion .keep file"
 msgstr "ignorar paquetes que tienen un archivo .keep acompañante"
 
-#: builtin/pack-objects.c:3027
+#: builtin/pack-objects.c:3167
+msgid "ignore this pack"
+msgstr "ignorar este paquete"
+
+#: builtin/pack-objects.c:3169
 msgid "pack compression level"
 msgstr "nivel de compresión del paquete"
 
-#: builtin/pack-objects.c:3029
+#: builtin/pack-objects.c:3171
 msgid "do not hide commits by grafts"
 msgstr "no ocultar commits por injertos"
 
-#: builtin/pack-objects.c:3031
+#: builtin/pack-objects.c:3173
 msgid "use a bitmap index if available to speed up counting objects"
 msgstr ""
 "usar un índice bitmap si está disponible para acelerar la cuenta de objetos"
 
-#: builtin/pack-objects.c:3033
+#: builtin/pack-objects.c:3175
 msgid "write a bitmap index together with the pack index"
 msgstr "escribir un índice de bitmap junto al índice de paquete"
 
-#: builtin/pack-objects.c:3036
+#: builtin/pack-objects.c:3178
 msgid "handling for missing objects"
 msgstr "manejo de objetos perdidos"
 
-#: builtin/pack-objects.c:3039
+#: builtin/pack-objects.c:3181
 msgid "do not pack objects in promisor packfiles"
 msgstr "no se puede empaquetar objetos en packfiles promisores"
 
-#: builtin/pack-objects.c:3178
-msgid "Counting objects"
-msgstr "Contando objetos"
+#: builtin/pack-objects.c:3205
+#, c-format
+msgid "delta chain depth %d is too deep, forcing %d"
+msgstr "profundidad de cadena de delta %d es muy profunda, forzando %d"
+
+#: builtin/pack-objects.c:3210
+#, c-format
+msgid "pack.deltaCacheLimit is too high, forcing %d"
+msgstr "pack.deltaCacheLimit es muy grande, forzando %d"
+
+#: builtin/pack-objects.c:3338
+msgid "Enumerating objects"
+msgstr "Enumerando objetos"
 
-#: builtin/pack-refs.c:6
+#: builtin/pack-refs.c:7
 msgid "git pack-refs [<options>]"
 msgstr "git pack-refs [<opciones>]"
 
-#: builtin/pack-refs.c:14
+#: builtin/pack-refs.c:15
 msgid "pack everything"
 msgstr "empaquetar todo"
 
-#: builtin/pack-refs.c:15
+#: builtin/pack-refs.c:16
 msgid "prune loose refs (default)"
 msgstr "recortar refs perdidos (default)"
 
@@ -11687,78 +12165,78 @@ msgstr "Removiendo objetos duplicados"
 msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]"
 msgstr "git prune [-n] [-v] [--progress] [--expire <tiempo>] [--] [<head>...]"
 
-#: builtin/prune.c:107
+#: builtin/prune.c:108
 msgid "report pruned objects"
 msgstr "reportar objetos recortados"
 
-#: builtin/prune.c:110
+#: builtin/prune.c:111
 msgid "expire objects older than <time>"
 msgstr "expirar objetos más viejos a <tiempo>"
 
-#: builtin/prune.c:112
+#: builtin/prune.c:113
 msgid "limit traversal to objects outside promisor packfiles"
 msgstr "limitar el recorrido a objetos fuera de los paquetes del promisor"
 
-#: builtin/prune.c:126
+#: builtin/prune.c:127
 msgid "cannot prune in a precious-objects repo"
 msgstr "no se puede recortar en un repositorio de objetos-preciosos"
 
-#: builtin/pull.c:54 builtin/pull.c:56
+#: builtin/pull.c:59 builtin/pull.c:61
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "Valor inválido para %s: %s"
 
-#: builtin/pull.c:76
+#: builtin/pull.c:81
 msgid "git pull [<options>] [<repository> [<refspec>...]]"
 msgstr ""
 "git pull [<opciones>] [<repositorio> [<especificación-de-referencia>...]]"
 
-#: builtin/pull.c:127
+#: builtin/pull.c:132
 msgid "control for recursive fetching of submodules"
 msgstr "control de fetch recursivo en submódulos"
 
-#: builtin/pull.c:131
+#: builtin/pull.c:136
 msgid "Options related to merging"
 msgstr "Opciones relacionadas a fusión"
 
-#: builtin/pull.c:134
+#: builtin/pull.c:139
 msgid "incorporate changes by rebasing rather than merging"
 msgstr "incorporar cambios por rebase en lugar de fusión"
 
-#: builtin/pull.c:161 builtin/rebase--helper.c:23 builtin/revert.c:121
+#: builtin/pull.c:166 builtin/rebase--helper.c:23 builtin/revert.c:121
 msgid "allow fast-forward"
 msgstr "permitir fast-forward"
 
-#: builtin/pull.c:170
+#: builtin/pull.c:175
 msgid "automatically stash/stash pop before and after rebase"
 msgstr "ejecutar automáticamente stash/stash pop antes y después de rebase"
 
-#: builtin/pull.c:186
+#: builtin/pull.c:191
 msgid "Options related to fetching"
 msgstr "Opciones relacionadas a fetch"
 
-#: builtin/pull.c:204
+#: builtin/pull.c:209
 msgid "number of submodules pulled in parallel"
 msgstr "número de submódulos que realizan pull en paralelo"
 
-#: builtin/pull.c:299
+#: builtin/pull.c:304
 #, c-format
 msgid "Invalid value for pull.ff: %s"
 msgstr "Valor inválido para pull.ff: %s"
 
-#: builtin/pull.c:415
+#: builtin/pull.c:420
 msgid ""
 "There is no candidate for rebasing against among the refs that you just "
 "fetched."
 msgstr "No hay candidato para rebasar entre las refs que has bajado con fetch."
 
-#: builtin/pull.c:417
+#: builtin/pull.c:422
 msgid ""
 "There are no candidates for merging among the refs that you just fetched."
 msgstr ""
 "No hay candidatos para fusionar entre las refs que has bajado con fetch."
 
-#: builtin/pull.c:418
+#: builtin/pull.c:423
 msgid ""
 "Generally this means that you provided a wildcard refspec which had no\n"
 "matches on the remote end."
@@ -11767,7 +12245,7 @@ msgstr ""
 "tiene\n"
 "concordancia en el final remoto."
 
-#: builtin/pull.c:421
+#: builtin/pull.c:426
 #, c-format
 msgid ""
 "You asked to pull from the remote '%s', but did not specify\n"
@@ -11778,44 +12256,44 @@ msgstr ""
 "una rama. Porque este no es el remoto configurado por default\n"
 "para tu rama actual, tienes que especificar una rama en la línea de comando."
 
-#: builtin/pull.c:426 git-parse-remote.sh:73
+#: builtin/pull.c:431 git-parse-remote.sh:73
 msgid "You are not currently on a branch."
 msgstr "No te encuentras actualmente en la rama."
 
-#: builtin/pull.c:428 builtin/pull.c:443 git-parse-remote.sh:79
+#: builtin/pull.c:433 builtin/pull.c:448 git-parse-remote.sh:79
 msgid "Please specify which branch you want to rebase against."
 msgstr "Por favor especifica a qué rama quieres rebasar."
 
-#: builtin/pull.c:430 builtin/pull.c:445 git-parse-remote.sh:82
+#: builtin/pull.c:435 builtin/pull.c:450 git-parse-remote.sh:82
 msgid "Please specify which branch you want to merge with."
 msgstr "Por favor especifica a qué rama quieres fusionar."
 
-#: builtin/pull.c:431 builtin/pull.c:446
+#: builtin/pull.c:436 builtin/pull.c:451
 msgid "See git-pull(1) for details."
 msgstr "Ver git-pull(1) para detalles."
 
-#: builtin/pull.c:433 builtin/pull.c:439 builtin/pull.c:448
+#: builtin/pull.c:438 builtin/pull.c:444 builtin/pull.c:453
 #: git-parse-remote.sh:64
 msgid "<remote>"
 msgstr "<remoto>"
 
-#: builtin/pull.c:433 builtin/pull.c:448 builtin/pull.c:453 git-rebase.sh:477
+#: builtin/pull.c:438 builtin/pull.c:453 builtin/pull.c:458 git-rebase.sh:523
 #: git-parse-remote.sh:65
 msgid "<branch>"
 msgstr "<rama>"
 
-#: builtin/pull.c:441 git-parse-remote.sh:75
+#: builtin/pull.c:446 git-parse-remote.sh:75
 msgid "There is no tracking information for the current branch."
 msgstr "No hay información de rastreo para la rama actual."
 
-#: builtin/pull.c:450 git-parse-remote.sh:95
+#: builtin/pull.c:455 git-parse-remote.sh:95
 msgid ""
 "If you wish to set tracking information for this branch you can do so with:"
 msgstr ""
 "Si deseas configurar el rastreo de información para esta rama, puedes "
 "hacerlo con:"
 
-#: builtin/pull.c:455
+#: builtin/pull.c:460
 #, c-format
 msgid ""
 "Your configuration specifies to merge with the ref '%s'\n"
@@ -11824,27 +12302,27 @@ msgstr ""
 "Tu configuración especifica fusionar con la ref '%s'\n"
 "de tu remoto, pero no se pudo hacer fetch a esa ref."
 
-#: builtin/pull.c:819
+#: builtin/pull.c:826
 msgid "ignoring --verify-signatures for rebase"
 msgstr "ignorando --verify-signatures para rebase"
 
-#: builtin/pull.c:867
+#: builtin/pull.c:874
 msgid "--[no-]autostash option is only valid with --rebase."
 msgstr "La opción --[no-]autostash sólo es válida con --rebase."
 
-#: builtin/pull.c:875
+#: builtin/pull.c:882
 msgid "Updating an unborn branch with changes added to the index."
 msgstr "Actualizando una rama no nata con cambios agregados al índice."
 
-#: builtin/pull.c:878
+#: builtin/pull.c:885
 msgid "pull with rebase"
 msgstr "pull con rebase"
 
-#: builtin/pull.c:879
+#: builtin/pull.c:886
 msgid "please commit or stash them."
 msgstr "por favor realiza un commit o un stash con ellos."
 
-#: builtin/pull.c:904
+#: builtin/pull.c:911
 #, c-format
 msgid ""
 "fetch updated the current branch head.\n"
@@ -11855,7 +12333,7 @@ msgstr ""
 "realizando fast-forward al árbol de trabajo\n"
 "desde commit %s."
 
-#: builtin/pull.c:909
+#: builtin/pull.c:916
 #, c-format
 msgid ""
 "Cannot fast-forward your working tree.\n"
@@ -11872,33 +12350,33 @@ msgstr ""
 "$ git reset --hard\n"
 "para recuperar."
 
-#: builtin/pull.c:924
+#: builtin/pull.c:931
 msgid "Cannot merge multiple branches into empty head."
 msgstr "No se puede fusionar múltiples ramas en un head vacío."
 
-#: builtin/pull.c:928
+#: builtin/pull.c:935
 msgid "Cannot rebase onto multiple branches."
 msgstr "No se puede rebasar en múltiples ramas."
 
-#: builtin/pull.c:935
+#: builtin/pull.c:942
 msgid "cannot rebase with locally recorded submodule modifications"
 msgstr ""
 "no se puede rebasar con modificaciones de submódulos grabadas localmente"
 
-#: builtin/push.c:17
+#: builtin/push.c:19
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr ""
 "git push [<opciones>] [<repositorio> [<especificaciones-de-referencia>...]]"
 
-#: builtin/push.c:92
+#: builtin/push.c:111
 msgid "tag shorthand without <tag>"
 msgstr "taquigrafía de tag sin <tag>"
 
-#: builtin/push.c:102
+#: builtin/push.c:121
 msgid "--delete only accepts plain target ref names"
 msgstr "--delete solo acepta como objetivos nombres de ref planos"
 
-#: builtin/push.c:146
+#: builtin/push.c:165
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -11907,7 +12385,7 @@ msgstr ""
 "Para elegir si la opción es permanente, mira push.default en 'git help "
 "config'."
 
-#: builtin/push.c:149
+#: builtin/push.c:168
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -11932,7 +12410,7 @@ msgstr ""
 "\tgit push %s %s\n"
 "%s"
 
-#: builtin/push.c:164
+#: builtin/push.c:183
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -11947,7 +12425,7 @@ msgstr ""
 "\n"
 "\tgit push %s HEAD:<nombre-de-rama-remota>\n"
 
-#: builtin/push.c:178
+#: builtin/push.c:197
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -11961,12 +12439,12 @@ msgstr ""
 "\n"
 "\tgit push --set-upstream %s %s\n"
 
-#: builtin/push.c:186
+#: builtin/push.c:205
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr "La rama actual %s tiene múltiples ramas upstream, rechazando el push."
 
-#: builtin/push.c:189
+#: builtin/push.c:208
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -11977,13 +12455,13 @@ msgstr ""
 "su rama actual '%s', sin decirme qué poner en el push\n"
 "para actualizar en qué rama de remoto."
 
-#: builtin/push.c:248
+#: builtin/push.c:267
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
 "No se especificó ningún refspecs para hacer push, y push.default es \"nada\"."
 
-#: builtin/push.c:255
+#: builtin/push.c:274
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -11995,7 +12473,7 @@ msgstr ""
 "'git pull ...') antes de hacer push de nuevo.\n"
 "Mira 'Note about fast-forwards' en 'git push --help' para mas detalles."
 
-#: builtin/push.c:261
+#: builtin/push.c:280
 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"
@@ -12008,7 +12486,7 @@ msgstr ""
 "(ejem. 'git pull ...') antes de volver a hacer push.\n"
 "Vea las 'Notes about fast-forwards' en 'git push --help' para más detalles."
 
-#: builtin/push.c:267
+#: builtin/push.c:286
 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"
@@ -12022,12 +12500,12 @@ msgstr ""
 "remotos (ej. 'git pull ...') antes de volver a hacer push.\n"
 "Vea 'Notes about fast-forwards0 en 'git push --help' para detalles."
 
-#: builtin/push.c:274
+#: builtin/push.c:293
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr ""
 "Actualizaciones fueron rechazadas porque el tag ya existe en el remoto."
 
-#: builtin/push.c:277
+#: builtin/push.c:296
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -12037,22 +12515,22 @@ msgstr ""
 "o actualizar un ref remoto para hacer que  apunte a un objeto no-commit,\n"
 "sin usar la opción '--force'.\n"
 
-#: builtin/push.c:337
+#: builtin/push.c:357
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "Haciendo push a %s\n"
 
-#: builtin/push.c:341
+#: builtin/push.c:361
 #, c-format
 msgid "failed to push some refs to '%s'"
-msgstr "fallo el push de algunas referencias a '%s'"
+msgstr "falló el push de algunas referencias a '%s'"
 
-#: builtin/push.c:372
+#: builtin/push.c:395
 #, c-format
 msgid "bad repository '%s'"
 msgstr "mal repositorio '%s'"
 
-#: builtin/push.c:373
+#: builtin/push.c:396
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -12074,112 +12552,104 @@ msgstr ""
 "\n"
 "    git push <nombre>\n"
 
-#: builtin/push.c:391
-msgid "--all and --tags are incompatible"
-msgstr "--all y --tags son incompatibles"
-
-#: builtin/push.c:392
-msgid "--all can't be combined with refspecs"
-msgstr "--all no puede ser combinada con refspecs"
-
-#: builtin/push.c:397
-msgid "--mirror and --tags are incompatible"
-msgstr "--mirror y --tags son incompatibles"
-
-#: builtin/push.c:398
-msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror no puede ser combinado con refspecs"
-
-#: builtin/push.c:403
-msgid "--all and --mirror are incompatible"
-msgstr "--all y --mirror son incompatibles"
-
-#: builtin/push.c:535
+#: builtin/push.c:551
 msgid "repository"
 msgstr "repositorio"
 
-#: builtin/push.c:536 builtin/send-pack.c:163
+#: builtin/push.c:552 builtin/send-pack.c:164
 msgid "push all refs"
 msgstr "realizar push a todas las refs"
 
-#: builtin/push.c:537 builtin/send-pack.c:165
+#: builtin/push.c:553 builtin/send-pack.c:166
 msgid "mirror all refs"
 msgstr "realizar mirror a todas las refs"
 
-#: builtin/push.c:539
+#: builtin/push.c:555
 msgid "delete refs"
 msgstr "borrar refs"
 
-#: builtin/push.c:540
+#: builtin/push.c:556
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr "realizar push a tags (no puede ser usado con --all o --mirror)"
 
-#: builtin/push.c:543 builtin/send-pack.c:166
+#: builtin/push.c:559 builtin/send-pack.c:167
 msgid "force updates"
 msgstr "forzar actualizaciones"
 
-#: builtin/push.c:545 builtin/send-pack.c:180
+#: builtin/push.c:561 builtin/send-pack.c:181
 msgid "refname>:<expect"
 msgstr "refname>:<expect"
 
-#: builtin/push.c:546 builtin/send-pack.c:181
+#: builtin/push.c:562 builtin/send-pack.c:182
 msgid "require old value of ref to be at this value"
 msgstr "requiere haber valor viejo de ref en este valor"
 
-#: builtin/push.c:549
+#: builtin/push.c:565
 msgid "control recursive pushing of submodules"
 msgstr "controlar push recursivo de submódulos"
 
-#: builtin/push.c:551 builtin/send-pack.c:174
+#: builtin/push.c:567 builtin/send-pack.c:175
 msgid "use thin pack"
 msgstr "usar empaquetado delgado"
 
-#: builtin/push.c:552 builtin/push.c:553 builtin/send-pack.c:160
-#: builtin/send-pack.c:161
+#: builtin/push.c:568 builtin/push.c:569 builtin/send-pack.c:161
+#: builtin/send-pack.c:162
 msgid "receive pack program"
 msgstr "recibir programa de paquete"
 
-#: builtin/push.c:554
+#: builtin/push.c:570
 msgid "set upstream for git pull/status"
 msgstr "configurar upstream para git pulll/status"
 
-#: builtin/push.c:557
+#: builtin/push.c:573
 msgid "prune locally removed refs"
 msgstr "recortando refs removidas localmente"
 
-#: builtin/push.c:559
+#: builtin/push.c:575
 msgid "bypass pre-push hook"
 msgstr "hacer un bypass al hook pre-push"
 
-#: builtin/push.c:560
+#: builtin/push.c:576
 msgid "push missing but relevant tags"
 msgstr "realizar push de tags faltantes pero relevantes"
 
-#: builtin/push.c:563 builtin/send-pack.c:168
+#: builtin/push.c:579 builtin/send-pack.c:169
 msgid "GPG sign the push"
 msgstr "Firmar con GPG el push"
 
-#: builtin/push.c:565 builtin/send-pack.c:175
+#: builtin/push.c:581 builtin/send-pack.c:176
 msgid "request atomic transaction on remote side"
 msgstr "solicitar transacción atómica en el lado remoto"
 
-#: builtin/push.c:566 builtin/send-pack.c:171
-msgid "server-specific"
-msgstr "especifico-de-servidor"
-
-#: builtin/push.c:566 builtin/send-pack.c:172
-msgid "option to transmit"
-msgstr "opción para trasmitir"
-
-#: builtin/push.c:583
+#: builtin/push.c:599
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr "--delete es incompatible con --all, --mirror y --tags"
 
-#: builtin/push.c:585
+#: builtin/push.c:601
 msgid "--delete doesn't make sense without any refs"
 msgstr "--delete no tiene sentido sin ninguna referencia"
 
 #: builtin/push.c:604
+msgid "--all and --tags are incompatible"
+msgstr "--all y --tags son incompatibles"
+
+#: builtin/push.c:606
+msgid "--all can't be combined with refspecs"
+msgstr "--all no puede ser combinada con refspecs"
+
+#: builtin/push.c:610
+msgid "--mirror and --tags are incompatible"
+msgstr "--mirror y --tags son incompatibles"
+
+#: builtin/push.c:612
+msgid "--mirror can't be combined with refspecs"
+msgstr "--mirror no puede ser combinado con refspecs"
+
+#: builtin/push.c:615
+msgid "--all and --mirror are incompatible"
+msgstr "--all y --mirror son incompatibles"
+
+#: builtin/push.c:634
 msgid "push options must not have new line characters"
 msgstr "opciones de push no pueden tener caracteres de línea nueva"
 
@@ -12194,67 +12664,67 @@ msgstr ""
 "sparse-checkout] [--index-output=<archivo>] (--empty | <árbol-ismo1> [<árbol-"
 "ismo2> [<árbol-ismo3>]])"
 
-#: builtin/read-tree.c:121
+#: builtin/read-tree.c:120
 msgid "write resulting index to <file>"
 msgstr "escribir índice resultante en <archivo>"
 
-#: builtin/read-tree.c:124
+#: builtin/read-tree.c:123
 msgid "only empty the index"
 msgstr "solo vaciar el índice"
 
-#: builtin/read-tree.c:126
+#: builtin/read-tree.c:125
 msgid "Merging"
 msgstr "Fusionando"
 
-#: builtin/read-tree.c:128
+#: builtin/read-tree.c:127
 msgid "perform a merge in addition to a read"
 msgstr "realizar un merge en adición a una lectura"
 
-#: builtin/read-tree.c:130
+#: builtin/read-tree.c:129
 msgid "3-way merge if no file level merging required"
 msgstr "fusión de 3-vías si no se requiere ninguna fusión a nivel de archivo"
 
-#: builtin/read-tree.c:132
+#: builtin/read-tree.c:131
 msgid "3-way merge in presence of adds and removes"
 msgstr "fusión en 3-vías en presencia de adiciones y remociones"
 
-#: builtin/read-tree.c:134
+#: builtin/read-tree.c:133
 msgid "same as -m, but discard unmerged entries"
 msgstr "igual que -m, pero descarta entradas sin fusionar"
 
-#: builtin/read-tree.c:135
+#: builtin/read-tree.c:134
 msgid "<subdirectory>/"
 msgstr "<subdirectorio>/"
 
-#: builtin/read-tree.c:136
+#: builtin/read-tree.c:135
 msgid "read the tree into the index under <subdirectory>/"
 msgstr "lea el árbol en el índice bajo <subdirectorio>/"
 
-#: builtin/read-tree.c:139
+#: builtin/read-tree.c:138
 msgid "update working tree with merge result"
 msgstr "actualiza el árbol de trabajo con el resultado de la fusión"
 
-#: builtin/read-tree.c:141
+#: builtin/read-tree.c:140
 msgid "gitignore"
 msgstr "gitignore"
 
-#: builtin/read-tree.c:142
+#: builtin/read-tree.c:141
 msgid "allow explicitly ignored files to be overwritten"
 msgstr "permitir sobrescritura de archivos explícitamente ignorados"
 
-#: builtin/read-tree.c:145
+#: builtin/read-tree.c:144
 msgid "don't check the working tree after merging"
 msgstr "no revisar el árbol de trabajo tras fusionar"
 
-#: builtin/read-tree.c:146
+#: builtin/read-tree.c:145
 msgid "don't update the index or the work tree"
 msgstr "no actualizar el índice o el árbol de trabajo"
 
-#: builtin/read-tree.c:148
+#: builtin/read-tree.c:147
 msgid "skip applying sparse checkout filter"
 msgstr "saltar aplicado de filtro de sparse checkout"
 
-#: builtin/read-tree.c:150
+#: builtin/read-tree.c:149
 msgid "debug unpack-trees"
 msgstr "debug de árboles-desempacados"
 
@@ -12271,46 +12741,58 @@ msgid "allow commits with empty messages"
 msgstr "permitir commits con mensajes vacíos"
 
 #: builtin/rebase--helper.c:27
+msgid "rebase merge commits"
+msgstr "rebasando commits de fusión"
+
+#: builtin/rebase--helper.c:29
+msgid "keep original branch points of cousins"
+msgstr "mantener puntos originales de la rama de sus primos"
+
+#: builtin/rebase--helper.c:30
 msgid "continue rebase"
 msgstr "continuar rebase"
 
-#: builtin/rebase--helper.c:29
+#: builtin/rebase--helper.c:32
 msgid "abort rebase"
 msgstr "abortar rebase"
 
-#: builtin/rebase--helper.c:32
+#: builtin/rebase--helper.c:35
 msgid "make rebase script"
 msgstr "generar script de rebase"
 
-#: builtin/rebase--helper.c:34
+#: builtin/rebase--helper.c:37
 msgid "shorten commit ids in the todo list"
 msgstr "ids de commits cortos en la lista de pendientes"
 
-#: builtin/rebase--helper.c:36
+#: builtin/rebase--helper.c:39
 msgid "expand commit ids in the todo list"
 msgstr "expandir ids de commits en la lista de pendientes"
 
-#: builtin/rebase--helper.c:38
+#: builtin/rebase--helper.c:41
 msgid "check the todo list"
 msgstr "revisar la lista de pendientes"
 
-#: builtin/rebase--helper.c:40
+#: builtin/rebase--helper.c:43
 msgid "skip unnecessary picks"
 msgstr "saltar los picks innecesarios"
 
-#: builtin/rebase--helper.c:42
+#: builtin/rebase--helper.c:45
 msgid "rearrange fixup/squash lines"
 msgstr "reorganizar líneas fixup/squash"
 
-#: builtin/rebase--helper.c:44
+#: builtin/rebase--helper.c:47
 msgid "insert exec commands in todo list"
 msgstr "insertar comando exec en la lista de pendientes"
 
-#: builtin/receive-pack.c:30
+#: builtin/rebase--helper.c:68
+msgid "--[no-]rebase-cousins has no effect without --rebase-merges"
+msgstr "--[no-]rebase-cousins no tiene efecto sin --rebase-merges"
+
+#: builtin/receive-pack.c:31
 msgid "git receive-pack <git-dir>"
 msgstr "git receive-pack <git-dir>"
 
-#: builtin/receive-pack.c:841
+#: builtin/receive-pack.c:842
 msgid ""
 "By default, updating the current branch in a non-bare repository\n"
 "is denied, because it will make the index and work tree inconsistent\n"
@@ -12343,7 +12825,7 @@ msgstr ""
 "Para suprimir este mensaje y mantener el comportamiento predeterminado,\n"
 "configure 'receive.denyCurrentBranch' a 'refuse'."
 
-#: builtin/receive-pack.c:861
+#: builtin/receive-pack.c:862
 msgid ""
 "By default, deleting the current branch is denied, because the next\n"
 "'git clone' won't result in any file checked out, causing confusion.\n"
@@ -12364,11 +12846,11 @@ msgstr ""
 "\n"
 "Para suprimir este mensaje, puede configurarlo en 'refuse'."
 
-#: builtin/receive-pack.c:1934
+#: builtin/receive-pack.c:1935
 msgid "quiet"
 msgstr "tranquilo"
 
-#: builtin/receive-pack.c:1948
+#: builtin/receive-pack.c:1949
 msgid "You must specify a directory."
 msgstr "Se tiene que especificar un directorio."
 
@@ -12377,11 +12859,11 @@ msgstr "Se tiene que especificar un directorio."
 msgid "'%s' is not a valid timestamp"
 msgstr "'%s' no es una marca de tiempo válida"
 
-#: builtin/remote.c:13
+#: builtin/remote.c:14
 msgid "git remote [-v | --verbose]"
 msgstr "git remote [-v | --verbose]"
 
-#: builtin/remote.c:14
+#: builtin/remote.c:15
 msgid ""
 "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <name> <url>"
@@ -12389,82 +12871,82 @@ msgstr ""
 "git remote add [-t <rama>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <nombre> <url>"
 
-#: builtin/remote.c:15 builtin/remote.c:35
+#: builtin/remote.c:16 builtin/remote.c:36
 msgid "git remote rename <old> <new>"
 msgstr "git remote rename <viejo> <nuevo>"
 
-#: builtin/remote.c:16 builtin/remote.c:40
+#: builtin/remote.c:17 builtin/remote.c:41
 msgid "git remote remove <name>"
 msgstr "git remote remove <nombre>"
 
-#: builtin/remote.c:17 builtin/remote.c:45
+#: builtin/remote.c:18 builtin/remote.c:46
 msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
 msgstr "git remote set-head <nombre> (-a | --auto | -d | --delete | <rama>)"
 
-#: builtin/remote.c:18
+#: builtin/remote.c:19
 msgid "git remote [-v | --verbose] show [-n] <name>"
 msgstr "git remote [-v | --verbose] show [-n] <nombre>"
 
-#: builtin/remote.c:19
+#: builtin/remote.c:20
 msgid "git remote prune [-n | --dry-run] <name>"
 msgstr "git remote prune [-n | --dry-run] <nombre>"
 
-#: builtin/remote.c:20
+#: builtin/remote.c:21
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
 msgstr ""
 "git remote [-v | --verbose] update [-p | --prune] [(<grupo> | <remoto>)...]"
 
-#: builtin/remote.c:21
+#: builtin/remote.c:22
 msgid "git remote set-branches [--add] <name> <branch>..."
 msgstr "git remote set-branches [--add] <nombre> <rama>..."
 
-#: builtin/remote.c:22 builtin/remote.c:71
+#: builtin/remote.c:23 builtin/remote.c:72
 msgid "git remote get-url [--push] [--all] <name>"
 msgstr "git remote get-url [--push] [--all] <nombre>"
 
-#: builtin/remote.c:23 builtin/remote.c:76
+#: builtin/remote.c:24 builtin/remote.c:77
 msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]"
 msgstr "git remote set-url [--push] <nombre> <nuevo-url> [<viejo-url>]"
 
-#: builtin/remote.c:24 builtin/remote.c:77
+#: builtin/remote.c:25 builtin/remote.c:78
 msgid "git remote set-url --add <name> <newurl>"
 msgstr "git remote set-url --add <nombre> <nuevo-url>"
 
-#: builtin/remote.c:25 builtin/remote.c:78
+#: builtin/remote.c:26 builtin/remote.c:79
 msgid "git remote set-url --delete <name> <url>"
 msgstr "git remote set-url --delete <nombre> <url>"
 
-#: builtin/remote.c:30
+#: builtin/remote.c:31
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<opciones>] <nombre> <url>"
 
-#: builtin/remote.c:50
+#: builtin/remote.c:51
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <nombre> <rama>..."
 
-#: builtin/remote.c:51
+#: builtin/remote.c:52
 msgid "git remote set-branches --add <name> <branch>..."
 msgstr "git remote set-branches --add <nombre> <rama>..."
 
-#: builtin/remote.c:56
+#: builtin/remote.c:57
 msgid "git remote show [<options>] <name>"
 msgstr "git remote show [<opciones>] <nombre>"
 
-#: builtin/remote.c:61
+#: builtin/remote.c:62
 msgid "git remote prune [<options>] <name>"
 msgstr "git remote prune [<opciones>] <nombre>"
 
-#: builtin/remote.c:66
+#: builtin/remote.c:67
 msgid "git remote update [<options>] [<group> | <remote>]..."
 msgstr "git remote update [<opciones>] [<grupo> | <remoto>]..."
 
-#: builtin/remote.c:95
+#: builtin/remote.c:96
 #, c-format
 msgid "Updating %s"
 msgstr "Actualizando %s"
 
-#: builtin/remote.c:127
+#: builtin/remote.c:128
 msgid ""
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
@@ -12472,88 +12954,88 @@ msgstr ""
 "Usar --mirror es peligroso y está desaprobado;\n"
 "\t usa más bien --mirror=fetch o --mirror=push"
 
-#: builtin/remote.c:144
+#: builtin/remote.c:145
 #, c-format
 msgid "unknown mirror argument: %s"
 msgstr "argumento mirror desconocido: %s"
 
-#: builtin/remote.c:160
+#: builtin/remote.c:161
 msgid "fetch the remote branches"
 msgstr "realizar fetch a las ramas remotas"
 
-#: builtin/remote.c:162
+#: builtin/remote.c:163
 msgid "import all tags and associated objects when fetching"
 msgstr "importar todos los tags y objetos asociados cuando realiza el fetch"
 
-#: builtin/remote.c:165
+#: builtin/remote.c:166
 msgid "or do not fetch any tag at all (--no-tags)"
 msgstr "o no realziar fetch a ningún tag (--no-tags)"
 
-#: builtin/remote.c:167
+#: builtin/remote.c:168
 msgid "branch(es) to track"
 msgstr "rama(s) para rastrear"
 
-#: builtin/remote.c:168
+#: builtin/remote.c:169
 msgid "master branch"
 msgstr "rama master"
 
-#: builtin/remote.c:169
+#: builtin/remote.c:170
 msgid "push|fetch"
 msgstr "push|fetch"
 
-#: builtin/remote.c:170
+#: builtin/remote.c:171
 msgid "set up remote as a mirror to push to or fetch from"
 msgstr ""
 "configurar remote como mirror para realizar push o desde el cual realizar "
 "fetch"
 
-#: builtin/remote.c:182
+#: builtin/remote.c:183
 msgid "specifying a master branch makes no sense with --mirror"
 msgstr "especificar una rama master no tiene sentido con --mirror"
 
-#: builtin/remote.c:184
+#: builtin/remote.c:185
 msgid "specifying branches to track makes sense only with fetch mirrors"
 msgstr "especificar ramas para rastrear solo tiene sentido con fetch mirrors"
 
-#: builtin/remote.c:191 builtin/remote.c:631
+#: builtin/remote.c:192 builtin/remote.c:634
 #, c-format
 msgid "remote %s already exists."
 msgstr "remoto %s ya existe."
 
-#: builtin/remote.c:195 builtin/remote.c:635
+#: builtin/remote.c:196 builtin/remote.c:638
 #, c-format
 msgid "'%s' is not a valid remote name"
 msgstr "'%s' no es un nombre remoto válido"
 
-#: builtin/remote.c:235
+#: builtin/remote.c:236
 #, c-format
 msgid "Could not setup master '%s'"
 msgstr "No se pudo configurar master '%s'"
 
-#: builtin/remote.c:337
+#: builtin/remote.c:342
 #, c-format
 msgid "Could not get fetch map for refspec %s"
 msgstr "No se pudo realizar el fetch al mapa para refspec %s"
 
-#: builtin/remote.c:438 builtin/remote.c:446
+#: builtin/remote.c:441 builtin/remote.c:449
 msgid "(matching)"
 msgstr "(concordando)"
 
-#: builtin/remote.c:450
+#: builtin/remote.c:453
 msgid "(delete)"
 msgstr "(eliminar)"
 
-#: builtin/remote.c:624 builtin/remote.c:759 builtin/remote.c:858
+#: builtin/remote.c:627 builtin/remote.c:762 builtin/remote.c:861
 #, c-format
 msgid "No such remote: %s"
 msgstr "No existe el remoto: %s"
 
-#: builtin/remote.c:641
+#: builtin/remote.c:644
 #, c-format
 msgid "Could not rename config section '%s' to '%s'"
 msgstr "No se pudo renombrar la sección de configuración '%s' a '%s'"
 
-#: builtin/remote.c:661
+#: builtin/remote.c:664
 #, c-format
 msgid ""
 "Not updating non-default fetch refspec\n"
@@ -12564,17 +13046,17 @@ msgstr ""
 "\t%s\n"
 "\tPor favor actualice la configuración manualmente si es necesario."
 
-#: builtin/remote.c:697
+#: builtin/remote.c:700
 #, c-format
 msgid "deleting '%s' failed"
 msgstr "borrando '%s' falló"
 
-#: builtin/remote.c:731
+#: builtin/remote.c:734
 #, c-format
 msgid "creating '%s' failed"
 msgstr "creando '%s' falló"
 
-#: builtin/remote.c:796
+#: builtin/remote.c:799
 msgid ""
 "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
 "to delete it, use:"
@@ -12589,113 +13071,118 @@ msgstr[1] ""
 "removidas;\n"
 "para borrarlas, use:"
 
-#: builtin/remote.c:810
+#: builtin/remote.c:813
 #, c-format
 msgid "Could not remove config section '%s'"
 msgstr "No se pudo borrar la sección de configuración '%s'"
 
-#: builtin/remote.c:911
+#: builtin/remote.c:914
 #, c-format
 msgid " new (next fetch will store in remotes/%s)"
 msgstr " nuevo (siguiente fetch se guardará en remotes/%s)"
 
-#: builtin/remote.c:914
+#: builtin/remote.c:917
 msgid " tracked"
 msgstr " rastreada"
 
-#: builtin/remote.c:916
+#: builtin/remote.c:919
 msgid " stale (use 'git remote prune' to remove)"
 msgstr " viejo ( use 'git remote prune' para remover)"
 
-#: builtin/remote.c:918
+#: builtin/remote.c:921
 msgid " ???"
 msgstr " ???"
 
-#: builtin/remote.c:959
+#: builtin/remote.c:962
 #, c-format
 msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
 msgstr "invalido branch.%s.merge; no se puede rebasar en > 1 rama"
 
-#: builtin/remote.c:967
+#: builtin/remote.c:971
 #, c-format
 msgid "rebases interactively onto remote %s"
 msgstr "rebasa interactivamente en remoto %s"
 
-#: builtin/remote.c:968
+#: builtin/remote.c:973
+#, c-format
+msgid "rebases interactively (with merges) onto remote %s"
+msgstr "rebasa interactivamente (con fusiones) en remoto %s"
+
+#: builtin/remote.c:976
 #, c-format
 msgid "rebases onto remote %s"
 msgstr "rebasa sobre el remoto %s"
 
-#: builtin/remote.c:971
+#: builtin/remote.c:980
 #, c-format
 msgid " merges with remote %s"
 msgstr " se fusiona con remoto %s"
 
-#: builtin/remote.c:974
+#: builtin/remote.c:983
 #, c-format
 msgid "merges with remote %s"
 msgstr "fusiona con remoto %s"
 
-#: builtin/remote.c:977
+#: builtin/remote.c:986
 #, c-format
 msgid "%-*s    and with remote %s\n"
 msgstr "%-*s y con el remoto %s\n"
 
-#: builtin/remote.c:1020
+#: builtin/remote.c:1029
 msgid "create"
 msgstr "crear"
 
-#: builtin/remote.c:1023
+#: builtin/remote.c:1032
 msgid "delete"
 msgstr "borrar"
 
-#: builtin/remote.c:1027
+#: builtin/remote.c:1036
 msgid "up to date"
 msgstr "actualizado"
 
-#: builtin/remote.c:1030
+#: builtin/remote.c:1039
 msgid "fast-forwardable"
 msgstr "puede realizar fast-forward"
 
-#: builtin/remote.c:1033
+#: builtin/remote.c:1042
 msgid "local out of date"
 msgstr "desactualizado local"
 
-#: builtin/remote.c:1040
+#: builtin/remote.c:1049
 #, c-format
 msgid "    %-*s forces to %-*s (%s)"
 msgstr "    %-*s fuerza a %-*s (%s)"
 
-#: builtin/remote.c:1043
+#: builtin/remote.c:1052
 #, c-format
 msgid "    %-*s pushes to %-*s (%s)"
 msgstr "    %-*s publica a %-*s (%s)"
 
-#: builtin/remote.c:1047
+#: builtin/remote.c:1056
 #, c-format
 msgid "    %-*s forces to %s"
 msgstr "    %-*s fuerza a %s"
 
-#: builtin/remote.c:1050
+#: builtin/remote.c:1059
 #, c-format
 msgid "    %-*s pushes to %s"
 msgstr "    %-*s publica a %s"
 
-#: builtin/remote.c:1118
+#: builtin/remote.c:1127
 msgid "do not query remotes"
 msgstr "no consultar remotos"
 
-#: builtin/remote.c:1145
+#: builtin/remote.c:1154
 #, c-format
 msgid "* remote %s"
 msgstr "* remoto %s"
 
-#: builtin/remote.c:1146
+#: builtin/remote.c:1155
 #, c-format
 msgid "  Fetch URL: %s"
 msgstr "  URL  para obtener: %s"
 
-#: builtin/remote.c:1147 builtin/remote.c:1163 builtin/remote.c:1302
+#: builtin/remote.c:1156 builtin/remote.c:1172 builtin/remote.c:1311
 msgid "(no URL)"
 msgstr "(sin URL)"
 
@@ -12703,185 +13190,185 @@ msgstr "(sin URL)"
 #. with the one in " Fetch URL: %s"
 #. translation.
 #.
-#: builtin/remote.c:1161 builtin/remote.c:1163
+#: builtin/remote.c:1170 builtin/remote.c:1172
 #, c-format
 msgid "  Push  URL: %s"
 msgstr "  URL para publicar: %s"
 
-#: builtin/remote.c:1165 builtin/remote.c:1167 builtin/remote.c:1169
+#: builtin/remote.c:1174 builtin/remote.c:1176 builtin/remote.c:1178
 #, c-format
 msgid "  HEAD branch: %s"
 msgstr "  Rama HEAD: %s"
 
-#: builtin/remote.c:1165
+#: builtin/remote.c:1174
 msgid "(not queried)"
 msgstr "(no consultado)"
 
-#: builtin/remote.c:1167
+#: builtin/remote.c:1176
 msgid "(unknown)"
 msgstr "(desconocido)"
 
-#: builtin/remote.c:1171
+#: builtin/remote.c:1180
 #, c-format
 msgid ""
 "  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
 msgstr ""
 "  HEAD en rama ( HEAD remoto es ambiguo, puede ser uno de los siguientes):\n"
 
-#: builtin/remote.c:1183
+#: builtin/remote.c:1192
 #, c-format
 msgid "  Remote branch:%s"
 msgid_plural "  Remote branches:%s"
 msgstr[0] "  Rama remota:%s"
 msgstr[1] "  Ramas remotas:%s"
 
-#: builtin/remote.c:1186 builtin/remote.c:1212
+#: builtin/remote.c:1195 builtin/remote.c:1221
 msgid " (status not queried)"
 msgstr " (estado no consultado)"
 
-#: builtin/remote.c:1195
+#: builtin/remote.c:1204
 msgid "  Local branch configured for 'git pull':"
 msgid_plural "  Local branches configured for 'git pull':"
 msgstr[0] "  Rama local configurada para 'git pull':"
 msgstr[1] "  Ramas locales configuradas para 'git pull':"
 
-#: builtin/remote.c:1203
+#: builtin/remote.c:1212
 msgid "  Local refs will be mirrored by 'git push'"
 msgstr "  Las referencias locales serán reflejadas por 'git push'"
 
-#: builtin/remote.c:1209
+#: builtin/remote.c:1218
 #, c-format
 msgid "  Local ref configured for 'git push'%s:"
 msgid_plural "  Local refs configured for 'git push'%s:"
 msgstr[0] "  Referencia local configurada para 'git push'%s:"
 msgstr[1] "  Referencias locales configuradas para 'git push'%s:"
 
-#: builtin/remote.c:1230
+#: builtin/remote.c:1239
 msgid "set refs/remotes/<name>/HEAD according to remote"
 msgstr "configurar refs/remotes/<nombre>/HEAD de acuerdo al remoto"
 
-#: builtin/remote.c:1232
+#: builtin/remote.c:1241
 msgid "delete refs/remotes/<name>/HEAD"
 msgstr "borrar refs/remotos/<nombre>/HEAD"
 
-#: builtin/remote.c:1247
+#: builtin/remote.c:1256
 msgid "Cannot determine remote HEAD"
 msgstr "No se puede determinar el HEAD remoto"
 
-#: builtin/remote.c:1249
+#: builtin/remote.c:1258
 msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
 msgstr "Múltiples ramas HEAD remotas. Por favor escoja una explícitamente con:"
 
-#: builtin/remote.c:1259
+#: builtin/remote.c:1268
 #, c-format
 msgid "Could not delete %s"
 msgstr "No se pudo borrar %s"
 
-#: builtin/remote.c:1267
+#: builtin/remote.c:1276
 #, c-format
 msgid "Not a valid ref: %s"
 msgstr "No es un ref válido: %s"
 
-#: builtin/remote.c:1269
+#: builtin/remote.c:1278
 #, c-format
 msgid "Could not setup %s"
 msgstr "No se pudo configurar %s"
 
-#: builtin/remote.c:1287
+#: builtin/remote.c:1296
 #, c-format
 msgid " %s will become dangling!"
 msgstr " %s será colgado!"
 
-#: builtin/remote.c:1288
+#: builtin/remote.c:1297
 #, c-format
 msgid " %s has become dangling!"
 msgstr " %s ha sido colgado!"
 
-#: builtin/remote.c:1298
+#: builtin/remote.c:1307
 #, c-format
 msgid "Pruning %s"
 msgstr "Recortando %s"
 
-#: builtin/remote.c:1299
+#: builtin/remote.c:1308
 #, c-format
 msgid "URL: %s"
 msgstr "URL: %s"
 
-#: builtin/remote.c:1315
+#: builtin/remote.c:1324
 #, c-format
 msgid " * [would prune] %s"
 msgstr " * [ejecutará prune] %s"
 
-#: builtin/remote.c:1318
+#: builtin/remote.c:1327
 #, c-format
 msgid " * [pruned] %s"
 msgstr " * [prune realizado] %s"
 
-#: builtin/remote.c:1363
+#: builtin/remote.c:1372
 msgid "prune remotes after fetching"
 msgstr "recortar remotos tras realizar fetch"
 
-#: builtin/remote.c:1426 builtin/remote.c:1480 builtin/remote.c:1548
+#: builtin/remote.c:1435 builtin/remote.c:1489 builtin/remote.c:1557
 #, c-format
 msgid "No such remote '%s'"
 msgstr "No existe el remoto '%s'"
 
-#: builtin/remote.c:1442
+#: builtin/remote.c:1451
 msgid "add branch"
 msgstr "agregar rama"
 
-#: builtin/remote.c:1449
+#: builtin/remote.c:1458
 msgid "no remote specified"
 msgstr "no hay remotos especificados"
 
-#: builtin/remote.c:1466
+#: builtin/remote.c:1475
 msgid "query push URLs rather than fetch URLs"
 msgstr "consultar URLs de push en lugar de URLs de fetch"
 
-#: builtin/remote.c:1468
+#: builtin/remote.c:1477
 msgid "return all URLs"
 msgstr "retornar todos los URLs"
 
-#: builtin/remote.c:1496
+#: builtin/remote.c:1505
 #, c-format
 msgid "no URLs configured for remote '%s'"
 msgstr "no hay URLs configurados para remoto '%s'"
 
-#: builtin/remote.c:1522
+#: builtin/remote.c:1531
 msgid "manipulate push URLs"
 msgstr "manipular URLs de push"
 
-#: builtin/remote.c:1524
+#: builtin/remote.c:1533
 msgid "add URL"
 msgstr "agregar URL"
 
-#: builtin/remote.c:1526
+#: builtin/remote.c:1535
 msgid "delete URLs"
 msgstr "borrar URLs"
 
-#: builtin/remote.c:1533
+#: builtin/remote.c:1542
 msgid "--add --delete doesn't make sense"
 msgstr "--add --delete no tiene sentido"
 
-#: builtin/remote.c:1572
+#: builtin/remote.c:1581
 #, c-format
 msgid "Invalid old URL pattern: %s"
 msgstr "Patrón de URL viejo inválido: %s"
 
-#: builtin/remote.c:1580
+#: builtin/remote.c:1589
 #, c-format
 msgid "No such URL found: %s"
 msgstr "No se encontró URL: %s"
 
-#: builtin/remote.c:1582
+#: builtin/remote.c:1591
 msgid "Will not delete all non-push URLs"
 msgstr "No borrará todos los URLs de no-push"
 
-#: builtin/remote.c:1598
+#: builtin/remote.c:1607
 msgid "be verbose; must be placed before a subcommand"
 msgstr "ser verboso; tiene que ser agregado antes de un subcomando"
 
-#: builtin/remote.c:1629
+#: builtin/remote.c:1638
 #, c-format
 msgid "Unknown subcommand: %s"
 msgstr "Sub-comando desconocido: %s"
@@ -12898,129 +13385,137 @@ msgstr ""
 "Re empaquetados incrementales son incompatibles con índices bitmap. Use \n"
 "--no-write-bitmap-index o deshabilite la configuración pack.writebitmaps."
 
-#: builtin/repack.c:170
+#: builtin/repack.c:180
 msgid "pack everything in a single pack"
 msgstr "empaquetar todo en un único paquete"
 
-#: builtin/repack.c:172
+#: builtin/repack.c:182
 msgid "same as -a, and turn unreachable objects loose"
 msgstr "lo mismo que -a, y pierde objetos inaccesibles"
 
-#: builtin/repack.c:175
+#: builtin/repack.c:185
 msgid "remove redundant packs, and run git-prune-packed"
 msgstr "remover paquetes redundantes, y ejecutar git-prune-packed"
 
-#: builtin/repack.c:177
+#: builtin/repack.c:187
 msgid "pass --no-reuse-delta to git-pack-objects"
 msgstr "pasar --no-reuse-delta a git-pack-objects"
 
-#: builtin/repack.c:179
+#: builtin/repack.c:189
 msgid "pass --no-reuse-object to git-pack-objects"
 msgstr "pasar --no-reuse-object a git-pack-objects"
 
-#: builtin/repack.c:181
+#: builtin/repack.c:191
 msgid "do not run git-update-server-info"
 msgstr "no ejecutar git-update-server-info"
 
-#: builtin/repack.c:184
+#: builtin/repack.c:194
 msgid "pass --local to git-pack-objects"
 msgstr "pasar --local a git-pack-objects"
 
-#: builtin/repack.c:186
+#: builtin/repack.c:196
 msgid "write bitmap index"
 msgstr "escribir un índice de bitmap"
 
-#: builtin/repack.c:187
+#: builtin/repack.c:197
 msgid "approxidate"
 msgstr "aproxime"
 
-#: builtin/repack.c:188
+#: builtin/repack.c:198
 msgid "with -A, do not loosen objects older than this"
 msgstr "con -A, no perder objetos más antiguos que este"
 
-#: builtin/repack.c:190
+#: builtin/repack.c:200
 msgid "with -a, repack unreachable objects"
 msgstr "con -a, re empaquetar objetos inalcanzables"
 
-#: builtin/repack.c:192
+#: builtin/repack.c:202
 msgid "size of the window used for delta compression"
 msgstr "tamaño de la ventana usado para la compresión delta"
 
-#: builtin/repack.c:193 builtin/repack.c:199
+#: builtin/repack.c:203 builtin/repack.c:209
 msgid "bytes"
 msgstr "bytes"
 
-#: builtin/repack.c:194
+#: builtin/repack.c:204
 msgid "same as the above, but limit memory size instead of entries count"
 msgstr ""
 "lo mismo que arriba, pero limita el tamaño de memoria en lugar de contar "
 "entradas"
 
-#: builtin/repack.c:196
+#: builtin/repack.c:206
 msgid "limits the maximum delta depth"
 msgstr "limita la profundidad máxima del delta"
 
-#: builtin/repack.c:198
+#: builtin/repack.c:208
 msgid "limits the maximum number of threads"
 msgstr "limita el número máximo de hilos"
 
-#: builtin/repack.c:200
+#: builtin/repack.c:210
 msgid "maximum size of each packfile"
 msgstr "tamaño máximo de cada paquete"
 
-#: builtin/repack.c:202
+#: builtin/repack.c:212
 msgid "repack objects in packs marked with .keep"
 msgstr "re-empaquetar objetos en paquetes marcados con .keep"
 
-#: builtin/repack.c:212
+#: builtin/repack.c:214
+msgid "do not repack this pack"
+msgstr "no reempaquetar este paquete"
+
+#: builtin/repack.c:224
 msgid "cannot delete packs in a precious-objects repo"
 msgstr "no se pueden borrar paquetes en un repositorio de objetos-preciosos"
 
-#: builtin/repack.c:216
+#: builtin/repack.c:228
 msgid "--keep-unreachable and -A are incompatible"
 msgstr "--keep-unreachable y -A son incompatibles"
 
-#: builtin/repack.c:410 builtin/worktree.c:148
+#: builtin/repack.c:425 builtin/worktree.c:139
 #, c-format
 msgid "failed to remove '%s'"
 msgstr "falló al remover '%s'"
 
-#: builtin/replace.c:20
+#: builtin/replace.c:22
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <objeto> <remplazo>"
 
-#: builtin/replace.c:21
+#: builtin/replace.c:23
 msgid "git replace [-f] --edit <object>"
 msgstr "git replace [-f] --edit <objeto>"
 
-#: builtin/replace.c:22
+#: builtin/replace.c:24
 msgid "git replace [-f] --graft <commit> [<parent>...]"
 msgstr "git replace [-f] --graft <commit> [<padre>...]"
 
-#: builtin/replace.c:23
+#: builtin/replace.c:25
+msgid "git replace [-f] --convert-graft-file"
+msgstr "git replace [-f] --convert-graft-file"
+
+#: builtin/replace.c:26
 msgid "git replace -d <object>..."
 msgstr "git replace -d <objeto>..."
 
-#: builtin/replace.c:24
+#: builtin/replace.c:27
 msgid "git replace [--format=<format>] [-l [<pattern>]]"
 msgstr "git replace [--format=<formato>] [-l [<patrón>]]"
 
-#: builtin/replace.c:331 builtin/replace.c:369 builtin/replace.c:397
+#: builtin/replace.c:371 builtin/replace.c:415 builtin/replace.c:445
 #, c-format
 msgid "Not a valid object name: '%s'"
 msgstr "Nombre de objeto no válido: '%s'"
 
-#: builtin/replace.c:361
+#: builtin/replace.c:407
 #, c-format
 msgid "bad mergetag in commit '%s'"
 msgstr "mal mergetag en commit '%s'"
 
-#: builtin/replace.c:363
+#: builtin/replace.c:409
 #, c-format
 msgid "malformed mergetag in commit '%s'"
 msgstr "mergetag mal formado en commit '%s'"
 
-#: builtin/replace.c:374
+#: builtin/replace.c:421
 #, c-format
 msgid ""
 "original commit '%s' contains mergetag '%s' that is discarded; use --edit "
@@ -13029,45 +13524,58 @@ msgstr ""
 "commit original '%s' contiene un mergetag '%s' que es descartado; use --edit "
 "en lugar de --graft"
 
-#: builtin/replace.c:407
+#: builtin/replace.c:460
 #, c-format
 msgid "the original commit '%s' has a gpg signature."
 msgstr "el commit original '%s' tiene una firma gpg."
 
-#: builtin/replace.c:408
+#: builtin/replace.c:461
 msgid "the signature will be removed in the replacement commit!"
 msgstr "la firma será removida en el commit de reemplazo!"
 
-#: builtin/replace.c:414
+#: builtin/replace.c:471
 #, c-format
 msgid "could not write replacement commit for: '%s'"
 msgstr "no se pudo escribir el commit de reemplazo: '%s'"
 
-#: builtin/replace.c:438
+#: builtin/replace.c:514
+#, c-format
+msgid ""
+"could not convert the following graft(s):\n"
+"%s"
+msgstr ""
+"no se pudo convertir el siguiente graft(s):\n"
+"%s"
+
+#: builtin/replace.c:535
 msgid "list replace refs"
 msgstr "listar replace refs"
 
-#: builtin/replace.c:439
+#: builtin/replace.c:536
 msgid "delete replace refs"
 msgstr "borrar replace refs"
 
-#: builtin/replace.c:440
+#: builtin/replace.c:537
 msgid "edit existing object"
 msgstr "editar objeto existente"
 
-#: builtin/replace.c:441
+#: builtin/replace.c:538
 msgid "change a commit's parents"
 msgstr "cambiar un padre de commit"
 
-#: builtin/replace.c:442
+#: builtin/replace.c:539
+msgid "convert existing graft file"
+msgstr "convertir archivo graft existente"
+
+#: builtin/replace.c:540
 msgid "replace the ref if it exists"
 msgstr "reemplazar el ref si este existe"
 
-#: builtin/replace.c:444
+#: builtin/replace.c:542
 msgid "do not pretty-print contents for --edit"
 msgstr "no se puede imprimir contenidos para --edit"
 
-#: builtin/replace.c:445
+#: builtin/replace.c:543
 msgid "use this format"
 msgstr "usar este formato"
 
@@ -13228,23 +13736,23 @@ msgstr "rev-list no soporta mostrar notas"
 msgid "cannot combine --use-bitmap-index with object filtering"
 msgstr "no se puede combinar --use-bitmap-index con objetos de filtrado"
 
-#: builtin/rev-parse.c:402
+#: builtin/rev-parse.c:406
 msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
 msgstr "git rev-parse --parseopt [<opciones>] -- [<args>...]"
 
-#: builtin/rev-parse.c:407
+#: builtin/rev-parse.c:411
 msgid "keep the `--` passed as an arg"
 msgstr "mantener el `--` pasado como un arg"
 
-#: builtin/rev-parse.c:409
+#: builtin/rev-parse.c:413
 msgid "stop parsing after the first non-option argument"
 msgstr "detener análisis tras el primer argumento que no es opción"
 
-#: builtin/rev-parse.c:412
+#: builtin/rev-parse.c:416
 msgid "output in stuck long form"
 msgstr "salida en formulario largo de atasco"
 
-#: builtin/rev-parse.c:545
+#: builtin/rev-parse.c:549
 msgid ""
 "git rev-parse --parseopt [<options>] -- [<args>...]\n"
 "   or: git rev-parse --sq-quote [<arg>...]\n"
@@ -13386,42 +13894,42 @@ msgid_plural "the following files have local modifications:"
 msgstr[0] "el siguiente archivo tiene modificaciones locales:"
 msgstr[1] "los siguientes archivos tienen modificaciones locales:"
 
-#: builtin/rm.c:243
+#: builtin/rm.c:241
 msgid "do not list removed files"
 msgstr "no listar archivos removidos"
 
-#: builtin/rm.c:244
+#: builtin/rm.c:242
 msgid "only remove from the index"
 msgstr "solo remover del índice"
 
-#: builtin/rm.c:245
+#: builtin/rm.c:243
 msgid "override the up-to-date check"
 msgstr "sobrescribir el check de actualizado"
 
-#: builtin/rm.c:246
+#: builtin/rm.c:244
 msgid "allow recursive removal"
 msgstr "permitir remover de forma recursiva"
 
-#: builtin/rm.c:248
+#: builtin/rm.c:246
 msgid "exit with a zero status even if nothing matched"
 msgstr "salir con estado cero incluso si nada coincide"
 
-#: builtin/rm.c:307
+#: builtin/rm.c:306
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "no removiendo '%s' de manera recursiva sin -r"
 
-#: builtin/rm.c:346
+#: builtin/rm.c:345
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm: no es posible remover %s"
 
-#: builtin/rm.c:369
+#: builtin/rm.c:368
 #, c-format
 msgid "could not remove '%s'"
 msgstr "no se pudo remover '%s'"
 
-#: builtin/send-pack.c:19
+#: builtin/send-pack.c:20
 msgid ""
 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-"
 "receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> "
@@ -13433,50 +13941,70 @@ msgstr ""
 "[<ref>...]\n"
 "  --all y especificaciones <ref> explícitas son mutuamente exclusivas."
 
-#: builtin/send-pack.c:162
+#: builtin/send-pack.c:163
 msgid "remote name"
 msgstr "nombre remoto"
 
-#: builtin/send-pack.c:176
+#: builtin/send-pack.c:177
 msgid "use stateless RPC protocol"
 msgstr "usar protocolo RPC sin estado"
 
-#: builtin/send-pack.c:177
+#: builtin/send-pack.c:178
 msgid "read refs from stdin"
 msgstr "leer refs de stdin"
 
-#: builtin/send-pack.c:178
+#: builtin/send-pack.c:179
 msgid "print status from remote helper"
 msgstr "mostrar status del remote helper"
 
+#: builtin/serve.c:7
+msgid "git serve [<options>]"
+msgstr "git serve [<opciones>]"
+
+#: builtin/serve.c:17 builtin/upload-pack.c:23
+msgid "quit after a single request/response exchange"
+msgstr "sale después de un intercambio petición/respuesta único"
+
+#: builtin/serve.c:19
+msgid "exit immediately after advertising capabilities"
+msgstr "salir inmediatamente tras anunciar capacidades"
+
 #: builtin/shortlog.c:14
-msgid "git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"
-msgstr "git shortlog [<opciones>] [<rango-de-revisión>] [[--] [<ruta>...]]"
+msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]"
+msgstr "git shortlog [<opciones>] [<rango-de-revisión>] [[--] <ruta>...]"
+
+#: builtin/shortlog.c:15
+msgid "git log --pretty=short | git shortlog [<options>]"
+msgstr "git log --pretty=short | git shorlog [<opciones>]"
 
-#: builtin/shortlog.c:263
+#: builtin/shortlog.c:264
 msgid "Group by committer rather than author"
 msgstr "Agrupar por committer en lugar de autor"
 
-#: builtin/shortlog.c:265
+#: builtin/shortlog.c:266
 msgid "sort output according to the number of commits per author"
 msgstr "ordenar salida de acuerdo al número de commits por autor"
 
-#: builtin/shortlog.c:267
+#: builtin/shortlog.c:268
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr "Suprimir descripción de commits, solo proveer cuenta de commits"
 
-#: builtin/shortlog.c:269
+#: builtin/shortlog.c:270
 msgid "Show the email address of each author"
 msgstr "Mostrar la dirección de correo de cada autor"
 
-#: builtin/shortlog.c:270
+#: builtin/shortlog.c:271
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:271
+#: builtin/shortlog.c:272
 msgid "Linewrap output"
 msgstr "Salida de línea"
 
+#: builtin/shortlog.c:298
+msgid "too many arguments given outside repository"
+msgstr "demasiados argumentos dados fuera del repositorio"
+
 #: builtin/show-branch.c:12
 msgid ""
 "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
@@ -13673,39 +14201,39 @@ msgstr ""
 msgid "prepend comment character and space to each line"
 msgstr "anteponer carácter de comentario y espacio a cada línea"
 
-#: builtin/submodule--helper.c:35 builtin/submodule--helper.c:1669
+#: builtin/submodule--helper.c:37 builtin/submodule--helper.c:1688
 #, c-format
 msgid "No such ref: %s"
 msgstr "No existe ref: %s"
 
-#: builtin/submodule--helper.c:42 builtin/submodule--helper.c:1678
+#: builtin/submodule--helper.c:44 builtin/submodule--helper.c:1697
 #, c-format
 msgid "Expecting a full ref name, got %s"
 msgstr "Se esperaba un nombre de ref completo, se obtuvo %s"
 
-#: builtin/submodule--helper.c:59
+#: builtin/submodule--helper.c:61
 msgid "submodule--helper print-default-remote takes no arguments"
 msgstr "subomdule--helper print-default-remote no toma argumentos"
 
-#: builtin/submodule--helper.c:96
+#: builtin/submodule--helper.c:98
 #, c-format
 msgid "cannot strip one component off url '%s'"
 msgstr "no se puede quitar un componente del url '%s'"
 
-#: builtin/submodule--helper.c:404 builtin/submodule--helper.c:1198
+#: builtin/submodule--helper.c:406 builtin/submodule--helper.c:1211
 msgid "alternative anchor for relative paths"
 msgstr "ancho alternativo para rutas relativas"
 
-#: builtin/submodule--helper.c:409
+#: builtin/submodule--helper.c:411
 msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper list [--prefix=<ruta>] [<ruta>...]"
 
-#: builtin/submodule--helper.c:460 builtin/submodule--helper.c:483
+#: builtin/submodule--helper.c:462 builtin/submodule--helper.c:485
 #, c-format
 msgid "No url found for submodule path '%s' in .gitmodules"
 msgstr "No se encontró url para la ruta del submódulo '%s' en .gitmodules"
 
-#: builtin/submodule--helper.c:498
+#: builtin/submodule--helper.c:500
 #, c-format
 msgid ""
 "could not lookup configuration '%s'. Assuming this repository is its own "
@@ -13714,57 +14242,57 @@ msgstr ""
 "no se pudo encontrar configuración '%s'. Asumiendo que este repositorio es "
 "su propio upstream autoritativo."
 
-#: builtin/submodule--helper.c:509
+#: builtin/submodule--helper.c:511
 #, c-format
 msgid "Failed to register url for submodule path '%s'"
 msgstr "Falló al registrar el url para la ruta del submódulo '%s'"
 
-#: builtin/submodule--helper.c:513
+#: builtin/submodule--helper.c:515
 #, c-format
 msgid "Submodule '%s' (%s) registered for path '%s'\n"
 msgstr "Submódulo '%s' (%s) registrado para ruta '%s'\n"
 
-#: builtin/submodule--helper.c:523
+#: builtin/submodule--helper.c:525
 #, c-format
 msgid "warning: command update mode suggested for submodule '%s'\n"
 msgstr ""
 "peligro: modo de actualización de comandos sugerido para el submódulo '%s'\n"
 
-#: builtin/submodule--helper.c:530
+#: builtin/submodule--helper.c:532
 #, c-format
 msgid "Failed to register update mode for submodule path '%s'"
 msgstr ""
 "Error al registrar el modo de actualización para la ruta del submódulo '%s'"
 
-#: builtin/submodule--helper.c:552
+#: builtin/submodule--helper.c:554
 msgid "Suppress output for initializing a submodule"
 msgstr "Suprime la salida para inicializar un submódulo"
 
-#: builtin/submodule--helper.c:557
+#: builtin/submodule--helper.c:559
 msgid "git submodule--helper init [<path>]"
 msgstr "git submodule--helper init [<ruta>]"
 
-#: builtin/submodule--helper.c:625 builtin/submodule--helper.c:747
+#: builtin/submodule--helper.c:631 builtin/submodule--helper.c:757
 #, c-format
 msgid "no submodule mapping found in .gitmodules for path '%s'"
 msgstr ""
 "no se ha encontrado mapeo de submódulos en .gitmodules para la ruta '%s'"
 
-#: builtin/submodule--helper.c:660
+#: builtin/submodule--helper.c:670
 #, c-format
 msgid "could not resolve HEAD ref inside the submodule '%s'"
 msgstr "no pudo resolver ref de HEAD dentro del submódulo '%s'"
 
-#: builtin/submodule--helper.c:687 builtin/submodule--helper.c:856
+#: builtin/submodule--helper.c:697 builtin/submodule--helper.c:866
 #, c-format
 msgid "failed to recurse into submodule '%s'"
 msgstr "falló al recursar en el submódulo '%s'"
 
-#: builtin/submodule--helper.c:711 builtin/submodule--helper.c:1021
+#: builtin/submodule--helper.c:721 builtin/submodule--helper.c:1031
 msgid "Suppress submodule status output"
 msgstr "Suprimir output del estado del submódulo"
 
-#: builtin/submodule--helper.c:712
+#: builtin/submodule--helper.c:722
 msgid ""
 "Use commit stored in the index instead of the one stored in the submodule "
 "HEAD"
@@ -13772,51 +14300,51 @@ msgstr ""
 "Usar el commit guardado en el índice en lugar del guardado en el submódulo "
 "HEAD"
 
-#: builtin/submodule--helper.c:713
+#: builtin/submodule--helper.c:723
 msgid "recurse into nested submodules"
 msgstr "recursar en submódulos anidados"
 
-#: builtin/submodule--helper.c:718
+#: builtin/submodule--helper.c:728
 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
 msgstr "git submodule status [--quiet] [--cached] [--recursive] [<ruta>...]"
 
-#: builtin/submodule--helper.c:742
+#: builtin/submodule--helper.c:752
 msgid "git submodule--helper name <path>"
 msgstr "git submodule--helper name <ruta>"
 
-#: builtin/submodule--helper.c:806
+#: builtin/submodule--helper.c:816
 #, c-format
 msgid "Synchronizing submodule url for '%s'\n"
 msgstr "Sincronizando url del submódulo para '%s'\n"
 
-#: builtin/submodule--helper.c:812
+#: builtin/submodule--helper.c:822
 #, c-format
 msgid "failed to register url for submodule path '%s'"
 msgstr "falló al registrar el url para la ruta del submódulo '%s'"
 
-#: builtin/submodule--helper.c:826
+#: builtin/submodule--helper.c:836
 #, c-format
 msgid "failed to get the default remote for submodule '%s'"
 msgstr "error al conseguir el remoto por defecto para el submódulo '%s'"
 
-#: builtin/submodule--helper.c:837
+#: builtin/submodule--helper.c:847
 #, c-format
 msgid "failed to update remote for submodule '%s'"
 msgstr "error al actualizar el remoto para el submódulo '%s'"
 
-#: builtin/submodule--helper.c:885
+#: builtin/submodule--helper.c:895
 msgid "Suppress output of synchronizing submodule url"
 msgstr "Suprime la salida del url del submódulo que se sincroniza"
 
-#: builtin/submodule--helper.c:887
+#: builtin/submodule--helper.c:897
 msgid "Recurse into nested submodules"
 msgstr "Recursar en submódulos anidados"
 
-#: builtin/submodule--helper.c:892
+#: builtin/submodule--helper.c:902
 msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
 msgstr "git submodule--helper sync [--quiet] [--recursive] [<ruta>]"
 
-#: builtin/submodule--helper.c:946
+#: builtin/submodule--helper.c:956
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you "
@@ -13825,7 +14353,7 @@ msgstr ""
 "El árbol de trabajo del submódulo '%s' contiene un directorio .git (use 'rm -"
 "rf' si realmente quiere removerlo incluyendo todo en su historia)"
 
-#: builtin/submodule--helper.c:958
+#: builtin/submodule--helper.c:968
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains local modifications; use '-f' to discard "
@@ -13834,81 +14362,81 @@ msgstr ""
 "El árbol de trabajo del submódulo '%s' contiene modificaciones locales; usa "
 "'-f' para descartarlas"
 
-#: builtin/submodule--helper.c:966
+#: builtin/submodule--helper.c:976
 #, c-format
 msgid "Cleared directory '%s'\n"
 msgstr "Directorio '%s' limpiado\n"
 
-#: builtin/submodule--helper.c:968
+#: builtin/submodule--helper.c:978
 #, c-format
 msgid "Could not remove submodule work tree '%s'\n"
 msgstr "No se pudo eliminar el árbol de trabajo del submódulo '%s'\n"
 
-#: builtin/submodule--helper.c:977
+#: builtin/submodule--helper.c:987
 #, c-format
 msgid "could not create empty submodule directory %s"
 msgstr "no se pudo crear directorio vacío de submódulo %s"
 
-#: builtin/submodule--helper.c:993
+#: builtin/submodule--helper.c:1003
 #, c-format
 msgid "Submodule '%s' (%s) unregistered for path '%s'\n"
 msgstr "Submódulo '%s' (%s) no registrado para ruta '%s'\n"
 
-#: builtin/submodule--helper.c:1022
+#: builtin/submodule--helper.c:1032
 msgid "Remove submodule working trees even if they contain local changes"
 msgstr ""
 "Remover arboles de trabajo de submódulos incluso si contienen cambios locales"
 
-#: builtin/submodule--helper.c:1023
+#: builtin/submodule--helper.c:1033
 msgid "Unregister all submodules"
 msgstr "Quitar todos los submódulos"
 
-#: builtin/submodule--helper.c:1028
+#: builtin/submodule--helper.c:1038
 msgid ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
 msgstr ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<ruta>...]]"
 
-#: builtin/submodule--helper.c:1042
+#: builtin/submodule--helper.c:1052
 msgid "Use '--all' if you really want to deinitialize all submodules"
 msgstr "Usa '--all' si realmente quieres des-inicializar todos los submódulos"
 
-#: builtin/submodule--helper.c:1133 builtin/submodule--helper.c:1136
+#: builtin/submodule--helper.c:1145 builtin/submodule--helper.c:1148
 #, c-format
 msgid "submodule '%s' cannot add alternate: %s"
 msgstr "submódulo '%s' no puede agregar alterno: %s"
 
-#: builtin/submodule--helper.c:1172
+#: builtin/submodule--helper.c:1184
 #, c-format
 msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized"
 msgstr "Valor '%s' para submodule.alternateErrorStrategy no es reconocido"
 
-#: builtin/submodule--helper.c:1179
+#: builtin/submodule--helper.c:1191
 #, c-format
 msgid "Value '%s' for submodule.alternateLocation is not recognized"
 msgstr "Valor '%s' para submodule.alternateLocation no es reconocido"
 
-#: builtin/submodule--helper.c:1201
+#: builtin/submodule--helper.c:1214
 msgid "where the new submodule will be cloned to"
 msgstr "a donde el nuevo submódulo será clonado"
 
-#: builtin/submodule--helper.c:1204
+#: builtin/submodule--helper.c:1217
 msgid "name of the new submodule"
 msgstr "nombre del nuevo submódulo"
 
-#: builtin/submodule--helper.c:1207
+#: builtin/submodule--helper.c:1220
 msgid "url where to clone the submodule from"
 msgstr "url de dónde clonar el submódulo"
 
-#: builtin/submodule--helper.c:1213
+#: builtin/submodule--helper.c:1228
 msgid "depth for shallow clones"
 msgstr "profundidad para clones superficiales"
 
-#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1587
+#: builtin/submodule--helper.c:1231 builtin/submodule--helper.c:1606
 msgid "force cloning progress"
 msgstr "forzar el proceso de clonado"
 
-#: builtin/submodule--helper.c:1221
+#: builtin/submodule--helper.c:1236
 msgid ""
 "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
 "<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>"
@@ -13917,83 +14445,83 @@ msgstr ""
 "<repositorio>] [--name <nombre>] [--depth <profundidad>] --url <url> --path "
 "<ruta>"
 
-#: builtin/submodule--helper.c:1252
+#: builtin/submodule--helper.c:1267
 #, c-format
 msgid "clone of '%s' into submodule path '%s' failed"
 msgstr "clon de '%s' en la ruta de submódulo '%s' falló"
 
-#: builtin/submodule--helper.c:1267
+#: builtin/submodule--helper.c:1281
 #, c-format
 msgid "could not get submodule directory for '%s'"
 msgstr "no se pudo obtener el directorio de submódulo para '%s'"
 
-#: builtin/submodule--helper.c:1332
+#: builtin/submodule--helper.c:1347
 #, c-format
 msgid "Submodule path '%s' not initialized"
 msgstr "Ruta de submódulo '%s' no inicializada"
 
-#: builtin/submodule--helper.c:1336
+#: builtin/submodule--helper.c:1351
 msgid "Maybe you want to use 'update --init'?"
 msgstr "Tal vez quiere usar 'update --init'?"
 
-#: builtin/submodule--helper.c:1365
+#: builtin/submodule--helper.c:1380
 #, c-format
 msgid "Skipping unmerged submodule %s"
 msgstr "Saltando submódulo %s no fusionado"
 
-#: builtin/submodule--helper.c:1394
+#: builtin/submodule--helper.c:1409
 #, c-format
 msgid "Skipping submodule '%s'"
 msgstr "Saltando submódulo '%s'"
 
-#: builtin/submodule--helper.c:1527
+#: builtin/submodule--helper.c:1544
 #, c-format
 msgid "Failed to clone '%s'. Retry scheduled"
 msgstr "Falló al clonar '%s'. Reintento programado"
 
-#: builtin/submodule--helper.c:1538
+#: builtin/submodule--helper.c:1555
 #, c-format
 msgid "Failed to clone '%s' a second time, aborting"
 msgstr "Falló al clonar '%s' una segunda vez, abortando"
 
-#: builtin/submodule--helper.c:1568 builtin/submodule--helper.c:1788
+#: builtin/submodule--helper.c:1585 builtin/submodule--helper.c:1808
 msgid "path into the working tree"
 msgstr "ruta hacia el árbol de trabajo"
 
-#: builtin/submodule--helper.c:1571
+#: builtin/submodule--helper.c:1588
 msgid "path into the working tree, across nested submodule boundaries"
 msgstr ""
 "ruta hacia el árbol de trabajo, a través de extremos de submódulos anidados"
 
-#: builtin/submodule--helper.c:1575
+#: builtin/submodule--helper.c:1592
 msgid "rebase, merge, checkout or none"
 msgstr "rebase, merge, checkout o none"
 
-#: builtin/submodule--helper.c:1579
+#: builtin/submodule--helper.c:1598
 msgid "Create a shallow clone truncated to the specified number of revisions"
 msgstr "Crea un clon superficial truncado al número especificado de revisión"
 
-#: builtin/submodule--helper.c:1582
+#: builtin/submodule--helper.c:1601
 msgid "parallel jobs"
 msgstr "trabajos paralelos"
 
-#: builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1603
 msgid "whether the initial clone should follow the shallow recommendation"
 msgstr "si el clon inicial debe seguir la recomendación superficial"
 
-#: builtin/submodule--helper.c:1585
+#: builtin/submodule--helper.c:1604
 msgid "don't print cloning progress"
 msgstr "no mostrar el progreso de clonado"
 
-#: builtin/submodule--helper.c:1592
+#: builtin/submodule--helper.c:1611
 msgid "git submodule--helper update_clone [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper update_clone [--prefix=<ruta>] [<ruta>...]"
 
-#: builtin/submodule--helper.c:1605
+#: builtin/submodule--helper.c:1624
 msgid "bad value for update parameter"
 msgstr "mal valor para parámetro update"
 
-#: builtin/submodule--helper.c:1673
+#: builtin/submodule--helper.c:1692
 #, c-format
 msgid ""
 "Submodule (%s) branch configured to inherit branch from superproject, but "
@@ -14002,20 +14530,20 @@ msgstr ""
 "Rama de submódulo (%s)  configurada para heredar rama del superproyecto, "
 "pero el superproyecto no está en ninguna rama"
 
-#: builtin/submodule--helper.c:1789
+#: builtin/submodule--helper.c:1809
 msgid "recurse into submodules"
 msgstr "recurrir a submódulos"
 
-#: builtin/submodule--helper.c:1795
+#: builtin/submodule--helper.c:1815
 msgid "git submodule--helper embed-git-dir [<path>...]"
 msgstr "git submodule--helper embed-git-dir [<ruta>...]"
 
-#: builtin/submodule--helper.c:1857
+#: builtin/submodule--helper.c:1901
 #, c-format
 msgid "%s doesn't support --super-prefix"
 msgstr "%s no soporta --super-prefix"
 
-#: builtin/submodule--helper.c:1863
+#: builtin/submodule--helper.c:1907
 #, c-format
 msgid "'%s' is not a valid submodule--helper subcommand"
 msgstr "'%s' no es un comando submodule--helper valido"
@@ -14084,7 +14612,7 @@ msgstr "tag '%s' no encontrado."
 msgid "Deleted tag '%s' (was %s)\n"
 msgstr "Etiqueta '%s' eliminada (era %s)\n"
 
-#: builtin/tag.c:131
+#: builtin/tag.c:132
 #, c-format
 msgid ""
 "\n"
@@ -14097,7 +14625,7 @@ msgstr ""
 "  %s\n"
 "Las líneas que comienzan con '%c' serán ignoradas.\n"
 
-#: builtin/tag.c:135
+#: builtin/tag.c:136
 #, c-format
 msgid ""
 "\n"
@@ -14112,146 +14640,146 @@ msgstr ""
 "Las líneas que comienzan con '%c' serán conservadas; puedes eliminarlas por "
 "ti mismo si quieres hacerlo.\n"
 
-#: builtin/tag.c:189
+#: builtin/tag.c:190
 msgid "unable to sign the tag"
 msgstr "incapaz de firmar tag"
 
-#: builtin/tag.c:191
+#: builtin/tag.c:192
 msgid "unable to write tag file"
 msgstr "incapaz de escribir el archivo de tag"
 
-#: builtin/tag.c:216
+#: builtin/tag.c:217
 msgid "bad object type."
 msgstr "tipo de objeto erróneo."
 
-#: builtin/tag.c:265
+#: builtin/tag.c:266
 msgid "no tag message?"
 msgstr "¿Sin mensaje de tag?"
 
-#: builtin/tag.c:272
+#: builtin/tag.c:273
 #, c-format
 msgid "The tag message has been left in %s\n"
 msgstr "El mensaje del tag ha sido dejado en %s\n"
 
-#: builtin/tag.c:381
+#: builtin/tag.c:382
 msgid "list tag names"
 msgstr "listar nombres de tags"
 
-#: builtin/tag.c:383
+#: builtin/tag.c:384
 msgid "print <n> lines of each tag message"
 msgstr "imprimir <n> líneas de cada mensaje de tag"
 
-#: builtin/tag.c:385
+#: builtin/tag.c:386
 msgid "delete tags"
 msgstr "eliminar tags"
 
-#: builtin/tag.c:386
+#: builtin/tag.c:387
 msgid "verify tags"
 msgstr "verificar tags"
 
-#: builtin/tag.c:388
+#: builtin/tag.c:389
 msgid "Tag creation options"
 msgstr "Opciones de creación de tags"
 
-#: builtin/tag.c:390
+#: builtin/tag.c:391
 msgid "annotated tag, needs a message"
 msgstr "tags anotadas necesitan un mensaje"
 
-#: builtin/tag.c:392
+#: builtin/tag.c:393
 msgid "tag message"
 msgstr "mensaje de tag"
 
-#: builtin/tag.c:394
+#: builtin/tag.c:395
 msgid "force edit of tag message"
 msgstr "forzar la edición del mensaje de tag"
 
-#: builtin/tag.c:395
+#: builtin/tag.c:396
 msgid "annotated and GPG-signed tag"
 msgstr "tag anotado y firmado con GPG"
 
-#: builtin/tag.c:399
+#: builtin/tag.c:400
 msgid "use another key to sign the tag"
 msgstr "usar otra clave para firmar el tag"
 
-#: builtin/tag.c:400
+#: builtin/tag.c:401
 msgid "replace the tag if exists"
 msgstr "remplazar tag si existe"
 
-#: builtin/tag.c:401 builtin/update-ref.c:368
+#: builtin/tag.c:402 builtin/update-ref.c:368
 msgid "create a reflog"
 msgstr "crear un reflog"
 
-#: builtin/tag.c:403
+#: builtin/tag.c:404
 msgid "Tag listing options"
 msgstr "Opciones de listado de tag"
 
-#: builtin/tag.c:404
+#: builtin/tag.c:405
 msgid "show tag list in columns"
 msgstr "mostrar lista de tags en columnas"
 
-#: builtin/tag.c:405 builtin/tag.c:407
+#: builtin/tag.c:406 builtin/tag.c:408
 msgid "print only tags that contain the commit"
 msgstr "mostrar solo tags que contienen el commit"
 
-#: builtin/tag.c:406 builtin/tag.c:408
+#: builtin/tag.c:407 builtin/tag.c:409
 msgid "print only tags that don't contain the commit"
 msgstr "mostrar solo tags que no contienen el commit"
 
-#: builtin/tag.c:409
+#: builtin/tag.c:410
 msgid "print only tags that are merged"
 msgstr "sólo imprimir las tags que están fusionadas"
 
-#: builtin/tag.c:410
+#: builtin/tag.c:411
 msgid "print only tags that are not merged"
 msgstr "sólo imprimir las tags que no están fusionadas"
 
-#: builtin/tag.c:415
+#: builtin/tag.c:416
 msgid "print only tags of the object"
 msgstr "sólo imprimir tags de el objeto"
 
-#: builtin/tag.c:459
+#: builtin/tag.c:460
 msgid "--column and -n are incompatible"
 msgstr "--column y -n son incompatibles"
 
-#: builtin/tag.c:481
+#: builtin/tag.c:482
 msgid "-n option is only allowed in list mode"
 msgstr "opción -n solo es permitida en modo lista"
 
-#: builtin/tag.c:483
+#: builtin/tag.c:484
 msgid "--contains option is only allowed in list mode"
 msgstr "opción --contains solo es permitido en modo lista"
 
-#: builtin/tag.c:485
+#: builtin/tag.c:486
 msgid "--no-contains option is only allowed in list mode"
 msgstr "opción --no-contains solo es permitida en modo lista"
 
-#: builtin/tag.c:487
+#: builtin/tag.c:488
 msgid "--points-at option is only allowed in list mode"
 msgstr "opción --points-at solo es permitida en modo lista"
 
-#: builtin/tag.c:489
+#: builtin/tag.c:490
 msgid "--merged and --no-merged options are only allowed in list mode"
 msgstr "opciones --merged y --no-merged  solo están permitidas en modo lista"
 
-#: builtin/tag.c:500
+#: builtin/tag.c:501
 msgid "only one -F or -m option is allowed."
 msgstr "sólo se permite una de las opciones, -m ó -F."
 
-#: builtin/tag.c:519
+#: builtin/tag.c:520
 msgid "too many params"
 msgstr "demasiados parámetros"
 
-#: builtin/tag.c:525
+#: builtin/tag.c:526
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "'%s' no es un nombre de tag válido."
 
-#: builtin/tag.c:530
+#: builtin/tag.c:531
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "el tag '%s' ya existe"
 
-#: builtin/tag.c:561
+#: builtin/tag.c:562
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "Etiqueta '%s' actualizada (era %s)\n"
@@ -14263,27 +14791,27 @@ msgstr "Desempaquetando objetos"
 #: builtin/update-index.c:82
 #, c-format
 msgid "failed to create directory %s"
-msgstr "fallo al crear directorio %s"
+msgstr "falló al crear directorio %s"
 
 #: builtin/update-index.c:88
 #, c-format
 msgid "failed to stat %s"
-msgstr "fallo al iniciar %s"
+msgstr "falló al iniciar %s"
 
 #: builtin/update-index.c:98
 #, c-format
 msgid "failed to create file %s"
-msgstr "fallo al crear el archivo %s"
+msgstr "falló al crear el archivo %s"
 
 #: builtin/update-index.c:106
 #, c-format
 msgid "failed to delete file %s"
-msgstr "fallo al eliminar el archivo %s"
+msgstr "falló al eliminar el archivo %s"
 
 #: builtin/update-index.c:113 builtin/update-index.c:219
 #, c-format
 msgid "failed to delete directory %s"
-msgstr "fallo al eliminar directorio %s"
+msgstr "falló al eliminar directorio %s"
 
 #: builtin/update-index.c:138
 #, c-format
@@ -14321,147 +14849,147 @@ msgstr "info de estado del directorio no cambia tras borrar un directorio"
 msgid " OK"
 msgstr " OK"
 
-#: builtin/update-index.c:579
+#: builtin/update-index.c:589
 msgid "git update-index [<options>] [--] [<file>...]"
 msgstr "git update-index [<opciones>] [--] [<archivo>...]"
 
-#: builtin/update-index.c:936
+#: builtin/update-index.c:946
 msgid "continue refresh even when index needs update"
 msgstr ""
 "continuar refresh (Actualización) incluso cuando el índice necesita "
 "actualización"
 
-#: builtin/update-index.c:939
+#: builtin/update-index.c:949
 msgid "refresh: ignore submodules"
 msgstr "refresh: ignora submódulos"
 
-#: builtin/update-index.c:942
+#: builtin/update-index.c:952
 msgid "do not ignore new files"
 msgstr "no ignorar archivos nuevos"
 
-#: builtin/update-index.c:944
+#: builtin/update-index.c:954
 msgid "let files replace directories and vice-versa"
 msgstr "permitir que archivos remplacen directorios y vice-versa"
 
-#: builtin/update-index.c:946
+#: builtin/update-index.c:956
 msgid "notice files missing from worktree"
 msgstr "avisar de archivos faltando en el árbol de trabajo"
 
-#: builtin/update-index.c:948
+#: builtin/update-index.c:958
 msgid "refresh even if index contains unmerged entries"
 msgstr "ejecutar refresh incluso si el índice contiene entradas sin cambios"
 
-#: builtin/update-index.c:951
+#: builtin/update-index.c:961
 msgid "refresh stat information"
 msgstr "refresh información de estado"
 
-#: builtin/update-index.c:955
+#: builtin/update-index.c:965
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "como --refresh, pero ignora configuración assume-unchanged"
 
-#: builtin/update-index.c:959
+#: builtin/update-index.c:969
 msgid "<mode>,<object>,<path>"
 msgstr "<modo>,<objeto>,<ruta>"
 
-#: builtin/update-index.c:960
+#: builtin/update-index.c:970
 msgid "add the specified entry to the index"
 msgstr "agregar la entrada especificada al índice"
 
-#: builtin/update-index.c:969
+#: builtin/update-index.c:979
 msgid "mark files as \"not changing\""
 msgstr "marcar archivos como \"not changing\""
 
-#: builtin/update-index.c:972
+#: builtin/update-index.c:982
 msgid "clear assumed-unchanged bit"
 msgstr "limpiar bit assumed-unchanged"
 
-#: builtin/update-index.c:975
+#: builtin/update-index.c:985
 msgid "mark files as \"index-only\""
 msgstr "marcar archivos como \"index-only\""
 
-#: builtin/update-index.c:978
+#: builtin/update-index.c:988
 msgid "clear skip-worktree bit"
 msgstr "limpiar bit skip-worktree"
 
-#: builtin/update-index.c:981
+#: builtin/update-index.c:991
 msgid "add to index only; do not add content to object database"
 msgstr ""
 "agregar solo al índice; no agregar contenido a la base de datos de objetos"
 
-#: builtin/update-index.c:983
+#: builtin/update-index.c:993
 msgid "remove named paths even if present in worktree"
 msgstr ""
 "remover rutas nombradas incluso si están presentes en el árbol de trabajo"
 
-#: builtin/update-index.c:985
+#: builtin/update-index.c:995
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr "con --stdin: las lineas de entrada son terminadas con bytes nulos"
 
-#: builtin/update-index.c:987
+#: builtin/update-index.c:997
 msgid "read list of paths to be updated from standard input"
 msgstr "leer la lista de rutas para ser actualizada desde standard input"
 
-#: builtin/update-index.c:991
+#: builtin/update-index.c:1001
 msgid "add entries from standard input to the index"
 msgstr "agregar entradas de standard input al índice"
 
-#: builtin/update-index.c:995
+#: builtin/update-index.c:1005
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr "repoblar stages #2 y #3 para las rutas listadas"
 
-#: builtin/update-index.c:999
+#: builtin/update-index.c:1009
 msgid "only update entries that differ from HEAD"
 msgstr "solo actualizar entradas que difieren de HEAD"
 
-#: builtin/update-index.c:1003
+#: builtin/update-index.c:1013
 msgid "ignore files missing from worktree"
 msgstr "ignorar archivos faltantes en el árbol de trabajo"
 
-#: builtin/update-index.c:1006
+#: builtin/update-index.c:1016
 msgid "report actions to standard output"
 msgstr "reportar acciones por standard output"
 
-#: builtin/update-index.c:1008
+#: builtin/update-index.c:1018
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "(para porcelanas) olvidar conflictos sin resolver guardados"
 
-#: builtin/update-index.c:1012
+#: builtin/update-index.c:1022
 msgid "write index in this format"
 msgstr "escribir índice en este formato"
 
-#: builtin/update-index.c:1014
+#: builtin/update-index.c:1024
 msgid "enable or disable split index"
 msgstr "activar o desactivar índice dividido"
 
-#: builtin/update-index.c:1016
+#: builtin/update-index.c:1026
 msgid "enable/disable untracked cache"
 msgstr "habilitar o deshabilitar caché no rastreado"
 
-#: builtin/update-index.c:1018
+#: builtin/update-index.c:1028
 msgid "test if the filesystem supports untracked cache"
 msgstr "probar si el filesystem soporta caché no rastreado"
 
-#: builtin/update-index.c:1020
+#: builtin/update-index.c:1030
 msgid "enable untracked cache without testing the filesystem"
 msgstr "habilitar caché no rastreado sin probar el filesystem"
 
-#: builtin/update-index.c:1022
+#: builtin/update-index.c:1032
 msgid "write out the index even if is not flagged as changed"
 msgstr "escribir el índice incluso si no está marcado como cambiado"
 
-#: builtin/update-index.c:1024
+#: builtin/update-index.c:1034
 msgid "enable or disable file system monitor"
 msgstr "activar o desactivar monitor de sistema de archivos"
 
-#: builtin/update-index.c:1026
+#: builtin/update-index.c:1036
 msgid "mark files as fsmonitor valid"
 msgstr "marcar archivos como válidos para fsmonitor"
 
-#: builtin/update-index.c:1029
+#: builtin/update-index.c:1039
 msgid "clear fsmonitor valid bit"
 msgstr "limpia el bit de validación fsmonitor"
 
-#: builtin/update-index.c:1127
+#: builtin/update-index.c:1138
 msgid ""
 "core.splitIndex is set to false; remove or change it, if you really want to "
 "enable split index"
@@ -14469,7 +14997,7 @@ msgstr ""
 "core.splitIndex está configurado en false; remuévelo o cámbialo, si "
 "realmente quieres habilitar el índice partido"
 
-#: builtin/update-index.c:1136
+#: builtin/update-index.c:1147
 msgid ""
 "core.splitIndex is set to true; remove or change it, if you really want to "
 "disable split index"
@@ -14477,7 +15005,7 @@ msgstr ""
 "core.splitIndex está configurado en true; remuévelo o cámbialo, si realmente "
 "quieres deshabilitar el índice partido"
 
-#: builtin/update-index.c:1147
+#: builtin/update-index.c:1158
 msgid ""
 "core.untrackedCache is set to true; remove or change it, if you really want "
 "to disable the untracked cache"
@@ -14485,11 +15013,11 @@ msgstr ""
 "core.untrackedCache está configurado en true; remuévelo o cámbialo, si "
 "realmente quieres deshabilitar el chaché no rastreado"
 
-#: builtin/update-index.c:1151
+#: builtin/update-index.c:1162
 msgid "Untracked cache disabled"
 msgstr "Caché no rastreado deshabilitado"
 
-#: builtin/update-index.c:1159
+#: builtin/update-index.c:1170
 msgid ""
 "core.untrackedCache is set to false; remove or change it, if you really want "
 "to enable the untracked cache"
@@ -14497,29 +15025,29 @@ msgstr ""
 "core.untrackedCache está configurado en false; remuévelo o cámbialo, si "
 "realmente quieres habilitar el caché no rastreado"
 
-#: builtin/update-index.c:1163
+#: builtin/update-index.c:1174
 #, c-format
 msgid "Untracked cache enabled for '%s'"
 msgstr "Caché no rastreado habilitado para '%s'"
 
-#: builtin/update-index.c:1171
+#: builtin/update-index.c:1182
 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
 msgstr ""
 "core.fsmonitor no está configurado; actívalo si realmente quieres habilitar "
 "fsmonitor"
 
-#: builtin/update-index.c:1175
+#: builtin/update-index.c:1186
 msgid "fsmonitor enabled"
 msgstr "fsmonitor activado"
 
-#: builtin/update-index.c:1178
+#: builtin/update-index.c:1189
 msgid ""
 "core.fsmonitor is set; remove it if you really want to disable fsmonitor"
 msgstr ""
 "core.fsmonitor está configurado; remuévelo si realmente quieres deshabilitar "
 "el fsmonitor"
 
-#: builtin/update-index.c:1182
+#: builtin/update-index.c:1193
 msgid "fsmonitor disabled"
 msgstr "fsmonitor desactivado"
 
@@ -14561,13 +15089,29 @@ msgstr "git update-server-info [--force]"
 msgid "update the info files from scratch"
 msgstr "actualiza los archivos info desde cero"
 
-#: builtin/verify-commit.c:18
-msgid "git verify-commit [-v | --verbose] <commit>..."
-msgstr "git verify-commit [-v | --verbose] <commit>..."
+#: builtin/upload-pack.c:11
+msgid "git upload-pack [<options>] <dir>"
+msgstr "git upload-pack [<opciones>] <directorio>"
 
-#: builtin/verify-commit.c:73
-msgid "print commit contents"
-msgstr "imprimir contenido del commit"
+#: builtin/upload-pack.c:25
+msgid "exit immediately after initial ref advertisement"
+msgstr "salir inmediatamente tras el anuncio inicial de ref"
+
+#: builtin/upload-pack.c:27
+msgid "do not try <directory>/.git/ if <directory> is no Git directory"
+msgstr "no intente <directorio>/.git/ si <directorio> no es un directorio Git"
+
+#: builtin/upload-pack.c:29
+msgid "interrupt transfer after <n> seconds of inactivity"
+msgstr "interrumpir transferencia tras <n> segundos de inactividad"
+
+#: builtin/verify-commit.c:18
+msgid "git verify-commit [-v | --verbose] <commit>..."
+msgstr "git verify-commit [-v | --verbose] <commit>..."
+
+#: builtin/verify-commit.c:73
+msgid "print commit contents"
+msgstr "imprimir contenido del commit"
 
 #: builtin/verify-commit.c:74 builtin/verify-tag.c:38
 msgid "print raw gpg status output"
@@ -14621,22 +15165,22 @@ msgstr "git worktree remove [<opciones>] <worktree>"
 msgid "git worktree unlock <path>"
 msgstr "git worktree unlock <ruta>"
 
-#: builtin/worktree.c:60
+#: builtin/worktree.c:58
 #, c-format
 msgid "Removing worktrees/%s: not a valid directory"
 msgstr "Removiendo el worktrees/%s: no es un directorio válido"
 
-#: builtin/worktree.c:66
+#: builtin/worktree.c:64
 #, c-format
 msgid "Removing worktrees/%s: gitdir file does not exist"
 msgstr "Removiendo worktrees/%s: archivo gitdir no existe"
 
-#: builtin/worktree.c:71 builtin/worktree.c:80
+#: builtin/worktree.c:69 builtin/worktree.c:78
 #, c-format
 msgid "Removing worktrees/%s: unable to read gitdir file (%s)"
 msgstr "Removiendo worktrees/%s: no es posible leer el archivo gitdir (%s)"
 
-#: builtin/worktree.c:90
+#: builtin/worktree.c:88
 #, c-format
 msgid ""
 "Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read "
@@ -14645,183 +15189,198 @@ msgstr ""
 "Removiendo árboles de trabajo/%s: lectura corta (se esperan %<PRIuMAX> "
 "bytes, %<PRIuMAX> leídos)"
 
-#: builtin/worktree.c:98
+#: builtin/worktree.c:96
 #, c-format
 msgid "Removing worktrees/%s: invalid gitdir file"
 msgstr "Removiendo worktrees/%s: archivo gitdir inválido"
 
-#: builtin/worktree.c:114
+#: builtin/worktree.c:105
 #, c-format
 msgid "Removing worktrees/%s: gitdir file points to non-existent location"
 msgstr ""
 "Removiendo worktrees/%s: archivo gitdir apunta a una ubicación no existente"
 
-#: builtin/worktree.c:161
+#: builtin/worktree.c:152
 msgid "report pruned working trees"
 msgstr "reporta árboles de trabajo recortados"
 
-#: builtin/worktree.c:163
+#: builtin/worktree.c:154
 msgid "expire working trees older than <time>"
 msgstr "expirar árboles de trabajo más viejos a <tiempo>"
 
-#: builtin/worktree.c:238
+#: builtin/worktree.c:229
 #, c-format
 msgid "'%s' already exists"
 msgstr "'%s' ya existe"
 
-#: builtin/worktree.c:269
+#: builtin/worktree.c:260
 #, c-format
 msgid "could not create directory of '%s'"
 msgstr "no se pudo crear directorio de '%s'"
 
-#: builtin/worktree.c:308
+#: builtin/worktree.c:373 builtin/worktree.c:379
+#, c-format
+msgid "Preparing worktree (new branch '%s')"
+msgstr "Preparando árbol de trabajo (nueva rama '%s')"
+
+#: builtin/worktree.c:375
+#, c-format
+msgid "Preparing worktree (resetting branch '%s'; was at %s)"
+msgstr "Preparando árbol de trabajo (reiniciando rama '%s'; estaba en %s)"
+
+#: builtin/worktree.c:384
 #, c-format
-msgid "Preparing %s (identifier %s)"
-msgstr "Preparando %s (identificador %s)"
+msgid "Preparing worktree (checking out '%s')"
+msgstr "Preparando árbol de trabajo (haciendo checkout a '%s')"
 
-#: builtin/worktree.c:385
+#: builtin/worktree.c:390
+#, c-format
+msgid "Preparing worktree (detached HEAD %s)"
+msgstr "Preparando árbol de trabajo (HEAD desacoplado %s)"
+
+#: builtin/worktree.c:431
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr ""
 "hacer checkout a <rama> incluso si ya ha hecho checkout en otro árbol de "
 "trabajo"
 
-#: builtin/worktree.c:388
+#: builtin/worktree.c:434
 msgid "create a new branch"
 msgstr "crear una nueva rama"
 
-#: builtin/worktree.c:390
+#: builtin/worktree.c:436
 msgid "create or reset a branch"
 msgstr "crear o restablecer una rama"
 
-#: builtin/worktree.c:392
+#: builtin/worktree.c:438
 msgid "populate the new working tree"
 msgstr "popular el nuevo árbol de trabajo"
 
-#: builtin/worktree.c:393
+#: builtin/worktree.c:439
 msgid "keep the new working tree locked"
 msgstr "mantener el nuevo árbol de trabajo bloqueado"
 
-#: builtin/worktree.c:395
+#: builtin/worktree.c:441
 msgid "set up tracking mode (see git-branch(1))"
 msgstr "configurando modo tracking (mirar git-branch(1))"
 
-#: builtin/worktree.c:398
+#: builtin/worktree.c:444
 msgid "try to match the new branch name with a remote-tracking branch"
 msgstr ""
 "intentar emparejar el nuevo nombre de rama con una rama de rastreo remoto"
 
-#: builtin/worktree.c:406
+#: builtin/worktree.c:452
 msgid "-b, -B, and --detach are mutually exclusive"
 msgstr "-b, -B, y --detach son mutuamente exclusivas"
 
-#: builtin/worktree.c:471
+#: builtin/worktree.c:511
 msgid "--[no-]track can only be used if a new branch is created"
 msgstr "--[no-]track solo puede ser usado si una nueva rama es creada"
 
-#: builtin/worktree.c:571
+#: builtin/worktree.c:611
 msgid "reason for locking"
 msgstr "razón para bloquear"
 
-#: builtin/worktree.c:583 builtin/worktree.c:616 builtin/worktree.c:670
-#: builtin/worktree.c:809
+#: builtin/worktree.c:623 builtin/worktree.c:656 builtin/worktree.c:710
+#: builtin/worktree.c:850
 #, c-format
 msgid "'%s' is not a working tree"
 msgstr "'%s' no es un árbol de trabajo"
 
-#: builtin/worktree.c:585 builtin/worktree.c:618
+#: builtin/worktree.c:625 builtin/worktree.c:658
 msgid "The main working tree cannot be locked or unlocked"
 msgstr "El árbol de trabajo principal no puede ser bloqueado ni desbloqueado"
 
-#: builtin/worktree.c:590
+#: builtin/worktree.c:630
 #, c-format
 msgid "'%s' is already locked, reason: %s"
 msgstr "'%s' ya está bloqueado; razón: %s"
 
-#: builtin/worktree.c:592
+#: builtin/worktree.c:632
 #, c-format
 msgid "'%s' is already locked"
 msgstr "'%s' ya está bloqueado"
 
-#: builtin/worktree.c:620
+#: builtin/worktree.c:660
 #, c-format
 msgid "'%s' is not locked"
 msgstr "'%s' no está bloqueado"
 
-#: builtin/worktree.c:645
+#: builtin/worktree.c:685
 msgid "working trees containing submodules cannot be moved or removed"
 msgstr ""
 "árboles de trabajo conteniendo submódulos no puede ser movidos o removidos"
 
-#: builtin/worktree.c:672 builtin/worktree.c:811
+#: builtin/worktree.c:712 builtin/worktree.c:852
 #, c-format
 msgid "'%s' is a main working tree"
 msgstr "'%s' es un árbol de trabajo principal"
 
-#: builtin/worktree.c:677
+#: builtin/worktree.c:717
 #, c-format
 msgid "could not figure out destination name from '%s'"
 msgstr "no se pudo descubrir el nombre de destino de '%s'"
 
-#: builtin/worktree.c:683
+#: builtin/worktree.c:723
 #, c-format
 msgid "target '%s' already exists"
 msgstr "el objetivo '%s' ya existe"
 
-#: builtin/worktree.c:690
+#: builtin/worktree.c:730
 #, c-format
 msgid "cannot move a locked working tree, lock reason: %s"
 msgstr ""
 "no se puede mover un árbol de trabajo encerrado, motivo del encierro: %s"
 
-#: builtin/worktree.c:692
+#: builtin/worktree.c:732
 msgid "cannot move a locked working tree"
 msgstr "no se puede mover un árbol de trabajo encerrado"
 
-#: builtin/worktree.c:695
+#: builtin/worktree.c:735
 #, c-format
 msgid "validation failed, cannot move working tree: %s"
 msgstr "falló validación, no se puede mover el árbol de trabajo: %s"
 
-#: builtin/worktree.c:700
+#: builtin/worktree.c:740
 #, c-format
 msgid "failed to move '%s' to '%s'"
-msgstr "fallo al mover '%s' a '%s'"
+msgstr "falló al mover '%s' a '%s'"
 
-#: builtin/worktree.c:748
+#: builtin/worktree.c:788
 #, c-format
 msgid "failed to run 'git status' on '%s'"
 msgstr "falló al ejecutar 'git status' en '%s'"
 
-#: builtin/worktree.c:752
+#: builtin/worktree.c:792
 #, c-format
 msgid "'%s' is dirty, use --force to delete it"
 msgstr "'%s' está sucio, use --force para borrarlo"
 
-#: builtin/worktree.c:757
+#: builtin/worktree.c:797
 #, c-format
 msgid "failed to run 'git status' on '%s', code %d"
 msgstr "no se pudo ejecutar 'git status' en '%s', código %d"
 
-#: builtin/worktree.c:768 builtin/worktree.c:782
+#: builtin/worktree.c:808 builtin/worktree.c:822
 #, c-format
 msgid "failed to delete '%s'"
-msgstr "fallo al borrar '%s'"
+msgstr "falló al borrar '%s'"
 
-#: builtin/worktree.c:794
+#: builtin/worktree.c:834
 msgid "force removing even if the worktree is dirty"
 msgstr "forzar remoción incluso si el árbol de trabajo está sucio"
 
-#: builtin/worktree.c:815
+#: builtin/worktree.c:856
 #, c-format
 msgid "cannot remove a locked working tree, lock reason: %s"
 msgstr ""
 "no se pueden remover árbol de trabajo encerrado, razón del encierro: %s"
 
-#: builtin/worktree.c:817
+#: builtin/worktree.c:858
 msgid "cannot remove a locked working tree"
 msgstr "no se puede remover árbol de trabajo encerrado"
 
-#: builtin/worktree.c:820
+#: builtin/worktree.c:861
 #, c-format
 msgid "validation failed, cannot remove working tree: %s"
 msgstr "falló validación, no se puede remover árbol de trabajo: %s"
@@ -14842,26 +15401,6 @@ msgstr "escribir objeto de  árbol para un subdirectorio <prefijo>"
 msgid "only useful for debugging"
 msgstr "sólo útil para depurar"
 
-#: upload-pack.c:27
-msgid "git upload-pack [<options>] <dir>"
-msgstr "git upload-pack [<opciones>] <directorio>"
-
-#: upload-pack.c:1070
-msgid "quit after a single request/response exchange"
-msgstr "sale después de un intercambio petición/respuesta único"
-
-#: upload-pack.c:1072
-msgid "exit immediately after initial ref advertisement"
-msgstr "salir inmediatamente tras el anuncio inicial de ref"
-
-#: upload-pack.c:1074
-msgid "do not try <directory>/.git/ if <directory> is no Git directory"
-msgstr "no intente <directorio>/.git/ si <directorio> no es un directorio Git"
-
-#: upload-pack.c:1076
-msgid "interrupt transfer after <n> seconds of inactivity"
-msgstr "interrumpir transferencia tras <n> segundos de inactividad"
-
 #: credential-cache--daemon.c:222
 #, c-format
 msgid ""
@@ -14880,21 +15419,23 @@ msgstr ""
 msgid "print debugging messages to stderr"
 msgstr "mostrar mensajes de debug en stderr"
 
-#: git.c:8
+#: git.c:27
 msgid ""
 "git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
 "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
 "           <command> [<args>]"
 msgstr ""
 "git [--version] [--help] [-C <ruta>] [-c <nombre>=<valor>]\n"
 "           [--exec-path[=<ruta>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<ruta>] [--work-tree=<ruta>] [--namespace=<nombre>]\n"
 "           <comando> [<args>]"
 
-#: git.c:15
+#: git.c:34
 msgid ""
 "'git help -a' and 'git help -g' list available subcommands and some\n"
 "concept guides. See 'git help <command>' or 'git help <concept>'\n"
@@ -14904,65 +15445,65 @@ msgstr ""
 "guías de concepto. Consulte 'git help <command>' o 'git help <concepto>'\n"
 "para leer sobre un subcomando o concepto específico."
 
-#: git.c:95
+#: git.c:173
 #, c-format
 msgid "no directory given for --git-dir\n"
 msgstr "no se entregó directorio para --git-dir\n"
 
-#: git.c:109
+#: git.c:187
 #, c-format
 msgid "no namespace given for --namespace\n"
 msgstr "no se entregó namespace para --namespace\n"
 
-#: git.c:123
+#: git.c:201
 #, c-format
 msgid "no directory given for --work-tree\n"
 msgstr "no se entregó directorio para --work-tree\n"
 
-#: git.c:137
+#: git.c:215
 #, c-format
 msgid "no prefix given for --super-prefix\n"
 msgstr "no se entregó prefijo para --super-prefix\n"
 
-#: git.c:159
+#: git.c:237
 #, c-format
 msgid "-c expects a configuration string\n"
 msgstr "-c espera un string de configuración\n"
 
-#: git.c:197
+#: git.c:275
 #, c-format
 msgid "no directory given for -C\n"
 msgstr "no se entregó directorio para -C\n"
 
-#: git.c:212
+#: git.c:300
 #, c-format
 msgid "unknown option: %s\n"
 msgstr "opción %s desconocida\n"
 
-#: git.c:687
+#: git.c:765
 #, c-format
 msgid "expansion of alias '%s' failed; '%s' is not a git command\n"
 msgstr "expansión del alias '%s' falló; '%s' no es un comando de git\n"
 
-#: git.c:699
+#: git.c:777
 #, c-format
 msgid "failed to run command '%s': %s\n"
-msgstr "fallo al ejecutar comando '%s': %s\n"
+msgstr "falló al ejecutar comando '%s': %s\n"
 
-#: http.c:342
+#: http.c:348
 #, c-format
 msgid "negative value for http.postbuffer; defaulting to %d"
 msgstr "valor negativo para http.postbuffer; poniendo el default a %d"
 
-#: http.c:363
+#: http.c:369
 msgid "Delegation control is not supported with cURL < 7.22.0"
 msgstr "Delegación de control no es soportada con cURL < 7.22.0"
 
-#: http.c:372
+#: http.c:378
 msgid "Public key pinning not supported with cURL < 7.44.0"
 msgstr "Fijación de llave pública no es soportada con cURL < 7.44.0"
 
-#: http.c:1857
+#: http.c:1854
 #, c-format
 msgid ""
 "unable to update url base from redirection:\n"
@@ -14973,7 +15514,7 @@ msgstr ""
 "  preguntaba por: %s\n"
 "   redireccionamiento: %s"
 
-#: remote-curl.c:345
+#: remote-curl.c:401
 #, c-format
 msgid "redirecting to %s"
 msgstr "redirigiendo a %s"
@@ -14986,129 +15527,669 @@ msgstr "args"
 msgid "object filtering"
 msgstr "filtrado de objeto"
 
-#: common-cmds.h:9
-msgid "start a working area (see also: git help tutorial)"
-msgstr "comienza un área de trabajo (ver también: git help tutorial)"
+#: parse-options.h:157
+msgid "expiry-date"
+msgstr "fecha de expiración"
 
-#: common-cmds.h:10
-msgid "work on the current change (see also: git help everyday)"
-msgstr "trabaja en los cambios actuales (ver también: git help everyday)"
+#: parse-options.h:172
+msgid "no-op (backward compatibility)"
+msgstr "no-op (compatibilidad con versiones anteriores)"
 
-#: common-cmds.h:11
-msgid "examine the history and state (see also: git help revisions)"
-msgstr "examina el historial y el estado (ver también: git help revisions)"
+#: parse-options.h:251
+msgid "be more verbose"
+msgstr "ser mas verboso"
 
-#: common-cmds.h:12
-msgid "grow, mark and tweak your common history"
-msgstr "crece, marca y ajusta tu historial común"
+#: parse-options.h:253
+msgid "be more quiet"
+msgstr "ser mas discreto"
 
-#: common-cmds.h:13
-msgid "collaborate (see also: git help workflows)"
-msgstr "colabora (mira también: git help workflows)"
+#: parse-options.h:259
+msgid "use <n> digits to display SHA-1s"
+msgstr "usa <n> dígitos para mostrar SHA-1s"
 
-#: common-cmds.h:17
+#: command-list.h:50
 msgid "Add file contents to the index"
 msgstr "Agrega contenido de carpetas al índice"
 
-#: common-cmds.h:18
+#: command-list.h:51
+msgid "Apply a series of patches from a mailbox"
+msgstr "Aplicar una serie de parches de un mailbox"
+
+#: command-list.h:52
+msgid "Annotate file lines with commit information"
+msgstr "Anotar líneas de archivo con información de commit"
+
+#: command-list.h:53
+msgid "Apply a patch to files and/or to the index"
+msgstr "Aplicar un parche a archivos y/o  el índice"
+
+#: command-list.h:54
+msgid "Import an Arch repository into Git"
+msgstr "Importar un repositorio Arch en Git"
+
+#: command-list.h:55
+msgid "Create an archive of files from a named tree"
+msgstr "Crear un archivo o archivos de un árbol nombrado"
+
+#: command-list.h:56
 msgid "Use binary search to find the commit that introduced a bug"
 msgstr "Use la búsqueda binaria para encontrar el commit que introdujo el bug"
 
-#: common-cmds.h:19
+#: command-list.h:57
+msgid "Show what revision and author last modified each line of a file"
+msgstr ""
+"Mostrar qué revisión y autor modificaron al último cada línea de un archivo"
+
+#: command-list.h:58
 msgid "List, create, or delete branches"
 msgstr "Lista, crea, o borra ramas"
 
-#: common-cmds.h:20
+#: command-list.h:59
+msgid "Move objects and refs by archive"
+msgstr "Mover objetos y referencias por archivo"
+
+#: command-list.h:60
+msgid "Provide content or type and size information for repository objects"
+msgstr ""
+"Proveer contenido o tipo y tamaño de información para objetos de repositorio"
+
+#: command-list.h:61
+msgid "Display gitattributes information"
+msgstr "Mostrar información de gitattributes"
+
+#: command-list.h:62
+msgid "Debug gitignore / exclude files"
+msgstr "Debug a gitignore / excluir archivos"
+
+#: command-list.h:63
+msgid "Show canonical names and email addresses of contacts"
+msgstr "Mostrar nombres canónicos y direcciones de correo de contactos"
+
+#: command-list.h:64
 msgid "Switch branches or restore working tree files"
 msgstr "Cambia ramas o restaura los archivos de tu árbol de trabajo"
 
-#: common-cmds.h:21
+#: command-list.h:65
+msgid "Copy files from the index to the working tree"
+msgstr "Copiar archivos del índice al árbol de trabajo"
+
+#: command-list.h:66
+msgid "Ensures that a reference name is well formed"
+msgstr "Asegura que un nombre de referencia esté bien formado"
+
+#: command-list.h:67
+msgid "Find commits yet to be applied to upstream"
+msgstr "Encuentra commits que faltan aplicar en upstream"
+
+#: command-list.h:68
+msgid "Apply the changes introduced by some existing commits"
+msgstr "Aplica los cambios introducidos por algunos commits existentes"
+
+#: command-list.h:69
+msgid "Graphical alternative to git-commit"
+msgstr "Opción gráfica a git-commit"
+
+#: command-list.h:70
+msgid "Remove untracked files from the working tree"
+msgstr "Remueve archivos del árbol de trabajo no rastreados"
+
+#: command-list.h:71
 msgid "Clone a repository into a new directory"
 msgstr "Clona un repositorio dentro de un nuevo directorio"
 
-#: common-cmds.h:22
+#: command-list.h:72
+msgid "Display data in columns"
+msgstr "Mostrar data en columnas"
+
+#: command-list.h:73
 msgid "Record changes to the repository"
 msgstr "Graba los cambios en tu repositorio"
 
-#: common-cmds.h:23
+#: command-list.h:74
+msgid "Write and verify Git commit graph files"
+msgstr "Escribe y verifica los archivos de Git commit graph"
+
+#: command-list.h:75
+msgid "Create a new commit object"
+msgstr "Crea un nuevo objeto commit"
+
+#: command-list.h:76
+msgid "Get and set repository or global options"
+msgstr "Configurar repositorio u opciones globales"
+
+#: command-list.h:77
+msgid "Count unpacked number of objects and their disk consumption"
+msgstr "Contar número de objetos no empaquetados y su consumo en disco"
+
+#: command-list.h:78
+msgid "Retrieve and store user credentials"
+msgstr "Obtener y guardar credenciales de usuario"
+
+#: command-list.h:79
+msgid "Helper to temporarily store passwords in memory"
+msgstr "Auxiliar para almacenar temporalmente claves en memoria"
+
+#: command-list.h:80
+msgid "Helper to store credentials on disk"
+msgstr "Auxiliar para guardar credenciales en disco"
+
+#: command-list.h:81
+msgid "Export a single commit to a CVS checkout"
+msgstr "Exporta un commit único a CVS checkout"
+
+#: command-list.h:82
+msgid "Salvage your data out of another SCM people love to hate"
+msgstr "Salva tus datos de otro SCM que la gente adora odiar"
+
+#: command-list.h:83
+msgid "A CVS server emulator for Git"
+msgstr "Un servidor emulador de CVS para Git"
+
+#: command-list.h:84
+msgid "A really simple server for Git repositories"
+msgstr "Un servidor realmente simple para repositorios Git"
+
+#: command-list.h:85
+msgid "Give an object a human readable name based on an available ref"
+msgstr ""
+"Dar a un objeto un nombre legible por humanos basado en una referencia "
+"disponible"
+
+#: command-list.h:86
 msgid "Show changes between commits, commit and working tree, etc"
 msgstr "Muestra los cambios entre commits, commit y árbol de trabajo, etc"
 
-#: common-cmds.h:24
+#: command-list.h:87
+msgid "Compares files in the working tree and the index"
+msgstr "Compara archivos del árbol de trabajo y del índice"
+
+#: command-list.h:88
+msgid "Compare a tree to the working tree or index"
+msgstr "Compara un árbol con el árbol de trabajo o índice"
+
+#: command-list.h:89
+msgid "Compares the content and mode of blobs found via two tree objects"
+msgstr ""
+"Compara el contenido y el modo de blobs encontrados a través de dos objetos "
+"de árbol"
+
+#: command-list.h:90
+msgid "Show changes using common diff tools"
+msgstr "Mostrar cambios usando herramientas de diff comunes"
+
+#: command-list.h:91
+msgid "Git data exporter"
+msgstr "Exportador de data Git"
+
+#: command-list.h:92
+msgid "Backend for fast Git data importers"
+msgstr "Backend para importadores de data de Git rápidos"
+
+#: command-list.h:93
 msgid "Download objects and refs from another repository"
 msgstr "Descarga objetos y referencias de otro repositorio"
 
-#: common-cmds.h:25
+#: command-list.h:94
+msgid "Receive missing objects from another repository"
+msgstr "Descarga objetos faltantes de otro repositorio"
+
+#: command-list.h:95
+msgid "Rewrite branches"
+msgstr "Reescribir ramas"
+
+#: command-list.h:96
+msgid "Produce a merge commit message"
+msgstr "Produce un mensaje de commit para fusión"
+
+#: command-list.h:97
+msgid "Output information on each ref"
+msgstr "Información de output en cada ref"
+
+#: command-list.h:98
+msgid "Prepare patches for e-mail submission"
+msgstr "Prepara parches para ser enviados por e-mail"
+
+#: command-list.h:99
+msgid "Verifies the connectivity and validity of the objects in the database"
+msgstr ""
+"Verifica la conectividad y disponibilidad de los objetos en la base de datos"
+
+#: command-list.h:100
+msgid "Cleanup unnecessary files and optimize the local repository"
+msgstr "Limpia archivos innecesarios y optimiza el repositorio local"
+
+#: command-list.h:101
+msgid "Extract commit ID from an archive created using git-archive"
+msgstr "Extrae el ID de commit de un archivo creado usando git-archive"
+
+#: command-list.h:102
 msgid "Print lines matching a pattern"
 msgstr "Imprime las líneas que concuerdan con el patron"
 
-#: common-cmds.h:26
+#: command-list.h:103
+msgid "A portable graphical interface to Git"
+msgstr "Una interfaz gráfica portátil para Git"
+
+#: command-list.h:104
+msgid "Compute object ID and optionally creates a blob from a file"
+msgstr "Computa ID de objeto y, opcionalmente, crea un blob de un archivo"
+
+#: command-list.h:105
+msgid "Display help information about Git"
+msgstr "Mostrar información sobre Git"
+
+#: command-list.h:106
+msgid "Server side implementation of Git over HTTP"
+msgstr "Implementación de lado de servidor de Git por HTTP"
+
+#: command-list.h:107
+msgid "Download from a remote Git repository via HTTP"
+msgstr "Descarga de un repositorio Git remoto vía HTTP"
+
+#: command-list.h:108
+msgid "Push objects over HTTP/DAV to another repository"
+msgstr "Empuja objetos por HTTP/DAV a otro repositorio"
+
+#: command-list.h:109
+msgid "Send a collection of patches from stdin to an IMAP folder"
+msgstr "Enviar una colección de parches de stdin a una carpeta IMAP"
+
+#: command-list.h:110
+msgid "Build pack index file for an existing packed archive"
+msgstr "Constuye un archivo de índice para un archivo empaquetado existente"
+
+#: command-list.h:111
 msgid "Create an empty Git repository or reinitialize an existing one"
 msgstr "Crea un repositorio de Git vacío o reinicia el que ya existe"
 
-#: common-cmds.h:27
+#: command-list.h:112
+msgid "Instantly browse your working repository in gitweb"
+msgstr "Buscar instantáneamente tu repositorio de trabajo en gitweb"
+
+#: command-list.h:113
+msgid "add or parse structured information in commit messages"
+msgstr "agregar o analizar información estructurada en mensajes de commit"
+
+#: command-list.h:114
+msgid "The Git repository browser"
+msgstr "El navegador de repositorio Git"
+
+#: command-list.h:115
 msgid "Show commit logs"
 msgstr "Muestra los logs de los commits"
 
-#: common-cmds.h:28
+#: command-list.h:116
+msgid "Show information about files in the index and the working tree"
+msgstr "Muestra información sobre archivos in el índice y el árbol de trabajo"
+
+#: command-list.h:117
+msgid "List references in a remote repository"
+msgstr "Lista referencias en un repositorio remoto"
+
+#: command-list.h:118
+msgid "List the contents of a tree object"
+msgstr "Lista los contenidos de un objeto árbol"
+
+#: command-list.h:119
+msgid "Extracts patch and authorship from a single e-mail message"
+msgstr "Extraer parche y autoría de un único mensaje de e-mail"
+
+#: command-list.h:120
+msgid "Simple UNIX mbox splitter program"
+msgstr "Programa divisor de mbox simple de UNIX"
+
+#: command-list.h:121
 msgid "Join two or more development histories together"
 msgstr "Junta dos o mas historiales de desarrollo juntos"
 
-#: common-cmds.h:29
+#: command-list.h:122
+msgid "Find as good common ancestors as possible for a merge"
+msgstr "Encuentra un ancestro común bueno para una posible fusión"
+
+#: command-list.h:123
+msgid "Run a three-way file merge"
+msgstr "Ejecuta una fusión de tres vías en un archivo"
+
+#: command-list.h:124
+msgid "Run a merge for files needing merging"
+msgstr "Ejecuta una fusión para archivos que la necesitan"
+
+#: command-list.h:125
+msgid "The standard helper program to use with git-merge-index"
+msgstr "El programa de ayuda estándar para usar con git-merge-index"
+
+#: command-list.h:126
+msgid "Run merge conflict resolution tools to resolve merge conflicts"
+msgstr ""
+"Ejecuta las herramientas de fusión de resolución de conflictos para resolver "
+"conflictos de fusión"
+
+#: command-list.h:127
+msgid "Show three-way merge without touching index"
+msgstr "Mostrar fusión de tres vías sin tocar el índice"
+
+#: command-list.h:128
+msgid "Creates a tag object"
+msgstr "Crea un objeto tag"
+
+#: command-list.h:129
+msgid "Build a tree-object from ls-tree formatted text"
+msgstr "Construir un objeto árbol de un texto en formato ls-tree"
+
+#: command-list.h:130
 msgid "Move or rename a file, a directory, or a symlink"
 msgstr "Mueve o cambia el nombre a archivos, directorios o enlaces simbólicos"
 
-#: common-cmds.h:30
+#: command-list.h:131
+msgid "Find symbolic names for given revs"
+msgstr "Encontrar nombres simbólicos para revs dados"
+
+#: command-list.h:132
+msgid "Add or inspect object notes"
+msgstr "Agrega o inspecciona objetos nota"
+
+#: command-list.h:133
+msgid "Import from and submit to Perforce repositories"
+msgstr "Importar desde y enviar a repositorios Perforce"
+
+#: command-list.h:134
+msgid "Create a packed archive of objects"
+msgstr "Crea un archivo de objetos empaquetados"
+
+#: command-list.h:135
+msgid "Find redundant pack files"
+msgstr "Encuentra archivos empaquetados de manera redundante"
+
+#: command-list.h:136
+msgid "Pack heads and tags for efficient repository access"
+msgstr "Empaqueta heads y tags para un acceso eficiente al repositorio"
+
+#: command-list.h:137
+msgid "Routines to help parsing remote repository access parameters"
+msgstr ""
+"Rutinas para ayudar a analizar los parámetros de acceso del repositorio "
+"remoto"
+
+#: command-list.h:138
+msgid "Compute unique ID for a patch"
+msgstr "Calcular ID único para un parche"
+
+#: command-list.h:139
+msgid "Prune all unreachable objects from the object database"
+msgstr "Limpia todos los objetos no alcanzables de la base de datos de objetos"
+
+#: command-list.h:140
+msgid "Remove extra objects that are already in pack files"
+msgstr "Remover objetos extra que ya están en archivos empaquetados"
+
+#: command-list.h:141
 msgid "Fetch from and integrate with another repository or a local branch"
 msgstr "Realiza un fetch e integra con otro repositorio o rama local"
 
-#: common-cmds.h:31
+#: command-list.h:142
 msgid "Update remote refs along with associated objects"
 msgstr "Actualiza referencias remotas junto con sus objetos asociados"
 
-#: common-cmds.h:32
+#: command-list.h:143
+msgid "Applies a quilt patchset onto the current branch"
+msgstr "Aplica un parche quilt en la rama actual"
+
+#: command-list.h:144
+msgid "Reads tree information into the index"
+msgstr "Lee información del ábol en el índice"
+
+#: command-list.h:145
 msgid "Reapply commits on top of another base tip"
 msgstr "Vuelve a aplicar commits en la punta de otra rama"
 
-#: common-cmds.h:33
+#: command-list.h:146
+msgid "Receive what is pushed into the repository"
+msgstr "Recibir lo que es empujado en el respositorio"
+
+#: command-list.h:147
+msgid "Manage reflog information"
+msgstr "Gestionar información de reflog"
+
+#: command-list.h:148
+msgid "Manage set of tracked repositories"
+msgstr "Gestiona un conjunto de repositorios rastreados"
+
+#: command-list.h:149
+msgid "Pack unpacked objects in a repository"
+msgstr "empaquetar objetos no empaquetados en un repositorio"
+
+#: command-list.h:150
+msgid "Create, list, delete refs to replace objects"
+msgstr "Crea, lista, borra referencias para reemplazar objetos"
+
+#: command-list.h:151
+msgid "Generates a summary of pending changes"
+msgstr "Genera un resumen de cambios pendientes"
+
+#: command-list.h:152
+msgid "Reuse recorded resolution of conflicted merges"
+msgstr "Reutilizar la resolución registrada de fusiones conflictivas"
+
+#: command-list.h:153
 msgid "Reset current HEAD to the specified state"
 msgstr "Reinicia el HEAD actual a un estado especifico"
 
-#: common-cmds.h:34
+#: command-list.h:154
+msgid "Revert some existing commits"
+msgstr "Revierte algunos commits existentes"
+
+#: command-list.h:155
+msgid "Lists commit objects in reverse chronological order"
+msgstr "Lista objetos commit en orden cronológico inverso"
+
+#: command-list.h:156
+msgid "Pick out and massage parameters"
+msgstr "Seleccionar y masajear los parámetros"
+
+#: command-list.h:157
 msgid "Remove files from the working tree and from the index"
 msgstr "Borra archivos del árbol de trabajo y del índice"
 
-#: common-cmds.h:35
+#: command-list.h:158
+msgid "Send a collection of patches as emails"
+msgstr "Envía una colección de parches como e-mails"
+
+#: command-list.h:159
+msgid "Push objects over Git protocol to another repository"
+msgstr "Empujar objetos por protocolo Git a otro repositorio"
+
+#: command-list.h:160
+msgid "Restricted login shell for Git-only SSH access"
+msgstr "Shell de inicio de sesión restringido para acceso SSH exclusivo de Git"
+
+#: command-list.h:161
+msgid "Summarize 'git log' output"
+msgstr "Resumir la salida 'git log'"
+
+#: command-list.h:162
 msgid "Show various types of objects"
 msgstr "Muestra varios tipos de objetos"
 
-#: common-cmds.h:36
+#: command-list.h:163
+msgid "Show branches and their commits"
+msgstr "Mostrar ramas y sus commits"
+
+#: command-list.h:164
+msgid "Show packed archive index"
+msgstr "Mostrar el índice de archivo empaquetado"
+
+#: command-list.h:165
+msgid "List references in a local repository"
+msgstr "Listar referencias en el repositorio local"
+
+#: command-list.h:166
+msgid "Git's i18n setup code for shell scripts"
+msgstr "El código de configuración i18n de Git para scripts de shell"
+
+#: command-list.h:167
+msgid "Common Git shell script setup code"
+msgstr "Código de configuración de script de shell común de Git"
+
+#: command-list.h:168
+msgid "Stash the changes in a dirty working directory away"
+msgstr ""
+"Poner en un stash los cambios en un directorio de trabajo sucio de todas "
+"maneras"
+
+#: command-list.h:169
+msgid "Add file contents to the staging area"
+msgstr "Agrega contenidos de un archivo al área de staging"
+
+#: command-list.h:170
 msgid "Show the working tree status"
 msgstr "Muestra el estado del árbol de trabajo"
 
-#: common-cmds.h:37
+#: command-list.h:171
+msgid "Remove unnecessary whitespace"
+msgstr "Eliminar el espacio en blanco innecesario"
+
+#: command-list.h:172
+msgid "Initialize, update or inspect submodules"
+msgstr "Inicializa, actualiza o inspecciona submódulos"
+
+#: command-list.h:173
+msgid "Bidirectional operation between a Subversion repository and Git"
+msgstr "Operación bidireccional entre un repositorio Subversion y Git"
+
+#: command-list.h:174
+msgid "Read, modify and delete symbolic refs"
+msgstr "Lee, modifica y borra referencias simbólicas"
+
+#: command-list.h:175
 msgid "Create, list, delete or verify a tag object signed with GPG"
 msgstr "Crea, lista, borra o verifica un tag de objeto firmado con GPG"
 
-#: parse-options.h:157
-msgid "expiry-date"
-msgstr "fecha de expiración"
+#: command-list.h:176
+msgid "Creates a temporary file with a blob's contents"
+msgstr "Crea un archivo temporal con contenidos de un blob"
 
-#: parse-options.h:172
-msgid "no-op (backward compatibility)"
-msgstr "no-op (compatibilidad con versiones anteriores)"
+#: command-list.h:177
+msgid "Unpack objects from a packed archive"
+msgstr "Desempaqueta objetos de un archivo empaquetado"
 
-#: parse-options.h:250
-msgid "be more verbose"
-msgstr "ser mas verboso"
+#: command-list.h:178
+msgid "Register file contents in the working tree to the index"
+msgstr "Registra contenidos de archivos en el árbol de trabajo al índice"
 
-#: parse-options.h:252
-msgid "be more quiet"
-msgstr "ser mas discreto"
+#: command-list.h:179
+msgid "Update the object name stored in a ref safely"
+msgstr ""
+"Actualiza el nombre del objeto almacenado en una referencia de forma segura"
 
-#: parse-options.h:258
-msgid "use <n> digits to display SHA-1s"
-msgstr "usa <n> dígitos para mostrar SHA-1s"
+#: command-list.h:180
+msgid "Update auxiliary info file to help dumb servers"
+msgstr ""
+"Actualiza el archivo de información auxiliar para ayudar a los servidores "
+"dumb"
+
+#: command-list.h:181
+msgid "Send archive back to git-archive"
+msgstr "Enviar archivo a git-archive"
+
+#: command-list.h:182
+msgid "Send objects packed back to git-fetch-pack"
+msgstr "Enviar objetos empaquetados a git-fetch-pack"
+
+#: command-list.h:183
+msgid "Show a Git logical variable"
+msgstr "Mostrar una variable lógica de Git"
+
+#: command-list.h:184
+msgid "Check the GPG signature of commits"
+msgstr "Verificar firma GPG de commits"
+
+#: command-list.h:185
+msgid "Validate packed Git archive files"
+msgstr "Valida archivos Git empaquetados"
+
+#: command-list.h:186
+msgid "Check the GPG signature of tags"
+msgstr "Verifica la firma GPG de etiquetas"
+
+#: command-list.h:187
+msgid "Git web interface (web frontend to Git repositories)"
+msgstr "Interfaz web Git (interfaz web para repositorios Git)"
+
+#: command-list.h:188
+msgid "Show logs with difference each commit introduces"
+msgstr "Muestra logs con las diferencias que cada commit introduce"
+
+#: command-list.h:189
+msgid "Manage multiple working trees"
+msgstr "Gestiona múltiples árboles de trabajo"
+
+#: command-list.h:190
+msgid "Create a tree object from the current index"
+msgstr "Crea un objeto árbol del índice actual"
+
+#: command-list.h:191
+msgid "Defining attributes per path"
+msgstr "Definiendo atributos por ruta"
+
+#: command-list.h:192
+msgid "Git command-line interface and conventions"
+msgstr "Interfaz y convenciones de línea de comandos de Git"
+
+#: command-list.h:193
+msgid "A Git core tutorial for developers"
+msgstr "Un tutorial básico de Git para desarrolladores"
+
+#: command-list.h:194
+msgid "Git for CVS users"
+msgstr "Git para usuarios CVS"
+
+#: command-list.h:195
+msgid "Tweaking diff output"
+msgstr "Afinar la salida de diff"
+
+#: command-list.h:196
+msgid "A useful minimum set of commands for Everyday Git"
+msgstr "Un conjunto mínimo útil de comandos diarios de Git"
+
+#: command-list.h:197
+msgid "A Git Glossary"
+msgstr "Un Glosario de Git"
+
+#: command-list.h:198
+msgid "Hooks used by Git"
+msgstr "Hooks utilizados por Git"
+
+#: command-list.h:199
+msgid "Specifies intentionally untracked files to ignore"
+msgstr "Especifica de forma intencional archivos sin seguimiento a ignorar"
+
+#: command-list.h:200
+msgid "Defining submodule properties"
+msgstr "Definiendo las propiedades del submódulo"
+
+#: command-list.h:201
+msgid "Git namespaces"
+msgstr "namespaces de Git"
+
+#: command-list.h:202
+msgid "Git Repository Layout"
+msgstr "Disposición del repositorio Git"
+
+#: command-list.h:203
+msgid "Specifying revisions and ranges for Git"
+msgstr "Especificando revisiones y rangos para Git"
+
+#: command-list.h:204
+msgid "A tutorial introduction to Git: part two"
+msgstr "Un tutorial de introducción a Git: parte dos"
+
+#: command-list.h:205
+msgid "A tutorial introduction to Git"
+msgstr "Un tutorial de introducción para Git"
+
+#: command-list.h:206
+msgid "An overview of recommended workflows with Git"
+msgstr "Una visión general de flujos de trabajo recomendados con Git"
 
 #: rerere.h:40
 msgid "update the index with reused conflict resolution if possible"
@@ -15339,7 +16420,7 @@ msgstr "Intentando fusión simple con $pretty_name"
 msgid "Simple merge did not work, trying automatic merge."
 msgstr "Fusión simple no funcionó, intentando fusión automática."
 
-#: git-rebase.sh:60
+#: git-rebase.sh:61
 msgid ""
 "Resolve all conflicts manually, mark them as resolved with\n"
 "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
@@ -15354,42 +16435,42 @@ msgstr ""
 "Para abortar y regresar al estado previo al \"git rebase\", ejecute \"git "
 "rebase --abort\"."
 
-#: git-rebase.sh:163 git-rebase.sh:409
+#: git-rebase.sh:173 git-rebase.sh:442
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "No se puede regresar a $head_name"
 
-#: git-rebase.sh:174
+#: git-rebase.sh:184
 msgid "Applied autostash."
 msgstr "Autostash aplicado."
 
-#: git-rebase.sh:177
+#: git-rebase.sh:187
 #, sh-format
 msgid "Cannot store $stash_sha1"
 msgstr "No se puede almacenar $stash_sha1"
 
-#: git-rebase.sh:218
+#: git-rebase.sh:229
 msgid "The pre-rebase hook refused to rebase."
 msgstr "El hook pre-rebase rechazó el rebase."
 
-#: git-rebase.sh:223
+#: git-rebase.sh:234
 msgid "It looks like 'git am' is in progress. Cannot rebase."
 msgstr "Parece que 'git am' está en progreso. No se puede rebasar."
 
-#: git-rebase.sh:370
+#: git-rebase.sh:403
 msgid "No rebase in progress?"
 msgstr "No hay rebase en progreso?"
 
-#: git-rebase.sh:381
+#: git-rebase.sh:414
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
 "La acción --edit-todo sólo puede ser usada al rebasar interactivamente."
 
-#: git-rebase.sh:388
+#: git-rebase.sh:421
 msgid "Cannot read HEAD"
 msgstr "No se puede leer el HEAD"
 
-#: git-rebase.sh:391
+#: git-rebase.sh:424
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -15397,7 +16478,7 @@ msgstr ""
 "Tienes que editar todos los conflictos de fusión y luego\n"
 "marcarlos como resueltos usando git add"
 
-#: git-rebase.sh:435
+#: git-rebase.sh:468
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -15418,76 +16499,80 @@ msgstr ""
 "y ejecúteme nuevamente.  Me estoy deteniendo en caso de que tenga\n"
 "algo de valor ahí."
 
-#: git-rebase.sh:491
+#: git-rebase.sh:509
+msgid "error: cannot combine '--signoff' with '--preserve-merges'"
+msgstr "error: no se puede combinar '--signoff' con '--preserve-merges'"
+
+#: git-rebase.sh:537
 #, sh-format
 msgid "invalid upstream '$upstream_name'"
 msgstr "upstream inválido '$upstream_name'"
 
-#: git-rebase.sh:515
+#: git-rebase.sh:561
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name: hay más de una base de fusión"
 
-#: git-rebase.sh:518 git-rebase.sh:522
+#: git-rebase.sh:564 git-rebase.sh:568
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name: no hay base de fusión"
 
-#: git-rebase.sh:527
+#: git-rebase.sh:573
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "No apunta a un commit válido: $onto_name"
 
-#: git-rebase.sh:553
+#: git-rebase.sh:599
 #, sh-format
 msgid "fatal: no such branch/commit '$branch_name'"
 msgstr "fatal: no existe la rama/commit: '$branch_name'"
 
-#: git-rebase.sh:586
+#: git-rebase.sh:632
 msgid "Cannot autostash"
 msgstr "No se puede ejecutar autostash"
 
-#: git-rebase.sh:591
+#: git-rebase.sh:637
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "Autostash creado: $stash_abbrev"
 
-#: git-rebase.sh:595
+#: git-rebase.sh:641
 msgid "Please commit or stash them."
 msgstr "Por favor, confírmalos o guárdalos."
 
-#: git-rebase.sh:618
+#: git-rebase.sh:664
 #, sh-format
 msgid "HEAD is up to date."
 msgstr "HEAD está actualizado."
 
-#: git-rebase.sh:620
+#: git-rebase.sh:666
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "La rama actual $branch_name está actualizada."
 
-#: git-rebase.sh:628
+#: git-rebase.sh:674
 #, sh-format
 msgid "HEAD is up to date, rebase forced."
 msgstr "HEAD está actualizado, rebase forzado."
 
-#: git-rebase.sh:630
+#: git-rebase.sh:676
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr "Rama actual $branch_name está actualizada, rebase forzado."
 
-#: git-rebase.sh:642
+#: git-rebase.sh:688
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "Cambios desde $mb a $onto:"
 
-#: git-rebase.sh:651
+#: git-rebase.sh:697
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr ""
 "En primer lugar, rebobinando HEAD para después reproducir tus cambios encima "
 "de ésta..."
 
-#: git-rebase.sh:661
+#: git-rebase.sh:707
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "Avance rápido de $branch_name a $onto_name."
@@ -15555,111 +16640,111 @@ msgstr "No se puede guardar el estado actual"
 msgid "Saved working directory and index state $stash_msg"
 msgstr "Directorio de trabajo guardado y estado de índice $stash_msg"
 
-#: git-stash.sh:340
+#: git-stash.sh:342
 msgid "Cannot remove worktree changes"
 msgstr "No se pueden remover cambios del árbol de trabajo"
 
-#: git-stash.sh:488
+#: git-stash.sh:490
 #, sh-format
 msgid "unknown option: $opt"
 msgstr "opción desconocida: $opt"
 
-#: git-stash.sh:501
+#: git-stash.sh:503
 msgid "No stash entries found."
 msgstr "No se encontraron entradas de stash."
 
-#: git-stash.sh:508
+#: git-stash.sh:510
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "Se especificaron demasiadas revisiones: $REV"
 
-#: git-stash.sh:523
+#: git-stash.sh:525
 #, sh-format
 msgid "$reference is not a valid reference"
 msgstr "$reference no es una referencia válida"
 
-#: git-stash.sh:551
+#: git-stash.sh:553
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "'$args' no es un commit estilo stash"
 
-#: git-stash.sh:562
+#: git-stash.sh:564
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "'$args' no es una referencia stash"
 
-#: git-stash.sh:570
+#: git-stash.sh:572
 msgid "unable to refresh index"
 msgstr "incapaz de refrescar el índice"
 
-#: git-stash.sh:574
+#: git-stash.sh:576
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "No se puede aplicar un stash en medio de una fusión"
 
-#: git-stash.sh:582
+#: git-stash.sh:584
 msgid "Conflicts in index. Try without --index."
 msgstr "Conflictos en índice. Intente sin --index."
 
-#: git-stash.sh:584
+#: git-stash.sh:586
 msgid "Could not save index tree"
 msgstr "No se puede guardar el índice del árbol"
 
-#: git-stash.sh:593
+#: git-stash.sh:595
 msgid "Could not restore untracked files from stash entry"
 msgstr "No se pueden restaurar archivos no rastreados de la entrada stash"
 
-#: git-stash.sh:618
+#: git-stash.sh:620
 msgid "Cannot unstage modified files"
 msgstr "No se puede sacar de stage archivos modificados"
 
-#: git-stash.sh:633
+#: git-stash.sh:635
 msgid "Index was not unstashed."
 msgstr "El índice no fue sacado de stash."
 
-#: git-stash.sh:647
+#: git-stash.sh:649
 msgid "The stash entry is kept in case you need it again."
 msgstr "La entrada de stash se guardó en caso de ser necesario nuevamente."
 
-#: git-stash.sh:656
+#: git-stash.sh:658
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "Botado ${REV} ($s)"
 
-#: git-stash.sh:657
+#: git-stash.sh:659
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "${REV}: No se pudo borrar entrada stash"
 
-#: git-stash.sh:665
+#: git-stash.sh:667
 msgid "No branch name specified"
 msgstr "No se especificó el nombre de la rama"
 
-#: git-stash.sh:744
+#: git-stash.sh:746
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(Para restaurarlos, escribe \"git stash apply\")"
 
-#: git-submodule.sh:181
+#: git-submodule.sh:188
 msgid "Relative path can only be used from the toplevel of the working tree"
 msgstr ""
 "La ruta relativa sólo se puede usar desde el nivel superior del árbol de "
 "trabajo"
 
-#: git-submodule.sh:191
+#: git-submodule.sh:198
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr "repo URL: '$repo' debe ser absoluta o iniciar con ./|../"
 
-#: git-submodule.sh:210
+#: git-submodule.sh:217
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "'$sm_path' ya existe en el índice"
 
-#: git-submodule.sh:213
+#: git-submodule.sh:220
 #, sh-format
 msgid "'$sm_path' already exists in the index and is not a submodule"
 msgstr "'$sm_path' ya existe en el índice y no es un submódulo"
 
-#: git-submodule.sh:219
+#: git-submodule.sh:226
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -15670,24 +16755,24 @@ msgstr ""
 "$sm_path\n"
 "Usa -f si en verdad quieres agregarlo."
 
-#: git-submodule.sh:237
+#: git-submodule.sh:249
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "Agregando el repositorio existente en '$sm_path' al índice"
 
-#: git-submodule.sh:239
+#: git-submodule.sh:251
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "'$sm_path' ya existe y no es un repositorio git válido"
 
-#: git-submodule.sh:247
+#: git-submodule.sh:259
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
 msgstr ""
 "Se encontró localmente un directorio git para '$sm_name' con el(los) "
 "remoto(s):"
 
-#: git-submodule.sh:249
+#: git-submodule.sh:261
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from\n"
@@ -15704,50 +16789,50 @@ msgstr ""
 "o no está seguro de lo que esto significa, escoja otro nombre con la opción "
 "'--name'."
 
-#: git-submodule.sh:255
+#: git-submodule.sh:267
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
 msgstr "Reactivar directorio git local para el submódulo '$sm_name'."
 
-#: git-submodule.sh:267
+#: git-submodule.sh:279
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "No es posible hacer checkout al submódulo '$sm_path'"
 
-#: git-submodule.sh:272
+#: git-submodule.sh:284
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
-msgstr "Fallo al agregar el submódulo '$sm_path'"
+msgstr "Falló al agregar el submódulo '$sm_path'"
 
-#: git-submodule.sh:281
+#: git-submodule.sh:293
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
-msgstr "Fallo al registrar el submódulo '$sm_path'"
+msgstr "Falló al registrar el submódulo '$sm_path'"
 
-#: git-submodule.sh:342
+#: git-submodule.sh:354
 #, sh-format
 msgid "Entering '$displaypath'"
 msgstr "Entrando a '$displaypath'"
 
-#: git-submodule.sh:362
+#: git-submodule.sh:374
 #, sh-format
 msgid "Stopping at '$displaypath'; script returned non-zero status."
 msgstr ""
 "Deteniendo en '$displaypath'; script retornó un status distinto de cero."
 
-#: git-submodule.sh:584
+#: git-submodule.sh:600
 #, sh-format
 msgid "Unable to find current revision in submodule path '$displaypath'"
 msgstr ""
 "No se pudo encontrar la revisión actual en la ruta de submódulo "
 "'$displaypath'"
 
-#: git-submodule.sh:594
+#: git-submodule.sh:610
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "No es posible realizar fetch en la ruta de submódulo '$sm_path'"
 
-#: git-submodule.sh:599
+#: git-submodule.sh:615
 #, sh-format
 msgid ""
 "Unable to find current ${remote_name}/${branch} revision in submodule path "
@@ -15756,12 +16841,12 @@ msgstr ""
 "No es posible encontrar revisión actual ${remote_name}/${branch} en la ruta "
 "de submódulo  '$sm_path'"
 
-#: git-submodule.sh:617
+#: git-submodule.sh:633
 #, sh-format
 msgid "Unable to fetch in submodule path '$displaypath'"
 msgstr "No es posible realizar fetch en la ruta de submódulo '$displaypath'"
 
-#: git-submodule.sh:623
+#: git-submodule.sh:639
 #, sh-format
 msgid ""
 "Fetched in submodule path '$displaypath', but it did not contain $sha1. "
@@ -15770,75 +16855,75 @@ msgstr ""
 "Fetch realizado en ruta de submódulo '$displaypath', pero no contenía $sha1. "
 "Fetch directo del commit falló."
 
-#: git-submodule.sh:630
+#: git-submodule.sh:646
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
 msgstr "No es posible revisar '$sha1' en la ruta de submódulo '$displaypath'"
 
-#: git-submodule.sh:631
+#: git-submodule.sh:647
 #, sh-format
 msgid "Submodule path '$displaypath': checked out '$sha1'"
 msgstr "Ruta de submódulo '$displaypath': check out realizado a '$sha1'"
 
-#: git-submodule.sh:635
+#: git-submodule.sh:651
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
 msgstr ""
 "No se posible ejecutar rebase a '$sha1' en la ruta de submódulo "
 "'$displaypath'"
 
-#: git-submodule.sh:636
+#: git-submodule.sh:652
 #, sh-format
 msgid "Submodule path '$displaypath': rebased into '$sha1'"
 msgstr "Ruta de submódulo '$displaypath': rebasada en '$sha1'"
 
-#: git-submodule.sh:641
+#: git-submodule.sh:657
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$displaypath'"
 msgstr "Incapaz de fusionar '$sha1' en la ruta del submódulo '$displaypath'"
 
-#: git-submodule.sh:642
+#: git-submodule.sh:658
 #, sh-format
 msgid "Submodule path '$displaypath': merged in '$sha1'"
 msgstr "Ruta de submódulo '$displaypath': fusionada en '$sha1'"
 
-#: git-submodule.sh:647
+#: git-submodule.sh:663
 #, sh-format
 msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'"
 msgstr ""
 "Falló la ejecución  de  '$command $sha1' en la ruta de submódulo "
 "'$displaypath'"
 
-#: git-submodule.sh:648
+#: git-submodule.sh:664
 #, sh-format
 msgid "Submodule path '$displaypath': '$command $sha1'"
 msgstr "Ruta de submódulo '$displaypath': '$command $sha1'"
 
-#: git-submodule.sh:679
+#: git-submodule.sh:695
 #, sh-format
 msgid "Failed to recurse into submodule path '$displaypath'"
 msgstr "Falló al recurrir en la ruta de submódulo '$displaypath'"
 
-#: git-submodule.sh:775
+#: git-submodule.sh:791
 msgid "The --cached option cannot be used with the --files option"
 msgstr "La opción --cached no puede ser usada con la opción --files"
 
-#: git-submodule.sh:827
+#: git-submodule.sh:843
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "modo $mod_dst inesperado"
 
-#: git-submodule.sh:847
+#: git-submodule.sh:863
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr "  Advertencia: $display_name no contiene el commit $sha1_src"
 
-#: git-submodule.sh:850
+#: git-submodule.sh:866
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr "  Advertencia: $display_name no contiene el commit $sha1_dst"
 
-#: git-submodule.sh:853
+#: git-submodule.sh:869
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
@@ -15849,39 +16934,52 @@ msgstr ""
 msgid "See git-${cmd}(1) for details."
 msgstr "Véase git-${cmd}(1) para más detalles."
 
-#: git-rebase--interactive.sh:140
+#: git-rebase--interactive.sh:142
 #, sh-format
 msgid "Rebasing ($new_count/$total)"
 msgstr "Rebasando ($new_count/$total)"
 
-#: git-rebase--interactive.sh:156
+#: git-rebase--interactive.sh:158
 msgid ""
 "\n"
 "Commands:\n"
-"p, pick = use commit\n"
-"r, reword = use commit, but edit the commit message\n"
-"e, edit = use commit, but stop for amending\n"
-"s, squash = use commit, but meld into previous commit\n"
-"f, fixup = like \"squash\", but discard this commit's log message\n"
-"x, exec = run command (the rest of the line) using shell\n"
-"d, drop = remove commit\n"
+"p, pick <commit> = use commit\n"
+"r, reword <commit> = use commit, but edit the commit message\n"
+"e, edit <commit> = use commit, but stop for amending\n"
+"s, squash <commit> = use commit, but meld into previous commit\n"
+"f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
+"x, exec <command> = run command (the rest of the line) using shell\n"
+"d, drop <commit> = remove commit\n"
+"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"
 "\n"
 "These lines can be re-ordered; they are executed from top to bottom.\n"
 msgstr ""
 "\n"
 "Comandos:\n"
-" p, pick = usar commit\n"
-" r, reword = usar commit, pero editar el mensaje\n"
-" e, edit = usar commit, pero detener para enmendar\n"
-" s, squash = usar commit, pero unirlo al commit previo\n"
-" f, fixup = como \"squash\", pero descartar el mensaje del commit en el log\n"
-" x, exec = ejecutar comando (el resto de la línea) usando un shell\n"
-" d, drop = borrar commit\n"
+"p, pick <commit> = usar commit\n"
+"r, reword <commit> = usar commit, pero editar el mensaje de commit\n"
+"e, edit <commit> = usar commit, pero parar para un amend\n"
+"s, squash <commit> = usar commit, pero fusionarlo en el commit previo\n"
+"f, fixup <commit> = como \"squash\", pero descarta el mensaje del log de "
+"este commit\n"
+"x, exec <commit> = ejecuta comando ( el resto de la línea) usando un shell\n"
+"d, drop <commit> = remover commit\n"
+"l, label <label> = poner label al HEAD actual con un nombre\n"
+"t, reset <label> = reiniciar HEAD a el label\n"
+"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
+".       crea un commit de fusión usando el mensaje original de\n"
+".       fusión (o la línea de oneline, si no se especifica un mensaje\n"
+".       de commit). Use -c <commit> para reescribir el mensaje del commit.\n"
 "\n"
-"Estas líneas pueden ser re-ordenadas; son ejecutadas desde arriba hacia "
+"Estas líneas pueden ser reordenadas; son ejecutadas desde arriba hacia "
 "abajo.\n"
 
-#: git-rebase--interactive.sh:171
+#: git-rebase--interactive.sh:179
 msgid ""
 "\n"
 "Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
@@ -15889,7 +16987,7 @@ msgstr ""
 "\n"
 "No eliminar ninguna línea. Usa 'drop' explícitamente para borrar un commit \n"
 
-#: git-rebase--interactive.sh:175
+#: git-rebase--interactive.sh:183
 msgid ""
 "\n"
 "If you remove a line here THAT COMMIT WILL BE LOST.\n"
@@ -15897,7 +16995,7 @@ msgstr ""
 "\n"
 "Si remueves una línea aquí EL COMMIT SE PERDERÁ.\n"
 
-#: git-rebase--interactive.sh:213
+#: git-rebase--interactive.sh:221
 #, sh-format
 msgid ""
 "You can amend the commit now, with\n"
@@ -15916,83 +17014,83 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:238
+#: git-rebase--interactive.sh:246
 #, sh-format
 msgid "$sha1: not a commit that can be picked"
 msgstr "$sha1: no es un commit que pueda ser cogido"
 
-#: git-rebase--interactive.sh:277
+#: git-rebase--interactive.sh:285
 #, sh-format
 msgid "Invalid commit name: $sha1"
 msgstr "Nombre de commit inválido: $sha1"
 
-#: git-rebase--interactive.sh:319
+#: git-rebase--interactive.sh:325
 msgid "Cannot write current commit's replacement sha1"
 msgstr "No se puede escribir el remplazo sha1 del commit actual"
 
-#: git-rebase--interactive.sh:371
+#: git-rebase--interactive.sh:376
 #, sh-format
 msgid "Fast-forward to $sha1"
 msgstr "Avance rápido a $sha1"
 
-#: git-rebase--interactive.sh:373
+#: git-rebase--interactive.sh:378
 #, sh-format
 msgid "Cannot fast-forward to $sha1"
 msgstr "No se puede realizar avance rápido a $sha1"
 
-#: git-rebase--interactive.sh:382
+#: git-rebase--interactive.sh:387
 #, sh-format
 msgid "Cannot move HEAD to $first_parent"
 msgstr "No se puede mover HEAD a $first_parent"
 
-#: git-rebase--interactive.sh:387
+#: git-rebase--interactive.sh:392
 #, sh-format
 msgid "Refusing to squash a merge: $sha1"
 msgstr "Rehusando a ejecutar squash en fusión: $sha1"
 
-#: git-rebase--interactive.sh:405
+#: git-rebase--interactive.sh:410
 #, sh-format
 msgid "Error redoing merge $sha1"
 msgstr "Error rehaciendo fusión $sha1"
 
-#: git-rebase--interactive.sh:414
+#: git-rebase--interactive.sh:419
 #, sh-format
 msgid "Could not pick $sha1"
 msgstr "No se pudo coger $sha1"
 
-#: git-rebase--interactive.sh:423
+#: git-rebase--interactive.sh:428
 #, sh-format
 msgid "This is the commit message #${n}:"
 msgstr "Este es el mensaje del commit #${n}:"
 
-#: git-rebase--interactive.sh:428
+#: git-rebase--interactive.sh:433
 #, sh-format
 msgid "The commit message #${n} will be skipped:"
 msgstr "El mensaje del commit  #${n} será ignorado:"
 
-#: git-rebase--interactive.sh:439
+#: git-rebase--interactive.sh:444
 #, sh-format
 msgid "This is a combination of $count commit."
 msgid_plural "This is a combination of $count commits."
 msgstr[0] "Esta es una combinación de $count commit."
 msgstr[1] "Esta es la combinación de $count commits."
 
-#: git-rebase--interactive.sh:448
+#: git-rebase--interactive.sh:453
 #, sh-format
 msgid "Cannot write $fixup_msg"
 msgstr "No se puede escribir $fixup_msg"
 
-#: git-rebase--interactive.sh:451
+#: git-rebase--interactive.sh:456
 msgid "This is a combination of 2 commits."
 msgstr "Esto es una combinación de 2 commits."
 
-#: git-rebase--interactive.sh:492 git-rebase--interactive.sh:535
-#: git-rebase--interactive.sh:538
+#: git-rebase--interactive.sh:497 git-rebase--interactive.sh:540
+#: git-rebase--interactive.sh:543
 #, sh-format
 msgid "Could not apply $sha1... $rest"
 msgstr "No se puede aplicar $sha1... $rest"
 
-#: git-rebase--interactive.sh:567
+#: git-rebase--interactive.sh:572
 #, sh-format
 msgid ""
 "Could not amend commit after successfully picking $sha1... $rest\n"
@@ -16009,31 +17107,31 @@ msgstr ""
 "problema antes\n"
 "de que sea capaz de reformular el commit."
 
-#: git-rebase--interactive.sh:582
+#: git-rebase--interactive.sh:587
 #, sh-format
 msgid "Stopped at $sha1_abbrev... $rest"
 msgstr "Detenido en $sha1_abbrev... $rest"
 
-#: git-rebase--interactive.sh:597
+#: git-rebase--interactive.sh:602
 #, sh-format
 msgid "Cannot '$squash_style' without a previous commit"
 msgstr "No se puede '$squash_style' sin un commit previo"
 
-#: git-rebase--interactive.sh:639
+#: git-rebase--interactive.sh:644
 #, sh-format
 msgid "Executing: $rest"
 msgstr "Ejecutando: $rest"
 
-#: git-rebase--interactive.sh:647
+#: git-rebase--interactive.sh:652
 #, sh-format
 msgid "Execution failed: $rest"
 msgstr "Ejecución fallida: $rest"
 
-#: git-rebase--interactive.sh:649
+#: git-rebase--interactive.sh:654
 msgid "and made changes to the index and/or the working tree"
 msgstr "y hizo cambios al índice y/o al árbol de trabajo"
 
-#: git-rebase--interactive.sh:651
+#: git-rebase--interactive.sh:656
 msgid ""
 "You can fix the problem, and then run\n"
 "\n"
@@ -16044,7 +17142,7 @@ msgstr ""
 "\tgit rebase --continue"
 
 #. TRANSLATORS: after these lines is a command to be issued by the user
-#: git-rebase--interactive.sh:664
+#: git-rebase--interactive.sh:669
 #, sh-format
 msgid ""
 "Execution succeeded: $rest\n"
@@ -16059,29 +17157,29 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:675
+#: git-rebase--interactive.sh:680
 #, sh-format
 msgid "Unknown command: $command $sha1 $rest"
 msgstr "Comando desconocido: $command $sha1 $rest"
 
-#: git-rebase--interactive.sh:676
+#: git-rebase--interactive.sh:681
 msgid "Please fix this using 'git rebase --edit-todo'."
 msgstr "Por favor, corrige esto usando 'git rebase --edit-todo'."
 
-#: git-rebase--interactive.sh:711
+#: git-rebase--interactive.sh:716
 #, sh-format
 msgid "Successfully rebased and updated $head_name."
 msgstr "$head_name rebasado y actualizado satisfactoriamente."
 
-#: git-rebase--interactive.sh:735
+#: git-rebase--interactive.sh:740
 msgid "could not detach HEAD"
 msgstr "no se puede desacoplar HEAD"
 
-#: git-rebase--interactive.sh:771
+#: git-rebase--interactive.sh:778
 msgid "Could not remove CHERRY_PICK_HEAD"
 msgstr "No se pudo remover CHERRY_PICK_HEAD"
 
-#: git-rebase--interactive.sh:776
+#: git-rebase--interactive.sh:783
 #, sh-format
 msgid ""
 "You have staged changes in your working tree.\n"
@@ -16112,12 +17210,12 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: git-rebase--interactive.sh:793
+#: git-rebase--interactive.sh:800
 msgid "Error trying to find the author identity to amend commit"
 msgstr ""
 "Error tratando de encontrar la identidad del autor para remediar el commit"
 
-#: git-rebase--interactive.sh:798
+#: git-rebase--interactive.sh:805
 msgid ""
 "You have uncommitted changes in your working tree. Please commit them\n"
 "first and then run 'git rebase --continue' again."
@@ -16125,11 +17223,11 @@ msgstr ""
 "Tienes cambios sin confirmar en tu árbol de trabajo. Por favor, confírmalos\n"
 "primero y entonces ejecuta 'git rebase --continue' de nuevo."
 
-#: git-rebase--interactive.sh:803 git-rebase--interactive.sh:807
+#: git-rebase--interactive.sh:810 git-rebase--interactive.sh:814
 msgid "Could not commit staged changes."
 msgstr "No se pudo realizar el commit con los cambios en el área de stage."
 
-#: git-rebase--interactive.sh:836
+#: git-rebase--interactive.sh:843
 msgid ""
 "\n"
 "You are editing the todo file of an ongoing interactive rebase.\n"
@@ -16143,57 +17241,59 @@ msgstr ""
 "    git rebase --continue\n"
 "\n"
 
-#: git-rebase--interactive.sh:844 git-rebase--interactive.sh:1008
+#: git-rebase--interactive.sh:851 git-rebase--interactive.sh:937
 msgid "Could not execute editor"
 msgstr "No se pudo ejecutar el editor"
 
-#: git-rebase--interactive.sh:860
+#: git-rebase--interactive.sh:872
 #, sh-format
 msgid "Could not checkout $switch_to"
 msgstr "No se pudo actualizar el árbol de trabajo a $switch_to"
 
-#: git-rebase--interactive.sh:865
+#: git-rebase--interactive.sh:879
 msgid "No HEAD?"
 msgstr "¿Sin HEAD?"
 
-#: git-rebase--interactive.sh:866
+#: git-rebase--interactive.sh:880
 #, sh-format
 msgid "Could not create temporary $state_dir"
 msgstr "No se pudo crear $state_dir temporalmente"
 
-#: git-rebase--interactive.sh:869
+#: git-rebase--interactive.sh:883
 msgid "Could not mark as interactive"
 msgstr "No se pudo marcar como interactivo"
 
-#: git-rebase--interactive.sh:879 git-rebase--interactive.sh:884
-msgid "Could not init rewritten commits"
-msgstr "No se puede inicializar los commits reescritos"
-
-#: git-rebase--interactive.sh:910
-msgid "Could not generate todo list"
-msgstr "No se pudo generar lista de pendientes"
-
-#: git-rebase--interactive.sh:986
+#: git-rebase--interactive.sh:915
 #, sh-format
 msgid "Rebase $shortrevisions onto $shortonto ($todocount command)"
 msgid_plural "Rebase $shortrevisions onto $shortonto ($todocount commands)"
 msgstr[0] "Rebase $shortrevisions en $shortonto ($todocount comando)"
 msgstr[1] "Rebase $shortrevisions en $shortonto ($todocount comandos)"
 
-#: git-rebase--interactive.sh:991
+#: git-rebase--interactive.sh:920
 msgid ""
 "\n"
-"However, if you remove everything, the rebase will be aborted.\n"
+"\tHowever, if you remove everything, the rebase will be aborted.\n"
 "\n"
+"\t"
 msgstr ""
 "\n"
-"Como sea, si se remueve todo, el rebase sera abortado.\n"
+"\tComo sea, si quieres borrar todo, el rebase será abortado.\n"
 "\n"
+"\t"
 
-#: git-rebase--interactive.sh:998
+#: git-rebase--interactive.sh:927
 msgid "Note that empty commits are commented out"
 msgstr "Tenga en cuenta que los commits vacíos están comentados"
 
+#: git-rebase--interactive.sh:980
+msgid "Could not generate todo list"
+msgstr "No se pudo generar lista de pendientes"
+
+#: git-rebase--interactive.sh:1001 git-rebase--interactive.sh:1006
+msgid "Could not init rewritten commits"
+msgstr "No se puede inicializar los commits reescritos"
+
 #: git-sh-setup.sh:89 git-sh-setup.sh:94
 #, sh-format
 msgid "usage: $dashless $USAGE"
@@ -16277,68 +17377,68 @@ msgstr "rastreado"
 msgid "unstaged"
 msgstr "no rastreado"
 
-#: git-add--interactive.perl:246 git-add--interactive.perl:271
+#: git-add--interactive.perl:253 git-add--interactive.perl:278
 msgid "binary"
 msgstr "binario"
 
-#: git-add--interactive.perl:255 git-add--interactive.perl:309
+#: git-add--interactive.perl:262 git-add--interactive.perl:316
 msgid "nothing"
 msgstr "nada"
 
-#: git-add--interactive.perl:291 git-add--interactive.perl:306
+#: git-add--interactive.perl:298 git-add--interactive.perl:313
 msgid "unchanged"
 msgstr "sin cambios"
 
-#: git-add--interactive.perl:602
+#: git-add--interactive.perl:609
 #, perl-format
 msgid "added %d path\n"
 msgid_plural "added %d paths\n"
 msgstr[0] "agregada %d ruta\n"
 msgstr[1] "agregadas %d rutas\n"
 
-#: git-add--interactive.perl:605
+#: git-add--interactive.perl:612
 #, perl-format
 msgid "updated %d path\n"
 msgid_plural "updated %d paths\n"
 msgstr[0] "actualizada %d ruta\n"
 msgstr[1] "actualizadas %d rutas\n"
 
-#: git-add--interactive.perl:608
+#: git-add--interactive.perl:615
 #, perl-format
 msgid "reverted %d path\n"
 msgid_plural "reverted %d paths\n"
 msgstr[0] "revertida %d ruta\n"
 msgstr[1] "revertidas %d rutas\n"
 
-#: git-add--interactive.perl:611
+#: git-add--interactive.perl:618
 #, perl-format
 msgid "touched %d path\n"
 msgid_plural "touched %d paths\n"
 msgstr[0] "touch hecho a %d ruta\n"
 msgstr[1] "touch hecho a %d rutas\n"
 
-#: git-add--interactive.perl:620
+#: git-add--interactive.perl:627
 msgid "Update"
 msgstr "Actualizar"
 
-#: git-add--interactive.perl:632
+#: git-add--interactive.perl:639
 msgid "Revert"
 msgstr "Revertir"
 
-#: git-add--interactive.perl:655
+#: git-add--interactive.perl:662
 #, perl-format
 msgid "note: %s is untracked now.\n"
 msgstr "nota: %s no es rastreado ahora.\n"
 
-#: git-add--interactive.perl:666
+#: git-add--interactive.perl:673
 msgid "Add untracked"
 msgstr "Agregar no rastreados"
 
-#: git-add--interactive.perl:672
+#: git-add--interactive.perl:679
 msgid "No untracked files.\n"
 msgstr "No hay archivos sin rastrear.\n"
 
-#: git-add--interactive.perl:1026
+#: git-add--interactive.perl:1033
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for staging."
@@ -16346,7 +17446,7 @@ msgstr ""
 "Si el parche aplica limpiamente, el hunk editado sera marcado\n"
 "inmediatamente para el área de stage."
 
-#: git-add--interactive.perl:1029
+#: git-add--interactive.perl:1036
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for stashing."
@@ -16354,7 +17454,7 @@ msgstr ""
 "Si el parche aplica limpiamente, el hunk editado sera marcado\n"
 "inmediatamente para aplicar stash."
 
-#: git-add--interactive.perl:1032
+#: git-add--interactive.perl:1039
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for unstaging."
@@ -16362,7 +17462,7 @@ msgstr ""
 "Si el parche aplica limpiamente, el hunk editado sera marcado\n"
 "inmediatamente para sacar del área de stage."
 
-#: git-add--interactive.perl:1035 git-add--interactive.perl:1044
+#: git-add--interactive.perl:1042 git-add--interactive.perl:1051
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for applying."
@@ -16370,7 +17470,7 @@ msgstr ""
 "Si el parche aplica de forma limpia, el hunk editado sera marcado \n"
 "inmediatamente para aplicar."
 
-#: git-add--interactive.perl:1038 git-add--interactive.perl:1041
+#: git-add--interactive.perl:1045 git-add--interactive.perl:1048
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for discarding."
@@ -16378,16 +17478,16 @@ msgstr ""
 "Si el parche aplica de forma limpia, el hunk editado sera marcado\n"
 "inmediatamente para descarte."
 
-#: git-add--interactive.perl:1078
+#: git-add--interactive.perl:1085
 #, perl-format
 msgid "failed to open hunk edit file for writing: %s"
-msgstr "fallo al abrir el archivo de adición del hunk para escritura: %s"
+msgstr "falló al abrir el archivo de adición del hunk para escritura: %s"
 
-#: git-add--interactive.perl:1079
+#: git-add--interactive.perl:1086
 msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
 msgstr "Modo de edición manual de hunk -- vea abajo para una guía rápida.\n"
 
-#: git-add--interactive.perl:1085
+#: git-add--interactive.perl:1092
 #, perl-format
 msgid ""
 "---\n"
@@ -16401,7 +17501,7 @@ msgstr ""
 "Lineas comenzando con  %s serán removidas.\n"
 
 #. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
-#: git-add--interactive.perl:1093
+#: git-add--interactive.perl:1100
 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"
@@ -16411,10 +17511,10 @@ msgstr ""
 "editar nuevamente. Si todas las líneas del hunk son removidas, entonces \n"
 "la edición es abortada y el hunk queda sin cambios.\n"
 
-#: git-add--interactive.perl:1107
+#: git-add--interactive.perl:1114
 #, perl-format
 msgid "failed to open hunk edit file for reading: %s"
-msgstr "fallo al abrir el archivo de edición del hunk para lectura: %s"
+msgstr "falló al abrir el archivo de edición del hunk para lectura: %s"
 
 #. TRANSLATORS: do not translate [y/n]
 #. The program will only accept that input
@@ -16422,13 +17522,13 @@ msgstr "fallo al abrir el archivo de edición del hunk para lectura: %s"
 #. 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:1206
+#: git-add--interactive.perl:1213
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
 "Tu hunk editado no aplica. Editar nuevamente (decir \"no\" descarta!) [y/n]? "
 
-#: git-add--interactive.perl:1215
+#: git-add--interactive.perl:1222
 msgid ""
 "y - stage this hunk\n"
 "n - do not stage this hunk\n"
@@ -16443,7 +17543,7 @@ msgstr ""
 "d - no aplicar stage a este hunk o a ninguno de los posteriores en este "
 "archivo"
 
-#: git-add--interactive.perl:1221
+#: git-add--interactive.perl:1228
 msgid ""
 "y - stash this hunk\n"
 "n - do not stash this hunk\n"
@@ -16457,7 +17557,7 @@ msgstr ""
 "a - aplicar stash a este hunk y a todos los posteriores en el archivo\n"
 "d - no aplicar stash a este hunk o ninguno de los posteriores en el archivo"
 
-#: git-add--interactive.perl:1227
+#: git-add--interactive.perl:1234
 msgid ""
 "y - unstage this hunk\n"
 "n - do not unstage this hunk\n"
@@ -16472,7 +17572,7 @@ msgstr ""
 "d - no sacar del area de stage este hunk o ninguno de los posteriores en el "
 "archivo"
 
-#: git-add--interactive.perl:1233
+#: git-add--interactive.perl:1240
 msgid ""
 "y - apply this hunk to index\n"
 "n - do not apply this hunk to index\n"
@@ -16486,7 +17586,7 @@ msgstr ""
 "a - aplicar este hunk y todos los posteriores en el archivo\n"
 "d - no aplicar este hunko ninguno de los posteriores en el archivo"
 
-#: git-add--interactive.perl:1239
+#: git-add--interactive.perl:1246
 msgid ""
 "y - discard this hunk from worktree\n"
 "n - do not discard this hunk from worktree\n"
@@ -16500,7 +17600,7 @@ msgstr ""
 "a - descartar este hunk y todos los posteriores en este archivo\n"
 "d - no descartar este hunk o ninguno de los posteriores en el archivo"
 
-#: git-add--interactive.perl:1245
+#: git-add--interactive.perl:1252
 msgid ""
 "y - discard this hunk from index and worktree\n"
 "n - do not discard this hunk from index and worktree\n"
@@ -16514,7 +17614,7 @@ msgstr ""
 "a - descartar este hunk y todos los posteriores en este archivo\n"
 "d - no descartar este hunk o ninguno posterior en el archivo"
 
-#: git-add--interactive.perl:1251
+#: git-add--interactive.perl:1258
 msgid ""
 "y - apply this hunk to index and worktree\n"
 "n - do not apply this hunk to index and worktree\n"
@@ -16528,7 +17628,7 @@ msgstr ""
 "a - aplicar este hunk y todos los posteriores en el archivo\n"
 "d - no aplicar este hunk o ninguno de los siguientes en este archivo"
 
-#: git-add--interactive.perl:1266
+#: git-add--interactive.perl:1273
 msgid ""
 "g - select a hunk to go to\n"
 "/ - search for a hunk matching the given regex\n"
@@ -16550,213 +17650,213 @@ msgstr ""
 "e - editar manualmente el hunk actual\n"
 "? - imprimir ayuda\n"
 
-#: git-add--interactive.perl:1297
+#: git-add--interactive.perl:1304
 msgid "The selected hunks do not apply to the index!\n"
 msgstr "Los hunks seleccionados no aplican al índice!\n"
 
-#: git-add--interactive.perl:1298
+#: git-add--interactive.perl:1305
 msgid "Apply them to the worktree anyway? "
 msgstr "Aplicarlos al árbol de trabajo de todas maneras? "
 
-#: git-add--interactive.perl:1301
+#: git-add--interactive.perl:1308
 msgid "Nothing was applied.\n"
 msgstr "Nada fue aplicado.\n"
 
-#: git-add--interactive.perl:1312
+#: git-add--interactive.perl:1319
 #, perl-format
 msgid "ignoring unmerged: %s\n"
 msgstr "ignorando lo no fusionado: %s\n"
 
-#: git-add--interactive.perl:1321
+#: git-add--interactive.perl:1328
 msgid "Only binary files changed.\n"
 msgstr "Solo cambiaron archivos binarios.\n"
 
-#: git-add--interactive.perl:1323
+#: git-add--interactive.perl:1330
 msgid "No changes.\n"
 msgstr "Sin cambios.\n"
 
-#: git-add--interactive.perl:1331
+#: git-add--interactive.perl:1338
 msgid "Patch update"
 msgstr "Actualización del parche"
 
-#: git-add--interactive.perl:1383
+#: git-add--interactive.perl:1390
 #, perl-format
 msgid "Stage mode change [y,n,q,a,d%s,?]? "
 msgstr "Cambio de modo de stage [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1384
+#: git-add--interactive.perl:1391
 #, perl-format
 msgid "Stage deletion [y,n,q,a,d%s,?]? "
 msgstr "Aplicar stage al borrado [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1385
+#: git-add--interactive.perl:1392
 #, perl-format
 msgid "Stage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Aplicar stage a este hunk [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1388
+#: git-add--interactive.perl:1395
 #, perl-format
 msgid "Stash mode change [y,n,q,a,d%s,?]? "
 msgstr "Aplicar stash al cambio de modo [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1389
+#: git-add--interactive.perl:1396
 #, perl-format
 msgid "Stash deletion [y,n,q,a,d%s,?]? "
 msgstr "Aplicar stash al borrado [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1390
+#: git-add--interactive.perl:1397
 #, perl-format
 msgid "Stash this hunk [y,n,q,a,d%s,?]? "
 msgstr "Aplicar stash a este hunk [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1393
+#: git-add--interactive.perl:1400
 #, perl-format
 msgid "Unstage mode change [y,n,q,a,d%s,?]? "
 msgstr "Sacar cambio de modo del stage [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1394
+#: git-add--interactive.perl:1401
 #, perl-format
 msgid "Unstage deletion [y,n,q,a,d%s,?]? "
 msgstr "Sacar borrado del stage [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1395
+#: git-add--interactive.perl:1402
 #, perl-format
 msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Sacar este hunk del stage [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1398
+#: git-add--interactive.perl:1405
 #, perl-format
 msgid "Apply mode change to index [y,n,q,a,d%s,?]? "
 msgstr "Aplicar cambio de modo al índice [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1399
+#: git-add--interactive.perl:1406
 #, perl-format
 msgid "Apply deletion to index [y,n,q,a,d%s,?]? "
 msgstr "Aplicar borrado al índice [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1400
+#: git-add--interactive.perl:1407
 #, perl-format
 msgid "Apply this hunk to index [y,n,q,a,d%s,?]? "
 msgstr "Aplicar este hunk al índice [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1403
+#: git-add--interactive.perl:1410
 #, perl-format
 msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? "
 msgstr "Descartar cambio de modo del árbol de trabajo [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1404
+#: git-add--interactive.perl:1411
 #, perl-format
 msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? "
 msgstr "Descartar borrado del árbol de trabajo [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1405
+#: git-add--interactive.perl:1412
 #, perl-format
 msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
 msgstr "Descartar este hunk del árbol de trabajo [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1408
+#: git-add--interactive.perl:1415
 #, perl-format
 msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 "Descartar cambio de modo del índice y el árbol de trabajo [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1409
+#: git-add--interactive.perl:1416
 #, perl-format
 msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Descartar borrado del índice y el árbol de trabajo [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1410
+#: git-add--interactive.perl:1417
 #, perl-format
 msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Descartar este hunk del índice y el árbol de trabajo [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1413
+#: git-add--interactive.perl:1420
 #, perl-format
 msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 "Aplicar cambio de modo para el índice y el árbol de trabajo [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1414
+#: git-add--interactive.perl:1421
 #, perl-format
 msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Aplicar borrado al índice y al árbol de trabajo [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1415
+#: git-add--interactive.perl:1422
 #, perl-format
 msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Aplicar este hunk al índice y árbol de trabajo [y,n,q,a,d,/%s,?]? "
 
-#: git-add--interactive.perl:1515
+#: git-add--interactive.perl:1522
 msgid "No other hunks to goto\n"
 msgstr "No hay más pedazos para el ir\n"
 
-#: git-add--interactive.perl:1522
+#: git-add--interactive.perl:1529
 msgid "go to which hunk (<ret> to see more)? "
 msgstr "a que hunk ir (<enter> para ver mas)? "
 
-#: git-add--interactive.perl:1524
+#: git-add--interactive.perl:1531
 msgid "go to which hunk? "
 msgstr "a que hunk ir? "
 
-#: git-add--interactive.perl:1533
+#: git-add--interactive.perl:1540
 #, perl-format
 msgid "Invalid number: '%s'\n"
 msgstr "Numero invalido: '%s'\n"
 
-#: git-add--interactive.perl:1538
+#: git-add--interactive.perl:1545
 #, perl-format
 msgid "Sorry, only %d hunk available.\n"
 msgid_plural "Sorry, only %d hunks available.\n"
 msgstr[0] "Lo siento, solo %d hunk disponible.\n"
 msgstr[1] "Lo siento, solo %d hunks disponibles.\n"
 
-#: git-add--interactive.perl:1564
+#: git-add--interactive.perl:1571
 msgid "No other hunks to search\n"
 msgstr "No hay más pedazos para buscar\n"
 
-#: git-add--interactive.perl:1568
+#: git-add--interactive.perl:1575
 msgid "search for regex? "
 msgstr "buscar para regexp? "
 
-#: git-add--interactive.perl:1581
+#: git-add--interactive.perl:1588
 #, perl-format
 msgid "Malformed search regexp %s: %s\n"
 msgstr "Regexp para la búsqueda mal formado %s: %s\n"
 
-#: git-add--interactive.perl:1591
+#: git-add--interactive.perl:1598
 msgid "No hunk matches the given pattern\n"
 msgstr "No hay hunks que concuerden con el patrón entregado.\n"
 
-#: git-add--interactive.perl:1603 git-add--interactive.perl:1625
+#: git-add--interactive.perl:1610 git-add--interactive.perl:1632
 msgid "No previous hunk\n"
 msgstr "No el anterior hunk\n"
 
-#: git-add--interactive.perl:1612 git-add--interactive.perl:1631
+#: git-add--interactive.perl:1619 git-add--interactive.perl:1638
 msgid "No next hunk\n"
 msgstr "No el siguiente hunk\n"
 
-#: git-add--interactive.perl:1637
+#: git-add--interactive.perl:1644
 msgid "Sorry, cannot split this hunk\n"
 msgstr "Perdón, no se puede dividir este pedazo\n"
 
-#: git-add--interactive.perl:1643
+#: git-add--interactive.perl:1650
 #, perl-format
 msgid "Split into %d hunk.\n"
 msgid_plural "Split into %d hunks.\n"
 msgstr[0] "Cortar en %d hunk.\n"
 msgstr[1] "Cortar en  %d hunks.\n"
 
-#: git-add--interactive.perl:1653
+#: git-add--interactive.perl:1660
 msgid "Sorry, cannot edit this hunk\n"
 msgstr "Perdón, no se puede editar este pedazo\n"
 
-#: git-add--interactive.perl:1699
+#: git-add--interactive.perl:1706
 msgid "Review diff"
 msgstr "Revisión de  diff"
 
 #. TRANSLATORS: please do not translate the command names
 #. 'status', 'update', 'revert', etc.
-#: git-add--interactive.perl:1718
+#: git-add--interactive.perl:1725
 msgid ""
 "status        - show paths with changes\n"
 "update        - add working tree state to the staged set of changes\n"
@@ -16776,18 +17876,18 @@ msgstr ""
 "add untracked - agrega contenidos de archivos no rastreados al grupo de "
 "cambios del area de stage\n"
 
-#: git-add--interactive.perl:1735 git-add--interactive.perl:1740
-#: git-add--interactive.perl:1743 git-add--interactive.perl:1750
-#: git-add--interactive.perl:1754 git-add--interactive.perl:1760
+#: git-add--interactive.perl:1742 git-add--interactive.perl:1747
+#: git-add--interactive.perl:1750 git-add--interactive.perl:1757
+#: git-add--interactive.perl:1761 git-add--interactive.perl:1767
 msgid "missing --"
 msgstr "falta --"
 
-#: git-add--interactive.perl:1756
+#: git-add--interactive.perl:1763
 #, perl-format
 msgid "unknown --patch mode: %s"
 msgstr "modo --patch desconocido: %s"
 
-#: git-add--interactive.perl:1762 git-add--interactive.perl:1768
+#: git-add--interactive.perl:1769 git-add--interactive.perl:1775
 #, perl-format
 msgid "invalid argument %s, expecting --"
 msgstr "argumento invalido %s, se esperaba --"
@@ -16880,7 +17980,7 @@ msgstr ""
 #: git-send-email.perl:625
 #, perl-format
 msgid "Failed to opendir %s: %s"
-msgstr "Fallo al abrir directorio %s: %s"
+msgstr "Falló al abrir directorio %s: %s"
 
 #: git-send-email.perl:649
 #, perl-format
@@ -16909,7 +18009,7 @@ msgstr "No hay línea de subject en %s?"
 #: git-send-email.perl:683
 #, perl-format
 msgid "Failed to open for writing %s: %s"
-msgstr "Fallo al abrir para escritura %s: %s"
+msgstr "Falló al abrir para escritura %s: %s"
 
 #: git-send-email.perl:694
 msgid ""
@@ -16928,12 +18028,12 @@ msgstr ""
 #: git-send-email.perl:718
 #, perl-format
 msgid "Failed to open %s: %s"
-msgstr "Fallo al abrir %s: %s"
+msgstr "Falló al abrir %s: %s"
 
 #: git-send-email.perl:735
 #, perl-format
 msgid "Failed to open %s.final: %s"
-msgstr "Fallo al abrir %s.final: %s"
+msgstr "Falló al abrir %s.final: %s"
 
 #: git-send-email.perl:778
 msgid "Summary email is empty, skipping it\n"
@@ -17002,7 +18102,7 @@ msgstr "Que hacer con esta dirección? ([q]salir|[d]botar|[e]ditar): "
 msgid "CA path \"%s\" does not exist"
 msgstr "Ruta CA \"%s\" no existe"
 
-#: git-send-email.perl:1395
+#: git-send-email.perl:1400
 msgid ""
 "    The Cc list above has been expanded by additional\n"
 "    addresses found in the patch commit message. By default\n"
@@ -17027,137 +18127,167 @@ msgstr ""
 "    ejecuta 'git config --global sendemail.confirm auto'.\n"
 "\n"
 
-#. TRANSLATORS: Make sure to include [y] [n] [q] [a] in your
+#. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
 #. translation. The program will only accept English input
 #. at this point.
-#: git-send-email.perl:1410
-msgid "Send this email? ([y]es|[n]o|[q]uit|[a]ll): "
-msgstr "Mandar este email? ([y]si||[n]o|[q]salir|[a]todo): "
+#: git-send-email.perl:1415
+msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
+msgstr "Mandar este email? ([y]si||[n]o|[e]editar|[q]salir|[a]todo): "
 
-#: git-send-email.perl:1413
+#: git-send-email.perl:1418
 msgid "Send this email reply required"
 msgstr "Necesitas mandar esta respuesta de email"
 
-#: git-send-email.perl:1439
+#: git-send-email.perl:1446
 msgid "The required SMTP server is not properly defined."
 msgstr "El servidor SMTP no esta definido adecuadamente."
 
-#: git-send-email.perl:1486
+#: git-send-email.perl:1493
 #, perl-format
 msgid "Server does not support STARTTLS! %s"
 msgstr "Servidor no soporta STARTTLS! %s"
 
-#: git-send-email.perl:1491 git-send-email.perl:1495
+#: git-send-email.perl:1498 git-send-email.perl:1502
 #, perl-format
 msgid "STARTTLS failed! %s"
 msgstr "Falló STARTTLS! %s"
 
-#: git-send-email.perl:1505
+#: git-send-email.perl:1512
 msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug."
 msgstr ""
 "No es posible inicializar SMTP adecuadamente. Verificar config y usar ---"
 "smtp-debug."
 
-#: git-send-email.perl:1523
+#: git-send-email.perl:1530
 #, perl-format
 msgid "Failed to send %s\n"
-msgstr "Fallo al enviar %s\n"
+msgstr "Falló al enviar %s\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Dry-Sent %s\n"
 msgstr "Dry-Sent %s\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Sent %s\n"
 msgstr "Enviado %s\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "Dry-OK. Log says:\n"
 msgstr "Dry-OK. Log dice:\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "OK. Log says:\n"
 msgstr "OK. Log dice:\n"
 
-#: git-send-email.perl:1540
+#: git-send-email.perl:1547
 msgid "Result: "
 msgstr "Resultado: "
 
-#: git-send-email.perl:1543
+#: git-send-email.perl:1550
 msgid "Result: OK\n"
 msgstr "Resultado: OK\n"
 
-#: git-send-email.perl:1556
+#: git-send-email.perl:1568
 #, perl-format
 msgid "can't open file %s"
 msgstr "no se puede abrir el archivo %s"
 
-#: git-send-email.perl:1603 git-send-email.perl:1623
+#: git-send-email.perl:1615 git-send-email.perl:1635
 #, perl-format
 msgid "(mbox) Adding cc: %s from line '%s'\n"
 msgstr "(mbox) Agregando cc: %s de línea '%s'\n"
 
-#: git-send-email.perl:1609
+#: git-send-email.perl:1621
 #, perl-format
 msgid "(mbox) Adding to: %s from line '%s'\n"
 msgstr "(mbox) Agregando para: %s de la línea '%s'\n"
 
-#: git-send-email.perl:1657
+#: git-send-email.perl:1674
 #, perl-format
 msgid "(non-mbox) Adding cc: %s from line '%s'\n"
 msgstr "(non-mbox) Agregando cc: %s de la línea '%s'\n"
 
-#: git-send-email.perl:1682
+#: git-send-email.perl:1699
 #, perl-format
 msgid "(body) Adding cc: %s from line '%s'\n"
 msgstr "(body) Agregando cc: %s de la línea '%s'\n"
 
-#: git-send-email.perl:1788
+#: git-send-email.perl:1817
 #, perl-format
 msgid "(%s) Could not execute '%s'"
 msgstr "(%s) no se pudo ejecutar '%s'"
 
-#: git-send-email.perl:1795
+#: git-send-email.perl:1824
 #, perl-format
 msgid "(%s) Adding %s: %s from: '%s'\n"
 msgstr "(%s) Agregando %s: %s de: '%s'\n"
 
-#: git-send-email.perl:1799
+#: git-send-email.perl:1828
 #, perl-format
 msgid "(%s) failed to close pipe to '%s'"
-msgstr "(%s) fallo al cerrar el pipe para '%s'"
+msgstr "(%s) falló al cerrar el pipe para '%s'"
 
-#: git-send-email.perl:1826
+#: git-send-email.perl:1855
 msgid "cannot send message as 7bit"
 msgstr "no se puede mandar mensaje como 7bit"
 
-#: git-send-email.perl:1834
+#: git-send-email.perl:1863
 msgid "invalid transfer encoding"
 msgstr "codificación de transferencia invalida"
 
-#: git-send-email.perl:1872 git-send-email.perl:1923 git-send-email.perl:1933
+#: git-send-email.perl:1901 git-send-email.perl:1952 git-send-email.perl:1962
 #, perl-format
 msgid "unable to open %s: %s\n"
 msgstr "no es posible abrir %s: %s\n"
 
-#: git-send-email.perl:1875
+#: git-send-email.perl:1904
 #, perl-format
 msgid "%s: patch contains a line longer than 998 characters"
 msgstr "%s: el parche contiene una línea con mas de 998 caracteres"
 
-#: git-send-email.perl:1891
+#: git-send-email.perl:1920
 #, perl-format
 msgid "Skipping %s with backup suffix '%s'.\n"
 msgstr "Saltando %s con el sufijo de backup '%s'.\n"
 
 #. TRANSLATORS: please keep "[y|N]" as is.
-#: git-send-email.perl:1895
+#: git-send-email.perl:1924
 #, perl-format
 msgid "Do you really want to send %s? [y|N]: "
 msgstr "Realmente deseas mandar %s?[y|N]: "
 
+#~ msgid "Everyday Git With 20 Commands Or So"
+#~ msgstr "Git diario con 20 comandos o algo así"
+
+#~ msgid "Could not open '%s' for writing"
+#~ msgstr "No se pudo abrir '%s' para escritura"
+
+#~ msgid ""
+#~ "unexpected 1st line of squash message:\n"
+#~ "\n"
+#~ "\t%.*s"
+#~ msgstr ""
+#~ "1ra línea del mensaje squash no esperada:\n"
+#~ "\n"
+#~ "\t%.*s"
+
+#~ msgid ""
+#~ "invalid 1st line of squash message:\n"
+#~ "\n"
+#~ "\t%.*s"
+#~ msgstr ""
+#~ "1ra línea del mensaje squash inválida:\n"
+#~ "\n"
+#~ "\t%.*s"
+
+#~ msgid "BUG: returned path string doesn't match cwd?"
+#~ msgstr "BUG: string de ruta recibido no concuerda con cwd?"
+
+#~ msgid "Error in object"
+#~ msgstr "Error en el objeto"
+
 #~ msgid "git fetch-pack: expected ACK/NAK, got EOF"
 #~ msgstr "git getch-pack: se esperaba ACK/NAK, se obtuvo EOF"
 
index d45ee87b0c7ecb7b899552cd48b7faa4ee92d66f..2bae7536042ed949fb5ae83b4a7679597c2888ac 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -74,8 +74,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2018-03-16 07:29+0800\n"
-"PO-Revision-Date: 2018-03-23 23:03+0100\n"
+"POT-Creation-Date: 2018-06-16 22:06+0800\n"
+"PO-Revision-Date: 2018-06-16 20:42+0200\n"
 "Last-Translator: Jean-Noël Avila <jn.avila@free.fr>\n"
 "Language-Team: Jean-Noël Avila <jn.avila@free.fr>\n"
 "Language: fr\n"
@@ -84,37 +84,37 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=n<=1 ?0 : 1;\n"
 
-#: advice.c:62
+#: advice.c:92
 #, c-format
-msgid "hint: %.*s\n"
-msgstr "astuce: %.*s\n"
+msgid "%shint: %.*s%s\n"
+msgstr "%sastuce: %.*s%s\n"
 
-#: advice.c:90
+#: advice.c:137
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr "Impossible de picorer car vous avez des fichiers non fusionnés."
 
-#: advice.c:92
+#: advice.c:139
 msgid "Committing is not possible because you have unmerged files."
 msgstr "Impossible de valider car vous avez des fichiers non fusionnés."
 
-#: advice.c:94
+#: advice.c:141
 msgid "Merging is not possible because you have unmerged files."
 msgstr "Impossible de fusionner car vous avez des fichiers non fusionnés."
 
-#: advice.c:96
+#: advice.c:143
 msgid "Pulling is not possible because you have unmerged files."
 msgstr "Impossible de tirer car vous avez des fichiers non fusionnés."
 
-#: advice.c:98
+#: advice.c:145
 msgid "Reverting is not possible because you have unmerged files."
 msgstr "Impossible d'annuler car vous avez des fichiers non fusionnés."
 
-#: advice.c:100
+#: advice.c:147
 #, c-format
 msgid "It is not possible to %s because you have unmerged files."
 msgstr "%s n'est pas possible car vous avez des fichiers non fusionnés."
 
-#: advice.c:108
+#: advice.c:155
 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."
@@ -122,23 +122,23 @@ msgstr ""
 "Corrigez-les puis lancez 'git add/rm <fichier>'\n"
 "si nécessaire pour marquer la résolution et valider."
 
-#: advice.c:116
+#: advice.c:163
 msgid "Exiting because of an unresolved conflict."
 msgstr "Abandon à cause de conflit non résolu."
 
-#: advice.c:121 builtin/merge.c:1251
+#: advice.c:168 builtin/merge.c:1250
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
 msgstr "Vous n'avez pas terminé votre fusion (MERGE_HEAD existe)."
 
-#: advice.c:123
+#: advice.c:170
 msgid "Please, commit your changes before merging."
 msgstr "Veuillez valider vos changements avant de fusionner."
 
-#: advice.c:124
+#: advice.c:171
 msgid "Exiting because of unfinished merge."
 msgstr "Abandon à cause d'une fusion non terminée."
 
-#: advice.c:130
+#: advice.c:177
 #, c-format
 msgid ""
 "Note: checking out '%s'.\n"
@@ -419,7 +419,7 @@ msgstr "le patch a échoué : %s:%ld"
 msgid "cannot checkout %s"
 msgstr "extraction de %s impossible"
 
-#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:277
+#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:278
 #, c-format
 msgid "failed to read %s"
 msgstr "échec de la lecture de %s"
@@ -624,7 +624,7 @@ msgstr[1] "Application du patch %%s avec %d rejets..."
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "troncature du nom de fichier .rej en %.*s.rej"
 
-#: apply.c:4545 builtin/fetch.c:775 builtin/fetch.c:1025
+#: apply.c:4545 builtin/fetch.c:786 builtin/fetch.c:1036
 #, c-format
 msgid "cannot open %s"
 msgstr "impossible d'ouvrir %s"
@@ -678,15 +678,15 @@ msgid_plural "%d lines applied after fixing whitespace errors."
 msgstr[0] "%d ligne ajoutée après correction des erreurs d'espace."
 msgstr[1] "%d lignes ajoutées après correction des erreurs d'espace."
 
-#: apply.c:4894 builtin/add.c:539 builtin/mv.c:298 builtin/rm.c:390
+#: apply.c:4894 builtin/add.c:538 builtin/mv.c:300 builtin/rm.c:389
 msgid "Unable to write new index file"
 msgstr "Impossible d'écrire le nouveau fichier d'index"
 
 #: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257
-#: builtin/clone.c:118 builtin/fetch.c:127 builtin/pull.c:193
-#: builtin/submodule--helper.c:403 builtin/submodule--helper.c:1197
-#: builtin/submodule--helper.c:1200 builtin/submodule--helper.c:1567
-#: builtin/submodule--helper.c:1570 builtin/submodule--helper.c:1787
+#: builtin/clone.c:120 builtin/fetch.c:126 builtin/pull.c:198
+#: builtin/submodule--helper.c:405 builtin/submodule--helper.c:1210
+#: builtin/submodule--helper.c:1213 builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1587 builtin/submodule--helper.c:1807
 #: git-add--interactive.perl:197
 msgid "path"
 msgstr "chemin"
@@ -763,7 +763,7 @@ msgstr "s'assurer d'au moins <n> lignes de correspondance de contexte"
 
 #: apply.c:4960 builtin/am.c:2242 builtin/interpret-trailers.c:95
 #: builtin/interpret-trailers.c:97 builtin/interpret-trailers.c:99
-#: builtin/pack-objects.c:3035
+#: builtin/pack-objects.c:3177
 msgid "action"
 msgstr "action"
 
@@ -793,9 +793,9 @@ msgstr "laisser les sections rejetées dans les fichiers *.rej correspondants"
 msgid "allow overlapping hunks"
 msgstr "accepter les recouvrements de sections"
 
-#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21
-#: builtin/commit.c:1276 builtin/count-objects.c:96 builtin/fsck.c:665
-#: builtin/log.c:1901 builtin/mv.c:123 builtin/read-tree.c:125
+#: apply.c:4977 builtin/add.c:290 builtin/check-ignore.c:21
+#: builtin/commit.c:1301 builtin/count-objects.c:98 builtin/fsck.c:666
+#: builtin/log.c:1901 builtin/mv.c:122 builtin/read-tree.c:124
 msgid "be verbose"
 msgstr "mode verbeux"
 
@@ -836,98 +836,98 @@ msgstr ""
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <dépôt> [--exec <commande>] --list"
 
-#: archive.c:351 builtin/add.c:176 builtin/add.c:515 builtin/rm.c:299
+#: archive.c:351 builtin/add.c:176 builtin/add.c:514 builtin/rm.c:298
 #, c-format
 msgid "pathspec '%s' did not match any files"
 msgstr "le chemin '%s' ne correspond à aucun fichier"
 
-#: archive.c:436
+#: archive.c:434
 msgid "fmt"
 msgstr "fmt"
 
-#: archive.c:436
+#: archive.c:434
 msgid "archive format"
 msgstr "format d'archive"
 
-#: archive.c:437 builtin/log.c:1462
+#: archive.c:435 builtin/log.c:1462
 msgid "prefix"
 msgstr "préfixe"
 
-#: archive.c:438
+#: archive.c:436
 msgid "prepend prefix to each pathname in the archive"
 msgstr "préfixer chaque chemin de fichier dans l'archive"
 
-#: archive.c:439 builtin/blame.c:702 builtin/blame.c:703 builtin/config.c:62
-#: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:869
+#: archive.c:437 builtin/blame.c:813 builtin/blame.c:814 builtin/config.c:127
+#: builtin/fast-export.c:1007 builtin/fast-export.c:1009 builtin/grep.c:869
 #: builtin/hash-object.c:103 builtin/ls-files.c:551 builtin/ls-files.c:554
-#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120
+#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:119
 #: parse-options.h:165
 msgid "file"
 msgstr "fichier"
 
-#: archive.c:440 builtin/archive.c:89
+#: archive.c:438 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "écrire l'archive dans ce fichier"
 
-#: archive.c:442
+#: archive.c:440
 msgid "read .gitattributes in working directory"
 msgstr "lire .gitattributes dans le répertoire de travail"
 
-#: archive.c:443
+#: archive.c:441
 msgid "report archived files on stderr"
 msgstr "afficher les fichiers archivés sur stderr"
 
-#: archive.c:444
+#: archive.c:442
 msgid "store only"
 msgstr "stockage seulement"
 
-#: archive.c:445
+#: archive.c:443
 msgid "compress faster"
 msgstr "compression rapide"
 
-#: archive.c:453
+#: archive.c:451
 msgid "compress better"
 msgstr "compression efficace"
 
-#: archive.c:456
+#: archive.c:454
 msgid "list supported archive formats"
 msgstr "afficher les formats d'archive supportés"
 
-#: archive.c:458 builtin/archive.c:90 builtin/clone.c:108 builtin/clone.c:111
-#: builtin/submodule--helper.c:1209 builtin/submodule--helper.c:1576
+#: archive.c:456 builtin/archive.c:90 builtin/clone.c:110 builtin/clone.c:113
+#: builtin/submodule--helper.c:1222 builtin/submodule--helper.c:1593
 msgid "repo"
 msgstr "dépôt"
 
-#: archive.c:459 builtin/archive.c:91
+#: archive.c:457 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "récupérer l'archive depuis le dépôt distant <dépôt>"
 
-#: archive.c:460 builtin/archive.c:92 builtin/notes.c:489
+#: archive.c:458 builtin/archive.c:92 builtin/notes.c:489
 msgid "command"
 msgstr "commande"
 
-#: archive.c:461 builtin/archive.c:93
+#: archive.c:459 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "chemin vers la commande distante git-upload-archive"
 
-#: archive.c:468
+#: archive.c:466
 msgid "Unexpected option --remote"
 msgstr "Option --remote inattendue"
 
-#: archive.c:470
+#: archive.c:468
 msgid "Option --exec can only be used together with --remote"
 msgstr "L'option --exec ne peut être utilisée qu'en complément de --remote"
 
-#: archive.c:472
+#: archive.c:470
 msgid "Unexpected option --output"
 msgstr "Option --output inattendue"
 
-#: archive.c:494
+#: archive.c:492
 #, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Format d'archive inconnu '%s'"
 
-#: archive.c:501
+#: archive.c:499
 #, c-format
 msgid "Argument not supported for format '%s': -%d"
 msgstr "Argument non supporté pour le format '%s' : -%d"
@@ -945,22 +945,22 @@ msgstr ""
 "Les motifs de négation sont ignorés dans les attributs git\n"
 "Utilisez '\\!' pour un point d'exclamation littéral."
 
-#: bisect.c:460
+#: bisect.c:461
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Contenu mal cité dans le fichier '%s' : %s"
 
-#: bisect.c:668
+#: bisect.c:669
 #, c-format
 msgid "We cannot bisect more!\n"
 msgstr "Impossible de pousser la bissection plus loin !\n"
 
-#: bisect.c:722
+#: bisect.c:723
 #, c-format
 msgid "Not a valid commit name %s"
 msgstr "%s n'est pas un nom de commit valide"
 
-#: bisect.c:746
+#: bisect.c:747
 #, c-format
 msgid ""
 "The merge base %s is bad.\n"
@@ -969,7 +969,7 @@ msgstr ""
 "La base de fusion %s est mauvaise.\n"
 "Cela signifie que le bogue été corrigé entre %s et [%s].\n"
 
-#: bisect.c:751
+#: bisect.c:752
 #, c-format
 msgid ""
 "The merge base %s is new.\n"
@@ -978,7 +978,7 @@ msgstr ""
 "La base de fusion %s est nouvelle.\n"
 "La propriété a changé entre %s et [%s].\n"
 
-#: bisect.c:756
+#: bisect.c:757
 #, c-format
 msgid ""
 "The merge base %s is %s.\n"
@@ -987,7 +987,7 @@ msgstr ""
 "La base de fusion %s est %s.\n"
 "Ceci signifie que le premier commit '%s' est entre %s et [%s].\n"
 
-#: bisect.c:764
+#: bisect.c:765
 #, c-format
 msgid ""
 "Some %s revs are not ancestors of the %s rev.\n"
@@ -998,7 +998,7 @@ msgstr ""
 "git bisect ne peut pas fonctionner correctement dans ce cas.\n"
 "Peut-être les révisions %s et %s ne sont-elles pas les bonnes ?\n"
 
-#: bisect.c:777
+#: bisect.c:778
 #, c-format
 msgid ""
 "the merge base between %s and [%s] must be skipped.\n"
@@ -1010,36 +1010,36 @@ msgstr ""
 "et %s.\n"
 "On continue tout de même."
 
-#: bisect.c:810
+#: bisect.c:811
 #, c-format
 msgid "Bisecting: a merge base must be tested\n"
 msgstr "Bissection : une base de fusion doit être testée\n"
 
-#: bisect.c:850
+#: bisect.c:851
 #, c-format
 msgid "a %s revision is needed"
 msgstr "une révision %s est nécessaire"
 
-#: bisect.c:869 builtin/notes.c:175 builtin/tag.c:235
+#: bisect.c:870 builtin/notes.c:175 builtin/tag.c:236
 #, c-format
 msgid "could not create file '%s'"
 msgstr "impossible de créer le fichier '%s'"
 
-#: bisect.c:920
+#: bisect.c:921
 #, c-format
 msgid "could not read file '%s'"
 msgstr "impossible de lire le fichier '%s'"
 
-#: bisect.c:950
+#: bisect.c:951
 msgid "reading bisect refs failed"
 msgstr "impossible de lire les références de bissection"
 
-#: bisect.c:969
+#: bisect.c:970
 #, c-format
 msgid "%s was both %s and %s\n"
 msgstr "%s était à la fois %s et %s\n"
 
-#: bisect.c:977
+#: bisect.c:978
 #, c-format
 msgid ""
 "No testable commit found.\n"
@@ -1048,7 +1048,7 @@ msgstr ""
 "Aucun commit testable n'a été trouvé\n"
 "Peut-être avez-vous démarré avec un mauvais paramètre de chemin ?\n"
 
-#: bisect.c:996
+#: bisect.c:997
 #, c-format
 msgid "(roughly %d step)"
 msgid_plural "(roughly %d steps)"
@@ -1058,52 +1058,52 @@ msgstr[1] "(à peu près %d étapes)"
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
 #.
-#: bisect.c:1002
+#: bisect.c:1003
 #, 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] "Bissection : %d révision à tester après cette %s\n"
 msgstr[1] "Bissection : %d révisions à tester après cette %s\n"
 
-#: blame.c:1758
+#: blame.c:1756
 msgid "--contents and --reverse do not blend well."
 msgstr "--contents et --reverse ne font pas bon ménage."
 
-#: blame.c:1769
+#: blame.c:1767
 msgid "cannot use --contents with final commit object name"
 msgstr "on ne peut pas utiliser --contents avec un nom d'objet commit final"
 
-#: blame.c:1789
+#: blame.c:1787
 msgid "--reverse and --first-parent together require specified latest commit"
 msgstr ""
 "--reverse et --first-parent ensemble nécessitent la spécification d'un "
 "dernier commit"
 
-#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699
-#: sequencer.c:2901 builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920
-#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370
-#: builtin/shortlog.c:191
+#: blame.c:1796 bundle.c:160 ref-filter.c:2075 sequencer.c:1861
+#: sequencer.c:3632 builtin/commit.c:981 builtin/log.c:366 builtin/log.c:920
+#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:372
+#: builtin/shortlog.c:192
 msgid "revision walk setup failed"
 msgstr "échec de la préparation du parcours des révisions"
 
-#: blame.c:1816
+#: blame.c:1814
 msgid ""
 "--reverse --first-parent together require range along first-parent chain"
 msgstr ""
 "--reverse --first-parent ensemble nécessitent une portée avec la chaîne de "
 "premier parent"
 
-#: blame.c:1827
+#: blame.c:1825
 #, c-format
 msgid "no such path %s in %s"
 msgstr "pas de chemin %s dans %s"
 
-#: blame.c:1838
+#: blame.c:1836
 #, c-format
 msgid "cannot read blob %s for path %s"
 msgstr "impossible de lire le blob %s  pour le chemin %s"
 
-#: branch.c:53
+#: branch.c:54
 #, c-format
 msgid ""
 "\n"
@@ -1116,97 +1116,97 @@ msgstr ""
 "l'information de suivi distant en invoquant\n"
 "\"git branch --setup-upstream-to=%s%s%s\"."
 
-#: branch.c:67
+#: branch.c:68
 #, c-format
 msgid "Not setting branch %s as its own upstream."
 msgstr "La branche %s ne peut pas être sa propre branche amont."
 
-#: branch.c:93
+#: branch.c:94
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s' by rebasing."
 msgstr ""
 "La branche '%s' est paramétrée pour suivre la branche distante '%s' de '%s' "
 "en rebasant."
 
-#: branch.c:94
+#: branch.c:95
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s'."
 msgstr ""
 "La branche '%s' est paramétrée pour suivre la branche distante '%s' depuis "
 "'%s'."
 
-#: branch.c:98
+#: branch.c:99
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s' by rebasing."
 msgstr ""
 "La branche '%s' est paramétrée pour suivre la branche locale '%'s en "
 "rebasant."
 
-#: branch.c:99
+#: branch.c:100
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s'."
 msgstr "La branche '%s' est paramétrée pour suivre la branche locale '%s'."
 
-#: branch.c:104
+#: branch.c:105
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s' by rebasing."
 msgstr ""
 "La branche '%s' est paramétrée pour suivre la référence distante '%s' en "
 "rebasant."
 
-#: branch.c:105
+#: branch.c:106
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s'."
 msgstr "La branche '%s' est paramétrée pour suivre la référence distante '%s'."
 
-#: branch.c:109
+#: branch.c:110
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s' by rebasing."
 msgstr ""
 "La branche '%s' est paramétrée pour suivre la référence locale '%s' en "
 "rebasant."
 
-#: branch.c:110
+#: branch.c:111
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s'."
 msgstr "La branche '%s' est paramétrée pour suivre la référence locale '%s'."
 
-#: branch.c:119
+#: branch.c:120
 msgid "Unable to write upstream branch configuration"
 msgstr "Échec de l'écriture de la configuration de branche amont"
 
-#: branch.c:156
+#: branch.c:157
 #, c-format
 msgid "Not tracking: ambiguous information for ref %s"
 msgstr "Pas de suivi : information ambiguë pour la référence %s"
 
-#: branch.c:189
+#: branch.c:190
 #, c-format
 msgid "'%s' is not a valid branch name."
 msgstr "'%s' n'est pas un nom de branche valide."
 
-#: branch.c:208
+#: branch.c:209
 #, c-format
 msgid "A branch named '%s' already exists."
 msgstr "Une branche nommée '%s' existe déjà."
 
-#: branch.c:213
+#: branch.c:214
 msgid "Cannot force update the current branch."
 msgstr "Impossible de forcer la mise à jour de la branche courante."
 
-#: branch.c:233
+#: branch.c:234
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr ""
 "Impossible de paramétrer le suivi de branche ; le point de départ '%s' n'est "
 "pas une branche."
 
-#: branch.c:235
+#: branch.c:236
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr "la branche amont demandée '%s' n'existe pas"
 
-#: branch.c:237
+#: branch.c:238
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -1226,27 +1226,27 @@ msgstr ""
 "sa jumelle distante, vous pouvez utiliser \"git push -u\"\n"
 "pour paramétrer le suivi distant en même temps que vous poussez."
 
-#: branch.c:280
+#: branch.c:281
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "Nom d'objet invalide : '%s'."
 
-#: branch.c:300
+#: branch.c:301
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "Nom d'objet ambigu : '%s'."
 
-#: branch.c:305
+#: branch.c:306
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "Point d'embranchement invalide : '%s'."
 
-#: branch.c:359
+#: branch.c:360
 #, c-format
 msgid "'%s' is already checked out at '%s'"
 msgstr "'%s' est déjà extrait dans '%s'"
 
-#: branch.c:382
+#: branch.c:383
 #, c-format
 msgid "HEAD of working tree %s is not updated"
 msgstr "la HEAD de la copie de travail %s n'est pas mise à jour"
@@ -1261,7 +1261,7 @@ msgstr "'%s' ne semble pas être un fichier bundle v2"
 msgid "unrecognized header: %s%s (%d)"
 msgstr "en-tête non reconnu : %s%s (%d)"
 
-#: bundle.c:88 sequencer.c:1879 sequencer.c:2337 builtin/commit.c:750
+#: bundle.c:88 sequencer.c:2081 sequencer.c:2558 builtin/commit.c:755
 #, c-format
 msgid "could not open '%s'"
 msgstr "impossible d'ouvrir '%s'"
@@ -1305,7 +1305,7 @@ msgstr "rev-list a disparu"
 msgid "ref '%s' is excluded by the rev-list options"
 msgstr "la référence '%s' est exclue par les options de rev-list"
 
-#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:296
+#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:303
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "argument non reconnu : %s"
@@ -1328,18 +1328,39 @@ msgstr "l'index de groupe a disparu"
 msgid "invalid color value: %.*s"
 msgstr "Valeur invalide de couleur : %.*s"
 
-#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465
-#: builtin/am.c:1436 builtin/am.c:2072
+#: commit.c:43 sequencer.c:2364 builtin/am.c:421 builtin/am.c:465
+#: builtin/am.c:1436 builtin/am.c:2072 builtin/replace.c:376
+#: builtin/replace.c:448
 #, c-format
 msgid "could not parse %s"
 msgstr "impossible d'analyser %s"
 
-#: commit.c:43
+#: commit.c:45
 #, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s n'est pas un commit !"
 
-#: commit.c:1506
+#: commit.c:182
+msgid ""
+"Support for <GIT_DIR>/info/grafts is deprecated\n"
+"and will be removed in a future Git version.\n"
+"\n"
+"Please use \"git replace --convert-graft-file\"\n"
+"to convert the grafts into replace refs.\n"
+"\n"
+"Turn this message off by running\n"
+"\"git config advice.graftFileDeprecated false\""
+msgstr ""
+"Le support de <GIT_DIR>/info/grafts est déconseillé\n"
+"et sera supprimé dans une version future de Git.\n"
+"\n"
+"Veuillez utiliser \"git replace --convert-graft-file\"\n"
+"pour convertir les grafts en référence de remplacement.\n"
+"\n"
+"Supprimez ce message en lançant\n"
+"\"git config advice.graftFileDeprecated false\""
+
+#: commit.c:1540
 msgid ""
 "Warning: commit message did not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
@@ -1351,189 +1372,203 @@ msgstr ""
 "variable de configuration i18n.commitencoding à l'encodage utilisé par votre "
 "projet.\n"
 
+#: commit-graph.c:669
+#, c-format
+msgid "the commit graph format cannot write %d commits"
+msgstr "le graphe de commits ne peut pas écrire %d commits"
+
+#: commit-graph.c:696
+msgid "too many commits to write graph"
+msgstr "trop de commits pour écrire un graphe"
+
+#: commit-graph.c:707 builtin/init-db.c:516 builtin/init-db.c:521
+#, c-format
+msgid "cannot mkdir %s"
+msgstr "impossible de créer le répertoire (mkdir) %s"
+
 #: compat/obstack.c:405 compat/obstack.c:407
 msgid "memory exhausted"
 msgstr "plus de mémoire"
 
-#: config.c:186
+#: config.c:187
 msgid "relative config include conditionals must come from files"
 msgstr ""
 "les conditions d'inclusion de configuration relative doivent venir de "
 "fichiers"
 
-#: config.c:720
+#: config.c:788
 #, c-format
 msgid "bad config line %d in blob %s"
 msgstr "ligne %d de config incorrecte dans le blob %s"
 
-#: config.c:724
+#: config.c:792
 #, c-format
 msgid "bad config line %d in file %s"
 msgstr "ligne %d de config incorrecte dans le fichier %s"
 
-#: config.c:728
+#: config.c:796
 #, c-format
 msgid "bad config line %d in standard input"
 msgstr "ligne %d de config incorrecte dans l'entrée standard"
 
-#: config.c:732
+#: config.c:800
 #, c-format
 msgid "bad config line %d in submodule-blob %s"
 msgstr "ligne %d de config incorrecte dans le blob de sous-module %s"
 
-#: config.c:736
+#: config.c:804
 #, c-format
 msgid "bad config line %d in command line %s"
 msgstr "ligne %d de config incorrecte dans la ligne de commande %s"
 
-#: config.c:740
+#: config.c:808
 #, c-format
 msgid "bad config line %d in %s"
 msgstr "ligne %d de config incorrecte dans %s"
 
-#: config.c:868
+#: config.c:936
 msgid "out of range"
 msgstr "hors plage"
 
-#: config.c:868
+#: config.c:936
 msgid "invalid unit"
 msgstr "unité invalide"
 
-#: config.c:874
+#: config.c:942
 #, c-format
 msgid "bad numeric config value '%s' for '%s': %s"
 msgstr "valeur numérique de configuration invalide '%s' pour '%s' : %s"
 
-#: config.c:879
+#: config.c:947
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
 msgstr ""
 "valeur numérique de configuration incorrecte '%s' pour '%s' dans le blob "
 "%s : %s"
 
-#: config.c:882
+#: config.c:950
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in file %s: %s"
 msgstr ""
 "valeur numérique de configuration incorrecte '%s' pour '%s' dans le fichier "
 "%s : %s"
 
-#: config.c:885
+#: config.c:953
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in standard input: %s"
 msgstr ""
 "valeur numérique de configuration incorrecte '%s' pour '%s' dans l'entrée "
 "standard : %s"
 
-#: config.c:888
+#: config.c:956
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
 msgstr ""
 "valeur numérique de configuration incorrecte '%s' pour '%s' dans le blob de "
 "sous-module %s : %s"
 
-#: config.c:891
+#: config.c:959
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
 msgstr ""
 "valeur numérique de configuration incorrecte '%s' pour '%s' dans la ligne de "
 "commande %s : %s"
 
-#: config.c:894
+#: config.c:962
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in %s: %s"
 msgstr ""
 "valeur numérique de configuration incorrecte '%s' pour '%s' dans %s : %s"
 
-#: config.c:989
+#: config.c:1057
 #, c-format
 msgid "failed to expand user dir in: '%s'"
 msgstr "impossible d'étendre le répertoire utilisateur dans : '%s'"
 
-#: config.c:998
+#: config.c:1066
 #, c-format
 msgid "'%s' for '%s' is not a valid timestamp"
 msgstr "'%s' pour '%s' n'est pas un horodatage valide"
 
-#: config.c:1094 config.c:1105
+#: config.c:1171 config.c:1182
 #, c-format
 msgid "bad zlib compression level %d"
 msgstr "niveau de compression zlib incorrect %d"
 
-#: config.c:1225
+#: config.c:1307
 #, c-format
 msgid "invalid mode for object creation: %s"
 msgstr "mode invalide pour la création d'objet : %s"
 
-#: config.c:1386
+#: config.c:1473
 #, c-format
 msgid "bad pack compression level %d"
 msgstr "niveau de compression du paquet %d"
 
-#: config.c:1582
+#: config.c:1681
 msgid "unable to parse command-line config"
 msgstr "lecture de la configuration de ligne de commande impossible"
 
-#: config.c:1914
+#: config.c:2013
 msgid "unknown error occurred while reading the configuration files"
 msgstr "erreur inconnue pendant la lecture des fichiers de configuration"
 
-#: config.c:2101
+#: config.c:2200
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "%s invalide : '%s'"
 
-#: config.c:2144
+#: config.c:2243
 #, c-format
 msgid "unknown core.untrackedCache value '%s'; using 'keep' default value"
 msgstr ""
 "valeur '%s' de core.untrackedCache inconnue ; utilisation de 'keep' par "
 "défaut"
 
-#: config.c:2170
+#: config.c:2269
 #, c-format
 msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100"
 msgstr ""
 "la valeur '%d' de splitIndex.maxPercentChange devrait se situer entre 0 et "
 "100"
 
-#: config.c:2195
+#: config.c:2294
 #, c-format
 msgid "unable to parse '%s' from command-line config"
 msgstr ""
 "impossible d'analyser '%s' depuis le configuration en ligne de commande"
 
-#: config.c:2197
+#: config.c:2296
 #, c-format
 msgid "bad config variable '%s' in file '%s' at line %d"
 msgstr ""
 "variable de configuration '%s' incorrecte dans le fichier '%s' à la ligne %d"
 
-#: config.c:2256
+#: config.c:2402
 #, c-format
 msgid "%s has multiple values"
 msgstr "%s a des valeurs multiples"
 
-#: config.c:2599 config.c:2816
+#: config.c:2766 config.c:3019
 #, c-format
 msgid "fstat on %s failed"
 msgstr "échec de fstat sur %s"
 
-#: config.c:2706
+#: config.c:2905
 #, c-format
 msgid "could not set '%s' to '%s'"
 msgstr "impossible de régler '%s' à '%s'"
 
-#: config.c:2708 builtin/remote.c:776
+#: config.c:2907 builtin/remote.c:779
 #, c-format
 msgid "could not unset '%s'"
 msgstr "impossible de désinitialiser '%s'"
 
-#: connect.c:52
+#: connect.c:61
 msgid "The remote end hung up upon initial contact"
 msgstr "L'hôte distant a fermé la connexion lors du contact initial"
 
-#: connect.c:54
+#: connect.c:63
 msgid ""
 "Could not read from remote repository.\n"
 "\n"
@@ -1545,7 +1580,7 @@ msgstr ""
 "Veuillez vérifier que vous avez les droits d'accès\n"
 "et que le dépôt existe."
 
-#: connected.c:66 builtin/fsck.c:198 builtin/prune.c:144
+#: connected.c:66 builtin/fsck.c:201 builtin/prune.c:145
 msgid "Checking connectivity"
 msgstr "Vérification de la connectivité"
 
@@ -1561,12 +1596,12 @@ msgstr "impossible d'écrire dans la rev-list"
 msgid "failed to close rev-list's stdin"
 msgstr "impossible de fermer l'entrée standard du rev-list"
 
-#: convert.c:205
+#: convert.c:206
 #, c-format
 msgid "CRLF would be replaced by LF in %s."
 msgstr "Les CRLF seraient remplacés par des LF dans %s."
 
-#: convert.c:207
+#: convert.c:208
 #, c-format
 msgid ""
 "CRLF will be replaced by LF in %s.\n"
@@ -1576,12 +1611,12 @@ msgstr ""
 "Le fichier conservera ses fins de ligne d'origine dans votre copie de "
 "travail."
 
-#: convert.c:215
+#: convert.c:216
 #, c-format
 msgid "LF would be replaced by CRLF in %s"
 msgstr "Les LF seraient remplacés par des CRLF dans %s"
 
-#: convert.c:217
+#: convert.c:218
 #, c-format
 msgid ""
 "LF will be replaced by CRLF in %s.\n"
@@ -1591,6 +1626,51 @@ msgstr ""
 "Le fichier conservera ses fins de ligne d'origine dans votre copie de "
 "travail."
 
+#: convert.c:279
+#, c-format
+msgid "BOM is prohibited in '%s' if encoded as %s"
+msgstr "Aucun BOM n'est permis dans '%s' s'il est encodé comme %s"
+
+#: convert.c:286
+#, c-format
+msgid ""
+"The file '%s' contains a byte order mark (BOM). Please use UTF-%s as working-"
+"tree-encoding."
+msgstr ""
+"Le fichier '%s' contient un marqueur d'ordre d'octets (BOM). Veuillez "
+"utiliser UTF-%s comme encodage d'arbre de travail."
+
+#: convert.c:304
+#, c-format
+msgid "BOM is required in '%s' if encoded as %s"
+msgstr "Un BOM est obligatoire dans '%s' s'il est encodé comme %s"
+
+#: convert.c:306
+#, 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 ""
+"Il manque un marqueur d'ordre d'octets (BOM) au fichier '%s'. Veuillez "
+"utiliser UTF-%sBE ou UTF-%sLE (selon l'ordre désiré) comme encodage d'arbre "
+"de travail."
+
+#: convert.c:424
+#, c-format
+msgid "failed to encode '%s' from %s to %s"
+msgstr "échec de l'encodage de '%s' de %s vers %s"
+
+#: convert.c:467
+#, c-format
+msgid "encoding '%s' from %s to %s and back is not the same"
+msgstr ""
+"encoder '%s' depuis %s vers %s puis inversement ne produit pas le même "
+"contenu"
+
+#: convert.c:1225
+msgid "true/false are no valid working-tree-encodings"
+msgstr "true/false ne sont pas des encodages d'arbre de travail valides"
+
 #: date.c:116
 msgid "in the future"
 msgstr "dans le futur"
@@ -1707,24 +1787,24 @@ msgstr ""
 "Erreurs dans la variable de configuration 'diff.dirstat' :\n"
 "%s"
 
-#: diff.c:3822
+#: diff.c:3823
 #, c-format
 msgid "external diff died, stopping at %s"
 msgstr "l'application de diff externe a disparu, arrêt à %s"
 
-#: diff.c:4146
+#: diff.c:4153
 msgid "--name-only, --name-status, --check and -s are mutually exclusive"
 msgstr "--name-only, --name-status, --check et -s sont mutuellement exclusifs"
 
-#: diff.c:4149
+#: diff.c:4156
 msgid "-G, -S and --find-object are mutually exclusive"
 msgstr "-G, -S et --find-object sont mutuellement exclusifs"
 
-#: diff.c:4237
+#: diff.c:4244
 msgid "--follow requires exactly one pathspec"
 msgstr "--follow a besoin d'une spécification de chemin unique"
 
-#: diff.c:4403
+#: diff.c:4410
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -1733,24 +1813,24 @@ msgstr ""
 "Impossible d'analyser le paramètre de l'option --dirstat/-X :\n"
 "%s"
 
-#: diff.c:4417
+#: diff.c:4424
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "Impossible d'analyser le paramètre de l'option --submodule : '%s'"
 
-#: diff.c:5493
+#: diff.c:5500
 msgid "inexact rename detection was skipped due to too many files."
 msgstr ""
 "détection de renommage inexact annulée à cause d'un trop grand nombre de "
 "fichiers."
 
-#: diff.c:5496
+#: diff.c:5503
 msgid "only found copies from modified paths due to too many files."
 msgstr ""
 "recherche uniquement des copies par modification de chemin à cause d'un trop "
 "grand nombre de fichiers."
 
-#: diff.c:5499
+#: diff.c:5506
 #, c-format
 msgid ""
 "you may want to set your %s variable to at least %d and retry the command."
@@ -1758,25 +1838,25 @@ msgstr ""
 "vous souhaitez peut-être régler la variable %s à au moins %d et réessayer le "
 "commande."
 
-#: dir.c:1866
+#: dir.c:1867
 #, c-format
 msgid "could not open directory '%s'"
 msgstr "impossible d'ouvrir le répertoire '%s'"
 
-#: dir.c:2108
+#: dir.c:2109
 msgid "failed to get kernel name and information"
 msgstr "echec de l'obtention d'information de kernel"
 
-#: dir.c:2232
+#: dir.c:2233
 msgid "Untracked cache is disabled on this system or location."
 msgstr "Le cache non suivi est désactivé sur ce système ou sur cet endroit."
 
-#: dir.c:3024 dir.c:3029
+#: dir.c:3075 dir.c:3080
 #, c-format
 msgid "could not create directories for %s"
 msgstr "impossible de créer les répertoires pour %s"
 
-#: dir.c:3054
+#: dir.c:3109
 #, c-format
 msgid "could not migrate git directory from '%s' to '%s'"
 msgstr "impossible de migrer le répertoire git de '%s' vers '%s'"
@@ -1801,201 +1881,205 @@ msgstr "impossible de stat le fichier '%s'"
 msgid "Remote with no URL"
 msgstr "Dépôt distant sans URL"
 
-#: fetch-pack.c:253
+#: fetch-pack.c:254
 msgid "git fetch-pack: expected shallow list"
 msgstr "git fetch-pack : list courte attendue"
 
-#: fetch-pack.c:265
+#: fetch-pack.c:266
 msgid "git fetch-pack: expected ACK/NAK, got a flush packet"
 msgstr "git fetch-pack : ACK/NACK attendu, paquet de nettoyage reçu"
 
-#: fetch-pack.c:284 builtin/archive.c:63
+#: fetch-pack.c:285 builtin/archive.c:63
 #, c-format
 msgid "remote error: %s"
 msgstr "erreur distante : %s"
 
-#: fetch-pack.c:285
+#: fetch-pack.c:286
 #, c-format
 msgid "git fetch-pack: expected ACK/NAK, got '%s'"
 msgstr "git fetch-pack : ACK/NACK attendu, '%s' reçu"
 
-#: fetch-pack.c:337
+#: fetch-pack.c:338
 msgid "--stateless-rpc requires multi_ack_detailed"
 msgstr "--stateless-rpc nécessite multi_ack_detailed"
 
-#: fetch-pack.c:428
+#: fetch-pack.c:429 fetch-pack.c:1310
 #, c-format
 msgid "invalid shallow line: %s"
 msgstr "ligne de superficiel invalide : %s"
 
-#: fetch-pack.c:434
+#: fetch-pack.c:435 fetch-pack.c:1316
 #, c-format
 msgid "invalid unshallow line: %s"
 msgstr "ligne de fin de superficiel invalide : %s"
 
-#: fetch-pack.c:436
+#: fetch-pack.c:437 fetch-pack.c:1318
 #, c-format
 msgid "object not found: %s"
 msgstr "objet non trouvé : %s"
 
-#: fetch-pack.c:439
+#: fetch-pack.c:440 fetch-pack.c:1321
 #, c-format
 msgid "error in object: %s"
 msgstr "Erreur dans l'objet : %s"
 
-#: fetch-pack.c:441
+#: fetch-pack.c:442 fetch-pack.c:1323
 #, c-format
 msgid "no shallow found: %s"
 msgstr "Pas de superficiel trouvé : %s"
 
-#: fetch-pack.c:444
+#: fetch-pack.c:445 fetch-pack.c:1326
 #, c-format
 msgid "expected shallow/unshallow, got %s"
 msgstr "superficiel/non superficiel attendu, %s trouvé"
 
-#: fetch-pack.c:485
+#: fetch-pack.c:486
 #, c-format
 msgid "got %s %d %s"
 msgstr "réponse %s %d %s"
 
-#: fetch-pack.c:499
+#: fetch-pack.c:500
 #, c-format
 msgid "invalid commit %s"
 msgstr "commit invalide %s"
 
-#: fetch-pack.c:532
+#: fetch-pack.c:533
 msgid "giving up"
 msgstr "abandon"
 
-#: fetch-pack.c:542 progress.c:229
+#: fetch-pack.c:543 progress.c:229
 msgid "done"
 msgstr "fait"
 
-#: fetch-pack.c:554
+#: fetch-pack.c:555
 #, c-format
 msgid "got %s (%d) %s"
 msgstr "%s trouvé (%d) %s"
 
-#: fetch-pack.c:600
+#: fetch-pack.c:601
 #, c-format
 msgid "Marking %s as complete"
 msgstr "Marquage de %s comme terminé"
 
-#: fetch-pack.c:788
+#: fetch-pack.c:828
 #, c-format
 msgid "already have %s (%s)"
 msgstr "%s déjà possédé (%s)"
 
-#: fetch-pack.c:829
+#: fetch-pack.c:869
 msgid "fetch-pack: unable to fork off sideband demultiplexer"
 msgstr "fetch-pack : impossible de dupliquer le démultiplexeur latéral"
 
-#: fetch-pack.c:837
+#: fetch-pack.c:877
 msgid "protocol error: bad pack header"
 msgstr "erreur de protocole : mauvais entête de paquet"
 
-#: fetch-pack.c:895
+#: fetch-pack.c:944
 #, c-format
 msgid "fetch-pack: unable to fork off %s"
 msgstr "fetch-pack : impossible de dupliquer %s"
 
-#: fetch-pack.c:911
+#: fetch-pack.c:960
 #, c-format
 msgid "%s failed"
 msgstr "échec de %s"
 
-#: fetch-pack.c:913
+#: fetch-pack.c:962
 msgid "error in sideband demultiplexer"
 msgstr "erreur dans le démultiplexer latéral"
 
-#: fetch-pack.c:940
+#: fetch-pack.c:989
 msgid "Server does not support shallow clients"
 msgstr "Le serveur ne supporte les clients superficiels"
 
-#: fetch-pack.c:944
+#: fetch-pack.c:993
 msgid "Server supports multi_ack_detailed"
 msgstr "Le serveur supporte multi_ack_detailed"
 
-#: fetch-pack.c:947
+#: fetch-pack.c:996
 msgid "Server supports no-done"
 msgstr "Le serveur support no-done"
 
-#: fetch-pack.c:953
+#: fetch-pack.c:1002
 msgid "Server supports multi_ack"
 msgstr "Le serveur supporte multi_ack"
 
-#: fetch-pack.c:957
+#: fetch-pack.c:1006
 msgid "Server supports side-band-64k"
 msgstr "Le serveur supporte side-band-64k"
 
-#: fetch-pack.c:961
+#: fetch-pack.c:1010
 msgid "Server supports side-band"
 msgstr "Le serveru supporte side-band"
 
-#: fetch-pack.c:965
+#: fetch-pack.c:1014
 msgid "Server supports allow-tip-sha1-in-want"
 msgstr "Le serveur supporte allow-tip-sha1-in-want"
 
-#: fetch-pack.c:969
+#: fetch-pack.c:1018
 msgid "Server supports allow-reachable-sha1-in-want"
 msgstr "Le serveur supporte allow-reachable-sha1-in-want"
 
-#: fetch-pack.c:979
+#: fetch-pack.c:1028
 msgid "Server supports ofs-delta"
 msgstr "Le serveur supporte ofs-delta"
 
-#: fetch-pack.c:985
+#: fetch-pack.c:1034 fetch-pack.c:1204
 msgid "Server supports filter"
 msgstr "Le serveur supporte filter"
 
-#: fetch-pack.c:993
+#: fetch-pack.c:1042
 #, c-format
 msgid "Server version is %.*s"
 msgstr "La version du serveur est %.*s"
 
-#: fetch-pack.c:999
+#: fetch-pack.c:1048
 msgid "Server does not support --shallow-since"
 msgstr "Le receveur ne gère pas --shallow-since"
 
-#: fetch-pack.c:1003
+#: fetch-pack.c:1052
 msgid "Server does not support --shallow-exclude"
 msgstr "Le receveur ne gère pas --shallow-exclude"
 
-#: fetch-pack.c:1005
+#: fetch-pack.c:1054
 msgid "Server does not support --deepen"
 msgstr "Le receveur ne gère pas --deepen"
 
-#: fetch-pack.c:1016
+#: fetch-pack.c:1065
 msgid "no common commits"
 msgstr "pas de commit commun"
 
-#: fetch-pack.c:1028
+#: fetch-pack.c:1077 fetch-pack.c:1414
 msgid "git fetch-pack: fetch failed."
 msgstr "git fetch-pack : échec de le récupération."
 
-#: fetch-pack.c:1190
+#: fetch-pack.c:1199
+msgid "Server does not support shallow requests"
+msgstr "Le serveur ne supporte les requêtes superficielles"
+
+#: fetch-pack.c:1584
 msgid "no matching remote head"
 msgstr "pas de HEAD distante correspondante"
 
-#: fetch-pack.c:1212
+#: fetch-pack.c:1610
 #, c-format
 msgid "no such remote ref %s"
 msgstr "référence distante inconnue %s"
 
-#: fetch-pack.c:1215
+#: fetch-pack.c:1613
 #, c-format
 msgid "Server does not allow request for unadvertised object %s"
 msgstr "Le serveur n'autorise pas de requête pour l'objet %s non annoncé"
 
-#: gpg-interface.c:181
+#: gpg-interface.c:185
 msgid "gpg failed to sign the data"
 msgstr "gpg n'a pas pu signer les données"
 
-#: gpg-interface.c:211
+#: gpg-interface.c:210
 msgid "could not create temporary file"
 msgstr "impossible de créer un fichier temporaire"
 
-#: gpg-interface.c:214
+#: gpg-interface.c:213
 #, c-format
 msgid "failed writing detached signature to '%s'"
 msgstr "impossible d'écrire la signature détachée dans '%s'"
@@ -2005,36 +2089,98 @@ msgstr "impossible d'écrire la signature détachée dans '%s'"
 msgid "ignore invalid color '%.*s' in log.graphColors"
 msgstr "couleur invalide '%.*s' ignorée dans log.graphColors"
 
-#: grep.c:2022
+#: grep.c:2020
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "'%s' : lecture de %s impossible"
 
-#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81
+#: grep.c:2037 setup.c:164 builtin/clone.c:409 builtin/diff.c:81
 #: builtin/rm.c:134
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "échec du stat de '%s'"
 
-#: grep.c:2050
+#: grep.c:2048
 #, c-format
 msgid "'%s': short read"
 msgstr "'%s' : lecture tronquée"
 
-#: help.c:179
+#: help.c:23
+msgid "start a working area (see also: git help tutorial)"
+msgstr "démarrer une zone de travail (voir aussi : git help tutorial)"
+
+#: help.c:24
+msgid "work on the current change (see also: git help everyday)"
+msgstr ""
+"travailler sur la modification actuelle (voir aussi : git help revisions)"
+
+#: help.c:25
+msgid "examine the history and state (see also: git help revisions)"
+msgstr "examiner l'historique et l'état (voir aussi : git help revisions)"
+
+#: help.c:26
+msgid "grow, mark and tweak your common history"
+msgstr "agrandir, marquer et modifier votre historique"
+
+#: help.c:27
+msgid "collaborate (see also: git help workflows)"
+msgstr "collaborer (voir aussi : git help workflows)"
+
+#: help.c:31
+msgid "Main Porcelain Commands"
+msgstr "Commandes Porcelaine Principales"
+
+#: help.c:32
+msgid "Ancillary Commands / Manipulators"
+msgstr "Commandes Auxiliaires / Manipulateurs"
+
+#: help.c:33
+msgid "Ancillary Commands / Interrogators"
+msgstr "Commandes Auxiliaires / Interrogateurs"
+
+#: help.c:34
+msgid "Interacting with Others"
+msgstr "Interaction avec d'autres développeurs"
+
+#: help.c:35
+msgid "Low-level Commands / Manipulators"
+msgstr "Commandes bas-niveau / Manipulateurs"
+
+#: help.c:36
+msgid "Low-level Commands / Interrogators"
+msgstr "Commandes bas niveau / Interrogateurs"
+
+#: help.c:37
+msgid "Low-level Commands / Synching Repositories"
+msgstr "Commandes bas niveau / Synchronisation de dépôts"
+
+#: help.c:38
+msgid "Low-level Commands / Internal Helpers"
+msgstr "Commandes bas niveau / Assistants internes"
+
+#: help.c:293
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "commandes git disponibles dans '%s'"
 
-#: help.c:186
+#: help.c:300
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "commandes git disponibles depuis un autre endroit de votre $PATH"
 
-#: help.c:217
+#: help.c:309
 msgid "These are common Git commands used in various situations:"
 msgstr "Ci-dessous les commandes Git habituelles dans diverses situations :"
 
-#: help.c:281
+#: help.c:358 git.c:90
+#, c-format
+msgid "unsupported command listing type '%s'"
+msgstr "type de liste de commandes non supporté '%s'"
+
+#: help.c:405
+msgid "The common Git guides are:"
+msgstr "Les guides Git populaires sont :"
+
+#: help.c:467
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -2043,33 +2189,33 @@ msgstr ""
 "'%s' semble être une commande git, mais elle n'a pas pu\n"
 "être exécutée. Peut-être git-%s est-elle cassée ?"
 
-#: help.c:336
+#: help.c:526
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Ahem. Votre système n'indique aucune commande Git."
 
-#: help.c:358
+#: help.c:548
 #, c-format
 msgid "WARNING: You called a Git command named '%s', which does not exist."
 msgstr ""
 "ATTENTION : vous avez invoqué une commande Git nommée '%s' qui n'existe pas."
 
-#: help.c:363
+#: help.c:553
 #, c-format
 msgid "Continuing under the assumption that you meant '%s'."
 msgstr "Continuons en supposant que vous avez voulu dire '%s'."
 
-#: help.c:368
+#: help.c:558
 #, c-format
 msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
 msgstr ""
 "Continuons dans %0.1f secondes en supposant que vous avez voulu dire '%s'."
 
-#: help.c:376
+#: help.c:566
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git : '%s' n'est pas une commande git. Voir 'git --help'."
 
-#: help.c:380
+#: help.c:570
 msgid ""
 "\n"
 "The most similar command is"
@@ -2083,16 +2229,16 @@ msgstr[1] ""
 "\n"
 "Les commandes les plus ressemblantes sont"
 
-#: help.c:395
+#: help.c:585
 msgid "git version [<options>]"
 msgstr "git version [<options>]"
 
-#: help.c:462
+#: help.c:652
 #, c-format
 msgid "%s: %s - %s"
 msgstr "%s: %s - %s"
 
-#: help.c:466
+#: help.c:656
 msgid ""
 "\n"
 "Did you mean this?"
@@ -2160,7 +2306,7 @@ msgstr "nom d'identifiant vide (pour <%s>) non permis"
 msgid "name consists only of disallowed characters: %s"
 msgstr "le nom n'est constitué que de caractères interdits : %s"
 
-#: ident.c:416 builtin/commit.c:582
+#: ident.c:416 builtin/commit.c:587
 #, c-format
 msgid "invalid date format: %s"
 msgstr "format de date invalide : %s"
@@ -2197,82 +2343,163 @@ msgstr ""
 msgid "Unable to create '%s.lock': %s"
 msgstr "Impossible de créer '%s.lock' : %s"
 
-#: merge.c:74
+#: merge.c:71
 msgid "failed to read the cache"
 msgstr "impossible de lire le cache"
 
-#: merge.c:134 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
-#: builtin/checkout.c:599 builtin/clone.c:759
+#: merge.c:136 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
+#: builtin/checkout.c:606 builtin/clone.c:761
 msgid "unable to write new index file"
 msgstr "impossible d'écrire le nouveau fichier d'index"
 
-#: merge-recursive.c:235
+#: merge-recursive.c:298
 msgid "(bad commit)\n"
 msgstr "(mauvais commit)\n"
 
-#: merge-recursive.c:257 merge-recursive.c:265
+#: merge-recursive.c:320
+#, c-format
+msgid "add_cacheinfo failed for path '%s'; merge aborting."
+msgstr "échec de addinfo_cache pour le chemin '%s' ; abandon de la fusion."
+
+#: merge-recursive.c:328
 #, c-format
-msgid "addinfo_cache failed for path '%s'"
-msgstr "échec de addinfo_cache pour le chemin '%s'"
+msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
+msgstr "échec de addinfo_cache pour le chemin '%s' ; abandon de la fusion."
 
-#: merge-recursive.c:329
+#: merge-recursive.c:410
 msgid "error building trees"
 msgstr "erreur de construction des arbres"
 
-#: merge-recursive.c:771
+#: merge-recursive.c:881
 #, c-format
 msgid "failed to create path '%s'%s"
 msgstr "impossible de créer le chemin '%s' %s"
 
-#: merge-recursive.c:782
+#: merge-recursive.c:892
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr "Suppression de %s pour faire de la place pour le sous-répertoire\n"
 
-#: merge-recursive.c:796 merge-recursive.c:815
+#: merge-recursive.c:906 merge-recursive.c:925
 msgid ": perhaps a D/F conflict?"
 msgstr ": peut-être un conflit D/F ?"
 
-#: merge-recursive.c:805
+#: merge-recursive.c:915
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
 msgstr "refus de perdre le fichier non suivi '%s'"
 
-#: merge-recursive.c:847 builtin/cat-file.c:37
+#: merge-recursive.c:957 builtin/cat-file.c:37
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr "impossible de lire l'objet %s '%s'"
 
-#: merge-recursive.c:849
+#: merge-recursive.c:959
 #, c-format
 msgid "blob expected for %s '%s'"
 msgstr "blob attendu pour %s '%s'"
 
-#: merge-recursive.c:873
+#: merge-recursive.c:983
 #, c-format
 msgid "failed to open '%s': %s"
 msgstr "échec à l'ouverture de '%s' : %s"
 
-#: merge-recursive.c:884
+#: merge-recursive.c:994
 #, c-format
 msgid "failed to symlink '%s': %s"
 msgstr "échec à la création du lien symbolique '%s' : %s"
 
-#: merge-recursive.c:889
+#: merge-recursive.c:999
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
 msgstr "ne sait pas traiter %06o %s '%s'"
 
-#: merge-recursive.c:1029
+#: merge-recursive.c:1186
+#, c-format
+msgid "Failed to merge submodule %s (not checked out)"
+msgstr "Échec de la fusion du sous-module %s (non extrait)"
+
+#: merge-recursive.c:1193
+#, c-format
+msgid "Failed to merge submodule %s (commits not present)"
+msgstr "Échec de fusion du sous-module %s (commits non présents)"
+
+#: merge-recursive.c:1200
+#, 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 "
+"base de fusion)"
+
+#: merge-recursive.c:1208 merge-recursive.c:1220
+#, c-format
+msgid "Fast-forwarding submodule %s to the following commit:"
+msgstr "Avance rapide du sous-module %s au commit suivant :"
+
+#: merge-recursive.c:1211 merge-recursive.c:1223
+#, c-format
+msgid "Fast-forwarding submodule %s"
+msgstr "Avance rapide du sous-module %s"
+
+#: merge-recursive.c:1245
+#, c-format
+msgid "Failed to merge submodule %s (merge following commits not found)"
+msgstr ""
+"Échec de fusion du sous-module %s (fusion suivant les commits non trouvée)"
+
+#: merge-recursive.c:1249
+#, c-format
+msgid "Failed to merge submodule %s (not fast-forward)"
+msgstr "Échec de fusion du sous-module %s (pas en avance rapide)"
+
+#: merge-recursive.c:1250
+msgid "Found a possible merge resolution for the submodule:\n"
+msgstr "Résolution possible de fusion trouvée pour le sous-module :\n"
+
+#: merge-recursive.c:1253
+#, 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 ""
+"Si c'est correct, ajoutez le simplement à l'index\n"
+"en utilisant par exemple :\n"
+"\n"
+"  git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"qui acceptera cette suggestion.\n"
+
+#: merge-recursive.c:1262
+#, c-format
+msgid "Failed to merge submodule %s (multiple merges found)"
+msgstr "Échec de fusion du sous-module %s (plusieurs fusions trouvées)"
+
+#: merge-recursive.c:1321
 msgid "Failed to execute internal merge"
 msgstr "Échec à l'exécution de la fusion interne"
 
-#: merge-recursive.c:1034
+#: merge-recursive.c:1326
 #, c-format
 msgid "Unable to add %s to database"
 msgstr "Impossible d'ajouter %s à la base de données"
 
-#: merge-recursive.c:1146
+#: merge-recursive.c:1358
+#, c-format
+msgid "Auto-merging %s"
+msgstr "Fusion automatique de %s"
+
+#: merge-recursive.c:1423
+#, c-format
+msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
+msgstr ""
+"Erreur : refus de perdre le fichier non suivi %s ; écriture dans %s à la "
+"place."
+
+#: merge-recursive.c:1475
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2281,7 +2508,7 @@ msgstr ""
 "CONFLIT (%s/suppression) : %s supprimé dans %s et %s dans %s. Version %s de "
 "%s laissée dans l'arbre."
 
-#: merge-recursive.c:1151
+#: merge-recursive.c:1480
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2290,7 +2517,7 @@ msgstr ""
 "CONFLIT (%s/suppression) : %s supprimé dans %s et %s à %s dans %s. Version "
 "%s de %s laissée dans l'arbre."
 
-#: merge-recursive.c:1158
+#: merge-recursive.c:1487
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2299,7 +2526,7 @@ msgstr ""
 "CONFLIT (%s/suppression) : %s supprimé dans %s et %s dans %s. Version %s de "
 "%s laissée dans l'arbre dans le fichier %s."
 
-#: merge-recursive.c:1163
+#: merge-recursive.c:1492
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2308,20 +2535,31 @@ msgstr ""
 "CONFLIT (%s/suppression) : %s supprimé dans %s et %s à %s dans %s. Version "
 "%s de %s laissée dans l'arbre dans le fichier %s."
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "rename"
 msgstr "renommage"
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "renamed"
 msgstr "renommé"
 
-#: merge-recursive.c:1254
+#: merge-recursive.c:1580 merge-recursive.c:1736 merge-recursive.c:2368
+#: merge-recursive.c:3086
+#, c-format
+msgid "Refusing to lose dirty file at %s"
+msgstr "Refus de perdre le fichier modifié %s"
+
+#: merge-recursive.c:1594
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr "%s est un répertoire dans %s ajouté plutôt comme %s"
 
-#: merge-recursive.c:1279
+#: merge-recursive.c:1599
+#, c-format
+msgid "Refusing to lose untracked file at %s; adding as %s instead"
+msgstr "Refus de perdre le fichier non suivi %s ; ajout comme %s à la place"
+
+#: merge-recursive.c:1625
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
@@ -2330,142 +2568,189 @@ msgstr ""
 "CONFLIT (renommage/renommage) : Renommage de \"%s\"->\"%s\" dans la branche "
 "\"%s\" et renommage \"%s\"->\"%s\" dans \"%s\"%s"
 
-#: merge-recursive.c:1284
+#: merge-recursive.c:1630
 msgid " (left unresolved)"
 msgstr " (laissé non résolu)"
 
-#: merge-recursive.c:1346
+#: merge-recursive.c:1694
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
 "CONFLIT (renommage/renommage) : renommage '%s'->'%s' dans %s. Renommage '%s'-"
 ">'%s' dans %s"
 
-#: merge-recursive.c:1379
+#: merge-recursive.c:1733
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr "Renommage de %s en %s et de %s en %s à la place"
 
-#: merge-recursive.c:1582
+#: merge-recursive.c:1745
+#, c-format
+msgid "Refusing to lose untracked file at %s, even though it's in the way."
+msgstr "Refus de perdre le fichier non suivi %s, même s'il gêne."
+
+#: merge-recursive.c:1951
+#, c-format
+msgid ""
+"CONFLICT (directory rename split): Unclear where to place %s because "
+"directory %s was renamed to multiple other directories, with no destination "
+"getting a majority of the files."
+msgstr ""
+"CONFLIT (renommage de répertoire coupé) : la place de %s n'est pas claire "
+"parce que le répertoire %s a été renommé en plusieurs autres répertoires, "
+"sans aucune destination récupérant la majorité des fichiers."
+
+#: merge-recursive.c:1983
+#, c-format
+msgid ""
+"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 ""
+"CONFLIT (renommage implicite de répertoire) : le répertoire/fichier %s gêne "
+"des renommages implicites de répertoire déplaçant les chemins suivants : %s."
+
+#: merge-recursive.c:1993
+#, 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 ""
+"CONFLIT (renommage implicite de répertoire) : impossible de transformer "
+"plusieurs chemins sur %s ; les chemins concernés sont : %s"
+
+#: merge-recursive.c:2085
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-"
+">%s in %s"
+msgstr ""
+"CONFLIT (renommage/renommage) : renommage du répertoire %s->%s dans %s. "
+"Renommage de répertoire %s->%s dans %s"
+
+#: merge-recursive.c:2330
+#, c-format
+msgid ""
+"WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
+"renamed."
+msgstr ""
+"AVERTISSEMENT : ne renomme pas %s->%s dans %s, parce que %s lui-même a été "
+"renommé."
+
+#: merge-recursive.c:2736
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
 msgstr ""
 "CONFLIT (renommage/ajout) : Renommage de %s->%s dans %s. %s ajouté dans %s"
 
-#: merge-recursive.c:1597
+#: merge-recursive.c:2751
 #, c-format
 msgid "Adding merged %s"
 msgstr "Ajout de %s fusionné"
 
-#: merge-recursive.c:1604 merge-recursive.c:1834
+#: merge-recursive.c:2758 merge-recursive.c:3089
 #, c-format
 msgid "Adding as %s instead"
 msgstr "Ajout plutôt comme %s"
 
-#: merge-recursive.c:1661
+#: merge-recursive.c:2914
 #, c-format
 msgid "cannot read object %s"
 msgstr "impossible de lire l'objet %s"
 
-#: merge-recursive.c:1664
+#: merge-recursive.c:2917
 #, c-format
 msgid "object %s is not a blob"
 msgstr "l'objet %s n'est pas un blob"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modify"
 msgstr "modification"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modified"
 msgstr "modifié"
 
-#: merge-recursive.c:1743
+#: merge-recursive.c:2997
 msgid "content"
 msgstr "contenu"
 
-#: merge-recursive.c:1750
+#: merge-recursive.c:3004
 msgid "add/add"
 msgstr "ajout/ajout"
 
-#: merge-recursive.c:1786
+#: merge-recursive.c:3046
 #, c-format
 msgid "Skipped %s (merged same as existing)"
 msgstr "%s sauté (fusion identique à l'existant)"
 
-#: merge-recursive.c:1800
-#, c-format
-msgid "Auto-merging %s"
-msgstr "Fusion automatique de %s"
-
-#: merge-recursive.c:1804 git-submodule.sh:879
+#: merge-recursive.c:3055 git-submodule.sh:895
 msgid "submodule"
 msgstr "sous-module"
 
-#: merge-recursive.c:1805
+#: merge-recursive.c:3056
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
 msgstr "CONFLIT (%s) : Conflit de fusion dans %s"
 
-#: merge-recursive.c:1899
+#: merge-recursive.c:3178
 #, c-format
 msgid "Removing %s"
 msgstr "Suppression de %s"
 
-#: merge-recursive.c:1925
+#: merge-recursive.c:3204
 msgid "file/directory"
 msgstr "fichier/répertoire"
 
-#: merge-recursive.c:1931
+#: merge-recursive.c:3210
 msgid "directory/file"
 msgstr "répertoire/fichier"
 
-#: merge-recursive.c:1938
+#: merge-recursive.c:3217
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
 msgstr ""
 "CONFLIT (%s) : Il y a un répertoire nommé %s dans %s. Ajout de %s comme %s"
 
-#: merge-recursive.c:1947
+#: merge-recursive.c:3226
 #, c-format
 msgid "Adding %s"
 msgstr "Ajout de %s"
 
-#: merge-recursive.c:1987
+#: merge-recursive.c:3267
 #, c-format
 msgid "Dirty index: cannot merge (dirty: %s)"
 msgstr "Index sale : fusion impossible (sales : %s)"
 
-#: merge-recursive.c:1991
+#: merge-recursive.c:3271
 msgid "Already up to date!"
 msgstr "Déjà à jour !"
 
-#: merge-recursive.c:2000
+#: merge-recursive.c:3280
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr "échec de fusion des arbres %s et %s"
 
-#: merge-recursive.c:2097
+#: merge-recursive.c:3379
 msgid "Merging:"
 msgstr "Fusion :"
 
-#: merge-recursive.c:2110
+#: merge-recursive.c:3392
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] "%u ancêtre commun trouvé :"
 msgstr[1] "%u ancêtres communs trouvés :"
 
-#: merge-recursive.c:2149
+#: merge-recursive.c:3431
 msgid "merge returned no commit"
 msgstr "la fusion n'a pas retourné de commit"
 
-#: merge-recursive.c:2212
+#: merge-recursive.c:3495
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr "Impossible d'analyser l'objet '%s'"
 
-#: merge-recursive.c:2228 builtin/merge.c:657 builtin/merge.c:816
+#: merge-recursive.c:3511 builtin/merge.c:659 builtin/merge.c:816
 msgid "Unable to write index."
 msgstr "Impossible d'écrire l'index."
 
@@ -2508,31 +2793,31 @@ msgstr "Refus de réécrire des notes dans %s (hors de refs/notes/)"
 msgid "Bad %s value: '%s'"
 msgstr "Mauvaise valeur de %s : '%s'"
 
-#: object.c:239
+#: object.c:242
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "impossible d'analyser l'objet : %s"
 
-#: packfile.c:561
+#: packfile.c:563
 msgid "offset before end of packfile (broken .idx?)"
 msgstr "offset avant la fin du fichier paquet (.idx cassé ?)"
 
-#: packfile.c:1694
+#: packfile.c:1742
 #, c-format
 msgid "offset before start of pack index for %s (corrupt index?)"
 msgstr "offset avant le début de l'index de paquet pour %s (index corrompu ?)"
 
-#: packfile.c:1698
+#: packfile.c:1746
 #, c-format
 msgid "offset beyond end of pack index for %s (truncated index?)"
 msgstr ""
 "offset au delà de la fin de l'index de paquet pour %s (index tronqué ?)"
 
-#: parse-options.c:619
+#: parse-options.c:621
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:638
+#: parse-options.c:640
 #, c-format
 msgid "usage: %s"
 msgstr "usage : %s"
@@ -2540,26 +2825,31 @@ msgstr "usage : %s"
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation.
 #.
-#: parse-options.c:644
+#: parse-options.c:646
 #, c-format
 msgid "   or: %s"
 msgstr "   ou : %s"
 
-#: parse-options.c:647
+#: parse-options.c:649
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:686
+#: parse-options.c:688
 msgid "-NUM"
 msgstr "-NUM"
 
-#: parse-options-cb.c:108
+#: parse-options-cb.c:44
+#, c-format
+msgid "malformed expiration date '%s'"
+msgstr "date d'expiration malformée : '%s'"
+
+#: parse-options-cb.c:112
 #, c-format
 msgid "malformed object name '%s'"
 msgstr "nom d'objet malformé '%s'"
 
-#: path.c:891
+#: path.c:892
 #, c-format
 msgid "Could not make %s writable by group"
 msgstr "Impossible de rendre %s inscriptible pour le groupe"
@@ -2647,7 +2937,7 @@ msgstr "le chemin '%s' est au-delà d'un lien symbolique"
 msgid "unable to parse --pretty format"
 msgstr "impossible d'analyser le format --pretty"
 
-#: read-cache.c:1473
+#: read-cache.c:1500
 #, c-format
 msgid ""
 "index.version set, but the value is invalid.\n"
@@ -2656,7 +2946,7 @@ msgstr ""
 "version d'index renseignée, mais la valeur est invalide.\n"
 "Utilisation de la version %i"
 
-#: read-cache.c:1483
+#: read-cache.c:1510
 #, c-format
 msgid ""
 "GIT_INDEX_VERSION set, but the value is invalid.\n"
@@ -2665,53 +2955,54 @@ msgstr ""
 "GIT_INDEX_VERSION est renseigné, mais la valeur est invalide.\n"
 "Utilisation de la version %i"
 
-#: read-cache.c:2375 sequencer.c:3248 wrapper.c:658 builtin/merge.c:1049
+#: read-cache.c:2404 sequencer.c:4338 wrapper.c:658 builtin/merge.c:1048
 #, c-format
 msgid "could not close '%s'"
 msgstr "impossible de fermer '%s'"
 
-#: read-cache.c:2448 sequencer.c:1900 sequencer.c:2627
+#: read-cache.c:2477 sequencer.c:2102 sequencer.c:3234
 #, c-format
 msgid "could not stat '%s'"
 msgstr "stat impossible de '%s'"
 
-#: read-cache.c:2461
+#: read-cache.c:2490
 #, c-format
 msgid "unable to open git dir: %s"
 msgstr "impossible d'ouvrir le répertoire git : %s"
 
-#: read-cache.c:2473
+#: read-cache.c:2502
 #, c-format
 msgid "unable to unlink: %s"
 msgstr "échec lors de l'unlink : %s"
 
-#: refs.c:706
+#: refs.c:732 sequencer.c:4334 sequencer.c:4393 wrapper.c:225 wrapper.c:395
+#: builtin/am.c:779
 #, c-format
-msgid "Could not open '%s' for writing"
-msgstr "Impossible d'ouvrir '%s' en écriture"
+msgid "could not open '%s' for writing"
+msgstr "impossible d'ouvrir '%s' en écriture"
 
-#: refs.c:1850
+#: refs.c:1880
 msgid "ref updates forbidden inside quarantine environment"
 msgstr "mises à jour des références interdites en environnement de quarantaine"
 
-#: refs/files-backend.c:1189
+#: refs/files-backend.c:1191
 #, c-format
 msgid "could not remove reference %s"
 msgstr "impossible de supprimer la référence %s"
 
-#: refs/files-backend.c:1203 refs/packed-backend.c:1528
-#: refs/packed-backend.c:1538
+#: refs/files-backend.c:1205 refs/packed-backend.c:1531
+#: refs/packed-backend.c:1541
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "Impossible de supprimer la référence %s : %s"
 
-#: refs/files-backend.c:1206 refs/packed-backend.c:1541
+#: refs/files-backend.c:1208 refs/packed-backend.c:1544
 #, c-format
 msgid "could not delete references: %s"
 msgstr "impossible de supprimer les références : %s"
 
 # à priori on parle d'une branche ici
-#: ref-filter.c:35 wt-status.c:1842
+#: ref-filter.c:35 wt-status.c:1850
 msgid "gone"
 msgstr "disparue"
 
@@ -2730,157 +3021,162 @@ msgstr "en retard de %d"
 msgid "ahead %d, behind %d"
 msgstr "en avance de %d, en retard de %d"
 
-#: ref-filter.c:107
+#: ref-filter.c:121
 #, c-format
 msgid "expected format: %%(color:<color>)"
 msgstr "format attendu : %%(color:<couleur>)"
 
-#: ref-filter.c:109
+#: ref-filter.c:123
 #, c-format
 msgid "unrecognized color: %%(color:%s)"
 msgstr "couleur non reconnue : %%(color:%s)"
 
-#: ref-filter.c:129
+#: ref-filter.c:145
 #, c-format
 msgid "Integer value expected refname:lstrip=%s"
 msgstr "Valeur entière attendue refname:lstrip=%s"
 
-#: ref-filter.c:133
+#: ref-filter.c:149
 #, c-format
 msgid "Integer value expected refname:rstrip=%s"
 msgstr "Valeur entière attendue refname:rstrip=%s"
 
-#: ref-filter.c:135
+#: ref-filter.c:151
 #, c-format
 msgid "unrecognized %%(%s) argument: %s"
 msgstr "argument %%(%s) non reconnu : %s"
 
-#: ref-filter.c:184
+#: ref-filter.c:206
 #, c-format
 msgid "%%(body) does not take arguments"
 msgstr "%%(body) n'accepte pas d'argument"
 
-#: ref-filter.c:191
+#: ref-filter.c:215
 #, c-format
 msgid "%%(subject) does not take arguments"
 msgstr "%%(subject) n'accepte pas d'argument"
 
-#: ref-filter.c:209
+#: ref-filter.c:235
 #, c-format
 msgid "unknown %%(trailers) argument: %s"
 msgstr "argument %%(trailers) inconnu : %s"
 
-#: ref-filter.c:232
+#: ref-filter.c:264
 #, c-format
 msgid "positive value expected contents:lines=%s"
 msgstr "valeur positive attendue contents:lines=%s"
 
-#: ref-filter.c:234
+#: ref-filter.c:266
 #, c-format
 msgid "unrecognized %%(contents) argument: %s"
 msgstr "argument %%(contents) non reconnu : %s"
 
-#: ref-filter.c:247
+#: ref-filter.c:281
 #, c-format
 msgid "positive value expected objectname:short=%s"
 msgstr "valeur positive attendue objectname:short=%s"
 
-#: ref-filter.c:251
+#: ref-filter.c:285
 #, c-format
 msgid "unrecognized %%(objectname) argument: %s"
 msgstr "argument %%(objectname) non reconnu : %s"
 
-#: ref-filter.c:278
+#: ref-filter.c:315
 #, c-format
 msgid "expected format: %%(align:<width>,<position>)"
 msgstr "format attendu : %%(align:<largeur>,<position>)"
 
-#: ref-filter.c:290
+#: ref-filter.c:327
 #, c-format
 msgid "unrecognized position:%s"
 msgstr "position non reconnue : %s"
 
-#: ref-filter.c:294
+#: ref-filter.c:334
 #, c-format
 msgid "unrecognized width:%s"
 msgstr "largeur non reconnue : %s"
 
-#: ref-filter.c:300
+#: ref-filter.c:343
 #, c-format
 msgid "unrecognized %%(align) argument: %s"
 msgstr "argument %%(align) non reconnu : %s"
 
-#: ref-filter.c:304
+#: ref-filter.c:351
 #, c-format
 msgid "positive width expected with the %%(align) atom"
 msgstr "valeur positive attendue avec l'atome %%(align)"
 
-#: ref-filter.c:319
+#: ref-filter.c:369
 #, c-format
 msgid "unrecognized %%(if) argument: %s"
 msgstr "argument %%(if) non reconnu : %s"
 
-#: ref-filter.c:409
+#: ref-filter.c:464
 #, c-format
 msgid "malformed field name: %.*s"
 msgstr "nom de champ malformé %.*s"
 
-#: ref-filter.c:435
+#: ref-filter.c:491
 #, c-format
 msgid "unknown field name: %.*s"
 msgstr "nom de champ inconnu : %.*s"
 
-#: ref-filter.c:547
+#: ref-filter.c:608
 #, c-format
 msgid "format: %%(if) atom used without a %%(then) atom"
 msgstr "format : atome %%(if) utilisé sans un atome %%(then)"
 
-#: ref-filter.c:607
+#: ref-filter.c:671
 #, c-format
 msgid "format: %%(then) atom used without an %%(if) atom"
 msgstr "format : atome %%(then) utilisé sans un atome %%(if)"
 
-#: ref-filter.c:609
+#: ref-filter.c:673
 #, c-format
 msgid "format: %%(then) atom used more than once"
 msgstr "format : atome %%(then) utilisé plus d'une fois"
 
-#: ref-filter.c:611
+#: ref-filter.c:675
 #, c-format
 msgid "format: %%(then) atom used after %%(else)"
 msgstr "format: atome %%(then) utilisé après %%(else)"
 
-#: ref-filter.c:637
+#: ref-filter.c:703
 #, c-format
 msgid "format: %%(else) atom used without an %%(if) atom"
 msgstr "format : atome %%(else) utilisé sans un atome %%(if)"
 
-#: ref-filter.c:639
+#: ref-filter.c:705
 #, c-format
 msgid "format: %%(else) atom used without a %%(then) atom"
 msgstr "format : atome %%(else) utilisé sans un atome %%(then)"
 
-#: ref-filter.c:641
+#: ref-filter.c:707
 #, c-format
 msgid "format: %%(else) atom used more than once"
 msgstr "format : atome %%(else) utilisé plus d'une fois"
 
-#: ref-filter.c:654
+#: ref-filter.c:722
 #, c-format
 msgid "format: %%(end) atom used without corresponding atom"
 msgstr "format : atome %%(end) utilisé sans atome correspondant"
 
-#: ref-filter.c:709
+#: ref-filter.c:779
 #, c-format
 msgid "malformed format string %s"
 msgstr "Chaîne de formatage mal formée %s"
 
-#: ref-filter.c:1313
+#: ref-filter.c:1387
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(aucune branche, rebasage de %s)"
 
-#: ref-filter.c:1316
+#: ref-filter.c:1390
+#, c-format
+msgid "(no branch, rebasing detached HEAD %s)"
+msgstr "(aucune branche, rebasage de la HEAD détachée %s)"
+
+#: ref-filter.c:1393
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(aucune branche, bisect a démarré sur %s)"
@@ -2888,7 +3184,7 @@ msgstr "(aucune branche, bisect a démarré sur %s)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached at " in wt-status.c
 #.
-#: ref-filter.c:1324
+#: ref-filter.c:1401
 #, c-format
 msgid "(HEAD detached at %s)"
 msgstr "(HEAD détachée sur %s)"
@@ -2896,150 +3192,150 @@ msgstr "(HEAD détachée sur %s)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached from " in wt-status.c
 #.
-#: ref-filter.c:1331
+#: ref-filter.c:1408
 #, c-format
 msgid "(HEAD detached from %s)"
 msgstr "(HEAD détachée depuis %s)"
 
-#: ref-filter.c:1335
+#: ref-filter.c:1412
 msgid "(no branch)"
 msgstr "(aucune branche)"
 
-#: ref-filter.c:1364
+#: ref-filter.c:1442
 #, c-format
 msgid "missing object %s for %s"
 msgstr "objet manquant %s pour %s"
 
-#: ref-filter.c:1367
+#: ref-filter.c:1445
 #, c-format
 msgid "parse_object_buffer failed on %s for %s"
 msgstr "echec de parse_object_buffer sur %s pour %s"
 
-#: ref-filter.c:1819
+#: ref-filter.c:1902
 #, c-format
 msgid "malformed object at '%s'"
 msgstr "objet malformé à '%s'"
 
-#: ref-filter.c:1886
+#: ref-filter.c:1984
 #, c-format
 msgid "ignoring ref with broken name %s"
 msgstr "réf avec un nom cassé %s ignoré"
 
-#: ref-filter.c:1891
+#: ref-filter.c:1989
 #, c-format
 msgid "ignoring broken ref %s"
 msgstr "réf cassé %s ignoré"
 
-#: ref-filter.c:2152
+#: ref-filter.c:2261
 #, c-format
 msgid "format: %%(end) atom missing"
 msgstr "format: atome %%(end) manquant"
 
-#: ref-filter.c:2246
+#: ref-filter.c:2365
 #, c-format
 msgid "malformed object name %s"
 msgstr "nom d'objet malformé %s"
 
-#: remote.c:795
+#: remote.c:605
 #, c-format
 msgid "Cannot fetch both %s and %s to %s"
 msgstr "Impossible de récupérer à la fois %s et %s pour %s"
 
-#: remote.c:799
+#: remote.c:609
 #, c-format
 msgid "%s usually tracks %s, not %s"
 msgstr "%s suit habituellement %s, pas %s"
 
-#: remote.c:803
+#: remote.c:613
 #, c-format
 msgid "%s tracks both %s and %s"
 msgstr "%s suit à la fois %s et %s"
 
-#: remote.c:811
+#: remote.c:621
 msgid "Internal error"
 msgstr "Erreur interne"
 
-#: remote.c:1726 remote.c:1828
+#: remote.c:1534 remote.c:1635
 msgid "HEAD does not point to a branch"
 msgstr "HEAD ne pointe pas sur une branche"
 
-#: remote.c:1735
+#: remote.c:1543
 #, c-format
 msgid "no such branch: '%s'"
 msgstr "pas de branche '%s'"
 
-#: remote.c:1738
+#: remote.c:1546
 #, c-format
 msgid "no upstream configured for branch '%s'"
 msgstr "aucune branche amont configurée pour la branche '%s'"
 
-#: remote.c:1744
+#: remote.c:1552
 #, c-format
 msgid "upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "la branche amont '%s' n'est pas stockée comme branche de suivi"
 
-#: remote.c:1759
+#: remote.c:1567
 #, c-format
 msgid "push destination '%s' on remote '%s' has no local tracking branch"
 msgstr ""
 "la destination de poussée '%s' sur le serveur distant '%s' n'a pas de "
 "branche locale de suivi"
 
-#: remote.c:1771
+#: remote.c:1579
 #, c-format
 msgid "branch '%s' has no remote for pushing"
 msgstr "la branche '%s' n'a aucune branche distante de poussée"
 
-#: remote.c:1782
+#: remote.c:1589
 #, c-format
 msgid "push refspecs for '%s' do not include '%s'"
 msgstr "les références de spec pour '%s' n'incluent pas '%s'"
 
-#: remote.c:1795
+#: remote.c:1602
 msgid "push has no destination (push.default is 'nothing')"
 msgstr "la poussée n'a pas de destination (push.default vaut 'nothing')"
 
-#: remote.c:1817
+#: remote.c:1624
 msgid "cannot resolve 'simple' push to a single destination"
 msgstr ""
 "impossible de résoudre une poussée 'simple' pour une destination unique"
 
-#: remote.c:2132
+#: remote.c:1939
 #, c-format
 msgid "Your branch is based on '%s', but the upstream is gone.\n"
 msgstr "Votre branche est basée sur '%s', mais la branche amont a disparu.\n"
 
-#: remote.c:2136
+#: remote.c:1943
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
 msgstr "  (utilisez \"git branch --unset-upstream\" pour corriger)\n"
 
-#: remote.c:2139
+#: remote.c:1946
 #, c-format
 msgid "Your branch is up to date with '%s'.\n"
 msgstr "Votre branche est à jour avec '%s'.\n"
 
-#: remote.c:2143
+#: remote.c:1950
 #, c-format
 msgid "Your branch and '%s' refer to different commits.\n"
 msgstr "Votre branche et '%s' font référence à des commits différents.\n"
 
-#: remote.c:2146
+#: remote.c:1953
 #, c-format
 msgid "  (use \"%s\" for details)\n"
 msgstr "  (utilisez \"%s\" pour plus de détails)\n"
 
-#: remote.c:2150
+#: remote.c:1957
 #, 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] "Votre branche est en avance sur '%s' de %d commit.\n"
 msgstr[1] "Votre branche est en avance sur '%s' de %d commits.\n"
 
-#: remote.c:2156
+#: remote.c:1963
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (utilisez \"git push\" pour publier vos commits locaux)\n"
 
-#: remote.c:2159
+#: remote.c:1966
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -3051,11 +3347,11 @@ msgstr[1] ""
 "Votre branche est en retard sur '%s' de %d commits, et peut être mise à jour "
 "en avance rapide.\n"
 
-#: remote.c:2167
+#: remote.c:1974
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (utilisez \"git pull\" pour mettre à jour votre branche locale)\n"
 
-#: remote.c:2170
+#: remote.c:1977
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -3070,29 +3366,29 @@ msgstr[1] ""
 "Votre branche et '%s' ont divergé,\n"
 "et ont %d et %d commits différents chacune respectivement.\n"
 
-#: remote.c:2180
+#: remote.c:1987
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr ""
 "  (utilisez \"git pull\" pour fusionner la branche distante dans la vôtre)\n"
 
-#: revision.c:2277
+#: revision.c:2289
 msgid "your current branch appears to be broken"
 msgstr "votre branche actuelle semble cassée"
 
-#: revision.c:2280
+#: revision.c:2292
 #, c-format
 msgid "your current branch '%s' does not have any commits yet"
 msgstr "votre branche actuelle '%s' ne contient encore aucun commit"
 
-#: revision.c:2477
+#: revision.c:2489
 msgid "--first-parent is incompatible with --bisect"
 msgstr "--first-parent est incompatible avec --bisect"
 
-#: run-command.c:731
+#: run-command.c:728
 msgid "open /dev/null failed"
 msgstr "échec de l'ouverture de /dev/null"
 
-#: run-command.c:1274
+#: run-command.c:1271
 #, c-format
 msgid ""
 "The '%s' hook was ignored because it's not set as executable.\n"
@@ -3104,7 +3400,9 @@ msgstr ""
 
 #: send-pack.c:141
 msgid "unexpected flush packet while reading remote unpack status"
-msgstr "paquet de nettoyage inattendu pendant la lecture de l'état de dépaquetage distant"
+msgstr ""
+"paquet de nettoyage inattendu pendant la lecture de l'état de dépaquetage "
+"distant"
 
 #: send-pack.c:143
 #, c-format
@@ -3140,29 +3438,34 @@ msgstr "Le receveur ne gère pas les poussées avec --atomic"
 msgid "the receiving end does not support push options"
 msgstr "Le receveur ne gère pas les options de poussées"
 
-#: sequencer.c:158
+#: sequencer.c:175
 #, c-format
 msgid "invalid commit message cleanup mode '%s'"
 msgstr "mode de nettoyage invalide de message de validation '%s'"
 
-#: sequencer.c:267
+#: sequencer.c:275
+#, c-format
+msgid "could not delete '%s'"
+msgstr "Impossible de supprimer '%s'"
+
+#: sequencer.c:301
 msgid "revert"
 msgstr "revert"
 
-#: sequencer.c:269
+#: sequencer.c:303
 msgid "cherry-pick"
 msgstr "cherry-pick"
 
-#: sequencer.c:271
+#: sequencer.c:305
 msgid "rebase -i"
 msgstr "rebase -i"
 
-#: sequencer.c:273
+#: sequencer.c:307
 #, c-format
 msgid "Unknown action: %d"
 msgstr "Action inconnue : %d"
 
-#: sequencer.c:330
+#: sequencer.c:364
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
@@ -3170,7 +3473,7 @@ msgstr ""
 "après résolution des conflits, marquez les chemins corrigés\n"
 "avec 'git add <chemins>' ou 'git rm <chemins>'"
 
-#: sequencer.c:333
+#: sequencer.c:367
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'\n"
@@ -3180,43 +3483,45 @@ msgstr ""
 "avec 'git add <chemins>' ou 'git rm <chemins>'\n"
 "puis validez le résultat avec 'git commit'"
 
-#: sequencer.c:346 sequencer.c:2245
+#: sequencer.c:380 sequencer.c:2468
 #, c-format
 msgid "could not lock '%s'"
 msgstr "impossible de verrouiller '%s'"
 
-#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264
-#: sequencer.c:3246 sequencer.c:3310 wrapper.c:656
+#: sequencer.c:382 sequencer.c:2346 sequencer.c:2472 sequencer.c:2486
+#: sequencer.c:2694 sequencer.c:4336 sequencer.c:4399 wrapper.c:656
 #, c-format
 msgid "could not write to '%s'"
 msgstr "impossible d'écrire dans '%s'"
 
-#: sequencer.c:353
+#: sequencer.c:387
 #, c-format
 msgid "could not write eol to '%s'"
 msgstr "impossible d'écrire la fin de ligne dans '%s'"
 
-#: sequencer.c:356 sequencer.c:2128 sequencer.c:2252
+#: sequencer.c:392 sequencer.c:2351 sequencer.c:2474 sequencer.c:2488
+#: sequencer.c:2702
 #, c-format
 msgid "failed to finalize '%s'"
 msgstr "échec lors de la finalisation de '%s'"
 
-#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259
-#: builtin/commit.c:722 builtin/merge.c:1047
+#: sequencer.c:415 sequencer.c:804 sequencer.c:1493 sequencer.c:2371
+#: sequencer.c:2684 sequencer.c:2788 builtin/am.c:259 builtin/commit.c:727
+#: builtin/merge.c:1046
 #, c-format
 msgid "could not read '%s'"
 msgstr "impossible de lire '%s'"
 
-#: sequencer.c:405
+#: sequencer.c:441
 #, c-format
 msgid "your local changes would be overwritten by %s."
 msgstr "vos modifications locales seraient écrasées par %s."
 
-#: sequencer.c:409
+#: sequencer.c:445
 msgid "commit your changes or stash them to proceed."
 msgstr "validez vos modifications ou les remiser pour continuer."
 
-#: sequencer.c:438
+#: sequencer.c:474
 #, c-format
 msgid "%s: fast-forward"
 msgstr "%s : avance rapide"
@@ -3224,20 +3529,20 @@ msgstr "%s : avance rapide"
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase -i".
 #.
-#: sequencer.c:526
+#: sequencer.c:563
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: Impossible d'écrire le nouveau fichier index"
 
-#: sequencer.c:542
-msgid "could not resolve HEAD commit"
-msgstr "impossible de résoudre le commit HEAD"
-
-#: sequencer.c:562
+#: sequencer.c:579
 msgid "unable to update cache tree"
 msgstr "impossible de mettre à jour l'arbre de cache"
 
-#: sequencer.c:658
+#: sequencer.c:592
+msgid "could not resolve HEAD commit"
+msgstr "impossible de résoudre le commit HEAD"
+
+#: sequencer.c:749
 #, c-format
 msgid ""
 "you have staged changes in your working tree\n"
@@ -3266,11 +3571,15 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: sequencer.c:915
+#: sequencer.c:818
+msgid "writing root commit"
+msgstr "écriture du commit racine"
+
+#: sequencer.c:1043
 msgid "'prepare-commit-msg' hook failed"
 msgstr "échec du crochet 'prepare-commit-msg'"
 
-#: sequencer.c:922
+#: sequencer.c:1050
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3298,7 +3607,7 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:935
+#: sequencer.c:1063
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3324,330 +3633,316 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:975
+#: sequencer.c:1103
 msgid "couldn't look up newly created commit"
 msgstr "impossible de retrouver le commit nouvellement créé"
 
-#: sequencer.c:977
+#: sequencer.c:1105
 msgid "could not parse newly created commit"
 msgstr "impossible d'analyser le commit nouvellement créé"
 
-#: sequencer.c:1023
+#: sequencer.c:1151
 msgid "unable to resolve HEAD after creating commit"
 msgstr "impossible de résoudre HEAD après création du commit"
 
-#: sequencer.c:1025
+#: sequencer.c:1153
 msgid "detached HEAD"
 msgstr "HEAD détachée"
 
-#: sequencer.c:1029
+#: sequencer.c:1157
 msgid " (root-commit)"
 msgstr " (commit racine)"
 
-#: sequencer.c:1050
+#: sequencer.c:1178
 msgid "could not parse HEAD"
 msgstr "impossible de lire HEAD"
 
-#: sequencer.c:1052
+#: sequencer.c:1180
 #, c-format
 msgid "HEAD %s is not a commit!"
 msgstr "HEAD %s n'est pas un commit !"
 
-#: sequencer.c:1056 builtin/commit.c:1491
+#: sequencer.c:1184 builtin/commit.c:1528
 msgid "could not parse HEAD commit"
 msgstr "impossible d'analyser le commit HEAD"
 
-#: sequencer.c:1107 sequencer.c:1673
+#: sequencer.c:1235 sequencer.c:1832
 msgid "unable to parse commit author"
 msgstr "impossible d'analyser l'auteur du commit"
 
-#: sequencer.c:1117 builtin/am.c:1630 builtin/merge.c:643
+#: sequencer.c:1245 builtin/am.c:1630 builtin/merge.c:645
 msgid "git write-tree failed to write a tree"
 msgstr "git write-tree a échoué à écrire un arbre"
 
-#: sequencer.c:1134 sequencer.c:1186
+#: sequencer.c:1262 sequencer.c:1317
 #, c-format
 msgid "unable to read commit message from '%s'"
 msgstr "impossible de lire le message de validation de '%s'"
 
-#: sequencer.c:1154 builtin/am.c:1650 builtin/commit.c:1594 builtin/merge.c:826
-#: builtin/merge.c:851
+#: sequencer.c:1284 builtin/am.c:1650 builtin/commit.c:1631 builtin/merge.c:825
+#: builtin/merge.c:850
 msgid "failed to write commit object"
 msgstr "échec de l'écriture de l'objet commit"
 
-#: sequencer.c:1213
+#: sequencer.c:1344
 #, c-format
 msgid "could not parse commit %s"
 msgstr "impossible d'analyser le commit %s"
 
-#: sequencer.c:1218
+#: sequencer.c:1349
 #, c-format
 msgid "could not parse parent commit %s"
 msgstr "impossible d'analyser le commit parent %s"
 
-#: sequencer.c:1347
-#, c-format
-msgid ""
-"unexpected 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"première ligne de message de compression inattendue :\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1353
-#, c-format
-msgid ""
-"invalid 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"première ligne de message de compression invalide :\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1359 sequencer.c:1384
+#: sequencer.c:1500 sequencer.c:1525
 #, c-format
 msgid "This is a combination of %d commits."
 msgstr "Ceci est la combinaison de %d commits."
 
-#: sequencer.c:1368 sequencer.c:3265
+#: sequencer.c:1510 sequencer.c:4355
 msgid "need a HEAD to fixup"
 msgstr "une HEAD est nécessaire à la correction"
 
-#: sequencer.c:1370
+#: sequencer.c:1512 sequencer.c:2729
 msgid "could not read HEAD"
 msgstr "Impossible de lire HEAD"
 
-#: sequencer.c:1372
+#: sequencer.c:1514
 msgid "could not read HEAD's commit message"
 msgstr "impossible de lire le message de validation de HEAD"
 
-#: sequencer.c:1378
+#: sequencer.c:1520
 #, c-format
 msgid "cannot write '%s'"
 msgstr "impossible d'écrire '%s'"
 
-#: sequencer.c:1387 git-rebase--interactive.sh:452
+#: sequencer.c:1527 git-rebase--interactive.sh:457
 msgid "This is the 1st commit message:"
 msgstr "Ceci est le premier message de validation :"
 
-#: sequencer.c:1395
+#: sequencer.c:1535
 #, c-format
 msgid "could not read commit message of %s"
 msgstr "impossible de lire le message de validation de %s"
 
-#: sequencer.c:1402
+#: sequencer.c:1542
 #, c-format
 msgid "This is the commit message #%d:"
 msgstr "Ceci est le message de validation numéro %d :"
 
-#: sequencer.c:1407
+#: sequencer.c:1548
 #, c-format
 msgid "The commit message #%d will be skipped:"
 msgstr "Le message de validation %d sera ignoré :"
 
-#: sequencer.c:1412
+#: sequencer.c:1553
 #, c-format
 msgid "unknown command: %d"
 msgstr "commande inconnue : %d"
 
-#: sequencer.c:1479
+#: sequencer.c:1631
 msgid "your index file is unmerged."
 msgstr "votre fichier d'index n'est pas fusionné."
 
-#: sequencer.c:1498
+#: sequencer.c:1638
+msgid "cannot fixup root commit"
+msgstr "impossible de réparer le commit racine"
+
+#: sequencer.c:1657
 #, c-format
 msgid "commit %s is a merge but no -m option was given."
 msgstr "le commit %s est une fusion mais l'option -m n'a pas été spécifiée."
 
-#: sequencer.c:1506
+#: sequencer.c:1665
 #, c-format
 msgid "commit %s does not have parent %d"
 msgstr "le commit %s n'a pas de parent %d"
 
-#: sequencer.c:1510
+#: sequencer.c:1669
 #, c-format
 msgid "mainline was specified but commit %s is not a merge."
 msgstr ""
 "une branche principale a été spécifiée mais le commit %s n'est pas une "
 "fusion."
 
-#: sequencer.c:1516
+#: sequencer.c:1675
 #, c-format
 msgid "cannot get commit message for %s"
 msgstr "impossible d'obtenir un message de validation pour %s"
 
 #. TRANSLATORS: The first %s will be a "todo" command like
 #. "revert" or "pick", the second %s a SHA1.
-#: sequencer.c:1535
+#: sequencer.c:1694
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s : impossible d'analyser le commit parent %s"
 
-#: sequencer.c:1600 sequencer.c:2397
+#: sequencer.c:1759
 #, c-format
 msgid "could not rename '%s' to '%s'"
 msgstr "impossible de renommer '%s' en '%s'"
 
-#: sequencer.c:1654
+#: sequencer.c:1813
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "impossible d'annuler %s... %s"
 
-#: sequencer.c:1655
+#: sequencer.c:1814
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "impossible d'appliquer %s... %s"
 
-#: sequencer.c:1702
+#: sequencer.c:1864
 msgid "empty commit set passed"
 msgstr "l'ensemble de commits spécifié est vide"
 
-#: sequencer.c:1712
+#: sequencer.c:1874
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s : échec à la lecture de l'index"
 
-#: sequencer.c:1718
+#: sequencer.c:1881
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr "git %s : échec du rafraîchissement de l'index"
 
-#: sequencer.c:1792
+#: sequencer.c:1961
 #, c-format
 msgid "%s does not accept arguments: '%s'"
 msgstr "%s n'accepte pas d'argument : '%s'"
 
-#: sequencer.c:1801
+#: sequencer.c:1970
 #, c-format
 msgid "missing arguments for %s"
 msgstr "argument manquant pour %s"
 
-#: sequencer.c:1844
+#: sequencer.c:2029
 #, c-format
 msgid "invalid line %d: %.*s"
 msgstr "ligne %d invalide : %.*s"
 
-#: sequencer.c:1852
+#: sequencer.c:2037
 #, c-format
 msgid "cannot '%s' without a previous commit"
 msgstr "'%s' impossible avec le commit précédent"
 
-#: sequencer.c:1883 sequencer.c:3056 sequencer.c:3091
+#: sequencer.c:2085 sequencer.c:4138 sequencer.c:4173
 #, c-format
 msgid "could not read '%s'."
 msgstr "impossible de lire '%s'."
 
-#: sequencer.c:1906
+#: sequencer.c:2108
 msgid "please fix this using 'git rebase --edit-todo'."
 msgstr "veuillez corriger ceci en utilisant 'git rebase --edit-todo'."
 
-#: sequencer.c:1908
+#: sequencer.c:2110
 #, c-format
 msgid "unusable instruction sheet: '%s'"
 msgstr "feuille d'instruction inutilisable : '%s'"
 
-#: sequencer.c:1913
+#: sequencer.c:2115
 msgid "no commits parsed."
 msgstr "aucun commit analysé."
 
-#: sequencer.c:1924
+#: sequencer.c:2126
 msgid "cannot cherry-pick during a revert."
 msgstr "impossible de picorer pendant l'annulation d'un commit."
 
-#: sequencer.c:1926
+#: sequencer.c:2128
 msgid "cannot revert during a cherry-pick."
 msgstr "impossible d'annuler un commit pendant un picorage."
 
-#: sequencer.c:1993
+#: sequencer.c:2195
 #, c-format
 msgid "invalid key: %s"
 msgstr "clé invalide : %s"
 
-#: sequencer.c:1996
+#: sequencer.c:2198
 #, c-format
 msgid "invalid value for %s: %s"
 msgstr "valeur invalide pour %s : %s"
 
-#: sequencer.c:2062
+#: sequencer.c:2269
+msgid "unusable squash-onto"
+msgstr "\"écrase-sur\" inutilisable"
+
+#: sequencer.c:2285
 #, c-format
 msgid "malformed options sheet: '%s'"
 msgstr "feuille d'options malformée : %s"
 
-#: sequencer.c:2100
+#: sequencer.c:2323
 msgid "a cherry-pick or revert is already in progress"
 msgstr "un picorage ou un retour est déjà en cours"
 
-#: sequencer.c:2101
+#: sequencer.c:2324
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "essayez \"git cherry-pick (--continue|--quit|-- abort)\""
 
-#: sequencer.c:2104
+#: sequencer.c:2327
 #, c-format
 msgid "could not create sequencer directory '%s'"
 msgstr "impossible de créer le répertoire de séquenceur '%s'"
 
-#: sequencer.c:2118
+#: sequencer.c:2341
 msgid "could not lock HEAD"
 msgstr "impossible de verrouiller HEAD"
 
-#: sequencer.c:2173 sequencer.c:2761
+#: sequencer.c:2396 sequencer.c:3403
 msgid "no cherry-pick or revert in progress"
 msgstr "aucun picorage ou retour en cours"
 
-#: sequencer.c:2175
+#: sequencer.c:2398
 msgid "cannot resolve HEAD"
 msgstr "impossible de résoudre HEAD"
 
-#: sequencer.c:2177 sequencer.c:2212
+#: sequencer.c:2400 sequencer.c:2435
 msgid "cannot abort from a branch yet to be born"
 msgstr "impossible d'abandonner depuis une branche non encore créée"
 
-#: sequencer.c:2198 builtin/grep.c:720
+#: sequencer.c:2421 builtin/grep.c:720
 #, c-format
 msgid "cannot open '%s'"
 msgstr "impossible d'ouvrir '%s'"
 
-#: sequencer.c:2200
+#: sequencer.c:2423
 #, c-format
 msgid "cannot read '%s': %s"
 msgstr "impossible de lire '%s' : %s"
 
-#: sequencer.c:2201
+#: sequencer.c:2424
 msgid "unexpected end of file"
 msgstr "fin de fichier inattendue"
 
-#: sequencer.c:2207
+#: sequencer.c:2430
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr "le fichier HEAD de préparation de picorage '%s' est corrompu"
 
-#: sequencer.c:2218
+#: sequencer.c:2441
 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
 msgstr ""
 "Vous semblez avoir déplacé la HEAD. Pas de rembobinage, vérifiez votre HEAD !"
 
-#: sequencer.c:2324 sequencer.c:2679
+#: sequencer.c:2545 sequencer.c:3321
 #, c-format
 msgid "could not update %s"
 msgstr "impossible de mettre à jour %s"
 
-#: sequencer.c:2362 sequencer.c:2659
+#: sequencer.c:2583 sequencer.c:3301
 msgid "cannot read HEAD"
 msgstr "impossible de lire HEAD"
 
-#: sequencer.c:2402 builtin/difftool.c:639
+#: sequencer.c:2618 sequencer.c:2622 builtin/difftool.c:639
 #, c-format
 msgid "could not copy '%s' to '%s'"
 msgstr "impossible de copier '%s' vers '%s'"
 
-#: sequencer.c:2421
+#: sequencer.c:2641
 msgid "could not read index"
 msgstr "impossible de lire l'index"
 
-#: sequencer.c:2426
+#: sequencer.c:2646
 #, c-format
 msgid ""
 "execution failed: %s\n"
@@ -3662,11 +3957,11 @@ msgstr ""
 "git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2432
+#: sequencer.c:2652
 msgid "and made changes to the index and/or the working tree\n"
 msgstr "et a mis à jour l'index ou l'arbre de travail\n"
 
-#: sequencer.c:2438
+#: sequencer.c:2658
 #, c-format
 msgid ""
 "execution succeeded: %s\n"
@@ -3683,17 +3978,62 @@ msgstr ""
 "  git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2497
+#: sequencer.c:2771
+msgid "writing fake root commit"
+msgstr "écriture d'un commit racine bidon"
+
+#: sequencer.c:2776
+msgid "writing squash-onto"
+msgstr "écriture de 'écraser-sur'"
+
+#: sequencer.c:2811
+#, c-format
+msgid "failed to find tree of %s"
+msgstr "impossible de trouver l'arbre de %s"
+
+#: sequencer.c:2829
+msgid "could not write index"
+msgstr "impossible d'écrire l'index"
+
+#: sequencer.c:2861
+msgid "cannot merge without a current revision"
+msgstr "impossible de fusionner avec une révision courante"
+
+#: sequencer.c:2884
+#, c-format
+msgid "could not resolve '%s'"
+msgstr "impossible de résoudre '%s'"
+
+#: sequencer.c:2906
+#, c-format
+msgid "could not get commit message of '%s'"
+msgstr "impossible de lire le message de validation de '%s'"
+
+#: sequencer.c:2916 sequencer.c:2941
+#, c-format
+msgid "could not write '%s'"
+msgstr "impossible d'écrire '%s'"
+
+#: sequencer.c:3005
+#, c-format
+msgid "could not even attempt to merge '%.*s'"
+msgstr "impossible de seulement essayer de fusionner '%.*s'"
+
+#: sequencer.c:3021
+msgid "merge: Unable to write new index file"
+msgstr "fusion : Impossible d'écrire le nouveau fichier index"
+
+#: sequencer.c:3088
 #, c-format
 msgid "Applied autostash.\n"
 msgstr "Autoremisage appliqué.\n"
 
-#: sequencer.c:2509
+#: sequencer.c:3100
 #, c-format
 msgid "cannot store %s"
 msgstr "impossible de stocker %s"
 
-#: sequencer.c:2512 git-rebase.sh:178
+#: sequencer.c:3103 git-rebase.sh:188
 #, c-format
 msgid ""
 "Applying autostash resulted in conflicts.\n"
@@ -3704,52 +4044,69 @@ msgstr ""
 "Vos  modifications sont à l'abri dans la remise.\n"
 "Vous pouvez lancer \"git stash pop\" ou \"git stash drop\" à tout moment.\n"
 
-#: sequencer.c:2595
+#: sequencer.c:3134
+#, c-format
+msgid ""
+"Could not execute the todo command\n"
+"\n"
+"    %.*s\n"
+"It has been rescheduled; To edit the command before continuing, please\n"
+"edit the todo list first:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+msgstr ""
+"Impossible d'exécuter la commande\n"
+"\n"
+"    %.*s\n"
+"Elle a été reprogrammée ; pour éditer la commande avant de poursuivre,\n"
+"veuillez éditer la liste de commandes en premier :\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+
+#: sequencer.c:3202
 #, c-format
 msgid "Stopped at %s...  %.*s\n"
 msgstr "arrêt à %s... %.*s\n"
 
-#: sequencer.c:2637
+#: sequencer.c:3264
 #, c-format
 msgid "unknown command %d"
 msgstr "commande inconnue %d"
 
-#: sequencer.c:2667
+#: sequencer.c:3309
 msgid "could not read orig-head"
 msgstr "impossible de lire orig-head"
 
-#: sequencer.c:2672 sequencer.c:3262
+#: sequencer.c:3314 sequencer.c:4352
 msgid "could not read 'onto'"
 msgstr "impossible de lire 'onto'"
 
-#: sequencer.c:2686
+#: sequencer.c:3328
 #, c-format
 msgid "could not update HEAD to %s"
 msgstr "impossible de mettre à jour HEAD sur %s"
 
-#: sequencer.c:2770
+#: sequencer.c:3414
 msgid "cannot rebase: You have unstaged changes."
 msgstr "impossible de rebaser : vous avez des modifications non indexées."
 
-#: sequencer.c:2775
-msgid "could not remove CHERRY_PICK_HEAD"
-msgstr "impossible de supprimer CHERRY_PICK_HEAD"
-
-#: sequencer.c:2784
+#: sequencer.c:3423
 msgid "cannot amend non-existing commit"
 msgstr "impossible de corriger un commit non-existant"
 
-#: sequencer.c:2786
+#: sequencer.c:3425
 #, c-format
 msgid "invalid file: '%s'"
 msgstr "fichier invalide : '%s'"
 
-#: sequencer.c:2788
+#: sequencer.c:3427
 #, c-format
 msgid "invalid contents: '%s'"
 msgstr "contenu invalide : '%s'"
 
-#: sequencer.c:2791
+#: sequencer.c:3430
 msgid ""
 "\n"
 "You have uncommitted changes in your working tree. Please, commit them\n"
@@ -3759,45 +4116,54 @@ msgstr ""
 "Vous avez des modifications non validées dans votre copie de travail.\n"
 "Veuillez les valider d'abord, puis relancer 'git rebase --continue'."
 
-#: sequencer.c:2801
+#: sequencer.c:3455 sequencer.c:3493
+#, c-format
+msgid "could not write file: '%s'"
+msgstr "impossible d'écrire le fichier : '%s'"
+
+#: sequencer.c:3508
+msgid "could not remove CHERRY_PICK_HEAD"
+msgstr "impossible de supprimer CHERRY_PICK_HEAD"
+
+#: sequencer.c:3515
 msgid "could not commit staged changes."
 msgstr "impossible de valider les modifications indexées."
 
-#: sequencer.c:2881
+#: sequencer.c:3612
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s : impossible de picorer un %s"
 
-#: sequencer.c:2885
+#: sequencer.c:3616
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s : mauvaise révision"
 
-#: sequencer.c:2918
+#: sequencer.c:3649
 msgid "can't revert as initial commit"
 msgstr "impossible d'annuler en tant que commit initial"
 
-#: sequencer.c:3023
+#: sequencer.c:4098
 msgid "make_script: unhandled options"
 msgstr "make_script : options non gérées"
 
-#: sequencer.c:3026
+#: sequencer.c:4101
 msgid "make_script: error preparing revisions"
 msgstr "make_script : erreur lors de la préparation des révisions"
 
-#: sequencer.c:3060 sequencer.c:3095
+#: sequencer.c:4142 sequencer.c:4177
 #, c-format
 msgid "unusable todo list: '%s'"
 msgstr "liste à faire inutilisable : '%s'"
 
-#: sequencer.c:3146
+#: sequencer.c:4236
 #, c-format
 msgid ""
 "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
 msgstr ""
 "paramètre non reconnu %s pour l'option rebase.missingCommitsCheck. Ignoré."
 
-#: sequencer.c:3212
+#: sequencer.c:4302
 #, c-format
 msgid ""
 "Warning: some commits may have been dropped accidentally.\n"
@@ -3806,7 +4172,7 @@ msgstr ""
 "Attention : certains commits ont pu être accidentellement supprimés.\n"
 "Commits supprimés (du plus jeune au plus vieux) :\n"
 
-#: sequencer.c:3219
+#: sequencer.c:4309
 #, c-format
 msgid ""
 "To avoid this message, use \"drop\" to explicitly remove a commit.\n"
@@ -3824,7 +4190,7 @@ msgstr ""
 "Les comportements disponibles sont : ignore, warn, error.\n"
 "\n"
 
-#: sequencer.c:3231
+#: sequencer.c:4321
 #, c-format
 msgid ""
 "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
@@ -3835,27 +4201,21 @@ msgstr ""
 "rebase --continue'.\n"
 "Ou vous pouvez abandonner le rebasage avec 'git rebase --abort'.\n"
 
-#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395
-#: builtin/am.c:779
-#, c-format
-msgid "could not open '%s' for writing"
-msgstr "impossible d'ouvrir '%s' en écriture"
-
-#: sequencer.c:3285
+#: sequencer.c:4375
 #, c-format
 msgid "could not parse commit '%s'"
 msgstr "impossible d'analyser le commit '%s'"
 
-#: sequencer.c:3401
+#: sequencer.c:4490
 msgid "the script was already rearranged."
 msgstr "le script a déjà été réarrangé."
 
-#: setup.c:122
+#: setup.c:123
 #, c-format
 msgid "'%s' is outside repository"
 msgstr "'%s' est hors du dépôt"
 
-#: setup.c:171
+#: setup.c:172
 #, c-format
 msgid ""
 "%s: no such path in the working tree.\n"
@@ -3865,7 +4225,7 @@ msgstr ""
 "Utilisez 'git <commande> -- <chemin>...' pour spécifier des chemins qui "
 "n'existent pas localement."
 
-#: setup.c:184
+#: setup.c:185
 #, c-format
 msgid ""
 "ambiguous argument '%s': unknown revision or path not in the working tree.\n"
@@ -3876,12 +4236,14 @@ msgstr ""
 "Utilisez '--' pour séparer les chemins des révisions, comme ceci :\n"
 "'git <commande> [<révision>...] -- [<chemin>...]'"
 
-#: setup.c:233
+#: setup.c:234
 #, c-format
 msgid "option '%s' must come before non-option arguments"
-msgstr "l'option '%s' doit être présente avant les arguments qui ne sont pas des options"
+msgstr ""
+"l'option '%s' doit être présente avant les arguments qui ne sont pas des "
+"options"
 
-#: setup.c:252
+#: setup.c:253
 #, c-format
 msgid ""
 "ambiguous argument '%s': both revision and filename\n"
@@ -3892,158 +4254,163 @@ msgstr ""
 "Utilisez '--' pour séparer les chemins des révisions, comme ceci :\n"
 "'git <commande> [<révision>...] -- [<chemin>...]'"
 
-#: setup.c:388
+#: setup.c:389
 msgid "unable to set up work tree using invalid config"
-msgstr "impossible de mettre en place le répertoire de travail en utilisant une configuration invalide"
+msgstr ""
+"impossible de mettre en place le répertoire de travail en utilisant une "
+"configuration invalide"
 
-#: setup.c:395
+#: setup.c:393
 msgid "this operation must be run in a work tree"
 msgstr "Cette opération doit être effectuée dans un arbre de travail"
 
-#: setup.c:506
+#: setup.c:503
 #, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Version attendue du dépôt git <= %d, %d trouvée"
 
-#: setup.c:514
+#: setup.c:511
 msgid "unknown repository extensions found:"
 msgstr "extensions de dépôt inconnues trouvées :"
 
-#: setup.c:533
+#: setup.c:530
 #, c-format
 msgid "error opening '%s'"
 msgstr "erreur à l'ouverture de '%s'"
 
-#: setup.c:535
+#: setup.c:532
 #, c-format
 msgid "too large to be a .git file: '%s'"
 msgstr "trop gros pour être une fichier .git : '%s'"
 
-#: setup.c:537
+#: setup.c:534
 #, c-format
 msgid "error reading %s"
 msgstr "erreur à la lecture de %s"
 
-#: setup.c:539
+#: setup.c:536
 #, c-format
 msgid "invalid gitfile format: %s"
 msgstr "format de fichier git invalide : %s"
 
-#: setup.c:541
+#: setup.c:538
 #, c-format
 msgid "no path in gitfile: %s"
 msgstr "aucun chemin dans le fichier git : %s"
 
-#: setup.c:543
+#: setup.c:540
 #, c-format
 msgid "not a git repository: %s"
 msgstr "ce n'est pas un dépôt git : %s"
 
-#: setup.c:642
+#: setup.c:639
 #, c-format
 msgid "'$%s' too big"
 msgstr "'$%s' trop gros"
 
-#: setup.c:656
+#: setup.c:653
 #, c-format
 msgid "not a git repository: '%s'"
 msgstr "ce n'est pas un dépôt git : '%s'"
 
-#: setup.c:685 setup.c:687 setup.c:718
+#: setup.c:682 setup.c:684 setup.c:715
 #, c-format
 msgid "cannot chdir to '%s'"
 msgstr "impossible de se déplacer vers le répertoire (chdir) '%s'"
 
-#: setup.c:690 setup.c:746 setup.c:756 setup.c:795 setup.c:803 setup.c:818
+#: setup.c:687 setup.c:743 setup.c:753 setup.c:792 setup.c:800 setup.c:815
 msgid "cannot come back to cwd"
 msgstr "impossible de revenir au répertoire de travail courant"
 
-#: setup.c:816
+#: setup.c:813
 #, c-format
 msgid "not a git repository (or any of the parent directories): %s"
 msgstr "ni ceci ni aucun de ses répertoires parents n'est un dépôt git : %s"
 
-#: setup.c:827
+#: setup.c:824
 #, c-format
 msgid "failed to stat '%*s%s%s'"
 msgstr "échec du stat de '%*s%s%s'"
 
-#: setup.c:1057
+#: setup.c:1054
 msgid "Unable to read current working directory"
 msgstr "Impossible d'accéder au répertoire de travail courant"
 
-#: setup.c:1069 setup.c:1075
+#: setup.c:1066 setup.c:1072
 #, c-format
 msgid "cannot change to '%s'"
 msgstr "impossible de modifier en '%s'"
 
-#: setup.c:1088
+#: setup.c:1085
 #, 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 ""
-"ni ceci ni aucun de ses répertoires parents (jusqu'au point de montage %s) n'est un dépôt git\n"
-"Arrêt à la limite du système de fichiers (GIT_DISCOVERY_ACROSS_FILESYSTEM n'est pas défini)."
+"ni ceci ni aucun de ses répertoires parents (jusqu'au point de montage %s) "
+"n'est un dépôt git\n"
+"Arrêt à la limite du système de fichiers (GIT_DISCOVERY_ACROSS_FILESYSTEM "
+"n'est pas défini)."
 
-#: setup.c:1172
+#: setup.c:1168
 #, c-format
 msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
 "The owner of files must always have read and write permissions."
 msgstr ""
 "problème avec la valeur de core.sharedRepository (0%.3o).\n"
-"Le propriétaire des fichiers doit toujours avoir les droits en lecture et écriture."
+"Le propriétaire des fichiers doit toujours avoir les droits en lecture et "
+"écriture."
 
-#: setup.c:1215
+#: setup.c:1211
 msgid "open /dev/null or dup failed"
 msgstr "échec de l'ouverture ou au dup de /dev/null"
 
-#: setup.c:1230
+#: setup.c:1226
 msgid "fork failed"
 msgstr "échec de la bifurcation"
 
-#: setup.c:1235
+#: setup.c:1231
 msgid "setsid failed"
 msgstr "échec du setsid"
 
-#: sha1_file.c:592
+#: sha1-file.c:625
 #, c-format
 msgid "path '%s' does not exist"
 msgstr "le chemin '%s' n'existe pas"
 
-#: sha1_file.c:618
+#: sha1-file.c:651
 #, c-format
 msgid "reference repository '%s' as a linked checkout is not supported yet."
 msgstr ""
 "extraire le dépôt de référence '%s' comme une extraction liée n'est pas "
 "encore supporté."
 
-#: sha1_file.c:624
+#: sha1-file.c:657
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "le dépôt de référence '%s' n'est pas un dépôt local."
 
-#: sha1_file.c:630
+#: sha1-file.c:663
 #, c-format
 msgid "reference repository '%s' is shallow"
 msgstr "le dépôt de référence '%s' est superficiel"
 
-#: sha1_file.c:638
+#: sha1-file.c:671
 #, c-format
 msgid "reference repository '%s' is grafted"
 msgstr "le dépôt de référence '%s' est greffé"
 
-#: sha1_name.c:422
+#: sha1-name.c:442
 #, c-format
 msgid "short SHA1 %s is ambiguous"
 msgstr "le SHA1 court %s est ambigu"
 
-#: sha1_name.c:433
+#: sha1-name.c:453
 msgid "The candidates are:"
 msgstr "Les candidats sont :"
 
-#: sha1_name.c:693
+#: sha1-name.c:695
 msgid ""
 "Git normally never creates a ref that ends with 40 hex characters\n"
 "because it will be ignored when you just specify 40-hex. These refs\n"
@@ -4068,72 +4435,72 @@ msgstr ""
 "message\n"
 "en lançant \"git config advice.objectNameWarning false\""
 
-#: submodule.c:96 submodule.c:130
+#: submodule.c:97 submodule.c:131
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr ""
 "Modification impossible de .gitmodules non fusionné, résolvez les conflits "
 "d'abord"
 
-#: submodule.c:100 submodule.c:134
+#: submodule.c:101 submodule.c:135
 #, c-format
 msgid "Could not find section in .gitmodules where path=%s"
 msgstr "Impossible de trouver une section où path=%s dans .gitmodules"
 
-#: submodule.c:108
+#: submodule.c:109
 #, c-format
 msgid "Could not update .gitmodules entry %s"
 msgstr "Impossible de mettre à jour l'élément %s de .gitmodules"
 
 # ici %s est un chemin
-#: submodule.c:141
+#: submodule.c:142
 #, c-format
 msgid "Could not remove .gitmodules entry for %s"
 msgstr "Impossible de supprimer l'élément de .gitmodules pour %s"
 
-#: submodule.c:152
+#: submodule.c:153
 msgid "staging updated .gitmodules failed"
 msgstr "échec de la mise en index du .gitmodules mis à jour"
 
-#: submodule.c:312
+#: submodule.c:315
 #, c-format
 msgid "in unpopulated submodule '%s'"
 msgstr "dans le sous-module '%s' non populé"
 
-#: submodule.c:343
+#: submodule.c:346
 #, c-format
 msgid "Pathspec '%s' is in submodule '%.*s'"
 msgstr "Le chemin '%s' est dans le sous-module '%.*s'"
 
-#: submodule.c:833
+#: submodule.c:837
 #, c-format
 msgid "submodule entry '%s' (%s) is a %s, not a commit"
 msgstr "l'entrée de sous-module '%s' (%s) est un %s, pas un commit"
 
-#: submodule.c:1065 builtin/branch.c:648 builtin/submodule--helper.c:1724
+#: submodule.c:1069 builtin/branch.c:651 builtin/submodule--helper.c:1743
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "Échec de résolution de HEAD comme référence valide."
 
-#: submodule.c:1370
+#: submodule.c:1375
 #, c-format
 msgid "'%s' not recognized as a git repository"
 msgstr "'%s' n'est pas reconnu comme dépôt git"
 
-#: submodule.c:1508
+#: submodule.c:1513
 #, c-format
 msgid "could not start 'git status' in submodule '%s'"
 msgstr "impossible de démarrer 'git status' dans le sous-module '%s'"
 
-#: submodule.c:1521
+#: submodule.c:1526
 #, c-format
 msgid "could not run 'git status' in submodule '%s'"
 msgstr "impossible de lancer 'git status' dans le sous-module '%s'"
 
-#: submodule.c:1614
+#: submodule.c:1619
 #, c-format
 msgid "submodule '%s' has dirty index"
 msgstr "le sous-module '%s' a un index sale"
 
-#: submodule.c:1878
+#: submodule.c:1718
 #, c-format
 msgid ""
 "relocate_gitdir for submodule '%s' with more than one worktree not supported"
@@ -4141,18 +4508,18 @@ msgstr ""
 "relocate_gitdir pour le sous-module '%s' avec plus d'un arbre de travail "
 "n'est pas supporté"
 
-#: submodule.c:1890 submodule.c:1946
+#: submodule.c:1730 submodule.c:1786
 #, c-format
 msgid "could not lookup name for submodule '%s'"
 msgstr "impossible de trouve le nom pour le sous-module '%s'"
 
-#: submodule.c:1894 builtin/submodule--helper.c:1246
-#: builtin/submodule--helper.c:1256
+#: submodule.c:1734 builtin/submodule--helper.c:1261
+#: builtin/submodule--helper.c:1271
 #, c-format
 msgid "could not create directory '%s'"
 msgstr "impossible de créer le répertoire '%s'"
 
-#: submodule.c:1897
+#: submodule.c:1737
 #, c-format
 msgid ""
 "Migrating git directory of '%s%s' from\n"
@@ -4163,29 +4530,30 @@ msgstr ""
 "'%s' sur\n"
 "'%s'\n"
 
-#: submodule.c:1981
+#: submodule.c:1821
 #, c-format
 msgid "could not recurse into submodule '%s'"
 msgstr "récursion impossible dans le sous-module '%s'"
 
-#: submodule.c:2025
+#: submodule.c:1865
 msgid "could not start ls-files in .."
 msgstr "impossible de démarrer ls-files dans .."
 
-#: submodule.c:2045
-msgid "BUG: returned path string doesn't match cwd?"
-msgstr "BUG : le chemin renvoyé ne correspond pas à cwd ?"
-
-#: submodule.c:2064
+#: submodule.c:1904
 #, c-format
 msgid "ls-tree returned unexpected return code %d"
 msgstr "ls-tree a renvoyé un code de retour inattendu %d"
 
-#: submodule-config.c:263
+#: submodule-config.c:230
+#, c-format
+msgid "ignoring suspicious submodule name: %s"
+msgstr "nom de sous-module suspicieux %s ignoré"
+
+#: submodule-config.c:294
 msgid "negative values not allowed for submodule.fetchjobs"
 msgstr "les valeurs négatives ne sont pas permises pour submodule.fetchJobs"
 
-#: submodule-config.c:436
+#: submodule-config.c:467
 #, c-format
 msgid "invalid value for %s"
 msgstr "Valeur invalide pour %s"
@@ -4201,7 +4569,7 @@ msgstr "échec de la commande trailer '%s'"
 msgid "unknown value '%s' for key '%s'"
 msgstr "valeur inconnue '%s' pour la clé '%s'"
 
-#: trailer.c:539 trailer.c:544 builtin/remote.c:290
+#: trailer.c:539 trailer.c:544 builtin/remote.c:293
 #, c-format
 msgid "more than one %s"
 msgstr "plus d'un %s"
@@ -4244,17 +4612,21 @@ msgstr "impossible de créer un fichier temporaire"
 msgid "could not rename temporary file to %s"
 msgstr "impossible de renommer un fichier temporaire en %s"
 
-#: transport.c:63
+#: transport.c:116
 #, c-format
 msgid "Would set upstream of '%s' to '%s' of '%s'\n"
 msgstr "Positionnerait la branche amont de '%s' sur '%s' de '%s'\n"
 
-#: transport.c:152
+#: transport.c:208
 #, c-format
 msgid "transport: invalid depth option '%s'"
 msgstr "transport : option de profondeur invalide '%s'"
 
-#: transport.c:916
+#: transport.c:584
+msgid "could not parse transport.color.* config"
+msgstr "impossible d'analyser la configuration transport.color.*"
+
+#: transport.c:996
 #, c-format
 msgid ""
 "The following submodule paths contain changes that can\n"
@@ -4263,7 +4635,7 @@ msgstr ""
 "Les chemins suivant de sous-module contiennent des modifications\n"
 "qui ne peuvent être trouvées sur aucun distant :\n"
 
-#: transport.c:920
+#: transport.c:1000
 #, c-format
 msgid ""
 "\n"
@@ -4290,11 +4662,11 @@ msgstr ""
 "pour les pousser vers un serveur distant.\n"
 "\n"
 
-#: transport.c:928
+#: transport.c:1008
 msgid "Aborting."
 msgstr "Abandon."
 
-#: transport-helper.c:1079
+#: transport-helper.c:1087
 #, c-format
 msgid "Could not read ref %s"
 msgstr "impossible de lire la réf %s"
@@ -4311,11 +4683,11 @@ msgstr "mode invalide dans l'entrée d'arbre"
 msgid "empty filename in tree entry"
 msgstr "nom de fichier vide dans une entrée de l'arbre"
 
-#: tree-walk.c:114
+#: tree-walk.c:113
 msgid "too-short tree file"
 msgstr "fichier arbre trop court"
 
-#: unpack-trees.c:108
+#: unpack-trees.c:111
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4326,7 +4698,7 @@ msgstr ""
 "%%sVeuillez valider ou remiser vos modifications avant de basculer de "
 "branche."
 
-#: unpack-trees.c:110
+#: unpack-trees.c:113
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4336,7 +4708,7 @@ msgstr ""
 "l'extraction :\n"
 "%%s"
 
-#: unpack-trees.c:113
+#: unpack-trees.c:116
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4346,7 +4718,7 @@ msgstr ""
 "fusion :\n"
 "%%sVeuillez valider ou remiser vos modifications avant la fusion."
 
-#: unpack-trees.c:115
+#: unpack-trees.c:118
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4356,7 +4728,7 @@ msgstr ""
 "fusion :\n"
 "%%s"
 
-#: unpack-trees.c:118
+#: unpack-trees.c:121
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4365,7 +4737,7 @@ msgstr ""
 "Vos modifications locales aux fichiers suivants seraient écrasées par %s :\n"
 "%%sVeuillez valider ou remiser vos modifications avant %s."
 
-#: unpack-trees.c:120
+#: unpack-trees.c:123
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4374,7 +4746,7 @@ msgstr ""
 "Vos modifications locales aux fichiers suivants seraient écrasées par %s :\n"
 "%%s"
 
-#: unpack-trees.c:125
+#: unpack-trees.c:128
 #, c-format
 msgid ""
 "Updating the following directories would lose untracked files in them:\n"
@@ -4384,7 +4756,7 @@ msgstr ""
 "contenus :\n"
 "%s"
 
-#: unpack-trees.c:129
+#: unpack-trees.c:132
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4394,7 +4766,7 @@ msgstr ""
 "l'extraction :\n"
 "%%sVeuillez renommer ou effacer ces fichiers avant de basculer de branche."
 
-#: unpack-trees.c:131
+#: unpack-trees.c:134
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4403,7 +4775,7 @@ msgstr ""
 "Les fichiers suivants non suivis seraient effacés par l'extraction :\n"
 "%%s"
 
-#: unpack-trees.c:134
+#: unpack-trees.c:137
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4413,7 +4785,7 @@ msgstr ""
 "la fusion :\n"
 "%%sVeuillez renommer ou effacer ces fichiers avant la fusion."
 
-#: unpack-trees.c:136
+#: unpack-trees.c:139
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4422,7 +4794,7 @@ msgstr ""
 "Les fichiers suivants non suivis seraient effacés par la fusion :\n"
 "%%s"
 
-#: unpack-trees.c:139
+#: unpack-trees.c:142
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4432,7 +4804,7 @@ msgstr ""
 "%s :\n"
 "%%sVeuillez renommer ou effacer ces fichiers avant %s."
 
-#: unpack-trees.c:141
+#: unpack-trees.c:144
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4441,7 +4813,7 @@ msgstr ""
 "Les fichiers suivants non suivis seraient effacés par %s :\n"
 "%%s"
 
-#: unpack-trees.c:146
+#: unpack-trees.c:150
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4452,7 +4824,7 @@ msgstr ""
 "l'extraction :\n"
 "%%sVeuillez renommer ou effacer ces fichiers avant de basculer de branche."
 
-#: unpack-trees.c:148
+#: unpack-trees.c:152
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4462,7 +4834,7 @@ msgstr ""
 "Les fichiers suivants non suivis seraient écrasés par l'extraction :\n"
 "%%s"
 
-#: unpack-trees.c:151
+#: unpack-trees.c:155
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4472,7 +4844,7 @@ msgstr ""
 "la fusion :\n"
 "%%sVeuillez renommer ou effacer ces fichiers avant la fusion."
 
-#: unpack-trees.c:153
+#: unpack-trees.c:157
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4481,7 +4853,7 @@ msgstr ""
 "Les fichiers suivants non suivis seraient écrasés par la fusion :\n"
 "%%s"
 
-#: unpack-trees.c:156
+#: unpack-trees.c:160
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4491,7 +4863,7 @@ msgstr ""
 "%s :\n"
 "%%sVeuillez renommer ou effacer ces fichiers avant %s."
 
-#: unpack-trees.c:158
+#: unpack-trees.c:162
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4500,12 +4872,12 @@ msgstr ""
 "Les fichiers suivants non suivis seraient écrasés par %s :\n"
 "%%s"
 
-#: unpack-trees.c:165
+#: unpack-trees.c:170
 #, c-format
 msgid "Entry '%s' overlaps with '%s'.  Cannot bind."
 msgstr "L'entrée '%s' surcharge avec '%s'. Affectation impossible."
 
-#: unpack-trees.c:168
+#: unpack-trees.c:173
 #, c-format
 msgid ""
 "Cannot update sparse checkout: the following entries are not up to date:\n"
@@ -4515,7 +4887,7 @@ msgstr ""
 "pas à jour :\n"
 "%s"
 
-#: unpack-trees.c:170
+#: unpack-trees.c:175
 #, c-format
 msgid ""
 "The following working tree files would be overwritten by sparse checkout "
@@ -4526,7 +4898,7 @@ msgstr ""
 "jour par l'extraction creuse :\n"
 "%s"
 
-#: unpack-trees.c:172
+#: unpack-trees.c:177
 #, c-format
 msgid ""
 "The following working tree files would be removed by sparse checkout "
@@ -4537,7 +4909,7 @@ msgstr ""
 "à jour par extraction creuse :\n"
 "%s"
 
-#: unpack-trees.c:174
+#: unpack-trees.c:179
 #, c-format
 msgid ""
 "Cannot update submodule:\n"
@@ -4546,12 +4918,12 @@ msgstr ""
 "Mise à jour impossible pour le sous-module :\n"
 "%s"
 
-#: unpack-trees.c:251
+#: unpack-trees.c:262
 #, c-format
 msgid "Aborting\n"
 msgstr "Abandon\n"
 
-#: unpack-trees.c:333
+#: unpack-trees.c:344
 msgid "Checking out files"
 msgstr "Extraction des fichiers"
 
@@ -4592,12 +4964,15 @@ msgstr "échec de la lecture de '%s'"
 #: worktree.c:291
 #, c-format
 msgid "'%s' at main working tree is not the repository directory"
-msgstr "'%s' dans l'arbre de travail principal n'est pas le répertoire de dépôt"
+msgstr ""
+"'%s' dans l'arbre de travail principal n'est pas le répertoire de dépôt"
 
 #: worktree.c:302
 #, c-format
 msgid "'%s' file does not contain absolute path to the working tree location"
-msgstr "le fichier '%s' ne contient pas de chemin absolu à l'emplacement de l'arbre de travail"
+msgstr ""
+"le fichier '%s' ne contient pas de chemin absolu à l'emplacement de l'arbre "
+"de travail"
 
 #: worktree.c:314
 #, c-format
@@ -4620,7 +4995,7 @@ msgid "could not open '%s' for reading and writing"
 msgstr "impossible d'ouvrir '%s' en lecture/écriture"
 
 #: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770
-#: builtin/am.c:862 builtin/merge.c:1044
+#: builtin/am.c:862 builtin/merge.c:1043
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "impossible d'ouvrir '%s' en lecture"
@@ -4634,158 +5009,158 @@ msgstr "impossible d'accéder à '%s'"
 msgid "unable to get current working directory"
 msgstr "impossible d'accéder au répertoire de travail courant"
 
-#: wt-status.c:151
+#: wt-status.c:154
 msgid "Unmerged paths:"
 msgstr "Chemins non fusionnés :"
 
-#: wt-status.c:178 wt-status.c:205
+#: wt-status.c:181 wt-status.c:208
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (utilisez \"git reset %s <fichier>...\" pour désindexer)"
 
-#: wt-status.c:180 wt-status.c:207
+#: wt-status.c:183 wt-status.c:210
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (utilisez \"git rm --cached <fichier>...\" pour désindexer)"
 
-#: wt-status.c:184
+#: wt-status.c:187
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (utilisez \"git add <fichier>...\" pour marquer comme résolu)"
 
-#: wt-status.c:186 wt-status.c:190
+#: wt-status.c:189 wt-status.c:193
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
 "  (utilisez \"git add/rm <fichier>...\" si nécessaire pour marquer comme "
 "résolu)"
 
-#: wt-status.c:188
+#: wt-status.c:191
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (utilisez \"git rm <fichier>...\" pour marquer comme résolu)"
 
-#: wt-status.c:199 wt-status.c:1007
+#: wt-status.c:202 wt-status.c:1015
 msgid "Changes to be committed:"
 msgstr "Modifications qui seront validées :"
 
-#: wt-status.c:217 wt-status.c:1016
+#: wt-status.c:220 wt-status.c:1024
 msgid "Changes not staged for commit:"
 msgstr "Modifications qui ne seront pas validées :"
 
-#: wt-status.c:221
+#: wt-status.c:224
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
 "  (utilisez \"git add <fichier>...\" pour mettre à jour ce qui sera validé)"
 
-#: wt-status.c:223
+#: wt-status.c:226
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
 "  (utilisez \"git add/rm <fichier>...\" pour mettre à jour ce qui sera "
 "validé)"
 
-#: wt-status.c:224
+#: wt-status.c:227
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 "  (utilisez \"git checkout -- <fichier>...\" pour annuler les modifications "
 "dans la copie de travail)"
 
-#: wt-status.c:226
+#: wt-status.c:229
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 "  (valider ou annuler le contenu non suivi ou modifié dans les sous-modules)"
 
-#: wt-status.c:238
+#: wt-status.c:241
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
 "  (utilisez \"git %s <fichier>...\" pour inclure dans ce qui sera validé)"
 
-#: wt-status.c:253
+#: wt-status.c:256
 msgid "both deleted:"
 msgstr "supprimé des deux côtés :"
 
-#: wt-status.c:255
+#: wt-status.c:258
 msgid "added by us:"
 msgstr "ajouté par nous :"
 
-#: wt-status.c:257
+#: wt-status.c:260
 msgid "deleted by them:"
 msgstr "supprimé par eux :"
 
-#: wt-status.c:259
+#: wt-status.c:262
 msgid "added by them:"
 msgstr "ajouté par eux :"
 
-#: wt-status.c:261
+#: wt-status.c:264
 msgid "deleted by us:"
 msgstr "supprimé par nous :"
 
-#: wt-status.c:263
+#: wt-status.c:266
 msgid "both added:"
 msgstr "ajouté de deux côtés :"
 
-#: wt-status.c:265
+#: wt-status.c:268
 msgid "both modified:"
 msgstr "modifié des deux côtés :"
 
-#: wt-status.c:275
+#: wt-status.c:278
 msgid "new file:"
 msgstr "nouveau fichier :"
 
-#: wt-status.c:277
+#: wt-status.c:280
 msgid "copied:"
 msgstr "copié :"
 
-#: wt-status.c:279
+#: wt-status.c:282
 msgid "deleted:"
 msgstr "supprimé :"
 
-#: wt-status.c:281
+#: wt-status.c:284
 msgid "modified:"
 msgstr "modifié :"
 
-#: wt-status.c:283
+#: wt-status.c:286
 msgid "renamed:"
 msgstr "renommé :"
 
-#: wt-status.c:285
+#: wt-status.c:288
 msgid "typechange:"
 msgstr "modif. type :"
 
-#: wt-status.c:287
+#: wt-status.c:290
 msgid "unknown:"
 msgstr "inconnu :"
 
-#: wt-status.c:289
+#: wt-status.c:292
 msgid "unmerged:"
 msgstr "non fusionné :"
 
-#: wt-status.c:369
+#: wt-status.c:372
 msgid "new commits, "
 msgstr "nouveaux commits, "
 
-#: wt-status.c:371
+#: wt-status.c:374
 msgid "modified content, "
 msgstr "contenu modifié, "
 
-#: wt-status.c:373
+#: wt-status.c:376
 msgid "untracked content, "
 msgstr "contenu non suivi, "
 
-#: wt-status.c:847
+#: wt-status.c:853
 #, c-format
 msgid "Your stash currently has %d entry"
 msgid_plural "Your stash currently has %d entries"
 msgstr[0] "Votre remisage contient actuellement %d entrée"
 msgstr[1] "Votre remisage contient actuellement %d entrées"
 
-#: wt-status.c:879
+#: wt-status.c:885
 msgid "Submodules changed but not updated:"
 msgstr "Sous-modules modifiés mais non mis à jour :"
 
-#: wt-status.c:881
+#: wt-status.c:887
 msgid "Submodule changes to be committed:"
 msgstr "Changements du sous-module à valider :"
 
-#: wt-status.c:963
+#: wt-status.c:969
 msgid ""
 "Do not modify or remove the line above.\n"
 "Everything below it will be ignored."
@@ -4793,107 +5168,107 @@ msgstr ""
 "Ne touchez pas à la ligne ci-dessus.\n"
 "Tout ce qui suit sera éliminé."
 
-#: wt-status.c:1076
+#: wt-status.c:1084
 msgid "You have unmerged paths."
 msgstr "Vous avez des chemins non fusionnés."
 
-#: wt-status.c:1079
+#: wt-status.c:1087
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (réglez les conflits puis lancez \"git commit\")"
 
-#: wt-status.c:1081
+#: wt-status.c:1089
 msgid "  (use \"git merge --abort\" to abort the merge)"
 msgstr "  (utilisez \"git merge --abort\" pour annuler la fusion)"
 
-#: wt-status.c:1086
+#: wt-status.c:1094
 msgid "All conflicts fixed but you are still merging."
 msgstr "Tous les conflits sont réglés mais la fusion n'est pas terminée."
 
-#: wt-status.c:1089
+#: wt-status.c:1097
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (utilisez \"git commit\" pour terminer la fusion)"
 
-#: wt-status.c:1099
+#: wt-status.c:1107
 msgid "You are in the middle of an am session."
 msgstr "Vous êtes au milieu d'une session am."
 
-#: wt-status.c:1102
+#: wt-status.c:1110
 msgid "The current patch is empty."
 msgstr "Le patch actuel est vide."
 
-#: wt-status.c:1106
+#: wt-status.c:1114
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr "  (réglez les conflits puis lancez \"git am --continue\")"
 
-#: wt-status.c:1108
+#: wt-status.c:1116
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (utilisez \"git am --skip\" pour sauter ce patch)"
 
-#: wt-status.c:1110
+#: wt-status.c:1118
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (utilisez \"git am --abort\" pour restaurer la branche d'origine)"
 
-#: wt-status.c:1242
+#: wt-status.c:1250
 msgid "git-rebase-todo is missing."
 msgstr "git-rebase-todo est manquant."
 
-#: wt-status.c:1244
+#: wt-status.c:1252
 msgid "No commands done."
 msgstr "Aucune commande réalisée."
 
-#: wt-status.c:1247
+#: wt-status.c:1255
 #, c-format
 msgid "Last command done (%d command done):"
 msgid_plural "Last commands done (%d commands done):"
 msgstr[0] "Dernière commande effectuée (%d commande effectuée) :"
 msgstr[1] "Dernières commandes effectuées (%d commandes effectuées) :"
 
-#: wt-status.c:1258
+#: wt-status.c:1266
 #, c-format
 msgid "  (see more in file %s)"
 msgstr "  (voir plus dans le fichier %s)"
 
-#: wt-status.c:1263
+#: wt-status.c:1271
 msgid "No commands remaining."
 msgstr "Aucune commande restante."
 
-#: wt-status.c:1266
+#: wt-status.c:1274
 #, c-format
 msgid "Next command to do (%d remaining command):"
 msgid_plural "Next commands to do (%d remaining commands):"
 msgstr[0] "Prochaine commande à effectuer (%d commande restante) :"
 msgstr[1] "Prochaines commandes à effectuer (%d commandes restantes) :"
 
-#: wt-status.c:1274
+#: wt-status.c:1282
 msgid "  (use \"git rebase --edit-todo\" to view and edit)"
 msgstr "  (utilisez \"git rebase --edit-todo\" pour voir et éditer)"
 
-#: wt-status.c:1287
+#: wt-status.c:1295
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "Vous êtes en train de rebaser la branche '%s' sur '%s'."
 
-#: wt-status.c:1292
+#: wt-status.c:1300
 msgid "You are currently rebasing."
 msgstr "Vous êtes en train de rebaser."
 
-#: wt-status.c:1306
+#: wt-status.c:1314
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (réglez les conflits puis lancez \"git rebase --continue\")"
 
-#: wt-status.c:1308
+#: wt-status.c:1316
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (utilisez \"git rebase --skip\" pour sauter ce patch)"
 
-#: wt-status.c:1310
+#: wt-status.c:1318
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (utilisez \"git rebase --abort\" pour extraire la branche d'origine)"
 
-#: wt-status.c:1316
+#: wt-status.c:1324
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (tous les conflits sont réglés : lancez \"git rebase --continue\")"
 
-#: wt-status.c:1320
+#: wt-status.c:1328
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
@@ -4901,128 +5276,128 @@ msgstr ""
 "Vous êtes actuellement en train de fractionner un commit pendant un rebasage "
 "de la branche '%s' sur '%s'."
 
-#: wt-status.c:1325
+#: wt-status.c:1333
 msgid "You are currently splitting a commit during a rebase."
 msgstr ""
 "Vous êtes actuellement en train de fractionner un commit pendant un rebasage."
 
-#: wt-status.c:1328
+#: wt-status.c:1336
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr ""
 "  (Une fois la copie de travail nettoyée, lancez \"git rebase --continue\")"
 
-#: wt-status.c:1332
+#: wt-status.c:1340
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 "Vous êtes actuellement en train d'éditer un commit pendant un rebasage de la "
 "branche '%s' sur '%s'."
 
-#: wt-status.c:1337
+#: wt-status.c:1345
 msgid "You are currently editing a commit during a rebase."
 msgstr ""
 "Vous êtes actuellement en train d'éditer un commit pendant un rebasage."
 
-#: wt-status.c:1340
+#: wt-status.c:1348
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr "  (utilisez \"git commit --amend\" pour corriger le commit actuel)"
 
-#: wt-status.c:1342
+#: wt-status.c:1350
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
 "  (utilisez \"git rebase --continue\" quand vous avez effectué toutes vos "
 "modifications)"
 
-#: wt-status.c:1352
+#: wt-status.c:1360
 #, c-format
 msgid "You are currently cherry-picking commit %s."
 msgstr "Vous êtes actuellement en train de picorer le commit %s."
 
-#: wt-status.c:1357
+#: wt-status.c:1365
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr "  (réglez les conflits puis lancez \"git cherry-pick --continue\")"
 
-#: wt-status.c:1360
+#: wt-status.c:1368
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr ""
 "  (tous les conflits sont réglés : lancez \"git cherry-pick --continue\")"
 
-#: wt-status.c:1362
+#: wt-status.c:1370
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr "  (utilisez \"git cherry-pick --abort\" pour annuler le picorage)"
 
-#: wt-status.c:1371
+#: wt-status.c:1379
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "Vous êtes actuellement en train de rétablir le commit %s."
 
-#: wt-status.c:1376
+#: wt-status.c:1384
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (réglez les conflits puis lancez \"git revert --continue\")"
 
-#: wt-status.c:1379
+#: wt-status.c:1387
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr "  (tous les conflits sont réglés : lancez \"git revert --continue\")"
 
-#: wt-status.c:1381
+#: wt-status.c:1389
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr "  (utilisez \"git revert --abort\" pour annuler le rétablissement)"
 
-#: wt-status.c:1392
+#: wt-status.c:1400
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr "Vous êtes en cours de bissection, depuis la branche '%s'."
 
-#: wt-status.c:1396
+#: wt-status.c:1404
 msgid "You are currently bisecting."
 msgstr "Vous êtes en cours de bissection."
 
-#: wt-status.c:1399
+#: wt-status.c:1407
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr "  (utilisez \"git bisect reset\" pour revenir à la branche d'origine)"
 
-#: wt-status.c:1596
+#: wt-status.c:1604
 msgid "On branch "
 msgstr "Sur la branche "
 
-#: wt-status.c:1602
+#: wt-status.c:1610
 msgid "interactive rebase in progress; onto "
 msgstr "rebasage interactif en cours ; sur "
 
-#: wt-status.c:1604
+#: wt-status.c:1612
 msgid "rebase in progress; onto "
 msgstr "rebasage en cours ; sur "
 
-#: wt-status.c:1609
+#: wt-status.c:1617
 msgid "HEAD detached at "
 msgstr "HEAD détachée sur "
 
-#: wt-status.c:1611
+#: wt-status.c:1619
 msgid "HEAD detached from "
 msgstr "HEAD détachée depuis "
 
-#: wt-status.c:1614
+#: wt-status.c:1622
 msgid "Not currently on any branch."
 msgstr "Actuellement sur aucun branche."
 
-#: wt-status.c:1634
+#: wt-status.c:1642
 msgid "Initial commit"
 msgstr "Validation initiale"
 
-#: wt-status.c:1635
+#: wt-status.c:1643
 msgid "No commits yet"
 msgstr "Aucun commit"
 
-#: wt-status.c:1649
+#: wt-status.c:1657
 msgid "Untracked files"
 msgstr "Fichiers non suivis"
 
-#: wt-status.c:1651
+#: wt-status.c:1659
 msgid "Ignored files"
 msgstr "Fichiers ignorés"
 
-#: wt-status.c:1655
+#: wt-status.c:1663
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -5034,32 +5409,32 @@ msgstr ""
 "oublier d'ajouter les nouveaux fichiers par vous-même (voir 'git help "
 "status')."
 
-#: wt-status.c:1661
+#: wt-status.c:1669
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "Fichiers non suivis non affichés%s"
 
-#: wt-status.c:1663
+#: wt-status.c:1671
 msgid " (use -u option to show untracked files)"
 msgstr " (utilisez -u pour afficher les fichiers non suivis)"
 
-#: wt-status.c:1669
+#: wt-status.c:1677
 msgid "No changes"
 msgstr "Aucune modification"
 
-#: wt-status.c:1674
+#: wt-status.c:1682
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
 "aucune modification n'a été ajoutée à la validation (utilisez \"git add\" ou "
 "\"git commit -a\")\n"
 
-#: wt-status.c:1677
+#: wt-status.c:1685
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "aucune modification ajoutée à la validation\n"
 
-#: wt-status.c:1680
+#: wt-status.c:1688
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
@@ -5068,71 +5443,71 @@ msgstr ""
 "aucune modification ajoutée à la validation mais des fichiers non suivis "
 "sont présents (utilisez \"git add\" pour les suivre)\n"
 
-#: wt-status.c:1683
+#: wt-status.c:1691
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr ""
 "aucune modification ajoutée à la validation mais des fichiers non suivis "
 "sont présents\n"
 
-#: wt-status.c:1686
+#: wt-status.c:1694
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
 "rien à valider (créez/copiez des fichiers et utilisez \"git add\" pour les "
 "suivre)\n"
 
-#: wt-status.c:1689 wt-status.c:1694
+#: wt-status.c:1697 wt-status.c:1702
 #, c-format
 msgid "nothing to commit\n"
 msgstr "rien à valider\n"
 
-#: wt-status.c:1692
+#: wt-status.c:1700
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr "rien à valider (utilisez -u pour afficher les fichiers non suivis)\n"
 
-#: wt-status.c:1696
+#: wt-status.c:1704
 #, c-format
 msgid "nothing to commit, working tree clean\n"
 msgstr "rien à valider, la copie de travail est propre\n"
 
-#: wt-status.c:1809
+#: wt-status.c:1817
 msgid "No commits yet on "
 msgstr "Encore aucun commit sur "
 
-#: wt-status.c:1813
+#: wt-status.c:1821
 msgid "HEAD (no branch)"
 msgstr "HEAD (aucune branche)"
 
-#: wt-status.c:1844
+#: wt-status.c:1852
 msgid "different"
 msgstr "différent"
 
-#: wt-status.c:1846 wt-status.c:1854
+#: wt-status.c:1854 wt-status.c:1862
 msgid "behind "
 msgstr "derrière "
 
-#: wt-status.c:1849 wt-status.c:1852
+#: wt-status.c:1857 wt-status.c:1860
 msgid "ahead "
 msgstr "devant "
 
 #. TRANSLATORS: the action is e.g. "pull with rebase"
-#: wt-status.c:2358
+#: wt-status.c:2366
 #, c-format
 msgid "cannot %s: You have unstaged changes."
 msgstr "Impossible de %s : vous avez des modifications non indexées."
 
-#: wt-status.c:2364
+#: wt-status.c:2372
 msgid "additionally, your index contains uncommitted changes."
 msgstr "de plus, votre index contient des modifications non validées."
 
-#: wt-status.c:2366
+#: wt-status.c:2374
 #, c-format
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "%s impossible : votre index contient des modifications non validées."
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:440
+#: compat/precompose_utf8.c:58 builtin/clone.c:442
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr "échec lors de l'unlink de '%s'"
@@ -5146,7 +5521,7 @@ msgstr "git add [<options>] [--] <chemin>..."
 msgid "unexpected diff status %c"
 msgstr "état de diff inattendu %c"
 
-#: builtin/add.c:88 builtin/commit.c:257
+#: builtin/add.c:88 builtin/commit.c:266
 msgid "updating files failed"
 msgstr "échec de la mise à jour des fichiers"
 
@@ -5159,7 +5534,7 @@ msgstr "suppression de '%s'\n"
 msgid "Unstaged changes after refreshing the index:"
 msgstr "Modifications non indexées après rafraîchissement de l'index :"
 
-#: builtin/add.c:233 builtin/rev-parse.c:888
+#: builtin/add.c:233 builtin/rev-parse.c:892
 msgid "Could not read the index"
 msgstr "Impossible de lire l'index"
 
@@ -5190,82 +5565,82 @@ msgstr "Patch vide. Abandon."
 msgid "Could not apply '%s'"
 msgstr "Impossible d'appliquer '%s'"
 
-#: builtin/add.c:271
+#: builtin/add.c:269
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr ""
 "Les chemins suivants sont ignorés par un de vos fichiers .gitignore :\n"
 
-#: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:146 builtin/mv.c:124
-#: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541
-#: builtin/remote.c:1333 builtin/rm.c:242 builtin/send-pack.c:164
+#: builtin/add.c:289 builtin/clean.c:911 builtin/fetch.c:145 builtin/mv.c:123
+#: builtin/prune-packed.c:55 builtin/pull.c:212 builtin/push.c:557
+#: builtin/remote.c:1342 builtin/rm.c:240 builtin/send-pack.c:165
 msgid "dry run"
 msgstr "simuler l'action"
 
-#: builtin/add.c:294
+#: builtin/add.c:292
 msgid "interactive picking"
 msgstr "sélection interactive"
 
-#: builtin/add.c:295 builtin/checkout.c:1128 builtin/reset.c:302
+#: builtin/add.c:293 builtin/checkout.c:1135 builtin/reset.c:302
 msgid "select hunks interactively"
 msgstr "sélection interactive des sections"
 
-#: builtin/add.c:296
+#: builtin/add.c:294
 msgid "edit current diff and apply"
 msgstr "édition du diff actuel et application"
 
-#: builtin/add.c:297
+#: builtin/add.c:295
 msgid "allow adding otherwise ignored files"
 msgstr "permettre l'ajout de fichiers ignorés"
 
-#: builtin/add.c:298
+#: builtin/add.c:296
 msgid "update tracked files"
 msgstr "mettre à jour les fichiers suivis"
 
-#: builtin/add.c:299
+#: builtin/add.c:297
 msgid "renormalize EOL of tracked files (implies -u)"
 msgstr ""
 "renormaliser les fins de lignes (EOL) des fichiers suivis (implique -u)"
 
-#: builtin/add.c:300
+#: builtin/add.c:298
 msgid "record only the fact that the path will be added later"
 msgstr "enregistrer seulement le fait que le chemin sera ajouté plus tard"
 
-#: builtin/add.c:301
+#: builtin/add.c:299
 msgid "add changes from all tracked and untracked files"
 msgstr "ajouter les modifications de tous les fichiers suivis et non suivis"
 
-#: builtin/add.c:304
+#: builtin/add.c:302
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr ""
 "ignorer les chemins effacés dans la copie de travail (identique à --no-all)"
 
-#: builtin/add.c:306
+#: builtin/add.c:304
 msgid "don't add, only refresh the index"
 msgstr "ne pas ajouter, juste rafraîchir l'index"
 
-#: builtin/add.c:307
+#: builtin/add.c:305
 msgid "just skip files which cannot be added because of errors"
 msgstr ""
 "sauter seulement les fichiers qui ne peuvent pas être ajoutés du fait "
 "d'erreurs"
 
-#: builtin/add.c:308
+#: builtin/add.c:306
 msgid "check if - even missing - files are ignored in dry run"
 msgstr "vérifier si des fichiers - même manquants - sont ignorés, à vide"
 
-#: builtin/add.c:309 builtin/update-index.c:964
+#: builtin/add.c:307 builtin/update-index.c:974
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/add.c:309 builtin/update-index.c:965
+#: builtin/add.c:307 builtin/update-index.c:975
 msgid "override the executable bit of the listed files"
 msgstr "outrepasser le bit exécutable pour les fichiers listés"
 
-#: builtin/add.c:311
+#: builtin/add.c:309
 msgid "warn when adding an embedded repository"
 msgstr "avertir lors de l'ajout d'un dépôt embarqué"
 
-#: builtin/add.c:326
+#: builtin/add.c:324
 #, c-format
 msgid ""
 "You've added another git repository inside your current repository.\n"
@@ -5296,48 +5671,48 @@ msgstr ""
 "\n"
 "Référez-vous à \"git help submodule\" pour plus d'information."
 
-#: builtin/add.c:354
+#: builtin/add.c:352
 #, c-format
 msgid "adding embedded git repository: %s"
 msgstr "dépôt git embarqué ajouté : %s"
 
-#: builtin/add.c:372
+#: builtin/add.c:370
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "Utilisez -f si vous voulez réellement les ajouter.\n"
 
-#: builtin/add.c:380
+#: builtin/add.c:378
 msgid "adding files failed"
 msgstr "échec de l'ajout de fichiers"
 
-#: builtin/add.c:417
+#: builtin/add.c:416
 msgid "-A and -u are mutually incompatible"
 msgstr "-A et -u sont mutuellement incompatibles"
 
-#: builtin/add.c:424
+#: builtin/add.c:423
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr ""
 "L'option --ignore-missing ne peut être utilisée qu'en complément de --dry-run"
 
-#: builtin/add.c:428
+#: builtin/add.c:427
 #, c-format
 msgid "--chmod param '%s' must be either -x or +x"
 msgstr "Le paramètre '%s' de --chmod doit être soit -x soit +x"
 
-#: builtin/add.c:443
+#: builtin/add.c:442
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "Rien de spécifié, rien n'a été ajouté.\n"
 
-#: builtin/add.c:444
+#: builtin/add.c:443
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Vous vouliez sûrement dire 'git add .' ?\n"
 
-#: builtin/add.c:449 builtin/check-ignore.c:177 builtin/checkout.c:280
-#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316
+#: builtin/add.c:448 builtin/check-ignore.c:177 builtin/checkout.c:280
+#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:325
 #: builtin/diff-tree.c:114 builtin/mv.c:144 builtin/reset.c:241
-#: builtin/rm.c:271 builtin/submodule--helper.c:326
+#: builtin/rm.c:270 builtin/submodule--helper.c:328
 msgid "index file corrupt"
 msgstr "fichier d'index corrompu"
 
@@ -5389,7 +5764,7 @@ msgstr "décalage horaire invalide"
 msgid "Patch format detection failed."
 msgstr "Échec de détection du format du patch."
 
-#: builtin/am.c:1013 builtin/clone.c:405
+#: builtin/am.c:1013 builtin/clone.c:407
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "échec de la création du répertoire '%s'"
@@ -5398,7 +5773,7 @@ msgstr "échec de la création du répertoire '%s'"
 msgid "Failed to split patches."
 msgstr "Échec de découpage des patchs."
 
-#: builtin/am.c:1148 builtin/commit.c:342
+#: builtin/am.c:1148 builtin/commit.c:351
 msgid "unable to write index file"
 msgstr "impossible d'écrire le fichier d'index"
 
@@ -5507,7 +5882,8 @@ msgstr "le patch a échoué à %s %.*s"
 
 #: builtin/am.c:1838
 msgid "Use 'git am --show-current-patch' to see the failed patch"
-msgstr "Utilisez 'git am --show-current-patch' pour visualiser le patch en échec"
+msgstr ""
+"Utilisez 'git am --show-current-patch' pour visualiser le patch en échec"
 
 #: builtin/am.c:1882
 msgid ""
@@ -5577,7 +5953,7 @@ msgid "allow fall back on 3way merging if needed"
 msgstr "permettre de revenir à une fusion à 3 points si nécessaire"
 
 #: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57
-#: builtin/repack.c:182
+#: builtin/repack.c:192
 msgid "be quiet"
 msgstr "être silencieux"
 
@@ -5620,16 +5996,17 @@ msgstr "retirer tout le contenu avant la ligne des ciseaux"
 msgid "pass it through git-apply"
 msgstr "le passer jusqu'à git-apply"
 
-#: builtin/am.c:2260 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668
-#: builtin/grep.c:853 builtin/merge.c:206 builtin/pull.c:145 builtin/pull.c:203
-#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197
-#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:382
-#: parse-options.h:144 parse-options.h:146 parse-options.h:257
+#: builtin/am.c:2260 builtin/commit.c:1332 builtin/fmt-merge-msg.c:665
+#: builtin/fmt-merge-msg.c:668 builtin/grep.c:853 builtin/merge.c:208
+#: builtin/pull.c:150 builtin/pull.c:208 builtin/repack.c:201
+#: builtin/repack.c:205 builtin/repack.c:207 builtin/show-branch.c:631
+#: builtin/show-ref.c:169 builtin/tag.c:383 parse-options.h:144
+#: parse-options.h:146 parse-options.h:258
 msgid "n"
 msgstr "n"
 
-#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38
-#: builtin/replace.c:445 builtin/tag.c:418 builtin/verify-tag.c:39
+#: builtin/am.c:2266 builtin/branch.c:632 builtin/for-each-ref.c:38
+#: builtin/replace.c:543 builtin/tag.c:419 builtin/verify-tag.c:39
 msgid "format"
 msgstr "format"
 
@@ -5674,8 +6051,8 @@ msgstr "mentir sur la date de validation"
 msgid "use current timestamp for author date"
 msgstr "utiliser l'horodatage actuel pour la date d'auteur"
 
-#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237
-#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:398
+#: builtin/am.c:2298 builtin/commit.c:1468 builtin/merge.c:239
+#: builtin/pull.c:183 builtin/revert.c:112 builtin/tag.c:399
 msgid "key-id"
 msgstr "id-clé"
 
@@ -5817,121 +6194,148 @@ msgstr "--write-terms exige deux arguments"
 msgid "--bisect-clean-state requires no arguments"
 msgstr "--bisect-clean-state ne supporte aucun argument"
 
-#: builtin/blame.c:27
+#: builtin/blame.c:29
 msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
 msgstr "git blame [<options>] [<rev-opts>] [<rev>] [--] <fichier>"
 
-#: builtin/blame.c:32
+#: builtin/blame.c:34
 msgid "<rev-opts> are documented in git-rev-list(1)"
 msgstr "<options-de-révision> sont documentés dans git-rev-list(1)"
 
-#: builtin/blame.c:677
+#: builtin/blame.c:404
+#, c-format
+msgid "expecting a color: %s"
+msgstr "couleur attendue : %s"
+
+#: builtin/blame.c:411
+msgid "must end with a color"
+msgstr "doit finir avec une couleur"
+
+#: builtin/blame.c:697
+#, c-format
+msgid "invalid color '%s' in color.blame.repeatedLines"
+msgstr "couleur invalide '%s' dans color.blame.repeatedlines"
+
+#: builtin/blame.c:715
+msgid "invalid value for blame.coloring"
+msgstr "valeur invalide pour blame.coloring"
+
+#: builtin/blame.c:786
 msgid "Show blame entries as we find them, incrementally"
 msgstr ""
 "Montrer les éléments de blâme au fur et à mesure de leur découverte, de "
 "manière incrémentale"
 
-#: builtin/blame.c:678
+#: builtin/blame.c:787
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr "Montrer un SHA-1 blanc pour les commits de limite (Défaut : désactivé)"
 
-#: builtin/blame.c:679
+#: builtin/blame.c:788
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr ""
 "Ne pas traiter les commits racine comme des limites (Défaut : désactivé)"
 
-#: builtin/blame.c:680
+#: builtin/blame.c:789
 msgid "Show work cost statistics"
 msgstr "Montrer les statistiques de coût d'activité"
 
-#: builtin/blame.c:681
+#: builtin/blame.c:790
 msgid "Force progress reporting"
 msgstr "Forcer l'affichage de l'état d'avancement"
 
-#: builtin/blame.c:682
+#: builtin/blame.c:791
 msgid "Show output score for blame entries"
 msgstr "Montrer le score de sortie pour les éléments de blâme"
 
-#: builtin/blame.c:683
+#: builtin/blame.c:792
 msgid "Show original filename (Default: auto)"
 msgstr "Montrer les noms de fichier originaux (Défaut : auto)"
 
-#: builtin/blame.c:684
+#: builtin/blame.c:793
 msgid "Show original linenumber (Default: off)"
 msgstr "Montrer les numéros de lignes originaux (Défaut : désactivé)"
 
-#: builtin/blame.c:685
+#: builtin/blame.c:794
 msgid "Show in a format designed for machine consumption"
 msgstr "Afficher dans un format propice à la consommation par machine"
 
-#: builtin/blame.c:686
+#: builtin/blame.c:795
 msgid "Show porcelain format with per-line commit information"
 msgstr "Afficher en format porcelaine avec l'information de commit par ligne"
 
-#: builtin/blame.c:687
+#: builtin/blame.c:796
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr "Utiliser le même mode de sortie que git-annotate (Défaut : désactivé)"
 
-#: builtin/blame.c:688
+#: builtin/blame.c:797
 msgid "Show raw timestamp (Default: off)"
 msgstr "Afficher les horodatages bruts (Défaut : désactivé)"
 
-#: builtin/blame.c:689
+#: builtin/blame.c:798
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "Afficher les longs SHA1 de commits (Défaut : désactivé)"
 
-#: builtin/blame.c:690
+#: builtin/blame.c:799
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "Supprimer le nom de l'auteur et l'horodatage (Défaut : désactivé)"
 
-#: builtin/blame.c:691
+#: builtin/blame.c:800
 msgid "Show author email instead of name (Default: off)"
 msgstr "Afficher le courriel de l'auteur au lieu du nom (Défaut : désactivé)"
 
-#: builtin/blame.c:692
+#: builtin/blame.c:801
 msgid "Ignore whitespace differences"
 msgstr "Ignorer les différences d'espace"
 
-#: builtin/blame.c:699
+#: builtin/blame.c:802
+msgid "color redundant metadata from previous line differently"
+msgstr ""
+"colorer différemment les métadonnées redondantes avec la ligne précédente"
+
+#: builtin/blame.c:803
+msgid "color lines by age"
+msgstr "colorier les lignes par âge"
+
+#: builtin/blame.c:810
 msgid "Use an experimental heuristic to improve diffs"
 msgstr "Utiliser une heuristique expérimentale pour améliorer les diffs"
 
-#: builtin/blame.c:701
+#: builtin/blame.c:812
 msgid "Spend extra cycles to find better match"
 msgstr ""
 "Dépenser des cycles supplémentaires pour trouver une meilleure correspondance"
 
-#: builtin/blame.c:702
+#: builtin/blame.c:813
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr ""
 "Utiliser les révisions du fichier <fichier> au lieu d'appeler git-rev-list"
 
-#: builtin/blame.c:703
+#: builtin/blame.c:814
 msgid "Use <file>'s contents as the final image"
 msgstr "Utiliser le contenu de <fichier> comme image finale"
 
-#: builtin/blame.c:704 builtin/blame.c:705
+#: builtin/blame.c:815 builtin/blame.c:816
 msgid "score"
 msgstr "score"
 
-#: builtin/blame.c:704
+#: builtin/blame.c:815
 msgid "Find line copies within and across files"
 msgstr "Trouver les copies de ligne dans et entre les fichiers"
 
-#: builtin/blame.c:705
+#: builtin/blame.c:816
 msgid "Find line movements within and across files"
 msgstr "Trouver les mouvements de ligne dans et entre les fichiers"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "Process only line range n,m, counting from 1"
 msgstr ""
 "Traiter seulement l'intervalle de ligne n,m en commençant le compte à 1"
 
-#: builtin/blame.c:753
+#: builtin/blame.c:866
 msgid "--progress can't be used with --incremental or porcelain formats"
 msgstr ""
 "--progress ne peut pas être utilisé avec --incremental ou les formats "
@@ -5945,18 +6349,18 @@ msgstr ""
 #. your language may need more or fewer display
 #. columns.
 #.
-#: builtin/blame.c:804
+#: builtin/blame.c:917
 msgid "4 years, 11 months ago"
 msgstr "il y a 10 ans et 11 mois"
 
-#: builtin/blame.c:890
+#: builtin/blame.c:1003
 #, c-format
 msgid "file %s has only %lu line"
 msgid_plural "file %s has only %lu lines"
 msgstr[0] "le fichier %s n'a qu'%lu ligne"
 msgstr[1] "le fichier %s n'a que %lu lignes"
 
-#: builtin/blame.c:936
+#: builtin/blame.c:1049
 msgid "Blaming lines"
 msgstr "Assignation de blâme aux lignes"
 
@@ -6069,69 +6473,69 @@ msgstr "Branche de suivi %s supprimée (précédemment %s).\n"
 msgid "Deleted branch %s (was %s).\n"
 msgstr "Branche %s supprimée (précédemment %s).\n"
 
-#: builtin/branch.c:417 builtin/tag.c:58
+#: builtin/branch.c:416 builtin/tag.c:58
 msgid "unable to parse format string"
 msgstr "impossible d'analyser la chaîne de format"
 
-#: builtin/branch.c:450
+#: builtin/branch.c:453
 #, c-format
 msgid "Branch %s is being rebased at %s"
 msgstr "La branche %s est en cours de rebasage sur %s"
 
-#: builtin/branch.c:454
+#: builtin/branch.c:457
 #, c-format
 msgid "Branch %s is being bisected at %s"
 msgstr "La branche %s est en cours de bissection sur %s"
 
-#: builtin/branch.c:471
+#: builtin/branch.c:474
 msgid "cannot copy the current branch while not on any."
 msgstr "impossible de copier la branche actuelle, il n'y en a pas."
 
-#: builtin/branch.c:473
+#: builtin/branch.c:476
 msgid "cannot rename the current branch while not on any."
 msgstr "impossible de renommer la branche actuelle, il n'y en a pas."
 
-#: builtin/branch.c:484
+#: builtin/branch.c:487
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "Nom de branche invalide : '%s'"
 
-#: builtin/branch.c:511
+#: builtin/branch.c:514
 msgid "Branch rename failed"
 msgstr "Échec de renommage de la branche"
 
-#: builtin/branch.c:513
+#: builtin/branch.c:516
 msgid "Branch copy failed"
 msgstr "Échec de copie de la branche"
 
-#: builtin/branch.c:517
+#: builtin/branch.c:520
 #, c-format
 msgid "Created a copy of a misnamed branch '%s'"
 msgstr "Création d'une copie d'une branche mal nommée '%s'"
 
-#: builtin/branch.c:520
+#: builtin/branch.c:523
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "Renommage d'une branche mal nommée '%s'"
 
-#: builtin/branch.c:526
+#: builtin/branch.c:529
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "La branche a été renommée en %s, mais HEAD n'est pas mise à jour !"
 
-#: builtin/branch.c:535
+#: builtin/branch.c:538
 msgid "Branch is renamed, but update of config-file failed"
 msgstr ""
 "La branche est renommée, mais la mise à jour du fichier de configuration a "
 "échoué"
 
-#: builtin/branch.c:537
+#: builtin/branch.c:540
 msgid "Branch is copied, but update of config-file failed"
 msgstr ""
 "La branche est copiée, mais la mise à jour du fichier de configuration a "
 "échoué"
 
-#: builtin/branch.c:553
+#: builtin/branch.c:556
 #, c-format
 msgid ""
 "Please edit the description for the branch\n"
@@ -6142,184 +6546,186 @@ msgstr ""
 "  %s\n"
 "Les lignes commençant par '%c' seront ignorées.\n"
 
-#: builtin/branch.c:586
+#: builtin/branch.c:589
 msgid "Generic options"
 msgstr "Options génériques"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:591
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "afficher le hachage et le sujet, doublé pour la branche amont"
 
-#: builtin/branch.c:589
+#: builtin/branch.c:592
 msgid "suppress informational messages"
 msgstr "supprimer les messages d'information"
 
-#: builtin/branch.c:590
+#: builtin/branch.c:593
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "régler le mode de suivi (voir git-pull(1))"
 
-#: builtin/branch.c:592
+#: builtin/branch.c:595
 msgid "do not use"
 msgstr "ne pas utiliser"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "upstream"
 msgstr "amont"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "change the upstream info"
 msgstr "modifier l'information amont"
 
-#: builtin/branch.c:595
+#: builtin/branch.c:598
 msgid "Unset the upstream info"
 msgstr "Désactiver l'information amont"
 
-#: builtin/branch.c:596
+#: builtin/branch.c:599
 msgid "use colored output"
 msgstr "utiliser la coloration dans la sortie"
 
-#: builtin/branch.c:597
+#: builtin/branch.c:600
 msgid "act on remote-tracking branches"
 msgstr "agir sur les branches de suivi distantes"
 
-#: builtin/branch.c:599 builtin/branch.c:601
+#: builtin/branch.c:602 builtin/branch.c:604
 msgid "print only branches that contain the commit"
 msgstr "afficher seulement les branches qui contiennent le commit"
 
-#: builtin/branch.c:600 builtin/branch.c:602
+#: builtin/branch.c:603 builtin/branch.c:605
 msgid "print only branches that don't contain the commit"
 msgstr "afficher seulement les branches qui ne contiennent pas le commit"
 
-#: builtin/branch.c:605
+#: builtin/branch.c:608
 msgid "Specific git-branch actions:"
 msgstr "Actions spécifiques à git-branch :"
 
-#: builtin/branch.c:606
+#: builtin/branch.c:609
 msgid "list both remote-tracking and local branches"
 msgstr "afficher à la fois les branches de suivi et les branches locales"
 
-#: builtin/branch.c:608
+#: builtin/branch.c:611
 msgid "delete fully merged branch"
 msgstr "supprimer une branche totalement fusionnée"
 
-#: builtin/branch.c:609
+#: builtin/branch.c:612
 msgid "delete branch (even if not merged)"
 msgstr "supprimer une branche (même non fusionnée)"
 
-#: builtin/branch.c:610
+#: builtin/branch.c:613
 msgid "move/rename a branch and its reflog"
 msgstr "déplacer/renommer une branche et son reflog"
 
-#: builtin/branch.c:611
+#: builtin/branch.c:614
 msgid "move/rename a branch, even if target exists"
 msgstr "déplacer/renommer une branche, même si la cible existe"
 
-#: builtin/branch.c:612
+#: builtin/branch.c:615
 msgid "copy a branch and its reflog"
 msgstr "copier une branche et son reflog"
 
-#: builtin/branch.c:613
+#: builtin/branch.c:616
 msgid "copy a branch, even if target exists"
 msgstr "copier une branche, même si la cible existe"
 
-#: builtin/branch.c:614
+#: builtin/branch.c:617
 msgid "list branch names"
 msgstr "afficher les noms des branches"
 
-#: builtin/branch.c:615
+#: builtin/branch.c:618
 msgid "create the branch's reflog"
 msgstr "créer le reflog de la branche"
 
-#: builtin/branch.c:617
+#: builtin/branch.c:620
 msgid "edit the description for the branch"
 msgstr "éditer la description de la branche"
 
-#: builtin/branch.c:618
+#: builtin/branch.c:621
 msgid "force creation, move/rename, deletion"
 msgstr "forcer la création, le déplacement/renommage, ou la suppression"
 
-#: builtin/branch.c:619
+#: builtin/branch.c:622
 msgid "print only branches that are merged"
 msgstr "afficher seulement les branches qui sont fusionnées"
 
-#: builtin/branch.c:620
+#: builtin/branch.c:623
 msgid "print only branches that are not merged"
 msgstr "afficher seulement les branches qui ne sont pas fusionnées"
 
-#: builtin/branch.c:621
+#: builtin/branch.c:624
 msgid "list branches in columns"
 msgstr "afficher les branches en colonnes"
 
-#: builtin/branch.c:622 builtin/for-each-ref.c:40 builtin/tag.c:411
+#: builtin/branch.c:625 builtin/for-each-ref.c:40 builtin/ls-remote.c:70
+#: builtin/tag.c:412
 msgid "key"
 msgstr "clé"
 
-#: builtin/branch.c:623 builtin/for-each-ref.c:41 builtin/tag.c:412
+#: builtin/branch.c:626 builtin/for-each-ref.c:41 builtin/ls-remote.c:71
+#: builtin/tag.c:413
 msgid "field name to sort on"
 msgstr "nom du champ servant à trier"
 
-#: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408
+#: builtin/branch.c:628 builtin/for-each-ref.c:43 builtin/notes.c:408
 #: builtin/notes.c:411 builtin/notes.c:571 builtin/notes.c:574
-#: builtin/tag.c:414
+#: builtin/tag.c:415
 msgid "object"
 msgstr "objet"
 
-#: builtin/branch.c:626
+#: builtin/branch.c:629
 msgid "print only branches of the object"
 msgstr "afficher seulement les branches de l'objet"
 
-#: builtin/branch.c:628 builtin/for-each-ref.c:49 builtin/tag.c:421
+#: builtin/branch.c:631 builtin/for-each-ref.c:49 builtin/tag.c:422
 msgid "sorting and filtering are case insensitive"
 msgstr "le tri et le filtrage sont non-sensibles à la casse"
 
-#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419
+#: builtin/branch.c:632 builtin/for-each-ref.c:38 builtin/tag.c:420
 #: builtin/verify-tag.c:39
 msgid "format to use for the output"
 msgstr "format à utiliser pour la sortie"
 
-#: builtin/branch.c:652 builtin/clone.c:735
+#: builtin/branch.c:655 builtin/clone.c:737
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD non trouvée sous refs/heads !"
 
-#: builtin/branch.c:675
+#: builtin/branch.c:678
 msgid "--column and --verbose are incompatible"
 msgstr "--column et --verbose sont incompatibles"
 
-#: builtin/branch.c:690 builtin/branch.c:742 builtin/branch.c:751
+#: builtin/branch.c:693 builtin/branch.c:745 builtin/branch.c:754
 msgid "branch name required"
 msgstr "le nom de branche est requis"
 
-#: builtin/branch.c:718
+#: builtin/branch.c:721
 msgid "Cannot give description to detached HEAD"
 msgstr "Impossible de décrire une HEAD détachée"
 
-#: builtin/branch.c:723
+#: builtin/branch.c:726
 msgid "cannot edit description of more than one branch"
 msgstr "impossible d'éditer la description de plus d'une branche"
 
-#: builtin/branch.c:730
+#: builtin/branch.c:733
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "Aucun commit sur la branche '%s'."
 
-#: builtin/branch.c:733
+#: builtin/branch.c:736
 #, c-format
 msgid "No branch named '%s'."
 msgstr "Aucune branche nommée '%s'."
 
-#: builtin/branch.c:748
+#: builtin/branch.c:751
 msgid "too many branches for a copy operation"
 msgstr "trop de branches pour une opération de copie"
 
-#: builtin/branch.c:757
+#: builtin/branch.c:760
 msgid "too many arguments for a rename operation"
 msgstr "trop d'arguments pour une opération de renommage"
 
-#: builtin/branch.c:762
+#: builtin/branch.c:765
 msgid "too many arguments to set new upstream"
 msgstr "trop d'arguments pour spécifier une branche amont"
 
-#: builtin/branch.c:766
+#: builtin/branch.c:769
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
@@ -6327,37 +6733,37 @@ msgstr ""
 "impossible de spécifier une branche amont de HEAD par %s qui ne pointe sur "
 "aucune branche."
 
-#: builtin/branch.c:769 builtin/branch.c:791 builtin/branch.c:807
+#: builtin/branch.c:772 builtin/branch.c:794 builtin/branch.c:810
 #, c-format
 msgid "no such branch '%s'"
 msgstr "pas de branche '%s'"
 
-#: builtin/branch.c:773
+#: builtin/branch.c:776
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "la branche '%s' n'existe pas"
 
-#: builtin/branch.c:785
+#: builtin/branch.c:788
 msgid "too many arguments to unset upstream"
 msgstr "trop d'arguments pour désactiver un amont"
 
-#: builtin/branch.c:789
+#: builtin/branch.c:792
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
 "impossible de désactiver une branche amont de HEAD quand elle ne pointe sur "
 "aucune branche."
 
-#: builtin/branch.c:795
+#: builtin/branch.c:798
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "La branche '%s' n'a aucune information de branche amont"
 
-#: builtin/branch.c:810
+#: builtin/branch.c:813
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr ""
 "les options -a et -r de 'git branch' n'ont pas de sens avec un nom de branche"
 
-#: builtin/branch.c:813
+#: builtin/branch.c:816
 msgid ""
 "the '--set-upstream' option is no longer supported. Please use '--track' or "
 "'--set-upstream-to' instead."
@@ -6378,7 +6784,7 @@ msgstr "La création d'un colis requiert un dépôt."
 msgid "Need a repository to unbundle."
 msgstr "Le dépaquetage d'un colis requiert un dépôt."
 
-#: builtin/cat-file.c:523
+#: builtin/cat-file.c:525
 msgid ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <type> | --textconv | --filters) [--path=<path>] <object>"
@@ -6386,7 +6792,7 @@ msgstr ""
 "git cat-file (-t [--allow-unknow-type] | -s [--allow-unknow-type] | -e | -p "
 "| <type> | --textconv | --filters) [--path=<chemin>] <objet>"
 
-#: builtin/cat-file.c:524
+#: builtin/cat-file.c:526
 msgid ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
@@ -6394,66 +6800,66 @@ msgstr ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
 
-#: builtin/cat-file.c:561
+#: builtin/cat-file.c:563
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<type> peut être : blob, tree, commit ou tag"
 
-#: builtin/cat-file.c:562
+#: builtin/cat-file.c:564
 msgid "show object type"
 msgstr "afficher le type de l'objet"
 
-#: builtin/cat-file.c:563
+#: builtin/cat-file.c:565
 msgid "show object size"
 msgstr "afficher la taille de l'objet"
 
-#: builtin/cat-file.c:565
+#: builtin/cat-file.c:567
 msgid "exit with zero when there's no error"
 msgstr "sortir avec un code d'erreur nul quand il n'y a aucune erreur"
 
-#: builtin/cat-file.c:566
+#: builtin/cat-file.c:568
 msgid "pretty-print object's content"
 msgstr "afficher avec mise en forme le contenu de l'objet"
 
-#: builtin/cat-file.c:568
+#: builtin/cat-file.c:570
 msgid "for blob objects, run textconv on object's content"
 msgstr "pour les objets blob, lancer textconv sur le contenu de l'objet"
 
-#: builtin/cat-file.c:570
+#: builtin/cat-file.c:572
 msgid "for blob objects, run filters on object's content"
 msgstr "pour les objets blob, lancer les filtres sur le contenu de l'objet"
 
-#: builtin/cat-file.c:571 git-submodule.sh:878
+#: builtin/cat-file.c:573 git-submodule.sh:894
 msgid "blob"
 msgstr "blob"
 
-#: builtin/cat-file.c:572
+#: builtin/cat-file.c:574
 msgid "use a specific path for --textconv/--filters"
 msgstr "utiliser un chemin spécifique pour --textconv/--filters"
 
-#: builtin/cat-file.c:574
+#: builtin/cat-file.c:576
 msgid "allow -s and -t to work with broken/corrupt objects"
 msgstr "autoriser -s et -t à travailler sur des objets cassés/corrompus"
 
-#: builtin/cat-file.c:575
+#: builtin/cat-file.c:577
 msgid "buffer --batch output"
 msgstr "bufferiser la sortie de --batch"
 
-#: builtin/cat-file.c:577
+#: builtin/cat-file.c:579
 msgid "show info and content of objects fed from the standard input"
 msgstr ""
 "afficher l'information et le contenu des objets passés en entrée standard"
 
-#: builtin/cat-file.c:580
+#: builtin/cat-file.c:582
 msgid "show info about objects fed from the standard input"
 msgstr "afficher l'information des objets passés en entrée standard"
 
-#: builtin/cat-file.c:583
+#: builtin/cat-file.c:585
 msgid "follow in-tree symlinks (used with --batch or --batch-check)"
 msgstr ""
 "suivre les liens symbolique internes à la copie de travail (utilisé avec --"
 "batch ou --batch-check)"
 
-#: builtin/cat-file.c:585
+#: builtin/cat-file.c:587
 msgid "show all objects with --batch or --batch-check"
 msgstr "montrer tous les objets avec --batch ou --batch-check"
 
@@ -6482,7 +6888,7 @@ msgid "terminate input and output records by a NUL character"
 msgstr ""
 "terminer les enregistrements en entrée et en sortie par un caractère NUL"
 
-#: builtin/check-ignore.c:20 builtin/checkout.c:1106 builtin/gc.c:358
+#: builtin/check-ignore.c:20 builtin/checkout.c:1113 builtin/gc.c:500
 msgid "suppress progress reporting"
 msgstr "supprimer l'état d'avancement"
 
@@ -6574,9 +6980,9 @@ msgid "write the content to temporary files"
 msgstr "écrire le contenu dans des fichiers temporaires"
 
 #: builtin/checkout-index.c:173 builtin/column.c:31
-#: builtin/submodule--helper.c:1203 builtin/submodule--helper.c:1206
-#: builtin/submodule--helper.c:1212 builtin/submodule--helper.c:1574
-#: builtin/worktree.c:570
+#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1219
+#: builtin/submodule--helper.c:1227 builtin/submodule--helper.c:1591
+#: builtin/worktree.c:610
 msgid "string"
 msgstr "chaîne"
 
@@ -6649,54 +7055,54 @@ msgstr ""
 msgid "path '%s' is unmerged"
 msgstr "le chemin '%s' n'est pas fusionné"
 
-#: builtin/checkout.c:505
+#: builtin/checkout.c:506
 msgid "you need to resolve your current index first"
 msgstr "vous devez d'abord résoudre votre index courant"
 
-#: builtin/checkout.c:636
+#: builtin/checkout.c:643
 #, c-format
 msgid "Can not do reflog for '%s': %s\n"
 msgstr "Impossible de faire un reflog pour '%s' : %s\n"
 
-#: builtin/checkout.c:677
+#: builtin/checkout.c:684
 msgid "HEAD is now at"
 msgstr "HEAD est maintenant sur"
 
-#: builtin/checkout.c:681 builtin/clone.c:689
+#: builtin/checkout.c:688 builtin/clone.c:691
 msgid "unable to update HEAD"
 msgstr "impossible de mettre à jour HEAD"
 
-#: builtin/checkout.c:685
+#: builtin/checkout.c:692
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Remise à zéro de la branche '%s'\n"
 
-#: builtin/checkout.c:688
+#: builtin/checkout.c:695
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Déjà sur '%s'\n"
 
-#: builtin/checkout.c:692
+#: builtin/checkout.c:699
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Basculement et remise à zéro de la branche '%s'\n"
 
-#: builtin/checkout.c:694 builtin/checkout.c:1039
+#: builtin/checkout.c:701 builtin/checkout.c:1046
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Basculement sur la nouvelle branche '%s'\n"
 
-#: builtin/checkout.c:696
+#: builtin/checkout.c:703
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Basculement sur la branche '%s'\n"
 
-#: builtin/checkout.c:747
+#: builtin/checkout.c:754
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... et %d en plus.\n"
 
-#: builtin/checkout.c:753
+#: builtin/checkout.c:760
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -6719,7 +7125,7 @@ msgstr[1] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:772
+#: builtin/checkout.c:779
 #, c-format
 msgid ""
 "If you want to keep it by creating a new branch, this may be a good time\n"
@@ -6748,162 +7154,162 @@ msgstr[1] ""
 "git branch <nouvelle-branche> %s\n"
 "\n"
 
-#: builtin/checkout.c:804
+#: builtin/checkout.c:811
 msgid "internal error in revision walk"
 msgstr "erreur interne lors du parcours des révisions"
 
-#: builtin/checkout.c:808
+#: builtin/checkout.c:815
 msgid "Previous HEAD position was"
 msgstr "La position précédente de HEAD était sur"
 
-#: builtin/checkout.c:836 builtin/checkout.c:1034
+#: builtin/checkout.c:843 builtin/checkout.c:1041
 msgid "You are on a branch yet to be born"
 msgstr "Vous êtes sur une branche qui doit encore naître"
 
-#: builtin/checkout.c:940
+#: builtin/checkout.c:947
 #, c-format
 msgid "only one reference expected, %d given."
 msgstr "une seule référence attendue, %d fournies."
 
-#: builtin/checkout.c:980 builtin/worktree.c:249
+#: builtin/checkout.c:987 builtin/worktree.c:240 builtin/worktree.c:389
 #, c-format
 msgid "invalid reference: %s"
 msgstr "référence invalide : %s"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1016
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "la référence n'est pas un arbre : %s"
 
-#: builtin/checkout.c:1048
+#: builtin/checkout.c:1055
 msgid "paths cannot be used with switching branches"
 msgstr "impossible d'utiliser des chemins avec un basculement de branches"
 
-#: builtin/checkout.c:1051 builtin/checkout.c:1055
+#: builtin/checkout.c:1058 builtin/checkout.c:1062
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "'%s' ne peut pas être utilisé avec un basculement de branches"
 
-#: builtin/checkout.c:1059 builtin/checkout.c:1062 builtin/checkout.c:1067
-#: builtin/checkout.c:1070
+#: builtin/checkout.c:1066 builtin/checkout.c:1069 builtin/checkout.c:1074
+#: builtin/checkout.c:1077
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "'%s' ne peut pas être utilisé avec '%s'"
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1082
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "Impossible de basculer de branche vers '%s' qui n'est pas un commit"
 
-#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116
-#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:387
-#: builtin/worktree.c:389
+#: builtin/checkout.c:1114 builtin/checkout.c:1116 builtin/clone.c:118
+#: builtin/remote.c:167 builtin/remote.c:169 builtin/worktree.c:433
+#: builtin/worktree.c:435
 msgid "branch"
 msgstr "branche"
 
-#: builtin/checkout.c:1108
+#: builtin/checkout.c:1115
 msgid "create and checkout a new branch"
 msgstr "créer et extraire une nouvelle branche"
 
-#: builtin/checkout.c:1110
+#: builtin/checkout.c:1117
 msgid "create/reset and checkout a branch"
 msgstr "créer/réinitialiser et extraire une branche"
 
-#: builtin/checkout.c:1111
+#: builtin/checkout.c:1118
 msgid "create reflog for new branch"
 msgstr "créer un reflog pour une nouvelle branche"
 
-#: builtin/checkout.c:1112 builtin/worktree.c:391
+#: builtin/checkout.c:1119 builtin/worktree.c:437
 msgid "detach HEAD at named commit"
 msgstr "détacher la HEAD au commit nommé"
 
-#: builtin/checkout.c:1113
+#: builtin/checkout.c:1120
 msgid "set upstream info for new branch"
 msgstr "paramétrer les coordonnées de branche amont pour une nouvelle branche"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new-branch"
 msgstr "nouvelle branche"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new unparented branch"
 msgstr "nouvelle branche sans parent"
 
-#: builtin/checkout.c:1116
+#: builtin/checkout.c:1123
 msgid "checkout our version for unmerged files"
 msgstr "extraire notre version pour les fichiers non fusionnés"
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1125
 msgid "checkout their version for unmerged files"
 msgstr "extraire leur version pour les fichiers non fusionnés"
 
-#: builtin/checkout.c:1120
+#: builtin/checkout.c:1127
 msgid "force checkout (throw away local modifications)"
 msgstr "forcer l'extraction (laisser tomber les modifications locales)"
 
-#: builtin/checkout.c:1122
+#: builtin/checkout.c:1129
 msgid "perform a 3-way merge with the new branch"
 msgstr "effectuer une fusion à 3 points avec la nouvelle branche"
 
-#: builtin/checkout.c:1124 builtin/merge.c:239
+#: builtin/checkout.c:1131 builtin/merge.c:241
 msgid "update ignored files (default)"
 msgstr "mettre à jour les fichiers ignorés (par défaut)"
 
-#: builtin/checkout.c:1126 builtin/log.c:1499 parse-options.h:263
+#: builtin/checkout.c:1133 builtin/log.c:1499 parse-options.h:264
 msgid "style"
 msgstr "style"
 
-#: builtin/checkout.c:1127
+#: builtin/checkout.c:1134
 msgid "conflict style (merge or diff3)"
 msgstr "style de conflit (merge (fusion) ou diff3)"
 
-#: builtin/checkout.c:1130
+#: builtin/checkout.c:1137
 msgid "do not limit pathspecs to sparse entries only"
 msgstr "ne pas limiter les spécificateurs de chemins aux seuls éléments creux"
 
-#: builtin/checkout.c:1132
+#: builtin/checkout.c:1139
 msgid "second guess 'git checkout <no-such-branch>'"
 msgstr "réessayer d'interpréter 'git checkout <branche-inexistante>'"
 
-#: builtin/checkout.c:1134
+#: builtin/checkout.c:1141
 msgid "do not check if another worktree is holding the given ref"
 msgstr ""
 "ne pas vérifier si une autre copie de travail contient le référence fournie"
 
-#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150
-#: builtin/merge.c:236 builtin/pull.c:123 builtin/push.c:556
-#: builtin/send-pack.c:173
+#: builtin/checkout.c:1145 builtin/clone.c:85 builtin/fetch.c:149
+#: builtin/merge.c:238 builtin/pull.c:128 builtin/push.c:572
+#: builtin/send-pack.c:174
 msgid "force progress reporting"
 msgstr "forcer l'affichage de l'état d'avancement"
 
-#: builtin/checkout.c:1168
+#: builtin/checkout.c:1175
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "-b, -B et --orphan sont mutuellement exclusifs"
 
-#: builtin/checkout.c:1185
+#: builtin/checkout.c:1192
 msgid "--track needs a branch name"
 msgstr "--track requiert un nom de branche"
 
-#: builtin/checkout.c:1190
+#: builtin/checkout.c:1197
 msgid "Missing branch name; try -b"
 msgstr "Nom de branche manquant ; essayez -b"
 
-#: builtin/checkout.c:1226
+#: builtin/checkout.c:1233
 msgid "invalid path specification"
 msgstr "spécification de chemin invalide"
 
-#: builtin/checkout.c:1233
+#: builtin/checkout.c:1240
 #, c-format
 msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
 msgstr ""
 "'%s' n'est pas un commit et une branche '%s' ne peut pas en être créée depuis"
 
-#: builtin/checkout.c:1237
+#: builtin/checkout.c:1244
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout: --detach n'accepte pas un argument de chemin '%s'"
 
-#: builtin/checkout.c:1241
+#: builtin/checkout.c:1248
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -6942,7 +7348,7 @@ msgstr "Ignorerait le dépôt %s\n"
 msgid "failed to remove %s"
 msgstr "échec de la suppression de %s"
 
-#: builtin/clean.c:302 git-add--interactive.perl:572
+#: builtin/clean.c:302 git-add--interactive.perl:579
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6955,7 +7361,7 @@ msgstr ""
 "foo         - sélectionner un élément par un préfixe unique\n"
 "            - (vide) ne rien sélectionner\n"
 
-#: builtin/clean.c:306 git-add--interactive.perl:581
+#: builtin/clean.c:306 git-add--interactive.perl:588
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6976,8 +7382,8 @@ msgstr ""
 "*          - choisir tous les éléments\n"
 "           - (vide) terminer la sélection\n"
 
-#: builtin/clean.c:522 git-add--interactive.perl:547
-#: git-add--interactive.perl:552
+#: builtin/clean.c:522 git-add--interactive.perl:554
+#: git-add--interactive.perl:559
 #, c-format, perl-format
 msgid "Huh (%s)?\n"
 msgstr "Hein (%s) ?\n"
@@ -7002,7 +7408,7 @@ msgstr "Sélectionner les éléments à supprimer"
 msgid "Remove %s [y/N]? "
 msgstr "Supprimer %s [y/N] ? "
 
-#: builtin/clean.c:788 git-add--interactive.perl:1710
+#: builtin/clean.c:788 git-add--interactive.perl:1717
 #, c-format
 msgid "Bye.\n"
 msgstr "Au revoir.\n"
@@ -7025,11 +7431,11 @@ msgstr ""
 "help                - cet écran\n"
 "?                   - aide pour la sélection en ligne"
 
-#: builtin/clean.c:823 git-add--interactive.perl:1786
+#: builtin/clean.c:823 git-add--interactive.perl:1793
 msgid "*** Commands ***"
 msgstr "*** Commandes ***"
 
-#: builtin/clean.c:824 git-add--interactive.perl:1783
+#: builtin/clean.c:824 git-add--interactive.perl:1790
 msgid "What now"
 msgstr "Et maintenant ?"
 
@@ -7098,147 +7504,149 @@ msgstr ""
 "clean.requireForce à true par défaut et ni -i, -n ou -f fourni ; refus de "
 "nettoyer"
 
-#: builtin/clone.c:40
+#: builtin/clone.c:42
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<options>] [--] <dépôt> [<répertoire>]"
 
-#: builtin/clone.c:85
+#: builtin/clone.c:87
 msgid "don't create a checkout"
 msgstr "ne pas créer d'extraction"
 
-#: builtin/clone.c:86 builtin/clone.c:88 builtin/init-db.c:479
+#: builtin/clone.c:88 builtin/clone.c:90 builtin/init-db.c:479
 msgid "create a bare repository"
 msgstr "créer un dépôt nu"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:92
 msgid "create a mirror repository (implies bare)"
 msgstr "créer un dépôt miroir (implique dépôt nu)"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:94
 msgid "to clone from a local repository"
 msgstr "pour cloner depuis un dépôt local"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:96
 msgid "don't use local hardlinks, always copy"
 msgstr "ne pas utiliser de liens durs locaux, toujours copier"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:98
 msgid "setup as shared repository"
 msgstr "régler comme dépôt partagé"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "pathspec"
 msgstr "spécificateur de chemin"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "initialize submodules in the clone"
 msgstr "initialiser les sous-modules dans le clone"
 
-#: builtin/clone.c:105
+#: builtin/clone.c:107
 msgid "number of submodules cloned in parallel"
 msgstr "nombre de sous-modules clonés en parallèle"
 
-#: builtin/clone.c:106 builtin/init-db.c:476
+#: builtin/clone.c:108 builtin/init-db.c:476
 msgid "template-directory"
 msgstr "répertoire-modèle"
 
-#: builtin/clone.c:107 builtin/init-db.c:477
+#: builtin/clone.c:109 builtin/init-db.c:477
 msgid "directory from which templates will be used"
 msgstr "répertoire depuis lequel les modèles vont être utilisés"
 
-#: builtin/clone.c:109 builtin/clone.c:111 builtin/submodule--helper.c:1210
-#: builtin/submodule--helper.c:1577
+#: builtin/clone.c:111 builtin/clone.c:113 builtin/submodule--helper.c:1223
+#: builtin/submodule--helper.c:1594
 msgid "reference repository"
 msgstr "dépôt de référence"
 
-#: builtin/clone.c:113
+#: builtin/clone.c:115 builtin/submodule--helper.c:1225
+#: builtin/submodule--helper.c:1596
 msgid "use --reference only while cloning"
 msgstr "utiliser seulement --reference pour cloner"
 
-#: builtin/clone.c:114 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/clone.c:116 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/pack-objects.c:3166 builtin/repack.c:213
 msgid "name"
 msgstr "nom"
 
-#: builtin/clone.c:115
+#: builtin/clone.c:117
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "utiliser <nom> au lieu de 'origin' pour suivre la branche amont"
 
-#: builtin/clone.c:117
+#: builtin/clone.c:119
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "extraire <branche> au lieu de la HEAD du répertoire distant"
 
-#: builtin/clone.c:119
+#: builtin/clone.c:121
 msgid "path to git-upload-pack on the remote"
 msgstr "chemin vers git-upload-pack sur le serveur distant"
 
-#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813
-#: builtin/pull.c:211
+#: builtin/clone.c:122 builtin/fetch.c:150 builtin/grep.c:813
+#: builtin/pull.c:216
 msgid "depth"
 msgstr "profondeur"
 
-#: builtin/clone.c:121
+#: builtin/clone.c:123
 msgid "create a shallow clone of that depth"
 msgstr "créer un clone superficiel de cette profondeur"
 
-#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017
+#: builtin/clone.c:124 builtin/fetch.c:152 builtin/pack-objects.c:3157
 #: parse-options.h:154
 msgid "time"
 msgstr "heure"
 
-#: builtin/clone.c:123
+#: builtin/clone.c:125
 msgid "create a shallow clone since a specific time"
 msgstr "créer un clone superficiel depuis une date spécifique"
 
-#: builtin/clone.c:124 builtin/fetch.c:155
+#: builtin/clone.c:126 builtin/fetch.c:154
 msgid "revision"
 msgstr "révision"
 
-#: builtin/clone.c:125 builtin/fetch.c:156
+#: builtin/clone.c:127 builtin/fetch.c:155
 msgid "deepen history of shallow clone, excluding rev"
 msgstr ""
 "approfondir l'historique d'un clone superficiel en excluant une révision"
 
-#: builtin/clone.c:127
+#: builtin/clone.c:129
 msgid "clone only one branch, HEAD or --branch"
 msgstr "cloner seulement une branche, HEAD ou --branch"
 
-#: builtin/clone.c:129
+#: builtin/clone.c:131
 msgid "don't clone any tags, and make later fetches not to follow them"
 msgstr ""
 "ne pas cloner les tags et indiquer aux récupérations futures de ne pas le "
 "faire"
 
-#: builtin/clone.c:131
+#: builtin/clone.c:133
 msgid "any cloned submodules will be shallow"
 msgstr "tous les sous-modules clonés seront superficiels"
 
-#: builtin/clone.c:132 builtin/init-db.c:485
+#: builtin/clone.c:134 builtin/init-db.c:485
 msgid "gitdir"
 msgstr "gitdir"
 
-#: builtin/clone.c:133 builtin/init-db.c:486
+#: builtin/clone.c:135 builtin/init-db.c:486
 msgid "separate git dir from working tree"
 msgstr "séparer le répertoire git de la copie de travail"
 
-#: builtin/clone.c:134
+#: builtin/clone.c:136
 msgid "key=value"
 msgstr "clé=valeur"
 
-#: builtin/clone.c:135
+#: builtin/clone.c:137
 msgid "set config inside the new repository"
 msgstr "régler la configuration dans le nouveau dépôt"
 
-#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224
-#: builtin/push.c:567
+#: builtin/clone.c:138 builtin/fetch.c:173 builtin/pull.c:229
+#: builtin/push.c:583
 msgid "use IPv4 addresses only"
 msgstr "n'utiliser que des adresses IPv4"
 
-#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227
-#: builtin/push.c:569
+#: builtin/clone.c:140 builtin/fetch.c:175 builtin/pull.c:232
+#: builtin/push.c:585
 msgid "use IPv6 addresses only"
 msgstr "n'utiliser que des adresses IPv6"
 
-#: builtin/clone.c:276
+#: builtin/clone.c:278
 msgid ""
 "No directory name could be guessed.\n"
 "Please specify a directory on the command line"
@@ -7246,42 +7654,42 @@ msgstr ""
 "Aucun nom de répertoire n'a pu être deviné\n"
 "Veuillez spécifier un répertoire dans la ligne de commande"
 
-#: builtin/clone.c:329
+#: builtin/clone.c:331
 #, c-format
 msgid "info: Could not add alternate for '%s': %s\n"
 msgstr "info : impossible d'ajouter une alternative pour '%s' : %s\n"
 
-#: builtin/clone.c:401
+#: builtin/clone.c:403
 #, c-format
 msgid "failed to open '%s'"
 msgstr "échec à l'ouverture de '%s'"
 
-#: builtin/clone.c:409
+#: builtin/clone.c:411
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "%s existe et n'est pas un répertoire"
 
-#: builtin/clone.c:423
+#: builtin/clone.c:425
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "échec du stat de %s\n"
 
-#: builtin/clone.c:445
+#: builtin/clone.c:447
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "échec de la création du lien '%s'"
 
-#: builtin/clone.c:449
+#: builtin/clone.c:451
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "échec de la copie vers '%s'"
 
-#: builtin/clone.c:475
+#: builtin/clone.c:477
 #, c-format
 msgid "done.\n"
 msgstr "fait.\n"
 
-#: builtin/clone.c:489
+#: builtin/clone.c:491
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -7291,102 +7699,102 @@ msgstr ""
 "Vous pouvez inspecter ce qui a été extrait avec 'git status'\n"
 "et réessayer l'extraction avec 'git checkout -f HEAD'\n"
 
-#: builtin/clone.c:566
+#: builtin/clone.c:568
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "Impossible de trouver la branche distante '%s' à cloner."
 
-#: builtin/clone.c:661
+#: builtin/clone.c:663
 msgid "remote did not send all necessary objects"
 msgstr "le serveur distant n'a pas envoyé tous les objets nécessaires"
 
-#: builtin/clone.c:677
+#: builtin/clone.c:679
 #, c-format
 msgid "unable to update %s"
 msgstr "impossible de mettre à jour %s"
 
-#: builtin/clone.c:726
+#: builtin/clone.c:728
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
 "la HEAD distante réfère à une référence non existante, impossible de "
 "l'extraire.\n"
 
-#: builtin/clone.c:756
+#: builtin/clone.c:758
 msgid "unable to checkout working tree"
 msgstr "impossible d'extraire la copie de travail"
 
-#: builtin/clone.c:801
+#: builtin/clone.c:803
 msgid "unable to write parameters to config file"
 msgstr "impossible d'écrire les paramètres dans le fichier de configuration"
 
-#: builtin/clone.c:864
+#: builtin/clone.c:866
 msgid "cannot repack to clean up"
 msgstr "impossible de remballer pour nettoyer"
 
-#: builtin/clone.c:866
+#: builtin/clone.c:868
 msgid "cannot unlink temporary alternates file"
 msgstr "impossible de unlinker le fichier temporaire alternates"
 
-#: builtin/clone.c:906 builtin/receive-pack.c:1946
+#: builtin/clone.c:907 builtin/receive-pack.c:1947
 msgid "Too many arguments."
 msgstr "Trop d'arguments."
 
-#: builtin/clone.c:910
+#: builtin/clone.c:911
 msgid "You must specify a repository to clone."
 msgstr "Vous devez spécifier un dépôt à cloner."
 
-#: builtin/clone.c:923
+#: builtin/clone.c:924
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "les options --bare et --origin %s sont incompatibles."
 
-#: builtin/clone.c:926
+#: builtin/clone.c:927
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "--bare et --separate-git-dir sont incompatibles."
 
-#: builtin/clone.c:939
+#: builtin/clone.c:940
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "le dépôt '%s' n'existe pas"
 
-#: builtin/clone.c:945 builtin/fetch.c:1455
+#: builtin/clone.c:946 builtin/fetch.c:1460
 #, c-format
 msgid "depth %s is not a positive number"
 msgstr "la profondeur %s n'est pas un entier positif"
 
-#: builtin/clone.c:955
+#: builtin/clone.c:956
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr ""
 "le chemin de destination '%s' existe déjà et n'est pas un répertoire vide."
 
-#: builtin/clone.c:965
+#: builtin/clone.c:966
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "la copie de travail '%s' existe déjà."
 
-#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270
-#: builtin/worktree.c:255 builtin/worktree.c:285
+#: builtin/clone.c:981 builtin/clone.c:1002 builtin/difftool.c:270
+#: builtin/worktree.c:246 builtin/worktree.c:276
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "impossible de créer les répertoires de premier niveau dans '%s'"
 
-#: builtin/clone.c:985
+#: builtin/clone.c:986
 #, c-format
 msgid "could not create work tree dir '%s'"
 msgstr "impossible de créer le répertoire de la copie de travail '%s'"
 
-#: builtin/clone.c:1005
+#: builtin/clone.c:1006
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Clonage dans le dépôt nu '%s'\n"
 
-#: builtin/clone.c:1007
+#: builtin/clone.c:1008
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Clonage dans '%s'...\n"
 
-#: builtin/clone.c:1031
+#: builtin/clone.c:1032
 msgid ""
 "clone --recursive is not compatible with both --reference and --reference-if-"
 "able"
@@ -7460,7 +7868,7 @@ msgstr "Remplissage d'espace sur le côté droit"
 msgid "Padding space between columns"
 msgstr "Remplissage d'espace entre les colonnes"
 
-#: builtin/column.c:52
+#: builtin/column.c:51
 msgid "--command must be the first argument"
 msgstr "--command doit être le premier argument"
 
@@ -7518,61 +7926,61 @@ msgstr ""
 "Puis \"git cherry-pick --continue\" continuera le picorage \n"
 "des commits restants.\n"
 
-#: builtin/commit.c:284
+#: builtin/commit.c:293
 msgid "failed to unpack HEAD tree object"
 msgstr "échec du dépaquetage de l'objet arbre HEAD"
 
-#: builtin/commit.c:325
+#: builtin/commit.c:334
 msgid "unable to create temporary index"
 msgstr "impossible de créer l'index temporaire"
 
-#: builtin/commit.c:331
+#: builtin/commit.c:340
 msgid "interactive add failed"
 msgstr "échec de l'ajout interactif"
 
-#: builtin/commit.c:344
+#: builtin/commit.c:353
 msgid "unable to update temporary index"
 msgstr "impossible de mettre à jour l'index temporaire"
 
-#: builtin/commit.c:346
+#: builtin/commit.c:355
 msgid "Failed to update main cache tree"
 msgstr "Impossible de mettre à jour l'arbre de cache principal"
 
-#: builtin/commit.c:371 builtin/commit.c:395 builtin/commit.c:444
+#: builtin/commit.c:380 builtin/commit.c:403 builtin/commit.c:449
 msgid "unable to write new_index file"
 msgstr "impossible d'écrire le fichier new_index"
 
-#: builtin/commit.c:427
+#: builtin/commit.c:432
 msgid "cannot do a partial commit during a merge."
 msgstr "impossible de faire une validation partielle pendant une fusion."
 
-#: builtin/commit.c:429
+#: builtin/commit.c:434
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "impossible de faire une validation partielle pendant un picorage."
 
-#: builtin/commit.c:437
+#: builtin/commit.c:442
 msgid "cannot read the index"
 msgstr "impossible de lire l'index"
 
-#: builtin/commit.c:456
+#: builtin/commit.c:461
 msgid "unable to write temporary index file"
 msgstr "impossible d'écrire le fichier d'index temporaire"
 
-#: builtin/commit.c:553
+#: builtin/commit.c:558
 #, c-format
 msgid "commit '%s' lacks author header"
 msgstr "entête d'auteur manquant dans le commit '%s'"
 
-#: builtin/commit.c:555
+#: builtin/commit.c:560
 #, c-format
 msgid "commit '%s' has malformed author line"
 msgstr "le commit '%s' a une ligne d'auteur malformée"
 
-#: builtin/commit.c:574
+#: builtin/commit.c:579
 msgid "malformed --author parameter"
 msgstr "paramètre --author mal formé"
 
-#: builtin/commit.c:626
+#: builtin/commit.c:631
 msgid ""
 "unable to select a comment character that is not used\n"
 "in the current commit message"
@@ -7580,38 +7988,38 @@ msgstr ""
 "impossible de sélectionner un caractère de commentaire\n"
 "qui n'est pas utilisé dans le message de validation actuel"
 
-#: builtin/commit.c:663 builtin/commit.c:696 builtin/commit.c:1024
+#: builtin/commit.c:668 builtin/commit.c:701 builtin/commit.c:1029
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "impossible de rechercher le commit %s"
 
-#: builtin/commit.c:675 builtin/shortlog.c:309
+#: builtin/commit.c:680 builtin/shortlog.c:316
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(lecture du message de journal depuis l'entrée standard)\n"
 
-#: builtin/commit.c:677
+#: builtin/commit.c:682
 msgid "could not read log from standard input"
 msgstr "impossible de lire le journal depuis l'entrée standard"
 
-#: builtin/commit.c:681
+#: builtin/commit.c:686
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "impossible de lire le fichier de journal '%s'"
 
-#: builtin/commit.c:710 builtin/commit.c:718
+#: builtin/commit.c:715 builtin/commit.c:723
 msgid "could not read SQUASH_MSG"
 msgstr "impossible de lire SQUASH_MSG"
 
-#: builtin/commit.c:715
+#: builtin/commit.c:720
 msgid "could not read MERGE_MSG"
 msgstr "impossible de lire MERGE_MSG"
 
-#: builtin/commit.c:769
+#: builtin/commit.c:774
 msgid "could not write commit template"
 msgstr "impossible d'écrire le modèle de commit"
 
-#: builtin/commit.c:787
+#: builtin/commit.c:792
 #, c-format
 msgid ""
 "\n"
@@ -7626,7 +8034,7 @@ msgstr ""
 "\t%s\n"
 "et essayez à nouveau.\n"
 
-#: builtin/commit.c:792
+#: builtin/commit.c:797
 #, c-format
 msgid ""
 "\n"
@@ -7641,7 +8049,7 @@ msgstr ""
 "\t%s\n"
 "et essayez à nouveau.\n"
 
-#: builtin/commit.c:805
+#: builtin/commit.c:810
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7651,7 +8059,7 @@ msgstr ""
 "commençant par '%c' seront ignorées, et un message vide abandonne la "
 "validation.\n"
 
-#: builtin/commit.c:813
+#: builtin/commit.c:818
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7662,151 +8070,151 @@ msgstr ""
 "commençant par '%c' seront conservées ; vous pouvez les supprimer vous-même\n"
 "si vous le souhaitez. Un message vide abandonne la validation.\n"
 
-#: builtin/commit.c:830
+#: builtin/commit.c:835
 #, c-format
 msgid "%sAuthor:    %.*s <%.*s>"
 msgstr "%sAuteur :     %.*s <%.*s>"
 
-#: builtin/commit.c:838
+#: builtin/commit.c:843
 #, c-format
 msgid "%sDate:      %s"
 msgstr "%sDate :       %s"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:850
 #, c-format
 msgid "%sCommitter: %.*s <%.*s>"
 msgstr "%sValidateur : %.*s <%.*s>"
 
-#: builtin/commit.c:862
+#: builtin/commit.c:867
 msgid "Cannot read index"
 msgstr "Impossible de lire l'index"
 
-#: builtin/commit.c:928
+#: builtin/commit.c:933
 msgid "Error building trees"
 msgstr "Erreur lors de la construction des arbres"
 
-#: builtin/commit.c:942 builtin/tag.c:256
+#: builtin/commit.c:947 builtin/tag.c:257
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "Veuillez fournir le message en utilisant l'option -m ou -F.\n"
 
-#: builtin/commit.c:986
+#: builtin/commit.c:991
 #, c-format
 msgid "--author '%s' is not 'Name <email>' and matches no existing author"
 msgstr ""
 "--author '%s' n'est pas de la forme 'Nom <email>' ni ne correspond à aucun "
 "auteur existant"
 
-#: builtin/commit.c:1000
+#: builtin/commit.c:1005
 #, c-format
 msgid "Invalid ignored mode '%s'"
 msgstr "Mode de fichier ignoré invalide '%s'"
 
-#: builtin/commit.c:1014 builtin/commit.c:1264
+#: builtin/commit.c:1019 builtin/commit.c:1269
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "Mode de fichier non suivi invalide '%s'"
 
-#: builtin/commit.c:1052
+#: builtin/commit.c:1057
 msgid "--long and -z are incompatible"
 msgstr "--long et -z sont incompatibles"
 
-#: builtin/commit.c:1085
+#: builtin/commit.c:1090
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "L'utilisation simultanée de --reset-author et --author n'a pas de sens"
 
-#: builtin/commit.c:1094
+#: builtin/commit.c:1099
 msgid "You have nothing to amend."
 msgstr "Il n'y a rien à corriger."
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1102
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "Vous êtes en pleine fusion -- impossible de corriger (amend)."
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1104
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "Vous êtes en plein picorage -- impossible de corriger (amend)."
 
-#: builtin/commit.c:1102
+#: builtin/commit.c:1107
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "Les options --squash et --fixup ne peuvent pas être utilisées ensemble"
 
-#: builtin/commit.c:1112
+#: builtin/commit.c:1117
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "Une seule option parmi -c/-C/-F/--fixup peut être utilisée."
 
-#: builtin/commit.c:1114
+#: builtin/commit.c:1119
 msgid "Option -m cannot be combined with -c/-C/-F."
 msgstr "L'option -m ne peut pas être combinée avec -c/-C/-F."
 
-#: builtin/commit.c:1122
+#: builtin/commit.c:1127
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr "--reset-author ne peut être utilisé qu'avec -C, -c ou --amend."
 
-#: builtin/commit.c:1139
+#: builtin/commit.c:1144
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 "Une seule option parmi --include/--only/--all/--interactive/--patch peut "
 "être utilisée."
 
-#: builtin/commit.c:1141
+#: builtin/commit.c:1146
 msgid "No paths with --include/--only does not make sense."
 msgstr "Aucun chemin avec les options --include/--only n'a pas de sens."
 
-#: builtin/commit.c:1155 builtin/tag.c:542
+#: builtin/commit.c:1160 builtin/tag.c:543
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Mode de nettoyage invalide %s"
 
-#: builtin/commit.c:1160
+#: builtin/commit.c:1165
 msgid "Paths with -a does not make sense."
 msgstr "Spécifier des chemins avec l'option -a n'a pas de sens."
 
-#: builtin/commit.c:1278 builtin/commit.c:1443
+#: builtin/commit.c:1303 builtin/commit.c:1480
 msgid "show status concisely"
 msgstr "afficher l'état avec concision"
 
-#: builtin/commit.c:1280 builtin/commit.c:1445
+#: builtin/commit.c:1305 builtin/commit.c:1482
 msgid "show branch information"
 msgstr "afficher l'information de branche"
 
-#: builtin/commit.c:1282
+#: builtin/commit.c:1307
 msgid "show stash information"
 msgstr "afficher l'information de remisage"
 
-#: builtin/commit.c:1284 builtin/commit.c:1447
+#: builtin/commit.c:1309 builtin/commit.c:1484
 msgid "compute full ahead/behind values"
 msgstr "calcule les valeurs complètes en avance/en retard"
 
-#: builtin/commit.c:1286
+#: builtin/commit.c:1311
 msgid "version"
 msgstr "version"
 
-#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542
-#: builtin/worktree.c:541
+#: builtin/commit.c:1311 builtin/commit.c:1486 builtin/push.c:558
+#: builtin/worktree.c:581
 msgid "machine-readable output"
 msgstr "sortie pour traitement automatique"
 
-#: builtin/commit.c:1289 builtin/commit.c:1451
+#: builtin/commit.c:1314 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "afficher l'état en format long (par défaut)"
 
-#: builtin/commit.c:1292 builtin/commit.c:1454
+#: builtin/commit.c:1317 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "terminer les éléments par NUL"
 
-#: builtin/commit.c:1294 builtin/commit.c:1298 builtin/commit.c:1457
-#: builtin/fast-export.c:999 builtin/fast-export.c:1002 builtin/tag.c:396
+#: builtin/commit.c:1319 builtin/commit.c:1323 builtin/commit.c:1494
+#: builtin/fast-export.c:1001 builtin/fast-export.c:1004 builtin/tag.c:397
 msgid "mode"
 msgstr "mode"
 
-#: builtin/commit.c:1295 builtin/commit.c:1457
+#: builtin/commit.c:1320 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
 "afficher les fichiers non suivis, \"mode\" facultatif : all (tous), normal, "
 "no. (Défaut : all)"
 
-#: builtin/commit.c:1299
+#: builtin/commit.c:1324
 msgid ""
 "show ignored files, optional modes: traditional, matching, no. (Default: "
 "traditional)"
@@ -7814,11 +8222,11 @@ msgstr ""
 "afficher les fichiers ignorés, \"mode\" facultatif : traditional "
 "(traditionnel), matching (correspondant), no. (Défaut : traditional)"
 
-#: builtin/commit.c:1301 parse-options.h:167
+#: builtin/commit.c:1326 parse-options.h:167
 msgid "when"
 msgstr "quand"
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1327
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
@@ -7826,187 +8234,197 @@ msgstr ""
 "ignorer les modifications dans les sous-modules, \"quand\" facultatif : all "
 "(tous), dirty (sale), untracked (non suivi). (Défaut : all)"
 
-#: builtin/commit.c:1304
+#: builtin/commit.c:1329
 msgid "list untracked files in columns"
 msgstr "afficher les fichiers non suivis en colonnes"
 
-#: builtin/commit.c:1323
+#: builtin/commit.c:1330
+msgid "do not detect renames"
+msgstr "ne pas détecter les renommages"
+
+#: builtin/commit.c:1332
+msgid "detect renames, optionally set similarity index"
+msgstr ""
+"détecter les renommages, en spécifiant optionnellement le facteur de "
+"similarité"
+
+#: builtin/commit.c:1352
 msgid "Unsupported combination of ignored and untracked-files arguments"
 msgstr ""
 "Combinaison non supportée d'arguments sur les fichiers ignorés et non-suivis"
 
-#: builtin/commit.c:1413
+#: builtin/commit.c:1450
 msgid "suppress summary after successful commit"
 msgstr "supprimer le résumé après une validation réussie"
 
-#: builtin/commit.c:1414
+#: builtin/commit.c:1451
 msgid "show diff in commit message template"
 msgstr "afficher les diff dans le modèle de message de validation"
 
-#: builtin/commit.c:1416
+#: builtin/commit.c:1453
 msgid "Commit message options"
 msgstr "Options du message de validation"
 
-#: builtin/commit.c:1417 builtin/tag.c:393
+#: builtin/commit.c:1454 builtin/tag.c:394
 msgid "read message from file"
 msgstr "lire le message depuis un fichier"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "author"
 msgstr "auteur"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "override author for commit"
 msgstr "remplacer l'auteur pour la validation"
 
-#: builtin/commit.c:1419 builtin/gc.c:359
+#: builtin/commit.c:1456 builtin/gc.c:501
 msgid "date"
 msgstr "date"
 
-#: builtin/commit.c:1419
+#: builtin/commit.c:1456
 msgid "override date for commit"
 msgstr "remplacer la date pour la validation"
 
-#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402
-#: builtin/notes.c:565 builtin/tag.c:391
+#: builtin/commit.c:1457 builtin/merge.c:228 builtin/notes.c:402
+#: builtin/notes.c:565 builtin/tag.c:392
 msgid "message"
 msgstr "message"
 
-#: builtin/commit.c:1420
+#: builtin/commit.c:1457
 msgid "commit message"
 msgstr "message de validation"
 
-#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423
-#: builtin/commit.c:1424 parse-options.h:269 ref-filter.h:92
+#: builtin/commit.c:1458 builtin/commit.c:1459 builtin/commit.c:1460
+#: builtin/commit.c:1461 parse-options.h:270 ref-filter.h:92
 msgid "commit"
 msgstr "commit"
 
-#: builtin/commit.c:1421
+#: builtin/commit.c:1458
 msgid "reuse and edit message from specified commit"
 msgstr "réutiliser et éditer le message du commit spécifié"
 
-#: builtin/commit.c:1422
+#: builtin/commit.c:1459
 msgid "reuse message from specified commit"
 msgstr "réutiliser le message du commit spécifié"
 
-#: builtin/commit.c:1423
+#: builtin/commit.c:1460
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
 "utiliser un message au format autosquash pour corriger le commit spécifié"
 
-#: builtin/commit.c:1424
+#: builtin/commit.c:1461
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
 "utiliser un message au format autosquash pour compresser le commit spécifié"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1462
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr ""
 "à présent je suis l'auteur de la validation (utilisé avec -C/-c/--amend)"
 
-#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240
-#: builtin/pull.c:149 builtin/revert.c:105
+#: builtin/commit.c:1463 builtin/log.c:1446 builtin/merge.c:242
+#: builtin/pull.c:154 builtin/revert.c:105
 msgid "add Signed-off-by:"
 msgstr "ajouter une entrée Signed-off-by :"
 
-#: builtin/commit.c:1427
+#: builtin/commit.c:1464
 msgid "use specified template file"
 msgstr "utiliser le fichier de modèle spécifié"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1465
 msgid "force edit of commit"
 msgstr "forcer l'édition du commit"
 
-#: builtin/commit.c:1429
+#: builtin/commit.c:1466
 msgid "default"
 msgstr "défaut"
 
-#: builtin/commit.c:1429 builtin/tag.c:397
+#: builtin/commit.c:1466 builtin/tag.c:398
 msgid "how to strip spaces and #comments from message"
 msgstr "comment éliminer les espaces et les commentaires # du message"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1467
 msgid "include status in commit message template"
 msgstr "inclure l'état dans le modèle de message de validation"
 
-#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179
+#: builtin/commit.c:1469 builtin/merge.c:240 builtin/pull.c:184
 #: builtin/revert.c:113
 msgid "GPG sign commit"
 msgstr "signer la validation avec GPG"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1472
 msgid "Commit contents options"
 msgstr "Valider les options des contenus"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1473
 msgid "commit all changed files"
 msgstr "valider tous les fichiers modifiés"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1474
 msgid "add specified files to index for commit"
 msgstr "ajouter les fichiers spécifiés à l'index pour la validation"
 
-#: builtin/commit.c:1438
+#: builtin/commit.c:1475
 msgid "interactively add files"
 msgstr "ajouter des fichiers en mode interactif"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1476
 msgid "interactively add changes"
 msgstr "ajouter les modifications en mode interactif"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1477
 msgid "commit only specified files"
 msgstr "valider seulement les fichiers spécifiés"
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1478
 msgid "bypass pre-commit and commit-msg hooks"
 msgstr "éviter d'utiliser les crochets pre-commit et commit-msg"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1479
 msgid "show what would be committed"
 msgstr "afficher ce qui serait validé"
 
-#: builtin/commit.c:1455
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "corriger la validation précédente"
 
-#: builtin/commit.c:1456
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "éviter d'utiliser le crochet post-rewrite"
 
-#: builtin/commit.c:1461
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "accepter d'enregistrer une modification vide"
 
-#: builtin/commit.c:1463
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "accepter d'enregistrer une modification avec un message vide"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1573
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Fichier MERGE_HEAD corrompu (%s)"
 
-#: builtin/commit.c:1543
+#: builtin/commit.c:1580
 msgid "could not read MERGE_MODE"
 msgstr "impossible de lire MERGE_MODE"
 
-#: builtin/commit.c:1562
+#: builtin/commit.c:1599
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "impossible de lire le message de validation : %s"
 
-#: builtin/commit.c:1573
+#: builtin/commit.c:1610
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "Abandon de la validation dû à un message de validation vide.\n"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1615
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "Abandon de la validation ; vous n'avez pas édité le message\n"
 
-#: builtin/commit.c:1613
+#: builtin/commit.c:1650
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full and quota is\n"
@@ -8016,150 +8434,215 @@ msgstr ""
 "new_index. Vérifiez que le disque n'est pas plein ou que le quota\n"
 "n'a pas été dépassé, puis lancez \"git reset HEAD\" pour réparer."
 
+#: builtin/commit-graph.c:9
+msgid "git commit-graph [--object-dir <objdir>]"
+msgstr "git commit-graph [--object-dir <objdir>]"
+
+#: builtin/commit-graph.c:10 builtin/commit-graph.c:16
+msgid "git commit-graph read [--object-dir <objdir>]"
+msgstr "git commit-graph read [--object-dir <objdir>]"
+
+#: builtin/commit-graph.c:11 builtin/commit-graph.c:21
+msgid ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+msgstr ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+
+#: builtin/commit-graph.c:39 builtin/commit-graph.c:92
+#: builtin/commit-graph.c:147 builtin/fetch.c:161 builtin/log.c:1466
+msgid "dir"
+msgstr "répertoire"
+
+#: builtin/commit-graph.c:40 builtin/commit-graph.c:93
+#: builtin/commit-graph.c:148
+msgid "The object directory to store the graph"
+msgstr "Le répertoire d'objet où stocker le graphe"
+
+#: builtin/commit-graph.c:95
+msgid "scan pack-indexes listed by stdin for commits"
+msgstr "scanner les index compactés listés sur stdin à la recherche de commits"
+
+#: builtin/commit-graph.c:97
+msgid "start walk at commits listed by stdin"
+msgstr "commencer le parcours aux commits listés sur stdin"
+
+#: builtin/commit-graph.c:99
+msgid "include all commits already in the commit-graph file"
+msgstr ""
+"inclure tous les commits déjà présents dans le fichier de graphe de commits"
+
+#: builtin/commit-graph.c:108
+msgid "cannot use both --stdin-commits and --stdin-packs"
+msgstr "impossible d'utiliser à la fois --stdin-commits et --stdin-packs"
+
 #: builtin/config.c:10
 msgid "git config [<options>]"
 msgstr "git config [<options>]"
 
-#: builtin/config.c:58
+#: builtin/config.c:101
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "argument --type non reconnu, %s"
+
+#: builtin/config.c:123
 msgid "Config file location"
 msgstr "Emplacement du fichier de configuration"
 
-#: builtin/config.c:59
+#: builtin/config.c:124
 msgid "use global config file"
 msgstr "utiliser les fichier de configuration global"
 
-#: builtin/config.c:60
+#: builtin/config.c:125
 msgid "use system config file"
 msgstr "utiliser le fichier de configuration du système"
 
-#: builtin/config.c:61
+#: builtin/config.c:126
 msgid "use repository config file"
 msgstr "utiliser le fichier de configuration du dépôt"
 
-#: builtin/config.c:62
+#: builtin/config.c:127
 msgid "use given config file"
 msgstr "utiliser le fichier de configuration spécifié"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "blob-id"
 msgstr "blob-id"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "read config from given blob object"
 msgstr "lire la configuration depuis l'objet blob fourni"
 
-#: builtin/config.c:64
+#: builtin/config.c:129
 msgid "Action"
 msgstr "Action"
 
-#: builtin/config.c:65
+#: builtin/config.c:130
 msgid "get value: name [value-regex]"
 msgstr "obtenir la valeur : nom [regex-de-valeur]"
 
-#: builtin/config.c:66
+#: builtin/config.c:131
 msgid "get all values: key [value-regex]"
 msgstr "obtenir toutes les valeurs : clé [regex-de-valeur]"
 
-#: builtin/config.c:67
+#: builtin/config.c:132
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr "obtenir les valeur pour la regexp : regex-de-nom [regex-de-valeur]"
 
-#: builtin/config.c:68
+#: builtin/config.c:133
 msgid "get value specific for the URL: section[.var] URL"
 msgstr "obtenir la valeur spécifique pour l'URL : section[.var] URL"
 
-#: builtin/config.c:69
+#: builtin/config.c:134
 msgid "replace all matching variables: name value [value_regex]"
 msgstr ""
 "remplacer toutes les variables correspondant : nom valeur [regex-de-valeur]"
 
-#: builtin/config.c:70
+#: builtin/config.c:135
 msgid "add a new variable: name value"
 msgstr "ajouter une nouvelle variable : nom valeur"
 
-#: builtin/config.c:71
+#: builtin/config.c:136
 msgid "remove a variable: name [value-regex]"
 msgstr "supprimer une variable : nom [regex-de-valeur]"
 
-#: builtin/config.c:72
+#: builtin/config.c:137
 msgid "remove all matches: name [value-regex]"
 msgstr "supprimer toutes les correspondances nom [regex-de-valeur]"
 
-#: builtin/config.c:73
+#: builtin/config.c:138
 msgid "rename section: old-name new-name"
 msgstr "renommer une section : ancien-nom nouveau-nom"
 
-#: builtin/config.c:74
+#: builtin/config.c:139
 msgid "remove a section: name"
 msgstr "supprimer une section : nom"
 
-#: builtin/config.c:75
+#: builtin/config.c:140
 msgid "list all"
 msgstr "afficher tout"
 
-#: builtin/config.c:76
+#: builtin/config.c:141
 msgid "open an editor"
 msgstr "ouvrir un éditeur"
 
-#: builtin/config.c:77
+#: builtin/config.c:142
 msgid "find the color configured: slot [default]"
 msgstr "trouver la couleur configurée : slot [par défaut]"
 
-#: builtin/config.c:78
+#: builtin/config.c:143
 msgid "find the color setting: slot [stdout-is-tty]"
 msgstr "trouver le réglage de la couleur : slot [stdout-est-tty]"
 
-#: builtin/config.c:79
+#: builtin/config.c:144
 msgid "Type"
 msgstr "Type"
 
-#: builtin/config.c:80
+#: builtin/config.c:145
+msgid "value is given this type"
+msgstr "ce type est assigné à la valeur"
+
+#: builtin/config.c:146
 msgid "value is \"true\" or \"false\""
 msgstr "la valeur est \"true\" (vrai) ou \"false\" (faux)"
 
-#: builtin/config.c:81
+#: builtin/config.c:147
 msgid "value is decimal number"
 msgstr "la valeur est un nombre décimal"
 
-#: builtin/config.c:82
+#: builtin/config.c:148
 msgid "value is --bool or --int"
 msgstr "la valeur est --bool ou --int"
 
-#: builtin/config.c:83
+#: builtin/config.c:149
 msgid "value is a path (file or directory name)"
 msgstr "la valeur est un chemin (vers un fichier ou un répertoire)"
 
-#: builtin/config.c:84
+#: builtin/config.c:150
 msgid "value is an expiry date"
 msgstr "la valeur est une date d'expiration"
 
-#: builtin/config.c:85
+#: builtin/config.c:151
 msgid "Other"
 msgstr "Autre"
 
-#: builtin/config.c:86
+#: builtin/config.c:152
 msgid "terminate values with NUL byte"
 msgstr "terminer les valeurs avec un caractère NUL"
 
-#: builtin/config.c:87
+#: builtin/config.c:153
 msgid "show variable names only"
 msgstr "n'afficher que les noms de variable"
 
-#: builtin/config.c:88
+#: builtin/config.c:154
 msgid "respect include directives on lookup"
 msgstr "respecter les directives d'inclusion lors de la recherche"
 
-#: builtin/config.c:89
+#: builtin/config.c:155
 msgid "show origin of config (file, standard input, blob, command line)"
 msgstr ""
 "afficher l'origine de la configuration (fichier, entrée standard, blob, "
 "ligne de commande)"
 
-#: builtin/config.c:335
+#: builtin/config.c:156
+msgid "value"
+msgstr "valeur"
+
+#: builtin/config.c:156
+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"
+
+#: builtin/config.c:332
+#, c-format
+msgid "failed to format default config value: %s"
+msgstr "échec du formatage de la valeur de config par défaut : %s"
+
+#: builtin/config.c:431
 msgid "unable to parse default color value"
 msgstr "impossible de lire la valeur de couleur par défaut"
 
-#: builtin/config.c:479
+#: builtin/config.c:575
 #, c-format
 msgid ""
 "# This is Git's per-user configuration file.\n"
@@ -8174,16 +8657,20 @@ msgstr ""
 "#\tname = %s\n"
 "#\temail = %s\n"
 
-#: builtin/config.c:507
+#: builtin/config.c:603
 msgid "--local can only be used inside a git repository"
 msgstr "--local ne peut être utilisé qu'à l'intérieur d'un dépôt git"
 
-#: builtin/config.c:632
+#: builtin/config.c:606
+msgid "--blob can only be used inside a git repository"
+msgstr "--blob ne peut être utilisé qu'à l'intérieur d'un dépôt git"
+
+#: builtin/config.c:735
 #, c-format
 msgid "cannot create configuration file %s"
 msgstr "création impossible du fichier de configuration '%s'"
 
-#: builtin/config.c:645
+#: builtin/config.c:748
 #, c-format
 msgid ""
 "cannot overwrite multiple values with a single value\n"
@@ -8192,11 +8679,11 @@ msgstr ""
 "impossible de surcharger des valeurs multiples avec une seule valeur\n"
 "       Utilisez une regexp, --add ou --replace-all pour modifier %s."
 
-#: builtin/count-objects.c:88
+#: builtin/count-objects.c:90
 msgid "git count-objects [-v] [-H | --human-readable]"
 msgstr "git count-objects [-v] [-H | --human-readable]"
 
-#: builtin/count-objects.c:98
+#: builtin/count-objects.c:100
 msgid "print sizes in human readable format"
 msgstr "affiche les tailles dans un format humainement lisible"
 
@@ -8465,23 +8952,23 @@ msgstr "réalise un diff de répertoire complet"
 msgid "do not prompt before launching a diff tool"
 msgstr "ne pas confirmer avant de lancer l'outil de diff"
 
-#: builtin/difftool.c:705
+#: builtin/difftool.c:704
 msgid "use symlinks in dir-diff mode"
 msgstr "utiliser les liens symboliques en mode de diff de répertoire"
 
-#: builtin/difftool.c:706
+#: builtin/difftool.c:705
 msgid "<tool>"
 msgstr "<outil>"
 
-#: builtin/difftool.c:707
+#: builtin/difftool.c:706
 msgid "use the specified diff tool"
 msgstr "utiliser l'outil de diff spécifié"
 
-#: builtin/difftool.c:709
+#: builtin/difftool.c:708
 msgid "print a list of diff tools that may be used with `--tool`"
 msgstr "afficher une liste des outils de diff utilisables avec `--tool`"
 
-#: builtin/difftool.c:712
+#: builtin/difftool.c:711
 msgid ""
 "make 'git-difftool' exit when an invoked diff tool returns a non - zero exit "
 "code"
@@ -8489,170 +8976,168 @@ msgstr ""
 "provoque la fin de 'git-difftool' si l'outil de diff invoqué renvoie un code "
 "non-nul"
 
-#: builtin/difftool.c:714
+#: builtin/difftool.c:713
 msgid "<command>"
 msgstr "<commande>"
 
-#: builtin/difftool.c:715
+#: builtin/difftool.c:714
 msgid "specify a custom command for viewing diffs"
 msgstr "spécifier une commande personnalisée pour visualiser les différences"
 
-#: builtin/difftool.c:739
+#: builtin/difftool.c:738
 msgid "no <tool> given for --tool=<tool>"
 msgstr "pas d'<outil> spécifié pour --tool=<outil>"
 
-#: builtin/difftool.c:746
+#: builtin/difftool.c:745
 msgid "no <cmd> given for --extcmd=<cmd>"
 msgstr "pas de <commande> spécifié pour --extcmd=<commande>"
 
-#: builtin/fast-export.c:26
+#: builtin/fast-export.c:27
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [options-de-liste-de-révisions]"
 
-#: builtin/fast-export.c:998
+#: builtin/fast-export.c:1000
 msgid "show progress after <n> objects"
 msgstr "afficher la progression après <n> objets"
 
-#: builtin/fast-export.c:1000
+#: builtin/fast-export.c:1002
 msgid "select handling of signed tags"
 msgstr "sélectionner la gestion des étiquettes signées"
 
-#: builtin/fast-export.c:1003
+#: builtin/fast-export.c:1005
 msgid "select handling of tags that tag filtered objects"
 msgstr ""
 "sélectionner la gestion des étiquettes qui pointent sur des objets filtrés"
 
-#: builtin/fast-export.c:1006
+#: builtin/fast-export.c:1008
 msgid "Dump marks to this file"
 msgstr "Enregistrer les marques dans ce fichier"
 
-#: builtin/fast-export.c:1008
+#: builtin/fast-export.c:1010
 msgid "Import marks from this file"
 msgstr "importer les marques depuis ce fichier"
 
-#: builtin/fast-export.c:1010
+#: builtin/fast-export.c:1012
 msgid "Fake a tagger when tags lack one"
 msgstr "falsifier un auteur d'étiquette si l'étiquette n'en présente pas"
 
-#: builtin/fast-export.c:1012
+#: builtin/fast-export.c:1014
 msgid "Output full tree for each commit"
 msgstr "Afficher l'arbre complet pour chaque commit"
 
-#: builtin/fast-export.c:1014
+#: builtin/fast-export.c:1016
 msgid "Use the done feature to terminate the stream"
 msgstr "Utiliser la fonction \"done\" pour terminer le flux"
 
-#: builtin/fast-export.c:1015
+#: builtin/fast-export.c:1017
 msgid "Skip output of blob data"
 msgstr "Sauter l'affichage de données de blob"
 
-#: builtin/fast-export.c:1016
+#: builtin/fast-export.c:1018
 msgid "refspec"
 msgstr "spécificateur de référence"
 
-#: builtin/fast-export.c:1017
+#: builtin/fast-export.c:1019
 msgid "Apply refspec to exported refs"
 msgstr "Appliquer le spécificateur de référence aux références exportées"
 
-#: builtin/fast-export.c:1018
+#: builtin/fast-export.c:1020
 msgid "anonymize output"
 msgstr "anonymise la sortie"
 
-#: builtin/fetch.c:25
+#: builtin/fetch.c:26
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
 msgstr "git fetch [<options>] [<dépôt> [<spécification-de-référence>...]]"
 
-#: builtin/fetch.c:26
+#: builtin/fetch.c:27
 msgid "git fetch [<options>] <group>"
 msgstr "git fetch [<options>] <groupe>"
 
-#: builtin/fetch.c:27
+#: builtin/fetch.c:28
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
 msgstr "git fetch --multiple [<options>] [(<dépôt> | <groupe>)...]"
 
-#: builtin/fetch.c:28
+#: builtin/fetch.c:29
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<options>]"
 
-#: builtin/fetch.c:124 builtin/pull.c:188
+#: builtin/fetch.c:123 builtin/pull.c:193
 msgid "fetch from all remotes"
 msgstr "récupérer depuis tous les dépôts distants"
 
-#: builtin/fetch.c:126 builtin/pull.c:191
+#: builtin/fetch.c:125 builtin/pull.c:196
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "ajouter à .git/FETCH_HEAD au lieu de l'écraser"
 
-#: builtin/fetch.c:128 builtin/pull.c:194
+#: builtin/fetch.c:127 builtin/pull.c:199
 msgid "path to upload pack on remote end"
 msgstr "chemin vers lequel télécharger le paquet sur le poste distant"
 
-#: builtin/fetch.c:129 builtin/pull.c:196
+#: builtin/fetch.c:128 builtin/pull.c:201
 msgid "force overwrite of local branch"
 msgstr "forcer l'écrasement de la branche locale"
 
-#: builtin/fetch.c:131
+#: builtin/fetch.c:130
 msgid "fetch from multiple remotes"
 msgstr "récupérer depuis plusieurs dépôts distants"
 
-#: builtin/fetch.c:133 builtin/pull.c:198
+#: builtin/fetch.c:132 builtin/pull.c:203
 msgid "fetch all tags and associated objects"
 msgstr "récupérer toutes les étiquettes et leurs objets associés"
 
-#: builtin/fetch.c:135
+#: builtin/fetch.c:134
 msgid "do not fetch all tags (--no-tags)"
 msgstr "ne pas récupérer toutes les étiquettes (--no-tags)"
 
-#: builtin/fetch.c:137
+#: builtin/fetch.c:136
 msgid "number of submodules fetched in parallel"
 msgstr "nombre de sous-modules récupérés en parallèle"
 
-#: builtin/fetch.c:139 builtin/pull.c:201
+#: builtin/fetch.c:138 builtin/pull.c:206
 msgid "prune remote-tracking branches no longer on remote"
 msgstr ""
 "éliminer les branches de suivi distant si la branche n'existe plus dans le "
 "dépôt distant"
 
-#: builtin/fetch.c:141
+#: builtin/fetch.c:140
 msgid "prune local tags no longer on remote and clobber changed tags"
-msgstr "éliminer les étiquettes locales qui ont disparu du dépôt distant et qui encombrent les étiquettes modifiées"
+msgstr ""
+"éliminer les étiquettes locales qui ont disparu du dépôt distant et qui "
+"encombrent les étiquettes modifiées"
 
-#: builtin/fetch.c:142 builtin/fetch.c:165 builtin/pull.c:126
+#: builtin/fetch.c:141 builtin/fetch.c:164 builtin/pull.c:131
 msgid "on-demand"
 msgstr "à la demande"
 
-#: builtin/fetch.c:143
+#: builtin/fetch.c:142
 msgid "control recursive fetching of submodules"
 msgstr "contrôler la récupération récursive dans les sous-modules"
 
-#: builtin/fetch.c:147 builtin/pull.c:209
+#: builtin/fetch.c:146 builtin/pull.c:214
 msgid "keep downloaded pack"
 msgstr "conserver le paquet téléchargé"
 
-#: builtin/fetch.c:149
+#: builtin/fetch.c:148
 msgid "allow updating of HEAD ref"
 msgstr "permettre la mise à jour de la référence HEAD"
 
-#: builtin/fetch.c:152 builtin/fetch.c:158 builtin/pull.c:212
+#: builtin/fetch.c:151 builtin/fetch.c:157 builtin/pull.c:217
 msgid "deepen history of shallow clone"
 msgstr "approfondir l'historique d'un clone superficiel"
 
-#: builtin/fetch.c:154
+#: builtin/fetch.c:153
 msgid "deepen history of shallow repository based on time"
 msgstr "approfondir l'historique d'un clone superficiel en fonction d'une date"
 
-#: builtin/fetch.c:160 builtin/pull.c:215
+#: builtin/fetch.c:159 builtin/pull.c:220
 msgid "convert to a complete repository"
 msgstr "convertir en un dépôt complet"
 
-#: builtin/fetch.c:162 builtin/log.c:1466
-msgid "dir"
-msgstr "répertoire"
-
-#: builtin/fetch.c:163
+#: builtin/fetch.c:162
 msgid "prepend this to submodule path output"
 msgstr "préfixer ceci à la sortie du chemin du sous-module"
 
-#: builtin/fetch.c:166
+#: builtin/fetch.c:165
 msgid ""
 "default for recursive fetching of submodules (lower priority than config "
 "files)"
@@ -8660,91 +9145,101 @@ msgstr ""
 "par défaut pour la récupération récursive de sous-modules (priorité plus "
 "basse que les fichiers de config)"
 
-#: builtin/fetch.c:170 builtin/pull.c:218
+#: builtin/fetch.c:169 builtin/pull.c:223
 msgid "accept refs that update .git/shallow"
 msgstr "accepter les références qui mettent à jour .git/shallow"
 
-#: builtin/fetch.c:171 builtin/pull.c:220
+#: builtin/fetch.c:170 builtin/pull.c:225
 msgid "refmap"
 msgstr "correspondance de référence"
 
-#: builtin/fetch.c:172 builtin/pull.c:221
+#: builtin/fetch.c:171 builtin/pull.c:226
 msgid "specify fetch refmap"
 msgstr "spécifier une correspondance de référence pour la récupération"
 
-#: builtin/fetch.c:431
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:172
+msgid "server-specific"
+msgstr "spécifique au serveur"
+
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:173
+msgid "option to transmit"
+msgstr "option à transmettre"
+
+#: builtin/fetch.c:442
 msgid "Couldn't find remote ref HEAD"
 msgstr "impossible de trouver la référence HEAD distante"
 
-#: builtin/fetch.c:549
+#: builtin/fetch.c:560
 #, c-format
 msgid "configuration fetch.output contains invalid value %s"
 msgstr ""
 "le paramètre de configuration fetch.output contient une valeur invalide %s"
 
-#: builtin/fetch.c:642
+#: builtin/fetch.c:653
 #, c-format
 msgid "object %s not found"
 msgstr "objet %s non trouvé"
 
-#: builtin/fetch.c:646
+#: builtin/fetch.c:657
 msgid "[up to date]"
 msgstr "[à jour]"
 
-#: builtin/fetch.c:659 builtin/fetch.c:739
+#: builtin/fetch.c:670 builtin/fetch.c:750
 msgid "[rejected]"
 msgstr "[rejeté]"
 
-#: builtin/fetch.c:660
+#: builtin/fetch.c:671
 msgid "can't fetch in current branch"
 msgstr "impossible de récupérer dans la branche actuelle"
 
-#: builtin/fetch.c:669
+#: builtin/fetch.c:680
 msgid "[tag update]"
 msgstr "[mise à jour de l'étiquette]"
 
-#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719
-#: builtin/fetch.c:734
+#: builtin/fetch.c:681 builtin/fetch.c:714 builtin/fetch.c:730
+#: builtin/fetch.c:745
 msgid "unable to update local ref"
 msgstr "impossible de mettre à jour la référence locale"
 
-#: builtin/fetch.c:689
+#: builtin/fetch.c:700
 msgid "[new tag]"
 msgstr "[nouvelle étiquette]"
 
-#: builtin/fetch.c:692
+#: builtin/fetch.c:703
 msgid "[new branch]"
 msgstr "[nouvelle branche]"
 
-#: builtin/fetch.c:695
+#: builtin/fetch.c:706
 msgid "[new ref]"
 msgstr "[nouvelle référence]"
 
-#: builtin/fetch.c:734
+#: builtin/fetch.c:745
 msgid "forced update"
 msgstr "mise à jour forcée"
 
-#: builtin/fetch.c:739
+#: builtin/fetch.c:750
 msgid "non-fast-forward"
 msgstr "pas en avance rapide"
 
-#: builtin/fetch.c:784
+#: builtin/fetch.c:795
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "%s n'a pas envoyé tous les objets nécessaires\n"
 
-#: builtin/fetch.c:804
+#: builtin/fetch.c:815
 #, c-format
 msgid "reject %s because shallow roots are not allowed to be updated"
 msgstr ""
 "%s rejeté parce que les racines superficielles ne sont pas mises à jour"
 
-#: builtin/fetch.c:892 builtin/fetch.c:988
+#: builtin/fetch.c:903 builtin/fetch.c:999
 #, c-format
 msgid "From %.*s\n"
 msgstr "Depuis %.*s\n"
 
-#: builtin/fetch.c:903
+#: builtin/fetch.c:914
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -8753,55 +9248,57 @@ msgstr ""
 "des références locales n'ont pas pu être mises à jour ; essayez de lancer\n"
 " 'git remote prune %s' pour supprimer des branches anciennes en conflit"
 
-#: builtin/fetch.c:958
+#: builtin/fetch.c:969
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (%s sera en suspens)"
 
-#: builtin/fetch.c:959
+#: builtin/fetch.c:970
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (%s est devenu en suspens)"
 
-#: builtin/fetch.c:991
+#: builtin/fetch.c:1002
 msgid "[deleted]"
 msgstr "[supprimé]"
 
-#: builtin/fetch.c:992 builtin/remote.c:1024
+#: builtin/fetch.c:1003 builtin/remote.c:1033
 msgid "(none)"
 msgstr "(aucun(e))"
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1026
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr "Refus de récupérer dans la branche courant %s d'un dépôt non nu"
 
-#: builtin/fetch.c:1034
+#: builtin/fetch.c:1045
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr "La valeur \"%2$s\" de l'option \"%1$s\" est invalide pour %3$s"
 
-#: builtin/fetch.c:1037
+#: builtin/fetch.c:1048
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "L'option \"%s\" est ignorée pour %s\n"
 
-#: builtin/fetch.c:1277
+#: builtin/fetch.c:1287
 #, c-format
 msgid "Fetching %s\n"
 msgstr "Récupération de %s\n"
 
-#: builtin/fetch.c:1279 builtin/remote.c:97
+#: builtin/fetch.c:1289 builtin/remote.c:98
 #, c-format
 msgid "Could not fetch %s"
 msgstr "Impossible de récupérer %s"
 
-#: builtin/fetch.c:1325 builtin/fetch.c:1498
+#: builtin/fetch.c:1335 builtin/fetch.c:1503
 msgid ""
 "--filter can only be used with the remote configured in core.partialClone"
-msgstr "--filter ne peut être utilisé qu'avec le dépôt distant configuré dans core.partialClone"
+msgstr ""
+"--filter ne peut être utilisé qu'avec le dépôt distant configuré dans core."
+"partialClone"
 
-#: builtin/fetch.c:1350
+#: builtin/fetch.c:1358
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
@@ -8809,40 +9306,40 @@ msgstr ""
 "Aucun dépôt distant spécifié. Veuillez spécifier une URL ou un nom\n"
 "distant depuis lesquels les nouvelles révisions devraient être récupérées."
 
-#: builtin/fetch.c:1394
+#: builtin/fetch.c:1395
 msgid "You need to specify a tag name."
 msgstr "Vous devez spécifier un nom d'étiquette."
 
-#: builtin/fetch.c:1439
+#: builtin/fetch.c:1444
 msgid "Negative depth in --deepen is not supported"
 msgstr "Une profondeur négative dans --deepen n'est pas supportée"
 
-#: builtin/fetch.c:1441
+#: builtin/fetch.c:1446
 msgid "--deepen and --depth are mutually exclusive"
 msgstr "--deepen et --depth sont mutuellement exclusifs"
 
-#: builtin/fetch.c:1446
+#: builtin/fetch.c:1451
 msgid "--depth and --unshallow cannot be used together"
 msgstr "--depth et --unshallow ne peuvent pas être utilisés ensemble"
 
-#: builtin/fetch.c:1448
+#: builtin/fetch.c:1453
 msgid "--unshallow on a complete repository does not make sense"
 msgstr "--unshallow sur un dépôt complet n'a pas de sens"
 
-#: builtin/fetch.c:1464
+#: builtin/fetch.c:1469
 msgid "fetch --all does not take a repository argument"
 msgstr "fetch --all n'accepte pas d'argument de dépôt"
 
-#: builtin/fetch.c:1466
+#: builtin/fetch.c:1471
 msgid "fetch --all does not make sense with refspecs"
 msgstr "fetch --all n'a pas de sens avec des spécifications de référence"
 
-#: builtin/fetch.c:1475
+#: builtin/fetch.c:1480
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "distant ou groupe distant inexistant : %s"
 
-#: builtin/fetch.c:1482
+#: builtin/fetch.c:1487
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr ""
 "La récupération d'un groupe et les spécifications de référence n'ont pas de "
@@ -8910,7 +9407,7 @@ msgstr "échapper les champs réservés pour compatibilité avec Tcl"
 msgid "show only <n> matched refs"
 msgstr "n'afficher que <n> références correspondant"
 
-#: builtin/for-each-ref.c:39 builtin/tag.c:420
+#: builtin/for-each-ref.c:39 builtin/tag.c:421
 msgid "respect format colors"
 msgstr "respecter les couleurs de formatage"
 
@@ -8934,82 +9431,82 @@ msgstr "afficher seulement les références qui contiennent le commit"
 msgid "print only refs which don't contain the commit"
 msgstr "afficher seulement les références qui ne contiennent pas le commit"
 
-#: builtin/fsck.c:568
+#: builtin/fsck.c:569
 msgid "Checking object directories"
 msgstr "Vérification des répertoires d'objet"
 
-#: builtin/fsck.c:660
+#: builtin/fsck.c:661
 msgid "git fsck [<options>] [<object>...]"
 msgstr "git fsck [<options>] [<objet>...]"
 
-#: builtin/fsck.c:666
+#: builtin/fsck.c:667
 msgid "show unreachable objects"
 msgstr "afficher les objets inaccessibles"
 
-#: builtin/fsck.c:667
+#: builtin/fsck.c:668
 msgid "show dangling objects"
 msgstr "afficher les objets en suspens"
 
-#: builtin/fsck.c:668
+#: builtin/fsck.c:669
 msgid "report tags"
 msgstr "afficher les étiquettes"
 
-#: builtin/fsck.c:669
+#: builtin/fsck.c:670
 msgid "report root nodes"
 msgstr "signaler les nœuds racines"
 
-#: builtin/fsck.c:670
+#: builtin/fsck.c:671
 msgid "make index objects head nodes"
 msgstr "considérer les objets de l'index comme nœuds tête"
 
 # translated from man page
-#: builtin/fsck.c:671
+#: builtin/fsck.c:672
 msgid "make reflogs head nodes (default)"
 msgstr "considérer les reflogs comme nœuds tête (par défaut)"
 
-#: builtin/fsck.c:672
+#: builtin/fsck.c:673
 msgid "also consider packs and alternate objects"
 msgstr "inspecter aussi les objets pack et alternatifs"
 
-#: builtin/fsck.c:673
+#: builtin/fsck.c:674
 msgid "check only connectivity"
 msgstr "ne vérifier que la connectivité"
 
-#: builtin/fsck.c:674
+#: builtin/fsck.c:675
 msgid "enable more strict checking"
 msgstr "activer une vérification plus strict"
 
-#: builtin/fsck.c:676
+#: builtin/fsck.c:677
 msgid "write dangling objects in .git/lost-found"
 msgstr "écrire les objets en suspens dans .git/lost-found"
 
-#: builtin/fsck.c:677 builtin/prune.c:108
+#: builtin/fsck.c:678 builtin/prune.c:109
 msgid "show progress"
 msgstr "afficher la progression"
 
-#: builtin/fsck.c:678
+#: builtin/fsck.c:679
 msgid "show verbose names for reachable objects"
 msgstr "afficher les noms étendus pour les objets inaccessibles"
 
-#: builtin/fsck.c:742
+#: builtin/fsck.c:745
 msgid "Checking objects"
 msgstr "Vérification des objets"
 
-#: builtin/gc.c:27
+#: builtin/gc.c:33
 msgid "git gc [<options>]"
 msgstr "git gc [<options>]"
 
-#: builtin/gc.c:80
+#: builtin/gc.c:88
 #, c-format
 msgid "Failed to fstat %s: %s"
 msgstr "Échec du stat de %s : %s"
 
-#: builtin/gc.c:312
+#: builtin/gc.c:452
 #, c-format
 msgid "Can't stat %s"
 msgstr "impossible de faire un stat de %s"
 
-#: builtin/gc.c:321
+#: builtin/gc.c:461
 #, c-format
 msgid ""
 "The last gc run reported the following. Please correct the root cause\n"
@@ -9025,47 +9522,56 @@ msgstr ""
 "\n"
 "%s"
 
-#: builtin/gc.c:360
+#: builtin/gc.c:502
 msgid "prune unreferenced objects"
 msgstr "éliminer les objets non référencés"
 
-#: builtin/gc.c:362
+#: builtin/gc.c:504
 msgid "be more thorough (increased runtime)"
 msgstr "être plus consciencieux (durée de traitement allongée)"
 
-#: builtin/gc.c:363
+#: builtin/gc.c:505
 msgid "enable auto-gc mode"
 msgstr "activer le mode auto-gc"
 
-#: builtin/gc.c:366
+#: builtin/gc.c:508
 msgid "force running gc even if there may be another gc running"
 msgstr ""
 "forcer le lancement du ramasse-miettes même si un autre ramasse-miettes "
 "tourne déjà"
 
-#: builtin/gc.c:384
+#: builtin/gc.c:511
+msgid "repack all other packs except the largest pack"
+msgstr "recompacter tous les autres paquets excepté le plus gros paquet"
+
+#: builtin/gc.c:528
 #, c-format
-msgid "Failed to parse gc.logexpiry value %s"
-msgstr "impossible de lire la valeur de gc.logexpiry %s"
+msgid "failed to parse gc.logexpiry value %s"
+msgstr "impossible d'analyser gc.logexpiry %s"
 
-#: builtin/gc.c:412
+#: builtin/gc.c:539
+#, c-format
+msgid "failed to parse prune expiry value %s"
+msgstr "impossible d'analyser la valeur d'expiration d'élagage %s"
+
+#: builtin/gc.c:559
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
 msgstr ""
 "Compression automatique du dépôt en tâche de fond pour optimiser les "
 "performances.\n"
 
-#: builtin/gc.c:414
+#: builtin/gc.c:561
 #, c-format
 msgid "Auto packing the repository for optimum performance.\n"
 msgstr "Compression du dépôt pour optimiser les performances.\n"
 
-#: builtin/gc.c:415
+#: builtin/gc.c:562
 #, c-format
 msgid "See \"git help gc\" for manual housekeeping.\n"
 msgstr "Voir \"git help gc\" pour toute information sur le nettoyage manuel.\n"
 
-#: builtin/gc.c:440
+#: builtin/gc.c:598
 #, c-format
 msgid ""
 "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
@@ -9073,23 +9579,23 @@ msgstr ""
 "un ramasse-miettes est déjà en cours sur la machine '%s' pid %<PRIuMAX> "
 "(utilisez --force si ce n'est pas le cas)"
 
-#: builtin/gc.c:487
+#: builtin/gc.c:645
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
 "Il y a trop d'objets seuls inaccessibles ; lancez 'git prune' pour les "
 "supprimer."
 
-#: builtin/grep.c:27
+#: builtin/grep.c:28
 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [<options>] [-e] <motif> [<révision>...] [[--] <chemin>...]"
 
-#: builtin/grep.c:225
+#: builtin/grep.c:226
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep : échec de création du fil: %s"
 
-#: builtin/grep.c:283
+#: builtin/grep.c:284
 #, c-format
 msgid "invalid number of threads specified (%d) for %s"
 msgstr "nombre de fils spécifié invalide (%d) pour %s"
@@ -9098,17 +9604,17 @@ msgstr "nombre de fils spécifié invalide (%d) pour %s"
 #. variable for tweaking threads, currently
 #. grep.threads
 #.
-#: builtin/grep.c:292 builtin/index-pack.c:1523 builtin/index-pack.c:1712
+#: builtin/grep.c:293 builtin/index-pack.c:1535 builtin/index-pack.c:1727
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "pas de support des fils, ignore %s"
 
-#: builtin/grep.c:460 builtin/grep.c:580 builtin/grep.c:622
+#: builtin/grep.c:461 builtin/grep.c:582 builtin/grep.c:623
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "impossible de lire l'arbre (%s)"
 
-#: builtin/grep.c:637
+#: builtin/grep.c:638
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "impossible de faire un grep sur un objet de type %s"
@@ -9315,7 +9821,7 @@ msgstr ""
 msgid "unable to resolve revision: %s"
 msgstr "impossible de résoudre la révision : %s"
 
-#: builtin/grep.c:1036 builtin/index-pack.c:1519
+#: builtin/grep.c:1036 builtin/index-pack.c:1531
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "nombre de fils spécifié invalide (%d)"
@@ -9388,58 +9894,62 @@ msgstr ""
 msgid "process file as it were from this path"
 msgstr "traiter le fichier comme s'il venait de ce chemin"
 
-#: builtin/help.c:43
+#: builtin/help.c:45
 msgid "print all available commands"
 msgstr "afficher toutes les commandes disponibles"
 
-#: builtin/help.c:44
+#: builtin/help.c:46
 msgid "exclude guides"
 msgstr "exclure les guides"
 
-#: builtin/help.c:45
+#: builtin/help.c:47
 msgid "print list of useful guides"
 msgstr "afficher une liste de guides utiles"
 
-#: builtin/help.c:46
+#: builtin/help.c:48
 msgid "show man page"
 msgstr "afficher la page de manuel"
 
-#: builtin/help.c:47
+#: builtin/help.c:49
 msgid "show manual in web browser"
 msgstr "afficher le manuel dans un navigateur web"
 
-#: builtin/help.c:49
+#: builtin/help.c:51
 msgid "show info page"
 msgstr "afficher la page info"
 
-#: builtin/help.c:55
+#: builtin/help.c:53
+msgid "print command description"
+msgstr "afficher la description de la commande"
+
+#: builtin/help.c:58
 msgid "git help [--all] [--guides] [--man | --web | --info] [<command>]"
 msgstr "git help [--all] [--guides] [--man | --web | --info] [<commande>]"
 
-#: builtin/help.c:67
+#: builtin/help.c:70
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "format d'aide non reconnu '%s'"
 
-#: builtin/help.c:94
+#: builtin/help.c:97
 msgid "Failed to start emacsclient."
 msgstr "échec de démarrage d'emacsclient."
 
-#: builtin/help.c:107
+#: builtin/help.c:110
 msgid "Failed to parse emacsclient version."
 msgstr "échec d'analyse de la version d'emacsclient."
 
-#: builtin/help.c:115
+#: builtin/help.c:118
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "la version d'emacsclient '%d' est trop ancienne (<22)."
 
-#: builtin/help.c:133 builtin/help.c:155 builtin/help.c:165 builtin/help.c:173
+#: builtin/help.c:136 builtin/help.c:158 builtin/help.c:168 builtin/help.c:176
 #, c-format
 msgid "failed to exec '%s'"
 msgstr "échec de l'exécution de '%s'"
 
-#: builtin/help.c:211
+#: builtin/help.c:214
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -9448,7 +9958,7 @@ msgstr ""
 "'%s' : chemin pour l'utilitaire de visualisation de manuel non supporté.\n"
 "Veuillez utiliser plutôt 'man.<outil>.cmd'."
 
-#: builtin/help.c:223
+#: builtin/help.c:226
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -9457,360 +9967,327 @@ msgstr ""
 "'%s' : chemin pour l'utilitaire de visualisation de manuel supporté.\n"
 "Veuillez utiliser plutôt 'man.<outil>.cmd'."
 
-#: builtin/help.c:340
+#: builtin/help.c:343
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "'%s' : visualiseur de manuel inconnu."
 
-#: builtin/help.c:357
+#: builtin/help.c:360
 msgid "no man viewer handled the request"
 msgstr "aucun visualiseur de manuel n'a pris en charge la demande"
 
-#: builtin/help.c:365
+#: builtin/help.c:368
 msgid "no info viewer handled the request"
 msgstr "aucun visualiseur de 'info' n'a pris en charge la demande"
 
-#: builtin/help.c:407
-msgid "Defining attributes per path"
-msgstr "Définition des attributs par chemin"
-
-#: builtin/help.c:408
-msgid "Everyday Git With 20 Commands Or So"
-msgstr "Git de tous les jours avec à peu près 20 commandes"
-
-#: builtin/help.c:409
-msgid "A Git glossary"
-msgstr "Un glossaire Git"
-
-#: builtin/help.c:410
-msgid "Specifies intentionally untracked files to ignore"
-msgstr "Spécifie les fichiers non-suivis à ignorer intentionnellement"
-
-#: builtin/help.c:411
-msgid "Defining submodule properties"
-msgstr "Définition des propriétés de sous-module"
-
-#: builtin/help.c:412
-msgid "Specifying revisions and ranges for Git"
-msgstr "Spécification des révisions et portées pour Git"
-
-#: builtin/help.c:413
-msgid "A tutorial introduction to Git (for version 1.5.1 or newer)"
-msgstr ""
-"Une introduction pratique à Git (pour les versions 1.5.1 et supérieures)"
-
-#: builtin/help.c:414
-msgid "An overview of recommended workflows with Git"
-msgstr "Un aperçu des flux de travail recommandés avec Git"
-
-#: builtin/help.c:426
-msgid "The common Git guides are:\n"
-msgstr "Les guides Git populaires sont : \n"
-
-#: builtin/help.c:444
+#: builtin/help.c:415
 #, c-format
 msgid "'%s' is aliased to '%s'"
 msgstr "'%s' est un alias de '%s'"
 
-#: builtin/help.c:466 builtin/help.c:483
+#: builtin/help.c:442 builtin/help.c:459
 #, c-format
 msgid "usage: %s%s"
 msgstr "usage : %s%s"
 
-#: builtin/index-pack.c:157
+#: builtin/index-pack.c:158
 #, c-format
 msgid "unable to open %s"
 msgstr "impossible d'ouvrir %s"
 
-#: builtin/index-pack.c:207
+#: builtin/index-pack.c:208
 #, c-format
 msgid "object type mismatch at %s"
 msgstr "type d'objet non correspondant à %s"
 
-#: builtin/index-pack.c:227
+#: builtin/index-pack.c:228
 #, c-format
 msgid "did not receive expected object %s"
 msgstr "objet attendu non reçu %s"
 
-#: builtin/index-pack.c:230
+#: builtin/index-pack.c:231
 #, c-format
 msgid "object %s: expected type %s, found %s"
 msgstr "objet %s : type attendu %s, reçu %s"
 
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
 #, c-format
 msgid "cannot fill %d byte"
 msgid_plural "cannot fill %d bytes"
 msgstr[0] "impossible de remplir %d octet"
 msgstr[1] "impossible de remplir %d octets"
 
-#: builtin/index-pack.c:282
+#: builtin/index-pack.c:283
 msgid "early EOF"
 msgstr "fin de fichier prématurée"
 
-#: builtin/index-pack.c:283
+#: builtin/index-pack.c:284
 msgid "read error on input"
 msgstr "erreur de lecture sur l'entrée"
 
-#: builtin/index-pack.c:295
+#: builtin/index-pack.c:296
 msgid "used more bytes than were available"
 msgstr "plus d'octets utilisés que disponibles"
 
-#: builtin/index-pack.c:302
+#: builtin/index-pack.c:303
 msgid "pack too large for current definition of off_t"
 msgstr "le paquet est trop grand pour la définition actuelle de off_t"
 
-#: builtin/index-pack.c:305 builtin/unpack-objects.c:93
+#: builtin/index-pack.c:306 builtin/unpack-objects.c:93
 msgid "pack exceeds maximum allowed size"
 msgstr "le paquet dépasse la taille maximale permise"
 
-#: builtin/index-pack.c:320
+#: builtin/index-pack.c:321
 #, c-format
 msgid "unable to create '%s'"
 msgstr "impossible de créer '%s'"
 
-#: builtin/index-pack.c:326
+#: builtin/index-pack.c:327
 #, c-format
 msgid "cannot open packfile '%s'"
 msgstr "impossible d'ouvrir le fichier paquet '%s'"
 
-#: builtin/index-pack.c:340
+#: builtin/index-pack.c:341
 msgid "pack signature mismatch"
 msgstr "la signature du paquet ne correspond pas"
 
-#: builtin/index-pack.c:342
+#: builtin/index-pack.c:343
 #, c-format
 msgid "pack version %<PRIu32> unsupported"
 msgstr "la version de paquet %<PRIu32> non supportée"
 
-#: builtin/index-pack.c:360
+#: builtin/index-pack.c:361
 #, c-format
 msgid "pack has bad object at offset %<PRIuMAX>: %s"
 msgstr "le paquet a un mauvais objet à l'offset %<PRIuMAX> : %s"
 
-#: builtin/index-pack.c:481
+#: builtin/index-pack.c:482
 #, c-format
 msgid "inflate returned %d"
 msgstr "la décompression (inflate) a retourné %d"
 
-#: builtin/index-pack.c:530
+#: builtin/index-pack.c:531
 msgid "offset value overflow for delta base object"
 msgstr "dépassement de la valeur d'offset pour l'objet delta de base"
 
-#: builtin/index-pack.c:538
+#: builtin/index-pack.c:539
 msgid "delta base offset is out of bound"
 msgstr "l'objet delta de base est hors limite"
 
-#: builtin/index-pack.c:546
+#: builtin/index-pack.c:547
 #, c-format
 msgid "unknown object type %d"
 msgstr "type d'objet inconnu %d"
 
-#: builtin/index-pack.c:577
+#: builtin/index-pack.c:578
 msgid "cannot pread pack file"
 msgstr "impossible de lire (pread) le fichier paquet"
 
-#: builtin/index-pack.c:579
+#: builtin/index-pack.c:580
 #, c-format
 msgid "premature end of pack file, %<PRIuMAX> byte missing"
 msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
 msgstr[0] "fin prématurée du fichier paquet, %<PRIuMAX> octet lu"
 msgstr[1] "fin prématurée du fichier paquet, %<PRIuMAX> octets lus"
 
-#: builtin/index-pack.c:605
+#: builtin/index-pack.c:606
 msgid "serious inflate inconsistency"
 msgstr "grave incohérence dans la décompression (inflate)"
 
-#: builtin/index-pack.c:750 builtin/index-pack.c:756 builtin/index-pack.c:779
-#: builtin/index-pack.c:818 builtin/index-pack.c:827
+#: builtin/index-pack.c:751 builtin/index-pack.c:757 builtin/index-pack.c:780
+#: builtin/index-pack.c:819 builtin/index-pack.c:828
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "COLLISION SHA1 TROUVÉE AVEC %s !"
 
-#: builtin/index-pack.c:753 builtin/pack-objects.c:182
-#: builtin/pack-objects.c:276
+#: builtin/index-pack.c:754 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:292
 #, c-format
 msgid "unable to read %s"
 msgstr "impossible de lire %s"
 
-#: builtin/index-pack.c:816
+#: builtin/index-pack.c:817
 #, c-format
 msgid "cannot read existing object info %s"
 msgstr "impossible de lire l'information existante de l'objet %s"
 
-#: builtin/index-pack.c:824
+#: builtin/index-pack.c:825
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "impossible de lire l'objet existant %s"
 
-#: builtin/index-pack.c:838
+#: builtin/index-pack.c:839
 #, c-format
 msgid "invalid blob object %s"
 msgstr "objet blob invalide %s"
 
-#: builtin/index-pack.c:853
+#: builtin/index-pack.c:842 builtin/index-pack.c:860
+msgid "fsck error in packed object"
+msgstr "erreur de fsck dans l'objet empaqueté"
+
+#: builtin/index-pack.c:857
 #, c-format
 msgid "invalid %s"
 msgstr "%s invalide"
 
-#: builtin/index-pack.c:856
-msgid "Error in object"
-msgstr "Erreur dans l'objet"
-
-#: builtin/index-pack.c:858
+#: builtin/index-pack.c:862
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "Tous les objets enfants de %s ne sont pas accessibles"
 
-#: builtin/index-pack.c:930 builtin/index-pack.c:961
+#: builtin/index-pack.c:934 builtin/index-pack.c:965
 msgid "failed to apply delta"
 msgstr "échec d'application du delta"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Receiving objects"
 msgstr "Réception d'objets"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Indexing objects"
 msgstr "Indexation d'objets"
 
-#: builtin/index-pack.c:1165
+#: builtin/index-pack.c:1169
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "le paquet est corrompu (SHA1 ne correspond pas)"
 
-#: builtin/index-pack.c:1170
+#: builtin/index-pack.c:1174
 msgid "cannot fstat packfile"
 msgstr "impossible d'obtenir le statut (fstat) du fichier paquet"
 
-#: builtin/index-pack.c:1173
+#: builtin/index-pack.c:1177
 msgid "pack has junk at the end"
 msgstr "le paquet est invalide à la fin"
 
-#: builtin/index-pack.c:1185
+#: builtin/index-pack.c:1189
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "confusion extrême dans parse_pack_objects()"
 
-#: builtin/index-pack.c:1208
+#: builtin/index-pack.c:1212
 msgid "Resolving deltas"
 msgstr "Résolution des deltas"
 
-#: builtin/index-pack.c:1219
+#: builtin/index-pack.c:1223
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "impossible de créer le fil : %s"
 
-#: builtin/index-pack.c:1261
+#: builtin/index-pack.c:1265
 msgid "confusion beyond insanity"
 msgstr "confusion extrême"
 
-#: builtin/index-pack.c:1267
+#: builtin/index-pack.c:1271
 #, c-format
 msgid "completed with %d local object"
 msgid_plural "completed with %d local objects"
 msgstr[0] "complété avec %d objet local"
 msgstr[1] "complété avec %d objets locaux"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1283
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr ""
 "Somme de contrôle de fin inattendue pour %s (corruption sur le disque ?)"
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1287
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "le paquet a %d delta non résolu"
 msgstr[1] "le paquet a %d deltas non résolus"
 
-#: builtin/index-pack.c:1307
+#: builtin/index-pack.c:1311
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "impossible de compresser l'objet ajouté (%d)"
 
-#: builtin/index-pack.c:1383
+#: builtin/index-pack.c:1388
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "l'objet local %s est corrompu"
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1402
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "le nom de fichier paquet '%s' ne se termine pas par '.pack'"
 
-#: builtin/index-pack.c:1422
+#: builtin/index-pack.c:1427
 #, c-format
 msgid "cannot write %s file '%s'"
 msgstr "impossible d'écrire le fichier %s '%s'"
 
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1435
 #, c-format
 msgid "cannot close written %s file '%s'"
 msgstr "impossible de fermer le fichier %s écrit '%s'"
 
-#: builtin/index-pack.c:1454
+#: builtin/index-pack.c:1459
 msgid "error while closing pack file"
 msgstr "erreur en fermeture du fichier paquet"
 
-#: builtin/index-pack.c:1468
+#: builtin/index-pack.c:1473
 msgid "cannot store pack file"
 msgstr "impossible de stocker le fichier paquet"
 
-#: builtin/index-pack.c:1476
+#: builtin/index-pack.c:1481
 msgid "cannot store index file"
 msgstr "impossible de stocker le fichier d'index"
 
-#: builtin/index-pack.c:1513
+#: builtin/index-pack.c:1525
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "mauvais pack.indexversion=%<PRIu32>"
 
-#: builtin/index-pack.c:1581
+#: builtin/index-pack.c:1594
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "Impossible d'ouvrir le fichier paquet existant '%s'"
 
-#: builtin/index-pack.c:1583
+#: builtin/index-pack.c:1596
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "Impossible d'ouvrir le fichier paquet d'index existant pour '%s'"
 
-#: builtin/index-pack.c:1631
+#: builtin/index-pack.c:1644
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "pas un delta : %d objet"
 msgstr[1] "pas un delta : %d objets"
 
-#: builtin/index-pack.c:1638
+#: builtin/index-pack.c:1651
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] "longueur chaînée = %d : %lu objet"
 msgstr[1] "longueur chaînée = %d : %lu objets"
 
-#: builtin/index-pack.c:1675
+#: builtin/index-pack.c:1688
 msgid "Cannot come back to cwd"
 msgstr "Impossible de revenir au répertoire de travail courant"
 
-#: builtin/index-pack.c:1724 builtin/index-pack.c:1727
-#: builtin/index-pack.c:1743 builtin/index-pack.c:1747
+#: builtin/index-pack.c:1739 builtin/index-pack.c:1742
+#: builtin/index-pack.c:1758 builtin/index-pack.c:1762
 #, c-format
 msgid "bad %s"
 msgstr "mauvais %s"
 
-#: builtin/index-pack.c:1763
+#: builtin/index-pack.c:1778
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin ne peut pas être utilisé sans --stdin"
 
-#: builtin/index-pack.c:1765
+#: builtin/index-pack.c:1780
 msgid "--stdin requires a git repository"
 msgstr "--stdin requiert un dépôt git"
 
-#: builtin/index-pack.c:1771
+#: builtin/index-pack.c:1786
 msgid "--verify with no packfile name given"
 msgstr "--verify sans nom de fichier paquet donné"
 
+#: builtin/index-pack.c:1836 builtin/unpack-objects.c:578
+msgid "fsck error in pack objects"
+msgstr "erreur de fsck dans les objets paquets"
+
 #: builtin/init-db.c:55
 #, c-format
 msgid "cannot stat '%s'"
@@ -9848,8 +10325,8 @@ msgstr "modèle %s ignoré"
 
 #: builtin/init-db.c:120
 #, c-format
-msgid "templates not found %s"
-msgstr "modèles non trouvés %s"
+msgid "templates not found in %s"
+msgstr "modèles non trouvés dans %s"
 
 #: builtin/init-db.c:135
 #, c-format
@@ -9907,11 +10384,6 @@ msgstr "permissions"
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr "spécifier que le dépôt git sera partagé entre plusieurs utilisateurs"
 
-#: builtin/init-db.c:516 builtin/init-db.c:521
-#, c-format
-msgid "cannot mkdir %s"
-msgstr "impossible de créer le répertoire (mkdir) %s"
-
 #: builtin/init-db.c:525
 #, c-format
 msgid "cannot chdir to %s"
@@ -10097,7 +10569,7 @@ msgstr "Deux répertoires de sortie ?"
 msgid "Unknown commit %s"
 msgstr "Commit inconnu %s"
 
-#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:522
+#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:523
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr "Impossible de résoudre '%s' comme une référence valide."
@@ -10457,7 +10929,7 @@ msgstr ""
 msgid "show debugging data"
 msgstr "afficher les données de débogage"
 
-#: builtin/ls-remote.c:7
+#: builtin/ls-remote.c:9
 msgid ""
 "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
@@ -10467,41 +10939,41 @@ msgstr ""
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
 "                     [--symref] [<dépôt> [<références>...]]"
 
-#: builtin/ls-remote.c:52
+#: builtin/ls-remote.c:59
 msgid "do not print remote URL"
 msgstr "ne pas afficher les URL distantes"
 
-#: builtin/ls-remote.c:53 builtin/ls-remote.c:55
+#: builtin/ls-remote.c:60 builtin/ls-remote.c:62
 msgid "exec"
 msgstr "exécutable"
 
-#: builtin/ls-remote.c:54 builtin/ls-remote.c:56
+#: builtin/ls-remote.c:61 builtin/ls-remote.c:63
 msgid "path of git-upload-pack on the remote host"
 msgstr "chemin vers git-upload-pack sur le serveur distant"
 
-#: builtin/ls-remote.c:58
+#: builtin/ls-remote.c:65
 msgid "limit to tags"
 msgstr "limiter aux étiquettes"
 
-#: builtin/ls-remote.c:59
+#: builtin/ls-remote.c:66
 msgid "limit to heads"
 msgstr "limiter aux heads"
 
-#: builtin/ls-remote.c:60
+#: builtin/ls-remote.c:67
 msgid "do not show peeled tags"
 msgstr "ne pas afficher les étiquettes pelées"
 
-#: builtin/ls-remote.c:62
+#: builtin/ls-remote.c:69
 msgid "take url.<base>.insteadOf into account"
 msgstr "prendre en compte url.<base>.insteadOf"
 
-#: builtin/ls-remote.c:64
+#: builtin/ls-remote.c:73
 msgid "exit with exit code 2 if no matching refs are found"
 msgstr ""
 "sortir avec un code d'erreur 2 si aucune correspondance de référence n'est "
 "trouvée"
 
-#: builtin/ls-remote.c:67
+#: builtin/ls-remote.c:76
 msgid "show underlying ref in addition to the object pointed by it"
 msgstr "afficher la réf sous-jacente en plus de l'objet pointé par elle"
 
@@ -10548,168 +11020,168 @@ msgstr ""
 msgid "empty mbox: '%s'"
 msgstr "mbox vide : '%s'"
 
-#: builtin/merge.c:49
+#: builtin/merge.c:51
 msgid "git merge [<options>] [<commit>...]"
 msgstr "git merge [<options>] [<commit>...]"
 
-#: builtin/merge.c:50
+#: builtin/merge.c:52
 msgid "git merge --abort"
 msgstr "git merge --abort"
 
-#: builtin/merge.c:51
+#: builtin/merge.c:53
 msgid "git merge --continue"
 msgstr "git merge --continue"
 
-#: builtin/merge.c:108
+#: builtin/merge.c:110
 msgid "switch `m' requires a value"
 msgstr "le commutateur `m' a besoin d'une valeur"
 
-#: builtin/merge.c:145
+#: builtin/merge.c:147
 #, c-format
 msgid "Could not find merge strategy '%s'.\n"
 msgstr "Impossible de trouver la stratégie de fusion '%s'.\n"
 
-#: builtin/merge.c:146
+#: builtin/merge.c:148
 #, c-format
 msgid "Available strategies are:"
 msgstr "Les stratégies disponibles sont :"
 
-#: builtin/merge.c:151
+#: builtin/merge.c:153
 #, c-format
 msgid "Available custom strategies are:"
 msgstr "Les stratégies personnalisées sont :"
 
-#: builtin/merge.c:201 builtin/pull.c:137
+#: builtin/merge.c:203 builtin/pull.c:142
 msgid "do not show a diffstat at the end of the merge"
 msgstr "ne pas afficher un diffstat à la fin de la fusion"
 
-#: builtin/merge.c:204 builtin/pull.c:140
+#: builtin/merge.c:206 builtin/pull.c:145
 msgid "show a diffstat at the end of the merge"
 msgstr "afficher un diffstat à la fin de la fusion"
 
-#: builtin/merge.c:205 builtin/pull.c:143
+#: builtin/merge.c:207 builtin/pull.c:148
 msgid "(synonym to --stat)"
 msgstr "(synonyme de --stat)"
 
-#: builtin/merge.c:207 builtin/pull.c:146
+#: builtin/merge.c:209 builtin/pull.c:151
 msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr ""
 "ajouter (au plus <n>) éléments du journal court au message de validation de "
 "la fusion"
 
-#: builtin/merge.c:210 builtin/pull.c:152
+#: builtin/merge.c:212 builtin/pull.c:157
 msgid "create a single commit instead of doing a merge"
 msgstr "créer une validation unique au lieu de faire une fusion"
 
-#: builtin/merge.c:212 builtin/pull.c:155
+#: builtin/merge.c:214 builtin/pull.c:160
 msgid "perform a commit if the merge succeeds (default)"
 msgstr "effectuer une validation si la fusion réussit (défaut)"
 
-#: builtin/merge.c:214 builtin/pull.c:158
+#: builtin/merge.c:216 builtin/pull.c:163
 msgid "edit message before committing"
 msgstr "éditer le message avant la validation"
 
-#: builtin/merge.c:215
+#: builtin/merge.c:217
 msgid "allow fast-forward (default)"
 msgstr "autoriser l'avance rapide (défaut)"
 
-#: builtin/merge.c:217 builtin/pull.c:164
+#: builtin/merge.c:219 builtin/pull.c:169
 msgid "abort if fast-forward is not possible"
 msgstr "abandonner si l'avance rapide n'est pas possible"
 
-#: builtin/merge.c:221 builtin/pull.c:167
+#: builtin/merge.c:223 builtin/pull.c:172
 msgid "verify that the named commit has a valid GPG signature"
 msgstr "vérifier que le commit nommé a une signature GPG valide"
 
-#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171
+#: builtin/merge.c:224 builtin/notes.c:777 builtin/pull.c:176
 #: builtin/revert.c:109
 msgid "strategy"
 msgstr "stratégie"
 
-#: builtin/merge.c:223 builtin/pull.c:172
+#: builtin/merge.c:225 builtin/pull.c:177
 msgid "merge strategy to use"
 msgstr "stratégie de fusion à utiliser"
 
-#: builtin/merge.c:224 builtin/pull.c:175
+#: builtin/merge.c:226 builtin/pull.c:180
 msgid "option=value"
 msgstr "option=valeur"
 
-#: builtin/merge.c:225 builtin/pull.c:176
+#: builtin/merge.c:227 builtin/pull.c:181
 msgid "option for selected merge strategy"
 msgstr "option pour la stratégie de fusion sélectionnée"
 
-#: builtin/merge.c:227
+#: builtin/merge.c:229
 msgid "merge commit message (for a non-fast-forward merge)"
 msgstr ""
 "message de validation de la fusion (pour une fusion sans avance rapide)"
 
-#: builtin/merge.c:231
+#: builtin/merge.c:233
 msgid "abort the current in-progress merge"
 msgstr "abandonner la fusion en cours"
 
-#: builtin/merge.c:233
+#: builtin/merge.c:235
 msgid "continue the current in-progress merge"
 msgstr "continuer la fusion en cours"
 
-#: builtin/merge.c:235 builtin/pull.c:183
+#: builtin/merge.c:237 builtin/pull.c:188
 msgid "allow merging unrelated histories"
 msgstr "permettre la fusion d'historiques sans rapport"
 
-#: builtin/merge.c:241
+#: builtin/merge.c:243
 msgid "verify commit-msg hook"
 msgstr "vérifier le crochet commit-msg"
 
-#: builtin/merge.c:266
+#: builtin/merge.c:268
 msgid "could not run stash."
 msgstr "impossible de lancer le remisage."
 
-#: builtin/merge.c:271
+#: builtin/merge.c:273
 msgid "stash failed"
 msgstr "échec du remisage"
 
-#: builtin/merge.c:276
+#: builtin/merge.c:278
 #, c-format
 msgid "not a valid object: %s"
 msgstr "pas un objet valide : %s"
 
-#: builtin/merge.c:298 builtin/merge.c:315
+#: builtin/merge.c:300 builtin/merge.c:317
 msgid "read-tree failed"
 msgstr "read-tree a échoué"
 
-#: builtin/merge.c:345
+#: builtin/merge.c:347
 msgid " (nothing to squash)"
 msgstr " (rien à compresser)"
 
-#: builtin/merge.c:356
+#: builtin/merge.c:358
 #, c-format
 msgid "Squash commit -- not updating HEAD\n"
 msgstr "Validation compressée -- HEAD non mise à jour\n"
 
-#: builtin/merge.c:406
+#: builtin/merge.c:408
 #, c-format
 msgid "No merge message -- not updating HEAD\n"
 msgstr "Pas de message de fusion -- pas de mise à jour de HEAD\n"
 
-#: builtin/merge.c:456
+#: builtin/merge.c:458
 #, c-format
 msgid "'%s' does not point to a commit"
 msgstr "'%s' ne pointe pas sur un commit"
 
-#: builtin/merge.c:546
+#: builtin/merge.c:548
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "Mauvaise chaîne branch.%s.mergeoptions : %s"
 
-#: builtin/merge.c:668
+#: builtin/merge.c:669
 msgid "Not handling anything other than two heads merge."
 msgstr "Impossible de gérer autre chose que la fusion de deux têtes."
 
-#: builtin/merge.c:682
+#: builtin/merge.c:683
 #, c-format
 msgid "Unknown option for merge-recursive: -X%s"
 msgstr "Options inconnue pour merge-recursive : -X%s"
 
-#: builtin/merge.c:697
+#: builtin/merge.c:698
 #, c-format
 msgid "unable to write %s"
 msgstr "impossible d'écrire %s"
@@ -10747,66 +11219,66 @@ msgstr ""
 msgid "Empty commit message."
 msgstr "Message de validation vide."
 
-#: builtin/merge.c:820
+#: builtin/merge.c:819
 #, c-format
 msgid "Wonderful.\n"
 msgstr "Merveilleux.\n"
 
-#: builtin/merge.c:873
+#: builtin/merge.c:872
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr ""
 "La fusion automatique a échoué ; réglez les conflits et validez le "
 "résultat.\n"
 
-#: builtin/merge.c:912
+#: builtin/merge.c:911
 msgid "No current branch."
 msgstr "Pas de branche courante."
 
-#: builtin/merge.c:914
+#: builtin/merge.c:913
 msgid "No remote for the current branch."
 msgstr "Pas de branche distante pour la branche courante."
 
-#: builtin/merge.c:916
+#: builtin/merge.c:915
 msgid "No default upstream defined for the current branch."
 msgstr "Pas de branche amont par défaut définie pour la branche courante."
 
-#: builtin/merge.c:921
+#: builtin/merge.c:920
 #, c-format
 msgid "No remote-tracking branch for %s from %s"
 msgstr "Pas de branche de suivi pour %s depuis %s"
 
-#: builtin/merge.c:974
+#: builtin/merge.c:973
 #, c-format
 msgid "Bad value '%s' in environment '%s'"
 msgstr "Mauvaise valeur '%s' dans l'environnement '%s'"
 
-#: builtin/merge.c:1076
+#: builtin/merge.c:1075
 #, c-format
 msgid "not something we can merge in %s: %s"
 msgstr "pas possible de fusionner ceci dans %s : %s"
 
-#: builtin/merge.c:1110
+#: builtin/merge.c:1109
 msgid "not something we can merge"
 msgstr "pas possible de fusionner ceci"
 
-#: builtin/merge.c:1212
+#: builtin/merge.c:1211
 msgid "--abort expects no arguments"
 msgstr "--abort n'accepte pas d'argument"
 
-#: builtin/merge.c:1216
+#: builtin/merge.c:1215
 msgid "There is no merge to abort (MERGE_HEAD missing)."
 msgstr "Il n'y a pas de fusion à abandonner (MERGE_HEAD manquant)."
 
-#: builtin/merge.c:1228
+#: builtin/merge.c:1227
 msgid "--continue expects no arguments"
 msgstr "--continue ne supporte aucun argument"
 
-#: builtin/merge.c:1232
+#: builtin/merge.c:1231
 msgid "There is no merge in progress (MERGE_HEAD missing)."
 msgstr "Il n'y a pas de fusion en cours (MERGE_HEAD manquant)."
 
-#: builtin/merge.c:1248
+#: builtin/merge.c:1247
 msgid ""
 "You have not concluded your merge (MERGE_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10814,7 +11286,7 @@ msgstr ""
 "Vous n'avez pas terminé votre fusion (MERGE_HEAD existe).\n"
 "Veuillez valider vos modifications avant de pouvoir fusionner."
 
-#: builtin/merge.c:1255
+#: builtin/merge.c:1254
 msgid ""
 "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10822,114 +11294,114 @@ msgstr ""
 "Vous n'avez pas terminé votre picorage (CHERRY_PICK_HEAD existe).\n"
 "Veuillez valider vos modifications avant de pouvoir fusionner."
 
-#: builtin/merge.c:1258
+#: builtin/merge.c:1257
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
 msgstr "Vous n'avez pas terminé votre picorage (CHERRY_PICK_HEAD existe)."
 
-#: builtin/merge.c:1267
+#: builtin/merge.c:1266
 msgid "You cannot combine --squash with --no-ff."
 msgstr "Vous ne pouvez pas combiner --squash avec --no-ff."
 
-#: builtin/merge.c:1275
+#: builtin/merge.c:1274
 msgid "No commit specified and merge.defaultToUpstream not set."
 msgstr ""
 "Pas de validation spécifiée et merge.defaultToUpstream n'est pas défini."
 
-#: builtin/merge.c:1292
+#: builtin/merge.c:1291
 msgid "Squash commit into empty head not supported yet"
 msgstr "La validation compressée vers une tête vide n'est pas encore supportée"
 
-#: builtin/merge.c:1294
+#: builtin/merge.c:1293
 msgid "Non-fast-forward commit does not make sense into an empty head"
 msgstr "Une validation sans avance rapide n'a pas de sens dans une tête vide"
 
-#: builtin/merge.c:1299
+#: builtin/merge.c:1298
 #, c-format
 msgid "%s - not something we can merge"
 msgstr "%s - pas possible de fusionner ceci"
 
-#: builtin/merge.c:1301
+#: builtin/merge.c:1300
 msgid "Can merge only exactly one commit into empty head"
 msgstr ""
 "Possible de fusionner exactement une seule validation dans une tête vide"
 
-#: builtin/merge.c:1335
+#: builtin/merge.c:1334
 #, c-format
 msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
 msgstr "La validation %s a une signature GPG non fiable, prétendument par %s."
 
-#: builtin/merge.c:1338
+#: builtin/merge.c:1337
 #, c-format
 msgid "Commit %s has a bad GPG signature allegedly by %s."
 msgstr "La validation %s a une mauvaise signature GPG prétendument par %s."
 
-#: builtin/merge.c:1341
+#: builtin/merge.c:1340
 #, c-format
 msgid "Commit %s does not have a GPG signature."
 msgstr "La validation %s n'a pas de signature GPG."
 
-#: builtin/merge.c:1344
+#: builtin/merge.c:1343
 #, c-format
 msgid "Commit %s has a good GPG signature by %s\n"
 msgstr "La validation %s a une signature GPG correcte par %s\n"
 
-#: builtin/merge.c:1403
+#: builtin/merge.c:1402
 msgid "refusing to merge unrelated histories"
 msgstr "refus de fusionner des historiques sans relation"
 
-#: builtin/merge.c:1412
+#: builtin/merge.c:1411
 msgid "Already up to date."
 msgstr "Déjà à jour."
 
-#: builtin/merge.c:1422
+#: builtin/merge.c:1421
 #, c-format
 msgid "Updating %s..%s\n"
 msgstr "Mise à jour %s..%s\n"
 
-#: builtin/merge.c:1463
+#: builtin/merge.c:1462
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
 msgstr "Essai de fusion vraiment triviale dans l'index...\n"
 
-#: builtin/merge.c:1470
+#: builtin/merge.c:1469
 #, c-format
 msgid "Nope.\n"
 msgstr "Non.\n"
 
-#: builtin/merge.c:1495
+#: builtin/merge.c:1494
 msgid "Already up to date. Yeeah!"
 msgstr "Déjà à jour. Ouais !"
 
-#: builtin/merge.c:1501
+#: builtin/merge.c:1500
 msgid "Not possible to fast-forward, aborting."
 msgstr "Pas possible d'avancer rapidement, abandon."
 
-#: builtin/merge.c:1524 builtin/merge.c:1603
+#: builtin/merge.c:1523 builtin/merge.c:1602
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
 msgstr "Retour de l'arbre à l'original...\n"
 
-#: builtin/merge.c:1528
+#: builtin/merge.c:1527
 #, c-format
 msgid "Trying merge strategy %s...\n"
 msgstr "Essai de la stratégie de fusion %s...\n"
 
-#: builtin/merge.c:1594
+#: builtin/merge.c:1593
 #, c-format
 msgid "No merge strategy handled the merge.\n"
 msgstr "Aucune stratégie de fusion n'a pris en charge la fusion.\n"
 
-#: builtin/merge.c:1596
+#: builtin/merge.c:1595
 #, c-format
 msgid "Merge with strategy %s failed.\n"
 msgstr "La fusion avec la stratégie %s a échoué.\n"
 
-#: builtin/merge.c:1605
+#: builtin/merge.c:1604
 #, c-format
 msgid "Using the %s to prepare resolving by hand.\n"
 msgstr "Utilisation de %s pour préparer la résolution à la main.\n"
 
-#: builtin/merge.c:1617
+#: builtin/merge.c:1616
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr ""
@@ -11066,27 +11538,27 @@ msgstr "autoriser la création de plus d'un arbre"
 msgid "git mv [<options>] <source>... <destination>"
 msgstr "git mv [<options>] <source>... <destination>"
 
-#: builtin/mv.c:83
+#: builtin/mv.c:82
 #, c-format
 msgid "Directory %s is in index and no submodule?"
 msgstr "Le répertoire %s est dans l'index et pourtant aucun sous-module ?"
 
-#: builtin/mv.c:85 builtin/rm.c:289
+#: builtin/mv.c:84 builtin/rm.c:288
 msgid "Please stage your changes to .gitmodules or stash them to proceed"
 msgstr ""
 "Veuillez indexer vos modifications de .gitmodules ou les remiser pour "
 "continuer"
 
-#: builtin/mv.c:103
+#: builtin/mv.c:102
 #, c-format
 msgid "%.*s is in index"
 msgstr "%.*s est dans l'index"
 
-#: builtin/mv.c:125
+#: builtin/mv.c:124
 msgid "force move/rename even if target exists"
 msgstr "forcer le déplacement/renommage même si la cible existe"
 
-#: builtin/mv.c:127
+#: builtin/mv.c:126
 msgid "skip move/rename errors"
 msgstr "sauter les erreurs de déplacement/renommage"
 
@@ -11151,7 +11623,7 @@ msgstr "%s, source=%s, destination=%s"
 msgid "Renaming %s to %s\n"
 msgstr "Renommage de %s en %s\n"
 
-#: builtin/mv.c:276 builtin/remote.c:712 builtin/repack.c:394
+#: builtin/mv.c:276 builtin/remote.c:715 builtin/repack.c:409
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "le renommage de '%s' a échoué"
@@ -11344,12 +11816,12 @@ msgstr "impossible d'écrire l'objet note"
 msgid "the note contents have been left in %s"
 msgstr "le contenu de la note a été laissé dans %s"
 
-#: builtin/notes.c:234 builtin/tag.c:506
+#: builtin/notes.c:234 builtin/tag.c:507
 #, c-format
 msgid "cannot read '%s'"
 msgstr "impossible de lire '%s'"
 
-#: builtin/notes.c:236 builtin/tag.c:509
+#: builtin/notes.c:236 builtin/tag.c:510
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "impossible d'ouvrir ou lire '%s'"
@@ -11597,7 +12069,7 @@ msgstr ""
 msgid "read object names from the standard input"
 msgstr "lire les noms d'objet depuis l'entrée standard"
 
-#: builtin/notes.c:943 builtin/prune.c:106 builtin/worktree.c:160
+#: builtin/notes.c:943 builtin/prune.c:107 builtin/worktree.c:151
 msgid "do not remove, show only"
 msgstr "ne pas supprimer, afficher seulement"
 
@@ -11618,224 +12090,252 @@ msgstr "utiliser les notes depuis <références-notes>"
 msgid "unknown subcommand: %s"
 msgstr "sous-commande inconnue : %s"
 
-#: builtin/pack-objects.c:33
+#: builtin/pack-objects.c:48
 msgid ""
 "git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
 msgstr ""
 "git pack-objects --stdout [options...] [< <liste-références> | < <liste-"
 "objets>]"
 
-#: builtin/pack-objects.c:34
+#: builtin/pack-objects.c:49
 msgid ""
 "git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
 msgstr ""
 "git pack-objects [options...] base-name [< <liste-références> | < <liste-"
 "objets>]"
 
-#: builtin/pack-objects.c:195 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:211 builtin/pack-objects.c:214
 #, c-format
 msgid "deflate error (%d)"
 msgstr "erreur de compression (%d)"
 
-#: builtin/pack-objects.c:791
+#: builtin/pack-objects.c:810
 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
 msgstr ""
 "désactivation de l'écriture en bitmap, les fichiers paquets sont scindés à "
 "cause de pack.packSizeLimit"
 
-#: builtin/pack-objects.c:804
+#: builtin/pack-objects.c:823
 msgid "Writing objects"
 msgstr "Écriture des objets"
 
-#: builtin/pack-objects.c:1084
+#: builtin/pack-objects.c:1106
 msgid "disabling bitmap writing, as some objects are not being packed"
 msgstr ""
 "désactivation de l'écriture en bitmap car certains objets ne sont pas "
 "compressés"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:1765
+msgid "Counting objects"
+msgstr "Décompte des objets"
+
+#: builtin/pack-objects.c:1895
+#, c-format
+msgid "unable to get size of %s"
+msgstr "impossible de récupérer la taille de %s"
+
+#: builtin/pack-objects.c:1910
+#, c-format
+msgid "unable to parse object header of %s"
+msgstr "impossible d'analyser l'entête d'objet de %s"
+
+#: builtin/pack-objects.c:2564
 msgid "Compressing objects"
 msgstr "Compression des objets"
 
-#: builtin/pack-objects.c:2625
+#: builtin/pack-objects.c:2735
 msgid "invalid value for --missing"
 msgstr "valeur invalide pour --missing"
 
-#: builtin/pack-objects.c:2928
+#: builtin/pack-objects.c:3067
 #, c-format
 msgid "unsupported index version %s"
 msgstr "version d'index non supportée %s"
 
-#: builtin/pack-objects.c:2932
+#: builtin/pack-objects.c:3071
 #, c-format
 msgid "bad index version '%s'"
 msgstr "mauvaise version d'index '%s'"
 
-#: builtin/pack-objects.c:2962
+#: builtin/pack-objects.c:3102
 msgid "do not show progress meter"
 msgstr "ne pas afficher la barre de progression"
 
-#: builtin/pack-objects.c:2964
+#: builtin/pack-objects.c:3104
 msgid "show progress meter"
 msgstr "afficher la barre de progression"
 
-#: builtin/pack-objects.c:2966
+#: builtin/pack-objects.c:3106
 msgid "show progress meter during object writing phase"
 msgstr "afficher la barre de progression durant la phase d'écrite des objets"
 
-#: builtin/pack-objects.c:2969
+#: builtin/pack-objects.c:3109
 msgid "similar to --all-progress when progress meter is shown"
 msgstr "similaire à --all-progress quand la barre de progression est affichée"
 
-#: builtin/pack-objects.c:2970
+#: builtin/pack-objects.c:3110
 msgid "version[,offset]"
 msgstr "version[,offset]"
 
-#: builtin/pack-objects.c:2971
+#: builtin/pack-objects.c:3111
 msgid "write the pack index file in the specified idx format version"
 msgstr ""
 "écrire le fichier d'index du paquet dans le format d'index de version "
 "spécifié"
 
-#: builtin/pack-objects.c:2974
+#: builtin/pack-objects.c:3114
 msgid "maximum size of each output pack file"
 msgstr "taille maximum de chaque fichier paquet en sortie"
 
-#: builtin/pack-objects.c:2976
+#: builtin/pack-objects.c:3116
 msgid "ignore borrowed objects from alternate object store"
 msgstr "ignorer les objets empruntés à un autre magasin d'objets"
 
-#: builtin/pack-objects.c:2978
+#: builtin/pack-objects.c:3118
 msgid "ignore packed objects"
 msgstr "ignorer les objets empaquetés"
 
-#: builtin/pack-objects.c:2980
+#: builtin/pack-objects.c:3120
 msgid "limit pack window by objects"
 msgstr "limiter la fenêtre d'empaquetage par objets"
 
-#: builtin/pack-objects.c:2982
+#: builtin/pack-objects.c:3122
 msgid "limit pack window by memory in addition to object limit"
 msgstr ""
 "limiter la fenêtre d'empaquetage par mémoire en plus de la limite d'objets"
 
-#: builtin/pack-objects.c:2984
+#: builtin/pack-objects.c:3124
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr ""
 "longueur maximum de la chaîne de delta autorisée dans le paquet résultant"
 
-#: builtin/pack-objects.c:2986
+#: builtin/pack-objects.c:3126
 msgid "reuse existing deltas"
 msgstr "réutiliser les deltas existants"
 
-#: builtin/pack-objects.c:2988
+#: builtin/pack-objects.c:3128
 msgid "reuse existing objects"
 msgstr "réutiliser les objets existants"
 
-#: builtin/pack-objects.c:2990
+#: builtin/pack-objects.c:3130
 msgid "use OFS_DELTA objects"
 msgstr "utiliser les objets OFS_DELTA"
 
-#: builtin/pack-objects.c:2992
+#: builtin/pack-objects.c:3132
 msgid "use threads when searching for best delta matches"
 msgstr ""
 "utiliser des fils lors de la recherche pour une meilleurs correspondance des "
 "deltas"
 
-#: builtin/pack-objects.c:2994
+#: builtin/pack-objects.c:3134
 msgid "do not create an empty pack output"
 msgstr "ne pas créer un paquet vide"
 
-#: builtin/pack-objects.c:2996
+#: builtin/pack-objects.c:3136
 msgid "read revision arguments from standard input"
 msgstr "lire les paramètres de révision depuis l'entrée standard"
 
-#: builtin/pack-objects.c:2998
+#: builtin/pack-objects.c:3138
 msgid "limit the objects to those that are not yet packed"
 msgstr "limiter les objets à ceux qui ne sont pas encore empaquetés"
 
-#: builtin/pack-objects.c:3001
+#: builtin/pack-objects.c:3141
 msgid "include objects reachable from any reference"
 msgstr "inclure les objets accessibles depuis toute référence"
 
-#: builtin/pack-objects.c:3004
+#: builtin/pack-objects.c:3144
 msgid "include objects referred by reflog entries"
 msgstr "inclure les objets référencés par les éléments de reflog"
 
-#: builtin/pack-objects.c:3007
+#: builtin/pack-objects.c:3147
 msgid "include objects referred to by the index"
 msgstr "inclure les objets référencés par l'index"
 
-#: builtin/pack-objects.c:3010
+#: builtin/pack-objects.c:3150
 msgid "output pack to stdout"
 msgstr "afficher l'empaquetage sur la sortie standard"
 
-#: builtin/pack-objects.c:3012
+#: builtin/pack-objects.c:3152
 msgid "include tag objects that refer to objects to be packed"
 msgstr "inclure les objets d'étiquettes qui réfèrent à des objets à empaqueter"
 
-#: builtin/pack-objects.c:3014
+#: builtin/pack-objects.c:3154
 msgid "keep unreachable objects"
 msgstr "garder les objets inaccessibles"
 
-#: builtin/pack-objects.c:3016
+#: builtin/pack-objects.c:3156
 msgid "pack loose unreachable objects"
 msgstr "empaqueter les objets inaccessibles détachés"
 
-#: builtin/pack-objects.c:3018
+#: builtin/pack-objects.c:3158
 msgid "unpack unreachable objects newer than <time>"
 msgstr "dépaqueter les objets inaccessibles plus récents que <heure>"
 
-#: builtin/pack-objects.c:3021
+#: builtin/pack-objects.c:3161
 msgid "create thin packs"
 msgstr "créer des paquets légers"
 
-#: builtin/pack-objects.c:3023
+#: builtin/pack-objects.c:3163
 msgid "create packs suitable for shallow fetches"
 msgstr "créer des paquets permettant des récupérations superficielles"
 
-#: builtin/pack-objects.c:3025
+#: builtin/pack-objects.c:3165
 msgid "ignore packs that have companion .keep file"
 msgstr "ignorer les paquets qui ont un fichier .keep"
 
-#: builtin/pack-objects.c:3027
+#: builtin/pack-objects.c:3167
+msgid "ignore this pack"
+msgstr "ignorer ce paquet"
+
+#: builtin/pack-objects.c:3169
 msgid "pack compression level"
 msgstr "niveau de compression du paquet"
 
-#: builtin/pack-objects.c:3029
+#: builtin/pack-objects.c:3171
 msgid "do not hide commits by grafts"
 msgstr "ne pas cacher les validations par greffes"
 
-#: builtin/pack-objects.c:3031
+#: builtin/pack-objects.c:3173
 msgid "use a bitmap index if available to speed up counting objects"
 msgstr ""
 "utiliser un index en bitmap si disponible pour accélerer le décompte des "
 "objets"
 
-#: builtin/pack-objects.c:3033
+#: builtin/pack-objects.c:3175
 msgid "write a bitmap index together with the pack index"
 msgstr "écrire un index en bitmap associé à l'index de paquet"
 
-#: builtin/pack-objects.c:3036
+#: builtin/pack-objects.c:3178
 msgid "handling for missing objects"
 msgstr "gestion des objets manquants"
 
-#: builtin/pack-objects.c:3039
+#: builtin/pack-objects.c:3181
 msgid "do not pack objects in promisor packfiles"
 msgstr "ne pas empaqueter les objets dans les fichiers paquets prometteurs"
 
-#: builtin/pack-objects.c:3178
-msgid "Counting objects"
-msgstr "Décompte des objets"
+#: builtin/pack-objects.c:3205
+#, c-format
+msgid "delta chain depth %d is too deep, forcing %d"
+msgstr "la profondeur %d de chaîne de delta est trop grande, forcée à %d"
+
+#: builtin/pack-objects.c:3210
+#, c-format
+msgid "pack.deltaCacheLimit is too high, forcing %d"
+msgstr "pack.deltaCacheLimit est trop grand, forcé à %d"
 
-#: builtin/pack-refs.c:6
+#: builtin/pack-objects.c:3338
+msgid "Enumerating objects"
+msgstr "Énumération des objets"
+
+#: builtin/pack-refs.c:7
 msgid "git pack-refs [<options>]"
 msgstr "git pack-refs [<options>]"
 
-#: builtin/pack-refs.c:14
+#: builtin/pack-refs.c:15
 msgid "pack everything"
 msgstr "empaqueter tout"
 
-#: builtin/pack-refs.c:15
+#: builtin/pack-refs.c:16
 msgid "prune loose refs (default)"
 msgstr "éliminer les références perdues (défaut)"
 
@@ -11851,65 +12351,65 @@ msgstr "Suppression des objets dupliqués"
 msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]"
 msgstr "git prune [-n] [-v] [--progress] [--expire <heure>] [--] [<head>…]"
 
-#: builtin/prune.c:107
+#: builtin/prune.c:108
 msgid "report pruned objects"
 msgstr "afficher les objets éliminés"
 
-#: builtin/prune.c:110
+#: builtin/prune.c:111
 msgid "expire objects older than <time>"
 msgstr "faire expirer les objets plus vieux que <heure>"
 
-#: builtin/prune.c:112
+#: builtin/prune.c:113
 msgid "limit traversal to objects outside promisor packfiles"
 msgstr "limiter la traversée aux objets hors des fichiers paquets prometteurs"
 
-#: builtin/prune.c:126
+#: builtin/prune.c:127
 msgid "cannot prune in a precious-objects repo"
 msgstr "impossible de nettoyer dans un dépôt d'objets précieux"
 
-#: builtin/pull.c:54 builtin/pull.c:56
+#: builtin/pull.c:59 builtin/pull.c:61
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "Valeur invalide pour %s : %s"
 
-#: builtin/pull.c:76
+#: builtin/pull.c:81
 msgid "git pull [<options>] [<repository> [<refspec>...]]"
 msgstr "git pull [<options>] [<dépôt> [<spécification-de-référence>...]]"
 
-#: builtin/pull.c:127
+#: builtin/pull.c:132
 msgid "control for recursive fetching of submodules"
 msgstr "contrôler la récupération récursive dans les sous-modules"
 
-#: builtin/pull.c:131
+#: builtin/pull.c:136
 msgid "Options related to merging"
 msgstr "Options relatives à la fusion"
 
-#: builtin/pull.c:134
+#: builtin/pull.c:139
 msgid "incorporate changes by rebasing rather than merging"
 msgstr "incorporer les modifications en rebasant plutôt qu'en fusionnant"
 
-#: builtin/pull.c:161 builtin/rebase--helper.c:23 builtin/revert.c:121
+#: builtin/pull.c:166 builtin/rebase--helper.c:23 builtin/revert.c:121
 msgid "allow fast-forward"
 msgstr "autoriser l'avance rapide"
 
-#: builtin/pull.c:170
+#: builtin/pull.c:175
 msgid "automatically stash/stash pop before and after rebase"
 msgstr "remiser avant et réappliquer après le rebasage automatiquement"
 
-#: builtin/pull.c:186
+#: builtin/pull.c:191
 msgid "Options related to fetching"
 msgstr "Options relatives au rapatriement"
 
-#: builtin/pull.c:204
+#: builtin/pull.c:209
 msgid "number of submodules pulled in parallel"
 msgstr "nombre de sous-modules tirés en parallèle"
 
-#: builtin/pull.c:299
+#: builtin/pull.c:304
 #, c-format
 msgid "Invalid value for pull.ff: %s"
 msgstr "Valeur invalide pour pull.ff : %s"
 
-#: builtin/pull.c:415
+#: builtin/pull.c:420
 msgid ""
 "There is no candidate for rebasing against among the refs that you just "
 "fetched."
@@ -11917,14 +12417,14 @@ msgstr ""
 "Il n'y a pas de candidate sur laquelle rebaser parmi les références que vous "
 "venez de récupérer."
 
-#: builtin/pull.c:417
+#: builtin/pull.c:422
 msgid ""
 "There are no candidates for merging among the refs that you just fetched."
 msgstr ""
 "Il n'y a pas de candidate avec laquelle fusionner parmi les références que "
 "vous venez de récupérer."
 
-#: builtin/pull.c:418
+#: builtin/pull.c:423
 msgid ""
 "Generally this means that you provided a wildcard refspec which had no\n"
 "matches on the remote end."
@@ -11932,7 +12432,7 @@ msgstr ""
 "Généralement, cela signifie que vous avez indiqué un spécificateur\n"
 "de référence joker qui n'a pas eu de correspondance sur le serveur distant."
 
-#: builtin/pull.c:421
+#: builtin/pull.c:426
 #, c-format
 msgid ""
 "You asked to pull from the remote '%s', but did not specify\n"
@@ -11944,44 +12444,44 @@ msgstr ""
 "configuration\n"
 "pour la branche actuelle, vous devez spécifier la branche avec la commande."
 
-#: builtin/pull.c:426 git-parse-remote.sh:73
+#: builtin/pull.c:431 git-parse-remote.sh:73
 msgid "You are not currently on a branch."
 msgstr "Vous n'êtes actuellement sur aucune branche."
 
-#: builtin/pull.c:428 builtin/pull.c:443 git-parse-remote.sh:79
+#: builtin/pull.c:433 builtin/pull.c:448 git-parse-remote.sh:79
 msgid "Please specify which branch you want to rebase against."
 msgstr "Veuillez spécifier sur quelle branche vous souhaiter rebaser."
 
-#: builtin/pull.c:430 builtin/pull.c:445 git-parse-remote.sh:82
+#: builtin/pull.c:435 builtin/pull.c:450 git-parse-remote.sh:82
 msgid "Please specify which branch you want to merge with."
 msgstr "Veuillez spécifier une branche avec laquelle fusionner."
 
-#: builtin/pull.c:431 builtin/pull.c:446
+#: builtin/pull.c:436 builtin/pull.c:451
 msgid "See git-pull(1) for details."
 msgstr "Référez-vous à git-pull(1) pour de plus amples détails."
 
-#: builtin/pull.c:433 builtin/pull.c:439 builtin/pull.c:448
+#: builtin/pull.c:438 builtin/pull.c:444 builtin/pull.c:453
 #: git-parse-remote.sh:64
 msgid "<remote>"
 msgstr "<distant>"
 
-#: builtin/pull.c:433 builtin/pull.c:448 builtin/pull.c:453 git-rebase.sh:477
+#: builtin/pull.c:438 builtin/pull.c:453 builtin/pull.c:458 git-rebase.sh:523
 #: git-parse-remote.sh:65
 msgid "<branch>"
 msgstr "<branche>"
 
-#: builtin/pull.c:441 git-parse-remote.sh:75
+#: builtin/pull.c:446 git-parse-remote.sh:75
 msgid "There is no tracking information for the current branch."
 msgstr "Pas d'information de suivi distant pour la branche actuelle."
 
-#: builtin/pull.c:450 git-parse-remote.sh:95
+#: builtin/pull.c:455 git-parse-remote.sh:95
 msgid ""
 "If you wish to set tracking information for this branch you can do so with:"
 msgstr ""
 "Si vous souhaitez indiquer l'information de suivi distant pour cette "
 "branche, vous pouvez le faire avec :"
 
-#: builtin/pull.c:455
+#: builtin/pull.c:460
 #, c-format
 msgid ""
 "Your configuration specifies to merge with the ref '%s'\n"
@@ -11991,29 +12491,29 @@ msgstr ""
 "'%s'\n"
 "du serveur distant, mais cette référence n'a pas été récupérée."
 
-#: builtin/pull.c:819
+#: builtin/pull.c:826
 msgid "ignoring --verify-signatures for rebase"
 msgstr "--verify-signatures est ignoré pour un rebasage"
 
-#: builtin/pull.c:867
+#: builtin/pull.c:874
 msgid "--[no-]autostash option is only valid with --rebase."
 msgstr "l'option --[no-]autostash n'est valide qu'avec --rebase."
 
-#: builtin/pull.c:875
+#: builtin/pull.c:882
 msgid "Updating an unborn branch with changes added to the index."
 msgstr ""
 "Mise à jour d'une branche non encore créée avec les changements ajoutés dans "
 "l'index."
 
-#: builtin/pull.c:878
+#: builtin/pull.c:885
 msgid "pull with rebase"
 msgstr "tirer avec un rebasage"
 
-#: builtin/pull.c:879
+#: builtin/pull.c:886
 msgid "please commit or stash them."
 msgstr "veuillez les valider ou les remiser."
 
-#: builtin/pull.c:904
+#: builtin/pull.c:911
 #, c-format
 msgid ""
 "fetch updated the current branch head.\n"
@@ -12024,7 +12524,7 @@ msgstr ""
 "avance rapide de votre copie de travail\n"
 "depuis le commit %s."
 
-#: builtin/pull.c:909
+#: builtin/pull.c:916
 #, c-format
 msgid ""
 "Cannot fast-forward your working tree.\n"
@@ -12041,33 +12541,33 @@ msgstr ""
 "$ git reset --hard\n"
 "pour régénérer."
 
-#: builtin/pull.c:924
+#: builtin/pull.c:931
 msgid "Cannot merge multiple branches into empty head."
 msgstr "Impossible de fusionner de multiples branches sur une tête vide."
 
-#: builtin/pull.c:928
+#: builtin/pull.c:935
 msgid "Cannot rebase onto multiple branches."
 msgstr "Impossible de rebaser sur de multiples branches."
 
-#: builtin/pull.c:935
+#: builtin/pull.c:942
 msgid "cannot rebase with locally recorded submodule modifications"
 msgstr ""
 "impossible de rebaser avec des modifications de sous-modules enregistrées "
 "localement"
 
-#: builtin/push.c:17
+#: builtin/push.c:19
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr "git push [<options>] [<dépôt> [<spécification-de-référence>...]]"
 
-#: builtin/push.c:92
+#: builtin/push.c:111
 msgid "tag shorthand without <tag>"
 msgstr "raccourci d'étiquette sans <étiquette>"
 
-#: builtin/push.c:102
+#: builtin/push.c:121
 msgid "--delete only accepts plain target ref names"
 msgstr "--delete accepte seulement des noms entiers de références cibles"
 
-#: builtin/push.c:146
+#: builtin/push.c:165
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -12076,7 +12576,7 @@ msgstr ""
 "Pour choisir l'option de manière permanente, voir push.default dans 'git "
 "help config'."
 
-#: builtin/push.c:149
+#: builtin/push.c:168
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -12101,7 +12601,7 @@ msgstr ""
 "    git push %s %s\n"
 "%s"
 
-#: builtin/push.c:164
+#: builtin/push.c:183
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -12116,7 +12616,7 @@ msgstr ""
 "\n"
 "    git push %s HEAD:<nom-de-la-branche-amont>\n"
 
-#: builtin/push.c:178
+#: builtin/push.c:197
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -12130,13 +12630,13 @@ msgstr ""
 "\n"
 "    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:186
+#: builtin/push.c:205
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr ""
 "La branche courante %s a de multiples branches amont, impossible de pousser."
 
-#: builtin/push.c:189
+#: builtin/push.c:208
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -12147,14 +12647,14 @@ msgstr ""
 "pas une branche amont de votre branche courante '%s', sans me dire\n"
 "quoi pousser pour mettre à jour quelle branche amont."
 
-#: builtin/push.c:248
+#: builtin/push.c:267
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
 "Vous n'avez pas spécifié de spécifications de référence à pousser, et push."
 "default est \"nothing\"."
 
-#: builtin/push.c:255
+#: builtin/push.c:274
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -12169,7 +12669,7 @@ msgstr ""
 "Voir la 'Note à propos des avances rapides' dans 'git push --help' pour plus "
 "d'information."
 
-#: builtin/push.c:261
+#: builtin/push.c:280
 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"
@@ -12184,7 +12684,7 @@ msgstr ""
 "Voir la 'Note à propos des avances rapides' dans 'git push --help' pour plus "
 "d'information."
 
-#: builtin/push.c:267
+#: builtin/push.c:286
 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"
@@ -12202,13 +12702,13 @@ msgstr ""
 "Voir la 'Note à propos des avances rapides' dans 'git push --help' pour plus "
 "d'information."
 
-#: builtin/push.c:274
+#: builtin/push.c:293
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr ""
 "Les mises à jour ont été rejetées car l'étiquette existe déjà dans la "
 "branche distante."
 
-#: builtin/push.c:277
+#: builtin/push.c:296
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -12220,22 +12720,22 @@ msgstr ""
 "pointer\n"
 "vers un objet qui n'est pas un commit, sans utiliser l'option '--force'.\n"
 
-#: builtin/push.c:337
+#: builtin/push.c:357
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "Poussée vers %s\n"
 
-#: builtin/push.c:341
+#: builtin/push.c:361
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr "impossible de pousser des références vers '%s'"
 
-#: builtin/push.c:372
+#: builtin/push.c:395
 #, c-format
 msgid "bad repository '%s'"
 msgstr "mauvais dépôt '%s'"
 
-#: builtin/push.c:373
+#: builtin/push.c:396
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -12257,113 +12757,105 @@ msgstr ""
 "\n"
 "    git push <nom>\n"
 
-#: builtin/push.c:391
-msgid "--all and --tags are incompatible"
-msgstr "--all et --tags sont incompatibles"
-
-#: builtin/push.c:392
-msgid "--all can't be combined with refspecs"
-msgstr "--all ne peut pas être combiné avec des spécifications de référence"
-
-#: builtin/push.c:397
-msgid "--mirror and --tags are incompatible"
-msgstr "--mirror et --tags sont incompatibles"
-
-#: builtin/push.c:398
-msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror ne peut pas être combiné avec des spécifications de référence"
-
-#: builtin/push.c:403
-msgid "--all and --mirror are incompatible"
-msgstr "--all et --mirror sont incompatibles"
-
-#: builtin/push.c:535
+#: builtin/push.c:551
 msgid "repository"
 msgstr "dépôt"
 
-#: builtin/push.c:536 builtin/send-pack.c:163
+#: builtin/push.c:552 builtin/send-pack.c:164
 msgid "push all refs"
 msgstr "pousser toutes les références"
 
-#: builtin/push.c:537 builtin/send-pack.c:165
+#: builtin/push.c:553 builtin/send-pack.c:166
 msgid "mirror all refs"
 msgstr "refléter toutes les références"
 
-#: builtin/push.c:539
+#: builtin/push.c:555
 msgid "delete refs"
 msgstr "supprimer les références"
 
-#: builtin/push.c:540
+#: builtin/push.c:556
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr ""
 "pousser les étiquettes (ne peut pas être utilisé avec --all ou --mirror)"
 
-#: builtin/push.c:543 builtin/send-pack.c:166
+#: builtin/push.c:559 builtin/send-pack.c:167
 msgid "force updates"
 msgstr "forcer les mises à jour"
 
-#: builtin/push.c:545 builtin/send-pack.c:180
+#: builtin/push.c:561 builtin/send-pack.c:181
 msgid "refname>:<expect"
 msgstr "nom de référence>:<attendu"
 
-#: builtin/push.c:546 builtin/send-pack.c:181
+#: builtin/push.c:562 builtin/send-pack.c:182
 msgid "require old value of ref to be at this value"
 msgstr "exiger que l'ancienne valeur de la référence soit à cette valeur"
 
-#: builtin/push.c:549
+#: builtin/push.c:565
 msgid "control recursive pushing of submodules"
 msgstr "contrôler la poussée récursive des sous-modules"
 
-#: builtin/push.c:551 builtin/send-pack.c:174
+#: builtin/push.c:567 builtin/send-pack.c:175
 msgid "use thin pack"
 msgstr "utiliser un empaquetage léger"
 
-#: builtin/push.c:552 builtin/push.c:553 builtin/send-pack.c:160
-#: builtin/send-pack.c:161
+#: builtin/push.c:568 builtin/push.c:569 builtin/send-pack.c:161
+#: builtin/send-pack.c:162
 msgid "receive pack program"
 msgstr "recevoir le programme d'empaquetage"
 
-#: builtin/push.c:554
+#: builtin/push.c:570
 msgid "set upstream for git pull/status"
 msgstr "définir la branche amont pour git pull/status"
 
-#: builtin/push.c:557
+#: builtin/push.c:573
 msgid "prune locally removed refs"
 msgstr "éliminer les références locales supprimées"
 
-#: builtin/push.c:559
+#: builtin/push.c:575
 msgid "bypass pre-push hook"
 msgstr "éviter d'utiliser le crochet pre-push"
 
-#: builtin/push.c:560
+#: builtin/push.c:576
 msgid "push missing but relevant tags"
 msgstr "pousser les étiquettes manquantes mais pertinentes"
 
-#: builtin/push.c:563 builtin/send-pack.c:168
+#: builtin/push.c:579 builtin/send-pack.c:169
 msgid "GPG sign the push"
 msgstr "signer la poussée avec GPG"
 
-#: builtin/push.c:565 builtin/send-pack.c:175
+#: builtin/push.c:581 builtin/send-pack.c:176
 msgid "request atomic transaction on remote side"
 msgstr "demande une transaction atomique sur le serveur distant"
 
-#: builtin/push.c:566 builtin/send-pack.c:171
-msgid "server-specific"
-msgstr "spécifique au serveur"
-
-#: builtin/push.c:566 builtin/send-pack.c:172
-msgid "option to transmit"
-msgstr "option à transmettre"
-
-#: builtin/push.c:583
+#: builtin/push.c:599
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr "--delete est incompatible avec --all, --mirror et --tags"
 
-#: builtin/push.c:585
+#: builtin/push.c:601
 msgid "--delete doesn't make sense without any refs"
 msgstr "--delete n'a pas de sens sans aucune référence"
 
 #: builtin/push.c:604
+msgid "--all and --tags are incompatible"
+msgstr "--all et --tags sont incompatibles"
+
+#: builtin/push.c:606
+msgid "--all can't be combined with refspecs"
+msgstr "--all ne peut pas être combiné avec des spécifications de référence"
+
+#: builtin/push.c:610
+msgid "--mirror and --tags are incompatible"
+msgstr "--mirror et --tags sont incompatibles"
+
+#: builtin/push.c:612
+msgid "--mirror can't be combined with refspecs"
+msgstr "--mirror ne peut pas être combiné avec des spécifications de référence"
+
+#: builtin/push.c:615
+msgid "--all and --mirror are incompatible"
+msgstr "--all et --mirror sont incompatibles"
+
+#: builtin/push.c:634
 msgid "push options must not have new line characters"
 msgstr ""
 "les options de poussée ne peuvent pas contenir de caractères de nouvelle "
@@ -12380,67 +12872,67 @@ msgstr ""
 "sparse-checkout] [--index-output=<fichier>] (--empty | <arbre ou apparenté "
 "1> [<arbre ou apparenté 2> [<arbre ou apparenté 3>]])"
 
-#: builtin/read-tree.c:121
+#: builtin/read-tree.c:120
 msgid "write resulting index to <file>"
 msgstr "écrire l'index résultant dans <fichier>"
 
-#: builtin/read-tree.c:124
+#: builtin/read-tree.c:123
 msgid "only empty the index"
 msgstr "juste vider l'index"
 
-#: builtin/read-tree.c:126
+#: builtin/read-tree.c:125
 msgid "Merging"
 msgstr "Fusion"
 
-#: builtin/read-tree.c:128
+#: builtin/read-tree.c:127
 msgid "perform a merge in addition to a read"
 msgstr "effectuer une fusion en plus d'une lecture"
 
-#: builtin/read-tree.c:130
+#: builtin/read-tree.c:129
 msgid "3-way merge if no file level merging required"
 msgstr "fusion à 3 points si aucune fusion de niveau fichier n'est requise"
 
-#: builtin/read-tree.c:132
+#: builtin/read-tree.c:131
 msgid "3-way merge in presence of adds and removes"
 msgstr "fusion à 3 points en présence d'ajouts et suppressions"
 
-#: builtin/read-tree.c:134
+#: builtin/read-tree.c:133
 msgid "same as -m, but discard unmerged entries"
 msgstr "comme -m, mais annule les éléments non fusionnés"
 
-#: builtin/read-tree.c:135
+#: builtin/read-tree.c:134
 msgid "<subdirectory>/"
 msgstr "<sous-répertoire>/"
 
-#: builtin/read-tree.c:136
+#: builtin/read-tree.c:135
 msgid "read the tree into the index under <subdirectory>/"
 msgstr "lire l'arbre dans l'index dans <sous-répertoire>/"
 
-#: builtin/read-tree.c:139
+#: builtin/read-tree.c:138
 msgid "update working tree with merge result"
 msgstr "mettre à jour la copie de travail avec le résultat de la fusion"
 
-#: builtin/read-tree.c:141
+#: builtin/read-tree.c:140
 msgid "gitignore"
 msgstr "gitignore"
 
-#: builtin/read-tree.c:142
+#: builtin/read-tree.c:141
 msgid "allow explicitly ignored files to be overwritten"
 msgstr "autoriser explicitement les fichiers ignorés à être écrasés"
 
-#: builtin/read-tree.c:145
+#: builtin/read-tree.c:144
 msgid "don't check the working tree after merging"
 msgstr "ne pas vérifier la copie de travail après la fusion"
 
-#: builtin/read-tree.c:146
+#: builtin/read-tree.c:145
 msgid "don't update the index or the work tree"
 msgstr "ne pas mettre à jour l'index ou la copie de travail"
 
-#: builtin/read-tree.c:148
+#: builtin/read-tree.c:147
 msgid "skip applying sparse checkout filter"
 msgstr "sauter l'application du filtre d'extraction creuse"
 
-#: builtin/read-tree.c:150
+#: builtin/read-tree.c:149
 msgid "debug unpack-trees"
 msgstr "déboguer unpack-trees"
 
@@ -12457,46 +12949,58 @@ msgid "allow commits with empty messages"
 msgstr "autoriser les validations avec des messages vides"
 
 #: builtin/rebase--helper.c:27
+msgid "rebase merge commits"
+msgstr "rebaser les commits de fusion"
+
+#: builtin/rebase--helper.c:29
+msgid "keep original branch points of cousins"
+msgstr "conserver les points de branchement de cousins originaux"
+
+#: builtin/rebase--helper.c:30
 msgid "continue rebase"
 msgstr "continuer le rebasage"
 
-#: builtin/rebase--helper.c:29
+#: builtin/rebase--helper.c:32
 msgid "abort rebase"
 msgstr "abandonner le rebasage"
 
-#: builtin/rebase--helper.c:32
+#: builtin/rebase--helper.c:35
 msgid "make rebase script"
 msgstr "créer les script de rebasage"
 
-#: builtin/rebase--helper.c:34
+#: builtin/rebase--helper.c:37
 msgid "shorten commit ids in the todo list"
 msgstr "raccourcir les identifiants de commits dans la liste à-faire"
 
-#: builtin/rebase--helper.c:36
+#: builtin/rebase--helper.c:39
 msgid "expand commit ids in the todo list"
 msgstr "étendre les identifiants de commit dans la liste à-faire"
 
-#: builtin/rebase--helper.c:38
+#: builtin/rebase--helper.c:41
 msgid "check the todo list"
 msgstr "vérifier la liste à-faire"
 
-#: builtin/rebase--helper.c:40
+#: builtin/rebase--helper.c:43
 msgid "skip unnecessary picks"
 msgstr "éviter les commandes de picorage non nécessaires"
 
-#: builtin/rebase--helper.c:42
+#: builtin/rebase--helper.c:45
 msgid "rearrange fixup/squash lines"
 msgstr "réarranger les lignes fixup/squash"
 
-#: builtin/rebase--helper.c:44
+#: builtin/rebase--helper.c:47
 msgid "insert exec commands in todo list"
 msgstr "insérer les commandes exec dans la liste à-faire"
 
-#: builtin/receive-pack.c:30
+#: builtin/rebase--helper.c:68
+msgid "--[no-]rebase-cousins has no effect without --rebase-merges"
+msgstr "--[no-]rebase-cousins n'a aucun effet sans --rebase-merges"
+
+#: builtin/receive-pack.c:31
 msgid "git receive-pack <git-dir>"
 msgstr "git receive-pack <répertoire-git>"
 
-#: builtin/receive-pack.c:841
+#: builtin/receive-pack.c:842
 msgid ""
 "By default, updating the current branch in a non-bare repository\n"
 "is denied, because it will make the index and work tree inconsistent\n"
@@ -12526,7 +13030,7 @@ msgstr ""
 "Pour éliminer ce message et conserver le comportement par défaut,\n"
 "réglez « receive.denyCurrentBranch » à 'refuse'."
 
-#: builtin/receive-pack.c:861
+#: builtin/receive-pack.c:862
 msgid ""
 "By default, deleting the current branch is denied, because the next\n"
 "'git clone' won't result in any file checked out, causing confusion.\n"
@@ -12546,11 +13050,11 @@ msgstr ""
 "\n"
 "Pour éliminer ce message, réglez-le à 'refuse'."
 
-#: builtin/receive-pack.c:1934
+#: builtin/receive-pack.c:1935
 msgid "quiet"
 msgstr "quiet"
 
-#: builtin/receive-pack.c:1948
+#: builtin/receive-pack.c:1949
 msgid "You must specify a directory."
 msgstr "Vous devez spécifier un répertoire."
 
@@ -12559,11 +13063,11 @@ msgstr "Vous devez spécifier un répertoire."
 msgid "'%s' is not a valid timestamp"
 msgstr "'%s' n'est pas un horodatage valide"
 
-#: builtin/remote.c:13
+#: builtin/remote.c:14
 msgid "git remote [-v | --verbose]"
 msgstr "git remote [-v | --verbose]"
 
-#: builtin/remote.c:14
+#: builtin/remote.c:15
 msgid ""
 "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <name> <url>"
@@ -12571,83 +13075,83 @@ msgstr ""
 "git remote add [-t <branche>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <nom> <url>"
 
-#: builtin/remote.c:15 builtin/remote.c:35
+#: builtin/remote.c:16 builtin/remote.c:36
 msgid "git remote rename <old> <new>"
 msgstr "git remote rename <ancienne> <nouvelle>"
 
-#: builtin/remote.c:16 builtin/remote.c:40
+#: builtin/remote.c:17 builtin/remote.c:41
 msgid "git remote remove <name>"
 msgstr "git remote remove <nom>"
 
-#: builtin/remote.c:17 builtin/remote.c:45
+#: builtin/remote.c:18 builtin/remote.c:46
 msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
 msgstr "git remote set-head <nom> (-a | --auto | -d | --delete | <branche>)"
 
-#: builtin/remote.c:18
+#: builtin/remote.c:19
 msgid "git remote [-v | --verbose] show [-n] <name>"
 msgstr "git remote [-v | --verbose] show [-n] <nom>"
 
-#: builtin/remote.c:19
+#: builtin/remote.c:20
 msgid "git remote prune [-n | --dry-run] <name>"
 msgstr "git remote prune [-n | --dry-run] <nom>"
 
-#: builtin/remote.c:20
+#: builtin/remote.c:21
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
 msgstr ""
 "git remote [-v | --verbose] update [-p | --prune] [(<groupe> | "
 "<distante>)...]"
 
-#: builtin/remote.c:21
+#: builtin/remote.c:22
 msgid "git remote set-branches [--add] <name> <branch>..."
 msgstr "git remote set-branches [--add] <nom> <branche>..."
 
-#: builtin/remote.c:22 builtin/remote.c:71
+#: builtin/remote.c:23 builtin/remote.c:72
 msgid "git remote get-url [--push] [--all] <name>"
 msgstr "git remote get-url [--push] [--all] <nom>"
 
-#: builtin/remote.c:23 builtin/remote.c:76
+#: builtin/remote.c:24 builtin/remote.c:77
 msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]"
 msgstr "git remote set-url [--push] <nom> <nouvelle-URL> [<ancienne-URL>]"
 
-#: builtin/remote.c:24 builtin/remote.c:77
+#: builtin/remote.c:25 builtin/remote.c:78
 msgid "git remote set-url --add <name> <newurl>"
 msgstr "git remote set-url --add <nom> <nouvelle-URL>"
 
-#: builtin/remote.c:25 builtin/remote.c:78
+#: builtin/remote.c:26 builtin/remote.c:79
 msgid "git remote set-url --delete <name> <url>"
 msgstr "git remote set-url --delete <nom> <URL>"
 
-#: builtin/remote.c:30
+#: builtin/remote.c:31
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<options>] <nom> <URL>"
 
-#: builtin/remote.c:50
+#: builtin/remote.c:51
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <nom> <branche>..."
 
-#: builtin/remote.c:51
+#: builtin/remote.c:52
 msgid "git remote set-branches --add <name> <branch>..."
 msgstr "git remote set-branches --add <nom> <branche>..."
 
-#: builtin/remote.c:56
+#: builtin/remote.c:57
 msgid "git remote show [<options>] <name>"
 msgstr "git remote show [<options>] <nom>"
 
-#: builtin/remote.c:61
+#: builtin/remote.c:62
 msgid "git remote prune [<options>] <name>"
 msgstr "git remote prune [<options>] <nom>"
 
-#: builtin/remote.c:66
+#: builtin/remote.c:67
 msgid "git remote update [<options>] [<group> | <remote>]..."
 msgstr "git remote update [<options>] [<groupe> | <distante>]..."
 
-#: builtin/remote.c:95
+#: builtin/remote.c:96
 #, c-format
 msgid "Updating %s"
 msgstr "Mise à jour de %s"
 
-#: builtin/remote.c:127
+#: builtin/remote.c:128
 msgid ""
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
@@ -12655,92 +13159,92 @@ msgstr ""
 "--mirror est dangereux et obsolète ; merci\n"
 "\t d'utiliser --mirror=fetch ou --mirror=push à la place"
 
-#: builtin/remote.c:144
+#: builtin/remote.c:145
 #, c-format
 msgid "unknown mirror argument: %s"
 msgstr "argument miroir inconnu : %s"
 
-#: builtin/remote.c:160
+#: builtin/remote.c:161
 msgid "fetch the remote branches"
 msgstr "rapatrier les branches distantes"
 
-#: builtin/remote.c:162
+#: builtin/remote.c:163
 msgid "import all tags and associated objects when fetching"
 msgstr ""
 "importer toutes les étiquettes et les objets associés lors du rapatriement"
 
-#: builtin/remote.c:165
+#: builtin/remote.c:166
 msgid "or do not fetch any tag at all (--no-tags)"
 msgstr "ou ne rapatrier aucune étiquette (--no-tags)"
 
-#: builtin/remote.c:167
+#: builtin/remote.c:168
 msgid "branch(es) to track"
 msgstr "branche(s) à suivre"
 
-#: builtin/remote.c:168
+#: builtin/remote.c:169
 msgid "master branch"
 msgstr "branche maîtresse"
 
-#: builtin/remote.c:169
+#: builtin/remote.c:170
 msgid "push|fetch"
 msgstr "push|fetch"
 
-#: builtin/remote.c:170
+#: builtin/remote.c:171
 msgid "set up remote as a mirror to push to or fetch from"
 msgstr ""
 "paramétrer la distante comme miroir pour pousser ou pour rapatrier depuis"
 
-#: builtin/remote.c:182
+#: builtin/remote.c:183
 msgid "specifying a master branch makes no sense with --mirror"
 msgstr "spécifier une branche maîtresse n'a pas de sens avec --mirror"
 
-#: builtin/remote.c:184
+#: builtin/remote.c:185
 msgid "specifying branches to track makes sense only with fetch mirrors"
 msgstr ""
 "spécifier les branches à suivre n'a de sens qu'avec des miroirs de "
 "rapatriement"
 
-#: builtin/remote.c:191 builtin/remote.c:631
+#: builtin/remote.c:192 builtin/remote.c:634
 #, c-format
 msgid "remote %s already exists."
 msgstr "la distante %s existe déjà."
 
-#: builtin/remote.c:195 builtin/remote.c:635
+#: builtin/remote.c:196 builtin/remote.c:638
 #, c-format
 msgid "'%s' is not a valid remote name"
 msgstr "'%s' n'est pas un nom valide de distante"
 
-#: builtin/remote.c:235
+#: builtin/remote.c:236
 #, c-format
 msgid "Could not setup master '%s'"
 msgstr "Impossible de paramétrer la maîtresse '%s'"
 
-#: builtin/remote.c:337
+#: builtin/remote.c:342
 #, c-format
 msgid "Could not get fetch map for refspec %s"
 msgstr ""
 "Impossible d'obtenir une correspondance distante pour la spécification de "
 "référence %s"
 
-#: builtin/remote.c:438 builtin/remote.c:446
+#: builtin/remote.c:441 builtin/remote.c:449
 msgid "(matching)"
 msgstr "(correspond)"
 
-#: builtin/remote.c:450
+#: builtin/remote.c:453
 msgid "(delete)"
 msgstr "(supprimer)"
 
-#: builtin/remote.c:624 builtin/remote.c:759 builtin/remote.c:858
+#: builtin/remote.c:627 builtin/remote.c:762 builtin/remote.c:861
 #, c-format
 msgid "No such remote: %s"
 msgstr "Distante inconnue : %s"
 
-#: builtin/remote.c:641
+#: builtin/remote.c:644
 #, c-format
 msgid "Could not rename config section '%s' to '%s'"
 msgstr "Impossible de renommer la section de configuration '%s' en '%s'"
 
-#: builtin/remote.c:661
+#: builtin/remote.c:664
 #, c-format
 msgid ""
 "Not updating non-default fetch refspec\n"
@@ -12751,17 +13255,17 @@ msgstr ""
 "\t%s\n"
 "\tVeuillez mettre à jour la configuration manuellement si nécessaire."
 
-#: builtin/remote.c:697
+#: builtin/remote.c:700
 #, c-format
 msgid "deleting '%s' failed"
 msgstr "échec de suppression de '%s'"
 
-#: builtin/remote.c:731
+#: builtin/remote.c:734
 #, c-format
 msgid "creating '%s' failed"
 msgstr "échec de création de '%s'"
 
-#: builtin/remote.c:796
+#: builtin/remote.c:799
 msgid ""
 "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
 "to delete it, use:"
@@ -12776,113 +13280,118 @@ msgstr[1] ""
 "supprimées ;\n"
 "pour les supprimer, utilisez :"
 
-#: builtin/remote.c:810
+#: builtin/remote.c:813
 #, c-format
 msgid "Could not remove config section '%s'"
 msgstr "Impossible de supprimer la section de configuration '%s'"
 
-#: builtin/remote.c:911
+#: builtin/remote.c:914
 #, c-format
 msgid " new (next fetch will store in remotes/%s)"
 msgstr " nouveau (le prochain rapatriement (fetch) stockera dans remotes/%s)"
 
-#: builtin/remote.c:914
+#: builtin/remote.c:917
 msgid " tracked"
 msgstr " suivi"
 
-#: builtin/remote.c:916
+#: builtin/remote.c:919
 msgid " stale (use 'git remote prune' to remove)"
 msgstr " dépassé (utilisez 'git remote prune' pour supprimer)"
 
-#: builtin/remote.c:918
+#: builtin/remote.c:921
 msgid " ???"
 msgstr " ???"
 
-#: builtin/remote.c:959
+#: builtin/remote.c:962
 #, c-format
 msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
 msgstr "branch.%s.merge invalide ; ne peut pas rebaser sur plus d'une branche"
 
-#: builtin/remote.c:967
+#: builtin/remote.c:971
 #, c-format
 msgid "rebases interactively onto remote %s"
 msgstr "rebase de manière interactive sur la distante %s"
 
-#: builtin/remote.c:968
+#: builtin/remote.c:973
+#, c-format
+msgid "rebases interactively (with merges) onto remote %s"
+msgstr "rebase de manière interactive (avec fusions) sur la distante %s"
+
+#: builtin/remote.c:976
 #, c-format
 msgid "rebases onto remote %s"
 msgstr "rebase sur la distante %s"
 
-#: builtin/remote.c:971
+#: builtin/remote.c:980
 #, c-format
 msgid " merges with remote %s"
 msgstr " fusionne avec la distante %s"
 
-#: builtin/remote.c:974
+#: builtin/remote.c:983
 #, c-format
 msgid "merges with remote %s"
 msgstr "fusionne avec la distante %s"
 
-#: builtin/remote.c:977
+#: builtin/remote.c:986
 #, c-format
 msgid "%-*s    and with remote %s\n"
 msgstr "%-*s    et avec la distante %s\n"
 
-#: builtin/remote.c:1020
+#: builtin/remote.c:1029
 msgid "create"
 msgstr "créer"
 
-#: builtin/remote.c:1023
+#: builtin/remote.c:1032
 msgid "delete"
 msgstr "supprimer"
 
-#: builtin/remote.c:1027
+#: builtin/remote.c:1036
 msgid "up to date"
 msgstr "à jour"
 
-#: builtin/remote.c:1030
+#: builtin/remote.c:1039
 msgid "fast-forwardable"
 msgstr "peut être mis à jour en avance rapide"
 
-#: builtin/remote.c:1033
+#: builtin/remote.c:1042
 msgid "local out of date"
 msgstr "le local n'est pas à jour"
 
-#: builtin/remote.c:1040
+#: builtin/remote.c:1049
 #, c-format
 msgid "    %-*s forces to %-*s (%s)"
 msgstr "    %-*s force vers %-*s (%s)"
 
-#: builtin/remote.c:1043
+#: builtin/remote.c:1052
 #, c-format
 msgid "    %-*s pushes to %-*s (%s)"
 msgstr "    %-*s pousse vers %-*s (%s)"
 
-#: builtin/remote.c:1047
+#: builtin/remote.c:1056
 #, c-format
 msgid "    %-*s forces to %s"
 msgstr "    %-*s force vers %s"
 
-#: builtin/remote.c:1050
+#: builtin/remote.c:1059
 #, c-format
 msgid "    %-*s pushes to %s"
 msgstr "    %-*s pousse vers %s"
 
-#: builtin/remote.c:1118
+#: builtin/remote.c:1127
 msgid "do not query remotes"
 msgstr "ne pas interroger les distantes"
 
-#: builtin/remote.c:1145
+#: builtin/remote.c:1154
 #, c-format
 msgid "* remote %s"
 msgstr "* distante %s"
 
-#: builtin/remote.c:1146
+#: builtin/remote.c:1155
 #, c-format
 msgid "  Fetch URL: %s"
 msgstr "  URL de rapatriement : %s"
 
-#: builtin/remote.c:1147 builtin/remote.c:1163 builtin/remote.c:1302
+#: builtin/remote.c:1156 builtin/remote.c:1172 builtin/remote.c:1311
 msgid "(no URL)"
 msgstr "(pas d'URL)"
 
@@ -12890,25 +13399,25 @@ msgstr "(pas d'URL)"
 #. with the one in " Fetch URL: %s"
 #. translation.
 #.
-#: builtin/remote.c:1161 builtin/remote.c:1163
+#: builtin/remote.c:1170 builtin/remote.c:1172
 #, c-format
 msgid "  Push  URL: %s"
 msgstr "  URL push : %s"
 
-#: builtin/remote.c:1165 builtin/remote.c:1167 builtin/remote.c:1169
+#: builtin/remote.c:1174 builtin/remote.c:1176 builtin/remote.c:1178
 #, c-format
 msgid "  HEAD branch: %s"
 msgstr "  Branche HEAD : %s"
 
-#: builtin/remote.c:1165
+#: builtin/remote.c:1174
 msgid "(not queried)"
 msgstr "(non demandé)"
 
-#: builtin/remote.c:1167
+#: builtin/remote.c:1176
 msgid "(unknown)"
 msgstr "(inconnu)"
 
-#: builtin/remote.c:1171
+#: builtin/remote.c:1180
 #, c-format
 msgid ""
 "  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
@@ -12916,162 +13425,162 @@ msgstr ""
 "  Branche HEAD (la HEAD distante est ambiguë, peut être l'une des "
 "suivantes) :\n"
 
-#: builtin/remote.c:1183
+#: builtin/remote.c:1192
 #, c-format
 msgid "  Remote branch:%s"
 msgid_plural "  Remote branches:%s"
 msgstr[0] "  Branche distante :%s"
 msgstr[1] "  Branches distantes :%s"
 
-#: builtin/remote.c:1186 builtin/remote.c:1212
+#: builtin/remote.c:1195 builtin/remote.c:1221
 msgid " (status not queried)"
 msgstr " (état non demandé)"
 
-#: builtin/remote.c:1195
+#: builtin/remote.c:1204
 msgid "  Local branch configured for 'git pull':"
 msgid_plural "  Local branches configured for 'git pull':"
 msgstr[0] "  Branche locale configurée pour 'git pull' :"
 msgstr[1] "  Branches locales configurées pour 'git pull' :"
 
-#: builtin/remote.c:1203
+#: builtin/remote.c:1212
 msgid "  Local refs will be mirrored by 'git push'"
 msgstr "  Les références locales seront reflétées par 'git push'"
 
-#: builtin/remote.c:1209
+#: builtin/remote.c:1218
 #, c-format
 msgid "  Local ref configured for 'git push'%s:"
 msgid_plural "  Local refs configured for 'git push'%s:"
 msgstr[0] "  Référence locale configurée pour 'git push'%s :"
 msgstr[1] "  Références locales configurées pour 'git push'%s :"
 
-#: builtin/remote.c:1230
+#: builtin/remote.c:1239
 msgid "set refs/remotes/<name>/HEAD according to remote"
 msgstr "définir refs/remotes/<nom>/HEAD selon la distante"
 
-#: builtin/remote.c:1232
+#: builtin/remote.c:1241
 msgid "delete refs/remotes/<name>/HEAD"
 msgstr "supprimer refs/remotes/<nom>/HEAD"
 
-#: builtin/remote.c:1247
+#: builtin/remote.c:1256
 msgid "Cannot determine remote HEAD"
 msgstr "Impossible de déterminer la HEAD distante"
 
-#: builtin/remote.c:1249
+#: builtin/remote.c:1258
 msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
 msgstr ""
 "Il y a de multiples branches HEAD distantes. Veuillez en choisir une "
 "explicitement avec :"
 
-#: builtin/remote.c:1259
+#: builtin/remote.c:1268
 #, c-format
 msgid "Could not delete %s"
 msgstr "Impossible de supprimer %s"
 
-#: builtin/remote.c:1267
+#: builtin/remote.c:1276
 #, c-format
 msgid "Not a valid ref: %s"
 msgstr "Référence non valide : %s"
 
-#: builtin/remote.c:1269
+#: builtin/remote.c:1278
 #, c-format
 msgid "Could not setup %s"
 msgstr "Impossible de paramétrer %s"
 
-#: builtin/remote.c:1287
+#: builtin/remote.c:1296
 #, c-format
 msgid " %s will become dangling!"
 msgstr " %s se retrouvera en suspens !"
 
-#: builtin/remote.c:1288
+#: builtin/remote.c:1297
 #, c-format
 msgid " %s has become dangling!"
 msgstr " %s se retrouve en suspens !"
 
-#: builtin/remote.c:1298
+#: builtin/remote.c:1307
 #, c-format
 msgid "Pruning %s"
 msgstr "Élimination de %s"
 
-#: builtin/remote.c:1299
+#: builtin/remote.c:1308
 #, c-format
 msgid "URL: %s"
 msgstr "URL : %s"
 
-#: builtin/remote.c:1315
+#: builtin/remote.c:1324
 #, c-format
 msgid " * [would prune] %s"
 msgstr " * [serait éliminé] %s"
 
-#: builtin/remote.c:1318
+#: builtin/remote.c:1327
 #, c-format
 msgid " * [pruned] %s"
 msgstr " * [éliminé] %s"
 
-#: builtin/remote.c:1363
+#: builtin/remote.c:1372
 msgid "prune remotes after fetching"
 msgstr "éliminer les distants après le rapatriement"
 
-#: builtin/remote.c:1426 builtin/remote.c:1480 builtin/remote.c:1548
+#: builtin/remote.c:1435 builtin/remote.c:1489 builtin/remote.c:1557
 #, c-format
 msgid "No such remote '%s'"
 msgstr "Pas de serveur remote '%s'"
 
-#: builtin/remote.c:1442
+#: builtin/remote.c:1451
 msgid "add branch"
 msgstr "ajouter une branche"
 
-#: builtin/remote.c:1449
+#: builtin/remote.c:1458
 msgid "no remote specified"
 msgstr "pas de serveur distant spécifié"
 
-#: builtin/remote.c:1466
+#: builtin/remote.c:1475
 msgid "query push URLs rather than fetch URLs"
 msgstr "interroger les URLs de poussée plutôt que les URLs de récupération"
 
-#: builtin/remote.c:1468
+#: builtin/remote.c:1477
 msgid "return all URLs"
 msgstr "retourner toutes les URLs"
 
-#: builtin/remote.c:1496
+#: builtin/remote.c:1505
 #, c-format
 msgid "no URLs configured for remote '%s'"
 msgstr "aucune URL configurée pour le dépôt distant '%s'"
 
-#: builtin/remote.c:1522
+#: builtin/remote.c:1531
 msgid "manipulate push URLs"
 msgstr "manipuler les URLs push"
 
-#: builtin/remote.c:1524
+#: builtin/remote.c:1533
 msgid "add URL"
 msgstr "ajouter une URL"
 
-#: builtin/remote.c:1526
+#: builtin/remote.c:1535
 msgid "delete URLs"
 msgstr "supprimer des URLs"
 
-#: builtin/remote.c:1533
+#: builtin/remote.c:1542
 msgid "--add --delete doesn't make sense"
 msgstr "--add --delete n'a aucun sens"
 
-#: builtin/remote.c:1572
+#: builtin/remote.c:1581
 #, c-format
 msgid "Invalid old URL pattern: %s"
 msgstr "Motif d'URL ancien invalide : %s"
 
-#: builtin/remote.c:1580
+#: builtin/remote.c:1589
 #, c-format
 msgid "No such URL found: %s"
 msgstr "Pas d'URL trouvée : %s"
 
-#: builtin/remote.c:1582
+#: builtin/remote.c:1591
 msgid "Will not delete all non-push URLs"
 msgstr "Pas de suppression de toutes les URLs non-push"
 
-#: builtin/remote.c:1598
+#: builtin/remote.c:1607
 msgid "be verbose; must be placed before a subcommand"
 msgstr "être verbeux : doit être placé avant une sous-commande"
 
-#: builtin/remote.c:1629
+#: builtin/remote.c:1638
 #, c-format
 msgid "Unknown subcommand: %s"
 msgstr "Sous-commande inconnue : %s"
@@ -13089,128 +13598,136 @@ msgstr ""
 "Utilisez\n"
 "--no-write-bitmap-index ou désactivez le paramètre pack.writebitmaps."
 
-#: builtin/repack.c:170
+#: builtin/repack.c:180
 msgid "pack everything in a single pack"
 msgstr "empaqueter tout dans un seul paquet"
 
-#: builtin/repack.c:172
+#: builtin/repack.c:182
 msgid "same as -a, and turn unreachable objects loose"
 msgstr "identique à -a et transformer les objets inaccessibles en suspens"
 
-#: builtin/repack.c:175
+#: builtin/repack.c:185
 msgid "remove redundant packs, and run git-prune-packed"
 msgstr "supprimer les paquets redondants et lancer git-prune-packed"
 
-#: builtin/repack.c:177
+#: builtin/repack.c:187
 msgid "pass --no-reuse-delta to git-pack-objects"
 msgstr "passer --no-reuse-delta à git-pack-objects"
 
-#: builtin/repack.c:179
+#: builtin/repack.c:189
 msgid "pass --no-reuse-object to git-pack-objects"
 msgstr "passer --no-reuse-object à git-pack-objects"
 
-#: builtin/repack.c:181
+#: builtin/repack.c:191
 msgid "do not run git-update-server-info"
 msgstr "ne pas lancer git update-server-info"
 
-#: builtin/repack.c:184
+#: builtin/repack.c:194
 msgid "pass --local to git-pack-objects"
 msgstr "passer --local à git-pack-objects"
 
-#: builtin/repack.c:186
+#: builtin/repack.c:196
 msgid "write bitmap index"
 msgstr "écrire un index en bitmap"
 
-#: builtin/repack.c:187
+#: builtin/repack.c:197
 msgid "approxidate"
 msgstr "date approximative"
 
-#: builtin/repack.c:188
+#: builtin/repack.c:198
 msgid "with -A, do not loosen objects older than this"
 msgstr "avec -A, ne pas suspendre les objets plus vieux que celui-ci"
 
-#: builtin/repack.c:190
+#: builtin/repack.c:200
 msgid "with -a, repack unreachable objects"
 msgstr "avec -a, repaquétiser les objets inaccessibles"
 
-#: builtin/repack.c:192
+#: builtin/repack.c:202
 msgid "size of the window used for delta compression"
 msgstr "taille de la fenêtre utilisée pour la compression des deltas"
 
-#: builtin/repack.c:193 builtin/repack.c:199
+#: builtin/repack.c:203 builtin/repack.c:209
 msgid "bytes"
 msgstr "octets"
 
-#: builtin/repack.c:194
+#: builtin/repack.c:204
 msgid "same as the above, but limit memory size instead of entries count"
 msgstr ""
 "idem ci-dessus, mais limiter la taille mémoire au lieu du nombre d'éléments"
 
-#: builtin/repack.c:196
+#: builtin/repack.c:206
 msgid "limits the maximum delta depth"
 msgstr "limite la profondeur maximale des deltas"
 
-#: builtin/repack.c:198
+#: builtin/repack.c:208
 msgid "limits the maximum number of threads"
 msgstr "limite le nombre maximal de fils"
 
-#: builtin/repack.c:200
+#: builtin/repack.c:210
 msgid "maximum size of each packfile"
 msgstr "taille maximum de chaque fichier paquet"
 
-#: builtin/repack.c:202
+#: builtin/repack.c:212
 msgid "repack objects in packs marked with .keep"
 msgstr "réempaqueter les objets dans des paquets marqués avec .keep"
 
-#: builtin/repack.c:212
+#: builtin/repack.c:214
+msgid "do not repack this pack"
+msgstr "ne pas rempaqueter ce paquet"
+
+#: builtin/repack.c:224
 msgid "cannot delete packs in a precious-objects repo"
 msgstr "impossible de supprimer les paquets dans un dépôt d'objets précieux"
 
-#: builtin/repack.c:216
+#: builtin/repack.c:228
 msgid "--keep-unreachable and -A are incompatible"
 msgstr "--keep-unreachable et -A sont incompatibles"
 
-#: builtin/repack.c:410 builtin/worktree.c:148
+#: builtin/repack.c:425 builtin/worktree.c:139
 #, c-format
 msgid "failed to remove '%s'"
 msgstr "échec de la suppression de '%s'"
 
-#: builtin/replace.c:20
+#: builtin/replace.c:22
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <objet> <remplacement>"
 
-#: builtin/replace.c:21
+#: builtin/replace.c:23
 msgid "git replace [-f] --edit <object>"
 msgstr "git replace [-f] --edit <objet>"
 
-#: builtin/replace.c:22
+#: builtin/replace.c:24
 msgid "git replace [-f] --graft <commit> [<parent>...]"
 msgstr "git replace [-f] --graft <commit> [<parent>...]"
 
-#: builtin/replace.c:23
+#: builtin/replace.c:25
+msgid "git replace [-f] --convert-graft-file"
+msgstr "git replace [-f] --convert-graft-file"
+
+#: builtin/replace.c:26
 msgid "git replace -d <object>..."
 msgstr "git replace -d <objet>..."
 
-#: builtin/replace.c:24
+#: builtin/replace.c:27
 msgid "git replace [--format=<format>] [-l [<pattern>]]"
 msgstr "git replace [--format=<format>] [-l [<motif>]]"
 
-#: builtin/replace.c:331 builtin/replace.c:369 builtin/replace.c:397
+#: builtin/replace.c:371 builtin/replace.c:415 builtin/replace.c:445
 #, c-format
 msgid "Not a valid object name: '%s'"
 msgstr "Nom d'objet invalide : '%s'"
 
-#: builtin/replace.c:361
+#: builtin/replace.c:407
 #, c-format
 msgid "bad mergetag in commit '%s'"
 msgstr "mauvaise étiquette de fusion dans le commit '%s'"
 
-#: builtin/replace.c:363
+#: builtin/replace.c:409
 #, c-format
 msgid "malformed mergetag in commit '%s'"
 msgstr "étiquette de fusion malformée dans le commit '%s'"
 
-#: builtin/replace.c:374
+#: builtin/replace.c:421
 #, c-format
 msgid ""
 "original commit '%s' contains mergetag '%s' that is discarded; use --edit "
@@ -13219,45 +13736,58 @@ msgstr ""
 "le commit original '%s' contient l'étiquette de fusion '%s' qui a disparu ; "
 "utilisez --edit au lieu de --graft"
 
-#: builtin/replace.c:407
+#: builtin/replace.c:460
 #, c-format
 msgid "the original commit '%s' has a gpg signature."
 msgstr "le commit original '%s' contient une signature GPG."
 
-#: builtin/replace.c:408
+#: builtin/replace.c:461
 msgid "the signature will be removed in the replacement commit!"
 msgstr "la signature sera éliminée dans la validation de remplacement !"
 
-#: builtin/replace.c:414
+#: builtin/replace.c:471
 #, c-format
 msgid "could not write replacement commit for: '%s'"
 msgstr "Impossible d'écrire le commit de remplacement pour '%s'"
 
-#: builtin/replace.c:438
+#: builtin/replace.c:514
+#, c-format
+msgid ""
+"could not convert the following graft(s):\n"
+"%s"
+msgstr ""
+"impossible de convertir la(les) greffe(s) suivante(s) :\n"
+"%s"
+
+#: builtin/replace.c:535
 msgid "list replace refs"
 msgstr "afficher les références de remplacement"
 
-#: builtin/replace.c:439
+#: builtin/replace.c:536
 msgid "delete replace refs"
 msgstr "supprimer les références de remplacement"
 
-#: builtin/replace.c:440
+#: builtin/replace.c:537
 msgid "edit existing object"
 msgstr "éditer l'objet existant"
 
-#: builtin/replace.c:441
+#: builtin/replace.c:538
 msgid "change a commit's parents"
 msgstr "Modifier les parents d'un commit"
 
-#: builtin/replace.c:442
+#: builtin/replace.c:539
+msgid "convert existing graft file"
+msgstr "convertir le fichier de greffe existant"
+
+#: builtin/replace.c:540
 msgid "replace the ref if it exists"
 msgstr "remplacer la référence si elle existe"
 
-#: builtin/replace.c:444
+#: builtin/replace.c:542
 msgid "do not pretty-print contents for --edit"
 msgstr "afficher sans mise en forme pour --edit"
 
-#: builtin/replace.c:445
+#: builtin/replace.c:543
 msgid "use this format"
 msgstr "utiliser ce format"
 
@@ -13421,23 +13951,23 @@ msgstr "rev-list ne supporte l'affichage des notes"
 msgid "cannot combine --use-bitmap-index with object filtering"
 msgstr "impossible de combiner --use-bitmap-index avec le filtrage d'objet"
 
-#: builtin/rev-parse.c:402
+#: builtin/rev-parse.c:406
 msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
 msgstr "git rev-parse --parseopt [<options>] -- [<arguments>...]"
 
-#: builtin/rev-parse.c:407
+#: builtin/rev-parse.c:411
 msgid "keep the `--` passed as an arg"
 msgstr "garder le `--` passé en argument"
 
-#: builtin/rev-parse.c:409
+#: builtin/rev-parse.c:413
 msgid "stop parsing after the first non-option argument"
 msgstr "arrêt de l'analyse après le premier argument qui n'est pas une option"
 
-#: builtin/rev-parse.c:412
+#: builtin/rev-parse.c:416
 msgid "output in stuck long form"
 msgstr "sortie en forme longue fixée"
 
-#: builtin/rev-parse.c:545
+#: builtin/rev-parse.c:549
 msgid ""
 "git rev-parse --parseopt [<options>] -- [<args>...]\n"
 "   or: git rev-parse --sq-quote [<arg>...]\n"
@@ -13579,42 +14109,42 @@ msgid_plural "the following files have local modifications:"
 msgstr[0] "le fichier suivant a des modifications locales :"
 msgstr[1] "les fichiers suivants ont des modifications locales :"
 
-#: builtin/rm.c:243
+#: builtin/rm.c:241
 msgid "do not list removed files"
 msgstr "ne pas afficher les fichiers supprimés"
 
-#: builtin/rm.c:244
+#: builtin/rm.c:242
 msgid "only remove from the index"
 msgstr "supprimer seulement de l'index"
 
-#: builtin/rm.c:245
+#: builtin/rm.c:243
 msgid "override the up-to-date check"
 msgstr "outrepasser la vérification des fichiers à jour"
 
-#: builtin/rm.c:246
+#: builtin/rm.c:244
 msgid "allow recursive removal"
 msgstr "autoriser la suppression récursive"
 
-#: builtin/rm.c:248
+#: builtin/rm.c:246
 msgid "exit with a zero status even if nothing matched"
 msgstr "sortir avec un état zéro même si rien ne correspondait"
 
-#: builtin/rm.c:307
+#: builtin/rm.c:306
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "pas de suppression récursive de '%s' sans -r"
 
-#: builtin/rm.c:346
+#: builtin/rm.c:345
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm : impossible de supprimer %s"
 
-#: builtin/rm.c:369
+#: builtin/rm.c:368
 #, c-format
 msgid "could not remove '%s'"
 msgstr "impossible de supprimer '%s'"
 
-#: builtin/send-pack.c:19
+#: builtin/send-pack.c:20
 msgid ""
 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-"
 "receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> "
@@ -13627,52 +14157,72 @@ msgstr ""
 "  --all et la spécification explicite de <référence> sont mutuellement "
 "exclusifs."
 
-#: builtin/send-pack.c:162
+#: builtin/send-pack.c:163
 msgid "remote name"
 msgstr "nom distant"
 
-#: builtin/send-pack.c:176
+#: builtin/send-pack.c:177
 msgid "use stateless RPC protocol"
 msgstr "utiliser un protocole RPC sans état"
 
-#: builtin/send-pack.c:177
+#: builtin/send-pack.c:178
 msgid "read refs from stdin"
 msgstr "lire les références depuis l'entrée standard"
 
-#: builtin/send-pack.c:178
+#: builtin/send-pack.c:179
 msgid "print status from remote helper"
 msgstr "afficher les messages du greffon de protocole distant"
 
+#: builtin/serve.c:7
+msgid "git serve [<options>]"
+msgstr "git serve [<options>]"
+
+#: builtin/serve.c:17 builtin/upload-pack.c:23
+msgid "quit after a single request/response exchange"
+msgstr "quitter après un unique échange requête/réponse"
+
+#: builtin/serve.c:19
+msgid "exit immediately after advertising capabilities"
+msgstr "sortir immédiatement après l'annonce des capacités"
+
 #: builtin/shortlog.c:14
-msgid "git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"
-msgstr "git shortlog [<options>] [<intervalle-révisions>] [[--] [<chemin>...]]"
+msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]"
+msgstr "git shortlog [<options>] [<intervalle-révisions>] [[--] <chemin>...]"
 
-#: builtin/shortlog.c:263
+#: builtin/shortlog.c:15
+msgid "git log --pretty=short | git shortlog [<options>]"
+msgstr "git log --pretty=short | git shortlog [<options>]"
+
+#: builtin/shortlog.c:264
 msgid "Group by committer rather than author"
 msgstr "Grouper par validateur plutôt que par auteur"
 
-#: builtin/shortlog.c:265
+#: builtin/shortlog.c:266
 msgid "sort output according to the number of commits per author"
 msgstr "trier la sortie sur le nombre de validations par auteur"
 
-#: builtin/shortlog.c:267
+#: builtin/shortlog.c:268
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr ""
 "Supprimer les descriptions de validation, fournit seulement le nombre de "
 "validations"
 
-#: builtin/shortlog.c:269
+#: builtin/shortlog.c:270
 msgid "Show the email address of each author"
 msgstr "Afficher l'adresse courriel de chaque auteur"
 
-#: builtin/shortlog.c:270
+#: builtin/shortlog.c:271
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:271
+#: builtin/shortlog.c:272
 msgid "Linewrap output"
 msgstr "Couper les lignes"
 
+#: builtin/shortlog.c:298
+msgid "too many arguments given outside repository"
+msgstr "trop d'arguments fournis hors d'un dépôt"
+
 #: builtin/show-branch.c:12
 msgid ""
 "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
@@ -13878,39 +14428,39 @@ msgstr ""
 msgid "prepend comment character and space to each line"
 msgstr "ajouter devant chaque ligne le caractère de commentaire et un espace"
 
-#: builtin/submodule--helper.c:35 builtin/submodule--helper.c:1669
+#: builtin/submodule--helper.c:37 builtin/submodule--helper.c:1688
 #, c-format
 msgid "No such ref: %s"
 msgstr "Référence inexistante : %s"
 
-#: builtin/submodule--helper.c:42 builtin/submodule--helper.c:1678
+#: builtin/submodule--helper.c:44 builtin/submodule--helper.c:1697
 #, c-format
 msgid "Expecting a full ref name, got %s"
 msgstr "Nom de référence complet attendu, %s obtenu"
 
-#: builtin/submodule--helper.c:59
+#: builtin/submodule--helper.c:61
 msgid "submodule--helper print-default-remote takes no arguments"
 msgstr "submodule--helper  print-default-remote n'accepte aucun argument"
 
-#: builtin/submodule--helper.c:96
+#: builtin/submodule--helper.c:98
 #, c-format
 msgid "cannot strip one component off url '%s'"
 msgstr "impossible de supprimer un composant de l'URL '%s'"
 
-#: builtin/submodule--helper.c:404 builtin/submodule--helper.c:1198
+#: builtin/submodule--helper.c:406 builtin/submodule--helper.c:1211
 msgid "alternative anchor for relative paths"
 msgstr "ancre alternative pour les chemins relatifs"
 
-#: builtin/submodule--helper.c:409
+#: builtin/submodule--helper.c:411
 msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper list [--prefix=<chemin>] [<chemin>...]"
 
-#: builtin/submodule--helper.c:460 builtin/submodule--helper.c:483
+#: builtin/submodule--helper.c:462 builtin/submodule--helper.c:485
 #, c-format
 msgid "No url found for submodule path '%s' in .gitmodules"
 msgstr "URL non trouvée pour le chemin de sous-module '%s' dans .gitmodules"
 
-#: builtin/submodule--helper.c:498
+#: builtin/submodule--helper.c:500
 #, c-format
 msgid ""
 "could not lookup configuration '%s'. Assuming this repository is its own "
@@ -13919,60 +14469,60 @@ msgstr ""
 "impossible de trouver la configuration '%s'. Ce dépôt est considéré comme "
 "son propre amont d'autorité."
 
-#: builtin/submodule--helper.c:509
+#: builtin/submodule--helper.c:511
 #, c-format
 msgid "Failed to register url for submodule path '%s'"
 msgstr "Échec d'enregistrement de l'URL pour le chemin de sous-module '%s'"
 
-#: builtin/submodule--helper.c:513
+#: builtin/submodule--helper.c:515
 #, c-format
 msgid "Submodule '%s' (%s) registered for path '%s'\n"
 msgstr "Sous-module '%s' (%s) enregistré pour le chemin '%s'\n"
 
-#: builtin/submodule--helper.c:523
+#: builtin/submodule--helper.c:525
 #, c-format
 msgid "warning: command update mode suggested for submodule '%s'\n"
 msgstr ""
 "attention : nous vous suggérons de spécifier une commande de mode de mise à "
 "jour pour le sous-module '%s'\n"
 
-#: builtin/submodule--helper.c:530
+#: builtin/submodule--helper.c:532
 #, c-format
 msgid "Failed to register update mode for submodule path '%s'"
 msgstr ""
 "Échec d'enregistrement du mode de mise à jour pour le chemin de sous-module "
 "'%s'"
 
-#: builtin/submodule--helper.c:552
+#: builtin/submodule--helper.c:554
 msgid "Suppress output for initializing a submodule"
 msgstr "Supprimer la sortie lors de l'initialisation d'un sous-module"
 
-#: builtin/submodule--helper.c:557
+#: builtin/submodule--helper.c:559
 msgid "git submodule--helper init [<path>]"
 msgstr "git submodule--helper init [<chemin>]"
 
-#: builtin/submodule--helper.c:625 builtin/submodule--helper.c:747
+#: builtin/submodule--helper.c:631 builtin/submodule--helper.c:757
 #, c-format
 msgid "no submodule mapping found in .gitmodules for path '%s'"
 msgstr ""
 "Pas de mise en correspondance du sous-module trouvé dans .gitmodules pour le "
 "chemin '%s'"
 
-#: builtin/submodule--helper.c:660
+#: builtin/submodule--helper.c:670
 #, c-format
 msgid "could not resolve HEAD ref inside the submodule '%s'"
 msgstr "impossible de résoudre HEAD dans le sous-module '%s'"
 
-#: builtin/submodule--helper.c:687 builtin/submodule--helper.c:856
+#: builtin/submodule--helper.c:697 builtin/submodule--helper.c:866
 #, c-format
 msgid "failed to recurse into submodule '%s'"
 msgstr "récursion impossible dans le sous-module '%s'"
 
-#: builtin/submodule--helper.c:711 builtin/submodule--helper.c:1021
+#: builtin/submodule--helper.c:721 builtin/submodule--helper.c:1031
 msgid "Suppress submodule status output"
 msgstr "supprimer la sortie d'état du sous-module"
 
-#: builtin/submodule--helper.c:712
+#: builtin/submodule--helper.c:722
 msgid ""
 "Use commit stored in the index instead of the one stored in the submodule "
 "HEAD"
@@ -13980,139 +14530,148 @@ msgstr ""
 "Utiliser le commit stocké dans l'index au lieu de celui stocké dans la HEAD "
 "du sous-module"
 
-#: builtin/submodule--helper.c:713
+#: builtin/submodule--helper.c:723
 msgid "recurse into nested submodules"
 msgstr "parcourir récursivement les sous-modules"
 
-#: builtin/submodule--helper.c:718
+#: builtin/submodule--helper.c:728
 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
 msgstr "git submodule status [--quiet] [--cached] [--recursive] [<chemin>...]"
 
-#: builtin/submodule--helper.c:742
+#: builtin/submodule--helper.c:752
 msgid "git submodule--helper name <path>"
 msgstr "git submodule--helper <nom> <chemin>"
 
-#: builtin/submodule--helper.c:806
+#: builtin/submodule--helper.c:816
 #, c-format
 msgid "Synchronizing submodule url for '%s'\n"
 msgstr "Synchronisation de l'URL sous-module pour '%s'\n"
 
-#: builtin/submodule--helper.c:812
+#: builtin/submodule--helper.c:822
 #, c-format
 msgid "failed to register url for submodule path '%s'"
 msgstr "échec d'enregistrement de l'URL pour le chemin de sous-module '%s'"
 
-#: builtin/submodule--helper.c:826
+#: builtin/submodule--helper.c:836
 #, c-format
 msgid "failed to get the default remote for submodule '%s'"
 msgstr "échec d'obtention du dépôt distant par défaut pour le sous-module '%s'"
 
-#: builtin/submodule--helper.c:837
+#: builtin/submodule--helper.c:847
 #, c-format
 msgid "failed to update remote for submodule '%s'"
 msgstr "échec de mise à jour du dépôt distant pour le sous-module '%s'"
 
-#: builtin/submodule--helper.c:885
+#: builtin/submodule--helper.c:895
 msgid "Suppress output of synchronizing submodule url"
-msgstr "Supprimer la sortie lors de la synchronisation de l'URL d'un sous-module"
+msgstr ""
+"Supprimer la sortie lors de la synchronisation de l'URL d'un sous-module"
 
-#: builtin/submodule--helper.c:887
+#: builtin/submodule--helper.c:897
 msgid "Recurse into nested submodules"
 msgstr "Parcourir récursivement les sous-modules"
 
-#: builtin/submodule--helper.c:892
+#: builtin/submodule--helper.c:902
 msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
 msgstr "git submodule--helper sync [--quiet] [--recursive] [<chemin>]"
 
-#: builtin/submodule--helper.c:946
+#: builtin/submodule--helper.c:956
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you "
 "really want to remove it including all of its history)"
-msgstr "L'arbre de travail du sous-module '%s' contient un répertoire .git (utilisez 'rm -rf' si vous voulez vraiment le supprimer en incluant tout son historique)"
+msgstr ""
+"L'arbre de travail du sous-module '%s' contient un répertoire .git (utilisez "
+"'rm -rf' si vous voulez vraiment le supprimer en incluant tout son "
+"historique)"
 
-#: builtin/submodule--helper.c:958
+#: builtin/submodule--helper.c:968
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains local modifications; use '-f' to discard "
 "them"
-msgstr "L'arbre de travail du sous-module '%s' contient des modifications locales ; utilisez '-f' pour les annuler"
+msgstr ""
+"L'arbre de travail du sous-module '%s' contient des modifications locales ; "
+"utilisez '-f' pour les annuler"
 
-#: builtin/submodule--helper.c:966
+#: builtin/submodule--helper.c:976
 #, c-format
 msgid "Cleared directory '%s'\n"
 msgstr "Répertoire '%s' nettoyé\n"
 
-#: builtin/submodule--helper.c:968
+#: builtin/submodule--helper.c:978
 #, c-format
 msgid "Could not remove submodule work tree '%s'\n"
 msgstr "Impossible de supprimer l'arbre de travail du sous-module '%s'\n"
 
-#: builtin/submodule--helper.c:977
+#: builtin/submodule--helper.c:987
 #, c-format
 msgid "could not create empty submodule directory %s"
 msgstr "impossible de créer le répertoire vide du sous-module %s"
 
-#: builtin/submodule--helper.c:993
+#: builtin/submodule--helper.c:1003
 #, c-format
 msgid "Submodule '%s' (%s) unregistered for path '%s'\n"
 msgstr "Sous-module '%s' (%s) non enregistré pour le chemin '%s'\n"
 
-#: builtin/submodule--helper.c:1022
+#: builtin/submodule--helper.c:1032
 msgid "Remove submodule working trees even if they contain local changes"
-msgstr "Éliminer les arbres de travail des sous-modules même s'ils contiennent des modifications locales"
+msgstr ""
+"Éliminer les arbres de travail des sous-modules même s'ils contiennent des "
+"modifications locales"
 
-#: builtin/submodule--helper.c:1023
+#: builtin/submodule--helper.c:1033
 msgid "Unregister all submodules"
 msgstr "Désenregistrer tous les sous-modules"
 
-#: builtin/submodule--helper.c:1028
+#: builtin/submodule--helper.c:1038
 msgid ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
-msgstr "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<chemin>...]]"
+msgstr ""
+"git submodule deinit [--quiet] [-f | --force] [--all | [--] [<chemin>...]]"
 
-#: builtin/submodule--helper.c:1042
+#: builtin/submodule--helper.c:1052
 msgid "Use '--all' if you really want to deinitialize all submodules"
 msgstr ""
 "Utilisez '--all' si vous voulez vraiment réinitialiser tous les sous-modules"
 
-#: builtin/submodule--helper.c:1133 builtin/submodule--helper.c:1136
+#: builtin/submodule--helper.c:1145 builtin/submodule--helper.c:1148
 #, c-format
 msgid "submodule '%s' cannot add alternate: %s"
 msgstr "le sous-module '%s' ne peut pas ajouter d'alternative : %s"
 
-#: builtin/submodule--helper.c:1172
+#: builtin/submodule--helper.c:1184
 #, c-format
 msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized"
 msgstr ""
 "La valeur '%s' pour submodule.alternateErrorStrategy n'est pas reconnue"
 
-#: builtin/submodule--helper.c:1179
+#: builtin/submodule--helper.c:1191
 #, c-format
 msgid "Value '%s' for submodule.alternateLocation is not recognized"
 msgstr "La valeur '%s' pour submodule.alternateLocation n'est pas reconnue"
 
-#: builtin/submodule--helper.c:1201
+#: builtin/submodule--helper.c:1214
 msgid "where the new submodule will be cloned to"
 msgstr "emplacement où le sous-module sera cloné"
 
-#: builtin/submodule--helper.c:1204
+#: builtin/submodule--helper.c:1217
 msgid "name of the new submodule"
 msgstr "nom du nouveau sous-module"
 
-#: builtin/submodule--helper.c:1207
+#: builtin/submodule--helper.c:1220
 msgid "url where to clone the submodule from"
 msgstr "URL depuis laquelle cloner le sous-module"
 
-#: builtin/submodule--helper.c:1213
+#: builtin/submodule--helper.c:1228
 msgid "depth for shallow clones"
 msgstr "profondeur de l'historique des clones superficiels"
 
-#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1587
+#: builtin/submodule--helper.c:1231 builtin/submodule--helper.c:1606
 msgid "force cloning progress"
 msgstr "forcer l'affichage de la progression du clonage"
 
-#: builtin/submodule--helper.c:1221
+#: builtin/submodule--helper.c:1236
 msgid ""
 "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
 "<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>"
@@ -14120,83 +14679,83 @@ msgstr ""
 "git submodule--helper clone [--prefix=<chemin>] [--quiet] [--reference "
 "<dépôt>] [--name <nom>] [--depth <profondeur>]  --url <url> --path <chemin>"
 
-#: builtin/submodule--helper.c:1252
+#: builtin/submodule--helper.c:1267
 #, c-format
 msgid "clone of '%s' into submodule path '%s' failed"
 msgstr "Le clonage de '%s' dans le chemin de sous-module '%s' a échoué"
 
-#: builtin/submodule--helper.c:1267
+#: builtin/submodule--helper.c:1281
 #, c-format
 msgid "could not get submodule directory for '%s'"
 msgstr "impossible de créer le répertoire de sous-module pour '%s'"
 
-#: builtin/submodule--helper.c:1332
+#: builtin/submodule--helper.c:1347
 #, c-format
 msgid "Submodule path '%s' not initialized"
 msgstr "Le chemin de sous-module '%s' n'est pas initialisé"
 
-#: builtin/submodule--helper.c:1336
+#: builtin/submodule--helper.c:1351
 msgid "Maybe you want to use 'update --init'?"
 msgstr "Vous voudriez sûrement utiliser 'update --init' ?"
 
-#: builtin/submodule--helper.c:1365
+#: builtin/submodule--helper.c:1380
 #, c-format
 msgid "Skipping unmerged submodule %s"
 msgstr "Sous-module non fusionné %s non traité"
 
-#: builtin/submodule--helper.c:1394
+#: builtin/submodule--helper.c:1409
 #, c-format
 msgid "Skipping submodule '%s'"
 msgstr "Sous-module '%s' non traité"
 
-#: builtin/submodule--helper.c:1527
+#: builtin/submodule--helper.c:1544
 #, c-format
 msgid "Failed to clone '%s'. Retry scheduled"
 msgstr "Impossible de cloner '%s'. Réessai prévu"
 
-#: builtin/submodule--helper.c:1538
+#: builtin/submodule--helper.c:1555
 #, c-format
 msgid "Failed to clone '%s' a second time, aborting"
 msgstr "Impossible de cloner '%s' pour la seconde fois, abandon"
 
-#: builtin/submodule--helper.c:1568 builtin/submodule--helper.c:1788
+#: builtin/submodule--helper.c:1585 builtin/submodule--helper.c:1808
 msgid "path into the working tree"
 msgstr "chemin dans la copie de travail"
 
-#: builtin/submodule--helper.c:1571
+#: builtin/submodule--helper.c:1588
 msgid "path into the working tree, across nested submodule boundaries"
 msgstr ""
 "chemin dans la copie de travail, traversant les frontières de sous-modules"
 
-#: builtin/submodule--helper.c:1575
+#: builtin/submodule--helper.c:1592
 msgid "rebase, merge, checkout or none"
 msgstr "valeurs possibles : rebase, merge, checkout ou none"
 
-#: builtin/submodule--helper.c:1579
+#: builtin/submodule--helper.c:1598
 msgid "Create a shallow clone truncated to the specified number of revisions"
 msgstr "Créer un clone superficiel tronqué au nombre de révisions spécifié"
 
-#: builtin/submodule--helper.c:1582
+#: builtin/submodule--helper.c:1601
 msgid "parallel jobs"
 msgstr "jobs parallèles"
 
-#: builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1603
 msgid "whether the initial clone should follow the shallow recommendation"
 msgstr "spécifie si le clonage initial doit être aussi superficiel"
 
-#: builtin/submodule--helper.c:1585
+#: builtin/submodule--helper.c:1604
 msgid "don't print cloning progress"
 msgstr "ne pas afficher la progression du clonage"
 
-#: builtin/submodule--helper.c:1592
+#: builtin/submodule--helper.c:1611
 msgid "git submodule--helper update_clone [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper update_clone [--prefix=<chemin>] [<chemin>...]"
 
-#: builtin/submodule--helper.c:1605
+#: builtin/submodule--helper.c:1624
 msgid "bad value for update parameter"
 msgstr "valeur invalide pour la mise à jour du paramètre"
 
-#: builtin/submodule--helper.c:1673
+#: builtin/submodule--helper.c:1692
 #, c-format
 msgid ""
 "Submodule (%s) branch configured to inherit branch from superproject, but "
@@ -14205,20 +14764,20 @@ msgstr ""
 "la branche du sous-module %s est configurée pour hériter de la branche du "
 "superprojet, mais le superprojet n'est sur aucune branche"
 
-#: builtin/submodule--helper.c:1789
+#: builtin/submodule--helper.c:1809
 msgid "recurse into submodules"
 msgstr "parcourir récursivement les sous-modules"
 
-#: builtin/submodule--helper.c:1795
+#: builtin/submodule--helper.c:1815
 msgid "git submodule--helper embed-git-dir [<path>...]"
 msgstr "git submodule--helper embed-git-dir [<chemin>...]"
 
-#: builtin/submodule--helper.c:1857
+#: builtin/submodule--helper.c:1901
 #, c-format
 msgid "%s doesn't support --super-prefix"
 msgstr "%s ne gère pas --super-prefix"
 
-#: builtin/submodule--helper.c:1863
+#: builtin/submodule--helper.c:1907
 #, c-format
 msgid "'%s' is not a valid submodule--helper subcommand"
 msgstr "'%s' n'est pas une sous-commande valide de submodule--helper"
@@ -14288,7 +14847,7 @@ msgstr "étiquette '%s' non trouvée."
 msgid "Deleted tag '%s' (was %s)\n"
 msgstr "Étiquette '%s' supprimée (elle était sur %s)\n"
 
-#: builtin/tag.c:131
+#: builtin/tag.c:132
 #, c-format
 msgid ""
 "\n"
@@ -14301,7 +14860,7 @@ msgstr ""
 "  %s\n"
 "Les lignes commençant par '%c' seront ignorées.\n"
 
-#: builtin/tag.c:135
+#: builtin/tag.c:136
 #, c-format
 msgid ""
 "\n"
@@ -14316,147 +14875,147 @@ msgstr ""
 "Les lignes commençant par '%c' seront gardées ; vous pouvez les retirer vous-"
 "même si vous le souhaitez.\n"
 
-#: builtin/tag.c:189
+#: builtin/tag.c:190
 msgid "unable to sign the tag"
 msgstr "impossible de signer l'étiquette"
 
-#: builtin/tag.c:191
+#: builtin/tag.c:192
 msgid "unable to write tag file"
 msgstr "impossible d'écrire le fichier d'étiquettes"
 
-#: builtin/tag.c:216
+#: builtin/tag.c:217
 msgid "bad object type."
 msgstr "mauvais type d'objet."
 
-#: builtin/tag.c:265
+#: builtin/tag.c:266
 msgid "no tag message?"
 msgstr "pas de message pour l'étiquette ?"
 
-#: builtin/tag.c:272
+#: builtin/tag.c:273
 #, c-format
 msgid "The tag message has been left in %s\n"
 msgstr "Le message pour l'étiquette a été laissé dans %s\n"
 
-#: builtin/tag.c:381
+#: builtin/tag.c:382
 msgid "list tag names"
 msgstr "afficher les noms des étiquettes"
 
-#: builtin/tag.c:383
+#: builtin/tag.c:384
 msgid "print <n> lines of each tag message"
 msgstr "affiche <n> lignes de chaque message d'étiquette"
 
-#: builtin/tag.c:385
+#: builtin/tag.c:386
 msgid "delete tags"
 msgstr "supprimer des étiquettes"
 
-#: builtin/tag.c:386
+#: builtin/tag.c:387
 msgid "verify tags"
 msgstr "vérifier des étiquettes"
 
-#: builtin/tag.c:388
+#: builtin/tag.c:389
 msgid "Tag creation options"
 msgstr "Options de création de l'étiquette"
 
-#: builtin/tag.c:390
+#: builtin/tag.c:391
 msgid "annotated tag, needs a message"
 msgstr "étiquette annotée, nécessite un message"
 
-#: builtin/tag.c:392
+#: builtin/tag.c:393
 msgid "tag message"
 msgstr "message pour l'étiquette"
 
-#: builtin/tag.c:394
+#: builtin/tag.c:395
 msgid "force edit of tag message"
 msgstr "forcer l'édition du message d'étiquetage"
 
-#: builtin/tag.c:395
+#: builtin/tag.c:396
 msgid "annotated and GPG-signed tag"
 msgstr "étiquette annotée et signée avec GPG"
 
-#: builtin/tag.c:399
+#: builtin/tag.c:400
 msgid "use another key to sign the tag"
 msgstr "utiliser une autre clé pour signer l'étiquette"
 
-#: builtin/tag.c:400
+#: builtin/tag.c:401
 msgid "replace the tag if exists"
 msgstr "remplacer l'étiquette si elle existe"
 
-#: builtin/tag.c:401 builtin/update-ref.c:368
+#: builtin/tag.c:402 builtin/update-ref.c:368
 msgid "create a reflog"
 msgstr "créer un reflog"
 
-#: builtin/tag.c:403
+#: builtin/tag.c:404
 msgid "Tag listing options"
 msgstr "Options d'affichage des étiquettes"
 
-#: builtin/tag.c:404
+#: builtin/tag.c:405
 msgid "show tag list in columns"
 msgstr "afficher la liste des étiquettes sous forme de colonnes"
 
-#: builtin/tag.c:405 builtin/tag.c:407
+#: builtin/tag.c:406 builtin/tag.c:408
 msgid "print only tags that contain the commit"
 msgstr "afficher seulement les étiquettes qui contiennent la validation"
 
-#: builtin/tag.c:406 builtin/tag.c:408
+#: builtin/tag.c:407 builtin/tag.c:409
 msgid "print only tags that don't contain the commit"
 msgstr "afficher seulement les étiquettes qui ne contiennent pas la validation"
 
-#: builtin/tag.c:409
+#: builtin/tag.c:410
 msgid "print only tags that are merged"
 msgstr "afficher seulement les étiquettes qui sont fusionnées"
 
-#: builtin/tag.c:410
+#: builtin/tag.c:411
 msgid "print only tags that are not merged"
 msgstr "afficher seulement les étiquettes qui ne sont pas fusionnées"
 
-#: builtin/tag.c:415
+#: builtin/tag.c:416
 msgid "print only tags of the object"
 msgstr "afficher seulement les étiquettes de l'objet"
 
-#: builtin/tag.c:459
+#: builtin/tag.c:460
 msgid "--column and -n are incompatible"
 msgstr "--column et -n sont incompatibles"
 
-#: builtin/tag.c:481
+#: builtin/tag.c:482
 msgid "-n option is only allowed in list mode"
 msgstr "l'option -n est autorisée seulement en mode de liste"
 
-#: builtin/tag.c:483
+#: builtin/tag.c:484
 msgid "--contains option is only allowed in list mode"
 msgstr "l'option --contains est autorisée seulement en mode de liste"
 
-#: builtin/tag.c:485
+#: builtin/tag.c:486
 msgid "--no-contains option is only allowed in list mode"
 msgstr "l'option --contains est autorisée seulement en mode liste"
 
-#: builtin/tag.c:487
+#: builtin/tag.c:488
 msgid "--points-at option is only allowed in list mode"
 msgstr "l'option --points-at est autorisée seulement en mode liste"
 
-#: builtin/tag.c:489
+#: builtin/tag.c:490
 msgid "--merged and --no-merged options are only allowed in list mode"
 msgstr ""
 "les options --merged et --no-merged ne sont autorisées qu'en mode liste"
 
-#: builtin/tag.c:500
+#: builtin/tag.c:501
 msgid "only one -F or -m option is allowed."
 msgstr "une seule option -F ou -m est autorisée."
 
-#: builtin/tag.c:519
+#: builtin/tag.c:520
 msgid "too many params"
 msgstr "trop de paramètres"
 
-#: builtin/tag.c:525
+#: builtin/tag.c:526
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "'%s' n'est pas un nom d'étiquette valide."
 
-#: builtin/tag.c:530
+#: builtin/tag.c:531
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "l'étiquette '%s' existe déjà"
 
-#: builtin/tag.c:561
+#: builtin/tag.c:562
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "Étiquette '%s' mise à jour (elle était sur %s)\n"
@@ -14532,148 +15091,148 @@ msgstr ""
 msgid " OK"
 msgstr " OK"
 
-#: builtin/update-index.c:579
+#: builtin/update-index.c:589
 msgid "git update-index [<options>] [--] [<file>...]"
 msgstr "git update-index [<options>] [--] [<fichier>...]"
 
-#: builtin/update-index.c:936
+#: builtin/update-index.c:946
 msgid "continue refresh even when index needs update"
 msgstr "continuer de rafraîchir même si l'index a besoin d'une mise à jour"
 
-#: builtin/update-index.c:939
+#: builtin/update-index.c:949
 msgid "refresh: ignore submodules"
 msgstr "rafraîchir : ignorer les sous-modules"
 
-#: builtin/update-index.c:942
+#: builtin/update-index.c:952
 msgid "do not ignore new files"
 msgstr "ne pas ignorer les nouveaux fichiers"
 
-#: builtin/update-index.c:944
+#: builtin/update-index.c:954
 msgid "let files replace directories and vice-versa"
 msgstr "laisser les fichiers remplacer des répertoires et vice-versa"
 
-#: builtin/update-index.c:946
+#: builtin/update-index.c:956
 msgid "notice files missing from worktree"
 msgstr "aviser des fichiers manquants dans la copie de travail"
 
-#: builtin/update-index.c:948
+#: builtin/update-index.c:958
 msgid "refresh even if index contains unmerged entries"
 msgstr "rafraîchir même si l'index contient des éléments non fusionnés"
 
-#: builtin/update-index.c:951
+#: builtin/update-index.c:961
 msgid "refresh stat information"
 msgstr "rafraîchir l'information de stat"
 
-#: builtin/update-index.c:955
+#: builtin/update-index.c:965
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "comme --refresh, mais en ignorant l'option assume-unchanged"
 
-#: builtin/update-index.c:959
+#: builtin/update-index.c:969
 msgid "<mode>,<object>,<path>"
 msgstr "<mode>, <objet>, <chemin>"
 
-#: builtin/update-index.c:960
+#: builtin/update-index.c:970
 msgid "add the specified entry to the index"
 msgstr "ajouter l'élément spécifié dans l'index"
 
-#: builtin/update-index.c:969
+#: builtin/update-index.c:979
 msgid "mark files as \"not changing\""
 msgstr "marquer les fichiers comme \"non changeants\""
 
-#: builtin/update-index.c:972
+#: builtin/update-index.c:982
 msgid "clear assumed-unchanged bit"
 msgstr "mettre à zéro le bit supposé-non-modifié"
 
-#: builtin/update-index.c:975
+#: builtin/update-index.c:985
 msgid "mark files as \"index-only\""
 msgstr "marquer les fichiers comme \"index seulement\""
 
-#: builtin/update-index.c:978
+#: builtin/update-index.c:988
 msgid "clear skip-worktree bit"
 msgstr "mettre à zéro le bit sauter-la-copie-de travail"
 
-#: builtin/update-index.c:981
+#: builtin/update-index.c:991
 msgid "add to index only; do not add content to object database"
 msgstr ""
 "ajouter seulement à l'index ; ne pas ajouter le contenu dans la base de "
 "données des objets"
 
-#: builtin/update-index.c:983
+#: builtin/update-index.c:993
 msgid "remove named paths even if present in worktree"
 msgstr ""
 "supprimer les chemins nommés même s'ils sont présents dans la copie de "
 "travail"
 
-#: builtin/update-index.c:985
+#: builtin/update-index.c:995
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr "avec --stdin : les lignes en entrée sont terminées par des octets nuls"
 
-#: builtin/update-index.c:987
+#: builtin/update-index.c:997
 msgid "read list of paths to be updated from standard input"
 msgstr "lire la liste des chemins à mettre à jour depuis l'entrée standard"
 
-#: builtin/update-index.c:991
+#: builtin/update-index.c:1001
 msgid "add entries from standard input to the index"
 msgstr "ajouter les éléments depuis l'entrée standard à l'index"
 
-#: builtin/update-index.c:995
+#: builtin/update-index.c:1005
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr "repeupler les étapes n°2 et n°3 pour les chemins listés"
 
-#: builtin/update-index.c:999
+#: builtin/update-index.c:1009
 msgid "only update entries that differ from HEAD"
 msgstr "mettre à jour seulement les éléments qui diffèrent de HEAD"
 
-#: builtin/update-index.c:1003
+#: builtin/update-index.c:1013
 msgid "ignore files missing from worktree"
 msgstr "ignorer les fichiers manquants dans la copie de travail"
 
-#: builtin/update-index.c:1006
+#: builtin/update-index.c:1016
 msgid "report actions to standard output"
 msgstr "afficher les actions sur la sortie standard"
 
-#: builtin/update-index.c:1008
+#: builtin/update-index.c:1018
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "(pour porcelaines) oublier les conflits sauvés et non résolus"
 
-#: builtin/update-index.c:1012
+#: builtin/update-index.c:1022
 msgid "write index in this format"
 msgstr "écrire l'index dans ce format"
 
-#: builtin/update-index.c:1014
+#: builtin/update-index.c:1024
 msgid "enable or disable split index"
 msgstr "activer ou désactiver l'index divisé"
 
-#: builtin/update-index.c:1016
+#: builtin/update-index.c:1026
 msgid "enable/disable untracked cache"
 msgstr "activer ou désactiver le cache de non-suivis"
 
-#: builtin/update-index.c:1018
+#: builtin/update-index.c:1028
 msgid "test if the filesystem supports untracked cache"
 msgstr "tester si le système de fichier supporte le cache de non-suivis"
 
-#: builtin/update-index.c:1020
+#: builtin/update-index.c:1030
 msgid "enable untracked cache without testing the filesystem"
 msgstr "activer le cache de non-suivis sans tester le système de fichier"
 
-#: builtin/update-index.c:1022
+#: builtin/update-index.c:1032
 msgid "write out the index even if is not flagged as changed"
 msgstr "écrire l'index même s'il n'est pas marqué comme modifié"
 
-#: builtin/update-index.c:1024
+#: builtin/update-index.c:1034
 msgid "enable or disable file system monitor"
 msgstr ""
 "activer ou désactiver la surveillance du système de fichier (fsmonitor)"
 
-#: builtin/update-index.c:1026
+#: builtin/update-index.c:1036
 msgid "mark files as fsmonitor valid"
 msgstr "marquer les fichiers comme valides pour fsmonitor"
 
-#: builtin/update-index.c:1029
+#: builtin/update-index.c:1039
 msgid "clear fsmonitor valid bit"
 msgstr "effacer le bit de validité fsmonitor"
 
-#: builtin/update-index.c:1127
+#: builtin/update-index.c:1138
 msgid ""
 "core.splitIndex is set to false; remove or change it, if you really want to "
 "enable split index"
@@ -14681,7 +15240,7 @@ msgstr ""
 "core.splitIndex est réglé à false ; supprimez-le ou changez-le si vous "
 "souhaitez vraiment activer l'index coupé"
 
-#: builtin/update-index.c:1136
+#: builtin/update-index.c:1147
 msgid ""
 "core.splitIndex is set to true; remove or change it, if you really want to "
 "disable split index"
@@ -14689,7 +15248,7 @@ msgstr ""
 "core.splitIndex est réglé à vrai ; supprimez-le ou changez-le si vous "
 "souhaitez vraiment désactiver l'index coupé"
 
-#: builtin/update-index.c:1147
+#: builtin/update-index.c:1158
 msgid ""
 "core.untrackedCache is set to true; remove or change it, if you really want "
 "to disable the untracked cache"
@@ -14697,11 +15256,11 @@ msgstr ""
 "core.untrackedCache est réglé à true ; supprimez-le ou changez-le si vous "
 "souhaitez vraiment désactiver le cache des fichiers non-suivis"
 
-#: builtin/update-index.c:1151
+#: builtin/update-index.c:1162
 msgid "Untracked cache disabled"
 msgstr "Le cache non suivi est désactivé"
 
-#: builtin/update-index.c:1159
+#: builtin/update-index.c:1170
 msgid ""
 "core.untrackedCache is set to false; remove or change it, if you really want "
 "to enable the untracked cache"
@@ -14709,29 +15268,29 @@ msgstr ""
 "core.untrackedCache est réglé à false ; supprimez-le ou changez-le si vous "
 "souhaitez vraiment activer le cache des fichiers non-suivis"
 
-#: builtin/update-index.c:1163
+#: builtin/update-index.c:1174
 #, c-format
 msgid "Untracked cache enabled for '%s'"
 msgstr "Le cache non suivi est activé pour '%s'"
 
-#: builtin/update-index.c:1171
+#: builtin/update-index.c:1182
 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
 msgstr ""
 "core.fsmonitor est réglé à false ; changez-le si vous souhaitez vraiment "
 "activer la surveillance du système de fichiers"
 
-#: builtin/update-index.c:1175
+#: builtin/update-index.c:1186
 msgid "fsmonitor enabled"
 msgstr "fsmonitor activé"
 
-#: builtin/update-index.c:1178
+#: builtin/update-index.c:1189
 msgid ""
 "core.fsmonitor is set; remove it if you really want to disable fsmonitor"
 msgstr ""
 "core.fsmonitor est réglé à true ; supprimez-le ou changez-le si vous "
 "souhaitez vraiment désactiver la surveillance du système de fichiers"
 
-#: builtin/update-index.c:1182
+#: builtin/update-index.c:1193
 msgid "fsmonitor disabled"
 msgstr "fsmonitor désactivé"
 
@@ -14773,8 +15332,26 @@ msgstr "git update-server-info [--force]"
 msgid "update the info files from scratch"
 msgstr "mettre à jour les fichiers d'information à partir de zéro"
 
-#: builtin/verify-commit.c:18
-msgid "git verify-commit [-v | --verbose] <commit>..."
+#: builtin/upload-pack.c:11
+msgid "git upload-pack [<options>] <dir>"
+msgstr "git upload-pack [<options>] <répertoire>"
+
+#: builtin/upload-pack.c:25
+msgid "exit immediately after initial ref advertisement"
+msgstr "Sortir immédiatement après l'annonce initiale des références"
+
+#: builtin/upload-pack.c:27
+msgid "do not try <directory>/.git/ if <directory> is no Git directory"
+msgstr ""
+"nes pas essayer <répertoire>/.git/ si <répertoire> n'est pas un répertoire "
+"Git"
+
+#: builtin/upload-pack.c:29
+msgid "interrupt transfer after <n> seconds of inactivity"
+msgstr "interrompre le transfert après <n> secondes d'inactivité"
+
+#: builtin/verify-commit.c:18
+msgid "git verify-commit [-v | --verbose] <commit>..."
 msgstr "git verify-commit [-v | --verbose] <commit>..."
 
 #: builtin/verify-commit.c:73
@@ -14833,23 +15410,23 @@ msgstr "git worktree remove [<options>] <arbre-de-travail>"
 msgid "git worktree unlock <path>"
 msgstr "git worktree unlock <chemin>"
 
-#: builtin/worktree.c:60
+#: builtin/worktree.c:58
 #, c-format
 msgid "Removing worktrees/%s: not a valid directory"
 msgstr "Suppression de worktrees/%s : répertoire invalide"
 
-#: builtin/worktree.c:66
+#: builtin/worktree.c:64
 #, c-format
 msgid "Removing worktrees/%s: gitdir file does not exist"
 msgstr "Suppression de worktrees/%s : le fichier gitdir n'existe pas"
 
-#: builtin/worktree.c:71 builtin/worktree.c:80
+#: builtin/worktree.c:69 builtin/worktree.c:78
 #, c-format
 msgid "Removing worktrees/%s: unable to read gitdir file (%s)"
 msgstr ""
 "Suppression de worktrees/%s : echec de la lecture du fichier gitdir (%s)"
 
-#: builtin/worktree.c:90
+#: builtin/worktree.c:88
 #, c-format
 msgid ""
 "Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read "
@@ -14858,185 +15435,209 @@ msgstr ""
 "Suppression de worktrees/%s: lecture trop courte ( %<PRIuMAX> octets "
 "attendus, %<PRIuMAX> octets lus)"
 
-#: builtin/worktree.c:98
+#: builtin/worktree.c:96
 #, c-format
 msgid "Removing worktrees/%s: invalid gitdir file"
 msgstr "Suppression de worktrees/%s : fichier gitdir invalide"
 
-#: builtin/worktree.c:114
+#: builtin/worktree.c:105
 #, c-format
 msgid "Removing worktrees/%s: gitdir file points to non-existent location"
 msgstr ""
 "Suppression de worktrees/%s : le fichier gitdir point sur un endroit "
 "inexistant"
 
-#: builtin/worktree.c:161
+#: builtin/worktree.c:152
 msgid "report pruned working trees"
 msgstr "afficher les arbres de travail éliminés"
 
-#: builtin/worktree.c:163
+#: builtin/worktree.c:154
 msgid "expire working trees older than <time>"
 msgstr "faire expirer les arbres de travail plus vieux que <temps>"
 
-#: builtin/worktree.c:238
+#: builtin/worktree.c:229
 #, c-format
 msgid "'%s' already exists"
 msgstr "'%s' existe déjà"
 
-#: builtin/worktree.c:269
+#: builtin/worktree.c:260
 #, c-format
 msgid "could not create directory of '%s'"
 msgstr "impossible de créer le répertoire de '%s'"
 
-#: builtin/worktree.c:308
+#: builtin/worktree.c:373 builtin/worktree.c:379
 #, c-format
-msgid "Preparing %s (identifier %s)"
-msgstr "Préparation de %s (identifiant %s)"
+msgid "Preparing worktree (new branch '%s')"
+msgstr "Préparation de l'arbre de travail (nouvelle branche '%s')"
 
-#: builtin/worktree.c:385
+#: builtin/worktree.c:375
+#, c-format
+msgid "Preparing worktree (resetting branch '%s'; was at %s)"
+msgstr ""
+"Préparation de l'arbre de travail (réinitialisation de la branche '%s' ; "
+"précédemment sur %s)"
+
+#: builtin/worktree.c:384
+#, c-format
+msgid "Preparing worktree (checking out '%s')"
+msgstr "Préparation de l'arbre de travail (extraction de '%s')"
+
+#: builtin/worktree.c:390
+#, c-format
+msgid "Preparing worktree (detached HEAD %s)"
+msgstr "Préparation de l'arbre de travail (HEAD détachée %s)"
+
+#: builtin/worktree.c:431
 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 "
 "travail"
 
-#: builtin/worktree.c:388
+#: builtin/worktree.c:434
 msgid "create a new branch"
 msgstr "créer une nouvelle branche"
 
-#: builtin/worktree.c:390
+#: builtin/worktree.c:436
 msgid "create or reset a branch"
 msgstr "créer ou réinitialiser une branche"
 
-#: builtin/worktree.c:392
+#: builtin/worktree.c:438
 msgid "populate the new working tree"
 msgstr "remplissage de la nouvelle copie de travail"
 
-#: builtin/worktree.c:393
+#: builtin/worktree.c:439
 msgid "keep the new working tree locked"
 msgstr "conserver le verrou sur le nouvel arbre de travail"
 
-#: builtin/worktree.c:395
+#: builtin/worktree.c:441
 msgid "set up tracking mode (see git-branch(1))"
 msgstr "régler le mode de suivi (voir git-branch(1))"
 
-#: builtin/worktree.c:398
+#: builtin/worktree.c:444
 msgid "try to match the new branch name with a remote-tracking branch"
 msgstr "essayer de nommer la nouvelle branche comme la branche amont"
 
-#: builtin/worktree.c:406
+#: builtin/worktree.c:452
 msgid "-b, -B, and --detach are mutually exclusive"
 msgstr "-b, -B et --detach sont mutuellement exclusifs"
 
-#: builtin/worktree.c:471
+#: builtin/worktree.c:511
 msgid "--[no-]track can only be used if a new branch is created"
 msgstr ""
 "--[no-]track ne peut être utilisé qu'à la création d'une nouvelle branche"
 
-#: builtin/worktree.c:571
+#: builtin/worktree.c:611
 msgid "reason for locking"
 msgstr "raison du verrouillage"
 
-#: builtin/worktree.c:583 builtin/worktree.c:616 builtin/worktree.c:670
-#: builtin/worktree.c:809
+#: builtin/worktree.c:623 builtin/worktree.c:656 builtin/worktree.c:710
+#: builtin/worktree.c:850
 #, c-format
 msgid "'%s' is not a working tree"
 msgstr "'%s' n'est pas une copie de travail"
 
-#: builtin/worktree.c:585 builtin/worktree.c:618
+#: builtin/worktree.c:625 builtin/worktree.c:658
 msgid "The main working tree cannot be locked or unlocked"
 msgstr ""
 "La copie de travail principale ne peut pas être verrouillée ou déverrouillée"
 
-#: builtin/worktree.c:590
+#: builtin/worktree.c:630
 #, c-format
 msgid "'%s' is already locked, reason: %s"
 msgstr "'%s' est déjà verrouillé, car '%s'"
 
-#: builtin/worktree.c:592
+#: builtin/worktree.c:632
 #, c-format
 msgid "'%s' is already locked"
 msgstr "'%s' est déjà verrouillé"
 
-#: builtin/worktree.c:620
+#: builtin/worktree.c:660
 #, c-format
 msgid "'%s' is not locked"
 msgstr "'%s' n'est pas verrouillé"
 
-#: builtin/worktree.c:645
+#: builtin/worktree.c:685
 msgid "working trees containing submodules cannot be moved or removed"
-msgstr "les arbres de travail contenant des sous-modules ne peuvent pas être déplacés ou supprimés"
+msgstr ""
+"les arbres de travail contenant des sous-modules ne peuvent pas être "
+"déplacés ou supprimés"
 
-#: builtin/worktree.c:672 builtin/worktree.c:811
+#: builtin/worktree.c:712 builtin/worktree.c:852
 #, c-format
 msgid "'%s' is a main working tree"
 msgstr "'%s' est un arbre de travail principal"
 
-#: builtin/worktree.c:677
+#: builtin/worktree.c:717
 #, c-format
 msgid "could not figure out destination name from '%s'"
 msgstr "impossible de trouver le nom de la destination à partir de '%s'"
 
-#: builtin/worktree.c:683
+#: builtin/worktree.c:723
 #, c-format
 msgid "target '%s' already exists"
 msgstr "la cible '%s' existe déjà"
 
-#: builtin/worktree.c:690
+#: builtin/worktree.c:730
 #, c-format
 msgid "cannot move a locked working tree, lock reason: %s"
-msgstr "impossible de déplacer un arbre de travail verrouillé, raison du verrouillage : %s"
+msgstr ""
+"impossible de déplacer un arbre de travail verrouillé, raison du "
+"verrouillage : %s"
 
-#: builtin/worktree.c:692
+#: builtin/worktree.c:732
 msgid "cannot move a locked working tree"
 msgstr "impossible de déplacer un arbre de travail verrouillé"
 
-#: builtin/worktree.c:695
+#: builtin/worktree.c:735
 #, c-format
 msgid "validation failed, cannot move working tree: %s"
 msgstr "la validation a échoué, impossible de déplacer l'arbre de travail : %s"
 
-#: builtin/worktree.c:700
+#: builtin/worktree.c:740
 #, c-format
 msgid "failed to move '%s' to '%s'"
 msgstr "échec au déplacement de '%s' vers '%s'"
 
-#: builtin/worktree.c:748
+#: builtin/worktree.c:788
 #, c-format
 msgid "failed to run 'git status' on '%s'"
 msgstr "échec du lancement de 'git status' sur '%s'"
 
-#: builtin/worktree.c:752
+#: builtin/worktree.c:792
 #, c-format
 msgid "'%s' is dirty, use --force to delete it"
 msgstr "'%s' est sale, utilisez --force pour le supprimer"
 
-#: builtin/worktree.c:757
+#: builtin/worktree.c:797
 #, c-format
 msgid "failed to run 'git status' on '%s', code %d"
 msgstr "impossible de lancer 'git status' sur '%s', code %d"
 
-#: builtin/worktree.c:768 builtin/worktree.c:782
+#: builtin/worktree.c:808 builtin/worktree.c:822
 #, c-format
 msgid "failed to delete '%s'"
 msgstr "échec de la suppression de '%s'"
 
-#: builtin/worktree.c:794
+#: builtin/worktree.c:834
 msgid "force removing even if the worktree is dirty"
 msgstr "forcer la suppression même si l'arbre de travail est sale"
 
-#: builtin/worktree.c:815
+#: builtin/worktree.c:856
 #, c-format
 msgid "cannot remove a locked working tree, lock reason: %s"
-msgstr "impossible de supprimer un arbre de travail verrouillé, raison du verrouillage : %s"
+msgstr ""
+"impossible de supprimer un arbre de travail verrouillé, raison du "
+"verrouillage : %s"
 
-#: builtin/worktree.c:817
+#: builtin/worktree.c:858
 msgid "cannot remove a locked working tree"
 msgstr "impossible de supprimer un arbre de travail verrouillé"
 
-#: builtin/worktree.c:820
+#: builtin/worktree.c:861
 #, c-format
 msgid "validation failed, cannot remove working tree: %s"
-msgstr "la validation a échoué, impossible de supprimer l'arbre de travail : %s"
+msgstr ""
+"la validation a échoué, impossible de supprimer l'arbre de travail : %s"
 
 #: builtin/write-tree.c:14
 msgid "git write-tree [--missing-ok] [--prefix=<prefix>/]"
@@ -15054,28 +15655,6 @@ msgstr "écrire l'objet arbre pour un sous-répertoire <préfixe>"
 msgid "only useful for debugging"
 msgstr "seulement utile pour le débogage"
 
-#: upload-pack.c:27
-msgid "git upload-pack [<options>] <dir>"
-msgstr "git upload-pack [<options>] <répertoire>"
-
-#: upload-pack.c:1070
-msgid "quit after a single request/response exchange"
-msgstr "quitter après un unique échange requête/réponse"
-
-#: upload-pack.c:1072
-msgid "exit immediately after initial ref advertisement"
-msgstr "Sortir immédiatement après l'annonce initiale des références"
-
-#: upload-pack.c:1074
-msgid "do not try <directory>/.git/ if <directory> is no Git directory"
-msgstr ""
-"nes pas essayer <répertoire>/.git/ si <répertoire> n'est pas un répertoire "
-"Git"
-
-#: upload-pack.c:1076
-msgid "interrupt transfer after <n> seconds of inactivity"
-msgstr "interrompre le transfert après <n> secondes d'inactivité"
-
 #: credential-cache--daemon.c:222
 #, c-format
 msgid ""
@@ -15093,21 +15672,24 @@ msgstr ""
 msgid "print debugging messages to stderr"
 msgstr "afficher les messages de debug sur stderr"
 
-#: git.c:8
+#: git.c:27
 msgid ""
 "git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
 "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
 "           <command> [<args>]"
 msgstr ""
 "git [--version] [--help] [-C <chemin>] [-c <nom>=<valeur>]\n"
-"           [--exec-path[=<chemin>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [--exec-path[=<chemin>]] [--html-path] [--man-path] [--info-"
+"path]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<chemin>] [--work-tree=<chemin>] [--namespace=<nom>]\n"
 "           <commande> [<args>]"
 
-#: git.c:15
+#: git.c:34
 msgid ""
 "'git help -a' and 'git help -g' list available subcommands and some\n"
 "concept guides. See 'git help <command>' or 'git help <concept>'\n"
@@ -15117,66 +15699,67 @@ msgstr ""
 "quelques concepts. Voir 'git help <commande>' ou 'git help <concept>'\n"
 "pour en lire plus à propos d'une commande spécifique ou d'un concept."
 
-#: git.c:95
+#: git.c:173
 #, c-format
 msgid "no directory given for --git-dir\n"
 msgstr "aucun répertoire fourni pour --git-dir\n"
 
-#: git.c:109
+#: git.c:187
 #, c-format
 msgid "no namespace given for --namespace\n"
 msgstr "aucun espace de nom fournit pour --namespace\n"
 
-#: git.c:123
+#: git.c:201
 #, c-format
 msgid "no directory given for --work-tree\n"
 msgstr "aucun répertoire fourni pour --work-tree\n"
 
-#: git.c:137
+#: git.c:215
 #, c-format
 msgid "no prefix given for --super-prefix\n"
 msgstr "aucun préfixe fourni pour --super-prefix\n"
 
-#: git.c:159
+#: git.c:237
 #, c-format
 msgid "-c expects a configuration string\n"
 msgstr "-c requiert une chaîne de configuration\n"
 
-#: git.c:197
+#: git.c:275
 #, c-format
 msgid "no directory given for -C\n"
 msgstr "aucun répertoire fourni pour -C\n"
 
-#: git.c:212
+#: git.c:300
 #, c-format
 msgid "unknown option: %s\n"
 msgstr "option inconnue : %s\n"
 
-#: git.c:687
+#: git.c:765
 #, c-format
 msgid "expansion of alias '%s' failed; '%s' is not a git command\n"
-msgstr "l'expansion de l'alias '%s' a échoué : '%s' n'est pas une commande git\n"
+msgstr ""
+"l'expansion de l'alias '%s' a échoué : '%s' n'est pas une commande git\n"
 
-#: git.c:699
+#: git.c:777
 #, c-format
 msgid "failed to run command '%s': %s\n"
 msgstr "échec au lancement de la commande '%s' : %s\n"
 
-#: http.c:342
+#: http.c:348
 #, c-format
 msgid "negative value for http.postbuffer; defaulting to %d"
 msgstr ""
 "valeur négative pour http.postbuffer ; utilisation de la valeur par défaut %d"
 
-#: http.c:363
+#: http.c:369
 msgid "Delegation control is not supported with cURL < 7.22.0"
 msgstr "La délégation de commande n'est pas supporté avec cuRL < 7.22.0"
 
-#: http.c:372
+#: http.c:378
 msgid "Public key pinning not supported with cURL < 7.44.0"
 msgstr "L'épinglage de clé publique n'est pas supporté avec cuRL < 7.44.0"
 
-#: http.c:1857
+#: http.c:1854
 #, c-format
 msgid ""
 "unable to update url base from redirection:\n"
@@ -15187,7 +15770,7 @@ msgstr ""
 "      demandé : %s\n"
 "  redirection : %s"
 
-#: remote-curl.c:345
+#: remote-curl.c:401
 #, c-format
 msgid "redirecting to %s"
 msgstr "redirection vers %s"
@@ -15200,133 +15783,678 @@ msgstr "args"
 msgid "object filtering"
 msgstr "filtrage d'objet"
 
-#: common-cmds.h:9
-msgid "start a working area (see also: git help tutorial)"
-msgstr "démarrer une zone de travail (voir aussi : git help tutorial)"
+#: parse-options.h:157
+msgid "expiry-date"
+msgstr "date-d'expiration"
 
-#: common-cmds.h:10
-msgid "work on the current change (see also: git help everyday)"
-msgstr ""
-"travailler sur la modification actuelle (voir aussi : git help revisions)"
+#: parse-options.h:172
+msgid "no-op (backward compatibility)"
+msgstr "sans action (rétrocompatibilité)"
 
-#: common-cmds.h:11
-msgid "examine the history and state (see also: git help revisions)"
-msgstr "examiner l'historique et l'état (voir aussi : git help revisions)"
+#: parse-options.h:251
+msgid "be more verbose"
+msgstr "être plus verbeux"
 
-#: common-cmds.h:12
-msgid "grow, mark and tweak your common history"
-msgstr "agrandir, marquer et modifier votre historique"
+#: parse-options.h:253
+msgid "be more quiet"
+msgstr "être plus silencieux"
 
-#: common-cmds.h:13
-msgid "collaborate (see also: git help workflows)"
-msgstr "collaborer (voir aussi : git help workflows)"
+#: parse-options.h:259
+msgid "use <n> digits to display SHA-1s"
+msgstr "utiliser <n> chiffres pour afficher les SHA-1s"
 
-#: common-cmds.h:17
+#: command-list.h:50
 msgid "Add file contents to the index"
 msgstr "Ajouter le contenu de fichiers dans l'index"
 
-#: common-cmds.h:18
+#: command-list.h:51
+msgid "Apply a series of patches from a mailbox"
+msgstr "Appliquer une série de patchs depuis une boîte mail"
+
+#: command-list.h:52
+msgid "Annotate file lines with commit information"
+msgstr "Annoter les lignes du fichier avec l'information de commit"
+
+#: command-list.h:53
+msgid "Apply a patch to files and/or to the index"
+msgstr "Appliquer une patch à des fichiers ou à l'index"
+
+#: command-list.h:54
+msgid "Import an Arch repository into Git"
+msgstr "Importer dans Git un dépôt Arch"
+
+#: command-list.h:55
+msgid "Create an archive of files from a named tree"
+msgstr "Créer une archive des fichiers depuis un arbre nommé"
+
+#: command-list.h:56
 msgid "Use binary search to find the commit that introduced a bug"
 msgstr "Trouver par recherche binaire la modification qui a introduit un bogue"
 
-#: common-cmds.h:19
+#: command-list.h:57
+msgid "Show what revision and author last modified each line of a file"
+msgstr ""
+"Montrer la révision et l'auteur qui ont modifié en dernier chaque ligne d'un "
+"fichier"
+
+#: command-list.h:58
 msgid "List, create, or delete branches"
 msgstr "Lister, créer ou supprimer des branches"
 
-#: common-cmds.h:20
+#: command-list.h:59
+msgid "Move objects and refs by archive"
+msgstr "Déplacer les objets et références par archive"
+
+#: command-list.h:60
+msgid "Provide content or type and size information for repository objects"
+msgstr ""
+"Fournir les contenu ou l'information de type et taille pour les objets du "
+"dépôt"
+
+#: command-list.h:61
+msgid "Display gitattributes information"
+msgstr "Afficher les informations gitattributes"
+
+#: command-list.h:62
+msgid "Debug gitignore / exclude files"
+msgstr "Déboguer gitignore / les fichiers d'exclusion"
+
+#: command-list.h:63
+msgid "Show canonical names and email addresses of contacts"
+msgstr "Afficher les noms canoniques et les adresses courriel des contacts"
+
+#: command-list.h:64
 msgid "Switch branches or restore working tree files"
 msgstr "Basculer de branche ou restaurer la copie de travail"
 
-#: common-cmds.h:21
+#: command-list.h:65
+msgid "Copy files from the index to the working tree"
+msgstr "Copier les fichiers depuis l'index dans la copie de travail"
+
+#: command-list.h:66
+msgid "Ensures that a reference name is well formed"
+msgstr "Assure qu'un nom de référence est bien formé"
+
+#: command-list.h:67
+msgid "Find commits yet to be applied to upstream"
+msgstr "Trouver les commits à appliquer en amont"
+
+#: command-list.h:68
+msgid "Apply the changes introduced by some existing commits"
+msgstr "Appliquer les modifications introduites par des commits existants"
+
+#: command-list.h:69
+msgid "Graphical alternative to git-commit"
+msgstr "Alternative graphique à git-commit"
+
+#: command-list.h:70
+msgid "Remove untracked files from the working tree"
+msgstr "Supprimer les fichiers non-suivis de l'arbre de travail"
+
+#: command-list.h:71
 msgid "Clone a repository into a new directory"
 msgstr "Cloner un dépôt dans un nouveau répertoire"
 
-#: common-cmds.h:22
+#: command-list.h:72
+msgid "Display data in columns"
+msgstr "Afficher les données en colonnes"
+
+#: command-list.h:73
 msgid "Record changes to the repository"
 msgstr "Enregistrer les modifications dans le dépôt"
 
-#: common-cmds.h:23
+#: command-list.h:74
+msgid "Write and verify Git commit graph files"
+msgstr "Écrire et vérifier les fichiers de graphe de commit Git"
+
+#: command-list.h:75
+msgid "Create a new commit object"
+msgstr "Créer un nouvel objet commit"
+
+#: command-list.h:76
+msgid "Get and set repository or global options"
+msgstr "voir et régler les options globales ou de dépôt"
+
+#: command-list.h:77
+msgid "Count unpacked number of objects and their disk consumption"
+msgstr ""
+"Compter le nombre d'objets non-empaquetés et leur consommation d'espace "
+"disque"
+
+#: command-list.h:78
+msgid "Retrieve and store user credentials"
+msgstr "Récupérer et sauvegarder les certificats d'utilisateur"
+
+#: command-list.h:79
+msgid "Helper to temporarily store passwords in memory"
+msgstr "Assistant pour maintenir temporairement en mémoire les mots de passe"
+
+#: command-list.h:80
+msgid "Helper to store credentials on disk"
+msgstr "Assistant pour sauvegarder les certificats sur disque"
+
+#: command-list.h:81
+msgid "Export a single commit to a CVS checkout"
+msgstr "Exporter un commit unique en extraction CVS"
+
+#: command-list.h:82
+msgid "Salvage your data out of another SCM people love to hate"
+msgstr "Sauver vos données depuis un autre SCM qu'on aime à haïr"
+
+#: command-list.h:83
+msgid "A CVS server emulator for Git"
+msgstr "Un émulateur de serveur CVS pour Git"
+
+#: command-list.h:84
+msgid "A really simple server for Git repositories"
+msgstr "Un serveur vraiment simple pour les dépôts Git"
+
+#: command-list.h:85
+msgid "Give an object a human readable name based on an available ref"
+msgstr ""
+"Baptiser un objet avec un nom lisible à partir d'une référence disponible"
+
+#: command-list.h:86
 msgid "Show changes between commits, commit and working tree, etc"
 msgstr ""
 "Afficher les changements entre les validations, entre validation et copie de "
 "travail, etc"
 
-#: common-cmds.h:24
+#: command-list.h:87
+msgid "Compares files in the working tree and the index"
+msgstr "Compare des fichiers de l'arbre de travail et de l'index"
+
+#: command-list.h:88
+msgid "Compare a tree to the working tree or index"
+msgstr "Comparer un arbre avec l'arbre de travail ou l'index"
+
+#: command-list.h:89
+msgid "Compares the content and mode of blobs found via two tree objects"
+msgstr "Compare le contenu et la mode des blobs trouvés via deux objets arbre"
+
+#: command-list.h:90
+msgid "Show changes using common diff tools"
+msgstr "Afficher les modifications en utilisant les outils habituel de diff"
+
+#: command-list.h:91
+msgid "Git data exporter"
+msgstr "Exporteur de données Git"
+
+#: command-list.h:92
+msgid "Backend for fast Git data importers"
+msgstr "Moteur pour les importateurs rapides de données Git"
+
+#: command-list.h:93
 msgid "Download objects and refs from another repository"
 msgstr "Télécharger les objets et références depuis un autre dépôt"
 
-#: common-cmds.h:25
+#: command-list.h:94
+msgid "Receive missing objects from another repository"
+msgstr "Télécharger les objets manquants depuis un autre dépôt"
+
+#: command-list.h:95
+msgid "Rewrite branches"
+msgstr "Réécrire les branches"
+
+#: command-list.h:96
+msgid "Produce a merge commit message"
+msgstr "Produire un message de validation de fusion"
+
+#: command-list.h:97
+msgid "Output information on each ref"
+msgstr "Afficher l'information de chaque référence"
+
+#: command-list.h:98
+msgid "Prepare patches for e-mail submission"
+msgstr "Préparer les patchs pour soumission par courriel"
+
+#: command-list.h:99
+msgid "Verifies the connectivity and validity of the objects in the database"
+msgstr ""
+"Vérifier la connectivité et la validité des objets dans la base de données"
+
+#: command-list.h:100
+msgid "Cleanup unnecessary files and optimize the local repository"
+msgstr "Effacer les fichiers non-nécessaires et optimiser le dépôt local"
+
+#: command-list.h:101
+msgid "Extract commit ID from an archive created using git-archive"
+msgstr "Extraire l'ID du commit depuis une archive créée par git-archive"
+
+#: command-list.h:102
 msgid "Print lines matching a pattern"
 msgstr "Afficher les lignes correspondant à un motif"
 
-#: common-cmds.h:26
+#: command-list.h:103
+msgid "A portable graphical interface to Git"
+msgstr "Une interface graphique portable pour Git"
+
+#: command-list.h:104
+msgid "Compute object ID and optionally creates a blob from a file"
+msgstr ""
+"Calculer l'ID d'objet et créer optionnellement un blob depuis un fichier"
+
+#: command-list.h:105
+msgid "Display help information about Git"
+msgstr "Afficher l'information d'aide à propos de Git"
+
+#: command-list.h:106
+msgid "Server side implementation of Git over HTTP"
+msgstr "Implantation côté serveur de Git sur HTTP"
+
+#: command-list.h:107
+msgid "Download from a remote Git repository via HTTP"
+msgstr "Télécharger depuis un dépôt Git distant via HTTP"
+
+#: command-list.h:108
+msgid "Push objects over HTTP/DAV to another repository"
+msgstr "Pousser les objets sur un autre dépôt via HTTP/DAV"
+
+#: command-list.h:109
+msgid "Send a collection of patches from stdin to an IMAP folder"
+msgstr "Envoyer un ensemble de patchs depuis stdin vers un répertoire IMAP"
+
+#: command-list.h:110
+msgid "Build pack index file for an existing packed archive"
+msgstr ""
+"Construire un fichier d'index pack depuis une archive compactée existante"
+
+#: command-list.h:111
 msgid "Create an empty Git repository or reinitialize an existing one"
 msgstr "Créer un dépôt Git vide ou réinitialiser un existant"
 
-#: common-cmds.h:27
+#: command-list.h:112
+msgid "Instantly browse your working repository in gitweb"
+msgstr "Naviguer instantanément votre dépôt de travail dans gitweb"
+
+#: command-list.h:113
+msgid "add or parse structured information in commit messages"
+msgstr ""
+"ajouter ou analyser l'information structurée dans les messages de validation"
+
+#: command-list.h:114
+msgid "The Git repository browser"
+msgstr "Le navigateur de dépôt Git"
+
+#: command-list.h:115
 msgid "Show commit logs"
 msgstr "Afficher l'historique des validations"
 
-#: common-cmds.h:28
+#: command-list.h:116
+msgid "Show information about files in the index and the working tree"
+msgstr ""
+"Afficher l'information à propos des fichiers dans l'index ou l'arbre de "
+"travail"
+
+#: command-list.h:117
+msgid "List references in a remote repository"
+msgstr "Lister les références dans un dépôt distant"
+
+#: command-list.h:118
+msgid "List the contents of a tree object"
+msgstr "Afficher le contenu d'un objet arbre"
+
+#: command-list.h:119
+msgid "Extracts patch and authorship from a single e-mail message"
+msgstr ""
+"Extraire le patch et l'information de d'auteur depuis un simple message de "
+"courriel"
+
+#: command-list.h:120
+msgid "Simple UNIX mbox splitter program"
+msgstr "Programme simple de découpage de mbox UNIX"
+
+#: command-list.h:121
 msgid "Join two or more development histories together"
 msgstr "Fusionner deux ou plusieurs historiques de développement ensemble"
 
-#: common-cmds.h:29
+#: command-list.h:122
+msgid "Find as good common ancestors as possible for a merge"
+msgstr "Trouver un ancêtre aussi bon que possible pour une fusion"
+
+#: command-list.h:123
+msgid "Run a three-way file merge"
+msgstr "Lancer une fusion à 3 points"
+
+#: command-list.h:124
+msgid "Run a merge for files needing merging"
+msgstr "Lancer une fusion à 3 points pour les fichiers à fusionner"
+
+#: command-list.h:125
+msgid "The standard helper program to use with git-merge-index"
+msgstr "Le programme assistant standard à utiliser avec git-merge-index"
+
+#: command-list.h:126
+msgid "Run merge conflict resolution tools to resolve merge conflicts"
+msgstr ""
+"Lancer les outils de résolution de conflit de fusion pour résoudre les "
+"conflits de fusion"
+
+#: command-list.h:127
+msgid "Show three-way merge without touching index"
+msgstr "Afficher la fusion à trois points sans modifier l'index"
+
+#: command-list.h:128
+msgid "Creates a tag object"
+msgstr "Créer un objet étiquette"
+
+#: command-list.h:129
+msgid "Build a tree-object from ls-tree formatted text"
+msgstr "Construire un objet arbre depuis une texte formaté comme ls-tree"
+
+#: command-list.h:130
 msgid "Move or rename a file, a directory, or a symlink"
 msgstr "Déplacer ou renommer un fichier, un répertoire, ou un lien symbolique"
 
-#: common-cmds.h:30
+#: command-list.h:131
+msgid "Find symbolic names for given revs"
+msgstr "Trouver les noms symboliques pour des révisions données"
+
+#: command-list.h:132
+msgid "Add or inspect object notes"
+msgstr "Ajouter ou inspecter les notes d'un objets"
+
+#: command-list.h:133
+msgid "Import from and submit to Perforce repositories"
+msgstr "Importer et soumettre à des dépôt Perforce"
+
+#: command-list.h:134
+msgid "Create a packed archive of objects"
+msgstr "Créer une archive compactée d'objets"
+
+#: command-list.h:135
+msgid "Find redundant pack files"
+msgstr "Trouver les fichiers pack redondants"
+
+#: command-list.h:136
+msgid "Pack heads and tags for efficient repository access"
+msgstr "Empaqueter les têtes et les étiquettes pour un accès efficace au dépôt"
+
+#: command-list.h:137
+msgid "Routines to help parsing remote repository access parameters"
+msgstr ""
+"Routines pour aider à analyser les paramètres d'accès aux dépôts distants"
+
+#: command-list.h:138
+msgid "Compute unique ID for a patch"
+msgstr "Calculer l'ID unique d'un patch"
+
+#: command-list.h:139
+msgid "Prune all unreachable objects from the object database"
+msgstr ""
+"Éliminer les objets inatteignables depuis la base de données des objets"
+
+#: command-list.h:140
+msgid "Remove extra objects that are already in pack files"
+msgstr "Éliminer les objets qui sont déjà présents dans les fichiers pack"
+
+#: command-list.h:141
 msgid "Fetch from and integrate with another repository or a local branch"
 msgstr "Rapatrier et intégrer un autre dépôt ou une branche locale"
 
-#: common-cmds.h:31
+#: command-list.h:142
 msgid "Update remote refs along with associated objects"
 msgstr "Mettre à jour les références distantes ainsi que les objets associés"
 
-#: common-cmds.h:32
+#: command-list.h:143
+msgid "Applies a quilt patchset onto the current branch"
+msgstr "Appliquer un patchset quilt sur la branche courante"
+
+#: command-list.h:144
+msgid "Reads tree information into the index"
+msgstr "Lire l'information d'arbre dans l'index"
+
+#: command-list.h:145
 msgid "Reapply commits on top of another base tip"
 msgstr "Réapplication des commits sur le sommet de l'autre base"
 
-#: common-cmds.h:33
+#: command-list.h:146
+msgid "Receive what is pushed into the repository"
+msgstr "Recevoir ce qui est poussé dans le dépôt"
+
+#: command-list.h:147
+msgid "Manage reflog information"
+msgstr "Gérer l'information de reflog"
+
+#: command-list.h:148
+msgid "Manage set of tracked repositories"
+msgstr "Gérer un ensemble de dépôts suivis"
+
+#: command-list.h:149
+msgid "Pack unpacked objects in a repository"
+msgstr "Empaqueter les objets non-empaquetés d'un dépôt"
+
+#: command-list.h:150
+msgid "Create, list, delete refs to replace objects"
+msgstr "Créer, lister, supprimer des référence pour remplacer des objets"
+
+#: command-list.h:151
+msgid "Generates a summary of pending changes"
+msgstr "Générer une résumé des modifications en attentes"
+
+#: command-list.h:152
+msgid "Reuse recorded resolution of conflicted merges"
+msgstr "Réutiliser une résolution enregistrée de fusions conflictuelles"
+
+#: command-list.h:153
 msgid "Reset current HEAD to the specified state"
 msgstr "Réinitialiser la HEAD courante à l'état spécifié"
 
-#: common-cmds.h:34
+#: command-list.h:154
+msgid "Revert some existing commits"
+msgstr "Inverser des commits existants"
+
+#: command-list.h:155
+msgid "Lists commit objects in reverse chronological order"
+msgstr "Afficher les objets commit dans l'ordre chronologique inverse"
+
+#: command-list.h:156
+msgid "Pick out and massage parameters"
+msgstr "Analyser et préparer les paramètres"
+
+#: command-list.h:157
 msgid "Remove files from the working tree and from the index"
 msgstr "Supprimer des fichiers de la copie de travail et de l'index"
 
-#: common-cmds.h:35
+#: command-list.h:158
+msgid "Send a collection of patches as emails"
+msgstr "Envoyer un ensemble de patchs comme courriels"
+
+#: command-list.h:159
+msgid "Push objects over Git protocol to another repository"
+msgstr "Pousser les objets sur un autre dépôt via le protocole Git"
+
+#: command-list.h:160
+msgid "Restricted login shell for Git-only SSH access"
+msgstr "shell de login restreint pour un accès SSH vers Git seulement"
+
+#: command-list.h:161
+msgid "Summarize 'git log' output"
+msgstr "Résumer la sortie de 'git log'"
+
+#: command-list.h:162
 msgid "Show various types of objects"
 msgstr "Afficher différents types d'objets"
 
-#: common-cmds.h:36
+#: command-list.h:163
+msgid "Show branches and their commits"
+msgstr "Afficher les branches et leurs commits"
+
+#: command-list.h:164
+msgid "Show packed archive index"
+msgstr "Afficher l'index de l'archive empaquetée"
+
+#: command-list.h:165
+msgid "List references in a local repository"
+msgstr "Lister les références du dépôt local"
+
+#: command-list.h:166
+msgid "Git's i18n setup code for shell scripts"
+msgstr "Le code d'initialisation i18n pour les scripts shell"
+
+#: command-list.h:167
+msgid "Common Git shell script setup code"
+msgstr "Le code d'initialisation commun aux scripts shell Git"
+
+#: command-list.h:168
+msgid "Stash the changes in a dirty working directory away"
+msgstr "Remiser les modifications d'un répertoire de travail sale"
+
+#: command-list.h:169
+msgid "Add file contents to the staging area"
+msgstr "Ajouter le contenu de fichiers à l'index"
+
+#: command-list.h:170
 msgid "Show the working tree status"
 msgstr "Afficher l'état de la copie de travail"
 
-#: common-cmds.h:37
+#: command-list.h:171
+msgid "Remove unnecessary whitespace"
+msgstr "Retirer les espaces inutiles"
+
+#: command-list.h:172
+msgid "Initialize, update or inspect submodules"
+msgstr "Initialiser, mettre à jour et inspecter les sous-modules"
+
+#: command-list.h:173
+msgid "Bidirectional operation between a Subversion repository and Git"
+msgstr "Opération Bidirectionnelles entre un dépôt Subversion et Git"
+
+#: command-list.h:174
+msgid "Read, modify and delete symbolic refs"
+msgstr "Lire, modifier et supprimer les références symboliques"
+
+#: command-list.h:175
 msgid "Create, list, delete or verify a tag object signed with GPG"
 msgstr ""
 "Créer, lister, supprimer ou vérifier un objet d'étiquette signé avec GPG"
 
-#: parse-options.h:157
-msgid "expiry-date"
-msgstr "date-d'expiration"
+#: command-list.h:176
+msgid "Creates a temporary file with a blob's contents"
+msgstr "Créer un fichier temporaire avec le contenu d'un blob"
 
-#: parse-options.h:172
-msgid "no-op (backward compatibility)"
-msgstr "sans action (rétrocompatibilité)"
+#: command-list.h:177
+msgid "Unpack objects from a packed archive"
+msgstr "Dépaqueter les objets depuis une archive empaquetée"
 
-#: parse-options.h:250
-msgid "be more verbose"
-msgstr "être plus verbeux"
+#: command-list.h:178
+msgid "Register file contents in the working tree to the index"
+msgstr "Enregistrer le contenu d'un fichier de l'arbre de travail dans l'index"
 
-#: parse-options.h:252
-msgid "be more quiet"
-msgstr "être plus silencieux"
+#: command-list.h:179
+msgid "Update the object name stored in a ref safely"
+msgstr ""
+"Mettre à jour le nom d'objet stocké dans une référence en toute sécurité"
 
-#: parse-options.h:258
-msgid "use <n> digits to display SHA-1s"
-msgstr "utiliser <n> chiffres pour afficher les SHA-1s"
+#: command-list.h:180
+msgid "Update auxiliary info file to help dumb servers"
+msgstr ""
+"Mettre à jour le fichier d'informations auxiliaires pour aider les serveurs "
+"idiots"
+
+#: command-list.h:181
+msgid "Send archive back to git-archive"
+msgstr "Renvoyer une archive dans git-archive"
+
+#: command-list.h:182
+msgid "Send objects packed back to git-fetch-pack"
+msgstr "Renvoyer des objets empaquetés dans git-fetch-pack"
+
+#: command-list.h:183
+msgid "Show a Git logical variable"
+msgstr "Afficher un variable logique de Git"
+
+#: command-list.h:184
+msgid "Check the GPG signature of commits"
+msgstr "Vérifier la signature GPG de commits"
+
+#: command-list.h:185
+msgid "Validate packed Git archive files"
+msgstr "Valider des fichiers d'archive Git empaquetés"
+
+#: command-list.h:186
+msgid "Check the GPG signature of tags"
+msgstr "Vérifier la signature GPG d'étiquettes"
+
+#: command-list.h:187
+msgid "Git web interface (web frontend to Git repositories)"
+msgstr "Interface web de Git"
+
+#: command-list.h:188
+msgid "Show logs with difference each commit introduces"
+msgstr "Afficher les journaux avec la différence que chaque commit introduit"
+
+#: command-list.h:189
+msgid "Manage multiple working trees"
+msgstr "Gère de arbres de travail multiples"
+
+#: command-list.h:190
+msgid "Create a tree object from the current index"
+msgstr "Créer un objet arbre depuis l'index courant"
+
+#: command-list.h:191
+msgid "Defining attributes per path"
+msgstr "Définition des attributs par chemin"
+
+#: command-list.h:192
+msgid "Git command-line interface and conventions"
+msgstr "interface en ligne de commande et conventions de Git"
+
+#: command-list.h:193
+msgid "A Git core tutorial for developers"
+msgstr "Tutoriel du cœur de Git pour les développeurs"
+
+#: command-list.h:194
+msgid "Git for CVS users"
+msgstr "Git pour les utilisateurs de CVS"
+
+#: command-list.h:195
+msgid "Tweaking diff output"
+msgstr "Bidouillage de la sortie diff"
+
+#: command-list.h:196
+msgid "A useful minimum set of commands for Everyday Git"
+msgstr "Un ensemble minimal utile des commandes de Git pour tous les jours"
+
+#: command-list.h:197
+msgid "A Git Glossary"
+msgstr "Un glossaire Git"
+
+#: command-list.h:198
+msgid "Hooks used by Git"
+msgstr "Crochets utilisés par Git"
+
+#: command-list.h:199
+msgid "Specifies intentionally untracked files to ignore"
+msgstr "Spécifie les fichiers non-suivis à ignorer intentionnellement"
+
+#: command-list.h:200
+msgid "Defining submodule properties"
+msgstr "Définition des propriétés de sous-module"
+
+#: command-list.h:201
+msgid "Git namespaces"
+msgstr "Espaces de nom de Git"
+
+#: command-list.h:202
+msgid "Git Repository Layout"
+msgstr "Disposition d'un dépôt Git"
+
+#: command-list.h:203
+msgid "Specifying revisions and ranges for Git"
+msgstr "Spécification des révisions et portées pour Git"
+
+#: command-list.h:204
+msgid "A tutorial introduction to Git: part two"
+msgstr "Une introduction pratique à Git : deuxième partie"
+
+#: command-list.h:205
+msgid "A tutorial introduction to Git"
+msgstr "Une introduction pratique à Git"
+
+#: command-list.h:206
+msgid "An overview of recommended workflows with Git"
+msgstr "Un aperçu des flux de travail recommandés avec Git"
 
 #: rerere.h:40
 msgid "update the index with reused conflict resolution if possible"
@@ -15562,7 +16690,7 @@ msgstr "Essai de fusion simple avec $pretty_name"
 msgid "Simple merge did not work, trying automatic merge."
 msgstr "La fusion simple a échoué, essai avec la fusion automatique."
 
-#: git-rebase.sh:60
+#: git-rebase.sh:61
 msgid ""
 "Resolve all conflicts manually, mark them as resolved with\n"
 "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
@@ -15576,43 +16704,43 @@ msgstr ""
 "arrêter\n"
 "et revenir à l'état antérieur à la commande, lancez \"git rebase --abort\"."
 
-#: git-rebase.sh:163 git-rebase.sh:409
+#: git-rebase.sh:173 git-rebase.sh:442
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "Impossible de revenir à $head_name"
 
-#: git-rebase.sh:174
+#: git-rebase.sh:184
 msgid "Applied autostash."
 msgstr "Autoremisage appliqué."
 
-#: git-rebase.sh:177
+#: git-rebase.sh:187
 #, sh-format
 msgid "Cannot store $stash_sha1"
 msgstr "Impossible de stocker $stash_sha1"
 
-#: git-rebase.sh:218
+#: git-rebase.sh:229
 msgid "The pre-rebase hook refused to rebase."
 msgstr "Le crochet pre-rebase a refusé de rebaser."
 
-#: git-rebase.sh:223
+#: git-rebase.sh:234
 msgid "It looks like 'git am' is in progress. Cannot rebase."
 msgstr "Il semble que 'git-am' soit en cours. Impossible de rebaser."
 
-#: git-rebase.sh:370
+#: git-rebase.sh:403
 msgid "No rebase in progress?"
 msgstr "Pas de rebasage en cours ?"
 
-#: git-rebase.sh:381
+#: git-rebase.sh:414
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
 "L'action --edit-todo peut seulement être utilisée lors d'un rebasage "
 "interactif."
 
-#: git-rebase.sh:388
+#: git-rebase.sh:421
 msgid "Cannot read HEAD"
 msgstr "Impossible de lire HEAD"
 
-#: git-rebase.sh:391
+#: git-rebase.sh:424
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -15620,7 +16748,7 @@ msgstr ""
 "Vous devez éditer tous les conflits de fusion et\n"
 "les marquer comme résolus avec git add"
 
-#: git-rebase.sh:435
+#: git-rebase.sh:468
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -15642,76 +16770,80 @@ msgstr ""
 "chose\n"
 "d'important ici."
 
-#: git-rebase.sh:491
+#: git-rebase.sh:509
+msgid "error: cannot combine '--signoff' with '--preserve-merges'"
+msgstr "erreur : '--signoff' et '--preserve-merges' sont incompatibles"
+
+#: git-rebase.sh:537
 #, sh-format
 msgid "invalid upstream '$upstream_name'"
 msgstr "invalide '$upstream_name' en amont"
 
-#: git-rebase.sh:515
+#: git-rebase.sh:561
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name : il y a plus d'une base de fusion"
 
-#: git-rebase.sh:518 git-rebase.sh:522
+#: git-rebase.sh:564 git-rebase.sh:568
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name : il n'y a pas de base de fusion"
 
-#: git-rebase.sh:527
+#: git-rebase.sh:573
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "Ne pointe pas sur une validation valide : $onto_name"
 
-#: git-rebase.sh:553
+#: git-rebase.sh:599
 #, sh-format
 msgid "fatal: no such branch/commit '$branch_name'"
 msgstr "fatal : pas de branche ou commit '$branch_name'"
 
-#: git-rebase.sh:586
+#: git-rebase.sh:632
 msgid "Cannot autostash"
 msgstr "Autoremisage impossible"
 
-#: git-rebase.sh:591
+#: git-rebase.sh:637
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "Autoremisage créé : $stash_abbrev"
 
-#: git-rebase.sh:595
+#: git-rebase.sh:641
 msgid "Please commit or stash them."
 msgstr "Veuillez les valider ou les remiser."
 
-#: git-rebase.sh:618
+#: git-rebase.sh:664
 #, sh-format
 msgid "HEAD is up to date."
 msgstr "HEAD est à jour."
 
-#: git-rebase.sh:620
+#: git-rebase.sh:666
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "La branche courante $branch_name est à jour."
 
-#: git-rebase.sh:628
+#: git-rebase.sh:674
 #, sh-format
 msgid "HEAD is up to date, rebase forced."
 msgstr "HEAD est à jour, rebasage forcé."
 
-#: git-rebase.sh:630
+#: git-rebase.sh:676
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr "La branche courante $branch_name est à jour, rebasage forcé."
 
-#: git-rebase.sh:642
+#: git-rebase.sh:688
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "Changements de $mb sur $onto :"
 
-#: git-rebase.sh:651
+#: git-rebase.sh:697
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr ""
 "Rembobinage préalable de head pour pouvoir rejouer votre travail par-"
 "dessus..."
 
-#: git-rebase.sh:661
+#: git-rebase.sh:707
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "$branch_name mise à jour en avance rapide sur $onto_name."
@@ -15780,113 +16912,113 @@ msgstr "Impossible de sauver l'état courant"
 msgid "Saved working directory and index state $stash_msg"
 msgstr "Copie de travail et état de l'index sauvegardés dans $stash_msg"
 
-#: git-stash.sh:340
+#: git-stash.sh:342
 msgid "Cannot remove worktree changes"
 msgstr "Impossible de supprimer les changements de la copie de travail"
 
-#: git-stash.sh:488
+#: git-stash.sh:490
 #, sh-format
 msgid "unknown option: $opt"
 msgstr "option inconnue : $opt"
 
-#: git-stash.sh:501
+#: git-stash.sh:503
 msgid "No stash entries found."
 msgstr "Aucune entrée de remisage trouvée."
 
-#: git-stash.sh:508
+#: git-stash.sh:510
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "Trop de révisions spécifiées : $REV"
 
-#: git-stash.sh:523
+#: git-stash.sh:525
 #, sh-format
 msgid "$reference is not a valid reference"
 msgstr "$reference n'est pas une référence valide"
 
-#: git-stash.sh:551
+#: git-stash.sh:553
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "'$args' n'est pas une validation de type remisage"
 
-#: git-stash.sh:562
+#: git-stash.sh:564
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "'$args' n'est pas une référence de remisage"
 
-#: git-stash.sh:570
+#: git-stash.sh:572
 msgid "unable to refresh index"
 msgstr "impossible de rafraîchir l'index"
 
-#: git-stash.sh:574
+#: git-stash.sh:576
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "Impossible d'appliquer un remisage en cours de fusion"
 
-#: git-stash.sh:582
+#: git-stash.sh:584
 msgid "Conflicts in index. Try without --index."
 msgstr "Conflits dans l'index. Essayez sans --index."
 
-#: git-stash.sh:584
+#: git-stash.sh:586
 msgid "Could not save index tree"
 msgstr "Impossible de sauvegarder l'arbre d'index"
 
-#: git-stash.sh:593
+#: git-stash.sh:595
 msgid "Could not restore untracked files from stash entry"
 msgstr ""
 "Impossible de restaurer les fichiers non-suivis depuis l'entrée de remisage"
 
-#: git-stash.sh:618
+#: git-stash.sh:620
 msgid "Cannot unstage modified files"
 msgstr "Impossible de désindexer les fichiers modifiés"
 
-#: git-stash.sh:633
+#: git-stash.sh:635
 msgid "Index was not unstashed."
 msgstr "L'index n'a pas été sorti de remise."
 
-#: git-stash.sh:647
+#: git-stash.sh:649
 msgid "The stash entry is kept in case you need it again."
 msgstr ""
 "L'entrée de remisage est conservée au cas où vous en auriez encore besoin."
 
-#: git-stash.sh:656
+#: git-stash.sh:658
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "${REV} supprimé ($s)"
 
-#: git-stash.sh:657
+#: git-stash.sh:659
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "${REV}: Impossible de supprimer l'élément de stash"
 
-#: git-stash.sh:665
+#: git-stash.sh:667
 msgid "No branch name specified"
 msgstr "Aucune branche spécifiée"
 
-#: git-stash.sh:744
+#: git-stash.sh:746
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(Pour les restaurer tapez \"git stash apply\")"
 
-#: git-submodule.sh:181
+#: git-submodule.sh:188
 msgid "Relative path can only be used from the toplevel of the working tree"
 msgstr ""
 "Un chemin relatif ne peut être utilisé que depuis la racine de la copie de "
 "travail"
 
-#: git-submodule.sh:191
+#: git-submodule.sh:198
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr "L'URL de dépôt '$repo' doit être absolu ou commencer par ./|../"
 
-#: git-submodule.sh:210
+#: git-submodule.sh:217
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "'$sm_path' existe déjà dans l'index"
 
-#: git-submodule.sh:213
+#: git-submodule.sh:220
 #, sh-format
 msgid "'$sm_path' already exists in the index and is not a submodule"
 msgstr "'$sm_path' existe déjà dans l'index et n'est pas un sous-module"
 
-#: git-submodule.sh:219
+#: git-submodule.sh:226
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -15897,24 +17029,24 @@ msgstr ""
 "$sm_path\n"
 "Utilisez -f si vous voulez vraiment l'ajouter."
 
-#: git-submodule.sh:237
+#: git-submodule.sh:249
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "Ajout du dépôt existant à '$sm_path' dans l'index"
 
-#: git-submodule.sh:239
+#: git-submodule.sh:251
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "'$sm_path' existe déjà et n'est pas un dépôt git valide"
 
-#: git-submodule.sh:247
+#: git-submodule.sh:259
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
 msgstr ""
 "Un répertoire git pour '$sm_name' est trouvé en local avec le(s) serveur(s) "
 "distant(s) :"
 
-#: git-submodule.sh:249
+#: git-submodule.sh:261
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from\n"
@@ -15931,49 +17063,49 @@ msgstr ""
 "correct\n"
 "ou si ceci n'est pas clair, choisissez un autre nom avec l'option '--name'."
 
-#: git-submodule.sh:255
+#: git-submodule.sh:267
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
 msgstr "Réactivation du répertoire git local pour le sous-module '$sm_name'."
 
-#: git-submodule.sh:267
+#: git-submodule.sh:279
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "Impossible d'extraire le sous-module '$sm_path'"
 
-#: git-submodule.sh:272
+#: git-submodule.sh:284
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "Échec d'ajout du sous-module '$sm_path'"
 
-#: git-submodule.sh:281
+#: git-submodule.sh:293
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "Échec d'enregistrement du sous-module '$sm_path'"
 
-#: git-submodule.sh:342
+#: git-submodule.sh:354
 #, sh-format
 msgid "Entering '$displaypath'"
 msgstr "Entrée dans '$displaypath'"
 
-#: git-submodule.sh:362
+#: git-submodule.sh:374
 #, sh-format
 msgid "Stopping at '$displaypath'; script returned non-zero status."
 msgstr "Arrêt sur '$displaypath' ; le script a retourné un état non nul."
 
-#: git-submodule.sh:584
+#: git-submodule.sh:600
 #, sh-format
 msgid "Unable to find current revision in submodule path '$displaypath'"
 msgstr ""
 "Impossible de trouver la révision courante dans le chemin de sous-module "
 "'$displaypath'"
 
-#: git-submodule.sh:594
+#: git-submodule.sh:610
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "Impossible de rapatrier dans le chemin de sous-module '$sm_path'"
 
-#: git-submodule.sh:599
+#: git-submodule.sh:615
 #, sh-format
 msgid ""
 "Unable to find current ${remote_name}/${branch} revision in submodule path "
@@ -15982,12 +17114,12 @@ msgstr ""
 "Impossible de trouver la révision courante ${remote_name}/${branch} dans le "
 "chemin de sous-module '$sm_path'"
 
-#: git-submodule.sh:617
+#: git-submodule.sh:633
 #, sh-format
 msgid "Unable to fetch in submodule path '$displaypath'"
 msgstr "Impossible de rapatrier dans le chemin de sous-module '$displaypath'"
 
-#: git-submodule.sh:623
+#: git-submodule.sh:639
 #, sh-format
 msgid ""
 "Fetched in submodule path '$displaypath', but it did not contain $sha1. "
@@ -15996,76 +17128,76 @@ msgstr ""
 "Chemin de sous-module '$displaypath' récupéré, mais il ne contenait pas "
 "$sha1. La récupération directe de ce commit a échoué."
 
-#: git-submodule.sh:630
+#: git-submodule.sh:646
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
 msgstr ""
 "Impossible d'extraire '$sha1' dans le chemin de sous-module '$displaypath'"
 
-#: git-submodule.sh:631
+#: git-submodule.sh:647
 #, sh-format
 msgid "Submodule path '$displaypath': checked out '$sha1'"
 msgstr "Chemin de sous-module '$displaypath' : '$sha1' extrait"
 
-#: git-submodule.sh:635
+#: git-submodule.sh:651
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
 msgstr ""
 "Impossible de rebaser '$sha1' dans le chemin de sous-module '$displaypath'"
 
-#: git-submodule.sh:636
+#: git-submodule.sh:652
 #, sh-format
 msgid "Submodule path '$displaypath': rebased into '$sha1'"
 msgstr "Chemin de sous-module '$displaypath' : rebasé dans '$sha1'"
 
-#: git-submodule.sh:641
+#: git-submodule.sh:657
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$displaypath'"
 msgstr ""
 "Impossible de fusionner '$sha1' dans le chemin de sous-module '$displaypath'"
 
-#: git-submodule.sh:642
+#: git-submodule.sh:658
 #, sh-format
 msgid "Submodule path '$displaypath': merged in '$sha1'"
 msgstr "Chemin de sous-module '$displaypath' : fusionné dans '$sha1'"
 
-#: git-submodule.sh:647
+#: git-submodule.sh:663
 #, sh-format
 msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'"
 msgstr ""
 "L'exécution de '$command $sha1' a échoué dans le chemin de sous-module "
 "'$displaypath'"
 
-#: git-submodule.sh:648
+#: git-submodule.sh:664
 #, sh-format
 msgid "Submodule path '$displaypath': '$command $sha1'"
 msgstr "Chemin de sous-module '$displaypath' : '$command $sha1'"
 
-#: git-submodule.sh:679
+#: git-submodule.sh:695
 #, sh-format
 msgid "Failed to recurse into submodule path '$displaypath'"
 msgstr "Échec de parcours dans le chemin du sous-module '$displaypath'"
 
-#: git-submodule.sh:775
+#: git-submodule.sh:791
 msgid "The --cached option cannot be used with the --files option"
 msgstr "L'option --cached ne peut pas être utilisée avec l'option --files"
 
-#: git-submodule.sh:827
+#: git-submodule.sh:843
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "mode $mod_dst inattendu"
 
-#: git-submodule.sh:847
+#: git-submodule.sh:863
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr "  Attention : $display_name ne contient pas la validation $sha1_src"
 
-#: git-submodule.sh:850
+#: git-submodule.sh:866
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr "  Attention : $display_name ne contient pas la validation $sha1_dst"
 
-#: git-submodule.sh:853
+#: git-submodule.sh:869
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
@@ -16077,38 +17209,51 @@ msgstr ""
 msgid "See git-${cmd}(1) for details."
 msgstr "Référez-vous à git-${cmd}(1) pour de plus amples détails."
 
-#: git-rebase--interactive.sh:140
+#: git-rebase--interactive.sh:142
 #, sh-format
 msgid "Rebasing ($new_count/$total)"
 msgstr "Rebasage ($new_count/$total)"
 
-#: git-rebase--interactive.sh:156
+#: git-rebase--interactive.sh:158
 msgid ""
 "\n"
 "Commands:\n"
-"p, pick = use commit\n"
-"r, reword = use commit, but edit the commit message\n"
-"e, edit = use commit, but stop for amending\n"
-"s, squash = use commit, but meld into previous commit\n"
-"f, fixup = like \"squash\", but discard this commit's log message\n"
-"x, exec = run command (the rest of the line) using shell\n"
-"d, drop = remove commit\n"
+"p, pick <commit> = use commit\n"
+"r, reword <commit> = use commit, but edit the commit message\n"
+"e, edit <commit> = use commit, but stop for amending\n"
+"s, squash <commit> = use commit, but meld into previous commit\n"
+"f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
+"x, exec <command> = run command (the rest of the line) using shell\n"
+"d, drop <commit> = remove commit\n"
+"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"
 "\n"
 "These lines can be re-ordered; they are executed from top to bottom.\n"
 msgstr ""
 "\n"
 "Commandes :\n"
-" p, pick = utiliser le commit\n"
-" r, reword = utiliser le commit, mais reformuler son message\n"
-" e, edit = utiliser le commit, mais s'arrêter pour le modifier\n"
-" s, squash = utiliser le commit, mais le fusionner avec le précédent\n"
-" f, fixup = comme \"squash\", mais en éliminant son message\n"
-" x, exec = lancer la commande (reste de la ligne) dans un shell\n"
-" d, drop = supprimer le commit\n"
+" p, pick <commit> = utiliser le commit\n"
+" r, reword <commit> = utiliser le commit, mais reformuler son message\n"
+" e, edit <commit> = utiliser le commit, mais s'arrêter pour le modifier\n"
+" s, squash <commit> = utiliser le commit, mais le fusionner avec le "
+"précédent\n"
+" f, fixup <commit> = comme \"squash\", mais en éliminant son message\n"
+" x, exec <commit> = lancer la commande (reste de la ligne) dans un shell\n"
+" d, drop <commit> = supprimer le commit\n"
+" l, label <label> = étiqueter la HEAD courante avec un nom\n"
+" t, reset <label> = réinitialiser HEAD à label\n"
+" m, merge [-C <commit> | -c <commit>] <label> [# <uniligne>]\n"
+"         créer un commit de fusion utilisant le message de fusion original\n"
+"         (ou l'uniligne, si aucun commit de fusion n'a été spécifié).\n"
+"         Utilisez -c <commit> pour reformuler le message de validation.\n"
 "\n"
 "Vous pouvez réordonner ces lignes ; elles sont exécutées de haut en bas.\n"
 
-#: git-rebase--interactive.sh:171
+#: git-rebase--interactive.sh:179
 msgid ""
 "\n"
 "Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
@@ -16117,7 +17262,7 @@ msgstr ""
 "Ne supprimez aucune ligne. Utilisez 'drop' explicitement pour supprimer un "
 "commit.\n"
 
-#: git-rebase--interactive.sh:175
+#: git-rebase--interactive.sh:183
 msgid ""
 "\n"
 "If you remove a line here THAT COMMIT WILL BE LOST.\n"
@@ -16125,7 +17270,7 @@ msgstr ""
 "\n"
 "Si vous éliminez une ligne ici, LE COMMIT CORRESPONDANT SERA PERDU.\n"
 
-#: git-rebase--interactive.sh:213
+#: git-rebase--interactive.sh:221
 #, sh-format
 msgid ""
 "You can amend the commit now, with\n"
@@ -16144,83 +17289,83 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:238
+#: git-rebase--interactive.sh:246
 #, sh-format
 msgid "$sha1: not a commit that can be picked"
 msgstr "$sha1 n'est pas un commit qui peut être picorer"
 
-#: git-rebase--interactive.sh:277
+#: git-rebase--interactive.sh:285
 #, sh-format
 msgid "Invalid commit name: $sha1"
 msgstr "Nom de commit invalide : $sha1"
 
-#: git-rebase--interactive.sh:319
+#: git-rebase--interactive.sh:325
 msgid "Cannot write current commit's replacement sha1"
 msgstr "Impossible de sauver le sha1 du remplaçant du commit en cours"
 
-#: git-rebase--interactive.sh:371
+#: git-rebase--interactive.sh:376
 #, sh-format
 msgid "Fast-forward to $sha1"
 msgstr "Avance rapide sur $sha1"
 
-#: git-rebase--interactive.sh:373
+#: git-rebase--interactive.sh:378
 #, sh-format
 msgid "Cannot fast-forward to $sha1"
 msgstr "Avance rapide impossible sur $sha1"
 
-#: git-rebase--interactive.sh:382
+#: git-rebase--interactive.sh:387
 #, sh-format
 msgid "Cannot move HEAD to $first_parent"
 msgstr "Impossible de déplacer HEAD sur $first_parent"
 
-#: git-rebase--interactive.sh:387
+#: git-rebase--interactive.sh:392
 #, sh-format
 msgid "Refusing to squash a merge: $sha1"
 msgstr "Refus d'écraser un commit de fusion: $sha1"
 
-#: git-rebase--interactive.sh:405
+#: git-rebase--interactive.sh:410
 #, sh-format
 msgid "Error redoing merge $sha1"
 msgstr "Erreur lors de la réapplication de la fusion $sha1"
 
-#: git-rebase--interactive.sh:414
+#: git-rebase--interactive.sh:419
 #, sh-format
 msgid "Could not pick $sha1"
 msgstr "Impossible de picorer $sha1"
 
-#: git-rebase--interactive.sh:423
+#: git-rebase--interactive.sh:428
 #, sh-format
 msgid "This is the commit message #${n}:"
 msgstr "Ceci est le ${n}ième message de validation :"
 
-#: git-rebase--interactive.sh:428
+#: git-rebase--interactive.sh:433
 #, sh-format
 msgid "The commit message #${n} will be skipped:"
 msgstr "Le message de validation ${n} sera ignoré :"
 
-#: git-rebase--interactive.sh:439
+#: git-rebase--interactive.sh:444
 #, sh-format
 msgid "This is a combination of $count commit."
 msgid_plural "This is a combination of $count commits."
 msgstr[0] "Ceci est la combinaison de $count commit."
 msgstr[1] "Ceci est la combinaison de $count commits."
 
-#: git-rebase--interactive.sh:448
+#: git-rebase--interactive.sh:453
 #, sh-format
 msgid "Cannot write $fixup_msg"
 msgstr "Impossible d'écrire $fixup_msg"
 
-#: git-rebase--interactive.sh:451
+#: git-rebase--interactive.sh:456
 msgid "This is a combination of 2 commits."
 msgstr "Ceci est la combinaison de 2 commits."
 
-#: git-rebase--interactive.sh:492 git-rebase--interactive.sh:535
-#: git-rebase--interactive.sh:538
+#: git-rebase--interactive.sh:497 git-rebase--interactive.sh:540
+#: git-rebase--interactive.sh:543
 #, sh-format
 msgid "Could not apply $sha1... $rest"
 msgstr "Impossible d'appliquer $sha1... $rest"
 
-#: git-rebase--interactive.sh:567
+#: git-rebase--interactive.sh:572
 #, sh-format
 msgid ""
 "Could not amend commit after successfully picking $sha1... $rest\n"
@@ -16237,31 +17382,31 @@ msgstr ""
 "le\n"
 "problème avant de pouvoir reformuler le message du commit."
 
-#: git-rebase--interactive.sh:582
+#: git-rebase--interactive.sh:587
 #, sh-format
 msgid "Stopped at $sha1_abbrev... $rest"
 msgstr "Arrêté à $sha1_abbrev... $rest"
 
-#: git-rebase--interactive.sh:597
+#: git-rebase--interactive.sh:602
 #, sh-format
 msgid "Cannot '$squash_style' without a previous commit"
 msgstr "'$squash_style' impossible avec le commit précédent"
 
-#: git-rebase--interactive.sh:639
+#: git-rebase--interactive.sh:644
 #, sh-format
 msgid "Executing: $rest"
 msgstr "Exécution : $rest"
 
-#: git-rebase--interactive.sh:647
+#: git-rebase--interactive.sh:652
 #, sh-format
 msgid "Execution failed: $rest"
 msgstr "L'exécution a échoué : $rest"
 
-#: git-rebase--interactive.sh:649
+#: git-rebase--interactive.sh:654
 msgid "and made changes to the index and/or the working tree"
 msgstr "et a mis à jour l'index ou la copie de travail"
 
-#: git-rebase--interactive.sh:651
+#: git-rebase--interactive.sh:656
 msgid ""
 "You can fix the problem, and then run\n"
 "\n"
@@ -16272,7 +17417,7 @@ msgstr ""
 "git rebase --continue"
 
 #. TRANSLATORS: after these lines is a command to be issued by the user
-#: git-rebase--interactive.sh:664
+#: git-rebase--interactive.sh:669
 #, sh-format
 msgid ""
 "Execution succeeded: $rest\n"
@@ -16287,29 +17432,29 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:675
+#: git-rebase--interactive.sh:680
 #, sh-format
 msgid "Unknown command: $command $sha1 $rest"
 msgstr "Commande inconnue : $command $sha1 $rest"
 
-#: git-rebase--interactive.sh:676
+#: git-rebase--interactive.sh:681
 msgid "Please fix this using 'git rebase --edit-todo'."
 msgstr "Veuillez corriger ceci en utilisant 'git rebase --edit-todo'."
 
-#: git-rebase--interactive.sh:711
+#: git-rebase--interactive.sh:716
 #, sh-format
 msgid "Successfully rebased and updated $head_name."
 msgstr "Rebasage et mise à jour de $head_name avec succès."
 
-#: git-rebase--interactive.sh:735
+#: git-rebase--interactive.sh:740
 msgid "could not detach HEAD"
 msgstr "Impossible de détacher HEAD"
 
-#: git-rebase--interactive.sh:771
+#: git-rebase--interactive.sh:778
 msgid "Could not remove CHERRY_PICK_HEAD"
 msgstr "Impossible de supprimer CHERRY_PICK_HEAD"
 
-#: git-rebase--interactive.sh:776
+#: git-rebase--interactive.sh:783
 #, sh-format
 msgid ""
 "You have staged changes in your working tree.\n"
@@ -16340,12 +17485,12 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: git-rebase--interactive.sh:793
+#: git-rebase--interactive.sh:800
 msgid "Error trying to find the author identity to amend commit"
 msgstr ""
 "Erreur lors de la recherche de l'identité de l'auteur pour corriger le commit"
 
-#: git-rebase--interactive.sh:798
+#: git-rebase--interactive.sh:805
 msgid ""
 "You have uncommitted changes in your working tree. Please commit them\n"
 "first and then run 'git rebase --continue' again."
@@ -16353,11 +17498,11 @@ msgstr ""
 "Vous avez des modifications non validées dans votre copie de travail.\n"
 "Veuillez les valider d'abord, puis relancer 'git rebase --continue'."
 
-#: git-rebase--interactive.sh:803 git-rebase--interactive.sh:807
+#: git-rebase--interactive.sh:810 git-rebase--interactive.sh:814
 msgid "Could not commit staged changes."
 msgstr "impossible de valider les modifications indexées."
 
-#: git-rebase--interactive.sh:836
+#: git-rebase--interactive.sh:843
 msgid ""
 "\n"
 "You are editing the todo file of an ongoing interactive rebase.\n"
@@ -16372,57 +17517,59 @@ msgstr ""
 "    git rebase --continue\n"
 "\n"
 
-#: git-rebase--interactive.sh:844 git-rebase--interactive.sh:1008
+#: git-rebase--interactive.sh:851 git-rebase--interactive.sh:937
 msgid "Could not execute editor"
 msgstr "Impossible de lancer l'éditeur"
 
-#: git-rebase--interactive.sh:860
+#: git-rebase--interactive.sh:872
 #, sh-format
 msgid "Could not checkout $switch_to"
 msgstr "Impossible d'extraire $switch_to"
 
-#: git-rebase--interactive.sh:865
+#: git-rebase--interactive.sh:879
 msgid "No HEAD?"
 msgstr "Pas de HEAD ?"
 
-#: git-rebase--interactive.sh:866
+#: git-rebase--interactive.sh:880
 #, sh-format
 msgid "Could not create temporary $state_dir"
 msgstr "Impossible de créer un répertoire temporaire $state_dir"
 
-#: git-rebase--interactive.sh:869
+#: git-rebase--interactive.sh:883
 msgid "Could not mark as interactive"
 msgstr "Impossible de marquer comme interactif"
 
-#: git-rebase--interactive.sh:879 git-rebase--interactive.sh:884
-msgid "Could not init rewritten commits"
-msgstr "Impossible d'initialiser les commits réécrits"
-
-#: git-rebase--interactive.sh:910
-msgid "Could not generate todo list"
-msgstr "Impossible de générer la liste à-faire"
-
-#: git-rebase--interactive.sh:986
+#: git-rebase--interactive.sh:915
 #, sh-format
 msgid "Rebase $shortrevisions onto $shortonto ($todocount command)"
 msgid_plural "Rebase $shortrevisions onto $shortonto ($todocount commands)"
 msgstr[0] "Rebasage de $shortrevisions sur $shortonto ($todocount commande)"
 msgstr[1] "Rebasage de $shortrevisions sur $shortonto ($todocount commandes)"
 
-#: git-rebase--interactive.sh:991
+#: git-rebase--interactive.sh:920
 msgid ""
 "\n"
-"However, if you remove everything, the rebase will be aborted.\n"
+"\tHowever, if you remove everything, the rebase will be aborted.\n"
 "\n"
+"\t"
 msgstr ""
 "\n"
 "Cependant, si vous effacez tout, le rebasage sera annulé.\n"
 "\n"
+"\t"
 
-#: git-rebase--interactive.sh:998
+#: git-rebase--interactive.sh:927
 msgid "Note that empty commits are commented out"
 msgstr "Veuillez noter que les commits vides sont en commentaire"
 
+#: git-rebase--interactive.sh:980
+msgid "Could not generate todo list"
+msgstr "Impossible de générer la liste à-faire"
+
+#: git-rebase--interactive.sh:1001 git-rebase--interactive.sh:1006
+msgid "Could not init rewritten commits"
+msgstr "Impossible d'initialiser les commits réécrits"
+
 #: git-sh-setup.sh:89 git-sh-setup.sh:94
 #, sh-format
 msgid "usage: $dashless $USAGE"
@@ -16504,68 +17651,68 @@ msgstr "indexé"
 msgid "unstaged"
 msgstr "non-indexé"
 
-#: git-add--interactive.perl:246 git-add--interactive.perl:271
+#: git-add--interactive.perl:253 git-add--interactive.perl:278
 msgid "binary"
 msgstr "binaire"
 
-#: git-add--interactive.perl:255 git-add--interactive.perl:309
+#: git-add--interactive.perl:262 git-add--interactive.perl:316
 msgid "nothing"
 msgstr "rien"
 
-#: git-add--interactive.perl:291 git-add--interactive.perl:306
+#: git-add--interactive.perl:298 git-add--interactive.perl:313
 msgid "unchanged"
 msgstr "inchangé"
 
-#: git-add--interactive.perl:602
+#: git-add--interactive.perl:609
 #, perl-format
 msgid "added %d path\n"
 msgid_plural "added %d paths\n"
 msgstr[0] "%d chemin ajouté\n"
 msgstr[1] "%d chemins ajoutés\n"
 
-#: git-add--interactive.perl:605
+#: git-add--interactive.perl:612
 #, perl-format
 msgid "updated %d path\n"
 msgid_plural "updated %d paths\n"
 msgstr[0] "%d chemin mis à jour\n"
 msgstr[1] "%d chemins mis à jour\n"
 
-#: git-add--interactive.perl:608
+#: git-add--interactive.perl:615
 #, perl-format
 msgid "reverted %d path\n"
 msgid_plural "reverted %d paths\n"
 msgstr[0] "%d chemin inversé\n"
 msgstr[1] "%d chemins inversés\n"
 
-#: git-add--interactive.perl:611
+#: git-add--interactive.perl:618
 #, perl-format
 msgid "touched %d path\n"
 msgid_plural "touched %d paths\n"
 msgstr[0] "%d chemin touché\n"
 msgstr[1] "%d chemins touchés\n"
 
-#: git-add--interactive.perl:620
+#: git-add--interactive.perl:627
 msgid "Update"
 msgstr "Mise à jour"
 
-#: git-add--interactive.perl:632
+#: git-add--interactive.perl:639
 msgid "Revert"
 msgstr "Inverser"
 
-#: git-add--interactive.perl:655
+#: git-add--interactive.perl:662
 #, perl-format
 msgid "note: %s is untracked now.\n"
 msgstr "note : %s n'est plus suivi à présent.\n"
 
-#: git-add--interactive.perl:666
+#: git-add--interactive.perl:673
 msgid "Add untracked"
 msgstr "Ajouter un fichier non-suivi"
 
-#: git-add--interactive.perl:672
+#: git-add--interactive.perl:679
 msgid "No untracked files.\n"
 msgstr "Aucun Fichier non suivi.\n"
 
-#: git-add--interactive.perl:1026
+#: git-add--interactive.perl:1033
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for staging."
@@ -16573,7 +17720,7 @@ msgstr ""
 "Si le patch s'applique proprement, la section éditée sera\n"
 "immédiatement marquée comme indexée."
 
-#: git-add--interactive.perl:1029
+#: git-add--interactive.perl:1036
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for stashing."
@@ -16581,7 +17728,7 @@ msgstr ""
 "Si le patch s'applique proprement, la section éditée sera\n"
 "immédiatement marquée comme remisée."
 
-#: git-add--interactive.perl:1032
+#: git-add--interactive.perl:1039
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for unstaging."
@@ -16589,7 +17736,7 @@ msgstr ""
 "Si le patch s'applique proprement, la section éditée sera\n"
 "immédiatement marquée comme desindexée."
 
-#: git-add--interactive.perl:1035 git-add--interactive.perl:1044
+#: git-add--interactive.perl:1042 git-add--interactive.perl:1051
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for applying."
@@ -16597,7 +17744,7 @@ msgstr ""
 "Si le patch s'applique proprement, la section éditée sera\n"
 "immédiatement marquée comme appliquée."
 
-#: git-add--interactive.perl:1038 git-add--interactive.perl:1041
+#: git-add--interactive.perl:1045 git-add--interactive.perl:1048
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for discarding."
@@ -16605,17 +17752,17 @@ msgstr ""
 "Si le patch s'applique proprement, la section éditée sera\n"
 "immédiatement marquée comme éliminée."
 
-#: git-add--interactive.perl:1078
+#: git-add--interactive.perl:1085
 #, perl-format
 msgid "failed to open hunk edit file for writing: %s"
 msgstr "impossible d'ouvrir le fichier d'édition de section en écriture : %s"
 
-#: git-add--interactive.perl:1079
+#: git-add--interactive.perl:1086
 msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
 msgstr ""
 "Mode d'édition manuelle de section -- voir ci-dessous pour un guide rapide.\n"
 
-#: git-add--interactive.perl:1085
+#: git-add--interactive.perl:1092
 #, perl-format
 msgid ""
 "---\n"
@@ -16629,7 +17776,7 @@ msgstr ""
 "Les lignes commençant par %s seront éliminées.\n"
 
 #. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
-#: git-add--interactive.perl:1093
+#: git-add--interactive.perl:1100
 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"
@@ -16639,7 +17786,7 @@ msgstr ""
 "l'éditer à nouveau. Si toutes les lignes de la section sont supprimées,\n"
 "alors l'édition sera abandonnée et la section conservée.\n"
 
-#: git-add--interactive.perl:1107
+#: git-add--interactive.perl:1114
 #, perl-format
 msgid "failed to open hunk edit file for reading: %s"
 msgstr "échec de l'ouverture du fichier d'édition de section en lecture : %s"
@@ -16650,14 +17797,14 @@ msgstr "échec de l'ouverture du fichier d'édition de section en lecture : %s"
 #. 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:1206
+#: git-add--interactive.perl:1213
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
 "Votre section éditée ne s'applique pas. L'éditer à nouveau (\"no\" "
 "l'élimine !) [y|n] ? "
 
-#: git-add--interactive.perl:1215
+#: git-add--interactive.perl:1222
 msgid ""
 "y - stage this hunk\n"
 "n - do not stage this hunk\n"
@@ -16671,7 +17818,7 @@ msgstr ""
 "a - indexer cette section et toutes les suivantes de ce fichier\n"
 "d - ne pas indexer cette section ni les suivantes de ce fichier"
 
-#: git-add--interactive.perl:1221
+#: git-add--interactive.perl:1228
 msgid ""
 "y - stash this hunk\n"
 "n - do not stash this hunk\n"
@@ -16685,7 +17832,7 @@ msgstr ""
 "a - remiser cette section et toutes les suivantes de ce fichier\n"
 "d - ne pas remiser cette section ni les suivantes de ce fichier"
 
-#: git-add--interactive.perl:1227
+#: git-add--interactive.perl:1234
 msgid ""
 "y - unstage this hunk\n"
 "n - do not unstage this hunk\n"
@@ -16699,7 +17846,7 @@ msgstr ""
 "a - désindexer cette section et toutes les suivantes de ce fichier\n"
 "d - ne pas désindexer cette section ni les suivantes de ce fichier"
 
-#: git-add--interactive.perl:1233
+#: git-add--interactive.perl:1240
 msgid ""
 "y - apply this hunk to index\n"
 "n - do not apply this hunk to index\n"
@@ -16713,7 +17860,7 @@ msgstr ""
 "a - appliquer cette section et toutes les suivantes de ce fichier\n"
 "d - ne pas appliquer cette section ni les suivantes de ce fichier"
 
-#: git-add--interactive.perl:1239
+#: git-add--interactive.perl:1246
 msgid ""
 "y - discard this hunk from worktree\n"
 "n - do not discard this hunk from worktree\n"
@@ -16727,7 +17874,7 @@ msgstr ""
 "a - supprimer cette section et toutes les suivantes de ce fichier\n"
 "d - ne pas supprimer cette section ni les suivantes de ce fichier"
 
-#: git-add--interactive.perl:1245
+#: git-add--interactive.perl:1252
 msgid ""
 "y - discard this hunk from index and worktree\n"
 "n - do not discard this hunk from index and worktree\n"
@@ -16741,7 +17888,7 @@ msgstr ""
 "a - éliminer cette section et toutes les suivantes de ce fichier\n"
 "d - ne pas éliminer cette section ni les suivantes de ce fichier"
 
-#: git-add--interactive.perl:1251
+#: git-add--interactive.perl:1258
 msgid ""
 "y - apply this hunk to index and worktree\n"
 "n - do not apply this hunk to index and worktree\n"
@@ -16755,7 +17902,7 @@ msgstr ""
 "a - appliquer cette section et toutes les suivantes de ce fichier\n"
 "d - ne pas appliquer cette section ni les suivantes de ce fichier"
 
-#: git-add--interactive.perl:1266
+#: git-add--interactive.perl:1273
 msgid ""
 "g - select a hunk to go to\n"
 "/ - search for a hunk matching the given regex\n"
@@ -16777,211 +17924,218 @@ msgstr ""
 "e - éditer manuellement la section actuelle\n"
 "? - afficher l'aide\n"
 
-#: git-add--interactive.perl:1297
+#: git-add--interactive.perl:1304
 msgid "The selected hunks do not apply to the index!\n"
 msgstr "Les sections sélectionnées ne s'applique pas à l'index !\n"
 
-#: git-add--interactive.perl:1298
+#: git-add--interactive.perl:1305
 msgid "Apply them to the worktree anyway? "
 msgstr "Les appliquer quand même à l'arbre de travail ? "
 
-#: git-add--interactive.perl:1301
+#: git-add--interactive.perl:1308
 msgid "Nothing was applied.\n"
 msgstr "Rien n'a été appliqué.\n"
 
-#: git-add--interactive.perl:1312
+#: git-add--interactive.perl:1319
 #, perl-format
 msgid "ignoring unmerged: %s\n"
 msgstr "fichier non-fusionné ignoré : %s\n"
 
-#: git-add--interactive.perl:1321
+#: git-add--interactive.perl:1328
 msgid "Only binary files changed.\n"
 msgstr "Seuls des fichiers binaires ont changé.\n"
 
-#: git-add--interactive.perl:1323
+#: git-add--interactive.perl:1330
 msgid "No changes.\n"
 msgstr "Aucune modification.\n"
 
-#: git-add--interactive.perl:1331
+#: git-add--interactive.perl:1338
 msgid "Patch update"
 msgstr "Mise à jour par patch"
 
-#: git-add--interactive.perl:1383
+#: git-add--interactive.perl:1390
 #, perl-format
 msgid "Stage mode change [y,n,q,a,d%s,?]? "
 msgstr "Indexer le changement de mode [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1384
+#: git-add--interactive.perl:1391
 #, perl-format
 msgid "Stage deletion [y,n,q,a,d%s,?]? "
 msgstr "Indexer la suppression [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1385
+#: git-add--interactive.perl:1392
 #, perl-format
 msgid "Stage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Indexer cette section [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1388
+#: git-add--interactive.perl:1395
 #, perl-format
 msgid "Stash mode change [y,n,q,a,d%s,?]? "
 msgstr "Remiser le changement de mode [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1389
+#: git-add--interactive.perl:1396
 #, perl-format
 msgid "Stash deletion [y,n,q,a,d%s,?]? "
 msgstr "Remiser la suppression [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1390
+#: git-add--interactive.perl:1397
 #, perl-format
 msgid "Stash this hunk [y,n,q,a,d%s,?]? "
 msgstr "Remiser cette section [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1393
+#: git-add--interactive.perl:1400
 #, perl-format
 msgid "Unstage mode change [y,n,q,a,d%s,?]? "
 msgstr "Désindexer le changement de mode [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1394
+#: git-add--interactive.perl:1401
 #, perl-format
 msgid "Unstage deletion [y,n,q,a,d%s,?]? "
 msgstr "Désindexer la suppression [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1395
+#: git-add--interactive.perl:1402
 #, perl-format
 msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Désindexer cette section [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1398
+#: git-add--interactive.perl:1405
 #, perl-format
 msgid "Apply mode change to index [y,n,q,a,d%s,?]? "
 msgstr "Appliquer le changement de mode à l'index [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1399
+#: git-add--interactive.perl:1406
 #, perl-format
 msgid "Apply deletion to index [y,n,q,a,d%s,?]? "
 msgstr "Appliquer la suppression à l'index [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1400
+#: git-add--interactive.perl:1407
 #, perl-format
 msgid "Apply this hunk to index [y,n,q,a,d%s,?]? "
 msgstr "Appliquer cette section à l'index [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1403
+#: git-add--interactive.perl:1410
 #, perl-format
 msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? "
 msgstr "Abandonner le changement de mode dans l'arbre [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1404
+#: git-add--interactive.perl:1411
 #, perl-format
 msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? "
 msgstr "Abandonner la suppression dans l'arbre [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1405
+#: git-add--interactive.perl:1412
 #, perl-format
 msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
 msgstr "Abandonner cette section dans l'arbre [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1408
+#: git-add--interactive.perl:1415
 #, perl-format
 msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Abandonner le changement de mode dans l'index et l'arbre [y,n,q,a,d%s,?] ? "
+msgstr ""
+"Abandonner le changement de mode dans l'index et l'arbre [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1409
+#: git-add--interactive.perl:1416
 #, perl-format
 msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Abandonner la suppression de l'index et de l'arbre [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1410
+#: git-add--interactive.perl:1417
 #, perl-format
 msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Supprimer la section dans l'index et l'arbre de travail [y,n,q,a,d%s,?] ? "
+msgstr ""
+"Supprimer la section dans l'index et l'arbre de travail [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1413
+#: git-add--interactive.perl:1420
 #, perl-format
 msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Appliquer le changement de mode dans l'index et l'arbre de travail [y,n,q,a,d%s,?] ? "
+msgstr ""
+"Appliquer le changement de mode dans l'index et l'arbre de travail [y,n,q,a,d"
+"%s,?] ? "
 
-#: git-add--interactive.perl:1414
+#: git-add--interactive.perl:1421
 #, perl-format
 msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Appliquer la suppression dans l'index et l'arbre de travail [y,n,q,a,d%s,?] ? "
+msgstr ""
+"Appliquer la suppression dans l'index et l'arbre de travail [y,n,q,a,d"
+"%s,?] ? "
 
-#: git-add--interactive.perl:1415
+#: git-add--interactive.perl:1422
 #, perl-format
 msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
-msgstr "Appliquer la section à l'index et l'arbre de travail [y,n,q,a,d%s,?] ? "
+msgstr ""
+"Appliquer la section à l'index et l'arbre de travail [y,n,q,a,d%s,?] ? "
 
-#: git-add--interactive.perl:1515
+#: git-add--interactive.perl:1522
 msgid "No other hunks to goto\n"
 msgstr "Aucune autre section à atteindre\n"
 
-#: git-add--interactive.perl:1522
+#: git-add--interactive.perl:1529
 msgid "go to which hunk (<ret> to see more)? "
 msgstr "aller à quelle section (<ret> pour voir plus) ? "
 
-#: git-add--interactive.perl:1524
+#: git-add--interactive.perl:1531
 msgid "go to which hunk? "
 msgstr "aller à quelle section ? "
 
-#: git-add--interactive.perl:1533
+#: git-add--interactive.perl:1540
 #, perl-format
 msgid "Invalid number: '%s'\n"
 msgstr "Nombre invalide : '%s'\n"
 
-#: git-add--interactive.perl:1538
+#: git-add--interactive.perl:1545
 #, perl-format
 msgid "Sorry, only %d hunk available.\n"
 msgid_plural "Sorry, only %d hunks available.\n"
 msgstr[0] "Désolé, %d seule section disponible.\n"
 msgstr[1] "Désolé, Seulement %d sections disponibles.\n"
 
-#: git-add--interactive.perl:1564
+#: git-add--interactive.perl:1571
 msgid "No other hunks to search\n"
 msgstr "aucune autre section à rechercher\n"
 
-#: git-add--interactive.perl:1568
+#: git-add--interactive.perl:1575
 msgid "search for regex? "
 msgstr "rechercher la regex ? "
 
-#: git-add--interactive.perl:1581
+#: git-add--interactive.perl:1588
 #, perl-format
 msgid "Malformed search regexp %s: %s\n"
 msgstr "Regex de recherche malformée %s : %s\n"
 
-#: git-add--interactive.perl:1591
+#: git-add--interactive.perl:1598
 msgid "No hunk matches the given pattern\n"
 msgstr "Aucune section ne correspond au motif donné\n"
 
-#: git-add--interactive.perl:1603 git-add--interactive.perl:1625
+#: git-add--interactive.perl:1610 git-add--interactive.perl:1632
 msgid "No previous hunk\n"
 msgstr "Pas de section précédente\n"
 
-#: git-add--interactive.perl:1612 git-add--interactive.perl:1631
+#: git-add--interactive.perl:1619 git-add--interactive.perl:1638
 msgid "No next hunk\n"
 msgstr "Pas de section suivante\n"
 
-#: git-add--interactive.perl:1637
+#: git-add--interactive.perl:1644
 msgid "Sorry, cannot split this hunk\n"
 msgstr "Désolé, impossible de découper cette section\n"
 
-#: git-add--interactive.perl:1643
+#: git-add--interactive.perl:1650
 #, perl-format
 msgid "Split into %d hunk.\n"
 msgid_plural "Split into %d hunks.\n"
 msgstr[0] "Découpée en %d section.\n"
 msgstr[1] "Découpée en %d sections.\n"
 
-#: git-add--interactive.perl:1653
+#: git-add--interactive.perl:1660
 msgid "Sorry, cannot edit this hunk\n"
 msgstr "Désolé, impossible d'éditer cette section\n"
 
-#: git-add--interactive.perl:1699
+#: git-add--interactive.perl:1706
 msgid "Review diff"
 msgstr "Réviser la différence"
 
 #. TRANSLATORS: please do not translate the command names
 #. 'status', 'update', 'revert', etc.
-#: git-add--interactive.perl:1718
+#: git-add--interactive.perl:1725
 msgid ""
 "status        - show paths with changes\n"
 "update        - add working tree state to the staged set of changes\n"
@@ -16999,18 +18153,18 @@ msgstr ""
 "diff          - visualiser les diff entre HEAD et l'index\n"
 "add untracked - ajouter les fichiers non-suivis aux modifications à indexer\n"
 
-#: git-add--interactive.perl:1735 git-add--interactive.perl:1740
-#: git-add--interactive.perl:1743 git-add--interactive.perl:1750
-#: git-add--interactive.perl:1754 git-add--interactive.perl:1760
+#: git-add--interactive.perl:1742 git-add--interactive.perl:1747
+#: git-add--interactive.perl:1750 git-add--interactive.perl:1757
+#: git-add--interactive.perl:1761 git-add--interactive.perl:1767
 msgid "missing --"
 msgstr "-- manquant"
 
-#: git-add--interactive.perl:1756
+#: git-add--interactive.perl:1763
 #, perl-format
 msgid "unknown --patch mode: %s"
 msgstr "mode de --patch inconnu : %s"
 
-#: git-add--interactive.perl:1762 git-add--interactive.perl:1768
+#: git-add--interactive.perl:1769 git-add--interactive.perl:1775
 #, perl-format
 msgid "invalid argument %s, expecting --"
 msgstr "argument invalide %s, -- attendu"
@@ -17052,7 +18206,9 @@ msgstr "Lancement de git format-patch impossible à l'extérieur d'un dépôt\n"
 msgid ""
 "`batch-size` and `relogin` must be specified together (via command-line or "
 "configuration option)\n"
-msgstr "`batch-size` et `relogin` doivent être spécifiés ensembles (via la ligne de commande ou des options de configuration)\n"
+msgstr ""
+"`batch-size` et `relogin` doivent être spécifiés ensembles (via la ligne de "
+"commande ou des options de configuration)\n"
 
 #: git-send-email.perl:456
 #, perl-format
@@ -17226,7 +18382,7 @@ msgstr "Que faire de cette adresse ? ([q]uitter|[d]élaisser|[e]diter): "
 msgid "CA path \"%s\" does not exist"
 msgstr "le chemin vers la CA \"%s\" n'existe pas"
 
-#: git-send-email.perl:1395
+#: git-send-email.perl:1400
 msgid ""
 "    The Cc list above has been expanded by additional\n"
 "    addresses found in the patch commit message. By default\n"
@@ -17250,137 +18406,167 @@ msgstr ""
 "   lancez 'git config --global sendemail.confirm auto'.\n"
 "\n"
 
-#. TRANSLATORS: Make sure to include [y] [n] [q] [a] in your
+#. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
 #. translation. The program will only accept English input
 #. at this point.
-#: git-send-email.perl:1410
-msgid "Send this email? ([y]es|[n]o|[q]uit|[a]ll): "
-msgstr "Envoyer ce courriel ? ([y]es|[n]o|[q]uit|[a]ll) : "
+#: git-send-email.perl:1415
+msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
+msgstr "Envoyer ce courriel ? ([y]es|[n]o|[e]dit|[q]uit|[a]ll) : "
 
-#: git-send-email.perl:1413
+#: git-send-email.perl:1418
 msgid "Send this email reply required"
 msgstr "Une réponse est nécessaire"
 
-#: git-send-email.perl:1439
+#: git-send-email.perl:1446
 msgid "The required SMTP server is not properly defined."
 msgstr "Le serveur SMTP nécessaire n'est pas défini correctement."
 
-#: git-send-email.perl:1486
+#: git-send-email.perl:1493
 #, perl-format
 msgid "Server does not support STARTTLS! %s"
 msgstr "Le serveur ne supporte pas STARTTLS ! %s"
 
-#: git-send-email.perl:1491 git-send-email.perl:1495
+#: git-send-email.perl:1498 git-send-email.perl:1502
 #, perl-format
 msgid "STARTTLS failed! %s"
 msgstr "echec de STARTTLS ! %s"
 
-#: git-send-email.perl:1505
+#: git-send-email.perl:1512
 msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug."
 msgstr ""
 "Impossible d'initialiser SMTP. Vérifiez la configuration et utilisez --smtp-"
 "debug."
 
-#: git-send-email.perl:1523
+#: git-send-email.perl:1530
 #, perl-format
 msgid "Failed to send %s\n"
 msgstr "échec de l'envoi de %s\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Dry-Sent %s\n"
 msgstr "Envoi simulé de %s\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Sent %s\n"
 msgstr "%s envoyé\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "Dry-OK. Log says:\n"
 msgstr "Simulation OK. Le journal indique :\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "OK. Log says:\n"
 msgstr "OK. Le journal indique :\n"
 
-#: git-send-email.perl:1540
+#: git-send-email.perl:1547
 msgid "Result: "
 msgstr "Résultat : "
 
-#: git-send-email.perl:1543
+#: git-send-email.perl:1550
 msgid "Result: OK\n"
 msgstr "Résultat : OK\n"
 
-#: git-send-email.perl:1556
+#: git-send-email.perl:1568
 #, perl-format
 msgid "can't open file %s"
 msgstr "impossible d'ouvrir le fichier %s"
 
-#: git-send-email.perl:1603 git-send-email.perl:1623
+#: git-send-email.perl:1615 git-send-email.perl:1635
 #, perl-format
 msgid "(mbox) Adding cc: %s from line '%s'\n"
 msgstr "(mbox) Ajout de cc: %s depuis la ligne '%s'\n"
 
-#: git-send-email.perl:1609
+#: git-send-email.perl:1621
 #, perl-format
 msgid "(mbox) Adding to: %s from line '%s'\n"
 msgstr "(mbox) Ajout de to: %s depuis la ligne '%s'\n"
 
-#: git-send-email.perl:1657
+#: git-send-email.perl:1674
 #, perl-format
 msgid "(non-mbox) Adding cc: %s from line '%s'\n"
 msgstr "(non-mbox) Ajout de cc: %s depuis la ligne '%s'\n"
 
-#: git-send-email.perl:1682
+#: git-send-email.perl:1699
 #, perl-format
 msgid "(body) Adding cc: %s from line '%s'\n"
 msgstr "(corps) Ajout de cc: %s depuis la ligne '%s'\n"
 
-#: git-send-email.perl:1788
+#: git-send-email.perl:1817
 #, perl-format
 msgid "(%s) Could not execute '%s'"
 msgstr "(%s) Impossible d'exécuter '%s'"
 
-#: git-send-email.perl:1795
+#: git-send-email.perl:1824
 #, perl-format
 msgid "(%s) Adding %s: %s from: '%s'\n"
 msgstr "(%s) Ajout de %s : %s depuis : '%s'\n"
 
-#: git-send-email.perl:1799
+#: git-send-email.perl:1828
 #, perl-format
 msgid "(%s) failed to close pipe to '%s'"
 msgstr "(%s) échec de la fermeture du pipe vers '%s'"
 
-#: git-send-email.perl:1826
+#: git-send-email.perl:1855
 msgid "cannot send message as 7bit"
 msgstr "impossible d'envoyer un message comme 7bit"
 
-#: git-send-email.perl:1834
+#: git-send-email.perl:1863
 msgid "invalid transfer encoding"
 msgstr "codage de transfert invalide"
 
-#: git-send-email.perl:1872 git-send-email.perl:1923 git-send-email.perl:1933
+#: git-send-email.perl:1901 git-send-email.perl:1952 git-send-email.perl:1962
 #, perl-format
 msgid "unable to open %s: %s\n"
 msgstr "impossible d'ouvrir %s :%s\n"
 
-#: git-send-email.perl:1875
+#: git-send-email.perl:1904
 #, perl-format
 msgid "%s: patch contains a line longer than 998 characters"
 msgstr "%s : le patch contient une ligne plus longue que 998 caractères"
 
-#: git-send-email.perl:1891
+#: git-send-email.perl:1920
 #, perl-format
 msgid "Skipping %s with backup suffix '%s'.\n"
 msgstr "%s sauté avec un suffix de sauvegarde '%s'.\n"
 
 #. TRANSLATORS: please keep "[y|N]" as is.
-#: git-send-email.perl:1895
+#: git-send-email.perl:1924
 #, perl-format
 msgid "Do you really want to send %s? [y|N]: "
 msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : "
 
+#~ msgid "Everyday Git With 20 Commands Or So"
+#~ msgstr "Git de tous les jours avec à peu près 20 commandes"
+
+#~ msgid "Could not open '%s' for writing"
+#~ msgstr "Impossible d'ouvrir '%s' en écriture"
+
+#~ msgid ""
+#~ "unexpected 1st line of squash message:\n"
+#~ "\n"
+#~ "\t%.*s"
+#~ msgstr ""
+#~ "première ligne de message de compression inattendue :\n"
+#~ "\n"
+#~ "\t%.*s"
+
+#~ msgid ""
+#~ "invalid 1st line of squash message:\n"
+#~ "\n"
+#~ "\t%.*s"
+#~ msgstr ""
+#~ "première ligne de message de compression invalide :\n"
+#~ "\n"
+#~ "\t%.*s"
+
+#~ msgid "BUG: returned path string doesn't match cwd?"
+#~ msgstr "BUG : le chemin renvoyé ne correspond pas à cwd ?"
+
+#~ msgid "Error in object"
+#~ msgstr "Erreur dans l'objet"
+
 #~ msgid "git fetch-pack: expected ACK/NAK, got EOF"
 #~ msgstr "git fetch-pack : ACK/NACK attendu, EOF reçu"
 
@@ -17560,9 +18746,6 @@ msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : "
 #~ msgid "blob object"
 #~ msgstr "objet blob"
 
-#~ msgid "other tag object"
-#~ msgstr "objet étiquette autre"
-
 #~ msgid ""
 #~ "There is nothing to exclude from by :(exclude) patterns.\n"
 #~ "Perhaps you forgot to add either ':/' or '.' ?"
@@ -17898,9 +19081,6 @@ msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : "
 #~ "Veuillez indexer vos modifications de .gitmodules ou remisez-les pour "
 #~ "continuer"
 
-#~ msgid "could not verify the tag '%s'"
-#~ msgstr "impossible de vérifier l'étiquette '%s'"
-
 #~ msgid "failed to remove: %s"
 #~ msgstr "échec de la suppression de %s"
 
@@ -18114,9 +19294,6 @@ msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : "
 #~ msgid "no branch specified"
 #~ msgstr "aucune branche spécifiée"
 
-#~ msgid "check a branch out in a separate working directory"
-#~ msgstr "extraire une branche dans un répertoire de travail séparé"
-
 #~ msgid "prune .git/worktrees"
 #~ msgstr "éliminer .git/worktrees"
 
index ab5d1796712b7317bf400cdd49608f13912044fe..d4c7f0bec6e3d7bc34c718f23cd3f1871cc2f7fe 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2018-03-16 07:29+0800\n"
+"POT-Creation-Date: 2018-06-16 22:06+0800\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -18,59 +18,59 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
-#: advice.c:62
+#: advice.c:92
 #, c-format
-msgid "hint: %.*s\n"
+msgid "%shint: %.*s%s\n"
 msgstr ""
 
-#: advice.c:90
+#: advice.c:137
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr ""
 
-#: advice.c:92
+#: advice.c:139
 msgid "Committing is not possible because you have unmerged files."
 msgstr ""
 
-#: advice.c:94
+#: advice.c:141
 msgid "Merging is not possible because you have unmerged files."
 msgstr ""
 
-#: advice.c:96
+#: advice.c:143
 msgid "Pulling is not possible because you have unmerged files."
 msgstr ""
 
-#: advice.c:98
+#: advice.c:145
 msgid "Reverting is not possible because you have unmerged files."
 msgstr ""
 
-#: advice.c:100
+#: advice.c:147
 #, c-format
 msgid "It is not possible to %s because you have unmerged files."
 msgstr ""
 
-#: advice.c:108
+#: advice.c:155
 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 ""
 
-#: advice.c:116
+#: advice.c:163
 msgid "Exiting because of an unresolved conflict."
 msgstr ""
 
-#: advice.c:121 builtin/merge.c:1251
+#: advice.c:168 builtin/merge.c:1250
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
 msgstr ""
 
-#: advice.c:123
+#: advice.c:170
 msgid "Please, commit your changes before merging."
 msgstr ""
 
-#: advice.c:124
+#: advice.c:171
 msgid "Exiting because of unfinished merge."
 msgstr ""
 
-#: advice.c:130
+#: advice.c:177
 #, c-format
 msgid ""
 "Note: checking out '%s'.\n"
@@ -315,7 +315,7 @@ msgstr ""
 msgid "cannot checkout %s"
 msgstr ""
 
-#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:277
+#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:278
 #, c-format
 msgid "failed to read %s"
 msgstr ""
@@ -514,7 +514,7 @@ msgstr[1] ""
 msgid "truncating .rej filename to %.*s.rej"
 msgstr ""
 
-#: apply.c:4545 builtin/fetch.c:775 builtin/fetch.c:1025
+#: apply.c:4545 builtin/fetch.c:786 builtin/fetch.c:1036
 #, c-format
 msgid "cannot open %s"
 msgstr ""
@@ -568,15 +568,15 @@ msgid_plural "%d lines applied after fixing whitespace errors."
 msgstr[0] ""
 msgstr[1] ""
 
-#: apply.c:4894 builtin/add.c:539 builtin/mv.c:298 builtin/rm.c:390
+#: apply.c:4894 builtin/add.c:538 builtin/mv.c:300 builtin/rm.c:389
 msgid "Unable to write new index file"
 msgstr ""
 
 #: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257
-#: builtin/clone.c:118 builtin/fetch.c:127 builtin/pull.c:193
-#: builtin/submodule--helper.c:403 builtin/submodule--helper.c:1197
-#: builtin/submodule--helper.c:1200 builtin/submodule--helper.c:1567
-#: builtin/submodule--helper.c:1570 builtin/submodule--helper.c:1787
+#: builtin/clone.c:120 builtin/fetch.c:126 builtin/pull.c:198
+#: builtin/submodule--helper.c:405 builtin/submodule--helper.c:1210
+#: builtin/submodule--helper.c:1213 builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1587 builtin/submodule--helper.c:1807
 #: git-add--interactive.perl:197
 msgid "path"
 msgstr ""
@@ -651,7 +651,7 @@ msgstr ""
 
 #: apply.c:4960 builtin/am.c:2242 builtin/interpret-trailers.c:95
 #: builtin/interpret-trailers.c:97 builtin/interpret-trailers.c:99
-#: builtin/pack-objects.c:3035
+#: builtin/pack-objects.c:3177
 msgid "action"
 msgstr ""
 
@@ -679,9 +679,9 @@ msgstr ""
 msgid "allow overlapping hunks"
 msgstr ""
 
-#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21
-#: builtin/commit.c:1276 builtin/count-objects.c:96 builtin/fsck.c:665
-#: builtin/log.c:1901 builtin/mv.c:123 builtin/read-tree.c:125
+#: apply.c:4977 builtin/add.c:290 builtin/check-ignore.c:21
+#: builtin/commit.c:1301 builtin/count-objects.c:98 builtin/fsck.c:666
+#: builtin/log.c:1901 builtin/mv.c:122 builtin/read-tree.c:124
 msgid "be verbose"
 msgstr ""
 
@@ -718,98 +718,98 @@ msgstr ""
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr ""
 
-#: archive.c:351 builtin/add.c:176 builtin/add.c:515 builtin/rm.c:299
+#: archive.c:351 builtin/add.c:176 builtin/add.c:514 builtin/rm.c:298
 #, c-format
 msgid "pathspec '%s' did not match any files"
 msgstr ""
 
-#: archive.c:436
+#: archive.c:434
 msgid "fmt"
 msgstr ""
 
-#: archive.c:436
+#: archive.c:434
 msgid "archive format"
 msgstr ""
 
-#: archive.c:437 builtin/log.c:1462
+#: archive.c:435 builtin/log.c:1462
 msgid "prefix"
 msgstr ""
 
-#: archive.c:438
+#: archive.c:436
 msgid "prepend prefix to each pathname in the archive"
 msgstr ""
 
-#: archive.c:439 builtin/blame.c:702 builtin/blame.c:703 builtin/config.c:62
-#: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:869
+#: archive.c:437 builtin/blame.c:813 builtin/blame.c:814 builtin/config.c:127
+#: builtin/fast-export.c:1007 builtin/fast-export.c:1009 builtin/grep.c:869
 #: builtin/hash-object.c:103 builtin/ls-files.c:551 builtin/ls-files.c:554
-#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120
+#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:119
 #: parse-options.h:165
 msgid "file"
 msgstr ""
 
-#: archive.c:440 builtin/archive.c:89
+#: archive.c:438 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr ""
 
-#: archive.c:442
+#: archive.c:440
 msgid "read .gitattributes in working directory"
 msgstr ""
 
-#: archive.c:443
+#: archive.c:441
 msgid "report archived files on stderr"
 msgstr ""
 
-#: archive.c:444
+#: archive.c:442
 msgid "store only"
 msgstr ""
 
-#: archive.c:445
+#: archive.c:443
 msgid "compress faster"
 msgstr ""
 
-#: archive.c:453
+#: archive.c:451
 msgid "compress better"
 msgstr ""
 
-#: archive.c:456
+#: archive.c:454
 msgid "list supported archive formats"
 msgstr ""
 
-#: archive.c:458 builtin/archive.c:90 builtin/clone.c:108 builtin/clone.c:111
-#: builtin/submodule--helper.c:1209 builtin/submodule--helper.c:1576
+#: archive.c:456 builtin/archive.c:90 builtin/clone.c:110 builtin/clone.c:113
+#: builtin/submodule--helper.c:1222 builtin/submodule--helper.c:1593
 msgid "repo"
 msgstr ""
 
-#: archive.c:459 builtin/archive.c:91
+#: archive.c:457 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr ""
 
-#: archive.c:460 builtin/archive.c:92 builtin/notes.c:489
+#: archive.c:458 builtin/archive.c:92 builtin/notes.c:489
 msgid "command"
 msgstr ""
 
-#: archive.c:461 builtin/archive.c:93
+#: archive.c:459 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr ""
 
-#: archive.c:468
+#: archive.c:466
 msgid "Unexpected option --remote"
 msgstr ""
 
-#: archive.c:470
+#: archive.c:468
 msgid "Option --exec can only be used together with --remote"
 msgstr ""
 
-#: archive.c:472
+#: archive.c:470
 msgid "Unexpected option --output"
 msgstr ""
 
-#: archive.c:494
+#: archive.c:492
 #, c-format
 msgid "Unknown archive format '%s'"
 msgstr ""
 
-#: archive.c:501
+#: archive.c:499
 #, c-format
 msgid "Argument not supported for format '%s': -%d"
 msgstr ""
@@ -825,43 +825,43 @@ msgid ""
 "Use '\\!' for literal leading exclamation."
 msgstr ""
 
-#: bisect.c:460
+#: bisect.c:461
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr ""
 
-#: bisect.c:668
+#: bisect.c:669
 #, c-format
 msgid "We cannot bisect more!\n"
 msgstr ""
 
-#: bisect.c:722
+#: bisect.c:723
 #, c-format
 msgid "Not a valid commit name %s"
 msgstr ""
 
-#: bisect.c:746
+#: bisect.c:747
 #, c-format
 msgid ""
 "The merge base %s is bad.\n"
 "This means the bug has been fixed between %s and [%s].\n"
 msgstr ""
 
-#: bisect.c:751
+#: bisect.c:752
 #, c-format
 msgid ""
 "The merge base %s is new.\n"
 "The property has changed between %s and [%s].\n"
 msgstr ""
 
-#: bisect.c:756
+#: bisect.c:757
 #, c-format
 msgid ""
 "The merge base %s is %s.\n"
 "This means the first '%s' commit is between %s and [%s].\n"
 msgstr ""
 
-#: bisect.c:764
+#: bisect.c:765
 #, c-format
 msgid ""
 "Some %s revs are not ancestors of the %s rev.\n"
@@ -869,7 +869,7 @@ msgid ""
 "Maybe you mistook %s and %s revs?\n"
 msgstr ""
 
-#: bisect.c:777
+#: bisect.c:778
 #, c-format
 msgid ""
 "the merge base between %s and [%s] must be skipped.\n"
@@ -877,43 +877,43 @@ msgid ""
 "We continue anyway."
 msgstr ""
 
-#: bisect.c:810
+#: bisect.c:811
 #, c-format
 msgid "Bisecting: a merge base must be tested\n"
 msgstr ""
 
-#: bisect.c:850
+#: bisect.c:851
 #, c-format
 msgid "a %s revision is needed"
 msgstr ""
 
-#: bisect.c:869 builtin/notes.c:175 builtin/tag.c:235
+#: bisect.c:870 builtin/notes.c:175 builtin/tag.c:236
 #, c-format
 msgid "could not create file '%s'"
 msgstr ""
 
-#: bisect.c:920
+#: bisect.c:921
 #, c-format
 msgid "could not read file '%s'"
 msgstr ""
 
-#: bisect.c:950
+#: bisect.c:951
 msgid "reading bisect refs failed"
 msgstr ""
 
-#: bisect.c:969
+#: bisect.c:970
 #, c-format
 msgid "%s was both %s and %s\n"
 msgstr ""
 
-#: bisect.c:977
+#: bisect.c:978
 #, c-format
 msgid ""
 "No testable commit found.\n"
 "Maybe you started with bad path parameters?\n"
 msgstr ""
 
-#: bisect.c:996
+#: bisect.c:997
 #, c-format
 msgid "(roughly %d step)"
 msgid_plural "(roughly %d steps)"
@@ -923,48 +923,48 @@ msgstr[1] ""
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
 #.
-#: bisect.c:1002
+#: bisect.c:1003
 #, 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] ""
 msgstr[1] ""
 
-#: blame.c:1758
+#: blame.c:1756
 msgid "--contents and --reverse do not blend well."
 msgstr ""
 
-#: blame.c:1769
+#: blame.c:1767
 msgid "cannot use --contents with final commit object name"
 msgstr ""
 
-#: blame.c:1789
+#: blame.c:1787
 msgid "--reverse and --first-parent together require specified latest commit"
 msgstr ""
 
-#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699
-#: sequencer.c:2901 builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920
-#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370
-#: builtin/shortlog.c:191
+#: blame.c:1796 bundle.c:160 ref-filter.c:2075 sequencer.c:1861
+#: sequencer.c:3632 builtin/commit.c:981 builtin/log.c:366 builtin/log.c:920
+#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:372
+#: builtin/shortlog.c:192
 msgid "revision walk setup failed"
 msgstr ""
 
-#: blame.c:1816
+#: blame.c:1814
 msgid ""
 "--reverse --first-parent together require range along first-parent chain"
 msgstr ""
 
-#: blame.c:1827
+#: blame.c:1825
 #, c-format
 msgid "no such path %s in %s"
 msgstr ""
 
-#: blame.c:1838
+#: blame.c:1836
 #, c-format
 msgid "cannot read blob %s for path %s"
 msgstr ""
 
-#: branch.c:53
+#: branch.c:54
 #, c-format
 msgid ""
 "\n"
@@ -973,85 +973,85 @@ msgid ""
 "\"git branch --set-upstream-to=%s%s%s\"."
 msgstr ""
 
-#: branch.c:67
+#: branch.c:68
 #, c-format
 msgid "Not setting branch %s as its own upstream."
 msgstr ""
 
-#: branch.c:93
+#: branch.c:94
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s' by rebasing."
 msgstr ""
 
-#: branch.c:94
+#: branch.c:95
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s'."
 msgstr ""
 
-#: branch.c:98
+#: branch.c:99
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s' by rebasing."
 msgstr ""
 
-#: branch.c:99
+#: branch.c:100
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s'."
 msgstr ""
 
-#: branch.c:104
+#: branch.c:105
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s' by rebasing."
 msgstr ""
 
-#: branch.c:105
+#: branch.c:106
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s'."
 msgstr ""
 
-#: branch.c:109
+#: branch.c:110
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s' by rebasing."
 msgstr ""
 
-#: branch.c:110
+#: branch.c:111
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s'."
 msgstr ""
 
-#: branch.c:119
+#: branch.c:120
 msgid "Unable to write upstream branch configuration"
 msgstr ""
 
-#: branch.c:156
+#: branch.c:157
 #, c-format
 msgid "Not tracking: ambiguous information for ref %s"
 msgstr ""
 
-#: branch.c:189
+#: branch.c:190
 #, c-format
 msgid "'%s' is not a valid branch name."
 msgstr ""
 
-#: branch.c:208
+#: branch.c:209
 #, c-format
 msgid "A branch named '%s' already exists."
 msgstr ""
 
-#: branch.c:213
+#: branch.c:214
 msgid "Cannot force update the current branch."
 msgstr ""
 
-#: branch.c:233
+#: branch.c:234
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr ""
 
-#: branch.c:235
+#: branch.c:236
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr ""
 
-#: branch.c:237
+#: branch.c:238
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -1063,27 +1063,27 @@ msgid ""
 "\"git push -u\" to set the upstream config as you push."
 msgstr ""
 
-#: branch.c:280
+#: branch.c:281
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr ""
 
-#: branch.c:300
+#: branch.c:301
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr ""
 
-#: branch.c:305
+#: branch.c:306
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr ""
 
-#: branch.c:359
+#: branch.c:360
 #, c-format
 msgid "'%s' is already checked out at '%s'"
 msgstr ""
 
-#: branch.c:382
+#: branch.c:383
 #, c-format
 msgid "HEAD of working tree %s is not updated"
 msgstr ""
@@ -1098,7 +1098,7 @@ msgstr ""
 msgid "unrecognized header: %s%s (%d)"
 msgstr ""
 
-#: bundle.c:88 sequencer.c:1879 sequencer.c:2337 builtin/commit.c:750
+#: bundle.c:88 sequencer.c:2081 sequencer.c:2558 builtin/commit.c:755
 #, c-format
 msgid "could not open '%s'"
 msgstr ""
@@ -1142,7 +1142,7 @@ msgstr ""
 msgid "ref '%s' is excluded by the rev-list options"
 msgstr ""
 
-#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:296
+#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:303
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr ""
@@ -1165,188 +1165,215 @@ msgstr ""
 msgid "invalid color value: %.*s"
 msgstr ""
 
-#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465
-#: builtin/am.c:1436 builtin/am.c:2072
+#: commit.c:43 sequencer.c:2364 builtin/am.c:421 builtin/am.c:465
+#: builtin/am.c:1436 builtin/am.c:2072 builtin/replace.c:376
+#: builtin/replace.c:448
 #, c-format
 msgid "could not parse %s"
 msgstr ""
 
-#: commit.c:43
+#: commit.c:45
 #, c-format
 msgid "%s %s is not a commit!"
 msgstr ""
 
-#: commit.c:1506
+#: commit.c:182
+msgid ""
+"Support for <GIT_DIR>/info/grafts is deprecated\n"
+"and will be removed in a future Git version.\n"
+"\n"
+"Please use \"git replace --convert-graft-file\"\n"
+"to convert the grafts into replace refs.\n"
+"\n"
+"Turn this message off by running\n"
+"\"git config advice.graftFileDeprecated false\""
+msgstr ""
+
+#: commit.c:1540
 msgid ""
 "Warning: commit message did not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
 "variable i18n.commitencoding to the encoding your project uses.\n"
 msgstr ""
 
+#: commit-graph.c:669
+#, c-format
+msgid "the commit graph format cannot write %d commits"
+msgstr ""
+
+#: commit-graph.c:696
+msgid "too many commits to write graph"
+msgstr ""
+
+#: commit-graph.c:707 builtin/init-db.c:516 builtin/init-db.c:521
+#, c-format
+msgid "cannot mkdir %s"
+msgstr ""
+
 #: compat/obstack.c:405 compat/obstack.c:407
 msgid "memory exhausted"
 msgstr ""
 
-#: config.c:186
+#: config.c:187
 msgid "relative config include conditionals must come from files"
 msgstr ""
 
-#: config.c:720
+#: config.c:788
 #, c-format
 msgid "bad config line %d in blob %s"
 msgstr ""
 
-#: config.c:724
+#: config.c:792
 #, c-format
 msgid "bad config line %d in file %s"
 msgstr ""
 
-#: config.c:728
+#: config.c:796
 #, c-format
 msgid "bad config line %d in standard input"
 msgstr ""
 
-#: config.c:732
+#: config.c:800
 #, c-format
 msgid "bad config line %d in submodule-blob %s"
 msgstr ""
 
-#: config.c:736
+#: config.c:804
 #, c-format
 msgid "bad config line %d in command line %s"
 msgstr ""
 
-#: config.c:740
+#: config.c:808
 #, c-format
 msgid "bad config line %d in %s"
 msgstr ""
 
-#: config.c:868
+#: config.c:936
 msgid "out of range"
 msgstr ""
 
-#: config.c:868
+#: config.c:936
 msgid "invalid unit"
 msgstr ""
 
-#: config.c:874
+#: config.c:942
 #, c-format
 msgid "bad numeric config value '%s' for '%s': %s"
 msgstr ""
 
-#: config.c:879
+#: config.c:947
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
 msgstr ""
 
-#: config.c:882
+#: config.c:950
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in file %s: %s"
 msgstr ""
 
-#: config.c:885
+#: config.c:953
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in standard input: %s"
 msgstr ""
 
-#: config.c:888
+#: config.c:956
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
 msgstr ""
 
-#: config.c:891
+#: config.c:959
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
 msgstr ""
 
-#: config.c:894
+#: config.c:962
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in %s: %s"
 msgstr ""
 
-#: config.c:989
+#: config.c:1057
 #, c-format
 msgid "failed to expand user dir in: '%s'"
 msgstr ""
 
-#: config.c:998
+#: config.c:1066
 #, c-format
 msgid "'%s' for '%s' is not a valid timestamp"
 msgstr ""
 
-#: config.c:1094 config.c:1105
+#: config.c:1171 config.c:1182
 #, c-format
 msgid "bad zlib compression level %d"
 msgstr ""
 
-#: config.c:1225
+#: config.c:1307
 #, c-format
 msgid "invalid mode for object creation: %s"
 msgstr ""
 
-#: config.c:1386
+#: config.c:1473
 #, c-format
 msgid "bad pack compression level %d"
 msgstr ""
 
-#: config.c:1582
+#: config.c:1681
 msgid "unable to parse command-line config"
 msgstr ""
 
-#: config.c:1914
+#: config.c:2013
 msgid "unknown error occurred while reading the configuration files"
 msgstr ""
 
-#: config.c:2101
+#: config.c:2200
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr ""
 
-#: config.c:2144
+#: config.c:2243
 #, c-format
 msgid "unknown core.untrackedCache value '%s'; using 'keep' default value"
 msgstr ""
 
-#: config.c:2170
+#: config.c:2269
 #, c-format
 msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100"
 msgstr ""
 
-#: config.c:2195
+#: config.c:2294
 #, c-format
 msgid "unable to parse '%s' from command-line config"
 msgstr ""
 
-#: config.c:2197
+#: config.c:2296
 #, c-format
 msgid "bad config variable '%s' in file '%s' at line %d"
 msgstr ""
 
-#: config.c:2256
+#: config.c:2402
 #, c-format
 msgid "%s has multiple values"
 msgstr ""
 
-#: config.c:2599 config.c:2816
+#: config.c:2766 config.c:3019
 #, c-format
 msgid "fstat on %s failed"
 msgstr ""
 
-#: config.c:2706
+#: config.c:2905
 #, c-format
 msgid "could not set '%s' to '%s'"
 msgstr ""
 
-#: config.c:2708 builtin/remote.c:776
+#: config.c:2907 builtin/remote.c:779
 #, c-format
 msgid "could not unset '%s'"
 msgstr ""
 
-#: connect.c:52
+#: connect.c:61
 msgid "The remote end hung up upon initial contact"
 msgstr ""
 
-#: connect.c:54
+#: connect.c:63
 msgid ""
 "Could not read from remote repository.\n"
 "\n"
@@ -1354,7 +1381,7 @@ msgid ""
 "and the repository exists."
 msgstr ""
 
-#: connected.c:66 builtin/fsck.c:198 builtin/prune.c:144
+#: connected.c:66 builtin/fsck.c:201 builtin/prune.c:145
 msgid "Checking connectivity"
 msgstr ""
 
@@ -1370,30 +1397,68 @@ msgstr ""
 msgid "failed to close rev-list's stdin"
 msgstr ""
 
-#: convert.c:205
+#: convert.c:206
 #, c-format
 msgid "CRLF would be replaced by LF in %s."
 msgstr ""
 
-#: convert.c:207
+#: convert.c:208
 #, 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 ""
 
-#: convert.c:215
+#: convert.c:216
 #, c-format
 msgid "LF would be replaced by CRLF in %s"
 msgstr ""
 
-#: convert.c:217
+#: convert.c:218
 #, 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 ""
 
+#: convert.c:279
+#, c-format
+msgid "BOM is prohibited in '%s' if encoded as %s"
+msgstr ""
+
+#: convert.c:286
+#, c-format
+msgid ""
+"The file '%s' contains a byte order mark (BOM). Please use UTF-%s as working-"
+"tree-encoding."
+msgstr ""
+
+#: convert.c:304
+#, c-format
+msgid "BOM is required in '%s' if encoded as %s"
+msgstr ""
+
+#: convert.c:306
+#, 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 ""
+
+#: convert.c:424
+#, c-format
+msgid "failed to encode '%s' from %s to %s"
+msgstr ""
+
+#: convert.c:467
+#, c-format
+msgid "encoding '%s' from %s to %s and back is not the same"
+msgstr ""
+
+#: convert.c:1225
+msgid "true/false are no valid working-tree-encodings"
+msgstr ""
+
 #: date.c:116
 msgid "in the future"
 msgstr ""
@@ -1504,68 +1569,68 @@ msgid ""
 "%s"
 msgstr ""
 
-#: diff.c:3822
+#: diff.c:3823
 #, c-format
 msgid "external diff died, stopping at %s"
 msgstr ""
 
-#: diff.c:4146
+#: diff.c:4153
 msgid "--name-only, --name-status, --check and -s are mutually exclusive"
 msgstr ""
 
-#: diff.c:4149
+#: diff.c:4156
 msgid "-G, -S and --find-object are mutually exclusive"
 msgstr ""
 
-#: diff.c:4237
+#: diff.c:4244
 msgid "--follow requires exactly one pathspec"
 msgstr ""
 
-#: diff.c:4403
+#: diff.c:4410
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
 "%s"
 msgstr ""
 
-#: diff.c:4417
+#: diff.c:4424
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr ""
 
-#: diff.c:5493
+#: diff.c:5500
 msgid "inexact rename detection was skipped due to too many files."
 msgstr ""
 
-#: diff.c:5496
+#: diff.c:5503
 msgid "only found copies from modified paths due to too many files."
 msgstr ""
 
-#: diff.c:5499
+#: diff.c:5506
 #, c-format
 msgid ""
 "you may want to set your %s variable to at least %d and retry the command."
 msgstr ""
 
-#: dir.c:1866
+#: dir.c:1867
 #, c-format
 msgid "could not open directory '%s'"
 msgstr ""
 
-#: dir.c:2108
+#: dir.c:2109
 msgid "failed to get kernel name and information"
 msgstr ""
 
-#: dir.c:2232
+#: dir.c:2233
 msgid "Untracked cache is disabled on this system or location."
 msgstr ""
 
-#: dir.c:3024 dir.c:3029
+#: dir.c:3075 dir.c:3080
 #, c-format
 msgid "could not create directories for %s"
 msgstr ""
 
-#: dir.c:3054
+#: dir.c:3109
 #, c-format
 msgid "could not migrate git directory from '%s' to '%s'"
 msgstr ""
@@ -1588,201 +1653,205 @@ msgstr ""
 msgid "Remote with no URL"
 msgstr ""
 
-#: fetch-pack.c:253
+#: fetch-pack.c:254
 msgid "git fetch-pack: expected shallow list"
 msgstr ""
 
-#: fetch-pack.c:265
+#: fetch-pack.c:266
 msgid "git fetch-pack: expected ACK/NAK, got a flush packet"
 msgstr ""
 
-#: fetch-pack.c:284 builtin/archive.c:63
+#: fetch-pack.c:285 builtin/archive.c:63
 #, c-format
 msgid "remote error: %s"
 msgstr ""
 
-#: fetch-pack.c:285
+#: fetch-pack.c:286
 #, c-format
 msgid "git fetch-pack: expected ACK/NAK, got '%s'"
 msgstr ""
 
-#: fetch-pack.c:337
+#: fetch-pack.c:338
 msgid "--stateless-rpc requires multi_ack_detailed"
 msgstr ""
 
-#: fetch-pack.c:428
+#: fetch-pack.c:429 fetch-pack.c:1310
 #, c-format
 msgid "invalid shallow line: %s"
 msgstr ""
 
-#: fetch-pack.c:434
+#: fetch-pack.c:435 fetch-pack.c:1316
 #, c-format
 msgid "invalid unshallow line: %s"
 msgstr ""
 
-#: fetch-pack.c:436
+#: fetch-pack.c:437 fetch-pack.c:1318
 #, c-format
 msgid "object not found: %s"
 msgstr ""
 
-#: fetch-pack.c:439
+#: fetch-pack.c:440 fetch-pack.c:1321
 #, c-format
 msgid "error in object: %s"
 msgstr ""
 
-#: fetch-pack.c:441
+#: fetch-pack.c:442 fetch-pack.c:1323
 #, c-format
 msgid "no shallow found: %s"
 msgstr ""
 
-#: fetch-pack.c:444
+#: fetch-pack.c:445 fetch-pack.c:1326
 #, c-format
 msgid "expected shallow/unshallow, got %s"
 msgstr ""
 
-#: fetch-pack.c:485
+#: fetch-pack.c:486
 #, c-format
 msgid "got %s %d %s"
 msgstr ""
 
-#: fetch-pack.c:499
+#: fetch-pack.c:500
 #, c-format
 msgid "invalid commit %s"
 msgstr ""
 
-#: fetch-pack.c:532
+#: fetch-pack.c:533
 msgid "giving up"
 msgstr ""
 
-#: fetch-pack.c:542 progress.c:229
+#: fetch-pack.c:543 progress.c:229
 msgid "done"
 msgstr ""
 
-#: fetch-pack.c:554
+#: fetch-pack.c:555
 #, c-format
 msgid "got %s (%d) %s"
 msgstr ""
 
-#: fetch-pack.c:600
+#: fetch-pack.c:601
 #, c-format
 msgid "Marking %s as complete"
 msgstr ""
 
-#: fetch-pack.c:788
+#: fetch-pack.c:828
 #, c-format
 msgid "already have %s (%s)"
 msgstr ""
 
-#: fetch-pack.c:829
+#: fetch-pack.c:869
 msgid "fetch-pack: unable to fork off sideband demultiplexer"
 msgstr ""
 
-#: fetch-pack.c:837
+#: fetch-pack.c:877
 msgid "protocol error: bad pack header"
 msgstr ""
 
-#: fetch-pack.c:895
+#: fetch-pack.c:944
 #, c-format
 msgid "fetch-pack: unable to fork off %s"
 msgstr ""
 
-#: fetch-pack.c:911
+#: fetch-pack.c:960
 #, c-format
 msgid "%s failed"
 msgstr ""
 
-#: fetch-pack.c:913
+#: fetch-pack.c:962
 msgid "error in sideband demultiplexer"
 msgstr ""
 
-#: fetch-pack.c:940
+#: fetch-pack.c:989
 msgid "Server does not support shallow clients"
 msgstr ""
 
-#: fetch-pack.c:944
+#: fetch-pack.c:993
 msgid "Server supports multi_ack_detailed"
 msgstr ""
 
-#: fetch-pack.c:947
+#: fetch-pack.c:996
 msgid "Server supports no-done"
 msgstr ""
 
-#: fetch-pack.c:953
+#: fetch-pack.c:1002
 msgid "Server supports multi_ack"
 msgstr ""
 
-#: fetch-pack.c:957
+#: fetch-pack.c:1006
 msgid "Server supports side-band-64k"
 msgstr ""
 
-#: fetch-pack.c:961
+#: fetch-pack.c:1010
 msgid "Server supports side-band"
 msgstr ""
 
-#: fetch-pack.c:965
+#: fetch-pack.c:1014
 msgid "Server supports allow-tip-sha1-in-want"
 msgstr ""
 
-#: fetch-pack.c:969
+#: fetch-pack.c:1018
 msgid "Server supports allow-reachable-sha1-in-want"
 msgstr ""
 
-#: fetch-pack.c:979
+#: fetch-pack.c:1028
 msgid "Server supports ofs-delta"
 msgstr ""
 
-#: fetch-pack.c:985
+#: fetch-pack.c:1034 fetch-pack.c:1204
 msgid "Server supports filter"
 msgstr ""
 
-#: fetch-pack.c:993
+#: fetch-pack.c:1042
 #, c-format
 msgid "Server version is %.*s"
 msgstr ""
 
-#: fetch-pack.c:999
+#: fetch-pack.c:1048
 msgid "Server does not support --shallow-since"
 msgstr ""
 
-#: fetch-pack.c:1003
+#: fetch-pack.c:1052
 msgid "Server does not support --shallow-exclude"
 msgstr ""
 
-#: fetch-pack.c:1005
+#: fetch-pack.c:1054
 msgid "Server does not support --deepen"
 msgstr ""
 
-#: fetch-pack.c:1016
+#: fetch-pack.c:1065
 msgid "no common commits"
 msgstr ""
 
-#: fetch-pack.c:1028
+#: fetch-pack.c:1077 fetch-pack.c:1414
 msgid "git fetch-pack: fetch failed."
 msgstr ""
 
-#: fetch-pack.c:1190
+#: fetch-pack.c:1199
+msgid "Server does not support shallow requests"
+msgstr ""
+
+#: fetch-pack.c:1584
 msgid "no matching remote head"
 msgstr ""
 
-#: fetch-pack.c:1212
+#: fetch-pack.c:1610
 #, c-format
 msgid "no such remote ref %s"
 msgstr ""
 
-#: fetch-pack.c:1215
+#: fetch-pack.c:1613
 #, c-format
 msgid "Server does not allow request for unadvertised object %s"
 msgstr ""
 
-#: gpg-interface.c:181
+#: gpg-interface.c:185
 msgid "gpg failed to sign the data"
 msgstr ""
 
-#: gpg-interface.c:211
+#: gpg-interface.c:210
 msgid "could not create temporary file"
 msgstr ""
 
-#: gpg-interface.c:214
+#: gpg-interface.c:213
 #, c-format
 msgid "failed writing detached signature to '%s'"
 msgstr ""
@@ -1792,67 +1861,128 @@ msgstr ""
 msgid "ignore invalid color '%.*s' in log.graphColors"
 msgstr ""
 
-#: grep.c:2022
+#: grep.c:2020
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr ""
 
-#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81
+#: grep.c:2037 setup.c:164 builtin/clone.c:409 builtin/diff.c:81
 #: builtin/rm.c:134
 #, c-format
 msgid "failed to stat '%s'"
 msgstr ""
 
-#: grep.c:2050
+#: grep.c:2048
 #, c-format
 msgid "'%s': short read"
 msgstr ""
 
-#: help.c:179
+#: help.c:23
+msgid "start a working area (see also: git help tutorial)"
+msgstr ""
+
+#: help.c:24
+msgid "work on the current change (see also: git help everyday)"
+msgstr ""
+
+#: help.c:25
+msgid "examine the history and state (see also: git help revisions)"
+msgstr ""
+
+#: help.c:26
+msgid "grow, mark and tweak your common history"
+msgstr ""
+
+#: help.c:27
+msgid "collaborate (see also: git help workflows)"
+msgstr ""
+
+#: help.c:31
+msgid "Main Porcelain Commands"
+msgstr ""
+
+#: help.c:32
+msgid "Ancillary Commands / Manipulators"
+msgstr ""
+
+#: help.c:33
+msgid "Ancillary Commands / Interrogators"
+msgstr ""
+
+#: help.c:34
+msgid "Interacting with Others"
+msgstr ""
+
+#: help.c:35
+msgid "Low-level Commands / Manipulators"
+msgstr ""
+
+#: help.c:36
+msgid "Low-level Commands / Interrogators"
+msgstr ""
+
+#: help.c:37
+msgid "Low-level Commands / Synching Repositories"
+msgstr ""
+
+#: help.c:38
+msgid "Low-level Commands / Internal Helpers"
+msgstr ""
+
+#: help.c:293
 #, c-format
 msgid "available git commands in '%s'"
 msgstr ""
 
-#: help.c:186
+#: help.c:300
 msgid "git commands available from elsewhere on your $PATH"
 msgstr ""
 
-#: help.c:217
+#: help.c:309
 msgid "These are common Git commands used in various situations:"
 msgstr ""
 
-#: help.c:281
+#: help.c:358 git.c:90
+#, c-format
+msgid "unsupported command listing type '%s'"
+msgstr ""
+
+#: help.c:405
+msgid "The common Git guides are:"
+msgstr ""
+
+#: help.c:467
 #, 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 ""
 
-#: help.c:336
+#: help.c:526
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr ""
 
-#: help.c:358
+#: help.c:548
 #, c-format
 msgid "WARNING: You called a Git command named '%s', which does not exist."
 msgstr ""
 
-#: help.c:363
+#: help.c:553
 #, c-format
 msgid "Continuing under the assumption that you meant '%s'."
 msgstr ""
 
-#: help.c:368
+#: help.c:558
 #, c-format
 msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
 msgstr ""
 
-#: help.c:376
+#: help.c:566
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr ""
 
-#: help.c:380
+#: help.c:570
 msgid ""
 "\n"
 "The most similar command is"
@@ -1862,16 +1992,16 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: help.c:395
+#: help.c:585
 msgid "git version [<options>]"
 msgstr ""
 
-#: help.c:462
+#: help.c:652
 #, c-format
 msgid "%s: %s - %s"
 msgstr ""
 
-#: help.c:466
+#: help.c:656
 msgid ""
 "\n"
 "Did you mean this?"
@@ -1924,7 +2054,7 @@ msgstr ""
 msgid "name consists only of disallowed characters: %s"
 msgstr ""
 
-#: ident.c:416 builtin/commit.c:582
+#: ident.c:416 builtin/commit.c:587
 #, c-format
 msgid "invalid date format: %s"
 msgstr ""
@@ -1954,261 +2084,378 @@ msgstr ""
 msgid "Unable to create '%s.lock': %s"
 msgstr ""
 
-#: merge.c:74
+#: merge.c:71
 msgid "failed to read the cache"
 msgstr ""
 
-#: merge.c:134 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
-#: builtin/checkout.c:599 builtin/clone.c:759
+#: merge.c:136 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
+#: builtin/checkout.c:606 builtin/clone.c:761
 msgid "unable to write new index file"
 msgstr ""
 
-#: merge-recursive.c:235
+#: merge-recursive.c:298
 msgid "(bad commit)\n"
 msgstr ""
 
-#: merge-recursive.c:257 merge-recursive.c:265
+#: merge-recursive.c:320
+#, c-format
+msgid "add_cacheinfo failed for path '%s'; merge aborting."
+msgstr ""
+
+#: merge-recursive.c:328
 #, c-format
-msgid "addinfo_cache failed for path '%s'"
+msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
 msgstr ""
 
-#: merge-recursive.c:329
+#: merge-recursive.c:410
 msgid "error building trees"
 msgstr ""
 
-#: merge-recursive.c:771
+#: merge-recursive.c:881
 #, c-format
 msgid "failed to create path '%s'%s"
 msgstr ""
 
-#: merge-recursive.c:782
+#: merge-recursive.c:892
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr ""
 
-#: merge-recursive.c:796 merge-recursive.c:815
+#: merge-recursive.c:906 merge-recursive.c:925
 msgid ": perhaps a D/F conflict?"
 msgstr ""
 
-#: merge-recursive.c:805
+#: merge-recursive.c:915
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
 msgstr ""
 
-#: merge-recursive.c:847 builtin/cat-file.c:37
+#: merge-recursive.c:957 builtin/cat-file.c:37
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr ""
 
-#: merge-recursive.c:849
+#: merge-recursive.c:959
 #, c-format
 msgid "blob expected for %s '%s'"
 msgstr ""
 
-#: merge-recursive.c:873
+#: merge-recursive.c:983
 #, c-format
 msgid "failed to open '%s': %s"
 msgstr ""
 
-#: merge-recursive.c:884
+#: merge-recursive.c:994
 #, c-format
 msgid "failed to symlink '%s': %s"
 msgstr ""
 
-#: merge-recursive.c:889
+#: merge-recursive.c:999
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
 msgstr ""
 
-#: merge-recursive.c:1029
+#: merge-recursive.c:1186
+#, c-format
+msgid "Failed to merge submodule %s (not checked out)"
+msgstr ""
+
+#: merge-recursive.c:1193
+#, c-format
+msgid "Failed to merge submodule %s (commits not present)"
+msgstr ""
+
+#: merge-recursive.c:1200
+#, c-format
+msgid "Failed to merge submodule %s (commits don't follow merge-base)"
+msgstr ""
+
+#: merge-recursive.c:1208 merge-recursive.c:1220
+#, c-format
+msgid "Fast-forwarding submodule %s to the following commit:"
+msgstr ""
+
+#: merge-recursive.c:1211 merge-recursive.c:1223
+#, c-format
+msgid "Fast-forwarding submodule %s"
+msgstr ""
+
+#: merge-recursive.c:1245
+#, c-format
+msgid "Failed to merge submodule %s (merge following commits not found)"
+msgstr ""
+
+#: merge-recursive.c:1249
+#, c-format
+msgid "Failed to merge submodule %s (not fast-forward)"
+msgstr ""
+
+#: merge-recursive.c:1250
+msgid "Found a possible merge resolution for the submodule:\n"
+msgstr ""
+
+#: merge-recursive.c:1253
+#, 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 ""
+
+#: merge-recursive.c:1262
+#, c-format
+msgid "Failed to merge submodule %s (multiple merges found)"
+msgstr ""
+
+#: merge-recursive.c:1321
 msgid "Failed to execute internal merge"
 msgstr ""
 
-#: merge-recursive.c:1034
+#: merge-recursive.c:1326
 #, c-format
 msgid "Unable to add %s to database"
 msgstr ""
 
-#: merge-recursive.c:1146
+#: merge-recursive.c:1358
+#, c-format
+msgid "Auto-merging %s"
+msgstr ""
+
+#: merge-recursive.c:1423
+#, c-format
+msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
+msgstr ""
+
+#: merge-recursive.c:1475
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
 "in tree."
 msgstr ""
 
-#: merge-recursive.c:1151
+#: merge-recursive.c:1480
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
 "left in tree."
 msgstr ""
 
-#: merge-recursive.c:1158
+#: merge-recursive.c:1487
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
 "in tree at %s."
 msgstr ""
 
-#: merge-recursive.c:1163
+#: merge-recursive.c:1492
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
 "left in tree at %s."
 msgstr ""
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "rename"
 msgstr ""
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "renamed"
 msgstr ""
 
-#: merge-recursive.c:1254
+#: merge-recursive.c:1580 merge-recursive.c:1736 merge-recursive.c:2368
+#: merge-recursive.c:3086
+#, c-format
+msgid "Refusing to lose dirty file at %s"
+msgstr ""
+
+#: merge-recursive.c:1594
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr ""
 
-#: merge-recursive.c:1279
+#: merge-recursive.c:1599
+#, c-format
+msgid "Refusing to lose untracked file at %s; adding as %s instead"
+msgstr ""
+
+#: merge-recursive.c:1625
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
 "\"->\"%s\" in \"%s\"%s"
 msgstr ""
 
-#: merge-recursive.c:1284
+#: merge-recursive.c:1630
 msgid " (left unresolved)"
 msgstr ""
 
-#: merge-recursive.c:1346
+#: merge-recursive.c:1694
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
 
-#: merge-recursive.c:1379
+#: merge-recursive.c:1733
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr ""
 
-#: merge-recursive.c:1582
+#: merge-recursive.c:1745
+#, c-format
+msgid "Refusing to lose untracked file at %s, even though it's in the way."
+msgstr ""
+
+#: merge-recursive.c:1951
+#, c-format
+msgid ""
+"CONFLICT (directory rename split): Unclear where to place %s because "
+"directory %s was renamed to multiple other directories, with no destination "
+"getting a majority of the files."
+msgstr ""
+
+#: merge-recursive.c:1983
+#, c-format
+msgid ""
+"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 ""
+
+#: merge-recursive.c:1993
+#, 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 ""
+
+#: merge-recursive.c:2085
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-"
+">%s in %s"
+msgstr ""
+
+#: merge-recursive.c:2330
+#, c-format
+msgid ""
+"WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
+"renamed."
+msgstr ""
+
+#: merge-recursive.c:2736
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
 msgstr ""
 
-#: merge-recursive.c:1597
+#: merge-recursive.c:2751
 #, c-format
 msgid "Adding merged %s"
 msgstr ""
 
-#: merge-recursive.c:1604 merge-recursive.c:1834
+#: merge-recursive.c:2758 merge-recursive.c:3089
 #, c-format
 msgid "Adding as %s instead"
 msgstr ""
 
-#: merge-recursive.c:1661
+#: merge-recursive.c:2914
 #, c-format
 msgid "cannot read object %s"
 msgstr ""
 
-#: merge-recursive.c:1664
+#: merge-recursive.c:2917
 #, c-format
 msgid "object %s is not a blob"
 msgstr ""
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modify"
 msgstr ""
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modified"
 msgstr ""
 
-#: merge-recursive.c:1743
+#: merge-recursive.c:2997
 msgid "content"
 msgstr ""
 
-#: merge-recursive.c:1750
+#: merge-recursive.c:3004
 msgid "add/add"
 msgstr ""
 
-#: merge-recursive.c:1786
+#: merge-recursive.c:3046
 #, c-format
 msgid "Skipped %s (merged same as existing)"
 msgstr ""
 
-#: merge-recursive.c:1800
-#, c-format
-msgid "Auto-merging %s"
-msgstr ""
-
-#: merge-recursive.c:1804 git-submodule.sh:879
+#: merge-recursive.c:3055 git-submodule.sh:895
 msgid "submodule"
 msgstr ""
 
-#: merge-recursive.c:1805
+#: merge-recursive.c:3056
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
 msgstr ""
 
-#: merge-recursive.c:1899
+#: merge-recursive.c:3178
 #, c-format
 msgid "Removing %s"
 msgstr ""
 
-#: merge-recursive.c:1925
+#: merge-recursive.c:3204
 msgid "file/directory"
 msgstr ""
 
-#: merge-recursive.c:1931
+#: merge-recursive.c:3210
 msgid "directory/file"
 msgstr ""
 
-#: merge-recursive.c:1938
+#: merge-recursive.c:3217
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
 msgstr ""
 
-#: merge-recursive.c:1947
+#: merge-recursive.c:3226
 #, c-format
 msgid "Adding %s"
 msgstr ""
 
-#: merge-recursive.c:1987
+#: merge-recursive.c:3267
 #, c-format
 msgid "Dirty index: cannot merge (dirty: %s)"
 msgstr ""
 
-#: merge-recursive.c:1991
+#: merge-recursive.c:3271
 msgid "Already up to date!"
 msgstr ""
 
-#: merge-recursive.c:2000
+#: merge-recursive.c:3280
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr ""
 
-#: merge-recursive.c:2097
+#: merge-recursive.c:3379
 msgid "Merging:"
 msgstr ""
 
-#: merge-recursive.c:2110
+#: merge-recursive.c:3392
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: merge-recursive.c:2149
+#: merge-recursive.c:3431
 msgid "merge returned no commit"
 msgstr ""
 
-#: merge-recursive.c:2212
+#: merge-recursive.c:3495
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr ""
 
-#: merge-recursive.c:2228 builtin/merge.c:657 builtin/merge.c:816
+#: merge-recursive.c:3511 builtin/merge.c:659 builtin/merge.c:816
 msgid "Unable to write index."
 msgstr ""
 
@@ -2248,30 +2495,30 @@ msgstr ""
 msgid "Bad %s value: '%s'"
 msgstr ""
 
-#: object.c:239
+#: object.c:242
 #, c-format
 msgid "unable to parse object: %s"
 msgstr ""
 
-#: packfile.c:561
+#: packfile.c:563
 msgid "offset before end of packfile (broken .idx?)"
 msgstr ""
 
-#: packfile.c:1694
+#: packfile.c:1742
 #, c-format
 msgid "offset before start of pack index for %s (corrupt index?)"
 msgstr ""
 
-#: packfile.c:1698
+#: packfile.c:1746
 #, c-format
 msgid "offset beyond end of pack index for %s (truncated index?)"
 msgstr ""
 
-#: parse-options.c:619
+#: parse-options.c:621
 msgid "..."
 msgstr ""
 
-#: parse-options.c:638
+#: parse-options.c:640
 #, c-format
 msgid "usage: %s"
 msgstr ""
@@ -2279,26 +2526,31 @@ msgstr ""
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation.
 #.
-#: parse-options.c:644
+#: parse-options.c:646
 #, c-format
 msgid "   or: %s"
 msgstr ""
 
-#: parse-options.c:647
+#: parse-options.c:649
 #, c-format
 msgid "    %s"
 msgstr ""
 
-#: parse-options.c:686
+#: parse-options.c:688
 msgid "-NUM"
 msgstr ""
 
-#: parse-options-cb.c:108
+#: parse-options-cb.c:44
+#, c-format
+msgid "malformed expiration date '%s'"
+msgstr ""
+
+#: parse-options-cb.c:112
 #, c-format
 msgid "malformed object name '%s'"
 msgstr ""
 
-#: path.c:891
+#: path.c:892
 #, c-format
 msgid "Could not make %s writable by group"
 msgstr ""
@@ -2378,66 +2630,67 @@ msgstr ""
 msgid "unable to parse --pretty format"
 msgstr ""
 
-#: read-cache.c:1473
+#: read-cache.c:1500
 #, c-format
 msgid ""
 "index.version set, but the value is invalid.\n"
 "Using version %i"
 msgstr ""
 
-#: read-cache.c:1483
+#: read-cache.c:1510
 #, c-format
 msgid ""
 "GIT_INDEX_VERSION set, but the value is invalid.\n"
 "Using version %i"
 msgstr ""
 
-#: read-cache.c:2375 sequencer.c:3248 wrapper.c:658 builtin/merge.c:1049
+#: read-cache.c:2404 sequencer.c:4338 wrapper.c:658 builtin/merge.c:1048
 #, c-format
 msgid "could not close '%s'"
 msgstr ""
 
-#: read-cache.c:2448 sequencer.c:1900 sequencer.c:2627
+#: read-cache.c:2477 sequencer.c:2102 sequencer.c:3234
 #, c-format
 msgid "could not stat '%s'"
 msgstr ""
 
-#: read-cache.c:2461
+#: read-cache.c:2490
 #, c-format
 msgid "unable to open git dir: %s"
 msgstr ""
 
-#: read-cache.c:2473
+#: read-cache.c:2502
 #, c-format
 msgid "unable to unlink: %s"
 msgstr ""
 
-#: refs.c:706
+#: refs.c:732 sequencer.c:4334 sequencer.c:4393 wrapper.c:225 wrapper.c:395
+#: builtin/am.c:779
 #, c-format
-msgid "Could not open '%s' for writing"
+msgid "could not open '%s' for writing"
 msgstr ""
 
-#: refs.c:1850
+#: refs.c:1880
 msgid "ref updates forbidden inside quarantine environment"
 msgstr ""
 
-#: refs/files-backend.c:1189
+#: refs/files-backend.c:1191
 #, c-format
 msgid "could not remove reference %s"
 msgstr ""
 
-#: refs/files-backend.c:1203 refs/packed-backend.c:1528
-#: refs/packed-backend.c:1538
+#: refs/files-backend.c:1205 refs/packed-backend.c:1531
+#: refs/packed-backend.c:1541
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr ""
 
-#: refs/files-backend.c:1206 refs/packed-backend.c:1541
+#: refs/files-backend.c:1208 refs/packed-backend.c:1544
 #, c-format
 msgid "could not delete references: %s"
 msgstr ""
 
-#: ref-filter.c:35 wt-status.c:1842
+#: ref-filter.c:35 wt-status.c:1850
 msgid "gone"
 msgstr ""
 
@@ -2456,157 +2709,162 @@ msgstr ""
 msgid "ahead %d, behind %d"
 msgstr ""
 
-#: ref-filter.c:107
+#: ref-filter.c:121
 #, c-format
 msgid "expected format: %%(color:<color>)"
 msgstr ""
 
-#: ref-filter.c:109
+#: ref-filter.c:123
 #, c-format
 msgid "unrecognized color: %%(color:%s)"
 msgstr ""
 
-#: ref-filter.c:129
+#: ref-filter.c:145
 #, c-format
 msgid "Integer value expected refname:lstrip=%s"
 msgstr ""
 
-#: ref-filter.c:133
+#: ref-filter.c:149
 #, c-format
 msgid "Integer value expected refname:rstrip=%s"
 msgstr ""
 
-#: ref-filter.c:135
+#: ref-filter.c:151
 #, c-format
 msgid "unrecognized %%(%s) argument: %s"
 msgstr ""
 
-#: ref-filter.c:184
+#: ref-filter.c:206
 #, c-format
 msgid "%%(body) does not take arguments"
 msgstr ""
 
-#: ref-filter.c:191
+#: ref-filter.c:215
 #, c-format
 msgid "%%(subject) does not take arguments"
 msgstr ""
 
-#: ref-filter.c:209
+#: ref-filter.c:235
 #, c-format
 msgid "unknown %%(trailers) argument: %s"
 msgstr ""
 
-#: ref-filter.c:232
+#: ref-filter.c:264
 #, c-format
 msgid "positive value expected contents:lines=%s"
 msgstr ""
 
-#: ref-filter.c:234
+#: ref-filter.c:266
 #, c-format
 msgid "unrecognized %%(contents) argument: %s"
 msgstr ""
 
-#: ref-filter.c:247
+#: ref-filter.c:281
 #, c-format
 msgid "positive value expected objectname:short=%s"
 msgstr ""
 
-#: ref-filter.c:251
+#: ref-filter.c:285
 #, c-format
 msgid "unrecognized %%(objectname) argument: %s"
 msgstr ""
 
-#: ref-filter.c:278
+#: ref-filter.c:315
 #, c-format
 msgid "expected format: %%(align:<width>,<position>)"
 msgstr ""
 
-#: ref-filter.c:290
+#: ref-filter.c:327
 #, c-format
 msgid "unrecognized position:%s"
 msgstr ""
 
-#: ref-filter.c:294
+#: ref-filter.c:334
 #, c-format
 msgid "unrecognized width:%s"
 msgstr ""
 
-#: ref-filter.c:300
+#: ref-filter.c:343
 #, c-format
 msgid "unrecognized %%(align) argument: %s"
 msgstr ""
 
-#: ref-filter.c:304
+#: ref-filter.c:351
 #, c-format
 msgid "positive width expected with the %%(align) atom"
 msgstr ""
 
-#: ref-filter.c:319
+#: ref-filter.c:369
 #, c-format
 msgid "unrecognized %%(if) argument: %s"
 msgstr ""
 
-#: ref-filter.c:409
+#: ref-filter.c:464
 #, c-format
 msgid "malformed field name: %.*s"
 msgstr ""
 
-#: ref-filter.c:435
+#: ref-filter.c:491
 #, c-format
 msgid "unknown field name: %.*s"
 msgstr ""
 
-#: ref-filter.c:547
+#: ref-filter.c:608
 #, c-format
 msgid "format: %%(if) atom used without a %%(then) atom"
 msgstr ""
 
-#: ref-filter.c:607
+#: ref-filter.c:671
 #, c-format
 msgid "format: %%(then) atom used without an %%(if) atom"
 msgstr ""
 
-#: ref-filter.c:609
+#: ref-filter.c:673
 #, c-format
 msgid "format: %%(then) atom used more than once"
 msgstr ""
 
-#: ref-filter.c:611
+#: ref-filter.c:675
 #, c-format
 msgid "format: %%(then) atom used after %%(else)"
 msgstr ""
 
-#: ref-filter.c:637
+#: ref-filter.c:703
 #, c-format
 msgid "format: %%(else) atom used without an %%(if) atom"
 msgstr ""
 
-#: ref-filter.c:639
+#: ref-filter.c:705
 #, c-format
 msgid "format: %%(else) atom used without a %%(then) atom"
 msgstr ""
 
-#: ref-filter.c:641
+#: ref-filter.c:707
 #, c-format
 msgid "format: %%(else) atom used more than once"
 msgstr ""
 
-#: ref-filter.c:654
+#: ref-filter.c:722
 #, c-format
 msgid "format: %%(end) atom used without corresponding atom"
 msgstr ""
 
-#: ref-filter.c:709
+#: ref-filter.c:779
 #, c-format
 msgid "malformed format string %s"
 msgstr ""
 
-#: ref-filter.c:1313
+#: ref-filter.c:1387
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr ""
 
-#: ref-filter.c:1316
+#: ref-filter.c:1390
+#, c-format
+msgid "(no branch, rebasing detached HEAD %s)"
+msgstr ""
+
+#: ref-filter.c:1393
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr ""
@@ -2614,7 +2872,7 @@ msgstr ""
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached at " in wt-status.c
 #.
-#: ref-filter.c:1324
+#: ref-filter.c:1401
 #, c-format
 msgid "(HEAD detached at %s)"
 msgstr ""
@@ -2622,147 +2880,147 @@ msgstr ""
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached from " in wt-status.c
 #.
-#: ref-filter.c:1331
+#: ref-filter.c:1408
 #, c-format
 msgid "(HEAD detached from %s)"
 msgstr ""
 
-#: ref-filter.c:1335
+#: ref-filter.c:1412
 msgid "(no branch)"
 msgstr ""
 
-#: ref-filter.c:1364
+#: ref-filter.c:1442
 #, c-format
 msgid "missing object %s for %s"
 msgstr ""
 
-#: ref-filter.c:1367
+#: ref-filter.c:1445
 #, c-format
 msgid "parse_object_buffer failed on %s for %s"
 msgstr ""
 
-#: ref-filter.c:1819
+#: ref-filter.c:1902
 #, c-format
 msgid "malformed object at '%s'"
 msgstr ""
 
-#: ref-filter.c:1886
+#: ref-filter.c:1984
 #, c-format
 msgid "ignoring ref with broken name %s"
 msgstr ""
 
-#: ref-filter.c:1891
+#: ref-filter.c:1989
 #, c-format
 msgid "ignoring broken ref %s"
 msgstr ""
 
-#: ref-filter.c:2152
+#: ref-filter.c:2261
 #, c-format
 msgid "format: %%(end) atom missing"
 msgstr ""
 
-#: ref-filter.c:2246
+#: ref-filter.c:2365
 #, c-format
 msgid "malformed object name %s"
 msgstr ""
 
-#: remote.c:795
+#: remote.c:605
 #, c-format
 msgid "Cannot fetch both %s and %s to %s"
 msgstr ""
 
-#: remote.c:799
+#: remote.c:609
 #, c-format
 msgid "%s usually tracks %s, not %s"
 msgstr ""
 
-#: remote.c:803
+#: remote.c:613
 #, c-format
 msgid "%s tracks both %s and %s"
 msgstr ""
 
-#: remote.c:811
+#: remote.c:621
 msgid "Internal error"
 msgstr ""
 
-#: remote.c:1726 remote.c:1828
+#: remote.c:1534 remote.c:1635
 msgid "HEAD does not point to a branch"
 msgstr ""
 
-#: remote.c:1735
+#: remote.c:1543
 #, c-format
 msgid "no such branch: '%s'"
 msgstr ""
 
-#: remote.c:1738
+#: remote.c:1546
 #, c-format
 msgid "no upstream configured for branch '%s'"
 msgstr ""
 
-#: remote.c:1744
+#: remote.c:1552
 #, c-format
 msgid "upstream branch '%s' not stored as a remote-tracking branch"
 msgstr ""
 
-#: remote.c:1759
+#: remote.c:1567
 #, c-format
 msgid "push destination '%s' on remote '%s' has no local tracking branch"
 msgstr ""
 
-#: remote.c:1771
+#: remote.c:1579
 #, c-format
 msgid "branch '%s' has no remote for pushing"
 msgstr ""
 
-#: remote.c:1782
+#: remote.c:1589
 #, c-format
 msgid "push refspecs for '%s' do not include '%s'"
 msgstr ""
 
-#: remote.c:1795
+#: remote.c:1602
 msgid "push has no destination (push.default is 'nothing')"
 msgstr ""
 
-#: remote.c:1817
+#: remote.c:1624
 msgid "cannot resolve 'simple' push to a single destination"
 msgstr ""
 
-#: remote.c:2132
+#: remote.c:1939
 #, c-format
 msgid "Your branch is based on '%s', but the upstream is gone.\n"
 msgstr ""
 
-#: remote.c:2136
+#: remote.c:1943
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
 msgstr ""
 
-#: remote.c:2139
+#: remote.c:1946
 #, c-format
 msgid "Your branch is up to date with '%s'.\n"
 msgstr ""
 
-#: remote.c:2143
+#: remote.c:1950
 #, c-format
 msgid "Your branch and '%s' refer to different commits.\n"
 msgstr ""
 
-#: remote.c:2146
+#: remote.c:1953
 #, c-format
 msgid "  (use \"%s\" for details)\n"
 msgstr ""
 
-#: remote.c:2150
+#: remote.c:1957
 #, 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] ""
 msgstr[1] ""
 
-#: remote.c:2156
+#: remote.c:1963
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr ""
 
-#: remote.c:2159
+#: remote.c:1966
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -2770,11 +3028,11 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: remote.c:2167
+#: remote.c:1974
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr ""
 
-#: remote.c:2170
+#: remote.c:1977
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -2785,28 +3043,28 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: remote.c:2180
+#: remote.c:1987
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr ""
 
-#: revision.c:2277
+#: revision.c:2289
 msgid "your current branch appears to be broken"
 msgstr ""
 
-#: revision.c:2280
+#: revision.c:2292
 #, c-format
 msgid "your current branch '%s' does not have any commits yet"
 msgstr ""
 
-#: revision.c:2477
+#: revision.c:2489
 msgid "--first-parent is incompatible with --bisect"
 msgstr ""
 
-#: run-command.c:731
+#: run-command.c:728
 msgid "open /dev/null failed"
 msgstr ""
 
-#: run-command.c:1274
+#: run-command.c:1271
 #, c-format
 msgid ""
 "The '%s' hook was ignored because it's not set as executable.\n"
@@ -2849,78 +3107,85 @@ msgstr ""
 msgid "the receiving end does not support push options"
 msgstr ""
 
-#: sequencer.c:158
+#: sequencer.c:175
 #, c-format
 msgid "invalid commit message cleanup mode '%s'"
 msgstr ""
 
-#: sequencer.c:267
+#: sequencer.c:275
+#, c-format
+msgid "could not delete '%s'"
+msgstr ""
+
+#: sequencer.c:301
 msgid "revert"
 msgstr ""
 
-#: sequencer.c:269
+#: sequencer.c:303
 msgid "cherry-pick"
 msgstr ""
 
-#: sequencer.c:271
+#: sequencer.c:305
 msgid "rebase -i"
 msgstr ""
 
-#: sequencer.c:273
+#: sequencer.c:307
 #, c-format
 msgid "Unknown action: %d"
 msgstr ""
 
-#: sequencer.c:330
+#: sequencer.c:364
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
 msgstr ""
 
-#: sequencer.c:333
+#: sequencer.c:367
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'\n"
 "and commit the result with 'git commit'"
 msgstr ""
 
-#: sequencer.c:346 sequencer.c:2245
+#: sequencer.c:380 sequencer.c:2468
 #, c-format
 msgid "could not lock '%s'"
 msgstr ""
 
-#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264
-#: sequencer.c:3246 sequencer.c:3310 wrapper.c:656
+#: sequencer.c:382 sequencer.c:2346 sequencer.c:2472 sequencer.c:2486
+#: sequencer.c:2694 sequencer.c:4336 sequencer.c:4399 wrapper.c:656
 #, c-format
 msgid "could not write to '%s'"
 msgstr ""
 
-#: sequencer.c:353
+#: sequencer.c:387
 #, c-format
 msgid "could not write eol to '%s'"
 msgstr ""
 
-#: sequencer.c:356 sequencer.c:2128 sequencer.c:2252
+#: sequencer.c:392 sequencer.c:2351 sequencer.c:2474 sequencer.c:2488
+#: sequencer.c:2702
 #, c-format
 msgid "failed to finalize '%s'"
 msgstr ""
 
-#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259
-#: builtin/commit.c:722 builtin/merge.c:1047
+#: sequencer.c:415 sequencer.c:804 sequencer.c:1493 sequencer.c:2371
+#: sequencer.c:2684 sequencer.c:2788 builtin/am.c:259 builtin/commit.c:727
+#: builtin/merge.c:1046
 #, c-format
 msgid "could not read '%s'"
 msgstr ""
 
-#: sequencer.c:405
+#: sequencer.c:441
 #, c-format
 msgid "your local changes would be overwritten by %s."
 msgstr ""
 
-#: sequencer.c:409
+#: sequencer.c:445
 msgid "commit your changes or stash them to proceed."
 msgstr ""
 
-#: sequencer.c:438
+#: sequencer.c:474
 #, c-format
 msgid "%s: fast-forward"
 msgstr ""
@@ -2928,20 +3193,20 @@ msgstr ""
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase -i".
 #.
-#: sequencer.c:526
+#: sequencer.c:563
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr ""
 
-#: sequencer.c:542
-msgid "could not resolve HEAD commit"
+#: sequencer.c:579
+msgid "unable to update cache tree"
 msgstr ""
 
-#: sequencer.c:562
-msgid "unable to update cache tree"
+#: sequencer.c:592
+msgid "could not resolve HEAD commit"
 msgstr ""
 
-#: sequencer.c:658
+#: sequencer.c:749
 #, c-format
 msgid ""
 "you have staged changes in your working tree\n"
@@ -2958,11 +3223,15 @@ msgid ""
 "  git rebase --continue\n"
 msgstr ""
 
-#: sequencer.c:915
+#: sequencer.c:818
+msgid "writing root commit"
+msgstr ""
+
+#: sequencer.c:1043
 msgid "'prepare-commit-msg' hook failed"
 msgstr ""
 
-#: sequencer.c:922
+#: sequencer.c:1050
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -2977,7 +3246,7 @@ msgid ""
 "    git commit --amend --reset-author\n"
 msgstr ""
 
-#: sequencer.c:935
+#: sequencer.c:1063
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -2991,321 +3260,313 @@ msgid ""
 "    git commit --amend --reset-author\n"
 msgstr ""
 
-#: sequencer.c:975
+#: sequencer.c:1103
 msgid "couldn't look up newly created commit"
 msgstr ""
 
-#: sequencer.c:977
+#: sequencer.c:1105
 msgid "could not parse newly created commit"
 msgstr ""
 
-#: sequencer.c:1023
+#: sequencer.c:1151
 msgid "unable to resolve HEAD after creating commit"
 msgstr ""
 
-#: sequencer.c:1025
+#: sequencer.c:1153
 msgid "detached HEAD"
 msgstr ""
 
-#: sequencer.c:1029
+#: sequencer.c:1157
 msgid " (root-commit)"
 msgstr ""
 
-#: sequencer.c:1050
+#: sequencer.c:1178
 msgid "could not parse HEAD"
 msgstr ""
 
-#: sequencer.c:1052
+#: sequencer.c:1180
 #, c-format
 msgid "HEAD %s is not a commit!"
 msgstr ""
 
-#: sequencer.c:1056 builtin/commit.c:1491
+#: sequencer.c:1184 builtin/commit.c:1528
 msgid "could not parse HEAD commit"
 msgstr ""
 
-#: sequencer.c:1107 sequencer.c:1673
+#: sequencer.c:1235 sequencer.c:1832
 msgid "unable to parse commit author"
 msgstr ""
 
-#: sequencer.c:1117 builtin/am.c:1630 builtin/merge.c:643
+#: sequencer.c:1245 builtin/am.c:1630 builtin/merge.c:645
 msgid "git write-tree failed to write a tree"
 msgstr ""
 
-#: sequencer.c:1134 sequencer.c:1186
+#: sequencer.c:1262 sequencer.c:1317
 #, c-format
 msgid "unable to read commit message from '%s'"
 msgstr ""
 
-#: sequencer.c:1154 builtin/am.c:1650 builtin/commit.c:1594 builtin/merge.c:826
-#: builtin/merge.c:851
+#: sequencer.c:1284 builtin/am.c:1650 builtin/commit.c:1631 builtin/merge.c:825
+#: builtin/merge.c:850
 msgid "failed to write commit object"
 msgstr ""
 
-#: sequencer.c:1213
+#: sequencer.c:1344
 #, c-format
 msgid "could not parse commit %s"
 msgstr ""
 
-#: sequencer.c:1218
+#: sequencer.c:1349
 #, c-format
 msgid "could not parse parent commit %s"
 msgstr ""
 
-#: sequencer.c:1347
-#, c-format
-msgid ""
-"unexpected 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-
-#: sequencer.c:1353
-#, c-format
-msgid ""
-"invalid 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-
-#: sequencer.c:1359 sequencer.c:1384
+#: sequencer.c:1500 sequencer.c:1525
 #, c-format
 msgid "This is a combination of %d commits."
 msgstr ""
 
-#: sequencer.c:1368 sequencer.c:3265
+#: sequencer.c:1510 sequencer.c:4355
 msgid "need a HEAD to fixup"
 msgstr ""
 
-#: sequencer.c:1370
+#: sequencer.c:1512 sequencer.c:2729
 msgid "could not read HEAD"
 msgstr ""
 
-#: sequencer.c:1372
+#: sequencer.c:1514
 msgid "could not read HEAD's commit message"
 msgstr ""
 
-#: sequencer.c:1378
+#: sequencer.c:1520
 #, c-format
 msgid "cannot write '%s'"
 msgstr ""
 
-#: sequencer.c:1387 git-rebase--interactive.sh:452
+#: sequencer.c:1527 git-rebase--interactive.sh:457
 msgid "This is the 1st commit message:"
 msgstr ""
 
-#: sequencer.c:1395
+#: sequencer.c:1535
 #, c-format
 msgid "could not read commit message of %s"
 msgstr ""
 
-#: sequencer.c:1402
+#: sequencer.c:1542
 #, c-format
 msgid "This is the commit message #%d:"
 msgstr ""
 
-#: sequencer.c:1407
+#: sequencer.c:1548
 #, c-format
 msgid "The commit message #%d will be skipped:"
 msgstr ""
 
-#: sequencer.c:1412
+#: sequencer.c:1553
 #, c-format
 msgid "unknown command: %d"
 msgstr ""
 
-#: sequencer.c:1479
+#: sequencer.c:1631
 msgid "your index file is unmerged."
 msgstr ""
 
-#: sequencer.c:1498
+#: sequencer.c:1638
+msgid "cannot fixup root commit"
+msgstr ""
+
+#: sequencer.c:1657
 #, c-format
 msgid "commit %s is a merge but no -m option was given."
 msgstr ""
 
-#: sequencer.c:1506
+#: sequencer.c:1665
 #, c-format
 msgid "commit %s does not have parent %d"
 msgstr ""
 
-#: sequencer.c:1510
+#: sequencer.c:1669
 #, c-format
 msgid "mainline was specified but commit %s is not a merge."
 msgstr ""
 
-#: sequencer.c:1516
+#: sequencer.c:1675
 #, c-format
 msgid "cannot get commit message for %s"
 msgstr ""
 
 #. TRANSLATORS: The first %s will be a "todo" command like
 #. "revert" or "pick", the second %s a SHA1.
-#: sequencer.c:1535
+#: sequencer.c:1694
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr ""
 
-#: sequencer.c:1600 sequencer.c:2397
+#: sequencer.c:1759
 #, c-format
 msgid "could not rename '%s' to '%s'"
 msgstr ""
 
-#: sequencer.c:1654
+#: sequencer.c:1813
 #, c-format
 msgid "could not revert %s... %s"
 msgstr ""
 
-#: sequencer.c:1655
+#: sequencer.c:1814
 #, c-format
 msgid "could not apply %s... %s"
 msgstr ""
 
-#: sequencer.c:1702
+#: sequencer.c:1864
 msgid "empty commit set passed"
 msgstr ""
 
-#: sequencer.c:1712
+#: sequencer.c:1874
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr ""
 
-#: sequencer.c:1718
+#: sequencer.c:1881
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr ""
 
-#: sequencer.c:1792
+#: sequencer.c:1961
 #, c-format
 msgid "%s does not accept arguments: '%s'"
 msgstr ""
 
-#: sequencer.c:1801
+#: sequencer.c:1970
 #, c-format
 msgid "missing arguments for %s"
 msgstr ""
 
-#: sequencer.c:1844
+#: sequencer.c:2029
 #, c-format
 msgid "invalid line %d: %.*s"
 msgstr ""
 
-#: sequencer.c:1852
+#: sequencer.c:2037
 #, c-format
 msgid "cannot '%s' without a previous commit"
 msgstr ""
 
-#: sequencer.c:1883 sequencer.c:3056 sequencer.c:3091
+#: sequencer.c:2085 sequencer.c:4138 sequencer.c:4173
 #, c-format
 msgid "could not read '%s'."
 msgstr ""
 
-#: sequencer.c:1906
+#: sequencer.c:2108
 msgid "please fix this using 'git rebase --edit-todo'."
 msgstr ""
 
-#: sequencer.c:1908
+#: sequencer.c:2110
 #, c-format
 msgid "unusable instruction sheet: '%s'"
 msgstr ""
 
-#: sequencer.c:1913
+#: sequencer.c:2115
 msgid "no commits parsed."
 msgstr ""
 
-#: sequencer.c:1924
+#: sequencer.c:2126
 msgid "cannot cherry-pick during a revert."
 msgstr ""
 
-#: sequencer.c:1926
+#: sequencer.c:2128
 msgid "cannot revert during a cherry-pick."
 msgstr ""
 
-#: sequencer.c:1993
+#: sequencer.c:2195
 #, c-format
 msgid "invalid key: %s"
 msgstr ""
 
-#: sequencer.c:1996
+#: sequencer.c:2198
 #, c-format
 msgid "invalid value for %s: %s"
 msgstr ""
 
-#: sequencer.c:2062
+#: sequencer.c:2269
+msgid "unusable squash-onto"
+msgstr ""
+
+#: sequencer.c:2285
 #, c-format
 msgid "malformed options sheet: '%s'"
 msgstr ""
 
-#: sequencer.c:2100
+#: sequencer.c:2323
 msgid "a cherry-pick or revert is already in progress"
 msgstr ""
 
-#: sequencer.c:2101
+#: sequencer.c:2324
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr ""
 
-#: sequencer.c:2104
+#: sequencer.c:2327
 #, c-format
 msgid "could not create sequencer directory '%s'"
 msgstr ""
 
-#: sequencer.c:2118
+#: sequencer.c:2341
 msgid "could not lock HEAD"
 msgstr ""
 
-#: sequencer.c:2173 sequencer.c:2761
+#: sequencer.c:2396 sequencer.c:3403
 msgid "no cherry-pick or revert in progress"
 msgstr ""
 
-#: sequencer.c:2175
+#: sequencer.c:2398
 msgid "cannot resolve HEAD"
 msgstr ""
 
-#: sequencer.c:2177 sequencer.c:2212
+#: sequencer.c:2400 sequencer.c:2435
 msgid "cannot abort from a branch yet to be born"
 msgstr ""
 
-#: sequencer.c:2198 builtin/grep.c:720
+#: sequencer.c:2421 builtin/grep.c:720
 #, c-format
 msgid "cannot open '%s'"
 msgstr ""
 
-#: sequencer.c:2200
+#: sequencer.c:2423
 #, c-format
 msgid "cannot read '%s': %s"
 msgstr ""
 
-#: sequencer.c:2201
+#: sequencer.c:2424
 msgid "unexpected end of file"
 msgstr ""
 
-#: sequencer.c:2207
+#: sequencer.c:2430
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr ""
 
-#: sequencer.c:2218
+#: sequencer.c:2441
 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
 msgstr ""
 
-#: sequencer.c:2324 sequencer.c:2679
+#: sequencer.c:2545 sequencer.c:3321
 #, c-format
 msgid "could not update %s"
 msgstr ""
 
-#: sequencer.c:2362 sequencer.c:2659
+#: sequencer.c:2583 sequencer.c:3301
 msgid "cannot read HEAD"
 msgstr ""
 
-#: sequencer.c:2402 builtin/difftool.c:639
+#: sequencer.c:2618 sequencer.c:2622 builtin/difftool.c:639
 #, c-format
 msgid "could not copy '%s' to '%s'"
 msgstr ""
 
-#: sequencer.c:2421
+#: sequencer.c:2641
 msgid "could not read index"
 msgstr ""
 
-#: sequencer.c:2426
+#: sequencer.c:2646
 #, c-format
 msgid ""
 "execution failed: %s\n"
@@ -3315,11 +3576,11 @@ msgid ""
 "\n"
 msgstr ""
 
-#: sequencer.c:2432
+#: sequencer.c:2652
 msgid "and made changes to the index and/or the working tree\n"
 msgstr ""
 
-#: sequencer.c:2438
+#: sequencer.c:2658
 #, c-format
 msgid ""
 "execution succeeded: %s\n"
@@ -3330,17 +3591,62 @@ msgid ""
 "\n"
 msgstr ""
 
-#: sequencer.c:2497
+#: sequencer.c:2771
+msgid "writing fake root commit"
+msgstr ""
+
+#: sequencer.c:2776
+msgid "writing squash-onto"
+msgstr ""
+
+#: sequencer.c:2811
+#, c-format
+msgid "failed to find tree of %s"
+msgstr ""
+
+#: sequencer.c:2829
+msgid "could not write index"
+msgstr ""
+
+#: sequencer.c:2861
+msgid "cannot merge without a current revision"
+msgstr ""
+
+#: sequencer.c:2884
+#, c-format
+msgid "could not resolve '%s'"
+msgstr ""
+
+#: sequencer.c:2906
+#, c-format
+msgid "could not get commit message of '%s'"
+msgstr ""
+
+#: sequencer.c:2916 sequencer.c:2941
+#, c-format
+msgid "could not write '%s'"
+msgstr ""
+
+#: sequencer.c:3005
+#, c-format
+msgid "could not even attempt to merge '%.*s'"
+msgstr ""
+
+#: sequencer.c:3021
+msgid "merge: Unable to write new index file"
+msgstr ""
+
+#: sequencer.c:3088
 #, c-format
 msgid "Applied autostash.\n"
 msgstr ""
 
-#: sequencer.c:2509
+#: sequencer.c:3100
 #, c-format
 msgid "cannot store %s"
 msgstr ""
 
-#: sequencer.c:2512 git-rebase.sh:178
+#: sequencer.c:3103 git-rebase.sh:188
 #, c-format
 msgid ""
 "Applying autostash resulted in conflicts.\n"
@@ -3348,103 +3654,121 @@ msgid ""
 "You can run \"git stash pop\" or \"git stash drop\" at any time.\n"
 msgstr ""
 
-#: sequencer.c:2595
+#: sequencer.c:3134
+#, c-format
+msgid ""
+"Could not execute the todo command\n"
+"\n"
+"    %.*s\n"
+"It has been rescheduled; To edit the command before continuing, please\n"
+"edit the todo list first:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+msgstr ""
+
+#: sequencer.c:3202
 #, c-format
 msgid "Stopped at %s...  %.*s\n"
 msgstr ""
 
-#: sequencer.c:2637
+#: sequencer.c:3264
 #, c-format
 msgid "unknown command %d"
 msgstr ""
 
-#: sequencer.c:2667
+#: sequencer.c:3309
 msgid "could not read orig-head"
 msgstr ""
 
-#: sequencer.c:2672 sequencer.c:3262
+#: sequencer.c:3314 sequencer.c:4352
 msgid "could not read 'onto'"
 msgstr ""
 
-#: sequencer.c:2686
+#: sequencer.c:3328
 #, c-format
 msgid "could not update HEAD to %s"
 msgstr ""
 
-#: sequencer.c:2770
+#: sequencer.c:3414
 msgid "cannot rebase: You have unstaged changes."
 msgstr ""
 
-#: sequencer.c:2775
-msgid "could not remove CHERRY_PICK_HEAD"
-msgstr ""
-
-#: sequencer.c:2784
+#: sequencer.c:3423
 msgid "cannot amend non-existing commit"
 msgstr ""
 
-#: sequencer.c:2786
+#: sequencer.c:3425
 #, c-format
 msgid "invalid file: '%s'"
 msgstr ""
 
-#: sequencer.c:2788
+#: sequencer.c:3427
 #, c-format
 msgid "invalid contents: '%s'"
 msgstr ""
 
-#: sequencer.c:2791
+#: sequencer.c:3430
 msgid ""
 "\n"
 "You have uncommitted changes in your working tree. Please, commit them\n"
 "first and then run 'git rebase --continue' again."
 msgstr ""
 
-#: sequencer.c:2801
+#: sequencer.c:3455 sequencer.c:3493
+#, c-format
+msgid "could not write file: '%s'"
+msgstr ""
+
+#: sequencer.c:3508
+msgid "could not remove CHERRY_PICK_HEAD"
+msgstr ""
+
+#: sequencer.c:3515
 msgid "could not commit staged changes."
 msgstr ""
 
-#: sequencer.c:2881
+#: sequencer.c:3612
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr ""
 
-#: sequencer.c:2885
+#: sequencer.c:3616
 #, c-format
 msgid "%s: bad revision"
 msgstr ""
 
-#: sequencer.c:2918
+#: sequencer.c:3649
 msgid "can't revert as initial commit"
 msgstr ""
 
-#: sequencer.c:3023
+#: sequencer.c:4098
 msgid "make_script: unhandled options"
 msgstr ""
 
-#: sequencer.c:3026
+#: sequencer.c:4101
 msgid "make_script: error preparing revisions"
 msgstr ""
 
-#: sequencer.c:3060 sequencer.c:3095
+#: sequencer.c:4142 sequencer.c:4177
 #, c-format
 msgid "unusable todo list: '%s'"
 msgstr ""
 
-#: sequencer.c:3146
+#: sequencer.c:4236
 #, c-format
 msgid ""
 "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
 msgstr ""
 
-#: sequencer.c:3212
+#: sequencer.c:4302
 #, c-format
 msgid ""
 "Warning: some commits may have been dropped accidentally.\n"
 "Dropped commits (newer to older):\n"
 msgstr ""
 
-#: sequencer.c:3219
+#: sequencer.c:4309
 #, c-format
 msgid ""
 "To avoid this message, use \"drop\" to explicitly remove a commit.\n"
@@ -3455,7 +3779,7 @@ msgid ""
 "\n"
 msgstr ""
 
-#: sequencer.c:3231
+#: sequencer.c:4321
 #, c-format
 msgid ""
 "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
@@ -3463,34 +3787,28 @@ msgid ""
 "Or you can abort the rebase with 'git rebase --abort'.\n"
 msgstr ""
 
-#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395
-#: builtin/am.c:779
-#, c-format
-msgid "could not open '%s' for writing"
-msgstr ""
-
-#: sequencer.c:3285
+#: sequencer.c:4375
 #, c-format
 msgid "could not parse commit '%s'"
 msgstr ""
 
-#: sequencer.c:3401
+#: sequencer.c:4490
 msgid "the script was already rearranged."
 msgstr ""
 
-#: setup.c:122
+#: setup.c:123
 #, c-format
 msgid "'%s' is outside repository"
 msgstr ""
 
-#: setup.c:171
+#: setup.c:172
 #, c-format
 msgid ""
 "%s: no such path in the working tree.\n"
 "Use 'git <command> -- <path>...' to specify paths that do not exist locally."
 msgstr ""
 
-#: setup.c:184
+#: setup.c:185
 #, c-format
 msgid ""
 "ambiguous argument '%s': unknown revision or path not in the working tree.\n"
@@ -3498,12 +3816,12 @@ msgid ""
 "'git <command> [<revision>...] -- [<file>...]'"
 msgstr ""
 
-#: setup.c:233
+#: setup.c:234
 #, c-format
 msgid "option '%s' must come before non-option arguments"
 msgstr ""
 
-#: setup.c:252
+#: setup.c:253
 #, c-format
 msgid ""
 "ambiguous argument '%s': both revision and filename\n"
@@ -3511,152 +3829,152 @@ msgid ""
 "'git <command> [<revision>...] -- [<file>...]'"
 msgstr ""
 
-#: setup.c:388
+#: setup.c:389
 msgid "unable to set up work tree using invalid config"
 msgstr ""
 
-#: setup.c:395
+#: setup.c:393
 msgid "this operation must be run in a work tree"
 msgstr ""
 
-#: setup.c:506
+#: setup.c:503
 #, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr ""
 
-#: setup.c:514
+#: setup.c:511
 msgid "unknown repository extensions found:"
 msgstr ""
 
-#: setup.c:533
+#: setup.c:530
 #, c-format
 msgid "error opening '%s'"
 msgstr ""
 
-#: setup.c:535
+#: setup.c:532
 #, c-format
 msgid "too large to be a .git file: '%s'"
 msgstr ""
 
-#: setup.c:537
+#: setup.c:534
 #, c-format
 msgid "error reading %s"
 msgstr ""
 
-#: setup.c:539
+#: setup.c:536
 #, c-format
 msgid "invalid gitfile format: %s"
 msgstr ""
 
-#: setup.c:541
+#: setup.c:538
 #, c-format
 msgid "no path in gitfile: %s"
 msgstr ""
 
-#: setup.c:543
+#: setup.c:540
 #, c-format
 msgid "not a git repository: %s"
 msgstr ""
 
-#: setup.c:642
+#: setup.c:639
 #, c-format
 msgid "'$%s' too big"
 msgstr ""
 
-#: setup.c:656
+#: setup.c:653
 #, c-format
 msgid "not a git repository: '%s'"
 msgstr ""
 
-#: setup.c:685 setup.c:687 setup.c:718
+#: setup.c:682 setup.c:684 setup.c:715
 #, c-format
 msgid "cannot chdir to '%s'"
 msgstr ""
 
-#: setup.c:690 setup.c:746 setup.c:756 setup.c:795 setup.c:803 setup.c:818
+#: setup.c:687 setup.c:743 setup.c:753 setup.c:792 setup.c:800 setup.c:815
 msgid "cannot come back to cwd"
 msgstr ""
 
-#: setup.c:816
+#: setup.c:813
 #, c-format
 msgid "not a git repository (or any of the parent directories): %s"
 msgstr ""
 
-#: setup.c:827
+#: setup.c:824
 #, c-format
 msgid "failed to stat '%*s%s%s'"
 msgstr ""
 
-#: setup.c:1057
+#: setup.c:1054
 msgid "Unable to read current working directory"
 msgstr ""
 
-#: setup.c:1069 setup.c:1075
+#: setup.c:1066 setup.c:1072
 #, c-format
 msgid "cannot change to '%s'"
 msgstr ""
 
-#: setup.c:1088
+#: setup.c:1085
 #, 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 ""
 
-#: setup.c:1172
+#: setup.c:1168
 #, c-format
 msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
 "The owner of files must always have read and write permissions."
 msgstr ""
 
-#: setup.c:1215
+#: setup.c:1211
 msgid "open /dev/null or dup failed"
 msgstr ""
 
-#: setup.c:1230
+#: setup.c:1226
 msgid "fork failed"
 msgstr ""
 
-#: setup.c:1235
+#: setup.c:1231
 msgid "setsid failed"
 msgstr ""
 
-#: sha1_file.c:592
+#: sha1-file.c:625
 #, c-format
 msgid "path '%s' does not exist"
 msgstr ""
 
-#: sha1_file.c:618
+#: sha1-file.c:651
 #, c-format
 msgid "reference repository '%s' as a linked checkout is not supported yet."
 msgstr ""
 
-#: sha1_file.c:624
+#: sha1-file.c:657
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr ""
 
-#: sha1_file.c:630
+#: sha1-file.c:663
 #, c-format
 msgid "reference repository '%s' is shallow"
 msgstr ""
 
-#: sha1_file.c:638
+#: sha1-file.c:671
 #, c-format
 msgid "reference repository '%s' is grafted"
 msgstr ""
 
-#: sha1_name.c:422
+#: sha1-name.c:442
 #, c-format
 msgid "short SHA1 %s is ambiguous"
 msgstr ""
 
-#: sha1_name.c:433
+#: sha1-name.c:453
 msgid "The candidates are:"
 msgstr ""
 
-#: sha1_name.c:693
+#: sha1-name.c:695
 msgid ""
 "Git normally never creates a ref that ends with 40 hex characters\n"
 "because it will be ignored when you just specify 40-hex. These refs\n"
@@ -3669,86 +3987,86 @@ msgid ""
 "running \"git config advice.objectNameWarning false\""
 msgstr ""
 
-#: submodule.c:96 submodule.c:130
+#: submodule.c:97 submodule.c:131
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr ""
 
-#: submodule.c:100 submodule.c:134
+#: submodule.c:101 submodule.c:135
 #, c-format
 msgid "Could not find section in .gitmodules where path=%s"
 msgstr ""
 
-#: submodule.c:108
+#: submodule.c:109
 #, c-format
 msgid "Could not update .gitmodules entry %s"
 msgstr ""
 
-#: submodule.c:141
+#: submodule.c:142
 #, c-format
 msgid "Could not remove .gitmodules entry for %s"
 msgstr ""
 
-#: submodule.c:152
+#: submodule.c:153
 msgid "staging updated .gitmodules failed"
 msgstr ""
 
-#: submodule.c:312
+#: submodule.c:315
 #, c-format
 msgid "in unpopulated submodule '%s'"
 msgstr ""
 
-#: submodule.c:343
+#: submodule.c:346
 #, c-format
 msgid "Pathspec '%s' is in submodule '%.*s'"
 msgstr ""
 
-#: submodule.c:833
+#: submodule.c:837
 #, c-format
 msgid "submodule entry '%s' (%s) is a %s, not a commit"
 msgstr ""
 
-#: submodule.c:1065 builtin/branch.c:648 builtin/submodule--helper.c:1724
+#: submodule.c:1069 builtin/branch.c:651 builtin/submodule--helper.c:1743
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr ""
 
-#: submodule.c:1370
+#: submodule.c:1375
 #, c-format
 msgid "'%s' not recognized as a git repository"
 msgstr ""
 
-#: submodule.c:1508
+#: submodule.c:1513
 #, c-format
 msgid "could not start 'git status' in submodule '%s'"
 msgstr ""
 
-#: submodule.c:1521
+#: submodule.c:1526
 #, c-format
 msgid "could not run 'git status' in submodule '%s'"
 msgstr ""
 
-#: submodule.c:1614
+#: submodule.c:1619
 #, c-format
 msgid "submodule '%s' has dirty index"
 msgstr ""
 
-#: submodule.c:1878
+#: submodule.c:1718
 #, c-format
 msgid ""
 "relocate_gitdir for submodule '%s' with more than one worktree not supported"
 msgstr ""
 
-#: submodule.c:1890 submodule.c:1946
+#: submodule.c:1730 submodule.c:1786
 #, c-format
 msgid "could not lookup name for submodule '%s'"
 msgstr ""
 
-#: submodule.c:1894 builtin/submodule--helper.c:1246
-#: builtin/submodule--helper.c:1256
+#: submodule.c:1734 builtin/submodule--helper.c:1261
+#: builtin/submodule--helper.c:1271
 #, c-format
 msgid "could not create directory '%s'"
 msgstr ""
 
-#: submodule.c:1897
+#: submodule.c:1737
 #, c-format
 msgid ""
 "Migrating git directory of '%s%s' from\n"
@@ -3756,29 +4074,30 @@ msgid ""
 "'%s'\n"
 msgstr ""
 
-#: submodule.c:1981
+#: submodule.c:1821
 #, c-format
 msgid "could not recurse into submodule '%s'"
 msgstr ""
 
-#: submodule.c:2025
+#: submodule.c:1865
 msgid "could not start ls-files in .."
 msgstr ""
 
-#: submodule.c:2045
-msgid "BUG: returned path string doesn't match cwd?"
+#: submodule.c:1904
+#, c-format
+msgid "ls-tree returned unexpected return code %d"
 msgstr ""
 
-#: submodule.c:2064
+#: submodule-config.c:230
 #, c-format
-msgid "ls-tree returned unexpected return code %d"
+msgid "ignoring suspicious submodule name: %s"
 msgstr ""
 
-#: submodule-config.c:263
+#: submodule-config.c:294
 msgid "negative values not allowed for submodule.fetchjobs"
 msgstr ""
 
-#: submodule-config.c:436
+#: submodule-config.c:467
 #, c-format
 msgid "invalid value for %s"
 msgstr ""
@@ -3794,7 +4113,7 @@ msgstr ""
 msgid "unknown value '%s' for key '%s'"
 msgstr ""
 
-#: trailer.c:539 trailer.c:544 builtin/remote.c:290
+#: trailer.c:539 trailer.c:544 builtin/remote.c:293
 #, c-format
 msgid "more than one %s"
 msgstr ""
@@ -3837,24 +4156,28 @@ msgstr ""
 msgid "could not rename temporary file to %s"
 msgstr ""
 
-#: transport.c:63
+#: transport.c:116
 #, c-format
 msgid "Would set upstream of '%s' to '%s' of '%s'\n"
 msgstr ""
 
-#: transport.c:152
+#: transport.c:208
 #, c-format
 msgid "transport: invalid depth option '%s'"
 msgstr ""
 
-#: transport.c:916
+#: transport.c:584
+msgid "could not parse transport.color.* config"
+msgstr ""
+
+#: transport.c:996
 #, c-format
 msgid ""
 "The following submodule paths contain changes that can\n"
 "not be found on any remote:\n"
 msgstr ""
 
-#: transport.c:920
+#: transport.c:1000
 #, c-format
 msgid ""
 "\n"
@@ -3870,11 +4193,11 @@ msgid ""
 "\n"
 msgstr ""
 
-#: transport.c:928
+#: transport.c:1008
 msgid "Aborting."
 msgstr ""
 
-#: transport-helper.c:1079
+#: transport-helper.c:1087
 #, c-format
 msgid "Could not read ref %s"
 msgstr ""
@@ -3891,102 +4214,102 @@ msgstr ""
 msgid "empty filename in tree entry"
 msgstr ""
 
-#: tree-walk.c:114
+#: tree-walk.c:113
 msgid "too-short tree file"
 msgstr ""
 
-#: unpack-trees.c:108
+#: unpack-trees.c:111
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
 "%%sPlease commit your changes or stash them before you switch branches."
 msgstr ""
 
-#: unpack-trees.c:110
+#: unpack-trees.c:113
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
 "%%s"
 msgstr ""
 
-#: unpack-trees.c:113
+#: unpack-trees.c:116
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
 "%%sPlease commit your changes or stash them before you merge."
 msgstr ""
 
-#: unpack-trees.c:115
+#: unpack-trees.c:118
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
 "%%s"
 msgstr ""
 
-#: unpack-trees.c:118
+#: unpack-trees.c:121
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
 "%%sPlease commit your changes or stash them before you %s."
 msgstr ""
 
-#: unpack-trees.c:120
+#: unpack-trees.c:123
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
 "%%s"
 msgstr ""
 
-#: unpack-trees.c:125
+#: unpack-trees.c:128
 #, c-format
 msgid ""
 "Updating the following directories would lose untracked files in them:\n"
 "%s"
 msgstr ""
 
-#: unpack-trees.c:129
+#: unpack-trees.c:132
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
 "%%sPlease move or remove them before you switch branches."
 msgstr ""
 
-#: unpack-trees.c:131
+#: unpack-trees.c:134
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
 "%%s"
 msgstr ""
 
-#: unpack-trees.c:134
+#: unpack-trees.c:137
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
 "%%sPlease move or remove them before you merge."
 msgstr ""
 
-#: unpack-trees.c:136
+#: unpack-trees.c:139
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
 "%%s"
 msgstr ""
 
-#: unpack-trees.c:139
+#: unpack-trees.c:142
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
 "%%sPlease move or remove them before you %s."
 msgstr ""
 
-#: unpack-trees.c:141
+#: unpack-trees.c:144
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
 "%%s"
 msgstr ""
 
-#: unpack-trees.c:146
+#: unpack-trees.c:150
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -3994,7 +4317,7 @@ msgid ""
 "%%sPlease move or remove them before you switch branches."
 msgstr ""
 
-#: unpack-trees.c:148
+#: unpack-trees.c:152
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4002,47 +4325,47 @@ msgid ""
 "%%s"
 msgstr ""
 
-#: unpack-trees.c:151
+#: unpack-trees.c:155
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
 "%%sPlease move or remove them before you merge."
 msgstr ""
 
-#: unpack-trees.c:153
+#: unpack-trees.c:157
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
 "%%s"
 msgstr ""
 
-#: unpack-trees.c:156
+#: unpack-trees.c:160
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
 "%%sPlease move or remove them before you %s."
 msgstr ""
 
-#: unpack-trees.c:158
+#: unpack-trees.c:162
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
 "%%s"
 msgstr ""
 
-#: unpack-trees.c:165
+#: unpack-trees.c:170
 #, c-format
 msgid "Entry '%s' overlaps with '%s'.  Cannot bind."
 msgstr ""
 
-#: unpack-trees.c:168
+#: unpack-trees.c:173
 #, c-format
 msgid ""
 "Cannot update sparse checkout: the following entries are not up to date:\n"
 "%s"
 msgstr ""
 
-#: unpack-trees.c:170
+#: unpack-trees.c:175
 #, c-format
 msgid ""
 "The following working tree files would be overwritten by sparse checkout "
@@ -4050,7 +4373,7 @@ msgid ""
 "%s"
 msgstr ""
 
-#: unpack-trees.c:172
+#: unpack-trees.c:177
 #, c-format
 msgid ""
 "The following working tree files would be removed by sparse checkout "
@@ -4058,19 +4381,19 @@ msgid ""
 "%s"
 msgstr ""
 
-#: unpack-trees.c:174
+#: unpack-trees.c:179
 #, c-format
 msgid ""
 "Cannot update submodule:\n"
 "%s"
 msgstr ""
 
-#: unpack-trees.c:251
+#: unpack-trees.c:262
 #, c-format
 msgid "Aborting\n"
 msgstr ""
 
-#: unpack-trees.c:333
+#: unpack-trees.c:344
 msgid "Checking out files"
 msgstr ""
 
@@ -4139,7 +4462,7 @@ msgid "could not open '%s' for reading and writing"
 msgstr ""
 
 #: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770
-#: builtin/am.c:862 builtin/merge.c:1044
+#: builtin/am.c:862 builtin/merge.c:1043
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr ""
@@ -4153,374 +4476,374 @@ msgstr ""
 msgid "unable to get current working directory"
 msgstr ""
 
-#: wt-status.c:151
+#: wt-status.c:154
 msgid "Unmerged paths:"
 msgstr ""
 
-#: wt-status.c:178 wt-status.c:205
+#: wt-status.c:181 wt-status.c:208
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr ""
 
-#: wt-status.c:180 wt-status.c:207
+#: wt-status.c:183 wt-status.c:210
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr ""
 
-#: wt-status.c:184
+#: wt-status.c:187
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr ""
 
-#: wt-status.c:186 wt-status.c:190
+#: wt-status.c:189 wt-status.c:193
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
 
-#: wt-status.c:188
+#: wt-status.c:191
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr ""
 
-#: wt-status.c:199 wt-status.c:1007
+#: wt-status.c:202 wt-status.c:1015
 msgid "Changes to be committed:"
 msgstr ""
 
-#: wt-status.c:217 wt-status.c:1016
+#: wt-status.c:220 wt-status.c:1024
 msgid "Changes not staged for commit:"
 msgstr ""
 
-#: wt-status.c:221
+#: wt-status.c:224
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
 
-#: wt-status.c:223
+#: wt-status.c:226
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
 
-#: wt-status.c:224
+#: wt-status.c:227
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 
-#: wt-status.c:226
+#: wt-status.c:229
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 
-#: wt-status.c:238
+#: wt-status.c:241
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
 
-#: wt-status.c:253
+#: wt-status.c:256
 msgid "both deleted:"
 msgstr ""
 
-#: wt-status.c:255
+#: wt-status.c:258
 msgid "added by us:"
 msgstr ""
 
-#: wt-status.c:257
+#: wt-status.c:260
 msgid "deleted by them:"
 msgstr ""
 
-#: wt-status.c:259
+#: wt-status.c:262
 msgid "added by them:"
 msgstr ""
 
-#: wt-status.c:261
+#: wt-status.c:264
 msgid "deleted by us:"
 msgstr ""
 
-#: wt-status.c:263
+#: wt-status.c:266
 msgid "both added:"
 msgstr ""
 
-#: wt-status.c:265
+#: wt-status.c:268
 msgid "both modified:"
 msgstr ""
 
-#: wt-status.c:275
+#: wt-status.c:278
 msgid "new file:"
 msgstr ""
 
-#: wt-status.c:277
+#: wt-status.c:280
 msgid "copied:"
 msgstr ""
 
-#: wt-status.c:279
+#: wt-status.c:282
 msgid "deleted:"
 msgstr ""
 
-#: wt-status.c:281
+#: wt-status.c:284
 msgid "modified:"
 msgstr ""
 
-#: wt-status.c:283
+#: wt-status.c:286
 msgid "renamed:"
 msgstr ""
 
-#: wt-status.c:285
+#: wt-status.c:288
 msgid "typechange:"
 msgstr ""
 
-#: wt-status.c:287
+#: wt-status.c:290
 msgid "unknown:"
 msgstr ""
 
-#: wt-status.c:289
+#: wt-status.c:292
 msgid "unmerged:"
 msgstr ""
 
-#: wt-status.c:369
+#: wt-status.c:372
 msgid "new commits, "
 msgstr ""
 
-#: wt-status.c:371
+#: wt-status.c:374
 msgid "modified content, "
 msgstr ""
 
-#: wt-status.c:373
+#: wt-status.c:376
 msgid "untracked content, "
 msgstr ""
 
-#: wt-status.c:847
+#: wt-status.c:853
 #, c-format
 msgid "Your stash currently has %d entry"
 msgid_plural "Your stash currently has %d entries"
 msgstr[0] ""
 msgstr[1] ""
 
-#: wt-status.c:879
+#: wt-status.c:885
 msgid "Submodules changed but not updated:"
 msgstr ""
 
-#: wt-status.c:881
+#: wt-status.c:887
 msgid "Submodule changes to be committed:"
 msgstr ""
 
-#: wt-status.c:963
+#: wt-status.c:969
 msgid ""
 "Do not modify or remove the line above.\n"
 "Everything below it will be ignored."
 msgstr ""
 
-#: wt-status.c:1076
+#: wt-status.c:1084
 msgid "You have unmerged paths."
 msgstr ""
 
-#: wt-status.c:1079
+#: wt-status.c:1087
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr ""
 
-#: wt-status.c:1081
+#: wt-status.c:1089
 msgid "  (use \"git merge --abort\" to abort the merge)"
 msgstr ""
 
-#: wt-status.c:1086
+#: wt-status.c:1094
 msgid "All conflicts fixed but you are still merging."
 msgstr ""
 
-#: wt-status.c:1089
+#: wt-status.c:1097
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr ""
 
-#: wt-status.c:1099
+#: wt-status.c:1107
 msgid "You are in the middle of an am session."
 msgstr ""
 
-#: wt-status.c:1102
+#: wt-status.c:1110
 msgid "The current patch is empty."
 msgstr ""
 
-#: wt-status.c:1106
+#: wt-status.c:1114
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr ""
 
-#: wt-status.c:1108
+#: wt-status.c:1116
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr ""
 
-#: wt-status.c:1110
+#: wt-status.c:1118
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr ""
 
-#: wt-status.c:1242
+#: wt-status.c:1250
 msgid "git-rebase-todo is missing."
 msgstr ""
 
-#: wt-status.c:1244
+#: wt-status.c:1252
 msgid "No commands done."
 msgstr ""
 
-#: wt-status.c:1247
+#: wt-status.c:1255
 #, c-format
 msgid "Last command done (%d command done):"
 msgid_plural "Last commands done (%d commands done):"
 msgstr[0] ""
 msgstr[1] ""
 
-#: wt-status.c:1258
+#: wt-status.c:1266
 #, c-format
 msgid "  (see more in file %s)"
 msgstr ""
 
-#: wt-status.c:1263
+#: wt-status.c:1271
 msgid "No commands remaining."
 msgstr ""
 
-#: wt-status.c:1266
+#: wt-status.c:1274
 #, c-format
 msgid "Next command to do (%d remaining command):"
 msgid_plural "Next commands to do (%d remaining commands):"
 msgstr[0] ""
 msgstr[1] ""
 
-#: wt-status.c:1274
+#: wt-status.c:1282
 msgid "  (use \"git rebase --edit-todo\" to view and edit)"
 msgstr ""
 
-#: wt-status.c:1287
+#: wt-status.c:1295
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr ""
 
-#: wt-status.c:1292
+#: wt-status.c:1300
 msgid "You are currently rebasing."
 msgstr ""
 
-#: wt-status.c:1306
+#: wt-status.c:1314
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr ""
 
-#: wt-status.c:1308
+#: wt-status.c:1316
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr ""
 
-#: wt-status.c:1310
+#: wt-status.c:1318
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr ""
 
-#: wt-status.c:1316
+#: wt-status.c:1324
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr ""
 
-#: wt-status.c:1320
+#: wt-status.c:1328
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 
-#: wt-status.c:1325
+#: wt-status.c:1333
 msgid "You are currently splitting a commit during a rebase."
 msgstr ""
 
-#: wt-status.c:1328
+#: wt-status.c:1336
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr ""
 
-#: wt-status.c:1332
+#: wt-status.c:1340
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 
-#: wt-status.c:1337
+#: wt-status.c:1345
 msgid "You are currently editing a commit during a rebase."
 msgstr ""
 
-#: wt-status.c:1340
+#: wt-status.c:1348
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr ""
 
-#: wt-status.c:1342
+#: wt-status.c:1350
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr ""
 
-#: wt-status.c:1352
+#: wt-status.c:1360
 #, c-format
 msgid "You are currently cherry-picking commit %s."
 msgstr ""
 
-#: wt-status.c:1357
+#: wt-status.c:1365
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr ""
 
-#: wt-status.c:1360
+#: wt-status.c:1368
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr ""
 
-#: wt-status.c:1362
+#: wt-status.c:1370
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr ""
 
-#: wt-status.c:1371
+#: wt-status.c:1379
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr ""
 
-#: wt-status.c:1376
+#: wt-status.c:1384
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr ""
 
-#: wt-status.c:1379
+#: wt-status.c:1387
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr ""
 
-#: wt-status.c:1381
+#: wt-status.c:1389
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr ""
 
-#: wt-status.c:1392
+#: wt-status.c:1400
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr ""
 
-#: wt-status.c:1396
+#: wt-status.c:1404
 msgid "You are currently bisecting."
 msgstr ""
 
-#: wt-status.c:1399
+#: wt-status.c:1407
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr ""
 
-#: wt-status.c:1596
+#: wt-status.c:1604
 msgid "On branch "
 msgstr ""
 
-#: wt-status.c:1602
+#: wt-status.c:1610
 msgid "interactive rebase in progress; onto "
 msgstr ""
 
-#: wt-status.c:1604
+#: wt-status.c:1612
 msgid "rebase in progress; onto "
 msgstr ""
 
-#: wt-status.c:1609
+#: wt-status.c:1617
 msgid "HEAD detached at "
 msgstr ""
 
-#: wt-status.c:1611
+#: wt-status.c:1619
 msgid "HEAD detached from "
 msgstr ""
 
-#: wt-status.c:1614
+#: wt-status.c:1622
 msgid "Not currently on any branch."
 msgstr ""
 
-#: wt-status.c:1634
+#: wt-status.c:1642
 msgid "Initial commit"
 msgstr ""
 
-#: wt-status.c:1635
+#: wt-status.c:1643
 msgid "No commits yet"
 msgstr ""
 
-#: wt-status.c:1649
+#: wt-status.c:1657
 msgid "Untracked files"
 msgstr ""
 
-#: wt-status.c:1651
+#: wt-status.c:1659
 msgid "Ignored files"
 msgstr ""
 
-#: wt-status.c:1655
+#: wt-status.c:1663
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -4528,97 +4851,97 @@ msgid ""
 "new files yourself (see 'git help status')."
 msgstr ""
 
-#: wt-status.c:1661
+#: wt-status.c:1669
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr ""
 
-#: wt-status.c:1663
+#: wt-status.c:1671
 msgid " (use -u option to show untracked files)"
 msgstr ""
 
-#: wt-status.c:1669
+#: wt-status.c:1677
 msgid "No changes"
 msgstr ""
 
-#: wt-status.c:1674
+#: wt-status.c:1682
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
 
-#: wt-status.c:1677
+#: wt-status.c:1685
 #, c-format
 msgid "no changes added to commit\n"
 msgstr ""
 
-#: wt-status.c:1680
+#: wt-status.c:1688
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
 "track)\n"
 msgstr ""
 
-#: wt-status.c:1683
+#: wt-status.c:1691
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr ""
 
-#: wt-status.c:1686
+#: wt-status.c:1694
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
 
-#: wt-status.c:1689 wt-status.c:1694
+#: wt-status.c:1697 wt-status.c:1702
 #, c-format
 msgid "nothing to commit\n"
 msgstr ""
 
-#: wt-status.c:1692
+#: wt-status.c:1700
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr ""
 
-#: wt-status.c:1696
+#: wt-status.c:1704
 #, c-format
 msgid "nothing to commit, working tree clean\n"
 msgstr ""
 
-#: wt-status.c:1809
+#: wt-status.c:1817
 msgid "No commits yet on "
 msgstr ""
 
-#: wt-status.c:1813
+#: wt-status.c:1821
 msgid "HEAD (no branch)"
 msgstr ""
 
-#: wt-status.c:1844
+#: wt-status.c:1852
 msgid "different"
 msgstr ""
 
-#: wt-status.c:1846 wt-status.c:1854
+#: wt-status.c:1854 wt-status.c:1862
 msgid "behind "
 msgstr ""
 
-#: wt-status.c:1849 wt-status.c:1852
+#: wt-status.c:1857 wt-status.c:1860
 msgid "ahead "
 msgstr ""
 
 #. TRANSLATORS: the action is e.g. "pull with rebase"
-#: wt-status.c:2358
+#: wt-status.c:2366
 #, c-format
 msgid "cannot %s: You have unstaged changes."
 msgstr ""
 
-#: wt-status.c:2364
+#: wt-status.c:2372
 msgid "additionally, your index contains uncommitted changes."
 msgstr ""
 
-#: wt-status.c:2366
+#: wt-status.c:2374
 #, c-format
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr ""
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:440
+#: compat/precompose_utf8.c:58 builtin/clone.c:442
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr ""
@@ -4632,7 +4955,7 @@ msgstr ""
 msgid "unexpected diff status %c"
 msgstr ""
 
-#: builtin/add.c:88 builtin/commit.c:257
+#: builtin/add.c:88 builtin/commit.c:266
 msgid "updating files failed"
 msgstr ""
 
@@ -4645,7 +4968,7 @@ msgstr ""
 msgid "Unstaged changes after refreshing the index:"
 msgstr ""
 
-#: builtin/add.c:233 builtin/rev-parse.c:888
+#: builtin/add.c:233 builtin/rev-parse.c:892
 msgid "Could not read the index"
 msgstr ""
 
@@ -4676,77 +4999,77 @@ msgstr ""
 msgid "Could not apply '%s'"
 msgstr ""
 
-#: builtin/add.c:271
+#: builtin/add.c:269
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr ""
 
-#: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:146 builtin/mv.c:124
-#: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541
-#: builtin/remote.c:1333 builtin/rm.c:242 builtin/send-pack.c:164
+#: builtin/add.c:289 builtin/clean.c:911 builtin/fetch.c:145 builtin/mv.c:123
+#: builtin/prune-packed.c:55 builtin/pull.c:212 builtin/push.c:557
+#: builtin/remote.c:1342 builtin/rm.c:240 builtin/send-pack.c:165
 msgid "dry run"
 msgstr ""
 
-#: builtin/add.c:294
+#: builtin/add.c:292
 msgid "interactive picking"
 msgstr ""
 
-#: builtin/add.c:295 builtin/checkout.c:1128 builtin/reset.c:302
+#: builtin/add.c:293 builtin/checkout.c:1135 builtin/reset.c:302
 msgid "select hunks interactively"
 msgstr ""
 
-#: builtin/add.c:296
+#: builtin/add.c:294
 msgid "edit current diff and apply"
 msgstr ""
 
-#: builtin/add.c:297
+#: builtin/add.c:295
 msgid "allow adding otherwise ignored files"
 msgstr ""
 
-#: builtin/add.c:298
+#: builtin/add.c:296
 msgid "update tracked files"
 msgstr ""
 
-#: builtin/add.c:299
+#: builtin/add.c:297
 msgid "renormalize EOL of tracked files (implies -u)"
 msgstr ""
 
-#: builtin/add.c:300
+#: builtin/add.c:298
 msgid "record only the fact that the path will be added later"
 msgstr ""
 
-#: builtin/add.c:301
+#: builtin/add.c:299
 msgid "add changes from all tracked and untracked files"
 msgstr ""
 
-#: builtin/add.c:304
+#: builtin/add.c:302
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr ""
 
-#: builtin/add.c:306
+#: builtin/add.c:304
 msgid "don't add, only refresh the index"
 msgstr ""
 
-#: builtin/add.c:307
+#: builtin/add.c:305
 msgid "just skip files which cannot be added because of errors"
 msgstr ""
 
-#: builtin/add.c:308
+#: builtin/add.c:306
 msgid "check if - even missing - files are ignored in dry run"
 msgstr ""
 
-#: builtin/add.c:309 builtin/update-index.c:964
+#: builtin/add.c:307 builtin/update-index.c:974
 msgid "(+/-)x"
 msgstr ""
 
-#: builtin/add.c:309 builtin/update-index.c:965
+#: builtin/add.c:307 builtin/update-index.c:975
 msgid "override the executable bit of the listed files"
 msgstr ""
 
-#: builtin/add.c:311
+#: builtin/add.c:309
 msgid "warn when adding an embedded repository"
 msgstr ""
 
-#: builtin/add.c:326
+#: builtin/add.c:324
 #, c-format
 msgid ""
 "You've added another git repository inside your current repository.\n"
@@ -4764,47 +5087,47 @@ msgid ""
 "See \"git help submodule\" for more information."
 msgstr ""
 
-#: builtin/add.c:354
+#: builtin/add.c:352
 #, c-format
 msgid "adding embedded git repository: %s"
 msgstr ""
 
-#: builtin/add.c:372
+#: builtin/add.c:370
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr ""
 
-#: builtin/add.c:380
+#: builtin/add.c:378
 msgid "adding files failed"
 msgstr ""
 
-#: builtin/add.c:417
+#: builtin/add.c:416
 msgid "-A and -u are mutually incompatible"
 msgstr ""
 
-#: builtin/add.c:424
+#: builtin/add.c:423
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr ""
 
-#: builtin/add.c:428
+#: builtin/add.c:427
 #, c-format
 msgid "--chmod param '%s' must be either -x or +x"
 msgstr ""
 
-#: builtin/add.c:443
+#: builtin/add.c:442
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr ""
 
-#: builtin/add.c:444
+#: builtin/add.c:443
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr ""
 
-#: builtin/add.c:449 builtin/check-ignore.c:177 builtin/checkout.c:280
-#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316
+#: builtin/add.c:448 builtin/check-ignore.c:177 builtin/checkout.c:280
+#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:325
 #: builtin/diff-tree.c:114 builtin/mv.c:144 builtin/reset.c:241
-#: builtin/rm.c:271 builtin/submodule--helper.c:326
+#: builtin/rm.c:270 builtin/submodule--helper.c:328
 msgid "index file corrupt"
 msgstr ""
 
@@ -4856,7 +5179,7 @@ msgstr ""
 msgid "Patch format detection failed."
 msgstr ""
 
-#: builtin/am.c:1013 builtin/clone.c:405
+#: builtin/am.c:1013 builtin/clone.c:407
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr ""
@@ -4865,7 +5188,7 @@ msgstr ""
 msgid "Failed to split patches."
 msgstr ""
 
-#: builtin/am.c:1148 builtin/commit.c:342
+#: builtin/am.c:1148 builtin/commit.c:351
 msgid "unable to write index file"
 msgstr ""
 
@@ -5025,7 +5348,7 @@ msgid "allow fall back on 3way merging if needed"
 msgstr ""
 
 #: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57
-#: builtin/repack.c:182
+#: builtin/repack.c:192
 msgid "be quiet"
 msgstr ""
 
@@ -5067,16 +5390,17 @@ msgstr ""
 msgid "pass it through git-apply"
 msgstr ""
 
-#: builtin/am.c:2260 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668
-#: builtin/grep.c:853 builtin/merge.c:206 builtin/pull.c:145 builtin/pull.c:203
-#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197
-#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:382
-#: parse-options.h:144 parse-options.h:146 parse-options.h:257
+#: builtin/am.c:2260 builtin/commit.c:1332 builtin/fmt-merge-msg.c:665
+#: builtin/fmt-merge-msg.c:668 builtin/grep.c:853 builtin/merge.c:208
+#: builtin/pull.c:150 builtin/pull.c:208 builtin/repack.c:201
+#: builtin/repack.c:205 builtin/repack.c:207 builtin/show-branch.c:631
+#: builtin/show-ref.c:169 builtin/tag.c:383 parse-options.h:144
+#: parse-options.h:146 parse-options.h:258
 msgid "n"
 msgstr ""
 
-#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38
-#: builtin/replace.c:445 builtin/tag.c:418 builtin/verify-tag.c:39
+#: builtin/am.c:2266 builtin/branch.c:632 builtin/for-each-ref.c:38
+#: builtin/replace.c:543 builtin/tag.c:419 builtin/verify-tag.c:39
 msgid "format"
 msgstr ""
 
@@ -5120,8 +5444,8 @@ msgstr ""
 msgid "use current timestamp for author date"
 msgstr ""
 
-#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237
-#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:398
+#: builtin/am.c:2298 builtin/commit.c:1468 builtin/merge.c:239
+#: builtin/pull.c:183 builtin/revert.c:112 builtin/tag.c:399
 msgid "key-id"
 msgstr ""
 
@@ -5256,115 +5580,141 @@ msgstr ""
 msgid "--bisect-clean-state requires no arguments"
 msgstr ""
 
-#: builtin/blame.c:27
+#: builtin/blame.c:29
 msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
 msgstr ""
 
-#: builtin/blame.c:32
+#: builtin/blame.c:34
 msgid "<rev-opts> are documented in git-rev-list(1)"
 msgstr ""
 
-#: builtin/blame.c:677
+#: builtin/blame.c:404
+#, c-format
+msgid "expecting a color: %s"
+msgstr ""
+
+#: builtin/blame.c:411
+msgid "must end with a color"
+msgstr ""
+
+#: builtin/blame.c:697
+#, c-format
+msgid "invalid color '%s' in color.blame.repeatedLines"
+msgstr ""
+
+#: builtin/blame.c:715
+msgid "invalid value for blame.coloring"
+msgstr ""
+
+#: builtin/blame.c:786
 msgid "Show blame entries as we find them, incrementally"
 msgstr ""
 
-#: builtin/blame.c:678
+#: builtin/blame.c:787
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:679
+#: builtin/blame.c:788
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:680
+#: builtin/blame.c:789
 msgid "Show work cost statistics"
 msgstr ""
 
-#: builtin/blame.c:681
+#: builtin/blame.c:790
 msgid "Force progress reporting"
 msgstr ""
 
-#: builtin/blame.c:682
+#: builtin/blame.c:791
 msgid "Show output score for blame entries"
 msgstr ""
 
-#: builtin/blame.c:683
+#: builtin/blame.c:792
 msgid "Show original filename (Default: auto)"
 msgstr ""
 
-#: builtin/blame.c:684
+#: builtin/blame.c:793
 msgid "Show original linenumber (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:685
+#: builtin/blame.c:794
 msgid "Show in a format designed for machine consumption"
 msgstr ""
 
-#: builtin/blame.c:686
+#: builtin/blame.c:795
 msgid "Show porcelain format with per-line commit information"
 msgstr ""
 
-#: builtin/blame.c:687
+#: builtin/blame.c:796
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:688
+#: builtin/blame.c:797
 msgid "Show raw timestamp (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:689
+#: builtin/blame.c:798
 msgid "Show long commit SHA1 (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:690
+#: builtin/blame.c:799
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:691
+#: builtin/blame.c:800
 msgid "Show author email instead of name (Default: off)"
 msgstr ""
 
-#: builtin/blame.c:692
+#: builtin/blame.c:801
 msgid "Ignore whitespace differences"
 msgstr ""
 
-#: builtin/blame.c:699
+#: builtin/blame.c:802
+msgid "color redundant metadata from previous line differently"
+msgstr ""
+
+#: builtin/blame.c:803
+msgid "color lines by age"
+msgstr ""
+
+#: builtin/blame.c:810
 msgid "Use an experimental heuristic to improve diffs"
 msgstr ""
 
-#: builtin/blame.c:701
+#: builtin/blame.c:812
 msgid "Spend extra cycles to find better match"
 msgstr ""
 
-#: builtin/blame.c:702
+#: builtin/blame.c:813
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr ""
 
-#: builtin/blame.c:703
+#: builtin/blame.c:814
 msgid "Use <file>'s contents as the final image"
 msgstr ""
 
-#: builtin/blame.c:704 builtin/blame.c:705
+#: builtin/blame.c:815 builtin/blame.c:816
 msgid "score"
 msgstr ""
 
-#: builtin/blame.c:704
+#: builtin/blame.c:815
 msgid "Find line copies within and across files"
 msgstr ""
 
-#: builtin/blame.c:705
+#: builtin/blame.c:816
 msgid "Find line movements within and across files"
 msgstr ""
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "n,m"
 msgstr ""
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "Process only line range n,m, counting from 1"
 msgstr ""
 
-#: builtin/blame.c:753
+#: builtin/blame.c:866
 msgid "--progress can't be used with --incremental or porcelain formats"
 msgstr ""
 
@@ -5376,18 +5726,18 @@ msgstr ""
 #. your language may need more or fewer display
 #. columns.
 #.
-#: builtin/blame.c:804
+#: builtin/blame.c:917
 msgid "4 years, 11 months ago"
 msgstr ""
 
-#: builtin/blame.c:890
+#: builtin/blame.c:1003
 #, c-format
 msgid "file %s has only %lu line"
 msgid_plural "file %s has only %lu lines"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/blame.c:936
+#: builtin/blame.c:1049
 msgid "Blaming lines"
 msgstr ""
 
@@ -5492,65 +5842,65 @@ msgstr ""
 msgid "Deleted branch %s (was %s).\n"
 msgstr ""
 
-#: builtin/branch.c:417 builtin/tag.c:58
+#: builtin/branch.c:416 builtin/tag.c:58
 msgid "unable to parse format string"
 msgstr ""
 
-#: builtin/branch.c:450
+#: builtin/branch.c:453
 #, c-format
 msgid "Branch %s is being rebased at %s"
 msgstr ""
 
-#: builtin/branch.c:454
+#: builtin/branch.c:457
 #, c-format
 msgid "Branch %s is being bisected at %s"
 msgstr ""
 
-#: builtin/branch.c:471
+#: builtin/branch.c:474
 msgid "cannot copy the current branch while not on any."
 msgstr ""
 
-#: builtin/branch.c:473
+#: builtin/branch.c:476
 msgid "cannot rename the current branch while not on any."
 msgstr ""
 
-#: builtin/branch.c:484
+#: builtin/branch.c:487
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr ""
 
-#: builtin/branch.c:511
+#: builtin/branch.c:514
 msgid "Branch rename failed"
 msgstr ""
 
-#: builtin/branch.c:513
+#: builtin/branch.c:516
 msgid "Branch copy failed"
 msgstr ""
 
-#: builtin/branch.c:517
+#: builtin/branch.c:520
 #, c-format
 msgid "Created a copy of a misnamed branch '%s'"
 msgstr ""
 
-#: builtin/branch.c:520
+#: builtin/branch.c:523
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr ""
 
-#: builtin/branch.c:526
+#: builtin/branch.c:529
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr ""
 
-#: builtin/branch.c:535
+#: builtin/branch.c:538
 msgid "Branch is renamed, but update of config-file failed"
 msgstr ""
 
-#: builtin/branch.c:537
+#: builtin/branch.c:540
 msgid "Branch is copied, but update of config-file failed"
 msgstr ""
 
-#: builtin/branch.c:553
+#: builtin/branch.c:556
 #, c-format
 msgid ""
 "Please edit the description for the branch\n"
@@ -5558,217 +5908,219 @@ msgid ""
 "Lines starting with '%c' will be stripped.\n"
 msgstr ""
 
-#: builtin/branch.c:586
+#: builtin/branch.c:589
 msgid "Generic options"
 msgstr ""
 
-#: builtin/branch.c:588
+#: builtin/branch.c:591
 msgid "show hash and subject, give twice for upstream branch"
 msgstr ""
 
-#: builtin/branch.c:589
+#: builtin/branch.c:592
 msgid "suppress informational messages"
 msgstr ""
 
-#: builtin/branch.c:590
+#: builtin/branch.c:593
 msgid "set up tracking mode (see git-pull(1))"
 msgstr ""
 
-#: builtin/branch.c:592
+#: builtin/branch.c:595
 msgid "do not use"
 msgstr ""
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "upstream"
 msgstr ""
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "change the upstream info"
 msgstr ""
 
-#: builtin/branch.c:595
+#: builtin/branch.c:598
 msgid "Unset the upstream info"
 msgstr ""
 
-#: builtin/branch.c:596
+#: builtin/branch.c:599
 msgid "use colored output"
 msgstr ""
 
-#: builtin/branch.c:597
+#: builtin/branch.c:600
 msgid "act on remote-tracking branches"
 msgstr ""
 
-#: builtin/branch.c:599 builtin/branch.c:601
+#: builtin/branch.c:602 builtin/branch.c:604
 msgid "print only branches that contain the commit"
 msgstr ""
 
-#: builtin/branch.c:600 builtin/branch.c:602
+#: builtin/branch.c:603 builtin/branch.c:605
 msgid "print only branches that don't contain the commit"
 msgstr ""
 
-#: builtin/branch.c:605
+#: builtin/branch.c:608
 msgid "Specific git-branch actions:"
 msgstr ""
 
-#: builtin/branch.c:606
+#: builtin/branch.c:609
 msgid "list both remote-tracking and local branches"
 msgstr ""
 
-#: builtin/branch.c:608
+#: builtin/branch.c:611
 msgid "delete fully merged branch"
 msgstr ""
 
-#: builtin/branch.c:609
+#: builtin/branch.c:612
 msgid "delete branch (even if not merged)"
 msgstr ""
 
-#: builtin/branch.c:610
+#: builtin/branch.c:613
 msgid "move/rename a branch and its reflog"
 msgstr ""
 
-#: builtin/branch.c:611
+#: builtin/branch.c:614
 msgid "move/rename a branch, even if target exists"
 msgstr ""
 
-#: builtin/branch.c:612
+#: builtin/branch.c:615
 msgid "copy a branch and its reflog"
 msgstr ""
 
-#: builtin/branch.c:613
+#: builtin/branch.c:616
 msgid "copy a branch, even if target exists"
 msgstr ""
 
-#: builtin/branch.c:614
+#: builtin/branch.c:617
 msgid "list branch names"
 msgstr ""
 
-#: builtin/branch.c:615
+#: builtin/branch.c:618
 msgid "create the branch's reflog"
 msgstr ""
 
-#: builtin/branch.c:617
+#: builtin/branch.c:620
 msgid "edit the description for the branch"
 msgstr ""
 
-#: builtin/branch.c:618
+#: builtin/branch.c:621
 msgid "force creation, move/rename, deletion"
 msgstr ""
 
-#: builtin/branch.c:619
+#: builtin/branch.c:622
 msgid "print only branches that are merged"
 msgstr ""
 
-#: builtin/branch.c:620
+#: builtin/branch.c:623
 msgid "print only branches that are not merged"
 msgstr ""
 
-#: builtin/branch.c:621
+#: builtin/branch.c:624
 msgid "list branches in columns"
 msgstr ""
 
-#: builtin/branch.c:622 builtin/for-each-ref.c:40 builtin/tag.c:411
+#: builtin/branch.c:625 builtin/for-each-ref.c:40 builtin/ls-remote.c:70
+#: builtin/tag.c:412
 msgid "key"
 msgstr ""
 
-#: builtin/branch.c:623 builtin/for-each-ref.c:41 builtin/tag.c:412
+#: builtin/branch.c:626 builtin/for-each-ref.c:41 builtin/ls-remote.c:71
+#: builtin/tag.c:413
 msgid "field name to sort on"
 msgstr ""
 
-#: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408
+#: builtin/branch.c:628 builtin/for-each-ref.c:43 builtin/notes.c:408
 #: builtin/notes.c:411 builtin/notes.c:571 builtin/notes.c:574
-#: builtin/tag.c:414
+#: builtin/tag.c:415
 msgid "object"
 msgstr ""
 
-#: builtin/branch.c:626
+#: builtin/branch.c:629
 msgid "print only branches of the object"
 msgstr ""
 
-#: builtin/branch.c:628 builtin/for-each-ref.c:49 builtin/tag.c:421
+#: builtin/branch.c:631 builtin/for-each-ref.c:49 builtin/tag.c:422
 msgid "sorting and filtering are case insensitive"
 msgstr ""
 
-#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419
+#: builtin/branch.c:632 builtin/for-each-ref.c:38 builtin/tag.c:420
 #: builtin/verify-tag.c:39
 msgid "format to use for the output"
 msgstr ""
 
-#: builtin/branch.c:652 builtin/clone.c:735
+#: builtin/branch.c:655 builtin/clone.c:737
 msgid "HEAD not found below refs/heads!"
 msgstr ""
 
-#: builtin/branch.c:675
+#: builtin/branch.c:678
 msgid "--column and --verbose are incompatible"
 msgstr ""
 
-#: builtin/branch.c:690 builtin/branch.c:742 builtin/branch.c:751
+#: builtin/branch.c:693 builtin/branch.c:745 builtin/branch.c:754
 msgid "branch name required"
 msgstr ""
 
-#: builtin/branch.c:718
+#: builtin/branch.c:721
 msgid "Cannot give description to detached HEAD"
 msgstr ""
 
-#: builtin/branch.c:723
+#: builtin/branch.c:726
 msgid "cannot edit description of more than one branch"
 msgstr ""
 
-#: builtin/branch.c:730
+#: builtin/branch.c:733
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr ""
 
-#: builtin/branch.c:733
+#: builtin/branch.c:736
 #, c-format
 msgid "No branch named '%s'."
 msgstr ""
 
-#: builtin/branch.c:748
+#: builtin/branch.c:751
 msgid "too many branches for a copy operation"
 msgstr ""
 
-#: builtin/branch.c:757
+#: builtin/branch.c:760
 msgid "too many arguments for a rename operation"
 msgstr ""
 
-#: builtin/branch.c:762
+#: builtin/branch.c:765
 msgid "too many arguments to set new upstream"
 msgstr ""
 
-#: builtin/branch.c:766
+#: builtin/branch.c:769
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
 msgstr ""
 
-#: builtin/branch.c:769 builtin/branch.c:791 builtin/branch.c:807
+#: builtin/branch.c:772 builtin/branch.c:794 builtin/branch.c:810
 #, c-format
 msgid "no such branch '%s'"
 msgstr ""
 
-#: builtin/branch.c:773
+#: builtin/branch.c:776
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr ""
 
-#: builtin/branch.c:785
+#: builtin/branch.c:788
 msgid "too many arguments to unset upstream"
 msgstr ""
 
-#: builtin/branch.c:789
+#: builtin/branch.c:792
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
 
-#: builtin/branch.c:795
+#: builtin/branch.c:798
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr ""
 
-#: builtin/branch.c:810
+#: builtin/branch.c:813
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr ""
 
-#: builtin/branch.c:813
+#: builtin/branch.c:816
 msgid ""
 "the '--set-upstream' option is no longer supported. Please use '--track' or "
 "'--set-upstream-to' instead."
@@ -5787,75 +6139,75 @@ msgstr ""
 msgid "Need a repository to unbundle."
 msgstr ""
 
-#: builtin/cat-file.c:523
+#: builtin/cat-file.c:525
 msgid ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <type> | --textconv | --filters) [--path=<path>] <object>"
 msgstr ""
 
-#: builtin/cat-file.c:524
+#: builtin/cat-file.c:526
 msgid ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
 msgstr ""
 
-#: builtin/cat-file.c:561
+#: builtin/cat-file.c:563
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr ""
 
-#: builtin/cat-file.c:562
+#: builtin/cat-file.c:564
 msgid "show object type"
 msgstr ""
 
-#: builtin/cat-file.c:563
+#: builtin/cat-file.c:565
 msgid "show object size"
 msgstr ""
 
-#: builtin/cat-file.c:565
+#: builtin/cat-file.c:567
 msgid "exit with zero when there's no error"
 msgstr ""
 
-#: builtin/cat-file.c:566
+#: builtin/cat-file.c:568
 msgid "pretty-print object's content"
 msgstr ""
 
-#: builtin/cat-file.c:568
+#: builtin/cat-file.c:570
 msgid "for blob objects, run textconv on object's content"
 msgstr ""
 
-#: builtin/cat-file.c:570
+#: builtin/cat-file.c:572
 msgid "for blob objects, run filters on object's content"
 msgstr ""
 
-#: builtin/cat-file.c:571 git-submodule.sh:878
+#: builtin/cat-file.c:573 git-submodule.sh:894
 msgid "blob"
 msgstr ""
 
-#: builtin/cat-file.c:572
+#: builtin/cat-file.c:574
 msgid "use a specific path for --textconv/--filters"
 msgstr ""
 
-#: builtin/cat-file.c:574
+#: builtin/cat-file.c:576
 msgid "allow -s and -t to work with broken/corrupt objects"
 msgstr ""
 
-#: builtin/cat-file.c:575
+#: builtin/cat-file.c:577
 msgid "buffer --batch output"
 msgstr ""
 
-#: builtin/cat-file.c:577
+#: builtin/cat-file.c:579
 msgid "show info and content of objects fed from the standard input"
 msgstr ""
 
-#: builtin/cat-file.c:580
+#: builtin/cat-file.c:582
 msgid "show info about objects fed from the standard input"
 msgstr ""
 
-#: builtin/cat-file.c:583
+#: builtin/cat-file.c:585
 msgid "follow in-tree symlinks (used with --batch or --batch-check)"
 msgstr ""
 
-#: builtin/cat-file.c:585
+#: builtin/cat-file.c:587
 msgid "show all objects with --batch or --batch-check"
 msgstr ""
 
@@ -5883,7 +6235,7 @@ msgstr ""
 msgid "terminate input and output records by a NUL character"
 msgstr ""
 
-#: builtin/check-ignore.c:20 builtin/checkout.c:1106 builtin/gc.c:358
+#: builtin/check-ignore.c:20 builtin/checkout.c:1113 builtin/gc.c:500
 msgid "suppress progress reporting"
 msgstr ""
 
@@ -5973,9 +6325,9 @@ msgid "write the content to temporary files"
 msgstr ""
 
 #: builtin/checkout-index.c:173 builtin/column.c:31
-#: builtin/submodule--helper.c:1203 builtin/submodule--helper.c:1206
-#: builtin/submodule--helper.c:1212 builtin/submodule--helper.c:1574
-#: builtin/worktree.c:570
+#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1219
+#: builtin/submodule--helper.c:1227 builtin/submodule--helper.c:1591
+#: builtin/worktree.c:610
 msgid "string"
 msgstr ""
 
@@ -6046,54 +6398,54 @@ msgstr ""
 msgid "path '%s' is unmerged"
 msgstr ""
 
-#: builtin/checkout.c:505
+#: builtin/checkout.c:506
 msgid "you need to resolve your current index first"
 msgstr ""
 
-#: builtin/checkout.c:636
+#: builtin/checkout.c:643
 #, c-format
 msgid "Can not do reflog for '%s': %s\n"
 msgstr ""
 
-#: builtin/checkout.c:677
+#: builtin/checkout.c:684
 msgid "HEAD is now at"
 msgstr ""
 
-#: builtin/checkout.c:681 builtin/clone.c:689
+#: builtin/checkout.c:688 builtin/clone.c:691
 msgid "unable to update HEAD"
 msgstr ""
 
-#: builtin/checkout.c:685
+#: builtin/checkout.c:692
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:688
+#: builtin/checkout.c:695
 #, c-format
 msgid "Already on '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:692
+#: builtin/checkout.c:699
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:694 builtin/checkout.c:1039
+#: builtin/checkout.c:701 builtin/checkout.c:1046
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:696
+#: builtin/checkout.c:703
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr ""
 
-#: builtin/checkout.c:747
+#: builtin/checkout.c:754
 #, c-format
 msgid " ... and %d more.\n"
 msgstr ""
 
-#: builtin/checkout.c:753
+#: builtin/checkout.c:760
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -6108,7 +6460,7 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/checkout.c:772
+#: builtin/checkout.c:779
 #, c-format
 msgid ""
 "If you want to keep it by creating a new branch, this may be a good time\n"
@@ -6125,160 +6477,160 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/checkout.c:804
+#: builtin/checkout.c:811
 msgid "internal error in revision walk"
 msgstr ""
 
-#: builtin/checkout.c:808
+#: builtin/checkout.c:815
 msgid "Previous HEAD position was"
 msgstr ""
 
-#: builtin/checkout.c:836 builtin/checkout.c:1034
+#: builtin/checkout.c:843 builtin/checkout.c:1041
 msgid "You are on a branch yet to be born"
 msgstr ""
 
-#: builtin/checkout.c:940
+#: builtin/checkout.c:947
 #, c-format
 msgid "only one reference expected, %d given."
 msgstr ""
 
-#: builtin/checkout.c:980 builtin/worktree.c:249
+#: builtin/checkout.c:987 builtin/worktree.c:240 builtin/worktree.c:389
 #, c-format
 msgid "invalid reference: %s"
 msgstr ""
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1016
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr ""
 
-#: builtin/checkout.c:1048
+#: builtin/checkout.c:1055
 msgid "paths cannot be used with switching branches"
 msgstr ""
 
-#: builtin/checkout.c:1051 builtin/checkout.c:1055
+#: builtin/checkout.c:1058 builtin/checkout.c:1062
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr ""
 
-#: builtin/checkout.c:1059 builtin/checkout.c:1062 builtin/checkout.c:1067
-#: builtin/checkout.c:1070
+#: builtin/checkout.c:1066 builtin/checkout.c:1069 builtin/checkout.c:1074
+#: builtin/checkout.c:1077
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr ""
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1082
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr ""
 
-#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116
-#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:387
-#: builtin/worktree.c:389
+#: builtin/checkout.c:1114 builtin/checkout.c:1116 builtin/clone.c:118
+#: builtin/remote.c:167 builtin/remote.c:169 builtin/worktree.c:433
+#: builtin/worktree.c:435
 msgid "branch"
 msgstr ""
 
-#: builtin/checkout.c:1108
+#: builtin/checkout.c:1115
 msgid "create and checkout a new branch"
 msgstr ""
 
-#: builtin/checkout.c:1110
+#: builtin/checkout.c:1117
 msgid "create/reset and checkout a branch"
 msgstr ""
 
-#: builtin/checkout.c:1111
+#: builtin/checkout.c:1118
 msgid "create reflog for new branch"
 msgstr ""
 
-#: builtin/checkout.c:1112 builtin/worktree.c:391
+#: builtin/checkout.c:1119 builtin/worktree.c:437
 msgid "detach HEAD at named commit"
 msgstr ""
 
-#: builtin/checkout.c:1113
+#: builtin/checkout.c:1120
 msgid "set upstream info for new branch"
 msgstr ""
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new-branch"
 msgstr ""
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new unparented branch"
 msgstr ""
 
-#: builtin/checkout.c:1116
+#: builtin/checkout.c:1123
 msgid "checkout our version for unmerged files"
 msgstr ""
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1125
 msgid "checkout their version for unmerged files"
 msgstr ""
 
-#: builtin/checkout.c:1120
+#: builtin/checkout.c:1127
 msgid "force checkout (throw away local modifications)"
 msgstr ""
 
-#: builtin/checkout.c:1122
+#: builtin/checkout.c:1129
 msgid "perform a 3-way merge with the new branch"
 msgstr ""
 
-#: builtin/checkout.c:1124 builtin/merge.c:239
+#: builtin/checkout.c:1131 builtin/merge.c:241
 msgid "update ignored files (default)"
 msgstr ""
 
-#: builtin/checkout.c:1126 builtin/log.c:1499 parse-options.h:263
+#: builtin/checkout.c:1133 builtin/log.c:1499 parse-options.h:264
 msgid "style"
 msgstr ""
 
-#: builtin/checkout.c:1127
+#: builtin/checkout.c:1134
 msgid "conflict style (merge or diff3)"
 msgstr ""
 
-#: builtin/checkout.c:1130
+#: builtin/checkout.c:1137
 msgid "do not limit pathspecs to sparse entries only"
 msgstr ""
 
-#: builtin/checkout.c:1132
+#: builtin/checkout.c:1139
 msgid "second guess 'git checkout <no-such-branch>'"
 msgstr ""
 
-#: builtin/checkout.c:1134
+#: builtin/checkout.c:1141
 msgid "do not check if another worktree is holding the given ref"
 msgstr ""
 
-#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150
-#: builtin/merge.c:236 builtin/pull.c:123 builtin/push.c:556
-#: builtin/send-pack.c:173
+#: builtin/checkout.c:1145 builtin/clone.c:85 builtin/fetch.c:149
+#: builtin/merge.c:238 builtin/pull.c:128 builtin/push.c:572
+#: builtin/send-pack.c:174
 msgid "force progress reporting"
 msgstr ""
 
-#: builtin/checkout.c:1168
+#: builtin/checkout.c:1175
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr ""
 
-#: builtin/checkout.c:1185
+#: builtin/checkout.c:1192
 msgid "--track needs a branch name"
 msgstr ""
 
-#: builtin/checkout.c:1190
+#: builtin/checkout.c:1197
 msgid "Missing branch name; try -b"
 msgstr ""
 
-#: builtin/checkout.c:1226
+#: builtin/checkout.c:1233
 msgid "invalid path specification"
 msgstr ""
 
-#: builtin/checkout.c:1233
+#: builtin/checkout.c:1240
 #, c-format
 msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
 msgstr ""
 
-#: builtin/checkout.c:1237
+#: builtin/checkout.c:1244
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr ""
 
-#: builtin/checkout.c:1241
+#: builtin/checkout.c:1248
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -6314,7 +6666,7 @@ msgstr ""
 msgid "failed to remove %s"
 msgstr ""
 
-#: builtin/clean.c:302 git-add--interactive.perl:572
+#: builtin/clean.c:302 git-add--interactive.perl:579
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6323,7 +6675,7 @@ msgid ""
 "           - (empty) select nothing\n"
 msgstr ""
 
-#: builtin/clean.c:306 git-add--interactive.perl:581
+#: builtin/clean.c:306 git-add--interactive.perl:588
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6336,8 +6688,8 @@ msgid ""
 "           - (empty) finish selecting\n"
 msgstr ""
 
-#: builtin/clean.c:522 git-add--interactive.perl:547
-#: git-add--interactive.perl:552
+#: builtin/clean.c:522 git-add--interactive.perl:554
+#: git-add--interactive.perl:559
 #, c-format, perl-format
 msgid "Huh (%s)?\n"
 msgstr ""
@@ -6362,7 +6714,7 @@ msgstr ""
 msgid "Remove %s [y/N]? "
 msgstr ""
 
-#: builtin/clean.c:788 git-add--interactive.perl:1710
+#: builtin/clean.c:788 git-add--interactive.perl:1717
 #, c-format
 msgid "Bye.\n"
 msgstr ""
@@ -6378,11 +6730,11 @@ msgid ""
 "?                   - help for prompt selection"
 msgstr ""
 
-#: builtin/clean.c:823 git-add--interactive.perl:1786
+#: builtin/clean.c:823 git-add--interactive.perl:1793
 msgid "*** Commands ***"
 msgstr ""
 
-#: builtin/clean.c:824 git-add--interactive.perl:1783
+#: builtin/clean.c:824 git-add--interactive.perl:1790
 msgid "What now"
 msgstr ""
 
@@ -6447,284 +6799,286 @@ msgid ""
 "refusing to clean"
 msgstr ""
 
-#: builtin/clone.c:40
+#: builtin/clone.c:42
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr ""
 
-#: builtin/clone.c:85
+#: builtin/clone.c:87
 msgid "don't create a checkout"
 msgstr ""
 
-#: builtin/clone.c:86 builtin/clone.c:88 builtin/init-db.c:479
+#: builtin/clone.c:88 builtin/clone.c:90 builtin/init-db.c:479
 msgid "create a bare repository"
 msgstr ""
 
-#: builtin/clone.c:90
+#: builtin/clone.c:92
 msgid "create a mirror repository (implies bare)"
 msgstr ""
 
-#: builtin/clone.c:92
+#: builtin/clone.c:94
 msgid "to clone from a local repository"
 msgstr ""
 
-#: builtin/clone.c:94
+#: builtin/clone.c:96
 msgid "don't use local hardlinks, always copy"
 msgstr ""
 
-#: builtin/clone.c:96
+#: builtin/clone.c:98
 msgid "setup as shared repository"
 msgstr ""
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "pathspec"
 msgstr ""
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "initialize submodules in the clone"
 msgstr ""
 
-#: builtin/clone.c:105
+#: builtin/clone.c:107
 msgid "number of submodules cloned in parallel"
 msgstr ""
 
-#: builtin/clone.c:106 builtin/init-db.c:476
+#: builtin/clone.c:108 builtin/init-db.c:476
 msgid "template-directory"
 msgstr ""
 
-#: builtin/clone.c:107 builtin/init-db.c:477
+#: builtin/clone.c:109 builtin/init-db.c:477
 msgid "directory from which templates will be used"
 msgstr ""
 
-#: builtin/clone.c:109 builtin/clone.c:111 builtin/submodule--helper.c:1210
-#: builtin/submodule--helper.c:1577
+#: builtin/clone.c:111 builtin/clone.c:113 builtin/submodule--helper.c:1223
+#: builtin/submodule--helper.c:1594
 msgid "reference repository"
 msgstr ""
 
-#: builtin/clone.c:113
+#: builtin/clone.c:115 builtin/submodule--helper.c:1225
+#: builtin/submodule--helper.c:1596
 msgid "use --reference only while cloning"
 msgstr ""
 
-#: builtin/clone.c:114 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/clone.c:116 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/pack-objects.c:3166 builtin/repack.c:213
 msgid "name"
 msgstr ""
 
-#: builtin/clone.c:115
+#: builtin/clone.c:117
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr ""
 
-#: builtin/clone.c:117
+#: builtin/clone.c:119
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr ""
 
-#: builtin/clone.c:119
+#: builtin/clone.c:121
 msgid "path to git-upload-pack on the remote"
 msgstr ""
 
-#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813
-#: builtin/pull.c:211
+#: builtin/clone.c:122 builtin/fetch.c:150 builtin/grep.c:813
+#: builtin/pull.c:216
 msgid "depth"
 msgstr ""
 
-#: builtin/clone.c:121
+#: builtin/clone.c:123
 msgid "create a shallow clone of that depth"
 msgstr ""
 
-#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017
+#: builtin/clone.c:124 builtin/fetch.c:152 builtin/pack-objects.c:3157
 #: parse-options.h:154
 msgid "time"
 msgstr ""
 
-#: builtin/clone.c:123
+#: builtin/clone.c:125
 msgid "create a shallow clone since a specific time"
 msgstr ""
 
-#: builtin/clone.c:124 builtin/fetch.c:155
+#: builtin/clone.c:126 builtin/fetch.c:154
 msgid "revision"
 msgstr ""
 
-#: builtin/clone.c:125 builtin/fetch.c:156
+#: builtin/clone.c:127 builtin/fetch.c:155
 msgid "deepen history of shallow clone, excluding rev"
 msgstr ""
 
-#: builtin/clone.c:127
+#: builtin/clone.c:129
 msgid "clone only one branch, HEAD or --branch"
 msgstr ""
 
-#: builtin/clone.c:129
+#: builtin/clone.c:131
 msgid "don't clone any tags, and make later fetches not to follow them"
 msgstr ""
 
-#: builtin/clone.c:131
+#: builtin/clone.c:133
 msgid "any cloned submodules will be shallow"
 msgstr ""
 
-#: builtin/clone.c:132 builtin/init-db.c:485
+#: builtin/clone.c:134 builtin/init-db.c:485
 msgid "gitdir"
 msgstr ""
 
-#: builtin/clone.c:133 builtin/init-db.c:486
+#: builtin/clone.c:135 builtin/init-db.c:486
 msgid "separate git dir from working tree"
 msgstr ""
 
-#: builtin/clone.c:134
+#: builtin/clone.c:136
 msgid "key=value"
 msgstr ""
 
-#: builtin/clone.c:135
+#: builtin/clone.c:137
 msgid "set config inside the new repository"
 msgstr ""
 
-#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224
-#: builtin/push.c:567
+#: builtin/clone.c:138 builtin/fetch.c:173 builtin/pull.c:229
+#: builtin/push.c:583
 msgid "use IPv4 addresses only"
 msgstr ""
 
-#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227
-#: builtin/push.c:569
+#: builtin/clone.c:140 builtin/fetch.c:175 builtin/pull.c:232
+#: builtin/push.c:585
 msgid "use IPv6 addresses only"
 msgstr ""
 
-#: builtin/clone.c:276
+#: builtin/clone.c:278
 msgid ""
 "No directory name could be guessed.\n"
 "Please specify a directory on the command line"
 msgstr ""
 
-#: builtin/clone.c:329
+#: builtin/clone.c:331
 #, c-format
 msgid "info: Could not add alternate for '%s': %s\n"
 msgstr ""
 
-#: builtin/clone.c:401
+#: builtin/clone.c:403
 #, c-format
 msgid "failed to open '%s'"
 msgstr ""
 
-#: builtin/clone.c:409
+#: builtin/clone.c:411
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr ""
 
-#: builtin/clone.c:423
+#: builtin/clone.c:425
 #, c-format
 msgid "failed to stat %s\n"
 msgstr ""
 
-#: builtin/clone.c:445
+#: builtin/clone.c:447
 #, c-format
 msgid "failed to create link '%s'"
 msgstr ""
 
-#: builtin/clone.c:449
+#: builtin/clone.c:451
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr ""
 
-#: builtin/clone.c:475
+#: builtin/clone.c:477
 #, c-format
 msgid "done.\n"
 msgstr ""
 
-#: builtin/clone.c:489
+#: builtin/clone.c:491
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
 "and retry the checkout with 'git checkout -f HEAD'\n"
 msgstr ""
 
-#: builtin/clone.c:566
+#: builtin/clone.c:568
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr ""
 
-#: builtin/clone.c:661
+#: builtin/clone.c:663
 msgid "remote did not send all necessary objects"
 msgstr ""
 
-#: builtin/clone.c:677
+#: builtin/clone.c:679
 #, c-format
 msgid "unable to update %s"
 msgstr ""
 
-#: builtin/clone.c:726
+#: builtin/clone.c:728
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
 
-#: builtin/clone.c:756
+#: builtin/clone.c:758
 msgid "unable to checkout working tree"
 msgstr ""
 
-#: builtin/clone.c:801
+#: builtin/clone.c:803
 msgid "unable to write parameters to config file"
 msgstr ""
 
-#: builtin/clone.c:864
+#: builtin/clone.c:866
 msgid "cannot repack to clean up"
 msgstr ""
 
-#: builtin/clone.c:866
+#: builtin/clone.c:868
 msgid "cannot unlink temporary alternates file"
 msgstr ""
 
-#: builtin/clone.c:906 builtin/receive-pack.c:1946
+#: builtin/clone.c:907 builtin/receive-pack.c:1947
 msgid "Too many arguments."
 msgstr ""
 
-#: builtin/clone.c:910
+#: builtin/clone.c:911
 msgid "You must specify a repository to clone."
 msgstr ""
 
-#: builtin/clone.c:923
+#: builtin/clone.c:924
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr ""
 
-#: builtin/clone.c:926
+#: builtin/clone.c:927
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr ""
 
-#: builtin/clone.c:939
+#: builtin/clone.c:940
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr ""
 
-#: builtin/clone.c:945 builtin/fetch.c:1455
+#: builtin/clone.c:946 builtin/fetch.c:1460
 #, c-format
 msgid "depth %s is not a positive number"
 msgstr ""
 
-#: builtin/clone.c:955
+#: builtin/clone.c:956
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr ""
 
-#: builtin/clone.c:965
+#: builtin/clone.c:966
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr ""
 
-#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270
-#: builtin/worktree.c:255 builtin/worktree.c:285
+#: builtin/clone.c:981 builtin/clone.c:1002 builtin/difftool.c:270
+#: builtin/worktree.c:246 builtin/worktree.c:276
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr ""
 
-#: builtin/clone.c:985
+#: builtin/clone.c:986
 #, c-format
 msgid "could not create work tree dir '%s'"
 msgstr ""
 
-#: builtin/clone.c:1005
+#: builtin/clone.c:1006
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr ""
 
-#: builtin/clone.c:1007
+#: builtin/clone.c:1008
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr ""
 
-#: builtin/clone.c:1031
+#: builtin/clone.c:1032
 msgid ""
 "clone --recursive is not compatible with both --reference and --reference-if-"
 "able"
@@ -6791,7 +7145,7 @@ msgstr ""
 msgid "Padding space between columns"
 msgstr ""
 
-#: builtin/column.c:52
+#: builtin/column.c:51
 msgid "--command must be the first argument"
 msgstr ""
 
@@ -6833,98 +7187,98 @@ msgid ""
 "the remaining commits.\n"
 msgstr ""
 
-#: builtin/commit.c:284
+#: builtin/commit.c:293
 msgid "failed to unpack HEAD tree object"
 msgstr ""
 
-#: builtin/commit.c:325
+#: builtin/commit.c:334
 msgid "unable to create temporary index"
 msgstr ""
 
-#: builtin/commit.c:331
+#: builtin/commit.c:340
 msgid "interactive add failed"
 msgstr ""
 
-#: builtin/commit.c:344
+#: builtin/commit.c:353
 msgid "unable to update temporary index"
 msgstr ""
 
-#: builtin/commit.c:346
+#: builtin/commit.c:355
 msgid "Failed to update main cache tree"
 msgstr ""
 
-#: builtin/commit.c:371 builtin/commit.c:395 builtin/commit.c:444
+#: builtin/commit.c:380 builtin/commit.c:403 builtin/commit.c:449
 msgid "unable to write new_index file"
 msgstr ""
 
-#: builtin/commit.c:427
+#: builtin/commit.c:432
 msgid "cannot do a partial commit during a merge."
 msgstr ""
 
-#: builtin/commit.c:429
+#: builtin/commit.c:434
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr ""
 
-#: builtin/commit.c:437
+#: builtin/commit.c:442
 msgid "cannot read the index"
 msgstr ""
 
-#: builtin/commit.c:456
+#: builtin/commit.c:461
 msgid "unable to write temporary index file"
 msgstr ""
 
-#: builtin/commit.c:553
+#: builtin/commit.c:558
 #, c-format
 msgid "commit '%s' lacks author header"
 msgstr ""
 
-#: builtin/commit.c:555
+#: builtin/commit.c:560
 #, c-format
 msgid "commit '%s' has malformed author line"
 msgstr ""
 
-#: builtin/commit.c:574
+#: builtin/commit.c:579
 msgid "malformed --author parameter"
 msgstr ""
 
-#: builtin/commit.c:626
+#: builtin/commit.c:631
 msgid ""
 "unable to select a comment character that is not used\n"
 "in the current commit message"
 msgstr ""
 
-#: builtin/commit.c:663 builtin/commit.c:696 builtin/commit.c:1024
+#: builtin/commit.c:668 builtin/commit.c:701 builtin/commit.c:1029
 #, c-format
 msgid "could not lookup commit %s"
 msgstr ""
 
-#: builtin/commit.c:675 builtin/shortlog.c:309
+#: builtin/commit.c:680 builtin/shortlog.c:316
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr ""
 
-#: builtin/commit.c:677
+#: builtin/commit.c:682
 msgid "could not read log from standard input"
 msgstr ""
 
-#: builtin/commit.c:681
+#: builtin/commit.c:686
 #, c-format
 msgid "could not read log file '%s'"
 msgstr ""
 
-#: builtin/commit.c:710 builtin/commit.c:718
+#: builtin/commit.c:715 builtin/commit.c:723
 msgid "could not read SQUASH_MSG"
 msgstr ""
 
-#: builtin/commit.c:715
+#: builtin/commit.c:720
 msgid "could not read MERGE_MSG"
 msgstr ""
 
-#: builtin/commit.c:769
+#: builtin/commit.c:774
 msgid "could not write commit template"
 msgstr ""
 
-#: builtin/commit.c:787
+#: builtin/commit.c:792
 #, c-format
 msgid ""
 "\n"
@@ -6934,7 +7288,7 @@ msgid ""
 "and try again.\n"
 msgstr ""
 
-#: builtin/commit.c:792
+#: builtin/commit.c:797
 #, c-format
 msgid ""
 "\n"
@@ -6944,14 +7298,14 @@ msgid ""
 "and try again.\n"
 msgstr ""
 
-#: builtin/commit.c:805
+#: builtin/commit.c:810
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
 "with '%c' will be ignored, and an empty message aborts the commit.\n"
 msgstr ""
 
-#: builtin/commit.c:813
+#: builtin/commit.c:818
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -6959,484 +7313,554 @@ msgid ""
 "An empty message aborts the commit.\n"
 msgstr ""
 
-#: builtin/commit.c:830
+#: builtin/commit.c:835
 #, c-format
 msgid "%sAuthor:    %.*s <%.*s>"
 msgstr ""
 
-#: builtin/commit.c:838
+#: builtin/commit.c:843
 #, c-format
 msgid "%sDate:      %s"
 msgstr ""
 
-#: builtin/commit.c:845
+#: builtin/commit.c:850
 #, c-format
 msgid "%sCommitter: %.*s <%.*s>"
 msgstr ""
 
-#: builtin/commit.c:862
+#: builtin/commit.c:867
 msgid "Cannot read index"
 msgstr ""
 
-#: builtin/commit.c:928
+#: builtin/commit.c:933
 msgid "Error building trees"
 msgstr ""
 
-#: builtin/commit.c:942 builtin/tag.c:256
+#: builtin/commit.c:947 builtin/tag.c:257
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr ""
 
-#: builtin/commit.c:986
+#: builtin/commit.c:991
 #, c-format
 msgid "--author '%s' is not 'Name <email>' and matches no existing author"
 msgstr ""
 
-#: builtin/commit.c:1000
+#: builtin/commit.c:1005
 #, c-format
 msgid "Invalid ignored mode '%s'"
 msgstr ""
 
-#: builtin/commit.c:1014 builtin/commit.c:1264
+#: builtin/commit.c:1019 builtin/commit.c:1269
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr ""
 
-#: builtin/commit.c:1052
+#: builtin/commit.c:1057
 msgid "--long and -z are incompatible"
 msgstr ""
 
-#: builtin/commit.c:1085
+#: builtin/commit.c:1090
 msgid "Using both --reset-author and --author does not make sense"
 msgstr ""
 
-#: builtin/commit.c:1094
+#: builtin/commit.c:1099
 msgid "You have nothing to amend."
 msgstr ""
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1102
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr ""
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1104
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr ""
 
-#: builtin/commit.c:1102
+#: builtin/commit.c:1107
 msgid "Options --squash and --fixup cannot be used together"
 msgstr ""
 
-#: builtin/commit.c:1112
+#: builtin/commit.c:1117
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr ""
 
-#: builtin/commit.c:1114
+#: builtin/commit.c:1119
 msgid "Option -m cannot be combined with -c/-C/-F."
 msgstr ""
 
-#: builtin/commit.c:1122
+#: builtin/commit.c:1127
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr ""
 
-#: builtin/commit.c:1139
+#: builtin/commit.c:1144
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 
-#: builtin/commit.c:1141
+#: builtin/commit.c:1146
 msgid "No paths with --include/--only does not make sense."
 msgstr ""
 
-#: builtin/commit.c:1155 builtin/tag.c:542
+#: builtin/commit.c:1160 builtin/tag.c:543
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr ""
 
-#: builtin/commit.c:1160
+#: builtin/commit.c:1165
 msgid "Paths with -a does not make sense."
 msgstr ""
 
-#: builtin/commit.c:1278 builtin/commit.c:1443
+#: builtin/commit.c:1303 builtin/commit.c:1480
 msgid "show status concisely"
 msgstr ""
 
-#: builtin/commit.c:1280 builtin/commit.c:1445
+#: builtin/commit.c:1305 builtin/commit.c:1482
 msgid "show branch information"
 msgstr ""
 
-#: builtin/commit.c:1282
+#: builtin/commit.c:1307
 msgid "show stash information"
 msgstr ""
 
-#: builtin/commit.c:1284 builtin/commit.c:1447
+#: builtin/commit.c:1309 builtin/commit.c:1484
 msgid "compute full ahead/behind values"
 msgstr ""
 
-#: builtin/commit.c:1286
+#: builtin/commit.c:1311
 msgid "version"
 msgstr ""
 
-#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542
-#: builtin/worktree.c:541
+#: builtin/commit.c:1311 builtin/commit.c:1486 builtin/push.c:558
+#: builtin/worktree.c:581
 msgid "machine-readable output"
 msgstr ""
 
-#: builtin/commit.c:1289 builtin/commit.c:1451
+#: builtin/commit.c:1314 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr ""
 
-#: builtin/commit.c:1292 builtin/commit.c:1454
+#: builtin/commit.c:1317 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr ""
 
-#: builtin/commit.c:1294 builtin/commit.c:1298 builtin/commit.c:1457
-#: builtin/fast-export.c:999 builtin/fast-export.c:1002 builtin/tag.c:396
+#: builtin/commit.c:1319 builtin/commit.c:1323 builtin/commit.c:1494
+#: builtin/fast-export.c:1001 builtin/fast-export.c:1004 builtin/tag.c:397
 msgid "mode"
 msgstr ""
 
-#: builtin/commit.c:1295 builtin/commit.c:1457
+#: builtin/commit.c:1320 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
 
-#: builtin/commit.c:1299
+#: builtin/commit.c:1324
 msgid ""
 "show ignored files, optional modes: traditional, matching, no. (Default: "
 "traditional)"
 msgstr ""
 
-#: builtin/commit.c:1301 parse-options.h:167
+#: builtin/commit.c:1326 parse-options.h:167
 msgid "when"
 msgstr ""
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1327
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
 msgstr ""
 
-#: builtin/commit.c:1304
+#: builtin/commit.c:1329
 msgid "list untracked files in columns"
 msgstr ""
 
-#: builtin/commit.c:1323
+#: builtin/commit.c:1330
+msgid "do not detect renames"
+msgstr ""
+
+#: builtin/commit.c:1332
+msgid "detect renames, optionally set similarity index"
+msgstr ""
+
+#: builtin/commit.c:1352
 msgid "Unsupported combination of ignored and untracked-files arguments"
 msgstr ""
 
-#: builtin/commit.c:1413
+#: builtin/commit.c:1450
 msgid "suppress summary after successful commit"
 msgstr ""
 
-#: builtin/commit.c:1414
+#: builtin/commit.c:1451
 msgid "show diff in commit message template"
 msgstr ""
 
-#: builtin/commit.c:1416
+#: builtin/commit.c:1453
 msgid "Commit message options"
 msgstr ""
 
-#: builtin/commit.c:1417 builtin/tag.c:393
+#: builtin/commit.c:1454 builtin/tag.c:394
 msgid "read message from file"
 msgstr ""
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "author"
 msgstr ""
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "override author for commit"
 msgstr ""
 
-#: builtin/commit.c:1419 builtin/gc.c:359
+#: builtin/commit.c:1456 builtin/gc.c:501
 msgid "date"
 msgstr ""
 
-#: builtin/commit.c:1419
+#: builtin/commit.c:1456
 msgid "override date for commit"
 msgstr ""
 
-#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402
-#: builtin/notes.c:565 builtin/tag.c:391
+#: builtin/commit.c:1457 builtin/merge.c:228 builtin/notes.c:402
+#: builtin/notes.c:565 builtin/tag.c:392
 msgid "message"
 msgstr ""
 
-#: builtin/commit.c:1420
+#: builtin/commit.c:1457
 msgid "commit message"
 msgstr ""
 
-#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423
-#: builtin/commit.c:1424 parse-options.h:269 ref-filter.h:92
+#: builtin/commit.c:1458 builtin/commit.c:1459 builtin/commit.c:1460
+#: builtin/commit.c:1461 parse-options.h:270 ref-filter.h:92
 msgid "commit"
 msgstr ""
 
-#: builtin/commit.c:1421
+#: builtin/commit.c:1458
 msgid "reuse and edit message from specified commit"
 msgstr ""
 
-#: builtin/commit.c:1422
+#: builtin/commit.c:1459
 msgid "reuse message from specified commit"
 msgstr ""
 
-#: builtin/commit.c:1423
+#: builtin/commit.c:1460
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
 
-#: builtin/commit.c:1424
+#: builtin/commit.c:1461
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1462
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr ""
 
-#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240
-#: builtin/pull.c:149 builtin/revert.c:105
+#: builtin/commit.c:1463 builtin/log.c:1446 builtin/merge.c:242
+#: builtin/pull.c:154 builtin/revert.c:105
 msgid "add Signed-off-by:"
 msgstr ""
 
-#: builtin/commit.c:1427
+#: builtin/commit.c:1464
 msgid "use specified template file"
 msgstr ""
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1465
 msgid "force edit of commit"
 msgstr ""
 
-#: builtin/commit.c:1429
+#: builtin/commit.c:1466
 msgid "default"
 msgstr ""
 
-#: builtin/commit.c:1429 builtin/tag.c:397
+#: builtin/commit.c:1466 builtin/tag.c:398
 msgid "how to strip spaces and #comments from message"
 msgstr ""
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1467
 msgid "include status in commit message template"
 msgstr ""
 
-#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179
+#: builtin/commit.c:1469 builtin/merge.c:240 builtin/pull.c:184
 #: builtin/revert.c:113
 msgid "GPG sign commit"
 msgstr ""
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1472
 msgid "Commit contents options"
 msgstr ""
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1473
 msgid "commit all changed files"
 msgstr ""
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1474
 msgid "add specified files to index for commit"
 msgstr ""
 
-#: builtin/commit.c:1438
+#: builtin/commit.c:1475
 msgid "interactively add files"
 msgstr ""
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1476
 msgid "interactively add changes"
 msgstr ""
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1477
 msgid "commit only specified files"
 msgstr ""
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1478
 msgid "bypass pre-commit and commit-msg hooks"
 msgstr ""
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1479
 msgid "show what would be committed"
 msgstr ""
 
-#: builtin/commit.c:1455
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr ""
 
-#: builtin/commit.c:1456
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr ""
 
-#: builtin/commit.c:1461
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr ""
 
-#: builtin/commit.c:1463
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr ""
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1573
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr ""
 
-#: builtin/commit.c:1543
+#: builtin/commit.c:1580
 msgid "could not read MERGE_MODE"
 msgstr ""
 
-#: builtin/commit.c:1562
+#: builtin/commit.c:1599
 #, c-format
 msgid "could not read commit message: %s"
 msgstr ""
 
-#: builtin/commit.c:1573
+#: builtin/commit.c:1610
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr ""
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1615
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr ""
 
-#: builtin/commit.c:1613
+#: builtin/commit.c:1650
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full and quota is\n"
 "not exceeded, and then \"git reset HEAD\" to recover."
 msgstr ""
 
+#: builtin/commit-graph.c:9
+msgid "git commit-graph [--object-dir <objdir>]"
+msgstr ""
+
+#: builtin/commit-graph.c:10 builtin/commit-graph.c:16
+msgid "git commit-graph read [--object-dir <objdir>]"
+msgstr ""
+
+#: builtin/commit-graph.c:11 builtin/commit-graph.c:21
+msgid ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+msgstr ""
+
+#: builtin/commit-graph.c:39 builtin/commit-graph.c:92
+#: builtin/commit-graph.c:147 builtin/fetch.c:161 builtin/log.c:1466
+msgid "dir"
+msgstr ""
+
+#: builtin/commit-graph.c:40 builtin/commit-graph.c:93
+#: builtin/commit-graph.c:148
+msgid "The object directory to store the graph"
+msgstr ""
+
+#: builtin/commit-graph.c:95
+msgid "scan pack-indexes listed by stdin for commits"
+msgstr ""
+
+#: builtin/commit-graph.c:97
+msgid "start walk at commits listed by stdin"
+msgstr ""
+
+#: builtin/commit-graph.c:99
+msgid "include all commits already in the commit-graph file"
+msgstr ""
+
+#: builtin/commit-graph.c:108
+msgid "cannot use both --stdin-commits and --stdin-packs"
+msgstr ""
+
 #: builtin/config.c:10
 msgid "git config [<options>]"
 msgstr ""
 
-#: builtin/config.c:58
+#: builtin/config.c:101
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr ""
+
+#: builtin/config.c:123
 msgid "Config file location"
 msgstr ""
 
-#: builtin/config.c:59
+#: builtin/config.c:124
 msgid "use global config file"
 msgstr ""
 
-#: builtin/config.c:60
+#: builtin/config.c:125
 msgid "use system config file"
 msgstr ""
 
-#: builtin/config.c:61
+#: builtin/config.c:126
 msgid "use repository config file"
 msgstr ""
 
-#: builtin/config.c:62
+#: builtin/config.c:127
 msgid "use given config file"
 msgstr ""
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "blob-id"
 msgstr ""
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "read config from given blob object"
 msgstr ""
 
-#: builtin/config.c:64
+#: builtin/config.c:129
 msgid "Action"
 msgstr ""
 
-#: builtin/config.c:65
+#: builtin/config.c:130
 msgid "get value: name [value-regex]"
 msgstr ""
 
-#: builtin/config.c:66
+#: builtin/config.c:131
 msgid "get all values: key [value-regex]"
 msgstr ""
 
-#: builtin/config.c:67
+#: builtin/config.c:132
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr ""
 
-#: builtin/config.c:68
+#: builtin/config.c:133
 msgid "get value specific for the URL: section[.var] URL"
 msgstr ""
 
-#: builtin/config.c:69
+#: builtin/config.c:134
 msgid "replace all matching variables: name value [value_regex]"
 msgstr ""
 
-#: builtin/config.c:70
+#: builtin/config.c:135
 msgid "add a new variable: name value"
 msgstr ""
 
-#: builtin/config.c:71
+#: builtin/config.c:136
 msgid "remove a variable: name [value-regex]"
 msgstr ""
 
-#: builtin/config.c:72
+#: builtin/config.c:137
 msgid "remove all matches: name [value-regex]"
 msgstr ""
 
-#: builtin/config.c:73
+#: builtin/config.c:138
 msgid "rename section: old-name new-name"
 msgstr ""
 
-#: builtin/config.c:74
+#: builtin/config.c:139
 msgid "remove a section: name"
 msgstr ""
 
-#: builtin/config.c:75
+#: builtin/config.c:140
 msgid "list all"
 msgstr ""
 
-#: builtin/config.c:76
+#: builtin/config.c:141
 msgid "open an editor"
 msgstr ""
 
-#: builtin/config.c:77
+#: builtin/config.c:142
 msgid "find the color configured: slot [default]"
 msgstr ""
 
-#: builtin/config.c:78
+#: builtin/config.c:143
 msgid "find the color setting: slot [stdout-is-tty]"
 msgstr ""
 
-#: builtin/config.c:79
+#: builtin/config.c:144
 msgid "Type"
 msgstr ""
 
-#: builtin/config.c:80
+#: builtin/config.c:145
+msgid "value is given this type"
+msgstr ""
+
+#: builtin/config.c:146
 msgid "value is \"true\" or \"false\""
 msgstr ""
 
-#: builtin/config.c:81
+#: builtin/config.c:147
 msgid "value is decimal number"
 msgstr ""
 
-#: builtin/config.c:82
+#: builtin/config.c:148
 msgid "value is --bool or --int"
 msgstr ""
 
-#: builtin/config.c:83
+#: builtin/config.c:149
 msgid "value is a path (file or directory name)"
 msgstr ""
 
-#: builtin/config.c:84
+#: builtin/config.c:150
 msgid "value is an expiry date"
 msgstr ""
 
-#: builtin/config.c:85
+#: builtin/config.c:151
 msgid "Other"
 msgstr ""
 
-#: builtin/config.c:86
+#: builtin/config.c:152
 msgid "terminate values with NUL byte"
 msgstr ""
 
-#: builtin/config.c:87
+#: builtin/config.c:153
 msgid "show variable names only"
 msgstr ""
 
-#: builtin/config.c:88
+#: builtin/config.c:154
 msgid "respect include directives on lookup"
 msgstr ""
 
-#: builtin/config.c:89
+#: builtin/config.c:155
 msgid "show origin of config (file, standard input, blob, command line)"
 msgstr ""
 
-#: builtin/config.c:335
+#: builtin/config.c:156
+msgid "value"
+msgstr ""
+
+#: builtin/config.c:156
+msgid "with --get, use default value when missing entry"
+msgstr ""
+
+#: builtin/config.c:332
+#, c-format
+msgid "failed to format default config value: %s"
+msgstr ""
+
+#: builtin/config.c:431
 msgid "unable to parse default color value"
 msgstr ""
 
-#: builtin/config.c:479
+#: builtin/config.c:575
 #, c-format
 msgid ""
 "# This is Git's per-user configuration file.\n"
@@ -7446,27 +7870,31 @@ msgid ""
 "#\temail = %s\n"
 msgstr ""
 
-#: builtin/config.c:507
+#: builtin/config.c:603
 msgid "--local can only be used inside a git repository"
 msgstr ""
 
-#: builtin/config.c:632
+#: builtin/config.c:606
+msgid "--blob can only be used inside a git repository"
+msgstr ""
+
+#: builtin/config.c:735
 #, c-format
 msgid "cannot create configuration file %s"
 msgstr ""
 
-#: builtin/config.c:645
+#: builtin/config.c:748
 #, c-format
 msgid ""
 "cannot overwrite multiple values with a single value\n"
 "       Use a regexp, --add or --replace-all to change %s."
 msgstr ""
 
-#: builtin/count-objects.c:88
+#: builtin/count-objects.c:90
 msgid "git count-objects [-v] [-H | --human-readable]"
 msgstr ""
 
-#: builtin/count-objects.c:98
+#: builtin/count-objects.c:100
 msgid "print sizes in human readable format"
 msgstr ""
 
@@ -7722,371 +8150,377 @@ msgstr ""
 msgid "do not prompt before launching a diff tool"
 msgstr ""
 
-#: builtin/difftool.c:705
+#: builtin/difftool.c:704
 msgid "use symlinks in dir-diff mode"
 msgstr ""
 
-#: builtin/difftool.c:706
+#: builtin/difftool.c:705
 msgid "<tool>"
 msgstr ""
 
-#: builtin/difftool.c:707
+#: builtin/difftool.c:706
 msgid "use the specified diff tool"
 msgstr ""
 
-#: builtin/difftool.c:709
+#: builtin/difftool.c:708
 msgid "print a list of diff tools that may be used with `--tool`"
 msgstr ""
 
-#: builtin/difftool.c:712
+#: builtin/difftool.c:711
 msgid ""
 "make 'git-difftool' exit when an invoked diff tool returns a non - zero exit "
 "code"
 msgstr ""
 
-#: builtin/difftool.c:714
+#: builtin/difftool.c:713
 msgid "<command>"
 msgstr ""
 
-#: builtin/difftool.c:715
+#: builtin/difftool.c:714
 msgid "specify a custom command for viewing diffs"
 msgstr ""
 
-#: builtin/difftool.c:739
+#: builtin/difftool.c:738
 msgid "no <tool> given for --tool=<tool>"
 msgstr ""
 
-#: builtin/difftool.c:746
+#: builtin/difftool.c:745
 msgid "no <cmd> given for --extcmd=<cmd>"
 msgstr ""
 
-#: builtin/fast-export.c:26
+#: builtin/fast-export.c:27
 msgid "git fast-export [rev-list-opts]"
 msgstr ""
 
-#: builtin/fast-export.c:998
+#: builtin/fast-export.c:1000
 msgid "show progress after <n> objects"
 msgstr ""
 
-#: builtin/fast-export.c:1000
+#: builtin/fast-export.c:1002
 msgid "select handling of signed tags"
 msgstr ""
 
-#: builtin/fast-export.c:1003
+#: builtin/fast-export.c:1005
 msgid "select handling of tags that tag filtered objects"
 msgstr ""
 
-#: builtin/fast-export.c:1006
+#: builtin/fast-export.c:1008
 msgid "Dump marks to this file"
 msgstr ""
 
-#: builtin/fast-export.c:1008
+#: builtin/fast-export.c:1010
 msgid "Import marks from this file"
 msgstr ""
 
-#: builtin/fast-export.c:1010
+#: builtin/fast-export.c:1012
 msgid "Fake a tagger when tags lack one"
 msgstr ""
 
-#: builtin/fast-export.c:1012
+#: builtin/fast-export.c:1014
 msgid "Output full tree for each commit"
 msgstr ""
 
-#: builtin/fast-export.c:1014
+#: builtin/fast-export.c:1016
 msgid "Use the done feature to terminate the stream"
 msgstr ""
 
-#: builtin/fast-export.c:1015
+#: builtin/fast-export.c:1017
 msgid "Skip output of blob data"
 msgstr ""
 
-#: builtin/fast-export.c:1016
+#: builtin/fast-export.c:1018
 msgid "refspec"
 msgstr ""
 
-#: builtin/fast-export.c:1017
+#: builtin/fast-export.c:1019
 msgid "Apply refspec to exported refs"
 msgstr ""
 
-#: builtin/fast-export.c:1018
+#: builtin/fast-export.c:1020
 msgid "anonymize output"
 msgstr ""
 
-#: builtin/fetch.c:25
+#: builtin/fetch.c:26
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
 msgstr ""
 
-#: builtin/fetch.c:26
+#: builtin/fetch.c:27
 msgid "git fetch [<options>] <group>"
 msgstr ""
 
-#: builtin/fetch.c:27
+#: builtin/fetch.c:28
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
 msgstr ""
 
-#: builtin/fetch.c:28
+#: builtin/fetch.c:29
 msgid "git fetch --all [<options>]"
 msgstr ""
 
-#: builtin/fetch.c:124 builtin/pull.c:188
+#: builtin/fetch.c:123 builtin/pull.c:193
 msgid "fetch from all remotes"
 msgstr ""
 
-#: builtin/fetch.c:126 builtin/pull.c:191
+#: builtin/fetch.c:125 builtin/pull.c:196
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr ""
 
-#: builtin/fetch.c:128 builtin/pull.c:194
+#: builtin/fetch.c:127 builtin/pull.c:199
 msgid "path to upload pack on remote end"
 msgstr ""
 
-#: builtin/fetch.c:129 builtin/pull.c:196
+#: builtin/fetch.c:128 builtin/pull.c:201
 msgid "force overwrite of local branch"
 msgstr ""
 
-#: builtin/fetch.c:131
+#: builtin/fetch.c:130
 msgid "fetch from multiple remotes"
 msgstr ""
 
-#: builtin/fetch.c:133 builtin/pull.c:198
+#: builtin/fetch.c:132 builtin/pull.c:203
 msgid "fetch all tags and associated objects"
 msgstr ""
 
-#: builtin/fetch.c:135
+#: builtin/fetch.c:134
 msgid "do not fetch all tags (--no-tags)"
 msgstr ""
 
-#: builtin/fetch.c:137
+#: builtin/fetch.c:136
 msgid "number of submodules fetched in parallel"
 msgstr ""
 
-#: builtin/fetch.c:139 builtin/pull.c:201
+#: builtin/fetch.c:138 builtin/pull.c:206
 msgid "prune remote-tracking branches no longer on remote"
 msgstr ""
 
-#: builtin/fetch.c:141
+#: builtin/fetch.c:140
 msgid "prune local tags no longer on remote and clobber changed tags"
 msgstr ""
 
-#: builtin/fetch.c:142 builtin/fetch.c:165 builtin/pull.c:126
+#: builtin/fetch.c:141 builtin/fetch.c:164 builtin/pull.c:131
 msgid "on-demand"
 msgstr ""
 
-#: builtin/fetch.c:143
+#: builtin/fetch.c:142
 msgid "control recursive fetching of submodules"
 msgstr ""
 
-#: builtin/fetch.c:147 builtin/pull.c:209
+#: builtin/fetch.c:146 builtin/pull.c:214
 msgid "keep downloaded pack"
 msgstr ""
 
-#: builtin/fetch.c:149
+#: builtin/fetch.c:148
 msgid "allow updating of HEAD ref"
 msgstr ""
 
-#: builtin/fetch.c:152 builtin/fetch.c:158 builtin/pull.c:212
+#: builtin/fetch.c:151 builtin/fetch.c:157 builtin/pull.c:217
 msgid "deepen history of shallow clone"
 msgstr ""
 
-#: builtin/fetch.c:154
+#: builtin/fetch.c:153
 msgid "deepen history of shallow repository based on time"
 msgstr ""
 
-#: builtin/fetch.c:160 builtin/pull.c:215
+#: builtin/fetch.c:159 builtin/pull.c:220
 msgid "convert to a complete repository"
 msgstr ""
 
-#: builtin/fetch.c:162 builtin/log.c:1466
-msgid "dir"
-msgstr ""
-
-#: builtin/fetch.c:163
+#: builtin/fetch.c:162
 msgid "prepend this to submodule path output"
 msgstr ""
 
-#: builtin/fetch.c:166
+#: builtin/fetch.c:165
 msgid ""
 "default for recursive fetching of submodules (lower priority than config "
 "files)"
 msgstr ""
 
-#: builtin/fetch.c:170 builtin/pull.c:218
+#: builtin/fetch.c:169 builtin/pull.c:223
 msgid "accept refs that update .git/shallow"
 msgstr ""
 
-#: builtin/fetch.c:171 builtin/pull.c:220
+#: builtin/fetch.c:170 builtin/pull.c:225
 msgid "refmap"
 msgstr ""
 
-#: builtin/fetch.c:172 builtin/pull.c:221
+#: builtin/fetch.c:171 builtin/pull.c:226
 msgid "specify fetch refmap"
 msgstr ""
 
-#: builtin/fetch.c:431
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:172
+msgid "server-specific"
+msgstr ""
+
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:173
+msgid "option to transmit"
+msgstr ""
+
+#: builtin/fetch.c:442
 msgid "Couldn't find remote ref HEAD"
 msgstr ""
 
-#: builtin/fetch.c:549
+#: builtin/fetch.c:560
 #, c-format
 msgid "configuration fetch.output contains invalid value %s"
 msgstr ""
 
-#: builtin/fetch.c:642
+#: builtin/fetch.c:653
 #, c-format
 msgid "object %s not found"
 msgstr ""
 
-#: builtin/fetch.c:646
+#: builtin/fetch.c:657
 msgid "[up to date]"
 msgstr ""
 
-#: builtin/fetch.c:659 builtin/fetch.c:739
+#: builtin/fetch.c:670 builtin/fetch.c:750
 msgid "[rejected]"
 msgstr ""
 
-#: builtin/fetch.c:660
+#: builtin/fetch.c:671
 msgid "can't fetch in current branch"
 msgstr ""
 
-#: builtin/fetch.c:669
+#: builtin/fetch.c:680
 msgid "[tag update]"
 msgstr ""
 
-#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719
-#: builtin/fetch.c:734
+#: builtin/fetch.c:681 builtin/fetch.c:714 builtin/fetch.c:730
+#: builtin/fetch.c:745
 msgid "unable to update local ref"
 msgstr ""
 
-#: builtin/fetch.c:689
+#: builtin/fetch.c:700
 msgid "[new tag]"
 msgstr ""
 
-#: builtin/fetch.c:692
+#: builtin/fetch.c:703
 msgid "[new branch]"
 msgstr ""
 
-#: builtin/fetch.c:695
+#: builtin/fetch.c:706
 msgid "[new ref]"
 msgstr ""
 
-#: builtin/fetch.c:734
+#: builtin/fetch.c:745
 msgid "forced update"
 msgstr ""
 
-#: builtin/fetch.c:739
+#: builtin/fetch.c:750
 msgid "non-fast-forward"
 msgstr ""
 
-#: builtin/fetch.c:784
+#: builtin/fetch.c:795
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr ""
 
-#: builtin/fetch.c:804
+#: builtin/fetch.c:815
 #, c-format
 msgid "reject %s because shallow roots are not allowed to be updated"
 msgstr ""
 
-#: builtin/fetch.c:892 builtin/fetch.c:988
+#: builtin/fetch.c:903 builtin/fetch.c:999
 #, c-format
 msgid "From %.*s\n"
 msgstr ""
 
-#: builtin/fetch.c:903
+#: builtin/fetch.c:914
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
 " 'git remote prune %s' to remove any old, conflicting branches"
 msgstr ""
 
-#: builtin/fetch.c:958
+#: builtin/fetch.c:969
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr ""
 
-#: builtin/fetch.c:959
+#: builtin/fetch.c:970
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr ""
 
-#: builtin/fetch.c:991
+#: builtin/fetch.c:1002
 msgid "[deleted]"
 msgstr ""
 
-#: builtin/fetch.c:992 builtin/remote.c:1024
+#: builtin/fetch.c:1003 builtin/remote.c:1033
 msgid "(none)"
 msgstr ""
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1026
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr ""
 
-#: builtin/fetch.c:1034
+#: builtin/fetch.c:1045
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr ""
 
-#: builtin/fetch.c:1037
+#: builtin/fetch.c:1048
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr ""
 
-#: builtin/fetch.c:1277
+#: builtin/fetch.c:1287
 #, c-format
 msgid "Fetching %s\n"
 msgstr ""
 
-#: builtin/fetch.c:1279 builtin/remote.c:97
+#: builtin/fetch.c:1289 builtin/remote.c:98
 #, c-format
 msgid "Could not fetch %s"
 msgstr ""
 
-#: builtin/fetch.c:1325 builtin/fetch.c:1498
+#: builtin/fetch.c:1335 builtin/fetch.c:1503
 msgid ""
 "--filter can only be used with the remote configured in core.partialClone"
 msgstr ""
 
-#: builtin/fetch.c:1350
+#: builtin/fetch.c:1358
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
 msgstr ""
 
-#: builtin/fetch.c:1394
+#: builtin/fetch.c:1395
 msgid "You need to specify a tag name."
 msgstr ""
 
-#: builtin/fetch.c:1439
+#: builtin/fetch.c:1444
 msgid "Negative depth in --deepen is not supported"
 msgstr ""
 
-#: builtin/fetch.c:1441
+#: builtin/fetch.c:1446
 msgid "--deepen and --depth are mutually exclusive"
 msgstr ""
 
-#: builtin/fetch.c:1446
+#: builtin/fetch.c:1451
 msgid "--depth and --unshallow cannot be used together"
 msgstr ""
 
-#: builtin/fetch.c:1448
+#: builtin/fetch.c:1453
 msgid "--unshallow on a complete repository does not make sense"
 msgstr ""
 
-#: builtin/fetch.c:1464
+#: builtin/fetch.c:1469
 msgid "fetch --all does not take a repository argument"
 msgstr ""
 
-#: builtin/fetch.c:1466
+#: builtin/fetch.c:1471
 msgid "fetch --all does not make sense with refspecs"
 msgstr ""
 
-#: builtin/fetch.c:1475
+#: builtin/fetch.c:1480
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr ""
 
-#: builtin/fetch.c:1482
+#: builtin/fetch.c:1487
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr ""
 
@@ -8151,7 +8585,7 @@ msgstr ""
 msgid "show only <n> matched refs"
 msgstr ""
 
-#: builtin/for-each-ref.c:39 builtin/tag.c:420
+#: builtin/for-each-ref.c:39 builtin/tag.c:421
 msgid "respect format colors"
 msgstr ""
 
@@ -8175,81 +8609,81 @@ msgstr ""
 msgid "print only refs which don't contain the commit"
 msgstr ""
 
-#: builtin/fsck.c:568
+#: builtin/fsck.c:569
 msgid "Checking object directories"
 msgstr ""
 
-#: builtin/fsck.c:660
+#: builtin/fsck.c:661
 msgid "git fsck [<options>] [<object>...]"
 msgstr ""
 
-#: builtin/fsck.c:666
+#: builtin/fsck.c:667
 msgid "show unreachable objects"
 msgstr ""
 
-#: builtin/fsck.c:667
+#: builtin/fsck.c:668
 msgid "show dangling objects"
 msgstr ""
 
-#: builtin/fsck.c:668
+#: builtin/fsck.c:669
 msgid "report tags"
 msgstr ""
 
-#: builtin/fsck.c:669
+#: builtin/fsck.c:670
 msgid "report root nodes"
 msgstr ""
 
-#: builtin/fsck.c:670
+#: builtin/fsck.c:671
 msgid "make index objects head nodes"
 msgstr ""
 
-#: builtin/fsck.c:671
+#: builtin/fsck.c:672
 msgid "make reflogs head nodes (default)"
 msgstr ""
 
-#: builtin/fsck.c:672
+#: builtin/fsck.c:673
 msgid "also consider packs and alternate objects"
 msgstr ""
 
-#: builtin/fsck.c:673
+#: builtin/fsck.c:674
 msgid "check only connectivity"
 msgstr ""
 
-#: builtin/fsck.c:674
+#: builtin/fsck.c:675
 msgid "enable more strict checking"
 msgstr ""
 
-#: builtin/fsck.c:676
+#: builtin/fsck.c:677
 msgid "write dangling objects in .git/lost-found"
 msgstr ""
 
-#: builtin/fsck.c:677 builtin/prune.c:108
+#: builtin/fsck.c:678 builtin/prune.c:109
 msgid "show progress"
 msgstr ""
 
-#: builtin/fsck.c:678
+#: builtin/fsck.c:679
 msgid "show verbose names for reachable objects"
 msgstr ""
 
-#: builtin/fsck.c:742
+#: builtin/fsck.c:745
 msgid "Checking objects"
 msgstr ""
 
-#: builtin/gc.c:27
+#: builtin/gc.c:33
 msgid "git gc [<options>]"
 msgstr ""
 
-#: builtin/gc.c:80
+#: builtin/gc.c:88
 #, c-format
 msgid "Failed to fstat %s: %s"
 msgstr ""
 
-#: builtin/gc.c:312
+#: builtin/gc.c:452
 #, c-format
 msgid "Can't stat %s"
 msgstr ""
 
-#: builtin/gc.c:321
+#: builtin/gc.c:461
 #, c-format
 msgid ""
 "The last gc run reported the following. Please correct the root cause\n"
@@ -8259,63 +8693,72 @@ msgid ""
 "%s"
 msgstr ""
 
-#: builtin/gc.c:360
+#: builtin/gc.c:502
 msgid "prune unreferenced objects"
 msgstr ""
 
-#: builtin/gc.c:362
+#: builtin/gc.c:504
 msgid "be more thorough (increased runtime)"
 msgstr ""
 
-#: builtin/gc.c:363
+#: builtin/gc.c:505
 msgid "enable auto-gc mode"
 msgstr ""
 
-#: builtin/gc.c:366
+#: builtin/gc.c:508
 msgid "force running gc even if there may be another gc running"
 msgstr ""
 
-#: builtin/gc.c:384
+#: builtin/gc.c:511
+msgid "repack all other packs except the largest pack"
+msgstr ""
+
+#: builtin/gc.c:528
+#, c-format
+msgid "failed to parse gc.logexpiry value %s"
+msgstr ""
+
+#: builtin/gc.c:539
 #, c-format
-msgid "Failed to parse gc.logexpiry value %s"
+msgid "failed to parse prune expiry value %s"
 msgstr ""
 
-#: builtin/gc.c:412
+#: builtin/gc.c:559
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
 msgstr ""
 
-#: builtin/gc.c:414
+#: builtin/gc.c:561
 #, c-format
 msgid "Auto packing the repository for optimum performance.\n"
 msgstr ""
 
-#: builtin/gc.c:415
+#: builtin/gc.c:562
 #, c-format
 msgid "See \"git help gc\" for manual housekeeping.\n"
 msgstr ""
 
-#: builtin/gc.c:440
+#: builtin/gc.c:598
 #, c-format
 msgid ""
 "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
 msgstr ""
 
-#: builtin/gc.c:487
+#: builtin/gc.c:645
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
 
-#: builtin/grep.c:27
+#: builtin/grep.c:28
 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr ""
 
-#: builtin/grep.c:225
+#: builtin/grep.c:226
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr ""
 
-#: builtin/grep.c:283
+#: builtin/grep.c:284
 #, c-format
 msgid "invalid number of threads specified (%d) for %s"
 msgstr ""
@@ -8324,17 +8767,17 @@ msgstr ""
 #. variable for tweaking threads, currently
 #. grep.threads
 #.
-#: builtin/grep.c:292 builtin/index-pack.c:1523 builtin/index-pack.c:1712
+#: builtin/grep.c:293 builtin/index-pack.c:1535 builtin/index-pack.c:1727
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr ""
 
-#: builtin/grep.c:460 builtin/grep.c:580 builtin/grep.c:622
+#: builtin/grep.c:461 builtin/grep.c:582 builtin/grep.c:623
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr ""
 
-#: builtin/grep.c:637
+#: builtin/grep.c:638
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr ""
@@ -8533,7 +8976,7 @@ msgstr ""
 msgid "unable to resolve revision: %s"
 msgstr ""
 
-#: builtin/grep.c:1036 builtin/index-pack.c:1519
+#: builtin/grep.c:1036 builtin/index-pack.c:1531
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr ""
@@ -8601,423 +9044,395 @@ msgstr ""
 msgid "process file as it were from this path"
 msgstr ""
 
-#: builtin/help.c:43
+#: builtin/help.c:45
 msgid "print all available commands"
 msgstr ""
 
-#: builtin/help.c:44
+#: builtin/help.c:46
 msgid "exclude guides"
 msgstr ""
 
-#: builtin/help.c:45
+#: builtin/help.c:47
 msgid "print list of useful guides"
 msgstr ""
 
-#: builtin/help.c:46
+#: builtin/help.c:48
 msgid "show man page"
 msgstr ""
 
-#: builtin/help.c:47
+#: builtin/help.c:49
 msgid "show manual in web browser"
 msgstr ""
 
-#: builtin/help.c:49
+#: builtin/help.c:51
 msgid "show info page"
 msgstr ""
 
-#: builtin/help.c:55
+#: builtin/help.c:53
+msgid "print command description"
+msgstr ""
+
+#: builtin/help.c:58
 msgid "git help [--all] [--guides] [--man | --web | --info] [<command>]"
 msgstr ""
 
-#: builtin/help.c:67
+#: builtin/help.c:70
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr ""
 
-#: builtin/help.c:94
+#: builtin/help.c:97
 msgid "Failed to start emacsclient."
 msgstr ""
 
-#: builtin/help.c:107
+#: builtin/help.c:110
 msgid "Failed to parse emacsclient version."
 msgstr ""
 
-#: builtin/help.c:115
+#: builtin/help.c:118
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr ""
 
-#: builtin/help.c:133 builtin/help.c:155 builtin/help.c:165 builtin/help.c:173
+#: builtin/help.c:136 builtin/help.c:158 builtin/help.c:168 builtin/help.c:176
 #, c-format
 msgid "failed to exec '%s'"
 msgstr ""
 
-#: builtin/help.c:211
+#: builtin/help.c:214
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
 "Please consider using 'man.<tool>.cmd' instead."
 msgstr ""
 
-#: builtin/help.c:223
+#: builtin/help.c:226
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
 "Please consider using 'man.<tool>.path' instead."
 msgstr ""
 
-#: builtin/help.c:340
+#: builtin/help.c:343
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr ""
 
-#: builtin/help.c:357
+#: builtin/help.c:360
 msgid "no man viewer handled the request"
 msgstr ""
 
-#: builtin/help.c:365
+#: builtin/help.c:368
 msgid "no info viewer handled the request"
 msgstr ""
 
-#: builtin/help.c:407
-msgid "Defining attributes per path"
-msgstr ""
-
-#: builtin/help.c:408
-msgid "Everyday Git With 20 Commands Or So"
-msgstr ""
-
-#: builtin/help.c:409
-msgid "A Git glossary"
-msgstr ""
-
-#: builtin/help.c:410
-msgid "Specifies intentionally untracked files to ignore"
-msgstr ""
-
-#: builtin/help.c:411
-msgid "Defining submodule properties"
-msgstr ""
-
-#: builtin/help.c:412
-msgid "Specifying revisions and ranges for Git"
-msgstr ""
-
-#: builtin/help.c:413
-msgid "A tutorial introduction to Git (for version 1.5.1 or newer)"
-msgstr ""
-
-#: builtin/help.c:414
-msgid "An overview of recommended workflows with Git"
-msgstr ""
-
-#: builtin/help.c:426
-msgid "The common Git guides are:\n"
-msgstr ""
-
-#: builtin/help.c:444
+#: builtin/help.c:415
 #, c-format
 msgid "'%s' is aliased to '%s'"
 msgstr ""
 
-#: builtin/help.c:466 builtin/help.c:483
+#: builtin/help.c:442 builtin/help.c:459
 #, c-format
 msgid "usage: %s%s"
 msgstr ""
 
-#: builtin/index-pack.c:157
+#: builtin/index-pack.c:158
 #, c-format
 msgid "unable to open %s"
 msgstr ""
 
-#: builtin/index-pack.c:207
+#: builtin/index-pack.c:208
 #, c-format
 msgid "object type mismatch at %s"
 msgstr ""
 
-#: builtin/index-pack.c:227
+#: builtin/index-pack.c:228
 #, c-format
 msgid "did not receive expected object %s"
 msgstr ""
 
-#: builtin/index-pack.c:230
+#: builtin/index-pack.c:231
 #, c-format
 msgid "object %s: expected type %s, found %s"
 msgstr ""
 
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
 #, c-format
 msgid "cannot fill %d byte"
 msgid_plural "cannot fill %d bytes"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:282
+#: builtin/index-pack.c:283
 msgid "early EOF"
 msgstr ""
 
-#: builtin/index-pack.c:283
+#: builtin/index-pack.c:284
 msgid "read error on input"
 msgstr ""
 
-#: builtin/index-pack.c:295
+#: builtin/index-pack.c:296
 msgid "used more bytes than were available"
 msgstr ""
 
-#: builtin/index-pack.c:302
+#: builtin/index-pack.c:303
 msgid "pack too large for current definition of off_t"
 msgstr ""
 
-#: builtin/index-pack.c:305 builtin/unpack-objects.c:93
+#: builtin/index-pack.c:306 builtin/unpack-objects.c:93
 msgid "pack exceeds maximum allowed size"
 msgstr ""
 
-#: builtin/index-pack.c:320
+#: builtin/index-pack.c:321
 #, c-format
 msgid "unable to create '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:326
+#: builtin/index-pack.c:327
 #, c-format
 msgid "cannot open packfile '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:340
+#: builtin/index-pack.c:341
 msgid "pack signature mismatch"
 msgstr ""
 
-#: builtin/index-pack.c:342
+#: builtin/index-pack.c:343
 #, c-format
 msgid "pack version %<PRIu32> unsupported"
 msgstr ""
 
-#: builtin/index-pack.c:360
+#: builtin/index-pack.c:361
 #, c-format
 msgid "pack has bad object at offset %<PRIuMAX>: %s"
 msgstr ""
 
-#: builtin/index-pack.c:481
+#: builtin/index-pack.c:482
 #, c-format
 msgid "inflate returned %d"
 msgstr ""
 
-#: builtin/index-pack.c:530
+#: builtin/index-pack.c:531
 msgid "offset value overflow for delta base object"
 msgstr ""
 
-#: builtin/index-pack.c:538
+#: builtin/index-pack.c:539
 msgid "delta base offset is out of bound"
 msgstr ""
 
-#: builtin/index-pack.c:546
+#: builtin/index-pack.c:547
 #, c-format
 msgid "unknown object type %d"
 msgstr ""
 
-#: builtin/index-pack.c:577
+#: builtin/index-pack.c:578
 msgid "cannot pread pack file"
 msgstr ""
 
-#: builtin/index-pack.c:579
+#: builtin/index-pack.c:580
 #, c-format
 msgid "premature end of pack file, %<PRIuMAX> byte missing"
 msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:605
+#: builtin/index-pack.c:606
 msgid "serious inflate inconsistency"
 msgstr ""
 
-#: builtin/index-pack.c:750 builtin/index-pack.c:756 builtin/index-pack.c:779
-#: builtin/index-pack.c:818 builtin/index-pack.c:827
+#: builtin/index-pack.c:751 builtin/index-pack.c:757 builtin/index-pack.c:780
+#: builtin/index-pack.c:819 builtin/index-pack.c:828
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr ""
 
-#: builtin/index-pack.c:753 builtin/pack-objects.c:182
-#: builtin/pack-objects.c:276
+#: builtin/index-pack.c:754 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:292
 #, c-format
 msgid "unable to read %s"
 msgstr ""
 
-#: builtin/index-pack.c:816
+#: builtin/index-pack.c:817
 #, c-format
 msgid "cannot read existing object info %s"
 msgstr ""
 
-#: builtin/index-pack.c:824
+#: builtin/index-pack.c:825
 #, c-format
 msgid "cannot read existing object %s"
 msgstr ""
 
-#: builtin/index-pack.c:838
+#: builtin/index-pack.c:839
 #, c-format
 msgid "invalid blob object %s"
 msgstr ""
 
-#: builtin/index-pack.c:853
-#, c-format
-msgid "invalid %s"
+#: builtin/index-pack.c:842 builtin/index-pack.c:860
+msgid "fsck error in packed object"
 msgstr ""
 
-#: builtin/index-pack.c:856
-msgid "Error in object"
+#: builtin/index-pack.c:857
+#, c-format
+msgid "invalid %s"
 msgstr ""
 
-#: builtin/index-pack.c:858
+#: builtin/index-pack.c:862
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr ""
 
-#: builtin/index-pack.c:930 builtin/index-pack.c:961
+#: builtin/index-pack.c:934 builtin/index-pack.c:965
 msgid "failed to apply delta"
 msgstr ""
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Receiving objects"
 msgstr ""
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Indexing objects"
 msgstr ""
 
-#: builtin/index-pack.c:1165
+#: builtin/index-pack.c:1169
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr ""
 
-#: builtin/index-pack.c:1170
+#: builtin/index-pack.c:1174
 msgid "cannot fstat packfile"
 msgstr ""
 
-#: builtin/index-pack.c:1173
+#: builtin/index-pack.c:1177
 msgid "pack has junk at the end"
 msgstr ""
 
-#: builtin/index-pack.c:1185
+#: builtin/index-pack.c:1189
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr ""
 
-#: builtin/index-pack.c:1208
+#: builtin/index-pack.c:1212
 msgid "Resolving deltas"
 msgstr ""
 
-#: builtin/index-pack.c:1219
+#: builtin/index-pack.c:1223
 #, c-format
 msgid "unable to create thread: %s"
 msgstr ""
 
-#: builtin/index-pack.c:1261
+#: builtin/index-pack.c:1265
 msgid "confusion beyond insanity"
 msgstr ""
 
-#: builtin/index-pack.c:1267
+#: builtin/index-pack.c:1271
 #, c-format
 msgid "completed with %d local object"
 msgid_plural "completed with %d local objects"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1283
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr ""
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1287
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:1307
+#: builtin/index-pack.c:1311
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr ""
 
-#: builtin/index-pack.c:1383
+#: builtin/index-pack.c:1388
 #, c-format
 msgid "local object %s is corrupt"
 msgstr ""
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1402
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr ""
 
-#: builtin/index-pack.c:1422
+#: builtin/index-pack.c:1427
 #, c-format
 msgid "cannot write %s file '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1435
 #, c-format
 msgid "cannot close written %s file '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1454
+#: builtin/index-pack.c:1459
 msgid "error while closing pack file"
 msgstr ""
 
-#: builtin/index-pack.c:1468
+#: builtin/index-pack.c:1473
 msgid "cannot store pack file"
 msgstr ""
 
-#: builtin/index-pack.c:1476
+#: builtin/index-pack.c:1481
 msgid "cannot store index file"
 msgstr ""
 
-#: builtin/index-pack.c:1513
+#: builtin/index-pack.c:1525
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr ""
 
-#: builtin/index-pack.c:1581
+#: builtin/index-pack.c:1594
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1583
+#: builtin/index-pack.c:1596
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr ""
 
-#: builtin/index-pack.c:1631
+#: builtin/index-pack.c:1644
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:1638
+#: builtin/index-pack.c:1651
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/index-pack.c:1675
+#: builtin/index-pack.c:1688
 msgid "Cannot come back to cwd"
 msgstr ""
 
-#: builtin/index-pack.c:1724 builtin/index-pack.c:1727
-#: builtin/index-pack.c:1743 builtin/index-pack.c:1747
+#: builtin/index-pack.c:1739 builtin/index-pack.c:1742
+#: builtin/index-pack.c:1758 builtin/index-pack.c:1762
 #, c-format
 msgid "bad %s"
 msgstr ""
 
-#: builtin/index-pack.c:1763
+#: builtin/index-pack.c:1778
 msgid "--fix-thin cannot be used without --stdin"
 msgstr ""
 
-#: builtin/index-pack.c:1765
+#: builtin/index-pack.c:1780
 msgid "--stdin requires a git repository"
 msgstr ""
 
-#: builtin/index-pack.c:1771
+#: builtin/index-pack.c:1786
 msgid "--verify with no packfile name given"
 msgstr ""
 
+#: builtin/index-pack.c:1836 builtin/unpack-objects.c:578
+msgid "fsck error in pack objects"
+msgstr ""
+
 #: builtin/init-db.c:55
 #, c-format
 msgid "cannot stat '%s'"
@@ -9055,7 +9470,7 @@ msgstr ""
 
 #: builtin/init-db.c:120
 #, c-format
-msgid "templates not found %s"
+msgid "templates not found in %s"
 msgstr ""
 
 #: builtin/init-db.c:135
@@ -9112,11 +9527,6 @@ msgstr ""
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr ""
 
-#: builtin/init-db.c:516 builtin/init-db.c:521
-#, c-format
-msgid "cannot mkdir %s"
-msgstr ""
-
 #: builtin/init-db.c:525
 #, c-format
 msgid "cannot chdir to %s"
@@ -9296,7 +9706,7 @@ msgstr ""
 msgid "Unknown commit %s"
 msgstr ""
 
-#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:522
+#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:523
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr ""
@@ -9641,46 +10051,46 @@ msgstr ""
 msgid "show debugging data"
 msgstr ""
 
-#: builtin/ls-remote.c:7
+#: builtin/ls-remote.c:9
 msgid ""
 "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
 "                     [--symref] [<repository> [<refs>...]]"
 msgstr ""
 
-#: builtin/ls-remote.c:52
+#: builtin/ls-remote.c:59
 msgid "do not print remote URL"
 msgstr ""
 
-#: builtin/ls-remote.c:53 builtin/ls-remote.c:55
+#: builtin/ls-remote.c:60 builtin/ls-remote.c:62
 msgid "exec"
 msgstr ""
 
-#: builtin/ls-remote.c:54 builtin/ls-remote.c:56
+#: builtin/ls-remote.c:61 builtin/ls-remote.c:63
 msgid "path of git-upload-pack on the remote host"
 msgstr ""
 
-#: builtin/ls-remote.c:58
+#: builtin/ls-remote.c:65
 msgid "limit to tags"
 msgstr ""
 
-#: builtin/ls-remote.c:59
+#: builtin/ls-remote.c:66
 msgid "limit to heads"
 msgstr ""
 
-#: builtin/ls-remote.c:60
+#: builtin/ls-remote.c:67
 msgid "do not show peeled tags"
 msgstr ""
 
-#: builtin/ls-remote.c:62
+#: builtin/ls-remote.c:69
 msgid "take url.<base>.insteadOf into account"
 msgstr ""
 
-#: builtin/ls-remote.c:64
+#: builtin/ls-remote.c:73
 msgid "exit with exit code 2 if no matching refs are found"
 msgstr ""
 
-#: builtin/ls-remote.c:67
+#: builtin/ls-remote.c:76
 msgid "show underlying ref in addition to the object pointed by it"
 msgstr ""
 
@@ -9725,165 +10135,165 @@ msgstr ""
 msgid "empty mbox: '%s'"
 msgstr ""
 
-#: builtin/merge.c:49
+#: builtin/merge.c:51
 msgid "git merge [<options>] [<commit>...]"
 msgstr ""
 
-#: builtin/merge.c:50
+#: builtin/merge.c:52
 msgid "git merge --abort"
 msgstr ""
 
-#: builtin/merge.c:51
+#: builtin/merge.c:53
 msgid "git merge --continue"
 msgstr ""
 
-#: builtin/merge.c:108
+#: builtin/merge.c:110
 msgid "switch `m' requires a value"
 msgstr ""
 
-#: builtin/merge.c:145
+#: builtin/merge.c:147
 #, c-format
 msgid "Could not find merge strategy '%s'.\n"
 msgstr ""
 
-#: builtin/merge.c:146
+#: builtin/merge.c:148
 #, c-format
 msgid "Available strategies are:"
 msgstr ""
 
-#: builtin/merge.c:151
+#: builtin/merge.c:153
 #, c-format
 msgid "Available custom strategies are:"
 msgstr ""
 
-#: builtin/merge.c:201 builtin/pull.c:137
+#: builtin/merge.c:203 builtin/pull.c:142
 msgid "do not show a diffstat at the end of the merge"
 msgstr ""
 
-#: builtin/merge.c:204 builtin/pull.c:140
+#: builtin/merge.c:206 builtin/pull.c:145
 msgid "show a diffstat at the end of the merge"
 msgstr ""
 
-#: builtin/merge.c:205 builtin/pull.c:143
+#: builtin/merge.c:207 builtin/pull.c:148
 msgid "(synonym to --stat)"
 msgstr ""
 
-#: builtin/merge.c:207 builtin/pull.c:146
+#: builtin/merge.c:209 builtin/pull.c:151
 msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr ""
 
-#: builtin/merge.c:210 builtin/pull.c:152
+#: builtin/merge.c:212 builtin/pull.c:157
 msgid "create a single commit instead of doing a merge"
 msgstr ""
 
-#: builtin/merge.c:212 builtin/pull.c:155
+#: builtin/merge.c:214 builtin/pull.c:160
 msgid "perform a commit if the merge succeeds (default)"
 msgstr ""
 
-#: builtin/merge.c:214 builtin/pull.c:158
+#: builtin/merge.c:216 builtin/pull.c:163
 msgid "edit message before committing"
 msgstr ""
 
-#: builtin/merge.c:215
+#: builtin/merge.c:217
 msgid "allow fast-forward (default)"
 msgstr ""
 
-#: builtin/merge.c:217 builtin/pull.c:164
+#: builtin/merge.c:219 builtin/pull.c:169
 msgid "abort if fast-forward is not possible"
 msgstr ""
 
-#: builtin/merge.c:221 builtin/pull.c:167
+#: builtin/merge.c:223 builtin/pull.c:172
 msgid "verify that the named commit has a valid GPG signature"
 msgstr ""
 
-#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171
+#: builtin/merge.c:224 builtin/notes.c:777 builtin/pull.c:176
 #: builtin/revert.c:109
 msgid "strategy"
 msgstr ""
 
-#: builtin/merge.c:223 builtin/pull.c:172
+#: builtin/merge.c:225 builtin/pull.c:177
 msgid "merge strategy to use"
 msgstr ""
 
-#: builtin/merge.c:224 builtin/pull.c:175
+#: builtin/merge.c:226 builtin/pull.c:180
 msgid "option=value"
 msgstr ""
 
-#: builtin/merge.c:225 builtin/pull.c:176
+#: builtin/merge.c:227 builtin/pull.c:181
 msgid "option for selected merge strategy"
 msgstr ""
 
-#: builtin/merge.c:227
+#: builtin/merge.c:229
 msgid "merge commit message (for a non-fast-forward merge)"
 msgstr ""
 
-#: builtin/merge.c:231
+#: builtin/merge.c:233
 msgid "abort the current in-progress merge"
 msgstr ""
 
-#: builtin/merge.c:233
+#: builtin/merge.c:235
 msgid "continue the current in-progress merge"
 msgstr ""
 
-#: builtin/merge.c:235 builtin/pull.c:183
+#: builtin/merge.c:237 builtin/pull.c:188
 msgid "allow merging unrelated histories"
 msgstr ""
 
-#: builtin/merge.c:241
+#: builtin/merge.c:243
 msgid "verify commit-msg hook"
 msgstr ""
 
-#: builtin/merge.c:266
+#: builtin/merge.c:268
 msgid "could not run stash."
 msgstr ""
 
-#: builtin/merge.c:271
+#: builtin/merge.c:273
 msgid "stash failed"
 msgstr ""
 
-#: builtin/merge.c:276
+#: builtin/merge.c:278
 #, c-format
 msgid "not a valid object: %s"
 msgstr ""
 
-#: builtin/merge.c:298 builtin/merge.c:315
+#: builtin/merge.c:300 builtin/merge.c:317
 msgid "read-tree failed"
 msgstr ""
 
-#: builtin/merge.c:345
+#: builtin/merge.c:347
 msgid " (nothing to squash)"
 msgstr ""
 
-#: builtin/merge.c:356
+#: builtin/merge.c:358
 #, c-format
 msgid "Squash commit -- not updating HEAD\n"
 msgstr ""
 
-#: builtin/merge.c:406
+#: builtin/merge.c:408
 #, c-format
 msgid "No merge message -- not updating HEAD\n"
 msgstr ""
 
-#: builtin/merge.c:456
+#: builtin/merge.c:458
 #, c-format
 msgid "'%s' does not point to a commit"
 msgstr ""
 
-#: builtin/merge.c:546
+#: builtin/merge.c:548
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr ""
 
-#: builtin/merge.c:668
+#: builtin/merge.c:669
 msgid "Not handling anything other than two heads merge."
 msgstr ""
 
-#: builtin/merge.c:682
+#: builtin/merge.c:683
 #, c-format
 msgid "Unknown option for merge-recursive: -X%s"
 msgstr ""
 
-#: builtin/merge.c:697
+#: builtin/merge.c:698
 #, c-format
 msgid "unable to write %s"
 msgstr ""
@@ -9912,181 +10322,181 @@ msgstr ""
 msgid "Empty commit message."
 msgstr ""
 
-#: builtin/merge.c:820
+#: builtin/merge.c:819
 #, c-format
 msgid "Wonderful.\n"
 msgstr ""
 
-#: builtin/merge.c:873
+#: builtin/merge.c:872
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr ""
 
-#: builtin/merge.c:912
+#: builtin/merge.c:911
 msgid "No current branch."
 msgstr ""
 
-#: builtin/merge.c:914
+#: builtin/merge.c:913
 msgid "No remote for the current branch."
 msgstr ""
 
-#: builtin/merge.c:916
+#: builtin/merge.c:915
 msgid "No default upstream defined for the current branch."
 msgstr ""
 
-#: builtin/merge.c:921
+#: builtin/merge.c:920
 #, c-format
 msgid "No remote-tracking branch for %s from %s"
 msgstr ""
 
-#: builtin/merge.c:974
+#: builtin/merge.c:973
 #, c-format
 msgid "Bad value '%s' in environment '%s'"
 msgstr ""
 
-#: builtin/merge.c:1076
+#: builtin/merge.c:1075
 #, c-format
 msgid "not something we can merge in %s: %s"
 msgstr ""
 
-#: builtin/merge.c:1110
+#: builtin/merge.c:1109
 msgid "not something we can merge"
 msgstr ""
 
-#: builtin/merge.c:1212
+#: builtin/merge.c:1211
 msgid "--abort expects no arguments"
 msgstr ""
 
-#: builtin/merge.c:1216
+#: builtin/merge.c:1215
 msgid "There is no merge to abort (MERGE_HEAD missing)."
 msgstr ""
 
-#: builtin/merge.c:1228
+#: builtin/merge.c:1227
 msgid "--continue expects no arguments"
 msgstr ""
 
-#: builtin/merge.c:1232
+#: builtin/merge.c:1231
 msgid "There is no merge in progress (MERGE_HEAD missing)."
 msgstr ""
 
-#: builtin/merge.c:1248
+#: builtin/merge.c:1247
 msgid ""
 "You have not concluded your merge (MERGE_HEAD exists).\n"
 "Please, commit your changes before you merge."
 msgstr ""
 
-#: builtin/merge.c:1255
+#: builtin/merge.c:1254
 msgid ""
 "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 "Please, commit your changes before you merge."
 msgstr ""
 
-#: builtin/merge.c:1258
+#: builtin/merge.c:1257
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
 msgstr ""
 
-#: builtin/merge.c:1267
+#: builtin/merge.c:1266
 msgid "You cannot combine --squash with --no-ff."
 msgstr ""
 
-#: builtin/merge.c:1275
+#: builtin/merge.c:1274
 msgid "No commit specified and merge.defaultToUpstream not set."
 msgstr ""
 
-#: builtin/merge.c:1292
+#: builtin/merge.c:1291
 msgid "Squash commit into empty head not supported yet"
 msgstr ""
 
-#: builtin/merge.c:1294
+#: builtin/merge.c:1293
 msgid "Non-fast-forward commit does not make sense into an empty head"
 msgstr ""
 
-#: builtin/merge.c:1299
+#: builtin/merge.c:1298
 #, c-format
 msgid "%s - not something we can merge"
 msgstr ""
 
-#: builtin/merge.c:1301
+#: builtin/merge.c:1300
 msgid "Can merge only exactly one commit into empty head"
 msgstr ""
 
-#: builtin/merge.c:1335
+#: builtin/merge.c:1334
 #, c-format
 msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
 msgstr ""
 
-#: builtin/merge.c:1338
+#: builtin/merge.c:1337
 #, c-format
 msgid "Commit %s has a bad GPG signature allegedly by %s."
 msgstr ""
 
-#: builtin/merge.c:1341
+#: builtin/merge.c:1340
 #, c-format
 msgid "Commit %s does not have a GPG signature."
 msgstr ""
 
-#: builtin/merge.c:1344
+#: builtin/merge.c:1343
 #, c-format
 msgid "Commit %s has a good GPG signature by %s\n"
 msgstr ""
 
-#: builtin/merge.c:1403
+#: builtin/merge.c:1402
 msgid "refusing to merge unrelated histories"
 msgstr ""
 
-#: builtin/merge.c:1412
+#: builtin/merge.c:1411
 msgid "Already up to date."
 msgstr ""
 
-#: builtin/merge.c:1422
+#: builtin/merge.c:1421
 #, c-format
 msgid "Updating %s..%s\n"
 msgstr ""
 
-#: builtin/merge.c:1463
+#: builtin/merge.c:1462
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
 msgstr ""
 
-#: builtin/merge.c:1470
+#: builtin/merge.c:1469
 #, c-format
 msgid "Nope.\n"
 msgstr ""
 
-#: builtin/merge.c:1495
+#: builtin/merge.c:1494
 msgid "Already up to date. Yeeah!"
 msgstr ""
 
-#: builtin/merge.c:1501
+#: builtin/merge.c:1500
 msgid "Not possible to fast-forward, aborting."
 msgstr ""
 
-#: builtin/merge.c:1524 builtin/merge.c:1603
+#: builtin/merge.c:1523 builtin/merge.c:1602
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
 msgstr ""
 
-#: builtin/merge.c:1528
+#: builtin/merge.c:1527
 #, c-format
 msgid "Trying merge strategy %s...\n"
 msgstr ""
 
-#: builtin/merge.c:1594
+#: builtin/merge.c:1593
 #, c-format
 msgid "No merge strategy handled the merge.\n"
 msgstr ""
 
-#: builtin/merge.c:1596
+#: builtin/merge.c:1595
 #, c-format
 msgid "Merge with strategy %s failed.\n"
 msgstr ""
 
-#: builtin/merge.c:1605
+#: builtin/merge.c:1604
 #, c-format
 msgid "Using the %s to prepare resolving by hand.\n"
 msgstr ""
 
-#: builtin/merge.c:1617
+#: builtin/merge.c:1616
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr ""
@@ -10220,25 +10630,25 @@ msgstr ""
 msgid "git mv [<options>] <source>... <destination>"
 msgstr ""
 
-#: builtin/mv.c:83
+#: builtin/mv.c:82
 #, c-format
 msgid "Directory %s is in index and no submodule?"
 msgstr ""
 
-#: builtin/mv.c:85 builtin/rm.c:289
+#: builtin/mv.c:84 builtin/rm.c:288
 msgid "Please stage your changes to .gitmodules or stash them to proceed"
 msgstr ""
 
-#: builtin/mv.c:103
+#: builtin/mv.c:102
 #, c-format
 msgid "%.*s is in index"
 msgstr ""
 
-#: builtin/mv.c:125
+#: builtin/mv.c:124
 msgid "force move/rename even if target exists"
 msgstr ""
 
-#: builtin/mv.c:127
+#: builtin/mv.c:126
 msgid "skip move/rename errors"
 msgstr ""
 
@@ -10303,7 +10713,7 @@ msgstr ""
 msgid "Renaming %s to %s\n"
 msgstr ""
 
-#: builtin/mv.c:276 builtin/remote.c:712 builtin/repack.c:394
+#: builtin/mv.c:276 builtin/remote.c:715 builtin/repack.c:409
 #, c-format
 msgid "renaming '%s' failed"
 msgstr ""
@@ -10488,12 +10898,12 @@ msgstr ""
 msgid "the note contents have been left in %s"
 msgstr ""
 
-#: builtin/notes.c:234 builtin/tag.c:506
+#: builtin/notes.c:234 builtin/tag.c:507
 #, c-format
 msgid "cannot read '%s'"
 msgstr ""
 
-#: builtin/notes.c:236 builtin/tag.c:509
+#: builtin/notes.c:236 builtin/tag.c:510
 #, c-format
 msgid "could not open or read '%s'"
 msgstr ""
@@ -10727,7 +11137,7 @@ msgstr ""
 msgid "read object names from the standard input"
 msgstr ""
 
-#: builtin/notes.c:943 builtin/prune.c:106 builtin/worktree.c:160
+#: builtin/notes.c:943 builtin/prune.c:107 builtin/worktree.c:151
 msgid "do not remove, show only"
 msgstr ""
 
@@ -10748,208 +11158,236 @@ msgstr ""
 msgid "unknown subcommand: %s"
 msgstr ""
 
-#: builtin/pack-objects.c:33
+#: builtin/pack-objects.c:48
 msgid ""
 "git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
 msgstr ""
 
-#: builtin/pack-objects.c:34
+#: builtin/pack-objects.c:49
 msgid ""
 "git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
 msgstr ""
 
-#: builtin/pack-objects.c:195 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:211 builtin/pack-objects.c:214
 #, c-format
 msgid "deflate error (%d)"
 msgstr ""
 
-#: builtin/pack-objects.c:791
+#: builtin/pack-objects.c:810
 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
 msgstr ""
 
-#: builtin/pack-objects.c:804
+#: builtin/pack-objects.c:823
 msgid "Writing objects"
 msgstr ""
 
-#: builtin/pack-objects.c:1084
+#: builtin/pack-objects.c:1106
 msgid "disabling bitmap writing, as some objects are not being packed"
 msgstr ""
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:1765
+msgid "Counting objects"
+msgstr ""
+
+#: builtin/pack-objects.c:1895
+#, c-format
+msgid "unable to get size of %s"
+msgstr ""
+
+#: builtin/pack-objects.c:1910
+#, c-format
+msgid "unable to parse object header of %s"
+msgstr ""
+
+#: builtin/pack-objects.c:2564
 msgid "Compressing objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2625
+#: builtin/pack-objects.c:2735
 msgid "invalid value for --missing"
 msgstr ""
 
-#: builtin/pack-objects.c:2928
+#: builtin/pack-objects.c:3067
 #, c-format
 msgid "unsupported index version %s"
 msgstr ""
 
-#: builtin/pack-objects.c:2932
+#: builtin/pack-objects.c:3071
 #, c-format
 msgid "bad index version '%s'"
 msgstr ""
 
-#: builtin/pack-objects.c:2962
+#: builtin/pack-objects.c:3102
 msgid "do not show progress meter"
 msgstr ""
 
-#: builtin/pack-objects.c:2964
+#: builtin/pack-objects.c:3104
 msgid "show progress meter"
 msgstr ""
 
-#: builtin/pack-objects.c:2966
+#: builtin/pack-objects.c:3106
 msgid "show progress meter during object writing phase"
 msgstr ""
 
-#: builtin/pack-objects.c:2969
+#: builtin/pack-objects.c:3109
 msgid "similar to --all-progress when progress meter is shown"
 msgstr ""
 
-#: builtin/pack-objects.c:2970
+#: builtin/pack-objects.c:3110
 msgid "version[,offset]"
 msgstr ""
 
-#: builtin/pack-objects.c:2971
+#: builtin/pack-objects.c:3111
 msgid "write the pack index file in the specified idx format version"
 msgstr ""
 
-#: builtin/pack-objects.c:2974
+#: builtin/pack-objects.c:3114
 msgid "maximum size of each output pack file"
 msgstr ""
 
-#: builtin/pack-objects.c:2976
+#: builtin/pack-objects.c:3116
 msgid "ignore borrowed objects from alternate object store"
 msgstr ""
 
-#: builtin/pack-objects.c:2978
+#: builtin/pack-objects.c:3118
 msgid "ignore packed objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2980
+#: builtin/pack-objects.c:3120
 msgid "limit pack window by objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2982
+#: builtin/pack-objects.c:3122
 msgid "limit pack window by memory in addition to object limit"
 msgstr ""
 
-#: builtin/pack-objects.c:2984
+#: builtin/pack-objects.c:3124
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr ""
 
-#: builtin/pack-objects.c:2986
+#: builtin/pack-objects.c:3126
 msgid "reuse existing deltas"
 msgstr ""
 
-#: builtin/pack-objects.c:2988
+#: builtin/pack-objects.c:3128
 msgid "reuse existing objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2990
+#: builtin/pack-objects.c:3130
 msgid "use OFS_DELTA objects"
 msgstr ""
 
-#: builtin/pack-objects.c:2992
+#: builtin/pack-objects.c:3132
 msgid "use threads when searching for best delta matches"
 msgstr ""
 
-#: builtin/pack-objects.c:2994
+#: builtin/pack-objects.c:3134
 msgid "do not create an empty pack output"
 msgstr ""
 
-#: builtin/pack-objects.c:2996
+#: builtin/pack-objects.c:3136
 msgid "read revision arguments from standard input"
 msgstr ""
 
-#: builtin/pack-objects.c:2998
+#: builtin/pack-objects.c:3138
 msgid "limit the objects to those that are not yet packed"
 msgstr ""
 
-#: builtin/pack-objects.c:3001
+#: builtin/pack-objects.c:3141
 msgid "include objects reachable from any reference"
 msgstr ""
 
-#: builtin/pack-objects.c:3004
+#: builtin/pack-objects.c:3144
 msgid "include objects referred by reflog entries"
 msgstr ""
 
-#: builtin/pack-objects.c:3007
+#: builtin/pack-objects.c:3147
 msgid "include objects referred to by the index"
 msgstr ""
 
-#: builtin/pack-objects.c:3010
+#: builtin/pack-objects.c:3150
 msgid "output pack to stdout"
 msgstr ""
 
-#: builtin/pack-objects.c:3012
+#: builtin/pack-objects.c:3152
 msgid "include tag objects that refer to objects to be packed"
 msgstr ""
 
-#: builtin/pack-objects.c:3014
+#: builtin/pack-objects.c:3154
 msgid "keep unreachable objects"
 msgstr ""
 
-#: builtin/pack-objects.c:3016
+#: builtin/pack-objects.c:3156
 msgid "pack loose unreachable objects"
 msgstr ""
 
-#: builtin/pack-objects.c:3018
+#: builtin/pack-objects.c:3158
 msgid "unpack unreachable objects newer than <time>"
 msgstr ""
 
-#: builtin/pack-objects.c:3021
+#: builtin/pack-objects.c:3161
 msgid "create thin packs"
 msgstr ""
 
-#: builtin/pack-objects.c:3023
+#: builtin/pack-objects.c:3163
 msgid "create packs suitable for shallow fetches"
 msgstr ""
 
-#: builtin/pack-objects.c:3025
+#: builtin/pack-objects.c:3165
 msgid "ignore packs that have companion .keep file"
 msgstr ""
 
-#: builtin/pack-objects.c:3027
+#: builtin/pack-objects.c:3167
+msgid "ignore this pack"
+msgstr ""
+
+#: builtin/pack-objects.c:3169
 msgid "pack compression level"
 msgstr ""
 
-#: builtin/pack-objects.c:3029
+#: builtin/pack-objects.c:3171
 msgid "do not hide commits by grafts"
 msgstr ""
 
-#: builtin/pack-objects.c:3031
+#: builtin/pack-objects.c:3173
 msgid "use a bitmap index if available to speed up counting objects"
 msgstr ""
 
-#: builtin/pack-objects.c:3033
+#: builtin/pack-objects.c:3175
 msgid "write a bitmap index together with the pack index"
 msgstr ""
 
-#: builtin/pack-objects.c:3036
+#: builtin/pack-objects.c:3178
 msgid "handling for missing objects"
 msgstr ""
 
-#: builtin/pack-objects.c:3039
+#: builtin/pack-objects.c:3181
 msgid "do not pack objects in promisor packfiles"
 msgstr ""
 
-#: builtin/pack-objects.c:3178
-msgid "Counting objects"
+#: builtin/pack-objects.c:3205
+#, c-format
+msgid "delta chain depth %d is too deep, forcing %d"
+msgstr ""
+
+#: builtin/pack-objects.c:3210
+#, c-format
+msgid "pack.deltaCacheLimit is too high, forcing %d"
+msgstr ""
+
+#: builtin/pack-objects.c:3338
+msgid "Enumerating objects"
 msgstr ""
 
-#: builtin/pack-refs.c:6
+#: builtin/pack-refs.c:7
 msgid "git pack-refs [<options>]"
 msgstr ""
 
-#: builtin/pack-refs.c:14
+#: builtin/pack-refs.c:15
 msgid "pack everything"
 msgstr ""
 
-#: builtin/pack-refs.c:15
+#: builtin/pack-refs.c:16
 msgid "prune loose refs (default)"
 msgstr ""
 
@@ -10965,82 +11403,82 @@ msgstr ""
 msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]"
 msgstr ""
 
-#: builtin/prune.c:107
+#: builtin/prune.c:108
 msgid "report pruned objects"
 msgstr ""
 
-#: builtin/prune.c:110
+#: builtin/prune.c:111
 msgid "expire objects older than <time>"
 msgstr ""
 
-#: builtin/prune.c:112
+#: builtin/prune.c:113
 msgid "limit traversal to objects outside promisor packfiles"
 msgstr ""
 
-#: builtin/prune.c:126
+#: builtin/prune.c:127
 msgid "cannot prune in a precious-objects repo"
 msgstr ""
 
-#: builtin/pull.c:54 builtin/pull.c:56
+#: builtin/pull.c:59 builtin/pull.c:61
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr ""
 
-#: builtin/pull.c:76
+#: builtin/pull.c:81
 msgid "git pull [<options>] [<repository> [<refspec>...]]"
 msgstr ""
 
-#: builtin/pull.c:127
+#: builtin/pull.c:132
 msgid "control for recursive fetching of submodules"
 msgstr ""
 
-#: builtin/pull.c:131
+#: builtin/pull.c:136
 msgid "Options related to merging"
 msgstr ""
 
-#: builtin/pull.c:134
+#: builtin/pull.c:139
 msgid "incorporate changes by rebasing rather than merging"
 msgstr ""
 
-#: builtin/pull.c:161 builtin/rebase--helper.c:23 builtin/revert.c:121
+#: builtin/pull.c:166 builtin/rebase--helper.c:23 builtin/revert.c:121
 msgid "allow fast-forward"
 msgstr ""
 
-#: builtin/pull.c:170
+#: builtin/pull.c:175
 msgid "automatically stash/stash pop before and after rebase"
 msgstr ""
 
-#: builtin/pull.c:186
+#: builtin/pull.c:191
 msgid "Options related to fetching"
 msgstr ""
 
-#: builtin/pull.c:204
+#: builtin/pull.c:209
 msgid "number of submodules pulled in parallel"
 msgstr ""
 
-#: builtin/pull.c:299
+#: builtin/pull.c:304
 #, c-format
 msgid "Invalid value for pull.ff: %s"
 msgstr ""
 
-#: builtin/pull.c:415
+#: builtin/pull.c:420
 msgid ""
 "There is no candidate for rebasing against among the refs that you just "
 "fetched."
 msgstr ""
 
-#: builtin/pull.c:417
+#: builtin/pull.c:422
 msgid ""
 "There are no candidates for merging among the refs that you just fetched."
 msgstr ""
 
-#: builtin/pull.c:418
+#: builtin/pull.c:423
 msgid ""
 "Generally this means that you provided a wildcard refspec which had no\n"
 "matches on the remote end."
 msgstr ""
 
-#: builtin/pull.c:421
+#: builtin/pull.c:426
 #, c-format
 msgid ""
 "You asked to pull from the remote '%s', but did not specify\n"
@@ -11048,69 +11486,69 @@ msgid ""
 "for your current branch, you must specify a branch on the command line."
 msgstr ""
 
-#: builtin/pull.c:426 git-parse-remote.sh:73
+#: builtin/pull.c:431 git-parse-remote.sh:73
 msgid "You are not currently on a branch."
 msgstr ""
 
-#: builtin/pull.c:428 builtin/pull.c:443 git-parse-remote.sh:79
+#: builtin/pull.c:433 builtin/pull.c:448 git-parse-remote.sh:79
 msgid "Please specify which branch you want to rebase against."
 msgstr ""
 
-#: builtin/pull.c:430 builtin/pull.c:445 git-parse-remote.sh:82
+#: builtin/pull.c:435 builtin/pull.c:450 git-parse-remote.sh:82
 msgid "Please specify which branch you want to merge with."
 msgstr ""
 
-#: builtin/pull.c:431 builtin/pull.c:446
+#: builtin/pull.c:436 builtin/pull.c:451
 msgid "See git-pull(1) for details."
 msgstr ""
 
-#: builtin/pull.c:433 builtin/pull.c:439 builtin/pull.c:448
+#: builtin/pull.c:438 builtin/pull.c:444 builtin/pull.c:453
 #: git-parse-remote.sh:64
 msgid "<remote>"
 msgstr ""
 
-#: builtin/pull.c:433 builtin/pull.c:448 builtin/pull.c:453 git-rebase.sh:477
+#: builtin/pull.c:438 builtin/pull.c:453 builtin/pull.c:458 git-rebase.sh:523
 #: git-parse-remote.sh:65
 msgid "<branch>"
 msgstr ""
 
-#: builtin/pull.c:441 git-parse-remote.sh:75
+#: builtin/pull.c:446 git-parse-remote.sh:75
 msgid "There is no tracking information for the current branch."
 msgstr ""
 
-#: builtin/pull.c:450 git-parse-remote.sh:95
+#: builtin/pull.c:455 git-parse-remote.sh:95
 msgid ""
 "If you wish to set tracking information for this branch you can do so with:"
 msgstr ""
 
-#: builtin/pull.c:455
+#: builtin/pull.c:460
 #, c-format
 msgid ""
 "Your configuration specifies to merge with the ref '%s'\n"
 "from the remote, but no such ref was fetched."
 msgstr ""
 
-#: builtin/pull.c:819
+#: builtin/pull.c:826
 msgid "ignoring --verify-signatures for rebase"
 msgstr ""
 
-#: builtin/pull.c:867
+#: builtin/pull.c:874
 msgid "--[no-]autostash option is only valid with --rebase."
 msgstr ""
 
-#: builtin/pull.c:875
+#: builtin/pull.c:882
 msgid "Updating an unborn branch with changes added to the index."
 msgstr ""
 
-#: builtin/pull.c:878
+#: builtin/pull.c:885
 msgid "pull with rebase"
 msgstr ""
 
-#: builtin/pull.c:879
+#: builtin/pull.c:886
 msgid "please commit or stash them."
 msgstr ""
 
-#: builtin/pull.c:904
+#: builtin/pull.c:911
 #, c-format
 msgid ""
 "fetch updated the current branch head.\n"
@@ -11118,7 +11556,7 @@ msgid ""
 "commit %s."
 msgstr ""
 
-#: builtin/pull.c:909
+#: builtin/pull.c:916
 #, c-format
 msgid ""
 "Cannot fast-forward your working tree.\n"
@@ -11129,37 +11567,37 @@ msgid ""
 "to recover."
 msgstr ""
 
-#: builtin/pull.c:924
+#: builtin/pull.c:931
 msgid "Cannot merge multiple branches into empty head."
 msgstr ""
 
-#: builtin/pull.c:928
+#: builtin/pull.c:935
 msgid "Cannot rebase onto multiple branches."
 msgstr ""
 
-#: builtin/pull.c:935
+#: builtin/pull.c:942
 msgid "cannot rebase with locally recorded submodule modifications"
 msgstr ""
 
-#: builtin/push.c:17
+#: builtin/push.c:19
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr ""
 
-#: builtin/push.c:92
+#: builtin/push.c:111
 msgid "tag shorthand without <tag>"
 msgstr ""
 
-#: builtin/push.c:102
+#: builtin/push.c:121
 msgid "--delete only accepts plain target ref names"
 msgstr ""
 
-#: builtin/push.c:146
+#: builtin/push.c:165
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
 msgstr ""
 
-#: builtin/push.c:149
+#: builtin/push.c:168
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -11174,7 +11612,7 @@ msgid ""
 "%s"
 msgstr ""
 
-#: builtin/push.c:164
+#: builtin/push.c:183
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -11184,7 +11622,7 @@ msgid ""
 "    git push %s HEAD:<name-of-remote-branch>\n"
 msgstr ""
 
-#: builtin/push.c:178
+#: builtin/push.c:197
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -11193,12 +11631,12 @@ msgid ""
 "    git push --set-upstream %s %s\n"
 msgstr ""
 
-#: builtin/push.c:186
+#: builtin/push.c:205
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr ""
 
-#: builtin/push.c:189
+#: builtin/push.c:208
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -11206,12 +11644,12 @@ msgid ""
 "to update which remote branch."
 msgstr ""
 
-#: builtin/push.c:248
+#: builtin/push.c:267
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
 
-#: builtin/push.c:255
+#: builtin/push.c:274
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -11219,7 +11657,7 @@ msgid ""
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
 
-#: builtin/push.c:261
+#: builtin/push.c:280
 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"
@@ -11227,7 +11665,7 @@ msgid ""
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
 
-#: builtin/push.c:267
+#: builtin/push.c:286
 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"
@@ -11236,33 +11674,33 @@ msgid ""
 "See the 'Note about fast-forwards' in 'git push --help' for details."
 msgstr ""
 
-#: builtin/push.c:274
+#: builtin/push.c:293
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr ""
 
-#: builtin/push.c:277
+#: builtin/push.c:296
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
 "without using the '--force' option.\n"
 msgstr ""
 
-#: builtin/push.c:337
+#: builtin/push.c:357
 #, c-format
 msgid "Pushing to %s\n"
 msgstr ""
 
-#: builtin/push.c:341
+#: builtin/push.c:361
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr ""
 
-#: builtin/push.c:372
+#: builtin/push.c:395
 #, c-format
 msgid "bad repository '%s'"
 msgstr ""
 
-#: builtin/push.c:373
+#: builtin/push.c:396
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -11275,112 +11713,104 @@ msgid ""
 "    git push <name>\n"
 msgstr ""
 
-#: builtin/push.c:391
-msgid "--all and --tags are incompatible"
-msgstr ""
-
-#: builtin/push.c:392
-msgid "--all can't be combined with refspecs"
-msgstr ""
-
-#: builtin/push.c:397
-msgid "--mirror and --tags are incompatible"
-msgstr ""
-
-#: builtin/push.c:398
-msgid "--mirror can't be combined with refspecs"
-msgstr ""
-
-#: builtin/push.c:403
-msgid "--all and --mirror are incompatible"
-msgstr ""
-
-#: builtin/push.c:535
+#: builtin/push.c:551
 msgid "repository"
 msgstr ""
 
-#: builtin/push.c:536 builtin/send-pack.c:163
+#: builtin/push.c:552 builtin/send-pack.c:164
 msgid "push all refs"
 msgstr ""
 
-#: builtin/push.c:537 builtin/send-pack.c:165
+#: builtin/push.c:553 builtin/send-pack.c:166
 msgid "mirror all refs"
 msgstr ""
 
-#: builtin/push.c:539
+#: builtin/push.c:555
 msgid "delete refs"
 msgstr ""
 
-#: builtin/push.c:540
+#: builtin/push.c:556
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr ""
 
-#: builtin/push.c:543 builtin/send-pack.c:166
+#: builtin/push.c:559 builtin/send-pack.c:167
 msgid "force updates"
 msgstr ""
 
-#: builtin/push.c:545 builtin/send-pack.c:180
+#: builtin/push.c:561 builtin/send-pack.c:181
 msgid "refname>:<expect"
 msgstr ""
 
-#: builtin/push.c:546 builtin/send-pack.c:181
+#: builtin/push.c:562 builtin/send-pack.c:182
 msgid "require old value of ref to be at this value"
 msgstr ""
 
-#: builtin/push.c:549
+#: builtin/push.c:565
 msgid "control recursive pushing of submodules"
 msgstr ""
 
-#: builtin/push.c:551 builtin/send-pack.c:174
+#: builtin/push.c:567 builtin/send-pack.c:175
 msgid "use thin pack"
 msgstr ""
 
-#: builtin/push.c:552 builtin/push.c:553 builtin/send-pack.c:160
-#: builtin/send-pack.c:161
+#: builtin/push.c:568 builtin/push.c:569 builtin/send-pack.c:161
+#: builtin/send-pack.c:162
 msgid "receive pack program"
 msgstr ""
 
-#: builtin/push.c:554
+#: builtin/push.c:570
 msgid "set upstream for git pull/status"
 msgstr ""
 
-#: builtin/push.c:557
+#: builtin/push.c:573
 msgid "prune locally removed refs"
 msgstr ""
 
-#: builtin/push.c:559
+#: builtin/push.c:575
 msgid "bypass pre-push hook"
 msgstr ""
 
-#: builtin/push.c:560
+#: builtin/push.c:576
 msgid "push missing but relevant tags"
 msgstr ""
 
-#: builtin/push.c:563 builtin/send-pack.c:168
+#: builtin/push.c:579 builtin/send-pack.c:169
 msgid "GPG sign the push"
 msgstr ""
 
-#: builtin/push.c:565 builtin/send-pack.c:175
+#: builtin/push.c:581 builtin/send-pack.c:176
 msgid "request atomic transaction on remote side"
 msgstr ""
 
-#: builtin/push.c:566 builtin/send-pack.c:171
-msgid "server-specific"
+#: builtin/push.c:599
+msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr ""
 
-#: builtin/push.c:566 builtin/send-pack.c:172
-msgid "option to transmit"
+#: builtin/push.c:601
+msgid "--delete doesn't make sense without any refs"
 msgstr ""
 
-#: builtin/push.c:583
-msgid "--delete is incompatible with --all, --mirror and --tags"
+#: builtin/push.c:604
+msgid "--all and --tags are incompatible"
 msgstr ""
 
-#: builtin/push.c:585
-msgid "--delete doesn't make sense without any refs"
+#: builtin/push.c:606
+msgid "--all can't be combined with refspecs"
 msgstr ""
 
-#: builtin/push.c:604
+#: builtin/push.c:610
+msgid "--mirror and --tags are incompatible"
+msgstr ""
+
+#: builtin/push.c:612
+msgid "--mirror can't be combined with refspecs"
+msgstr ""
+
+#: builtin/push.c:615
+msgid "--all and --mirror are incompatible"
+msgstr ""
+
+#: builtin/push.c:634
 msgid "push options must not have new line characters"
 msgstr ""
 
@@ -11391,67 +11821,67 @@ msgid ""
 "index-output=<file>] (--empty | <tree-ish1> [<tree-ish2> [<tree-ish3>]])"
 msgstr ""
 
-#: builtin/read-tree.c:121
+#: builtin/read-tree.c:120
 msgid "write resulting index to <file>"
 msgstr ""
 
-#: builtin/read-tree.c:124
+#: builtin/read-tree.c:123
 msgid "only empty the index"
 msgstr ""
 
-#: builtin/read-tree.c:126
+#: builtin/read-tree.c:125
 msgid "Merging"
 msgstr ""
 
-#: builtin/read-tree.c:128
+#: builtin/read-tree.c:127
 msgid "perform a merge in addition to a read"
 msgstr ""
 
-#: builtin/read-tree.c:130
+#: builtin/read-tree.c:129
 msgid "3-way merge if no file level merging required"
 msgstr ""
 
-#: builtin/read-tree.c:132
+#: builtin/read-tree.c:131
 msgid "3-way merge in presence of adds and removes"
 msgstr ""
 
-#: builtin/read-tree.c:134
+#: builtin/read-tree.c:133
 msgid "same as -m, but discard unmerged entries"
 msgstr ""
 
-#: builtin/read-tree.c:135
+#: builtin/read-tree.c:134
 msgid "<subdirectory>/"
 msgstr ""
 
-#: builtin/read-tree.c:136
+#: builtin/read-tree.c:135
 msgid "read the tree into the index under <subdirectory>/"
 msgstr ""
 
-#: builtin/read-tree.c:139
+#: builtin/read-tree.c:138
 msgid "update working tree with merge result"
 msgstr ""
 
-#: builtin/read-tree.c:141
+#: builtin/read-tree.c:140
 msgid "gitignore"
 msgstr ""
 
-#: builtin/read-tree.c:142
+#: builtin/read-tree.c:141
 msgid "allow explicitly ignored files to be overwritten"
 msgstr ""
 
-#: builtin/read-tree.c:145
+#: builtin/read-tree.c:144
 msgid "don't check the working tree after merging"
 msgstr ""
 
-#: builtin/read-tree.c:146
+#: builtin/read-tree.c:145
 msgid "don't update the index or the work tree"
 msgstr ""
 
-#: builtin/read-tree.c:148
+#: builtin/read-tree.c:147
 msgid "skip applying sparse checkout filter"
 msgstr ""
 
-#: builtin/read-tree.c:150
+#: builtin/read-tree.c:149
 msgid "debug unpack-trees"
 msgstr ""
 
@@ -11468,46 +11898,58 @@ msgid "allow commits with empty messages"
 msgstr ""
 
 #: builtin/rebase--helper.c:27
-msgid "continue rebase"
+msgid "rebase merge commits"
 msgstr ""
 
 #: builtin/rebase--helper.c:29
-msgid "abort rebase"
+msgid "keep original branch points of cousins"
+msgstr ""
+
+#: builtin/rebase--helper.c:30
+msgid "continue rebase"
 msgstr ""
 
 #: builtin/rebase--helper.c:32
+msgid "abort rebase"
+msgstr ""
+
+#: builtin/rebase--helper.c:35
 msgid "make rebase script"
 msgstr ""
 
-#: builtin/rebase--helper.c:34
+#: builtin/rebase--helper.c:37
 msgid "shorten commit ids in the todo list"
 msgstr ""
 
-#: builtin/rebase--helper.c:36
+#: builtin/rebase--helper.c:39
 msgid "expand commit ids in the todo list"
 msgstr ""
 
-#: builtin/rebase--helper.c:38
+#: builtin/rebase--helper.c:41
 msgid "check the todo list"
 msgstr ""
 
-#: builtin/rebase--helper.c:40
+#: builtin/rebase--helper.c:43
 msgid "skip unnecessary picks"
 msgstr ""
 
-#: builtin/rebase--helper.c:42
+#: builtin/rebase--helper.c:45
 msgid "rearrange fixup/squash lines"
 msgstr ""
 
-#: builtin/rebase--helper.c:44
+#: builtin/rebase--helper.c:47
 msgid "insert exec commands in todo list"
 msgstr ""
 
-#: builtin/receive-pack.c:30
+#: builtin/rebase--helper.c:68
+msgid "--[no-]rebase-cousins has no effect without --rebase-merges"
+msgstr ""
+
+#: builtin/receive-pack.c:31
 msgid "git receive-pack <git-dir>"
 msgstr ""
 
-#: builtin/receive-pack.c:841
+#: builtin/receive-pack.c:842
 msgid ""
 "By default, updating the current branch in a non-bare repository\n"
 "is denied, because it will make the index and work tree inconsistent\n"
@@ -11524,7 +11966,7 @@ msgid ""
 "'receive.denyCurrentBranch' configuration variable to 'refuse'."
 msgstr ""
 
-#: builtin/receive-pack.c:861
+#: builtin/receive-pack.c:862
 msgid ""
 "By default, deleting the current branch is denied, because the next\n"
 "'git clone' won't result in any file checked out, causing confusion.\n"
@@ -11536,11 +11978,11 @@ msgid ""
 "To squelch this message, you can set it to 'refuse'."
 msgstr ""
 
-#: builtin/receive-pack.c:1934
+#: builtin/receive-pack.c:1935
 msgid "quiet"
 msgstr ""
 
-#: builtin/receive-pack.c:1948
+#: builtin/receive-pack.c:1949
 msgid "You must specify a directory."
 msgstr ""
 
@@ -11549,176 +11991,176 @@ msgstr ""
 msgid "'%s' is not a valid timestamp"
 msgstr ""
 
-#: builtin/remote.c:13
+#: builtin/remote.c:14
 msgid "git remote [-v | --verbose]"
 msgstr ""
 
-#: builtin/remote.c:14
+#: builtin/remote.c:15
 msgid ""
 "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <name> <url>"
 msgstr ""
 
-#: builtin/remote.c:15 builtin/remote.c:35
+#: builtin/remote.c:16 builtin/remote.c:36
 msgid "git remote rename <old> <new>"
 msgstr ""
 
-#: builtin/remote.c:16 builtin/remote.c:40
+#: builtin/remote.c:17 builtin/remote.c:41
 msgid "git remote remove <name>"
 msgstr ""
 
-#: builtin/remote.c:17 builtin/remote.c:45
+#: builtin/remote.c:18 builtin/remote.c:46
 msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
 msgstr ""
 
-#: builtin/remote.c:18
+#: builtin/remote.c:19
 msgid "git remote [-v | --verbose] show [-n] <name>"
 msgstr ""
 
-#: builtin/remote.c:19
+#: builtin/remote.c:20
 msgid "git remote prune [-n | --dry-run] <name>"
 msgstr ""
 
-#: builtin/remote.c:20
+#: builtin/remote.c:21
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
 msgstr ""
 
-#: builtin/remote.c:21
+#: builtin/remote.c:22
 msgid "git remote set-branches [--add] <name> <branch>..."
 msgstr ""
 
-#: builtin/remote.c:22 builtin/remote.c:71
+#: builtin/remote.c:23 builtin/remote.c:72
 msgid "git remote get-url [--push] [--all] <name>"
 msgstr ""
 
-#: builtin/remote.c:23 builtin/remote.c:76
+#: builtin/remote.c:24 builtin/remote.c:77
 msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]"
 msgstr ""
 
-#: builtin/remote.c:24 builtin/remote.c:77
+#: builtin/remote.c:25 builtin/remote.c:78
 msgid "git remote set-url --add <name> <newurl>"
 msgstr ""
 
-#: builtin/remote.c:25 builtin/remote.c:78
+#: builtin/remote.c:26 builtin/remote.c:79
 msgid "git remote set-url --delete <name> <url>"
 msgstr ""
 
-#: builtin/remote.c:30
+#: builtin/remote.c:31
 msgid "git remote add [<options>] <name> <url>"
 msgstr ""
 
-#: builtin/remote.c:50
+#: builtin/remote.c:51
 msgid "git remote set-branches <name> <branch>..."
 msgstr ""
 
-#: builtin/remote.c:51
+#: builtin/remote.c:52
 msgid "git remote set-branches --add <name> <branch>..."
 msgstr ""
 
-#: builtin/remote.c:56
+#: builtin/remote.c:57
 msgid "git remote show [<options>] <name>"
 msgstr ""
 
-#: builtin/remote.c:61
+#: builtin/remote.c:62
 msgid "git remote prune [<options>] <name>"
 msgstr ""
 
-#: builtin/remote.c:66
+#: builtin/remote.c:67
 msgid "git remote update [<options>] [<group> | <remote>]..."
 msgstr ""
 
-#: builtin/remote.c:95
+#: builtin/remote.c:96
 #, c-format
 msgid "Updating %s"
 msgstr ""
 
-#: builtin/remote.c:127
+#: builtin/remote.c:128
 msgid ""
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
 msgstr ""
 
-#: builtin/remote.c:144
+#: builtin/remote.c:145
 #, c-format
 msgid "unknown mirror argument: %s"
 msgstr ""
 
-#: builtin/remote.c:160
+#: builtin/remote.c:161
 msgid "fetch the remote branches"
 msgstr ""
 
-#: builtin/remote.c:162
+#: builtin/remote.c:163
 msgid "import all tags and associated objects when fetching"
 msgstr ""
 
-#: builtin/remote.c:165
+#: builtin/remote.c:166
 msgid "or do not fetch any tag at all (--no-tags)"
 msgstr ""
 
-#: builtin/remote.c:167
+#: builtin/remote.c:168
 msgid "branch(es) to track"
 msgstr ""
 
-#: builtin/remote.c:168
+#: builtin/remote.c:169
 msgid "master branch"
 msgstr ""
 
-#: builtin/remote.c:169
+#: builtin/remote.c:170
 msgid "push|fetch"
 msgstr ""
 
-#: builtin/remote.c:170
+#: builtin/remote.c:171
 msgid "set up remote as a mirror to push to or fetch from"
 msgstr ""
 
-#: builtin/remote.c:182
+#: builtin/remote.c:183
 msgid "specifying a master branch makes no sense with --mirror"
 msgstr ""
 
-#: builtin/remote.c:184
+#: builtin/remote.c:185
 msgid "specifying branches to track makes sense only with fetch mirrors"
 msgstr ""
 
-#: builtin/remote.c:191 builtin/remote.c:631
+#: builtin/remote.c:192 builtin/remote.c:634
 #, c-format
 msgid "remote %s already exists."
 msgstr ""
 
-#: builtin/remote.c:195 builtin/remote.c:635
+#: builtin/remote.c:196 builtin/remote.c:638
 #, c-format
 msgid "'%s' is not a valid remote name"
 msgstr ""
 
-#: builtin/remote.c:235
+#: builtin/remote.c:236
 #, c-format
 msgid "Could not setup master '%s'"
 msgstr ""
 
-#: builtin/remote.c:337
+#: builtin/remote.c:342
 #, c-format
 msgid "Could not get fetch map for refspec %s"
 msgstr ""
 
-#: builtin/remote.c:438 builtin/remote.c:446
+#: builtin/remote.c:441 builtin/remote.c:449
 msgid "(matching)"
 msgstr ""
 
-#: builtin/remote.c:450
+#: builtin/remote.c:453
 msgid "(delete)"
 msgstr ""
 
-#: builtin/remote.c:624 builtin/remote.c:759 builtin/remote.c:858
+#: builtin/remote.c:627 builtin/remote.c:762 builtin/remote.c:861
 #, c-format
 msgid "No such remote: %s"
 msgstr ""
 
-#: builtin/remote.c:641
+#: builtin/remote.c:644
 #, c-format
 msgid "Could not rename config section '%s' to '%s'"
 msgstr ""
 
-#: builtin/remote.c:661
+#: builtin/remote.c:664
 #, c-format
 msgid ""
 "Not updating non-default fetch refspec\n"
@@ -11726,17 +12168,17 @@ msgid ""
 "\tPlease update the configuration manually if necessary."
 msgstr ""
 
-#: builtin/remote.c:697
+#: builtin/remote.c:700
 #, c-format
 msgid "deleting '%s' failed"
 msgstr ""
 
-#: builtin/remote.c:731
+#: builtin/remote.c:734
 #, c-format
 msgid "creating '%s' failed"
 msgstr ""
 
-#: builtin/remote.c:796
+#: builtin/remote.c:799
 msgid ""
 "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
 "to delete it, use:"
@@ -11746,113 +12188,118 @@ msgid_plural ""
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/remote.c:810
+#: builtin/remote.c:813
 #, c-format
 msgid "Could not remove config section '%s'"
 msgstr ""
 
-#: builtin/remote.c:911
+#: builtin/remote.c:914
 #, c-format
 msgid " new (next fetch will store in remotes/%s)"
 msgstr ""
 
-#: builtin/remote.c:914
+#: builtin/remote.c:917
 msgid " tracked"
 msgstr ""
 
-#: builtin/remote.c:916
+#: builtin/remote.c:919
 msgid " stale (use 'git remote prune' to remove)"
 msgstr ""
 
-#: builtin/remote.c:918
+#: builtin/remote.c:921
 msgid " ???"
 msgstr ""
 
-#: builtin/remote.c:959
+#: builtin/remote.c:962
 #, c-format
 msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
 msgstr ""
 
-#: builtin/remote.c:967
+#: builtin/remote.c:971
 #, c-format
 msgid "rebases interactively onto remote %s"
 msgstr ""
 
-#: builtin/remote.c:968
+#: builtin/remote.c:973
+#, c-format
+msgid "rebases interactively (with merges) onto remote %s"
+msgstr ""
+
+#: builtin/remote.c:976
 #, c-format
 msgid "rebases onto remote %s"
 msgstr ""
 
-#: builtin/remote.c:971
+#: builtin/remote.c:980
 #, c-format
 msgid " merges with remote %s"
 msgstr ""
 
-#: builtin/remote.c:974
+#: builtin/remote.c:983
 #, c-format
 msgid "merges with remote %s"
 msgstr ""
 
-#: builtin/remote.c:977
+#: builtin/remote.c:986
 #, c-format
 msgid "%-*s    and with remote %s\n"
 msgstr ""
 
-#: builtin/remote.c:1020
+#: builtin/remote.c:1029
 msgid "create"
 msgstr ""
 
-#: builtin/remote.c:1023
+#: builtin/remote.c:1032
 msgid "delete"
 msgstr ""
 
-#: builtin/remote.c:1027
+#: builtin/remote.c:1036
 msgid "up to date"
 msgstr ""
 
-#: builtin/remote.c:1030
+#: builtin/remote.c:1039
 msgid "fast-forwardable"
 msgstr ""
 
-#: builtin/remote.c:1033
+#: builtin/remote.c:1042
 msgid "local out of date"
 msgstr ""
 
-#: builtin/remote.c:1040
+#: builtin/remote.c:1049
 #, c-format
 msgid "    %-*s forces to %-*s (%s)"
 msgstr ""
 
-#: builtin/remote.c:1043
+#: builtin/remote.c:1052
 #, c-format
 msgid "    %-*s pushes to %-*s (%s)"
 msgstr ""
 
-#: builtin/remote.c:1047
+#: builtin/remote.c:1056
 #, c-format
 msgid "    %-*s forces to %s"
 msgstr ""
 
-#: builtin/remote.c:1050
+#: builtin/remote.c:1059
 #, c-format
 msgid "    %-*s pushes to %s"
 msgstr ""
 
-#: builtin/remote.c:1118
+#: builtin/remote.c:1127
 msgid "do not query remotes"
 msgstr ""
 
-#: builtin/remote.c:1145
+#: builtin/remote.c:1154
 #, c-format
 msgid "* remote %s"
 msgstr ""
 
-#: builtin/remote.c:1146
+#: builtin/remote.c:1155
 #, c-format
 msgid "  Fetch URL: %s"
 msgstr ""
 
-#: builtin/remote.c:1147 builtin/remote.c:1163 builtin/remote.c:1302
+#: builtin/remote.c:1156 builtin/remote.c:1172 builtin/remote.c:1311
 msgid "(no URL)"
 msgstr ""
 
@@ -11860,184 +12307,184 @@ msgstr ""
 #. with the one in " Fetch URL: %s"
 #. translation.
 #.
-#: builtin/remote.c:1161 builtin/remote.c:1163
+#: builtin/remote.c:1170 builtin/remote.c:1172
 #, c-format
 msgid "  Push  URL: %s"
 msgstr ""
 
-#: builtin/remote.c:1165 builtin/remote.c:1167 builtin/remote.c:1169
+#: builtin/remote.c:1174 builtin/remote.c:1176 builtin/remote.c:1178
 #, c-format
 msgid "  HEAD branch: %s"
 msgstr ""
 
-#: builtin/remote.c:1165
+#: builtin/remote.c:1174
 msgid "(not queried)"
 msgstr ""
 
-#: builtin/remote.c:1167
+#: builtin/remote.c:1176
 msgid "(unknown)"
 msgstr ""
 
-#: builtin/remote.c:1171
+#: builtin/remote.c:1180
 #, c-format
 msgid ""
 "  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
 msgstr ""
 
-#: builtin/remote.c:1183
+#: builtin/remote.c:1192
 #, c-format
 msgid "  Remote branch:%s"
 msgid_plural "  Remote branches:%s"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/remote.c:1186 builtin/remote.c:1212
+#: builtin/remote.c:1195 builtin/remote.c:1221
 msgid " (status not queried)"
 msgstr ""
 
-#: builtin/remote.c:1195
+#: builtin/remote.c:1204
 msgid "  Local branch configured for 'git pull':"
 msgid_plural "  Local branches configured for 'git pull':"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/remote.c:1203
+#: builtin/remote.c:1212
 msgid "  Local refs will be mirrored by 'git push'"
 msgstr ""
 
-#: builtin/remote.c:1209
+#: builtin/remote.c:1218
 #, c-format
 msgid "  Local ref configured for 'git push'%s:"
 msgid_plural "  Local refs configured for 'git push'%s:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/remote.c:1230
+#: builtin/remote.c:1239
 msgid "set refs/remotes/<name>/HEAD according to remote"
 msgstr ""
 
-#: builtin/remote.c:1232
+#: builtin/remote.c:1241
 msgid "delete refs/remotes/<name>/HEAD"
 msgstr ""
 
-#: builtin/remote.c:1247
+#: builtin/remote.c:1256
 msgid "Cannot determine remote HEAD"
 msgstr ""
 
-#: builtin/remote.c:1249
+#: builtin/remote.c:1258
 msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
 msgstr ""
 
-#: builtin/remote.c:1259
+#: builtin/remote.c:1268
 #, c-format
 msgid "Could not delete %s"
 msgstr ""
 
-#: builtin/remote.c:1267
+#: builtin/remote.c:1276
 #, c-format
 msgid "Not a valid ref: %s"
 msgstr ""
 
-#: builtin/remote.c:1269
+#: builtin/remote.c:1278
 #, c-format
 msgid "Could not setup %s"
 msgstr ""
 
-#: builtin/remote.c:1287
+#: builtin/remote.c:1296
 #, c-format
 msgid " %s will become dangling!"
 msgstr ""
 
-#: builtin/remote.c:1288
+#: builtin/remote.c:1297
 #, c-format
 msgid " %s has become dangling!"
 msgstr ""
 
-#: builtin/remote.c:1298
+#: builtin/remote.c:1307
 #, c-format
 msgid "Pruning %s"
 msgstr ""
 
-#: builtin/remote.c:1299
+#: builtin/remote.c:1308
 #, c-format
 msgid "URL: %s"
 msgstr ""
 
-#: builtin/remote.c:1315
+#: builtin/remote.c:1324
 #, c-format
 msgid " * [would prune] %s"
 msgstr ""
 
-#: builtin/remote.c:1318
+#: builtin/remote.c:1327
 #, c-format
 msgid " * [pruned] %s"
 msgstr ""
 
-#: builtin/remote.c:1363
+#: builtin/remote.c:1372
 msgid "prune remotes after fetching"
 msgstr ""
 
-#: builtin/remote.c:1426 builtin/remote.c:1480 builtin/remote.c:1548
+#: builtin/remote.c:1435 builtin/remote.c:1489 builtin/remote.c:1557
 #, c-format
 msgid "No such remote '%s'"
 msgstr ""
 
-#: builtin/remote.c:1442
+#: builtin/remote.c:1451
 msgid "add branch"
 msgstr ""
 
-#: builtin/remote.c:1449
+#: builtin/remote.c:1458
 msgid "no remote specified"
 msgstr ""
 
-#: builtin/remote.c:1466
+#: builtin/remote.c:1475
 msgid "query push URLs rather than fetch URLs"
 msgstr ""
 
-#: builtin/remote.c:1468
+#: builtin/remote.c:1477
 msgid "return all URLs"
 msgstr ""
 
-#: builtin/remote.c:1496
+#: builtin/remote.c:1505
 #, c-format
 msgid "no URLs configured for remote '%s'"
 msgstr ""
 
-#: builtin/remote.c:1522
+#: builtin/remote.c:1531
 msgid "manipulate push URLs"
 msgstr ""
 
-#: builtin/remote.c:1524
+#: builtin/remote.c:1533
 msgid "add URL"
 msgstr ""
 
-#: builtin/remote.c:1526
+#: builtin/remote.c:1535
 msgid "delete URLs"
 msgstr ""
 
-#: builtin/remote.c:1533
+#: builtin/remote.c:1542
 msgid "--add --delete doesn't make sense"
 msgstr ""
 
-#: builtin/remote.c:1572
+#: builtin/remote.c:1581
 #, c-format
 msgid "Invalid old URL pattern: %s"
 msgstr ""
 
-#: builtin/remote.c:1580
+#: builtin/remote.c:1589
 #, c-format
 msgid "No such URL found: %s"
 msgstr ""
 
-#: builtin/remote.c:1582
+#: builtin/remote.c:1591
 msgid "Will not delete all non-push URLs"
 msgstr ""
 
-#: builtin/remote.c:1598
+#: builtin/remote.c:1607
 msgid "be verbose; must be placed before a subcommand"
 msgstr ""
 
-#: builtin/remote.c:1629
+#: builtin/remote.c:1638
 #, c-format
 msgid "Unknown subcommand: %s"
 msgstr ""
@@ -12052,172 +12499,191 @@ msgid ""
 "--no-write-bitmap-index or disable the pack.writebitmaps configuration."
 msgstr ""
 
-#: builtin/repack.c:170
+#: builtin/repack.c:180
 msgid "pack everything in a single pack"
 msgstr ""
 
-#: builtin/repack.c:172
+#: builtin/repack.c:182
 msgid "same as -a, and turn unreachable objects loose"
 msgstr ""
 
-#: builtin/repack.c:175
+#: builtin/repack.c:185
 msgid "remove redundant packs, and run git-prune-packed"
 msgstr ""
 
-#: builtin/repack.c:177
+#: builtin/repack.c:187
 msgid "pass --no-reuse-delta to git-pack-objects"
 msgstr ""
 
-#: builtin/repack.c:179
+#: builtin/repack.c:189
 msgid "pass --no-reuse-object to git-pack-objects"
 msgstr ""
 
-#: builtin/repack.c:181
+#: builtin/repack.c:191
 msgid "do not run git-update-server-info"
 msgstr ""
 
-#: builtin/repack.c:184
+#: builtin/repack.c:194
 msgid "pass --local to git-pack-objects"
 msgstr ""
 
-#: builtin/repack.c:186
+#: builtin/repack.c:196
 msgid "write bitmap index"
 msgstr ""
 
-#: builtin/repack.c:187
+#: builtin/repack.c:197
 msgid "approxidate"
 msgstr ""
 
-#: builtin/repack.c:188
+#: builtin/repack.c:198
 msgid "with -A, do not loosen objects older than this"
 msgstr ""
 
-#: builtin/repack.c:190
+#: builtin/repack.c:200
 msgid "with -a, repack unreachable objects"
 msgstr ""
 
-#: builtin/repack.c:192
+#: builtin/repack.c:202
 msgid "size of the window used for delta compression"
 msgstr ""
 
-#: builtin/repack.c:193 builtin/repack.c:199
+#: builtin/repack.c:203 builtin/repack.c:209
 msgid "bytes"
 msgstr ""
 
-#: builtin/repack.c:194
+#: builtin/repack.c:204
 msgid "same as the above, but limit memory size instead of entries count"
 msgstr ""
 
-#: builtin/repack.c:196
+#: builtin/repack.c:206
 msgid "limits the maximum delta depth"
 msgstr ""
 
-#: builtin/repack.c:198
+#: builtin/repack.c:208
 msgid "limits the maximum number of threads"
 msgstr ""
 
-#: builtin/repack.c:200
+#: builtin/repack.c:210
 msgid "maximum size of each packfile"
 msgstr ""
 
-#: builtin/repack.c:202
+#: builtin/repack.c:212
 msgid "repack objects in packs marked with .keep"
 msgstr ""
 
-#: builtin/repack.c:212
+#: builtin/repack.c:214
+msgid "do not repack this pack"
+msgstr ""
+
+#: builtin/repack.c:224
 msgid "cannot delete packs in a precious-objects repo"
 msgstr ""
 
-#: builtin/repack.c:216
+#: builtin/repack.c:228
 msgid "--keep-unreachable and -A are incompatible"
 msgstr ""
 
-#: builtin/repack.c:410 builtin/worktree.c:148
+#: builtin/repack.c:425 builtin/worktree.c:139
 #, c-format
 msgid "failed to remove '%s'"
 msgstr ""
 
-#: builtin/replace.c:20
+#: builtin/replace.c:22
 msgid "git replace [-f] <object> <replacement>"
 msgstr ""
 
-#: builtin/replace.c:21
+#: builtin/replace.c:23
 msgid "git replace [-f] --edit <object>"
 msgstr ""
 
-#: builtin/replace.c:22
+#: builtin/replace.c:24
 msgid "git replace [-f] --graft <commit> [<parent>...]"
 msgstr ""
 
-#: builtin/replace.c:23
+#: builtin/replace.c:25
+msgid "git replace [-f] --convert-graft-file"
+msgstr ""
+
+#: builtin/replace.c:26
 msgid "git replace -d <object>..."
 msgstr ""
 
-#: builtin/replace.c:24
+#: builtin/replace.c:27
 msgid "git replace [--format=<format>] [-l [<pattern>]]"
 msgstr ""
 
-#: builtin/replace.c:331 builtin/replace.c:369 builtin/replace.c:397
+#: builtin/replace.c:371 builtin/replace.c:415 builtin/replace.c:445
 #, c-format
 msgid "Not a valid object name: '%s'"
 msgstr ""
 
-#: builtin/replace.c:361
+#: builtin/replace.c:407
 #, c-format
 msgid "bad mergetag in commit '%s'"
 msgstr ""
 
-#: builtin/replace.c:363
+#: builtin/replace.c:409
 #, c-format
 msgid "malformed mergetag in commit '%s'"
 msgstr ""
 
-#: builtin/replace.c:374
+#: builtin/replace.c:421
 #, c-format
 msgid ""
 "original commit '%s' contains mergetag '%s' that is discarded; use --edit "
 "instead of --graft"
 msgstr ""
 
-#: builtin/replace.c:407
+#: builtin/replace.c:460
 #, c-format
 msgid "the original commit '%s' has a gpg signature."
 msgstr ""
 
-#: builtin/replace.c:408
+#: builtin/replace.c:461
 msgid "the signature will be removed in the replacement commit!"
 msgstr ""
 
-#: builtin/replace.c:414
+#: builtin/replace.c:471
 #, c-format
 msgid "could not write replacement commit for: '%s'"
 msgstr ""
 
-#: builtin/replace.c:438
+#: builtin/replace.c:514
+#, c-format
+msgid ""
+"could not convert the following graft(s):\n"
+"%s"
+msgstr ""
+
+#: builtin/replace.c:535
 msgid "list replace refs"
 msgstr ""
 
-#: builtin/replace.c:439
+#: builtin/replace.c:536
 msgid "delete replace refs"
 msgstr ""
 
-#: builtin/replace.c:440
+#: builtin/replace.c:537
 msgid "edit existing object"
 msgstr ""
 
-#: builtin/replace.c:441
+#: builtin/replace.c:538
 msgid "change a commit's parents"
 msgstr ""
 
-#: builtin/replace.c:442
+#: builtin/replace.c:539
+msgid "convert existing graft file"
+msgstr ""
+
+#: builtin/replace.c:540
 msgid "replace the ref if it exists"
 msgstr ""
 
-#: builtin/replace.c:444
+#: builtin/replace.c:542
 msgid "do not pretty-print contents for --edit"
 msgstr ""
 
-#: builtin/replace.c:445
+#: builtin/replace.c:543
 msgid "use this format"
 msgstr ""
 
@@ -12375,23 +12841,23 @@ msgstr ""
 msgid "cannot combine --use-bitmap-index with object filtering"
 msgstr ""
 
-#: builtin/rev-parse.c:402
+#: builtin/rev-parse.c:406
 msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
 msgstr ""
 
-#: builtin/rev-parse.c:407
+#: builtin/rev-parse.c:411
 msgid "keep the `--` passed as an arg"
 msgstr ""
 
-#: builtin/rev-parse.c:409
+#: builtin/rev-parse.c:413
 msgid "stop parsing after the first non-option argument"
 msgstr ""
 
-#: builtin/rev-parse.c:412
+#: builtin/rev-parse.c:416
 msgid "output in stuck long form"
 msgstr ""
 
-#: builtin/rev-parse.c:545
+#: builtin/rev-parse.c:549
 msgid ""
 "git rev-parse --parseopt [<options>] -- [<args>...]\n"
 "   or: git rev-parse --sq-quote [<arg>...]\n"
@@ -12519,42 +12985,42 @@ msgid_plural "the following files have local modifications:"
 msgstr[0] ""
 msgstr[1] ""
 
-#: builtin/rm.c:243
+#: builtin/rm.c:241
 msgid "do not list removed files"
 msgstr ""
 
-#: builtin/rm.c:244
+#: builtin/rm.c:242
 msgid "only remove from the index"
 msgstr ""
 
-#: builtin/rm.c:245
+#: builtin/rm.c:243
 msgid "override the up-to-date check"
 msgstr ""
 
-#: builtin/rm.c:246
+#: builtin/rm.c:244
 msgid "allow recursive removal"
 msgstr ""
 
-#: builtin/rm.c:248
+#: builtin/rm.c:246
 msgid "exit with a zero status even if nothing matched"
 msgstr ""
 
-#: builtin/rm.c:307
+#: builtin/rm.c:306
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr ""
 
-#: builtin/rm.c:346
+#: builtin/rm.c:345
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr ""
 
-#: builtin/rm.c:369
+#: builtin/rm.c:368
 #, c-format
 msgid "could not remove '%s'"
 msgstr ""
 
-#: builtin/send-pack.c:19
+#: builtin/send-pack.c:20
 msgid ""
 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-"
 "receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> "
@@ -12562,50 +13028,70 @@ msgid ""
 "  --all and explicit <ref> specification are mutually exclusive."
 msgstr ""
 
-#: builtin/send-pack.c:162
+#: builtin/send-pack.c:163
 msgid "remote name"
 msgstr ""
 
-#: builtin/send-pack.c:176
+#: builtin/send-pack.c:177
 msgid "use stateless RPC protocol"
 msgstr ""
 
-#: builtin/send-pack.c:177
+#: builtin/send-pack.c:178
 msgid "read refs from stdin"
 msgstr ""
 
-#: builtin/send-pack.c:178
+#: builtin/send-pack.c:179
 msgid "print status from remote helper"
 msgstr ""
 
-#: builtin/shortlog.c:14
-msgid "git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"
+#: builtin/serve.c:7
+msgid "git serve [<options>]"
 msgstr ""
 
-#: builtin/shortlog.c:263
-msgid "Group by committer rather than author"
+#: builtin/serve.c:17 builtin/upload-pack.c:23
+msgid "quit after a single request/response exchange"
 msgstr ""
 
-#: builtin/shortlog.c:265
-msgid "sort output according to the number of commits per author"
+#: builtin/serve.c:19
+msgid "exit immediately after advertising capabilities"
 msgstr ""
 
-#: builtin/shortlog.c:267
-msgid "Suppress commit descriptions, only provides commit count"
+#: builtin/shortlog.c:14
+msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]"
 msgstr ""
 
-#: builtin/shortlog.c:269
-msgid "Show the email address of each author"
+#: builtin/shortlog.c:15
+msgid "git log --pretty=short | git shortlog [<options>]"
+msgstr ""
+
+#: builtin/shortlog.c:264
+msgid "Group by committer rather than author"
+msgstr ""
+
+#: builtin/shortlog.c:266
+msgid "sort output according to the number of commits per author"
+msgstr ""
+
+#: builtin/shortlog.c:268
+msgid "Suppress commit descriptions, only provides commit count"
 msgstr ""
 
 #: builtin/shortlog.c:270
-msgid "w[,i1[,i2]]"
+msgid "Show the email address of each author"
 msgstr ""
 
 #: builtin/shortlog.c:271
+msgid "w[,i1[,i2]]"
+msgstr ""
+
+#: builtin/shortlog.c:272
 msgid "Linewrap output"
 msgstr ""
 
+#: builtin/shortlog.c:298
+msgid "too many arguments given outside repository"
+msgstr ""
+
 #: builtin/show-branch.c:12
 msgid ""
 "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
@@ -12794,330 +13280,330 @@ msgstr ""
 msgid "prepend comment character and space to each line"
 msgstr ""
 
-#: builtin/submodule--helper.c:35 builtin/submodule--helper.c:1669
+#: builtin/submodule--helper.c:37 builtin/submodule--helper.c:1688
 #, c-format
 msgid "No such ref: %s"
 msgstr ""
 
-#: builtin/submodule--helper.c:42 builtin/submodule--helper.c:1678
+#: builtin/submodule--helper.c:44 builtin/submodule--helper.c:1697
 #, c-format
 msgid "Expecting a full ref name, got %s"
 msgstr ""
 
-#: builtin/submodule--helper.c:59
+#: builtin/submodule--helper.c:61
 msgid "submodule--helper print-default-remote takes no arguments"
 msgstr ""
 
-#: builtin/submodule--helper.c:96
+#: builtin/submodule--helper.c:98
 #, c-format
 msgid "cannot strip one component off url '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:404 builtin/submodule--helper.c:1198
+#: builtin/submodule--helper.c:406 builtin/submodule--helper.c:1211
 msgid "alternative anchor for relative paths"
 msgstr ""
 
-#: builtin/submodule--helper.c:409
+#: builtin/submodule--helper.c:411
 msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
 msgstr ""
 
-#: builtin/submodule--helper.c:460 builtin/submodule--helper.c:483
+#: builtin/submodule--helper.c:462 builtin/submodule--helper.c:485
 #, c-format
 msgid "No url found for submodule path '%s' in .gitmodules"
 msgstr ""
 
-#: builtin/submodule--helper.c:498
+#: builtin/submodule--helper.c:500
 #, c-format
 msgid ""
 "could not lookup configuration '%s'. Assuming this repository is its own "
 "authoritative upstream."
 msgstr ""
 
-#: builtin/submodule--helper.c:509
+#: builtin/submodule--helper.c:511
 #, c-format
 msgid "Failed to register url for submodule path '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:513
+#: builtin/submodule--helper.c:515
 #, c-format
 msgid "Submodule '%s' (%s) registered for path '%s'\n"
 msgstr ""
 
-#: builtin/submodule--helper.c:523
+#: builtin/submodule--helper.c:525
 #, c-format
 msgid "warning: command update mode suggested for submodule '%s'\n"
 msgstr ""
 
-#: builtin/submodule--helper.c:530
+#: builtin/submodule--helper.c:532
 #, c-format
 msgid "Failed to register update mode for submodule path '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:552
+#: builtin/submodule--helper.c:554
 msgid "Suppress output for initializing a submodule"
 msgstr ""
 
-#: builtin/submodule--helper.c:557
+#: builtin/submodule--helper.c:559
 msgid "git submodule--helper init [<path>]"
 msgstr ""
 
-#: builtin/submodule--helper.c:625 builtin/submodule--helper.c:747
+#: builtin/submodule--helper.c:631 builtin/submodule--helper.c:757
 #, c-format
 msgid "no submodule mapping found in .gitmodules for path '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:660
+#: builtin/submodule--helper.c:670
 #, c-format
 msgid "could not resolve HEAD ref inside the submodule '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:687 builtin/submodule--helper.c:856
+#: builtin/submodule--helper.c:697 builtin/submodule--helper.c:866
 #, c-format
 msgid "failed to recurse into submodule '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:711 builtin/submodule--helper.c:1021
+#: builtin/submodule--helper.c:721 builtin/submodule--helper.c:1031
 msgid "Suppress submodule status output"
 msgstr ""
 
-#: builtin/submodule--helper.c:712
+#: builtin/submodule--helper.c:722
 msgid ""
 "Use commit stored in the index instead of the one stored in the submodule "
 "HEAD"
 msgstr ""
 
-#: builtin/submodule--helper.c:713
+#: builtin/submodule--helper.c:723
 msgid "recurse into nested submodules"
 msgstr ""
 
-#: builtin/submodule--helper.c:718
+#: builtin/submodule--helper.c:728
 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
 msgstr ""
 
-#: builtin/submodule--helper.c:742
+#: builtin/submodule--helper.c:752
 msgid "git submodule--helper name <path>"
 msgstr ""
 
-#: builtin/submodule--helper.c:806
+#: builtin/submodule--helper.c:816
 #, c-format
 msgid "Synchronizing submodule url for '%s'\n"
 msgstr ""
 
-#: builtin/submodule--helper.c:812
+#: builtin/submodule--helper.c:822
 #, c-format
 msgid "failed to register url for submodule path '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:826
+#: builtin/submodule--helper.c:836
 #, c-format
 msgid "failed to get the default remote for submodule '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:837
+#: builtin/submodule--helper.c:847
 #, c-format
 msgid "failed to update remote for submodule '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:885
+#: builtin/submodule--helper.c:895
 msgid "Suppress output of synchronizing submodule url"
 msgstr ""
 
-#: builtin/submodule--helper.c:887
+#: builtin/submodule--helper.c:897
 msgid "Recurse into nested submodules"
 msgstr ""
 
-#: builtin/submodule--helper.c:892
+#: builtin/submodule--helper.c:902
 msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
 msgstr ""
 
-#: builtin/submodule--helper.c:946
+#: builtin/submodule--helper.c:956
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you "
 "really want to remove it including all of its history)"
 msgstr ""
 
-#: builtin/submodule--helper.c:958
+#: builtin/submodule--helper.c:968
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains local modifications; use '-f' to discard "
 "them"
 msgstr ""
 
-#: builtin/submodule--helper.c:966
+#: builtin/submodule--helper.c:976
 #, c-format
 msgid "Cleared directory '%s'\n"
 msgstr ""
 
-#: builtin/submodule--helper.c:968
+#: builtin/submodule--helper.c:978
 #, c-format
 msgid "Could not remove submodule work tree '%s'\n"
 msgstr ""
 
-#: builtin/submodule--helper.c:977
+#: builtin/submodule--helper.c:987
 #, c-format
 msgid "could not create empty submodule directory %s"
 msgstr ""
 
-#: builtin/submodule--helper.c:993
+#: builtin/submodule--helper.c:1003
 #, c-format
 msgid "Submodule '%s' (%s) unregistered for path '%s'\n"
 msgstr ""
 
-#: builtin/submodule--helper.c:1022
+#: builtin/submodule--helper.c:1032
 msgid "Remove submodule working trees even if they contain local changes"
 msgstr ""
 
-#: builtin/submodule--helper.c:1023
+#: builtin/submodule--helper.c:1033
 msgid "Unregister all submodules"
 msgstr ""
 
-#: builtin/submodule--helper.c:1028
+#: builtin/submodule--helper.c:1038
 msgid ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
 msgstr ""
 
-#: builtin/submodule--helper.c:1042
+#: builtin/submodule--helper.c:1052
 msgid "Use '--all' if you really want to deinitialize all submodules"
 msgstr ""
 
-#: builtin/submodule--helper.c:1133 builtin/submodule--helper.c:1136
+#: builtin/submodule--helper.c:1145 builtin/submodule--helper.c:1148
 #, c-format
 msgid "submodule '%s' cannot add alternate: %s"
 msgstr ""
 
-#: builtin/submodule--helper.c:1172
+#: builtin/submodule--helper.c:1184
 #, c-format
 msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized"
 msgstr ""
 
-#: builtin/submodule--helper.c:1179
+#: builtin/submodule--helper.c:1191
 #, c-format
 msgid "Value '%s' for submodule.alternateLocation is not recognized"
 msgstr ""
 
-#: builtin/submodule--helper.c:1201
+#: builtin/submodule--helper.c:1214
 msgid "where the new submodule will be cloned to"
 msgstr ""
 
-#: builtin/submodule--helper.c:1204
+#: builtin/submodule--helper.c:1217
 msgid "name of the new submodule"
 msgstr ""
 
-#: builtin/submodule--helper.c:1207
+#: builtin/submodule--helper.c:1220
 msgid "url where to clone the submodule from"
 msgstr ""
 
-#: builtin/submodule--helper.c:1213
+#: builtin/submodule--helper.c:1228
 msgid "depth for shallow clones"
 msgstr ""
 
-#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1587
+#: builtin/submodule--helper.c:1231 builtin/submodule--helper.c:1606
 msgid "force cloning progress"
 msgstr ""
 
-#: builtin/submodule--helper.c:1221
+#: builtin/submodule--helper.c:1236
 msgid ""
 "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
 "<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>"
 msgstr ""
 
-#: builtin/submodule--helper.c:1252
+#: builtin/submodule--helper.c:1267
 #, c-format
 msgid "clone of '%s' into submodule path '%s' failed"
 msgstr ""
 
-#: builtin/submodule--helper.c:1267
+#: builtin/submodule--helper.c:1281
 #, c-format
 msgid "could not get submodule directory for '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:1332
+#: builtin/submodule--helper.c:1347
 #, c-format
 msgid "Submodule path '%s' not initialized"
 msgstr ""
 
-#: builtin/submodule--helper.c:1336
+#: builtin/submodule--helper.c:1351
 msgid "Maybe you want to use 'update --init'?"
 msgstr ""
 
-#: builtin/submodule--helper.c:1365
+#: builtin/submodule--helper.c:1380
 #, c-format
 msgid "Skipping unmerged submodule %s"
 msgstr ""
 
-#: builtin/submodule--helper.c:1394
+#: builtin/submodule--helper.c:1409
 #, c-format
 msgid "Skipping submodule '%s'"
 msgstr ""
 
-#: builtin/submodule--helper.c:1527
+#: builtin/submodule--helper.c:1544
 #, c-format
 msgid "Failed to clone '%s'. Retry scheduled"
 msgstr ""
 
-#: builtin/submodule--helper.c:1538
+#: builtin/submodule--helper.c:1555
 #, c-format
 msgid "Failed to clone '%s' a second time, aborting"
 msgstr ""
 
-#: builtin/submodule--helper.c:1568 builtin/submodule--helper.c:1788
+#: builtin/submodule--helper.c:1585 builtin/submodule--helper.c:1808
 msgid "path into the working tree"
 msgstr ""
 
-#: builtin/submodule--helper.c:1571
+#: builtin/submodule--helper.c:1588
 msgid "path into the working tree, across nested submodule boundaries"
 msgstr ""
 
-#: builtin/submodule--helper.c:1575
+#: builtin/submodule--helper.c:1592
 msgid "rebase, merge, checkout or none"
 msgstr ""
 
-#: builtin/submodule--helper.c:1579
+#: builtin/submodule--helper.c:1598
 msgid "Create a shallow clone truncated to the specified number of revisions"
 msgstr ""
 
-#: builtin/submodule--helper.c:1582
+#: builtin/submodule--helper.c:1601
 msgid "parallel jobs"
 msgstr ""
 
-#: builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1603
 msgid "whether the initial clone should follow the shallow recommendation"
 msgstr ""
 
-#: builtin/submodule--helper.c:1585
+#: builtin/submodule--helper.c:1604
 msgid "don't print cloning progress"
 msgstr ""
 
-#: builtin/submodule--helper.c:1592
+#: builtin/submodule--helper.c:1611
 msgid "git submodule--helper update_clone [--prefix=<path>] [<path>...]"
 msgstr ""
 
-#: builtin/submodule--helper.c:1605
+#: builtin/submodule--helper.c:1624
 msgid "bad value for update parameter"
 msgstr ""
 
-#: builtin/submodule--helper.c:1673
+#: builtin/submodule--helper.c:1692
 #, c-format
 msgid ""
 "Submodule (%s) branch configured to inherit branch from superproject, but "
 "the superproject is not on any branch"
 msgstr ""
 
-#: builtin/submodule--helper.c:1789
+#: builtin/submodule--helper.c:1809
 msgid "recurse into submodules"
 msgstr ""
 
-#: builtin/submodule--helper.c:1795
+#: builtin/submodule--helper.c:1815
 msgid "git submodule--helper embed-git-dir [<path>...]"
 msgstr ""
 
-#: builtin/submodule--helper.c:1857
+#: builtin/submodule--helper.c:1901
 #, c-format
 msgid "%s doesn't support --super-prefix"
 msgstr ""
 
-#: builtin/submodule--helper.c:1863
+#: builtin/submodule--helper.c:1907
 #, c-format
 msgid "'%s' is not a valid submodule--helper subcommand"
 msgstr ""
@@ -13181,7 +13667,7 @@ msgstr ""
 msgid "Deleted tag '%s' (was %s)\n"
 msgstr ""
 
-#: builtin/tag.c:131
+#: builtin/tag.c:132
 #, c-format
 msgid ""
 "\n"
@@ -13190,7 +13676,7 @@ msgid ""
 "Lines starting with '%c' will be ignored.\n"
 msgstr ""
 
-#: builtin/tag.c:135
+#: builtin/tag.c:136
 #, c-format
 msgid ""
 "\n"
@@ -13200,146 +13686,146 @@ msgid ""
 "want to.\n"
 msgstr ""
 
-#: builtin/tag.c:189
+#: builtin/tag.c:190
 msgid "unable to sign the tag"
 msgstr ""
 
-#: builtin/tag.c:191
+#: builtin/tag.c:192
 msgid "unable to write tag file"
 msgstr ""
 
-#: builtin/tag.c:216
+#: builtin/tag.c:217
 msgid "bad object type."
 msgstr ""
 
-#: builtin/tag.c:265
+#: builtin/tag.c:266
 msgid "no tag message?"
 msgstr ""
 
-#: builtin/tag.c:272
+#: builtin/tag.c:273
 #, c-format
 msgid "The tag message has been left in %s\n"
 msgstr ""
 
-#: builtin/tag.c:381
+#: builtin/tag.c:382
 msgid "list tag names"
 msgstr ""
 
-#: builtin/tag.c:383
+#: builtin/tag.c:384
 msgid "print <n> lines of each tag message"
 msgstr ""
 
-#: builtin/tag.c:385
+#: builtin/tag.c:386
 msgid "delete tags"
 msgstr ""
 
-#: builtin/tag.c:386
+#: builtin/tag.c:387
 msgid "verify tags"
 msgstr ""
 
-#: builtin/tag.c:388
+#: builtin/tag.c:389
 msgid "Tag creation options"
 msgstr ""
 
-#: builtin/tag.c:390
+#: builtin/tag.c:391
 msgid "annotated tag, needs a message"
 msgstr ""
 
-#: builtin/tag.c:392
+#: builtin/tag.c:393
 msgid "tag message"
 msgstr ""
 
-#: builtin/tag.c:394
+#: builtin/tag.c:395
 msgid "force edit of tag message"
 msgstr ""
 
-#: builtin/tag.c:395
+#: builtin/tag.c:396
 msgid "annotated and GPG-signed tag"
 msgstr ""
 
-#: builtin/tag.c:399
+#: builtin/tag.c:400
 msgid "use another key to sign the tag"
 msgstr ""
 
-#: builtin/tag.c:400
+#: builtin/tag.c:401
 msgid "replace the tag if exists"
 msgstr ""
 
-#: builtin/tag.c:401 builtin/update-ref.c:368
+#: builtin/tag.c:402 builtin/update-ref.c:368
 msgid "create a reflog"
 msgstr ""
 
-#: builtin/tag.c:403
+#: builtin/tag.c:404
 msgid "Tag listing options"
 msgstr ""
 
-#: builtin/tag.c:404
+#: builtin/tag.c:405
 msgid "show tag list in columns"
 msgstr ""
 
-#: builtin/tag.c:405 builtin/tag.c:407
+#: builtin/tag.c:406 builtin/tag.c:408
 msgid "print only tags that contain the commit"
 msgstr ""
 
-#: builtin/tag.c:406 builtin/tag.c:408
+#: builtin/tag.c:407 builtin/tag.c:409
 msgid "print only tags that don't contain the commit"
 msgstr ""
 
-#: builtin/tag.c:409
+#: builtin/tag.c:410
 msgid "print only tags that are merged"
 msgstr ""
 
-#: builtin/tag.c:410
+#: builtin/tag.c:411
 msgid "print only tags that are not merged"
 msgstr ""
 
-#: builtin/tag.c:415
+#: builtin/tag.c:416
 msgid "print only tags of the object"
 msgstr ""
 
-#: builtin/tag.c:459
+#: builtin/tag.c:460
 msgid "--column and -n are incompatible"
 msgstr ""
 
-#: builtin/tag.c:481
+#: builtin/tag.c:482
 msgid "-n option is only allowed in list mode"
 msgstr ""
 
-#: builtin/tag.c:483
+#: builtin/tag.c:484
 msgid "--contains option is only allowed in list mode"
 msgstr ""
 
-#: builtin/tag.c:485
+#: builtin/tag.c:486
 msgid "--no-contains option is only allowed in list mode"
 msgstr ""
 
-#: builtin/tag.c:487
+#: builtin/tag.c:488
 msgid "--points-at option is only allowed in list mode"
 msgstr ""
 
-#: builtin/tag.c:489
+#: builtin/tag.c:490
 msgid "--merged and --no-merged options are only allowed in list mode"
 msgstr ""
 
-#: builtin/tag.c:500
+#: builtin/tag.c:501
 msgid "only one -F or -m option is allowed."
 msgstr ""
 
-#: builtin/tag.c:519
+#: builtin/tag.c:520
 msgid "too many params"
 msgstr ""
 
-#: builtin/tag.c:525
+#: builtin/tag.c:526
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr ""
 
-#: builtin/tag.c:530
+#: builtin/tag.c:531
 #, c-format
 msgid "tag '%s' already exists"
 msgstr ""
 
-#: builtin/tag.c:561
+#: builtin/tag.c:562
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr ""
@@ -13406,189 +13892,189 @@ msgstr ""
 msgid " OK"
 msgstr ""
 
-#: builtin/update-index.c:579
+#: builtin/update-index.c:589
 msgid "git update-index [<options>] [--] [<file>...]"
 msgstr ""
 
-#: builtin/update-index.c:936
+#: builtin/update-index.c:946
 msgid "continue refresh even when index needs update"
 msgstr ""
 
-#: builtin/update-index.c:939
+#: builtin/update-index.c:949
 msgid "refresh: ignore submodules"
 msgstr ""
 
-#: builtin/update-index.c:942
+#: builtin/update-index.c:952
 msgid "do not ignore new files"
 msgstr ""
 
-#: builtin/update-index.c:944
+#: builtin/update-index.c:954
 msgid "let files replace directories and vice-versa"
 msgstr ""
 
-#: builtin/update-index.c:946
+#: builtin/update-index.c:956
 msgid "notice files missing from worktree"
 msgstr ""
 
-#: builtin/update-index.c:948
+#: builtin/update-index.c:958
 msgid "refresh even if index contains unmerged entries"
 msgstr ""
 
-#: builtin/update-index.c:951
+#: builtin/update-index.c:961
 msgid "refresh stat information"
 msgstr ""
 
-#: builtin/update-index.c:955
+#: builtin/update-index.c:965
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr ""
 
-#: builtin/update-index.c:959
+#: builtin/update-index.c:969
 msgid "<mode>,<object>,<path>"
 msgstr ""
 
-#: builtin/update-index.c:960
+#: builtin/update-index.c:970
 msgid "add the specified entry to the index"
 msgstr ""
 
-#: builtin/update-index.c:969
+#: builtin/update-index.c:979
 msgid "mark files as \"not changing\""
 msgstr ""
 
-#: builtin/update-index.c:972
+#: builtin/update-index.c:982
 msgid "clear assumed-unchanged bit"
 msgstr ""
 
-#: builtin/update-index.c:975
+#: builtin/update-index.c:985
 msgid "mark files as \"index-only\""
 msgstr ""
 
-#: builtin/update-index.c:978
+#: builtin/update-index.c:988
 msgid "clear skip-worktree bit"
 msgstr ""
 
-#: builtin/update-index.c:981
+#: builtin/update-index.c:991
 msgid "add to index only; do not add content to object database"
 msgstr ""
 
-#: builtin/update-index.c:983
+#: builtin/update-index.c:993
 msgid "remove named paths even if present in worktree"
 msgstr ""
 
-#: builtin/update-index.c:985
+#: builtin/update-index.c:995
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr ""
 
-#: builtin/update-index.c:987
+#: builtin/update-index.c:997
 msgid "read list of paths to be updated from standard input"
 msgstr ""
 
-#: builtin/update-index.c:991
+#: builtin/update-index.c:1001
 msgid "add entries from standard input to the index"
 msgstr ""
 
-#: builtin/update-index.c:995
+#: builtin/update-index.c:1005
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr ""
 
-#: builtin/update-index.c:999
+#: builtin/update-index.c:1009
 msgid "only update entries that differ from HEAD"
 msgstr ""
 
-#: builtin/update-index.c:1003
+#: builtin/update-index.c:1013
 msgid "ignore files missing from worktree"
 msgstr ""
 
-#: builtin/update-index.c:1006
+#: builtin/update-index.c:1016
 msgid "report actions to standard output"
 msgstr ""
 
-#: builtin/update-index.c:1008
+#: builtin/update-index.c:1018
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr ""
 
-#: builtin/update-index.c:1012
+#: builtin/update-index.c:1022
 msgid "write index in this format"
 msgstr ""
 
-#: builtin/update-index.c:1014
+#: builtin/update-index.c:1024
 msgid "enable or disable split index"
 msgstr ""
 
-#: builtin/update-index.c:1016
+#: builtin/update-index.c:1026
 msgid "enable/disable untracked cache"
 msgstr ""
 
-#: builtin/update-index.c:1018
+#: builtin/update-index.c:1028
 msgid "test if the filesystem supports untracked cache"
 msgstr ""
 
-#: builtin/update-index.c:1020
+#: builtin/update-index.c:1030
 msgid "enable untracked cache without testing the filesystem"
 msgstr ""
 
-#: builtin/update-index.c:1022
+#: builtin/update-index.c:1032
 msgid "write out the index even if is not flagged as changed"
 msgstr ""
 
-#: builtin/update-index.c:1024
+#: builtin/update-index.c:1034
 msgid "enable or disable file system monitor"
 msgstr ""
 
-#: builtin/update-index.c:1026
+#: builtin/update-index.c:1036
 msgid "mark files as fsmonitor valid"
 msgstr ""
 
-#: builtin/update-index.c:1029
+#: builtin/update-index.c:1039
 msgid "clear fsmonitor valid bit"
 msgstr ""
 
-#: builtin/update-index.c:1127
+#: builtin/update-index.c:1138
 msgid ""
 "core.splitIndex is set to false; remove or change it, if you really want to "
 "enable split index"
 msgstr ""
 
-#: builtin/update-index.c:1136
+#: builtin/update-index.c:1147
 msgid ""
 "core.splitIndex is set to true; remove or change it, if you really want to "
 "disable split index"
 msgstr ""
 
-#: builtin/update-index.c:1147
+#: builtin/update-index.c:1158
 msgid ""
 "core.untrackedCache is set to true; remove or change it, if you really want "
 "to disable the untracked cache"
 msgstr ""
 
-#: builtin/update-index.c:1151
+#: builtin/update-index.c:1162
 msgid "Untracked cache disabled"
 msgstr ""
 
-#: builtin/update-index.c:1159
+#: builtin/update-index.c:1170
 msgid ""
 "core.untrackedCache is set to false; remove or change it, if you really want "
 "to enable the untracked cache"
 msgstr ""
 
-#: builtin/update-index.c:1163
+#: builtin/update-index.c:1174
 #, c-format
 msgid "Untracked cache enabled for '%s'"
 msgstr ""
 
-#: builtin/update-index.c:1171
+#: builtin/update-index.c:1182
 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
 msgstr ""
 
-#: builtin/update-index.c:1175
+#: builtin/update-index.c:1186
 msgid "fsmonitor enabled"
 msgstr ""
 
-#: builtin/update-index.c:1178
+#: builtin/update-index.c:1189
 msgid ""
 "core.fsmonitor is set; remove it if you really want to disable fsmonitor"
 msgstr ""
 
-#: builtin/update-index.c:1182
+#: builtin/update-index.c:1193
 msgid "fsmonitor disabled"
 msgstr ""
 
@@ -13628,6 +14114,22 @@ msgstr ""
 msgid "update the info files from scratch"
 msgstr ""
 
+#: builtin/upload-pack.c:11
+msgid "git upload-pack [<options>] <dir>"
+msgstr ""
+
+#: builtin/upload-pack.c:25
+msgid "exit immediately after initial ref advertisement"
+msgstr ""
+
+#: builtin/upload-pack.c:27
+msgid "do not try <directory>/.git/ if <directory> is no Git directory"
+msgstr ""
+
+#: builtin/upload-pack.c:29
+msgid "interrupt transfer after <n> seconds of inactivity"
+msgstr ""
+
 #: builtin/verify-commit.c:18
 msgid "git verify-commit [-v | --verbose] <commit>..."
 msgstr ""
@@ -13688,198 +14190,213 @@ msgstr ""
 msgid "git worktree unlock <path>"
 msgstr ""
 
-#: builtin/worktree.c:60
+#: builtin/worktree.c:58
 #, c-format
 msgid "Removing worktrees/%s: not a valid directory"
 msgstr ""
 
-#: builtin/worktree.c:66
+#: builtin/worktree.c:64
 #, c-format
 msgid "Removing worktrees/%s: gitdir file does not exist"
 msgstr ""
 
-#: builtin/worktree.c:71 builtin/worktree.c:80
+#: builtin/worktree.c:69 builtin/worktree.c:78
 #, c-format
 msgid "Removing worktrees/%s: unable to read gitdir file (%s)"
 msgstr ""
 
-#: builtin/worktree.c:90
+#: builtin/worktree.c:88
 #, c-format
 msgid ""
 "Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read "
 "%<PRIuMAX>)"
 msgstr ""
 
-#: builtin/worktree.c:98
+#: builtin/worktree.c:96
 #, c-format
 msgid "Removing worktrees/%s: invalid gitdir file"
 msgstr ""
 
-#: builtin/worktree.c:114
+#: builtin/worktree.c:105
 #, c-format
 msgid "Removing worktrees/%s: gitdir file points to non-existent location"
 msgstr ""
 
-#: builtin/worktree.c:161
+#: builtin/worktree.c:152
 msgid "report pruned working trees"
 msgstr ""
 
-#: builtin/worktree.c:163
+#: builtin/worktree.c:154
 msgid "expire working trees older than <time>"
 msgstr ""
 
-#: builtin/worktree.c:238
+#: builtin/worktree.c:229
 #, c-format
 msgid "'%s' already exists"
 msgstr ""
 
-#: builtin/worktree.c:269
+#: builtin/worktree.c:260
 #, c-format
 msgid "could not create directory of '%s'"
 msgstr ""
 
-#: builtin/worktree.c:308
+#: builtin/worktree.c:373 builtin/worktree.c:379
 #, c-format
-msgid "Preparing %s (identifier %s)"
+msgid "Preparing worktree (new branch '%s')"
 msgstr ""
 
-#: builtin/worktree.c:385
+#: builtin/worktree.c:375
+#, c-format
+msgid "Preparing worktree (resetting branch '%s'; was at %s)"
+msgstr ""
+
+#: builtin/worktree.c:384
+#, c-format
+msgid "Preparing worktree (checking out '%s')"
+msgstr ""
+
+#: builtin/worktree.c:390
+#, c-format
+msgid "Preparing worktree (detached HEAD %s)"
+msgstr ""
+
+#: builtin/worktree.c:431
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr ""
 
-#: builtin/worktree.c:388
+#: builtin/worktree.c:434
 msgid "create a new branch"
 msgstr ""
 
-#: builtin/worktree.c:390
+#: builtin/worktree.c:436
 msgid "create or reset a branch"
 msgstr ""
 
-#: builtin/worktree.c:392
+#: builtin/worktree.c:438
 msgid "populate the new working tree"
 msgstr ""
 
-#: builtin/worktree.c:393
+#: builtin/worktree.c:439
 msgid "keep the new working tree locked"
 msgstr ""
 
-#: builtin/worktree.c:395
+#: builtin/worktree.c:441
 msgid "set up tracking mode (see git-branch(1))"
 msgstr ""
 
-#: builtin/worktree.c:398
+#: builtin/worktree.c:444
 msgid "try to match the new branch name with a remote-tracking branch"
 msgstr ""
 
-#: builtin/worktree.c:406
+#: builtin/worktree.c:452
 msgid "-b, -B, and --detach are mutually exclusive"
 msgstr ""
 
-#: builtin/worktree.c:471
+#: builtin/worktree.c:511
 msgid "--[no-]track can only be used if a new branch is created"
 msgstr ""
 
-#: builtin/worktree.c:571
+#: builtin/worktree.c:611
 msgid "reason for locking"
 msgstr ""
 
-#: builtin/worktree.c:583 builtin/worktree.c:616 builtin/worktree.c:670
-#: builtin/worktree.c:809
+#: builtin/worktree.c:623 builtin/worktree.c:656 builtin/worktree.c:710
+#: builtin/worktree.c:850
 #, c-format
 msgid "'%s' is not a working tree"
 msgstr ""
 
-#: builtin/worktree.c:585 builtin/worktree.c:618
+#: builtin/worktree.c:625 builtin/worktree.c:658
 msgid "The main working tree cannot be locked or unlocked"
 msgstr ""
 
-#: builtin/worktree.c:590
+#: builtin/worktree.c:630
 #, c-format
 msgid "'%s' is already locked, reason: %s"
 msgstr ""
 
-#: builtin/worktree.c:592
+#: builtin/worktree.c:632
 #, c-format
 msgid "'%s' is already locked"
 msgstr ""
 
-#: builtin/worktree.c:620
+#: builtin/worktree.c:660
 #, c-format
 msgid "'%s' is not locked"
 msgstr ""
 
-#: builtin/worktree.c:645
+#: builtin/worktree.c:685
 msgid "working trees containing submodules cannot be moved or removed"
 msgstr ""
 
-#: builtin/worktree.c:672 builtin/worktree.c:811
+#: builtin/worktree.c:712 builtin/worktree.c:852
 #, c-format
 msgid "'%s' is a main working tree"
 msgstr ""
 
-#: builtin/worktree.c:677
+#: builtin/worktree.c:717
 #, c-format
 msgid "could not figure out destination name from '%s'"
 msgstr ""
 
-#: builtin/worktree.c:683
+#: builtin/worktree.c:723
 #, c-format
 msgid "target '%s' already exists"
 msgstr ""
 
-#: builtin/worktree.c:690
+#: builtin/worktree.c:730
 #, c-format
 msgid "cannot move a locked working tree, lock reason: %s"
 msgstr ""
 
-#: builtin/worktree.c:692
+#: builtin/worktree.c:732
 msgid "cannot move a locked working tree"
 msgstr ""
 
-#: builtin/worktree.c:695
+#: builtin/worktree.c:735
 #, c-format
 msgid "validation failed, cannot move working tree: %s"
 msgstr ""
 
-#: builtin/worktree.c:700
+#: builtin/worktree.c:740
 #, c-format
 msgid "failed to move '%s' to '%s'"
 msgstr ""
 
-#: builtin/worktree.c:748
+#: builtin/worktree.c:788
 #, c-format
 msgid "failed to run 'git status' on '%s'"
 msgstr ""
 
-#: builtin/worktree.c:752
+#: builtin/worktree.c:792
 #, c-format
 msgid "'%s' is dirty, use --force to delete it"
 msgstr ""
 
-#: builtin/worktree.c:757
+#: builtin/worktree.c:797
 #, c-format
 msgid "failed to run 'git status' on '%s', code %d"
 msgstr ""
 
-#: builtin/worktree.c:768 builtin/worktree.c:782
+#: builtin/worktree.c:808 builtin/worktree.c:822
 #, c-format
 msgid "failed to delete '%s'"
 msgstr ""
 
-#: builtin/worktree.c:794
+#: builtin/worktree.c:834
 msgid "force removing even if the worktree is dirty"
 msgstr ""
 
-#: builtin/worktree.c:815
+#: builtin/worktree.c:856
 #, c-format
 msgid "cannot remove a locked working tree, lock reason: %s"
 msgstr ""
 
-#: builtin/worktree.c:817
+#: builtin/worktree.c:858
 msgid "cannot remove a locked working tree"
 msgstr ""
 
-#: builtin/worktree.c:820
+#: builtin/worktree.c:861
 #, c-format
 msgid "validation failed, cannot remove working tree: %s"
 msgstr ""
@@ -13900,26 +14417,6 @@ msgstr ""
 msgid "only useful for debugging"
 msgstr ""
 
-#: upload-pack.c:27
-msgid "git upload-pack [<options>] <dir>"
-msgstr ""
-
-#: upload-pack.c:1070
-msgid "quit after a single request/response exchange"
-msgstr ""
-
-#: upload-pack.c:1072
-msgid "exit immediately after initial ref advertisement"
-msgstr ""
-
-#: upload-pack.c:1074
-msgid "do not try <directory>/.git/ if <directory> is no Git directory"
-msgstr ""
-
-#: upload-pack.c:1076
-msgid "interrupt transfer after <n> seconds of inactivity"
-msgstr ""
-
 #: credential-cache--daemon.c:222
 #, c-format
 msgid ""
@@ -13933,81 +14430,82 @@ msgstr ""
 msgid "print debugging messages to stderr"
 msgstr ""
 
-#: git.c:8
+#: git.c:27
 msgid ""
 "git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
 "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
 "           <command> [<args>]"
 msgstr ""
 
-#: git.c:15
+#: git.c:34
 msgid ""
 "'git help -a' and 'git help -g' list available subcommands and some\n"
 "concept guides. See 'git help <command>' or 'git help <concept>'\n"
 "to read about a specific subcommand or concept."
 msgstr ""
 
-#: git.c:95
+#: git.c:173
 #, c-format
 msgid "no directory given for --git-dir\n"
 msgstr ""
 
-#: git.c:109
+#: git.c:187
 #, c-format
 msgid "no namespace given for --namespace\n"
 msgstr ""
 
-#: git.c:123
+#: git.c:201
 #, c-format
 msgid "no directory given for --work-tree\n"
 msgstr ""
 
-#: git.c:137
+#: git.c:215
 #, c-format
 msgid "no prefix given for --super-prefix\n"
 msgstr ""
 
-#: git.c:159
+#: git.c:237
 #, c-format
 msgid "-c expects a configuration string\n"
 msgstr ""
 
-#: git.c:197
+#: git.c:275
 #, c-format
 msgid "no directory given for -C\n"
 msgstr ""
 
-#: git.c:212
+#: git.c:300
 #, c-format
 msgid "unknown option: %s\n"
 msgstr ""
 
-#: git.c:687
+#: git.c:765
 #, c-format
 msgid "expansion of alias '%s' failed; '%s' is not a git command\n"
 msgstr ""
 
-#: git.c:699
+#: git.c:777
 #, c-format
 msgid "failed to run command '%s': %s\n"
 msgstr ""
 
-#: http.c:342
+#: http.c:348
 #, c-format
 msgid "negative value for http.postbuffer; defaulting to %d"
 msgstr ""
 
-#: http.c:363
+#: http.c:369
 msgid "Delegation control is not supported with cURL < 7.22.0"
 msgstr ""
 
-#: http.c:372
+#: http.c:378
 msgid "Public key pinning not supported with cURL < 7.44.0"
 msgstr ""
 
-#: http.c:1857
+#: http.c:1854
 #, c-format
 msgid ""
 "unable to update url base from redirection:\n"
@@ -14015,7 +14513,7 @@ msgid ""
 "   redirect: %s"
 msgstr ""
 
-#: remote-curl.c:345
+#: remote-curl.c:401
 #, c-format
 msgid "redirecting to %s"
 msgstr ""
@@ -14028,128 +14526,652 @@ msgstr ""
 msgid "object filtering"
 msgstr ""
 
-#: common-cmds.h:9
-msgid "start a working area (see also: git help tutorial)"
+#: parse-options.h:157
+msgid "expiry-date"
 msgstr ""
 
-#: common-cmds.h:10
-msgid "work on the current change (see also: git help everyday)"
+#: parse-options.h:172
+msgid "no-op (backward compatibility)"
 msgstr ""
 
-#: common-cmds.h:11
-msgid "examine the history and state (see also: git help revisions)"
+#: parse-options.h:251
+msgid "be more verbose"
 msgstr ""
 
-#: common-cmds.h:12
-msgid "grow, mark and tweak your common history"
+#: parse-options.h:253
+msgid "be more quiet"
 msgstr ""
 
-#: common-cmds.h:13
-msgid "collaborate (see also: git help workflows)"
+#: parse-options.h:259
+msgid "use <n> digits to display SHA-1s"
 msgstr ""
 
-#: common-cmds.h:17
+#: command-list.h:50
 msgid "Add file contents to the index"
 msgstr ""
 
-#: common-cmds.h:18
+#: command-list.h:51
+msgid "Apply a series of patches from a mailbox"
+msgstr ""
+
+#: command-list.h:52
+msgid "Annotate file lines with commit information"
+msgstr ""
+
+#: command-list.h:53
+msgid "Apply a patch to files and/or to the index"
+msgstr ""
+
+#: command-list.h:54
+msgid "Import an Arch repository into Git"
+msgstr ""
+
+#: command-list.h:55
+msgid "Create an archive of files from a named tree"
+msgstr ""
+
+#: command-list.h:56
 msgid "Use binary search to find the commit that introduced a bug"
 msgstr ""
 
-#: common-cmds.h:19
+#: command-list.h:57
+msgid "Show what revision and author last modified each line of a file"
+msgstr ""
+
+#: command-list.h:58
 msgid "List, create, or delete branches"
 msgstr ""
 
-#: common-cmds.h:20
+#: command-list.h:59
+msgid "Move objects and refs by archive"
+msgstr ""
+
+#: command-list.h:60
+msgid "Provide content or type and size information for repository objects"
+msgstr ""
+
+#: command-list.h:61
+msgid "Display gitattributes information"
+msgstr ""
+
+#: command-list.h:62
+msgid "Debug gitignore / exclude files"
+msgstr ""
+
+#: command-list.h:63
+msgid "Show canonical names and email addresses of contacts"
+msgstr ""
+
+#: command-list.h:64
 msgid "Switch branches or restore working tree files"
 msgstr ""
 
-#: common-cmds.h:21
+#: command-list.h:65
+msgid "Copy files from the index to the working tree"
+msgstr ""
+
+#: command-list.h:66
+msgid "Ensures that a reference name is well formed"
+msgstr ""
+
+#: command-list.h:67
+msgid "Find commits yet to be applied to upstream"
+msgstr ""
+
+#: command-list.h:68
+msgid "Apply the changes introduced by some existing commits"
+msgstr ""
+
+#: command-list.h:69
+msgid "Graphical alternative to git-commit"
+msgstr ""
+
+#: command-list.h:70
+msgid "Remove untracked files from the working tree"
+msgstr ""
+
+#: command-list.h:71
 msgid "Clone a repository into a new directory"
 msgstr ""
 
-#: common-cmds.h:22
+#: command-list.h:72
+msgid "Display data in columns"
+msgstr ""
+
+#: command-list.h:73
 msgid "Record changes to the repository"
 msgstr ""
 
-#: common-cmds.h:23
+#: command-list.h:74
+msgid "Write and verify Git commit graph files"
+msgstr ""
+
+#: command-list.h:75
+msgid "Create a new commit object"
+msgstr ""
+
+#: command-list.h:76
+msgid "Get and set repository or global options"
+msgstr ""
+
+#: command-list.h:77
+msgid "Count unpacked number of objects and their disk consumption"
+msgstr ""
+
+#: command-list.h:78
+msgid "Retrieve and store user credentials"
+msgstr ""
+
+#: command-list.h:79
+msgid "Helper to temporarily store passwords in memory"
+msgstr ""
+
+#: command-list.h:80
+msgid "Helper to store credentials on disk"
+msgstr ""
+
+#: command-list.h:81
+msgid "Export a single commit to a CVS checkout"
+msgstr ""
+
+#: command-list.h:82
+msgid "Salvage your data out of another SCM people love to hate"
+msgstr ""
+
+#: command-list.h:83
+msgid "A CVS server emulator for Git"
+msgstr ""
+
+#: command-list.h:84
+msgid "A really simple server for Git repositories"
+msgstr ""
+
+#: command-list.h:85
+msgid "Give an object a human readable name based on an available ref"
+msgstr ""
+
+#: command-list.h:86
 msgid "Show changes between commits, commit and working tree, etc"
 msgstr ""
 
-#: common-cmds.h:24
+#: command-list.h:87
+msgid "Compares files in the working tree and the index"
+msgstr ""
+
+#: command-list.h:88
+msgid "Compare a tree to the working tree or index"
+msgstr ""
+
+#: command-list.h:89
+msgid "Compares the content and mode of blobs found via two tree objects"
+msgstr ""
+
+#: command-list.h:90
+msgid "Show changes using common diff tools"
+msgstr ""
+
+#: command-list.h:91
+msgid "Git data exporter"
+msgstr ""
+
+#: command-list.h:92
+msgid "Backend for fast Git data importers"
+msgstr ""
+
+#: command-list.h:93
 msgid "Download objects and refs from another repository"
 msgstr ""
 
-#: common-cmds.h:25
+#: command-list.h:94
+msgid "Receive missing objects from another repository"
+msgstr ""
+
+#: command-list.h:95
+msgid "Rewrite branches"
+msgstr ""
+
+#: command-list.h:96
+msgid "Produce a merge commit message"
+msgstr ""
+
+#: command-list.h:97
+msgid "Output information on each ref"
+msgstr ""
+
+#: command-list.h:98
+msgid "Prepare patches for e-mail submission"
+msgstr ""
+
+#: command-list.h:99
+msgid "Verifies the connectivity and validity of the objects in the database"
+msgstr ""
+
+#: command-list.h:100
+msgid "Cleanup unnecessary files and optimize the local repository"
+msgstr ""
+
+#: command-list.h:101
+msgid "Extract commit ID from an archive created using git-archive"
+msgstr ""
+
+#: command-list.h:102
 msgid "Print lines matching a pattern"
 msgstr ""
 
-#: common-cmds.h:26
+#: command-list.h:103
+msgid "A portable graphical interface to Git"
+msgstr ""
+
+#: command-list.h:104
+msgid "Compute object ID and optionally creates a blob from a file"
+msgstr ""
+
+#: command-list.h:105
+msgid "Display help information about Git"
+msgstr ""
+
+#: command-list.h:106
+msgid "Server side implementation of Git over HTTP"
+msgstr ""
+
+#: command-list.h:107
+msgid "Download from a remote Git repository via HTTP"
+msgstr ""
+
+#: command-list.h:108
+msgid "Push objects over HTTP/DAV to another repository"
+msgstr ""
+
+#: command-list.h:109
+msgid "Send a collection of patches from stdin to an IMAP folder"
+msgstr ""
+
+#: command-list.h:110
+msgid "Build pack index file for an existing packed archive"
+msgstr ""
+
+#: command-list.h:111
 msgid "Create an empty Git repository or reinitialize an existing one"
 msgstr ""
 
-#: common-cmds.h:27
+#: command-list.h:112
+msgid "Instantly browse your working repository in gitweb"
+msgstr ""
+
+#: command-list.h:113
+msgid "add or parse structured information in commit messages"
+msgstr ""
+
+#: command-list.h:114
+msgid "The Git repository browser"
+msgstr ""
+
+#: command-list.h:115
 msgid "Show commit logs"
 msgstr ""
 
-#: common-cmds.h:28
+#: command-list.h:116
+msgid "Show information about files in the index and the working tree"
+msgstr ""
+
+#: command-list.h:117
+msgid "List references in a remote repository"
+msgstr ""
+
+#: command-list.h:118
+msgid "List the contents of a tree object"
+msgstr ""
+
+#: command-list.h:119
+msgid "Extracts patch and authorship from a single e-mail message"
+msgstr ""
+
+#: command-list.h:120
+msgid "Simple UNIX mbox splitter program"
+msgstr ""
+
+#: command-list.h:121
 msgid "Join two or more development histories together"
 msgstr ""
 
-#: common-cmds.h:29
+#: command-list.h:122
+msgid "Find as good common ancestors as possible for a merge"
+msgstr ""
+
+#: command-list.h:123
+msgid "Run a three-way file merge"
+msgstr ""
+
+#: command-list.h:124
+msgid "Run a merge for files needing merging"
+msgstr ""
+
+#: command-list.h:125
+msgid "The standard helper program to use with git-merge-index"
+msgstr ""
+
+#: command-list.h:126
+msgid "Run merge conflict resolution tools to resolve merge conflicts"
+msgstr ""
+
+#: command-list.h:127
+msgid "Show three-way merge without touching index"
+msgstr ""
+
+#: command-list.h:128
+msgid "Creates a tag object"
+msgstr ""
+
+#: command-list.h:129
+msgid "Build a tree-object from ls-tree formatted text"
+msgstr ""
+
+#: command-list.h:130
 msgid "Move or rename a file, a directory, or a symlink"
 msgstr ""
 
-#: common-cmds.h:30
+#: command-list.h:131
+msgid "Find symbolic names for given revs"
+msgstr ""
+
+#: command-list.h:132
+msgid "Add or inspect object notes"
+msgstr ""
+
+#: command-list.h:133
+msgid "Import from and submit to Perforce repositories"
+msgstr ""
+
+#: command-list.h:134
+msgid "Create a packed archive of objects"
+msgstr ""
+
+#: command-list.h:135
+msgid "Find redundant pack files"
+msgstr ""
+
+#: command-list.h:136
+msgid "Pack heads and tags for efficient repository access"
+msgstr ""
+
+#: command-list.h:137
+msgid "Routines to help parsing remote repository access parameters"
+msgstr ""
+
+#: command-list.h:138
+msgid "Compute unique ID for a patch"
+msgstr ""
+
+#: command-list.h:139
+msgid "Prune all unreachable objects from the object database"
+msgstr ""
+
+#: command-list.h:140
+msgid "Remove extra objects that are already in pack files"
+msgstr ""
+
+#: command-list.h:141
 msgid "Fetch from and integrate with another repository or a local branch"
 msgstr ""
 
-#: common-cmds.h:31
+#: command-list.h:142
 msgid "Update remote refs along with associated objects"
 msgstr ""
 
-#: common-cmds.h:32
+#: command-list.h:143
+msgid "Applies a quilt patchset onto the current branch"
+msgstr ""
+
+#: command-list.h:144
+msgid "Reads tree information into the index"
+msgstr ""
+
+#: command-list.h:145
 msgid "Reapply commits on top of another base tip"
 msgstr ""
 
-#: common-cmds.h:33
+#: command-list.h:146
+msgid "Receive what is pushed into the repository"
+msgstr ""
+
+#: command-list.h:147
+msgid "Manage reflog information"
+msgstr ""
+
+#: command-list.h:148
+msgid "Manage set of tracked repositories"
+msgstr ""
+
+#: command-list.h:149
+msgid "Pack unpacked objects in a repository"
+msgstr ""
+
+#: command-list.h:150
+msgid "Create, list, delete refs to replace objects"
+msgstr ""
+
+#: command-list.h:151
+msgid "Generates a summary of pending changes"
+msgstr ""
+
+#: command-list.h:152
+msgid "Reuse recorded resolution of conflicted merges"
+msgstr ""
+
+#: command-list.h:153
 msgid "Reset current HEAD to the specified state"
 msgstr ""
 
-#: common-cmds.h:34
+#: command-list.h:154
+msgid "Revert some existing commits"
+msgstr ""
+
+#: command-list.h:155
+msgid "Lists commit objects in reverse chronological order"
+msgstr ""
+
+#: command-list.h:156
+msgid "Pick out and massage parameters"
+msgstr ""
+
+#: command-list.h:157
 msgid "Remove files from the working tree and from the index"
 msgstr ""
 
-#: common-cmds.h:35
+#: command-list.h:158
+msgid "Send a collection of patches as emails"
+msgstr ""
+
+#: command-list.h:159
+msgid "Push objects over Git protocol to another repository"
+msgstr ""
+
+#: command-list.h:160
+msgid "Restricted login shell for Git-only SSH access"
+msgstr ""
+
+#: command-list.h:161
+msgid "Summarize 'git log' output"
+msgstr ""
+
+#: command-list.h:162
 msgid "Show various types of objects"
 msgstr ""
 
-#: common-cmds.h:36
+#: command-list.h:163
+msgid "Show branches and their commits"
+msgstr ""
+
+#: command-list.h:164
+msgid "Show packed archive index"
+msgstr ""
+
+#: command-list.h:165
+msgid "List references in a local repository"
+msgstr ""
+
+#: command-list.h:166
+msgid "Git's i18n setup code for shell scripts"
+msgstr ""
+
+#: command-list.h:167
+msgid "Common Git shell script setup code"
+msgstr ""
+
+#: command-list.h:168
+msgid "Stash the changes in a dirty working directory away"
+msgstr ""
+
+#: command-list.h:169
+msgid "Add file contents to the staging area"
+msgstr ""
+
+#: command-list.h:170
 msgid "Show the working tree status"
 msgstr ""
 
-#: common-cmds.h:37
+#: command-list.h:171
+msgid "Remove unnecessary whitespace"
+msgstr ""
+
+#: command-list.h:172
+msgid "Initialize, update or inspect submodules"
+msgstr ""
+
+#: command-list.h:173
+msgid "Bidirectional operation between a Subversion repository and Git"
+msgstr ""
+
+#: command-list.h:174
+msgid "Read, modify and delete symbolic refs"
+msgstr ""
+
+#: command-list.h:175
 msgid "Create, list, delete or verify a tag object signed with GPG"
 msgstr ""
 
-#: parse-options.h:157
-msgid "expiry-date"
+#: command-list.h:176
+msgid "Creates a temporary file with a blob's contents"
 msgstr ""
 
-#: parse-options.h:172
-msgid "no-op (backward compatibility)"
+#: command-list.h:177
+msgid "Unpack objects from a packed archive"
 msgstr ""
 
-#: parse-options.h:250
-msgid "be more verbose"
+#: command-list.h:178
+msgid "Register file contents in the working tree to the index"
 msgstr ""
 
-#: parse-options.h:252
-msgid "be more quiet"
+#: command-list.h:179
+msgid "Update the object name stored in a ref safely"
 msgstr ""
 
-#: parse-options.h:258
-msgid "use <n> digits to display SHA-1s"
+#: command-list.h:180
+msgid "Update auxiliary info file to help dumb servers"
+msgstr ""
+
+#: command-list.h:181
+msgid "Send archive back to git-archive"
+msgstr ""
+
+#: command-list.h:182
+msgid "Send objects packed back to git-fetch-pack"
+msgstr ""
+
+#: command-list.h:183
+msgid "Show a Git logical variable"
+msgstr ""
+
+#: command-list.h:184
+msgid "Check the GPG signature of commits"
+msgstr ""
+
+#: command-list.h:185
+msgid "Validate packed Git archive files"
+msgstr ""
+
+#: command-list.h:186
+msgid "Check the GPG signature of tags"
+msgstr ""
+
+#: command-list.h:187
+msgid "Git web interface (web frontend to Git repositories)"
+msgstr ""
+
+#: command-list.h:188
+msgid "Show logs with difference each commit introduces"
+msgstr ""
+
+#: command-list.h:189
+msgid "Manage multiple working trees"
+msgstr ""
+
+#: command-list.h:190
+msgid "Create a tree object from the current index"
+msgstr ""
+
+#: command-list.h:191
+msgid "Defining attributes per path"
+msgstr ""
+
+#: command-list.h:192
+msgid "Git command-line interface and conventions"
+msgstr ""
+
+#: command-list.h:193
+msgid "A Git core tutorial for developers"
+msgstr ""
+
+#: command-list.h:194
+msgid "Git for CVS users"
+msgstr ""
+
+#: command-list.h:195
+msgid "Tweaking diff output"
+msgstr ""
+
+#: command-list.h:196
+msgid "A useful minimum set of commands for Everyday Git"
+msgstr ""
+
+#: command-list.h:197
+msgid "A Git Glossary"
+msgstr ""
+
+#: command-list.h:198
+msgid "Hooks used by Git"
+msgstr ""
+
+#: command-list.h:199
+msgid "Specifies intentionally untracked files to ignore"
+msgstr ""
+
+#: command-list.h:200
+msgid "Defining submodule properties"
+msgstr ""
+
+#: command-list.h:201
+msgid "Git namespaces"
+msgstr ""
+
+#: command-list.h:202
+msgid "Git Repository Layout"
+msgstr ""
+
+#: command-list.h:203
+msgid "Specifying revisions and ranges for Git"
+msgstr ""
+
+#: command-list.h:204
+msgid "A tutorial introduction to Git: part two"
+msgstr ""
+
+#: command-list.h:205
+msgid "A tutorial introduction to Git"
+msgstr ""
+
+#: command-list.h:206
+msgid "An overview of recommended workflows with Git"
 msgstr ""
 
 #: rerere.h:40
@@ -14361,7 +15383,7 @@ msgstr ""
 msgid "Simple merge did not work, trying automatic merge."
 msgstr ""
 
-#: git-rebase.sh:60
+#: git-rebase.sh:61
 msgid ""
 "Resolve all conflicts manually, mark them as resolved with\n"
 "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
@@ -14370,47 +15392,47 @@ msgid ""
 "abort\"."
 msgstr ""
 
-#: git-rebase.sh:163 git-rebase.sh:409
+#: git-rebase.sh:173 git-rebase.sh:442
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr ""
 
-#: git-rebase.sh:174
+#: git-rebase.sh:184
 msgid "Applied autostash."
 msgstr ""
 
-#: git-rebase.sh:177
+#: git-rebase.sh:187
 #, sh-format
 msgid "Cannot store $stash_sha1"
 msgstr ""
 
-#: git-rebase.sh:218
+#: git-rebase.sh:229
 msgid "The pre-rebase hook refused to rebase."
 msgstr ""
 
-#: git-rebase.sh:223
+#: git-rebase.sh:234
 msgid "It looks like 'git am' is in progress. Cannot rebase."
 msgstr ""
 
-#: git-rebase.sh:370
+#: git-rebase.sh:403
 msgid "No rebase in progress?"
 msgstr ""
 
-#: git-rebase.sh:381
+#: git-rebase.sh:414
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr ""
 
-#: git-rebase.sh:388
+#: git-rebase.sh:421
 msgid "Cannot read HEAD"
 msgstr ""
 
-#: git-rebase.sh:391
+#: git-rebase.sh:424
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
 msgstr ""
 
-#: git-rebase.sh:435
+#: git-rebase.sh:468
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -14423,74 +15445,78 @@ msgid ""
 "valuable there."
 msgstr ""
 
-#: git-rebase.sh:491
+#: git-rebase.sh:509
+msgid "error: cannot combine '--signoff' with '--preserve-merges'"
+msgstr ""
+
+#: git-rebase.sh:537
 #, sh-format
 msgid "invalid upstream '$upstream_name'"
 msgstr ""
 
-#: git-rebase.sh:515
+#: git-rebase.sh:561
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr ""
 
-#: git-rebase.sh:518 git-rebase.sh:522
+#: git-rebase.sh:564 git-rebase.sh:568
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr ""
 
-#: git-rebase.sh:527
+#: git-rebase.sh:573
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr ""
 
-#: git-rebase.sh:553
+#: git-rebase.sh:599
 #, sh-format
 msgid "fatal: no such branch/commit '$branch_name'"
 msgstr ""
 
-#: git-rebase.sh:586
+#: git-rebase.sh:632
 msgid "Cannot autostash"
 msgstr ""
 
-#: git-rebase.sh:591
+#: git-rebase.sh:637
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr ""
 
-#: git-rebase.sh:595
+#: git-rebase.sh:641
 msgid "Please commit or stash them."
 msgstr ""
 
-#: git-rebase.sh:618
+#: git-rebase.sh:664
 #, sh-format
 msgid "HEAD is up to date."
 msgstr ""
 
-#: git-rebase.sh:620
+#: git-rebase.sh:666
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr ""
 
-#: git-rebase.sh:628
+#: git-rebase.sh:674
 #, sh-format
 msgid "HEAD is up to date, rebase forced."
 msgstr ""
 
-#: git-rebase.sh:630
+#: git-rebase.sh:676
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr ""
 
-#: git-rebase.sh:642
+#: git-rebase.sh:688
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr ""
 
-#: git-rebase.sh:651
+#: git-rebase.sh:697
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr ""
 
-#: git-rebase.sh:661
+#: git-rebase.sh:707
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr ""
@@ -14558,109 +15584,109 @@ msgstr ""
 msgid "Saved working directory and index state $stash_msg"
 msgstr ""
 
-#: git-stash.sh:340
+#: git-stash.sh:342
 msgid "Cannot remove worktree changes"
 msgstr ""
 
-#: git-stash.sh:488
+#: git-stash.sh:490
 #, sh-format
 msgid "unknown option: $opt"
 msgstr ""
 
-#: git-stash.sh:501
+#: git-stash.sh:503
 msgid "No stash entries found."
 msgstr ""
 
-#: git-stash.sh:508
+#: git-stash.sh:510
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr ""
 
-#: git-stash.sh:523
+#: git-stash.sh:525
 #, sh-format
 msgid "$reference is not a valid reference"
 msgstr ""
 
-#: git-stash.sh:551
+#: git-stash.sh:553
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr ""
 
-#: git-stash.sh:562
+#: git-stash.sh:564
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr ""
 
-#: git-stash.sh:570
+#: git-stash.sh:572
 msgid "unable to refresh index"
 msgstr ""
 
-#: git-stash.sh:574
+#: git-stash.sh:576
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr ""
 
-#: git-stash.sh:582
+#: git-stash.sh:584
 msgid "Conflicts in index. Try without --index."
 msgstr ""
 
-#: git-stash.sh:584
+#: git-stash.sh:586
 msgid "Could not save index tree"
 msgstr ""
 
-#: git-stash.sh:593
+#: git-stash.sh:595
 msgid "Could not restore untracked files from stash entry"
 msgstr ""
 
-#: git-stash.sh:618
+#: git-stash.sh:620
 msgid "Cannot unstage modified files"
 msgstr ""
 
-#: git-stash.sh:633
+#: git-stash.sh:635
 msgid "Index was not unstashed."
 msgstr ""
 
-#: git-stash.sh:647
+#: git-stash.sh:649
 msgid "The stash entry is kept in case you need it again."
 msgstr ""
 
-#: git-stash.sh:656
+#: git-stash.sh:658
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr ""
 
-#: git-stash.sh:657
+#: git-stash.sh:659
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr ""
 
-#: git-stash.sh:665
+#: git-stash.sh:667
 msgid "No branch name specified"
 msgstr ""
 
-#: git-stash.sh:744
+#: git-stash.sh:746
 msgid "(To restore them type \"git stash apply\")"
 msgstr ""
 
-#: git-submodule.sh:181
+#: git-submodule.sh:188
 msgid "Relative path can only be used from the toplevel of the working tree"
 msgstr ""
 
-#: git-submodule.sh:191
+#: git-submodule.sh:198
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr ""
 
-#: git-submodule.sh:210
+#: git-submodule.sh:217
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr ""
 
-#: git-submodule.sh:213
+#: git-submodule.sh:220
 #, sh-format
 msgid "'$sm_path' already exists in the index and is not a submodule"
 msgstr ""
 
-#: git-submodule.sh:219
+#: git-submodule.sh:226
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -14668,22 +15694,22 @@ msgid ""
 "Use -f if you really want to add it."
 msgstr ""
 
-#: git-submodule.sh:237
+#: git-submodule.sh:249
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr ""
 
-#: git-submodule.sh:239
+#: git-submodule.sh:251
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr ""
 
-#: git-submodule.sh:247
+#: git-submodule.sh:259
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
 msgstr ""
 
-#: git-submodule.sh:249
+#: git-submodule.sh:261
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from\n"
@@ -14694,130 +15720,130 @@ msgid ""
 "option."
 msgstr ""
 
-#: git-submodule.sh:255
+#: git-submodule.sh:267
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
 msgstr ""
 
-#: git-submodule.sh:267
+#: git-submodule.sh:279
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:272
+#: git-submodule.sh:284
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:281
+#: git-submodule.sh:293
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:342
+#: git-submodule.sh:354
 #, sh-format
 msgid "Entering '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:362
+#: git-submodule.sh:374
 #, sh-format
 msgid "Stopping at '$displaypath'; script returned non-zero status."
 msgstr ""
 
-#: git-submodule.sh:584
+#: git-submodule.sh:600
 #, sh-format
 msgid "Unable to find current revision in submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:594
+#: git-submodule.sh:610
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:599
+#: git-submodule.sh:615
 #, sh-format
 msgid ""
 "Unable to find current ${remote_name}/${branch} revision in submodule path "
 "'$sm_path'"
 msgstr ""
 
-#: git-submodule.sh:617
+#: git-submodule.sh:633
 #, sh-format
 msgid "Unable to fetch in submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:623
+#: git-submodule.sh:639
 #, sh-format
 msgid ""
 "Fetched in submodule path '$displaypath', but it did not contain $sha1. "
 "Direct fetching of that commit failed."
 msgstr ""
 
-#: git-submodule.sh:630
+#: git-submodule.sh:646
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:631
+#: git-submodule.sh:647
 #, sh-format
 msgid "Submodule path '$displaypath': checked out '$sha1'"
 msgstr ""
 
-#: git-submodule.sh:635
+#: git-submodule.sh:651
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:636
+#: git-submodule.sh:652
 #, sh-format
 msgid "Submodule path '$displaypath': rebased into '$sha1'"
 msgstr ""
 
-#: git-submodule.sh:641
+#: git-submodule.sh:657
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:642
+#: git-submodule.sh:658
 #, sh-format
 msgid "Submodule path '$displaypath': merged in '$sha1'"
 msgstr ""
 
-#: git-submodule.sh:647
+#: git-submodule.sh:663
 #, sh-format
 msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:648
+#: git-submodule.sh:664
 #, sh-format
 msgid "Submodule path '$displaypath': '$command $sha1'"
 msgstr ""
 
-#: git-submodule.sh:679
+#: git-submodule.sh:695
 #, sh-format
 msgid "Failed to recurse into submodule path '$displaypath'"
 msgstr ""
 
-#: git-submodule.sh:775
+#: git-submodule.sh:791
 msgid "The --cached option cannot be used with the --files option"
 msgstr ""
 
-#: git-submodule.sh:827
+#: git-submodule.sh:843
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr ""
 
-#: git-submodule.sh:847
+#: git-submodule.sh:863
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr ""
 
-#: git-submodule.sh:850
+#: git-submodule.sh:866
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr ""
 
-#: git-submodule.sh:853
+#: git-submodule.sh:869
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
@@ -14827,39 +15853,45 @@ msgstr ""
 msgid "See git-${cmd}(1) for details."
 msgstr ""
 
-#: git-rebase--interactive.sh:140
+#: git-rebase--interactive.sh:142
 #, sh-format
 msgid "Rebasing ($new_count/$total)"
 msgstr ""
 
-#: git-rebase--interactive.sh:156
+#: git-rebase--interactive.sh:158
 msgid ""
 "\n"
 "Commands:\n"
-"p, pick = use commit\n"
-"r, reword = use commit, but edit the commit message\n"
-"e, edit = use commit, but stop for amending\n"
-"s, squash = use commit, but meld into previous commit\n"
-"f, fixup = like \"squash\", but discard this commit's log message\n"
-"x, exec = run command (the rest of the line) using shell\n"
-"d, drop = remove commit\n"
+"p, pick <commit> = use commit\n"
+"r, reword <commit> = use commit, but edit the commit message\n"
+"e, edit <commit> = use commit, but stop for amending\n"
+"s, squash <commit> = use commit, but meld into previous commit\n"
+"f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
+"x, exec <command> = run command (the rest of the line) using shell\n"
+"d, drop <commit> = remove commit\n"
+"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"
 "\n"
 "These lines can be re-ordered; they are executed from top to bottom.\n"
 msgstr ""
 
-#: git-rebase--interactive.sh:171
+#: git-rebase--interactive.sh:179
 msgid ""
 "\n"
 "Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
 msgstr ""
 
-#: git-rebase--interactive.sh:175
+#: git-rebase--interactive.sh:183
 msgid ""
 "\n"
 "If you remove a line here THAT COMMIT WILL BE LOST.\n"
 msgstr ""
 
-#: git-rebase--interactive.sh:213
+#: git-rebase--interactive.sh:221
 #, sh-format
 msgid ""
 "You can amend the commit now, with\n"
@@ -14871,83 +15903,83 @@ msgid ""
 "\tgit rebase --continue"
 msgstr ""
 
-#: git-rebase--interactive.sh:238
+#: git-rebase--interactive.sh:246
 #, sh-format
 msgid "$sha1: not a commit that can be picked"
 msgstr ""
 
-#: git-rebase--interactive.sh:277
+#: git-rebase--interactive.sh:285
 #, sh-format
 msgid "Invalid commit name: $sha1"
 msgstr ""
 
-#: git-rebase--interactive.sh:319
+#: git-rebase--interactive.sh:325
 msgid "Cannot write current commit's replacement sha1"
 msgstr ""
 
-#: git-rebase--interactive.sh:371
+#: git-rebase--interactive.sh:376
 #, sh-format
 msgid "Fast-forward to $sha1"
 msgstr ""
 
-#: git-rebase--interactive.sh:373
+#: git-rebase--interactive.sh:378
 #, sh-format
 msgid "Cannot fast-forward to $sha1"
 msgstr ""
 
-#: git-rebase--interactive.sh:382
+#: git-rebase--interactive.sh:387
 #, sh-format
 msgid "Cannot move HEAD to $first_parent"
 msgstr ""
 
-#: git-rebase--interactive.sh:387
+#: git-rebase--interactive.sh:392
 #, sh-format
 msgid "Refusing to squash a merge: $sha1"
 msgstr ""
 
-#: git-rebase--interactive.sh:405
+#: git-rebase--interactive.sh:410
 #, sh-format
 msgid "Error redoing merge $sha1"
 msgstr ""
 
-#: git-rebase--interactive.sh:414
+#: git-rebase--interactive.sh:419
 #, sh-format
 msgid "Could not pick $sha1"
 msgstr ""
 
-#: git-rebase--interactive.sh:423
+#: git-rebase--interactive.sh:428
 #, sh-format
 msgid "This is the commit message #${n}:"
 msgstr ""
 
-#: git-rebase--interactive.sh:428
+#: git-rebase--interactive.sh:433
 #, sh-format
 msgid "The commit message #${n} will be skipped:"
 msgstr ""
 
-#: git-rebase--interactive.sh:439
+#: git-rebase--interactive.sh:444
 #, sh-format
 msgid "This is a combination of $count commit."
 msgid_plural "This is a combination of $count commits."
 msgstr[0] ""
 msgstr[1] ""
 
-#: git-rebase--interactive.sh:448
+#: git-rebase--interactive.sh:453
 #, sh-format
 msgid "Cannot write $fixup_msg"
 msgstr ""
 
-#: git-rebase--interactive.sh:451
+#: git-rebase--interactive.sh:456
 msgid "This is a combination of 2 commits."
 msgstr ""
 
-#: git-rebase--interactive.sh:492 git-rebase--interactive.sh:535
-#: git-rebase--interactive.sh:538
+#: git-rebase--interactive.sh:497 git-rebase--interactive.sh:540
+#: git-rebase--interactive.sh:543
 #, sh-format
 msgid "Could not apply $sha1... $rest"
 msgstr ""
 
-#: git-rebase--interactive.sh:567
+#: git-rebase--interactive.sh:572
 #, sh-format
 msgid ""
 "Could not amend commit after successfully picking $sha1... $rest\n"
@@ -14957,31 +15989,31 @@ msgid ""
 "you are able to reword the commit."
 msgstr ""
 
-#: git-rebase--interactive.sh:582
+#: git-rebase--interactive.sh:587
 #, sh-format
 msgid "Stopped at $sha1_abbrev... $rest"
 msgstr ""
 
-#: git-rebase--interactive.sh:597
+#: git-rebase--interactive.sh:602
 #, sh-format
 msgid "Cannot '$squash_style' without a previous commit"
 msgstr ""
 
-#: git-rebase--interactive.sh:639
+#: git-rebase--interactive.sh:644
 #, sh-format
 msgid "Executing: $rest"
 msgstr ""
 
-#: git-rebase--interactive.sh:647
+#: git-rebase--interactive.sh:652
 #, sh-format
 msgid "Execution failed: $rest"
 msgstr ""
 
-#: git-rebase--interactive.sh:649
+#: git-rebase--interactive.sh:654
 msgid "and made changes to the index and/or the working tree"
 msgstr ""
 
-#: git-rebase--interactive.sh:651
+#: git-rebase--interactive.sh:656
 msgid ""
 "You can fix the problem, and then run\n"
 "\n"
@@ -14989,7 +16021,7 @@ msgid ""
 msgstr ""
 
 #. TRANSLATORS: after these lines is a command to be issued by the user
-#: git-rebase--interactive.sh:664
+#: git-rebase--interactive.sh:669
 #, sh-format
 msgid ""
 "Execution succeeded: $rest\n"
@@ -14999,29 +16031,29 @@ msgid ""
 "\tgit rebase --continue"
 msgstr ""
 
-#: git-rebase--interactive.sh:675
+#: git-rebase--interactive.sh:680
 #, sh-format
 msgid "Unknown command: $command $sha1 $rest"
 msgstr ""
 
-#: git-rebase--interactive.sh:676
+#: git-rebase--interactive.sh:681
 msgid "Please fix this using 'git rebase --edit-todo'."
 msgstr ""
 
-#: git-rebase--interactive.sh:711
+#: git-rebase--interactive.sh:716
 #, sh-format
 msgid "Successfully rebased and updated $head_name."
 msgstr ""
 
-#: git-rebase--interactive.sh:735
+#: git-rebase--interactive.sh:740
 msgid "could not detach HEAD"
 msgstr ""
 
-#: git-rebase--interactive.sh:771
+#: git-rebase--interactive.sh:778
 msgid "Could not remove CHERRY_PICK_HEAD"
 msgstr ""
 
-#: git-rebase--interactive.sh:776
+#: git-rebase--interactive.sh:783
 #, sh-format
 msgid ""
 "You have staged changes in your working tree.\n"
@@ -15039,21 +16071,21 @@ msgid ""
 "  git rebase --continue\n"
 msgstr ""
 
-#: git-rebase--interactive.sh:793
+#: git-rebase--interactive.sh:800
 msgid "Error trying to find the author identity to amend commit"
 msgstr ""
 
-#: git-rebase--interactive.sh:798
+#: git-rebase--interactive.sh:805
 msgid ""
 "You have uncommitted changes in your working tree. Please commit them\n"
 "first and then run 'git rebase --continue' again."
 msgstr ""
 
-#: git-rebase--interactive.sh:803 git-rebase--interactive.sh:807
+#: git-rebase--interactive.sh:810 git-rebase--interactive.sh:814
 msgid "Could not commit staged changes."
 msgstr ""
 
-#: git-rebase--interactive.sh:836
+#: git-rebase--interactive.sh:843
 msgid ""
 "\n"
 "You are editing the todo file of an ongoing interactive rebase.\n"
@@ -15062,54 +16094,55 @@ msgid ""
 "\n"
 msgstr ""
 
-#: git-rebase--interactive.sh:844 git-rebase--interactive.sh:1008
+#: git-rebase--interactive.sh:851 git-rebase--interactive.sh:937
 msgid "Could not execute editor"
 msgstr ""
 
-#: git-rebase--interactive.sh:860
+#: git-rebase--interactive.sh:872
 #, sh-format
 msgid "Could not checkout $switch_to"
 msgstr ""
 
-#: git-rebase--interactive.sh:865
+#: git-rebase--interactive.sh:879
 msgid "No HEAD?"
 msgstr ""
 
-#: git-rebase--interactive.sh:866
+#: git-rebase--interactive.sh:880
 #, sh-format
 msgid "Could not create temporary $state_dir"
 msgstr ""
 
-#: git-rebase--interactive.sh:869
+#: git-rebase--interactive.sh:883
 msgid "Could not mark as interactive"
 msgstr ""
 
-#: git-rebase--interactive.sh:879 git-rebase--interactive.sh:884
-msgid "Could not init rewritten commits"
-msgstr ""
-
-#: git-rebase--interactive.sh:910
-msgid "Could not generate todo list"
-msgstr ""
-
-#: git-rebase--interactive.sh:986
+#: git-rebase--interactive.sh:915
 #, sh-format
 msgid "Rebase $shortrevisions onto $shortonto ($todocount command)"
 msgid_plural "Rebase $shortrevisions onto $shortonto ($todocount commands)"
 msgstr[0] ""
 msgstr[1] ""
 
-#: git-rebase--interactive.sh:991
+#: git-rebase--interactive.sh:920
 msgid ""
 "\n"
-"However, if you remove everything, the rebase will be aborted.\n"
+"\tHowever, if you remove everything, the rebase will be aborted.\n"
 "\n"
+"\t"
 msgstr ""
 
-#: git-rebase--interactive.sh:998
+#: git-rebase--interactive.sh:927
 msgid "Note that empty commits are commented out"
 msgstr ""
 
+#: git-rebase--interactive.sh:980
+msgid "Could not generate todo list"
+msgstr ""
+
+#: git-rebase--interactive.sh:1001 git-rebase--interactive.sh:1006
+msgid "Could not init rewritten commits"
+msgstr ""
+
 #: git-sh-setup.sh:89 git-sh-setup.sh:94
 #, sh-format
 msgid "usage: $dashless $USAGE"
@@ -15181,107 +16214,107 @@ msgstr ""
 msgid "unstaged"
 msgstr ""
 
-#: git-add--interactive.perl:246 git-add--interactive.perl:271
+#: git-add--interactive.perl:253 git-add--interactive.perl:278
 msgid "binary"
 msgstr ""
 
-#: git-add--interactive.perl:255 git-add--interactive.perl:309
+#: git-add--interactive.perl:262 git-add--interactive.perl:316
 msgid "nothing"
 msgstr ""
 
-#: git-add--interactive.perl:291 git-add--interactive.perl:306
+#: git-add--interactive.perl:298 git-add--interactive.perl:313
 msgid "unchanged"
 msgstr ""
 
-#: git-add--interactive.perl:602
+#: git-add--interactive.perl:609
 #, perl-format
 msgid "added %d path\n"
 msgid_plural "added %d paths\n"
 msgstr[0] ""
 msgstr[1] ""
 
-#: git-add--interactive.perl:605
+#: git-add--interactive.perl:612
 #, perl-format
 msgid "updated %d path\n"
 msgid_plural "updated %d paths\n"
 msgstr[0] ""
 msgstr[1] ""
 
-#: git-add--interactive.perl:608
+#: git-add--interactive.perl:615
 #, perl-format
 msgid "reverted %d path\n"
 msgid_plural "reverted %d paths\n"
 msgstr[0] ""
 msgstr[1] ""
 
-#: git-add--interactive.perl:611
+#: git-add--interactive.perl:618
 #, perl-format
 msgid "touched %d path\n"
 msgid_plural "touched %d paths\n"
 msgstr[0] ""
 msgstr[1] ""
 
-#: git-add--interactive.perl:620
+#: git-add--interactive.perl:627
 msgid "Update"
 msgstr ""
 
-#: git-add--interactive.perl:632
+#: git-add--interactive.perl:639
 msgid "Revert"
 msgstr ""
 
-#: git-add--interactive.perl:655
+#: git-add--interactive.perl:662
 #, perl-format
 msgid "note: %s is untracked now.\n"
 msgstr ""
 
-#: git-add--interactive.perl:666
+#: git-add--interactive.perl:673
 msgid "Add untracked"
 msgstr ""
 
-#: git-add--interactive.perl:672
+#: git-add--interactive.perl:679
 msgid "No untracked files.\n"
 msgstr ""
 
-#: git-add--interactive.perl:1026
+#: git-add--interactive.perl:1033
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for staging."
 msgstr ""
 
-#: git-add--interactive.perl:1029
+#: git-add--interactive.perl:1036
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for stashing."
 msgstr ""
 
-#: git-add--interactive.perl:1032
+#: git-add--interactive.perl:1039
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for unstaging."
 msgstr ""
 
-#: git-add--interactive.perl:1035 git-add--interactive.perl:1044
+#: git-add--interactive.perl:1042 git-add--interactive.perl:1051
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for applying."
 msgstr ""
 
-#: git-add--interactive.perl:1038 git-add--interactive.perl:1041
+#: git-add--interactive.perl:1045 git-add--interactive.perl:1048
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for discarding."
 msgstr ""
 
-#: git-add--interactive.perl:1078
+#: git-add--interactive.perl:1085
 #, perl-format
 msgid "failed to open hunk edit file for writing: %s"
 msgstr ""
 
-#: git-add--interactive.perl:1079
+#: git-add--interactive.perl:1086
 msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
 msgstr ""
 
-#: git-add--interactive.perl:1085
+#: git-add--interactive.perl:1092
 #, perl-format
 msgid ""
 "---\n"
@@ -15291,14 +16324,14 @@ msgid ""
 msgstr ""
 
 #. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
-#: git-add--interactive.perl:1093
+#: git-add--interactive.perl:1100
 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 ""
 
-#: git-add--interactive.perl:1107
+#: git-add--interactive.perl:1114
 #, perl-format
 msgid "failed to open hunk edit file for reading: %s"
 msgstr ""
@@ -15309,12 +16342,12 @@ msgstr ""
 #. 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:1206
+#: git-add--interactive.perl:1213
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
 
-#: git-add--interactive.perl:1215
+#: git-add--interactive.perl:1222
 msgid ""
 "y - stage this hunk\n"
 "n - do not stage this hunk\n"
@@ -15323,7 +16356,7 @@ msgid ""
 "d - do not stage this hunk or any of the later hunks in the file"
 msgstr ""
 
-#: git-add--interactive.perl:1221
+#: git-add--interactive.perl:1228
 msgid ""
 "y - stash this hunk\n"
 "n - do not stash this hunk\n"
@@ -15332,7 +16365,7 @@ msgid ""
 "d - do not stash this hunk or any of the later hunks in the file"
 msgstr ""
 
-#: git-add--interactive.perl:1227
+#: git-add--interactive.perl:1234
 msgid ""
 "y - unstage this hunk\n"
 "n - do not unstage this hunk\n"
@@ -15341,7 +16374,7 @@ msgid ""
 "d - do not unstage this hunk or any of the later hunks in the file"
 msgstr ""
 
-#: git-add--interactive.perl:1233
+#: git-add--interactive.perl:1240
 msgid ""
 "y - apply this hunk to index\n"
 "n - do not apply this hunk to index\n"
@@ -15350,7 +16383,7 @@ msgid ""
 "d - do not apply this hunk or any of the later hunks in the file"
 msgstr ""
 
-#: git-add--interactive.perl:1239
+#: git-add--interactive.perl:1246
 msgid ""
 "y - discard this hunk from worktree\n"
 "n - do not discard this hunk from worktree\n"
@@ -15359,7 +16392,7 @@ msgid ""
 "d - do not discard this hunk or any of the later hunks in the file"
 msgstr ""
 
-#: git-add--interactive.perl:1245
+#: git-add--interactive.perl:1252
 msgid ""
 "y - discard this hunk from index and worktree\n"
 "n - do not discard this hunk from index and worktree\n"
@@ -15368,7 +16401,7 @@ msgid ""
 "d - do not discard this hunk or any of the later hunks in the file"
 msgstr ""
 
-#: git-add--interactive.perl:1251
+#: git-add--interactive.perl:1258
 msgid ""
 "y - apply this hunk to index and worktree\n"
 "n - do not apply this hunk to index and worktree\n"
@@ -15377,7 +16410,7 @@ msgid ""
 "d - do not apply this hunk or any of the later hunks in the file"
 msgstr ""
 
-#: git-add--interactive.perl:1266
+#: git-add--interactive.perl:1273
 msgid ""
 "g - select a hunk to go to\n"
 "/ - search for a hunk matching the given regex\n"
@@ -15390,211 +16423,211 @@ msgid ""
 "? - print help\n"
 msgstr ""
 
-#: git-add--interactive.perl:1297
+#: git-add--interactive.perl:1304
 msgid "The selected hunks do not apply to the index!\n"
 msgstr ""
 
-#: git-add--interactive.perl:1298
+#: git-add--interactive.perl:1305
 msgid "Apply them to the worktree anyway? "
 msgstr ""
 
-#: git-add--interactive.perl:1301
+#: git-add--interactive.perl:1308
 msgid "Nothing was applied.\n"
 msgstr ""
 
-#: git-add--interactive.perl:1312
+#: git-add--interactive.perl:1319
 #, perl-format
 msgid "ignoring unmerged: %s\n"
 msgstr ""
 
-#: git-add--interactive.perl:1321
+#: git-add--interactive.perl:1328
 msgid "Only binary files changed.\n"
 msgstr ""
 
-#: git-add--interactive.perl:1323
+#: git-add--interactive.perl:1330
 msgid "No changes.\n"
 msgstr ""
 
-#: git-add--interactive.perl:1331
+#: git-add--interactive.perl:1338
 msgid "Patch update"
 msgstr ""
 
-#: git-add--interactive.perl:1383
+#: git-add--interactive.perl:1390
 #, perl-format
 msgid "Stage mode change [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1384
+#: git-add--interactive.perl:1391
 #, perl-format
 msgid "Stage deletion [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1385
+#: git-add--interactive.perl:1392
 #, perl-format
 msgid "Stage this hunk [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1388
+#: git-add--interactive.perl:1395
 #, perl-format
 msgid "Stash mode change [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1389
+#: git-add--interactive.perl:1396
 #, perl-format
 msgid "Stash deletion [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1390
+#: git-add--interactive.perl:1397
 #, perl-format
 msgid "Stash this hunk [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1393
+#: git-add--interactive.perl:1400
 #, perl-format
 msgid "Unstage mode change [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1394
+#: git-add--interactive.perl:1401
 #, perl-format
 msgid "Unstage deletion [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1395
+#: git-add--interactive.perl:1402
 #, perl-format
 msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1398
+#: git-add--interactive.perl:1405
 #, perl-format
 msgid "Apply mode change to index [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1399
+#: git-add--interactive.perl:1406
 #, perl-format
 msgid "Apply deletion to index [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1400
+#: git-add--interactive.perl:1407
 #, perl-format
 msgid "Apply this hunk to index [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1403
+#: git-add--interactive.perl:1410
 #, perl-format
 msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1404
+#: git-add--interactive.perl:1411
 #, perl-format
 msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1405
+#: git-add--interactive.perl:1412
 #, perl-format
 msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1408
+#: git-add--interactive.perl:1415
 #, perl-format
 msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1409
+#: git-add--interactive.perl:1416
 #, perl-format
 msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1410
+#: git-add--interactive.perl:1417
 #, perl-format
 msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1413
+#: git-add--interactive.perl:1420
 #, perl-format
 msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1414
+#: git-add--interactive.perl:1421
 #, perl-format
 msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1415
+#: git-add--interactive.perl:1422
 #, perl-format
 msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
 msgstr ""
 
-#: git-add--interactive.perl:1515
+#: git-add--interactive.perl:1522
 msgid "No other hunks to goto\n"
 msgstr ""
 
-#: git-add--interactive.perl:1522
+#: git-add--interactive.perl:1529
 msgid "go to which hunk (<ret> to see more)? "
 msgstr ""
 
-#: git-add--interactive.perl:1524
+#: git-add--interactive.perl:1531
 msgid "go to which hunk? "
 msgstr ""
 
-#: git-add--interactive.perl:1533
+#: git-add--interactive.perl:1540
 #, perl-format
 msgid "Invalid number: '%s'\n"
 msgstr ""
 
-#: git-add--interactive.perl:1538
+#: git-add--interactive.perl:1545
 #, perl-format
 msgid "Sorry, only %d hunk available.\n"
 msgid_plural "Sorry, only %d hunks available.\n"
 msgstr[0] ""
 msgstr[1] ""
 
-#: git-add--interactive.perl:1564
+#: git-add--interactive.perl:1571
 msgid "No other hunks to search\n"
 msgstr ""
 
-#: git-add--interactive.perl:1568
+#: git-add--interactive.perl:1575
 msgid "search for regex? "
 msgstr ""
 
-#: git-add--interactive.perl:1581
+#: git-add--interactive.perl:1588
 #, perl-format
 msgid "Malformed search regexp %s: %s\n"
 msgstr ""
 
-#: git-add--interactive.perl:1591
+#: git-add--interactive.perl:1598
 msgid "No hunk matches the given pattern\n"
 msgstr ""
 
-#: git-add--interactive.perl:1603 git-add--interactive.perl:1625
+#: git-add--interactive.perl:1610 git-add--interactive.perl:1632
 msgid "No previous hunk\n"
 msgstr ""
 
-#: git-add--interactive.perl:1612 git-add--interactive.perl:1631
+#: git-add--interactive.perl:1619 git-add--interactive.perl:1638
 msgid "No next hunk\n"
 msgstr ""
 
-#: git-add--interactive.perl:1637
+#: git-add--interactive.perl:1644
 msgid "Sorry, cannot split this hunk\n"
 msgstr ""
 
-#: git-add--interactive.perl:1643
+#: git-add--interactive.perl:1650
 #, perl-format
 msgid "Split into %d hunk.\n"
 msgid_plural "Split into %d hunks.\n"
 msgstr[0] ""
 msgstr[1] ""
 
-#: git-add--interactive.perl:1653
+#: git-add--interactive.perl:1660
 msgid "Sorry, cannot edit this hunk\n"
 msgstr ""
 
-#: git-add--interactive.perl:1699
+#: git-add--interactive.perl:1706
 msgid "Review diff"
 msgstr ""
 
 #. TRANSLATORS: please do not translate the command names
 #. 'status', 'update', 'revert', etc.
-#: git-add--interactive.perl:1718
+#: git-add--interactive.perl:1725
 msgid ""
 "status        - show paths with changes\n"
 "update        - add working tree state to the staged set of changes\n"
@@ -15605,18 +16638,18 @@ msgid ""
 "changes\n"
 msgstr ""
 
-#: git-add--interactive.perl:1735 git-add--interactive.perl:1740
-#: git-add--interactive.perl:1743 git-add--interactive.perl:1750
-#: git-add--interactive.perl:1754 git-add--interactive.perl:1760
+#: git-add--interactive.perl:1742 git-add--interactive.perl:1747
+#: git-add--interactive.perl:1750 git-add--interactive.perl:1757
+#: git-add--interactive.perl:1761 git-add--interactive.perl:1767
 msgid "missing --"
 msgstr ""
 
-#: git-add--interactive.perl:1756
+#: git-add--interactive.perl:1763
 #, perl-format
 msgid "unknown --patch mode: %s"
 msgstr ""
 
-#: git-add--interactive.perl:1762 git-add--interactive.perl:1768
+#: git-add--interactive.perl:1769 git-add--interactive.perl:1775
 #, perl-format
 msgid "invalid argument %s, expecting --"
 msgstr ""
@@ -15805,7 +16838,7 @@ msgstr ""
 msgid "CA path \"%s\" does not exist"
 msgstr ""
 
-#: git-send-email.perl:1395
+#: git-send-email.perl:1400
 msgid ""
 "    The Cc list above has been expanded by additional\n"
 "    addresses found in the patch commit message. By default\n"
@@ -15819,131 +16852,131 @@ msgid ""
 "\n"
 msgstr ""
 
-#. TRANSLATORS: Make sure to include [y] [n] [q] [a] in your
+#. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
 #. translation. The program will only accept English input
 #. at this point.
-#: git-send-email.perl:1410
-msgid "Send this email? ([y]es|[n]o|[q]uit|[a]ll): "
+#: git-send-email.perl:1415
+msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
 msgstr ""
 
-#: git-send-email.perl:1413
+#: git-send-email.perl:1418
 msgid "Send this email reply required"
 msgstr ""
 
-#: git-send-email.perl:1439
+#: git-send-email.perl:1446
 msgid "The required SMTP server is not properly defined."
 msgstr ""
 
-#: git-send-email.perl:1486
+#: git-send-email.perl:1493
 #, perl-format
 msgid "Server does not support STARTTLS! %s"
 msgstr ""
 
-#: git-send-email.perl:1491 git-send-email.perl:1495
+#: git-send-email.perl:1498 git-send-email.perl:1502
 #, perl-format
 msgid "STARTTLS failed! %s"
 msgstr ""
 
-#: git-send-email.perl:1505
+#: git-send-email.perl:1512
 msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug."
 msgstr ""
 
-#: git-send-email.perl:1523
+#: git-send-email.perl:1530
 #, perl-format
 msgid "Failed to send %s\n"
 msgstr ""
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Dry-Sent %s\n"
 msgstr ""
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Sent %s\n"
 msgstr ""
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "Dry-OK. Log says:\n"
 msgstr ""
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "OK. Log says:\n"
 msgstr ""
 
-#: git-send-email.perl:1540
+#: git-send-email.perl:1547
 msgid "Result: "
 msgstr ""
 
-#: git-send-email.perl:1543
+#: git-send-email.perl:1550
 msgid "Result: OK\n"
 msgstr ""
 
-#: git-send-email.perl:1556
+#: git-send-email.perl:1568
 #, perl-format
 msgid "can't open file %s"
 msgstr ""
 
-#: git-send-email.perl:1603 git-send-email.perl:1623
+#: git-send-email.perl:1615 git-send-email.perl:1635
 #, perl-format
 msgid "(mbox) Adding cc: %s from line '%s'\n"
 msgstr ""
 
-#: git-send-email.perl:1609
+#: git-send-email.perl:1621
 #, perl-format
 msgid "(mbox) Adding to: %s from line '%s'\n"
 msgstr ""
 
-#: git-send-email.perl:1657
+#: git-send-email.perl:1674
 #, perl-format
 msgid "(non-mbox) Adding cc: %s from line '%s'\n"
 msgstr ""
 
-#: git-send-email.perl:1682
+#: git-send-email.perl:1699
 #, perl-format
 msgid "(body) Adding cc: %s from line '%s'\n"
 msgstr ""
 
-#: git-send-email.perl:1788
+#: git-send-email.perl:1817
 #, perl-format
 msgid "(%s) Could not execute '%s'"
 msgstr ""
 
-#: git-send-email.perl:1795
+#: git-send-email.perl:1824
 #, perl-format
 msgid "(%s) Adding %s: %s from: '%s'\n"
 msgstr ""
 
-#: git-send-email.perl:1799
+#: git-send-email.perl:1828
 #, perl-format
 msgid "(%s) failed to close pipe to '%s'"
 msgstr ""
 
-#: git-send-email.perl:1826
+#: git-send-email.perl:1855
 msgid "cannot send message as 7bit"
 msgstr ""
 
-#: git-send-email.perl:1834
+#: git-send-email.perl:1863
 msgid "invalid transfer encoding"
 msgstr ""
 
-#: git-send-email.perl:1872 git-send-email.perl:1923 git-send-email.perl:1933
+#: git-send-email.perl:1901 git-send-email.perl:1952 git-send-email.perl:1962
 #, perl-format
 msgid "unable to open %s: %s\n"
 msgstr ""
 
-#: git-send-email.perl:1875
+#: git-send-email.perl:1904
 #, perl-format
 msgid "%s: patch contains a line longer than 998 characters"
 msgstr ""
 
-#: git-send-email.perl:1891
+#: git-send-email.perl:1920
 #, perl-format
 msgid "Skipping %s with backup suffix '%s'.\n"
 msgstr ""
 
 #. TRANSLATORS: please keep "[y|N]" as is.
-#: git-send-email.perl:1895
+#: git-send-email.perl:1924
 #, perl-format
 msgid "Do you really want to send %s? [y|N]: "
 msgstr ""
index f833709acbb4dbc942f464305b7e69a7ed9fe3b9..dcfe21c223513488116977ed03ac624c2ff4f200 100644 (file)
--- a/po/ko.po
+++ b/po/ko.po
@@ -36,6 +36,7 @@
 #  | fast-forward | 정방향 진행                                  |
 #  | fsmonitor    | 파일 시스템 모니터                           |
 #  | Git          | 깃                                           |
+#  | graft        | 그래프트                                     |
 #  | head         | 헤드                                         |
 #  | hook         | 후크                                         |
 #  | history      | (커밋) 내역                                  |
@@ -63,8 +64,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2018-03-16 07:29+0800\n"
-"PO-Revision-Date: 2018-03-28 23:28+0900\n"
+"POT-Creation-Date: 2018-06-16 22:06+0800\n"
+"PO-Revision-Date: 2018-06-19 02:00+0900\n"
 "Last-Translator: Changwoo Ryu <cwryu@debian.org>\n"
 "Language-Team: Git Korean translation <http://github.com/changwoo/git-l10n-"
 "ko>\n"
@@ -75,37 +76,37 @@ msgstr ""
 "Plural-Forms: nplurals=1; plural=0;\n"
 "X-Generator: Poedit 2.0.6\n"
 
-#: advice.c:62
+#: advice.c:92
 #, c-format
-msgid "hint: %.*s\n"
-msgstr "힌트: %.*s\n"
+msgid "%shint: %.*s%s\n"
+msgstr "%s힌트: %.*s%s\n"
 
-#: advice.c:90
+#: advice.c:137
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr "병합하지 않은 파일이 있으므로, 커밋 빼오기를 할 수 없습니다."
 
-#: advice.c:92
+#: advice.c:139
 msgid "Committing is not possible because you have unmerged files."
 msgstr "병합하지 않은 파일이 있으므로, 커밋할 수 없습니다."
 
-#: advice.c:94
+#: advice.c:141
 msgid "Merging is not possible because you have unmerged files."
 msgstr "병합하지 않은 파일이 있으므로, 병합할 수 없습니다."
 
-#: advice.c:96
+#: advice.c:143
 msgid "Pulling is not possible because you have unmerged files."
 msgstr "병합하지 않은 파일이 있으므로, 풀을 할 수 없습니다."
 
-#: advice.c:98
+#: advice.c:145
 msgid "Reverting is not possible because you have unmerged files."
 msgstr "병합하지 않은 파일이 있으므로, 되돌리기를 할 수 없습니다."
 
-#: advice.c:100
+#: advice.c:147
 #, c-format
 msgid "It is not possible to %s because you have unmerged files."
 msgstr "병합하지 않은 파일이 있으므로, %s 할 수 없습니다."
 
-#: advice.c:108
+#: advice.c:155
 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."
@@ -113,23 +114,23 @@ msgstr ""
 "작업 폴더에서 문제를 바로잡은 다음, 'git add/rm <파일>'을 적절히\n"
 "사용해 해결 표시하고 커밋하십시오."
 
-#: advice.c:116
+#: advice.c:163
 msgid "Exiting because of an unresolved conflict."
 msgstr "해결하지 못한 충돌 때문에 끝납니다."
 
-#: advice.c:121 builtin/merge.c:1251
+#: advice.c:168 builtin/merge.c:1250
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
 msgstr "병합 작업을 다 마치지 않았습니다 (MERGE_HEAD 파일이 있습니다)."
 
-#: advice.c:123
+#: advice.c:170
 msgid "Please, commit your changes before merging."
 msgstr "병합하기 전에 변경 사항을 커밋하십시오."
 
-#: advice.c:124
+#: advice.c:171
 msgid "Exiting because of unfinished merge."
 msgstr "병합을 마치지 못했기 때문에 끝납니다."
 
-#: advice.c:130
+#: advice.c:177
 #, c-format
 msgid ""
 "Note: checking out '%s'.\n"
@@ -395,7 +396,7 @@ msgstr "패치 실패: %s:%ld"
 msgid "cannot checkout %s"
 msgstr "%s을(를) 가져올 수 없습니다"
 
-#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:277
+#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:278
 #, c-format
 msgid "failed to read %s"
 msgstr "%s을(를) 읽는데 실패했습니다"
@@ -593,7 +594,7 @@ msgstr[0] "%%s 패치를 (%d개 거부) 적용..."
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "truncating .rej 파일 이름을 '%.*s.rej'(으)로 자름"
 
-#: apply.c:4545 builtin/fetch.c:775 builtin/fetch.c:1025
+#: apply.c:4545 builtin/fetch.c:786 builtin/fetch.c:1036
 #, c-format
 msgid "cannot open %s"
 msgstr "%s을(를) 열 수 없습니다"
@@ -644,15 +645,15 @@ msgid "%d line applied after fixing whitespace errors."
 msgid_plural "%d lines applied after fixing whitespace errors."
 msgstr[0] "공백 오류를 바로잡은 뒤에 %d번 줄 적용."
 
-#: apply.c:4894 builtin/add.c:539 builtin/mv.c:298 builtin/rm.c:390
+#: apply.c:4894 builtin/add.c:538 builtin/mv.c:300 builtin/rm.c:389
 msgid "Unable to write new index file"
 msgstr "새 인덱스 파일에 쓸 수 없습니다"
 
 #: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257
-#: builtin/clone.c:118 builtin/fetch.c:127 builtin/pull.c:193
-#: builtin/submodule--helper.c:403 builtin/submodule--helper.c:1197
-#: builtin/submodule--helper.c:1200 builtin/submodule--helper.c:1567
-#: builtin/submodule--helper.c:1570 builtin/submodule--helper.c:1787
+#: builtin/clone.c:120 builtin/fetch.c:126 builtin/pull.c:198
+#: builtin/submodule--helper.c:405 builtin/submodule--helper.c:1210
+#: builtin/submodule--helper.c:1213 builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1587 builtin/submodule--helper.c:1807
 #: git-add--interactive.perl:197
 msgid "path"
 msgstr "경로"
@@ -727,7 +728,7 @@ msgstr "최소한 <n>줄이 컨텍스트와 일치하는지 확인합니다"
 
 #: apply.c:4960 builtin/am.c:2242 builtin/interpret-trailers.c:95
 #: builtin/interpret-trailers.c:97 builtin/interpret-trailers.c:99
-#: builtin/pack-objects.c:3035
+#: builtin/pack-objects.c:3177
 msgid "action"
 msgstr "동작"
 
@@ -755,9 +756,9 @@ msgstr "거부된 패치 부분을 대응되는 *.rej 파일에 남겨둡니다"
 msgid "allow overlapping hunks"
 msgstr "패치 부분이 겹쳐도 허용합니다"
 
-#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21
-#: builtin/commit.c:1276 builtin/count-objects.c:96 builtin/fsck.c:665
-#: builtin/log.c:1901 builtin/mv.c:123 builtin/read-tree.c:125
+#: apply.c:4977 builtin/add.c:290 builtin/check-ignore.c:21
+#: builtin/commit.c:1301 builtin/count-objects.c:98 builtin/fsck.c:666
+#: builtin/log.c:1901 builtin/mv.c:122 builtin/read-tree.c:124
 msgid "be verbose"
 msgstr "자세히 표시"
 
@@ -796,98 +797,98 @@ msgstr ""
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <저장소> [--exec <명령>] --list"
 
-#: archive.c:351 builtin/add.c:176 builtin/add.c:515 builtin/rm.c:299
+#: archive.c:351 builtin/add.c:176 builtin/add.c:514 builtin/rm.c:298
 #, c-format
 msgid "pathspec '%s' did not match any files"
 msgstr "'%s' 경로명세가 어떤 파일과도 일치하지 않습니다"
 
-#: archive.c:436
+#: archive.c:434
 msgid "fmt"
 msgstr "형식"
 
-#: archive.c:436
+#: archive.c:434
 msgid "archive format"
 msgstr "압축 형식"
 
-#: archive.c:437 builtin/log.c:1462
+#: archive.c:435 builtin/log.c:1462
 msgid "prefix"
 msgstr "접두어"
 
-#: archive.c:438
+#: archive.c:436
 msgid "prepend prefix to each pathname in the archive"
 msgstr "아카이브의 각 경로 이름의 앞에 지정한 경로를 붙입니다"
 
-#: archive.c:439 builtin/blame.c:702 builtin/blame.c:703 builtin/config.c:62
-#: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:869
+#: archive.c:437 builtin/blame.c:813 builtin/blame.c:814 builtin/config.c:127
+#: builtin/fast-export.c:1007 builtin/fast-export.c:1009 builtin/grep.c:869
 #: builtin/hash-object.c:103 builtin/ls-files.c:551 builtin/ls-files.c:554
-#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120
+#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:119
 #: parse-options.h:165
 msgid "file"
 msgstr "파일"
 
-#: archive.c:440 builtin/archive.c:89
+#: archive.c:438 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "아카이브를 이 파일에 씁니다"
 
-#: archive.c:442
+#: archive.c:440
 msgid "read .gitattributes in working directory"
 msgstr "작업 폴더의 .gitattributes를 읽습니다"
 
-#: archive.c:443
+#: archive.c:441
 msgid "report archived files on stderr"
 msgstr "아카이브에 포함된 파일을 표준오류로 표시합니다"
 
-#: archive.c:444
+#: archive.c:442
 msgid "store only"
 msgstr "저장만 하기"
 
-#: archive.c:445
+#: archive.c:443
 msgid "compress faster"
 msgstr "더 빠르게 압축"
 
-#: archive.c:453
+#: archive.c:451
 msgid "compress better"
 msgstr "더 작게 압축"
 
-#: archive.c:456
+#: archive.c:454
 msgid "list supported archive formats"
 msgstr "지원하는 압축 형식의 목록을 표시합니다"
 
-#: archive.c:458 builtin/archive.c:90 builtin/clone.c:108 builtin/clone.c:111
-#: builtin/submodule--helper.c:1209 builtin/submodule--helper.c:1576
+#: archive.c:456 builtin/archive.c:90 builtin/clone.c:110 builtin/clone.c:113
+#: builtin/submodule--helper.c:1222 builtin/submodule--helper.c:1593
 msgid "repo"
 msgstr "저장소"
 
-#: archive.c:459 builtin/archive.c:91
+#: archive.c:457 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "원격 저장소 <저장소>에서 아카이브를 가져옵니다"
 
-#: archive.c:460 builtin/archive.c:92 builtin/notes.c:489
+#: archive.c:458 builtin/archive.c:92 builtin/notes.c:489
 msgid "command"
 msgstr "명령"
 
-#: archive.c:461 builtin/archive.c:93
+#: archive.c:459 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "원격 git-upload-archive 명령의 경로"
 
-#: archive.c:468
+#: archive.c:466
 msgid "Unexpected option --remote"
 msgstr "예상치 못한 옵션 --remote"
 
-#: archive.c:470
+#: archive.c:468
 msgid "Option --exec can only be used together with --remote"
 msgstr "--exec 옵션은 --remote 옵션과 같이 사용할 경우에만 쓸 수 있습니다."
 
-#: archive.c:472
+#: archive.c:470
 msgid "Unexpected option --output"
 msgstr "예상치 못한 옵션 --output"
 
-#: archive.c:494
+#: archive.c:492
 #, c-format
 msgid "Unknown archive format '%s'"
 msgstr "알 수 없는 아카이브 형식 '%s'"
 
-#: archive.c:501
+#: archive.c:499
 #, c-format
 msgid "Argument not supported for format '%s': -%d"
 msgstr "'%s' 형식에서는 지원하지 않는 인자: -%d"
@@ -905,22 +906,22 @@ msgstr ""
 "git attributes에서 반대 패턴은 무시됩니다.\n"
 "앞에 느낌표를 쓰려면 '\\!'를 사용하십시오."
 
-#: bisect.c:460
+#: bisect.c:461
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "'%s' 파일 안에 잘못된 따옴표가 붙은 내용: %s"
 
-#: bisect.c:668
+#: bisect.c:669
 #, c-format
 msgid "We cannot bisect more!\n"
 msgstr "더 이상 이등분할 수 없습니다!\n"
 
-#: bisect.c:722
+#: bisect.c:723
 #, c-format
 msgid "Not a valid commit name %s"
 msgstr "올바른 커밋 이름이 아닙니다 (%s)"
 
-#: bisect.c:746
+#: bisect.c:747
 #, c-format
 msgid ""
 "The merge base %s is bad.\n"
@@ -929,7 +930,7 @@ msgstr ""
 "%s 병합 베이스가 비정상입니다.\n"
 "버그가 %s 및 [%s] 사이에서 고쳐졌다는 뜻입니다.\n"
 
-#: bisect.c:751
+#: bisect.c:752
 #, c-format
 msgid ""
 "The merge base %s is new.\n"
@@ -938,7 +939,7 @@ msgstr ""
 "%s 병합 베이스가 새롭습니다.\n"
 "속성이 %s 및 [%s] 사이에서 변경되었습니다.\n"
 
-#: bisect.c:756
+#: bisect.c:757
 #, c-format
 msgid ""
 "The merge base %s is %s.\n"
@@ -947,7 +948,7 @@ msgstr ""
 "%s 병합 베이스가 %s입니다.\n"
 "처음 '%s' 커밋이 %s 및 [%s] 사이라는 뜻입니다.\n"
 
-#: bisect.c:764
+#: bisect.c:765
 #, c-format
 msgid ""
 "Some %s revs are not ancestors of the %s rev.\n"
@@ -958,47 +959,47 @@ msgstr ""
 "git bisect 명령은 이 경우에는 올바르게 동작하지 않습니다.\n"
 "%s 및 %s 리비전을 잘못 쓴 것 아닙니까?\n"
 
-#: bisect.c:777
+#: bisect.c:778
 #, c-format
 msgid ""
 "the merge base between %s and [%s] must be skipped.\n"
 "So we cannot be sure the first %s commit is between %s and %s.\n"
 "We continue anyway."
 msgstr ""
-"%s ë°\8f %s ì\82¬ì\9d´ì\9d\98 ë¨¸ì§\80 베이스를 건너뜁니다.\n"
+"%s ë°\8f %s ì\82¬ì\9d´ì\9d\98 ë³\91í\95© 베이스를 건너뜁니다.\n"
 "그러므로 처음 %s 커밋이 %s 및 %s 사이에 있는지 확신할 수 없습니다.\n"
 "어쨌든 계속합니다."
 
-#: bisect.c:810
+#: bisect.c:811
 #, c-format
 msgid "Bisecting: a merge base must be tested\n"
 msgstr "이등분: 병합 베이스를 시험해야 합니다\n"
 
-#: bisect.c:850
+#: bisect.c:851
 #, c-format
 msgid "a %s revision is needed"
 msgstr "하나의 %s 리비전이 필요합니다"
 
-#: bisect.c:869 builtin/notes.c:175 builtin/tag.c:235
+#: bisect.c:870 builtin/notes.c:175 builtin/tag.c:236
 #, c-format
 msgid "could not create file '%s'"
 msgstr "'%s' 파일을 만들 수 없습니다"
 
-#: bisect.c:920
+#: bisect.c:921
 #, c-format
 msgid "could not read file '%s'"
 msgstr "'%s' 파일을 읽을 수 없습니다"
 
-#: bisect.c:950
+#: bisect.c:951
 msgid "reading bisect refs failed"
 msgstr "이등분 레퍼런스 읽기에 실패했습니다"
 
-#: bisect.c:969
+#: bisect.c:970
 #, c-format
 msgid "%s was both %s and %s\n"
 msgstr "%s은(는) %s 및 %s 모두에 해당됩니다\n"
 
-#: bisect.c:977
+#: bisect.c:978
 #, c-format
 msgid ""
 "No testable commit found.\n"
@@ -1007,7 +1008,7 @@ msgstr ""
 "시험 가능한 커밋이 없습니다.\n"
 "잘못된 경로 파라미터로 시작하지 않았습니까?\n"
 
-#: bisect.c:996
+#: bisect.c:997
 #, c-format
 msgid "(roughly %d step)"
 msgid_plural "(roughly %d steps)"
@@ -1016,50 +1017,50 @@ msgstr[0] "(대략 %d 단계)"
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
 #.
-#: bisect.c:1002
+#: bisect.c:1003
 #, 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] "이등분: %2$s 뒤에 시험할 리비전이 %1$d개 남았습니다\n"
 
-#: blame.c:1758
+#: blame.c:1756
 msgid "--contents and --reverse do not blend well."
 msgstr "--contents 및 --reverse 옵션은 호환되지 않습니다."
 
-#: blame.c:1769
+#: blame.c:1767
 msgid "cannot use --contents with final commit object name"
 msgstr "--contents 옵션을 마지막 오브젝트 이름에 사용할 수 없습니다"
 
-#: blame.c:1789
+#: blame.c:1787
 msgid "--reverse and --first-parent together require specified latest commit"
 msgstr ""
 "--reverse 및 --first-parent 옵션을 같이 쓰면 최근 커밋을 지정해야 합니다"
 
-#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699
-#: sequencer.c:2901 builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920
-#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370
-#: builtin/shortlog.c:191
+#: blame.c:1796 bundle.c:160 ref-filter.c:2075 sequencer.c:1861
+#: sequencer.c:3632 builtin/commit.c:981 builtin/log.c:366 builtin/log.c:920
+#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:372
+#: builtin/shortlog.c:192
 msgid "revision walk setup failed"
 msgstr "리비전 walk 준비가 실패했습니다"
 
-#: blame.c:1816
+#: blame.c:1814
 msgid ""
 "--reverse --first-parent together require range along first-parent chain"
 msgstr ""
 "--reverse 및 --first-parent 옵션을 같이 쓰면 최초-상위 체인과 범위가 필요합니"
 "다"
 
-#: blame.c:1827
+#: blame.c:1825
 #, c-format
 msgid "no such path %s in %s"
 msgstr "%s 경로가 %s 안에 없습니다"
 
-#: blame.c:1838
+#: blame.c:1836
 #, c-format
 msgid "cannot read blob %s for path %s"
 msgstr "%s 경로에 대해 %s 블롭을 읽을 수 없음"
 
-#: branch.c:53
+#: branch.c:54
 #, c-format
 msgid ""
 "\n"
@@ -1072,95 +1073,95 @@ msgstr ""
 "\"git branch --set-upstream-to=%s%s%s\" 명령을\n"
 "실행해 수정할 수 있습니다."
 
-#: branch.c:67
+#: branch.c:68
 #, c-format
 msgid "Not setting branch %s as its own upstream."
 msgstr "%s 브랜치를 자신의 업스트림으로 지정하지 않음."
 
-#: branch.c:93
+#: branch.c:94
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s' by rebasing."
 msgstr ""
 "'%s' 브랜치가 리베이스를 통해 리모트의 '%s' 브랜치를 ('%s'에서) 따라가도록 설"
 "정되었습니다."
 
-#: branch.c:94
+#: branch.c:95
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s'."
 msgstr ""
 "'%s' 브랜치가 리모트의 '%s' 브랜치를 ('%s'에서) 따라가도록 설정되었습니다."
 
-#: branch.c:98
+#: branch.c:99
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s' by rebasing."
 msgstr ""
 "'%s' 브랜치가 리베이스를 통해 리모트의 '%s' 브랜치를 따라가도록 설정되었습니"
 "다."
 
-#: branch.c:99
+#: branch.c:100
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s'."
 msgstr "'%s' 브랜치가 '%s' 브랜치를 따라가도록 설정되었습니다."
 
-#: branch.c:104
+#: branch.c:105
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s' by rebasing."
 msgstr ""
 "'%s' 브랜치가 리베이스를 통해 리모트의 '%s' 레퍼런스를 따라가도록 설정되었습"
 "니다."
 
-#: branch.c:105
+#: branch.c:106
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s'."
 msgstr "'%s' 브랜치가 리모트의 '%s' 레퍼런스를 따라가도록 설정되었습니다."
 
-#: branch.c:109
+#: branch.c:110
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s' by rebasing."
 msgstr ""
 "'%s' 브랜치가 리베이스를 통해 로컬의 '%s' 레퍼런스를 따라가도록 설정되었습니"
 "다."
 
-#: branch.c:110
+#: branch.c:111
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s'."
 msgstr "'%s' 브랜치가 로컬의 '%s' 레퍼런스를 따라가도록 설정되었습니다."
 
-#: branch.c:119
+#: branch.c:120
 msgid "Unable to write upstream branch configuration"
 msgstr "업스트림 브랜치 설정을 쓸 수 없습니다"
 
-#: branch.c:156
+#: branch.c:157
 #, c-format
 msgid "Not tracking: ambiguous information for ref %s"
 msgstr "따라가지 않음: %s 레퍼런스에 대해 애매한 정보"
 
-#: branch.c:189
+#: branch.c:190
 #, c-format
 msgid "'%s' is not a valid branch name."
 msgstr "'%s'은(는) 올바른 브랜치 이름이 아닙니다."
 
-#: branch.c:208
+#: branch.c:209
 #, c-format
 msgid "A branch named '%s' already exists."
 msgstr "이름이 '%s'인 브랜치가 이미 있습니다."
 
-#: branch.c:213
+#: branch.c:214
 msgid "Cannot force update the current branch."
 msgstr "현재 브랜치를 강제로 업데이트할 수 없습니다."
 
-#: branch.c:233
+#: branch.c:234
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr ""
 "따라가기 정보를 설정할 수 없습니다. 시작 위치 '%s'이(가) 브랜치가 아닙니다."
 
-#: branch.c:235
+#: branch.c:236
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr "요청한 업스트림 '%s' 브랜치가 없습니다"
 
-#: branch.c:237
+#: branch.c:238
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -1178,27 +1179,27 @@ msgstr ""
 "새 로컬 브랜치를 거기에 해당하는 리모트 브랜치로 push하려면,\n"
 "\"git push -u\"로 push하는 업스트림을 설정할 수 있습니다."
 
-#: branch.c:280
+#: branch.c:281
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "올바른 오브젝트 이름이 아닙니다: '%s'."
 
-#: branch.c:300
+#: branch.c:301
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "애매한 오브젝트 이름: '%s'."
 
-#: branch.c:305
+#: branch.c:306
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "올바른 브랜치 위치가 아닙니다: '%s'."
 
-#: branch.c:359
+#: branch.c:360
 #, c-format
 msgid "'%s' is already checked out at '%s'"
 msgstr "'%s'은(는) 이미 '%s' 위치에 받아져 있습니다"
 
-#: branch.c:382
+#: branch.c:383
 #, c-format
 msgid "HEAD of working tree %s is not updated"
 msgstr "작업 폴더 %s의 헤드가 업데이트되지 않았습니다"
@@ -1213,7 +1214,7 @@ msgstr "'%s' 파일이 버전2 번들 파일로 보이지 않습니다"
 msgid "unrecognized header: %s%s (%d)"
 msgstr "인식할 수 없는 헤더: %s%s (%d)"
 
-#: bundle.c:88 sequencer.c:1879 sequencer.c:2337 builtin/commit.c:750
+#: bundle.c:88 sequencer.c:2081 sequencer.c:2558 builtin/commit.c:755
 #, c-format
 msgid "could not open '%s'"
 msgstr "'%s'을(를) 열 수 없습니다"
@@ -1255,7 +1256,7 @@ msgstr "rev-list 명령이 죽었습니다"
 msgid "ref '%s' is excluded by the rev-list options"
 msgstr "rev-list 옵션에서 '%s' 레퍼런스가 제외되었습니다"
 
-#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:296
+#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:303
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "알 수 없는 인자: %s"
@@ -1278,18 +1279,41 @@ msgstr "index-pack 명령이 죽었습니다"
 msgid "invalid color value: %.*s"
 msgstr "잘못된 색 값: %.*s"
 
-#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465
-#: builtin/am.c:1436 builtin/am.c:2072
+#: commit.c:43 sequencer.c:2364 builtin/am.c:421 builtin/am.c:465
+#: builtin/am.c:1436 builtin/am.c:2072 builtin/replace.c:376
+#: builtin/replace.c:448
 #, c-format
 msgid "could not parse %s"
 msgstr "parse %s을(를) 파싱할 수 없습니다"
 
-#: commit.c:43
+#: commit.c:45
 #, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s, 커밋이 아닙니다"
 
-#: commit.c:1506
+#: commit.c:182
+msgid ""
+"Support for <GIT_DIR>/info/grafts is deprecated\n"
+"and will be removed in a future Git version.\n"
+"\n"
+"Please use \"git replace --convert-graft-file\"\n"
+"to convert the grafts into replace refs.\n"
+"\n"
+"Turn this message off by running\n"
+"\"git config advice.graftFileDeprecated false\""
+msgstr ""
+"<GIT_DIR>/info/grafts에 대한 지원은 다음 깃\n"
+"버전에서 제거될 예정입니다.\n"
+"\n"
+"그래프트를 레퍼런스로 전환하려면\n"
+"\"git replace --convert-graft-file\" 명령을\n"
+"사용하십시오.\n"
+"\n"
+"이 메시지를 보지 않으려면\n"
+"\"git config advice.graftFileDeprecated false\"\n"
+"명령을 사용하십시오"
+
+#: commit.c:1540
 msgid ""
 "Warning: commit message did not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
@@ -1299,170 +1323,184 @@ msgstr ""
 "메시지를 수정한 다음 커밋을 수정하거나, 설정의 i18n.commitencoding\n"
 "변수를 프로젝트가 사용 중인 인코딩으로 맞추십시오.\n"
 
+#: commit-graph.c:669
+#, c-format
+msgid "the commit graph format cannot write %d commits"
+msgstr "커밋 그래프 포맷에서 커밋 %d개를 쓸 수 없습니다"
+
+#: commit-graph.c:696
+msgid "too many commits to write graph"
+msgstr "그래프를 쓰기에는 커밋 수가 너무 많습니다"
+
+#: commit-graph.c:707 builtin/init-db.c:516 builtin/init-db.c:521
+#, c-format
+msgid "cannot mkdir %s"
+msgstr "%s에 대해 mkdir를 할 수 없습니다"
+
 #: compat/obstack.c:405 compat/obstack.c:407
 msgid "memory exhausted"
 msgstr "메모리 바닥남"
 
-#: config.c:186
+#: config.c:187
 msgid "relative config include conditionals must come from files"
 msgstr "상대 경로 설정 include 조건은 파일에서 와야 합니다"
 
-#: config.c:720
+#: config.c:788
 #, c-format
 msgid "bad config line %d in blob %s"
 msgstr "블롭 %2$s 안에 %1$d번 줄에 잘못된 설정"
 
-#: config.c:724
+#: config.c:792
 #, c-format
 msgid "bad config line %d in file %s"
 msgstr "파일 %2$s 안에 %1$d번 줄에 잘못된 설정"
 
-#: config.c:728
+#: config.c:796
 #, c-format
 msgid "bad config line %d in standard input"
 msgstr "표준 입력 안에 %d번 줄에 잘못된 설정"
 
-#: config.c:732
+#: config.c:800
 #, c-format
 msgid "bad config line %d in submodule-blob %s"
 msgstr "하위 모듈 블롭 %2$s 안에 %1$d번 줄에 잘못된 설정"
 
-#: config.c:736
+#: config.c:804
 #, c-format
 msgid "bad config line %d in command line %s"
 msgstr "명령행 %2$s 안에 %1$d번 줄에 잘못된 설정"
 
-#: config.c:740
+#: config.c:808
 #, c-format
 msgid "bad config line %d in %s"
 msgstr "%2$s 안에 %1$d번 줄에 잘못된 설정"
 
-#: config.c:868
+#: config.c:936
 msgid "out of range"
 msgstr "범위를 벗어남"
 
-#: config.c:868
+#: config.c:936
 msgid "invalid unit"
 msgstr "단위가 잘못됨"
 
-#: config.c:874
+#: config.c:942
 #, c-format
 msgid "bad numeric config value '%s' for '%s': %s"
 msgstr "잘못된 수치 설정 값 '%s' (키 '%s'): %s"
 
-#: config.c:879
+#: config.c:947
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
 msgstr "잘못된 수치 설정 값 '%s' (키 '%s', 블롭 %s): %s"
 
-#: config.c:882
+#: config.c:950
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in file %s: %s"
 msgstr "잘못된 수치 설정 값 '%s' (키 '%s', 파일 %s): %s"
 
-#: config.c:885
+#: config.c:953
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in standard input: %s"
 msgstr "잘못된 수치 설정 값 '%s' (키 '%s', 표준입력): %s"
 
-#: config.c:888
+#: config.c:956
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
 msgstr "잘못된 수치 설정 값 '%s' (키 '%s', 하위 모듈 블롭 %s): %s"
 
-#: config.c:891
+#: config.c:959
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
 msgstr "잘못된 수치 설정 값 '%s' (키 '%s', 명령행 %s): %s"
 
-#: config.c:894
+#: config.c:962
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in %s: %s"
 msgstr "잘못된 수치 설정 값 '%s' (키 '%s', %s 안에): %s"
 
-#: config.c:989
+#: config.c:1057
 #, c-format
 msgid "failed to expand user dir in: '%s'"
 msgstr "다음에 사용자 디렉터리 확장에 실패: '%s'"
 
-#: config.c:998
+#: config.c:1066
 #, c-format
 msgid "'%s' for '%s' is not a valid timestamp"
 msgstr "'%s' 값이 '%s'에 대해 올바른 시각 값이 아닙니다"
 
-#: config.c:1094 config.c:1105
+#: config.c:1171 config.c:1182
 #, c-format
 msgid "bad zlib compression level %d"
 msgstr "%d번은 올바른 zlib 압축 단계가 아닙니다"
 
-#: config.c:1225
+#: config.c:1307
 #, c-format
 msgid "invalid mode for object creation: %s"
 msgstr "오브젝트 생성 모드가 올바르지 않습니다: %s"
 
-#: config.c:1386
+#: config.c:1473
 #, c-format
 msgid "bad pack compression level %d"
 msgstr "잘못 묶음 압축 단계 %d"
 
-#: config.c:1582
+#: config.c:1681
 msgid "unable to parse command-line config"
 msgstr "명령행 설정을 파싱할 수 없습니다"
 
-#: config.c:1914
+#: config.c:2013
 msgid "unknown error occurred while reading the configuration files"
 msgstr "설정 파일을 읽는 중 알 수 없는 오류가 생겼습니다"
 
-#: config.c:2101
+#: config.c:2200
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "잘못된 %s: '%s'"
 
-#: config.c:2144
+#: config.c:2243
 #, c-format
 msgid "unknown core.untrackedCache value '%s'; using 'keep' default value"
-msgstr "알 수 없는 core.untrackedCache 값 '%s'; 기본값으로 'keep' 사용"
+msgstr "알 수 없는 core.untrackedCache 값 '%s'. 기본값으로 'keep' 사용"
 
-#: config.c:2170
+#: config.c:2269
 #, c-format
 msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100"
 msgstr "splitIndex.maxPercentChange 값('%d')은 0에서 100 사이여야 합니다"
 
-#: config.c:2195
+#: config.c:2294
 #, c-format
 msgid "unable to parse '%s' from command-line config"
 msgstr "명령행 설정에서 '%s'을(를) 설정할 수 없습니다"
 
-#: config.c:2197
+#: config.c:2296
 #, c-format
 msgid "bad config variable '%s' in file '%s' at line %d"
 msgstr "'%2$s' 파일의 %3$d번 줄 '%1$s' 설정 변수가 잘못되었습니다"
 
-#: config.c:2256
+#: config.c:2402
 #, c-format
 msgid "%s has multiple values"
 msgstr "%s은(는) 여러 개 값이 있습니다"
 
-#: config.c:2599 config.c:2816
+#: config.c:2766 config.c:3019
 #, c-format
 msgid "fstat on %s failed"
 msgstr "%s에 대해 fstat 실패"
 
-#: config.c:2706
+#: config.c:2905
 #, c-format
 msgid "could not set '%s' to '%s'"
 msgstr "'%s'을(를) '%s'(으)로 설정할 수 없습니다"
 
-#: config.c:2708 builtin/remote.c:776
+#: config.c:2907 builtin/remote.c:779
 #, c-format
 msgid "could not unset '%s'"
 msgstr "'%s' 설정을 지울 수 없습니다"
 
-#: connect.c:52
+#: connect.c:61
 msgid "The remote end hung up upon initial contact"
 msgstr "리모트 측이 최초 연결했을 때 연결을 끊었습니다"
 
-#: connect.c:54
+#: connect.c:63
 msgid ""
 "Could not read from remote repository.\n"
 "\n"
@@ -1474,7 +1512,7 @@ msgstr ""
 "올바른 접근 권한이 있는지, 그리고 저장소가 있는지\n"
 "확인하십시오."
 
-#: connected.c:66 builtin/fsck.c:198 builtin/prune.c:144
+#: connected.c:66 builtin/fsck.c:201 builtin/prune.c:145
 msgid "Checking connectivity"
 msgstr "연결을 확인하는 중입니다"
 
@@ -1490,12 +1528,12 @@ msgstr "rev-list 쓰기에 실패했습니다"
 msgid "failed to close rev-list's stdin"
 msgstr "rev-list의 표준입력을 닫는데 실패했습니다"
 
-#: convert.c:205
+#: convert.c:206
 #, c-format
 msgid "CRLF would be replaced by LF in %s."
 msgstr "%s에서 CRLF는 LF로 바뀝니다."
 
-#: convert.c:207
+#: convert.c:208
 #, c-format
 msgid ""
 "CRLF will be replaced by LF in %s.\n"
@@ -1504,12 +1542,12 @@ msgstr ""
 "%s에서 CRLF는 LF로 바뀝니다.\n"
 "작업 디렉터리에서는 원래 줄 바꿈 형식을 유지합니다."
 
-#: convert.c:215
+#: convert.c:216
 #, c-format
 msgid "LF would be replaced by CRLF in %s"
 msgstr "%s에서 LF는 CRLF로 바뀝니다."
 
-#: convert.c:217
+#: convert.c:218
 #, c-format
 msgid ""
 "LF will be replaced by CRLF in %s.\n"
@@ -1518,6 +1556,50 @@ msgstr ""
 "%s에서 LF는 CRLF로 바뀝니다.\n"
 "작업 디렉터리에서는 원래 줄 바꿈 형식을 유지합니다."
 
+#: convert.c:279
+#, c-format
+msgid "BOM is prohibited in '%s' if encoded as %s"
+msgstr "'%s'에서 인코딩이 %s이면 BOM이 금지됩니다"
+
+#: convert.c:286
+#, c-format
+msgid ""
+"The file '%s' contains a byte order mark (BOM). Please use UTF-%s as working-"
+"tree-encoding."
+msgstr ""
+"'%s' 파일에 BOM(byte order mark)이 들어 있습니다. working-tree-encoding으로 "
+"UTF-%s 값을 사용하십시오."
+
+#: convert.c:304
+#, c-format
+msgid "BOM is required in '%s' if encoded as %s"
+msgstr "'%s'에서 인코딩이 %s이면 BOM이 필요합니다"
+
+#: convert.c:306
+#, 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 ""
+"'%s' 파일에 BOM(byte order mark)이 없습니다. (바이트 순서에 따라) UTF-%sBE 또"
+"는 UTF-%sLE 값을 working-tree-encoding으로 사용하십시오."
+
+#: convert.c:424
+#, c-format
+msgid "failed to encode '%s' from %s to %s"
+msgstr "'%s'의 인코딩을 %s에서 %s(으)로 변환하는데 실패했습니다"
+
+#: convert.c:467
+#, c-format
+msgid "encoding '%s' from %s to %s and back is not the same"
+msgstr ""
+"'%s'의 인코딩을 %s에서 %s(으)로 변환하고 다시 역으로 변환했을 때 원래 내용과 "
+"다릅니다."
+
+#: convert.c:1225
+msgid "true/false are no valid working-tree-encodings"
+msgstr "true/false는 올바른 working-tree-encodings 값이 아닙니다"
+
 #: date.c:116
 msgid "in the future"
 msgstr "미래에"
@@ -1623,25 +1705,25 @@ msgstr ""
 "'diff.submodule' 설정 변수에 오류:\n"
 "%s'"
 
-#: diff.c:3822
+#: diff.c:3823
 #, c-format
 msgid "external diff died, stopping at %s"
 msgstr "외부 diff 프로그램이 죽음, %s 위치에서 멈춤"
 
-#: diff.c:4146
+#: diff.c:4153
 msgid "--name-only, --name-status, --check and -s are mutually exclusive"
 msgstr ""
 "\"--name-only, --name-status, --check, -s 옵션 중 하나만 쓸 수 있습니다"
 
-#: diff.c:4149
+#: diff.c:4156
 msgid "-G, -S and --find-object are mutually exclusive"
 msgstr "-G, -S, --find-object 옵션 중 하나만 쓸 수 있습니다"
 
-#: diff.c:4237
+#: diff.c:4244
 msgid "--follow requires exactly one pathspec"
 msgstr "--follow 옵션에는 정확히 하나의 경로명세가 필요합니다"
 
-#: diff.c:4403
+#: diff.c:4410
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -1650,44 +1732,44 @@ msgstr ""
 "--dirstat/-X 옵션 파라미터를 파싱하는데 실패했습니다:\n"
 "%s"
 
-#: diff.c:4417
+#: diff.c:4424
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "--submodule 옵션 파라미터 파싱에 실패했습니다: '%s'"
 
-#: diff.c:5493
+#: diff.c:5500
 msgid "inexact rename detection was skipped due to too many files."
 msgstr "파일이 너무 많아서 부정확한 이름 바꾸기 검색 기능을 건너뜁니다."
 
-#: diff.c:5496
+#: diff.c:5503
 msgid "only found copies from modified paths due to too many files."
 msgstr "파일이 너무 많아서 수정한 경로의 복사본만 찾았습니다."
 
-#: diff.c:5499
+#: diff.c:5506
 #, c-format
 msgid ""
 "you may want to set your %s variable to at least %d and retry the command."
 msgstr "%s 변수를 최소한 %d(으)로 설정하고 명령을 다시 시도해 보십시오."
 
-#: dir.c:1866
+#: dir.c:1867
 #, c-format
 msgid "could not open directory '%s'"
 msgstr "'%s' 디렉터리를 열 수 없습니다"
 
-#: dir.c:2108
+#: dir.c:2109
 msgid "failed to get kernel name and information"
 msgstr "커널 이름과 정보를 가져오는데 실패했습니다"
 
-#: dir.c:2232
+#: dir.c:2233
 msgid "Untracked cache is disabled on this system or location."
 msgstr "이 시스템 또는 위치에서는 추적되지 않는 캐시를 사용하지 않습니다."
 
-#: dir.c:3024 dir.c:3029
+#: dir.c:3075 dir.c:3080
 #, c-format
 msgid "could not create directories for %s"
 msgstr "%s에 필요한 디렉터리를 만들 수 없습니다"
 
-#: dir.c:3054
+#: dir.c:3109
 #, c-format
 msgid "could not migrate git directory from '%s' to '%s'"
 msgstr "'%s'에서 '%s'(으)로 git 디렉터리를 옮겨올 수 없습니다"
@@ -1710,201 +1792,205 @@ msgstr "'%s' 파일에 stat을 할 수 없습니다"
 msgid "Remote with no URL"
 msgstr "URL 없는 리모트"
 
-#: fetch-pack.c:253
+#: fetch-pack.c:254
 msgid "git fetch-pack: expected shallow list"
 msgstr "git fetch-pack: 얕은 목록을 예상함"
 
-#: fetch-pack.c:265
+#: fetch-pack.c:266
 msgid "git fetch-pack: expected ACK/NAK, got a flush packet"
 msgstr "git fetch-pack: ACK/NAK가 와야 하지만, 플러시 패킷을 받았습니다"
 
-#: fetch-pack.c:284 builtin/archive.c:63
+#: fetch-pack.c:285 builtin/archive.c:63
 #, c-format
 msgid "remote error: %s"
 msgstr "리모트 오류: %s"
 
-#: fetch-pack.c:285
+#: fetch-pack.c:286
 #, c-format
 msgid "git fetch-pack: expected ACK/NAK, got '%s'"
 msgstr "git fetch-pack: ACK/NAK가 와야 하지만, '%s'을(를) 받았습니다"
 
-#: fetch-pack.c:337
+#: fetch-pack.c:338
 msgid "--stateless-rpc requires multi_ack_detailed"
 msgstr "--stateless-rpc 옵션은 multi_ack_detailed가 필요합니다"
 
-#: fetch-pack.c:428
+#: fetch-pack.c:429 fetch-pack.c:1310
 #, c-format
 msgid "invalid shallow line: %s"
 msgstr "shallow 줄이 잘못됨: %s"
 
-#: fetch-pack.c:434
+#: fetch-pack.c:435 fetch-pack.c:1316
 #, c-format
 msgid "invalid unshallow line: %s"
 msgstr "unshallow 줄이 잘못됨: %s"
 
-#: fetch-pack.c:436
+#: fetch-pack.c:437 fetch-pack.c:1318
 #, c-format
 msgid "object not found: %s"
 msgstr "오브젝트가 없습니다: %s"
 
-#: fetch-pack.c:439
+#: fetch-pack.c:440 fetch-pack.c:1321
 #, c-format
 msgid "error in object: %s"
 msgstr "오브젝트에 오류: %s"
 
-#: fetch-pack.c:441
+#: fetch-pack.c:442 fetch-pack.c:1323
 #, c-format
 msgid "no shallow found: %s"
 msgstr "shallow가 없습니다: %s"
 
-#: fetch-pack.c:444
+#: fetch-pack.c:445 fetch-pack.c:1326
 #, c-format
 msgid "expected shallow/unshallow, got %s"
 msgstr "shallow/unshallow가 와야 하지만, %s을(를) 받았습니다"
 
-#: fetch-pack.c:485
+#: fetch-pack.c:486
 #, c-format
 msgid "got %s %d %s"
 msgstr "받음: %s %d %s"
 
-#: fetch-pack.c:499
+#: fetch-pack.c:500
 #, c-format
 msgid "invalid commit %s"
 msgstr "잘못된 커밋 %s"
 
-#: fetch-pack.c:532
+#: fetch-pack.c:533
 msgid "giving up"
 msgstr "포기함"
 
-#: fetch-pack.c:542 progress.c:229
+#: fetch-pack.c:543 progress.c:229
 msgid "done"
 msgstr "완료"
 
-#: fetch-pack.c:554
+#: fetch-pack.c:555
 #, c-format
 msgid "got %s (%d) %s"
 msgstr "받음: %s (%d) %s"
 
-#: fetch-pack.c:600
+#: fetch-pack.c:601
 #, c-format
 msgid "Marking %s as complete"
 msgstr "%s 항목을 완료로 표시"
 
-#: fetch-pack.c:788
+#: fetch-pack.c:828
 #, c-format
 msgid "already have %s (%s)"
 msgstr "이미 %s (%s) 있음"
 
-#: fetch-pack.c:829
+#: fetch-pack.c:869
 msgid "fetch-pack: unable to fork off sideband demultiplexer"
 msgstr "fetch-pack: 사이드밴드 디멀티플렉서를 fork할 수 없습니다"
 
-#: fetch-pack.c:837
+#: fetch-pack.c:877
 msgid "protocol error: bad pack header"
 msgstr "프로토콜 오류: 잘못된 묶음 헤더"
 
-#: fetch-pack.c:895
+#: fetch-pack.c:944
 #, c-format
 msgid "fetch-pack: unable to fork off %s"
 msgstr "fetch-pack: %s 명령을 fork할 수 없습니다"
 
-#: fetch-pack.c:911
+#: fetch-pack.c:960
 #, c-format
 msgid "%s failed"
 msgstr "%s 실패"
 
-#: fetch-pack.c:913
+#: fetch-pack.c:962
 msgid "error in sideband demultiplexer"
 msgstr "사이드밴드 디멀티플렉서에 오류"
 
-#: fetch-pack.c:940
+#: fetch-pack.c:989
 msgid "Server does not support shallow clients"
 msgstr "서버에서 shallow 클라이언트를 지원하지 않습니다"
 
-#: fetch-pack.c:944
+#: fetch-pack.c:993
 msgid "Server supports multi_ack_detailed"
 msgstr "서버에서 multi_ack_detailed를 지원합니다"
 
-#: fetch-pack.c:947
+#: fetch-pack.c:996
 msgid "Server supports no-done"
 msgstr "서버에서 no-done을 지원합니다"
 
-#: fetch-pack.c:953
+#: fetch-pack.c:1002
 msgid "Server supports multi_ack"
 msgstr "서버에서 multi_ack를 지원합니다"
 
-#: fetch-pack.c:957
+#: fetch-pack.c:1006
 msgid "Server supports side-band-64k"
 msgstr "서버에서 side-band-64k를 지원합니다"
 
-#: fetch-pack.c:961
+#: fetch-pack.c:1010
 msgid "Server supports side-band"
 msgstr "서버에서 side-band를 지원합니다"
 
-#: fetch-pack.c:965
+#: fetch-pack.c:1014
 msgid "Server supports allow-tip-sha1-in-want"
 msgstr "서버에서 allow-tip-sha1-in-want를 지원합니다"
 
-#: fetch-pack.c:969
+#: fetch-pack.c:1018
 msgid "Server supports allow-reachable-sha1-in-want"
 msgstr "서버에서 allow-reachable-sha1-in-want를 지원합니다"
 
-#: fetch-pack.c:979
+#: fetch-pack.c:1028
 msgid "Server supports ofs-delta"
 msgstr "서버에서 ofs-delta를 지원합니다"
 
-#: fetch-pack.c:985
+#: fetch-pack.c:1034 fetch-pack.c:1204
 msgid "Server supports filter"
 msgstr "서버에서 필터를 지원합니다"
 
-#: fetch-pack.c:993
+#: fetch-pack.c:1042
 #, c-format
 msgid "Server version is %.*s"
 msgstr "서버 버전이 %.*s입니다"
 
-#: fetch-pack.c:999
+#: fetch-pack.c:1048
 msgid "Server does not support --shallow-since"
 msgstr "서버에서 --shallow-signed 옵션을 지원하지 않습니다"
 
-#: fetch-pack.c:1003
+#: fetch-pack.c:1052
 msgid "Server does not support --shallow-exclude"
 msgstr "서버에서 --shallow-exclude 옵션을 지원하지 않습니다"
 
-#: fetch-pack.c:1005
+#: fetch-pack.c:1054
 msgid "Server does not support --deepen"
 msgstr "서버에서 --deepen 옵션을 지원하지 않습니다"
 
-#: fetch-pack.c:1016
+#: fetch-pack.c:1065
 msgid "no common commits"
 msgstr "공통 커밋 없음"
 
-#: fetch-pack.c:1028
+#: fetch-pack.c:1077 fetch-pack.c:1414
 msgid "git fetch-pack: fetch failed."
 msgstr "git fetch-pack: 가져오기 실패."
 
-#: fetch-pack.c:1190
+#: fetch-pack.c:1199
+msgid "Server does not support shallow requests"
+msgstr "서버에서 shallow 요청을 지원하지 않습니다"
+
+#: fetch-pack.c:1584
 msgid "no matching remote head"
 msgstr "해당하는 리모트 헤드가 없습니다"
 
-#: fetch-pack.c:1212
+#: fetch-pack.c:1610
 #, c-format
 msgid "no such remote ref %s"
 msgstr "그런 리모트가 레퍼런스가 없습니다: %s"
 
-#: fetch-pack.c:1215
+#: fetch-pack.c:1613
 #, c-format
 msgid "Server does not allow request for unadvertised object %s"
 msgstr "서버에서 알려지지 않은 %s 오브젝트에 대한 요청을 허용하지 않습니다"
 
-#: gpg-interface.c:181
+#: gpg-interface.c:185
 msgid "gpg failed to sign the data"
 msgstr "gpg에서 데이터를 서명하는데 실패했습니다."
 
-#: gpg-interface.c:211
+#: gpg-interface.c:210
 msgid "could not create temporary file"
 msgstr "임시 파일을 만들 수 없습니다"
 
-#: gpg-interface.c:214
+#: gpg-interface.c:213
 #, c-format
 msgid "failed writing detached signature to '%s'"
 msgstr "분리된 서명을 '%s'에 쓰는데 실패했습니다"
@@ -1914,36 +2000,97 @@ msgstr "분리된 서명을 '%s'에 쓰는데 실패했습니다"
 msgid "ignore invalid color '%.*s' in log.graphColors"
 msgstr "log.graphColors에 잘못된 색을 ('%.*s') 무시합니다"
 
-#: grep.c:2022
+#: grep.c:2020
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "'%s': %s을(를) 읽을 수 없습니다"
 
-#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81
+#: grep.c:2037 setup.c:164 builtin/clone.c:409 builtin/diff.c:81
 #: builtin/rm.c:134
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "'%s'에 대해 stat()이 실패했습니다"
 
-#: grep.c:2050
+#: grep.c:2048
 #, c-format
 msgid "'%s': short read"
 msgstr "'%s': 읽다가 잘림"
 
-#: help.c:179
+#: help.c:23
+msgid "start a working area (see also: git help tutorial)"
+msgstr "작업 공간 시작 (참고: git help tutorial)"
+
+#: help.c:24
+msgid "work on the current change (see also: git help everyday)"
+msgstr "변경 사항에 대한 작업 (참고: git help everyday)"
+
+#: help.c:25
+msgid "examine the history and state (see also: git help revisions)"
+msgstr "커밋 내역과 상태 보기 (참고: git help revisions)"
+
+#: help.c:26
+msgid "grow, mark and tweak your common history"
+msgstr "커밋 내역을 키우고, 표시하고, 조작하기"
+
+#: help.c:27
+msgid "collaborate (see also: git help workflows)"
+msgstr "협동 작업 (참고: git help workflows)"
+
+#: help.c:31
+msgid "Main Porcelain Commands"
+msgstr "주요 사용자용 명령"
+
+#: help.c:32
+msgid "Ancillary Commands / Manipulators"
+msgstr "보조 명령 / 조작 기능"
+
+#: help.c:33
+msgid "Ancillary Commands / Interrogators"
+msgstr "보조 명령 / 정보 획득 기능"
+
+#: help.c:34
+msgid "Interacting with Others"
+msgstr "다른 사람과 소통"
+
+#: help.c:35
+msgid "Low-level Commands / Manipulators"
+msgstr "저수준 명령/ 조작 기능"
+
+#: help.c:36
+msgid "Low-level Commands / Interrogators"
+msgstr "보조 명령 / 정보 획득 기능"
+
+#: help.c:37
+msgid "Low-level Commands / Synching Repositories"
+msgstr "보조 명령 / 저장소 동기화 기능"
+
+#: help.c:38
+msgid "Low-level Commands / Internal Helpers"
+msgstr "보조 명령 / 내부 사용 기능"
+
+#: help.c:293
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "'%s'에 있는 깃 명령"
 
-#: help.c:186
+#: help.c:300
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "다른 $PATH에 있는 깃 명령"
 
-#: help.c:217
+#: help.c:309
 msgid "These are common Git commands used in various situations:"
 msgstr "다음은 여러가지 상황에서 자주 사용하는 깃 명령입니다:"
 
-#: help.c:281
+#: help.c:358 git.c:90
+#, c-format
+msgid "unsupported command listing type '%s'"
+msgstr "지원하지 명령 열거 방식 '%s'"
+
+#: help.c:405
+msgid "The common Git guides are:"
+msgstr "자주 사용하는 깃 안내서는 다음과 같습니다:"
+
+#: help.c:467
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -1952,31 +2099,31 @@ msgstr ""
 "'%s'은(는) 깃 명령으로 보이지만, 실행할 수\n"
 "없습니다. 아마도 git-%s 망가진 것 같습니다."
 
-#: help.c:336
+#: help.c:526
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "어라라. 시스템에 깃 명령이 하나도 없다고 나옵니다."
 
-#: help.c:358
+#: help.c:548
 #, c-format
 msgid "WARNING: You called a Git command named '%s', which does not exist."
 msgstr "경고: 이름이 '%s'인 깃 명령을 실행했지만, 그 명령이 없습니다."
 
-#: help.c:363
+#: help.c:553
 #, c-format
 msgid "Continuing under the assumption that you meant '%s'."
 msgstr "'%s' 명령이라고 가정하고 계속합니다."
 
-#: help.c:368
+#: help.c:558
 #, c-format
 msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
 msgstr "%0.1f초 뒤에 '%s' 명령이라고 가정하고 계속합니다."
 
-#: help.c:376
+#: help.c:566
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git: '%s'은(는) 깃 명령이 아닙니다. 'git --help'를 참고하십시오."
 
-#: help.c:380
+#: help.c:570
 msgid ""
 "\n"
 "The most similar command is"
@@ -1987,16 +2134,16 @@ msgstr[0] ""
 "\n"
 "가장 비슷한 명령은"
 
-#: help.c:395
+#: help.c:585
 msgid "git version [<options>]"
 msgstr "git version [<옵션>]"
 
-#: help.c:462
+#: help.c:652
 #, c-format
 msgid "%s: %s - %s"
 msgstr "%s: %s - %s"
 
-#: help.c:466
+#: help.c:656
 msgid ""
 "\n"
 "Did you mean this?"
@@ -2061,7 +2208,7 @@ msgstr "빈 이름의 신원 정보는 (<%s>에 대해) 허용하지 않습니
 msgid "name consists only of disallowed characters: %s"
 msgstr "이름이 허용하지 않는 문자로만 이루어져 있습니다: %s"
 
-#: ident.c:416 builtin/commit.c:582
+#: ident.c:416 builtin/commit.c:587
 #, c-format
 msgid "invalid date format: %s"
 msgstr "시각 형식이 잘못되었습니다: %s"
@@ -2098,273 +2245,409 @@ msgstr ""
 msgid "Unable to create '%s.lock': %s"
 msgstr "'%s.lock'을 만들 수 없습니다: %s"
 
-#: merge.c:74
+#: merge.c:71
 msgid "failed to read the cache"
 msgstr "캐시를 읽는데 실패했습니다"
 
-#: merge.c:134 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
-#: builtin/checkout.c:599 builtin/clone.c:759
+#: merge.c:136 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
+#: builtin/checkout.c:606 builtin/clone.c:761
 msgid "unable to write new index file"
 msgstr "새 인덱스 파일을 쓸 수 없습니다"
 
-#: merge-recursive.c:235
+#: merge-recursive.c:298
 msgid "(bad commit)\n"
 msgstr "(잘못된 커밋)\n"
 
-#: merge-recursive.c:257 merge-recursive.c:265
+#: merge-recursive.c:320
+#, c-format
+msgid "add_cacheinfo failed for path '%s'; merge aborting."
+msgstr "'%s' 경로에 대해 addinfo_cache 실패. 병합 중지."
+
+#: merge-recursive.c:328
 #, c-format
-msgid "addinfo_cache failed for path '%s'"
-msgstr "'%s' 경로에 대해 addinfo_cache가 실패했습니다"
+msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
+msgstr "'%s' 경로에 대해 addinfo_cache 새로 고침 실패. 병합 중지."
 
-#: merge-recursive.c:329
+#: merge-recursive.c:410
 msgid "error building trees"
 msgstr "트리 빌드에 오류"
 
-#: merge-recursive.c:771
+#: merge-recursive.c:881
 #, c-format
 msgid "failed to create path '%s'%s"
 msgstr "'%s' 경로 만들기에 실패했습니다%s"
 
-#: merge-recursive.c:782
+#: merge-recursive.c:892
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr "하위 디렉터리에 공간을 만드려고 %s을(를) 제거합니다\n"
 
-#: merge-recursive.c:796 merge-recursive.c:815
+#: merge-recursive.c:906 merge-recursive.c:925
 msgid ": perhaps a D/F conflict?"
 msgstr ": 아마도 D/F 충돌?"
 
-#: merge-recursive.c:805
+#: merge-recursive.c:915
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
 msgstr "'%s' 위치의 추적되지 않는 파일을 잃기를 거부합니다"
 
-#: merge-recursive.c:847 builtin/cat-file.c:37
+#: merge-recursive.c:957 builtin/cat-file.c:37
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr "%s '%s' 오브젝트를 읽을 수 없음"
 
-#: merge-recursive.c:849
+#: merge-recursive.c:959
 #, c-format
 msgid "blob expected for %s '%s'"
 msgstr "%s '%s'에 대해 블롭을 예상"
 
-#: merge-recursive.c:873
+#: merge-recursive.c:983
 #, c-format
 msgid "failed to open '%s': %s"
 msgstr "'%s'을(를) 여는데 실패: %s"
 
-#: merge-recursive.c:884
+#: merge-recursive.c:994
 #, c-format
 msgid "failed to symlink '%s': %s"
 msgstr "'%s' 심볼릭 링크에 실패: %s"
 
-#: merge-recursive.c:889
+#: merge-recursive.c:999
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
 msgstr "다음을 어떻게 할지 알 수 없습니다: %06o %s '%s'"
 
-#: merge-recursive.c:1029
+#: merge-recursive.c:1186
+#, c-format
+msgid "Failed to merge submodule %s (not checked out)"
+msgstr "%s 하위 모듈 병합 실패 (가져오지 않음)"
+
+#: merge-recursive.c:1193
+#, c-format
+msgid "Failed to merge submodule %s (commits not present)"
+msgstr "%s 하위 모듈 병합 실패 (커밋이 없습니다)"
+
+#: merge-recursive.c:1200
+#, c-format
+msgid "Failed to merge submodule %s (commits don't follow merge-base)"
+msgstr "%s 하위 모듈 병합 실패 (커밋이 병합 베이스를 따르지 않습니다)"
+
+#: merge-recursive.c:1208 merge-recursive.c:1220
+#, c-format
+msgid "Fast-forwarding submodule %s to the following commit:"
+msgstr "%s 하위 모듈을 다음 커밋으로 정방향 진행:"
+
+#: merge-recursive.c:1211 merge-recursive.c:1223
+#, c-format
+msgid "Fast-forwarding submodule %s"
+msgstr "%s 하위 모듈을 정방향 진행"
+
+#: merge-recursive.c:1245
+#, c-format
+msgid "Failed to merge submodule %s (merge following commits not found)"
+msgstr "%s 하위 모듈 병합 실패 (병합할 때 따라갈 커밋이 없습니다)"
+
+#: merge-recursive.c:1249
+#, c-format
+msgid "Failed to merge submodule %s (not fast-forward)"
+msgstr "%s 하위 모듈 병합 실패 (정방향이 아닙니다)"
+
+#: merge-recursive.c:1250
+msgid "Found a possible merge resolution for the submodule:\n"
+msgstr "하위 모듈에 대해 가능한 병합 방법을 찾았습니다:\n"
+
+#: merge-recursive.c:1253
+#, 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"
+"다음 명령을 사용하면:\n"
+"\n"
+"  git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"제안을 받아들이게 됩니다.\n"
+
+#: merge-recursive.c:1262
+#, c-format
+msgid "Failed to merge submodule %s (multiple merges found)"
+msgstr "%s 하위 모듈 병합 실패 (병합이 여러개 있습니다)"
+
+#: merge-recursive.c:1321
 msgid "Failed to execute internal merge"
 msgstr "내부 병합 실행에 실패"
 
-#: merge-recursive.c:1034
+#: merge-recursive.c:1326
 #, c-format
 msgid "Unable to add %s to database"
 msgstr "%s을(를) 데이터베이스에 추가할 수 없습니다"
 
-#: merge-recursive.c:1146
+#: merge-recursive.c:1358
+#, c-format
+msgid "Auto-merging %s"
+msgstr "자동 병합: %s"
+
+#: merge-recursive.c:1423
+#, c-format
+msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
+msgstr ""
+"오류: %s 위치의 추적되지 않는 파일을 잃기를 거부합니다. 대신 %s에 씁니다."
+
+#: merge-recursive.c:1475
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
 "in tree."
 msgstr ""
-"충돌! (%s/삭제): %s (위치 %s) 및 %s (%s에서) 삭제. %s 버전의 %s 트리에 남음."
+"충돌 (%s/삭제): %s (위치 %s) 및 %s (%s에서) 삭제. %s 버전의 %s 트리에 남음."
 
-#: merge-recursive.c:1151
+#: merge-recursive.c:1480
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
 "left in tree."
 msgstr ""
-"충돌! (%s/삭제): %s (위치 %s) 삭제, %s에서 %s(으)로 (위치 %s). %s 버전의 %s "
-"리에 남음."
+"충돌 (%s/삭제): %s (위치 %s) 삭제, %s에서 %s(으)로 (위치 %s). %s 버전의 %s 트"
+"리에 남음."
 
-#: merge-recursive.c:1158
+#: merge-recursive.c:1487
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
 "in tree at %s."
 msgstr ""
-"충돌! (%s/삭제): %s (위치 %s) 및 %s (위치 %s) 삭제. %s 버전의 %s 트리에 "
-"%s(으)로 남음."
+"충돌 (%s/삭제): %s (위치 %s) 및 %s (위치 %s) 삭제. %s 버전의 %s 트리에 %s(으)"
+"로 남음."
 
-#: merge-recursive.c:1163
+#: merge-recursive.c:1492
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
 "left in tree at %s."
 msgstr ""
-"충돌! (%s/삭제): %s (위치 %s) 삭제, %s에서 %s(으)로 (위치 %s). %s 버전의 %s "
-"리에 남음 (위치 %s)."
+"충돌 (%s/삭제): %s (위치 %s) 삭제, %s에서 %s(으)로 (위치 %s). %s 버전의 %s 트"
+"리에 남음 (위치 %s)."
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "rename"
 msgstr "이름바꾸기"
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "renamed"
 msgstr "이름바꿈"
 
-#: merge-recursive.c:1254
+#: merge-recursive.c:1580 merge-recursive.c:1736 merge-recursive.c:2368
+#: merge-recursive.c:3086
+#, c-format
+msgid "Refusing to lose dirty file at %s"
+msgstr "%s 위치의 변경된 파일을 잃기를 거부합니다"
+
+#: merge-recursive.c:1594
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr "%s은(는) %s에 있는 디렉터리로 %s(으)로 이름을 바꿉니다"
 
-#: merge-recursive.c:1279
+#: merge-recursive.c:1599
+#, c-format
+msgid "Refusing to lose untracked file at %s; adding as %s instead"
+msgstr "%s 위치의 추적되지 않는 파일을 잃기를 거부합니다. 대신 %s 추가"
+
+#: merge-recursive.c:1625
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
 "\"->\"%s\" in \"%s\"%s"
 msgstr ""
-"충돌! (이름바꾸기/이름바꾸기): \"%3$s\" 브랜치에서 이름바꾸기 \"%1$s\"->"
-"\"%2$s\" \"%6$s\" 브랜치에서 이름 바꾸기 \"%4$s\"->\"%5$s\"%7$s"
+"충돌 (이름바꾸기/이름바꾸기): \"%3$s\" 브랜치에서 이름바꾸기 \"%1$s\"->\"%2$s"
+"\" \"%6$s\" 브랜치에서 이름 바꾸기 \"%4$s\"->\"%5$s\"%7$s"
 
-#: merge-recursive.c:1284
+#: merge-recursive.c:1630
 msgid " (left unresolved)"
 msgstr " (해결되지 않음)"
 
-#: merge-recursive.c:1346
+#: merge-recursive.c:1694
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
-"충돌! (rename/rename): 이름 바꾸기 %s->%s (위치 %s). 이름 바꾸기 %s->%s (위"
-"치 %s)"
+"충돌 (rename/rename): 이름 바꾸기 %s->%s (위치 %s). 이름 바꾸기 %s->%s (위치 "
+"%s)"
 
-#: merge-recursive.c:1379
+#: merge-recursive.c:1733
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr "대신 이름을 %s에서 %s(으)로 바꾸고 %s에서 %s(으)로 바꿉니다"
 
-#: merge-recursive.c:1582
+#: merge-recursive.c:1745
+#, c-format
+msgid "Refusing to lose untracked file at %s, even though it's in the way."
+msgstr ""
+"%s 위치의 추적되지 않는 파일을 잃기를 (잃어버릴 예정이지만) 거부합니다."
+
+#: merge-recursive.c:1951
+#, c-format
+msgid ""
+"CONFLICT (directory rename split): Unclear where to place %s because "
+"directory %s was renamed to multiple other directories, with no destination "
+"getting a majority of the files."
+msgstr ""
+"충돌 (디렉터리 이름 바꾸기 분리): %s 파일을 어디에 놓을지 불분명합니다. %s 디"
+"렉터리가 여러 개의 다른 디렉터리로 이름이 바뀌었고 파일 다수가 들어 있는 대상"
+"이 없기 때문입니다."
+
+#: merge-recursive.c:1983
+#, c-format
+msgid ""
+"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 ""
+"충돌 (묵시적인 디렉터리 이름 바꾸기): %s 위치의 기존 파일/디렉터리가 묵시적으"
+"로 디렉터리 이름이 바뀌어 다음 경로가 들어갈 예정입니다: %s."
+
+#: merge-recursive.c:1993
+#, 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 ""
+"충돌 (묵시적인 디렉터리 이름 바꾸기): 여러 개의 경로를 %s에 대응할 수 없습니"
+"다. 묵시적인 디렉터리 이름 바꾸기 기능은 이들 경로를 해당 위치에 놓도록 시도"
+"합니다: %s"
+
+#: merge-recursive.c:2085
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-"
+">%s in %s"
+msgstr ""
+"충돌 (rename/rename): 이름 바꾸기 %s->%s (위치 %s). 이름 바꾸기 %s->%s (위치 "
+"%s)"
+
+#: merge-recursive.c:2330
+#, c-format
+msgid ""
+"WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
+"renamed."
+msgstr ""
+"경고: %s -> %s 이름 바꾸기 (대상 %s) 적용 거부. %s 자체가 이미 이름이 바뀌었"
+"습니다."
+
+#: merge-recursive.c:2736
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
-msgstr "충돌! (rename/add): 이름 바꾸기 %s->%s (위치 %s). %s 추가 (위치 %s)"
+msgstr "충돌 (rename/add): 이름 바꾸기 %s->%s (위치 %s). %s 추가 (위치 %s)"
 
-#: merge-recursive.c:1597
+#: merge-recursive.c:2751
 #, c-format
 msgid "Adding merged %s"
 msgstr "병합된 %s을(를) 추가합니다"
 
-#: merge-recursive.c:1604 merge-recursive.c:1834
+#: merge-recursive.c:2758 merge-recursive.c:3089
 #, c-format
 msgid "Adding as %s instead"
 msgstr "대신 %s(으)로 추가합니다"
 
-#: merge-recursive.c:1661
+#: merge-recursive.c:2914
 #, c-format
 msgid "cannot read object %s"
 msgstr "%s 오브젝트를 읽을 수 없습니다"
 
-#: merge-recursive.c:1664
+#: merge-recursive.c:2917
 #, c-format
 msgid "object %s is not a blob"
 msgstr "%s 오브젝트는 블롭이 아닙니다"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modify"
 msgstr "수정"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modified"
 msgstr "수정됨"
 
-#: merge-recursive.c:1743
+#: merge-recursive.c:2997
 msgid "content"
 msgstr "내용"
 
-#: merge-recursive.c:1750
+#: merge-recursive.c:3004
 msgid "add/add"
 msgstr "추가/추가"
 
-#: merge-recursive.c:1786
+#: merge-recursive.c:3046
 #, c-format
 msgid "Skipped %s (merged same as existing)"
 msgstr "건너뛰기: %s (기존과 같게 병합)"
 
-#: merge-recursive.c:1800
-#, c-format
-msgid "Auto-merging %s"
-msgstr "자동 병합: %s"
-
-#: merge-recursive.c:1804 git-submodule.sh:879
+#: merge-recursive.c:3055 git-submodule.sh:895
 msgid "submodule"
 msgstr "하위 모듈"
 
-#: merge-recursive.c:1805
+#: merge-recursive.c:3056
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
-msgstr "충돌! (%s): %s에 병합 충돌"
+msgstr "충돌 (%s): %s에 병합 충돌"
 
-#: merge-recursive.c:1899
+#: merge-recursive.c:3178
 #, c-format
 msgid "Removing %s"
 msgstr "제거: %s"
 
-#: merge-recursive.c:1925
+#: merge-recursive.c:3204
 msgid "file/directory"
 msgstr "파일/디렉터리"
 
-#: merge-recursive.c:1931
+#: merge-recursive.c:3210
 msgid "directory/file"
 msgstr "디렉터리/파일"
 
-#: merge-recursive.c:1938
+#: merge-recursive.c:3217
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
 msgstr ""
-"충돌! (%s): 이름이 %s인 디렉터리가 %s에 있습니다. %s을(를) %s(으)로 추가합니"
-"다"
+"충돌 (%s): 이름이 %s인 디렉터리가 %s에 있습니다. %s을(를) %s(으)로 추가합니다"
 
-#: merge-recursive.c:1947
+#: merge-recursive.c:3226
 #, c-format
 msgid "Adding %s"
 msgstr "추가: %s"
 
-#: merge-recursive.c:1987
+#: merge-recursive.c:3267
 #, c-format
 msgid "Dirty index: cannot merge (dirty: %s)"
 msgstr "변경된 인덱스: 병합할 수 없습니다 (dirty: %s)"
 
-#: merge-recursive.c:1991
+#: merge-recursive.c:3271
 msgid "Already up to date!"
 msgstr "이미 업데이트 상태입니다!"
 
-#: merge-recursive.c:2000
+#: merge-recursive.c:3280
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr "%s 및 %s 트리의 병합이 실패했습니다"
 
-#: merge-recursive.c:2097
+#: merge-recursive.c:3379
 msgid "Merging:"
 msgstr "병합:"
 
-#: merge-recursive.c:2110
+#: merge-recursive.c:3392
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] "과거의 공통 커밋 %u개 발견:"
 
-#: merge-recursive.c:2149
+#: merge-recursive.c:3431
 msgid "merge returned no commit"
 msgstr "병합 결과에 커밋이 없습니다"
 
-#: merge-recursive.c:2212
+#: merge-recursive.c:3495
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr "'%s' 오브젝트를 파싱할 수 없습니다"
 
-#: merge-recursive.c:2228 builtin/merge.c:657 builtin/merge.c:816
+#: merge-recursive.c:3511 builtin/merge.c:659 builtin/merge.c:816
 msgid "Unable to write index."
 msgstr "인덱스를 쓸 수 없습니다."
 
@@ -2407,30 +2690,30 @@ msgstr "%s에서 노트를 다시 쓰기를 거부합니다 (refs/notes/ 밖임)
 msgid "Bad %s value: '%s'"
 msgstr "잘못된 %s 값: '%s'"
 
-#: object.c:239
+#: object.c:242
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "오브젝트를 파싱할 수 없습니다: %s"
 
-#: packfile.c:561
+#: packfile.c:563
 msgid "offset before end of packfile (broken .idx?)"
 msgstr "오프셋이 묶음 파일 앞입니다 (망가진 .idx?)"
 
-#: packfile.c:1694
+#: packfile.c:1742
 #, c-format
 msgid "offset before start of pack index for %s (corrupt index?)"
 msgstr "오프셋이 %s의 묶음 인덱스 시작보다 앞입니다 (망가진 인덱스?)"
 
-#: packfile.c:1698
+#: packfile.c:1746
 #, c-format
 msgid "offset beyond end of pack index for %s (truncated index?)"
 msgstr "오프셋이 %s의 묶음 인덱스 끝보다 뒤입니다 (망가진 인덱스?)"
 
-#: parse-options.c:619
+#: parse-options.c:621
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:638
+#: parse-options.c:640
 #, c-format
 msgid "usage: %s"
 msgstr "사용법: %s"
@@ -2438,26 +2721,31 @@ msgstr "사용법: %s"
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation.
 #.
-#: parse-options.c:644
+#: parse-options.c:646
 #, c-format
 msgid "   or: %s"
 msgstr "  또는: %s"
 
-#: parse-options.c:647
+#: parse-options.c:649
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:686
+#: parse-options.c:688
 msgid "-NUM"
 msgstr "-NUM"
 
-#: parse-options-cb.c:108
+#: parse-options-cb.c:44
+#, c-format
+msgid "malformed expiration date '%s'"
+msgstr "형식이 잘못된 만료 시각: '%s'"
+
+#: parse-options-cb.c:112
 #, c-format
 msgid "malformed object name '%s'"
 msgstr "잘못된 형식의 오브젝트 이름 '%s'"
 
-#: path.c:891
+#: path.c:892
 #, c-format
 msgid "Could not make %s writable by group"
 msgstr "%s을(를) 그룹에서 쓰기 가능하도록 만들 수 없습니다"
@@ -2538,7 +2826,7 @@ msgstr "'%s' 경로명세는 심볼릭 링크 아래에 있습니다"
 msgid "unable to parse --pretty format"
 msgstr "--pretty 형식을 파싱할 수 없습니다"
 
-#: read-cache.c:1473
+#: read-cache.c:1500
 #, c-format
 msgid ""
 "index.version set, but the value is invalid.\n"
@@ -2547,7 +2835,7 @@ msgstr ""
 "index.version이 설정되었지만, 이 값이 잘못되었습니다.\n"
 "%i 버전을 사용합니다"
 
-#: read-cache.c:1483
+#: read-cache.c:1510
 #, c-format
 msgid ""
 "GIT_INDEX_VERSION set, but the value is invalid.\n"
@@ -2556,52 +2844,53 @@ msgstr ""
 "GIT_INDEX_VERSION이 설정되었지만, 이 값이 잘못되었습니다.\n"
 "%i 버전을 사용합니다"
 
-#: read-cache.c:2375 sequencer.c:3248 wrapper.c:658 builtin/merge.c:1049
+#: read-cache.c:2404 sequencer.c:4338 wrapper.c:658 builtin/merge.c:1048
 #, c-format
 msgid "could not close '%s'"
 msgstr "'%s'을(를) 닫을 수 없습니다"
 
-#: read-cache.c:2448 sequencer.c:1900 sequencer.c:2627
+#: read-cache.c:2477 sequencer.c:2102 sequencer.c:3234
 #, c-format
 msgid "could not stat '%s'"
 msgstr "'%s'을(를) stat()할 수 없습니다"
 
-#: read-cache.c:2461
+#: read-cache.c:2490
 #, c-format
 msgid "unable to open git dir: %s"
 msgstr "git 디렉터리를 열 수 없습니다: %s"
 
-#: read-cache.c:2473
+#: read-cache.c:2502
 #, c-format
 msgid "unable to unlink: %s"
 msgstr "링크 해제할 수 없습니다: %s"
 
-#: refs.c:706
+#: refs.c:732 sequencer.c:4334 sequencer.c:4393 wrapper.c:225 wrapper.c:395
+#: builtin/am.c:779
 #, c-format
-msgid "Could not open '%s' for writing"
+msgid "could not open '%s' for writing"
 msgstr "'%s'을(를) 쓰기용으로 열 수 없습니다"
 
-#: refs.c:1850
+#: refs.c:1880
 msgid "ref updates forbidden inside quarantine environment"
 msgstr "격리된 환경에서 레퍼런스 업데이트가 금지됩니다"
 
-#: refs/files-backend.c:1189
+#: refs/files-backend.c:1191
 #, c-format
 msgid "could not remove reference %s"
 msgstr "%s 레퍼런스를 제거할 수 없습니다"
 
-#: refs/files-backend.c:1203 refs/packed-backend.c:1528
-#: refs/packed-backend.c:1538
+#: refs/files-backend.c:1205 refs/packed-backend.c:1531
+#: refs/packed-backend.c:1541
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "%s 레퍼런스를 삭제할 수 없습니다: %s"
 
-#: refs/files-backend.c:1206 refs/packed-backend.c:1541
+#: refs/files-backend.c:1208 refs/packed-backend.c:1544
 #, c-format
 msgid "could not delete references: %s"
 msgstr "레퍼런스를 삭제할 수 없습니다: %s"
 
-#: ref-filter.c:35 wt-status.c:1842
+#: ref-filter.c:35 wt-status.c:1850
 msgid "gone"
 msgstr "없음"
 
@@ -2620,157 +2909,162 @@ msgstr "%d개 뒤"
 msgid "ahead %d, behind %d"
 msgstr "%d개 앞, %d개 뒤"
 
-#: ref-filter.c:107
+#: ref-filter.c:121
 #, c-format
 msgid "expected format: %%(color:<color>)"
 msgstr "예상한 형식: %%(color:<색>)"
 
-#: ref-filter.c:109
+#: ref-filter.c:123
 #, c-format
 msgid "unrecognized color: %%(color:%s)"
 msgstr "인식할 수 없는 색: %%(color:%s)"
 
-#: ref-filter.c:129
+#: ref-filter.c:145
 #, c-format
 msgid "Integer value expected refname:lstrip=%s"
 msgstr "정수 값이 와야 합니다 refname:lstrip=%s"
 
-#: ref-filter.c:133
+#: ref-filter.c:149
 #, c-format
 msgid "Integer value expected refname:rstrip=%s"
 msgstr "정수 값이 와야 합니다 refname:rstrip=%s"
 
-#: ref-filter.c:135
+#: ref-filter.c:151
 #, c-format
 msgid "unrecognized %%(%s) argument: %s"
 msgstr "인식할 수 없는 %%(%s) 인자: %s"
 
-#: ref-filter.c:184
+#: ref-filter.c:206
 #, c-format
 msgid "%%(body) does not take arguments"
 msgstr "%%(body)에 인자를 받지 않습니다"
 
-#: ref-filter.c:191
+#: ref-filter.c:215
 #, c-format
 msgid "%%(subject) does not take arguments"
 msgstr "%%(subject)에 인자를 받지 않습니다"
 
-#: ref-filter.c:209
+#: ref-filter.c:235
 #, c-format
 msgid "unknown %%(trailers) argument: %s"
 msgstr "알 수 없는 %%(trailers) 옵션 인자: %s"
 
-#: ref-filter.c:232
+#: ref-filter.c:264
 #, c-format
 msgid "positive value expected contents:lines=%s"
 msgstr "'contents:lines=%s'에서 0보다 큰 값이 와야 합니다"
 
-#: ref-filter.c:234
+#: ref-filter.c:266
 #, c-format
 msgid "unrecognized %%(contents) argument: %s"
 msgstr "알 수 없는 %%(contents) 인자: %s"
 
-#: ref-filter.c:247
+#: ref-filter.c:281
 #, c-format
 msgid "positive value expected objectname:short=%s"
 msgstr "'contents:short=%s'에서 0보다 큰 값이 와야 합니다"
 
-#: ref-filter.c:251
+#: ref-filter.c:285
 #, c-format
 msgid "unrecognized %%(objectname) argument: %s"
 msgstr "알 수 없는 %%(objectname) 인자: %s"
 
-#: ref-filter.c:278
+#: ref-filter.c:315
 #, c-format
 msgid "expected format: %%(align:<width>,<position>)"
 msgstr "예상한 형식: %%(align:<너비>,<위치>)"
 
-#: ref-filter.c:290
+#: ref-filter.c:327
 #, c-format
 msgid "unrecognized position:%s"
 msgstr "인식할 수 없는 위치:%s"
 
-#: ref-filter.c:294
+#: ref-filter.c:334
 #, c-format
 msgid "unrecognized width:%s"
 msgstr "인식할 수 없는 너비:%s"
 
-#: ref-filter.c:300
+#: ref-filter.c:343
 #, c-format
 msgid "unrecognized %%(align) argument: %s"
 msgstr "인식할 수 없는 %%(align) 인자:%s"
 
-#: ref-filter.c:304
+#: ref-filter.c:351
 #, c-format
 msgid "positive width expected with the %%(align) atom"
 msgstr "%%(align) 아톰에 너비가 0보다 커야 합니다"
 
-#: ref-filter.c:319
+#: ref-filter.c:369
 #, c-format
 msgid "unrecognized %%(if) argument: %s"
 msgstr "인식할 수 없는 %%(if) 인자: %s"
 
-#: ref-filter.c:409
+#: ref-filter.c:464
 #, c-format
 msgid "malformed field name: %.*s"
 msgstr "잘못된 형식의 필드 이름: %.*s"
 
-#: ref-filter.c:435
+#: ref-filter.c:491
 #, c-format
 msgid "unknown field name: %.*s"
 msgstr "알 수 없는 필드 이름: %.*s"
 
-#: ref-filter.c:547
+#: ref-filter.c:608
 #, c-format
 msgid "format: %%(if) atom used without a %%(then) atom"
 msgstr "형식: %%(if) 아톰이 %%(then) 아톰 없이 사용되었습니다"
 
-#: ref-filter.c:607
+#: ref-filter.c:671
 #, c-format
 msgid "format: %%(then) atom used without an %%(if) atom"
 msgstr "형식: %%(then) 아톰이 %%(if) 아톰 없이 사용되었습니다"
 
-#: ref-filter.c:609
+#: ref-filter.c:673
 #, c-format
 msgid "format: %%(then) atom used more than once"
 msgstr "형식: %%(then) 아톰이 여러번 사용되었습니다"
 
-#: ref-filter.c:611
+#: ref-filter.c:675
 #, c-format
 msgid "format: %%(then) atom used after %%(else)"
 msgstr "형식: %%(then) 아톰이 %%(else) 뒤에 사용되었습니다"
 
-#: ref-filter.c:637
+#: ref-filter.c:703
 #, c-format
 msgid "format: %%(else) atom used without an %%(if) atom"
 msgstr "형식: %%(else) 아톰이 %%(if) 아톰 없이 사용되었습니다"
 
-#: ref-filter.c:639
+#: ref-filter.c:705
 #, c-format
 msgid "format: %%(else) atom used without a %%(then) atom"
 msgstr "형식: %%(else) 아톰이 %%(then) 아톰 없이 사용되었습니다"
 
-#: ref-filter.c:641
+#: ref-filter.c:707
 #, c-format
 msgid "format: %%(else) atom used more than once"
 msgstr "형식: %%(else) 아톰이 여러번 사용되었습니다"
 
-#: ref-filter.c:654
+#: ref-filter.c:722
 #, c-format
 msgid "format: %%(end) atom used without corresponding atom"
 msgstr "형식: %%(end) 아톰이 대응되는 아톰 없이 사용되었습니다"
 
-#: ref-filter.c:709
+#: ref-filter.c:779
 #, c-format
 msgid "malformed format string %s"
 msgstr "잘못된 형식의 문자열 %s"
 
-#: ref-filter.c:1313
+#: ref-filter.c:1387
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(브랜치 없음, %s 리베이스)"
 
-#: ref-filter.c:1316
+#: ref-filter.c:1390
+#, c-format
+msgid "(no branch, rebasing detached HEAD %s)"
+msgstr "(브랜치 없음, 분리된 HEAD %s 리베이스)"
+
+#: ref-filter.c:1393
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(브랜치 없음, 이등분 %s에서 시작)"
@@ -2778,7 +3072,7 @@ msgstr "(브랜치 없음, 이등분 %s에서 시작)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached at " in wt-status.c
 #.
-#: ref-filter.c:1324
+#: ref-filter.c:1401
 #, c-format
 msgid "(HEAD detached at %s)"
 msgstr "(HEAD %s 위치에서 분리됨)"
@@ -2786,157 +3080,157 @@ msgstr "(HEAD %s 위치에서 분리됨)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached from " in wt-status.c
 #.
-#: ref-filter.c:1331
+#: ref-filter.c:1408
 #, c-format
 msgid "(HEAD detached from %s)"
 msgstr "(HEAD %s(으)로부터 분리됨)"
 
-#: ref-filter.c:1335
+#: ref-filter.c:1412
 msgid "(no branch)"
 msgstr "(브랜치 없음)"
 
-#: ref-filter.c:1364
+#: ref-filter.c:1442
 #, c-format
 msgid "missing object %s for %s"
 msgstr "없는 오브젝트 %s, %s에 대해"
 
-#: ref-filter.c:1367
+#: ref-filter.c:1445
 #, c-format
 msgid "parse_object_buffer failed on %s for %s"
 msgstr "%s에 parse_object_buffer 실패 (%s에 대해)"
 
-#: ref-filter.c:1819
+#: ref-filter.c:1902
 #, c-format
 msgid "malformed object at '%s'"
 msgstr "'%s'에 잘못된 형식의 오브젝트"
 
-#: ref-filter.c:1886
+#: ref-filter.c:1984
 #, c-format
 msgid "ignoring ref with broken name %s"
 msgstr "망가진 이름 %s에 레퍼런스를 무시합니다"
 
-#: ref-filter.c:1891
+#: ref-filter.c:1989
 #, c-format
 msgid "ignoring broken ref %s"
 msgstr "망가진 레퍼런스 %s 무시"
 
-#: ref-filter.c:2152
+#: ref-filter.c:2261
 #, c-format
 msgid "format: %%(end) atom missing"
 msgstr "형식: %%(end) 아톰이 없습니다"
 
-#: ref-filter.c:2246
+#: ref-filter.c:2365
 #, c-format
 msgid "malformed object name %s"
 msgstr "잘못된 형식의 오브젝트 이름 %s"
 
-#: remote.c:795
+#: remote.c:605
 #, c-format
 msgid "Cannot fetch both %s and %s to %s"
 msgstr "%s 및 %s을(를) 모두 %s에 가져올 수 없습니다"
 
-#: remote.c:799
+#: remote.c:609
 #, c-format
 msgid "%s usually tracks %s, not %s"
 msgstr "%s은(는) 보통 %s을(를) 추적하고, %s을(를) 추적하지 않습니다"
 
-#: remote.c:803
+#: remote.c:613
 #, c-format
 msgid "%s tracks both %s and %s"
 msgstr "%s은(는) %s 및 %s 모두 추적합니다"
 
-#: remote.c:811
+#: remote.c:621
 msgid "Internal error"
 msgstr "내부 오류"
 
-#: remote.c:1726 remote.c:1828
+#: remote.c:1534 remote.c:1635
 msgid "HEAD does not point to a branch"
 msgstr "HEAD가 브랜치를 가리키지 않습니다"
 
-#: remote.c:1735
+#: remote.c:1543
 #, c-format
 msgid "no such branch: '%s'"
 msgstr "그런 브랜치가 없습니다: '%s'"
 
-#: remote.c:1738
+#: remote.c:1546
 #, c-format
 msgid "no upstream configured for branch '%s'"
 msgstr "'%s' 브랜치에 대해 업스트림을 설정하지 않았습니다"
 
-#: remote.c:1744
+#: remote.c:1552
 #, c-format
 msgid "upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "업스트림 '%s' 브랜치가 리모트 추적 브랜치로 저장되지 않았습니다"
 
-#: remote.c:1759
+#: remote.c:1567
 #, c-format
 msgid "push destination '%s' on remote '%s' has no local tracking branch"
 msgstr "리모트 '%2$s'의 푸시 대상 '%1$s'에 로컬 추적 브랜치가 없습니다"
 
-#: remote.c:1771
+#: remote.c:1579
 #, c-format
 msgid "branch '%s' has no remote for pushing"
 msgstr "'%s' 브랜치에 푸시 리모트가 없습니다"
 
-#: remote.c:1782
+#: remote.c:1589
 #, c-format
 msgid "push refspecs for '%s' do not include '%s'"
 msgstr "'%s'에 대한 푸시 레퍼런스명세에 '%s'이(가) 들어 있지 않습니다"
 
-#: remote.c:1795
+#: remote.c:1602
 msgid "push has no destination (push.default is 'nothing')"
 msgstr "푸시의 대상이 없습니다 (push.default가 'nothing'입니다)"
 
-#: remote.c:1817
+#: remote.c:1624
 msgid "cannot resolve 'simple' push to a single destination"
 msgstr "하나의 대상에 대해 'simple' 푸시를 처리할 수 없습니다"
 
-#: remote.c:2132
+#: remote.c:1939
 #, c-format
 msgid "Your branch is based on '%s', but the upstream is gone.\n"
 msgstr "현재 브랜치가 '%s' 기반이지만, 업스트림이 없어졌습니다.\n"
 
-#: remote.c:2136
+#: remote.c:1943
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
 msgstr "  (바로잡으려면 \"git branch --unset-upstream\"을 사용하십시오)\n"
 
-#: remote.c:2139
+#: remote.c:1946
 #, c-format
 msgid "Your branch is up to date with '%s'.\n"
 msgstr "브랜치가 '%s'에 맞게 업데이트된 상태입니다.\n"
 
-#: remote.c:2143
+#: remote.c:1950
 #, c-format
 msgid "Your branch and '%s' refer to different commits.\n"
 msgstr "현재 브랜치와 '%s'이(가) 다른 커밋을 레퍼런스합니다.\n"
 
-#: remote.c:2146
+#: remote.c:1953
 #, c-format
 msgid "  (use \"%s\" for details)\n"
 msgstr " (자세한 정보를 위해 \"%s\"을(를) 사용하십시오)\n"
 
-#: remote.c:2150
+#: remote.c:1957
 #, 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] "브랜치가 '%s'보다 %d개 커밋만큼 앞에 있습니다.\n"
 
-#: remote.c:2156
+#: remote.c:1963
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (로컬에 있는 커밋을 제출하려면 \"git push\"를 사용하십시오)\n"
 
-#: remote.c:2159
+#: remote.c:1966
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
 "Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n"
 msgstr[0] "브랜치가 '%s'보다 %d개 커밋 뒤에 있고, 앞으로 돌릴 수 있습니다.\n"
 
-#: remote.c:2167
+#: remote.c:1974
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (로컬 브랜치를 업데이트하려면 \"git pull\"을 사용하십시오)\n"
 
-#: remote.c:2170
+#: remote.c:1977
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -2948,29 +3242,29 @@ msgstr[0] ""
 "현재 브랜치와 '%s'이(가) 갈라졌습니다,\n"
 "다른 커밋이 각각 %d개와 %d개 있습니다.\n"
 
-#: remote.c:2180
+#: remote.c:1987
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr ""
 "  (리모트의 브랜치를 현재 브랜치로 병합하려면 \"git pull\"을 사용하십시오)\n"
 
-#: revision.c:2277
+#: revision.c:2289
 msgid "your current branch appears to be broken"
 msgstr "현재 브랜치가 망가진 것처럼 보입니다"
 
-#: revision.c:2280
+#: revision.c:2292
 #, c-format
 msgid "your current branch '%s' does not have any commits yet"
 msgstr "현재 '%s' 브랜치에 아직 아무 커밋도 없습니다"
 
-#: revision.c:2477
+#: revision.c:2489
 msgid "--first-parent is incompatible with --bisect"
 msgstr "--first-parent 옵션은 --bisect 옵션과 호환되지 않습니다"
 
-#: run-command.c:731
+#: run-command.c:728
 msgid "open /dev/null failed"
 msgstr "/dev/null 열기 실패"
 
-#: run-command.c:1274
+#: run-command.c:1271
 #, c-format
 msgid ""
 "The '%s' hook was ignored because it's not set as executable.\n"
@@ -3016,29 +3310,34 @@ msgstr "받는 쪽에서 --atomic 푸시를 지원하지 않습니다"
 msgid "the receiving end does not support push options"
 msgstr "받는 쪽에서 푸시 옵션을 지원하지 않습니다"
 
-#: sequencer.c:158
+#: sequencer.c:175
 #, c-format
 msgid "invalid commit message cleanup mode '%s'"
 msgstr "잘못된 커밋 메시지 정리 모드 '%s'"
 
-#: sequencer.c:267
+#: sequencer.c:275
+#, c-format
+msgid "could not delete '%s'"
+msgstr "'%s'을(를) 삭제할 수 없습니다"
+
+#: sequencer.c:301
 msgid "revert"
 msgstr "revert"
 
-#: sequencer.c:269
+#: sequencer.c:303
 msgid "cherry-pick"
 msgstr "cherry-pick"
 
-#: sequencer.c:271
+#: sequencer.c:305
 msgid "rebase -i"
 msgstr "rebase -i"
 
-#: sequencer.c:273
+#: sequencer.c:307
 #, c-format
 msgid "Unknown action: %d"
 msgstr "알 수 없는 동작: %d"
 
-#: sequencer.c:330
+#: sequencer.c:364
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
@@ -3046,7 +3345,7 @@ msgstr ""
 "이 충돌을 해결한 뒤에, 바로잡은 경로를\n"
 "'git add <경로>' 또는 'git rm <경로>'로 표시하십시오"
 
-#: sequencer.c:333
+#: sequencer.c:367
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'\n"
@@ -3056,43 +3355,45 @@ msgstr ""
 "'git add <경로>' 또는 'git rm <경로>'로 표시하십시오.\n"
 "그리고 결과물을 'git commit'으로 커밋하십시오"
 
-#: sequencer.c:346 sequencer.c:2245
+#: sequencer.c:380 sequencer.c:2468
 #, c-format
 msgid "could not lock '%s'"
 msgstr "'%s'을(를) 잠글 수 없습니다"
 
-#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264
-#: sequencer.c:3246 sequencer.c:3310 wrapper.c:656
+#: sequencer.c:382 sequencer.c:2346 sequencer.c:2472 sequencer.c:2486
+#: sequencer.c:2694 sequencer.c:4336 sequencer.c:4399 wrapper.c:656
 #, c-format
 msgid "could not write to '%s'"
 msgstr "'%s'에 쓸 수 없습니다"
 
-#: sequencer.c:353
+#: sequencer.c:387
 #, c-format
 msgid "could not write eol to '%s'"
 msgstr "'%s'에 줄바꿈을 쓸 수 없습니다"
 
-#: sequencer.c:356 sequencer.c:2128 sequencer.c:2252
+#: sequencer.c:392 sequencer.c:2351 sequencer.c:2474 sequencer.c:2488
+#: sequencer.c:2702
 #, c-format
 msgid "failed to finalize '%s'"
 msgstr "'%s' 마치는데 실패했습니다"
 
-#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259
-#: builtin/commit.c:722 builtin/merge.c:1047
+#: sequencer.c:415 sequencer.c:804 sequencer.c:1493 sequencer.c:2371
+#: sequencer.c:2684 sequencer.c:2788 builtin/am.c:259 builtin/commit.c:727
+#: builtin/merge.c:1046
 #, c-format
 msgid "could not read '%s'"
 msgstr "'%s'에서 읽을 수 없습니다"
 
-#: sequencer.c:405
+#: sequencer.c:441
 #, c-format
 msgid "your local changes would be overwritten by %s."
 msgstr "로컬 변경 사항을 %s 때문에 덮어 쓰게 됩니다."
 
-#: sequencer.c:409
+#: sequencer.c:445
 msgid "commit your changes or stash them to proceed."
 msgstr "변경 사항을 커밋하거나 스태시한 다음 계속하십시오."
 
-#: sequencer.c:438
+#: sequencer.c:474
 #, c-format
 msgid "%s: fast-forward"
 msgstr "%s: 정방향 진행"
@@ -3100,20 +3401,20 @@ msgstr "%s: 정방향 진행"
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase -i".
 #.
-#: sequencer.c:526
+#: sequencer.c:563
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: 새 인덱스 파일을 쓸 수 없습니다"
 
-#: sequencer.c:542
-msgid "could not resolve HEAD commit"
-msgstr "HEAD 커밋을 찾을 수 없습니다"
-
-#: sequencer.c:562
+#: sequencer.c:579
 msgid "unable to update cache tree"
 msgstr "캐시 트리를 업데이트할 수 없습니다"
 
-#: sequencer.c:658
+#: sequencer.c:592
+msgid "could not resolve HEAD commit"
+msgstr "HEAD 커밋을 찾을 수 없습니다"
+
+#: sequencer.c:749
 #, c-format
 msgid ""
 "you have staged changes in your working tree\n"
@@ -3143,11 +3444,15 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: sequencer.c:915
+#: sequencer.c:818
+msgid "writing root commit"
+msgstr "최상위 커밋을 씁니다"
+
+#: sequencer.c:1043
 msgid "'prepare-commit-msg' hook failed"
 msgstr "'prepare-commit-msg' 후크가 실패했습니다"
 
-#: sequencer.c:922
+#: sequencer.c:1050
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3174,7 +3479,7 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:935
+#: sequencer.c:1063
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3199,328 +3504,314 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:975
+#: sequencer.c:1103
 msgid "couldn't look up newly created commit"
 msgstr "새로 만든 커밋을 찾아볼 수 없습니다"
 
-#: sequencer.c:977
+#: sequencer.c:1105
 msgid "could not parse newly created commit"
 msgstr "새로 만든 커밋을 파싱할 수 없습니다"
 
-#: sequencer.c:1023
+#: sequencer.c:1151
 msgid "unable to resolve HEAD after creating commit"
 msgstr "커밋을 만든 후 HEAD를 찾을 수 없습니다"
 
-#: sequencer.c:1025
+#: sequencer.c:1153
 msgid "detached HEAD"
 msgstr "HEAD 분리됨"
 
-#: sequencer.c:1029
+#: sequencer.c:1157
 msgid " (root-commit)"
 msgstr " (최상위-커밋)"
 
-#: sequencer.c:1050
+#: sequencer.c:1178
 msgid "could not parse HEAD"
 msgstr "HEAD를 파싱할 수 없습니다"
 
-#: sequencer.c:1052
+#: sequencer.c:1180
 #, c-format
 msgid "HEAD %s is not a commit!"
 msgstr "HEAD %s은(는) 커밋이 아닙니다!"
 
-#: sequencer.c:1056 builtin/commit.c:1491
+#: sequencer.c:1184 builtin/commit.c:1528
 msgid "could not parse HEAD commit"
 msgstr "HEAD 커밋을 파싱할 수 없습니다"
 
-#: sequencer.c:1107 sequencer.c:1673
+#: sequencer.c:1235 sequencer.c:1832
 msgid "unable to parse commit author"
 msgstr "커밋 작성자를 파싱할 수 없습니다"
 
-#: sequencer.c:1117 builtin/am.c:1630 builtin/merge.c:643
+#: sequencer.c:1245 builtin/am.c:1630 builtin/merge.c:645
 msgid "git write-tree failed to write a tree"
 msgstr "git write-tree가 트리를 쓰는데 실패했습니다"
 
-#: sequencer.c:1134 sequencer.c:1186
+#: sequencer.c:1262 sequencer.c:1317
 #, c-format
 msgid "unable to read commit message from '%s'"
 msgstr " '%s'의 커밋 메시지를 읽을 수 없습니다"
 
-#: sequencer.c:1154 builtin/am.c:1650 builtin/commit.c:1594 builtin/merge.c:826
-#: builtin/merge.c:851
+#: sequencer.c:1284 builtin/am.c:1650 builtin/commit.c:1631 builtin/merge.c:825
+#: builtin/merge.c:850
 msgid "failed to write commit object"
 msgstr "커밋 오브젝트를 쓰는데 실패했습니다"
 
-#: sequencer.c:1213
+#: sequencer.c:1344
 #, c-format
 msgid "could not parse commit %s"
 msgstr "%s 커밋을 파싱할 수 없습니다"
 
-#: sequencer.c:1218
+#: sequencer.c:1349
 #, c-format
 msgid "could not parse parent commit %s"
 msgstr "%s 이전 커밋을 파싱할 수 없습니다"
 
-#: sequencer.c:1347
-#, c-format
-msgid ""
-"unexpected 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"커밋 합치기 메시지의 첫 줄이 예상치 못함:\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1353
-#, c-format
-msgid ""
-"invalid 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"커밋 합치기 메시지의 첫 줄이 잘못됨:\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1359 sequencer.c:1384
+#: sequencer.c:1500 sequencer.c:1525
 #, c-format
 msgid "This is a combination of %d commits."
 msgstr "커밋 %d개가 섞인 결과입니다."
 
-#: sequencer.c:1368 sequencer.c:3265
+#: sequencer.c:1510 sequencer.c:4355
 msgid "need a HEAD to fixup"
 msgstr "바로잡으려면 HEAD가 필요합니다"
 
-#: sequencer.c:1370
+#: sequencer.c:1512 sequencer.c:2729
 msgid "could not read HEAD"
 msgstr "HEAD를 읽을 수 없습니다"
 
-#: sequencer.c:1372
+#: sequencer.c:1514
 msgid "could not read HEAD's commit message"
 msgstr "HEAD의 커밋 메시지를 읽을 수 없습니다"
 
-#: sequencer.c:1378
+#: sequencer.c:1520
 #, c-format
 msgid "cannot write '%s'"
 msgstr "'%s'을(를) 쓸 수 없습니다"
 
-#: sequencer.c:1387 git-rebase--interactive.sh:452
+#: sequencer.c:1527 git-rebase--interactive.sh:457
 msgid "This is the 1st commit message:"
 msgstr "1번째 커밋 메시지입니다:"
 
-#: sequencer.c:1395
+#: sequencer.c:1535
 #, c-format
 msgid "could not read commit message of %s"
 msgstr "%s의 커밋 메시지를 읽을 수 없습니다"
 
-#: sequencer.c:1402
+#: sequencer.c:1542
 #, c-format
 msgid "This is the commit message #%d:"
 msgstr "커밋 메시지 #%d번입니다:"
 
-#: sequencer.c:1407
+#: sequencer.c:1548
 #, c-format
 msgid "The commit message #%d will be skipped:"
 msgstr "커밋 메시지 #%d번을 건너뜁니다:"
 
-#: sequencer.c:1412
+#: sequencer.c:1553
 #, c-format
 msgid "unknown command: %d"
 msgstr "알 수 없는 명령: %d"
 
-#: sequencer.c:1479
+#: sequencer.c:1631
 msgid "your index file is unmerged."
 msgstr "인덱스 파일이 병합되지 않았습니다."
 
-#: sequencer.c:1498
+#: sequencer.c:1638
+msgid "cannot fixup root commit"
+msgstr "최상위 커밋을 바로잡을 수 없습니다"
+
+#: sequencer.c:1657
 #, c-format
 msgid "commit %s is a merge but no -m option was given."
 msgstr "%s 커밋은 병합이지만 -m 옵션이 주어지지 않았습니다."
 
 # FIXME: "parent %d" 번호가 무슨 의미?
-#: sequencer.c:1506
+#: sequencer.c:1665
 #, c-format
 msgid "commit %s does not have parent %d"
 msgstr "%s 커밋에 이전 커밋 %d이(가) 없습니다"
 
-#: sequencer.c:1510
+#: sequencer.c:1669
 #, c-format
 msgid "mainline was specified but commit %s is not a merge."
 msgstr "메인라인을 지정했지만 %s 커밋이 병합 커밋이 아닙니다."
 
-#: sequencer.c:1516
+#: sequencer.c:1675
 #, c-format
 msgid "cannot get commit message for %s"
 msgstr "%s에 대한 커밋 메시지를 가져올 수 없습니다"
 
 #. TRANSLATORS: The first %s will be a "todo" command like
 #. "revert" or "pick", the second %s a SHA1.
-#: sequencer.c:1535
+#: sequencer.c:1694
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s: %s 이전 커밋을 파싱할 수 없습니다"
 
-#: sequencer.c:1600 sequencer.c:2397
+#: sequencer.c:1759
 #, c-format
 msgid "could not rename '%s' to '%s'"
 msgstr "'%s'에서 '%s'(으)로 이름을 바꿀 수 없습니다"
 
-#: sequencer.c:1654
+#: sequencer.c:1813
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "다음을 되돌릴(revert) 수 없습니다: %s... %s"
 
-#: sequencer.c:1655
+#: sequencer.c:1814
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "다음을 적용할(apply) 수 없습니다: %s... %s"
 
-#: sequencer.c:1702
+#: sequencer.c:1864
 msgid "empty commit set passed"
 msgstr "빈 커밋 모음을 건너 뜁니다"
 
-#: sequencer.c:1712
+#: sequencer.c:1874
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s: 인덱스 읽기에 실패했습니다"
 
-#: sequencer.c:1718
+#: sequencer.c:1881
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr "git %s: 인덱스 새로 고침에 실패했습니다"
 
-#: sequencer.c:1792
+#: sequencer.c:1961
 #, c-format
 msgid "%s does not accept arguments: '%s'"
 msgstr "%s(은)는 인자를 허용하지 않습니다: '%s'"
 
-#: sequencer.c:1801
+#: sequencer.c:1970
 #, c-format
 msgid "missing arguments for %s"
 msgstr "없는 인자, %s에 대해"
 
-#: sequencer.c:1844
+#: sequencer.c:2029
 #, c-format
 msgid "invalid line %d: %.*s"
 msgstr "잘못된 줄 %d: %.*s"
 
-#: sequencer.c:1852
+#: sequencer.c:2037
 #, c-format
 msgid "cannot '%s' without a previous commit"
 msgstr "이전 커밋 없이 '%s' 수행할 수 없습니다"
 
-#: sequencer.c:1883 sequencer.c:3056 sequencer.c:3091
+#: sequencer.c:2085 sequencer.c:4138 sequencer.c:4173
 #, c-format
 msgid "could not read '%s'."
 msgstr "'%s'에서 읽을 수 없습니다."
 
-#: sequencer.c:1906
+#: sequencer.c:2108
 msgid "please fix this using 'git rebase --edit-todo'."
 msgstr "'git rebase --edit-todo' 명령으로 바로잡으십시오."
 
-#: sequencer.c:1908
+#: sequencer.c:2110
 #, c-format
 msgid "unusable instruction sheet: '%s'"
 msgstr "사용 불가능 인스트럭션 시트: '%s'"
 
-#: sequencer.c:1913
+#: sequencer.c:2115
 msgid "no commits parsed."
 msgstr "파싱한 커밋이 없습니다."
 
-#: sequencer.c:1924
+#: sequencer.c:2126
 msgid "cannot cherry-pick during a revert."
 msgstr "되돌리기(revert) 중에 빼오기(cherry-pick)를 할 수 없습니다."
 
-#: sequencer.c:1926
+#: sequencer.c:2128
 msgid "cannot revert during a cherry-pick."
 msgstr "빼오기(cherry-pick) 중에 되돌리기(revert)를 할 수 없습니다."
 
-#: sequencer.c:1993
+#: sequencer.c:2195
 #, c-format
 msgid "invalid key: %s"
 msgstr "잘못된 키: %s"
 
-#: sequencer.c:1996
+#: sequencer.c:2198
 #, c-format
 msgid "invalid value for %s: %s"
 msgstr "%s의 값이 잘못됨: %s"
 
-#: sequencer.c:2062
+#: sequencer.c:2269
+msgid "unusable squash-onto"
+msgstr "불안한 squash-onto"
+
+#: sequencer.c:2285
 #, c-format
 msgid "malformed options sheet: '%s'"
 msgstr "형식이 잘못된 옵션 시트: '%s'"
 
-#: sequencer.c:2100
+#: sequencer.c:2323
 msgid "a cherry-pick or revert is already in progress"
 msgstr "이미 커밋 빼오기(cherry-pick) 또는 되돌리기(revert)가 진행 중입니다"
 
-#: sequencer.c:2101
+#: sequencer.c:2324
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "\"git cherry-pick (--continue | --quit | --abort)\" 명령을 해 보십시오"
 
-#: sequencer.c:2104
+#: sequencer.c:2327
 #, c-format
 msgid "could not create sequencer directory '%s'"
 msgstr "'%s' 시퀀서 디렉터리를 만들 수 없습니다"
 
-#: sequencer.c:2118
+#: sequencer.c:2341
 msgid "could not lock HEAD"
 msgstr "HEAD를 잠글 수 없습니다"
 
-#: sequencer.c:2173 sequencer.c:2761
+#: sequencer.c:2396 sequencer.c:3403
 msgid "no cherry-pick or revert in progress"
 msgstr "빼오기(cherry-pick) 또는 되돌리기(revert)가 진행 중이지 않습니다"
 
-#: sequencer.c:2175
+#: sequencer.c:2398
 msgid "cannot resolve HEAD"
 msgstr "HEAD를 구해 올 수 없습니다"
 
-#: sequencer.c:2177 sequencer.c:2212
+#: sequencer.c:2400 sequencer.c:2435
 msgid "cannot abort from a branch yet to be born"
 msgstr "새로 만들고 있는 브랜치에서 중지할 수 없습니다"
 
-#: sequencer.c:2198 builtin/grep.c:720
+#: sequencer.c:2421 builtin/grep.c:720
 #, c-format
 msgid "cannot open '%s'"
 msgstr "'%s'을(를) 열 수 없습니다"
 
-#: sequencer.c:2200
+#: sequencer.c:2423
 #, c-format
 msgid "cannot read '%s': %s"
 msgstr "'%s'을(를) 읽을 수 없습니다: %s"
 
-#: sequencer.c:2201
+#: sequencer.c:2424
 msgid "unexpected end of file"
 msgstr "예상치 못하게 파일이 끝났습니다"
 
-#: sequencer.c:2207
+#: sequencer.c:2430
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr "빼오기 전에 저장한 HEAD 파일이('%s') 손상되었습니다"
 
-#: sequencer.c:2218
+#: sequencer.c:2441
 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
 msgstr "HEAD를 옮긴 것 같습니다. 되돌리지 않습니다. HEAD를 확인하십시오!"
 
-#: sequencer.c:2324 sequencer.c:2679
+#: sequencer.c:2545 sequencer.c:3321
 #, c-format
 msgid "could not update %s"
 msgstr "%s을(를) 업데이트할 수 없습니다"
 
-#: sequencer.c:2362 sequencer.c:2659
+#: sequencer.c:2583 sequencer.c:3301
 msgid "cannot read HEAD"
 msgstr "HEAD를 읽을 수 없습니다"
 
-#: sequencer.c:2402 builtin/difftool.c:639
+#: sequencer.c:2618 sequencer.c:2622 builtin/difftool.c:639
 #, c-format
 msgid "could not copy '%s' to '%s'"
 msgstr "'%s'에서 '%s'(으)로 복사할 수 없습니다"
 
-#: sequencer.c:2421
+#: sequencer.c:2641
 msgid "could not read index"
 msgstr "인덱스를 읽을 수 없습니다"
 
-#: sequencer.c:2426
+#: sequencer.c:2646
 #, c-format
 msgid ""
 "execution failed: %s\n"
@@ -3535,11 +3826,11 @@ msgstr ""
 "  git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2432
+#: sequencer.c:2652
 msgid "and made changes to the index and/or the working tree\n"
 msgstr "그리고 인덱스 그리고/또는 작업 폴더에 변경 사항이 있습니다\n"
 
-#: sequencer.c:2438
+#: sequencer.c:2658
 #, c-format
 msgid ""
 "execution succeeded: %s\n"
@@ -3556,17 +3847,62 @@ msgstr ""
 "  git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2497
+#: sequencer.c:2771
+msgid "writing fake root commit"
+msgstr "가짜 최상위 커밋을 씁니다"
+
+#: sequencer.c:2776
+msgid "writing squash-onto"
+msgstr "squash-onto를 씁니다"
+
+#: sequencer.c:2811
+#, c-format
+msgid "failed to find tree of %s"
+msgstr "%s의 트리를 찾는데 실패했습니다"
+
+#: sequencer.c:2829
+msgid "could not write index"
+msgstr "인덱스를 쓸 수 없습니다"
+
+#: sequencer.c:2861
+msgid "cannot merge without a current revision"
+msgstr "현재 리비전 없이 병합할 수 없습니다"
+
+#: sequencer.c:2884
+#, c-format
+msgid "could not resolve '%s'"
+msgstr "'%s' 해결할 수 없습니다"
+
+#: sequencer.c:2906
+#, c-format
+msgid "could not get commit message of '%s'"
+msgstr "'%s'의 커밋 메시지를 읽을 수 없습니다"
+
+#: sequencer.c:2916 sequencer.c:2941
+#, c-format
+msgid "could not write '%s'"
+msgstr "'%s'에 쓸 수 없습니다"
+
+#: sequencer.c:3005
+#, c-format
+msgid "could not even attempt to merge '%.*s'"
+msgstr "'%.*s' 병합을 시도도 할 수 없습니다"
+
+#: sequencer.c:3021
+msgid "merge: Unable to write new index file"
+msgstr "병합: 새 인덱스 파일을 쓸 수 없습니다"
+
+#: sequencer.c:3088
 #, c-format
 msgid "Applied autostash.\n"
 msgstr "자동 스태시 적용.\n"
 
-#: sequencer.c:2509
+#: sequencer.c:3100
 #, c-format
 msgid "cannot store %s"
 msgstr "%s을(를) 저장할 수 없습니다"
 
-#: sequencer.c:2512 git-rebase.sh:178
+#: sequencer.c:3103 git-rebase.sh:188
 #, c-format
 msgid ""
 "Applying autostash resulted in conflicts.\n"
@@ -3577,52 +3913,69 @@ msgstr ""
 "변경 사항은 스태시 안에 안전하게 들어 있습니다.\n"
 "언제든지 \"git stash pop\" 또는 \"git stash drop\"을 실행할 수 있습니다.\n"
 
-#: sequencer.c:2595
+#: sequencer.c:3134
+#, c-format
+msgid ""
+"Could not execute the todo command\n"
+"\n"
+"    %.*s\n"
+"It has been rescheduled; To edit the command before continuing, please\n"
+"edit the todo list first:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+msgstr ""
+"할 일 목록 명령을 실행할 수 없습니다\n"
+"\n"
+"    %.*s\n"
+"스케줄을 조정합니다. 계속 하기 전에 명령어를 편집하려면, 먼저 다음\n"
+"할 일 목록을 편집하십시오:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+
+#: sequencer.c:3202
 #, c-format
 msgid "Stopped at %s...  %.*s\n"
 msgstr "%s...  %.*s 위치에서 멈췄습니다\n"
 
-#: sequencer.c:2637
+#: sequencer.c:3264
 #, c-format
 msgid "unknown command %d"
 msgstr "알 수 없는 명령 %d"
 
-#: sequencer.c:2667
+#: sequencer.c:3309
 msgid "could not read orig-head"
 msgstr "orig-head를 읽을 수 없습니다"
 
-#: sequencer.c:2672 sequencer.c:3262
+#: sequencer.c:3314 sequencer.c:4352
 msgid "could not read 'onto'"
 msgstr "'onto'를 읽을 수 없습니다"
 
-#: sequencer.c:2686
+#: sequencer.c:3328
 #, c-format
 msgid "could not update HEAD to %s"
 msgstr "HEAD를 %s 위치로 업데이트할 수 없습니다"
 
-#: sequencer.c:2770
+#: sequencer.c:3414
 msgid "cannot rebase: You have unstaged changes."
 msgstr "리베이스할 수 없습니다: 스테이징하지 않은 변경 사항이 있습니다."
 
-#: sequencer.c:2775
-msgid "could not remove CHERRY_PICK_HEAD"
-msgstr "CHERRY_PICK_HEAD를 제거할 수 없습니다"
-
-#: sequencer.c:2784
+#: sequencer.c:3423
 msgid "cannot amend non-existing commit"
 msgstr "없는 커밋을 수정할 수 없습니다"
 
-#: sequencer.c:2786
+#: sequencer.c:3425
 #, c-format
 msgid "invalid file: '%s'"
 msgstr "잘못된 파일: '%s'"
 
-#: sequencer.c:2788
+#: sequencer.c:3427
 #, c-format
 msgid "invalid contents: '%s'"
 msgstr "잘못된 내용: '%s'"
 
-#: sequencer.c:2791
+#: sequencer.c:3430
 msgid ""
 "\n"
 "You have uncommitted changes in your working tree. Please, commit them\n"
@@ -3632,45 +3985,54 @@ msgstr ""
 "작업 폴더에 커밋하지 않은 변경 사항이 있습니다. 이 사항을 먼저\n"
 "커밋하고 'git rebase --continue' 명령을 다시 실행하십시오."
 
-#: sequencer.c:2801
+#: sequencer.c:3455 sequencer.c:3493
+#, c-format
+msgid "could not write file: '%s'"
+msgstr "파일을 쓸 수 없습니다: '%s'"
+
+#: sequencer.c:3508
+msgid "could not remove CHERRY_PICK_HEAD"
+msgstr "CHERRY_PICK_HEAD를 제거할 수 없습니다"
+
+#: sequencer.c:3515
 msgid "could not commit staged changes."
 msgstr "스테이징한 변경 사항을 커밋할 수 없습니다."
 
-#: sequencer.c:2881
+#: sequencer.c:3612
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s: %s 커밋을 빼올 수 없습니다"
 
-#: sequencer.c:2885
+#: sequencer.c:3616
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s: 잘못된 리비전"
 
-#: sequencer.c:2918
+#: sequencer.c:3649
 msgid "can't revert as initial commit"
 msgstr "최초의 커밋으로 되돌릴 수 없습니다"
 
-#: sequencer.c:3023
+#: sequencer.c:4098
 msgid "make_script: unhandled options"
 msgstr "make_script: 처리하지 않은 옵션"
 
-#: sequencer.c:3026
+#: sequencer.c:4101
 msgid "make_script: error preparing revisions"
 msgstr "make_script: 리비전 준비 중 오류"
 
-#: sequencer.c:3060 sequencer.c:3095
+#: sequencer.c:4142 sequencer.c:4177
 #, c-format
 msgid "unusable todo list: '%s'"
 msgstr "사용할 수 없는 할 일 목록: %s"
 
-#: sequencer.c:3146
+#: sequencer.c:4236
 #, c-format
 msgid ""
 "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
 msgstr ""
 "rebase.missingCommitsCheck 옵션에 대해 인식할 수 없는 %s 설정. 무시합니다."
 
-#: sequencer.c:3212
+#: sequencer.c:4302
 #, c-format
 msgid ""
 "Warning: some commits may have been dropped accidentally.\n"
@@ -3679,7 +4041,7 @@ msgstr ""
 "경고: 일부 커밋이 의도치 않게 버려졌을 수도 있습니다.\n"
 "버려진 커밋 (최근에서 과거 순서):\n"
 
-#: sequencer.c:3219
+#: sequencer.c:4309
 #, c-format
 msgid ""
 "To avoid this message, use \"drop\" to explicitly remove a commit.\n"
@@ -3697,7 +4059,7 @@ msgstr ""
 "가능한 동작은: ignore, warn, error\n"
 "\n"
 
-#: sequencer.c:3231
+#: sequencer.c:4321
 #, c-format
 msgid ""
 "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
@@ -3708,27 +4070,21 @@ msgstr ""
 "령을 실행합니다.\n"
 "또는 'git rebase --abort' 명령으로 리베이스를 중지할 수도 있습니다.\n"
 
-#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395
-#: builtin/am.c:779
-#, c-format
-msgid "could not open '%s' for writing"
-msgstr "'%s'을(를) 쓰기용으로 열 수 없습니다"
-
-#: sequencer.c:3285
+#: sequencer.c:4375
 #, c-format
 msgid "could not parse commit '%s'"
 msgstr "'%s' 커밋을 파싱할 수 없습니다"
 
-#: sequencer.c:3401
+#: sequencer.c:4490
 msgid "the script was already rearranged."
 msgstr "스크립트를 이미 재구성했습니다."
 
-#: setup.c:122
+#: setup.c:123
 #, c-format
 msgid "'%s' is outside repository"
 msgstr "'%s'은(는) 저장소 밖입니다"
 
-#: setup.c:171
+#: setup.c:172
 #, c-format
 msgid ""
 "%s: no such path in the working tree.\n"
@@ -3737,7 +4093,7 @@ msgstr ""
 "%s: 작업 폴더에 그런 경로가 없습니다.\n"
 "로컬에 없는 경로를 지정하려면 'git <명령> -- <경로>...' 식으로 사용하십시오."
 
-#: setup.c:184
+#: setup.c:185
 #, c-format
 msgid ""
 "ambiguous argument '%s': unknown revision or path not in the working tree.\n"
@@ -3748,12 +4104,12 @@ msgstr ""
 "경로와 리비전을 구분하려면 다음과 같이 '--'를 사용하십시오:\n"
 "'git <명령> [<리비전>...] -- [<파일>...]'"
 
-#: setup.c:233
+#: setup.c:234
 #, c-format
 msgid "option '%s' must come before non-option arguments"
 msgstr "'%s' 옵션은  옵션이 아닌 인자 전에 와야 합니다"
 
-#: setup.c:252
+#: setup.c:253
 #, c-format
 msgid ""
 "ambiguous argument '%s': both revision and filename\n"
@@ -3764,92 +4120,92 @@ msgstr ""
 "경로와 리비전을 구분하려면 다음과 같이 '--'를 사용하십시오:\n"
 "'git <명령> [<리비전>...] -- [<파일>...]'"
 
-#: setup.c:388
+#: setup.c:389
 msgid "unable to set up work tree using invalid config"
 msgstr "잘못된 설정을 사용하여 작업 폴더를 설정할 수 없습니다"
 
-#: setup.c:395
+#: setup.c:393
 msgid "this operation must be run in a work tree"
 msgstr "이 작업은 작업 폴더에서 실행해야 합니다"
 
-#: setup.c:506
+#: setup.c:503
 #, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "깃 저장소 버전 <= %d 버전을 기대하지만, %d 버전이 발견되었습니다"
 
-#: setup.c:514
+#: setup.c:511
 msgid "unknown repository extensions found:"
 msgstr "알 수 없는 저장소 확장이 있습니다:"
 
-#: setup.c:533
+#: setup.c:530
 #, c-format
 msgid "error opening '%s'"
 msgstr "'%s'을(를) 여는데 오류"
 
-#: setup.c:535
+#: setup.c:532
 #, c-format
 msgid "too large to be a .git file: '%s'"
 msgstr ".git 파일이 너무 큽니다: '%s'"
 
-#: setup.c:537
+#: setup.c:534
 #, c-format
 msgid "error reading %s"
 msgstr "%s을(를) 읽는데 오류"
 
-#: setup.c:539
+#: setup.c:536
 #, c-format
 msgid "invalid gitfile format: %s"
 msgstr "깃파일 형식이 잘못되었습니다: %s"
 
-#: setup.c:541
+#: setup.c:538
 #, c-format
 msgid "no path in gitfile: %s"
 msgstr "깃파일에 경로가 없습니다: %s"
 
-#: setup.c:543
+#: setup.c:540
 #, c-format
 msgid "not a git repository: %s"
 msgstr "깃 저장소가 아닙니다: %s"
 
-#: setup.c:642
+#: setup.c:639
 #, c-format
 msgid "'$%s' too big"
 msgstr "'$%s'이(가) 너무 큽니다"
 
-#: setup.c:656
+#: setup.c:653
 #, c-format
 msgid "not a git repository: '%s'"
 msgstr "깃 저장소가 아닙니다: '%s'"
 
-#: setup.c:685 setup.c:687 setup.c:718
+#: setup.c:682 setup.c:684 setup.c:715
 #, c-format
 msgid "cannot chdir to '%s'"
 msgstr "'%s'에 대해 chdir를 할 수 없습니다"
 
-#: setup.c:690 setup.c:746 setup.c:756 setup.c:795 setup.c:803 setup.c:818
+#: setup.c:687 setup.c:743 setup.c:753 setup.c:792 setup.c:800 setup.c:815
 msgid "cannot come back to cwd"
 msgstr "현재 디렉터리로 돌아올 수 없습니다"
 
-#: setup.c:816
+#: setup.c:813
 #, c-format
 msgid "not a git repository (or any of the parent directories): %s"
 msgstr "(현재 폴더 또는 상위 폴더 중 일부가) 깃 저장소가 아닙니다: %s"
 
-#: setup.c:827
+#: setup.c:824
 #, c-format
 msgid "failed to stat '%*s%s%s'"
 msgstr "'%*s%s%s'에 대해 stat()이 실패했습니다"
 
-#: setup.c:1057
+#: setup.c:1054
 msgid "Unable to read current working directory"
 msgstr "현재 작업 디렉터리를 읽을 수 없습니다"
 
-#: setup.c:1069 setup.c:1075
+#: setup.c:1066 setup.c:1072
 #, c-format
 msgid "cannot change to '%s'"
 msgstr "'%s'에 대해 변경 할 수 없습니다"
 
-#: setup.c:1088
+#: setup.c:1085
 #, c-format
 msgid ""
 "not a git repository (or any parent up to mount point %s)\n"
@@ -3860,7 +4216,7 @@ msgstr ""
 "파일 시스템 경계에서 중지합니다. (GIT_DISCOVERY_ACROSS_FILESYSTEM 설정되지 않"
 "음)"
 
-#: setup.c:1172
+#: setup.c:1168
 #, c-format
 msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
@@ -3869,54 +4225,54 @@ msgstr ""
 "core.sharedRepository 파일모드 값에 (0%.3o) 문제가 있습니다.\n"
 "파일의 소유자에 읽기와 쓰기 권한이 있어야 합니다."
 
-#: setup.c:1215
+#: setup.c:1211
 msgid "open /dev/null or dup failed"
 msgstr "/dev/null 열기 또는 dup()이 실패"
 
-#: setup.c:1230
+#: setup.c:1226
 msgid "fork failed"
 msgstr "fork 실패"
 
-#: setup.c:1235
+#: setup.c:1231
 msgid "setsid failed"
 msgstr "setsid 실패"
 
-#: sha1_file.c:592
+#: sha1-file.c:625
 #, c-format
 msgid "path '%s' does not exist"
 msgstr "'%s' 경로가 없습니다"
 
-#: sha1_file.c:618
+#: sha1-file.c:651
 #, c-format
 msgid "reference repository '%s' as a linked checkout is not supported yet."
 msgstr ""
 "레퍼런스 '%s' 저장소를 연결된 체크아웃으로 쓰기는 아직 지원하지 않습니다."
 
-#: sha1_file.c:624
+#: sha1-file.c:657
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "레퍼런스 '%s' 저장소가 로컬 저장소가 아닙니다."
 
-#: sha1_file.c:630
+#: sha1-file.c:663
 #, c-format
 msgid "reference repository '%s' is shallow"
 msgstr "레퍼런스 '%s' 저장소가 얕은 저장소입니다"
 
-#: sha1_file.c:638
+#: sha1-file.c:671
 #, c-format
 msgid "reference repository '%s' is grafted"
-msgstr "레퍼런스 '%s' 저장소가 붙어 있는 저장소입니다"
+msgstr "레퍼런스 '%s' 저장소가 그래프트로 붙은 저장소입니다"
 
-#: sha1_name.c:422
+#: sha1-name.c:442
 #, c-format
 msgid "short SHA1 %s is ambiguous"
 msgstr "짧은 SHA1 %s은(는) 여럿에 대응됩니다"
 
-#: sha1_name.c:433
+#: sha1-name.c:453
 msgid "The candidates are:"
 msgstr "후보는 다음과 같습니다:"
 
-#: sha1_name.c:693
+#: sha1-name.c:695
 msgid ""
 "Git normally never creates a ref that ends with 40 hex characters\n"
 "because it will be ignored when you just specify 40-hex. These refs\n"
@@ -3938,70 +4294,70 @@ msgstr ""
 "확인해 보시고 잘못 만들어진 것이면 지우십시오. 이 메시지를 보고 싶지\n"
 "않으면 \"git config advice.objectNameWarning false\" 명령을 사용하십시오."
 
-#: submodule.c:96 submodule.c:130
+#: submodule.c:97 submodule.c:131
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr ""
 "병합하지 않은 .gitmodules를 바꿀 수 없습니다. 병합 충돌을 먼저 해결하십시오"
 
-#: submodule.c:100 submodule.c:134
+#: submodule.c:101 submodule.c:135
 #, c-format
 msgid "Could not find section in .gitmodules where path=%s"
 msgstr "경로가 %s일 때 .gitmodules의 섹션을 찾을 수 없습니다"
 
-#: submodule.c:108
+#: submodule.c:109
 #, c-format
 msgid "Could not update .gitmodules entry %s"
 msgstr ".gitmodules 항목 %s을(를) 업데이트할 수 없습니다"
 
-#: submodule.c:141
+#: submodule.c:142
 #, c-format
 msgid "Could not remove .gitmodules entry for %s"
 msgstr "%s에 대한 .gitmodules 항목을 제거할 수 없습니다"
 
-#: submodule.c:152
+#: submodule.c:153
 msgid "staging updated .gitmodules failed"
 msgstr "업데이트한 .gitmodules를 커밋할 사항으로 표시하는데 실패"
 
-#: submodule.c:312
+#: submodule.c:315
 #, c-format
 msgid "in unpopulated submodule '%s'"
 msgstr "내용이 없는 하위 모듈 '%s'에서"
 
-#: submodule.c:343
+#: submodule.c:346
 #, c-format
 msgid "Pathspec '%s' is in submodule '%.*s'"
 msgstr "경로명세 '%s'은(는) ''%.*s' 하위 모듈 안에 있습니다"
 
-#: submodule.c:833
+#: submodule.c:837
 #, c-format
 msgid "submodule entry '%s' (%s) is a %s, not a commit"
 msgstr "서브모듈 항목 '%s'(%s)은(는) %s이고, 커밋이 아닙니다"
 
-#: submodule.c:1065 builtin/branch.c:648 builtin/submodule--helper.c:1724
+#: submodule.c:1069 builtin/branch.c:651 builtin/submodule--helper.c:1743
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "HEAD를 올바른 레퍼런스로 구해내는데 실패했습니다."
 
-#: submodule.c:1370
+#: submodule.c:1375
 #, c-format
 msgid "'%s' not recognized as a git repository"
 msgstr "'%s'은(는) 깃 저장소로 인식되지 않습니다"
 
-#: submodule.c:1508
+#: submodule.c:1513
 #, c-format
 msgid "could not start 'git status' in submodule '%s'"
 msgstr "하위 모듈 '%s'에서 'git status'를 시작할 수 없습니다"
 
-#: submodule.c:1521
+#: submodule.c:1526
 #, c-format
 msgid "could not run 'git status' in submodule '%s'"
 msgstr "하위 모듈 '%s'에서 'git status'를 실행할 수 없습니다"
 
-#: submodule.c:1614
+#: submodule.c:1619
 #, c-format
 msgid "submodule '%s' has dirty index"
 msgstr "'%s' 하위 모듈에 변경된 인덱스가 있습니다"
 
-#: submodule.c:1878
+#: submodule.c:1718
 #, c-format
 msgid ""
 "relocate_gitdir for submodule '%s' with more than one worktree not supported"
@@ -4009,18 +4365,18 @@ msgstr ""
 "여러 개의 작업 폴더가 있는 하위 모듈 '%s'에 대해 relocate_gitdir은 지원하지 "
 "않습니다"
 
-#: submodule.c:1890 submodule.c:1946
+#: submodule.c:1730 submodule.c:1786
 #, c-format
 msgid "could not lookup name for submodule '%s'"
 msgstr "하위 모듈 '%s'의 이름을 찾아볼 수 없습니다"
 
-#: submodule.c:1894 builtin/submodule--helper.c:1246
-#: builtin/submodule--helper.c:1256
+#: submodule.c:1734 builtin/submodule--helper.c:1261
+#: builtin/submodule--helper.c:1271
 #, c-format
 msgid "could not create directory '%s'"
 msgstr "'%s' 디렉터리를 만들 수 없습니다"
 
-#: submodule.c:1897
+#: submodule.c:1737
 #, c-format
 msgid ""
 "Migrating git directory of '%s%s' from\n"
@@ -4031,29 +4387,30 @@ msgstr ""
 "'%s'에서\n"
 "'%s'(으)로\n"
 
-#: submodule.c:1981
+#: submodule.c:1821
 #, c-format
 msgid "could not recurse into submodule '%s'"
 msgstr "재귀적으로 '%s' 하위 모듈에 들어갈 수 없습니다"
 
-#: submodule.c:2025
+#: submodule.c:1865
 msgid "could not start ls-files in .."
 msgstr "'..' 안에서 ls-files를 시작할 수 없습니다"
 
-#: submodule.c:2045
-msgid "BUG: returned path string doesn't match cwd?"
-msgstr "버그: 리턴된 경로 문자열이 현재 디렉터리와 맞지 않습니다?"
-
-#: submodule.c:2064
+#: submodule.c:1904
 #, c-format
 msgid "ls-tree returned unexpected return code %d"
 msgstr "ls-tree가 예상치 못한 코드 %d번을 리턴했습니다"
 
-#: submodule-config.c:263
+#: submodule-config.c:230
+#, c-format
+msgid "ignoring suspicious submodule name: %s"
+msgstr "의심스러운 하위 모듈 이름을 무시합니다: %s"
+
+#: submodule-config.c:294
 msgid "negative values not allowed for submodule.fetchjobs"
 msgstr "submodule.fetchjobs 값에 음수를 쓸 수 없습니다"
 
-#: submodule-config.c:436
+#: submodule-config.c:467
 #, c-format
 msgid "invalid value for %s"
 msgstr "%s의 값이 올바르지 않습니다"
@@ -4069,7 +4426,7 @@ msgstr "트레일러 명령 '%s' 실행 실패"
 msgid "unknown value '%s' for key '%s'"
 msgstr "알 수 없는 값 '%s', 키 '%s'"
 
-#: trailer.c:539 trailer.c:544 builtin/remote.c:290
+#: trailer.c:539 trailer.c:544 builtin/remote.c:293
 #, c-format
 msgid "more than one %s"
 msgstr "%s이(가) 여러개입니다"
@@ -4112,17 +4469,21 @@ msgstr "임시 파일을 열 수 없습니다: %s"
 msgid "could not rename temporary file to %s"
 msgstr "임시 파일 이름을 '%s'(으)로 바꿀 수 없습니다"
 
-#: transport.c:63
+#: transport.c:116
 #, c-format
 msgid "Would set upstream of '%s' to '%s' of '%s'\n"
 msgstr "'%1$s'의 업스트림을 '%3$s'의 '%2$s'(으)로 설정합니다\n"
 
-#: transport.c:152
+#: transport.c:208
 #, c-format
 msgid "transport: invalid depth option '%s'"
 msgstr "transport: 잘못된 깊이 옵션: %s"
 
-#: transport.c:916
+#: transport.c:584
+msgid "could not parse transport.color.* config"
+msgstr "transport.color.* 설정을 파싱할 수 없습니다"
+
+#: transport.c:996
 #, c-format
 msgid ""
 "The following submodule paths contain changes that can\n"
@@ -4131,7 +4492,7 @@ msgstr ""
 "다음 하위 모듈 경로에 리모트 어디에도 없는\n"
 "변경 사항이 있습니다:\n"
 
-#: transport.c:920
+#: transport.c:1000
 #, c-format
 msgid ""
 "\n"
@@ -4158,11 +4519,11 @@ msgstr ""
 "명령을 시도해 보십시오\n"
 "\n"
 
-#: transport.c:928
+#: transport.c:1008
 msgid "Aborting."
 msgstr "중지함."
 
-#: transport-helper.c:1079
+#: transport-helper.c:1087
 #, c-format
 msgid "Could not read ref %s"
 msgstr "%s 레퍼런스를 읽을 수 없습니다"
@@ -4179,11 +4540,11 @@ msgstr "트리 엔트리에 잘못된 형식의 모드"
 msgid "empty filename in tree entry"
 msgstr "트리 엔트리에 빈 파일 이름"
 
-#: tree-walk.c:114
+#: tree-walk.c:113
 msgid "too-short tree file"
 msgstr "너무 짧은 트리 파일"
 
-#: unpack-trees.c:108
+#: unpack-trees.c:111
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4192,7 +4553,7 @@ msgstr ""
 "다음 파일의 로컬 변경 사항을 체크아웃 때문에 덮어 쓰게 됩니다:\n"
 "%%s브랜치를 전환하기 전에 변경 사항을 커밋하거나 스태시하십시오."
 
-#: unpack-trees.c:110
+#: unpack-trees.c:113
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4201,7 +4562,7 @@ msgstr ""
 "다음 파일의 로컬 변경 사항을 체크아웃 때문에 덮어 쓰게 됩니다:\n"
 "%%s"
 
-#: unpack-trees.c:113
+#: unpack-trees.c:116
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4210,14 +4571,14 @@ msgstr ""
 "다음 파일의 로컬 변경 사항을 병합 때문에 덮어 쓰게 됩니다:\n"
 "%%s병합하기 전에 변경 사항을 커밋하거나 스태시하십시오."
 
-#: unpack-trees.c:115
+#: unpack-trees.c:118
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
 "%%s"
 msgstr "다음 파일의 로컬 변경 사항을 병합 때문에 덮어 쓰게 됩니다."
 
-#: unpack-trees.c:118
+#: unpack-trees.c:121
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4226,7 +4587,7 @@ msgstr ""
 "다음 파일의 로컬 변경 사항을 %s 때문에 덮어 쓰게 됩니다:\n"
 "%%s%s 전에 변경 사항을 커밋하거나 스태시하십시오."
 
-#: unpack-trees.c:120
+#: unpack-trees.c:123
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4235,7 +4596,7 @@ msgstr ""
 "다음 파일의 로컬 변경 사항을 %s 때문에 덮어 쓰게 됩니다:\n"
 "%%s"
 
-#: unpack-trees.c:125
+#: unpack-trees.c:128
 #, c-format
 msgid ""
 "Updating the following directories would lose untracked files in them:\n"
@@ -4244,7 +4605,7 @@ msgstr ""
 "다음 디렉터리를 업데이트하면 그 안의 추적하지 않는 파일을 잃어버립니다:\n"
 "%s"
 
-#: unpack-trees.c:129
+#: unpack-trees.c:132
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4253,7 +4614,7 @@ msgstr ""
 "체크아웃 때문에 추적하지 않는 다음 작업 폴더의 파일이 제거됩니다:\n"
 "%%s브랜치를 전환하기 전에 이 파일을 옮기거나 제거하십시오."
 
-#: unpack-trees.c:131
+#: unpack-trees.c:134
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4262,7 +4623,7 @@ msgstr ""
 "체크아웃 때문에 추적하지 않는 다음 작업 폴더 파일이 제거됩니다:\n"
 "%%s"
 
-#: unpack-trees.c:134
+#: unpack-trees.c:137
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4271,7 +4632,7 @@ msgstr ""
 "병합 때문에 추적하지 않는 다음 작업 폴더의 파일이 제거됩니다:\n"
 "%%s병합하기 전에 이 파일을 옮기거나 제거하십시오."
 
-#: unpack-trees.c:136
+#: unpack-trees.c:139
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4280,7 +4641,7 @@ msgstr ""
 "병합 때문에 추적하지 않는 다음 작업 폴더 파일이 제거됩니다:\n"
 "%%s"
 
-#: unpack-trees.c:139
+#: unpack-trees.c:142
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4289,7 +4650,7 @@ msgstr ""
 "%s 때문에 추적하지 않는 다음 작업 폴더의 파일이 제거됩니다:\n"
 "%%s%s 하기 전에 이 파일을 옮기거나 제거하십시오."
 
-#: unpack-trees.c:141
+#: unpack-trees.c:144
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4298,7 +4659,7 @@ msgstr ""
 "%s 때문에 추적하지 않는 다음 작업 폴더 파일이 제거됩니다:\n"
 "%%s"
 
-#: unpack-trees.c:146
+#: unpack-trees.c:150
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4308,7 +4669,7 @@ msgstr ""
 "체크아웃 때문에 추적하지 않는 다음 작업 폴더의 파일을 덮어씁니다:\n"
 "%%s브랜치를 전환하기 전에 이 파일을 옮기거나 제거하십시오."
 
-#: unpack-trees.c:148
+#: unpack-trees.c:152
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4318,7 +4679,7 @@ msgstr ""
 "체크아웃 때문에 추적하지 않는 다음 작업 폴더 파일을 덮어씁니다:\n"
 "%%s"
 
-#: unpack-trees.c:151
+#: unpack-trees.c:155
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4327,7 +4688,7 @@ msgstr ""
 "병합 때문에 추적하지 않는 다음 작업 폴더의 파일을 덮어씁니다:\n"
 "%%s병합하기 전에 이 파일을 옮기거나 제거하십시오."
 
-#: unpack-trees.c:153
+#: unpack-trees.c:157
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4336,7 +4697,7 @@ msgstr ""
 "병합 때문에 추적하지 않는 다음 작업 폴더 파일을 덮어씁니다:\n"
 "%%s"
 
-#: unpack-trees.c:156
+#: unpack-trees.c:160
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4345,7 +4706,7 @@ msgstr ""
 "%s 때문에 추적하지 않는 다음 작업 폴더의 파일을 덮어씁니다:\n"
 "%%s%s 하기 전에 이 파일을 옮기거나 제거하십시오."
 
-#: unpack-trees.c:158
+#: unpack-trees.c:162
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4354,12 +4715,12 @@ msgstr ""
 "%s 때문에 추적하지 않는 다음 작업 폴더 파일을 덮어씁니다:\n"
 "%%s"
 
-#: unpack-trees.c:165
+#: unpack-trees.c:170
 #, c-format
 msgid "Entry '%s' overlaps with '%s'.  Cannot bind."
 msgstr "'%s' 항목이 '%s'와(과) 겹칩니다.  묶을 수 없습니다."
 
-#: unpack-trees.c:168
+#: unpack-trees.c:173
 #, c-format
 msgid ""
 "Cannot update sparse checkout: the following entries are not up to date:\n"
@@ -4369,7 +4730,7 @@ msgstr ""
 "았습니다:\n"
 "%s"
 
-#: unpack-trees.c:170
+#: unpack-trees.c:175
 #, c-format
 msgid ""
 "The following working tree files would be overwritten by sparse checkout "
@@ -4380,7 +4741,7 @@ msgstr ""
 "다:\n"
 "%s"
 
-#: unpack-trees.c:172
+#: unpack-trees.c:177
 #, c-format
 msgid ""
 "The following working tree files would be removed by sparse checkout "
@@ -4391,7 +4752,7 @@ msgstr ""
 "다:\n"
 "%s"
 
-#: unpack-trees.c:174
+#: unpack-trees.c:179
 #, c-format
 msgid ""
 "Cannot update submodule:\n"
@@ -4400,12 +4761,12 @@ msgstr ""
 "하위 모듈을  업데이트할 수 없습니다:\n"
 "%s"
 
-#: unpack-trees.c:251
+#: unpack-trees.c:262
 #, c-format
 msgid "Aborting\n"
 msgstr "중지함\n"
 
-#: unpack-trees.c:333
+#: unpack-trees.c:344
 msgid "Checking out files"
 msgstr "파일을 가져옵니다"
 
@@ -4474,7 +4835,7 @@ msgid "could not open '%s' for reading and writing"
 msgstr "읽기와 쓰기용으로 '%s'을(를) 열 수 없습니다"
 
 #: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770
-#: builtin/am.c:862 builtin/merge.c:1044
+#: builtin/am.c:862 builtin/merge.c:1043
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "'%s'을(를) 읽기용으로 열 수 없습니다"
@@ -4488,152 +4849,152 @@ msgstr "'%s'에 접근할 수 없습니다"
 msgid "unable to get current working directory"
 msgstr "현재 작업 디렉터리를 가져올 수 없습니다"
 
-#: wt-status.c:151
+#: wt-status.c:154
 msgid "Unmerged paths:"
 msgstr "병합하지 않은 경로:"
 
-#: wt-status.c:178 wt-status.c:205
+#: wt-status.c:181 wt-status.c:208
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (스테이지 해제하려면 \"git reset %s <파일>...\"을 사용하십시오)"
 
-#: wt-status.c:180 wt-status.c:207
+#: wt-status.c:183 wt-status.c:210
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (스테이지 해제하려면 \"git rm --cached <파일>...\"을 사용하십시오)"
 
-#: wt-status.c:184
+#: wt-status.c:187
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (해결했다고 표시하려면 \"git add <파일>...\"을 사용하십시오)"
 
-#: wt-status.c:186 wt-status.c:190
+#: wt-status.c:189 wt-status.c:193
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr ""
 "  (해결했다고 표시하려면 알맞게 \"git add/rm <파일>...\"을 사용하십시오)"
 
-#: wt-status.c:188
+#: wt-status.c:191
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (해결했다고 표시하려면 \"git rm <파일>...\"을 사용하십시오)"
 
-#: wt-status.c:199 wt-status.c:1007
+#: wt-status.c:202 wt-status.c:1015
 msgid "Changes to be committed:"
 msgstr "커밋할 변경 사항:"
 
-#: wt-status.c:217 wt-status.c:1016
+#: wt-status.c:220 wt-status.c:1024
 msgid "Changes not staged for commit:"
 msgstr "커밋하도록 정하지 않은 변경 사항:"
 
-#: wt-status.c:221
+#: wt-status.c:224
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr "  (무엇을 커밋할지 바꾸려면 \"git add <파일>...\"을 사용하십시오)"
 
-#: wt-status.c:223
+#: wt-status.c:226
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr "  (무엇을 커밋할지 바꾸려면 \"git add/rm <파일>...\"을 사용하십시오)"
 
-#: wt-status.c:224
+#: wt-status.c:227
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 "  (작업 폴더의 변경 사항을 버리려면 \"git checkout -- <파일>...\"을 사용하십"
 "시오)"
 
-#: wt-status.c:226
+#: wt-status.c:229
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 "  (하위 모듈의 추적되지 않는 파일이나 수정된 내용을 커밋하거나 버리십시오)"
 
-#: wt-status.c:238
+#: wt-status.c:241
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr "  (커밋할 사항에 포함하려면 \"git %s <파일>...\"을 사용하십시오)"
 
-#: wt-status.c:253
+#: wt-status.c:256
 msgid "both deleted:"
 msgstr "양쪽에서 삭제:"
 
-#: wt-status.c:255
+#: wt-status.c:258
 msgid "added by us:"
 msgstr "이 쪽에서 추가:"
 
-#: wt-status.c:257
+#: wt-status.c:260
 msgid "deleted by them:"
 msgstr "저 쪽에서 삭제:"
 
-#: wt-status.c:259
+#: wt-status.c:262
 msgid "added by them:"
 msgstr "저 쪽에서 추가:"
 
-#: wt-status.c:261
+#: wt-status.c:264
 msgid "deleted by us:"
 msgstr "이 쪽에서 삭제:"
 
-#: wt-status.c:263
+#: wt-status.c:266
 msgid "both added:"
 msgstr "양쪽에서 추가:"
 
-#: wt-status.c:265
+#: wt-status.c:268
 msgid "both modified:"
 msgstr "양쪽에서 수정:"
 
-#: wt-status.c:275
+#: wt-status.c:278
 msgid "new file:"
 msgstr "새 파일:"
 
-#: wt-status.c:277
+#: wt-status.c:280
 msgid "copied:"
 msgstr "복사함:"
 
-#: wt-status.c:279
+#: wt-status.c:282
 msgid "deleted:"
 msgstr "삭제함:"
 
-#: wt-status.c:281
+#: wt-status.c:284
 msgid "modified:"
 msgstr "수정함:"
 
-#: wt-status.c:283
+#: wt-status.c:286
 msgid "renamed:"
 msgstr "이름 바꿈:"
 
-#: wt-status.c:285
+#: wt-status.c:288
 msgid "typechange:"
 msgstr "종류 바뀜:"
 
-#: wt-status.c:287
+#: wt-status.c:290
 msgid "unknown:"
 msgstr "알 수 없음:"
 
-#: wt-status.c:289
+#: wt-status.c:292
 msgid "unmerged:"
 msgstr "병합하지 않음:"
 
-#: wt-status.c:369
+#: wt-status.c:372
 msgid "new commits, "
 msgstr "새 커밋, "
 
-#: wt-status.c:371
+#: wt-status.c:374
 msgid "modified content, "
 msgstr "수정한 내용, "
 
-#: wt-status.c:373
+#: wt-status.c:376
 msgid "untracked content, "
 msgstr "추적하지 않은 내용, "
 
-#: wt-status.c:847
+#: wt-status.c:853
 #, c-format
 msgid "Your stash currently has %d entry"
 msgid_plural "Your stash currently has %d entries"
 msgstr[0] "현재 스태시에 %d개 항목이 있습니다"
 
-#: wt-status.c:879
+#: wt-status.c:885
 msgid "Submodules changed but not updated:"
 msgstr "변경되었지만 업데이트하지 않은 하위 모듈:"
 
-#: wt-status.c:881
+#: wt-status.c:887
 msgid "Submodule changes to be committed:"
 msgstr "커밋할 하위 모듈의 변경 사항:"
 
-#: wt-status.c:963
+#: wt-status.c:969
 msgid ""
 "Do not modify or remove the line above.\n"
 "Everything below it will be ignored."
@@ -4641,227 +5002,227 @@ msgstr ""
 "위의 줄을 바꾸거나 지우지 마십시오.\n"
 "아래 있는 내용은 모두 무시됩니다."
 
-#: wt-status.c:1076
+#: wt-status.c:1084
 msgid "You have unmerged paths."
 msgstr "병합하지 않은 경로가 있습니다."
 
-#: wt-status.c:1079
+#: wt-status.c:1087
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (충돌을 바로잡고 \"git commit\"을 실행하십시오)"
 
-#: wt-status.c:1081
+#: wt-status.c:1089
 msgid "  (use \"git merge --abort\" to abort the merge)"
 msgstr "  (병합을 중단하려면 \"git merge --abort\"를 사용하십시오)"
 
-#: wt-status.c:1086
+#: wt-status.c:1094
 msgid "All conflicts fixed but you are still merging."
 msgstr "모든 충돌을 바로잡았지만 아직 병합하는 중입니다."
 
-#: wt-status.c:1089
+#: wt-status.c:1097
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (병합을 마무리하려면 \"git commit\"을 사용하십시오)"
 
-#: wt-status.c:1099
+#: wt-status.c:1107
 msgid "You are in the middle of an am session."
 msgstr "am 세션 중간에 있습니다."
 
-#: wt-status.c:1102
+#: wt-status.c:1110
 msgid "The current patch is empty."
 msgstr "현재 패치가 비어 있습니다."
 
-#: wt-status.c:1106
+#: wt-status.c:1114
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr "  (충돌을 바로잡은 다음 \"git am --continue\"를 사용하십시오)"
 
-#: wt-status.c:1108
+#: wt-status.c:1116
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (이 패치를 건너 뛰려면 \"git am --skip\"을 사용하십시오)"
 
-#: wt-status.c:1110
+#: wt-status.c:1118
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (원본 브랜치를 복구하려면 \"git am --abort\"를 사용하십시오)"
 
-#: wt-status.c:1242
+#: wt-status.c:1250
 msgid "git-rebase-todo is missing."
 msgstr "git-rebase-todo가 없습니다."
 
-#: wt-status.c:1244
+#: wt-status.c:1252
 msgid "No commands done."
 msgstr "완료한 명령 없음."
 
-#: wt-status.c:1247
+#: wt-status.c:1255
 #, c-format
 msgid "Last command done (%d command done):"
 msgid_plural "Last commands done (%d commands done):"
 msgstr[0] "최근 완료한 명령 (%d개 명령 완료):"
 
-#: wt-status.c:1258
+#: wt-status.c:1266
 #, c-format
 msgid "  (see more in file %s)"
 msgstr "  (자세한 정보는 %s 파일 참고)"
 
-#: wt-status.c:1263
+#: wt-status.c:1271
 msgid "No commands remaining."
 msgstr "명령이 남아있지 않음."
 
-#: wt-status.c:1266
+#: wt-status.c:1274
 #, c-format
 msgid "Next command to do (%d remaining command):"
 msgid_plural "Next commands to do (%d remaining commands):"
 msgstr[0] "다음에 할 명령 (%d개 명령 남음):"
 
-#: wt-status.c:1274
+#: wt-status.c:1282
 msgid "  (use \"git rebase --edit-todo\" to view and edit)"
 msgstr "  (보고 편집하려면 \"git rebase --edit-todo\"를 사용하십시오)"
 
-#: wt-status.c:1287
+#: wt-status.c:1295
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "현재 '%s' 브랜치를 '%s' 위로 리베이스하는 중입니다."
 
-#: wt-status.c:1292
+#: wt-status.c:1300
 msgid "You are currently rebasing."
 msgstr "현재 리베이스하는 중입니다."
 
-#: wt-status.c:1306
+#: wt-status.c:1314
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (충돌을 바로잡고 \"git rebase --continue\"를 사용하십시오)"
 
-#: wt-status.c:1308
+#: wt-status.c:1316
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (이 패치를 건너뛰려면 \"git rebase --skip\"을 사용하십시오)"
 
-#: wt-status.c:1310
+#: wt-status.c:1318
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (원본 브랜치를 가져오려면 \"git rebase --abort\"를 사용하십시오)"
 
-#: wt-status.c:1316
+#: wt-status.c:1324
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr ""
 "  (모든 충돌을 바로잡았습니다: \"git rebase --continue\"를 실행하십시오)"
 
-#: wt-status.c:1320
+#: wt-status.c:1328
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
 msgstr "현재 '%s' 브랜치를 '%s' 위로 리베이스하는 중 커밋을 분리하는 중입니다."
 
-#: wt-status.c:1325
+#: wt-status.c:1333
 msgid "You are currently splitting a commit during a rebase."
 msgstr "현재 리베이스하는 중 커밋을 분리하는 중입니다."
 
-#: wt-status.c:1328
+#: wt-status.c:1336
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr "  (작업 폴더가 깨끗해지면, \"git rebase --continue\"를 실행하십시오)"
 
-#: wt-status.c:1332
+#: wt-status.c:1340
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr "'%s' 브랜치를 '%s' 위로 리베이스하는 중 커밋을 편집하는 중입니다."
 
-#: wt-status.c:1337
+#: wt-status.c:1345
 msgid "You are currently editing a commit during a rebase."
 msgstr "리베이스 중에 커밋을 편집하는 중입니다."
 
-#: wt-status.c:1340
+#: wt-status.c:1348
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr "  (현재 커밋을 수정하려면 \"git commit --amend\"을 사용하십시오)"
 
-#: wt-status.c:1342
+#: wt-status.c:1350
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr "  (변경 사항에 만족할 때 \"git rebase --continue\"를 사용하십시오)"
 
-#: wt-status.c:1352
+#: wt-status.c:1360
 #, c-format
 msgid "You are currently cherry-picking commit %s."
 msgstr "현재 %s 커밋을 뽑아 내고 있습니다."
 
-#: wt-status.c:1357
+#: wt-status.c:1365
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr "  (충돌을 바로잡고 \"git cherry-pick --continue\"를 실행하십시오)"
 
-#: wt-status.c:1360
+#: wt-status.c:1368
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr ""
 "  (모든 충돌을 바로잡았습니다: \"git cherry-pick --continue\"를 실행하십시오)"
 
-#: wt-status.c:1362
+#: wt-status.c:1370
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr "  (뽑기 작업을 취소하려면 \"git cherry-pick --abort\"를 사용하십시오)"
 
-#: wt-status.c:1371
+#: wt-status.c:1379
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "현재 %s 커밋을 되돌리는 중입니다."
 
-#: wt-status.c:1376
+#: wt-status.c:1384
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (충돌을 바로잡고 \"git revert --continue\"를 실행하십시오)"
 
-#: wt-status.c:1379
+#: wt-status.c:1387
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr ""
 "  (모든 충돌을 바로잡았습니다: \"git revert --continue\"를 실행하십시오)"
 
-#: wt-status.c:1381
+#: wt-status.c:1389
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr "  (되돌리기 작업을 취소하려면 \"git revert --abort\"를 사용하십시오)"
 
-#: wt-status.c:1392
+#: wt-status.c:1400
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr "'이등분하는 중입니다. '%s' 브랜치부터 시작."
 
-#: wt-status.c:1396
+#: wt-status.c:1404
 msgid "You are currently bisecting."
 msgstr "'이등분하는 중입니다."
 
-#: wt-status.c:1399
+#: wt-status.c:1407
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr "  (원래 브랜치로 돌아가려면 \"git bisect reset\"을 사용하십시오)"
 
-#: wt-status.c:1596
+#: wt-status.c:1604
 msgid "On branch "
 msgstr "현재 브랜치 "
 
-#: wt-status.c:1602
+#: wt-status.c:1610
 msgid "interactive rebase in progress; onto "
 msgstr "대화형 리베이스 진행 중. 갈 위치는 "
 
-#: wt-status.c:1604
+#: wt-status.c:1612
 msgid "rebase in progress; onto "
 msgstr "리베이스 진행 중. 갈 위치는 "
 
-#: wt-status.c:1609
+#: wt-status.c:1617
 msgid "HEAD detached at "
 msgstr "HEAD가 다음 위치에서 분리: "
 
-#: wt-status.c:1611
+#: wt-status.c:1619
 msgid "HEAD detached from "
 msgstr "HEAD가 다음으로부터 분리: "
 
-#: wt-status.c:1614
+#: wt-status.c:1622
 msgid "Not currently on any branch."
 msgstr "현재 어떤 브랜치도 사용하지 않음."
 
-#: wt-status.c:1634
+#: wt-status.c:1642
 msgid "Initial commit"
 msgstr "최초 커밋"
 
-#: wt-status.c:1635
+#: wt-status.c:1643
 msgid "No commits yet"
 msgstr "아직 커밋이 없습니다"
 
-#: wt-status.c:1649
+#: wt-status.c:1657
 msgid "Untracked files"
 msgstr "추적하지 않는 파일"
 
-#: wt-status.c:1651
+#: wt-status.c:1659
 msgid "Ignored files"
 msgstr "무시한 파일"
 
-#: wt-status.c:1655
+#: wt-status.c:1663
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -4872,20 +5233,20 @@ msgstr ""
 "'status -uno' 옵션을 쓰면 빨라질 수도 있지만, 새 파일을\n"
 "직접 찾아서 추가해야 합니다. ('git help status' 참고)"
 
-#: wt-status.c:1661
+#: wt-status.c:1669
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "추적하지 않는 파일을 보지 않습니다%s"
 
-#: wt-status.c:1663
+#: wt-status.c:1671
 msgid " (use -u option to show untracked files)"
 msgstr " (추적하지 않는 파일을 보려면 -u 옵션을 사용하십시오)"
 
-#: wt-status.c:1669
+#: wt-status.c:1677
 msgid "No changes"
 msgstr "변경 사항 없음"
 
-#: wt-status.c:1674
+#: wt-status.c:1682
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
@@ -4893,12 +5254,12 @@ msgstr ""
 "\"를\n"
 "사용하십시오)\n"
 
-#: wt-status.c:1677
+#: wt-status.c:1685
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "커밋할 변경 사항을 추가하지 않았습니다\n"
 
-#: wt-status.c:1680
+#: wt-status.c:1688
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
@@ -4908,70 +5269,70 @@ msgstr ""
 "\"git\n"
 "add\"를 사용하십시오)\n"
 
-#: wt-status.c:1683
+#: wt-status.c:1691
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr "커밋할 사항을 추가하지 않았지만 추적하지 않는 파일이 있습니다\n"
 
-#: wt-status.c:1686
+#: wt-status.c:1694
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
 "커밋할 사항 없음 (파일을 만들거나 복사하고 \"git add\"를 사용하면 추적합니"
 "다)\n"
 
-#: wt-status.c:1689 wt-status.c:1694
+#: wt-status.c:1697 wt-status.c:1702
 #, c-format
 msgid "nothing to commit\n"
 msgstr "커밋할 사항 없음\n"
 
-#: wt-status.c:1692
+#: wt-status.c:1700
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr ""
 "커밋할 사항 없음 (추적하지 않는 파일을 보려면 -u 옵션을 사용하십시오)\n"
 
-#: wt-status.c:1696
+#: wt-status.c:1704
 #, c-format
 msgid "nothing to commit, working tree clean\n"
 msgstr "커밋할 사항 없음, 작업 폴더 깨끗함\n"
 
-#: wt-status.c:1809
+#: wt-status.c:1817
 msgid "No commits yet on "
 msgstr "아직 커밋이 없습니다, 위치: <"
 
-#: wt-status.c:1813
+#: wt-status.c:1821
 msgid "HEAD (no branch)"
 msgstr "HEAD (브랜치 없음)"
 
-#: wt-status.c:1844
+#: wt-status.c:1852
 msgid "different"
 msgstr "다름"
 
-#: wt-status.c:1846 wt-status.c:1854
+#: wt-status.c:1854 wt-status.c:1862
 msgid "behind "
 msgstr "다음 뒤에: "
 
-#: wt-status.c:1849 wt-status.c:1852
+#: wt-status.c:1857 wt-status.c:1860
 msgid "ahead "
 msgstr "다음 앞에: "
 
 #. TRANSLATORS: the action is e.g. "pull with rebase"
-#: wt-status.c:2358
+#: wt-status.c:2366
 #, c-format
 msgid "cannot %s: You have unstaged changes."
 msgstr "%s 할 수 없습니다: 스테이징하지 않은 변경 사항이 있습니다."
 
-#: wt-status.c:2364
+#: wt-status.c:2372
 msgid "additionally, your index contains uncommitted changes."
 msgstr "추가로, 인덱스에 커밋하지 않은 변경 사항이 있습니다."
 
-#: wt-status.c:2366
+#: wt-status.c:2374
 #, c-format
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "%s 할 수 없습니다: 인덱스에 커밋하지 않은 변경 사항이 있습니다."
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:440
+#: compat/precompose_utf8.c:58 builtin/clone.c:442
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr "'%s' 파일 삭제에 실패했습니다"
@@ -4985,7 +5346,7 @@ msgstr "git add [<옵션>] [--] <경로명세>..."
 msgid "unexpected diff status %c"
 msgstr "예상치 못한 diff 상태 %c"
 
-#: builtin/add.c:88 builtin/commit.c:257
+#: builtin/add.c:88 builtin/commit.c:266
 msgid "updating files failed"
 msgstr "파일 업데이트가 실패했습니다"
 
@@ -4998,7 +5359,7 @@ msgstr "'%s' 제거\n"
 msgid "Unstaged changes after refreshing the index:"
 msgstr "인덱스를 새로 고친 다음 커밋 표시하지 않은 변경 사항:"
 
-#: builtin/add.c:233 builtin/rev-parse.c:888
+#: builtin/add.c:233 builtin/rev-parse.c:892
 msgid "Could not read the index"
 msgstr "인덱스를 읽을 수 없습니다"
 
@@ -5029,77 +5390,77 @@ msgstr "빈 패치. 중지."
 msgid "Could not apply '%s'"
 msgstr "'%s'을(를) 적용할 수 없습니다"
 
-#: builtin/add.c:271
+#: builtin/add.c:269
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr "다음 경로는 .gitignore 파일 중 하나 때문에 무시합니다:\n"
 
-#: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:146 builtin/mv.c:124
-#: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541
-#: builtin/remote.c:1333 builtin/rm.c:242 builtin/send-pack.c:164
+#: builtin/add.c:289 builtin/clean.c:911 builtin/fetch.c:145 builtin/mv.c:123
+#: builtin/prune-packed.c:55 builtin/pull.c:212 builtin/push.c:557
+#: builtin/remote.c:1342 builtin/rm.c:240 builtin/send-pack.c:165
 msgid "dry run"
 msgstr "가짜로 실행"
 
-#: builtin/add.c:294
+#: builtin/add.c:292
 msgid "interactive picking"
 msgstr "대화식으로 고릅니다"
 
-#: builtin/add.c:295 builtin/checkout.c:1128 builtin/reset.c:302
+#: builtin/add.c:293 builtin/checkout.c:1135 builtin/reset.c:302
 msgid "select hunks interactively"
 msgstr "대화식으로 변경된 부분을 선택합니다"
 
-#: builtin/add.c:296
+#: builtin/add.c:294
 msgid "edit current diff and apply"
 msgstr "현재 diff를 편집하고 적용합니다"
 
-#: builtin/add.c:297
+#: builtin/add.c:295
 msgid "allow adding otherwise ignored files"
 msgstr "무시하는 파일의 추가를 허용합니다"
 
-#: builtin/add.c:298
+#: builtin/add.c:296
 msgid "update tracked files"
 msgstr "추적되는 파일을 업데이트합니다"
 
-#: builtin/add.c:299
+#: builtin/add.c:297
 msgid "renormalize EOL of tracked files (implies -u)"
 msgstr "추적된 파일의 새줄문자(EOL)를 재 적용합니다 (-u 옵션 포함)"
 
-#: builtin/add.c:300
+#: builtin/add.c:298
 msgid "record only the fact that the path will be added later"
 msgstr "나중에 추가할 것이라는 사실만 기록합니다"
 
-#: builtin/add.c:301
+#: builtin/add.c:299
 msgid "add changes from all tracked and untracked files"
 msgstr "추적되고 추적되지 않는 모든 파일의 변경 사항을 추가합니다"
 
-#: builtin/add.c:304
+#: builtin/add.c:302
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr "작업 폴더에서 제거한 경로를 무시합니다 (--no-all과 동일)"
 
-#: builtin/add.c:306
+#: builtin/add.c:304
 msgid "don't add, only refresh the index"
 msgstr "추가하지 않고 인덱스만 새로 고칩니다"
 
-#: builtin/add.c:307
+#: builtin/add.c:305
 msgid "just skip files which cannot be added because of errors"
 msgstr "오류 때문에 추가할 수 없는 파일을 건너뜁니다"
 
-#: builtin/add.c:308
+#: builtin/add.c:306
 msgid "check if - even missing - files are ignored in dry run"
 msgstr "가짜로 실행했을 때 파일을 무시하는지 확인합니다"
 
-#: builtin/add.c:309 builtin/update-index.c:964
+#: builtin/add.c:307 builtin/update-index.c:974
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/add.c:309 builtin/update-index.c:965
+#: builtin/add.c:307 builtin/update-index.c:975
 msgid "override the executable bit of the listed files"
 msgstr "목록의 파일에서 실행 가능 비트를 바꿉니다"
 
-#: builtin/add.c:311
+#: builtin/add.c:309
 msgid "warn when adding an embedded repository"
 msgstr "내장 저장소를 추가할 때 경고를 표시합니다"
 
-#: builtin/add.c:326
+#: builtin/add.c:324
 #, c-format
 msgid ""
 "You've added another git repository inside your current repository.\n"
@@ -5129,48 +5490,48 @@ msgstr ""
 "\n"
 "더 자세한 정보는 \"git help submodule\"을 참고하십시오."
 
-#: builtin/add.c:354
+#: builtin/add.c:352
 #, c-format
 msgid "adding embedded git repository: %s"
 msgstr "내장 깃 저장소 추가: %s"
 
-#: builtin/add.c:372
+#: builtin/add.c:370
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "정말로 추가하려면 -f 옵션을 사용하십시오.\n"
 
-#: builtin/add.c:380
+#: builtin/add.c:378
 msgid "adding files failed"
 msgstr "파일 추가가 실패했습니다"
 
-#: builtin/add.c:417
+#: builtin/add.c:416
 msgid "-A and -u are mutually incompatible"
 msgstr "-A 및 -u 옵션은 서로 호환되지 않습니다"
 
-#: builtin/add.c:424
+#: builtin/add.c:423
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr ""
 "--ignore-missing 옵션은 --dry-run 옵션과 같이 사용할 경우에만 쓸 수 있습니다."
 
-#: builtin/add.c:428
+#: builtin/add.c:427
 #, c-format
 msgid "--chmod param '%s' must be either -x or +x"
 msgstr "--chmod 파라미터 '%s'은(는) -x 또는 +x 형식이어야 합니다"
 
-#: builtin/add.c:443
+#: builtin/add.c:442
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "아무 것도 지정하지 않았으므로 아무 것도 추가하지 않습니다.\n"
 
-#: builtin/add.c:444
+#: builtin/add.c:443
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "'git add .' 명령을 실행하려고 한 것 아니었습니까?\n"
 
-#: builtin/add.c:449 builtin/check-ignore.c:177 builtin/checkout.c:280
-#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316
+#: builtin/add.c:448 builtin/check-ignore.c:177 builtin/checkout.c:280
+#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:325
 #: builtin/diff-tree.c:114 builtin/mv.c:144 builtin/reset.c:241
-#: builtin/rm.c:271 builtin/submodule--helper.c:326
+#: builtin/rm.c:270 builtin/submodule--helper.c:328
 msgid "index file corrupt"
 msgstr "인덱스 파일이 손상되었습니다"
 
@@ -5222,7 +5583,7 @@ msgstr "시간대 오프셋이 잘못되었습니다"
 msgid "Patch format detection failed."
 msgstr "패치 형식 검색이 실패했습니다."
 
-#: builtin/am.c:1013 builtin/clone.c:405
+#: builtin/am.c:1013 builtin/clone.c:407
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "'%s' 디렉터리 만들기가 실패했습니다"
@@ -5231,7 +5592,7 @@ msgstr "'%s' 디렉터리 만들기가 실패했습니다"
 msgid "Failed to split patches."
 msgstr "패치를 쪼개는데 실패했습니다."
 
-#: builtin/am.c:1148 builtin/commit.c:342
+#: builtin/am.c:1148 builtin/commit.c:351
 msgid "unable to write index file"
 msgstr "인덱스 파일을 쓸 수 없습니다"
 
@@ -5403,7 +5764,7 @@ msgid "allow fall back on 3way merging if needed"
 msgstr "필요하면 3-방향 병합으로 대신하도록 허용합니다"
 
 #: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57
-#: builtin/repack.c:182
+#: builtin/repack.c:192
 msgid "be quiet"
 msgstr "간략히 표시합니다"
 
@@ -5446,16 +5807,17 @@ msgstr "절취선 앞의 모든 사항을 무시합니다"
 msgid "pass it through git-apply"
 msgstr "git-apply에 넘깁니다"
 
-#: builtin/am.c:2260 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668
-#: builtin/grep.c:853 builtin/merge.c:206 builtin/pull.c:145 builtin/pull.c:203
-#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197
-#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:382
-#: parse-options.h:144 parse-options.h:146 parse-options.h:257
+#: builtin/am.c:2260 builtin/commit.c:1332 builtin/fmt-merge-msg.c:665
+#: builtin/fmt-merge-msg.c:668 builtin/grep.c:853 builtin/merge.c:208
+#: builtin/pull.c:150 builtin/pull.c:208 builtin/repack.c:201
+#: builtin/repack.c:205 builtin/repack.c:207 builtin/show-branch.c:631
+#: builtin/show-ref.c:169 builtin/tag.c:383 parse-options.h:144
+#: parse-options.h:146 parse-options.h:258
 msgid "n"
 msgstr "n"
 
-#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38
-#: builtin/replace.c:445 builtin/tag.c:418 builtin/verify-tag.c:39
+#: builtin/am.c:2266 builtin/branch.c:632 builtin/for-each-ref.c:38
+#: builtin/replace.c:543 builtin/tag.c:419 builtin/verify-tag.c:39
 msgid "format"
 msgstr "형식"
 
@@ -5501,8 +5863,8 @@ msgstr "커미터 시각을 작성자 시각으로 넣습니다"
 msgid "use current timestamp for author date"
 msgstr "현재 시각을 작성자 시각으로 사용합니다"
 
-#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237
-#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:398
+#: builtin/am.c:2298 builtin/commit.c:1468 builtin/merge.c:239
+#: builtin/pull.c:183 builtin/revert.c:112 builtin/tag.c:399
 msgid "key-id"
 msgstr "키-ID"
 
@@ -5641,115 +6003,141 @@ msgstr "--write-terms 옵션은 두 인자가 필요합니다"
 msgid "--bisect-clean-state requires no arguments"
 msgstr "--bisect-clean-state 옵션은 인자가 필요하지 않습니다"
 
-#: builtin/blame.c:27
+#: builtin/blame.c:29
 msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
 msgstr "git blame [<옵션>] [<리비전-옵션>] [<리비전>] [--] <파일>"
 
-#: builtin/blame.c:32
+#: builtin/blame.c:34
 msgid "<rev-opts> are documented in git-rev-list(1)"
 msgstr "<리비전-옵션>은 git-rev-list(1)에 설명되어 있습니다"
 
-#: builtin/blame.c:677
+#: builtin/blame.c:404
+#, c-format
+msgid "expecting a color: %s"
+msgstr "색을 예상합니다: %s"
+
+#: builtin/blame.c:411
+msgid "must end with a color"
+msgstr "색으로 끝나야 합니다"
+
+#: builtin/blame.c:697
+#, c-format
+msgid "invalid color '%s' in color.blame.repeatedLines"
+msgstr "color.blame.repeatedLines에 잘못된 색을 ('%s') 무시합니다"
+
+#: builtin/blame.c:715
+msgid "invalid value for blame.coloring"
+msgstr "blame.coloring의 값이 올바르지 않습니다"
+
+#: builtin/blame.c:786
 msgid "Show blame entries as we find them, incrementally"
 msgstr "블레임 항목을 찾자마자 점진적으로 표시합니다"
 
-#: builtin/blame.c:678
+#: builtin/blame.c:787
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr "가장자리 커밋에 대해 빈 SHA-1을 표시합니다 (기본값: 꺼짐)"
 
-#: builtin/blame.c:679
+#: builtin/blame.c:788
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr "최상위 커밋을 가장자리 커밋으로 취급하지 않습니다 (기본값: 꺼짐)"
 
-#: builtin/blame.c:680
+#: builtin/blame.c:789
 msgid "Show work cost statistics"
 msgstr "작업 비용 통계를 표시합니다"
 
-#: builtin/blame.c:681
+#: builtin/blame.c:790
 msgid "Force progress reporting"
 msgstr "강제로 진행 상황을 표시합니다"
 
-#: builtin/blame.c:682
+#: builtin/blame.c:791
 msgid "Show output score for blame entries"
 msgstr "블레임 항목에 대해 출력 점수를 표시합니다"
 
-#: builtin/blame.c:683
+#: builtin/blame.c:792
 msgid "Show original filename (Default: auto)"
 msgstr "원래 파일 이름 표시 (기본값: 자동)"
 
-#: builtin/blame.c:684
+#: builtin/blame.c:793
 msgid "Show original linenumber (Default: off)"
 msgstr "원래 줄 번호 표시 (기본값: 하지 않음)"
 
-#: builtin/blame.c:685
+#: builtin/blame.c:794
 msgid "Show in a format designed for machine consumption"
 msgstr "컴퓨터 처리용으로 설계된 형식으로 표시합니다"
 
-#: builtin/blame.c:686
+#: builtin/blame.c:795
 msgid "Show porcelain format with per-line commit information"
 msgstr "줄마다 커밋 정보가 표시되는 사용자용 형식으로 표시합니다"
 
-#: builtin/blame.c:687
+#: builtin/blame.c:796
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr "git-annotate와 동일한 형식을 사용합니다 (기본값: 꺼짐)"
 
-#: builtin/blame.c:688
+#: builtin/blame.c:797
 msgid "Show raw timestamp (Default: off)"
 msgstr "내부 형식으로 시각을 표시합니다 (기본값: 꺼짐)"
 
-#: builtin/blame.c:689
+#: builtin/blame.c:798
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "길게 커밋 SHA1을 표시합니다 (기본값: 꺼짐)"
 
-#: builtin/blame.c:690
+#: builtin/blame.c:799
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "작성자 이름과 시각을 표시하지 않습니다 (기본값: 꺼짐)"
 
-#: builtin/blame.c:691
+#: builtin/blame.c:800
 msgid "Show author email instead of name (Default: off)"
 msgstr "작성자 이름 대신에 전자메일을 표시합니다 (기본값: 꺼짐)"
 
-#: builtin/blame.c:692
+#: builtin/blame.c:801
 msgid "Ignore whitespace differences"
 msgstr "공백 문자 차이점을 무시합니다"
 
-#: builtin/blame.c:699
+#: builtin/blame.c:802
+msgid "color redundant metadata from previous line differently"
+msgstr "불필요한 메타데이터를 앞의 줄과 다르게 색을 칠합니다"
+
+#: builtin/blame.c:803
+msgid "color lines by age"
+msgstr "줄이 얼마나 오래 됐느냐에 따라 다르게 색을 칠합니다"
+
+#: builtin/blame.c:810
 msgid "Use an experimental heuristic to improve diffs"
 msgstr "diff를 향상하는데 실험적인 휴리스틱을 사용합니다"
 
-#: builtin/blame.c:701
+#: builtin/blame.c:812
 msgid "Spend extra cycles to find better match"
 msgstr "더 일치하는 항목을 찾는데 더 시간을 소모합니다"
 
-#: builtin/blame.c:702
+#: builtin/blame.c:813
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr "git-rev-list를 호출하는 대신 <파일>에서 리비전을 사용합니다"
 
-#: builtin/blame.c:703
+#: builtin/blame.c:814
 msgid "Use <file>'s contents as the final image"
 msgstr "<파일>의 내용을 최종 이미지로 사용합니다"
 
-#: builtin/blame.c:704 builtin/blame.c:705
+#: builtin/blame.c:815 builtin/blame.c:816
 msgid "score"
 msgstr "점수"
 
-#: builtin/blame.c:704
+#: builtin/blame.c:815
 msgid "Find line copies within and across files"
 msgstr "파일 내부와 파일 사이의 복사된 줄을 찾습니다"
 
-#: builtin/blame.c:705
+#: builtin/blame.c:816
 msgid "Find line movements within and across files"
 msgstr "파일 내부와 파일 사이의 옮겨진 줄을 찾습니다"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "Process only line range n,m, counting from 1"
 msgstr "n,m줄 (1번 줄부터 시작) 사이의 범위만 처리"
 
-#: builtin/blame.c:753
+#: builtin/blame.c:866
 msgid "--progress can't be used with --incremental or porcelain formats"
 msgstr ""
 "--progress 옵션은 --incremental 옵션이나 포스레인 형식에서 사용할 수 없습니다"
@@ -5762,17 +6150,17 @@ msgstr ""
 #. your language may need more or fewer display
 #. columns.
 #.
-#: builtin/blame.c:804
+#: builtin/blame.c:917
 msgid "4 years, 11 months ago"
 msgstr "4년 11달 전"
 
-#: builtin/blame.c:890
+#: builtin/blame.c:1003
 #, c-format
 msgid "file %s has only %lu line"
 msgid_plural "file %s has only %lu lines"
 msgstr[0] "%s 파일에는 줄이 %lu개 뿐입니다"
 
-#: builtin/blame.c:936
+#: builtin/blame.c:1049
 msgid "Blaming lines"
 msgstr "블레임 줄"
 
@@ -5883,65 +6271,65 @@ msgstr "리모트 추적 '%s' 브랜치를 삭제합니다. (과거 %s)\n"
 msgid "Deleted branch %s (was %s).\n"
 msgstr "%s 브랜치 삭제 (과거 %s).\n"
 
-#: builtin/branch.c:417 builtin/tag.c:58
+#: builtin/branch.c:416 builtin/tag.c:58
 msgid "unable to parse format string"
 msgstr "포맷 문자열을 파싱할 수 없습니다"
 
-#: builtin/branch.c:450
+#: builtin/branch.c:453
 #, c-format
 msgid "Branch %s is being rebased at %s"
 msgstr "%s 브랜치를 %s 위치에 리베이스합니다"
 
-#: builtin/branch.c:454
+#: builtin/branch.c:457
 #, c-format
 msgid "Branch %s is being bisected at %s"
 msgstr "%s 브랜치를 %s 위치에서 bisect합니다"
 
-#: builtin/branch.c:471
+#: builtin/branch.c:474
 msgid "cannot copy the current branch while not on any."
 msgstr "브랜치 위에 없으면서 현재 브랜치를 복사할 수 없습니다."
 
-#: builtin/branch.c:473
+#: builtin/branch.c:476
 msgid "cannot rename the current branch while not on any."
 msgstr "브랜치 위에 없으면서 현재 브랜치 이름을 바꿀 수 없습니다."
 
-#: builtin/branch.c:484
+#: builtin/branch.c:487
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "잘못된 브랜치 이름: '%s'"
 
-#: builtin/branch.c:511
+#: builtin/branch.c:514
 msgid "Branch rename failed"
 msgstr "브랜치 이름 바꾸기 실패"
 
-#: builtin/branch.c:513
+#: builtin/branch.c:516
 msgid "Branch copy failed"
 msgstr "브랜치 복사 실패"
 
-#: builtin/branch.c:517
+#: builtin/branch.c:520
 #, c-format
 msgid "Created a copy of a misnamed branch '%s'"
 msgstr "이름이 잘못된 '%s' 브랜치의 복사본을 만들었습니다"
 
-#: builtin/branch.c:520
+#: builtin/branch.c:523
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "이름이 잘못된 '%s' 브랜치의 이름을 다르게 바꿉니다"
 
-#: builtin/branch.c:526
+#: builtin/branch.c:529
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "브랜치 이름을 %s(으)로 바꾸지만, HEAD를 업데이트하지 않습니다!"
 
-#: builtin/branch.c:535
+#: builtin/branch.c:538
 msgid "Branch is renamed, but update of config-file failed"
 msgstr "브랜치의 이름을 바꾸지만, config-file 업데이트가 실패했습니다"
 
-#: builtin/branch.c:537
+#: builtin/branch.c:540
 msgid "Branch is copied, but update of config-file failed"
 msgstr "브랜치를 복사했지만, config-file 업데이트가 실패했습니다"
 
-#: builtin/branch.c:553
+#: builtin/branch.c:556
 #, c-format
 msgid ""
 "Please edit the description for the branch\n"
@@ -5952,185 +6340,187 @@ msgstr ""
 "  %s\n"
 "'%c' 문자로 시작하는 줄은 무시됩니다.\n"
 
-#: builtin/branch.c:586
+#: builtin/branch.c:589
 msgid "Generic options"
 msgstr "일반 옵션"
 
 # FIXME: give twice?
-#: builtin/branch.c:588
+#: builtin/branch.c:591
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "해시와 제목을 표시하고, 업스트림 브랜치에 대한 위치를 표시합니다"
 
-#: builtin/branch.c:589
+#: builtin/branch.c:592
 msgid "suppress informational messages"
 msgstr "여러가지 안내 메시지를 표시하지 않습니다"
 
-#: builtin/branch.c:590
+#: builtin/branch.c:593
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "추적 모드를 설정합니다 (git-pull(1) 참고)"
 
-#: builtin/branch.c:592
+#: builtin/branch.c:595
 msgid "do not use"
 msgstr "사용하지 않습니다"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "upstream"
 msgstr "업스트림"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "change the upstream info"
 msgstr "업스트림 정보를 바꿉니다"
 
-#: builtin/branch.c:595
+#: builtin/branch.c:598
 msgid "Unset the upstream info"
 msgstr "업스트림 정보를 해제합니다"
 
-#: builtin/branch.c:596
+#: builtin/branch.c:599
 msgid "use colored output"
 msgstr "여러 색으로 출력합니다"
 
-#: builtin/branch.c:597
+#: builtin/branch.c:600
 msgid "act on remote-tracking branches"
 msgstr "리모트 추적 브랜치에 대해 동작합니다"
 
-#: builtin/branch.c:599 builtin/branch.c:601
+#: builtin/branch.c:602 builtin/branch.c:604
 msgid "print only branches that contain the commit"
 msgstr "커밋이 있는 브랜치만 표시합니다"
 
-#: builtin/branch.c:600 builtin/branch.c:602
+#: builtin/branch.c:603 builtin/branch.c:605
 msgid "print only branches that don't contain the commit"
 msgstr "커밋이 들어있지 않은 브랜치만 표시합니다"
 
-#: builtin/branch.c:605
+#: builtin/branch.c:608
 msgid "Specific git-branch actions:"
 msgstr "특정 git-branch 동작:"
 
-#: builtin/branch.c:606
+#: builtin/branch.c:609
 msgid "list both remote-tracking and local branches"
 msgstr "리모트와 로컬의 브랜치 목록을 모두 표시합니다"
 
-#: builtin/branch.c:608
+#: builtin/branch.c:611
 msgid "delete fully merged branch"
 msgstr "완전히 병합된 브랜치를 삭제합니다"
 
-#: builtin/branch.c:609
+#: builtin/branch.c:612
 msgid "delete branch (even if not merged)"
 msgstr "브랜치를 삭제합니다 (병합되지 않았더라도)"
 
-#: builtin/branch.c:610
+#: builtin/branch.c:613
 msgid "move/rename a branch and its reflog"
 msgstr "브랜치와 그 reflog를 옮기거나 이름을 바꿉니다"
 
-#: builtin/branch.c:611
+#: builtin/branch.c:614
 msgid "move/rename a branch, even if target exists"
 msgstr "대상이 이미 있더라도 브랜치를 옮기거나 이름을 바꿉니다"
 
-#: builtin/branch.c:612
+#: builtin/branch.c:615
 msgid "copy a branch and its reflog"
 msgstr "브랜치와 그 reflog를 복사합니다"
 
-#: builtin/branch.c:613
+#: builtin/branch.c:616
 msgid "copy a branch, even if target exists"
 msgstr "대상이 이미 있더라도 브랜치를 복사합니다"
 
-#: builtin/branch.c:614
+#: builtin/branch.c:617
 msgid "list branch names"
 msgstr "브랜치 이름 목록을 표시합니다"
 
-#: builtin/branch.c:615
+#: builtin/branch.c:618
 msgid "create the branch's reflog"
 msgstr "브랜치의 reflog를 만듭니다"
 
-#: builtin/branch.c:617
+#: builtin/branch.c:620
 msgid "edit the description for the branch"
 msgstr "브랜치의 설명을 편집합니다"
 
-#: builtin/branch.c:618
+#: builtin/branch.c:621
 msgid "force creation, move/rename, deletion"
 msgstr "강제로 만들고, 옮기거나 이름을 바꾸고, 삭제합니다"
 
-#: builtin/branch.c:619
+#: builtin/branch.c:622
 msgid "print only branches that are merged"
 msgstr "병합되는 브랜치만 표시합니다"
 
-#: builtin/branch.c:620
+#: builtin/branch.c:623
 msgid "print only branches that are not merged"
 msgstr "병합되지 않는 브랜치만 표시합니다"
 
-#: builtin/branch.c:621
+#: builtin/branch.c:624
 msgid "list branches in columns"
 msgstr "목록을 여러 열로 표시합니다"
 
-#: builtin/branch.c:622 builtin/for-each-ref.c:40 builtin/tag.c:411
+#: builtin/branch.c:625 builtin/for-each-ref.c:40 builtin/ls-remote.c:70
+#: builtin/tag.c:412
 msgid "key"
 msgstr "키"
 
-#: builtin/branch.c:623 builtin/for-each-ref.c:41 builtin/tag.c:412
+#: builtin/branch.c:626 builtin/for-each-ref.c:41 builtin/ls-remote.c:71
+#: builtin/tag.c:413
 msgid "field name to sort on"
 msgstr "정렬한 기준이 되는 필드 이름"
 
-#: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408
+#: builtin/branch.c:628 builtin/for-each-ref.c:43 builtin/notes.c:408
 #: builtin/notes.c:411 builtin/notes.c:571 builtin/notes.c:574
-#: builtin/tag.c:414
+#: builtin/tag.c:415
 msgid "object"
 msgstr "오브젝트"
 
-#: builtin/branch.c:626
+#: builtin/branch.c:629
 msgid "print only branches of the object"
 msgstr "해당 오브젝트의 브랜치만 표시합니다"
 
-#: builtin/branch.c:628 builtin/for-each-ref.c:49 builtin/tag.c:421
+#: builtin/branch.c:631 builtin/for-each-ref.c:49 builtin/tag.c:422
 msgid "sorting and filtering are case insensitive"
 msgstr "정렬과 필터링은 대소문자를 구분하지 않습니다"
 
-#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419
+#: builtin/branch.c:632 builtin/for-each-ref.c:38 builtin/tag.c:420
 #: builtin/verify-tag.c:39
 msgid "format to use for the output"
 msgstr "출력에 사용할 형식"
 
-#: builtin/branch.c:652 builtin/clone.c:735
+#: builtin/branch.c:655 builtin/clone.c:737
 msgid "HEAD not found below refs/heads!"
 msgstr "레퍼런스/헤드 아래에 HEAD가 없습니다!"
 
-#: builtin/branch.c:675
+#: builtin/branch.c:678
 msgid "--column and --verbose are incompatible"
 msgstr "--column 및 --verbose 옵션은 호환되지 않습니다"
 
-#: builtin/branch.c:690 builtin/branch.c:742 builtin/branch.c:751
+#: builtin/branch.c:693 builtin/branch.c:745 builtin/branch.c:754
 msgid "branch name required"
 msgstr "브랜치 이름이 필요합니다"
 
-#: builtin/branch.c:718
+#: builtin/branch.c:721
 msgid "Cannot give description to detached HEAD"
 msgstr "분리된 HEAD에 대한 설명을 부여할 수 없습니다"
 
-#: builtin/branch.c:723
+#: builtin/branch.c:726
 msgid "cannot edit description of more than one branch"
 msgstr "여러 브랜치에 대한 설명을 편집할 수 없습니다"
 
-#: builtin/branch.c:730
+#: builtin/branch.c:733
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "아직 '%s' 브랜치에 커밋이 없습니다."
 
-#: builtin/branch.c:733
+#: builtin/branch.c:736
 #, c-format
 msgid "No branch named '%s'."
 msgstr "이름이 '%s'인 브랜치가 없습니다."
 
-#: builtin/branch.c:748
+#: builtin/branch.c:751
 msgid "too many branches for a copy operation"
 msgstr "복사 작업에 대해 브랜치가 너무 많습니다"
 
-#: builtin/branch.c:757
+#: builtin/branch.c:760
 msgid "too many arguments for a rename operation"
 msgstr "이름 바꾸기 작업에 대해 인자가 너무 많습니다"
 
-#: builtin/branch.c:762
+#: builtin/branch.c:765
 msgid "too many arguments to set new upstream"
 msgstr "새 업스트림을 설정하는데 인자가 너무 많습니다"
 
-#: builtin/branch.c:766
+#: builtin/branch.c:769
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
@@ -6138,37 +6528,37 @@ msgstr ""
 "HEAD의 업스트림을 %s(으)로 설정할 수 없습니다. 어떤 브랜치도 가리키지 않습니"
 "다."
 
-#: builtin/branch.c:769 builtin/branch.c:791 builtin/branch.c:807
+#: builtin/branch.c:772 builtin/branch.c:794 builtin/branch.c:810
 #, c-format
 msgid "no such branch '%s'"
 msgstr "그런 브랜치가 ('%s') 없습니다"
 
-#: builtin/branch.c:773
+#: builtin/branch.c:776
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "'%s' 브랜치가 없습니다"
 
-#: builtin/branch.c:785
+#: builtin/branch.c:788
 msgid "too many arguments to unset upstream"
 msgstr "업스트림 설정을 해제하는데 인자가 너무 많습니다"
 
-#: builtin/branch.c:789
+#: builtin/branch.c:792
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
 "HEAD의 업스트림 설정을 해제할 수 없습니다. 어떤 브랜치도 가리키지 않습니다."
 
-#: builtin/branch.c:795
+#: builtin/branch.c:798
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "'%s' 브랜치에 업스트림 정보가 없습니다"
 
-#: builtin/branch.c:810
+#: builtin/branch.c:813
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr ""
 "'git branch'에 대해 -a 및 -r 옵션은 브랜치 이름과 같이 쓰면 앞뒤가 맞지 않습"
 "니다"
 
-#: builtin/branch.c:813
+#: builtin/branch.c:816
 msgid ""
 "the '--set-upstream' option is no longer supported. Please use '--track' or "
 "'--set-upstream-to' instead."
@@ -6189,7 +6579,7 @@ msgstr "번들을 만드려면 저장소가 필요합니다."
 msgid "Need a repository to unbundle."
 msgstr "번들을 해제하려면 저장소가 필요합니다."
 
-#: builtin/cat-file.c:523
+#: builtin/cat-file.c:525
 msgid ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <type> | --textconv | --filters) [--path=<path>] <object>"
@@ -6197,7 +6587,7 @@ msgstr ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <종류> | --textconv | --filters) [--path=<경로>] <오브젝트>"
 
-#: builtin/cat-file.c:524
+#: builtin/cat-file.c:526
 msgid ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
@@ -6205,64 +6595,64 @@ msgstr ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
 
-#: builtin/cat-file.c:561
+#: builtin/cat-file.c:563
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<종류>는 다음 중 하나가 될 수 있습니다: blob, tree, commit, tag"
 
-#: builtin/cat-file.c:562
+#: builtin/cat-file.c:564
 msgid "show object type"
 msgstr "오브젝트 종류를 봅니다"
 
-#: builtin/cat-file.c:563
+#: builtin/cat-file.c:565
 msgid "show object size"
 msgstr "오브젝트 크기를 봅니다"
 
-#: builtin/cat-file.c:565
+#: builtin/cat-file.c:567
 msgid "exit with zero when there's no error"
 msgstr "오류가 없을 때 0을 리턴하고 끝냅니다"
 
-#: builtin/cat-file.c:566
+#: builtin/cat-file.c:568
 msgid "pretty-print object's content"
 msgstr "오브젝트의 내용을 예쁘게 표시합니다"
 
-#: builtin/cat-file.c:568
+#: builtin/cat-file.c:570
 msgid "for blob objects, run textconv on object's content"
 msgstr "블롭 오브젝트에 대해서는, 오브젝트의 내용에 대해 textconv를 실행합니다"
 
-#: builtin/cat-file.c:570
+#: builtin/cat-file.c:572
 msgid "for blob objects, run filters on object's content"
 msgstr "블롭 오브젝트에 대해서는, 오브젝트의 내용에 대해 필터를 실행합니다"
 
-#: builtin/cat-file.c:571 git-submodule.sh:878
+#: builtin/cat-file.c:573 git-submodule.sh:894
 msgid "blob"
 msgstr "블롭"
 
-#: builtin/cat-file.c:572
+#: builtin/cat-file.c:574
 msgid "use a specific path for --textconv/--filters"
 msgstr "--textconv/--filters 옵션에 경로를 지정합니다"
 
-#: builtin/cat-file.c:574
+#: builtin/cat-file.c:576
 msgid "allow -s and -t to work with broken/corrupt objects"
 msgstr "-s 및 -t 옵션이 손상된 오브젝트에 대해 동작하도록 허용합니다"
 
-#: builtin/cat-file.c:575
+#: builtin/cat-file.c:577
 msgid "buffer --batch output"
 msgstr "--batch 출력에 대해 버퍼링합니다"
 
-#: builtin/cat-file.c:577
+#: builtin/cat-file.c:579
 msgid "show info and content of objects fed from the standard input"
 msgstr "표준 입력에서 입력된 오브젝트의 정보와 내용을 표시합니다"
 
-#: builtin/cat-file.c:580
+#: builtin/cat-file.c:582
 msgid "show info about objects fed from the standard input"
 msgstr "표준 입력에서 입력된 오브젝트의 정보를 표시합니다"
 
-#: builtin/cat-file.c:583
+#: builtin/cat-file.c:585
 msgid "follow in-tree symlinks (used with --batch or --batch-check)"
 msgstr ""
 "트리 내부의 심볼릭 링크를 따라갑니다 (--batch 또는 --batch-check와 같이 사용)"
 
-#: builtin/cat-file.c:585
+#: builtin/cat-file.c:587
 msgid "show all objects with --batch or --batch-check"
 msgstr "--batch 또는 --batch-check에서 모든 오브젝트를 표시합니다"
 
@@ -6290,7 +6680,7 @@ msgstr "표준 입력에서 파일 이름을 읽습니다"
 msgid "terminate input and output records by a NUL character"
 msgstr "NUL 문자를 기준으로 자료 입력 및 출력을 멈춥니다"
 
-#: builtin/check-ignore.c:20 builtin/checkout.c:1106 builtin/gc.c:358
+#: builtin/check-ignore.c:20 builtin/checkout.c:1113 builtin/gc.c:500
 msgid "suppress progress reporting"
 msgstr "진행 상황 표시를 하지 않습니다"
 
@@ -6380,9 +6770,9 @@ msgid "write the content to temporary files"
 msgstr "내용을 임시 파일에 씁니다"
 
 #: builtin/checkout-index.c:173 builtin/column.c:31
-#: builtin/submodule--helper.c:1203 builtin/submodule--helper.c:1206
-#: builtin/submodule--helper.c:1212 builtin/submodule--helper.c:1574
-#: builtin/worktree.c:570
+#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1219
+#: builtin/submodule--helper.c:1227 builtin/submodule--helper.c:1591
+#: builtin/worktree.c:610
 msgid "string"
 msgstr "문자열"
 
@@ -6453,54 +6843,54 @@ msgstr "경로를 업데이트하고 '%s' 브랜치로 전환하는 일은 동
 msgid "path '%s' is unmerged"
 msgstr "'%s' 경로를 병합하지 않았습니다"
 
-#: builtin/checkout.c:505
+#: builtin/checkout.c:506
 msgid "you need to resolve your current index first"
 msgstr "현재 인덱스를 먼저 해결해야 합니다"
 
-#: builtin/checkout.c:636
+#: builtin/checkout.c:643
 #, c-format
 msgid "Can not do reflog for '%s': %s\n"
 msgstr "'%s'에 대해 reflog할 수 없습니다: %s\n"
 
-#: builtin/checkout.c:677
+#: builtin/checkout.c:684
 msgid "HEAD is now at"
 msgstr "HEAD의 현재 위치는"
 
-#: builtin/checkout.c:681 builtin/clone.c:689
+#: builtin/checkout.c:688 builtin/clone.c:691
 msgid "unable to update HEAD"
 msgstr "HEAD를 업데이트할 수 없습니다"
 
-#: builtin/checkout.c:685
+#: builtin/checkout.c:692
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "'%s' 브랜치 리셋\n"
 
-#: builtin/checkout.c:688
+#: builtin/checkout.c:695
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "이미 '%s'에 있습니다\n"
 
-#: builtin/checkout.c:692
+#: builtin/checkout.c:699
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "'%s' 브랜치로 전환하고 리셋합니다\n"
 
-#: builtin/checkout.c:694 builtin/checkout.c:1039
+#: builtin/checkout.c:701 builtin/checkout.c:1046
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "새로 만든 '%s' 브랜치로 전환합니다\n"
 
-#: builtin/checkout.c:696
+#: builtin/checkout.c:703
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "'%s' 브랜치로 전환합니다\n"
 
-#: builtin/checkout.c:747
+#: builtin/checkout.c:754
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... 그리고 %d개 더.\n"
 
-#: builtin/checkout.c:753
+#: builtin/checkout.c:760
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -6518,7 +6908,7 @@ msgstr[0] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:772
+#: builtin/checkout.c:779
 #, c-format
 msgid ""
 "If you want to keep it by creating a new branch, this may be a good time\n"
@@ -6539,161 +6929,161 @@ msgstr[0] ""
 " git branch <새-브랜치-이름> %s\n"
 "\n"
 
-#: builtin/checkout.c:804
+#: builtin/checkout.c:811
 msgid "internal error in revision walk"
 msgstr "리비전 walk에 내부 오류"
 
-#: builtin/checkout.c:808
+#: builtin/checkout.c:815
 msgid "Previous HEAD position was"
 msgstr "이전 HEAD 위치는"
 
-#: builtin/checkout.c:836 builtin/checkout.c:1034
+#: builtin/checkout.c:843 builtin/checkout.c:1041
 msgid "You are on a branch yet to be born"
 msgstr "현재 위치가 만들 예정인 브랜치에 있습니다"
 
-#: builtin/checkout.c:940
+#: builtin/checkout.c:947
 #, c-format
 msgid "only one reference expected, %d given."
 msgstr "하나의 레퍼런스만 지정해야 하지만 %d개를 지정했습니다."
 
-#: builtin/checkout.c:980 builtin/worktree.c:249
+#: builtin/checkout.c:987 builtin/worktree.c:240 builtin/worktree.c:389
 #, c-format
 msgid "invalid reference: %s"
 msgstr "잘못된 레퍼런스: %s"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1016
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "레퍼런스가 트리가 아닙니다: %s"
 
-#: builtin/checkout.c:1048
+#: builtin/checkout.c:1055
 msgid "paths cannot be used with switching branches"
 msgstr "브랜치를 전환하는데 경로를 사용할 수 없습니다"
 
-#: builtin/checkout.c:1051 builtin/checkout.c:1055
+#: builtin/checkout.c:1058 builtin/checkout.c:1062
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "'%s' 옵션은 브랜치를 전환할 때 쓸 수 없습니다"
 
-#: builtin/checkout.c:1059 builtin/checkout.c:1062 builtin/checkout.c:1067
-#: builtin/checkout.c:1070
+#: builtin/checkout.c:1066 builtin/checkout.c:1069 builtin/checkout.c:1074
+#: builtin/checkout.c:1077
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "'%s' 옵션은 '%s' 옵션과 같이 쓸 수 없습니다"
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1082
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "브랜치를 커밋이 아닌 '%s'(으)로 전환할 수 없습니다"
 
-#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116
-#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:387
-#: builtin/worktree.c:389
+#: builtin/checkout.c:1114 builtin/checkout.c:1116 builtin/clone.c:118
+#: builtin/remote.c:167 builtin/remote.c:169 builtin/worktree.c:433
+#: builtin/worktree.c:435
 msgid "branch"
 msgstr "브랜치"
 
-#: builtin/checkout.c:1108
+#: builtin/checkout.c:1115
 msgid "create and checkout a new branch"
 msgstr "새 브랜치를 만들고 가져옵니다"
 
-#: builtin/checkout.c:1110
+#: builtin/checkout.c:1117
 msgid "create/reset and checkout a branch"
 msgstr "브랜치를 만들거나 리셋하고 가져옵니다"
 
-#: builtin/checkout.c:1111
+#: builtin/checkout.c:1118
 msgid "create reflog for new branch"
 msgstr "새 브랜치에 대한 reflog를 만듭니다"
 
-#: builtin/checkout.c:1112 builtin/worktree.c:391
+#: builtin/checkout.c:1119 builtin/worktree.c:437
 msgid "detach HEAD at named commit"
 msgstr "HEAD를 해당 커밋에서 분리합니다"
 
-#: builtin/checkout.c:1113
+#: builtin/checkout.c:1120
 msgid "set upstream info for new branch"
 msgstr "새 브랜치에 대한 업스트림 정보를 설정합니다"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new-branch"
 msgstr "새-브랜치"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new unparented branch"
 msgstr "상위 브랜치가 없는 새 브랜치"
 
-#: builtin/checkout.c:1116
+#: builtin/checkout.c:1123
 msgid "checkout our version for unmerged files"
 msgstr "병합되지 않은 파일에 대해 우리쪽 버전을 가져옵니다"
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1125
 msgid "checkout their version for unmerged files"
 msgstr "병합되지 않은 파일에 대해 상대편 버전을 가져옵니다"
 
-#: builtin/checkout.c:1120
+#: builtin/checkout.c:1127
 msgid "force checkout (throw away local modifications)"
 msgstr "강제로 체크아웃합니다 (로컬에서 수정한 사항을 버립니다)"
 
-#: builtin/checkout.c:1122
+#: builtin/checkout.c:1129
 msgid "perform a 3-way merge with the new branch"
 msgstr "새 브랜치에 대해 3-방향 병합을 수행합니다"
 
-#: builtin/checkout.c:1124 builtin/merge.c:239
+#: builtin/checkout.c:1131 builtin/merge.c:241
 msgid "update ignored files (default)"
 msgstr "무시하는 파일을 업데이트합니다 (기본값)"
 
-#: builtin/checkout.c:1126 builtin/log.c:1499 parse-options.h:263
+#: builtin/checkout.c:1133 builtin/log.c:1499 parse-options.h:264
 msgid "style"
 msgstr "스타일"
 
-#: builtin/checkout.c:1127
+#: builtin/checkout.c:1134
 msgid "conflict style (merge or diff3)"
 msgstr "충돌 스타일 (merge 또는 diff3)"
 
 # FIXME: 의미 불명
-#: builtin/checkout.c:1130
+#: builtin/checkout.c:1137
 msgid "do not limit pathspecs to sparse entries only"
 msgstr "경로명세를 드문 항목에만 제한하지 않습니다"
 
-#: builtin/checkout.c:1132
+#: builtin/checkout.c:1139
 msgid "second guess 'git checkout <no-such-branch>'"
 msgstr "'git checkout <없는-브랜치>'에 대해 추측합니다"
 
-#: builtin/checkout.c:1134
+#: builtin/checkout.c:1141
 msgid "do not check if another worktree is holding the given ref"
 msgstr "다른 작업폴더에 주어진 레퍼런스가 있는지 확인하지 않습니다"
 
-#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150
-#: builtin/merge.c:236 builtin/pull.c:123 builtin/push.c:556
-#: builtin/send-pack.c:173
+#: builtin/checkout.c:1145 builtin/clone.c:85 builtin/fetch.c:149
+#: builtin/merge.c:238 builtin/pull.c:128 builtin/push.c:572
+#: builtin/send-pack.c:174
 msgid "force progress reporting"
 msgstr "강제로 진행 상황을 표시합니다"
 
-#: builtin/checkout.c:1168
+#: builtin/checkout.c:1175
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "-b, -B 및 --orphan 옵션은 서로 호환되지 않습니다"
 
-#: builtin/checkout.c:1185
+#: builtin/checkout.c:1192
 msgid "--track needs a branch name"
 msgstr "--track 옵션은 브랜치 이름이 필요합니다"
 
-#: builtin/checkout.c:1190
+#: builtin/checkout.c:1197
 msgid "Missing branch name; try -b"
 msgstr "브랜치 이름이 없습니다. -b 옵션을 사용해 보십시오"
 
-#: builtin/checkout.c:1226
+#: builtin/checkout.c:1233
 msgid "invalid path specification"
 msgstr "경로 명세가 잘못되었습니다"
 
-#: builtin/checkout.c:1233
+#: builtin/checkout.c:1240
 #, c-format
 msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
 msgstr "'%s'은(는) 커밋이 아니고 여기에서 '%s' 브랜치를 만들 수 없습니다"
 
-#: builtin/checkout.c:1237
+#: builtin/checkout.c:1244
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout: --detach 옵션은 경로 인자를 받지 않습니다 '%s'"
 
-#: builtin/checkout.c:1241
+#: builtin/checkout.c:1248
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -6732,7 +7122,7 @@ msgstr "%s 저장소 건너뛸 예정\n"
 msgid "failed to remove %s"
 msgstr "%s 제거에 실패했습니다"
 
-#: builtin/clean.c:302 git-add--interactive.perl:572
+#: builtin/clean.c:302 git-add--interactive.perl:579
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6745,7 +7135,7 @@ msgstr ""
 "foo        - 유일한 접두어에 해당하는 항목 선택\n"
 "           - (빈 입력) 선택하지 않음\n"
 
-#: builtin/clean.c:306 git-add--interactive.perl:581
+#: builtin/clean.c:306 git-add--interactive.perl:588
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6766,8 +7156,8 @@ msgstr ""
 "*          - 모든 항목 선택\n"
 "           - (빈 입력) 선택 마침\n"
 
-#: builtin/clean.c:522 git-add--interactive.perl:547
-#: git-add--interactive.perl:552
+#: builtin/clean.c:522 git-add--interactive.perl:554
+#: git-add--interactive.perl:559
 #, c-format, perl-format
 msgid "Huh (%s)?\n"
 msgstr "어라라 (%s)?\n"
@@ -6792,7 +7182,7 @@ msgstr "삭제할 항목을 선택하십시오"
 msgid "Remove %s [y/N]? "
 msgstr "%s 제거합니까 [y/N]? "
 
-#: builtin/clean.c:788 git-add--interactive.perl:1710
+#: builtin/clean.c:788 git-add--interactive.perl:1717
 #, c-format
 msgid "Bye.\n"
 msgstr "끝.\n"
@@ -6815,11 +7205,11 @@ msgstr ""
 "help                - 이 화면 표시\n"
 "?                   - 프롬프트 선택 도움말"
 
-#: builtin/clean.c:823 git-add--interactive.perl:1786
+#: builtin/clean.c:823 git-add--interactive.perl:1793
 msgid "*** Commands ***"
 msgstr "*** 명령 ***"
 
-#: builtin/clean.c:824 git-add--interactive.perl:1783
+#: builtin/clean.c:824 git-add--interactive.perl:1790
 msgid "What now"
 msgstr "무엇을 할까요"
 
@@ -6887,144 +7277,146 @@ msgstr ""
 "clean.requireForce 기본값이 true이고 -i, -n, -f 옵션 중 하나도 쓰지 않았습니"
 "다. 지우지 않습니다"
 
-#: builtin/clone.c:40
+#: builtin/clone.c:42
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<옵션>] [--] <저장소> [<디렉터리>]"
 
-#: builtin/clone.c:85
+#: builtin/clone.c:87
 msgid "don't create a checkout"
 msgstr "체크아웃을 만들지 않습니다"
 
-#: builtin/clone.c:86 builtin/clone.c:88 builtin/init-db.c:479
+#: builtin/clone.c:88 builtin/clone.c:90 builtin/init-db.c:479
 msgid "create a bare repository"
 msgstr "간략한 저장소를 만듭니다"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:92
 msgid "create a mirror repository (implies bare)"
 msgstr "미러 저장소를 만듭니다 (간략한 저장소로 취급)"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:94
 msgid "to clone from a local repository"
 msgstr "로컬 저장소에서 복제합니다"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:96
 msgid "don't use local hardlinks, always copy"
 msgstr "로컬 하드링크를 사용하지 않고, 항상 복사합니다"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:98
 msgid "setup as shared repository"
 msgstr "공유 저장소로 설정합니다"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "pathspec"
 msgstr "경로명세"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "initialize submodules in the clone"
 msgstr "복제한 결과물에서 하위 모듈을 초기화합니다"
 
-#: builtin/clone.c:105
+#: builtin/clone.c:107
 msgid "number of submodules cloned in parallel"
 msgstr "병렬적으로 복제하는 하위모듈 개수"
 
-#: builtin/clone.c:106 builtin/init-db.c:476
+#: builtin/clone.c:108 builtin/init-db.c:476
 msgid "template-directory"
 msgstr "서식-디렉터리"
 
-#: builtin/clone.c:107 builtin/init-db.c:477
+#: builtin/clone.c:109 builtin/init-db.c:477
 msgid "directory from which templates will be used"
 msgstr "서식을 사용할 디렉터리 위치"
 
-#: builtin/clone.c:109 builtin/clone.c:111 builtin/submodule--helper.c:1210
-#: builtin/submodule--helper.c:1577
+#: builtin/clone.c:111 builtin/clone.c:113 builtin/submodule--helper.c:1223
+#: builtin/submodule--helper.c:1594
 msgid "reference repository"
 msgstr "레퍼런스 저장소"
 
-#: builtin/clone.c:113
+#: builtin/clone.c:115 builtin/submodule--helper.c:1225
+#: builtin/submodule--helper.c:1596
 msgid "use --reference only while cloning"
 msgstr "복제할 경우에만 --reference를 사용합니다"
 
-#: builtin/clone.c:114 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/clone.c:116 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/pack-objects.c:3166 builtin/repack.c:213
 msgid "name"
 msgstr "이름"
 
-#: builtin/clone.c:115
+#: builtin/clone.c:117
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "업스트림 추적에 'origin' 대신 <이름>을 사용합니다"
 
-#: builtin/clone.c:117
+#: builtin/clone.c:119
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "리모트의 HEAD 대신 <브랜치>를 가져옵니다"
 
-#: builtin/clone.c:119
+#: builtin/clone.c:121
 msgid "path to git-upload-pack on the remote"
 msgstr "리모트의 git-upload-pack 경로"
 
-#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813
-#: builtin/pull.c:211
+#: builtin/clone.c:122 builtin/fetch.c:150 builtin/grep.c:813
+#: builtin/pull.c:216
 msgid "depth"
 msgstr "깊이"
 
-#: builtin/clone.c:121
+#: builtin/clone.c:123
 msgid "create a shallow clone of that depth"
 msgstr "지정한 깊이의 얕은 복제를 만듭니다"
 
-#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017
+#: builtin/clone.c:124 builtin/fetch.c:152 builtin/pack-objects.c:3157
 #: parse-options.h:154
 msgid "time"
 msgstr "시각"
 
-#: builtin/clone.c:123
+#: builtin/clone.c:125
 msgid "create a shallow clone since a specific time"
 msgstr "지정한 시간 이후의 얕은 복제를 만듭니다"
 
-#: builtin/clone.c:124 builtin/fetch.c:155
+#: builtin/clone.c:126 builtin/fetch.c:154
 msgid "revision"
 msgstr "리비전"
 
-#: builtin/clone.c:125 builtin/fetch.c:156
+#: builtin/clone.c:127 builtin/fetch.c:155
 msgid "deepen history of shallow clone, excluding rev"
 msgstr "리비전을 제외해 얕은 복제의 커밋 내역을 깊게 만듭니다"
 
-#: builtin/clone.c:127
+#: builtin/clone.c:129
 msgid "clone only one branch, HEAD or --branch"
 msgstr "하나의 브랜치만 복제합니다 (HEAD 또는 --branch로 지정)"
 
-#: builtin/clone.c:129
+#: builtin/clone.c:131
 msgid "don't clone any tags, and make later fetches not to follow them"
 msgstr "태그를 복제하지 않습니다. 나중에 가져올 때도 태그를 따르지 않습니다."
 
-#: builtin/clone.c:131
+#: builtin/clone.c:133
 msgid "any cloned submodules will be shallow"
 msgstr "모든 복제한 하위 모듈은 얕은 모듈입니다"
 
-#: builtin/clone.c:132 builtin/init-db.c:485
+#: builtin/clone.c:134 builtin/init-db.c:485
 msgid "gitdir"
 msgstr "gitdir"
 
-#: builtin/clone.c:133 builtin/init-db.c:486
+#: builtin/clone.c:135 builtin/init-db.c:486
 msgid "separate git dir from working tree"
 msgstr "깃 디렉터리를 작업 폴더와 별개의 위치에 놓습니다"
 
-#: builtin/clone.c:134
+#: builtin/clone.c:136
 msgid "key=value"
 msgstr "키=값"
 
-#: builtin/clone.c:135
+#: builtin/clone.c:137
 msgid "set config inside the new repository"
 msgstr "새 저장소 안에서 설정합니다"
 
-#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224
-#: builtin/push.c:567
+#: builtin/clone.c:138 builtin/fetch.c:173 builtin/pull.c:229
+#: builtin/push.c:583
 msgid "use IPv4 addresses only"
 msgstr "IPv4 주소만 사용합니다"
 
-#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227
-#: builtin/push.c:569
+#: builtin/clone.c:140 builtin/fetch.c:175 builtin/pull.c:232
+#: builtin/push.c:585
 msgid "use IPv6 addresses only"
 msgstr "IPv6 주소만 사용합니다"
 
-#: builtin/clone.c:276
+#: builtin/clone.c:278
 msgid ""
 "No directory name could be guessed.\n"
 "Please specify a directory on the command line"
@@ -7032,42 +7424,42 @@ msgstr ""
 "디렉터리 이름을 알아낼 수 없습니다.\n"
 "명령행에서 디렉터리를 지정하십시오"
 
-#: builtin/clone.c:329
+#: builtin/clone.c:331
 #, c-format
 msgid "info: Could not add alternate for '%s': %s\n"
 msgstr "정보: '%s'에 대한 보조 파일을 추가할 수 없습니다: %s\n"
 
-#: builtin/clone.c:401
+#: builtin/clone.c:403
 #, c-format
 msgid "failed to open '%s'"
 msgstr "'%s'을(를) 여는데 실패"
 
-#: builtin/clone.c:409
+#: builtin/clone.c:411
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "'%s'이(가) 있지만 디렉터리가 아닙니다"
 
-#: builtin/clone.c:423
+#: builtin/clone.c:425
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "'%s'에 대해 stat()이 실패했습니다\n"
 
-#: builtin/clone.c:445
+#: builtin/clone.c:447
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "'%s' 링크를 만드는데 실패했습니다"
 
-#: builtin/clone.c:449
+#: builtin/clone.c:451
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "파일을 '%s'(으)로 복사하는데 실패했습니다"
 
-#: builtin/clone.c:475
+#: builtin/clone.c:477
 #, c-format
 msgid "done.\n"
 msgstr "완료.\n"
 
-#: builtin/clone.c:489
+#: builtin/clone.c:491
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -7077,99 +7469,99 @@ msgstr ""
 "'git status' 명령으로 무엇을 체크아웃했는지 살펴볼 수 있고\n"
 "'git checkout -f HEAD'로 체크아웃을 다시 할 수 있습니다\n"
 
-#: builtin/clone.c:566
+#: builtin/clone.c:568
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "복제할 리모트의 %s 브랜치를 찾을 수 없습니다."
 
-#: builtin/clone.c:661
+#: builtin/clone.c:663
 msgid "remote did not send all necessary objects"
 msgstr "리모트에서 필요한 오브젝트를 모두 보내지 않았습니다"
 
-#: builtin/clone.c:677
+#: builtin/clone.c:679
 #, c-format
 msgid "unable to update %s"
 msgstr "%s을(를) 업데이트할 수 없습니다"
 
-#: builtin/clone.c:726
+#: builtin/clone.c:728
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr "리모트 HEAD가 없는 레퍼런스를 참고하므로, 체크아웃할 수 없습니다.\n"
 
-#: builtin/clone.c:756
+#: builtin/clone.c:758
 msgid "unable to checkout working tree"
 msgstr "작업 폴더를 체크아웃할 수 없습니다"
 
-#: builtin/clone.c:801
+#: builtin/clone.c:803
 msgid "unable to write parameters to config file"
 msgstr "파라미터를 설정 파일에 쓸 수 없습니다"
 
-#: builtin/clone.c:864
+#: builtin/clone.c:866
 msgid "cannot repack to clean up"
 msgstr "정리용으로 repack할 수 없습니다"
 
-#: builtin/clone.c:866
+#: builtin/clone.c:868
 msgid "cannot unlink temporary alternates file"
 msgstr "보조 임시 파일을 삭제할 수 없습니다"
 
-#: builtin/clone.c:906 builtin/receive-pack.c:1946
+#: builtin/clone.c:907 builtin/receive-pack.c:1947
 msgid "Too many arguments."
 msgstr "너무 인자가 많습니다."
 
-#: builtin/clone.c:910
+#: builtin/clone.c:911
 msgid "You must specify a repository to clone."
 msgstr "복제할 저장소를 지정해야 합니다."
 
-#: builtin/clone.c:923
+#: builtin/clone.c:924
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "--bare 및 --origin %s 옵션은 호환되지 않습니다."
 
-#: builtin/clone.c:926
+#: builtin/clone.c:927
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "--bare 및 --separate-git-dir 옵션은 호환되지 않습니다."
 
-#: builtin/clone.c:939
+#: builtin/clone.c:940
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "'%s' 저장소가 없습니다"
 
-#: builtin/clone.c:945 builtin/fetch.c:1455
+#: builtin/clone.c:946 builtin/fetch.c:1460
 #, c-format
 msgid "depth %s is not a positive number"
 msgstr "깊이가(%s) 0보다 큰 수가 아닙니다"
 
-#: builtin/clone.c:955
+#: builtin/clone.c:956
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr "대상 경로가('%s') 이미 있고 빈 디렉터리가 아닙니다."
 
-#: builtin/clone.c:965
+#: builtin/clone.c:966
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "작업 폴더가('%s') 이미 있습니다."
 
-#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270
-#: builtin/worktree.c:255 builtin/worktree.c:285
+#: builtin/clone.c:981 builtin/clone.c:1002 builtin/difftool.c:270
+#: builtin/worktree.c:246 builtin/worktree.c:276
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "'%s'의 앞 디렉터리를 만들 수 없습니다"
 
-#: builtin/clone.c:985
+#: builtin/clone.c:986
 #, c-format
 msgid "could not create work tree dir '%s'"
 msgstr "작업 폴더를('%s') 만들 수 없습니다"
 
-#: builtin/clone.c:1005
+#: builtin/clone.c:1006
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "간략한 저장소로('%s') 복제합니다...\n"
 
-#: builtin/clone.c:1007
+#: builtin/clone.c:1008
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "'%s'에 복제합니다...\n"
 
-#: builtin/clone.c:1031
+#: builtin/clone.c:1032
 msgid ""
 "clone --recursive is not compatible with both --reference and --reference-if-"
 "able"
@@ -7244,7 +7636,7 @@ msgstr "오른쪽 가장자리에 채울 공백"
 msgid "Padding space between columns"
 msgstr "열 사이에 채울 공백"
 
-#: builtin/column.c:52
+#: builtin/column.c:51
 msgid "--command must be the first argument"
 msgstr "--command는 첫 번째 인자여야 합니다"
 
@@ -7300,61 +7692,61 @@ msgstr ""
 "그 다음에 \"git cherry-pick --continue\"를 하면 나머지 커밋에\n"
 "대해 커밋 빼오기를 다시 시작합니다.\n"
 
-#: builtin/commit.c:284
+#: builtin/commit.c:293
 msgid "failed to unpack HEAD tree object"
 msgstr "HEAD 트리 오브젝트의 묶음을 푸는데 실패했습니다"
 
-#: builtin/commit.c:325
+#: builtin/commit.c:334
 msgid "unable to create temporary index"
 msgstr "임시 인덱스를 만들 수 없습니다"
 
-#: builtin/commit.c:331
+#: builtin/commit.c:340
 msgid "interactive add failed"
 msgstr "대화형 추가가 실패했습니다"
 
-#: builtin/commit.c:344
+#: builtin/commit.c:353
 msgid "unable to update temporary index"
 msgstr "임시 인덱스를 업데이트할 수 없습니다"
 
-#: builtin/commit.c:346
+#: builtin/commit.c:355
 msgid "Failed to update main cache tree"
 msgstr "주요 캐시 트리를 업데이트하는데 실패했습니다"
 
-#: builtin/commit.c:371 builtin/commit.c:395 builtin/commit.c:444
+#: builtin/commit.c:380 builtin/commit.c:403 builtin/commit.c:449
 msgid "unable to write new_index file"
 msgstr "new_index 파일에 쓸 수 없습니다"
 
-#: builtin/commit.c:427
+#: builtin/commit.c:432
 msgid "cannot do a partial commit during a merge."
 msgstr "병합하는 중 부분 커밋을 할 수 없습니다."
 
-#: builtin/commit.c:429
+#: builtin/commit.c:434
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "커밋 빼오기를 하는 중 부분 커밋을 할 수 없습니다."
 
-#: builtin/commit.c:437
+#: builtin/commit.c:442
 msgid "cannot read the index"
 msgstr "인덱스를 읽을 수 없습니다"
 
-#: builtin/commit.c:456
+#: builtin/commit.c:461
 msgid "unable to write temporary index file"
 msgstr "임시 인덱스 파일을 쓸 수 없습니다"
 
-#: builtin/commit.c:553
+#: builtin/commit.c:558
 #, c-format
 msgid "commit '%s' lacks author header"
 msgstr "'%s' 커밋에 작성자 헤더가 없습니다"
 
-#: builtin/commit.c:555
+#: builtin/commit.c:560
 #, c-format
 msgid "commit '%s' has malformed author line"
 msgstr "'%s' 커밋의 작성자 헤더 형식이 잘못되었습니다"
 
-#: builtin/commit.c:574
+#: builtin/commit.c:579
 msgid "malformed --author parameter"
 msgstr "--author 파라미터 형식이 잘못되었습니다"
 
-#: builtin/commit.c:626
+#: builtin/commit.c:631
 msgid ""
 "unable to select a comment character that is not used\n"
 "in the current commit message"
@@ -7362,38 +7754,38 @@ msgstr ""
 "현재 커밋 메시지에서 사용되지 않는 주석 문자를\n"
 "선택할 수 없습니다"
 
-#: builtin/commit.c:663 builtin/commit.c:696 builtin/commit.c:1024
+#: builtin/commit.c:668 builtin/commit.c:701 builtin/commit.c:1029
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "%s 커밋을 찾아볼 수 없습니다"
 
-#: builtin/commit.c:675 builtin/shortlog.c:309
+#: builtin/commit.c:680 builtin/shortlog.c:316
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(표준 입력에서 로그 메시지를 읽음)\n"
 
-#: builtin/commit.c:677
+#: builtin/commit.c:682
 msgid "could not read log from standard input"
 msgstr "표준 입력에서 로그 메시지를 읽을 수 없습니다"
 
-#: builtin/commit.c:681
+#: builtin/commit.c:686
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "'%s' 로그 파일을 읽을 수 없습니다"
 
-#: builtin/commit.c:710 builtin/commit.c:718
+#: builtin/commit.c:715 builtin/commit.c:723
 msgid "could not read SQUASH_MSG"
 msgstr "SQUASH_MSG를 읽을 수 없습니다"
 
-#: builtin/commit.c:715
+#: builtin/commit.c:720
 msgid "could not read MERGE_MSG"
 msgstr "MERGE_MSG를 읽을 수 없습니다"
 
-#: builtin/commit.c:769
+#: builtin/commit.c:774
 msgid "could not write commit template"
 msgstr "커밋 서식을 쓸 수 없습니다"
 
-#: builtin/commit.c:787
+#: builtin/commit.c:792
 #, c-format
 msgid ""
 "\n"
@@ -7408,7 +7800,7 @@ msgstr ""
 "\t%s\n"
 "다시 시도하십시오.\n"
 
-#: builtin/commit.c:792
+#: builtin/commit.c:797
 #, c-format
 msgid ""
 "\n"
@@ -7423,7 +7815,7 @@ msgstr ""
 "\t%s\n"
 "다시 시도하십시오.\n"
 
-#: builtin/commit.c:805
+#: builtin/commit.c:810
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7432,7 +7824,7 @@ msgstr ""
 "변경 사항에 대한 커밋 메시지를 입력하십시오. '%c' 문자로 시작하는\n"
 "줄은 무시되고, 메시지를 입력하지 않으면 커밋이 중지됩니다.\n"
 
-#: builtin/commit.c:813
+#: builtin/commit.c:818
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7443,149 +7835,149 @@ msgstr ""
 "줄은 보존되니, 필요하면 직접 제거하십시오. 메시지를 입력하지\n"
 "않으면 커밋이 중지됩니다.\n"
 
-#: builtin/commit.c:830
+#: builtin/commit.c:835
 #, c-format
 msgid "%sAuthor:    %.*s <%.*s>"
 msgstr "%s작성자:    %.*s <%.*s>"
 
-#: builtin/commit.c:838
+#: builtin/commit.c:843
 #, c-format
 msgid "%sDate:      %s"
 msgstr "%s시각:      %s"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:850
 #, c-format
 msgid "%sCommitter: %.*s <%.*s>"
 msgstr "%s커미터: %.*s <%.*s>"
 
-#: builtin/commit.c:862
+#: builtin/commit.c:867
 msgid "Cannot read index"
 msgstr "인덱스를 읽을 수 없습니다"
 
-#: builtin/commit.c:928
+#: builtin/commit.c:933
 msgid "Error building trees"
 msgstr "트리를 만드는데 오류"
 
-#: builtin/commit.c:942 builtin/tag.c:256
+#: builtin/commit.c:947 builtin/tag.c:257
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "메시지를 -m 또는 -F 옵션으로 입력하십시오.\n"
 
-#: builtin/commit.c:986
+#: builtin/commit.c:991
 #, c-format
 msgid "--author '%s' is not 'Name <email>' and matches no existing author"
 msgstr ""
 "--author '%s' 옵션이 '이름 <전자메일>' 형식이 아니고 기존 작성자에도 없습니다"
 
-#: builtin/commit.c:1000
+#: builtin/commit.c:1005
 #, c-format
 msgid "Invalid ignored mode '%s'"
 msgstr "무시한 모드가 ('%s') 잘못되었습니다"
 
-#: builtin/commit.c:1014 builtin/commit.c:1264
+#: builtin/commit.c:1019 builtin/commit.c:1269
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "추적되지 않는 파일 모드가 ('%s') 잘못되었습니다"
 
-#: builtin/commit.c:1052
+#: builtin/commit.c:1057
 msgid "--long and -z are incompatible"
 msgstr "--long 및 -z 옵션은 호환되지 않습니다"
 
-#: builtin/commit.c:1085
+#: builtin/commit.c:1090
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "--reset-author 및 --author 옵션을 모두 사용하면 앞뒤가 맞지 않습니다"
 
-#: builtin/commit.c:1094
+#: builtin/commit.c:1099
 msgid "You have nothing to amend."
 msgstr "바꿀 사항이 없습니다."
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1102
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "병합 중에 있습니다 -- 커밋을 바꿀 수 없습니다."
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1104
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "커밋 빼오기 중에 있습니다 -- 커밋을 바꿀 수 없습니다."
 
-#: builtin/commit.c:1102
+#: builtin/commit.c:1107
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "--squash 및 --fixup 옵션은 같이 쓸 수 없습니다"
 
-#: builtin/commit.c:1112
+#: builtin/commit.c:1117
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "-c/-C/-F/--fixup 옵션 중에 하나만 사용할 수 있습니다."
 
-#: builtin/commit.c:1114
+#: builtin/commit.c:1119
 msgid "Option -m cannot be combined with -c/-C/-F."
 msgstr "-m 옵션은 -c/-C/-F 옵션과 같이 쓸 수 없습니다."
 
-#: builtin/commit.c:1122
+#: builtin/commit.c:1127
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr "--reset-author 옵션은 -C, -c 또는 --amend 옵션과 같이 써야 합니다."
 
-#: builtin/commit.c:1139
+#: builtin/commit.c:1144
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 "--include/--only/--all/--interactive/--patch 옵션 중 하나만 사용할 수 있습니"
 "다."
 
-#: builtin/commit.c:1141
+#: builtin/commit.c:1146
 msgid "No paths with --include/--only does not make sense."
 msgstr "경로가 없이 --include/--only 옵션을 쓰면 앞뒤가 맞지 않습니다."
 
-#: builtin/commit.c:1155 builtin/tag.c:542
+#: builtin/commit.c:1160 builtin/tag.c:543
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "잘못된 정리 모드 %s"
 
-#: builtin/commit.c:1160
+#: builtin/commit.c:1165
 msgid "Paths with -a does not make sense."
 msgstr "-a 옵션과 경로를 같이 사용하면 앞뒤가 맞지 않습니다."
 
-#: builtin/commit.c:1278 builtin/commit.c:1443
+#: builtin/commit.c:1303 builtin/commit.c:1480
 msgid "show status concisely"
 msgstr "상태를 간략하게 표시합니다"
 
-#: builtin/commit.c:1280 builtin/commit.c:1445
+#: builtin/commit.c:1305 builtin/commit.c:1482
 msgid "show branch information"
 msgstr "브랜치 정보를 표시합니다"
 
-#: builtin/commit.c:1282
+#: builtin/commit.c:1307
 msgid "show stash information"
 msgstr "스태시 정보를 표시합니다"
 
-#: builtin/commit.c:1284 builtin/commit.c:1447
+#: builtin/commit.c:1309 builtin/commit.c:1484
 msgid "compute full ahead/behind values"
 msgstr "앞/뒤 값 전체를 계산합니다"
 
-#: builtin/commit.c:1286
+#: builtin/commit.c:1311
 msgid "version"
 msgstr "버전"
 
-#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542
-#: builtin/worktree.c:541
+#: builtin/commit.c:1311 builtin/commit.c:1486 builtin/push.c:558
+#: builtin/worktree.c:581
 msgid "machine-readable output"
 msgstr "컴퓨터가 읽을 수 있는 형식"
 
-#: builtin/commit.c:1289 builtin/commit.c:1451
+#: builtin/commit.c:1314 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "긴 형식으로 상태를 표시합니다 (기본값)"
 
-#: builtin/commit.c:1292 builtin/commit.c:1454
+#: builtin/commit.c:1317 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "NUL 문자로 항목을 끝냅니다"
 
-#: builtin/commit.c:1294 builtin/commit.c:1298 builtin/commit.c:1457
-#: builtin/fast-export.c:999 builtin/fast-export.c:1002 builtin/tag.c:396
+#: builtin/commit.c:1319 builtin/commit.c:1323 builtin/commit.c:1494
+#: builtin/fast-export.c:1001 builtin/fast-export.c:1004 builtin/tag.c:397
 msgid "mode"
 msgstr "모드"
 
-#: builtin/commit.c:1295 builtin/commit.c:1457
+#: builtin/commit.c:1320 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
 "추적되지 않는 파일을 표시합니다. 추가 옵션: all, normal, no (기본값: all)"
 
-#: builtin/commit.c:1299
+#: builtin/commit.c:1324
 msgid ""
 "show ignored files, optional modes: traditional, matching, no. (Default: "
 "traditional)"
@@ -7593,11 +7985,11 @@ msgstr ""
 "무시된 파일을 표시합니다. 추가 옵션: traditional, matching, no. (기본값: "
 "traditional)"
 
-#: builtin/commit.c:1301 parse-options.h:167
+#: builtin/commit.c:1326 parse-options.h:167
 msgid "when"
 msgstr "언제"
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1327
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
@@ -7605,183 +7997,191 @@ msgstr ""
 "하위 모듈의 변경을 무시합니다. 추가 옵션: all, dirty, untracked. (기본값: "
 "all)"
 
-#: builtin/commit.c:1304
+#: builtin/commit.c:1329
 msgid "list untracked files in columns"
 msgstr "추적되지 않는 파일의 목록을 여러 열로 표시합니다"
 
-#: builtin/commit.c:1323
+#: builtin/commit.c:1330
+msgid "do not detect renames"
+msgstr "이름 바꾸기를 검사하지 않습니다"
+
+#: builtin/commit.c:1332
+msgid "detect renames, optionally set similarity index"
+msgstr "이름 바꾸기 검사하고, 부가적으로 유사성 인덱스를 설정합니다"
+
+#: builtin/commit.c:1352
 msgid "Unsupported combination of ignored and untracked-files arguments"
 msgstr "무시한 모드와 추적되지 않는 파일의 인수가 지원되지 않는 조합입니다"
 
-#: builtin/commit.c:1413
+#: builtin/commit.c:1450
 msgid "suppress summary after successful commit"
 msgstr "성공적인 커밋 후에 요약을 표시하지 않습니다"
 
-#: builtin/commit.c:1414
+#: builtin/commit.c:1451
 msgid "show diff in commit message template"
 msgstr "커밋 메시지 서식에 diff를 표시합니다"
 
-#: builtin/commit.c:1416
+#: builtin/commit.c:1453
 msgid "Commit message options"
 msgstr "커밋 메시지 옵션"
 
-#: builtin/commit.c:1417 builtin/tag.c:393
+#: builtin/commit.c:1454 builtin/tag.c:394
 msgid "read message from file"
 msgstr "파일에서 메시지를 읽습니다"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "author"
 msgstr "작성자"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "override author for commit"
 msgstr "커밋의 작성자를 지정합니다"
 
-#: builtin/commit.c:1419 builtin/gc.c:359
+#: builtin/commit.c:1456 builtin/gc.c:501
 msgid "date"
 msgstr "시각"
 
-#: builtin/commit.c:1419
+#: builtin/commit.c:1456
 msgid "override date for commit"
 msgstr "커밋의 시각을 지정합니다"
 
-#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402
-#: builtin/notes.c:565 builtin/tag.c:391
+#: builtin/commit.c:1457 builtin/merge.c:228 builtin/notes.c:402
+#: builtin/notes.c:565 builtin/tag.c:392
 msgid "message"
 msgstr "메시지"
 
-#: builtin/commit.c:1420
+#: builtin/commit.c:1457
 msgid "commit message"
 msgstr "커밋 메시지"
 
-#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423
-#: builtin/commit.c:1424 parse-options.h:269 ref-filter.h:92
+#: builtin/commit.c:1458 builtin/commit.c:1459 builtin/commit.c:1460
+#: builtin/commit.c:1461 parse-options.h:270 ref-filter.h:92
 msgid "commit"
 msgstr "커밋"
 
-#: builtin/commit.c:1421
+#: builtin/commit.c:1458
 msgid "reuse and edit message from specified commit"
 msgstr "지정한 커밋의 메시지를 재사용하고 편집합니다"
 
-#: builtin/commit.c:1422
+#: builtin/commit.c:1459
 msgid "reuse message from specified commit"
 msgstr "지정한 커밋에서 메시지를 재사용합니다"
 
-#: builtin/commit.c:1423
+#: builtin/commit.c:1460
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr "지정한 커밋을 수정하는데 autosquash 형식 메시지를 사용합니다"
 
-#: builtin/commit.c:1424
+#: builtin/commit.c:1461
 msgid "use autosquash formatted message to squash specified commit"
 msgstr "지정한 커밋을 합치는데 autosquash 형식 메시지를 사용합니다"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1462
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr "커밋을 내가 작성한 것으로 만듭니다 (-C/-c/--amend와 같이 사용)"
 
-#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240
-#: builtin/pull.c:149 builtin/revert.c:105
+#: builtin/commit.c:1463 builtin/log.c:1446 builtin/merge.c:242
+#: builtin/pull.c:154 builtin/revert.c:105
 msgid "add Signed-off-by:"
 msgstr "Signed-off-by: 줄을 추가합니다"
 
-#: builtin/commit.c:1427
+#: builtin/commit.c:1464
 msgid "use specified template file"
 msgstr "지정한 서식 파일을 사용합니다"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1465
 msgid "force edit of commit"
 msgstr "커밋 편집을 강제합니다"
 
-#: builtin/commit.c:1429
+#: builtin/commit.c:1466
 msgid "default"
 msgstr "기본값"
 
-#: builtin/commit.c:1429 builtin/tag.c:397
+#: builtin/commit.c:1466 builtin/tag.c:398
 msgid "how to strip spaces and #comments from message"
 msgstr "메시지에서 공백과 #주석을 지웁니다"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1467
 msgid "include status in commit message template"
 msgstr "커밋 메시지 서식에 상태를 포함합니다"
 
-#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179
+#: builtin/commit.c:1469 builtin/merge.c:240 builtin/pull.c:184
 #: builtin/revert.c:113
 msgid "GPG sign commit"
 msgstr "GPG 서명 커밋"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1472
 msgid "Commit contents options"
 msgstr "커밋 내용 옵션"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1473
 msgid "commit all changed files"
 msgstr "변경된 파일을 모두 커밋합니다"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1474
 msgid "add specified files to index for commit"
 msgstr "지정한 파일을 커밋할 인덱스에 추가합니다"
 
-#: builtin/commit.c:1438
+#: builtin/commit.c:1475
 msgid "interactively add files"
 msgstr "대화형으로 파일을 추가합니다"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1476
 msgid "interactively add changes"
 msgstr "대화형으로 변경 사항을 추가합니다"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1477
 msgid "commit only specified files"
 msgstr "지정한 파일만 커밋합니다"
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1478
 msgid "bypass pre-commit and commit-msg hooks"
 msgstr "커밋 전 후크와 커밋 메시지 후크를 건너뜁니다"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1479
 msgid "show what would be committed"
 msgstr "무엇을 커밋할지 표시합니다"
 
-#: builtin/commit.c:1455
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "바로 앞 커밋을 바꿉니다"
 
-#: builtin/commit.c:1456
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "다시쓰기 후 후크를 건너뜁니다"
 
-#: builtin/commit.c:1461
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "빈 변경 사항을 기록하도록 허용합니다"
 
-#: builtin/commit.c:1463
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "빈 메시지와 같이 변경 사항을 기록하도록 허용합니다"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1573
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "손상된 MERGE_HEAD 파일 (%s)"
 
-#: builtin/commit.c:1543
+#: builtin/commit.c:1580
 msgid "could not read MERGE_MODE"
 msgstr "MERGE_MODE를 읽을 수 없습니다"
 
-#: builtin/commit.c:1562
+#: builtin/commit.c:1599
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "커밋 메시지를 읽을 수 없습니다: %s"
 
-#: builtin/commit.c:1573
+#: builtin/commit.c:1610
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "커밋을 중지합니다. 커밋 메시지가 비어 있습니다.\n"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1615
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "커밋을 중지합니다. 메시지를 편집하지 않았습니다.\n"
 
-#: builtin/commit.c:1613
+#: builtin/commit.c:1650
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full and quota is\n"
@@ -7791,147 +8191,211 @@ msgstr ""
 "없습니다. 디스크가 꽉 차지 않았고 제한 용량을 넘어가지\n"
 "않았는지 확인하십시오. 그리고 'git reset HEAD'로 복구하십시오."
 
+#: builtin/commit-graph.c:9
+msgid "git commit-graph [--object-dir <objdir>]"
+msgstr "git commit-graph [--object-dir <오브젝트디렉터리>]"
+
+#: builtin/commit-graph.c:10 builtin/commit-graph.c:16
+msgid "git commit-graph read [--object-dir <objdir>]"
+msgstr "git commit-graph read [--object-dir <오브젝트디렉터리>]"
+
+#: builtin/commit-graph.c:11 builtin/commit-graph.c:21
+msgid ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+msgstr ""
+"git commit-graph write [--object-dir <오브젝트디렉터리>] [--append] [--stdin-"
+"packs|--stdin-commits]"
+
+#: builtin/commit-graph.c:39 builtin/commit-graph.c:92
+#: builtin/commit-graph.c:147 builtin/fetch.c:161 builtin/log.c:1466
+msgid "dir"
+msgstr "디렉터리"
+
+#: builtin/commit-graph.c:40 builtin/commit-graph.c:93
+#: builtin/commit-graph.c:148
+msgid "The object directory to store the graph"
+msgstr "그래프를 저장할 오브젝트 디렉터리"
+
+#: builtin/commit-graph.c:95
+msgid "scan pack-indexes listed by stdin for commits"
+msgstr "커밋을 찾을 때 표준입력에서 열거한 묶음 인덱스를 검사합니다"
+
+#: builtin/commit-graph.c:97
+msgid "start walk at commits listed by stdin"
+msgstr "표준 입력에 열거한 커밋에서부터 그리기를 시작합니다"
+
+#: builtin/commit-graph.c:99
+msgid "include all commits already in the commit-graph file"
+msgstr "commit-graph 파일에 이미 있는 모든 커밋을 포함합니다"
+
+#: builtin/commit-graph.c:108
+msgid "cannot use both --stdin-commits and --stdin-packs"
+msgstr "--stdin-commits 및 --stdin-packs 옵션은 같이 쓸 수 없습니다"
+
 #: builtin/config.c:10
 msgid "git config [<options>]"
 msgstr "git config [<옵션>]"
 
-#: builtin/config.c:58
+#: builtin/config.c:101
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "알 수 없는 --type 인자: %s"
+
+#: builtin/config.c:123
 msgid "Config file location"
 msgstr "설정 파일 위치"
 
-#: builtin/config.c:59
+#: builtin/config.c:124
 msgid "use global config file"
 msgstr "공통 설정 파일을 사용합니다"
 
-#: builtin/config.c:60
+#: builtin/config.c:125
 msgid "use system config file"
 msgstr "시스템 설정 파일을 사용합니다"
 
-#: builtin/config.c:61
+#: builtin/config.c:126
 msgid "use repository config file"
 msgstr "저장소 설정 파일을 사용합니다"
 
-#: builtin/config.c:62
+#: builtin/config.c:127
 msgid "use given config file"
 msgstr "지정한 설정 파일을 사용합니다"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "blob-id"
 msgstr "블롭-id"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "read config from given blob object"
 msgstr "지정한 블롭 오브젝트에서 설정을 읽습니다"
 
-#: builtin/config.c:64
+#: builtin/config.c:129
 msgid "Action"
 msgstr "동작"
 
-#: builtin/config.c:65
+#: builtin/config.c:130
 msgid "get value: name [value-regex]"
 msgstr "값을 가져옵니다: <이름> [<값-정규식>]"
 
-#: builtin/config.c:66
+#: builtin/config.c:131
 msgid "get all values: key [value-regex]"
 msgstr "모든 값을 가져옵니다: <키> [<값-정규식>]"
 
-#: builtin/config.c:67
+#: builtin/config.c:132
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr "정규식에 대한 값을 가져옵니다: <이름-정규식> [<값-정규식>]"
 
-#: builtin/config.c:68
+#: builtin/config.c:133
 msgid "get value specific for the URL: section[.var] URL"
 msgstr "<URL>에 특정되는 값을 가져옵니다: <섹션>[.<변수>] <URL>"
 
-#: builtin/config.c:69
+#: builtin/config.c:134
 msgid "replace all matching variables: name value [value_regex]"
 msgstr "해당하는 변수를 모두 제거합니다: <이름> <값> [<값-정규식>]"
 
-#: builtin/config.c:70
+#: builtin/config.c:135
 msgid "add a new variable: name value"
 msgstr "새 변수를 추가합니다: <이름> <값>"
 
-#: builtin/config.c:71
+#: builtin/config.c:136
 msgid "remove a variable: name [value-regex]"
 msgstr "변수를 제거합니다: <이름> [<값-정규식>]"
 
-#: builtin/config.c:72
+#: builtin/config.c:137
 msgid "remove all matches: name [value-regex]"
 msgstr "해당하는 항목을 모두 제거합니다: <이름> [<값-정규식>]"
 
-#: builtin/config.c:73
+#: builtin/config.c:138
 msgid "rename section: old-name new-name"
 msgstr "섹션의 이름을 바꿉니다: <옛-이름> <새-이름>"
 
-#: builtin/config.c:74
+#: builtin/config.c:139
 msgid "remove a section: name"
 msgstr "섹션을 제거합니다: <이름>"
 
-#: builtin/config.c:75
+#: builtin/config.c:140
 msgid "list all"
 msgstr "전체 목록을 표시합니다"
 
-#: builtin/config.c:76
+#: builtin/config.c:141
 msgid "open an editor"
 msgstr "편집기를 엽니다"
 
-#: builtin/config.c:77
+#: builtin/config.c:142
 msgid "find the color configured: slot [default]"
 msgstr "설정한 색을 찾습니다: slot [<기본값>]"
 
-#: builtin/config.c:78
+#: builtin/config.c:143
 msgid "find the color setting: slot [stdout-is-tty]"
 msgstr "색 설정을 찾습니다: slot [<표준출력이-TTY인지-여부>]"
 
-#: builtin/config.c:79
+#: builtin/config.c:144
 msgid "Type"
 msgstr "값 종류"
 
-#: builtin/config.c:80
+#: builtin/config.c:145
+msgid "value is given this type"
+msgstr "값이 해당 종류로 주어집니다"
+
+#: builtin/config.c:146
 msgid "value is \"true\" or \"false\""
 msgstr "값이 \"true\" 또는 \"false\"입니다"
 
-#: builtin/config.c:81
+#: builtin/config.c:147
 msgid "value is decimal number"
 msgstr "값이 십진수입니다"
 
-#: builtin/config.c:82
+#: builtin/config.c:148
 msgid "value is --bool or --int"
 msgstr "값이 --bool 또는 --int입니다"
 
-#: builtin/config.c:83
+#: builtin/config.c:149
 msgid "value is a path (file or directory name)"
 msgstr "값이 경로(파일 또는 디렉터리 이름)입니다"
 
-#: builtin/config.c:84
+#: builtin/config.c:150
 msgid "value is an expiry date"
 msgstr "값이 만료 시각입니다"
 
-#: builtin/config.c:85
+#: builtin/config.c:151
 msgid "Other"
 msgstr "기타"
 
-#: builtin/config.c:86
+#: builtin/config.c:152
 msgid "terminate values with NUL byte"
 msgstr "값을 NUL 바이트로 끝냅니다"
 
-#: builtin/config.c:87
+#: builtin/config.c:153
 msgid "show variable names only"
 msgstr "변수 이름만 표시합니다"
 
-#: builtin/config.c:88
+#: builtin/config.c:154
 msgid "respect include directives on lookup"
 msgstr "찾아볼 때 include 지시어를 고려합니다"
 
-#: builtin/config.c:89
+#: builtin/config.c:155
 msgid "show origin of config (file, standard input, blob, command line)"
 msgstr "설정의 출처를 표시합니다 (파일, 표준 입력, 블롭, 명령행)"
 
-#: builtin/config.c:335
+#: builtin/config.c:156
+msgid "value"
+msgstr "값"
+
+#: builtin/config.c:156
+msgid "with --get, use default value when missing entry"
+msgstr "--wget 옵션에서, 해당 항목이 없으면 기본값을 사용합니다"
+
+#: builtin/config.c:332
+#, c-format
+msgid "failed to format default config value: %s"
+msgstr "기본 설정 값을 포매팅하는데 실패했습니다: %s"
+
+#: builtin/config.c:431
 msgid "unable to parse default color value"
 msgstr "기본 색 값을 파싱할 수 없습니다"
 
-#: builtin/config.c:479
+#: builtin/config.c:575
 #, c-format
 msgid ""
 "# This is Git's per-user configuration file.\n"
@@ -7946,16 +8410,20 @@ msgstr ""
 "#\tname = %s\n"
 "#\temail = %s\n"
 
-#: builtin/config.c:507
+#: builtin/config.c:603
 msgid "--local can only be used inside a git repository"
 msgstr "--local 옵션은 깃 저장소 안에서만 쓸 수 있습니다"
 
-#: builtin/config.c:632
+#: builtin/config.c:606
+msgid "--blob can only be used inside a git repository"
+msgstr "--blob 옵션은 깃 저장소 안에서만 쓸 수 있습니다"
+
+#: builtin/config.c:735
 #, c-format
 msgid "cannot create configuration file %s"
 msgstr "%s 설정 파일을 만들 수 없습니다"
 
-#: builtin/config.c:645
+#: builtin/config.c:748
 #, c-format
 msgid ""
 "cannot overwrite multiple values with a single value\n"
@@ -7965,11 +8433,11 @@ msgstr ""
 "%s을(를) 변경하려면 정규식을 쓰거나, --add 또는 --replace-all 옵션을\n"
 "사용하십시오."
 
-#: builtin/count-objects.c:88
+#: builtin/count-objects.c:90
 msgid "git count-objects [-v] [-H | --human-readable]"
 msgstr "git count-objects [-v] [-H | --human-readable]"
 
-#: builtin/count-objects.c:98
+#: builtin/count-objects.c:100
 msgid "print sizes in human readable format"
 msgstr "사람이 읽기 좋은 형식으로 크기를 표시합니다"
 
@@ -8233,278 +8701,284 @@ msgstr "전체 디렉터리 diff를 수행합니다"
 msgid "do not prompt before launching a diff tool"
 msgstr "diff 도구를 실행하기 전에 프롬프트를 표시하지 않습니다"
 
-#: builtin/difftool.c:705
+#: builtin/difftool.c:704
 msgid "use symlinks in dir-diff mode"
 msgstr "dir-diff 모드에서 심볼릭 링크를 사용합니다"
 
-#: builtin/difftool.c:706
+#: builtin/difftool.c:705
 msgid "<tool>"
 msgstr "<도구>"
 
-#: builtin/difftool.c:707
+#: builtin/difftool.c:706
 msgid "use the specified diff tool"
 msgstr "지정한 diff 도구를 사용합니다"
 
-#: builtin/difftool.c:709
+#: builtin/difftool.c:708
 msgid "print a list of diff tools that may be used with `--tool`"
 msgstr "`--tool` 옵션에서 사용할 수 있는 diff 도구 목록을 표시합니다"
 
-#: builtin/difftool.c:712
+#: builtin/difftool.c:711
 msgid ""
 "make 'git-difftool' exit when an invoked diff tool returns a non - zero exit "
 "code"
 msgstr ""
 "실행한 diff 도구가 0이 아닌 코드를 리턴하면 'git-difftool'이 끝나게 합니다"
 
-#: builtin/difftool.c:714
+#: builtin/difftool.c:713
 msgid "<command>"
 msgstr "<명령>"
 
-#: builtin/difftool.c:715
+#: builtin/difftool.c:714
 msgid "specify a custom command for viewing diffs"
 msgstr "diff를 보는 명령어를 사용자가 지정합니다"
 
-#: builtin/difftool.c:739
+#: builtin/difftool.c:738
 msgid "no <tool> given for --tool=<tool>"
 msgstr "--tool=<도구> 옵션에 <도구>가 주어지지 않았습니다"
 
-#: builtin/difftool.c:746
+#: builtin/difftool.c:745
 msgid "no <cmd> given for --extcmd=<cmd>"
 msgstr "--extcmd=<명령> 옵션에 <명령>이 주어지지 않았습니다"
 
-#: builtin/fast-export.c:26
+#: builtin/fast-export.c:27
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [rev-list-옵션]"
 
-#: builtin/fast-export.c:998
+#: builtin/fast-export.c:1000
 msgid "show progress after <n> objects"
 msgstr "오브젝트 <n>개 뒤에 진행 상황을 표시합니다"
 
-#: builtin/fast-export.c:1000
+#: builtin/fast-export.c:1002
 msgid "select handling of signed tags"
 msgstr "서명한 태그의 처리 방식을 선택합니다"
 
-#: builtin/fast-export.c:1003
+#: builtin/fast-export.c:1005
 msgid "select handling of tags that tag filtered objects"
 msgstr "필터링한 오브젝트에 대한 태그의 처리 방식을 선택합니다"
 
-#: builtin/fast-export.c:1006
+#: builtin/fast-export.c:1008
 msgid "Dump marks to this file"
 msgstr "이 파일로 표시를 내보냅니다"
 
-#: builtin/fast-export.c:1008
+#: builtin/fast-export.c:1010
 msgid "Import marks from this file"
 msgstr "이 파일에서 표시를 가져옵니다"
 
-#: builtin/fast-export.c:1010
+#: builtin/fast-export.c:1012
 msgid "Fake a tagger when tags lack one"
 msgstr "태그에 태그붙인 사람이 없을 때 가짜로 만듭니다"
 
-#: builtin/fast-export.c:1012
+#: builtin/fast-export.c:1014
 msgid "Output full tree for each commit"
 msgstr "커밋 마다 전체 트리를 출력합니다"
 
-#: builtin/fast-export.c:1014
+#: builtin/fast-export.c:1016
 msgid "Use the done feature to terminate the stream"
 msgstr "스트림을 끝내는데 완료 기능을 사용합니다"
 
-#: builtin/fast-export.c:1015
+#: builtin/fast-export.c:1017
 msgid "Skip output of blob data"
 msgstr "블롭 데이터의 출력을 건너뜁니다"
 
-#: builtin/fast-export.c:1016
+#: builtin/fast-export.c:1018
 msgid "refspec"
 msgstr "레퍼런스명세"
 
-#: builtin/fast-export.c:1017
+#: builtin/fast-export.c:1019
 msgid "Apply refspec to exported refs"
 msgstr "레퍼런스명세를 내보낸 레퍼런스에 적용합니다"
 
-#: builtin/fast-export.c:1018
+#: builtin/fast-export.c:1020
 msgid "anonymize output"
 msgstr "출력을 익명화합니다"
 
-#: builtin/fetch.c:25
+#: builtin/fetch.c:26
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
 msgstr "git fetch [<옵션>] [<저장소> [<레퍼런스명세>...]]"
 
-#: builtin/fetch.c:26
+#: builtin/fetch.c:27
 msgid "git fetch [<options>] <group>"
 msgstr "git fetch [<옵션>] <그룹>"
 
-#: builtin/fetch.c:27
+#: builtin/fetch.c:28
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
 msgstr "git fetch --multiple [<옵션>] [(<저장소> | <그룹>)...]"
 
-#: builtin/fetch.c:28
+#: builtin/fetch.c:29
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<옵션>]"
 
-#: builtin/fetch.c:124 builtin/pull.c:188
+#: builtin/fetch.c:123 builtin/pull.c:193
 msgid "fetch from all remotes"
 msgstr "모든 리모트에서 가져옵니다"
 
-#: builtin/fetch.c:126 builtin/pull.c:191
+#: builtin/fetch.c:125 builtin/pull.c:196
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "덮어쓰지 말고 .git/FETCH_HEAD에 덧붙입니다"
 
-#: builtin/fetch.c:128 builtin/pull.c:194
+#: builtin/fetch.c:127 builtin/pull.c:199
 msgid "path to upload pack on remote end"
 msgstr "리모트 쪽에 묶음을 업로드할 경로"
 
-#: builtin/fetch.c:129 builtin/pull.c:196
+#: builtin/fetch.c:128 builtin/pull.c:201
 msgid "force overwrite of local branch"
 msgstr "로컬 브랜치를 강제로 덮어씁니다"
 
-#: builtin/fetch.c:131
+#: builtin/fetch.c:130
 msgid "fetch from multiple remotes"
 msgstr "여러 리모트에서 가져옵니다"
 
-#: builtin/fetch.c:133 builtin/pull.c:198
+#: builtin/fetch.c:132 builtin/pull.c:203
 msgid "fetch all tags and associated objects"
 msgstr "모든 태그와 관련 오브젝트를 가져옵니다"
 
-#: builtin/fetch.c:135
+#: builtin/fetch.c:134
 msgid "do not fetch all tags (--no-tags)"
 msgstr "모든 태그를 가져오지 않습니다 (--no-tags)"
 
-#: builtin/fetch.c:137
+#: builtin/fetch.c:136
 msgid "number of submodules fetched in parallel"
 msgstr "병렬적으로 받아오는 하위모듈 개수"
 
-#: builtin/fetch.c:139 builtin/pull.c:201
+#: builtin/fetch.c:138 builtin/pull.c:206
 msgid "prune remote-tracking branches no longer on remote"
 msgstr "리모트에 이제 없는 리모트 추적 브랜치를 잘라냅니다"
 
-#: builtin/fetch.c:141
+#: builtin/fetch.c:140
 msgid "prune local tags no longer on remote and clobber changed tags"
 msgstr "리모트 저장소에 없는 로컬 태그를 제거하고 변경된 태크를 적용합니다"
 
-#: builtin/fetch.c:142 builtin/fetch.c:165 builtin/pull.c:126
+#: builtin/fetch.c:141 builtin/fetch.c:164 builtin/pull.c:131
 msgid "on-demand"
 msgstr "주문형"
 
-#: builtin/fetch.c:143
+#: builtin/fetch.c:142
 msgid "control recursive fetching of submodules"
 msgstr "하위 모듈 재귀적으로 가져오기 방식을 설정합니다"
 
-#: builtin/fetch.c:147 builtin/pull.c:209
+#: builtin/fetch.c:146 builtin/pull.c:214
 msgid "keep downloaded pack"
 msgstr "다운로드한 묶음을 보존합니다"
 
-#: builtin/fetch.c:149
+#: builtin/fetch.c:148
 msgid "allow updating of HEAD ref"
 msgstr "HEAD 레퍼런스 업데이트를 허용합니다"
 
-#: builtin/fetch.c:152 builtin/fetch.c:158 builtin/pull.c:212
+#: builtin/fetch.c:151 builtin/fetch.c:157 builtin/pull.c:217
 msgid "deepen history of shallow clone"
 msgstr "얕은 복제의 커밋 내역을 깊게 만듭니다"
 
-#: builtin/fetch.c:154
+#: builtin/fetch.c:153
 msgid "deepen history of shallow repository based on time"
 msgstr "얕은 복제의 커밋 내역을 시간을 기준으로 깊게 만듭니다"
 
-#: builtin/fetch.c:160 builtin/pull.c:215
+#: builtin/fetch.c:159 builtin/pull.c:220
 msgid "convert to a complete repository"
 msgstr "완전한 저장소로 전환합니다"
 
-#: builtin/fetch.c:162 builtin/log.c:1466
-msgid "dir"
-msgstr "디렉터리"
-
-#: builtin/fetch.c:163
+#: builtin/fetch.c:162
 msgid "prepend this to submodule path output"
 msgstr "하위 모듈 경로 출력의 앞에 이 디렉터리를 붙입니다"
 
-#: builtin/fetch.c:166
+#: builtin/fetch.c:165
 msgid ""
 "default for recursive fetching of submodules (lower priority than config "
 "files)"
 msgstr "하위 모듈을 재귀적으로 가져올 때 기본값 (설정 파일보다 낮은 우선 순위)"
 
-#: builtin/fetch.c:170 builtin/pull.c:218
+#: builtin/fetch.c:169 builtin/pull.c:223
 msgid "accept refs that update .git/shallow"
 msgstr ".git/shallow를 업데이트하는 레퍼런스를 허용합니다"
 
-#: builtin/fetch.c:171 builtin/pull.c:220
+#: builtin/fetch.c:170 builtin/pull.c:225
 msgid "refmap"
 msgstr "레퍼런스맵"
 
-#: builtin/fetch.c:172 builtin/pull.c:221
+#: builtin/fetch.c:171 builtin/pull.c:226
 msgid "specify fetch refmap"
 msgstr "레퍼런스맵 가져오기를 지정합니다"
 
-#: builtin/fetch.c:431
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:172
+msgid "server-specific"
+msgstr "서버-전용-옵션"
+
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:173
+msgid "option to transmit"
+msgstr "전송할 옵션"
+
+#: builtin/fetch.c:442
 msgid "Couldn't find remote ref HEAD"
 msgstr "리모트 레퍼런스 HEAD를 찾을 수 없습니다"
 
-#: builtin/fetch.c:549
+#: builtin/fetch.c:560
 #, c-format
 msgid "configuration fetch.output contains invalid value %s"
 msgstr "fetch.output 설정에 잘못된 값이 있습니다: %s"
 
-#: builtin/fetch.c:642
+#: builtin/fetch.c:653
 #, c-format
 msgid "object %s not found"
 msgstr "%s 오브젝트가 없습니다"
 
-#: builtin/fetch.c:646
+#: builtin/fetch.c:657
 msgid "[up to date]"
 msgstr "[최신 상태]"
 
-#: builtin/fetch.c:659 builtin/fetch.c:739
+#: builtin/fetch.c:670 builtin/fetch.c:750
 msgid "[rejected]"
 msgstr "[거부됨]"
 
-#: builtin/fetch.c:660
+#: builtin/fetch.c:671
 msgid "can't fetch in current branch"
 msgstr "현재 브랜치에서 가져올 수 없음"
 
-#: builtin/fetch.c:669
+#: builtin/fetch.c:680
 msgid "[tag update]"
 msgstr "[태그 업데이트]"
 
-#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719
-#: builtin/fetch.c:734
+#: builtin/fetch.c:681 builtin/fetch.c:714 builtin/fetch.c:730
+#: builtin/fetch.c:745
 msgid "unable to update local ref"
 msgstr "로컬 레퍼런스를 업데이트할 수 없습니다"
 
-#: builtin/fetch.c:689
+#: builtin/fetch.c:700
 msgid "[new tag]"
 msgstr "[새로운 태그]"
 
-#: builtin/fetch.c:692
+#: builtin/fetch.c:703
 msgid "[new branch]"
 msgstr "[새로운 브랜치]"
 
-#: builtin/fetch.c:695
+#: builtin/fetch.c:706
 msgid "[new ref]"
 msgstr "[새로운 레퍼런스]"
 
-#: builtin/fetch.c:734
+#: builtin/fetch.c:745
 msgid "forced update"
 msgstr "강제 업데이트"
 
-#: builtin/fetch.c:739
+#: builtin/fetch.c:750
 msgid "non-fast-forward"
 msgstr "정방향 진행이 아님"
 
-#: builtin/fetch.c:784
+#: builtin/fetch.c:795
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "%s이(가) 모든 필요한 오브젝트를 보내지 않았습니다\n"
 
-#: builtin/fetch.c:804
+#: builtin/fetch.c:815
 #, c-format
 msgid "reject %s because shallow roots are not allowed to be updated"
 msgstr "얕은 최상위의 업데이트가 허용되지 않으므로 %s을(를) 거부합니다"
 
-#: builtin/fetch.c:892 builtin/fetch.c:988
+#: builtin/fetch.c:903 builtin/fetch.c:999
 #, c-format
 msgid "From %.*s\n"
 msgstr "%.*s URL에서\n"
 
-#: builtin/fetch.c:903
+#: builtin/fetch.c:914
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -8513,57 +8987,57 @@ msgstr ""
 "업데이트할 수 없는 로컬 레퍼런스가 있습니다. 과거 충돌 브랜치를\n"
 " 제거하려면 'git remote prune %s' 명령을 실행해 보십시오"
 
-#: builtin/fetch.c:958
+#: builtin/fetch.c:969
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (%s 레퍼런스가 연결이 끊어지게 됩니다)"
 
-#: builtin/fetch.c:959
+#: builtin/fetch.c:970
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (%s 레퍼런스가 연결이 끊어졌습니다)"
 
-#: builtin/fetch.c:991
+#: builtin/fetch.c:1002
 msgid "[deleted]"
 msgstr "[삭제됨]"
 
-#: builtin/fetch.c:992 builtin/remote.c:1024
+#: builtin/fetch.c:1003 builtin/remote.c:1033
 msgid "(none)"
 msgstr "(없음)"
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1026
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr "간략한 저장소가 아닌 저장소의 현재 %s 브랜치로 가져오기를 거절합니다"
 
-#: builtin/fetch.c:1034
+#: builtin/fetch.c:1045
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr "\"%s\" 옵션의 \"%s\" 값은 %s에 대해 올바르지 않습니다"
 
-#: builtin/fetch.c:1037
+#: builtin/fetch.c:1048
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "\"%s\" 옵션은 '%s'에 대해 무시됩니다\n"
 
-#: builtin/fetch.c:1277
+#: builtin/fetch.c:1287
 #, c-format
 msgid "Fetching %s\n"
 msgstr "%s을(를) 가져오는 중\n"
 
-#: builtin/fetch.c:1279 builtin/remote.c:97
+#: builtin/fetch.c:1289 builtin/remote.c:98
 #, c-format
 msgid "Could not fetch %s"
 msgstr "%s을(를) 가져올 수 없습니다"
 
-#: builtin/fetch.c:1325 builtin/fetch.c:1498
+#: builtin/fetch.c:1335 builtin/fetch.c:1503
 msgid ""
 "--filter can only be used with the remote configured in core.partialClone"
 msgstr ""
 "--filter 옵션은 core.partialClone에 설정된 리모트 저장소에만 사용할 수 있습니"
 "다"
 
-#: builtin/fetch.c:1350
+#: builtin/fetch.c:1358
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
@@ -8571,41 +9045,41 @@ msgstr ""
 "리모트 저장소를 지정하지 않았습니다. 새 리비전을 가져올 수 있는\n"
 "URL이나 리모트 이름을 지정하십시오."
 
-#: builtin/fetch.c:1394
+#: builtin/fetch.c:1395
 msgid "You need to specify a tag name."
 msgstr "태그 이름을 지정해야 합니다."
 
-#: builtin/fetch.c:1439
+#: builtin/fetch.c:1444
 msgid "Negative depth in --deepen is not supported"
 msgstr "--deepen 옵션에 음수 깊이는 지원하지 않습니다"
 
-#: builtin/fetch.c:1441
+#: builtin/fetch.c:1446
 msgid "--deepen and --depth are mutually exclusive"
 msgstr "--deepen, --depth 옵션 중 하나만 쓸 수 있습니다"
 
-#: builtin/fetch.c:1446
+#: builtin/fetch.c:1451
 msgid "--depth and --unshallow cannot be used together"
 msgstr "--depth 및 --unshallow 옵션은 같이 쓸 수 없습니다"
 
-#: builtin/fetch.c:1448
+#: builtin/fetch.c:1453
 msgid "--unshallow on a complete repository does not make sense"
 msgstr ""
 "완전한 저장소에 대해 --unshallow 옵션을 사용하는 건 앞뒤가 맞지 않습니다"
 
-#: builtin/fetch.c:1464
+#: builtin/fetch.c:1469
 msgid "fetch --all does not take a repository argument"
 msgstr "fetch --all 명령에 저장소 인자가 없습니다"
 
-#: builtin/fetch.c:1466
+#: builtin/fetch.c:1471
 msgid "fetch --all does not make sense with refspecs"
 msgstr "fetch --all 명령은 레퍼런스명세 인자와 같이 쓰면 앞뒤가 맞지 않습니다"
 
-#: builtin/fetch.c:1475
+#: builtin/fetch.c:1480
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "그런 리모트나 리모트 그룹이 없습니다: %s"
 
-#: builtin/fetch.c:1482
+#: builtin/fetch.c:1487
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr "그룹을 가져오고 레퍼런스명세를 지정하면 앞뒤가 맞지 않습니다"
 
@@ -8671,7 +9145,7 @@ msgstr "티클에 적합하게 플레이스홀더를 인용합니다"
 msgid "show only <n> matched refs"
 msgstr "<n>개의 해당하는 레퍼런스만 표시합니다"
 
-#: builtin/for-each-ref.c:39 builtin/tag.c:420
+#: builtin/for-each-ref.c:39 builtin/tag.c:421
 msgid "respect format colors"
 msgstr "포맷 색을 유지합니다"
 
@@ -8695,81 +9169,81 @@ msgstr "커밋이 들어 있는 레퍼런스만 표시합니다"
 msgid "print only refs which don't contain the commit"
 msgstr "커밋이 들어 있지 않은 레퍼런스만 표시합니다"
 
-#: builtin/fsck.c:568
+#: builtin/fsck.c:569
 msgid "Checking object directories"
 msgstr "오브젝트 디렉터리를 확인하는 중입니다"
 
-#: builtin/fsck.c:660
+#: builtin/fsck.c:661
 msgid "git fsck [<options>] [<object>...]"
 msgstr "git fsck [<옵션>] [<오브젝트>...]"
 
-#: builtin/fsck.c:666
+#: builtin/fsck.c:667
 msgid "show unreachable objects"
 msgstr "접근할 수 없는 오브젝트를 표시합니다"
 
-#: builtin/fsck.c:667
+#: builtin/fsck.c:668
 msgid "show dangling objects"
 msgstr "연결이 끊어진 오브젝트를 표시합니다"
 
-#: builtin/fsck.c:668
+#: builtin/fsck.c:669
 msgid "report tags"
 msgstr "태그를 알립니다"
 
-#: builtin/fsck.c:669
+#: builtin/fsck.c:670
 msgid "report root nodes"
 msgstr "최상위 노드를 알립니다"
 
-#: builtin/fsck.c:670
+#: builtin/fsck.c:671
 msgid "make index objects head nodes"
 msgstr "인덱스 오브젝트 헤드 노드를 만듭니다"
 
-#: builtin/fsck.c:671
+#: builtin/fsck.c:672
 msgid "make reflogs head nodes (default)"
 msgstr "reflog 헤드 노드를 만듭니다 (기본값)"
 
-#: builtin/fsck.c:672
+#: builtin/fsck.c:673
 msgid "also consider packs and alternate objects"
 msgstr "묶음과 보조 오브젝트도 만듭니다"
 
-#: builtin/fsck.c:673
+#: builtin/fsck.c:674
 msgid "check only connectivity"
 msgstr "연결만 확인합니다"
 
-#: builtin/fsck.c:674
+#: builtin/fsck.c:675
 msgid "enable more strict checking"
 msgstr "더 엄격하게 확인합니다"
 
-#: builtin/fsck.c:676
+#: builtin/fsck.c:677
 msgid "write dangling objects in .git/lost-found"
 msgstr ".git/lost-found 안에 연결이 끊어진 오브젝트를 씁니다"
 
-#: builtin/fsck.c:677 builtin/prune.c:108
+#: builtin/fsck.c:678 builtin/prune.c:109
 msgid "show progress"
 msgstr "진행 상황을 표시합니다"
 
-#: builtin/fsck.c:678
+#: builtin/fsck.c:679
 msgid "show verbose names for reachable objects"
 msgstr "접근할 수 없는 오브젝트의 이름을 자세히 표시합니다"
 
-#: builtin/fsck.c:742
+#: builtin/fsck.c:745
 msgid "Checking objects"
 msgstr "오브젝트를 확인합니다"
 
-#: builtin/gc.c:27
+#: builtin/gc.c:33
 msgid "git gc [<options>]"
 msgstr "git gc [<옵션>]"
 
-#: builtin/gc.c:80
+#: builtin/gc.c:88
 #, c-format
 msgid "Failed to fstat %s: %s"
 msgstr "'%s'에 fstat()하는데 실패했습니다: %s"
 
-#: builtin/gc.c:312
+#: builtin/gc.c:452
 #, c-format
 msgid "Can't stat %s"
 msgstr "'%s'에 stat()할 수 없습니다"
 
-#: builtin/gc.c:321
+#: builtin/gc.c:461
 #, c-format
 msgid ""
 "The last gc run reported the following. Please correct the root cause\n"
@@ -8784,43 +9258,52 @@ msgstr ""
 "\n"
 "%s"
 
-#: builtin/gc.c:360
+#: builtin/gc.c:502
 msgid "prune unreferenced objects"
 msgstr "레퍼런스하지 않는 오브젝트를 잘라냅니다"
 
-#: builtin/gc.c:362
+#: builtin/gc.c:504
 msgid "be more thorough (increased runtime)"
 msgstr "더 자세히 검사합니다 (실행 시간 늘어남)"
 
-#: builtin/gc.c:363
+#: builtin/gc.c:505
 msgid "enable auto-gc mode"
 msgstr "자동 가비지컬렉터 모드를 사용합니다"
 
-#: builtin/gc.c:366
+#: builtin/gc.c:508
 msgid "force running gc even if there may be another gc running"
 msgstr "이미 가비지컬렉터가 실행 중이더라도 강제로 가비지컬렉터를 실행합니다"
 
-#: builtin/gc.c:384
+#: builtin/gc.c:511
+msgid "repack all other packs except the largest pack"
+msgstr "가장 큰 묶음을 제외한 다른 묶음을 다시 묶습니다"
+
+#: builtin/gc.c:528
 #, c-format
-msgid "Failed to parse gc.logexpiry value %s"
+msgid "failed to parse gc.logexpiry value %s"
 msgstr "gc.logexpiry 값을 (%s) 파싱하는데 실패했습니다"
 
-#: builtin/gc.c:412
+#: builtin/gc.c:539
+#, c-format
+msgid "failed to parse prune expiry value %s"
+msgstr "만료값 %s 파싱하는데 실패했습니다"
+
+#: builtin/gc.c:559
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
 msgstr "최적 성능을 위해 백그라운드에서 자동으로 저장소의 묶음을 만듭니다.\n"
 
-#: builtin/gc.c:414
+#: builtin/gc.c:561
 #, c-format
 msgid "Auto packing the repository for optimum performance.\n"
 msgstr "최적 성능을 위해 자동으로 저장소의 묶음을 만듭니다.\n"
 
-#: builtin/gc.c:415
+#: builtin/gc.c:562
 #, c-format
 msgid "See \"git help gc\" for manual housekeeping.\n"
 msgstr "수동 관리 작업은 \"git help gc\" 내용을 참고하십시오.\n"
 
-#: builtin/gc.c:440
+#: builtin/gc.c:598
 #, c-format
 msgid ""
 "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
@@ -8828,22 +9311,22 @@ msgstr ""
 "가비지컬렉터가 이미 '%s' 컴퓨터에서 %<PRIuMAX> PID로 실행 중입니다 (아니면 --"
 "force를 사용하십시오)"
 
-#: builtin/gc.c:487
+#: builtin/gc.c:645
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
 "느슨한 오브젝트가 너무 많습니다. 제거하려면 'git prune'을 실행하십시오."
 
-#: builtin/grep.c:27
+#: builtin/grep.c:28
 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [<옵션>] [-e] <패턴> [<리비전>...] [[--] <경로>...]"
 
-#: builtin/grep.c:225
+#: builtin/grep.c:226
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep: 스레드를 만드는데 실패했습니다: %s"
 
-#: builtin/grep.c:283
+#: builtin/grep.c:284
 #, c-format
 msgid "invalid number of threads specified (%d) for %s"
 msgstr "잘못된 스레드 수를 %2$s에 대해 지정했습니다 (%1$d)"
@@ -8852,17 +9335,17 @@ msgstr "잘못된 스레드 수를 %2$s에 대해 지정했습니다 (%1$d)"
 #. variable for tweaking threads, currently
 #. grep.threads
 #.
-#: builtin/grep.c:292 builtin/index-pack.c:1523 builtin/index-pack.c:1712
+#: builtin/grep.c:293 builtin/index-pack.c:1535 builtin/index-pack.c:1727
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "스레드 기능이 없습니다. %s 무시"
 
-#: builtin/grep.c:460 builtin/grep.c:580 builtin/grep.c:622
+#: builtin/grep.c:461 builtin/grep.c:582 builtin/grep.c:623
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "트리를 읽을 수 없습니다 (%s)"
 
-#: builtin/grep.c:637
+#: builtin/grep.c:638
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "종류가 %s인 오브젝트에서 grep을 할 수 없습니다"
@@ -9061,7 +9544,7 @@ msgstr "--no-index 또는 --untracked 옵션은 리비전과 같이 쓸 수 없
 msgid "unable to resolve revision: %s"
 msgstr "리비전을 찾아낼 수 없습니다: %s"
 
-#: builtin/grep.c:1036 builtin/index-pack.c:1519
+#: builtin/grep.c:1036 builtin/index-pack.c:1531
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "잘못된 스레드 수를 지정했습니다 (%d)"
@@ -9132,58 +9615,62 @@ msgstr "임의의 쓰레기 데이터를 해시해 손상된 오브젝트를 만
 msgid "process file as it were from this path"
 msgstr "파일이 이 경로에서 온 것처럼 처리합니다"
 
-#: builtin/help.c:43
+#: builtin/help.c:45
 msgid "print all available commands"
 msgstr "사용 가능한 모든 명령의 목록을 표시합니다"
 
-#: builtin/help.c:44
+#: builtin/help.c:46
 msgid "exclude guides"
 msgstr "설명서 제외"
 
-#: builtin/help.c:45
+#: builtin/help.c:47
 msgid "print list of useful guides"
 msgstr "유용한 안내서 목록을 표시합니다"
 
-#: builtin/help.c:46
+#: builtin/help.c:48
 msgid "show man page"
 msgstr "맨 페이지를 표시합니다"
 
-#: builtin/help.c:47
+#: builtin/help.c:49
 msgid "show manual in web browser"
 msgstr "웹 브라우저에서 설명서를 표시합니다"
 
-#: builtin/help.c:49
+#: builtin/help.c:51
 msgid "show info page"
 msgstr "인포 페이지를 표시합니다"
 
-#: builtin/help.c:55
+#: builtin/help.c:53
+msgid "print command description"
+msgstr "명령어 설명을 표시합니다"
+
+#: builtin/help.c:58
 msgid "git help [--all] [--guides] [--man | --web | --info] [<command>]"
 msgstr "git help [--all] [--guides] [--man | --web | --info] [<명령>]"
 
-#: builtin/help.c:67
+#: builtin/help.c:70
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "'%s' 도움말 포맷을 인식할 수 없습니다"
 
-#: builtin/help.c:94
+#: builtin/help.c:97
 msgid "Failed to start emacsclient."
 msgstr "emacsclient 시작에 실패했습니다."
 
-#: builtin/help.c:107
+#: builtin/help.c:110
 msgid "Failed to parse emacsclient version."
 msgstr "emacsclient 버전 파싱에 실패했습니다."
 
-#: builtin/help.c:115
+#: builtin/help.c:118
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "emacsclient '%d' 버전은 너무 과거 (< 22) 버전입니다."
 
-#: builtin/help.c:133 builtin/help.c:155 builtin/help.c:165 builtin/help.c:173
+#: builtin/help.c:136 builtin/help.c:158 builtin/help.c:168 builtin/help.c:176
 #, c-format
 msgid "failed to exec '%s'"
 msgstr "실행 실패: '%s'"
 
-#: builtin/help.c:211
+#: builtin/help.c:214
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -9192,7 +9679,7 @@ msgstr ""
 "'%s': 지원하지 않는 맨 페이지 보기 프로그램 경로.\n"
 "대신에 'man.<도구>.cmd' 옵션을 사용해 보십시오."
 
-#: builtin/help.c:223
+#: builtin/help.c:226
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -9201,352 +9688,320 @@ msgstr ""
 "'%s': 지원하지 않는 맨 페이지 보기 프로그램 명령.\n"
 "대신에 'man.<도구>.path' 옵션을 사용해 보십시오."
 
-#: builtin/help.c:340
+#: builtin/help.c:343
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "'%s': 알 수 없는 맨 페이지 보기 프로그램."
 
-#: builtin/help.c:357
+#: builtin/help.c:360
 msgid "no man viewer handled the request"
 msgstr "요청을 처리한 맨 페이지 보기 프로그램이 없습니다"
 
-#: builtin/help.c:365
+#: builtin/help.c:368
 msgid "no info viewer handled the request"
 msgstr "요청을 처리한 인포 페이지 보기 프로그램이 없습니다"
 
-#: builtin/help.c:407
-msgid "Defining attributes per path"
-msgstr "경로마다 속성 정의하기"
+#: builtin/help.c:415
+#, c-format
+msgid "'%s' is aliased to '%s'"
+msgstr "'%s' 명령은 '%s' 명령의 단축입니다"
 
-#: builtin/help.c:408
-msgid "Everyday Git With 20 Commands Or So"
-msgstr "매일매일 사용하는 20개 내외의 깃 명령"
+#: builtin/help.c:442 builtin/help.c:459
+#, c-format
+msgid "usage: %s%s"
+msgstr "사용법: %s%s"
 
-#: builtin/help.c:409
-msgid "A Git glossary"
-msgstr "깃 용어 사전"
+#: builtin/index-pack.c:158
+#, c-format
+msgid "unable to open %s"
+msgstr "%s을(를) 열 수 없습니다"
 
-#: builtin/help.c:410
-msgid "Specifies intentionally untracked files to ignore"
-msgstr "의도적으로 추적하지 않는 파일을 무시하게 지정하기"
-
-#: builtin/help.c:411
-msgid "Defining submodule properties"
-msgstr "하위 모듈 속성 정의하기"
-
-#: builtin/help.c:412
-msgid "Specifying revisions and ranges for Git"
-msgstr "깃의 리비전 및 범위를 지정하기"
-
-#: builtin/help.c:413
-msgid "A tutorial introduction to Git (for version 1.5.1 or newer)"
-msgstr "깃 따라하기 안내서 (버전 1.5.1 이후)"
-
-#: builtin/help.c:414
-msgid "An overview of recommended workflows with Git"
-msgstr "추천하는 깃 활용 작업 순서의 개요"
-
-#: builtin/help.c:426
-msgid "The common Git guides are:\n"
-msgstr "자주 사용하는 깃 안내서는 다음과 같습니다:\n"
-
-#: builtin/help.c:444
-#, c-format
-msgid "'%s' is aliased to '%s'"
-msgstr "'%s' 명령은 '%s' 명령의 단축입니다"
-
-#: builtin/help.c:466 builtin/help.c:483
-#, c-format
-msgid "usage: %s%s"
-msgstr "사용법: %s%s"
-
-#: builtin/index-pack.c:157
-#, c-format
-msgid "unable to open %s"
-msgstr "%s을(를) 열 수 없습니다"
-
-#: builtin/index-pack.c:207
+#: builtin/index-pack.c:208
 #, c-format
 msgid "object type mismatch at %s"
 msgstr "오브젝트 종류가 맞지 않습니다 (%s)"
 
-#: builtin/index-pack.c:227
+#: builtin/index-pack.c:228
 #, c-format
 msgid "did not receive expected object %s"
 msgstr "예상한 %s 오브젝트를 받지 않았습니다"
 
-#: builtin/index-pack.c:230
+#: builtin/index-pack.c:231
 #, c-format
 msgid "object %s: expected type %s, found %s"
 msgstr "%s 오브젝트: 예상한 종류 %s, 실제 %s"
 
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
 #, c-format
 msgid "cannot fill %d byte"
 msgid_plural "cannot fill %d bytes"
 msgstr[0] "%d 바이트를 채울 수 없습니다"
 
-#: builtin/index-pack.c:282
+#: builtin/index-pack.c:283
 msgid "early EOF"
 msgstr "너무 빨리 파일이 끝남"
 
-#: builtin/index-pack.c:283
+#: builtin/index-pack.c:284
 msgid "read error on input"
 msgstr "입력에 읽기 오류"
 
-#: builtin/index-pack.c:295
+#: builtin/index-pack.c:296
 msgid "used more bytes than were available"
 msgstr "있는 바이트보다 더 많이 사용합니다"
 
-#: builtin/index-pack.c:302
+#: builtin/index-pack.c:303
 msgid "pack too large for current definition of off_t"
 msgstr "현재 정의된 off_t에 비해 묶음이 너무 큽니다"
 
-#: builtin/index-pack.c:305 builtin/unpack-objects.c:93
+#: builtin/index-pack.c:306 builtin/unpack-objects.c:93
 msgid "pack exceeds maximum allowed size"
 msgstr "묶음 크기가 최대 허용 크기를 넘었습니다"
 
-#: builtin/index-pack.c:320
+#: builtin/index-pack.c:321
 #, c-format
 msgid "unable to create '%s'"
 msgstr "'%s'을(를) 만들 수 없습니다"
 
-#: builtin/index-pack.c:326
+#: builtin/index-pack.c:327
 #, c-format
 msgid "cannot open packfile '%s'"
 msgstr "'%s' 묶음 파일을 열 수 없습니다"
 
-#: builtin/index-pack.c:340
+#: builtin/index-pack.c:341
 msgid "pack signature mismatch"
 msgstr "묶음 서명이 맞지 않습니다"
 
-#: builtin/index-pack.c:342
+#: builtin/index-pack.c:343
 #, c-format
 msgid "pack version %<PRIu32> unsupported"
 msgstr "묶음의 %<PRIu32> 버전을 지원하지 않습니다"
 
-#: builtin/index-pack.c:360
+#: builtin/index-pack.c:361
 #, c-format
 msgid "pack has bad object at offset %<PRIuMAX>: %s"
 msgstr "묶음의 %<PRIuMAX> 오프셋에 잘못된 오브젝트가 있습니다: %s"
 
-#: builtin/index-pack.c:481
+#: builtin/index-pack.c:482
 #, c-format
 msgid "inflate returned %d"
 msgstr "inflate가 %d번을 리턴했습니다"
 
-#: builtin/index-pack.c:530
+#: builtin/index-pack.c:531
 msgid "offset value overflow for delta base object"
 msgstr "델타 베이스 오브젝트에 대해 오프셋 값이 오버플로우"
 
-#: builtin/index-pack.c:538
+#: builtin/index-pack.c:539
 msgid "delta base offset is out of bound"
 msgstr "델타 베이스 오프셋이 범위를 벗어났습니다"
 
-#: builtin/index-pack.c:546
+#: builtin/index-pack.c:547
 #, c-format
 msgid "unknown object type %d"
 msgstr "알 수 없는 오브젝트 종류 %d번"
 
-#: builtin/index-pack.c:577
+#: builtin/index-pack.c:578
 msgid "cannot pread pack file"
 msgstr "묶음 파일에 대해 pread를 할 수 없습니다"
 
-#: builtin/index-pack.c:579
+#: builtin/index-pack.c:580
 #, c-format
 msgid "premature end of pack file, %<PRIuMAX> byte missing"
 msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
 msgstr[0] "묶음 파일이 너무 일찍 끝남. %<PRIuMAX> 바이트 부족"
 
-#: builtin/index-pack.c:605
+#: builtin/index-pack.c:606
 msgid "serious inflate inconsistency"
 msgstr "심각한 inflate 부조화"
 
-#: builtin/index-pack.c:750 builtin/index-pack.c:756 builtin/index-pack.c:779
-#: builtin/index-pack.c:818 builtin/index-pack.c:827
+#: builtin/index-pack.c:751 builtin/index-pack.c:757 builtin/index-pack.c:780
+#: builtin/index-pack.c:819 builtin/index-pack.c:828
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "SHA1 충돌이 %s에서 발견되었습니다!"
 
-#: builtin/index-pack.c:753 builtin/pack-objects.c:182
-#: builtin/pack-objects.c:276
+#: builtin/index-pack.c:754 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:292
 #, c-format
 msgid "unable to read %s"
 msgstr "%s을(를) 읽을 수 없습니다"
 
-#: builtin/index-pack.c:816
+#: builtin/index-pack.c:817
 #, c-format
 msgid "cannot read existing object info %s"
 msgstr "기존 %s 오브젝트 정보를 읽을 수 없습니다"
 
-#: builtin/index-pack.c:824
+#: builtin/index-pack.c:825
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "기존 %s 오브젝트를 읽을 수 없습니다"
 
-#: builtin/index-pack.c:838
+#: builtin/index-pack.c:839
 #, c-format
 msgid "invalid blob object %s"
 msgstr "잘못된 블롭 오브젝트 %s"
 
-#: builtin/index-pack.c:853
+#: builtin/index-pack.c:842 builtin/index-pack.c:860
+msgid "fsck error in packed object"
+msgstr "묶음 오브젝트에서 fsck 오류"
+
+#: builtin/index-pack.c:857
 #, c-format
 msgid "invalid %s"
 msgstr "잘못된 %s"
 
-#: builtin/index-pack.c:856
-msgid "Error in object"
-msgstr "오브젝트에 오류"
-
-#: builtin/index-pack.c:858
+#: builtin/index-pack.c:862
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "%s의 모든 하위 오브젝트에 접근할 수 없습니다"
 
-#: builtin/index-pack.c:930 builtin/index-pack.c:961
+#: builtin/index-pack.c:934 builtin/index-pack.c:965
 msgid "failed to apply delta"
 msgstr "델타를 적용하는데 실패했습니다"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Receiving objects"
 msgstr "오브젝트를 받는 중"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Indexing objects"
 msgstr "오브젝트 인덱스를 만드는 중"
 
-#: builtin/index-pack.c:1165
+#: builtin/index-pack.c:1169
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "묶음이 손상되었습니다 (SHA1 일치하지 않음)"
 
-#: builtin/index-pack.c:1170
+#: builtin/index-pack.c:1174
 msgid "cannot fstat packfile"
 msgstr "묶음 파일에 대해 fstat()할 수 없습니다"
 
-#: builtin/index-pack.c:1173
+#: builtin/index-pack.c:1177
 msgid "pack has junk at the end"
 msgstr "묶음의 끝에 쓰레기 데이터가 있습니다"
 
-#: builtin/index-pack.c:1185
+#: builtin/index-pack.c:1189
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "parse_pack_objects()에서 극심한 혼란"
 
-#: builtin/index-pack.c:1208
+#: builtin/index-pack.c:1212
 msgid "Resolving deltas"
 msgstr "델타를 알아내는 중"
 
-#: builtin/index-pack.c:1219
+#: builtin/index-pack.c:1223
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "스레드를 만들 수 없습니다: %s"
 
-#: builtin/index-pack.c:1261
+#: builtin/index-pack.c:1265
 msgid "confusion beyond insanity"
 msgstr "극심한 혼란"
 
-#: builtin/index-pack.c:1267
+#: builtin/index-pack.c:1271
 #, c-format
 msgid "completed with %d local object"
 msgid_plural "completed with %d local objects"
 msgstr[0] "로컬 오브젝트 %d개 마침"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1283
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr "%s에 대해 예상치 못한 테일 체크섬 (디스크 손상?)"
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1287
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "묶음에 알아내지 못한 델타 %d개가 있습니다"
 
-#: builtin/index-pack.c:1307
+#: builtin/index-pack.c:1311
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "추가한 오브젝트를 deflate할 수 없습니다 (%d)"
 
-#: builtin/index-pack.c:1383
+#: builtin/index-pack.c:1388
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "%s 로컬 오브젝트가 손상되었습니다"
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1402
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "'%s' 묶음파일 이름이 '.pack'으로 끝나지 않습니다"
 
-#: builtin/index-pack.c:1422
+#: builtin/index-pack.c:1427
 #, c-format
 msgid "cannot write %s file '%s'"
 msgstr "%s 파일을 쓸 수 없습니다 '%s'"
 
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1435
 #, c-format
 msgid "cannot close written %s file '%s'"
 msgstr "쓴 %s파일을 닫을 수 없습니다 '%s'"
 
-#: builtin/index-pack.c:1454
+#: builtin/index-pack.c:1459
 msgid "error while closing pack file"
 msgstr "묶음 파일을 닫는데 오류"
 
-#: builtin/index-pack.c:1468
+#: builtin/index-pack.c:1473
 msgid "cannot store pack file"
 msgstr "묶음 파일을 저장할 수 없습니다"
 
-#: builtin/index-pack.c:1476
+#: builtin/index-pack.c:1481
 msgid "cannot store index file"
 msgstr "인덱스 파일을 저장할 수 없습니다"
 
-#: builtin/index-pack.c:1513
+#: builtin/index-pack.c:1525
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "잘못된 pack.indexversion=%<PRIu32>"
 
-#: builtin/index-pack.c:1581
+#: builtin/index-pack.c:1594
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "기존 '%s' 묶음 파일을 열 수 없습니다"
 
-#: builtin/index-pack.c:1583
+#: builtin/index-pack.c:1596
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "'%s'에 대한 기존 묶음 idx 파일을 열 수 없습니다"
 
-#: builtin/index-pack.c:1631
+#: builtin/index-pack.c:1644
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "델타 아님: 오브젝트 %d개"
 
-#: builtin/index-pack.c:1638
+#: builtin/index-pack.c:1651
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] "체인 길이 = %d: 오브젝트 %lu개"
 
-#: builtin/index-pack.c:1675
+#: builtin/index-pack.c:1688
 msgid "Cannot come back to cwd"
 msgstr "현재 디렉터리로 돌아올 수 없습니다"
 
-#: builtin/index-pack.c:1724 builtin/index-pack.c:1727
-#: builtin/index-pack.c:1743 builtin/index-pack.c:1747
+#: builtin/index-pack.c:1739 builtin/index-pack.c:1742
+#: builtin/index-pack.c:1758 builtin/index-pack.c:1762
 #, c-format
 msgid "bad %s"
 msgstr "잘못된 %s"
 
-#: builtin/index-pack.c:1763
+#: builtin/index-pack.c:1778
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin 옵션은 --stdin 옵션과 같이 쓸 수 없습니다"
 
-#: builtin/index-pack.c:1765
+#: builtin/index-pack.c:1780
 msgid "--stdin requires a git repository"
 msgstr "--stdin 옵션은 깃 저장소가 필요합니다"
 
-#: builtin/index-pack.c:1771
+#: builtin/index-pack.c:1786
 msgid "--verify with no packfile name given"
 msgstr "--verify 옵션에 묶음파일 이름을 지정하지 않았습니다"
 
+#: builtin/index-pack.c:1836 builtin/unpack-objects.c:578
+msgid "fsck error in pack objects"
+msgstr "묶음 오브젝트에서 fsck 오류"
+
 #: builtin/init-db.c:55
 #, c-format
 msgid "cannot stat '%s'"
@@ -9584,7 +10039,7 @@ msgstr "%s 서식을 무시합니다"
 
 #: builtin/init-db.c:120
 #, c-format
-msgid "templates not found %s"
+msgid "templates not found in %s"
 msgstr "%s에 서식이 없습니다"
 
 #: builtin/init-db.c:135
@@ -9643,11 +10098,6 @@ msgstr "권한"
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr "깃 저장소를 다른 사용자가 공유할 수 있게 지정"
 
-#: builtin/init-db.c:516 builtin/init-db.c:521
-#, c-format
-msgid "cannot mkdir %s"
-msgstr "%s에 대해 mkdir를 할 수 없습니다"
-
 #: builtin/init-db.c:525
 #, c-format
 msgid "cannot chdir to %s"
@@ -9831,7 +10281,7 @@ msgstr "출력 디렉터리가 두개?"
 msgid "Unknown commit %s"
 msgstr "알 수 없는 커밋 %s"
 
-#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:522
+#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:523
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr "'%s'을(를) 올바른 레퍼런스로 알아내는데 실패했습니다."
@@ -10182,7 +10632,7 @@ msgstr "<트리-따위> 뒤로 제거한 경로가 있다고 가정합니다"
 msgid "show debugging data"
 msgstr "디버깅 데이터를 표시합니다"
 
-#: builtin/ls-remote.c:7
+#: builtin/ls-remote.c:9
 msgid ""
 "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
@@ -10192,39 +10642,39 @@ msgstr ""
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
 "                     [--symref] [<저장소> [<레퍼런스>...]]"
 
-#: builtin/ls-remote.c:52
+#: builtin/ls-remote.c:59
 msgid "do not print remote URL"
 msgstr "원격 URL을 표시하지 않습니다"
 
-#: builtin/ls-remote.c:53 builtin/ls-remote.c:55
+#: builtin/ls-remote.c:60 builtin/ls-remote.c:62
 msgid "exec"
 msgstr "실행"
 
-#: builtin/ls-remote.c:54 builtin/ls-remote.c:56
+#: builtin/ls-remote.c:61 builtin/ls-remote.c:63
 msgid "path of git-upload-pack on the remote host"
 msgstr "원격 호스트의 git-upload-pack 경로"
 
-#: builtin/ls-remote.c:58
+#: builtin/ls-remote.c:65
 msgid "limit to tags"
 msgstr "태그에 한정"
 
-#: builtin/ls-remote.c:59
+#: builtin/ls-remote.c:66
 msgid "limit to heads"
 msgstr "헤드에 한정"
 
-#: builtin/ls-remote.c:60
+#: builtin/ls-remote.c:67
 msgid "do not show peeled tags"
 msgstr "벗겨진 태그를 표시하지 않습니다"
 
-#: builtin/ls-remote.c:62
+#: builtin/ls-remote.c:69
 msgid "take url.<base>.insteadOf into account"
 msgstr "url.<베이스>.insteadOf 설정을 고려합니다"
 
-#: builtin/ls-remote.c:64
+#: builtin/ls-remote.c:73
 msgid "exit with exit code 2 if no matching refs are found"
 msgstr "해당하는 레퍼런스가 없으면 코드 2번으로 끝냅니다"
 
-#: builtin/ls-remote.c:67
+#: builtin/ls-remote.c:76
 msgid "show underlying ref in addition to the object pointed by it"
 msgstr "레퍼런스와 레퍼런스가 가리키는 오브젝트를 표시합니다"
 
@@ -10269,165 +10719,165 @@ msgstr "전체 트리 목록 표시, 현재 디렉터리만 아니라 (--full-na
 msgid "empty mbox: '%s'"
 msgstr "빈 mbox: '%s'"
 
-#: builtin/merge.c:49
+#: builtin/merge.c:51
 msgid "git merge [<options>] [<commit>...]"
 msgstr "git merge [<옵션>] [<커밋>...]"
 
-#: builtin/merge.c:50
+#: builtin/merge.c:52
 msgid "git merge --abort"
 msgstr "git merge --abort"
 
-#: builtin/merge.c:51
+#: builtin/merge.c:53
 msgid "git merge --continue"
 msgstr "git merge --continue"
 
-#: builtin/merge.c:108
+#: builtin/merge.c:110
 msgid "switch `m' requires a value"
 msgstr "`m' 옵션에는 값이 필요합니다"
 
-#: builtin/merge.c:145
+#: builtin/merge.c:147
 #, c-format
 msgid "Could not find merge strategy '%s'.\n"
 msgstr "'%s' 병합 전략을 찾을 수 없습니다.\n"
 
-#: builtin/merge.c:146
+#: builtin/merge.c:148
 #, c-format
 msgid "Available strategies are:"
 msgstr "사용 가능한 전략은:"
 
-#: builtin/merge.c:151
+#: builtin/merge.c:153
 #, c-format
 msgid "Available custom strategies are:"
 msgstr "사용 가능한 사용자 설정 전략은:"
 
-#: builtin/merge.c:201 builtin/pull.c:137
+#: builtin/merge.c:203 builtin/pull.c:142
 msgid "do not show a diffstat at the end of the merge"
 msgstr "병합이 끝날 때 diffstat을 표시하지 않습니다"
 
-#: builtin/merge.c:204 builtin/pull.c:140
+#: builtin/merge.c:206 builtin/pull.c:145
 msgid "show a diffstat at the end of the merge"
 msgstr "병합이 끝날 때 diffstat을 표시합니다"
 
-#: builtin/merge.c:205 builtin/pull.c:143
+#: builtin/merge.c:207 builtin/pull.c:148
 msgid "(synonym to --stat)"
 msgstr "(--stat 옵션과 동일)"
 
-#: builtin/merge.c:207 builtin/pull.c:146
+#: builtin/merge.c:209 builtin/pull.c:151
 msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr "병합 커밋의 메시지에 shortlog 항목을 (최대 <n>개) 추가합니다"
 
-#: builtin/merge.c:210 builtin/pull.c:152
+#: builtin/merge.c:212 builtin/pull.c:157
 msgid "create a single commit instead of doing a merge"
 msgstr "병합하는 대신 하나의 커밋을 만듭니다"
 
-#: builtin/merge.c:212 builtin/pull.c:155
+#: builtin/merge.c:214 builtin/pull.c:160
 msgid "perform a commit if the merge succeeds (default)"
 msgstr "병합이 성공하면 커밋을 합니다 (기본값)"
 
-#: builtin/merge.c:214 builtin/pull.c:158
+#: builtin/merge.c:216 builtin/pull.c:163
 msgid "edit message before committing"
 msgstr "커밋 전에 메시지를 편집합니다"
 
-#: builtin/merge.c:215
+#: builtin/merge.c:217
 msgid "allow fast-forward (default)"
 msgstr "정방향 진행을 허용합니다 (기본값)"
 
-#: builtin/merge.c:217 builtin/pull.c:164
+#: builtin/merge.c:219 builtin/pull.c:169
 msgid "abort if fast-forward is not possible"
 msgstr "정방향 진행이 불가능하면 중지합니다"
 
-#: builtin/merge.c:221 builtin/pull.c:167
+#: builtin/merge.c:223 builtin/pull.c:172
 msgid "verify that the named commit has a valid GPG signature"
 msgstr "지정한 커밋에 올바른 GPG 서명이 있는지 검증합니다"
 
-#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171
+#: builtin/merge.c:224 builtin/notes.c:777 builtin/pull.c:176
 #: builtin/revert.c:109
 msgid "strategy"
 msgstr "전략"
 
-#: builtin/merge.c:223 builtin/pull.c:172
+#: builtin/merge.c:225 builtin/pull.c:177
 msgid "merge strategy to use"
 msgstr "사용할 병합 전략"
 
-#: builtin/merge.c:224 builtin/pull.c:175
+#: builtin/merge.c:226 builtin/pull.c:180
 msgid "option=value"
 msgstr "옵션=값"
 
-#: builtin/merge.c:225 builtin/pull.c:176
+#: builtin/merge.c:227 builtin/pull.c:181
 msgid "option for selected merge strategy"
 msgstr "선택한 병합 전략에 대한 옵션"
 
-#: builtin/merge.c:227
+#: builtin/merge.c:229
 msgid "merge commit message (for a non-fast-forward merge)"
 msgstr "병합 커밋 메시지 (정방향이 아닌 병합에 대해)"
 
-#: builtin/merge.c:231
+#: builtin/merge.c:233
 msgid "abort the current in-progress merge"
 msgstr "현재 진행 중인 병합을 중지합니다"
 
-#: builtin/merge.c:233
+#: builtin/merge.c:235
 msgid "continue the current in-progress merge"
 msgstr "현재 진행 중인 병합을 계속합니다"
 
-#: builtin/merge.c:235 builtin/pull.c:183
+#: builtin/merge.c:237 builtin/pull.c:188
 msgid "allow merging unrelated histories"
 msgstr "관계 없는 커밋 내역의 병합을 허용합니다"
 
-#: builtin/merge.c:241
+#: builtin/merge.c:243
 msgid "verify commit-msg hook"
 msgstr "커밋 메시지 후크를 검증합니다"
 
-#: builtin/merge.c:266
+#: builtin/merge.c:268
 msgid "could not run stash."
 msgstr "stash를 실행할 수 없습니다."
 
-#: builtin/merge.c:271
+#: builtin/merge.c:273
 msgid "stash failed"
 msgstr "스태시 실패"
 
-#: builtin/merge.c:276
+#: builtin/merge.c:278
 #, c-format
 msgid "not a valid object: %s"
 msgstr "올바른 오브젝트가 아닙니다: %s"
 
-#: builtin/merge.c:298 builtin/merge.c:315
+#: builtin/merge.c:300 builtin/merge.c:317
 msgid "read-tree failed"
 msgstr "read-tree 실패"
 
-#: builtin/merge.c:345
+#: builtin/merge.c:347
 msgid " (nothing to squash)"
 msgstr " (합칠 내용이 없습니다)"
 
-#: builtin/merge.c:356
+#: builtin/merge.c:358
 #, c-format
 msgid "Squash commit -- not updating HEAD\n"
 msgstr "커밋 합치기 -- HEAD를 업데이트하지 않습니다\n"
 
-#: builtin/merge.c:406
+#: builtin/merge.c:408
 #, c-format
 msgid "No merge message -- not updating HEAD\n"
 msgstr "병합 메시지가 없습니다 -- HEAD를 업데이트하지 않습니다\n"
 
-#: builtin/merge.c:456
+#: builtin/merge.c:458
 #, c-format
 msgid "'%s' does not point to a commit"
 msgstr "'%s'이(가) 커밋을 가리키지 않습니다"
 
-#: builtin/merge.c:546
+#: builtin/merge.c:548
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "잘못된 branch.%s.mergeoptions 문자열: %s"
 
-#: builtin/merge.c:668
+#: builtin/merge.c:669
 msgid "Not handling anything other than two heads merge."
 msgstr "두 개의 헤드 병합 외에는 처리하지 않습니다."
 
-#: builtin/merge.c:682
+#: builtin/merge.c:683
 #, c-format
 msgid "Unknown option for merge-recursive: -X%s"
 msgstr "merge-recursive에 대해 알 수 없는 옵션: -X%s"
 
-#: builtin/merge.c:697
+#: builtin/merge.c:698
 #, c-format
 msgid "unable to write %s"
 msgstr "%s에 쓸 수 없습니다"
@@ -10463,64 +10913,64 @@ msgstr ""
 msgid "Empty commit message."
 msgstr "빈 커밋 메시지."
 
-#: builtin/merge.c:820
+#: builtin/merge.c:819
 #, c-format
 msgid "Wonderful.\n"
 msgstr "훌륭합니다.\n"
 
-#: builtin/merge.c:873
+#: builtin/merge.c:872
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr "자동 병합이 실패했습니다. 충돌을 바로잡고 결과물을 커밋하십시오.\n"
 
-#: builtin/merge.c:912
+#: builtin/merge.c:911
 msgid "No current branch."
 msgstr "현재 브랜치가 없습니다."
 
-#: builtin/merge.c:914
+#: builtin/merge.c:913
 msgid "No remote for the current branch."
 msgstr "현재 브랜치에 대한 리모트가 없습니다."
 
-#: builtin/merge.c:916
+#: builtin/merge.c:915
 msgid "No default upstream defined for the current branch."
 msgstr "현재 브랜치에 대해 기본 업스트림을 지정하지 않았습니다."
 
-#: builtin/merge.c:921
+#: builtin/merge.c:920
 #, c-format
 msgid "No remote-tracking branch for %s from %s"
 msgstr "리모트 %2$s에서 %1$s에 대한 리모트 추적 브랜치가 없습니다"
 
-#: builtin/merge.c:974
+#: builtin/merge.c:973
 #, c-format
 msgid "Bad value '%s' in environment '%s'"
 msgstr "잘못된 값 '%s', 환경 '%s'"
 
-#: builtin/merge.c:1076
+#: builtin/merge.c:1075
 #, c-format
 msgid "not something we can merge in %s: %s"
 msgstr "%s 안에서 병합할 수 있는 항목이 아닙니다: %s"
 
-#: builtin/merge.c:1110
+#: builtin/merge.c:1109
 msgid "not something we can merge"
 msgstr "병합할 수 있는 항목이 아닙니다"
 
-#: builtin/merge.c:1212
+#: builtin/merge.c:1211
 msgid "--abort expects no arguments"
 msgstr "--abort 옵션은 인자를 받지 않습니다"
 
-#: builtin/merge.c:1216
+#: builtin/merge.c:1215
 msgid "There is no merge to abort (MERGE_HEAD missing)."
 msgstr "중지할 병합 작업이 없습니다. (MERGE_HEAD가 없음)"
 
-#: builtin/merge.c:1228
+#: builtin/merge.c:1227
 msgid "--continue expects no arguments"
 msgstr "--continue 옵션은 인자를 받지 않습니다"
 
-#: builtin/merge.c:1232
+#: builtin/merge.c:1231
 msgid "There is no merge in progress (MERGE_HEAD missing)."
 msgstr "진행 중인 병합 작업이 없습니다. (MERGE_HEAD가 없음)"
 
-#: builtin/merge.c:1248
+#: builtin/merge.c:1247
 msgid ""
 "You have not concluded your merge (MERGE_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10528,7 +10978,7 @@ msgstr ""
 "병합을 마치지 않았습니다. (MERGE_HEAD 있음)\n"
 "병합하기 전에 변경 사항을 커밋하십시오."
 
-#: builtin/merge.c:1255
+#: builtin/merge.c:1254
 msgid ""
 "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10536,112 +10986,112 @@ msgstr ""
 "커밋 빼오기를 마치지 않았습니다. (COMMIT_PICK_HEAD 있음)\n"
 "병합하기 전에 변경 사항을 커밋하십시오."
 
-#: builtin/merge.c:1258
+#: builtin/merge.c:1257
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
 msgstr "커밋 빼오기를 마치지 않았습니다. (CHERRY_PICK_HEAD 있음)"
 
-#: builtin/merge.c:1267
+#: builtin/merge.c:1266
 msgid "You cannot combine --squash with --no-ff."
 msgstr "--squash 옵션을 --no-ff 옵션과 같이 쓸 수 없습니다."
 
-#: builtin/merge.c:1275
+#: builtin/merge.c:1274
 msgid "No commit specified and merge.defaultToUpstream not set."
 msgstr "커밋을 지정하지 않았고  merge.defaultToUpstream를 설정하지 않았습니다."
 
-#: builtin/merge.c:1292
+#: builtin/merge.c:1291
 msgid "Squash commit into empty head not supported yet"
 msgstr "빈 헤드로 커밋을 합치기는 지원하지 않습니다"
 
-#: builtin/merge.c:1294
+#: builtin/merge.c:1293
 msgid "Non-fast-forward commit does not make sense into an empty head"
 msgstr "정방향이 아닌 커밋은 빈 헤드에서는 앞뒤가 맞지 않습니다"
 
-#: builtin/merge.c:1299
+#: builtin/merge.c:1298
 #, c-format
 msgid "%s - not something we can merge"
 msgstr "%s - 병합할 수 있는 항목이 아닙니다"
 
-#: builtin/merge.c:1301
+#: builtin/merge.c:1300
 msgid "Can merge only exactly one commit into empty head"
 msgstr "빈 헤드에는 정확히 하나의 커밋만 병합할 수 있습니다"
 
-#: builtin/merge.c:1335
+#: builtin/merge.c:1334
 #, c-format
 msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
 msgstr "%s 커밋에 신뢰하지 않는 (서명자가 %s라고 하는) GPG 서명이 있습니다."
 
-#: builtin/merge.c:1338
+#: builtin/merge.c:1337
 #, c-format
 msgid "Commit %s has a bad GPG signature allegedly by %s."
 msgstr "%s 커밋에 잘못된 (서명자가 %s라고 하는) GPG 서명이 있습니다."
 
-#: builtin/merge.c:1341
+#: builtin/merge.c:1340
 #, c-format
 msgid "Commit %s does not have a GPG signature."
 msgstr "%s 커밋에 GPG 서명이 없습니다."
 
-#: builtin/merge.c:1344
+#: builtin/merge.c:1343
 #, c-format
 msgid "Commit %s has a good GPG signature by %s\n"
 msgstr "%s 커밋에 %s의 올바른 GPG 서명이 없습니다\n"
 
-#: builtin/merge.c:1403
+#: builtin/merge.c:1402
 msgid "refusing to merge unrelated histories"
 msgstr "관계 없는 커밋 내역의 병합을 거부합니다"
 
-#: builtin/merge.c:1412
+#: builtin/merge.c:1411
 msgid "Already up to date."
 msgstr "이미 업데이트 상태입니다."
 
-#: builtin/merge.c:1422
+#: builtin/merge.c:1421
 #, c-format
 msgid "Updating %s..%s\n"
 msgstr "업데이트 중 %s..%s\n"
 
-#: builtin/merge.c:1463
+#: builtin/merge.c:1462
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
 msgstr "아주 간단한 인덱스 내부 병합을 시도합니다...\n"
 
-#: builtin/merge.c:1470
+#: builtin/merge.c:1469
 #, c-format
 msgid "Nope.\n"
 msgstr "아님.\n"
 
-#: builtin/merge.c:1495
+#: builtin/merge.c:1494
 msgid "Already up to date. Yeeah!"
 msgstr "이미 업데이트 상태입니다. 야호!"
 
-#: builtin/merge.c:1501
+#: builtin/merge.c:1500
 msgid "Not possible to fast-forward, aborting."
 msgstr "정방향이 불가능하므로, 중지합니다."
 
-#: builtin/merge.c:1524 builtin/merge.c:1603
+#: builtin/merge.c:1523 builtin/merge.c:1602
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
 msgstr "트리를 본래 위치로 되돌립니다...\n"
 
-#: builtin/merge.c:1528
+#: builtin/merge.c:1527
 #, c-format
 msgid "Trying merge strategy %s...\n"
 msgstr "병합 전략 %s 시도...\n"
 
-#: builtin/merge.c:1594
+#: builtin/merge.c:1593
 #, c-format
 msgid "No merge strategy handled the merge.\n"
 msgstr "병합을 처리한 전략이 없습니다.\n"
 
-#: builtin/merge.c:1596
+#: builtin/merge.c:1595
 #, c-format
 msgid "Merge with strategy %s failed.\n"
 msgstr "전략 %s(으)로 병합이 실패했습니다.\n"
 
-#: builtin/merge.c:1605
+#: builtin/merge.c:1604
 #, c-format
 msgid "Using the %s to prepare resolving by hand.\n"
 msgstr "수동 해결의 준비를 위해 %s 전략을 사용합니다.\n"
 
-#: builtin/merge.c:1617
+#: builtin/merge.c:1616
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr "자동 병합이 잘 진행되었습니다. 요청한대로 커밋 전에 중지합니다\n"
@@ -10776,25 +11226,25 @@ msgstr "여러개 트리 만들기를 허용합니다"
 msgid "git mv [<options>] <source>... <destination>"
 msgstr "git mv [<옵션>] <원본>... <대상>"
 
-#: builtin/mv.c:83
+#: builtin/mv.c:82
 #, c-format
 msgid "Directory %s is in index and no submodule?"
 msgstr "%s 디렉터리가 인덱스에 있고 하위 모듈이 없습니다?"
 
-#: builtin/mv.c:85 builtin/rm.c:289
+#: builtin/mv.c:84 builtin/rm.c:288
 msgid "Please stage your changes to .gitmodules or stash them to proceed"
 msgstr "계속하려면 .gitmodules의 변경 사항을 스테이지에 넣거나 스태시 하십시오"
 
-#: builtin/mv.c:103
+#: builtin/mv.c:102
 #, c-format
 msgid "%.*s is in index"
 msgstr "%.*s이(가) 인덱스에 있습니다"
 
-#: builtin/mv.c:125
+#: builtin/mv.c:124
 msgid "force move/rename even if target exists"
 msgstr "대상이 이미 있어도 강제로 옮기기/이름 바꾸기를 합니다"
 
-#: builtin/mv.c:127
+#: builtin/mv.c:126
 msgid "skip move/rename errors"
 msgstr "옮기기/이름 바꾸기 오류를 건너 뜁니다"
 
@@ -10859,7 +11309,7 @@ msgstr "%s, 원본=%s, 대상=%s"
 msgid "Renaming %s to %s\n"
 msgstr "이름 바꾸기, '%s'에서 '%s'(으)로\n"
 
-#: builtin/mv.c:276 builtin/remote.c:712 builtin/repack.c:394
+#: builtin/mv.c:276 builtin/remote.c:715 builtin/repack.c:409
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "'%s'의 이름 바꾸기가 실패했습니다"
@@ -11050,12 +11500,12 @@ msgstr "노트 오브젝트를 쓸 수 없습니다"
 msgid "the note contents have been left in %s"
 msgstr "노트 내용은 %s에 남습니다"
 
-#: builtin/notes.c:234 builtin/tag.c:506
+#: builtin/notes.c:234 builtin/tag.c:507
 #, c-format
 msgid "cannot read '%s'"
 msgstr "'%s'을(를) 읽을 수 없습니다"
 
-#: builtin/notes.c:236 builtin/tag.c:509
+#: builtin/notes.c:236 builtin/tag.c:510
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "'%s'을(를) 열거나 읽을 수 없습니다"
@@ -11300,7 +11750,7 @@ msgstr "없는 노트를 제거하려는 시도를 오류가 아닌 것으로 
 msgid "read object names from the standard input"
 msgstr "표준 입력에서 오브젝트 이름을 읽습니다"
 
-#: builtin/notes.c:943 builtin/prune.c:106 builtin/worktree.c:160
+#: builtin/notes.c:943 builtin/prune.c:107 builtin/worktree.c:151
 msgid "do not remove, show only"
 msgstr "제거하지 않고, 보여주기만 합니다"
 
@@ -11321,213 +11771,240 @@ msgstr "<노트-레퍼런스>에서 노트를 사용합니다"
 msgid "unknown subcommand: %s"
 msgstr "알 수 없는 하위 명령: %s"
 
-#: builtin/pack-objects.c:33
+#: builtin/pack-objects.c:48
 msgid ""
 "git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
 msgstr ""
 "git pack-objects --stdout [<옵션>...] [< <레퍼런스목록> | < <오브젝트목록>]"
 
-#: builtin/pack-objects.c:34
+#: builtin/pack-objects.c:49
 msgid ""
 "git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
 msgstr ""
 "git pack-objects [<옵션>...] <베이스이름> [< <레퍼런스목록> | < <오브젝트목록"
 ">]"
 
-#: builtin/pack-objects.c:195 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:211 builtin/pack-objects.c:214
 #, c-format
 msgid "deflate error (%d)"
 msgstr "deflate 오류 (%d)"
 
-#: builtin/pack-objects.c:791
+#: builtin/pack-objects.c:810
 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
 msgstr ""
 "배트맵 쓰기를 하지 않습니다. 묶음은 pack.packSizeLimit 값에 따라 쪼개집니다"
 
-#: builtin/pack-objects.c:804
+#: builtin/pack-objects.c:823
 msgid "Writing objects"
 msgstr "오브젝트 쓰는 중"
 
-#: builtin/pack-objects.c:1084
+#: builtin/pack-objects.c:1106
 msgid "disabling bitmap writing, as some objects are not being packed"
 msgstr "묶음에 들어있지 않은 오브젝트가 있으므로, 비트맵 쓰기를 하지 않습니다"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:1765
+msgid "Counting objects"
+msgstr "오브젝트 개수 세는 중"
+
+#: builtin/pack-objects.c:1895
+#, c-format
+msgid "unable to get size of %s"
+msgstr "%s의 크기를 알아낼 수 없습니다"
+
+#: builtin/pack-objects.c:1910
+#, c-format
+msgid "unable to parse object header of %s"
+msgstr "%s의 오브젝트 헤더를 파싱할 수 없습니다"
+
+#: builtin/pack-objects.c:2564
 msgid "Compressing objects"
 msgstr "오브젝트 압축하는 중"
 
-#: builtin/pack-objects.c:2625
+#: builtin/pack-objects.c:2735
 msgid "invalid value for --missing"
 msgstr "--missing의 값이 올바르지 않습니다"
 
-#: builtin/pack-objects.c:2928
+#: builtin/pack-objects.c:3067
 #, c-format
 msgid "unsupported index version %s"
 msgstr "지원하지 않는 인덱스 버전 %s"
 
-#: builtin/pack-objects.c:2932
+#: builtin/pack-objects.c:3071
 #, c-format
 msgid "bad index version '%s'"
 msgstr "잘못된 인덱스 버전 '%s'"
 
-#: builtin/pack-objects.c:2962
+#: builtin/pack-objects.c:3102
 msgid "do not show progress meter"
 msgstr "진행률을 표시하지 않습니다"
 
-#: builtin/pack-objects.c:2964
+#: builtin/pack-objects.c:3104
 msgid "show progress meter"
 msgstr "진행률을 표시합니다"
 
-#: builtin/pack-objects.c:2966
+#: builtin/pack-objects.c:3106
 msgid "show progress meter during object writing phase"
 msgstr "오브젝트 쓰기 단계에서 진행률을 표시합니다"
 
-#: builtin/pack-objects.c:2969
+#: builtin/pack-objects.c:3109
 msgid "similar to --all-progress when progress meter is shown"
 msgstr "진행률이 표시될 때 --all-progress와 비슷합니다"
 
-#: builtin/pack-objects.c:2970
+#: builtin/pack-objects.c:3110
 msgid "version[,offset]"
 msgstr "버전[,오프셋]"
 
-#: builtin/pack-objects.c:2971
+#: builtin/pack-objects.c:3111
 msgid "write the pack index file in the specified idx format version"
 msgstr "지정한 버전의 인덱스 형식에 따라 묶음 인덱스 파일을 씁니다"
 
-#: builtin/pack-objects.c:2974
+#: builtin/pack-objects.c:3114
 msgid "maximum size of each output pack file"
 msgstr "출력 묶음 파일의 최대 크기"
 
-#: builtin/pack-objects.c:2976
+#: builtin/pack-objects.c:3116
 msgid "ignore borrowed objects from alternate object store"
 msgstr "보조 오브젝트 저장소에서 빌려온 오브젝트를 무시합니다"
 
-#: builtin/pack-objects.c:2978
+#: builtin/pack-objects.c:3118
 msgid "ignore packed objects"
 msgstr "묶음 오브젝트를 무시합니다"
 
-#: builtin/pack-objects.c:2980
+#: builtin/pack-objects.c:3120
 msgid "limit pack window by objects"
 msgstr "묶음 윈도우를 오브젝트 단위로 제한합니다"
 
-#: builtin/pack-objects.c:2982
+#: builtin/pack-objects.c:3122
 msgid "limit pack window by memory in addition to object limit"
 msgstr "묶음 윈도우를 오브젝트 단위에 추가로 메모리 단위로 제한합니다"
 
-#: builtin/pack-objects.c:2984
+#: builtin/pack-objects.c:3124
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr "결과물 묶음에서 허용되는 최대 길이의 델타 체인"
 
-#: builtin/pack-objects.c:2986
+#: builtin/pack-objects.c:3126
 msgid "reuse existing deltas"
 msgstr "기존 델타를 재사용합니다"
 
-#: builtin/pack-objects.c:2988
+#: builtin/pack-objects.c:3128
 msgid "reuse existing objects"
 msgstr "기존 오브젝트를 재사용합니다"
 
-#: builtin/pack-objects.c:2990
+#: builtin/pack-objects.c:3130
 msgid "use OFS_DELTA objects"
 msgstr "OFS_DELTA 오브젝트를 사용합니다"
 
-#: builtin/pack-objects.c:2992
+#: builtin/pack-objects.c:3132
 msgid "use threads when searching for best delta matches"
 msgstr "최상의 델타 일치를 검색하는데 스레드를 사용합니다"
 
-#: builtin/pack-objects.c:2994
+#: builtin/pack-objects.c:3134
 msgid "do not create an empty pack output"
 msgstr "빈 묶음 출력을 만들지 않습니다"
 
-#: builtin/pack-objects.c:2996
+#: builtin/pack-objects.c:3136
 msgid "read revision arguments from standard input"
 msgstr "표준 입력에서 리비전 인자를 읽습니다"
 
-#: builtin/pack-objects.c:2998
+#: builtin/pack-objects.c:3138
 msgid "limit the objects to those that are not yet packed"
 msgstr "묶지 않는 오브젝트 수를 제한합니다"
 
-#: builtin/pack-objects.c:3001
+#: builtin/pack-objects.c:3141
 msgid "include objects reachable from any reference"
 msgstr "모든 레퍼런스에서 접근 가능한 오브젝트를 포함합니다"
 
-#: builtin/pack-objects.c:3004
+#: builtin/pack-objects.c:3144
 msgid "include objects referred by reflog entries"
 msgstr "reflog 항목에서 레퍼런스할 수 있는 오브젝트를 포함합니다"
 
-#: builtin/pack-objects.c:3007
+#: builtin/pack-objects.c:3147
 msgid "include objects referred to by the index"
 msgstr "인덱스에서< 레퍼런스하는 오브젝트를 포함합니다"
 
-#: builtin/pack-objects.c:3010
+#: builtin/pack-objects.c:3150
 msgid "output pack to stdout"
 msgstr "묶음을 표준 출력으로 출력합니다"
 
-#: builtin/pack-objects.c:3012
+#: builtin/pack-objects.c:3152
 msgid "include tag objects that refer to objects to be packed"
 msgstr "묶음에 들어갈 오브젝트를 레퍼런스하는 태그 오브젝트를 포함합니다"
 
-#: builtin/pack-objects.c:3014
+#: builtin/pack-objects.c:3154
 msgid "keep unreachable objects"
 msgstr "접근 불가능 오브젝트를 보존합니다"
 
-#: builtin/pack-objects.c:3016
+#: builtin/pack-objects.c:3156
 msgid "pack loose unreachable objects"
 msgstr "느슨한 접근 불가능 오브젝트를 묶습니다"
 
-#: builtin/pack-objects.c:3018
+#: builtin/pack-objects.c:3158
 msgid "unpack unreachable objects newer than <time>"
 msgstr "<시각>보다 새로운 접근 불가능 오브젝트의 묶음을 풉니다"
 
-#: builtin/pack-objects.c:3021
+#: builtin/pack-objects.c:3161
 msgid "create thin packs"
 msgstr "얇은 묶음을 만듭니다"
 
-#: builtin/pack-objects.c:3023
+#: builtin/pack-objects.c:3163
 msgid "create packs suitable for shallow fetches"
 msgstr "얕은 가져오기에 적합한 묶음을 만듭니다"
 
-#: builtin/pack-objects.c:3025
+#: builtin/pack-objects.c:3165
 msgid "ignore packs that have companion .keep file"
 msgstr "해당하는 .keep 파일이 있는 묶음을 무시합니다"
 
-#: builtin/pack-objects.c:3027
+#: builtin/pack-objects.c:3167
+msgid "ignore this pack"
+msgstr "이 묶음을 무시합니다"
+
+#: builtin/pack-objects.c:3169
 msgid "pack compression level"
 msgstr "묶음 압축 단계"
 
-# FIXME: graft?
-#: builtin/pack-objects.c:3029
+#: builtin/pack-objects.c:3171
 msgid "do not hide commits by grafts"
-msgstr "붙어 있는 커밋을 숨기지 않습니다"
+msgstr "그래프트로 발생한 커밋을 숨기지 않습니다"
 
-#: builtin/pack-objects.c:3031
+#: builtin/pack-objects.c:3173
 msgid "use a bitmap index if available to speed up counting objects"
 msgstr "가능하면 비트맵 인덱스를 사용해 오브젝트 세기 속도를 높입니다"
 
-#: builtin/pack-objects.c:3033
+#: builtin/pack-objects.c:3175
 msgid "write a bitmap index together with the pack index"
 msgstr "묶음 인덱스와 같이 비트맵 인덱스를 씁니다"
 
-#: builtin/pack-objects.c:3036
+#: builtin/pack-objects.c:3178
 msgid "handling for missing objects"
 msgstr "없는 오브젝트를 처리합니다"
 
-#: builtin/pack-objects.c:3039
+#: builtin/pack-objects.c:3181
 msgid "do not pack objects in promisor packfiles"
 msgstr "프라미서 묶음 파일에 오브젝트를 묶지 않습니다"
 
-#: builtin/pack-objects.c:3178
-msgid "Counting objects"
-msgstr "오브젝트 개수 세는 중"
+#: builtin/pack-objects.c:3205
+#, c-format
+msgid "delta chain depth %d is too deep, forcing %d"
+msgstr "델타 체인 깊이 값이 (%d) 너무 큽니다. %d 값으로 조정합니다"
 
-#: builtin/pack-refs.c:6
+#: builtin/pack-objects.c:3210
+#, c-format
+msgid "pack.deltaCacheLimit is too high, forcing %d"
+msgstr "pack.deltaCacheLimit 값이 너무 큽니다. %d 값으로 조정합니다"
+
+#: builtin/pack-objects.c:3338
+msgid "Enumerating objects"
+msgstr "오브젝트 나열하는 중"
+
+#: builtin/pack-refs.c:7
 msgid "git pack-refs [<options>]"
 msgstr "git pack-refs [<옵션>]"
 
-#: builtin/pack-refs.c:14
+#: builtin/pack-refs.c:15
 msgid "pack everything"
 msgstr "모두 묶습니다"
 
-#: builtin/pack-refs.c:15
+#: builtin/pack-refs.c:16
 msgid "prune loose refs (default)"
 msgstr "느슨한 레퍼런스를 잘라냅니다 (기본값)"
 
@@ -11543,76 +12020,76 @@ msgstr "중복된 오브젝트 제거"
 msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]"
 msgstr "git prune [-n] [-v] [--progress] [--expire <시각>] [--] [<헤드>...]"
 
-#: builtin/prune.c:107
+#: builtin/prune.c:108
 msgid "report pruned objects"
 msgstr "잘라낸 오브젝트를 알립니다"
 
-#: builtin/prune.c:110
+#: builtin/prune.c:111
 msgid "expire objects older than <time>"
 msgstr "<시각>보다 오래 된 오브젝트를 만료합니다"
 
-#: builtin/prune.c:112
+#: builtin/prune.c:113
 msgid "limit traversal to objects outside promisor packfiles"
 msgstr "프라미서 묶음파일 밖에서 오브젝트 찾지 않습니다"
 
-#: builtin/prune.c:126
+#: builtin/prune.c:127
 msgid "cannot prune in a precious-objects repo"
 msgstr "precious-objects 저장소에서 잘라낼 수 없습니다"
 
-#: builtin/pull.c:54 builtin/pull.c:56
+#: builtin/pull.c:59 builtin/pull.c:61
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "%s의 값이 올바르지 않습니다: %s"
 
-#: builtin/pull.c:76
+#: builtin/pull.c:81
 msgid "git pull [<options>] [<repository> [<refspec>...]]"
 msgstr "git pull [<옵션>] [<저장소> [<레퍼런스명세>...]]"
 
-#: builtin/pull.c:127
+#: builtin/pull.c:132
 msgid "control for recursive fetching of submodules"
 msgstr "하위 모듈 재귀적으로 가져오기 방식을 조정합니다"
 
-#: builtin/pull.c:131
+#: builtin/pull.c:136
 msgid "Options related to merging"
 msgstr "병합 관련 옵션"
 
-#: builtin/pull.c:134
+#: builtin/pull.c:139
 msgid "incorporate changes by rebasing rather than merging"
 msgstr "변경 사항을 적용할 때 병합하는 대신 리베이스합니다"
 
-#: builtin/pull.c:161 builtin/rebase--helper.c:23 builtin/revert.c:121
+#: builtin/pull.c:166 builtin/rebase--helper.c:23 builtin/revert.c:121
 msgid "allow fast-forward"
 msgstr "정방향 진행을 허용합니다"
 
-#: builtin/pull.c:170
+#: builtin/pull.c:175
 msgid "automatically stash/stash pop before and after rebase"
 msgstr "리베이스 전과 후에 stash 및 stash pop을 자동으로 합니다"
 
-#: builtin/pull.c:186
+#: builtin/pull.c:191
 msgid "Options related to fetching"
 msgstr "가져오기 관련 옵션"
 
-#: builtin/pull.c:204
+#: builtin/pull.c:209
 msgid "number of submodules pulled in parallel"
 msgstr "병렬적으로 풀을 실행할 하위모듈 개수"
 
-#: builtin/pull.c:299
+#: builtin/pull.c:304
 #, c-format
 msgid "Invalid value for pull.ff: %s"
 msgstr "pull.ff에 대해 잘못된 값: %s"
 
-#: builtin/pull.c:415
+#: builtin/pull.c:420
 msgid ""
 "There is no candidate for rebasing against among the refs that you just "
 "fetched."
 msgstr "가져온 레퍼런스 중에 리베이스할 대상 후보가 없습니다."
 
-#: builtin/pull.c:417
+#: builtin/pull.c:422
 msgid ""
 "There are no candidates for merging among the refs that you just fetched."
 msgstr "가져온 레퍼런스 중에 병합할 대상 후보가 없습니다."
 
-#: builtin/pull.c:418
+#: builtin/pull.c:423
 msgid ""
 "Generally this means that you provided a wildcard refspec which had no\n"
 "matches on the remote end."
@@ -11620,7 +12097,7 @@ msgstr ""
 "보통 이런 경우는 리모트 쪽에는 없는 와일드카드 레퍼런스명세가\n"
 "주어졌을 때 일어납니다."
 
-#: builtin/pull.c:421
+#: builtin/pull.c:426
 #, c-format
 msgid ""
 "You asked to pull from the remote '%s', but did not specify\n"
@@ -11631,42 +12108,42 @@ msgstr ""
 "이 리모트는 현재 브랜치에 대해 기본으로 설정된 리모트가\n"
 "아니기 때문에, 명령행에서 브랜치를 지정해야 합니다."
 
-#: builtin/pull.c:426 git-parse-remote.sh:73
+#: builtin/pull.c:431 git-parse-remote.sh:73
 msgid "You are not currently on a branch."
 msgstr "현재 어떤 브랜치 위에도 있지 않습니다."
 
-#: builtin/pull.c:428 builtin/pull.c:443 git-parse-remote.sh:79
+#: builtin/pull.c:433 builtin/pull.c:448 git-parse-remote.sh:79
 msgid "Please specify which branch you want to rebase against."
 msgstr "어떤 브랜치를 대상으로 리베이스할지 지정하십시오."
 
-#: builtin/pull.c:430 builtin/pull.c:445 git-parse-remote.sh:82
+#: builtin/pull.c:435 builtin/pull.c:450 git-parse-remote.sh:82
 msgid "Please specify which branch you want to merge with."
 msgstr "어떤 브랜치를 대상으로 병합할지 지정하십시오."
 
-#: builtin/pull.c:431 builtin/pull.c:446
+#: builtin/pull.c:436 builtin/pull.c:451
 msgid "See git-pull(1) for details."
 msgstr "자세한 정보는 git-pull(1) 페이지를 참고하십시오."
 
-#: builtin/pull.c:433 builtin/pull.c:439 builtin/pull.c:448
+#: builtin/pull.c:438 builtin/pull.c:444 builtin/pull.c:453
 #: git-parse-remote.sh:64
 msgid "<remote>"
 msgstr "<리모트>"
 
-#: builtin/pull.c:433 builtin/pull.c:448 builtin/pull.c:453 git-rebase.sh:477
+#: builtin/pull.c:438 builtin/pull.c:453 builtin/pull.c:458 git-rebase.sh:523
 #: git-parse-remote.sh:65
 msgid "<branch>"
 msgstr "<브랜치>"
 
-#: builtin/pull.c:441 git-parse-remote.sh:75
+#: builtin/pull.c:446 git-parse-remote.sh:75
 msgid "There is no tracking information for the current branch."
 msgstr "현재 브랜치에 추적 정보가 없습니다."
 
-#: builtin/pull.c:450 git-parse-remote.sh:95
+#: builtin/pull.c:455 git-parse-remote.sh:95
 msgid ""
 "If you wish to set tracking information for this branch you can do so with:"
 msgstr "이 브랜치에 대한 추적 정보를 설정하려면 다음과 같이 할 수 있습니다:"
 
-#: builtin/pull.c:455
+#: builtin/pull.c:460
 #, c-format
 msgid ""
 "Your configuration specifies to merge with the ref '%s'\n"
@@ -11675,27 +12152,27 @@ msgstr ""
 "설정에서 리모트의 '%s' 레퍼런스와 병합하도록 지정했지만,\n"
 "그런 레퍼런스를 가져오지 않았습니다."
 
-#: builtin/pull.c:819
+#: builtin/pull.c:826
 msgid "ignoring --verify-signatures for rebase"
 msgstr "리베이스에 대해 --verify-signatures 옵션을 무시합니다"
 
-#: builtin/pull.c:867
+#: builtin/pull.c:874
 msgid "--[no-]autostash option is only valid with --rebase."
 msgstr "--[no-]autostash 옵션은 --rebase 옵션과 같이 써야 합니다."
 
-#: builtin/pull.c:875
+#: builtin/pull.c:882
 msgid "Updating an unborn branch with changes added to the index."
 msgstr "만들어지지 않은 브랜치를 인덱스에 추가된 변경 사항으로 업데이트합니다."
 
-#: builtin/pull.c:878
+#: builtin/pull.c:885
 msgid "pull with rebase"
 msgstr "리베이스로 풀하기"
 
-#: builtin/pull.c:879
+#: builtin/pull.c:886
 msgid "please commit or stash them."
 msgstr "커밋하거나 스태시에 넣으십시오."
 
-#: builtin/pull.c:904
+#: builtin/pull.c:911
 #, c-format
 msgid ""
 "fetch updated the current branch head.\n"
@@ -11706,7 +12183,7 @@ msgstr ""
 "작업 폴더를 %s 커밋에서 정방향\n"
 "진행합니다."
 
-#: builtin/pull.c:909
+#: builtin/pull.c:916
 #, c-format
 msgid ""
 "Cannot fast-forward your working tree.\n"
@@ -11723,31 +12200,31 @@ msgstr ""
 "$ git reset --hard\n"
 "복구됩니다."
 
-#: builtin/pull.c:924
+#: builtin/pull.c:931
 msgid "Cannot merge multiple branches into empty head."
 msgstr "여러 브랜치를 빈 헤드로 병합할 수 없습니다."
 
-#: builtin/pull.c:928
+#: builtin/pull.c:935
 msgid "Cannot rebase onto multiple branches."
 msgstr "여러 브랜치로 리베이스할 수 없습니다."
 
-#: builtin/pull.c:935
+#: builtin/pull.c:942
 msgid "cannot rebase with locally recorded submodule modifications"
 msgstr "로컬에서 기록한 하위 모듈 수정 사항을 이용해 리베이스할 수 없습니다"
 
-#: builtin/push.c:17
+#: builtin/push.c:19
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr "git push [<옵션>] [<저장소> [<레퍼런스명세>...]]"
 
-#: builtin/push.c:92
+#: builtin/push.c:111
 msgid "tag shorthand without <tag>"
 msgstr "<태그> 없이 태그 줄임"
 
-#: builtin/push.c:102
+#: builtin/push.c:121
 msgid "--delete only accepts plain target ref names"
 msgstr "--delete 옵션은 일반 대상 레퍼런스 이름만 받습니다"
 
-#: builtin/push.c:146
+#: builtin/push.c:165
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -11756,7 +12233,7 @@ msgstr ""
 "어느 한 쪽 옵션만 계속 선택하려면, 'git help config'에서 push.default를 참고"
 "하십시오."
 
-#: builtin/push.c:149
+#: builtin/push.c:168
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -11781,7 +12258,7 @@ msgstr ""
 "    git push %s %s\n"
 "%s"
 
-#: builtin/push.c:164
+#: builtin/push.c:183
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -11796,7 +12273,7 @@ msgstr ""
 "\n"
 "    git push %s HEAD:<name-of-remote-branch>\n"
 
-#: builtin/push.c:178
+#: builtin/push.c:197
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -11810,12 +12287,12 @@ msgstr ""
 "\n"
 "    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:186
+#: builtin/push.c:205
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr "현재 브랜치  %s에 여러 업스트림 브랜치가 있습니다. 푸시를 거절합니다."
 
-#: builtin/push.c:189
+#: builtin/push.c:208
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -11826,13 +12303,13 @@ msgstr ""
 "'%s' 브랜치의 업스트림이 아닙니다. 어떤 리모트 브랜치에 무엇을\n"
 "푸시할지 설정하지 않았습니다."
 
-#: builtin/push.c:248
+#: builtin/push.c:267
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
 "푸시할 레퍼런스명세를 지정하지 않았고, push.default 값이 'nothing'입니다."
 
-#: builtin/push.c:255
+#: builtin/push.c:274
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -11845,7 +12322,7 @@ msgstr ""
 "자세한 정보는 'git push --help'의 \"Note about fast-forwards' 부분을\n"
 "참고하십시오."
 
-#: builtin/push.c:261
+#: builtin/push.c:280
 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"
@@ -11858,7 +12335,7 @@ msgstr ""
 "자세한 정보는 'git push --help'의 \"Note about fast-forwards' 부분을\n"
 "참고하십시오."
 
-#: builtin/push.c:267
+#: builtin/push.c:286
 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"
@@ -11874,11 +12351,11 @@ msgstr ""
 "자세한 정보는 'git push --help'의 \"Note about fast-forwards' 부분을\n"
 "참고하십시오."
 
-#: builtin/push.c:274
+#: builtin/push.c:293
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr "리모트에 태그가 이미 있기 때문에 업데이트가 거부되었습니다."
 
-#: builtin/push.c:277
+#: builtin/push.c:296
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -11888,22 +12365,22 @@ msgstr ""
 "레퍼런스를 업데이트하거나, 커밋이 아닌 오브젝트를 가리키도록\n"
 "업데이트할 수 없습니다.\n"
 
-#: builtin/push.c:337
+#: builtin/push.c:357
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "다음에 푸시: %s\n"
 
-#: builtin/push.c:341
+#: builtin/push.c:361
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr "레퍼런스를 '%s'에 푸시하는데 실패했습니다"
 
-#: builtin/push.c:372
+#: builtin/push.c:395
 #, c-format
 msgid "bad repository '%s'"
 msgstr "잘못된 저장소 '%s'"
 
-#: builtin/push.c:373
+#: builtin/push.c:396
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -11924,112 +12401,104 @@ msgstr ""
 "\n"
 "    git push <name>\n"
 
-#: builtin/push.c:391
-msgid "--all and --tags are incompatible"
-msgstr "--all 및 --tags 옵션은 호환되지 않습니다"
-
-#: builtin/push.c:392
-msgid "--all can't be combined with refspecs"
-msgstr "--all 옵션은 레퍼런스명세와 같이 쓸 수 없습니다"
-
-#: builtin/push.c:397
-msgid "--mirror and --tags are incompatible"
-msgstr "--mirror 및 --tags 옵션은 호환되지 않습니다"
-
-#: builtin/push.c:398
-msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror 옵션은 레퍼런스명세와 같이 쓸 수 없습니다"
-
-#: builtin/push.c:403
-msgid "--all and --mirror are incompatible"
-msgstr "--all 및 --mirror 옵션은 호환되지 않습니다"
-
-#: builtin/push.c:535
+#: builtin/push.c:551
 msgid "repository"
 msgstr "저장소"
 
-#: builtin/push.c:536 builtin/send-pack.c:163
+#: builtin/push.c:552 builtin/send-pack.c:164
 msgid "push all refs"
 msgstr "모든 레퍼런스 푸시하기"
 
-#: builtin/push.c:537 builtin/send-pack.c:165
+#: builtin/push.c:553 builtin/send-pack.c:166
 msgid "mirror all refs"
 msgstr "모든 레퍼런스 미러"
 
-#: builtin/push.c:539
+#: builtin/push.c:555
 msgid "delete refs"
 msgstr "레퍼런스 삭제"
 
-#: builtin/push.c:540
+#: builtin/push.c:556
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr "태그 푸시하기 (--all 또는 --mirror 옵션과 같이 쓸 수 없음)"
 
-#: builtin/push.c:543 builtin/send-pack.c:166
+#: builtin/push.c:559 builtin/send-pack.c:167
 msgid "force updates"
 msgstr "강제로 업데이트"
 
-#: builtin/push.c:545 builtin/send-pack.c:180
+#: builtin/push.c:561 builtin/send-pack.c:181
 msgid "refname>:<expect"
 msgstr "레퍼런스이름>:<예상"
 
-#: builtin/push.c:546 builtin/send-pack.c:181
+#: builtin/push.c:562 builtin/send-pack.c:182
 msgid "require old value of ref to be at this value"
 msgstr "레퍼런스의 과거 값이 이 값이어야 합니다"
 
-#: builtin/push.c:549
+#: builtin/push.c:565
 msgid "control recursive pushing of submodules"
 msgstr "재귀적 하위 모듈 푸시 방식을 설정합니다"
 
-#: builtin/push.c:551 builtin/send-pack.c:174
+#: builtin/push.c:567 builtin/send-pack.c:175
 msgid "use thin pack"
 msgstr "얇은 묶음을 사용합니다"
 
-#: builtin/push.c:552 builtin/push.c:553 builtin/send-pack.c:160
-#: builtin/send-pack.c:161
+#: builtin/push.c:568 builtin/push.c:569 builtin/send-pack.c:161
+#: builtin/send-pack.c:162
 msgid "receive pack program"
 msgstr "receive pack 프로그램"
 
-#: builtin/push.c:554
+#: builtin/push.c:570
 msgid "set upstream for git pull/status"
 msgstr "git pull/status에 대한 업스트림을 설정합니다"
 
-#: builtin/push.c:557
+#: builtin/push.c:573
 msgid "prune locally removed refs"
 msgstr "로컬에서 제거한 레퍼런스를 잘라냅니다"
 
-#: builtin/push.c:559
+#: builtin/push.c:575
 msgid "bypass pre-push hook"
 msgstr "푸시 전 후크를 건너뜁니다"
 
-#: builtin/push.c:560
+#: builtin/push.c:576
 msgid "push missing but relevant tags"
 msgstr "빠졌지만 관련된 태그를 푸시합니다"
 
-#: builtin/push.c:563 builtin/send-pack.c:168
+#: builtin/push.c:579 builtin/send-pack.c:169
 msgid "GPG sign the push"
 msgstr "푸시에 GPG 서명"
 
-#: builtin/push.c:565 builtin/send-pack.c:175
+#: builtin/push.c:581 builtin/send-pack.c:176
 msgid "request atomic transaction on remote side"
 msgstr "리모트 쪽에 원자 트랜잭션을 요청합니다"
 
-#: builtin/push.c:566 builtin/send-pack.c:171
-msgid "server-specific"
-msgstr "서버-전용-옵션"
-
-#: builtin/push.c:566 builtin/send-pack.c:172
-msgid "option to transmit"
-msgstr "전송할 옵션"
-
-#: builtin/push.c:583
+#: builtin/push.c:599
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr "--delete 옵션은 --all, --mirror, --tags 옵션과 호환되지 않습니다"
 
-#: builtin/push.c:585
+#: builtin/push.c:601
 msgid "--delete doesn't make sense without any refs"
 msgstr "--delete 옵션은 레퍼런스 없이 앞뒤가 맞지 않습니다"
 
 #: builtin/push.c:604
+msgid "--all and --tags are incompatible"
+msgstr "--all 및 --tags 옵션은 호환되지 않습니다"
+
+#: builtin/push.c:606
+msgid "--all can't be combined with refspecs"
+msgstr "--all 옵션은 레퍼런스명세와 같이 쓸 수 없습니다"
+
+#: builtin/push.c:610
+msgid "--mirror and --tags are incompatible"
+msgstr "--mirror 및 --tags 옵션은 호환되지 않습니다"
+
+#: builtin/push.c:612
+msgid "--mirror can't be combined with refspecs"
+msgstr "--mirror 옵션은 레퍼런스명세와 같이 쓸 수 없습니다"
+
+#: builtin/push.c:615
+msgid "--all and --mirror are incompatible"
+msgstr "--all 및 --mirror 옵션은 호환되지 않습니다"
+
+#: builtin/push.c:634
 msgid "push options must not have new line characters"
 msgstr "푸시 옵션에는 줄바꿈 문자가 들어갈 수 없습니다"
 
@@ -12043,67 +12512,67 @@ msgstr ""
 "[-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--"
 "index-output=<파일>] (--empty | <트리-따위> [<트리-따위2> [<트리-따위3>]])"
 
-#: builtin/read-tree.c:121
+#: builtin/read-tree.c:120
 msgid "write resulting index to <file>"
 msgstr "결과 인덱스를 <파일>에 씁니다"
 
-#: builtin/read-tree.c:124
+#: builtin/read-tree.c:123
 msgid "only empty the index"
 msgstr "인덱스를 비우기만 합니다"
 
-#: builtin/read-tree.c:126
+#: builtin/read-tree.c:125
 msgid "Merging"
 msgstr "병합하기"
 
-#: builtin/read-tree.c:128
+#: builtin/read-tree.c:127
 msgid "perform a merge in addition to a read"
 msgstr "읽은 다음 병합을 수행합니다"
 
-#: builtin/read-tree.c:130
+#: builtin/read-tree.c:129
 msgid "3-way merge if no file level merging required"
 msgstr "파일 단위 병합이 필요하지 않으면 3-방향 병합을 합니다"
 
-#: builtin/read-tree.c:132
+#: builtin/read-tree.c:131
 msgid "3-way merge in presence of adds and removes"
 msgstr "추가와 제거가 있을 때 3-방향 병합을 합니다"
 
-#: builtin/read-tree.c:134
+#: builtin/read-tree.c:133
 msgid "same as -m, but discard unmerged entries"
 msgstr "-m과 동일하지만, 병합되지 않은 항목을 버립니다"
 
-#: builtin/read-tree.c:135
+#: builtin/read-tree.c:134
 msgid "<subdirectory>/"
 msgstr "<하위디렉터리>/"
 
-#: builtin/read-tree.c:136
+#: builtin/read-tree.c:135
 msgid "read the tree into the index under <subdirectory>/"
 msgstr "트리를 <하위디렉터리>/ 아래 인덱스로 읽습니다"
 
-#: builtin/read-tree.c:139
+#: builtin/read-tree.c:138
 msgid "update working tree with merge result"
 msgstr "작업 폴더를 병합 결과로 업데이트합니다"
 
-#: builtin/read-tree.c:141
+#: builtin/read-tree.c:140
 msgid "gitignore"
 msgstr "gitignore"
 
-#: builtin/read-tree.c:142
+#: builtin/read-tree.c:141
 msgid "allow explicitly ignored files to be overwritten"
 msgstr "무시하는 파일을 덮어쓰도록 명시적으로 허용합니다"
 
-#: builtin/read-tree.c:145
+#: builtin/read-tree.c:144
 msgid "don't check the working tree after merging"
 msgstr "병합 후에 작업 폴더를 확인하지 않습니다"
 
-#: builtin/read-tree.c:146
+#: builtin/read-tree.c:145
 msgid "don't update the index or the work tree"
 msgstr "인덱스나 작업 폴더를 업데이트하지 않습니다"
 
-#: builtin/read-tree.c:148
+#: builtin/read-tree.c:147
 msgid "skip applying sparse checkout filter"
 msgstr "드문 체크아웃 필터 적용을 건너뜁니다"
 
-#: builtin/read-tree.c:150
+#: builtin/read-tree.c:149
 msgid "debug unpack-trees"
 msgstr "unpack-trees 디버깅"
 
@@ -12120,47 +12589,60 @@ msgid "allow commits with empty messages"
 msgstr "빈 메시지로 커밋을 허용합니다"
 
 #: builtin/rebase--helper.c:27
+msgid "rebase merge commits"
+msgstr "병합 커밋을 리베이스합니다"
+
+#: builtin/rebase--helper.c:29
+msgid "keep original branch points of cousins"
+msgstr "관련된 본래 브랜치 위치를 유지합니다"
+
+#: builtin/rebase--helper.c:30
 msgid "continue rebase"
 msgstr "리베이스 계속"
 
-#: builtin/rebase--helper.c:29
+#: builtin/rebase--helper.c:32
 msgid "abort rebase"
 msgstr "리베이스를 중지합니다"
 
-#: builtin/rebase--helper.c:32
+#: builtin/rebase--helper.c:35
 msgid "make rebase script"
 msgstr "리베이스 스크립트를 만듭니다"
 
-#: builtin/rebase--helper.c:34
+#: builtin/rebase--helper.c:37
 msgid "shorten commit ids in the todo list"
 msgstr "할 일 목록의 커밋 아이디를 줄입니다."
 
-#: builtin/rebase--helper.c:36
+#: builtin/rebase--helper.c:39
 msgid "expand commit ids in the todo list"
 msgstr "할 일 목록의 커밋 아이디를 늘입니다."
 
-#: builtin/rebase--helper.c:38
+#: builtin/rebase--helper.c:41
 msgid "check the todo list"
 msgstr "할 일 목록을 확인합니다"
 
-#: builtin/rebase--helper.c:40
+#: builtin/rebase--helper.c:43
 msgid "skip unnecessary picks"
 msgstr "불필요한 빼오기를 건너뜁니다"
 
-#: builtin/rebase--helper.c:42
+#: builtin/rebase--helper.c:45
 msgid "rearrange fixup/squash lines"
 msgstr "fixup/squash 줄 재구성"
 
 # English Text에서는 insert를 사용하지만, 소스코드에는 add로 표현되어 있습니다.
-#: builtin/rebase--helper.c:44
+#: builtin/rebase--helper.c:47
 msgid "insert exec commands in todo list"
 msgstr "할 일 목록에 실행 명령을 추가합니다"
 
-#: builtin/receive-pack.c:30
+#: builtin/rebase--helper.c:68
+msgid "--[no-]rebase-cousins has no effect without --rebase-merges"
+msgstr ""
+"--[no-]rebase-cousins 옵션은 --rebase-merges 옵션 없이는 아무 효과가 없습니다"
+
+#: builtin/receive-pack.c:31
 msgid "git receive-pack <git-dir>"
 msgstr "git receive-pack <git-dir>"
 
-#: builtin/receive-pack.c:841
+#: builtin/receive-pack.c:842
 msgid ""
 "By default, updating the current branch in a non-bare repository\n"
 "is denied, because it will make the index and work tree inconsistent\n"
@@ -12187,7 +12669,7 @@ msgstr ""
 "이 메시지를 보지 않고 기본 동작을 계속 하려면,\n"
 "'receive.denyCurrentBranch' 설정 변수를 'refuse'로 설정하십시오."
 
-#: builtin/receive-pack.c:861
+#: builtin/receive-pack.c:862
 msgid ""
 "By default, deleting the current branch is denied, because the next\n"
 "'git clone' won't result in any file checked out, causing confusion.\n"
@@ -12207,11 +12689,11 @@ msgstr ""
 "\n"
 "이 메시지를 보지 않으려면, 이 설정 변수를 'refuse'로 설정하십시오."
 
-#: builtin/receive-pack.c:1934
+#: builtin/receive-pack.c:1935
 msgid "quiet"
 msgstr "출력 않기"
 
-#: builtin/receive-pack.c:1948
+#: builtin/receive-pack.c:1949
 msgid "You must specify a directory."
 msgstr "디렉터리를 지정해야 합니다."
 
@@ -12220,11 +12702,11 @@ msgstr "디렉터리를 지정해야 합니다."
 msgid "'%s' is not a valid timestamp"
 msgstr "'%s'은(는) 올바른 시각 값이 아닙니다"
 
-#: builtin/remote.c:13
+#: builtin/remote.c:14
 msgid "git remote [-v | --verbose]"
 msgstr "git remote [-v | --verbose]"
 
-#: builtin/remote.c:14
+#: builtin/remote.c:15
 msgid ""
 "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <name> <url>"
@@ -12232,82 +12714,82 @@ msgstr ""
 "git remote add [-t <브랜치>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <이름> <url>"
 
-#: builtin/remote.c:15 builtin/remote.c:35
+#: builtin/remote.c:16 builtin/remote.c:36
 msgid "git remote rename <old> <new>"
 msgstr "git remote rename <옛이름> <새이름>"
 
-#: builtin/remote.c:16 builtin/remote.c:40
+#: builtin/remote.c:17 builtin/remote.c:41
 msgid "git remote remove <name>"
 msgstr "git remote remove <이름>"
 
-#: builtin/remote.c:17 builtin/remote.c:45
+#: builtin/remote.c:18 builtin/remote.c:46
 msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
 msgstr "git remote set-head <이름> (-a | --auto | -d | --delete | <브랜치>)"
 
-#: builtin/remote.c:18
+#: builtin/remote.c:19
 msgid "git remote [-v | --verbose] show [-n] <name>"
 msgstr "git remote [-v | --verbose] show [-n] <이름>"
 
-#: builtin/remote.c:19
+#: builtin/remote.c:20
 msgid "git remote prune [-n | --dry-run] <name>"
 msgstr "git remote prune [-n | --dry-run] <이름>"
 
-#: builtin/remote.c:20
+#: builtin/remote.c:21
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
 msgstr ""
 "git remote [-v | --verbose] update [-p | --prune] [(<그룹> | <리모트>)...]"
 
-#: builtin/remote.c:21
+#: builtin/remote.c:22
 msgid "git remote set-branches [--add] <name> <branch>..."
 msgstr "git remote set-branches [--add] <이름> <브랜치>..."
 
-#: builtin/remote.c:22 builtin/remote.c:71
+#: builtin/remote.c:23 builtin/remote.c:72
 msgid "git remote get-url [--push] [--all] <name>"
 msgstr "git remote get-url [--push] [--all] <이름>"
 
-#: builtin/remote.c:23 builtin/remote.c:76
+#: builtin/remote.c:24 builtin/remote.c:77
 msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]"
 msgstr "git remote set-url [--push] <이름> <새url> [<옛url>]"
 
-#: builtin/remote.c:24 builtin/remote.c:77
+#: builtin/remote.c:25 builtin/remote.c:78
 msgid "git remote set-url --add <name> <newurl>"
 msgstr "git remote set-url --add <이름> <새url>"
 
-#: builtin/remote.c:25 builtin/remote.c:78
+#: builtin/remote.c:26 builtin/remote.c:79
 msgid "git remote set-url --delete <name> <url>"
 msgstr "git remote set-url --delete <이름> <url>"
 
-#: builtin/remote.c:30
+#: builtin/remote.c:31
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<옵션>] <이름> <url>"
 
-#: builtin/remote.c:50
+#: builtin/remote.c:51
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <이름> <브랜치>..."
 
-#: builtin/remote.c:51
+#: builtin/remote.c:52
 msgid "git remote set-branches --add <name> <branch>..."
 msgstr "git remote set-branches --add <이름> <브랜치>..."
 
-#: builtin/remote.c:56
+#: builtin/remote.c:57
 msgid "git remote show [<options>] <name>"
 msgstr "git remote show [<옵션>] <이름>"
 
-#: builtin/remote.c:61
+#: builtin/remote.c:62
 msgid "git remote prune [<options>] <name>"
 msgstr "git remote prune [<옵션>] <이름>"
 
-#: builtin/remote.c:66
+#: builtin/remote.c:67
 msgid "git remote update [<options>] [<group> | <remote>]..."
 msgstr "git remote update [<옵션>] [<그룹> | <리모트>]..."
 
-#: builtin/remote.c:95
+#: builtin/remote.c:96
 #, c-format
 msgid "Updating %s"
 msgstr "%s 업데이트 중"
 
-#: builtin/remote.c:127
+#: builtin/remote.c:128
 msgid ""
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
@@ -12315,86 +12797,86 @@ msgstr ""
 "--mirror는 위험하므로 사용을 권하지 않습니다. 대신에\n"
 "\t --mirror=fetch 또는 --mirror=push를 사용하십시오"
 
-#: builtin/remote.c:144
+#: builtin/remote.c:145
 #, c-format
 msgid "unknown mirror argument: %s"
 msgstr "알 수 없는 --mirror 옵션 인자: %s"
 
-#: builtin/remote.c:160
+#: builtin/remote.c:161
 msgid "fetch the remote branches"
 msgstr "리모트 브랜치를 가져옵니다"
 
-#: builtin/remote.c:162
+#: builtin/remote.c:163
 msgid "import all tags and associated objects when fetching"
 msgstr "가져올 때 모든 태그와 관련 오브젝트를 가져옵니다"
 
-#: builtin/remote.c:165
+#: builtin/remote.c:166
 msgid "or do not fetch any tag at all (--no-tags)"
 msgstr "아니면 아무 태그도 가져오지 않습니다 (--no-tags)"
 
-#: builtin/remote.c:167
+#: builtin/remote.c:168
 msgid "branch(es) to track"
 msgstr "추적할 브랜치"
 
-#: builtin/remote.c:168
+#: builtin/remote.c:169
 msgid "master branch"
 msgstr "마스터 브랜치"
 
-#: builtin/remote.c:169
+#: builtin/remote.c:170
 msgid "push|fetch"
 msgstr "push|fetch"
 
-#: builtin/remote.c:170
+#: builtin/remote.c:171
 msgid "set up remote as a mirror to push to or fetch from"
 msgstr "리모트를 푸시 또는 가져올 때 사용할 미러로 설정합니다"
 
-#: builtin/remote.c:182
+#: builtin/remote.c:183
 msgid "specifying a master branch makes no sense with --mirror"
 msgstr "--mirror 옵션과 같이 마스터 브랜치를 지정하면 앞뒤가 맞지 않습니다"
 
-#: builtin/remote.c:184
+#: builtin/remote.c:185
 msgid "specifying branches to track makes sense only with fetch mirrors"
 msgstr "마스터 브랜치를 지정은 fetch 미러에서만 앞뒤가 맞습니다"
 
-#: builtin/remote.c:191 builtin/remote.c:631
+#: builtin/remote.c:192 builtin/remote.c:634
 #, c-format
 msgid "remote %s already exists."
 msgstr "%s 리모트가 이미 있습니다."
 
-#: builtin/remote.c:195 builtin/remote.c:635
+#: builtin/remote.c:196 builtin/remote.c:638
 #, c-format
 msgid "'%s' is not a valid remote name"
 msgstr "'%s'은(는) 올바른 리모트 이름이 아닙니다"
 
-#: builtin/remote.c:235
+#: builtin/remote.c:236
 #, c-format
 msgid "Could not setup master '%s'"
 msgstr "마스터 '%s'을(를) 설정할 수 없습니다"
 
-#: builtin/remote.c:337
+#: builtin/remote.c:342
 #, c-format
 msgid "Could not get fetch map for refspec %s"
 msgstr "%s 레퍼런스명세에 대한 가져오기 맵을 얻을 수 없습니다"
 
-#: builtin/remote.c:438 builtin/remote.c:446
+#: builtin/remote.c:441 builtin/remote.c:449
 msgid "(matching)"
 msgstr "(일치)"
 
-#: builtin/remote.c:450
+#: builtin/remote.c:453
 msgid "(delete)"
 msgstr "(삭제)"
 
-#: builtin/remote.c:624 builtin/remote.c:759 builtin/remote.c:858
+#: builtin/remote.c:627 builtin/remote.c:762 builtin/remote.c:861
 #, c-format
 msgid "No such remote: %s"
 msgstr "그런 리모트가 없습니다: %s"
 
-#: builtin/remote.c:641
+#: builtin/remote.c:644
 #, c-format
 msgid "Could not rename config section '%s' to '%s'"
 msgstr "설정 섹션을 '%s'에서 '%s'(으)로 바꿀 수 없습니다"
 
-#: builtin/remote.c:661
+#: builtin/remote.c:664
 #, c-format
 msgid ""
 "Not updating non-default fetch refspec\n"
@@ -12405,17 +12887,17 @@ msgstr ""
 "\t%s\n"
 "\t필요하면 설정을 수동으로 업데이트하십시오."
 
-#: builtin/remote.c:697
+#: builtin/remote.c:700
 #, c-format
 msgid "deleting '%s' failed"
 msgstr "'%s' 삭제가 실패했습니다"
 
-#: builtin/remote.c:731
+#: builtin/remote.c:734
 #, c-format
 msgid "creating '%s' failed"
 msgstr "'%s' 만들기가 실패했습니다"
 
-#: builtin/remote.c:796
+#: builtin/remote.c:799
 msgid ""
 "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
 "to delete it, use:"
@@ -12427,113 +12909,118 @@ msgstr[0] ""
 "다.\n"
 "삭제하려면 다음을 사용하십시오:"
 
-#: builtin/remote.c:810
+#: builtin/remote.c:813
 #, c-format
 msgid "Could not remove config section '%s'"
 msgstr "설정 섹션 '%s'을(를) 제거할 수 없습니다"
 
-#: builtin/remote.c:911
+#: builtin/remote.c:914
 #, c-format
 msgid " new (next fetch will store in remotes/%s)"
 msgstr " 새 항목 (다음 가져오기는 remotes/%s 아래 저장됩니다)"
 
-#: builtin/remote.c:914
+#: builtin/remote.c:917
 msgid " tracked"
 msgstr " 추적됨"
 
-#: builtin/remote.c:916
+#: builtin/remote.c:919
 msgid " stale (use 'git remote prune' to remove)"
 msgstr " 오래됨 (제거하려면 'git remote prune'을 사용하십시오)"
 
-#: builtin/remote.c:918
+#: builtin/remote.c:921
 msgid " ???"
 msgstr " ???"
 
-#: builtin/remote.c:959
+#: builtin/remote.c:962
 #, c-format
 msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
 msgstr "잘못된 branch.%s.merge 값. 여러 개 브랜치로 리베이스할 수 없습니다"
 
-#: builtin/remote.c:967
+#: builtin/remote.c:971
 #, c-format
 msgid "rebases interactively onto remote %s"
 msgstr "리모트 %s 위로 대화식으로 리베이스합니다"
 
-#: builtin/remote.c:968
+#: builtin/remote.c:973
+#, c-format
+msgid "rebases interactively (with merges) onto remote %s"
+msgstr "리모트 %s 위로 대화식으로 (병합 포함) 리베이스합니다"
+
+#: builtin/remote.c:976
 #, c-format
 msgid "rebases onto remote %s"
 msgstr "리모트 %s 위로 리베이스합니다"
 
-#: builtin/remote.c:971
+#: builtin/remote.c:980
 #, c-format
 msgid " merges with remote %s"
 msgstr " 병합: 리모트 %s"
 
-#: builtin/remote.c:974
+#: builtin/remote.c:983
 #, c-format
 msgid "merges with remote %s"
 msgstr "병합: 리모트 %s"
 
-#: builtin/remote.c:977
+#: builtin/remote.c:986
 #, c-format
 msgid "%-*s    and with remote %s\n"
 msgstr "%-*s    그리고 리모트 %s\n"
 
-#: builtin/remote.c:1020
+#: builtin/remote.c:1029
 msgid "create"
 msgstr "만들기"
 
-#: builtin/remote.c:1023
+#: builtin/remote.c:1032
 msgid "delete"
 msgstr "삭제"
 
-#: builtin/remote.c:1027
+#: builtin/remote.c:1036
 msgid "up to date"
 msgstr "최신 상태"
 
-#: builtin/remote.c:1030
+#: builtin/remote.c:1039
 msgid "fast-forwardable"
 msgstr "정방향 진행 가능"
 
-#: builtin/remote.c:1033
+#: builtin/remote.c:1042
 msgid "local out of date"
 msgstr "로컬이 뒤떨어짐"
 
-#: builtin/remote.c:1040
+#: builtin/remote.c:1049
 #, c-format
 msgid "    %-*s forces to %-*s (%s)"
 msgstr "    %-*s에서 %-*s(으)로 강제 (%s)"
 
-#: builtin/remote.c:1043
+#: builtin/remote.c:1052
 #, c-format
 msgid "    %-*s pushes to %-*s (%s)"
 msgstr "    %-*s에서 %-*s(으)로 푸시 (%s)"
 
-#: builtin/remote.c:1047
+#: builtin/remote.c:1056
 #, c-format
 msgid "    %-*s forces to %s"
 msgstr "    %-*s에서 %s(으)로 강제"
 
-#: builtin/remote.c:1050
+#: builtin/remote.c:1059
 #, c-format
 msgid "    %-*s pushes to %s"
 msgstr "    %-*s에서 %s(으)로 푸시"
 
-#: builtin/remote.c:1118
+#: builtin/remote.c:1127
 msgid "do not query remotes"
 msgstr "리모트에 질의하지 않습니다"
 
-#: builtin/remote.c:1145
+#: builtin/remote.c:1154
 #, c-format
 msgid "* remote %s"
 msgstr "* 리모트 %s"
 
-#: builtin/remote.c:1146
+#: builtin/remote.c:1155
 #, c-format
 msgid "  Fetch URL: %s"
 msgstr "  가져오기 URL: %s"
 
-#: builtin/remote.c:1147 builtin/remote.c:1163 builtin/remote.c:1302
+#: builtin/remote.c:1156 builtin/remote.c:1172 builtin/remote.c:1311
 msgid "(no URL)"
 msgstr "(URL 없음)"
 
@@ -12541,182 +13028,182 @@ msgstr "(URL 없음)"
 #. with the one in " Fetch URL: %s"
 #. translation.
 #.
-#: builtin/remote.c:1161 builtin/remote.c:1163
+#: builtin/remote.c:1170 builtin/remote.c:1172
 #, c-format
 msgid "  Push  URL: %s"
 msgstr "  푸시  URL: %s"
 
-#: builtin/remote.c:1165 builtin/remote.c:1167 builtin/remote.c:1169
+#: builtin/remote.c:1174 builtin/remote.c:1176 builtin/remote.c:1178
 #, c-format
 msgid "  HEAD branch: %s"
 msgstr "  HEAD 브랜치: %s"
 
-#: builtin/remote.c:1165
+#: builtin/remote.c:1174
 msgid "(not queried)"
 msgstr "(질의하지 않음)"
 
-#: builtin/remote.c:1167
+#: builtin/remote.c:1176
 msgid "(unknown)"
 msgstr "(알 수 없음)"
 
-#: builtin/remote.c:1171
+#: builtin/remote.c:1180
 #, c-format
 msgid ""
 "  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
 msgstr "  HEAD 브랜치 (리모트 HEAD는 애매하고, 다음 중 하나일 수 있습니다):\n"
 
-#: builtin/remote.c:1183
+#: builtin/remote.c:1192
 #, c-format
 msgid "  Remote branch:%s"
 msgid_plural "  Remote branches:%s"
 msgstr[0] "  리모트 브랜치:%s"
 
-#: builtin/remote.c:1186 builtin/remote.c:1212
+#: builtin/remote.c:1195 builtin/remote.c:1221
 msgid " (status not queried)"
 msgstr " (상태를 질의하지 않음)"
 
-#: builtin/remote.c:1195
+#: builtin/remote.c:1204
 msgid "  Local branch configured for 'git pull':"
 msgid_plural "  Local branches configured for 'git pull':"
 msgstr[0] "  'git pull'에 사용할 로컬 브랜치를 설정:"
 
-#: builtin/remote.c:1203
+#: builtin/remote.c:1212
 msgid "  Local refs will be mirrored by 'git push'"
 msgstr "  로컬 레퍼런스를 'git push'로 미러링할 예정"
 
-#: builtin/remote.c:1209
+#: builtin/remote.c:1218
 #, c-format
 msgid "  Local ref configured for 'git push'%s:"
 msgid_plural "  Local refs configured for 'git push'%s:"
 msgstr[0] "  로컬 레퍼런스를 'git push'로 미러링%s:"
 
-#: builtin/remote.c:1230
+#: builtin/remote.c:1239
 msgid "set refs/remotes/<name>/HEAD according to remote"
 msgstr "레퍼런스/리모트/<이름>/HEAD 값을 리모트에 맞게 설정합니다"
 
-#: builtin/remote.c:1232
+#: builtin/remote.c:1241
 msgid "delete refs/remotes/<name>/HEAD"
 msgstr "레퍼런스/리모트/<이름>/HEAD 값을 삭제합니다"
 
-#: builtin/remote.c:1247
+#: builtin/remote.c:1256
 msgid "Cannot determine remote HEAD"
 msgstr "리모트 HEAD를 결정할 수 없습니다"
 
-#: builtin/remote.c:1249
+#: builtin/remote.c:1258
 msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
 msgstr ""
 "리모트 HEAD 브랜치가 여러개입니다. 다음 중 하나를 명시적으로 지정하십시오:"
 
-#: builtin/remote.c:1259
+#: builtin/remote.c:1268
 #, c-format
 msgid "Could not delete %s"
 msgstr "%s을(를) 삭제할 수 없습니다"
 
-#: builtin/remote.c:1267
+#: builtin/remote.c:1276
 #, c-format
 msgid "Not a valid ref: %s"
 msgstr "올바른 레퍼런스가 아닙니다: %s"
 
-#: builtin/remote.c:1269
+#: builtin/remote.c:1278
 #, c-format
 msgid "Could not setup %s"
 msgstr "%s을(를) 설정할 수 없습니다"
 
-#: builtin/remote.c:1287
+#: builtin/remote.c:1296
 #, c-format
 msgid " %s will become dangling!"
 msgstr " %s의 연결이 끊어집니다!"
 
-#: builtin/remote.c:1288
+#: builtin/remote.c:1297
 #, c-format
 msgid " %s has become dangling!"
 msgstr " %s의 연결이 끊어졌습니다!"
 
-#: builtin/remote.c:1298
+#: builtin/remote.c:1307
 #, c-format
 msgid "Pruning %s"
 msgstr "잘라냄: %s"
 
-#: builtin/remote.c:1299
+#: builtin/remote.c:1308
 #, c-format
 msgid "URL: %s"
 msgstr "URL: %s"
 
-#: builtin/remote.c:1315
+#: builtin/remote.c:1324
 #, c-format
 msgid " * [would prune] %s"
 msgstr " * [잘라낼 예정] %s"
 
-#: builtin/remote.c:1318
+#: builtin/remote.c:1327
 #, c-format
 msgid " * [pruned] %s"
 msgstr " * [잘라냄] %s"
 
-#: builtin/remote.c:1363
+#: builtin/remote.c:1372
 msgid "prune remotes after fetching"
 msgstr "가져온 후에 리모트를 잘라냅니다"
 
-#: builtin/remote.c:1426 builtin/remote.c:1480 builtin/remote.c:1548
+#: builtin/remote.c:1435 builtin/remote.c:1489 builtin/remote.c:1557
 #, c-format
 msgid "No such remote '%s'"
 msgstr "그런 리모트가 없습니다 ('%s')"
 
-#: builtin/remote.c:1442
+#: builtin/remote.c:1451
 msgid "add branch"
 msgstr "브랜치를 추가합니다"
 
-#: builtin/remote.c:1449
+#: builtin/remote.c:1458
 msgid "no remote specified"
 msgstr "리모트를 지정하지 않았습니다"
 
-#: builtin/remote.c:1466
+#: builtin/remote.c:1475
 msgid "query push URLs rather than fetch URLs"
 msgstr "가져오기 URL이 아니라 푸시 URL을 질의합니다"
 
-#: builtin/remote.c:1468
+#: builtin/remote.c:1477
 msgid "return all URLs"
 msgstr "모든 URL을 리턴합니다"
 
-#: builtin/remote.c:1496
+#: builtin/remote.c:1505
 #, c-format
 msgid "no URLs configured for remote '%s'"
 msgstr "'%s' 리모트에 대한 URL을 설정하지 않았습니다"
 
-#: builtin/remote.c:1522
+#: builtin/remote.c:1531
 msgid "manipulate push URLs"
 msgstr "푸시 URL을 지정합니다"
 
-#: builtin/remote.c:1524
+#: builtin/remote.c:1533
 msgid "add URL"
 msgstr "URL을 추가합니다"
 
-#: builtin/remote.c:1526
+#: builtin/remote.c:1535
 msgid "delete URLs"
 msgstr "URL을 삭제합니다"
 
-#: builtin/remote.c:1533
+#: builtin/remote.c:1542
 msgid "--add --delete doesn't make sense"
 msgstr "--add --delete 옵션을 둘다 쓰면 안 됩니다"
 
-#: builtin/remote.c:1572
+#: builtin/remote.c:1581
 #, c-format
 msgid "Invalid old URL pattern: %s"
 msgstr "잘못된 오래전 URL 패턴: %s"
 
-#: builtin/remote.c:1580
+#: builtin/remote.c:1589
 #, c-format
 msgid "No such URL found: %s"
 msgstr "그런 URL이 없습니다: %s"
 
-#: builtin/remote.c:1582
+#: builtin/remote.c:1591
 msgid "Will not delete all non-push URLs"
 msgstr "푸시용이 아닌 모든 URL을 삭제하지 않습니다"
 
-#: builtin/remote.c:1598
+#: builtin/remote.c:1607
 msgid "be verbose; must be placed before a subcommand"
 msgstr "자세히 표시합니다 (하위 명령 앞에 와야 합니다)"
 
-#: builtin/remote.c:1629
+#: builtin/remote.c:1638
 #, c-format
 msgid "Unknown subcommand: %s"
 msgstr "알 수 없는 하위 명령: %s"
@@ -12733,128 +13220,136 @@ msgstr ""
 "점진적인 repack은 비트맵 인덱스와 호환되지 않습니다.\n"
 "--no-write-bitmap-index를 사용하거나 pack.writebitmaps 설정을 끄십시오."
 
-#: builtin/repack.c:170
+#: builtin/repack.c:180
 msgid "pack everything in a single pack"
 msgstr "하나의 묶음 안에 모두 묶습니다"
 
-#: builtin/repack.c:172
+#: builtin/repack.c:182
 msgid "same as -a, and turn unreachable objects loose"
 msgstr "-a와 동일하고, 접근 불가능 오브젝트를 느슨하게 바꿉니다"
 
-#: builtin/repack.c:175
+#: builtin/repack.c:185
 msgid "remove redundant packs, and run git-prune-packed"
 msgstr "여분의 묶음을 제거하고, git-prune-packed를 실행합니다"
 
-#: builtin/repack.c:177
+#: builtin/repack.c:187
 msgid "pass --no-reuse-delta to git-pack-objects"
 msgstr "git-pack-objects에 --no-reuse-delta 옵션을 넘깁니다"
 
-#: builtin/repack.c:179
+#: builtin/repack.c:189
 msgid "pass --no-reuse-object to git-pack-objects"
 msgstr "git-pack-objects에 --no-reuse-object 옵션을 넘깁니다"
 
-#: builtin/repack.c:181
+#: builtin/repack.c:191
 msgid "do not run git-update-server-info"
 msgstr "git-update-server-info를 실행하지 않습니다"
 
-#: builtin/repack.c:184
+#: builtin/repack.c:194
 msgid "pass --local to git-pack-objects"
 msgstr "git-pack-objects에 --local 옵션을 넘깁니다"
 
-#: builtin/repack.c:186
+#: builtin/repack.c:196
 msgid "write bitmap index"
 msgstr "비트맵 인덱스를 씁니다"
 
-#: builtin/repack.c:187
+#: builtin/repack.c:197
 msgid "approxidate"
 msgstr "대략의시각"
 
-#: builtin/repack.c:188
+#: builtin/repack.c:198
 msgid "with -A, do not loosen objects older than this"
 msgstr ""
 "-A에 추가로, 지정한 시각보다 오래된 오브젝트를 느슨하게 만들지 않습니다"
 
-#: builtin/repack.c:190
+#: builtin/repack.c:200
 msgid "with -a, repack unreachable objects"
 msgstr "-a와 같이, 접근 불가능 오브젝트를 다시 묶습니다"
 
-#: builtin/repack.c:192
+#: builtin/repack.c:202
 msgid "size of the window used for delta compression"
 msgstr "델타 압축에 사용할 윈도우 크기"
 
-#: builtin/repack.c:193 builtin/repack.c:199
+#: builtin/repack.c:203 builtin/repack.c:209
 msgid "bytes"
 msgstr "바이트수"
 
-#: builtin/repack.c:194
+#: builtin/repack.c:204
 msgid "same as the above, but limit memory size instead of entries count"
 msgstr "위와 동일하지만, 항목 수 대신 메모리 크기를 제한합니다"
 
-#: builtin/repack.c:196
+#: builtin/repack.c:206
 msgid "limits the maximum delta depth"
 msgstr "최대 델타 깊이를 제한합니다"
 
-#: builtin/repack.c:198
+#: builtin/repack.c:208
 msgid "limits the maximum number of threads"
 msgstr "최대 스레드 수를 제한합니다"
 
-#: builtin/repack.c:200
+#: builtin/repack.c:210
 msgid "maximum size of each packfile"
 msgstr "묶음 파일의 최대 크기"
 
-#: builtin/repack.c:202
+#: builtin/repack.c:212
 msgid "repack objects in packs marked with .keep"
 msgstr ".keep으로 표시된 묶음의 오브젝트를 다시 묶습니다"
 
-#: builtin/repack.c:212
+#: builtin/repack.c:214
+msgid "do not repack this pack"
+msgstr "이 묶음을 다시 묶지 않습니다"
+
+#: builtin/repack.c:224
 msgid "cannot delete packs in a precious-objects repo"
 msgstr "precious-objects 저장소의 묶음을 삭제할 수 없습니다"
 
-#: builtin/repack.c:216
+#: builtin/repack.c:228
 msgid "--keep-unreachable and -A are incompatible"
 msgstr "--keep-unreachable 및 -A 옵션은 호환되지 않습니다"
 
-#: builtin/repack.c:410 builtin/worktree.c:148
+#: builtin/repack.c:425 builtin/worktree.c:139
 #, c-format
 msgid "failed to remove '%s'"
 msgstr "'%s' 제거에 실패했습니다"
 
-#: builtin/replace.c:20
+#: builtin/replace.c:22
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <오브젝트> <대체이름>"
 
-#: builtin/replace.c:21
+#: builtin/replace.c:23
 msgid "git replace [-f] --edit <object>"
 msgstr "git replace [-f] --edit <오브젝트>"
 
-#: builtin/replace.c:22
+#: builtin/replace.c:24
 msgid "git replace [-f] --graft <commit> [<parent>...]"
 msgstr "git replace [-f] --graft <커밋> [<상위>...]"
 
-#: builtin/replace.c:23
+#: builtin/replace.c:25
+msgid "git replace [-f] --convert-graft-file"
+msgstr "git replace [-f] --convert-graft-file"
+
+#: builtin/replace.c:26
 msgid "git replace -d <object>..."
 msgstr "git replace -d <오브젝트>..."
 
-#: builtin/replace.c:24
+#: builtin/replace.c:27
 msgid "git replace [--format=<format>] [-l [<pattern>]]"
 msgstr "git replace [--format=<형식>] [-l [<패턴>]]"
 
-#: builtin/replace.c:331 builtin/replace.c:369 builtin/replace.c:397
+#: builtin/replace.c:371 builtin/replace.c:415 builtin/replace.c:445
 #, c-format
 msgid "Not a valid object name: '%s'"
 msgstr "올바른 오브젝트 이름이 아닙니다: '%s'"
 
-#: builtin/replace.c:361
+#: builtin/replace.c:407
 #, c-format
 msgid "bad mergetag in commit '%s'"
 msgstr "커밋 '%s'에 잘못된 병합태그"
 
-#: builtin/replace.c:363
+#: builtin/replace.c:409
 #, c-format
 msgid "malformed mergetag in commit '%s'"
 msgstr "커밋 '%s'에 잘못된 형식의 병합태그"
 
-#: builtin/replace.c:374
+#: builtin/replace.c:421
 #, c-format
 msgid ""
 "original commit '%s' contains mergetag '%s' that is discarded; use --edit "
@@ -12863,45 +13358,58 @@ msgstr ""
 "본래 커밋 '%s'에 버려진 병합태그 '%s'이(가) 들어 있습니다. --graft 대신 --"
 "edit 옵션을 사용하십시오"
 
-#: builtin/replace.c:407
+#: builtin/replace.c:460
 #, c-format
 msgid "the original commit '%s' has a gpg signature."
 msgstr "본래 커밋 '%s'에 GPG 서명이 있습니다."
 
-#: builtin/replace.c:408
+#: builtin/replace.c:461
 msgid "the signature will be removed in the replacement commit!"
 msgstr "대체 커밋에서 서명을 제거합니다!"
 
-#: builtin/replace.c:414
+#: builtin/replace.c:471
 #, c-format
 msgid "could not write replacement commit for: '%s'"
 msgstr "다음에 대한 대체 커밋을 쓸 수 없습니다: '%s'"
 
-#: builtin/replace.c:438
+#: builtin/replace.c:514
+#, c-format
+msgid ""
+"could not convert the following graft(s):\n"
+"%s"
+msgstr ""
+"다음 그래프트를 변환할 수 없습니다:\n"
+"%s"
+
+#: builtin/replace.c:535
 msgid "list replace refs"
 msgstr "대체 레퍼런스 목록을 표시합니다"
 
-#: builtin/replace.c:439
+#: builtin/replace.c:536
 msgid "delete replace refs"
 msgstr "대체 레퍼런스를 삭제합니다"
 
-#: builtin/replace.c:440
+#: builtin/replace.c:537
 msgid "edit existing object"
 msgstr "현재 오브젝트를 편집합니다"
 
-#: builtin/replace.c:441
+#: builtin/replace.c:538
 msgid "change a commit's parents"
 msgstr "커밋의 상위 항목을 바꿉니다"
 
-#: builtin/replace.c:442
+#: builtin/replace.c:539
+msgid "convert existing graft file"
+msgstr "기존 그래프트 파일을 변환합니다"
+
+#: builtin/replace.c:540
 msgid "replace the ref if it exists"
 msgstr "레퍼런스가 있으면 대체합니다"
 
-#: builtin/replace.c:444
+#: builtin/replace.c:542
 msgid "do not pretty-print contents for --edit"
 msgstr "--edit에 대한 내용을 예쁘게 표시하지 않습니다"
 
-#: builtin/replace.c:445
+#: builtin/replace.c:543
 msgid "use this format"
 msgstr "이 형식을 사용합니다"
 
@@ -13061,23 +13569,23 @@ msgstr "rev-list는 노트 표시를 지원하지 않습니다"
 msgid "cannot combine --use-bitmap-index with object filtering"
 msgstr "--use-bitmap-index 옵션에 오브젝트 필터링을 결합 할 수 없습니다"
 
-#: builtin/rev-parse.c:402
+#: builtin/rev-parse.c:406
 msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
 msgstr "git rev-parse --parseopt [<옵션>] -- [<인자>...]"
 
-#: builtin/rev-parse.c:407
+#: builtin/rev-parse.c:411
 msgid "keep the `--` passed as an arg"
 msgstr "인자로 넘긴 `--`를 유지합니다"
 
-#: builtin/rev-parse.c:409
+#: builtin/rev-parse.c:413
 msgid "stop parsing after the first non-option argument"
 msgstr "첫번째 옵션이 아닌 인자 뒤에 파싱을 중지합니다"
 
-#: builtin/rev-parse.c:412
+#: builtin/rev-parse.c:416
 msgid "output in stuck long form"
 msgstr "stuck long 형식으로 출력합니다"
 
-#: builtin/rev-parse.c:545
+#: builtin/rev-parse.c:549
 msgid ""
 "git rev-parse --parseopt [<options>] -- [<args>...]\n"
 "   or: git rev-parse --sq-quote [<arg>...]\n"
@@ -13215,42 +13723,42 @@ msgid "the following file has local modifications:"
 msgid_plural "the following files have local modifications:"
 msgstr[0] "다음 파일에 로컬 수정 사항이 있습니다:"
 
-#: builtin/rm.c:243
+#: builtin/rm.c:241
 msgid "do not list removed files"
 msgstr "제거한 파일 목록을 표시하지 않습니다"
 
-#: builtin/rm.c:244
+#: builtin/rm.c:242
 msgid "only remove from the index"
 msgstr "인덱스에서만 제거합니다"
 
-#: builtin/rm.c:245
+#: builtin/rm.c:243
 msgid "override the up-to-date check"
 msgstr "최신 버전 확인을 하지 않습니다"
 
-#: builtin/rm.c:246
+#: builtin/rm.c:244
 msgid "allow recursive removal"
 msgstr "재귀적 제거를 허용합니다"
 
-#: builtin/rm.c:248
+#: builtin/rm.c:246
 msgid "exit with a zero status even if nothing matched"
 msgstr "아무 것도 일치하지 않으면 상태 0번으로 끝납니다"
 
-#: builtin/rm.c:307
+#: builtin/rm.c:306
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "-r 옵션이 없으면 재귀적으로 '%s'을(를) 제거하지 않습니다"
 
-#: builtin/rm.c:346
+#: builtin/rm.c:345
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm: %s을(를) 제거할 수 없습니다"
 
-#: builtin/rm.c:369
+#: builtin/rm.c:368
 #, c-format
 msgid "could not remove '%s'"
 msgstr "'%s'을(를) 제거할 수 없습니다"
 
-#: builtin/send-pack.c:19
+#: builtin/send-pack.c:20
 msgid ""
 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-"
 "receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> "
@@ -13262,50 +13770,70 @@ msgstr ""
 "스>...]\n"
 "  --all 옵션과 명시적인 <레퍼런스> 명세 중 하나만 사용할 수 있습니다."
 
-#: builtin/send-pack.c:162
+#: builtin/send-pack.c:163
 msgid "remote name"
 msgstr "리모트 이름"
 
-#: builtin/send-pack.c:176
+#: builtin/send-pack.c:177
 msgid "use stateless RPC protocol"
 msgstr "상태 없는 RPC 프로토콜을 사용합니다"
 
-#: builtin/send-pack.c:177
+#: builtin/send-pack.c:178
 msgid "read refs from stdin"
 msgstr "표준 입력에서 레퍼런스를 읽습니다"
 
-#: builtin/send-pack.c:178
+#: builtin/send-pack.c:179
 msgid "print status from remote helper"
 msgstr "리모트 도움 프로그램의 상태를 표시합니다"
 
+#: builtin/serve.c:7
+msgid "git serve [<options>]"
+msgstr "git serve [<옵션>]"
+
+#: builtin/serve.c:17 builtin/upload-pack.c:23
+msgid "quit after a single request/response exchange"
+msgstr "하나의 요청/응답 교환 뒤에 끝납니다"
+
+#: builtin/serve.c:19
+msgid "exit immediately after advertising capabilities"
+msgstr "기능 정보 교환 뒤에 즉시 끝납니다"
+
 #: builtin/shortlog.c:14
-msgid "git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"
-msgstr "git shortlog [<옵션>] [<리비전-범위>] [[--] [<경로>...]]"
+msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]"
+msgstr "git shortlog [<옵션>] [<리비전-범위>] [[--] <경로>...]"
+
+#: builtin/shortlog.c:15
+msgid "git log --pretty=short | git shortlog [<options>]"
+msgstr "git log --pretty=short | git shortlog [<옵션>]"
 
-#: builtin/shortlog.c:263
+#: builtin/shortlog.c:264
 msgid "Group by committer rather than author"
 msgstr "작성자가 아닌 커미터로 묶습니다"
 
-#: builtin/shortlog.c:265
+#: builtin/shortlog.c:266
 msgid "sort output according to the number of commits per author"
 msgstr "작성자별 커밋 수에 따라 정렬합니다"
 
-#: builtin/shortlog.c:267
+#: builtin/shortlog.c:268
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr "커밋 설명을 생략하고, 커밋 수만 표시합니다"
 
-#: builtin/shortlog.c:269
+#: builtin/shortlog.c:270
 msgid "Show the email address of each author"
 msgstr "작성자의 전자메일 주소를 표시합니다"
 
-#: builtin/shortlog.c:270
+#: builtin/shortlog.c:271
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:271
+#: builtin/shortlog.c:272
 msgid "Linewrap output"
 msgstr "줄바꿈 출력"
 
+#: builtin/shortlog.c:298
+msgid "too many arguments given outside repository"
+msgstr "저장소 밖에서 주어진 인자가 너무 많습니다"
+
 #: builtin/show-branch.c:12
 msgid ""
 "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
@@ -13499,39 +14027,39 @@ msgstr "주석 문자로 시작하는 모든 줄을 건너뛰고 제거합니다
 msgid "prepend comment character and space to each line"
 msgstr "각 줄의 앞에 주석 문자와 공백을 붙입니다"
 
-#: builtin/submodule--helper.c:35 builtin/submodule--helper.c:1669
+#: builtin/submodule--helper.c:37 builtin/submodule--helper.c:1688
 #, c-format
 msgid "No such ref: %s"
 msgstr "그런 레퍼런스가 없습니다: %s"
 
-#: builtin/submodule--helper.c:42 builtin/submodule--helper.c:1678
+#: builtin/submodule--helper.c:44 builtin/submodule--helper.c:1697
 #, c-format
 msgid "Expecting a full ref name, got %s"
 msgstr "전체 레퍼런스 이름이 필요하지만, 입력은 %s"
 
-#: builtin/submodule--helper.c:59
+#: builtin/submodule--helper.c:61
 msgid "submodule--helper print-default-remote takes no arguments"
 msgstr "submodule--helper print-default-remote 옵션은 인자가 필요하지 않습니다"
 
-#: builtin/submodule--helper.c:96
+#: builtin/submodule--helper.c:98
 #, c-format
 msgid "cannot strip one component off url '%s'"
 msgstr "'%s' URL 하나의 단계를 잘라낼 수 없습니다"
 
-#: builtin/submodule--helper.c:404 builtin/submodule--helper.c:1198
+#: builtin/submodule--helper.c:406 builtin/submodule--helper.c:1211
 msgid "alternative anchor for relative paths"
 msgstr "상대 경로에 사용할 또다른 기준"
 
-#: builtin/submodule--helper.c:409
+#: builtin/submodule--helper.c:411
 msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper list [--prefix=<경로>] [<경로>...]"
 
-#: builtin/submodule--helper.c:460 builtin/submodule--helper.c:483
+#: builtin/submodule--helper.c:462 builtin/submodule--helper.c:485
 #, c-format
 msgid "No url found for submodule path '%s' in .gitmodules"
 msgstr ".gitmodules에서 하위 모듈 경로 '%s'에 대한 URL이 없습니다"
 
-#: builtin/submodule--helper.c:498
+#: builtin/submodule--helper.c:500
 #, c-format
 msgid ""
 "could not lookup configuration '%s'. Assuming this repository is its own "
@@ -13539,113 +14067,115 @@ msgid ""
 msgstr ""
 "'%s' 설정을 찾아볼 수 없습니다. 이 저장소가 자체 업스트림이라고 가정합니다."
 
-#: builtin/submodule--helper.c:509
+#: builtin/submodule--helper.c:511
 #, c-format
 msgid "Failed to register url for submodule path '%s'"
 msgstr "하위 모듈 경로 '%s'에 대한 URL을 등록하는데 실패했습니다"
 
-#: builtin/submodule--helper.c:513
+#: builtin/submodule--helper.c:515
 #, c-format
 msgid "Submodule '%s' (%s) registered for path '%s'\n"
 msgstr "'%3$s' 경로에 대해 '%1$s' (%2$s) 하위 모듈 등록\n"
 
-#: builtin/submodule--helper.c:523
+#: builtin/submodule--helper.c:525
 #, c-format
 msgid "warning: command update mode suggested for submodule '%s'\n"
 msgstr "경고: '%s' 하위 모듈에 대해 커맨드 업데이트 모드가 제안되었습니다\n"
 
-#: builtin/submodule--helper.c:530
+#: builtin/submodule--helper.c:532
 #, c-format
 msgid "Failed to register update mode for submodule path '%s'"
 msgstr "'%s' 하위 모듈에 대해 업데이트 모드 등록이 실패했습니다"
 
-#: builtin/submodule--helper.c:552
+#: builtin/submodule--helper.c:554
 msgid "Suppress output for initializing a submodule"
 msgstr "하위 모듈 초기화에 출력을 하지 않습니다"
 
-#: builtin/submodule--helper.c:557
+#: builtin/submodule--helper.c:559
 msgid "git submodule--helper init [<path>]"
 msgstr "git submodule--helper init [<경로>]"
 
-#: builtin/submodule--helper.c:625 builtin/submodule--helper.c:747
+#: builtin/submodule--helper.c:631 builtin/submodule--helper.c:757
 #, c-format
 msgid "no submodule mapping found in .gitmodules for path '%s'"
 msgstr "경로 '%s'에 대해 .gitmodules에 있는 하위모듈 매핑이 없습니다"
 
-#: builtin/submodule--helper.c:660
+#: builtin/submodule--helper.c:670
 #, c-format
 msgid "could not resolve HEAD ref inside the submodule '%s'"
 msgstr "HEAD 레퍼런스를 '%s' 하위 모듈 안에서 찾을 수 없습니다"
 
-#: builtin/submodule--helper.c:687 builtin/submodule--helper.c:856
+#: builtin/submodule--helper.c:697 builtin/submodule--helper.c:866
 #, c-format
 msgid "failed to recurse into submodule '%s'"
 msgstr "'%s' 하위 모듈에 재귀적으로 적용이 실패했습니다"
 
-#: builtin/submodule--helper.c:711 builtin/submodule--helper.c:1021
+#: builtin/submodule--helper.c:721 builtin/submodule--helper.c:1031
 msgid "Suppress submodule status output"
 msgstr "하위 모듈 상태를 출력하지 않습니다"
 
-#: builtin/submodule--helper.c:712
+#: builtin/submodule--helper.c:722
 msgid ""
 "Use commit stored in the index instead of the one stored in the submodule "
 "HEAD"
 msgstr "하위 모듈 HEAD에 저장된 커밋 대신 인덱스에 저장된 커밋을 사용합니다"
 
-#: builtin/submodule--helper.c:713
+#: builtin/submodule--helper.c:723
 msgid "recurse into nested submodules"
 msgstr "내장된 하위 모듈에 재귀적으로 적용"
 
-#: builtin/submodule--helper.c:718
+#: builtin/submodule--helper.c:728
 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
 msgstr "git submodule status [--quiet] [--cached] [--recursive] [<경로>...]"
 
-#: builtin/submodule--helper.c:742
+#: builtin/submodule--helper.c:752
 msgid "git submodule--helper name <path>"
 msgstr "git submodule--helper name <경로>"
 
-#: builtin/submodule--helper.c:806
+#: builtin/submodule--helper.c:816
 #, c-format
 msgid "Synchronizing submodule url for '%s'\n"
 msgstr "하위 모듈 URL을 '%s'에 대해 동기화\n"
 
-#: builtin/submodule--helper.c:812
+#: builtin/submodule--helper.c:822
 #, c-format
 msgid "failed to register url for submodule path '%s'"
 msgstr "하위 모듈 경로 '%s'에 대한 URL을 등록하는데 실패했습니다"
 
-#: builtin/submodule--helper.c:826
+#: builtin/submodule--helper.c:836
 #, c-format
 msgid "failed to get the default remote for submodule '%s'"
 msgstr ""
 "하위 모듈 경로 '%s'에 대한 기본 리모트 (저장소)를 가져오는데 실패했습니다"
 
-#: builtin/submodule--helper.c:837
+#: builtin/submodule--helper.c:847
 #, c-format
 msgid "failed to update remote for submodule '%s'"
 msgstr ""
 "하위 모듈 경로 '%s'에 대한 리모트 (저장소)를 업데이트하는데 실패했습니다"
 
-#: builtin/submodule--helper.c:885
+#: builtin/submodule--helper.c:895
 msgid "Suppress output of synchronizing submodule url"
 msgstr "하위 모듈 URL 동기화 출력 표시하지 않습니다"
 
-#: builtin/submodule--helper.c:887
+#: builtin/submodule--helper.c:897
 msgid "Recurse into nested submodules"
 msgstr "중첩된 하위 모듈에 재귀적으로 적용합니다"
 
-#: builtin/submodule--helper.c:892
+#: builtin/submodule--helper.c:902
 msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
 msgstr "git submodule--helper sync [--quiet] [--recursive] [<경로>]"
 
-#: builtin/submodule--helper.c:946
+#: builtin/submodule--helper.c:956
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you "
 "really want to remove it including all of its history)"
-msgstr "하위 모듈 작업 폴더 '%s'에 .git 디렉터리가 있습니다 (정말로 모든 커밋 내역을 포함하여 제거하려면 'rm -rf'를 사용하십시오)"
+msgstr ""
+"하위 모듈 작업 폴더 '%s'에 .git 디렉터리가 있습니다 (정말로 모든 커밋 내역을 "
+"포함하여 제거하려면 'rm -rf'를 사용하십시오)"
 
-#: builtin/submodule--helper.c:958
+#: builtin/submodule--helper.c:968
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains local modifications; use '-f' to discard "
@@ -13654,80 +14184,80 @@ msgstr ""
 "하위 모듈 작업 폴더 '%s'에 로컬 수정 사항이 있습니다. 버리려면 '-f'를 사용하"
 "십시오"
 
-#: builtin/submodule--helper.c:966
+#: builtin/submodule--helper.c:976
 #, c-format
 msgid "Cleared directory '%s'\n"
 msgstr "'%s' 디렉터리를 지웁니다\n"
 
-#: builtin/submodule--helper.c:968
+#: builtin/submodule--helper.c:978
 #, c-format
 msgid "Could not remove submodule work tree '%s'\n"
 msgstr "하위 모듈 작업 폴더  '%s'을(를) 제거할 수 없습니다\n"
 
-#: builtin/submodule--helper.c:977
+#: builtin/submodule--helper.c:987
 #, c-format
 msgid "could not create empty submodule directory %s"
 msgstr "빈 하위 모듈 디렉터리를 %s을(를) 만들 수 없습니다"
 
-#: builtin/submodule--helper.c:993
+#: builtin/submodule--helper.c:1003
 #, c-format
 msgid "Submodule '%s' (%s) unregistered for path '%s'\n"
 msgstr "'%s' 하위 모듈이 (%s) '%s' 경로에 대해 등록되지 않았습니다\n"
 
-#: builtin/submodule--helper.c:1022
+#: builtin/submodule--helper.c:1032
 msgid "Remove submodule working trees even if they contain local changes"
 msgstr "로컬 변경 사항이 있어도 하위 모듈 작업 폴더를 제거합니다"
 
-#: builtin/submodule--helper.c:1023
+#: builtin/submodule--helper.c:1033
 msgid "Unregister all submodules"
 msgstr "모든 하위 모듈을 목록에서 제거합니다"
 
-#: builtin/submodule--helper.c:1028
+#: builtin/submodule--helper.c:1038
 msgid ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
 msgstr ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<경로>...]]"
 
-#: builtin/submodule--helper.c:1042
+#: builtin/submodule--helper.c:1052
 msgid "Use '--all' if you really want to deinitialize all submodules"
 msgstr "정말로 모든 하위 모듈 초기화를 해제하려면 '--all'을 사용하십시오"
 
-#: builtin/submodule--helper.c:1133 builtin/submodule--helper.c:1136
+#: builtin/submodule--helper.c:1145 builtin/submodule--helper.c:1148
 #, c-format
 msgid "submodule '%s' cannot add alternate: %s"
 msgstr "'%s' 하위 모듈에 보조 오브젝트를 추가할 수 없습니다: %s"
 
-#: builtin/submodule--helper.c:1172
+#: builtin/submodule--helper.c:1184
 #, c-format
 msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized"
 msgstr "submodule.alternateErrorStrategy에 대한 값이('%s') 알 수 없는 값입니다"
 
-#: builtin/submodule--helper.c:1179
+#: builtin/submodule--helper.c:1191
 #, c-format
 msgid "Value '%s' for submodule.alternateLocation is not recognized"
 msgstr "submodule.alternateLocation에 대한 값이('%s') 알 수 없는 값입니다"
 
-#: builtin/submodule--helper.c:1201
+#: builtin/submodule--helper.c:1214
 msgid "where the new submodule will be cloned to"
 msgstr "새 하위 모듈을 복제할 대상 위치"
 
-#: builtin/submodule--helper.c:1204
+#: builtin/submodule--helper.c:1217
 msgid "name of the new submodule"
 msgstr "새 하위 모듈 이름"
 
-#: builtin/submodule--helper.c:1207
+#: builtin/submodule--helper.c:1220
 msgid "url where to clone the submodule from"
 msgstr "하위 모듈을 복제해 올 URL"
 
-#: builtin/submodule--helper.c:1213
+#: builtin/submodule--helper.c:1228
 msgid "depth for shallow clones"
 msgstr "얕은 복제에 사용할 깊이"
 
-#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1587
+#: builtin/submodule--helper.c:1231 builtin/submodule--helper.c:1606
 msgid "force cloning progress"
 msgstr "복제 진행 상황을 항상 표시합니다"
 
-#: builtin/submodule--helper.c:1221
+#: builtin/submodule--helper.c:1236
 msgid ""
 "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
 "<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>"
@@ -13735,82 +14265,82 @@ msgstr ""
 "git submodule--helper clone [--prefix=<경로>] [--quiet] [--reference <저장소"
 ">] [--name <이름>] [--depth <깊이>] --url <url> --path <경로>"
 
-#: builtin/submodule--helper.c:1252
+#: builtin/submodule--helper.c:1267
 #, c-format
 msgid "clone of '%s' into submodule path '%s' failed"
 msgstr "'%s'에서 하위 모듈 경로 '%s'에 복제하는데 실패했습니다"
 
-#: builtin/submodule--helper.c:1267
+#: builtin/submodule--helper.c:1281
 #, c-format
 msgid "could not get submodule directory for '%s'"
 msgstr "'%s'에 대한 하위 모듈 디렉터리를 가져올 수 없습니다"
 
-#: builtin/submodule--helper.c:1332
+#: builtin/submodule--helper.c:1347
 #, c-format
 msgid "Submodule path '%s' not initialized"
 msgstr "'%s' 하위 모듈 경로가 초기화되지 않았습니다"
 
-#: builtin/submodule--helper.c:1336
+#: builtin/submodule--helper.c:1351
 msgid "Maybe you want to use 'update --init'?"
 msgstr "'update --init'을 하려고 한 것 아니었습니까?"
 
-#: builtin/submodule--helper.c:1365
+#: builtin/submodule--helper.c:1380
 #, c-format
 msgid "Skipping unmerged submodule %s"
 msgstr "병합하지 하위 모듈 %s 건너뜀"
 
-#: builtin/submodule--helper.c:1394
+#: builtin/submodule--helper.c:1409
 #, c-format
 msgid "Skipping submodule '%s'"
 msgstr "하위 모듈 '%s' 건너뜀"
 
-#: builtin/submodule--helper.c:1527
+#: builtin/submodule--helper.c:1544
 #, c-format
 msgid "Failed to clone '%s'. Retry scheduled"
 msgstr "'%s' 복제하는데 실패했습니다. 재시도 예정"
 
-#: builtin/submodule--helper.c:1538
+#: builtin/submodule--helper.c:1555
 #, c-format
 msgid "Failed to clone '%s' a second time, aborting"
 msgstr "두번째 '%s' 복제하는데 실패했습니다. 중지합니다"
 
-#: builtin/submodule--helper.c:1568 builtin/submodule--helper.c:1788
+#: builtin/submodule--helper.c:1585 builtin/submodule--helper.c:1808
 msgid "path into the working tree"
 msgstr "작업 폴더로 가는 경로"
 
-#: builtin/submodule--helper.c:1571
+#: builtin/submodule--helper.c:1588
 msgid "path into the working tree, across nested submodule boundaries"
 msgstr "작업 폴더로 가는 경로, 내장된 하위 모듈의 경계 통과"
 
-#: builtin/submodule--helper.c:1575
+#: builtin/submodule--helper.c:1592
 msgid "rebase, merge, checkout or none"
 msgstr "rebase, merge, checkout 또는 none"
 
-#: builtin/submodule--helper.c:1579
+#: builtin/submodule--helper.c:1598
 msgid "Create a shallow clone truncated to the specified number of revisions"
 msgstr "지정한 개수의 리비전에서 잘린 얕은 복제를 만듭니다"
 
-#: builtin/submodule--helper.c:1582
+#: builtin/submodule--helper.c:1601
 msgid "parallel jobs"
 msgstr "병렬 작업 개수"
 
-#: builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1603
 msgid "whether the initial clone should follow the shallow recommendation"
 msgstr "최초 복제가 얕은 복제 추천을 따를지 여부"
 
-#: builtin/submodule--helper.c:1585
+#: builtin/submodule--helper.c:1604
 msgid "don't print cloning progress"
 msgstr "복제 과정을 표시하지 않습니다"
 
-#: builtin/submodule--helper.c:1592
+#: builtin/submodule--helper.c:1611
 msgid "git submodule--helper update_clone [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper update_clone [--prefix=<경로>] [<경로>...]"
 
-#: builtin/submodule--helper.c:1605
+#: builtin/submodule--helper.c:1624
 msgid "bad value for update parameter"
 msgstr "파라미터 업데이트에 값이 잘못되었습니다"
 
-#: builtin/submodule--helper.c:1673
+#: builtin/submodule--helper.c:1692
 #, c-format
 msgid ""
 "Submodule (%s) branch configured to inherit branch from superproject, but "
@@ -13819,20 +14349,20 @@ msgstr ""
 "하위 모듈 (%s) 브랜치가 상위 프로젝트 브랜치를 이어받도록 설정되었지만, 상위 "
 "프로젝트에 브랜치가 없습니다"
 
-#: builtin/submodule--helper.c:1789
+#: builtin/submodule--helper.c:1809
 msgid "recurse into submodules"
 msgstr "하위 모듈에 재귀적으로 적용"
 
-#: builtin/submodule--helper.c:1795
+#: builtin/submodule--helper.c:1815
 msgid "git submodule--helper embed-git-dir [<path>...]"
 msgstr "git submodule--helper embed-git-dir [<경로>...]"
 
-#: builtin/submodule--helper.c:1857
+#: builtin/submodule--helper.c:1901
 #, c-format
 msgid "%s doesn't support --super-prefix"
 msgstr "%s에서 --super-prefix 옵션을 지원하지 않습니다"
 
-#: builtin/submodule--helper.c:1863
+#: builtin/submodule--helper.c:1907
 #, c-format
 msgid "'%s' is not a valid submodule--helper subcommand"
 msgstr "'%s'은(는) 올바른 submodule--helper 하위 명령이 아닙니다"
@@ -13901,7 +14431,7 @@ msgstr "'%s' 태그가 없습니다."
 msgid "Deleted tag '%s' (was %s)\n"
 msgstr "'%s' 태그 삭제함 (과거 %s)\n"
 
-#: builtin/tag.c:131
+#: builtin/tag.c:132
 #, c-format
 msgid ""
 "\n"
@@ -13914,7 +14444,7 @@ msgstr ""
 "  %s\n"
 "'%c' 문자로 시작하는 줄은 무시됩니다.\n"
 
-#: builtin/tag.c:135
+#: builtin/tag.c:136
 #, c-format
 msgid ""
 "\n"
@@ -13928,146 +14458,146 @@ msgstr ""
 "  %s\n"
 "'%c' 문자로 시작하는 줄은 유지됩니다. 제거하려면 직접 지워야 합니다.\n"
 
-#: builtin/tag.c:189
+#: builtin/tag.c:190
 msgid "unable to sign the tag"
 msgstr "태그에 서명할 수 없습니다"
 
-#: builtin/tag.c:191
+#: builtin/tag.c:192
 msgid "unable to write tag file"
 msgstr "태그 파일을 쓸 수 없습니다"
 
-#: builtin/tag.c:216
+#: builtin/tag.c:217
 msgid "bad object type."
 msgstr "잘못된 오브젝트 종류."
 
-#: builtin/tag.c:265
+#: builtin/tag.c:266
 msgid "no tag message?"
 msgstr "태그 메시지 없음?"
 
-#: builtin/tag.c:272
+#: builtin/tag.c:273
 #, c-format
 msgid "The tag message has been left in %s\n"
 msgstr "태그 메시지가 %s 파일에 남아 있습니다\n"
 
-#: builtin/tag.c:381
+#: builtin/tag.c:382
 msgid "list tag names"
 msgstr "태그 이름 목록을 표시합니다"
 
-#: builtin/tag.c:383
+#: builtin/tag.c:384
 msgid "print <n> lines of each tag message"
 msgstr "각 태그 메시지의 <n>줄을 표시합니다"
 
-#: builtin/tag.c:385
+#: builtin/tag.c:386
 msgid "delete tags"
 msgstr "태그를 삭제합니다"
 
-#: builtin/tag.c:386
+#: builtin/tag.c:387
 msgid "verify tags"
 msgstr "태그를 검증합니다"
 
-#: builtin/tag.c:388
+#: builtin/tag.c:389
 msgid "Tag creation options"
 msgstr "태그 만들기 옵션"
 
-#: builtin/tag.c:390
+#: builtin/tag.c:391
 msgid "annotated tag, needs a message"
 msgstr "주석 달린 태그, 메시지가 필요합니다"
 
-#: builtin/tag.c:392
+#: builtin/tag.c:393
 msgid "tag message"
 msgstr "태그 메시지"
 
-#: builtin/tag.c:394
+#: builtin/tag.c:395
 msgid "force edit of tag message"
 msgstr "강제로 태그 메시지를 편집합니다"
 
-#: builtin/tag.c:395
+#: builtin/tag.c:396
 msgid "annotated and GPG-signed tag"
 msgstr "주석 달리고 GPG 서명한 태그"
 
-#: builtin/tag.c:399
+#: builtin/tag.c:400
 msgid "use another key to sign the tag"
 msgstr "태그를 서명하는데 지정한 키를 사용합니다"
 
-#: builtin/tag.c:400
+#: builtin/tag.c:401
 msgid "replace the tag if exists"
 msgstr "태그가 있으면 바꿉니다"
 
-#: builtin/tag.c:401 builtin/update-ref.c:368
+#: builtin/tag.c:402 builtin/update-ref.c:368
 msgid "create a reflog"
 msgstr "reflog를 만듭니다"
 
-#: builtin/tag.c:403
+#: builtin/tag.c:404
 msgid "Tag listing options"
 msgstr "태그 목록 보기 옵션"
 
-#: builtin/tag.c:404
+#: builtin/tag.c:405
 msgid "show tag list in columns"
 msgstr "태그 목록을 여러 열로 표시합니다"
 
-#: builtin/tag.c:405 builtin/tag.c:407
+#: builtin/tag.c:406 builtin/tag.c:408
 msgid "print only tags that contain the commit"
 msgstr "해당 커밋이 들어 있는 태그만 표시합니다"
 
-#: builtin/tag.c:406 builtin/tag.c:408
+#: builtin/tag.c:407 builtin/tag.c:409
 msgid "print only tags that don't contain the commit"
 msgstr "해당 커밋이 들어 있지 않은 태그만 표시합니다"
 
-#: builtin/tag.c:409
+#: builtin/tag.c:410
 msgid "print only tags that are merged"
 msgstr "병합된 태그만 표시합니다"
 
-#: builtin/tag.c:410
+#: builtin/tag.c:411
 msgid "print only tags that are not merged"
 msgstr "병합되지 않은 태그만 표시합니다"
 
-#: builtin/tag.c:415
+#: builtin/tag.c:416
 msgid "print only tags of the object"
 msgstr "해당 오브젝트의 태그만 표시합니다"
 
-#: builtin/tag.c:459
+#: builtin/tag.c:460
 msgid "--column and -n are incompatible"
 msgstr "--column 및 -n 옵션은 호환되지 않습니다"
 
-#: builtin/tag.c:481
+#: builtin/tag.c:482
 msgid "-n option is only allowed in list mode"
 msgstr "-n 옵션은 리스트 모드에서만 허용합니다"
 
-#: builtin/tag.c:483
+#: builtin/tag.c:484
 msgid "--contains option is only allowed in list mode"
 msgstr "--contains 옵션은 리스트 모드에서만 허용합니다"
 
-#: builtin/tag.c:485
+#: builtin/tag.c:486
 msgid "--no-contains option is only allowed in list mode"
 msgstr "--no-contains 옵션은 리스트 모드에서만 허용합니다"
 
-#: builtin/tag.c:487
+#: builtin/tag.c:488
 msgid "--points-at option is only allowed in list mode"
 msgstr "--points-at 옵션은 리스트 모드에서만 허용합니다"
 
-#: builtin/tag.c:489
+#: builtin/tag.c:490
 msgid "--merged and --no-merged options are only allowed in list mode"
 msgstr "--merged 및 --no-merged 옵션은 리스트 모드에서만 허용합니다"
 
-#: builtin/tag.c:500
+#: builtin/tag.c:501
 msgid "only one -F or -m option is allowed."
 msgstr "하나의 -F 또는 -m 옵션만 쓸 수 있습니다."
 
-#: builtin/tag.c:519
+#: builtin/tag.c:520
 msgid "too many params"
 msgstr "파라미터가 너무 많습니다"
 
-#: builtin/tag.c:525
+#: builtin/tag.c:526
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "'%s'은(는) 올바른 태그 이름이 아닙니다."
 
-#: builtin/tag.c:530
+#: builtin/tag.c:531
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "태그 '%s'이(가) 이미 있습니다"
 
-#: builtin/tag.c:561
+#: builtin/tag.c:562
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "태그 '%s' 업데이트 (과거 %s)\n"
@@ -14134,145 +14664,145 @@ msgstr "디렉터리를 삭제한 후에 디렉터리 정보가 바뀌지 않았
 msgid " OK"
 msgstr " 오케이"
 
-#: builtin/update-index.c:579
+#: builtin/update-index.c:589
 msgid "git update-index [<options>] [--] [<file>...]"
 msgstr "git update-index [<옵션>] [--] [<파일>...]"
 
-#: builtin/update-index.c:936
+#: builtin/update-index.c:946
 msgid "continue refresh even when index needs update"
 msgstr "인덱스에 업데이트가 필요하더라도 새로 고침을 계속합니다"
 
-#: builtin/update-index.c:939
+#: builtin/update-index.c:949
 msgid "refresh: ignore submodules"
 msgstr "새로 고침: 하위 모듈 무시"
 
-#: builtin/update-index.c:942
+#: builtin/update-index.c:952
 msgid "do not ignore new files"
 msgstr "새 파일을 무시할 수 않습니다"
 
-#: builtin/update-index.c:944
+#: builtin/update-index.c:954
 msgid "let files replace directories and vice-versa"
 msgstr "디렉터리를 파일로, 또는 그 반대로 바꿀 수 있게 허용합니다"
 
-#: builtin/update-index.c:946
+#: builtin/update-index.c:956
 msgid "notice files missing from worktree"
 msgstr "작업폴더에서 알림 파일이 없습니다"
 
-#: builtin/update-index.c:948
+#: builtin/update-index.c:958
 msgid "refresh even if index contains unmerged entries"
 msgstr "인덱스에 병합하지 않은 항목이 있어도 새로 고칩니다"
 
-#: builtin/update-index.c:951
+#: builtin/update-index.c:961
 msgid "refresh stat information"
 msgstr "파일 정보를 새로 고칩니다"
 
-#: builtin/update-index.c:955
+#: builtin/update-index.c:965
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "--refresh와 동일하지만, assume-unchanged 설정을 무시합니다"
 
-#: builtin/update-index.c:959
+#: builtin/update-index.c:969
 msgid "<mode>,<object>,<path>"
 msgstr "<모드>,<오브젝트>,<경로>"
 
-#: builtin/update-index.c:960
+#: builtin/update-index.c:970
 msgid "add the specified entry to the index"
 msgstr "지정한 항목을 인덱스에 추가합니다"
 
-#: builtin/update-index.c:969
+#: builtin/update-index.c:979
 msgid "mark files as \"not changing\""
 msgstr "파일을 \"바꾸지 않음\"으로 표시합니다"
 
-#: builtin/update-index.c:972
+#: builtin/update-index.c:982
 msgid "clear assumed-unchanged bit"
 msgstr "바꾸지 않음으로 가정 (assumed-unchanged) 비트를 지웁니다"
 
-#: builtin/update-index.c:975
+#: builtin/update-index.c:985
 msgid "mark files as \"index-only\""
 msgstr "파일을 인덱스 전용으로 (\"index-only\") 표시합니다"
 
-#: builtin/update-index.c:978
+#: builtin/update-index.c:988
 msgid "clear skip-worktree bit"
 msgstr "작업폴더 건너뛰기 (skip-worktree) 비트를 지웁니다"
 
-#: builtin/update-index.c:981
+#: builtin/update-index.c:991
 msgid "add to index only; do not add content to object database"
 msgstr ""
 "인덱스에만 추가합니다. 내용을 오브젝트 데이터베이스에 추가하지 않습니다"
 
-#: builtin/update-index.c:983
+#: builtin/update-index.c:993
 msgid "remove named paths even if present in worktree"
 msgstr "작업 폴더에 있어도 해당 경로를 제거합니다"
 
-#: builtin/update-index.c:985
+#: builtin/update-index.c:995
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr "--stdin과 같이 사용: 입력 줄은 NUL 바이트로 끝납니다"
 
-#: builtin/update-index.c:987
+#: builtin/update-index.c:997
 msgid "read list of paths to be updated from standard input"
 msgstr "표준 입력에서 업데이트할 경로의 목록을 읽습니다"
 
-#: builtin/update-index.c:991
+#: builtin/update-index.c:1001
 msgid "add entries from standard input to the index"
 msgstr "표준 입력에서 읽은 항목을 인덱스에 추가합니다"
 
-#: builtin/update-index.c:995
+#: builtin/update-index.c:1005
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr "경로 목록에 대해 #2 및 #3 스테이징을 다시 합니다"
 
-#: builtin/update-index.c:999
+#: builtin/update-index.c:1009
 msgid "only update entries that differ from HEAD"
 msgstr "HEAD와 다른 항목만 업데이트합니다"
 
-#: builtin/update-index.c:1003
+#: builtin/update-index.c:1013
 msgid "ignore files missing from worktree"
 msgstr "작업 폴더에 없는 파일을 무시합니다"
 
-#: builtin/update-index.c:1006
+#: builtin/update-index.c:1016
 msgid "report actions to standard output"
 msgstr "표준 출력에 동작을 알립니다"
 
-#: builtin/update-index.c:1008
+#: builtin/update-index.c:1018
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "저장한 해결되지 않은 충돌을 무시합니다 (사용자용 명령 용도)"
 
-#: builtin/update-index.c:1012
+#: builtin/update-index.c:1022
 msgid "write index in this format"
 msgstr "인덱스를 이 형식으로 씁니다"
 
-#: builtin/update-index.c:1014
+#: builtin/update-index.c:1024
 msgid "enable or disable split index"
 msgstr "스플릿 인덱스를 켜거나 끕니다"
 
-#: builtin/update-index.c:1016
+#: builtin/update-index.c:1026
 msgid "enable/disable untracked cache"
 msgstr "추적하지 않는 캐시 사용을 켜거나 끕니다"
 
-#: builtin/update-index.c:1018
+#: builtin/update-index.c:1028
 msgid "test if the filesystem supports untracked cache"
 msgstr "파일 시스템이 추적하지 않는 캐시를 지원하는지 검사합니다"
 
-#: builtin/update-index.c:1020
+#: builtin/update-index.c:1030
 msgid "enable untracked cache without testing the filesystem"
 msgstr "파일 시스템 시험 없이 추적하지 않는 캐시를 사용합니다"
 
-#: builtin/update-index.c:1022
+#: builtin/update-index.c:1032
 msgid "write out the index even if is not flagged as changed"
 msgstr "변경된 것으로 표시되지 않은 경우에도 인덱스에 씁니다"
 
-#: builtin/update-index.c:1024
+#: builtin/update-index.c:1034
 msgid "enable or disable file system monitor"
 msgstr "파일 시스템 모니터를 켜거나 끕니다"
 
-#: builtin/update-index.c:1026
+#: builtin/update-index.c:1036
 msgid "mark files as fsmonitor valid"
 msgstr ""
 "파일 시스템 모니터링 기능이 변경사항을 확인하는 비트를 파일에 표시합니다"
 
-#: builtin/update-index.c:1029
+#: builtin/update-index.c:1039
 msgid "clear fsmonitor valid bit"
 msgstr "파일 시스템 모니터링 기능이 변경사항을 확인하는 비트를 지웁니다"
 
-#: builtin/update-index.c:1127
+#: builtin/update-index.c:1138
 msgid ""
 "core.splitIndex is set to false; remove or change it, if you really want to "
 "enable split index"
@@ -14280,7 +14810,7 @@ msgstr ""
 "core.splitIndex 값이 거짓입니다. 정말로 스플릿 인덱스를 사용하려면 이 값을 제"
 "거하거나 바꾸십시오."
 
-#: builtin/update-index.c:1136
+#: builtin/update-index.c:1147
 msgid ""
 "core.splitIndex is set to true; remove or change it, if you really want to "
 "disable split index"
@@ -14288,7 +14818,7 @@ msgstr ""
 "core.splitIndex 값이 참입니다. 정말로 스플릿 인덱스를 사용하지 않으려면 이 값"
 "을 제거하거나 바꾸십시오."
 
-#: builtin/update-index.c:1147
+#: builtin/update-index.c:1158
 msgid ""
 "core.untrackedCache is set to true; remove or change it, if you really want "
 "to disable the untracked cache"
@@ -14296,11 +14826,11 @@ msgstr ""
 "core.untrackedCache 값이 참입니다. 정말로 추적하지 않는 캐시를 사용하지 않으"
 "려면 이 값을 제거하거나 바꾸십시오."
 
-#: builtin/update-index.c:1151
+#: builtin/update-index.c:1162
 msgid "Untracked cache disabled"
 msgstr "추적되지 않는 파일 캐시를 사용하지 않습니다"
 
-#: builtin/update-index.c:1159
+#: builtin/update-index.c:1170
 msgid ""
 "core.untrackedCache is set to false; remove or change it, if you really want "
 "to enable the untracked cache"
@@ -14308,29 +14838,29 @@ msgstr ""
 "core.untrackedCache 값이 거짓입니다. 정말로 추적하지 않는 캐시를 사용하려면 "
 "이 값을 제거하거나 바꾸십시오."
 
-#: builtin/update-index.c:1163
+#: builtin/update-index.c:1174
 #, c-format
 msgid "Untracked cache enabled for '%s'"
 msgstr "'%s'에 대해 추적되지 않는 캐시를 사용하지 않습니다"
 
-#: builtin/update-index.c:1171
+#: builtin/update-index.c:1182
 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
 msgstr ""
 "core.fsmonitor가 설정되지 않았습니다. 정말로 파일 시스템 모니터를 사용하려면 "
 "설정하십시오"
 
-#: builtin/update-index.c:1175
+#: builtin/update-index.c:1186
 msgid "fsmonitor enabled"
 msgstr "파일 시스템 모니터가 켜졌습니다"
 
-#: builtin/update-index.c:1178
+#: builtin/update-index.c:1189
 msgid ""
 "core.fsmonitor is set; remove it if you really want to disable fsmonitor"
 msgstr ""
 "core.fsmonitor가 설정되어 있습니다. 정말로 파일 시스템 모니터를 사용하지 않으"
 "려면 설정을 제거하십시오"
 
-#: builtin/update-index.c:1182
+#: builtin/update-index.c:1193
 msgid "fsmonitor disabled"
 msgstr "파일 시스템 모니터가 꺼졌습니다"
 
@@ -14370,9 +14900,26 @@ msgstr "git update-server-info [--force]"
 msgid "update the info files from scratch"
 msgstr "바닥부터 정보 파일을 업데이트합니다"
 
-#: builtin/verify-commit.c:18
-msgid "git verify-commit [-v | --verbose] <commit>..."
-msgstr "git verify-commit [-v | --verbose] <커밋>..."
+#: builtin/upload-pack.c:11
+msgid "git upload-pack [<options>] <dir>"
+msgstr "git upload-pack [<옵션>] <디렉터리>"
+
+#: builtin/upload-pack.c:25
+msgid "exit immediately after initial ref advertisement"
+msgstr "최초 레퍼런스 알림 뒤에 즉시 끝납니다"
+
+#: builtin/upload-pack.c:27
+msgid "do not try <directory>/.git/ if <directory> is no Git directory"
+msgstr ""
+"<디렉터리>가 깃 디렉터리가 아니면 <디렉터리>/.git/ 폴더를 시도하지 않습니다."
+
+#: builtin/upload-pack.c:29
+msgid "interrupt transfer after <n> seconds of inactivity"
+msgstr "<n>초 동안 반응이 없으면 전송을 중지합니다"
+
+#: builtin/verify-commit.c:18
+msgid "git verify-commit [-v | --verbose] <commit>..."
+msgstr "git verify-commit [-v | --verbose] <커밋>..."
 
 #: builtin/verify-commit.c:73
 msgid "print commit contents"
@@ -14430,22 +14977,22 @@ msgstr "git worktree remove [<옵션>] <작업트리>"
 msgid "git worktree unlock <path>"
 msgstr "git worktree unlock <경로>"
 
-#: builtin/worktree.c:60
+#: builtin/worktree.c:58
 #, c-format
 msgid "Removing worktrees/%s: not a valid directory"
 msgstr "worktrees/%s 제거: 올바른 디렉터리가 아닙나다"
 
-#: builtin/worktree.c:66
+#: builtin/worktree.c:64
 #, c-format
 msgid "Removing worktrees/%s: gitdir file does not exist"
 msgstr "worktrees/%s 제거: gitdir 파일이 없습니다"
 
-#: builtin/worktree.c:71 builtin/worktree.c:80
+#: builtin/worktree.c:69 builtin/worktree.c:78
 #, c-format
 msgid "Removing worktrees/%s: unable to read gitdir file (%s)"
 msgstr "worktrees/%s 제거: gitdir 파일을 읽을 수 없습니다 (%s)"
 
-#: builtin/worktree.c:90
+#: builtin/worktree.c:88
 #, c-format
 msgid ""
 "Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read "
@@ -14454,176 +15001,191 @@ msgstr ""
 "작업 트리 제거/%s: 부족하게 읽음 (%<PRIuMAX> 바이트 예상, %<PRIuMAX> 바이트 "
 "읽음)"
 
-#: builtin/worktree.c:98
+#: builtin/worktree.c:96
 #, c-format
 msgid "Removing worktrees/%s: invalid gitdir file"
 msgstr "worktrees/%s 제거: gitdir 파일이 올바르지 않습니다"
 
-#: builtin/worktree.c:114
+#: builtin/worktree.c:105
 #, c-format
 msgid "Removing worktrees/%s: gitdir file points to non-existent location"
 msgstr "worktrees/%s 제거: gitdir 파일이 없는 위치를 가리킵니다"
 
-#: builtin/worktree.c:161
+#: builtin/worktree.c:152
 msgid "report pruned working trees"
 msgstr "잘라낸 작업 폴더를 알립니다"
 
-#: builtin/worktree.c:163
+#: builtin/worktree.c:154
 msgid "expire working trees older than <time>"
 msgstr "<시각>보다 오래 된 작업 폴더를 만료합니다"
 
-#: builtin/worktree.c:238
+#: builtin/worktree.c:229
 #, c-format
 msgid "'%s' already exists"
 msgstr "'%s'이(가) 이미 있습니다"
 
-#: builtin/worktree.c:269
+#: builtin/worktree.c:260
 #, c-format
 msgid "could not create directory of '%s'"
 msgstr "'%s'의 디렉터리를 만들 수 없습니다"
 
-#: builtin/worktree.c:308
+#: builtin/worktree.c:373 builtin/worktree.c:379
+#, c-format
+msgid "Preparing worktree (new branch '%s')"
+msgstr "작업 트리 준비 중 (새 브랜치 '%s')"
+
+#: builtin/worktree.c:375
 #, c-format
-msgid "Preparing %s (identifier %s)"
-msgstr "%s 준비 중 (ID %s)"
+msgid "Preparing worktree (resetting branch '%s'; was at %s)"
+msgstr "작업 트리 준비 중 ('%s' 브랜치 재설정 중. 원래 위치 %s)"
 
-#: builtin/worktree.c:385
+#: builtin/worktree.c:384
+#, c-format
+msgid "Preparing worktree (checking out '%s')"
+msgstr "작업 트리 준비 중 ('%s' 가져오는 중)"
+
+#: builtin/worktree.c:390
+#, c-format
+msgid "Preparing worktree (detached HEAD %s)"
+msgstr "작업 트리 준비 중 (분리된 HEAD %s)"
+
+#: builtin/worktree.c:431
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr "다른 작업 폴더에서 체크아웃했더라도 <브랜치>를 체크아웃합니다"
 
-#: builtin/worktree.c:388
+#: builtin/worktree.c:434
 msgid "create a new branch"
 msgstr "새 브랜치를 만듭니다"
 
-#: builtin/worktree.c:390
+#: builtin/worktree.c:436
 msgid "create or reset a branch"
 msgstr "브랜치를 만들거나 리셋합니다"
 
-#: builtin/worktree.c:392
+#: builtin/worktree.c:438
 msgid "populate the new working tree"
 msgstr "새 작업 폴더를 만듭니다"
 
-#: builtin/worktree.c:393
+#: builtin/worktree.c:439
 msgid "keep the new working tree locked"
 msgstr "새 작업 폴더를 잠궈 둡니다"
 
-#: builtin/worktree.c:395
+#: builtin/worktree.c:441
 msgid "set up tracking mode (see git-branch(1))"
 msgstr "추적 모드를 설정합니다 (git-branch(1) 참고)"
 
-#: builtin/worktree.c:398
+#: builtin/worktree.c:444
 msgid "try to match the new branch name with a remote-tracking branch"
 msgstr "새 브랜치 이름과 리모트 추적 브랜치를 일치 시킵니다"
 
-#: builtin/worktree.c:406
+#: builtin/worktree.c:452
 msgid "-b, -B, and --detach are mutually exclusive"
 msgstr "-b, -B, --detach 옵션 중 하나만 쓸 수 있습니다"
 
-#: builtin/worktree.c:471
+#: builtin/worktree.c:511
 msgid "--[no-]track can only be used if a new branch is created"
 msgstr "--[no-]track 옵션은 새로운 브런치가 생성되었을 경우에만 쓸 수 있습니다"
 
-#: builtin/worktree.c:571
+#: builtin/worktree.c:611
 msgid "reason for locking"
 msgstr "잠그는 이유"
 
-#: builtin/worktree.c:583 builtin/worktree.c:616 builtin/worktree.c:670
-#: builtin/worktree.c:809
+#: builtin/worktree.c:623 builtin/worktree.c:656 builtin/worktree.c:710
+#: builtin/worktree.c:850
 #, c-format
 msgid "'%s' is not a working tree"
 msgstr "'%s'은(는) 작업 폴더가 아닙니다"
 
-#: builtin/worktree.c:585 builtin/worktree.c:618
+#: builtin/worktree.c:625 builtin/worktree.c:658
 msgid "The main working tree cannot be locked or unlocked"
 msgstr "메인 작업 폴더를 잠그거나 잠금 해제할 수 없습니다"
 
-#: builtin/worktree.c:590
+#: builtin/worktree.c:630
 #, c-format
 msgid "'%s' is already locked, reason: %s"
 msgstr "'%s'은(는) 이미 잠겼습니다. 이유: %s"
 
-#: builtin/worktree.c:592
+#: builtin/worktree.c:632
 #, c-format
 msgid "'%s' is already locked"
 msgstr "'%s'은(는) 이미 잠겼습니다"
 
-#: builtin/worktree.c:620
+#: builtin/worktree.c:660
 #, c-format
 msgid "'%s' is not locked"
 msgstr "'%s'은(는) 잠기지 않았습니다"
 
-#: builtin/worktree.c:645
+#: builtin/worktree.c:685
 msgid "working trees containing submodules cannot be moved or removed"
 msgstr "하위 모듈이 포함된 작업 폴더는 옮기거나 제거할 수 없습니다"
 
-#: builtin/worktree.c:672 builtin/worktree.c:811
+#: builtin/worktree.c:712 builtin/worktree.c:852
 #, c-format
 msgid "'%s' is a main working tree"
 msgstr "'%s'은(는) 메인 작업 폴더입니다"
 
-#: builtin/worktree.c:677
+#: builtin/worktree.c:717
 #, c-format
 msgid "could not figure out destination name from '%s'"
 msgstr "'%s'에서 대상 이름을 찾을 수 없습니다"
 
-#: builtin/worktree.c:683
+#: builtin/worktree.c:723
 #, c-format
 msgid "target '%s' already exists"
 msgstr "타게 '%s'이(가) 이미 있습니다"
 
-#: builtin/worktree.c:690
+#: builtin/worktree.c:730
 #, c-format
 msgid "cannot move a locked working tree, lock reason: %s"
 msgstr "잠긴 작업 폴더를 옮길 수 없습니다. 잠긴 이유: %s"
 
-#: builtin/worktree.c:692
+#: builtin/worktree.c:732
 msgid "cannot move a locked working tree"
 msgstr "잠긴 작업 폴더를 옮길 수 없습니다"
 
-#: builtin/worktree.c:695
+#: builtin/worktree.c:735
 #, c-format
 msgid "validation failed, cannot move working tree: %s"
 msgstr "유효성 검사에 실패하여, 작업 폴더를 옮길 수 없습니다: %s"
 
-#: builtin/worktree.c:700
+#: builtin/worktree.c:740
 #, c-format
 msgid "failed to move '%s' to '%s'"
 msgstr "'%s'을(를) '%s'(으)로 옮기는데 실패했습니다"
 
-#: builtin/worktree.c:748
+#: builtin/worktree.c:788
 #, c-format
 msgid "failed to run 'git status' on '%s'"
 msgstr "'%s'에서 'git status'를 실행하는데 실패했습니다"
 
-#: builtin/worktree.c:752
+#: builtin/worktree.c:792
 #, c-format
 msgid "'%s' is dirty, use --force to delete it"
 msgstr "'%s'이(가) 변경 되었습니다,  삭제하려면 --force를 사용하십시오"
 
-#: builtin/worktree.c:757
+#: builtin/worktree.c:797
 #, c-format
 msgid "failed to run 'git status' on '%s', code %d"
 msgstr "'%s'에서 'git status'를 실행하는데 실패했습니다,  코드 %d"
 
-#: builtin/worktree.c:768 builtin/worktree.c:782
+#: builtin/worktree.c:808 builtin/worktree.c:822
 #, c-format
 msgid "failed to delete '%s'"
 msgstr "'%s'을(를) 삭제하는데 실패했습니다"
 
-#: builtin/worktree.c:794
+#: builtin/worktree.c:834
 msgid "force removing even if the worktree is dirty"
 msgstr "작업트리에 변경사항이 있더라도 강제로 제거합니다"
 
-#: builtin/worktree.c:815
+#: builtin/worktree.c:856
 #, c-format
 msgid "cannot remove a locked working tree, lock reason: %s"
 msgstr "잠긴 작업 폴더를 제거할 수 없습니다. 잠긴 이유: %s"
 
-#: builtin/worktree.c:817
+#: builtin/worktree.c:858
 msgid "cannot remove a locked working tree"
 msgstr "잠긴 작업 폴더를 제거할 수 없습니다"
 
-#: builtin/worktree.c:820
+#: builtin/worktree.c:861
 #, c-format
 msgid "validation failed, cannot remove working tree: %s"
 msgstr "유효성 검사에 실패하여, 작업 폴더를 제거할 수 없습니다: %s"
@@ -14644,27 +15206,6 @@ msgstr "하위 디렉터리 <접두어>에 대해 트리 오브젝트를 씁니
 msgid "only useful for debugging"
 msgstr "디버깅 용도로만 사용"
 
-#: upload-pack.c:27
-msgid "git upload-pack [<options>] <dir>"
-msgstr "git upload-pack [<옵션>] <디렉터리>"
-
-#: upload-pack.c:1070
-msgid "quit after a single request/response exchange"
-msgstr "하나의 요청/응답 교환 뒤에 끝납니다"
-
-#: upload-pack.c:1072
-msgid "exit immediately after initial ref advertisement"
-msgstr "최초 레퍼런스 알림 뒤에 즉시 끝납니다"
-
-#: upload-pack.c:1074
-msgid "do not try <directory>/.git/ if <directory> is no Git directory"
-msgstr ""
-"<디렉터리>가 깃 디렉터리가 아니면 <디렉터리>/.git/ 폴더를 시도하지 않습니다."
-
-#: upload-pack.c:1076
-msgid "interrupt transfer after <n> seconds of inactivity"
-msgstr "<n>초 동안 반응이 없으면 전송을 중지합니다"
-
 #: credential-cache--daemon.c:222
 #, c-format
 msgid ""
@@ -14682,21 +15223,23 @@ msgstr ""
 msgid "print debugging messages to stderr"
 msgstr "디버깅 메시지를 표준오류로 출력합니다"
 
-#: git.c:8
+#: git.c:27
 msgid ""
 "git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
 "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
 "           <command> [<args>]"
 msgstr ""
 "git [--version] [--help] [-C <경로>] [-c <이름>=<값>]\n"
 "           [--exec-path[=<경로>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<경로>] [--work-tree=<경로>] [--namespace=<이름>]\n"
 "           <명령> [<인자>]"
 
-#: git.c:15
+#: git.c:34
 msgid ""
 "'git help -a' and 'git help -g' list available subcommands and some\n"
 "concept guides. See 'git help <command>' or 'git help <concept>'\n"
@@ -14706,66 +15249,66 @@ msgstr ""
 "목록을 볼 수 있습니다. 특정 하위 명령어나 개념에 대해 읽어 보려면 'git help\n"
 "<명령>' 또는 'git help <개념>' 명령을 실행하십시오."
 
-#: git.c:95
+#: git.c:173
 #, c-format
 msgid "no directory given for --git-dir\n"
 msgstr "--git-dir에 대한 주어진 디렉터리가 없습니다\n"
 
-#: git.c:109
+#: git.c:187
 #, c-format
 msgid "no namespace given for --namespace\n"
 msgstr "--namespace에 대한 주어진 네임 스페이스가 없습니다\n"
 
-#: git.c:123
+#: git.c:201
 #, c-format
 msgid "no directory given for --work-tree\n"
 msgstr "--work-tree에 대한 주어진 디렉터리가 없습니다\n"
 
-#: git.c:137
+#: git.c:215
 #, c-format
 msgid "no prefix given for --super-prefix\n"
 msgstr "--super-prefix에 대한 접두어가 주어지지 않았습니다\n"
 
-#: git.c:159
+#: git.c:237
 #, c-format
 msgid "-c expects a configuration string\n"
 msgstr "-c는 옵션에는 설정 문자열이 와야 합니다\n"
 
-#: git.c:197
+#: git.c:275
 #, c-format
 msgid "no directory given for -C\n"
 msgstr "-C 옵션에 주어진 디렉터리가 없습니다\n"
 
-#: git.c:212
+#: git.c:300
 #, c-format
 msgid "unknown option: %s\n"
 msgstr "알 수 없는 옵션: %s\n"
 
-#: git.c:687
+#: git.c:765
 #, c-format
 msgid "expansion of alias '%s' failed; '%s' is not a git command\n"
-msgstr "별칭 '%s'의 확장에 실패했습니다; '%s'은(는) 깃 명령이 아닙니다\n"
+msgstr "별칭 '%s'의 확장에 실패했습니다. '%s'은(는) 깃 명령이 아닙니다\n"
 
-#: git.c:699
+#: git.c:777
 #, c-format
 msgid "failed to run command '%s': %s\n"
 msgstr "'%s'을(를) 여는데 실패: %s\n"
 
-#: http.c:342
+#: http.c:348
 #, c-format
 msgid "negative value for http.postbuffer; defaulting to %d"
 msgstr "http.postbuffer이 0보다 작은 값입니다. 기본값 %d"
 
 # HTTP delegation
-#: http.c:363
+#: http.c:369
 msgid "Delegation control is not supported with cURL < 7.22.0"
 msgstr "딜리게이션 컨트롤은 cURL 7.44.0 앞 버전에서는 지원하지 않습니다"
 
-#: http.c:372
+#: http.c:378
 msgid "Public key pinning not supported with cURL < 7.44.0"
 msgstr "공개 키 고정은 cURL 7.44.0 앞 버전에서는 지원하지 않습니다"
 
-#: http.c:1857
+#: http.c:1854
 #, c-format
 msgid ""
 "unable to update url base from redirection:\n"
@@ -14776,7 +15319,7 @@ msgstr ""
 "       요청: %s\n"
 " 리다이렉트: %s"
 
-#: remote-curl.c:345
+#: remote-curl.c:401
 #, c-format
 msgid "redirecting to %s"
 msgstr "%s(으)로 리다이렉트"
@@ -14789,129 +15332,655 @@ msgstr "인자"
 msgid "object filtering"
 msgstr "오브젝트 필터링"
 
-#: common-cmds.h:9
-msgid "start a working area (see also: git help tutorial)"
-msgstr "작업 공간 시작 (참고: git help tutorial)"
+#: parse-options.h:157
+msgid "expiry-date"
+msgstr "만료-시각"
 
-#: common-cmds.h:10
-msgid "work on the current change (see also: git help everyday)"
-msgstr "변경 사항에 대한 작업 (참고: git help everyday)"
+#: parse-options.h:172
+msgid "no-op (backward compatibility)"
+msgstr "아무 동작도 하지 않음 (호환용)"
 
-#: common-cmds.h:11
-msgid "examine the history and state (see also: git help revisions)"
-msgstr "커밋 내역과 상태 보기 (참고: git help revisions)"
+#: parse-options.h:251
+msgid "be more verbose"
+msgstr "더 자세히 표시합니다"
 
-#: common-cmds.h:12
-msgid "grow, mark and tweak your common history"
-msgstr "커밋 내역을 키우고, 표시하고, 조작하기"
+#: parse-options.h:253
+msgid "be more quiet"
+msgstr "더 간략히 표시합니다"
 
-#: common-cmds.h:13
-msgid "collaborate (see also: git help workflows)"
-msgstr "협동 작업 (참고: git help workflows)"
+#: parse-options.h:259
+msgid "use <n> digits to display SHA-1s"
+msgstr "SHA-1 표시에 <n>개의 숫자를 사용합니다"
 
-#: common-cmds.h:17
+#: command-list.h:50
 msgid "Add file contents to the index"
 msgstr "파일 내용을 인덱스에 추가합니다"
 
-#: common-cmds.h:18
+#: command-list.h:51
+msgid "Apply a series of patches from a mailbox"
+msgstr "메일함에서 연속된 패치를 적용합니다"
+
+#: command-list.h:52
+msgid "Annotate file lines with commit information"
+msgstr "파일 줄마다 커밋 정보를 표시합니다"
+
+#: command-list.h:53
+msgid "Apply a patch to files and/or to the index"
+msgstr "패치를 파일 및/또는 인덱스에 적용합니다"
+
+#: command-list.h:54
+msgid "Import an Arch repository into Git"
+msgstr "arch 저장소를 깃 저장소로 가져옵니다"
+
+#: command-list.h:55
+msgid "Create an archive of files from a named tree"
+msgstr "지정한 트리에 들어 있는 파일의 아카이브를 만듭니다"
+
+#: command-list.h:56
 msgid "Use binary search to find the commit that introduced a bug"
 msgstr "이진 탐색으로 버그를 만들어낸 커밋을 찾습니다"
 
-#: common-cmds.h:19
+#: command-list.h:57
+msgid "Show what revision and author last modified each line of a file"
+msgstr "파일 줄마다 끝에 마지막으로 수정한 리비전과 작성자를 표시합니다"
+
+#: command-list.h:58
 msgid "List, create, or delete branches"
 msgstr "브랜치를 만들거나, 삭제하거나, 목록을 출력합니다"
 
-#: common-cmds.h:20
+#: command-list.h:59
+msgid "Move objects and refs by archive"
+msgstr "아카이브 형태로 오브젝트와 레퍼런스를 옮깁니다"
+
+#: command-list.h:60
+msgid "Provide content or type and size information for repository objects"
+msgstr "저장소 오브젝트에 대해 내용 또는 종류와 크기 정보를 표시합니다"
+
+#: command-list.h:61
+msgid "Display gitattributes information"
+msgstr "gitattributes 정보를 표시합니다"
+
+#: command-list.h:62
+msgid "Debug gitignore / exclude files"
+msgstr "gitignore / 제외할 파일을 디버깅합니다"
+
+#: command-list.h:63
+msgid "Show canonical names and email addresses of contacts"
+msgstr "연락처의 전체 이름과 메일 주소를 표시합니다"
+
+#: command-list.h:64
 msgid "Switch branches or restore working tree files"
 msgstr "브랜치를 전환하거나 작업 파일을 복구합니다"
 
-#: common-cmds.h:21
+#: command-list.h:65
+msgid "Copy files from the index to the working tree"
+msgstr "인덱스의 파일을 작업 폴더로 복사합니다"
+
+#: command-list.h:66
+msgid "Ensures that a reference name is well formed"
+msgstr "레퍼런스 이름의 형식이 올바른지 확인합니다"
+
+#: command-list.h:67
+msgid "Find commits yet to be applied to upstream"
+msgstr "업스트림에 적용해야 할 커밋을 찾습니다"
+
+#: command-list.h:68
+msgid "Apply the changes introduced by some existing commits"
+msgstr "기존 커밋으로 발생한 변경 사항을 적용합니다"
+
+#: command-list.h:69
+msgid "Graphical alternative to git-commit"
+msgstr "git-commit의 그래픽 대체 버전"
+
+#: command-list.h:70
+msgid "Remove untracked files from the working tree"
+msgstr "작업 폴더에서 추적되지 않는 파일을 제거합니다"
+
+#: command-list.h:71
 msgid "Clone a repository into a new directory"
-msgstr "저장소를 복제해 새 디렉터리로 가져 옵니다"
+msgstr "저장소를 복제해 새 디렉터리로 가져옵니다"
 
-#: common-cmds.h:22
+#: command-list.h:72
+msgid "Display data in columns"
+msgstr "데이터를 여러 열로 표시합니다"
+
+#: command-list.h:73
 msgid "Record changes to the repository"
 msgstr "바뀐 사항을 저장소에 기록합니다"
 
-#: common-cmds.h:23
+#: command-list.h:74
+msgid "Write and verify Git commit graph files"
+msgstr "깃 커밋 그래프 파일을 쓰고 확인합니다"
+
+#: command-list.h:75
+msgid "Create a new commit object"
+msgstr "새 커밋 오브젝트를 만듭니다"
+
+#: command-list.h:76
+msgid "Get and set repository or global options"
+msgstr "저장소 옵션 또는 전체 옵션을 보거나 설정합니다"
+
+#: command-list.h:77
+msgid "Count unpacked number of objects and their disk consumption"
+msgstr "묶여지지 않은 오브젝트의 개수 및 그 디스크 사용량을 측정합니다"
+
+#: command-list.h:78
+msgid "Retrieve and store user credentials"
+msgstr "사용자 비밀 정보를 가져오고 저장합니다"
+
+#: command-list.h:79
+msgid "Helper to temporarily store passwords in memory"
+msgstr "메모리에 임시로 암호 저장하는 도움 명령"
+
+#: command-list.h:80
+msgid "Helper to store credentials on disk"
+msgstr "비밀 정보를 디스크에 저장하는 도움 명령"
+
+#: command-list.h:81
+msgid "Export a single commit to a CVS checkout"
+msgstr "하나의 커밋을 CVS 체크아웃으로 내보냅니다"
+
+# * "people love to hate" 번역은 전달하기 힘들고 빠져도 내용 문제가 없으므로 생략
+#: command-list.h:82
+msgid "Salvage your data out of another SCM people love to hate"
+msgstr "다른 소스 코드 관리 시스템에서 데이터 가져오기"
+
+#: command-list.h:83
+msgid "A CVS server emulator for Git"
+msgstr "깃용 CVS 서버 에뮬레이터"
+
+#: command-list.h:84
+msgid "A really simple server for Git repositories"
+msgstr "깃 저장소에 대한 아주 간단한 서버"
+
+#: command-list.h:85
+msgid "Give an object a human readable name based on an available ref"
+msgstr "사용 가능한 레퍼런스를 기준으로 오브젝트에 읽을 수 있는 이름을 부여합니다"
+
+#: command-list.h:86
 msgid "Show changes between commits, commit and working tree, etc"
 msgstr "커밋과 커밋 사이, 커밋과 작업 내용 사이 등의 바뀐 점을 봅니다"
 
-#: common-cmds.h:24
+#: command-list.h:87
+msgid "Compares files in the working tree and the index"
+msgstr "작업 폴더와 인덱스의 파일을 비교합니다"
+
+#: command-list.h:88
+msgid "Compare a tree to the working tree or index"
+msgstr "트리를 작업 폴더나 인덱스와 비교합니다"
+
+#: command-list.h:89
+msgid "Compares the content and mode of blobs found via two tree objects"
+msgstr "두 개의 트리 오브젝트에 있는 내용과 블롭의 모드를 비교합니다"
+
+#: command-list.h:90
+msgid "Show changes using common diff tools"
+msgstr "일반적인 diff 도구를 사용해 변경 사항을 표시합니다"
+
+#: command-list.h:91
+msgid "Git data exporter"
+msgstr "깃 데이터 내보내기"
+
+#: command-list.h:92
+msgid "Backend for fast Git data importers"
+msgstr "고속 깃 데이터 가져오기 백엔드"
+
+#: command-list.h:93
 msgid "Download objects and refs from another repository"
 msgstr "다른 저장소에서 오브젝트와 레퍼런스를 다운로드합니다"
 
-#: common-cmds.h:25
+#: command-list.h:94
+msgid "Receive missing objects from another repository"
+msgstr "다른 저장소에서 없는 오브젝트를 다운로드합니다"
+
+#: command-list.h:95
+msgid "Rewrite branches"
+msgstr "리모트 브랜치"
+
+#: command-list.h:96
+msgid "Produce a merge commit message"
+msgstr "병합 커밋 메시지를 만듭니다"
+
+#: command-list.h:97
+msgid "Output information on each ref"
+msgstr "각 레퍼런스의 정보를 출력합니다"
+
+#: command-list.h:98
+msgid "Prepare patches for e-mail submission"
+msgstr "메일 제출 용도로 패치를 준비합니다"
+
+#: command-list.h:99
+msgid "Verifies the connectivity and validity of the objects in the database"
+msgstr "연결을 확인하고 데이터베이스의 오브젝트가 올바른지 확인합니다"
+
+#: command-list.h:100
+msgid "Cleanup unnecessary files and optimize the local repository"
+msgstr "불필요한 파일을 지우고 로컬 저장소를 최적화합니다"
+
+#: command-list.h:101
+msgid "Extract commit ID from an archive created using git-archive"
+msgstr "git-archive로 만든 아카이브에서 커밋 ID를 추출합니다"
+
+#: command-list.h:102
 msgid "Print lines matching a pattern"
 msgstr "패턴과 일치하는 줄을 표시합니다"
 
-#: common-cmds.h:26
+#: command-list.h:103
+msgid "A portable graphical interface to Git"
+msgstr "깃의 포터블 그래픽 인터페이스"
+
+#: command-list.h:104
+msgid "Compute object ID and optionally creates a blob from a file"
+msgstr "오브젝트 ID를 계산하고 선택적으로 파일의 블롭을 만듭니다"
+
+#: command-list.h:105
+msgid "Display help information about Git"
+msgstr "깃의 도움말 정보를 표시합니다"
+
+#: command-list.h:106
+msgid "Server side implementation of Git over HTTP"
+msgstr "깃 HTTP 프로토콜의 서버측 구현"
+
+#: command-list.h:107
+msgid "Download from a remote Git repository via HTTP"
+msgstr "원격 깃 저장소에서 HTTP를 통해 다운로드합니다"
+
+#: command-list.h:108
+msgid "Push objects over HTTP/DAV to another repository"
+msgstr "오브젝트를 HTTP/DAV를 통해 다른 저장소로 푸시합니다"
+
+#: command-list.h:109
+msgid "Send a collection of patches from stdin to an IMAP folder"
+msgstr "표준입력에서 패치 모음을 읽어 IMAP 폴더로 보냅니다"
+
+#: command-list.h:110
+msgid "Build pack index file for an existing packed archive"
+msgstr "기존 묶음 아카이브에 대한 묶음 인덱스 파일을 만듭니다"
+
+#: command-list.h:111
 msgid "Create an empty Git repository or reinitialize an existing one"
 msgstr "빈 깃 저장소를 만들거나 기존 저장소를 다시 초기화합니다"
 
-#: common-cmds.h:27
+#: command-list.h:112
+msgid "Instantly browse your working repository in gitweb"
+msgstr "내 작업 저장소를 gitweb에서 즉시 살펴봅니다"
+
+# * "Signed-off-by: name" 같은 정보를 말한다
+#: command-list.h:113
+msgid "add or parse structured information in commit messages"
+msgstr "커밋 메시지에 구조화된 정보를 추가하거나 정보를 파싱합니다"
+
+#: command-list.h:114
+msgid "The Git repository browser"
+msgstr "깃 저장소 살펴보기"
+
+#: command-list.h:115
 msgid "Show commit logs"
 msgstr "커밋 기록을 표시합니다"
 
-#: common-cmds.h:28
+#: command-list.h:116
+msgid "Show information about files in the index and the working tree"
+msgstr "인덱스와 작업 폴더의 파일에 대한 정보를 표시합니다"
+
+#: command-list.h:117
+msgid "List references in a remote repository"
+msgstr "원격 저장소의 레퍼런스를 열거합니다"
+
+#: command-list.h:118
+msgid "List the contents of a tree object"
+msgstr "트리 오브젝트의 내용을 열거합니다"
+
+#: command-list.h:119
+msgid "Extracts patch and authorship from a single e-mail message"
+msgstr "하나의 메일 메시지에서 패치와 작성자 정보를 뽑아냅니다"
+
+#: command-list.h:120
+msgid "Simple UNIX mbox splitter program"
+msgstr "간단한 유닉스 mbox 쪼개기 프로그램"
+
+#: command-list.h:121
 msgid "Join two or more development histories together"
 msgstr "여러 개의 개발 내역을 하나로 합칩니다"
 
-#: common-cmds.h:29
+#: command-list.h:122
+msgid "Find as good common ancestors as possible for a merge"
+msgstr "병합에 사용할 최선의 공통 과거 커밋을 찾습니다"
+
+#: command-list.h:123
+msgid "Run a three-way file merge"
+msgstr "3-방향 파일 병합을 실행합니다"
+
+#: command-list.h:124
+msgid "Run a merge for files needing merging"
+msgstr "병합이 필요한 파일에 대해 병합을 실행합니다"
+
+#: command-list.h:125
+msgid "The standard helper program to use with git-merge-index"
+msgstr "git-merge-index와 같이 사용하는 기본 도움 프로그램"
+
+#: command-list.h:126
+msgid "Run merge conflict resolution tools to resolve merge conflicts"
+msgstr "병합 충돌 상황에서 병합 충돌 해결 도구를 실행합니다"
+
+#: command-list.h:127
+msgid "Show three-way merge without touching index"
+msgstr "인덱스를 바꾸지 않고 3-방향 병합을 표시합니다"
+
+#: command-list.h:128
+msgid "Creates a tag object"
+msgstr "태그 오브젝트를 만듭니다"
+
+#: command-list.h:129
+msgid "Build a tree-object from ls-tree formatted text"
+msgstr "ls-tree 포맷의 텍스트에서 tree-object를 만듭니다"
+
+#: command-list.h:130
 msgid "Move or rename a file, a directory, or a symlink"
 msgstr "파일, 디렉터리, 심볼릭 링크를 옮기거나 이름을 바꿉니다"
 
-#: common-cmds.h:30
+#: command-list.h:131
+msgid "Find symbolic names for given revs"
+msgstr "주어진 리비전에 대한 심볼 이름을 찾습니다"
+
+#: command-list.h:132
+msgid "Add or inspect object notes"
+msgstr "오브젝트 노트를 추가하거나 살펴봅니다"
+
+#: command-list.h:133
+msgid "Import from and submit to Perforce repositories"
+msgstr "Perforce 저장소에서 가져오거나 저장소로 제출합니다"
+
+#: command-list.h:134
+msgid "Create a packed archive of objects"
+msgstr "오브젝트의 묶음 아카이브를 만듭니다"
+
+#: command-list.h:135
+msgid "Find redundant pack files"
+msgstr "중복된 묶음 파일을 찾습니다"
+
+#: command-list.h:136
+msgid "Pack heads and tags for efficient repository access"
+msgstr "효율적인 저장소 접근을 위해 헤드와 태그를 묶습니다"
+
+#: command-list.h:137
+msgid "Routines to help parsing remote repository access parameters"
+msgstr "원격 저장소 접근 파라미터를 파싱하는데 사용하는 공통 기능"
+
+#: command-list.h:138
+msgid "Compute unique ID for a patch"
+msgstr "패치에 대한 유일한 ID를 계산합니다"
+
+#: command-list.h:139
+msgid "Prune all unreachable objects from the object database"
+msgstr "오브젝트 데이터베이스에서 도달할 수 없는 오브젝트를 모두 잘라냅니다"
+
+#: command-list.h:140
+msgid "Remove extra objects that are already in pack files"
+msgstr "묶음 파일에 이미 들어 있는 오브젝트를 추가로 제거합니다"
+
+#: command-list.h:141
 msgid "Fetch from and integrate with another repository or a local branch"
 msgstr "다른 저장소 또는 다른 로컬 브랜치에서 가져오거나 통합합니다"
 
-#: common-cmds.h:31
+#: command-list.h:142
 msgid "Update remote refs along with associated objects"
 msgstr "원격 레퍼런스 및 그와 관련된 오브젝트를 업데이트합니다"
 
-#: common-cmds.h:32
+#: command-list.h:143
+msgid "Applies a quilt patchset onto the current branch"
+msgstr "현재 브랜치에 quilt 패치 모음을 적용합니다"
+
+#: command-list.h:144
+msgid "Reads tree information into the index"
+msgstr "트리 정보를 인덱스로 읽습니다"
+
+#: command-list.h:145
 msgid "Reapply commits on top of another base tip"
 msgstr "커밋을 다른 베이스 끝의 최상위에서 적용합니다"
 
-#: common-cmds.h:33
+#: command-list.h:146
+msgid "Receive what is pushed into the repository"
+msgstr "저장소에 푸시한 내용을 받습니다"
+
+#: command-list.h:147
+msgid "Manage reflog information"
+msgstr "reflog 정보를 관리합니다"
+
+#: command-list.h:148
+msgid "Manage set of tracked repositories"
+msgstr "추적하는 저장소 모음을 관리합니다"
+
+#: command-list.h:149
+msgid "Pack unpacked objects in a repository"
+msgstr "저장소의 묶여지지 않은 오브젝트를 묶습니다"
+
+#: command-list.h:150
+msgid "Create, list, delete refs to replace objects"
+msgstr "오브젝트를 바꾸는 레퍼런스를 만들거나, 표시하거나, 삭제합니다"
+
+#: command-list.h:151
+msgid "Generates a summary of pending changes"
+msgstr "예정된 변경 사항의 요약을 만듭니다"
+
+#: command-list.h:152
+msgid "Reuse recorded resolution of conflicted merges"
+msgstr "충돌하는 병합의 기록된 해결 방법을 다시 사용합니다"
+
+#: command-list.h:153
 msgid "Reset current HEAD to the specified state"
 msgstr "현재 HEAD를 지정한 상태로 재설정화합니다"
 
-#: common-cmds.h:34
+#: command-list.h:154
+msgid "Revert some existing commits"
+msgstr "기존 커밋을 되돌립니다"
+
+#: command-list.h:155
+msgid "Lists commit objects in reverse chronological order"
+msgstr "시간 반대 순서에 따라 커밋 오브젝트를 열거합니다"
+
+#: command-list.h:156
+msgid "Pick out and massage parameters"
+msgstr "파라미터를 찾아내서 조정합니다"
+
+#: command-list.h:157
 msgid "Remove files from the working tree and from the index"
 msgstr "파일을 작업 폴더에서 제거하고 인덱스에서도 제거합니다"
 
-#: common-cmds.h:35
+#: command-list.h:158
+msgid "Send a collection of patches as emails"
+msgstr "패치 모음을 메일로 보냅니다"
+
+#: command-list.h:159
+msgid "Push objects over Git protocol to another repository"
+msgstr "오브젝트를 깃 프로토콜을 통해 다른 저장소로 푸시합니다"
+
+#: command-list.h:160
+msgid "Restricted login shell for Git-only SSH access"
+msgstr "깃만 사용하는 SSH 접근에 필요한 제한된 로그인 셸"
+
+#: command-list.h:161
+msgid "Summarize 'git log' output"
+msgstr "'git log' 출력을 요약합니다"
+
+#: command-list.h:162
 msgid "Show various types of objects"
 msgstr "여러가지 종류의 오브젝트를 표시합니다"
 
-#: common-cmds.h:36
+#: command-list.h:163
+msgid "Show branches and their commits"
+msgstr "브랜치 목록과 그 커밋을 표시합니다"
+
+#: command-list.h:164
+msgid "Show packed archive index"
+msgstr "묶여진 아카이브 인덱스를 표시합니다"
+
+#: command-list.h:165
+msgid "List references in a local repository"
+msgstr "로컬 저장소의 레퍼런스를 열거합니다"
+
+#: command-list.h:166
+msgid "Git's i18n setup code for shell scripts"
+msgstr "셸 스크립트를 위한 깃의 국제화 준비 코드"
+
+#: command-list.h:167
+msgid "Common Git shell script setup code"
+msgstr "공통 깃 셸 스크립트 준비 코드"
+
+#: command-list.h:168
+msgid "Stash the changes in a dirty working directory away"
+msgstr "작업 폴더의 변경 사항을 임시로 다른 곳에 저장합니다"
+
+#: command-list.h:169
+msgid "Add file contents to the staging area"
+msgstr "파일 내용을 스테이징 영역에 추가합니다"
+
+#: command-list.h:170
 msgid "Show the working tree status"
 msgstr "작업 폴더 상태를 표시합니다"
 
-#: common-cmds.h:37
+#: command-list.h:171
+msgid "Remove unnecessary whitespace"
+msgstr "불필요한 공백 문자를 제거합니다"
+
+#: command-list.h:172
+msgid "Initialize, update or inspect submodules"
+msgstr "하위 모듈을 초기화하거나, 업데이트하거나, 조사합니다"
+
+#: command-list.h:173
+msgid "Bidirectional operation between a Subversion repository and Git"
+msgstr "서브버전 저장소와 깃 사이의 양방향 동작"
+
+#: command-list.h:174
+msgid "Read, modify and delete symbolic refs"
+msgstr "심볼릭 레퍼런스를 읽고, 수정하고, 삭제합니다"
+
+#: command-list.h:175
 msgid "Create, list, delete or verify a tag object signed with GPG"
 msgstr "태그를 만들거나, 표시하거나, 삭제하거나, GPG 서명을 검증합니다"
 
-#: parse-options.h:157
-msgid "expiry-date"
-msgstr "ë§\8cë£\8c\8b\9cê°\81"
+#: command-list.h:176
+msgid "Creates a temporary file with a blob's contents"
+msgstr "ë¸\94ë¡­ì\9d\98 ë\82´ì\9a©ì\9c¼ë¡\9c ì\9e\84ì\8b\9c í\8c\8cì\9d¼ì\9d\84 ë§\8cë\93­ë\8b\88ë\8b¤"
 
-#: parse-options.h:172
-msgid "no-op (backward compatibility)"
-msgstr "아무 동작도 하지 않음 (호환용)"
+#: command-list.h:177
+msgid "Unpack objects from a packed archive"
+msgstr "묶음 아카이브에서 오브젝트를 풀어냅니다"
 
-#: parse-options.h:250
-msgid "be more verbose"
-msgstr "더 자세히 표시합니다"
+#: command-list.h:178
+msgid "Register file contents in the working tree to the index"
+msgstr "작업 폴더에서 파일 내용을 인덱스에 등록합니다"
 
-#: parse-options.h:252
-msgid "be more quiet"
-msgstr "ë\8d\94 ê°\84ë\9eµí\9e\88 í\91\9cì\8b\9c합니다"
+#: command-list.h:179
+msgid "Update the object name stored in a ref safely"
+msgstr "ë \88í\8d¼ë\9f°ì\8a¤ì\97\90 ì \80ì\9e¥ë\90\9c ì\98¤ë¸\8cì \9dí\8a¸ ì\9d´ë¦\84ì\9d\84 ì\95\88ì \84í\95\98ê²\8c ì\97\85ë\8d°ì\9d´í\8a¸합니다"
 
-#: parse-options.h:258
-msgid "use <n> digits to display SHA-1s"
-msgstr "SHA-1 표시에 <n>개의 숫자를 사용합니다"
+#: command-list.h:180
+msgid "Update auxiliary info file to help dumb servers"
+msgstr "단순 서버에 도움을 주도록 보조 정보 파일을 업데이트합니다"
+
+#: command-list.h:181
+msgid "Send archive back to git-archive"
+msgstr "아카이브를 다시 git-archive로 보냅니다"
+
+#: command-list.h:182
+msgid "Send objects packed back to git-fetch-pack"
+msgstr "묶은 오브젝트를 다시 git-fetch-pack으로 보냅니다"
+
+#: command-list.h:183
+msgid "Show a Git logical variable"
+msgstr "깃의 논리적 변수를 표시합니다"
+
+#: command-list.h:184
+msgid "Check the GPG signature of commits"
+msgstr "커밋의 GPG 서명을 확인합니다"
+
+#: command-list.h:185
+msgid "Validate packed Git archive files"
+msgstr "묶음 깃 아카이브 파일을 검증합니다"
+
+#: command-list.h:186
+msgid "Check the GPG signature of tags"
+msgstr "태그의 GPG 서명을 확인합니다"
+
+#: command-list.h:187
+msgid "Git web interface (web frontend to Git repositories)"
+msgstr "깃 웹 인터페이스 (깃 저장소에 대한 웹 프론트엔드)"
+
+#: command-list.h:188
+msgid "Show logs with difference each commit introduces"
+msgstr "각 커밋으로 발생하는 차이점마다 기록을 표시합니다"
+
+#: command-list.h:189
+msgid "Manage multiple working trees"
+msgstr "여러 개의 작업 폴더를 관리합니다"
+
+#: command-list.h:190
+msgid "Create a tree object from the current index"
+msgstr "현재 인덱스에서 트리 오브젝트를 만듭니다"
+
+#: command-list.h:191
+msgid "Defining attributes per path"
+msgstr "경로마다 속성 정의하기"
+
+#: command-list.h:192
+msgid "Git command-line interface and conventions"
+msgstr "깃 명령행 인터페이스 및 관습"
+
+#: command-list.h:193
+msgid "A Git core tutorial for developers"
+msgstr "개발자를 위한 깃 핵심 따라하기 문서"
+
+#: command-list.h:194
+msgid "Git for CVS users"
+msgstr "CVS 사용자를 위한 깃"
+
+#: command-list.h:195
+msgid "Tweaking diff output"
+msgstr "diff 출력 미세 조정"
+
+#: command-list.h:196
+msgid "A useful minimum set of commands for Everyday Git"
+msgstr "매일매일 유용하게 사용할 최소한의 깃 명령어 모음"
+
+#: command-list.h:197
+msgid "A Git Glossary"
+msgstr "깃 용어 사전"
+
+#: command-list.h:198
+msgid "Hooks used by Git"
+msgstr "깃에서 사용하는 후크"
+
+#: command-list.h:199
+msgid "Specifies intentionally untracked files to ignore"
+msgstr "의도적으로 추적하지 않는 파일을 무시하게 지정하기"
+
+#: command-list.h:200
+msgid "Defining submodule properties"
+msgstr "하위 모듈 속성 정의하기"
+
+#: command-list.h:201
+msgid "Git namespaces"
+msgstr "깃 네임스페이스"
+
+#: command-list.h:202
+msgid "Git Repository Layout"
+msgstr "깃 저장소 구조"
+
+#: command-list.h:203
+msgid "Specifying revisions and ranges for Git"
+msgstr "깃의 리비전 및 범위를 지정하기"
+
+#: command-list.h:204
+msgid "A tutorial introduction to Git: part two"
+msgstr "깃 따라하기 안내서: 2부"
+
+#: command-list.h:205
+msgid "A tutorial introduction to Git"
+msgstr "깃 따라하기 안내서"
+
+#: command-list.h:206
+msgid "An overview of recommended workflows with Git"
+msgstr "추천하는 깃 활용 작업 순서의 개요"
 
 #: rerere.h:40
 msgid "update the index with reused conflict resolution if possible"
@@ -15137,7 +16206,7 @@ msgstr "$pretty_name에 간단한 병합 시도합니다"
 msgid "Simple merge did not work, trying automatic merge."
 msgstr "간단한 병합이 동작하지 않습니다. 자동 병합을 시도합니다."
 
-#: git-rebase.sh:60
+#: git-rebase.sh:61
 msgid ""
 "Resolve all conflicts manually, mark them as resolved with\n"
 "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
@@ -15153,41 +16222,41 @@ msgstr ""
 "abort\"\n"
 "명령을 실행하십시오."
 
-#: git-rebase.sh:163 git-rebase.sh:409
+#: git-rebase.sh:173 git-rebase.sh:442
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "'$head_name' 위치로 돌아갈 수 없습니다"
 
-#: git-rebase.sh:174
+#: git-rebase.sh:184
 msgid "Applied autostash."
 msgstr "자동스태시 적용."
 
-#: git-rebase.sh:177
+#: git-rebase.sh:187
 #, sh-format
 msgid "Cannot store $stash_sha1"
 msgstr "\"$stash_sha1\"을(를) 저장할 수 없습니다"
 
-#: git-rebase.sh:218
+#: git-rebase.sh:229
 msgid "The pre-rebase hook refused to rebase."
 msgstr "리베이스 전 후크에서 리베이스를 거부했습니다."
 
-#: git-rebase.sh:223
+#: git-rebase.sh:234
 msgid "It looks like 'git am' is in progress. Cannot rebase."
 msgstr "'git am'이 진행 중인 것처럼 보입니다. 리베이스할 수 없습니다."
 
-#: git-rebase.sh:370
+#: git-rebase.sh:403
 msgid "No rebase in progress?"
 msgstr "리베이스가 진행 중이지 않습니다"
 
-#: git-rebase.sh:381
+#: git-rebase.sh:414
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr "--edit-todo 동작은 대화형 리베이스에서만 사용할 수 있습니다."
 
-#: git-rebase.sh:388
+#: git-rebase.sh:421
 msgid "Cannot read HEAD"
 msgstr "HEAD를 읽을 수 없습니다"
 
-#: git-rebase.sh:391
+#: git-rebase.sh:424
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -15195,7 +16264,7 @@ msgstr ""
 "모든 병합 충돌을 편집하고 git add\n"
 "명령으로 해결되었다고 표시해야 합니다"
 
-#: git-rebase.sh:435
+#: git-rebase.sh:468
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -15216,74 +16285,79 @@ msgstr ""
 "이 명령을 다시 실행하십시오. 중요한 사항이 남아 있을 경우를\n"
 "대비해 여기서 멈춥니다."
 
-#: git-rebase.sh:491
+#: git-rebase.sh:509
+msgid "error: cannot combine '--signoff' with '--preserve-merges'"
+msgstr ""
+"오류: '--signoff' 옵션과 '--preserve-merges' 옵션을 같이 쓸 수 없습니다"
+
+#: git-rebase.sh:537
 #, sh-format
 msgid "invalid upstream '$upstream_name'"
 msgstr "잘못된 업스트림 '$upstream_name'"
 
-#: git-rebase.sh:515
+#: git-rebase.sh:561
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name: 여러 개의 병합 베이스가 있습니다"
 
-#: git-rebase.sh:518 git-rebase.sh:522
+#: git-rebase.sh:564 git-rebase.sh:568
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name: 병합 베이스가 없습니다"
 
-#: git-rebase.sh:527
+#: git-rebase.sh:573
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "올바른 커밋을 가리키지 않습니다: $onto_name"
 
-#: git-rebase.sh:553
+#: git-rebase.sh:599
 #, sh-format
 msgid "fatal: no such branch/commit '$branch_name'"
 msgstr "치명적 이상: 그런 브랜치/커밋이 없습니다 '$branch_name'"
 
-#: git-rebase.sh:586
+#: git-rebase.sh:632
 msgid "Cannot autostash"
 msgstr "자동 스태시를 할 수 없습니다"
 
-#: git-rebase.sh:591
+#: git-rebase.sh:637
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "자동 스태시를 만들었습니다: $stash_abbrev"
 
-#: git-rebase.sh:595
+#: git-rebase.sh:641
 msgid "Please commit or stash them."
 msgstr "커밋하거나 스태시에 넣으십시오."
 
-#: git-rebase.sh:618
+#: git-rebase.sh:664
 #, sh-format
 msgid "HEAD is up to date."
 msgstr "HEAD가 최신 상태입니다."
 
-#: git-rebase.sh:620
+#: git-rebase.sh:666
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "현재 브랜치가 ($branch_name) 최신 상태입니다."
 
-#: git-rebase.sh:628
+#: git-rebase.sh:674
 #, sh-format
 msgid "HEAD is up to date, rebase forced."
 msgstr "HEAD가 최신 상태입니다. 강제 리베이스합니다."
 
-#: git-rebase.sh:630
+#: git-rebase.sh:676
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr "현재 브랜치가 ($branch_name) 최신 상태입니다. 강제 리베이스합니다."
 
-#: git-rebase.sh:642
+#: git-rebase.sh:688
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "변경 사항 '$mb'에서 '$onto'(으)로:"
 
-#: git-rebase.sh:651
+#: git-rebase.sh:697
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr "작업 사항을 다시 넣기 위해 먼저 헤드를 뒤로 돌립니다..."
 
-#: git-rebase.sh:661
+#: git-rebase.sh:707
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "$branch_name 브랜치를 $onto_name 위치로 정방향 진행합니다."
@@ -15352,109 +16426,109 @@ msgstr "현재 상태를 저장할 수 없습니다"
 msgid "Saved working directory and index state $stash_msg"
 msgstr "작업 폴더와 $stash_msg 인덱스 상태를 저장했습니다"
 
-#: git-stash.sh:340
+#: git-stash.sh:342
 msgid "Cannot remove worktree changes"
 msgstr "작업폴더 변경 사항을 제거할 수 없습니다"
 
-#: git-stash.sh:488
+#: git-stash.sh:490
 #, sh-format
 msgid "unknown option: $opt"
 msgstr "알 수 없는 옵션: $opt"
 
-#: git-stash.sh:501
+#: git-stash.sh:503
 msgid "No stash entries found."
 msgstr "스태시 항목이 없습니다."
 
-#: git-stash.sh:508
+#: git-stash.sh:510
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "너무 많은 리비전을 지정했습니다: $REV"
 
-#: git-stash.sh:523
+#: git-stash.sh:525
 #, sh-format
 msgid "$reference is not a valid reference"
 msgstr "$reference은(는) 올바른 레퍼런스가 아닙니다"
 
-#: git-stash.sh:551
+#: git-stash.sh:553
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "'$args'은(는) 스태시 커밋이 아닙니다"
 
-#: git-stash.sh:562
+#: git-stash.sh:564
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "'$args'은(는) 스태시 레퍼런스가 아닙니다"
 
-#: git-stash.sh:570
+#: git-stash.sh:572
 msgid "unable to refresh index"
 msgstr "인덱스를 새로 고칠 수 없습니다"
 
-#: git-stash.sh:574
+#: git-stash.sh:576
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "병합 도중에 스태시를 적용할 수 없습니다"
 
-#: git-stash.sh:582
+#: git-stash.sh:584
 msgid "Conflicts in index. Try without --index."
 msgstr "인덱스에 충돌. --index 없이 시도해 보십시오."
 
-#: git-stash.sh:584
+#: git-stash.sh:586
 msgid "Could not save index tree"
 msgstr "인덱스 트리를 저장할 수 없습니다"
 
-#: git-stash.sh:593
+#: git-stash.sh:595
 msgid "Could not restore untracked files from stash entry"
 msgstr "스태시 항목에서 추적하지 않는 파일을 복구할 수 없습니다"
 
-#: git-stash.sh:618
+#: git-stash.sh:620
 msgid "Cannot unstage modified files"
 msgstr "수정한 파일을 스테이지에서 뺄 수 없습니다"
 
-#: git-stash.sh:633
+#: git-stash.sh:635
 msgid "Index was not unstashed."
 msgstr "인덱스가 스태시에서 빠졌습니다."
 
-#: git-stash.sh:647
+#: git-stash.sh:649
 msgid "The stash entry is kept in case you need it again."
 msgstr "다시 필요할 때를 대비해 스태시 항목을 보관합니다."
 
-#: git-stash.sh:656
+#: git-stash.sh:658
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "${REV} 지움 ($s)"
 
-#: git-stash.sh:657
+#: git-stash.sh:659
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "${REV}: 스태시 항목을 지울 수 없습니다"
 
-#: git-stash.sh:665
+#: git-stash.sh:667
 msgid "No branch name specified"
 msgstr "브랜치 이름을 지정하지 않았습니다"
 
-#: git-stash.sh:744
+#: git-stash.sh:746
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(복구하려면 \"git stash apply\"를 실행하십시오)"
 
-#: git-submodule.sh:181
+#: git-submodule.sh:188
 msgid "Relative path can only be used from the toplevel of the working tree"
 msgstr "상대 경로는 작업 폴더의 최상위에서만 쓸 수 있습니다"
 
-#: git-submodule.sh:191
+#: git-submodule.sh:198
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr "저장소 URL: '$repo' 값은 절대 경로거나 ./ 또는 ../로 시작해야 합니다."
 
-#: git-submodule.sh:210
+#: git-submodule.sh:217
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "'$sm_path'은(는) 이미 인덱스에 있습니다"
 
-#: git-submodule.sh:213
+#: git-submodule.sh:220
 #, sh-format
 msgid "'$sm_path' already exists in the index and is not a submodule"
 msgstr "'$sm_path'은(는) 이미 인덱스에 있고 하위 모듈이 아닙니다"
 
-#: git-submodule.sh:219
+#: git-submodule.sh:226
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -15465,22 +16539,22 @@ msgstr ""
 "$sm_path\n"
 "정말로 추가하려면 -f 옵션을 사용하십시오."
 
-#: git-submodule.sh:237
+#: git-submodule.sh:249
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "'$sm_path'의 기존 저장소를 인덱스에 추가합니다"
 
-#: git-submodule.sh:239
+#: git-submodule.sh:251
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "'$sm_path'이(가) 이미 있고 올바른 git 저장소가 아닙니다"
 
-#: git-submodule.sh:247
+#: git-submodule.sh:259
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
 msgstr "'$sm_name'에 대한 깃 디렉터리가 로컬에서 리모트가 있는 채로 있습니다:"
 
-#: git-submodule.sh:249
+#: git-submodule.sh:261
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from\n"
@@ -15495,47 +16569,47 @@ msgstr ""
 "'--force' 옵션을 사용하십시오. 로컬 깃 디렉터리가 올바른 저장소가 아니거나\n"
 "무슨 의미인지 잘 모르겠으면 '--name' 옵션으로 다른 이름을 선택하십시오."
 
-#: git-submodule.sh:255
+#: git-submodule.sh:267
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
 msgstr "로컬 깃 디렉터리를 '$sm_name' 하위모듈로 다시 활성화합니다."
 
-#: git-submodule.sh:267
+#: git-submodule.sh:279
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "'$sm_path' 하위 모듈을 체크아웃할 수 없습니다"
 
-#: git-submodule.sh:272
+#: git-submodule.sh:284
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "'$sm_path' 하위 모듈을 추가하는데 실패했습니다"
 
-#: git-submodule.sh:281
+#: git-submodule.sh:293
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "'$sm_path' 하위 모듈을 등록하는데 실패했습니다"
 
-#: git-submodule.sh:342
+#: git-submodule.sh:354
 #, sh-format
 msgid "Entering '$displaypath'"
 msgstr "'$displaypath' 들어감"
 
-#: git-submodule.sh:362
+#: git-submodule.sh:374
 #, sh-format
 msgid "Stopping at '$displaypath'; script returned non-zero status."
 msgstr "'$displaypath'에서 멈춤. 스크립트가 0이 아닌 상태를 리턴함."
 
-#: git-submodule.sh:584
+#: git-submodule.sh:600
 #, sh-format
 msgid "Unable to find current revision in submodule path '$displaypath'"
 msgstr "하위 모듈 경로에서 ('$displaypath') 현재 리비전을 찾을 수 없습니다"
 
-#: git-submodule.sh:594
+#: git-submodule.sh:610
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "하위 모듈 경로 '$sm_path'에서 가져올 수 없습니다"
 
-#: git-submodule.sh:599
+#: git-submodule.sh:615
 #, sh-format
 msgid ""
 "Unable to find current ${remote_name}/${branch} revision in submodule path "
@@ -15544,12 +16618,12 @@ msgstr ""
 "하위 모듈 경로 '$sm_path'에서 현재 ${remote_name}/${branch} 리비전을 찾을 수 "
 "없습니다"
 
-#: git-submodule.sh:617
+#: git-submodule.sh:633
 #, sh-format
 msgid "Unable to fetch in submodule path '$displaypath'"
 msgstr "하위 모듈 경로 '$displaypath'에서 가져올 수 없습니다"
 
-#: git-submodule.sh:623
+#: git-submodule.sh:639
 #, sh-format
 msgid ""
 "Fetched in submodule path '$displaypath', but it did not contain $sha1. "
@@ -15558,71 +16632,71 @@ msgstr ""
 "'$displaypath' 하위 모듈 경로에서 가져왔지만, $sha1 커밋이 들어있지 않습니"
 "다. 이 커밋을 직접 가져오는데 실패했습니다."
 
-#: git-submodule.sh:630
+#: git-submodule.sh:646
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
 msgstr "하위 모듈 경로 '$displaypath'에서 '$sha1'을(를) 체크아웃할 수 없습니다"
 
-#: git-submodule.sh:631
+#: git-submodule.sh:647
 #, sh-format
 msgid "Submodule path '$displaypath': checked out '$sha1'"
 msgstr "하위 모듈 경로 '$displaypath': '$sha1' 체크아웃"
 
-#: git-submodule.sh:635
+#: git-submodule.sh:651
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
 msgstr "하위 모듈 경로 '$displaypath'에서 '$sha1'을(를) 리베이스할 수 없습니다"
 
-#: git-submodule.sh:636
+#: git-submodule.sh:652
 #, sh-format
 msgid "Submodule path '$displaypath': rebased into '$sha1'"
 msgstr "하위 모듈 경로 '$displaypath': '$sha1'(으)로 리베이스"
 
-#: git-submodule.sh:641
+#: git-submodule.sh:657
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$displaypath'"
 msgstr "하위 모듈 경로 '$displaypath'에서 '$sha1' 병합할 수 없습니다"
 
-#: git-submodule.sh:642
+#: git-submodule.sh:658
 #, sh-format
 msgid "Submodule path '$displaypath': merged in '$sha1'"
 msgstr "하위 모듈 경로 '$displaypath': '$sha1'에서 병합"
 
-#: git-submodule.sh:647
+#: git-submodule.sh:663
 #, sh-format
 msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'"
 msgstr "'$command $sha1' 실행이 하위 모듈 경로 '$displaypath'에서 실패했습니다"
 
-#: git-submodule.sh:648
+#: git-submodule.sh:664
 #, sh-format
 msgid "Submodule path '$displaypath': '$command $sha1'"
 msgstr "하위 모듈 경로 '$displaypath': '$command $sha1'"
 
-#: git-submodule.sh:679
+#: git-submodule.sh:695
 #, sh-format
 msgid "Failed to recurse into submodule path '$displaypath'"
 msgstr "재귀적으로 하위 모듈 경로 '$displaypath'에 들어가는데 실패했습니다"
 
-#: git-submodule.sh:775
+#: git-submodule.sh:791
 msgid "The --cached option cannot be used with the --files option"
 msgstr "--cached 옵션은 --files 옵션과 같이 쓸 수 없습니다"
 
-#: git-submodule.sh:827
+#: git-submodule.sh:843
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "예상치 못한 모드 $mod_dst"
 
-#: git-submodule.sh:847
+#: git-submodule.sh:863
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr "  경고: '$display_name'에 '$sha1_src' 커밋이 들어있지 않습니다"
 
-#: git-submodule.sh:850
+#: git-submodule.sh:866
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr "  경고: '$display_name'에 '$sha1_dst' 커밋이 들어있지 않습니다"
 
-#: git-submodule.sh:853
+#: git-submodule.sh:869
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
@@ -15633,22 +16707,28 @@ msgstr ""
 msgid "See git-${cmd}(1) for details."
 msgstr "자세한 정보는 git-${cmd}(1) 페이지를 참고하십시오."
 
-#: git-rebase--interactive.sh:140
+#: git-rebase--interactive.sh:142
 #, sh-format
 msgid "Rebasing ($new_count/$total)"
 msgstr "리베이스중 ($new_count/$total)"
 
-#: git-rebase--interactive.sh:156
+#: git-rebase--interactive.sh:158
 msgid ""
 "\n"
 "Commands:\n"
-"p, pick = use commit\n"
-"r, reword = use commit, but edit the commit message\n"
-"e, edit = use commit, but stop for amending\n"
-"s, squash = use commit, but meld into previous commit\n"
-"f, fixup = like \"squash\", but discard this commit's log message\n"
-"x, exec = run command (the rest of the line) using shell\n"
-"d, drop = remove commit\n"
+"p, pick <commit> = use commit\n"
+"r, reword <commit> = use commit, but edit the commit message\n"
+"e, edit <commit> = use commit, but stop for amending\n"
+"s, squash <commit> = use commit, but meld into previous commit\n"
+"f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
+"x, exec <command> = run command (the rest of the line) using shell\n"
+"d, drop <commit> = remove commit\n"
+"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"
 "\n"
 "These lines can be re-ordered; they are executed from top to bottom.\n"
 msgstr ""
@@ -15661,10 +16741,16 @@ msgstr ""
 " f, fixup = \"squash\"와 같지만, 이 커밋의 로그 메시지를 버림\n"
 " x, exec = 셸을 사용해 명령 실행 (뒤에 명령 지정)\n"
 " d, drop = 커밋 제거\n"
+" l, label <레이블> = 현재 HEAD에 이름을 붙입니다\n"
+" t, reset <레이블> = HEAD를 레이블 위치로 리셋합니다\n"
+" m, merge [-C <커밋> | -c <커밋>] <레이블> [# <한줄>]\n"
+" .       본래 병합 커밋의 메시지를 이용해 병합 커밋을 만듭니다.\n"
+" .       (본래 병합 커밋을 지정하지 않는 경우, <한줄>을 메시지로\n"
+" .       사용합니다.) 커밋 메시지를 편집하려면 -c <커밋>을 사용.\n"
 "\n"
 "이 줄은 순서를 바꿀 수 있습니다. 위에서 아래 순서로 실행합니다.\n"
 
-#: git-rebase--interactive.sh:171
+#: git-rebase--interactive.sh:179
 msgid ""
 "\n"
 "Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
@@ -15672,7 +16758,7 @@ msgstr ""
 "\n"
 "줄을 제거하지 않습니다. 커밋을 제거하려면 명시적으로 'drop'을 사용하십시오.\n"
 
-#: git-rebase--interactive.sh:175
+#: git-rebase--interactive.sh:183
 msgid ""
 "\n"
 "If you remove a line here THAT COMMIT WILL BE LOST.\n"
@@ -15680,7 +16766,7 @@ msgstr ""
 "\n"
 "여기 줄을 제거하면 해당 커밋을 잃어버립니다!\n"
 
-#: git-rebase--interactive.sh:213
+#: git-rebase--interactive.sh:221
 #, sh-format
 msgid ""
 "You can amend the commit now, with\n"
@@ -15699,82 +16785,82 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:238
+#: git-rebase--interactive.sh:246
 #, sh-format
 msgid "$sha1: not a commit that can be picked"
 msgstr "$sha1: 빼오기가 가능한 커밋이 아닙니다"
 
-#: git-rebase--interactive.sh:277
+#: git-rebase--interactive.sh:285
 #, sh-format
 msgid "Invalid commit name: $sha1"
 msgstr "잘못된 커밋 이름: $sha1"
 
-#: git-rebase--interactive.sh:319
+#: git-rebase--interactive.sh:325
 msgid "Cannot write current commit's replacement sha1"
 msgstr "현재 커밋의 대체 sha1을 쓸 수 없습니다"
 
-#: git-rebase--interactive.sh:371
+#: git-rebase--interactive.sh:376
 #, sh-format
 msgid "Fast-forward to $sha1"
 msgstr "정방향 진행, $sha1 위치로"
 
-#: git-rebase--interactive.sh:373
+#: git-rebase--interactive.sh:378
 #, sh-format
 msgid "Cannot fast-forward to $sha1"
 msgstr "$sha1 위치로 정방향 진행할 수 없습니다"
 
-#: git-rebase--interactive.sh:382
+#: git-rebase--interactive.sh:387
 #, sh-format
 msgid "Cannot move HEAD to $first_parent"
 msgstr "HEAD를 $first_parent 위치로 옮길 수 없습니다"
 
-#: git-rebase--interactive.sh:387
+#: git-rebase--interactive.sh:392
 #, sh-format
 msgid "Refusing to squash a merge: $sha1"
 msgstr "병합 squash 거부: $sha1"
 
-#: git-rebase--interactive.sh:405
+#: git-rebase--interactive.sh:410
 #, sh-format
 msgid "Error redoing merge $sha1"
 msgstr "$sha1 병합을 다시 하는데 오류"
 
-#: git-rebase--interactive.sh:414
+#: git-rebase--interactive.sh:419
 #, sh-format
 msgid "Could not pick $sha1"
 msgstr "$sha1을 빼오기 할 수 없습니다"
 
-#: git-rebase--interactive.sh:423
+#: git-rebase--interactive.sh:428
 #, sh-format
 msgid "This is the commit message #${n}:"
 msgstr "커밋 메시지 #${n}번입니다:"
 
-#: git-rebase--interactive.sh:428
+#: git-rebase--interactive.sh:433
 #, sh-format
 msgid "The commit message #${n} will be skipped:"
 msgstr "#${n}번째 커밋 메시지를 건너뜁니다:"
 
-#: git-rebase--interactive.sh:439
+#: git-rebase--interactive.sh:444
 #, sh-format
 msgid "This is a combination of $count commit."
 msgid_plural "This is a combination of $count commits."
 msgstr[0] "커밋 $count개가 섞인 결과입니다."
 
-#: git-rebase--interactive.sh:448
+#: git-rebase--interactive.sh:453
 #, sh-format
 msgid "Cannot write $fixup_msg"
 msgstr "$fixup_msg를 쓸 수 없습니다"
 
-#: git-rebase--interactive.sh:451
+#: git-rebase--interactive.sh:456
 msgid "This is a combination of 2 commits."
 msgstr "커밋 2개가 섞인 결과입니다."
 
-#: git-rebase--interactive.sh:492 git-rebase--interactive.sh:535
-#: git-rebase--interactive.sh:538
+#: git-rebase--interactive.sh:497 git-rebase--interactive.sh:540
+#: git-rebase--interactive.sh:543
 #, sh-format
 msgid "Could not apply $sha1... $rest"
 msgstr "다음을 적용할(apply) 수 없습니다: $sha1... $rest"
 
-#: git-rebase--interactive.sh:567
+#: git-rebase--interactive.sh:572
 #, sh-format
 msgid ""
 "Could not amend commit after successfully picking $sha1... $rest\n"
@@ -15787,31 +16873,31 @@ msgstr ""
 "대부분의 경우 빈 커밋 메시지 때문이거나, 또는 커밋 전 후크가 실패했기\n"
 "때문입니다. 커밋 메시지를 수정하기 전에 이 문제를 먼저 해결해야 합니다."
 
-#: git-rebase--interactive.sh:582
+#: git-rebase--interactive.sh:587
 #, sh-format
 msgid "Stopped at $sha1_abbrev... $rest"
 msgstr "다음에서 멈춥니다: $sha1_abbrev... $rest"
 
-#: git-rebase--interactive.sh:597
+#: git-rebase--interactive.sh:602
 #, sh-format
 msgid "Cannot '$squash_style' without a previous commit"
 msgstr "이전 커밋 없이 '$squash_style' 수행할 수 없습니다"
 
-#: git-rebase--interactive.sh:639
+#: git-rebase--interactive.sh:644
 #, sh-format
 msgid "Executing: $rest"
 msgstr "실행 중: $rest"
 
-#: git-rebase--interactive.sh:647
+#: git-rebase--interactive.sh:652
 #, sh-format
 msgid "Execution failed: $rest"
 msgstr "실행 실패: $rest"
 
-#: git-rebase--interactive.sh:649
+#: git-rebase--interactive.sh:654
 msgid "and made changes to the index and/or the working tree"
 msgstr "그리고 인덱스 그리고/또는 작업 폴더에 변경 사항이 있습니다"
 
-#: git-rebase--interactive.sh:651
+#: git-rebase--interactive.sh:656
 msgid ""
 "You can fix the problem, and then run\n"
 "\n"
@@ -15822,7 +16908,7 @@ msgstr ""
 "\tgit rebase --continue"
 
 #. TRANSLATORS: after these lines is a command to be issued by the user
-#: git-rebase--interactive.sh:664
+#: git-rebase--interactive.sh:669
 #, sh-format
 msgid ""
 "Execution succeeded: $rest\n"
@@ -15837,29 +16923,29 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:675
+#: git-rebase--interactive.sh:680
 #, sh-format
 msgid "Unknown command: $command $sha1 $rest"
 msgstr "알 수 없는 명령: $command $sha1 $rest"
 
-#: git-rebase--interactive.sh:676
+#: git-rebase--interactive.sh:681
 msgid "Please fix this using 'git rebase --edit-todo'."
 msgstr "'git rebase --edit-todo' 명령으로 바로잡으십시오."
 
-#: git-rebase--interactive.sh:711
+#: git-rebase--interactive.sh:716
 #, sh-format
 msgid "Successfully rebased and updated $head_name."
 msgstr "성공적으로 리베이스했고 $head_name 업데이트했습니다."
 
-#: git-rebase--interactive.sh:735
+#: git-rebase--interactive.sh:740
 msgid "could not detach HEAD"
 msgstr "HEAD는 분리할 수 없습니다"
 
-#: git-rebase--interactive.sh:771
+#: git-rebase--interactive.sh:778
 msgid "Could not remove CHERRY_PICK_HEAD"
 msgstr "CHERRY_PICK_HEAD를 제거할 수 없습니다"
 
-#: git-rebase--interactive.sh:776
+#: git-rebase--interactive.sh:783
 #, sh-format
 msgid ""
 "You have staged changes in your working tree.\n"
@@ -15890,11 +16976,11 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: git-rebase--interactive.sh:793
+#: git-rebase--interactive.sh:800
 msgid "Error trying to find the author identity to amend commit"
 msgstr "커밋을 수정한 작성자 신원을 찾는데 오류"
 
-#: git-rebase--interactive.sh:798
+#: git-rebase--interactive.sh:805
 msgid ""
 "You have uncommitted changes in your working tree. Please commit them\n"
 "first and then run 'git rebase --continue' again."
@@ -15902,11 +16988,11 @@ msgstr ""
 "작업 폴더에 커밋하지 않은 변경 사항이 있습니다. 이 사항을 먼저\n"
 "커밋하고 'git rebase --continue' 명령을 다시 실행하십시오."
 
-#: git-rebase--interactive.sh:803 git-rebase--interactive.sh:807
+#: git-rebase--interactive.sh:810 git-rebase--interactive.sh:814
 msgid "Could not commit staged changes."
 msgstr "스테이징한 변경 사항은 커밋할 수 없습니다."
 
-#: git-rebase--interactive.sh:836
+#: git-rebase--interactive.sh:843
 msgid ""
 "\n"
 "You are editing the todo file of an ongoing interactive rebase.\n"
@@ -15920,56 +17006,58 @@ msgstr ""
 "    git rebase --continue\n"
 "\n"
 
-#: git-rebase--interactive.sh:844 git-rebase--interactive.sh:1008
+#: git-rebase--interactive.sh:851 git-rebase--interactive.sh:937
 msgid "Could not execute editor"
 msgstr "편집기를 실행할 수 없습니다"
 
-#: git-rebase--interactive.sh:860
+#: git-rebase--interactive.sh:872
 #, sh-format
 msgid "Could not checkout $switch_to"
 msgstr "$switch_to를 체크아웃할 수 없습니다"
 
-#: git-rebase--interactive.sh:865
+#: git-rebase--interactive.sh:879
 msgid "No HEAD?"
 msgstr "HEAD가 없습니다?"
 
-#: git-rebase--interactive.sh:866
+#: git-rebase--interactive.sh:880
 #, sh-format
 msgid "Could not create temporary $state_dir"
 msgstr "임시로 $state_dir 디렉터리를 만들 수 없습니다"
 
-#: git-rebase--interactive.sh:869
+#: git-rebase--interactive.sh:883
 msgid "Could not mark as interactive"
 msgstr "대화형으로 표시할 수 없습니다."
 
-#: git-rebase--interactive.sh:879 git-rebase--interactive.sh:884
-msgid "Could not init rewritten commits"
-msgstr "다시 작성된 커밋을 초기화할 수 없습니다"
-
-#: git-rebase--interactive.sh:910
-msgid "Could not generate todo list"
-msgstr "할 일 목록을 생성할 수 없습니다"
-
-#: git-rebase--interactive.sh:986
+#: git-rebase--interactive.sh:915
 #, sh-format
 msgid "Rebase $shortrevisions onto $shortonto ($todocount command)"
 msgid_plural "Rebase $shortrevisions onto $shortonto ($todocount commands)"
 msgstr[0] "리베이스 $shortrevisions, $shortonto 위로 (명령 $todocount개)"
 
-#: git-rebase--interactive.sh:991
+#: git-rebase--interactive.sh:920
 msgid ""
 "\n"
-"However, if you remove everything, the rebase will be aborted.\n"
+"\tHowever, if you remove everything, the rebase will be aborted.\n"
 "\n"
+"\t"
 msgstr ""
 "\n"
 "하지만 모두 제거할 경우, 리베이스를 중지합니다.\n"
 "\n"
+"\t"
 
-#: git-rebase--interactive.sh:998
+#: git-rebase--interactive.sh:927
 msgid "Note that empty commits are commented out"
 msgstr "단 빈 커밋은 주석 처리되었습니다."
 
+#: git-rebase--interactive.sh:980
+msgid "Could not generate todo list"
+msgstr "할 일 목록을 생성할 수 없습니다"
+
+#: git-rebase--interactive.sh:1001 git-rebase--interactive.sh:1006
+msgid "Could not init rewritten commits"
+msgstr "다시 작성된 커밋을 초기화할 수 없습니다"
+
 #: git-sh-setup.sh:89 git-sh-setup.sh:94
 #, sh-format
 msgid "usage: $dashless $USAGE"
@@ -16043,64 +17131,64 @@ msgstr "스테이징"
 msgid "unstaged"
 msgstr "안스테이징"
 
-#: git-add--interactive.perl:246 git-add--interactive.perl:271
+#: git-add--interactive.perl:253 git-add--interactive.perl:278
 msgid "binary"
 msgstr "바이너리"
 
-#: git-add--interactive.perl:255 git-add--interactive.perl:309
+#: git-add--interactive.perl:262 git-add--interactive.perl:316
 msgid "nothing"
 msgstr "없음"
 
-#: git-add--interactive.perl:291 git-add--interactive.perl:306
+#: git-add--interactive.perl:298 git-add--interactive.perl:313
 msgid "unchanged"
 msgstr "안바뀜"
 
-#: git-add--interactive.perl:602
+#: git-add--interactive.perl:609
 #, perl-format
 msgid "added %d path\n"
 msgid_plural "added %d paths\n"
 msgstr[0] "경로 %d개 추가\n"
 
-#: git-add--interactive.perl:605
+#: git-add--interactive.perl:612
 #, perl-format
 msgid "updated %d path\n"
 msgid_plural "updated %d paths\n"
 msgstr[0] "경로 %d개 업데이트\n"
 
-#: git-add--interactive.perl:608
+#: git-add--interactive.perl:615
 #, perl-format
 msgid "reverted %d path\n"
 msgid_plural "reverted %d paths\n"
 msgstr[0] "경로 %d개 되돌림\n"
 
-#: git-add--interactive.perl:611
+#: git-add--interactive.perl:618
 #, perl-format
 msgid "touched %d path\n"
 msgid_plural "touched %d paths\n"
 msgstr[0] "경로 %d개 건드림\n"
 
-#: git-add--interactive.perl:620
+#: git-add--interactive.perl:627
 msgid "Update"
 msgstr "업데이트"
 
-#: git-add--interactive.perl:632
+#: git-add--interactive.perl:639
 msgid "Revert"
 msgstr "되돌리기"
 
-#: git-add--interactive.perl:655
+#: git-add--interactive.perl:662
 #, perl-format
 msgid "note: %s is untracked now.\n"
 msgstr "주의: %s은(는) 현재 추적하지 않습니다.\n"
 
-#: git-add--interactive.perl:666
+#: git-add--interactive.perl:673
 msgid "Add untracked"
 msgstr "추적하지 않는 파일 추가"
 
-#: git-add--interactive.perl:672
+#: git-add--interactive.perl:679
 msgid "No untracked files.\n"
 msgstr "추적하지 않는 파일 없음.\n"
 
-#: git-add--interactive.perl:1026
+#: git-add--interactive.perl:1033
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for staging."
@@ -16108,7 +17196,7 @@ msgstr ""
 "패치가 깔끔하게 적용되면, 편집 부분은 즉시 스테이징으로\n"
 "표시됩니다."
 
-#: git-add--interactive.perl:1029
+#: git-add--interactive.perl:1036
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for stashing."
@@ -16116,7 +17204,7 @@ msgstr ""
 "패치가 깔끔하게 적용되면, 편집 부분은 즉시 스태시에\n"
 "표시됩니다."
 
-#: git-add--interactive.perl:1032
+#: git-add--interactive.perl:1039
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for unstaging."
@@ -16124,7 +17212,7 @@ msgstr ""
 "패치가 깔끔하게 적용되면, 편집 부분은 즉시 스테이징 아님으로\n"
 "표시됩니다."
 
-#: git-add--interactive.perl:1035 git-add--interactive.perl:1044
+#: git-add--interactive.perl:1042 git-add--interactive.perl:1051
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for applying."
@@ -16132,7 +17220,7 @@ msgstr ""
 "패치가 깔끔하게 적용되면, 편집 부분은 즉시 적용으로\n"
 "표시됩니다."
 
-#: git-add--interactive.perl:1038 git-add--interactive.perl:1041
+#: git-add--interactive.perl:1045 git-add--interactive.perl:1048
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for discarding."
@@ -16140,16 +17228,16 @@ msgstr ""
 "패치가 깔끔하게 적용되면, 편집 부분은 즉시 버림으로\n"
 "표시됩니다."
 
-#: git-add--interactive.perl:1078
+#: git-add--interactive.perl:1085
 #, perl-format
 msgid "failed to open hunk edit file for writing: %s"
 msgstr "부분 편집 파일을 쓰기용으로 여는데 실패: '%s'"
 
-#: git-add--interactive.perl:1079
+#: git-add--interactive.perl:1086
 msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
 msgstr "수동 부분 편집 모드 -- 빠른 설명은 맨 아래를 보십시오.\n"
 
-#: git-add--interactive.perl:1085
+#: git-add--interactive.perl:1092
 #, perl-format
 msgid ""
 "---\n"
@@ -16163,7 +17251,7 @@ msgstr ""
 "%s(으)로 시작하는 줄은 제거됩니다\n"
 
 #. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
-#: git-add--interactive.perl:1093
+#: git-add--interactive.perl:1100
 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"
@@ -16173,7 +17261,7 @@ msgstr ""
 "우,\n"
 "편집은 중단되고 이 부분은 변경되지 않은 상태로 남아있게 됩니다.\n"
 
-#: git-add--interactive.perl:1107
+#: git-add--interactive.perl:1114
 #, perl-format
 msgid "failed to open hunk edit file for reading: %s"
 msgstr "부분 편집 파일을 읽기용으로 여는데 실패: '%s'"
@@ -16184,14 +17272,14 @@ msgstr "부분 편집 파일을 읽기용으로 여는데 실패: '%s'"
 #. 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:1206
+#: git-add--interactive.perl:1213
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
 "편집한 부분이 적용되지 않습니다. 다시 편집하시겠습니까 (\"no\"라고 하면 버립"
 "니다!) [y/n]? "
 
-#: git-add--interactive.perl:1215
+#: git-add--interactive.perl:1222
 msgid ""
 "y - stage this hunk\n"
 "n - do not stage this hunk\n"
@@ -16205,7 +17293,7 @@ msgstr ""
 "a - 이 부분과 파일의 뒤 부분 모두 스테이징\n"
 "d - 이 부분과 파일의 뒤 부분 모두 스테이징하지 않음"
 
-#: git-add--interactive.perl:1221
+#: git-add--interactive.perl:1228
 msgid ""
 "y - stash this hunk\n"
 "n - do not stash this hunk\n"
@@ -16219,7 +17307,7 @@ msgstr ""
 "a - 이 부분과 파일의 뒤 부분 모두 스태시\n"
 "d - 이 부분과 파일의 뒤 부분 모두 스태시하지 않음"
 
-#: git-add--interactive.perl:1227
+#: git-add--interactive.perl:1234
 msgid ""
 "y - unstage this hunk\n"
 "n - do not unstage this hunk\n"
@@ -16233,7 +17321,7 @@ msgstr ""
 "a - 이 부분과 파일의 뒤 부분 모두 스테이징 해제\n"
 "d - 이 부분과 파일의 뒤 부분 모두 스테이징 해제하지 않음"
 
-#: git-add--interactive.perl:1233
+#: git-add--interactive.perl:1240
 msgid ""
 "y - apply this hunk to index\n"
 "n - do not apply this hunk to index\n"
@@ -16247,7 +17335,7 @@ msgstr ""
 "a - 이 부분과 파일의 뒤 부분 모두 \n"
 "d - 이 부분과 파일의 뒤 부분 모두 적용하지 않음"
 
-#: git-add--interactive.perl:1239
+#: git-add--interactive.perl:1246
 msgid ""
 "y - discard this hunk from worktree\n"
 "n - do not discard this hunk from worktree\n"
@@ -16261,7 +17349,7 @@ msgstr ""
 "a - 이 부분과 파일의 뒤 부분 모두 버림\n"
 "d - 이 부분과 파일의 뒤 부분 모두 버리지 않음"
 
-#: git-add--interactive.perl:1245
+#: git-add--interactive.perl:1252
 msgid ""
 "y - discard this hunk from index and worktree\n"
 "n - do not discard this hunk from index and worktree\n"
@@ -16275,7 +17363,7 @@ msgstr ""
 "a - 이 부분과 파일의 뒤 부분 모두 버림\n"
 "d - 이 부분과 파일의 뒤 부분 모두 버리지 않음"
 
-#: git-add--interactive.perl:1251
+#: git-add--interactive.perl:1258
 msgid ""
 "y - apply this hunk to index and worktree\n"
 "n - do not apply this hunk to index and worktree\n"
@@ -16289,7 +17377,7 @@ msgstr ""
 "a - 이 부분과 파일의 뒤 부분 모두 \n"
 "d - 이 부분과 파일의 뒤 부분 모두 적용하지 않음"
 
-#: git-add--interactive.perl:1266
+#: git-add--interactive.perl:1273
 msgid ""
 "g - select a hunk to go to\n"
 "/ - search for a hunk matching the given regex\n"
@@ -16311,209 +17399,209 @@ msgstr ""
 "e - 현재 부분을 수동으로 편집\n"
 "? - 도움말 보기\n"
 
-#: git-add--interactive.perl:1297
+#: git-add--interactive.perl:1304
 msgid "The selected hunks do not apply to the index!\n"
 msgstr "선택한 부분은 인덱스에 적용되지 않습니다!\n"
 
-#: git-add--interactive.perl:1298
+#: git-add--interactive.perl:1305
 msgid "Apply them to the worktree anyway? "
 msgstr "그래도 작업 폴더에 적용할까요?"
 
-#: git-add--interactive.perl:1301
+#: git-add--interactive.perl:1308
 msgid "Nothing was applied.\n"
 msgstr "아무 것도 적용되지 않았습니다.\n"
 
-#: git-add--interactive.perl:1312
+#: git-add--interactive.perl:1319
 #, perl-format
 msgid "ignoring unmerged: %s\n"
 msgstr "병합하지 않은 사항 무시: %s\n"
 
-#: git-add--interactive.perl:1321
+#: git-add--interactive.perl:1328
 msgid "Only binary files changed.\n"
 msgstr "바이너리 파일만 바뀌었습니다.\n"
 
-#: git-add--interactive.perl:1323
+#: git-add--interactive.perl:1330
 msgid "No changes.\n"
 msgstr "변경 사항 없음.\n"
 
-#: git-add--interactive.perl:1331
+#: git-add--interactive.perl:1338
 msgid "Patch update"
 msgstr "패치 업데이트"
 
-#: git-add--interactive.perl:1383
+#: git-add--interactive.perl:1390
 #, perl-format
 msgid "Stage mode change [y,n,q,a,d%s,?]? "
 msgstr "모드 변경을 스테이징합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1384
+#: git-add--interactive.perl:1391
 #, perl-format
 msgid "Stage deletion [y,n,q,a,d%s,?]? "
 msgstr "삭제를 스테이징합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1385
+#: git-add--interactive.perl:1392
 #, perl-format
 msgid "Stage this hunk [y,n,q,a,d%s,?]? "
 msgstr "이 부분 스테이징합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1388
+#: git-add--interactive.perl:1395
 #, perl-format
 msgid "Stash mode change [y,n,q,a,d%s,?]? "
 msgstr "모드 변경 스태시합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1389
+#: git-add--interactive.perl:1396
 #, perl-format
 msgid "Stash deletion [y,n,q,a,d%s,?]? "
 msgstr "삭제 스태시합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1390
+#: git-add--interactive.perl:1397
 #, perl-format
 msgid "Stash this hunk [y,n,q,a,d%s,?]? "
 msgstr "이 부분 스태시합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1393
+#: git-add--interactive.perl:1400
 #, perl-format
 msgid "Unstage mode change [y,n,q,a,d%s,?]? "
 msgstr "모드 변경을 스테이지 해제합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1394
+#: git-add--interactive.perl:1401
 #, perl-format
 msgid "Unstage deletion [y,n,q,a,d%s,?]? "
 msgstr "삭제를 스테이지 해제합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1395
+#: git-add--interactive.perl:1402
 #, perl-format
 msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
 msgstr "이 부분을 스테이지 해제합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1398
+#: git-add--interactive.perl:1405
 #, perl-format
 msgid "Apply mode change to index [y,n,q,a,d%s,?]? "
 msgstr "모드 변경을 인덱스에 적용합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1399
+#: git-add--interactive.perl:1406
 #, perl-format
 msgid "Apply deletion to index [y,n,q,a,d%s,?]? "
 msgstr "삭제를 인덱스에 적용합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1400
+#: git-add--interactive.perl:1407
 #, perl-format
 msgid "Apply this hunk to index [y,n,q,a,d%s,?]? "
 msgstr "이 부분을 인덱스에 적용합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1403
+#: git-add--interactive.perl:1410
 #, perl-format
 msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? "
 msgstr "모드 변경을 작업 폴더에서 버립니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1404
+#: git-add--interactive.perl:1411
 #, perl-format
 msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? "
 msgstr "삭제를 작업 폴더에서 버립니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1405
+#: git-add--interactive.perl:1412
 #, perl-format
 msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
 msgstr "이 부분을 작업 폴더에서 버립니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1408
+#: git-add--interactive.perl:1415
 #, perl-format
 msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "모드 변경을 인덱스와 작업 폴더에서 버립니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1409
+#: git-add--interactive.perl:1416
 #, perl-format
 msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "삭제를 인덱스와 작업 폴더에서 버립니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1410
+#: git-add--interactive.perl:1417
 #, perl-format
 msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "이 부분을 인덱스와 작업 폴더에서 버립니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1413
+#: git-add--interactive.perl:1420
 #, perl-format
 msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "모드 변경을 인덱스와 작업 폴더에 적용합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1414
+#: git-add--interactive.perl:1421
 #, perl-format
 msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "삭제를 인덱스와 작업 폴더에 적용합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1415
+#: git-add--interactive.perl:1422
 #, perl-format
 msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "이 부분을 인덱스와 작업 폴더에 적용합니까 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1515
+#: git-add--interactive.perl:1522
 msgid "No other hunks to goto\n"
 msgstr "이동할 부분이 없습니다\n"
 
-#: git-add--interactive.perl:1522
+#: git-add--interactive.perl:1529
 msgid "go to which hunk (<ret> to see more)? "
 msgstr "어느 부분으로 이동합니까 (더 보려면 <ret>)? "
 
-#: git-add--interactive.perl:1524
+#: git-add--interactive.perl:1531
 msgid "go to which hunk? "
 msgstr "어느 부분으로 이동합니까? "
 
-#: git-add--interactive.perl:1533
+#: git-add--interactive.perl:1540
 #, perl-format
 msgid "Invalid number: '%s'\n"
 msgstr "잘못된 번호: '%s'\n"
 
-#: git-add--interactive.perl:1538
+#: git-add--interactive.perl:1545
 #, perl-format
 msgid "Sorry, only %d hunk available.\n"
 msgid_plural "Sorry, only %d hunks available.\n"
 msgstr[0] "미안합니다. 부분이 %d개 밖에 없습니다.\n"
 
-#: git-add--interactive.perl:1564
+#: git-add--interactive.perl:1571
 msgid "No other hunks to search\n"
 msgstr "검색할 부분이 없습니다\n"
 
-#: git-add--interactive.perl:1568
+#: git-add--interactive.perl:1575
 msgid "search for regex? "
 msgstr "정규식을 검색합니까?"
 
-#: git-add--interactive.perl:1581
+#: git-add--interactive.perl:1588
 #, perl-format
 msgid "Malformed search regexp %s: %s\n"
 msgstr "잘못된 형태의 검색 정규식 %s: %s\n"
 
-#: git-add--interactive.perl:1591
+#: git-add--interactive.perl:1598
 msgid "No hunk matches the given pattern\n"
 msgstr "[주어진 패턴에 맞는 부분이 없습니다\n"
 
-#: git-add--interactive.perl:1603 git-add--interactive.perl:1625
+#: git-add--interactive.perl:1610 git-add--interactive.perl:1632
 msgid "No previous hunk\n"
 msgstr "이전 부분이 없습니다\n"
 
-#: git-add--interactive.perl:1612 git-add--interactive.perl:1631
+#: git-add--interactive.perl:1619 git-add--interactive.perl:1638
 msgid "No next hunk\n"
 msgstr "다음 부분이 없습니다\n"
 
-#: git-add--interactive.perl:1637
+#: git-add--interactive.perl:1644
 msgid "Sorry, cannot split this hunk\n"
 msgstr "미안합니다. 이 부분을 분리 할 수 없습니다\n"
 
-#: git-add--interactive.perl:1643
+#: git-add--interactive.perl:1650
 #, perl-format
 msgid "Split into %d hunk.\n"
 msgid_plural "Split into %d hunks.\n"
 msgstr[0] "%d개 부분으로 나눕니다.\n"
 
-#: git-add--interactive.perl:1653
+#: git-add--interactive.perl:1660
 msgid "Sorry, cannot edit this hunk\n"
 msgstr "미안합니다. 이 부분을 수정할 수 없습니다\n"
 
-#: git-add--interactive.perl:1699
+#: git-add--interactive.perl:1706
 msgid "Review diff"
 msgstr "diff 검토"
 
 #. TRANSLATORS: please do not translate the command names
 #. 'status', 'update', 'revert', etc.
-#: git-add--interactive.perl:1718
+#: git-add--interactive.perl:1725
 msgid ""
 "status        - show paths with changes\n"
 "update        - add working tree state to the staged set of changes\n"
@@ -16531,18 +17619,18 @@ msgstr ""
 "add untracked - 추적되지 않는 파일의 내용을 변경 사항 스테이징 모음에 추가합"
 "니다\n"
 
-#: git-add--interactive.perl:1735 git-add--interactive.perl:1740
-#: git-add--interactive.perl:1743 git-add--interactive.perl:1750
-#: git-add--interactive.perl:1754 git-add--interactive.perl:1760
+#: git-add--interactive.perl:1742 git-add--interactive.perl:1747
+#: git-add--interactive.perl:1750 git-add--interactive.perl:1757
+#: git-add--interactive.perl:1761 git-add--interactive.perl:1767
 msgid "missing --"
 msgstr "-- 빠짐"
 
-#: git-add--interactive.perl:1756
+#: git-add--interactive.perl:1763
 #, perl-format
 msgid "unknown --patch mode: %s"
 msgstr "알 수 없는 --patch 모드: %s"
 
-#: git-add--interactive.perl:1762 git-add--interactive.perl:1768
+#: git-add--interactive.perl:1769 git-add--interactive.perl:1775
 #, perl-format
 msgid "invalid argument %s, expecting --"
 msgstr "인자가 (%s) 잘못되었고, --가 와야 합니다"
@@ -16755,7 +17843,7 @@ msgstr "이 주소로 무엇을 하시겠습니까? ([q]끝내기|[d]버리기|[
 msgid "CA path \"%s\" does not exist"
 msgstr "\"%s\" CA 경로가 없습니다"
 
-#: git-send-email.perl:1395
+#: git-send-email.perl:1400
 msgid ""
 "    The Cc list above has been expanded by additional\n"
 "    addresses found in the patch commit message. By default\n"
@@ -16779,203 +17867,134 @@ msgstr ""
 "    실행하십시오.\n"
 "\n"
 
-#. TRANSLATORS: Make sure to include [y] [n] [q] [a] in your
+#. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
 #. translation. The program will only accept English input
 #. at this point.
-#: git-send-email.perl:1410
-msgid "Send this email? ([y]es|[n]o|[q]uit|[a]ll): "
-msgstr "이 전자메일을 보내시겠습니까? ([y]예|[n]아니오|[q]끝내기|[a]모두): "
+#: git-send-email.perl:1415
+msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
+msgstr ""
+"이 전자메일을 보내시겠습니까? ([y]예|[n]아니오|[e]편집|[q]끝내기|[a]모두): "
 
-#: git-send-email.perl:1413
+#: git-send-email.perl:1418
 msgid "Send this email reply required"
 msgstr "필요한 전자메일 답장 보냅니다"
 
-#: git-send-email.perl:1439
+#: git-send-email.perl:1446
 msgid "The required SMTP server is not properly defined."
 msgstr "필요한 SMTP 서버를 제대로 지정하지 않았습니다."
 
-#: git-send-email.perl:1486
+#: git-send-email.perl:1493
 #, perl-format
 msgid "Server does not support STARTTLS! %s"
 msgstr "서버에서 STARTTLS를 지원하지 않습니다! %s"
 
-#: git-send-email.perl:1491 git-send-email.perl:1495
+#: git-send-email.perl:1498 git-send-email.perl:1502
 #, perl-format
 msgid "STARTTLS failed! %s"
 msgstr "STARTTLS 실패! %s"
 
-#: git-send-email.perl:1505
+#: git-send-email.perl:1512
 msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug."
 msgstr ""
 "SMTP를 제대로 초기화할 수 없습니다. 설정을 확인하고 --smtp-debug 옵션을 사용"
 "하십시오."
 
-#: git-send-email.perl:1523
+#: git-send-email.perl:1530
 #, perl-format
 msgid "Failed to send %s\n"
 msgstr "%s을(를) 보내는데 실패했습니다\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Dry-Sent %s\n"
 msgstr "%s 보내는 흉내\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Sent %s\n"
 msgstr "%s 보냄\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "Dry-OK. Log says:\n"
 msgstr "성공 흉내. 기록은:\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "OK. Log says:\n"
 msgstr "성공. 기록은:\n"
 
-#: git-send-email.perl:1540
+#: git-send-email.perl:1547
 msgid "Result: "
 msgstr "결과: "
 
-#: git-send-email.perl:1543
+#: git-send-email.perl:1550
 msgid "Result: OK\n"
 msgstr "결과: 정상\n"
 
-#: git-send-email.perl:1556
+#: git-send-email.perl:1568
 #, perl-format
 msgid "can't open file %s"
 msgstr "%s 파일을 열 수 없습니다"
 
-#: git-send-email.perl:1603 git-send-email.perl:1623
+#: git-send-email.perl:1615 git-send-email.perl:1635
 #, perl-format
 msgid "(mbox) Adding cc: %s from line '%s'\n"
 msgstr "(mbox) cc: %s 추가, '%s' 줄에서\n"
 
-#: git-send-email.perl:1609
+#: git-send-email.perl:1621
 #, perl-format
 msgid "(mbox) Adding to: %s from line '%s'\n"
 msgstr "(mbox) to: %s 추가, '%s' 줄에서\n"
 
-#: git-send-email.perl:1657
+#: git-send-email.perl:1674
 #, perl-format
 msgid "(non-mbox) Adding cc: %s from line '%s'\n"
 msgstr "(mbox아님) cc: %s 추가, '%s' 줄에서\n"
 
-#: git-send-email.perl:1682
+#: git-send-email.perl:1699
 #, perl-format
 msgid "(body) Adding cc: %s from line '%s'\n"
 msgstr "(본문) cc: %s 추가, '%s' 줄에서\n"
 
-#: git-send-email.perl:1788
+#: git-send-email.perl:1817
 #, perl-format
 msgid "(%s) Could not execute '%s'"
 msgstr "(%s) '%s'을 실행할 수 없습니다"
 
-#: git-send-email.perl:1795
+#: git-send-email.perl:1824
 #, perl-format
 msgid "(%s) Adding %s: %s from: '%s'\n"
 msgstr "(%s) %s: %s 추가, '%s' 줄에서\n"
 
-#: git-send-email.perl:1799
+#: git-send-email.perl:1828
 #, perl-format
 msgid "(%s) failed to close pipe to '%s'"
 msgstr "(%s) '%s'(을)를 향한 파이프를 닫는데 실패했습니다"
 
-#: git-send-email.perl:1826
+#: git-send-email.perl:1855
 msgid "cannot send message as 7bit"
 msgstr "메시지를 7비트로 보낼 수 없습니다"
 
-#: git-send-email.perl:1834
+#: git-send-email.perl:1863
 msgid "invalid transfer encoding"
 msgstr "잘못된 전송 인코딩"
 
-#: git-send-email.perl:1872 git-send-email.perl:1923 git-send-email.perl:1933
+#: git-send-email.perl:1901 git-send-email.perl:1952 git-send-email.perl:1962
 #, perl-format
 msgid "unable to open %s: %s\n"
 msgstr "%s을(를) 열 수 없습니다: %s\n"
 
-#: git-send-email.perl:1875
+#: git-send-email.perl:1904
 #, perl-format
 msgid "%s: patch contains a line longer than 998 characters"
 msgstr "%s: 패치에 998자보다 더 긴 줄이 들어 있습니다"
 
-#: git-send-email.perl:1891
+#: git-send-email.perl:1920
 #, perl-format
 msgid "Skipping %s with backup suffix '%s'.\n"
 msgstr "%s 넘어감, 예비 확장자 '%s' 있음.\n"
 
 #. TRANSLATORS: please keep "[y|N]" as is.
-#: git-send-email.perl:1895
+#: git-send-email.perl:1924
 #, perl-format
 msgid "Do you really want to send %s? [y|N]: "
 msgstr "정말로 %s 파일을 보내시겠습니까? [y|N]: "
-
-#~ msgid "git fetch-pack: expected ACK/NAK, got EOF"
-#~ msgstr "git fetch-pack: ACK/NAK가 와야 하지만, EOF를 받았습니다"
-
-#~ msgid "invalid filter-spec expression '%s'"
-#~ msgstr "잘못된 필터 양식 '%s'"
-
-#~ msgid "The copy of the patch that failed is found in: %s"
-#~ msgstr "실패한 패치의 복사본이 다음 위치에 있습니다: %s"
-
-#~ msgid "pathspec and --all are incompatible"
-#~ msgstr "경로명세 및 --all 옵션은 호환되지 않습니다"
-
-#~ msgid "Submodule '$name' ($url) unregistered for path '$displaypath'"
-#~ msgstr ""
-#~ "'$name' 하위 모듈이 ($url) '$displaypath' 경로에 대해 등록되지 않았습니다"
-
-#~ msgid "To/Cc/Bcc fields are not interpreted yet, they have been ignored\n"
-#~ msgstr "To/Cc/Bcc 필드가 해석되지 않아서, 무시합니다\n"
-
-#~ msgid ""
-#~ "empty strings as pathspecs will be made invalid in upcoming releases. "
-#~ "please use . instead if you meant to match all paths"
-#~ msgstr ""
-#~ "경로명세로 빈 문자열을 넣는 일은 다음 릴리스에서 오류로 취급할 예정입니"
-#~ "다. 모든 경로를 지정하려면 점(.)을 사용하십시오."
-
-#~ msgid "unable to open '%s' for writing"
-#~ msgstr "'%s'을(를) 쓰기 용으로 열 수 없습니다"
-
-#~ msgid "could not truncate '%s'"
-#~ msgstr "'%s' 파일을 자를 수 없습니다"
-
-#~ msgid "could not finish '%s'"
-#~ msgstr "'%s'을(를) 마칠 수 없습니다"
-
-#~ msgid "could not close %s"
-#~ msgstr "%s을(를) 닫을 수 없습니다"
-
-#~ msgid "Copied a misnamed branch '%s' away"
-#~ msgstr "이름이 잘못된 '%s' 브랜치를 복사합니다"
-
-#~ msgid "it does not make sense to create 'HEAD' manually"
-#~ msgstr "'HEAD'를 수동으로 만드는 건 앞뒤가 맞지 않습니다"
-
-#~ msgid "Don't know how to clone %s"
-#~ msgstr "%s의 복제 방법을 알지 못합니다"
-
-#~ msgid "show ignored files"
-#~ msgstr "무시되는 파일을 표시합니다"
-
-#~ msgid "%s is not a valid '%s' object"
-#~ msgstr "%s은(는) 올바른 '%s' 오브젝트가 아닙니다"
-
-#~ msgid "Don't know how to fetch from %s"
-#~ msgstr "'%s'에서 가져오는 방법을 알 수 없습니다"
-
-#~ msgid "'$term' is not a valid term"
-#~ msgstr "'$term'이(가) 올바른 용어가 아닙니다"
-
-#~ msgid ""
-#~ "error: unknown option for 'stash save': $option\n"
-#~ "       To provide a message, use git stash save -- '$option'"
-#~ msgstr ""
-#~ "오류: 'stash save'에 대해 알 수 없는 옵션: $option\n"
-#~ "       메시지를 넘기려면, 다음과 같이 쓰십시오: git stash save -- "
-#~ "'$option'"
-
-#~ msgid "Failed to recurse into submodule path '$sm_path'"
-#~ msgstr "재귀적으로 하위 모듈 경로 '$sm_path'에 들어가는데 실패했습니다"
index 8331e777dcba3d60e8521d63c68a93ae68173013..502a32d7e7505a819f44fa59d571d109817e36f0 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -5,10 +5,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git 2.16.0\n"
+"Project-Id-Version: git 2.18.0\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2018-03-16 07:29+0800\n"
-"PO-Revision-Date: 2018-03-18 20:55+0100\n"
+"POT-Creation-Date: 2018-06-08 09:03+0800\n"
+"PO-Revision-Date: 2018-06-08 22:53+0100\n"
 "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
 "Language: sv\n"
@@ -18,47 +18,47 @@ msgstr ""
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 "X-Generator: Gtranslator 2.91.7\n"
 
-#: advice.c:62
+#: advice.c:92
 #, c-format
-msgid "hint: %.*s\n"
-msgstr "tips: %.*s\n"
+msgid "%shint: %.*s%s\n"
+msgstr "%stips: %.*s%s\n"
 
-#: advice.c:90
+#: advice.c:137
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr ""
 "Du kan inte utföra en cherry-pick eftersom du har filer som inte slagits "
 "samman."
 
-#: advice.c:92
+#: advice.c:139
 msgid "Committing is not possible because you have unmerged files."
 msgstr ""
 "Du kan inte utföra en incheckning eftersom du har filer som inte slagits "
 "samman."
 
-#: advice.c:94
+#: advice.c:141
 msgid "Merging is not possible because you have unmerged files."
 msgstr ""
 "Du kan inte utföra en sammanslagning eftersom du har filer som inte slagits "
 "samman."
 
-#: advice.c:96
+#: advice.c:143
 msgid "Pulling is not possible because you have unmerged files."
 msgstr ""
 "Du kan inte utföra en \"pull\" eftersom du har filer som inte slagits samman."
 
-#: advice.c:98
+#: advice.c:145
 msgid "Reverting is not possible because you have unmerged files."
 msgstr ""
 "Du kan inte utföra en \"revert\" eftersom du har filer som inte slagits "
 "samman."
 
-#: advice.c:100
+#: advice.c:147
 #, c-format
 msgid "It is not possible to %s because you have unmerged files."
 msgstr ""
 "Du kan inte utföra en \"%s\" eftersom du har filer som inte slagits samman."
 
-#: advice.c:108
+#: advice.c:155
 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."
@@ -66,23 +66,23 @@ msgstr ""
 "Rätta dem i din arbetskatalog och använd sedan \"git add/rm <fil>\"\n"
 "som lämpligt för att ange lösning och checka in."
 
-#: advice.c:116
+#: advice.c:163
 msgid "Exiting because of an unresolved conflict."
 msgstr "Avslutar på grund av olöst konflikgt."
 
-#: advice.c:121 builtin/merge.c:1251
+#: advice.c:168 builtin/merge.c:1250
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
 msgstr "Du har inte avslutat sammanslagningen (MERGE_HEAD finns)."
 
-#: advice.c:123
+#: advice.c:170
 msgid "Please, commit your changes before merging."
 msgstr "Checka in dina ändringar innan du utför sammanslagningen."
 
-#: advice.c:124
+#: advice.c:171
 msgid "Exiting because of unfinished merge."
 msgstr "Avslutar på grund av ofullbordad sammanslagning."
 
-#: advice.c:130
+#: advice.c:177
 #, c-format
 msgid ""
 "Note: checking out '%s'.\n"
@@ -352,7 +352,7 @@ msgstr "patch misslyckades: %s:%ld"
 msgid "cannot checkout %s"
 msgstr "kan inte checka ut %s"
 
-#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:277
+#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:278
 #, c-format
 msgid "failed to read %s"
 msgstr "misslyckades läsa %s"
@@ -553,7 +553,7 @@ msgstr[1] "Tillämpade patchen %%s med %d refuserade..."
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "trunkerar .rej-filnamnet till %.*s.rej"
 
-#: apply.c:4545 builtin/fetch.c:775 builtin/fetch.c:1025
+#: apply.c:4545 builtin/fetch.c:786 builtin/fetch.c:1036
 #, c-format
 msgid "cannot open %s"
 msgstr "kan inte öppna %s"
@@ -607,15 +607,15 @@ msgid_plural "%d lines applied after fixing whitespace errors."
 msgstr[0] "%d rad applicerade efter att ha rättat fel i blanksteg."
 msgstr[1] "%d rader applicerade efter att ha rättat fel i blanksteg."
 
-#: apply.c:4894 builtin/add.c:539 builtin/mv.c:298 builtin/rm.c:390
+#: apply.c:4894 builtin/add.c:538 builtin/mv.c:300 builtin/rm.c:389
 msgid "Unable to write new index file"
 msgstr "Kunde inte skriva ny indexfil"
 
 #: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257
-#: builtin/clone.c:118 builtin/fetch.c:127 builtin/pull.c:193
-#: builtin/submodule--helper.c:403 builtin/submodule--helper.c:1197
-#: builtin/submodule--helper.c:1200 builtin/submodule--helper.c:1567
-#: builtin/submodule--helper.c:1570 builtin/submodule--helper.c:1787
+#: builtin/clone.c:120 builtin/fetch.c:126 builtin/pull.c:198
+#: builtin/submodule--helper.c:405 builtin/submodule--helper.c:1210
+#: builtin/submodule--helper.c:1213 builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1587 builtin/submodule--helper.c:1807
 #: git-add--interactive.perl:197
 msgid "path"
 msgstr "sökväg"
@@ -690,7 +690,7 @@ msgstr "se till att åtminstone <n> rader sammanhang är lika"
 
 #: apply.c:4960 builtin/am.c:2242 builtin/interpret-trailers.c:95
 #: builtin/interpret-trailers.c:97 builtin/interpret-trailers.c:99
-#: builtin/pack-objects.c:3035
+#: builtin/pack-objects.c:3177
 msgid "action"
 msgstr "åtgärd"
 
@@ -718,9 +718,9 @@ msgstr "lämna refuserade stycken i motsvarande *.rej-filer"
 msgid "allow overlapping hunks"
 msgstr "tillåt överlappande stycken"
 
-#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21
-#: builtin/commit.c:1276 builtin/count-objects.c:96 builtin/fsck.c:665
-#: builtin/log.c:1901 builtin/mv.c:123 builtin/read-tree.c:125
+#: apply.c:4977 builtin/add.c:290 builtin/check-ignore.c:21
+#: builtin/commit.c:1301 builtin/count-objects.c:98 builtin/fsck.c:666
+#: builtin/log.c:1901 builtin/mv.c:122 builtin/read-tree.c:124
 msgid "be verbose"
 msgstr "var pratsam"
 
@@ -759,98 +759,98 @@ msgstr ""
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <arkiv> [--exec <kmd>] --list"
 
-#: archive.c:351 builtin/add.c:176 builtin/add.c:515 builtin/rm.c:299
+#: archive.c:351 builtin/add.c:176 builtin/add.c:514 builtin/rm.c:298
 #, c-format
 msgid "pathspec '%s' did not match any files"
 msgstr "sökvägsangivelsen \"%s\" motsvarade inte några filer"
 
-#: archive.c:436
+#: archive.c:434
 msgid "fmt"
 msgstr "fmt"
 
-#: archive.c:436
+#: archive.c:434
 msgid "archive format"
 msgstr "arkivformat"
 
-#: archive.c:437 builtin/log.c:1462
+#: archive.c:435 builtin/log.c:1462
 msgid "prefix"
 msgstr "prefix"
 
-#: archive.c:438
+#: archive.c:436
 msgid "prepend prefix to each pathname in the archive"
 msgstr "lägg till prefix till varje sökväg i arkivet"
 
-#: archive.c:439 builtin/blame.c:702 builtin/blame.c:703 builtin/config.c:62
-#: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:869
+#: archive.c:437 builtin/blame.c:813 builtin/blame.c:814 builtin/config.c:127
+#: builtin/fast-export.c:1007 builtin/fast-export.c:1009 builtin/grep.c:869
 #: builtin/hash-object.c:103 builtin/ls-files.c:551 builtin/ls-files.c:554
-#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120
+#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:119
 #: parse-options.h:165
 msgid "file"
 msgstr "fil"
 
-#: archive.c:440 builtin/archive.c:89
+#: archive.c:438 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "skriv arkivet till filen"
 
-#: archive.c:442
+#: archive.c:440
 msgid "read .gitattributes in working directory"
 msgstr "läs .gitattributes i arbetskatalogen"
 
-#: archive.c:443
+#: archive.c:441
 msgid "report archived files on stderr"
 msgstr "rapportera arkiverade filer på standard fel"
 
-#: archive.c:444
+#: archive.c:442
 msgid "store only"
 msgstr "endast spara"
 
-#: archive.c:445
+#: archive.c:443
 msgid "compress faster"
 msgstr "komprimera snabbare"
 
-#: archive.c:453
+#: archive.c:451
 msgid "compress better"
 msgstr "komprimera bättre"
 
-#: archive.c:456
+#: archive.c:454
 msgid "list supported archive formats"
 msgstr "visa understödda arkivformat"
 
-#: archive.c:458 builtin/archive.c:90 builtin/clone.c:108 builtin/clone.c:111
-#: builtin/submodule--helper.c:1209 builtin/submodule--helper.c:1576
+#: archive.c:456 builtin/archive.c:90 builtin/clone.c:110 builtin/clone.c:113
+#: builtin/submodule--helper.c:1222 builtin/submodule--helper.c:1593
 msgid "repo"
 msgstr "arkiv"
 
-#: archive.c:459 builtin/archive.c:91
+#: archive.c:457 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "hämta arkivet från fjärrarkivet <arkiv>"
 
-#: archive.c:460 builtin/archive.c:92 builtin/notes.c:489
+#: archive.c:458 builtin/archive.c:92 builtin/notes.c:489
 msgid "command"
 msgstr "kommando"
 
-#: archive.c:461 builtin/archive.c:93
+#: archive.c:459 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "sökväg till kommandot git-upload-archive på fjärren"
 
-#: archive.c:468
+#: archive.c:466
 msgid "Unexpected option --remote"
 msgstr "Oväntad flagga --remote"
 
-#: archive.c:470
+#: archive.c:468
 msgid "Option --exec can only be used together with --remote"
 msgstr "Flaggan --exec kan endast användas tillsammans med --remote"
 
-#: archive.c:472
+#: archive.c:470
 msgid "Unexpected option --output"
 msgstr "Oväntad flagga --output"
 
-#: archive.c:494
+#: archive.c:492
 #, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Okänt arkivformat \"%s\""
 
-#: archive.c:501
+#: archive.c:499
 #, c-format
 msgid "Argument not supported for format '%s': -%d"
 msgstr "Argumentet stöd inte för formatet \"%s\": -%d"
@@ -868,22 +868,22 @@ msgstr ""
 "Negativa mönster ignoreras i git-attribut\n"
 "Använd '\\!' för att inleda med ett utropstecken."
 
-#: bisect.c:460
+#: bisect.c:461
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "Felaktigt citerat innehåll i filen \"%s\": %s"
 
-#: bisect.c:668
+#: bisect.c:669
 #, c-format
 msgid "We cannot bisect more!\n"
 msgstr "Det finns inte mer att göra \"bisect\" på!\n"
 
-#: bisect.c:722
+#: bisect.c:723
 #, c-format
 msgid "Not a valid commit name %s"
 msgstr "Namnet på incheckningen är inte giltigt: %s"
 
-#: bisect.c:746
+#: bisect.c:747
 #, c-format
 msgid ""
 "The merge base %s is bad.\n"
@@ -892,7 +892,7 @@ msgstr ""
 "Sammanslagningsbasen %s är trasig.\n"
 "Det betyder att felet har rättats mellan %s och [%s].\n"
 
-#: bisect.c:751
+#: bisect.c:752
 #, c-format
 msgid ""
 "The merge base %s is new.\n"
@@ -901,7 +901,7 @@ msgstr ""
 "Sammanslagningsbasen %s är ny.\n"
 "Egenskapen har ändrats mellan %s och [%s].\n"
 
-#: bisect.c:756
+#: bisect.c:757
 #, c-format
 msgid ""
 "The merge base %s is %s.\n"
@@ -910,7 +910,7 @@ msgstr ""
 "Sammanslagningsbasen %s är %s.\n"
 "Det betyder att den första \"%s\" incheckningen är mellan %s och [%s].\n"
 
-#: bisect.c:764
+#: bisect.c:765
 #, c-format
 msgid ""
 "Some %s revs are not ancestors of the %s rev.\n"
@@ -921,7 +921,7 @@ msgstr ""
 "git bisect kan inte fungera korrekt i detta fall.\n"
 "Kanske du skrev fel %s- och %s-revisioner?\n"
 
-#: bisect.c:777
+#: bisect.c:778
 #, c-format
 msgid ""
 "the merge base between %s and [%s] must be skipped.\n"
@@ -933,36 +933,36 @@ msgstr ""
 "%s.\n"
 "Vi fortsätter ändå."
 
-#: bisect.c:810
+#: bisect.c:811
 #, c-format
 msgid "Bisecting: a merge base must be tested\n"
 msgstr "Bisect: en sammanslagningsbas måste testas\n"
 
-#: bisect.c:850
+#: bisect.c:851
 #, c-format
 msgid "a %s revision is needed"
 msgstr "en %s-revision behövs"
 
-#: bisect.c:869 builtin/notes.c:175 builtin/tag.c:235
+#: bisect.c:870 builtin/notes.c:175 builtin/tag.c:236
 #, c-format
 msgid "could not create file '%s'"
 msgstr "kunde inte skapa filen \"%s\""
 
-#: bisect.c:920
+#: bisect.c:921
 #, c-format
 msgid "could not read file '%s'"
 msgstr "kunde inte läsa filen \"%s\""
 
-#: bisect.c:950
+#: bisect.c:951
 msgid "reading bisect refs failed"
 msgstr "misslyckades läsa bisect-referenser"
 
-#: bisect.c:969
+#: bisect.c:970
 #, c-format
 msgid "%s was both %s and %s\n"
 msgstr "%s var både %s och %s\n"
 
-#: bisect.c:977
+#: bisect.c:978
 #, c-format
 msgid ""
 "No testable commit found.\n"
@@ -971,7 +971,7 @@ msgstr ""
 "Ingen testbar incheckning hittades.\n"
 "Kanske du startade med felaktiga sökvägsparametrar?\n"
 
-#: bisect.c:996
+#: bisect.c:997
 #, c-format
 msgid "(roughly %d step)"
 msgid_plural "(roughly %d steps)"
@@ -981,52 +981,52 @@ msgstr[1] "(ungefär %d steg)"
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
 #.
-#: bisect.c:1002
+#: bisect.c:1003
 #, 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] "Bisect: %d revision kvar att testa efter denna %s\n"
 msgstr[1] "Bisect: %d revisioner kvar att testa efter denna %s\n"
 
-#: blame.c:1758
+#: blame.c:1756
 msgid "--contents and --reverse do not blend well."
 msgstr "--contents och --reverse fungerar inte så bra tillsammans."
 
-#: blame.c:1769
+#: blame.c:1767
 msgid "cannot use --contents with final commit object name"
 msgstr "kan inte använda --contents med namn på slutgiltigt incheckningsobjekt"
 
-#: blame.c:1789
+#: blame.c:1787
 msgid "--reverse and --first-parent together require specified latest commit"
 msgstr ""
 "--reverse och --first-parent tillsammans kräver att du anger senaste "
 "incheckningen"
 
-#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699
-#: sequencer.c:2901 builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920
-#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370
-#: builtin/shortlog.c:191
+#: blame.c:1796 bundle.c:160 ref-filter.c:2075 sequencer.c:1861
+#: sequencer.c:3632 builtin/commit.c:981 builtin/log.c:366 builtin/log.c:920
+#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:372
+#: builtin/shortlog.c:192
 msgid "revision walk setup failed"
 msgstr "misslyckades skapa revisionstraversering"
 
-#: blame.c:1816
+#: blame.c:1814
 msgid ""
 "--reverse --first-parent together require range along first-parent chain"
 msgstr ""
 "--reverse --first-parent tillsammans kräver ett intervall på första-förälder-"
 "kedjan"
 
-#: blame.c:1827
+#: blame.c:1825
 #, c-format
 msgid "no such path %s in %s"
 msgstr "sökvägen %s i %s finns inte"
 
-#: blame.c:1838
+#: blame.c:1836
 #, c-format
 msgid "cannot read blob %s for path %s"
 msgstr "kan inte läsa objektet %s för sökvägen %s"
 
-#: branch.c:53
+#: branch.c:54
 #, c-format
 msgid ""
 "\n"
@@ -1039,92 +1039,92 @@ msgstr ""
 "fjärrspårningsinformationen genom att utföra\n"
 "\"git branch --set-upstream-to=%s%s%s\"."
 
-#: branch.c:67
+#: branch.c:68
 #, c-format
 msgid "Not setting branch %s as its own upstream."
 msgstr "Ställer inte in grenen %s som sin egen uppströmsgren."
 
-#: branch.c:93
+#: branch.c:94
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s' by rebasing."
 msgstr ""
 "Grenen %s ställdes in att spåra fjärrgrenen \"%s\" från \"%s\" genom "
 "ombasering."
 
-#: branch.c:94
+#: branch.c:95
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s'."
 msgstr "Grenen %s ställdes in att spåra fjärrgrenen \"%s\" från \"%s\"."
 
-#: branch.c:98
+#: branch.c:99
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s' by rebasing."
 msgstr ""
 "Grenen \"%s\" ställdes in att spåra den lokala grenen \"%s\"  genom "
 "ombasering."
 
-#: branch.c:99
+#: branch.c:100
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s'."
 msgstr "Grenen \"%s\" ställdes in att spåra den lokala grenen \"%s\"."
 
-#: branch.c:104
+#: branch.c:105
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s' by rebasing."
 msgstr ""
 "Grenen \"%s\" ställdes in att spåra fjärreferensen \"%s\" genom ombasering."
 
-#: branch.c:105
+#: branch.c:106
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s'."
 msgstr "Grenen \"%s\" ställdes in att spåra fjärreferensen \"%s\"."
 
-#: branch.c:109
+#: branch.c:110
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s' by rebasing."
 msgstr ""
 "Grenen \"%s\" ställdes in att spåra den lokala referensen \"%s\" genom "
 "ombasering."
 
-#: branch.c:110
+#: branch.c:111
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s'."
 msgstr "Grenen \"%s\" ställdes in att spåra den lokala referensen \"%s\"."
 
-#: branch.c:119
+#: branch.c:120
 msgid "Unable to write upstream branch configuration"
 msgstr "Kan inte skriva inställningar för uppströmsgren"
 
-#: branch.c:156
+#: branch.c:157
 #, c-format
 msgid "Not tracking: ambiguous information for ref %s"
 msgstr "Spårar inte: tvetydig information för referensen %s"
 
-#: branch.c:189
+#: branch.c:190
 #, c-format
 msgid "'%s' is not a valid branch name."
 msgstr "\"%s\" är inte ett giltigt grennamn."
 
-#: branch.c:208
+#: branch.c:209
 #, c-format
 msgid "A branch named '%s' already exists."
 msgstr "Det finns redan en gren som heter ”%s”."
 
-#: branch.c:213
+#: branch.c:214
 msgid "Cannot force update the current branch."
 msgstr "Kan inte tvinga uppdatering av aktuell gren."
 
-#: branch.c:233
+#: branch.c:234
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr "Kan inte ställa in spårning; startpunkten \"%s\" är inte en gren."
 
-#: branch.c:235
+#: branch.c:236
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr "den efterfrågade uppströmsgrenen \"%s\" finns inte"
 
-#: branch.c:237
+#: branch.c:238
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -1144,27 +1144,27 @@ msgstr ""
 "spåra dess fjärrmotsvarighet kan du använda \"git push -u\"\n"
 "för att ställa in uppströmskonfigurationen när du sänder in."
 
-#: branch.c:280
+#: branch.c:281
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "Objektnamnet är inte giltigt: \"%s\"."
 
-#: branch.c:300
+#: branch.c:301
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "Objektnamnet är tvetydigt: \"%s\"."
 
-#: branch.c:305
+#: branch.c:306
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "Avgreningspunkten är inte giltig: ”%s”."
 
-#: branch.c:359
+#: branch.c:360
 #, c-format
 msgid "'%s' is already checked out at '%s'"
 msgstr "\"%s\" är redan utcheckad på \"%s\""
 
-#: branch.c:382
+#: branch.c:383
 #, c-format
 msgid "HEAD of working tree %s is not updated"
 msgstr "HEAD i arbetskatalogen %s har inte uppdaterats"
@@ -1179,7 +1179,7 @@ msgstr "'%s' ser inte ut som en v2-bundle-fil"
 msgid "unrecognized header: %s%s (%d)"
 msgstr "okänt huvud: %s%s (%d)"
 
-#: bundle.c:88 sequencer.c:1879 sequencer.c:2337 builtin/commit.c:750
+#: bundle.c:88 sequencer.c:2081 sequencer.c:2558 builtin/commit.c:755
 #, c-format
 msgid "could not open '%s'"
 msgstr "kunde inte öppna \"%s\""
@@ -1223,7 +1223,7 @@ msgstr "rev-list dog"
 msgid "ref '%s' is excluded by the rev-list options"
 msgstr "referensen \"%s\" exkluderas av argumenten till rev-list"
 
-#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:296
+#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:303
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "okänt argument: %s"
@@ -1246,18 +1246,39 @@ msgstr "index-pack dog"
 msgid "invalid color value: %.*s"
 msgstr "felaktigt färgvärde: %.*s"
 
-#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465
-#: builtin/am.c:1436 builtin/am.c:2072
+#: commit.c:43 sequencer.c:2364 builtin/am.c:421 builtin/am.c:465
+#: builtin/am.c:1436 builtin/am.c:2072 builtin/replace.c:376
+#: builtin/replace.c:448
 #, c-format
 msgid "could not parse %s"
 msgstr "kunde inte tolka %s"
 
-#: commit.c:43
+#: commit.c:45
 #, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s är inte en incheckning!"
 
-#: commit.c:1506
+#: commit.c:182
+msgid ""
+"Support for <GIT_DIR>/info/grafts is deprecated\n"
+"and will be removed in a future Git version.\n"
+"\n"
+"Please use \"git replace --convert-graft-file\"\n"
+"to convert the grafts into replace refs.\n"
+"\n"
+"Turn this message off by running\n"
+"\"git config advice.graftFileDeprecated false\""
+msgstr ""
+"Stöd för <GIT_DIR>/info/grafts avråds från och\n"
+"kommer tas bort i en framtida version av Git.\n"
+"\n"
+"Använd \"git replace --convert-graft-file\"\n"
+"för att omvandla grafts till ersättningsreferenser.\n"
+"\n"
+"Slå av detta meddelande genom att skriva\n"
+"\"git config advice.graftFileDeprecated false\""
+
+#: commit.c:1537
 msgid ""
 "Warning: commit message did not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
@@ -1267,178 +1288,192 @@ msgstr ""
 "Uppdatera det efter att ha rättat meddelandet, eller ändra variabeln\n"
 "i18n.commitencoding till den teckenkodning som används i ditt projekt.\n"
 
+#: commit-graph.c:669
+#, c-format
+msgid "the commit graph format cannot write %d commits"
+msgstr "formatet på incheckningsgrafen kan inte visa %d incheckningar"
+
+#: commit-graph.c:696
+msgid "too many commits to write graph"
+msgstr "för många incheckningar för att skriva graf"
+
+#: commit-graph.c:707 builtin/init-db.c:516 builtin/init-db.c:521
+#, c-format
+msgid "cannot mkdir %s"
+msgstr "kan inte skapa katalogen (mkdir) %s"
+
 #: compat/obstack.c:405 compat/obstack.c:407
 msgid "memory exhausted"
 msgstr "minnet slut"
 
-#: config.c:186
+#: config.c:187
 msgid "relative config include conditionals must come from files"
 msgstr "relativa konfigureringsinkluderingsvillkor måste komma från filer"
 
-#: config.c:720
+#: config.c:788
 #, c-format
 msgid "bad config line %d in blob %s"
 msgstr "felaktig konfigurationsfil rad %d i blob:en %s"
 
-#: config.c:724
+#: config.c:792
 #, c-format
 msgid "bad config line %d in file %s"
 msgstr "felaktig konfigurationsfil rad %d i filen %s"
 
-#: config.c:728
+#: config.c:796
 #, c-format
 msgid "bad config line %d in standard input"
 msgstr "felaktig konfigurationsfil rad %d i standard in"
 
-#: config.c:732
+#: config.c:800
 #, c-format
 msgid "bad config line %d in submodule-blob %s"
 msgstr "felaktig konfigurationsfil rad %d i undermoduls-blob:en %s"
 
-#: config.c:736
+#: config.c:804
 #, c-format
 msgid "bad config line %d in command line %s"
 msgstr "felaktig konfigurationsfil rad %d i kommandoraden %s"
 
-#: config.c:740
+#: config.c:808
 #, c-format
 msgid "bad config line %d in %s"
 msgstr "felaktig konfigurationsfil rad %d i %s"
 
-#: config.c:868
+#: config.c:936
 msgid "out of range"
 msgstr "utanför intervallet"
 
-#: config.c:868
+#: config.c:936
 msgid "invalid unit"
 msgstr "ogiltig enhet"
 
-#: config.c:874
+#: config.c:942
 #, c-format
 msgid "bad numeric config value '%s' for '%s': %s"
 msgstr "felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\": %s"
 
-#: config.c:879
+#: config.c:947
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
 msgstr ""
 "felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i blob:en %s: %s"
 
-#: config.c:882
+#: config.c:950
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in file %s: %s"
 msgstr ""
 "felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i filen %s: %s"
 
-#: config.c:885
+#: config.c:953
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in standard input: %s"
 msgstr ""
 "felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i standard in: %s"
 
-#: config.c:888
+#: config.c:956
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
 msgstr ""
 "felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i undermodul-blob:"
 "en %s: %s"
 
-#: config.c:891
+#: config.c:959
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
 msgstr ""
 "felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i kommandoraden "
 "%s: %s"
 
-#: config.c:894
+#: config.c:962
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in %s: %s"
 msgstr "felaktigt numeriskt konfigurationsvärde \"%s\" för \"%s\" i %s: %s"
 
-#: config.c:989
+#: config.c:1057
 #, c-format
 msgid "failed to expand user dir in: '%s'"
 msgstr "misslyckades expandera användarkatalog i: \"%s\""
 
-#: config.c:998
+#: config.c:1066
 #, c-format
 msgid "'%s' for '%s' is not a valid timestamp"
 msgstr "\"%s\" för \"%s\" är inte en giltig tidsstämpel"
 
-#: config.c:1094 config.c:1105
+#: config.c:1171 config.c:1182
 #, c-format
 msgid "bad zlib compression level %d"
 msgstr "felaktigt zlib-komprimeringsgrad %d"
 
-#: config.c:1225
+#: config.c:1307
 #, c-format
 msgid "invalid mode for object creation: %s"
 msgstr "felaktigt läge för skapande av objekt: %s"
 
-#: config.c:1386
+#: config.c:1473
 #, c-format
 msgid "bad pack compression level %d"
 msgstr "felaktig paketkomprimeringsgrad %d"
 
-#: config.c:1582
+#: config.c:1681
 msgid "unable to parse command-line config"
 msgstr "kan inte tolka kommandoradskonfiguration"
 
-#: config.c:1914
+#: config.c:2013
 msgid "unknown error occurred while reading the configuration files"
 msgstr "okänt fel uppstod vid läsning av konfigurationsfilerna"
 
-#: config.c:2101
+#: config.c:2200
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "Felaktigt %s: \"%s\""
 
-#: config.c:2144
+#: config.c:2243
 #, c-format
 msgid "unknown core.untrackedCache value '%s'; using 'keep' default value"
 msgstr ""
 "okänt värde \"%s\" för core.untrackedCache; använder standardvärdet \"keep\""
 
-#: config.c:2170
+#: config.c:2269
 #, c-format
 msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100"
 msgstr "värdet \"%d\" för splitIndex.maxPercentage borde vara mellan 0 och 100"
 
-#: config.c:2195
+#: config.c:2294
 #, c-format
 msgid "unable to parse '%s' from command-line config"
 msgstr "kunde inte tolka värdet \"%s\" från kommandoradskonfiguration"
 
-#: config.c:2197
+#: config.c:2296
 #, c-format
 msgid "bad config variable '%s' in file '%s' at line %d"
 msgstr "felaktig konfigurationsvariabel \"%s\" i filen \"%s\" på rad %d"
 
-#: config.c:2256
+#: config.c:2402
 #, c-format
 msgid "%s has multiple values"
 msgstr "%s har flera värden"
 
-#: config.c:2599 config.c:2816
+#: config.c:2766 config.c:3019
 #, c-format
 msgid "fstat on %s failed"
 msgstr "fstat misslyckades på %s"
 
-#: config.c:2706
+#: config.c:2905
 #, c-format
 msgid "could not set '%s' to '%s'"
 msgstr "kunde inte ställa in \"%s\" till \"%s\""
 
-#: config.c:2708 builtin/remote.c:776
+#: config.c:2907 builtin/remote.c:779
 #, c-format
 msgid "could not unset '%s'"
 msgstr "kunde inte ta bort inställning för \"%s\""
 
-#: connect.c:52
+#: connect.c:61
 msgid "The remote end hung up upon initial contact"
 msgstr "Fjärren lade på vid inledande kontakt"
 
-#: connect.c:54
+#: connect.c:63
 msgid ""
 "Could not read from remote repository.\n"
 "\n"
@@ -1452,7 +1487,7 @@ msgstr ""
 
 # Vague original, not networking-related, but rather related to the actual
 # objects in the database.
-#: connected.c:66 builtin/fsck.c:198 builtin/prune.c:144
+#: connected.c:66 builtin/fsck.c:201 builtin/prune.c:145
 msgid "Checking connectivity"
 msgstr "Kontrollerar konnektivitet"
 
@@ -1468,12 +1503,12 @@ msgstr "kunde inte skriva till rev-list"
 msgid "failed to close rev-list's stdin"
 msgstr "kunde inte stänga rev-list:s standard in"
 
-#: convert.c:205
+#: convert.c:206
 #, c-format
 msgid "CRLF would be replaced by LF in %s."
 msgstr "CRLF skulle ersättas av LF i %s."
 
-#: convert.c:207
+#: convert.c:208
 #, c-format
 msgid ""
 "CRLF will be replaced by LF in %s.\n"
@@ -1482,12 +1517,12 @@ msgstr ""
 "CRLF kommer att ersättas av LF i %s.\n"
 "Filen kommer att ha sina ursprungliga radbrytningar i din arbetskatalog."
 
-#: convert.c:215
+#: convert.c:216
 #, c-format
 msgid "LF would be replaced by CRLF in %s"
 msgstr "LF skulle ersättas av CRLF i %s"
 
-#: convert.c:217
+#: convert.c:218
 #, c-format
 msgid ""
 "LF will be replaced by CRLF in %s.\n"
@@ -1496,6 +1531,49 @@ msgstr ""
 "LF kommer att ersättas av CRLF i %s.\n"
 "Filen kommer att ha sina ursprungliga radbrytningar i din arbetskatalog."
 
+#: convert.c:279
+#, c-format
+msgid "BOM is prohibited in '%s' if encoded as %s"
+msgstr "BOM är förbjudet i \"%s\" om kodat som %s"
+
+#: convert.c:286
+#, c-format
+msgid ""
+"The file '%s' contains a byte order mark (BOM). Please use UTF-%s as working-"
+"tree-encoding."
+msgstr ""
+"Filen \"%s\" innehåller byte order mark (BOM). Använd UTF-%s som "
+"teckenkodning i arbetskatalogen."
+
+#: convert.c:304
+#, c-format
+msgid "BOM is required in '%s' if encoded as %s"
+msgstr "BOM krävs om \"%s\" kodas som %s"
+
+#: convert.c:306
+#, 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 ""
+"Filen \"%s\" saknar byte order mark (BOM). Använd UTF-%sBE eller UTF-%sLE "
+"(beroende på byteordning) som teckenkodning i arbetskatalogen."
+
+#: convert.c:424
+#, c-format
+msgid "failed to encode '%s' from %s to %s"
+msgstr "misslyckades omkoda \"%s\" från %s till %s"
+
+#: convert.c:467
+#, c-format
+msgid "encoding '%s' from %s to %s and back is not the same"
+msgstr ""
+"omkodning av \"%s\" från %s till %s och tillbaka ger inte samma resultat"
+
+#: convert.c:1225
+msgid "true/false are no valid working-tree-encodings"
+msgstr "true/false är inte giltig teckenkodning för arbetskatalogen"
+
 #: date.c:116
 msgid "in the future"
 msgstr "i framtiden"
@@ -1610,24 +1688,24 @@ msgstr ""
 "Hittade fel i konfigurationsvariabeln \"diff.dirstat\":\n"
 "%s"
 
-#: diff.c:3822
+#: diff.c:3823
 #, c-format
 msgid "external diff died, stopping at %s"
 msgstr "extern diff dog, stannar vid %s"
 
-#: diff.c:4146
+#: diff.c:4153
 msgid "--name-only, --name-status, --check and -s are mutually exclusive"
 msgstr "--name-only, --name-status, -check och -s är ömsesidigt uteslutande"
 
-#: diff.c:4149
+#: diff.c:4156
 msgid "-G, -S and --find-object are mutually exclusive"
 msgstr "-G, -S och --find-object är ömsesidigt uteslutande"
 
-#: diff.c:4237
+#: diff.c:4244
 msgid "--follow requires exactly one pathspec"
 msgstr "--follow kräver exakt en sökvägsangivelse"
 
-#: diff.c:4403
+#: diff.c:4410
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -1636,46 +1714,46 @@ msgstr ""
 "Misslyckades tolka argument till flaggan --dirstat/-X;\n"
 "%s"
 
-#: diff.c:4417
+#: diff.c:4424
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "Misslyckades tolka argument till flaggan --submodule: \"%s\""
 
-#: diff.c:5493
+#: diff.c:5500
 msgid "inexact rename detection was skipped due to too many files."
 msgstr ""
 "onöjaktig namnbytesdetektering utfördes inte på grund av för många filer."
 
-#: diff.c:5496
+#: diff.c:5503
 msgid "only found copies from modified paths due to too many files."
 msgstr "hittade bara kopior från ändrade sökvägar på grund av för många filer."
 
-#: diff.c:5499
+#: diff.c:5506
 #, c-format
 msgid ""
 "you may want to set your %s variable to at least %d and retry the command."
 msgstr ""
 "du kan sätta variabeln %s till åtminstone %d och försöka kommandot på nytt."
 
-#: dir.c:1866
+#: dir.c:1867
 #, c-format
 msgid "could not open directory '%s'"
 msgstr "kunde inte öppna katalogen \"%s\""
 
-#: dir.c:2108
+#: dir.c:2109
 msgid "failed to get kernel name and information"
 msgstr "misslyckades hämta kärnans namn och information"
 
-#: dir.c:2232
+#: dir.c:2233
 msgid "Untracked cache is disabled on this system or location."
 msgstr "Ospårad cache är inaktiverad på systemet eller platsen."
 
-#: dir.c:3024 dir.c:3029
+#: dir.c:3075 dir.c:3080
 #, c-format
 msgid "could not create directories for %s"
 msgstr "kunde inte skapa kataloger för %s"
 
-#: dir.c:3054
+#: dir.c:3109
 #, c-format
 msgid "could not migrate git directory from '%s' to '%s'"
 msgstr "kunde inte migrera git-katalog från \"%s\" till \"%s\""
@@ -1698,201 +1776,205 @@ msgstr "kunde inte ta status på filen \"%s\""
 msgid "Remote with no URL"
 msgstr "Fjärr utan URL"
 
-#: fetch-pack.c:253
+#: fetch-pack.c:254
 msgid "git fetch-pack: expected shallow list"
 msgstr "git fetch-pack: förväntade grund lista"
 
-#: fetch-pack.c:265
+#: fetch-pack.c:266
 msgid "git fetch-pack: expected ACK/NAK, got a flush packet"
 msgstr "git fetch-pack: förväntade ACK/NAK, fick flush-paket"
 
-#: fetch-pack.c:284 builtin/archive.c:63
+#: fetch-pack.c:285 builtin/archive.c:63
 #, c-format
 msgid "remote error: %s"
 msgstr "fjärrfel: %s"
 
-#: fetch-pack.c:285
+#: fetch-pack.c:286
 #, c-format
 msgid "git fetch-pack: expected ACK/NAK, got '%s'"
 msgstr "git fetch-pack: förväntade ACK/NAK, fick \"%s\""
 
-#: fetch-pack.c:337
+#: fetch-pack.c:338
 msgid "--stateless-rpc requires multi_ack_detailed"
 msgstr "--stateless-rpc kräver ”multi_ack_detailed”"
 
-#: fetch-pack.c:428
+#: fetch-pack.c:429 fetch-pack.c:1310
 #, c-format
 msgid "invalid shallow line: %s"
 msgstr "ogiltig \"shallow\"-rad: %s"
 
-#: fetch-pack.c:434
+#: fetch-pack.c:435 fetch-pack.c:1316
 #, c-format
 msgid "invalid unshallow line: %s"
 msgstr "ogiltig \"unshallow\"-rad: %s"
 
-#: fetch-pack.c:436
+#: fetch-pack.c:437 fetch-pack.c:1318
 #, c-format
 msgid "object not found: %s"
 msgstr "objektet hittades inte: %s"
 
-#: fetch-pack.c:439
+#: fetch-pack.c:440 fetch-pack.c:1321
 #, c-format
 msgid "error in object: %s"
 msgstr "fel i objekt: %s"
 
-#: fetch-pack.c:441
+#: fetch-pack.c:442 fetch-pack.c:1323
 #, c-format
 msgid "no shallow found: %s"
 msgstr "ingen \"shallow\" hittades: %s"
 
-#: fetch-pack.c:444
+#: fetch-pack.c:445 fetch-pack.c:1326
 #, c-format
 msgid "expected shallow/unshallow, got %s"
 msgstr "förväntade shallow/unshallow, fick %s"
 
-#: fetch-pack.c:485
+#: fetch-pack.c:486
 #, c-format
 msgid "got %s %d %s"
 msgstr "fick %s %d %s"
 
-#: fetch-pack.c:499
+#: fetch-pack.c:500
 #, c-format
 msgid "invalid commit %s"
 msgstr "ogiltig incheckning %s"
 
-#: fetch-pack.c:532
+#: fetch-pack.c:533
 msgid "giving up"
 msgstr "ger upp"
 
-#: fetch-pack.c:542 progress.c:229
+#: fetch-pack.c:543 progress.c:229
 msgid "done"
 msgstr "klart"
 
-#: fetch-pack.c:554
+#: fetch-pack.c:555
 #, c-format
 msgid "got %s (%d) %s"
 msgstr "fick %s (%d) %s"
 
-#: fetch-pack.c:600
+#: fetch-pack.c:601
 #, c-format
 msgid "Marking %s as complete"
 msgstr "Markerar %s som komplett"
 
-#: fetch-pack.c:788
+#: fetch-pack.c:828
 #, c-format
 msgid "already have %s (%s)"
 msgstr "har redan %s (%s)"
 
-#: fetch-pack.c:829
+#: fetch-pack.c:869
 msgid "fetch-pack: unable to fork off sideband demultiplexer"
 msgstr "fetch-patch: kunde inte grena av sidbandsmultiplexare"
 
-#: fetch-pack.c:837
+#: fetch-pack.c:877
 msgid "protocol error: bad pack header"
 msgstr "protokollfel: felaktigt packhuvud"
 
-#: fetch-pack.c:895
+#: fetch-pack.c:944
 #, c-format
 msgid "fetch-pack: unable to fork off %s"
 msgstr "fetch-patch: kunde inte grena av %s"
 
-#: fetch-pack.c:911
+#: fetch-pack.c:960
 #, c-format
 msgid "%s failed"
 msgstr "%s misslyckades"
 
-#: fetch-pack.c:913
+#: fetch-pack.c:962
 msgid "error in sideband demultiplexer"
 msgstr "fel i sidbands-avmultiplexare"
 
-#: fetch-pack.c:940
+#: fetch-pack.c:989
 msgid "Server does not support shallow clients"
 msgstr "Servern stöder inte klienter med grunda arkiv"
 
-#: fetch-pack.c:944
+#: fetch-pack.c:993
 msgid "Server supports multi_ack_detailed"
 msgstr "Servern stöder \"multi_ack_detailed\""
 
-#: fetch-pack.c:947
+#: fetch-pack.c:996
 msgid "Server supports no-done"
 msgstr "Servern stöder \"no-done\""
 
-#: fetch-pack.c:953
+#: fetch-pack.c:1002
 msgid "Server supports multi_ack"
 msgstr "Servern stöder \"multi_ack\""
 
-#: fetch-pack.c:957
+#: fetch-pack.c:1006
 msgid "Server supports side-band-64k"
 msgstr "Servern stöder \"side-band-64k\""
 
-#: fetch-pack.c:961
+#: fetch-pack.c:1010
 msgid "Server supports side-band"
 msgstr "Servern stöder \"side-band\""
 
-#: fetch-pack.c:965
+#: fetch-pack.c:1014
 msgid "Server supports allow-tip-sha1-in-want"
 msgstr "Servern stöder \"allow-tip-sha1-in-want\""
 
-#: fetch-pack.c:969
+#: fetch-pack.c:1018
 msgid "Server supports allow-reachable-sha1-in-want"
 msgstr "Servern stöder \"allow-reachable-sha1-in-want\""
 
-#: fetch-pack.c:979
+#: fetch-pack.c:1028
 msgid "Server supports ofs-delta"
 msgstr "Servern stöder \"ofs-delta\""
 
-#: fetch-pack.c:985
+#: fetch-pack.c:1034 fetch-pack.c:1204
 msgid "Server supports filter"
 msgstr "Servern stöder filter"
 
-#: fetch-pack.c:993
+#: fetch-pack.c:1042
 #, c-format
 msgid "Server version is %.*s"
 msgstr "Serverversionen är %.*s"
 
-#: fetch-pack.c:999
+#: fetch-pack.c:1048
 msgid "Server does not support --shallow-since"
 msgstr "Servern stöder inte --shallow-since"
 
-#: fetch-pack.c:1003
+#: fetch-pack.c:1052
 msgid "Server does not support --shallow-exclude"
 msgstr "Servern stöder inte --shallow-exclude"
 
-#: fetch-pack.c:1005
+#: fetch-pack.c:1054
 msgid "Server does not support --deepen"
 msgstr "Servern stöder inte --deepen"
 
-#: fetch-pack.c:1016
+#: fetch-pack.c:1065
 msgid "no common commits"
 msgstr "inga gemensamma incheckningar"
 
-#: fetch-pack.c:1028
+#: fetch-pack.c:1077 fetch-pack.c:1414
 msgid "git fetch-pack: fetch failed."
 msgstr "git fetch-patch: hämtning misslyckades."
 
-#: fetch-pack.c:1190
+#: fetch-pack.c:1199
+msgid "Server does not support shallow requests"
+msgstr "Servern stöder inte grunda förfrågningar"
+
+#: fetch-pack.c:1584
 msgid "no matching remote head"
 msgstr "inget motsvarande fjärrhuvud"
 
-#: fetch-pack.c:1212
+#: fetch-pack.c:1610
 #, c-format
 msgid "no such remote ref %s"
 msgstr "ingen sådan fjärreferens: %s"
 
-#: fetch-pack.c:1215
+#: fetch-pack.c:1613
 #, c-format
 msgid "Server does not allow request for unadvertised object %s"
 msgstr "Servern tillåter inte förfrågan om ej tillkännagivet objekt %s"
 
-#: gpg-interface.c:181
+#: gpg-interface.c:185
 msgid "gpg failed to sign the data"
 msgstr "gpg misslyckades signera data"
 
-#: gpg-interface.c:211
+#: gpg-interface.c:210
 msgid "could not create temporary file"
 msgstr "kunde inte skapa temporära fil"
 
-#: gpg-interface.c:214
+#: gpg-interface.c:213
 #, c-format
 msgid "failed writing detached signature to '%s'"
 msgstr "misslyckades skriva fristående signatur till \"%s\""
@@ -1902,36 +1984,97 @@ msgstr "misslyckades skriva fristående signatur till \"%s\""
 msgid "ignore invalid color '%.*s' in log.graphColors"
 msgstr "ignorera felaktig färg \"%.*s\" i log.graphColors"
 
-#: grep.c:2022
+#: grep.c:2020
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "\"%s\" kunde inte läsa %s"
 
-#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81
+#: grep.c:2037 setup.c:164 builtin/clone.c:409 builtin/diff.c:81
 #: builtin/rm.c:134
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "misslyckades ta status på \"%s\""
 
-#: grep.c:2050
+#: grep.c:2048
 #, c-format
 msgid "'%s': short read"
 msgstr "\"%s\": kort läsning"
 
-#: help.c:179
+#: help.c:23
+msgid "start a working area (see also: git help tutorial)"
+msgstr "starta arbetskatalog (se också: git help tutorial)"
+
+#: help.c:24
+msgid "work on the current change (see also: git help everyday)"
+msgstr "jobba med aktuell förändring (se också: git help everyday)"
+
+#: help.c:25
+msgid "examine the history and state (see also: git help revisions)"
+msgstr "utforska historiken och tillståndet (se också: git help revisions)"
+
+#: help.c:26
+msgid "grow, mark and tweak your common history"
+msgstr "utöka, markera och justera din gemensamma historik"
+
+#: help.c:27
+msgid "collaborate (see also: git help workflows)"
+msgstr "samarbeta (se också: git help workflows)"
+
+#: help.c:31
+msgid "Main Porcelain Commands"
+msgstr "Huvudsakliga porslinskommandon"
+
+#: help.c:32
+msgid "Ancillary Commands / Manipulators"
+msgstr "Tilläggskommandon / manipulerare"
+
+#: help.c:33
+msgid "Ancillary Commands / Interrogators"
+msgstr "Tilläggskommandon / frågare"
+
+#: help.c:34
+msgid "Interacting with Others"
+msgstr "Interaktion med andra"
+
+#: help.c:35
+msgid "Low-level Commands / Manipulators"
+msgstr "Lågnivåkommandon / maniupulerare"
+
+#: help.c:36
+msgid "Low-level Commands / Interrogators"
+msgstr "Lågnivåkommandon / frågare"
+
+#: help.c:37
+msgid "Low-level Commands / Synching Repositories"
+msgstr "Lågnivåkommandon / synka arkiv"
+
+#: help.c:38
+msgid "Low-level Commands / Internal Helpers"
+msgstr "Lågnivåkommandon / interna hjälpare"
+
+#: help.c:293
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "git-kommandon tillgängliga i \"%s\""
 
-#: help.c:186
+#: help.c:300
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "git-kommandon från andra platser i din $PATH"
 
-#: help.c:217
+#: help.c:309
 msgid "These are common Git commands used in various situations:"
 msgstr "Dessa vanliga Git-kommandon används i olika situationer:"
 
-#: help.c:281
+#: help.c:358 git.c:90
+#, c-format
+msgid "unsupported command listing type '%s'"
+msgstr "okänd kommandolisttyp \"%s\""
+
+#: help.c:405
+msgid "The common Git guides are:"
+msgstr "De vanliga Git-vägledningarna är:"
+
+#: help.c:467
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -1940,32 +2083,32 @@ msgstr ""
 "\"%s\" verkar vara ett git-kommando, men vi kan inte\n"
 "köra det. Kanske git-%s är trasigt?"
 
-#: help.c:336
+#: help.c:526
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "Oj då. Ditt system rapporterar inga Git-kommandon alls."
 
-#: help.c:358
+#: help.c:548
 #, c-format
 msgid "WARNING: You called a Git command named '%s', which does not exist."
 msgstr "VARNING: Du anropade ett Git-kommando vid namn \"%s\", som inte finns."
 
-#: help.c:363
+#: help.c:553
 #, c-format
 msgid "Continuing under the assumption that you meant '%s'."
 msgstr "Fortsätter under förutsättningen att du menade ”%s”."
 
-#: help.c:368
+#: help.c:558
 #, c-format
 msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
 msgstr ""
 "Fortsätter om %0.1f sekunder, under förutsättningen att du menade ”%s”."
 
-#: help.c:376
+#: help.c:566
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git: \"%s\" är inte ett git-kommando. Se \"git --help\"."
 
-#: help.c:380
+#: help.c:570
 msgid ""
 "\n"
 "The most similar command is"
@@ -1979,16 +2122,16 @@ msgstr[1] ""
 "\n"
 "Mest lika kommandon är"
 
-#: help.c:395
+#: help.c:585
 msgid "git version [<options>]"
 msgstr "git version [<flaggor>]"
 
-#: help.c:462
+#: help.c:652
 #, c-format
 msgid "%s: %s - %s"
 msgstr "%s: %s - %s"
 
-#: help.c:466
+#: help.c:656
 msgid ""
 "\n"
 "Did you mean this?"
@@ -2056,7 +2199,7 @@ msgstr "tomt ident-namn (för <%s>) ej tillåtet"
 msgid "name consists only of disallowed characters: %s"
 msgstr "namnet består enbart av ej tillåtna tecken: %s"
 
-#: ident.c:416 builtin/commit.c:582
+#: ident.c:416 builtin/commit.c:587
 #, c-format
 msgid "invalid date format: %s"
 msgstr "felaktigt datumformat: %s"
@@ -2094,82 +2237,166 @@ msgstr ""
 msgid "Unable to create '%s.lock': %s"
 msgstr "Kunde inte skapa \"%s.lock\": %s"
 
-#: merge.c:74
+#: merge.c:71
 msgid "failed to read the cache"
 msgstr "misslyckades läsa cachen"
 
-#: merge.c:134 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
-#: builtin/checkout.c:599 builtin/clone.c:759
+#: merge.c:136 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
+#: builtin/checkout.c:606 builtin/clone.c:761
 msgid "unable to write new index file"
 msgstr "kunde inte skriva ny indexfil"
 
-#: merge-recursive.c:235
+#: merge-recursive.c:298
 msgid "(bad commit)\n"
 msgstr "(felaktig incheckning)\n"
 
-#: merge-recursive.c:257 merge-recursive.c:265
+#: merge-recursive.c:320
+#, c-format
+msgid "add_cacheinfo failed for path '%s'; merge aborting."
+msgstr ""
+"add_cahceinfo misslyckades för sökvägen \"%s\"; avslutar sammanslagningen."
+
+#: merge-recursive.c:328
 #, c-format
-msgid "addinfo_cache failed for path '%s'"
-msgstr "addinfo_cache misslyckades för sökvägen \"%s\""
+msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
+msgstr ""
+"add_cacheinfo misslyckades uppdatera för sökvägen \"%s\"; avslutar "
+"sammanslagningen."
 
-#: merge-recursive.c:329
+#: merge-recursive.c:410
 msgid "error building trees"
 msgstr "fel vid byggande av träd"
 
-#: merge-recursive.c:771
+#: merge-recursive.c:881
 #, c-format
 msgid "failed to create path '%s'%s"
 msgstr "misslyckades skapa sökvägen \"%s\"%s"
 
-#: merge-recursive.c:782
+#: merge-recursive.c:892
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr "Tar bort %s för att göra plats för underkatalog\n"
 
-#: merge-recursive.c:796 merge-recursive.c:815
+#: merge-recursive.c:906 merge-recursive.c:925
 msgid ": perhaps a D/F conflict?"
 msgstr ": kanske en K/F-konflikt?"
 
-#: merge-recursive.c:805
+#: merge-recursive.c:915
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
 msgstr "vägrar förlora ospårad fil vid \"%s\""
 
-#: merge-recursive.c:847 builtin/cat-file.c:37
+#: merge-recursive.c:957 builtin/cat-file.c:37
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr "kan inte läsa objektet %s: \"%s\""
 
-#: merge-recursive.c:849
+#: merge-recursive.c:959
 #, c-format
 msgid "blob expected for %s '%s'"
 msgstr "blob förväntades för %s \"%s\""
 
-#: merge-recursive.c:873
+#: merge-recursive.c:983
 #, c-format
 msgid "failed to open '%s': %s"
 msgstr "misslyckades öppna \"%s\": %s"
 
-#: merge-recursive.c:884
+#: merge-recursive.c:994
 #, c-format
 msgid "failed to symlink '%s': %s"
 msgstr "misslyckades skapa symboliska länken \"%s\": %s"
 
-#: merge-recursive.c:889
+#: merge-recursive.c:999
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
 msgstr "vet inte hur %06o %s \"%s\" skall hanteras"
 
-#: merge-recursive.c:1029
+#: merge-recursive.c:1186
+#, c-format
+msgid "Failed to merge submodule %s (not checked out)"
+msgstr "Misslyckades slå ihop undermodulen %s (ej utcheckad)"
+
+#: merge-recursive.c:1193
+#, c-format
+msgid "Failed to merge submodule %s (commits not present)"
+msgstr "Misslyckades slå ihop undermodulen %s (incheckningar saknas)"
+
+#: merge-recursive.c:1200
+#, c-format
+msgid "Failed to merge submodule %s (commits don't follow merge-base)"
+msgstr ""
+"Misslyckades slå ihop undermodulen %s (incheckningar följer inte "
+"sammanslagningsbasen)"
+
+#: merge-recursive.c:1208 merge-recursive.c:1220
+#, c-format
+msgid "Fast-forwarding submodule %s to the following commit:"
+msgstr "Snabbspolar undermodulen %s till följande incheckning:"
+
+#: merge-recursive.c:1211 merge-recursive.c:1223
+#, c-format
+msgid "Fast-forwarding submodule %s to %s"
+msgstr "Snabbspolar undermodulen %s till %s"
+
+#: merge-recursive.c:1245
+#, c-format
+msgid "Failed to merge submodule %s (merge following commits not found)"
+msgstr ""
+"Misslyckades slå ihop undermodulen %s (sammanslagning efter incheckningar "
+"hittades inte)"
+
+#: merge-recursive.c:1249
+#, c-format
+msgid "Failed to merge submodule %s (not fast-forward)"
+msgstr "Misslyckades slå ihop undermodulen %s (ej snabbspolning)"
+
+#: merge-recursive.c:1250
+msgid "Found a possible merge resolution for the submodule:\n"
+msgstr "Hittade en möjlig lösning av sammanslagning för undermodulen:\n"
+
+#: merge-recursive.c:1253
+#, 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 ""
+"Om detta är riktigt lägger du bara till det i indexet, till\n"
+"exempel så här:\n"
+"\n"
+"  git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"vilket godtar lösningen.\n"
+
+#: merge-recursive.c:1262
+#, c-format
+msgid "Failed to merge submodule %s (multiple merges found)"
+msgstr ""
+"Misslyckades slå ihop undermodulen %s (flera sammanslagningar hittades)"
+
+#: merge-recursive.c:1321
 msgid "Failed to execute internal merge"
 msgstr "Misslyckades exekvera intern sammanslagning"
 
-#: merge-recursive.c:1034
+#: merge-recursive.c:1326
 #, c-format
 msgid "Unable to add %s to database"
 msgstr "Kunde inte lägga till %s till databasen"
 
-#: merge-recursive.c:1146
+#: merge-recursive.c:1358
+#, c-format
+msgid "Auto-merging %s"
+msgstr "Slår ihop %s automatiskt"
+
+#: merge-recursive.c:1423
+#, c-format
+msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
+msgstr "Fel: Vägrar förlora ospårad fil vid %s; skriver till %s istället."
+
+#: merge-recursive.c:1475
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2178,7 +2405,7 @@ msgstr ""
 "KONFLIKT (%s/radera): %s raderad i %s och %s i %s. Versionen %s av %s lämnad "
 "i trädet."
 
-#: merge-recursive.c:1151
+#: merge-recursive.c:1480
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2187,7 +2414,7 @@ msgstr ""
 "KONFLIKT (%s/radera): %s raderad i %s och %s till %s i %s. Versionen %s av "
 "%s lämnad i trädet."
 
-#: merge-recursive.c:1158
+#: merge-recursive.c:1487
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2196,7 +2423,7 @@ msgstr ""
 "KONFLIKT (%s/radera): %s raderad i %s och %s i %s. Versionen %s av %s lämnad "
 "i trädet vid %s."
 
-#: merge-recursive.c:1163
+#: merge-recursive.c:1492
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2205,20 +2432,31 @@ msgstr ""
 "KONFLIKT (%s/radera): %s raderad i %s och %s till %s i %s. Versionen %s av "
 "%s lämnad i trädet vid %s."
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "rename"
 msgstr "namnbyte"
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "renamed"
 msgstr "namnbytt"
 
-#: merge-recursive.c:1254
+#: merge-recursive.c:1580 merge-recursive.c:1736 merge-recursive.c:2368
+#: merge-recursive.c:3086
+#, c-format
+msgid "Refusing to lose dirty file at %s"
+msgstr "Vägrar förlora lortig fil vid \"%s\""
+
+#: merge-recursive.c:1594
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr "%s är en katalog i %s lägger till som %s istället"
 
-#: merge-recursive.c:1279
+#: merge-recursive.c:1599
+#, c-format
+msgid "Refusing to lose untracked file at %s; adding as %s instead"
+msgstr "Vägrar förlora ospårad fil vid %s; lägger till som %s istället"
+
+#: merge-recursive.c:1625
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
@@ -2227,140 +2465,187 @@ msgstr ""
 "KONFLIKT (namnbyte/namnbyte): Namnbyte \"%s\"->\"%s\" på grenen \"%s\" "
 "namnbyte \"%s\"->\"%s\" i \"%s\"%s"
 
-#: merge-recursive.c:1284
+#: merge-recursive.c:1630
 msgid " (left unresolved)"
 msgstr " (lämnad olöst)"
 
-#: merge-recursive.c:1346
+#: merge-recursive.c:1694
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
 "KONFLIKT (namnbyte/namnbyte): Namnbyte %s->%s i %s. Namnbyte %s->%s i %s"
 
-#: merge-recursive.c:1379
+#: merge-recursive.c:1733
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr "Byter namn på %s till %s och %s till %s istället"
 
-#: merge-recursive.c:1582
+#: merge-recursive.c:1745
+#, c-format
+msgid "Refusing to lose untracked file at %s, even though it's in the way."
+msgstr "Vägrar förlora ospårad fil vid %s, trots att den är i vägen."
+
+#: merge-recursive.c:1951
+#, c-format
+msgid ""
+"CONFLICT (directory rename split): Unclear where to place %s because "
+"directory %s was renamed to multiple other directories, with no destination "
+"getting a majority of the files."
+msgstr ""
+"KONFLIKT (namnändrad delad katalog): Osäker på var %s skall placeras då "
+"katalogen %s bytte namn till flera andra kataloger, utan att någon "
+"destination fick en majoritet av filerna."
+
+#: merge-recursive.c:1983
+#, c-format
+msgid ""
+"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 ""
+"KONFLIKT (implicit nämnändrad kat): Befintlig fil/kat vid %s är i vägen för "
+"implicit namnändrad(e) katalog(er) som lägger dit följande sökväg(ar): %s."
+
+#: merge-recursive.c:1993
+#, 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 ""
+"KONFLIKT (implicit namnändrad kat): Kan inte koppla mer än en sökväg till "
+"%s; implicita katalognamnändringar försökte lägga följande sökvägar där: %s"
+
+#: merge-recursive.c:2085
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-"
+">%s in %s"
+msgstr ""
+"KONFLIKT (namnbyte/namnbyte): Namnbytt katalog %s->%s i %s. Namnbytt katalog "
+"%s->%s i %s"
+
+#: merge-recursive.c:2330
+#, c-format
+msgid ""
+"WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
+"renamed."
+msgstr ""
+"VARNING: Undviker att applicera namnändring %s -> %s på %s, då %s själv har "
+"bytt namn."
+
+#: merge-recursive.c:2736
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
 msgstr "KONFLIKT (namnbyte/tillägg): Namnbyte %s->%s i %s. %s tillagd i %s"
 
-#: merge-recursive.c:1597
+#: merge-recursive.c:2751
 #, c-format
 msgid "Adding merged %s"
 msgstr "Lägger till sammanslagen %s"
 
-#: merge-recursive.c:1604 merge-recursive.c:1834
+#: merge-recursive.c:2758 merge-recursive.c:3089
 #, c-format
 msgid "Adding as %s instead"
 msgstr "Lägger till som %s istället"
 
-#: merge-recursive.c:1661
+#: merge-recursive.c:2914
 #, c-format
 msgid "cannot read object %s"
 msgstr "kan inte läsa objektet %s"
 
-#: merge-recursive.c:1664
+#: merge-recursive.c:2917
 #, c-format
 msgid "object %s is not a blob"
 msgstr "objektet %s är inte en blob"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modify"
 msgstr "ändra"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modified"
 msgstr "ändrad"
 
-#: merge-recursive.c:1743
+#: merge-recursive.c:2997
 msgid "content"
 msgstr "innehåll"
 
-#: merge-recursive.c:1750
+#: merge-recursive.c:3004
 msgid "add/add"
 msgstr "tillägg/tillägg"
 
-#: merge-recursive.c:1786
+#: merge-recursive.c:3046
 #, c-format
 msgid "Skipped %s (merged same as existing)"
 msgstr "Hoppade över %s (sammanslagen samma som befintlig)"
 
-#: merge-recursive.c:1800
-#, c-format
-msgid "Auto-merging %s"
-msgstr "Slår ihop %s automatiskt"
-
-#: merge-recursive.c:1804 git-submodule.sh:879
+#: merge-recursive.c:3055 git-submodule.sh:895
 msgid "submodule"
 msgstr "undermodul"
 
-#: merge-recursive.c:1805
+#: merge-recursive.c:3056
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
 msgstr "KONFLIKT (%s): Sammanslagningskonflikt i %s"
 
-#: merge-recursive.c:1899
+#: merge-recursive.c:3178
 #, c-format
 msgid "Removing %s"
 msgstr "Tar bort %s"
 
-#: merge-recursive.c:1925
+#: merge-recursive.c:3204
 msgid "file/directory"
 msgstr "fil/katalog"
 
-#: merge-recursive.c:1931
+#: merge-recursive.c:3210
 msgid "directory/file"
 msgstr "katalog/fil"
 
-#: merge-recursive.c:1938
+#: merge-recursive.c:3217
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
 msgstr ""
 "KONFLIKT (%s): Det finns en katalog med namnet %s i %s. Lägger till %s som %s"
 
-#: merge-recursive.c:1947
+#: merge-recursive.c:3226
 #, c-format
 msgid "Adding %s"
 msgstr "Lägger till %s"
 
-#: merge-recursive.c:1987
+#: merge-recursive.c:3267
 #, c-format
 msgid "Dirty index: cannot merge (dirty: %s)"
 msgstr "Smutsigt index: kan inte slå ihop (smutsiga: %s)"
 
-#: merge-recursive.c:1991
+#: merge-recursive.c:3271
 msgid "Already up to date!"
 msgstr "Redan à jour!"
 
-#: merge-recursive.c:2000
+#: merge-recursive.c:3280
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr "sammanslagning av träden %s och %s misslyckades"
 
-#: merge-recursive.c:2097
+#: merge-recursive.c:3379
 msgid "Merging:"
 msgstr "Slår ihop:"
 
-#: merge-recursive.c:2110
+#: merge-recursive.c:3392
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] "hittade %u gemensam förfader:"
 msgstr[1] "hittade %u gemensamma förfäder:"
 
-#: merge-recursive.c:2149
+#: merge-recursive.c:3431
 msgid "merge returned no commit"
 msgstr "sammanslagningen returnerade ingen incheckning"
 
-#: merge-recursive.c:2212
+#: merge-recursive.c:3495
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr "Kunde inte tolka objektet \"%s\""
 
-#: merge-recursive.c:2228 builtin/merge.c:657 builtin/merge.c:816
+#: merge-recursive.c:3511 builtin/merge.c:659 builtin/merge.c:816
 msgid "Unable to write index."
 msgstr "Kunde inte skriva indexet."
 
@@ -2404,30 +2689,30 @@ msgstr "Vägrar skriva över anteckningar i %s (utanför refs/notes/)"
 msgid "Bad %s value: '%s'"
 msgstr "Felaktigt värde på %s: \"%s\""
 
-#: object.c:239
+#: object.c:242
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "kunde inte tolka objektet: %s"
 
-#: packfile.c:561
+#: packfile.c:563
 msgid "offset before end of packfile (broken .idx?)"
 msgstr "offset före slutet av packfilen (trasig .idx?)"
 
-#: packfile.c:1694
+#: packfile.c:1742
 #, c-format
 msgid "offset before start of pack index for %s (corrupt index?)"
 msgstr "offset före slutet av packindex för %s (trasigt index?)"
 
-#: packfile.c:1698
+#: packfile.c:1746
 #, c-format
 msgid "offset beyond end of pack index for %s (truncated index?)"
 msgstr "offset borton slutet av packindex för %s (trunkerat index?)"
 
-#: parse-options.c:619
+#: parse-options.c:621
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:638
+#: parse-options.c:640
 #, c-format
 msgid "usage: %s"
 msgstr "användning: %s"
@@ -2435,26 +2720,31 @@ msgstr "användning: %s"
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation.
 #.
-#: parse-options.c:644
+#: parse-options.c:646
 #, c-format
 msgid "   or: %s"
 msgstr "     eller: %s"
 
-#: parse-options.c:647
+#: parse-options.c:649
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:686
+#: parse-options.c:688
 msgid "-NUM"
 msgstr "-TAL"
 
-#: parse-options-cb.c:108
+#: parse-options-cb.c:44
+#, c-format
+msgid "malformed expiration date '%s'"
+msgstr "trasigt utlöpsdatum: ”%s”"
+
+#: parse-options-cb.c:112
 #, c-format
 msgid "malformed object name '%s'"
 msgstr "felformat objektnamn \"%s\""
 
-#: path.c:891
+#: path.c:892
 #, c-format
 msgid "Could not make %s writable by group"
 msgstr "Kunde inte göra %s skrivbar för gruppen"
@@ -2537,7 +2827,7 @@ msgstr "sökvägsangivelsen \"%s\" är på andra sidan av en symbolisk länk"
 msgid "unable to parse --pretty format"
 msgstr "kunde inte tolka format för --pretty"
 
-#: read-cache.c:1473
+#: read-cache.c:1500
 #, c-format
 msgid ""
 "index.version set, but the value is invalid.\n"
@@ -2546,7 +2836,7 @@ msgstr ""
 "index.version satt, men värdet är ogiltigt.\n"
 "Använder version %i"
 
-#: read-cache.c:1483
+#: read-cache.c:1510
 #, c-format
 msgid ""
 "GIT_INDEX_VERSION set, but the value is invalid.\n"
@@ -2555,52 +2845,53 @@ msgstr ""
 "GIT_INDEX_VERSION satt, men värdet är ogiltigt.\n"
 "Använder version %i"
 
-#: read-cache.c:2375 sequencer.c:3248 wrapper.c:658 builtin/merge.c:1049
+#: read-cache.c:2404 sequencer.c:4338 wrapper.c:658 builtin/merge.c:1048
 #, c-format
 msgid "could not close '%s'"
 msgstr "kunde inte stänga \"%s\""
 
-#: read-cache.c:2448 sequencer.c:1900 sequencer.c:2627
+#: read-cache.c:2477 sequencer.c:2102 sequencer.c:3234
 #, c-format
 msgid "could not stat '%s'"
 msgstr "kunde inte ta status på \"%s\""
 
-#: read-cache.c:2461
+#: read-cache.c:2490
 #, c-format
 msgid "unable to open git dir: %s"
 msgstr "kunde inte öppna git-katalog: %s"
 
-#: read-cache.c:2473
+#: read-cache.c:2502
 #, c-format
 msgid "unable to unlink: %s"
 msgstr "misslyckades ta bort länken: %s"
 
-#: refs.c:706
+#: refs.c:732 sequencer.c:4334 sequencer.c:4393 wrapper.c:225 wrapper.c:395
+#: builtin/am.c:779
 #, c-format
-msgid "Could not open '%s' for writing"
-msgstr "Kunde inte öppna \"%s\" för skrivning"
+msgid "could not open '%s' for writing"
+msgstr "kunde inte öppna \"%s\" för skrivning"
 
-#: refs.c:1850
+#: refs.c:1880
 msgid "ref updates forbidden inside quarantine environment"
 msgstr "referensuppdateringar förbjudna i karantänmiljö"
 
-#: refs/files-backend.c:1189
+#: refs/files-backend.c:1191
 #, c-format
 msgid "could not remove reference %s"
 msgstr "kunde inte ta bort referensen %s"
 
-#: refs/files-backend.c:1203 refs/packed-backend.c:1528
-#: refs/packed-backend.c:1538
+#: refs/files-backend.c:1205 refs/packed-backend.c:1531
+#: refs/packed-backend.c:1541
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "kunde inte ta bort referensen %s: %s"
 
-#: refs/files-backend.c:1206 refs/packed-backend.c:1541
+#: refs/files-backend.c:1208 refs/packed-backend.c:1544
 #, c-format
 msgid "could not delete references: %s"
 msgstr "kunde inte ta bort referenser: %s"
 
-#: ref-filter.c:35 wt-status.c:1842
+#: ref-filter.c:35 wt-status.c:1850
 msgid "gone"
 msgstr "försvunnen"
 
@@ -2619,157 +2910,162 @@ msgstr "bakom %d"
 msgid "ahead %d, behind %d"
 msgstr "före %d, bakom %d"
 
-#: ref-filter.c:107
+#: ref-filter.c:121
 #, c-format
 msgid "expected format: %%(color:<color>)"
 msgstr "förväntat format: %%(color:<color>)"
 
-#: ref-filter.c:109
+#: ref-filter.c:123
 #, c-format
 msgid "unrecognized color: %%(color:%s)"
 msgstr "okänd färg: %%(color:%s)"
 
-#: ref-filter.c:129
+#: ref-filter.c:145
 #, c-format
 msgid "Integer value expected refname:lstrip=%s"
 msgstr "Heltalsvärde förväntades refname:lstrip=%s"
 
-#: ref-filter.c:133
+#: ref-filter.c:149
 #, c-format
 msgid "Integer value expected refname:rstrip=%s"
 msgstr "Heltalsvärde förväntades refname:rstrip=%s"
 
-#: ref-filter.c:135
+#: ref-filter.c:151
 #, c-format
 msgid "unrecognized %%(%s) argument: %s"
 msgstr "okänt %%(%s)-argument: %s"
 
-#: ref-filter.c:184
+#: ref-filter.c:206
 #, c-format
 msgid "%%(body) does not take arguments"
 msgstr "%%(body) tar inte argument"
 
-#: ref-filter.c:191
+#: ref-filter.c:215
 #, c-format
 msgid "%%(subject) does not take arguments"
 msgstr "%%(subject) tar inte argument"
 
-#: ref-filter.c:209
+#: ref-filter.c:235
 #, c-format
 msgid "unknown %%(trailers) argument: %s"
 msgstr "okänt %%(trailers)-argument: %s"
 
-#: ref-filter.c:232
+#: ref-filter.c:264
 #, c-format
 msgid "positive value expected contents:lines=%s"
 msgstr "positivt värde förväntat contents:lines=%s"
 
-#: ref-filter.c:234
+#: ref-filter.c:266
 #, c-format
 msgid "unrecognized %%(contents) argument: %s"
 msgstr "okänt %%(contents)-argument: %s"
 
-#: ref-filter.c:247
+#: ref-filter.c:281
 #, c-format
 msgid "positive value expected objectname:short=%s"
 msgstr "positivt värde förväntat objectname:short=%s"
 
-#: ref-filter.c:251
+#: ref-filter.c:285
 #, c-format
 msgid "unrecognized %%(objectname) argument: %s"
 msgstr "okänt %%(objectname)-argument: %s"
 
-#: ref-filter.c:278
+#: ref-filter.c:315
 #, c-format
 msgid "expected format: %%(align:<width>,<position>)"
 msgstr "förväntat format: %%(align:<bredd>,<position>)"
 
-#: ref-filter.c:290
+#: ref-filter.c:327
 #, c-format
 msgid "unrecognized position:%s"
 msgstr "okänd position:%s"
 
-#: ref-filter.c:294
+#: ref-filter.c:334
 #, c-format
 msgid "unrecognized width:%s"
 msgstr "okänd bredd:%s"
 
-#: ref-filter.c:300
+#: ref-filter.c:343
 #, c-format
 msgid "unrecognized %%(align) argument: %s"
 msgstr "okänt %%(align)-argument: %s"
 
-#: ref-filter.c:304
+#: ref-filter.c:351
 #, c-format
 msgid "positive width expected with the %%(align) atom"
 msgstr "positiv bredd förväntad med atomen %%(align)"
 
-#: ref-filter.c:319
+#: ref-filter.c:369
 #, c-format
 msgid "unrecognized %%(if) argument: %s"
 msgstr "okänt %%(if)-argument: %s"
 
-#: ref-filter.c:409
+#: ref-filter.c:464
 #, c-format
 msgid "malformed field name: %.*s"
 msgstr "felformat fältnamn: %.*s"
 
-#: ref-filter.c:435
+#: ref-filter.c:491
 #, c-format
 msgid "unknown field name: %.*s"
 msgstr "okänt fältnamn: %.*s"
 
-#: ref-filter.c:547
+#: ref-filter.c:608
 #, c-format
 msgid "format: %%(if) atom used without a %%(then) atom"
 msgstr "format: atomen %%(if) använd utan en %%(then)-atom"
 
-#: ref-filter.c:607
+#: ref-filter.c:671
 #, c-format
 msgid "format: %%(then) atom used without an %%(if) atom"
 msgstr "format: atomen %%(then) använd utan en %%(if)-atom"
 
-#: ref-filter.c:609
+#: ref-filter.c:673
 #, c-format
 msgid "format: %%(then) atom used more than once"
 msgstr "format: atomen %%(then) använd mer än en gång"
 
-#: ref-filter.c:611
+#: ref-filter.c:675
 #, c-format
 msgid "format: %%(then) atom used after %%(else)"
 msgstr "format: atomen %%(then) använd efter %%(else)"
 
-#: ref-filter.c:637
+#: ref-filter.c:703
 #, c-format
 msgid "format: %%(else) atom used without an %%(if) atom"
 msgstr "format: atomen %%(else) använd utan en %%(if)-atom"
 
-#: ref-filter.c:639
+#: ref-filter.c:705
 #, c-format
 msgid "format: %%(else) atom used without a %%(then) atom"
 msgstr "format: atomen %%(else) använd utan en %%(then)-atom"
 
-#: ref-filter.c:641
+#: ref-filter.c:707
 #, c-format
 msgid "format: %%(else) atom used more than once"
 msgstr "format: atomen %%(else) använd mer än en gång"
 
-#: ref-filter.c:654
+#: ref-filter.c:722
 #, c-format
 msgid "format: %%(end) atom used without corresponding atom"
 msgstr "format: atomen %%(end) använd utan motsvarande atom"
 
-#: ref-filter.c:709
+#: ref-filter.c:779
 #, c-format
 msgid "malformed format string %s"
 msgstr "felformad formatsträng %s"
 
-#: ref-filter.c:1313
+#: ref-filter.c:1387
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(ingen gren, ombaserar %s)"
 
-#: ref-filter.c:1316
+#: ref-filter.c:1390
+#, c-format
+msgid "(no branch, rebasing detached HEAD %s)"
+msgstr "(ingen gren, ombaserar frånkopplat HEAD %s)"
+
+#: ref-filter.c:1393
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(ingen gren, \"bisect\" startad på %s)"
@@ -2777,7 +3073,7 @@ msgstr "(ingen gren, \"bisect\" startad på %s)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached at " in wt-status.c
 #.
-#: ref-filter.c:1324
+#: ref-filter.c:1401
 #, c-format
 msgid "(HEAD detached at %s)"
 msgstr "(HEAD frånkopplat vid %s)"
@@ -2785,147 +3081,147 @@ msgstr "(HEAD frånkopplat vid %s)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached from " in wt-status.c
 #.
-#: ref-filter.c:1331
+#: ref-filter.c:1408
 #, c-format
 msgid "(HEAD detached from %s)"
 msgstr "(HEAD frånkopplat från %s)"
 
-#: ref-filter.c:1335
+#: ref-filter.c:1412
 msgid "(no branch)"
 msgstr "(ingen gren)"
 
-#: ref-filter.c:1364
+#: ref-filter.c:1442
 #, c-format
 msgid "missing object %s for %s"
 msgstr "objektet %s saknas för %s"
 
-#: ref-filter.c:1367
+#: ref-filter.c:1445
 #, c-format
 msgid "parse_object_buffer failed on %s for %s"
 msgstr "parse_object_buffer misslyckades på %s för %s"
 
-#: ref-filter.c:1819
+#: ref-filter.c:1902
 #, c-format
 msgid "malformed object at '%s'"
 msgstr "felformat objekt vid \"%s\""
 
-#: ref-filter.c:1886
+#: ref-filter.c:1984
 #, c-format
 msgid "ignoring ref with broken name %s"
 msgstr "ignorerar referens med trasigt namn %s"
 
-#: ref-filter.c:1891
+#: ref-filter.c:1989
 #, c-format
 msgid "ignoring broken ref %s"
 msgstr "ignorerar trasig referens %s"
 
-#: ref-filter.c:2152
+#: ref-filter.c:2261
 #, c-format
 msgid "format: %%(end) atom missing"
 msgstr "format: atomen %%(end) saknas"
 
-#: ref-filter.c:2246
+#: ref-filter.c:2365
 #, c-format
 msgid "malformed object name %s"
 msgstr "felformat objektnamn %s"
 
-#: remote.c:795
+#: remote.c:605
 #, c-format
 msgid "Cannot fetch both %s and %s to %s"
 msgstr "Kan inte hämta både %s och %s till %s"
 
-#: remote.c:799
+#: remote.c:609
 #, c-format
 msgid "%s usually tracks %s, not %s"
 msgstr "%s spårar vanligtvis %s, inte %s"
 
-#: remote.c:803
+#: remote.c:613
 #, c-format
 msgid "%s tracks both %s and %s"
 msgstr "%s spårar både %s och %s"
 
-#: remote.c:811
+#: remote.c:621
 msgid "Internal error"
 msgstr "Internt fel"
 
-#: remote.c:1726 remote.c:1828
+#: remote.c:1534 remote.c:1635
 msgid "HEAD does not point to a branch"
 msgstr "HEAD pekar inte på en gren"
 
-#: remote.c:1735
+#: remote.c:1543
 #, c-format
 msgid "no such branch: '%s'"
 msgstr "okänd gren: \"%s\""
 
-#: remote.c:1738
+#: remote.c:1546
 #, c-format
 msgid "no upstream configured for branch '%s'"
 msgstr "ingen standarduppström angiven för grenen \"%s\""
 
-#: remote.c:1744
+#: remote.c:1552
 #, c-format
 msgid "upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "uppströmsgrenen \"%s\" är inte lagrad som en fjärrspårande gren"
 
-#: remote.c:1759
+#: remote.c:1567
 #, c-format
 msgid "push destination '%s' on remote '%s' has no local tracking branch"
 msgstr "push-målet \"%s\" på fjärren \"%s\" har ingen lokalt spårande gren"
 
-#: remote.c:1771
+#: remote.c:1579
 #, c-format
 msgid "branch '%s' has no remote for pushing"
 msgstr "grenen \"%s\" har ingen fjärr för \"push\""
 
-#: remote.c:1782
+#: remote.c:1589
 #, c-format
 msgid "push refspecs for '%s' do not include '%s'"
 msgstr "\"push\"-referensspecifikation för \"%s\" innehåller inte \"%s\""
 
-#: remote.c:1795
+#: remote.c:1602
 msgid "push has no destination (push.default is 'nothing')"
 msgstr "\"push\" har inget mål (push.default är \"ingenting\")"
 
-#: remote.c:1817
+#: remote.c:1624
 msgid "cannot resolve 'simple' push to a single destination"
 msgstr "\"enkel push\" motsvarar flera olika mål"
 
-#: remote.c:2132
+#: remote.c:1939
 #, c-format
 msgid "Your branch is based on '%s', but the upstream is gone.\n"
 msgstr "Din gren är baserad på \"%s\", men den har försvunnit uppströms.\n"
 
-#: remote.c:2136
+#: remote.c:1943
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
 msgstr "  (använd \"git branch --unset-upstream\" för att rätta)\n"
 
-#: remote.c:2139
+#: remote.c:1946
 #, c-format
 msgid "Your branch is up to date with '%s'.\n"
 msgstr "Din gren är à jour med \"%s\".\n"
 
-#: remote.c:2143
+#: remote.c:1950
 #, c-format
 msgid "Your branch and '%s' refer to different commits.\n"
 msgstr "Din gren och \"%s\" pekar på olika incheckningar.\n"
 
-#: remote.c:2146
+#: remote.c:1953
 #, c-format
 msgid "  (use \"%s\" for details)\n"
 msgstr "  (använd \"%s\" för detaljer)\n"
 
-#: remote.c:2150
+#: remote.c:1957
 #, 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] "Din gren ligger före \"%s\" med %d incheckning.\n"
 msgstr[1] "Din gren ligger före \"%s\" med %d incheckningar.\n"
 
-#: remote.c:2156
+#: remote.c:1963
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (använd \"git push\" för att publicera dina lokala incheckningar)\n"
 
-#: remote.c:2159
+#: remote.c:1966
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -2935,11 +3231,11 @@ msgstr[0] ""
 msgstr[1] ""
 "Din gren ligger efter \"%s\" med %d incheckningar, och kan snabbspolas.\n"
 
-#: remote.c:2167
+#: remote.c:1974
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (använd \"git pull\" för att uppdatera din lokala gren)\n"
 
-#: remote.c:2170
+#: remote.c:1977
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -2954,28 +3250,28 @@ msgstr[1] ""
 "Din gren och \"%s\" har divergerat,\n"
 "och har %d respektive %d olika incheckningar.\n"
 
-#: remote.c:2180
+#: remote.c:1987
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr "  (använd \"git pull\" för att slå ihop fjärrgrenen med din egen)\n"
 
-#: revision.c:2277
+#: revision.c:2289
 msgid "your current branch appears to be broken"
 msgstr "din nuvarande gren verkar vara trasig"
 
-#: revision.c:2280
+#: revision.c:2292
 #, c-format
 msgid "your current branch '%s' does not have any commits yet"
 msgstr "din nuvarande gren \"%s\" innehåller ännu inte några incheckningar"
 
-#: revision.c:2477
+#: revision.c:2489
 msgid "--first-parent is incompatible with --bisect"
 msgstr "--first-parent är inkompatibelt med --bisect"
 
-#: run-command.c:731
+#: run-command.c:728
 msgid "open /dev/null failed"
 msgstr "misslyckades öppna /dev/null"
 
-#: run-command.c:1274
+#: run-command.c:1271
 #, c-format
 msgid ""
 "The '%s' hook was ignored because it's not set as executable.\n"
@@ -3022,29 +3318,34 @@ msgstr "mottagarsidan stöder inte push med --atomic"
 msgid "the receiving end does not support push options"
 msgstr "mottagarsidan stöder inte push-flaggor"
 
-#: sequencer.c:158
+#: sequencer.c:175
 #, c-format
 msgid "invalid commit message cleanup mode '%s'"
 msgstr "felaktigt incheckningsmeddelandestädningsläge \"%s\""
 
-#: sequencer.c:267
+#: sequencer.c:275
+#, c-format
+msgid "could not delete '%s'"
+msgstr "kunde inte ta bort \"%s\""
+
+#: sequencer.c:301
 msgid "revert"
 msgstr "revert"
 
-#: sequencer.c:269
+#: sequencer.c:303
 msgid "cherry-pick"
 msgstr "cherry-pick"
 
-#: sequencer.c:271
+#: sequencer.c:305
 msgid "rebase -i"
 msgstr "rebase -i"
 
-#: sequencer.c:273
+#: sequencer.c:307
 #, c-format
 msgid "Unknown action: %d"
 msgstr "Okänd funktion: %d"
 
-#: sequencer.c:330
+#: sequencer.c:364
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
@@ -3052,7 +3353,7 @@ msgstr ""
 "efter att ha löst konflikterna, markera de rättade sökvägarna\n"
 "med \"git add <sökvägar>\" eller \"git rm <sökvägar>\""
 
-#: sequencer.c:333
+#: sequencer.c:367
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'\n"
@@ -3062,43 +3363,45 @@ msgstr ""
 "med \"git add <sökvägar>\" eller \"git rm <sökvägar>\"\n"
 "och checka in resultatet med \"git commit\""
 
-#: sequencer.c:346 sequencer.c:2245
+#: sequencer.c:380 sequencer.c:2468
 #, c-format
 msgid "could not lock '%s'"
 msgstr "kunde inte låsa \"%s\""
 
-#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264
-#: sequencer.c:3246 sequencer.c:3310 wrapper.c:656
+#: sequencer.c:382 sequencer.c:2346 sequencer.c:2472 sequencer.c:2486
+#: sequencer.c:2694 sequencer.c:4336 sequencer.c:4399 wrapper.c:656
 #, c-format
 msgid "could not write to '%s'"
 msgstr "kunde inte skriva till \"%s\""
 
-#: sequencer.c:353
+#: sequencer.c:387
 #, c-format
 msgid "could not write eol to '%s'"
 msgstr "kunde inte skriva radslut till \"%s\""
 
-#: sequencer.c:356 sequencer.c:2128 sequencer.c:2252
+#: sequencer.c:392 sequencer.c:2351 sequencer.c:2474 sequencer.c:2488
+#: sequencer.c:2702
 #, c-format
 msgid "failed to finalize '%s'"
 msgstr "misslyckades färdigställa \"%s\""
 
-#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259
-#: builtin/commit.c:722 builtin/merge.c:1047
+#: sequencer.c:415 sequencer.c:804 sequencer.c:1493 sequencer.c:2371
+#: sequencer.c:2684 sequencer.c:2788 builtin/am.c:259 builtin/commit.c:727
+#: builtin/merge.c:1046
 #, c-format
 msgid "could not read '%s'"
 msgstr "kunde inte läsa \"%s\""
 
-#: sequencer.c:405
+#: sequencer.c:441
 #, c-format
 msgid "your local changes would be overwritten by %s."
 msgstr "dina lokala ändringar skulle skrivas över av %s."
 
-#: sequencer.c:409
+#: sequencer.c:445
 msgid "commit your changes or stash them to proceed."
 msgstr "checka in dina ändringar eller använd \"stash\" för att fortsätta."
 
-#: sequencer.c:438
+#: sequencer.c:474
 #, c-format
 msgid "%s: fast-forward"
 msgstr "%s: snabbspola"
@@ -3106,20 +3409,20 @@ msgstr "%s: snabbspola"
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase -i".
 #.
-#: sequencer.c:526
+#: sequencer.c:563
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s: Kunde inte skriva ny indexfil"
 
-#: sequencer.c:542
-msgid "could not resolve HEAD commit"
-msgstr "kunde inte bestämma HEAD:s incheckning"
-
-#: sequencer.c:562
+#: sequencer.c:579
 msgid "unable to update cache tree"
 msgstr "kan inte uppdatera cacheträd"
 
-#: sequencer.c:658
+#: sequencer.c:592
+msgid "could not resolve HEAD commit"
+msgstr "kunde inte bestämma HEAD:s incheckning"
+
+#: sequencer.c:749
 #, c-format
 msgid ""
 "you have staged changes in your working tree\n"
@@ -3148,11 +3451,15 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: sequencer.c:915
+#: sequencer.c:818
+msgid "writing root commit"
+msgstr "skriver rotincheckning"
+
+#: sequencer.c:1043
 msgid "'prepare-commit-msg' hook failed"
 msgstr "kroken \"prepare-commit-msg\" misslyckades"
 
-#: sequencer.c:922
+#: sequencer.c:1050
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3179,7 +3486,7 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:935
+#: sequencer.c:1063
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3204,329 +3511,315 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:975
+#: sequencer.c:1103
 msgid "couldn't look up newly created commit"
 msgstr "kunde inte slå upp en precis skapad incheckning"
 
-#: sequencer.c:977
+#: sequencer.c:1105
 msgid "could not parse newly created commit"
 msgstr "kunde inte tolka en precis skapad incheckning"
 
-#: sequencer.c:1023
+#: sequencer.c:1151
 msgid "unable to resolve HEAD after creating commit"
 msgstr "kunde inte bestämma HEAD efter att ha skapat incheckning"
 
-#: sequencer.c:1025
+#: sequencer.c:1153
 msgid "detached HEAD"
 msgstr "frånkopplad HEAD"
 
-#: sequencer.c:1029
+#: sequencer.c:1157
 msgid " (root-commit)"
 msgstr " (rotincheckning)"
 
-#: sequencer.c:1050
+#: sequencer.c:1178
 msgid "could not parse HEAD"
 msgstr "kunde inte tolka HEAD"
 
-#: sequencer.c:1052
+#: sequencer.c:1180
 #, c-format
 msgid "HEAD %s is not a commit!"
 msgstr "HEAD %s är inte en incheckning!"
 
-#: sequencer.c:1056 builtin/commit.c:1491
+#: sequencer.c:1184 builtin/commit.c:1528
 msgid "could not parse HEAD commit"
 msgstr "kunde inte tolka HEAD:s incheckning"
 
-#: sequencer.c:1107 sequencer.c:1673
+#: sequencer.c:1235 sequencer.c:1832
 msgid "unable to parse commit author"
 msgstr "kunde inte tolka incheckningens författare"
 
-#: sequencer.c:1117 builtin/am.c:1630 builtin/merge.c:643
+#: sequencer.c:1245 builtin/am.c:1630 builtin/merge.c:645
 msgid "git write-tree failed to write a tree"
 msgstr "git write-tree misslyckades skriva ett träd"
 
-#: sequencer.c:1134 sequencer.c:1186
+#: sequencer.c:1262 sequencer.c:1317
 #, c-format
 msgid "unable to read commit message from '%s'"
 msgstr "kunde inte läsa incheckningsmeddelande från \"%s\""
 
-#: sequencer.c:1154 builtin/am.c:1650 builtin/commit.c:1594 builtin/merge.c:826
-#: builtin/merge.c:851
+#: sequencer.c:1284 builtin/am.c:1650 builtin/commit.c:1631 builtin/merge.c:825
+#: builtin/merge.c:850
 msgid "failed to write commit object"
 msgstr "kunde inte skriva incheckningsobjekt"
 
-#: sequencer.c:1213
+#: sequencer.c:1344
 #, c-format
 msgid "could not parse commit %s"
 msgstr "kunde inte tolka incheckningen %s"
 
-#: sequencer.c:1218
+#: sequencer.c:1349
 #, c-format
 msgid "could not parse parent commit %s"
 msgstr "kunde inte tolka föräldraincheckningen %s"
 
-#: sequencer.c:1347
-#, c-format
-msgid ""
-"unexpected 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"oväntad första rad i squash-meddelande:\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1353
-#, c-format
-msgid ""
-"invalid 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"ogiltig första rad i squash-meddelande:\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1359 sequencer.c:1384
+#: sequencer.c:1500 sequencer.c:1525
 #, c-format
 msgid "This is a combination of %d commits."
 msgstr "Det här är en kombination av %d incheckningar."
 
-#: sequencer.c:1368 sequencer.c:3265
+#: sequencer.c:1510 sequencer.c:4355
 msgid "need a HEAD to fixup"
 msgstr "behöver en HEAD-incheckning att rätta"
 
-#: sequencer.c:1370
+#: sequencer.c:1512 sequencer.c:2729
 msgid "could not read HEAD"
 msgstr "kunde inte läsa HEAD"
 
-#: sequencer.c:1372
+#: sequencer.c:1514
 msgid "could not read HEAD's commit message"
 msgstr "kunde inte läsa HEAD:s incheckningsmeddelande"
 
-#: sequencer.c:1378
+#: sequencer.c:1520
 #, c-format
 msgid "cannot write '%s'"
 msgstr "kan inte skriva \"%s\""
 
-#: sequencer.c:1387 git-rebase--interactive.sh:452
+#: sequencer.c:1527 git-rebase--interactive.sh:457
 msgid "This is the 1st commit message:"
 msgstr "Det här är 1:a incheckningsmeddelandet:"
 
-#: sequencer.c:1395
+#: sequencer.c:1535
 #, c-format
 msgid "could not read commit message of %s"
 msgstr "kunde inte läsa incheckningsmeddelande för %s"
 
-#: sequencer.c:1402
+#: sequencer.c:1542
 #, c-format
 msgid "This is the commit message #%d:"
 msgstr "Det här är incheckningsmeddelande %d:"
 
-#: sequencer.c:1407
+#: sequencer.c:1548
 #, c-format
 msgid "The commit message #%d will be skipped:"
 msgstr "Incheckningsmeddelande %d kommer hoppas över:"
 
-#: sequencer.c:1412
+#: sequencer.c:1553
 #, c-format
 msgid "unknown command: %d"
 msgstr "okänt kommando: %d"
 
-#: sequencer.c:1479
+#: sequencer.c:1631
 msgid "your index file is unmerged."
 msgstr "din indexfil har inte slagits ihop."
 
-#: sequencer.c:1498
+#: sequencer.c:1638
+msgid "cannot fixup root commit"
+msgstr "kan inte göra \"fixup\" på rotincheckning"
+
+#: sequencer.c:1657
 #, c-format
 msgid "commit %s is a merge but no -m option was given."
 msgstr "incheckning %s är en sammanslagning, men flaggan -m angavs inte."
 
-#: sequencer.c:1506
+#: sequencer.c:1665
 #, c-format
 msgid "commit %s does not have parent %d"
 msgstr "incheckning %s har inte förälder %d"
 
-#: sequencer.c:1510
+#: sequencer.c:1669
 #, c-format
 msgid "mainline was specified but commit %s is not a merge."
 msgstr "huvudlinje angavs, men incheckningen %s är inte en sammanslagning."
 
-#: sequencer.c:1516
+#: sequencer.c:1675
 #, c-format
 msgid "cannot get commit message for %s"
 msgstr "kan inte hämta incheckningsmeddelande för %s"
 
 #. TRANSLATORS: The first %s will be a "todo" command like
 #. "revert" or "pick", the second %s a SHA1.
-#: sequencer.c:1535
+#: sequencer.c:1694
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s: kan inte tolka föräldraincheckningen %s"
 
-#: sequencer.c:1600 sequencer.c:2397
+#: sequencer.c:1759
 #, c-format
 msgid "could not rename '%s' to '%s'"
 msgstr "kunde inte byta namn på \"%s\" till \"%s\""
 
-#: sequencer.c:1654
+#: sequencer.c:1813
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "kunde inte ångra %s... %s"
 
-#: sequencer.c:1655
+#: sequencer.c:1814
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "kunde inte tillämpa %s... %s"
 
-#: sequencer.c:1702
+#: sequencer.c:1864
 msgid "empty commit set passed"
 msgstr "den angivna uppsättningen incheckningar är tom"
 
-#: sequencer.c:1712
+#: sequencer.c:1874
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s: misslyckades läsa indexet"
 
-#: sequencer.c:1718
+#: sequencer.c:1881
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr "git %s: misslyckades uppdatera indexet"
 
-#: sequencer.c:1792
+#: sequencer.c:1961
 #, c-format
 msgid "%s does not accept arguments: '%s'"
 msgstr "%s tar inte argument: \"%s\""
 
-#: sequencer.c:1801
+#: sequencer.c:1970
 #, c-format
 msgid "missing arguments for %s"
 msgstr "argument saknas för %s"
 
-#: sequencer.c:1844
+#: sequencer.c:2029
 #, c-format
 msgid "invalid line %d: %.*s"
 msgstr "ogiltig rad %d: %.*s"
 
-#: sequencer.c:1852
+#: sequencer.c:2037
 #, c-format
 msgid "cannot '%s' without a previous commit"
 msgstr "kan inte utföra \"%s\" utan en föregående incheckning"
 
-#: sequencer.c:1883 sequencer.c:3056 sequencer.c:3091
+#: sequencer.c:2085 sequencer.c:4138 sequencer.c:4173
 #, c-format
 msgid "could not read '%s'."
 msgstr "kunde inte läsa \"%s\"."
 
-#: sequencer.c:1906
+#: sequencer.c:2108
 msgid "please fix this using 'git rebase --edit-todo'."
 msgstr "rätta det med \"git rebase --edit-todo\"."
 
-#: sequencer.c:1908
+#: sequencer.c:2110
 #, c-format
 msgid "unusable instruction sheet: '%s'"
 msgstr "oanvändbart manus: ”%s”"
 
-#: sequencer.c:1913
+#: sequencer.c:2115
 msgid "no commits parsed."
 msgstr "inga incheckningar lästes."
 
-#: sequencer.c:1924
+#: sequencer.c:2126
 msgid "cannot cherry-pick during a revert."
 msgstr "kan inte utföra \"cherry-pick\" under en \"revert\"."
 
-#: sequencer.c:1926
+#: sequencer.c:2128
 msgid "cannot revert during a cherry-pick."
 msgstr "kan inte utföra \"revert\" under en \"cherry-pick\"."
 
-#: sequencer.c:1993
+#: sequencer.c:2195
 #, c-format
 msgid "invalid key: %s"
 msgstr "felaktig nyckel: %s"
 
-#: sequencer.c:1996
+#: sequencer.c:2198
 #, c-format
 msgid "invalid value for %s: %s"
 msgstr "felaktigt värde för %s: %s"
 
-#: sequencer.c:2062
+#: sequencer.c:2269
+msgid "unusable squash-onto"
+msgstr "oanvändbar squash-onto"
+
+#: sequencer.c:2285
 #, c-format
 msgid "malformed options sheet: '%s'"
 msgstr "trasigt manus: ”%s”"
 
-#: sequencer.c:2100
+#: sequencer.c:2323
 msgid "a cherry-pick or revert is already in progress"
 msgstr "en \"cherry-pick\" eller \"revert\" pågår redan"
 
-#: sequencer.c:2101
+#: sequencer.c:2324
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "testa \"git cherry-pick (--continue | --quit | --abort)\""
 
-#: sequencer.c:2104
+#: sequencer.c:2327
 #, c-format
 msgid "could not create sequencer directory '%s'"
 msgstr "kunde inte skapa \"sequencer\"-katalogen \"%s\""
 
-#: sequencer.c:2118
+#: sequencer.c:2341
 msgid "could not lock HEAD"
 msgstr "kunde inte låsa HEAD"
 
-#: sequencer.c:2173 sequencer.c:2761
+#: sequencer.c:2396 sequencer.c:3403
 msgid "no cherry-pick or revert in progress"
 msgstr "ingen \"cherry-pick\" eller \"revert\" pågår"
 
-#: sequencer.c:2175
+#: sequencer.c:2398
 msgid "cannot resolve HEAD"
 msgstr "kan inte bestämma HEAD"
 
-#: sequencer.c:2177 sequencer.c:2212
+#: sequencer.c:2400 sequencer.c:2435
 msgid "cannot abort from a branch yet to be born"
 msgstr "kan inte avbryta från en gren som ännu inte är född"
 
-#: sequencer.c:2198 builtin/grep.c:720
+#: sequencer.c:2421 builtin/grep.c:720
 #, c-format
 msgid "cannot open '%s'"
 msgstr "kan inte öppna \"%s\""
 
-#: sequencer.c:2200
+#: sequencer.c:2423
 #, c-format
 msgid "cannot read '%s': %s"
 msgstr "kan inte läsa \"%s\": %s"
 
-#: sequencer.c:2201
+#: sequencer.c:2424
 msgid "unexpected end of file"
 msgstr "oväntat filslut"
 
-#: sequencer.c:2207
+#: sequencer.c:2430
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr "sparad HEAD-fil från före \"cherry-pick\", \"%s\", är trasig"
 
-#: sequencer.c:2218
+#: sequencer.c:2441
 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
 msgstr ""
 "Du verkar ha flyttat HEAD.\n"
 "Spolar inte tillbaka, kontrollera HEAD!"
 
-#: sequencer.c:2324 sequencer.c:2679
+#: sequencer.c:2545 sequencer.c:3321
 #, c-format
 msgid "could not update %s"
 msgstr "kunde inte uppdatera %s"
 
-#: sequencer.c:2362 sequencer.c:2659
+#: sequencer.c:2583 sequencer.c:3301
 msgid "cannot read HEAD"
 msgstr "kan inte läsa HEAD"
 
-#: sequencer.c:2402 builtin/difftool.c:639
+#: sequencer.c:2618 sequencer.c:2622 builtin/difftool.c:639
 #, c-format
 msgid "could not copy '%s' to '%s'"
 msgstr "kunde inte kopiera in \"%s\" till \"%s\""
 
-#: sequencer.c:2421
+#: sequencer.c:2641
 msgid "could not read index"
 msgstr "kunde inte läsa indexet"
 
-#: sequencer.c:2426
+#: sequencer.c:2646
 #, c-format
 msgid ""
 "execution failed: %s\n"
@@ -3541,11 +3834,11 @@ msgstr ""
 "\tgit rebase --continue\n"
 "\n"
 
-#: sequencer.c:2432
+#: sequencer.c:2652
 msgid "and made changes to the index and/or the working tree\n"
 msgstr "och gjorde ändringar till indexet och/eller arbetskatalogen\n"
 
-#: sequencer.c:2438
+#: sequencer.c:2658
 #, c-format
 msgid ""
 "execution succeeded: %s\n"
@@ -3562,17 +3855,62 @@ msgstr ""
 "\tgit rebase --continue\n"
 "\n"
 
-#: sequencer.c:2497
+#: sequencer.c:2771
+msgid "writing fake root commit"
+msgstr "skriver fejkad rotincheckning"
+
+#: sequencer.c:2776
+msgid "writing squash-onto"
+msgstr "skriver squash-onto"
+
+#: sequencer.c:2811
+#, c-format
+msgid "failed to find tree of %s"
+msgstr "kunde inte hitta trädet för %s."
+
+#: sequencer.c:2829
+msgid "could not write index"
+msgstr "kunde inte skriva indexet"
+
+#: sequencer.c:2861
+msgid "cannot merge without a current revision"
+msgstr "kan inte slå ihop utan en aktuell incheckning"
+
+#: sequencer.c:2884
+#, c-format
+msgid "could not resolve '%s'"
+msgstr "kunde inte upplösa \"%s\""
+
+#: sequencer.c:2906
+#, c-format
+msgid "could not get commit message of '%s'"
+msgstr "kunde inte läsa incheckningsmeddelande för \"%s\""
+
+#: sequencer.c:2916 sequencer.c:2941
+#, c-format
+msgid "could not write '%s'"
+msgstr "kunde inte skriva \"%s\""
+
+#: sequencer.c:3005
+#, c-format
+msgid "could not even attempt to merge '%.*s'"
+msgstr "kunde inte ens försöka slå ihop \"%.*s\""
+
+#: sequencer.c:3021
+msgid "merge: Unable to write new index file"
+msgstr "sammanslagning: Kunde inte skriva ny indexfil"
+
+#: sequencer.c:3088
 #, c-format
 msgid "Applied autostash.\n"
 msgstr "Tillämpade autostash.\n"
 
-#: sequencer.c:2509
+#: sequencer.c:3100
 #, c-format
 msgid "cannot store %s"
 msgstr "kan inte spara %s"
 
-#: sequencer.c:2512 git-rebase.sh:178
+#: sequencer.c:3103 git-rebase.sh:188
 #, c-format
 msgid ""
 "Applying autostash resulted in conflicts.\n"
@@ -3583,52 +3921,69 @@ msgstr ""
 "Dina ändringar är säkra i stashen.\n"
 "Du kan när som helst använda \"git stash pop\" eller \"git stash drop\".\n"
 
-#: sequencer.c:2595
+#: sequencer.c:3134
+#, c-format
+msgid ""
+"Could not execute the todo command\n"
+"\n"
+"    %.*s\n"
+"It has been rescheduled; To edit the command before continuing, please\n"
+"edit the todo list first:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+msgstr ""
+"Kunde inte köra todo-kommandot\n"
+"\n"
+"    %.*s\n"
+"Det har lagts tillbaka i kön; För att redigera kommandot innan du\n"
+"fortsätter, redigera först attgöra-listan:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+
+#: sequencer.c:3202
 #, c-format
 msgid "Stopped at %s...  %.*s\n"
 msgstr "Stoppade på %s... %.*s\n"
 
-#: sequencer.c:2637
+#: sequencer.c:3264
 #, c-format
 msgid "unknown command %d"
 msgstr "okänt kommando %d"
 
-#: sequencer.c:2667
+#: sequencer.c:3309
 msgid "could not read orig-head"
 msgstr "kunde inte läsa orig-head"
 
-#: sequencer.c:2672 sequencer.c:3262
+#: sequencer.c:3314 sequencer.c:4352
 msgid "could not read 'onto'"
 msgstr "kunde inte läsa \"onto\""
 
-#: sequencer.c:2686
+#: sequencer.c:3328
 #, c-format
 msgid "could not update HEAD to %s"
 msgstr "kunde inte uppdatera HEAD till %s"
 
-#: sequencer.c:2770
+#: sequencer.c:3414
 msgid "cannot rebase: You have unstaged changes."
 msgstr "kan inte ombasera: Du har oköade ändringar."
 
-#: sequencer.c:2775
-msgid "could not remove CHERRY_PICK_HEAD"
-msgstr "kunde inte ta bort CHERRY_PICK_HEAD"
-
-#: sequencer.c:2784
+#: sequencer.c:3423
 msgid "cannot amend non-existing commit"
 msgstr "kan inte lägga till incheckning som inte finns"
 
-#: sequencer.c:2786
+#: sequencer.c:3425
 #, c-format
 msgid "invalid file: '%s'"
 msgstr "ogiltig fil: \"%s\""
 
-#: sequencer.c:2788
+#: sequencer.c:3427
 #, c-format
 msgid "invalid contents: '%s'"
 msgstr "ogiltigt innehåll: \"%s\""
 
-#: sequencer.c:2791
+#: sequencer.c:3430
 msgid ""
 "\n"
 "You have uncommitted changes in your working tree. Please, commit them\n"
@@ -3638,45 +3993,54 @@ msgstr ""
 "Du har ändringar i arbetskatalogen som inte checkats in. Checka in dem\n"
 "först och kör sedan \"git rebase --continute\" igen."
 
-#: sequencer.c:2801
+#: sequencer.c:3455 sequencer.c:3493
+#, c-format
+msgid "could not write file: '%s'"
+msgstr "kunde inte skriva fil: \"%s\""
+
+#: sequencer.c:3508
+msgid "could not remove CHERRY_PICK_HEAD"
+msgstr "kunde inte ta bort CHERRY_PICK_HEAD"
+
+#: sequencer.c:3515
 msgid "could not commit staged changes."
 msgstr "kunde inte checka in köade ändringar."
 
-#: sequencer.c:2881
+#: sequencer.c:3612
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s: kan inte göra \"cherry-pick\" på typen ”%s”"
 
-#: sequencer.c:2885
+#: sequencer.c:3616
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s: felaktig revision"
 
-#: sequencer.c:2918
+#: sequencer.c:3649
 msgid "can't revert as initial commit"
 msgstr "kan inte ångra som första incheckning"
 
-#: sequencer.c:3023
+#: sequencer.c:4098
 msgid "make_script: unhandled options"
 msgstr "make_script: flaggor som inte stöds"
 
-#: sequencer.c:3026
+#: sequencer.c:4101
 msgid "make_script: error preparing revisions"
 msgstr "make_script: fel när revisioner skulle förberedas"
 
-#: sequencer.c:3060 sequencer.c:3095
+#: sequencer.c:4142 sequencer.c:4177
 #, c-format
 msgid "unusable todo list: '%s'"
 msgstr "oanvändbar todo-lista: %s"
 
-#: sequencer.c:3146
+#: sequencer.c:4236
 #, c-format
 msgid ""
 "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
 msgstr ""
 "okänd inställning %s för flaggan rebase.missingCommitsCheck. Ignorerar."
 
-#: sequencer.c:3212
+#: sequencer.c:4302
 #, c-format
 msgid ""
 "Warning: some commits may have been dropped accidentally.\n"
@@ -3685,7 +4049,7 @@ msgstr ""
 "Varning: vissa incheckningar kan av misstag ha tappats.\n"
 "Tappade incheckningar (nyaste först):\n"
 
-#: sequencer.c:3219
+#: sequencer.c:4309
 #, c-format
 msgid ""
 "To avoid this message, use \"drop\" to explicitly remove a commit.\n"
@@ -3705,7 +4069,7 @@ msgstr ""
 "\" (fel).\n"
 "\n"
 
-#: sequencer.c:3231
+#: sequencer.c:4321
 #, c-format
 msgid ""
 "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
@@ -3716,27 +4080,21 @@ msgstr ""
 "continue\".\n"
 "Avbryt ombaseringen med \"git rebase --abort\".\n"
 
-#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395
-#: builtin/am.c:779
-#, c-format
-msgid "could not open '%s' for writing"
-msgstr "kunde inte öppna \"%s\" för skrivning"
-
-#: sequencer.c:3285
+#: sequencer.c:4375
 #, c-format
 msgid "could not parse commit '%s'"
 msgstr "kunde inte tolka incheckningen\" %s\""
 
-#: sequencer.c:3401
+#: sequencer.c:4490
 msgid "the script was already rearranged."
 msgstr "skriptet har redan omordnats."
 
-#: setup.c:122
+#: setup.c:123
 #, c-format
 msgid "'%s' is outside repository"
 msgstr "\"%s\" är utanför arkivet"
 
-#: setup.c:171
+#: setup.c:172
 #, c-format
 msgid ""
 "%s: no such path in the working tree.\n"
@@ -3746,7 +4104,7 @@ msgstr ""
 "Använd \"git <kommando> -- <sökväg>..\" för att ange sökvägar som inte finns "
 "lokalt."
 
-#: setup.c:184
+#: setup.c:185
 #, c-format
 msgid ""
 "ambiguous argument '%s': unknown revision or path not in the working tree.\n"
@@ -3758,12 +4116,12 @@ msgstr ""
 "Använd \"--\" för att skilja sökvägar från revisioner, så här:\n"
 "\"git <kommando> [<revision>...] -- [<fil>...]\""
 
-#: setup.c:233
+#: setup.c:234
 #, c-format
 msgid "option '%s' must come before non-option arguments"
 msgstr "flaggan \"%s\" måste anges före argument som inte är flaggor"
 
-#: setup.c:252
+#: setup.c:253
 #, c-format
 msgid ""
 "ambiguous argument '%s': both revision and filename\n"
@@ -3774,92 +4132,92 @@ msgstr ""
 "Använd \"--\" för att skilja sökvägar från revisioner, så här:\n"
 "\"git <kommando> [<revision>...] -- [<fil>...]\""
 
-#: setup.c:388
+#: setup.c:389
 msgid "unable to set up work tree using invalid config"
 msgstr "kan inte skapa arbetskatalog med felaktig konfiguration"
 
-#: setup.c:395
+#: setup.c:393
 msgid "this operation must be run in a work tree"
 msgstr "funktionen måste köras i en arbetskatalog"
 
-#: setup.c:506
+#: setup.c:503
 #, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "Förväntade git-arkivversion <= %d, hittade %d"
 
-#: setup.c:514
+#: setup.c:511
 msgid "unknown repository extensions found:"
 msgstr "okända arkivutökningar hittades:"
 
-#: setup.c:533
+#: setup.c:530
 #, c-format
 msgid "error opening '%s'"
 msgstr "fel vid öppning av \"%s\""
 
-#: setup.c:535
+#: setup.c:532
 #, c-format
 msgid "too large to be a .git file: '%s'"
 msgstr "för stor för att vara en .git-fil: \"%s\""
 
-#: setup.c:537
+#: setup.c:534
 #, c-format
 msgid "error reading %s"
 msgstr "fel vid läsning av %s"
 
-#: setup.c:539
+#: setup.c:536
 #, c-format
 msgid "invalid gitfile format: %s"
 msgstr "ogiltigt gitfilformat: %s"
 
-#: setup.c:541
+#: setup.c:538
 #, c-format
 msgid "no path in gitfile: %s"
 msgstr "ingen sökväg i gitfil: %s"
 
-#: setup.c:543
+#: setup.c:540
 #, c-format
 msgid "not a git repository: %s"
 msgstr "inte ett git-arkiv: %s"
 
-#: setup.c:642
+#: setup.c:639
 #, c-format
 msgid "'$%s' too big"
 msgstr "\"$%s\" för stor"
 
-#: setup.c:656
+#: setup.c:653
 #, c-format
 msgid "not a git repository: '%s'"
 msgstr "inte ett git-arkiv: \"%s\""
 
-#: setup.c:685 setup.c:687 setup.c:718
+#: setup.c:682 setup.c:684 setup.c:715
 #, c-format
 msgid "cannot chdir to '%s'"
 msgstr "kan inte byta katalog (chdir) till \"%s\""
 
-#: setup.c:690 setup.c:746 setup.c:756 setup.c:795 setup.c:803 setup.c:818
+#: setup.c:687 setup.c:743 setup.c:753 setup.c:792 setup.c:800 setup.c:815
 msgid "cannot come back to cwd"
 msgstr "kan inte gå tillbaka till arbetskatalogen (cwd)"
 
-#: setup.c:816
+#: setup.c:813
 #, c-format
 msgid "not a git repository (or any of the parent directories): %s"
 msgstr "inte ett git-arkiv (eller någon av föräldrakatalogerna): %s"
 
-#: setup.c:827
+#: setup.c:824
 #, c-format
 msgid "failed to stat '%*s%s%s'"
 msgstr "misslyckades ta status på \"%*ss%s%s\""
 
-#: setup.c:1057
+#: setup.c:1054
 msgid "Unable to read current working directory"
 msgstr "Kan inte läsa aktuell arbetskatalog"
 
-#: setup.c:1069 setup.c:1075
+#: setup.c:1066 setup.c:1072
 #, c-format
 msgid "cannot change to '%s'"
 msgstr "kan inte byta till \"%s\""
 
-#: setup.c:1088
+#: setup.c:1085
 #, c-format
 msgid ""
 "not a git repository (or any parent up to mount point %s)\n"
@@ -3869,7 +4227,7 @@ msgstr ""
 "monteringspunkten %s)\n"
 "Stoppar vid filsystemsgräns (GIT_DISCOVERY_ACROSS_FILESYSTEM är inte satt)."
 
-#: setup.c:1172
+#: setup.c:1168
 #, c-format
 msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
@@ -3878,53 +4236,53 @@ msgstr ""
 "problem med filläges-värdet i core.sharedRepository (0%.3o).\n"
 "Ägaren av filerna måste alltid ha läs- och skrivbehörighet."
 
-#: setup.c:1215
+#: setup.c:1211
 msgid "open /dev/null or dup failed"
 msgstr "misslyckades öppna /dev/null eller \"dup\""
 
-#: setup.c:1230
+#: setup.c:1226
 msgid "fork failed"
 msgstr "\"fork\" misslyckades"
 
-#: setup.c:1235
+#: setup.c:1231
 msgid "setsid failed"
 msgstr "\"setsid\" misslyckades"
 
-#: sha1_file.c:592
+#: sha1-file.c:625
 #, c-format
 msgid "path '%s' does not exist"
 msgstr "sökvägen \"%s\" finns inte"
 
-#: sha1_file.c:618
+#: sha1-file.c:651
 #, c-format
 msgid "reference repository '%s' as a linked checkout is not supported yet."
 msgstr "referensarkivet \"%s\" som en länkad utcheckning stöds inte ännu."
 
-#: sha1_file.c:624
+#: sha1-file.c:657
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "referensarkivet \"%s\" är inte ett lokalt arkiv."
 
-#: sha1_file.c:630
+#: sha1-file.c:663
 #, c-format
 msgid "reference repository '%s' is shallow"
 msgstr "referensarkivet \"%s\" är grunt"
 
-#: sha1_file.c:638
+#: sha1-file.c:671
 #, c-format
 msgid "reference repository '%s' is grafted"
 msgstr "referensarkivet \"%s\" är ympat"
 
-#: sha1_name.c:422
+#: sha1-name.c:442
 #, c-format
 msgid "short SHA1 %s is ambiguous"
 msgstr "kort SHA1 %s är tvetydig"
 
-#: sha1_name.c:433
+#: sha1-name.c:453
 msgid "The candidates are:"
 msgstr "Kandidaterna är:"
 
-#: sha1_name.c:693
+#: sha1-name.c:695
 msgid ""
 "Git normally never creates a ref that ends with 40 hex characters\n"
 "because it will be ignored when you just specify 40-hex. These refs\n"
@@ -3946,71 +4304,71 @@ msgstr ""
 "Undersök referenserna och ta kanske bort dem. Stäng av meddelandet\n"
 "genom att köra \"git config advice.objectNameWarning false\""
 
-#: submodule.c:96 submodule.c:130
+#: submodule.c:97 submodule.c:131
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr ""
 "Kan inte ändra .gitmodules-fil som inte slagits ihop, lös "
 "sammanslagningskonflikter först"
 
-#: submodule.c:100 submodule.c:134
+#: submodule.c:101 submodule.c:135
 #, c-format
 msgid "Could not find section in .gitmodules where path=%s"
 msgstr "Hittade inte någon sektion i .gitmodules där sökväg=%s"
 
-#: submodule.c:108
+#: submodule.c:109
 #, c-format
 msgid "Could not update .gitmodules entry %s"
 msgstr "Kunde inte uppdatera .gitmodules-posten %s"
 
-#: submodule.c:141
+#: submodule.c:142
 #, c-format
 msgid "Could not remove .gitmodules entry for %s"
 msgstr "Kunde inte ta bort .gitmodules-posten för %s"
 
-#: submodule.c:152
+#: submodule.c:153
 msgid "staging updated .gitmodules failed"
 msgstr "misslyckades köa uppdaterad .gitmodules"
 
-#: submodule.c:312
+#: submodule.c:315
 #, c-format
 msgid "in unpopulated submodule '%s'"
 msgstr "i ej utcheckad undermodul \"%s\""
 
-#: submodule.c:343
+#: submodule.c:346
 #, c-format
 msgid "Pathspec '%s' is in submodule '%.*s'"
 msgstr "Sökvägsangivelsen \"%s\" är i undermodulen \"%.*s\""
 
-#: submodule.c:833
+#: submodule.c:837
 #, c-format
 msgid "submodule entry '%s' (%s) is a %s, not a commit"
 msgstr "undermodulposten \"%s\" (%s) är en %s, inte en incheckning"
 
-#: submodule.c:1065 builtin/branch.c:648 builtin/submodule--helper.c:1724
+#: submodule.c:1069 builtin/branch.c:651 builtin/submodule--helper.c:1743
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "Misslyckades slå upp HEAD som giltig referens."
 
-#: submodule.c:1370
+#: submodule.c:1375
 #, c-format
 msgid "'%s' not recognized as a git repository"
 msgstr "\"%s\" känns inte igen som ett git-arkiv"
 
-#: submodule.c:1508
+#: submodule.c:1513
 #, c-format
 msgid "could not start 'git status' in submodule '%s'"
 msgstr "kunde inte starta \"git status\" i undermodulen \"%s\""
 
-#: submodule.c:1521
+#: submodule.c:1526
 #, c-format
 msgid "could not run 'git status' in submodule '%s'"
 msgstr "kunde inte köra \"git status\" i undermodulen \"%s\""
 
-#: submodule.c:1614
+#: submodule.c:1619
 #, c-format
 msgid "submodule '%s' has dirty index"
 msgstr "undermodulen \"%s\" har ett smutsigt index"
 
-#: submodule.c:1878
+#: submodule.c:1718
 #, c-format
 msgid ""
 "relocate_gitdir for submodule '%s' with more than one worktree not supported"
@@ -4018,18 +4376,18 @@ msgstr ""
 "relocate_gitdir för undermodulen \"%s\", som har mer än en arbetskatalog, "
 "stöds ej"
 
-#: submodule.c:1890 submodule.c:1946
+#: submodule.c:1730 submodule.c:1786
 #, c-format
 msgid "could not lookup name for submodule '%s'"
 msgstr "kunde inte slå upp namnet för undermodulen \"%s\""
 
-#: submodule.c:1894 builtin/submodule--helper.c:1246
-#: builtin/submodule--helper.c:1256
+#: submodule.c:1734 builtin/submodule--helper.c:1261
+#: builtin/submodule--helper.c:1271
 #, c-format
 msgid "could not create directory '%s'"
 msgstr "kunde inte skapa katalogen \"%s\""
 
-#: submodule.c:1897
+#: submodule.c:1737
 #, c-format
 msgid ""
 "Migrating git directory of '%s%s' from\n"
@@ -4040,29 +4398,30 @@ msgstr ""
 "\"%s\" till\n"
 "\"%s\"\n"
 
-#: submodule.c:1981
+#: submodule.c:1821
 #, c-format
 msgid "could not recurse into submodule '%s'"
 msgstr "kunde inte rekursera in i undermodulen \"%s\""
 
-#: submodule.c:2025
+#: submodule.c:1865
 msgid "could not start ls-files in .."
 msgstr "kunde inte starta ls-files i .."
 
-#: submodule.c:2045
-msgid "BUG: returned path string doesn't match cwd?"
-msgstr "BUG: returnerad sökvägssträng matchar inte cwd?"
-
-#: submodule.c:2064
+#: submodule.c:1904
 #, c-format
 msgid "ls-tree returned unexpected return code %d"
 msgstr "ls-tree returnerade en oväntad returkod %d"
 
-#: submodule-config.c:263
+#: submodule-config.c:230
+#, c-format
+msgid "ignoring suspicious submodule name: %s"
+msgstr "ignorerar misstänkt undermodulnamn: %s"
+
+#: submodule-config.c:294
 msgid "negative values not allowed for submodule.fetchjobs"
 msgstr "negativa värden är inte tillåtna för submodule.fetchjobs"
 
-#: submodule-config.c:436
+#: submodule-config.c:467
 #, c-format
 msgid "invalid value for %s"
 msgstr "ogiltigt värde för %s"
@@ -4078,7 +4437,7 @@ msgstr "misslyckades utföra \"trailer\"-kommandot \"%s\""
 msgid "unknown value '%s' for key '%s'"
 msgstr "okänt värde \"%s\" för nyckeln \"%s\""
 
-#: trailer.c:539 trailer.c:544 builtin/remote.c:290
+#: trailer.c:539 trailer.c:544 builtin/remote.c:293
 #, c-format
 msgid "more than one %s"
 msgstr "mer än en %s"
@@ -4121,17 +4480,21 @@ msgstr "kunde inte öppna temporär fil"
 msgid "could not rename temporary file to %s"
 msgstr "kunde inte byta namn på temporär fil till %s"
 
-#: transport.c:63
+#: transport.c:116
 #, c-format
 msgid "Would set upstream of '%s' to '%s' of '%s'\n"
 msgstr "Skulle sätta uppströms för \"%s\" till \"%s\" från \"%s\"\n"
 
-#: transport.c:152
+#: transport.c:208
 #, c-format
 msgid "transport: invalid depth option '%s'"
 msgstr "transport: ogiltig flagga för depth: ”%s”"
 
-#: transport.c:916
+#: transport.c:584
+msgid "could not parse transport.color.* config"
+msgstr "kunde inte tolka inställningen för transport.color.*"
+
+#: transport.c:996
 #, c-format
 msgid ""
 "The following submodule paths contain changes that can\n"
@@ -4140,7 +4503,7 @@ msgstr ""
 "Följande undermodulsökvägar innehåller ändringar som\n"
 "inte kan hittas av fjärrarna:\n"
 
-#: transport.c:920
+#: transport.c:1000
 #, c-format
 msgid ""
 "\n"
@@ -4167,11 +4530,11 @@ msgstr ""
 "för att sända dem till fjärren.\n"
 "\n"
 
-#: transport.c:928
+#: transport.c:1008
 msgid "Aborting."
 msgstr "Avbryter."
 
-#: transport-helper.c:1079
+#: transport-helper.c:1087
 #, c-format
 msgid "Could not read ref %s"
 msgstr "Kunde inte läsa referensen %s"
@@ -4188,11 +4551,11 @@ msgstr "felformat läge i trädpost"
 msgid "empty filename in tree entry"
 msgstr "tomt filnamn i trädpost"
 
-#: tree-walk.c:114
+#: tree-walk.c:113
 msgid "too-short tree file"
 msgstr "trädfil för kort"
 
-#: unpack-trees.c:108
+#: unpack-trees.c:111
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4201,7 +4564,7 @@ msgstr ""
 "Dina lokala ändringar av följande filer skulle skrivas över av utcheckning:\n"
 "%%sChecka in dina ändringar eller använd \"stash\" innan du byter gren."
 
-#: unpack-trees.c:110
+#: unpack-trees.c:113
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4210,7 +4573,7 @@ msgstr ""
 "Dina lokala ändringar av följande filer skulle skrivas över av utcheckning:\n"
 "%%s"
 
-#: unpack-trees.c:113
+#: unpack-trees.c:116
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4220,7 +4583,7 @@ msgstr ""
 "sammanslagning:\n"
 "%%sChecka in dina ändringar eller använd \"stash\" innan du byter gren."
 
-#: unpack-trees.c:115
+#: unpack-trees.c:118
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4230,7 +4593,7 @@ msgstr ""
 "sammanslagning:\n"
 "%%s"
 
-#: unpack-trees.c:118
+#: unpack-trees.c:121
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4239,7 +4602,7 @@ msgstr ""
 "Dina lokala ändringar av följande filer skulle skrivas över av \"%s\":\n"
 "%%sChecka in dina ändringar eller använd \"stash\" innan du \"%s\"."
 
-#: unpack-trees.c:120
+#: unpack-trees.c:123
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4248,7 +4611,7 @@ msgstr ""
 "Dina lokala ändringar av följande filer skulle skrivas över av \"%s\":\n"
 "%%s"
 
-#: unpack-trees.c:125
+#: unpack-trees.c:128
 #, c-format
 msgid ""
 "Updating the following directories would lose untracked files in them:\n"
@@ -4258,7 +4621,7 @@ msgstr ""
 "dem:\n"
 "%s"
 
-#: unpack-trees.c:129
+#: unpack-trees.c:132
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4267,7 +4630,7 @@ msgstr ""
 "Följande ospårade filer i arbetskatalogen skulle tas bort av utcheckningen:\n"
 "%%sFlytta eller ta bort dem innan du byter gren."
 
-#: unpack-trees.c:131
+#: unpack-trees.c:134
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4276,7 +4639,7 @@ msgstr ""
 "Följande ospårade filer i arbetskatalogen skulle tas bort av utcheckningen:\n"
 "%%s"
 
-#: unpack-trees.c:134
+#: unpack-trees.c:137
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4286,7 +4649,7 @@ msgstr ""
 "sammanslagningen:\n"
 "%%sFlytta eller ta bort dem innan du slår samman."
 
-#: unpack-trees.c:136
+#: unpack-trees.c:139
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4296,7 +4659,7 @@ msgstr ""
 "sammanslagningen:\n"
 "%%s"
 
-#: unpack-trees.c:139
+#: unpack-trees.c:142
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4305,7 +4668,7 @@ msgstr ""
 "Följande ospårade filer i arbetskatalogen skulle tas bort av \"%s\":\n"
 "%%sFlytta eller ta bort dem innan du \"%s\"."
 
-#: unpack-trees.c:141
+#: unpack-trees.c:144
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4314,7 +4677,7 @@ msgstr ""
 "Följande ospårade filer i arbetskatalogen skulle tas bort av \"%s\":\n"
 "%%s"
 
-#: unpack-trees.c:146
+#: unpack-trees.c:150
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4325,7 +4688,7 @@ msgstr ""
 "utcheckningen:\n"
 "%%sFlytta eller ta bort dem innan du byter gren."
 
-#: unpack-trees.c:148
+#: unpack-trees.c:152
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4336,7 +4699,7 @@ msgstr ""
 "utcheckningen:\n"
 "%%s"
 
-#: unpack-trees.c:151
+#: unpack-trees.c:155
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4346,7 +4709,7 @@ msgstr ""
 "sammanslagningen:\n"
 "%%sFlytta eller ta bort dem innan du byter gren."
 
-#: unpack-trees.c:153
+#: unpack-trees.c:157
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4356,7 +4719,7 @@ msgstr ""
 "sammanslagningen:\n"
 "%%s"
 
-#: unpack-trees.c:156
+#: unpack-trees.c:160
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4365,7 +4728,7 @@ msgstr ""
 "Följande ospårade filer i arbetskatalogen skulle skrivas över av \"%s\":\n"
 "%%sFlytta eller ta bort dem innan du \"%s\"."
 
-#: unpack-trees.c:158
+#: unpack-trees.c:162
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4374,12 +4737,12 @@ msgstr ""
 "Följande ospårade filer i arbetskatalogen skulle skrivas över av \"%s\":\n"
 "%%s"
 
-#: unpack-trees.c:165
+#: unpack-trees.c:170
 #, c-format
 msgid "Entry '%s' overlaps with '%s'.  Cannot bind."
 msgstr "Posten \"%s\" överlappar \"%s\". Kan inte binda."
 
-#: unpack-trees.c:168
+#: unpack-trees.c:173
 #, c-format
 msgid ""
 "Cannot update sparse checkout: the following entries are not up to date:\n"
@@ -4388,7 +4751,7 @@ msgstr ""
 "Kan inte uppdatera gles utcheckning: följande poster är inte à jour:\n"
 "%s"
 
-#: unpack-trees.c:170
+#: unpack-trees.c:175
 #, c-format
 msgid ""
 "The following working tree files would be overwritten by sparse checkout "
@@ -4399,7 +4762,7 @@ msgstr ""
 "utcheckning:\n"
 "%s"
 
-#: unpack-trees.c:172
+#: unpack-trees.c:177
 #, c-format
 msgid ""
 "The following working tree files would be removed by sparse checkout "
@@ -4410,7 +4773,7 @@ msgstr ""
 "utcheckning:\n"
 "%s"
 
-#: unpack-trees.c:174
+#: unpack-trees.c:179
 #, c-format
 msgid ""
 "Cannot update submodule:\n"
@@ -4419,12 +4782,12 @@ msgstr ""
 "Kan inte uppdatera undermodul:\n"
 "%s"
 
-#: unpack-trees.c:251
+#: unpack-trees.c:262
 #, c-format
 msgid "Aborting\n"
 msgstr "Avbryter\n"
 
-#: unpack-trees.c:333
+#: unpack-trees.c:344
 msgid "Checking out files"
 msgstr "Checkar ut filer"
 
@@ -4493,7 +4856,7 @@ msgid "could not open '%s' for reading and writing"
 msgstr "kunde inte öppna \"%s\" för läsning och skrivning"
 
 #: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770
-#: builtin/am.c:862 builtin/merge.c:1044
+#: builtin/am.c:862 builtin/merge.c:1043
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "kunde inte öppna \"%s\" för läsning"
@@ -4507,155 +4870,155 @@ msgstr "kan inte komma åt \"%s\""
 msgid "unable to get current working directory"
 msgstr "kan inte hämta aktuell arbetskatalog"
 
-#: wt-status.c:151
+#: wt-status.c:154
 msgid "Unmerged paths:"
 msgstr "Ej sammanslagna sökvägar:"
 
-#: wt-status.c:178 wt-status.c:205
+#: wt-status.c:181 wt-status.c:208
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (använd \"git reset %s <fil>...\" för att ta bort från kö)"
 
-#: wt-status.c:180 wt-status.c:207
+#: wt-status.c:183 wt-status.c:210
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (använd \"git rm --cached <fil>...\" för att ta bort från kö)"
 
-#: wt-status.c:184
+#: wt-status.c:187
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (använd \"git add <fil>...\" för att ange lösning)"
 
-#: wt-status.c:186 wt-status.c:190
+#: wt-status.c:189 wt-status.c:193
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr "  (använd \"git add/rm <fil>...\" som lämpligt för att ange lösning)"
 
-#: wt-status.c:188
+#: wt-status.c:191
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (använd \"git rm <fil>...\" för att ange lösning)"
 
-#: wt-status.c:199 wt-status.c:1007
+#: wt-status.c:202 wt-status.c:1015
 msgid "Changes to be committed:"
 msgstr "Ändringar att checka in:"
 
-#: wt-status.c:217 wt-status.c:1016
+#: wt-status.c:220 wt-status.c:1024
 msgid "Changes not staged for commit:"
 msgstr "Ändringar ej i incheckningskön:"
 
-#: wt-status.c:221
+#: wt-status.c:224
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr ""
 "  (använd \"git add <fil>...\" för att uppdatera vad som skall checkas in)"
 
-#: wt-status.c:223
+#: wt-status.c:226
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr ""
 "  (använd \"git add/rm <fil>...\" för att uppdatera vad som skall checkas in)"
 
-#: wt-status.c:224
+#: wt-status.c:227
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 "  (använd \"git checkout -- <fil>...\" för att förkasta ändringar i "
 "arbetskatalogen)"
 
-#: wt-status.c:226
+#: wt-status.c:229
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr ""
 "  (checka in eller förkasta ospårat eller ändrat innehåll i undermoduler)"
 
-#: wt-status.c:238
+#: wt-status.c:241
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr ""
 "  (använd \"git %s <fil>...\" för att ta med i det som skall checkas in)"
 
-#: wt-status.c:253
+#: wt-status.c:256
 msgid "both deleted:"
 msgstr "borttaget av bägge:"
 
-#: wt-status.c:255
+#: wt-status.c:258
 msgid "added by us:"
 msgstr "tillagt av oss:"
 
-#: wt-status.c:257
+#: wt-status.c:260
 msgid "deleted by them:"
 msgstr "borttaget av dem:"
 
-#: wt-status.c:259
+#: wt-status.c:262
 msgid "added by them:"
 msgstr "tillagt av dem:"
 
-#: wt-status.c:261
+#: wt-status.c:264
 msgid "deleted by us:"
 msgstr "borttaget av oss:"
 
-#: wt-status.c:263
+#: wt-status.c:266
 msgid "both added:"
 msgstr "tillagt av bägge:"
 
-#: wt-status.c:265
+#: wt-status.c:268
 msgid "both modified:"
 msgstr "ändrat av bägge:"
 
-#: wt-status.c:275
+#: wt-status.c:278
 msgid "new file:"
 msgstr "ny fil:"
 
-#: wt-status.c:277
+#: wt-status.c:280
 msgid "copied:"
 msgstr "kopierad:"
 
-#: wt-status.c:279
+#: wt-status.c:282
 msgid "deleted:"
 msgstr "borttagen:"
 
-#: wt-status.c:281
+#: wt-status.c:284
 msgid "modified:"
 msgstr "ändrad:"
 
-#: wt-status.c:283
+#: wt-status.c:286
 msgid "renamed:"
 msgstr "namnbytt:"
 
-#: wt-status.c:285
+#: wt-status.c:288
 msgid "typechange:"
 msgstr "typbyte:"
 
-#: wt-status.c:287
+#: wt-status.c:290
 msgid "unknown:"
 msgstr "okänd:"
 
-#: wt-status.c:289
+#: wt-status.c:292
 msgid "unmerged:"
 msgstr "osammanslagen:"
 
-#: wt-status.c:369
+#: wt-status.c:372
 msgid "new commits, "
 msgstr "nya incheckningar, "
 
-#: wt-status.c:371
+#: wt-status.c:374
 msgid "modified content, "
 msgstr "ändrat innehåll, "
 
-#: wt-status.c:373
+#: wt-status.c:376
 msgid "untracked content, "
 msgstr "ospårat innehåll, "
 
-#: wt-status.c:847
+#: wt-status.c:853
 #, c-format
 msgid "Your stash currently has %d entry"
 msgid_plural "Your stash currently has %d entries"
 msgstr[0] "Stashen innehåller just nu %d post"
 msgstr[1] "Stashen innehåller just nu %d poster"
 
-#: wt-status.c:879
+#: wt-status.c:885
 msgid "Submodules changed but not updated:"
 msgstr "Undermoduler ändrade men inte uppdaterade:"
 
-#: wt-status.c:881
+#: wt-status.c:887
 msgid "Submodule changes to be committed:"
 msgstr "Undermodulers ändringar att checka in:"
 
-#: wt-status.c:963
+#: wt-status.c:969
 msgid ""
 "Do not modify or remove the line above.\n"
 "Everything below it will be ignored."
@@ -4663,107 +5026,107 @@ msgstr ""
 "Raden ovan får inte ändras eller tas bort.\n"
 "Allt under den kommer tas bort."
 
-#: wt-status.c:1076
+#: wt-status.c:1084
 msgid "You have unmerged paths."
 msgstr "Du har ej sammanslagna sökvägar."
 
-#: wt-status.c:1079
+#: wt-status.c:1087
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (rätta konflikter och kör \"git commit\")"
 
-#: wt-status.c:1081
+#: wt-status.c:1089
 msgid "  (use \"git merge --abort\" to abort the merge)"
 msgstr "  (använd \"git merge --abort\" för att avbryta sammanslagningen)"
 
-#: wt-status.c:1086
+#: wt-status.c:1094
 msgid "All conflicts fixed but you are still merging."
 msgstr "Alla konflikter har rättats men du är fortfarande i en sammanslagning."
 
-#: wt-status.c:1089
+#: wt-status.c:1097
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (använd \"git commit\" för att slutföra sammanslagningen)"
 
-#: wt-status.c:1099
+#: wt-status.c:1107
 msgid "You are in the middle of an am session."
 msgstr "Du är i mitten av en körning av \"git am\"."
 
-#: wt-status.c:1102
+#: wt-status.c:1110
 msgid "The current patch is empty."
 msgstr "Aktuell patch är tom."
 
-#: wt-status.c:1106
+#: wt-status.c:1114
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr "  (rätta konflikter och kör sedan \"git am --continue\")"
 
-#: wt-status.c:1108
+#: wt-status.c:1116
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (använd \"git am --skip\" för att hoppa över patchen)"
 
-#: wt-status.c:1110
+#: wt-status.c:1118
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (använd \"git am --abort\" för att återställa ursprungsgrenen)"
 
-#: wt-status.c:1242
+#: wt-status.c:1250
 msgid "git-rebase-todo is missing."
 msgstr "git-rebase-todo saknas."
 
-#: wt-status.c:1244
+#: wt-status.c:1252
 msgid "No commands done."
 msgstr "Inga kommandon utförda."
 
-#: wt-status.c:1247
+#: wt-status.c:1255
 #, c-format
 msgid "Last command done (%d command done):"
 msgid_plural "Last commands done (%d commands done):"
 msgstr[0] "Sista kommandot utfört (%d kommando utfört):"
 msgstr[1] "Sista kommandot utfört (%d kommandon utfört):"
 
-#: wt-status.c:1258
+#: wt-status.c:1266
 #, c-format
 msgid "  (see more in file %s)"
 msgstr "  (se fler i filen %s)"
 
-#: wt-status.c:1263
+#: wt-status.c:1271
 msgid "No commands remaining."
 msgstr "Inga kommandon återstår."
 
-#: wt-status.c:1266
+#: wt-status.c:1274
 #, c-format
 msgid "Next command to do (%d remaining command):"
 msgid_plural "Next commands to do (%d remaining commands):"
 msgstr[0] "Nästa kommando att utföra (%d kommando återstår):"
 msgstr[1] "Följande kommandon att utföra (%d kommandon återstår):"
 
-#: wt-status.c:1274
+#: wt-status.c:1282
 msgid "  (use \"git rebase --edit-todo\" to view and edit)"
 msgstr "  (använd \"git rebase --edit-todo\" för att visa och redigera)"
 
-#: wt-status.c:1287
+#: wt-status.c:1295
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "Du håller på att ombasera grenen \"%s\" ovanpå \"%s\"."
 
-#: wt-status.c:1292
+#: wt-status.c:1300
 msgid "You are currently rebasing."
 msgstr "Du håller på med en ombasering."
 
-#: wt-status.c:1306
+#: wt-status.c:1314
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (rätta konflikter och kör sedan \"git rebase --continue\")"
 
-#: wt-status.c:1308
+#: wt-status.c:1316
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (använd \"git rebase --skip\" för att hoppa över patchen)"
 
-#: wt-status.c:1310
+#: wt-status.c:1318
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (använd \"git rebase --abort\" för att checka ut ursprungsgrenen)"
 
-#: wt-status.c:1316
+#: wt-status.c:1324
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (alla konflikter rättade: kör \"git rebase --continue\")"
 
-#: wt-status.c:1320
+#: wt-status.c:1328
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
@@ -4771,126 +5134,126 @@ msgstr ""
 "Du håller på att dela upp en incheckning medan du ombaserar grenen \"%s\" "
 "ovanpå \"%s\"."
 
-#: wt-status.c:1325
+#: wt-status.c:1333
 msgid "You are currently splitting a commit during a rebase."
 msgstr "Du håller på att dela upp en incheckning i en ombasering."
 
-#: wt-status.c:1328
+#: wt-status.c:1336
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr "  (Så fort din arbetskatalog är ren, kör \"git rebase --continue\")"
 
-#: wt-status.c:1332
+#: wt-status.c:1340
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr ""
 "Du håller på att redigera en incheckning medan du ombaserar grenen \"%s\" "
 "ovanpå \"%s\"."
 
-#: wt-status.c:1337
+#: wt-status.c:1345
 msgid "You are currently editing a commit during a rebase."
 msgstr "Du håller på att redigera en incheckning under en ombasering."
 
-#: wt-status.c:1340
+#: wt-status.c:1348
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr ""
 "  (använd \"git commit --amend\" för att lägga till på aktuell incheckning)"
 
-#: wt-status.c:1342
+#: wt-status.c:1350
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr "  (använd \"git rebase --continue\" när du är nöjd med dina ändringar)"
 
-#: wt-status.c:1352
+#: wt-status.c:1360
 #, c-format
 msgid "You are currently cherry-picking commit %s."
 msgstr "Du håller på med en \"cherry-pick\" av incheckningen %s."
 
-#: wt-status.c:1357
+#: wt-status.c:1365
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr "  (rätta konflikter och kör sedan \"git cherry-pick --continue\")"
 
-#: wt-status.c:1360
+#: wt-status.c:1368
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr "  (alla konflikter rättade: kör \"git cherry-pick --continue\")"
 
-#: wt-status.c:1362
+#: wt-status.c:1370
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr ""
 "  (använd \"git cherry-pick --abort\" för att avbryta \"cherry-pick\"-"
 "operationen)"
 
-#: wt-status.c:1371
+#: wt-status.c:1379
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "Du håller på med att ångra incheckningen %s."
 
-#: wt-status.c:1376
+#: wt-status.c:1384
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (rätta konflikter och kör sedan \"git revert --continue\")"
 
-#: wt-status.c:1379
+#: wt-status.c:1387
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr "  (alla konflikter rättade: kör \"git revert --continue\")"
 
-#: wt-status.c:1381
+#: wt-status.c:1389
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr "  (använd \"git revert --abort\" för att avbryta ångrandet)"
 
-#: wt-status.c:1392
+#: wt-status.c:1400
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr "Du håller på med en \"bisect\", startad från grenen \"%s\"."
 
-#: wt-status.c:1396
+#: wt-status.c:1404
 msgid "You are currently bisecting."
 msgstr "Du håller på med en \"bisect\"."
 
-#: wt-status.c:1399
+#: wt-status.c:1407
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr ""
 "  (använd \"git bisect reset\" för att komma tillbaka till ursprungsgrenen)"
 
-#: wt-status.c:1596
+#: wt-status.c:1604
 msgid "On branch "
 msgstr "På grenen "
 
-#: wt-status.c:1602
+#: wt-status.c:1610
 msgid "interactive rebase in progress; onto "
 msgstr "interaktiv ombasering pågår; ovanpå "
 
-#: wt-status.c:1604
+#: wt-status.c:1612
 msgid "rebase in progress; onto "
 msgstr "ombasering pågår; ovanpå "
 
-#: wt-status.c:1609
+#: wt-status.c:1617
 msgid "HEAD detached at "
 msgstr "HEAD frånkopplad vid "
 
-#: wt-status.c:1611
+#: wt-status.c:1619
 msgid "HEAD detached from "
 msgstr "HEAD frånkopplad från "
 
-#: wt-status.c:1614
+#: wt-status.c:1622
 msgid "Not currently on any branch."
 msgstr "Inte på någon gren för närvarande."
 
-#: wt-status.c:1634
+#: wt-status.c:1642
 msgid "Initial commit"
 msgstr "Första incheckning"
 
-#: wt-status.c:1635
+#: wt-status.c:1643
 msgid "No commits yet"
 msgstr "Inga incheckningar ännu"
 
-#: wt-status.c:1649
+#: wt-status.c:1657
 msgid "Untracked files"
 msgstr "Ospårade filer"
 
-#: wt-status.c:1651
+#: wt-status.c:1659
 msgid "Ignored files"
 msgstr "Ignorerade filer"
 
-#: wt-status.c:1655
+#: wt-status.c:1663
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -4902,32 +5265,32 @@ msgstr ""
 "lägga till nya filer själv (se \"git help status\")."
 
 # %s är nästa sträng eller tom.
-#: wt-status.c:1661
+#: wt-status.c:1669
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "Ospårade filer visas ej%s"
 
-#: wt-status.c:1663
+#: wt-status.c:1671
 msgid " (use -u option to show untracked files)"
 msgstr " (använd flaggan -u för att visa ospårade filer)"
 
-#: wt-status.c:1669
+#: wt-status.c:1677
 msgid "No changes"
 msgstr "Inga ändringar"
 
-#: wt-status.c:1674
+#: wt-status.c:1682
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr ""
 "inga ändringar att checka in (använd \"git add\" och/eller \"git commit -a"
 "\")\n"
 
-#: wt-status.c:1677
+#: wt-status.c:1685
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "inga ändringar att checka in\n"
 
-#: wt-status.c:1680
+#: wt-status.c:1688
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
@@ -4936,67 +5299,67 @@ msgstr ""
 "inget köat för incheckning, men ospårade filer finns (spåra med \"git add"
 "\")\n"
 
-#: wt-status.c:1683
+#: wt-status.c:1691
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr "inget köat för incheckning, men ospårade filer finns\n"
 
-#: wt-status.c:1686
+#: wt-status.c:1694
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr "inget att checka in (skapa/kopiera filer och spåra med \"git add\")\n"
 
-#: wt-status.c:1689 wt-status.c:1694
+#: wt-status.c:1697 wt-status.c:1702
 #, c-format
 msgid "nothing to commit\n"
 msgstr "inget att checka in\n"
 
-#: wt-status.c:1692
+#: wt-status.c:1700
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr "inget att checka in (använd -u för att visa ospårade filer)\n"
 
-#: wt-status.c:1696
+#: wt-status.c:1704
 #, c-format
 msgid "nothing to commit, working tree clean\n"
 msgstr "inget att checka in, arbetskatalogen ren\n"
 
-#: wt-status.c:1809
+#: wt-status.c:1817
 msgid "No commits yet on "
 msgstr "Inga incheckningar ännu på "
 
-#: wt-status.c:1813
+#: wt-status.c:1821
 msgid "HEAD (no branch)"
 msgstr "HEAD (ingen gren)"
 
-#: wt-status.c:1844
+#: wt-status.c:1852
 msgid "different"
 msgstr "olika"
 
-#: wt-status.c:1846 wt-status.c:1854
+#: wt-status.c:1854 wt-status.c:1862
 msgid "behind "
 msgstr "efter "
 
-#: wt-status.c:1849 wt-status.c:1852
+#: wt-status.c:1857 wt-status.c:1860
 msgid "ahead "
 msgstr "före "
 
 #. TRANSLATORS: the action is e.g. "pull with rebase"
-#: wt-status.c:2358
+#: wt-status.c:2366
 #, c-format
 msgid "cannot %s: You have unstaged changes."
 msgstr "kan inte %s: Du har oköade ändringar."
 
-#: wt-status.c:2364
+#: wt-status.c:2372
 msgid "additionally, your index contains uncommitted changes."
 msgstr "dessutom innehåller dit index ändringar som inte har checkats in."
 
-#: wt-status.c:2366
+#: wt-status.c:2374
 #, c-format
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "kan inte %s: Ditt index innehåller ändringar som inte checkats in."
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:440
+#: compat/precompose_utf8.c:58 builtin/clone.c:442
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr "misslyckades ta bort länken \"%s\""
@@ -5010,7 +5373,7 @@ msgstr "git add [<flaggor>] [--] <sökväg>..."
 msgid "unexpected diff status %c"
 msgstr "diff-status %c förväntades inte"
 
-#: builtin/add.c:88 builtin/commit.c:257
+#: builtin/add.c:88 builtin/commit.c:266
 msgid "updating files failed"
 msgstr "misslyckades uppdatera filer"
 
@@ -5023,7 +5386,7 @@ msgstr "ta bort \"%s\"\n"
 msgid "Unstaged changes after refreshing the index:"
 msgstr "Oköade ändringar efter att ha uppdaterat indexet:"
 
-#: builtin/add.c:233 builtin/rev-parse.c:888
+#: builtin/add.c:233 builtin/rev-parse.c:892
 msgid "Could not read the index"
 msgstr "Kunde inte läsa indexet"
 
@@ -5054,77 +5417,77 @@ msgstr "Tom patch. Avbryter."
 msgid "Could not apply '%s'"
 msgstr "Kunde inte tillämpa \"%s\""
 
-#: builtin/add.c:271
+#: builtin/add.c:269
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr "Följande sökvägar ignoreras av en av dina .gitignore-filer:\n"
 
-#: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:146 builtin/mv.c:124
-#: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541
-#: builtin/remote.c:1333 builtin/rm.c:242 builtin/send-pack.c:164
+#: builtin/add.c:289 builtin/clean.c:911 builtin/fetch.c:145 builtin/mv.c:123
+#: builtin/prune-packed.c:55 builtin/pull.c:212 builtin/push.c:557
+#: builtin/remote.c:1342 builtin/rm.c:240 builtin/send-pack.c:165
 msgid "dry run"
 msgstr "testkörning"
 
-#: builtin/add.c:294
+#: builtin/add.c:292
 msgid "interactive picking"
 msgstr "plocka interaktivt"
 
-#: builtin/add.c:295 builtin/checkout.c:1128 builtin/reset.c:302
+#: builtin/add.c:293 builtin/checkout.c:1135 builtin/reset.c:302
 msgid "select hunks interactively"
 msgstr "välj stycken interaktivt"
 
-#: builtin/add.c:296
+#: builtin/add.c:294
 msgid "edit current diff and apply"
 msgstr "redigera aktuell diff och applicera"
 
-#: builtin/add.c:297
+#: builtin/add.c:295
 msgid "allow adding otherwise ignored files"
 msgstr "tillåt lägga till annars ignorerade filer"
 
-#: builtin/add.c:298
+#: builtin/add.c:296
 msgid "update tracked files"
 msgstr "uppdatera spårade filer"
 
-#: builtin/add.c:299
+#: builtin/add.c:297
 msgid "renormalize EOL of tracked files (implies -u)"
 msgstr "åternormalisera radslut i spårade filer (implicerar -u)"
 
-#: builtin/add.c:300
+#: builtin/add.c:298
 msgid "record only the fact that the path will be added later"
 msgstr "registrera endast att sökvägen kommer läggas till senare"
 
-#: builtin/add.c:301
+#: builtin/add.c:299
 msgid "add changes from all tracked and untracked files"
 msgstr "lägg till ändringar från alla spårade och ospårade filer"
 
-#: builtin/add.c:304
+#: builtin/add.c:302
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr "ignorera sökvägar borttagna i arbetskatalogen (samma som --no-all)"
 
-#: builtin/add.c:306
+#: builtin/add.c:304
 msgid "don't add, only refresh the index"
 msgstr "lägg inte till, uppdatera endast indexet"
 
-#: builtin/add.c:307
+#: builtin/add.c:305
 msgid "just skip files which cannot be added because of errors"
 msgstr "hoppa bara över filer som inte kan läggas till på grund av fel"
 
-#: builtin/add.c:308
+#: builtin/add.c:306
 msgid "check if - even missing - files are ignored in dry run"
 msgstr "se om - även saknade - filer ignoreras i testkörning"
 
-#: builtin/add.c:309 builtin/update-index.c:964
+#: builtin/add.c:307 builtin/update-index.c:974
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/add.c:309 builtin/update-index.c:965
+#: builtin/add.c:307 builtin/update-index.c:975
 msgid "override the executable bit of the listed files"
 msgstr "överstyr exekveringsbiten för angivna filer"
 
-#: builtin/add.c:311
+#: builtin/add.c:309
 msgid "warn when adding an embedded repository"
 msgstr "varna när ett inbyggt arkiv läggs till"
 
-#: builtin/add.c:326
+#: builtin/add.c:324
 #, c-format
 msgid ""
 "You've added another git repository inside your current repository.\n"
@@ -5155,47 +5518,47 @@ msgstr ""
 "\n"
 "Se ”git help submodule” för ytterligare information."
 
-#: builtin/add.c:354
+#: builtin/add.c:352
 #, c-format
 msgid "adding embedded git repository: %s"
 msgstr "lägger till inbäddat git-arkiv: %s"
 
-#: builtin/add.c:372
+#: builtin/add.c:370
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "Använd -f om du verkligen vill lägga till dem.\n"
 
-#: builtin/add.c:380
+#: builtin/add.c:378
 msgid "adding files failed"
 msgstr "misslyckades lägga till filer"
 
-#: builtin/add.c:417
+#: builtin/add.c:416
 msgid "-A and -u are mutually incompatible"
 msgstr "-A och -u är ömsesidigt inkompatibla"
 
-#: builtin/add.c:424
+#: builtin/add.c:423
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr "Flaggan --ignore-missing kan endast användas tillsammans med --dry-run"
 
-#: builtin/add.c:428
+#: builtin/add.c:427
 #, c-format
 msgid "--chmod param '%s' must be either -x or +x"
 msgstr "--chmod-parametern \"%s\" måste antingen vara -x eller +x"
 
-#: builtin/add.c:443
+#: builtin/add.c:442
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "Inget angivet, inget tillagt.\n"
 
-#: builtin/add.c:444
+#: builtin/add.c:443
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Kanske menade du att skriva \"git add .\"?\n"
 
-#: builtin/add.c:449 builtin/check-ignore.c:177 builtin/checkout.c:280
-#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316
+#: builtin/add.c:448 builtin/check-ignore.c:177 builtin/checkout.c:280
+#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:325
 #: builtin/diff-tree.c:114 builtin/mv.c:144 builtin/reset.c:241
-#: builtin/rm.c:271 builtin/submodule--helper.c:326
+#: builtin/rm.c:270 builtin/submodule--helper.c:328
 msgid "index file corrupt"
 msgstr "indexfilen trasig"
 
@@ -5247,7 +5610,7 @@ msgstr "ogiltig tidszons-offset"
 msgid "Patch format detection failed."
 msgstr "Misslyckades detektera patchformat."
 
-#: builtin/am.c:1013 builtin/clone.c:405
+#: builtin/am.c:1013 builtin/clone.c:407
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "misslyckades skapa katalogen \"%s\""
@@ -5256,7 +5619,7 @@ msgstr "misslyckades skapa katalogen \"%s\""
 msgid "Failed to split patches."
 msgstr "Misslyckades dela patchar."
 
-#: builtin/am.c:1148 builtin/commit.c:342
+#: builtin/am.c:1148 builtin/commit.c:351
 msgid "unable to write index file"
 msgstr "kan inte skriva indexfil"
 
@@ -5433,7 +5796,7 @@ msgid "allow fall back on 3way merging if needed"
 msgstr "tillåt falla tillbaka på trevägssammanslagning om nödvändigt"
 
 #: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57
-#: builtin/repack.c:182
+#: builtin/repack.c:192
 msgid "be quiet"
 msgstr "var tyst"
 
@@ -5475,16 +5838,17 @@ msgstr "ta bort allting före en saxlinje"
 msgid "pass it through git-apply"
 msgstr "sänd det genom git-apply"
 
-#: builtin/am.c:2260 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668
-#: builtin/grep.c:853 builtin/merge.c:206 builtin/pull.c:145 builtin/pull.c:203
-#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197
-#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:382
-#: parse-options.h:144 parse-options.h:146 parse-options.h:257
+#: builtin/am.c:2260 builtin/commit.c:1332 builtin/fmt-merge-msg.c:665
+#: builtin/fmt-merge-msg.c:668 builtin/grep.c:853 builtin/merge.c:208
+#: builtin/pull.c:150 builtin/pull.c:208 builtin/repack.c:201
+#: builtin/repack.c:205 builtin/repack.c:207 builtin/show-branch.c:631
+#: builtin/show-ref.c:169 builtin/tag.c:383 parse-options.h:144
+#: parse-options.h:146 parse-options.h:258
 msgid "n"
 msgstr "n"
 
-#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38
-#: builtin/replace.c:445 builtin/tag.c:418 builtin/verify-tag.c:39
+#: builtin/am.c:2266 builtin/branch.c:632 builtin/for-each-ref.c:38
+#: builtin/replace.c:543 builtin/tag.c:419 builtin/verify-tag.c:39
 msgid "format"
 msgstr "format"
 
@@ -5528,8 +5892,8 @@ msgstr "ljug om incheckningsdatum"
 msgid "use current timestamp for author date"
 msgstr "använd nuvarande tidsstämpel för författardatum"
 
-#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237
-#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:398
+#: builtin/am.c:2298 builtin/commit.c:1468 builtin/merge.c:239
+#: builtin/pull.c:183 builtin/revert.c:112 builtin/tag.c:399
 msgid "key-id"
 msgstr "nyckel-id"
 
@@ -5668,115 +6032,141 @@ msgstr "--write-terms kräver två argument"
 msgid "--bisect-clean-state requires no arguments"
 msgstr "--bisect-clean-state tar inga argument"
 
-#: builtin/blame.c:27
+#: builtin/blame.c:29
 msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
 msgstr "git blame [<flaggor>] [<rev-flaggor>] [<rev>] [--] <fil>"
 
-#: builtin/blame.c:32
+#: builtin/blame.c:34
 msgid "<rev-opts> are documented in git-rev-list(1)"
 msgstr "<rev-flaggor> dokumenteras i git-rev-list(1)"
 
-#: builtin/blame.c:677
+#: builtin/blame.c:404
+#, c-format
+msgid "expecting a color: %s"
+msgstr "förväntade en färg: %s"
+
+#: builtin/blame.c:411
+msgid "must end with a color"
+msgstr "måste sluta med en färg"
+
+#: builtin/blame.c:697
+#, c-format
+msgid "invalid color '%s' in color.blame.repeatedLines"
+msgstr "felaktig färg \"%s\" i color.blame.repeatedLines"
+
+#: builtin/blame.c:715
+msgid "invalid value for blame.coloring"
+msgstr "ogiltigt värde för blame.coloring"
+
+#: builtin/blame.c:786
 msgid "Show blame entries as we find them, incrementally"
 msgstr "Visa klandringsposter när vi hittar dem, interaktivt"
 
-#: builtin/blame.c:678
+#: builtin/blame.c:787
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr "Visa blank SHA-1 för gränsincheckningar (Standard: av)"
 
-#: builtin/blame.c:679
+#: builtin/blame.c:788
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr "Behandla inte rotincheckningar som gränser (Standard: av)"
 
-#: builtin/blame.c:680
+#: builtin/blame.c:789
 msgid "Show work cost statistics"
 msgstr "Visa statistik över arbetskostnad"
 
-#: builtin/blame.c:681
+#: builtin/blame.c:790
 msgid "Force progress reporting"
 msgstr "Tvinga förloppsrapportering"
 
-#: builtin/blame.c:682
+#: builtin/blame.c:791
 msgid "Show output score for blame entries"
 msgstr "Visa utdatapoäng för klandringsposter"
 
-#: builtin/blame.c:683
+#: builtin/blame.c:792
 msgid "Show original filename (Default: auto)"
 msgstr "Visa originalfilnamn (Standard: auto)"
 
-#: builtin/blame.c:684
+#: builtin/blame.c:793
 msgid "Show original linenumber (Default: off)"
 msgstr "Visa ursprungligt radnummer (Standard: av)"
 
-#: builtin/blame.c:685
+#: builtin/blame.c:794
 msgid "Show in a format designed for machine consumption"
 msgstr "Visa i ett format avsett för maskinkonsumtion"
 
-#: builtin/blame.c:686
+#: builtin/blame.c:795
 msgid "Show porcelain format with per-line commit information"
 msgstr "Visa porslinsformat med per-rad-incheckningsinformation"
 
-#: builtin/blame.c:687
+#: builtin/blame.c:796
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr "Använd samma utdataläge som git-annotate (Standard: av)"
 
-#: builtin/blame.c:688
+#: builtin/blame.c:797
 msgid "Show raw timestamp (Default: off)"
 msgstr "Visa rå tidsstämpel (Standard: av)"
 
-#: builtin/blame.c:689
+#: builtin/blame.c:798
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "Visa lång inchecknings-SHA1 (Standard: av)"
 
-#: builtin/blame.c:690
+#: builtin/blame.c:799
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "Undertryck författarnamn och tidsstämpel (Standard: av)"
 
-#: builtin/blame.c:691
+#: builtin/blame.c:800
 msgid "Show author email instead of name (Default: off)"
 msgstr "Visa författarens e-post istället för namn (Standard: av)"
 
-#: builtin/blame.c:692
+#: builtin/blame.c:801
 msgid "Ignore whitespace differences"
 msgstr "Ignorera ändringar i blanksteg"
 
-#: builtin/blame.c:699
+#: builtin/blame.c:802
+msgid "color redundant metadata from previous line differently"
+msgstr "färglägg redundant metadata från tidigare rader annorlunda"
+
+#: builtin/blame.c:803
+msgid "color lines by age"
+msgstr "färglägg rader efter ålder"
+
+#: builtin/blame.c:810
 msgid "Use an experimental heuristic to improve diffs"
 msgstr "Använd en experimentell algoritm för att förbättra diffar"
 
-#: builtin/blame.c:701
+#: builtin/blame.c:812
 msgid "Spend extra cycles to find better match"
 msgstr "Slösa extra cykler med att hitta bättre träff"
 
-#: builtin/blame.c:702
+#: builtin/blame.c:813
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr "Använd revisioner från <fil> istället för att anropa git-rev-list"
 
-#: builtin/blame.c:703
+#: builtin/blame.c:814
 msgid "Use <file>'s contents as the final image"
 msgstr "Använd <fil>s innehåll som slutgiltig bild"
 
-#: builtin/blame.c:704 builtin/blame.c:705
+#: builtin/blame.c:815 builtin/blame.c:816
 msgid "score"
 msgstr "poäng"
 
-#: builtin/blame.c:704
+#: builtin/blame.c:815
 msgid "Find line copies within and across files"
 msgstr "Hitta kopierade rader inuti och mellan filer"
 
-#: builtin/blame.c:705
+#: builtin/blame.c:816
 msgid "Find line movements within and across files"
 msgstr "Hitta flyttade rader inuti och mellan filer"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "Process only line range n,m, counting from 1"
 msgstr "Behandla endast radintervallet n,m, med början på 1"
 
-#: builtin/blame.c:753
+#: builtin/blame.c:866
 msgid "--progress can't be used with --incremental or porcelain formats"
 msgstr "--progress kan inte användas med --incremental eller porslinsformat"
 
@@ -5788,18 +6178,18 @@ msgstr "--progress kan inte användas med --incremental eller porslinsformat"
 #. your language may need more or fewer display
 #. columns.
 #.
-#: builtin/blame.c:804
+#: builtin/blame.c:917
 msgid "4 years, 11 months ago"
 msgstr "4 år, 11 månader sedan"
 
-#: builtin/blame.c:890
+#: builtin/blame.c:1003
 #, c-format
 msgid "file %s has only %lu line"
 msgid_plural "file %s has only %lu lines"
 msgstr[0] "filen %s har bara %lu rad"
 msgstr[1] "filen %s har bara %lu rader"
 
-#: builtin/blame.c:936
+#: builtin/blame.c:1049
 msgid "Blaming lines"
 msgstr "Klandra rader"
 
@@ -5910,66 +6300,66 @@ msgstr "Tog bort fjärrspårande grenen %s (var %s).\n"
 msgid "Deleted branch %s (was %s).\n"
 msgstr "Tog bort grenen %s (var %s).\n"
 
-#: builtin/branch.c:417 builtin/tag.c:58
+#: builtin/branch.c:416 builtin/tag.c:58
 msgid "unable to parse format string"
 msgstr "kan inte tolka formatsträng"
 
-#: builtin/branch.c:450
+#: builtin/branch.c:453
 #, c-format
 msgid "Branch %s is being rebased at %s"
 msgstr "Grenen %s ombaseras på %s"
 
-#: builtin/branch.c:454
+#: builtin/branch.c:457
 #, c-format
 msgid "Branch %s is being bisected at %s"
 msgstr "Grenen %s är i en \"bisect\" på %s"
 
-#: builtin/branch.c:471
+#: builtin/branch.c:474
 msgid "cannot copy the current branch while not on any."
 msgstr "kunde inte kopiera aktuell gren när du inte befinner dig på någon."
 
-#: builtin/branch.c:473
+#: builtin/branch.c:476
 msgid "cannot rename the current branch while not on any."
 msgstr ""
 "kunde inte byta namn på aktuell gren när du inte befinner dig på någon."
 
-#: builtin/branch.c:484
+#: builtin/branch.c:487
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "Felaktigt namn på gren: \"%s\""
 
-#: builtin/branch.c:511
+#: builtin/branch.c:514
 msgid "Branch rename failed"
 msgstr "Misslyckades byta namn på gren"
 
-#: builtin/branch.c:513
+#: builtin/branch.c:516
 msgid "Branch copy failed"
 msgstr "Misslyckades kopiera gren"
 
-#: builtin/branch.c:517
+#: builtin/branch.c:520
 #, c-format
 msgid "Created a copy of a misnamed branch '%s'"
 msgstr "Skapade kopia av felaktigt namngiven gren \"%s\""
 
-#: builtin/branch.c:520
+#: builtin/branch.c:523
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "Bytte bort namn på en felaktigt namngiven gren \"%s\""
 
-#: builtin/branch.c:526
+#: builtin/branch.c:529
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "Grenen namnbytt till %s, men HEAD har inte uppdaterats!"
 
-#: builtin/branch.c:535
+#: builtin/branch.c:538
 msgid "Branch is renamed, but update of config-file failed"
 msgstr "Grenen namnbytt, men misslyckades uppdatera konfigurationsfilen"
 
-#: builtin/branch.c:537
+#: builtin/branch.c:540
 msgid "Branch is copied, but update of config-file failed"
 msgstr "Grenen kopierades, men misslyckades uppdatera konfigurationsfilen"
 
-#: builtin/branch.c:553
+#: builtin/branch.c:556
 #, c-format
 msgid ""
 "Please edit the description for the branch\n"
@@ -5980,221 +6370,223 @@ msgstr ""
 "  %s\n"
 "Rader som inleds med \"%c\" ignoreras.\n"
 
-#: builtin/branch.c:586
+#: builtin/branch.c:589
 msgid "Generic options"
 msgstr "Allmänna flaggor"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:591
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "visa hash och ärenderad, ange två gånger för uppströmsgren"
 
-#: builtin/branch.c:589
+#: builtin/branch.c:592
 msgid "suppress informational messages"
 msgstr "undertryck informationsmeddelanden"
 
-#: builtin/branch.c:590
+#: builtin/branch.c:593
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "ställ in spårningsläge (se git-pull(1))"
 
-#: builtin/branch.c:592
+#: builtin/branch.c:595
 msgid "do not use"
 msgstr "använd ej"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "upstream"
 msgstr "uppströms"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "change the upstream info"
 msgstr "ändra uppströmsinformationen"
 
-#: builtin/branch.c:595
+#: builtin/branch.c:598
 msgid "Unset the upstream info"
 msgstr "Ta bort uppströmsinformationen"
 
-#: builtin/branch.c:596
+#: builtin/branch.c:599
 msgid "use colored output"
 msgstr "använd färgad utdata"
 
-#: builtin/branch.c:597
+#: builtin/branch.c:600
 msgid "act on remote-tracking branches"
 msgstr "arbeta på fjärrspårande grenar"
 
-#: builtin/branch.c:599 builtin/branch.c:601
+#: builtin/branch.c:602 builtin/branch.c:604
 msgid "print only branches that contain the commit"
 msgstr "visa endast grenar som innehåller incheckningen"
 
-#: builtin/branch.c:600 builtin/branch.c:602
+#: builtin/branch.c:603 builtin/branch.c:605
 msgid "print only branches that don't contain the commit"
 msgstr "visa endast grenar som inte innehåller incheckningen"
 
-#: builtin/branch.c:605
+#: builtin/branch.c:608
 msgid "Specific git-branch actions:"
 msgstr "Specifika git-branch-åtgärder:"
 
-#: builtin/branch.c:606
+#: builtin/branch.c:609
 msgid "list both remote-tracking and local branches"
 msgstr "visa både fjärrspårande och lokala grenar"
 
-#: builtin/branch.c:608
+#: builtin/branch.c:611
 msgid "delete fully merged branch"
 msgstr "ta bort helt sammanslagen gren"
 
-#: builtin/branch.c:609
+#: builtin/branch.c:612
 msgid "delete branch (even if not merged)"
 msgstr "ta bort gren (även om inte helt sammanslagen)"
 
-#: builtin/branch.c:610
+#: builtin/branch.c:613
 msgid "move/rename a branch and its reflog"
 msgstr "flytta/ta bort en gren och dess reflogg"
 
-#: builtin/branch.c:611
+#: builtin/branch.c:614
 msgid "move/rename a branch, even if target exists"
 msgstr "flytta/ta bort en gren, även om målet finns"
 
-#: builtin/branch.c:612
+#: builtin/branch.c:615
 msgid "copy a branch and its reflog"
 msgstr "kopiera en gren och dess reflogg"
 
-#: builtin/branch.c:613
+#: builtin/branch.c:616
 msgid "copy a branch, even if target exists"
 msgstr "kopiera en gren, även om målet finns"
 
-#: builtin/branch.c:614
+#: builtin/branch.c:617
 msgid "list branch names"
 msgstr "lista namn på grenar"
 
-#: builtin/branch.c:615
+#: builtin/branch.c:618
 msgid "create the branch's reflog"
 msgstr "skapa grenens reflogg"
 
-#: builtin/branch.c:617
+#: builtin/branch.c:620
 msgid "edit the description for the branch"
 msgstr "redigera beskrivning för grenen"
 
-#: builtin/branch.c:618
+#: builtin/branch.c:621
 msgid "force creation, move/rename, deletion"
 msgstr "tvinga skapande, flytt/namnändring, borttagande"
 
-#: builtin/branch.c:619
+#: builtin/branch.c:622
 msgid "print only branches that are merged"
 msgstr "visa endast sammanslagna grenar"
 
-#: builtin/branch.c:620
+#: builtin/branch.c:623
 msgid "print only branches that are not merged"
 msgstr "visa endast ej sammanslagna grenar"
 
-#: builtin/branch.c:621
+#: builtin/branch.c:624
 msgid "list branches in columns"
 msgstr "visa grenar i spalter"
 
-#: builtin/branch.c:622 builtin/for-each-ref.c:40 builtin/tag.c:411
+#: builtin/branch.c:625 builtin/for-each-ref.c:40 builtin/ls-remote.c:70
+#: builtin/tag.c:412
 msgid "key"
 msgstr "nyckel"
 
-#: builtin/branch.c:623 builtin/for-each-ref.c:41 builtin/tag.c:412
+#: builtin/branch.c:626 builtin/for-each-ref.c:41 builtin/ls-remote.c:71
+#: builtin/tag.c:413
 msgid "field name to sort on"
 msgstr "fältnamn att sortera på"
 
-#: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408
+#: builtin/branch.c:628 builtin/for-each-ref.c:43 builtin/notes.c:408
 #: builtin/notes.c:411 builtin/notes.c:571 builtin/notes.c:574
-#: builtin/tag.c:414
+#: builtin/tag.c:415
 msgid "object"
 msgstr "objekt"
 
-#: builtin/branch.c:626
+#: builtin/branch.c:629
 msgid "print only branches of the object"
 msgstr "visa endast grenar för objektet"
 
-#: builtin/branch.c:628 builtin/for-each-ref.c:49 builtin/tag.c:421
+#: builtin/branch.c:631 builtin/for-each-ref.c:49 builtin/tag.c:422
 msgid "sorting and filtering are case insensitive"
 msgstr "sortering och filtrering skiljer gemener och VERSALER"
 
-#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419
+#: builtin/branch.c:632 builtin/for-each-ref.c:38 builtin/tag.c:420
 #: builtin/verify-tag.c:39
 msgid "format to use for the output"
 msgstr "format att använda för utdata"
 
-#: builtin/branch.c:652 builtin/clone.c:735
+#: builtin/branch.c:655 builtin/clone.c:737
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD hittades inte under refs/heads!"
 
-#: builtin/branch.c:675
+#: builtin/branch.c:678
 msgid "--column and --verbose are incompatible"
 msgstr "--column och --verbose är inkompatibla"
 
-#: builtin/branch.c:690 builtin/branch.c:742 builtin/branch.c:751
+#: builtin/branch.c:693 builtin/branch.c:745 builtin/branch.c:754
 msgid "branch name required"
 msgstr "grennamn krävs"
 
-#: builtin/branch.c:718
+#: builtin/branch.c:721
 msgid "Cannot give description to detached HEAD"
 msgstr "Kan inte beskriva frånkopplad HEAD"
 
-#: builtin/branch.c:723
+#: builtin/branch.c:726
 msgid "cannot edit description of more than one branch"
 msgstr "kan inte redigera beskrivning för mer än en gren"
 
-#: builtin/branch.c:730
+#: builtin/branch.c:733
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "Inga incheckningar på grenen \"%s\" ännu."
 
-#: builtin/branch.c:733
+#: builtin/branch.c:736
 #, c-format
 msgid "No branch named '%s'."
 msgstr "Ingen gren vid namnet \"%s\"."
 
-#: builtin/branch.c:748
+#: builtin/branch.c:751
 msgid "too many branches for a copy operation"
 msgstr "för många grenar för kopiering"
 
-#: builtin/branch.c:757
+#: builtin/branch.c:760
 msgid "too many arguments for a rename operation"
 msgstr "för många flaggor för namnbyte"
 
-#: builtin/branch.c:762
+#: builtin/branch.c:765
 msgid "too many arguments to set new upstream"
 msgstr "för många flaggor för att byta uppström"
 
-#: builtin/branch.c:766
+#: builtin/branch.c:769
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
 msgstr ""
 "kunde inte sätta uppström för HEAD till %s när det inte pekar mot någon gren."
 
-#: builtin/branch.c:769 builtin/branch.c:791 builtin/branch.c:807
+#: builtin/branch.c:772 builtin/branch.c:794 builtin/branch.c:810
 #, c-format
 msgid "no such branch '%s'"
 msgstr "okänd gren \"%s\""
 
-#: builtin/branch.c:773
+#: builtin/branch.c:776
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "grenen \"%s\" finns inte"
 
-#: builtin/branch.c:785
+#: builtin/branch.c:788
 msgid "too many arguments to unset upstream"
 msgstr "för många flaggor för att ta bort uppström"
 
-#: builtin/branch.c:789
+#: builtin/branch.c:792
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr ""
 "kunde inte ta bort uppström för HEAD när det inte pekar mot någon gren."
 
-#: builtin/branch.c:795
+#: builtin/branch.c:798
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "Grenen \"%s\" har ingen uppströmsinformation"
 
-#: builtin/branch.c:810
+#: builtin/branch.c:813
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr ""
 "flaggorna -a och -r på \"git branch\" kan inte anges tillsammans med ett "
 "grennamn"
 
-#: builtin/branch.c:813
+#: builtin/branch.c:816
 msgid ""
 "the '--set-upstream' option is no longer supported. Please use '--track' or "
 "'--set-upstream-to' instead."
@@ -6215,7 +6607,7 @@ msgstr "Behöver ett arkiv för att skapa ett paket (bundle)."
 msgid "Need a repository to unbundle."
 msgstr "Behöver ett arkiv för att packa upp ett paket (bundle)."
 
-#: builtin/cat-file.c:523
+#: builtin/cat-file.c:525
 msgid ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <type> | --textconv | --filters) [--path=<path>] <object>"
@@ -6223,7 +6615,7 @@ msgstr ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <typ> | --textconv | --filters) [--path=<sökväg>] <objekt>"
 
-#: builtin/cat-file.c:524
+#: builtin/cat-file.c:526
 msgid ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
@@ -6231,64 +6623,64 @@ msgstr ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
 
-#: builtin/cat-file.c:561
+#: builtin/cat-file.c:563
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<typ> kan vara en av: blob, tree, commit, tag"
 
-#: builtin/cat-file.c:562
+#: builtin/cat-file.c:564
 msgid "show object type"
 msgstr "visa objekttyp"
 
-#: builtin/cat-file.c:563
+#: builtin/cat-file.c:565
 msgid "show object size"
 msgstr "visa objektstorlek"
 
-#: builtin/cat-file.c:565
+#: builtin/cat-file.c:567
 msgid "exit with zero when there's no error"
 msgstr "avsluta med noll när det inte uppstått något fel"
 
-#: builtin/cat-file.c:566
+#: builtin/cat-file.c:568
 msgid "pretty-print object's content"
 msgstr "visa objektets innehåll snyggt"
 
-#: builtin/cat-file.c:568
+#: builtin/cat-file.c:570
 msgid "for blob objects, run textconv on object's content"
 msgstr "för blob-objekt, kör filter på objektets innehåll"
 
-#: builtin/cat-file.c:570
+#: builtin/cat-file.c:572
 msgid "for blob objects, run filters on object's content"
 msgstr "för blob-objekt, kör filger på objektets innehåll"
 
-#: builtin/cat-file.c:571 git-submodule.sh:878
+#: builtin/cat-file.c:573 git-submodule.sh:894
 msgid "blob"
 msgstr "blob"
 
-#: builtin/cat-file.c:572
+#: builtin/cat-file.c:574
 msgid "use a specific path for --textconv/--filters"
 msgstr "använd specifik sökväg för --textconv/--filters"
 
-#: builtin/cat-file.c:574
+#: builtin/cat-file.c:576
 msgid "allow -s and -t to work with broken/corrupt objects"
 msgstr "låter -s och -t att fungera med trasiga/sönderskrivna objekt"
 
-#: builtin/cat-file.c:575
+#: builtin/cat-file.c:577
 msgid "buffer --batch output"
 msgstr "buffra utdata från --batch"
 
-#: builtin/cat-file.c:577
+#: builtin/cat-file.c:579
 msgid "show info and content of objects fed from the standard input"
 msgstr "visa information och innehåll för objekt som listas på standard in"
 
-#: builtin/cat-file.c:580
+#: builtin/cat-file.c:582
 msgid "show info about objects fed from the standard input"
 msgstr "visa information för objekt som listas på standard in"
 
-#: builtin/cat-file.c:583
+#: builtin/cat-file.c:585
 msgid "follow in-tree symlinks (used with --batch or --batch-check)"
 msgstr ""
 "följ symboliska länkar i trädet (använd med --batch eller --batch-check)"
 
-#: builtin/cat-file.c:585
+#: builtin/cat-file.c:587
 msgid "show all objects with --batch or --batch-check"
 msgstr "visa alla objekt med --batch eller --batch-check"
 
@@ -6316,7 +6708,7 @@ msgstr "läs filnamn från standard in"
 msgid "terminate input and output records by a NUL character"
 msgstr "avsluta in- och utdataposter med NUL-tecken"
 
-#: builtin/check-ignore.c:20 builtin/checkout.c:1106 builtin/gc.c:358
+#: builtin/check-ignore.c:20 builtin/checkout.c:1113 builtin/gc.c:500
 msgid "suppress progress reporting"
 msgstr "undertryck förloppsrapportering"
 
@@ -6406,9 +6798,9 @@ msgid "write the content to temporary files"
 msgstr "skriv innehåll till temporära filer"
 
 #: builtin/checkout-index.c:173 builtin/column.c:31
-#: builtin/submodule--helper.c:1203 builtin/submodule--helper.c:1206
-#: builtin/submodule--helper.c:1212 builtin/submodule--helper.c:1574
-#: builtin/worktree.c:570
+#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1219
+#: builtin/submodule--helper.c:1227 builtin/submodule--helper.c:1591
+#: builtin/worktree.c:610
 msgid "string"
 msgstr "sträng"
 
@@ -6479,54 +6871,54 @@ msgstr "Kan inte uppdatera sökvägar och växla till grenen \"%s\" samtidigt."
 msgid "path '%s' is unmerged"
 msgstr "sökvägen \"%s\" har inte slagits ihop"
 
-#: builtin/checkout.c:505
+#: builtin/checkout.c:506
 msgid "you need to resolve your current index first"
 msgstr "du måste lösa ditt befintliga index först"
 
-#: builtin/checkout.c:636
+#: builtin/checkout.c:643
 #, c-format
 msgid "Can not do reflog for '%s': %s\n"
 msgstr "Kan inte skapa referenslogg för \"%s\": %s\n"
 
-#: builtin/checkout.c:677
+#: builtin/checkout.c:684
 msgid "HEAD is now at"
 msgstr "HEAD är nu på"
 
-#: builtin/checkout.c:681 builtin/clone.c:689
+#: builtin/checkout.c:688 builtin/clone.c:691
 msgid "unable to update HEAD"
 msgstr "kan inte uppdatera HEAD"
 
-#: builtin/checkout.c:685
+#: builtin/checkout.c:692
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Återställ gren \"%s\"\n"
 
-#: builtin/checkout.c:688
+#: builtin/checkout.c:695
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Redan på \"%s\"\n"
 
-#: builtin/checkout.c:692
+#: builtin/checkout.c:699
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Växlade till och nollställde grenen \"%s\"\n"
 
-#: builtin/checkout.c:694 builtin/checkout.c:1039
+#: builtin/checkout.c:701 builtin/checkout.c:1046
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Växlade till en ny gren \"%s\"\n"
 
-#: builtin/checkout.c:696
+#: builtin/checkout.c:703
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Växlade till grenen \"%s\"\n"
 
-#: builtin/checkout.c:747
+#: builtin/checkout.c:754
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... och %d till.\n"
 
-#: builtin/checkout.c:753
+#: builtin/checkout.c:760
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -6549,7 +6941,7 @@ msgstr[1] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:772
+#: builtin/checkout.c:779
 #, c-format
 msgid ""
 "If you want to keep it by creating a new branch, this may be a good time\n"
@@ -6576,161 +6968,161 @@ msgstr[1] ""
 " git branch <nytt_grennamn> %s\n"
 "\n"
 
-#: builtin/checkout.c:804
+#: builtin/checkout.c:811
 msgid "internal error in revision walk"
 msgstr "internt fel vid genomgång av revisioner (revision walk)"
 
-#: builtin/checkout.c:808
+#: builtin/checkout.c:815
 msgid "Previous HEAD position was"
 msgstr "Tidigare position för HEAD var"
 
-#: builtin/checkout.c:836 builtin/checkout.c:1034
+#: builtin/checkout.c:843 builtin/checkout.c:1041
 msgid "You are on a branch yet to be born"
 msgstr "Du är på en gren som ännu inte är född"
 
-#: builtin/checkout.c:940
+#: builtin/checkout.c:947
 #, c-format
 msgid "only one reference expected, %d given."
 msgstr "endast en referens förväntades, %d gavs."
 
-#: builtin/checkout.c:980 builtin/worktree.c:249
+#: builtin/checkout.c:987 builtin/worktree.c:240 builtin/worktree.c:389
 #, c-format
 msgid "invalid reference: %s"
 msgstr "felaktig referens: %s"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1016
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "referensen är inte ett träd: %s"
 
-#: builtin/checkout.c:1048
+#: builtin/checkout.c:1055
 msgid "paths cannot be used with switching branches"
 msgstr "sökvägar kan inte användas vid byte av gren"
 
-#: builtin/checkout.c:1051 builtin/checkout.c:1055
+#: builtin/checkout.c:1058 builtin/checkout.c:1062
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "\"%s\" kan inte användas vid byte av gren"
 
-#: builtin/checkout.c:1059 builtin/checkout.c:1062 builtin/checkout.c:1067
-#: builtin/checkout.c:1070
+#: builtin/checkout.c:1066 builtin/checkout.c:1069 builtin/checkout.c:1074
+#: builtin/checkout.c:1077
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "\"%s\" kan inte användas med \"%s\""
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1082
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "Kan inte växla gren till icke-incheckningen \"%s\""
 
-#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116
-#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:387
-#: builtin/worktree.c:389
+#: builtin/checkout.c:1114 builtin/checkout.c:1116 builtin/clone.c:118
+#: builtin/remote.c:167 builtin/remote.c:169 builtin/worktree.c:433
+#: builtin/worktree.c:435
 msgid "branch"
 msgstr "gren"
 
-#: builtin/checkout.c:1108
+#: builtin/checkout.c:1115
 msgid "create and checkout a new branch"
 msgstr "skapa och checka ut en ny gren"
 
-#: builtin/checkout.c:1110
+#: builtin/checkout.c:1117
 msgid "create/reset and checkout a branch"
 msgstr "skapa/nollställ och checka ut en gren"
 
-#: builtin/checkout.c:1111
+#: builtin/checkout.c:1118
 msgid "create reflog for new branch"
 msgstr "skapa reflogg för ny gren"
 
-#: builtin/checkout.c:1112 builtin/worktree.c:391
+#: builtin/checkout.c:1119 builtin/worktree.c:437
 msgid "detach HEAD at named commit"
 msgstr "koppla från HEAD vid namngiven incheckning"
 
-#: builtin/checkout.c:1113
+#: builtin/checkout.c:1120
 msgid "set upstream info for new branch"
 msgstr "sätt uppströmsinformation för ny gren"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new-branch"
 msgstr "ny-gren"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new unparented branch"
 msgstr "ny gren utan förälder"
 
-#: builtin/checkout.c:1116
+#: builtin/checkout.c:1123
 msgid "checkout our version for unmerged files"
 msgstr "checka ut vår version för ej sammanslagna filer"
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1125
 msgid "checkout their version for unmerged files"
 msgstr "checka ut deras version för ej sammanslagna filer"
 
-#: builtin/checkout.c:1120
+#: builtin/checkout.c:1127
 msgid "force checkout (throw away local modifications)"
 msgstr "tvinga utcheckning (kasta bort lokala ändringar)"
 
-#: builtin/checkout.c:1122
+#: builtin/checkout.c:1129
 msgid "perform a 3-way merge with the new branch"
 msgstr "utför en 3-vägssammanslagning för den nya grenen"
 
-#: builtin/checkout.c:1124 builtin/merge.c:239
+#: builtin/checkout.c:1131 builtin/merge.c:241
 msgid "update ignored files (default)"
 msgstr "uppdatera ignorerade filer (standard)"
 
-#: builtin/checkout.c:1126 builtin/log.c:1499 parse-options.h:263
+#: builtin/checkout.c:1133 builtin/log.c:1499 parse-options.h:264
 msgid "style"
 msgstr "stil"
 
-#: builtin/checkout.c:1127
+#: builtin/checkout.c:1134
 msgid "conflict style (merge or diff3)"
 msgstr "konfliktstil (merge eller diff3)"
 
-#: builtin/checkout.c:1130
+#: builtin/checkout.c:1137
 msgid "do not limit pathspecs to sparse entries only"
 msgstr "begränsa inte sökvägar till endast glesa poster"
 
-#: builtin/checkout.c:1132
+#: builtin/checkout.c:1139
 msgid "second guess 'git checkout <no-such-branch>'"
 msgstr "förutspå \"git checkout <gren-saknas>\""
 
-#: builtin/checkout.c:1134
+#: builtin/checkout.c:1141
 msgid "do not check if another worktree is holding the given ref"
 msgstr ""
 "kontrollera inte om en annan arbetskatalog håller den angivna referensen"
 
-#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150
-#: builtin/merge.c:236 builtin/pull.c:123 builtin/push.c:556
-#: builtin/send-pack.c:173
+#: builtin/checkout.c:1145 builtin/clone.c:85 builtin/fetch.c:149
+#: builtin/merge.c:238 builtin/pull.c:128 builtin/push.c:572
+#: builtin/send-pack.c:174
 msgid "force progress reporting"
 msgstr "tvinga förloppsrapportering"
 
-#: builtin/checkout.c:1168
+#: builtin/checkout.c:1175
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "-b, -B och --orphan är ömsesidigt uteslutande"
 
-#: builtin/checkout.c:1185
+#: builtin/checkout.c:1192
 msgid "--track needs a branch name"
 msgstr "--track behöver ett namn på en gren"
 
-#: builtin/checkout.c:1190
+#: builtin/checkout.c:1197
 msgid "Missing branch name; try -b"
 msgstr "Grennamn saknas; försök med -b"
 
-#: builtin/checkout.c:1226
+#: builtin/checkout.c:1233
 msgid "invalid path specification"
 msgstr "felaktig sökvägsangivelse"
 
-#: builtin/checkout.c:1233
+#: builtin/checkout.c:1240
 #, c-format
 msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
 msgstr "”%s” är inte en incheckning och grenen ”%s” kan inte skapas från den"
 
-#: builtin/checkout.c:1237
+#: builtin/checkout.c:1244
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout: --detach tar inte en sökväg som argument \"%s\""
 
-#: builtin/checkout.c:1241
+#: builtin/checkout.c:1248
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -6770,7 +7162,7 @@ msgstr "Skulle hoppa över arkivet %s\n"
 msgid "failed to remove %s"
 msgstr "misslyckades ta bort %s"
 
-#: builtin/clean.c:302 git-add--interactive.perl:572
+#: builtin/clean.c:302 git-add--interactive.perl:579
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6783,7 +7175,7 @@ msgstr ""
 "foo        - markera post baserad på unikt prefix\n"
 "           - (tomt) markera ingenting\n"
 
-#: builtin/clean.c:306 git-add--interactive.perl:581
+#: builtin/clean.c:306 git-add--interactive.perl:588
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6804,8 +7196,8 @@ msgstr ""
 "*          - välj alla poster\n"
 "           - (tomt) avsluta markering\n"
 
-#: builtin/clean.c:522 git-add--interactive.perl:547
-#: git-add--interactive.perl:552
+#: builtin/clean.c:522 git-add--interactive.perl:554
+#: git-add--interactive.perl:559
 #, c-format, perl-format
 msgid "Huh (%s)?\n"
 msgstr "Vadå (%s)?\n"
@@ -6830,7 +7222,7 @@ msgstr "Välj poster att ta bort"
 msgid "Remove %s [y/N]? "
 msgstr "Ta bort %s [Y=ja / N=nej]? "
 
-#: builtin/clean.c:788 git-add--interactive.perl:1710
+#: builtin/clean.c:788 git-add--interactive.perl:1717
 #, c-format
 msgid "Bye.\n"
 msgstr "Hej då.\n"
@@ -6853,11 +7245,11 @@ msgstr ""
 "help                - denna skärm\n"
 "?                   - hjälp för kommandoval"
 
-#: builtin/clean.c:823 git-add--interactive.perl:1786
+#: builtin/clean.c:823 git-add--interactive.perl:1793
 msgid "*** Commands ***"
 msgstr "*** Kommandon ***"
 
-#: builtin/clean.c:824 git-add--interactive.perl:1783
+#: builtin/clean.c:824 git-add--interactive.perl:1790
 msgid "What now"
 msgstr "Vad nu"
 
@@ -6926,144 +7318,146 @@ msgstr ""
 "clean.requireForce har standardvärdet true och varken -i, -n eller -f "
 "angavs; vägrar städa"
 
-#: builtin/clone.c:40
+#: builtin/clone.c:42
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<flaggor>] [--] <arkiv> [<kat>]"
 
-#: builtin/clone.c:85
+#: builtin/clone.c:87
 msgid "don't create a checkout"
 msgstr "skapa inte någon utcheckning"
 
-#: builtin/clone.c:86 builtin/clone.c:88 builtin/init-db.c:479
+#: builtin/clone.c:88 builtin/clone.c:90 builtin/init-db.c:479
 msgid "create a bare repository"
 msgstr "skapa ett naket (\"bare\") arkiv"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:92
 msgid "create a mirror repository (implies bare)"
 msgstr "skapa ett spegelarkiv (implicerar \"bare\")"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:94
 msgid "to clone from a local repository"
 msgstr "för att klona från ett lokalt arkiv"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:96
 msgid "don't use local hardlinks, always copy"
 msgstr "skapa inte lokala hårda länkar, kopiera alltid"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:98
 msgid "setup as shared repository"
 msgstr "skapa som ett delat arkiv"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "pathspec"
 msgstr "sökvägsangivelse"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "initialize submodules in the clone"
 msgstr "initiera undermoduler i klonen"
 
-#: builtin/clone.c:105
+#: builtin/clone.c:107
 msgid "number of submodules cloned in parallel"
 msgstr "antal undermoduler som klonas parallellt"
 
-#: builtin/clone.c:106 builtin/init-db.c:476
+#: builtin/clone.c:108 builtin/init-db.c:476
 msgid "template-directory"
 msgstr "mallkatalog"
 
-#: builtin/clone.c:107 builtin/init-db.c:477
+#: builtin/clone.c:109 builtin/init-db.c:477
 msgid "directory from which templates will be used"
 msgstr "katalog att använda mallar från"
 
-#: builtin/clone.c:109 builtin/clone.c:111 builtin/submodule--helper.c:1210
-#: builtin/submodule--helper.c:1577
+#: builtin/clone.c:111 builtin/clone.c:113 builtin/submodule--helper.c:1223
+#: builtin/submodule--helper.c:1594
 msgid "reference repository"
 msgstr "referensarkiv"
 
-#: builtin/clone.c:113
+#: builtin/clone.c:115 builtin/submodule--helper.c:1225
+#: builtin/submodule--helper.c:1596
 msgid "use --reference only while cloning"
 msgstr "använd --reference endast under kloningen"
 
-#: builtin/clone.c:114 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/clone.c:116 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/pack-objects.c:3166 builtin/repack.c:213
 msgid "name"
 msgstr "namn"
 
-#: builtin/clone.c:115
+#: builtin/clone.c:117
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "använd <namn> istället för \"origin\" för att spåra uppströms"
 
-#: builtin/clone.c:117
+#: builtin/clone.c:119
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "checka ut <gren> istället för fjärrens HEAD"
 
-#: builtin/clone.c:119
+#: builtin/clone.c:121
 msgid "path to git-upload-pack on the remote"
 msgstr "sökväg till git-upload-pack på fjärren"
 
-#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813
-#: builtin/pull.c:211
+#: builtin/clone.c:122 builtin/fetch.c:150 builtin/grep.c:813
+#: builtin/pull.c:216
 msgid "depth"
 msgstr "djup"
 
-#: builtin/clone.c:121
+#: builtin/clone.c:123
 msgid "create a shallow clone of that depth"
 msgstr "skapa en grund klon på detta djup"
 
-#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017
+#: builtin/clone.c:124 builtin/fetch.c:152 builtin/pack-objects.c:3157
 #: parse-options.h:154
 msgid "time"
 msgstr "tid"
 
-#: builtin/clone.c:123
+#: builtin/clone.c:125
 msgid "create a shallow clone since a specific time"
 msgstr "skapa en grund klon från en angiven tidpunkt"
 
-#: builtin/clone.c:124 builtin/fetch.c:155
+#: builtin/clone.c:126 builtin/fetch.c:154
 msgid "revision"
 msgstr "revision"
 
-#: builtin/clone.c:125 builtin/fetch.c:156
+#: builtin/clone.c:127 builtin/fetch.c:155
 msgid "deepen history of shallow clone, excluding rev"
 msgstr "fördjupa historik för grund klon, exkludera revisionen"
 
-#: builtin/clone.c:127
+#: builtin/clone.c:129
 msgid "clone only one branch, HEAD or --branch"
 msgstr "klona endast en gren, HEAD eller --branch"
 
-#: builtin/clone.c:129
+#: builtin/clone.c:131
 msgid "don't clone any tags, and make later fetches not to follow them"
 msgstr "klona inga taggar och gör att senare hämtningar inte följer dem"
 
-#: builtin/clone.c:131
+#: builtin/clone.c:133
 msgid "any cloned submodules will be shallow"
 msgstr "klonade undermoduler kommer vara grunda"
 
-#: builtin/clone.c:132 builtin/init-db.c:485
+#: builtin/clone.c:134 builtin/init-db.c:485
 msgid "gitdir"
 msgstr "gitkat"
 
-#: builtin/clone.c:133 builtin/init-db.c:486
+#: builtin/clone.c:135 builtin/init-db.c:486
 msgid "separate git dir from working tree"
 msgstr "separera gitkatalogen från arbetskatalogen"
 
-#: builtin/clone.c:134
+#: builtin/clone.c:136
 msgid "key=value"
 msgstr "nyckel=värde"
 
-#: builtin/clone.c:135
+#: builtin/clone.c:137
 msgid "set config inside the new repository"
 msgstr "ställ in konfiguration i det nya arkivet"
 
-#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224
-#: builtin/push.c:567
+#: builtin/clone.c:138 builtin/fetch.c:173 builtin/pull.c:229
+#: builtin/push.c:583
 msgid "use IPv4 addresses only"
 msgstr "använd endast IPv4-adresser"
 
-#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227
-#: builtin/push.c:569
+#: builtin/clone.c:140 builtin/fetch.c:175 builtin/pull.c:232
+#: builtin/push.c:585
 msgid "use IPv6 addresses only"
 msgstr "använd endast IPv6-adresser"
 
-#: builtin/clone.c:276
+#: builtin/clone.c:278
 msgid ""
 "No directory name could be guessed.\n"
 "Please specify a directory on the command line"
@@ -7071,42 +7465,42 @@ msgstr ""
 "Kunde inte gissa katalognamn.\n"
 "Ange en katalog på kommandoraden"
 
-#: builtin/clone.c:329
+#: builtin/clone.c:331
 #, c-format
 msgid "info: Could not add alternate for '%s': %s\n"
 msgstr "info: Kan inte skapa alternativ för \"%s\": %s\n"
 
-#: builtin/clone.c:401
+#: builtin/clone.c:403
 #, c-format
 msgid "failed to open '%s'"
 msgstr "misslyckades öppna \"%s\""
 
-#: builtin/clone.c:409
+#: builtin/clone.c:411
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "%s finns och är ingen katalog"
 
-#: builtin/clone.c:423
+#: builtin/clone.c:425
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "misslyckades ta status på %s\n"
 
-#: builtin/clone.c:445
+#: builtin/clone.c:447
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "misslyckades skapa länken \"%s\""
 
-#: builtin/clone.c:449
+#: builtin/clone.c:451
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "misslyckades kopiera filen till \"%s\""
 
-#: builtin/clone.c:475
+#: builtin/clone.c:477
 #, c-format
 msgid "done.\n"
 msgstr "klart.\n"
 
-#: builtin/clone.c:489
+#: builtin/clone.c:491
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -7116,100 +7510,100 @@ msgstr ""
 "Du kan inspektera det som checkades ut med \"git status\"\n"
 "och försöka checka ut igen med \"git checkout -f HEAD\"\n"
 
-#: builtin/clone.c:566
+#: builtin/clone.c:568
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "Kunde inte hitta fjärrgrenen %s för att klona."
 
-#: builtin/clone.c:661
+#: builtin/clone.c:663
 msgid "remote did not send all necessary objects"
 msgstr "fjärren sände inte alla nödvändiga objekt"
 
-#: builtin/clone.c:677
+#: builtin/clone.c:679
 #, c-format
 msgid "unable to update %s"
 msgstr "kan inte uppdatera %s"
 
-#: builtin/clone.c:726
+#: builtin/clone.c:728
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr ""
 "HEAD hos fjärren pekar på en obefintlig referens, kan inte checka ut.\n"
 
-#: builtin/clone.c:756
+#: builtin/clone.c:758
 msgid "unable to checkout working tree"
 msgstr "kunde inte checka ut arbetskatalogen"
 
-#: builtin/clone.c:801
+#: builtin/clone.c:803
 msgid "unable to write parameters to config file"
 msgstr "kunde inte skriva parametrar till konfigurationsfilen"
 
-#: builtin/clone.c:864
+#: builtin/clone.c:866
 msgid "cannot repack to clean up"
 msgstr "kan inte packa om för att städa upp"
 
-#: builtin/clone.c:866
+#: builtin/clone.c:868
 msgid "cannot unlink temporary alternates file"
 msgstr "kunde inte ta bort temporär \"alternates\"-fil"
 
-#: builtin/clone.c:906 builtin/receive-pack.c:1946
+#: builtin/clone.c:907 builtin/receive-pack.c:1947
 msgid "Too many arguments."
 msgstr "För många argument."
 
-#: builtin/clone.c:910
+#: builtin/clone.c:911
 msgid "You must specify a repository to clone."
 msgstr "Du måste ange ett arkiv att klona."
 
-#: builtin/clone.c:923
+#: builtin/clone.c:924
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "flaggorna --bare och --origin %s är inkompatibla."
 
-#: builtin/clone.c:926
+#: builtin/clone.c:927
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "flaggorna --bare och --separate-git-dir är inkompatibla."
 
-#: builtin/clone.c:939
+#: builtin/clone.c:940
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "arkivet \"%s\" finns inte"
 
-#: builtin/clone.c:945 builtin/fetch.c:1455
+#: builtin/clone.c:946 builtin/fetch.c:1460
 #, c-format
 msgid "depth %s is not a positive number"
 msgstr "djupet %s är inte ett positivt tal"
 
-#: builtin/clone.c:955
+#: builtin/clone.c:956
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr "destinationssökvägen \"%s\" finns redan och är inte en tom katalog."
 
-#: builtin/clone.c:965
+#: builtin/clone.c:966
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "arbetsträdet \"%s\" finns redan."
 
-#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270
-#: builtin/worktree.c:255 builtin/worktree.c:285
+#: builtin/clone.c:981 builtin/clone.c:1002 builtin/difftool.c:270
+#: builtin/worktree.c:246 builtin/worktree.c:276
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "kunde inte skapa inledande kataloger för \"%s\""
 
-#: builtin/clone.c:985
+#: builtin/clone.c:986
 #, c-format
 msgid "could not create work tree dir '%s'"
 msgstr "kunde inte skapa arbetskatalogen \"%s\""
 
-#: builtin/clone.c:1005
+#: builtin/clone.c:1006
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Klonar till ett naket arkiv \"%s\"...\n"
 
-#: builtin/clone.c:1007
+#: builtin/clone.c:1008
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Klonar till \"%s\"...\n"
 
-#: builtin/clone.c:1031
+#: builtin/clone.c:1032
 msgid ""
 "clone --recursive is not compatible with both --reference and --reference-if-"
 "able"
@@ -7278,7 +7672,7 @@ msgstr "Spaltfyllnad i högerkanten"
 msgid "Padding space between columns"
 msgstr "Spaltfyllnad mellan spalter"
 
-#: builtin/column.c:52
+#: builtin/column.c:51
 msgid "--command must be the first argument"
 msgstr "--command måste vara första argument"
 
@@ -7334,61 +7728,61 @@ msgstr ""
 "\"git cherry-pick --continue\" kommer därefter att återuppta\n"
 "cherry-pick för återstående incheckningar.\n"
 
-#: builtin/commit.c:284
+#: builtin/commit.c:293
 msgid "failed to unpack HEAD tree object"
 msgstr "misslyckades packa upp HEAD:s trädobjekt"
 
-#: builtin/commit.c:325
+#: builtin/commit.c:334
 msgid "unable to create temporary index"
 msgstr "kunde inte skapa temporär indexfil"
 
-#: builtin/commit.c:331
+#: builtin/commit.c:340
 msgid "interactive add failed"
 msgstr "interaktiv tilläggning misslyckades"
 
-#: builtin/commit.c:344
+#: builtin/commit.c:353
 msgid "unable to update temporary index"
 msgstr "kan inte uppdatera temporärt index"
 
-#: builtin/commit.c:346
+#: builtin/commit.c:355
 msgid "Failed to update main cache tree"
 msgstr "Misslyckades uppdatera huvud-cacheträdet"
 
-#: builtin/commit.c:371 builtin/commit.c:395 builtin/commit.c:444
+#: builtin/commit.c:380 builtin/commit.c:403 builtin/commit.c:449
 msgid "unable to write new_index file"
 msgstr "kunde inte skriva filen new_index"
 
-#: builtin/commit.c:427
+#: builtin/commit.c:432
 msgid "cannot do a partial commit during a merge."
 msgstr "kan inte utföra en delvis incheckning under en sammanslagning."
 
-#: builtin/commit.c:429
+#: builtin/commit.c:434
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "kan inte utföra en delvis incheckning under en cherry-pick."
 
-#: builtin/commit.c:437
+#: builtin/commit.c:442
 msgid "cannot read the index"
 msgstr "kan inte läsa indexet"
 
-#: builtin/commit.c:456
+#: builtin/commit.c:461
 msgid "unable to write temporary index file"
 msgstr "kunde inte skriva temporär indexfil"
 
-#: builtin/commit.c:553
+#: builtin/commit.c:558
 #, c-format
 msgid "commit '%s' lacks author header"
 msgstr "incheckningen \"%s\" saknar författarhuvud"
 
-#: builtin/commit.c:555
+#: builtin/commit.c:560
 #, c-format
 msgid "commit '%s' has malformed author line"
 msgstr "incheckningen \"%s\" har felformaterat författarhuvud"
 
-#: builtin/commit.c:574
+#: builtin/commit.c:579
 msgid "malformed --author parameter"
 msgstr "felformad \"--author\"-flagga"
 
-#: builtin/commit.c:626
+#: builtin/commit.c:631
 msgid ""
 "unable to select a comment character that is not used\n"
 "in the current commit message"
@@ -7396,38 +7790,38 @@ msgstr ""
 "kunde inte välja ett kommentarstecken som inte använts\n"
 "i det befintliga incheckningsmeddelandet"
 
-#: builtin/commit.c:663 builtin/commit.c:696 builtin/commit.c:1024
+#: builtin/commit.c:668 builtin/commit.c:701 builtin/commit.c:1029
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "kunde inte slå upp incheckningen %s"
 
-#: builtin/commit.c:675 builtin/shortlog.c:309
+#: builtin/commit.c:680 builtin/shortlog.c:316
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(läser loggmeddelande från standard in)\n"
 
-#: builtin/commit.c:677
+#: builtin/commit.c:682
 msgid "could not read log from standard input"
 msgstr "kunde inte läsa logg från standard in"
 
-#: builtin/commit.c:681
+#: builtin/commit.c:686
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "kunde inte läsa loggfilen \"%s\""
 
-#: builtin/commit.c:710 builtin/commit.c:718
+#: builtin/commit.c:715 builtin/commit.c:723
 msgid "could not read SQUASH_MSG"
 msgstr "kunde inte läsa SQUASH_MSG"
 
-#: builtin/commit.c:715
+#: builtin/commit.c:720
 msgid "could not read MERGE_MSG"
 msgstr "kunde inte läsa MERGE_MSG"
 
-#: builtin/commit.c:769
+#: builtin/commit.c:774
 msgid "could not write commit template"
 msgstr "kunde inte skriva incheckningsmall"
 
-#: builtin/commit.c:787
+#: builtin/commit.c:792
 #, c-format
 msgid ""
 "\n"
@@ -7442,7 +7836,7 @@ msgstr ""
 "\t%s\n"
 "och försöker igen.\n"
 
-#: builtin/commit.c:792
+#: builtin/commit.c:797
 #, c-format
 msgid ""
 "\n"
@@ -7457,7 +7851,7 @@ msgstr ""
 "\t%s\n"
 "och försöker igen.\n"
 
-#: builtin/commit.c:805
+#: builtin/commit.c:810
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7467,7 +7861,7 @@ msgstr ""
 "med \"%c\" kommer ignoreras, och ett tomt meddelande avbryter "
 "incheckningen.\n"
 
-#: builtin/commit.c:813
+#: builtin/commit.c:818
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7478,147 +7872,147 @@ msgstr ""
 "med \"%c\" kommer behållas; du kan själv ta bort dem om du vill.\n"
 "Ett tomt meddelande avbryter incheckningen.\n"
 
-#: builtin/commit.c:830
+#: builtin/commit.c:835
 #, c-format
 msgid "%sAuthor:    %.*s <%.*s>"
 msgstr "%sFörfattare: %.*s <%.*s>"
 
-#: builtin/commit.c:838
+#: builtin/commit.c:843
 #, c-format
 msgid "%sDate:      %s"
 msgstr "%sDatum:      %s"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:850
 #, c-format
 msgid "%sCommitter: %.*s <%.*s>"
 msgstr "%sIncheckare: %.*s <%.*s>"
 
-#: builtin/commit.c:862
+#: builtin/commit.c:867
 msgid "Cannot read index"
 msgstr "Kan inte läsa indexet"
 
-#: builtin/commit.c:928
+#: builtin/commit.c:933
 msgid "Error building trees"
 msgstr "Fel vid byggande av träd"
 
-#: builtin/commit.c:942 builtin/tag.c:256
+#: builtin/commit.c:947 builtin/tag.c:257
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "Ange meddelandet en av flaggorna -m eller -F.\n"
 
-#: builtin/commit.c:986
+#: builtin/commit.c:991
 #, c-format
 msgid "--author '%s' is not 'Name <email>' and matches no existing author"
 msgstr ""
 "--author '%s' är inte 'Namn <epost>' och matchar ingen befintlig författare"
 
-#: builtin/commit.c:1000
+#: builtin/commit.c:1005
 #, c-format
 msgid "Invalid ignored mode '%s'"
 msgstr "Ogiltigt ignorerat läge \"%s\""
 
-#: builtin/commit.c:1014 builtin/commit.c:1264
+#: builtin/commit.c:1019 builtin/commit.c:1269
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "Ogiltigt läge för ospårade filer: \"%s\""
 
-#: builtin/commit.c:1052
+#: builtin/commit.c:1057
 msgid "--long and -z are incompatible"
 msgstr "--long och -z är inkompatibla"
 
-#: builtin/commit.c:1085
+#: builtin/commit.c:1090
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "Kan inte använda både --reset-author och --author"
 
-#: builtin/commit.c:1094
+#: builtin/commit.c:1099
 msgid "You have nothing to amend."
 msgstr "Du har inget att utöka."
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1102
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "Du är i mitten av en sammanslagning -- kan inte utöka."
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1104
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "Du är i mitten av en cherry-pick -- kan inte utöka."
 
-#: builtin/commit.c:1102
+#: builtin/commit.c:1107
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "Flaggorna --squash och --fixup kan inte användas samtidigt"
 
-#: builtin/commit.c:1112
+#: builtin/commit.c:1117
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "Endast en av -c/-C/-F/--fixup kan användas."
 
-#: builtin/commit.c:1114
+#: builtin/commit.c:1119
 msgid "Option -m cannot be combined with -c/-C/-F."
 msgstr "Flaggan -m kan inte kombineras med -c/-C/-F."
 
-#: builtin/commit.c:1122
+#: builtin/commit.c:1127
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr "--reset-author kan endast användas med -C, -c eller --amend."
 
-#: builtin/commit.c:1139
+#: builtin/commit.c:1144
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr ""
 "Endast en av --include/--only/--all/--interactive/--patch kan användas."
 
-#: builtin/commit.c:1141
+#: builtin/commit.c:1146
 msgid "No paths with --include/--only does not make sense."
 msgstr "Du måste ange sökvägar tillsammans med --include/--only."
 
-#: builtin/commit.c:1155 builtin/tag.c:542
+#: builtin/commit.c:1160 builtin/tag.c:543
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Felaktigt städningsläge %s"
 
-#: builtin/commit.c:1160
+#: builtin/commit.c:1165
 msgid "Paths with -a does not make sense."
 msgstr "Kan inte ange sökvägar med -a."
 
-#: builtin/commit.c:1278 builtin/commit.c:1443
+#: builtin/commit.c:1303 builtin/commit.c:1480
 msgid "show status concisely"
 msgstr "visa koncis status"
 
-#: builtin/commit.c:1280 builtin/commit.c:1445
+#: builtin/commit.c:1305 builtin/commit.c:1482
 msgid "show branch information"
 msgstr "visa information om gren"
 
-#: builtin/commit.c:1282
+#: builtin/commit.c:1307
 msgid "show stash information"
 msgstr "visa information om stash"
 
-#: builtin/commit.c:1284 builtin/commit.c:1447
+#: builtin/commit.c:1309 builtin/commit.c:1484
 msgid "compute full ahead/behind values"
 msgstr "beräkna fullständiga före-/efter-värden"
 
-#: builtin/commit.c:1286
+#: builtin/commit.c:1311
 msgid "version"
 msgstr "version"
 
-#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542
-#: builtin/worktree.c:541
+#: builtin/commit.c:1311 builtin/commit.c:1486 builtin/push.c:558
+#: builtin/worktree.c:581
 msgid "machine-readable output"
 msgstr "maskinläsbar utdata"
 
-#: builtin/commit.c:1289 builtin/commit.c:1451
+#: builtin/commit.c:1314 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "visa status i långt format (standard)"
 
-#: builtin/commit.c:1292 builtin/commit.c:1454
+#: builtin/commit.c:1317 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "terminera poster med NUL"
 
-#: builtin/commit.c:1294 builtin/commit.c:1298 builtin/commit.c:1457
-#: builtin/fast-export.c:999 builtin/fast-export.c:1002 builtin/tag.c:396
+#: builtin/commit.c:1319 builtin/commit.c:1323 builtin/commit.c:1494
+#: builtin/fast-export.c:1001 builtin/fast-export.c:1004 builtin/tag.c:397
 msgid "mode"
 msgstr "läge"
 
-#: builtin/commit.c:1295 builtin/commit.c:1457
+#: builtin/commit.c:1320 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr "visa ospårade filer, valfria lägen: all, normal, no. (Standard: all)"
 
-#: builtin/commit.c:1299
+#: builtin/commit.c:1324
 msgid ""
 "show ignored files, optional modes: traditional, matching, no. (Default: "
 "traditional)"
@@ -7626,11 +8020,11 @@ msgstr ""
 "visa ignorerade filer, valfria lägen: traditional, matching, no (Standard: "
 "traditional)"
 
-#: builtin/commit.c:1301 parse-options.h:167
+#: builtin/commit.c:1326 parse-options.h:167
 msgid "when"
 msgstr "när"
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1327
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
@@ -7638,186 +8032,194 @@ msgstr ""
 "ignorera ändringar i undermoduler, valfritt när: all, dirty, untracked. "
 "(Default: all)"
 
-#: builtin/commit.c:1304
+#: builtin/commit.c:1329
 msgid "list untracked files in columns"
 msgstr "visa ospårade filer i spalter"
 
-#: builtin/commit.c:1323
+#: builtin/commit.c:1330
+msgid "do not detect renames"
+msgstr "detektera inte namnändringar"
+
+#: builtin/commit.c:1332
+msgid "detect renames, optionally set similarity index"
+msgstr "detektera namnändringar, möjligen sätt likhetsindex"
+
+#: builtin/commit.c:1352
 msgid "Unsupported combination of ignored and untracked-files arguments"
 msgstr "Kombinationen av argument för ignorerade och ospårade filer stöds ej"
 
-#: builtin/commit.c:1413
+#: builtin/commit.c:1450
 msgid "suppress summary after successful commit"
 msgstr "undertryck sammanfattning efter framgångsrik incheckning"
 
-#: builtin/commit.c:1414
+#: builtin/commit.c:1451
 msgid "show diff in commit message template"
 msgstr "visa diff i mallen för incheckningsmeddelandet"
 
-#: builtin/commit.c:1416
+#: builtin/commit.c:1453
 msgid "Commit message options"
 msgstr "Alternativ för incheckningsmeddelande"
 
-#: builtin/commit.c:1417 builtin/tag.c:393
+#: builtin/commit.c:1454 builtin/tag.c:394
 msgid "read message from file"
 msgstr "läs meddelande från fil"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "author"
 msgstr "författare"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "override author for commit"
 msgstr "överstyr författare för incheckningen"
 
-#: builtin/commit.c:1419 builtin/gc.c:359
+#: builtin/commit.c:1456 builtin/gc.c:501
 msgid "date"
 msgstr "datum"
 
-#: builtin/commit.c:1419
+#: builtin/commit.c:1456
 msgid "override date for commit"
 msgstr "överstyr datum för incheckningen"
 
-#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402
-#: builtin/notes.c:565 builtin/tag.c:391
+#: builtin/commit.c:1457 builtin/merge.c:228 builtin/notes.c:402
+#: builtin/notes.c:565 builtin/tag.c:392
 msgid "message"
 msgstr "meddelande"
 
-#: builtin/commit.c:1420
+#: builtin/commit.c:1457
 msgid "commit message"
 msgstr "incheckningsmeddelande"
 
-#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423
-#: builtin/commit.c:1424 parse-options.h:269 ref-filter.h:92
+#: builtin/commit.c:1458 builtin/commit.c:1459 builtin/commit.c:1460
+#: builtin/commit.c:1461 parse-options.h:270 ref-filter.h:92
 msgid "commit"
 msgstr "incheckning"
 
-#: builtin/commit.c:1421
+#: builtin/commit.c:1458
 msgid "reuse and edit message from specified commit"
 msgstr "återanvänd och redigera meddelande från angiven incheckning"
 
-#: builtin/commit.c:1422
+#: builtin/commit.c:1459
 msgid "reuse message from specified commit"
 msgstr "återanvänd meddelande från angiven incheckning"
 
-#: builtin/commit.c:1423
+#: builtin/commit.c:1460
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
 "använd autosquash-formaterat meddelande för att fixa angiven incheckning"
 
-#: builtin/commit.c:1424
+#: builtin/commit.c:1461
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
 "använd autosquash-formaterat meddelande för att slå ihop med angiven "
 "incheckning"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1462
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr "jag är nu författare av incheckningen (används med -C/-c/--amend)"
 
-#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240
-#: builtin/pull.c:149 builtin/revert.c:105
+#: builtin/commit.c:1463 builtin/log.c:1446 builtin/merge.c:242
+#: builtin/pull.c:154 builtin/revert.c:105
 msgid "add Signed-off-by:"
 msgstr "lägg till Signed-off-by:"
 
-#: builtin/commit.c:1427
+#: builtin/commit.c:1464
 msgid "use specified template file"
 msgstr "använd angiven mallfil"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1465
 msgid "force edit of commit"
 msgstr "tvinga redigering av incheckning"
 
-#: builtin/commit.c:1429
+#: builtin/commit.c:1466
 msgid "default"
 msgstr "standard"
 
-#: builtin/commit.c:1429 builtin/tag.c:397
+#: builtin/commit.c:1466 builtin/tag.c:398
 msgid "how to strip spaces and #comments from message"
 msgstr "hur blanksteg och #kommentarer skall tas bort från meddelande"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1467
 msgid "include status in commit message template"
 msgstr "inkludera status i mallen för incheckningsmeddelandet"
 
-#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179
+#: builtin/commit.c:1469 builtin/merge.c:240 builtin/pull.c:184
 #: builtin/revert.c:113
 msgid "GPG sign commit"
 msgstr "GPG-signera incheckning"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1472
 msgid "Commit contents options"
 msgstr "Alternativ för incheckningens innehåll"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1473
 msgid "commit all changed files"
 msgstr "checka in alla ändrade filer"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1474
 msgid "add specified files to index for commit"
 msgstr "lägg till angivna filer till indexet för incheckning"
 
-#: builtin/commit.c:1438
+#: builtin/commit.c:1475
 msgid "interactively add files"
 msgstr "lägg till filer interaktivt"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1476
 msgid "interactively add changes"
 msgstr "lägg till ändringar interaktivt"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1477
 msgid "commit only specified files"
 msgstr "checka endast in angivna filer"
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1478
 msgid "bypass pre-commit and commit-msg hooks"
 msgstr "förbigå pre-commit- och commit-msg-krokar"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1479
 msgid "show what would be committed"
 msgstr "visa vad som skulle checkas in"
 
-#: builtin/commit.c:1455
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "lägg till föregående incheckning"
 
-#: builtin/commit.c:1456
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "förbigå post-rewrite-krok"
 
-#: builtin/commit.c:1461
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "ok att registrera en tom ändring"
 
-#: builtin/commit.c:1463
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "ok att registrera en ändring med tomt meddelande"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1573
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Trasig MERGE_HEAD-fil (%s)"
 
-#: builtin/commit.c:1543
+#: builtin/commit.c:1580
 msgid "could not read MERGE_MODE"
 msgstr "kunde inte läsa MERGE_MODE"
 
-#: builtin/commit.c:1562
+#: builtin/commit.c:1599
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "kunde inte läsa incheckningsmeddelande: %s"
 
-#: builtin/commit.c:1573
+#: builtin/commit.c:1610
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "Avbryter på grund av tomt incheckningsmeddelande.\n"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1615
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "Avbryter incheckning; meddelandet inte redigerat.\n"
 
-#: builtin/commit.c:1613
+#: builtin/commit.c:1650
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full and quota is\n"
@@ -7828,147 +8230,211 @@ msgstr ""
 "att kvoten inte har överskridits, och kör sedan\n"
 "\"git reset HEAD\" för att återställa."
 
+#: builtin/commit-graph.c:9
+msgid "git commit-graph [--object-dir <objdir>]"
+msgstr "git commit-graph [--object-dir <objkat>]"
+
+#: builtin/commit-graph.c:10 builtin/commit-graph.c:16
+msgid "git commit-graph read [--object-dir <objdir>]"
+msgstr "git commit-graph read [--object-dir <objkat>]"
+
+#: builtin/commit-graph.c:11 builtin/commit-graph.c:21
+msgid ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+msgstr ""
+"git commit-graph write [--object-dir <objkat>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+
+#: builtin/commit-graph.c:39 builtin/commit-graph.c:92
+#: builtin/commit-graph.c:147 builtin/fetch.c:161 builtin/log.c:1466
+msgid "dir"
+msgstr "kat"
+
+#: builtin/commit-graph.c:40 builtin/commit-graph.c:93
+#: builtin/commit-graph.c:148
+msgid "The object directory to store the graph"
+msgstr "Objektkatalogen där grafen skall lagras"
+
+#: builtin/commit-graph.c:95
+msgid "scan pack-indexes listed by stdin for commits"
+msgstr "sök paketindex listade på standard in efter incheckningar"
+
+#: builtin/commit-graph.c:97
+msgid "start walk at commits listed by stdin"
+msgstr "börja gå genom incheckningar listade på standard in"
+
+#: builtin/commit-graph.c:99
+msgid "include all commits already in the commit-graph file"
+msgstr "ta med alla incheckningar redan i filen commit-graph"
+
+#: builtin/commit-graph.c:108
+msgid "cannot use both --stdin-commits and --stdin-packs"
+msgstr "kan inte använda både --stdin-commit och --stdin-packs"
+
 #: builtin/config.c:10
 msgid "git config [<options>]"
 msgstr "git config [<flaggor>]"
 
-#: builtin/config.c:58
+#: builtin/config.c:101
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "okänt argument för --type, %s"
+
+#: builtin/config.c:123
 msgid "Config file location"
 msgstr "Konfigurationsfilens plats"
 
-#: builtin/config.c:59
+#: builtin/config.c:124
 msgid "use global config file"
 msgstr "använd global konfigurationsfil"
 
-#: builtin/config.c:60
+#: builtin/config.c:125
 msgid "use system config file"
 msgstr "använd systemets konfigurationsfil"
 
-#: builtin/config.c:61
+#: builtin/config.c:126
 msgid "use repository config file"
 msgstr "använd arkivets konfigurationsfil"
 
-#: builtin/config.c:62
+#: builtin/config.c:127
 msgid "use given config file"
 msgstr "använd angiven konfigurationsfil"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "blob-id"
 msgstr "blob-id"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "read config from given blob object"
 msgstr "läs konfiguration från givet blob-objekt"
 
-#: builtin/config.c:64
+#: builtin/config.c:129
 msgid "Action"
 msgstr "Åtgärd"
 
-#: builtin/config.c:65
+#: builtin/config.c:130
 msgid "get value: name [value-regex]"
 msgstr "hämta värde: namn [värde-reguttr]"
 
-#: builtin/config.c:66
+#: builtin/config.c:131
 msgid "get all values: key [value-regex]"
 msgstr "hämta alla värden: nyckel [värde-reguttr]"
 
-#: builtin/config.c:67
+#: builtin/config.c:132
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr "hämta värden för reguttr: namn-reguttr [värde-reguttr]"
 
-#: builtin/config.c:68
+#: builtin/config.c:133
 msgid "get value specific for the URL: section[.var] URL"
 msgstr "hämta värde specifikt URL:en: sektion[.var] URL"
 
-#: builtin/config.c:69
+#: builtin/config.c:134
 msgid "replace all matching variables: name value [value_regex]"
 msgstr "ersätt alla motsvarande variabler: namn värde [värde-reguttr]"
 
-#: builtin/config.c:70
+#: builtin/config.c:135
 msgid "add a new variable: name value"
 msgstr "lägg till en ny variabel: namn värde"
 
-#: builtin/config.c:71
+#: builtin/config.c:136
 msgid "remove a variable: name [value-regex]"
 msgstr "ta bort en variabel: namn [värde-reguttr]"
 
-#: builtin/config.c:72
+#: builtin/config.c:137
 msgid "remove all matches: name [value-regex]"
 msgstr "ta bort alla träffar: namn [värde-reguttr]"
 
-#: builtin/config.c:73
+#: builtin/config.c:138
 msgid "rename section: old-name new-name"
 msgstr "byt namn på sektion: gammalt-namn nytt-namn"
 
-#: builtin/config.c:74
+#: builtin/config.c:139
 msgid "remove a section: name"
 msgstr "ta bort en sektion: namn"
 
-#: builtin/config.c:75
+#: builtin/config.c:140
 msgid "list all"
 msgstr "visa alla"
 
-#: builtin/config.c:76
+#: builtin/config.c:141
 msgid "open an editor"
 msgstr "öppna textredigeringsprogram"
 
-#: builtin/config.c:77
+#: builtin/config.c:142
 msgid "find the color configured: slot [default]"
 msgstr "hitta den inställda färgen: slot [default]"
 
-#: builtin/config.c:78
+#: builtin/config.c:143
 msgid "find the color setting: slot [stdout-is-tty]"
 msgstr "hitta färginställningen: slot [stdout-is-tty]"
 
-#: builtin/config.c:79
+#: builtin/config.c:144
 msgid "Type"
 msgstr "Typ"
 
-#: builtin/config.c:80
+#: builtin/config.c:145
+msgid "value is given this type"
+msgstr "värdet har givits denna typ"
+
+#: builtin/config.c:146
 msgid "value is \"true\" or \"false\""
 msgstr "värdet är \"true\" eller \"false\""
 
-#: builtin/config.c:81
+#: builtin/config.c:147
 msgid "value is decimal number"
 msgstr "värdet är ett decimalt tal"
 
-#: builtin/config.c:82
+#: builtin/config.c:148
 msgid "value is --bool or --int"
 msgstr "värdet är --bool eller --int"
 
-#: builtin/config.c:83
+#: builtin/config.c:149
 msgid "value is a path (file or directory name)"
 msgstr "värdet är en sökväg (fil- eller katalognamn)"
 
-#: builtin/config.c:84
+#: builtin/config.c:150
 msgid "value is an expiry date"
 msgstr "värdet är ett utgångsdatum"
 
-#: builtin/config.c:85
+#: builtin/config.c:151
 msgid "Other"
 msgstr "Andra"
 
-#: builtin/config.c:86
+#: builtin/config.c:152
 msgid "terminate values with NUL byte"
 msgstr "terminera värden med NUL-byte"
 
-#: builtin/config.c:87
+#: builtin/config.c:153
 msgid "show variable names only"
 msgstr "visa endast variabelnamn"
 
-#: builtin/config.c:88
+#: builtin/config.c:154
 msgid "respect include directives on lookup"
 msgstr "respektera inkluderingsdirektiv vid uppslag"
 
-#: builtin/config.c:89
+#: builtin/config.c:155
 msgid "show origin of config (file, standard input, blob, command line)"
 msgstr "visa konfigurationskälla (fil, standard in, blob, kommandorad)"
 
-#: builtin/config.c:335
+#: builtin/config.c:156
+msgid "value"
+msgstr "värde"
+
+#: builtin/config.c:156
+msgid "with --get, use default value when missing entry"
+msgstr "med --get, använd standardvärde vid saknad post"
+
+#: builtin/config.c:332
+#, c-format
+msgid "failed to format default config value: %s"
+msgstr "misslyckades formatera standardkonfigurationsvärde: %s"
+
+#: builtin/config.c:431
 msgid "unable to parse default color value"
 msgstr "kan inte tolka standardfärgvärde"
 
-#: builtin/config.c:479
+#: builtin/config.c:575
 #, c-format
 msgid ""
 "# This is Git's per-user configuration file.\n"
@@ -7983,16 +8449,20 @@ msgstr ""
 "#\tname = %s\n"
 "#\temail = %s\n"
 
-#: builtin/config.c:507
+#: builtin/config.c:603
 msgid "--local can only be used inside a git repository"
 msgstr "--local kan bara användas inuti ett git-arkiv"
 
-#: builtin/config.c:632
+#: builtin/config.c:606
+msgid "--blob can only be used inside a git repository"
+msgstr "--blob kan bara användas inuti ett git-arkiv"
+
+#: builtin/config.c:735
 #, c-format
 msgid "cannot create configuration file %s"
 msgstr "kan inte skapa konfigurationsfilen \"%s\""
 
-#: builtin/config.c:645
+#: builtin/config.c:748
 #, c-format
 msgid ""
 "cannot overwrite multiple values with a single value\n"
@@ -8001,11 +8471,11 @@ msgstr ""
 "kan inte skriva över flera värden med ett ensamt värde\n"
 "       Använd en regexp, --add eller --replace-all för att ändra %s."
 
-#: builtin/count-objects.c:88
+#: builtin/count-objects.c:90
 msgid "git count-objects [-v] [-H | --human-readable]"
 msgstr "git count-objects [-v] [-H | --human-readable]"
 
-#: builtin/count-objects.c:98
+#: builtin/count-objects.c:100
 msgid "print sizes in human readable format"
 msgstr "skriv storlekar i människoläsbart format"
 
@@ -8271,23 +8741,23 @@ msgstr "utför diff för hela katalogen"
 msgid "do not prompt before launching a diff tool"
 msgstr "fråga inte vid start av diff-verktyg"
 
-#: builtin/difftool.c:705
+#: builtin/difftool.c:704
 msgid "use symlinks in dir-diff mode"
 msgstr "använd symboliska länkar i katalogdiffläge"
 
-#: builtin/difftool.c:706
+#: builtin/difftool.c:705
 msgid "<tool>"
 msgstr "<verktyg>"
 
-#: builtin/difftool.c:707
+#: builtin/difftool.c:706
 msgid "use the specified diff tool"
 msgstr "använd angivet diff-verktyg"
 
-#: builtin/difftool.c:709
+#: builtin/difftool.c:708
 msgid "print a list of diff tools that may be used with `--tool`"
 msgstr "visa en lista över diff-verktyg som kan användas med ”--tool”"
 
-#: builtin/difftool.c:712
+#: builtin/difftool.c:711
 msgid ""
 "make 'git-difftool' exit when an invoked diff tool returns a non - zero exit "
 "code"
@@ -8295,168 +8765,164 @@ msgstr ""
 "låt \"git-difftool\" avbryta när ett anropat diff-verktyg ger returvärde "
 "skilt från noll"
 
-#: builtin/difftool.c:714
+#: builtin/difftool.c:713
 msgid "<command>"
 msgstr "<kommando>"
 
-#: builtin/difftool.c:715
+#: builtin/difftool.c:714
 msgid "specify a custom command for viewing diffs"
 msgstr "ange eget kommando för att visa diffar"
 
-#: builtin/difftool.c:739
+#: builtin/difftool.c:738
 msgid "no <tool> given for --tool=<tool>"
 msgstr "inget <verktyg> angavs för --tool=<verktyg>"
 
-#: builtin/difftool.c:746
+#: builtin/difftool.c:745
 msgid "no <cmd> given for --extcmd=<cmd>"
 msgstr "inget <kommando> angavs för --extcmd=<kommando>"
 
-#: builtin/fast-export.c:26
+#: builtin/fast-export.c:27
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [rev-list-flaggor]"
 
-#: builtin/fast-export.c:998
+#: builtin/fast-export.c:1000
 msgid "show progress after <n> objects"
 msgstr "visa förlopp efter <n> objekt"
 
-#: builtin/fast-export.c:1000
+#: builtin/fast-export.c:1002
 msgid "select handling of signed tags"
 msgstr "välj hantering av signerade taggar"
 
-#: builtin/fast-export.c:1003
+#: builtin/fast-export.c:1005
 msgid "select handling of tags that tag filtered objects"
 msgstr "välj hantering av taggar som har taggfiltrerade objekt"
 
-#: builtin/fast-export.c:1006
+#: builtin/fast-export.c:1008
 msgid "Dump marks to this file"
 msgstr "Dump märken till filen"
 
-#: builtin/fast-export.c:1008
+#: builtin/fast-export.c:1010
 msgid "Import marks from this file"
 msgstr "Importera märken från filen"
 
-#: builtin/fast-export.c:1010
+#: builtin/fast-export.c:1012
 msgid "Fake a tagger when tags lack one"
 msgstr "Fejka taggare när taggen saknar en"
 
-#: builtin/fast-export.c:1012
+#: builtin/fast-export.c:1014
 msgid "Output full tree for each commit"
 msgstr "Skriv ut hela trädet för varje incheckning"
 
-#: builtin/fast-export.c:1014
+#: builtin/fast-export.c:1016
 msgid "Use the done feature to terminate the stream"
 msgstr "Använd done-funktionen för att avsluta strömmen"
 
-#: builtin/fast-export.c:1015
+#: builtin/fast-export.c:1017
 msgid "Skip output of blob data"
 msgstr "Hoppa över skrivning av blob-data"
 
-#: builtin/fast-export.c:1016
+#: builtin/fast-export.c:1018
 msgid "refspec"
 msgstr "referensspecifikation"
 
-#: builtin/fast-export.c:1017
+#: builtin/fast-export.c:1019
 msgid "Apply refspec to exported refs"
 msgstr "Applicera referensspecifikation på exporterade referenser"
 
-#: builtin/fast-export.c:1018
+#: builtin/fast-export.c:1020
 msgid "anonymize output"
 msgstr "anonymisera utdata"
 
-#: builtin/fetch.c:25
+#: builtin/fetch.c:26
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
 msgstr "git fetch [<flaggor>] [<arkiv> [<refspec>...]]"
 
-#: builtin/fetch.c:26
+#: builtin/fetch.c:27
 msgid "git fetch [<options>] <group>"
 msgstr "git fetch [<flaggor>] <grupp>"
 
-#: builtin/fetch.c:27
+#: builtin/fetch.c:28
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
 msgstr "git fetch --multiple [<flaggor>] [(<arkiv> | <grupp>)...]"
 
-#: builtin/fetch.c:28
+#: builtin/fetch.c:29
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<flaggor>]"
 
-#: builtin/fetch.c:124 builtin/pull.c:188
+#: builtin/fetch.c:123 builtin/pull.c:193
 msgid "fetch from all remotes"
 msgstr "hämta från alla fjärrar"
 
-#: builtin/fetch.c:126 builtin/pull.c:191
+#: builtin/fetch.c:125 builtin/pull.c:196
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "lägg till i .git/FETCH_HEAD istället för att skriva över"
 
-#: builtin/fetch.c:128 builtin/pull.c:194
+#: builtin/fetch.c:127 builtin/pull.c:199
 msgid "path to upload pack on remote end"
 msgstr "sökväg till upload pack på fjärren"
 
-#: builtin/fetch.c:129 builtin/pull.c:196
+#: builtin/fetch.c:128 builtin/pull.c:201
 msgid "force overwrite of local branch"
 msgstr "tvinga överskrivning av lokal gren"
 
-#: builtin/fetch.c:131
+#: builtin/fetch.c:130
 msgid "fetch from multiple remotes"
 msgstr "hämta från flera fjärrar"
 
-#: builtin/fetch.c:133 builtin/pull.c:198
+#: builtin/fetch.c:132 builtin/pull.c:203
 msgid "fetch all tags and associated objects"
 msgstr "hämta alla taggar och associerade objekt"
 
-#: builtin/fetch.c:135
+#: builtin/fetch.c:134
 msgid "do not fetch all tags (--no-tags)"
 msgstr "hämta inte alla taggar (--no-tags)"
 
-#: builtin/fetch.c:137
+#: builtin/fetch.c:136
 msgid "number of submodules fetched in parallel"
 msgstr "antal undermoduler som hämtas parallellt"
 
-#: builtin/fetch.c:139 builtin/pull.c:201
+#: builtin/fetch.c:138 builtin/pull.c:206
 msgid "prune remote-tracking branches no longer on remote"
 msgstr "rensa fjärrspårande grenar ej längre på fjärren"
 
-#: builtin/fetch.c:141
+#: builtin/fetch.c:140
 msgid "prune local tags no longer on remote and clobber changed tags"
 msgstr ""
 "rensa lokala taggar inte längre på fjärren och skriv över ändrade taggar"
 
-#: builtin/fetch.c:142 builtin/fetch.c:165 builtin/pull.c:126
+#: builtin/fetch.c:141 builtin/fetch.c:164 builtin/pull.c:131
 msgid "on-demand"
 msgstr "on-demand"
 
-#: builtin/fetch.c:143
+#: builtin/fetch.c:142
 msgid "control recursive fetching of submodules"
 msgstr "styr rekursiv hämtning av undermoduler"
 
-#: builtin/fetch.c:147 builtin/pull.c:209
+#: builtin/fetch.c:146 builtin/pull.c:214
 msgid "keep downloaded pack"
 msgstr "behåll hämtade paket"
 
-#: builtin/fetch.c:149
+#: builtin/fetch.c:148
 msgid "allow updating of HEAD ref"
 msgstr "tillåt uppdatering av HEAD-referens"
 
-#: builtin/fetch.c:152 builtin/fetch.c:158 builtin/pull.c:212
+#: builtin/fetch.c:151 builtin/fetch.c:157 builtin/pull.c:217
 msgid "deepen history of shallow clone"
 msgstr "fördjupa historik för grund klon"
 
-#: builtin/fetch.c:154
+#: builtin/fetch.c:153
 msgid "deepen history of shallow repository based on time"
 msgstr "fördjupa historik för grund klon baserad på tid"
 
-#: builtin/fetch.c:160 builtin/pull.c:215
+#: builtin/fetch.c:159 builtin/pull.c:220
 msgid "convert to a complete repository"
 msgstr "konvertera till komplett arkiv"
 
-#: builtin/fetch.c:162 builtin/log.c:1466
-msgid "dir"
-msgstr "kat"
-
-#: builtin/fetch.c:163
+#: builtin/fetch.c:162
 msgid "prepend this to submodule path output"
 msgstr "lägg till i början av undermodulens sökvägsutdata"
 
-#: builtin/fetch.c:166
+#: builtin/fetch.c:165
 msgid ""
 "default for recursive fetching of submodules (lower priority than config "
 "files)"
@@ -8464,89 +8930,101 @@ msgstr ""
 "standard för rekursiv hämtning av undermoduler (lägre prioritet än "
 "konfigurationsfiler)"
 
-#: builtin/fetch.c:170 builtin/pull.c:218
+#: builtin/fetch.c:169 builtin/pull.c:223
 msgid "accept refs that update .git/shallow"
 msgstr "tar emot referenser som uppdaterar .git/shallow"
 
-#: builtin/fetch.c:171 builtin/pull.c:220
+#: builtin/fetch.c:170 builtin/pull.c:225
 msgid "refmap"
 msgstr "referenskarta"
 
-#: builtin/fetch.c:172 builtin/pull.c:221
+#: builtin/fetch.c:171 builtin/pull.c:226
 msgid "specify fetch refmap"
 msgstr "ange referenskarta för \"fetch\""
 
-#: builtin/fetch.c:431
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:172
+msgid "server-specific"
+msgstr "serverspecifik"
+
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:173
+msgid "option to transmit"
+msgstr ""
+"inget att checka in\n"
+"flagga att sända"
+
+#: builtin/fetch.c:442
 msgid "Couldn't find remote ref HEAD"
 msgstr "Kunde inte hitta fjärr-referensen HEAD"
 
-#: builtin/fetch.c:549
+#: builtin/fetch.c:560
 #, c-format
 msgid "configuration fetch.output contains invalid value %s"
 msgstr "konfigurationen för fetch.output innehåller ogiltigt värde %s"
 
-#: builtin/fetch.c:642
+#: builtin/fetch.c:653
 #, c-format
 msgid "object %s not found"
 msgstr "objektet %s hittades inte"
 
-#: builtin/fetch.c:646
+#: builtin/fetch.c:657
 msgid "[up to date]"
 msgstr "[àjour]"
 
-#: builtin/fetch.c:659 builtin/fetch.c:739
+#: builtin/fetch.c:670 builtin/fetch.c:750
 msgid "[rejected]"
 msgstr "[refuserad]"
 
-#: builtin/fetch.c:660
+#: builtin/fetch.c:671
 msgid "can't fetch in current branch"
 msgstr "kan inte hämta i aktuell gren"
 
-#: builtin/fetch.c:669
+#: builtin/fetch.c:680
 msgid "[tag update]"
 msgstr "[uppdaterad tagg]"
 
-#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719
-#: builtin/fetch.c:734
+#: builtin/fetch.c:681 builtin/fetch.c:714 builtin/fetch.c:730
+#: builtin/fetch.c:745
 msgid "unable to update local ref"
 msgstr "kunde inte uppdatera lokal ref"
 
-#: builtin/fetch.c:689
+#: builtin/fetch.c:700
 msgid "[new tag]"
 msgstr "[ny tagg]"
 
-#: builtin/fetch.c:692
+#: builtin/fetch.c:703
 msgid "[new branch]"
 msgstr "[ny gren]"
 
-#: builtin/fetch.c:695
+#: builtin/fetch.c:706
 msgid "[new ref]"
 msgstr "[ny ref]"
 
-#: builtin/fetch.c:734
+#: builtin/fetch.c:745
 msgid "forced update"
 msgstr "tvingad uppdatering"
 
-#: builtin/fetch.c:739
+#: builtin/fetch.c:750
 msgid "non-fast-forward"
 msgstr "ej snabbspolad"
 
-#: builtin/fetch.c:784
+#: builtin/fetch.c:795
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "%s sände inte alla nödvändiga objekt\n"
 
-#: builtin/fetch.c:804
+#: builtin/fetch.c:815
 #, c-format
 msgid "reject %s because shallow roots are not allowed to be updated"
 msgstr "avvisa %s då grunda rötter inte kan uppdateras"
 
-#: builtin/fetch.c:892 builtin/fetch.c:988
+#: builtin/fetch.c:903 builtin/fetch.c:999
 #, c-format
 msgid "From %.*s\n"
 msgstr "Från %.*s\n"
 
-#: builtin/fetch.c:903
+#: builtin/fetch.c:914
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -8555,56 +9033,56 @@ msgstr ""
 "vissa lokala referenser kunde inte uppdateras; testa att köra\n"
 " \"git remote prune %s\" för att ta bort gamla grenar som står i konflikt"
 
-#: builtin/fetch.c:958
+#: builtin/fetch.c:969
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (%s kommer bli dinglande)"
 
-#: builtin/fetch.c:959
+#: builtin/fetch.c:970
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (%s har blivit dinglande)"
 
-#: builtin/fetch.c:991
+#: builtin/fetch.c:1002
 msgid "[deleted]"
 msgstr "[borttagen]"
 
-#: builtin/fetch.c:992 builtin/remote.c:1024
+#: builtin/fetch.c:1003 builtin/remote.c:1033
 msgid "(none)"
 msgstr "(ingen)"
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1026
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr "Vägrar hämta till aktuell gren %s i ett icke-naket arkiv"
 
-#: builtin/fetch.c:1034
+#: builtin/fetch.c:1045
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr "Flaggan \"%s\" och värdet \"%s\" är inte giltigt för %s"
 
-#: builtin/fetch.c:1037
+#: builtin/fetch.c:1048
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "Flaggan \"%s\" ignoreras för %s\n"
 
-#: builtin/fetch.c:1277
+#: builtin/fetch.c:1287
 #, c-format
 msgid "Fetching %s\n"
 msgstr "Hämtar %s\n"
 
-#: builtin/fetch.c:1279 builtin/remote.c:97
+#: builtin/fetch.c:1289 builtin/remote.c:98
 #, c-format
 msgid "Could not fetch %s"
 msgstr "Kunde inte hämta %s"
 
-#: builtin/fetch.c:1325 builtin/fetch.c:1498
+#: builtin/fetch.c:1335 builtin/fetch.c:1503
 msgid ""
 "--filter can only be used with the remote configured in core.partialClone"
 msgstr ""
 "--filter kan endast användas med fjärren konfigurerad i core.partialClone"
 
-#: builtin/fetch.c:1350
+#: builtin/fetch.c:1358
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
@@ -8612,40 +9090,40 @@ msgstr ""
 "Inget fjärrarkiv angavs. Ange antingen en URL eller namnet på ett\n"
 "fjärrarkiv som nya incheckningar skall hämtas från."
 
-#: builtin/fetch.c:1394
+#: builtin/fetch.c:1395
 msgid "You need to specify a tag name."
 msgstr "Du måste ange namnet på en tagg."
 
-#: builtin/fetch.c:1439
+#: builtin/fetch.c:1444
 msgid "Negative depth in --deepen is not supported"
 msgstr "Negativa djup stöds inte i --deepen"
 
-#: builtin/fetch.c:1441
+#: builtin/fetch.c:1446
 msgid "--deepen and --depth are mutually exclusive"
 msgstr "--deepen och --depth är ömsesidigt uteslutande"
 
-#: builtin/fetch.c:1446
+#: builtin/fetch.c:1451
 msgid "--depth and --unshallow cannot be used together"
 msgstr "--depth och --unshallow kan inte användas samtidigt"
 
-#: builtin/fetch.c:1448
+#: builtin/fetch.c:1453
 msgid "--unshallow on a complete repository does not make sense"
 msgstr "--unshallow kan inte användas på ett komplett arkiv"
 
-#: builtin/fetch.c:1464
+#: builtin/fetch.c:1469
 msgid "fetch --all does not take a repository argument"
 msgstr "fetch --all tar inte namnet på ett arkiv som argument"
 
-#: builtin/fetch.c:1466
+#: builtin/fetch.c:1471
 msgid "fetch --all does not make sense with refspecs"
 msgstr "fetch --all kan inte anges med referensspecifikationer"
 
-#: builtin/fetch.c:1475
+#: builtin/fetch.c:1480
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "Fjärren eller fjärrgruppen finns inte: %s"
 
-#: builtin/fetch.c:1482
+#: builtin/fetch.c:1487
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr "Kan inte hämta från grupp och ange referensspecifikationer"
 
@@ -8712,7 +9190,7 @@ msgstr "citera platshållare passande för Tcl"
 msgid "show only <n> matched refs"
 msgstr "visa endast <n> träffade refs"
 
-#: builtin/for-each-ref.c:39 builtin/tag.c:420
+#: builtin/for-each-ref.c:39 builtin/tag.c:421
 msgid "respect format colors"
 msgstr "använd formatfärger"
 
@@ -8736,83 +9214,83 @@ msgstr "visa endast referenser som innehåller incheckningen"
 msgid "print only refs which don't contain the commit"
 msgstr "visa endast referenser som inte innehåller incheckningen"
 
-#: builtin/fsck.c:568
+#: builtin/fsck.c:569
 msgid "Checking object directories"
 msgstr "Kontrollerar objektkataloger"
 
-#: builtin/fsck.c:660
+#: builtin/fsck.c:661
 msgid "git fsck [<options>] [<object>...]"
 msgstr "git fsck [<flaggor>] [<objekt>...]"
 
-#: builtin/fsck.c:666
+#: builtin/fsck.c:667
 msgid "show unreachable objects"
 msgstr "visa onåbara objekt"
 
-#: builtin/fsck.c:667
+#: builtin/fsck.c:668
 msgid "show dangling objects"
 msgstr "visa dinglande objekt"
 
-#: builtin/fsck.c:668
+#: builtin/fsck.c:669
 msgid "report tags"
 msgstr "rapportera taggar"
 
-#: builtin/fsck.c:669
+#: builtin/fsck.c:670
 msgid "report root nodes"
 msgstr "rapportera rotnoder"
 
-#: builtin/fsck.c:670
+#: builtin/fsck.c:671
 msgid "make index objects head nodes"
 msgstr "gör indexojekt till huvudnoder"
 
-#: builtin/fsck.c:671
+#: builtin/fsck.c:672
 msgid "make reflogs head nodes (default)"
 msgstr "gör refloggar till huvudnoder (standard)"
 
-#: builtin/fsck.c:672
+#: builtin/fsck.c:673
 msgid "also consider packs and alternate objects"
 msgstr "ta även hänsyn till paket och alternativa objekt"
 
 # Vague original, not networking-related, but rather related to the actual
 # objects in the database.
-#: builtin/fsck.c:673
+#: builtin/fsck.c:674
 msgid "check only connectivity"
 msgstr "kontrollera endast konnektivitet"
 
-#: builtin/fsck.c:674
+#: builtin/fsck.c:675
 msgid "enable more strict checking"
 msgstr "aktivera striktare kontroll"
 
-#: builtin/fsck.c:676
+#: builtin/fsck.c:677
 msgid "write dangling objects in .git/lost-found"
 msgstr "skriv dinglande objekt i .git/lost-found"
 
-#: builtin/fsck.c:677 builtin/prune.c:108
+#: builtin/fsck.c:678 builtin/prune.c:109
 msgid "show progress"
 msgstr "visa förlopp"
 
-#: builtin/fsck.c:678
+#: builtin/fsck.c:679
 msgid "show verbose names for reachable objects"
 msgstr "visa ordrika namn för nåbara objekt"
 
-#: builtin/fsck.c:742
+#: builtin/fsck.c:745
 msgid "Checking objects"
 msgstr "Kontrollerar objekt"
 
-#: builtin/gc.c:27
+#: builtin/gc.c:33
 msgid "git gc [<options>]"
 msgstr "git gc [<flaggor>]"
 
-#: builtin/gc.c:80
+#: builtin/gc.c:88
 #, c-format
 msgid "Failed to fstat %s: %s"
 msgstr "Misslyckades ta status (fstat) på %s: %s"
 
-#: builtin/gc.c:312
+#: builtin/gc.c:452
 #, c-format
 msgid "Can't stat %s"
 msgstr "Kan inte ta status på %s"
 
-#: builtin/gc.c:321
+#: builtin/gc.c:461
 #, c-format
 msgid ""
 "The last gc run reported the following. Please correct the root cause\n"
@@ -8827,43 +9305,52 @@ msgstr ""
 "\n"
 "%s"
 
-#: builtin/gc.c:360
+#: builtin/gc.c:502
 msgid "prune unreferenced objects"
 msgstr "rensa ej refererade objekt"
 
-#: builtin/gc.c:362
+#: builtin/gc.c:504
 msgid "be more thorough (increased runtime)"
 msgstr "var mer grundlig (ökar körtiden)"
 
-#: builtin/gc.c:363
+#: builtin/gc.c:505
 msgid "enable auto-gc mode"
 msgstr "aktivera auto-gc-läge"
 
-#: builtin/gc.c:366
+#: builtin/gc.c:508
 msgid "force running gc even if there may be another gc running"
 msgstr "tvinga gc-körning även om en annan gc kanske körs"
 
-#: builtin/gc.c:384
+#: builtin/gc.c:511
+msgid "repack all other packs except the largest pack"
+msgstr "packa om alla paket förutom det största paketet"
+
+#: builtin/gc.c:528
+#, c-format
+msgid "failed to parse gc.logexpiry value %s"
+msgstr "kunde inte tolka värdet %s för gc.logexpiry"
+
+#: builtin/gc.c:539
 #, c-format
-msgid "Failed to parse gc.logexpiry value %s"
-msgstr "Kan inte tolka värdet %s för gc.logexpiry"
+msgid "failed to parse prune expiry value %s"
+msgstr "kunde inte tolka värdet %s för prune expiry"
 
-#: builtin/gc.c:412
+#: builtin/gc.c:559
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
 msgstr "Packar arkivet automatiskt i bakgrunden för optimal prestanda.\n"
 
-#: builtin/gc.c:414
+#: builtin/gc.c:561
 #, c-format
 msgid "Auto packing the repository for optimum performance.\n"
 msgstr "Packar arkivet automatiskt för optimal prestanda.\n"
 
-#: builtin/gc.c:415
+#: builtin/gc.c:562
 #, c-format
 msgid "See \"git help gc\" for manual housekeeping.\n"
 msgstr "Se \"git help gc\" för manuell hushållning.\n"
 
-#: builtin/gc.c:440
+#: builtin/gc.c:598
 #, c-format
 msgid ""
 "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
@@ -8871,23 +9358,23 @@ msgstr ""
 "gc körs redan på maskinen \"%s\" pid %<PRIuMAX> (använd --force om så inte "
 "är fallet)"
 
-#: builtin/gc.c:487
+#: builtin/gc.c:645
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr ""
 "Det finns för många onåbara lösa objekt; kör \"git prune\" för att ta bort "
 "dem."
 
-#: builtin/grep.c:27
+#: builtin/grep.c:28
 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [<flaggor>] [-e] <mönster> [<rev>...] [[--] <sökväg>...]"
 
-#: builtin/grep.c:225
+#: builtin/grep.c:226
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep: misslyckades skapa tråd. %s"
 
-#: builtin/grep.c:283
+#: builtin/grep.c:284
 #, c-format
 msgid "invalid number of threads specified (%d) for %s"
 msgstr "felaktigt antal trådar angivet (%d) för %s"
@@ -8896,17 +9383,17 @@ msgstr "felaktigt antal trådar angivet (%d) för %s"
 #. variable for tweaking threads, currently
 #. grep.threads
 #.
-#: builtin/grep.c:292 builtin/index-pack.c:1523 builtin/index-pack.c:1712
+#: builtin/grep.c:293 builtin/index-pack.c:1531 builtin/index-pack.c:1723
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "trådstöd saknas, ignorerar %s"
 
-#: builtin/grep.c:460 builtin/grep.c:580 builtin/grep.c:622
+#: builtin/grep.c:461 builtin/grep.c:582 builtin/grep.c:623
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "kunde inte läsa träd (%s)"
 
-#: builtin/grep.c:637
+#: builtin/grep.c:638
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "kunde inte \"grep\" från objekt av typen %s"
@@ -9105,7 +9592,7 @@ msgstr "--no-index och --untracked kan inte användas med revisioner"
 msgid "unable to resolve revision: %s"
 msgstr "kan inte slå upp revision: %s"
 
-#: builtin/grep.c:1036 builtin/index-pack.c:1519
+#: builtin/grep.c:1036 builtin/index-pack.c:1527
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "felaktigt antal trådar angivet (%d)"
@@ -9176,58 +9663,62 @@ msgstr ""
 msgid "process file as it were from this path"
 msgstr "hantera filen som om den kom från sökvägen"
 
-#: builtin/help.c:43
+#: builtin/help.c:45
 msgid "print all available commands"
 msgstr "visa alla tillgängliga kommandon"
 
-#: builtin/help.c:44
+#: builtin/help.c:46
 msgid "exclude guides"
 msgstr "uteslut vägledningar"
 
-#: builtin/help.c:45
+#: builtin/help.c:47
 msgid "print list of useful guides"
 msgstr "lista användbara vägledningar"
 
-#: builtin/help.c:46
+#: builtin/help.c:48
 msgid "show man page"
 msgstr "visa manualsida"
 
-#: builtin/help.c:47
+#: builtin/help.c:49
 msgid "show manual in web browser"
 msgstr "visa manual i webbläsare"
 
-#: builtin/help.c:49
+#: builtin/help.c:51
 msgid "show info page"
 msgstr "visa info-sida"
 
-#: builtin/help.c:55
+#: builtin/help.c:53
+msgid "print command description"
+msgstr "visa kommandobeskrivning"
+
+#: builtin/help.c:58
 msgid "git help [--all] [--guides] [--man | --web | --info] [<command>]"
 msgstr "git help [--all] [--guides] [--man | --web | --info] [<kommando>]"
 
-#: builtin/help.c:67
+#: builtin/help.c:70
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "okänt hjälpformat: ”%s”"
 
-#: builtin/help.c:94
+#: builtin/help.c:97
 msgid "Failed to start emacsclient."
 msgstr "Misslyckades starta emacsclient."
 
-#: builtin/help.c:107
+#: builtin/help.c:110
 msgid "Failed to parse emacsclient version."
 msgstr "Kunde inte tolka emacsclient-version."
 
-#: builtin/help.c:115
+#: builtin/help.c:118
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "emacsclient version \"%d\" för gammal (< 22)."
 
-#: builtin/help.c:133 builtin/help.c:155 builtin/help.c:165 builtin/help.c:173
+#: builtin/help.c:136 builtin/help.c:158 builtin/help.c:168 builtin/help.c:176
 #, c-format
 msgid "failed to exec '%s'"
 msgstr "exec misslyckades för \"%s\""
 
-#: builtin/help.c:211
+#: builtin/help.c:214
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -9236,7 +9727,7 @@ msgstr ""
 "\"%s\": sökväg för man-visare som ej stöds.\n"
 "Använd \"man.<verktyg>.cmd\" istället."
 
-#: builtin/help.c:223
+#: builtin/help.c:226
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -9245,358 +9736,326 @@ msgstr ""
 "\"%s\": kommando för man-visare som stöds.\n"
 "Använd \"man.<verktyg>.path\" istället."
 
-#: builtin/help.c:340
+#: builtin/help.c:343
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "\"%s\": okänd man-visare."
 
-#: builtin/help.c:357
+#: builtin/help.c:360
 msgid "no man viewer handled the request"
 msgstr "ingen man-visare hanterade förfrågan"
 
-#: builtin/help.c:365
+#: builtin/help.c:368
 msgid "no info viewer handled the request"
 msgstr "ingen info-visare hanterade förfrågan"
 
-#: builtin/help.c:407
-msgid "Defining attributes per path"
-msgstr "Definierar attribut per sökväg"
-
-#: builtin/help.c:408
-msgid "Everyday Git With 20 Commands Or So"
-msgstr "Git för dagligt bruk i ungefär 20 kommandon"
+#: builtin/help.c:415
+#, c-format
+msgid "'%s' is aliased to '%s'"
+msgstr "\"%s\" är ett alias för \"%s\""
 
-#: builtin/help.c:409
-msgid "A Git glossary"
-msgstr "En Git-ordlista"
-
-#: builtin/help.c:410
-msgid "Specifies intentionally untracked files to ignore"
-msgstr "Ange avsiktligen ospårade filer att ignorera"
-
-#: builtin/help.c:411
-msgid "Defining submodule properties"
-msgstr "Ange egenskaper för undermoduler"
-
-#: builtin/help.c:412
-msgid "Specifying revisions and ranges for Git"
-msgstr "Ange versioner och intervall i Git"
-
-#: builtin/help.c:413
-msgid "A tutorial introduction to Git (for version 1.5.1 or newer)"
-msgstr "Introduktion till Git (för version 1.5.1 och senare)"
-
-#: builtin/help.c:414
-msgid "An overview of recommended workflows with Git"
-msgstr "Översikt över rekommenderade arbetsflöden med Git"
-
-#: builtin/help.c:426
-msgid "The common Git guides are:\n"
-msgstr "De vanliga Git-vägledningarna är:\n"
-
-#: builtin/help.c:444
-#, c-format
-msgid "'%s' is aliased to '%s'"
-msgstr "\"%s\" är ett alias för \"%s\""
-
-#: builtin/help.c:466 builtin/help.c:483
+#: builtin/help.c:442 builtin/help.c:459
 #, c-format
 msgid "usage: %s%s"
 msgstr "användning: %s%s"
 
-#: builtin/index-pack.c:157
+#: builtin/index-pack.c:158
 #, c-format
 msgid "unable to open %s"
 msgstr "kunde inte öppna %s"
 
-#: builtin/index-pack.c:207
+#: builtin/index-pack.c:208
 #, c-format
 msgid "object type mismatch at %s"
 msgstr "objekttyp stämmer inte överens vid %s"
 
-#: builtin/index-pack.c:227
+#: builtin/index-pack.c:228
 #, c-format
 msgid "did not receive expected object %s"
 msgstr "emottog inte det förväntade objektet %s"
 
-#: builtin/index-pack.c:230
+#: builtin/index-pack.c:231
 #, c-format
 msgid "object %s: expected type %s, found %s"
 msgstr "objektet %s: förväntad typ %s, såg %s"
 
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
 #, c-format
 msgid "cannot fill %d byte"
 msgid_plural "cannot fill %d bytes"
 msgstr[0] "kan inte fylla %d byte"
 msgstr[1] "kan inte fylla %d byte"
 
-#: builtin/index-pack.c:282
+#: builtin/index-pack.c:283
 msgid "early EOF"
 msgstr "tidigt filslut"
 
-#: builtin/index-pack.c:283
+#: builtin/index-pack.c:284
 msgid "read error on input"
 msgstr "indataläsfel"
 
-#: builtin/index-pack.c:295
+#: builtin/index-pack.c:296
 msgid "used more bytes than were available"
 msgstr "använde fler byte än tillgängligt"
 
-#: builtin/index-pack.c:302
+#: builtin/index-pack.c:303
 msgid "pack too large for current definition of off_t"
 msgstr "paket för stort för nuvarande definition av off_t"
 
-#: builtin/index-pack.c:305 builtin/unpack-objects.c:93
+#: builtin/index-pack.c:306 builtin/unpack-objects.c:93
 msgid "pack exceeds maximum allowed size"
 msgstr "paket är större än tillåten maximal storlek"
 
-#: builtin/index-pack.c:320
+#: builtin/index-pack.c:321
 #, c-format
 msgid "unable to create '%s'"
 msgstr "kunde inte skapa \"%s\""
 
-#: builtin/index-pack.c:326
+#: builtin/index-pack.c:327
 #, c-format
 msgid "cannot open packfile '%s'"
 msgstr "kan inte öppna paketfilen \"%s\""
 
-#: builtin/index-pack.c:340
+#: builtin/index-pack.c:341
 msgid "pack signature mismatch"
 msgstr "paketsignatur stämmer inte överens"
 
-#: builtin/index-pack.c:342
+#: builtin/index-pack.c:343
 #, c-format
 msgid "pack version %<PRIu32> unsupported"
 msgstr "paketversion %<PRIu32> stöds ej"
 
-#: builtin/index-pack.c:360
+#: builtin/index-pack.c:361
 #, c-format
 msgid "pack has bad object at offset %<PRIuMAX>: %s"
 msgstr "paketet har felaktigt objekt vid index %<PRIuMAX>: %s"
 
-#: builtin/index-pack.c:481
+#: builtin/index-pack.c:482
 #, c-format
 msgid "inflate returned %d"
 msgstr "inflate returnerade %d"
 
-#: builtin/index-pack.c:530
+#: builtin/index-pack.c:531
 msgid "offset value overflow for delta base object"
 msgstr "indexvärdespill för deltabasobjekt"
 
-#: builtin/index-pack.c:538
+#: builtin/index-pack.c:539
 msgid "delta base offset is out of bound"
 msgstr "deltabasindex utanför gränsen"
 
-#: builtin/index-pack.c:546
+#: builtin/index-pack.c:547
 #, c-format
 msgid "unknown object type %d"
 msgstr "okänd objekttyp %d"
 
-#: builtin/index-pack.c:577
+#: builtin/index-pack.c:578
 msgid "cannot pread pack file"
 msgstr "kan inte utföra \"pread\" på paketfil"
 
-#: builtin/index-pack.c:579
+#: builtin/index-pack.c:580
 #, c-format
 msgid "premature end of pack file, %<PRIuMAX> byte missing"
 msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
 msgstr[0] "för tidigt slut på paketfilen, %<PRIuMAX> byte saknas"
 msgstr[1] "för tidigt slut på paketfilen, %<PRIuMAX> byte saknas"
 
-#: builtin/index-pack.c:605
+#: builtin/index-pack.c:606
 msgid "serious inflate inconsistency"
 msgstr "allvarlig inflate-inkonsekvens"
 
-#: builtin/index-pack.c:750 builtin/index-pack.c:756 builtin/index-pack.c:779
-#: builtin/index-pack.c:818 builtin/index-pack.c:827
+#: builtin/index-pack.c:751 builtin/index-pack.c:757 builtin/index-pack.c:780
+#: builtin/index-pack.c:819 builtin/index-pack.c:828
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "SHA1-KOLLISION UPPTÄCKT VID %s !"
 
-#: builtin/index-pack.c:753 builtin/pack-objects.c:182
-#: builtin/pack-objects.c:276
+#: builtin/index-pack.c:754 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:292
 #, c-format
 msgid "unable to read %s"
 msgstr "kunde inte läsa %s"
 
-#: builtin/index-pack.c:816
+#: builtin/index-pack.c:817
 #, c-format
 msgid "cannot read existing object info %s"
 msgstr "kan inte läsa information om befintligt objekt %s"
 
-#: builtin/index-pack.c:824
+#: builtin/index-pack.c:825
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "kan inte läsa befintligt objekt %s"
 
-#: builtin/index-pack.c:838
+#: builtin/index-pack.c:839
 #, c-format
 msgid "invalid blob object %s"
 msgstr "ogiltigt blob-objekt %s"
 
-#: builtin/index-pack.c:853
+#: builtin/index-pack.c:842 builtin/index-pack.c:860
+msgid "fsck error in packed object"
+msgstr "fsck-fel i packat objekt"
+
+#: builtin/index-pack.c:857
 #, c-format
 msgid "invalid %s"
 msgstr "ogiltigt %s"
 
-#: builtin/index-pack.c:856
-msgid "Error in object"
-msgstr "Fel i objekt"
-
-#: builtin/index-pack.c:858
+#: builtin/index-pack.c:862
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "Inte alla barnobjekt för %s kan nås"
 
-#: builtin/index-pack.c:930 builtin/index-pack.c:961
+#: builtin/index-pack.c:934 builtin/index-pack.c:965
 msgid "failed to apply delta"
 msgstr "misslyckades tillämpa delta"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Receiving objects"
 msgstr "Tar emot objekt"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Indexing objects"
 msgstr "Skapar index för objekt"
 
-#: builtin/index-pack.c:1165
+#: builtin/index-pack.c:1169
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "paketet är trasigt (SHA1 stämmer inte)"
 
-#: builtin/index-pack.c:1170
+#: builtin/index-pack.c:1174
 msgid "cannot fstat packfile"
 msgstr "kan inte utföra \"fstat\" på paketfil"
 
-#: builtin/index-pack.c:1173
+#: builtin/index-pack.c:1177
 msgid "pack has junk at the end"
 msgstr "paket har skräp i slutet"
 
-#: builtin/index-pack.c:1185
+#: builtin/index-pack.c:1189
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "förvirrad bortom vanvett i parse_pack_objects()"
 
-#: builtin/index-pack.c:1208
+#: builtin/index-pack.c:1212
 msgid "Resolving deltas"
 msgstr "Analyserar delta"
 
-#: builtin/index-pack.c:1219
+#: builtin/index-pack.c:1223
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "kunde inte skapa tråd: %s"
 
-#: builtin/index-pack.c:1261
+#: builtin/index-pack.c:1265
 msgid "confusion beyond insanity"
 msgstr "förvirrad bortom vanvett"
 
-#: builtin/index-pack.c:1267
+#: builtin/index-pack.c:1271
 #, c-format
 msgid "completed with %d local object"
 msgid_plural "completed with %d local objects"
 msgstr[0] "slutfördes med %d lokalt objekt"
 msgstr[1] "slutfördes med %d lokala objekt"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1283
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr "Oväntad svanschecksumma för %s (trasig disk?)"
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1287
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "paketet har %d oanalyserat delta"
 msgstr[1] "paketet har %d oanalyserade delta"
 
-#: builtin/index-pack.c:1307
+#: builtin/index-pack.c:1311
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "kunde inte utföra \"deflate\" på tillagt objekt (%d)"
 
-#: builtin/index-pack.c:1383
+#: builtin/index-pack.c:1388
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "lokalt objekt %s är trasigt"
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1402
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "paketfilnamnet \"%s\" slutar inte med \".pack\""
 
-#: builtin/index-pack.c:1422
+#: builtin/index-pack.c:1427
 #, c-format
 msgid "cannot write %s file '%s'"
 msgstr "kan inte ta skriva %s-fil \"%s\""
 
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1435
 #, c-format
 msgid "cannot close written %s file '%s'"
 msgstr "kan inte stänga skriven %s-fil \"%s\""
 
-#: builtin/index-pack.c:1454
+#: builtin/index-pack.c:1459
 msgid "error while closing pack file"
 msgstr "fel vid stängning av paketfil"
 
-#: builtin/index-pack.c:1468
+#: builtin/index-pack.c:1473
 msgid "cannot store pack file"
 msgstr "kan inte spara paketfil"
 
-#: builtin/index-pack.c:1476
+#: builtin/index-pack.c:1481
 msgid "cannot store index file"
 msgstr "kan inte spara indexfil"
 
-#: builtin/index-pack.c:1513
+#: builtin/index-pack.c:1521
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "felaktig pack.indexversion=%<PRIu32>"
 
-#: builtin/index-pack.c:1581
+#: builtin/index-pack.c:1590
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "Kan inte öppna befintlig paketfil \"%s\""
 
-#: builtin/index-pack.c:1583
+#: builtin/index-pack.c:1592
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "Kan inte öppna befintlig paket-idx-fil för \"%s\""
 
-#: builtin/index-pack.c:1631
+#: builtin/index-pack.c:1640
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "icke-delta: %d objekt"
 msgstr[1] "icke-delta: %d objekt"
 
-#: builtin/index-pack.c:1638
+#: builtin/index-pack.c:1647
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] "kedjelängd = %d: %lu objekt"
 msgstr[1] "kedjelängd = %d: %lu objekt"
 
-#: builtin/index-pack.c:1675
+#: builtin/index-pack.c:1684
 msgid "Cannot come back to cwd"
 msgstr "Kan inte gå tillbaka till arbetskatalogen (cwd)"
 
-#: builtin/index-pack.c:1724 builtin/index-pack.c:1727
-#: builtin/index-pack.c:1743 builtin/index-pack.c:1747
+#: builtin/index-pack.c:1735 builtin/index-pack.c:1738
+#: builtin/index-pack.c:1754 builtin/index-pack.c:1758
 #, c-format
 msgid "bad %s"
 msgstr "felaktig %s"
 
-#: builtin/index-pack.c:1763
+#: builtin/index-pack.c:1774
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin kan inte användas med --stdin"
 
-#: builtin/index-pack.c:1765
+#: builtin/index-pack.c:1776
 msgid "--stdin requires a git repository"
 msgstr "--stdin kräver ett git-arkiv"
 
-#: builtin/index-pack.c:1771
+#: builtin/index-pack.c:1782
 msgid "--verify with no packfile name given"
 msgstr "--verify angavs utan paketfilnamn"
 
+#: builtin/index-pack.c:1832 builtin/unpack-objects.c:578
+msgid "fsck error in pack objects"
+msgstr "fsck-fel i packat objekt"
+
 #: builtin/init-db.c:55
 #, c-format
 msgid "cannot stat '%s'"
@@ -9634,8 +10093,8 @@ msgstr "ignorerar mallen %s"
 
 #: builtin/init-db.c:120
 #, c-format
-msgid "templates not found %s"
-msgstr "mallarna hittades inte %s"
+msgid "templates not found in %s"
+msgstr "mallarna hittades inte %s"
 
 #: builtin/init-db.c:135
 #, c-format
@@ -9693,11 +10152,6 @@ msgstr "behörigheter"
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr "ange att git-arkivet skall delas bland flera användare"
 
-#: builtin/init-db.c:516 builtin/init-db.c:521
-#, c-format
-msgid "cannot mkdir %s"
-msgstr "kan inte skapa katalogen (mkdir) %s"
-
 #: builtin/init-db.c:525
 #, c-format
 msgid "cannot chdir to %s"
@@ -9881,7 +10335,7 @@ msgstr "Två utdatakataloger?"
 msgid "Unknown commit %s"
 msgstr "Okänd incheckning %s"
 
-#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:522
+#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:523
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr "Kunde inte slå upp \"%s\" som en giltig referens."
@@ -10230,7 +10684,7 @@ msgstr "låtsas att sökvägar borttagna sedan <träd-igt> fortfarande finns"
 msgid "show debugging data"
 msgstr "visa felsökningsutdata"
 
-#: builtin/ls-remote.c:7
+#: builtin/ls-remote.c:9
 msgid ""
 "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
@@ -10240,39 +10694,39 @@ msgstr ""
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
 "                     [--symref] [<arkiv> [<referenser>...]]"
 
-#: builtin/ls-remote.c:52
+#: builtin/ls-remote.c:59
 msgid "do not print remote URL"
 msgstr "visa inte fjärr-URL"
 
-#: builtin/ls-remote.c:53 builtin/ls-remote.c:55
+#: builtin/ls-remote.c:60 builtin/ls-remote.c:62
 msgid "exec"
 msgstr "exec"
 
-#: builtin/ls-remote.c:54 builtin/ls-remote.c:56
+#: builtin/ls-remote.c:61 builtin/ls-remote.c:63
 msgid "path of git-upload-pack on the remote host"
 msgstr "sökväg till git-upload-pack på fjärren"
 
-#: builtin/ls-remote.c:58
+#: builtin/ls-remote.c:65
 msgid "limit to tags"
 msgstr "begränsa till taggar"
 
-#: builtin/ls-remote.c:59
+#: builtin/ls-remote.c:66
 msgid "limit to heads"
 msgstr "begränsa till huvuden"
 
-#: builtin/ls-remote.c:60
+#: builtin/ls-remote.c:67
 msgid "do not show peeled tags"
 msgstr "visa inte avskalade taggar"
 
-#: builtin/ls-remote.c:62
+#: builtin/ls-remote.c:69
 msgid "take url.<base>.insteadOf into account"
 msgstr "ta hänsyn till url.<bas>.insteadOf"
 
-#: builtin/ls-remote.c:64
+#: builtin/ls-remote.c:73
 msgid "exit with exit code 2 if no matching refs are found"
 msgstr "avsluta med felkod 2 om motsvarande referenser inte hittas"
 
-#: builtin/ls-remote.c:67
+#: builtin/ls-remote.c:76
 msgid "show underlying ref in addition to the object pointed by it"
 msgstr "visa underliggande referens och objektet det pekar på"
 
@@ -10317,166 +10771,166 @@ msgstr "visa hela trädet; inte bara aktuell katalog (implicerar --full-name)"
 msgid "empty mbox: '%s'"
 msgstr "tom mbox: ”%s”"
 
-#: builtin/merge.c:49
+#: builtin/merge.c:51
 msgid "git merge [<options>] [<commit>...]"
 msgstr "git merge [<flaggor>] [<incheckning>...]"
 
-#: builtin/merge.c:50
+#: builtin/merge.c:52
 msgid "git merge --abort"
 msgstr "git merge --abort"
 
-#: builtin/merge.c:51
+#: builtin/merge.c:53
 msgid "git merge --continue"
 msgstr "git merge --continue"
 
-#: builtin/merge.c:108
+#: builtin/merge.c:110
 msgid "switch `m' requires a value"
 msgstr "flaggan \"m\" behöver ett värde"
 
-#: builtin/merge.c:145
+#: builtin/merge.c:147
 #, c-format
 msgid "Could not find merge strategy '%s'.\n"
 msgstr "Kunde inte hitta sammanslagningsstrategin \"%s\".\n"
 
-#: builtin/merge.c:146
+#: builtin/merge.c:148
 #, c-format
 msgid "Available strategies are:"
 msgstr "Tillgängliga strategier är:"
 
-#: builtin/merge.c:151
+#: builtin/merge.c:153
 #, c-format
 msgid "Available custom strategies are:"
 msgstr "Tillgängliga skräddarsydda strategier är:"
 
-#: builtin/merge.c:201 builtin/pull.c:137
+#: builtin/merge.c:203 builtin/pull.c:142
 msgid "do not show a diffstat at the end of the merge"
 msgstr "visa inte en diffstat när sammanslagningen är färdig"
 
-#: builtin/merge.c:204 builtin/pull.c:140
+#: builtin/merge.c:206 builtin/pull.c:145
 msgid "show a diffstat at the end of the merge"
 msgstr "visa en diffstat när sammanslagningen är färdig"
 
-#: builtin/merge.c:205 builtin/pull.c:143
+#: builtin/merge.c:207 builtin/pull.c:148
 msgid "(synonym to --stat)"
 msgstr "(synonym till --stat)"
 
-#: builtin/merge.c:207 builtin/pull.c:146
+#: builtin/merge.c:209 builtin/pull.c:151
 msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr ""
 "lägg till (som mest <n>) poster från shortlog till incheckningsmeddelandet"
 
-#: builtin/merge.c:210 builtin/pull.c:152
+#: builtin/merge.c:212 builtin/pull.c:157
 msgid "create a single commit instead of doing a merge"
 msgstr "skapa en ensam incheckning istället för en sammanslagning"
 
-#: builtin/merge.c:212 builtin/pull.c:155
+#: builtin/merge.c:214 builtin/pull.c:160
 msgid "perform a commit if the merge succeeds (default)"
 msgstr "utför en incheckning om sammanslagningen lyckades (standard)"
 
-#: builtin/merge.c:214 builtin/pull.c:158
+#: builtin/merge.c:216 builtin/pull.c:163
 msgid "edit message before committing"
 msgstr "redigera meddelande innan incheckning"
 
-#: builtin/merge.c:215
+#: builtin/merge.c:217
 msgid "allow fast-forward (default)"
 msgstr "tillåt snabbspolning (standard)"
 
-#: builtin/merge.c:217 builtin/pull.c:164
+#: builtin/merge.c:219 builtin/pull.c:169
 msgid "abort if fast-forward is not possible"
 msgstr "avbryt om snabbspolning inte är möjlig"
 
-#: builtin/merge.c:221 builtin/pull.c:167
+#: builtin/merge.c:223 builtin/pull.c:172
 msgid "verify that the named commit has a valid GPG signature"
 msgstr "bekräfta att den namngivna incheckningen har en giltig GPG-signatur"
 
-#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171
+#: builtin/merge.c:224 builtin/notes.c:777 builtin/pull.c:176
 #: builtin/revert.c:109
 msgid "strategy"
 msgstr "strategi"
 
-#: builtin/merge.c:223 builtin/pull.c:172
+#: builtin/merge.c:225 builtin/pull.c:177
 msgid "merge strategy to use"
 msgstr "sammanslagningsstrategi att använda"
 
-#: builtin/merge.c:224 builtin/pull.c:175
+#: builtin/merge.c:226 builtin/pull.c:180
 msgid "option=value"
 msgstr "alternativ=värde"
 
-#: builtin/merge.c:225 builtin/pull.c:176
+#: builtin/merge.c:227 builtin/pull.c:181
 msgid "option for selected merge strategy"
 msgstr "alternativ för vald sammanslagningsstrategi"
 
-#: builtin/merge.c:227
+#: builtin/merge.c:229
 msgid "merge commit message (for a non-fast-forward merge)"
 msgstr "incheckningsmeddelande för (icke snabbspolande) sammanslagning"
 
-#: builtin/merge.c:231
+#: builtin/merge.c:233
 msgid "abort the current in-progress merge"
 msgstr "avbryt den pågående sammanslagningen"
 
-#: builtin/merge.c:233
+#: builtin/merge.c:235
 msgid "continue the current in-progress merge"
 msgstr "fortsätt den pågående sammanslagningen"
 
-#: builtin/merge.c:235 builtin/pull.c:183
+#: builtin/merge.c:237 builtin/pull.c:188
 msgid "allow merging unrelated histories"
 msgstr "tillåt sammanslagning av orelaterade historier"
 
-#: builtin/merge.c:241
+#: builtin/merge.c:243
 msgid "verify commit-msg hook"
 msgstr "bekräfta commit-msg-krok"
 
-#: builtin/merge.c:266
+#: builtin/merge.c:268
 msgid "could not run stash."
 msgstr "kunde köra stash."
 
-#: builtin/merge.c:271
+#: builtin/merge.c:273
 msgid "stash failed"
 msgstr "stash misslyckades"
 
-#: builtin/merge.c:276
+#: builtin/merge.c:278
 #, c-format
 msgid "not a valid object: %s"
 msgstr "inte ett giltigt objekt: %s"
 
-#: builtin/merge.c:298 builtin/merge.c:315
+#: builtin/merge.c:300 builtin/merge.c:317
 msgid "read-tree failed"
 msgstr "read-tree misslyckades"
 
-#: builtin/merge.c:345
+#: builtin/merge.c:347
 msgid " (nothing to squash)"
 msgstr " (inget att platta till)"
 
-#: builtin/merge.c:356
+#: builtin/merge.c:358
 #, c-format
 msgid "Squash commit -- not updating HEAD\n"
 msgstr "Tillplattningsincheckning -- uppdaterar inte HEAD\n"
 
-#: builtin/merge.c:406
+#: builtin/merge.c:408
 #, c-format
 msgid "No merge message -- not updating HEAD\n"
 msgstr "Inget sammanslagningsmeddelande -- uppdaterar inte HEAD\n"
 
-#: builtin/merge.c:456
+#: builtin/merge.c:458
 #, c-format
 msgid "'%s' does not point to a commit"
 msgstr "\"%s\" verkar inte peka på en incheckning"
 
-#: builtin/merge.c:546
+#: builtin/merge.c:548
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "Felaktig branch.%s.mergeoptions-sträng: %s"
 
-#: builtin/merge.c:668
+#: builtin/merge.c:669
 msgid "Not handling anything other than two heads merge."
 msgstr "Hanterar inte något annat än en sammanslagning av två huvuden."
 
-#: builtin/merge.c:682
+#: builtin/merge.c:683
 #, c-format
 msgid "Unknown option for merge-recursive: -X%s"
 msgstr "Felaktig flagga för merge-recursive: -X%s"
 
-#: builtin/merge.c:697
+#: builtin/merge.c:698
 #, c-format
 msgid "unable to write %s"
 msgstr "kunde inte skriva %s"
@@ -10513,65 +10967,65 @@ msgstr ""
 msgid "Empty commit message."
 msgstr "Tomt incheckningsmeddelande."
 
-#: builtin/merge.c:820
+#: builtin/merge.c:819
 #, c-format
 msgid "Wonderful.\n"
 msgstr "Underbart.\n"
 
-#: builtin/merge.c:873
+#: builtin/merge.c:872
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr ""
 "Kunde inte slå ihop automatiskt; fixa konflikter och checka in resultatet.\n"
 
-#: builtin/merge.c:912
+#: builtin/merge.c:911
 msgid "No current branch."
 msgstr "Inte på någon gren."
 
-#: builtin/merge.c:914
+#: builtin/merge.c:913
 msgid "No remote for the current branch."
 msgstr "Ingen fjärr för aktuell gren."
 
-#: builtin/merge.c:916
+#: builtin/merge.c:915
 msgid "No default upstream defined for the current branch."
 msgstr "Ingen standarduppström angiven för aktuell gren."
 
-#: builtin/merge.c:921
+#: builtin/merge.c:920
 #, c-format
 msgid "No remote-tracking branch for %s from %s"
 msgstr "Ingen fjärrspårande gren för %s från %s"
 
-#: builtin/merge.c:974
+#: builtin/merge.c:973
 #, c-format
 msgid "Bad value '%s' in environment '%s'"
 msgstr "Felaktigt värde \"%s\" i miljövariabeln \"%s\""
 
-#: builtin/merge.c:1076
+#: builtin/merge.c:1075
 #, c-format
 msgid "not something we can merge in %s: %s"
 msgstr "inte något vi kan slå ihop med %s: %s"
 
-#: builtin/merge.c:1110
+#: builtin/merge.c:1109
 msgid "not something we can merge"
 msgstr "inte något vi kan slå ihop"
 
-#: builtin/merge.c:1212
+#: builtin/merge.c:1211
 msgid "--abort expects no arguments"
 msgstr "--abort tar inga argument"
 
-#: builtin/merge.c:1216
+#: builtin/merge.c:1215
 msgid "There is no merge to abort (MERGE_HEAD missing)."
 msgstr "Ingen sammanslagning att avbryta (MERGE_HEAD saknas)."
 
-#: builtin/merge.c:1228
+#: builtin/merge.c:1227
 msgid "--continue expects no arguments"
 msgstr "--continue tar inga argument"
 
-#: builtin/merge.c:1232
+#: builtin/merge.c:1231
 msgid "There is no merge in progress (MERGE_HEAD missing)."
 msgstr "Ingen sammanslagning pågår (MERGE_HEAD saknas)."
 
-#: builtin/merge.c:1248
+#: builtin/merge.c:1247
 msgid ""
 "You have not concluded your merge (MERGE_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10579,7 +11033,7 @@ msgstr ""
 "Du har inte avslutat sammanslagningen (MERGE_HEAD finns).\n"
 "Checka in dina ändringar innan du slår ihop."
 
-#: builtin/merge.c:1255
+#: builtin/merge.c:1254
 msgid ""
 "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10587,114 +11041,114 @@ msgstr ""
 "Du har inte avslutat din \"cherry-pick\" (CHERRY_PICK_HEAD finns).\n"
 "Checka in dina ändringar innan du slår ihop."
 
-#: builtin/merge.c:1258
+#: builtin/merge.c:1257
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
 msgstr "Du har inte avslutat din \"cherry-pick\" (CHERRY_PICK_HEAD finns)."
 
-#: builtin/merge.c:1267
+#: builtin/merge.c:1266
 msgid "You cannot combine --squash with --no-ff."
 msgstr "Du kan inte kombinera --squash med --no-ff."
 
-#: builtin/merge.c:1275
+#: builtin/merge.c:1274
 msgid "No commit specified and merge.defaultToUpstream not set."
 msgstr "Ingen incheckning angiven och merge.defaultToUpstream är ej satt."
 
-#: builtin/merge.c:1292
+#: builtin/merge.c:1291
 msgid "Squash commit into empty head not supported yet"
 msgstr "Stöder inte en tillplattningsincheckning på ett tomt huvud ännu"
 
-#: builtin/merge.c:1294
+#: builtin/merge.c:1293
 msgid "Non-fast-forward commit does not make sense into an empty head"
 msgstr "Icke-snabbspolad incheckning kan inte användas med ett tomt huvud"
 
-#: builtin/merge.c:1299
+#: builtin/merge.c:1298
 #, c-format
 msgid "%s - not something we can merge"
 msgstr "%s - inte något vi kan slå ihop"
 
-#: builtin/merge.c:1301
+#: builtin/merge.c:1300
 msgid "Can merge only exactly one commit into empty head"
 msgstr "Kan endast slå ihop en enda incheckning i ett tomt huvud"
 
-#: builtin/merge.c:1335
+#: builtin/merge.c:1334
 #, c-format
 msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
 msgstr ""
 "Incheckningen %s har en obetrodd GPG-signatur som påstås vara gjord av %s."
 
-#: builtin/merge.c:1338
+#: builtin/merge.c:1337
 #, c-format
 msgid "Commit %s has a bad GPG signature allegedly by %s."
 msgstr ""
 "Incheckningen %s har en felaktig GPG-signatur som påstås vara gjord av %s."
 
-#: builtin/merge.c:1341
+#: builtin/merge.c:1340
 #, c-format
 msgid "Commit %s does not have a GPG signature."
 msgstr "Incheckning %s har inte någon GPG-signatur."
 
-#: builtin/merge.c:1344
+#: builtin/merge.c:1343
 #, c-format
 msgid "Commit %s has a good GPG signature by %s\n"
 msgstr "Incheckningen %s har en korrekt GPG-signatur av %s\n"
 
-#: builtin/merge.c:1403
+#: builtin/merge.c:1402
 msgid "refusing to merge unrelated histories"
 msgstr "vägrar slå samman orelaterad historik"
 
-#: builtin/merge.c:1412
+#: builtin/merge.c:1411
 msgid "Already up to date."
 msgstr "Redan à jour."
 
-#: builtin/merge.c:1422
+#: builtin/merge.c:1421
 #, c-format
 msgid "Updating %s..%s\n"
 msgstr "Uppdaterar %s..%s\n"
 
-#: builtin/merge.c:1463
+#: builtin/merge.c:1462
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
 msgstr "Försöker riktigt enkel sammanslagning i indexet...\n"
 
-#: builtin/merge.c:1470
+#: builtin/merge.c:1469
 #, c-format
 msgid "Nope.\n"
 msgstr "Nej.\n"
 
-#: builtin/merge.c:1495
+#: builtin/merge.c:1494
 msgid "Already up to date. Yeeah!"
 msgstr "Redan à jour. Toppen!"
 
-#: builtin/merge.c:1501
+#: builtin/merge.c:1500
 msgid "Not possible to fast-forward, aborting."
 msgstr "Kan inte snabbspola, avbryter."
 
-#: builtin/merge.c:1524 builtin/merge.c:1603
+#: builtin/merge.c:1523 builtin/merge.c:1602
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
 msgstr "Återspolar trädet till orört...\n"
 
-#: builtin/merge.c:1528
+#: builtin/merge.c:1527
 #, c-format
 msgid "Trying merge strategy %s...\n"
 msgstr "Försöker sammanslagningsstrategin %s...\n"
 
-#: builtin/merge.c:1594
+#: builtin/merge.c:1593
 #, c-format
 msgid "No merge strategy handled the merge.\n"
 msgstr "Ingen sammanslagningsstrategi hanterade sammanslagningen.\n"
 
-#: builtin/merge.c:1596
+#: builtin/merge.c:1595
 #, c-format
 msgid "Merge with strategy %s failed.\n"
 msgstr "Sammanslagning med strategin %s misslyckades.\n"
 
-#: builtin/merge.c:1605
+#: builtin/merge.c:1604
 #, c-format
 msgid "Using the %s to prepare resolving by hand.\n"
 msgstr "Använder %s för att förbereda lösning för hand.\n"
 
-#: builtin/merge.c:1617
+#: builtin/merge.c:1616
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr ""
@@ -10831,26 +11285,26 @@ msgstr "tillåt skapa mer än ett träd"
 msgid "git mv [<options>] <source>... <destination>"
 msgstr "git mv [<flaggor>] <källa>... <mål>"
 
-#: builtin/mv.c:83
+#: builtin/mv.c:82
 #, c-format
 msgid "Directory %s is in index and no submodule?"
 msgstr "Katalogen %s är i indexet och inte en undermodul?"
 
-#: builtin/mv.c:85 builtin/rm.c:289
+#: builtin/mv.c:84 builtin/rm.c:288
 msgid "Please stage your changes to .gitmodules or stash them to proceed"
 msgstr ""
 "Köa dina ändringar i .gitmodules eller använd \"stash\" för att fortsätta"
 
-#: builtin/mv.c:103
+#: builtin/mv.c:102
 #, c-format
 msgid "%.*s is in index"
 msgstr "%.*s är i indexet"
 
-#: builtin/mv.c:125
+#: builtin/mv.c:124
 msgid "force move/rename even if target exists"
 msgstr "tvinga flytta/ändra namn även om målet finns"
 
-#: builtin/mv.c:127
+#: builtin/mv.c:126
 msgid "skip move/rename errors"
 msgstr "hoppa över fel vid flytt/namnändring"
 
@@ -10915,7 +11369,7 @@ msgstr "%s, källa=%s, mål=%s"
 msgid "Renaming %s to %s\n"
 msgstr "Byter namn på %s till %s\n"
 
-#: builtin/mv.c:276 builtin/remote.c:712 builtin/repack.c:394
+#: builtin/mv.c:276 builtin/remote.c:715 builtin/repack.c:409
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "misslyckades byta namn på \"%s\""
@@ -11107,12 +11561,12 @@ msgstr "kunde inte skriva anteckningsobjekt"
 msgid "the note contents have been left in %s"
 msgstr "anteckningens innehåll har lämnats kvar i %s"
 
-#: builtin/notes.c:234 builtin/tag.c:506
+#: builtin/notes.c:234 builtin/tag.c:507
 #, c-format
 msgid "cannot read '%s'"
 msgstr "kunde inte läsa \"%s\""
 
-#: builtin/notes.c:236 builtin/tag.c:509
+#: builtin/notes.c:236 builtin/tag.c:510
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "kunde inte öppna eller läsa \"%s\""
@@ -11359,7 +11813,7 @@ msgstr "försök att ta bort icke-existerande anteckningar är inte ett fel"
 msgid "read object names from the standard input"
 msgstr "läs objektnamn från standard in"
 
-#: builtin/notes.c:943 builtin/prune.c:106 builtin/worktree.c:160
+#: builtin/notes.c:943 builtin/prune.c:107 builtin/worktree.c:151
 msgid "do not remove, show only"
 msgstr "ta inte bort, bara visa"
 
@@ -11380,211 +11834,239 @@ msgstr "använd anteckningar från <anteckningsref>"
 msgid "unknown subcommand: %s"
 msgstr "okänt underkommando: %s"
 
-#: builtin/pack-objects.c:33
+#: builtin/pack-objects.c:48
 msgid ""
 "git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
 msgstr ""
 "git pack-objects --stdout [<flaggor>...] [< <reflista> | < <objektlista>]"
 
-#: builtin/pack-objects.c:34
+#: builtin/pack-objects.c:49
 msgid ""
 "git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
 msgstr ""
 "git pack-objects [<flaggor>...] <basnamn> [< <reflista> | < <objektlista>]"
 
-#: builtin/pack-objects.c:195 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:211 builtin/pack-objects.c:214
 #, c-format
 msgid "deflate error (%d)"
 msgstr "fel i deflate (%d)"
 
-#: builtin/pack-objects.c:791
+#: builtin/pack-objects.c:810
 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
 msgstr ""
 "inaktiverar skrivning av bitkarta, paket delas på grund av pack.packSizeLimit"
 
-#: builtin/pack-objects.c:804
+#: builtin/pack-objects.c:823
 msgid "Writing objects"
 msgstr "Skriver objekt"
 
-#: builtin/pack-objects.c:1084
+#: builtin/pack-objects.c:1106
 msgid "disabling bitmap writing, as some objects are not being packed"
 msgstr "inaktiverar skrivning av bitkarta då några objekt inte packas"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:1765
+msgid "Counting objects"
+msgstr "Räknar objekt"
+
+#: builtin/pack-objects.c:1895
+#, c-format
+msgid "unable to get size of %s"
+msgstr "kan inte hämta storlek på %s"
+
+#: builtin/pack-objects.c:1910
+#, c-format
+msgid "unable to parse object header of %s"
+msgstr "kunde inte tolka objekthuvud för %s"
+
+#: builtin/pack-objects.c:2564
 msgid "Compressing objects"
 msgstr "Komprimerar objekt"
 
-#: builtin/pack-objects.c:2625
+#: builtin/pack-objects.c:2735
 msgid "invalid value for --missing"
 msgstr "ogiltigt värde för --missing"
 
-#: builtin/pack-objects.c:2928
+#: builtin/pack-objects.c:3067
 #, c-format
 msgid "unsupported index version %s"
 msgstr "indexversionen %s stöds ej"
 
-#: builtin/pack-objects.c:2932
+#: builtin/pack-objects.c:3071
 #, c-format
 msgid "bad index version '%s'"
 msgstr "felaktig indexversion \"%s\""
 
-#: builtin/pack-objects.c:2962
+#: builtin/pack-objects.c:3102
 msgid "do not show progress meter"
 msgstr "visa inte förloppsindikator"
 
-#: builtin/pack-objects.c:2964
+#: builtin/pack-objects.c:3104
 msgid "show progress meter"
 msgstr "visa förloppsindikator"
 
-#: builtin/pack-objects.c:2966
+#: builtin/pack-objects.c:3106
 msgid "show progress meter during object writing phase"
 msgstr "visa förloppsindikator under objektskrivningsfasen"
 
-#: builtin/pack-objects.c:2969
+#: builtin/pack-objects.c:3109
 msgid "similar to --all-progress when progress meter is shown"
 msgstr "som --all-progress när förloppsindikatorn visas"
 
-#: builtin/pack-objects.c:2970
+#: builtin/pack-objects.c:3110
 msgid "version[,offset]"
 msgstr "version[,offset]"
 
-#: builtin/pack-objects.c:2971
+#: builtin/pack-objects.c:3111
 msgid "write the pack index file in the specified idx format version"
 msgstr "skriv paketindexfilen i angiven indexformatversion"
 
-#: builtin/pack-objects.c:2974
+#: builtin/pack-objects.c:3114
 msgid "maximum size of each output pack file"
 msgstr "maximal storlek på varje utdatapaketfil"
 
-#: builtin/pack-objects.c:2976
+#: builtin/pack-objects.c:3116
 msgid "ignore borrowed objects from alternate object store"
 msgstr "ignorera lånade objekt från alternativa objektlager"
 
-#: builtin/pack-objects.c:2978
+#: builtin/pack-objects.c:3118
 msgid "ignore packed objects"
 msgstr "ignorera packade objekt"
 
-#: builtin/pack-objects.c:2980
+#: builtin/pack-objects.c:3120
 msgid "limit pack window by objects"
 msgstr "begränsa paketfönster efter objekt"
 
-#: builtin/pack-objects.c:2982
+#: builtin/pack-objects.c:3122
 msgid "limit pack window by memory in addition to object limit"
 msgstr "begränsa paketfönster efter minne förutom objektgräns"
 
-#: builtin/pack-objects.c:2984
+#: builtin/pack-objects.c:3124
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr "maximal längd på deltakedja tillåten i slutligt paket"
 
-#: builtin/pack-objects.c:2986
+#: builtin/pack-objects.c:3126
 msgid "reuse existing deltas"
 msgstr "återanvänd befintliga delta"
 
-#: builtin/pack-objects.c:2988
+#: builtin/pack-objects.c:3128
 msgid "reuse existing objects"
 msgstr "återanvänd befintliga objekt"
 
-#: builtin/pack-objects.c:2990
+#: builtin/pack-objects.c:3130
 msgid "use OFS_DELTA objects"
 msgstr "använd OFS_DELTA-objekt"
 
-#: builtin/pack-objects.c:2992
+#: builtin/pack-objects.c:3132
 msgid "use threads when searching for best delta matches"
 msgstr "använd trådar vid sökning efter bästa deltaträffar"
 
-#: builtin/pack-objects.c:2994
+#: builtin/pack-objects.c:3134
 msgid "do not create an empty pack output"
 msgstr "försök inte skapa tom paketutdata"
 
-#: builtin/pack-objects.c:2996
+#: builtin/pack-objects.c:3136
 msgid "read revision arguments from standard input"
 msgstr "läs revisionsargument från standard in"
 
-#: builtin/pack-objects.c:2998
+#: builtin/pack-objects.c:3138
 msgid "limit the objects to those that are not yet packed"
 msgstr "begränsa objekt till de som ännu inte packats"
 
-#: builtin/pack-objects.c:3001
+#: builtin/pack-objects.c:3141
 msgid "include objects reachable from any reference"
 msgstr "inkludera objekt som kan nås från någon referens"
 
-#: builtin/pack-objects.c:3004
+#: builtin/pack-objects.c:3144
 msgid "include objects referred by reflog entries"
 msgstr "inkludera objekt som refereras från referensloggposter"
 
-#: builtin/pack-objects.c:3007
+#: builtin/pack-objects.c:3147
 msgid "include objects referred to by the index"
 msgstr "inkludera objekt som refereras från indexet"
 
-#: builtin/pack-objects.c:3010
+#: builtin/pack-objects.c:3150
 msgid "output pack to stdout"
 msgstr "skriv paket på standard ut"
 
-#: builtin/pack-objects.c:3012
+#: builtin/pack-objects.c:3152
 msgid "include tag objects that refer to objects to be packed"
 msgstr "inkludera taggobjekt som refererar objekt som skall packas"
 
-#: builtin/pack-objects.c:3014
+#: builtin/pack-objects.c:3154
 msgid "keep unreachable objects"
 msgstr "behåll onåbara objekt"
 
-#: builtin/pack-objects.c:3016
+#: builtin/pack-objects.c:3156
 msgid "pack loose unreachable objects"
 msgstr "packa lösa onåbara objekt"
 
-#: builtin/pack-objects.c:3018
+#: builtin/pack-objects.c:3158
 msgid "unpack unreachable objects newer than <time>"
 msgstr "packa upp onåbara objekt nyare än <tid>"
 
-#: builtin/pack-objects.c:3021
+#: builtin/pack-objects.c:3161
 msgid "create thin packs"
 msgstr "skapa tunna paket"
 
-#: builtin/pack-objects.c:3023
+#: builtin/pack-objects.c:3163
 msgid "create packs suitable for shallow fetches"
 msgstr "skapa packfiler lämpade för grunda hämtningar"
 
-#: builtin/pack-objects.c:3025
+#: builtin/pack-objects.c:3165
 msgid "ignore packs that have companion .keep file"
 msgstr "ignorera paket som har tillhörande .keep-fil"
 
-#: builtin/pack-objects.c:3027
+#: builtin/pack-objects.c:3167
+msgid "ignore this pack"
+msgstr "ignorera detta paket"
+
+#: builtin/pack-objects.c:3169
 msgid "pack compression level"
 msgstr "komprimeringsgrad för paket"
 
-#: builtin/pack-objects.c:3029
+#: builtin/pack-objects.c:3171
 msgid "do not hide commits by grafts"
 msgstr "göm inte incheckningar med ympningar (\"grafts\")"
 
-#: builtin/pack-objects.c:3031
+#: builtin/pack-objects.c:3173
 msgid "use a bitmap index if available to speed up counting objects"
 msgstr "använd bitkartindex om tillgängligt för att räkna objekt snabbare"
 
-#: builtin/pack-objects.c:3033
+#: builtin/pack-objects.c:3175
 msgid "write a bitmap index together with the pack index"
 msgstr "använd bitkartindex tillsammans med packindexet"
 
-#: builtin/pack-objects.c:3036
+#: builtin/pack-objects.c:3178
 msgid "handling for missing objects"
 msgstr "hantering av saknade objekt"
 
-#: builtin/pack-objects.c:3039
+#: builtin/pack-objects.c:3181
 msgid "do not pack objects in promisor packfiles"
 msgstr "packa inte objekt i kontraktspackfiler"
 
-#: builtin/pack-objects.c:3178
-msgid "Counting objects"
-msgstr "Räknar objekt"
+#: builtin/pack-objects.c:3205
+#, c-format
+msgid "delta chain depth %d is too deep, forcing %d"
+msgstr "deltakedjedjupet %d är för djupt, påtvingar %d"
+
+#: builtin/pack-objects.c:3210
+#, c-format
+msgid "pack.deltaCacheLimit is too high, forcing %d"
+msgstr "pack.deltaCacheLimit är för högt, påtvingar %d"
+
+#: builtin/pack-objects.c:3338
+msgid "Enumerating objects"
+msgstr "Räknar upp objekt"
 
-#: builtin/pack-refs.c:6
+#: builtin/pack-refs.c:7
 msgid "git pack-refs [<options>]"
 msgstr "git pack-refs [<flaggor>]"
 
-#: builtin/pack-refs.c:14
+#: builtin/pack-refs.c:15
 msgid "pack everything"
 msgstr "packa allt"
 
-#: builtin/pack-refs.c:15
+#: builtin/pack-refs.c:16
 msgid "prune loose refs (default)"
 msgstr "ta bort lösa referenser (standard)"
 
@@ -11600,65 +12082,65 @@ msgstr "Tar bort duplicerade objekt"
 msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]"
 msgstr "git prune [-n] [-v] [--progress] [--expire <tid>] [--] [<huvud>...]"
 
-#: builtin/prune.c:107
+#: builtin/prune.c:108
 msgid "report pruned objects"
 msgstr "rapportera borttagna objekt"
 
-#: builtin/prune.c:110
+#: builtin/prune.c:111
 msgid "expire objects older than <time>"
 msgstr "låt tid gå ut för objekt äldre än <tid>"
 
-#: builtin/prune.c:112
+#: builtin/prune.c:113
 msgid "limit traversal to objects outside promisor packfiles"
 msgstr "begränsa vandring av objekt utanför kontraktspackfiler."
 
-#: builtin/prune.c:126
+#: builtin/prune.c:127
 msgid "cannot prune in a precious-objects repo"
 msgstr "kan inte rensa i ett \"precious-objekt\"-arkiv"
 
-#: builtin/pull.c:54 builtin/pull.c:56
+#: builtin/pull.c:59 builtin/pull.c:61
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "Felaktigt värde för %s: %s"
 
-#: builtin/pull.c:76
+#: builtin/pull.c:81
 msgid "git pull [<options>] [<repository> [<refspec>...]]"
 msgstr "git pull [<flaggor>] [<arkiv> [<refspec>...]]"
 
-#: builtin/pull.c:127
+#: builtin/pull.c:132
 msgid "control for recursive fetching of submodules"
 msgstr "styrning för rekursiv hämtning av undermoduler"
 
-#: builtin/pull.c:131
+#: builtin/pull.c:136
 msgid "Options related to merging"
 msgstr "Alternativ gällande sammanslagning"
 
-#: builtin/pull.c:134
+#: builtin/pull.c:139
 msgid "incorporate changes by rebasing rather than merging"
 msgstr "inlemma ändringar genom ombasering i stället för sammanslagning"
 
-#: builtin/pull.c:161 builtin/rebase--helper.c:23 builtin/revert.c:121
+#: builtin/pull.c:166 builtin/rebase--helper.c:23 builtin/revert.c:121
 msgid "allow fast-forward"
 msgstr "tillåt snabbspolning"
 
-#: builtin/pull.c:170
+#: builtin/pull.c:175
 msgid "automatically stash/stash pop before and after rebase"
 msgstr "utför automatiskt stash/stash pop före och efter ombasering"
 
-#: builtin/pull.c:186
+#: builtin/pull.c:191
 msgid "Options related to fetching"
 msgstr "Alternativ gällande hämtningar"
 
-#: builtin/pull.c:204
+#: builtin/pull.c:209
 msgid "number of submodules pulled in parallel"
 msgstr "antal undermoduler som hämtas parallellt"
 
-#: builtin/pull.c:299
+#: builtin/pull.c:304
 #, c-format
 msgid "Invalid value for pull.ff: %s"
 msgstr "Felaktigt värde för pull.ff: %s"
 
-#: builtin/pull.c:415
+#: builtin/pull.c:420
 msgid ""
 "There is no candidate for rebasing against among the refs that you just "
 "fetched."
@@ -11666,14 +12148,14 @@ msgstr ""
 "Det finns ingen kandidat för ombasering bland referenserna du precis har "
 "hämtat."
 
-#: builtin/pull.c:417
+#: builtin/pull.c:422
 msgid ""
 "There are no candidates for merging among the refs that you just fetched."
 msgstr ""
 "Det finns ingen kandidat för sammanslagning bland referenserna du precis har "
 "hämtat."
 
-#: builtin/pull.c:418
+#: builtin/pull.c:423
 msgid ""
 "Generally this means that you provided a wildcard refspec which had no\n"
 "matches on the remote end."
@@ -11681,7 +12163,7 @@ msgstr ""
 "Det betyder vanligtvis att du använt en jokertecken-refspec som inte\n"
 "motsvarade något i fjärränden."
 
-#: builtin/pull.c:421
+#: builtin/pull.c:426
 #, c-format
 msgid ""
 "You asked to pull from the remote '%s', but did not specify\n"
@@ -11692,42 +12174,42 @@ msgstr ""
 "gren. Eftersom det inte är den fjärr som är konfigurerad som\n"
 "standard för aktuell gren måste du ange en gren på kommandoraden."
 
-#: builtin/pull.c:426 git-parse-remote.sh:73
+#: builtin/pull.c:431 git-parse-remote.sh:73
 msgid "You are not currently on a branch."
 msgstr "Du är inte på någon gren för närvarande."
 
-#: builtin/pull.c:428 builtin/pull.c:443 git-parse-remote.sh:79
+#: builtin/pull.c:433 builtin/pull.c:448 git-parse-remote.sh:79
 msgid "Please specify which branch you want to rebase against."
 msgstr "Ange vilken gren du vill ombasera mot."
 
-#: builtin/pull.c:430 builtin/pull.c:445 git-parse-remote.sh:82
+#: builtin/pull.c:435 builtin/pull.c:450 git-parse-remote.sh:82
 msgid "Please specify which branch you want to merge with."
 msgstr "Ange vilken gren du vill slå samman med."
 
-#: builtin/pull.c:431 builtin/pull.c:446
+#: builtin/pull.c:436 builtin/pull.c:451
 msgid "See git-pull(1) for details."
 msgstr "Se git-pull(1) för detaljer."
 
-#: builtin/pull.c:433 builtin/pull.c:439 builtin/pull.c:448
+#: builtin/pull.c:438 builtin/pull.c:444 builtin/pull.c:453
 #: git-parse-remote.sh:64
 msgid "<remote>"
 msgstr "<fjärr>"
 
-#: builtin/pull.c:433 builtin/pull.c:448 builtin/pull.c:453 git-rebase.sh:477
+#: builtin/pull.c:438 builtin/pull.c:453 builtin/pull.c:458 git-rebase.sh:523
 #: git-parse-remote.sh:65
 msgid "<branch>"
 msgstr "<gren>"
 
-#: builtin/pull.c:441 git-parse-remote.sh:75
+#: builtin/pull.c:446 git-parse-remote.sh:75
 msgid "There is no tracking information for the current branch."
 msgstr "Det finns ingen spårningsinformation för aktuell gren."
 
-#: builtin/pull.c:450 git-parse-remote.sh:95
+#: builtin/pull.c:455 git-parse-remote.sh:95
 msgid ""
 "If you wish to set tracking information for this branch you can do so with:"
 msgstr "Om du vill ange spårningsinformation för grenen kan du göra det med:"
 
-#: builtin/pull.c:455
+#: builtin/pull.c:460
 #, c-format
 msgid ""
 "Your configuration specifies to merge with the ref '%s'\n"
@@ -11736,27 +12218,27 @@ msgstr ""
 "Dina inställningar anger sammanslagning med referensen \"%s\"\n"
 "från fjärren, men någon sådan referens togs inte emot."
 
-#: builtin/pull.c:819
+#: builtin/pull.c:826
 msgid "ignoring --verify-signatures for rebase"
 msgstr "ignorera --verify-signatures för ombasering"
 
-#: builtin/pull.c:867
+#: builtin/pull.c:874
 msgid "--[no-]autostash option is only valid with --rebase."
 msgstr "--[no-]autostash är endast giltig med --rebase."
 
-#: builtin/pull.c:875
+#: builtin/pull.c:882
 msgid "Updating an unborn branch with changes added to the index."
 msgstr "Uppdaterar en ofödd gren med ändringar som lagts till i indexet."
 
-#: builtin/pull.c:878
+#: builtin/pull.c:885
 msgid "pull with rebase"
 msgstr "pull med ombasering"
 
-#: builtin/pull.c:879
+#: builtin/pull.c:886
 msgid "please commit or stash them."
 msgstr "checka in eller använd \"stash\" på dem."
 
-#: builtin/pull.c:904
+#: builtin/pull.c:911
 #, c-format
 msgid ""
 "fetch updated the current branch head.\n"
@@ -11767,7 +12249,7 @@ msgstr ""
 "snabbspolar din arbetskatalog från\n"
 "incheckningen %s."
 
-#: builtin/pull.c:909
+#: builtin/pull.c:916
 #, c-format
 msgid ""
 "Cannot fast-forward your working tree.\n"
@@ -11784,31 +12266,31 @@ msgstr ""
 "$ git reset --hard\n"
 "för att återgå."
 
-#: builtin/pull.c:924
+#: builtin/pull.c:931
 msgid "Cannot merge multiple branches into empty head."
 msgstr "Kan inte slå ihop flera grenar i ett tomt huvud."
 
-#: builtin/pull.c:928
+#: builtin/pull.c:935
 msgid "Cannot rebase onto multiple branches."
 msgstr "Kan inte ombasera ovanpå flera grenar."
 
-#: builtin/pull.c:935
+#: builtin/pull.c:942
 msgid "cannot rebase with locally recorded submodule modifications"
 msgstr "kan inte ombasera med lokalt lagrade ändringar i undermoful"
 
-#: builtin/push.c:17
+#: builtin/push.c:19
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr "git push [<flaggor>] [<arkiv> [<refspec>...]]"
 
-#: builtin/push.c:92
+#: builtin/push.c:111
 msgid "tag shorthand without <tag>"
 msgstr "taggförkortning utan <tagg>"
 
-#: builtin/push.c:102
+#: builtin/push.c:121
 msgid "--delete only accepts plain target ref names"
 msgstr "--delete godtar endast enkla målreferensnamn"
 
-#: builtin/push.c:146
+#: builtin/push.c:165
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -11817,7 +12299,7 @@ msgstr ""
 "För att välja ett av alternativen permanent, se push.default i \"git help "
 "config\"."
 
-#: builtin/push.c:149
+#: builtin/push.c:168
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -11842,7 +12324,7 @@ msgstr ""
 "    git push %s %s\n"
 "%s"
 
-#: builtin/push.c:164
+#: builtin/push.c:183
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -11857,7 +12339,7 @@ msgstr ""
 "\n"
 "    git push %s HEAD:<namn-på-fjärrgren>\n"
 
-#: builtin/push.c:178
+#: builtin/push.c:197
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -11870,12 +12352,12 @@ msgstr ""
 "\n"
 "    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:186
+#: builtin/push.c:205
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr "Den aktuella grenen %s har flera uppströmsgrenar, vägrar sända."
 
-#: builtin/push.c:189
+#: builtin/push.c:208
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -11886,14 +12368,14 @@ msgstr ""
 "aktuella grenen \"%s\", utan att tala om för mig vad som\n"
 "skall sändas för att uppdatera fjärrgrenen."
 
-#: builtin/push.c:248
+#: builtin/push.c:267
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr ""
 "Du angav inga referensspecifikationer att sända, och push.default är "
 "\"nothing\"."
 
-#: builtin/push.c:255
+#: builtin/push.c:274
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -11905,7 +12387,7 @@ msgstr ""
 "\"git pull ....\") innan du sänder igen.\n"
 "Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer."
 
-#: builtin/push.c:261
+#: builtin/push.c:280
 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"
@@ -11917,7 +12399,7 @@ msgstr ""
 "\"git pull ...\") innan du sänder igen.\n"
 "Se avsnittet \"Note about fast-forward\" i \"git push --help\" för detaljer."
 
-#: builtin/push.c:267
+#: builtin/push.c:286
 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"
@@ -11931,11 +12413,11 @@ msgstr ""
 "(t.ex. \"git pull ...\") innan du sänder igen.\n"
 "Se avsnittet \"Note about fast-forwards\" i \"git push --help\" för detaljer."
 
-#: builtin/push.c:274
+#: builtin/push.c:293
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr "Uppdateringarna avvisades eftersom taggen redan finns på fjärren."
 
-#: builtin/push.c:277
+#: builtin/push.c:296
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -11946,22 +12428,22 @@ msgstr ""
 "pekar på något som inte är en incheckning, utan att använda flaggan\n"
 "\"--force\".\n"
 
-#: builtin/push.c:337
+#: builtin/push.c:357
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "Sänder till %s\n"
 
-#: builtin/push.c:341
+#: builtin/push.c:361
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr "misslyckades sända vissa referenser till \"%s\""
 
-#: builtin/push.c:372
+#: builtin/push.c:395
 #, c-format
 msgid "bad repository '%s'"
 msgstr "felaktigt arkiv \"%s\""
 
-#: builtin/push.c:373
+#: builtin/push.c:396
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -11982,114 +12464,104 @@ msgstr ""
 "\n"
 "    git push <namn>\n"
 
-#: builtin/push.c:391
-msgid "--all and --tags are incompatible"
-msgstr "--all och --tags är inkompatibla"
-
-#: builtin/push.c:392
-msgid "--all can't be combined with refspecs"
-msgstr "--all kan inte kombineras med referensspecifikationer"
-
-#: builtin/push.c:397
-msgid "--mirror and --tags are incompatible"
-msgstr "--mirror och --tags är inkompatibla"
-
-#: builtin/push.c:398
-msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror kan inte kombineras med referensspecifikationer"
-
-#: builtin/push.c:403
-msgid "--all and --mirror are incompatible"
-msgstr "--all och --mirror är inkompatibla"
-
-#: builtin/push.c:535
+#: builtin/push.c:551
 msgid "repository"
 msgstr "arkiv"
 
-#: builtin/push.c:536 builtin/send-pack.c:163
+#: builtin/push.c:552 builtin/send-pack.c:164
 msgid "push all refs"
 msgstr "sänd alla referenser"
 
-#: builtin/push.c:537 builtin/send-pack.c:165
+#: builtin/push.c:553 builtin/send-pack.c:166
 msgid "mirror all refs"
 msgstr "spegla alla referenser"
 
-#: builtin/push.c:539
+#: builtin/push.c:555
 msgid "delete refs"
 msgstr "ta bort referenser"
 
-#: builtin/push.c:540
+#: builtin/push.c:556
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr "sänd taggar (kan inte användas med --all eller --mirror)"
 
-#: builtin/push.c:543 builtin/send-pack.c:166
+#: builtin/push.c:559 builtin/send-pack.c:167
 msgid "force updates"
 msgstr "tvinga uppdateringar"
 
-#: builtin/push.c:545 builtin/send-pack.c:180
+#: builtin/push.c:561 builtin/send-pack.c:181
 msgid "refname>:<expect"
 msgstr "refnamn>:<förvänta"
 
-#: builtin/push.c:546 builtin/send-pack.c:181
+#: builtin/push.c:562 builtin/send-pack.c:182
 msgid "require old value of ref to be at this value"
 msgstr "kräv att ref:s tidigare värde är detta"
 
-#: builtin/push.c:549
+#: builtin/push.c:565
 msgid "control recursive pushing of submodules"
 msgstr "styr rekursiv insändning av undermoduler"
 
-#: builtin/push.c:551 builtin/send-pack.c:174
+#: builtin/push.c:567 builtin/send-pack.c:175
 msgid "use thin pack"
 msgstr "använd tunna paket"
 
-#: builtin/push.c:552 builtin/push.c:553 builtin/send-pack.c:160
-#: builtin/send-pack.c:161
+#: builtin/push.c:568 builtin/push.c:569 builtin/send-pack.c:161
+#: builtin/send-pack.c:162
 msgid "receive pack program"
 msgstr "program för att ta emot paket"
 
-#: builtin/push.c:554
+#: builtin/push.c:570
 msgid "set upstream for git pull/status"
 msgstr "ställ in uppström för git pull/status"
 
-#: builtin/push.c:557
+#: builtin/push.c:573
 msgid "prune locally removed refs"
 msgstr "ta bort lokalt borttagna referenser"
 
-#: builtin/push.c:559
+#: builtin/push.c:575
 msgid "bypass pre-push hook"
 msgstr "förbigå pre-push-krok"
 
-#: builtin/push.c:560
+#: builtin/push.c:576
 msgid "push missing but relevant tags"
 msgstr "sänd in saknade men relevanta taggar"
 
-#: builtin/push.c:563 builtin/send-pack.c:168
+#: builtin/push.c:579 builtin/send-pack.c:169
 msgid "GPG sign the push"
 msgstr "GPG-signera insändningen"
 
-#: builtin/push.c:565 builtin/send-pack.c:175
+#: builtin/push.c:581 builtin/send-pack.c:176
 msgid "request atomic transaction on remote side"
 msgstr "begär atomiska transaktioner på fjärrsidan"
 
-#: builtin/push.c:566 builtin/send-pack.c:171
-msgid "server-specific"
-msgstr "serverspecifik"
-
-#: builtin/push.c:566 builtin/send-pack.c:172
-msgid "option to transmit"
-msgstr ""
-"inget att checka in\n"
-"flagga att sända"
-
-#: builtin/push.c:583
+#: builtin/push.c:599
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr "--delete är inkompatibel med --all, --mirror och --tags"
 
-#: builtin/push.c:585
+#: builtin/push.c:601
 msgid "--delete doesn't make sense without any refs"
 msgstr "--delete kan inte användas utan referenser"
 
 #: builtin/push.c:604
+msgid "--all and --tags are incompatible"
+msgstr "--all och --tags är inkompatibla"
+
+#: builtin/push.c:606
+msgid "--all can't be combined with refspecs"
+msgstr "--all kan inte kombineras med referensspecifikationer"
+
+#: builtin/push.c:610
+msgid "--mirror and --tags are incompatible"
+msgstr "--mirror och --tags är inkompatibla"
+
+#: builtin/push.c:612
+msgid "--mirror can't be combined with refspecs"
+msgstr "--mirror kan inte kombineras med referensspecifikationer"
+
+#: builtin/push.c:615
+msgid "--all and --mirror are incompatible"
+msgstr "--all och --mirror är inkompatibla"
+
+#: builtin/push.c:634
 msgid "push options must not have new line characters"
 msgstr "push-flaggor kan inte innehålla radbrytning"
 
@@ -12103,67 +12575,67 @@ msgstr ""
 "[-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--"
 "index-output=<fil>] (--empty | <träd-igt1> [<träd-igt2> [<träd-igt3>]])"
 
-#: builtin/read-tree.c:121
+#: builtin/read-tree.c:120
 msgid "write resulting index to <file>"
 msgstr "skriv resulterande index till <fil>"
 
-#: builtin/read-tree.c:124
+#: builtin/read-tree.c:123
 msgid "only empty the index"
 msgstr "töm bara indexet"
 
-#: builtin/read-tree.c:126
+#: builtin/read-tree.c:125
 msgid "Merging"
 msgstr "Sammanslagning"
 
-#: builtin/read-tree.c:128
+#: builtin/read-tree.c:127
 msgid "perform a merge in addition to a read"
 msgstr "utför en sammanslagning i tillägg till en läsning"
 
-#: builtin/read-tree.c:130
+#: builtin/read-tree.c:129
 msgid "3-way merge if no file level merging required"
 msgstr "3-vägssammanslagning om sammanslagning på filnivå ej krävs"
 
-#: builtin/read-tree.c:132
+#: builtin/read-tree.c:131
 msgid "3-way merge in presence of adds and removes"
 msgstr "3-vägssammanslagning när det finns tillägg och borttagningar"
 
-#: builtin/read-tree.c:134
+#: builtin/read-tree.c:133
 msgid "same as -m, but discard unmerged entries"
 msgstr "som -m, men kasta bort ej sammanslagna poster"
 
-#: builtin/read-tree.c:135
+#: builtin/read-tree.c:134
 msgid "<subdirectory>/"
 msgstr "<underkatalog>/"
 
-#: builtin/read-tree.c:136
+#: builtin/read-tree.c:135
 msgid "read the tree into the index under <subdirectory>/"
 msgstr "läs in trädet i indexet under <underkatalog>/"
 
-#: builtin/read-tree.c:139
+#: builtin/read-tree.c:138
 msgid "update working tree with merge result"
 msgstr "uppdatera arbetskatalogen med resultatet från sammanslagningen"
 
-#: builtin/read-tree.c:141
+#: builtin/read-tree.c:140
 msgid "gitignore"
 msgstr "gitignore"
 
-#: builtin/read-tree.c:142
+#: builtin/read-tree.c:141
 msgid "allow explicitly ignored files to be overwritten"
 msgstr "tillåt explicit ignorerade filer att skrivas över"
 
-#: builtin/read-tree.c:145
+#: builtin/read-tree.c:144
 msgid "don't check the working tree after merging"
 msgstr "kontrollera inte arbetskatalogen efter sammanslagning"
 
-#: builtin/read-tree.c:146
+#: builtin/read-tree.c:145
 msgid "don't update the index or the work tree"
 msgstr "uppdatera inte indexet eller arbetskatalogen"
 
-#: builtin/read-tree.c:148
+#: builtin/read-tree.c:147
 msgid "skip applying sparse checkout filter"
 msgstr "hoppa över att applicera filter för gles utcheckning"
 
-#: builtin/read-tree.c:150
+#: builtin/read-tree.c:149
 msgid "debug unpack-trees"
 msgstr "felsök unpack-trees"
 
@@ -12180,46 +12652,58 @@ msgid "allow commits with empty messages"
 msgstr "tillåt incheckningar med tomt meddelande"
 
 #: builtin/rebase--helper.c:27
+msgid "rebase merge commits"
+msgstr "ombasera sammanslagningar"
+
+#: builtin/rebase--helper.c:29
+msgid "keep original branch points of cousins"
+msgstr "behåll ursprungliga förgreningspunkter för kusiner"
+
+#: builtin/rebase--helper.c:30
 msgid "continue rebase"
 msgstr "fortsätt ombasering"
 
-#: builtin/rebase--helper.c:29
+#: builtin/rebase--helper.c:32
 msgid "abort rebase"
 msgstr "avbryt ombasering"
 
-#: builtin/rebase--helper.c:32
+#: builtin/rebase--helper.c:35
 msgid "make rebase script"
 msgstr "skapa ombaseringsskript"
 
-#: builtin/rebase--helper.c:34
+#: builtin/rebase--helper.c:37
 msgid "shorten commit ids in the todo list"
 msgstr "förkorta inchecknings-id i todo-listan"
 
-#: builtin/rebase--helper.c:36
+#: builtin/rebase--helper.c:39
 msgid "expand commit ids in the todo list"
 msgstr "utöka inchecknings-id i todo-listan"
 
-#: builtin/rebase--helper.c:38
+#: builtin/rebase--helper.c:41
 msgid "check the todo list"
 msgstr "kontrollera todo-listan"
 
-#: builtin/rebase--helper.c:40
+#: builtin/rebase--helper.c:43
 msgid "skip unnecessary picks"
 msgstr "hoppa över onödiga \"pick\"-kommandon"
 
-#: builtin/rebase--helper.c:42
+#: builtin/rebase--helper.c:45
 msgid "rearrange fixup/squash lines"
 msgstr "ordna om fixup-/squash-rader"
 
-#: builtin/rebase--helper.c:44
+#: builtin/rebase--helper.c:47
 msgid "insert exec commands in todo list"
 msgstr "lägg in exec-kommandon i todo-listan"
 
-#: builtin/receive-pack.c:30
+#: builtin/rebase--helper.c:68
+msgid "--[no-]rebase-cousins has no effect without --rebase-merges"
+msgstr "--[no-]rebase-cousins har ingen effekt utan --rebase-merges"
+
+#: builtin/receive-pack.c:31
 msgid "git receive-pack <git-dir>"
 msgstr "git receive-pack <git-katalog>"
 
-#: builtin/receive-pack.c:841
+#: builtin/receive-pack.c:842
 msgid ""
 "By default, updating the current branch in a non-bare repository\n"
 "is denied, because it will make the index and work tree inconsistent\n"
@@ -12249,7 +12733,7 @@ msgstr ""
 "För att undvika detta meddelande och fortfarande behålla det\n"
 "normala beteendet, sätt \"receive.denyCurrentBranch\" till \"refuse\"."
 
-#: builtin/receive-pack.c:861
+#: builtin/receive-pack.c:862
 msgid ""
 "By default, deleting the current branch is denied, because the next\n"
 "'git clone' won't result in any file checked out, causing confusion.\n"
@@ -12270,11 +12754,11 @@ msgstr ""
 "\n"
 "För att undvika detta meddelande kan du sätta det till \"refuse\"."
 
-#: builtin/receive-pack.c:1934
+#: builtin/receive-pack.c:1935
 msgid "quiet"
 msgstr "tyst"
 
-#: builtin/receive-pack.c:1948
+#: builtin/receive-pack.c:1949
 msgid "You must specify a directory."
 msgstr "Du måste ange en katalog."
 
@@ -12283,11 +12767,11 @@ msgstr "Du måste ange en katalog."
 msgid "'%s' is not a valid timestamp"
 msgstr "\"%s\" är inte en giltig tidsstämpel"
 
-#: builtin/remote.c:13
+#: builtin/remote.c:14
 msgid "git remote [-v | --verbose]"
 msgstr "git remote [-v | --verbose]"
 
-#: builtin/remote.c:14
+#: builtin/remote.c:15
 msgid ""
 "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <name> <url>"
@@ -12295,82 +12779,82 @@ msgstr ""
 "git remote add [-t <gren>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <namn> <url>"
 
-#: builtin/remote.c:15 builtin/remote.c:35
+#: builtin/remote.c:16 builtin/remote.c:36
 msgid "git remote rename <old> <new>"
 msgstr "git remote rename <gammal> <ny>"
 
-#: builtin/remote.c:16 builtin/remote.c:40
+#: builtin/remote.c:17 builtin/remote.c:41
 msgid "git remote remove <name>"
 msgstr "git remote remove <namn>"
 
-#: builtin/remote.c:17 builtin/remote.c:45
+#: builtin/remote.c:18 builtin/remote.c:46
 msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
 msgstr "git remote set-head <namn> (-a | --auto | -d | --delete | <gren>)"
 
-#: builtin/remote.c:18
+#: builtin/remote.c:19
 msgid "git remote [-v | --verbose] show [-n] <name>"
 msgstr "git remote [-v | --verbose] show [-n] <namn>"
 
-#: builtin/remote.c:19
+#: builtin/remote.c:20
 msgid "git remote prune [-n | --dry-run] <name>"
 msgstr "git remote prune [-n | --dry-run] <namn>"
 
-#: builtin/remote.c:20
+#: builtin/remote.c:21
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
 msgstr ""
 "git remote [-v | --verbose] update [-p | --prune] [(<grupp> | <fjärr>)...]"
 
-#: builtin/remote.c:21
+#: builtin/remote.c:22
 msgid "git remote set-branches [--add] <name> <branch>..."
 msgstr "git remote set-branches [--add] <namn> <gren>..."
 
-#: builtin/remote.c:22 builtin/remote.c:71
+#: builtin/remote.c:23 builtin/remote.c:72
 msgid "git remote get-url [--push] [--all] <name>"
 msgstr "git remote get-url [--push] [--all] <namn>"
 
-#: builtin/remote.c:23 builtin/remote.c:76
+#: builtin/remote.c:24 builtin/remote.c:77
 msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]"
 msgstr "git remote set-url [--push] <namn> <nyurl> [<gammalurl>]"
 
-#: builtin/remote.c:24 builtin/remote.c:77
+#: builtin/remote.c:25 builtin/remote.c:78
 msgid "git remote set-url --add <name> <newurl>"
 msgstr "git remote set-url --add <namn> <nyurl>"
 
-#: builtin/remote.c:25 builtin/remote.c:78
+#: builtin/remote.c:26 builtin/remote.c:79
 msgid "git remote set-url --delete <name> <url>"
 msgstr "git remote set-url --delete <namn> <url>"
 
-#: builtin/remote.c:30
+#: builtin/remote.c:31
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<flaggor>] <namn> <url>"
 
-#: builtin/remote.c:50
+#: builtin/remote.c:51
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <namn> <gren>..."
 
-#: builtin/remote.c:51
+#: builtin/remote.c:52
 msgid "git remote set-branches --add <name> <branch>..."
 msgstr "git remote set-branches --add <namn> <gren>..."
 
-#: builtin/remote.c:56
+#: builtin/remote.c:57
 msgid "git remote show [<options>] <name>"
 msgstr "git remote show [<flaggor>] <namn>"
 
-#: builtin/remote.c:61
+#: builtin/remote.c:62
 msgid "git remote prune [<options>] <name>"
 msgstr "git remote prune [<flaggor>] <namn>"
 
-#: builtin/remote.c:66
+#: builtin/remote.c:67
 msgid "git remote update [<options>] [<group> | <remote>]..."
 msgstr "git remote update [<flaggor>] [<grupp> | <fjärr>]..."
 
-#: builtin/remote.c:95
+#: builtin/remote.c:96
 #, c-format
 msgid "Updating %s"
 msgstr "Uppdaterar %s"
 
-#: builtin/remote.c:127
+#: builtin/remote.c:128
 msgid ""
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
@@ -12378,86 +12862,86 @@ msgstr ""
 "--mirror är farlig och föråldrad; använd\n"
 "\t --mirror=fetch eller --mirror=push istället"
 
-#: builtin/remote.c:144
+#: builtin/remote.c:145
 #, c-format
 msgid "unknown mirror argument: %s"
 msgstr "okänt argument till mirror: %s"
 
-#: builtin/remote.c:160
+#: builtin/remote.c:161
 msgid "fetch the remote branches"
 msgstr "hämta fjärrgrenarna"
 
-#: builtin/remote.c:162
+#: builtin/remote.c:163
 msgid "import all tags and associated objects when fetching"
 msgstr "importera alla taggar och associerade objekt vid hämtning"
 
-#: builtin/remote.c:165
+#: builtin/remote.c:166
 msgid "or do not fetch any tag at all (--no-tags)"
 msgstr "eller hämta inte några taggar alls (--no-tags)"
 
-#: builtin/remote.c:167
+#: builtin/remote.c:168
 msgid "branch(es) to track"
 msgstr "gren(ar) att spåra"
 
-#: builtin/remote.c:168
+#: builtin/remote.c:169
 msgid "master branch"
 msgstr "huvudgren"
 
-#: builtin/remote.c:169
+#: builtin/remote.c:170
 msgid "push|fetch"
 msgstr "push|fetch"
 
-#: builtin/remote.c:170
+#: builtin/remote.c:171
 msgid "set up remote as a mirror to push to or fetch from"
 msgstr "ställ in arkiv som spegel att sända eller ta emot från"
 
-#: builtin/remote.c:182
+#: builtin/remote.c:183
 msgid "specifying a master branch makes no sense with --mirror"
 msgstr "att ange en master-gren ger ingen mening med --mirror"
 
-#: builtin/remote.c:184
+#: builtin/remote.c:185
 msgid "specifying branches to track makes sense only with fetch mirrors"
 msgstr "att ange grenar att spåra ger mening bara med hämtningsspeglar"
 
-#: builtin/remote.c:191 builtin/remote.c:631
+#: builtin/remote.c:192 builtin/remote.c:634
 #, c-format
 msgid "remote %s already exists."
 msgstr "fjärrarkivet %s finns redan."
 
-#: builtin/remote.c:195 builtin/remote.c:635
+#: builtin/remote.c:196 builtin/remote.c:638
 #, c-format
 msgid "'%s' is not a valid remote name"
 msgstr "\"%s\" är inte ett giltigt namn på fjärrarkiv"
 
-#: builtin/remote.c:235
+#: builtin/remote.c:236
 #, c-format
 msgid "Could not setup master '%s'"
 msgstr "Kunde inte skapa master \"%s\""
 
-#: builtin/remote.c:337
+#: builtin/remote.c:342
 #, c-format
 msgid "Could not get fetch map for refspec %s"
 msgstr "Kunde inte hämta mappning för referensspecifikation %s"
 
-#: builtin/remote.c:438 builtin/remote.c:446
+#: builtin/remote.c:441 builtin/remote.c:449
 msgid "(matching)"
 msgstr "(matchande)"
 
-#: builtin/remote.c:450
+#: builtin/remote.c:453
 msgid "(delete)"
 msgstr "(ta bort)"
 
-#: builtin/remote.c:624 builtin/remote.c:759 builtin/remote.c:858
+#: builtin/remote.c:627 builtin/remote.c:762 builtin/remote.c:861
 #, c-format
 msgid "No such remote: %s"
 msgstr "Inget sådant fjärrarkiv: %s"
 
-#: builtin/remote.c:641
+#: builtin/remote.c:644
 #, c-format
 msgid "Could not rename config section '%s' to '%s'"
 msgstr "Kunde inte byta namn på konfigurationssektionen \"%s\" till \"%s\""
 
-#: builtin/remote.c:661
+#: builtin/remote.c:664
 #, c-format
 msgid ""
 "Not updating non-default fetch refspec\n"
@@ -12468,17 +12952,17 @@ msgstr ""
 "\t%s\n"
 "\tUppdatera konfigurationen manuellt om nödvändigt."
 
-#: builtin/remote.c:697
+#: builtin/remote.c:700
 #, c-format
 msgid "deleting '%s' failed"
 msgstr "misslyckades ta bort \"%s\""
 
-#: builtin/remote.c:731
+#: builtin/remote.c:734
 #, c-format
 msgid "creating '%s' failed"
 msgstr "misslyckades skapa \"%s\""
 
-#: builtin/remote.c:796
+#: builtin/remote.c:799
 msgid ""
 "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
 "to delete it, use:"
@@ -12492,113 +12976,118 @@ msgstr[1] ""
 "Observera: Några grenar utanför hierarkin refs/remotes/ togs inte bort;\n"
 "för att ta bort dem, använd:"
 
-#: builtin/remote.c:810
+#: builtin/remote.c:813
 #, c-format
 msgid "Could not remove config section '%s'"
 msgstr "Kunde inte ta bort konfigurationssektionen \"%s\""
 
-#: builtin/remote.c:911
+#: builtin/remote.c:914
 #, c-format
 msgid " new (next fetch will store in remotes/%s)"
 msgstr " ny (nästa hämtning sparar i remotes/%s)"
 
-#: builtin/remote.c:914
+#: builtin/remote.c:917
 msgid " tracked"
 msgstr " spårad"
 
-#: builtin/remote.c:916
+#: builtin/remote.c:919
 msgid " stale (use 'git remote prune' to remove)"
 msgstr " förlegad (använd \"git remote prune\" för att ta bort)"
 
-#: builtin/remote.c:918
+#: builtin/remote.c:921
 msgid " ???"
 msgstr " ???"
 
-#: builtin/remote.c:959
+#: builtin/remote.c:962
 #, c-format
 msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
 msgstr "ogiltig branch.%s.merge; kan inte ombasera över > 1 gren"
 
-#: builtin/remote.c:967
+#: builtin/remote.c:971
 #, c-format
 msgid "rebases interactively onto remote %s"
 msgstr "ombaseras interaktivt på fjärren %s"
 
-#: builtin/remote.c:968
+#: builtin/remote.c:973
+#, c-format
+msgid "rebases interactively (with merges) onto remote %s"
+msgstr "ombaseras interaktivt (med sammanslagningar) på fjärren %s"
+
+#: builtin/remote.c:976
 #, c-format
 msgid "rebases onto remote %s"
 msgstr "ombaseras på fjärren %s"
 
-#: builtin/remote.c:971
+#: builtin/remote.c:980
 #, c-format
 msgid " merges with remote %s"
 msgstr " sammanslås med fjärren %s"
 
-#: builtin/remote.c:974
+#: builtin/remote.c:983
 #, c-format
 msgid "merges with remote %s"
 msgstr "sammanslås med fjärren %s"
 
-#: builtin/remote.c:977
+#: builtin/remote.c:986
 #, c-format
 msgid "%-*s    and with remote %s\n"
 msgstr "%-*s    och med fjärren %s\n"
 
-#: builtin/remote.c:1020
+#: builtin/remote.c:1029
 msgid "create"
 msgstr "skapa"
 
-#: builtin/remote.c:1023
+#: builtin/remote.c:1032
 msgid "delete"
 msgstr "ta bort"
 
-#: builtin/remote.c:1027
+#: builtin/remote.c:1036
 msgid "up to date"
 msgstr "àjour"
 
-#: builtin/remote.c:1030
+#: builtin/remote.c:1039
 msgid "fast-forwardable"
 msgstr "kan snabbspolas"
 
-#: builtin/remote.c:1033
+#: builtin/remote.c:1042
 msgid "local out of date"
 msgstr "lokal föråldrad"
 
-#: builtin/remote.c:1040
+#: builtin/remote.c:1049
 #, c-format
 msgid "    %-*s forces to %-*s (%s)"
 msgstr "    %-*s tvingar till %-*s (%s)"
 
-#: builtin/remote.c:1043
+#: builtin/remote.c:1052
 #, c-format
 msgid "    %-*s pushes to %-*s (%s)"
 msgstr "    %-*s sänder till %-*s (%s)"
 
-#: builtin/remote.c:1047
+#: builtin/remote.c:1056
 #, c-format
 msgid "    %-*s forces to %s"
 msgstr "    %-*s tvingar till %s"
 
-#: builtin/remote.c:1050
+#: builtin/remote.c:1059
 #, c-format
 msgid "    %-*s pushes to %s"
 msgstr "    %-*s sänder till %s"
 
-#: builtin/remote.c:1118
+#: builtin/remote.c:1127
 msgid "do not query remotes"
 msgstr "fråga inte fjärrar"
 
-#: builtin/remote.c:1145
+#: builtin/remote.c:1154
 #, c-format
 msgid "* remote %s"
 msgstr "* fjärr %s"
 
-#: builtin/remote.c:1146
+#: builtin/remote.c:1155
 #, c-format
 msgid "  Fetch URL: %s"
 msgstr "  Hämt-URL: %s"
 
-#: builtin/remote.c:1147 builtin/remote.c:1163 builtin/remote.c:1302
+#: builtin/remote.c:1156 builtin/remote.c:1172 builtin/remote.c:1311
 msgid "(no URL)"
 msgstr "(ingen URL)"
 
@@ -12606,184 +13095,184 @@ msgstr "(ingen URL)"
 #. with the one in " Fetch URL: %s"
 #. translation.
 #.
-#: builtin/remote.c:1161 builtin/remote.c:1163
+#: builtin/remote.c:1170 builtin/remote.c:1172
 #, c-format
 msgid "  Push  URL: %s"
 msgstr "  Sänd-URL: %s"
 
-#: builtin/remote.c:1165 builtin/remote.c:1167 builtin/remote.c:1169
+#: builtin/remote.c:1174 builtin/remote.c:1176 builtin/remote.c:1178
 #, c-format
 msgid "  HEAD branch: %s"
 msgstr "  HEAD-gren: %s"
 
-#: builtin/remote.c:1165
+#: builtin/remote.c:1174
 msgid "(not queried)"
 msgstr "(inte förfrågad)"
 
-#: builtin/remote.c:1167
+#: builtin/remote.c:1176
 msgid "(unknown)"
 msgstr "(okänd)"
 
-#: builtin/remote.c:1171
+#: builtin/remote.c:1180
 #, c-format
 msgid ""
 "  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
 msgstr "  HEAD-gren (HEAD på fjärr är tvetydig, kan vara en av följande):\n"
 
-#: builtin/remote.c:1183
+#: builtin/remote.c:1192
 #, c-format
 msgid "  Remote branch:%s"
 msgid_plural "  Remote branches:%s"
 msgstr[0] "  Fjärrgren:%s"
 msgstr[1] "  Fjärrgrenar:%s"
 
-#: builtin/remote.c:1186 builtin/remote.c:1212
+#: builtin/remote.c:1195 builtin/remote.c:1221
 msgid " (status not queried)"
 msgstr " (status inte förfrågad)"
 
-#: builtin/remote.c:1195
+#: builtin/remote.c:1204
 msgid "  Local branch configured for 'git pull':"
 msgid_plural "  Local branches configured for 'git pull':"
 msgstr[0] "  Lokal gren konfigurerad för \"git pull\":"
 msgstr[1] "  Lokala grenar konfigurerade för \"git pull\":"
 
-#: builtin/remote.c:1203
+#: builtin/remote.c:1212
 msgid "  Local refs will be mirrored by 'git push'"
 msgstr "  Lokala referenser speglas av \"git push\""
 
-#: builtin/remote.c:1209
+#: builtin/remote.c:1218
 #, c-format
 msgid "  Local ref configured for 'git push'%s:"
 msgid_plural "  Local refs configured for 'git push'%s:"
 msgstr[0] "  Lokal referens konfigurerad för \"git push\"%s:"
 msgstr[1] "  Lokala referenser konfigurerade för \"git push\"%s:"
 
-#: builtin/remote.c:1230
+#: builtin/remote.c:1239
 msgid "set refs/remotes/<name>/HEAD according to remote"
 msgstr "sätt refs/remotes/<namn>/HEAD enligt fjärren"
 
-#: builtin/remote.c:1232
+#: builtin/remote.c:1241
 msgid "delete refs/remotes/<name>/HEAD"
 msgstr "ta bort refs/remotes/<namn>/HEAD"
 
-#: builtin/remote.c:1247
+#: builtin/remote.c:1256
 msgid "Cannot determine remote HEAD"
 msgstr "Kan inte bestämma HEAD på fjärren"
 
-#: builtin/remote.c:1249
+#: builtin/remote.c:1258
 msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
 msgstr "Flera HEAD-grenar på fjärren. Välj en explicit med:"
 
-#: builtin/remote.c:1259
+#: builtin/remote.c:1268
 #, c-format
 msgid "Could not delete %s"
 msgstr "Kunde inte ta bort %s"
 
-#: builtin/remote.c:1267
+#: builtin/remote.c:1276
 #, c-format
 msgid "Not a valid ref: %s"
 msgstr "Inte en giltig referens: %s"
 
-#: builtin/remote.c:1269
+#: builtin/remote.c:1278
 #, c-format
 msgid "Could not setup %s"
 msgstr "Kunde inte ställa in %s"
 
-#: builtin/remote.c:1287
+#: builtin/remote.c:1296
 #, c-format
 msgid " %s will become dangling!"
 msgstr " %s kommer bli dinglande!"
 
-#: builtin/remote.c:1288
+#: builtin/remote.c:1297
 #, c-format
 msgid " %s has become dangling!"
 msgstr " %s har blivit dinglande!"
 
-#: builtin/remote.c:1298
+#: builtin/remote.c:1307
 #, c-format
 msgid "Pruning %s"
 msgstr "Rensar %s"
 
-#: builtin/remote.c:1299
+#: builtin/remote.c:1308
 #, c-format
 msgid "URL: %s"
 msgstr "URL: %s"
 
-#: builtin/remote.c:1315
+#: builtin/remote.c:1324
 #, c-format
 msgid " * [would prune] %s"
 msgstr " * [skulle rensa] %s"
 
-#: builtin/remote.c:1318
+#: builtin/remote.c:1327
 #, c-format
 msgid " * [pruned] %s"
 msgstr " * [rensad] %s"
 
-#: builtin/remote.c:1363
+#: builtin/remote.c:1372
 msgid "prune remotes after fetching"
 msgstr "rensa fjärrar efter hämtning"
 
-#: builtin/remote.c:1426 builtin/remote.c:1480 builtin/remote.c:1548
+#: builtin/remote.c:1435 builtin/remote.c:1489 builtin/remote.c:1557
 #, c-format
 msgid "No such remote '%s'"
 msgstr "Ingen sådan fjärr \"%s\""
 
-#: builtin/remote.c:1442
+#: builtin/remote.c:1451
 msgid "add branch"
 msgstr "lägg till gren"
 
-#: builtin/remote.c:1449
+#: builtin/remote.c:1458
 msgid "no remote specified"
 msgstr "ingen fjärr angavs"
 
-#: builtin/remote.c:1466
+#: builtin/remote.c:1475
 msgid "query push URLs rather than fetch URLs"
 msgstr "fråga sänd-URL:er istället för hämta-URL:er"
 
-#: builtin/remote.c:1468
+#: builtin/remote.c:1477
 msgid "return all URLs"
 msgstr "returnera alla URL:er"
 
-#: builtin/remote.c:1496
+#: builtin/remote.c:1505
 #, c-format
 msgid "no URLs configured for remote '%s'"
 msgstr "ingen URL:er angivna för fjärren \"%s\""
 
-#: builtin/remote.c:1522
+#: builtin/remote.c:1531
 msgid "manipulate push URLs"
 msgstr "manipulera URL:ar för sändning"
 
-#: builtin/remote.c:1524
+#: builtin/remote.c:1533
 msgid "add URL"
 msgstr "lägg till URL"
 
-#: builtin/remote.c:1526
+#: builtin/remote.c:1535
 msgid "delete URLs"
 msgstr "ta bort URL:ar"
 
-#: builtin/remote.c:1533
+#: builtin/remote.c:1542
 msgid "--add --delete doesn't make sense"
 msgstr "--add --delete ger ingen mening"
 
-#: builtin/remote.c:1572
+#: builtin/remote.c:1581
 #, c-format
 msgid "Invalid old URL pattern: %s"
 msgstr "Felaktig gammalt URL-mönster: %s"
 
-#: builtin/remote.c:1580
+#: builtin/remote.c:1589
 #, c-format
 msgid "No such URL found: %s"
 msgstr "Ingen sådan URL hittades: %s"
 
-#: builtin/remote.c:1582
+#: builtin/remote.c:1591
 msgid "Will not delete all non-push URLs"
 msgstr "Kommer inte ta bort alla icke-sänd-URL:er"
 
-#: builtin/remote.c:1598
+#: builtin/remote.c:1607
 msgid "be verbose; must be placed before a subcommand"
 msgstr "var pratsam; måste skrivas före ett underkommando"
 
-#: builtin/remote.c:1629
+#: builtin/remote.c:1638
 #, c-format
 msgid "Unknown subcommand: %s"
 msgstr "Okänt underkommando: %s"
@@ -12801,127 +13290,135 @@ msgstr ""
 "Använd --no-write-bitmap-index eller inaktivera inställningen\n"
 "pack.writebitmaps"
 
-#: builtin/repack.c:170
+#: builtin/repack.c:180
 msgid "pack everything in a single pack"
 msgstr "packa allt i ett enda paket"
 
-#: builtin/repack.c:172
+#: builtin/repack.c:182
 msgid "same as -a, and turn unreachable objects loose"
 msgstr "samma som -a, och gör onåbara objekt lösa"
 
-#: builtin/repack.c:175
+#: builtin/repack.c:185
 msgid "remove redundant packs, and run git-prune-packed"
 msgstr "ta bort överflödiga paket, och kör git-prune-packed"
 
-#: builtin/repack.c:177
+#: builtin/repack.c:187
 msgid "pass --no-reuse-delta to git-pack-objects"
 msgstr "sänd --no-reuse-delta till git-pack-objects"
 
-#: builtin/repack.c:179
+#: builtin/repack.c:189
 msgid "pass --no-reuse-object to git-pack-objects"
 msgstr "sänd --no-reuse-object till git-pack-objects"
 
-#: builtin/repack.c:181
+#: builtin/repack.c:191
 msgid "do not run git-update-server-info"
 msgstr "kör inte git-update-server-info"
 
-#: builtin/repack.c:184
+#: builtin/repack.c:194
 msgid "pass --local to git-pack-objects"
 msgstr "sänd --local till git-pack-objects"
 
-#: builtin/repack.c:186
+#: builtin/repack.c:196
 msgid "write bitmap index"
 msgstr "skriv bitkartindex"
 
-#: builtin/repack.c:187
+#: builtin/repack.c:197
 msgid "approxidate"
 msgstr "cirkadatum"
 
-#: builtin/repack.c:188
+#: builtin/repack.c:198
 msgid "with -A, do not loosen objects older than this"
 msgstr "med -A, lös inte upp objekt äldre än detta"
 
-#: builtin/repack.c:190
+#: builtin/repack.c:200
 msgid "with -a, repack unreachable objects"
 msgstr "med -a, packa om onåbara objekt"
 
-#: builtin/repack.c:192
+#: builtin/repack.c:202
 msgid "size of the window used for delta compression"
 msgstr "storlek på fönster använt för deltakomprimering"
 
-#: builtin/repack.c:193 builtin/repack.c:199
+#: builtin/repack.c:203 builtin/repack.c:209
 msgid "bytes"
 msgstr "byte"
 
-#: builtin/repack.c:194
+#: builtin/repack.c:204
 msgid "same as the above, but limit memory size instead of entries count"
 msgstr "samma som ovan, men begränsa minnesstorleken istället för postantal"
 
-#: builtin/repack.c:196
+#: builtin/repack.c:206
 msgid "limits the maximum delta depth"
 msgstr "begränsa maximalt deltadjup"
 
-#: builtin/repack.c:198
+#: builtin/repack.c:208
 msgid "limits the maximum number of threads"
 msgstr "begränsar maximalt antal trådar"
 
-#: builtin/repack.c:200
+#: builtin/repack.c:210
 msgid "maximum size of each packfile"
 msgstr "maximal storlek på varje paketfil"
 
-#: builtin/repack.c:202
+#: builtin/repack.c:212
 msgid "repack objects in packs marked with .keep"
 msgstr "packa om objekt i paket märkta med .keep"
 
-#: builtin/repack.c:212
+#: builtin/repack.c:214
+msgid "do not repack this pack"
+msgstr "packa inte om detta paket"
+
+#: builtin/repack.c:224
 msgid "cannot delete packs in a precious-objects repo"
 msgstr "kan inte ta bort paket i ett \"precious-objects\"-arkiv"
 
-#: builtin/repack.c:216
+#: builtin/repack.c:228
 msgid "--keep-unreachable and -A are incompatible"
 msgstr "--keep-unreachable och -A kan inte användas samtidigt"
 
-#: builtin/repack.c:410 builtin/worktree.c:148
+#: builtin/repack.c:425 builtin/worktree.c:139
 #, c-format
 msgid "failed to remove '%s'"
 msgstr "misslyckades ta bort \"%s\""
 
-#: builtin/replace.c:20
+#: builtin/replace.c:22
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <objekt> <ersättning>"
 
-#: builtin/replace.c:21
+#: builtin/replace.c:23
 msgid "git replace [-f] --edit <object>"
 msgstr "git replace [-f] --edit <objekt>"
 
-#: builtin/replace.c:22
+#: builtin/replace.c:24
 msgid "git replace [-f] --graft <commit> [<parent>...]"
 msgstr "git replace [-f] --graft <incheckning> [<förälder>...]"
 
-#: builtin/replace.c:23
+#: builtin/replace.c:25
+msgid "git replace [-f] --convert-graft-file"
+msgstr "git replace [-f] --convert-graft-file"
+
+#: builtin/replace.c:26
 msgid "git replace -d <object>..."
 msgstr "git replace -d <objekt>..."
 
-#: builtin/replace.c:24
+#: builtin/replace.c:27
 msgid "git replace [--format=<format>] [-l [<pattern>]]"
 msgstr "git replace [--format=<format>] [-l [<mönster>]]"
 
-#: builtin/replace.c:331 builtin/replace.c:369 builtin/replace.c:397
+#: builtin/replace.c:371 builtin/replace.c:415 builtin/replace.c:445
 #, c-format
 msgid "Not a valid object name: '%s'"
 msgstr "Objektnamnet är inte giltigt: \"%s\""
 
-#: builtin/replace.c:361
+#: builtin/replace.c:407
 #, c-format
 msgid "bad mergetag in commit '%s'"
 msgstr "felaktig sammanslagningstagg i incheckningen \"%s\""
 
-#: builtin/replace.c:363
+#: builtin/replace.c:409
 #, c-format
 msgid "malformed mergetag in commit '%s'"
 msgstr "felformad sammanslagningstagg i incheckningen \"%s\""
 
-#: builtin/replace.c:374
+#: builtin/replace.c:421
 #, c-format
 msgid ""
 "original commit '%s' contains mergetag '%s' that is discarded; use --edit "
@@ -12930,45 +13427,58 @@ msgstr ""
 "den ursprungliga incheckningen \"%s\" innehåller sammanslagningstaggen \"%s"
 "\" som har förkastats; använd --edit istället för --graft"
 
-#: builtin/replace.c:407
+#: builtin/replace.c:460
 #, c-format
 msgid "the original commit '%s' has a gpg signature."
 msgstr "den ursprungliga incheckningen \"%s\" har en gpg-signatur."
 
-#: builtin/replace.c:408
+#: builtin/replace.c:461
 msgid "the signature will be removed in the replacement commit!"
 msgstr "signaturen kommer att tas bort i ersättningsincheckningen!"
 
-#: builtin/replace.c:414
+#: builtin/replace.c:471
 #, c-format
 msgid "could not write replacement commit for: '%s'"
 msgstr "kunde inte skriva ersättningsincheckning för: \"%s\""
 
-#: builtin/replace.c:438
+#: builtin/replace.c:514
+#, c-format
+msgid ""
+"could not convert the following graft(s):\n"
+"%s"
+msgstr ""
+"kunde inte konvertera följande ympning(ar):\n"
+"%s"
+
+#: builtin/replace.c:535
 msgid "list replace refs"
 msgstr "visa ersättningsreferenser"
 
-#: builtin/replace.c:439
+#: builtin/replace.c:536
 msgid "delete replace refs"
 msgstr "ta bort ersättningsreferenser"
 
-#: builtin/replace.c:440
+#: builtin/replace.c:537
 msgid "edit existing object"
 msgstr "redigera befintligt objekt"
 
-#: builtin/replace.c:441
+#: builtin/replace.c:538
 msgid "change a commit's parents"
 msgstr "ändra en inchecknings föräldrar"
 
-#: builtin/replace.c:442
+#: builtin/replace.c:539
+msgid "convert existing graft file"
+msgstr "konvertera befintlig ympningsfil"
+
+#: builtin/replace.c:540
 msgid "replace the ref if it exists"
 msgstr "ersätt referensen om den finns"
 
-#: builtin/replace.c:444
+#: builtin/replace.c:542
 msgid "do not pretty-print contents for --edit"
 msgstr "använd inte snygg visning av innehåll för --edit"
 
-#: builtin/replace.c:445
+#: builtin/replace.c:543
 msgid "use this format"
 msgstr "använd detta format"
 
@@ -13020,12 +13530,12 @@ msgstr "Du har inte en giltig HEAD."
 
 #: builtin/reset.c:80
 msgid "Failed to find tree of HEAD."
-msgstr "Kunde inte hitta träder för HEAD."
+msgstr "Kunde inte hitta trädet för HEAD."
 
 #: builtin/reset.c:86
 #, c-format
 msgid "Failed to find tree of %s."
-msgstr "Kunde inte hitta träder för %s."
+msgstr "Kunde inte hitta trädet för %s."
 
 #: builtin/reset.c:111
 #, c-format
@@ -13128,23 +13638,23 @@ msgstr "rev-list stöder inte visning av anteckningar"
 msgid "cannot combine --use-bitmap-index with object filtering"
 msgstr "kan inte kombinera --use-bitmap-index med objektfiltrering"
 
-#: builtin/rev-parse.c:402
+#: builtin/rev-parse.c:406
 msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
 msgstr "git rev-parse --parseopt [<options>] -- [<argument>...]"
 
-#: builtin/rev-parse.c:407
+#: builtin/rev-parse.c:411
 msgid "keep the `--` passed as an arg"
 msgstr "behåll \"--\" sänt som argument"
 
-#: builtin/rev-parse.c:409
+#: builtin/rev-parse.c:413
 msgid "stop parsing after the first non-option argument"
 msgstr "sluta tolka efter första argument som inte är flagga"
 
-#: builtin/rev-parse.c:412
+#: builtin/rev-parse.c:416
 msgid "output in stuck long form"
 msgstr "utdata fast i lång form"
 
-#: builtin/rev-parse.c:545
+#: builtin/rev-parse.c:549
 msgid ""
 "git rev-parse --parseopt [<options>] -- [<args>...]\n"
 "   or: git rev-parse --sq-quote [<arg>...]\n"
@@ -13284,42 +13794,42 @@ msgid_plural "the following files have local modifications:"
 msgstr[0] "följande fil har lokala ändringar:"
 msgstr[1] "följande filer har lokala ändringar:"
 
-#: builtin/rm.c:243
+#: builtin/rm.c:241
 msgid "do not list removed files"
 msgstr "lista inte borttagna filer"
 
-#: builtin/rm.c:244
+#: builtin/rm.c:242
 msgid "only remove from the index"
 msgstr "ta bara bort från indexet"
 
-#: builtin/rm.c:245
+#: builtin/rm.c:243
 msgid "override the up-to-date check"
 msgstr "överstyr àjour-testet"
 
-#: builtin/rm.c:246
+#: builtin/rm.c:244
 msgid "allow recursive removal"
 msgstr "tillåt rekursiv borttagning"
 
-#: builtin/rm.c:248
+#: builtin/rm.c:246
 msgid "exit with a zero status even if nothing matched"
 msgstr "avsluta med nollstatus även om inget träffades"
 
-#: builtin/rm.c:307
+#: builtin/rm.c:306
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "tar inte bort \"%s\" rekursivt utan -r"
 
-#: builtin/rm.c:346
+#: builtin/rm.c:345
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm: kan inte ta bort %s"
 
-#: builtin/rm.c:369
+#: builtin/rm.c:368
 #, c-format
 msgid "could not remove '%s'"
 msgstr "kunde inte ta bort \"%s\""
 
-#: builtin/send-pack.c:19
+#: builtin/send-pack.c:20
 msgid ""
 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-"
 "receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> "
@@ -13331,50 +13841,70 @@ msgstr ""
 "[<ref>...]\n"
 "  --all och explicit angiven <ref> är ömsesidigt uteslutande."
 
-#: builtin/send-pack.c:162
+#: builtin/send-pack.c:163
 msgid "remote name"
 msgstr "fjärrnamn"
 
-#: builtin/send-pack.c:176
+#: builtin/send-pack.c:177
 msgid "use stateless RPC protocol"
 msgstr "använd tillståndslöst RPC-protokoll"
 
-#: builtin/send-pack.c:177
+#: builtin/send-pack.c:178
 msgid "read refs from stdin"
 msgstr "läs referenser från standard in"
 
-#: builtin/send-pack.c:178
+#: builtin/send-pack.c:179
 msgid "print status from remote helper"
 msgstr "visa status från fjärrhjälpare"
 
+#: builtin/serve.c:7
+msgid "git serve [<options>]"
+msgstr "git serve [<flaggor>]"
+
+#: builtin/serve.c:17 builtin/upload-pack.c:23
+msgid "quit after a single request/response exchange"
+msgstr "avsluta omedelbart efter första anrop/svar-utväxling"
+
+#: builtin/serve.c:19
+msgid "exit immediately after advertising capabilities"
+msgstr "avsluta omedelbart efter kungörelse av kapabiliteter"
+
 #: builtin/shortlog.c:14
-msgid "git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"
+msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]"
 msgstr "git shortlog [<flaggor>] [<versionsintervall>] [[--] <sökväg>...]"
 
-#: builtin/shortlog.c:263
+#: builtin/shortlog.c:15
+msgid "git log --pretty=short | git shortlog [<options>]"
+msgstr "git log --pretty=short | git shortlog [<flaggor>]"
+
+#: builtin/shortlog.c:264
 msgid "Group by committer rather than author"
 msgstr "Gruppera efter incheckare istället för författare"
 
-#: builtin/shortlog.c:265
+#: builtin/shortlog.c:266
 msgid "sort output according to the number of commits per author"
 msgstr "sortera utdata enligt antal incheckningar per författare"
 
-#: builtin/shortlog.c:267
+#: builtin/shortlog.c:268
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr "Undertryck beskrivningar, visa bara antal incheckningar"
 
-#: builtin/shortlog.c:269
+#: builtin/shortlog.c:270
 msgid "Show the email address of each author"
 msgstr "Visa e-postadress för varje författare"
 
-#: builtin/shortlog.c:270
+#: builtin/shortlog.c:271
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:271
+#: builtin/shortlog.c:272
 msgid "Linewrap output"
 msgstr "Radbryt utdata"
 
+#: builtin/shortlog.c:298
+msgid "too many arguments given outside repository"
+msgstr "för många flaggor givna utanför arkivet"
+
 #: builtin/show-branch.c:12
 msgid ""
 "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
@@ -13571,39 +14101,39 @@ msgstr "hoppa över och ta bort alla rader som inleds med kommentarstecken"
 msgid "prepend comment character and space to each line"
 msgstr "lägg in kommentarstecken och blanksteg först på varje rad"
 
-#: builtin/submodule--helper.c:35 builtin/submodule--helper.c:1669
+#: builtin/submodule--helper.c:37 builtin/submodule--helper.c:1688
 #, c-format
 msgid "No such ref: %s"
 msgstr "Ingen sådan referens: %s"
 
-#: builtin/submodule--helper.c:42 builtin/submodule--helper.c:1678
+#: builtin/submodule--helper.c:44 builtin/submodule--helper.c:1697
 #, c-format
 msgid "Expecting a full ref name, got %s"
 msgstr "Förväntade fullt referensnamn, fick %s"
 
-#: builtin/submodule--helper.c:59
+#: builtin/submodule--helper.c:61
 msgid "submodule--helper print-default-remote takes no arguments"
 msgstr "submodule--helper print-default-remote tar inga argument"
 
-#: builtin/submodule--helper.c:96
+#: builtin/submodule--helper.c:98
 #, c-format
 msgid "cannot strip one component off url '%s'"
 msgstr "kan inte ta bort en komponent från url:en \"%s\""
 
-#: builtin/submodule--helper.c:404 builtin/submodule--helper.c:1198
+#: builtin/submodule--helper.c:406 builtin/submodule--helper.c:1211
 msgid "alternative anchor for relative paths"
 msgstr "alternativa ankare för relativa sökvägar"
 
-#: builtin/submodule--helper.c:409
+#: builtin/submodule--helper.c:411
 msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper list [--prefix=<sökväg>] [<sökväg>...]"
 
-#: builtin/submodule--helper.c:460 builtin/submodule--helper.c:483
+#: builtin/submodule--helper.c:462 builtin/submodule--helper.c:485
 #, c-format
 msgid "No url found for submodule path '%s' in .gitmodules"
 msgstr "Hittade ingen url för undermodulsökvägen \"%s\" i .gitmodules"
 
-#: builtin/submodule--helper.c:498
+#: builtin/submodule--helper.c:500
 #, c-format
 msgid ""
 "could not lookup configuration '%s'. Assuming this repository is its own "
@@ -13612,54 +14142,54 @@ msgstr ""
 "kunde inte slå upp konfigurationen \"%s\". Antar att arkivet är sn eget "
 "officiella uppström."
 
-#: builtin/submodule--helper.c:509
+#: builtin/submodule--helper.c:511
 #, c-format
 msgid "Failed to register url for submodule path '%s'"
 msgstr "Misslyckades registrera url för undermodulsökväg \"%s\""
 
-#: builtin/submodule--helper.c:513
+#: builtin/submodule--helper.c:515
 #, c-format
 msgid "Submodule '%s' (%s) registered for path '%s'\n"
 msgstr "Undermodulen \"%s\" (%s) registrerad för sökvägen \"%s\"\n"
 
-#: builtin/submodule--helper.c:523
+#: builtin/submodule--helper.c:525
 #, c-format
 msgid "warning: command update mode suggested for submodule '%s'\n"
 msgstr "varning: kommandouppdateringsläge föreslogs för undermodulen \"%s\"\n"
 
-#: builtin/submodule--helper.c:530
+#: builtin/submodule--helper.c:532
 #, c-format
 msgid "Failed to register update mode for submodule path '%s'"
 msgstr "Misslyckades registrera uppdateringsläge för undermodulsökväg \"%s\""
 
-#: builtin/submodule--helper.c:552
+#: builtin/submodule--helper.c:554
 msgid "Suppress output for initializing a submodule"
 msgstr "Dölj utdata från initiering av undermodul"
 
-#: builtin/submodule--helper.c:557
+#: builtin/submodule--helper.c:559
 msgid "git submodule--helper init [<path>]"
 msgstr "git submodule--helper init [<sökväg>]"
 
-#: builtin/submodule--helper.c:625 builtin/submodule--helper.c:747
+#: builtin/submodule--helper.c:631 builtin/submodule--helper.c:757
 #, c-format
 msgid "no submodule mapping found in .gitmodules for path '%s'"
 msgstr "hittade ingen undermodulmappning i .gitmodules för sökvägen \"%s\""
 
-#: builtin/submodule--helper.c:660
+#: builtin/submodule--helper.c:670
 #, c-format
 msgid "could not resolve HEAD ref inside the submodule '%s'"
 msgstr "kunde inte bestämma HEAD:s incheckning i undermodulen \"%s\""
 
-#: builtin/submodule--helper.c:687 builtin/submodule--helper.c:856
+#: builtin/submodule--helper.c:697 builtin/submodule--helper.c:866
 #, c-format
 msgid "failed to recurse into submodule '%s'"
 msgstr "misslyckades rekursera in i undermodulen \"%s\""
 
-#: builtin/submodule--helper.c:711 builtin/submodule--helper.c:1021
+#: builtin/submodule--helper.c:721 builtin/submodule--helper.c:1031
 msgid "Suppress submodule status output"
 msgstr "Hindra statusutskrift för undermodul"
 
-#: builtin/submodule--helper.c:712
+#: builtin/submodule--helper.c:722
 msgid ""
 "Use commit stored in the index instead of the one stored in the submodule "
 "HEAD"
@@ -13667,51 +14197,51 @@ msgstr ""
 "Visa incheckning från indexet istället för den som lagrats i undermodulens "
 "HEAD"
 
-#: builtin/submodule--helper.c:713
+#: builtin/submodule--helper.c:723
 msgid "recurse into nested submodules"
 msgstr "rekursera in i nästlade undermoduler"
 
-#: builtin/submodule--helper.c:718
+#: builtin/submodule--helper.c:728
 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
 msgstr "git submodule status [--quitet] [--cached] [--recursive] [<sökväg>...]"
 
-#: builtin/submodule--helper.c:742
+#: builtin/submodule--helper.c:752
 msgid "git submodule--helper name <path>"
 msgstr "git submodule--helper name <sökväg>"
 
-#: builtin/submodule--helper.c:806
+#: builtin/submodule--helper.c:816
 #, c-format
 msgid "Synchronizing submodule url for '%s'\n"
 msgstr "Synkroniserar undermodul-url för \"%s\"\n"
 
-#: builtin/submodule--helper.c:812
+#: builtin/submodule--helper.c:822
 #, c-format
 msgid "failed to register url for submodule path '%s'"
 msgstr "misslyckades registrera url för undermodulsökväg \"%s\""
 
-#: builtin/submodule--helper.c:826
+#: builtin/submodule--helper.c:836
 #, c-format
 msgid "failed to get the default remote for submodule '%s'"
 msgstr "misslyckades hämta standardfjärr för undermodulsökväg \"%s\""
 
-#: builtin/submodule--helper.c:837
+#: builtin/submodule--helper.c:847
 #, c-format
 msgid "failed to update remote for submodule '%s'"
 msgstr "misslyckades uppdatera fjärr för undermodulsökväg \"%s\""
 
-#: builtin/submodule--helper.c:885
+#: builtin/submodule--helper.c:895
 msgid "Suppress output of synchronizing submodule url"
 msgstr "Dölj utdata från synkroniering av undermodul-url"
 
-#: builtin/submodule--helper.c:887
+#: builtin/submodule--helper.c:897
 msgid "Recurse into nested submodules"
 msgstr "Rekursera in i nästlade undermoduler"
 
-#: builtin/submodule--helper.c:892
+#: builtin/submodule--helper.c:902
 msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
 msgstr "git submodule--helper sync [--quiet] [--recursive] [<sökväg>]"
 
-#: builtin/submodule--helper.c:946
+#: builtin/submodule--helper.c:956
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you "
@@ -13720,7 +14250,7 @@ msgstr ""
 "Undermodulsarbetskatalogen \"%s\" innehåller en .git-katalog (använd \"rm -rf"
 "\" om du verkligen vill ta bort den och all dess historik)"
 
-#: builtin/submodule--helper.c:958
+#: builtin/submodule--helper.c:968
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains local modifications; use '-f' to discard "
@@ -13729,81 +14259,81 @@ msgstr ""
 "Undermodulens arbetskatalog \"%s\" har lokala ändringar; \"-f\" kastar bort "
 "dem"
 
-#: builtin/submodule--helper.c:966
+#: builtin/submodule--helper.c:976
 #, c-format
 msgid "Cleared directory '%s'\n"
 msgstr "Rensade katalogen \"%s\"\n"
 
-#: builtin/submodule--helper.c:968
+#: builtin/submodule--helper.c:978
 #, c-format
 msgid "Could not remove submodule work tree '%s'\n"
 msgstr "Kunde inte ta bort undermodulens arbetskatalog \"%s\"\n"
 
-#: builtin/submodule--helper.c:977
+#: builtin/submodule--helper.c:987
 #, c-format
 msgid "could not create empty submodule directory %s"
 msgstr "kunde inte skapa tom undermodulskatalog %s"
 
-#: builtin/submodule--helper.c:993
+#: builtin/submodule--helper.c:1003
 #, c-format
 msgid "Submodule '%s' (%s) unregistered for path '%s'\n"
 msgstr "Undermodulen \"%s\" (%s) registrerad för sökvägen \"%s\"\n"
 
-#: builtin/submodule--helper.c:1022
+#: builtin/submodule--helper.c:1032
 msgid "Remove submodule working trees even if they contain local changes"
 msgstr ""
 "Ta bort undermodulers arbetskataloger även om de innehåller lokala ändringar"
 
-#: builtin/submodule--helper.c:1023
+#: builtin/submodule--helper.c:1033
 msgid "Unregister all submodules"
 msgstr "Avregistrera alla undermoduler"
 
-#: builtin/submodule--helper.c:1028
+#: builtin/submodule--helper.c:1038
 msgid ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
 msgstr ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<sökväg>...]]"
 
-#: builtin/submodule--helper.c:1042
+#: builtin/submodule--helper.c:1052
 msgid "Use '--all' if you really want to deinitialize all submodules"
 msgstr "Använd \"--all\" om du verkligen vill avinitiera alla undermoduler"
 
-#: builtin/submodule--helper.c:1133 builtin/submodule--helper.c:1136
+#: builtin/submodule--helper.c:1145 builtin/submodule--helper.c:1148
 #, c-format
 msgid "submodule '%s' cannot add alternate: %s"
 msgstr "undermodulen \"%s\" kan inte lägga till alternativ: %s"
 
-#: builtin/submodule--helper.c:1172
+#: builtin/submodule--helper.c:1184
 #, c-format
 msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized"
 msgstr "Värdet \"%s\" i submodule.alternateErrorStrategy förstås inte"
 
-#: builtin/submodule--helper.c:1179
+#: builtin/submodule--helper.c:1191
 #, c-format
 msgid "Value '%s' for submodule.alternateLocation is not recognized"
 msgstr "Värdet \"%s\" i submodule.alternateLocation förstås inte"
 
-#: builtin/submodule--helper.c:1201
+#: builtin/submodule--helper.c:1214
 msgid "where the new submodule will be cloned to"
 msgstr "var den nya undermodulen skall klonas till"
 
-#: builtin/submodule--helper.c:1204
+#: builtin/submodule--helper.c:1217
 msgid "name of the new submodule"
 msgstr "namn på den nya undermodulen"
 
-#: builtin/submodule--helper.c:1207
+#: builtin/submodule--helper.c:1220
 msgid "url where to clone the submodule from"
 msgstr "URL att klona undermodulen från"
 
-#: builtin/submodule--helper.c:1213
+#: builtin/submodule--helper.c:1228
 msgid "depth for shallow clones"
 msgstr "djup för grunda kloner"
 
-#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1587
+#: builtin/submodule--helper.c:1231 builtin/submodule--helper.c:1606
 msgid "force cloning progress"
 msgstr "tvinga kloningsförlopp"
 
-#: builtin/submodule--helper.c:1221
+#: builtin/submodule--helper.c:1236
 msgid ""
 "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
 "<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>"
@@ -13811,82 +14341,82 @@ msgstr ""
 "git submodule--helper clone [--prefix=<sökväg>] [--quiet] [--reference "
 "<arkvi>] [--name <namn>] [--depth <djup>] --url <url> --path <sökväg>"
 
-#: builtin/submodule--helper.c:1252
+#: builtin/submodule--helper.c:1267
 #, c-format
 msgid "clone of '%s' into submodule path '%s' failed"
 msgstr "misslyckades klona \"%s\" till undermodulsökvägen ”%s”"
 
-#: builtin/submodule--helper.c:1267
+#: builtin/submodule--helper.c:1281
 #, c-format
 msgid "could not get submodule directory for '%s'"
 msgstr "kunde inte få tag i undermodulkatalog för \"%s\""
 
-#: builtin/submodule--helper.c:1332
+#: builtin/submodule--helper.c:1347
 #, c-format
 msgid "Submodule path '%s' not initialized"
 msgstr "Undermodulsökvägen \"%s\" har inte initierats"
 
-#: builtin/submodule--helper.c:1336
+#: builtin/submodule--helper.c:1351
 msgid "Maybe you want to use 'update --init'?"
 msgstr "Kanske menade du att använda \"update --init\"?"
 
-#: builtin/submodule--helper.c:1365
+#: builtin/submodule--helper.c:1380
 #, c-format
 msgid "Skipping unmerged submodule %s"
 msgstr "Hoppar över ej sammanslagen undermodul %s"
 
-#: builtin/submodule--helper.c:1394
+#: builtin/submodule--helper.c:1409
 #, c-format
 msgid "Skipping submodule '%s'"
 msgstr "Hoppar över undermodulen \"%s\""
 
-#: builtin/submodule--helper.c:1527
+#: builtin/submodule--helper.c:1544
 #, c-format
 msgid "Failed to clone '%s'. Retry scheduled"
 msgstr "Misslyckades klona \"%s\". Nytt försök planlagt"
 
-#: builtin/submodule--helper.c:1538
+#: builtin/submodule--helper.c:1555
 #, c-format
 msgid "Failed to clone '%s' a second time, aborting"
 msgstr "Misslyckades klona \"%s\" för andra gången, avbryter"
 
-#: builtin/submodule--helper.c:1568 builtin/submodule--helper.c:1788
+#: builtin/submodule--helper.c:1585 builtin/submodule--helper.c:1808
 msgid "path into the working tree"
 msgstr "sökväg inuti arbetskatalogen"
 
-#: builtin/submodule--helper.c:1571
+#: builtin/submodule--helper.c:1588
 msgid "path into the working tree, across nested submodule boundaries"
 msgstr "sökväg inuti arbetskatalogen, genom nästlade undermodulgränser"
 
-#: builtin/submodule--helper.c:1575
+#: builtin/submodule--helper.c:1592
 msgid "rebase, merge, checkout or none"
 msgstr "rebase, merge, checkout eller none"
 
-#: builtin/submodule--helper.c:1579
+#: builtin/submodule--helper.c:1598
 msgid "Create a shallow clone truncated to the specified number of revisions"
 msgstr "Skapa en grund klon trunkerad till angivet antal revisioner"
 
-#: builtin/submodule--helper.c:1582
+#: builtin/submodule--helper.c:1601
 msgid "parallel jobs"
 msgstr "parallella jobb"
 
-#: builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1603
 msgid "whether the initial clone should follow the shallow recommendation"
 msgstr "om den första klonen skall följa rekommendation för grund kloning"
 
-#: builtin/submodule--helper.c:1585
+#: builtin/submodule--helper.c:1604
 msgid "don't print cloning progress"
 msgstr "skriv inte klonförlopp"
 
-#: builtin/submodule--helper.c:1592
+#: builtin/submodule--helper.c:1611
 msgid "git submodule--helper update_clone [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper update_clone [--prefix=<sökväg>] [<sökväg>...]"
 
-#: builtin/submodule--helper.c:1605
+#: builtin/submodule--helper.c:1624
 msgid "bad value for update parameter"
 msgstr "felaktigt värde för parametern update"
 
-#: builtin/submodule--helper.c:1673
+#: builtin/submodule--helper.c:1692
 #, c-format
 msgid ""
 "Submodule (%s) branch configured to inherit branch from superproject, but "
@@ -13895,20 +14425,20 @@ msgstr ""
 "Undermodulens (%s) gren inställd på att ärva gren från huvudprojektet, men "
 "huvudprojektet är inte på någon gren"
 
-#: builtin/submodule--helper.c:1789
+#: builtin/submodule--helper.c:1809
 msgid "recurse into submodules"
 msgstr "rekursera ner i undermoduler"
 
-#: builtin/submodule--helper.c:1795
+#: builtin/submodule--helper.c:1815
 msgid "git submodule--helper embed-git-dir [<path>...]"
 msgstr "git submodule--helper embed-git-dir [<sökväg>...]"
 
-#: builtin/submodule--helper.c:1857
+#: builtin/submodule--helper.c:1901
 #, c-format
 msgid "%s doesn't support --super-prefix"
 msgstr "%s stöder inte --super-prefix"
 
-#: builtin/submodule--helper.c:1863
+#: builtin/submodule--helper.c:1907
 #, c-format
 msgid "'%s' is not a valid submodule--helper subcommand"
 msgstr "\"%s\" är inte ett giltigt underkommando till submodule--helper"
@@ -13978,7 +14508,7 @@ msgstr "taggen \"%s\" hittades inte."
 msgid "Deleted tag '%s' (was %s)\n"
 msgstr "Tog bort tagg \"%s\" (var %s)\n"
 
-#: builtin/tag.c:131
+#: builtin/tag.c:132
 #, c-format
 msgid ""
 "\n"
@@ -13991,7 +14521,7 @@ msgstr ""
 "  %s\n"
 "Rader som inleds med \"%c\" ignoreras.\n"
 
-#: builtin/tag.c:135
+#: builtin/tag.c:136
 #, c-format
 msgid ""
 "\n"
@@ -14006,146 +14536,146 @@ msgstr ""
 "Rader som inleds med \"%c\" kommer behållas; du kan själv ta bort dem om\n"
 "du vill.\n"
 
-#: builtin/tag.c:189
+#: builtin/tag.c:190
 msgid "unable to sign the tag"
 msgstr "kunde inte signera taggen"
 
-#: builtin/tag.c:191
+#: builtin/tag.c:192
 msgid "unable to write tag file"
 msgstr "kunde inte skriva tagg-filen"
 
-#: builtin/tag.c:216
+#: builtin/tag.c:217
 msgid "bad object type."
 msgstr "felaktig objekttyp."
 
-#: builtin/tag.c:265
+#: builtin/tag.c:266
 msgid "no tag message?"
 msgstr "inget taggmeddelande?"
 
-#: builtin/tag.c:272
+#: builtin/tag.c:273
 #, c-format
 msgid "The tag message has been left in %s\n"
 msgstr "Taggmeddelandet har lämnats i %s\n"
 
-#: builtin/tag.c:381
+#: builtin/tag.c:382
 msgid "list tag names"
 msgstr "lista taggnamn"
 
-#: builtin/tag.c:383
+#: builtin/tag.c:384
 msgid "print <n> lines of each tag message"
 msgstr "visa <n> rader från varje taggmeddelande"
 
-#: builtin/tag.c:385
+#: builtin/tag.c:386
 msgid "delete tags"
 msgstr "ta bort taggar"
 
-#: builtin/tag.c:386
+#: builtin/tag.c:387
 msgid "verify tags"
 msgstr "verifiera taggar"
 
-#: builtin/tag.c:388
+#: builtin/tag.c:389
 msgid "Tag creation options"
 msgstr "Alternativ för att skapa taggar"
 
-#: builtin/tag.c:390
+#: builtin/tag.c:391
 msgid "annotated tag, needs a message"
 msgstr "annoterad tagg, behöver meddelande"
 
-#: builtin/tag.c:392
+#: builtin/tag.c:393
 msgid "tag message"
 msgstr "taggmeddelande"
 
-#: builtin/tag.c:394
+#: builtin/tag.c:395
 msgid "force edit of tag message"
 msgstr "tvinga redigering av incheckningsmeddelande"
 
-#: builtin/tag.c:395
+#: builtin/tag.c:396
 msgid "annotated and GPG-signed tag"
 msgstr "annoterad och GPG-signerad tagg"
 
-#: builtin/tag.c:399
+#: builtin/tag.c:400
 msgid "use another key to sign the tag"
 msgstr "använd annan nyckel för att signera taggen"
 
-#: builtin/tag.c:400
+#: builtin/tag.c:401
 msgid "replace the tag if exists"
 msgstr "ersätt taggen om den finns"
 
-#: builtin/tag.c:401 builtin/update-ref.c:368
+#: builtin/tag.c:402 builtin/update-ref.c:368
 msgid "create a reflog"
 msgstr "skapa en reflog"
 
-#: builtin/tag.c:403
+#: builtin/tag.c:404
 msgid "Tag listing options"
 msgstr "Alternativ för listning av taggar"
 
-#: builtin/tag.c:404
+#: builtin/tag.c:405
 msgid "show tag list in columns"
 msgstr "lista taggar i spalter"
 
-#: builtin/tag.c:405 builtin/tag.c:407
+#: builtin/tag.c:406 builtin/tag.c:408
 msgid "print only tags that contain the commit"
 msgstr "visa endast taggar som innehåller incheckningen"
 
-#: builtin/tag.c:406 builtin/tag.c:408
+#: builtin/tag.c:407 builtin/tag.c:409
 msgid "print only tags that don't contain the commit"
 msgstr "visa endast taggar som inte innehåller incheckningen"
 
-#: builtin/tag.c:409
+#: builtin/tag.c:410
 msgid "print only tags that are merged"
 msgstr "visa endast taggar som slagits samman"
 
-#: builtin/tag.c:410
+#: builtin/tag.c:411
 msgid "print only tags that are not merged"
 msgstr "visa endast taggar som ej slagits samman"
 
-#: builtin/tag.c:415
+#: builtin/tag.c:416
 msgid "print only tags of the object"
 msgstr "visa endast taggar för objektet"
 
-#: builtin/tag.c:459
+#: builtin/tag.c:460
 msgid "--column and -n are incompatible"
 msgstr "--column och -n är inkompatibla"
 
-#: builtin/tag.c:481
+#: builtin/tag.c:482
 msgid "-n option is only allowed in list mode"
 msgstr "Flaggan -n är endast tillåten i listläge"
 
-#: builtin/tag.c:483
+#: builtin/tag.c:484
 msgid "--contains option is only allowed in list mode"
 msgstr "Flaggan --contains är endast tillåten i listläge"
 
-#: builtin/tag.c:485
+#: builtin/tag.c:486
 msgid "--no-contains option is only allowed in list mode"
 msgstr "Flaggan --no-contains är endast tillåten i listläge"
 
-#: builtin/tag.c:487
+#: builtin/tag.c:488
 msgid "--points-at option is only allowed in list mode"
 msgstr "Flaggan --points-at är endast tillåten i listläge"
 
-#: builtin/tag.c:489
+#: builtin/tag.c:490
 msgid "--merged and --no-merged options are only allowed in list mode"
 msgstr "Flaggorna --merged och --no-merged är endast tillåtna i listläge"
 
-#: builtin/tag.c:500
+#: builtin/tag.c:501
 msgid "only one -F or -m option is allowed."
 msgstr "endast en av flaggorna -F eller -m tillåts."
 
-#: builtin/tag.c:519
+#: builtin/tag.c:520
 msgid "too many params"
 msgstr "för många parametrar"
 
-#: builtin/tag.c:525
+#: builtin/tag.c:526
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "\"%s\" är inte ett giltigt taggnamn."
 
-#: builtin/tag.c:530
+#: builtin/tag.c:531
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "taggen \"%s\" finns redan"
 
-#: builtin/tag.c:561
+#: builtin/tag.c:562
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "Uppdaterad tagg \"%s\" (var %s)\n"
@@ -14215,143 +14745,143 @@ msgstr "stat-informationen för en katalog ändras inte när en katalog tas bort
 msgid " OK"
 msgstr " OK"
 
-#: builtin/update-index.c:579
+#: builtin/update-index.c:589
 msgid "git update-index [<options>] [--] [<file>...]"
 msgstr "git update-index [<flaggor>] [--] [<fil>...]"
 
-#: builtin/update-index.c:936
+#: builtin/update-index.c:946
 msgid "continue refresh even when index needs update"
 msgstr "fortsätt uppdatera även när index inte är àjour"
 
-#: builtin/update-index.c:939
+#: builtin/update-index.c:949
 msgid "refresh: ignore submodules"
 msgstr "refresh: ignorera undermoduler"
 
-#: builtin/update-index.c:942
+#: builtin/update-index.c:952
 msgid "do not ignore new files"
 msgstr "ignorera inte nya filer"
 
-#: builtin/update-index.c:944
+#: builtin/update-index.c:954
 msgid "let files replace directories and vice-versa"
 msgstr "låt filer ersätta kataloger och omvänt"
 
-#: builtin/update-index.c:946
+#: builtin/update-index.c:956
 msgid "notice files missing from worktree"
 msgstr "lägg märke till filer som saknas i arbetskatalogen"
 
-#: builtin/update-index.c:948
+#: builtin/update-index.c:958
 msgid "refresh even if index contains unmerged entries"
 msgstr "uppdatera även om indexet innehåller ej sammanslagna poster"
 
-#: builtin/update-index.c:951
+#: builtin/update-index.c:961
 msgid "refresh stat information"
 msgstr "uppdatera statusinformation"
 
-#: builtin/update-index.c:955
+#: builtin/update-index.c:965
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "som --refresh, men ignorera assume-unchanged-inställning"
 
-#: builtin/update-index.c:959
+#: builtin/update-index.c:969
 msgid "<mode>,<object>,<path>"
 msgstr "<läge>,<objekt>,<sökväg>"
 
-#: builtin/update-index.c:960
+#: builtin/update-index.c:970
 msgid "add the specified entry to the index"
 msgstr "lägg till angiven post i indexet"
 
-#: builtin/update-index.c:969
+#: builtin/update-index.c:979
 msgid "mark files as \"not changing\""
 msgstr "markera filer som \"ändras inte\""
 
-#: builtin/update-index.c:972
+#: builtin/update-index.c:982
 msgid "clear assumed-unchanged bit"
 msgstr "rensa \"assume-unchanged\"-biten"
 
-#: builtin/update-index.c:975
+#: builtin/update-index.c:985
 msgid "mark files as \"index-only\""
 msgstr "markera filer som \"endast index\""
 
-#: builtin/update-index.c:978
+#: builtin/update-index.c:988
 msgid "clear skip-worktree bit"
 msgstr "töm \"skip-worktree\"-biten"
 
-#: builtin/update-index.c:981
+#: builtin/update-index.c:991
 msgid "add to index only; do not add content to object database"
 msgstr "lägg endast till indexet; lägg inte till innehållet i objektdatabasen"
 
-#: builtin/update-index.c:983
+#: builtin/update-index.c:993
 msgid "remove named paths even if present in worktree"
 msgstr "ta bort namngivna sökvägar även om de finns i arbetskatalogen"
 
-#: builtin/update-index.c:985
+#: builtin/update-index.c:995
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr "med --stdin: indatarader termineras med null-byte"
 
-#: builtin/update-index.c:987
+#: builtin/update-index.c:997
 msgid "read list of paths to be updated from standard input"
 msgstr "läs lista över sökvägar att uppdatera från standard in"
 
-#: builtin/update-index.c:991
+#: builtin/update-index.c:1001
 msgid "add entries from standard input to the index"
 msgstr "lägg poster från standard in till indexet"
 
-#: builtin/update-index.c:995
+#: builtin/update-index.c:1005
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr "återfyll etapp 2 och 3 från angivna sökvägar"
 
-#: builtin/update-index.c:999
+#: builtin/update-index.c:1009
 msgid "only update entries that differ from HEAD"
 msgstr "uppdatera endast poster som skiljer sig från HEAD"
 
-#: builtin/update-index.c:1003
+#: builtin/update-index.c:1013
 msgid "ignore files missing from worktree"
 msgstr "ignorera filer som saknas i arbetskatalogen"
 
-#: builtin/update-index.c:1006
+#: builtin/update-index.c:1016
 msgid "report actions to standard output"
 msgstr "rapportera åtgärder på standard ut"
 
-#: builtin/update-index.c:1008
+#: builtin/update-index.c:1018
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "(för porslin) glöm sparade olösta konflikter"
 
-#: builtin/update-index.c:1012
+#: builtin/update-index.c:1022
 msgid "write index in this format"
 msgstr "skriv index i detta format"
 
-#: builtin/update-index.c:1014
+#: builtin/update-index.c:1024
 msgid "enable or disable split index"
 msgstr "aktivera eller inaktivera delat index"
 
-#: builtin/update-index.c:1016
+#: builtin/update-index.c:1026
 msgid "enable/disable untracked cache"
 msgstr "aktivera/inaktivera ospårad cache"
 
-#: builtin/update-index.c:1018
+#: builtin/update-index.c:1028
 msgid "test if the filesystem supports untracked cache"
 msgstr "testa om filsystemet stöder ospårad cache"
 
-#: builtin/update-index.c:1020
+#: builtin/update-index.c:1030
 msgid "enable untracked cache without testing the filesystem"
 msgstr "aktivera ospårad cache utan att testa filsystemet"
 
-#: builtin/update-index.c:1022
+#: builtin/update-index.c:1032
 msgid "write out the index even if is not flagged as changed"
 msgstr "skriv ut indexet även om det inte angivits som ändrat"
 
-#: builtin/update-index.c:1024
+#: builtin/update-index.c:1034
 msgid "enable or disable file system monitor"
 msgstr "aktivera eller inaktivera filsystemsövervakning"
 
-#: builtin/update-index.c:1026
+#: builtin/update-index.c:1036
 msgid "mark files as fsmonitor valid"
 msgstr "markera filer som \"fsmonitor valid\""
 
-#: builtin/update-index.c:1029
+#: builtin/update-index.c:1039
 msgid "clear fsmonitor valid bit"
 msgstr "töm \"fsmonitor valid\"-bit"
 
-#: builtin/update-index.c:1127
+#: builtin/update-index.c:1138
 msgid ""
 "core.splitIndex is set to false; remove or change it, if you really want to "
 "enable split index"
@@ -14359,7 +14889,7 @@ msgstr ""
 "core.splitIndex är satt till false; ta bort eller ändra det om du verkligen "
 "vill aktivera delat index"
 
-#: builtin/update-index.c:1136
+#: builtin/update-index.c:1147
 msgid ""
 "core.splitIndex is set to true; remove or change it, if you really want to "
 "disable split index"
@@ -14367,7 +14897,7 @@ msgstr ""
 "core.splitIndex är satt till true; ta bort eller ändra det om du verkligen "
 "vill inaktivera delat index"
 
-#: builtin/update-index.c:1147
+#: builtin/update-index.c:1158
 msgid ""
 "core.untrackedCache is set to true; remove or change it, if you really want "
 "to disable the untracked cache"
@@ -14375,11 +14905,11 @@ msgstr ""
 "core.untrackedCache är satt till true; ta bort eller ändra det om du "
 "verkligen vill inaktivera den ospårade cachen"
 
-#: builtin/update-index.c:1151
+#: builtin/update-index.c:1162
 msgid "Untracked cache disabled"
 msgstr "Ospårad cache är inaktiverad"
 
-#: builtin/update-index.c:1159
+#: builtin/update-index.c:1170
 msgid ""
 "core.untrackedCache is set to false; remove or change it, if you really want "
 "to enable the untracked cache"
@@ -14387,26 +14917,26 @@ msgstr ""
 "core.untrackedCache är satt till false; ta bort eller ändra det om du "
 "verkligen vill aktivera den ospårade cachen"
 
-#: builtin/update-index.c:1163
+#: builtin/update-index.c:1174
 #, c-format
 msgid "Untracked cache enabled for '%s'"
 msgstr "Ospårad cache är aktiverad för \"%s\""
 
-#: builtin/update-index.c:1171
+#: builtin/update-index.c:1182
 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
 msgstr "core.fsmonitor inte satt; sätt om du verkligen vill aktivera fsmonitor"
 
-#: builtin/update-index.c:1175
+#: builtin/update-index.c:1186
 msgid "fsmonitor enabled"
 msgstr "fsmonitor aktiverat"
 
-#: builtin/update-index.c:1178
+#: builtin/update-index.c:1189
 msgid ""
 "core.fsmonitor is set; remove it if you really want to disable fsmonitor"
 msgstr ""
 "core.fsmonitor är satt; ta bort om du verkligen vill inaktivera fsmonitor"
 
-#: builtin/update-index.c:1182
+#: builtin/update-index.c:1193
 msgid "fsmonitor disabled"
 msgstr "fsmonitor inaktiverat"
 
@@ -14446,13 +14976,29 @@ msgstr "git update-server-info [--force]"
 msgid "update the info files from scratch"
 msgstr "uppdatera informationsfilerna från grunden"
 
-#: builtin/verify-commit.c:18
-msgid "git verify-commit [-v | --verbose] <commit>..."
-msgstr "git verify-commit [-v | --verbose] <incheckning>..."
+#: builtin/upload-pack.c:11
+msgid "git upload-pack [<options>] <dir>"
+msgstr "git upload-pack [<flaggor>] <katalog>"
 
-#: builtin/verify-commit.c:73
-msgid "print commit contents"
-msgstr "visa innehåll för incheckning"
+#: builtin/upload-pack.c:25
+msgid "exit immediately after initial ref advertisement"
+msgstr "avsluta omedelbart efter inledande kungörelse av referenser"
+
+#: builtin/upload-pack.c:27
+msgid "do not try <directory>/.git/ if <directory> is no Git directory"
+msgstr "testa inte <katalog>/.git/ om <katalog> inte är en Git-katalog"
+
+#: builtin/upload-pack.c:29
+msgid "interrupt transfer after <n> seconds of inactivity"
+msgstr "avbryt överföringen efter <n> sekunders inaktivitet"
+
+#: builtin/verify-commit.c:18
+msgid "git verify-commit [-v | --verbose] <commit>..."
+msgstr "git verify-commit [-v | --verbose] <incheckning>..."
+
+#: builtin/verify-commit.c:73
+msgid "print commit contents"
+msgstr "visa innehåll för incheckning"
 
 #: builtin/verify-commit.c:74 builtin/verify-tag.c:38
 msgid "print raw gpg status output"
@@ -14506,22 +15052,22 @@ msgstr "git worktree remove [<flaggor>] <arbetskatalog>"
 msgid "git worktree unlock <path>"
 msgstr "git worktree unlock <sökväg>"
 
-#: builtin/worktree.c:60
+#: builtin/worktree.c:58
 #, c-format
 msgid "Removing worktrees/%s: not a valid directory"
 msgstr "Tar bort worktrees/%s: inte en giltig katalog"
 
-#: builtin/worktree.c:66
+#: builtin/worktree.c:64
 #, c-format
 msgid "Removing worktrees/%s: gitdir file does not exist"
 msgstr "Tar bort worktrees/%s: gitdir-filen existerar inte"
 
-#: builtin/worktree.c:71 builtin/worktree.c:80
+#: builtin/worktree.c:69 builtin/worktree.c:78
 #, c-format
 msgid "Removing worktrees/%s: unable to read gitdir file (%s)"
 msgstr "Tar bort worktrees/%s: kan inte läsa gitdir-filen (%s)"
 
-#: builtin/worktree.c:90
+#: builtin/worktree.c:88
 #, c-format
 msgid ""
 "Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read "
@@ -14530,177 +15076,192 @@ msgstr ""
 "Tar bort worktrees/%s: kort läsning (förväntade %<PRIuMAX> byte, läste "
 "%<PRIuMAX>)"
 
-#: builtin/worktree.c:98
+#: builtin/worktree.c:96
 #, c-format
 msgid "Removing worktrees/%s: invalid gitdir file"
 msgstr "Tar bort worktrees/%s: felaktig gitdir-fil"
 
-#: builtin/worktree.c:114
+#: builtin/worktree.c:105
 #, c-format
 msgid "Removing worktrees/%s: gitdir file points to non-existent location"
 msgstr "Tar bort worktrees/%s: gitdir-filen pekar på en ickeexisterande plats"
 
-#: builtin/worktree.c:161
+#: builtin/worktree.c:152
 msgid "report pruned working trees"
 msgstr "rapportera borttagna arbetskataloger"
 
-#: builtin/worktree.c:163
+#: builtin/worktree.c:154
 msgid "expire working trees older than <time>"
 msgstr "låt tid gå ut för arbetskataloger äldre än <tid>"
 
-#: builtin/worktree.c:238
+#: builtin/worktree.c:229
 #, c-format
 msgid "'%s' already exists"
 msgstr "\"%s\" finns redan"
 
-#: builtin/worktree.c:269
+#: builtin/worktree.c:260
 #, c-format
 msgid "could not create directory of '%s'"
 msgstr "kunde inte skapa katalogen \"%s\""
 
-#: builtin/worktree.c:308
+#: builtin/worktree.c:373 builtin/worktree.c:379
+#, c-format
+msgid "Preparing worktree (new branch '%s')"
+msgstr "Förbereder arbetskatalog (ny gren \"%s\")"
+
+#: builtin/worktree.c:375
+#, c-format
+msgid "Preparing worktree (resetting branch '%s'; was at %s)"
+msgstr "Förbereder arbetskatalog (återställer gren \"%s\"; var på %s)"
+
+#: builtin/worktree.c:384
 #, c-format
-msgid "Preparing %s (identifier %s)"
-msgstr "Förbereder %s (identifieraren %s)"
+msgid "Preparing worktree (checking out '%s')"
+msgstr "Förbereder arbetskatalog (checkar ut \"%s\")"
 
-#: builtin/worktree.c:385
+#: builtin/worktree.c:390
+#, c-format
+msgid "Preparing worktree (detached HEAD %s)"
+msgstr "Förbereder arbetskatalog (frånkopplat HEAD %s)"
+
+#: builtin/worktree.c:431
 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"
 
-#: builtin/worktree.c:388
+#: builtin/worktree.c:434
 msgid "create a new branch"
 msgstr "skapa en ny gren"
 
-#: builtin/worktree.c:390
+#: builtin/worktree.c:436
 msgid "create or reset a branch"
 msgstr "skapa eller återställ en gren"
 
-#: builtin/worktree.c:392
+#: builtin/worktree.c:438
 msgid "populate the new working tree"
 msgstr "befolka den nya arbetskatalogen"
 
-#: builtin/worktree.c:393
+#: builtin/worktree.c:439
 msgid "keep the new working tree locked"
 msgstr "låt arbetskatalogen förbli låst"
 
-#: builtin/worktree.c:395
+#: builtin/worktree.c:441
 msgid "set up tracking mode (see git-branch(1))"
 msgstr "ställ in spårningsläge (se git-branch(1))"
 
-#: builtin/worktree.c:398
+#: builtin/worktree.c:444
 msgid "try to match the new branch name with a remote-tracking branch"
 msgstr "försök matcha namn på ny gren mot en fjärrspårande gren"
 
-#: builtin/worktree.c:406
+#: builtin/worktree.c:452
 msgid "-b, -B, and --detach are mutually exclusive"
 msgstr "-b, -B och --detach är ömsesidigt uteslutande"
 
-#: builtin/worktree.c:471
+#: builtin/worktree.c:511
 msgid "--[no-]track can only be used if a new branch is created"
 msgstr "--[no-]track kan endast användas när ny gran skapas"
 
-#: builtin/worktree.c:571
+#: builtin/worktree.c:611
 msgid "reason for locking"
 msgstr "orsak till lås"
 
-#: builtin/worktree.c:583 builtin/worktree.c:616 builtin/worktree.c:670
-#: builtin/worktree.c:809
+#: builtin/worktree.c:623 builtin/worktree.c:656 builtin/worktree.c:710
+#: builtin/worktree.c:850
 #, c-format
 msgid "'%s' is not a working tree"
 msgstr "\"%s\" är inte en arbetskatalog"
 
-#: builtin/worktree.c:585 builtin/worktree.c:618
+#: builtin/worktree.c:625 builtin/worktree.c:658
 msgid "The main working tree cannot be locked or unlocked"
 msgstr "Huvudarbetskatalogen kan inte låsas eller låsas upp"
 
-#: builtin/worktree.c:590
+#: builtin/worktree.c:630
 #, c-format
 msgid "'%s' is already locked, reason: %s"
 msgstr "\"%s\" är redan låst, orsak: %s"
 
-#: builtin/worktree.c:592
+#: builtin/worktree.c:632
 #, c-format
 msgid "'%s' is already locked"
 msgstr "\"%s\" är redan låst"
 
-#: builtin/worktree.c:620
+#: builtin/worktree.c:660
 #, c-format
 msgid "'%s' is not locked"
 msgstr "\"%s\" är inte låst"
 
-#: builtin/worktree.c:645
+#: builtin/worktree.c:685
 msgid "working trees containing submodules cannot be moved or removed"
 msgstr "arbetskataloger med undermoduler kan inte flyttas eller tas bort"
 
-#: builtin/worktree.c:672 builtin/worktree.c:811
+#: builtin/worktree.c:712 builtin/worktree.c:852
 #, c-format
 msgid "'%s' is a main working tree"
 msgstr "\"%s\" är inte en huvudarbetskatalog"
 
-#: builtin/worktree.c:677
+#: builtin/worktree.c:717
 #, c-format
 msgid "could not figure out destination name from '%s'"
 msgstr "kunde inte lista ut målnamn från \"%s\""
 
-#: builtin/worktree.c:683
+#: builtin/worktree.c:723
 #, c-format
 msgid "target '%s' already exists"
 msgstr "målet \"%s\" finns redan"
 
-#: builtin/worktree.c:690
+#: builtin/worktree.c:730
 #, c-format
 msgid "cannot move a locked working tree, lock reason: %s"
 msgstr "kan inte flytta en låst arbetskatalog, orsak till lås: %s"
 
-#: builtin/worktree.c:692
+#: builtin/worktree.c:732
 msgid "cannot move a locked working tree"
 msgstr "kan inte flytta en låst arbetskatalog"
 
-#: builtin/worktree.c:695
+#: builtin/worktree.c:735
 #, c-format
 msgid "validation failed, cannot move working tree: %s"
 msgstr "kontroll misslyckades, kan inte flytta arbetskatalog: %s"
 
-#: builtin/worktree.c:700
+#: builtin/worktree.c:740
 #, c-format
 msgid "failed to move '%s' to '%s'"
 msgstr "misslyckades flytta \"%s\" till \"%s\""
 
-#: builtin/worktree.c:748
+#: builtin/worktree.c:788
 #, c-format
 msgid "failed to run 'git status' on '%s'"
 msgstr "misslyckades köra \"git status\" på \"%s\""
 
-#: builtin/worktree.c:752
+#: builtin/worktree.c:792
 #, c-format
 msgid "'%s' is dirty, use --force to delete it"
 msgstr "\"%s\" är smutsigt, använd --force för att ta bort det"
 
-#: builtin/worktree.c:757
+#: builtin/worktree.c:797
 #, c-format
 msgid "failed to run 'git status' on '%s', code %d"
 msgstr "misslyckades köra \"git status\" på \"%s\", kod %d"
 
-#: builtin/worktree.c:768 builtin/worktree.c:782
+#: builtin/worktree.c:808 builtin/worktree.c:822
 #, c-format
 msgid "failed to delete '%s'"
 msgstr "misslyckades ta bort \"%s\""
 
-#: builtin/worktree.c:794
+#: builtin/worktree.c:834
 msgid "force removing even if the worktree is dirty"
 msgstr "tvinga ta bort även om arbetskatalogen är smutsig"
 
-#: builtin/worktree.c:815
+#: builtin/worktree.c:856
 #, c-format
 msgid "cannot remove a locked working tree, lock reason: %s"
 msgstr "kan inte ta bort en låst arbetskatalog, orsak till låset: %s"
 
-#: builtin/worktree.c:817
+#: builtin/worktree.c:858
 msgid "cannot remove a locked working tree"
 msgstr "kan inte ta bort en låst arbetskatalog"
 
-#: builtin/worktree.c:820
+#: builtin/worktree.c:861
 #, c-format
 msgid "validation failed, cannot remove working tree: %s"
 msgstr "kontroll misslyckades, kan inte ta bort arbetskatalog: %s"
@@ -14721,26 +15282,6 @@ msgstr "visa trädobjekt för underkatalogen <prefix>"
 msgid "only useful for debugging"
 msgstr "endast användbart vid felsökning"
 
-#: upload-pack.c:27
-msgid "git upload-pack [<options>] <dir>"
-msgstr "git upload-pack [<flaggor>] <katalog>"
-
-#: upload-pack.c:1070
-msgid "quit after a single request/response exchange"
-msgstr "avsluta omedelbart efter första anrop/svar-utväxling"
-
-#: upload-pack.c:1072
-msgid "exit immediately after initial ref advertisement"
-msgstr "avsluta omedelbart efter inledande kungörelse av referenser"
-
-#: upload-pack.c:1074
-msgid "do not try <directory>/.git/ if <directory> is no Git directory"
-msgstr "testa inte <katalog>/.git/ om <katalog> inte är en Git-katalog"
-
-#: upload-pack.c:1076
-msgid "interrupt transfer after <n> seconds of inactivity"
-msgstr "avbryt överföringen efter <n> sekunders inaktivitet"
-
 #: credential-cache--daemon.c:222
 #, c-format
 msgid ""
@@ -14758,22 +15299,24 @@ msgstr ""
 msgid "print debugging messages to stderr"
 msgstr "skriv felsökningsmeddelanden på standard fel"
 
-#: git.c:8
+#: git.c:27
 msgid ""
 "git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
 "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
 "           <command> [<args>]"
 msgstr ""
 "git [--version] [--help] [-C <sökväg>] [-c <namn>=<värde>]\n"
 "           [--exec-path[=<sökväg>]] [--html-path] [--man-path] [--info-"
 "path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<sökväg>] [--work-tree=<sökväg>] [--namespace=<namn>]\n"
 "           <kommando> [<flaggor>]"
 
-#: git.c:15
+#: git.c:34
 msgid ""
 "'git help -a' and 'git help -g' list available subcommands and some\n"
 "concept guides. See 'git help <command>' or 'git help <concept>'\n"
@@ -14783,66 +15326,66 @@ msgstr ""
 "några konceptvägledningar. Se \"git help <kommando>\" eller \"git help\n"
 "<koncept>\" för att läsa mer om specifika underkommandon och koncept."
 
-#: git.c:95
+#: git.c:173
 #, c-format
 msgid "no directory given for --git-dir\n"
 msgstr "ingen katalog angavs för --git-dir\n"
 
-#: git.c:109
+#: git.c:187
 #, c-format
 msgid "no namespace given for --namespace\n"
 msgstr "ingen namnrymd angavs för --namespace\n"
 
-#: git.c:123
+#: git.c:201
 #, c-format
 msgid "no directory given for --work-tree\n"
 msgstr "ingen katalog angavs för --work-tree\n"
 
-#: git.c:137
+#: git.c:215
 #, c-format
 msgid "no prefix given for --super-prefix\n"
 msgstr "inget prefix angavs för --super-prefix\n"
 
-#: git.c:159
+#: git.c:237
 #, c-format
 msgid "-c expects a configuration string\n"
 msgstr "-c förväntar en konfigurationssträng\n"
 
-#: git.c:197
+#: git.c:275
 #, c-format
 msgid "no directory given for -C\n"
 msgstr "ingen katalog angavs för -C\n"
 
-#: git.c:212
+#: git.c:300
 #, c-format
 msgid "unknown option: %s\n"
 msgstr "okänd flagga: %s\n"
 
-#: git.c:687
+#: git.c:765
 #, c-format
 msgid "expansion of alias '%s' failed; '%s' is not a git command\n"
 msgstr ""
 "expandering av alias \"%s\" misslyckades; \"%s\" är inte ett git-kommando\n"
 
-#: git.c:699
+#: git.c:777
 #, c-format
 msgid "failed to run command '%s': %s\n"
 msgstr "misslyckades köra kommandot \"%s\": %s\n"
 
-#: http.c:342
+#: http.c:348
 #, c-format
 msgid "negative value for http.postbuffer; defaulting to %d"
 msgstr "http.postbuffer har negativt värde; använder förvalet %d"
 
-#: http.c:363
+#: http.c:369
 msgid "Delegation control is not supported with cURL < 7.22.0"
 msgstr "Delegerad styrning stöds inte av cURL < 7.22.0"
 
-#: http.c:372
+#: http.c:378
 msgid "Public key pinning not supported with cURL < 7.44.0"
 msgstr "Fastnålning av öppen nyckel stöds inte av cURL < 7.44.0"
 
-#: http.c:1857
+#: http.c:1854
 #, c-format
 msgid ""
 "unable to update url base from redirection:\n"
@@ -14853,7 +15396,7 @@ msgstr ""
 "        bad om: %s\n"
 "  omdirigering: %s"
 
-#: remote-curl.c:345
+#: remote-curl.c:401
 #, c-format
 msgid "redirecting to %s"
 msgstr "omdirigerar till %s"
@@ -14866,129 +15409,656 @@ msgstr "argument"
 msgid "object filtering"
 msgstr "objektfiltrering"
 
-#: common-cmds.h:9
-msgid "start a working area (see also: git help tutorial)"
-msgstr "starta arbetskatalog (se också: git help tutorial)"
+#: parse-options.h:157
+msgid "expiry-date"
+msgstr "giltig-till"
 
-#: common-cmds.h:10
-msgid "work on the current change (see also: git help everyday)"
-msgstr "jobba med aktuell förändring (se också: git help everyday)"
+#: parse-options.h:172
+msgid "no-op (backward compatibility)"
+msgstr "ingen funktion (bakåtkompatibilitet)"
 
-#: common-cmds.h:11
-msgid "examine the history and state (see also: git help revisions)"
-msgstr "utforska historiken och tillståndet (se också: git help revisions)"
+#: parse-options.h:251
+msgid "be more verbose"
+msgstr "var mer pratsam"
 
-#: common-cmds.h:12
-msgid "grow, mark and tweak your common history"
-msgstr "utöka, markera och justera din gemensamma historik"
+#: parse-options.h:253
+msgid "be more quiet"
+msgstr "var mer tyst"
 
-#: common-cmds.h:13
-msgid "collaborate (see also: git help workflows)"
-msgstr "samarbeta (se också: git help workflows)"
+#: parse-options.h:259
+msgid "use <n> digits to display SHA-1s"
+msgstr "använd <n> siffror för att visa SHA-1:or"
 
-#: common-cmds.h:17
+#: command-list.h:50
 msgid "Add file contents to the index"
 msgstr "Lägg filinnehåll till indexet"
 
-#: common-cmds.h:18
+#: command-list.h:51
+msgid "Apply a series of patches from a mailbox"
+msgstr "Tillämpa en serie patchar från en brevlåda"
+
+#: command-list.h:52
+msgid "Annotate file lines with commit information"
+msgstr "Kommentera filrader med incheckningsinformation"
+
+#: command-list.h:53
+msgid "Apply a patch to files and/or to the index"
+msgstr "Tillämpa en patch på filer och/eller indexet"
+
+#: command-list.h:54
+msgid "Import an Arch repository into Git"
+msgstr "Importera ett Arch-arkiv till Git"
+
+#: command-list.h:55
+msgid "Create an archive of files from a named tree"
+msgstr "Skapa ett arkiv över filer från ett namngivet träd"
+
+#: command-list.h:56
 msgid "Use binary search to find the commit that introduced a bug"
 msgstr "Använd binärsökning för att hitta ändringen som introducerade ett fel"
 
-#: common-cmds.h:19
+#: command-list.h:57
+msgid "Show what revision and author last modified each line of a file"
+msgstr "Visa version och författare som sist modifierade varje rad i en fil"
+
+#: command-list.h:58
 msgid "List, create, or delete branches"
 msgstr "Visa, skapa eller ta bort grenar"
 
-#: common-cmds.h:20
+#: command-list.h:59
+msgid "Move objects and refs by archive"
+msgstr "Flytta objekt och referenser efter arkiv"
+
+#: command-list.h:60
+msgid "Provide content or type and size information for repository objects"
+msgstr ""
+"Visa innehåller eller typ- och storleksinformation för objekt i arkivet."
+
+#: command-list.h:61
+msgid "Display gitattributes information"
+msgstr "Visa information från gitattributes"
+
+#: command-list.h:62
+msgid "Debug gitignore / exclude files"
+msgstr "Felsök gitignore / exkluderings-filer"
+
+#: command-list.h:63
+msgid "Show canonical names and email addresses of contacts"
+msgstr "Visa kanoniska namn och e-postadresser för kontakter"
+
+#: command-list.h:64
 msgid "Switch branches or restore working tree files"
 msgstr "Byt till en ny gren eller återställ filer i arbetskatalogen"
 
-#: common-cmds.h:21
+#: command-list.h:65
+msgid "Copy files from the index to the working tree"
+msgstr "Kopiera filer från indexet till arbetskatalogen"
+
+#: command-list.h:66
+msgid "Ensures that a reference name is well formed"
+msgstr "Se till att referensen är välformad"
+
+#: command-list.h:67
+msgid "Find commits yet to be applied to upstream"
+msgstr "Hitta incheckningar som ännu inte applicerats uppströms"
+
+#: command-list.h:68
+msgid "Apply the changes introduced by some existing commits"
+msgstr "Applicera ändringarna introducerade av befintliga incheckningar"
+
+#: command-list.h:69
+msgid "Graphical alternative to git-commit"
+msgstr "Grafiskt alternativ till git-commit"
+
+#: command-list.h:70
+msgid "Remove untracked files from the working tree"
+msgstr "Ta bort ospårade filer från arbetskatalogen"
+
+#: command-list.h:71
 msgid "Clone a repository into a new directory"
 msgstr "Klona ett arkiv till en ny katalog"
 
-#: common-cmds.h:22
+#: command-list.h:72
+msgid "Display data in columns"
+msgstr "Visa data i kolumner"
+
+#: command-list.h:73
 msgid "Record changes to the repository"
 msgstr "Protokollför ändringar i arkivet"
 
-#: common-cmds.h:23
+#: command-list.h:74
+msgid "Write and verify Git commit graph files"
+msgstr "Skriv och verifiera Git-incheckningsgraffiler"
+
+#: command-list.h:75
+msgid "Create a new commit object"
+msgstr "Skapa ett nytt incheckningsobjekt"
+
+#: command-list.h:76
+msgid "Get and set repository or global options"
+msgstr "Läs och skriv alternativ för arkiv eller globalt"
+
+#: command-list.h:77
+msgid "Count unpacked number of objects and their disk consumption"
+msgstr "Räkna antal opackade objekt och mängd diskutrymme"
+
+#: command-list.h:78
+msgid "Retrieve and store user credentials"
+msgstr "Hämta och spara användarreferenser"
+
+#: command-list.h:79
+msgid "Helper to temporarily store passwords in memory"
+msgstr "Hjälpprogram för att tillfälligt lagra lösenord i minnet"
+
+#: command-list.h:80
+msgid "Helper to store credentials on disk"
+msgstr "Hjälpprogram för att lagra användarreferenser på disk"
+
+#: command-list.h:81
+msgid "Export a single commit to a CVS checkout"
+msgstr "Exportera en enkel incheckning i en CVS-utcheckning"
+
+#: command-list.h:82
+msgid "Salvage your data out of another SCM people love to hate"
+msgstr "Rädda dina data ut ur andra SCM folk älskar att hata"
+
+#: command-list.h:83
+msgid "A CVS server emulator for Git"
+msgstr "En CVS-serveremulator för Git"
+
+#: command-list.h:84
+msgid "A really simple server for Git repositories"
+msgstr "En riktigt enkel server för Git-arkiv"
+
+#: command-list.h:85
+msgid "Give an object a human readable name based on an available ref"
+msgstr "Ge ett objekt användarläsbara namn baserade på en tillgänglig referens"
+
+#: command-list.h:86
 msgid "Show changes between commits, commit and working tree, etc"
 msgstr "Visa ändringar mellan incheckningar, med arbetskatalogen, osv"
 
-#: common-cmds.h:24
+#: command-list.h:87
+msgid "Compares files in the working tree and the index"
+msgstr "Jämför filer i arbetskatalogen och indexet"
+
+#: command-list.h:88
+msgid "Compare a tree to the working tree or index"
+msgstr "Jämför en träd med arbetskatalogen eller indexet"
+
+#: command-list.h:89
+msgid "Compares the content and mode of blobs found via two tree objects"
+msgstr "Visar innehåll och läge för blob:ar som hittats via två trädobjekt"
+
+#: command-list.h:90
+msgid "Show changes using common diff tools"
+msgstr "Visa ändringar med vanliga diff-verktyg"
+
+#: command-list.h:91
+msgid "Git data exporter"
+msgstr "Exporterare för Git-data"
+
+#: command-list.h:92
+msgid "Backend for fast Git data importers"
+msgstr "Bakända för snabba Git-dataimporterare"
+
+#: command-list.h:93
 msgid "Download objects and refs from another repository"
 msgstr "Hämta objekt och referenser från annat arkiv"
 
-#: common-cmds.h:25
+#: command-list.h:94
+msgid "Receive missing objects from another repository"
+msgstr "Ta emot saknade objekt från annat arkiv"
+
+#: command-list.h:95
+msgid "Rewrite branches"
+msgstr "Skriv om grenar"
+
+#: command-list.h:96
+msgid "Produce a merge commit message"
+msgstr "Skapa incheckningsmeddelande för en sammanslagning"
+
+#: command-list.h:97
+msgid "Output information on each ref"
+msgstr "Visa information för varje referens"
+
+#: command-list.h:98
+msgid "Prepare patches for e-mail submission"
+msgstr "Förbered patchar för insändning via e-post"
+
+#: command-list.h:99
+msgid "Verifies the connectivity and validity of the objects in the database"
+msgstr "Bekräftar konnektivitet och validitet för objektet i databasen"
+
+#: command-list.h:100
+msgid "Cleanup unnecessary files and optimize the local repository"
+msgstr "Städa onödiga filer och optimera det lokala arkivet"
+
+#: command-list.h:101
+msgid "Extract commit ID from an archive created using git-archive"
+msgstr "Hämta inchecknings-ID från ett arkiv skapat med git-archive"
+
+#: command-list.h:102
 msgid "Print lines matching a pattern"
 msgstr "Visa rader som motsvarar mönster"
 
-#: common-cmds.h:26
+#: command-list.h:103
+msgid "A portable graphical interface to Git"
+msgstr "Ett portabelt grafiskt gränssnitt för Git"
+
+#: command-list.h:104
+msgid "Compute object ID and optionally creates a blob from a file"
+msgstr "Beräkna objekt-ID och möjligen skapa en blob från en fil"
+
+#: command-list.h:105
+msgid "Display help information about Git"
+msgstr "Visa hjälpinformation om Git"
+
+#: command-list.h:106
+msgid "Server side implementation of Git over HTTP"
+msgstr "Serversideimplementation av Git över HTTP"
+
+#: command-list.h:107
+msgid "Download from a remote Git repository via HTTP"
+msgstr "Hämta objekt och referenser från annat Git-arkiv över HTTP"
+
+#: command-list.h:108
+msgid "Push objects over HTTP/DAV to another repository"
+msgstr "Sänd objekt över HTTP/DAV till ett annat arkiv"
+
+#: command-list.h:109
+msgid "Send a collection of patches from stdin to an IMAP folder"
+msgstr "Sänd en samling patchar från stdin till en IMAP-mapp"
+
+#: command-list.h:110
+msgid "Build pack index file for an existing packed archive"
+msgstr "SKapa pack-indexfiler för ett befintligt packat arkiv"
+
+#: command-list.h:111
 msgid "Create an empty Git repository or reinitialize an existing one"
 msgstr "Skapa tomt Git-arkiv eller ominitiera ett befintligt"
 
-#: common-cmds.h:27
+#: command-list.h:112
+msgid "Instantly browse your working repository in gitweb"
+msgstr "Omedelbart bläddra i din arbetskatalog med gitweb"
+
+#: command-list.h:113
+msgid "add or parse structured information in commit messages"
+msgstr ""
+"lägg till eller tolka strukturerad information i incheckningsmeddelanden"
+
+#: command-list.h:114
+msgid "The Git repository browser"
+msgstr "Bläddraren för Git-arkiv"
+
+#: command-list.h:115
 msgid "Show commit logs"
 msgstr "Visa incheckningsloggar"
 
-#: common-cmds.h:28
+#: command-list.h:116
+msgid "Show information about files in the index and the working tree"
+msgstr "Visa information om filer i indexet och arbetskatalogen"
+
+#: command-list.h:117
+msgid "List references in a remote repository"
+msgstr "Lista referenser i ett fjärrarkiv"
+
+#: command-list.h:118
+msgid "List the contents of a tree object"
+msgstr "Visa innehållet i ett trädobjekt"
+
+#: command-list.h:119
+msgid "Extracts patch and authorship from a single e-mail message"
+msgstr "Hämta patch och ägarskap från ett enkelt e-postmeddelande"
+
+#: command-list.h:120
+msgid "Simple UNIX mbox splitter program"
+msgstr "Enkelt program för att dela en UNIX mbox"
+
+#: command-list.h:121
 msgid "Join two or more development histories together"
 msgstr "Slå ihop två eller flera utvecklingshistorier"
 
-#: common-cmds.h:29
+#: command-list.h:122
+msgid "Find as good common ancestors as possible for a merge"
+msgstr "Hitta en så bra anfader som möjligt för sammanslagning"
+
+#: command-list.h:123
+msgid "Run a three-way file merge"
+msgstr "Kör en trevägs-filsammanslagning"
+
+#: command-list.h:124
+msgid "Run a merge for files needing merging"
+msgstr "Kör en sammanslagning för filer som behöver det"
+
+#: command-list.h:125
+msgid "The standard helper program to use with git-merge-index"
+msgstr "Förvalt hjälpprogram att använda tillsammans med git-merge-index"
+
+#: command-list.h:126
+msgid "Run merge conflict resolution tools to resolve merge conflicts"
+msgstr "Kör verktyg för lösning av sammanslagningskonflikter"
+
+#: command-list.h:127
+msgid "Show three-way merge without touching index"
+msgstr "Visa trevägssammanslagning utan att röra indexet"
+
+#: command-list.h:128
+msgid "Creates a tag object"
+msgstr "Skapar ett taggobjekt"
+
+#: command-list.h:129
+msgid "Build a tree-object from ls-tree formatted text"
+msgstr "Bygg ett trädobjekt från ls-tree-formaterad text"
+
+#: command-list.h:130
 msgid "Move or rename a file, a directory, or a symlink"
 msgstr "Flytta eller byt namn på en fil, katalog eller symbolisk länk"
 
-#: common-cmds.h:30
+#: command-list.h:131
+msgid "Find symbolic names for given revs"
+msgstr "Hitta symboliska namn för givna referenser"
+
+#: command-list.h:132
+msgid "Add or inspect object notes"
+msgstr "Lägg till eller inspektera objektanteckningar"
+
+#: command-list.h:133
+msgid "Import from and submit to Perforce repositories"
+msgstr "Importera från eller sänd till Perforce-arkiv"
+
+#: command-list.h:134
+msgid "Create a packed archive of objects"
+msgstr "Skapa ett packat arkiv med objekt"
+
+#: command-list.h:135
+msgid "Find redundant pack files"
+msgstr "Hitta redundanta pack-filer"
+
+#: command-list.h:136
+msgid "Pack heads and tags for efficient repository access"
+msgstr "Packa huvuden och taggar för effektiv arkivåtkomst"
+
+#: command-list.h:137
+msgid "Routines to help parsing remote repository access parameters"
+msgstr ""
+"Rutiner för att göra det lättare att tolka åtkomstparametrar för fjärrarkiv"
+
+#: command-list.h:138
+msgid "Compute unique ID for a patch"
+msgstr "Beräkna unik ID för en patch"
+
+#: command-list.h:139
+msgid "Prune all unreachable objects from the object database"
+msgstr "Ta bort alla onåbara objekt från objektdatabasen"
+
+#: command-list.h:140
+msgid "Remove extra objects that are already in pack files"
+msgstr "Ta bort extraobjekt som redan finns i pack-filerna"
+
+#: command-list.h:141
 msgid "Fetch from and integrate with another repository or a local branch"
 msgstr "Hämta från och integrera med annat arkiv eller en lokal gren"
 
-#: common-cmds.h:31
+#: command-list.h:142
 msgid "Update remote refs along with associated objects"
 msgstr "Uppdatera fjärr-referenser och tillhörande objekt"
 
-#: common-cmds.h:32
+#: command-list.h:143
+msgid "Applies a quilt patchset onto the current branch"
+msgstr "Tillämpar en quilt-patchuppsättning på aktiv gren"
+
+#: command-list.h:144
+msgid "Reads tree information into the index"
+msgstr "Läser trädinformation in i indexet"
+
+#: command-list.h:145
 msgid "Reapply commits on top of another base tip"
 msgstr "Applicera incheckningar på nytt ovanpå en annan bastopp"
 
-#: common-cmds.h:33
+#: command-list.h:146
+msgid "Receive what is pushed into the repository"
+msgstr "Ta emot det som sänds till arkivet"
+
+#: command-list.h:147
+msgid "Manage reflog information"
+msgstr "Hantera referenslogg-information"
+
+#: command-list.h:148
+msgid "Manage set of tracked repositories"
+msgstr "Hantera uppsättningen spårade arkiv"
+
+#: command-list.h:149
+msgid "Pack unpacked objects in a repository"
+msgstr "Packa opackade objekt i ett arkiv"
+
+#: command-list.h:150
+msgid "Create, list, delete refs to replace objects"
+msgstr "Skapa, visa, ta bort referenser för att ersätta objekt"
+
+#: command-list.h:151
+msgid "Generates a summary of pending changes"
+msgstr "Skapar en sammanfattning av väntande ändringar"
+
+#: command-list.h:152
+msgid "Reuse recorded resolution of conflicted merges"
+msgstr "Återanvänd sparad lösning av sammanslagningskonflikter"
+
+#: command-list.h:153
 msgid "Reset current HEAD to the specified state"
 msgstr "Återställ aktuell HEAD till angivet tillstånd"
 
-#: common-cmds.h:34
+#: command-list.h:154
+msgid "Revert some existing commits"
+msgstr "Återställ några befintliga incheckningar"
+
+#: command-list.h:155
+msgid "Lists commit objects in reverse chronological order"
+msgstr "Visa incheckningsobjekt i omvänd kronologisk ordning"
+
+#: command-list.h:156
+msgid "Pick out and massage parameters"
+msgstr "Plocka ut och massera parametrar"
+
+#: command-list.h:157
 msgid "Remove files from the working tree and from the index"
 msgstr "Ta bort filer från arbetskatalogen och från indexet"
 
-#: common-cmds.h:35
+#: command-list.h:158
+msgid "Send a collection of patches as emails"
+msgstr "Sänd en uppsättning patchar som e-post"
+
+#: command-list.h:159
+msgid "Push objects over Git protocol to another repository"
+msgstr "Sänd objekt över Git-protokollet till annat arkiv"
+
+#: command-list.h:160
+msgid "Restricted login shell for Git-only SSH access"
+msgstr "Begränsat inloggningsskal för SSH-åtkomst till bara Git"
+
+#: command-list.h:161
+msgid "Summarize 'git log' output"
+msgstr "Summera \"git log\"-utdata"
+
+#: command-list.h:162
 msgid "Show various types of objects"
 msgstr "Visa olika sorters objekt"
 
-#: common-cmds.h:36
+#: command-list.h:163
+msgid "Show branches and their commits"
+msgstr "Visa grenar och deras incheckningar"
+
+#: command-list.h:164
+msgid "Show packed archive index"
+msgstr "Skapa packat arkivindex"
+
+#: command-list.h:165
+msgid "List references in a local repository"
+msgstr "Visa referenser i ett lokalt arkiv"
+
+#: command-list.h:166
+msgid "Git's i18n setup code for shell scripts"
+msgstr "Git:s i18n-startkod för skalskript"
+
+#: command-list.h:167
+msgid "Common Git shell script setup code"
+msgstr "Gemensam skriptstartkod för Git"
+
+#: command-list.h:168
+msgid "Stash the changes in a dirty working directory away"
+msgstr "Spara undan ändringar i en lortig arbetskatalog"
+
+#: command-list.h:169
+msgid "Add file contents to the staging area"
+msgstr "Lägg filinnehållet till indexet"
+
+#: command-list.h:170
 msgid "Show the working tree status"
 msgstr "Visa status för arbetskatalogen"
 
-#: common-cmds.h:37
+#: command-list.h:171
+msgid "Remove unnecessary whitespace"
+msgstr "Ta bort onödiga blanksteg"
+
+#: command-list.h:172
+msgid "Initialize, update or inspect submodules"
+msgstr "Initiera, uppdatera eller inspektera undermoduler"
+
+#: command-list.h:173
+msgid "Bidirectional operation between a Subversion repository and Git"
+msgstr "Dubbelriktad verkan mellan ett Subversion-arkiv och Git"
+
+#: command-list.h:174
+msgid "Read, modify and delete symbolic refs"
+msgstr "Läs, modifiera eller ta bort symbolisk referens"
+
+#: command-list.h:175
 msgid "Create, list, delete or verify a tag object signed with GPG"
 msgstr "Skapa, visa, ta bort eller verifiera GPG-signerat taggobjekt"
 
-#: parse-options.h:157
-msgid "expiry-date"
-msgstr "giltig-till"
+#: command-list.h:176
+msgid "Creates a temporary file with a blob's contents"
+msgstr "Skapar temporära filer med innehållet från en blob"
 
-#: parse-options.h:172
-msgid "no-op (backward compatibility)"
-msgstr "ingen funktion (bakåtkompatibilitet)"
+#: command-list.h:177
+msgid "Unpack objects from a packed archive"
+msgstr "Packa upp objekt från ett pakat arkiv"
 
-#: parse-options.h:250
-msgid "be more verbose"
-msgstr "var mer pratsam"
+#: command-list.h:178
+msgid "Register file contents in the working tree to the index"
+msgstr "Registrera filinnehållet från arbetskatalogen i indexet"
 
-#: parse-options.h:252
-msgid "be more quiet"
-msgstr "var mer tyst"
+#: command-list.h:179
+msgid "Update the object name stored in a ref safely"
+msgstr "Uppdatera objektnamnet i en referens på ett säkert sätt"
 
-#: parse-options.h:258
-msgid "use <n> digits to display SHA-1s"
-msgstr "använd <n> siffror för att visa SHA-1:or"
+#: command-list.h:180
+msgid "Update auxiliary info file to help dumb servers"
+msgstr "Uppdatera tilläggsinfofil för att hjälpa dumma servrar"
+
+#: command-list.h:181
+msgid "Send archive back to git-archive"
+msgstr "Sänd arkivet tillbaka till git-archive"
+
+#: command-list.h:182
+msgid "Send objects packed back to git-fetch-pack"
+msgstr "Sänd packade objekt tillbaka till git-fetch-pack"
+
+#: command-list.h:183
+msgid "Show a Git logical variable"
+msgstr "Visa en logisk Git-variabel"
+
+#: command-list.h:184
+msgid "Check the GPG signature of commits"
+msgstr "Kontrollera GPG-signaturer för incheckningar"
+
+#: command-list.h:185
+msgid "Validate packed Git archive files"
+msgstr "Bekräfta packade Git-arkivfiler"
+
+#: command-list.h:186
+msgid "Check the GPG signature of tags"
+msgstr "Kontrollera GPG-signaturer i taggar"
+
+#: command-list.h:187
+msgid "Git web interface (web frontend to Git repositories)"
+msgstr "Git-webbgränssnitt (webbframända för Git-arkiv)"
+
+#: command-list.h:188
+msgid "Show logs with difference each commit introduces"
+msgstr "Visa loggar med differenser varje incheckning introducerar"
+
+#: command-list.h:189
+msgid "Manage multiple working trees"
+msgstr "Hantera ytterligare arbetskataloger"
+
+#: command-list.h:190
+msgid "Create a tree object from the current index"
+msgstr "Skapa ett trädobjekt från aktuellt index"
+
+#: command-list.h:191
+msgid "Defining attributes per path"
+msgstr "Definierar attribut per sökväg"
+
+#: command-list.h:192
+msgid "Git command-line interface and conventions"
+msgstr "Gits kommandoradsgränssnitt och -konventioner"
+
+#: command-list.h:193
+msgid "A Git core tutorial for developers"
+msgstr "Grundläggande Git-handledning för utvecklare"
+
+#: command-list.h:194
+msgid "Git for CVS users"
+msgstr "Git för CVS-användare"
+
+#: command-list.h:195
+msgid "Tweaking diff output"
+msgstr "Justrea diff-utdata"
+
+#: command-list.h:196
+msgid "A useful minimum set of commands for Everyday Git"
+msgstr "Ett användbart minsta uppsättning kommandon för vardags-Git"
+
+#: command-list.h:197
+msgid "A Git Glossary"
+msgstr "En Git-ordlista"
+
+#: command-list.h:198
+msgid "Hooks used by Git"
+msgstr "Krokar som används av Git"
+
+#: command-list.h:199
+msgid "Specifies intentionally untracked files to ignore"
+msgstr "Ange avsiktligen ospårade filer att ignorera"
+
+#: command-list.h:200
+msgid "Defining submodule properties"
+msgstr "Ange egenskaper för undermoduler"
+
+#: command-list.h:201
+msgid "Git namespaces"
+msgstr "Git-namnrymder"
+
+#: command-list.h:202
+msgid "Git Repository Layout"
+msgstr "Gits arkivlayout"
+
+#: command-list.h:203
+msgid "Specifying revisions and ranges for Git"
+msgstr "Ange versioner och intervall i Git"
+
+#: command-list.h:204
+msgid "A tutorial introduction to Git: part two"
+msgstr "Introduktion till Git: del två"
+
+#: command-list.h:205
+msgid "A tutorial introduction to Git"
+msgstr "Introduktion till Git"
+
+#: command-list.h:206
+msgid "An overview of recommended workflows with Git"
+msgstr "Översikt över rekommenderade arbetsflöden med Git"
 
 #: rerere.h:40
 msgid "update the index with reused conflict resolution if possible"
@@ -15223,7 +16293,7 @@ msgstr "Försök enkel sammanslagning med $pretty_name"
 msgid "Simple merge did not work, trying automatic merge."
 msgstr "Enkel sammanslagning misslyckades, försöker automatisk sammanslagning."
 
-#: git-rebase.sh:60
+#: git-rebase.sh:61
 msgid ""
 "Resolve all conflicts manually, mark them as resolved with\n"
 "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
@@ -15237,41 +16307,41 @@ msgstr ""
 "För att avbryta och återgå till där du var före ombaseringen, kör \"git "
 "rebase --abort\"."
 
-#: git-rebase.sh:163 git-rebase.sh:409
+#: git-rebase.sh:173 git-rebase.sh:442
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "Kunde inte flytta tillbaka till $head_name"
 
-#: git-rebase.sh:174
+#: git-rebase.sh:184
 msgid "Applied autostash."
 msgstr "Tillämpade autostash."
 
-#: git-rebase.sh:177
+#: git-rebase.sh:187
 #, sh-format
 msgid "Cannot store $stash_sha1"
 msgstr "Kan inte spara $stash_sha1"
 
-#: git-rebase.sh:218
+#: git-rebase.sh:229
 msgid "The pre-rebase hook refused to rebase."
 msgstr "Kroken pre-rebase vägrade ombaseringen."
 
-#: git-rebase.sh:223
+#: git-rebase.sh:234
 msgid "It looks like 'git am' is in progress. Cannot rebase."
 msgstr "Det verkar som en \"git am\" körs. Kan inte ombasera."
 
-#: git-rebase.sh:370
+#: git-rebase.sh:403
 msgid "No rebase in progress?"
 msgstr "Ingen ombasering pågår?"
 
-#: git-rebase.sh:381
+#: git-rebase.sh:414
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr "Åtgärden --edit-todo kan endast användas under interaktiv ombasering."
 
-#: git-rebase.sh:388
+#: git-rebase.sh:421
 msgid "Cannot read HEAD"
 msgstr "Kan inte läsa HEAD"
 
-#: git-rebase.sh:391
+#: git-rebase.sh:424
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -15279,7 +16349,7 @@ msgstr ""
 "Du måste redigera alla sammanslagningskonflikter och\n"
 "därefter markera dem som lösta med git add"
 
-#: git-rebase.sh:435
+#: git-rebase.sh:468
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -15300,75 +16370,79 @@ msgstr ""
 "och kör programmet igen. Jag avslutar ifall du fortfarande har\n"
 "något av värde där."
 
-#: git-rebase.sh:491
+#: git-rebase.sh:509
+msgid "error: cannot combine '--signoff' with '--preserve-merges'"
+msgstr "fel: kan inte kombinera \"--signoff\" med \"--preserve-merges\""
+
+#: git-rebase.sh:537
 #, sh-format
 msgid "invalid upstream '$upstream_name'"
 msgstr "ogiltig uppström \"$upstream_name\""
 
-#: git-rebase.sh:515
+#: git-rebase.sh:561
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name: mer än en sammanslagningsbas finns"
 
-#: git-rebase.sh:518 git-rebase.sh:522
+#: git-rebase.sh:564 git-rebase.sh:568
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name: ingen sammanslagningsbas finns"
 
-#: git-rebase.sh:527
+#: git-rebase.sh:573
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "Peka på en giltig incheckning: $onto_name"
 
-#: git-rebase.sh:553
+#: git-rebase.sh:599
 #, sh-format
 msgid "fatal: no such branch/commit '$branch_name'"
 msgstr "ödesdigert: ingen sådan gren/incheckning: $branch_name"
 
-#: git-rebase.sh:586
+#: git-rebase.sh:632
 msgid "Cannot autostash"
 msgstr "Kan inte utföra \"autostash\""
 
-#: git-rebase.sh:591
+#: git-rebase.sh:637
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "Skapade autostash: $stash_abbrev"
 
-#: git-rebase.sh:595
+#: git-rebase.sh:641
 msgid "Please commit or stash them."
 msgstr "Checka in eller använd \"stash\" på dem."
 
-#: git-rebase.sh:618
+#: git-rebase.sh:664
 #, sh-format
 msgid "HEAD is up to date."
 msgstr "HEAD är à jour."
 
-#: git-rebase.sh:620
+#: git-rebase.sh:666
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "Aktuell gren $branch_name är à jour."
 
-#: git-rebase.sh:628
+#: git-rebase.sh:674
 #, sh-format
 msgid "HEAD is up to date, rebase forced."
 msgstr "HEAD är à jour, ombasering framtvingad."
 
-#: git-rebase.sh:630
+#: git-rebase.sh:676
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr "Aktuell gren $branch_name är à jour, ombasering framtvingad."
 
-#: git-rebase.sh:642
+#: git-rebase.sh:688
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "Ändringar från $mb till $onto:"
 
-#: git-rebase.sh:651
+#: git-rebase.sh:697
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr ""
 "Först, spolar tillbaka huvudet för att spela av ditt arbete ovanpå det..."
 
-#: git-rebase.sh:661
+#: git-rebase.sh:707
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "Snabbspolade $branch_name till $onto_name."
@@ -15436,109 +16510,109 @@ msgstr "Kan inte spara aktuell status"
 msgid "Saved working directory and index state $stash_msg"
 msgstr "Sparade arbetskatalogen och indexstatus $stash_msg"
 
-#: git-stash.sh:340
+#: git-stash.sh:342
 msgid "Cannot remove worktree changes"
 msgstr "Kan inte ta bort ändringar i arbetskatalogen"
 
-#: git-stash.sh:488
+#: git-stash.sh:490
 #, sh-format
 msgid "unknown option: $opt"
 msgstr "okänd flagga: $opt"
 
-#: git-stash.sh:501
+#: git-stash.sh:503
 msgid "No stash entries found."
 msgstr "Inga \"stash”-poster hittades."
 
-#: git-stash.sh:508
+#: git-stash.sh:510
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "För många revisioner angivna: $REV"
 
-#: git-stash.sh:523
+#: git-stash.sh:525
 #, sh-format
 msgid "$reference is not a valid reference"
 msgstr "$reference är inte en giltig referens"
 
-#: git-stash.sh:551
+#: git-stash.sh:553
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "\"$args\" är inte en \"stash\"-liknande incheckning"
 
-#: git-stash.sh:562
+#: git-stash.sh:564
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "\"$args\" är inte en \"stash\"-referens"
 
-#: git-stash.sh:570
+#: git-stash.sh:572
 msgid "unable to refresh index"
 msgstr "kan inte uppdatera indexet"
 
-#: git-stash.sh:574
+#: git-stash.sh:576
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "Kan inte tillämpa en \"stash\" mitt i en sammanslagning"
 
-#: git-stash.sh:582
+#: git-stash.sh:584
 msgid "Conflicts in index. Try without --index."
 msgstr "Konflikter i indexet. Testa utan --index."
 
-#: git-stash.sh:584
+#: git-stash.sh:586
 msgid "Could not save index tree"
 msgstr "Kunde inte spara indexträd"
 
-#: git-stash.sh:593
+#: git-stash.sh:595
 msgid "Could not restore untracked files from stash entry"
 msgstr "Kunde inte återställa ospårade filer från stash-post"
 
-#: git-stash.sh:618
+#: git-stash.sh:620
 msgid "Cannot unstage modified files"
 msgstr "Kan inte ta bort ändrade filer ur kön"
 
-#: git-stash.sh:633
+#: git-stash.sh:635
 msgid "Index was not unstashed."
 msgstr "Indexet har inte tagits ur kön."
 
-#: git-stash.sh:647
+#: git-stash.sh:649
 msgid "The stash entry is kept in case you need it again."
 msgstr "Stash-posten behålls ifall du behöver den igen."
 
-#: git-stash.sh:656
+#: git-stash.sh:658
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "Kastade ${REV} ($s)"
 
-#: git-stash.sh:657
+#: git-stash.sh:659
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "${REV}: Kunde inte kasta \"stash\"-post"
 
-#: git-stash.sh:665
+#: git-stash.sh:667
 msgid "No branch name specified"
 msgstr "Inget grennamn angavs"
 
-#: git-stash.sh:744
+#: git-stash.sh:746
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(För att återställa dem, skriv \"git stash apply\")"
 
-#: git-submodule.sh:181
+#: git-submodule.sh:188
 msgid "Relative path can only be used from the toplevel of the working tree"
 msgstr "Relativ sökväg kan endast användas från arbetskatalogens toppnivå"
 
-#: git-submodule.sh:191
+#: git-submodule.sh:198
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr "arkiv-URL: \"$repo\" måste vara absolut eller börja med ./|../"
 
-#: git-submodule.sh:210
+#: git-submodule.sh:217
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "\"$sm_path\" finns redan i indexet"
 
-#: git-submodule.sh:213
+#: git-submodule.sh:220
 #, sh-format
 msgid "'$sm_path' already exists in the index and is not a submodule"
 msgstr "\"$sm_path\" finns redan i indexet och är inte en undermodul"
 
-#: git-submodule.sh:219
+#: git-submodule.sh:226
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -15549,22 +16623,22 @@ msgstr ""
 "$sm_path\n"
 "Använd -f om du verkligen vill lägga till den."
 
-#: git-submodule.sh:237
+#: git-submodule.sh:249
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "Lägger till befintligt arkiv i \"$sm_path\" i indexet"
 
-#: git-submodule.sh:239
+#: git-submodule.sh:251
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "\"$sm_path\" finns redan och är inte ett giltigt git-arkiv"
 
-#: git-submodule.sh:247
+#: git-submodule.sh:259
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
 msgstr "En git-katalog för \"$sm_name\" hittades lokalt med fjärr(ar):"
 
-#: git-submodule.sh:249
+#: git-submodule.sh:261
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from\n"
@@ -15582,48 +16656,48 @@ msgstr ""
 "arkiv eller om du är osäker på vad det här betyder, välj ett annat namn med\n"
 "flaggan \"--name\"."
 
-#: git-submodule.sh:255
+#: git-submodule.sh:267
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
 msgstr "Aktiverar lokal git-katalog för undermodulen \"$sm_name\" på nytt."
 
-#: git-submodule.sh:267
+#: git-submodule.sh:279
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "Kan inte checka ut undermodulen \"$sm_path\""
 
-#: git-submodule.sh:272
+#: git-submodule.sh:284
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "Misslyckades lägga till undermodulen \"$sm_path\""
 
-#: git-submodule.sh:281
+#: git-submodule.sh:293
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "Misslyckades registrera undermodulen \"$sm_path\""
 
-#: git-submodule.sh:342
+#: git-submodule.sh:354
 #, sh-format
 msgid "Entering '$displaypath'"
 msgstr "Går in i \"$displaypath\""
 
-#: git-submodule.sh:362
+#: git-submodule.sh:374
 #, sh-format
 msgid "Stopping at '$displaypath'; script returned non-zero status."
 msgstr ""
 "Stoppar på \"$displaypath\"; skriptet returnerade en status skild från noll."
 
-#: git-submodule.sh:584
+#: git-submodule.sh:600
 #, sh-format
 msgid "Unable to find current revision in submodule path '$displaypath'"
 msgstr "Kan inte hitta aktuell revision i undermodulsökvägen \"$displaypath\""
 
-#: git-submodule.sh:594
+#: git-submodule.sh:610
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "Kan inte hämta i undermodulsökväg \"$sm_path\""
 
-#: git-submodule.sh:599
+#: git-submodule.sh:615
 #, sh-format
 msgid ""
 "Unable to find current ${remote_name}/${branch} revision in submodule path "
@@ -15632,12 +16706,12 @@ msgstr ""
 "Kan inte hitta aktuell revision för ${remote_name}/${branch} i "
 "undermodulsökvägen \"$sm_path\""
 
-#: git-submodule.sh:617
+#: git-submodule.sh:633
 #, sh-format
 msgid "Unable to fetch in submodule path '$displaypath'"
 msgstr "Kan inte hämta i undermodulsökväg \"$displaypath\""
 
-#: git-submodule.sh:623
+#: git-submodule.sh:639
 #, sh-format
 msgid ""
 "Fetched in submodule path '$displaypath', but it did not contain $sha1. "
@@ -15646,72 +16720,72 @@ msgstr ""
 "Hämtade i undermodulssökvägen \"$displaypath\", men den innehöll inte $sha1. "
 "Direkt hämtning av incheckningen misslyckades."
 
-#: git-submodule.sh:630
+#: git-submodule.sh:646
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
 msgstr "Kan inte checka ut \"$sha1\" i undermodulsökvägen \"$displaypath\""
 
-#: git-submodule.sh:631
+#: git-submodule.sh:647
 #, sh-format
 msgid "Submodule path '$displaypath': checked out '$sha1'"
 msgstr "Undermodulsökvägen \"$displaypath\": checkade ut \"$sha1\""
 
-#: git-submodule.sh:635
+#: git-submodule.sh:651
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
 msgstr "Kan inte ombasera \"$sha1\" i undermodulsökvägen \"$displaypath\""
 
-#: git-submodule.sh:636
+#: git-submodule.sh:652
 #, sh-format
 msgid "Submodule path '$displaypath': rebased into '$sha1'"
 msgstr "Undermodulsökvägen \"$displaypath\": ombaserade in i \"$sha1\""
 
-#: git-submodule.sh:641
+#: git-submodule.sh:657
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$displaypath'"
 msgstr "Kan inte slå ihop \"$sha1\" i undermodulsökvägen \"$displaypath\""
 
-#: git-submodule.sh:642
+#: git-submodule.sh:658
 #, sh-format
 msgid "Submodule path '$displaypath': merged in '$sha1'"
 msgstr "Undermodulsökvägen \"$displaypath\": sammanslagen i \"$sha1\""
 
-#: git-submodule.sh:647
+#: git-submodule.sh:663
 #, sh-format
 msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'"
 msgstr ""
 "Misslyckades köra \"$command $sha1\" i undermodulsökvägen \"$displaypath\""
 
-#: git-submodule.sh:648
+#: git-submodule.sh:664
 #, sh-format
 msgid "Submodule path '$displaypath': '$command $sha1'"
 msgstr "Undermodulsökvägen \"$displaypath\": \"$command $sha1\""
 
-#: git-submodule.sh:679
+#: git-submodule.sh:695
 #, sh-format
 msgid "Failed to recurse into submodule path '$displaypath'"
 msgstr "Misslyckades rekursera in i undermodulsökvägen \"$displaypath\""
 
-#: git-submodule.sh:775
+#: git-submodule.sh:791
 msgid "The --cached option cannot be used with the --files option"
 msgstr "Flaggan --cached kan inte användas med flaggan --files"
 
-#: git-submodule.sh:827
+#: git-submodule.sh:843
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "oväntat läge $mod_dst"
 
-#: git-submodule.sh:847
+#: git-submodule.sh:863
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr "  Varning: $display_name innehåller inte incheckningen $sha1_src"
 
-#: git-submodule.sh:850
+#: git-submodule.sh:866
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr "  Varning: $display_name innehåller inte incheckningen $sha1_dst"
 
-#: git-submodule.sh:853
+#: git-submodule.sh:869
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
@@ -15723,38 +16797,53 @@ msgstr ""
 msgid "See git-${cmd}(1) for details."
 msgstr "Se git-${cmd}(1) för detaljer."
 
-#: git-rebase--interactive.sh:140
+#: git-rebase--interactive.sh:142
 #, sh-format
 msgid "Rebasing ($new_count/$total)"
 msgstr "Ombaserar ($new_count/$total)"
 
-#: git-rebase--interactive.sh:156
+#: git-rebase--interactive.sh:158
 msgid ""
 "\n"
 "Commands:\n"
-"p, pick = use commit\n"
-"r, reword = use commit, but edit the commit message\n"
-"e, edit = use commit, but stop for amending\n"
-"s, squash = use commit, but meld into previous commit\n"
-"f, fixup = like \"squash\", but discard this commit's log message\n"
-"x, exec = run command (the rest of the line) using shell\n"
-"d, drop = remove commit\n"
+"p, pick <commit> = use commit\n"
+"r, reword <commit> = use commit, but edit the commit message\n"
+"e, edit <commit> = use commit, but stop for amending\n"
+"s, squash <commit> = use commit, but meld into previous commit\n"
+"f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
+"x, exec <command> = run command (the rest of the line) using shell\n"
+"d, drop <commit> = remove commit\n"
+"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"
 "\n"
 "These lines can be re-ordered; they are executed from top to bottom.\n"
 msgstr ""
 "\n"
 "Kommandon:\n"
-"p, pick = använd incheckning\n"
-"r, reword = använd incheckning, men redigera incheckningsmeddelandet\n"
-"e, edit = använd incheckning, men stanna för tillägg\n"
-"s, squash = använd incheckning, men infoga i föregående incheckning\n"
-"f, fixup = som \"squash\", men förkasta incheckningsmeddelandet\n"
-"x, exec = kör kommando (resten av raden) i skalet\n"
-"d, drop = ta bort incheckning\n"
+"p, pick <incheckning> = använd incheckning\n"
+"r, reword <incheckning> = använd incheckning, men redigera "
+"incheckningsmeddelandet\n"
+"e, edit <incheckning> = använd incheckning, men stanna för tillägg\n"
+"s, squash <incheckning> = använd incheckning, men infoga i föregående "
+"incheckning\n"
+"f, fixup <incheckning> = som \"squash\", men förkasta "
+"incheckningsmeddelandet\n"
+"x, exec <kommando> = kör kommando (resten av raden) i skalet\n"
+"d, drop <incheckning> = ta bort incheckning\n"
+"l, label <etikett> = ge aktuellt HEAD ett namn\n"
+"t, reset <etikett> = återställ HEAD till en etikett\n"
+"m, merge [-C <incheckning> | -c <incheckning>] <etikett> [# <enrads>]\n"
+".       skapa en sammanslagning med ursprungligt meddelande (eller\n"
+".       enrads, om inget incheckningsmeddelande angavs). Använd\n"
+".       -v <incheckning> för att skriva om meddelandet.\n"
 "\n"
 "Du kan byta ordning på raderna; de utförs uppifrån och ned.\n"
 
-#: git-rebase--interactive.sh:171
+#: git-rebase--interactive.sh:179
 msgid ""
 "\n"
 "Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
@@ -15763,7 +16852,7 @@ msgstr ""
 "Ta inte bort rader. Använd \"drop\" för att specifikt förkasta en "
 "incheckning.\n"
 
-#: git-rebase--interactive.sh:175
+#: git-rebase--interactive.sh:183
 msgid ""
 "\n"
 "If you remove a line here THAT COMMIT WILL BE LOST.\n"
@@ -15771,7 +16860,7 @@ msgstr ""
 "\n"
 "Om du tar bort en rad KOMMER DEN INCHECKNINGEN ATT FÖRLORAS.\n"
 
-#: git-rebase--interactive.sh:213
+#: git-rebase--interactive.sh:221
 #, sh-format
 msgid ""
 "You can amend the commit now, with\n"
@@ -15790,83 +16879,83 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:238
+#: git-rebase--interactive.sh:246
 #, sh-format
 msgid "$sha1: not a commit that can be picked"
 msgstr "$sha1: inte en incheckning som kan väljas"
 
-#: git-rebase--interactive.sh:277
+#: git-rebase--interactive.sh:285
 #, sh-format
 msgid "Invalid commit name: $sha1"
 msgstr "Felaktigt incheckningsnamn: $sha1"
 
-#: git-rebase--interactive.sh:319
+#: git-rebase--interactive.sh:325
 msgid "Cannot write current commit's replacement sha1"
 msgstr "Kan inte skriva ersättnings-sha1 för aktuell incheckning"
 
-#: git-rebase--interactive.sh:371
+#: git-rebase--interactive.sh:376
 #, sh-format
 msgid "Fast-forward to $sha1"
 msgstr "Snabbspolade till $sha1"
 
-#: git-rebase--interactive.sh:373
+#: git-rebase--interactive.sh:378
 #, sh-format
 msgid "Cannot fast-forward to $sha1"
 msgstr "Kan inte snabbspola till $sha1"
 
-#: git-rebase--interactive.sh:382
+#: git-rebase--interactive.sh:387
 #, sh-format
 msgid "Cannot move HEAD to $first_parent"
 msgstr "Kan inte flytta HEAD till $first_parent"
 
-#: git-rebase--interactive.sh:387
+#: git-rebase--interactive.sh:392
 #, sh-format
 msgid "Refusing to squash a merge: $sha1"
 msgstr "Vägrar utföra \"squash\" på en sammanslagning: $sha1"
 
-#: git-rebase--interactive.sh:405
+#: git-rebase--interactive.sh:410
 #, sh-format
 msgid "Error redoing merge $sha1"
 msgstr "Fel när sammanslagningen $sha1 skulle göras om"
 
-#: git-rebase--interactive.sh:414
+#: git-rebase--interactive.sh:419
 #, sh-format
 msgid "Could not pick $sha1"
 msgstr "Kunde inte välja $sha1"
 
-#: git-rebase--interactive.sh:423
+#: git-rebase--interactive.sh:428
 #, sh-format
 msgid "This is the commit message #${n}:"
 msgstr "Det här är incheckningsmeddelande ${n}:"
 
-#: git-rebase--interactive.sh:428
+#: git-rebase--interactive.sh:433
 #, sh-format
 msgid "The commit message #${n} will be skipped:"
 msgstr "Incheckningsmeddelande ${n} kommer hoppas över:"
 
-#: git-rebase--interactive.sh:439
+#: git-rebase--interactive.sh:444
 #, sh-format
 msgid "This is a combination of $count commit."
 msgid_plural "This is a combination of $count commits."
 msgstr[0] "Det här är en kombination av $count incheckning."
 msgstr[1] "Det här är en kombination av $count incheckningar."
 
-#: git-rebase--interactive.sh:448
+#: git-rebase--interactive.sh:453
 #, sh-format
 msgid "Cannot write $fixup_msg"
 msgstr "Kan inte skriva $fixup_msg"
 
-#: git-rebase--interactive.sh:451
+#: git-rebase--interactive.sh:456
 msgid "This is a combination of 2 commits."
 msgstr "Det här är en kombination av 2 incheckningar."
 
-#: git-rebase--interactive.sh:492 git-rebase--interactive.sh:535
-#: git-rebase--interactive.sh:538
+#: git-rebase--interactive.sh:497 git-rebase--interactive.sh:540
+#: git-rebase--interactive.sh:543
 #, sh-format
 msgid "Could not apply $sha1... $rest"
 msgstr "Kunde inte tillämpa $sha1... $rest"
 
-#: git-rebase--interactive.sh:567
+#: git-rebase--interactive.sh:572
 #, sh-format
 msgid ""
 "Could not amend commit after successfully picking $sha1... $rest\n"
@@ -15880,31 +16969,31 @@ msgstr ""
 "pre-commit-kroken misslyckades. Om pre-commit-kroken misslyckades kanske\n"
 "du måste lösa problemet innan du kan skriva om incheckningsmeddelandet."
 
-#: git-rebase--interactive.sh:582
+#: git-rebase--interactive.sh:587
 #, sh-format
 msgid "Stopped at $sha1_abbrev... $rest"
 msgstr "Stoppade på $sha1_abbrev... $rest"
 
-#: git-rebase--interactive.sh:597
+#: git-rebase--interactive.sh:602
 #, sh-format
 msgid "Cannot '$squash_style' without a previous commit"
 msgstr "Kan inte utföra \"$squash_style\" utan en föregående incheckning"
 
-#: git-rebase--interactive.sh:639
+#: git-rebase--interactive.sh:644
 #, sh-format
 msgid "Executing: $rest"
 msgstr "Kör: $rest"
 
-#: git-rebase--interactive.sh:647
+#: git-rebase--interactive.sh:652
 #, sh-format
 msgid "Execution failed: $rest"
 msgstr "Körning misslyckades: $rest"
 
-#: git-rebase--interactive.sh:649
+#: git-rebase--interactive.sh:654
 msgid "and made changes to the index and/or the working tree"
 msgstr "och gjorde ändringar till indexet och/eller arbetskatalogen"
 
-#: git-rebase--interactive.sh:651
+#: git-rebase--interactive.sh:656
 msgid ""
 "You can fix the problem, and then run\n"
 "\n"
@@ -15915,7 +17004,7 @@ msgstr ""
 "\tgit rebase --continue"
 
 #. TRANSLATORS: after these lines is a command to be issued by the user
-#: git-rebase--interactive.sh:664
+#: git-rebase--interactive.sh:669
 #, sh-format
 msgid ""
 "Execution succeeded: $rest\n"
@@ -15930,29 +17019,29 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:675
+#: git-rebase--interactive.sh:680
 #, sh-format
 msgid "Unknown command: $command $sha1 $rest"
 msgstr "Okänt kommando: $command $sha1 $rest"
 
-#: git-rebase--interactive.sh:676
+#: git-rebase--interactive.sh:681
 msgid "Please fix this using 'git rebase --edit-todo'."
 msgstr "Rätta det med \"git rebase --edit-todo\"."
 
-#: git-rebase--interactive.sh:711
+#: git-rebase--interactive.sh:716
 #, sh-format
 msgid "Successfully rebased and updated $head_name."
 msgstr "Lyckades ombasera och uppdatera $head_name."
 
-#: git-rebase--interactive.sh:735
+#: git-rebase--interactive.sh:740
 msgid "could not detach HEAD"
 msgstr "kunde inte koppla från HEAD"
 
-#: git-rebase--interactive.sh:771
+#: git-rebase--interactive.sh:778
 msgid "Could not remove CHERRY_PICK_HEAD"
 msgstr "Kunde inte ta bort CHERRY_PICK_HEAD"
 
-#: git-rebase--interactive.sh:776
+#: git-rebase--interactive.sh:783
 #, sh-format
 msgid ""
 "You have staged changes in your working tree.\n"
@@ -15983,11 +17072,11 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: git-rebase--interactive.sh:793
+#: git-rebase--interactive.sh:800
 msgid "Error trying to find the author identity to amend commit"
 msgstr "Fel vid försök att hitta författaridentitet för att utöka incheckning"
 
-#: git-rebase--interactive.sh:798
+#: git-rebase--interactive.sh:805
 msgid ""
 "You have uncommitted changes in your working tree. Please commit them\n"
 "first and then run 'git rebase --continue' again."
@@ -15995,11 +17084,11 @@ msgstr ""
 "Du har ändringar i arbetskatalogen som inte checkats in. Checka in dem\n"
 "först och kör sedan \"git rebase --continute\" igen."
 
-#: git-rebase--interactive.sh:803 git-rebase--interactive.sh:807
+#: git-rebase--interactive.sh:810 git-rebase--interactive.sh:814
 msgid "Could not commit staged changes."
 msgstr "Kunde inte checka in köade ändringar."
 
-#: git-rebase--interactive.sh:836
+#: git-rebase--interactive.sh:843
 msgid ""
 "\n"
 "You are editing the todo file of an ongoing interactive rebase.\n"
@@ -16013,57 +17102,59 @@ msgstr ""
 "    git rebase --continue\n"
 "\n"
 
-#: git-rebase--interactive.sh:844 git-rebase--interactive.sh:1008
+#: git-rebase--interactive.sh:851 git-rebase--interactive.sh:937
 msgid "Could not execute editor"
 msgstr "Kunde inte starta textredigerare"
 
-#: git-rebase--interactive.sh:860
+#: git-rebase--interactive.sh:872
 #, sh-format
 msgid "Could not checkout $switch_to"
 msgstr "Kunde inte checka ut $switch_to"
 
-#: git-rebase--interactive.sh:865
+#: git-rebase--interactive.sh:879
 msgid "No HEAD?"
 msgstr "Inget HEAD?"
 
-#: git-rebase--interactive.sh:866
+#: git-rebase--interactive.sh:880
 #, sh-format
 msgid "Could not create temporary $state_dir"
 msgstr "Kunde inte skapa temporär $state_dir"
 
-#: git-rebase--interactive.sh:869
+#: git-rebase--interactive.sh:883
 msgid "Could not mark as interactive"
 msgstr "Kunde inte markera som interaktiv"
 
-#: git-rebase--interactive.sh:879 git-rebase--interactive.sh:884
-msgid "Could not init rewritten commits"
-msgstr "Kunde inte initiera omskrivna incheckningar"
-
-#: git-rebase--interactive.sh:910
-msgid "Could not generate todo list"
-msgstr "Kunde inte skapa todo-lista"
-
-#: git-rebase--interactive.sh:986
+#: git-rebase--interactive.sh:915
 #, sh-format
 msgid "Rebase $shortrevisions onto $shortonto ($todocount command)"
 msgid_plural "Rebase $shortrevisions onto $shortonto ($todocount commands)"
 msgstr[0] "Ombasera $shortrevisions på $shortonto ($todocount incheckning)"
 msgstr[1] "Ombasera $shortrevisions på $shortonto ($todocount incheckningar)"
 
-#: git-rebase--interactive.sh:991
+#: git-rebase--interactive.sh:920
 msgid ""
 "\n"
-"However, if you remove everything, the rebase will be aborted.\n"
+"\tHowever, if you remove everything, the rebase will be aborted.\n"
 "\n"
+"\t"
 msgstr ""
 "\n"
-"Ombaseringen kommer dock att avbrytas om du tar bort allting.\n"
+"\tOmbaseringen kommer dock att avbrytas om du tar bort allting.\n"
 "\n"
+"\t"
 
-#: git-rebase--interactive.sh:998
+#: git-rebase--interactive.sh:927
 msgid "Note that empty commits are commented out"
 msgstr "Observera att tomma incheckningar är utkommenterade"
 
+#: git-rebase--interactive.sh:980
+msgid "Could not generate todo list"
+msgstr "Kunde inte skapa todo-lista"
+
+#: git-rebase--interactive.sh:1001 git-rebase--interactive.sh:1006
+msgid "Could not init rewritten commits"
+msgstr "Kunde inte initiera omskrivna incheckningar"
+
 #: git-sh-setup.sh:89 git-sh-setup.sh:94
 #, sh-format
 msgid "usage: $dashless $USAGE"
@@ -16138,68 +17229,68 @@ msgstr "köad"
 msgid "unstaged"
 msgstr "ej köad"
 
-#: git-add--interactive.perl:246 git-add--interactive.perl:271
+#: git-add--interactive.perl:253 git-add--interactive.perl:278
 msgid "binary"
 msgstr "binär"
 
-#: git-add--interactive.perl:255 git-add--interactive.perl:309
+#: git-add--interactive.perl:262 git-add--interactive.perl:316
 msgid "nothing"
 msgstr "ingenting"
 
-#: git-add--interactive.perl:291 git-add--interactive.perl:306
+#: git-add--interactive.perl:298 git-add--interactive.perl:313
 msgid "unchanged"
 msgstr "oändrad"
 
-#: git-add--interactive.perl:602
+#: git-add--interactive.perl:609
 #, perl-format
 msgid "added %d path\n"
 msgid_plural "added %d paths\n"
 msgstr[0] "lade till %d sökväg\n"
 msgstr[1] "lade till %d sökvägar\n"
 
-#: git-add--interactive.perl:605
+#: git-add--interactive.perl:612
 #, perl-format
 msgid "updated %d path\n"
 msgid_plural "updated %d paths\n"
 msgstr[0] "uppdaterade %d sökväg\n"
 msgstr[1] "uppdaterade %d sökvägar\n"
 
-#: git-add--interactive.perl:608
+#: git-add--interactive.perl:615
 #, perl-format
 msgid "reverted %d path\n"
 msgid_plural "reverted %d paths\n"
 msgstr[0] "återställde %d sökväg\n"
 msgstr[1] "återställde %d sökvägar\n"
 
-#: git-add--interactive.perl:611
+#: git-add--interactive.perl:618
 #, perl-format
 msgid "touched %d path\n"
 msgid_plural "touched %d paths\n"
 msgstr[0] "rörde %d sökväg\n"
 msgstr[1] "rörde %d sökvägar\n"
 
-#: git-add--interactive.perl:620
+#: git-add--interactive.perl:627
 msgid "Update"
 msgstr "Uppdatera"
 
-#: git-add--interactive.perl:632
+#: git-add--interactive.perl:639
 msgid "Revert"
 msgstr "Återställ"
 
-#: git-add--interactive.perl:655
+#: git-add--interactive.perl:662
 #, perl-format
 msgid "note: %s is untracked now.\n"
 msgstr "observera: %s spåras inte längre.\n"
 
-#: git-add--interactive.perl:666
+#: git-add--interactive.perl:673
 msgid "Add untracked"
 msgstr "Lägg till ospårad"
 
-#: git-add--interactive.perl:672
+#: git-add--interactive.perl:679
 msgid "No untracked files.\n"
 msgstr "Inga ospårade filer.\n"
 
-#: git-add--interactive.perl:1026
+#: git-add--interactive.perl:1033
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for staging."
@@ -16207,7 +17298,7 @@ msgstr ""
 "Om patchen kan appliceras rent kommer det redigerade stycket att\n"
 "köas omedelbart."
 
-#: git-add--interactive.perl:1029
+#: git-add--interactive.perl:1036
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for stashing."
@@ -16215,7 +17306,7 @@ msgstr ""
 "Om patchen kan appliceras rent kommer det redigerade stycket att\n"
 "läggas till i \"stash\" omedelbart."
 
-#: git-add--interactive.perl:1032
+#: git-add--interactive.perl:1039
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for unstaging."
@@ -16223,7 +17314,7 @@ msgstr ""
 "Om patchen kan appliceras rent kommer det redigerade stycket att\n"
 "tas bort från kön omedelbart."
 
-#: git-add--interactive.perl:1035 git-add--interactive.perl:1044
+#: git-add--interactive.perl:1042 git-add--interactive.perl:1051
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for applying."
@@ -16231,7 +17322,7 @@ msgstr ""
 "Om patchen kan appliceras rent kommer det redigerade stycket att\n"
 "markeras för applicering omedelbart."
 
-#: git-add--interactive.perl:1038 git-add--interactive.perl:1041
+#: git-add--interactive.perl:1045 git-add--interactive.perl:1048
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for discarding."
@@ -16239,16 +17330,16 @@ msgstr ""
 "Om patchen kan appliceras rent kommer det redigerade stycket att\n"
 "markeras för kasta omedelbart."
 
-#: git-add--interactive.perl:1078
+#: git-add--interactive.perl:1085
 #, perl-format
 msgid "failed to open hunk edit file for writing: %s"
 msgstr "misslyckades öppna styckeredigeringsfil för skrivning: %s"
 
-#: git-add--interactive.perl:1079
+#: git-add--interactive.perl:1086
 msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
 msgstr "Manuellt styckeredigeringsläge -- se nederst för snabbguide.\n"
 
-#: git-add--interactive.perl:1085
+#: git-add--interactive.perl:1092
 #, perl-format
 msgid ""
 "---\n"
@@ -16262,7 +17353,7 @@ msgstr ""
 "Rader som börjar med %s kommer att tas bort.\n"
 
 #. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
-#: git-add--interactive.perl:1093
+#: git-add--interactive.perl:1100
 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"
@@ -16272,7 +17363,7 @@ msgstr ""
 "redigera den igen. Om alla rader i ett stycke tas bort avbryts\n"
 "redigeringen och stycket lämnas oförändrat.\n"
 
-#: git-add--interactive.perl:1107
+#: git-add--interactive.perl:1114
 #, perl-format
 msgid "failed to open hunk edit file for reading: %s"
 msgstr "misslyckades öppna styckesredigeringsfil för läsning: %s"
@@ -16283,14 +17374,14 @@ msgstr "misslyckades öppna styckesredigeringsfil för läsning: %s"
 #. 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:1206
+#: git-add--interactive.perl:1213
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
 "Ditt redigerade stycke kan inte appliceras. Redigera igen (\"nej\" kastar!) "
 "[y/n]? "
 
-#: git-add--interactive.perl:1215
+#: git-add--interactive.perl:1222
 msgid ""
 "y - stage this hunk\n"
 "n - do not stage this hunk\n"
@@ -16304,7 +17395,7 @@ msgstr ""
 "a - köa stycket och alla följande i filen\n"
 "d - köa inte stycket eller något av de följande i filen"
 
-#: git-add--interactive.perl:1221
+#: git-add--interactive.perl:1228
 msgid ""
 "y - stash this hunk\n"
 "n - do not stash this hunk\n"
@@ -16318,7 +17409,7 @@ msgstr ""
 "a - \"stash\":a stycket och alla följande i filen\n"
 "d - \"stash\":a inte stycket eller något av de följande i filen"
 
-#: git-add--interactive.perl:1227
+#: git-add--interactive.perl:1234
 msgid ""
 "y - unstage this hunk\n"
 "n - do not unstage this hunk\n"
@@ -16332,7 +17423,7 @@ msgstr ""
 "a - ta bort stycket och alla följande i filen från kön\n"
 "d - ta inte bort stycket eller något av de följande i filen från kön"
 
-#: git-add--interactive.perl:1233
+#: git-add--interactive.perl:1240
 msgid ""
 "y - apply this hunk to index\n"
 "n - do not apply this hunk to index\n"
@@ -16346,7 +17437,7 @@ msgstr ""
 "a - applicera stycket och alla följande i filen\n"
 "d - applicera inte stycket eller något av de följande i filen"
 
-#: git-add--interactive.perl:1239
+#: git-add--interactive.perl:1246
 msgid ""
 "y - discard this hunk from worktree\n"
 "n - do not discard this hunk from worktree\n"
@@ -16360,7 +17451,7 @@ msgstr ""
 "a - förkasta stycket och alla följande i filen\n"
 "d - förkasta inte stycket eller något av de följande i filen"
 
-#: git-add--interactive.perl:1245
+#: git-add--interactive.perl:1252
 msgid ""
 "y - discard this hunk from index and worktree\n"
 "n - do not discard this hunk from index and worktree\n"
@@ -16374,7 +17465,7 @@ msgstr ""
 "a - förkasta stycket och alla följande i filen\n"
 "d - förkasta inte stycket eller något av de följande i filen"
 
-#: git-add--interactive.perl:1251
+#: git-add--interactive.perl:1258
 msgid ""
 "y - apply this hunk to index and worktree\n"
 "n - do not apply this hunk to index and worktree\n"
@@ -16388,7 +17479,7 @@ msgstr ""
 "a - applicera stycket och alla följande i filen\n"
 "d - applicera inte stycket eller något av de följande i filen"
 
-#: git-add--interactive.perl:1266
+#: git-add--interactive.perl:1273
 msgid ""
 "g - select a hunk to go to\n"
 "/ - search for a hunk matching the given regex\n"
@@ -16410,211 +17501,211 @@ msgstr ""
 "e - redigera aktuellt stycke manuellt\n"
 "? - visa hjälp\n"
 
-#: git-add--interactive.perl:1297
+#: git-add--interactive.perl:1304
 msgid "The selected hunks do not apply to the index!\n"
 msgstr "Markerade stycken kan inte appliceras på indexet!\n"
 
-#: git-add--interactive.perl:1298
+#: git-add--interactive.perl:1305
 msgid "Apply them to the worktree anyway? "
 msgstr "Applicera dem på arbetskatalogen trots det? "
 
-#: git-add--interactive.perl:1301
+#: git-add--interactive.perl:1308
 msgid "Nothing was applied.\n"
 msgstr "Ingenting applicerades.\n"
 
-#: git-add--interactive.perl:1312
+#: git-add--interactive.perl:1319
 #, perl-format
 msgid "ignoring unmerged: %s\n"
 msgstr "ignorerar ej sammanslagen: %s\n"
 
-#: git-add--interactive.perl:1321
+#: git-add--interactive.perl:1328
 msgid "Only binary files changed.\n"
 msgstr "Endast binära filer ändrade.\n"
 
-#: git-add--interactive.perl:1323
+#: git-add--interactive.perl:1330
 msgid "No changes.\n"
 msgstr "Inga ändringar.\n"
 
-#: git-add--interactive.perl:1331
+#: git-add--interactive.perl:1338
 msgid "Patch update"
 msgstr "Uppdatera patch"
 
-#: git-add--interactive.perl:1383
+#: git-add--interactive.perl:1390
 #, perl-format
 msgid "Stage mode change [y,n,q,a,d%s,?]? "
 msgstr "Köa ändrat läge [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1384
+#: git-add--interactive.perl:1391
 #, perl-format
 msgid "Stage deletion [y,n,q,a,d%s,?]? "
 msgstr "Köa borttagning [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1385
+#: git-add--interactive.perl:1392
 #, perl-format
 msgid "Stage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Köa stycket [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1388
+#: git-add--interactive.perl:1395
 #, perl-format
 msgid "Stash mode change [y,n,q,a,d%s,?]? "
 msgstr "Stash:a ändrat läge [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1389
+#: git-add--interactive.perl:1396
 #, perl-format
 msgid "Stash deletion [y,n,q,a,d%s,?]? "
 msgstr "Stash:a borttagning [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1390
+#: git-add--interactive.perl:1397
 #, perl-format
 msgid "Stash this hunk [y,n,q,a,d%s,?]? "
 msgstr "Stash:a stycket [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1393
+#: git-add--interactive.perl:1400
 #, perl-format
 msgid "Unstage mode change [y,n,q,a,d%s,?]? "
 msgstr "Ta bort ändrat läge från kön [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1394
+#: git-add--interactive.perl:1401
 #, perl-format
 msgid "Unstage deletion [y,n,q,a,d%s,?]? "
 msgstr "Ta bort borttagning från kön [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1395
+#: git-add--interactive.perl:1402
 #, perl-format
 msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Ta bort stycket från kön [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1398
+#: git-add--interactive.perl:1405
 #, perl-format
 msgid "Apply mode change to index [y,n,q,a,d%s,?]? "
 msgstr "Applicera ändrat läge på indexet [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1399
+#: git-add--interactive.perl:1406
 #, perl-format
 msgid "Apply deletion to index [y,n,q,a,d%s,?]? "
 msgstr "Applicera borttagning på indexet [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1400
+#: git-add--interactive.perl:1407
 #, perl-format
 msgid "Apply this hunk to index [y,n,q,a,d%s,?]? "
 msgstr "Applicera stycket på indexet [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1403
+#: git-add--interactive.perl:1410
 #, perl-format
 msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? "
 msgstr "Kasta ändrat läge från arbetskatalogen [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1404
+#: git-add--interactive.perl:1411
 #, perl-format
 msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? "
 msgstr "Kasta borttagning från arbetskatalogen [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1405
+#: git-add--interactive.perl:1412
 #, perl-format
 msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
 msgstr "Kasta stycket från arbetskatalogen [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1408
+#: git-add--interactive.perl:1415
 #, perl-format
 msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Kasta ändrat läge från indexet och arbetskatalogen [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1409
+#: git-add--interactive.perl:1416
 #, perl-format
 msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Kasta borttagning från indexet och arbetskatalogen [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1410
+#: git-add--interactive.perl:1417
 #, perl-format
 msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Kasta stycket från indexet och arbetskatalogen [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1413
+#: git-add--interactive.perl:1420
 #, perl-format
 msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Applicera ändrat läge på indexet och arbetskatalogen [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1414
+#: git-add--interactive.perl:1421
 #, perl-format
 msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Applicera borttagning på indexet och arbetskatalogen [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1415
+#: git-add--interactive.perl:1422
 #, perl-format
 msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Applicera stycket på indexet och arbetskatalogen [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1515
+#: git-add--interactive.perl:1522
 msgid "No other hunks to goto\n"
 msgstr "Inga andra stycken att gå till\n"
 
-#: git-add--interactive.perl:1522
+#: git-add--interactive.perl:1529
 msgid "go to which hunk (<ret> to see more)? "
 msgstr "gå till vilket stycke (<ret> för att se fler)? "
 
-#: git-add--interactive.perl:1524
+#: git-add--interactive.perl:1531
 msgid "go to which hunk? "
 msgstr "gå till vilket stycke? "
 
-#: git-add--interactive.perl:1533
+#: git-add--interactive.perl:1540
 #, perl-format
 msgid "Invalid number: '%s'\n"
 msgstr "Ogiltigt siffervärde: \"%s\"\n"
 
-#: git-add--interactive.perl:1538
+#: git-add--interactive.perl:1545
 #, perl-format
 msgid "Sorry, only %d hunk available.\n"
 msgid_plural "Sorry, only %d hunks available.\n"
 msgstr[0] "Beklagar, det finns bara %d stycke.\n"
 msgstr[1] "Beklagar, det finns bara %d stycken.\n"
 
-#: git-add--interactive.perl:1564
+#: git-add--interactive.perl:1571
 msgid "No other hunks to search\n"
 msgstr "Inga andra stycken att söka efter\n"
 
-#: git-add--interactive.perl:1568
+#: git-add--interactive.perl:1575
 msgid "search for regex? "
 msgstr "sök efter reguljärt uttryck? "
 
-#: git-add--interactive.perl:1581
+#: git-add--interactive.perl:1588
 #, perl-format
 msgid "Malformed search regexp %s: %s\n"
 msgstr "Felaktigt format på reguljärt sökuttryck %s: %s\n"
 
-#: git-add--interactive.perl:1591
+#: git-add--interactive.perl:1598
 msgid "No hunk matches the given pattern\n"
 msgstr "Inga stycken motsvarar givet mönster\n"
 
-#: git-add--interactive.perl:1603 git-add--interactive.perl:1625
+#: git-add--interactive.perl:1610 git-add--interactive.perl:1632
 msgid "No previous hunk\n"
 msgstr "Inget föregående stycke\n"
 
-#: git-add--interactive.perl:1612 git-add--interactive.perl:1631
+#: git-add--interactive.perl:1619 git-add--interactive.perl:1638
 msgid "No next hunk\n"
 msgstr "Inget följande stycke\n"
 
-#: git-add--interactive.perl:1637
+#: git-add--interactive.perl:1644
 msgid "Sorry, cannot split this hunk\n"
 msgstr "Beklagar, kan inte dela stycket\n"
 
-#: git-add--interactive.perl:1643
+#: git-add--interactive.perl:1650
 #, perl-format
 msgid "Split into %d hunk.\n"
 msgid_plural "Split into %d hunks.\n"
 msgstr[0] "Dela i %d stycke.\n"
 msgstr[1] "Dela i %d stycken.\n"
 
-#: git-add--interactive.perl:1653
+#: git-add--interactive.perl:1660
 msgid "Sorry, cannot edit this hunk\n"
 msgstr "Beklagar, kan inte redigera stycket\n"
 
-#: git-add--interactive.perl:1699
+#: git-add--interactive.perl:1706
 msgid "Review diff"
 msgstr "Granska diff"
 
 #. TRANSLATORS: please do not translate the command names
 #. 'status', 'update', 'revert', etc.
-#: git-add--interactive.perl:1718
+#: git-add--interactive.perl:1725
 msgid ""
 "status        - show paths with changes\n"
 "update        - add working tree state to the staged set of changes\n"
@@ -16631,18 +17722,18 @@ msgstr ""
 "diff          - visa diff mellan HEAD och index\n"
 "add untracked - lägg till innehåll i ospårade filer till köade ändringar\n"
 
-#: git-add--interactive.perl:1735 git-add--interactive.perl:1740
-#: git-add--interactive.perl:1743 git-add--interactive.perl:1750
-#: git-add--interactive.perl:1754 git-add--interactive.perl:1760
+#: git-add--interactive.perl:1742 git-add--interactive.perl:1747
+#: git-add--interactive.perl:1750 git-add--interactive.perl:1757
+#: git-add--interactive.perl:1761 git-add--interactive.perl:1767
 msgid "missing --"
 msgstr "saknad --"
 
-#: git-add--interactive.perl:1756
+#: git-add--interactive.perl:1763
 #, perl-format
 msgid "unknown --patch mode: %s"
 msgstr "okänt läge för --patch: %s"
 
-#: git-add--interactive.perl:1762 git-add--interactive.perl:1768
+#: git-add--interactive.perl:1769 git-add--interactive.perl:1775
 #, perl-format
 msgid "invalid argument %s, expecting --"
 msgstr "felaktigt argument %s, förväntar --"
@@ -16855,7 +17946,7 @@ msgstr "Vad vill du göra med adressen? (q=avsluta, d=kasta, e=redigera): "
 msgid "CA path \"%s\" does not exist"
 msgstr "CA-sökvägen \"%s\" finns inte"
 
-#: git-send-email.perl:1395
+#: git-send-email.perl:1400
 msgid ""
 "    The Cc list above has been expanded by additional\n"
 "    addresses found in the patch commit message. By default\n"
@@ -16879,127 +17970,127 @@ msgstr ""
 "    meddelande, kör \"git config --global sendemail.confirm auto\".\n"
 "\n"
 
-#. TRANSLATORS: Make sure to include [y] [n] [q] [a] in your
+#. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
 #. translation. The program will only accept English input
 #. at this point.
-#: git-send-email.perl:1410
-msgid "Send this email? ([y]es|[n]o|[q]uit|[a]ll): "
-msgstr "Sända brevet? (y=ja, n=nej, q=avsluta, a=alla): "
+#: git-send-email.perl:1415
+msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
+msgstr "Sända brevet? (y=ja, n=nej, e=redigera, q=avsluta, a=alla): "
 
-#: git-send-email.perl:1413
+#: git-send-email.perl:1418
 msgid "Send this email reply required"
 msgstr "Svar krävs på frågan \"Sända brevet?\""
 
-#: git-send-email.perl:1439
+#: git-send-email.perl:1446
 msgid "The required SMTP server is not properly defined."
 msgstr "Nödvändig SMTP-server har inte angivits korrekt."
 
-#: git-send-email.perl:1486
+#: git-send-email.perl:1493
 #, perl-format
 msgid "Server does not support STARTTLS! %s"
 msgstr "Servern stöder inte SMARTTLS! %s"
 
-#: git-send-email.perl:1491 git-send-email.perl:1495
+#: git-send-email.perl:1498 git-send-email.perl:1502
 #, perl-format
 msgid "STARTTLS failed! %s"
 msgstr "STARTTLS misslyckades! %s"
 
-#: git-send-email.perl:1505
+#: git-send-email.perl:1512
 msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug."
 msgstr ""
 "Kan inte initiera SMTP korrekt. Kontrollera inställningarna och använd --"
 "smtp-debug."
 
-#: git-send-email.perl:1523
+#: git-send-email.perl:1530
 #, perl-format
 msgid "Failed to send %s\n"
 msgstr "Misslyckades sända %s\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Dry-Sent %s\n"
 msgstr "Test-Sände %s\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Sent %s\n"
 msgstr "Sände %s\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "Dry-OK. Log says:\n"
 msgstr "Test-OK. Loggen säger:\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "OK. Log says:\n"
 msgstr "OK. Loggen säger:\n"
 
-#: git-send-email.perl:1540
+#: git-send-email.perl:1547
 msgid "Result: "
 msgstr "Resultat: "
 
-#: git-send-email.perl:1543
+#: git-send-email.perl:1550
 msgid "Result: OK\n"
 msgstr "Resultat: OK\n"
 
-#: git-send-email.perl:1556
+#: git-send-email.perl:1568
 #, perl-format
 msgid "can't open file %s"
 msgstr "kan inte öppna filen %s"
 
-#: git-send-email.perl:1603 git-send-email.perl:1623
+#: git-send-email.perl:1615 git-send-email.perl:1635
 #, perl-format
 msgid "(mbox) Adding cc: %s from line '%s'\n"
 msgstr "(mbox) Lägger till cc: %s från raden \"%s\"\n"
 
-#: git-send-email.perl:1609
+#: git-send-email.perl:1621
 #, perl-format
 msgid "(mbox) Adding to: %s from line '%s'\n"
 msgstr "(mbox) Lägger till to: %s från raden \"%s\"\n"
 
-#: git-send-email.perl:1657
+#: git-send-email.perl:1674
 #, perl-format
 msgid "(non-mbox) Adding cc: %s from line '%s'\n"
 msgstr "(icke-mbox) Lägger till cc: %s från raden \"%s\"\n"
 
-#: git-send-email.perl:1682
+#: git-send-email.perl:1699
 #, perl-format
 msgid "(body) Adding cc: %s from line '%s'\n"
 msgstr "(kropp) Lägger till cc: %s från raden \"%s\"\n"
 
-#: git-send-email.perl:1788
+#: git-send-email.perl:1817
 #, perl-format
 msgid "(%s) Could not execute '%s'"
 msgstr "(%s) Kunde inte köra \"%s\""
 
-#: git-send-email.perl:1795
+#: git-send-email.perl:1824
 #, perl-format
 msgid "(%s) Adding %s: %s from: '%s'\n"
 msgstr "(%s) Lägger till %s: %s från: \"%s\"\n"
 
-#: git-send-email.perl:1799
+#: git-send-email.perl:1828
 #, perl-format
 msgid "(%s) failed to close pipe to '%s'"
 msgstr "(%s) misslyckades stänga röret till \"%s\""
 
-#: git-send-email.perl:1826
+#: git-send-email.perl:1855
 msgid "cannot send message as 7bit"
 msgstr "kan inte sända brev som sjubitars"
 
-#: git-send-email.perl:1834
+#: git-send-email.perl:1863
 msgid "invalid transfer encoding"
 msgstr "ogiltig överföringskondning"
 
-#: git-send-email.perl:1872 git-send-email.perl:1923 git-send-email.perl:1933
+#: git-send-email.perl:1901 git-send-email.perl:1952 git-send-email.perl:1962
 #, perl-format
 msgid "unable to open %s: %s\n"
 msgstr "kunde inte öppna %s: %s\n"
 
-#: git-send-email.perl:1875
+#: git-send-email.perl:1904
 #, perl-format
 msgid "%s: patch contains a line longer than 998 characters"
 msgstr "%s: patchen innehåller en rad längre än 998 tecken"
 
-#: git-send-email.perl:1891
+#: git-send-email.perl:1920
 #, perl-format
 msgid "Skipping %s with backup suffix '%s'.\n"
 msgstr ""
@@ -17007,11 +18098,41 @@ msgstr ""
 "säkerhetskopior.\n"
 
 #. TRANSLATORS: please keep "[y|N]" as is.
-#: git-send-email.perl:1895
+#: git-send-email.perl:1924
 #, perl-format
 msgid "Do you really want to send %s? [y|N]: "
 msgstr "Vill du verkligen sända %s? [y=ja, n=nej]: "
 
+#~ msgid "Everyday Git With 20 Commands Or So"
+#~ msgstr "Git för dagligt bruk i ungefär 20 kommandon"
+
+#~ msgid "Could not open '%s' for writing"
+#~ msgstr "Kunde inte öppna \"%s\" för skrivning"
+
+#~ msgid ""
+#~ "unexpected 1st line of squash message:\n"
+#~ "\n"
+#~ "\t%.*s"
+#~ msgstr ""
+#~ "oväntad första rad i squash-meddelande:\n"
+#~ "\n"
+#~ "\t%.*s"
+
+#~ msgid ""
+#~ "invalid 1st line of squash message:\n"
+#~ "\n"
+#~ "\t%.*s"
+#~ msgstr ""
+#~ "ogiltig första rad i squash-meddelande:\n"
+#~ "\n"
+#~ "\t%.*s"
+
+#~ msgid "BUG: returned path string doesn't match cwd?"
+#~ msgstr "BUG: returnerad sökvägssträng matchar inte cwd?"
+
+#~ msgid "Error in object"
+#~ msgstr "Fel i objekt"
+
 #~ msgid "git fetch-pack: expected ACK/NAK, got EOF"
 #~ msgstr "git fetch-patch: förväntade ACK/NAK, fick EOF"
 
@@ -17199,9 +18320,6 @@ msgstr "Vill du verkligen sända %s? [y=ja, n=nej]: "
 #~ msgid "blob object"
 #~ msgstr "blob-objekt"
 
-#~ msgid "other tag object"
-#~ msgstr "annat taggobjekt"
-
 #~ msgid ""
 #~ "There is nothing to exclude from by :(exclude) patterns.\n"
 #~ "Perhaps you forgot to add either ':/' or '.' ?"
@@ -17571,9 +18689,6 @@ msgstr "Vill du verkligen sända %s? [y=ja, n=nej]: "
 #~ msgstr ""
 #~ "Köa dina ändringar i .gitmodules eller använd \"stash\" för att fortsätta"
 
-#~ msgid "could not verify the tag '%s'"
-#~ msgstr "kunde inte bekräfta taggen \"%s\""
-
 #~ msgid "failed to remove: %s"
 #~ msgstr "misslyckades ta bort: %s"
 
@@ -17775,9 +18890,6 @@ msgstr "Vill du verkligen sända %s? [y=ja, n=nej]: "
 #~ msgid "no branch specified"
 #~ msgstr "inget grennamn angavs"
 
-#~ msgid "check a branch out in a separate working directory"
-#~ msgstr "checka ut en gren i separat arbetskatalog"
-
 #~ msgid "prune .git/worktrees"
 #~ msgstr "rensa .git/worktrees"
 
@@ -17979,9 +19091,6 @@ msgstr "Vill du verkligen sända %s? [y=ja, n=nej]: "
 #~ msgid "more than %d trees given: '%s'"
 #~ msgstr "mer än %d träd angavs: \"%s\""
 
-#~ msgid "You cannot combine --no-ff with --ff-only."
-#~ msgstr "Du kan inte kombinera --no-ff med --ff-only."
-
 #~ msgid ""
 #~ "'%s' has changes staged in the index\n"
 #~ "(use --cached to keep the file, or -f to force removal)"
index 1ad2005ef0f4ff81e47739ac5b6c4178381f6c6c..dbc028bca75a36f1aff0f050df5783c9ee010143 100644 (file)
--- a/po/vi.po
+++ b/po/vi.po
@@ -6,10 +6,10 @@
 #
 msgid ""
 msgstr ""
-"Project-Id-Version: git v2.17.0\n"
+"Project-Id-Version: git v2.18.0.round3\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2018-03-16 07:29+0800\n"
-"PO-Revision-Date: 2018-03-17 07:50+0700\n"
+"POT-Creation-Date: 2018-06-16 22:06+0800\n"
+"PO-Revision-Date: 2018-06-17 07:06+0700\n"
 "Last-Translator: Trần Ngọc Quân <vnwildman@gmail.com>\n"
 "Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n"
 "Language: vi\n"
@@ -22,69 +22,69 @@ msgstr ""
 "X-Poedit-Basepath: ../\n"
 "X-Generator: Gtranslator 2.91.7\n"
 
-#: advice.c:62
+#: advice.c:92
 #, c-format
-msgid "hint: %.*s\n"
-msgstr "gợi ý: %.*s\n"
+msgid "%shint: %.*s%s\n"
+msgstr "%sgợi ý: %.*s%s\n"
 
-#: advice.c:90
+#: advice.c:137
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr ""
-"Cherry 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."
+"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."
 
-#: advice.c:92
+#: advice.c:139
 msgid "Committing is not possible because you have unmerged files."
 msgstr ""
 "Commit 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."
 
-#: advice.c:94
+#: advice.c:141
 msgid "Merging is not possible because you have unmerged files."
 msgstr ""
 "Merge 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."
 
-#: advice.c:96
+#: advice.c:143
 msgid "Pulling is not possible because you have unmerged files."
 msgstr ""
 "Pull 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."
 
-#: advice.c:98
+#: advice.c:145
 msgid "Reverting is not possible because you have unmerged files."
 msgstr ""
 "Revert 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."
 
-#: advice.c:100
+#: advice.c:147
 #, c-format
 msgid "It is not possible to %s because you have unmerged files."
 msgstr ""
 "Nó là 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."
 
-#: advice.c:108
+#: advice.c:155
 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,\n"
-"và sau đó dùng lệnh “git add/rm <tập-tin>”\n"
+"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."
 
-#: advice.c:116
+#: advice.c:163
 msgid "Exiting because of an unresolved conflict."
 msgstr "Thoát ra bởi vì xung đột không thể giải quyết."
 
-#: advice.c:121 builtin/merge.c:1251
+#: advice.c:168 builtin/merge.c:1250
 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)."
 
-#: advice.c:123
+#: advice.c:170
 msgid "Please, commit your changes before merging."
 msgstr "Vui lòng chuyển giao các thay đổi trước khi hòa trộn."
 
-#: advice.c:124
+#: advice.c:171
 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."
 
-#: advice.c:130
+#: advice.c:177
 #, c-format
 msgid ""
 "Note: checking out '%s'.\n"
@@ -354,7 +354,7 @@ msgstr "gặp lỗi khi vá: %s:%ld"
 msgid "cannot checkout %s"
 msgstr "không thể lấy ra %s"
 
-#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:277
+#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:278
 #, c-format
 msgid "failed to read %s"
 msgstr "gặp lỗi khi đọc %s"
@@ -552,7 +552,7 @@ msgstr[0] "Đang áp dụng miếng vá %%s với %d lần từ chối…"
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "đang cắt ngắn tên tập tin .rej thành %.*s.rej"
 
-#: apply.c:4545 builtin/fetch.c:775 builtin/fetch.c:1025
+#: apply.c:4545 builtin/fetch.c:786 builtin/fetch.c:1036
 #, c-format
 msgid "cannot open %s"
 msgstr "không mở được “%s”"
@@ -603,15 +603,15 @@ msgid "%d line applied after fixing whitespace errors."
 msgid_plural "%d lines applied after fixing whitespace errors."
 msgstr[0] "%d dòng được áp dụng sau khi sửa các lỗi khoảng trắng."
 
-#: apply.c:4894 builtin/add.c:539 builtin/mv.c:298 builtin/rm.c:390
+#: apply.c:4894 builtin/add.c:538 builtin/mv.c:300 builtin/rm.c:389
 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"
 
 #: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257
-#: builtin/clone.c:118 builtin/fetch.c:127 builtin/pull.c:193
-#: builtin/submodule--helper.c:403 builtin/submodule--helper.c:1197
-#: builtin/submodule--helper.c:1200 builtin/submodule--helper.c:1567
-#: builtin/submodule--helper.c:1570 builtin/submodule--helper.c:1787
+#: builtin/clone.c:120 builtin/fetch.c:126 builtin/pull.c:198
+#: builtin/submodule--helper.c:405 builtin/submodule--helper.c:1210
+#: builtin/submodule--helper.c:1213 builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1587 builtin/submodule--helper.c:1807
 #: git-add--interactive.perl:197
 msgid "path"
 msgstr "đường-dẫn"
@@ -690,7 +690,7 @@ msgstr "đảm bảo rằng có ít nhất <n> dòng nội dung khớp"
 
 #: apply.c:4960 builtin/am.c:2242 builtin/interpret-trailers.c:95
 #: builtin/interpret-trailers.c:97 builtin/interpret-trailers.c:99
-#: builtin/pack-objects.c:3035
+#: builtin/pack-objects.c:3177
 msgid "action"
 msgstr "hành động"
 
@@ -718,9 +718,9 @@ msgstr "để lại khối dữ liệu bị từ chối trong các tập tin *.r
 msgid "allow overlapping hunks"
 msgstr "cho phép chồng khối nhớ"
 
-#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21
-#: builtin/commit.c:1276 builtin/count-objects.c:96 builtin/fsck.c:665
-#: builtin/log.c:1901 builtin/mv.c:123 builtin/read-tree.c:125
+#: apply.c:4977 builtin/add.c:290 builtin/check-ignore.c:21
+#: builtin/commit.c:1301 builtin/count-objects.c:98 builtin/fsck.c:666
+#: builtin/log.c:1901 builtin/mv.c:122 builtin/read-tree.c:124
 msgid "be verbose"
 msgstr "chi tiết"
 
@@ -760,98 +760,98 @@ msgstr ""
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <kho> [--exec <lệnh>] --list"
 
-#: archive.c:351 builtin/add.c:176 builtin/add.c:515 builtin/rm.c:299
+#: archive.c:351 builtin/add.c:176 builtin/add.c:514 builtin/rm.c:298
 #, 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"
 
-#: archive.c:436
+#: archive.c:434
 msgid "fmt"
 msgstr "định_dạng"
 
-#: archive.c:436
+#: archive.c:434
 msgid "archive format"
 msgstr "định dạng lưu trữ"
 
-#: archive.c:437 builtin/log.c:1462
+#: archive.c:435 builtin/log.c:1462
 msgid "prefix"
 msgstr "tiền_tố"
 
-#: archive.c:438
+#: archive.c:436
 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"
 
-#: archive.c:439 builtin/blame.c:702 builtin/blame.c:703 builtin/config.c:62
-#: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:869
+#: archive.c:437 builtin/blame.c:813 builtin/blame.c:814 builtin/config.c:127
+#: builtin/fast-export.c:1007 builtin/fast-export.c:1009 builtin/grep.c:869
 #: builtin/hash-object.c:103 builtin/ls-files.c:551 builtin/ls-files.c:554
-#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120
+#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:119
 #: parse-options.h:165
 msgid "file"
 msgstr "tập_tin"
 
-#: archive.c:440 builtin/archive.c:89
+#: archive.c:438 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "ghi kho lưu vào tập tin này"
 
-#: archive.c:442
+#: archive.c:440
 msgid "read .gitattributes in working directory"
 msgstr "đọc .gitattributes trong thư mục làm việc"
 
-#: archive.c:443
+#: archive.c:441
 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)"
 
-#: archive.c:444
+#: archive.c:442
 msgid "store only"
 msgstr "chỉ lưu (không nén)"
 
-#: archive.c:445
+#: archive.c:443
 msgid "compress faster"
 msgstr "nén nhanh hơn"
 
-#: archive.c:453
+#: archive.c:451
 msgid "compress better"
 msgstr "nén nhỏ hơn"
 
-#: archive.c:456
+#: archive.c:454
 msgid "list supported archive formats"
 msgstr "liệt kê các kiểu nén được hỗ trợ"
 
-#: archive.c:458 builtin/archive.c:90 builtin/clone.c:108 builtin/clone.c:111
-#: builtin/submodule--helper.c:1209 builtin/submodule--helper.c:1576
+#: archive.c:456 builtin/archive.c:90 builtin/clone.c:110 builtin/clone.c:113
+#: builtin/submodule--helper.c:1222 builtin/submodule--helper.c:1593
 msgid "repo"
 msgstr "kho"
 
-#: archive.c:459 builtin/archive.c:91
+#: archive.c:457 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "nhận kho nén từ kho chứa <kho> trên máy chủ"
 
-#: archive.c:460 builtin/archive.c:92 builtin/notes.c:489
+#: archive.c:458 builtin/archive.c:92 builtin/notes.c:489
 msgid "command"
 msgstr "lệnh"
 
-#: archive.c:461 builtin/archive.c:93
+#: archive.c:459 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "đường dẫn đến lệnh git-upload-pack trên máy chủ"
 
-#: archive.c:468
+#: archive.c:466
 msgid "Unexpected option --remote"
 msgstr "Gặp tùy chọn --remote không cần"
 
-#: archive.c:470
+#: archive.c:468
 msgid "Option --exec can only be used together with --remote"
 msgstr "Tùy chọn --exec chỉ có thể được dùng cùng với --remote"
 
-#: archive.c:472
+#: archive.c:470
 msgid "Unexpected option --output"
 msgstr "Gặp tùy chọn không cần --output"
 
-#: archive.c:494
+#: archive.c:492
 #, c-format
 msgid "Unknown archive format '%s'"
 msgstr "Không hiểu định dạng “%s”"
 
-#: archive.c:501
+#: archive.c:499
 #, c-format
 msgid "Argument not supported for format '%s': -%d"
 msgstr "Tham số không được hỗ trợ cho định dạng “%s”: -%d"
@@ -869,22 +869,22 @@ 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."
 
-#: bisect.c:460
+#: bisect.c:461
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "nội dung được trích dẫn sai tập tin “%s”: %s"
 
-#: bisect.c:668
+#: bisect.c:669
 #, c-format
 msgid "We cannot bisect more!\n"
 msgstr "Chúng tôi không bisect thêm nữa!\n"
 
-#: bisect.c:722
+#: bisect.c:723
 #, c-format
 msgid "Not a valid commit name %s"
 msgstr "Không phải tên đối tượng commit %s hợp lệ"
 
-#: bisect.c:746
+#: bisect.c:747
 #, c-format
 msgid ""
 "The merge base %s is bad.\n"
@@ -893,7 +893,7 @@ 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"
 
-#: bisect.c:751
+#: bisect.c:752
 #, c-format
 msgid ""
 "The merge base %s is new.\n"
@@ -902,7 +902,7 @@ 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"
 
-#: bisect.c:756
+#: bisect.c:757
 #, c-format
 msgid ""
 "The merge base %s is %s.\n"
@@ -911,7 +911,7 @@ 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"
 
-#: bisect.c:764
+#: bisect.c:765
 #, c-format
 msgid ""
 "Some %s revs are not ancestors of the %s rev.\n"
@@ -922,7 +922,7 @@ msgstr ""
 "git bisect không thể làm việc đúng đắn 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"
 
-#: bisect.c:777
+#: bisect.c:778
 #, c-format
 msgid ""
 "the merge base between %s and [%s] must be skipped.\n"
@@ -934,36 +934,36 @@ msgstr ""
 "%s.\n"
 "Chúng tôi vẫn cứ tiếp tục."
 
-#: bisect.c:810
+#: bisect.c:811
 #, 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"
 
-#: bisect.c:850
+#: bisect.c:851
 #, c-format
 msgid "a %s revision is needed"
 msgstr "cần một điểm xét duyệt %s"
 
-#: bisect.c:869 builtin/notes.c:175 builtin/tag.c:235
+#: bisect.c:870 builtin/notes.c:175 builtin/tag.c:236
 #, c-format
 msgid "could not create file '%s'"
 msgstr "không thể tạo tập tin “%s”"
 
-#: bisect.c:920
+#: bisect.c:921
 #, c-format
 msgid "could not read file '%s'"
 msgstr "không thể đọc tập tin “%s”"
 
-#: bisect.c:950
+#: bisect.c:951
 msgid "reading bisect refs failed"
 msgstr "việc đọc tham chiếu bisect gặp lỗi"
 
-#: bisect.c:969
+#: bisect.c:970
 #, c-format
 msgid "%s was both %s and %s\n"
 msgstr "%s là cả %s và %s\n"
 
-#: bisect.c:977
+#: bisect.c:978
 #, c-format
 msgid ""
 "No testable commit found.\n"
@@ -972,7 +972,7 @@ msgstr ""
 "không tìm thấy lần chuyển giao kiểm tra được nào.\n"
 "Có lẽ bạn bắt đầu với các tham số đường dẫn sai?\n"
 
-#: bisect.c:996
+#: bisect.c:997
 #, c-format
 msgid "(roughly %d step)"
 msgid_plural "(roughly %d steps)"
@@ -981,50 +981,50 @@ msgstr[0] "(ước chừng %d bước)"
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
 #.
-#: bisect.c:1002
+#: bisect.c:1003
 #, 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"
 
-#: blame.c:1758
+#: blame.c:1756
 msgid "--contents and --reverse do not blend well."
 msgstr "tùy chọn--contents và --reverse không được trộn vào nhau."
 
-#: blame.c:1769
+#: blame.c:1767
 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"
 
-#: blame.c:1789
+#: blame.c:1787
 msgid "--reverse and --first-parent together require specified latest commit"
 msgstr ""
 "--reverse và --first-parent cùng nhau cần chỉ định lần chuyển giao cuối"
 
-#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699
-#: sequencer.c:2901 builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920
-#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370
-#: builtin/shortlog.c:191
+#: blame.c:1796 bundle.c:160 ref-filter.c:2075 sequencer.c:1861
+#: sequencer.c:3632 builtin/commit.c:981 builtin/log.c:366 builtin/log.c:920
+#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:372
+#: builtin/shortlog.c:192
 msgid "revision walk setup failed"
 msgstr "cài đặt việc di chuyển qua các điểm xét duyệt gặp lỗi"
 
-#: blame.c:1816
+#: blame.c:1814
 msgid ""
 "--reverse --first-parent together require range along first-parent chain"
 msgstr ""
 "--reverse --first-parent cùng nhau yêu cầu vùng cùng với chuỗi cha-mẹ-đầu-"
 "tiên"
 
-#: blame.c:1827
+#: blame.c:1825
 #, c-format
 msgid "no such path %s in %s"
 msgstr "không có đường dẫn %s trong “%s”"
 
-#: blame.c:1838
+#: blame.c:1836
 #, c-format
 msgid "cannot read blob %s for path %s"
 msgstr "không thể đọc blob %s cho đường dẫn “%s”"
 
-#: branch.c:53
+#: branch.c:54
 #, c-format
 msgid ""
 "\n"
@@ -1037,90 +1037,90 @@ msgstr ""
 "thông tin theo dõi máy chủ bằng cách gọi lệnh\n"
 "\"git branch --set-upstream-to=%s%s%s\"."
 
-#: branch.c:67
+#: branch.c:68
 #, c-format
 msgid "Not setting branch %s as its own upstream."
 msgstr "Chưa cài đặt nhánh %s như là thượng nguồn của nó."
 
-#: branch.c:93
+#: branch.c:94
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s' by rebasing."
 msgstr ""
 "Nhánh “%s” cài đặt để theo dõi nhánh máy chủ “%s” từ “%s” bằng cách rebase."
 
-#: branch.c:94
+#: branch.c:95
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s'."
 msgstr "Nhánh “%s” cài đặt để theo dõi nhánh máy chủ “%s” từ “%s”."
 
-#: branch.c:98
+#: branch.c:99
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s' by rebasing."
 msgstr "Nhánh “%s” cài đặt để theo dõi nhánh nội bộ “%s” bằng cách rebase."
 
-#: branch.c:99
+#: branch.c:100
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s'."
 msgstr "Nhánh “%s” cài đặt để theo dõi nhánh nội bộ “%s”."
 
-#: branch.c:104
+#: branch.c:105
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s' by rebasing."
 msgstr ""
 "Nhánh “%s” cài đặt để theo dõi tham chiếu máy chủ “%s” bằng cách rebase."
 
-#: branch.c:105
+#: branch.c:106
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s'."
 msgstr "Nhánh “%s” cài đặt để theo dõi tham chiếu máy chủ “%s”."
 
-#: branch.c:109
+#: branch.c:110
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s' by rebasing."
 msgstr ""
 "Nhánh “%s” cài đặt để theo dõi tham chiếu nội bộ “%s” bằng cách rebase."
 
-#: branch.c:110
+#: branch.c:111
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s'."
 msgstr "Nhánh “%s” cài đặt để theo dõi tham chiếu nội bộ “%s”."
 
-#: branch.c:119
+#: branch.c:120
 msgid "Unable to write upstream branch configuration"
 msgstr "Không thể ghi cấu hình nhánh thượng nguồn"
 
-#: branch.c:156
+#: branch.c:157
 #, c-format
 msgid "Not tracking: ambiguous information for ref %s"
 msgstr "Không theo dõi: thông tin chưa rõ ràng cho tham chiếu %s"
 
-#: branch.c:189
+#: branch.c:190
 #, 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ệ."
 
-#: branch.c:208
+#: branch.c:209
 #, c-format
 msgid "A branch named '%s' already exists."
 msgstr "Đã có nhánh mang tên “%s”."
 
-#: branch.c:213
+#: branch.c:214
 msgid "Cannot force update the current branch."
 msgstr "Không thể ép buộc cập nhật nhánh hiện hành."
 
-#: branch.c:233
+#: branch.c:234
 #, c-format
 msgid "Cannot setup 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 "
 "nhánh."
 
-#: branch.c:235
+#: branch.c:236
 #, 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"
 
-#: branch.c:237
+#: branch.c:238
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -1140,27 +1140,27 @@ msgstr ""
 "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."
 
-#: branch.c:280
+#: branch.c:281
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "Không phải tên đối tượng hợp lệ: “%s”."
 
-#: branch.c:300
+#: branch.c:301
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "Tên đối tượng chưa rõ ràng: “%s”."
 
-#: branch.c:305
+#: branch.c:306
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "Nhánh không hợp lệ: “%s”."
 
-#: branch.c:359
+#: branch.c:360
 #, c-format
 msgid "'%s' is already checked out at '%s'"
 msgstr "“%s” đã được lấy ra tại “%s” rồi"
 
-#: branch.c:382
+#: branch.c:383
 #, 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"
@@ -1175,7 +1175,7 @@ msgstr "“%s” không giống như tập tin v2 bundle (định dạng dump c
 msgid "unrecognized header: %s%s (%d)"
 msgstr "phần đầu không được thừa nhận: %s%s (%d)"
 
-#: bundle.c:88 sequencer.c:1879 sequencer.c:2337 builtin/commit.c:750
+#: bundle.c:88 sequencer.c:2081 sequencer.c:2558 builtin/commit.c:755
 #, c-format
 msgid "could not open '%s'"
 msgstr "không thể mở “%s”"
@@ -1217,7 +1217,7 @@ msgstr "rev-list đã chết"
 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"
 
-#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:296
+#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:303
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "đối số không được thừa nhận: %s"
@@ -1240,18 +1240,39 @@ msgstr "mục lục gói đã chết"
 msgid "invalid color value: %.*s"
 msgstr "giá trị màu không hợp lệ: %.*s"
 
-#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465
-#: builtin/am.c:1436 builtin/am.c:2072
+#: commit.c:43 sequencer.c:2364 builtin/am.c:421 builtin/am.c:465
+#: builtin/am.c:1436 builtin/am.c:2072 builtin/replace.c:376
+#: builtin/replace.c:448
 #, c-format
 msgid "could not parse %s"
 msgstr "không thể phân tích cú pháp %s"
 
-#: commit.c:43
+#: commit.c:45
 #, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s không phải là một lần chuyển giao!"
 
-#: commit.c:1506
+#: commit.c:182
+msgid ""
+"Support for <GIT_DIR>/info/grafts is deprecated\n"
+"and will be removed in a future Git version.\n"
+"\n"
+"Please use \"git replace --convert-graft-file\"\n"
+"to convert the grafts into replace refs.\n"
+"\n"
+"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"
+"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"
+"để chuyển đổi các graft thành các tham chiếu thay thế.\n"
+"\n"
+"Tắt lời nhắn này bằng cách chạy\n"
+"\"git config advice.graftFileDeprecated false\""
+
+#: commit.c:1540
 msgid ""
 "Warning: commit message did not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
@@ -1261,173 +1282,187 @@ msgstr ""
 "Bạn có lẽ muốn tu bổ nó sau khi sửa lời chú thích, hoặc là đặt biến\n"
 "cấu hình i18n.commitencoding thành bảng mã mà dự án của bạn muốn dùng.\n"
 
+#: commit-graph.c:669
+#, c-format
+msgid "the commit graph format cannot write %d commits"
+msgstr "định dạng đồ họa các lần chuyển giao không thể ghi %d lần chuyển giao"
+
+#: commit-graph.c:696
+msgid "too many commits to write graph"
+msgstr "có quá nhiều lần chuyển giao để ghi đồ thị"
+
+#: commit-graph.c:707 builtin/init-db.c:516 builtin/init-db.c:521
+#, c-format
+msgid "cannot mkdir %s"
+msgstr "không thể mkdir (tạo thư mục): %s"
+
 #: compat/obstack.c:405 compat/obstack.c:407
 msgid "memory exhausted"
 msgstr "hết bộ nhớ"
 
-#: config.c:186
+#: config.c:187
 msgid "relative config include conditionals must come from files"
 msgstr "các điều kiện bao gồm cấu hình liên quan phải đến từ các tập tin"
 
-#: config.c:720
+#: config.c:788
 #, c-format
 msgid "bad config line %d in blob %s"
 msgstr "tập tin cấu hình sai tại dòng %d trong blob %s"
 
-#: config.c:724
+#: config.c:792
 #, c-format
 msgid "bad config line %d in file %s"
 msgstr "cấu hình sai tại dòng %d trong tập tin %s"
 
-#: config.c:728
+#: config.c:796
 #, 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"
 
-#: config.c:732
+#: config.c:800
 #, c-format
 msgid "bad config line %d in submodule-blob %s"
 msgstr "cấu hình sai tại dòng %d trong blob-mô-đun-con %s"
 
-#: config.c:736
+#: config.c:804
 #, c-format
 msgid "bad config line %d in command line %s"
 msgstr "cấu hình sai tại dòng %d trong dòng lệnh %s"
 
-#: config.c:740
+#: config.c:808
 #, c-format
 msgid "bad config line %d in %s"
 msgstr "cấu hình sai tại dòng %d trong %s"
 
-#: config.c:868
+#: config.c:936
 msgid "out of range"
 msgstr "nằm ngoài phạm vi"
 
-#: config.c:868
+#: config.c:936
 msgid "invalid unit"
 msgstr "đơn vị không hợp lệ"
 
-#: config.c:874
+#: config.c:942
 #, 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"
 
-#: config.c:879
+#: config.c:947
 #, 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"
 
-#: config.c:882
+#: config.c:950
 #, 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"
 
-#: config.c:885
+#: config.c:953
 #, 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"
 
-#: config.c:888
+#: config.c:956
 #, 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"
 
-#: config.c:891
+#: config.c:959
 #, 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"
 
-#: config.c:894
+#: config.c:962
 #, 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"
 
-#: config.c:989
+#: config.c:1057
 #, 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”"
 
-#: config.c:998
+#: config.c:1066
 #, 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ệ"
 
-#: config.c:1094 config.c:1105
+#: config.c:1171 config.c:1182
 #, c-format
 msgid "bad zlib compression level %d"
 msgstr "mức nén zlib %d là sai"
 
-#: config.c:1225
+#: config.c:1307
 #, c-format
 msgid "invalid mode for object creation: %s"
 msgstr "chế độ không hợp lệ đối với việc tạo đối tượng: %s"
 
-#: config.c:1386
+#: config.c:1473
 #, c-format
 msgid "bad pack compression level %d"
 msgstr "mức nén gói %d không hợp lệ"
 
-#: config.c:1582
+#: config.c:1681
 msgid "unable to parse command-line config"
 msgstr "không thể phân tích cấu hình dòng lệnh"
 
-#: config.c:1914
+#: config.c:2013
 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"
 
-#: config.c:2101
+#: config.c:2200
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "%s không hợp lệ: “%s”"
 
-#: config.c:2144
+#: config.c:2243
 #, c-format
 msgid "unknown core.untrackedCache value '%s'; using 'keep' default value"
 msgstr ""
 "không hiểu giá trị core.untrackedCache “%s”; dùng giá trị mặc định “keep”"
 
-#: config.c:2170
+#: config.c:2269
 #, 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"
 
-#: config.c:2195
+#: config.c:2294
 #, 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"
 
-#: config.c:2197
+#: config.c:2296
 #, 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"
 
-#: config.c:2256
+#: config.c:2402
 #, c-format
 msgid "%s has multiple values"
 msgstr "%s có đa giá trị"
 
-#: config.c:2599 config.c:2816
+#: config.c:2766 config.c:3019
 #, c-format
 msgid "fstat on %s failed"
 msgstr "fstat trên %s gặp lỗi"
 
-#: config.c:2706
+#: config.c:2905
 #, c-format
 msgid "could not set '%s' to '%s'"
 msgstr "không thể đặt “%s” thành “%s”"
 
-#: config.c:2708 builtin/remote.c:776
+#: config.c:2907 builtin/remote.c:779
 #, c-format
 msgid "could not unset '%s'"
 msgstr "không thể thôi đặt “%s”"
 
-#: connect.c:52
+#: connect.c:61
 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"
 
-#: connect.c:54
+#: connect.c:63
 msgid ""
 "Could not read from remote repository.\n"
 "\n"
@@ -1439,7 +1474,7 @@ msgstr ""
 "Vui lòng chắc chắn là bạn có đủ thẩm quyền truy cập\n"
 "và kho chứa đã sẵn có."
 
-#: connected.c:66 builtin/fsck.c:198 builtin/prune.c:144
+#: connected.c:66 builtin/fsck.c:201 builtin/prune.c:145
 msgid "Checking connectivity"
 msgstr "Đang kiểm tra kết nối"
 
@@ -1455,12 +1490,12 @@ 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"
 
-#: convert.c:205
+#: convert.c:206
 #, c-format
 msgid "CRLF would be replaced by LF in %s."
 msgstr "CRLF nên được thay bằng LF trong %s."
 
-#: convert.c:207
+#: convert.c:208
 #, c-format
 msgid ""
 "CRLF will be replaced by LF in %s.\n"
@@ -1469,12 +1504,12 @@ 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."
 
-#: convert.c:215
+#: convert.c:216
 #, c-format
 msgid "LF would be replaced by CRLF in %s"
 msgstr "LF nên thay bằng CRLF trong %s"
 
-#: convert.c:217
+#: convert.c:218
 #, c-format
 msgid ""
 "LF will be replaced by CRLF in %s.\n"
@@ -1483,6 +1518,48 @@ 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."
 
+#: convert.c:279
+#, 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"
+
+#: convert.c:286
+#, 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ư là "
+"bảng mã cây làm việc."
+
+#: convert.c:304
+#, 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"
+
+#: convert.c:306
+#, 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 "
+"UTF-%sLE (còn phục thuộc vào thứ tự byte) như là bảng mã cây làm việc."
+
+#: convert.c:424
+#, 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”"
+
+#: convert.c:467
+#, 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"
+
+#: convert.c:1225
+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ệ "
+
 #: date.c:116
 msgid "in the future"
 msgstr "ở thời tương lai"
@@ -1588,24 +1665,24 @@ msgstr ""
 "Tìm thấy các lỗi trong biến cấu hình “diff.dirstat”:\n"
 "%s"
 
-#: diff.c:3822
+#: diff.c:3823
 #, 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"
 
-#: diff.c:4146
+#: diff.c:4153
 msgid "--name-only, --name-status, --check and -s are mutually exclusive"
 msgstr "--name-only, --name-status, --check và -s loại từ lẫn nhau"
 
-#: diff.c:4149
+#: diff.c:4156
 msgid "-G, -S and --find-object are mutually exclusive"
 msgstr "Các tùy chọn -G, -S, và --find-object loại từ lẫn nhau"
 
-#: diff.c:4237
+#: diff.c:4244
 msgid "--follow requires exactly one pathspec"
 msgstr "--follow cần chính xác một đặc tả đường dẫn"
 
-#: diff.c:4403
+#: diff.c:4410
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -1614,22 +1691,22 @@ msgstr ""
 "Gặp lỗi khi phân tích đối số tùy chọn --dirstat/-X:\n"
 "%s"
 
-#: diff.c:4417
+#: diff.c:4424
 #, 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”"
 
-#: diff.c:5493
+#: diff.c:5500
 msgid "inexact rename detection was skipped due to too many files."
 msgstr ""
 "nhận thấy đổi tên không chính xác đã bị bỏ qua bởi có quá nhiều tập tin."
 
-#: diff.c:5496
+#: diff.c:5503
 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."
 
-#: diff.c:5499
+#: diff.c:5506
 #, c-format
 msgid ""
 "you may want to set your %s variable to at least %d and retry the command."
@@ -1637,25 +1714,25 @@ 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."
 
-#: dir.c:1866
+#: dir.c:1867
 #, c-format
 msgid "could not open directory '%s'"
 msgstr "không thể mở thư mục “%s”"
 
-#: dir.c:2108
+#: dir.c:2109
 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"
 
-#: dir.c:2232
+#: dir.c:2233
 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."
 
-#: dir.c:3024 dir.c:3029
+#: dir.c:3075 dir.c:3080
 #, c-format
 msgid "could not create directories for %s"
 msgstr "không thể tạo thư mục cho %s"
 
-#: dir.c:3054
+#: dir.c:3109
 #, c-format
 msgid "could not migrate git directory from '%s' to '%s'"
 msgstr "không thể di cư thư mục git từ “%s” sang “%s”"
@@ -1678,202 +1755,206 @@ msgstr "không thể lấy thống kê tập tin “%s”"
 msgid "Remote with no URL"
 msgstr "Máy chủ không có địa chỉ URL"
 
-#: fetch-pack.c:253
+#: fetch-pack.c:254
 msgid "git fetch-pack: expected shallow list"
 msgstr "git fetch-pack: cần danh sách shallow"
 
-#: fetch-pack.c:265
+#: fetch-pack.c:266
 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"
 
-#: fetch-pack.c:284 builtin/archive.c:63
+#: fetch-pack.c:285 builtin/archive.c:63
 #, c-format
 msgid "remote error: %s"
 msgstr "lỗi máy chủ: %s"
 
-#: fetch-pack.c:285
+#: fetch-pack.c:286
 #, 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”"
 
-#: fetch-pack.c:337
+#: fetch-pack.c:338
 msgid "--stateless-rpc requires multi_ack_detailed"
 msgstr "--stateless-rpc cần multi_ack_detailed"
 
-#: fetch-pack.c:428
+#: fetch-pack.c:429 fetch-pack.c:1310
 #, c-format
 msgid "invalid shallow line: %s"
 msgstr "dòng shallow không hợp lệ: %s"
 
-#: fetch-pack.c:434
+#: fetch-pack.c:435 fetch-pack.c:1316
 #, c-format
 msgid "invalid unshallow line: %s"
 msgstr "dòng unshallow không hợp lệ: %s"
 
-#: fetch-pack.c:436
+#: fetch-pack.c:437 fetch-pack.c:1318
 #, c-format
 msgid "object not found: %s"
 msgstr "Không tìm thấy đối tượng: %s"
 
-#: fetch-pack.c:439
+#: fetch-pack.c:440 fetch-pack.c:1321
 #, c-format
 msgid "error in object: %s"
 msgstr "lỗi trong đối tượng: %s"
 
-#: fetch-pack.c:441
+#: fetch-pack.c:442 fetch-pack.c:1323
 #, c-format
 msgid "no shallow found: %s"
 msgstr "không tìm shallow nào: %s"
 
-#: fetch-pack.c:444
+#: fetch-pack.c:445 fetch-pack.c:1326
 #, c-format
 msgid "expected shallow/unshallow, got %s"
 msgstr "cần shallow/unshallow, nhưng lại nhận được %s"
 
-#: fetch-pack.c:485
+#: fetch-pack.c:486
 #, c-format
 msgid "got %s %d %s"
 msgstr "nhận %s %d - %s"
 
-#: fetch-pack.c:499
+#: fetch-pack.c:500
 #, c-format
 msgid "invalid commit %s"
 msgstr "lần chuyển giao %s không hợp lệ"
 
-#: fetch-pack.c:532
+#: fetch-pack.c:533
 msgid "giving up"
 msgstr "chịu thua"
 
-#: fetch-pack.c:542 progress.c:229
+#: fetch-pack.c:543 progress.c:229
 msgid "done"
 msgstr "xong"
 
-#: fetch-pack.c:554
+#: fetch-pack.c:555
 #, c-format
 msgid "got %s (%d) %s"
 msgstr "nhận %s (%d) %s"
 
-#: fetch-pack.c:600
+#: fetch-pack.c:601
 #, c-format
 msgid "Marking %s as complete"
 msgstr "Đánh dấu %s là đã hoàn thành"
 
-#: fetch-pack.c:788
+#: fetch-pack.c:828
 #, c-format
 msgid "already have %s (%s)"
 msgstr "đã sẵn có %s (%s)"
 
-#: fetch-pack.c:829
+#: fetch-pack.c:869
 msgid "fetch-pack: unable to fork off sideband demultiplexer"
 msgstr "fetch-pack: không thể rẽ nhánh sideband demultiplexer"
 
-#: fetch-pack.c:837
+#: fetch-pack.c:877
 msgid "protocol error: bad pack header"
 msgstr "lỗi giao thức: phần đầu gói bị sai"
 
-#: fetch-pack.c:895
+#: fetch-pack.c:944
 #, c-format
 msgid "fetch-pack: unable to fork off %s"
 msgstr "fetch-pack: không thể rẽ nhánh %s"
 
-#: fetch-pack.c:911
+#: fetch-pack.c:960
 #, c-format
 msgid "%s failed"
 msgstr "%s gặp lỗi"
 
-#: fetch-pack.c:913
+#: fetch-pack.c:962
 msgid "error in sideband demultiplexer"
 msgstr "có lỗi trong sideband demultiplexer"
 
-#: fetch-pack.c:940
+#: fetch-pack.c:989
 msgid "Server does not support shallow clients"
 msgstr "Máy chủ không hỗ trợ máy khách shallow"
 
-#: fetch-pack.c:944
+#: fetch-pack.c:993
 msgid "Server supports multi_ack_detailed"
 msgstr "Máy chủ hỗ trợ multi_ack_detailed"
 
-#: fetch-pack.c:947
+#: fetch-pack.c:996
 msgid "Server supports no-done"
 msgstr "Máy chủ hỗ trợ no-done"
 
-#: fetch-pack.c:953
+#: fetch-pack.c:1002
 msgid "Server supports multi_ack"
 msgstr "Máy chủ hỗ trợ multi_ack"
 
-#: fetch-pack.c:957
+#: fetch-pack.c:1006
 msgid "Server supports side-band-64k"
 msgstr "Máy chủ hỗ trợ side-band-64k"
 
-#: fetch-pack.c:961
+#: fetch-pack.c:1010
 msgid "Server supports side-band"
 msgstr "Máy chủ hỗ trợ side-band"
 
-#: fetch-pack.c:965
+#: fetch-pack.c:1014
 msgid "Server supports allow-tip-sha1-in-want"
 msgstr "Máy chủ hỗ trợ allow-tip-sha1-in-want"
 
-#: fetch-pack.c:969
+#: fetch-pack.c:1018
 msgid "Server supports allow-reachable-sha1-in-want"
 msgstr "Máy chủ hỗ trợ allow-reachable-sha1-in-want"
 
-#: fetch-pack.c:979
+#: fetch-pack.c:1028
 msgid "Server supports ofs-delta"
 msgstr "Máy chủ hỗ trợ ofs-delta"
 
-#: fetch-pack.c:985
+#: fetch-pack.c:1034 fetch-pack.c:1204
 msgid "Server supports filter"
 msgstr "Máy chủ hỗ trợ bộ lọc"
 
-#: fetch-pack.c:993
+#: fetch-pack.c:1042
 #, c-format
 msgid "Server version is %.*s"
 msgstr "Phiên bản máy chủ là %.*s"
 
-#: fetch-pack.c:999
+#: fetch-pack.c:1048
 msgid "Server does not support --shallow-since"
 msgstr "Máy chủ không hỗ trợ --shallow-since"
 
-#: fetch-pack.c:1003
+#: fetch-pack.c:1052
 msgid "Server does not support --shallow-exclude"
 msgstr "Máy chủ không hỗ trợ --shallow-exclude"
 
-#: fetch-pack.c:1005
+#: fetch-pack.c:1054
 msgid "Server does not support --deepen"
 msgstr "Máy chủ không hỗ trợ --deepen"
 
-#: fetch-pack.c:1016
+#: fetch-pack.c:1065
 msgid "no common commits"
 msgstr "không có lần chuyển giao chung nào"
 
-#: fetch-pack.c:1028
+#: fetch-pack.c:1077 fetch-pack.c:1414
 msgid "git fetch-pack: fetch failed."
 msgstr "git fetch-pack: fetch gặp lỗi."
 
-#: fetch-pack.c:1190
+#: fetch-pack.c:1199
+msgid "Server does not support shallow requests"
+msgstr "Máy chủ không hỗ trợ yêu cầu shallow"
+
+#: fetch-pack.c:1584
 msgid "no matching remote head"
 msgstr "không khớp phần đầu máy chủ"
 
-#: fetch-pack.c:1212
+#: fetch-pack.c:1610
 #, c-format
 msgid "no such remote ref %s"
 msgstr "Không có máy chủ tham chiếu nào như %s"
 
-#: fetch-pack.c:1215
+#: fetch-pack.c:1613
 #, 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"
 
-#: gpg-interface.c:181
+#: gpg-interface.c:185
 msgid "gpg failed to sign the data"
 msgstr "gpg gặp lỗi khi ký dữ liệu"
 
-#: gpg-interface.c:211
+#: gpg-interface.c:210
 msgid "could not create temporary file"
 msgstr "không thể tạo tập tin tạm thời"
 
-#: gpg-interface.c:214
+#: gpg-interface.c:213
 #, c-format
 msgid "failed writing detached signature to '%s'"
 msgstr "gặp lỗi khi ghi chữ ký đính kèm vào “%s”"
@@ -1883,36 +1964,97 @@ msgstr "gặp lỗi khi ghi chữ ký đính kèm vào “%s”"
 msgid "ignore invalid color '%.*s' in log.graphColors"
 msgstr "bỏ qua màu không hợp lệ “%.*s” trong log.graphColors"
 
-#: grep.c:2022
+#: grep.c:2020
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "“%s”: không thể đọc %s"
 
-#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81
+#: grep.c:2037 setup.c:164 builtin/clone.c:409 builtin/diff.c:81
 #: builtin/rm.c:134
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "gặp lỗi khi lấy thống kê về “%s”"
 
-#: grep.c:2050
+#: grep.c:2048
 #, c-format
 msgid "'%s': short read"
 msgstr "“%s”: đọc ngắn"
 
-#: help.c:179
+#: help.c:23
+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)"
+
+#: help.c:24
+msgid "work on the current change (see also: git help everyday)"
+msgstr "làm việc trên thay đổi hiện tại (xem thêm: git help everyday)"
+
+#: help.c:25
+msgid "examine the history and state (see also: git help revisions)"
+msgstr "xem xét lịch sử tình trạng (xem thêm: git help revisions)"
+
+#: help.c:26
+msgid "grow, mark and tweak your common history"
+msgstr "thêm, ghi dấu và chỉnh lịch sử chung của bạn"
+
+#: help.c:27
+msgid "collaborate (see also: git help workflows)"
+msgstr "làm việc nhóm (xem thêm: git help workflows)"
+
+#: help.c:31
+msgid "Main Porcelain Commands"
+msgstr "Các lệnh Porcelain chính"
+
+#: help.c:32
+msgid "Ancillary Commands / Manipulators"
+msgstr "Lệnh/thao tác thứ cấp"
+
+#: help.c:33
+msgid "Ancillary Commands / Interrogators"
+msgstr "Lệnh/bộ hỏi thứ cấp"
+
+#: help.c:34
+msgid "Interacting with Others"
+msgstr "Tương tác với những cái khác"
+
+#: help.c:35
+msgid "Low-level Commands / Manipulators"
+msgstr "Lệnh/thao tác ở mức thấp"
+
+#: help.c:36
+msgid "Low-level Commands / Interrogators"
+msgstr "Lệnh/bộ hỏi ở mức thấp"
+
+#: help.c:37
+msgid "Low-level Commands / Synching Repositories"
+msgstr "Lệnh/Đồng bộ kho ở mức thấp"
+
+#: help.c:38
+msgid "Low-level Commands / Internal Helpers"
+msgstr "Lệnh/Hỗ trợ nội tại ở mức thấp"
+
+#: help.c:293
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "các lệnh git sẵn có trong thư mục “%s”:"
 
-#: help.c:186
+#: help.c:300
 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"
 
-#: help.c:217
+#: help.c:309
 msgid "These are common Git commands used in various situations:"
 msgstr "Có các lệnh Git chung được sử dụng trong các tình huống khác nhau:"
 
-#: help.c:281
+#: help.c:358 git.c:90
+#, c-format
+msgid "unsupported command listing type '%s'"
+msgstr "không hỗ trợ liệt kê lệnh kiểu “%s”"
+
+#: help.c:405
+msgid "The common Git guides are:"
+msgstr "Các chỉ dẫn chung về Git là:"
+
+#: help.c:467
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -1921,31 +2063,31 @@ msgstr ""
 "“%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?"
 
-#: help.c:336
+#: help.c:526
 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ả."
 
-#: help.c:358
+#: help.c:548
 #, 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."
 
-#: help.c:363
+#: help.c:553
 #, c-format
 msgid "Continuing under the assumption that you meant '%s'."
 msgstr "Tiếp tục và coi rằng ý bạn là “%s”."
 
-#: help.c:368
+#: help.c:558
 #, 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”."
 
-#: help.c:376
+#: help.c:566
 #, 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”."
 
-#: help.c:380
+#: help.c:570
 msgid ""
 "\n"
 "The most similar command is"
@@ -1956,16 +2098,16 @@ msgstr[0] ""
 "\n"
 "Những lệnh giống nhất là"
 
-#: help.c:395
+#: help.c:585
 msgid "git version [<options>]"
 msgstr "git version [<các-tùy-chọn>]"
 
-#: help.c:462
+#: help.c:652
 #, c-format
 msgid "%s: %s - %s"
 msgstr "%s: %s - %s"
 
-#: help.c:466
+#: help.c:656
 msgid ""
 "\n"
 "Did you mean this?"
@@ -2030,7 +2172,7 @@ msgstr "không cho phép tên định danh là rỗng (cho <%s>)"
 msgid "name consists only of disallowed characters: %s"
 msgstr "tên chỉ được phép bao gồm các ký tự sau: %s"
 
-#: ident.c:416 builtin/commit.c:582
+#: ident.c:416 builtin/commit.c:587
 #, c-format
 msgid "invalid date format: %s"
 msgstr "ngày tháng không hợp lệ: %s"
@@ -2067,82 +2209,166 @@ msgstr ""
 msgid "Unable to create '%s.lock': %s"
 msgstr "Không thể tạo “%s.lock”: %s"
 
-#: merge.c:74
+#: merge.c:71
 msgid "failed to read the cache"
 msgstr "gặp lỗi khi đọc bộ nhớ đệm"
 
-#: merge.c:134 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
-#: builtin/checkout.c:599 builtin/clone.c:759
+#: merge.c:136 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
+#: builtin/checkout.c:606 builtin/clone.c:761
 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"
 
-#: merge-recursive.c:235
+#: merge-recursive.c:298
 msgid "(bad commit)\n"
 msgstr "(commit sai)\n"
 
-#: merge-recursive.c:257 merge-recursive.c:265
+#: merge-recursive.c:320
+#, c-format
+msgid "add_cacheinfo failed for path '%s'; merge aborting."
+msgstr "addinfo_cache gặp lỗi đối với đường dẫn “%s”; việc hòa trộn bị bãi bỏ."
+
+#: merge-recursive.c:328
 #, c-format
-msgid "addinfo_cache failed for path '%s'"
-msgstr "addinfo_cache gặp lỗi đối với đường dẫn “%s”"
+msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
+msgstr ""
+"addinfo_cache 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ỏ."
 
-#: merge-recursive.c:329
+#: merge-recursive.c:410
 msgid "error building trees"
 msgstr "gặp lỗi khi xây dựng cây"
 
-#: merge-recursive.c:771
+#: merge-recursive.c:881
 #, c-format
 msgid "failed to create path '%s'%s"
 msgstr "gặp lỗi khi tạo đường dẫn “%s”%s"
 
-#: merge-recursive.c:782
+#: merge-recursive.c:892
 #, 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"
 
-#: merge-recursive.c:796 merge-recursive.c:815
+#: merge-recursive.c:906 merge-recursive.c:925
 msgid ": perhaps a D/F conflict?"
 msgstr ": có lẽ là một xung đột D/F?"
 
-#: merge-recursive.c:805
+#: merge-recursive.c:915
 #, 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”"
 
-#: merge-recursive.c:847 builtin/cat-file.c:37
+#: merge-recursive.c:957 builtin/cat-file.c:37
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr "không thể đọc đối tượng %s “%s”"
 
-#: merge-recursive.c:849
+#: merge-recursive.c:959
 #, c-format
 msgid "blob expected for %s '%s'"
-msgstr "đối tượng blob được mong đợi cho %s “%s”"
+msgstr "mong đợi đối tượng blob cho %s “%s”"
 
-#: merge-recursive.c:873
+#: merge-recursive.c:983
 #, c-format
 msgid "failed to open '%s': %s"
 msgstr "gặp lỗi khi mở “%s”: %s"
 
-#: merge-recursive.c:884
+#: merge-recursive.c:994
 #, 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"
 
-#: merge-recursive.c:889
+#: merge-recursive.c:999
 #, 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”"
 
-#: merge-recursive.c:1029
+#: merge-recursive.c:1186
+#, 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)"
+
+#: merge-recursive.c:1193
+#, 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)"
+
+#: merge-recursive.c:1200
+#, 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-"
+"trộn)"
+
+#: merge-recursive.c:1208 merge-recursive.c:1220
+#, 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:"
+
+#: merge-recursive.c:1211 merge-recursive.c:1223
+#, c-format
+msgid "Fast-forwarding submodule %s"
+msgstr "Chuyển-tiếp-nhanh mô-đun-con “%s”"
+
+#: merge-recursive.c:1245
+#, 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 "
+"theo sau hòa trộn)"
+
+#: merge-recursive.c:1249
+#, 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)"
+
+#: merge-recursive.c:1250
+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"
+
+#: merge-recursive.c:1253
+#, 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"
+
+#: merge-recursive.c:1262
+#, 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)"
+
+#: merge-recursive.c:1321
 msgid "Failed to execute internal merge"
 msgstr "Gặp lỗi khi thực hiện trộn nội bộ"
 
-#: merge-recursive.c:1034
+#: merge-recursive.c:1326
 #, c-format
 msgid "Unable to add %s to database"
 msgstr "Không thể thêm %s vào cơ sở dữ liệu"
 
-#: merge-recursive.c:1146
+#: merge-recursive.c:1358
+#, c-format
+msgid "Auto-merging %s"
+msgstr "Tự-động-hòa-trộn %s"
+
+#: merge-recursive.c:1423
+#, 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 "
+"%s."
+
+#: merge-recursive.c:1475
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2151,7 +2377,7 @@ msgstr ""
 "XUNG ĐỘT (%s/xóa): %s bị xóa trong %s và %s trong %s. Phiên bản %s của %s "
 "còn lại trong cây (tree)."
 
-#: merge-recursive.c:1151
+#: merge-recursive.c:1480
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2160,7 +2386,7 @@ msgstr ""
 "XUNG ĐỘT (%s/xóa): %s bị xóa trong %s và %s đến %s trong %s. Phiên bản %s "
 "của %s còn lại trong cây (tree)."
 
-#: merge-recursive.c:1158
+#: merge-recursive.c:1487
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2169,7 +2395,7 @@ msgstr ""
 "XUNG ĐỘT (%s/xóa): %s bị xóa trong %s và %s trong %s. Phiên bản %s của %s "
 "còn lại trong cây (tree) tại %s."
 
-#: merge-recursive.c:1163
+#: merge-recursive.c:1492
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2178,20 +2404,33 @@ msgstr ""
 "XUNG ĐỘT (%s/xóa): %s bị xóa trong %s và %s đến %s trong %s. Phiên bản %s "
 "của %s còn lại trong cây (tree) tại %s."
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "rename"
 msgstr "đổi tên"
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "renamed"
 msgstr "đã đổi tên"
 
-#: merge-recursive.c:1254
+#: merge-recursive.c:1580 merge-recursive.c:1736 merge-recursive.c:2368
+#: merge-recursive.c:3086
+#, 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”"
+
+#: merge-recursive.c:1594
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr "%s là một thư mục trong %s thay vào đó thêm vào như là %s"
 
-#: merge-recursive.c:1279
+#: merge-recursive.c:1599
+#, 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 "
+"thành %s"
+
+#: merge-recursive.c:1625
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
@@ -2200,141 +2439,190 @@ 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"
 
-#: merge-recursive.c:1284
+#: merge-recursive.c:1630
 msgid " (left unresolved)"
 msgstr " (cần giải quyết)"
 
-#: merge-recursive.c:1346
+#: merge-recursive.c:1694
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
 "XUNG ĐỘT (đổi-tên/đổi-tên): Đổi tên %s->%s trong %s. Đổi tên %s->%s trong %s"
 
-#: merge-recursive.c:1379
+#: merge-recursive.c:1733
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr "Đang đổi tên %s thành %s thay vì %s thành %s"
 
-#: merge-recursive.c:1582
+#: merge-recursive.c:1745
+#, 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 "
+"đường."
+
+#: merge-recursive.c:1951
+#, c-format
+msgid ""
+"CONFLICT (directory rename split): Unclear where to place %s because "
+"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."
+
+#: merge-recursive.c:1983
+#, c-format
+msgid ""
+"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."
+
+#: merge-recursive.c:1993
+#, 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."
+
+#: merge-recursive.c:2085
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-"
+">%s in %s"
+msgstr ""
+"XUNG ĐỘT (đổi-tên/đổi-tên): Đổi tên thư mục %s->%s trong %s. Đổi tên thư mục "
+"%s->%s trong %s"
+
+#: merge-recursive.c:2330
+#, 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."
+
+#: merge-recursive.c:2736
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
 msgstr ""
 "XUNG ĐỘT (đổi-tên/thêm): Đổi tên %s->%s trong %s. %s được thêm vào trong %s"
 
-#: merge-recursive.c:1597
+#: merge-recursive.c:2751
 #, c-format
 msgid "Adding merged %s"
 msgstr "Thêm hòa trộn %s"
 
-#: merge-recursive.c:1604 merge-recursive.c:1834
+#: merge-recursive.c:2758 merge-recursive.c:3089
 #, c-format
 msgid "Adding as %s instead"
 msgstr "Thay vào đó thêm vào %s"
 
-#: merge-recursive.c:1661
+#: merge-recursive.c:2914
 #, c-format
 msgid "cannot read object %s"
 msgstr "không thể đọc đối tượng %s"
 
-#: merge-recursive.c:1664
+#: merge-recursive.c:2917
 #, c-format
 msgid "object %s is not a blob"
 msgstr "đối tượng %s không phải là một blob"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modify"
 msgstr "sửa đổi"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modified"
 msgstr "đã sửa"
 
-#: merge-recursive.c:1743
+#: merge-recursive.c:2997
 msgid "content"
 msgstr "nội dung"
 
-#: merge-recursive.c:1750
+#: merge-recursive.c:3004
 msgid "add/add"
 msgstr "thêm/thêm"
 
-#: merge-recursive.c:1786
+#: merge-recursive.c:3046
 #, c-format
 msgid "Skipped %s (merged same as existing)"
 msgstr "Đã bỏ qua %s (đã có sẵn lần hòa trộn này)"
 
-#: merge-recursive.c:1800
-#, c-format
-msgid "Auto-merging %s"
-msgstr "Tự-động-hòa-trộn %s"
-
-#: merge-recursive.c:1804 git-submodule.sh:879
+#: merge-recursive.c:3055 git-submodule.sh:895
 msgid "submodule"
 msgstr "mô-đun-con"
 
-#: merge-recursive.c:1805
+#: merge-recursive.c:3056
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
 msgstr "XUNG ĐỘT (%s): Xung đột hòa trộn trong %s"
 
-#: merge-recursive.c:1899
+#: merge-recursive.c:3178
 #, c-format
 msgid "Removing %s"
 msgstr "Đang xóa %s"
 
-#: merge-recursive.c:1925
+#: merge-recursive.c:3204
 msgid "file/directory"
 msgstr "tập-tin/thư-mục"
 
-#: merge-recursive.c:1931
+#: merge-recursive.c:3210
 msgid "directory/file"
 msgstr "thư-mục/tập-tin"
 
-#: merge-recursive.c:1938
+#: merge-recursive.c:3217
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
 msgstr ""
 "XUNG ĐỘT (%s): Ở đây không có thư mục nào có tên %s trong %s. Thêm %s như là "
 "%s"
 
-#: merge-recursive.c:1947
+#: merge-recursive.c:3226
 #, c-format
 msgid "Adding %s"
 msgstr "Thêm \"%s\""
 
-#: merge-recursive.c:1987
+#: merge-recursive.c:3267
 #, c-format
 msgid "Dirty index: cannot merge (dirty: %s)"
 msgstr "Bảng mục lục bẩn: không thể hòa trộn (bẩn: %s)"
 
-#: merge-recursive.c:1991
+#: merge-recursive.c:3271
 msgid "Already up to date!"
 msgstr "Đã cập nhật rồi!"
 
-#: merge-recursive.c:2000
+#: merge-recursive.c:3280
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr "hòa trộn các cây %s và %s gặp lỗi"
 
-#: merge-recursive.c:2097
+#: merge-recursive.c:3379
 msgid "Merging:"
 msgstr "Đang trộn:"
 
-#: merge-recursive.c:2110
+#: merge-recursive.c:3392
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] "tìm thấy %u tổ tiên chung:"
 
-#: merge-recursive.c:2149
+#: merge-recursive.c:3431
 msgid "merge returned no commit"
 msgstr "hòa trộn không trả về lần chuyển giao nào"
 
-#: merge-recursive.c:2212
+#: merge-recursive.c:3495
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr "Không thể phân tích đối tượng “%s”"
 
-#: merge-recursive.c:2228 builtin/merge.c:657 builtin/merge.c:816
+#: merge-recursive.c:3511 builtin/merge.c:659 builtin/merge.c:816
 msgid "Unable to write index."
 msgstr "Không thể ghi bảng mục lục"
 
@@ -2380,31 +2668,31 @@ msgstr "Từ chối ghi đè ghi chú trong %s (nằm ngoài refs/notes/)"
 msgid "Bad %s value: '%s'"
 msgstr "Giá trị %s sai: “%s”"
 
-#: object.c:239
+#: object.c:242
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "không thể phân tích đối tượng: “%s”"
 
-#: packfile.c:561
+#: packfile.c:563
 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 à?)"
 
-#: packfile.c:1694
+#: packfile.c:1742
 #, 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 à?)"
 
-#: packfile.c:1698
+#: packfile.c:1746
 #, 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 à?)"
 
-#: parse-options.c:619
+#: parse-options.c:621
 msgid "..."
 msgstr "…"
 
-#: parse-options.c:638
+#: parse-options.c:640
 #, c-format
 msgid "usage: %s"
 msgstr "cách dùng: %s"
@@ -2412,26 +2700,31 @@ msgstr "cách dùng: %s"
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation.
 #.
-#: parse-options.c:644
+#: parse-options.c:646
 #, c-format
 msgid "   or: %s"
 msgstr "     hoặc: %s"
 
-#: parse-options.c:647
+#: parse-options.c:649
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:686
+#: parse-options.c:688
 msgid "-NUM"
 msgstr "-SỐ"
 
-#: parse-options-cb.c:108
+#: parse-options-cb.c:44
+#, c-format
+msgid "malformed expiration date '%s'"
+msgstr "ngày tháng hết hạn dị hình “%s”"
+
+#: parse-options-cb.c:112
 #, c-format
 msgid "malformed object name '%s'"
 msgstr "tên đối tượng dị hình “%s”"
 
-#: path.c:891
+#: path.c:892
 #, c-format
 msgid "Could not make %s writable by group"
 msgstr "Không thể làm %s được ghi bởi nhóm"
@@ -2515,7 +2808,7 @@ msgstr "đặc tả đường dẫn “%s” vượt ra ngoài liên kết mềm
 msgid "unable to parse --pretty format"
 msgstr "không thể phân tích định dạng --pretty"
 
-#: read-cache.c:1473
+#: read-cache.c:1500
 #, c-format
 msgid ""
 "index.version set, but the value is invalid.\n"
@@ -2524,7 +2817,7 @@ msgstr ""
 "index.version được đặt, nhưng giá trị của nó lại không hợp lệ.\n"
 "Dùng phiên bản %i"
 
-#: read-cache.c:1483
+#: read-cache.c:1510
 #, c-format
 msgid ""
 "GIT_INDEX_VERSION set, but the value is invalid.\n"
@@ -2533,52 +2826,53 @@ msgstr ""
 "GIT_INDEX_VERSION được đặt, nhưng giá trị của nó lại không hợp lệ.\n"
 "Dùng phiên bản %i"
 
-#: read-cache.c:2375 sequencer.c:3248 wrapper.c:658 builtin/merge.c:1049
+#: read-cache.c:2404 sequencer.c:4338 wrapper.c:658 builtin/merge.c:1048
 #, c-format
 msgid "could not close '%s'"
 msgstr "không thể đóng “%s”"
 
-#: read-cache.c:2448 sequencer.c:1900 sequencer.c:2627
+#: read-cache.c:2477 sequencer.c:2102 sequencer.c:3234
 #, c-format
 msgid "could not stat '%s'"
 msgstr "không thể lấy thông tin thống kê về “%s”"
 
-#: read-cache.c:2461
+#: read-cache.c:2490
 #, c-format
 msgid "unable to open git dir: %s"
 msgstr "không thể mở thư mục git: %s"
 
-#: read-cache.c:2473
+#: read-cache.c:2502
 #, c-format
 msgid "unable to unlink: %s"
 msgstr "không thể bỏ liên kết (unlink): “%s”"
 
-#: refs.c:706
+#: refs.c:732 sequencer.c:4334 sequencer.c:4393 wrapper.c:225 wrapper.c:395
+#: builtin/am.c:779
 #, c-format
-msgid "Could not open '%s' for writing"
-msgstr "Không thể mở “%s” để ghi"
+msgid "could not open '%s' for writing"
+msgstr "không thể mở “%s” để ghi"
 
-#: refs.c:1850
+#: refs.c:1880
 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"
 
-#: refs/files-backend.c:1189
+#: refs/files-backend.c:1191
 #, c-format
 msgid "could not remove reference %s"
 msgstr "không thể gỡ bỏ tham chiếu: %s"
 
-#: refs/files-backend.c:1203 refs/packed-backend.c:1528
-#: refs/packed-backend.c:1538
+#: refs/files-backend.c:1205 refs/packed-backend.c:1531
+#: refs/packed-backend.c:1541
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "không thể xóa bỏ tham chiếu %s: %s"
 
-#: refs/files-backend.c:1206 refs/packed-backend.c:1541
+#: refs/files-backend.c:1208 refs/packed-backend.c:1544
 #, c-format
 msgid "could not delete references: %s"
 msgstr "không thể xóa bỏ tham chiếu: %s"
 
-#: ref-filter.c:35 wt-status.c:1842
+#: ref-filter.c:35 wt-status.c:1850
 msgid "gone"
 msgstr "đã ra đi"
 
@@ -2597,157 +2891,162 @@ msgstr "đằng sau %d"
 msgid "ahead %d, behind %d"
 msgstr "trước %d, sau %d"
 
-#: ref-filter.c:107
+#: ref-filter.c:121
 #, c-format
 msgid "expected format: %%(color:<color>)"
 msgstr "cần định dạng: %%(color:<color>)"
 
-#: ref-filter.c:109
+#: ref-filter.c:123
 #, c-format
 msgid "unrecognized color: %%(color:%s)"
 msgstr "không nhận ra màu: %%(màu:%s)"
 
-#: ref-filter.c:129
+#: ref-filter.c:145
 #, c-format
 msgid "Integer value expected refname:lstrip=%s"
 msgstr "Giá trị nguyên cần tên tham chiếu:lstrip=%s"
 
-#: ref-filter.c:133
+#: ref-filter.c:149
 #, c-format
 msgid "Integer value expected refname:rstrip=%s"
 msgstr "Giá trị nguyên cần tên tham chiếu:rstrip=%s"
 
-#: ref-filter.c:135
+#: ref-filter.c:151
 #, c-format
 msgid "unrecognized %%(%s) argument: %s"
 msgstr "đối số không được thừa nhận %%(%s): %s"
 
-#: ref-filter.c:184
+#: ref-filter.c:206
 #, c-format
 msgid "%%(body) does not take arguments"
 msgstr "%%(body) không nhận các đối số"
 
-#: ref-filter.c:191
+#: ref-filter.c:215
 #, c-format
 msgid "%%(subject) does not take arguments"
 msgstr "%%(subject) không nhận các đối số"
 
-#: ref-filter.c:209
+#: ref-filter.c:235
 #, c-format
 msgid "unknown %%(trailers) argument: %s"
 msgstr "không hiểu tham số %%(trailers): %s"
 
-#: ref-filter.c:232
+#: ref-filter.c:264
 #, c-format
 msgid "positive value expected contents:lines=%s"
 msgstr "cần nội dung mang giá trị dương:lines=%s"
 
-#: ref-filter.c:234
+#: ref-filter.c:266
 #, c-format
 msgid "unrecognized %%(contents) argument: %s"
 msgstr "đối số không được thừa nhận %%(contents): %s"
 
-#: ref-filter.c:247
+#: ref-filter.c:281
 #, c-format
 msgid "positive value expected objectname:short=%s"
 msgstr "cần nội dung mang giá trị dương:shot=%s"
 
-#: ref-filter.c:251
+#: ref-filter.c:285
 #, c-format
 msgid "unrecognized %%(objectname) argument: %s"
 msgstr "đối số không được thừa nhận %%(objectname): %s"
 
-#: ref-filter.c:278
+#: ref-filter.c:315
 #, c-format
 msgid "expected format: %%(align:<width>,<position>)"
 msgstr "cần định dạng: %%(align:<width>,<position>)"
 
-#: ref-filter.c:290
+#: ref-filter.c:327
 #, c-format
 msgid "unrecognized position:%s"
 msgstr "vị trí không được thừa nhận:%s"
 
-#: ref-filter.c:294
+#: ref-filter.c:334
 #, c-format
 msgid "unrecognized width:%s"
 msgstr "chiều rộng không được thừa nhận:%s"
 
-#: ref-filter.c:300
+#: ref-filter.c:343
 #, c-format
 msgid "unrecognized %%(align) argument: %s"
 msgstr "đối số không được thừa nhận %%(align): %s"
 
-#: ref-filter.c:304
+#: ref-filter.c:351
 #, 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)"
 
-#: ref-filter.c:319
+#: ref-filter.c:369
 #, c-format
 msgid "unrecognized %%(if) argument: %s"
 msgstr "đối số không được thừa nhận %%(if): %s"
 
-#: ref-filter.c:409
+#: ref-filter.c:464
 #, c-format
 msgid "malformed field name: %.*s"
 msgstr "tên trường dị hình: %.*s"
 
-#: ref-filter.c:435
+#: ref-filter.c:491
 #, c-format
 msgid "unknown field name: %.*s"
 msgstr "không hiểu tên trường: %.*s"
 
-#: ref-filter.c:547
+#: ref-filter.c:608
 #, c-format
 msgid "format: %%(if) atom used without a %%(then) atom"
 msgstr "định dạng: nguyên tử %%(if) được dùng mà không có nguyên tử %%(then)"
 
-#: ref-filter.c:607
+#: ref-filter.c:671
 #, c-format
 msgid "format: %%(then) atom used without an %%(if) atom"
 msgstr "định dạng: nguyên tử %%(then) được dùng mà không có nguyên tử %%(if)"
 
-#: ref-filter.c:609
+#: ref-filter.c:673
 #, 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"
 
-#: ref-filter.c:611
+#: ref-filter.c:675
 #, c-format
 msgid "format: %%(then) atom used after %%(else)"
 msgstr "định dạng: nguyên tử %%(then) được dùng sau %%(else)"
 
-#: ref-filter.c:637
+#: ref-filter.c:703
 #, c-format
 msgid "format: %%(else) atom used without an %%(if) atom"
 msgstr "định dạng: nguyên tử %%(else) được dùng mà không có nguyên tử %%(if)"
 
-#: ref-filter.c:639
+#: ref-filter.c:705
 #, c-format
 msgid "format: %%(else) atom used without a %%(then) atom"
 msgstr "định dạng: nguyên tử %%(else) được dùng mà không có nguyên tử %%(then)"
 
-#: ref-filter.c:641
+#: ref-filter.c:707
 #, 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"
 
-#: ref-filter.c:654
+#: ref-filter.c:722
 #, 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"
 
-#: ref-filter.c:709
+#: ref-filter.c:779
 #, c-format
 msgid "malformed format string %s"
 msgstr "chuỗi định dạng dị hình %s"
 
-#: ref-filter.c:1313
+#: ref-filter.c:1387
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(không nhánh, đang cải tổ %s)"
 
-#: ref-filter.c:1316
+#: ref-filter.c:1390
+#, c-format
+msgid "(no branch, rebasing detached HEAD %s)"
+msgstr "(không nhánh, đang cải tổ HEAD %s đã tách rời)"
+
+#: ref-filter.c:1393
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(không nhánh, di chuyển nửa bước được bắt đầu tại %s)"
@@ -2755,7 +3054,7 @@ msgstr "(không nhánh, di chuyển nửa bước được bắt đầu tại %s
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached at " in wt-status.c
 #.
-#: ref-filter.c:1324
+#: ref-filter.c:1401
 #, c-format
 msgid "(HEAD detached at %s)"
 msgstr "(HEAD được tách rời tại %s)"
@@ -2763,148 +3062,148 @@ msgstr "(HEAD được tách rời tại %s)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached from " in wt-status.c
 #.
-#: ref-filter.c:1331
+#: ref-filter.c:1408
 #, c-format
 msgid "(HEAD detached from %s)"
 msgstr "(HEAD được tách rời từ %s)"
 
-#: ref-filter.c:1335
+#: ref-filter.c:1412
 msgid "(no branch)"
 msgstr "(không nhánh)"
 
-#: ref-filter.c:1364
+#: ref-filter.c:1442
 #, c-format
 msgid "missing object %s for %s"
 msgstr "thiếu đối tượng %s cho %s"
 
-#: ref-filter.c:1367
+#: ref-filter.c:1445
 #, c-format
 msgid "parse_object_buffer failed on %s for %s"
 msgstr "parse_object_buffer gặp lỗi trên %s cho %s"
 
-#: ref-filter.c:1819
+#: ref-filter.c:1902
 #, c-format
 msgid "malformed object at '%s'"
 msgstr "đối tượng dị hình tại “%s”"
 
-#: ref-filter.c:1886
+#: ref-filter.c:1984
 #, c-format
 msgid "ignoring ref with broken name %s"
 msgstr "đang lờ đi tham chiếu với tên hỏng %s"
 
-#: ref-filter.c:1891
+#: ref-filter.c:1989
 #, c-format
 msgid "ignoring broken ref %s"
 msgstr "đang lờ đi tham chiếu hỏng %s"
 
-#: ref-filter.c:2152
+#: ref-filter.c:2261
 #, c-format
 msgid "format: %%(end) atom missing"
 msgstr "định dạng: thiếu nguyên tử %%(end)"
 
-#: ref-filter.c:2246
+#: ref-filter.c:2365
 #, c-format
 msgid "malformed object name %s"
 msgstr "tên đối tượng dị hình %s"
 
-#: remote.c:795
+#: remote.c:605
 #, c-format
 msgid "Cannot fetch both %s and %s to %s"
 msgstr "Không thể lấy về cả %s và %s cho %s"
 
-#: remote.c:799
+#: remote.c:609
 #, c-format
 msgid "%s usually tracks %s, not %s"
 msgstr "%s thường theo dõi %s, không phải %s"
 
-#: remote.c:803
+#: remote.c:613
 #, c-format
 msgid "%s tracks both %s and %s"
 msgstr "%s theo dõi cả %s và %s"
 
-#: remote.c:811
+#: remote.c:621
 msgid "Internal error"
 msgstr "Lỗi nội bộ"
 
-#: remote.c:1726 remote.c:1828
+#: remote.c:1534 remote.c:1635
 msgid "HEAD does not point to a branch"
 msgstr "HEAD không chỉ đến một nhánh nào cả"
 
-#: remote.c:1735
+#: remote.c:1543
 #, c-format
 msgid "no such branch: '%s'"
 msgstr "không có nhánh nào như thế: “%s”"
 
-#: remote.c:1738
+#: remote.c:1546
 #, 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”"
 
-#: remote.c:1744
+#: remote.c:1552
 #, 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ủ"
 
-#: remote.c:1759
+#: remote.c:1567
 #, 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ộ"
 
-#: remote.c:1771
+#: remote.c:1579
 #, c-format
 msgid "branch '%s' has no remote for pushing"
 msgstr "nhánh “%s” không có máy chủ để đẩy lên"
 
-#: remote.c:1782
+#: remote.c:1589
 #, c-format
 msgid "push refspecs for '%s' do not include '%s'"
 msgstr "đẩy refspecs cho “%s” không bao gồm “%s”"
 
-#: remote.c:1795
+#: remote.c:1602
 msgid "push has no destination (push.default is 'nothing')"
 msgstr "đẩy lên mà không có đích (push.default là “nothing”)"
 
-#: remote.c:1817
+#: remote.c:1624
 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"
 
-#: remote.c:2132
+#: remote.c:1939
 #, 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"
 
-#: remote.c:2136
+#: remote.c:1943
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
 msgstr "   (dùng \" git branch --unset-upstream\" để sửa)\n"
 
-#: remote.c:2139
+#: remote.c:1946
 #, 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"
 
-#: remote.c:2143
+#: remote.c:1950
 #, 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"
 
-#: remote.c:2146
+#: remote.c:1953
 #, c-format
 msgid "  (use \"%s\" for details)\n"
 msgstr "  (dùng \"%s\" để biết thêm chi tiết)\n"
 
-#: remote.c:2150
+#: remote.c:1957
 #, 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"
 
-#: remote.c:2156
+#: remote.c:1963
 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"
 
-#: remote.c:2159
+#: remote.c:1966
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -2913,11 +3212,11 @@ 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"
 
-#: remote.c:2167
+#: remote.c:1974
 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"
 
-#: remote.c:2170
+#: remote.c:1977
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -2930,30 +3229,30 @@ msgstr[0] ""
 "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"
 
-#: remote.c:2180
+#: remote.c:1987
 msgid "  (use \"git pull\" to merge the remote branch into 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"
 
-#: revision.c:2277
+#: revision.c:2289
 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"
 
-#: revision.c:2280
+#: revision.c:2292
 #, 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ả"
 
-#: revision.c:2477
+#: revision.c:2489
 msgid "--first-parent is incompatible with --bisect"
 msgstr "--first-parent xung khắc với --bisect"
 
-#: run-command.c:731
+#: run-command.c:728
 msgid "open /dev/null failed"
 msgstr "gặp lỗi khi mở “/dev/null”"
 
-#: run-command.c:1274
+#: run-command.c:1271
 #, c-format
 msgid ""
 "The '%s' hook was ignored because it's not set as executable.\n"
@@ -3001,29 +3300,34 @@ msgstr "kết thúc nhận không hỗ trợ đẩy --atomic"
 msgid "the receiving end does not support push options"
 msgstr "kết thúc nhận không hỗ trợ các tùy chọn của lệnh push"
 
-#: sequencer.c:158
+#: sequencer.c:175
 #, 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”"
 
-#: sequencer.c:267
+#: sequencer.c:275
+#, c-format
+msgid "could not delete '%s'"
+msgstr "không thể xóa bỏ “%s”"
+
+#: sequencer.c:301
 msgid "revert"
 msgstr "hoàn nguyên"
 
-#: sequencer.c:269
+#: sequencer.c:303
 msgid "cherry-pick"
 msgstr "cherry-pick"
 
-#: sequencer.c:271
+#: sequencer.c:305
 msgid "rebase -i"
 msgstr "rebase -i"
 
-#: sequencer.c:273
+#: sequencer.c:307
 #, c-format
 msgid "Unknown action: %d"
 msgstr "Không nhận ra thao tác: %d"
 
-#: sequencer.c:330
+#: sequencer.c:364
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
@@ -3031,7 +3335,7 @@ 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 <đường_dẫn>” hoặc “git rm <đường_dẫn>”"
 
-#: sequencer.c:333
+#: sequencer.c:367
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'\n"
@@ -3041,43 +3345,45 @@ msgstr ""
 "với lệnh “git add <đường_dẫn>” hoặc “git rm <đường_dẫn>”\n"
 "và chuyển giao kết quả bằng lệnh “git commit”"
 
-#: sequencer.c:346 sequencer.c:2245
+#: sequencer.c:380 sequencer.c:2468
 #, c-format
 msgid "could not lock '%s'"
 msgstr "không thể khóa “%s”"
 
-#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264
-#: sequencer.c:3246 sequencer.c:3310 wrapper.c:656
+#: sequencer.c:382 sequencer.c:2346 sequencer.c:2472 sequencer.c:2486
+#: sequencer.c:2694 sequencer.c:4336 sequencer.c:4399 wrapper.c:656
 #, c-format
 msgid "could not write to '%s'"
 msgstr "không thể ghi vào “%s”"
 
-#: sequencer.c:353
+#: sequencer.c:387
 #, c-format
 msgid "could not write eol to '%s'"
 msgstr "không thể ghi eol vào “%s”"
 
-#: sequencer.c:356 sequencer.c:2128 sequencer.c:2252
+#: sequencer.c:392 sequencer.c:2351 sequencer.c:2474 sequencer.c:2488
+#: sequencer.c:2702
 #, c-format
 msgid "failed to finalize '%s'"
 msgstr "gặp lỗi khi hoàn thành “%s”"
 
-#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259
-#: builtin/commit.c:722 builtin/merge.c:1047
+#: sequencer.c:415 sequencer.c:804 sequencer.c:1493 sequencer.c:2371
+#: sequencer.c:2684 sequencer.c:2788 builtin/am.c:259 builtin/commit.c:727
+#: builtin/merge.c:1046
 #, c-format
 msgid "could not read '%s'"
 msgstr "Không thể đọc “%s”."
 
-#: sequencer.c:405
+#: sequencer.c:441
 #, c-format
 msgid "your local changes would be overwritten by %s."
 msgstr "các thay đổi nội bộ của bạn có thể bị ghi đè bởi lệnh %s."
 
-#: sequencer.c:409
+#: sequencer.c:445
 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ý."
 
-#: sequencer.c:438
+#: sequencer.c:474
 #, c-format
 msgid "%s: fast-forward"
 msgstr "%s: chuyển-tiếp-nhanh"
@@ -3085,20 +3391,20 @@ msgstr "%s: chuyển-tiếp-nhanh"
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase -i".
 #.
-#: sequencer.c:526
+#: sequencer.c:563
 #, 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"
 
-#: sequencer.c:542
-msgid "could not resolve HEAD commit"
-msgstr "không thể phân giải lần chuyển giao HEAD"
-
-#: sequencer.c:562
+#: sequencer.c:579
 msgid "unable to update cache tree"
 msgstr "không thể cập nhật cây bộ nhớ đệm"
 
-#: sequencer.c:658
+#: sequencer.c:592
+msgid "could not resolve HEAD commit"
+msgstr "không thể phân giải lần chuyển giao HEAD"
+
+#: sequencer.c:749
 #, c-format
 msgid ""
 "you have staged changes in your working tree\n"
@@ -3127,11 +3433,15 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: sequencer.c:915
+#: sequencer.c:818
+msgid "writing root commit"
+msgstr "ghi chuyển giao gốc"
+
+#: sequencer.c:1043
 msgid "'prepare-commit-msg' hook failed"
 msgstr "móc “prepare-commit-msg” bị lỗi"
 
-#: sequencer.c:922
+#: sequencer.c:1050
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3162,7 +3472,7 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:935
+#: sequencer.c:1063
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3190,332 +3500,318 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:975
+#: sequencer.c:1103
 msgid "couldn't look up newly created commit"
 msgstr "không thể tìm thấy lần chuyển giao mới hơn đã được tạo"
 
-#: sequencer.c:977
+#: sequencer.c:1105
 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"
 
-#: sequencer.c:1023
+#: sequencer.c:1151
 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"
 
-#: sequencer.c:1025
+#: sequencer.c:1153
 msgid "detached HEAD"
 msgstr "đã rời khỏi HEAD"
 
-#: sequencer.c:1029
+#: sequencer.c:1157
 msgid " (root-commit)"
 msgstr " (root-commit)"
 
-#: sequencer.c:1050
+#: sequencer.c:1178
 msgid "could not parse HEAD"
 msgstr "không thể phân tích HEAD"
 
-#: sequencer.c:1052
+#: sequencer.c:1180
 #, c-format
 msgid "HEAD %s is not a commit!"
 msgstr "HEAD %s không phải là một lần chuyển giao!"
 
-#: sequencer.c:1056 builtin/commit.c:1491
+#: sequencer.c:1184 builtin/commit.c:1528
 msgid "could not parse HEAD commit"
 msgstr "không thể phân tích commit (lần chuyển giao) HEAD"
 
-#: sequencer.c:1107 sequencer.c:1673
+#: sequencer.c:1235 sequencer.c:1832
 msgid "unable to parse commit author"
 msgstr "không thể phân tích tác giả của lần chuyển giao"
 
-#: sequencer.c:1117 builtin/am.c:1630 builtin/merge.c:643
+#: sequencer.c:1245 builtin/am.c:1630 builtin/merge.c:645
 msgid "git write-tree failed to write a tree"
 msgstr "lệnh git write-tree gặp lỗi khi ghi một cây"
 
-#: sequencer.c:1134 sequencer.c:1186
+#: sequencer.c:1262 sequencer.c:1317
 #, c-format
 msgid "unable to read commit message from '%s'"
 msgstr "không thể đọc phần chú thích (message) từ “%s”"
 
-#: sequencer.c:1154 builtin/am.c:1650 builtin/commit.c:1594 builtin/merge.c:826
-#: builtin/merge.c:851
+#: sequencer.c:1284 builtin/am.c:1650 builtin/commit.c:1631 builtin/merge.c:825
+#: builtin/merge.c:850
 msgid "failed to write commit object"
 msgstr "gặp lỗi khi ghi đối tượng chuyển giao"
 
-#: sequencer.c:1213
+#: sequencer.c:1344
 #, c-format
 msgid "could not parse commit %s"
 msgstr "không thể phân tích lần chuyển giao %s"
 
-#: sequencer.c:1218
+#: sequencer.c:1349
 #, 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”"
 
-#: sequencer.c:1347
-#, c-format
-msgid ""
-"unexpected 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"không cần dòng thứ nhất của ghi chú squash:\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1353
-#, c-format
-msgid ""
-"invalid 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"dòng thứ nhất của ghi chú squash không hợp lệ:\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1359 sequencer.c:1384
+#: sequencer.c:1500 sequencer.c:1525
 #, c-format
 msgid "This is a combination of %d commits."
 msgstr "Đây là tổ hợp của %d lần chuyển giao."
 
-#: sequencer.c:1368 sequencer.c:3265
+#: sequencer.c:1510 sequencer.c:4355
 msgid "need a HEAD to fixup"
 msgstr "cần một HEAD để sửa"
 
-#: sequencer.c:1370
+#: sequencer.c:1512 sequencer.c:2729
 msgid "could not read HEAD"
 msgstr "không thể đọc HEAD"
 
-#: sequencer.c:1372
+#: sequencer.c:1514
 msgid "could not read HEAD's commit message"
 msgstr "không thể đọc phần chú thích (message) của HEAD"
 
-#: sequencer.c:1378
+#: sequencer.c:1520
 #, c-format
 msgid "cannot write '%s'"
 msgstr "không thể ghi “%s”"
 
-#: sequencer.c:1387 git-rebase--interactive.sh:452
+#: sequencer.c:1527 git-rebase--interactive.sh:457
 msgid "This is the 1st commit message:"
 msgstr "Đây là chú thích cho lần chuyển giao thứ nhất:"
 
-#: sequencer.c:1395
+#: sequencer.c:1535
 #, c-format
 msgid "could not read commit message of %s"
 msgstr "không thể đọc phần chú thích (message) của %s"
 
-#: sequencer.c:1402
+#: sequencer.c:1542
 #, c-format
 msgid "This is the commit message #%d:"
 msgstr "Đây là chú thích cho lần chuyển giao thứ #%d:"
 
-#: sequencer.c:1407
+#: sequencer.c:1548
 #, 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:"
 
-#: sequencer.c:1412
+#: sequencer.c:1553
 #, c-format
 msgid "unknown command: %d"
 msgstr "không hiểu câu lệnh %d"
 
-#: sequencer.c:1479
+#: sequencer.c:1631
 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."
 
-#: sequencer.c:1498
+#: sequencer.c:1638
+msgid "cannot fixup root commit"
+msgstr "không thể sửa chữa lần chuyển giao gốc"
+
+#: sequencer.c:1657
 #, 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."
 
-#: sequencer.c:1506
+#: sequencer.c:1665
 #, c-format
 msgid "commit %s does not have parent %d"
 msgstr "lần chuyển giao %s không có cha mẹ %d"
 
-#: sequencer.c:1510
+#: sequencer.c:1669
 #, c-format
 msgid "mainline was specified but commit %s is not a merge."
 msgstr ""
 "luồng chính đã được chỉ ra nhưng lần chuyển giao %s không phải là một lần "
 "hòa trộn."
 
-#: sequencer.c:1516
+#: sequencer.c:1675
 #, c-format
 msgid "cannot get commit message for %s"
 msgstr "không thể lấy ghi chú lần chuyển giao cho %s"
 
 #. TRANSLATORS: The first %s will be a "todo" command like
 #. "revert" or "pick", the second %s a SHA1.
-#: sequencer.c:1535
+#: sequencer.c:1694
 #, 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"
 
-#: sequencer.c:1600 sequencer.c:2397
+#: sequencer.c:1759
 #, c-format
 msgid "could not rename '%s' to '%s'"
 msgstr "không thể đổi tên “%s” thành “%s”"
 
-#: sequencer.c:1654
+#: sequencer.c:1813
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "không thể hoàn nguyên %s… %s"
 
-#: sequencer.c:1655
+#: sequencer.c:1814
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "không thể áp dụng miếng vá %s… %s"
 
-#: sequencer.c:1702
+#: sequencer.c:1864
 msgid "empty commit set passed"
 msgstr "lần chuyển giao trống rỗng đặt là hợp quy cách"
 
-#: sequencer.c:1712
+#: sequencer.c:1874
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s: gặp lỗi đọc bảng mục lục"
 
-#: sequencer.c:1718
+#: sequencer.c:1881
 #, 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"
 
-#: sequencer.c:1792
+#: sequencer.c:1961
 #, c-format
 msgid "%s does not accept arguments: '%s'"
 msgstr "%s không nhận các đối số: “%s”"
 
-#: sequencer.c:1801
+#: sequencer.c:1970
 #, c-format
 msgid "missing arguments for %s"
 msgstr "thiếu đối số cho %s"
 
-#: sequencer.c:1844
+#: sequencer.c:2029
 #, c-format
 msgid "invalid line %d: %.*s"
 msgstr "dòng không hợp lệ %d: %.*s"
 
-#: sequencer.c:1852
+#: sequencer.c:2037
 #, 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"
 
-#: sequencer.c:1883 sequencer.c:3056 sequencer.c:3091
+#: sequencer.c:2085 sequencer.c:4138 sequencer.c:4173
 #, c-format
 msgid "could not read '%s'."
 msgstr "không thể đọc “%s”."
 
-#: sequencer.c:1906
+#: sequencer.c:2108
 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”."
 
-#: sequencer.c:1908
+#: sequencer.c:2110
 #, c-format
 msgid "unusable instruction sheet: '%s'"
 msgstr "bảng chỉ thị không thể dùng được: %s"
 
-#: sequencer.c:1913
+#: sequencer.c:2115
 msgid "no commits parsed."
 msgstr "không có lần chuyển giao nào được phân tích."
 
-#: sequencer.c:1924
+#: sequencer.c:2126
 msgid "cannot cherry-pick during a revert."
 msgstr "không thể cherry-pick trong khi hoàn nguyên."
 
-#: sequencer.c:1926
+#: sequencer.c:2128
 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."
 
-#: sequencer.c:1993
+#: sequencer.c:2195
 #, c-format
 msgid "invalid key: %s"
 msgstr "khóa không đúng: %s"
 
-#: sequencer.c:1996
+#: sequencer.c:2198
 #, c-format
 msgid "invalid value for %s: %s"
 msgstr "giá trị cho %s không hợp lệ: %s"
 
-#: sequencer.c:2062
+#: sequencer.c:2269
+msgid "unusable squash-onto"
+msgstr "squash-onto không dùng được"
+
+#: sequencer.c:2285
 #, c-format
 msgid "malformed options sheet: '%s'"
 msgstr "bảng tùy chọn dị hình: “%s”"
 
-#: sequencer.c:2100
+#: sequencer.c:2323
 msgid "a cherry-pick or revert is already in progress"
 msgstr "có một thao tác “cherry-pick” hoặc “revert” đang được thực hiện"
 
-#: sequencer.c:2101
+#: sequencer.c:2324
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "hãy thử \"git cherry-pick (--continue | --quit | --abort)\""
 
-#: sequencer.c:2104
+#: sequencer.c:2327
 #, c-format
 msgid "could not create sequencer directory '%s'"
 msgstr "không thể tạo thư mục xếp dãy “%s”"
 
-#: sequencer.c:2118
+#: sequencer.c:2341
 msgid "could not lock HEAD"
 msgstr "không thể khóa HEAD"
 
-#: sequencer.c:2173 sequencer.c:2761
+#: sequencer.c:2396 sequencer.c:3403
 msgid "no cherry-pick or revert in progress"
 msgstr "không cherry-pick hay hoàn nguyên trong tiến trình"
 
-#: sequencer.c:2175
+#: sequencer.c:2398
 msgid "cannot resolve HEAD"
 msgstr "không thể phân giải HEAD"
 
-#: sequencer.c:2177 sequencer.c:2212
+#: sequencer.c:2400 sequencer.c:2435
 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"
 
-#: sequencer.c:2198 builtin/grep.c:720
+#: sequencer.c:2421 builtin/grep.c:720
 #, c-format
 msgid "cannot open '%s'"
 msgstr "không mở được “%s”"
 
-#: sequencer.c:2200
+#: sequencer.c:2423
 #, c-format
 msgid "cannot read '%s': %s"
 msgstr "không thể đọc “%s”: %s"
 
-#: sequencer.c:2201
+#: sequencer.c:2424
 msgid "unexpected end of file"
 msgstr "gặp kết thúc tập tin đột xuất"
 
-#: sequencer.c:2207
+#: sequencer.c:2430
 #, 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"
 
-#: sequencer.c:2218
+#: sequencer.c:2441
 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!"
 
-#: sequencer.c:2324 sequencer.c:2679
+#: sequencer.c:2545 sequencer.c:3321
 #, c-format
 msgid "could not update %s"
 msgstr "không thể cập nhật %s"
 
-#: sequencer.c:2362 sequencer.c:2659
+#: sequencer.c:2583 sequencer.c:3301
 msgid "cannot read HEAD"
 msgstr "không thể đọc HEAD"
 
-#: sequencer.c:2402 builtin/difftool.c:639
+#: sequencer.c:2618 sequencer.c:2622 builtin/difftool.c:639
 #, c-format
 msgid "could not copy '%s' to '%s'"
 msgstr "không thể chép “%s” sang “%s”"
 
-#: sequencer.c:2421
+#: sequencer.c:2641
 msgid "could not read index"
 msgstr "không thể đọc bảng mục lục"
 
-#: sequencer.c:2426
+#: sequencer.c:2646
 #, c-format
 msgid ""
 "execution failed: %s\n"
@@ -3530,11 +3826,11 @@ msgstr ""
 "  git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2432
+#: sequencer.c:2652
 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"
 
-#: sequencer.c:2438
+#: sequencer.c:2658
 #, c-format
 msgid ""
 "execution succeeded: %s\n"
@@ -3551,17 +3847,62 @@ msgstr ""
 "  git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2497
+#: sequencer.c:2771
+msgid "writing fake root commit"
+msgstr "ghi lần chuyển giao gốc giả"
+
+#: sequencer.c:2776
+msgid "writing squash-onto"
+msgstr "đang ghi squash-onto"
+
+#: sequencer.c:2811
+#, c-format
+msgid "failed to find tree of %s"
+msgstr "gặp lỗi khi tìm cây của %s"
+
+#: sequencer.c:2829
+msgid "could not write index"
+msgstr "không thể ghi bảng mục lục"
+
+#: sequencer.c:2861
+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"
+
+#: sequencer.c:2884
+#, c-format
+msgid "could not resolve '%s'"
+msgstr "không thể phân giải “%s”"
+
+#: sequencer.c:2906
+#, 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”"
+
+#: sequencer.c:2916 sequencer.c:2941
+#, c-format
+msgid "could not write '%s'"
+msgstr "không thể ghi “%s”"
+
+#: sequencer.c:3005
+#, c-format
+msgid "could not even attempt to merge '%.*s'"
+msgstr "không thể ngay cả khi thử hòa trộn “%.*s”"
+
+#: sequencer.c:3021
+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"
+
+#: sequencer.c:3088
 #, c-format
 msgid "Applied autostash.\n"
 msgstr "Đã áp dụng autostash.\n"
 
-#: sequencer.c:2509
+#: sequencer.c:3100
 #, c-format
 msgid "cannot store %s"
 msgstr "không thử lưu “%s”"
 
-#: sequencer.c:2512 git-rebase.sh:178
+#: sequencer.c:3103 git-rebase.sh:188
 #, c-format
 msgid ""
 "Applying autostash resulted in conflicts.\n"
@@ -3573,52 +3914,69 @@ msgstr ""
 "Bạn có thể chạy lệnh \"git stash pop\" hay \"git stash drop\" bất kỳ lúc "
 "nào.\n"
 
-#: sequencer.c:2595
+#: sequencer.c:3134
+#, c-format
+msgid ""
+"Could not execute the todo command\n"
+"\n"
+"    %.*s\n"
+"It has been rescheduled; To edit the command before continuing, please\n"
+"edit the todo list first:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+msgstr ""
+"Không thể thực thi lệnh todo\n"
+"\n"
+"    %.*s\n"
+"Nó đã được lập 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"
+
+#: sequencer.c:3202
 #, c-format
 msgid "Stopped at %s...  %.*s\n"
 msgstr "Dừng lại ở %s…  %.*s\n"
 
-#: sequencer.c:2637
+#: sequencer.c:3264
 #, c-format
 msgid "unknown command %d"
 msgstr "không hiểu câu lệnh %d"
 
-#: sequencer.c:2667
+#: sequencer.c:3309
 msgid "could not read orig-head"
 msgstr "không thể đọc orig-head"
 
-#: sequencer.c:2672 sequencer.c:3262
+#: sequencer.c:3314 sequencer.c:4352
 msgid "could not read 'onto'"
 msgstr "không thể đọc “onto”."
 
-#: sequencer.c:2686
+#: sequencer.c:3328
 #, c-format
 msgid "could not update HEAD to %s"
 msgstr "không thể cập nhật HEAD thành %s"
 
-#: sequencer.c:2770
+#: sequencer.c:3414
 msgid "cannot rebase: You have unstaged changes."
 msgstr "không thể cải tổ: Bạn có các thay đổi chưa được đưa lên bệ phóng."
 
-#: sequencer.c:2775
-msgid "could not remove CHERRY_PICK_HEAD"
-msgstr "không thể xóa bỏ CHERRY_PICK_HEAD"
-
-#: sequencer.c:2784
+#: sequencer.c:3423
 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"
 
-#: sequencer.c:2786
+#: sequencer.c:3425
 #, c-format
 msgid "invalid file: '%s'"
 msgstr "tập tin không hợp lệ: “%s”"
 
-#: sequencer.c:2788
+#: sequencer.c:3427
 #, c-format
 msgid "invalid contents: '%s'"
 msgstr "nội dung không hợp lệ: “%s”"
 
-#: sequencer.c:2791
+#: sequencer.c:3430
 msgid ""
 "\n"
 "You have uncommitted changes in your working tree. Please, commit them\n"
@@ -3628,45 +3986,54 @@ msgstr ""
 "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."
 
-#: sequencer.c:2801
+#: sequencer.c:3455 sequencer.c:3493
+#, c-format
+msgid "could not write file: '%s'"
+msgstr "không thể ghi tập tin: “%s”"
+
+#: sequencer.c:3508
+msgid "could not remove CHERRY_PICK_HEAD"
+msgstr "không thể xóa bỏ CHERRY_PICK_HEAD"
+
+#: sequencer.c:3515
 msgid "could not commit staged changes."
 msgstr "không thể chuyển giao các thay đổi đã đưa lên bệ phóng."
 
-#: sequencer.c:2881
+#: sequencer.c:3612
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s: không thể cherry-pick một %s"
 
-#: sequencer.c:2885
+#: sequencer.c:3616
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s: điểm xét duyệt sai"
 
-#: sequencer.c:2918
+#: sequencer.c:3649
 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"
 
-#: sequencer.c:3023
+#: sequencer.c:4098
 msgid "make_script: unhandled options"
 msgstr "make_script: các tùy chọn được không xử lý"
 
-#: sequencer.c:3026
+#: sequencer.c:4101
 msgid "make_script: error preparing revisions"
 msgstr "make_script: lỗi chuẩn bị điểm hiệu chỉnh"
 
-#: sequencer.c:3060 sequencer.c:3095
+#: sequencer.c:4142 sequencer.c:4177
 #, c-format
 msgid "unusable todo list: '%s'"
 msgstr "danh sách cần làm không dùng được: “%s”"
 
-#: sequencer.c:3146
+#: sequencer.c:4236
 #, c-format
 msgid ""
 "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
 msgstr ""
 "không nhận ra cài đặt %s cho tùy chọn rebase.missingCommitsCheck. Nên bỏ qua."
 
-#: sequencer.c:3212
+#: sequencer.c:4302
 #, c-format
 msgid ""
 "Warning: some commits may have been dropped accidentally.\n"
@@ -3675,7 +4042,7 @@ msgstr ""
 "Cảnh báo: một số lần chuyển giao có lẽ đã bị xóa một cách tình cờ.\n"
 "Các lần chuyển giao bị xóa (từ mới đến cũ):\n"
 
-#: sequencer.c:3219
+#: sequencer.c:4309
 #, c-format
 msgid ""
 "To avoid this message, use \"drop\" to explicitly remove a commit.\n"
@@ -3693,7 +4060,7 @@ msgstr ""
 "Cánh ứng xử có thể là: ignore, warn, error.\n"
 "\n"
 
-#: sequencer.c:3231
+#: sequencer.c:4321
 #, c-format
 msgid ""
 "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
@@ -3704,27 +4071,21 @@ msgstr ""
 "continue”.\n"
 "Hoặc là bạn có thể bãi bỏ việc cải tổ bằng “git rebase --abort”.\n"
 
-#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395
-#: builtin/am.c:779
-#, c-format
-msgid "could not open '%s' for writing"
-msgstr "không thể mở “%s” để ghi"
-
-#: sequencer.c:3285
+#: sequencer.c:4375
 #, c-format
 msgid "could not parse commit '%s'"
 msgstr "không thể phân tích lần chuyển giao “%s”"
 
-#: sequencer.c:3401
+#: sequencer.c:4490
 msgid "the script was already rearranged."
 msgstr "văn lệnh đã sẵn được sắp đặt rồi."
 
-#: setup.c:122
+#: setup.c:123
 #, c-format
 msgid "'%s' is outside repository"
 msgstr "“%s” ở ngoài một kho chứa"
 
-#: setup.c:171
+#: setup.c:172
 #, c-format
 msgid ""
 "%s: no such path in the working tree.\n"
@@ -3734,7 +4095,7 @@ msgstr ""
 "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ộ."
 
-#: setup.c:184
+#: setup.c:185
 #, c-format
 msgid ""
 "ambiguous argument '%s': unknown revision or path not in the working tree.\n"
@@ -3746,12 +4107,12 @@ msgstr ""
 "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>…]”"
 
-#: setup.c:233
+#: setup.c:234
 #, 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"
 
-#: setup.c:252
+#: setup.c:253
 #, c-format
 msgid ""
 "ambiguous argument '%s': both revision and filename\n"
@@ -3762,92 +4123,92 @@ msgstr ""
 "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>…]”"
 
-#: setup.c:388
+#: setup.c:389
 msgid "unable to set up work tree using invalid config"
 msgstr "Không thể đặt thư mục làm việc hiện hành sử dụng cấu hình không hợp lệ"
 
-#: setup.c:395
+#: setup.c:393
 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"
 
-#: setup.c:506
+#: setup.c:503
 #, 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"
 
-#: setup.c:514
+#: setup.c:511
 msgid "unknown repository extensions found:"
 msgstr "tìm thấy phần mở rộng kho chưa biết:"
 
-#: setup.c:533
+#: setup.c:530
 #, c-format
 msgid "error opening '%s'"
 msgstr "gặp lỗi khi mở “%s”"
 
-#: setup.c:535
+#: setup.c:532
 #, c-format
 msgid "too large to be a .git file: '%s'"
 msgstr "tập tin .git là quá lớn: “%s”"
 
-#: setup.c:537
+#: setup.c:534
 #, c-format
 msgid "error reading %s"
 msgstr "gặp lỗi khi đọc %s"
 
-#: setup.c:539
+#: setup.c:536
 #, c-format
 msgid "invalid gitfile format: %s"
 msgstr "định dạng tập tin git không hợp lệ: %s"
 
-#: setup.c:541
+#: setup.c:538
 #, c-format
 msgid "no path in gitfile: %s"
 msgstr "không có đường dẫn trong tập tin git: %s"
 
-#: setup.c:543
+#: setup.c:540
 #, c-format
 msgid "not a git repository: %s"
 msgstr "Không phải là kho git: %s"
 
-#: setup.c:642
+#: setup.c:639
 #, c-format
 msgid "'$%s' too big"
 msgstr "“$%s” quá lớn"
 
-#: setup.c:656
+#: setup.c:653
 #, c-format
 msgid "not a git repository: '%s'"
 msgstr "không phải là kho git: “%s”"
 
-#: setup.c:685 setup.c:687 setup.c:718
+#: setup.c:682 setup.c:684 setup.c:715
 #, c-format
 msgid "cannot chdir to '%s'"
 msgstr "không thể chdir (chuyển đổi thư mục) sang “%s”"
 
-#: setup.c:690 setup.c:746 setup.c:756 setup.c:795 setup.c:803 setup.c:818
+#: setup.c:687 setup.c:743 setup.c:753 setup.c:792 setup.c:800 setup.c:815
 msgid "cannot come back to cwd"
 msgstr "không thể quay lại cwd"
 
-#: setup.c:816
+#: setup.c:813
 #, 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"
 
-#: setup.c:827
+#: setup.c:824
 #, c-format
 msgid "failed to stat '%*s%s%s'"
 msgstr "gặp lỗi khi lấy thống kê về “%*s%s%s”"
 
-#: setup.c:1057
+#: setup.c:1054
 msgid "Unable to read current working directory"
 msgstr "Không thể đọc thư mục làm việc hiện hành"
 
-#: setup.c:1069 setup.c:1075
+#: setup.c:1066 setup.c:1072
 #, c-format
 msgid "cannot change to '%s'"
 msgstr "không thể chuyển sang “%s”"
 
-#: setup.c:1088
+#: setup.c:1085
 #, c-format
 msgid ""
 "not a git repository (or any parent up to mount point %s)\n"
@@ -3857,7 +4218,7 @@ msgstr ""
 "Dừng tại biên của hệ thống tập tin (GIT_DISCOVERY_ACROSS_FILESYSTEM chưa "
 "đặt)."
 
-#: setup.c:1172
+#: setup.c:1168
 #, c-format
 msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
@@ -3866,53 +4227,53 @@ msgstr ""
 "gặp vấn đề với giá trị chế độ tập tin core.sharedRepository (0%.3o).\n"
 "người sở hữu tập tin phải luôn có quyền đọc và ghi."
 
-#: setup.c:1215
+#: setup.c:1211
 msgid "open /dev/null or dup failed"
 msgstr "gặp lỗi khi mở “/dev/null” hay dup"
 
-#: setup.c:1230
+#: setup.c:1226
 msgid "fork failed"
 msgstr "gặp lỗi khi rẽ nhánh tiến trình"
 
-#: setup.c:1235
+#: setup.c:1231
 msgid "setsid failed"
 msgstr "setsid gặp lỗi"
 
-#: sha1_file.c:592
+#: sha1-file.c:625
 #, c-format
 msgid "path '%s' does not exist"
 msgstr "đường dẫn “%s” không tồn tại"
 
-#: sha1_file.c:618
+#: sha1-file.c:651
 #, 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ợ."
 
-#: sha1_file.c:624
+#: sha1-file.c:657
 #, 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ộ."
 
-#: sha1_file.c:630
+#: sha1-file.c:663
 #, c-format
 msgid "reference repository '%s' is shallow"
 msgstr "kho tham chiếu “%s” là nông"
 
-#: sha1_file.c:638
+#: sha1-file.c:671
 #, c-format
 msgid "reference repository '%s' is grafted"
 msgstr "kho tham chiếu “%s” bị cấy ghép"
 
-#: sha1_name.c:422
+#: sha1-name.c:442
 #, c-format
 msgid "short SHA1 %s is ambiguous"
 msgstr "tóm lược SHA1 %s chưa rõ ràng"
 
-#: sha1_name.c:433
+#: sha1-name.c:453
 msgid "The candidates are:"
 msgstr "Các ứng cử là:"
 
-#: sha1_name.c:693
+#: sha1-name.c:695
 msgid ""
 "Git normally never creates a ref that ends with 40 hex characters\n"
 "because it will be ignored when you just specify 40-hex. These refs\n"
@@ -3936,72 +4297,72 @@ msgstr ""
 "này\n"
 "bằng cách chạy lệnh \"git config advice.objectNameWarning false\""
 
-#: submodule.c:96 submodule.c:130
+#: submodule.c:97 submodule.c:131
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr ""
 "Không thể thay đổi .gitmodules chưa hòa trộn, hãy giải quyết xung đột trộn "
 "trước"
 
-#: submodule.c:100 submodule.c:134
+#: submodule.c:101 submodule.c:135
 #, c-format
 msgid "Could not find section in .gitmodules where path=%s"
 msgstr "Không thể tìm thấy phần trong .gitmodules nơi mà đường_dẫn=%s"
 
-#: submodule.c:108
+#: submodule.c:109
 #, c-format
 msgid "Could not update .gitmodules entry %s"
 msgstr "Không thể cập nhật mục .gitmodules %s"
 
-#: submodule.c:141
+#: submodule.c:142
 #, c-format
 msgid "Could not remove .gitmodules entry for %s"
 msgstr "Không thể gỡ bỏ mục .gitmodules dành cho %s"
 
-#: submodule.c:152
+#: submodule.c:153
 msgid "staging updated .gitmodules failed"
 msgstr "gặp lỗi khi tổ chức .gitmodules đã cập nhật"
 
-#: submodule.c:312
+#: submodule.c:315
 #, c-format
 msgid "in unpopulated submodule '%s'"
 msgstr "Trong mô-đun-con không có gì “%s”"
 
-#: submodule.c:343
+#: submodule.c:346
 #, c-format
 msgid "Pathspec '%s' is in submodule '%.*s'"
 msgstr "Đặc tả đường dẫn “%s” thì ở trong mô-đun-con “%.*s”"
 
-#: submodule.c:833
+#: submodule.c:837
 #, 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"
 
-#: submodule.c:1065 builtin/branch.c:648 builtin/submodule--helper.c:1724
+#: submodule.c:1069 builtin/branch.c:651 builtin/submodule--helper.c:1743
 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ệ."
 
-#: submodule.c:1370
+#: submodule.c:1375
 #, c-format
 msgid "'%s' not recognized as a git repository"
 msgstr "không nhận ra “%s” là một kho git"
 
-#: submodule.c:1508
+#: submodule.c:1513
 #, 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”"
 
-#: submodule.c:1521
+#: submodule.c:1526
 #, c-format
 msgid "could not run 'git status' in submodule '%s'"
 msgstr "không thể chạy “git status” trong mô-đun-con “%s”"
 
-#: submodule.c:1614
+#: submodule.c:1619
 #, c-format
 msgid "submodule '%s' has dirty index"
 msgstr "mô-đun-con “%s” có mục lục còn bẩn"
 
-#: submodule.c:1878
+#: submodule.c:1718
 #, c-format
 msgid ""
 "relocate_gitdir for submodule '%s' with more than one worktree not supported"
@@ -4009,18 +4370,18 @@ 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 "
 "được hỗ trợ"
 
-#: submodule.c:1890 submodule.c:1946
+#: submodule.c:1730 submodule.c:1786
 #, 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”"
 
-#: submodule.c:1894 builtin/submodule--helper.c:1246
-#: builtin/submodule--helper.c:1256
+#: submodule.c:1734 builtin/submodule--helper.c:1261
+#: builtin/submodule--helper.c:1271
 #, c-format
 msgid "could not create directory '%s'"
 msgstr "không thể tạo thư mục “%s”"
 
-#: submodule.c:1897
+#: submodule.c:1737
 #, c-format
 msgid ""
 "Migrating git directory of '%s%s' from\n"
@@ -4031,29 +4392,30 @@ msgstr ""
 "“%s” sang\n"
 "“%s”\n"
 
-#: submodule.c:1981
+#: submodule.c:1821
 #, c-format
 msgid "could not recurse into submodule '%s'"
 msgstr "không thể đệ quy vào trong mô-đun-con “%s”"
 
-#: submodule.c:2025
+#: submodule.c:1865
 msgid "could not start ls-files in .."
 msgstr "không thể lấy thông tin thống kê về ls-files trong .."
 
-#: submodule.c:2045
-msgid "BUG: returned path string doesn't match cwd?"
-msgstr "LỖI: trả về chuỗi đường dẫn không khớp cwd?"
-
-#: submodule.c:2064
+#: submodule.c:1904
 #, c-format
 msgid "ls-tree returned unexpected return code %d"
 msgstr "ls-tree trả về mã không như mong đợi %d"
 
-#: submodule-config.c:263
+#: submodule-config.c:230
+#, c-format
+msgid "ignoring suspicious submodule name: %s"
+msgstr "đang lờ đi tên mô-đun-con mập mờ: %s"
+
+#: submodule-config.c:294
 msgid "negative values not allowed for submodule.fetchjobs"
 msgstr "không cho phép giá trị âm ở submodule.fetchJobs"
 
-#: submodule-config.c:436
+#: submodule-config.c:467
 #, c-format
 msgid "invalid value for %s"
 msgstr "giá trị cho %s không hợp lệ"
@@ -4069,7 +4431,7 @@ msgstr "chạy lệnh kéo theo “%s” gặp lỗi"
 msgid "unknown value '%s' for key '%s'"
 msgstr "không hiểu giá trị “%s” cho khóa “%s”"
 
-#: trailer.c:539 trailer.c:544 builtin/remote.c:290
+#: trailer.c:539 trailer.c:544 builtin/remote.c:293
 #, c-format
 msgid "more than one %s"
 msgstr "nhiều hơn một %s"
@@ -4112,17 +4474,21 @@ msgstr "không thể tạo tập tin tạm thời"
 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"
 
-#: transport.c:63
+#: transport.c:116
 #, 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"
 
-#: transport.c:152
+#: transport.c:208
 #, 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ệ"
 
-#: transport.c:916
+#: transport.c:584
+msgid "could not parse transport.color.* config"
+msgstr "không thể phân tích cú pháp cấu hình transport.color.*"
+
+#: transport.c:996
 #, c-format
 msgid ""
 "The following submodule paths contain changes that can\n"
@@ -4131,7 +4497,7 @@ 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"
 
-#: transport.c:920
+#: transport.c:1000
 #, c-format
 msgid ""
 "\n"
@@ -4158,11 +4524,11 @@ msgstr ""
 "để đẩy chúng lên máy phục vụ.\n"
 "\n"
 
-#: transport.c:928
+#: transport.c:1008
 msgid "Aborting."
 msgstr "Bãi bỏ."
 
-#: transport-helper.c:1079
+#: transport-helper.c:1087
 #, c-format
 msgid "Could not read ref %s"
 msgstr "Không thể đọc tham chiếu %s"
@@ -4179,11 +4545,11 @@ msgstr "chế độ dị hình 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"
 
-#: tree-walk.c:114
+#: tree-walk.c:113
 msgid "too-short tree file"
 msgstr "tập tin cây quá ngắn"
 
-#: unpack-trees.c:108
+#: unpack-trees.c:111
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4194,7 +4560,7 @@ msgstr ""
 "%%sVui lòng chuyển giao các thay đổi hay tạm cất chúng đi trước khi bạn "
 "chuyển nhánh."
 
-#: unpack-trees.c:110
+#: unpack-trees.c:113
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4204,7 +4570,7 @@ msgstr ""
 "checkout:\n"
 "%%s"
 
-#: unpack-trees.c:113
+#: unpack-trees.c:116
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4215,7 +4581,7 @@ msgstr ""
 "%%sVui lòng chuyển giao các thay đổi hay tạm cất chúng đi trước khi bạn hòa "
 "trộn."
 
-#: unpack-trees.c:115
+#: unpack-trees.c:118
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4225,7 +4591,7 @@ msgstr ""
 "hòa trộn:\n"
 "%%s"
 
-#: unpack-trees.c:118
+#: unpack-trees.c:121
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4235,7 +4601,7 @@ msgstr ""
 "%s:\n"
 "%%sVui lòng chuyển giao các thay đổi hay tạm cất chúng đi trước khi bạn %s."
 
-#: unpack-trees.c:120
+#: unpack-trees.c:123
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4245,7 +4611,7 @@ msgstr ""
 "%s:\n"
 "%%s"
 
-#: unpack-trees.c:125
+#: unpack-trees.c:128
 #, c-format
 msgid ""
 "Updating the following directories would lose untracked files in them:\n"
@@ -4255,7 +4621,7 @@ msgstr ""
 "trong nó:\n"
 "%s"
 
-#: unpack-trees.c:129
+#: unpack-trees.c:132
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4265,7 +4631,7 @@ msgstr ""
 "checkout:\n"
 "%%sVui lòng di chuyển hay gỡ bỏ chúng trước khi bạn chuyển nhánh."
 
-#: unpack-trees.c:131
+#: unpack-trees.c:134
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4275,7 +4641,7 @@ msgstr ""
 "checkout:\n"
 "%%s"
 
-#: unpack-trees.c:134
+#: unpack-trees.c:137
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4285,7 +4651,7 @@ msgstr ""
 "trộn:\n"
 "%%sVui lòng di chuyển hay gỡ bỏ chúng trước khi bạn hòa trộn."
 
-#: unpack-trees.c:136
+#: unpack-trees.c:139
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4295,7 +4661,7 @@ msgstr ""
 "trộn:\n"
 "%%s"
 
-#: unpack-trees.c:139
+#: unpack-trees.c:142
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4304,7 +4670,7 @@ 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."
 
-#: unpack-trees.c:141
+#: unpack-trees.c:144
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4313,7 +4679,7 @@ 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"
 "%%s"
 
-#: unpack-trees.c:146
+#: unpack-trees.c:150
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4324,7 +4690,7 @@ msgstr ""
 "checkout:\n"
 "%%sVui lòng di chuyển hay gỡ bỏ chúng trước khi bạn chuyển nhánh."
 
-#: unpack-trees.c:148
+#: unpack-trees.c:152
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4335,7 +4701,7 @@ msgstr ""
 "checkout:\n"
 "%%s"
 
-#: unpack-trees.c:151
+#: unpack-trees.c:155
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4345,7 +4711,7 @@ msgstr ""
 "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."
 
-#: unpack-trees.c:153
+#: unpack-trees.c:157
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4355,7 +4721,7 @@ msgstr ""
 "hòa trộn:\n"
 "%%s"
 
-#: unpack-trees.c:156
+#: unpack-trees.c:160
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4365,7 +4731,7 @@ msgstr ""
 "%s:\n"
 "%%sVui lòng di chuyển hay gỡ bỏ chúng trước khi bạn %s."
 
-#: unpack-trees.c:158
+#: unpack-trees.c:162
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4375,12 +4741,12 @@ msgstr ""
 "%s:\n"
 "%%s"
 
-#: unpack-trees.c:165
+#: unpack-trees.c:170
 #, c-format
 msgid "Entry '%s' overlaps with '%s'.  Cannot bind."
 msgstr "Mục “%s” đè lên “%s”. Không thể buộc."
 
-#: unpack-trees.c:168
+#: unpack-trees.c:173
 #, c-format
 msgid ""
 "Cannot update sparse checkout: the following entries are not up to date:\n"
@@ -4389,7 +4755,7 @@ msgstr ""
 "Không thể cập nhật checkout rải rác: các mục tin sau đây chưa cập nhật:\n"
 "%s"
 
-#: unpack-trees.c:170
+#: unpack-trees.c:175
 #, c-format
 msgid ""
 "The following working tree files would be overwritten by sparse checkout "
@@ -4400,7 +4766,7 @@ msgstr ""
 "nhật checkout rải rác:\n"
 "%s"
 
-#: unpack-trees.c:172
+#: unpack-trees.c:177
 #, c-format
 msgid ""
 "The following working tree files would be removed by sparse checkout "
@@ -4411,7 +4777,7 @@ msgstr ""
 "nhật checkout rải rác:\n"
 "%s"
 
-#: unpack-trees.c:174
+#: unpack-trees.c:179
 #, c-format
 msgid ""
 "Cannot update submodule:\n"
@@ -4420,12 +4786,12 @@ msgstr ""
 "Không thể cập nhật mô-đun-con:\n"
 "%s"
 
-#: unpack-trees.c:251
+#: unpack-trees.c:262
 #, c-format
 msgid "Aborting\n"
 msgstr "Bãi bỏ\n"
 
-#: unpack-trees.c:333
+#: unpack-trees.c:344
 msgid "Checking out files"
 msgstr "Đang lấy ra các tập tin"
 
@@ -4495,7 +4861,7 @@ msgid "could not open '%s' for reading and writing"
 msgstr "không thể mở “%s” để đọc và ghi"
 
 #: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770
-#: builtin/am.c:862 builtin/merge.c:1044
+#: builtin/am.c:862 builtin/merge.c:1043
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "không thể mở “%s” để đọc"
@@ -4509,156 +4875,156 @@ 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"
 
-#: wt-status.c:151
+#: wt-status.c:154
 msgid "Unmerged paths:"
 msgstr "Những đường dẫn chưa được hòa trộn:"
 
-#: wt-status.c:178 wt-status.c:205
+#: wt-status.c:181 wt-status.c:208
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (dùng \"git reset %s <tập-tin>…\" để bỏ ra khỏi bệ phóng)"
 
-#: wt-status.c:180 wt-status.c:207
+#: wt-status.c:183 wt-status.c:210
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (dùng \"git rm --cached <tập-tin>…\" để bỏ ra khỏi bệ phóng)"
 
-#: wt-status.c:184
+#: wt-status.c:187
 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)"
 
-#: wt-status.c:186 wt-status.c:190
+#: wt-status.c:189 wt-status.c:193
 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)"
 
-#: wt-status.c:188
+#: wt-status.c:191
 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)"
 
-#: wt-status.c:199 wt-status.c:1007
+#: wt-status.c:202 wt-status.c:1015
 msgid "Changes to be committed:"
 msgstr "Những thay đổi sẽ được chuyển giao:"
 
-#: wt-status.c:217 wt-status.c:1016
+#: wt-status.c:220 wt-status.c:1024
 msgid "Changes not staged for commit:"
 msgstr "Các thay đổi chưa được đặt lên bệ phóng để chuyển giao:"
 
-#: wt-status.c:221
+#: wt-status.c:224
 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)"
 
-#: wt-status.c:223
+#: wt-status.c:226
 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)"
 
-#: wt-status.c:224
+#: wt-status.c:227
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr ""
 "  (dùng \"git checkout -- <tập-tin>…\" để loại bỏ các thay đổi trong thư mục "
 "làm việc)"
 
-#: wt-status.c:226
+#: wt-status.c:229
 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)"
 
-#: wt-status.c:238
+#: wt-status.c:241
 #, 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)"
 
-#: wt-status.c:253
+#: wt-status.c:256
 msgid "both deleted:"
 msgstr "bị xóa bởi cả hai:"
 
-#: wt-status.c:255
+#: wt-status.c:258
 msgid "added by us:"
 msgstr "được thêm vào bởi chúng ta:"
 
-#: wt-status.c:257
+#: wt-status.c:260
 msgid "deleted by them:"
 msgstr "bị xóa đi bởi họ:"
 
-#: wt-status.c:259
+#: wt-status.c:262
 msgid "added by them:"
 msgstr "được thêm vào bởi họ:"
 
-#: wt-status.c:261
+#: wt-status.c:264
 msgid "deleted by us:"
 msgstr "bị xóa bởi chúng ta:"
 
-#: wt-status.c:263
+#: wt-status.c:266
 msgid "both added:"
 msgstr "được thêm vào bởi cả hai:"
 
-#: wt-status.c:265
+#: wt-status.c:268
 msgid "both modified:"
 msgstr "bị sửa bởi cả hai:"
 
-#: wt-status.c:275
+#: wt-status.c:278
 msgid "new file:"
 msgstr "tập tin mới:"
 
-#: wt-status.c:277
+#: wt-status.c:280
 msgid "copied:"
 msgstr "đã chép:"
 
-#: wt-status.c:279
+#: wt-status.c:282
 msgid "deleted:"
 msgstr "đã xóa:"
 
-#: wt-status.c:281
+#: wt-status.c:284
 msgid "modified:"
 msgstr "đã sửa:"
 
-#: wt-status.c:283
+#: wt-status.c:286
 msgid "renamed:"
 msgstr "đã đổi tên:"
 
-#: wt-status.c:285
+#: wt-status.c:288
 msgid "typechange:"
 msgstr "đổi-kiểu:"
 
-#: wt-status.c:287
+#: wt-status.c:290
 msgid "unknown:"
 msgstr "không hiểu:"
 
-#: wt-status.c:289
+#: wt-status.c:292
 msgid "unmerged:"
 msgstr "chưa hòa trộn:"
 
-#: wt-status.c:369
+#: wt-status.c:372
 msgid "new commits, "
 msgstr "lần chuyển giao mới, "
 
-#: wt-status.c:371
+#: wt-status.c:374
 msgid "modified content, "
 msgstr "nội dung bị sửa đổi, "
 
-#: wt-status.c:373
+#: wt-status.c:376
 msgid "untracked content, "
 msgstr "nội dung chưa được theo dõi, "
 
-#: wt-status.c:847
+#: wt-status.c:853
 #, 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"
 
-#: wt-status.c:879
+#: wt-status.c:885
 msgid "Submodules changed but not updated:"
 msgstr "Những mô-đun-con đã bị thay đổi nhưng chưa được cập nhật:"
 
-#: wt-status.c:881
+#: wt-status.c:887
 msgid "Submodule changes to be committed:"
 msgstr "Những mô-đun-con thay đổi đã được chuyển giao:"
 
-#: wt-status.c:963
+#: wt-status.c:969
 msgid ""
 "Do not modify or remove the line above.\n"
 "Everything below it will be ignored."
@@ -4666,109 +5032,109 @@ 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ỏ."
 
-#: wt-status.c:1076
+#: wt-status.c:1084
 msgid "You have unmerged paths."
 msgstr "Bạn có những đường dẫn chưa được hòa trộn."
 
-#: wt-status.c:1079
+#: wt-status.c:1087
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (sửa các xung đột rồi chạy \"git commit\")"
 
-#: wt-status.c:1081
+#: wt-status.c:1089
 msgid "  (use \"git merge --abort\" to abort the merge)"
 msgstr "  (dùng \"git merge --abort\" để bãi bỏ việc hòa trộn)"
 
-#: wt-status.c:1086
+#: wt-status.c:1094
 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."
 
-#: wt-status.c:1089
+#: wt-status.c:1097
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (dùng \"git commit\" để hoàn tất việc hòa trộn)"
 
-#: wt-status.c:1099
+#: wt-status.c:1107
 msgid "You are in the middle of an am session."
 msgstr "Bạn đang ở giữa của một phiên “am”."
 
-#: wt-status.c:1102
+#: wt-status.c:1110
 msgid "The current patch is empty."
 msgstr "Miếng vá hiện tại bị trống rỗng."
 
-#: wt-status.c:1106
+#: wt-status.c:1114
 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\")"
 
-#: wt-status.c:1108
+#: wt-status.c:1116
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (dùng \"git am --skip\" để bỏ qua miếng vá này)"
 
-#: wt-status.c:1110
+#: wt-status.c:1118
 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)"
 
-#: wt-status.c:1242
+#: wt-status.c:1250
 msgid "git-rebase-todo is missing."
 msgstr "thiếu git-rebase-todo"
 
-#: wt-status.c:1244
+#: wt-status.c:1252
 msgid "No commands done."
 msgstr "Không thực hiện lệnh nào."
 
-#: wt-status.c:1247
+#: wt-status.c:1255
 #, c-format
 msgid "Last command done (%d command done):"
 msgid_plural "Last commands done (%d commands done):"
 msgstr[0] "Lệnh thực hiện cuối (%d lệnh được thực thi):"
 
-#: wt-status.c:1258
+#: wt-status.c:1266
 #, c-format
 msgid "  (see more in file %s)"
 msgstr "  (xem thêm trong %s)"
 
-#: wt-status.c:1263
+#: wt-status.c:1271
 msgid "No commands remaining."
 msgstr "Không có lệnh nào còn lại."
 
-#: wt-status.c:1266
+#: wt-status.c:1274
 #, c-format
 msgid "Next command to do (%d remaining command):"
 msgid_plural "Next commands to do (%d remaining commands):"
 msgstr[0] "Lệnh cần làm kế tiếp (%d lệnh còn lại):"
 
-#: wt-status.c:1274
+#: wt-status.c:1282
 msgid "  (use \"git rebase --edit-todo\" to view and edit)"
 msgstr "  (dùng lệnh \"git rebase --edit-todo\" để xem và sửa)"
 
-#: wt-status.c:1287
+#: wt-status.c:1295
 #, 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”."
 
-#: wt-status.c:1292
+#: wt-status.c:1300
 msgid "You are currently rebasing."
 msgstr "Bạn hiện nay đang thực hiện việc “rebase” (“cải tổ”)."
 
-#: wt-status.c:1306
+#: wt-status.c:1314
 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\")"
 
-#: wt-status.c:1308
+#: wt-status.c:1316
 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)"
 
-#: wt-status.c:1310
+#: wt-status.c:1318
 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)"
 
-#: wt-status.c:1316
+#: wt-status.c:1324
 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\")"
 
-#: wt-status.c:1320
+#: wt-status.c:1328
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
@@ -4776,134 +5142,134 @@ 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”."
 
-#: wt-status.c:1325
+#: wt-status.c:1333
 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."
 
-#: wt-status.c:1328
+#: wt-status.c:1336
 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\")"
 
-#: wt-status.c:1332
+#: wt-status.c:1340
 #, 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”."
 
-#: wt-status.c:1337
+#: wt-status.c:1345
 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."
 
-#: wt-status.c:1340
+#: wt-status.c:1348
 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)"
 
-#: wt-status.c:1342
+#: wt-status.c:1350
 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)"
 
-#: wt-status.c:1352
+#: wt-status.c:1360
 #, c-format
 msgid "You are currently cherry-picking commit %s."
 msgstr "Bạn hiện nay đang thực hiện việc cherry-pick lần chuyển giao %s."
 
-#: wt-status.c:1357
+#: wt-status.c:1365
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr ""
 "  (sửa các xung đột và sau đó chạy lệnh \"git cherry-pick --continue\")"
 
-#: wt-status.c:1360
+#: wt-status.c:1368
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr ""
 "  (khi tất cả các xung đột đã sửa xong: chạy lệnh \"git cherry-pick --"
 "continue\")"
 
-#: wt-status.c:1362
+#: wt-status.c:1370
 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)"
 
-#: wt-status.c:1371
+#: wt-status.c:1379
 #, 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”."
 
-#: wt-status.c:1376
+#: wt-status.c:1384
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (sửa các xung đột và sau đó chạy lệnh \"git revert --continue\")"
 
-#: wt-status.c:1379
+#: wt-status.c:1387
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr ""
 "  (khi tất cả các xung đột đã sửa xong: chạy lệnh \"git revert --continue\")"
 
-#: wt-status.c:1381
+#: wt-status.c:1389
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr "  (dùng \"git revert --abort\" để hủy bỏ thao tác hoàn nguyên)"
 
-#: wt-status.c:1392
+#: wt-status.c:1400
 #, c-format
 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”."
 
-#: wt-status.c:1396
+#: wt-status.c:1404
 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)."
 
-#: wt-status.c:1399
+#: wt-status.c:1407
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr "  (dùng \"git bisect reset\" để quay trở lại nhánh nguyên thủy)"
 
-#: wt-status.c:1596
+#: wt-status.c:1604
 msgid "On branch "
 msgstr "Trên nhánh "
 
-#: wt-status.c:1602
+#: wt-status.c:1610
 msgid "interactive rebase in progress; onto "
 msgstr "rebase ở chế độ tương tác đang được thực hiện; lên trên "
 
-#: wt-status.c:1604
+#: wt-status.c:1612
 msgid "rebase in progress; onto "
 msgstr "rebase đang được thực hiện: lên trên "
 
-#: wt-status.c:1609
+#: wt-status.c:1617
 msgid "HEAD detached at "
 msgstr "HEAD được tách rời tại "
 
-#: wt-status.c:1611
+#: wt-status.c:1619
 msgid "HEAD detached from "
 msgstr "HEAD được tách rời từ "
 
-#: wt-status.c:1614
+#: wt-status.c:1622
 msgid "Not currently on any branch."
 msgstr "Hiện tại chẳng ở nhánh nào cả."
 
-#: wt-status.c:1634
+#: wt-status.c:1642
 msgid "Initial commit"
 msgstr "Lần chuyển giao khởi tạo"
 
-#: wt-status.c:1635
+#: wt-status.c:1643
 msgid "No commits yet"
 msgstr "Vẫn chưa chuyển giao"
 
-#: wt-status.c:1649
+#: wt-status.c:1657
 msgid "Untracked files"
 msgstr "Những tập tin chưa được theo dõi"
 
-#: wt-status.c:1651
+#: wt-status.c:1659
 msgid "Ignored files"
 msgstr "Những tập tin bị lờ đi"
 
-#: wt-status.c:1655
+#: wt-status.c:1663
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -4915,32 +5281,32 @@ msgstr ""
 "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”.."
 
-#: wt-status.c:1661
+#: wt-status.c:1669
 #, 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"
 
-#: wt-status.c:1663
+#: wt-status.c:1671
 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)"
 
-#: wt-status.c:1669
+#: wt-status.c:1677
 msgid "No changes"
 msgstr "Không có thay đổi nào"
 
-#: wt-status.c:1674
+#: wt-status.c:1682
 #, 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 "
 "\"git commit -a\")\n"
 
-#: wt-status.c:1677
+#: wt-status.c:1685
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "không có thay đổi nào được thêm vào để chuyển giao\n"
 
-#: wt-status.c:1680
+#: wt-status.c:1688
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
@@ -4949,74 +5315,74 @@ 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"
 
-#: wt-status.c:1683
+#: wt-status.c:1691
 #, 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"
 
-#: wt-status.c:1686
+#: wt-status.c:1694
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr ""
 "không có gì để chuyển giao (tạo/sao-chép các tập tin và dùng \"git add\" để "
 "đưa vào theo dõi)\n"
 
-#: wt-status.c:1689 wt-status.c:1694
+#: wt-status.c:1697 wt-status.c:1702
 #, c-format
 msgid "nothing to commit\n"
 msgstr "không có gì để chuyển giao\n"
 
-#: wt-status.c:1692
+#: wt-status.c:1700
 #, 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"
 
-#: wt-status.c:1696
+#: wt-status.c:1704
 #, 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"
 
-#: wt-status.c:1809
+#: wt-status.c:1817
 msgid "No commits yet on "
 msgstr "Vẫn không thực hiện lệnh chuyển giao nào"
 
-#: wt-status.c:1813
+#: wt-status.c:1821
 msgid "HEAD (no branch)"
 msgstr "HEAD (không nhánh)"
 
-#: wt-status.c:1844
+#: wt-status.c:1852
 msgid "different"
 msgstr "khác"
 
-#: wt-status.c:1846 wt-status.c:1854
+#: wt-status.c:1854 wt-status.c:1862
 msgid "behind "
 msgstr "đằng sau "
 
-#: wt-status.c:1849 wt-status.c:1852
+#: wt-status.c:1857 wt-status.c:1860
 msgid "ahead "
 msgstr "phía trước "
 
 #. TRANSLATORS: the action is e.g. "pull with rebase"
-#: wt-status.c:2358
+#: wt-status.c:2366
 #, c-format
 msgid "cannot %s: You have unstaged changes."
 msgstr "không thể %s: Bạn có các thay đổi chưa được đưa lên bệ phóng."
 
-#: wt-status.c:2364
+#: wt-status.c:2372
 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."
 
-#: wt-status.c:2366
+#: wt-status.c:2374
 #, 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."
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:440
+#: compat/precompose_utf8.c:58 builtin/clone.c:442
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr "gặp lỗi khi bỏ liên kết (unlink) “%s”"
@@ -5030,7 +5396,7 @@ msgstr "git add [<các-tùy-chọn>] [--]  <pathspec>…"
 msgid "unexpected diff status %c"
 msgstr "trạng thái lệnh diff không như mong đợi %c"
 
-#: builtin/add.c:88 builtin/commit.c:257
+#: builtin/add.c:88 builtin/commit.c:266
 msgid "updating files failed"
 msgstr "Cập nhật tập tin gặp lỗi"
 
@@ -5044,7 +5410,7 @@ msgid "Unstaged changes after refreshing the index:"
 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:"
 
-#: builtin/add.c:233 builtin/rev-parse.c:888
+#: builtin/add.c:233 builtin/rev-parse.c:892
 msgid "Could not read the index"
 msgstr "Không thể đọc bảng mục lục"
 
@@ -5075,83 +5441,83 @@ msgstr "Miếng vá trống rỗng. Nên bỏ qua."
 msgid "Could not apply '%s'"
 msgstr "Không thể áp dụng miếng vá “%s”"
 
-#: builtin/add.c:271
+#: builtin/add.c:269
 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ủa bạn:\n"
 
-#: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:146 builtin/mv.c:124
-#: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541
-#: builtin/remote.c:1333 builtin/rm.c:242 builtin/send-pack.c:164
+#: builtin/add.c:289 builtin/clean.c:911 builtin/fetch.c:145 builtin/mv.c:123
+#: builtin/prune-packed.c:55 builtin/pull.c:212 builtin/push.c:557
+#: builtin/remote.c:1342 builtin/rm.c:240 builtin/send-pack.c:165
 msgid "dry run"
 msgstr "chạy thử"
 
-#: builtin/add.c:294
+#: builtin/add.c:292
 msgid "interactive picking"
 msgstr "sửa bằng cách tương tác"
 
-#: builtin/add.c:295 builtin/checkout.c:1128 builtin/reset.c:302
+#: builtin/add.c:293 builtin/checkout.c:1135 builtin/reset.c:302
 msgid "select hunks interactively"
 msgstr "chọn “hunks” theo kiểu tương tác"
 
-#: builtin/add.c:296
+#: builtin/add.c:294
 msgid "edit current diff and apply"
 msgstr "sửa diff hiện nay và áp dụng nó"
 
-#: builtin/add.c:297
+#: builtin/add.c:295
 msgid "allow adding otherwise ignored files"
 msgstr "cho phép thêm các tập tin bị bỏ qua khác"
 
-#: builtin/add.c:298
+#: builtin/add.c:296
 msgid "update tracked files"
 msgstr "cập nhật các tập tin được theo dõi"
 
-#: builtin/add.c:299
+#: builtin/add.c:297
 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)"
 
-#: builtin/add.c:300
+#: builtin/add.c:298
 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"
 
-#: builtin/add.c:301
+#: builtin/add.c:299
 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"
 
-#: builtin/add.c:304
+#: builtin/add.c:302
 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)"
 
-#: builtin/add.c:306
+#: builtin/add.c:304
 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"
 
-#: builtin/add.c:307
+#: builtin/add.c:305
 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"
 
-#: builtin/add.c:308
+#: builtin/add.c:306
 msgid "check if - even missing - files are ignored in dry run"
 msgstr ""
 "kiểm tra xem - thậm chí thiếu - tập tin bị bỏ qua trong quá trình chạy thử"
 
-#: builtin/add.c:309 builtin/update-index.c:964
+#: builtin/add.c:307 builtin/update-index.c:974
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/add.c:309 builtin/update-index.c:965
+#: builtin/add.c:307 builtin/update-index.c:975
 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ê"
 
-#: builtin/add.c:311
+#: builtin/add.c:309
 msgid "warn when adding an embedded repository"
 msgstr "cảnh báo khi thêm một kho nhúng"
 
-#: builtin/add.c:326
+#: builtin/add.c:324
 #, c-format
 msgid ""
 "You've added another git repository inside your current repository.\n"
@@ -5182,47 +5548,47 @@ msgstr ""
 "\n"
 "Xem \"git help submodule\" để biết thêm chi tiết."
 
-#: builtin/add.c:354
+#: builtin/add.c:352
 #, c-format
 msgid "adding embedded git repository: %s"
 msgstr "thêm cần một kho git nhúng: %s"
 
-#: builtin/add.c:372
+#: builtin/add.c:370
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "Sử dụng tùy chọn -f nếu bạn thực sự muốn thêm chúng vào.\n"
 
-#: builtin/add.c:380
+#: builtin/add.c:378
 msgid "adding files failed"
 msgstr "thêm tập tin gặp lỗi"
 
-#: builtin/add.c:417
+#: builtin/add.c:416
 msgid "-A and -u are mutually incompatible"
 msgstr "-A và -u xung khắc nhau"
 
-#: builtin/add.c:424
+#: builtin/add.c:423
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr "Tùy chọn --ignore-missing chỉ có thể được dùng cùng với --dry-run"
 
-#: builtin/add.c:428
+#: builtin/add.c:427
 #, 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"
 
-#: builtin/add.c:443
+#: builtin/add.c:442
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "Không có gì được chỉ ra, không có gì được thêm vào.\n"
 
-#: builtin/add.c:444
+#: builtin/add.c:443
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "Có lẽ ý bạn là “git add .” phải không?\n"
 
-#: builtin/add.c:449 builtin/check-ignore.c:177 builtin/checkout.c:280
-#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316
+#: builtin/add.c:448 builtin/check-ignore.c:177 builtin/checkout.c:280
+#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:325
 #: builtin/diff-tree.c:114 builtin/mv.c:144 builtin/reset.c:241
-#: builtin/rm.c:271 builtin/submodule--helper.c:326
+#: builtin/rm.c:270 builtin/submodule--helper.c:328
 msgid "index file corrupt"
 msgstr "tập tin ghi bảng mục lục bị hỏng"
 
@@ -5274,7 +5640,7 @@ 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."
 
-#: builtin/am.c:1013 builtin/clone.c:405
+#: builtin/am.c:1013 builtin/clone.c:407
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "tạo thư mục \"%s\" gặp lỗi"
@@ -5283,7 +5649,7 @@ 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á."
 
-#: builtin/am.c:1148 builtin/commit.c:342
+#: builtin/am.c:1148 builtin/commit.c:351
 msgid "unable to write index file"
 msgstr "không thể ghi tập tin lưu mục lục"
 
@@ -5461,7 +5827,7 @@ 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"
 
 #: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57
-#: builtin/repack.c:182
+#: builtin/repack.c:192
 msgid "be quiet"
 msgstr "im lặng"
 
@@ -5504,16 +5870,17 @@ msgstr "cắt mọi thứ trước dòng scissors"
 msgid "pass it through git-apply"
 msgstr "chuyển nó qua git-apply"
 
-#: builtin/am.c:2260 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668
-#: builtin/grep.c:853 builtin/merge.c:206 builtin/pull.c:145 builtin/pull.c:203
-#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197
-#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:382
-#: parse-options.h:144 parse-options.h:146 parse-options.h:257
+#: builtin/am.c:2260 builtin/commit.c:1332 builtin/fmt-merge-msg.c:665
+#: builtin/fmt-merge-msg.c:668 builtin/grep.c:853 builtin/merge.c:208
+#: builtin/pull.c:150 builtin/pull.c:208 builtin/repack.c:201
+#: builtin/repack.c:205 builtin/repack.c:207 builtin/show-branch.c:631
+#: builtin/show-ref.c:169 builtin/tag.c:383 parse-options.h:144
+#: parse-options.h:146 parse-options.h:258
 msgid "n"
 msgstr "n"
 
-#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38
-#: builtin/replace.c:445 builtin/tag.c:418 builtin/verify-tag.c:39
+#: builtin/am.c:2266 builtin/branch.c:632 builtin/for-each-ref.c:38
+#: builtin/replace.c:543 builtin/tag.c:419 builtin/verify-tag.c:39
 msgid "format"
 msgstr "định dạng"
 
@@ -5557,8 +5924,8 @@ msgstr "nói dối về ngày chuyển giao"
 msgid "use current timestamp for author date"
 msgstr "dùng dấu thời gian hiện tại cho ngày tác giả"
 
-#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237
-#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:398
+#: builtin/am.c:2298 builtin/commit.c:1468 builtin/merge.c:239
+#: builtin/pull.c:183 builtin/revert.c:112 builtin/tag.c:399
 msgid "key-id"
 msgstr "mã-số-khóa"
 
@@ -5698,117 +6065,143 @@ msgstr "--write-terms cần hai tham số"
 msgid "--bisect-clean-state requires no arguments"
 msgstr "--bisect-clean-state không nhận đối số"
 
-#: builtin/blame.c:27
+#: builtin/blame.c:29
 msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
 msgstr "git blame [<các-tùy-chọn>] [<rev-opts>] [<rev>] [--] <tập-tin>"
 
-#: builtin/blame.c:32
+#: builtin/blame.c:34
 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)"
 
-#: builtin/blame.c:677
+#: builtin/blame.c:404
+#, c-format
+msgid "expecting a color: %s"
+msgstr "cần một màu: %s"
+
+#: builtin/blame.c:411
+msgid "must end with a color"
+msgstr "phải kết thúc bằng một màu"
+
+#: builtin/blame.c:697
+#, c-format
+msgid "invalid color '%s' in color.blame.repeatedLines"
+msgstr "màu không hợp lệ “%s” trong color.blame.repeatedLines"
+
+#: builtin/blame.c:715
+msgid "invalid value for blame.coloring"
+msgstr "màu không hợp lệ cho blame.coloring"
+
+#: builtin/blame.c:786
 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"
 
-#: builtin/blame.c:678
+#: builtin/blame.c:787
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr ""
 "Hiển thị SHA-1 trắng cho những lần chuyển giao biên giới (Mặc định: off)"
 
-#: builtin/blame.c:679
+#: builtin/blame.c:788
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr "Không coi các lần chuyển giao gốc là giới hạn (Mặc định: off)"
 
-#: builtin/blame.c:680
+#: builtin/blame.c:789
 msgid "Show work cost statistics"
 msgstr "Hiển thị thống kê công sức làm việc"
 
-#: builtin/blame.c:681
+#: builtin/blame.c:790
 msgid "Force progress reporting"
 msgstr "Ép buộc báo cáo tiến triển công việc"
 
-#: builtin/blame.c:682
+#: builtin/blame.c:791
 msgid "Show output score for blame entries"
 msgstr "Hiển thị kết xuất điểm số có các mục tin “blame”"
 
-#: builtin/blame.c:683
+#: builtin/blame.c:792
 msgid "Show original filename (Default: auto)"
 msgstr "Hiển thị tên tập tin gốc (Mặc định: auto)"
 
-#: builtin/blame.c:684
+#: builtin/blame.c:793
 msgid "Show original linenumber (Default: off)"
 msgstr "Hiển thị số dòng gốc (Mặc định: off)"
 
-#: builtin/blame.c:685
+#: builtin/blame.c:794
 msgid "Show in a format designed for machine consumption"
 msgstr "Hiển thị ở định dạng đã thiết kế cho sự tiêu dùng bằng máy"
 
-#: builtin/blame.c:686
+#: builtin/blame.c:795
 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"
 
-#: builtin/blame.c:687
+#: builtin/blame.c:796
 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)"
 
-#: builtin/blame.c:688
+#: builtin/blame.c:797
 msgid "Show raw timestamp (Default: off)"
 msgstr "Hiển thị dấu vết thời gian dạng thô (Mặc định: off)"
 
-#: builtin/blame.c:689
+#: builtin/blame.c:798
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "Hiển thị SHA1 của lần chuyển giao dạng dài (Mặc định: off)"
 
-#: builtin/blame.c:690
+#: builtin/blame.c:799
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "Không hiển thị tên tác giả và dấu vết thời gian (Mặc định: off)"
 
-#: builtin/blame.c:691
+#: builtin/blame.c:800
 msgid "Show author email instead of name (Default: off)"
 msgstr "Hiển thị thư điện tử của tác giả thay vì tên (Mặc định: off)"
 
-#: builtin/blame.c:692
+#: builtin/blame.c:801
 msgid "Ignore whitespace differences"
 msgstr "Bỏ qua các khác biệt do khoảng trắng gây ra"
 
-#: builtin/blame.c:699
+#: builtin/blame.c:802
+msgid "color redundant metadata from previous line differently"
+msgstr "siêu dữ liệu dư thừa màu từ dòng trước khác hẳn"
+
+#: builtin/blame.c:803
+msgid "color lines by age"
+msgstr "các dòng màu theo tuổi"
+
+#: builtin/blame.c:810
 msgid "Use an experimental heuristic to improve diffs"
 msgstr "Dùng một phỏng đoán thử nghiệm để tăng cường các diff"
 
-#: builtin/blame.c:701
+#: builtin/blame.c:812
 msgid "Spend extra cycles to find better match"
 msgstr "Tiêu thụ thêm năng tài nguyên máy móc để tìm kiếm tốt hơn nữa"
 
-#: builtin/blame.c:702
+#: builtin/blame.c:813
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr ""
 "Sử dụng điểm xét duyệt (revision) từ <tập tin> thay vì gọi “git-rev-list”"
 
-#: builtin/blame.c:703
+#: builtin/blame.c:814
 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"
 
-#: builtin/blame.c:704 builtin/blame.c:705
+#: builtin/blame.c:815 builtin/blame.c:816
 msgid "score"
 msgstr "điểm số"
 
-#: builtin/blame.c:704
+#: builtin/blame.c:815
 msgid "Find line copies within and across files"
 msgstr "Tìm các bản sao chép dòng trong và ngang qua tập tin"
 
-#: builtin/blame.c:705
+#: builtin/blame.c:816
 msgid "Find line movements within and across files"
 msgstr "Tìm các di chuyển dòng trong và ngang qua tập tin"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "Process only line range n,m, counting from 1"
 msgstr "Xử lý chỉ dòng vùng n,m, tính từ 1"
 
-#: builtin/blame.c:753
+#: builtin/blame.c:866
 msgid "--progress can't be used with --incremental or porcelain formats"
 msgstr ""
 "--progress không được dùng cùng với --incremental hay các định dạng porcelain"
@@ -5821,17 +6214,17 @@ msgstr ""
 #. your language may need more or fewer display
 #. columns.
 #.
-#: builtin/blame.c:804
+#: builtin/blame.c:917
 msgid "4 years, 11 months ago"
 msgstr "4 năm, 11 tháng trước"
 
-#: builtin/blame.c:890
+#: builtin/blame.c:1003
 #, c-format
 msgid "file %s has only %lu line"
 msgid_plural "file %s has only %lu lines"
 msgstr[0] "tập tin %s chỉ có %lu dòng"
 
-#: builtin/blame.c:936
+#: builtin/blame.c:1049
 msgid "Blaming lines"
 msgstr "Các dòng blame"
 
@@ -5942,65 +6335,65 @@ msgstr "Đã xóa nhánh theo dõi máy chủ \"%s\" (từng là %s).\n"
 msgid "Deleted branch %s (was %s).\n"
 msgstr "Nhánh “%s” đã bị xóa (từng là %s)\n"
 
-#: builtin/branch.c:417 builtin/tag.c:58
+#: builtin/branch.c:416 builtin/tag.c:58
 msgid "unable to parse format string"
 msgstr "không thể phân tích chuỗi định dạng"
 
-#: builtin/branch.c:450
+#: builtin/branch.c:453
 #, c-format
 msgid "Branch %s is being rebased at %s"
 msgstr "Nhánh %s đang được cải tổ lại tại %s"
 
-#: builtin/branch.c:454
+#: builtin/branch.c:457
 #, 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"
 
-#: builtin/branch.c:471
+#: builtin/branch.c:474
 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ả."
 
-#: builtin/branch.c:473
+#: builtin/branch.c:476
 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ả."
 
-#: builtin/branch.c:484
+#: builtin/branch.c:487
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "Tên nhánh không hợp lệ: “%s”"
 
-#: builtin/branch.c:511
+#: builtin/branch.c:514
 msgid "Branch rename failed"
 msgstr "Gặp lỗi khi đổi tên nhánh"
 
-#: builtin/branch.c:513
+#: builtin/branch.c:516
 msgid "Branch copy failed"
 msgstr "Gặp lỗi khi sao chép nhánh"
 
-#: builtin/branch.c:517
+#: builtin/branch.c:520
 #, 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”"
 
-#: builtin/branch.c:520
+#: builtin/branch.c:523
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "Đã đổi tên nhánh khuyết danh “%s” đi"
 
-#: builtin/branch.c:526
+#: builtin/branch.c:529
 #, 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!"
 
-#: builtin/branch.c:535
+#: builtin/branch.c:538
 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"
 
-#: builtin/branch.c:537
+#: builtin/branch.c:540
 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"
 
-#: builtin/branch.c:553
+#: builtin/branch.c:556
 #, c-format
 msgid ""
 "Please edit the description for the branch\n"
@@ -6011,184 +6404,186 @@ msgstr ""
 "  %s\n"
 "Những dòng được bắt đầu bằng “%c” sẽ được cắt bỏ.\n"
 
-#: builtin/branch.c:586
+#: builtin/branch.c:589
 msgid "Generic options"
 msgstr "Tùy chọn chung"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:591
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "hiển thị mã băm và chủ đề, đưa ra hai lần cho nhánh thượng nguồn"
 
-#: builtin/branch.c:589
+#: builtin/branch.c:592
 msgid "suppress informational messages"
 msgstr "không xuất các thông tin"
 
-#: builtin/branch.c:590
+#: builtin/branch.c:593
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "cài đặt chế độ theo dõi (xem git-pull(1))"
 
-#: builtin/branch.c:592
+#: builtin/branch.c:595
 msgid "do not use"
 msgstr "không dùng"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "upstream"
 msgstr "thượng nguồn"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "change the upstream info"
 msgstr "thay đổi thông tin thượng nguồn"
 
-#: builtin/branch.c:595
+#: builtin/branch.c:598
 msgid "Unset the upstream info"
 msgstr "Bỏ đặt thông tin thượng nguồn"
 
-#: builtin/branch.c:596
+#: builtin/branch.c:599
 msgid "use colored output"
 msgstr "tô màu kết xuất"
 
-#: builtin/branch.c:597
+#: builtin/branch.c:600
 msgid "act on remote-tracking branches"
 msgstr "thao tác trên nhánh “remote-tracking”"
 
-#: builtin/branch.c:599 builtin/branch.c:601
+#: builtin/branch.c:602 builtin/branch.c:604
 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"
 
-#: builtin/branch.c:600 builtin/branch.c:602
+#: builtin/branch.c:603 builtin/branch.c:605
 msgid "print only branches that don't contain the commit"
 msgstr "chỉ hiển thị những nhánh mà nó không chứa lần chuyển giao"
 
-#: builtin/branch.c:605
+#: builtin/branch.c:608
 msgid "Specific git-branch actions:"
 msgstr "Hành động git-branch:"
 
-#: builtin/branch.c:606
+#: builtin/branch.c:609
 msgid "list both remote-tracking and local branches"
 msgstr "liệt kê cả nhánh “remote-tracking” và nội bộ"
 
-#: builtin/branch.c:608
+#: builtin/branch.c:611
 msgid "delete fully merged branch"
 msgstr "xóa một toàn bộ nhánh đã hòa trộn"
 
-#: builtin/branch.c:609
+#: builtin/branch.c:612
 msgid "delete branch (even if not merged)"
 msgstr "xóa nhánh (cho dù là chưa được hòa trộn)"
 
-#: builtin/branch.c:610
+#: builtin/branch.c:613
 msgid "move/rename a branch and its reflog"
 msgstr "di chuyển hay đổi tên một nhánh và reflog của nó"
 
-#: builtin/branch.c:611
+#: builtin/branch.c:614
 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"
 
-#: builtin/branch.c:612
+#: builtin/branch.c:615
 msgid "copy a branch and its reflog"
 msgstr "sao chép một nhánh và reflog của nó"
 
-#: builtin/branch.c:613
+#: builtin/branch.c:616
 msgid "copy a branch, even if target exists"
 msgstr "sao chép một nhánh ngay cả khi đích đã có sẵn"
 
-#: builtin/branch.c:614
+#: builtin/branch.c:617
 msgid "list branch names"
 msgstr "liệt kê các tên nhánh"
 
-#: builtin/branch.c:615
+#: builtin/branch.c:618
 msgid "create the branch's reflog"
 msgstr "tạo reflog của nhánh"
 
-#: builtin/branch.c:617
+#: builtin/branch.c:620
 msgid "edit the description for the branch"
 msgstr "sửa mô tả cho nhánh"
 
-#: builtin/branch.c:618
+#: builtin/branch.c:621
 msgid "force creation, move/rename, deletion"
 msgstr "buộc tạo, di chuyển/đổi tên, xóa"
 
-#: builtin/branch.c:619
+#: builtin/branch.c:622
 msgid "print only branches that are merged"
 msgstr "chỉ hiển thị những nhánh mà nó được hòa trộn"
 
-#: builtin/branch.c:620
+#: builtin/branch.c:623
 msgid "print only branches that are not merged"
 msgstr "chỉ hiển thị những nhánh mà nó không được hòa trộn"
 
-#: builtin/branch.c:621
+#: builtin/branch.c:624
 msgid "list branches in columns"
 msgstr "liệt kê các nhánh trong các cột"
 
-#: builtin/branch.c:622 builtin/for-each-ref.c:40 builtin/tag.c:411
+#: builtin/branch.c:625 builtin/for-each-ref.c:40 builtin/ls-remote.c:70
+#: builtin/tag.c:412
 msgid "key"
 msgstr "khóa"
 
-#: builtin/branch.c:623 builtin/for-each-ref.c:41 builtin/tag.c:412
+#: builtin/branch.c:626 builtin/for-each-ref.c:41 builtin/ls-remote.c:71
+#: builtin/tag.c:413
 msgid "field name to sort on"
 msgstr "tên trường cần sắp xếp"
 
-#: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408
+#: builtin/branch.c:628 builtin/for-each-ref.c:43 builtin/notes.c:408
 #: builtin/notes.c:411 builtin/notes.c:571 builtin/notes.c:574
-#: builtin/tag.c:414
+#: builtin/tag.c:415
 msgid "object"
 msgstr "đối tượng"
 
-#: builtin/branch.c:626
+#: builtin/branch.c:629
 msgid "print only branches of the object"
 msgstr "chỉ hiển thị các nhánh của đối tượng"
 
-#: builtin/branch.c:628 builtin/for-each-ref.c:49 builtin/tag.c:421
+#: builtin/branch.c:631 builtin/for-each-ref.c:49 builtin/tag.c:422
 msgid "sorting and filtering are case insensitive"
 msgstr "sắp xếp và lọc là phân biệt HOA thường"
 
-#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419
+#: builtin/branch.c:632 builtin/for-each-ref.c:38 builtin/tag.c:420
 #: builtin/verify-tag.c:39
 msgid "format to use for the output"
 msgstr "định dạng sẽ dùng cho đầu ra"
 
-#: builtin/branch.c:652 builtin/clone.c:735
+#: builtin/branch.c:655 builtin/clone.c:737
 msgid "HEAD not found below refs/heads!"
 msgstr "không tìm thấy HEAD ở dưới refs/heads!"
 
-#: builtin/branch.c:675
+#: builtin/branch.c:678
 msgid "--column and --verbose are incompatible"
 msgstr "tùy chọn --column và --verbose xung khắc nhau"
 
-#: builtin/branch.c:690 builtin/branch.c:742 builtin/branch.c:751
+#: builtin/branch.c:693 builtin/branch.c:745 builtin/branch.c:754
 msgid "branch name required"
 msgstr "cần chỉ ra tên nhánh"
 
-#: builtin/branch.c:718
+#: builtin/branch.c:721
 msgid "Cannot give description to detached HEAD"
 msgstr "Không thể đưa ra mô tả HEAD đã tách rời"
 
-#: builtin/branch.c:723
+#: builtin/branch.c:726
 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"
 
-#: builtin/branch.c:730
+#: builtin/branch.c:733
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "Vẫn chưa chuyển giao trên nhánh “%s”."
 
-#: builtin/branch.c:733
+#: builtin/branch.c:736
 #, c-format
 msgid "No branch named '%s'."
 msgstr "Không có nhánh nào có tên “%s”."
 
-#: builtin/branch.c:748
+#: builtin/branch.c:751
 msgid "too many branches for a copy operation"
 msgstr "quá nhiều nhánh dành cho thao tác sao chép"
 
-#: builtin/branch.c:757
+#: builtin/branch.c:760
 msgid "too many arguments for a rename operation"
 msgstr "quá nhiều tham số cho thao tác đổi tên"
 
-#: builtin/branch.c:762
+#: builtin/branch.c:765
 msgid "too many arguments to set new upstream"
 msgstr "quá nhiều tham số để đặt thượng nguồn mới"
 
-#: builtin/branch.c:766
+#: builtin/branch.c:769
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
@@ -6196,36 +6591,36 @@ 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ả."
 
-#: builtin/branch.c:769 builtin/branch.c:791 builtin/branch.c:807
+#: builtin/branch.c:772 builtin/branch.c:794 builtin/branch.c:810
 #, c-format
 msgid "no such branch '%s'"
 msgstr "không có nhánh nào như thế “%s”"
 
-#: builtin/branch.c:773
+#: builtin/branch.c:776
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "chưa có nhánh “%s”"
 
-#: builtin/branch.c:785
+#: builtin/branch.c:788
 msgid "too many arguments to unset upstream"
 msgstr "quá nhiều tham số để bỏ đặt thượng nguồn"
 
-#: builtin/branch.c:789
+#: builtin/branch.c:792
 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ả."
 
-#: builtin/branch.c:795
+#: builtin/branch.c:798
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "Nhánh “%s” không có thông tin thượng nguồn"
 
-#: builtin/branch.c:810
+#: builtin/branch.c:813
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr ""
 "hai tùy chọn -a và -r áp dụng cho lệnh “git branch” không hợp lý đối với tên "
 "nhánh"
 
-#: builtin/branch.c:813
+#: builtin/branch.c:816
 msgid ""
 "the '--set-upstream' option is no longer supported. Please use '--track' or "
 "'--set-upstream-to' instead."
@@ -6246,7 +6641,7 @@ msgstr "Cần một kho chứa để có thể tạo một bundle."
 msgid "Need a repository to unbundle."
 msgstr "Cần một kho chứa để có thể giải nén một bundle."
 
-#: builtin/cat-file.c:523
+#: builtin/cat-file.c:525
 msgid ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <type> | --textconv | --filters) [--path=<path>] <object>"
@@ -6254,7 +6649,7 @@ 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>"
 
-#: builtin/cat-file.c:524
+#: builtin/cat-file.c:526
 msgid ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
@@ -6262,64 +6657,64 @@ msgstr ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
 
-#: builtin/cat-file.c:561
+#: builtin/cat-file.c:563
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<kiểu> là một trong số: blob, tree, commit hoặc tag"
 
-#: builtin/cat-file.c:562
+#: builtin/cat-file.c:564
 msgid "show object type"
 msgstr "hiển thị kiểu đối tượng"
 
-#: builtin/cat-file.c:563
+#: builtin/cat-file.c:565
 msgid "show object size"
 msgstr "hiển thị kích thước đối tượng"
 
-#: builtin/cat-file.c:565
+#: builtin/cat-file.c:567
 msgid "exit with zero when there's no error"
 msgstr "thoát với 0 khi không có lỗi"
 
-#: builtin/cat-file.c:566
+#: builtin/cat-file.c:568
 msgid "pretty-print object's content"
 msgstr "in nội dung đối tượng dạng dễ đọc"
 
-#: builtin/cat-file.c:568
+#: builtin/cat-file.c:570
 msgid "for blob objects, run textconv on object's content"
 msgstr "với đối tượng blob, chạy lệnh textconv trên nội dung của đối tượng"
 
-#: builtin/cat-file.c:570
+#: builtin/cat-file.c:572
 msgid "for blob objects, run filters on object's content"
 msgstr "với đối tượng blob, chạy lệnh filters trên nội dung của đối tượng"
 
-#: builtin/cat-file.c:571 git-submodule.sh:878
+#: builtin/cat-file.c:573 git-submodule.sh:894
 msgid "blob"
 msgstr "blob"
 
-#: builtin/cat-file.c:572
+#: builtin/cat-file.c:574
 msgid "use a specific path for --textconv/--filters"
 msgstr "dùng một đường dẫn rõ ràng cho --textconv/--filters"
 
-#: builtin/cat-file.c:574
+#: builtin/cat-file.c:576
 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"
 
-#: builtin/cat-file.c:575
+#: builtin/cat-file.c:577
 msgid "buffer --batch output"
 msgstr "đệm kết xuất --batch"
 
-#: builtin/cat-file.c:577
+#: builtin/cat-file.c:579
 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"
 
-#: builtin/cat-file.c:580
+#: builtin/cat-file.c:582
 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"
 
-#: builtin/cat-file.c:583
+#: builtin/cat-file.c:585
 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)"
 
-#: builtin/cat-file.c:585
+#: builtin/cat-file.c:587
 msgid "show all objects with --batch or --batch-check"
 msgstr "hiển thị mọi đối tượng với --batch hay --batch-check"
 
@@ -6347,7 +6742,7 @@ msgstr "đọc tên tập tin từ đầu vào tiêu chuẩn"
 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"
 
-#: builtin/check-ignore.c:20 builtin/checkout.c:1106 builtin/gc.c:358
+#: builtin/check-ignore.c:20 builtin/checkout.c:1113 builtin/gc.c:500
 msgid "suppress progress reporting"
 msgstr "chặn các báo cáo tiến trình hoạt động"
 
@@ -6438,9 +6833,9 @@ msgid "write the content to temporary files"
 msgstr "ghi nội dung vào tập tin tạm"
 
 #: builtin/checkout-index.c:173 builtin/column.c:31
-#: builtin/submodule--helper.c:1203 builtin/submodule--helper.c:1206
-#: builtin/submodule--helper.c:1212 builtin/submodule--helper.c:1574
-#: builtin/worktree.c:570
+#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1219
+#: builtin/submodule--helper.c:1227 builtin/submodule--helper.c:1591
+#: builtin/worktree.c:610
 msgid "string"
 msgstr "chuỗi"
 
@@ -6512,54 +6907,54 @@ msgstr ""
 msgid "path '%s' is unmerged"
 msgstr "đường dẫn “%s” không được hòa trộn"
 
-#: builtin/checkout.c:505
+#: builtin/checkout.c:506
 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 đã"
 
-#: builtin/checkout.c:636
+#: builtin/checkout.c:643
 #, c-format
 msgid "Can not do reflog for '%s': %s\n"
 msgstr "Không thể thực hiện reflog cho “%s”: %s\n"
 
-#: builtin/checkout.c:677
+#: builtin/checkout.c:684
 msgid "HEAD is now at"
 msgstr "HEAD hiện giờ tại"
 
-#: builtin/checkout.c:681 builtin/clone.c:689
+#: builtin/checkout.c:688 builtin/clone.c:691
 msgid "unable to update HEAD"
 msgstr "không thể cập nhật HEAD"
 
-#: builtin/checkout.c:685
+#: builtin/checkout.c:692
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "Đặt lại nhánh “%s”\n"
 
-#: builtin/checkout.c:688
+#: builtin/checkout.c:695
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "Đã sẵn sàng trên “%s”\n"
 
-#: builtin/checkout.c:692
+#: builtin/checkout.c:699
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "Đã chuyển tới và đặt lại nhánh “%s”\n"
 
-#: builtin/checkout.c:694 builtin/checkout.c:1039
+#: builtin/checkout.c:701 builtin/checkout.c:1046
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "Đã chuyển đến nhánh mới “%s”\n"
 
-#: builtin/checkout.c:696
+#: builtin/checkout.c:703
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "Đã chuyển đến nhánh “%s”\n"
 
-#: builtin/checkout.c:747
+#: builtin/checkout.c:754
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " … và nhiều hơn %d.\n"
 
-#: builtin/checkout.c:753
+#: builtin/checkout.c:760
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -6578,7 +6973,7 @@ msgstr[0] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:772
+#: builtin/checkout.c:779
 #, c-format
 msgid ""
 "If you want to keep it by creating a new branch, this may be a good time\n"
@@ -6599,164 +6994,164 @@ msgstr[0] ""
 " git branch <tên_nhánh_mới> %s\n"
 "\n"
 
-#: builtin/checkout.c:804
+#: builtin/checkout.c:811
 msgid "internal error in revision walk"
 msgstr "lỗi nội bộ trong khi di chuyển qua các điểm xét duyệt"
 
-#: builtin/checkout.c:808
+#: builtin/checkout.c:815
 msgid "Previous HEAD position was"
 msgstr "Vị trí trước kia của HEAD là"
 
-#: builtin/checkout.c:836 builtin/checkout.c:1034
+#: builtin/checkout.c:843 builtin/checkout.c:1041
 msgid "You are on a branch yet to be born"
 msgstr "Bạn tại nhánh mà nó chưa hề được sinh ra"
 
-#: builtin/checkout.c:940
+#: builtin/checkout.c:947
 #, c-format
 msgid "only one reference expected, %d given."
 msgstr "chỉ cần một tham chiếu, nhưng lại đưa ra %d."
 
-#: builtin/checkout.c:980 builtin/worktree.c:249
+#: builtin/checkout.c:987 builtin/worktree.c:240 builtin/worktree.c:389
 #, c-format
 msgid "invalid reference: %s"
 msgstr "tham chiếu không hợp lệ: %s"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1016
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "tham chiếu không phải là một cây:%s"
 
-#: builtin/checkout.c:1048
+#: builtin/checkout.c:1055
 msgid "paths cannot be used with switching branches"
 msgstr "các đường dẫn không thể dùng cùng với các nhánh chuyển"
 
-#: builtin/checkout.c:1051 builtin/checkout.c:1055
+#: builtin/checkout.c:1058 builtin/checkout.c:1062
 #, 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"
 
-#: builtin/checkout.c:1059 builtin/checkout.c:1062 builtin/checkout.c:1067
-#: builtin/checkout.c:1070
+#: builtin/checkout.c:1066 builtin/checkout.c:1069 builtin/checkout.c:1074
+#: builtin/checkout.c:1077
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "“%s” không thể được dùng với “%s”"
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1082
 #, 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”"
 
-#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116
-#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:387
-#: builtin/worktree.c:389
+#: builtin/checkout.c:1114 builtin/checkout.c:1116 builtin/clone.c:118
+#: builtin/remote.c:167 builtin/remote.c:169 builtin/worktree.c:433
+#: builtin/worktree.c:435
 msgid "branch"
 msgstr "nhánh"
 
-#: builtin/checkout.c:1108
+#: builtin/checkout.c:1115
 msgid "create and checkout a new branch"
 msgstr "tạo và checkout một nhánh mới"
 
-#: builtin/checkout.c:1110
+#: builtin/checkout.c:1117
 msgid "create/reset and checkout a branch"
 msgstr "tạo/đặt_lại và checkout một nhánh"
 
-#: builtin/checkout.c:1111
+#: builtin/checkout.c:1118
 msgid "create reflog for new branch"
 msgstr "tạo reflog cho nhánh mới"
 
-#: builtin/checkout.c:1112 builtin/worktree.c:391
+#: builtin/checkout.c:1119 builtin/worktree.c:437
 msgid "detach HEAD at named commit"
 msgstr "rời bỏ HEAD tại lần chuyển giao theo tên"
 
-#: builtin/checkout.c:1113
+#: builtin/checkout.c:1120
 msgid "set upstream info for new branch"
 msgstr "đặt thông tin thượng nguồn cho nhánh mới"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new-branch"
 msgstr "nhánh-mới"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new unparented branch"
 msgstr "nhánh không cha mới"
 
-#: builtin/checkout.c:1116
+#: builtin/checkout.c:1123
 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"
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1125
 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"
 
-#: builtin/checkout.c:1120
+#: builtin/checkout.c:1127
 msgid "force checkout (throw away local modifications)"
 msgstr "ép buộc lấy ra (bỏ đi những thay đổi nội bộ)"
 
-#: builtin/checkout.c:1122
+#: builtin/checkout.c:1129
 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"
 
-#: builtin/checkout.c:1124 builtin/merge.c:239
+#: builtin/checkout.c:1131 builtin/merge.c:241
 msgid "update ignored files (default)"
 msgstr "cập nhật các tập tin bị bỏ qua (mặc định)"
 
-#: builtin/checkout.c:1126 builtin/log.c:1499 parse-options.h:263
+#: builtin/checkout.c:1133 builtin/log.c:1499 parse-options.h:264
 msgid "style"
 msgstr "kiểu"
 
-#: builtin/checkout.c:1127
+#: builtin/checkout.c:1134
 msgid "conflict style (merge or diff3)"
 msgstr "xung đột kiểu (hòa trộn hoặc diff3)"
 
-#: builtin/checkout.c:1130
+#: builtin/checkout.c:1137
 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 thưa thớt"
 
-#: builtin/checkout.c:1132
+#: builtin/checkout.c:1139
 msgid "second guess 'git checkout <no-such-branch>'"
 msgstr "gợi ý thứ hai \"git checkout <không-nhánh-nào-như-vậy>\""
 
-#: builtin/checkout.c:1134
+#: builtin/checkout.c:1141
 msgid "do not check if another worktree is holding the given ref"
 msgstr "không kiểm tra nếu cây làm việc khác đang giữ tham chiếu đã cho"
 
-#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150
-#: builtin/merge.c:236 builtin/pull.c:123 builtin/push.c:556
-#: builtin/send-pack.c:173
+#: builtin/checkout.c:1145 builtin/clone.c:85 builtin/fetch.c:149
+#: builtin/merge.c:238 builtin/pull.c:128 builtin/push.c:572
+#: builtin/send-pack.c:174
 msgid "force progress reporting"
 msgstr "ép buộc báo cáo tiến triển công việc"
 
-#: builtin/checkout.c:1168
+#: builtin/checkout.c:1175
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "Các tùy chọn -b, -B và --orphan loại từ lẫn nhau"
 
-#: builtin/checkout.c:1185
+#: builtin/checkout.c:1192
 msgid "--track needs a branch name"
 msgstr "--track cần tên một nhánh"
 
-#: builtin/checkout.c:1190
+#: builtin/checkout.c:1197
 msgid "Missing branch name; try -b"
 msgstr "Thiếu tên nhánh; hãy thử -b"
 
-#: builtin/checkout.c:1226
+#: builtin/checkout.c:1233
 msgid "invalid path specification"
 msgstr "đường dẫn đã cho không hợp lệ"
 
-#: builtin/checkout.c:1233
+#: builtin/checkout.c:1240
 #, 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 "
 "từ đó"
 
-#: builtin/checkout.c:1237
+#: builtin/checkout.c:1244
 #, 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”"
 
-#: builtin/checkout.c:1241
+#: builtin/checkout.c:1248
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -6795,7 +7190,7 @@ msgstr "Nên bỏ qua kho chứa %s\n"
 msgid "failed to remove %s"
 msgstr "gặp lỗi khi gỡ bỏ %s"
 
-#: builtin/clean.c:302 git-add--interactive.perl:572
+#: builtin/clean.c:302 git-add--interactive.perl:579
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6808,7 +7203,7 @@ msgstr ""
 "foo        - chọn mục trên cơ sở tiền tố duy nhất\n"
 "           - (để trống) không chọn gì cả\n"
 
-#: builtin/clean.c:306 git-add--interactive.perl:581
+#: builtin/clean.c:306 git-add--interactive.perl:588
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6829,8 +7224,8 @@ msgstr ""
 "*          - chọn tất\n"
 "           - (để trống) kết thúc việc chọn\n"
 
-#: builtin/clean.c:522 git-add--interactive.perl:547
-#: git-add--interactive.perl:552
+#: builtin/clean.c:522 git-add--interactive.perl:554
+#: git-add--interactive.perl:559
 #, c-format, perl-format
 msgid "Huh (%s)?\n"
 msgstr "Hả (%s)?\n"
@@ -6855,7 +7250,7 @@ msgstr "Chọn mục muốn xóa"
 msgid "Remove %s [y/N]? "
 msgstr "Xóa bỏ “%s” [y/N]? "
 
-#: builtin/clean.c:788 git-add--interactive.perl:1710
+#: builtin/clean.c:788 git-add--interactive.perl:1717
 #, c-format
 msgid "Bye.\n"
 msgstr "Tạm biệt.\n"
@@ -6878,11 +7273,11 @@ msgstr ""
 "help                - hiển thị chính trợ giúp này\n"
 "?                   - trợ giúp dành cho chọn bằng cách nhắc"
 
-#: builtin/clean.c:823 git-add--interactive.perl:1786
+#: builtin/clean.c:823 git-add--interactive.perl:1793
 msgid "*** Commands ***"
 msgstr "*** Lệnh ***"
 
-#: builtin/clean.c:824 git-add--interactive.perl:1783
+#: builtin/clean.c:824 git-add--interactive.perl:1790
 msgid "What now"
 msgstr "Giờ thì sao"
 
@@ -6950,146 +7345,148 @@ 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)"
 
-#: builtin/clone.c:40
+#: builtin/clone.c:42
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<các-tùy-chọn>] [--] <kho> [<t.mục>]"
 
-#: builtin/clone.c:85
+#: builtin/clone.c:87
 msgid "don't create a checkout"
 msgstr "không tạo một checkout"
 
-#: builtin/clone.c:86 builtin/clone.c:88 builtin/init-db.c:479
+#: builtin/clone.c:88 builtin/clone.c:90 builtin/init-db.c:479
 msgid "create a bare repository"
 msgstr "tạo kho thuần"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:92
 msgid "create a mirror repository (implies bare)"
 msgstr "tạo kho bản sao (ý là kho thuần)"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:94
 msgid "to clone from a local repository"
 msgstr "để nhân bản từ kho nội bộ"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:96
 msgid "don't use local hardlinks, always copy"
 msgstr "không sử dụng liên kết cứng nội bộ, luôn sao chép"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:98
 msgid "setup as shared repository"
 msgstr "cài đặt đây là kho chia sẻ"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "pathspec"
 msgstr "đặc-tả-đường-dẫn"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "initialize submodules in the clone"
 msgstr "khởi tạo mô-đun-con trong bản sao"
 
-#: builtin/clone.c:105
+#: builtin/clone.c:107
 msgid "number of submodules cloned in parallel"
 msgstr "số lượng mô-đun-con được nhân bản đồng thời"
 
-#: builtin/clone.c:106 builtin/init-db.c:476
+#: builtin/clone.c:108 builtin/init-db.c:476
 msgid "template-directory"
 msgstr "thư-mục-mẫu"
 
-#: builtin/clone.c:107 builtin/init-db.c:477
+#: builtin/clone.c:109 builtin/init-db.c:477
 msgid "directory from which templates will be used"
 msgstr "thư mục mà tại đó các mẫu sẽ được dùng"
 
-#: builtin/clone.c:109 builtin/clone.c:111 builtin/submodule--helper.c:1210
-#: builtin/submodule--helper.c:1577
+#: builtin/clone.c:111 builtin/clone.c:113 builtin/submodule--helper.c:1223
+#: builtin/submodule--helper.c:1594
 msgid "reference repository"
 msgstr "kho tham chiếu"
 
-#: builtin/clone.c:113
+#: builtin/clone.c:115 builtin/submodule--helper.c:1225
+#: builtin/submodule--helper.c:1596
 msgid "use --reference only while cloning"
 msgstr "chỉ dùng --reference khi nhân bản"
 
-#: builtin/clone.c:114 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/clone.c:116 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/pack-objects.c:3166 builtin/repack.c:213
 msgid "name"
 msgstr "tên"
 
-#: builtin/clone.c:115
+#: builtin/clone.c:117
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "dùng <tên> thay cho “origin” để theo dõi thượng nguồn"
 
-#: builtin/clone.c:117
+#: builtin/clone.c:119
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "lấy ra <nhánh> thay cho HEAD của máy chủ"
 
-#: builtin/clone.c:119
+#: builtin/clone.c:121
 msgid "path to git-upload-pack on the remote"
 msgstr "đường dẫn đến git-upload-pack trên máy chủ"
 
-#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813
-#: builtin/pull.c:211
+#: builtin/clone.c:122 builtin/fetch.c:150 builtin/grep.c:813
+#: builtin/pull.c:216
 msgid "depth"
 msgstr "độ-sâu"
 
-#: builtin/clone.c:121
+#: builtin/clone.c:123
 msgid "create a shallow clone of that depth"
 msgstr "tạo bản sao không đầy đủ cho mức sâu đã cho"
 
-#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017
+#: builtin/clone.c:124 builtin/fetch.c:152 builtin/pack-objects.c:3157
 #: parse-options.h:154
 msgid "time"
 msgstr "thời-gian"
 
-#: builtin/clone.c:123
+#: builtin/clone.c:125
 msgid "create a shallow clone since a specific time"
 msgstr "tạo bản sao không đầy đủ từ thời điểm đã cho"
 
-#: builtin/clone.c:124 builtin/fetch.c:155
+#: builtin/clone.c:126 builtin/fetch.c:154
 msgid "revision"
 msgstr "điểm xét duyệt"
 
-#: builtin/clone.c:125 builtin/fetch.c:156
+#: builtin/clone.c:127 builtin/fetch.c:155
 msgid "deepen history of shallow clone, excluding rev"
 msgstr "làm sâu hơn lịch sử của bản sao shallow, bằng điểm xét duyệt loại trừ"
 
-#: builtin/clone.c:127
+#: builtin/clone.c:129
 msgid "clone only one branch, HEAD or --branch"
 msgstr "chỉ nhân bản một nhánh, HEAD hoặc --branch"
 
-#: builtin/clone.c:129
+#: builtin/clone.c:131
 msgid "don't clone any tags, and make later fetches not to follow them"
 msgstr ""
 "đứng có nhân bản bất kỳ nhánh nào, và làm cho những lần lấy về sau không "
 "theo chúng nữa"
 
-#: builtin/clone.c:131
+#: builtin/clone.c:133
 msgid "any cloned submodules will be shallow"
 msgstr "mọi mô-đun-con nhân bản sẽ là shallow (nông)"
 
-#: builtin/clone.c:132 builtin/init-db.c:485
+#: builtin/clone.c:134 builtin/init-db.c:485
 msgid "gitdir"
 msgstr "gitdir"
 
-#: builtin/clone.c:133 builtin/init-db.c:486
+#: builtin/clone.c:135 builtin/init-db.c:486
 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"
 
-#: builtin/clone.c:134
+#: builtin/clone.c:136
 msgid "key=value"
 msgstr "khóa=giá_trị"
 
-#: builtin/clone.c:135
+#: builtin/clone.c:137
 msgid "set config inside the new repository"
 msgstr "đặt cấu hình bên trong một kho chứa mới"
 
-#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224
-#: builtin/push.c:567
+#: builtin/clone.c:138 builtin/fetch.c:173 builtin/pull.c:229
+#: builtin/push.c:583
 msgid "use IPv4 addresses only"
 msgstr "chỉ dùng địa chỉ IPv4"
 
-#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227
-#: builtin/push.c:569
+#: builtin/clone.c:140 builtin/fetch.c:175 builtin/pull.c:232
+#: builtin/push.c:585
 msgid "use IPv6 addresses only"
 msgstr "chỉ dùng địa chỉ IPv6"
 
-#: builtin/clone.c:276
+#: builtin/clone.c:278
 msgid ""
 "No directory name could be guessed.\n"
 "Please specify a directory on the command line"
@@ -7097,42 +7494,42 @@ 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"
 
-#: builtin/clone.c:329
+#: builtin/clone.c:331
 #, 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"
 
-#: builtin/clone.c:401
+#: builtin/clone.c:403
 #, c-format
 msgid "failed to open '%s'"
 msgstr "gặp lỗi khi mở “%s”"
 
-#: builtin/clone.c:409
+#: builtin/clone.c:411
 #, 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"
 
-#: builtin/clone.c:423
+#: builtin/clone.c:425
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "gặp lỗi khi lấy thông tin thống kê về %s\n"
 
-#: builtin/clone.c:445
+#: builtin/clone.c:447
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "gặp lỗi khi tạo được liên kết mềm %s"
 
-#: builtin/clone.c:449
+#: builtin/clone.c:451
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "gặp lỗi khi sao chép tập tin và “%s”"
 
-#: builtin/clone.c:475
+#: builtin/clone.c:477
 #, c-format
 msgid "done.\n"
 msgstr "hoàn tất.\n"
 
-#: builtin/clone.c:489
+#: builtin/clone.c:491
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -7142,99 +7539,99 @@ msgstr ""
 "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 checkout -f HEAD”\n"
 
-#: builtin/clone.c:566
+#: builtin/clone.c:568
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "Không tìm thấy nhánh máy chủ %s để nhân bản (clone)."
 
-#: builtin/clone.c:661
+#: builtin/clone.c:663
 msgid "remote did not send all necessary objects"
 msgstr "máy chủ đã không gửi tất cả các đối tượng cần thiết"
 
-#: builtin/clone.c:677
+#: builtin/clone.c:679
 #, c-format
 msgid "unable to update %s"
 msgstr "không thể cập nhật %s"
 
-#: builtin/clone.c:726
+#: builtin/clone.c:728
 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"
 
-#: builtin/clone.c:756
+#: builtin/clone.c:758
 msgid "unable to checkout working tree"
 msgstr "không thể lấy ra (checkout) cây làm việc"
 
-#: builtin/clone.c:801
+#: builtin/clone.c:803
 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"
 
-#: builtin/clone.c:864
+#: builtin/clone.c:866
 msgid "cannot repack to clean up"
 msgstr "không thể đóng gói để dọn dẹp"
 
-#: builtin/clone.c:866
+#: builtin/clone.c:868
 msgid "cannot unlink temporary alternates file"
 msgstr "không thể bỏ liên kết tập tin thay thế tạm thời"
 
-#: builtin/clone.c:906 builtin/receive-pack.c:1946
+#: builtin/clone.c:907 builtin/receive-pack.c:1947
 msgid "Too many arguments."
 msgstr "Có quá nhiều đối số."
 
-#: builtin/clone.c:910
+#: builtin/clone.c:911
 msgid "You must specify a repository to clone."
 msgstr "Bạn phải chỉ định một kho để mà nhân bản (clone)."
 
-#: builtin/clone.c:923
+#: builtin/clone.c:924
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "tùy chọn --bare và --origin %s xung khắc nhau."
 
-#: builtin/clone.c:926
+#: builtin/clone.c:927
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "tùy chọn --bare và --separate-git-dir xung khắc nhau."
 
-#: builtin/clone.c:939
+#: builtin/clone.c:940
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "kho chứa “%s” chưa tồn tại"
 
-#: builtin/clone.c:945 builtin/fetch.c:1455
+#: builtin/clone.c:946 builtin/fetch.c:1460
 #, c-format
 msgid "depth %s is not a positive number"
 msgstr "độ sâu %s không phải là một số nguyên dương"
 
-#: builtin/clone.c:955
+#: builtin/clone.c:956
 #, 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."
 
-#: builtin/clone.c:965
+#: builtin/clone.c:966
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "cây làm việc “%s” đã sẵn tồn tại rồi."
 
-#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270
-#: builtin/worktree.c:255 builtin/worktree.c:285
+#: builtin/clone.c:981 builtin/clone.c:1002 builtin/difftool.c:270
+#: builtin/worktree.c:246 builtin/worktree.c:276
 #, 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”"
 
-#: builtin/clone.c:985
+#: builtin/clone.c:986
 #, 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”"
 
-#: builtin/clone.c:1005
+#: builtin/clone.c:1006
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "Đang nhân bản thành kho chứa bare “%s”…\n"
 
-#: builtin/clone.c:1007
+#: builtin/clone.c:1008
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "Đang nhân bản thành “%s”…\n"
 
-#: builtin/clone.c:1031
+#: builtin/clone.c:1032
 msgid ""
 "clone --recursive is not compatible with both --reference and --reference-if-"
 "able"
@@ -7308,7 +7705,7 @@ msgstr "Chèn thêm khoảng trắng vào bên phải"
 msgid "Padding space between columns"
 msgstr "Chèn thêm khoảng trắng giữa các cột"
 
-#: builtin/column.c:52
+#: builtin/column.c:51
 msgid "--command must be the first argument"
 msgstr "--command phải là đối số đầu tiên"
 
@@ -7368,63 +7765,63 @@ msgstr ""
 "Thế thì \"git cherry-pick --continue\" sẽ phục hồi lại việc cherry-pick\n"
 "những lần chuyển giao còn lại.\n"
 
-#: builtin/commit.c:284
+#: builtin/commit.c:293
 msgid "failed to unpack HEAD tree object"
 msgstr "gặp lỗi khi tháo dỡ HEAD đối tượng cây"
 
-#: builtin/commit.c:325
+#: builtin/commit.c:334
 msgid "unable to create temporary index"
 msgstr "không thể tạo bảng mục lục tạm thời"
 
-#: builtin/commit.c:331
+#: builtin/commit.c:340
 msgid "interactive add failed"
 msgstr "gặp lỗi khi thêm bằng cách tương"
 
-#: builtin/commit.c:344
+#: builtin/commit.c:353
 msgid "unable to update temporary index"
 msgstr "không thể cập nhật bảng mục lục tạm thời"
 
-#: builtin/commit.c:346
+#: builtin/commit.c:355
 msgid "Failed to update main cache tree"
 msgstr "Gặp lỗi khi cập nhật cây bộ nhớ đệm"
 
-#: builtin/commit.c:371 builtin/commit.c:395 builtin/commit.c:444
+#: builtin/commit.c:380 builtin/commit.c:403 builtin/commit.c:449
 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)"
 
-#: builtin/commit.c:427
+#: builtin/commit.c:432
 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."
 
-#: builtin/commit.c:429
+#: builtin/commit.c:434
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr ""
 "không thể thực hiện việc chuyển giao bộ phận trong khi đang cherry-pick."
 
-#: builtin/commit.c:437
+#: builtin/commit.c:442
 msgid "cannot read the index"
 msgstr "không đọc được bảng mục lục"
 
-#: builtin/commit.c:456
+#: builtin/commit.c:461
 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"
 
-#: builtin/commit.c:553
+#: builtin/commit.c:558
 #, c-format
 msgid "commit '%s' lacks author header"
 msgstr "lần chuyển giao “%s” thiếu phần tác giả ở đầu"
 
-#: builtin/commit.c:555
+#: builtin/commit.c:560
 #, 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"
 
-#: builtin/commit.c:574
+#: builtin/commit.c:579
 msgid "malformed --author parameter"
 msgstr "đối số cho --author bị dị hình"
 
-#: builtin/commit.c:626
+#: builtin/commit.c:631
 msgid ""
 "unable to select a comment character that is not used\n"
 "in the current commit message"
@@ -7432,38 +7829,38 @@ msgstr ""
 "không thể chọn một ký tự ghi chú cái mà không được dùng\n"
 "trong phần ghi chú hiện tại"
 
-#: builtin/commit.c:663 builtin/commit.c:696 builtin/commit.c:1024
+#: builtin/commit.c:668 builtin/commit.c:701 builtin/commit.c:1029
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "không thể tìm kiếm commit (lần chuyển giao) %s"
 
-#: builtin/commit.c:675 builtin/shortlog.c:309
+#: builtin/commit.c:680 builtin/shortlog.c:316
 #, 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"
 
-#: builtin/commit.c:677
+#: builtin/commit.c:682
 msgid "could not read log from standard input"
 msgstr "không thể đọc nhật ký từ đầu vào tiêu chuẩn"
 
-#: builtin/commit.c:681
+#: builtin/commit.c:686
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "không đọc được tệp nhật ký “%s”"
 
-#: builtin/commit.c:710 builtin/commit.c:718
+#: builtin/commit.c:715 builtin/commit.c:723
 msgid "could not read SQUASH_MSG"
 msgstr "không thể đọc SQUASH_MSG"
 
-#: builtin/commit.c:715
+#: builtin/commit.c:720
 msgid "could not read MERGE_MSG"
 msgstr "không thể đọc MERGE_MSG"
 
-#: builtin/commit.c:769
+#: builtin/commit.c:774
 msgid "could not write commit template"
 msgstr "không thể ghi mẫu chuyển giao"
 
-#: builtin/commit.c:787
+#: builtin/commit.c:792
 #, c-format
 msgid ""
 "\n"
@@ -7478,7 +7875,7 @@ msgstr ""
 "\t%s\n"
 "và thử lại.\n"
 
-#: builtin/commit.c:792
+#: builtin/commit.c:797
 #, c-format
 msgid ""
 "\n"
@@ -7493,7 +7890,7 @@ msgstr ""
 "\t%s\n"
 "và thử lại.\n"
 
-#: builtin/commit.c:805
+#: builtin/commit.c:810
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7504,7 +7901,7 @@ msgstr ""
 "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 "
 "chuyển giao.\n"
 
-#: builtin/commit.c:813
+#: builtin/commit.c:818
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7516,156 +7913,156 @@ msgstr ""
 "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"
 "Phần chú thích này nếu trống rỗng sẽ hủy bỏ lần chuyển giao.\n"
 
-#: builtin/commit.c:830
+#: builtin/commit.c:835
 #, c-format
 msgid "%sAuthor:    %.*s <%.*s>"
 msgstr "%sTác giả:           %.*s <%.*s>"
 
-#: builtin/commit.c:838
+#: builtin/commit.c:843
 #, c-format
 msgid "%sDate:      %s"
 msgstr "%sNgày tháng:        %s"
 
-#: builtin/commit.c:845
+#: builtin/commit.c:850
 #, c-format
 msgid "%sCommitter: %.*s <%.*s>"
 msgstr "%sNgười chuyển giao: %.*s <%.*s>"
 
-#: builtin/commit.c:862
+#: builtin/commit.c:867
 msgid "Cannot read index"
 msgstr "Không đọc được bảng mục lục"
 
-#: builtin/commit.c:928
+#: builtin/commit.c:933
 msgid "Error building trees"
 msgstr "Gặp lỗi khi xây dựng cây"
 
-#: builtin/commit.c:942 builtin/tag.c:256
+#: builtin/commit.c:947 builtin/tag.c:257
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "Xin hãy cung cấp lời chú giải hoặc là dùng tùy chọn -m hoặc là -F.\n"
 
-#: builtin/commit.c:986
+#: builtin/commit.c:991
 #, 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ó"
 
-#: builtin/commit.c:1000
+#: builtin/commit.c:1005
 #, c-format
 msgid "Invalid ignored mode '%s'"
 msgstr "Chế độ bỏ qua không hợp lệ “%s”"
 
-#: builtin/commit.c:1014 builtin/commit.c:1264
+#: builtin/commit.c:1019 builtin/commit.c:1269
 #, 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”"
 
-#: builtin/commit.c:1052
+#: builtin/commit.c:1057
 msgid "--long and -z are incompatible"
 msgstr "hai tùy chọn -long và -z không tương thích với nhau"
 
-#: builtin/commit.c:1085
+#: builtin/commit.c:1090
 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ý"
 
-#: builtin/commit.c:1094
+#: builtin/commit.c:1099
 msgid "You have nothing to amend."
 msgstr "Không có gì để mà “tu bổ” cả."
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1102
 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ổ”."
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1104
 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ổ”."
 
-#: builtin/commit.c:1102
+#: builtin/commit.c:1107
 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"
 
-#: builtin/commit.c:1112
+#: builtin/commit.c:1117
 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 tùy chọn -c/-C/-F/--fixup"
 
-#: builtin/commit.c:1114
+#: builtin/commit.c:1119
 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."
 
-#: builtin/commit.c:1122
+#: builtin/commit.c:1127
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr ""
 "--reset-author chỉ có thể được sử dụng với tùy chọn -C, -c hay --amend."
 
-#: builtin/commit.c:1139
+#: builtin/commit.c:1144
 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."
 
-#: builtin/commit.c:1141
+#: builtin/commit.c:1146
 msgid "No paths with --include/--only does not make sense."
 msgstr "Không đường dẫn với các tùy chọn --include/--only không hợp lý."
 
-#: builtin/commit.c:1155 builtin/tag.c:542
+#: builtin/commit.c:1160 builtin/tag.c:543
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "Chế độ dọn dẹp không hợp lệ %s"
 
-#: builtin/commit.c:1160
+#: builtin/commit.c:1165
 msgid "Paths with -a does not make sense."
 msgstr "Các đường dẫn với tùy chọn -a không hợp lý."
 
-#: builtin/commit.c:1278 builtin/commit.c:1443
+#: builtin/commit.c:1303 builtin/commit.c:1480
 msgid "show status concisely"
 msgstr "hiển thị trạng thái ở dạng súc tích"
 
-#: builtin/commit.c:1280 builtin/commit.c:1445
+#: builtin/commit.c:1305 builtin/commit.c:1482
 msgid "show branch information"
 msgstr "hiển thị thông tin nhánh"
 
-#: builtin/commit.c:1282
+#: builtin/commit.c:1307
 msgid "show stash information"
 msgstr "hiển thị thông tin về tạm cất"
 
-#: builtin/commit.c:1284 builtin/commit.c:1447
+#: builtin/commit.c:1309 builtin/commit.c:1484
 msgid "compute full ahead/behind values"
 msgstr "tính đầy đủ giá trị trước/sau"
 
-#: builtin/commit.c:1286
+#: builtin/commit.c:1311
 msgid "version"
 msgstr "phiên bản"
 
-#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542
-#: builtin/worktree.c:541
+#: builtin/commit.c:1311 builtin/commit.c:1486 builtin/push.c:558
+#: builtin/worktree.c:581
 msgid "machine-readable output"
 msgstr "kết xuất dạng máy-có-thể-đọc"
 
-#: builtin/commit.c:1289 builtin/commit.c:1451
+#: builtin/commit.c:1314 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "hiển thị trạng thái ở định dạng dài (mặc định)"
 
-#: builtin/commit.c:1292 builtin/commit.c:1454
+#: builtin/commit.c:1317 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "chấm dứt các mục bằng NUL"
 
-#: builtin/commit.c:1294 builtin/commit.c:1298 builtin/commit.c:1457
-#: builtin/fast-export.c:999 builtin/fast-export.c:1002 builtin/tag.c:396
+#: builtin/commit.c:1319 builtin/commit.c:1323 builtin/commit.c:1494
+#: builtin/fast-export.c:1001 builtin/fast-export.c:1004 builtin/tag.c:397
 msgid "mode"
 msgstr "chế độ"
 
-#: builtin/commit.c:1295 builtin/commit.c:1457
+#: builtin/commit.c:1320 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr ""
 "hiển thị các tập tin chưa được theo dõi  dấu vết, các chế độ tùy chọn:  all, "
 "normal, no. (Mặc định: all)"
 
-#: builtin/commit.c:1299
+#: builtin/commit.c:1324
 msgid ""
 "show ignored files, optional modes: traditional, matching, no. (Default: "
 "traditional)"
@@ -7673,11 +8070,11 @@ msgstr ""
 "hiển thị các tập tin bị bỏ qua, các chế độ tùy chọn: traditional, matching, "
 "no. (Mặc định: traditional)"
 
-#: builtin/commit.c:1301 parse-options.h:167
+#: builtin/commit.c:1326 parse-options.h:167
 msgid "when"
 msgstr "khi"
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1327
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
@@ -7685,190 +8082,198 @@ msgstr ""
 "bỏ qua các thay đổi trong mô-đun-con, tùy chọn khi: all, dirty, untracked. "
 "(Mặc định: all)"
 
-#: builtin/commit.c:1304
+#: builtin/commit.c:1329
 msgid "list untracked files in columns"
 msgstr "hiển thị danh sách các tập-tin chưa được theo dõi trong các cột"
 
-#: builtin/commit.c:1323
+#: builtin/commit.c:1330
+msgid "do not detect renames"
+msgstr "không dò tìm các tên thay đổi"
+
+#: builtin/commit.c:1332
+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ự"
+
+#: builtin/commit.c:1352
 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"
 
-#: builtin/commit.c:1413
+#: builtin/commit.c:1450
 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"
 
-#: builtin/commit.c:1414
+#: builtin/commit.c:1451
 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"
 
-#: builtin/commit.c:1416
+#: builtin/commit.c:1453
 msgid "Commit message options"
 msgstr "Các tùy chọn ghi chú commit"
 
-#: builtin/commit.c:1417 builtin/tag.c:393
+#: builtin/commit.c:1454 builtin/tag.c:394
 msgid "read message from file"
 msgstr "đọc chú thích từ tập tin"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "author"
 msgstr "tác giả"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "override author for commit"
 msgstr "ghi đè tác giả cho commit"
 
-#: builtin/commit.c:1419 builtin/gc.c:359
+#: builtin/commit.c:1456 builtin/gc.c:501
 msgid "date"
 msgstr "ngày tháng"
 
-#: builtin/commit.c:1419
+#: builtin/commit.c:1456
 msgid "override date for commit"
 msgstr "ghi đè ngày tháng cho lần chuyển giao"
 
-#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402
-#: builtin/notes.c:565 builtin/tag.c:391
+#: builtin/commit.c:1457 builtin/merge.c:228 builtin/notes.c:402
+#: builtin/notes.c:565 builtin/tag.c:392
 msgid "message"
 msgstr "chú thích"
 
-#: builtin/commit.c:1420
+#: builtin/commit.c:1457
 msgid "commit message"
 msgstr "chú thích của lần chuyển giao"
 
-#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423
-#: builtin/commit.c:1424 parse-options.h:269 ref-filter.h:92
+#: builtin/commit.c:1458 builtin/commit.c:1459 builtin/commit.c:1460
+#: builtin/commit.c:1461 parse-options.h:270 ref-filter.h:92
 msgid "commit"
 msgstr "lần_chuyển_giao"
 
-#: builtin/commit.c:1421
+#: builtin/commit.c:1458
 msgid "reuse and edit message from specified commit"
 msgstr "dùng lại các ghi chú từ lần chuyển giao đã cho nhưng có cho sửa chữa"
 
-#: builtin/commit.c:1422
+#: builtin/commit.c:1459
 msgid "reuse message from specified commit"
 msgstr "dùng lại các ghi chú từ lần chuyển giao đã cho"
 
-#: builtin/commit.c:1423
+#: builtin/commit.c:1460
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr ""
 "dùng ghi chú có định dạng autosquash để sửa chữa lần chuyển giao đã chỉ ra"
 
-#: builtin/commit.c:1424
+#: builtin/commit.c:1461
 msgid "use autosquash formatted message to squash specified commit"
 msgstr ""
 "dùng lời nhắn có định dạng tự động nén để nén lại các lần chuyển giao đã chỉ "
 "ra"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1462
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr ""
 "lần chuyển giao nhận tôi là tác giả (được dùng với tùy chọn -C/-c/--amend)"
 
-#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240
-#: builtin/pull.c:149 builtin/revert.c:105
+#: builtin/commit.c:1463 builtin/log.c:1446 builtin/merge.c:242
+#: builtin/pull.c:154 builtin/revert.c:105
 msgid "add Signed-off-by:"
 msgstr "(nên dùng) thêm dòng Signed-off-by:"
 
-#: builtin/commit.c:1427
+#: builtin/commit.c:1464
 msgid "use specified template file"
 msgstr "sử dụng tập tin mẫu đã cho"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1465
 msgid "force edit of commit"
 msgstr "ép buộc sửa lần commit"
 
-#: builtin/commit.c:1429
+#: builtin/commit.c:1466
 msgid "default"
 msgstr "mặc định"
 
-#: builtin/commit.c:1429 builtin/tag.c:397
+#: builtin/commit.c:1466 builtin/tag.c:398
 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"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1467
 msgid "include status in commit message template"
 msgstr "bao gồm các trạng thái trong mẫu ghi chú chuyển giao"
 
-#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179
+#: builtin/commit.c:1469 builtin/merge.c:240 builtin/pull.c:184
 #: builtin/revert.c:113
 msgid "GPG sign commit"
 msgstr "ký lần chuyển giao dùng GPG"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1472
 msgid "Commit contents options"
 msgstr "Các tùy nội dung ghi chú commit"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1473
 msgid "commit all changed files"
 msgstr "chuyển giao tất cả các tập tin có thay đổi"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1474
 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"
 
-#: builtin/commit.c:1438
+#: builtin/commit.c:1475
 msgid "interactively add files"
 msgstr "thêm các tập-tin bằng tương tác"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1476
 msgid "interactively add changes"
 msgstr "thêm các thay đổi bằng tương tác"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1477
 msgid "commit only specified files"
 msgstr "chỉ chuyển giao các tập tin đã chỉ ra"
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1478
 msgid "bypass pre-commit and commit-msg hooks"
 msgstr "vòng qua móc (hook) pre-commit và commit-msg"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1479
 msgid "show what would be committed"
 msgstr "hiển thị xem cái gì có thể được chuyển giao"
 
-#: builtin/commit.c:1455
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "“tu bổ” (amend) lần commit trước"
 
-#: builtin/commit.c:1456
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "vòng qua móc (hook) post-rewrite"
 
-#: builtin/commit.c:1461
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "ok để ghi lại một thay đổi trống rỗng"
 
-#: builtin/commit.c:1463
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "ok để ghi các thay đổi với lời nhắn trống rỗng"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1573
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "Tập tin MERGE_HEAD sai hỏng (%s)"
 
-#: builtin/commit.c:1543
+#: builtin/commit.c:1580
 msgid "could not read MERGE_MODE"
 msgstr "không thể đọc MERGE_MODE"
 
-#: builtin/commit.c:1562
+#: builtin/commit.c:1599
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "không thể đọc phần chú thích (message) của lần chuyển giao: %s"
 
-#: builtin/commit.c:1573
+#: builtin/commit.c:1610
 #, 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"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1615
 #, 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"
 
-#: builtin/commit.c:1613
+#: builtin/commit.c:1650
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full and quota is\n"
@@ -7879,149 +8284,217 @@ msgstr ""
 "có bị đầy quá hay quota (hạn nghạch đĩa cứng) bị vượt quá,\n"
 "và sau đó \"git reset HEAD\" để khắc phục."
 
+#: builtin/commit-graph.c:9
+msgid "git commit-graph [--object-dir <objdir>]"
+msgstr "git commit-graph [--object-dir <objdir>]"
+
+#: builtin/commit-graph.c:10 builtin/commit-graph.c:16
+msgid "git commit-graph read [--object-dir <objdir>]"
+msgstr "git commit-graph read [--object-dir <objdir>]"
+
+#: builtin/commit-graph.c:11 builtin/commit-graph.c:21
+msgid ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+msgstr ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+
+#: builtin/commit-graph.c:39 builtin/commit-graph.c:92
+#: builtin/commit-graph.c:147 builtin/fetch.c:161 builtin/log.c:1466
+msgid "dir"
+msgstr "tmục"
+
+#: builtin/commit-graph.c:40 builtin/commit-graph.c:93
+#: builtin/commit-graph.c:148
+msgid "The object directory to store the graph"
+msgstr "Thư mục đối tượng để lưu đồ thị"
+
+#: builtin/commit-graph.c:95
+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"
+
+#: builtin/commit-graph.c:97
+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"
+
+#: builtin/commit-graph.c:99
+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ị lần chuyển giao"
+
+#: builtin/commit-graph.c:108
+msgid "cannot use both --stdin-commits and --stdin-packs"
+msgstr "không thể sử dụng cả hai --stdin-commits và --stdin-packs"
+
 #: builtin/config.c:10
 msgid "git config [<options>]"
 msgstr "git config [<các-tùy-chọn>]"
 
-#: builtin/config.c:58
+#: builtin/config.c:101
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "đối số không được thừa nhận --type, %s"
+
+#: builtin/config.c:123
 msgid "Config file location"
 msgstr "Vị trí tập tin cấu hình"
 
-#: builtin/config.c:59
+#: builtin/config.c:124
 msgid "use global config file"
 msgstr "dùng tập tin cấu hình toàn cục"
 
-#: builtin/config.c:60
+#: builtin/config.c:125
 msgid "use system config file"
 msgstr "sử dụng tập tin cấu hình hệ thống"
 
-#: builtin/config.c:61
+#: builtin/config.c:126
 msgid "use repository config file"
 msgstr "dùng tập tin cấu hình của kho"
 
-#: builtin/config.c:62
+#: builtin/config.c:127
 msgid "use given config file"
 msgstr "sử dụng tập tin cấu hình đã cho"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "blob-id"
 msgstr "blob-id"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "read config from given blob object"
 msgstr "đọc cấu hình từ đối tượng blob đã cho"
 
-#: builtin/config.c:64
+#: builtin/config.c:129
 msgid "Action"
 msgstr "Hành động"
 
-#: builtin/config.c:65
+#: builtin/config.c:130
 msgid "get value: name [value-regex]"
 msgstr "lấy giá-trị: tên [value-regex]"
 
-#: builtin/config.c:66
+#: builtin/config.c:131
 msgid "get all values: key [value-regex]"
 msgstr "lấy tất cả giá-trị: khóa [value-regex]"
 
-#: builtin/config.c:67
+#: builtin/config.c:132
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr "lấy giá trị cho regexp: name-regex [value-regex]"
 
-#: builtin/config.c:68
+#: builtin/config.c:133
 msgid "get value specific for the URL: section[.var] URL"
 msgstr "lấy đặc tả giá trị cho URL: phần[.biến] URL"
 
-#: builtin/config.c:69
+#: builtin/config.c:134
 msgid "replace all matching variables: name value [value_regex]"
 msgstr "thay thế tất cả các biến khớp mẫu: tên giá-trị [value_regex]"
 
-#: builtin/config.c:70
+#: builtin/config.c:135
 msgid "add a new variable: name value"
 msgstr "thêm biến mới: tên giá-trị"
 
-#: builtin/config.c:71
+#: builtin/config.c:136
 msgid "remove a variable: name [value-regex]"
 msgstr "gỡ bỏ biến: tên [value-regex]"
 
-#: builtin/config.c:72
+#: builtin/config.c:137
 msgid "remove all matches: name [value-regex]"
 msgstr "gỡ bỏ mọi cái khớp: tên [value-regex]"
 
-#: builtin/config.c:73
+#: builtin/config.c:138
 msgid "rename section: old-name new-name"
 msgstr "đổi tên phần: tên-cũ tên-mới"
 
-#: builtin/config.c:74
+#: builtin/config.c:139
 msgid "remove a section: name"
 msgstr "gỡ bỏ phần: tên"
 
-#: builtin/config.c:75
+#: builtin/config.c:140
 msgid "list all"
 msgstr "liệt kê tất"
 
-#: builtin/config.c:76
+#: builtin/config.c:141
 msgid "open an editor"
 msgstr "mở một trình biên soạn"
 
-#: builtin/config.c:77
+#: builtin/config.c:142
 msgid "find the color configured: slot [default]"
 msgstr "tìm cấu hình màu sắc: slot [mặc định]"
 
-#: builtin/config.c:78
+#: builtin/config.c:143
 msgid "find the color setting: slot [stdout-is-tty]"
 msgstr "tìm các cài đặt về màu sắc: slot [stdout-là-tty]"
 
-#: builtin/config.c:79
+#: builtin/config.c:144
 msgid "Type"
 msgstr "Kiểu"
 
-#: builtin/config.c:80
+#: builtin/config.c:145
+msgid "value is given this type"
+msgstr "giá trị được đưa kiểu này"
+
+#: builtin/config.c:146
 msgid "value is \"true\" or \"false\""
 msgstr "giá trị là \"true\" hoặc \"false\""
 
-#: builtin/config.c:81
+#: builtin/config.c:147
 msgid "value is decimal number"
 msgstr "giá trị ở dạng số thập phân"
 
-#: builtin/config.c:82
+#: builtin/config.c:148
 msgid "value is --bool or --int"
 msgstr "giá trị là --bool hoặc --int"
 
-#: builtin/config.c:83
+#: builtin/config.c:149
 msgid "value is a path (file or directory name)"
 msgstr "giá trị là đường dẫn (tên tập tin hay thư mục)"
 
-#: builtin/config.c:84
+#: builtin/config.c:150
 msgid "value is an expiry date"
 msgstr "giá trị là một ngày hết hạn"
 
-#: builtin/config.c:85
+#: builtin/config.c:151
 msgid "Other"
 msgstr "Khác"
 
-#: builtin/config.c:86
+#: builtin/config.c:152
 msgid "terminate values with NUL byte"
 msgstr "chấm dứt giá trị với byte NUL"
 
-#: builtin/config.c:87
+#: builtin/config.c:153
 msgid "show variable names only"
 msgstr "chỉ hiển thị các tên biến"
 
-#: builtin/config.c:88
+#: builtin/config.c:154
 msgid "respect include directives on lookup"
 msgstr "tôn trọng kể cà các hướng trong tìm kiếm"
 
-#: builtin/config.c:89
+#: builtin/config.c:155
 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)"
 
-#: builtin/config.c:335
+#: builtin/config.c:156
+msgid "value"
+msgstr "giá trị"
+
+#: builtin/config.c:156
+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"
+
+#: builtin/config.c:332
+#, c-format
+msgid "failed to format default config value: %s"
+msgstr "gặp lỗi khi định dạng giá trị cấu hình mặc định: %s"
+
+#: builtin/config.c:431
 msgid "unable to parse default color value"
 msgstr "không thể phân tích giá trị màu mặc định"
 
-#: builtin/config.c:479
+#: builtin/config.c:575
 #, c-format
 msgid ""
 "# This is Git's per-user configuration file.\n"
@@ -8036,16 +8509,20 @@ msgstr ""
 "#\tname = %s\n"
 "#\temail = %s\n"
 
-#: builtin/config.c:507
+#: builtin/config.c:603
 msgid "--local can only be used inside a git repository"
 msgstr "--local chỉ có thể được dùng bên trong một kho git"
 
-#: builtin/config.c:632
+#: builtin/config.c:606
+msgid "--blob can only be used inside a git repository"
+msgstr "--blob chỉ có thể được dùng bên trong một kho git"
+
+#: builtin/config.c:735
 #, c-format
 msgid "cannot create configuration file %s"
 msgstr "không thể tạo tập tin cấu hình “%s”"
 
-#: builtin/config.c:645
+#: builtin/config.c:748
 #, c-format
 msgid ""
 "cannot overwrite multiple values with a single value\n"
@@ -8054,11 +8531,11 @@ msgstr ""
 "không thể ghi đè nhiều giá trị với một giá trị đơn\n"
 "      Dùng một biểu thức chính quy, --add hay --replace-all để thay đổi %s."
 
-#: builtin/count-objects.c:88
+#: builtin/count-objects.c:90
 msgid "git count-objects [-v] [-H | --human-readable]"
 msgstr "git count-objects [-v] [-H | --human-readable]"
 
-#: builtin/count-objects.c:98
+#: builtin/count-objects.c:100
 msgid "print sizes in human readable format"
 msgstr "hiển thị kích cỡ theo định dạng dành cho người đọc"
 
@@ -8324,23 +8801,23 @@ msgstr "thực hiện một diff toàn thư mục"
 msgid "do not prompt before launching a diff tool"
 msgstr "đừng nhắc khi khởi chạy công cụ diff"
 
-#: builtin/difftool.c:705
+#: builtin/difftool.c:704
 msgid "use symlinks in dir-diff mode"
 msgstr "dùng liên kết mềm trong diff-thư-mục"
 
-#: builtin/difftool.c:706
+#: builtin/difftool.c:705
 msgid "<tool>"
 msgstr "<công_cụ>"
 
-#: builtin/difftool.c:707
+#: builtin/difftool.c:706
 msgid "use the specified diff tool"
 msgstr "dùng công cụ diff đã cho"
 
-#: builtin/difftool.c:709
+#: builtin/difftool.c:708
 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“"
 
-#: builtin/difftool.c:712
+#: builtin/difftool.c:711
 msgid ""
 "make 'git-difftool' exit when an invoked diff tool returns a non - zero exit "
 "code"
@@ -8348,169 +8825,165 @@ msgstr ""
 "làm cho “git-difftool” thoát khi gọi công cụ diff trả về mã không phải số "
 "không"
 
-#: builtin/difftool.c:714
+#: builtin/difftool.c:713
 msgid "<command>"
 msgstr "<lệnh>"
 
-#: builtin/difftool.c:715
+#: builtin/difftool.c:714
 msgid "specify a custom command for viewing diffs"
 msgstr "chỉ định một lệnh tùy ý để xem diff"
 
-#: builtin/difftool.c:739
+#: builtin/difftool.c:738
 msgid "no <tool> given for --tool=<tool>"
 msgstr "chưa đưa ra <công_cụ> cho --tool=<công_cụ>"
 
-#: builtin/difftool.c:746
+#: builtin/difftool.c:745
 msgid "no <cmd> given for --extcmd=<cmd>"
 msgstr "chưa đưa ra <lệnh> cho --extcmd=<lệnh>"
 
-#: builtin/fast-export.c:26
+#: builtin/fast-export.c:27
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [rev-list-opts]"
 
-#: builtin/fast-export.c:998
+#: builtin/fast-export.c:1000
 msgid "show progress after <n> objects"
 msgstr "hiển thị tiến triển sau <n> đối tượng"
 
-#: builtin/fast-export.c:1000
+#: builtin/fast-export.c:1002
 msgid "select handling of signed tags"
 msgstr "chọn điều khiển của thẻ đã ký"
 
-#: builtin/fast-export.c:1003
+#: builtin/fast-export.c:1005
 msgid "select handling of tags that tag filtered objects"
 msgstr "chọn sự xử lý của các thẻ, cái mà đánh thẻ các đối tượng được lọc ra"
 
-#: builtin/fast-export.c:1006
+#: builtin/fast-export.c:1008
 msgid "Dump marks to this file"
 msgstr "Đổ các đánh dấu này vào tập-tin"
 
-#: builtin/fast-export.c:1008
+#: builtin/fast-export.c:1010
 msgid "Import marks from this file"
 msgstr "nhập vào đánh dấu từ tập tin này"
 
-#: builtin/fast-export.c:1010
+#: builtin/fast-export.c:1012
 msgid "Fake a tagger when tags lack one"
 msgstr "Làm giả một cái thẻ khi thẻ bị thiếu một cái"
 
-#: builtin/fast-export.c:1012
+#: builtin/fast-export.c:1014
 msgid "Output full tree for each commit"
 msgstr "Xuất ra toàn bộ cây cho mỗi lần chuyển giao"
 
-#: builtin/fast-export.c:1014
+#: builtin/fast-export.c:1016
 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"
 
-#: builtin/fast-export.c:1015
+#: builtin/fast-export.c:1017
 msgid "Skip output of blob data"
 msgstr "Bỏ qua kết xuất của dữ liệu blob"
 
-#: builtin/fast-export.c:1016
+#: builtin/fast-export.c:1018
 msgid "refspec"
 msgstr "refspec"
 
-#: builtin/fast-export.c:1017
+#: builtin/fast-export.c:1019
 msgid "Apply refspec to exported refs"
 msgstr "Áp dụng refspec cho refs đã xuất"
 
-#: builtin/fast-export.c:1018
+#: builtin/fast-export.c:1020
 msgid "anonymize output"
 msgstr "kết xuất anonymize"
 
-#: builtin/fetch.c:25
+#: builtin/fetch.c:26
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
 msgstr "git fetch [<các-tùy-chọn>] [<kho-chứa> [<refspec>…]]"
 
-#: builtin/fetch.c:26
+#: builtin/fetch.c:27
 msgid "git fetch [<options>] <group>"
 msgstr "git fetch [<các-tùy-chọn>] [<nhóm>"
 
-#: builtin/fetch.c:27
+#: builtin/fetch.c:28
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
 msgstr "git fetch --multiple [<các-tùy-chọn>] [(<kho> | <nhóm>)…]"
 
-#: builtin/fetch.c:28
+#: builtin/fetch.c:29
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<các-tùy-chọn>]"
 
-#: builtin/fetch.c:124 builtin/pull.c:188
+#: builtin/fetch.c:123 builtin/pull.c:193
 msgid "fetch from all remotes"
 msgstr "lấy về từ tất cả các máy chủ"
 
-#: builtin/fetch.c:126 builtin/pull.c:191
+#: builtin/fetch.c:125 builtin/pull.c:196
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "nối thêm vào .git/FETCH_HEAD thay vì ghi đè lên nó"
 
-#: builtin/fetch.c:128 builtin/pull.c:194
+#: builtin/fetch.c:127 builtin/pull.c:199
 msgid "path to upload pack on remote end"
 msgstr "đường dẫn đến gói tải lên trên máy chủ cuối"
 
-#: builtin/fetch.c:129 builtin/pull.c:196
+#: builtin/fetch.c:128 builtin/pull.c:201
 msgid "force overwrite of local branch"
 msgstr "ép buộc ghi đè lên nhánh nội bộ"
 
-#: builtin/fetch.c:131
+#: builtin/fetch.c:130
 msgid "fetch from multiple remotes"
 msgstr "lấy từ nhiều máy chủ cùng lúc"
 
-#: builtin/fetch.c:133 builtin/pull.c:198
+#: builtin/fetch.c:132 builtin/pull.c:203
 msgid "fetch all tags and associated objects"
 msgstr "lấy tất cả các thẻ cùng với các đối tượng liên quan đến nó"
 
-#: builtin/fetch.c:135
+#: builtin/fetch.c:134
 msgid "do not fetch all tags (--no-tags)"
 msgstr "không lấy tất cả các thẻ (--no-tags)"
 
-#: builtin/fetch.c:137
+#: builtin/fetch.c:136
 msgid "number of submodules fetched in parallel"
 msgstr "số lượng mô-đun-con được lấy đồng thời"
 
-#: builtin/fetch.c:139 builtin/pull.c:201
+#: builtin/fetch.c:138 builtin/pull.c:206
 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"
 
-#: builtin/fetch.c:141
+#: builtin/fetch.c:140
 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"
 
-#: builtin/fetch.c:142 builtin/fetch.c:165 builtin/pull.c:126
+#: builtin/fetch.c:141 builtin/fetch.c:164 builtin/pull.c:131
 msgid "on-demand"
 msgstr "khi-cần"
 
-#: builtin/fetch.c:143
+#: builtin/fetch.c:142
 msgid "control recursive fetching of submodules"
 msgstr "điều khiển việc lấy về đệ quy trong các mô-đun-con"
 
-#: builtin/fetch.c:147 builtin/pull.c:209
+#: builtin/fetch.c:146 builtin/pull.c:214
 msgid "keep downloaded pack"
 msgstr "giữ lại gói đã tải về"
 
-#: builtin/fetch.c:149
+#: builtin/fetch.c:148
 msgid "allow updating of HEAD ref"
 msgstr "cho phép cập nhật th.chiếu HEAD"
 
-#: builtin/fetch.c:152 builtin/fetch.c:158 builtin/pull.c:212
+#: builtin/fetch.c:151 builtin/fetch.c:157 builtin/pull.c:217
 msgid "deepen history of shallow clone"
 msgstr "làm sâu hơn lịch sử của bản sao"
 
-#: builtin/fetch.c:154
+#: builtin/fetch.c:153
 msgid "deepen history of shallow repository based on time"
 msgstr "làm sâu hơn lịch sử của kho bản sao shallow dựa trên thời gian"
 
-#: builtin/fetch.c:160 builtin/pull.c:215
+#: builtin/fetch.c:159 builtin/pull.c:220
 msgid "convert to a complete repository"
 msgstr "chuyển đổi hoàn toàn sang kho git"
 
-#: builtin/fetch.c:162 builtin/log.c:1466
-msgid "dir"
-msgstr "tmục"
-
-#: builtin/fetch.c:163
+#: builtin/fetch.c:162
 msgid "prepend this to submodule path output"
 msgstr "soạn sẵn cái này cho kết xuất đường dẫn mô-đun-con"
 
-#: builtin/fetch.c:166
+#: builtin/fetch.c:165
 msgid ""
 "default for recursive fetching of submodules (lower priority than config "
 "files)"
@@ -8518,89 +8991,99 @@ msgstr ""
 "mặc định cho việc lấy đệ quy các mô-đun-con (có mức ưu tiên thấp hơn các tập "
 "tin cấu hình config)"
 
-#: builtin/fetch.c:170 builtin/pull.c:218
+#: builtin/fetch.c:169 builtin/pull.c:223
 msgid "accept refs that update .git/shallow"
 msgstr "chấp nhận tham chiếu cập nhật .git/shallow"
 
-#: builtin/fetch.c:171 builtin/pull.c:220
+#: builtin/fetch.c:170 builtin/pull.c:225
 msgid "refmap"
 msgstr "refmap"
 
-#: builtin/fetch.c:172 builtin/pull.c:221
+#: builtin/fetch.c:171 builtin/pull.c:226
 msgid "specify fetch refmap"
 msgstr "chỉ ra refmap cần lấy về"
 
-#: builtin/fetch.c:431
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:172
+msgid "server-specific"
+msgstr "đặc-tả-máy-phục-vụ"
+
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:173
+msgid "option to transmit"
+msgstr "tùy chọn để chuyển giao"
+
+#: builtin/fetch.c:442
 msgid "Couldn't find remote ref HEAD"
 msgstr "Không thể tìm thấy máy chủ cho tham chiếu HEAD"
 
-#: builtin/fetch.c:549
+#: builtin/fetch.c:560
 #, 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"
 
-#: builtin/fetch.c:642
+#: builtin/fetch.c:653
 #, c-format
 msgid "object %s not found"
 msgstr "Không tìm thấy đối tượng %s"
 
-#: builtin/fetch.c:646
+#: builtin/fetch.c:657
 msgid "[up to date]"
 msgstr "[đã cập nhật]"
 
-#: builtin/fetch.c:659 builtin/fetch.c:739
+#: builtin/fetch.c:670 builtin/fetch.c:750
 msgid "[rejected]"
 msgstr "[Bị từ chối]"
 
-#: builtin/fetch.c:660
+#: builtin/fetch.c:671
 msgid "can't fetch in current branch"
 msgstr "không thể fetch (lấy) về nhánh hiện hành"
 
-#: builtin/fetch.c:669
+#: builtin/fetch.c:680
 msgid "[tag update]"
 msgstr "[cập nhật thẻ]"
 
-#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719
-#: builtin/fetch.c:734
+#: builtin/fetch.c:681 builtin/fetch.c:714 builtin/fetch.c:730
+#: builtin/fetch.c:745
 msgid "unable to update local ref"
 msgstr "không thể cập nhật tham chiếu nội bộ"
 
-#: builtin/fetch.c:689
+#: builtin/fetch.c:700
 msgid "[new tag]"
 msgstr "[thẻ mới]"
 
-#: builtin/fetch.c:692
+#: builtin/fetch.c:703
 msgid "[new branch]"
 msgstr "[nhánh mới]"
 
-#: builtin/fetch.c:695
+#: builtin/fetch.c:706
 msgid "[new ref]"
 msgstr "[ref (tham chiếu) mới]"
 
-#: builtin/fetch.c:734
+#: builtin/fetch.c:745
 msgid "forced update"
 msgstr "cưỡng bức cập nhật"
 
-#: builtin/fetch.c:739
+#: builtin/fetch.c:750
 msgid "non-fast-forward"
 msgstr "không-phải-chuyển-tiếp-nhanh"
 
-#: builtin/fetch.c:784
+#: builtin/fetch.c:795
 #, 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"
 
-#: builtin/fetch.c:804
+#: builtin/fetch.c:815
 #, c-format
 msgid "reject %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"
 
-#: builtin/fetch.c:892 builtin/fetch.c:988
+#: builtin/fetch.c:903 builtin/fetch.c:999
 #, c-format
 msgid "From %.*s\n"
 msgstr "Từ %.*s\n"
 
-#: builtin/fetch.c:903
+#: builtin/fetch.c:914
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -8609,59 +9092,59 @@ 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"
 
-#: builtin/fetch.c:958
+#: builtin/fetch.c:969
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (%s sẽ trở thành không đầu (không được quản lý))"
 
-#: builtin/fetch.c:959
+#: builtin/fetch.c:970
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (%s đã trở thành không đầu (không được quản lý))"
 
-#: builtin/fetch.c:991
+#: builtin/fetch.c:1002
 msgid "[deleted]"
 msgstr "[đã xóa]"
 
-#: builtin/fetch.c:992 builtin/remote.c:1024
+#: builtin/fetch.c:1003 builtin/remote.c:1033
 msgid "(none)"
 msgstr "(không)"
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1026
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr ""
 "Từ chối việc lấy vào trong nhánh hiện tại %s của một kho chứa không phải kho "
 "trần (bare)"
 
-#: builtin/fetch.c:1034
+#: builtin/fetch.c:1045
 #, 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"
 
-#: builtin/fetch.c:1037
+#: builtin/fetch.c:1048
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "Tùy chọn \"%s\" bị bỏ qua với %s\n"
 
-#: builtin/fetch.c:1277
+#: builtin/fetch.c:1287
 #, c-format
 msgid "Fetching %s\n"
 msgstr "Đang lấy “%s” về\n"
 
-#: builtin/fetch.c:1279 builtin/remote.c:97
+#: builtin/fetch.c:1289 builtin/remote.c:98
 #, c-format
 msgid "Could not fetch %s"
 msgstr "không thể “%s” về"
 
-#: builtin/fetch.c:1325 builtin/fetch.c:1498
+#: builtin/fetch.c:1335 builtin/fetch.c:1503
 msgid ""
 "--filter can only be used with the remote configured in core.partialClone"
 msgstr ""
 "--filter chỉ có thể được dùng với máy chủ được cấu hình bằng core."
 "partialClone"
 
-#: builtin/fetch.c:1350
+#: builtin/fetch.c:1358
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
@@ -8669,40 +9152,40 @@ 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ề)."
 
-#: builtin/fetch.c:1394
+#: builtin/fetch.c:1395
 msgid "You need to specify a tag name."
 msgstr "Bạn phải định rõ tên thẻ."
 
-#: builtin/fetch.c:1439
+#: builtin/fetch.c:1444
 msgid "Negative depth in --deepen is not supported"
 msgstr "Mức sâu là số âm trong --deepen là không được hỗ trợ"
 
-#: builtin/fetch.c:1441
+#: builtin/fetch.c:1446
 msgid "--deepen and --depth are mutually exclusive"
 msgstr "Các tùy chọn--deepen và --depth loại từ lẫn nhau"
 
-#: builtin/fetch.c:1446
+#: builtin/fetch.c:1451
 msgid "--depth and --unshallow cannot be used together"
 msgstr "tùy chọn --depth và --unshallow không thể sử dụng cùng với nhau"
 
-#: builtin/fetch.c:1448
+#: builtin/fetch.c:1453
 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ý"
 
-#: builtin/fetch.c:1464
+#: builtin/fetch.c:1469
 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"
 
-#: builtin/fetch.c:1466
+#: builtin/fetch.c:1471
 msgid "fetch --all does not make sense with refspecs"
 msgstr "lệnh lấy về \"fetch --all\" không hợp lý với refspecs"
 
-#: builtin/fetch.c:1475
+#: builtin/fetch.c:1480
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "không có nhóm máy chủ hay máy chủ như thế: %s"
 
-#: builtin/fetch.c:1482
+#: builtin/fetch.c:1487
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr "Việc lấy về cả một nhóm và chỉ định refspecs không hợp lý"
 
@@ -8771,7 +9254,7 @@ msgstr "trích dẫn để phù hợp cho Tcl"
 msgid "show only <n> matched refs"
 msgstr "hiển thị chỉ <n> tham chiếu khớp"
 
-#: builtin/for-each-ref.c:39 builtin/tag.c:420
+#: builtin/for-each-ref.c:39 builtin/tag.c:421
 msgid "respect format colors"
 msgstr "các màu định dạng lưu tâm"
 
@@ -8795,81 +9278,81 @@ msgstr "chỉ hiển thị những tham chiếu mà nó chứa lần chuyển gi
 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"
 
-#: builtin/fsck.c:568
+#: builtin/fsck.c:569
 msgid "Checking object directories"
 msgstr "Đang kiểm tra các thư mục đối tượng"
 
-#: builtin/fsck.c:660
+#: builtin/fsck.c:661
 msgid "git fsck [<options>] [<object>...]"
 msgstr "git fsck [<các-tùy-chọn>] [<đối-tượng>…]"
 
-#: builtin/fsck.c:666
+#: builtin/fsck.c:667
 msgid "show unreachable objects"
 msgstr "hiển thị các đối tượng không thể đọc được"
 
-#: builtin/fsck.c:667
+#: builtin/fsck.c:668
 msgid "show dangling objects"
 msgstr "hiển thị các đối tượng không được quản lý"
 
-#: builtin/fsck.c:668
+#: builtin/fsck.c:669
 msgid "report tags"
 msgstr "báo cáo các thẻ"
 
-#: builtin/fsck.c:669
+#: builtin/fsck.c:670
 msgid "report root nodes"
 msgstr "báo cáo node gốc"
 
-#: builtin/fsck.c:670
+#: builtin/fsck.c:671
 msgid "make index objects head nodes"
 msgstr "tạo “index objects head nodes”"
 
-#: builtin/fsck.c:671
+#: builtin/fsck.c:672
 msgid "make reflogs head nodes (default)"
 msgstr "tạo “reflogs head nodes” (mặc định)"
 
-#: builtin/fsck.c:672
+#: builtin/fsck.c:673
 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ế"
 
-#: builtin/fsck.c:673
+#: builtin/fsck.c:674
 msgid "check only connectivity"
 msgstr "chỉ kiểm tra kết nối"
 
-#: builtin/fsck.c:674
+#: builtin/fsck.c:675
 msgid "enable more strict checking"
 msgstr "cho phép kiểm tra hạn chế hơn"
 
-#: builtin/fsck.c:676
+#: builtin/fsck.c:677
 msgid "write dangling objects in .git/lost-found"
 msgstr "ghi các đối tượng không được quản lý trong .git/lost-found"
 
-#: builtin/fsck.c:677 builtin/prune.c:108
+#: builtin/fsck.c:678 builtin/prune.c:109
 msgid "show progress"
 msgstr "hiển thị quá trình"
 
-#: builtin/fsck.c:678
+#: builtin/fsck.c:679
 msgid "show verbose names for reachable objects"
 msgstr "hiển thị tên chi tiết cho các đối tượng đọc được"
 
-#: builtin/fsck.c:742
+#: builtin/fsck.c:745
 msgid "Checking objects"
 msgstr "Đang kiểm tra các đối tượng"
 
-#: builtin/gc.c:27
+#: builtin/gc.c:33
 msgid "git gc [<options>]"
 msgstr "git gc [<các-tùy-chọn>]"
 
-#: builtin/gc.c:80
+#: builtin/gc.c:88
 #, 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"
 
-#: builtin/gc.c:312
+#: builtin/gc.c:452
 #, c-format
 msgid "Can't stat %s"
 msgstr "không thể lấy thông tin thống kê về “%s”"
 
-#: builtin/gc.c:321
+#: builtin/gc.c:461
 #, c-format
 msgid ""
 "The last gc run reported the following. Please correct the root cause\n"
@@ -8884,45 +9367,54 @@ msgstr ""
 "\n"
 "%s"
 
-#: builtin/gc.c:360
+#: builtin/gc.c:502
 msgid "prune unreferenced objects"
 msgstr "xóa bỏ các đối tượng không được tham chiếu"
 
-#: builtin/gc.c:362
+#: builtin/gc.c:504
 msgid "be more thorough (increased runtime)"
 msgstr "cẩn thận hơn nữa (tăng thời gian chạy)"
 
-#: builtin/gc.c:363
+#: builtin/gc.c:505
 msgid "enable auto-gc mode"
 msgstr "bật chế độ auto-gc"
 
-#: builtin/gc.c:366
+#: builtin/gc.c:508
 msgid "force running gc even if there may be another gc running"
 msgstr "buộc gc chạy ngay cả khi có tiến trình gc khác đang chạy"
 
-#: builtin/gc.c:384
+#: builtin/gc.c:511
+msgid "repack all other packs except the largest pack"
+msgstr "đóng gói lại tất cả các gói khác ngoại trừ gói lớn nhất"
+
+#: builtin/gc.c:528
 #, 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"
+msgid "failed to parse gc.logexpiry value %s"
+msgstr "gặp lỗi khi phân tích giá trị gc.logexpiry %s"
 
-#: builtin/gc.c:412
+#: builtin/gc.c:539
+#, c-format
+msgid "failed to parse prune expiry value %s"
+msgstr "gặp lỗi khi phân tích giá trị prune %s"
+
+#: builtin/gc.c:559
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
 msgstr ""
 "Tự động đóng gói kho chứa trên nền hệ thống để tối ưu hóa hiệu suất làm "
 "việc.\n"
 
-#: builtin/gc.c:414
+#: builtin/gc.c:561
 #, c-format
 msgid "Auto packing the repository for optimum performance.\n"
 msgstr "Tự động đóng gói kho chứa để tối ưu hóa hiệu suất làm việc.\n"
 
-#: builtin/gc.c:415
+#: builtin/gc.c:562
 #, c-format
 msgid "See \"git help gc\" for manual housekeeping.\n"
 msgstr "Xem \"git help gc\" để có hướng dẫn cụ thể về cách dọn dẹp kho git.\n"
 
-#: builtin/gc.c:440
+#: builtin/gc.c:598
 #, c-format
 msgid ""
 "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
@@ -8930,23 +9422,23 @@ msgstr ""
 "gc đang được thực hiện trên máy “%s” pid %<PRIuMAX> (dùng --force nếu không "
 "phải thế)"
 
-#: builtin/gc.c:487
+#: builtin/gc.c:645
 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” "
 "để xóa bỏ chúng đi."
 
-#: builtin/grep.c:27
+#: builtin/grep.c:28
 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [<các-tùy-chọn>] [-e] <mẫu> [<rev>…] [[--] <đường-dẫn>…]"
 
-#: builtin/grep.c:225
+#: builtin/grep.c:226
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep: gặp lỗi tạo tuyến (thread): %s"
 
-#: builtin/grep.c:283
+#: builtin/grep.c:284
 #, c-format
 msgid "invalid number of threads specified (%d) for %s"
 msgstr "số tuyến đã cho không hợp lệ (%d) cho %s"
@@ -8955,17 +9447,17 @@ msgstr "số tuyến đã cho không hợp lệ (%d) cho %s"
 #. variable for tweaking threads, currently
 #. grep.threads
 #.
-#: builtin/grep.c:292 builtin/index-pack.c:1523 builtin/index-pack.c:1712
+#: builtin/grep.c:293 builtin/index-pack.c:1535 builtin/index-pack.c:1727
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "không hỗ trợ đa tuyến, bỏ qua %s"
 
-#: builtin/grep.c:460 builtin/grep.c:580 builtin/grep.c:622
+#: builtin/grep.c:461 builtin/grep.c:582 builtin/grep.c:623
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "không thể đọc cây (%s)"
 
-#: builtin/grep.c:637
+#: builtin/grep.c:638
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "không thể thực hiện lệnh grep (lọc tìm) từ đối tượng thuộc kiểu %s"
@@ -9165,7 +9657,7 @@ msgstr "--no-index hay --untracked không được sử dụng cùng với revs"
 msgid "unable to resolve revision: %s"
 msgstr "không thể phân giải điểm xét duyệt: %s"
 
-#: builtin/grep.c:1036 builtin/index-pack.c:1519
+#: builtin/grep.c:1036 builtin/index-pack.c:1531
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "số tuyến chỉ ra không hợp lệ (%d)"
@@ -9235,58 +9727,62 @@ msgstr "chỉ cần băm rác ngẫu nhiên để tạo một đối tượng h
 msgid "process file as it were from this path"
 msgstr "xử lý tập tin như là nó đang ở thư mục này"
 
-#: builtin/help.c:43
+#: builtin/help.c:45
 msgid "print all available commands"
 msgstr "hiển thị danh sách các câu lệnh người dùng có thể sử dụng"
 
-#: builtin/help.c:44
+#: builtin/help.c:46
 msgid "exclude guides"
 msgstr "hướng dẫn loại trừ"
 
-#: builtin/help.c:45
+#: builtin/help.c:47
 msgid "print list of useful guides"
 msgstr "hiển thị danh sách các hướng dẫn hữu dụng"
 
-#: builtin/help.c:46
+#: builtin/help.c:48
 msgid "show man page"
 msgstr "hiển thị trang man"
 
-#: builtin/help.c:47
+#: builtin/help.c:49
 msgid "show manual in web browser"
 msgstr "hiển thị hướng dẫn sử dụng trong trình duyệt web"
 
-#: builtin/help.c:49
+#: builtin/help.c:51
 msgid "show info page"
 msgstr "hiện trang info"
 
-#: builtin/help.c:55
+#: builtin/help.c:53
+msgid "print command description"
+msgstr "hiển thị mô tả lệnh"
+
+#: builtin/help.c:58
 msgid "git help [--all] [--guides] [--man | --web | --info] [<command>]"
 msgstr "git help [--all] [--guides] [--man | --web | --info] [<lệnh>]"
 
-#: builtin/help.c:67
+#: builtin/help.c:70
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "không nhận ra định dạng trợ giúp “%s”"
 
-#: builtin/help.c:94
+#: builtin/help.c:97
 msgid "Failed to start emacsclient."
 msgstr "Gặp lỗi khi khởi chạy emacsclient."
 
-#: builtin/help.c:107
+#: builtin/help.c:110
 msgid "Failed to parse emacsclient version."
 msgstr "Gặp lỗi khi phân tích phiên bản emacsclient."
 
-#: builtin/help.c:115
+#: builtin/help.c:118
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "phiên bản của emacsclient “%d” quá cũ (< 22)."
 
-#: builtin/help.c:133 builtin/help.c:155 builtin/help.c:165 builtin/help.c:173
+#: builtin/help.c:136 builtin/help.c:158 builtin/help.c:168 builtin/help.c:176
 #, c-format
 msgid "failed to exec '%s'"
 msgstr "gặp lỗi khi thực thi “%s”"
 
-#: builtin/help.c:211
+#: builtin/help.c:214
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -9295,7 +9791,7 @@ 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ế."
 
-#: builtin/help.c:223
+#: builtin/help.c:226
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -9304,352 +9800,320 @@ 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ế."
 
-#: builtin/help.c:340
+#: builtin/help.c:343
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "“%s”: không rõ chương trình xem man."
 
-#: builtin/help.c:357
+#: builtin/help.c:360
 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"
 
-#: builtin/help.c:365
+#: builtin/help.c:368
 msgid "no info viewer handled the request"
 msgstr "không có trình xem trợ giúp dạng info tiếp hợp với yêu cầu"
 
-#: builtin/help.c:407
-msgid "Defining attributes per path"
-msgstr "Định nghĩa các thuộc tính cho mỗi đường dẫn"
+#: builtin/help.c:415
+#, c-format
+msgid "'%s' is aliased to '%s'"
+msgstr "“%s” được đặt bí danh thành “%s”"
 
-#: builtin/help.c:408
-msgid "Everyday Git With 20 Commands Or So"
-msgstr "Mỗi ngày học 20 lệnh Git hay hơn"
-
-#: builtin/help.c:409
-msgid "A Git glossary"
-msgstr "Thuật ngữ chuyên môn Git"
-
-#: builtin/help.c:410
-msgid "Specifies intentionally untracked files to ignore"
-msgstr "Chỉ định các tập tin không cần theo dõi"
-
-#: builtin/help.c:411
-msgid "Defining submodule properties"
-msgstr "Định nghĩa thuộc tính mô-đun-con"
-
-#: builtin/help.c:412
-msgid "Specifying revisions and ranges for Git"
-msgstr "Chỉ định điểm xét duyệt và vùng cho Git"
-
-#: builtin/help.c:413
-msgid "A tutorial introduction to Git (for version 1.5.1 or newer)"
-msgstr "Hướng dẫn cách dùng Git ở mức cơ bản (bản 1.5.1 hay mới hơn)"
-
-#: builtin/help.c:414
-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."
-
-#: builtin/help.c:426
-msgid "The common Git guides are:\n"
-msgstr "Các chỉ dẫn chung về cách dùng Git là:\n"
-
-#: builtin/help.c:444
-#, c-format
-msgid "'%s' is aliased to '%s'"
-msgstr "“%s” được đặt bí danh thành “%s”"
-
-#: builtin/help.c:466 builtin/help.c:483
+#: builtin/help.c:442 builtin/help.c:459
 #, c-format
 msgid "usage: %s%s"
 msgstr "cách dùng: %s%s"
 
-#: builtin/index-pack.c:157
+#: builtin/index-pack.c:158
 #, c-format
 msgid "unable to open %s"
 msgstr "không thể mở %s"
 
-#: builtin/index-pack.c:207
+#: builtin/index-pack.c:208
 #, c-format
 msgid "object type mismatch at %s"
 msgstr "kiểu đối tượng không khớp tại %s"
 
-#: builtin/index-pack.c:227
+#: builtin/index-pack.c:228
 #, c-format
 msgid "did not receive expected object %s"
 msgstr "Không thể lấy về đối tượng cần %s"
 
-#: builtin/index-pack.c:230
+#: builtin/index-pack.c:231
 #, 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"
 
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
 #, c-format
 msgid "cannot fill %d byte"
 msgid_plural "cannot fill %d bytes"
 msgstr[0] "không thể điền thêm vào %d byte"
 
-#: builtin/index-pack.c:282
+#: builtin/index-pack.c:283
 msgid "early EOF"
 msgstr "gặp kết thúc tập tin EOF quá sớm"
 
-#: builtin/index-pack.c:283
+#: builtin/index-pack.c:284
 msgid "read error on input"
 msgstr "lỗi đọc ở đầu vào"
 
-#: builtin/index-pack.c:295
+#: builtin/index-pack.c:296
 msgid "used more bytes than were available"
 msgstr "sử dụng nhiều hơn số lượng byte mà nó sẵn có"
 
-#: builtin/index-pack.c:302
+#: builtin/index-pack.c:303
 msgid "pack too large for current definition of off_t"
 msgstr "gói quá lớn so với định nghĩa hiện tại của kiểu off_t"
 
-#: builtin/index-pack.c:305 builtin/unpack-objects.c:93
+#: builtin/index-pack.c:306 builtin/unpack-objects.c:93
 msgid "pack exceeds maximum allowed size"
 msgstr "gói đã vượt quá cỡ tối đa được phép"
 
-#: builtin/index-pack.c:320
+#: builtin/index-pack.c:321
 #, c-format
 msgid "unable to create '%s'"
 msgstr "không thể tạo “%s”"
 
-#: builtin/index-pack.c:326
+#: builtin/index-pack.c:327
 #, c-format
 msgid "cannot open packfile '%s'"
 msgstr "không thể mở packfile “%s”"
 
-#: builtin/index-pack.c:340
+#: builtin/index-pack.c:341
 msgid "pack signature mismatch"
 msgstr "chữ ký cho gói không khớp"
 
-#: builtin/index-pack.c:342
+#: builtin/index-pack.c:343
 #, c-format
 msgid "pack version %<PRIu32> unsupported"
 msgstr "không hỗ trợ phiên bản gói %<PRIu32>"
 
-#: builtin/index-pack.c:360
+#: builtin/index-pack.c:361
 #, c-format
 msgid "pack has bad object at offset %<PRIuMAX>: %s"
 msgstr "gói có đối tượng sai tại khoảng bù %<PRIuMAX>: %s"
 
-#: builtin/index-pack.c:481
+#: builtin/index-pack.c:482
 #, c-format
 msgid "inflate returned %d"
 msgstr "xả nén trả về %d"
 
-#: builtin/index-pack.c:530
+#: builtin/index-pack.c:531
 msgid "offset value overflow for delta base object"
 msgstr "tràn giá trị khoảng bù cho đối tượng delta cơ sở"
 
-#: builtin/index-pack.c:538
+#: builtin/index-pack.c:539
 msgid "delta base offset is out of bound"
 msgstr "khoảng bù cơ sở cho delta nằm ngoài phạm vi"
 
-#: builtin/index-pack.c:546
+#: builtin/index-pack.c:547
 #, c-format
 msgid "unknown object type %d"
 msgstr "không hiểu kiểu đối tượng %d"
 
-#: builtin/index-pack.c:577
+#: builtin/index-pack.c:578
 msgid "cannot pread pack file"
 msgstr "không thể chạy hàm pread cho tập tin gói"
 
-#: builtin/index-pack.c:579
+#: builtin/index-pack.c:580
 #, c-format
 msgid "premature end of pack file, %<PRIuMAX> byte missing"
 msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
 msgstr[0] "tập tin gói bị kết thúc sớm, thiếu %<PRIuMAX> byte"
 
-#: builtin/index-pack.c:605
+#: builtin/index-pack.c:606
 msgid "serious inflate inconsistency"
 msgstr "sự mâu thuẫn xả nén nghiêm trọng"
 
-#: builtin/index-pack.c:750 builtin/index-pack.c:756 builtin/index-pack.c:779
-#: builtin/index-pack.c:818 builtin/index-pack.c:827
+#: builtin/index-pack.c:751 builtin/index-pack.c:757 builtin/index-pack.c:780
+#: builtin/index-pack.c:819 builtin/index-pack.c:828
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "SỰ VA CHẠM SHA1 ĐàXẢY RA VỚI %s!"
 
-#: builtin/index-pack.c:753 builtin/pack-objects.c:182
-#: builtin/pack-objects.c:276
+#: builtin/index-pack.c:754 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:292
 #, c-format
 msgid "unable to read %s"
 msgstr "không thể đọc %s"
 
-#: builtin/index-pack.c:816
+#: builtin/index-pack.c:817
 #, c-format
 msgid "cannot read existing object info %s"
 msgstr "không thể đọc thông tin đối tượng sẵn có %s"
 
-#: builtin/index-pack.c:824
+#: builtin/index-pack.c:825
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "không thể đọc đối tượng đã tồn tại %s"
 
-#: builtin/index-pack.c:838
+#: builtin/index-pack.c:839
 #, c-format
 msgid "invalid blob object %s"
 msgstr "đối tượng blob không hợp lệ %s"
 
-#: builtin/index-pack.c:853
+#: builtin/index-pack.c:842 builtin/index-pack.c:860
+msgid "fsck error in packed object"
+msgstr "lỗi fsck trong đối tượng đóng gói"
+
+#: builtin/index-pack.c:857
 #, c-format
 msgid "invalid %s"
 msgstr "%s không hợp lệ"
 
-#: builtin/index-pack.c:856
-msgid "Error in object"
-msgstr "Lỗi trong đối tượng"
-
-#: builtin/index-pack.c:858
+#: builtin/index-pack.c:862
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "Không phải tất cả các đối tượng con của %s là có thể với tới được"
 
-#: builtin/index-pack.c:930 builtin/index-pack.c:961
+#: builtin/index-pack.c:934 builtin/index-pack.c:965
 msgid "failed to apply delta"
 msgstr "gặp lỗi khi áp dụng delta"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Receiving objects"
 msgstr "Đang nhận về các đối tượng"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Indexing objects"
 msgstr "Các đối tượng bảng mục lục"
 
-#: builtin/index-pack.c:1165
+#: builtin/index-pack.c:1169
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "gói bị sai hỏng (SHA1 không khớp)"
 
-#: builtin/index-pack.c:1170
+#: builtin/index-pack.c:1174
 msgid "cannot fstat packfile"
 msgstr "không thể lấy thông tin thống kê packfile"
 
-#: builtin/index-pack.c:1173
+#: builtin/index-pack.c:1177
 msgid "pack has junk at the end"
 msgstr "pack có phần thừa ở cuối"
 
-#: builtin/index-pack.c:1185
+#: builtin/index-pack.c:1189
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "lộn xộn hơn cả điên rồ khi chạy hàm parse_pack_objects()"
 
-#: builtin/index-pack.c:1208
+#: builtin/index-pack.c:1212
 msgid "Resolving deltas"
 msgstr "Đang phân giải các delta"
 
-#: builtin/index-pack.c:1219
+#: builtin/index-pack.c:1223
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "không thể tạo tuyến: %s"
 
-#: builtin/index-pack.c:1261
+#: builtin/index-pack.c:1265
 msgid "confusion beyond insanity"
 msgstr "lộn xộn hơn cả điên rồ"
 
-#: builtin/index-pack.c:1267
+#: builtin/index-pack.c:1271
 #, c-format
 msgid "completed with %d local object"
 msgid_plural "completed with %d local objects"
 msgstr[0] "đầy đủ với %d đối tượng nội bộ"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1283
 #, 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?)"
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1287
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "gói có %d delta chưa được giải quyết"
 
-#: builtin/index-pack.c:1307
+#: builtin/index-pack.c:1311
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "không thể xả nén đối tượng nối thêm (%d)"
 
-#: builtin/index-pack.c:1383
+#: builtin/index-pack.c:1388
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "đối tượng nội bộ %s bị hỏng"
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1402
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "tên tập tin tập tin gói “%s” không được kết thúc bằng đuôi “.pack”"
 
-#: builtin/index-pack.c:1422
+#: builtin/index-pack.c:1427
 #, c-format
 msgid "cannot write %s file '%s'"
 msgstr "không thể ghi %s tập tin “%s”"
 
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1435
 #, c-format
 msgid "cannot close written %s file '%s'"
 msgstr "không thể đóng tập tin được ghi %s “%s”"
 
-#: builtin/index-pack.c:1454
+#: builtin/index-pack.c:1459
 msgid "error while closing pack file"
 msgstr "gặp lỗi trong khi đóng tập tin gói"
 
-#: builtin/index-pack.c:1468
+#: builtin/index-pack.c:1473
 msgid "cannot store pack file"
 msgstr "không thể lưu tập tin gói"
 
-#: builtin/index-pack.c:1476
+#: builtin/index-pack.c:1481
 msgid "cannot store index file"
 msgstr "không thể lưu trữ tập tin ghi mục lục"
 
-#: builtin/index-pack.c:1513
+#: builtin/index-pack.c:1525
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "sai pack.indexversion=%<PRIu32>"
 
-#: builtin/index-pack.c:1581
+#: builtin/index-pack.c:1594
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "Không thể mở tập tin gói đã sẵn có “%s”"
 
-#: builtin/index-pack.c:1583
+#: builtin/index-pack.c:1596
 #, 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”"
 
-#: builtin/index-pack.c:1631
+#: builtin/index-pack.c:1644
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "không delta: %d đối tượng"
 
-#: builtin/index-pack.c:1638
+#: builtin/index-pack.c:1651
 #, 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"
 
-#: builtin/index-pack.c:1675
+#: builtin/index-pack.c:1688
 msgid "Cannot come back to cwd"
 msgstr "Không thể quay lại cwd"
 
-#: builtin/index-pack.c:1724 builtin/index-pack.c:1727
-#: builtin/index-pack.c:1743 builtin/index-pack.c:1747
+#: builtin/index-pack.c:1739 builtin/index-pack.c:1742
+#: builtin/index-pack.c:1758 builtin/index-pack.c:1762
 #, c-format
 msgid "bad %s"
 msgstr "%s sai"
 
-#: builtin/index-pack.c:1763
+#: builtin/index-pack.c:1778
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin không thể được dùng mà không có --stdin"
 
-#: builtin/index-pack.c:1765
+#: builtin/index-pack.c:1780
 msgid "--stdin requires a git repository"
 msgstr "--stdin cần một kho git"
 
-#: builtin/index-pack.c:1771
+#: builtin/index-pack.c:1786
 msgid "--verify with no packfile name given"
 msgstr "dùng tùy chọn --verify mà không đưa ra tên packfile"
 
+#: builtin/index-pack.c:1836 builtin/unpack-objects.c:578
+msgid "fsck error in pack objects"
+msgstr "lỗi fsck trong các đối tượng gói"
+
 #: builtin/init-db.c:55
 #, c-format
 msgid "cannot stat '%s'"
@@ -9687,8 +10151,8 @@ msgstr "đang lờ đi mẫu “%s”"
 
 #: builtin/init-db.c:120
 #, c-format
-msgid "templates not found %s"
-msgstr "các mẫu không được tìm thấy %s"
+msgid "templates not found in %s"
+msgstr "các mẫu không được tìm thấy trong %s"
 
 #: builtin/init-db.c:135
 #, c-format
@@ -9746,11 +10210,6 @@ msgstr "các quyền"
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr "chỉ ra cái mà kho git được chia sẻ giữa nhiều người dùng"
 
-#: builtin/init-db.c:516 builtin/init-db.c:521
-#, c-format
-msgid "cannot mkdir %s"
-msgstr "không thể mkdir (tạo thư mục): %s"
-
 #: builtin/init-db.c:525
 #, c-format
 msgid "cannot chdir to %s"
@@ -9934,7 +10393,7 @@ msgstr "Hai thư mục kết xuất?"
 msgid "Unknown commit %s"
 msgstr "Không hiểu lần chuyển giao %s"
 
-#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:522
+#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:523
 #, 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ệ."
@@ -10289,7 +10748,7 @@ msgstr ""
 msgid "show debugging data"
 msgstr "hiển thị dữ liệu gỡ lỗi"
 
-#: builtin/ls-remote.c:7
+#: builtin/ls-remote.c:9
 msgid ""
 "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
@@ -10299,39 +10758,39 @@ msgstr ""
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
 "                     [--symref] [<kho> [<các tham chiếu>…]]"
 
-#: builtin/ls-remote.c:52
+#: builtin/ls-remote.c:59
 msgid "do not print remote URL"
 msgstr "không hiển thị URL máy chủ"
 
-#: builtin/ls-remote.c:53 builtin/ls-remote.c:55
+#: builtin/ls-remote.c:60 builtin/ls-remote.c:62
 msgid "exec"
 msgstr "thực thi"
 
-#: builtin/ls-remote.c:54 builtin/ls-remote.c:56
+#: builtin/ls-remote.c:61 builtin/ls-remote.c:63
 msgid "path of git-upload-pack on the remote host"
 msgstr "đường dẫn của git-upload-pack trên máy chủ"
 
-#: builtin/ls-remote.c:58
+#: builtin/ls-remote.c:65
 msgid "limit to tags"
 msgstr "giới hạn tới các thẻ"
 
-#: builtin/ls-remote.c:59
+#: builtin/ls-remote.c:66
 msgid "limit to heads"
 msgstr "giới hạn cho các đầu"
 
-#: builtin/ls-remote.c:60
+#: builtin/ls-remote.c:67
 msgid "do not show peeled tags"
 msgstr "không hiển thị thẻ bị peel (gọt bỏ)"
 
-#: builtin/ls-remote.c:62
+#: builtin/ls-remote.c:69
 msgid "take url.<base>.insteadOf into account"
 msgstr "lấy url.<base>.insteadOf vào trong tài khoản"
 
-#: builtin/ls-remote.c:64
+#: builtin/ls-remote.c:73
 msgid "exit with exit code 2 if no matching refs are found"
 msgstr "thoát với mã là 2 nếu không tìm thấy tham chiếu nào khớp"
 
-#: builtin/ls-remote.c:67
+#: builtin/ls-remote.c:76
 msgid "show underlying ref in addition to the object pointed by it"
 msgstr "hiển thị tham chiếu nằm dưới để thêm vào đối tượng được chỉ bởi nó"
 
@@ -10376,167 +10835,167 @@ msgstr "liệt kê cây mục tin; không chỉ thư mục hiện hành (ngụ 
 msgid "empty mbox: '%s'"
 msgstr "mbox trống rỗng: “%s”"
 
-#: builtin/merge.c:49
+#: builtin/merge.c:51
 msgid "git merge [<options>] [<commit>...]"
 msgstr "git merge [<các-tùy-chọn>] [<commit>…]"
 
-#: builtin/merge.c:50
+#: builtin/merge.c:52
 msgid "git merge --abort"
 msgstr "git merge --abort"
 
-#: builtin/merge.c:51
+#: builtin/merge.c:53
 msgid "git merge --continue"
 msgstr "git merge --continue"
 
-#: builtin/merge.c:108
+#: builtin/merge.c:110
 msgid "switch `m' requires a value"
 msgstr "switch “m” yêu cầu một giá trị"
 
-#: builtin/merge.c:145
+#: builtin/merge.c:147
 #, 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"
 
-#: builtin/merge.c:146
+#: builtin/merge.c:148
 #, c-format
 msgid "Available strategies are:"
 msgstr "Các chiến lược sẵn sàng là:"
 
-#: builtin/merge.c:151
+#: builtin/merge.c:153
 #, c-format
 msgid "Available custom strategies are:"
 msgstr "Các chiến lược tùy chỉnh sẵn sàng là:"
 
-#: builtin/merge.c:201 builtin/pull.c:137
+#: builtin/merge.c:203 builtin/pull.c:142
 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"
 
-#: builtin/merge.c:204 builtin/pull.c:140
+#: builtin/merge.c:206 builtin/pull.c:145
 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"
 
-#: builtin/merge.c:205 builtin/pull.c:143
+#: builtin/merge.c:207 builtin/pull.c:148
 msgid "(synonym to --stat)"
 msgstr "(đồng nghĩa với --stat)"
 
-#: builtin/merge.c:207 builtin/pull.c:146
+#: builtin/merge.c:209 builtin/pull.c:151
 msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr "thêm (ít nhất <n>) mục từ shortlog cho ghi chú chuyển giao hòa trộn"
 
-#: builtin/merge.c:210 builtin/pull.c:152
+#: builtin/merge.c:212 builtin/pull.c:157
 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"
 
-#: builtin/merge.c:212 builtin/pull.c:155
+#: builtin/merge.c:214 builtin/pull.c:160
 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)"
 
-#: builtin/merge.c:214 builtin/pull.c:158
+#: builtin/merge.c:216 builtin/pull.c:163
 msgid "edit message before committing"
 msgstr "sửa chú thích trước khi chuyển giao"
 
-#: builtin/merge.c:215
+#: builtin/merge.c:217
 msgid "allow fast-forward (default)"
 msgstr "cho phép chuyển-tiếp-nhanh (mặc định)"
 
-#: builtin/merge.c:217 builtin/pull.c:164
+#: builtin/merge.c:219 builtin/pull.c:169
 msgid "abort if fast-forward is not possible"
 msgstr "bỏ qua nếu chuyển-tiếp-nhanh không thể được"
 
-#: builtin/merge.c:221 builtin/pull.c:167
+#: builtin/merge.c:223 builtin/pull.c:172
 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"
 
-#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171
+#: builtin/merge.c:224 builtin/notes.c:777 builtin/pull.c:176
 #: builtin/revert.c:109
 msgid "strategy"
 msgstr "chiến lược"
 
-#: builtin/merge.c:223 builtin/pull.c:172
+#: builtin/merge.c:225 builtin/pull.c:177
 msgid "merge strategy to use"
 msgstr "chiến lược hòa trộn sẽ dùng"
 
-#: builtin/merge.c:224 builtin/pull.c:175
+#: builtin/merge.c:226 builtin/pull.c:180
 msgid "option=value"
 msgstr "tùy_chọn=giá_trị"
 
-#: builtin/merge.c:225 builtin/pull.c:176
+#: builtin/merge.c:227 builtin/pull.c:181
 msgid "option for selected merge strategy"
 msgstr "tùy chọn cho chiến lược hòa trộn đã chọn"
 
-#: builtin/merge.c:227
+#: builtin/merge.c:229
 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-"
 "nhanh)"
 
-#: builtin/merge.c:231
+#: builtin/merge.c:233
 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"
 
-#: builtin/merge.c:233
+#: builtin/merge.c:235
 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"
 
-#: builtin/merge.c:235 builtin/pull.c:183
+#: builtin/merge.c:237 builtin/pull.c:188
 msgid "allow merging unrelated histories"
 msgstr "cho phép hòa trộn lịch sử không liên quan"
 
-#: builtin/merge.c:241
+#: builtin/merge.c:243
 msgid "verify commit-msg hook"
 msgstr "thẩm tra móc (hook) commit-msg"
 
-#: builtin/merge.c:266
+#: builtin/merge.c:268
 msgid "could not run stash."
 msgstr "không thể chạy stash."
 
-#: builtin/merge.c:271
+#: builtin/merge.c:273
 msgid "stash failed"
 msgstr "lệnh tạm cất gặp lỗi"
 
-#: builtin/merge.c:276
+#: builtin/merge.c:278
 #, c-format
 msgid "not a valid object: %s"
 msgstr "không phải là một đối tượng hợp lệ: %s"
 
-#: builtin/merge.c:298 builtin/merge.c:315
+#: builtin/merge.c:300 builtin/merge.c:317
 msgid "read-tree failed"
 msgstr "read-tree gặp lỗi"
 
-#: builtin/merge.c:345
+#: builtin/merge.c:347
 msgid " (nothing to squash)"
 msgstr " (không có gì để squash)"
 
-#: builtin/merge.c:356
+#: builtin/merge.c:358
 #, c-format
 msgid "Squash commit -- not updating HEAD\n"
 msgstr "Squash commit -- không cập nhật HEAD\n"
 
-#: builtin/merge.c:406
+#: builtin/merge.c:408
 #, c-format
 msgid "No merge message -- not updating HEAD\n"
 msgstr "Không có lời chú thích hòa trộn -- nên không cập nhật HEAD\n"
 
-#: builtin/merge.c:456
+#: builtin/merge.c:458
 #, 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ả"
 
-#: builtin/merge.c:546
+#: builtin/merge.c:548
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "Chuỗi branch.%s.mergeoptions sai: %s"
 
-#: builtin/merge.c:668
+#: builtin/merge.c:669
 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"
 
-#: builtin/merge.c:682
+#: builtin/merge.c:683
 #, c-format
 msgid "Unknown option for merge-recursive: -X%s"
 msgstr "Không hiểu tùy chọn cho merge-recursive: -X%s"
 
-#: builtin/merge.c:697
+#: builtin/merge.c:698
 #, c-format
 msgid "unable to write %s"
 msgstr "không thể ghi %s"
@@ -10575,67 +11034,67 @@ msgstr ""
 msgid "Empty commit message."
 msgstr "Chú thích của lần commit (chuyển giao) bị trống rỗng."
 
-#: builtin/merge.c:820
+#: builtin/merge.c:819
 #, c-format
 msgid "Wonderful.\n"
 msgstr "Tuyệt vời.\n"
 
-#: builtin/merge.c:873
+#: builtin/merge.c:872
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr ""
 "Việc tự động hòa trộn gặp lỗi; hãy sửa các xung đột sau đó chuyển giao kết "
 "quả.\n"
 
-#: builtin/merge.c:912
+#: builtin/merge.c:911
 msgid "No current branch."
 msgstr "không phải nhánh hiện hành"
 
-#: builtin/merge.c:914
+#: builtin/merge.c:913
 msgid "No remote for the current branch."
 msgstr "Không có máy chủ cho nhánh hiện hành."
 
-#: builtin/merge.c:916
+#: builtin/merge.c:915
 msgid "No default upstream defined for the current branch."
 msgstr "Không có thượng nguồn mặc định được định nghĩa cho nhánh hiện hành."
 
-#: builtin/merge.c:921
+#: builtin/merge.c:920
 #, c-format
 msgid "No remote-tracking branch for %s from %s"
 msgstr "Không nhánh mạng theo dõi cho %s từ %s"
 
-#: builtin/merge.c:974
+#: builtin/merge.c:973
 #, c-format
 msgid "Bad value '%s' in environment '%s'"
 msgstr "Giá trị sai “%s” trong biến môi trường “%s”"
 
-#: builtin/merge.c:1076
+#: builtin/merge.c:1075
 #, 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"
 
-#: builtin/merge.c:1110
+#: builtin/merge.c:1109
 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"
 
-#: builtin/merge.c:1212
+#: builtin/merge.c:1211
 msgid "--abort expects no arguments"
 msgstr "--abort không nhận các đối số"
 
-#: builtin/merge.c:1216
+#: builtin/merge.c:1215
 msgid "There is no merge to abort (MERGE_HEAD missing)."
 msgstr ""
 "Ở đây không có lần hòa trộn nào được hủy bỏ giữa chừng cả (thiếu MERGE_HEAD)."
 
-#: builtin/merge.c:1228
+#: builtin/merge.c:1227
 msgid "--continue expects no arguments"
 msgstr "--continue không nhận đối số"
 
-#: builtin/merge.c:1232
+#: builtin/merge.c:1231
 msgid "There is no merge in progress (MERGE_HEAD missing)."
 msgstr "Ở đây không có lần hòa trộn nào đang được xử lý cả (thiếu MERGE_HEAD)."
 
-#: builtin/merge.c:1248
+#: builtin/merge.c:1247
 msgid ""
 "You have not concluded your merge (MERGE_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10643,7 +11102,7 @@ msgstr ""
 "Bạn chưa kết thúc việc hòa trộn (MERGE_HEAD vẫn tồn tại).\n"
 "Hãy chuyển giao các thay đổi trước khi bạn có thể hòa trộn."
 
-#: builtin/merge.c:1255
+#: builtin/merge.c:1254
 msgid ""
 "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10651,115 +11110,115 @@ msgstr ""
 "Bạn chưa kết thúc việc cherry-pick (CHERRY_PICK_HEAD vẫn tồn tại).\n"
 "Hãy chuyển giao các thay đổi trước khi bạn có thể hòa trộn."
 
-#: builtin/merge.c:1258
+#: builtin/merge.c:1257
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
 msgstr "Bạn chưa kết thúc việc cherry-pick (CHERRY_PICK_HEAD vẫn tồn tại)."
 
-#: builtin/merge.c:1267
+#: builtin/merge.c:1266
 msgid "You cannot combine --squash with --no-ff."
 msgstr "Bạn không thể kết hợp --squash với --no-ff."
 
-#: builtin/merge.c:1275
+#: builtin/merge.c:1274
 msgid "No commit specified and merge.defaultToUpstream not set."
 msgstr "Không chỉ ra lần chuyển giao và merge.defaultToUpstream chưa được đặt."
 
-#: builtin/merge.c:1292
+#: builtin/merge.c:1291
 msgid "Squash commit into empty head not supported yet"
 msgstr "Squash commit vào một head trống rỗng vẫn chưa được hỗ trợ"
 
-#: builtin/merge.c:1294
+#: builtin/merge.c:1293
 msgid "Non-fast-forward commit does not make sense into an empty head"
 msgstr ""
 "Chuyển giao không-chuyển-tiếp-nhanh không hợp lý ở trong một head trống rỗng"
 
-#: builtin/merge.c:1299
+#: builtin/merge.c:1298
 #, c-format
 msgid "%s - not something we can merge"
 msgstr "%s - không phải là thứ gì đó mà chúng tôi có thể hòa trộn"
 
-#: builtin/merge.c:1301
+#: builtin/merge.c:1300
 msgid "Can merge only exactly one commit into empty head"
 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"
 
-#: builtin/merge.c:1335
+#: builtin/merge.c:1334
 #, 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."
 
-#: builtin/merge.c:1338
+#: builtin/merge.c:1337
 #, c-format
 msgid "Commit %s has a bad GPG signature allegedly by %s."
 msgstr "Lần chuyển giao %s có một chữ ký GPG sai, được cho là bởi %s."
 
-#: builtin/merge.c:1341
+#: builtin/merge.c:1340
 #, c-format
 msgid "Commit %s does not have a GPG signature."
 msgstr "Lần chuyển giao %s không có chữ ký GPG."
 
-#: builtin/merge.c:1344
+#: builtin/merge.c:1343
 #, c-format
 msgid "Commit %s has a good GPG signature by %s\n"
 msgstr "Lần chuyển giao %s có một chữ ký GPG tốt bởi %s\n"
 
-#: builtin/merge.c:1403
+#: builtin/merge.c:1402
 msgid "refusing to merge unrelated histories"
 msgstr "từ chối hòa trộn lịch sử không liên quan"
 
-#: builtin/merge.c:1412
+#: builtin/merge.c:1411
 msgid "Already up to date."
 msgstr "Đã cập nhật rồi."
 
-#: builtin/merge.c:1422
+#: builtin/merge.c:1421
 #, c-format
 msgid "Updating %s..%s\n"
 msgstr "Đang cập nhật %s..%s\n"
 
-#: builtin/merge.c:1463
+#: builtin/merge.c:1462
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
 msgstr "Đang thử hòa trộn kiểu “trivial in-index”…\n"
 
-#: builtin/merge.c:1470
+#: builtin/merge.c:1469
 #, c-format
 msgid "Nope.\n"
 msgstr "Không.\n"
 
-#: builtin/merge.c:1495
+#: builtin/merge.c:1494
 msgid "Already up to date. Yeeah!"
 msgstr "Đã cập nhật rồi. Yeeah!"
 
-#: builtin/merge.c:1501
+#: builtin/merge.c:1500
 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."
 
-#: builtin/merge.c:1524 builtin/merge.c:1603
+#: builtin/merge.c:1523 builtin/merge.c:1602
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
 msgstr "Đang tua lại cây thành thời xa xưa…\n"
 
-#: builtin/merge.c:1528
+#: builtin/merge.c:1527
 #, c-format
 msgid "Trying merge strategy %s...\n"
 msgstr "Đang thử chiến lược hòa trộn %s…\n"
 
-#: builtin/merge.c:1594
+#: builtin/merge.c:1593
 #, 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"
 
-#: builtin/merge.c:1596
+#: builtin/merge.c:1595
 #, c-format
 msgid "Merge with strategy %s failed.\n"
 msgstr "Hòa trộn với chiến lược %s gặp lỗi.\n"
 
-#: builtin/merge.c:1605
+#: builtin/merge.c:1604
 #, c-format
 msgid "Using the %s to prepare resolving by hand.\n"
 msgstr "Sử dụng %s để chuẩn bị giải quyết bằng tay.\n"
 
-#: builtin/merge.c:1617
+#: builtin/merge.c:1616
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr ""
@@ -10896,26 +11355,26 @@ msgstr "cho phép tạo nhiều hơn một cây"
 msgid "git mv [<options>] <source>... <destination>"
 msgstr "git mv [<các-tùy-chọn>] <nguồn>… <đích>"
 
-#: builtin/mv.c:83
+#: builtin/mv.c:82
 #, 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?"
 
-#: builtin/mv.c:85 builtin/rm.c:289
+#: builtin/mv.c:84 builtin/rm.c:288
 msgid "Please stage your changes to .gitmodules or stash them to proceed"
 msgstr ""
 "Hãy đưa các thay đổi của bạn vào .gitmodules hay tạm cất chúng đi để xử lý"
 
-#: builtin/mv.c:103
+#: builtin/mv.c:102
 #, c-format
 msgid "%.*s is in index"
 msgstr "%.*s trong bảng mục lục"
 
-#: builtin/mv.c:125
+#: builtin/mv.c:124
 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"
 
-#: builtin/mv.c:127
+#: builtin/mv.c:126
 msgid "skip move/rename errors"
 msgstr "bỏ qua các lỗi liên quan đến di chuyển, đổi tên"
 
@@ -10980,7 +11439,7 @@ msgstr "%s, nguồn=%s, đích=%s"
 msgid "Renaming %s to %s\n"
 msgstr "Đổi tên %s thành %s\n"
 
-#: builtin/mv.c:276 builtin/remote.c:712 builtin/repack.c:394
+#: builtin/mv.c:276 builtin/remote.c:715 builtin/repack.c:409
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "gặp lỗi khi đổi tên “%s”"
@@ -11172,12 +11631,12 @@ msgstr "không thể ghi đối tượng ghi chú (note)"
 msgid "the note contents have been left in %s"
 msgstr "nội dung ghi chú còn lại %s"
 
-#: builtin/notes.c:234 builtin/tag.c:506
+#: builtin/notes.c:234 builtin/tag.c:507
 #, c-format
 msgid "cannot read '%s'"
 msgstr "không thể đọc “%s”"
 
-#: builtin/notes.c:236 builtin/tag.c:509
+#: builtin/notes.c:236 builtin/tag.c:510
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "không thể mở hay đọc “%s”"
@@ -11424,7 +11883,7 @@ msgstr "cố gắng gỡ bỏ một note chưa từng tồn tại không phải
 msgid "read object names from the standard input"
 msgstr "đọc tên đối tượng từ thiết bị nhập chuẩn"
 
-#: builtin/notes.c:943 builtin/prune.c:106 builtin/worktree.c:160
+#: builtin/notes.c:943 builtin/prune.c:107 builtin/worktree.c:151
 msgid "do not remove, show only"
 msgstr "không gỡ bỏ, chỉ hiển thị"
 
@@ -11445,213 +11904,241 @@ msgstr "dùng “notes” từ <notes-ref>"
 msgid "unknown subcommand: %s"
 msgstr "không hiểu câu lệnh con: %s"
 
-#: builtin/pack-objects.c:33
+#: builtin/pack-objects.c:48
 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> | < "
 "<danh-sách-đối-tượng>]"
 
-#: builtin/pack-objects.c:34
+#: builtin/pack-objects.c:49
 msgid ""
 "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-"
 "sách-đối-tượng>]"
 
-#: builtin/pack-objects.c:195 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:211 builtin/pack-objects.c:214
 #, c-format
 msgid "deflate error (%d)"
 msgstr "lỗi giải nén (%d)"
 
-#: builtin/pack-objects.c:791
+#: builtin/pack-objects.c:810
 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
 msgstr "tắt ghi bitmap, các gói bị chia nhỏ bởi vì pack.packSizeLimit"
 
-#: builtin/pack-objects.c:804
+#: builtin/pack-objects.c:823
 msgid "Writing objects"
 msgstr "Đang ghi lại các đối tượng"
 
-#: builtin/pack-objects.c:1084
+#: builtin/pack-objects.c:1106
 msgid "disabling bitmap writing, as some objects are not being packed"
 msgstr "tắt ghi bitmap, như vậy một số đối tượng sẽ không được đóng gói"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:1765
+msgid "Counting objects"
+msgstr "Đang đếm các đối tượng"
+
+#: builtin/pack-objects.c:1895
+#, c-format
+msgid "unable to get size of %s"
+msgstr "không thể lấy kích cỡ của %s"
+
+#: builtin/pack-objects.c:1910
+#, 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”"
+
+#: builtin/pack-objects.c:2564
 msgid "Compressing objects"
 msgstr "Đang nén các đối tượng"
 
-#: builtin/pack-objects.c:2625
+#: builtin/pack-objects.c:2735
 msgid "invalid value for --missing"
 msgstr "giá trị cho --missing không hợp lệ"
 
-#: builtin/pack-objects.c:2928
+#: builtin/pack-objects.c:3067
 #, c-format
 msgid "unsupported index version %s"
 msgstr "phiên bản mục lục không được hỗ trợ %s"
 
-#: builtin/pack-objects.c:2932
+#: builtin/pack-objects.c:3071
 #, c-format
 msgid "bad index version '%s'"
 msgstr "phiên bản mục lục sai “%s”"
 
-#: builtin/pack-objects.c:2962
+#: builtin/pack-objects.c:3102
 msgid "do not show progress meter"
 msgstr "không hiển thị bộ đo tiến trình"
 
-#: builtin/pack-objects.c:2964
+#: builtin/pack-objects.c:3104
 msgid "show progress meter"
 msgstr "hiển thị bộ đo tiến trình"
 
-#: builtin/pack-objects.c:2966
+#: builtin/pack-objects.c:3106
 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"
 
-#: builtin/pack-objects.c:2969
+#: builtin/pack-objects.c:3109
 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"
 
-#: builtin/pack-objects.c:2970
+#: builtin/pack-objects.c:3110
 msgid "version[,offset]"
 msgstr "phiên bản[,offset]"
 
-#: builtin/pack-objects.c:2971
+#: builtin/pack-objects.c:3111
 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"
 
-#: builtin/pack-objects.c:2974
+#: builtin/pack-objects.c:3114
 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"
 
-#: builtin/pack-objects.c:2976
+#: builtin/pack-objects.c:3116
 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ế"
 
-#: builtin/pack-objects.c:2978
+#: builtin/pack-objects.c:3118
 msgid "ignore packed objects"
 msgstr "bỏ qua các đối tượng đóng gói"
 
-#: builtin/pack-objects.c:2980
+#: builtin/pack-objects.c:3120
 msgid "limit pack window by objects"
 msgstr "giới hạn cửa sổ đóng gói theo đối tượng"
 
-#: builtin/pack-objects.c:2982
+#: builtin/pack-objects.c:3122
 msgid "limit pack window by memory in addition to object limit"
 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"
 
-#: builtin/pack-objects.c:2984
+#: builtin/pack-objects.c:3124
 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ả"
 
-#: builtin/pack-objects.c:2986
+#: builtin/pack-objects.c:3126
 msgid "reuse existing deltas"
 msgstr "dùng lại các delta sẵn có"
 
-#: builtin/pack-objects.c:2988
+#: builtin/pack-objects.c:3128
 msgid "reuse existing objects"
 msgstr "dùng lại các đối tượng sẵn có"
 
-#: builtin/pack-objects.c:2990
+#: builtin/pack-objects.c:3130
 msgid "use OFS_DELTA objects"
 msgstr "dùng các đối tượng OFS_DELTA"
 
-#: builtin/pack-objects.c:2992
+#: builtin/pack-objects.c:3132
 msgid "use threads when searching for best delta matches"
 msgstr "sử dụng các tuyến trình khi tìm kiếm cho các mẫu khớp delta tốt nhất"
 
-#: builtin/pack-objects.c:2994
+#: builtin/pack-objects.c:3134
 msgid "do not create an empty pack output"
 msgstr "không thể tạo kết xuất gói trống rỗng"
 
-#: builtin/pack-objects.c:2996
+#: builtin/pack-objects.c:3136
 msgid "read revision arguments from standard input"
 msgstr " đọc tham số “revision” từ thiết bị nhập chuẩn"
 
-#: builtin/pack-objects.c:2998
+#: builtin/pack-objects.c:3138
 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"
 
-#: builtin/pack-objects.c:3001
+#: builtin/pack-objects.c:3141
 msgid "include objects reachable from any reference"
 msgstr "bao gồm các đối tượng có thể đọc được từ bất kỳ tham chiếu nào"
 
-#: builtin/pack-objects.c:3004
+#: builtin/pack-objects.c:3144
 msgid "include objects referred by reflog entries"
 msgstr "bao gồm các đối tượng được tham chiếu bởi các mục reflog"
 
-#: builtin/pack-objects.c:3007
+#: builtin/pack-objects.c:3147
 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"
 
-#: builtin/pack-objects.c:3010
+#: builtin/pack-objects.c:3150
 msgid "output pack to stdout"
 msgstr "xuất gói ra đầu ra tiêu chuẩn"
 
-#: builtin/pack-objects.c:3012
+#: builtin/pack-objects.c:3152
 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"
 
-#: builtin/pack-objects.c:3014
+#: builtin/pack-objects.c:3154
 msgid "keep unreachable objects"
 msgstr "giữ lại các đối tượng không thể đọc được"
 
-#: builtin/pack-objects.c:3016
+#: builtin/pack-objects.c:3156
 msgid "pack loose unreachable objects"
 msgstr "pack mất các đối tượng không thể đọc được"
 
-#: builtin/pack-objects.c:3018
+#: builtin/pack-objects.c:3158
 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>"
 
-#: builtin/pack-objects.c:3021
+#: builtin/pack-objects.c:3161
 msgid "create thin packs"
 msgstr "tạo gói nhẹ"
 
-#: builtin/pack-objects.c:3023
+#: builtin/pack-objects.c:3163
 msgid "create packs suitable for shallow fetches"
 msgstr "tạo gói để phù hợp cho lấy về nông (shallow)"
 
-#: builtin/pack-objects.c:3025
+#: builtin/pack-objects.c:3165
 msgid "ignore packs that have companion .keep file"
 msgstr "bỏ qua các gói mà nó có tập tin .keep đi kèm"
 
-#: builtin/pack-objects.c:3027
+#: builtin/pack-objects.c:3167
+msgid "ignore this pack"
+msgstr "bỏ qua gói này"
+
+#: builtin/pack-objects.c:3169
 msgid "pack compression level"
 msgstr "mức nén gói"
 
-#: builtin/pack-objects.c:3029
+#: builtin/pack-objects.c:3171
 msgid "do not hide commits by grafts"
 msgstr "không ẩn các lần chuyển giao bởi “grafts”"
 
-#: builtin/pack-objects.c:3031
+#: builtin/pack-objects.c:3173
 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"
 
-#: builtin/pack-objects.c:3033
+#: builtin/pack-objects.c:3175
 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"
 
-#: builtin/pack-objects.c:3036
+#: builtin/pack-objects.c:3178
 msgid "handling for missing objects"
 msgstr "xử lý cho thiếu đối tượng"
 
-#: builtin/pack-objects.c:3039
+#: builtin/pack-objects.c:3181
 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"
 
-#: builtin/pack-objects.c:3178
-msgid "Counting objects"
-msgstr "Đang đếm các đối tượng"
+#: builtin/pack-objects.c:3205
+#, 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"
+
+#: builtin/pack-objects.c:3210
+#, c-format
+msgid "pack.deltaCacheLimit is too high, forcing %d"
+msgstr "pack.deltaCacheLimit là quá cao, ép dùng %d"
+
+#: builtin/pack-objects.c:3338
+msgid "Enumerating objects"
+msgstr "Đánh số các đối tượng"
 
-#: builtin/pack-refs.c:6
+#: builtin/pack-refs.c:7
 msgid "git pack-refs [<options>]"
 msgstr "git pack-refs [<các-tùy-chọn>]"
 
-#: builtin/pack-refs.c:14
+#: builtin/pack-refs.c:15
 msgid "pack everything"
 msgstr "đóng gói mọi thứ"
 
-#: builtin/pack-refs.c:15
+#: builtin/pack-refs.c:16
 msgid "prune loose refs (default)"
 msgstr "prune (cắt cụt) những tham chiếu bị mất (mặc định)"
 
@@ -11667,65 +12154,65 @@ msgstr "Đang gỡ các đối tượng trùng lặp"
 msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]"
 msgstr "git prune [-n] [-v] [--progress] [--expire <thời-gian>] [--] [<head>…]"
 
-#: builtin/prune.c:107
+#: builtin/prune.c:108
 msgid "report pruned objects"
 msgstr "báo cáo các đối tượng đã prune"
 
-#: builtin/prune.c:110
+#: builtin/prune.c:111
 msgid "expire objects older than <time>"
 msgstr "các đối tượng hết hạn cũ hơn khoảng <thời gian>"
 
-#: builtin/prune.c:112
+#: builtin/prune.c:113
 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"
 
-#: builtin/prune.c:126
+#: builtin/prune.c:127
 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"
 
-#: builtin/pull.c:54 builtin/pull.c:56
+#: builtin/pull.c:59 builtin/pull.c:61
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "Giá trị không hợp lệ %s: %s"
 
-#: builtin/pull.c:76
+#: builtin/pull.c:81
 msgid "git pull [<options>] [<repository> [<refspec>...]]"
 msgstr "git pull [<các-tùy-chọn>] [<kho-chứa> [<refspec>…]]"
 
-#: builtin/pull.c:127
+#: builtin/pull.c:132
 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"
 
-#: builtin/pull.c:131
+#: builtin/pull.c:136
 msgid "Options related to merging"
 msgstr "Các tùy chọn liên quan đến hòa trộn"
 
-#: builtin/pull.c:134
+#: builtin/pull.c:139
 msgid "incorporate changes by rebasing rather than merging"
 msgstr "các thay đổi hợp nhất bằng cải tổ thay vì hòa trộn"
 
-#: builtin/pull.c:161 builtin/rebase--helper.c:23 builtin/revert.c:121
+#: builtin/pull.c:166 builtin/rebase--helper.c:23 builtin/revert.c:121
 msgid "allow fast-forward"
 msgstr "cho phép chuyển-tiếp-nhanh"
 
-#: builtin/pull.c:170
+#: builtin/pull.c:175
 msgid "automatically stash/stash pop before and after rebase"
 msgstr "tự động stash/stash pop tước và sau tu bổ (rebase)"
 
-#: builtin/pull.c:186
+#: builtin/pull.c:191
 msgid "Options related to fetching"
 msgstr "Các tùy chọn liên quan đến lệnh lấy về"
 
-#: builtin/pull.c:204
+#: builtin/pull.c:209
 msgid "number of submodules pulled in parallel"
 msgstr "số lượng mô-đun-con được đẩy lên đồng thời"
 
-#: builtin/pull.c:299
+#: builtin/pull.c:304
 #, c-format
 msgid "Invalid value for pull.ff: %s"
 msgstr "Giá trị không hợp lệ cho pull.ff: %s"
 
-#: builtin/pull.c:415
+#: builtin/pull.c:420
 msgid ""
 "There is no candidate for rebasing against among the refs that you just "
 "fetched."
@@ -11733,14 +12220,14 @@ msgstr ""
 "Ở đây không có ứng cử nào để cải tổ lại trong số các tham chiếu mà bạn vừa "
 "lấy về."
 
-#: builtin/pull.c:417
+#: builtin/pull.c:422
 msgid ""
 "There are no candidates for merging among the refs that you just fetched."
 msgstr ""
 "Ở đây không có ứng cử nào để hòa trộn trong số các tham chiếu mà bạn vừa lấy "
 "về."
 
-#: builtin/pull.c:418
+#: builtin/pull.c:423
 msgid ""
 "Generally this means that you provided a wildcard refspec which had no\n"
 "matches on the remote end."
@@ -11749,7 +12236,7 @@ msgstr ""
 "tự\n"
 "đại diện mà nó lại không khớp trên điểm cuối máy phục vụ."
 
-#: builtin/pull.c:421
+#: builtin/pull.c:426
 #, c-format
 msgid ""
 "You asked to pull from the remote '%s', but did not specify\n"
@@ -11761,43 +12248,43 @@ msgstr ""
 "theo 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."
 
-#: builtin/pull.c:426 git-parse-remote.sh:73
+#: builtin/pull.c:431 git-parse-remote.sh:73
 msgid "You are not currently on a branch."
 msgstr "Hiện tại bạn chẳng ở nhánh nào cả."
 
-#: builtin/pull.c:428 builtin/pull.c:443 git-parse-remote.sh:79
+#: builtin/pull.c:433 builtin/pull.c:448 git-parse-remote.sh:79
 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."
 
-#: builtin/pull.c:430 builtin/pull.c:445 git-parse-remote.sh:82
+#: builtin/pull.c:435 builtin/pull.c:450 git-parse-remote.sh:82
 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."
 
-#: builtin/pull.c:431 builtin/pull.c:446
+#: builtin/pull.c:436 builtin/pull.c:451
 msgid "See git-pull(1) for details."
 msgstr "Xem git-pull(1) để biết thêm chi tiết."
 
-#: builtin/pull.c:433 builtin/pull.c:439 builtin/pull.c:448
+#: builtin/pull.c:438 builtin/pull.c:444 builtin/pull.c:453
 #: git-parse-remote.sh:64
 msgid "<remote>"
 msgstr "<máy chủ>"
 
-#: builtin/pull.c:433 builtin/pull.c:448 builtin/pull.c:453 git-rebase.sh:477
+#: builtin/pull.c:438 builtin/pull.c:453 builtin/pull.c:458 git-rebase.sh:523
 #: git-parse-remote.sh:65
 msgid "<branch>"
 msgstr "<nhánh>"
 
-#: builtin/pull.c:441 git-parse-remote.sh:75
+#: builtin/pull.c:446 git-parse-remote.sh:75
 msgid "There is no tracking information for the current branch."
 msgstr "Ở đây không có thông tin theo dõi cho nhánh hiện hành."
 
-#: builtin/pull.c:450 git-parse-remote.sh:95
+#: builtin/pull.c:455 git-parse-remote.sh:95
 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:"
 
-#: builtin/pull.c:455
+#: builtin/pull.c:460
 #, c-format
 msgid ""
 "Your configuration specifies to merge with the ref '%s'\n"
@@ -11806,29 +12293,29 @@ 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ề."
 
-#: builtin/pull.c:819
+#: builtin/pull.c:826
 msgid "ignoring --verify-signatures for rebase"
 msgstr "bỏ qua --verify-signatures khi rebase"
 
-#: builtin/pull.c:867
+#: builtin/pull.c:874
 msgid "--[no-]autostash option is only valid with --rebase."
 msgstr "tùy chọn --[no-]autostash chỉ hợp lệ khi dùng với --rebase."
 
-#: builtin/pull.c:875
+#: builtin/pull.c:882
 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."
 
-#: builtin/pull.c:878
+#: builtin/pull.c:885
 msgid "pull with rebase"
 msgstr "pull với rebase"
 
-#: builtin/pull.c:879
+#: builtin/pull.c:886
 msgid "please commit or stash them."
 msgstr "xin hãy chuyển giao hoặc tạm cất (stash) chúng."
 
-#: builtin/pull.c:904
+#: builtin/pull.c:911
 #, c-format
 msgid ""
 "fetch updated the current branch head.\n"
@@ -11839,7 +12326,7 @@ msgstr ""
 "đang chuyển-tiếp-nhanh cây làm việc của bạn từ\n"
 "lần chuyển giaot %s."
 
-#: builtin/pull.c:909
+#: builtin/pull.c:916
 #, c-format
 msgid ""
 "Cannot fast-forward your working tree.\n"
@@ -11857,32 +12344,32 @@ msgstr ""
 "$ git reset --hard\n"
 "để khôi phục lại."
 
-#: builtin/pull.c:924
+#: builtin/pull.c:931
 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."
 
-#: builtin/pull.c:928
+#: builtin/pull.c:935
 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."
 
-#: builtin/pull.c:935
+#: builtin/pull.c:942
 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ộ"
 
-#: builtin/push.c:17
+#: builtin/push.c:19
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr "git push [<các-tùy-chọn>] [<kho-chứa> [<refspec>…]]"
 
-#: builtin/push.c:92
+#: builtin/push.c:111
 msgid "tag shorthand without <tag>"
 msgstr "dùng tốc ký thẻ không có <thẻ>"
 
-#: builtin/push.c:102
+#: builtin/push.c:121
 msgid "--delete only accepts plain target ref names"
 msgstr "--delete chỉ chấp nhận các tên tham chiếu dạng thường"
 
-#: builtin/push.c:146
+#: builtin/push.c:165
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -11891,7 +12378,7 @@ msgstr ""
 "Để chọn mỗi tùy chọn một cách cố định, xem push.default trong “git help "
 "config”."
 
-#: builtin/push.c:149
+#: builtin/push.c:168
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -11916,7 +12403,7 @@ msgstr ""
 "    git push %s %s\n"
 "%s"
 
-#: builtin/push.c:164
+#: builtin/push.c:183
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -11931,7 +12418,7 @@ msgstr ""
 "\n"
 "    git push %s HEAD:<tên-của-nhánh-máy-chủ>\n"
 
-#: builtin/push.c:178
+#: builtin/push.c:197
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -11945,12 +12432,12 @@ msgstr ""
 "\n"
 "    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:186
+#: builtin/push.c:205
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr "Nhánh hiện tại %s có nhiều nhánh thượng nguồn, từ chối push."
 
-#: builtin/push.c:189
+#: builtin/push.c:208
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -11962,14 +12449,14 @@ msgstr ""
 "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."
 
-#: builtin/push.c:248
+#: builtin/push.c:267
 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ả\"."
 
-#: builtin/push.c:255
+#: builtin/push.c:274
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -11982,7 +12469,7 @@ msgstr ""
 "Xem “Note about fast-forwards” trong “git push --help” để có thông tin chi "
 "tiết."
 
-#: builtin/push.c:261
+#: builtin/push.c:280
 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"
@@ -11996,7 +12483,7 @@ msgstr ""
 "Xem “Note about fast-forwards” trong “git push --help” để có thông tin chi "
 "tiết."
 
-#: builtin/push.c:267
+#: builtin/push.c:286
 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"
@@ -12011,11 +12498,11 @@ msgstr ""
 "Xem “Note about fast-forwards” trong “git push --help” để có thông tin chi "
 "tiết."
 
-#: builtin/push.c:274
+#: builtin/push.c:293
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr "Việc cập nhật bị từ chối bởi vì thẻ đã sẵn có từ trước trên máy chủ."
 
-#: builtin/push.c:277
+#: builtin/push.c:296
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -12027,22 +12514,22 @@ msgstr ""
 "đối tượng\n"
 "không phải chuyển giao, mà không sử dụng tùy chọn “--force”.\n"
 
-#: builtin/push.c:337
+#: builtin/push.c:357
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "Đang đẩy lên %s\n"
 
-#: builtin/push.c:341
+#: builtin/push.c:361
 #, 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”"
 
-#: builtin/push.c:372
+#: builtin/push.c:395
 #, c-format
 msgid "bad repository '%s'"
 msgstr "repository (kho) sai “%s”"
 
-#: builtin/push.c:373
+#: builtin/push.c:396
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -12063,112 +12550,104 @@ msgstr ""
 "\n"
 "    git push <tên>\n"
 
-#: builtin/push.c:391
-msgid "--all and --tags are incompatible"
-msgstr "--all và --tags xung khắc nhau"
-
-#: builtin/push.c:392
-msgid "--all can't be combined with refspecs"
-msgstr "--all không thể được tổ hợp cùng với đặc tả đường dẫn"
-
-#: builtin/push.c:397
-msgid "--mirror and --tags are incompatible"
-msgstr "--mirror và --tags xung khắc nhau"
-
-#: builtin/push.c:398
-msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror không thể được tổ hợp cùng với đặc tả đường dẫn"
-
-#: builtin/push.c:403
-msgid "--all and --mirror are incompatible"
-msgstr "--all và --mirror xung khắc nhau"
-
-#: builtin/push.c:535
+#: builtin/push.c:551
 msgid "repository"
 msgstr "kho"
 
-#: builtin/push.c:536 builtin/send-pack.c:163
+#: builtin/push.c:552 builtin/send-pack.c:164
 msgid "push all refs"
 msgstr "đẩy tất cả các tham chiếu"
 
-#: builtin/push.c:537 builtin/send-pack.c:165
+#: builtin/push.c:553 builtin/send-pack.c:166
 msgid "mirror all refs"
 msgstr "mirror tất cả các tham chiếu"
 
-#: builtin/push.c:539
+#: builtin/push.c:555
 msgid "delete refs"
 msgstr "xóa các tham chiếu"
 
-#: builtin/push.c:540
+#: builtin/push.c:556
 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)"
 
-#: builtin/push.c:543 builtin/send-pack.c:166
+#: builtin/push.c:559 builtin/send-pack.c:167
 msgid "force updates"
 msgstr "ép buộc cập nhật"
 
-#: builtin/push.c:545 builtin/send-pack.c:180
+#: builtin/push.c:561 builtin/send-pack.c:181
 msgid "refname>:<expect"
 msgstr "tên-tham-chiếu>:<cần"
 
-#: builtin/push.c:546 builtin/send-pack.c:181
+#: builtin/push.c:562 builtin/send-pack.c:182
 msgid "require old value of ref to be at this value"
 msgstr "yêu cầu giá-trị cũ của tham chiếu thì là giá-trị này"
 
-#: builtin/push.c:549
+#: builtin/push.c:565
 msgid "control recursive pushing of submodules"
 msgstr "điều khiển việc đẩy lên (push) đệ qui của mô-đun-con"
 
-#: builtin/push.c:551 builtin/send-pack.c:174
+#: builtin/push.c:567 builtin/send-pack.c:175
 msgid "use thin pack"
 msgstr "tạo gói nhẹ"
 
-#: builtin/push.c:552 builtin/push.c:553 builtin/send-pack.c:160
-#: builtin/send-pack.c:161
+#: builtin/push.c:568 builtin/push.c:569 builtin/send-pack.c:161
+#: builtin/send-pack.c:162
 msgid "receive pack program"
 msgstr "chương trình nhận gói"
 
-#: builtin/push.c:554
+#: builtin/push.c:570
 msgid "set upstream for git pull/status"
 msgstr "đặt thượng nguồn cho git pull/status"
 
-#: builtin/push.c:557
+#: builtin/push.c:573
 msgid "prune locally removed refs"
 msgstr "xén tỉa những tham chiếu bị gỡ bỏ"
 
-#: builtin/push.c:559
+#: builtin/push.c:575
 msgid "bypass pre-push hook"
 msgstr "vòng qua móc tiền-đẩy (pre-push)"
 
-#: builtin/push.c:560
+#: builtin/push.c:576
 msgid "push missing but relevant tags"
 msgstr "push phần bị thiếu nhưng các thẻ lại thích hợp"
 
-#: builtin/push.c:563 builtin/send-pack.c:168
+#: builtin/push.c:579 builtin/send-pack.c:169
 msgid "GPG sign the push"
 msgstr "ký lần đẩy dùng GPG"
 
-#: builtin/push.c:565 builtin/send-pack.c:175
+#: builtin/push.c:581 builtin/send-pack.c:176
 msgid "request atomic transaction on remote side"
 msgstr "yêu cầu giao dịch hạt nhân bên phía máy chủ"
 
-#: builtin/push.c:566 builtin/send-pack.c:171
-msgid "server-specific"
-msgstr "đặc-tả-máy-phục-vụ"
-
-#: builtin/push.c:566 builtin/send-pack.c:172
-msgid "option to transmit"
-msgstr "tùy chọn để chuyển giao"
-
-#: builtin/push.c:583
+#: builtin/push.c:599
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr "--delete là xung khắc với các tùy chọn --all, --mirror và --tags"
 
-#: builtin/push.c:585
+#: builtin/push.c:601
 msgid "--delete doesn't make sense without any refs"
 msgstr "--delete không hợp lý nếu không có bất kỳ tham chiếu nào"
 
 #: builtin/push.c:604
+msgid "--all and --tags are incompatible"
+msgstr "--all và --tags xung khắc nhau"
+
+#: builtin/push.c:606
+msgid "--all can't be combined with refspecs"
+msgstr "--all không thể được tổ hợp cùng với đặc tả đường dẫn"
+
+#: builtin/push.c:610
+msgid "--mirror and --tags are incompatible"
+msgstr "--mirror và --tags xung khắc nhau"
+
+#: builtin/push.c:612
+msgid "--mirror can't be combined with refspecs"
+msgstr "--mirror không thể được tổ hợp cùng với đặc tả đường dẫn"
+
+#: builtin/push.c:615
+msgid "--all and --mirror are incompatible"
+msgstr "--all và --mirror xung khắc nhau"
+
+#: builtin/push.c:634
 msgid "push options must not have new line characters"
 msgstr "các tùy chọn push phải không có ký tự dòng mới"
 
@@ -12183,68 +12662,68 @@ msgstr ""
 "[--index-output=<tập-tin>] (--empty | <tree-ish1> [<tree-ish2> [<tree-"
 "ish3>]])"
 
-#: builtin/read-tree.c:121
+#: builtin/read-tree.c:120
 msgid "write resulting index to <file>"
 msgstr "ghi mục lục kết quả vào <tập-tin>"
 
-#: builtin/read-tree.c:124
+#: builtin/read-tree.c:123
 msgid "only empty the index"
 msgstr "chỉ với bảng mục lục trống rỗng"
 
-#: builtin/read-tree.c:126
+#: builtin/read-tree.c:125
 msgid "Merging"
 msgstr "Hòa trộn"
 
-#: builtin/read-tree.c:128
+#: builtin/read-tree.c:127
 msgid "perform a merge in addition to a read"
 msgstr "thực hiện một hòa trộn thêm vào việc đọc"
 
-#: builtin/read-tree.c:130
+#: builtin/read-tree.c:129
 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 "
 
-#: builtin/read-tree.c:132
+#: builtin/read-tree.c:131
 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”"
 
-#: builtin/read-tree.c:134
+#: builtin/read-tree.c:133
 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"
 
-#: builtin/read-tree.c:135
+#: builtin/read-tree.c:134
 msgid "<subdirectory>/"
 msgstr "<thư-mục-con>/"
 
-#: builtin/read-tree.c:136
+#: builtin/read-tree.c:135
 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>/"
 
-#: builtin/read-tree.c:139
+#: builtin/read-tree.c:138
 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"
 
-#: builtin/read-tree.c:141
+#: builtin/read-tree.c:140
 msgid "gitignore"
 msgstr "gitignore"
 
-#: builtin/read-tree.c:142
+#: builtin/read-tree.c:141
 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 đè"
 
-#: builtin/read-tree.c:145
+#: builtin/read-tree.c:144
 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"
 
-#: builtin/read-tree.c:146
+#: builtin/read-tree.c:145
 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"
 
-#: builtin/read-tree.c:148
+#: builtin/read-tree.c:147
 msgid "skip applying sparse checkout filter"
 msgstr "bỏ qua áp dụng bộ lọc lấy ra (checkout) thưa thớt"
 
-#: builtin/read-tree.c:150
+#: builtin/read-tree.c:149
 msgid "debug unpack-trees"
 msgstr "gỡ lỗi “unpack-trees”"
 
@@ -12261,46 +12740,58 @@ msgid "allow commits with empty messages"
 msgstr "chấp nhận chuyển giao mà không ghi chú gì"
 
 #: builtin/rebase--helper.c:27
+msgid "rebase merge commits"
+msgstr "cải tổ các lần chuyển giao hòa trộn"
+
+#: builtin/rebase--helper.c:29
+msgid "keep original branch points of cousins"
+msgstr "giữ các điểm nhánh nguyên bản của các anh em họ"
+
+#: builtin/rebase--helper.c:30
 msgid "continue rebase"
 msgstr "tiếp tục cải tổ"
 
-#: builtin/rebase--helper.c:29
+#: builtin/rebase--helper.c:32
 msgid "abort rebase"
 msgstr "bãi bỏ việc cải tổ"
 
-#: builtin/rebase--helper.c:32
+#: builtin/rebase--helper.c:35
 msgid "make rebase script"
 msgstr "tạo văn lệnh rebase"
 
-#: builtin/rebase--helper.c:34
+#: builtin/rebase--helper.c:37
 msgid "shorten commit ids in the todo list"
 msgstr "rút ngắn mã chuyển giao trong danh sách cần làm"
 
-#: builtin/rebase--helper.c:36
+#: builtin/rebase--helper.c:39
 msgid "expand commit ids in the todo list"
 msgstr "khai triển mã chuyển giao trong danh sách cần làm"
 
-#: builtin/rebase--helper.c:38
+#: builtin/rebase--helper.c:41
 msgid "check the todo list"
 msgstr "kiểm tra danh sách cần làm"
 
-#: builtin/rebase--helper.c:40
+#: builtin/rebase--helper.c:43
 msgid "skip unnecessary picks"
 msgstr "bỏ qua các lệnh cậy (pick) không cần thiết"
 
-#: builtin/rebase--helper.c:42
+#: builtin/rebase--helper.c:45
 msgid "rearrange fixup/squash lines"
 msgstr "sắp xếp lại các dòng fixup/squash"
 
-#: builtin/rebase--helper.c:44
+#: builtin/rebase--helper.c:47
 msgid "insert exec commands in todo list"
 msgstr "chèn các lệnh thực thi trong danh sách cần làm"
 
-#: builtin/receive-pack.c:30
+#: builtin/rebase--helper.c:68
+msgid "--[no-]rebase-cousins has no effect without --rebase-merges"
+msgstr "--[no-]rebase-cousins không có tác dụng khi không có --rebase-merges"
+
+#: builtin/receive-pack.c:31
 msgid "git receive-pack <git-dir>"
 msgstr "git receive-pack <thư-mục-git>"
 
-#: builtin/receive-pack.c:841
+#: builtin/receive-pack.c:842
 msgid ""
 "By default, updating the current branch in a non-bare repository\n"
 "is denied, because it will make the index and work tree inconsistent\n"
@@ -12330,7 +12821,7 @@ msgstr ""
 "Để 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”."
 
-#: builtin/receive-pack.c:861
+#: builtin/receive-pack.c:862
 msgid ""
 "By default, deleting the current branch is denied, because the next\n"
 "'git clone' won't result in any file checked out, causing confusion.\n"
@@ -12351,11 +12842,11 @@ msgstr ""
 "\n"
 "Để chấm dứt lời nhắn này, bạn hãy đặt nó thành “refuse”."
 
-#: builtin/receive-pack.c:1934
+#: builtin/receive-pack.c:1935
 msgid "quiet"
 msgstr "im lặng"
 
-#: builtin/receive-pack.c:1948
+#: builtin/receive-pack.c:1949
 msgid "You must specify a directory."
 msgstr "Bạn phải chỉ định thư mục."
 
@@ -12364,11 +12855,11 @@ msgstr "Bạn phải chỉ định thư mục."
 msgid "'%s' is not a valid timestamp"
 msgstr "“%s” không phải là dấu thời gian hợp lệ"
 
-#: builtin/remote.c:13
+#: builtin/remote.c:14
 msgid "git remote [-v | --verbose]"
 msgstr "git remote [-v | --verbose]"
 
-#: builtin/remote.c:14
+#: builtin/remote.c:15
 msgid ""
 "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <name> <url>"
@@ -12376,82 +12867,82 @@ msgstr ""
 "git remote add [-t <nhánh>] [-m <master>] [-f] [--tags|--no-tags] [--"
 "mirror=<fetch|push>] <tên> <url>"
 
-#: builtin/remote.c:15 builtin/remote.c:35
+#: builtin/remote.c:16 builtin/remote.c:36
 msgid "git remote rename <old> <new>"
 msgstr "git remote rename <tên-cũ> <tên-mới>"
 
-#: builtin/remote.c:16 builtin/remote.c:40
+#: builtin/remote.c:17 builtin/remote.c:41
 msgid "git remote remove <name>"
 msgstr "git remote remove <tên>"
 
-#: builtin/remote.c:17 builtin/remote.c:45
+#: builtin/remote.c:18 builtin/remote.c:46
 msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
 msgstr "git remote set-head <tên> (-a | --auto | -d | --delete | <nhánh>)"
 
-#: builtin/remote.c:18
+#: builtin/remote.c:19
 msgid "git remote [-v | --verbose] show [-n] <name>"
 msgstr "git remote [-v | --verbose] show [-n] <tên>"
 
-#: builtin/remote.c:19
+#: builtin/remote.c:20
 msgid "git remote prune [-n | --dry-run] <name>"
 msgstr "git remote prune [-n | --dry-run] <tên>"
 
-#: builtin/remote.c:20
+#: builtin/remote.c:21
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
 msgstr ""
 "git remote [-v | --verbose] update [-p | --prune] [(<nhóm> | <máy-chủ>)…]"
 
-#: builtin/remote.c:21
+#: builtin/remote.c:22
 msgid "git remote set-branches [--add] <name> <branch>..."
 msgstr "git remote set-branches [--add] <tên> <nhánh>…"
 
-#: builtin/remote.c:22 builtin/remote.c:71
+#: builtin/remote.c:23 builtin/remote.c:72
 msgid "git remote get-url [--push] [--all] <name>"
 msgstr "git remote set-url [--push] [--all] <tên>"
 
-#: builtin/remote.c:23 builtin/remote.c:76
+#: builtin/remote.c:24 builtin/remote.c:77
 msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]"
 msgstr "git remote set-url [--push] <tên> <url-mới> [<url-cũ>]"
 
-#: builtin/remote.c:24 builtin/remote.c:77
+#: builtin/remote.c:25 builtin/remote.c:78
 msgid "git remote set-url --add <name> <newurl>"
 msgstr "git remote set-url --add <tên> <url-mới>"
 
-#: builtin/remote.c:25 builtin/remote.c:78
+#: builtin/remote.c:26 builtin/remote.c:79
 msgid "git remote set-url --delete <name> <url>"
 msgstr "git remote set-url --delete <tên> <url>"
 
-#: builtin/remote.c:30
+#: builtin/remote.c:31
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<các-tùy-chọn>] <tên> <url>"
 
-#: builtin/remote.c:50
+#: builtin/remote.c:51
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <tên> <nhánh>…"
 
-#: builtin/remote.c:51
+#: builtin/remote.c:52
 msgid "git remote set-branches --add <name> <branch>..."
 msgstr "git remote set-branches --add <tên> <nhánh>…"
 
-#: builtin/remote.c:56
+#: builtin/remote.c:57
 msgid "git remote show [<options>] <name>"
 msgstr "git remote show [<các-tùy-chọn>] <tên>"
 
-#: builtin/remote.c:61
+#: builtin/remote.c:62
 msgid "git remote prune [<options>] <name>"
 msgstr "git remote prune [<các-tùy-chọn>] <tên>"
 
-#: builtin/remote.c:66
+#: builtin/remote.c:67
 msgid "git remote update [<options>] [<group> | <remote>]..."
 msgstr "git remote update [<các-tùy-chọn>] [<nhóm> | <máy-chủ>]…"
 
-#: builtin/remote.c:95
+#: builtin/remote.c:96
 #, c-format
 msgid "Updating %s"
 msgstr "Đang cập nhật %s"
 
-#: builtin/remote.c:127
+#: builtin/remote.c:128
 msgid ""
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
@@ -12459,86 +12950,86 @@ msgstr ""
 "--mirror nguy hiểm và không dùng nữa; xin hãy\n"
 "\t sử dụng tùy chọn --mirror=fetch hoặc --mirror=push để thay thế"
 
-#: builtin/remote.c:144
+#: builtin/remote.c:145
 #, c-format
 msgid "unknown mirror argument: %s"
 msgstr "không hiểu tham số máy bản sao (mirror): %s"
 
-#: builtin/remote.c:160
+#: builtin/remote.c:161
 msgid "fetch the remote branches"
 msgstr "lấy về các nhánh từ máy chủ"
 
-#: builtin/remote.c:162
+#: builtin/remote.c:163
 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ề"
 
-#: builtin/remote.c:165
+#: builtin/remote.c:166
 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)"
 
-#: builtin/remote.c:167
+#: builtin/remote.c:168
 msgid "branch(es) to track"
 msgstr "các nhánh để theo dõi"
 
-#: builtin/remote.c:168
+#: builtin/remote.c:169
 msgid "master branch"
 msgstr "nhánh master"
 
-#: builtin/remote.c:169
+#: builtin/remote.c:170
 msgid "push|fetch"
 msgstr "push|fetch"
 
-#: builtin/remote.c:170
+#: builtin/remote.c:171
 msgid "set up remote as a mirror to push to or fetch from"
 msgstr "đặt máy chủ (remote) như là một máy bản sao để push hay fetch từ đó"
 
-#: builtin/remote.c:182
+#: builtin/remote.c:183
 msgid "specifying a master branch makes no sense with --mirror"
 msgstr "đang chỉ định một nhánh master không hợp lý với tùy chọn --mirror"
 
-#: builtin/remote.c:184
+#: builtin/remote.c:185
 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”"
 
-#: builtin/remote.c:191 builtin/remote.c:631
+#: builtin/remote.c:192 builtin/remote.c:634
 #, c-format
 msgid "remote %s already exists."
 msgstr "máy chủ %s đã tồn tại rồi."
 
-#: builtin/remote.c:195 builtin/remote.c:635
+#: builtin/remote.c:196 builtin/remote.c:638
 #, c-format
 msgid "'%s' is not a valid remote name"
 msgstr "“%s” không phải tên máy chủ hợp lệ"
 
-#: builtin/remote.c:235
+#: builtin/remote.c:236
 #, c-format
 msgid "Could not setup master '%s'"
 msgstr "Không thể cài đặt nhánh master “%s”"
 
-#: builtin/remote.c:337
+#: builtin/remote.c:342
 #, c-format
 msgid "Could not get fetch map for refspec %s"
 msgstr "Không thể lấy ánh xạ (map) fetch cho đặc tả tham chiếu %s"
 
-#: builtin/remote.c:438 builtin/remote.c:446
+#: builtin/remote.c:441 builtin/remote.c:449
 msgid "(matching)"
 msgstr "(khớp)"
 
-#: builtin/remote.c:450
+#: builtin/remote.c:453
 msgid "(delete)"
 msgstr "(xóa)"
 
-#: builtin/remote.c:624 builtin/remote.c:759 builtin/remote.c:858
+#: builtin/remote.c:627 builtin/remote.c:762 builtin/remote.c:861
 #, c-format
 msgid "No such remote: %s"
 msgstr "Không có máy chủ nào như thế: %s"
 
-#: builtin/remote.c:641
+#: builtin/remote.c:644
 #, 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”"
 
-#: builtin/remote.c:661
+#: builtin/remote.c:664
 #, c-format
 msgid ""
 "Not updating non-default fetch refspec\n"
@@ -12549,17 +13040,17 @@ msgstr ""
 "\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."
 
-#: builtin/remote.c:697
+#: builtin/remote.c:700
 #, c-format
 msgid "deleting '%s' failed"
 msgstr "gặp lỗi khi xóa “%s”"
 
-#: builtin/remote.c:731
+#: builtin/remote.c:734
 #, c-format
 msgid "creating '%s' failed"
 msgstr "gặp lỗi khi tạo “%s”"
 
-#: builtin/remote.c:796
+#: builtin/remote.c:799
 msgid ""
 "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
 "to delete it, use:"
@@ -12571,113 +13062,119 @@ msgstr[0] ""
 "đi;\n"
 "để xóa đi, sử dụng:"
 
-#: builtin/remote.c:810
+#: builtin/remote.c:813
 #, c-format
 msgid "Could not remove config section '%s'"
 msgstr "Không thể gỡ bỏ phần cấu hình “%s”"
 
-#: builtin/remote.c:911
+#: builtin/remote.c:914
 #, c-format
 msgid " new (next fetch will store in remotes/%s)"
 msgstr " mới (lần lấy về tiếp theo sẽ lưu trong remotes/%s)"
 
-#: builtin/remote.c:914
+#: builtin/remote.c:917
 msgid " tracked"
 msgstr " được theo dõi"
 
-#: builtin/remote.c:916
+#: builtin/remote.c:919
 msgid " stale (use 'git remote prune' to remove)"
 msgstr " cũ rích (dùng “git remote prune” để gỡ bỏ)"
 
-#: builtin/remote.c:918
+#: builtin/remote.c:921
 msgid " ???"
 msgstr " ???"
 
-#: builtin/remote.c:959
+#: builtin/remote.c:962
 #, c-format
 msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
 msgstr "branch.%s.merge không hợp lệ; không thể cải tổ về phía > 1 nhánh"
 
-#: builtin/remote.c:967
+#: builtin/remote.c:971
 #, c-format
 msgid "rebases interactively onto remote %s"
 msgstr "thực hiện rebase một cách tương tác trên máy chủ %s"
 
-#: builtin/remote.c:968
+#: builtin/remote.c:973
+#, c-format
+msgid "rebases interactively (with merges) onto remote %s"
+msgstr ""
+"thực hiện cải tổ (với các hòa trộn) một cách tương tác lên trên máy chủ %s"
+
+#: builtin/remote.c:976
 #, c-format
 msgid "rebases onto remote %s"
 msgstr "thực hiện rebase trên máy chủ %s"
 
-#: builtin/remote.c:971
+#: builtin/remote.c:980
 #, c-format
 msgid " merges with remote %s"
 msgstr " hòa trộn với máy chủ %s"
 
-#: builtin/remote.c:974
+#: builtin/remote.c:983
 #, c-format
 msgid "merges with remote %s"
 msgstr "hòa trộn với máy chủ %s"
 
-#: builtin/remote.c:977
+#: builtin/remote.c:986
 #, c-format
 msgid "%-*s    and with remote %s\n"
 msgstr "%-*s    và với máy chủ %s\n"
 
-#: builtin/remote.c:1020
+#: builtin/remote.c:1029
 msgid "create"
 msgstr "tạo"
 
-#: builtin/remote.c:1023
+#: builtin/remote.c:1032
 msgid "delete"
 msgstr "xóa"
 
-#: builtin/remote.c:1027
+#: builtin/remote.c:1036
 msgid "up to date"
 msgstr "đã cập nhật"
 
-#: builtin/remote.c:1030
+#: builtin/remote.c:1039
 msgid "fast-forwardable"
 msgstr "có-thể-chuyển-tiếp-nhanh"
 
-#: builtin/remote.c:1033
+#: builtin/remote.c:1042
 msgid "local out of date"
 msgstr "dữ liệu nội bộ đã cũ"
 
-#: builtin/remote.c:1040
+#: builtin/remote.c:1049
 #, c-format
 msgid "    %-*s forces to %-*s (%s)"
 msgstr "    %-*s ép buộc thành %-*s (%s)"
 
-#: builtin/remote.c:1043
+#: builtin/remote.c:1052
 #, c-format
 msgid "    %-*s pushes to %-*s (%s)"
 msgstr "    %-*s đẩy lên thành %-*s (%s)"
 
-#: builtin/remote.c:1047
+#: builtin/remote.c:1056
 #, c-format
 msgid "    %-*s forces to %s"
 msgstr "    %-*s ép buộc thành %s"
 
-#: builtin/remote.c:1050
+#: builtin/remote.c:1059
 #, c-format
 msgid "    %-*s pushes to %s"
 msgstr "    %-*s đẩy lên thành %s"
 
-#: builtin/remote.c:1118
+#: builtin/remote.c:1127
 msgid "do not query remotes"
 msgstr "không truy vấn các máy chủ"
 
-#: builtin/remote.c:1145
+#: builtin/remote.c:1154
 #, c-format
 msgid "* remote %s"
 msgstr "* máy chủ %s"
 
-#: builtin/remote.c:1146
+#: builtin/remote.c:1155
 #, c-format
 msgid "  Fetch URL: %s"
 msgstr "  URL để lấy về: %s"
 
-#: builtin/remote.c:1147 builtin/remote.c:1163 builtin/remote.c:1302
+#: builtin/remote.c:1156 builtin/remote.c:1172 builtin/remote.c:1311
 msgid "(no URL)"
 msgstr "(không có URL)"
 
@@ -12685,181 +13182,181 @@ msgstr "(không có URL)"
 #. with the one in " Fetch URL: %s"
 #. translation.
 #.
-#: builtin/remote.c:1161 builtin/remote.c:1163
+#: builtin/remote.c:1170 builtin/remote.c:1172
 #, c-format
 msgid "  Push  URL: %s"
 msgstr "  URL để đẩy lên: %s"
 
-#: builtin/remote.c:1165 builtin/remote.c:1167 builtin/remote.c:1169
+#: builtin/remote.c:1174 builtin/remote.c:1176 builtin/remote.c:1178
 #, c-format
 msgid "  HEAD branch: %s"
 msgstr "  Nhánh HEAD: %s"
 
-#: builtin/remote.c:1165
+#: builtin/remote.c:1174
 msgid "(not queried)"
 msgstr "(không yêu cầu)"
 
-#: builtin/remote.c:1167
+#: builtin/remote.c:1176
 msgid "(unknown)"
 msgstr "(không hiểu)"
 
-#: builtin/remote.c:1171
+#: builtin/remote.c:1180
 #, c-format
 msgid ""
 "  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
 msgstr "  nhánh HEAD (HEAD máy chủ chưa rõ ràng, có lẽ là một trong số sau):\n"
 
-#: builtin/remote.c:1183
+#: builtin/remote.c:1192
 #, c-format
 msgid "  Remote branch:%s"
 msgid_plural "  Remote branches:%s"
 msgstr[0] "  Những nhánh trên máy chủ:%s"
 
-#: builtin/remote.c:1186 builtin/remote.c:1212
+#: builtin/remote.c:1195 builtin/remote.c:1221
 msgid " (status not queried)"
 msgstr " (trạng thái không được yêu cầu)"
 
-#: builtin/remote.c:1195
+#: builtin/remote.c:1204
 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”:"
 
-#: builtin/remote.c:1203
+#: builtin/remote.c:1212
 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”"
 
-#: builtin/remote.c:1209
+#: builtin/remote.c:1218
 #, 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:"
 
-#: builtin/remote.c:1230
+#: builtin/remote.c:1239
 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ủ"
 
-#: builtin/remote.c:1232
+#: builtin/remote.c:1241
 msgid "delete refs/remotes/<name>/HEAD"
 msgstr "xóa refs/remotes/<tên>/HEAD"
 
-#: builtin/remote.c:1247
+#: builtin/remote.c:1256
 msgid "Cannot determine remote HEAD"
 msgstr "Không thể xác định được HEAD máy chủ"
 
-#: builtin/remote.c:1249
+#: builtin/remote.c:1258
 msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
 msgstr "Nhiều nhánh HEAD máy chủ. Hãy chọn rõ ràng một:"
 
-#: builtin/remote.c:1259
+#: builtin/remote.c:1268
 #, c-format
 msgid "Could not delete %s"
 msgstr "Không thể xóa bỏ %s"
 
-#: builtin/remote.c:1267
+#: builtin/remote.c:1276
 #, c-format
 msgid "Not a valid ref: %s"
 msgstr "Không phải là tham chiếu hợp lệ: %s"
 
-#: builtin/remote.c:1269
+#: builtin/remote.c:1278
 #, c-format
 msgid "Could not setup %s"
 msgstr "Không thể cài đặt %s"
 
-#: builtin/remote.c:1287
+#: builtin/remote.c:1296
 #, c-format
 msgid " %s will become dangling!"
 msgstr " %s sẽ trở thành không đầu (không được quản lý)!"
 
-#: builtin/remote.c:1288
+#: builtin/remote.c:1297
 #, c-format
 msgid " %s has become dangling!"
 msgstr " %s đã trở thành không đầu (không được quản lý)!"
 
-#: builtin/remote.c:1298
+#: builtin/remote.c:1307
 #, c-format
 msgid "Pruning %s"
 msgstr "Đang xén bớt %s"
 
-#: builtin/remote.c:1299
+#: builtin/remote.c:1308
 #, c-format
 msgid "URL: %s"
 msgstr "URL: %s"
 
-#: builtin/remote.c:1315
+#: builtin/remote.c:1324
 #, c-format
 msgid " * [would prune] %s"
 msgstr " * [nên xén bớt] %s"
 
-#: builtin/remote.c:1318
+#: builtin/remote.c:1327
 #, c-format
 msgid " * [pruned] %s"
 msgstr " * [đã bị xén] %s"
 
-#: builtin/remote.c:1363
+#: builtin/remote.c:1372
 msgid "prune remotes after fetching"
 msgstr "cắt máy chủ sau khi lấy về"
 
-#: builtin/remote.c:1426 builtin/remote.c:1480 builtin/remote.c:1548
+#: builtin/remote.c:1435 builtin/remote.c:1489 builtin/remote.c:1557
 #, c-format
 msgid "No such remote '%s'"
 msgstr "Không có máy chủ nào có tên “%s”"
 
-#: builtin/remote.c:1442
+#: builtin/remote.c:1451
 msgid "add branch"
 msgstr "thêm nhánh"
 
-#: builtin/remote.c:1449
+#: builtin/remote.c:1458
 msgid "no remote specified"
 msgstr "chưa chỉ ra máy chủ nào"
 
-#: builtin/remote.c:1466
+#: builtin/remote.c:1475
 msgid "query push URLs rather than fetch URLs"
 msgstr "truy vấn đẩy URL thay vì lấy"
 
-#: builtin/remote.c:1468
+#: builtin/remote.c:1477
 msgid "return all URLs"
 msgstr "trả về mọi URL"
 
-#: builtin/remote.c:1496
+#: builtin/remote.c:1505
 #, 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”"
 
-#: builtin/remote.c:1522
+#: builtin/remote.c:1531
 msgid "manipulate push URLs"
 msgstr "đẩy các “URL” bằng tay"
 
-#: builtin/remote.c:1524
+#: builtin/remote.c:1533
 msgid "add URL"
 msgstr "thêm URL"
 
-#: builtin/remote.c:1526
+#: builtin/remote.c:1535
 msgid "delete URLs"
 msgstr "xóa URLs"
 
-#: builtin/remote.c:1533
+#: builtin/remote.c:1542
 msgid "--add --delete doesn't make sense"
 msgstr "--add --delete không hợp lý"
 
-#: builtin/remote.c:1572
+#: builtin/remote.c:1581
 #, c-format
 msgid "Invalid old URL pattern: %s"
 msgstr "Kiểu mẫu URL cũ không hợp lệ: %s"
 
-#: builtin/remote.c:1580
+#: builtin/remote.c:1589
 #, c-format
 msgid "No such URL found: %s"
 msgstr "Không tìm thấy URL như vậy: %s"
 
-#: builtin/remote.c:1582
+#: builtin/remote.c:1591
 msgid "Will not delete all non-push URLs"
 msgstr "Sẽ không xóa những địa chỉ URL không-push"
 
-#: builtin/remote.c:1598
+#: builtin/remote.c:1607
 msgid "be verbose; must be placed before a subcommand"
 msgstr "chi tiết; phải được đặt trước một lệnh-con"
 
-#: builtin/remote.c:1629
+#: builtin/remote.c:1638
 #, c-format
 msgid "Unknown subcommand: %s"
 msgstr "Không hiểu câu lệnh con: %s"
@@ -12876,127 +13373,135 @@ msgstr ""
 "Gia tăng repack là không tương thích với chỉ mục bitmap. Dùng\n"
 "--no-write-bitmap-index hay tắt cấu hình pack.writebitmaps."
 
-#: builtin/repack.c:170
+#: builtin/repack.c:180
 msgid "pack everything in a single pack"
 msgstr "đóng gói mọi thứ trong một gói đơn"
 
-#: builtin/repack.c:172
+#: builtin/repack.c:182
 msgid "same as -a, and turn unreachable objects loose"
 msgstr "giống với -a, và chỉnh sửa các đối tượng không đọc được thiếu sót"
 
-#: builtin/repack.c:175
+#: builtin/repack.c:185
 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"
 
-#: builtin/repack.c:177
+#: builtin/repack.c:187
 msgid "pass --no-reuse-delta to git-pack-objects"
 msgstr "chuyển --no-reuse-delta cho git-pack-objects"
 
-#: builtin/repack.c:179
+#: builtin/repack.c:189
 msgid "pass --no-reuse-object to git-pack-objects"
 msgstr "chuyển --no-reuse-object cho git-pack-objects"
 
-#: builtin/repack.c:181
+#: builtin/repack.c:191
 msgid "do not run git-update-server-info"
 msgstr "không chạy git-update-server-info"
 
-#: builtin/repack.c:184
+#: builtin/repack.c:194
 msgid "pass --local to git-pack-objects"
 msgstr "chuyển --local cho git-pack-objects"
 
-#: builtin/repack.c:186
+#: builtin/repack.c:196
 msgid "write bitmap index"
 msgstr "ghi mục lục ánh xạ"
 
-#: builtin/repack.c:187
+#: builtin/repack.c:197
 msgid "approxidate"
 msgstr "ngày ước tính"
 
-#: builtin/repack.c:188
+#: builtin/repack.c:198
 msgid "with -A, do not loosen objects older than this"
 msgstr "với -A, các đối tượng cũ hơn khoảng thời gian này thì không bị mất"
 
-#: builtin/repack.c:190
+#: builtin/repack.c:200
 msgid "with -a, repack unreachable objects"
 msgstr "với -a, đóng gói lại các đối tượng không thể đọc được"
 
-#: builtin/repack.c:192
+#: builtin/repack.c:202
 msgid "size of the window used for delta compression"
 msgstr "kích thước cửa sổ được dùng cho nén “delta”"
 
-#: builtin/repack.c:193 builtin/repack.c:199
+#: builtin/repack.c:203 builtin/repack.c:209
 msgid "bytes"
 msgstr "byte"
 
-#: builtin/repack.c:194
+#: builtin/repack.c:204
 msgid "same as the above, but limit memory size instead of entries count"
 msgstr "giống như trên, nhưng giới hạn kích thước bộ nhớ hay vì số lượng"
 
-#: builtin/repack.c:196
+#: builtin/repack.c:206
 msgid "limits the maximum delta depth"
 msgstr "giới hạn độ sâu tối đa của “delta”"
 
-#: builtin/repack.c:198
+#: builtin/repack.c:208
 msgid "limits the maximum number of threads"
 msgstr "giới hạn số lượng tối đa tuyến trình"
 
-#: builtin/repack.c:200
+#: builtin/repack.c:210
 msgid "maximum size of each packfile"
 msgstr "kích thước tối đa cho từng tập tin gói"
 
-#: builtin/repack.c:202
+#: builtin/repack.c:212
 msgid "repack objects in packs marked with .keep"
 msgstr "đóng gói lại các đối tượng trong các gói đã đánh dấu bằng .keep"
 
-#: builtin/repack.c:212
+#: builtin/repack.c:214
+msgid "do not repack this pack"
+msgstr "đừng đóng gói lại gói này"
+
+#: builtin/repack.c:224
 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"
 
-#: builtin/repack.c:216
+#: builtin/repack.c:228
 msgid "--keep-unreachable and -A are incompatible"
 msgstr "--keep-unreachable và -A xung khắc nhau"
 
-#: builtin/repack.c:410 builtin/worktree.c:148
+#: builtin/repack.c:425 builtin/worktree.c:139
 #, c-format
 msgid "failed to remove '%s'"
 msgstr "gặp lỗi khi gỡ bỏ “%s”"
 
-#: builtin/replace.c:20
+#: builtin/replace.c:22
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <đối-tượng> <thay-thế>"
 
-#: builtin/replace.c:21
+#: builtin/replace.c:23
 msgid "git replace [-f] --edit <object>"
 msgstr "git replace [-f] --edit <đối tượng>"
 
-#: builtin/replace.c:22
+#: builtin/replace.c:24
 msgid "git replace [-f] --graft <commit> [<parent>...]"
 msgstr "git replace [-f] --graft <lần_chuyển_giao> [<cha_mẹ>…]"
 
-#: builtin/replace.c:23
+#: builtin/replace.c:25
+msgid "git replace [-f] --convert-graft-file"
+msgstr "git replace [-f] --convert-graft-file"
+
+#: builtin/replace.c:26
 msgid "git replace -d <object>..."
 msgstr "git replace -d <đối tượng>…"
 
-#: builtin/replace.c:24
+#: builtin/replace.c:27
 msgid "git replace [--format=<format>] [-l [<pattern>]]"
 msgstr "git replace [--format=<định_dạng>] [-l [<mẫu>]]"
 
-#: builtin/replace.c:331 builtin/replace.c:369 builtin/replace.c:397
+#: builtin/replace.c:371 builtin/replace.c:415 builtin/replace.c:445
 #, c-format
 msgid "Not a valid object name: '%s'"
 msgstr "Không phải là tên đối tượng hợp lệ: “%s”"
 
-#: builtin/replace.c:361
+#: builtin/replace.c:407
 #, c-format
 msgid "bad mergetag in commit '%s'"
 msgstr "thẻ hòa trộn sai trong lần chuyển giao “%s”"
 
-#: builtin/replace.c:363
+#: builtin/replace.c:409
 #, 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”"
 
-#: builtin/replace.c:374
+#: builtin/replace.c:421
 #, c-format
 msgid ""
 "original commit '%s' contains mergetag '%s' that is discarded; use --edit "
@@ -13005,45 +13510,58 @@ 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"
 
-#: builtin/replace.c:407
+#: builtin/replace.c:460
 #, c-format
 msgid "the original commit '%s' has a gpg signature."
 msgstr "lần chuyển giao gốc “%s” có chữ ký GPG."
 
-#: builtin/replace.c:408
+#: builtin/replace.c:461
 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ế!"
 
-#: builtin/replace.c:414
+#: builtin/replace.c:471
 #, c-format
 msgid "could not write replacement commit for: '%s'"
 msgstr "không thể ghi lần chuyển giao thay thế cho: “%s”"
 
-#: builtin/replace.c:438
+#: builtin/replace.c:514
+#, c-format
+msgid ""
+"could not convert the following graft(s):\n"
+"%s"
+msgstr ""
+"Không thể chuyển đổi các graft sau đây:\n"
+"%s"
+
+#: builtin/replace.c:535
 msgid "list replace refs"
 msgstr "liệt kê các refs thay thế"
 
-#: builtin/replace.c:439
+#: builtin/replace.c:536
 msgid "delete replace refs"
 msgstr "xóa tham chiếu thay thế"
 
-#: builtin/replace.c:440
+#: builtin/replace.c:537
 msgid "edit existing object"
 msgstr "sửa đối tượng sẵn có"
 
-#: builtin/replace.c:441
+#: builtin/replace.c:538
 msgid "change a commit's parents"
 msgstr "thay đổi cha mẹ của lần chuyển giao"
 
-#: builtin/replace.c:442
+#: builtin/replace.c:539
+msgid "convert existing graft file"
+msgstr "chuyển đổi các tập tin graft sẵn có"
+
+#: builtin/replace.c:540
 msgid "replace the ref if it exists"
 msgstr "thay thế tham chiếu nếu nó đã sẵn có"
 
-#: builtin/replace.c:444
+#: builtin/replace.c:542
 msgid "do not pretty-print contents for --edit"
 msgstr "đừng in đẹp các nội dung cho --edit"
 
-#: builtin/replace.c:445
+#: builtin/replace.c:543
 msgid "use this format"
 msgstr "dùng định dạng này"
 
@@ -13205,23 +13723,23 @@ msgstr "rev-list không hỗ trợ hiển thị các ghi chú"
 msgid "cannot combine --use-bitmap-index with object filtering"
 msgstr "không thể tổ hợp --use-bitmap-index với lọc đối tượng"
 
-#: builtin/rev-parse.c:402
+#: builtin/rev-parse.c:406
 msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
 msgstr "git rev-parse --parseopt [<các-tùy-chọn>] -- [<các tham số>…]"
 
-#: builtin/rev-parse.c:407
+#: builtin/rev-parse.c:411
 msgid "keep the `--` passed as an arg"
 msgstr "giữ lại “--” chuyển sang làm tham số"
 
-#: builtin/rev-parse.c:409
+#: builtin/rev-parse.c:413
 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"
 
-#: builtin/rev-parse.c:412
+#: builtin/rev-parse.c:416
 msgid "output in stuck long form"
 msgstr "kết xuất trong định dạng gậy dài"
 
-#: builtin/rev-parse.c:545
+#: builtin/rev-parse.c:549
 msgid ""
 "git rev-parse --parseopt [<options>] -- [<args>...]\n"
 "   or: git rev-parse --sq-quote [<arg>...]\n"
@@ -13357,42 +13875,42 @@ msgid "the following file has local modifications:"
 msgid_plural "the following files have local modifications:"
 msgstr[0] "những tập tin sau đây có những thay đổi nội bộ:"
 
-#: builtin/rm.c:243
+#: builtin/rm.c:241
 msgid "do not list removed files"
 msgstr "không liệt kê các tập tin đã gỡ bỏ"
 
-#: builtin/rm.c:244
+#: builtin/rm.c:242
 msgid "only remove from the index"
 msgstr "chỉ gỡ bỏ từ mục lục"
 
-#: builtin/rm.c:245
+#: builtin/rm.c:243
 msgid "override the up-to-date check"
 msgstr "ghi đè lên kiểm tra cập nhật"
 
-#: builtin/rm.c:246
+#: builtin/rm.c:244
 msgid "allow recursive removal"
 msgstr "cho phép gỡ bỏ đệ qui"
 
-#: builtin/rm.c:248
+#: builtin/rm.c:246
 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"
 
-#: builtin/rm.c:307
+#: builtin/rm.c:306
 #, 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"
 
-#: builtin/rm.c:346
+#: builtin/rm.c:345
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm: không thể gỡ bỏ %s"
 
-#: builtin/rm.c:369
+#: builtin/rm.c:368
 #, c-format
 msgid "could not remove '%s'"
 msgstr "không thể gỡ bỏ “%s”"
 
-#: builtin/send-pack.c:19
+#: builtin/send-pack.c:20
 msgid ""
 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-"
 "receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> "
@@ -13404,50 +13922,70 @@ msgstr ""
 "chiếu>…]\n"
 "  --all và đặc tả <ref> rõ ràng là loại trừ lẫn nhau."
 
-#: builtin/send-pack.c:162
+#: builtin/send-pack.c:163
 msgid "remote name"
 msgstr "tên máy dịch vụ"
 
-#: builtin/send-pack.c:176
+#: builtin/send-pack.c:177
 msgid "use stateless RPC protocol"
 msgstr "dùng giao thức RPC không ổn định"
 
-#: builtin/send-pack.c:177
+#: builtin/send-pack.c:178
 msgid "read refs from stdin"
 msgstr "đọc tham chiếu từ đầu vào tiêu chuẩn"
 
-#: builtin/send-pack.c:178
+#: builtin/send-pack.c:179
 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ụ"
 
+#: builtin/serve.c:7
+msgid "git serve [<options>]"
+msgstr "git serve [<các-tùy-chọn>]"
+
+#: builtin/serve.c:17 builtin/upload-pack.c:23
+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"
+
+#: builtin/serve.c:19
+msgid "exit immediately after advertising capabilities"
+msgstr "thoát ngay sau khi khởi tạo quảng cáo capabilities"
+
 #: builtin/shortlog.c:14
-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>…]]"
+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>…]]"
 
-#: builtin/shortlog.c:263
+#: builtin/shortlog.c:15
+msgid "git log --pretty=short | git shortlog [<options>]"
+msgstr "git log --pretty=short | git shortlog [<các-tùy-chọn>]"
+
+#: builtin/shortlog.c:264
 msgid "Group by committer rather than author"
 msgstr "Nhóm theo người chuyển giao thay vì tác giả"
 
-#: builtin/shortlog.c:265
+#: builtin/shortlog.c:266
 msgid "sort output according to the number of commits per author"
 msgstr "sắp xếp kết xuất tuân theo số lượng chuyển giao trên mỗi tác giả"
 
-#: builtin/shortlog.c:267
+#: builtin/shortlog.c:268
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr "Chặn mọi mô tả lần chuyển giao, chỉ đưa ra số lượng lần chuyển giao"
 
-#: builtin/shortlog.c:269
+#: builtin/shortlog.c:270
 msgid "Show the email address of each author"
 msgstr "Hiển thị thư điện tử cho từng tác giả"
 
-#: builtin/shortlog.c:270
+#: builtin/shortlog.c:271
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:271
+#: builtin/shortlog.c:272
 msgid "Linewrap output"
 msgstr "Ngắt dòng khi quá dài"
 
+#: builtin/shortlog.c:298
+msgid "too many arguments given outside repository"
+msgstr "quá nhiều tham số đưa ra ngoài kho chứa"
+
 #: builtin/show-branch.c:12
 msgid ""
 "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
@@ -13645,39 +14183,39 @@ msgstr "giữ và xóa bỏ mọi dòng bắt đầu bằng ký tự ghi chú"
 msgid "prepend comment character and space to each line"
 msgstr "treo trước ký tự ghi chú và ký tự khoảng trắng cho từng dòng"
 
-#: builtin/submodule--helper.c:35 builtin/submodule--helper.c:1669
+#: builtin/submodule--helper.c:37 builtin/submodule--helper.c:1688
 #, c-format
 msgid "No such ref: %s"
 msgstr "Không có tham chiếu nào như thế: %s"
 
-#: builtin/submodule--helper.c:42 builtin/submodule--helper.c:1678
+#: builtin/submodule--helper.c:44 builtin/submodule--helper.c:1697
 #, 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"
 
-#: builtin/submodule--helper.c:59
+#: builtin/submodule--helper.c:61
 msgid "submodule--helper print-default-remote takes no arguments"
 msgstr "submodule--helper print-default-remote takes không nhận tham số"
 
-#: builtin/submodule--helper.c:96
+#: builtin/submodule--helper.c:98
 #, 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"
 
-#: builtin/submodule--helper.c:404 builtin/submodule--helper.c:1198
+#: builtin/submodule--helper.c:406 builtin/submodule--helper.c:1211
 msgid "alternative anchor for relative paths"
 msgstr "điểm neo thay thế cho các đường dẫn tương đối"
 
-#: builtin/submodule--helper.c:409
+#: builtin/submodule--helper.c:411
 msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper list [--prefix=</đường/dẫn>] [</đường/dẫn>…]"
 
-#: builtin/submodule--helper.c:460 builtin/submodule--helper.c:483
+#: builtin/submodule--helper.c:462 builtin/submodule--helper.c:485
 #, 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"
 
-#: builtin/submodule--helper.c:498
+#: builtin/submodule--helper.c:500
 #, c-format
 msgid ""
 "could not lookup configuration '%s'. Assuming this repository is its own "
@@ -13686,56 +14224,56 @@ msgstr ""
 "không thể tìm thấy cấu hình “%s”. Coi rằng kho này là thượng nguồn có quyền "
 "sở hữu chính nó."
 
-#: builtin/submodule--helper.c:509
+#: builtin/submodule--helper.c:511
 #, 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”"
 
-#: builtin/submodule--helper.c:513
+#: builtin/submodule--helper.c:515
 #, 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"
 
-#: builtin/submodule--helper.c:523
+#: builtin/submodule--helper.c:525
 #, 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"
 
-#: builtin/submodule--helper.c:530
+#: builtin/submodule--helper.c:532
 #, 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”"
 
-#: builtin/submodule--helper.c:552
+#: builtin/submodule--helper.c:554
 msgid "Suppress output for initializing a submodule"
 msgstr "Chặn kết xuất cho khởi tạo một mô-đun-con"
 
-#: builtin/submodule--helper.c:557
+#: builtin/submodule--helper.c:559
 msgid "git submodule--helper init [<path>]"
 msgstr "git submodule--helper init [</đường/dẫn>]"
 
-#: builtin/submodule--helper.c:625 builtin/submodule--helper.c:747
+#: builtin/submodule--helper.c:631 builtin/submodule--helper.c:757
 #, 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”"
 
-#: builtin/submodule--helper.c:660
+#: builtin/submodule--helper.c:670
 #, 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”"
 
-#: builtin/submodule--helper.c:687 builtin/submodule--helper.c:856
+#: builtin/submodule--helper.c:697 builtin/submodule--helper.c:866
 #, c-format
 msgid "failed to recurse into submodule '%s'"
 msgstr "gặp lỗi khi đệ quy vào trong mô-đun-con “%s”"
 
-#: builtin/submodule--helper.c:711 builtin/submodule--helper.c:1021
+#: builtin/submodule--helper.c:721 builtin/submodule--helper.c:1031
 msgid "Suppress submodule status output"
 msgstr "Chặn két xuất tình trạng mô-đun-con"
 
-#: builtin/submodule--helper.c:712
+#: builtin/submodule--helper.c:722
 msgid ""
 "Use commit stored in the index instead of the one stored in the submodule "
 "HEAD"
@@ -13743,52 +14281,52 @@ 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ô-"
 "đun-con"
 
-#: builtin/submodule--helper.c:713
+#: builtin/submodule--helper.c:723
 msgid "recurse into nested submodules"
 msgstr "đệ quy vào trong mô-đun-con lồng nhau"
 
-#: builtin/submodule--helper.c:718
+#: builtin/submodule--helper.c:728
 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
 msgstr ""
 "git submodule status [--quiet] [--cached] [--recursive] [</đường/dẫn>…]"
 
-#: builtin/submodule--helper.c:742
+#: builtin/submodule--helper.c:752
 msgid "git submodule--helper name <path>"
 msgstr "git submodule--helper name </đường/dẫn>"
 
-#: builtin/submodule--helper.c:806
+#: builtin/submodule--helper.c:816
 #, c-format
 msgid "Synchronizing submodule url for '%s'\n"
 msgstr "url mô-đun-con đồng bộ hóa cho “%s”\n"
 
-#: builtin/submodule--helper.c:812
+#: builtin/submodule--helper.c:822
 #, 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”"
 
-#: builtin/submodule--helper.c:826
+#: builtin/submodule--helper.c:836
 #, 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”"
 
-#: builtin/submodule--helper.c:837
+#: builtin/submodule--helper.c:847
 #, 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”"
 
-#: builtin/submodule--helper.c:885
+#: builtin/submodule--helper.c:895
 msgid "Suppress output of synchronizing submodule url"
 msgstr "Chặn kết xuất cho đồng bộ url mô-đun-con"
 
-#: builtin/submodule--helper.c:887
+#: builtin/submodule--helper.c:897
 msgid "Recurse into nested submodules"
 msgstr "Đệ quy vào trong các mô-đun-con lồng nhau"
 
-#: builtin/submodule--helper.c:892
+#: builtin/submodule--helper.c:902
 msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
 msgstr "git submodule--helper sync [--quiet] [--recursive] [</đường/dẫn>]"
 
-#: builtin/submodule--helper.c:946
+#: builtin/submodule--helper.c:956
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you "
@@ -13797,7 +14335,7 @@ msgstr ""
 "Cây làm việc mô-đun-con “%s” có chứa thư mục .git (dùng “rm -rf” nếu bạn "
 "thực sự muốn gỡ bỏ nó cùng với toàn bộ lịch sử của chúng)"
 
-#: builtin/submodule--helper.c:958
+#: builtin/submodule--helper.c:968
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains local modifications; use '-f' to discard "
@@ -13806,80 +14344,80 @@ 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 "
 "bỏ chúng đi"
 
-#: builtin/submodule--helper.c:966
+#: builtin/submodule--helper.c:976
 #, c-format
 msgid "Cleared directory '%s'\n"
 msgstr "Đã xóa thư mục “%s”\n"
 
-#: builtin/submodule--helper.c:968
+#: builtin/submodule--helper.c:978
 #, 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"
 
-#: builtin/submodule--helper.c:977
+#: builtin/submodule--helper.c:987
 #, 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”"
 
-#: builtin/submodule--helper.c:993
+#: builtin/submodule--helper.c:1003
 #, 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"
 
-#: builtin/submodule--helper.c:1022
+#: builtin/submodule--helper.c:1032
 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ộ"
 
-#: builtin/submodule--helper.c:1023
+#: builtin/submodule--helper.c:1033
 msgid "Unregister all submodules"
 msgstr "Bỏ đăng ký tất cả các trong mô-đun-con"
 
-#: builtin/submodule--helper.c:1028
+#: builtin/submodule--helper.c:1038
 msgid ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
 msgstr ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--]  [</đường/dẫn>…]]"
 
-#: builtin/submodule--helper.c:1042
+#: builtin/submodule--helper.c:1052
 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"
 
-#: builtin/submodule--helper.c:1133 builtin/submodule--helper.c:1136
+#: builtin/submodule--helper.c:1145 builtin/submodule--helper.c:1148
 #, c-format
 msgid "submodule '%s' cannot add alternate: %s"
 msgstr "mô-đun-con “%s” không thể thêm thay thế: %s"
 
-#: builtin/submodule--helper.c:1172
+#: builtin/submodule--helper.c:1184
 #, 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"
 
-#: builtin/submodule--helper.c:1179
+#: builtin/submodule--helper.c:1191
 #, 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"
 
-#: builtin/submodule--helper.c:1201
+#: builtin/submodule--helper.c:1214
 msgid "where the new submodule will be cloned to"
 msgstr "nhân bản mô-đun-con mới vào chỗ nào"
 
-#: builtin/submodule--helper.c:1204
+#: builtin/submodule--helper.c:1217
 msgid "name of the new submodule"
 msgstr "tên của mô-đun-con mới"
 
-#: builtin/submodule--helper.c:1207
+#: builtin/submodule--helper.c:1220
 msgid "url where to clone the submodule from"
 msgstr "url nơi mà nhân bản mô-đun-con từ đó"
 
-#: builtin/submodule--helper.c:1213
+#: builtin/submodule--helper.c:1228
 msgid "depth for shallow clones"
 msgstr "chiều sâu lịch sử khi tạo bản sao"
 
-#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1587
+#: builtin/submodule--helper.c:1231 builtin/submodule--helper.c:1606
 msgid "force cloning progress"
 msgstr "ép buộc tiến trình nhân bản"
 
-#: builtin/submodule--helper.c:1221
+#: builtin/submodule--helper.c:1236
 msgid ""
 "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
 "<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>"
@@ -13887,84 +14425,84 @@ msgstr ""
 "git submodule--helper clone [--prefix=</đường/dẫn>] [--quiet] [--reference "
 "<kho>] [--name <tên>] [--depth <sâu>] [--url <url>] [</đường/dẫn>…]"
 
-#: builtin/submodule--helper.c:1252
+#: builtin/submodule--helper.c:1267
 #, c-format
 msgid "clone of '%s' into submodule path '%s' failed"
 msgstr "Nhân bản “%s” vào đường dẫn mô-đun-con “%s” gặp lỗi"
 
-#: builtin/submodule--helper.c:1267
+#: builtin/submodule--helper.c:1281
 #, c-format
 msgid "could not get submodule directory for '%s'"
 msgstr "không thể lấy thư mục mô-đun-con cho “%s”"
 
-#: builtin/submodule--helper.c:1332
+#: builtin/submodule--helper.c:1347
 #, c-format
 msgid "Submodule path '%s' not initialized"
 msgstr "Đường dẫn mô-đun-con “%s” chưa được khởi tạo"
 
-#: builtin/submodule--helper.c:1336
+#: builtin/submodule--helper.c:1351
 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?"
 
-#: builtin/submodule--helper.c:1365
+#: builtin/submodule--helper.c:1380
 #, c-format
 msgid "Skipping unmerged submodule %s"
 msgstr "Bỏ qua các mô-đun-con chưa được hòa trộn %s"
 
-#: builtin/submodule--helper.c:1394
+#: builtin/submodule--helper.c:1409
 #, c-format
 msgid "Skipping submodule '%s'"
 msgstr "Bỏ qua mô-đun-con “%s”"
 
-#: builtin/submodule--helper.c:1527
+#: builtin/submodule--helper.c:1544
 #, 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"
 
-#: builtin/submodule--helper.c:1538
+#: builtin/submodule--helper.c:1555
 #, 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ỏ"
 
-#: builtin/submodule--helper.c:1568 builtin/submodule--helper.c:1788
+#: builtin/submodule--helper.c:1585 builtin/submodule--helper.c:1808
 msgid "path into the working tree"
 msgstr "đường dẫn đến cây làm việc"
 
-#: builtin/submodule--helper.c:1571
+#: builtin/submodule--helper.c:1588
 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"
 
-#: builtin/submodule--helper.c:1575
+#: builtin/submodule--helper.c:1592
 msgid "rebase, merge, checkout or none"
 msgstr "rebase, merge, checkout hoặc không làm gì cả"
 
-#: builtin/submodule--helper.c:1579
+#: builtin/submodule--helper.c:1598
 msgid "Create a shallow clone truncated to the specified number of revisions"
 msgstr ""
 "Tạo một bản sao nông được cắt ngắn thành số lượng điểm xét duyệt đã cho"
 
-#: builtin/submodule--helper.c:1582
+#: builtin/submodule--helper.c:1601
 msgid "parallel jobs"
 msgstr "công việc đồng thời"
 
-#: builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1603
 msgid "whether the initial clone should follow the shallow recommendation"
 msgstr "nhân bản lần đầu có nên theo khuyến nghị là nông hay không"
 
-#: builtin/submodule--helper.c:1585
+#: builtin/submodule--helper.c:1604
 msgid "don't print cloning progress"
 msgstr "đừng in tiến trình nhân bản"
 
-#: builtin/submodule--helper.c:1592
+#: builtin/submodule--helper.c:1611
 msgid "git submodule--helper update_clone [--prefix=<path>] [<path>...]"
 msgstr ""
 "git submodule--helper update_clone [--prefix=</đường/dẫn>] [</đường/dẫn>…]"
 
-#: builtin/submodule--helper.c:1605
+#: builtin/submodule--helper.c:1624
 msgid "bad value for update parameter"
 msgstr "giá trị cho  tham số cập nhật bị sai"
 
-#: builtin/submodule--helper.c:1673
+#: builtin/submodule--helper.c:1692
 #, c-format
 msgid ""
 "Submodule (%s) branch configured to inherit branch from superproject, but "
@@ -13973,20 +14511,20 @@ 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"
 
-#: builtin/submodule--helper.c:1789
+#: builtin/submodule--helper.c:1809
 msgid "recurse into submodules"
 msgstr "đệ quy vào trong mô-đun-con"
 
-#: builtin/submodule--helper.c:1795
+#: builtin/submodule--helper.c:1815
 msgid "git submodule--helper embed-git-dir [<path>...]"
 msgstr "git submodule--helper embed-git-dir [</đường/dẫn>…]"
 
-#: builtin/submodule--helper.c:1857
+#: builtin/submodule--helper.c:1901
 #, c-format
 msgid "%s doesn't support --super-prefix"
 msgstr "%s không hỗ trợ --super-prefix"
 
-#: builtin/submodule--helper.c:1863
+#: builtin/submodule--helper.c:1907
 #, 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ệ"
@@ -14055,7 +14593,7 @@ msgstr "không tìm thấy tìm thấy thẻ “%s”."
 msgid "Deleted tag '%s' (was %s)\n"
 msgstr "Thẻ đã bị xóa “%s” (từng là %s)\n"
 
-#: builtin/tag.c:131
+#: builtin/tag.c:132
 #, c-format
 msgid ""
 "\n"
@@ -14068,7 +14606,7 @@ msgstr ""
 "  %s\n"
 "Những dòng được bắt đầu bằng “%c” sẽ được bỏ qua.\n"
 
-#: builtin/tag.c:135
+#: builtin/tag.c:136
 #, c-format
 msgid ""
 "\n"
@@ -14083,147 +14621,147 @@ msgstr ""
 "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 "
 "nếu muốn.\n"
 
-#: builtin/tag.c:189
+#: builtin/tag.c:190
 msgid "unable to sign the tag"
 msgstr "không thể ký thẻ"
 
-#: builtin/tag.c:191
+#: builtin/tag.c:192
 msgid "unable to write tag file"
 msgstr "không thể ghi vào tập tin lưu thẻ"
 
-#: builtin/tag.c:216
+#: builtin/tag.c:217
 msgid "bad object type."
 msgstr "kiểu đối tượng sai."
 
-#: builtin/tag.c:265
+#: builtin/tag.c:266
 msgid "no tag message?"
 msgstr "không có chú thích gì cho cho thẻ à?"
 
-#: builtin/tag.c:272
+#: builtin/tag.c:273
 #, c-format
 msgid "The tag message has been left in %s\n"
 msgstr "Nội dung ghi chú còn lại %s\n"
 
-#: builtin/tag.c:381
+#: builtin/tag.c:382
 msgid "list tag names"
 msgstr "chỉ liệt kê tên các thẻ"
 
-#: builtin/tag.c:383
+#: builtin/tag.c:384
 msgid "print <n> lines of each tag message"
 msgstr "hiển thị <n> dòng cho mỗi ghi chú"
 
-#: builtin/tag.c:385
+#: builtin/tag.c:386
 msgid "delete tags"
 msgstr "xóa thẻ"
 
-#: builtin/tag.c:386
+#: builtin/tag.c:387
 msgid "verify tags"
 msgstr "thẩm tra thẻ"
 
-#: builtin/tag.c:388
+#: builtin/tag.c:389
 msgid "Tag creation options"
 msgstr "Tùy chọn tạo thẻ"
 
-#: builtin/tag.c:390
+#: builtin/tag.c:391
 msgid "annotated tag, needs a message"
 msgstr "để chú giải cho thẻ, cần một lời ghi chú"
 
-#: builtin/tag.c:392
+#: builtin/tag.c:393
 msgid "tag message"
 msgstr "phần chú thích cho thẻ"
 
-#: builtin/tag.c:394
+#: builtin/tag.c:395
 msgid "force edit of tag message"
 msgstr "ép buộc sửa thẻ lần commit"
 
-#: builtin/tag.c:395
+#: builtin/tag.c:396
 msgid "annotated and GPG-signed tag"
 msgstr "thẻ chú giải và ký kiểu GPG"
 
-#: builtin/tag.c:399
+#: builtin/tag.c:400
 msgid "use another key to sign the tag"
 msgstr "dùng kháo khác để ký thẻ"
 
-#: builtin/tag.c:400
+#: builtin/tag.c:401
 msgid "replace the tag if exists"
 msgstr "thay thế nếu thẻ đó đã có trước"
 
-#: builtin/tag.c:401 builtin/update-ref.c:368
+#: builtin/tag.c:402 builtin/update-ref.c:368
 msgid "create a reflog"
 msgstr "tạo một reflog"
 
-#: builtin/tag.c:403
+#: builtin/tag.c:404
 msgid "Tag listing options"
 msgstr "Các tùy chọn liệt kê thẻ"
 
-#: builtin/tag.c:404
+#: builtin/tag.c:405
 msgid "show tag list in columns"
 msgstr "hiển thị danh sách thẻ trong các cột"
 
-#: builtin/tag.c:405 builtin/tag.c:407
+#: builtin/tag.c:406 builtin/tag.c:408
 msgid "print only tags that contain the commit"
 msgstr "chỉ hiển thị những nhánh mà nó chứa lần chuyển giao"
 
-#: builtin/tag.c:406 builtin/tag.c:408
+#: builtin/tag.c:407 builtin/tag.c:409
 msgid "print only tags that don't contain the commit"
 msgstr "chỉ hiển thị những thẻ mà nó không chứa lần chuyển giao"
 
-#: builtin/tag.c:409
+#: builtin/tag.c:410
 msgid "print only tags that are merged"
 msgstr "chỉ hiển thị những thẻ mà nó được hòa trộn"
 
-#: builtin/tag.c:410
+#: builtin/tag.c:411
 msgid "print only tags that are not merged"
 msgstr "chỉ hiển thị những thẻ mà nó không được hòa trộn"
 
-#: builtin/tag.c:415
+#: builtin/tag.c:416
 msgid "print only tags of the object"
 msgstr "chỉ hiển thị các thẻ của đối tượng"
 
-#: builtin/tag.c:459
+#: builtin/tag.c:460
 msgid "--column and -n are incompatible"
 msgstr "--column và -n xung khắc nhau"
 
-#: builtin/tag.c:481
+#: builtin/tag.c:482
 msgid "-n option is only allowed in list mode"
 msgstr "tùy chọn -n chỉ cho phép dùng trong chế độ liệt kê"
 
-#: builtin/tag.c:483
+#: builtin/tag.c:484
 msgid "--contains option is only allowed in list mode"
 msgstr "tùy chọn --contains chỉ cho phép dùng trong chế độ liệt kê"
 
-#: builtin/tag.c:485
+#: builtin/tag.c:486
 msgid "--no-contains option is only allowed in list mode"
 msgstr "tùy chọn --no-contains chỉ cho phép dùng trong chế độ liệt kê"
 
-#: builtin/tag.c:487
+#: builtin/tag.c:488
 msgid "--points-at option is only allowed in list mode"
 msgstr "tùy chọn --points-at chỉ cho phép dùng trong chế độ liệt kê"
 
-#: builtin/tag.c:489
+#: builtin/tag.c:490
 msgid "--merged and --no-merged options are only allowed in list mode"
 msgstr ""
 "tùy chọn --merged và --no-merged chỉ cho phép dùng trong chế độ liệt kê"
 
-#: builtin/tag.c:500
+#: builtin/tag.c:501
 msgid "only one -F or -m option is allowed."
 msgstr "chỉ có một tùy chọn -F hoặc -m là được phép."
 
-#: builtin/tag.c:519
+#: builtin/tag.c:520
 msgid "too many params"
 msgstr "quá nhiều đối số"
 
-#: builtin/tag.c:525
+#: builtin/tag.c:526
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "“%s” không phải thẻ hợp lệ."
 
-#: builtin/tag.c:530
+#: builtin/tag.c:531
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "Thẻ “%s” đã tồn tại rồi"
 
-#: builtin/tag.c:561
+#: builtin/tag.c:562
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "Đã cập nhật thẻ “%s” (trước là %s)\n"
@@ -14292,147 +14830,147 @@ msgstr "thông tin thống kê thư mục không thay đổi sau khi xóa thư m
 msgid " OK"
 msgstr " Đồng ý"
 
-#: builtin/update-index.c:579
+#: builtin/update-index.c:589
 msgid "git update-index [<options>] [--] [<file>...]"
 msgstr "git update-index [<các-tùy-chọn>] [--] [<tập-tin>…]"
 
-#: builtin/update-index.c:936
+#: builtin/update-index.c:946
 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"
 
-#: builtin/update-index.c:939
+#: builtin/update-index.c:949
 msgid "refresh: ignore submodules"
 msgstr "refresh: lờ đi mô-đun-con"
 
-#: builtin/update-index.c:942
+#: builtin/update-index.c:952
 msgid "do not ignore new files"
 msgstr "không bỏ qua các tập tin mới tạo"
 
-#: builtin/update-index.c:944
+#: builtin/update-index.c:954
 msgid "let files replace directories and vice-versa"
 msgstr "để các tập tin thay thế các thư mục và “vice-versa”"
 
-#: builtin/update-index.c:946
+#: builtin/update-index.c:956
 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"
 
-#: builtin/update-index.c:948
+#: builtin/update-index.c:958
 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"
 
-#: builtin/update-index.c:951
+#: builtin/update-index.c:961
 msgid "refresh stat information"
 msgstr "lấy lại thông tin thống kê"
 
-#: builtin/update-index.c:955
+#: builtin/update-index.c:965
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "giống --refresh, nhưng bỏ qua các cài đặt “assume-unchanged”"
 
-#: builtin/update-index.c:959
+#: builtin/update-index.c:969
 msgid "<mode>,<object>,<path>"
 msgstr "<chế_độ>,<đối_tượng>,<đường_dẫn>"
 
-#: builtin/update-index.c:960
+#: builtin/update-index.c:970
 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"
 
-#: builtin/update-index.c:969
+#: builtin/update-index.c:979
 msgid "mark files as \"not changing\""
 msgstr "Đánh dấu các tập tin là \"không thay đổi\""
 
-#: builtin/update-index.c:972
+#: builtin/update-index.c:982
 msgid "clear assumed-unchanged bit"
 msgstr "xóa bít assumed-unchanged (giả định là không thay đổi)"
 
-#: builtin/update-index.c:975
+#: builtin/update-index.c:985
 msgid "mark files as \"index-only\""
 msgstr "đánh dấu các tập tin là “chỉ-đọc”"
 
-#: builtin/update-index.c:978
+#: builtin/update-index.c:988
 msgid "clear skip-worktree bit"
 msgstr "xóa bít skip-worktree"
 
-#: builtin/update-index.c:981
+#: builtin/update-index.c:991
 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"
 
-#: builtin/update-index.c:983
+#: builtin/update-index.c:993
 msgid "remove named paths even if present in worktree"
 msgstr ""
 "gỡ bỏ các đường dẫn được đặt tên thậm chí cả khi nó hiện diện trong thư mục "
 "làm việc"
 
-#: builtin/update-index.c:985
+#: builtin/update-index.c:995
 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"
 
-#: builtin/update-index.c:987
+#: builtin/update-index.c:997
 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"
 
-#: builtin/update-index.c:991
+#: builtin/update-index.c:1001
 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"
 
-#: builtin/update-index.c:995
+#: builtin/update-index.c:1005
 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ê"
 
-#: builtin/update-index.c:999
+#: builtin/update-index.c:1009
 msgid "only update entries that differ from HEAD"
 msgstr "chỉ cập nhật các mục tin mà nó khác biệt so với HEAD"
 
-#: builtin/update-index.c:1003
+#: builtin/update-index.c:1013
 msgid "ignore files missing from worktree"
 msgstr "bỏ qua các tập-tin thiếu trong thư-mục làm việc"
 
-#: builtin/update-index.c:1006
+#: builtin/update-index.c:1016
 msgid "report actions to standard output"
 msgstr "báo cáo các thao tác ra thiết bị xuất chuẩn"
 
-#: builtin/update-index.c:1008
+#: builtin/update-index.c:1018
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "(cho “porcelains”) quên các xung đột chưa được giải quyết đã ghi"
 
-#: builtin/update-index.c:1012
+#: builtin/update-index.c:1022
 msgid "write index in this format"
 msgstr "ghi mục lục ở định dạng này"
 
-#: builtin/update-index.c:1014
+#: builtin/update-index.c:1024
 msgid "enable or disable split index"
 msgstr "bật/tắt chia cắt bảng mục lục"
 
-#: builtin/update-index.c:1016
+#: builtin/update-index.c:1026
 msgid "enable/disable untracked cache"
 msgstr "bật/tắt bộ đệm không theo vết"
 
-#: builtin/update-index.c:1018
+#: builtin/update-index.c:1028
 msgid "test if the filesystem supports untracked cache"
 msgstr "kiểm tra xem hệ thống tập tin có hỗ trợ đệm không theo dõi hay không"
 
-#: builtin/update-index.c:1020
+#: builtin/update-index.c:1030
 msgid "enable untracked cache without testing the filesystem"
 msgstr "bật bộ đệm không theo vết mà không kiểm tra hệ thống tập tin"
 
-#: builtin/update-index.c:1022
+#: builtin/update-index.c:1032
 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"
 
-#: builtin/update-index.c:1024
+#: builtin/update-index.c:1034
 msgid "enable or disable file system monitor"
 msgstr "bật/tắt theo dõi hệ thống tập tin"
 
-#: builtin/update-index.c:1026
+#: builtin/update-index.c:1036
 msgid "mark files as fsmonitor valid"
 msgstr "đánh dấu các tập tin là hợp lệ fsmonitor"
 
-#: builtin/update-index.c:1029
+#: builtin/update-index.c:1039
 msgid "clear fsmonitor valid bit"
 msgstr "xóa bít hợp lệ fsmonitor"
 
-#: builtin/update-index.c:1127
+#: builtin/update-index.c:1138
 msgid ""
 "core.splitIndex is set to false; remove or change it, if you really want to "
 "enable split index"
@@ -14440,7 +14978,7 @@ 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"
 
-#: builtin/update-index.c:1136
+#: builtin/update-index.c:1147
 msgid ""
 "core.splitIndex is set to true; remove or change it, if you really want to "
 "disable split index"
@@ -14448,7 +14986,7 @@ 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"
 
-#: builtin/update-index.c:1147
+#: builtin/update-index.c:1158
 msgid ""
 "core.untrackedCache is set to true; remove or change it, if you really want "
 "to disable the untracked cache"
@@ -14456,11 +14994,11 @@ msgstr ""
 "core.untrackedCache được đặt là đúng; xóa bỏ hay thay đổi nó, nếu bạn thực "
 "sự muốn tắt bộ đệm chưa theo dõi"
 
-#: builtin/update-index.c:1151
+#: builtin/update-index.c:1162
 msgid "Untracked cache disabled"
 msgstr "Nhớ đệm không theo vết bị tắt"
 
-#: builtin/update-index.c:1159
+#: builtin/update-index.c:1170
 msgid ""
 "core.untrackedCache is set to false; remove or change it, if you really want "
 "to enable the untracked cache"
@@ -14468,29 +15006,29 @@ msgstr ""
 "core.untrackedCache được đặt là sai; xóa bỏ hay thay đổi nó, nếu bạn thực sự "
 "muốn bật bộ đệm chưa theo dõi"
 
-#: builtin/update-index.c:1163
+#: builtin/update-index.c:1174
 #, c-format
 msgid "Untracked cache enabled for '%s'"
 msgstr "Nhớ đệm không theo vết được bật cho “%s”"
 
-#: builtin/update-index.c:1171
+#: builtin/update-index.c:1182
 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
 msgstr ""
 "core.fsmonitor chưa được đặt; đặt nó nếu bạn thực sự muốn bật theo dõi hệ "
 "thống tập tin"
 
-#: builtin/update-index.c:1175
+#: builtin/update-index.c:1186
 msgid "fsmonitor enabled"
 msgstr "fsmonitor được bật"
 
-#: builtin/update-index.c:1178
+#: builtin/update-index.c:1189
 msgid ""
 "core.fsmonitor is set; remove it if you really want to disable fsmonitor"
 msgstr ""
 "core.fsmonitor đã được đặt; bỏ đặt nó nếu bạn thực sự muốn bật theo dõi hệ "
 "thống tập tin"
 
-#: builtin/update-index.c:1182
+#: builtin/update-index.c:1193
 msgid "fsmonitor disabled"
 msgstr "fsmonitor bị tắt"
 
@@ -14530,13 +15068,29 @@ msgstr "git update-server-info [--force]"
 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"
 
-#: builtin/verify-commit.c:18
-msgid "git verify-commit [-v | --verbose] <commit>..."
-msgstr "git verify-commit [-v | --verbose] <lần_chuyển_giao>…"
-
-#: builtin/verify-commit.c:73
-msgid "print commit contents"
-msgstr "hiển thị nội dung của lần chuyển giao"
+#: builtin/upload-pack.c:11
+msgid "git upload-pack [<options>] <dir>"
+msgstr "git upload-pack [<các-tùy-chọn>] </đường/dẫn>"
+
+#: builtin/upload-pack.c:25
+msgid "exit immediately after initial ref advertisement"
+msgstr "thoát ngay sau khi khởi tạo quảng cáo tham chiếu"
+
+#: builtin/upload-pack.c:27
+msgid "do not try <directory>/.git/ if <directory> is no Git directory"
+msgstr "đừng thử <thư_mục>/.git/ nếu <thư_mục> không phải là thư mục Git"
+
+#: builtin/upload-pack.c:29
+msgid "interrupt transfer after <n> seconds of inactivity"
+msgstr "ngắt truyền thông sau <n> giây không hoạt động"
+
+#: builtin/verify-commit.c:18
+msgid "git verify-commit [-v | --verbose] <commit>..."
+msgstr "git verify-commit [-v | --verbose] <lần_chuyển_giao>…"
+
+#: builtin/verify-commit.c:73
+msgid "print commit contents"
+msgstr "hiển thị nội dung của lần chuyển giao"
 
 #: builtin/verify-commit.c:74 builtin/verify-tag.c:38
 msgid "print raw gpg status output"
@@ -14590,198 +15144,213 @@ msgstr "git worktree remove [<các-tùy-chọn>] <worktree>"
 msgid "git worktree unlock <path>"
 msgstr "git worktree unlock </đường/dẫn>"
 
-#: builtin/worktree.c:60
+#: builtin/worktree.c:58
 #, c-format
 msgid "Removing worktrees/%s: not a valid directory"
 msgstr "Gỡ bỏ cây làm việc/%s: không phải là thư mục hợp lệ"
 
-#: builtin/worktree.c:66
+#: builtin/worktree.c:64
 #, c-format
 msgid "Removing worktrees/%s: gitdir file does not exist"
 msgstr "Gỡ bỏ cây làm việc/%s: không có tập tin gitdir"
 
-#: builtin/worktree.c:71 builtin/worktree.c:80
+#: builtin/worktree.c:69 builtin/worktree.c:78
 #, c-format
 msgid "Removing worktrees/%s: unable to read gitdir file (%s)"
 msgstr "Gỡ bỏ cây làm việc/%s: không thể đọc tập tin gitdir (%s)"
 
-#: builtin/worktree.c:90
+#: builtin/worktree.c:88
 #, c-format
 msgid ""
 "Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read "
 "%<PRIuMAX>)"
 msgstr "Gỡ bỏ cây làm việc/%s: đọc ngắn (cần %<PRIuMAX> byte, đọc %<PRIuMAX>)"
 
-#: builtin/worktree.c:98
+#: builtin/worktree.c:96
 #, c-format
 msgid "Removing worktrees/%s: invalid gitdir file"
 msgstr "Gỡ bỏ cây làm việc/%s: tập tin gitdir không hợp lệ"
 
-#: builtin/worktree.c:114
+#: builtin/worktree.c:105
 #, c-format
 msgid "Removing worktrees/%s: gitdir file points to non-existent location"
 msgstr "Gỡ bỏ cây làm việc/%s: tập tin gitdir chỉ đến vị trí không tồn tại"
 
-#: builtin/worktree.c:161
+#: builtin/worktree.c:152
 msgid "report pruned working trees"
 msgstr "báo cáo các cây làm việc đã prune"
 
-#: builtin/worktree.c:163
+#: builtin/worktree.c:154
 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>"
 
-#: builtin/worktree.c:238
+#: builtin/worktree.c:229
 #, c-format
 msgid "'%s' already exists"
 msgstr "“%s” đã có từ trước rồi"
 
-#: builtin/worktree.c:269
+#: builtin/worktree.c:260
 #, c-format
 msgid "could not create directory of '%s'"
 msgstr "không thể tạo thư mục của “%s”"
 
-#: builtin/worktree.c:308
+#: builtin/worktree.c:373 builtin/worktree.c:379
+#, c-format
+msgid "Preparing worktree (new branch '%s')"
+msgstr "Đang chuẩn bị cây làm việc (nhánh mới “%s”)"
+
+#: builtin/worktree.c:375
+#, 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)"
+
+#: builtin/worktree.c:384
 #, c-format
-msgid "Preparing %s (identifier %s)"
-msgstr "Đang chuẩn bị %s (định danh %s)"
+msgid "Preparing worktree (checking out '%s')"
+msgstr "Đang chuẩn bị cây làm việc (đang lấy ra “%s”)"
 
-#: builtin/worktree.c:385
+#: builtin/worktree.c:390
+#, 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”)"
+
+#: builtin/worktree.c:431
 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"
 
-#: builtin/worktree.c:388
+#: builtin/worktree.c:434
 msgid "create a new branch"
 msgstr "tạo nhánh mới"
 
-#: builtin/worktree.c:390
+#: builtin/worktree.c:436
 msgid "create or reset a branch"
 msgstr "tạo hay đặt lại một nhánh"
 
-#: builtin/worktree.c:392
+#: builtin/worktree.c:438
 msgid "populate the new working tree"
 msgstr "di chuyển cây làm việc mới"
 
-#: builtin/worktree.c:393
+#: builtin/worktree.c:439
 msgid "keep the new working tree locked"
 msgstr "giữ cây làm việc mới bị khóa"
 
-#: builtin/worktree.c:395
+#: builtin/worktree.c:441
 msgid "set up tracking mode (see git-branch(1))"
 msgstr "cài đặt chế độ theo dõi (xem git-branch(1))"
 
-#: builtin/worktree.c:398
+#: builtin/worktree.c:444
 msgid "try to match the new branch name with a remote-tracking branch"
 msgstr "có khớp tên tên nhánh mới với một nhánh theo dõi máy chủ"
 
-#: builtin/worktree.c:406
+#: builtin/worktree.c:452
 msgid "-b, -B, and --detach are mutually exclusive"
 msgstr "Các tùy chọn -b, -B, và --detach loại từ lẫn nhau"
 
-#: builtin/worktree.c:471
+#: builtin/worktree.c:511
 msgid "--[no-]track can only be used if a new branch is created"
 msgstr "--[no-]track chỉ có thể được dùng nếu một nhánh mới được tạo"
 
-#: builtin/worktree.c:571
+#: builtin/worktree.c:611
 msgid "reason for locking"
 msgstr "lý do khóa"
 
-#: builtin/worktree.c:583 builtin/worktree.c:616 builtin/worktree.c:670
-#: builtin/worktree.c:809
+#: builtin/worktree.c:623 builtin/worktree.c:656 builtin/worktree.c:710
+#: builtin/worktree.c:850
 #, c-format
 msgid "'%s' is not a working tree"
 msgstr "%s không phải là cây làm việc"
 
-#: builtin/worktree.c:585 builtin/worktree.c:618
+#: builtin/worktree.c:625 builtin/worktree.c:658
 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"
 
-#: builtin/worktree.c:590
+#: builtin/worktree.c:630
 #, c-format
 msgid "'%s' is already locked, reason: %s"
 msgstr "“%s” đã được khóa rồi, lý do: %s"
 
-#: builtin/worktree.c:592
+#: builtin/worktree.c:632
 #, c-format
 msgid "'%s' is already locked"
 msgstr "“%s” đã được khóa rồi"
 
-#: builtin/worktree.c:620
+#: builtin/worktree.c:660
 #, c-format
 msgid "'%s' is not locked"
 msgstr "“%s” chưa bị khóa"
 
-#: builtin/worktree.c:645
+#: builtin/worktree.c:685
 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ỏ"
 
-#: builtin/worktree.c:672 builtin/worktree.c:811
+#: builtin/worktree.c:712 builtin/worktree.c:852
 #, c-format
 msgid "'%s' is a main working tree"
 msgstr "“%s” là cây làm việc chính"
 
-#: builtin/worktree.c:677
+#: builtin/worktree.c:717
 #, 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”"
 
-#: builtin/worktree.c:683
+#: builtin/worktree.c:723
 #, c-format
 msgid "target '%s' already exists"
 msgstr "đích “%s” đã tồn tại rồi"
 
-#: builtin/worktree.c:690
+#: builtin/worktree.c:730
 #, c-format
 msgid "cannot move a locked working tree, lock reason: %s"
 msgstr "không thể di chuyển một cây-làm-việc bị khóa, khóa vì: %s"
 
-#: builtin/worktree.c:692
+#: builtin/worktree.c:732
 msgid "cannot move a locked working tree"
 msgstr "không thể di chuyển một cây-làm-việc bị khóa"
 
-#: builtin/worktree.c:695
+#: builtin/worktree.c:735
 #, c-format
 msgid "validation failed, cannot move working tree: %s"
 msgstr "thẩm tra gặp lỗi, không thể di chuyển một cây-làm-việc: %s"
 
-#: builtin/worktree.c:700
+#: builtin/worktree.c:740
 #, c-format
 msgid "failed to move '%s' to '%s'"
 msgstr "gặp lỗi khi chuyển “%s” sang “%s”"
 
-#: builtin/worktree.c:748
+#: builtin/worktree.c:788
 #, c-format
 msgid "failed to run 'git status' on '%s'"
 msgstr "gặp lỗi khi chạy “git status” vào “%s”"
 
-#: builtin/worktree.c:752
+#: builtin/worktree.c:792
 #, c-format
 msgid "'%s' is dirty, use --force to delete it"
 msgstr "“%s” đang bẩn, hãy dùng --force để xóa nó"
 
-#: builtin/worktree.c:757
+#: builtin/worktree.c:797
 #, 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"
 
-#: builtin/worktree.c:768 builtin/worktree.c:782
+#: builtin/worktree.c:808 builtin/worktree.c:822
 #, c-format
 msgid "failed to delete '%s'"
 msgstr "gặp lỗi khi xóa “%s”"
 
-#: builtin/worktree.c:794
+#: builtin/worktree.c:834
 msgid "force removing even if the worktree is dirty"
 msgstr "ép buộc di chuyển thậm chí cả khi cây làm việc đang bẩn"
 
-#: builtin/worktree.c:815
+#: builtin/worktree.c:856
 #, c-format
 msgid "cannot remove a locked working tree, lock reason: %s"
 msgstr "không thể gỡ bỏ một cây-làm-việc bị khóa, khóa vì: %s"
 
-#: builtin/worktree.c:817
+#: builtin/worktree.c:858
 msgid "cannot remove a locked working tree"
 msgstr "không thể gỡ bỏ một cây-làm-việc bị khóa"
 
-#: builtin/worktree.c:820
+#: builtin/worktree.c:861
 #, c-format
 msgid "validation failed, cannot remove working tree: %s"
 msgstr "thẩm tra gặp lỗi, không thể gỡ bỏ một cây-làm-việc: %s"
@@ -14802,26 +15371,6 @@ msgstr "ghi đối tượng cây (tree) cho <tiền tố> thư mục con"
 msgid "only useful for debugging"
 msgstr "chỉ hữu ích khi cần gỡ lỗi"
 
-#: upload-pack.c:27
-msgid "git upload-pack [<options>] <dir>"
-msgstr "git upload-pack [<các-tùy-chọn>] </đường/dẫn>"
-
-#: upload-pack.c:1070
-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"
-
-#: upload-pack.c:1072
-msgid "exit immediately after initial ref advertisement"
-msgstr "thoát ngay sau khi khởi tạo quảng cáo tham chiếu"
-
-#: upload-pack.c:1074
-msgid "do not try <directory>/.git/ if <directory> is no Git directory"
-msgstr "đừng thử <thư_mục>/.git/ nếu <thư_mục> không phải là thư mục Git"
-
-#: upload-pack.c:1076
-msgid "interrupt transfer after <n> seconds of inactivity"
-msgstr "ngắt truyền thông sau <n> giây không hoạt động"
-
 #: credential-cache--daemon.c:222
 #, c-format
 msgid ""
@@ -14839,23 +15388,25 @@ msgstr ""
 msgid "print debugging messages to stderr"
 msgstr "in thông tin gỡ lỗi ra đầu ra lỗi tiêu chuẩn"
 
-#: git.c:8
+#: git.c:27
 msgid ""
 "git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
 "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
 "           <command> [<args>]"
 msgstr ""
 "git [--version] [--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 | --no-pager] [--no-replace-objects] [--bare]\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"
 "           <lệnh> [<các tham số>]"
 
-#: git.c:15
+#: git.c:34
 msgid ""
 "'git help -a' and 'git help -g' list available subcommands and some\n"
 "concept guides. See 'git help <command>' or 'git help <concept>'\n"
@@ -14865,67 +15416,67 @@ msgstr ""
 "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ể."
 
-#: git.c:95
+#: git.c:173
 #, c-format
 msgid "no directory given for --git-dir\n"
 msgstr "chưa chỉ ra thư mục cho --git-dir\n"
 
-#: git.c:109
+#: git.c:187
 #, c-format
 msgid "no namespace given for --namespace\n"
 msgstr "chưa đưa ra không gian làm việc cho --namespace\n"
 
-#: git.c:123
+#: git.c:201
 #, c-format
 msgid "no directory given for --work-tree\n"
 msgstr "chưa đưa ra cây làm việc cho --work-tree\n"
 
-#: git.c:137
+#: git.c:215
 #, c-format
 msgid "no prefix given for --super-prefix\n"
 msgstr "chưa đưa ra tiền tố cho --super-prefix\n"
 
-#: git.c:159
+#: git.c:237
 #, c-format
 msgid "-c expects a configuration string\n"
 msgstr "-c cần một chuỗi cấu hình\n"
 
-#: git.c:197
+#: git.c:275
 #, c-format
 msgid "no directory given for -C\n"
 msgstr ""
 "chưa đưa ra thư mục cho -C\n"
 "\n"
 
-#: git.c:212
+#: git.c:300
 #, c-format
 msgid "unknown option: %s\n"
 msgstr "không hiểu tùy chọn: %s\n"
 
-#: git.c:687
+#: git.c:765
 #, 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"
 
-#: git.c:699
+#: git.c:777
 #, c-format
 msgid "failed to run command '%s': %s\n"
 msgstr "gặp lỗi khi chạy lệnh “%s”: %s\n"
 
-#: http.c:342
+#: http.c:348
 #, c-format
 msgid "negative value for http.postbuffer; defaulting to %d"
 msgstr "giá trị âm cho http.postbuffer; mặc định là %d"
 
-#: http.c:363
+#: http.c:369
 msgid "Delegation control is not supported with cURL < 7.22.0"
 msgstr "Điều khiển giao quyền không được hỗ trợ với cURL < 7.22.0"
 
-#: http.c:372
+#: http.c:378
 msgid "Public key pinning not supported with cURL < 7.44.0"
 msgstr "Chốt khóa công không được hỗ trợ với cURL < 7.44.0"
 
-#: http.c:1857
+#: http.c:1854
 #, c-format
 msgid ""
 "unable to update url base from redirection:\n"
@@ -14936,7 +15487,7 @@ msgstr ""
 "      hỏi cho: %s\n"
 " chuyển hướng: %s"
 
-#: remote-curl.c:345
+#: remote-curl.c:401
 #, c-format
 msgid "redirecting to %s"
 msgstr "chuyển hướng đến %s"
@@ -14949,131 +15500,669 @@ msgstr "các_tham_số"
 msgid "object filtering"
 msgstr "lọc đối tượng"
 
-#: common-cmds.h:9
-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)"
+#: parse-options.h:157
+msgid "expiry-date"
+msgstr "ngày hết hạn"
 
-#: common-cmds.h:10
-msgid "work on the current change (see also: git help everyday)"
-msgstr "làm việc trên thay đổi hiện tại (xem thêm: git help everyday)"
+#: parse-options.h:172
+msgid "no-op (backward compatibility)"
+msgstr "no-op (tương thích ngược)"
 
-#: common-cmds.h:11
-msgid "examine the history and state (see also: git help revisions)"
-msgstr "xem xét lịch sử tình trạng (xem thêm: git help revisions)"
+#: parse-options.h:251
+msgid "be more verbose"
+msgstr "chi tiết hơn nữa"
 
-#: common-cmds.h:12
-msgid "grow, mark and tweak your common history"
-msgstr "thêm, ghi dấu và chỉnh lịch sử chung của bạn"
+#: parse-options.h:253
+msgid "be more quiet"
+msgstr "im lặng hơn nữa"
 
-#: common-cmds.h:13
-msgid "collaborate (see also: git help workflows)"
-msgstr "làm việc nhóm (xem thêm: git help workflows)"
+#: parse-options.h:259
+msgid "use <n> digits to display SHA-1s"
+msgstr "sử dụng <n> chữ số để hiển thị SHA-1s"
 
-#: common-cmds.h:17
+#: command-list.h:50
 msgid "Add file contents to the index"
 msgstr "Thêm nội dung tập tin vào bảng mục lục"
 
-#: common-cmds.h:18
+#: command-list.h:51
+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"
+
+#: command-list.h:52
+msgid "Annotate file lines with commit information"
+msgstr "Các dòng diễn giải tập tin với thông tin chuyển giao"
+
+#: command-list.h:53
+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"
+
+#: command-list.h:54
+msgid "Import an Arch repository into Git"
+msgstr "Nhập một kho Arch vào một kho Git"
+
+#: command-list.h:55
+msgid "Create an archive of files from a named tree"
+msgstr "Tạo một kho nén các tập tin từ cây làm việc có tên"
+
+#: command-list.h:56
 msgid "Use binary search to find the commit that introduced a bug"
 msgstr "Tìm kiếm dạng nhị phân để tìm ra lần chuyển giao nào đưa ra lỗi"
 
-#: common-cmds.h:19
+#: command-list.h:57
+msgid "Show what revision and author last modified each line of a file"
+msgstr ""
+"Hiển thị số hiệu phiên bản và tác giả sửa đổi cuối cho từng dòng của một tập "
+"tin"
+
+#: command-list.h:58
 msgid "List, create, or delete branches"
 msgstr "Liệt kê, tạo hay là xóa các nhánh"
 
-#: common-cmds.h:20
+#: command-list.h:59
+msgid "Move objects and refs by archive"
+msgstr "Di chuyển các đối tượng và tham chiếu theo kho lưu"
+
+#: command-list.h:60
+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"
+
+#: command-list.h:61
+msgid "Display gitattributes information"
+msgstr "Hiển thị thông tin gitattributes"
+
+#: command-list.h:62
+msgid "Debug gitignore / exclude files"
+msgstr "Gỡ lỗi các tập tin gitignore / exclude"
+
+#: command-list.h:63
+msgid "Show canonical names and email addresses of contacts"
+msgstr "Hiển thị tên và địa chỉ thư điện tử của các liên hệ dạng chuẩn hóa"
+
+#: command-list.h:64
 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"
 
-#: common-cmds.h:21
+#: command-list.h:65
+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"
+
+#: command-list.h:66
+msgid "Ensures that a reference name is well formed"
+msgstr "Đảm bảo rằng một tên tham chiếu ở dạng thức tốt"
+
+#: command-list.h:67
+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"
+
+#: command-list.h:68
+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ó"
+
+#: command-list.h:69
+msgid "Graphical alternative to git-commit"
+msgstr "Tương tác đồ họa với git-commit"
+
+#: command-list.h:70
+msgid "Remove untracked files from the working tree"
+msgstr "Gỡ bỏ các tập tin không được theo dõi từ cây làm việc"
+
+#: command-list.h:71
 msgid "Clone a repository into a new directory"
 msgstr "Nhân bản một kho chứa đến một thư mục mới"
 
-#: common-cmds.h:22
+#: command-list.h:72
+msgid "Display data in columns"
+msgstr "Hiển thị dữ liệu dạng các cột"
+
+#: command-list.h:73
 msgid "Record changes to the repository"
 msgstr "Ghi các thay đổi vào kho chứa"
 
-#: common-cmds.h:23
+#: command-list.h:74
+msgid "Write and verify Git commit graph files"
+msgstr "Ghi và thẩm tra các tập tin đồ họa các lền chuyển giao git"
+
+#: command-list.h:75
+msgid "Create a new commit object"
+msgstr "Tạo một đối tượng chuyển giao"
+
+#: command-list.h:76
+msgid "Get and set repository or global options"
+msgstr "Lấy và đặt kho hoặc các tùy chọn toàn cục"
+
+#: command-list.h:77
+msgid "Count unpacked number of objects and their disk consumption"
+msgstr ""
+"Đếm số lượng đối tượng chưa được đóng gói và mức tiêu dùng đĩa của chúng"
+
+#: command-list.h:78
+msgid "Retrieve and store user credentials"
+msgstr "Nhận và lưu chứng nhận của người dùng"
+
+#: command-list.h:79
+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ớ"
+
+#: command-list.h:80
+msgid "Helper to store credentials on disk"
+msgstr "Bộ hỗ trợ để lưu chứng nhận vào đĩa"
+
+#: command-list.h:81
+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"
+
+#: command-list.h:82
+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"
+
+#: command-list.h:83
+msgid "A CVS server emulator for Git"
+msgstr "Một bộ mô phỏng máy dịch vụ CVS cho Git"
+
+#: command-list.h:84
+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"
+
+#: command-list.h:85
+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ó"
+
+#: command-list.h:86
 msgid "Show changes between commits, commit and working tree, etc"
 msgstr ""
 "Xem 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.."
 
-#: common-cmds.h:24
+#: command-list.h:87
+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"
+
+#: command-list.h:88
+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"
+
+#: command-list.h:89
+msgid "Compares the content and mode of blobs found via two tree objects"
+msgstr ""
+"So sánh nội dung và chế độ của các blob tìm thấy thông qua hai đối tượng cây"
+
+#: command-list.h:90
+msgid "Show changes using common diff tools"
+msgstr "Hiển thị các thay đổi sử dụng các công cụ diff chung"
+
+#: command-list.h:91
+msgid "Git data exporter"
+msgstr "Bộ xuất dữ liệu Git"
+
+#: command-list.h:92
+msgid "Backend for fast Git data importers"
+msgstr "Ứng dụng chạy phía sau cho bộ nhập nhanh dữ liệu Git"
+
+#: command-list.h:93
 msgid "Download objects and refs from another repository"
 msgstr "Tải về các đối tượng và tham chiếu từ kho chứa khác"
 
-#: common-cmds.h:25
+#: command-list.h:94
+msgid "Receive missing objects from another repository"
+msgstr "Tải về các đối tượng còn thiếu từ kho chứa khác"
+
+#: command-list.h:95
+msgid "Rewrite branches"
+msgstr "Những nhánh ghi lại"
+
+#: command-list.h:96
+msgid "Produce a merge commit message"
+msgstr "Sản sinh một ghi chú lần chuyển giao hòa trộn"
+
+#: command-list.h:97
+msgid "Output information on each ref"
+msgstr "Xuất thông tin cho từng tham chiếu"
+
+#: command-list.h:98
+msgid "Prepare patches for e-mail submission"
+msgstr "Chuẩn bị các miếng vá để gửi qua thư điện tử"
+
+#: command-list.h:99
+msgid "Verifies the connectivity and validity of the objects in the database"
+msgstr ""
+"Thẩm tra lại tính kết nối và tính hiệu lực cảu các đối tượng trong cơ sở dữ "
+"liệu"
+
+#: command-list.h:100
+msgid "Cleanup unnecessary files and optimize the local repository"
+msgstr "Dọn dẹp các tập tin không cần thiết và tối ưu kho nội bộ"
+
+#: command-list.h:101
+msgid "Extract commit ID from an archive created using git-archive"
+msgstr ""
+"Rút trích mã số lần chuyển giao từ một kho nén đã được tạo bởi git-archive"
+
+#: command-list.h:102
 msgid "Print lines matching a pattern"
 msgstr "In ra những dòng khớp với một mẫu"
 
-#: common-cmds.h:26
+#: command-list.h:103
+msgid "A portable graphical interface to Git"
+msgstr "Một giao diện đồ họa khả chuyển cho Git"
+
+#: command-list.h:104
+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"
+
+#: command-list.h:105
+msgid "Display help information about Git"
+msgstr "Hiển thị thông tin trợ giúp về Git"
+
+#: command-list.h:106
+msgid "Server side implementation of Git over HTTP"
+msgstr "Thi hành phía máy chủ của Git qua HTTP"
+
+#: command-list.h:107
+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"
+
+#: command-list.h:108
+msgid "Push objects over HTTP/DAV to another repository"
+msgstr "Đẩy các đối tượng lên thông qua HTTP/DAV đến kho chứa khác"
+
+#: command-list.h:109
+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"
+
+#: command-list.h:110
+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ó"
+
+#: command-list.h:111
 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"
 
-#: common-cmds.h:27
+#: command-list.h:112
+msgid "Instantly browse your working repository in gitweb"
+msgstr "Duyệt ngay kho làm việc của bạn trong gitweb"
+
+#: command-list.h:113
+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"
+
+#: command-list.h:114
+msgid "The Git repository browser"
+msgstr "Bộ duyện kho Git"
+
+#: command-list.h:115
 msgid "Show commit logs"
 msgstr "Hiển thị nhật ký các lần chuyển giao"
 
-#: common-cmds.h:28
+#: command-list.h:116
+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"
+
+#: command-list.h:117
+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"
+
+#: command-list.h:118
+msgid "List the contents of a tree object"
+msgstr "Liệt kê nội dung của đối tượng cây"
+
+#: command-list.h:119
+msgid "Extracts patch and authorship from a single e-mail message"
+msgstr "Trích xuất miếng và và nguồn tác giả từ một thư điện tử đơn"
+
+#: command-list.h:120
+msgid "Simple UNIX mbox splitter program"
+msgstr "Chương trình phân tách UNIX mbox đơn giản"
+
+#: command-list.h:121
 msgid "Join two or more development histories together"
 msgstr "Hợp nhất hai hay nhiều hơn lịch sử của các nhà phát triển"
 
-#: common-cmds.h:29
+#: command-list.h:122
+msgid "Find as good common ancestors as possible for a merge"
+msgstr "Tìm các tổ tiên chung tốt có thể được cho hòa trộn"
+
+#: command-list.h:123
+msgid "Run a three-way file merge"
+msgstr "Chạy một hòa trộn tập tin “3-đường”"
+
+#: command-list.h:124
+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"
+
+#: command-list.h:125
+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"
+
+#: command-list.h:126
+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"
+
+#: command-list.h:127
+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"
+
+#: command-list.h:128
+msgid "Creates a tag object"
+msgstr "Tạo một đối tượng thẻ"
+
+#: command-list.h:129
+msgid "Build a tree-object from ls-tree formatted text"
+msgstr "Xây dựng một tree-object từ văn bản định dạng ls-tree"
+
+#: command-list.h:130
 msgid "Move or rename a file, a directory, or a symlink"
 msgstr "Di chuyển hay đổi tên một tập tin, thư mục hoặc liên kết mềm"
 
-#: common-cmds.h:30
+#: command-list.h:131
+msgid "Find symbolic names for given revs"
+msgstr "Tìm các tên liên kết mềm cho điểm xét đã cho"
+
+#: command-list.h:132
+msgid "Add or inspect object notes"
+msgstr "thêm hoặc điều tra đối tượng ghi chú"
+
+#: command-list.h:133
+msgid "Import from and submit to Perforce repositories"
+msgstr "Nhập vào từ và gửi đến các kho cần thiết"
+
+#: command-list.h:134
+msgid "Create a packed archive of objects"
+msgstr "Tạo một kho lưu được đóng gói cho các đối"
+
+#: command-list.h:135
+msgid "Find redundant pack files"
+msgstr "Tìm các tập tin gói dư thừa"
+
+#: command-list.h:136
+msgid "Pack heads and tags for efficient repository access"
+msgstr "Đóng gói các phần đầu và thẻ để truy cập kho hiệu quả hơn"
+
+#: command-list.h:137
+msgid "Routines to help parsing remote repository access parameters"
+msgstr "Các thủ tục để giúp phân tích các tham số truy cập kho chứa trên mạng"
+
+#: command-list.h:138
+msgid "Compute unique ID for a patch"
+msgstr "Tính toán ID duy nhất cho một miếng vá"
+
+#: command-list.h:139
+msgid "Prune all unreachable objects from the object database"
+msgstr ""
+"Xén bớt tất các các đối tượng không tiếp cận được từ cơ sở dữ liệu đối tượng"
+
+#: command-list.h:140
+msgid "Remove extra objects that are already in pack files"
+msgstr "Xóa bỏ các đối tượng mở rộng cái mà đã sẵn có trong các tập tin gói"
+
+#: command-list.h:141
 msgid "Fetch from and integrate with another repository or a local branch"
 msgstr "Lấy về và hợp nhất với kho khác hay một nhánh nội bộ"
 
-#: common-cmds.h:31
+#: command-list.h:142
 msgid "Update remote refs along with associated objects"
 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ó"
 
-#: common-cmds.h:32
+#: command-list.h:143
+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"
+
+#: command-list.h:144
+msgid "Reads tree information into the index"
+msgstr "Đọc thông tin cây vào trong mục lục"
+
+#: command-list.h:145
 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"
 
-#: common-cmds.h:33
+#: command-list.h:146
+msgid "Receive what is pushed into the repository"
+msgstr "Nhận cái mà được đẩy vào trong kho"
+
+#: command-list.h:147
+msgid "Manage reflog information"
+msgstr "Quản lý thông tin reflog"
+
+#: command-list.h:148
+msgid "Manage set of tracked repositories"
+msgstr "Quản lý tập hợp các kho chứa đã được theo dõi"
+
+#: command-list.h:149
+msgid "Pack unpacked objects in a repository"
+msgstr "Đóng gói các đối tượng chưa đóng gói ở một kho chứa"
+
+#: command-list.h:150
+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"
+
+#: command-list.h:151
+msgid "Generates a summary of pending changes"
+msgstr "Tạo ra một tóm tắt các thay đổi còn treo"
+
+#: command-list.h:152
+msgid "Reuse recorded resolution of conflicted merges"
+msgstr "Dùng lại các giải pháp đã ghi lại của các hòa trộn bị xung đột"
+
+#: command-list.h:153
 msgid "Reset current HEAD to the specified state"
 msgstr "Đặt lại HEAD hiện hành thành trạng thái đã cho"
 
-#: common-cmds.h:34
+#: command-list.h:154
+msgid "Revert some existing commits"
+msgstr "Hoàn lại một số lần chuyển giao sẵn có"
+
+#: command-list.h:155
+msgid "Lists commit objects in reverse chronological order"
+msgstr "Liệt kê các đối tượng chuyển giao theo thứ tự tôpô đảo ngược"
+
+#: command-list.h:156
+msgid "Pick out and massage parameters"
+msgstr "Cậy ra và xử lý các tham số"
+
+#: command-list.h:157
 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"
 
-#: common-cmds.h:35
+#: command-list.h:158
+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ử"
+
+#: command-list.h:159
+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"
+
+#: command-list.h:160
+msgid "Restricted login shell for Git-only SSH access"
+msgstr "Hệ vỏ đăng nhập có hạn chế cho truy cập SSH chỉ-Git"
+
+#: command-list.h:161
+msgid "Summarize 'git log' output"
+msgstr "Kết xuất “git log” dạng tóm tắt"
+
+#: command-list.h:162
 msgid "Show various types of objects"
 msgstr "Hiển thị các kiểu khác nhau của các đối tượng"
 
-#: common-cmds.h:36
+#: command-list.h:163
+msgid "Show branches and their commits"
+msgstr "Hiển thị những nhánh và các lần chuyển giao của chúng"
+
+#: command-list.h:164
+msgid "Show packed archive index"
+msgstr "Hiển thị các muc lục kho nén đã đóng gói"
+
+#: command-list.h:165
+msgid "List references in a local repository"
+msgstr "Liệt kê các tham chiếu trong một kho nội bộ"
+
+#: command-list.h:166
+msgid "Git's i18n setup code for shell scripts"
+msgstr "Nã cài đặt quốc tế hóa của Git cho văn lệnh hệ vỏ"
+
+#: command-list.h:167
+msgid "Common Git shell script setup code"
+msgstr "Mã cài đặt văn lệnh hệ vỏ Git chung"
+
+#: command-list.h:168
+msgid "Stash the changes in a dirty working directory away"
+msgstr "Tạm cất đi các thay đổi trong một thư mục làm việc bẩn"
+
+#: command-list.h:169
+msgid "Add file contents to the staging area"
+msgstr "Thêm nội dung tập tin vào vùng bệ phóng"
+
+#: command-list.h:170
 msgid "Show the working tree status"
 msgstr "Hiển thị trạng thái cây làm việc"
 
-#: common-cmds.h:37
+#: command-list.h:171
+msgid "Remove unnecessary whitespace"
+msgstr "Xóa bỏ các khoảng trắng không cần thiết"
+
+#: command-list.h:172
+msgid "Initialize, update or inspect submodules"
+msgstr "Khởi tạo, cập nhật hay điều tra các mô-đun-con"
+
+#: command-list.h:173
+msgid "Bidirectional operation between a Subversion repository and Git"
+msgstr "Thao tác hai hướng giữ hai kho Subversion và Git"
+
+#: command-list.h:174
+msgid "Read, modify and delete symbolic refs"
+msgstr "Đọc, sửa và xóa tham chiếu mềm"
+
+#: command-list.h:175
 msgid "Create, list, delete or verify a tag object signed with GPG"
 msgstr "Tạo, liệt kê, xóa hay xác thực một đối tượng thẻ được ký bằng GPG"
 
-#: parse-options.h:157
-msgid "expiry-date"
-msgstr "ngày hết hạn"
+#: command-list.h:176
+msgid "Creates a temporary file with a blob's contents"
+msgstr "Tạo một tập tin tạm với nội dung của blob"
 
-#: parse-options.h:172
-msgid "no-op (backward compatibility)"
-msgstr "no-op (tương thích ngược)"
+#: command-list.h:177
+msgid "Unpack objects from a packed archive"
+msgstr "Gỡ các đối tượng khỏi một kho lưu đã đóng gói"
 
-#: parse-options.h:250
-msgid "be more verbose"
-msgstr "chi tiết hơn nữa"
+#: command-list.h:178
+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"
 
-#: parse-options.h:252
-msgid "be more quiet"
-msgstr "im lặng hơn nữa"
+#: command-list.h:179
+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"
 
-#: parse-options.h:258
-msgid "use <n> digits to display SHA-1s"
-msgstr "sử dụng <n> chữ số để hiển thị SHA-1s"
+#: command-list.h:180
+msgid "Update auxiliary info file to help dumb servers"
+msgstr "Cập nhật tập tin thông tin phụ trợ để giúp đỡ các dịch vụ dumb"
+
+#: command-list.h:181
+msgid "Send archive back to git-archive"
+msgstr "Gửi trở lại kho lưu đến git-archive"
+
+#: command-list.h:182
+msgid "Send objects packed back to git-fetch-pack"
+msgstr "Gửi trở lại các đối tượng đã đóng gói cho git-fetch-pack"
+
+#: command-list.h:183
+msgid "Show a Git logical variable"
+msgstr "Hiển thị một biến Git luận lý"
+
+#: command-list.h:184
+msgid "Check the GPG signature of commits"
+msgstr "Kiểm tra ký lần chuyển giao dùng GPG"
+
+#: command-list.h:185
+msgid "Validate packed Git archive files"
+msgstr "Kiểm tra lại các tập tin kho (lưu trữ, nén) Git đã được đóng gói"
+
+#: command-list.h:186
+msgid "Check the GPG signature of tags"
+msgstr "Kiểm tra chữ ký GPG của các thẻ"
+
+#: command-list.h:187
+msgid "Git web interface (web frontend to Git repositories)"
+msgstr "Giao diện Git trên nền web (ứng dụng web chạy trên kho Git)"
+
+#: command-list.h:188
+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"
+
+#: command-list.h:189
+msgid "Manage multiple working trees"
+msgstr "Quản lý nhiều cây làm việc"
+
+#: command-list.h:190
+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"
+
+#: command-list.h:191
+msgid "Defining attributes per path"
+msgstr "Định nghĩa các thuộc tính cho mỗi đường dẫn"
+
+#: command-list.h:192
+msgid "Git command-line interface and conventions"
+msgstr "Giao diện dòng lệnh Git và quy ước"
+
+#: command-list.h:193
+msgid "A Git core tutorial for developers"
+msgstr "Hướng dẫn Git cơ bản cho nhà phát triển"
+
+#: command-list.h:194
+msgid "Git for CVS users"
+msgstr "Git dành cho những người dùng CVS"
+
+#: command-list.h:195
+msgid "Tweaking diff output"
+msgstr "Chỉnh kết xuất diff"
+
+#: command-list.h:196
+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"
+
+#: command-list.h:197
+msgid "A Git Glossary"
+msgstr "Thuật ngữ chuyên môn Git"
+
+#: command-list.h:198
+msgid "Hooks used by Git"
+msgstr "Các móc được sử dụng bởi Git"
+
+#: command-list.h:199
+msgid "Specifies intentionally untracked files to ignore"
+msgstr "Chỉ định các tập tin không cần theo dõi"
+
+#: command-list.h:200
+msgid "Defining submodule properties"
+msgstr "Định nghĩa thuộc tính mô-đun-con"
+
+#: command-list.h:201
+msgid "Git namespaces"
+msgstr "không gian tên Git"
+
+#: command-list.h:202
+msgid "Git Repository Layout"
+msgstr "Bố cục kho Git"
+
+#: command-list.h:203
+msgid "Specifying revisions and ranges for Git"
+msgstr "Chỉ định điểm xét duyệt và vùng cho Git"
+
+#: command-list.h:204
+msgid "A tutorial introduction to Git: part two"
+msgstr "Hướng dẫn cách dùng Git: phần hai"
+
+#: command-list.h:205
+msgid "A tutorial introduction to Git"
+msgstr "Hướng dẫn cách dùng Git"
+
+#: command-list.h:206
+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."
 
 #: rerere.h:40
 msgid "update the index with reused conflict resolution if possible"
@@ -15304,7 +16393,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."
 
-#: git-rebase.sh:60
+#: git-rebase.sh:61
 msgid ""
 "Resolve all conflicts manually, mark them as resolved with\n"
 "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
@@ -15319,44 +16408,44 @@ msgstr ""
 "Để bãi bỏ và quay trở lại trạng thái trước \"git rebase\", chạy \"git rebase "
 "--abort\"."
 
-#: git-rebase.sh:163 git-rebase.sh:409
+#: git-rebase.sh:173 git-rebase.sh:442
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "Không thể quay trở lại $head_name"
 
-#: git-rebase.sh:174
+#: git-rebase.sh:184
 msgid "Applied autostash."
 msgstr "Đã áp dụng autostash."
 
-#: git-rebase.sh:177
+#: git-rebase.sh:187
 #, sh-format
 msgid "Cannot store $stash_sha1"
 msgstr "Không thể lưu $stash_sha1"
 
-#: git-rebase.sh:218
+#: git-rebase.sh:229
 msgid "The pre-rebase hook refused to rebase."
 msgstr "Móc (hook) pre-rebase từ chối rebase."
 
-#: git-rebase.sh:223
+#: git-rebase.sh:234
 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."
 
-#: git-rebase.sh:370
+#: git-rebase.sh:403
 msgid "No rebase in progress?"
 msgstr "Không có tiến trình rebase nào phải không?"
 
-#: git-rebase.sh:381
+#: git-rebase.sh:414
 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 "
 "sử) tương tác."
 
-#: git-rebase.sh:388
+#: git-rebase.sh:421
 msgid "Cannot read HEAD"
 msgstr "Không thể đọc HEAD"
 
-#: git-rebase.sh:391
+#: git-rebase.sh:424
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -15364,7 +16453,7 @@ msgstr ""
 "Bạn phải sửa tất cả các lần hòa trộn xung đột và sau\n"
 "đó đánh dấu chúng là cần xử lý sử dụng lệnh git add"
 
-#: git-rebase.sh:435
+#: git-rebase.sh:468
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -15385,74 +16474,78 @@ msgstr ""
 "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."
 
-#: git-rebase.sh:491
+#: git-rebase.sh:509
+msgid "error: cannot combine '--signoff' with '--preserve-merges'"
+msgstr "lỗi: không thể kết hợp “--signoff” với “--preserve-merges”"
+
+#: git-rebase.sh:537
 #, sh-format
 msgid "invalid upstream '$upstream_name'"
 msgstr "thượng nguồn không hợp lệ “$upstream_name”"
 
-#: git-rebase.sh:515
+#: git-rebase.sh:561
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name: ở đây có nhiều hơn một nền móng hòa trộn"
 
-#: git-rebase.sh:518 git-rebase.sh:522
+#: git-rebase.sh:564 git-rebase.sh:568
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name: ở đây không có nền móng hòa trộn nào"
 
-#: git-rebase.sh:527
+#: git-rebase.sh:573
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "Không chỉ đến một lần chuyển giao không hợp lệ: $onto_name"
 
-#: git-rebase.sh:553
+#: git-rebase.sh:599
 #, sh-format
 msgid "fatal: no such branch/commit '$branch_name'"
 msgstr "nghiêm trọng: không có nhánh như thế: “$branch_name”"
 
-#: git-rebase.sh:586
+#: git-rebase.sh:632
 msgid "Cannot autostash"
 msgstr "Không thể autostash"
 
-#: git-rebase.sh:591
+#: git-rebase.sh:637
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "Đã tạo autostash: $stash_abbrev"
 
-#: git-rebase.sh:595
+#: git-rebase.sh:641
 msgid "Please commit or stash them."
 msgstr "Xin hãy chuyển giao hoặc tạm cất (stash) chúng."
 
-#: git-rebase.sh:618
+#: git-rebase.sh:664
 #, sh-format
 msgid "HEAD is up to date."
 msgstr "HEAD đã cập nhật."
 
-#: git-rebase.sh:620
+#: git-rebase.sh:666
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "Nhánh hiện tại $branch_name đã được cập nhật rồi."
 
-#: git-rebase.sh:628
+#: git-rebase.sh:674
 #, sh-format
 msgid "HEAD is up to date, rebase forced."
 msgstr "HEAD hiện đã được cập nhật rồi, bị ép buộc rebase."
 
-#: git-rebase.sh:630
+#: git-rebase.sh:676
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr "Nhánh hiện tại $branch_name đã được cập nhật rồi, lệnh rebase ép buộc."
 
-#: git-rebase.sh:642
+#: git-rebase.sh:688
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "Thay đổi từ $mb thành $onto:"
 
-#: git-rebase.sh:651
+#: git-rebase.sh:697
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr "Trước tiên, di chuyển head để xem lại các công việc trên đỉnh của nó…"
 
-#: git-rebase.sh:661
+#: git-rebase.sh:707
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "Chuyển-tiếp-nhanh $branch_name thành $onto_name."
@@ -15521,114 +16614,114 @@ msgstr "Không thể ghi lại trạng thái hiện hành"
 msgid "Saved working directory and index state $stash_msg"
 msgstr "Đã ghi lại thư mục làm việc và trạng thái mục lục $stash_msg"
 
-#: git-stash.sh:340
+#: git-stash.sh:342
 msgid "Cannot remove worktree changes"
 msgstr "Không thể gỡ bỏ các thay đổi cây-làm-việc"
 
-#: git-stash.sh:488
+#: git-stash.sh:490
 #, sh-format
 msgid "unknown option: $opt"
 msgstr "không hiểu tùy chọn: $opt"
 
-#: git-stash.sh:501
+#: git-stash.sh:503
 msgid "No stash entries found."
 msgstr "Không tìm thấy các mục tạm cất (stash) nào."
 
-#: git-stash.sh:508
+#: git-stash.sh:510
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "Chỉ ra quá nhiều điểm xét duyệt: $REV"
 
-#: git-stash.sh:523
+#: git-stash.sh:525
 #, sh-format
 msgid "$reference is not a valid reference"
 msgstr "$reference không phải là tham chiếu hợp lệ"
 
-#: git-stash.sh:551
+#: git-stash.sh:553
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "“$args” không phải là lần chuyển giao kiểu-stash (cất đi)"
 
-#: git-stash.sh:562
+#: git-stash.sh:564
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "”$args” không phải tham chiếu đến stash"
 
-#: git-stash.sh:570
+#: git-stash.sh:572
 msgid "unable to refresh index"
 msgstr "không thể làm tươi mới bảng mục lục"
 
-#: git-stash.sh:574
+#: git-stash.sh:576
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "Không thể áp dụng một stash ở giữa của quá trình hòa trộn"
 
-#: git-stash.sh:582
+#: git-stash.sh:584
 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."
 
-#: git-stash.sh:584
+#: git-stash.sh:586
 msgid "Could not save index tree"
 msgstr "Không thể ghi lại cây chỉ mục"
 
-#: git-stash.sh:593
+#: git-stash.sh:595
 msgid "Could not restore untracked files from stash entry"
 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)"
 
-#: git-stash.sh:618
+#: git-stash.sh:620
 msgid "Cannot unstage modified files"
 msgstr "Không thể bỏ ra khỏi bệ phóng các tập tin đã được sửa chữa"
 
-#: git-stash.sh:633
+#: git-stash.sh:635
 msgid "Index was not unstashed."
 msgstr "Bảng mục lục đã không được bỏ stash."
 
-#: git-stash.sh:647
+#: git-stash.sh:649
 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ó."
 
-#: git-stash.sh:656
+#: git-stash.sh:658
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "Đã xóa ${REV} ($s)"
 
-#: git-stash.sh:657
+#: git-stash.sh:659
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "${REV}: Không thể xóa bỏ mục stash"
 
-#: git-stash.sh:665
+#: git-stash.sh:667
 msgid "No branch name specified"
 msgstr "Chưa chỉ ra tên của nhánh"
 
-#: git-stash.sh:744
+#: git-stash.sh:746
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(Để phục hồi lại chúng hãy gõ \"git stash apply\")"
 
-#: git-submodule.sh:181
+#: git-submodule.sh:188
 msgid "Relative path can only be used from the toplevel of the working tree"
 msgstr ""
 "Đường dẫn tương đối chỉ có thể dùng từ thư mục ở mức cao nhất của cây làm "
 "việc"
 
-#: git-submodule.sh:191
+#: git-submodule.sh:198
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr ""
 "repo URL: “$repo” phải là đường dẫn tuyệt đối hoặc là bắt đầu bằng ./|../"
 
-#: git-submodule.sh:210
+#: git-submodule.sh:217
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "”$sm_path” thực sự đã tồn tại ở bảng mục lục rồi"
 
-#: git-submodule.sh:213
+#: git-submodule.sh:220
 #, sh-format
 msgid "'$sm_path' already exists in the index and is not a submodule"
 msgstr ""
 "”$sm_path” 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"
 
-#: git-submodule.sh:219
+#: git-submodule.sh:226
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -15640,23 +16733,23 @@ msgstr ""
 "$sm_path\n"
 "Sử dụng -f nếu bạn thực sự muốn thêm nó vào."
 
-#: git-submodule.sh:237
+#: git-submodule.sh:249
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "Đang thêm repo có sẵn tại “$sm_path” vào bảng mục lục"
 
-#: git-submodule.sh:239
+#: git-submodule.sh:251
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "”$sm_path” đã tồn tại từ trước và không phải là một kho git hợp lệ"
 
-#: git-submodule.sh:247
+#: git-submodule.sh:259
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
 msgstr ""
 "Thư mục git cho “$sm_name” được tìm thấy một cách cục bộ với các máy chủ:"
 
-#: git-submodule.sh:249
+#: git-submodule.sh:261
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from\n"
@@ -15672,50 +16765,50 @@ msgstr ""
 "hoặc 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”."
 
-#: git-submodule.sh:255
+#: git-submodule.sh:267
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
 msgstr ""
 "Phục hồi sự hoạt động của thư mục git nội bộ cho mô-đun-con “$sm_name”."
 
-#: git-submodule.sh:267
+#: git-submodule.sh:279
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "Không thể lấy ra mô-đun-con “$sm_path”"
 
-#: git-submodule.sh:272
+#: git-submodule.sh:284
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "Gặp lỗi khi thêm mô-đun-con “$sm_path”"
 
-#: git-submodule.sh:281
+#: git-submodule.sh:293
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "Gặp lỗi khi đăng ký với hệ thống mô-đun-con “$sm_path”"
 
-#: git-submodule.sh:342
+#: git-submodule.sh:354
 #, sh-format
 msgid "Entering '$displaypath'"
 msgstr "Đang vào “$displaypath”"
 
-#: git-submodule.sh:362
+#: git-submodule.sh:374
 #, sh-format
 msgid "Stopping at '$displaypath'; script returned non-zero status."
 msgstr "Dừng lại tại “$displaypath”; script trả về trạng thái khác không."
 
-#: git-submodule.sh:584
+#: git-submodule.sh:600
 #, sh-format
 msgid "Unable to find current revision in submodule path '$displaypath'"
 msgstr ""
 "Không tìm thấy điểm xét duyệt hiện hành trong đường dẫn mô-đun-con "
 "“$displaypath”"
 
-#: git-submodule.sh:594
+#: git-submodule.sh:610
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "Không thể lấy về trong đường dẫn mô-đun-con “$sm_path”"
 
-#: git-submodule.sh:599
+#: git-submodule.sh:615
 #, sh-format
 msgid ""
 "Unable to find current ${remote_name}/${branch} revision in submodule path "
@@ -15724,12 +16817,12 @@ 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”"
 
-#: git-submodule.sh:617
+#: git-submodule.sh:633
 #, sh-format
 msgid "Unable to fetch in submodule path '$displaypath'"
 msgstr "Không thể lấy về trong đường dẫn mô-đun-con “$displaypath”"
 
-#: git-submodule.sh:623
+#: git-submodule.sh:639
 #, sh-format
 msgid ""
 "Fetched in submodule path '$displaypath', but it did not contain $sha1. "
@@ -15738,74 +16831,74 @@ msgstr ""
 "Đã lấy về từ đường dẫn mô-đun con “$displaypath”, nhưng nó không chứa $sha1. "
 "Lấy về theo định hướng của lần chuyển giao đó gặp lỗi."
 
-#: git-submodule.sh:630
+#: git-submodule.sh:646
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
 msgstr "Không thể lấy ra “$sha1” trong đường dẫn mô-đun-con “$displaypath”"
 
-#: git-submodule.sh:631
+#: git-submodule.sh:647
 #, sh-format
 msgid "Submodule path '$displaypath': checked out '$sha1'"
 msgstr "Đường dẫn mô-đun-con “$displaypath”: đã checkout “$sha1”"
 
-#: git-submodule.sh:635
+#: git-submodule.sh:651
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
 msgstr "Không thể cải tổ “$sha1” trong đường dẫn mô-đun-con “$displaypath”"
 
-#: git-submodule.sh:636
+#: git-submodule.sh:652
 #, sh-format
 msgid "Submodule path '$displaypath': rebased into '$sha1'"
 msgstr "Đường dẫn mô-đun-con “$displaypath”: được rebase vào trong “$sha1”"
 
-#: git-submodule.sh:641
+#: git-submodule.sh:657
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$displaypath'"
 msgstr ""
 "Không thể hòa trộn (merge) “$sha1” trong đường dẫn mô-đun-con “$displaypath”"
 
-#: git-submodule.sh:642
+#: git-submodule.sh:658
 #, sh-format
 msgid "Submodule path '$displaypath': merged in '$sha1'"
 msgstr "Đường dẫn mô-đun-con “$displaypath”: được hòa trộn vào “$sha1”"
 
-#: git-submodule.sh:647
+#: git-submodule.sh:663
 #, sh-format
 msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'"
 msgstr ""
 "Thực hiện không thành công lệnh “$command $sha1” trong đường dẫn mô-đun-con "
 "“$displaypath”"
 
-#: git-submodule.sh:648
+#: git-submodule.sh:664
 #, sh-format
 msgid "Submodule path '$displaypath': '$command $sha1'"
 msgstr "Đường dẫn mô-đun-con “$displaypath”: “$command $sha1”"
 
-#: git-submodule.sh:679
+#: git-submodule.sh:695
 #, 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”"
 
-#: git-submodule.sh:775
+#: git-submodule.sh:791
 msgid "The --cached option cannot be used with the --files option"
 msgstr "Tùy chọn --cached không thể dùng cùng với tùy chọn --files"
 
-#: git-submodule.sh:827
+#: git-submodule.sh:843
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "chế độ không như mong chờ $mod_dst"
 
-#: git-submodule.sh:847
+#: git-submodule.sh:863
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr "  Cảnh báo: $display_name không chứa lần chuyển giao $sha1_src"
 
-#: git-submodule.sh:850
+#: git-submodule.sh:866
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr "  Cảnh báo: $display_name không chứa lần chuyển giao $sha1_dst"
 
-#: git-submodule.sh:853
+#: git-submodule.sh:869
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr ""
@@ -15817,40 +16910,55 @@ msgstr ""
 msgid "See git-${cmd}(1) for details."
 msgstr "Xem git-${cmd}(1) để biết thêm chi tiết."
 
-#: git-rebase--interactive.sh:140
+#: git-rebase--interactive.sh:142
 #, sh-format
 msgid "Rebasing ($new_count/$total)"
 msgstr "Đang rebase ($new_count/$total)"
 
-#: git-rebase--interactive.sh:156
+#: git-rebase--interactive.sh:158
 msgid ""
 "\n"
 "Commands:\n"
-"p, pick = use commit\n"
-"r, reword = use commit, but edit the commit message\n"
-"e, edit = use commit, but stop for amending\n"
-"s, squash = use commit, but meld into previous commit\n"
-"f, fixup = like \"squash\", but discard this commit's log message\n"
-"x, exec = run command (the rest of the line) using shell\n"
-"d, drop = remove commit\n"
+"p, pick <commit> = use commit\n"
+"r, reword <commit> = use commit, but edit the commit message\n"
+"e, edit <commit> = use commit, but stop for amending\n"
+"s, squash <commit> = use commit, but meld into previous commit\n"
+"f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
+"x, exec <command> = run command (the rest of the line) using shell\n"
+"d, drop <commit> = remove commit\n"
+"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"
 "\n"
 "These lines can be re-ordered; they are executed from top to bottom.\n"
 msgstr ""
 "\n"
 "Các lệnh:\n"
-" p, pick = dùng lần chuyển giao\n"
-" r, reword = dùng lần chuyển giao, nhưng sửa lại phần chú thích\n"
-" e, edit = dùng lần chuyển giao, nhưng dừng lại để tu bổ (amend)\n"
-" s, squash = dùng lần chuyển giao, nhưng meld vào lần chuyển giao kế trước\n"
-" f, fixup = giống như \"squash\", nhưng loại bỏ chú thích của lần chuyển "
-"giao này\n"
-" x, exec = chạy lệnh (phần còn lại của dòng) dùng hệ vỏ\n"
-" d, drop = xóa lần chuyển giao\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"
+"s, squash <commit> = dùng lần chuyển giao, nhưng meld vào lần chuyển giao kế "
+"trước\n"
+"f, fixup <commit> = giống như \"squash\", nhưng loại bỏ chú thích nhật ký "
+"của lần chuyển giao này\n"
+"x, exec <commit> = chạy lệnh (phần còn lại của dòng) dùng hệ vỏ\n"
+"d, drop <commit> = xóa 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"
+"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"
 "\n"
 "Những dòng này có thể đảo ngược thứ tự; chúng chạy từ trên đỉnh xuống dưới "
 "đáy.\n"
 
-#: git-rebase--interactive.sh:171
+#: git-rebase--interactive.sh:179
 msgid ""
 "\n"
 "Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
@@ -15859,7 +16967,7 @@ msgstr ""
 "Đừ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"
 
-#: git-rebase--interactive.sh:175
+#: git-rebase--interactive.sh:183
 msgid ""
 "\n"
 "If you remove a line here THAT COMMIT WILL BE LOST.\n"
@@ -15867,7 +16975,7 @@ msgstr ""
 "\n"
 "Nếu bạn xóa bỏ một dòng ở đây thì LẦN CHUYỂN GIAO ĐÓ SẼ MẤT.\n"
 
-#: git-rebase--interactive.sh:213
+#: git-rebase--interactive.sh:221
 #, sh-format
 msgid ""
 "You can amend the commit now, with\n"
@@ -15886,82 +16994,82 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:238
+#: git-rebase--interactive.sh:246
 #, sh-format
 msgid "$sha1: not a commit that can be picked"
 msgstr "$sha1: không phải là lần chuyển giao mà có thể lấy ra được"
 
-#: git-rebase--interactive.sh:277
+#: git-rebase--interactive.sh:285
 #, sh-format
 msgid "Invalid commit name: $sha1"
 msgstr "Tên lần chuyển giao không hợp lệ: $sha1"
 
-#: git-rebase--interactive.sh:319
+#: git-rebase--interactive.sh:325
 msgid "Cannot write current commit's replacement sha1"
 msgstr "Không thể ghi lại sha1 thay thế của lần chuyển giao"
 
-#: git-rebase--interactive.sh:371
+#: git-rebase--interactive.sh:376
 #, sh-format
 msgid "Fast-forward to $sha1"
 msgstr "Chuyển-tiếp-nhanh đến $sha1"
 
-#: git-rebase--interactive.sh:373
+#: git-rebase--interactive.sh:378
 #, sh-format
 msgid "Cannot fast-forward to $sha1"
 msgstr "Không thể chuyển-tiếp-nhanh đến $sha1"
 
-#: git-rebase--interactive.sh:382
+#: git-rebase--interactive.sh:387
 #, sh-format
 msgid "Cannot move HEAD to $first_parent"
 msgstr "Không thể di chuyển HEAD đến $first_parent"
 
-#: git-rebase--interactive.sh:387
+#: git-rebase--interactive.sh:392
 #, sh-format
 msgid "Refusing to squash a merge: $sha1"
 msgstr "Từ chối squash lần hòa trộn: $sha1"
 
-#: git-rebase--interactive.sh:405
+#: git-rebase--interactive.sh:410
 #, sh-format
 msgid "Error redoing merge $sha1"
 msgstr "Gặp lỗi khi hoàn lại bước hòa trộn $sha1"
 
-#: git-rebase--interactive.sh:414
+#: git-rebase--interactive.sh:419
 #, sh-format
 msgid "Could not pick $sha1"
 msgstr "Không thể lấy ra $sha1"
 
-#: git-rebase--interactive.sh:423
+#: git-rebase--interactive.sh:428
 #, sh-format
 msgid "This is the commit message #${n}:"
 msgstr "Đây là chú thích cho lần chuyển giao thứ #${n}:"
 
-#: git-rebase--interactive.sh:428
+#: git-rebase--interactive.sh:433
 #, sh-format
 msgid "The commit message #${n} will be skipped:"
 msgstr "Chú thích cho lần chuyển giao thứ #${n} sẽ bị bỏ qua:"
 
-#: git-rebase--interactive.sh:439
+#: git-rebase--interactive.sh:444
 #, sh-format
 msgid "This is a combination of $count commit."
 msgid_plural "This is a combination of $count commits."
 msgstr[0] "Đây là tổ hợp của $count lần chuyển giao."
 
-#: git-rebase--interactive.sh:448
+#: git-rebase--interactive.sh:453
 #, sh-format
 msgid "Cannot write $fixup_msg"
 msgstr "Không thể $fixup_msg"
 
-#: git-rebase--interactive.sh:451
+#: git-rebase--interactive.sh:456
 msgid "This is a combination of 2 commits."
 msgstr "Đây là tổ hợp của 2 lần chuyển giao."
 
-#: git-rebase--interactive.sh:492 git-rebase--interactive.sh:535
-#: git-rebase--interactive.sh:538
+#: git-rebase--interactive.sh:497 git-rebase--interactive.sh:540
+#: git-rebase--interactive.sh:543
 #, sh-format
 msgid "Could not apply $sha1... $rest"
 msgstr "Không thể áp dụng $sha1… $rest"
 
-#: git-rebase--interactive.sh:567
+#: git-rebase--interactive.sh:572
 #, sh-format
 msgid ""
 "Could not amend commit after successfully picking $sha1... $rest\n"
@@ -15977,31 +17085,31 @@ msgstr ""
 "này\n"
 "trước khi bạn có thể làm việc lại với lần chuyển giao."
 
-#: git-rebase--interactive.sh:582
+#: git-rebase--interactive.sh:587
 #, sh-format
 msgid "Stopped at $sha1_abbrev... $rest"
 msgstr "Bị dừng tại $sha1_abbrev… $rest"
 
-#: git-rebase--interactive.sh:597
+#: git-rebase--interactive.sh:602
 #, sh-format
 msgid "Cannot '$squash_style' without a previous commit"
 msgstr "Không “$squash_style” thể mà không có lần chuyển giao kế trước"
 
-#: git-rebase--interactive.sh:639
+#: git-rebase--interactive.sh:644
 #, sh-format
 msgid "Executing: $rest"
 msgstr "Thực thi: $rest"
 
-#: git-rebase--interactive.sh:647
+#: git-rebase--interactive.sh:652
 #, sh-format
 msgid "Execution failed: $rest"
 msgstr "Thực thi gặp lỗi: $rest"
 
-#: git-rebase--interactive.sh:649
+#: git-rebase--interactive.sh:654
 msgid "and made changes to the index and/or the working tree"
 msgstr "và tạo các thay đổi bảng mục lục và/hay cây làm việc"
 
-#: git-rebase--interactive.sh:651
+#: git-rebase--interactive.sh:656
 msgid ""
 "You can fix the problem, and then run\n"
 "\n"
@@ -16012,7 +17120,7 @@ msgstr ""
 "\tgit rebase --continue"
 
 #. TRANSLATORS: after these lines is a command to be issued by the user
-#: git-rebase--interactive.sh:664
+#: git-rebase--interactive.sh:669
 #, sh-format
 msgid ""
 "Execution succeeded: $rest\n"
@@ -16027,29 +17135,29 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:675
+#: git-rebase--interactive.sh:680
 #, sh-format
 msgid "Unknown command: $command $sha1 $rest"
 msgstr "Lệnh chưa biết: $command $sha1 $rest"
 
-#: git-rebase--interactive.sh:676
+#: git-rebase--interactive.sh:681
 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”."
 
-#: git-rebase--interactive.sh:711
+#: git-rebase--interactive.sh:716
 #, sh-format
 msgid "Successfully rebased and updated $head_name."
 msgstr "Cài tổ và cập nhật $head_name một cách thành công."
 
-#: git-rebase--interactive.sh:735
+#: git-rebase--interactive.sh:740
 msgid "could not detach HEAD"
 msgstr "không thể tách rời HEAD"
 
-#: git-rebase--interactive.sh:771
+#: git-rebase--interactive.sh:778
 msgid "Could not remove CHERRY_PICK_HEAD"
 msgstr "Không thể xóa bỏ CHERRY_PICK_HEAD"
 
-#: git-rebase--interactive.sh:776
+#: git-rebase--interactive.sh:783
 #, sh-format
 msgid ""
 "You have staged changes in your working tree.\n"
@@ -16080,11 +17188,11 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: git-rebase--interactive.sh:793
+#: git-rebase--interactive.sh:800
 msgid "Error trying to find the author identity to amend commit"
 msgstr "Lỗi khi cố tìm định danh của tác giả để tu bổ lần chuyển giao"
 
-#: git-rebase--interactive.sh:798
+#: git-rebase--interactive.sh:805
 msgid ""
 "You have uncommitted changes in your working tree. Please commit them\n"
 "first and then run 'git rebase --continue' again."
@@ -16093,11 +17201,11 @@ msgstr ""
 "Vui lòng chuyển giao chúng và sau đó chạy lệnh “git rebase --continue” lần "
 "nữa."
 
-#: git-rebase--interactive.sh:803 git-rebase--interactive.sh:807
+#: git-rebase--interactive.sh:810 git-rebase--interactive.sh:814
 msgid "Could not commit staged changes."
 msgstr "Không thể chuyển giao các thay đổi đã đưa lên bệ phóng."
 
-#: git-rebase--interactive.sh:836
+#: git-rebase--interactive.sh:843
 msgid ""
 "\n"
 "You are editing the todo file of an ongoing interactive rebase.\n"
@@ -16111,55 +17219,58 @@ msgstr ""
 "    git rebase --continue\n"
 "\n"
 
-#: git-rebase--interactive.sh:844 git-rebase--interactive.sh:1008
+#: git-rebase--interactive.sh:851 git-rebase--interactive.sh:937
 msgid "Could not execute editor"
 msgstr "Không thể thực thi trình biên soạn"
 
-#: git-rebase--interactive.sh:860
+#: git-rebase--interactive.sh:872
 #, sh-format
 msgid "Could not checkout $switch_to"
 msgstr "Không thể checkout $switch_to"
 
-#: git-rebase--interactive.sh:865
+#: git-rebase--interactive.sh:879
 msgid "No HEAD?"
 msgstr "Không HEAD?"
 
-#: git-rebase--interactive.sh:866
+#: git-rebase--interactive.sh:880
 #, sh-format
 msgid "Could not create temporary $state_dir"
 msgstr "Không thể tạo thư mục tạm thời $state_dir"
 
-#: git-rebase--interactive.sh:869
+#: git-rebase--interactive.sh:883
 msgid "Could not mark as interactive"
 msgstr "Không thể đánh dấu là tương tác"
 
-#: git-rebase--interactive.sh:879 git-rebase--interactive.sh:884
-msgid "Could not init rewritten commits"
-msgstr "Không thể khởi tạo các lần chuyển giao ghi lại"
-
-#: git-rebase--interactive.sh:910
-msgid "Could not generate todo list"
-msgstr "Không thể tạo danh sách cần làm"
-
-#: git-rebase--interactive.sh:986
+#: git-rebase--interactive.sh:915
 #, sh-format
 msgid "Rebase $shortrevisions onto $shortonto ($todocount command)"
 msgid_plural "Rebase $shortrevisions onto $shortonto ($todocount commands)"
 msgstr[0] "Cải tổ $shortrevisions vào $shortonto (các lệnh $todocount)"
 
-#: git-rebase--interactive.sh:991
+#: git-rebase--interactive.sh:920
 msgid ""
 "\n"
-"However, if you remove everything, the rebase will be aborted.\n"
+"\tHowever, if you remove everything, the rebase will be aborted.\n"
 "\n"
+"\t"
 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"
+"\tTuy nhiên, nếu bạn xóa bỏ mọi thứ, việc cải tổ sẽ bị bãi bỏ.\n"
+"\n"
+"\t"
 
-#: git-rebase--interactive.sh:998
+#: git-rebase--interactive.sh:927
 msgid "Note that empty commits are commented out"
 msgstr "Chú ý rằng lần chuyển giao trống rỗng là ghi chú"
 
+#: git-rebase--interactive.sh:980
+msgid "Could not generate todo list"
+msgstr "Không thể tạo danh sách cần làm"
+
+#: git-rebase--interactive.sh:1001 git-rebase--interactive.sh:1006
+msgid "Could not init rewritten commits"
+msgstr "Không thể khởi tạo các lần chuyển giao ghi lại"
+
 #: git-sh-setup.sh:89 git-sh-setup.sh:94
 #, sh-format
 msgid "usage: $dashless $USAGE"
@@ -16240,64 +17351,64 @@ msgstr "đã đưa lên bệ phóng"
 msgid "unstaged"
 msgstr "chưa đưa lên bệ phóng"
 
-#: git-add--interactive.perl:246 git-add--interactive.perl:271
+#: git-add--interactive.perl:253 git-add--interactive.perl:278
 msgid "binary"
 msgstr "nhị phân"
 
-#: git-add--interactive.perl:255 git-add--interactive.perl:309
+#: git-add--interactive.perl:262 git-add--interactive.perl:316
 msgid "nothing"
 msgstr "không có gì"
 
-#: git-add--interactive.perl:291 git-add--interactive.perl:306
+#: git-add--interactive.perl:298 git-add--interactive.perl:313
 msgid "unchanged"
 msgstr "không thay đổi"
 
-#: git-add--interactive.perl:602
+#: git-add--interactive.perl:609
 #, perl-format
 msgid "added %d path\n"
 msgid_plural "added %d paths\n"
 msgstr[0] "đã thêm %d đường dẫn\n"
 
-#: git-add--interactive.perl:605
+#: git-add--interactive.perl:612
 #, perl-format
 msgid "updated %d path\n"
 msgid_plural "updated %d paths\n"
 msgstr[0] "đã cập nhật %d đường dẫn\n"
 
-#: git-add--interactive.perl:608
+#: git-add--interactive.perl:615
 #, perl-format
 msgid "reverted %d path\n"
 msgid_plural "reverted %d paths\n"
 msgstr[0] "đã hoàn nguyên %d đường dẫn\n"
 
-#: git-add--interactive.perl:611
+#: git-add--interactive.perl:618
 #, perl-format
 msgid "touched %d path\n"
 msgid_plural "touched %d paths\n"
 msgstr[0] "%d đường dẫn đã touch (chạm)\n"
 
-#: git-add--interactive.perl:620
+#: git-add--interactive.perl:627
 msgid "Update"
 msgstr "Cập nhật"
 
-#: git-add--interactive.perl:632
+#: git-add--interactive.perl:639
 msgid "Revert"
 msgstr "Hoàn nguyên"
 
-#: git-add--interactive.perl:655
+#: git-add--interactive.perl:662
 #, perl-format
 msgid "note: %s is untracked now.\n"
 msgstr "chú ý: %s giờ đã bỏ theo dõi.\n"
 
-#: git-add--interactive.perl:666
+#: git-add--interactive.perl:673
 msgid "Add untracked"
 msgstr "Thêm các cái chưa được theo dõi"
 
-#: git-add--interactive.perl:672
+#: git-add--interactive.perl:679
 msgid "No untracked files.\n"
 msgstr "Không có tập tin nào chưa được theo dõi.\n"
 
-#: git-add--interactive.perl:1026
+#: git-add--interactive.perl:1033
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for staging."
@@ -16305,7 +17416,7 @@ msgstr ""
 "Nếu miếng vá được áp dụng sạch sẽ, hunk đã sửa sẽ ngay lập tức\n"
 "được đánh dấu để chuyển lên bệ phóng."
 
-#: git-add--interactive.perl:1029
+#: git-add--interactive.perl:1036
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for stashing."
@@ -16313,7 +17424,7 @@ msgstr ""
 "Nếu miếng vá được áp dụng sạch sẽ, hunk đã sửa sẽ ngay lập tức\n"
 "được đánh dấu để tạm cất."
 
-#: git-add--interactive.perl:1032
+#: git-add--interactive.perl:1039
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for unstaging."
@@ -16321,7 +17432,7 @@ msgstr ""
 "Nếu miếng vá được áp dụng sạch sẽ, hunk đã sửa sẽ ngay lập tức\n"
 "được đánh dấu để bỏ chuyển lên bệ phóng."
 
-#: git-add--interactive.perl:1035 git-add--interactive.perl:1044
+#: git-add--interactive.perl:1042 git-add--interactive.perl:1051
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for applying."
@@ -16329,7 +17440,7 @@ msgstr ""
 "Nếu miếng vá được áp dụng sạch sẽ, hunk đã sửa sẽ ngay lập tức\n"
 "được đánh dấu để áp dụng."
 
-#: git-add--interactive.perl:1038 git-add--interactive.perl:1041
+#: git-add--interactive.perl:1045 git-add--interactive.perl:1048
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for discarding."
@@ -16337,16 +17448,16 @@ msgstr ""
 "Nếu miếng vá được áp dụng sạch sẽ, hunk đã sửa sẽ ngay lập tức\n"
 "được đánh dấu để loại bỏ."
 
-#: git-add--interactive.perl:1078
+#: git-add--interactive.perl:1085
 #, perl-format
 msgid "failed to open hunk edit file for writing: %s"
 msgstr "gặp lỗi khi tập tin sửa hunk để ghi: %s"
 
-#: git-add--interactive.perl:1079
+#: git-add--interactive.perl:1086
 msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
 msgstr "Chế độ sửa hunk bằng tay -- xem ở đáy để có hướng dẫn sử dụng nhanh.\n"
 
-#: git-add--interactive.perl:1085
+#: git-add--interactive.perl:1092
 #, perl-format
 msgid ""
 "---\n"
@@ -16360,7 +17471,7 @@ msgstr ""
 "Những dòng bắt đầu bằng %s sẽ bị loại bỏ.\n"
 
 #. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
-#: git-add--interactive.perl:1093
+#: git-add--interactive.perl:1100
 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"
@@ -16370,7 +17481,7 @@ msgstr ""
 "để sửa lần nữa. Nếu mọi dòng của hunk bị xóa bỏ, thế thì những\n"
 "sửa dổi sẽ bị loại bỏ, và hunk vẫn giữ nguyên.\n"
 
-#: git-add--interactive.perl:1107
+#: git-add--interactive.perl:1114
 #, perl-format
 msgid "failed to open hunk edit file for reading: %s"
 msgstr "gặp lỗi khi mở tập tin hunk để đọc: %s"
@@ -16381,14 +17492,14 @@ msgstr "gặp lỗi khi mở tập tin hunk để đọc: %s"
 #. 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:1206
+#: git-add--interactive.perl:1213
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr ""
 "Hunk đã sửa của bạn không được áp dụng. Sửa lại lần nữa (nói \"n\" để loại "
 "bỏ!) [y/n]? "
 
-#: git-add--interactive.perl:1215
+#: git-add--interactive.perl:1222
 msgid ""
 "y - stage this hunk\n"
 "n - do not stage this hunk\n"
@@ -16403,7 +17514,7 @@ msgstr ""
 "d - đừng đưa lên bệ phóng hunk này cũng như bất kỳ cái nào còn lại trong tập "
 "tin"
 
-#: git-add--interactive.perl:1221
+#: git-add--interactive.perl:1228
 msgid ""
 "y - stash this hunk\n"
 "n - do not stash this hunk\n"
@@ -16417,7 +17528,7 @@ msgstr ""
 "a - tạm cất hunk này và tất cả các hunk sau này trong tập tin\n"
 "d - đừng tạm cất hunk này cũng như bất kỳ cái nào còn lại trong tập tin"
 
-#: git-add--interactive.perl:1227
+#: git-add--interactive.perl:1234
 msgid ""
 "y - unstage this hunk\n"
 "n - do not unstage this hunk\n"
@@ -16433,7 +17544,7 @@ msgstr ""
 "d - đừng đưa ra khỏi bệ phóng hunk này cũng như bất kỳ cái nào còn lại trong "
 "tập tin"
 
-#: git-add--interactive.perl:1233
+#: git-add--interactive.perl:1240
 msgid ""
 "y - apply this hunk to index\n"
 "n - do not apply this hunk to index\n"
@@ -16447,7 +17558,7 @@ msgstr ""
 "a - áp dụng hunk này và tất cả các hunk sau này trong tập tin\n"
 "d - đừng áp dụng hunk này cũng như bất kỳ cái nào sau này trong tập tin"
 
-#: git-add--interactive.perl:1239
+#: git-add--interactive.perl:1246
 msgid ""
 "y - discard this hunk from worktree\n"
 "n - do not discard this hunk from worktree\n"
@@ -16461,7 +17572,7 @@ msgstr ""
 "a - loại bỏ hunk này và tất cả các hunk sau này trong tập tin\n"
 "d - đừng loại bỏ hunk này cũng như bất kỳ cái nào sau này trong tập tin"
 
-#: git-add--interactive.perl:1245
+#: git-add--interactive.perl:1252
 msgid ""
 "y - discard this hunk from index and worktree\n"
 "n - do not discard this hunk from index and worktree\n"
@@ -16475,7 +17586,7 @@ msgstr ""
 "a - loại bỏ hunk này và tất cả các hunk sau này trong tập tin\n"
 "d - đừng loại bỏ hunk này cũng như bất kỳ cái nào sau này trong tập tin"
 
-#: git-add--interactive.perl:1251
+#: git-add--interactive.perl:1258
 msgid ""
 "y - apply this hunk to index and worktree\n"
 "n - do not apply this hunk to index and worktree\n"
@@ -16489,7 +17600,7 @@ msgstr ""
 "a - áp dụng hunk này và tất cả các hunk sau này trong tập tin\n"
 "d - đừng áp dụng hunk này cũng như bất kỳ cái nào sau này trong tập tin"
 
-#: git-add--interactive.perl:1266
+#: git-add--interactive.perl:1273
 msgid ""
 "g - select a hunk to go to\n"
 "/ - search for a hunk matching the given regex\n"
@@ -16511,209 +17622,209 @@ msgstr ""
 "e - sửa bằng tay hunk hiện hành\n"
 "? - in trợ giúp\n"
 
-#: git-add--interactive.perl:1297
+#: git-add--interactive.perl:1304
 msgid "The selected hunks do not apply to the index!\n"
 msgstr "Các hunk đã chọn không được áp dụng vào bảng mục lục!\n"
 
-#: git-add--interactive.perl:1298
+#: git-add--interactive.perl:1305
 msgid "Apply them to the worktree anyway? "
 msgstr "Vẫn áp dụng chúng cho cây làm việc? "
 
-#: git-add--interactive.perl:1301
+#: git-add--interactive.perl:1308
 msgid "Nothing was applied.\n"
 msgstr "Đã không áp dụng gì cả.\n"
 
-#: git-add--interactive.perl:1312
+#: git-add--interactive.perl:1319
 #, perl-format
 msgid "ignoring unmerged: %s\n"
 msgstr "bỏ qua những thứ chưa hòa trộn: %s\n"
 
-#: git-add--interactive.perl:1321
+#: git-add--interactive.perl:1328
 msgid "Only binary files changed.\n"
 msgstr "Chỉ có các tập tin nhị phân là thay đổi.\n"
 
-#: git-add--interactive.perl:1323
+#: git-add--interactive.perl:1330
 msgid "No changes.\n"
 msgstr "Không có thay đổi nào.\n"
 
-#: git-add--interactive.perl:1331
+#: git-add--interactive.perl:1338
 msgid "Patch update"
 msgstr "Cập nhật miếng vá"
 
-#: git-add--interactive.perl:1383
+#: git-add--interactive.perl:1390
 #, perl-format
 msgid "Stage mode change [y,n,q,a,d%s,?]? "
 msgstr "Thay đổi chế độ bệ phóng [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1384
+#: git-add--interactive.perl:1391
 #, perl-format
 msgid "Stage deletion [y,n,q,a,d%s,?]? "
 msgstr "Xóa khỏi bệ phóng [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1385
+#: git-add--interactive.perl:1392
 #, perl-format
 msgid "Stage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Đưa lên bệ phóng hunk này [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1388
+#: git-add--interactive.perl:1395
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1389
+#: git-add--interactive.perl:1396
 #, perl-format
 msgid "Stash deletion [y,n,q,a,d%s,?]? "
 msgstr "Xóa tạm cất [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1390
+#: git-add--interactive.perl:1397
 #, perl-format
 msgid "Stash this hunk [y,n,q,a,d%s,?]? "
 msgstr "Tạm cất hunk này [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1393
+#: git-add--interactive.perl:1400
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1394
+#: git-add--interactive.perl:1401
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1395
+#: git-add--interactive.perl:1402
 #, perl-format
 msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
 msgstr "Bỏ ra khỏi bệ phóng hunk này [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1398
+#: git-add--interactive.perl:1405
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1399
+#: git-add--interactive.perl:1406
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1400
+#: git-add--interactive.perl:1407
 #, perl-format
 msgid "Apply this hunk to index [y,n,q,a,d%s,?]? "
 msgstr "Áo dụng hunk này vào mục lục [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1403
+#: git-add--interactive.perl:1410
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1404
+#: git-add--interactive.perl:1411
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1405
+#: git-add--interactive.perl:1412
 #, perl-format
 msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
 msgstr "Loại bỏ hunk này khỏi cây làm việc [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1408
+#: git-add--interactive.perl:1415
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1409
+#: git-add--interactive.perl:1416
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1410
+#: git-add--interactive.perl:1417
 #, perl-format
 msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Loại bỏ hunk này khỏi mục lục và cây làm việc [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1413
+#: git-add--interactive.perl:1420
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1414
+#: git-add--interactive.perl:1421
 #, perl-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,?]? "
 
-#: git-add--interactive.perl:1415
+#: git-add--interactive.perl:1422
 #, perl-format
 msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "Áp dụng hunk này vào mục lục và cây làm việc [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1515
+#: git-add--interactive.perl:1522
 msgid "No other hunks to goto\n"
 msgstr "Không còn hunk nào để mà nhảy đến\n"
 
-#: git-add--interactive.perl:1522
+#: git-add--interactive.perl:1529
 msgid "go to which hunk (<ret> to see more)? "
 msgstr "nhảy đến hunk nào (<ret> để xem thêm)? "
 
-#: git-add--interactive.perl:1524
+#: git-add--interactive.perl:1531
 msgid "go to which hunk? "
 msgstr "nhảy đến hunk nào?"
 
-#: git-add--interactive.perl:1533
+#: git-add--interactive.perl:1540
 #, perl-format
 msgid "Invalid number: '%s'\n"
 msgstr "Số không hợp lệ: “%s”\n"
 
-#: git-add--interactive.perl:1538
+#: git-add--interactive.perl:1545
 #, 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 hunk..\n"
 
-#: git-add--interactive.perl:1564
+#: git-add--interactive.perl:1571
 msgid "No other hunks to search\n"
 msgstr "Không còn hunk nào để mà tìm kiếm\n"
 
-#: git-add--interactive.perl:1568
+#: git-add--interactive.perl:1575
 msgid "search for regex? "
 msgstr "tìm kiếm cho regex? "
 
-#: git-add--interactive.perl:1581
+#: git-add--interactive.perl:1588
 #, 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"
 
-#: git-add--interactive.perl:1591
+#: git-add--interactive.perl:1598
 msgid "No hunk matches the given pattern\n"
 msgstr "Không thấy hunk nào khớp mẫu đã cho\n"
 
-#: git-add--interactive.perl:1603 git-add--interactive.perl:1625
+#: git-add--interactive.perl:1610 git-add--interactive.perl:1632
 msgid "No previous hunk\n"
 msgstr "Không có hunk kế trước\n"
 
-#: git-add--interactive.perl:1612 git-add--interactive.perl:1631
+#: git-add--interactive.perl:1619 git-add--interactive.perl:1638
 msgid "No next hunk\n"
 msgstr "Không có hunk kế tiếp\n"
 
-#: git-add--interactive.perl:1637
+#: git-add--interactive.perl:1644
 msgid "Sorry, cannot split this hunk\n"
 msgstr "Rất tiếc, không thể chia nhỏ hunk này\n"
 
-#: git-add--interactive.perl:1643
+#: git-add--interactive.perl:1650
 #, perl-format
 msgid "Split into %d hunk.\n"
 msgid_plural "Split into %d hunks.\n"
 msgstr[0] "Chi nhỏ thành %d hunks.\n"
 
-#: git-add--interactive.perl:1653
+#: git-add--interactive.perl:1660
 msgid "Sorry, cannot edit this hunk\n"
 msgstr "Rất tiếc, không thể sửa hunk này\n"
 
-#: git-add--interactive.perl:1699
+#: git-add--interactive.perl:1706
 msgid "Review diff"
 msgstr "Xem xét lại diff"
 
 #. TRANSLATORS: please do not translate the command names
 #. 'status', 'update', 'revert', etc.
-#: git-add--interactive.perl:1718
+#: git-add--interactive.perl:1725
 msgid ""
 "status        - show paths with changes\n"
 "update        - add working tree state to the staged set of changes\n"
@@ -16733,18 +17844,18 @@ msgstr ""
 "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"
 
-#: git-add--interactive.perl:1735 git-add--interactive.perl:1740
-#: git-add--interactive.perl:1743 git-add--interactive.perl:1750
-#: git-add--interactive.perl:1754 git-add--interactive.perl:1760
+#: git-add--interactive.perl:1742 git-add--interactive.perl:1747
+#: git-add--interactive.perl:1750 git-add--interactive.perl:1757
+#: git-add--interactive.perl:1761 git-add--interactive.perl:1767
 msgid "missing --"
 msgstr "thiếu --"
 
-#: git-add--interactive.perl:1756
+#: git-add--interactive.perl:1763
 #, perl-format
 msgid "unknown --patch mode: %s"
 msgstr "không hiểu chế độ --patch: %s"
 
-#: git-add--interactive.perl:1762 git-add--interactive.perl:1768
+#: git-add--interactive.perl:1769 git-add--interactive.perl:1775
 #, perl-format
 msgid "invalid argument %s, expecting --"
 msgstr "đối số không hợp lệ %s, cần --"
@@ -16956,7 +18067,7 @@ msgstr "Làm gì với địa chỉ này? (thoát[q]|xóa[d]|sửa[e]): "
 msgid "CA path \"%s\" does not exist"
 msgstr "đường dẫn CA “%s” không tồn tại"
 
-#: git-send-email.perl:1395
+#: git-send-email.perl:1400
 msgid ""
 "    The Cc list above has been expanded by additional\n"
 "    addresses found in the patch commit message. By default\n"
@@ -16980,136 +18091,166 @@ msgstr ""
 "    chạy “git config --global sendemail.confirm auto”.\n"
 "\n"
 
-#. TRANSLATORS: Make sure to include [y] [n] [q] [a] in your
+#. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
 #. translation. The program will only accept English input
 #. at this point.
-#: git-send-email.perl:1410
-msgid "Send this email? ([y]es|[n]o|[q]uit|[a]ll): "
-msgstr "Gửi thư này chứ? ([y]có|[n]không|[q]thoát|[a]tất): "
+#: git-send-email.perl:1415
+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): "
 
-#: git-send-email.perl:1413
+#: git-send-email.perl:1418
 msgid "Send this email reply required"
 msgstr "Gửi thư này trả lời yêu cầu"
 
-#: git-send-email.perl:1439
+#: git-send-email.perl:1446
 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."
 
-#: git-send-email.perl:1486
+#: git-send-email.perl:1493
 #, perl-format
 msgid "Server does not support STARTTLS! %s"
 msgstr "Máy chủ không hỗ trợ STARTTLS! %s"
 
-#: git-send-email.perl:1491 git-send-email.perl:1495
+#: git-send-email.perl:1498 git-send-email.perl:1502
 #, perl-format
 msgid "STARTTLS failed! %s"
 msgstr "STARTTLS gặp lỗi! %s"
 
-#: git-send-email.perl:1505
+#: git-send-email.perl:1512
 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."
 
-#: git-send-email.perl:1523
+#: git-send-email.perl:1530
 #, perl-format
 msgid "Failed to send %s\n"
 msgstr "Gặp lỗi khi gửi %s\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Dry-Sent %s\n"
 msgstr "Thử gửi %s\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Sent %s\n"
 msgstr "Gửi %s\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "Dry-OK. Log says:\n"
 msgstr "Dry-OK. Nhật ký nói rằng:\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "OK. Log says:\n"
 msgstr "OK. Nhật ký nói rằng:\n"
 
-#: git-send-email.perl:1540
+#: git-send-email.perl:1547
 msgid "Result: "
 msgstr "Kết quả: "
 
-#: git-send-email.perl:1543
+#: git-send-email.perl:1550
 msgid "Result: OK\n"
 msgstr "Kết quả: Tốt\n"
 
-#: git-send-email.perl:1556
+#: git-send-email.perl:1568
 #, perl-format
 msgid "can't open file %s"
 msgstr "không thể mở tập tin “%s”"
 
-#: git-send-email.perl:1603 git-send-email.perl:1623
+#: git-send-email.perl:1615 git-send-email.perl:1635
 #, perl-format
 msgid "(mbox) Adding cc: %s from line '%s'\n"
 msgstr "(mbox) Thêm cc: %s từ dòng “%s”\n"
 
-#: git-send-email.perl:1609
+#: git-send-email.perl:1621
 #, perl-format
 msgid "(mbox) Adding to: %s from line '%s'\n"
 msgstr "(mbox) Đang thêm to: %s từ dòng “%s”\n"
 
-#: git-send-email.perl:1657
+#: git-send-email.perl:1674
 #, perl-format
 msgid "(non-mbox) Adding cc: %s from line '%s'\n"
 msgstr "(non-mbox) Thêm cc: %s từ dòng “%s”\n"
 
-#: git-send-email.perl:1682
+#: git-send-email.perl:1699
 #, perl-format
 msgid "(body) Adding cc: %s from line '%s'\n"
 msgstr "(body) Thêm cc: %s từ dòng “%s”\n"
 
-#: git-send-email.perl:1788
+#: git-send-email.perl:1817
 #, perl-format
 msgid "(%s) Could not execute '%s'"
 msgstr "(%s) Không thể thực thi “%s”"
 
-#: git-send-email.perl:1795
+#: git-send-email.perl:1824
 #, perl-format
 msgid "(%s) Adding %s: %s from: '%s'\n"
 msgstr "(%s) Đang thêm %s: %s từ: “%s”\n"
 
-#: git-send-email.perl:1799
+#: git-send-email.perl:1828
 #, perl-format
 msgid "(%s) failed to close pipe to '%s'"
 msgstr "(%s) gặp lỗi khi đóng đường ống đến “%s”"
 
-#: git-send-email.perl:1826
+#: git-send-email.perl:1855
 msgid "cannot send message as 7bit"
 msgstr "không thể lấy gửi thư dạng 7 bít"
 
-#: git-send-email.perl:1834
+#: git-send-email.perl:1863
 msgid "invalid transfer encoding"
 msgstr "bảng mã truyền không hợp lệ"
 
-#: git-send-email.perl:1872 git-send-email.perl:1923 git-send-email.perl:1933
+#: git-send-email.perl:1901 git-send-email.perl:1952 git-send-email.perl:1962
 #, perl-format
 msgid "unable to open %s: %s\n"
 msgstr "không thể mở %s: %s\n"
 
-#: git-send-email.perl:1875
+#: git-send-email.perl:1904
 #, perl-format
 msgid "%s: patch contains a line longer than 998 characters"
 msgstr "%s: miếng vá có chứa dòng dài hơn 998 ký tự"
 
-#: git-send-email.perl:1891
+#: git-send-email.perl:1920
 #, 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"
 
 #. TRANSLATORS: please keep "[y|N]" as is.
-#: git-send-email.perl:1895
+#: git-send-email.perl:1924
 #, 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]: "
+msgstr "Bạn có thực sự muốn gửi %s? [y|N](có/KHÔNG): "
+
+#~ msgid "Everyday Git With 20 Commands Or So"
+#~ msgstr "Mỗi ngày học 20 lệnh Git hay hơn"
+
+#~ msgid "Could not open '%s' for writing"
+#~ msgstr "Không thể mở “%s” để ghi"
+
+#~ msgid ""
+#~ "unexpected 1st line of squash message:\n"
+#~ "\n"
+#~ "\t%.*s"
+#~ msgstr ""
+#~ "không cần dòng thứ nhất của ghi chú squash:\n"
+#~ "\n"
+#~ "\t%.*s"
+
+#~ msgid ""
+#~ "invalid 1st line of squash message:\n"
+#~ "\n"
+#~ "\t%.*s"
+#~ msgstr ""
+#~ "dòng thứ nhất của ghi chú squash không hợp lệ:\n"
+#~ "\n"
+#~ "\t%.*s"
+
+#~ msgid "BUG: returned path string doesn't match cwd?"
+#~ msgstr "LỖI: trả về chuỗi đường dẫn không khớp cwd?"
+
+#~ msgid "Error in object"
+#~ msgstr "Lỗi trong đối tượng"
 
 #~ msgid "git fetch-pack: expected ACK/NAK, got EOF"
 #~ msgstr "git fetch-pack: cần ACK/NAK, nhưng lại nhận được EOF"
@@ -17305,9 +18446,6 @@ msgstr "Bạn có thực sự muốn gửi %s? [y|N]: "
 #~ msgid "blob object"
 #~ msgstr "đối tượng blob"
 
-#~ msgid "other tag object"
-#~ msgstr "đối tượng thẻ khác"
-
 #~ msgid ""
 #~ "There is nothing to exclude from by :(exclude) patterns.\n"
 #~ "Perhaps you forgot to add either ':/' or '.' ?"
@@ -17671,9 +18809,6 @@ msgstr "Bạn có thực sự muốn gửi %s? [y|N]: "
 #~ "Vui lòng đưa các thay đổi của bạn vào “.gitmodules” hay tạm cất chúng đi "
 #~ "để xử lý"
 
-#~ msgid "could not verify the tag '%s'"
-#~ msgstr "không thể thẩm tra thẻ “%s”"
-
 #~ msgid "failed to remove: %s"
 #~ msgstr "gặp lỗi khi gỡ bỏ: %s"
 
@@ -17865,9 +19000,6 @@ msgstr "Bạn có thực sự muốn gửi %s? [y|N]: "
 #~ msgid "no branch specified"
 #~ msgstr "chưa chỉ ra tên của nhánh"
 
-#~ msgid "check a branch out in a separate working directory"
-#~ msgstr "lấy ra một nhánh trong một thư mục làm việc cách biệt"
-
 #~ msgid "prune .git/worktrees"
 #~ msgstr "xén .git/worktrees"
 
@@ -18078,9 +19210,6 @@ msgstr "Bạn có thực sự muốn gửi %s? [y|N]: "
 #~ msgid "more than %d trees given: '%s'"
 #~ msgstr "đã chỉ ra nhiều hơn %d cây (tree): “%s”"
 
-#~ msgid "You cannot combine --no-ff with --ff-only."
-#~ msgstr "Bạn không thể kết hợp --no-ff với --ff-only."
-
 #~ msgid ""
 #~ "'%s' has changes staged in the index\n"
 #~ "(use --cached to keep the file, or -f to force removal)"
index fa3f48445633ca3a86b12665a88c7feb40ec5fdf..239a54a7e3f7fa12bda5af07b4af1c56150a306b 100644 (file)
@@ -58,7 +58,7 @@
 #   fork                             |  派生
 #   Git archive                      |  仓库(对于 arch 用户)
 #   gitfile                          |  gitfile(仓库链接文件)
-#   grafts                           |  (提交)嫁接
+#   grafts                           |  (提交)移植
 #   hash                             |  哈希值
 #   HEAD                             |  HEAD(头指针,亦即当前分支)
 #   head                             |  头、分支
@@ -138,8 +138,8 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Git\n"
 "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n"
-"POT-Creation-Date: 2018-03-16 07:29+0800\n"
-"PO-Revision-Date: 2018-03-25 22:20+0800\n"
+"POT-Creation-Date: 2018-06-16 22:06+0800\n"
+"PO-Revision-Date: 2018-06-18 00:28+0800\n"
 "Last-Translator: Jiang Xin <worldhello.net@gmail.com>\n"
 "Language-Team: GitHub <https://github.com/jiangxin/git/>\n"
 "Language: zh_CN\n"
@@ -148,37 +148,37 @@ msgstr ""
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
 
-#: advice.c:62
+#: advice.c:92
 #, c-format
-msgid "hint: %.*s\n"
-msgstr "提示:%.*s\n"
+msgid "%shint: %.*s%s\n"
+msgstr "%s提示:%.*s%s\n"
 
-#: advice.c:90
+#: advice.c:137
 msgid "Cherry-picking is not possible because you have unmerged files."
 msgstr "无法拣选,因为您有未合并的文件。"
 
-#: advice.c:92
+#: advice.c:139
 msgid "Committing is not possible because you have unmerged files."
 msgstr "无法提交,因为您有未合并的文件。"
 
-#: advice.c:94
+#: advice.c:141
 msgid "Merging is not possible because you have unmerged files."
 msgstr "无法合并,因为您有未合并的文件。"
 
-#: advice.c:96
+#: advice.c:143
 msgid "Pulling is not possible because you have unmerged files."
 msgstr "无法拉取,因为您有未合并的文件。"
 
-#: advice.c:98
+#: advice.c:145
 msgid "Reverting is not possible because you have unmerged files."
 msgstr "无法回退,因为您有未合并的文件。"
 
-#: advice.c:100
+#: advice.c:147
 #, c-format
 msgid "It is not possible to %s because you have unmerged files."
 msgstr "无法 %s,因为您有未合并的文件。"
 
-#: advice.c:108
+#: advice.c:155
 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."
@@ -186,23 +186,23 @@ msgstr ""
 "请在工作区改正文件,然后酌情使用 'git add/rm <文件>' 命令标记\n"
 "解决方案并提交。"
 
-#: advice.c:116
+#: advice.c:163
 msgid "Exiting because of an unresolved conflict."
 msgstr "因为存在未解决的冲突而退出。"
 
-#: advice.c:121 builtin/merge.c:1251
+#: advice.c:168 builtin/merge.c:1250
 msgid "You have not concluded your merge (MERGE_HEAD exists)."
 msgstr "您尚未结束您的合并(存在 MERGE_HEAD)。"
 
-#: advice.c:123
+#: advice.c:170
 msgid "Please, commit your changes before merging."
 msgstr "请在合并前先提交您的修改。"
 
-#: advice.c:124
+#: advice.c:171
 msgid "Exiting because of unfinished merge."
 msgstr "因为存在未完成的合并而退出。"
 
-#: advice.c:130
+#: advice.c:177
 #, c-format
 msgid ""
 "Note: checking out '%s'.\n"
@@ -460,7 +460,7 @@ msgstr "打补丁失败:%s:%ld"
 msgid "cannot checkout %s"
 msgstr "不能检出 %s"
 
-#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:277
+#: apply.c:3396 apply.c:3407 apply.c:3453 setup.c:278
 #, c-format
 msgid "failed to read %s"
 msgstr "无法读取 %s"
@@ -659,7 +659,7 @@ msgstr[1] "应用 %%s 个补丁,其中 %d 个被拒绝..."
 msgid "truncating .rej filename to %.*s.rej"
 msgstr "截短 .rej 文件名为 %.*s.rej"
 
-#: apply.c:4545 builtin/fetch.c:775 builtin/fetch.c:1025
+#: apply.c:4545 builtin/fetch.c:786 builtin/fetch.c:1036
 #, c-format
 msgid "cannot open %s"
 msgstr "不能打开 %s"
@@ -713,15 +713,15 @@ msgid_plural "%d lines applied after fixing whitespace errors."
 msgstr[0] "修复空白错误后,应用了 %d 行。"
 msgstr[1] "修复空白错误后,应用了 %d 行。"
 
-#: apply.c:4894 builtin/add.c:539 builtin/mv.c:298 builtin/rm.c:390
+#: apply.c:4894 builtin/add.c:538 builtin/mv.c:300 builtin/rm.c:389
 msgid "Unable to write new index file"
 msgstr "无法写入新索引文件"
 
 #: apply.c:4921 apply.c:4924 builtin/am.c:2254 builtin/am.c:2257
-#: builtin/clone.c:118 builtin/fetch.c:127 builtin/pull.c:193
-#: builtin/submodule--helper.c:403 builtin/submodule--helper.c:1197
-#: builtin/submodule--helper.c:1200 builtin/submodule--helper.c:1567
-#: builtin/submodule--helper.c:1570 builtin/submodule--helper.c:1787
+#: builtin/clone.c:120 builtin/fetch.c:126 builtin/pull.c:198
+#: builtin/submodule--helper.c:405 builtin/submodule--helper.c:1210
+#: builtin/submodule--helper.c:1213 builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1587 builtin/submodule--helper.c:1807
 #: git-add--interactive.perl:197
 msgid "path"
 msgstr "路径"
@@ -796,7 +796,7 @@ msgstr "确保至少匹配 <n> 行上下文"
 
 #: apply.c:4960 builtin/am.c:2242 builtin/interpret-trailers.c:95
 #: builtin/interpret-trailers.c:97 builtin/interpret-trailers.c:99
-#: builtin/pack-objects.c:3035
+#: builtin/pack-objects.c:3177
 msgid "action"
 msgstr "动作"
 
@@ -824,9 +824,9 @@ msgstr "将拒绝的补丁片段保存在对应的 *.rej 文件中"
 msgid "allow overlapping hunks"
 msgstr "允许重叠的补丁片段"
 
-#: apply.c:4977 builtin/add.c:292 builtin/check-ignore.c:21
-#: builtin/commit.c:1276 builtin/count-objects.c:96 builtin/fsck.c:665
-#: builtin/log.c:1901 builtin/mv.c:123 builtin/read-tree.c:125
+#: apply.c:4977 builtin/add.c:290 builtin/check-ignore.c:21
+#: builtin/commit.c:1301 builtin/count-objects.c:98 builtin/fsck.c:666
+#: builtin/log.c:1901 builtin/mv.c:122 builtin/read-tree.c:124
 msgid "be verbose"
 msgstr "冗长输出"
 
@@ -864,98 +864,98 @@ msgstr ""
 msgid "git archive --remote <repo> [--exec <cmd>] --list"
 msgstr "git archive --remote <仓库> [--exec <命令>] --list"
 
-#: archive.c:351 builtin/add.c:176 builtin/add.c:515 builtin/rm.c:299
+#: archive.c:351 builtin/add.c:176 builtin/add.c:514 builtin/rm.c:298
 #, c-format
 msgid "pathspec '%s' did not match any files"
 msgstr "路径规格 '%s' 未匹配任何文件"
 
-#: archive.c:436
+#: archive.c:434
 msgid "fmt"
 msgstr "格式"
 
-#: archive.c:436
+#: archive.c:434
 msgid "archive format"
 msgstr "归档格式"
 
-#: archive.c:437 builtin/log.c:1462
+#: archive.c:435 builtin/log.c:1462
 msgid "prefix"
 msgstr "前缀"
 
-#: archive.c:438
+#: archive.c:436
 msgid "prepend prefix to each pathname in the archive"
 msgstr "为归档中每个路径名加上前缀"
 
-#: archive.c:439 builtin/blame.c:702 builtin/blame.c:703 builtin/config.c:62
-#: builtin/fast-export.c:1005 builtin/fast-export.c:1007 builtin/grep.c:869
+#: archive.c:437 builtin/blame.c:813 builtin/blame.c:814 builtin/config.c:127
+#: builtin/fast-export.c:1007 builtin/fast-export.c:1009 builtin/grep.c:869
 #: builtin/hash-object.c:103 builtin/ls-files.c:551 builtin/ls-files.c:554
-#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:120
+#: builtin/notes.c:405 builtin/notes.c:568 builtin/read-tree.c:119
 #: parse-options.h:165
 msgid "file"
 msgstr "文件"
 
-#: archive.c:440 builtin/archive.c:89
+#: archive.c:438 builtin/archive.c:89
 msgid "write the archive to this file"
 msgstr "归档写入此文件"
 
-#: archive.c:442
+#: archive.c:440
 msgid "read .gitattributes in working directory"
 msgstr "读取工作区中的 .gitattributes"
 
-#: archive.c:443
+#: archive.c:441
 msgid "report archived files on stderr"
 msgstr "在标准错误上报告归档文件"
 
-#: archive.c:444
+#: archive.c:442
 msgid "store only"
 msgstr "只存储"
 
-#: archive.c:445
+#: archive.c:443
 msgid "compress faster"
 msgstr "压缩速度更快"
 
-#: archive.c:453
+#: archive.c:451
 msgid "compress better"
 msgstr "压缩效果更好"
 
-#: archive.c:456
+#: archive.c:454
 msgid "list supported archive formats"
 msgstr "列出支持的归档格式"
 
-#: archive.c:458 builtin/archive.c:90 builtin/clone.c:108 builtin/clone.c:111
-#: builtin/submodule--helper.c:1209 builtin/submodule--helper.c:1576
+#: archive.c:456 builtin/archive.c:90 builtin/clone.c:110 builtin/clone.c:113
+#: builtin/submodule--helper.c:1222 builtin/submodule--helper.c:1593
 msgid "repo"
 msgstr "仓库"
 
-#: archive.c:459 builtin/archive.c:91
+#: archive.c:457 builtin/archive.c:91
 msgid "retrieve the archive from remote repository <repo>"
 msgstr "从远程仓库(<仓库>)提取归档文件"
 
-#: archive.c:460 builtin/archive.c:92 builtin/notes.c:489
+#: archive.c:458 builtin/archive.c:92 builtin/notes.c:489
 msgid "command"
 msgstr "命令"
 
-#: archive.c:461 builtin/archive.c:93
+#: archive.c:459 builtin/archive.c:93
 msgid "path to the remote git-upload-archive command"
 msgstr "远程 git-upload-archive 命令的路径"
 
-#: archive.c:468
+#: archive.c:466
 msgid "Unexpected option --remote"
 msgstr "未知参数 --remote"
 
-#: archive.c:470
+#: archive.c:468
 msgid "Option --exec can only be used together with --remote"
 msgstr "选项 --exec 只能和 --remote 同时使用"
 
-#: archive.c:472
+#: archive.c:470
 msgid "Unexpected option --output"
 msgstr "未知参数 --output"
 
-#: archive.c:494
+#: archive.c:492
 #, c-format
 msgid "Unknown archive format '%s'"
 msgstr "未知归档格式 '%s'"
 
-#: archive.c:501
+#: archive.c:499
 #, c-format
 msgid "Argument not supported for format '%s': -%d"
 msgstr "参数不支持此格式 '%s':-%d"
@@ -973,22 +973,22 @@ msgstr ""
 "负值模版在 git attributes 中被忽略\n"
 "当字符串确实要以感叹号开始时,使用 '\\!'。"
 
-#: bisect.c:460
+#: bisect.c:461
 #, c-format
 msgid "Badly quoted content in file '%s': %s"
 msgstr "文件 '%s' 包含错误的引用格式:%s"
 
-#: bisect.c:668
+#: bisect.c:669
 #, c-format
 msgid "We cannot bisect more!\n"
 msgstr "我们无法进行更多的二分查找!\n"
 
-#: bisect.c:722
+#: bisect.c:723
 #, c-format
 msgid "Not a valid commit name %s"
 msgstr "不是一个有效的提交名 %s"
 
-#: bisect.c:746
+#: bisect.c:747
 #, c-format
 msgid ""
 "The merge base %s is bad.\n"
@@ -997,7 +997,7 @@ msgstr ""
 "合并基线 %s 是坏的。\n"
 "这意味着介于 %s 和 [%s] 之间的 bug 已经被修复。\n"
 
-#: bisect.c:751
+#: bisect.c:752
 #, c-format
 msgid ""
 "The merge base %s is new.\n"
@@ -1006,7 +1006,7 @@ msgstr ""
 "合并基线 %s 是新的。\n"
 "介于 %s 和 [%s] 之间的属性已经被修改。\n"
 
-#: bisect.c:756
+#: bisect.c:757
 #, c-format
 msgid ""
 "The merge base %s is %s.\n"
@@ -1015,7 +1015,7 @@ msgstr ""
 "合并基线 %s 是 %s。\n"
 "这意味着第一个 '%s' 提交位于 %s 和 [%s] 之间。\n"
 
-#: bisect.c:764
+#: bisect.c:765
 #, c-format
 msgid ""
 "Some %s revs are not ancestors of the %s rev.\n"
@@ -1026,7 +1026,7 @@ msgstr ""
 "这种情况下 git 二分查找无法正常工作。\n"
 "您可能弄错了 %s 和 %s 版本?\n"
 
-#: bisect.c:777
+#: bisect.c:778
 #, c-format
 msgid ""
 "the merge base between %s and [%s] must be skipped.\n"
@@ -1037,36 +1037,36 @@ msgstr ""
 "所以我们无法确认第一个 %s 提交是否介于 %s 和 %s 之间。\n"
 "我们仍旧继续。"
 
-#: bisect.c:810
+#: bisect.c:811
 #, c-format
 msgid "Bisecting: a merge base must be tested\n"
 msgstr "二分查找中:合并基线必须是经过测试的\n"
 
-#: bisect.c:850
+#: bisect.c:851
 #, c-format
 msgid "a %s revision is needed"
 msgstr "需要一个 %s 版本"
 
-#: bisect.c:869 builtin/notes.c:175 builtin/tag.c:235
+#: bisect.c:870 builtin/notes.c:175 builtin/tag.c:236
 #, c-format
 msgid "could not create file '%s'"
 msgstr "不能创建文件 '%s'"
 
-#: bisect.c:920
+#: bisect.c:921
 #, c-format
 msgid "could not read file '%s'"
 msgstr "不能读取文件 '%s'"
 
-#: bisect.c:950
+#: bisect.c:951
 msgid "reading bisect refs failed"
 msgstr "读取二分查找引用失败"
 
-#: bisect.c:969
+#: bisect.c:970
 #, c-format
 msgid "%s was both %s and %s\n"
 msgstr "%s 同时为 %s 和 %s\n"
 
-#: bisect.c:977
+#: bisect.c:978
 #, c-format
 msgid ""
 "No testable commit found.\n"
@@ -1075,7 +1075,7 @@ msgstr ""
 "没有发现可测试的提交。\n"
 "可能您在运行时使用了错误的路径参数?\n"
 
-#: bisect.c:996
+#: bisect.c:997
 #, c-format
 msgid "(roughly %d step)"
 msgid_plural "(roughly %d steps)"
@@ -1085,48 +1085,48 @@ msgstr[1] "(大概 %d 步)"
 #. TRANSLATORS: the last %s will be replaced with "(roughly %d
 #. steps)" translation.
 #.
-#: bisect.c:1002
+#: bisect.c:1003
 #, c-format
 msgid "Bisecting: %d revision left to test after this %s\n"
 msgid_plural "Bisecting: %d revisions left to test after this %s\n"
 msgstr[0] "二分查找中:在此之后,还剩 %d 个版本待测试 %s\n"
 msgstr[1] "二分查找中:在此之后,还剩 %d 个版本待测试 %s\n"
 
-#: blame.c:1758
+#: blame.c:1756
 msgid "--contents and --reverse do not blend well."
 msgstr "--contents 和 --reverse 不能混用。"
 
-#: blame.c:1769
+#: blame.c:1767
 msgid "cannot use --contents with final commit object name"
 msgstr "不能将 --contents 和最终的提交对象名共用"
 
-#: blame.c:1789
+#: blame.c:1787
 msgid "--reverse and --first-parent together require specified latest commit"
 msgstr "--reverse 和 --first-parent 共用,需要指定最新的提交"
 
-#: blame.c:1798 bundle.c:160 ref-filter.c:1978 sequencer.c:1699
-#: sequencer.c:2901 builtin/commit.c:976 builtin/log.c:366 builtin/log.c:920
-#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:370
-#: builtin/shortlog.c:191
+#: blame.c:1796 bundle.c:160 ref-filter.c:2075 sequencer.c:1861
+#: sequencer.c:3632 builtin/commit.c:981 builtin/log.c:366 builtin/log.c:920
+#: builtin/log.c:1371 builtin/log.c:1702 builtin/log.c:1950 builtin/merge.c:372
+#: builtin/shortlog.c:192
 msgid "revision walk setup failed"
 msgstr "版本遍历设置失败"
 
-#: blame.c:1816
+#: blame.c:1814
 msgid ""
 "--reverse --first-parent together require range along first-parent chain"
 msgstr "--reverse 和 --first-parent 共用,需要第一祖先链上的提交范围"
 
-#: blame.c:1827
+#: blame.c:1825
 #, c-format
 msgid "no such path %s in %s"
 msgstr "在 %2$s 中无此路径 %1$s"
 
-#: blame.c:1838
+#: blame.c:1836
 #, c-format
 msgid "cannot read blob %s for path %s"
 msgstr "不能为路径 %2$s 读取数据对象 %1$s"
 
-#: branch.c:53
+#: branch.c:54
 #, c-format
 msgid ""
 "\n"
@@ -1138,85 +1138,85 @@ msgstr ""
 "在修复错误后,您可以尝试修改远程跟踪分支,通过执行命令\n"
 "\"git branch --set-upstream-to=%s%s%s\" 。"
 
-#: branch.c:67
+#: branch.c:68
 #, c-format
 msgid "Not setting branch %s as its own upstream."
 msgstr "未设置分支 %s 作为它自己的上游。"
 
-#: branch.c:93
+#: branch.c:94
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s' by rebasing."
 msgstr "分支 '%1$s' 设置为使用变基来跟踪来自 '%3$s' 的远程分支 '%2$s'。"
 
-#: branch.c:94
+#: branch.c:95
 #, c-format
 msgid "Branch '%s' set up to track remote branch '%s' from '%s'."
 msgstr "分支 '%1$s' 设置为跟踪来自 '%3$s' 的远程分支 '%2$s'。"
 
-#: branch.c:98
+#: branch.c:99
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s' by rebasing."
 msgstr "分支 '%s' 设置为使用变基来跟踪本地分支 '%s'。"
 
-#: branch.c:99
+#: branch.c:100
 #, c-format
 msgid "Branch '%s' set up to track local branch '%s'."
 msgstr "分支 '%s' 设置为跟踪本地分支 '%s'。"
 
-#: branch.c:104
+#: branch.c:105
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s' by rebasing."
 msgstr "分支 '%s' 设置为使用变基来跟踪远程引用 '%s'。"
 
-#: branch.c:105
+#: branch.c:106
 #, c-format
 msgid "Branch '%s' set up to track remote ref '%s'."
 msgstr "分支 '%s' 设置为跟踪远程引用 '%s'。"
 
-#: branch.c:109
+#: branch.c:110
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s' by rebasing."
 msgstr "分支 '%s' 设置为使用变基来跟踪本地引用 '%s'。"
 
-#: branch.c:110
+#: branch.c:111
 #, c-format
 msgid "Branch '%s' set up to track local ref '%s'."
 msgstr "分支 '%s' 设置为跟踪本地引用 '%s'。"
 
-#: branch.c:119
+#: branch.c:120
 msgid "Unable to write upstream branch configuration"
 msgstr "无法写入上游分支配置"
 
-#: branch.c:156
+#: branch.c:157
 #, c-format
 msgid "Not tracking: ambiguous information for ref %s"
 msgstr "未跟踪:引用 %s 有歧义"
 
-#: branch.c:189
+#: branch.c:190
 #, c-format
 msgid "'%s' is not a valid branch name."
 msgstr "'%s' 不是一个有效的分支名称。"
 
-#: branch.c:208
+#: branch.c:209
 #, c-format
 msgid "A branch named '%s' already exists."
 msgstr "一个分支名 '%s' 已经存在。"
 
-#: branch.c:213
+#: branch.c:214
 msgid "Cannot force update the current branch."
 msgstr "无法强制更新当前分支。"
 
-#: branch.c:233
+#: branch.c:234
 #, c-format
 msgid "Cannot setup tracking information; starting point '%s' is not a branch."
 msgstr "无法设置跟踪信息;起始点 '%s' 不是一个分支。"
 
-#: branch.c:235
+#: branch.c:236
 #, c-format
 msgid "the requested upstream branch '%s' does not exist"
 msgstr "请求的上游分支 '%s' 不存在"
 
-#: branch.c:237
+#: branch.c:238
 msgid ""
 "\n"
 "If you are planning on basing your work on an upstream\n"
@@ -1234,27 +1234,27 @@ msgstr ""
 "如果您正计划推送一个能与对应远程分支建立跟踪的新的本地分支,\n"
 "您可能需要使用 \"git push -u\" 推送分支并配置和上游的关联。"
 
-#: branch.c:280
+#: branch.c:281
 #, c-format
 msgid "Not a valid object name: '%s'."
 msgstr "不是一个有效的对象名:'%s'。"
 
-#: branch.c:300
+#: branch.c:301
 #, c-format
 msgid "Ambiguous object name: '%s'."
 msgstr "歧义的对象名:'%s'。"
 
-#: branch.c:305
+#: branch.c:306
 #, c-format
 msgid "Not a valid branch point: '%s'."
 msgstr "无效的分支点:'%s'。"
 
-#: branch.c:359
+#: branch.c:360
 #, c-format
 msgid "'%s' is already checked out at '%s'"
 msgstr "'%s' 已经检出到 '%s'"
 
-#: branch.c:382
+#: branch.c:383
 #, c-format
 msgid "HEAD of working tree %s is not updated"
 msgstr "工作区 %s 的 HEAD 指向没有被更新"
@@ -1269,7 +1269,7 @@ msgstr "'%s' 不像是一个 v2 版本的包文件"
 msgid "unrecognized header: %s%s (%d)"
 msgstr "未能识别的包头:%s%s (%d)"
 
-#: bundle.c:88 sequencer.c:1879 sequencer.c:2337 builtin/commit.c:750
+#: bundle.c:88 sequencer.c:2081 sequencer.c:2558 builtin/commit.c:755
 #, c-format
 msgid "could not open '%s'"
 msgstr "不能打开 '%s'"
@@ -1313,7 +1313,7 @@ msgstr "rev-list 终止"
 msgid "ref '%s' is excluded by the rev-list options"
 msgstr "引用 '%s' 被 rev-list 选项排除"
 
-#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:296
+#: bundle.c:450 builtin/log.c:183 builtin/log.c:1607 builtin/shortlog.c:303
 #, c-format
 msgid "unrecognized argument: %s"
 msgstr "未能识别的参数:%s"
@@ -1336,18 +1336,39 @@ msgstr "index-pack 终止"
 msgid "invalid color value: %.*s"
 msgstr "无效的颜色值:%.*s"
 
-#: commit.c:41 sequencer.c:2141 builtin/am.c:421 builtin/am.c:465
-#: builtin/am.c:1436 builtin/am.c:2072
+#: commit.c:43 sequencer.c:2364 builtin/am.c:421 builtin/am.c:465
+#: builtin/am.c:1436 builtin/am.c:2072 builtin/replace.c:376
+#: builtin/replace.c:448
 #, c-format
 msgid "could not parse %s"
 msgstr "不能解析 %s"
 
-#: commit.c:43
+#: commit.c:45
 #, c-format
 msgid "%s %s is not a commit!"
 msgstr "%s %s 不是一个提交!"
 
-#: commit.c:1506
+#: commit.c:182
+msgid ""
+"Support for <GIT_DIR>/info/grafts is deprecated\n"
+"and will be removed in a future Git version.\n"
+"\n"
+"Please use \"git replace --convert-graft-file\"\n"
+"to convert the grafts into replace refs.\n"
+"\n"
+"Turn this message off by running\n"
+"\"git config advice.graftFileDeprecated false\""
+msgstr ""
+"对 <GIT_DIR>/info/grafts 的支持已被弃用,并将在\n"
+"未来的Git版本中被移除。\n"
+"\n"
+"请使用 \"git replace --convert-graft-file\" 将\n"
+"grafts 转换为替换引用。\n"
+"\n"
+"设置 \"git config advice.graftFileDeprecated false\"\n"
+"可关闭本消息"
+
+#: commit.c:1540
 msgid ""
 "Warning: commit message did not conform to UTF-8.\n"
 "You may want to amend it after fixing the message, or set the config\n"
@@ -1357,170 +1378,184 @@ msgstr ""
 "您可以通过修补提交来改正提交说明,或者将配置变量 i18n.commitencoding\n"
 "设置为您项目所用的字符编码。\n"
 
+#: commit-graph.c:669
+#, c-format
+msgid "the commit graph format cannot write %d commits"
+msgstr "提交图形格式不能写入 %d 个提交"
+
+#: commit-graph.c:696
+msgid "too many commits to write graph"
+msgstr "提交太多不能画图"
+
+#: commit-graph.c:707 builtin/init-db.c:516 builtin/init-db.c:521
+#, c-format
+msgid "cannot mkdir %s"
+msgstr "不能创建目录 %s"
+
 #: compat/obstack.c:405 compat/obstack.c:407
 msgid "memory exhausted"
 msgstr "内存耗尽"
 
-#: config.c:186
+#: config.c:187
 msgid "relative config include conditionals must come from files"
 msgstr "包含相对路径的条件引用必须来自于文件"
 
-#: config.c:720
+#: config.c:788
 #, c-format
 msgid "bad config line %d in blob %s"
 msgstr "数据对象 %2$s 中错误的配置行 %1$d"
 
-#: config.c:724
+#: config.c:792
 #, c-format
 msgid "bad config line %d in file %s"
 msgstr "文件 %2$s 中错误的配置行 %1$d"
 
-#: config.c:728
+#: config.c:796
 #, c-format
 msgid "bad config line %d in standard input"
 msgstr "标准输入中错误的配置行 %d"
 
-#: config.c:732
+#: config.c:800
 #, c-format
 msgid "bad config line %d in submodule-blob %s"
 msgstr "子模组数据对象 %2$s 中错误的配置行 %1$d"
 
-#: config.c:736
+#: config.c:804
 #, c-format
 msgid "bad config line %d in command line %s"
 msgstr "命令行 %2$s 中错误的配置行 %1$d"
 
-#: config.c:740
+#: config.c:808
 #, c-format
 msgid "bad config line %d in %s"
 msgstr "在 %2$s 中错误的配置行 %1$d"
 
-#: config.c:868
+#: config.c:936
 msgid "out of range"
 msgstr "超出范围"
 
-#: config.c:868
+#: config.c:936
 msgid "invalid unit"
 msgstr "无效的单位"
 
-#: config.c:874
+#: config.c:942
 #, c-format
 msgid "bad numeric config value '%s' for '%s': %s"
 msgstr "配置变量 '%2$s' 的数字取值 '%1$s' 设置错误:%3$s"
 
-#: config.c:879
+#: config.c:947
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in blob %s: %s"
 msgstr "数据对象 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s':%4$s"
 
-#: config.c:882
+#: config.c:950
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in file %s: %s"
 msgstr "文件 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s':%4$s"
 
-#: config.c:885
+#: config.c:953
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in standard input: %s"
 msgstr "标准输入中配置变量 '%2$s' 错误的取值 '%1$s':%3$s"
 
-#: config.c:888
+#: config.c:956
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s"
 msgstr "子模组数据 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s':%4$s"
 
-#: config.c:891
+#: config.c:959
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in command line %s: %s"
 msgstr "命令行 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s':%4$s"
 
-#: config.c:894
+#: config.c:962
 #, c-format
 msgid "bad numeric config value '%s' for '%s' in %s: %s"
 msgstr "在 %3$s 中配置变量 '%2$s' 错误的取值 '%1$s':%4$s"
 
-#: config.c:989
+#: config.c:1057
 #, c-format
 msgid "failed to expand user dir in: '%s'"
 msgstr "无法扩展 '%s' 中的用户目录"
 
-#: config.c:998
+#: config.c:1066
 #, c-format
 msgid "'%s' for '%s' is not a valid timestamp"
 msgstr "'%2$s' 的值 '%1$s' 不是一个有效的时间戳"
 
-#: config.c:1094 config.c:1105
+#: config.c:1171 config.c:1182
 #, c-format
 msgid "bad zlib compression level %d"
 msgstr "错误的 zlib 压缩级别 %d"
 
-#: config.c:1225
+#: config.c:1307
 #, c-format
 msgid "invalid mode for object creation: %s"
 msgstr "无效的对象创建模式:%s"
 
-#: config.c:1386
+#: config.c:1473
 #, c-format
 msgid "bad pack compression level %d"
 msgstr "错误的打包压缩级别 %d"
 
-#: config.c:1582
+#: config.c:1681
 msgid "unable to parse command-line config"
 msgstr "无法解析命令行中的配置"
 
-#: config.c:1914
+#: config.c:2013
 msgid "unknown error occurred while reading the configuration files"
 msgstr "在读取配置文件时遇到未知错误"
 
-#: config.c:2101
+#: config.c:2200
 #, c-format
 msgid "Invalid %s: '%s'"
 msgstr "无效 %s:'%s'"
 
-#: config.c:2144
+#: config.c:2243
 #, c-format
 msgid "unknown core.untrackedCache value '%s'; using 'keep' default value"
 msgstr "未知的 core.untrackedCache 取值 '%s',使用默认值 'keep'"
 
-#: config.c:2170
+#: config.c:2269
 #, c-format
 msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100"
 msgstr "splitIndex.maxPercentChange 的取值 '%d' 应该介于 0 和 100 之间"
 
-#: config.c:2195
+#: config.c:2294
 #, c-format
 msgid "unable to parse '%s' from command-line config"
 msgstr "无法解析命令行配置中的 '%s'"
 
-#: config.c:2197
+#: config.c:2296
 #, c-format
 msgid "bad config variable '%s' in file '%s' at line %d"
 msgstr "在文件 '%2$s' 的第 %3$d 行发现错误的配置变量 '%1$s'"
 
-#: config.c:2256
+#: config.c:2402
 #, c-format
 msgid "%s has multiple values"
 msgstr "%s 有多个取值"
 
-#: config.c:2599 config.c:2816
+#: config.c:2766 config.c:3019
 #, c-format
 msgid "fstat on %s failed"
 msgstr "对 %s 调用 fstat 失败"
 
-#: config.c:2706
+#: config.c:2905
 #, c-format
 msgid "could not set '%s' to '%s'"
 msgstr "不能设置 '%s' 为 '%s'"
 
-#: config.c:2708 builtin/remote.c:776
+#: config.c:2907 builtin/remote.c:779
 #, c-format
 msgid "could not unset '%s'"
 msgstr "不能取消设置 '%s'"
 
-#: connect.c:52
+#: connect.c:61
 msgid "The remote end hung up upon initial contact"
 msgstr "远端在连接发起时即挂断"
 
-#: connect.c:54
+#: connect.c:63
 msgid ""
 "Could not read from remote repository.\n"
 "\n"
@@ -1531,7 +1566,7 @@ msgstr ""
 "\n"
 "请确认您有正确的访问权限并且仓库存在。"
 
-#: connected.c:66 builtin/fsck.c:198 builtin/prune.c:144
+#: connected.c:66 builtin/fsck.c:201 builtin/prune.c:145
 msgid "Checking connectivity"
 msgstr "检查连接中"
 
@@ -1547,12 +1582,12 @@ msgstr "无法写入 rev-list"
 msgid "failed to close rev-list's stdin"
 msgstr "无法关闭 rev-list 的标准输入"
 
-#: convert.c:205
+#: convert.c:206
 #, c-format
 msgid "CRLF would be replaced by LF in %s."
 msgstr "文件 %s 中的 CRLF 将被 LF 替换。"
 
-#: convert.c:207
+#: convert.c:208
 #, c-format
 msgid ""
 "CRLF will be replaced by LF in %s.\n"
@@ -1561,12 +1596,12 @@ msgstr ""
 "文件 %s 中的 CRLF 将被 LF 替换。\n"
 "在工作区中该文件仍保持原有的换行符。"
 
-#: convert.c:215
+#: convert.c:216
 #, c-format
 msgid "LF would be replaced by CRLF in %s"
 msgstr "文件 %s 中的 LF 将被 CRLF 替换"
 
-#: convert.c:217
+#: convert.c:218
 #, c-format
 msgid ""
 "LF will be replaced by CRLF in %s.\n"
@@ -1575,6 +1610,46 @@ msgstr ""
 "文件 %s 中的 LF 将被 CRLF 替换。\n"
 "在工作区中该文件仍保持原有的换行符。"
 
+#: convert.c:279
+#, c-format
+msgid "BOM is prohibited in '%s' if encoded as %s"
+msgstr "如果使用 %2$s 编码,禁止在 '%1$s' 中使用 BOM"
+
+#: convert.c:286
+#, c-format
+msgid ""
+"The file '%s' contains a byte order mark (BOM). Please use UTF-%s as working-"
+"tree-encoding."
+msgstr "文件 '%s' 包含一个字节顺序标记(BOM)。请使用 UTF-%s 作为工作区编码。"
+
+#: convert.c:304
+#, c-format
+msgid "BOM is required in '%s' if encoded as %s"
+msgstr "如果编码为 %2$s,需要在 '%1$s' 中使用 BOM"
+
+#: convert.c:306
+#, 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 ""
+"文件 '%s' 缺失一个字节顺序标记(BOM)。请使用 UTF-%sBE or UTF-%sLE(取决于字"
+"节序)作为工作区编码。"
+
+#: convert.c:424
+#, c-format
+msgid "failed to encode '%s' from %s to %s"
+msgstr "无法对 '%s' 进行从 %s 到 %s 的编码"
+
+#: convert.c:467
+#, c-format
+msgid "encoding '%s' from %s to %s and back is not the same"
+msgstr "将'%s' 的编码从 %s 到 %s 来回转换不一致"
+
+#: convert.c:1225
+msgid "true/false are no valid working-tree-encodings"
+msgstr "true/false 不是有效的工作区编码"
+
 #: date.c:116
 msgid "in the future"
 msgstr "在将来"
@@ -1690,24 +1765,24 @@ msgstr ""
 "发现配置变量 'diff.dirstat' 中的错误:\n"
 "%s"
 
-#: diff.c:3822
+#: diff.c:3823
 #, c-format
 msgid "external diff died, stopping at %s"
 msgstr "外部 diff 退出,停止在 %s"
 
-#: diff.c:4146
+#: diff.c:4153
 msgid "--name-only, --name-status, --check and -s are mutually exclusive"
 msgstr "--name-only、--name-status、--check 和 -s 是互斥的"
 
-#: diff.c:4149
+#: diff.c:4156
 msgid "-G, -S and --find-object are mutually exclusive"
 msgstr "-G、-S 和 --find-object 是互斥的"
 
-#: diff.c:4237
+#: diff.c:4244
 msgid "--follow requires exactly one pathspec"
 msgstr "--follow 明确要求只跟一个路径规格"
 
-#: diff.c:4403
+#: diff.c:4410
 #, c-format
 msgid ""
 "Failed to parse --dirstat/-X option parameter:\n"
@@ -1716,44 +1791,44 @@ msgstr ""
 "无法解析 --dirstat/-X 选项的参数:\n"
 "%s"
 
-#: diff.c:4417
+#: diff.c:4424
 #, c-format
 msgid "Failed to parse --submodule option parameter: '%s'"
 msgstr "无法解析 --submodule 选项的参数:'%s'"
 
-#: diff.c:5493
+#: diff.c:5500
 msgid "inexact rename detection was skipped due to too many files."
 msgstr "因为文件太多,略过不严格的重命名检查。"
 
-#: diff.c:5496
+#: diff.c:5503
 msgid "only found copies from modified paths due to too many files."
 msgstr "因为文件太多,只在修改的路径中查找拷贝。"
 
-#: diff.c:5499
+#: diff.c:5506
 #, c-format
 msgid ""
 "you may want to set your %s variable to at least %d and retry the command."
 msgstr "您可能想要将变量 %s 设置为至少 %d 并再次执行此命令。"
 
-#: dir.c:1866
+#: dir.c:1867
 #, c-format
 msgid "could not open directory '%s'"
 msgstr "不能打开目录 '%s'"
 
-#: dir.c:2108
+#: dir.c:2109
 msgid "failed to get kernel name and information"
 msgstr "无法获得内核名称和信息"
 
-#: dir.c:2232
+#: dir.c:2233
 msgid "Untracked cache is disabled on this system or location."
 msgstr "缓存未跟踪文件在本系统或位置中被禁用。"
 
-#: dir.c:3024 dir.c:3029
+#: dir.c:3075 dir.c:3080
 #, c-format
 msgid "could not create directories for %s"
 msgstr "不能为 %s 创建目录"
 
-#: dir.c:3054
+#: dir.c:3109
 #, c-format
 msgid "could not migrate git directory from '%s' to '%s'"
 msgstr "不能从 '%s' 迁移 git 目录到 '%s'"
@@ -1776,201 +1851,205 @@ msgstr "不能对文件 '%s' 调用 stat"
 msgid "Remote with no URL"
 msgstr "远程未设置 URL"
 
-#: fetch-pack.c:253
+#: fetch-pack.c:254
 msgid "git fetch-pack: expected shallow list"
 msgstr "git fetch-pack:应为 shallow 列表"
 
-#: fetch-pack.c:265
+#: fetch-pack.c:266
 msgid "git fetch-pack: expected ACK/NAK, got a flush packet"
 msgstr "git fetch-pack:期望 ACK/NAK,却得到 flush 包"
 
-#: fetch-pack.c:284 builtin/archive.c:63
+#: fetch-pack.c:285 builtin/archive.c:63
 #, c-format
 msgid "remote error: %s"
 msgstr "远程错误:%s"
 
-#: fetch-pack.c:285
+#: fetch-pack.c:286
 #, c-format
 msgid "git fetch-pack: expected ACK/NAK, got '%s'"
 msgstr "git fetch-pack:应为 ACK/NAK,却得到 '%s'"
 
-#: fetch-pack.c:337
+#: fetch-pack.c:338
 msgid "--stateless-rpc requires multi_ack_detailed"
 msgstr "--stateless-rpc 需要 multi_ack_detailed"
 
-#: fetch-pack.c:428
+#: fetch-pack.c:429 fetch-pack.c:1310
 #, c-format
 msgid "invalid shallow line: %s"
 msgstr "无效的 shallow 信息:%s"
 
-#: fetch-pack.c:434
+#: fetch-pack.c:435 fetch-pack.c:1316
 #, c-format
 msgid "invalid unshallow line: %s"
 msgstr "无效的 unshallow 信息:%s"
 
-#: fetch-pack.c:436
+#: fetch-pack.c:437 fetch-pack.c:1318
 #, c-format
 msgid "object not found: %s"
 msgstr "对象未找到:%s"
 
-#: fetch-pack.c:439
+#: fetch-pack.c:440 fetch-pack.c:1321
 #, c-format
 msgid "error in object: %s"
 msgstr "对象中出错:%s"
 
-#: fetch-pack.c:441
+#: fetch-pack.c:442 fetch-pack.c:1323
 #, c-format
 msgid "no shallow found: %s"
 msgstr "未发现 shallow:%s"
 
-#: fetch-pack.c:444
+#: fetch-pack.c:445 fetch-pack.c:1326
 #, c-format
 msgid "expected shallow/unshallow, got %s"
 msgstr "应为 shallow/unshallow,却得到 %s"
 
-#: fetch-pack.c:485
+#: fetch-pack.c:486
 #, c-format
 msgid "got %s %d %s"
 msgstr "得到 %s %d %s"
 
-#: fetch-pack.c:499
+#: fetch-pack.c:500
 #, c-format
 msgid "invalid commit %s"
 msgstr "无效提交 %s"
 
-#: fetch-pack.c:532
+#: fetch-pack.c:533
 msgid "giving up"
 msgstr "放弃"
 
-#: fetch-pack.c:542 progress.c:229
+#: fetch-pack.c:543 progress.c:229
 msgid "done"
 msgstr "完成"
 
-#: fetch-pack.c:554
+#: fetch-pack.c:555
 #, c-format
 msgid "got %s (%d) %s"
 msgstr "得到 %s (%d) %s"
 
-#: fetch-pack.c:600
+#: fetch-pack.c:601
 #, c-format
 msgid "Marking %s as complete"
 msgstr "标记 %s 为完成"
 
-#: fetch-pack.c:788
+#: fetch-pack.c:828
 #, c-format
 msgid "already have %s (%s)"
 msgstr "已经有 %s(%s)"
 
-#: fetch-pack.c:829
+#: fetch-pack.c:869
 msgid "fetch-pack: unable to fork off sideband demultiplexer"
 msgstr "fetch-pack:无法派生 sideband 多路输出"
 
-#: fetch-pack.c:837
+#: fetch-pack.c:877
 msgid "protocol error: bad pack header"
 msgstr "协议错误:坏的包头"
 
-#: fetch-pack.c:895
+#: fetch-pack.c:944
 #, c-format
 msgid "fetch-pack: unable to fork off %s"
 msgstr "fetch-pack:无法派生进程 %s"
 
-#: fetch-pack.c:911
+#: fetch-pack.c:960
 #, c-format
 msgid "%s failed"
 msgstr "%s 失败"
 
-#: fetch-pack.c:913
+#: fetch-pack.c:962
 msgid "error in sideband demultiplexer"
 msgstr "sideband 多路输出出错"
 
-#: fetch-pack.c:940
+#: fetch-pack.c:989
 msgid "Server does not support shallow clients"
 msgstr "服务器不支持 shalllow 客户端"
 
-#: fetch-pack.c:944
+#: fetch-pack.c:993
 msgid "Server supports multi_ack_detailed"
 msgstr "服务器支持 multi_ack_detailed"
 
-#: fetch-pack.c:947
+#: fetch-pack.c:996
 msgid "Server supports no-done"
 msgstr "服务器支持 no-done"
 
-#: fetch-pack.c:953
+#: fetch-pack.c:1002
 msgid "Server supports multi_ack"
 msgstr "服务器支持 multi_ack"
 
-#: fetch-pack.c:957
+#: fetch-pack.c:1006
 msgid "Server supports side-band-64k"
 msgstr "服务器支持 side-band-64k"
 
-#: fetch-pack.c:961
+#: fetch-pack.c:1010
 msgid "Server supports side-band"
 msgstr "服务器支持 side-band"
 
-#: fetch-pack.c:965
+#: fetch-pack.c:1014
 msgid "Server supports allow-tip-sha1-in-want"
 msgstr "服务器支持 allow-tip-sha1-in-want"
 
-#: fetch-pack.c:969
+#: fetch-pack.c:1018
 msgid "Server supports allow-reachable-sha1-in-want"
 msgstr "服务器支持 allow-reachable-sha1-in-want"
 
-#: fetch-pack.c:979
+#: fetch-pack.c:1028
 msgid "Server supports ofs-delta"
 msgstr "服务器支持 ofs-delta"
 
-#: fetch-pack.c:985
+#: fetch-pack.c:1034 fetch-pack.c:1204
 msgid "Server supports filter"
 msgstr "服务器支持 filter"
 
-#: fetch-pack.c:993
+#: fetch-pack.c:1042
 #, c-format
 msgid "Server version is %.*s"
 msgstr "服务器版本 %.*s"
 
-#: fetch-pack.c:999
+#: fetch-pack.c:1048
 msgid "Server does not support --shallow-since"
 msgstr "服务器不支持 --shallow-since"
 
-#: fetch-pack.c:1003
+#: fetch-pack.c:1052
 msgid "Server does not support --shallow-exclude"
 msgstr "服务器不支持 --shallow-exclude"
 
-#: fetch-pack.c:1005
+#: fetch-pack.c:1054
 msgid "Server does not support --deepen"
 msgstr "服务器不支持 --deepen"
 
-#: fetch-pack.c:1016
+#: fetch-pack.c:1065
 msgid "no common commits"
 msgstr "没有共同的提交"
 
-#: fetch-pack.c:1028
+#: fetch-pack.c:1077 fetch-pack.c:1414
 msgid "git fetch-pack: fetch failed."
 msgstr "git fetch-pack:获取失败。"
 
-#: fetch-pack.c:1190
+#: fetch-pack.c:1199
+msgid "Server does not support shallow requests"
+msgstr "服务器不支持 shalllow 请求"
+
+#: fetch-pack.c:1584
 msgid "no matching remote head"
 msgstr "没有匹配的远程分支"
 
-#: fetch-pack.c:1212
+#: fetch-pack.c:1610
 #, c-format
 msgid "no such remote ref %s"
 msgstr "没有这样的远程引用 %s"
 
-#: fetch-pack.c:1215
+#: fetch-pack.c:1613
 #, c-format
 msgid "Server does not allow request for unadvertised object %s"
 msgstr "服务器不允许请求未公开的对象 %s"
 
-#: gpg-interface.c:181
+#: gpg-interface.c:185
 msgid "gpg failed to sign the data"
 msgstr "gpg 无法为数据签名"
 
-#: gpg-interface.c:211
+#: gpg-interface.c:210
 msgid "could not create temporary file"
 msgstr "不能创建临时文件"
 
-#: gpg-interface.c:214
+#: gpg-interface.c:213
 #, c-format
 msgid "failed writing detached signature to '%s'"
 msgstr "无法将分离式签名写入 '%s'"
@@ -1980,36 +2059,97 @@ msgstr "无法将分离式签名写入 '%s'"
 msgid "ignore invalid color '%.*s' in log.graphColors"
 msgstr "忽略 log.graphColors 中无效的颜色 '%.*s'"
 
-#: grep.c:2022
+#: grep.c:2020
 #, c-format
 msgid "'%s': unable to read %s"
 msgstr "'%s':无法读取 %s"
 
-#: grep.c:2039 setup.c:163 builtin/clone.c:407 builtin/diff.c:81
+#: grep.c:2037 setup.c:164 builtin/clone.c:409 builtin/diff.c:81
 #: builtin/rm.c:134
 #, c-format
 msgid "failed to stat '%s'"
 msgstr "对 '%s' 调用 stat 失败"
 
-#: grep.c:2050
+#: grep.c:2048
 #, c-format
 msgid "'%s': short read"
 msgstr "'%s':读取不完整"
 
-#: help.c:179
+#: help.c:23
+msgid "start a working area (see also: git help tutorial)"
+msgstr "开始一个工作区(参见:git help tutorial)"
+
+#: help.c:24
+msgid "work on the current change (see also: git help everyday)"
+msgstr "在当前变更上工作(参见:git help everyday)"
+
+#: help.c:25
+msgid "examine the history and state (see also: git help revisions)"
+msgstr "检查历史和状态(参见:git help revisions)"
+
+#: help.c:26
+msgid "grow, mark and tweak your common history"
+msgstr "扩展、标记和调校您的历史记录"
+
+#: help.c:27
+msgid "collaborate (see also: git help workflows)"
+msgstr "协同(参见:git help workflows)"
+
+#: help.c:31
+msgid "Main Porcelain Commands"
+msgstr "主要的上层命令"
+
+#: help.c:32
+msgid "Ancillary Commands / Manipulators"
+msgstr "辅助命令/操作者"
+
+#: help.c:33
+msgid "Ancillary Commands / Interrogators"
+msgstr "辅助命令/询问者"
+
+#: help.c:34
+msgid "Interacting with Others"
+msgstr "与其它系统交互"
+
+#: help.c:35
+msgid "Low-level Commands / Manipulators"
+msgstr "低级命令/操作者"
+
+#: help.c:36
+msgid "Low-level Commands / Interrogators"
+msgstr "低级命令/询问者"
+
+#: help.c:37
+msgid "Low-level Commands / Synching Repositories"
+msgstr "低级命令/同步仓库"
+
+#: help.c:38
+msgid "Low-level Commands / Internal Helpers"
+msgstr "低级命令/内部助手"
+
+#: help.c:293
 #, c-format
 msgid "available git commands in '%s'"
 msgstr "在 '%s' 下可用的 git 命令"
 
-#: help.c:186
+#: help.c:300
 msgid "git commands available from elsewhere on your $PATH"
 msgstr "在 $PATH 路径中的其他地方可用的 git 命令"
 
-#: help.c:217
+#: help.c:309
 msgid "These are common Git commands used in various situations:"
 msgstr "这些是各种场合常见的 Git 命令:"
 
-#: help.c:281
+#: help.c:358 git.c:90
+#, c-format
+msgid "unsupported command listing type '%s'"
+msgstr "不支持的命令列表类型 '%s'"
+
+#: help.c:405
+msgid "The common Git guides are:"
+msgstr "最常用的 Git 向导有:"
+
+#: help.c:467
 #, c-format
 msgid ""
 "'%s' appears to be a git command, but we were not\n"
@@ -2018,31 +2158,31 @@ msgstr ""
 "'%s' 像是一个 git 命令,但却无法运行。\n"
 "可能是 git-%s 受损?"
 
-#: help.c:336
+#: help.c:526
 msgid "Uh oh. Your system reports no Git commands at all."
 msgstr "唉呀,您的系统中未发现 Git 命令。"
 
-#: help.c:358
+#: help.c:548
 #, c-format
 msgid "WARNING: You called a Git command named '%s', which does not exist."
 msgstr "警告:您运行了一个并不存在的 Git 命令 '%s'。"
 
-#: help.c:363
+#: help.c:553
 #, c-format
 msgid "Continuing under the assumption that you meant '%s'."
 msgstr "假定你想要的是 '%s' 并继续。"
 
-#: help.c:368
+#: help.c:558
 #, c-format
 msgid "Continuing in %0.1f seconds, assuming that you meant '%s'."
 msgstr "假定你想要的是 '%2$s',在 %1$0.1f 秒钟后继续。"
 
-#: help.c:376
+#: help.c:566
 #, c-format
 msgid "git: '%s' is not a git command. See 'git --help'."
 msgstr "git:'%s' 不是一个 git 命令。参见 'git --help'。"
 
-#: help.c:380
+#: help.c:570
 msgid ""
 "\n"
 "The most similar command is"
@@ -2056,16 +2196,16 @@ msgstr[1] ""
 "\n"
 "最相似的命令是"
 
-#: help.c:395
+#: help.c:585
 msgid "git version [<options>]"
 msgstr "git version [<选项>]"
 
-#: help.c:462
+#: help.c:652
 #, c-format
 msgid "%s: %s - %s"
 msgstr "%s:%s - %s"
 
-#: help.c:466
+#: help.c:656
 msgid ""
 "\n"
 "Did you mean this?"
@@ -2132,7 +2272,7 @@ msgstr "不允许空的姓名(对于 <%s>)"
 msgid "name consists only of disallowed characters: %s"
 msgstr "姓名中仅包含禁用字符:%s"
 
-#: ident.c:416 builtin/commit.c:582
+#: ident.c:416 builtin/commit.c:587
 #, c-format
 msgid "invalid date format: %s"
 msgstr "无效的日期格式:%s"
@@ -2168,82 +2308,157 @@ msgstr ""
 msgid "Unable to create '%s.lock': %s"
 msgstr "不能创建 '%s.lock':%s"
 
-#: merge.c:74
+#: merge.c:71
 msgid "failed to read the cache"
 msgstr "无法读取缓存"
 
-#: merge.c:134 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
-#: builtin/checkout.c:599 builtin/clone.c:759
+#: merge.c:136 builtin/am.c:1946 builtin/am.c:1980 builtin/checkout.c:378
+#: builtin/checkout.c:606 builtin/clone.c:761
 msgid "unable to write new index file"
 msgstr "无法写新的索引文件"
 
-#: merge-recursive.c:235
+#: merge-recursive.c:298
 msgid "(bad commit)\n"
 msgstr "(坏提交)\n"
 
-#: merge-recursive.c:257 merge-recursive.c:265
+#: merge-recursive.c:320
 #, c-format
-msgid "addinfo_cache failed for path '%s'"
-msgstr "为路径 '%s' addinfo_cache 失败"
+msgid "add_cacheinfo failed for path '%s'; merge aborting."
+msgstr "addinfo_cache 对路径 '%s' 执行失败,合并终止。"
 
-#: merge-recursive.c:329
+#: merge-recursive.c:328
+#, c-format
+msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting."
+msgstr "addinfo_cache 无法刷新路径 '%s',合并终止。"
+
+#: merge-recursive.c:410
 msgid "error building trees"
 msgstr "无法创建树"
 
-#: merge-recursive.c:771
+#: merge-recursive.c:881
 #, c-format
 msgid "failed to create path '%s'%s"
 msgstr "无法创建路径 '%s'%s"
 
-#: merge-recursive.c:782
+#: merge-recursive.c:892
 #, c-format
 msgid "Removing %s to make room for subdirectory\n"
 msgstr "删除 %s 以便为子目录留出空间\n"
 
-#: merge-recursive.c:796 merge-recursive.c:815
+#: merge-recursive.c:906 merge-recursive.c:925
 msgid ": perhaps a D/F conflict?"
 msgstr ":可能是一个目录/文件冲突?"
 
-#: merge-recursive.c:805
+#: merge-recursive.c:915
 #, c-format
 msgid "refusing to lose untracked file at '%s'"
 msgstr "拒绝丢弃 '%s' 中的未跟踪文件"
 
-#: merge-recursive.c:847 builtin/cat-file.c:37
+#: merge-recursive.c:957 builtin/cat-file.c:37
 #, c-format
 msgid "cannot read object %s '%s'"
 msgstr "不能读取对象 %s '%s'"
 
-#: merge-recursive.c:849
+#: merge-recursive.c:959
 #, c-format
 msgid "blob expected for %s '%s'"
 msgstr "%s '%s' 应为数据对象"
 
-#: merge-recursive.c:873
+#: merge-recursive.c:983
 #, c-format
 msgid "failed to open '%s': %s"
 msgstr "无法打开 '%s':%s"
 
-#: merge-recursive.c:884
+#: merge-recursive.c:994
 #, c-format
 msgid "failed to symlink '%s': %s"
 msgstr "无法创建符号链接 '%s':%s"
 
-#: merge-recursive.c:889
+#: merge-recursive.c:999
 #, c-format
 msgid "do not know what to do with %06o %s '%s'"
 msgstr "不知道如何处理 %06o %s '%s'"
 
-#: merge-recursive.c:1029
+#: merge-recursive.c:1186
+#, c-format
+msgid "Failed to merge submodule %s (not checked out)"
+msgstr "无法合并子模组 %s (没有检出)"
+
+#: merge-recursive.c:1193
+#, c-format
+msgid "Failed to merge submodule %s (commits not present)"
+msgstr "无法合并子模组 %s(提交不存在)"
+
+#: merge-recursive.c:1200
+#, c-format
+msgid "Failed to merge submodule %s (commits don't follow merge-base)"
+msgstr "无法合并子模组 %s (提交未跟随合并基线)"
+
+#: merge-recursive.c:1208 merge-recursive.c:1220
+#, c-format
+msgid "Fast-forwarding submodule %s to the following commit:"
+msgstr "子模组 %s 快进到如下提交:"
+
+#: merge-recursive.c:1211 merge-recursive.c:1223
+#, c-format
+msgid "Fast-forwarding submodule %s"
+msgstr "快进子模组 %s"
+
+#: merge-recursive.c:1245
+#, c-format
+msgid "Failed to merge submodule %s (merge following commits not found)"
+msgstr "无法合并子模组 %s (没发现合并跟随的提交)"
+
+#: merge-recursive.c:1249
+#, c-format
+msgid "Failed to merge submodule %s (not fast-forward)"
+msgstr "无法合并子模组 %s(非快进)"
+
+#: merge-recursive.c:1250
+msgid "Found a possible merge resolution for the submodule:\n"
+msgstr "找到子模组的一个可能的合并方案:\n"
+
+#: merge-recursive.c:1253
+#, 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"
+"\n"
+"  git update-index --cacheinfo 160000 %s \"%s\"\n"
+"\n"
+"以接受此建议。\n"
+
+#: merge-recursive.c:1262
+#, c-format
+msgid "Failed to merge submodule %s (multiple merges found)"
+msgstr "无法合并子模组 %s (发现多个合并)"
+
+#: merge-recursive.c:1321
 msgid "Failed to execute internal merge"
 msgstr "无法执行内部合并"
 
-#: merge-recursive.c:1034
+#: merge-recursive.c:1326
 #, c-format
 msgid "Unable to add %s to database"
 msgstr "不能添加 %s 至对象库"
 
-#: merge-recursive.c:1146
+#: merge-recursive.c:1358
+#, c-format
+msgid "Auto-merging %s"
+msgstr "自动合并 %s"
+
+#: merge-recursive.c:1423
+#, c-format
+msgid "Error: Refusing to lose untracked file at %s; writing to %s instead."
+msgstr "错误:拒绝丢失未跟踪文件 '%s',而是写入 %s。"
+
+#: merge-recursive.c:1475
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2252,7 +2467,7 @@ msgstr ""
 "冲突(%1$s/删除):%2$s 在 %3$s 中被删除,在 %5$s 中被 %4$s。%7$s 的 %6$s 版"
 "本被保留。"
 
-#: merge-recursive.c:1151
+#: merge-recursive.c:1480
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2261,7 +2476,7 @@ msgstr ""
 "冲突(%1$s/删除):%2$s 在 %3$s 中被删除,在 %6$s 中的 %5$s 被 %4$s。%8$s 的 "
 "%7$s 版本被保留。"
 
-#: merge-recursive.c:1158
+#: merge-recursive.c:1487
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left "
@@ -2270,7 +2485,7 @@ msgstr ""
 "冲突(%1$s/删除):%2$s 在 %3$s 中被删除,在 %5$s 中被 %4$s。%7$s 的 %6$s 版"
 "本保留在 %8$s 中。"
 
-#: merge-recursive.c:1163
+#: merge-recursive.c:1492
 #, c-format
 msgid ""
 "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s "
@@ -2279,20 +2494,31 @@ msgstr ""
 "冲突(%1$s/删除):%2$s 在 %3$s 中被删除,在 %6$s 中的 %5$s 被 %4$s。%8$s 的 "
 "%7$s 版本保留在 %9$s 中。"
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "rename"
 msgstr "重命名"
 
-#: merge-recursive.c:1197
+#: merge-recursive.c:1526
 msgid "renamed"
 msgstr "重命名"
 
-#: merge-recursive.c:1254
+#: merge-recursive.c:1580 merge-recursive.c:1736 merge-recursive.c:2368
+#: merge-recursive.c:3086
+#, c-format
+msgid "Refusing to lose dirty file at %s"
+msgstr "拒绝丢失脏文件 '%s'"
+
+#: merge-recursive.c:1594
 #, c-format
 msgid "%s is a directory in %s adding as %s instead"
 msgstr "%s 是 %s 中的一个目录而以 %s 为名被添加"
 
-#: merge-recursive.c:1279
+#: merge-recursive.c:1599
+#, c-format
+msgid "Refusing to lose untracked file at %s; adding as %s instead"
+msgstr "拒绝丢失未跟踪文件 '%s',而是添加为 %s"
+
+#: merge-recursive.c:1625
 #, c-format
 msgid ""
 "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s"
@@ -2301,140 +2527,184 @@ msgstr ""
 "冲突(重命名/重命名):在分支 \"%3$s\" 中重命名 \"%1$s\"->\"%2$s\",在分支 "
 "\"%6$s\" 中重命名 \"%4$s\"->\"%5$s\"%7$s"
 
-#: merge-recursive.c:1284
+#: merge-recursive.c:1630
 msgid " (left unresolved)"
 msgstr "(留下未解决)"
 
-#: merge-recursive.c:1346
+#: merge-recursive.c:1694
 #, c-format
 msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s"
 msgstr ""
 "冲突(重命名/重命名):在 %3$s 中重命名 %1$s->%2$s,在 %6$s 中重命名 %4$s->"
 "%5$s"
 
-#: merge-recursive.c:1379
+#: merge-recursive.c:1733
 #, c-format
 msgid "Renaming %s to %s and %s to %s instead"
 msgstr "而是重命名 %s 至 %s,以及 %s 至 %s"
 
-#: merge-recursive.c:1582
+#: merge-recursive.c:1745
+#, c-format
+msgid "Refusing to lose untracked file at %s, even though it's in the way."
+msgstr "拒绝丢失未跟踪文件 '%s',即使它妨碍了。"
+
+#: merge-recursive.c:1951
+#, c-format
+msgid ""
+"CONFLICT (directory rename split): Unclear where to place %s because "
+"directory %s was renamed to multiple other directories, with no destination "
+"getting a majority of the files."
+msgstr ""
+"冲突(分割的目录重命名):不清楚 %s 应该放在哪里,因为目录 %s 被重命名到多个"
+"其它目录,没有一个目录包含主要的文件。"
+
+#: merge-recursive.c:1983
+#, c-format
+msgid ""
+"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 ""
+"冲突(隐式目录重命名):处于隐式目录重命名的现存文件/目录 %s,将以下路径放"
+"在:%s。"
+
+#: merge-recursive.c:1993
+#, 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 ""
+"冲突(隐式目录重命名):无法映射一个以上路径到 %s,隐式目录重命名尝试将这些路"
+"径放置于此:%s"
+
+#: merge-recursive.c:2085
+#, c-format
+msgid ""
+"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-"
+">%s in %s"
+msgstr ""
+"冲突(重命名/重命名):在 %3$s 中重命名目录 %1$s->%2$s,在 %6$s 中重命名目录 "
+"%4$s->%5$s"
+
+#: merge-recursive.c:2330
+#, c-format
+msgid ""
+"WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was "
+"renamed."
+msgstr "警告:避免应用 %s -> %s 的重命名到 %s,因为 %s 本身已被重命名。"
+
+#: merge-recursive.c:2736
 #, c-format
 msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s"
 msgstr "冲突(重命名/添加):在 %3$s 中重命名 %1$s->%2$s。在 %5$s 中添加 %4$s"
 
-#: merge-recursive.c:1597
+#: merge-recursive.c:2751
 #, c-format
 msgid "Adding merged %s"
 msgstr "添加合并后的 %s"
 
-#: merge-recursive.c:1604 merge-recursive.c:1834
+#: merge-recursive.c:2758 merge-recursive.c:3089
 #, c-format
 msgid "Adding as %s instead"
 msgstr "而是以 %s 为名添加"
 
-#: merge-recursive.c:1661
+#: merge-recursive.c:2914
 #, c-format
 msgid "cannot read object %s"
 msgstr "不能读取对象 %s"
 
-#: merge-recursive.c:1664
+#: merge-recursive.c:2917
 #, c-format
 msgid "object %s is not a blob"
 msgstr "对象 %s 不是一个数据对象"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modify"
 msgstr "修改"
 
-#: merge-recursive.c:1733
+#: merge-recursive.c:2986
 msgid "modified"
 msgstr "修改"
 
-#: merge-recursive.c:1743
+#: merge-recursive.c:2997
 msgid "content"
 msgstr "内容"
 
-#: merge-recursive.c:1750
+#: merge-recursive.c:3004
 msgid "add/add"
 msgstr "添加/添加"
 
-#: merge-recursive.c:1786
+#: merge-recursive.c:3046
 #, c-format
 msgid "Skipped %s (merged same as existing)"
 msgstr "略过 %s(已经做过相同合并)"
 
-#: merge-recursive.c:1800
-#, c-format
-msgid "Auto-merging %s"
-msgstr "自动合并 %s"
-
-#: merge-recursive.c:1804 git-submodule.sh:879
+#: merge-recursive.c:3055 git-submodule.sh:895
 msgid "submodule"
 msgstr "子模组"
 
-#: merge-recursive.c:1805
+#: merge-recursive.c:3056
 #, c-format
 msgid "CONFLICT (%s): Merge conflict in %s"
 msgstr "冲突(%s):合并冲突于 %s"
 
-#: merge-recursive.c:1899
+#: merge-recursive.c:3178
 #, c-format
 msgid "Removing %s"
 msgstr "删除 %s"
 
-#: merge-recursive.c:1925
+#: merge-recursive.c:3204
 msgid "file/directory"
 msgstr "文件/目录"
 
-#: merge-recursive.c:1931
+#: merge-recursive.c:3210
 msgid "directory/file"
 msgstr "目录/文件"
 
-#: merge-recursive.c:1938
+#: merge-recursive.c:3217
 #, c-format
 msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s"
 msgstr "冲突(%1$s):在 %3$s 中有一个名为 %2$s 的目录。以 %5$s 为名添加 %4$s"
 
-#: merge-recursive.c:1947
+#: merge-recursive.c:3226
 #, c-format
 msgid "Adding %s"
 msgstr "添加 %s"
 
-#: merge-recursive.c:1987
+#: merge-recursive.c:3267
 #, c-format
 msgid "Dirty index: cannot merge (dirty: %s)"
 msgstr "脏索引:不能合并(脏文件:%s)"
 
-#: merge-recursive.c:1991
+#: merge-recursive.c:3271
 msgid "Already up to date!"
 msgstr "已经是最新的!"
 
-#: merge-recursive.c:2000
+#: merge-recursive.c:3280
 #, c-format
 msgid "merging of trees %s and %s failed"
 msgstr "无法合并树 %s 和 %s"
 
-#: merge-recursive.c:2097
+#: merge-recursive.c:3379
 msgid "Merging:"
 msgstr "合并:"
 
-#: merge-recursive.c:2110
+#: merge-recursive.c:3392
 #, c-format
 msgid "found %u common ancestor:"
 msgid_plural "found %u common ancestors:"
 msgstr[0] "发现 %u 个共同祖先:"
 msgstr[1] "发现 %u 个共同祖先:"
 
-#: merge-recursive.c:2149
+#: merge-recursive.c:3431
 msgid "merge returned no commit"
 msgstr "合并未返回提交"
 
-#: merge-recursive.c:2212
+#: merge-recursive.c:3495
 #, c-format
 msgid "Could not parse object '%s'"
 msgstr "不能解析对象 '%s'"
 
-#: merge-recursive.c:2228 builtin/merge.c:657 builtin/merge.c:816
+#: merge-recursive.c:3511 builtin/merge.c:659 builtin/merge.c:816
 msgid "Unable to write index."
 msgstr "不能写入索引。"
 
@@ -2477,30 +2747,30 @@ msgstr "拒绝向 %s(在 refs/notes/ 之外)写入注解"
 msgid "Bad %s value: '%s'"
 msgstr "坏的 %s 值:'%s'"
 
-#: object.c:239
+#: object.c:242
 #, c-format
 msgid "unable to parse object: %s"
 msgstr "不能解析对象:%s"
 
-#: packfile.c:561
+#: packfile.c:563
 msgid "offset before end of packfile (broken .idx?)"
 msgstr "偏移量在包文件结束之前(损坏的 .idx?)"
 
-#: packfile.c:1694
+#: packfile.c:1742
 #, c-format
 msgid "offset before start of pack index for %s (corrupt index?)"
 msgstr "偏移量在 %s 的包索引开始之前(损坏的索引?)"
 
-#: packfile.c:1698
+#: packfile.c:1746
 #, c-format
 msgid "offset beyond end of pack index for %s (truncated index?)"
 msgstr "偏移量越过了 %s 的包索引的结尾(被截断的索引?)"
 
-#: parse-options.c:619
+#: parse-options.c:621
 msgid "..."
 msgstr "..."
 
-#: parse-options.c:638
+#: parse-options.c:640
 #, c-format
 msgid "usage: %s"
 msgstr "用法:%s"
@@ -2508,27 +2778,32 @@ msgstr "用法:%s"
 #. TRANSLATORS: the colon here should align with the
 #. one in "usage: %s" translation.
 #.
-#: parse-options.c:644
+#: parse-options.c:646
 #, c-format
 msgid "   or: %s"
 msgstr "  或:%s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: parse-options.c:647
+#: parse-options.c:649
 #, c-format
 msgid "    %s"
 msgstr "    %s"
 
-#: parse-options.c:686
+#: parse-options.c:688
 msgid "-NUM"
 msgstr "-数字"
 
-#: parse-options-cb.c:108
+#: parse-options-cb.c:44
+#, c-format
+msgid "malformed expiration date '%s'"
+msgstr "格式错误的到期时间:'%s'"
+
+#: parse-options-cb.c:112
 #, c-format
 msgid "malformed object name '%s'"
-msgstr "非法的对象名 '%s'"
+msgstr "格式错误的对象名 '%s'"
 
-#: path.c:891
+#: path.c:892
 #, c-format
 msgid "Could not make %s writable by group"
 msgstr "不能设置 %s 为组可写"
@@ -2608,7 +2883,7 @@ msgstr "路径规格 '%s' 位于符号链接中"
 msgid "unable to parse --pretty format"
 msgstr "不能解析 --pretty 格式"
 
-#: read-cache.c:1473
+#: read-cache.c:1500
 #, c-format
 msgid ""
 "index.version set, but the value is invalid.\n"
@@ -2617,7 +2892,7 @@ msgstr ""
 "设置了 index.version,但是取值无效。\n"
 "使用版本 %i"
 
-#: read-cache.c:1483
+#: read-cache.c:1510
 #, c-format
 msgid ""
 "GIT_INDEX_VERSION set, but the value is invalid.\n"
@@ -2626,52 +2901,53 @@ msgstr ""
 "设置了 GIT_INDEX_VERSION,但是取值无效。\n"
 "使用版本 %i"
 
-#: read-cache.c:2375 sequencer.c:3248 wrapper.c:658 builtin/merge.c:1049
+#: read-cache.c:2404 sequencer.c:4338 wrapper.c:658 builtin/merge.c:1048
 #, c-format
 msgid "could not close '%s'"
 msgstr "不能关闭 '%s'"
 
-#: read-cache.c:2448 sequencer.c:1900 sequencer.c:2627
+#: read-cache.c:2477 sequencer.c:2102 sequencer.c:3234
 #, c-format
 msgid "could not stat '%s'"
 msgstr "不能对 '%s' 调用 stat"
 
-#: read-cache.c:2461
+#: read-cache.c:2490
 #, c-format
 msgid "unable to open git dir: %s"
 msgstr "不能打开 git 目录:%s"
 
-#: read-cache.c:2473
+#: read-cache.c:2502
 #, c-format
 msgid "unable to unlink: %s"
 msgstr "无法删除:%s"
 
-#: refs.c:706
+#: refs.c:732 sequencer.c:4334 sequencer.c:4393 wrapper.c:225 wrapper.c:395
+#: builtin/am.c:779
 #, c-format
-msgid "Could not open '%s' for writing"
+msgid "could not open '%s' for writing"
 msgstr "无法打开 '%s' 进行写入"
 
-#: refs.c:1850
+#: refs.c:1880
 msgid "ref updates forbidden inside quarantine environment"
 msgstr "在隔离环境中禁止更新引用"
 
-#: refs/files-backend.c:1189
+#: refs/files-backend.c:1191
 #, c-format
 msgid "could not remove reference %s"
 msgstr "无法删除引用 %s"
 
-#: refs/files-backend.c:1203 refs/packed-backend.c:1528
-#: refs/packed-backend.c:1538
+#: refs/files-backend.c:1205 refs/packed-backend.c:1531
+#: refs/packed-backend.c:1541
 #, c-format
 msgid "could not delete reference %s: %s"
 msgstr "无法删除引用 %s:%s"
 
-#: refs/files-backend.c:1206 refs/packed-backend.c:1541
+#: refs/files-backend.c:1208 refs/packed-backend.c:1544
 #, c-format
 msgid "could not delete references: %s"
 msgstr "无法删除引用:%s"
 
-#: ref-filter.c:35 wt-status.c:1842
+#: ref-filter.c:35 wt-status.c:1850
 msgid "gone"
 msgstr "丢失"
 
@@ -2690,157 +2966,162 @@ msgstr "落后 %d"
 msgid "ahead %d, behind %d"
 msgstr "领先 %d,落后 %d"
 
-#: ref-filter.c:107
+#: ref-filter.c:121
 #, c-format
 msgid "expected format: %%(color:<color>)"
 msgstr "期望的格式:%%(color:<颜色>)"
 
-#: ref-filter.c:109
+#: ref-filter.c:123
 #, c-format
 msgid "unrecognized color: %%(color:%s)"
 msgstr "未能识别的颜色:%%(color:%s)"
 
-#: ref-filter.c:129
+#: ref-filter.c:145
 #, c-format
 msgid "Integer value expected refname:lstrip=%s"
 msgstr "期望整数值 refname:lstrip=%s"
 
-#: ref-filter.c:133
+#: ref-filter.c:149
 #, c-format
 msgid "Integer value expected refname:rstrip=%s"
 msgstr "期望整数值 refname:rstrip=%s"
 
-#: ref-filter.c:135
+#: ref-filter.c:151
 #, c-format
 msgid "unrecognized %%(%s) argument: %s"
 msgstr "未能识别的 %%(%s) 参数:%s"
 
-#: ref-filter.c:184
+#: ref-filter.c:206
 #, c-format
 msgid "%%(body) does not take arguments"
 msgstr "%%(body) 不带参数"
 
-#: ref-filter.c:191
+#: ref-filter.c:215
 #, c-format
 msgid "%%(subject) does not take arguments"
 msgstr "%%(subject) 不带参数"
 
-#: ref-filter.c:209
+#: ref-filter.c:235
 #, c-format
 msgid "unknown %%(trailers) argument: %s"
 msgstr "未知的 %%(trailers) 参数:%s"
 
-#: ref-filter.c:232
+#: ref-filter.c:264
 #, c-format
 msgid "positive value expected contents:lines=%s"
 msgstr "期望一个正数 contents:lines=%s"
 
-#: ref-filter.c:234
+#: ref-filter.c:266
 #, c-format
 msgid "unrecognized %%(contents) argument: %s"
 msgstr "未能识别的 %%(contents) 参数:%s"
 
-#: ref-filter.c:247
+#: ref-filter.c:281
 #, c-format
 msgid "positive value expected objectname:short=%s"
 msgstr "期望一个正数 objectname:short=%s"
 
-#: ref-filter.c:251
+#: ref-filter.c:285
 #, c-format
 msgid "unrecognized %%(objectname) argument: %s"
 msgstr "未能识别的 %%(objectname) 参数:%s"
 
-#: ref-filter.c:278
+#: ref-filter.c:315
 #, c-format
 msgid "expected format: %%(align:<width>,<position>)"
 msgstr "期望的格式:%%(align:<宽度>,<位置>)"
 
-#: ref-filter.c:290
+#: ref-filter.c:327
 #, c-format
 msgid "unrecognized position:%s"
 msgstr "未能识别的位置:%s"
 
-#: ref-filter.c:294
+#: ref-filter.c:334
 #, c-format
 msgid "unrecognized width:%s"
 msgstr "未能识别的宽度:%s"
 
-#: ref-filter.c:300
+#: ref-filter.c:343
 #, c-format
 msgid "unrecognized %%(align) argument: %s"
 msgstr "未能识别的 %%(align) 参数:%s"
 
-#: ref-filter.c:304
+#: ref-filter.c:351
 #, c-format
 msgid "positive width expected with the %%(align) atom"
 msgstr "元素 %%(align) 需要一个正数的宽度"
 
-#: ref-filter.c:319
+#: ref-filter.c:369
 #, c-format
 msgid "unrecognized %%(if) argument: %s"
 msgstr "未能识别的 %%(if) 参数:%s"
 
-#: ref-filter.c:409
+#: ref-filter.c:464
 #, c-format
 msgid "malformed field name: %.*s"
-msgstr "非法的字段名:%.*s"
+msgstr "格式错误的字段名:%.*s"
 
-#: ref-filter.c:435
+#: ref-filter.c:491
 #, c-format
 msgid "unknown field name: %.*s"
 msgstr "未知的字段名:%.*s"
 
-#: ref-filter.c:547
+#: ref-filter.c:608
 #, c-format
 msgid "format: %%(if) atom used without a %%(then) atom"
 msgstr "格式:使用了 %%(if) 元素而没有 %%(then) 元素"
 
-#: ref-filter.c:607
+#: ref-filter.c:671
 #, c-format
 msgid "format: %%(then) atom used without an %%(if) atom"
 msgstr "格式:使用了 %%(then) 元素而没有 %%(if) 元素"
 
-#: ref-filter.c:609
+#: ref-filter.c:673
 #, c-format
 msgid "format: %%(then) atom used more than once"
 msgstr "格式:%%(then) 元素用了多次"
 
-#: ref-filter.c:611
+#: ref-filter.c:675
 #, c-format
 msgid "format: %%(then) atom used after %%(else)"
 msgstr "格式:%%(then) 元素用在了 %%(else) 之后"
 
-#: ref-filter.c:637
+#: ref-filter.c:703
 #, c-format
 msgid "format: %%(else) atom used without an %%(if) atom"
 msgstr "格式:使用了 %%(else) 元素而没有 %%(if) 元素"
 
-#: ref-filter.c:639
+#: ref-filter.c:705
 #, c-format
 msgid "format: %%(else) atom used without a %%(then) atom"
 msgstr "格式:使用了 %%(else) 元素而没有 %%(then) 元素"
 
-#: ref-filter.c:641
+#: ref-filter.c:707
 #, c-format
 msgid "format: %%(else) atom used more than once"
 msgstr "格式:%%(else) 元素用了多次"
 
-#: ref-filter.c:654
+#: ref-filter.c:722
 #, c-format
 msgid "format: %%(end) atom used without corresponding atom"
 msgstr "格式:使用了 %%(end) 元素却没有它的对应元素"
 
-#: ref-filter.c:709
+#: ref-filter.c:779
 #, c-format
 msgid "malformed format string %s"
-msgstr "é\9d\9eæ³\95的格式化字符串 %s"
+msgstr "é\94\99误的格式化字符串 %s"
 
-#: ref-filter.c:1313
+#: ref-filter.c:1387
 #, c-format
 msgid "(no branch, rebasing %s)"
 msgstr "(非分支,正变基 %s)"
 
-#: ref-filter.c:1316
+#: ref-filter.c:1390
+#, c-format
+msgid "(no branch, rebasing detached HEAD %s)"
+msgstr "(非分支,正变基分离头指针 %s)"
+
+#: ref-filter.c:1393
 #, c-format
 msgid "(no branch, bisect started on %s)"
 msgstr "(非分支,二分查找开始于 %s)"
@@ -2848,7 +3129,7 @@ msgstr "(非分支,二分查找开始于 %s)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached at " in wt-status.c
 #.
-#: ref-filter.c:1324
+#: ref-filter.c:1401
 #, c-format
 msgid "(HEAD detached at %s)"
 msgstr "(头指针分离于 %s)"
@@ -2856,147 +3137,147 @@ msgstr "(头指针分离于 %s)"
 #. TRANSLATORS: make sure this matches "HEAD
 #. detached from " in wt-status.c
 #.
-#: ref-filter.c:1331
+#: ref-filter.c:1408
 #, c-format
 msgid "(HEAD detached from %s)"
 msgstr "(头指针分离自 %s)"
 
-#: ref-filter.c:1335
+#: ref-filter.c:1412
 msgid "(no branch)"
 msgstr "(非分支)"
 
-#: ref-filter.c:1364
+#: ref-filter.c:1442
 #, c-format
 msgid "missing object %s for %s"
 msgstr "缺失 %2$s 的对象 %1$s"
 
-#: ref-filter.c:1367
+#: ref-filter.c:1445
 #, c-format
 msgid "parse_object_buffer failed on %s for %s"
 msgstr "parse_object_buffer 失败于 %2$s 的 %1$s"
 
-#: ref-filter.c:1819
+#: ref-filter.c:1902
 #, c-format
 msgid "malformed object at '%s'"
-msgstr "非法的对象于 '%s'"
+msgstr "格式错误的对象 '%s'"
 
-#: ref-filter.c:1886
+#: ref-filter.c:1984
 #, c-format
 msgid "ignoring ref with broken name %s"
 msgstr "忽略带有错误名称 %s 的引用"
 
-#: ref-filter.c:1891
+#: ref-filter.c:1989
 #, c-format
 msgid "ignoring broken ref %s"
 msgstr "忽略损坏的引用 %s"
 
-#: ref-filter.c:2152
+#: ref-filter.c:2261
 #, c-format
 msgid "format: %%(end) atom missing"
 msgstr "格式:缺少 %%(end) 元素"
 
-#: ref-filter.c:2246
+#: ref-filter.c:2365
 #, c-format
 msgid "malformed object name %s"
-msgstr "非法的对象名 %s"
+msgstr "格式错误的对象名 %s"
 
-#: remote.c:795
+#: remote.c:605
 #, c-format
 msgid "Cannot fetch both %s and %s to %s"
 msgstr "不能同时获取 %s 和 %s 至 %s"
 
-#: remote.c:799
+#: remote.c:609
 #, c-format
 msgid "%s usually tracks %s, not %s"
 msgstr "%s 通常跟踪 %s,而非 %s"
 
-#: remote.c:803
+#: remote.c:613
 #, c-format
 msgid "%s tracks both %s and %s"
 msgstr "%s 同时跟踪 %s 和 %s"
 
-#: remote.c:811
+#: remote.c:621
 msgid "Internal error"
 msgstr "内部错误"
 
-#: remote.c:1726 remote.c:1828
+#: remote.c:1534 remote.c:1635
 msgid "HEAD does not point to a branch"
 msgstr "HEAD 没有指向一个分支"
 
-#: remote.c:1735
+#: remote.c:1543
 #, c-format
 msgid "no such branch: '%s'"
 msgstr "没有此分支:'%s'"
 
-#: remote.c:1738
+#: remote.c:1546
 #, c-format
 msgid "no upstream configured for branch '%s'"
 msgstr "尚未给分支 '%s' 设置上游"
 
-#: remote.c:1744
+#: remote.c:1552
 #, c-format
 msgid "upstream branch '%s' not stored as a remote-tracking branch"
 msgstr "上游分支 '%s' 没有存储为一个远程跟踪分支"
 
-#: remote.c:1759
+#: remote.c:1567
 #, c-format
 msgid "push destination '%s' on remote '%s' has no local tracking branch"
 msgstr "推送目标 '%s' 至远程 '%s' 没有本地跟踪分支"
 
-#: remote.c:1771
+#: remote.c:1579
 #, c-format
 msgid "branch '%s' has no remote for pushing"
 msgstr "分支 '%s' 没有设置要推送的远程服务器"
 
-#: remote.c:1782
+#: remote.c:1589
 #, c-format
 msgid "push refspecs for '%s' do not include '%s'"
 msgstr "向 '%s' 推送引用规格未包含 '%s'"
 
-#: remote.c:1795
+#: remote.c:1602
 msgid "push has no destination (push.default is 'nothing')"
 msgstr "推送无目标(push.default 是 'nothing')"
 
-#: remote.c:1817
+#: remote.c:1624
 msgid "cannot resolve 'simple' push to a single destination"
 msgstr "无法解析 'simple' 推送至一个单独的目标"
 
-#: remote.c:2132
+#: remote.c:1939
 #, c-format
 msgid "Your branch is based on '%s', but the upstream is gone.\n"
 msgstr "您的分支基于 '%s',但此上游分支已经不存在。\n"
 
-#: remote.c:2136
+#: remote.c:1943
 msgid "  (use \"git branch --unset-upstream\" to fixup)\n"
 msgstr "  (使用 \"git branch --unset-upstream\" 来修复)\n"
 
-#: remote.c:2139
+#: remote.c:1946
 #, c-format
 msgid "Your branch is up to date with '%s'.\n"
 msgstr "您的分支与上游分支 '%s' 一致。\n"
 
-#: remote.c:2143
+#: remote.c:1950
 #, c-format
 msgid "Your branch and '%s' refer to different commits.\n"
 msgstr "您的分支和 '%s' 指向不同的提交。\n"
 
-#: remote.c:2146
+#: remote.c:1953
 #, c-format
 msgid "  (use \"%s\" for details)\n"
 msgstr "  (使用 \"%s\" 查看详情)\n"
 
-#: remote.c:2150
+#: remote.c:1957
 #, 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] "您的分支领先 '%s' 共 %d 个提交。\n"
 msgstr[1] "您的分支领先 '%s' 共 %d 个提交。\n"
 
-#: remote.c:2156
+#: remote.c:1963
 msgid "  (use \"git push\" to publish your local commits)\n"
 msgstr "  (使用 \"git push\" 来发布您的本地提交)\n"
 
-#: remote.c:2159
+#: remote.c:1966
 #, c-format
 msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n"
 msgid_plural ""
@@ -3005,11 +3286,11 @@ msgstr[0] "您的分支落后 '%s' 共 %d 个提交,并且可以快进。\n"
 msgstr[1] "您的分支落后 '%s' 共 %d 个提交,并且可以快进。\n"
 
 #  译者:注意保持前导空格
-#: remote.c:2167
+#: remote.c:1974
 msgid "  (use \"git pull\" to update your local branch)\n"
 msgstr "  (使用 \"git pull\" 来更新您的本地分支)\n"
 
-#: remote.c:2170
+#: remote.c:1977
 #, c-format
 msgid ""
 "Your branch and '%s' have diverged,\n"
@@ -3025,28 +3306,28 @@ msgstr[1] ""
 "并且分别有 %d 和 %d 处不同的提交。\n"
 
 #  译者:注意保持前导空格
-#: remote.c:2180
+#: remote.c:1987
 msgid "  (use \"git pull\" to merge the remote branch into yours)\n"
 msgstr "  (使用 \"git pull\" 来合并远程分支)\n"
 
-#: revision.c:2277
+#: revision.c:2289
 msgid "your current branch appears to be broken"
 msgstr "您的当前分支好像被损坏"
 
-#: revision.c:2280
+#: revision.c:2292
 #, c-format
 msgid "your current branch '%s' does not have any commits yet"
 msgstr "您的当前分支 '%s' 尚无任何提交"
 
-#: revision.c:2477
+#: revision.c:2489
 msgid "--first-parent is incompatible with --bisect"
 msgstr "--first-parent 与 --bisect 不兼容"
 
-#: run-command.c:731
+#: run-command.c:728
 msgid "open /dev/null failed"
 msgstr "不能打开 /dev/null"
 
-#: run-command.c:1274
+#: run-command.c:1271
 #, c-format
 msgid ""
 "The '%s' hook was ignored because it's not set as executable.\n"
@@ -3091,29 +3372,34 @@ msgstr "接收端不支持原子推送"
 msgid "the receiving end does not support push options"
 msgstr "接收端不支持推送选项"
 
-#: sequencer.c:158
+#: sequencer.c:175
 #, c-format
 msgid "invalid commit message cleanup mode '%s'"
 msgstr "无效的提交信息清理模式 '%s'"
 
-#: sequencer.c:267
+#: sequencer.c:275
+#, c-format
+msgid "could not delete '%s'"
+msgstr "无法删除 '%s'"
+
+#: sequencer.c:301
 msgid "revert"
 msgstr "还原"
 
-#: sequencer.c:269
+#: sequencer.c:303
 msgid "cherry-pick"
 msgstr "拣选"
 
-#: sequencer.c:271
+#: sequencer.c:305
 msgid "rebase -i"
 msgstr "rebase -i"
 
-#: sequencer.c:273
+#: sequencer.c:307
 #, c-format
 msgid "Unknown action: %d"
 msgstr "未知动作:%d"
 
-#: sequencer.c:330
+#: sequencer.c:364
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'"
@@ -3121,7 +3407,7 @@ msgstr ""
 "冲突解决完毕后,用 'git add <路径>' 或 'git rm <路径>'\n"
 "命令标记修正后的文件"
 
-#: sequencer.c:333
+#: sequencer.c:367
 msgid ""
 "after resolving the conflicts, mark the corrected paths\n"
 "with 'git add <paths>' or 'git rm <paths>'\n"
@@ -3130,43 +3416,45 @@ msgstr ""
 "冲突解决完毕后,用 'git add <路径>' 或 'git rm <路径>'\n"
 "对修正后的文件做标记,然后用 'git commit' 提交"
 
-#: sequencer.c:346 sequencer.c:2245
+#: sequencer.c:380 sequencer.c:2468
 #, c-format
 msgid "could not lock '%s'"
 msgstr "不能锁定 '%s'"
 
-#: sequencer.c:349 sequencer.c:2124 sequencer.c:2250 sequencer.c:2264
-#: sequencer.c:3246 sequencer.c:3310 wrapper.c:656
+#: sequencer.c:382 sequencer.c:2346 sequencer.c:2472 sequencer.c:2486
+#: sequencer.c:2694 sequencer.c:4336 sequencer.c:4399 wrapper.c:656
 #, c-format
 msgid "could not write to '%s'"
 msgstr "不能写入 '%s'"
 
-#: sequencer.c:353
+#: sequencer.c:387
 #, c-format
 msgid "could not write eol to '%s'"
 msgstr "不能将换行符写入 '%s'"
 
-#: sequencer.c:356 sequencer.c:2128 sequencer.c:2252
+#: sequencer.c:392 sequencer.c:2351 sequencer.c:2474 sequencer.c:2488
+#: sequencer.c:2702
 #, c-format
 msgid "failed to finalize '%s'"
 msgstr "无法完成 '%s'"
 
-#: sequencer.c:379 sequencer.c:1340 sequencer.c:2148 builtin/am.c:259
-#: builtin/commit.c:722 builtin/merge.c:1047
+#: sequencer.c:415 sequencer.c:804 sequencer.c:1493 sequencer.c:2371
+#: sequencer.c:2684 sequencer.c:2788 builtin/am.c:259 builtin/commit.c:727
+#: builtin/merge.c:1046
 #, c-format
 msgid "could not read '%s'"
 msgstr "不能读取 '%s'"
 
-#: sequencer.c:405
+#: sequencer.c:441
 #, c-format
 msgid "your local changes would be overwritten by %s."
 msgstr "您的本地修改将被%s覆盖。"
 
-#: sequencer.c:409
+#: sequencer.c:445
 msgid "commit your changes or stash them to proceed."
 msgstr "提交您的修改或贮藏后再继续。"
 
-#: sequencer.c:438
+#: sequencer.c:474
 #, c-format
 msgid "%s: fast-forward"
 msgstr "%s:快进"
@@ -3174,20 +3462,20 @@ msgstr "%s:快进"
 #. TRANSLATORS: %s will be "revert", "cherry-pick" or
 #. "rebase -i".
 #.
-#: sequencer.c:526
+#: sequencer.c:563
 #, c-format
 msgid "%s: Unable to write new index file"
 msgstr "%s:无法写入新索引文件"
 
-#: sequencer.c:542
-msgid "could not resolve HEAD commit"
-msgstr "不能解析 HEAD 提交"
-
-#: sequencer.c:562
+#: sequencer.c:579
 msgid "unable to update cache tree"
 msgstr "不能更新缓存树"
 
-#: sequencer.c:658
+#: sequencer.c:592
+msgid "could not resolve HEAD commit"
+msgstr "不能解析 HEAD 提交"
+
+#: sequencer.c:749
 #, c-format
 msgid ""
 "you have staged changes in your working tree\n"
@@ -3216,11 +3504,15 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: sequencer.c:915
+#: sequencer.c:818
+msgid "writing root commit"
+msgstr "写根提交"
+
+#: sequencer.c:1043
 msgid "'prepare-commit-msg' hook failed"
 msgstr "'prepare-commit-msg' 钩子失败"
 
-#: sequencer.c:922
+#: sequencer.c:1050
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3244,7 +3536,7 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:935
+#: sequencer.c:1063
 msgid ""
 "Your name and email address were configured automatically based\n"
 "on your username and hostname. Please check that they are accurate.\n"
@@ -3267,329 +3559,315 @@ msgstr ""
 "\n"
 "    git commit --amend --reset-author\n"
 
-#: sequencer.c:975
+#: sequencer.c:1103
 msgid "couldn't look up newly created commit"
 msgstr "无法找到新创建的提交"
 
-#: sequencer.c:977
+#: sequencer.c:1105
 msgid "could not parse newly created commit"
 msgstr "不能解析新创建的提交"
 
-#: sequencer.c:1023
+#: sequencer.c:1151
 msgid "unable to resolve HEAD after creating commit"
 msgstr "创建提交后,不能解析 HEAD"
 
-#: sequencer.c:1025
+#: sequencer.c:1153
 msgid "detached HEAD"
 msgstr "分离头指针"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: sequencer.c:1029
+#: sequencer.c:1157
 msgid " (root-commit)"
 msgstr "(根提交)"
 
-#: sequencer.c:1050
+#: sequencer.c:1178
 msgid "could not parse HEAD"
 msgstr "不能解析 HEAD"
 
-#: sequencer.c:1052
+#: sequencer.c:1180
 #, c-format
 msgid "HEAD %s is not a commit!"
 msgstr "HEAD %s 不是一个提交!"
 
-#: sequencer.c:1056 builtin/commit.c:1491
+#: sequencer.c:1184 builtin/commit.c:1528
 msgid "could not parse HEAD commit"
 msgstr "不能解析 HEAD 提交"
 
-#: sequencer.c:1107 sequencer.c:1673
+#: sequencer.c:1235 sequencer.c:1832
 msgid "unable to parse commit author"
 msgstr "不能解析提交作者"
 
-#: sequencer.c:1117 builtin/am.c:1630 builtin/merge.c:643
+#: sequencer.c:1245 builtin/am.c:1630 builtin/merge.c:645
 msgid "git write-tree failed to write a tree"
 msgstr "git write-tree 无法写入树对象"
 
-#: sequencer.c:1134 sequencer.c:1186
+#: sequencer.c:1262 sequencer.c:1317
 #, c-format
 msgid "unable to read commit message from '%s'"
 msgstr "不能从 '%s' 读取提交说明"
 
-#: sequencer.c:1154 builtin/am.c:1650 builtin/commit.c:1594 builtin/merge.c:826
-#: builtin/merge.c:851
+#: sequencer.c:1284 builtin/am.c:1650 builtin/commit.c:1631 builtin/merge.c:825
+#: builtin/merge.c:850
 msgid "failed to write commit object"
 msgstr "无法写提交对象"
 
-#: sequencer.c:1213
+#: sequencer.c:1344
 #, c-format
 msgid "could not parse commit %s"
 msgstr "不能解析提交 %s"
 
-#: sequencer.c:1218
+#: sequencer.c:1349
 #, c-format
 msgid "could not parse parent commit %s"
 msgstr "不能解析父提交 %s"
 
-#: sequencer.c:1347
-#, c-format
-msgid ""
-"unexpected 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"意外的压缩提交首行提交信息:\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1353
-#, c-format
-msgid ""
-"invalid 1st line of squash message:\n"
-"\n"
-"\t%.*s"
-msgstr ""
-"压缩提交的首行提交信息无效:\n"
-"\n"
-"\t%.*s"
-
-#: sequencer.c:1359 sequencer.c:1384
+#: sequencer.c:1500 sequencer.c:1525
 #, c-format
 msgid "This is a combination of %d commits."
 msgstr "这是一个 %d 个提交的组合。"
 
-#: sequencer.c:1368 sequencer.c:3265
+#: sequencer.c:1510 sequencer.c:4355
 msgid "need a HEAD to fixup"
 msgstr "需要一个 HEAD 来修复"
 
-#: sequencer.c:1370
+#: sequencer.c:1512 sequencer.c:2729
 msgid "could not read HEAD"
 msgstr "不能读取 HEAD"
 
-#: sequencer.c:1372
+#: sequencer.c:1514
 msgid "could not read HEAD's commit message"
 msgstr "不能读取 HEAD 的提交说明"
 
-#: sequencer.c:1378
+#: sequencer.c:1520
 #, c-format
 msgid "cannot write '%s'"
 msgstr "不能写 '%s'"
 
-#: sequencer.c:1387 git-rebase--interactive.sh:452
+#: sequencer.c:1527 git-rebase--interactive.sh:457
 msgid "This is the 1st commit message:"
 msgstr "这是第一个提交说明:"
 
-#: sequencer.c:1395
+#: sequencer.c:1535
 #, c-format
 msgid "could not read commit message of %s"
 msgstr "不能读取 %s 的提交说明"
 
-#: sequencer.c:1402
+#: sequencer.c:1542
 #, c-format
 msgid "This is the commit message #%d:"
 msgstr "这是提交说明 #%d:"
 
-#: sequencer.c:1407
+#: sequencer.c:1548
 #, c-format
 msgid "The commit message #%d will be skipped:"
 msgstr "提交说明 #%d 将被跳过:"
 
-#: sequencer.c:1412
+#: sequencer.c:1553
 #, c-format
 msgid "unknown command: %d"
 msgstr "未知命令:%d"
 
-#: sequencer.c:1479
+#: sequencer.c:1631
 msgid "your index file is unmerged."
 msgstr "您的索引文件未完成合并。"
 
-#: sequencer.c:1498
+#: sequencer.c:1638
+msgid "cannot fixup root commit"
+msgstr "不能修复根提交"
+
+#: sequencer.c:1657
 #, c-format
 msgid "commit %s is a merge but no -m option was given."
 msgstr "提交 %s 是一个合并提交但未提供 -m 选项。"
 
-#: sequencer.c:1506
+#: sequencer.c:1665
 #, c-format
 msgid "commit %s does not have parent %d"
 msgstr "提交 %s 没有第 %d 个父提交"
 
-#: sequencer.c:1510
+#: sequencer.c:1669
 #, c-format
 msgid "mainline was specified but commit %s is not a merge."
 msgstr "指定了主线,但是提交 %s 不是一个合并提交。"
 
-#: sequencer.c:1516
+#: sequencer.c:1675
 #, c-format
 msgid "cannot get commit message for %s"
 msgstr "不能得到 %s 的提交说明"
 
 #. TRANSLATORS: The first %s will be a "todo" command like
 #. "revert" or "pick", the second %s a SHA1.
-#: sequencer.c:1535
+#: sequencer.c:1694
 #, c-format
 msgid "%s: cannot parse parent commit %s"
 msgstr "%s:不能解析父提交 %s"
 
-#: sequencer.c:1600 sequencer.c:2397
+#: sequencer.c:1759
 #, c-format
 msgid "could not rename '%s' to '%s'"
 msgstr "不能将 '%s' 重命名为 '%s'"
 
-#: sequencer.c:1654
+#: sequencer.c:1813
 #, c-format
 msgid "could not revert %s... %s"
 msgstr "不能还原 %s... %s"
 
-#: sequencer.c:1655
+#: sequencer.c:1814
 #, c-format
 msgid "could not apply %s... %s"
 msgstr "不能应用 %s... %s"
 
-#: sequencer.c:1702
+#: sequencer.c:1864
 msgid "empty commit set passed"
 msgstr "提供了空的提交集"
 
-#: sequencer.c:1712
+#: sequencer.c:1874
 #, c-format
 msgid "git %s: failed to read the index"
 msgstr "git %s:无法读取索引"
 
-#: sequencer.c:1718
+#: sequencer.c:1881
 #, c-format
 msgid "git %s: failed to refresh the index"
 msgstr "git %s:无法刷新索引"
 
-#: sequencer.c:1792
+#: sequencer.c:1961
 #, c-format
 msgid "%s does not accept arguments: '%s'"
 msgstr "%s 不接受参数:'%s'"
 
-#: sequencer.c:1801
+#: sequencer.c:1970
 #, c-format
 msgid "missing arguments for %s"
 msgstr "缺少 %s 的参数"
 
-#: sequencer.c:1844
+#: sequencer.c:2029
 #, c-format
 msgid "invalid line %d: %.*s"
 msgstr "无效行 %d:%.*s"
 
-#: sequencer.c:1852
+#: sequencer.c:2037
 #, c-format
 msgid "cannot '%s' without a previous commit"
 msgstr "没有父提交的情况下不能 '%s'"
 
-#: sequencer.c:1883 sequencer.c:3056 sequencer.c:3091
+#: sequencer.c:2085 sequencer.c:4138 sequencer.c:4173
 #, c-format
 msgid "could not read '%s'."
 msgstr "不能读取 '%s'。"
 
-#: sequencer.c:1906
+#: sequencer.c:2108
 msgid "please fix this using 'git rebase --edit-todo'."
 msgstr "请用 'git rebase --edit-todo' 来修改。"
 
-#: sequencer.c:1908
+#: sequencer.c:2110
 #, c-format
 msgid "unusable instruction sheet: '%s'"
 msgstr "不可用的指令清单:'%s'"
 
-#: sequencer.c:1913
+#: sequencer.c:2115
 msgid "no commits parsed."
 msgstr "没有解析提交。"
 
-#: sequencer.c:1924
+#: sequencer.c:2126
 msgid "cannot cherry-pick during a revert."
 msgstr "不能在回退中执行拣选。"
 
-#: sequencer.c:1926
+#: sequencer.c:2128
 msgid "cannot revert during a cherry-pick."
 msgstr "不能在拣选中执行回退。"
 
-#: sequencer.c:1993
+#: sequencer.c:2195
 #, c-format
 msgid "invalid key: %s"
 msgstr "无效键名:%s"
 
-#: sequencer.c:1996
+#: sequencer.c:2198
 #, c-format
 msgid "invalid value for %s: %s"
 msgstr "%s 的值无效:%s"
 
-#: sequencer.c:2062
+#: sequencer.c:2269
+msgid "unusable squash-onto"
+msgstr "不可用的 squash-onto"
+
+#: sequencer.c:2285
 #, c-format
 msgid "malformed options sheet: '%s'"
-msgstr "非法的选项清单:'%s'"
+msgstr "格式错误的选项清单:'%s'"
 
-#: sequencer.c:2100
+#: sequencer.c:2323
 msgid "a cherry-pick or revert is already in progress"
 msgstr "一个拣选或还原操作已在进行"
 
-#: sequencer.c:2101
+#: sequencer.c:2324
 msgid "try \"git cherry-pick (--continue | --quit | --abort)\""
 msgstr "尝试 \"git cherry-pick (--continue | --quit | --abort)\""
 
-#: sequencer.c:2104
+#: sequencer.c:2327
 #, c-format
 msgid "could not create sequencer directory '%s'"
 msgstr "不能创建序列目录 '%s'"
 
-#: sequencer.c:2118
+#: sequencer.c:2341
 msgid "could not lock HEAD"
 msgstr "不能锁定 HEAD"
 
-#: sequencer.c:2173 sequencer.c:2761
+#: sequencer.c:2396 sequencer.c:3403
 msgid "no cherry-pick or revert in progress"
 msgstr "拣选或还原操作并未进行"
 
-#: sequencer.c:2175
+#: sequencer.c:2398
 msgid "cannot resolve HEAD"
 msgstr "不能解析 HEAD"
 
-#: sequencer.c:2177 sequencer.c:2212
+#: sequencer.c:2400 sequencer.c:2435
 msgid "cannot abort from a branch yet to be born"
 msgstr "不能从尚未建立的分支终止"
 
-#: sequencer.c:2198 builtin/grep.c:720
+#: sequencer.c:2421 builtin/grep.c:720
 #, c-format
 msgid "cannot open '%s'"
 msgstr "不能打开 '%s'"
 
-#: sequencer.c:2200
+#: sequencer.c:2423
 #, c-format
 msgid "cannot read '%s': %s"
 msgstr "不能读取 '%s':%s"
 
-#: sequencer.c:2201
+#: sequencer.c:2424
 msgid "unexpected end of file"
 msgstr "意外的文件结束"
 
-#: sequencer.c:2207
+#: sequencer.c:2430
 #, c-format
 msgid "stored pre-cherry-pick HEAD file '%s' is corrupt"
 msgstr "保存拣选提交前的 HEAD 文件 '%s' 损坏"
 
-#: sequencer.c:2218
+#: sequencer.c:2441
 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!"
 msgstr "您好像移动了 HEAD。未能回退,检查您的 HEAD!"
 
-#: sequencer.c:2324 sequencer.c:2679
+#: sequencer.c:2545 sequencer.c:3321
 #, c-format
 msgid "could not update %s"
 msgstr "不能更新 %s"
 
-#: sequencer.c:2362 sequencer.c:2659
+#: sequencer.c:2583 sequencer.c:3301
 msgid "cannot read HEAD"
 msgstr "不能读取 HEAD"
 
-#: sequencer.c:2402 builtin/difftool.c:639
+#: sequencer.c:2618 sequencer.c:2622 builtin/difftool.c:639
 #, c-format
 msgid "could not copy '%s' to '%s'"
 msgstr "不能拷贝 '%s' 至 '%s'"
 
-#: sequencer.c:2421
+#: sequencer.c:2641
 msgid "could not read index"
 msgstr "不能读取索引"
 
 #  译者:注意保持前导空格
-#: sequencer.c:2426
+#: sequencer.c:2646
 #, c-format
 msgid ""
 "execution failed: %s\n"
@@ -3604,11 +3882,11 @@ msgstr ""
 "  git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2432
+#: sequencer.c:2652
 msgid "and made changes to the index and/or the working tree\n"
 msgstr "并且修改索引和/或工作区\n"
 
-#: sequencer.c:2438
+#: sequencer.c:2658
 #, c-format
 msgid ""
 "execution succeeded: %s\n"
@@ -3625,17 +3903,62 @@ msgstr ""
 "  git rebase --continue\n"
 "\n"
 
-#: sequencer.c:2497
+#: sequencer.c:2771
+msgid "writing fake root commit"
+msgstr "写伪根提交"
+
+#: sequencer.c:2776
+msgid "writing squash-onto"
+msgstr "写入 squash-onto"
+
+#: sequencer.c:2811
+#, c-format
+msgid "failed to find tree of %s"
+msgstr "无法找到 %s 指向的树。"
+
+#: sequencer.c:2829
+msgid "could not write index"
+msgstr "不能写入索引"
+
+#: sequencer.c:2861
+msgid "cannot merge without a current revision"
+msgstr "没有当前版本不能合并"
+
+#: sequencer.c:2884
+#, c-format
+msgid "could not resolve '%s'"
+msgstr "无法解析 '%s'"
+
+#: sequencer.c:2906
+#, c-format
+msgid "could not get commit message of '%s'"
+msgstr "不能获取 '%s' 的提交说明"
+
+#: sequencer.c:2916 sequencer.c:2941
+#, c-format
+msgid "could not write '%s'"
+msgstr "不能写入 '%s'"
+
+#: sequencer.c:3005
+#, c-format
+msgid "could not even attempt to merge '%.*s'"
+msgstr "甚至不能尝试合并 '%.*s'"
+
+#: sequencer.c:3021
+msgid "merge: Unable to write new index file"
+msgstr "合并:无法写入新索引文件"
+
+#: sequencer.c:3088
 #, c-format
 msgid "Applied autostash.\n"
 msgstr "已应用 autostash。\n"
 
-#: sequencer.c:2509
+#: sequencer.c:3100
 #, c-format
 msgid "cannot store %s"
 msgstr "不能存储 %s"
 
-#: sequencer.c:2512 git-rebase.sh:178
+#: sequencer.c:3103 git-rebase.sh:188
 #, c-format
 msgid ""
 "Applying autostash resulted in conflicts.\n"
@@ -3646,52 +3969,68 @@ msgstr ""
 "您的修改安全地保存在贮藏区中。\n"
 "您可以在任何时候运行 \"git stash pop\" 或 \"git stash drop\"。\n"
 
-#: sequencer.c:2595
+#: sequencer.c:3134
+#, c-format
+msgid ""
+"Could not execute the todo command\n"
+"\n"
+"    %.*s\n"
+"It has been rescheduled; To edit the command before continuing, please\n"
+"edit the todo list first:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+msgstr ""
+"无法执行待办命令\n"
+"\n"
+"    %.*s\n"
+"已被重新安排,在继续之前编辑命令,请先编辑待办列表:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n"
+
+#: sequencer.c:3202
 #, c-format
 msgid "Stopped at %s...  %.*s\n"
 msgstr "停止在 %s... %.*s\n"
 
-#: sequencer.c:2637
+#: sequencer.c:3264
 #, c-format
 msgid "unknown command %d"
 msgstr "未知命令 %d"
 
-#: sequencer.c:2667
+#: sequencer.c:3309
 msgid "could not read orig-head"
 msgstr "不能读取 orig-head"
 
-#: sequencer.c:2672 sequencer.c:3262
+#: sequencer.c:3314 sequencer.c:4352
 msgid "could not read 'onto'"
 msgstr "不能读取 'onto'"
 
-#: sequencer.c:2686
+#: sequencer.c:3328
 #, c-format
 msgid "could not update HEAD to %s"
 msgstr "不能更新 HEAD 为 %s"
 
-#: sequencer.c:2770
+#: sequencer.c:3414
 msgid "cannot rebase: You have unstaged changes."
 msgstr "不能变基:您有未暂存的变更。"
 
-#: sequencer.c:2775
-msgid "could not remove CHERRY_PICK_HEAD"
-msgstr "不能删除 CHERRY_PICK_HEAD"
-
-#: sequencer.c:2784
+#: sequencer.c:3423
 msgid "cannot amend non-existing commit"
 msgstr "不能修补不存在的提交"
 
-#: sequencer.c:2786
+#: sequencer.c:3425
 #, c-format
 msgid "invalid file: '%s'"
 msgstr "无效文件:'%s'"
 
-#: sequencer.c:2788
+#: sequencer.c:3427
 #, c-format
 msgid "invalid contents: '%s'"
 msgstr "无效内容:'%s'"
 
-#: sequencer.c:2791
+#: sequencer.c:3430
 msgid ""
 "\n"
 "You have uncommitted changes in your working tree. Please, commit them\n"
@@ -3700,44 +4039,53 @@ msgstr ""
 "\n"
 "您的工作区中有未提交的变更。请先提交然后再次运行 'git rebase --continue'。"
 
-#: sequencer.c:2801
+#: sequencer.c:3455 sequencer.c:3493
+#, c-format
+msgid "could not write file: '%s'"
+msgstr "不能写入文件:'%s'"
+
+#: sequencer.c:3508
+msgid "could not remove CHERRY_PICK_HEAD"
+msgstr "不能删除 CHERRY_PICK_HEAD"
+
+#: sequencer.c:3515
 msgid "could not commit staged changes."
 msgstr "不能提交暂存的修改。"
 
-#: sequencer.c:2881
+#: sequencer.c:3612
 #, c-format
 msgid "%s: can't cherry-pick a %s"
 msgstr "%s:不能拣选一个%s"
 
-#: sequencer.c:2885
+#: sequencer.c:3616
 #, c-format
 msgid "%s: bad revision"
 msgstr "%s:错误的版本"
 
-#: sequencer.c:2918
+#: sequencer.c:3649
 msgid "can't revert as initial commit"
 msgstr "不能作为初始提交回退"
 
-#: sequencer.c:3023
+#: sequencer.c:4098
 msgid "make_script: unhandled options"
 msgstr "make_script:有未能处理的选项"
 
-#: sequencer.c:3026
+#: sequencer.c:4101
 msgid "make_script: error preparing revisions"
 msgstr "make_script:准备版本时错误"
 
-#: sequencer.c:3060 sequencer.c:3095
+#: sequencer.c:4142 sequencer.c:4177
 #, c-format
 msgid "unusable todo list: '%s'"
 msgstr "不可用的待办列表:'%s'"
 
-#: sequencer.c:3146
+#: sequencer.c:4236
 #, c-format
 msgid ""
 "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring."
 msgstr "选项 rebase.missingCommitsCheck 的值 %s 无法识别。已忽略。"
 
-#: sequencer.c:3212
+#: sequencer.c:4302
 #, c-format
 msgid ""
 "Warning: some commits may have been dropped accidentally.\n"
@@ -3746,7 +4094,7 @@ msgstr ""
 "警告:一些提交可能被意外丢弃。\n"
 "丢弃的提交(从新到旧):\n"
 
-#: sequencer.c:3219
+#: sequencer.c:4309
 #, c-format
 msgid ""
 "To avoid this message, use \"drop\" to explicitly remove a commit.\n"
@@ -3762,7 +4110,7 @@ msgstr ""
 "可选值有:ignore、warn、error。\n"
 "\n"
 
-#: sequencer.c:3231
+#: sequencer.c:4321
 #, c-format
 msgid ""
 "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --"
@@ -3772,27 +4120,21 @@ msgstr ""
 "您可以用 'git rebase --edit-todo' 修正,然后执行 'git rebase --continue'。\n"
 "或者您可以用 'git rebase --abort' 终止变基。\n"
 
-#: sequencer.c:3244 sequencer.c:3304 wrapper.c:225 wrapper.c:395
-#: builtin/am.c:779
-#, c-format
-msgid "could not open '%s' for writing"
-msgstr "无法打开 '%s' 进行写入"
-
-#: sequencer.c:3285
+#: sequencer.c:4375
 #, c-format
 msgid "could not parse commit '%s'"
 msgstr "不能解析提交 '%s'"
 
-#: sequencer.c:3401
+#: sequencer.c:4490
 msgid "the script was already rearranged."
 msgstr "脚本已经重新编排。"
 
-#: setup.c:122
+#: setup.c:123
 #, c-format
 msgid "'%s' is outside repository"
 msgstr "'%s' 在仓库之外"
 
-#: setup.c:171
+#: setup.c:172
 #, c-format
 msgid ""
 "%s: no such path in the working tree.\n"
@@ -3801,7 +4143,7 @@ msgstr ""
 "%s:工作区中无此路径。\n"
 "使用命令 'git <命令> -- <路径>...' 来指定本地不存在的路径。"
 
-#: setup.c:184
+#: setup.c:185
 #, c-format
 msgid ""
 "ambiguous argument '%s': unknown revision or path not in the working tree.\n"
@@ -3812,12 +4154,12 @@ msgstr ""
 "使用 '--' 来分隔版本和路径,例如:\n"
 "'git <命令> [<版本>...] -- [<文件>...]'"
 
-#: setup.c:233
+#: setup.c:234
 #, c-format
 msgid "option '%s' must come before non-option arguments"
 msgstr "选项 '%s' 必须在其他非选项参数之前"
 
-#: setup.c:252
+#: setup.c:253
 #, c-format
 msgid ""
 "ambiguous argument '%s': both revision and filename\n"
@@ -3828,92 +4170,92 @@ msgstr ""
 "使用 '--' 来分隔版本和路径,例如:\n"
 "'git <命令> [<版本>...] -- [<文件>...]'"
 
-#: setup.c:388
+#: setup.c:389
 msgid "unable to set up work tree using invalid config"
 msgstr "无法使用无效配置来创建工作区"
 
-#: setup.c:395
+#: setup.c:393
 msgid "this operation must be run in a work tree"
 msgstr "该操作必须在一个工作区中运行"
 
-#: setup.c:506
+#: setup.c:503
 #, c-format
 msgid "Expected git repo version <= %d, found %d"
 msgstr "期望 git 仓库版本 <= %d,却得到 %d"
 
-#: setup.c:514
+#: setup.c:511
 msgid "unknown repository extensions found:"
 msgstr "发现未知的仓库扩展:"
 
-#: setup.c:533
+#: setup.c:530
 #, c-format
 msgid "error opening '%s'"
 msgstr "无法打开 '%s'"
 
-#: setup.c:535
+#: setup.c:532
 #, c-format
 msgid "too large to be a .git file: '%s'"
 msgstr "文件太大,无法作为 .git 文件:'%s'"
 
-#: setup.c:537
+#: setup.c:534
 #, c-format
 msgid "error reading %s"
 msgstr "无法读取 %s"
 
-#: setup.c:539
+#: setup.c:536
 #, c-format
 msgid "invalid gitfile format: %s"
 msgstr "无效的 gitfile 格式:%s"
 
-#: setup.c:541
+#: setup.c:538
 #, c-format
 msgid "no path in gitfile: %s"
 msgstr "在 gitfile 中没有路径:%s"
 
-#: setup.c:543
+#: setup.c:540
 #, c-format
 msgid "not a git repository: %s"
 msgstr "不是一个 git 仓库:%s"
 
-#: setup.c:642
+#: setup.c:639
 #, c-format
 msgid "'$%s' too big"
 msgstr "'$%s' 太大"
 
-#: setup.c:656
+#: setup.c:653
 #, c-format
 msgid "not a git repository: '%s'"
 msgstr "不是一个 git 仓库:'%s'"
 
-#: setup.c:685 setup.c:687 setup.c:718
+#: setup.c:682 setup.c:684 setup.c:715
 #, c-format
 msgid "cannot chdir to '%s'"
 msgstr "不能切换目录到 '%s'"
 
-#: setup.c:690 setup.c:746 setup.c:756 setup.c:795 setup.c:803 setup.c:818
+#: setup.c:687 setup.c:743 setup.c:753 setup.c:792 setup.c:800 setup.c:815
 msgid "cannot come back to cwd"
 msgstr "无法返回当前工作目录"
 
-#: setup.c:816
+#: setup.c:813
 #, c-format
 msgid "not a git repository (or any of the parent directories): %s"
 msgstr "不是一个 git 仓库(或者任何父目录):%s"
 
-#: setup.c:827
+#: setup.c:824
 #, c-format
 msgid "failed to stat '%*s%s%s'"
 msgstr "无法获取 '%*s%s%s' 状态(stat)"
 
-#: setup.c:1057
+#: setup.c:1054
 msgid "Unable to read current working directory"
 msgstr "不能读取当前工作目录"
 
-#: setup.c:1069 setup.c:1075
+#: setup.c:1066 setup.c:1072
 #, c-format
 msgid "cannot change to '%s'"
 msgstr "不能切换到 '%s'"
 
-#: setup.c:1088
+#: setup.c:1085
 #, c-format
 msgid ""
 "not a git repository (or any parent up to mount point %s)\n"
@@ -3922,7 +4264,7 @@ msgstr ""
 "不是一个 git 仓库(或者直至挂载点 %s 的任何父目录)\n"
 "停止在文件系统边界(未设置 GIT_DISCOVERY_ACROSS_FILESYSTEM)。"
 
-#: setup.c:1172
+#: setup.c:1168
 #, c-format
 msgid ""
 "problem with core.sharedRepository filemode value (0%.3o).\n"
@@ -3931,53 +4273,53 @@ msgstr ""
 "参数 core.sharedRepository 的文件属性值有问题(0%.3o)。\n"
 "文件属主必须始终拥有读写权限。"
 
-#: setup.c:1215
+#: setup.c:1211
 msgid "open /dev/null or dup failed"
 msgstr "不能打开或者复制 /dev/null"
 
-#: setup.c:1230
+#: setup.c:1226
 msgid "fork failed"
 msgstr "fork 失败"
 
-#: setup.c:1235
+#: setup.c:1231
 msgid "setsid failed"
 msgstr "setsid 失败"
 
-#: sha1_file.c:592
+#: sha1-file.c:625
 #, c-format
 msgid "path '%s' does not exist"
 msgstr "路径 '%s' 不存在"
 
-#: sha1_file.c:618
+#: sha1-file.c:651
 #, c-format
 msgid "reference repository '%s' as a linked checkout is not supported yet."
 msgstr "尚不支持将参考仓库 '%s' 作为一个链接检出。"
 
-#: sha1_file.c:624
+#: sha1-file.c:657
 #, c-format
 msgid "reference repository '%s' is not a local repository."
 msgstr "参考仓库 '%s' 不是一个本地仓库。"
 
-#: sha1_file.c:630
+#: sha1-file.c:663
 #, c-format
 msgid "reference repository '%s' is shallow"
 msgstr "参考仓库 '%s' 是一个浅克隆"
 
-#: sha1_file.c:638
+#: sha1-file.c:671
 #, c-format
 msgid "reference repository '%s' is grafted"
-msgstr "参考仓库 '%s' 已被嫁接"
+msgstr "参考仓库 '%s' 已被移植"
 
-#: sha1_name.c:422
+#: sha1-name.c:442
 #, c-format
 msgid "short SHA1 %s is ambiguous"
 msgstr "短 SHA1 %s 存在歧义"
 
-#: sha1_name.c:433
+#: sha1-name.c:453
 msgid "The candidates are:"
 msgstr "候选者有:"
 
-#: sha1_name.c:693
+#: sha1-name.c:695
 msgid ""
 "Git normally never creates a ref that ends with 40 hex characters\n"
 "because it will be ignored when you just specify 40-hex. These refs\n"
@@ -3998,86 +4340,86 @@ msgstr ""
 "可能需要删除它们。用 \"git config advice.objectNameWarning false\"\n"
 "命令关闭本消息通知。"
 
-#: submodule.c:96 submodule.c:130
+#: submodule.c:97 submodule.c:131
 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first"
 msgstr "无法修改未合并的 .gitmodules,先解决合并冲突"
 
-#: submodule.c:100 submodule.c:134
+#: submodule.c:101 submodule.c:135
 #, c-format
 msgid "Could not find section in .gitmodules where path=%s"
 msgstr "无法在 .gitmodules 中找到 path=%s 的小节"
 
-#: submodule.c:108
+#: submodule.c:109
 #, c-format
 msgid "Could not update .gitmodules entry %s"
 msgstr "不能更新 .gitmodules 条目 %s"
 
-#: submodule.c:141
+#: submodule.c:142
 #, c-format
 msgid "Could not remove .gitmodules entry for %s"
 msgstr "无法移除 %s 的 .gitmodules 条目"
 
-#: submodule.c:152
+#: submodule.c:153
 msgid "staging updated .gitmodules failed"
 msgstr "将更新后 .gitmodules 添加暂存区失败"
 
-#: submodule.c:312
+#: submodule.c:315
 #, c-format
 msgid "in unpopulated submodule '%s'"
 msgstr "位于未检出的子模组 '%s'"
 
-#: submodule.c:343
+#: submodule.c:346
 #, c-format
 msgid "Pathspec '%s' is in submodule '%.*s'"
 msgstr "路径规格 '%s' 在子模组 '%.*s' 中"
 
-#: submodule.c:833
+#: submodule.c:837
 #, c-format
 msgid "submodule entry '%s' (%s) is a %s, not a commit"
 msgstr "子模组条目 '%s'(%s)是一个 %s,不是一个提交"
 
-#: submodule.c:1065 builtin/branch.c:648 builtin/submodule--helper.c:1724
+#: submodule.c:1069 builtin/branch.c:651 builtin/submodule--helper.c:1743
 msgid "Failed to resolve HEAD as a valid ref."
 msgstr "无法将 HEAD 解析为有效引用。"
 
-#: submodule.c:1370
+#: submodule.c:1375
 #, c-format
 msgid "'%s' not recognized as a git repository"
 msgstr "无法将 '%s' 识别为一个 git 仓库"
 
-#: submodule.c:1508
+#: submodule.c:1513
 #, c-format
 msgid "could not start 'git status' in submodule '%s'"
 msgstr "无法在子模组 '%s' 中启动 'git status'"
 
-#: submodule.c:1521
+#: submodule.c:1526
 #, c-format
 msgid "could not run 'git status' in submodule '%s'"
 msgstr "无法在子模组 '%s' 中执行 'git status'"
 
-#: submodule.c:1614
+#: submodule.c:1619
 #, c-format
 msgid "submodule '%s' has dirty index"
 msgstr "子模组 '%s' 中有脏索引"
 
-#: submodule.c:1878
+#: submodule.c:1718
 #, c-format
 msgid ""
 "relocate_gitdir for submodule '%s' with more than one worktree not supported"
 msgstr "不支持对有多个工作区的子模组 '%s' 执行 relocate_gitdir"
 
-#: submodule.c:1890 submodule.c:1946
+#: submodule.c:1730 submodule.c:1786
 #, c-format
 msgid "could not lookup name for submodule '%s'"
 msgstr "不能查询子模组 '%s' 的名称"
 
-#: submodule.c:1894 builtin/submodule--helper.c:1246
-#: builtin/submodule--helper.c:1256
+#: submodule.c:1734 builtin/submodule--helper.c:1261
+#: builtin/submodule--helper.c:1271
 #, c-format
 msgid "could not create directory '%s'"
 msgstr "不能创建目录 '%s'"
 
-#: submodule.c:1897
+#: submodule.c:1737
 #, c-format
 msgid ""
 "Migrating git directory of '%s%s' from\n"
@@ -4088,29 +4430,30 @@ msgstr ""
 "'%s' 迁移至\n"
 "'%s'\n"
 
-#: submodule.c:1981
+#: submodule.c:1821
 #, c-format
 msgid "could not recurse into submodule '%s'"
 msgstr "无法递归进子模组路径 '%s'"
 
-#: submodule.c:2025
+#: submodule.c:1865
 msgid "could not start ls-files in .."
 msgstr "无法在 .. 中启动 ls-files"
 
-#: submodule.c:2045
-msgid "BUG: returned path string doesn't match cwd?"
-msgstr "BUG:返回的路径和当前路径不匹配?"
-
-#: submodule.c:2064
+#: submodule.c:1904
 #, c-format
 msgid "ls-tree returned unexpected return code %d"
 msgstr "ls-tree 返回未知返回值 %d"
 
-#: submodule-config.c:263
+#: submodule-config.c:230
+#, c-format
+msgid "ignoring suspicious submodule name: %s"
+msgstr "忽略可疑的子模组名称:%s"
+
+#: submodule-config.c:294
 msgid "negative values not allowed for submodule.fetchjobs"
 msgstr "submodule.fetchjobs 不允许为负值"
 
-#: submodule-config.c:436
+#: submodule-config.c:467
 #, c-format
 msgid "invalid value for %s"
 msgstr "%s 的值无效"
@@ -4126,7 +4469,7 @@ msgstr "执行 trailer 命令 '%s' 失败"
 msgid "unknown value '%s' for key '%s'"
 msgstr "键 '%2$s' 的未知取值 '%1$s'"
 
-#: trailer.c:539 trailer.c:544 builtin/remote.c:290
+#: trailer.c:539 trailer.c:544 builtin/remote.c:293
 #, c-format
 msgid "more than one %s"
 msgstr "多于一个 %s"
@@ -4169,24 +4512,28 @@ msgstr "不能打开临时文件"
 msgid "could not rename temporary file to %s"
 msgstr "不能重命名临时文件为 %s"
 
-#: transport.c:63
+#: transport.c:116
 #, c-format
 msgid "Would set upstream of '%s' to '%s' of '%s'\n"
 msgstr "将要设置 '%1$s' 的上游为 '%3$s' 的 '%2$s'\n"
 
-#: transport.c:152
+#: transport.c:208
 #, c-format
 msgid "transport: invalid depth option '%s'"
 msgstr "传输:无效的深度选项 '%s'"
 
-#: transport.c:916
+#: transport.c:584
+msgid "could not parse transport.color.* config"
+msgstr "不能解析 transport.color.* 配置"
+
+#: transport.c:996
 #, c-format
 msgid ""
 "The following submodule paths contain changes that can\n"
 "not be found on any remote:\n"
 msgstr "下列子模组路径所包含的修改在任何远程源中都找不到:\n"
 
-#: transport.c:920
+#: transport.c:1000
 #, c-format
 msgid ""
 "\n"
@@ -4213,11 +4560,11 @@ msgstr ""
 "以推送至远程。\n"
 "\n"
 
-#: transport.c:928
+#: transport.c:1008
 msgid "Aborting."
 msgstr "正在终止。"
 
-#: transport-helper.c:1079
+#: transport-helper.c:1087
 #, c-format
 msgid "Could not read ref %s"
 msgstr "不能读取引用 %s"
@@ -4234,11 +4581,11 @@ msgstr "树对象中的条目模式错误"
 msgid "empty filename in tree entry"
 msgstr "树对象条目中空的文件名"
 
-#: tree-walk.c:114
+#: tree-walk.c:113
 msgid "too-short tree file"
 msgstr "太短的树文件"
 
-#: unpack-trees.c:108
+#: unpack-trees.c:111
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4247,7 +4594,7 @@ msgstr ""
 "您对下列文件的本地修改将被检出操作覆盖:\n"
 "%%s请在切换分支前提交或贮藏您的修改。"
 
-#: unpack-trees.c:110
+#: unpack-trees.c:113
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by checkout:\n"
@@ -4256,7 +4603,7 @@ msgstr ""
 "您对下列文件的本地修改将被检出操作覆盖:\n"
 "%%s"
 
-#: unpack-trees.c:113
+#: unpack-trees.c:116
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4265,7 +4612,7 @@ msgstr ""
 "您对下列文件的本地修改将被合并操作覆盖:\n"
 "%%s请在合并前提交或贮藏您的修改。"
 
-#: unpack-trees.c:115
+#: unpack-trees.c:118
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by merge:\n"
@@ -4274,7 +4621,7 @@ msgstr ""
 "您对下列文件的本地修改将被合并操作覆盖:\n"
 "%%s"
 
-#: unpack-trees.c:118
+#: unpack-trees.c:121
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4283,7 +4630,7 @@ msgstr ""
 "您对下列文件的本地修改将被 %s 覆盖:\n"
 "%%s请在 %s 之前提交或贮藏您的修改。"
 
-#: unpack-trees.c:120
+#: unpack-trees.c:123
 #, c-format
 msgid ""
 "Your local changes to the following files would be overwritten by %s:\n"
@@ -4292,7 +4639,7 @@ msgstr ""
 "您对下列文件的本地修改将被 %s 覆盖:\n"
 "%%s"
 
-#: unpack-trees.c:125
+#: unpack-trees.c:128
 #, c-format
 msgid ""
 "Updating the following directories would lose untracked files in them:\n"
@@ -4301,7 +4648,7 @@ msgstr ""
 "更新如下目录将会丢失其中未跟踪的文件:\n"
 "%s"
 
-#: unpack-trees.c:129
+#: unpack-trees.c:132
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4310,7 +4657,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为检出操作而被删除:\n"
 "%%s请在切换分支之前移动或删除。"
 
-#: unpack-trees.c:131
+#: unpack-trees.c:134
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by checkout:\n"
@@ -4319,7 +4666,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为检出操作而被删除:\n"
 "%%s"
 
-#: unpack-trees.c:134
+#: unpack-trees.c:137
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4328,7 +4675,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为合并操作而被删除:\n"
 "%%s请在合并前移动或删除。"
 
-#: unpack-trees.c:136
+#: unpack-trees.c:139
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by merge:\n"
@@ -4337,7 +4684,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为合并操作而被删除:\n"
 "%%s"
 
-#: unpack-trees.c:139
+#: unpack-trees.c:142
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4346,7 +4693,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为 %s 操作而被删除:\n"
 "%%s请在 %s 前移动或删除。"
 
-#: unpack-trees.c:141
+#: unpack-trees.c:144
 #, c-format
 msgid ""
 "The following untracked working tree files would be removed by %s:\n"
@@ -4355,7 +4702,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为 %s 操作而被删除:\n"
 "%%s"
 
-#: unpack-trees.c:146
+#: unpack-trees.c:150
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4365,7 +4712,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为检出操作而被覆盖:\n"
 "%%s请在切换分支前移动或删除。"
 
-#: unpack-trees.c:148
+#: unpack-trees.c:152
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by "
@@ -4375,7 +4722,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为检出操作而被覆盖:\n"
 "%%s"
 
-#: unpack-trees.c:151
+#: unpack-trees.c:155
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4384,7 +4731,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为合并操作而被覆盖:\n"
 "%%s请在合并前移动或删除。"
 
-#: unpack-trees.c:153
+#: unpack-trees.c:157
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by merge:\n"
@@ -4393,7 +4740,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为合并操作而被覆盖:\n"
 "%%s"
 
-#: unpack-trees.c:156
+#: unpack-trees.c:160
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4402,7 +4749,7 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为 %s 操作而被覆盖:\n"
 "%%s请在 %s 前移动或删除。"
 
-#: unpack-trees.c:158
+#: unpack-trees.c:162
 #, c-format
 msgid ""
 "The following untracked working tree files would be overwritten by %s:\n"
@@ -4411,12 +4758,12 @@ msgstr ""
 "工作区中下列未跟踪的文件将会因为 %s 操作而被覆盖:\n"
 "%%s"
 
-#: unpack-trees.c:165
+#: unpack-trees.c:170
 #, c-format
 msgid "Entry '%s' overlaps with '%s'.  Cannot bind."
 msgstr "条目 '%s' 和 '%s' 重叠。无法合并。"
 
-#: unpack-trees.c:168
+#: unpack-trees.c:173
 #, c-format
 msgid ""
 "Cannot update sparse checkout: the following entries are not up to date:\n"
@@ -4425,7 +4772,7 @@ msgstr ""
 "无法更新稀疏检出:如下条目不是最新:\n"
 "%s"
 
-#: unpack-trees.c:170
+#: unpack-trees.c:175
 #, c-format
 msgid ""
 "The following working tree files would be overwritten by sparse checkout "
@@ -4435,7 +4782,7 @@ msgstr ""
 "工作区中下列文件将被稀疏检出更新所覆盖:\n"
 "%s"
 
-#: unpack-trees.c:172
+#: unpack-trees.c:177
 #, c-format
 msgid ""
 "The following working tree files would be removed by sparse checkout "
@@ -4445,7 +4792,7 @@ msgstr ""
 "工作区中下列文件将被稀疏检出更新所删除:\n"
 "%s"
 
-#: unpack-trees.c:174
+#: unpack-trees.c:179
 #, c-format
 msgid ""
 "Cannot update submodule:\n"
@@ -4454,12 +4801,12 @@ msgstr ""
 "无法更新子模组:\n"
 "%s"
 
-#: unpack-trees.c:251
+#: unpack-trees.c:262
 #, c-format
 msgid "Aborting\n"
 msgstr "终止中\n"
 
-#: unpack-trees.c:333
+#: unpack-trees.c:344
 msgid "Checking out files"
 msgstr "正在检出文件"
 
@@ -4528,7 +4875,7 @@ msgid "could not open '%s' for reading and writing"
 msgstr "无法打开 '%s' 进行读写"
 
 #: wrapper.c:227 wrapper.c:397 builtin/am.c:320 builtin/am.c:770
-#: builtin/am.c:862 builtin/merge.c:1044
+#: builtin/am.c:862 builtin/merge.c:1043
 #, c-format
 msgid "could not open '%s' for reading"
 msgstr "无法打开 '%s' 进行读取"
@@ -4542,162 +4889,162 @@ msgstr "不能访问 '%s'"
 msgid "unable to get current working directory"
 msgstr "不能获取当前工作目录"
 
-#: wt-status.c:151
+#: wt-status.c:154
 msgid "Unmerged paths:"
 msgstr "未合并的路径:"
 
 #  译者:注意保持前导空格
-#: wt-status.c:178 wt-status.c:205
+#: wt-status.c:181 wt-status.c:208
 #, c-format
 msgid "  (use \"git reset %s <file>...\" to unstage)"
 msgstr "  (使用 \"git reset %s <文件>...\" 以取消暂存)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:180 wt-status.c:207
+#: wt-status.c:183 wt-status.c:210
 msgid "  (use \"git rm --cached <file>...\" to unstage)"
 msgstr "  (使用 \"git rm --cached <文件>...\" 以取消暂存)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:184
+#: wt-status.c:187
 msgid "  (use \"git add <file>...\" to mark resolution)"
 msgstr "  (使用 \"git add <文件>...\" 标记解决方案)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:186 wt-status.c:190
+#: wt-status.c:189 wt-status.c:193
 msgid "  (use \"git add/rm <file>...\" as appropriate to mark resolution)"
 msgstr "  (酌情使用 \"git add/rm <文件>...\" 标记解决方案)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:188
+#: wt-status.c:191
 msgid "  (use \"git rm <file>...\" to mark resolution)"
 msgstr "  (使用 \"git rm <文件>...\" 标记解决方案)"
 
-#: wt-status.c:199 wt-status.c:1007
+#: wt-status.c:202 wt-status.c:1015
 msgid "Changes to be committed:"
 msgstr "要提交的变更:"
 
-#: wt-status.c:217 wt-status.c:1016
+#: wt-status.c:220 wt-status.c:1024
 msgid "Changes not staged for commit:"
 msgstr "尚未暂存以备提交的变更:"
 
 #  译者:注意保持前导空格
-#: wt-status.c:221
+#: wt-status.c:224
 msgid "  (use \"git add <file>...\" to update what will be committed)"
 msgstr "  (使用 \"git add <文件>...\" 更新要提交的内容)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:223
+#: wt-status.c:226
 msgid "  (use \"git add/rm <file>...\" to update what will be committed)"
 msgstr "  (使用 \"git add/rm <文件>...\" 更新要提交的内容)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:224
+#: wt-status.c:227
 msgid ""
 "  (use \"git checkout -- <file>...\" to discard changes in working directory)"
 msgstr "  (使用 \"git checkout -- <文件>...\" 丢弃工作区的改动)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:226
+#: wt-status.c:229
 msgid "  (commit or discard the untracked or modified content in submodules)"
 msgstr "  (提交或丢弃子模组中未跟踪或修改的内容)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:238
+#: wt-status.c:241
 #, c-format
 msgid "  (use \"git %s <file>...\" to include in what will be committed)"
 msgstr "  (使用 \"git %s <文件>...\" 以包含要提交的内容)"
 
-#: wt-status.c:253
+#: wt-status.c:256
 msgid "both deleted:"
 msgstr "双方删除:"
 
-#: wt-status.c:255
+#: wt-status.c:258
 msgid "added by us:"
 msgstr "由我们添加:"
 
-#: wt-status.c:257
+#: wt-status.c:260
 msgid "deleted by them:"
 msgstr "由他们删除:"
 
-#: wt-status.c:259
+#: wt-status.c:262
 msgid "added by them:"
 msgstr "由他们添加:"
 
-#: wt-status.c:261
+#: wt-status.c:264
 msgid "deleted by us:"
 msgstr "由我们删除:"
 
-#: wt-status.c:263
+#: wt-status.c:266
 msgid "both added:"
 msgstr "双方添加:"
 
-#: wt-status.c:265
+#: wt-status.c:268
 msgid "both modified:"
 msgstr "双方修改:"
 
-#: wt-status.c:275
+#: wt-status.c:278
 msgid "new file:"
 msgstr "新文件:"
 
-#: wt-status.c:277
+#: wt-status.c:280
 msgid "copied:"
 msgstr "拷贝:"
 
-#: wt-status.c:279
+#: wt-status.c:282
 msgid "deleted:"
 msgstr "删除:"
 
-#: wt-status.c:281
+#: wt-status.c:284
 msgid "modified:"
 msgstr "修改:"
 
-#: wt-status.c:283
+#: wt-status.c:286
 msgid "renamed:"
 msgstr "重命名:"
 
-#: wt-status.c:285
+#: wt-status.c:288
 msgid "typechange:"
 msgstr "类型变更:"
 
-#: wt-status.c:287
+#: wt-status.c:290
 msgid "unknown:"
 msgstr "未知:"
 
-#: wt-status.c:289
+#: wt-status.c:292
 msgid "unmerged:"
 msgstr "未合并:"
 
 #  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:369
+#: wt-status.c:372
 msgid "new commits, "
 msgstr "新提交, "
 
 #  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:371
+#: wt-status.c:374
 msgid "modified content, "
 msgstr "修改的内容, "
 
 #  译者:末尾两个字节可能被删减,如果翻译为中文标点会出现半个汉字
-#: wt-status.c:373
+#: wt-status.c:376
 msgid "untracked content, "
 msgstr "未跟踪的内容, "
 
-#: wt-status.c:847
+#: wt-status.c:853
 #, c-format
 msgid "Your stash currently has %d entry"
 msgid_plural "Your stash currently has %d entries"
 msgstr[0] "您的贮藏区当前有 %d 条记录"
 msgstr[1] "您的贮藏区当前有 %d 条记录"
 
-#: wt-status.c:879
+#: wt-status.c:885
 msgid "Submodules changed but not updated:"
 msgstr "子模组已修改但尚未更新:"
 
-#: wt-status.c:881
+#: wt-status.c:887
 msgid "Submodule changes to be committed:"
 msgstr "要提交的子模组变更:"
 
-#: wt-status.c:963
+#: wt-status.c:969
 msgid ""
 "Do not modify or remove the line above.\n"
 "Everything below it will be ignored."
@@ -4705,77 +5052,77 @@ msgstr ""
 "不要改动或删除上面的一行。\n"
 "其下所有内容都将被忽略。"
 
-#: wt-status.c:1076
+#: wt-status.c:1084
 msgid "You have unmerged paths."
 msgstr "您有尚未合并的路径。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1079
+#: wt-status.c:1087
 msgid "  (fix conflicts and run \"git commit\")"
 msgstr "  (解决冲突并运行 \"git commit\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1081
+#: wt-status.c:1089
 msgid "  (use \"git merge --abort\" to abort the merge)"
 msgstr "  (使用 \"git merge --abort\" 终止合并)"
 
-#: wt-status.c:1086
+#: wt-status.c:1094
 msgid "All conflicts fixed but you are still merging."
 msgstr "所有冲突已解决但您仍处于合并中。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1089
+#: wt-status.c:1097
 msgid "  (use \"git commit\" to conclude merge)"
 msgstr "  (使用 \"git commit\" 结束合并)"
 
-#: wt-status.c:1099
+#: wt-status.c:1107
 msgid "You are in the middle of an am session."
 msgstr "您正处于 am 操作过程中。"
 
-#: wt-status.c:1102
+#: wt-status.c:1110
 msgid "The current patch is empty."
 msgstr "当前的补丁为空。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1106
+#: wt-status.c:1114
 msgid "  (fix conflicts and then run \"git am --continue\")"
 msgstr "  (解决冲突,然后运行 \"git am --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1108
+#: wt-status.c:1116
 msgid "  (use \"git am --skip\" to skip this patch)"
 msgstr "  (使用 \"git am --skip\" 跳过此补丁)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1110
+#: wt-status.c:1118
 msgid "  (use \"git am --abort\" to restore the original branch)"
 msgstr "  (使用 \"git am --abort\" 恢复原有分支)"
 
-#: wt-status.c:1242
+#: wt-status.c:1250
 msgid "git-rebase-todo is missing."
 msgstr "git-rebase-todo 丢失。"
 
-#: wt-status.c:1244
+#: wt-status.c:1252
 msgid "No commands done."
 msgstr "没有命令被执行。"
 
-#: wt-status.c:1247
+#: wt-status.c:1255
 #, c-format
 msgid "Last command done (%d command done):"
 msgid_plural "Last commands done (%d commands done):"
 msgstr[0] "最后一条命令已完成(%d 条命令被执行):"
 msgstr[1] "最后的命令已完成(%d 条命令被执行):"
 
-#: wt-status.c:1258
+#: wt-status.c:1266
 #, c-format
 msgid "  (see more in file %s)"
 msgstr "  (更多参见文件 %s)"
 
-#: wt-status.c:1263
+#: wt-status.c:1271
 msgid "No commands remaining."
 msgstr "未剩下任何命令。"
 
-#: wt-status.c:1266
+#: wt-status.c:1274
 #, c-format
 msgid "Next command to do (%d remaining command):"
 msgid_plural "Next commands to do (%d remaining commands):"
@@ -4783,169 +5130,169 @@ msgstr[0] "接下来要执行的命令(剩余 %d 条命令):"
 msgstr[1] "接下来要执行的命令(剩余 %d 条命令):"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1274
+#: wt-status.c:1282
 msgid "  (use \"git rebase --edit-todo\" to view and edit)"
 msgstr "  (使用 \"git rebase --edit-todo\" 来查看和编辑)"
 
-#: wt-status.c:1287
+#: wt-status.c:1295
 #, c-format
 msgid "You are currently rebasing branch '%s' on '%s'."
 msgstr "您在执行将分支 '%s' 变基到 '%s' 的操作。"
 
-#: wt-status.c:1292
+#: wt-status.c:1300
 msgid "You are currently rebasing."
 msgstr "您在执行变基操作。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1306
+#: wt-status.c:1314
 msgid "  (fix conflicts and then run \"git rebase --continue\")"
 msgstr "  (解决冲突,然后运行 \"git rebase --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1308
+#: wt-status.c:1316
 msgid "  (use \"git rebase --skip\" to skip this patch)"
 msgstr "  (使用 \"git rebase --skip\" 跳过此补丁)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1310
+#: wt-status.c:1318
 msgid "  (use \"git rebase --abort\" to check out the original branch)"
 msgstr "  (使用 \"git rebase --abort\" 以检出原有分支)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1316
+#: wt-status.c:1324
 msgid "  (all conflicts fixed: run \"git rebase --continue\")"
 msgstr "  (所有冲突已解决:运行 \"git rebase --continue\")"
 
-#: wt-status.c:1320
+#: wt-status.c:1328
 #, c-format
 msgid ""
 "You are currently splitting a commit while rebasing branch '%s' on '%s'."
 msgstr "您在执行将分支 '%s' 变基到 '%s' 的操作时拆分提交。"
 
-#: wt-status.c:1325
+#: wt-status.c:1333
 msgid "You are currently splitting a commit during a rebase."
 msgstr "您在执行变基操作时拆分提交。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1328
+#: wt-status.c:1336
 msgid "  (Once your working directory is clean, run \"git rebase --continue\")"
 msgstr "  (一旦您工作目录提交干净后,运行 \"git rebase --continue\")"
 
-#: wt-status.c:1332
+#: wt-status.c:1340
 #, c-format
 msgid "You are currently editing a commit while rebasing branch '%s' on '%s'."
 msgstr "您在执行将分支 '%s' 变基到 '%s' 的操作时编辑提交。"
 
-#: wt-status.c:1337
+#: wt-status.c:1345
 msgid "You are currently editing a commit during a rebase."
 msgstr "您在执行变基操作时编辑提交。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1340
+#: wt-status.c:1348
 msgid "  (use \"git commit --amend\" to amend the current commit)"
 msgstr "  (使用 \"git commit --amend\" 修补当前提交)"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1342
+#: wt-status.c:1350
 msgid ""
 "  (use \"git rebase --continue\" once you are satisfied with your changes)"
 msgstr "  (当您对您的修改满意后执行 \"git rebase --continue\")"
 
-#: wt-status.c:1352
+#: wt-status.c:1360
 #, c-format
 msgid "You are currently cherry-picking commit %s."
 msgstr "您在执行拣选提交 %s 的操作。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1357
+#: wt-status.c:1365
 msgid "  (fix conflicts and run \"git cherry-pick --continue\")"
 msgstr "  (解决冲突并运行 \"git cherry-pick --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1360
+#: wt-status.c:1368
 msgid "  (all conflicts fixed: run \"git cherry-pick --continue\")"
 msgstr "  (所有冲突已解决:运行 \"git cherry-pick --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1362
+#: wt-status.c:1370
 msgid "  (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)"
 msgstr "  (使用 \"git cherry-pick --abort\" 以取消拣选操作)"
 
-#: wt-status.c:1371
+#: wt-status.c:1379
 #, c-format
 msgid "You are currently reverting commit %s."
 msgstr "您在执行反转提交 %s 的操作。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1376
+#: wt-status.c:1384
 msgid "  (fix conflicts and run \"git revert --continue\")"
 msgstr "  (解决冲突并运行 \"git revert --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1379
+#: wt-status.c:1387
 msgid "  (all conflicts fixed: run \"git revert --continue\")"
 msgstr "  (所有冲突已解决:运行 \"git revert --continue\")"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1381
+#: wt-status.c:1389
 msgid "  (use \"git revert --abort\" to cancel the revert operation)"
 msgstr "  (使用 \"git revert --abort\" 以取消反转提交操作)"
 
-#: wt-status.c:1392
+#: wt-status.c:1400
 #, c-format
 msgid "You are currently bisecting, started from branch '%s'."
 msgstr "您在执行从分支 '%s' 开始的二分查找操作。"
 
-#: wt-status.c:1396
+#: wt-status.c:1404
 msgid "You are currently bisecting."
 msgstr "您在执行二分查找操作。"
 
 #  译者:注意保持前导空格
-#: wt-status.c:1399
+#: wt-status.c:1407
 msgid "  (use \"git bisect reset\" to get back to the original branch)"
 msgstr "  (使用 \"git bisect reset\" 以回到原有分支)"
 
-#: wt-status.c:1596
+#: wt-status.c:1604
 msgid "On branch "
 msgstr "位于分支 "
 
-#: wt-status.c:1602
+#: wt-status.c:1610
 msgid "interactive rebase in progress; onto "
 msgstr "交互式变基操作正在进行中;至 "
 
-#: wt-status.c:1604
+#: wt-status.c:1612
 msgid "rebase in progress; onto "
 msgstr "变基操作正在进行中;至 "
 
-#: wt-status.c:1609
+#: wt-status.c:1617
 msgid "HEAD detached at "
 msgstr "头指针分离于 "
 
-#: wt-status.c:1611
+#: wt-status.c:1619
 msgid "HEAD detached from "
 msgstr "头指针分离自 "
 
-#: wt-status.c:1614
+#: wt-status.c:1622
 msgid "Not currently on any branch."
 msgstr "当前不在任何分支上。"
 
-#: wt-status.c:1634
+#: wt-status.c:1642
 msgid "Initial commit"
 msgstr "初始提交"
 
-#: wt-status.c:1635
+#: wt-status.c:1643
 msgid "No commits yet"
 msgstr "尚无提交"
 
-#: wt-status.c:1649
+#: wt-status.c:1657
 msgid "Untracked files"
 msgstr "未跟踪的文件"
 
-#: wt-status.c:1651
+#: wt-status.c:1659
 msgid "Ignored files"
 msgstr "忽略的文件"
 
-#: wt-status.c:1655
+#: wt-status.c:1663
 #, c-format
 msgid ""
 "It took %.2f seconds to enumerate untracked files. 'status -uno'\n"
@@ -4955,102 +5302,102 @@ msgstr ""
 "耗费了 %.2f 秒以枚举未跟踪的文件。'status -uno' 也许能提高速度,\n"
 "但您需要小心不要忘了添加新文件(参见 'git help status')。"
 
-#: wt-status.c:1661
+#: wt-status.c:1669
 #, c-format
 msgid "Untracked files not listed%s"
 msgstr "未跟踪的文件没有列出%s"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1663
+#: wt-status.c:1671
 msgid " (use -u option to show untracked files)"
 msgstr "(使用 -u 参数显示未跟踪的文件)"
 
-#: wt-status.c:1669
+#: wt-status.c:1677
 msgid "No changes"
 msgstr "没有修改"
 
-#: wt-status.c:1674
+#: wt-status.c:1682
 #, c-format
 msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n"
 msgstr "修改尚未加入提交(使用 \"git add\" 和/或 \"git commit -a\")\n"
 
-#: wt-status.c:1677
+#: wt-status.c:1685
 #, c-format
 msgid "no changes added to commit\n"
 msgstr "修改尚未加入提交\n"
 
-#: wt-status.c:1680
+#: wt-status.c:1688
 #, c-format
 msgid ""
 "nothing added to commit but untracked files present (use \"git add\" to "
 "track)\n"
 msgstr "提交为空,但是存在尚未跟踪的文件(使用 \"git add\" 建立跟踪)\n"
 
-#: wt-status.c:1683
+#: wt-status.c:1691
 #, c-format
 msgid "nothing added to commit but untracked files present\n"
 msgstr "提交为空,但是存在尚未跟踪的文件\n"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1686
+#: wt-status.c:1694
 #, c-format
 msgid "nothing to commit (create/copy files and use \"git add\" to track)\n"
 msgstr "无文件要提交(创建/拷贝文件并使用 \"git add\" 建立跟踪)\n"
 
-#: wt-status.c:1689 wt-status.c:1694
+#: wt-status.c:1697 wt-status.c:1702
 #, c-format
 msgid "nothing to commit\n"
 msgstr "无文件要提交\n"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1692
+#: wt-status.c:1700
 #, c-format
 msgid "nothing to commit (use -u to show untracked files)\n"
 msgstr "无文件要提交(使用 -u 显示未跟踪的文件)\n"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: wt-status.c:1696
+#: wt-status.c:1704
 #, c-format
 msgid "nothing to commit, working tree clean\n"
 msgstr "无文件要提交,干净的工作区\n"
 
-#: wt-status.c:1809
+#: wt-status.c:1817
 msgid "No commits yet on "
 msgstr "尚无提交在 "
 
-#: wt-status.c:1813
+#: wt-status.c:1821
 msgid "HEAD (no branch)"
 msgstr "HEAD(非分支)"
 
-#: wt-status.c:1844
+#: wt-status.c:1852
 msgid "different"
 msgstr "不同"
 
 #  译者:注意保持句尾空格
-#: wt-status.c:1846 wt-status.c:1854
+#: wt-status.c:1854 wt-status.c:1862
 msgid "behind "
 msgstr "落后 "
 
-#: wt-status.c:1849 wt-status.c:1852
+#: wt-status.c:1857 wt-status.c:1860
 msgid "ahead "
 msgstr "领先 "
 
 #. TRANSLATORS: the action is e.g. "pull with rebase"
-#: wt-status.c:2358
+#: wt-status.c:2366
 #, c-format
 msgid "cannot %s: You have unstaged changes."
 msgstr "不能%s:您有未暂存的变更。"
 
-#: wt-status.c:2364
+#: wt-status.c:2372
 msgid "additionally, your index contains uncommitted changes."
 msgstr "另外,您的索引中包含未提交的变更。"
 
-#: wt-status.c:2366
+#: wt-status.c:2374
 #, c-format
 msgid "cannot %s: Your index contains uncommitted changes."
 msgstr "不能%s:您的索引中包含未提交的变更。"
 
-#: compat/precompose_utf8.c:58 builtin/clone.c:440
+#: compat/precompose_utf8.c:58 builtin/clone.c:442
 #, c-format
 msgid "failed to unlink '%s'"
 msgstr "无法删除 '%s'"
@@ -5064,7 +5411,7 @@ msgstr "git add [<选项>] [--] <路径规格>..."
 msgid "unexpected diff status %c"
 msgstr "意外的差异状态 %c"
 
-#: builtin/add.c:88 builtin/commit.c:257
+#: builtin/add.c:88 builtin/commit.c:266
 msgid "updating files failed"
 msgstr "更新文件失败"
 
@@ -5077,7 +5424,7 @@ msgstr "删除 '%s'\n"
 msgid "Unstaged changes after refreshing the index:"
 msgstr "刷新索引之后尚未被暂存的变更:"
 
-#: builtin/add.c:233 builtin/rev-parse.c:888
+#: builtin/add.c:233 builtin/rev-parse.c:892
 msgid "Could not read the index"
 msgstr "不能读取索引"
 
@@ -5108,77 +5455,77 @@ msgstr "空补丁。异常终止。"
 msgid "Could not apply '%s'"
 msgstr "不能应用 '%s'"
 
-#: builtin/add.c:271
+#: builtin/add.c:269
 msgid "The following paths are ignored by one of your .gitignore files:\n"
 msgstr "下列路径根据您的一个 .gitignore 文件而被忽略:\n"
 
-#: builtin/add.c:291 builtin/clean.c:911 builtin/fetch.c:146 builtin/mv.c:124
-#: builtin/prune-packed.c:55 builtin/pull.c:207 builtin/push.c:541
-#: builtin/remote.c:1333 builtin/rm.c:242 builtin/send-pack.c:164
+#: builtin/add.c:289 builtin/clean.c:911 builtin/fetch.c:145 builtin/mv.c:123
+#: builtin/prune-packed.c:55 builtin/pull.c:212 builtin/push.c:557
+#: builtin/remote.c:1342 builtin/rm.c:240 builtin/send-pack.c:165
 msgid "dry run"
 msgstr "演习"
 
-#: builtin/add.c:294
+#: builtin/add.c:292
 msgid "interactive picking"
 msgstr "交互式拣选"
 
-#: builtin/add.c:295 builtin/checkout.c:1128 builtin/reset.c:302
+#: builtin/add.c:293 builtin/checkout.c:1135 builtin/reset.c:302
 msgid "select hunks interactively"
 msgstr "交互式挑选数据块"
 
-#: builtin/add.c:296
+#: builtin/add.c:294
 msgid "edit current diff and apply"
 msgstr "编辑当前差异并应用"
 
-#: builtin/add.c:297
+#: builtin/add.c:295
 msgid "allow adding otherwise ignored files"
 msgstr "允许添加忽略的文件"
 
-#: builtin/add.c:298
+#: builtin/add.c:296
 msgid "update tracked files"
 msgstr "更新已跟踪的文件"
 
-#: builtin/add.c:299
+#: builtin/add.c:297
 msgid "renormalize EOL of tracked files (implies -u)"
 msgstr "对已跟踪文件(暗含 -u)重新归一换行符"
 
-#: builtin/add.c:300
+#: builtin/add.c:298
 msgid "record only the fact that the path will be added later"
 msgstr "只记录,该路径稍后再添加"
 
-#: builtin/add.c:301
+#: builtin/add.c:299
 msgid "add changes from all tracked and untracked files"
 msgstr "添加所有改变的已跟踪文件和未跟踪文件"
 
-#: builtin/add.c:304
+#: builtin/add.c:302
 msgid "ignore paths removed in the working tree (same as --no-all)"
 msgstr "忽略工作区中移除的路径(和 --no-all 相同)"
 
-#: builtin/add.c:306
+#: builtin/add.c:304
 msgid "don't add, only refresh the index"
 msgstr "不添加,只刷新索引"
 
-#: builtin/add.c:307
+#: builtin/add.c:305
 msgid "just skip files which cannot be added because of errors"
 msgstr "跳过因出错不能添加的文件"
 
-#: builtin/add.c:308
+#: builtin/add.c:306
 msgid "check if - even missing - files are ignored in dry run"
 msgstr "检查在演习模式下文件(即使不存在)是否被忽略"
 
-#: builtin/add.c:309 builtin/update-index.c:964
+#: builtin/add.c:307 builtin/update-index.c:974
 msgid "(+/-)x"
 msgstr "(+/-)x"
 
-#: builtin/add.c:309 builtin/update-index.c:965
+#: builtin/add.c:307 builtin/update-index.c:975
 msgid "override the executable bit of the listed files"
 msgstr "覆盖列表里文件的可执行位"
 
-#: builtin/add.c:311
+#: builtin/add.c:309
 msgid "warn when adding an embedded repository"
 msgstr "创建一个嵌入式仓库时给予警告"
 
-#: builtin/add.c:326
+#: builtin/add.c:324
 #, c-format
 msgid ""
 "You've added another git repository inside your current repository.\n"
@@ -5207,47 +5554,47 @@ msgstr ""
 "\n"
 "参见 \"git help submodule\" 获取更多信息。"
 
-#: builtin/add.c:354
+#: builtin/add.c:352
 #, c-format
 msgid "adding embedded git repository: %s"
 msgstr "正在添加嵌入式 git 仓库:%s"
 
-#: builtin/add.c:372
+#: builtin/add.c:370
 #, c-format
 msgid "Use -f if you really want to add them.\n"
 msgstr "使用 -f 参数如果您确实要添加它们。\n"
 
-#: builtin/add.c:380
+#: builtin/add.c:378
 msgid "adding files failed"
 msgstr "添加文件失败"
 
-#: builtin/add.c:417
+#: builtin/add.c:416
 msgid "-A and -u are mutually incompatible"
 msgstr "-A 和 -u 选项互斥"
 
-#: builtin/add.c:424
+#: builtin/add.c:423
 msgid "Option --ignore-missing can only be used together with --dry-run"
 msgstr "选项 --ignore-missing 只能和 --dry-run 同时使用"
 
-#: builtin/add.c:428
+#: builtin/add.c:427
 #, c-format
 msgid "--chmod param '%s' must be either -x or +x"
 msgstr "参数 --chmod 取值 '%s' 必须是 -x 或 +x"
 
-#: builtin/add.c:443
+#: builtin/add.c:442
 #, c-format
 msgid "Nothing specified, nothing added.\n"
 msgstr "没有指定文件,也没有文件被添加。\n"
 
-#: builtin/add.c:444
+#: builtin/add.c:443
 #, c-format
 msgid "Maybe you wanted to say 'git add .'?\n"
 msgstr "也许您想要执行 'git add .'?\n"
 
-#: builtin/add.c:449 builtin/check-ignore.c:177 builtin/checkout.c:280
-#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:316
+#: builtin/add.c:448 builtin/check-ignore.c:177 builtin/checkout.c:280
+#: builtin/checkout.c:483 builtin/clean.c:958 builtin/commit.c:325
 #: builtin/diff-tree.c:114 builtin/mv.c:144 builtin/reset.c:241
-#: builtin/rm.c:271 builtin/submodule--helper.c:326
+#: builtin/rm.c:270 builtin/submodule--helper.c:328
 msgid "index file corrupt"
 msgstr "索引文件损坏"
 
@@ -5299,7 +5646,7 @@ msgstr "无效的时区偏移值"
 msgid "Patch format detection failed."
 msgstr "补丁格式探测失败。"
 
-#: builtin/am.c:1013 builtin/clone.c:405
+#: builtin/am.c:1013 builtin/clone.c:407
 #, c-format
 msgid "failed to create directory '%s'"
 msgstr "无法创建目录 '%s'"
@@ -5308,7 +5655,7 @@ msgstr "无法创建目录 '%s'"
 msgid "Failed to split patches."
 msgstr "无法拆分补丁。"
 
-#: builtin/am.c:1148 builtin/commit.c:342
+#: builtin/am.c:1148 builtin/commit.c:351
 msgid "unable to write index file"
 msgstr "无法写入索引文件"
 
@@ -5477,7 +5824,7 @@ msgid "allow fall back on 3way merging if needed"
 msgstr "如果必要,允许使用三方合并。"
 
 #: builtin/am.c:2222 builtin/init-db.c:484 builtin/prune-packed.c:57
-#: builtin/repack.c:182
+#: builtin/repack.c:192
 msgid "be quiet"
 msgstr "静默模式"
 
@@ -5519,16 +5866,17 @@ msgstr "丢弃裁切线前的所有内容"
 msgid "pass it through git-apply"
 msgstr "传递给 git-apply"
 
-#: builtin/am.c:2260 builtin/fmt-merge-msg.c:665 builtin/fmt-merge-msg.c:668
-#: builtin/grep.c:853 builtin/merge.c:206 builtin/pull.c:145 builtin/pull.c:203
-#: builtin/repack.c:191 builtin/repack.c:195 builtin/repack.c:197
-#: builtin/show-branch.c:631 builtin/show-ref.c:169 builtin/tag.c:382
-#: parse-options.h:144 parse-options.h:146 parse-options.h:257
+#: builtin/am.c:2260 builtin/commit.c:1332 builtin/fmt-merge-msg.c:665
+#: builtin/fmt-merge-msg.c:668 builtin/grep.c:853 builtin/merge.c:208
+#: builtin/pull.c:150 builtin/pull.c:208 builtin/repack.c:201
+#: builtin/repack.c:205 builtin/repack.c:207 builtin/show-branch.c:631
+#: builtin/show-ref.c:169 builtin/tag.c:383 parse-options.h:144
+#: parse-options.h:146 parse-options.h:258
 msgid "n"
 msgstr "n"
 
-#: builtin/am.c:2266 builtin/branch.c:629 builtin/for-each-ref.c:38
-#: builtin/replace.c:445 builtin/tag.c:418 builtin/verify-tag.c:39
+#: builtin/am.c:2266 builtin/branch.c:632 builtin/for-each-ref.c:38
+#: builtin/replace.c:543 builtin/tag.c:419 builtin/verify-tag.c:39
 msgid "format"
 msgstr "格式"
 
@@ -5572,8 +5920,8 @@ msgstr "将作者日期作为提交日期"
 msgid "use current timestamp for author date"
 msgstr "用当前时间作为作者日期"
 
-#: builtin/am.c:2298 builtin/commit.c:1431 builtin/merge.c:237
-#: builtin/pull.c:178 builtin/revert.c:112 builtin/tag.c:398
+#: builtin/am.c:2298 builtin/commit.c:1468 builtin/merge.c:239
+#: builtin/pull.c:183 builtin/revert.c:112 builtin/tag.c:399
 msgid "key-id"
 msgstr "key-id"
 
@@ -5712,115 +6060,141 @@ msgstr "--write-terms 需要两个参数"
 msgid "--bisect-clean-state requires no arguments"
 msgstr "--bisect-clean-state 不需要参数"
 
-#: builtin/blame.c:27
+#: builtin/blame.c:29
 msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>"
 msgstr "git blame [<选项>] [<版本选项>] [<版本>] [--] <文件>"
 
-#: builtin/blame.c:32
+#: builtin/blame.c:34
 msgid "<rev-opts> are documented in git-rev-list(1)"
 msgstr "<版本选项> 的文档记录在 git-rev-list(1) 中"
 
-#: builtin/blame.c:677
+#: builtin/blame.c:404
+#, c-format
+msgid "expecting a color: %s"
+msgstr "期望一个颜色:%s"
+
+#: builtin/blame.c:411
+msgid "must end with a color"
+msgstr "必须以一个颜色结尾"
+
+#: builtin/blame.c:697
+#, c-format
+msgid "invalid color '%s' in color.blame.repeatedLines"
+msgstr "设置 color.blame.repeatedLines 中的无效颜色 '%s'"
+
+#: builtin/blame.c:715
+msgid "invalid value for blame.coloring"
+msgstr "设置 blame.coloring 中的无效取值"
+
+#: builtin/blame.c:786
 msgid "Show blame entries as we find them, incrementally"
 msgstr "增量式地显示发现的 blame 条目"
 
-#: builtin/blame.c:678
+#: builtin/blame.c:787
 msgid "Show blank SHA-1 for boundary commits (Default: off)"
 msgstr "边界提交显示空的 SHA-1(默认:关闭)"
 
-#: builtin/blame.c:679
+#: builtin/blame.c:788
 msgid "Do not treat root commits as boundaries (Default: off)"
 msgstr "不把根提交作为边界(默认:关闭)"
 
-#: builtin/blame.c:680
+#: builtin/blame.c:789
 msgid "Show work cost statistics"
 msgstr "显示命令消耗统计"
 
-#: builtin/blame.c:681
+#: builtin/blame.c:790
 msgid "Force progress reporting"
 msgstr "强制进度显示"
 
-#: builtin/blame.c:682
+#: builtin/blame.c:791
 msgid "Show output score for blame entries"
 msgstr "显示判断 blame 条目位移的得分诊断信息"
 
-#: builtin/blame.c:683
+#: builtin/blame.c:792
 msgid "Show original filename (Default: auto)"
 msgstr "显示原始文件名(默认:自动)"
 
-#: builtin/blame.c:684
+#: builtin/blame.c:793
 msgid "Show original linenumber (Default: off)"
 msgstr "显示原始的行号(默认:关闭)"
 
-#: builtin/blame.c:685
+#: builtin/blame.c:794
 msgid "Show in a format designed for machine consumption"
 msgstr "显示为一个适合机器读取的格式"
 
-#: builtin/blame.c:686
+#: builtin/blame.c:795
 msgid "Show porcelain format with per-line commit information"
 msgstr "为每一行显示机器适用的提交信息"
 
-#: builtin/blame.c:687
+#: builtin/blame.c:796
 msgid "Use the same output mode as git-annotate (Default: off)"
 msgstr "使用和 git-annotate 相同的输出模式(默认:关闭)"
 
-#: builtin/blame.c:688
+#: builtin/blame.c:797
 msgid "Show raw timestamp (Default: off)"
 msgstr "显示原始时间戳(默认:关闭)"
 
-#: builtin/blame.c:689
+#: builtin/blame.c:798
 msgid "Show long commit SHA1 (Default: off)"
 msgstr "显示长的 SHA1 提交号(默认:关闭)"
 
-#: builtin/blame.c:690
+#: builtin/blame.c:799
 msgid "Suppress author name and timestamp (Default: off)"
 msgstr "隐藏作者名字和时间戳(默认:关闭)"
 
-#: builtin/blame.c:691
+#: builtin/blame.c:800
 msgid "Show author email instead of name (Default: off)"
 msgstr "显示作者的邮箱而不是名字(默认:关闭)"
 
-#: builtin/blame.c:692
+#: builtin/blame.c:801
 msgid "Ignore whitespace differences"
 msgstr "忽略空白差异"
 
-#: builtin/blame.c:699
+#: builtin/blame.c:802
+msgid "color redundant metadata from previous line differently"
+msgstr "使用颜色间隔输出与前一行不同的重复元信息"
+
+#: builtin/blame.c:803
+msgid "color lines by age"
+msgstr "依据时间着色"
+
+#: builtin/blame.c:810
 msgid "Use an experimental heuristic to improve diffs"
 msgstr "使用一个试验性的启发式算法改进差异显示"
 
-#: builtin/blame.c:701
+#: builtin/blame.c:812
 msgid "Spend extra cycles to find better match"
 msgstr "花费额外的循环来找到更好的匹配"
 
-#: builtin/blame.c:702
+#: builtin/blame.c:813
 msgid "Use revisions from <file> instead of calling git-rev-list"
 msgstr "使用来自 <文件> 的修订集而不是调用 git-rev-list"
 
-#: builtin/blame.c:703
+#: builtin/blame.c:814
 msgid "Use <file>'s contents as the final image"
 msgstr "使用 <文件> 的内容作为最终的图片"
 
-#: builtin/blame.c:704 builtin/blame.c:705
+#: builtin/blame.c:815 builtin/blame.c:816
 msgid "score"
 msgstr "得分"
 
-#: builtin/blame.c:704
+#: builtin/blame.c:815
 msgid "Find line copies within and across files"
 msgstr "找到文件内及跨文件的行拷贝"
 
-#: builtin/blame.c:705
+#: builtin/blame.c:816
 msgid "Find line movements within and across files"
 msgstr "找到文件内及跨文件的行移动"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "n,m"
 msgstr "n,m"
 
-#: builtin/blame.c:706
+#: builtin/blame.c:817
 msgid "Process only line range n,m, counting from 1"
 msgstr "只处理行范围在 n 和 m 之间的,从 1 开始"
 
-#: builtin/blame.c:753
+#: builtin/blame.c:866
 msgid "--progress can't be used with --incremental or porcelain formats"
 msgstr "--progress 不能和 --incremental 或 --porcelain 同时使用"
 
@@ -5832,18 +6206,18 @@ msgstr "--progress 不能和 --incremental 或 --porcelain 同时使用"
 #. your language may need more or fewer display
 #. columns.
 #.
-#: builtin/blame.c:804
+#: builtin/blame.c:917
 msgid "4 years, 11 months ago"
 msgstr "4 年 11 个月前"
 
-#: builtin/blame.c:890
+#: builtin/blame.c:1003
 #, c-format
 msgid "file %s has only %lu line"
 msgid_plural "file %s has only %lu lines"
 msgstr[0] "文件 %s 只有 %lu 行"
 msgstr[1] "文件 %s 只有 %lu 行"
 
-#: builtin/blame.c:936
+#: builtin/blame.c:1049
 msgid "Blaming lines"
 msgstr "追踪代码行"
 
@@ -5956,65 +6330,65 @@ msgstr "已删除远程跟踪分支 %s(曾为 %s)。\n"
 msgid "Deleted branch %s (was %s).\n"
 msgstr "已删除分支 %s(曾为 %s)。\n"
 
-#: builtin/branch.c:417 builtin/tag.c:58
+#: builtin/branch.c:416 builtin/tag.c:58
 msgid "unable to parse format string"
 msgstr "不能解析格式化字符串"
 
-#: builtin/branch.c:450
+#: builtin/branch.c:453
 #, c-format
 msgid "Branch %s is being rebased at %s"
 msgstr "分支 %s 正被变基到 %s"
 
-#: builtin/branch.c:454
+#: builtin/branch.c:457
 #, c-format
 msgid "Branch %s is being bisected at %s"
 msgstr "分支 %s 正被二分查找于 %s"
 
-#: builtin/branch.c:471
+#: builtin/branch.c:474
 msgid "cannot copy the current branch while not on any."
 msgstr "无法拷贝当前分支因为不处于任何分支上。"
 
-#: builtin/branch.c:473
+#: builtin/branch.c:476
 msgid "cannot rename the current branch while not on any."
 msgstr "无法重命名当前分支因为不处于任何分支上。"
 
-#: builtin/branch.c:484
+#: builtin/branch.c:487
 #, c-format
 msgid "Invalid branch name: '%s'"
 msgstr "无效的分支名:'%s'"
 
-#: builtin/branch.c:511
+#: builtin/branch.c:514
 msgid "Branch rename failed"
 msgstr "分支重命名失败"
 
-#: builtin/branch.c:513
+#: builtin/branch.c:516
 msgid "Branch copy failed"
 msgstr "分支拷贝失败"
 
-#: builtin/branch.c:517
+#: builtin/branch.c:520
 #, c-format
 msgid "Created a copy of a misnamed branch '%s'"
 msgstr "已为错误命名的分支 '%s' 创建了一个副本"
 
-#: builtin/branch.c:520
+#: builtin/branch.c:523
 #, c-format
 msgid "Renamed a misnamed branch '%s' away"
 msgstr "已将错误命名的分支 '%s' 重命名"
 
-#: builtin/branch.c:526
+#: builtin/branch.c:529
 #, c-format
 msgid "Branch renamed to %s, but HEAD is not updated!"
 msgstr "分支重命名为 %s,但 HEAD 没有更新!"
 
-#: builtin/branch.c:535
+#: builtin/branch.c:538
 msgid "Branch is renamed, but update of config-file failed"
 msgstr "分支被重命名,但更新配置文件失败"
 
-#: builtin/branch.c:537
+#: builtin/branch.c:540
 msgid "Branch is copied, but update of config-file failed"
 msgstr "分支已拷贝,但更新配置文件失败"
 
-#: builtin/branch.c:553
+#: builtin/branch.c:556
 #, c-format
 msgid ""
 "Please edit the description for the branch\n"
@@ -6025,217 +6399,219 @@ msgstr ""
 "  %s\n"
 "以 '%c' 开头的行将被过滤。\n"
 
-#: builtin/branch.c:586
+#: builtin/branch.c:589
 msgid "Generic options"
 msgstr "通用选项"
 
-#: builtin/branch.c:588
+#: builtin/branch.c:591
 msgid "show hash and subject, give twice for upstream branch"
 msgstr "显示哈希值和主题,若参数出现两次则显示上游分支"
 
-#: builtin/branch.c:589
+#: builtin/branch.c:592
 msgid "suppress informational messages"
 msgstr "不显示信息"
 
-#: builtin/branch.c:590
+#: builtin/branch.c:593
 msgid "set up tracking mode (see git-pull(1))"
 msgstr "设置跟踪模式(参见 git-pull(1))"
 
-#: builtin/branch.c:592
+#: builtin/branch.c:595
 msgid "do not use"
 msgstr "不要使用"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "upstream"
 msgstr "上游"
 
-#: builtin/branch.c:594
+#: builtin/branch.c:597
 msgid "change the upstream info"
 msgstr "改变上游信息"
 
-#: builtin/branch.c:595
+#: builtin/branch.c:598
 msgid "Unset the upstream info"
 msgstr "取消上游信息的设置"
 
-#: builtin/branch.c:596
+#: builtin/branch.c:599
 msgid "use colored output"
 msgstr "使用彩色输出"
 
-#: builtin/branch.c:597
+#: builtin/branch.c:600
 msgid "act on remote-tracking branches"
 msgstr "作用于远程跟踪分支"
 
-#: builtin/branch.c:599 builtin/branch.c:601
+#: builtin/branch.c:602 builtin/branch.c:604
 msgid "print only branches that contain the commit"
 msgstr "只打印包含该提交的分支"
 
-#: builtin/branch.c:600 builtin/branch.c:602
+#: builtin/branch.c:603 builtin/branch.c:605
 msgid "print only branches that don't contain the commit"
 msgstr "只打印不包含该提交的分支"
 
-#: builtin/branch.c:605
+#: builtin/branch.c:608
 msgid "Specific git-branch actions:"
 msgstr "具体的 git-branch 动作:"
 
-#: builtin/branch.c:606
+#: builtin/branch.c:609
 msgid "list both remote-tracking and local branches"
 msgstr "列出远程跟踪及本地分支"
 
-#: builtin/branch.c:608
+#: builtin/branch.c:611
 msgid "delete fully merged branch"
 msgstr "删除完全合并的分支"
 
-#: builtin/branch.c:609
+#: builtin/branch.c:612
 msgid "delete branch (even if not merged)"
 msgstr "删除分支(即使没有合并)"
 
-#: builtin/branch.c:610
+#: builtin/branch.c:613
 msgid "move/rename a branch and its reflog"
 msgstr "移动/重命名一个分支,以及它的引用日志"
 
-#: builtin/branch.c:611
+#: builtin/branch.c:614
 msgid "move/rename a branch, even if target exists"
 msgstr "移动/重命名一个分支,即使目标已存在"
 
-#: builtin/branch.c:612
+#: builtin/branch.c:615
 msgid "copy a branch and its reflog"
 msgstr "拷贝一个分支和它的引用日志"
 
-#: builtin/branch.c:613
+#: builtin/branch.c:616
 msgid "copy a branch, even if target exists"
 msgstr "拷贝一个分支,即使目标已存在"
 
-#: builtin/branch.c:614
+#: builtin/branch.c:617
 msgid "list branch names"
 msgstr "列出分支名"
 
-#: builtin/branch.c:615
+#: builtin/branch.c:618
 msgid "create the branch's reflog"
 msgstr "创建分支的引用日志"
 
-#: builtin/branch.c:617
+#: builtin/branch.c:620
 msgid "edit the description for the branch"
 msgstr "标记分支的描述"
 
-#: builtin/branch.c:618
+#: builtin/branch.c:621
 msgid "force creation, move/rename, deletion"
 msgstr "强制创建、移动/重命名、删除"
 
-#: builtin/branch.c:619
+#: builtin/branch.c:622
 msgid "print only branches that are merged"
 msgstr "只打印已经合并的分支"
 
-#: builtin/branch.c:620
+#: builtin/branch.c:623
 msgid "print only branches that are not merged"
 msgstr "只打印尚未合并的分支"
 
-#: builtin/branch.c:621
+#: builtin/branch.c:624
 msgid "list branches in columns"
 msgstr "以列的方式显示分支"
 
-#: builtin/branch.c:622 builtin/for-each-ref.c:40 builtin/tag.c:411
+#: builtin/branch.c:625 builtin/for-each-ref.c:40 builtin/ls-remote.c:70
+#: builtin/tag.c:412
 msgid "key"
 msgstr "key"
 
-#: builtin/branch.c:623 builtin/for-each-ref.c:41 builtin/tag.c:412
+#: builtin/branch.c:626 builtin/for-each-ref.c:41 builtin/ls-remote.c:71
+#: builtin/tag.c:413
 msgid "field name to sort on"
 msgstr "排序的字段名"
 
-#: builtin/branch.c:625 builtin/for-each-ref.c:43 builtin/notes.c:408
+#: builtin/branch.c:628 builtin/for-each-ref.c:43 builtin/notes.c:408
 #: builtin/notes.c:411 builtin/notes.c:571 builtin/notes.c:574
-#: builtin/tag.c:414
+#: builtin/tag.c:415
 msgid "object"
 msgstr "对象"
 
-#: builtin/branch.c:626
+#: builtin/branch.c:629
 msgid "print only branches of the object"
 msgstr "只打印指向该对象的分支"
 
-#: builtin/branch.c:628 builtin/for-each-ref.c:49 builtin/tag.c:421
+#: builtin/branch.c:631 builtin/for-each-ref.c:49 builtin/tag.c:422
 msgid "sorting and filtering are case insensitive"
 msgstr "排序和过滤属于大小写不敏感"
 
-#: builtin/branch.c:629 builtin/for-each-ref.c:38 builtin/tag.c:419
+#: builtin/branch.c:632 builtin/for-each-ref.c:38 builtin/tag.c:420
 #: builtin/verify-tag.c:39
 msgid "format to use for the output"
 msgstr "输出格式"
 
-#: builtin/branch.c:652 builtin/clone.c:735
+#: builtin/branch.c:655 builtin/clone.c:737
 msgid "HEAD not found below refs/heads!"
 msgstr "HEAD 没有位于 /refs/heads 之下!"
 
-#: builtin/branch.c:675
+#: builtin/branch.c:678
 msgid "--column and --verbose are incompatible"
 msgstr "--column 和 --verbose 不兼容"
 
-#: builtin/branch.c:690 builtin/branch.c:742 builtin/branch.c:751
+#: builtin/branch.c:693 builtin/branch.c:745 builtin/branch.c:754
 msgid "branch name required"
 msgstr "必须提供分支名"
 
-#: builtin/branch.c:718
+#: builtin/branch.c:721
 msgid "Cannot give description to detached HEAD"
 msgstr "不能向分离头指针提供描述"
 
-#: builtin/branch.c:723
+#: builtin/branch.c:726
 msgid "cannot edit description of more than one branch"
 msgstr "不能为一个以上的分支编辑描述"
 
-#: builtin/branch.c:730
+#: builtin/branch.c:733
 #, c-format
 msgid "No commit on branch '%s' yet."
 msgstr "分支 '%s' 尚无提交。"
 
-#: builtin/branch.c:733
+#: builtin/branch.c:736
 #, c-format
 msgid "No branch named '%s'."
 msgstr "没有分支 '%s'。"
 
-#: builtin/branch.c:748
+#: builtin/branch.c:751
 msgid "too many branches for a copy operation"
 msgstr "为拷贝操作提供了太多的分支名"
 
-#: builtin/branch.c:757
+#: builtin/branch.c:760
 msgid "too many arguments for a rename operation"
 msgstr "为重命名操作提供了太多的参数"
 
-#: builtin/branch.c:762
+#: builtin/branch.c:765
 msgid "too many arguments to set new upstream"
 msgstr "为设置新上游提供了太多的参数"
 
-#: builtin/branch.c:766
+#: builtin/branch.c:769
 #, c-format
 msgid ""
 "could not set upstream of HEAD to %s when it does not point to any branch."
 msgstr "无法设置 HEAD 的上游为 %s,因为 HEAD 没有指向任何分支。"
 
-#: builtin/branch.c:769 builtin/branch.c:791 builtin/branch.c:807
+#: builtin/branch.c:772 builtin/branch.c:794 builtin/branch.c:810
 #, c-format
 msgid "no such branch '%s'"
 msgstr "没有此分支 '%s'"
 
-#: builtin/branch.c:773
+#: builtin/branch.c:776
 #, c-format
 msgid "branch '%s' does not exist"
 msgstr "分支 '%s' 不存在"
 
-#: builtin/branch.c:785
+#: builtin/branch.c:788
 msgid "too many arguments to unset upstream"
 msgstr "为取消上游设置操作提供了太多的参数"
 
-#: builtin/branch.c:789
+#: builtin/branch.c:792
 msgid "could not unset upstream of HEAD when it does not point to any branch."
 msgstr "无法取消 HEAD 的上游设置因为它没有指向一个分支"
 
-#: builtin/branch.c:795
+#: builtin/branch.c:798
 #, c-format
 msgid "Branch '%s' has no upstream information"
 msgstr "分支 '%s' 没有上游信息"
 
-#: builtin/branch.c:810
+#: builtin/branch.c:813
 msgid "-a and -r options to 'git branch' do not make sense with a branch name"
 msgstr "'git branch' 的 -a 和 -r 选项带一个分支名参数没有意义"
 
-#: builtin/branch.c:813
+#: builtin/branch.c:816
 msgid ""
 "the '--set-upstream' option is no longer supported. Please use '--track' or "
 "'--set-upstream-to' instead."
@@ -6255,7 +6631,7 @@ msgstr "需要一个仓库来创建包。"
 msgid "Need a repository to unbundle."
 msgstr "需要一个仓库来解包。"
 
-#: builtin/cat-file.c:523
+#: builtin/cat-file.c:525
 msgid ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <type> | --textconv | --filters) [--path=<path>] <object>"
@@ -6263,7 +6639,7 @@ msgstr ""
 "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -"
 "p | <类型> | --textconv | --filters) [--path=<路径>] <对象>"
 
-#: builtin/cat-file.c:524
+#: builtin/cat-file.c:526
 msgid ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
@@ -6271,63 +6647,63 @@ msgstr ""
 "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --"
 "filters]"
 
-#: builtin/cat-file.c:561
+#: builtin/cat-file.c:563
 msgid "<type> can be one of: blob, tree, commit, tag"
 msgstr "<类型> 可以是其中之一:blob、tree、commit、tag"
 
-#: builtin/cat-file.c:562
+#: builtin/cat-file.c:564
 msgid "show object type"
 msgstr "显示对象类型"
 
-#: builtin/cat-file.c:563
+#: builtin/cat-file.c:565
 msgid "show object size"
 msgstr "显示对象大小"
 
-#: builtin/cat-file.c:565
+#: builtin/cat-file.c:567
 msgid "exit with zero when there's no error"
 msgstr "当没有错误时退出并返回零"
 
-#: builtin/cat-file.c:566
+#: builtin/cat-file.c:568
 msgid "pretty-print object's content"
 msgstr "美观地打印对象的内容"
 
-#: builtin/cat-file.c:568
+#: builtin/cat-file.c:570
 msgid "for blob objects, run textconv on object's content"
 msgstr "对于数据对象,对其内容做文本转换"
 
-#: builtin/cat-file.c:570
+#: builtin/cat-file.c:572
 msgid "for blob objects, run filters on object's content"
 msgstr "对于数据对象,对其内容做过滤"
 
-#: builtin/cat-file.c:571 git-submodule.sh:878
+#: builtin/cat-file.c:573 git-submodule.sh:894
 msgid "blob"
 msgstr "数据对象"
 
-#: builtin/cat-file.c:572
+#: builtin/cat-file.c:574
 msgid "use a specific path for --textconv/--filters"
 msgstr "对于 --textconv/--filters 使用一个特定的路径"
 
-#: builtin/cat-file.c:574
+#: builtin/cat-file.c:576
 msgid "allow -s and -t to work with broken/corrupt objects"
 msgstr "允许 -s 和 -t 对损坏的对象生效"
 
-#: builtin/cat-file.c:575
+#: builtin/cat-file.c:577
 msgid "buffer --batch output"
 msgstr "缓冲 --batch 的输出"
 
-#: builtin/cat-file.c:577
+#: builtin/cat-file.c:579
 msgid "show info and content of objects fed from the standard input"
 msgstr "显示从标准输入提供的对象的信息和内容"
 
-#: builtin/cat-file.c:580
+#: builtin/cat-file.c:582
 msgid "show info about objects fed from the standard input"
 msgstr "显示从标准输入提供的对象的信息"
 
-#: builtin/cat-file.c:583
+#: builtin/cat-file.c:585
 msgid "follow in-tree symlinks (used with --batch or --batch-check)"
 msgstr "跟随树内符号链接(和 --batch 或 --batch-check 共用)"
 
-#: builtin/cat-file.c:585
+#: builtin/cat-file.c:587
 msgid "show all objects with --batch or --batch-check"
 msgstr "使用 --batch 或 --batch-check 参数显示所有对象"
 
@@ -6355,7 +6731,7 @@ msgstr "从标准输入读出文件名"
 msgid "terminate input and output records by a NUL character"
 msgstr "输入和输出的记录使用 NUL 字符终结"
 
-#: builtin/check-ignore.c:20 builtin/checkout.c:1106 builtin/gc.c:358
+#: builtin/check-ignore.c:20 builtin/checkout.c:1113 builtin/gc.c:500
 msgid "suppress progress reporting"
 msgstr "不显示进度报告"
 
@@ -6445,9 +6821,9 @@ msgid "write the content to temporary files"
 msgstr "将内容写入临时文件"
 
 #: builtin/checkout-index.c:173 builtin/column.c:31
-#: builtin/submodule--helper.c:1203 builtin/submodule--helper.c:1206
-#: builtin/submodule--helper.c:1212 builtin/submodule--helper.c:1574
-#: builtin/worktree.c:570
+#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1219
+#: builtin/submodule--helper.c:1227 builtin/submodule--helper.c:1591
+#: builtin/worktree.c:610
 msgid "string"
 msgstr "字符串"
 
@@ -6518,55 +6894,55 @@ msgstr "不能同时更新路径并切换到分支'%s'。"
 msgid "path '%s' is unmerged"
 msgstr "路径 '%s' 未合并"
 
-#: builtin/checkout.c:505
+#: builtin/checkout.c:506
 msgid "you need to resolve your current index first"
 msgstr "您需要先解决当前索引的冲突"
 
-#: builtin/checkout.c:636
+#: builtin/checkout.c:643
 #, c-format
 msgid "Can not do reflog for '%s': %s\n"
 msgstr "不能对 '%s' 执行 reflog 操作:%s\n"
 
-#: builtin/checkout.c:677
+#: builtin/checkout.c:684
 msgid "HEAD is now at"
 msgstr "HEAD 目前位于"
 
-#: builtin/checkout.c:681 builtin/clone.c:689
+#: builtin/checkout.c:688 builtin/clone.c:691
 msgid "unable to update HEAD"
 msgstr "不能更新 HEAD"
 
-#: builtin/checkout.c:685
+#: builtin/checkout.c:692
 #, c-format
 msgid "Reset branch '%s'\n"
 msgstr "重置分支 '%s'\n"
 
-#: builtin/checkout.c:688
+#: builtin/checkout.c:695
 #, c-format
 msgid "Already on '%s'\n"
 msgstr "已经位于 '%s'\n"
 
-#: builtin/checkout.c:692
+#: builtin/checkout.c:699
 #, c-format
 msgid "Switched to and reset branch '%s'\n"
 msgstr "切换并重置分支 '%s'\n"
 
-#: builtin/checkout.c:694 builtin/checkout.c:1039
+#: builtin/checkout.c:701 builtin/checkout.c:1046
 #, c-format
 msgid "Switched to a new branch '%s'\n"
 msgstr "切换到一个新分支 '%s'\n"
 
-#: builtin/checkout.c:696
+#: builtin/checkout.c:703
 #, c-format
 msgid "Switched to branch '%s'\n"
 msgstr "切换到分支 '%s'\n"
 
 #  译者:注意保持前导空格
-#: builtin/checkout.c:747
+#: builtin/checkout.c:754
 #, c-format
 msgid " ... and %d more.\n"
 msgstr " ... 及其它 %d 个。\n"
 
-#: builtin/checkout.c:753
+#: builtin/checkout.c:760
 #, c-format
 msgid ""
 "Warning: you are leaving %d commit behind, not connected to\n"
@@ -6587,7 +6963,7 @@ msgstr[1] ""
 "\n"
 "%s\n"
 
-#: builtin/checkout.c:772
+#: builtin/checkout.c:779
 #, c-format
 msgid ""
 "If you want to keep it by creating a new branch, this may be a good time\n"
@@ -6614,160 +6990,160 @@ msgstr[1] ""
 " git branch <新分支名> %s\n"
 "\n"
 
-#: builtin/checkout.c:804
+#: builtin/checkout.c:811
 msgid "internal error in revision walk"
 msgstr "在版本遍历时遇到内部错误"
 
-#: builtin/checkout.c:808
+#: builtin/checkout.c:815
 msgid "Previous HEAD position was"
 msgstr "之前的 HEAD 位置是"
 
-#: builtin/checkout.c:836 builtin/checkout.c:1034
+#: builtin/checkout.c:843 builtin/checkout.c:1041
 msgid "You are on a branch yet to be born"
 msgstr "您位于一个尚未初始化的分支"
 
-#: builtin/checkout.c:940
+#: builtin/checkout.c:947
 #, c-format
 msgid "only one reference expected, %d given."
 msgstr "应只有一个引用,却给出了 %d 个"
 
-#: builtin/checkout.c:980 builtin/worktree.c:249
+#: builtin/checkout.c:987 builtin/worktree.c:240 builtin/worktree.c:389
 #, c-format
 msgid "invalid reference: %s"
 msgstr "无效引用:%s"
 
-#: builtin/checkout.c:1009
+#: builtin/checkout.c:1016
 #, c-format
 msgid "reference is not a tree: %s"
 msgstr "引用不是一个树:%s"
 
-#: builtin/checkout.c:1048
+#: builtin/checkout.c:1055
 msgid "paths cannot be used with switching branches"
 msgstr "路径不能和切换分支同时使用"
 
-#: builtin/checkout.c:1051 builtin/checkout.c:1055
+#: builtin/checkout.c:1058 builtin/checkout.c:1062
 #, c-format
 msgid "'%s' cannot be used with switching branches"
 msgstr "'%s' 不能和切换分支同时使用"
 
-#: builtin/checkout.c:1059 builtin/checkout.c:1062 builtin/checkout.c:1067
-#: builtin/checkout.c:1070
+#: builtin/checkout.c:1066 builtin/checkout.c:1069 builtin/checkout.c:1074
+#: builtin/checkout.c:1077
 #, c-format
 msgid "'%s' cannot be used with '%s'"
 msgstr "'%s' 不能和 '%s' 同时使用"
 
-#: builtin/checkout.c:1075
+#: builtin/checkout.c:1082
 #, c-format
 msgid "Cannot switch branch to a non-commit '%s'"
 msgstr "不能切换分支到一个非提交 '%s'"
 
-#: builtin/checkout.c:1107 builtin/checkout.c:1109 builtin/clone.c:116
-#: builtin/remote.c:166 builtin/remote.c:168 builtin/worktree.c:387
-#: builtin/worktree.c:389
+#: builtin/checkout.c:1114 builtin/checkout.c:1116 builtin/clone.c:118
+#: builtin/remote.c:167 builtin/remote.c:169 builtin/worktree.c:433
+#: builtin/worktree.c:435
 msgid "branch"
 msgstr "分支"
 
-#: builtin/checkout.c:1108
+#: builtin/checkout.c:1115
 msgid "create and checkout a new branch"
 msgstr "创建并检出一个新的分支"
 
-#: builtin/checkout.c:1110
+#: builtin/checkout.c:1117
 msgid "create/reset and checkout a branch"
 msgstr "创建/重置并检出一个分支"
 
-#: builtin/checkout.c:1111
+#: builtin/checkout.c:1118
 msgid "create reflog for new branch"
 msgstr "为新的分支创建引用日志"
 
-#: builtin/checkout.c:1112 builtin/worktree.c:391
+#: builtin/checkout.c:1119 builtin/worktree.c:437
 msgid "detach HEAD at named commit"
 msgstr "HEAD 从指定的提交分离"
 
-#: builtin/checkout.c:1113
+#: builtin/checkout.c:1120
 msgid "set upstream info for new branch"
 msgstr "为新的分支设置上游信息"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new-branch"
 msgstr "新分支"
 
-#: builtin/checkout.c:1115
+#: builtin/checkout.c:1122
 msgid "new unparented branch"
 msgstr "新的没有父提交的分支"
 
-#: builtin/checkout.c:1116
+#: builtin/checkout.c:1123
 msgid "checkout our version for unmerged files"
 msgstr "对尚未合并的文件检出我们的版本"
 
-#: builtin/checkout.c:1118
+#: builtin/checkout.c:1125
 msgid "checkout their version for unmerged files"
 msgstr "对尚未合并的文件检出他们的版本"
 
-#: builtin/checkout.c:1120
+#: builtin/checkout.c:1127
 msgid "force checkout (throw away local modifications)"
 msgstr "强制检出(丢弃本地修改)"
 
-#: builtin/checkout.c:1122
+#: builtin/checkout.c:1129
 msgid "perform a 3-way merge with the new branch"
 msgstr "和新的分支执行三方合并"
 
-#: builtin/checkout.c:1124 builtin/merge.c:239
+#: builtin/checkout.c:1131 builtin/merge.c:241
 msgid "update ignored files (default)"
 msgstr "更新忽略的文件(默认)"
 
-#: builtin/checkout.c:1126 builtin/log.c:1499 parse-options.h:263
+#: builtin/checkout.c:1133 builtin/log.c:1499 parse-options.h:264
 msgid "style"
 msgstr "风格"
 
-#: builtin/checkout.c:1127
+#: builtin/checkout.c:1134
 msgid "conflict style (merge or diff3)"
 msgstr "冲突输出风格(merge 或 diff3)"
 
-#: builtin/checkout.c:1130
+#: builtin/checkout.c:1137
 msgid "do not limit pathspecs to sparse entries only"
 msgstr "对路径不做稀疏检出的限制"
 
-#: builtin/checkout.c:1132
+#: builtin/checkout.c:1139
 msgid "second guess 'git checkout <no-such-branch>'"
 msgstr "二次猜测'git checkout <无此分支>'"
 
-#: builtin/checkout.c:1134
+#: builtin/checkout.c:1141
 msgid "do not check if another worktree is holding the given ref"
 msgstr "不检查指定的引用是否被其他工作区所占用"
 
-#: builtin/checkout.c:1138 builtin/clone.c:83 builtin/fetch.c:150
-#: builtin/merge.c:236 builtin/pull.c:123 builtin/push.c:556
-#: builtin/send-pack.c:173
+#: builtin/checkout.c:1145 builtin/clone.c:85 builtin/fetch.c:149
+#: builtin/merge.c:238 builtin/pull.c:128 builtin/push.c:572
+#: builtin/send-pack.c:174
 msgid "force progress reporting"
 msgstr "强制显示进度报告"
 
-#: builtin/checkout.c:1168
+#: builtin/checkout.c:1175
 msgid "-b, -B and --orphan are mutually exclusive"
 msgstr "-b、-B 和 --orphan 是互斥的"
 
-#: builtin/checkout.c:1185
+#: builtin/checkout.c:1192
 msgid "--track needs a branch name"
 msgstr "--track 需要一个分支名"
 
-#: builtin/checkout.c:1190
+#: builtin/checkout.c:1197
 msgid "Missing branch name; try -b"
 msgstr "缺少分支名;尝试 -b"
 
-#: builtin/checkout.c:1226
+#: builtin/checkout.c:1233
 msgid "invalid path specification"
 msgstr "无效的路径规格"
 
-#: builtin/checkout.c:1233
+#: builtin/checkout.c:1240
 #, c-format
 msgid "'%s' is not a commit and a branch '%s' cannot be created from it"
 msgstr "'%s' 不是一个提交,不能基于它创建分支 '%s'"
 
-#: builtin/checkout.c:1237
+#: builtin/checkout.c:1244
 #, c-format
 msgid "git checkout: --detach does not take a path argument '%s'"
 msgstr "git checkout:--detach 不能接收路径参数 '%s'"
 
-#: builtin/checkout.c:1241
+#: builtin/checkout.c:1248
 msgid ""
 "git checkout: --ours/--theirs, --force and --merge are incompatible when\n"
 "checking out of the index."
@@ -6805,7 +7181,7 @@ msgstr "将忽略仓库 %s\n"
 msgid "failed to remove %s"
 msgstr "无法删除 %s"
 
-#: builtin/clean.c:302 git-add--interactive.perl:572
+#: builtin/clean.c:302 git-add--interactive.perl:579
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6818,7 +7194,7 @@ msgstr ""
 "foo        - 通过唯一前缀选择一个选项\n"
 "           - (空)什么也不选择\n"
 
-#: builtin/clean.c:306 git-add--interactive.perl:581
+#: builtin/clean.c:306 git-add--interactive.perl:588
 #, c-format
 msgid ""
 "Prompt help:\n"
@@ -6839,8 +7215,8 @@ msgstr ""
 "*          - 选择所有选项\n"
 "           - (空)结束选择\n"
 
-#: builtin/clean.c:522 git-add--interactive.perl:547
-#: git-add--interactive.perl:552
+#: builtin/clean.c:522 git-add--interactive.perl:554
+#: git-add--interactive.perl:559
 #, c-format, perl-format
 msgid "Huh (%s)?\n"
 msgstr "嗯(%s)?\n"
@@ -6865,7 +7241,7 @@ msgstr "选择要删除的条目"
 msgid "Remove %s [y/N]? "
 msgstr "删除 %s [y/N]?"
 
-#: builtin/clean.c:788 git-add--interactive.perl:1710
+#: builtin/clean.c:788 git-add--interactive.perl:1717
 #, c-format
 msgid "Bye.\n"
 msgstr "再见。\n"
@@ -6888,11 +7264,11 @@ msgstr ""
 "help                - 显示本帮助\n"
 "?                   - 显示如何在提示符下选择的帮助"
 
-#: builtin/clean.c:823 git-add--interactive.perl:1786
+#: builtin/clean.c:823 git-add--interactive.perl:1793
 msgid "*** Commands ***"
 msgstr "*** 命令 ***"
 
-#: builtin/clean.c:824 git-add--interactive.perl:1783
+#: builtin/clean.c:824 git-add--interactive.perl:1790
 msgid "What now"
 msgstr "请选择"
 
@@ -6959,144 +7335,146 @@ msgid ""
 msgstr ""
 "clean.requireForce 默认为 true 且未提供 -i、-n 或 -f 选项,拒绝执行清理动作"
 
-#: builtin/clone.c:40
+#: builtin/clone.c:42
 msgid "git clone [<options>] [--] <repo> [<dir>]"
 msgstr "git clone [<选项>] [--] <仓库> [<路径>]"
 
-#: builtin/clone.c:85
+#: builtin/clone.c:87
 msgid "don't create a checkout"
 msgstr "不创建一个检出"
 
-#: builtin/clone.c:86 builtin/clone.c:88 builtin/init-db.c:479
+#: builtin/clone.c:88 builtin/clone.c:90 builtin/init-db.c:479
 msgid "create a bare repository"
 msgstr "创建一个纯仓库"
 
-#: builtin/clone.c:90
+#: builtin/clone.c:92
 msgid "create a mirror repository (implies bare)"
 msgstr "创建一个镜像仓库(也是纯仓库)"
 
-#: builtin/clone.c:92
+#: builtin/clone.c:94
 msgid "to clone from a local repository"
 msgstr "从本地仓库克隆"
 
-#: builtin/clone.c:94
+#: builtin/clone.c:96
 msgid "don't use local hardlinks, always copy"
 msgstr "不使用本地硬链接,始终复制"
 
-#: builtin/clone.c:96
+#: builtin/clone.c:98
 msgid "setup as shared repository"
 msgstr "设置为共享仓库"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "pathspec"
 msgstr "路径规格"
 
-#: builtin/clone.c:98 builtin/clone.c:102
+#: builtin/clone.c:100 builtin/clone.c:104
 msgid "initialize submodules in the clone"
 msgstr "在克隆时初始化子模组"
 
-#: builtin/clone.c:105
+#: builtin/clone.c:107
 msgid "number of submodules cloned in parallel"
 msgstr "并发克隆的子模组的数量"
 
-#: builtin/clone.c:106 builtin/init-db.c:476
+#: builtin/clone.c:108 builtin/init-db.c:476
 msgid "template-directory"
 msgstr "模板目录"
 
-#: builtin/clone.c:107 builtin/init-db.c:477
+#: builtin/clone.c:109 builtin/init-db.c:477
 msgid "directory from which templates will be used"
 msgstr "模板目录将被使用"
 
-#: builtin/clone.c:109 builtin/clone.c:111 builtin/submodule--helper.c:1210
-#: builtin/submodule--helper.c:1577
+#: builtin/clone.c:111 builtin/clone.c:113 builtin/submodule--helper.c:1223
+#: builtin/submodule--helper.c:1594
 msgid "reference repository"
 msgstr "参考仓库"
 
-#: builtin/clone.c:113
+#: builtin/clone.c:115 builtin/submodule--helper.c:1225
+#: builtin/submodule--helper.c:1596
 msgid "use --reference only while cloning"
 msgstr "仅在克隆时参考 --reference 指向的本地仓库"
 
-#: builtin/clone.c:114 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/clone.c:116 builtin/column.c:27 builtin/merge-file.c:44
+#: builtin/pack-objects.c:3166 builtin/repack.c:213
 msgid "name"
 msgstr "名称"
 
-#: builtin/clone.c:115
+#: builtin/clone.c:117
 msgid "use <name> instead of 'origin' to track upstream"
 msgstr "使用 <名称> 而不是 'origin' 去跟踪上游"
 
-#: builtin/clone.c:117
+#: builtin/clone.c:119
 msgid "checkout <branch> instead of the remote's HEAD"
 msgstr "检出 <分支> 而不是远程 HEAD"
 
-#: builtin/clone.c:119
+#: builtin/clone.c:121
 msgid "path to git-upload-pack on the remote"
 msgstr "远程 git-upload-pack 路径"
 
-#: builtin/clone.c:120 builtin/fetch.c:151 builtin/grep.c:813
-#: builtin/pull.c:211
+#: builtin/clone.c:122 builtin/fetch.c:150 builtin/grep.c:813
+#: builtin/pull.c:216
 msgid "depth"
 msgstr "深度"
 
-#: builtin/clone.c:121
+#: builtin/clone.c:123
 msgid "create a shallow clone of that depth"
 msgstr "创建一个指定深度的浅克隆"
 
-#: builtin/clone.c:122 builtin/fetch.c:153 builtin/pack-objects.c:3017
+#: builtin/clone.c:124 builtin/fetch.c:152 builtin/pack-objects.c:3157
 #: parse-options.h:154
 msgid "time"
 msgstr "时间"
 
-#: builtin/clone.c:123
+#: builtin/clone.c:125
 msgid "create a shallow clone since a specific time"
 msgstr "从一个特定时间创建一个浅克隆"
 
-#: builtin/clone.c:124 builtin/fetch.c:155
+#: builtin/clone.c:126 builtin/fetch.c:154
 msgid "revision"
 msgstr "版本"
 
-#: builtin/clone.c:125 builtin/fetch.c:156
+#: builtin/clone.c:127 builtin/fetch.c:155
 msgid "deepen history of shallow clone, excluding rev"
 msgstr "深化浅克隆的历史,除了特定版本"
 
-#: builtin/clone.c:127
+#: builtin/clone.c:129
 msgid "clone only one branch, HEAD or --branch"
 msgstr "只克隆一个分支、HEAD 或 --branch"
 
-#: builtin/clone.c:129
+#: builtin/clone.c:131
 msgid "don't clone any tags, and make later fetches not to follow them"
 msgstr "不要克隆任何标签,并且后续获取操作也不下载它们"
 
-#: builtin/clone.c:131
+#: builtin/clone.c:133
 msgid "any cloned submodules will be shallow"
 msgstr "子模组将以浅下载模式克隆"
 
-#: builtin/clone.c:132 builtin/init-db.c:485
+#: builtin/clone.c:134 builtin/init-db.c:485
 msgid "gitdir"
 msgstr "git目录"
 
-#: builtin/clone.c:133 builtin/init-db.c:486
+#: builtin/clone.c:135 builtin/init-db.c:486
 msgid "separate git dir from working tree"
 msgstr "git目录和工作区分离"
 
-#: builtin/clone.c:134
+#: builtin/clone.c:136
 msgid "key=value"
 msgstr "key=value"
 
-#: builtin/clone.c:135
+#: builtin/clone.c:137
 msgid "set config inside the new repository"
 msgstr "在新仓库中设置配置信息"
 
-#: builtin/clone.c:136 builtin/fetch.c:173 builtin/pull.c:224
-#: builtin/push.c:567
+#: builtin/clone.c:138 builtin/fetch.c:173 builtin/pull.c:229
+#: builtin/push.c:583
 msgid "use IPv4 addresses only"
 msgstr "只使用 IPv4 地址"
 
-#: builtin/clone.c:138 builtin/fetch.c:175 builtin/pull.c:227
-#: builtin/push.c:569
+#: builtin/clone.c:140 builtin/fetch.c:175 builtin/pull.c:232
+#: builtin/push.c:585
 msgid "use IPv6 addresses only"
 msgstr "只使用 IPv6 地址"
 
-#: builtin/clone.c:276
+#: builtin/clone.c:278
 msgid ""
 "No directory name could be guessed.\n"
 "Please specify a directory on the command line"
@@ -7104,42 +7482,42 @@ msgstr ""
 "无法猜到目录名。\n"
 "请在命令行指定一个目录"
 
-#: builtin/clone.c:329
+#: builtin/clone.c:331
 #, c-format
 msgid "info: Could not add alternate for '%s': %s\n"
 msgstr "info: 不能为 '%s' 添加一个备用:%s\n"
 
-#: builtin/clone.c:401
+#: builtin/clone.c:403
 #, c-format
 msgid "failed to open '%s'"
 msgstr "无法打开 '%s'"
 
-#: builtin/clone.c:409
+#: builtin/clone.c:411
 #, c-format
 msgid "%s exists and is not a directory"
 msgstr "%s 存在且不是一个目录"
 
-#: builtin/clone.c:423
+#: builtin/clone.c:425
 #, c-format
 msgid "failed to stat %s\n"
 msgstr "对 %s 调用 stat 失败\n"
 
-#: builtin/clone.c:445
+#: builtin/clone.c:447
 #, c-format
 msgid "failed to create link '%s'"
 msgstr "无法创建链接 '%s'"
 
-#: builtin/clone.c:449
+#: builtin/clone.c:451
 #, c-format
 msgid "failed to copy file to '%s'"
 msgstr "无法拷贝文件至 '%s'"
 
-#: builtin/clone.c:475
+#: builtin/clone.c:477
 #, c-format
 msgid "done.\n"
 msgstr "完成。\n"
 
-#: builtin/clone.c:489
+#: builtin/clone.c:491
 msgid ""
 "Clone succeeded, but checkout failed.\n"
 "You can inspect what was checked out with 'git status'\n"
@@ -7149,99 +7527,99 @@ msgstr ""
 "您可以通过 'git status' 检查哪些已被检出,然后使用命令\n"
 "'git checkout -f HEAD' 重试\n"
 
-#: builtin/clone.c:566
+#: builtin/clone.c:568
 #, c-format
 msgid "Could not find remote branch %s to clone."
 msgstr "不能发现要克隆的远程分支 %s。"
 
-#: builtin/clone.c:661
+#: builtin/clone.c:663
 msgid "remote did not send all necessary objects"
 msgstr "远程没有发送所有必须的对象"
 
-#: builtin/clone.c:677
+#: builtin/clone.c:679
 #, c-format
 msgid "unable to update %s"
 msgstr "不能更新 %s"
 
-#: builtin/clone.c:726
+#: builtin/clone.c:728
 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n"
 msgstr "远程 HEAD 指向一个不存在的引用,无法检出。\n"
 
-#: builtin/clone.c:756
+#: builtin/clone.c:758
 msgid "unable to checkout working tree"
 msgstr "不能检出工作区"
 
-#: builtin/clone.c:801
+#: builtin/clone.c:803
 msgid "unable to write parameters to config file"
 msgstr "无法将参数写入配置文件"
 
-#: builtin/clone.c:864
+#: builtin/clone.c:866
 msgid "cannot repack to clean up"
 msgstr "无法执行 repack 来清理"
 
-#: builtin/clone.c:866
+#: builtin/clone.c:868
 msgid "cannot unlink temporary alternates file"
 msgstr "无法删除临时的 alternates 文件"
 
-#: builtin/clone.c:906 builtin/receive-pack.c:1946
+#: builtin/clone.c:907 builtin/receive-pack.c:1947
 msgid "Too many arguments."
 msgstr "太多参数。"
 
-#: builtin/clone.c:910
+#: builtin/clone.c:911
 msgid "You must specify a repository to clone."
 msgstr "您必须指定一个仓库来克隆。"
 
-#: builtin/clone.c:923
+#: builtin/clone.c:924
 #, c-format
 msgid "--bare and --origin %s options are incompatible."
 msgstr "--bare 和 --origin %s 选项不兼容。"
 
-#: builtin/clone.c:926
+#: builtin/clone.c:927
 msgid "--bare and --separate-git-dir are incompatible."
 msgstr "--bare 和 --separate-git-dir 选项不兼容。"
 
-#: builtin/clone.c:939
+#: builtin/clone.c:940
 #, c-format
 msgid "repository '%s' does not exist"
 msgstr "仓库 '%s' 不存在"
 
-#: builtin/clone.c:945 builtin/fetch.c:1455
+#: builtin/clone.c:946 builtin/fetch.c:1460
 #, c-format
 msgid "depth %s is not a positive number"
 msgstr "深度 %s 不是一个正数"
 
-#: builtin/clone.c:955
+#: builtin/clone.c:956
 #, c-format
 msgid "destination path '%s' already exists and is not an empty directory."
 msgstr "目标路径 '%s' 已经存在,并且不是一个空目录。"
 
-#: builtin/clone.c:965
+#: builtin/clone.c:966
 #, c-format
 msgid "working tree '%s' already exists."
 msgstr "工作区 '%s' 已经存在。"
 
-#: builtin/clone.c:980 builtin/clone.c:1001 builtin/difftool.c:270
-#: builtin/worktree.c:255 builtin/worktree.c:285
+#: builtin/clone.c:981 builtin/clone.c:1002 builtin/difftool.c:270
+#: builtin/worktree.c:246 builtin/worktree.c:276
 #, c-format
 msgid "could not create leading directories of '%s'"
 msgstr "不能为 '%s' 创建先导目录"
 
-#: builtin/clone.c:985
+#: builtin/clone.c:986
 #, c-format
 msgid "could not create work tree dir '%s'"
 msgstr "不能创建工作区目录 '%s'"
 
-#: builtin/clone.c:1005
+#: builtin/clone.c:1006
 #, c-format
 msgid "Cloning into bare repository '%s'...\n"
 msgstr "克隆到纯仓库 '%s'...\n"
 
-#: builtin/clone.c:1007
+#: builtin/clone.c:1008
 #, c-format
 msgid "Cloning into '%s'...\n"
 msgstr "正克隆到 '%s'...\n"
 
-#: builtin/clone.c:1031
+#: builtin/clone.c:1032
 msgid ""
 "clone --recursive is not compatible with both --reference and --reference-if-"
 "able"
@@ -7308,7 +7686,7 @@ msgstr "右边框的填充空间"
 msgid "Padding space between columns"
 msgstr "两列之间的填充空间"
 
-#: builtin/column.c:52
+#: builtin/column.c:51
 msgid "--command must be the first argument"
 msgstr "--command 必须是第一个参数"
 
@@ -7363,98 +7741,98 @@ msgstr ""
 "然后执行 \"git cherry-pick --continue\" 继续对其余提交执行拣选\n"
 "操作。\n"
 
-#: builtin/commit.c:284
+#: builtin/commit.c:293
 msgid "failed to unpack HEAD tree object"
 msgstr "无法解包 HEAD 树对象"
 
-#: builtin/commit.c:325
+#: builtin/commit.c:334
 msgid "unable to create temporary index"
 msgstr "不能创建临时索引"
 
-#: builtin/commit.c:331
+#: builtin/commit.c:340
 msgid "interactive add failed"
 msgstr "交互式添加失败"
 
-#: builtin/commit.c:344
+#: builtin/commit.c:353
 msgid "unable to update temporary index"
 msgstr "无法更新临时索引"
 
-#: builtin/commit.c:346
+#: builtin/commit.c:355
 msgid "Failed to update main cache tree"
 msgstr "不能更新树的主缓存"
 
-#: builtin/commit.c:371 builtin/commit.c:395 builtin/commit.c:444
+#: builtin/commit.c:380 builtin/commit.c:403 builtin/commit.c:449
 msgid "unable to write new_index file"
 msgstr "无法写 new_index 文件"
 
-#: builtin/commit.c:427
+#: builtin/commit.c:432
 msgid "cannot do a partial commit during a merge."
 msgstr "在合并过程中不能做部分提交。"
 
-#: builtin/commit.c:429
+#: builtin/commit.c:434
 msgid "cannot do a partial commit during a cherry-pick."
 msgstr "在拣选过程中不能做部分提交。"
 
-#: builtin/commit.c:437
+#: builtin/commit.c:442
 msgid "cannot read the index"
 msgstr "无法读取索引"
 
-#: builtin/commit.c:456
+#: builtin/commit.c:461
 msgid "unable to write temporary index file"
 msgstr "无法写临时索引文件"
 
-#: builtin/commit.c:553
+#: builtin/commit.c:558
 #, c-format
 msgid "commit '%s' lacks author header"
 msgstr "提交 '%s' 缺少作者信息"
 
-#: builtin/commit.c:555
+#: builtin/commit.c:560
 #, c-format
 msgid "commit '%s' has malformed author line"
-msgstr "提交 '%s' 有非法的作者信息"
+msgstr "提交 '%s' 有格式错误的作者信息"
 
-#: builtin/commit.c:574
+#: builtin/commit.c:579
 msgid "malformed --author parameter"
-msgstr "非法的 --author 参数"
+msgstr "格式错误的 --author 参数"
 
-#: builtin/commit.c:626
+#: builtin/commit.c:631
 msgid ""
 "unable to select a comment character that is not used\n"
 "in the current commit message"
 msgstr "无法选择一个未被当前提交说明使用的注释字符"
 
-#: builtin/commit.c:663 builtin/commit.c:696 builtin/commit.c:1024
+#: builtin/commit.c:668 builtin/commit.c:701 builtin/commit.c:1029
 #, c-format
 msgid "could not lookup commit %s"
 msgstr "不能查询提交 %s"
 
-#: builtin/commit.c:675 builtin/shortlog.c:309
+#: builtin/commit.c:680 builtin/shortlog.c:316
 #, c-format
 msgid "(reading log message from standard input)\n"
 msgstr "(正从标准输入中读取日志信息)\n"
 
-#: builtin/commit.c:677
+#: builtin/commit.c:682
 msgid "could not read log from standard input"
 msgstr "不能从标准输入中读取日志信息"
 
-#: builtin/commit.c:681
+#: builtin/commit.c:686
 #, c-format
 msgid "could not read log file '%s'"
 msgstr "不能读取日志文件 '%s'"
 
-#: builtin/commit.c:710 builtin/commit.c:718
+#: builtin/commit.c:715 builtin/commit.c:723
 msgid "could not read SQUASH_MSG"
 msgstr "不能读取 SQUASH_MSG"
 
-#: builtin/commit.c:715
+#: builtin/commit.c:720
 msgid "could not read MERGE_MSG"
 msgstr "不能读取 MERGE_MSG"
 
-#: builtin/commit.c:769
+#: builtin/commit.c:774
 msgid "could not write commit template"
 msgstr "不能写提交模版"
 
-#: builtin/commit.c:787
+#: builtin/commit.c:792
 #, c-format
 msgid ""
 "\n"
@@ -7468,7 +7846,7 @@ msgstr ""
 "\t%s\n"
 "然后重试。\n"
 
-#: builtin/commit.c:792
+#: builtin/commit.c:797
 #, c-format
 msgid ""
 "\n"
@@ -7482,7 +7860,7 @@ msgstr ""
 "\t%s\n"
 "然后重试。\n"
 
-#: builtin/commit.c:805
+#: builtin/commit.c:810
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7491,7 +7869,7 @@ msgstr ""
 "请为您的变更输入提交说明。以 '%c' 开始的行将被忽略,而一个空的提交\n"
 "说明将会终止提交。\n"
 
-#: builtin/commit.c:813
+#: builtin/commit.c:818
 #, c-format
 msgid ""
 "Please enter the commit message for your changes. Lines starting\n"
@@ -7502,342 +7880,350 @@ msgstr ""
 "也可以删除它们。一个空的提交说明将会终止提交。\n"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: builtin/commit.c:830
+#: builtin/commit.c:835
 #, c-format
 msgid "%sAuthor:    %.*s <%.*s>"
 msgstr "%s作者:  %.*s <%.*s>"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: builtin/commit.c:838
+#: builtin/commit.c:843
 #, c-format
 msgid "%sDate:      %s"
 msgstr "%s日期:  %s"
 
 #  译者:为保证在输出中对齐,注意调整句中空格!
-#: builtin/commit.c:845
+#: builtin/commit.c:850
 #, c-format
 msgid "%sCommitter: %.*s <%.*s>"
 msgstr "%s提交者:%.*s <%.*s>"
 
-#: builtin/commit.c:862
+#: builtin/commit.c:867
 msgid "Cannot read index"
 msgstr "无法读取索引"
 
-#: builtin/commit.c:928
+#: builtin/commit.c:933
 msgid "Error building trees"
 msgstr "无法创建树对象"
 
-#: builtin/commit.c:942 builtin/tag.c:256
+#: builtin/commit.c:947 builtin/tag.c:257
 #, c-format
 msgid "Please supply the message using either -m or -F option.\n"
 msgstr "请使用 -m 或 -F 选项提供提交说明。\n"
 
-#: builtin/commit.c:986
+#: builtin/commit.c:991
 #, c-format
 msgid "--author '%s' is not 'Name <email>' and matches no existing author"
 msgstr "--author '%s' 不是 '姓名 <邮箱>' 格式,且未能在现有作者中找到匹配"
 
-#: builtin/commit.c:1000
+#: builtin/commit.c:1005
 #, c-format
 msgid "Invalid ignored mode '%s'"
 msgstr "无效的忽略模式 '%s'"
 
-#: builtin/commit.c:1014 builtin/commit.c:1264
+#: builtin/commit.c:1019 builtin/commit.c:1269
 #, c-format
 msgid "Invalid untracked files mode '%s'"
 msgstr "无效的未追踪文件参数 '%s'"
 
-#: builtin/commit.c:1052
+#: builtin/commit.c:1057
 msgid "--long and -z are incompatible"
 msgstr "--long 和 -z 选项不兼容"
 
-#: builtin/commit.c:1085
+#: builtin/commit.c:1090
 msgid "Using both --reset-author and --author does not make sense"
 msgstr "同时使用 --reset-author 和 --author 没有意义"
 
-#: builtin/commit.c:1094
+#: builtin/commit.c:1099
 msgid "You have nothing to amend."
 msgstr "您没有可修补的提交。"
 
-#: builtin/commit.c:1097
+#: builtin/commit.c:1102
 msgid "You are in the middle of a merge -- cannot amend."
 msgstr "您正处于一个合并过程中 -- 无法修补提交。"
 
-#: builtin/commit.c:1099
+#: builtin/commit.c:1104
 msgid "You are in the middle of a cherry-pick -- cannot amend."
 msgstr "您正处于一个拣选过程中 -- 无法修补提交。"
 
-#: builtin/commit.c:1102
+#: builtin/commit.c:1107
 msgid "Options --squash and --fixup cannot be used together"
 msgstr "选项 --squash 和 --fixup 不能同时使用"
 
-#: builtin/commit.c:1112
+#: builtin/commit.c:1117
 msgid "Only one of -c/-C/-F/--fixup can be used."
 msgstr "只能用一个 -c/-C/-F/--fixup 选项。"
 
-#: builtin/commit.c:1114
+#: builtin/commit.c:1119
 msgid "Option -m cannot be combined with -c/-C/-F."
 msgstr "选项 -m 不能和 -c/-C/-F 同时使用。"
 
-#: builtin/commit.c:1122
+#: builtin/commit.c:1127
 msgid "--reset-author can be used only with -C, -c or --amend."
 msgstr "--reset-author 只能和 -C、-c 或 --amend 同时使用。"
 
-#: builtin/commit.c:1139
+#: builtin/commit.c:1144
 msgid "Only one of --include/--only/--all/--interactive/--patch can be used."
 msgstr "只能用一个 --include/--only/--all/--interactive/--patch 选项。"
 
-#: builtin/commit.c:1141
+#: builtin/commit.c:1146
 msgid "No paths with --include/--only does not make sense."
 msgstr "参数 --include/--only 不跟路径没有意义。"
 
-#: builtin/commit.c:1155 builtin/tag.c:542
+#: builtin/commit.c:1160 builtin/tag.c:543
 #, c-format
 msgid "Invalid cleanup mode %s"
 msgstr "无效的清理模式 %s"
 
-#: builtin/commit.c:1160
+#: builtin/commit.c:1165
 msgid "Paths with -a does not make sense."
 msgstr "路径和 -a 选项同时使用没有意义。"
 
-#: builtin/commit.c:1278 builtin/commit.c:1443
+#: builtin/commit.c:1303 builtin/commit.c:1480
 msgid "show status concisely"
 msgstr "以简洁的格式显示状态"
 
-#: builtin/commit.c:1280 builtin/commit.c:1445
+#: builtin/commit.c:1305 builtin/commit.c:1482
 msgid "show branch information"
 msgstr "显示分支信息"
 
-#: builtin/commit.c:1282
+#: builtin/commit.c:1307
 msgid "show stash information"
 msgstr "显示贮藏区信息"
 
-#: builtin/commit.c:1284 builtin/commit.c:1447
+#: builtin/commit.c:1309 builtin/commit.c:1484
 msgid "compute full ahead/behind values"
 msgstr "计算完整的领先/落后值"
 
-#: builtin/commit.c:1286
+#: builtin/commit.c:1311
 msgid "version"
 msgstr "版本"
 
-#: builtin/commit.c:1286 builtin/commit.c:1449 builtin/push.c:542
-#: builtin/worktree.c:541
+#: builtin/commit.c:1311 builtin/commit.c:1486 builtin/push.c:558
+#: builtin/worktree.c:581
 msgid "machine-readable output"
 msgstr "机器可读的输出"
 
-#: builtin/commit.c:1289 builtin/commit.c:1451
+#: builtin/commit.c:1314 builtin/commit.c:1488
 msgid "show status in long format (default)"
 msgstr "以长格式显示状态(默认)"
 
-#: builtin/commit.c:1292 builtin/commit.c:1454
+#: builtin/commit.c:1317 builtin/commit.c:1491
 msgid "terminate entries with NUL"
 msgstr "条目以 NUL 字符结尾"
 
-#: builtin/commit.c:1294 builtin/commit.c:1298 builtin/commit.c:1457
-#: builtin/fast-export.c:999 builtin/fast-export.c:1002 builtin/tag.c:396
+#: builtin/commit.c:1319 builtin/commit.c:1323 builtin/commit.c:1494
+#: builtin/fast-export.c:1001 builtin/fast-export.c:1004 builtin/tag.c:397
 msgid "mode"
 msgstr "模式"
 
-#: builtin/commit.c:1295 builtin/commit.c:1457
+#: builtin/commit.c:1320 builtin/commit.c:1494
 msgid "show untracked files, optional modes: all, normal, no. (Default: all)"
 msgstr "显示未跟踪的文件,“模式”的可选参数:all、normal、no。(默认:all)"
 
-#: builtin/commit.c:1299
+#: builtin/commit.c:1324
 msgid ""
 "show ignored files, optional modes: traditional, matching, no. (Default: "
 "traditional)"
 msgstr ""
 "显示已忽略的文件,可选模式:traditional、matching、no。(默认:traditional)"
 
-#: builtin/commit.c:1301 parse-options.h:167
+#: builtin/commit.c:1326 parse-options.h:167
 msgid "when"
 msgstr "何时"
 
-#: builtin/commit.c:1302
+#: builtin/commit.c:1327
 msgid ""
 "ignore changes to submodules, optional when: all, dirty, untracked. "
 "(Default: all)"
 msgstr ""
 "忽略子模组的更改,“何时”的可选参数:all、dirty、untracked。(默认:all)"
 
-#: builtin/commit.c:1304
+#: builtin/commit.c:1329
 msgid "list untracked files in columns"
 msgstr "以列的方式显示未跟踪的文件"
 
-#: builtin/commit.c:1323
+#: builtin/commit.c:1330
+msgid "do not detect renames"
+msgstr "不检测重命名"
+
+#: builtin/commit.c:1332
+msgid "detect renames, optionally set similarity index"
+msgstr "检测重命名,可以设置索引相似度"
+
+#: builtin/commit.c:1352
 msgid "Unsupported combination of ignored and untracked-files arguments"
 msgstr "不支持已忽略和未跟踪文件参数的组合"
 
-#: builtin/commit.c:1413
+#: builtin/commit.c:1450
 msgid "suppress summary after successful commit"
 msgstr "提交成功后不显示概述信息"
 
-#: builtin/commit.c:1414
+#: builtin/commit.c:1451
 msgid "show diff in commit message template"
 msgstr "在提交说明模板里显示差异"
 
-#: builtin/commit.c:1416
+#: builtin/commit.c:1453
 msgid "Commit message options"
 msgstr "提交说明选项"
 
-#: builtin/commit.c:1417 builtin/tag.c:393
+#: builtin/commit.c:1454 builtin/tag.c:394
 msgid "read message from file"
 msgstr "从文件中读取提交说明"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "author"
 msgstr "作者"
 
-#: builtin/commit.c:1418
+#: builtin/commit.c:1455
 msgid "override author for commit"
 msgstr "提交时覆盖作者"
 
-#: builtin/commit.c:1419 builtin/gc.c:359
+#: builtin/commit.c:1456 builtin/gc.c:501
 msgid "date"
 msgstr "日期"
 
-#: builtin/commit.c:1419
+#: builtin/commit.c:1456
 msgid "override date for commit"
 msgstr "提交时覆盖日期"
 
-#: builtin/commit.c:1420 builtin/merge.c:226 builtin/notes.c:402
-#: builtin/notes.c:565 builtin/tag.c:391
+#: builtin/commit.c:1457 builtin/merge.c:228 builtin/notes.c:402
+#: builtin/notes.c:565 builtin/tag.c:392
 msgid "message"
 msgstr "说明"
 
-#: builtin/commit.c:1420
+#: builtin/commit.c:1457
 msgid "commit message"
 msgstr "提交说明"
 
-#: builtin/commit.c:1421 builtin/commit.c:1422 builtin/commit.c:1423
-#: builtin/commit.c:1424 parse-options.h:269 ref-filter.h:92
+#: builtin/commit.c:1458 builtin/commit.c:1459 builtin/commit.c:1460
+#: builtin/commit.c:1461 parse-options.h:270 ref-filter.h:92
 msgid "commit"
 msgstr "提交"
 
-#: builtin/commit.c:1421
+#: builtin/commit.c:1458
 msgid "reuse and edit message from specified commit"
 msgstr "重用并编辑指定提交的提交说明"
 
-#: builtin/commit.c:1422
+#: builtin/commit.c:1459
 msgid "reuse message from specified commit"
 msgstr "重用指定提交的提交说明"
 
-#: builtin/commit.c:1423
+#: builtin/commit.c:1460
 msgid "use autosquash formatted message to fixup specified commit"
 msgstr "使用 autosquash 格式的提交说明用以修正指定的提交"
 
-#: builtin/commit.c:1424
+#: builtin/commit.c:1461
 msgid "use autosquash formatted message to squash specified commit"
 msgstr "使用 autosquash 格式的提交说明用以压缩至指定的提交"
 
-#: builtin/commit.c:1425
+#: builtin/commit.c:1462
 msgid "the commit is authored by me now (used with -C/-c/--amend)"
 msgstr "现在将该提交的作者改为我(和 -C/-c/--amend 参数共用)"
 
-#: builtin/commit.c:1426 builtin/log.c:1446 builtin/merge.c:240
-#: builtin/pull.c:149 builtin/revert.c:105
+#: builtin/commit.c:1463 builtin/log.c:1446 builtin/merge.c:242
+#: builtin/pull.c:154 builtin/revert.c:105
 msgid "add Signed-off-by:"
 msgstr "添加 Signed-off-by: 签名"
 
-#: builtin/commit.c:1427
+#: builtin/commit.c:1464
 msgid "use specified template file"
 msgstr "使用指定的模板文件"
 
-#: builtin/commit.c:1428
+#: builtin/commit.c:1465
 msgid "force edit of commit"
 msgstr "强制编辑提交"
 
 #  译者:可选值,不能翻译(或是原文中笔误,应为 mode)
-#: builtin/commit.c:1429
+#: builtin/commit.c:1466
 msgid "default"
 msgstr "default"
 
-#: builtin/commit.c:1429 builtin/tag.c:397
+#: builtin/commit.c:1466 builtin/tag.c:398
 msgid "how to strip spaces and #comments from message"
 msgstr "设置如何删除提交说明里的空格和#注释"
 
-#: builtin/commit.c:1430
+#: builtin/commit.c:1467
 msgid "include status in commit message template"
 msgstr "在提交说明模板里包含状态信息"
 
-#: builtin/commit.c:1432 builtin/merge.c:238 builtin/pull.c:179
+#: builtin/commit.c:1469 builtin/merge.c:240 builtin/pull.c:184
 #: builtin/revert.c:113
 msgid "GPG sign commit"
 msgstr "GPG 提交签名"
 
-#: builtin/commit.c:1435
+#: builtin/commit.c:1472
 msgid "Commit contents options"
 msgstr "提交内容选项"
 
-#: builtin/commit.c:1436
+#: builtin/commit.c:1473
 msgid "commit all changed files"
 msgstr "提交所有改动的文件"
 
-#: builtin/commit.c:1437
+#: builtin/commit.c:1474
 msgid "add specified files to index for commit"
 msgstr "添加指定的文件到索引区等待提交"
 
-#: builtin/commit.c:1438
+#: builtin/commit.c:1475
 msgid "interactively add files"
 msgstr "交互式添加文件"
 
-#: builtin/commit.c:1439
+#: builtin/commit.c:1476
 msgid "interactively add changes"
 msgstr "交互式添加变更"
 
-#: builtin/commit.c:1440
+#: builtin/commit.c:1477
 msgid "commit only specified files"
 msgstr "只提交指定的文件"
 
-#: builtin/commit.c:1441
+#: builtin/commit.c:1478
 msgid "bypass pre-commit and commit-msg hooks"
 msgstr "绕过 pre-commit 和 commit-msg 钩子"
 
-#: builtin/commit.c:1442
+#: builtin/commit.c:1479
 msgid "show what would be committed"
 msgstr "显示将要提交的内容"
 
-#: builtin/commit.c:1455
+#: builtin/commit.c:1492
 msgid "amend previous commit"
 msgstr "修改先前的提交"
 
-#: builtin/commit.c:1456
+#: builtin/commit.c:1493
 msgid "bypass post-rewrite hook"
 msgstr "绕过 post-rewrite 钩子"
 
-#: builtin/commit.c:1461
+#: builtin/commit.c:1498
 msgid "ok to record an empty change"
 msgstr "允许一个空提交"
 
-#: builtin/commit.c:1463
+#: builtin/commit.c:1500
 msgid "ok to record a change with an empty message"
 msgstr "允许空的提交说明"
 
-#: builtin/commit.c:1536
+#: builtin/commit.c:1573
 #, c-format
 msgid "Corrupt MERGE_HEAD file (%s)"
 msgstr "损坏的 MERGE_HEAD 文件(%s)"
 
-#: builtin/commit.c:1543
+#: builtin/commit.c:1580
 msgid "could not read MERGE_MODE"
 msgstr "不能读取 MERGE_MODE"
 
-#: builtin/commit.c:1562
+#: builtin/commit.c:1599
 #, c-format
 msgid "could not read commit message: %s"
 msgstr "不能读取提交说明:%s"
 
-#: builtin/commit.c:1573
+#: builtin/commit.c:1610
 #, c-format
 msgid "Aborting commit due to empty commit message.\n"
 msgstr "终止提交因为提交说明为空。\n"
 
-#: builtin/commit.c:1578
+#: builtin/commit.c:1615
 #, c-format
 msgid "Aborting commit; you did not edit the message.\n"
 msgstr "终止提交;您未更改来自模版的提交说明。\n"
 
-#: builtin/commit.c:1613
+#: builtin/commit.c:1650
 msgid ""
 "Repository has been updated, but unable to write\n"
 "new_index file. Check that disk is not full and quota is\n"
@@ -7846,147 +8232,211 @@ msgstr ""
 "仓库已更新,但无法写 new_index 文件。检查是否磁盘已满\n"
 "或磁盘配额已耗尽,然后执行 \"git reset HEAD\" 恢复。"
 
+#: builtin/commit-graph.c:9
+msgid "git commit-graph [--object-dir <objdir>]"
+msgstr "git commit-graph [--object-dir <对象目录>]"
+
+#: builtin/commit-graph.c:10 builtin/commit-graph.c:16
+msgid "git commit-graph read [--object-dir <objdir>]"
+msgstr "git commit-graph read [--object-dir <对象目录>]"
+
+#: builtin/commit-graph.c:11 builtin/commit-graph.c:21
+msgid ""
+"git commit-graph write [--object-dir <objdir>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+msgstr ""
+"git commit-graph write [--object-dir <对象目录>] [--append] [--stdin-packs|--"
+"stdin-commits]"
+
+#: builtin/commit-graph.c:39 builtin/commit-graph.c:92
+#: builtin/commit-graph.c:147 builtin/fetch.c:161 builtin/log.c:1466
+msgid "dir"
+msgstr "目录"
+
+#: builtin/commit-graph.c:40 builtin/commit-graph.c:93
+#: builtin/commit-graph.c:148
+msgid "The object directory to store the graph"
+msgstr "保存图形的对象目录"
+
+#: builtin/commit-graph.c:95
+msgid "scan pack-indexes listed by stdin for commits"
+msgstr "从标准输入中的包索引文件列表中扫描提交"
+
+#: builtin/commit-graph.c:97
+msgid "start walk at commits listed by stdin"
+msgstr "从标准输入中的提交开始扫描"
+
+#: builtin/commit-graph.c:99
+msgid "include all commits already in the commit-graph file"
+msgstr "包含 commit-graph 文件中已有所有提交"
+
+#: builtin/commit-graph.c:108
+msgid "cannot use both --stdin-commits and --stdin-packs"
+msgstr "不能同时使用 --stdin-commits 和 --stdin-packs 选项"
+
 #: builtin/config.c:10
 msgid "git config [<options>]"
 msgstr "git config [<选项>]"
 
-#: builtin/config.c:58
+#: builtin/config.c:101
+#, c-format
+msgid "unrecognized --type argument, %s"
+msgstr "未能识别的 --type 参数,%s"
+
+#: builtin/config.c:123
 msgid "Config file location"
 msgstr "配置文件位置"
 
-#: builtin/config.c:59
+#: builtin/config.c:124
 msgid "use global config file"
 msgstr "使用全局配置文件"
 
-#: builtin/config.c:60
+#: builtin/config.c:125
 msgid "use system config file"
 msgstr "使用系统级配置文件"
 
-#: builtin/config.c:61
+#: builtin/config.c:126
 msgid "use repository config file"
 msgstr "使用仓库级配置文件"
 
-#: builtin/config.c:62
+#: builtin/config.c:127
 msgid "use given config file"
 msgstr "使用指定的配置文件"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "blob-id"
 msgstr "数据对象 ID"
 
-#: builtin/config.c:63
+#: builtin/config.c:128
 msgid "read config from given blob object"
 msgstr "从给定的数据对象读取配置"
 
-#: builtin/config.c:64
+#: builtin/config.c:129
 msgid "Action"
 msgstr "操作"
 
-#: builtin/config.c:65
+#: builtin/config.c:130
 msgid "get value: name [value-regex]"
 msgstr "获取值:name [value-regex]"
 
-#: builtin/config.c:66
+#: builtin/config.c:131
 msgid "get all values: key [value-regex]"
 msgstr "获得所有的值:key [value-regex]"
 
-#: builtin/config.c:67
+#: builtin/config.c:132
 msgid "get values for regexp: name-regex [value-regex]"
 msgstr "根据正则表达式获得值:name-regex [value-regex]"
 
-#: builtin/config.c:68
+#: builtin/config.c:133
 msgid "get value specific for the URL: section[.var] URL"
 msgstr "获得 URL 取值:section[.var] URL"
 
-#: builtin/config.c:69
+#: builtin/config.c:134
 msgid "replace all matching variables: name value [value_regex]"
 msgstr "替换所有匹配的变量:name value [value_regex]"
 
-#: builtin/config.c:70
+#: builtin/config.c:135
 msgid "add a new variable: name value"
 msgstr "添加一个新的变量:name value"
 
-#: builtin/config.c:71
+#: builtin/config.c:136
 msgid "remove a variable: name [value-regex]"
 msgstr "删除一个变量:name [value-regex]"
 
-#: builtin/config.c:72
+#: builtin/config.c:137
 msgid "remove all matches: name [value-regex]"
 msgstr "删除所有匹配项:name [value-regex]"
 
-#: builtin/config.c:73
+#: builtin/config.c:138
 msgid "rename section: old-name new-name"
 msgstr "重命名小节:old-name new-name"
 
-#: builtin/config.c:74
+#: builtin/config.c:139
 msgid "remove a section: name"
 msgstr "删除一个小节:name"
 
-#: builtin/config.c:75
+#: builtin/config.c:140
 msgid "list all"
 msgstr "列出所有"
 
-#: builtin/config.c:76
+#: builtin/config.c:141
 msgid "open an editor"
 msgstr "打开一个编辑器"
 
-#: builtin/config.c:77
+#: builtin/config.c:142
 msgid "find the color configured: slot [default]"
 msgstr "获得配置的颜色:配置 [默认]"
 
-#: builtin/config.c:78
+#: builtin/config.c:143
 msgid "find the color setting: slot [stdout-is-tty]"
 msgstr "获得颜色设置:配置 [stdout-is-tty]"
 
-#: builtin/config.c:79
+#: builtin/config.c:144
 msgid "Type"
 msgstr "类型"
 
-#: builtin/config.c:80
+#: builtin/config.c:145
+msgid "value is given this type"
+msgstr "取值为该类型"
+
+#: builtin/config.c:146
 msgid "value is \"true\" or \"false\""
 msgstr "值是 \"true\" 或 \"false\""
 
-#: builtin/config.c:81
+#: builtin/config.c:147
 msgid "value is decimal number"
 msgstr "值是十进制数"
 
-#: builtin/config.c:82
+#: builtin/config.c:148
 msgid "value is --bool or --int"
 msgstr "值是 --bool or --int"
 
-#: builtin/config.c:83
+#: builtin/config.c:149
 msgid "value is a path (file or directory name)"
 msgstr "值是一个路径(文件或目录名)"
 
-#: builtin/config.c:84
+#: builtin/config.c:150
 msgid "value is an expiry date"
 msgstr "值是一个到期日期"
 
-#: builtin/config.c:85
+#: builtin/config.c:151
 msgid "Other"
 msgstr "其它"
 
-#: builtin/config.c:86
+#: builtin/config.c:152
 msgid "terminate values with NUL byte"
 msgstr "终止值是 NUL 字节"
 
-#: builtin/config.c:87
+#: builtin/config.c:153
 msgid "show variable names only"
 msgstr "只显示变量名"
 
-#: builtin/config.c:88
+#: builtin/config.c:154
 msgid "respect include directives on lookup"
 msgstr "查询时参照 include 指令递归查找"
 
-#: builtin/config.c:89
+#: builtin/config.c:155
 msgid "show origin of config (file, standard input, blob, command line)"
 msgstr "显示配置的来源(文件、标准输入、数据对象,或命令行)"
 
-#: builtin/config.c:335
+#: builtin/config.c:156
+msgid "value"
+msgstr "取值"
+
+#: builtin/config.c:156
+msgid "with --get, use default value when missing entry"
+msgstr "使用 --get 参数,当缺少设置时使用默认值"
+
+#: builtin/config.c:332
+#, c-format
+msgid "failed to format default config value: %s"
+msgstr "无法格式化默认配置取值:%s"
+
+#: builtin/config.c:431
 msgid "unable to parse default color value"
 msgstr "不能解析默认颜色值"
 
-#: builtin/config.c:479
+#: builtin/config.c:575
 #, c-format
 msgid ""
 "# This is Git's per-user configuration file.\n"
@@ -8001,16 +8451,20 @@ msgstr ""
 "#\tname = %s\n"
 "#\temail = %s\n"
 
-#: builtin/config.c:507
+#: builtin/config.c:603
 msgid "--local can only be used inside a git repository"
 msgstr "--local 只能在一个仓库内使用"
 
-#: builtin/config.c:632
+#: builtin/config.c:606
+msgid "--blob can only be used inside a git repository"
+msgstr "--blob 只能在一个仓库内使用"
+
+#: builtin/config.c:735
 #, c-format
 msgid "cannot create configuration file %s"
 msgstr "不能创建配置文件 %s"
 
-#: builtin/config.c:645
+#: builtin/config.c:748
 #, c-format
 msgid ""
 "cannot overwrite multiple values with a single value\n"
@@ -8019,11 +8473,11 @@ msgstr ""
 "无法用一个值覆盖多个值\n"
 "       使用一个正则表达式、--add 或 --replace-all 来修改 %s。"
 
-#: builtin/count-objects.c:88
+#: builtin/count-objects.c:90
 msgid "git count-objects [-v] [-H | --human-readable]"
 msgstr "git count-objects [-v] [-H | --human-readable]"
 
-#: builtin/count-objects.c:98
+#: builtin/count-objects.c:100
 msgid "print sizes in human readable format"
 msgstr "以用户可读的格式显示大小"
 
@@ -8287,278 +8741,284 @@ msgstr "执行一个全目录差异比较"
 msgid "do not prompt before launching a diff tool"
 msgstr "启动差异比较工具之前不提示"
 
-#: builtin/difftool.c:705
+#: builtin/difftool.c:704
 msgid "use symlinks in dir-diff mode"
 msgstr "在 dir-diff 模式中使用符号链接"
 
-#: builtin/difftool.c:706
+#: builtin/difftool.c:705
 msgid "<tool>"
 msgstr "<工具>"
 
-#: builtin/difftool.c:707
+#: builtin/difftool.c:706
 msgid "use the specified diff tool"
 msgstr "使用指定的差异比较工具"
 
-#: builtin/difftool.c:709
+#: builtin/difftool.c:708
 msgid "print a list of diff tools that may be used with `--tool`"
 msgstr "显示可以用在 `--tool` 参数后的差异工具列表"
 
-#: builtin/difftool.c:712
+#: builtin/difftool.c:711
 msgid ""
 "make 'git-difftool' exit when an invoked diff tool returns a non - zero exit "
 "code"
 msgstr "当执行 diff 工具返回非零退出码时,使 'git-difftool' 退出"
 
-#: builtin/difftool.c:714
+#: builtin/difftool.c:713
 msgid "<command>"
 msgstr "<命令>"
 
-#: builtin/difftool.c:715
+#: builtin/difftool.c:714
 msgid "specify a custom command for viewing diffs"
 msgstr "指定一个用于查看差异的自定义命令"
 
-#: builtin/difftool.c:739
+#: builtin/difftool.c:738
 msgid "no <tool> given for --tool=<tool>"
 msgstr "没有为 --tool=<工具> 参数提供 <工具>"
 
-#: builtin/difftool.c:746
+#: builtin/difftool.c:745
 msgid "no <cmd> given for --extcmd=<cmd>"
 msgstr "没有为 --extcmd=<命令> 参数提供 <命令>"
 
-#: builtin/fast-export.c:26
+#: builtin/fast-export.c:27
 msgid "git fast-export [rev-list-opts]"
 msgstr "git fast-export [rev-list-opts]"
 
-#: builtin/fast-export.c:998
+#: builtin/fast-export.c:1000
 msgid "show progress after <n> objects"
 msgstr "在 <n> 个对象之后显示进度"
 
-#: builtin/fast-export.c:1000
+#: builtin/fast-export.c:1002
 msgid "select handling of signed tags"
 msgstr "选择如何处理签名标签"
 
-#: builtin/fast-export.c:1003
+#: builtin/fast-export.c:1005
 msgid "select handling of tags that tag filtered objects"
 msgstr "选择当标签指向被过滤对象时该标签的处理方式"
 
-#: builtin/fast-export.c:1006
+#: builtin/fast-export.c:1008
 msgid "Dump marks to this file"
 msgstr "把标记存储到这个文件"
 
-#: builtin/fast-export.c:1008
+#: builtin/fast-export.c:1010
 msgid "Import marks from this file"
 msgstr "从这个文件导入标记"
 
-#: builtin/fast-export.c:1010
+#: builtin/fast-export.c:1012
 msgid "Fake a tagger when tags lack one"
 msgstr "当标签缺少标记者字段时,假装提供一个"
 
-#: builtin/fast-export.c:1012
+#: builtin/fast-export.c:1014
 msgid "Output full tree for each commit"
 msgstr "每次提交都输出整个树"
 
-#: builtin/fast-export.c:1014
+#: builtin/fast-export.c:1016
 msgid "Use the done feature to terminate the stream"
 msgstr "使用 done 功能来终止流"
 
-#: builtin/fast-export.c:1015
+#: builtin/fast-export.c:1017
 msgid "Skip output of blob data"
 msgstr "跳过数据对象的输出"
 
-#: builtin/fast-export.c:1016
+#: builtin/fast-export.c:1018
 msgid "refspec"
 msgstr "引用规格"
 
-#: builtin/fast-export.c:1017
+#: builtin/fast-export.c:1019
 msgid "Apply refspec to exported refs"
 msgstr "对导出的引用应用引用规格"
 
-#: builtin/fast-export.c:1018
+#: builtin/fast-export.c:1020
 msgid "anonymize output"
 msgstr "匿名输出"
 
-#: builtin/fetch.c:25
+#: builtin/fetch.c:26
 msgid "git fetch [<options>] [<repository> [<refspec>...]]"
 msgstr "git fetch [<选项>] [<仓库> [<引用规格>...]]"
 
-#: builtin/fetch.c:26
+#: builtin/fetch.c:27
 msgid "git fetch [<options>] <group>"
 msgstr "git fetch [<选项>] <组>"
 
-#: builtin/fetch.c:27
+#: builtin/fetch.c:28
 msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]"
 msgstr "git fetch --multiple [<选项>] [(<仓库> | <组>)...]"
 
-#: builtin/fetch.c:28
+#: builtin/fetch.c:29
 msgid "git fetch --all [<options>]"
 msgstr "git fetch --all [<选项>]"
 
-#: builtin/fetch.c:124 builtin/pull.c:188
+#: builtin/fetch.c:123 builtin/pull.c:193
 msgid "fetch from all remotes"
 msgstr "从所有的远程抓取"
 
-#: builtin/fetch.c:126 builtin/pull.c:191
+#: builtin/fetch.c:125 builtin/pull.c:196
 msgid "append to .git/FETCH_HEAD instead of overwriting"
 msgstr "追加到 .git/FETCH_HEAD 而不是覆盖它"
 
-#: builtin/fetch.c:128 builtin/pull.c:194
+#: builtin/fetch.c:127 builtin/pull.c:199
 msgid "path to upload pack on remote end"
 msgstr "上传包到远程的路径"
 
-#: builtin/fetch.c:129 builtin/pull.c:196
+#: builtin/fetch.c:128 builtin/pull.c:201
 msgid "force overwrite of local branch"
 msgstr "强制覆盖本地分支"
 
-#: builtin/fetch.c:131
+#: builtin/fetch.c:130
 msgid "fetch from multiple remotes"
 msgstr "从多个远程抓取"
 
-#: builtin/fetch.c:133 builtin/pull.c:198
+#: builtin/fetch.c:132 builtin/pull.c:203
 msgid "fetch all tags and associated objects"
 msgstr "抓取所有的标签和关联对象"
 
-#: builtin/fetch.c:135
+#: builtin/fetch.c:134
 msgid "do not fetch all tags (--no-tags)"
 msgstr "不抓取任何标签(--no-tags)"
 
-#: builtin/fetch.c:137
+#: builtin/fetch.c:136
 msgid "number of submodules fetched in parallel"
 msgstr "子模组获取的并发数"
 
-#: builtin/fetch.c:139 builtin/pull.c:201
+#: builtin/fetch.c:138 builtin/pull.c:206
 msgid "prune remote-tracking branches no longer on remote"
 msgstr "清除远程已经不存在的分支的跟踪分支"
 
-#: builtin/fetch.c:141
+#: builtin/fetch.c:140
 msgid "prune local tags no longer on remote and clobber changed tags"
 msgstr "清除远程不存在的本地标签,并且替换变更标签"
 
 #  译者:可选值,不能翻译
-#: builtin/fetch.c:142 builtin/fetch.c:165 builtin/pull.c:126
+#: builtin/fetch.c:141 builtin/fetch.c:164 builtin/pull.c:131
 msgid "on-demand"
 msgstr "on-demand"
 
-#: builtin/fetch.c:143
+#: builtin/fetch.c:142
 msgid "control recursive fetching of submodules"
 msgstr "控制子模组的递归抓取"
 
-#: builtin/fetch.c:147 builtin/pull.c:209
+#: builtin/fetch.c:146 builtin/pull.c:214
 msgid "keep downloaded pack"
 msgstr "保持下载包"
 
-#: builtin/fetch.c:149
+#: builtin/fetch.c:148
 msgid "allow updating of HEAD ref"
 msgstr "允许更新 HEAD 引用"
 
-#: builtin/fetch.c:152 builtin/fetch.c:158 builtin/pull.c:212
+#: builtin/fetch.c:151 builtin/fetch.c:157 builtin/pull.c:217
 msgid "deepen history of shallow clone"
 msgstr "深化浅克隆的历史"
 
-#: builtin/fetch.c:154
+#: builtin/fetch.c:153
 msgid "deepen history of shallow repository based on time"
 msgstr "基于时间来深化浅克隆的历史"
 
-#: builtin/fetch.c:160 builtin/pull.c:215
+#: builtin/fetch.c:159 builtin/pull.c:220
 msgid "convert to a complete repository"
 msgstr "转换为一个完整的仓库"
 
-#: builtin/fetch.c:162 builtin/log.c:1466
-msgid "dir"
-msgstr "目录"
-
-#: builtin/fetch.c:163
+#: builtin/fetch.c:162
 msgid "prepend this to submodule path output"
 msgstr "在子模组路径输出的前面加上此目录"
 
-#: builtin/fetch.c:166
+#: builtin/fetch.c:165
 msgid ""
 "default for recursive fetching of submodules (lower priority than config "
 "files)"
 msgstr "递归获取子模组的缺省值(比配置文件优先级低)"
 
-#: builtin/fetch.c:170 builtin/pull.c:218
+#: builtin/fetch.c:169 builtin/pull.c:223
 msgid "accept refs that update .git/shallow"
 msgstr "接受更新 .git/shallow 的引用"
 
-#: builtin/fetch.c:171 builtin/pull.c:220
+#: builtin/fetch.c:170 builtin/pull.c:225
 msgid "refmap"
 msgstr "引用映射"
 
-#: builtin/fetch.c:172 builtin/pull.c:221
+#: builtin/fetch.c:171 builtin/pull.c:226
 msgid "specify fetch refmap"
 msgstr "指定获取操作的引用映射"
 
-#: builtin/fetch.c:431
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:172
+msgid "server-specific"
+msgstr "server-specific"
+
+#: builtin/fetch.c:172 builtin/ls-remote.c:77 builtin/push.c:582
+#: builtin/send-pack.c:173
+msgid "option to transmit"
+msgstr "传输选项"
+
+#: builtin/fetch.c:442
 msgid "Couldn't find remote ref HEAD"
 msgstr "无法发现远程 HEAD 引用"
 
-#: builtin/fetch.c:549
+#: builtin/fetch.c:560
 #, c-format
 msgid "configuration fetch.output contains invalid value %s"
 msgstr "配置变量 fetch.output 包含无效值 %s"
 
-#: builtin/fetch.c:642
+#: builtin/fetch.c:653
 #, c-format
 msgid "object %s not found"
 msgstr "对象 %s 未发现"
 
-#: builtin/fetch.c:646
+#: builtin/fetch.c:657
 msgid "[up to date]"
 msgstr "[最新]"
 
-#: builtin/fetch.c:659 builtin/fetch.c:739
+#: builtin/fetch.c:670 builtin/fetch.c:750
 msgid "[rejected]"
 msgstr "[已拒绝]"
 
-#: builtin/fetch.c:660
+#: builtin/fetch.c:671
 msgid "can't fetch in current branch"
 msgstr "当前分支下不能执行获取操作"
 
-#: builtin/fetch.c:669
+#: builtin/fetch.c:680
 msgid "[tag update]"
 msgstr "[标签更新]"
 
-#: builtin/fetch.c:670 builtin/fetch.c:703 builtin/fetch.c:719
-#: builtin/fetch.c:734
+#: builtin/fetch.c:681 builtin/fetch.c:714 builtin/fetch.c:730
+#: builtin/fetch.c:745
 msgid "unable to update local ref"
 msgstr "不能更新本地引用"
 
-#: builtin/fetch.c:689
+#: builtin/fetch.c:700
 msgid "[new tag]"
 msgstr "[新标签]"
 
-#: builtin/fetch.c:692
+#: builtin/fetch.c:703
 msgid "[new branch]"
 msgstr "[新分支]"
 
-#: builtin/fetch.c:695
+#: builtin/fetch.c:706
 msgid "[new ref]"
 msgstr "[新引用]"
 
-#: builtin/fetch.c:734
+#: builtin/fetch.c:745
 msgid "forced update"
 msgstr "强制更新"
 
-#: builtin/fetch.c:739
+#: builtin/fetch.c:750
 msgid "non-fast-forward"
 msgstr "非快进"
 
-#: builtin/fetch.c:784
+#: builtin/fetch.c:795
 #, c-format
 msgid "%s did not send all necessary objects\n"
 msgstr "%s 未发送所有必须的对象\n"
 
-#: builtin/fetch.c:804
+#: builtin/fetch.c:815
 #, c-format
 msgid "reject %s because shallow roots are not allowed to be updated"
 msgstr "拒绝 %s 因为浅克隆不允许被更新"
 
-#: builtin/fetch.c:892 builtin/fetch.c:988
+#: builtin/fetch.c:903 builtin/fetch.c:999
 #, c-format
 msgid "From %.*s\n"
 msgstr "来自 %.*s\n"
 
-#: builtin/fetch.c:903
+#: builtin/fetch.c:914
 #, c-format
 msgid ""
 "some local refs could not be updated; try running\n"
@@ -8568,95 +9028,95 @@ msgstr ""
 " 'git remote prune %s' 来删除旧的、有冲突的分支"
 
 #  译者:注意保持前导空格
-#: builtin/fetch.c:958
+#: builtin/fetch.c:969
 #, c-format
 msgid "   (%s will become dangling)"
 msgstr "   (%s 将成为摇摆状态)"
 
 #  译者:注意保持前导空格
-#: builtin/fetch.c:959
+#: builtin/fetch.c:970
 #, c-format
 msgid "   (%s has become dangling)"
 msgstr "   (%s 已成为摇摆状态)"
 
-#: builtin/fetch.c:991
+#: builtin/fetch.c:1002
 msgid "[deleted]"
 msgstr "[已删除]"
 
-#: builtin/fetch.c:992 builtin/remote.c:1024
+#: builtin/fetch.c:1003 builtin/remote.c:1033
 msgid "(none)"
 msgstr "(无)"
 
-#: builtin/fetch.c:1015
+#: builtin/fetch.c:1026
 #, c-format
 msgid "Refusing to fetch into current branch %s of non-bare repository"
 msgstr "拒绝获取到非纯仓库的当前分支 %s"
 
-#: builtin/fetch.c:1034
+#: builtin/fetch.c:1045
 #, c-format
 msgid "Option \"%s\" value \"%s\" is not valid for %s"
 msgstr "选项 \"%s\" 的值 \"%s\" 对于 %s 是无效的"
 
-#: builtin/fetch.c:1037
+#: builtin/fetch.c:1048
 #, c-format
 msgid "Option \"%s\" is ignored for %s\n"
 msgstr "选项 \"%s\" 为 %s 所忽略\n"
 
-#: builtin/fetch.c:1277
+#: builtin/fetch.c:1287
 #, c-format
 msgid "Fetching %s\n"
 msgstr "正在获取 %s\n"
 
-#: builtin/fetch.c:1279 builtin/remote.c:97
+#: builtin/fetch.c:1289 builtin/remote.c:98
 #, c-format
 msgid "Could not fetch %s"
 msgstr "不能获取 %s"
 
-#: builtin/fetch.c:1325 builtin/fetch.c:1498
+#: builtin/fetch.c:1335 builtin/fetch.c:1503
 msgid ""
 "--filter can only be used with the remote configured in core.partialClone"
 msgstr "只可以将 --filter 用于在 core.partialClone 中配置的远程仓库"
 
-#: builtin/fetch.c:1350
+#: builtin/fetch.c:1358
 msgid ""
 "No remote repository specified.  Please, specify either a URL or a\n"
 "remote name from which new revisions should be fetched."
 msgstr "未指定远程仓库。请通过一个 URL 或远程仓库名指定,用以获取新提交。"
 
-#: builtin/fetch.c:1394
+#: builtin/fetch.c:1395
 msgid "You need to specify a tag name."
 msgstr "您需要指定一个标签名称。"
 
-#: builtin/fetch.c:1439
+#: builtin/fetch.c:1444
 msgid "Negative depth in --deepen is not supported"
 msgstr "--deepen 不支持负数深度"
 
-#: builtin/fetch.c:1441
+#: builtin/fetch.c:1446
 msgid "--deepen and --depth are mutually exclusive"
 msgstr "--deepen 和 --depth 是互斥的"
 
-#: builtin/fetch.c:1446
+#: builtin/fetch.c:1451
 msgid "--depth and --unshallow cannot be used together"
 msgstr "--depth 和 --unshallow 不能同时使用"
 
-#: builtin/fetch.c:1448
+#: builtin/fetch.c:1453
 msgid "--unshallow on a complete repository does not make sense"
 msgstr "对于一个完整的仓库,参数 --unshallow 没有意义"
 
-#: builtin/fetch.c:1464
+#: builtin/fetch.c:1469
 msgid "fetch --all does not take a repository argument"
 msgstr "fetch --all 不能带一个仓库参数"
 
-#: builtin/fetch.c:1466
+#: builtin/fetch.c:1471
 msgid "fetch --all does not make sense with refspecs"
 msgstr "fetch --all 带引用规格没有任何意义"
 
-#: builtin/fetch.c:1475
+#: builtin/fetch.c:1480
 #, c-format
 msgid "No such remote or remote group: %s"
 msgstr "没有这样的远程或远程组:%s"
 
-#: builtin/fetch.c:1482
+#: builtin/fetch.c:1487
 msgid "Fetching a group and specifying refspecs does not make sense"
 msgstr "获取组并指定引用规格没有意义"
 
@@ -8721,7 +9181,7 @@ msgstr "引用占位符适用于 Tcl"
 msgid "show only <n> matched refs"
 msgstr "只显示 <n> 个匹配的引用"
 
-#: builtin/for-each-ref.c:39 builtin/tag.c:420
+#: builtin/for-each-ref.c:39 builtin/tag.c:421
 msgid "respect format colors"
 msgstr "遵照格式中的颜色输出"
 
@@ -8745,81 +9205,81 @@ msgstr "只打印包含该提交的引用"
 msgid "print only refs which don't contain the commit"
 msgstr "只打印不包含该提交的引用"
 
-#: builtin/fsck.c:568
+#: builtin/fsck.c:569
 msgid "Checking object directories"
 msgstr "检查对象目录中"
 
-#: builtin/fsck.c:660
+#: builtin/fsck.c:661
 msgid "git fsck [<options>] [<object>...]"
 msgstr "git fsck [<选项>] [<对象>...]"
 
-#: builtin/fsck.c:666
+#: builtin/fsck.c:667
 msgid "show unreachable objects"
 msgstr "显示不可达的对象"
 
-#: builtin/fsck.c:667
+#: builtin/fsck.c:668
 msgid "show dangling objects"
 msgstr "显示摇摆的对象"
 
-#: builtin/fsck.c:668
+#: builtin/fsck.c:669
 msgid "report tags"
 msgstr "报告标签"
 
-#: builtin/fsck.c:669
+#: builtin/fsck.c:670
 msgid "report root nodes"
 msgstr "报告根节点"
 
-#: builtin/fsck.c:670
+#: builtin/fsck.c:671
 msgid "make index objects head nodes"
 msgstr "将索引亦作为检查的头节点"
 
-#: builtin/fsck.c:671
+#: builtin/fsck.c:672
 msgid "make reflogs head nodes (default)"
 msgstr "将引用日志作为检查的头节点(默认)"
 
-#: builtin/fsck.c:672
+#: builtin/fsck.c:673
 msgid "also consider packs and alternate objects"
 msgstr "也考虑包和备用对象"
 
-#: builtin/fsck.c:673
+#: builtin/fsck.c:674
 msgid "check only connectivity"
 msgstr "仅检查连通性"
 
-#: builtin/fsck.c:674
+#: builtin/fsck.c:675
 msgid "enable more strict checking"
 msgstr "启用更严格的检查"
 
-#: builtin/fsck.c:676
+#: builtin/fsck.c:677
 msgid "write dangling objects in .git/lost-found"
 msgstr "将摇摆对象写入 .git/lost-found 中"
 
-#: builtin/fsck.c:677 builtin/prune.c:108
+#: builtin/fsck.c:678 builtin/prune.c:109
 msgid "show progress"
 msgstr "显示进度"
 
-#: builtin/fsck.c:678
+#: builtin/fsck.c:679
 msgid "show verbose names for reachable objects"
 msgstr "显示可达对象的详细名称"
 
-#: builtin/fsck.c:742
+#: builtin/fsck.c:745
 msgid "Checking objects"
 msgstr "检查对象中"
 
-#: builtin/gc.c:27
+#: builtin/gc.c:33
 msgid "git gc [<options>]"
 msgstr "git gc [<选项>]"
 
-#: builtin/gc.c:80
+#: builtin/gc.c:88
 #, c-format
 msgid "Failed to fstat %s: %s"
 msgstr "对 %s 调用 fstat 失败:%s"
 
-#: builtin/gc.c:312
+#: builtin/gc.c:452
 #, c-format
 msgid "Can't stat %s"
 msgstr "不能对 %s 调用 stat"
 
-#: builtin/gc.c:321
+#: builtin/gc.c:461
 #, c-format
 msgid ""
 "The last gc run reported the following. Please correct the root cause\n"
@@ -8833,64 +9293,73 @@ msgstr ""
 "\n"
 "%s"
 
-#: builtin/gc.c:360
+#: builtin/gc.c:502
 msgid "prune unreferenced objects"
 msgstr "清除未引用的对象"
 
-#: builtin/gc.c:362
+#: builtin/gc.c:504
 msgid "be more thorough (increased runtime)"
 msgstr "更彻底(增加运行时间)"
 
-#: builtin/gc.c:363
+#: builtin/gc.c:505
 msgid "enable auto-gc mode"
 msgstr "启用自动垃圾回收模式"
 
-#: builtin/gc.c:366
+#: builtin/gc.c:508
 msgid "force running gc even if there may be another gc running"
 msgstr "强制执行 gc 即使另外一个 gc 正在执行"
 
-#: builtin/gc.c:384
+#: builtin/gc.c:511
+msgid "repack all other packs except the largest pack"
+msgstr "除了最大的包之外,对所有其它包文件重新打包"
+
+#: builtin/gc.c:528
+#, c-format
+msgid "failed to parse gc.logexpiry value %s"
+msgstr "无法解析 gc.logexpiry 的值 %s"
+
+#: builtin/gc.c:539
 #, c-format
-msgid "Failed to parse gc.logexpiry value %s"
+msgid "failed to parse prune expiry value %s"
 msgstr "无法解析 gc.logexpiry 的值 %s"
 
-#: builtin/gc.c:412
+#: builtin/gc.c:559
 #, c-format
 msgid "Auto packing the repository in background for optimum performance.\n"
 msgstr "自动在后台执行仓库打包以求最佳性能。\n"
 
-#: builtin/gc.c:414
+#: builtin/gc.c:561
 #, c-format
 msgid "Auto packing the repository for optimum performance.\n"
 msgstr "自动打包仓库以求最佳性能。\n"
 
-#: builtin/gc.c:415
+#: builtin/gc.c:562
 #, c-format
 msgid "See \"git help gc\" for manual housekeeping.\n"
 msgstr "手工维护参见 \"git help gc\"。\n"
 
-#: builtin/gc.c:440
+#: builtin/gc.c:598
 #, c-format
 msgid ""
 "gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)"
 msgstr ""
 "已经有一个 gc 正运行在机器 '%s' pid %<PRIuMAX>(如果不是,使用 --force)"
 
-#: builtin/gc.c:487
+#: builtin/gc.c:645
 msgid ""
 "There are too many unreachable loose objects; run 'git prune' to remove them."
 msgstr "有太多不可达的松散对象,运行 'git prune' 删除它们。"
 
-#: builtin/grep.c:27
+#: builtin/grep.c:28
 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]"
 msgstr "git grep [<选项>] [-e] <模式> [<版本>...] [[--] <路径>...]"
 
-#: builtin/grep.c:225
+#: builtin/grep.c:226
 #, c-format
 msgid "grep: failed to create thread: %s"
 msgstr "grep:无法创建线程:%s"
 
-#: builtin/grep.c:283
+#: builtin/grep.c:284
 #, c-format
 msgid "invalid number of threads specified (%d) for %s"
 msgstr "为 %2$s 设定的线程数 (%1$d) 无效"
@@ -8899,17 +9368,17 @@ msgstr "为 %2$s 设定的线程数 (%1$d) 无效"
 #. variable for tweaking threads, currently
 #. grep.threads
 #.
-#: builtin/grep.c:292 builtin/index-pack.c:1523 builtin/index-pack.c:1712
+#: builtin/grep.c:293 builtin/index-pack.c:1535 builtin/index-pack.c:1727
 #, c-format
 msgid "no threads support, ignoring %s"
 msgstr "没有线程支持,忽略 %s"
 
-#: builtin/grep.c:460 builtin/grep.c:580 builtin/grep.c:622
+#: builtin/grep.c:461 builtin/grep.c:582 builtin/grep.c:623
 #, c-format
 msgid "unable to read tree (%s)"
 msgstr "无法读取树(%s)"
 
-#: builtin/grep.c:637
+#: builtin/grep.c:638
 #, c-format
 msgid "unable to grep from object of type %s"
 msgstr "无法抓取来自于 %s 类型的对象"
@@ -9109,7 +9578,7 @@ msgstr "--no-index 或 --untracked 不能和版本同时使用"
 msgid "unable to resolve revision: %s"
 msgstr "不能解析版本:%s"
 
-#: builtin/grep.c:1036 builtin/index-pack.c:1519
+#: builtin/grep.c:1036 builtin/index-pack.c:1531
 #, c-format
 msgid "invalid number of threads specified (%d)"
 msgstr "指定的线程数无效(%d)"
@@ -9179,58 +9648,62 @@ msgstr "允许对任意随机垃圾数据做散列来创建损坏的对象以便
 msgid "process file as it were from this path"
 msgstr "处理文件并假设其来自于此路径"
 
-#: builtin/help.c:43
+#: builtin/help.c:45
 msgid "print all available commands"
 msgstr "打印所有可用的命令"
 
-#: builtin/help.c:44
+#: builtin/help.c:46
 msgid "exclude guides"
 msgstr "排除向导"
 
-#: builtin/help.c:45
+#: builtin/help.c:47
 msgid "print list of useful guides"
 msgstr "显示有用的指南列表"
 
-#: builtin/help.c:46
+#: builtin/help.c:48
 msgid "show man page"
 msgstr "显示 man 手册"
 
-#: builtin/help.c:47
+#: builtin/help.c:49
 msgid "show manual in web browser"
 msgstr "在 web 浏览器中显示手册"
 
-#: builtin/help.c:49
+#: builtin/help.c:51
 msgid "show info page"
 msgstr "显示 info 手册"
 
-#: builtin/help.c:55
+#: builtin/help.c:53
+msgid "print command description"
+msgstr "打印命令描述"
+
+#: builtin/help.c:58
 msgid "git help [--all] [--guides] [--man | --web | --info] [<command>]"
 msgstr "git help [--all] [--guides] [--man | --web | --info] [<命令>]"
 
-#: builtin/help.c:67
+#: builtin/help.c:70
 #, c-format
 msgid "unrecognized help format '%s'"
 msgstr "未能识别的帮助格式 '%s'"
 
-#: builtin/help.c:94
+#: builtin/help.c:97
 msgid "Failed to start emacsclient."
 msgstr "无法启动 emacsclient。"
 
-#: builtin/help.c:107
+#: builtin/help.c:110
 msgid "Failed to parse emacsclient version."
 msgstr "无法解析 emacsclient 版本。"
 
-#: builtin/help.c:115
+#: builtin/help.c:118
 #, c-format
 msgid "emacsclient version '%d' too old (< 22)."
 msgstr "emacsclient 版本 '%d' 太老(< 22)。"
 
-#: builtin/help.c:133 builtin/help.c:155 builtin/help.c:165 builtin/help.c:173
+#: builtin/help.c:136 builtin/help.c:158 builtin/help.c:168 builtin/help.c:176
 #, c-format
 msgid "failed to exec '%s'"
 msgstr "无法执行 '%s'"
 
-#: builtin/help.c:211
+#: builtin/help.c:214
 #, c-format
 msgid ""
 "'%s': path for unsupported man viewer.\n"
@@ -9239,7 +9712,7 @@ msgstr ""
 "'%s':不支持的 man 手册查看器的路径。\n"
 "请使用 'man.<工具>.cmd'。"
 
-#: builtin/help.c:223
+#: builtin/help.c:226
 #, c-format
 msgid ""
 "'%s': cmd for supported man viewer.\n"
@@ -9248,358 +9721,326 @@ msgstr ""
 "'%s': 支持的 man 手册查看器命令。\n"
 "请使用 'man.<工具>.path'。"
 
-#: builtin/help.c:340
+#: builtin/help.c:343
 #, c-format
 msgid "'%s': unknown man viewer."
 msgstr "'%s':未知的 man 查看器。"
 
-#: builtin/help.c:357
+#: builtin/help.c:360
 msgid "no man viewer handled the request"
 msgstr "没有 man 查看器处理此请求"
 
-#: builtin/help.c:365
+#: builtin/help.c:368
 msgid "no info viewer handled the request"
 msgstr "没有 info 查看器处理此请求"
 
-#: builtin/help.c:407
-msgid "Defining attributes per path"
-msgstr "定义路径的属性"
-
-#: builtin/help.c:408
-msgid "Everyday Git With 20 Commands Or So"
-msgstr "每一天 Git 常用的约 20 条命令"
+#: builtin/help.c:415
+#, c-format
+msgid "'%s' is aliased to '%s'"
+msgstr "'%s' 是 '%s' 的别名"
 
-#: builtin/help.c:409
-msgid "A Git glossary"
-msgstr "Git 词汇表"
+#: builtin/help.c:442 builtin/help.c:459
+#, c-format
+msgid "usage: %s%s"
+msgstr "用法:%s%s"
 
-#: builtin/help.c:410
-msgid "Specifies intentionally untracked files to ignore"
-msgstr "忽略指定的未跟踪文件"
+#: builtin/index-pack.c:158
+#, c-format
+msgid "unable to open %s"
+msgstr "不能打开 %s"
 
-#: builtin/help.c:411
-msgid "Defining submodule properties"
-msgstr "定义子模组属性"
-
-#: builtin/help.c:412
-msgid "Specifying revisions and ranges for Git"
-msgstr "指定 Git 的版本和版本范围"
-
-#: builtin/help.c:413
-msgid "A tutorial introduction to Git (for version 1.5.1 or newer)"
-msgstr "一个 Git 教程(针对 1.5.1 或更新版本)"
-
-#: builtin/help.c:414
-msgid "An overview of recommended workflows with Git"
-msgstr "Git 推荐的工作流概览"
-
-#: builtin/help.c:426
-msgid "The common Git guides are:\n"
-msgstr "最常用的 Git 向导有:\n"
-
-#: builtin/help.c:444
-#, c-format
-msgid "'%s' is aliased to '%s'"
-msgstr "'%s' 是 '%s' 的别名"
-
-#: builtin/help.c:466 builtin/help.c:483
-#, c-format
-msgid "usage: %s%s"
-msgstr "用法:%s%s"
-
-#: builtin/index-pack.c:157
-#, c-format
-msgid "unable to open %s"
-msgstr "不能打开 %s"
-
-#: builtin/index-pack.c:207
+#: builtin/index-pack.c:208
 #, c-format
 msgid "object type mismatch at %s"
 msgstr "%s 的对象类型不匹配"
 
-#: builtin/index-pack.c:227
+#: builtin/index-pack.c:228
 #, c-format
 msgid "did not receive expected object %s"
 msgstr "未能获取预期的对象 %s"
 
-#: builtin/index-pack.c:230
+#: builtin/index-pack.c:231
 #, c-format
 msgid "object %s: expected type %s, found %s"
 msgstr "对象 %s:应为类型 %s,却是 %s"
 
-#: builtin/index-pack.c:272
+#: builtin/index-pack.c:273
 #, c-format
 msgid "cannot fill %d byte"
 msgid_plural "cannot fill %d bytes"
 msgstr[0] "无法填充 %d 字节"
 msgstr[1] "无法填充 %d 字节"
 
-#: builtin/index-pack.c:282
+#: builtin/index-pack.c:283
 msgid "early EOF"
 msgstr "过早的文件结束符(EOF)"
 
-#: builtin/index-pack.c:283
+#: builtin/index-pack.c:284
 msgid "read error on input"
 msgstr "输入上的读错误"
 
-#: builtin/index-pack.c:295
+#: builtin/index-pack.c:296
 msgid "used more bytes than were available"
 msgstr "用掉了超过可用的字节"
 
-#: builtin/index-pack.c:302
+#: builtin/index-pack.c:303
 msgid "pack too large for current definition of off_t"
 msgstr "包太大超过了当前 off_t 的定义"
 
-#: builtin/index-pack.c:305 builtin/unpack-objects.c:93
+#: builtin/index-pack.c:306 builtin/unpack-objects.c:93
 msgid "pack exceeds maximum allowed size"
 msgstr "包超过了最大允许值"
 
-#: builtin/index-pack.c:320
+#: builtin/index-pack.c:321
 #, c-format
 msgid "unable to create '%s'"
 msgstr "不能创建 '%s'"
 
-#: builtin/index-pack.c:326
+#: builtin/index-pack.c:327
 #, c-format
 msgid "cannot open packfile '%s'"
 msgstr "无法打开包文件 '%s'"
 
-#: builtin/index-pack.c:340
+#: builtin/index-pack.c:341
 msgid "pack signature mismatch"
 msgstr "包签名不匹配"
 
-#: builtin/index-pack.c:342
+#: builtin/index-pack.c:343
 #, c-format
 msgid "pack version %<PRIu32> unsupported"
 msgstr "不支持包版本 %<PRIu32>"
 
-#: builtin/index-pack.c:360
+#: builtin/index-pack.c:361
 #, c-format
 msgid "pack has bad object at offset %<PRIuMAX>: %s"
 msgstr "包中有错误的对象位于偏移量 %<PRIuMAX>:%s"
 
-#: builtin/index-pack.c:481
+#: builtin/index-pack.c:482
 #, c-format
 msgid "inflate returned %d"
 msgstr "解压缩返回 %d"
 
-#: builtin/index-pack.c:530
+#: builtin/index-pack.c:531
 msgid "offset value overflow for delta base object"
 msgstr "偏移值覆盖了 delta 基准对象"
 
-#: builtin/index-pack.c:538
+#: builtin/index-pack.c:539
 msgid "delta base offset is out of bound"
 msgstr "delta 基准偏移越界"
 
-#: builtin/index-pack.c:546
+#: builtin/index-pack.c:547
 #, c-format
 msgid "unknown object type %d"
 msgstr "未知对象类型 %d"
 
-#: builtin/index-pack.c:577
+#: builtin/index-pack.c:578
 msgid "cannot pread pack file"
 msgstr "无法读取包文件"
 
-#: builtin/index-pack.c:579
+#: builtin/index-pack.c:580
 #, c-format
 msgid "premature end of pack file, %<PRIuMAX> byte missing"
 msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing"
 msgstr[0] "包文件过早结束,缺少 %<PRIuMAX> 字节"
 msgstr[1] "包文件过早结束,缺少 %<PRIuMAX> 字节"
 
-#: builtin/index-pack.c:605
+#: builtin/index-pack.c:606
 msgid "serious inflate inconsistency"
 msgstr "解压缩严重的不一致"
 
-#: builtin/index-pack.c:750 builtin/index-pack.c:756 builtin/index-pack.c:779
-#: builtin/index-pack.c:818 builtin/index-pack.c:827
+#: builtin/index-pack.c:751 builtin/index-pack.c:757 builtin/index-pack.c:780
+#: builtin/index-pack.c:819 builtin/index-pack.c:828
 #, c-format
 msgid "SHA1 COLLISION FOUND WITH %s !"
 msgstr "发现 %s 出现 SHA1 冲突!"
 
-#: builtin/index-pack.c:753 builtin/pack-objects.c:182
-#: builtin/pack-objects.c:276
+#: builtin/index-pack.c:754 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:292
 #, c-format
 msgid "unable to read %s"
 msgstr "不能读 %s"
 
-#: builtin/index-pack.c:816
+#: builtin/index-pack.c:817
 #, c-format
 msgid "cannot read existing object info %s"
 msgstr "不能读取现存对象信息 %s"
 
-#: builtin/index-pack.c:824
+#: builtin/index-pack.c:825
 #, c-format
 msgid "cannot read existing object %s"
 msgstr "不能读取现存对象 %s"
 
-#: builtin/index-pack.c:838
+#: builtin/index-pack.c:839
 #, c-format
 msgid "invalid blob object %s"
 msgstr "无效的数据对象 %s"
 
-#: builtin/index-pack.c:853
+#: builtin/index-pack.c:842 builtin/index-pack.c:860
+msgid "fsck error in packed object"
+msgstr "对打包对象 fsck 检查出错"
+
+#: builtin/index-pack.c:857
 #, c-format
 msgid "invalid %s"
 msgstr "无效的 %s"
 
-#: builtin/index-pack.c:856
-msgid "Error in object"
-msgstr "对象中出错"
-
-#: builtin/index-pack.c:858
+#: builtin/index-pack.c:862
 #, c-format
 msgid "Not all child objects of %s are reachable"
 msgstr "%s 的所有子对象并非都可达"
 
-#: builtin/index-pack.c:930 builtin/index-pack.c:961
+#: builtin/index-pack.c:934 builtin/index-pack.c:965
 msgid "failed to apply delta"
 msgstr "无法应用 delta"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Receiving objects"
 msgstr "接收对象中"
 
-#: builtin/index-pack.c:1131
+#: builtin/index-pack.c:1135
 msgid "Indexing objects"
 msgstr "索引对象中"
 
-#: builtin/index-pack.c:1165
+#: builtin/index-pack.c:1169
 msgid "pack is corrupted (SHA1 mismatch)"
 msgstr "包冲突(SHA1 不匹配)"
 
-#: builtin/index-pack.c:1170
+#: builtin/index-pack.c:1174
 msgid "cannot fstat packfile"
 msgstr "不能对包文件调用 fstat"
 
-#: builtin/index-pack.c:1173
+#: builtin/index-pack.c:1177
 msgid "pack has junk at the end"
 msgstr "包的结尾有垃圾数据"
 
-#: builtin/index-pack.c:1185
+#: builtin/index-pack.c:1189
 msgid "confusion beyond insanity in parse_pack_objects()"
 msgstr "parse_pack_objects() 中遇到不可理喻的问题"
 
-#: builtin/index-pack.c:1208
+#: builtin/index-pack.c:1212
 msgid "Resolving deltas"
 msgstr "处理 delta 中"
 
-#: builtin/index-pack.c:1219
+#: builtin/index-pack.c:1223
 #, c-format
 msgid "unable to create thread: %s"
 msgstr "不能创建线程:%s"
 
-#: builtin/index-pack.c:1261
+#: builtin/index-pack.c:1265
 msgid "confusion beyond insanity"
 msgstr "不可理喻"
 
-#: builtin/index-pack.c:1267
+#: builtin/index-pack.c:1271
 #, c-format
 msgid "completed with %d local object"
 msgid_plural "completed with %d local objects"
 msgstr[0] "完成 %d 个本地对象"
 msgstr[1] "完成 %d 个本地对象"
 
-#: builtin/index-pack.c:1279
+#: builtin/index-pack.c:1283
 #, c-format
 msgid "Unexpected tail checksum for %s (disk corruption?)"
 msgstr "对 %s 的尾部校验出现意外(磁盘损坏?)"
 
-#: builtin/index-pack.c:1283
+#: builtin/index-pack.c:1287
 #, c-format
 msgid "pack has %d unresolved delta"
 msgid_plural "pack has %d unresolved deltas"
 msgstr[0] "包有 %d 个未解决的 delta"
 msgstr[1] "包有 %d 个未解决的 delta"
 
-#: builtin/index-pack.c:1307
+#: builtin/index-pack.c:1311
 #, c-format
 msgid "unable to deflate appended object (%d)"
 msgstr "不能压缩附加对象(%d)"
 
-#: builtin/index-pack.c:1383
+#: builtin/index-pack.c:1388
 #, c-format
 msgid "local object %s is corrupt"
 msgstr "本地对象 %s 已损坏"
 
-#: builtin/index-pack.c:1397
+#: builtin/index-pack.c:1402
 #, c-format
 msgid "packfile name '%s' does not end with '.pack'"
 msgstr "包文件名 '%s' 没有以 '.pack' 结尾"
 
-#: builtin/index-pack.c:1422
+#: builtin/index-pack.c:1427
 #, c-format
 msgid "cannot write %s file '%s'"
 msgstr "无法写入 %s 文件 '%s'"
 
-#: builtin/index-pack.c:1430
+#: builtin/index-pack.c:1435
 #, c-format
 msgid "cannot close written %s file '%s'"
 msgstr "无法关闭已写入的 %s 文件 '%s'"
 
-#: builtin/index-pack.c:1454
+#: builtin/index-pack.c:1459
 msgid "error while closing pack file"
 msgstr "关闭包文件时出错"
 
-#: builtin/index-pack.c:1468
+#: builtin/index-pack.c:1473
 msgid "cannot store pack file"
 msgstr "无法存储包文件"
 
-#: builtin/index-pack.c:1476
+#: builtin/index-pack.c:1481
 msgid "cannot store index file"
 msgstr "无法存储索引文件"
 
-#: builtin/index-pack.c:1513
+#: builtin/index-pack.c:1525
 #, c-format
 msgid "bad pack.indexversion=%<PRIu32>"
 msgstr "坏的 pack.indexversion=%<PRIu32>"
 
-#: builtin/index-pack.c:1581
+#: builtin/index-pack.c:1594
 #, c-format
 msgid "Cannot open existing pack file '%s'"
 msgstr "无法打开现存包文件 '%s'"
 
-#: builtin/index-pack.c:1583
+#: builtin/index-pack.c:1596
 #, c-format
 msgid "Cannot open existing pack idx file for '%s'"
 msgstr "无法为 %s 打开包索引文件"
 
-#: builtin/index-pack.c:1631
+#: builtin/index-pack.c:1644
 #, c-format
 msgid "non delta: %d object"
 msgid_plural "non delta: %d objects"
 msgstr[0] "非 delta:%d 个对象"
 msgstr[1] "非 delta:%d 个对象"
 
-#: builtin/index-pack.c:1638
+#: builtin/index-pack.c:1651
 #, c-format
 msgid "chain length = %d: %lu object"
 msgid_plural "chain length = %d: %lu objects"
 msgstr[0] "链长 = %d: %lu 对象"
 msgstr[1] "链长 = %d: %lu 对象"
 
-#: builtin/index-pack.c:1675
+#: builtin/index-pack.c:1688
 msgid "Cannot come back to cwd"
 msgstr "无法返回当前工作目录"
 
-#: builtin/index-pack.c:1724 builtin/index-pack.c:1727
-#: builtin/index-pack.c:1743 builtin/index-pack.c:1747
+#: builtin/index-pack.c:1739 builtin/index-pack.c:1742
+#: builtin/index-pack.c:1758 builtin/index-pack.c:1762
 #, c-format
 msgid "bad %s"
 msgstr "错误选项 %s"
 
-#: builtin/index-pack.c:1763
+#: builtin/index-pack.c:1778
 msgid "--fix-thin cannot be used without --stdin"
 msgstr "--fix-thin 不能和 --stdin 同时使用"
 
-#: builtin/index-pack.c:1765
+#: builtin/index-pack.c:1780
 msgid "--stdin requires a git repository"
 msgstr "--stdin 需要一个 git 仓库"
 
-#: builtin/index-pack.c:1771
+#: builtin/index-pack.c:1786
 msgid "--verify with no packfile name given"
 msgstr "--verify 没有提供包文件名参数"
 
+#: builtin/index-pack.c:1836 builtin/unpack-objects.c:578
+msgid "fsck error in pack objects"
+msgstr "在打包对象中 fsck 检查出错"
+
 #: builtin/init-db.c:55
 #, c-format
 msgid "cannot stat '%s'"
@@ -9637,8 +10078,8 @@ msgstr "忽略模版 %s"
 
 #: builtin/init-db.c:120
 #, c-format
-msgid "templates not found %s"
-msgstr "模ç\89\88æ\9cªæ\89¾å\88° %s"
+msgid "templates not found in %s"
+msgstr "没æ\9c\89å\9c¨ %s ä¸­æ\89¾å\88°æ¨¡ç\89\88"
 
 #: builtin/init-db.c:135
 #, c-format
@@ -9696,11 +10137,6 @@ msgstr "权限"
 msgid "specify that the git repository is to be shared amongst several users"
 msgstr "指定 git 仓库是多个用户之间共享的"
 
-#: builtin/init-db.c:516 builtin/init-db.c:521
-#, c-format
-msgid "cannot mkdir %s"
-msgstr "不能创建目录 %s"
-
 #: builtin/init-db.c:525
 #, c-format
 msgid "cannot chdir to %s"
@@ -9882,7 +10318,7 @@ msgstr "两个输出目录?"
 msgid "Unknown commit %s"
 msgstr "未知提交 %s"
 
-#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:522
+#: builtin/log.c:1289 builtin/notes.c:887 builtin/tag.c:523
 #, c-format
 msgid "Failed to resolve '%s' as a valid ref."
 msgstr "无法解析 '%s' 为一个有效引用。"
@@ -10230,7 +10666,7 @@ msgstr "假装自从 <树或提交> 之后删除的路径仍然存在"
 msgid "show debugging data"
 msgstr "显示调试数据"
 
-#: builtin/ls-remote.c:7
+#: builtin/ls-remote.c:9
 msgid ""
 "git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n"
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
@@ -10240,39 +10676,39 @@ msgstr ""
 "                     [-q | --quiet] [--exit-code] [--get-url]\n"
 "                     [--symref] [<仓库> [<引用>...]]"
 
-#: builtin/ls-remote.c:52
+#: builtin/ls-remote.c:59
 msgid "do not print remote URL"
 msgstr "不打印远程 URL"
 
-#: builtin/ls-remote.c:53 builtin/ls-remote.c:55
+#: builtin/ls-remote.c:60 builtin/ls-remote.c:62
 msgid "exec"
 msgstr "exec"
 
-#: builtin/ls-remote.c:54 builtin/ls-remote.c:56
+#: builtin/ls-remote.c:61 builtin/ls-remote.c:63
 msgid "path of git-upload-pack on the remote host"
 msgstr "远程主机上的 git-upload-pack 路径"
 
-#: builtin/ls-remote.c:58
+#: builtin/ls-remote.c:65
 msgid "limit to tags"
 msgstr "仅限于标签"
 
-#: builtin/ls-remote.c:59
+#: builtin/ls-remote.c:66
 msgid "limit to heads"
 msgstr "仅限于分支"
 
-#: builtin/ls-remote.c:60
+#: builtin/ls-remote.c:67
 msgid "do not show peeled tags"
 msgstr "不显示已解析的标签"
 
-#: builtin/ls-remote.c:62
+#: builtin/ls-remote.c:69
 msgid "take url.<base>.insteadOf into account"
 msgstr "参考 url.<base>.insteadOf 设置"
 
-#: builtin/ls-remote.c:64
+#: builtin/ls-remote.c:73
 msgid "exit with exit code 2 if no matching refs are found"
 msgstr "若未找到匹配的引用则以退出码2退出"
 
-#: builtin/ls-remote.c:67
+#: builtin/ls-remote.c:76
 msgid "show underlying ref in addition to the object pointed by it"
 msgstr "除了显示指向的对象外,显示指向的引用名"
 
@@ -10317,166 +10753,166 @@ msgstr "列出整个树;不仅仅当前目录(隐含 --full-name)"
 msgid "empty mbox: '%s'"
 msgstr "空的 mbox:'%s'"
 
-#: builtin/merge.c:49
+#: builtin/merge.c:51
 msgid "git merge [<options>] [<commit>...]"
 msgstr "git merge [<选项>] [<提交>...]"
 
-#: builtin/merge.c:50
+#: builtin/merge.c:52
 msgid "git merge --abort"
 msgstr "git merge --abort"
 
-#: builtin/merge.c:51
+#: builtin/merge.c:53
 msgid "git merge --continue"
 msgstr "git merge --continue"
 
-#: builtin/merge.c:108
+#: builtin/merge.c:110
 msgid "switch `m' requires a value"
 msgstr "开关 `m' 需要一个值"
 
-#: builtin/merge.c:145
+#: builtin/merge.c:147
 #, c-format
 msgid "Could not find merge strategy '%s'.\n"
 msgstr "不能找到合并策略 '%s'。\n"
 
-#: builtin/merge.c:146
+#: builtin/merge.c:148
 #, c-format
 msgid "Available strategies are:"
 msgstr "可用的策略有:"
 
-#: builtin/merge.c:151
+#: builtin/merge.c:153
 #, c-format
 msgid "Available custom strategies are:"
 msgstr "可用的自定义策略有:"
 
-#: builtin/merge.c:201 builtin/pull.c:137
+#: builtin/merge.c:203 builtin/pull.c:142
 msgid "do not show a diffstat at the end of the merge"
 msgstr "在合并的最后不显示差异统计"
 
-#: builtin/merge.c:204 builtin/pull.c:140
+#: builtin/merge.c:206 builtin/pull.c:145
 msgid "show a diffstat at the end of the merge"
 msgstr "在合并的最后显示差异统计"
 
-#: builtin/merge.c:205 builtin/pull.c:143
+#: builtin/merge.c:207 builtin/pull.c:148
 msgid "(synonym to --stat)"
 msgstr "(和 --stat 同义)"
 
-#: builtin/merge.c:207 builtin/pull.c:146
+#: builtin/merge.c:209 builtin/pull.c:151
 msgid "add (at most <n>) entries from shortlog to merge commit message"
 msgstr "在合并提交信息中添加(最多 <n> 条)精简提交记录"
 
-#: builtin/merge.c:210 builtin/pull.c:152
+#: builtin/merge.c:212 builtin/pull.c:157
 msgid "create a single commit instead of doing a merge"
 msgstr "创建一个单独的提交而不是做一次合并"
 
-#: builtin/merge.c:212 builtin/pull.c:155
+#: builtin/merge.c:214 builtin/pull.c:160
 msgid "perform a commit if the merge succeeds (default)"
 msgstr "如果合并成功,执行一次提交(默认)"
 
-#: builtin/merge.c:214 builtin/pull.c:158
+#: builtin/merge.c:216 builtin/pull.c:163
 msgid "edit message before committing"
 msgstr "在提交前编辑提交说明"
 
-#: builtin/merge.c:215
+#: builtin/merge.c:217
 msgid "allow fast-forward (default)"
 msgstr "允许快进(默认)"
 
-#: builtin/merge.c:217 builtin/pull.c:164
+#: builtin/merge.c:219 builtin/pull.c:169
 msgid "abort if fast-forward is not possible"
 msgstr "如果不能快进就放弃合并"
 
-#: builtin/merge.c:221 builtin/pull.c:167
+#: builtin/merge.c:223 builtin/pull.c:172
 msgid "verify that the named commit has a valid GPG signature"
 msgstr "验证指定的提交是否包含一个有效的 GPG 签名"
 
-#: builtin/merge.c:222 builtin/notes.c:777 builtin/pull.c:171
+#: builtin/merge.c:224 builtin/notes.c:777 builtin/pull.c:176
 #: builtin/revert.c:109
 msgid "strategy"
 msgstr "策略"
 
-#: builtin/merge.c:223 builtin/pull.c:172
+#: builtin/merge.c:225 builtin/pull.c:177
 msgid "merge strategy to use"
 msgstr "要使用的合并策略"
 
-#: builtin/merge.c:224 builtin/pull.c:175
+#: builtin/merge.c:226 builtin/pull.c:180
 msgid "option=value"
 msgstr "option=value"
 
-#: builtin/merge.c:225 builtin/pull.c:176
+#: builtin/merge.c:227 builtin/pull.c:181
 msgid "option for selected merge strategy"
 msgstr "所选的合并策略的选项"
 
-#: builtin/merge.c:227
+#: builtin/merge.c:229
 msgid "merge commit message (for a non-fast-forward merge)"
 msgstr "合并的提交说明(针对非快进式合并)"
 
-#: builtin/merge.c:231
+#: builtin/merge.c:233
 msgid "abort the current in-progress merge"
 msgstr "放弃当前正在进行的合并"
 
-#: builtin/merge.c:233
+#: builtin/merge.c:235
 msgid "continue the current in-progress merge"
 msgstr "继续当前正在进行的合并"
 
-#: builtin/merge.c:235 builtin/pull.c:183
+#: builtin/merge.c:237 builtin/pull.c:188
 msgid "allow merging unrelated histories"
 msgstr "允许合并不相关的历史"
 
-#: builtin/merge.c:241
+#: builtin/merge.c:243
 msgid "verify commit-msg hook"
 msgstr "校验 commit-msg 钩子"
 
-#: builtin/merge.c:266
+#: builtin/merge.c:268
 msgid "could not run stash."
 msgstr "不能运行贮藏。"
 
-#: builtin/merge.c:271
+#: builtin/merge.c:273
 msgid "stash failed"
 msgstr "贮藏失败"
 
-#: builtin/merge.c:276
+#: builtin/merge.c:278
 #, c-format
 msgid "not a valid object: %s"
 msgstr "不是一个有效对象:%s"
 
-#: builtin/merge.c:298 builtin/merge.c:315
+#: builtin/merge.c:300 builtin/merge.c:317
 msgid "read-tree failed"
 msgstr "读取树失败"
 
 #  译者:注意保持前导空格
-#: builtin/merge.c:345
+#: builtin/merge.c:347
 msgid " (nothing to squash)"
 msgstr " (无可压缩)"
 
-#: builtin/merge.c:356
+#: builtin/merge.c:358
 #, c-format
 msgid "Squash commit -- not updating HEAD\n"
 msgstr "压缩提交 -- 未更新 HEAD\n"
 
-#: builtin/merge.c:406
+#: builtin/merge.c:408
 #, c-format
 msgid "No merge message -- not updating HEAD\n"
 msgstr "无合并信息 -- 未更新 HEAD\n"
 
-#: builtin/merge.c:456
+#: builtin/merge.c:458
 #, c-format
 msgid "'%s' does not point to a commit"
 msgstr "'%s' 没有指向一个提交"
 
-#: builtin/merge.c:546
+#: builtin/merge.c:548
 #, c-format
 msgid "Bad branch.%s.mergeoptions string: %s"
 msgstr "坏的 branch.%s.mergeoptions 字符串:%s"
 
-#: builtin/merge.c:668
+#: builtin/merge.c:669
 msgid "Not handling anything other than two heads merge."
 msgstr "未处理两个头合并之外的任何操作。"
 
-#: builtin/merge.c:682
+#: builtin/merge.c:683
 #, c-format
 msgid "Unknown option for merge-recursive: -X%s"
 msgstr "merge-recursive 的未知选项:-X%s"
 
-#: builtin/merge.c:697
+#: builtin/merge.c:698
 #, c-format
 msgid "unable to write %s"
 msgstr "不能写 %s"
@@ -10509,64 +10945,64 @@ msgstr ""
 msgid "Empty commit message."
 msgstr "空提交信息。"
 
-#: builtin/merge.c:820
+#: builtin/merge.c:819
 #, c-format
 msgid "Wonderful.\n"
 msgstr "太棒了。\n"
 
-#: builtin/merge.c:873
+#: builtin/merge.c:872
 #, c-format
 msgid "Automatic merge failed; fix conflicts and then commit the result.\n"
 msgstr "自动合并失败,修正冲突然后提交修正的结果。\n"
 
-#: builtin/merge.c:912
+#: builtin/merge.c:911
 msgid "No current branch."
 msgstr "没有当前分支。"
 
-#: builtin/merge.c:914
+#: builtin/merge.c:913
 msgid "No remote for the current branch."
 msgstr "当前分支没有对应的远程仓库。"
 
-#: builtin/merge.c:916
+#: builtin/merge.c:915
 msgid "No default upstream defined for the current branch."
 msgstr "当前分支没有定义默认的上游分支。"
 
-#: builtin/merge.c:921
+#: builtin/merge.c:920
 #, c-format
 msgid "No remote-tracking branch for %s from %s"
 msgstr "对于 %s 没有来自 %s 的远程跟踪分支"
 
-#: builtin/merge.c:974
+#: builtin/merge.c:973
 #, c-format
 msgid "Bad value '%s' in environment '%s'"
 msgstr "环境 '%2$s' 中存在坏的取值 '%1$s'"
 
-#: builtin/merge.c:1076
+#: builtin/merge.c:1075
 #, c-format
 msgid "not something we can merge in %s: %s"
 msgstr "不能在 %s 中合并:%s"
 
-#: builtin/merge.c:1110
+#: builtin/merge.c:1109
 msgid "not something we can merge"
 msgstr "不能合并"
 
-#: builtin/merge.c:1212
+#: builtin/merge.c:1211
 msgid "--abort expects no arguments"
 msgstr "--abort 不带参数"
 
-#: builtin/merge.c:1216
+#: builtin/merge.c:1215
 msgid "There is no merge to abort (MERGE_HEAD missing)."
 msgstr "没有要终止的合并(MERGE_HEAD 丢失)。"
 
-#: builtin/merge.c:1228
+#: builtin/merge.c:1227
 msgid "--continue expects no arguments"
 msgstr "--continue 不带参数"
 
-#: builtin/merge.c:1232
+#: builtin/merge.c:1231
 msgid "There is no merge in progress (MERGE_HEAD missing)."
 msgstr "没有进行中的合并(MERGE_HEAD 丢失)。"
 
-#: builtin/merge.c:1248
+#: builtin/merge.c:1247
 msgid ""
 "You have not concluded your merge (MERGE_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10574,7 +11010,7 @@ msgstr ""
 "您尚未结束您的合并(存在 MERGE_HEAD)。\n"
 "请在合并前先提交您的修改。"
 
-#: builtin/merge.c:1255
+#: builtin/merge.c:1254
 msgid ""
 "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n"
 "Please, commit your changes before you merge."
@@ -10582,112 +11018,112 @@ msgstr ""
 "您尚未结束您的拣选(存在 CHERRY_PICK_HEAD)。\n"
 "请在合并前先提交您的修改。"
 
-#: builtin/merge.c:1258
+#: builtin/merge.c:1257
 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)."
 msgstr "您尚未结束您的拣选(存在 CHERRY_PICK_HEAD)。"
 
-#: builtin/merge.c:1267
+#: builtin/merge.c:1266
 msgid "You cannot combine --squash with --no-ff."
 msgstr "您不能将 --squash 与 --no-ff 同时使用。"
 
-#: builtin/merge.c:1275
+#: builtin/merge.c:1274
 msgid "No commit specified and merge.defaultToUpstream not set."
 msgstr "未指定提交并且 merge.defaultToUpstream 未设置。"
 
-#: builtin/merge.c:1292
+#: builtin/merge.c:1291
 msgid "Squash commit into empty head not supported yet"
 msgstr "尚不支持到空分支的压缩提交"
 
-#: builtin/merge.c:1294
+#: builtin/merge.c:1293
 msgid "Non-fast-forward commit does not make sense into an empty head"
 msgstr "到空分支的非快进式提交没有意义"
 
-#: builtin/merge.c:1299
+#: builtin/merge.c:1298
 #, c-format
 msgid "%s - not something we can merge"
 msgstr "%s - 不能被合并"
 
-#: builtin/merge.c:1301
+#: builtin/merge.c:1300
 msgid "Can merge only exactly one commit into empty head"
 msgstr "只能将一个提交合并到空分支上"
 
-#: builtin/merge.c:1335
+#: builtin/merge.c:1334
 #, c-format
 msgid "Commit %s has an untrusted GPG signature, allegedly by %s."
 msgstr "提交 %s 有一个非可信的声称来自 %s 的 GPG 签名。"
 
-#: builtin/merge.c:1338
+#: builtin/merge.c:1337
 #, c-format
 msgid "Commit %s has a bad GPG signature allegedly by %s."
 msgstr "提交 %s 有一个错误的声称来自 %s 的 GPG 签名。"
 
-#: builtin/merge.c:1341
+#: builtin/merge.c:1340
 #, c-format
 msgid "Commit %s does not have a GPG signature."
 msgstr "提交 %s 没有一个 GPG 签名。"
 
-#: builtin/merge.c:1344
+#: builtin/merge.c:1343
 #, c-format
 msgid "Commit %s has a good GPG signature by %s\n"
 msgstr "提交 %s 有一个来自 %s 的好的 GPG 签名。\n"
 
-#: builtin/merge.c:1403
+#: builtin/merge.c:1402
 msgid "refusing to merge unrelated histories"
 msgstr "拒绝合并无关的历史"
 
-#: builtin/merge.c:1412
+#: builtin/merge.c:1411
 msgid "Already up to date."
 msgstr "已经是最新的。"
 
-#: builtin/merge.c:1422
+#: builtin/merge.c:1421
 #, c-format
 msgid "Updating %s..%s\n"
 msgstr "更新 %s..%s\n"
 
-#: builtin/merge.c:1463
+#: builtin/merge.c:1462
 #, c-format
 msgid "Trying really trivial in-index merge...\n"
 msgstr "尝试非常小的索引内合并...\n"
 
-#: builtin/merge.c:1470
+#: builtin/merge.c:1469
 #, c-format
 msgid "Nope.\n"
 msgstr "无。\n"
 
-#: builtin/merge.c:1495
+#: builtin/merge.c:1494
 msgid "Already up to date. Yeeah!"
 msgstr "已经是最新的。耶!"
 
-#: builtin/merge.c:1501
+#: builtin/merge.c:1500
 msgid "Not possible to fast-forward, aborting."
 msgstr "无法快进,终止。"
 
-#: builtin/merge.c:1524 builtin/merge.c:1603
+#: builtin/merge.c:1523 builtin/merge.c:1602
 #, c-format
 msgid "Rewinding the tree to pristine...\n"
 msgstr "将树回滚至原始状态...\n"
 
-#: builtin/merge.c:1528
+#: builtin/merge.c:1527
 #, c-format
 msgid "Trying merge strategy %s...\n"
 msgstr "尝试合并策略 %s...\n"
 
-#: builtin/merge.c:1594
+#: builtin/merge.c:1593
 #, c-format
 msgid "No merge strategy handled the merge.\n"
 msgstr "没有合并策略处理此合并。\n"
 
-#: builtin/merge.c:1596
+#: builtin/merge.c:1595
 #, c-format
 msgid "Merge with strategy %s failed.\n"
 msgstr "使用策略 %s 合并失败。\n"
 
-#: builtin/merge.c:1605
+#: builtin/merge.c:1604
 #, c-format
 msgid "Using the %s to prepare resolving by hand.\n"
 msgstr "使用 %s 以准备手工解决。\n"
 
-#: builtin/merge.c:1617
+#: builtin/merge.c:1616
 #, c-format
 msgid "Automatic merge went well; stopped before committing as requested\n"
 msgstr "自动合并进展顺利,按要求在提交前停止\n"
@@ -10823,25 +11259,25 @@ msgstr "允许创建一个以上的树"
 msgid "git mv [<options>] <source>... <destination>"
 msgstr "git mv [<选项>] <源>... <目标>"
 
-#: builtin/mv.c:83
+#: builtin/mv.c:82
 #, c-format
 msgid "Directory %s is in index and no submodule?"
 msgstr "目录 %s 在索引中并且不是子模组?"
 
-#: builtin/mv.c:85 builtin/rm.c:289
+#: builtin/mv.c:84 builtin/rm.c:288
 msgid "Please stage your changes to .gitmodules or stash them to proceed"
 msgstr "请将您的修改暂存到 .gitmodules 中或贮藏后再继续"
 
-#: builtin/mv.c:103
+#: builtin/mv.c:102
 #, c-format
 msgid "%.*s is in index"
 msgstr "%.*s 在索引中"
 
-#: builtin/mv.c:125
+#: builtin/mv.c:124
 msgid "force move/rename even if target exists"
 msgstr "强制移动/重命令,即使目标存在"
 
-#: builtin/mv.c:127
+#: builtin/mv.c:126
 msgid "skip move/rename errors"
 msgstr "跳过移动/重命名错误"
 
@@ -10906,7 +11342,7 @@ msgstr "%s,源=%s,目标=%s"
 msgid "Renaming %s to %s\n"
 msgstr "重命名 %s 至 %s\n"
 
-#: builtin/mv.c:276 builtin/remote.c:712 builtin/repack.c:394
+#: builtin/mv.c:276 builtin/remote.c:715 builtin/repack.c:409
 #, c-format
 msgid "renaming '%s' failed"
 msgstr "重命名 '%s' 失败"
@@ -11095,12 +11531,12 @@ msgstr "不能写注解对象"
 msgid "the note contents have been left in %s"
 msgstr "注解内容被留在 %s 中"
 
-#: builtin/notes.c:234 builtin/tag.c:506
+#: builtin/notes.c:234 builtin/tag.c:507
 #, c-format
 msgid "cannot read '%s'"
 msgstr "不能读取 '%s'"
 
-#: builtin/notes.c:236 builtin/tag.c:509
+#: builtin/notes.c:236 builtin/tag.c:510
 #, c-format
 msgid "could not open or read '%s'"
 msgstr "不能打开或读取 '%s'"
@@ -11125,7 +11561,7 @@ msgstr "不能从非数据对象 '%s' 中读取注解数据。"
 #: builtin/notes.c:302
 #, c-format
 msgid "malformed input line: '%s'."
-msgstr "非法的输入行:'%s'。"
+msgstr "格式错误的输入行:'%s'。"
 
 #: builtin/notes.c:317
 #, c-format
@@ -11338,7 +11774,7 @@ msgstr "尝试删除不存在的注解不是一个错误"
 msgid "read object names from the standard input"
 msgstr "从标准输入读取对象名称"
 
-#: builtin/notes.c:943 builtin/prune.c:106 builtin/worktree.c:160
+#: builtin/notes.c:943 builtin/prune.c:107 builtin/worktree.c:151
 msgid "do not remove, show only"
 msgstr "不删除,只显示"
 
@@ -11359,208 +11795,236 @@ msgstr "从 <注解引用> 使用注解"
 msgid "unknown subcommand: %s"
 msgstr "未知子命令:%s"
 
-#: builtin/pack-objects.c:33
+#: builtin/pack-objects.c:48
 msgid ""
 "git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]"
 msgstr "git pack-objects --stdout [<选项>...] [< <引用列表> | < <对象列表>]"
 
-#: builtin/pack-objects.c:34
+#: builtin/pack-objects.c:49
 msgid ""
 "git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]"
 msgstr "git pack-objects [<选项>...] <前缀名称> [< <引用列表> | < <对象列表>]"
 
-#: builtin/pack-objects.c:195 builtin/pack-objects.c:198
+#: builtin/pack-objects.c:211 builtin/pack-objects.c:214
 #, c-format
 msgid "deflate error (%d)"
 msgstr "压缩错误 (%d)"
 
-#: builtin/pack-objects.c:791
+#: builtin/pack-objects.c:810
 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit"
 msgstr "禁用 bitmap 写入,因为 pack.packSizeLimit 设置使得包被切分为多个"
 
-#: builtin/pack-objects.c:804
+#: builtin/pack-objects.c:823
 msgid "Writing objects"
 msgstr "写入对象中"
 
-#: builtin/pack-objects.c:1084
+#: builtin/pack-objects.c:1106
 msgid "disabling bitmap writing, as some objects are not being packed"
 msgstr "禁用 bitmap 写入,因为一些对象将不会被打包"
 
-#: builtin/pack-objects.c:2454
+#: builtin/pack-objects.c:1765
+msgid "Counting objects"
+msgstr "对象计数中"
+
+#: builtin/pack-objects.c:1895
+#, c-format
+msgid "unable to get size of %s"
+msgstr "不能得到 %s 的大小"
+
+#: builtin/pack-objects.c:1910
+#, c-format
+msgid "unable to parse object header of %s"
+msgstr "无法解析对象 %s 头信息"
+
+#: builtin/pack-objects.c:2564
 msgid "Compressing objects"
 msgstr "压缩对象中"
 
-#: builtin/pack-objects.c:2625
+#: builtin/pack-objects.c:2735
 msgid "invalid value for --missing"
 msgstr "选项 --missing 的值无效"
 
-#: builtin/pack-objects.c:2928
+#: builtin/pack-objects.c:3067
 #, c-format
 msgid "unsupported index version %s"
 msgstr "不支持的索引版本 %s"
 
-#: builtin/pack-objects.c:2932
+#: builtin/pack-objects.c:3071
 #, c-format
 msgid "bad index version '%s'"
 msgstr "坏的索引版本 '%s'"
 
-#: builtin/pack-objects.c:2962
+#: builtin/pack-objects.c:3102
 msgid "do not show progress meter"
 msgstr "不显示进度表"
 
-#: builtin/pack-objects.c:2964
+#: builtin/pack-objects.c:3104
 msgid "show progress meter"
 msgstr "显示进度表"
 
-#: builtin/pack-objects.c:2966
+#: builtin/pack-objects.c:3106
 msgid "show progress meter during object writing phase"
 msgstr "在对象写入阶段显示进度表"
 
-#: builtin/pack-objects.c:2969
+#: builtin/pack-objects.c:3109
 msgid "similar to --all-progress when progress meter is shown"
 msgstr "当进度表显示时类似于 --all-progress"
 
-#: builtin/pack-objects.c:2970
+#: builtin/pack-objects.c:3110
 msgid "version[,offset]"
 msgstr "版本[,偏移]"
 
-#: builtin/pack-objects.c:2971
+#: builtin/pack-objects.c:3111
 msgid "write the pack index file in the specified idx format version"
 msgstr "用指定的 idx 格式版本来写包索引文件"
 
-#: builtin/pack-objects.c:2974
+#: builtin/pack-objects.c:3114
 msgid "maximum size of each output pack file"
 msgstr "每个输出包的最大尺寸"
 
-#: builtin/pack-objects.c:2976
+#: builtin/pack-objects.c:3116
 msgid "ignore borrowed objects from alternate object store"
 msgstr "忽略从备用对象存储里借用对象"
 
-#: builtin/pack-objects.c:2978
+#: builtin/pack-objects.c:3118
 msgid "ignore packed objects"
 msgstr "忽略包对象"
 
-#: builtin/pack-objects.c:2980
+#: builtin/pack-objects.c:3120
 msgid "limit pack window by objects"
 msgstr "限制打包窗口的对象数"
 
-#: builtin/pack-objects.c:2982
+#: builtin/pack-objects.c:3122
 msgid "limit pack window by memory in addition to object limit"
 msgstr "除对象数量限制外设置打包窗口的内存限制"
 
-#: builtin/pack-objects.c:2984
+#: builtin/pack-objects.c:3124
 msgid "maximum length of delta chain allowed in the resulting pack"
 msgstr "打包允许的 delta 链的最大长度"
 
-#: builtin/pack-objects.c:2986
+#: builtin/pack-objects.c:3126
 msgid "reuse existing deltas"
 msgstr "重用已存在的 deltas"
 
-#: builtin/pack-objects.c:2988
+#: builtin/pack-objects.c:3128
 msgid "reuse existing objects"
 msgstr "重用已存在的对象"
 
-#: builtin/pack-objects.c:2990
+#: builtin/pack-objects.c:3130
 msgid "use OFS_DELTA objects"
 msgstr "使用 OFS_DELTA 对象"
 
-#: builtin/pack-objects.c:2992
+#: builtin/pack-objects.c:3132
 msgid "use threads when searching for best delta matches"
 msgstr "使用线程查询最佳 delta 匹配"
 
-#: builtin/pack-objects.c:2994
+#: builtin/pack-objects.c:3134
 msgid "do not create an empty pack output"
 msgstr "不创建空的包输出"
 
-#: builtin/pack-objects.c:2996
+#: builtin/pack-objects.c:3136
 msgid "read revision arguments from standard input"
 msgstr "从标准输入读取版本号参数"
 
-#: builtin/pack-objects.c:2998
+#: builtin/pack-objects.c:3138
 msgid "limit the objects to those that are not yet packed"
 msgstr "限制那些尚未打包的对象"
 
-#: builtin/pack-objects.c:3001
+#: builtin/pack-objects.c:3141
 msgid "include objects reachable from any reference"
 msgstr "包括可以从任何引用访问到的对象"
 
-#: builtin/pack-objects.c:3004
+#: builtin/pack-objects.c:3144
 msgid "include objects referred by reflog entries"
 msgstr "包括被引用日志引用到的对象"
 
-#: builtin/pack-objects.c:3007
+#: builtin/pack-objects.c:3147
 msgid "include objects referred to by the index"
 msgstr "包括被索引引用到的对象"
 
-#: builtin/pack-objects.c:3010
+#: builtin/pack-objects.c:3150
 msgid "output pack to stdout"
 msgstr "输出包到标准输出"
 
-#: builtin/pack-objects.c:3012
+#: builtin/pack-objects.c:3152
 msgid "include tag objects that refer to objects to be packed"
 msgstr "包括那些引用了待打包对象的标签对象"
 
-#: builtin/pack-objects.c:3014
+#: builtin/pack-objects.c:3154
 msgid "keep unreachable objects"
 msgstr "维持不可达的对象"
 
-#: builtin/pack-objects.c:3016
+#: builtin/pack-objects.c:3156
 msgid "pack loose unreachable objects"
 msgstr "打包松散的不可达对象"
 
-#: builtin/pack-objects.c:3018
+#: builtin/pack-objects.c:3158
 msgid "unpack unreachable objects newer than <time>"
 msgstr "将比给定 <时间> 新的无法访问的对象解包"
 
-#: builtin/pack-objects.c:3021
+#: builtin/pack-objects.c:3161
 msgid "create thin packs"
 msgstr "创建精简包"
 
-#: builtin/pack-objects.c:3023
+#: builtin/pack-objects.c:3163
 msgid "create packs suitable for shallow fetches"
 msgstr "创建适合浅克隆仓库获取的包"
 
-#: builtin/pack-objects.c:3025
+#: builtin/pack-objects.c:3165
 msgid "ignore packs that have companion .keep file"
 msgstr "忽略配有 .keep 文件的包"
 
-#: builtin/pack-objects.c:3027
+#: builtin/pack-objects.c:3167
+msgid "ignore this pack"
+msgstr "忽略该 pack"
+
+#: builtin/pack-objects.c:3169
 msgid "pack compression level"
 msgstr "打包压缩级别"
 
-#: builtin/pack-objects.c:3029
+#: builtin/pack-objects.c:3171
 msgid "do not hide commits by grafts"
-msgstr "显示被嫁接隐藏的提交"
+msgstr "显示被移植隐藏的提交"
 
-#: builtin/pack-objects.c:3031
+#: builtin/pack-objects.c:3173
 msgid "use a bitmap index if available to speed up counting objects"
 msgstr "使用 bitmap 索引(如果有的话)以提高对象计数时的速度"
 
-#: builtin/pack-objects.c:3033
+#: builtin/pack-objects.c:3175
 msgid "write a bitmap index together with the pack index"
 msgstr "在建立包索引的同时创建 bitmap 索引"
 
-#: builtin/pack-objects.c:3036
+#: builtin/pack-objects.c:3178
 msgid "handling for missing objects"
 msgstr "处理丢失的对象"
 
-#: builtin/pack-objects.c:3039
+#: builtin/pack-objects.c:3181
 msgid "do not pack objects in promisor packfiles"
 msgstr "不要打包 promisor 包文件中的对象"
 
-#: builtin/pack-objects.c:3178
-msgid "Counting objects"
-msgstr "对象计数中"
+#: builtin/pack-objects.c:3205
+#, c-format
+msgid "delta chain depth %d is too deep, forcing %d"
+msgstr "增量链深度 %d 太深了,强制为 %d"
+
+#: builtin/pack-objects.c:3210
+#, c-format
+msgid "pack.deltaCacheLimit is too high, forcing %d"
+msgstr "配置 pack.deltaCacheLimit 太高了,强制为 %d"
 
-#: builtin/pack-refs.c:6
+#: builtin/pack-objects.c:3338
+msgid "Enumerating objects"
+msgstr "枚举对象"
+
+#: builtin/pack-refs.c:7
 msgid "git pack-refs [<options>]"
 msgstr "git pack-refs [<选项>]"
 
-#: builtin/pack-refs.c:14
+#: builtin/pack-refs.c:15
 msgid "pack everything"
 msgstr "打包一切"
 
-#: builtin/pack-refs.c:15
+#: builtin/pack-refs.c:16
 msgid "prune loose refs (default)"
 msgstr "清除松散的引用(默认)"
 
@@ -11576,82 +12040,82 @@ msgstr "正在删除重复对象"
 msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]"
 msgstr "git prune [-n] [-v] [--progress] [--expire <时间>] [--] [<head>...]"
 
-#: builtin/prune.c:107
+#: builtin/prune.c:108
 msgid "report pruned objects"
 msgstr "报告清除的对象"
 
-#: builtin/prune.c:110
+#: builtin/prune.c:111
 msgid "expire objects older than <time>"
 msgstr "使早于给定时间的对象过期"
 
-#: builtin/prune.c:112
+#: builtin/prune.c:113
 msgid "limit traversal to objects outside promisor packfiles"
 msgstr "限制遍历 promisor 包以外的对象"
 
-#: builtin/prune.c:126
+#: builtin/prune.c:127
 msgid "cannot prune in a precious-objects repo"
 msgstr "不能在珍品仓库中执行清理操作"
 
-#: builtin/pull.c:54 builtin/pull.c:56
+#: builtin/pull.c:59 builtin/pull.c:61
 #, c-format
 msgid "Invalid value for %s: %s"
 msgstr "%s 的值无效:%s"
 
-#: builtin/pull.c:76
+#: builtin/pull.c:81
 msgid "git pull [<options>] [<repository> [<refspec>...]]"
 msgstr "git pull [<选项>] [<仓库> [<引用规格>...]]"
 
-#: builtin/pull.c:127
+#: builtin/pull.c:132
 msgid "control for recursive fetching of submodules"
 msgstr "控制子模组的递归获取"
 
-#: builtin/pull.c:131
+#: builtin/pull.c:136
 msgid "Options related to merging"
 msgstr "和合并相关的选项"
 
-#: builtin/pull.c:134
+#: builtin/pull.c:139
 msgid "incorporate changes by rebasing rather than merging"
 msgstr "使用变基操作取代合并操作以合入修改"
 
-#: builtin/pull.c:161 builtin/rebase--helper.c:23 builtin/revert.c:121
+#: builtin/pull.c:166 builtin/rebase--helper.c:23 builtin/revert.c:121
 msgid "allow fast-forward"
 msgstr "允许快进式"
 
-#: builtin/pull.c:170
+#: builtin/pull.c:175
 msgid "automatically stash/stash pop before and after rebase"
 msgstr "变基操作前后执行自动贮藏和弹出贮藏"
 
-#: builtin/pull.c:186
+#: builtin/pull.c:191
 msgid "Options related to fetching"
 msgstr "和获取相关的参数"
 
-#: builtin/pull.c:204
+#: builtin/pull.c:209
 msgid "number of submodules pulled in parallel"
 msgstr "并发拉取的子模组的数量"
 
-#: builtin/pull.c:299
+#: builtin/pull.c:304
 #, c-format
 msgid "Invalid value for pull.ff: %s"
 msgstr "pull.ff 的取值无效:%s"
 
-#: builtin/pull.c:415
+#: builtin/pull.c:420
 msgid ""
 "There is no candidate for rebasing against among the refs that you just "
 "fetched."
 msgstr "在您刚刚获取到的引用中没有变基操作的候选。"
 
-#: builtin/pull.c:417
+#: builtin/pull.c:422
 msgid ""
 "There are no candidates for merging among the refs that you just fetched."
 msgstr "在您刚刚获取到的引用中没有合并操作的候选。"
 
-#: builtin/pull.c:418
+#: builtin/pull.c:423
 msgid ""
 "Generally this means that you provided a wildcard refspec which had no\n"
 "matches on the remote end."
 msgstr "通常这意味着您提供了一个通配符引用规格但未能和远端匹配。"
 
-#: builtin/pull.c:421
+#: builtin/pull.c:426
 #, c-format
 msgid ""
 "You asked to pull from the remote '%s', but did not specify\n"
@@ -11661,42 +12125,42 @@ msgstr ""
 "您要求从远程 '%s' 拉取,但是未指定一个分支。因为这不是当前\n"
 "分支默认的远程仓库,您必须在命令行中指定一个分支名。"
 
-#: builtin/pull.c:426 git-parse-remote.sh:73
+#: builtin/pull.c:431 git-parse-remote.sh:73
 msgid "You are not currently on a branch."
 msgstr "您当前不在一个分支上。"
 
-#: builtin/pull.c:428 builtin/pull.c:443 git-parse-remote.sh:79
+#: builtin/pull.c:433 builtin/pull.c:448 git-parse-remote.sh:79
 msgid "Please specify which branch you want to rebase against."
 msgstr "请指定您要变基到哪一个分支。"
 
-#: builtin/pull.c:430 builtin/pull.c:445 git-parse-remote.sh:82
+#: builtin/pull.c:435 builtin/pull.c:450 git-parse-remote.sh:82
 msgid "Please specify which branch you want to merge with."
 msgstr "请指定您要合并哪一个分支。"
 
-#: builtin/pull.c:431 builtin/pull.c:446
+#: builtin/pull.c:436 builtin/pull.c:451
 msgid "See git-pull(1) for details."
 msgstr "详见 git-pull(1)。"
 
-#: builtin/pull.c:433 builtin/pull.c:439 builtin/pull.c:448
+#: builtin/pull.c:438 builtin/pull.c:444 builtin/pull.c:453
 #: git-parse-remote.sh:64
 msgid "<remote>"
 msgstr "<远程>"
 
-#: builtin/pull.c:433 builtin/pull.c:448 builtin/pull.c:453 git-rebase.sh:477
+#: builtin/pull.c:438 builtin/pull.c:453 builtin/pull.c:458 git-rebase.sh:523
 #: git-parse-remote.sh:65
 msgid "<branch>"
 msgstr "<分支>"
 
-#: builtin/pull.c:441 git-parse-remote.sh:75
+#: builtin/pull.c:446 git-parse-remote.sh:75
 msgid "There is no tracking information for the current branch."
 msgstr "当前分支没有跟踪信息。"
 
-#: builtin/pull.c:450 git-parse-remote.sh:95
+#: builtin/pull.c:455 git-parse-remote.sh:95
 msgid ""
 "If you wish to set tracking information for this branch you can do so with:"
 msgstr "如果您想要为此分支创建跟踪信息,您可以执行:"
 
-#: builtin/pull.c:455
+#: builtin/pull.c:460
 #, c-format
 msgid ""
 "Your configuration specifies to merge with the ref '%s'\n"
@@ -11705,27 +12169,27 @@ msgstr ""
 "您的配置中指定要合并远程的引用 '%s',\n"
 "但是没有获取到这个引用。"
 
-#: builtin/pull.c:819
+#: builtin/pull.c:826
 msgid "ignoring --verify-signatures for rebase"
 msgstr "为变基操作忽略 --verify-signatures"
 
-#: builtin/pull.c:867
+#: builtin/pull.c:874
 msgid "--[no-]autostash option is only valid with --rebase."
 msgstr "--[no-]autostash 选项只在使用 --rebase 时有效。"
 
-#: builtin/pull.c:875
+#: builtin/pull.c:882
 msgid "Updating an unborn branch with changes added to the index."
 msgstr "更新尚未诞生的分支,变更添加至索引。"
 
-#: builtin/pull.c:878
+#: builtin/pull.c:885
 msgid "pull with rebase"
 msgstr "变基式拉取"
 
-#: builtin/pull.c:879
+#: builtin/pull.c:886
 msgid "please commit or stash them."
 msgstr "请提交或贮藏它们。"
 
-#: builtin/pull.c:904
+#: builtin/pull.c:911
 #, c-format
 msgid ""
 "fetch updated the current branch head.\n"
@@ -11735,7 +12199,7 @@ msgstr ""
 "fetch 更新了当前的分支。快进您的工作区\n"
 "至提交 %s。"
 
-#: builtin/pull.c:909
+#: builtin/pull.c:916
 #, c-format
 msgid ""
 "Cannot fast-forward your working tree.\n"
@@ -11752,31 +12216,31 @@ msgstr ""
 "$ git reset --hard\n"
 "恢复之前的状态。"
 
-#: builtin/pull.c:924
+#: builtin/pull.c:931
 msgid "Cannot merge multiple branches into empty head."
 msgstr "无法将多个分支合并到空分支。"
 
-#: builtin/pull.c:928
+#: builtin/pull.c:935
 msgid "Cannot rebase onto multiple branches."
 msgstr "无法变基到多个分支。"
 
-#: builtin/pull.c:935
+#: builtin/pull.c:942
 msgid "cannot rebase with locally recorded submodule modifications"
 msgstr "本地子模组中有修改,无法变基"
 
-#: builtin/push.c:17
+#: builtin/push.c:19
 msgid "git push [<options>] [<repository> [<refspec>...]]"
 msgstr "git push [<选项>] [<仓库> [<引用规格>...]]"
 
-#: builtin/push.c:92
+#: builtin/push.c:111
 msgid "tag shorthand without <tag>"
 msgstr "标签后面未提供 <标签> 参数"
 
-#: builtin/push.c:102
+#: builtin/push.c:121
 msgid "--delete only accepts plain target ref names"
 msgstr "--delete 只接受简单的目标引用名"
 
-#: builtin/push.c:146
+#: builtin/push.c:165
 msgid ""
 "\n"
 "To choose either option permanently, see push.default in 'git help config'."
@@ -11784,7 +12248,7 @@ msgstr ""
 "\n"
 "为了永久地选择任一选项,参见 'git help config' 中的 push.default。"
 
-#: builtin/push.c:149
+#: builtin/push.c:168
 #, c-format
 msgid ""
 "The upstream branch of your current branch does not match\n"
@@ -11808,7 +12272,7 @@ msgstr ""
 "    git push %s %s\n"
 "%s"
 
-#: builtin/push.c:164
+#: builtin/push.c:183
 #, c-format
 msgid ""
 "You are not currently on a branch.\n"
@@ -11822,7 +12286,7 @@ msgstr ""
 "\n"
 "    git push %s HEAD:<远程分支名字>\n"
 
-#: builtin/push.c:178
+#: builtin/push.c:197
 #, c-format
 msgid ""
 "The current branch %s has no upstream branch.\n"
@@ -11835,12 +12299,12 @@ msgstr ""
 "\n"
 "    git push --set-upstream %s %s\n"
 
-#: builtin/push.c:186
+#: builtin/push.c:205
 #, c-format
 msgid "The current branch %s has multiple upstream branches, refusing to push."
 msgstr "当前分支 %s 有多个上游分支,拒绝推送。"
 
-#: builtin/push.c:189
+#: builtin/push.c:208
 #, c-format
 msgid ""
 "You are pushing to remote '%s', which is not the upstream of\n"
@@ -11850,12 +12314,12 @@ msgstr ""
 "您正推送至远程 '%s'(其并非当前分支 '%s' 的上游),\n"
 "而没有告诉我要推送什么、更新哪个远程分支。"
 
-#: builtin/push.c:248
+#: builtin/push.c:267
 msgid ""
 "You didn't specify any refspecs to push, and push.default is \"nothing\"."
 msgstr "您没有为推送指定任何引用规格,并且 push.default 为 \"nothing\"。"
 
-#: builtin/push.c:255
+#: builtin/push.c:274
 msgid ""
 "Updates were rejected because the tip of your current branch is behind\n"
 "its remote counterpart. Integrate the remote changes (e.g.\n"
@@ -11866,7 +12330,7 @@ msgstr ""
 "再次推送前,先与远程变更合并(如 'git pull ...')。详见\n"
 "'git push --help' 中的 'Note about fast-forwards' 小节。"
 
-#: builtin/push.c:261
+#: builtin/push.c:280
 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"
@@ -11877,7 +12341,7 @@ msgstr ""
 "检出该分支并整合远程变更(如 'git pull ...'),然后再推送。详见\n"
 "'git push --help' 中的 'Note about fast-forwards' 小节。"
 
-#: builtin/push.c:267
+#: builtin/push.c:286
 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"
@@ -11890,11 +12354,11 @@ msgstr ""
 "(如 'git pull ...')。\n"
 "详见 'git push --help' 中的 'Note about fast-forwards' 小节。"
 
-#: builtin/push.c:274
+#: builtin/push.c:293
 msgid "Updates were rejected because the tag already exists in the remote."
 msgstr "更新被拒绝,因为该标签在远程已经存在。"
 
-#: builtin/push.c:277
+#: builtin/push.c:296
 msgid ""
 "You cannot update a remote ref that points at a non-commit object,\n"
 "or update a remote ref to make it point at a non-commit object,\n"
@@ -11903,22 +12367,22 @@ msgstr ""
 "如果不使用 '--force' 参数,您不能更新一个指向非提交对象的远程引用,\n"
 "也不能更新远程引用让其指向一个非提交对象。\n"
 
-#: builtin/push.c:337
+#: builtin/push.c:357
 #, c-format
 msgid "Pushing to %s\n"
 msgstr "推送到 %s\n"
 
-#: builtin/push.c:341
+#: builtin/push.c:361
 #, c-format
 msgid "failed to push some refs to '%s'"
 msgstr "无法推送一些引用到 '%s'"
 
-#: builtin/push.c:372
+#: builtin/push.c:395
 #, c-format
 msgid "bad repository '%s'"
 msgstr "坏的仓库 '%s'"
 
-#: builtin/push.c:373
+#: builtin/push.c:396
 msgid ""
 "No configured push destination.\n"
 "Either specify the URL from the command-line or configure a remote "
@@ -11939,112 +12403,104 @@ msgstr ""
 "\n"
 "    git push <名称>\n"
 
-#: builtin/push.c:391
-msgid "--all and --tags are incompatible"
-msgstr "--all 和 --tags 不兼容"
-
-#: builtin/push.c:392
-msgid "--all can't be combined with refspecs"
-msgstr "--all 不能和引用规格同时使用"
-
-#: builtin/push.c:397
-msgid "--mirror and --tags are incompatible"
-msgstr "--mirror 和 --tags 不兼容"
-
-#: builtin/push.c:398
-msgid "--mirror can't be combined with refspecs"
-msgstr "--mirror 不能和引用规格同时使用"
-
-#: builtin/push.c:403
-msgid "--all and --mirror are incompatible"
-msgstr "--all 和 --mirror 不兼容"
-
-#: builtin/push.c:535
+#: builtin/push.c:551
 msgid "repository"
 msgstr "仓库"
 
-#: builtin/push.c:536 builtin/send-pack.c:163
+#: builtin/push.c:552 builtin/send-pack.c:164
 msgid "push all refs"
 msgstr "推送所有引用"
 
-#: builtin/push.c:537 builtin/send-pack.c:165
+#: builtin/push.c:553 builtin/send-pack.c:166
 msgid "mirror all refs"
 msgstr "镜像所有引用"
 
-#: builtin/push.c:539
+#: builtin/push.c:555
 msgid "delete refs"
 msgstr "删除引用"
 
-#: builtin/push.c:540
+#: builtin/push.c:556
 msgid "push tags (can't be used with --all or --mirror)"
 msgstr "推送标签(不能使用 --all or --mirror)"
 
-#: builtin/push.c:543 builtin/send-pack.c:166
+#: builtin/push.c:559 builtin/send-pack.c:167
 msgid "force updates"
 msgstr "强制更新"
 
-#: builtin/push.c:545 builtin/send-pack.c:180
+#: builtin/push.c:561 builtin/send-pack.c:181
 msgid "refname>:<expect"
 msgstr "引用名>:<期望值"
 
-#: builtin/push.c:546 builtin/send-pack.c:181
+#: builtin/push.c:562 builtin/send-pack.c:182
 msgid "require old value of ref to be at this value"
 msgstr "要求引用旧的取值为设定值"
 
-#: builtin/push.c:549
+#: builtin/push.c:565
 msgid "control recursive pushing of submodules"
 msgstr "控制子模组的递归推送"
 
-#: builtin/push.c:551 builtin/send-pack.c:174
+#: builtin/push.c:567 builtin/send-pack.c:175
 msgid "use thin pack"
 msgstr "使用精简打包"
 
-#: builtin/push.c:552 builtin/push.c:553 builtin/send-pack.c:160
-#: builtin/send-pack.c:161
+#: builtin/push.c:568 builtin/push.c:569 builtin/send-pack.c:161
+#: builtin/send-pack.c:162
 msgid "receive pack program"
 msgstr "接收包程序"
 
-#: builtin/push.c:554
+#: builtin/push.c:570
 msgid "set upstream for git pull/status"
 msgstr "设置 git pull/status 的上游"
 
-#: builtin/push.c:557
+#: builtin/push.c:573
 msgid "prune locally removed refs"
 msgstr "清除本地删除的引用"
 
-#: builtin/push.c:559
+#: builtin/push.c:575
 msgid "bypass pre-push hook"
 msgstr "绕过 pre-push 钩子"
 
-#: builtin/push.c:560
+#: builtin/push.c:576
 msgid "push missing but relevant tags"
 msgstr "推送缺失但有关的标签"
 
-#: builtin/push.c:563 builtin/send-pack.c:168
+#: builtin/push.c:579 builtin/send-pack.c:169
 msgid "GPG sign the push"
 msgstr "用 GPG 为推送签名"
 
-#: builtin/push.c:565 builtin/send-pack.c:175
+#: builtin/push.c:581 builtin/send-pack.c:176
 msgid "request atomic transaction on remote side"
 msgstr "需要远端支持原子事务"
 
-#: builtin/push.c:566 builtin/send-pack.c:171
-msgid "server-specific"
-msgstr "server-specific"
-
-#: builtin/push.c:566 builtin/send-pack.c:172
-msgid "option to transmit"
-msgstr "传输选项"
-
-#: builtin/push.c:583
+#: builtin/push.c:599
 msgid "--delete is incompatible with --all, --mirror and --tags"
 msgstr "--delete 与 --all、--mirror 及 --tags 不兼容"
 
-#: builtin/push.c:585
+#: builtin/push.c:601
 msgid "--delete doesn't make sense without any refs"
 msgstr "--delete 未接任何引用没有意义"
 
 #: builtin/push.c:604
+msgid "--all and --tags are incompatible"
+msgstr "--all 和 --tags 不兼容"
+
+#: builtin/push.c:606
+msgid "--all can't be combined with refspecs"
+msgstr "--all 不能和引用规格同时使用"
+
+#: builtin/push.c:610
+msgid "--mirror and --tags are incompatible"
+msgstr "--mirror 和 --tags 不兼容"
+
+#: builtin/push.c:612
+msgid "--mirror can't be combined with refspecs"
+msgstr "--mirror 不能和引用规格同时使用"
+
+#: builtin/push.c:615
+msgid "--all and --mirror are incompatible"
+msgstr "--all 和 --mirror 不兼容"
+
+#: builtin/push.c:634
 msgid "push options must not have new line characters"
 msgstr "推送选项不能有换行符"
 
@@ -12058,67 +12514,67 @@ msgstr ""
 "u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--"
 "index-output=<文件>] (--empty | <树对象1> [<树对象2> [<树对象3>]])"
 
-#: builtin/read-tree.c:121
+#: builtin/read-tree.c:120
 msgid "write resulting index to <file>"
 msgstr "将索引结果写入 <文件>"
 
-#: builtin/read-tree.c:124
+#: builtin/read-tree.c:123
 msgid "only empty the index"
 msgstr "只是清空索引"
 
-#: builtin/read-tree.c:126
+#: builtin/read-tree.c:125
 msgid "Merging"
 msgstr "合并"
 
-#: builtin/read-tree.c:128
+#: builtin/read-tree.c:127
 msgid "perform a merge in addition to a read"
 msgstr "读取之余再执行一个合并"
 
-#: builtin/read-tree.c:130
+#: builtin/read-tree.c:129
 msgid "3-way merge if no file level merging required"
 msgstr "如果没有文件级合并需要,执行三方合并"
 
-#: builtin/read-tree.c:132
+#: builtin/read-tree.c:131
 msgid "3-way merge in presence of adds and removes"
 msgstr "存在添加和删除时,也执行三方合并"
 
-#: builtin/read-tree.c:134
+#: builtin/read-tree.c:133
 msgid "same as -m, but discard unmerged entries"
 msgstr "类似于 -m,但丢弃未合并的条目"
 
-#: builtin/read-tree.c:135
+#: builtin/read-tree.c:134
 msgid "<subdirectory>/"
 msgstr "<子目录>/"
 
-#: builtin/read-tree.c:136
+#: builtin/read-tree.c:135
 msgid "read the tree into the index under <subdirectory>/"
 msgstr "读取树对象到索引的 <子目录>/ 下"
 
-#: builtin/read-tree.c:139
+#: builtin/read-tree.c:138
 msgid "update working tree with merge result"
 msgstr "用合并的结果更新工作区"
 
-#: builtin/read-tree.c:141
+#: builtin/read-tree.c:140
 msgid "gitignore"
 msgstr "gitignore"
 
-#: builtin/read-tree.c:142
+#: builtin/read-tree.c:141
 msgid "allow explicitly ignored files to be overwritten"
 msgstr "允许忽略文件中设定的文件可以被覆盖"
 
-#: builtin/read-tree.c:145
+#: builtin/read-tree.c:144
 msgid "don't check the working tree after merging"
 msgstr "合并后不检查工作区"
 
-#: builtin/read-tree.c:146
+#: builtin/read-tree.c:145
 msgid "don't update the index or the work tree"
 msgstr "不更新索引区和工作区"
 
-#: builtin/read-tree.c:148
+#: builtin/read-tree.c:147
 msgid "skip applying sparse checkout filter"
 msgstr "跳过应用稀疏检出过滤器"
 
-#: builtin/read-tree.c:150
+#: builtin/read-tree.c:149
 msgid "debug unpack-trees"
 msgstr "调试 unpack-trees"
 
@@ -12135,46 +12591,58 @@ msgid "allow commits with empty messages"
 msgstr "允许提交说明为空"
 
 #: builtin/rebase--helper.c:27
+msgid "rebase merge commits"
+msgstr "对合并提交变基"
+
+#: builtin/rebase--helper.c:29
+msgid "keep original branch points of cousins"
+msgstr "保持兄弟提交的原始分支点"
+
+#: builtin/rebase--helper.c:30
 msgid "continue rebase"
 msgstr "继续变基"
 
-#: builtin/rebase--helper.c:29
+#: builtin/rebase--helper.c:32
 msgid "abort rebase"
 msgstr "中止变基"
 
-#: builtin/rebase--helper.c:32
+#: builtin/rebase--helper.c:35
 msgid "make rebase script"
 msgstr "制作变基脚本"
 
-#: builtin/rebase--helper.c:34
+#: builtin/rebase--helper.c:37
 msgid "shorten commit ids in the todo list"
 msgstr "缩短待办列表中的提交号"
 
-#: builtin/rebase--helper.c:36
+#: builtin/rebase--helper.c:39
 msgid "expand commit ids in the todo list"
 msgstr "扩展待办列表中的提交号"
 
-#: builtin/rebase--helper.c:38
+#: builtin/rebase--helper.c:41
 msgid "check the todo list"
 msgstr "检查待办列表"
 
-#: builtin/rebase--helper.c:40
+#: builtin/rebase--helper.c:43
 msgid "skip unnecessary picks"
 msgstr "跳过不必要的拣选"
 
-#: builtin/rebase--helper.c:42
+#: builtin/rebase--helper.c:45
 msgid "rearrange fixup/squash lines"
 msgstr "重新排列 fixup/squash 行"
 
-#: builtin/rebase--helper.c:44
+#: builtin/rebase--helper.c:47
 msgid "insert exec commands in todo list"
 msgstr "在待办列表中插入 exec 执行命令"
 
-#: builtin/receive-pack.c:30
+#: builtin/rebase--helper.c:68
+msgid "--[no-]rebase-cousins has no effect without --rebase-merges"
+msgstr "不使用 --rebase-merges,则 --[no-]rebase-cousins 没有效果"
+
+#: builtin/receive-pack.c:31
 msgid "git receive-pack <git-dir>"
 msgstr "git receive-pack <仓库目录>"
 
-#: builtin/receive-pack.c:841
+#: builtin/receive-pack.c:842
 msgid ""
 "By default, updating the current branch in a non-bare repository\n"
 "is denied, because it will make the index and work tree inconsistent\n"
@@ -12200,7 +12668,7 @@ msgstr ""
 "若要屏蔽此信息且保持默认行为,设置 'receive.denyCurrentBranch'\n"
 "配置变量为 'refuse'。"
 
-#: builtin/receive-pack.c:861
+#: builtin/receive-pack.c:862
 msgid ""
 "By default, deleting the current branch is denied, because the next\n"
 "'git clone' won't result in any file checked out, causing confusion.\n"
@@ -12219,11 +12687,11 @@ msgstr ""
 "\n"
 "若要屏蔽此信息,您可以设置它为 'refuse'。"
 
-#: builtin/receive-pack.c:1934
+#: builtin/receive-pack.c:1935
 msgid "quiet"
 msgstr "静默模式"
 
-#: builtin/receive-pack.c:1948
+#: builtin/receive-pack.c:1949
 msgid "You must specify a directory."
 msgstr "您必须指定一个目录。"
 
@@ -12232,11 +12700,11 @@ msgstr "您必须指定一个目录。"
 msgid "'%s' is not a valid timestamp"
 msgstr "'%s' 不是一个有效的时间戳"
 
-#: builtin/remote.c:13
+#: builtin/remote.c:14
 msgid "git remote [-v | --verbose]"
 msgstr "git remote [-v | --verbose]"
 
-#: builtin/remote.c:14
+#: builtin/remote.c:15
 msgid ""
 "git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <name> <url>"
@@ -12244,81 +12712,81 @@ msgstr ""
 "git remote add [-t <分支>] [-m <master>] [-f] [--tags | --no-tags] [--"
 "mirror=<fetch|push>] <名称> <地址>"
 
-#: builtin/remote.c:15 builtin/remote.c:35
+#: builtin/remote.c:16 builtin/remote.c:36
 msgid "git remote rename <old> <new>"
 msgstr "git remote rename <旧名称> <新名称>"
 
-#: builtin/remote.c:16 builtin/remote.c:40
+#: builtin/remote.c:17 builtin/remote.c:41
 msgid "git remote remove <name>"
 msgstr "git remote remove <名称>"
 
-#: builtin/remote.c:17 builtin/remote.c:45
+#: builtin/remote.c:18 builtin/remote.c:46
 msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"
 msgstr "git remote set-head <名称> (-a | --auto | -d | --delete | <分支>)"
 
-#: builtin/remote.c:18
+#: builtin/remote.c:19
 msgid "git remote [-v | --verbose] show [-n] <name>"
 msgstr "git remote [-v | --verbose] show [-n] <名称>"
 
-#: builtin/remote.c:19
+#: builtin/remote.c:20
 msgid "git remote prune [-n | --dry-run] <name>"
 msgstr "git remote prune [-n | --dry-run] <名称>"
 
-#: builtin/remote.c:20
+#: builtin/remote.c:21
 msgid ""
 "git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]"
 msgstr "git remote [-v | --verbose] update [-p | --prune] [(<组> | <远程>)...]"
 
-#: builtin/remote.c:21
+#: builtin/remote.c:22
 msgid "git remote set-branches [--add] <name> <branch>..."
 msgstr "git remote set-branches [--add] <名称> <分支>..."
 
-#: builtin/remote.c:22 builtin/remote.c:71
+#: builtin/remote.c:23 builtin/remote.c:72
 msgid "git remote get-url [--push] [--all] <name>"
 msgstr "git remote get-url [--push] [--all] <名称>"
 
-#: builtin/remote.c:23 builtin/remote.c:76
+#: builtin/remote.c:24 builtin/remote.c:77
 msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]"
 msgstr "git remote set-url [--push] <名称> <新的地址> [<旧的地址>]"
 
-#: builtin/remote.c:24 builtin/remote.c:77
+#: builtin/remote.c:25 builtin/remote.c:78
 msgid "git remote set-url --add <name> <newurl>"
 msgstr "git remote set-url --add <名称> <新的地址>"
 
-#: builtin/remote.c:25 builtin/remote.c:78
+#: builtin/remote.c:26 builtin/remote.c:79
 msgid "git remote set-url --delete <name> <url>"
 msgstr "git remote set-url --delete <名称> <地址>"
 
-#: builtin/remote.c:30
+#: builtin/remote.c:31
 msgid "git remote add [<options>] <name> <url>"
 msgstr "git remote add [<选项>] <名称> <地址>"
 
-#: builtin/remote.c:50
+#: builtin/remote.c:51
 msgid "git remote set-branches <name> <branch>..."
 msgstr "git remote set-branches <名称> <分支>..."
 
-#: builtin/remote.c:51
+#: builtin/remote.c:52
 msgid "git remote set-branches --add <name> <branch>..."
 msgstr "git remote set-branches --add <名称> <分支>..."
 
-#: builtin/remote.c:56
+#: builtin/remote.c:57
 msgid "git remote show [<options>] <name>"
 msgstr "git remote show [<选项>] <名称>"
 
-#: builtin/remote.c:61
+#: builtin/remote.c:62
 msgid "git remote prune [<options>] <name>"
 msgstr "git remote prune [<选项>] <名称>"
 
-#: builtin/remote.c:66
+#: builtin/remote.c:67
 msgid "git remote update [<options>] [<group> | <remote>]..."
 msgstr "git remote update [<选项>] [<组> | <远程>]..."
 
-#: builtin/remote.c:95
+#: builtin/remote.c:96
 #, c-format
 msgid "Updating %s"
 msgstr "更新 %s 中"
 
-#: builtin/remote.c:127
+#: builtin/remote.c:128
 msgid ""
 "--mirror is dangerous and deprecated; please\n"
 "\t use --mirror=fetch or --mirror=push instead"
@@ -12326,86 +12794,86 @@ msgstr ""
 "--mirror 选项危险且过时,请使用 --mirror=fetch\n"
 "\t 或 --mirror=push"
 
-#: builtin/remote.c:144
+#: builtin/remote.c:145
 #, c-format
 msgid "unknown mirror argument: %s"
 msgstr "未知的镜像参数:%s"
 
-#: builtin/remote.c:160
+#: builtin/remote.c:161
 msgid "fetch the remote branches"
 msgstr "抓取远程的分支"
 
-#: builtin/remote.c:162
+#: builtin/remote.c:163
 msgid "import all tags and associated objects when fetching"
 msgstr "抓取时导入所有的标签和关联对象"
 
-#: builtin/remote.c:165
+#: builtin/remote.c:166
 msgid "or do not fetch any tag at all (--no-tags)"
 msgstr "或不抓取任何标签(--no-tags)"
 
-#: builtin/remote.c:167
+#: builtin/remote.c:168
 msgid "branch(es) to track"
 msgstr "跟踪的分支"
 
-#: builtin/remote.c:168
+#: builtin/remote.c:169
 msgid "master branch"
 msgstr "主线分支"
 
-#: builtin/remote.c:169
+#: builtin/remote.c:170
 msgid "push|fetch"
 msgstr "push|fetch"
 
-#: builtin/remote.c:170
+#: builtin/remote.c:171
 msgid "set up remote as a mirror to push to or fetch from"
 msgstr "把远程设置为用以推送或抓取的镜像"
 
-#: builtin/remote.c:182
+#: builtin/remote.c:183
 msgid "specifying a master branch makes no sense with --mirror"
 msgstr "指定一个 master 分支并使用 --mirror 选项没有意义"
 
-#: builtin/remote.c:184
+#: builtin/remote.c:185
 msgid "specifying branches to track makes sense only with fetch mirrors"
 msgstr "指定要跟踪的分支只在与获取镜像同时使用才有意义"
 
-#: builtin/remote.c:191 builtin/remote.c:631
+#: builtin/remote.c:192 builtin/remote.c:634
 #, c-format
 msgid "remote %s already exists."
 msgstr "远程 %s 已经存在。"
 
-#: builtin/remote.c:195 builtin/remote.c:635
+#: builtin/remote.c:196 builtin/remote.c:638
 #, c-format
 msgid "'%s' is not a valid remote name"
 msgstr "'%s' 不是一个有效的远程名称"
 
-#: builtin/remote.c:235
+#: builtin/remote.c:236
 #, c-format
 msgid "Could not setup master '%s'"
 msgstr "无法设置 master '%s'"
 
-#: builtin/remote.c:337
+#: builtin/remote.c:342
 #, c-format
 msgid "Could not get fetch map for refspec %s"
 msgstr "无法得到引用规格 %s 的获取列表"
 
-#: builtin/remote.c:438 builtin/remote.c:446
+#: builtin/remote.c:441 builtin/remote.c:449
 msgid "(matching)"
 msgstr "(匹配)"
 
-#: builtin/remote.c:450
+#: builtin/remote.c:453
 msgid "(delete)"
 msgstr "(删除)"
 
-#: builtin/remote.c:624 builtin/remote.c:759 builtin/remote.c:858
+#: builtin/remote.c:627 builtin/remote.c:762 builtin/remote.c:861
 #, c-format
 msgid "No such remote: %s"
 msgstr "没有这样的远程:%s"
 
-#: builtin/remote.c:641
+#: builtin/remote.c:644
 #, c-format
 msgid "Could not rename config section '%s' to '%s'"
 msgstr "不能重命名配置小节 '%s' 到 '%s'"
 
-#: builtin/remote.c:661
+#: builtin/remote.c:664
 #, c-format
 msgid ""
 "Not updating non-default fetch refspec\n"
@@ -12416,17 +12884,17 @@ msgstr ""
 "\t%s\n"
 "\t如果必要请手动更新配置。"
 
-#: builtin/remote.c:697
+#: builtin/remote.c:700
 #, c-format
 msgid "deleting '%s' failed"
 msgstr "删除 '%s' 失败"
 
-#: builtin/remote.c:731
+#: builtin/remote.c:734
 #, c-format
 msgid "creating '%s' failed"
 msgstr "创建 '%s' 失败"
 
-#: builtin/remote.c:796
+#: builtin/remote.c:799
 msgid ""
 "Note: A branch outside the refs/remotes/ hierarchy was not removed;\n"
 "to delete it, use:"
@@ -12436,113 +12904,118 @@ msgid_plural ""
 msgstr[0] "注意:ref/remotes 层级之外的一个分支未被移除。要删除它,使用:"
 msgstr[1] "注意:ref/remotes 层级之外的一些分支未被移除。要删除它们,使用:"
 
-#: builtin/remote.c:810
+#: builtin/remote.c:813
 #, c-format
 msgid "Could not remove config section '%s'"
 msgstr "不能移除配置小节 '%s'"
 
-#: builtin/remote.c:911
+#: builtin/remote.c:914
 #, c-format
 msgid " new (next fetch will store in remotes/%s)"
 msgstr " 新的(下一次获取将存储于 remotes/%s)"
 
-#: builtin/remote.c:914
+#: builtin/remote.c:917
 msgid " tracked"
 msgstr " 已跟踪"
 
-#: builtin/remote.c:916
+#: builtin/remote.c:919
 msgid " stale (use 'git remote prune' to remove)"
 msgstr " 过时(使用 'git remote prune' 来移除)"
 
-#: builtin/remote.c:918
+#: builtin/remote.c:921
 msgid " ???"
 msgstr " ???"
 
-#: builtin/remote.c:959
+#: builtin/remote.c:962
 #, c-format
 msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch"
 msgstr "无效的 branch.%s.merge,不能变基到一个以上的分支"
 
-#: builtin/remote.c:967
+#: builtin/remote.c:971
 #, c-format
 msgid "rebases interactively onto remote %s"
 msgstr "交互式变基到远程 %s"
 
-#: builtin/remote.c:968
+#: builtin/remote.c:973
+#, c-format
+msgid "rebases interactively (with merges) onto remote %s"
+msgstr "交互式变基(含合并提交)到远程 %s"
+
+#: builtin/remote.c:976
 #, c-format
 msgid "rebases onto remote %s"
 msgstr "变基到远程 %s"
 
-#: builtin/remote.c:971
+#: builtin/remote.c:980
 #, c-format
 msgid " merges with remote %s"
 msgstr " 与远程 %s 合并"
 
-#: builtin/remote.c:974
+#: builtin/remote.c:983
 #, c-format
 msgid "merges with remote %s"
 msgstr "与远程 %s 合并"
 
-#: builtin/remote.c:977
+#: builtin/remote.c:986
 #, c-format
 msgid "%-*s    and with remote %s\n"
 msgstr "%-*s    以及和远程 %s\n"
 
-#: builtin/remote.c:1020
+#: builtin/remote.c:1029
 msgid "create"
 msgstr "创建"
 
-#: builtin/remote.c:1023
+#: builtin/remote.c:1032
 msgid "delete"
 msgstr "删除"
 
-#: builtin/remote.c:1027
+#: builtin/remote.c:1036
 msgid "up to date"
 msgstr "最新"
 
-#: builtin/remote.c:1030
+#: builtin/remote.c:1039
 msgid "fast-forwardable"
 msgstr "可快进"
 
-#: builtin/remote.c:1033
+#: builtin/remote.c:1042
 msgid "local out of date"
 msgstr "本地已过时"
 
-#: builtin/remote.c:1040
+#: builtin/remote.c:1049
 #, c-format
 msgid "    %-*s forces to %-*s (%s)"
 msgstr "    %-*s 强制推送至 %-*s (%s)"
 
-#: builtin/remote.c:1043
+#: builtin/remote.c:1052
 #, c-format
 msgid "    %-*s pushes to %-*s (%s)"
 msgstr "    %-*s 推送至 %-*s (%s)"
 
-#: builtin/remote.c:1047
+#: builtin/remote.c:1056
 #, c-format
 msgid "    %-*s forces to %s"
 msgstr "    %-*s 强制推送至 %s"
 
-#: builtin/remote.c:1050
+#: builtin/remote.c:1059
 #, c-format
 msgid "    %-*s pushes to %s"
 msgstr "    %-*s 推送至 %s"
 
-#: builtin/remote.c:1118
+#: builtin/remote.c:1127
 msgid "do not query remotes"
 msgstr "不查询远程"
 
-#: builtin/remote.c:1145
+#: builtin/remote.c:1154
 #, c-format
 msgid "* remote %s"
 msgstr "* 远程 %s"
 
-#: builtin/remote.c:1146
+#: builtin/remote.c:1155
 #, c-format
 msgid "  Fetch URL: %s"
 msgstr "  获取地址:%s"
 
-#: builtin/remote.c:1147 builtin/remote.c:1163 builtin/remote.c:1302
+#: builtin/remote.c:1156 builtin/remote.c:1172 builtin/remote.c:1311
 msgid "(no URL)"
 msgstr "(无 URL)"
 
@@ -12550,32 +13023,32 @@ msgstr "(无 URL)"
 #. with the one in " Fetch URL: %s"
 #. translation.
 #.
-#: builtin/remote.c:1161 builtin/remote.c:1163
+#: builtin/remote.c:1170 builtin/remote.c:1172
 #, c-format
 msgid "  Push  URL: %s"
 msgstr "  推送地址:%s"
 
-#: builtin/remote.c:1165 builtin/remote.c:1167 builtin/remote.c:1169
+#: builtin/remote.c:1174 builtin/remote.c:1176 builtin/remote.c:1178
 #, c-format
 msgid "  HEAD branch: %s"
 msgstr "  HEAD 分支:%s"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: builtin/remote.c:1165
+#: builtin/remote.c:1174
 msgid "(not queried)"
 msgstr "(未查询)"
 
-#: builtin/remote.c:1167
+#: builtin/remote.c:1176
 msgid "(unknown)"
 msgstr "(未知)"
 
-#: builtin/remote.c:1171
+#: builtin/remote.c:1180
 #, c-format
 msgid ""
 "  HEAD branch (remote HEAD is ambiguous, may be one of the following):\n"
 msgstr "  HEAD 分支(远程 HEAD 模糊,可能是下列中的一个):\n"
 
-#: builtin/remote.c:1183
+#: builtin/remote.c:1192
 #, c-format
 msgid "  Remote branch:%s"
 msgid_plural "  Remote branches:%s"
@@ -12583,155 +13056,155 @@ msgstr[0] "  远程分支:%s"
 msgstr[1] "  远程分支:%s"
 
 #  译者:中文字符串拼接,可删除前导空格
-#: builtin/remote.c:1186 builtin/remote.c:1212
+#: builtin/remote.c:1195 builtin/remote.c:1221
 msgid " (status not queried)"
 msgstr "(状态未查询)"
 
-#: builtin/remote.c:1195
+#: builtin/remote.c:1204
 msgid "  Local branch configured for 'git pull':"
 msgid_plural "  Local branches configured for 'git pull':"
 msgstr[0] "  为 'git pull' 配置的本地分支:"
 msgstr[1] "  为 'git pull' 配置的本地分支:"
 
-#: builtin/remote.c:1203
+#: builtin/remote.c:1212
 msgid "  Local refs will be mirrored by 'git push'"
 msgstr "  本地引用将在 'git push' 时被镜像"
 
-#: builtin/remote.c:1209
+#: builtin/remote.c:1218
 #, c-format
 msgid "  Local ref configured for 'git push'%s:"
 msgid_plural "  Local refs configured for 'git push'%s:"
 msgstr[0] "  为 'git push' 配置的本地引用%s:"
 msgstr[1] "  为 'git push' 配置的本地引用%s:"
 
-#: builtin/remote.c:1230
+#: builtin/remote.c:1239
 msgid "set refs/remotes/<name>/HEAD according to remote"
 msgstr "根据远程设置 refs/remotes/<名称>/HEAD"
 
-#: builtin/remote.c:1232
+#: builtin/remote.c:1241
 msgid "delete refs/remotes/<name>/HEAD"
 msgstr "删除 refs/remotes/<名称>/HEAD"
 
-#: builtin/remote.c:1247
+#: builtin/remote.c:1256
 msgid "Cannot determine remote HEAD"
 msgstr "无法确定远程 HEAD"
 
-#: builtin/remote.c:1249
+#: builtin/remote.c:1258
 msgid "Multiple remote HEAD branches. Please choose one explicitly with:"
 msgstr "多个远程 HEAD 分支。请明确地选择一个用命令:"
 
-#: builtin/remote.c:1259
+#: builtin/remote.c:1268
 #, c-format
 msgid "Could not delete %s"
 msgstr "无法删除 %s"
 
-#: builtin/remote.c:1267
+#: builtin/remote.c:1276
 #, c-format
 msgid "Not a valid ref: %s"
 msgstr "不是一个有效引用:%s"
 
-#: builtin/remote.c:1269
+#: builtin/remote.c:1278
 #, c-format
 msgid "Could not setup %s"
 msgstr "不能设置 %s"
 
 #  译者:注意保持前导空格
-#: builtin/remote.c:1287
+#: builtin/remote.c:1296
 #, c-format
 msgid " %s will become dangling!"
 msgstr " %s 将成为摇摆状态!"
 
 #  译者:注意保持前导空格
-#: builtin/remote.c:1288
+#: builtin/remote.c:1297
 #, c-format
 msgid " %s has become dangling!"
 msgstr " %s 已成为摇摆状态!"
 
-#: builtin/remote.c:1298
+#: builtin/remote.c:1307
 #, c-format
 msgid "Pruning %s"
 msgstr "修剪 %s"
 
-#: builtin/remote.c:1299
+#: builtin/remote.c:1308
 #, c-format
 msgid "URL: %s"
 msgstr "URL:%s"
 
-#: builtin/remote.c:1315
+#: builtin/remote.c:1324
 #, c-format
 msgid " * [would prune] %s"
 msgstr " * [将删除] %s"
 
-#: builtin/remote.c:1318
+#: builtin/remote.c:1327
 #, c-format
 msgid " * [pruned] %s"
 msgstr " * [已删除] %s"
 
-#: builtin/remote.c:1363
+#: builtin/remote.c:1372
 msgid "prune remotes after fetching"
 msgstr "抓取后清除远程"
 
-#: builtin/remote.c:1426 builtin/remote.c:1480 builtin/remote.c:1548
+#: builtin/remote.c:1435 builtin/remote.c:1489 builtin/remote.c:1557
 #, c-format
 msgid "No such remote '%s'"
 msgstr "没有此远程 '%s'"
 
-#: builtin/remote.c:1442
+#: builtin/remote.c:1451
 msgid "add branch"
 msgstr "添加分支"
 
-#: builtin/remote.c:1449
+#: builtin/remote.c:1458
 msgid "no remote specified"
 msgstr "未指定远程"
 
-#: builtin/remote.c:1466
+#: builtin/remote.c:1475
 msgid "query push URLs rather than fetch URLs"
 msgstr "查询推送 URL 地址,而非获取 URL 地址"
 
-#: builtin/remote.c:1468
+#: builtin/remote.c:1477
 msgid "return all URLs"
 msgstr "返回所有 URL 地址"
 
-#: builtin/remote.c:1496
+#: builtin/remote.c:1505
 #, c-format
 msgid "no URLs configured for remote '%s'"
 msgstr "没有给远程仓库 '%s' 设定 URL"
 
-#: builtin/remote.c:1522
+#: builtin/remote.c:1531
 msgid "manipulate push URLs"
 msgstr "操作推送 URLS"
 
-#: builtin/remote.c:1524
+#: builtin/remote.c:1533
 msgid "add URL"
 msgstr "添加 URL"
 
-#: builtin/remote.c:1526
+#: builtin/remote.c:1535
 msgid "delete URLs"
 msgstr "删除 URLS"
 
-#: builtin/remote.c:1533
+#: builtin/remote.c:1542
 msgid "--add --delete doesn't make sense"
 msgstr "--add --delete 无意义"
 
-#: builtin/remote.c:1572
+#: builtin/remote.c:1581
 #, c-format
 msgid "Invalid old URL pattern: %s"
 msgstr "无效的旧 URL 匹配模版:%s"
 
-#: builtin/remote.c:1580
+#: builtin/remote.c:1589
 #, c-format
 msgid "No such URL found: %s"
 msgstr "未找到此 URL:%s"
 
-#: builtin/remote.c:1582
+#: builtin/remote.c:1591
 msgid "Will not delete all non-push URLs"
 msgstr "将不会删除所有非推送 URL 地址"
 
-#: builtin/remote.c:1598
+#: builtin/remote.c:1607
 msgid "be verbose; must be placed before a subcommand"
 msgstr "冗长输出;必须置于子命令之前"
 
-#: builtin/remote.c:1629
+#: builtin/remote.c:1638
 #, c-format
 msgid "Unknown subcommand: %s"
 msgstr "未知子命令:%s"
@@ -12748,172 +13221,193 @@ msgstr ""
 "增量 repack 和 bitmap 索引不兼容。  使用 --no-write-bitmap-index\n"
 "或禁用 pack.writebitmaps 配置。"
 
-#: builtin/repack.c:170
+#: builtin/repack.c:180
 msgid "pack everything in a single pack"
 msgstr "所有内容打包到一个包文件中"
 
-#: builtin/repack.c:172
+#: builtin/repack.c:182
 msgid "same as -a, and turn unreachable objects loose"
 msgstr "和 -a 相同,并将不可达的对象设为松散对象"
 
-#: builtin/repack.c:175
+#: builtin/repack.c:185
 msgid "remove redundant packs, and run git-prune-packed"
 msgstr "删除多余的包,运行 git-prune-packed"
 
-#: builtin/repack.c:177
+#: builtin/repack.c:187
 msgid "pass --no-reuse-delta to git-pack-objects"
 msgstr "向 git-pack-objects 传递参数 --no-reuse-delta"
 
-#: builtin/repack.c:179
+#: builtin/repack.c:189
 msgid "pass --no-reuse-object to git-pack-objects"
 msgstr "向 git-pack-objects 传递参数 --no-reuse-object"
 
-#: builtin/repack.c:181
+#: builtin/repack.c:191
 msgid "do not run git-update-server-info"
 msgstr "不运行 git-update-server-info"
 
-#: builtin/repack.c:184
+#: builtin/repack.c:194
 msgid "pass --local to git-pack-objects"
 msgstr "向 git-pack-objects 传递参数 --local"
 
-#: builtin/repack.c:186
+#: builtin/repack.c:196
 msgid "write bitmap index"
 msgstr "写 bitmap 索引"
 
-#: builtin/repack.c:187
+#: builtin/repack.c:197
 msgid "approxidate"
 msgstr "近似日期"
 
-#: builtin/repack.c:188
+#: builtin/repack.c:198
 msgid "with -A, do not loosen objects older than this"
 msgstr "使用 -A,不要将早于给定时间的对象过期"
 
-#: builtin/repack.c:190
+#: builtin/repack.c:200
 msgid "with -a, repack unreachable objects"
 msgstr "使用 -a ,重新对不可达对象打包"
 
-#: builtin/repack.c:192
+#: builtin/repack.c:202
 msgid "size of the window used for delta compression"
 msgstr "用于增量压缩的窗口值"
 
-#: builtin/repack.c:193 builtin/repack.c:199
+#: builtin/repack.c:203 builtin/repack.c:209
 msgid "bytes"
 msgstr "字节"
 
-#: builtin/repack.c:194
+#: builtin/repack.c:204
 msgid "same as the above, but limit memory size instead of entries count"
 msgstr "和上面的相似,但限制内存大小而非条目数"
 
-#: builtin/repack.c:196
+#: builtin/repack.c:206
 msgid "limits the maximum delta depth"
 msgstr "限制最大增量深度"
 
-#: builtin/repack.c:198
+#: builtin/repack.c:208
 msgid "limits the maximum number of threads"
 msgstr "限制最大线程数"
 
-#: builtin/repack.c:200
+#: builtin/repack.c:210
 msgid "maximum size of each packfile"
 msgstr "每个包文件的最大尺寸"
 
-#: builtin/repack.c:202
+#: builtin/repack.c:212
 msgid "repack objects in packs marked with .keep"
 msgstr "对标记为 .keep 的包中的对象重新打包"
 
-#: builtin/repack.c:212
+#: builtin/repack.c:214
+msgid "do not repack this pack"
+msgstr "不要对该包文件重新打包"
+
+#: builtin/repack.c:224
 msgid "cannot delete packs in a precious-objects repo"
 msgstr "不能删除珍品仓库中的打包文件"
 
-#: builtin/repack.c:216
+#: builtin/repack.c:228
 msgid "--keep-unreachable and -A are incompatible"
 msgstr "--keep-unreachable 和 -A 不兼容"
 
-#: builtin/repack.c:410 builtin/worktree.c:148
+#: builtin/repack.c:425 builtin/worktree.c:139
 #, c-format
 msgid "failed to remove '%s'"
 msgstr "无法删除 '%s'"
 
-#: builtin/replace.c:20
+#: builtin/replace.c:22
 msgid "git replace [-f] <object> <replacement>"
 msgstr "git replace [-f] <对象> <替换物>"
 
-#: builtin/replace.c:21
+#: builtin/replace.c:23
 msgid "git replace [-f] --edit <object>"
 msgstr "git replace [-f] --edit <对象>"
 
-#: builtin/replace.c:22
+#: builtin/replace.c:24
 msgid "git replace [-f] --graft <commit> [<parent>...]"
 msgstr "git replace [-f] --graft <提交> [<父提交>...]"
 
-#: builtin/replace.c:23
+#: builtin/replace.c:25
+msgid "git replace [-f] --convert-graft-file"
+msgstr "git replace [-f] --convert-graft-file"
+
+#: builtin/replace.c:26
 msgid "git replace -d <object>..."
 msgstr "git replace -d <对象>..."
 
-#: builtin/replace.c:24
+#: builtin/replace.c:27
 msgid "git replace [--format=<format>] [-l [<pattern>]]"
 msgstr "git replace [--format=<格式>] [-l [<模式>]]"
 
-#: builtin/replace.c:331 builtin/replace.c:369 builtin/replace.c:397
+#: builtin/replace.c:371 builtin/replace.c:415 builtin/replace.c:445
 #, c-format
 msgid "Not a valid object name: '%s'"
 msgstr "不是一个有效的对象名:'%s'"
 
-#: builtin/replace.c:361
+#: builtin/replace.c:407
 #, c-format
 msgid "bad mergetag in commit '%s'"
 msgstr "提交 '%s' 中含有损坏的合并标签"
 
-#: builtin/replace.c:363
+#: builtin/replace.c:409
 #, c-format
 msgid "malformed mergetag in commit '%s'"
-msgstr "提交 '%s' 中含有非法的合并标签"
+msgstr "提交 '%s' 中含有格式错误的合并标签"
 
-#: builtin/replace.c:374
+#: builtin/replace.c:421
 #, c-format
 msgid ""
 "original commit '%s' contains mergetag '%s' that is discarded; use --edit "
 "instead of --graft"
 msgstr "原始提交 '%s' 包含已经丢弃的合并标签 '%s',使用 --edit 代替 --graft"
 
-#: builtin/replace.c:407
+#: builtin/replace.c:460
 #, c-format
 msgid "the original commit '%s' has a gpg signature."
 msgstr "原始提交 '%s' 中包含一个 GPG 签名"
 
-#: builtin/replace.c:408
+#: builtin/replace.c:461
 msgid "the signature will be removed in the replacement commit!"
 msgstr "在替换的提交中签名将被移除!"
 
-#: builtin/replace.c:414
+#: builtin/replace.c:471
 #, c-format
 msgid "could not write replacement commit for: '%s'"
 msgstr "不能为 '%s' 写替换提交"
 
-#: builtin/replace.c:438
+#: builtin/replace.c:514
+#, c-format
+msgid ""
+"could not convert the following graft(s):\n"
+"%s"
+msgstr ""
+"不能转换下列移植:\n"
+"%s"
+
+#: builtin/replace.c:535
 msgid "list replace refs"
 msgstr "列出替换的引用"
 
-#: builtin/replace.c:439
+#: builtin/replace.c:536
 msgid "delete replace refs"
 msgstr "删除替换的引用"
 
-#: builtin/replace.c:440
+#: builtin/replace.c:537
 msgid "edit existing object"
 msgstr "编辑现存的对象"
 
-#: builtin/replace.c:441
+#: builtin/replace.c:538
 msgid "change a commit's parents"
 msgstr "修改一个提交的父提交"
 
-#: builtin/replace.c:442
+#: builtin/replace.c:539
+msgid "convert existing graft file"
+msgstr "转换现存的移植文件"
+
+#: builtin/replace.c:540
 msgid "replace the ref if it exists"
 msgstr "如果存在则替换引用"
 
-#: builtin/replace.c:444
+#: builtin/replace.c:542
 msgid "do not pretty-print contents for --edit"
 msgstr "不要为 --edit 操作美观显示内容"
 
-#: builtin/replace.c:445
+#: builtin/replace.c:543
 msgid "use this format"
 msgstr "使用此格式"
 
@@ -13074,23 +13568,23 @@ msgstr "rev-list 不支持显示注解"
 msgid "cannot combine --use-bitmap-index with object filtering"
 msgstr "不能将 --use-bitmap-index 和对象过滤组合使用"
 
-#: builtin/rev-parse.c:402
+#: builtin/rev-parse.c:406
 msgid "git rev-parse --parseopt [<options>] -- [<args>...]"
 msgstr "git rev-parse --parseopt [<选项>] -- [<参数>...]"
 
-#: builtin/rev-parse.c:407
+#: builtin/rev-parse.c:411
 msgid "keep the `--` passed as an arg"
 msgstr "保持 `--` 作为一个参数传递"
 
-#: builtin/rev-parse.c:409
+#: builtin/rev-parse.c:413
 msgid "stop parsing after the first non-option argument"
 msgstr "遇到第一个非选项参数后停止解析"
 
-#: builtin/rev-parse.c:412
+#: builtin/rev-parse.c:416
 msgid "output in stuck long form"
 msgstr "以固定长格式输出"
 
-#: builtin/rev-parse.c:545
+#: builtin/rev-parse.c:549
 msgid ""
 "git rev-parse --parseopt [<options>] -- [<args>...]\n"
 "   or: git rev-parse --sq-quote [<arg>...]\n"
@@ -13227,42 +13721,42 @@ msgid_plural "the following files have local modifications:"
 msgstr[0] "如下文件有本地修改:"
 msgstr[1] "如下文件有本地修改:"
 
-#: builtin/rm.c:243
+#: builtin/rm.c:241
 msgid "do not list removed files"
 msgstr "不列出删除的文件"
 
-#: builtin/rm.c:244
+#: builtin/rm.c:242
 msgid "only remove from the index"
 msgstr "只从索引区删除"
 
-#: builtin/rm.c:245
+#: builtin/rm.c:243
 msgid "override the up-to-date check"
 msgstr "忽略文件更新状态检查"
 
-#: builtin/rm.c:246
+#: builtin/rm.c:244
 msgid "allow recursive removal"
 msgstr "允许递归删除"
 
-#: builtin/rm.c:248
+#: builtin/rm.c:246
 msgid "exit with a zero status even if nothing matched"
 msgstr "即使没有匹配,也以零状态退出"
 
-#: builtin/rm.c:307
+#: builtin/rm.c:306
 #, c-format
 msgid "not removing '%s' recursively without -r"
 msgstr "未提供 -r 选项不会递归删除 '%s'"
 
-#: builtin/rm.c:346
+#: builtin/rm.c:345
 #, c-format
 msgid "git rm: unable to remove %s"
 msgstr "git rm:不能删除 %s"
 
-#: builtin/rm.c:369
+#: builtin/rm.c:368
 #, c-format
 msgid "could not remove '%s'"
 msgstr "无法删除 '%s'"
 
-#: builtin/send-pack.c:19
+#: builtin/send-pack.c:20
 msgid ""
 "git send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-"
 "receive-pack>] [--verbose] [--thin] [--atomic] [<host>:]<directory> "
@@ -13273,50 +13767,70 @@ msgstr ""
 "receive-pack>] [--verbose] [--thin] [--atomic] [<主机>:]<目录> [<引用>...]\n"
 "  --all 和明确的 <引用> 互斥。"
 
-#: builtin/send-pack.c:162
+#: builtin/send-pack.c:163
 msgid "remote name"
 msgstr "远程名称"
 
-#: builtin/send-pack.c:176
+#: builtin/send-pack.c:177
 msgid "use stateless RPC protocol"
 msgstr "使用无状态的 RPC 协议"
 
-#: builtin/send-pack.c:177
+#: builtin/send-pack.c:178
 msgid "read refs from stdin"
 msgstr "从标准输入读取引用"
 
-#: builtin/send-pack.c:178
+#: builtin/send-pack.c:179
 msgid "print status from remote helper"
 msgstr "打印来自远程 helper 的状态"
 
+#: builtin/serve.c:7
+msgid "git serve [<options>]"
+msgstr "git serve [<选项>]"
+
+#: builtin/serve.c:17 builtin/upload-pack.c:23
+msgid "quit after a single request/response exchange"
+msgstr "在一次单独的请求/响应之后退出"
+
+#: builtin/serve.c:19
+msgid "exit immediately after advertising capabilities"
+msgstr "在广告功能后立即退出"
+
 #: builtin/shortlog.c:14
-msgid "git shortlog [<options>] [<revision-range>] [[--] [<path>...]]"
-msgstr "git shortlog [<选项>] [<版本范围>] [[--] [<路径>...]]"
+msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]"
+msgstr "git shortlog [<选项>] [<版本范围>] [[--] <路径>...]"
+
+#: builtin/shortlog.c:15
+msgid "git log --pretty=short | git shortlog [<options>]"
+msgstr "git log --pretty=short | git shortlog [<选项>]"
 
-#: builtin/shortlog.c:263
+#: builtin/shortlog.c:264
 msgid "Group by committer rather than author"
 msgstr "按照提交者分组而不是作者"
 
-#: builtin/shortlog.c:265
+#: builtin/shortlog.c:266
 msgid "sort output according to the number of commits per author"
 msgstr "根据每个作者的提交数量排序"
 
-#: builtin/shortlog.c:267
+#: builtin/shortlog.c:268
 msgid "Suppress commit descriptions, only provides commit count"
 msgstr "隐藏提交说明,只提供提交数量"
 
-#: builtin/shortlog.c:269
+#: builtin/shortlog.c:270
 msgid "Show the email address of each author"
 msgstr "显示每个作者的电子邮件地址"
 
-#: builtin/shortlog.c:270
+#: builtin/shortlog.c:271
 msgid "w[,i1[,i2]]"
 msgstr "w[,i1[,i2]]"
 
-#: builtin/shortlog.c:271
+#: builtin/shortlog.c:272
 msgid "Linewrap output"
 msgstr "折行输出"
 
+#: builtin/shortlog.c:298
+msgid "too many arguments given outside repository"
+msgstr "仓库外执行提供了太多的参数"
+
 #: builtin/show-branch.c:12
 msgid ""
 "git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n"
@@ -13511,233 +14025,233 @@ msgstr "跳过和移除所有的注释行"
 msgid "prepend comment character and space to each line"
 msgstr "为每一行的行首添加注释符和空格"
 
-#: builtin/submodule--helper.c:35 builtin/submodule--helper.c:1669
+#: builtin/submodule--helper.c:37 builtin/submodule--helper.c:1688
 #, c-format
 msgid "No such ref: %s"
 msgstr "没有这样的引用:%s"
 
-#: builtin/submodule--helper.c:42 builtin/submodule--helper.c:1678
+#: builtin/submodule--helper.c:44 builtin/submodule--helper.c:1697
 #, c-format
 msgid "Expecting a full ref name, got %s"
 msgstr "期望一个完整的引用名称,却得到 %s"
 
-#: builtin/submodule--helper.c:59
+#: builtin/submodule--helper.c:61
 msgid "submodule--helper print-default-remote takes no arguments"
 msgstr "submodule--helper print-default-remote 不带参数"
 
-#: builtin/submodule--helper.c:96
+#: builtin/submodule--helper.c:98
 #, c-format
 msgid "cannot strip one component off url '%s'"
 msgstr "无法从 url '%s' 剥离一个组件"
 
-#: builtin/submodule--helper.c:404 builtin/submodule--helper.c:1198
+#: builtin/submodule--helper.c:406 builtin/submodule--helper.c:1211
 msgid "alternative anchor for relative paths"
 msgstr "相对路径的替代锚记(anchor)"
 
-#: builtin/submodule--helper.c:409
+#: builtin/submodule--helper.c:411
 msgid "git submodule--helper list [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper list [--prefix=<路径>] [<路径>...]"
 
-#: builtin/submodule--helper.c:460 builtin/submodule--helper.c:483
+#: builtin/submodule--helper.c:462 builtin/submodule--helper.c:485
 #, c-format
 msgid "No url found for submodule path '%s' in .gitmodules"
 msgstr "在 .gitmodules 中未找到子模组 '%s' 的 url"
 
-#: builtin/submodule--helper.c:498
+#: builtin/submodule--helper.c:500
 #, c-format
 msgid ""
 "could not lookup configuration '%s'. Assuming this repository is its own "
 "authoritative upstream."
 msgstr "无法找到配置 '%s'。假定这个仓库是其自身的官方上游。"
 
-#: builtin/submodule--helper.c:509
+#: builtin/submodule--helper.c:511
 #, c-format
 msgid "Failed to register url for submodule path '%s'"
 msgstr "无法为子模组 '%s' 注册 url"
 
-#: builtin/submodule--helper.c:513
+#: builtin/submodule--helper.c:515
 #, c-format
 msgid "Submodule '%s' (%s) registered for path '%s'\n"
 msgstr "子模组 '%s'(%s)未对路径 '%s' 注册\n"
 
 #
-#: builtin/submodule--helper.c:523
+#: builtin/submodule--helper.c:525
 #, c-format
 msgid "warning: command update mode suggested for submodule '%s'\n"
 msgstr "警告:建议子模组 '%s' 使用命令更新模式\n"
 
-#: builtin/submodule--helper.c:530
+#: builtin/submodule--helper.c:532
 #, c-format
 msgid "Failed to register update mode for submodule path '%s'"
 msgstr "无法为子模组 '%s' 注册更新模式"
 
-#: builtin/submodule--helper.c:552
+#: builtin/submodule--helper.c:554
 msgid "Suppress output for initializing a submodule"
 msgstr "阻止子模组初始化的输出"
 
-#: builtin/submodule--helper.c:557
+#: builtin/submodule--helper.c:559
 msgid "git submodule--helper init [<path>]"
 msgstr "git submodule--helper init [<路径>]"
 
-#: builtin/submodule--helper.c:625 builtin/submodule--helper.c:747
+#: builtin/submodule--helper.c:631 builtin/submodule--helper.c:757
 #, c-format
 msgid "no submodule mapping found in .gitmodules for path '%s'"
 msgstr "在 .gitmodules 中没有发现路径 '%s' 的子模组映射"
 
-#: builtin/submodule--helper.c:660
+#: builtin/submodule--helper.c:670
 #, c-format
 msgid "could not resolve HEAD ref inside the submodule '%s'"
 msgstr "无法解析子模组 '%s' 的 HEAD 引用"
 
-#: builtin/submodule--helper.c:687 builtin/submodule--helper.c:856
+#: builtin/submodule--helper.c:697 builtin/submodule--helper.c:866
 #, c-format
 msgid "failed to recurse into submodule '%s'"
 msgstr "无法递归子模组 '%s'"
 
-#: builtin/submodule--helper.c:711 builtin/submodule--helper.c:1021
+#: builtin/submodule--helper.c:721 builtin/submodule--helper.c:1031
 msgid "Suppress submodule status output"
 msgstr "阻止子模组状态输出"
 
-#: builtin/submodule--helper.c:712
+#: builtin/submodule--helper.c:722
 msgid ""
 "Use commit stored in the index instead of the one stored in the submodule "
 "HEAD"
 msgstr "使用存储在索引中的提交,而非存储在子模组 HEAD 中的提交"
 
-#: builtin/submodule--helper.c:713
+#: builtin/submodule--helper.c:723
 msgid "recurse into nested submodules"
 msgstr "递归进入嵌套子模组中"
 
-#: builtin/submodule--helper.c:718
+#: builtin/submodule--helper.c:728
 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]"
 msgstr "git submodule status [--quiet] [--cached] [--recursive] [<路径>...]"
 
-#: builtin/submodule--helper.c:742
+#: builtin/submodule--helper.c:752
 msgid "git submodule--helper name <path>"
 msgstr "git submodule--helper name <路径>"
 
-#: builtin/submodule--helper.c:806
+#: builtin/submodule--helper.c:816
 #, c-format
 msgid "Synchronizing submodule url for '%s'\n"
 msgstr "为 '%s' 同步子模组 url\n"
 
-#: builtin/submodule--helper.c:812
+#: builtin/submodule--helper.c:822
 #, c-format
 msgid "failed to register url for submodule path '%s'"
 msgstr "无法为子模组路径 '%s' 注册 url"
 
-#: builtin/submodule--helper.c:826
+#: builtin/submodule--helper.c:836
 #, c-format
 msgid "failed to get the default remote for submodule '%s'"
 msgstr "无法得到子模组 '%s' 的默认远程关联"
 
-#: builtin/submodule--helper.c:837
+#: builtin/submodule--helper.c:847
 #, c-format
 msgid "failed to update remote for submodule '%s'"
 msgstr "无法为子模组 '%s' 更新远程关联"
 
-#: builtin/submodule--helper.c:885
+#: builtin/submodule--helper.c:895
 msgid "Suppress output of synchronizing submodule url"
 msgstr "阻止子模组 url 同步的输出"
 
-#: builtin/submodule--helper.c:887
+#: builtin/submodule--helper.c:897
 msgid "Recurse into nested submodules"
 msgstr "递归进入嵌套子模组中"
 
-#: builtin/submodule--helper.c:892
+#: builtin/submodule--helper.c:902
 msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]"
 msgstr "git submodule--helper sync [--quiet] [--recursive] [<路径>]"
 
-#: builtin/submodule--helper.c:946
+#: builtin/submodule--helper.c:956
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you "
 "really want to remove it including all of its history)"
 msgstr ""
-"子模组工作区 '%s' 包含一个 .git 目录(如果您确需删除它及其全部历史,使用 "
-"'rm -rf' 命令)"
+"子模组工作区 '%s' 包含一个 .git 目录(如果您确需删除它及其全部历史,使用 'rm "
+"-rf' 命令)"
 
-#: builtin/submodule--helper.c:958
+#: builtin/submodule--helper.c:968
 #, c-format
 msgid ""
 "Submodule work tree '%s' contains local modifications; use '-f' to discard "
 "them"
 msgstr "子模组工作区 '%s' 包含本地修改;使用 '-f' 丢弃它们"
 
-#: builtin/submodule--helper.c:966
+#: builtin/submodule--helper.c:976
 #, c-format
 msgid "Cleared directory '%s'\n"
 msgstr "已清除目录 '%s'\n"
 
-#: builtin/submodule--helper.c:968
+#: builtin/submodule--helper.c:978
 #, c-format
 msgid "Could not remove submodule work tree '%s'\n"
 msgstr "无法移除子模组工作区 '%s'\n"
 
-#: builtin/submodule--helper.c:977
+#: builtin/submodule--helper.c:987
 #, c-format
 msgid "could not create empty submodule directory %s"
 msgstr "不能创建空的子模组目录 %s"
 
-#: builtin/submodule--helper.c:993
+#: builtin/submodule--helper.c:1003
 #, c-format
 msgid "Submodule '%s' (%s) unregistered for path '%s'\n"
 msgstr "子模组 '%s'(%s)未对路径 '%s' 注册\n"
 
-#: builtin/submodule--helper.c:1022
+#: builtin/submodule--helper.c:1032
 msgid "Remove submodule working trees even if they contain local changes"
 msgstr "删除子模组工作区,即使包含本地修改"
 
-#: builtin/submodule--helper.c:1023
+#: builtin/submodule--helper.c:1033
 msgid "Unregister all submodules"
 msgstr "将所有子模组取消注册"
 
-#: builtin/submodule--helper.c:1028
+#: builtin/submodule--helper.c:1038
 msgid ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]"
 msgstr ""
 "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<路径>...]]"
 
-#: builtin/submodule--helper.c:1042
+#: builtin/submodule--helper.c:1052
 msgid "Use '--all' if you really want to deinitialize all submodules"
 msgstr "如果您确实想要对所有子模组执行取消初始化,请使用 '--all'"
 
-#: builtin/submodule--helper.c:1133 builtin/submodule--helper.c:1136
+#: builtin/submodule--helper.c:1145 builtin/submodule--helper.c:1148
 #, c-format
 msgid "submodule '%s' cannot add alternate: %s"
 msgstr "子模组 '%s' 不能添加仓库备选:%s"
 
-#: builtin/submodule--helper.c:1172
+#: builtin/submodule--helper.c:1184
 #, c-format
 msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized"
 msgstr "不能识别 submodule.alternateErrorStrategy 的取值 '%s'"
 
-#: builtin/submodule--helper.c:1179
+#: builtin/submodule--helper.c:1191
 #, c-format
 msgid "Value '%s' for submodule.alternateLocation is not recognized"
 msgstr "不能识别 submodule.alternateLocaion 的取值 '%s'"
 
-#: builtin/submodule--helper.c:1201
+#: builtin/submodule--helper.c:1214
 msgid "where the new submodule will be cloned to"
 msgstr "新的子模组将要克隆的路径"
 
-#: builtin/submodule--helper.c:1204
+#: builtin/submodule--helper.c:1217
 msgid "name of the new submodule"
 msgstr "新子模组的名称"
 
-#: builtin/submodule--helper.c:1207
+#: builtin/submodule--helper.c:1220
 msgid "url where to clone the submodule from"
 msgstr "克隆子模组的 url 地址"
 
-#: builtin/submodule--helper.c:1213
+#: builtin/submodule--helper.c:1228
 msgid "depth for shallow clones"
 msgstr "浅克隆的深度"
 
-#: builtin/submodule--helper.c:1216 builtin/submodule--helper.c:1587
+#: builtin/submodule--helper.c:1231 builtin/submodule--helper.c:1606
 msgid "force cloning progress"
 msgstr "强制显示克隆进度"
 
-#: builtin/submodule--helper.c:1221
+#: builtin/submodule--helper.c:1236
 msgid ""
 "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference "
 "<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>"
@@ -13745,102 +14259,102 @@ msgstr ""
 "git submodule--helper clone [--prefix=<路径>] [--quiet] [--reference <仓库>] "
 "[--name <名字>] [--depth <深度>] --url <url> --path <路径>"
 
-#: builtin/submodule--helper.c:1252
+#: builtin/submodule--helper.c:1267
 #, c-format
 msgid "clone of '%s' into submodule path '%s' failed"
 msgstr "无法克隆 '%s' 到子模组路径 '%s'"
 
-#: builtin/submodule--helper.c:1267
+#: builtin/submodule--helper.c:1281
 #, c-format
 msgid "could not get submodule directory for '%s'"
 msgstr "无法得到 '%s' 的子模组目录"
 
-#: builtin/submodule--helper.c:1332
+#: builtin/submodule--helper.c:1347
 #, c-format
 msgid "Submodule path '%s' not initialized"
 msgstr "子模组 '%s' 尚未初始化"
 
-#: builtin/submodule--helper.c:1336
+#: builtin/submodule--helper.c:1351
 msgid "Maybe you want to use 'update --init'?"
 msgstr "也许您想要执行 'update --init'?"
 
-#: builtin/submodule--helper.c:1365
+#: builtin/submodule--helper.c:1380
 #, c-format
 msgid "Skipping unmerged submodule %s"
 msgstr "略过未合并的子模组 %s"
 
-#: builtin/submodule--helper.c:1394
+#: builtin/submodule--helper.c:1409
 #, c-format
 msgid "Skipping submodule '%s'"
 msgstr "略过子模组 '%s'"
 
-#: builtin/submodule--helper.c:1527
+#: builtin/submodule--helper.c:1544
 #, c-format
 msgid "Failed to clone '%s'. Retry scheduled"
 msgstr "克隆 '%s' 失败。按计划重试"
 
-#: builtin/submodule--helper.c:1538
+#: builtin/submodule--helper.c:1555
 #, c-format
 msgid "Failed to clone '%s' a second time, aborting"
 msgstr "第二次尝试克隆 '%s' 失败,退出"
 
-#: builtin/submodule--helper.c:1568 builtin/submodule--helper.c:1788
+#: builtin/submodule--helper.c:1585 builtin/submodule--helper.c:1808
 msgid "path into the working tree"
 msgstr "到工作区的路径"
 
-#: builtin/submodule--helper.c:1571
+#: builtin/submodule--helper.c:1588
 msgid "path into the working tree, across nested submodule boundaries"
 msgstr "工作区中的路径,递归嵌套子模组"
 
-#: builtin/submodule--helper.c:1575
+#: builtin/submodule--helper.c:1592
 msgid "rebase, merge, checkout or none"
 msgstr "rebase、merge、checkout 或 none"
 
-#: builtin/submodule--helper.c:1579
+#: builtin/submodule--helper.c:1598
 msgid "Create a shallow clone truncated to the specified number of revisions"
 msgstr "创建一个指定深度的浅克隆"
 
-#: builtin/submodule--helper.c:1582
+#: builtin/submodule--helper.c:1601
 msgid "parallel jobs"
 msgstr "并发任务"
 
-#: builtin/submodule--helper.c:1584
+#: builtin/submodule--helper.c:1603
 msgid "whether the initial clone should follow the shallow recommendation"
 msgstr "初始克隆是否应该遵守推荐的浅克隆选项"
 
-#: builtin/submodule--helper.c:1585
+#: builtin/submodule--helper.c:1604
 msgid "don't print cloning progress"
 msgstr "不要输出克隆进度"
 
-#: builtin/submodule--helper.c:1592
+#: builtin/submodule--helper.c:1611
 msgid "git submodule--helper update_clone [--prefix=<path>] [<path>...]"
 msgstr "git submodule--helper update_clone [--prefix=<路径>] [<路径>...]"
 
-#: builtin/submodule--helper.c:1605
+#: builtin/submodule--helper.c:1624
 msgid "bad value for update parameter"
 msgstr "update 参数取值错误"
 
-#: builtin/submodule--helper.c:1673
+#: builtin/submodule--helper.c:1692
 #, c-format
 msgid ""
 "Submodule (%s) branch configured to inherit branch from superproject, but "
 "the superproject is not on any branch"
 msgstr "子模组(%s)的分支配置为继承上级项目的分支,但是上级项目不在任何分支上"
 
-#: builtin/submodule--helper.c:1789
+#: builtin/submodule--helper.c:1809
 msgid "recurse into submodules"
 msgstr "在子模组中递归"
 
-#: builtin/submodule--helper.c:1795
+#: builtin/submodule--helper.c:1815
 msgid "git submodule--helper embed-git-dir [<path>...]"
 msgstr "git submodule--helper embed-git-dir [<路径>...]"
 
-#: builtin/submodule--helper.c:1857
+#: builtin/submodule--helper.c:1901
 #, c-format
 msgid "%s doesn't support --super-prefix"
 msgstr "%s 不支持 --super-prefix"
 
-#: builtin/submodule--helper.c:1863
+#: builtin/submodule--helper.c:1907
 #, c-format
 msgid "'%s' is not a valid submodule--helper subcommand"
 msgstr "'%s' 不是一个有效的 submodule--helper 子命令"
@@ -13908,7 +14422,7 @@ msgstr "未发现标签 '%s'。"
 msgid "Deleted tag '%s' (was %s)\n"
 msgstr "已删除标签 '%s'(曾为 %s)\n"
 
-#: builtin/tag.c:131
+#: builtin/tag.c:132
 #, c-format
 msgid ""
 "\n"
@@ -13921,7 +14435,7 @@ msgstr ""
 "  %s\n"
 "以 '%c' 开头的行将被忽略。\n"
 
-#: builtin/tag.c:135
+#: builtin/tag.c:136
 #, c-format
 msgid ""
 "\n"
@@ -13935,146 +14449,146 @@ msgstr ""
 "  %s\n"
 "以 '%c' 开头的行将被保留,如果您愿意也可以删除它们。\n"
 
-#: builtin/tag.c:189
+#: builtin/tag.c:190
 msgid "unable to sign the tag"
 msgstr "无法签署标签"
 
-#: builtin/tag.c:191
+#: builtin/tag.c:192
 msgid "unable to write tag file"
 msgstr "无法写标签文件"
 
-#: builtin/tag.c:216
+#: builtin/tag.c:217
 msgid "bad object type."
 msgstr "坏的对象类型。"
 
-#: builtin/tag.c:265
+#: builtin/tag.c:266
 msgid "no tag message?"
 msgstr "无标签说明?"
 
-#: builtin/tag.c:272
+#: builtin/tag.c:273
 #, c-format
 msgid "The tag message has been left in %s\n"
 msgstr "标签说明被保留在 %s\n"
 
-#: builtin/tag.c:381
+#: builtin/tag.c:382
 msgid "list tag names"
 msgstr "列出标签名称"
 
-#: builtin/tag.c:383
+#: builtin/tag.c:384
 msgid "print <n> lines of each tag message"
 msgstr "每个标签信息打印 <n> 行"
 
-#: builtin/tag.c:385
+#: builtin/tag.c:386
 msgid "delete tags"
 msgstr "删除标签"
 
-#: builtin/tag.c:386
+#: builtin/tag.c:387
 msgid "verify tags"
 msgstr "验证标签"
 
-#: builtin/tag.c:388
+#: builtin/tag.c:389
 msgid "Tag creation options"
 msgstr "标签创建选项"
 
-#: builtin/tag.c:390
+#: builtin/tag.c:391
 msgid "annotated tag, needs a message"
 msgstr "附注标签,需要一个说明"
 
-#: builtin/tag.c:392
+#: builtin/tag.c:393
 msgid "tag message"
 msgstr "标签说明"
 
-#: builtin/tag.c:394
+#: builtin/tag.c:395
 msgid "force edit of tag message"
 msgstr "强制编辑标签说明"
 
-#: builtin/tag.c:395
+#: builtin/tag.c:396
 msgid "annotated and GPG-signed tag"
 msgstr "附注并附加 GPG 签名的标签"
 
-#: builtin/tag.c:399
+#: builtin/tag.c:400
 msgid "use another key to sign the tag"
 msgstr "使用另外的私钥签名该标签"
 
-#: builtin/tag.c:400
+#: builtin/tag.c:401
 msgid "replace the tag if exists"
 msgstr "如果存在,替换现有的标签"
 
-#: builtin/tag.c:401 builtin/update-ref.c:368
+#: builtin/tag.c:402 builtin/update-ref.c:368
 msgid "create a reflog"
 msgstr "创建引用日志"
 
-#: builtin/tag.c:403
+#: builtin/tag.c:404
 msgid "Tag listing options"
 msgstr "标签列表选项"
 
-#: builtin/tag.c:404
+#: builtin/tag.c:405
 msgid "show tag list in columns"
 msgstr "以列的方式显示标签列表"
 
-#: builtin/tag.c:405 builtin/tag.c:407
+#: builtin/tag.c:406 builtin/tag.c:408
 msgid "print only tags that contain the commit"
 msgstr "只打印包含该提交的标签"
 
-#: builtin/tag.c:406 builtin/tag.c:408
+#: builtin/tag.c:407 builtin/tag.c:409
 msgid "print only tags that don't contain the commit"
 msgstr "只打印不包含该提交的标签"
 
-#: builtin/tag.c:409
+#: builtin/tag.c:410
 msgid "print only tags that are merged"
 msgstr "只打印已经合并的标签"
 
-#: builtin/tag.c:410
+#: builtin/tag.c:411
 msgid "print only tags that are not merged"
 msgstr "只打印尚未合并的标签"
 
-#: builtin/tag.c:415
+#: builtin/tag.c:416
 msgid "print only tags of the object"
 msgstr "只打印指向该对象的标签"
 
-#: builtin/tag.c:459
+#: builtin/tag.c:460
 msgid "--column and -n are incompatible"
 msgstr "--column 和 -n 不兼容"
 
-#: builtin/tag.c:481
+#: builtin/tag.c:482
 msgid "-n option is only allowed in list mode"
 msgstr "-n 选项只允许用在列表显示模式"
 
-#: builtin/tag.c:483
+#: builtin/tag.c:484
 msgid "--contains option is only allowed in list mode"
 msgstr "--contains 选项只允许用在列表显示模式"
 
-#: builtin/tag.c:485
+#: builtin/tag.c:486
 msgid "--no-contains option is only allowed in list mode"
 msgstr "--no-contains 选项只允许用在列表显示模式"
 
-#: builtin/tag.c:487
+#: builtin/tag.c:488
 msgid "--points-at option is only allowed in list mode"
 msgstr "--points-at 选项只允许用在列表显示模式"
 
-#: builtin/tag.c:489
+#: builtin/tag.c:490
 msgid "--merged and --no-merged options are only allowed in list mode"
 msgstr "--merged 和 --no-merged 选项只允许用在列表显示模式"
 
-#: builtin/tag.c:500
+#: builtin/tag.c:501
 msgid "only one -F or -m option is allowed."
 msgstr "只允许一个 -F 或 -m 选项。"
 
-#: builtin/tag.c:519
+#: builtin/tag.c:520
 msgid "too many params"
 msgstr "太多参数"
 
-#: builtin/tag.c:525
+#: builtin/tag.c:526
 #, c-format
 msgid "'%s' is not a valid tag name."
 msgstr "'%s' 不是一个有效的标签名称。"
 
-#: builtin/tag.c:530
+#: builtin/tag.c:531
 #, c-format
 msgid "tag '%s' already exists"
 msgstr "标签 '%s' 已存在"
 
-#: builtin/tag.c:561
+#: builtin/tag.c:562
 #, c-format
 msgid "Updated tag '%s' (was %s)\n"
 msgstr "已更新标签 '%s'(曾为 %s)\n"
@@ -14141,157 +14655,157 @@ msgstr "删除一个目录后,目录的状态信息未改变"
 msgid " OK"
 msgstr " OK"
 
-#: builtin/update-index.c:579
+#: builtin/update-index.c:589
 msgid "git update-index [<options>] [--] [<file>...]"
 msgstr "git update-index [<选项>] [--] [<文件>...]"
 
-#: builtin/update-index.c:936
+#: builtin/update-index.c:946
 msgid "continue refresh even when index needs update"
 msgstr "当索引需要更新时继续刷新"
 
-#: builtin/update-index.c:939
+#: builtin/update-index.c:949
 msgid "refresh: ignore submodules"
 msgstr "刷新:忽略子模组"
 
-#: builtin/update-index.c:942
+#: builtin/update-index.c:952
 msgid "do not ignore new files"
 msgstr "不忽略新的文件"
 
-#: builtin/update-index.c:944
+#: builtin/update-index.c:954
 msgid "let files replace directories and vice-versa"
 msgstr "让文件替换目录(反之亦然)"
 
-#: builtin/update-index.c:946
+#: builtin/update-index.c:956
 msgid "notice files missing from worktree"
 msgstr "通知文件从工作区丢失"
 
-#: builtin/update-index.c:948
+#: builtin/update-index.c:958
 msgid "refresh even if index contains unmerged entries"
 msgstr "即使索引区包含未合并的条目也执行刷新"
 
-#: builtin/update-index.c:951
+#: builtin/update-index.c:961
 msgid "refresh stat information"
 msgstr "刷新统计信息"
 
-#: builtin/update-index.c:955
+#: builtin/update-index.c:965
 msgid "like --refresh, but ignore assume-unchanged setting"
 msgstr "类似于 --refresh,但是忽略 assume-unchanged 设置"
 
-#: builtin/update-index.c:959
+#: builtin/update-index.c:969
 msgid "<mode>,<object>,<path>"
 msgstr "<存取模式>,<对象>,<路径>"
 
-#: builtin/update-index.c:960
+#: builtin/update-index.c:970
 msgid "add the specified entry to the index"
 msgstr "添加指定的条目到索引区"
 
-#: builtin/update-index.c:969
+#: builtin/update-index.c:979
 msgid "mark files as \"not changing\""
 msgstr "把文件标记为 \"没有变更\""
 
-#: builtin/update-index.c:972
+#: builtin/update-index.c:982
 msgid "clear assumed-unchanged bit"
 msgstr "清除 assumed-unchanged 位"
 
-#: builtin/update-index.c:975
+#: builtin/update-index.c:985
 msgid "mark files as \"index-only\""
 msgstr "把文件标记为 \"仅索引\""
 
-#: builtin/update-index.c:978
+#: builtin/update-index.c:988
 msgid "clear skip-worktree bit"
 msgstr "清除 skip-worktree 位"
 
-#: builtin/update-index.c:981
+#: builtin/update-index.c:991
 msgid "add to index only; do not add content to object database"
 msgstr "只添加到索引区;不添加对象到对象库"
 
-#: builtin/update-index.c:983
+#: builtin/update-index.c:993
 msgid "remove named paths even if present in worktree"
 msgstr "即使存在工作区里,也删除路径"
 
-#: builtin/update-index.c:985
+#: builtin/update-index.c:995
 msgid "with --stdin: input lines are terminated by null bytes"
 msgstr "携带 --stdin:输入的行以 null 字符终止"
 
-#: builtin/update-index.c:987
+#: builtin/update-index.c:997
 msgid "read list of paths to be updated from standard input"
 msgstr "从标准输入中读取需要更新的路径列表"
 
-#: builtin/update-index.c:991
+#: builtin/update-index.c:1001
 msgid "add entries from standard input to the index"
 msgstr "从标准输入添加条目到索引区"
 
-#: builtin/update-index.c:995
+#: builtin/update-index.c:1005
 msgid "repopulate stages #2 and #3 for the listed paths"
 msgstr "为指定文件重新生成第2和第3暂存区"
 
-#: builtin/update-index.c:999
+#: builtin/update-index.c:1009
 msgid "only update entries that differ from HEAD"
 msgstr "只更新与 HEAD 不同的条目"
 
-#: builtin/update-index.c:1003
+#: builtin/update-index.c:1013
 msgid "ignore files missing from worktree"
 msgstr "忽略工作区丢失的文件"
 
-#: builtin/update-index.c:1006
+#: builtin/update-index.c:1016
 msgid "report actions to standard output"
 msgstr "在标准输出显示操作"
 
-#: builtin/update-index.c:1008
+#: builtin/update-index.c:1018
 msgid "(for porcelains) forget saved unresolved conflicts"
 msgstr "(for porcelains) 忘记保存的未解决的冲突"
 
-#: builtin/update-index.c:1012
+#: builtin/update-index.c:1022
 msgid "write index in this format"
 msgstr "以这种格式写入索引区"
 
-#: builtin/update-index.c:1014
+#: builtin/update-index.c:1024
 msgid "enable or disable split index"
 msgstr "启用或禁用索引拆分"
 
-#: builtin/update-index.c:1016
+#: builtin/update-index.c:1026
 msgid "enable/disable untracked cache"
 msgstr "启用/禁用对未跟踪文件的缓存"
 
-#: builtin/update-index.c:1018
+#: builtin/update-index.c:1028
 msgid "test if the filesystem supports untracked cache"
 msgstr "测试文件系统是否支持未跟踪文件缓存"
 
-#: builtin/update-index.c:1020
+#: builtin/update-index.c:1030
 msgid "enable untracked cache without testing the filesystem"
 msgstr "无需检测文件系统,启用对未跟踪文件的缓存"
 
-#: builtin/update-index.c:1022
+#: builtin/update-index.c:1032
 msgid "write out the index even if is not flagged as changed"
 msgstr "即使没有被标记为已更改,也要写出索引"
 
-#: builtin/update-index.c:1024
+#: builtin/update-index.c:1034
 msgid "enable or disable file system monitor"
 msgstr "启用或禁用文件系统监控"
 
-#: builtin/update-index.c:1026
+#: builtin/update-index.c:1036
 msgid "mark files as fsmonitor valid"
 msgstr "标记文件为 fsmonitor 有效"
 
-#: builtin/update-index.c:1029
+#: builtin/update-index.c:1039
 msgid "clear fsmonitor valid bit"
 msgstr "清除 fsmonitor 有效位"
 
-#: builtin/update-index.c:1127
+#: builtin/update-index.c:1138
 msgid ""
 "core.splitIndex is set to false; remove or change it, if you really want to "
 "enable split index"
 msgstr ""
 "core.splitIndex 被设置为 false。如果您确实要启用索引拆分,请删除或修改它。"
 
-#: builtin/update-index.c:1136
+#: builtin/update-index.c:1147
 msgid ""
 "core.splitIndex is set to true; remove or change it, if you really want to "
 "disable split index"
 msgstr ""
 "core.splitIndex 被设置为 true。如果您确实要禁用索引拆分,请删除或修改它。"
 
-#: builtin/update-index.c:1147
+#: builtin/update-index.c:1158
 msgid ""
 "core.untrackedCache is set to true; remove or change it, if you really want "
 "to disable the untracked cache"
@@ -14299,11 +14813,11 @@ msgstr ""
 "core.untrackedCache 被设置为 true。如果您确实要禁用未跟踪文件缓存,请删除或修"
 "改它。"
 
-#: builtin/update-index.c:1151
+#: builtin/update-index.c:1162
 msgid "Untracked cache disabled"
 msgstr "缓存未跟踪文件被禁用"
 
-#: builtin/update-index.c:1159
+#: builtin/update-index.c:1170
 msgid ""
 "core.untrackedCache is set to false; remove or change it, if you really want "
 "to enable the untracked cache"
@@ -14311,25 +14825,25 @@ msgstr ""
 "core.untrackedCache 被设置为 false。如果您确实要启用未跟踪文件缓存,请删除或"
 "修改它。"
 
-#: builtin/update-index.c:1163
+#: builtin/update-index.c:1174
 #, c-format
 msgid "Untracked cache enabled for '%s'"
 msgstr "缓存未跟踪文件在 '%s' 启用"
 
-#: builtin/update-index.c:1171
+#: builtin/update-index.c:1182
 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor"
 msgstr "core.fsmonitor 未设置;如果想要启用 fsmonitor 请设置该选项"
 
-#: builtin/update-index.c:1175
+#: builtin/update-index.c:1186
 msgid "fsmonitor enabled"
 msgstr "fsmonitor 被启用"
 
-#: builtin/update-index.c:1178
+#: builtin/update-index.c:1189
 msgid ""
 "core.fsmonitor is set; remove it if you really want to disable fsmonitor"
 msgstr "core.fsmonitor 已设置;如果想要禁用 fsmonitor 请移除该选项"
 
-#: builtin/update-index.c:1182
+#: builtin/update-index.c:1193
 msgid "fsmonitor disabled"
 msgstr "fsmonitor 被禁用"
 
@@ -14369,6 +14883,22 @@ msgstr "git update-server-info [--force]"
 msgid "update the info files from scratch"
 msgstr "从头开始更新文件信息"
 
+#: builtin/upload-pack.c:11
+msgid "git upload-pack [<options>] <dir>"
+msgstr "git upload-pack [<选项>] <目录>"
+
+#: builtin/upload-pack.c:25
+msgid "exit immediately after initial ref advertisement"
+msgstr "在初始的引用广告后立即退出"
+
+#: builtin/upload-pack.c:27
+msgid "do not try <directory>/.git/ if <directory> is no Git directory"
+msgstr "如果 <目录> 不是一个 Git 目录,不要尝试 <目录>/.git/"
+
+#: builtin/upload-pack.c:29
+msgid "interrupt transfer after <n> seconds of inactivity"
+msgstr "不活动 <n> 秒钟后终止传输"
+
 #: builtin/verify-commit.c:18
 msgid "git verify-commit [-v | --verbose] <commit>..."
 msgstr "git verify-commit [-v | --verbose] <提交>..."
@@ -14429,198 +14959,213 @@ msgstr "git worktree remove [<选项>] <工作区>"
 msgid "git worktree unlock <path>"
 msgstr "git worktree unlock <路径>"
 
-#: builtin/worktree.c:60
+#: builtin/worktree.c:58
 #, c-format
 msgid "Removing worktrees/%s: not a valid directory"
 msgstr "删除工作区/%s:不是一个有效的目录"
 
-#: builtin/worktree.c:66
+#: builtin/worktree.c:64
 #, c-format
 msgid "Removing worktrees/%s: gitdir file does not exist"
 msgstr "删除 worktrees/%s:gitdir 文件不存在"
 
-#: builtin/worktree.c:71 builtin/worktree.c:80
+#: builtin/worktree.c:69 builtin/worktree.c:78
 #, c-format
 msgid "Removing worktrees/%s: unable to read gitdir file (%s)"
 msgstr "删除 worktrees/%s:无法读取 gitdir 文件 (%s)"
 
-#: builtin/worktree.c:90
+#: builtin/worktree.c:88
 #, c-format
 msgid ""
 "Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read "
 "%<PRIuMAX>)"
 msgstr "删除工作树/%s:读取过短(期望 %<PRIuMAX> 字节,读取 %<PRIuMAX>)"
 
-#: builtin/worktree.c:98
+#: builtin/worktree.c:96
 #, c-format
 msgid "Removing worktrees/%s: invalid gitdir file"
 msgstr "删除 worktrees/%s:无效的 gitdir 文件"
 
-#: builtin/worktree.c:114
+#: builtin/worktree.c:105
 #, c-format
 msgid "Removing worktrees/%s: gitdir file points to non-existent location"
 msgstr "删除 worktrees/%s:gitdir 文件的指向不存在"
 
-#: builtin/worktree.c:161
+#: builtin/worktree.c:152
 msgid "report pruned working trees"
 msgstr "报告清除的工作区"
 
-#: builtin/worktree.c:163
+#: builtin/worktree.c:154
 msgid "expire working trees older than <time>"
 msgstr "将早于 <时间> 的工作区过期"
 
-#: builtin/worktree.c:238
+#: builtin/worktree.c:229
 #, c-format
 msgid "'%s' already exists"
 msgstr "'%s' 已经存在"
 
-#: builtin/worktree.c:269
+#: builtin/worktree.c:260
 #, c-format
 msgid "could not create directory of '%s'"
 msgstr "不能创建目录 '%s'"
 
-#: builtin/worktree.c:308
+#: builtin/worktree.c:373 builtin/worktree.c:379
+#, c-format
+msgid "Preparing worktree (new branch '%s')"
+msgstr "准备工作区(新分支 '%s')"
+
+#: builtin/worktree.c:375
+#, c-format
+msgid "Preparing worktree (resetting branch '%s'; was at %s)"
+msgstr "准备工作区(重置分支 '%s',之前为 %s)"
+
+#: builtin/worktree.c:384
+#, c-format
+msgid "Preparing worktree (checking out '%s')"
+msgstr "准备工作区(检出 '%s')"
+
+#: builtin/worktree.c:390
 #, c-format
-msgid "Preparing %s (identifier %s)"
-msgstr "准备 %s(标识符 %s)"
+msgid "Preparing worktree (detached HEAD %s)"
+msgstr "准备工作区(分离头指针 %s)"
 
-#: builtin/worktree.c:385
+#: builtin/worktree.c:431
 msgid "checkout <branch> even if already checked out in other worktree"
 msgstr "检出 <分支>,即使已经被检出到其它工作区"
 
-#: builtin/worktree.c:388
+#: builtin/worktree.c:434
 msgid "create a new branch"
 msgstr "创建一个新分支"
 
-#: builtin/worktree.c:390
+#: builtin/worktree.c:436
 msgid "create or reset a branch"
 msgstr "创建或重置一个分支"
 
-#: builtin/worktree.c:392
+#: builtin/worktree.c:438
 msgid "populate the new working tree"
 msgstr "生成新的工作区"
 
-#: builtin/worktree.c:393
+#: builtin/worktree.c:439
 msgid "keep the new working tree locked"
 msgstr "锁定新工作区"
 
-#: builtin/worktree.c:395
+#: builtin/worktree.c:441
 msgid "set up tracking mode (see git-branch(1))"
 msgstr "设置跟踪模式(参见 git-branch(1))"
 
-#: builtin/worktree.c:398
+#: builtin/worktree.c:444
 msgid "try to match the new branch name with a remote-tracking branch"
 msgstr "尝试为新分支名匹配一个远程跟踪分支"
 
-#: builtin/worktree.c:406
+#: builtin/worktree.c:452
 msgid "-b, -B, and --detach are mutually exclusive"
 msgstr "-b、-B 和 --detach 是互斥的"
 
-#: builtin/worktree.c:471
+#: builtin/worktree.c:511
 msgid "--[no-]track can only be used if a new branch is created"
 msgstr "只能在创建新分支时使用选项 --[no-]track "
 
-#: builtin/worktree.c:571
+#: builtin/worktree.c:611
 msgid "reason for locking"
 msgstr "锁定原因"
 
-#: builtin/worktree.c:583 builtin/worktree.c:616 builtin/worktree.c:670
-#: builtin/worktree.c:809
+#: builtin/worktree.c:623 builtin/worktree.c:656 builtin/worktree.c:710
+#: builtin/worktree.c:850
 #, c-format
 msgid "'%s' is not a working tree"
 msgstr "'%s' 不是一个工作区"
 
-#: builtin/worktree.c:585 builtin/worktree.c:618
+#: builtin/worktree.c:625 builtin/worktree.c:658
 msgid "The main working tree cannot be locked or unlocked"
 msgstr "主工作区无法被加锁或解锁"
 
-#: builtin/worktree.c:590
+#: builtin/worktree.c:630
 #, c-format
 msgid "'%s' is already locked, reason: %s"
 msgstr "'%s' 已被锁定,原因:%s"
 
-#: builtin/worktree.c:592
+#: builtin/worktree.c:632
 #, c-format
 msgid "'%s' is already locked"
 msgstr "'%s' 已被锁定"
 
-#: builtin/worktree.c:620
+#: builtin/worktree.c:660
 #, c-format
 msgid "'%s' is not locked"
 msgstr "'%s' 未被锁定"
 
-#: builtin/worktree.c:645
+#: builtin/worktree.c:685
 msgid "working trees containing submodules cannot be moved or removed"
 msgstr "不能移动或删除包含子模组的工作区"
 
-#: builtin/worktree.c:672 builtin/worktree.c:811
+#: builtin/worktree.c:712 builtin/worktree.c:852
 #, c-format
 msgid "'%s' is a main working tree"
 msgstr "'%s' 是一个主工作区"
 
-#: builtin/worktree.c:677
+#: builtin/worktree.c:717
 #, c-format
 msgid "could not figure out destination name from '%s'"
 msgstr "无法从 '%s' 算出目标名称"
 
-#: builtin/worktree.c:683
+#: builtin/worktree.c:723
 #, c-format
 msgid "target '%s' already exists"
 msgstr "目标 '%s' 已存在"
 
-#: builtin/worktree.c:690
+#: builtin/worktree.c:730
 #, c-format
 msgid "cannot move a locked working tree, lock reason: %s"
 msgstr "无法移动一个锁定的工作区,锁定原因:%s"
 
-#: builtin/worktree.c:692
+#: builtin/worktree.c:732
 msgid "cannot move a locked working tree"
 msgstr "无法移动一个锁定的工作区"
 
-#: builtin/worktree.c:695
+#: builtin/worktree.c:735
 #, c-format
 msgid "validation failed, cannot move working tree: %s"
 msgstr "验证失败,无法移动工作区:%s"
 
-#: builtin/worktree.c:700
+#: builtin/worktree.c:740
 #, c-format
 msgid "failed to move '%s' to '%s'"
 msgstr "无法移动 '%s' 到 '%s'"
 
-#: builtin/worktree.c:748
+#: builtin/worktree.c:788
 #, c-format
 msgid "failed to run 'git status' on '%s'"
 msgstr "无法在 '%s' 中执行 'git status'"
 
-#: builtin/worktree.c:752
+#: builtin/worktree.c:792
 #, c-format
 msgid "'%s' is dirty, use --force to delete it"
 msgstr "'%s' 是脏的,使用 --force 删除"
 
-#: builtin/worktree.c:757
+#: builtin/worktree.c:797
 #, c-format
 msgid "failed to run 'git status' on '%s', code %d"
 msgstr "无法在 '%s' 中执行 'git status',退出码 %d"
 
-#: builtin/worktree.c:768 builtin/worktree.c:782
+#: builtin/worktree.c:808 builtin/worktree.c:822
 #, c-format
 msgid "failed to delete '%s'"
 msgstr "无法删除 '%s'"
 
-#: builtin/worktree.c:794
+#: builtin/worktree.c:834
 msgid "force removing even if the worktree is dirty"
 msgstr "强制删除,即使工作区是脏的"
 
-#: builtin/worktree.c:815
+#: builtin/worktree.c:856
 #, c-format
 msgid "cannot remove a locked working tree, lock reason: %s"
 msgstr "无法删除一个锁定的工作区,锁定原因:%s"
 
-#: builtin/worktree.c:817
+#: builtin/worktree.c:858
 msgid "cannot remove a locked working tree"
 msgstr "无法删除一个锁定的工作区"
 
-#: builtin/worktree.c:820
+#: builtin/worktree.c:861
 #, c-format
 msgid "validation failed, cannot remove working tree: %s"
 msgstr "验证失败,无法删除工作区:%s"
@@ -14641,26 +15186,6 @@ msgstr "将 <前缀> 子目录内容写到一个树对象"
 msgid "only useful for debugging"
 msgstr "只对调试有用"
 
-#: upload-pack.c:27
-msgid "git upload-pack [<options>] <dir>"
-msgstr "git upload-pack [<选项>] <目录>"
-
-#: upload-pack.c:1070
-msgid "quit after a single request/response exchange"
-msgstr "在一次单独的请求/响应(request/response)交换后退出"
-
-#: upload-pack.c:1072
-msgid "exit immediately after initial ref advertisement"
-msgstr "在初始的引用广告后立即退出"
-
-#: upload-pack.c:1074
-msgid "do not try <directory>/.git/ if <directory> is no Git directory"
-msgstr "如果 <目录> 不是一个 Git 目录,不要尝试 <目录>/.git/"
-
-#: upload-pack.c:1076
-msgid "interrupt transfer after <n> seconds of inactivity"
-msgstr "不活动 <n> 秒钟后终止传输"
-
 #: credential-cache--daemon.c:222
 #, c-format
 msgid ""
@@ -14678,21 +15203,23 @@ msgstr ""
 msgid "print debugging messages to stderr"
 msgstr "调试信息输出到标准错误"
 
-#: git.c:8
+#: git.c:27
 msgid ""
 "git [--version] [--help] [-C <path>] [-c <name>=<value>]\n"
 "           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n"
 "           <command> [<args>]"
 msgstr ""
-"git [--version] [--help] [-C <path>] [-c <键名>=<值>]\n"
+"git [--version] [--help] [-C <路径>] [-c <名称>=<取值>]\n"
 "           [--exec-path[=<路径>]] [--html-path] [--man-path] [--info-path]\n"
-"           [-p | --paginate | --no-pager] [--no-replace-objects] [--bare]\n"
+"           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--"
+"bare]\n"
 "           [--git-dir=<路径>] [--work-tree=<路径>] [--namespace=<名称>]\n"
 "           <命令> [<参数>]"
 
-#: git.c:15
+#: git.c:34
 msgid ""
 "'git help -a' and 'git help -g' list available subcommands and some\n"
 "concept guides. See 'git help <command>' or 'git help <concept>'\n"
@@ -14702,65 +15229,65 @@ msgstr ""
 "查看 'git help <命令>' 或 'git help <概念>' 以获取给定子命令或概念的\n"
 "帮助。"
 
-#: git.c:95
+#: git.c:173
 #, c-format
 msgid "no directory given for --git-dir\n"
 msgstr "没有为 --git-dir 提供目录\n"
 
-#: git.c:109
+#: git.c:187
 #, c-format
 msgid "no namespace given for --namespace\n"
 msgstr "没有为 --namespace 提供命名空间\n"
 
-#: git.c:123
+#: git.c:201
 #, c-format
 msgid "no directory given for --work-tree\n"
 msgstr "没有为 --work-tree 提供目录\n"
 
-#: git.c:137
+#: git.c:215
 #, c-format
 msgid "no prefix given for --super-prefix\n"
 msgstr "没有为 --super-prefix 提供前缀\n"
 
-#: git.c:159
+#: git.c:237
 #, c-format
 msgid "-c expects a configuration string\n"
 msgstr "应为 -c 提供一个配置字符串\n"
 
-#: git.c:197
+#: git.c:275
 #, c-format
 msgid "no directory given for -C\n"
 msgstr "没有为 -C 提供目录\n"
 
-#: git.c:212
+#: git.c:300
 #, c-format
 msgid "unknown option: %s\n"
 msgstr "未知选项:%s\n"
 
-#: git.c:687
+#: git.c:765
 #, c-format
 msgid "expansion of alias '%s' failed; '%s' is not a git command\n"
 msgstr "展开别名命令 '%s' 失败,'%s' 不是一个 git 命令\n"
 
-#: git.c:699
+#: git.c:777
 #, c-format
 msgid "failed to run command '%s': %s\n"
 msgstr "无法运行命令 '%s':%s\n"
 
-#: http.c:342
+#: http.c:348
 #, c-format
 msgid "negative value for http.postbuffer; defaulting to %d"
 msgstr "http.postbuffer 为负值,默认为 %d"
 
-#: http.c:363
+#: http.c:369
 msgid "Delegation control is not supported with cURL < 7.22.0"
 msgstr "当 cURL < 7.22.0 时,不支持委托控制"
 
-#: http.c:372
+#: http.c:378
 msgid "Public key pinning not supported with cURL < 7.44.0"
 msgstr "不支持公钥文件锁定,因为 cURL < 7.44.0"
 
-#: http.c:1857
+#: http.c:1854
 #, c-format
 msgid ""
 "unable to update url base from redirection:\n"
@@ -14771,7 +15298,7 @@ msgstr ""
 "     请求:%s\n"
 "   重定向:%s"
 
-#: remote-curl.c:345
+#: remote-curl.c:401
 #, c-format
 msgid "redirecting to %s"
 msgstr "重定向到 %s"
@@ -14784,129 +15311,654 @@ msgstr "参数"
 msgid "object filtering"
 msgstr "对象过滤"
 
-#: common-cmds.h:9
-msgid "start a working area (see also: git help tutorial)"
-msgstr "å¼\80å§\8bä¸\80个工ä½\9cå\8cºï¼\88å\8f\82è§\81ï¼\9agit help tutorialï¼\89"
+#: parse-options.h:157
+msgid "expiry-date"
+msgstr "å\88°æ\9c\9fæ\97¶é\97´"
 
-#: common-cmds.h:10
-msgid "work on the current change (see also: git help everyday)"
-msgstr "在当前变更上工作(参见:git help everyday)"
+#: parse-options.h:172
+msgid "no-op (backward compatibility)"
+msgstr "空操作(向后兼容)"
 
-#: common-cmds.h:11
-msgid "examine the history and state (see also: git help revisions)"
-msgstr "æ£\80æ\9f¥å\8e\86å\8f²å\92\8cç\8a¶æ\80\81ï¼\88å\8f\82è§\81ï¼\9agit help revisionsï¼\89"
+#: parse-options.h:251
+msgid "be more verbose"
+msgstr "æ\9b´å\8a è¯¦ç»\86"
 
-#: common-cmds.h:12
-msgid "grow, mark and tweak your common history"
-msgstr "æ\89©å±\95ã\80\81æ \87è®°å\92\8cè°\83æ ¡æ\82¨ç\9a\84å\8e\86å\8f²è®°å½\95"
+#: parse-options.h:253
+msgid "be more quiet"
+msgstr "æ\9b´å\8a å®\89é\9d\99"
 
-#: common-cmds.h:13
-msgid "collaborate (see also: git help workflows)"
-msgstr "协同(参见:git help workflows)"
+#: parse-options.h:259
+msgid "use <n> digits to display SHA-1s"
+msgstr "用 <n> 位数字显示 SHA-1 哈希值"
 
-#: common-cmds.h:17
+#: command-list.h:50
 msgid "Add file contents to the index"
 msgstr "添加文件内容至索引"
 
-#: common-cmds.h:18
+#: command-list.h:51
+msgid "Apply a series of patches from a mailbox"
+msgstr "应用邮箱格式的系列补丁"
+
+#: command-list.h:52
+msgid "Annotate file lines with commit information"
+msgstr "使用提交信息注释文件行"
+
+#: command-list.h:53
+msgid "Apply a patch to files and/or to the index"
+msgstr "应用一个补丁到文件和/或索引区"
+
+#: command-list.h:54
+msgid "Import an Arch repository into Git"
+msgstr "将一个 Arch 仓库导入到 Git"
+
+#: command-list.h:55
+msgid "Create an archive of files from a named tree"
+msgstr "基于一个指定的树创建文件存档"
+
+#: command-list.h:56
 msgid "Use binary search to find the commit that introduced a bug"
 msgstr "通过二分查找定位引入 bug 的提交"
 
-#: common-cmds.h:19
+#: command-list.h:57
+msgid "Show what revision and author last modified each line of a file"
+msgstr "显示文件每一行最后修改的版本和修改者"
+
+#: command-list.h:58
 msgid "List, create, or delete branches"
 msgstr "列出、创建或删除分支"
 
-#: common-cmds.h:20
+#: command-list.h:59
+msgid "Move objects and refs by archive"
+msgstr "通过归档移动对象和引用"
+
+#: command-list.h:60
+msgid "Provide content or type and size information for repository objects"
+msgstr "提供仓库对象的内容、类型或大小"
+
+#: command-list.h:61
+msgid "Display gitattributes information"
+msgstr "显示 gitattributes 信息"
+
+#: command-list.h:62
+msgid "Debug gitignore / exclude files"
+msgstr "调试 gitignore / exclude 文件"
+
+#: command-list.h:63
+msgid "Show canonical names and email addresses of contacts"
+msgstr "显示联系人的规范名称和电子邮件"
+
+#: command-list.h:64
 msgid "Switch branches or restore working tree files"
 msgstr "切换分支或恢复工作区文件"
 
-#: common-cmds.h:21
+#: command-list.h:65
+msgid "Copy files from the index to the working tree"
+msgstr "从索引拷贝文件到工作区"
+
+#: command-list.h:66
+msgid "Ensures that a reference name is well formed"
+msgstr "确保引用名称格式正确"
+
+#: command-list.h:67
+msgid "Find commits yet to be applied to upstream"
+msgstr "查找尚未应用到上游的提交"
+
+#: command-list.h:68
+msgid "Apply the changes introduced by some existing commits"
+msgstr "应用一些现存提交引入的修改"
+
+#: command-list.h:69
+msgid "Graphical alternative to git-commit"
+msgstr "git-commit 的图形替代界面"
+
+#: command-list.h:70
+msgid "Remove untracked files from the working tree"
+msgstr "从工作区中删除未跟踪文件"
+
+#: command-list.h:71
 msgid "Clone a repository into a new directory"
 msgstr "克隆一个仓库到一个新目录"
 
-#: common-cmds.h:22
+#: command-list.h:72
+msgid "Display data in columns"
+msgstr "以列的方式显示数据"
+
+#: command-list.h:73
 msgid "Record changes to the repository"
 msgstr "记录变更到仓库"
 
-#: common-cmds.h:23
+#: command-list.h:74
+msgid "Write and verify Git commit graph files"
+msgstr "写入和校验 Git 提交图形文件"
+
+#: command-list.h:75
+msgid "Create a new commit object"
+msgstr "创建一个新的提交对象"
+
+#: command-list.h:76
+msgid "Get and set repository or global options"
+msgstr "获取和设置仓库或者全局选项"
+
+#: command-list.h:77
+msgid "Count unpacked number of objects and their disk consumption"
+msgstr "计算未打包对象的数量和磁盘空间占用"
+
+#: command-list.h:78
+msgid "Retrieve and store user credentials"
+msgstr "检索和存储用户密码"
+
+#: command-list.h:79
+msgid "Helper to temporarily store passwords in memory"
+msgstr "在内存中临时存储密码的助手"
+
+#: command-list.h:80
+msgid "Helper to store credentials on disk"
+msgstr "在磁盘存储密码的助手"
+
+#: command-list.h:81
+msgid "Export a single commit to a CVS checkout"
+msgstr "将一个提交导出到 CVS 检出中"
+
+#: command-list.h:82
+msgid "Salvage your data out of another SCM people love to hate"
+msgstr "从另外一个人们爱恨的配置管理系统中拯救你的数据"
+
+#: command-list.h:83
+msgid "A CVS server emulator for Git"
+msgstr "Git 的一个 CVS 服务模拟器"
+
+#: command-list.h:84
+msgid "A really simple server for Git repositories"
+msgstr "一个非常简单的 Git 仓库服务器"
+
+#: command-list.h:85
+msgid "Give an object a human readable name based on an available ref"
+msgstr "基于一个现存的引用为一个对象起一个可读的名称"
+
+#: command-list.h:86
 msgid "Show changes between commits, commit and working tree, etc"
 msgstr "显示提交之间、提交和工作区之间等的差异"
 
-#: common-cmds.h:24
+#: command-list.h:87
+msgid "Compares files in the working tree and the index"
+msgstr "比较工作区和索引区中的文件"
+
+#: command-list.h:88
+msgid "Compare a tree to the working tree or index"
+msgstr "将一个树和工作区或索引做比较"
+
+#: command-list.h:89
+msgid "Compares the content and mode of blobs found via two tree objects"
+msgstr "比较两个树对象的文件内容和模式"
+
+#: command-list.h:90
+msgid "Show changes using common diff tools"
+msgstr "使用常见的差异工具显示更改"
+
+#: command-list.h:91
+msgid "Git data exporter"
+msgstr "Git 数据导出器"
+
+#: command-list.h:92
+msgid "Backend for fast Git data importers"
+msgstr "Git 快速数据导入器后端"
+
+#: command-list.h:93
 msgid "Download objects and refs from another repository"
 msgstr "从另外一个仓库下载对象和引用"
 
-#: common-cmds.h:25
+#: command-list.h:94
+msgid "Receive missing objects from another repository"
+msgstr "从另一个仓库获取缺失的对象"
+
+#: command-list.h:95
+msgid "Rewrite branches"
+msgstr "重写分支"
+
+#: command-list.h:96
+msgid "Produce a merge commit message"
+msgstr "生成一个合并提交信息"
+
+#: command-list.h:97
+msgid "Output information on each ref"
+msgstr "对每一个引用输出信息 "
+
+#: command-list.h:98
+msgid "Prepare patches for e-mail submission"
+msgstr "准备电子邮件提交的补丁"
+
+#: command-list.h:99
+msgid "Verifies the connectivity and validity of the objects in the database"
+msgstr "验证仓库中对象的连通性和有效性"
+
+#: command-list.h:100
+msgid "Cleanup unnecessary files and optimize the local repository"
+msgstr "清除不必要的文件和优化本地仓库"
+
+#: command-list.h:101
+msgid "Extract commit ID from an archive created using git-archive"
+msgstr "从 git-archive 创建的归档文件中提取提交ID"
+
+#: command-list.h:102
 msgid "Print lines matching a pattern"
 msgstr "输出和模式匹配的行"
 
-#: common-cmds.h:26
+#: command-list.h:103
+msgid "A portable graphical interface to Git"
+msgstr "一个便携的 Git 图形客户端"
+
+#: command-list.h:104
+msgid "Compute object ID and optionally creates a blob from a file"
+msgstr "从一个文件计算对象ID,并可以创建 blob 数据对象"
+
+#: command-list.h:105
+msgid "Display help information about Git"
+msgstr "显示 Git 的帮助信息"
+
+#: command-list.h:106
+msgid "Server side implementation of Git over HTTP"
+msgstr "Git HTTP 协议的服务端实现"
+
+#: command-list.h:107
+msgid "Download from a remote Git repository via HTTP"
+msgstr "通过 HTTP 从远程 Git 仓库下载"
+
+#: command-list.h:108
+msgid "Push objects over HTTP/DAV to another repository"
+msgstr "通过 HTTP/DAV 推送对象另一个仓库"
+
+#: command-list.h:109
+msgid "Send a collection of patches from stdin to an IMAP folder"
+msgstr "从标准输入将一组补丁发送到IMAP文件夹"
+
+#: command-list.h:110
+msgid "Build pack index file for an existing packed archive"
+msgstr "从一个现存的包存档文件创建包索引"
+
+#: command-list.h:111
 msgid "Create an empty Git repository or reinitialize an existing one"
 msgstr "创建一个空的 Git 仓库或重新初始化一个已存在的仓库"
 
-#: common-cmds.h:27
+#: command-list.h:112
+msgid "Instantly browse your working repository in gitweb"
+msgstr "在 gitweb 中即时浏览您的工作仓库"
+
+#: command-list.h:113
+msgid "add or parse structured information in commit messages"
+msgstr "添加或解析提交说明中的结构化信息"
+
+#: command-list.h:114
+msgid "The Git repository browser"
+msgstr "Git 仓库浏览器"
+
+#: command-list.h:115
 msgid "Show commit logs"
 msgstr "显示提交日志"
 
-#: common-cmds.h:28
+#: command-list.h:116
+msgid "Show information about files in the index and the working tree"
+msgstr "显示索引和工作区中文件的信息"
+
+#: command-list.h:117
+msgid "List references in a remote repository"
+msgstr "显示一个远程仓库的引用"
+
+#: command-list.h:118
+msgid "List the contents of a tree object"
+msgstr "显示一个树对象的内容"
+
+#: command-list.h:119
+msgid "Extracts patch and authorship from a single e-mail message"
+msgstr "从单个电子邮件中提取补丁和作者身份"
+
+#: command-list.h:120
+msgid "Simple UNIX mbox splitter program"
+msgstr "简单的 UNIX mbox 邮箱切分程序"
+
+#: command-list.h:121
 msgid "Join two or more development histories together"
 msgstr "合并两个或更多开发历史"
 
-#: common-cmds.h:29
+#: command-list.h:122
+msgid "Find as good common ancestors as possible for a merge"
+msgstr "为了合并查找尽可能好的公共祖先提交"
+
+#: command-list.h:123
+msgid "Run a three-way file merge"
+msgstr "运行一个三路文件合并"
+
+#: command-list.h:124
+msgid "Run a merge for files needing merging"
+msgstr "对于需要合并的文件执行合并"
+
+#: command-list.h:125
+msgid "The standard helper program to use with git-merge-index"
+msgstr "与 git-merge-index 一起使用的标准向导程序"
+
+#: command-list.h:126
+msgid "Run merge conflict resolution tools to resolve merge conflicts"
+msgstr "运行合并冲突解决工具以解决合并冲突"
+
+#: command-list.h:127
+msgid "Show three-way merge without touching index"
+msgstr "显示三路合并而不动索引"
+
+#: command-list.h:128
+msgid "Creates a tag object"
+msgstr "创建一个标签对象"
+
+#: command-list.h:129
+msgid "Build a tree-object from ls-tree formatted text"
+msgstr "基于 ls-tree 的格式化文本创建一个树对象"
+
+#: command-list.h:130
 msgid "Move or rename a file, a directory, or a symlink"
 msgstr "移动或重命名一个文件、目录或符号链接"
 
-#: common-cmds.h:30
+# 查找给定版本的符号名称
+#: command-list.h:131
+msgid "Find symbolic names for given revs"
+msgstr "查找给定版本的符号名称"
+
+#: command-list.h:132
+msgid "Add or inspect object notes"
+msgstr "添加或检查对象注释"
+
+#: command-list.h:133
+msgid "Import from and submit to Perforce repositories"
+msgstr "导入和提交到 Perforce 仓库中"
+
+#: command-list.h:134
+msgid "Create a packed archive of objects"
+msgstr "创建对象的存档包"
+
+#: command-list.h:135
+msgid "Find redundant pack files"
+msgstr "查找冗余的包文件"
+
+#: command-list.h:136
+msgid "Pack heads and tags for efficient repository access"
+msgstr "打包头和标签以实现高效的仓库访问"
+
+#: command-list.h:137
+msgid "Routines to help parsing remote repository access parameters"
+msgstr "帮助解析远程仓库访问参数的例程"
+
+#: command-list.h:138
+msgid "Compute unique ID for a patch"
+msgstr "计算一个补丁的唯一ID"
+
+#: command-list.h:139
+msgid "Prune all unreachable objects from the object database"
+msgstr "删除对象库中所有不可达对象"
+
+#: command-list.h:140
+msgid "Remove extra objects that are already in pack files"
+msgstr "删除已经在包文件中的多余对象"
+
+#: command-list.h:141
 msgid "Fetch from and integrate with another repository or a local branch"
 msgstr "获取并整合另外的仓库或一个本地分支"
 
-#: common-cmds.h:31
+#: command-list.h:142
 msgid "Update remote refs along with associated objects"
 msgstr "更新远程引用和相关的对象"
 
-#: common-cmds.h:32
+#: command-list.h:143
+msgid "Applies a quilt patchset onto the current branch"
+msgstr "将一个 quilt 补丁集应用到当前分支。"
+
+#: command-list.h:144
+msgid "Reads tree information into the index"
+msgstr "将树信息读取到索引"
+
+#: command-list.h:145
 msgid "Reapply commits on top of another base tip"
 msgstr "在另一个分支上重新应用提交"
 
-#: common-cmds.h:33
+#: command-list.h:146
+msgid "Receive what is pushed into the repository"
+msgstr "接收推送到仓库中的对象"
+
+#: command-list.h:147
+msgid "Manage reflog information"
+msgstr "管理 reflog 信息"
+
+#: command-list.h:148
+msgid "Manage set of tracked repositories"
+msgstr "管理已跟踪仓库"
+
+#: command-list.h:149
+msgid "Pack unpacked objects in a repository"
+msgstr "打包仓库中未打包对象"
+
+#: command-list.h:150
+msgid "Create, list, delete refs to replace objects"
+msgstr "创建、列出、删除对象替换引用"
+
+#: command-list.h:151
+msgid "Generates a summary of pending changes"
+msgstr "生成待定更改的摘要"
+
+#: command-list.h:152
+msgid "Reuse recorded resolution of conflicted merges"
+msgstr "重用冲突合并的解决方案记录"
+
+#: command-list.h:153
 msgid "Reset current HEAD to the specified state"
 msgstr "重置当前 HEAD 到指定状态"
 
-#: common-cmds.h:34
+#: command-list.h:154
+msgid "Revert some existing commits"
+msgstr "回退一些现存提交"
+
+#: command-list.h:155
+msgid "Lists commit objects in reverse chronological order"
+msgstr "按时间顺序列出提交对象"
+
+#: command-list.h:156
+msgid "Pick out and massage parameters"
+msgstr "选出并处理参数"
+
+#: command-list.h:157
 msgid "Remove files from the working tree and from the index"
 msgstr "从工作区和索引中删除文件"
 
-#: common-cmds.h:35
+#: command-list.h:158
+msgid "Send a collection of patches as emails"
+msgstr "通过电子邮件发送一组补丁"
+
+#: command-list.h:159
+msgid "Push objects over Git protocol to another repository"
+msgstr "使用 Git 协议推送对象到另一个仓库"
+
+#: command-list.h:160
+msgid "Restricted login shell for Git-only SSH access"
+msgstr "只允许 Git SSH 访问的受限登录shell"
+
+#: command-list.h:161
+msgid "Summarize 'git log' output"
+msgstr "'git log' 输出摘要"
+
+#: command-list.h:162
 msgid "Show various types of objects"
 msgstr "显示各种类型的对象"
 
-#: common-cmds.h:36
+#: command-list.h:163
+msgid "Show branches and their commits"
+msgstr "显示分支和提交"
+
+#: command-list.h:164
+msgid "Show packed archive index"
+msgstr "显示打包归档索引"
+
+#: command-list.h:165
+msgid "List references in a local repository"
+msgstr "显示本地仓库中的引用"
+
+#: command-list.h:166
+msgid "Git's i18n setup code for shell scripts"
+msgstr "为 shell 脚本准备的 Git 国际化设置代码"
+
+#: command-list.h:167
+msgid "Common Git shell script setup code"
+msgstr "常用的 Git shell 脚本设置代码"
+
+#: command-list.h:168
+msgid "Stash the changes in a dirty working directory away"
+msgstr "贮藏脏工作区中的修改"
+
+#: command-list.h:169
+msgid "Add file contents to the staging area"
+msgstr "将文件内容添加到索引"
+
+#: command-list.h:170
 msgid "Show the working tree status"
 msgstr "显示工作区状态"
 
-#: common-cmds.h:37
+#: command-list.h:171
+msgid "Remove unnecessary whitespace"
+msgstr "删除不必要的空白字符"
+
+#: command-list.h:172
+msgid "Initialize, update or inspect submodules"
+msgstr "初始化、更新或检查子模组"
+
+#: command-list.h:173
+msgid "Bidirectional operation between a Subversion repository and Git"
+msgstr "Subersion 仓库和 Git 之间的双向操作"
+
+#: command-list.h:174
+msgid "Read, modify and delete symbolic refs"
+msgstr "读取、修改和删除符号引用"
+
+#: command-list.h:175
 msgid "Create, list, delete or verify a tag object signed with GPG"
 msgstr "创建、列出、删除或校验一个 GPG 签名的标签对象"
 
-#: parse-options.h:157
-msgid "expiry-date"
-msgstr "到期时间"
+#: command-list.h:176
+msgid "Creates a temporary file with a blob's contents"
+msgstr "用 blob 数据对象的内容创建一个临时文件"
 
-#: parse-options.h:172
-msgid "no-op (backward compatibility)"
-msgstr "空操作(向后兼容)"
+#: command-list.h:177
+msgid "Unpack objects from a packed archive"
+msgstr "从打包文件中解压缩对象"
 
-#: parse-options.h:250
-msgid "be more verbose"
-msgstr "更加详细"
+#: command-list.h:178
+msgid "Register file contents in the working tree to the index"
+msgstr "将工作区的文件内容注册到索引"
 
-#: parse-options.h:252
-msgid "be more quiet"
-msgstr "更加安静"
+#: command-list.h:179
+msgid "Update the object name stored in a ref safely"
+msgstr "安全地更新存储于引用中的对象名称"
 
-#: parse-options.h:258
-msgid "use <n> digits to display SHA-1s"
-msgstr "用 <n> 位数字显示 SHA-1 哈希值"
+#: command-list.h:180
+msgid "Update auxiliary info file to help dumb servers"
+msgstr "更新辅助信息文件以帮助哑协议服务"
+
+#: command-list.h:181
+msgid "Send archive back to git-archive"
+msgstr "将存档发送回 git-archive"
+
+#: command-list.h:182
+msgid "Send objects packed back to git-fetch-pack"
+msgstr "将对象压缩包发送回 git-fetch-pack"
+
+#: command-list.h:183
+msgid "Show a Git logical variable"
+msgstr "显示一个Git逻辑变量"
+
+#: command-list.h:184
+msgid "Check the GPG signature of commits"
+msgstr "检查 GPG 提交签名"
+
+#: command-list.h:185
+msgid "Validate packed Git archive files"
+msgstr "校验打包的Git存仓文件"
+
+#: command-list.h:186
+msgid "Check the GPG signature of tags"
+msgstr "检查标签的 GPG 签名"
+
+#: command-list.h:187
+msgid "Git web interface (web frontend to Git repositories)"
+msgstr "Git web 界面(Git 仓库的 web 前端)"
+
+#: command-list.h:188
+msgid "Show logs with difference each commit introduces"
+msgstr "显示每一个提交引入的差异日志"
+
+#: command-list.h:189
+msgid "Manage multiple working trees"
+msgstr "管理多个工作区"
+
+#: command-list.h:190
+msgid "Create a tree object from the current index"
+msgstr "从当前索引创建一个树对象"
+
+#: command-list.h:191
+msgid "Defining attributes per path"
+msgstr "定义路径的属性"
+
+#: command-list.h:192
+msgid "Git command-line interface and conventions"
+msgstr "Git 命令行界面和约定"
+
+#: command-list.h:193
+msgid "A Git core tutorial for developers"
+msgstr "面向开发人员的 Git 核心教程"
+
+#: command-list.h:194
+msgid "Git for CVS users"
+msgstr "适合 CVS 用户的 Git 帮助"
+
+#: command-list.h:195
+msgid "Tweaking diff output"
+msgstr "调整差异输出"
+
+#: command-list.h:196
+msgid "A useful minimum set of commands for Everyday Git"
+msgstr "每一天 Git 的一组有用的最小命令集合"
+
+#: command-list.h:197
+msgid "A Git Glossary"
+msgstr "Git 词汇表"
+
+#: command-list.h:198
+msgid "Hooks used by Git"
+msgstr "Git 使用的钩子"
+
+#: command-list.h:199
+msgid "Specifies intentionally untracked files to ignore"
+msgstr "忽略指定的未跟踪文件"
+
+#: command-list.h:200
+msgid "Defining submodule properties"
+msgstr "定义子模组属性"
+
+#: command-list.h:201
+msgid "Git namespaces"
+msgstr "Git 名字空间"
+
+#: command-list.h:202
+msgid "Git Repository Layout"
+msgstr "Git 仓库布局"
+
+#: command-list.h:203
+msgid "Specifying revisions and ranges for Git"
+msgstr "指定 Git 的版本和版本范围"
+
+#: command-list.h:204
+msgid "A tutorial introduction to Git: part two"
+msgstr "一个 Git 教程:第二部分"
+
+#: command-list.h:205
+msgid "A tutorial introduction to Git"
+msgstr "一个 Git 教程"
+
+#: command-list.h:206
+msgid "An overview of recommended workflows with Git"
+msgstr "Git 推荐的工作流概览"
 
 #: rerere.h:40
 msgid "update the index with reused conflict resolution if possible"
@@ -15132,7 +16184,7 @@ msgstr "尝试和 $pretty_name 的简单合并"
 msgid "Simple merge did not work, trying automatic merge."
 msgstr "简单合并未生效,尝试自动合并。"
 
-#: git-rebase.sh:60
+#: git-rebase.sh:61
 msgid ""
 "Resolve all conflicts manually, mark them as resolved with\n"
 "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n"
@@ -15145,41 +16197,41 @@ msgstr ""
 "\"git rebase --skip\" 命令跳过这个提交。如果想要终止执行并回到\n"
 "\"git rebase\" 执行之前的状态,执行 \"git rebase --abort\"。"
 
-#: git-rebase.sh:163 git-rebase.sh:409
+#: git-rebase.sh:173 git-rebase.sh:442
 #, sh-format
 msgid "Could not move back to $head_name"
 msgstr "无法移回 $head_name"
 
-#: git-rebase.sh:174
+#: git-rebase.sh:184
 msgid "Applied autostash."
 msgstr "成功应用 autostash。"
 
-#: git-rebase.sh:177
+#: git-rebase.sh:187
 #, sh-format
 msgid "Cannot store $stash_sha1"
 msgstr "无法保存 $stash_sha1"
 
-#: git-rebase.sh:218
+#: git-rebase.sh:229
 msgid "The pre-rebase hook refused to rebase."
 msgstr "钩子 pre-rebase 拒绝变基操作。"
 
-#: git-rebase.sh:223
+#: git-rebase.sh:234
 msgid "It looks like 'git am' is in progress. Cannot rebase."
 msgstr "看起来 'git-am' 正在执行中。无法变基。"
 
-#: git-rebase.sh:370
+#: git-rebase.sh:403
 msgid "No rebase in progress?"
 msgstr "没有正在进行的变基?"
 
-#: git-rebase.sh:381
+#: git-rebase.sh:414
 msgid "The --edit-todo action can only be used during interactive rebase."
 msgstr "动作 --edit-todo 只能用在交互式变基过程中。"
 
-#: git-rebase.sh:388
+#: git-rebase.sh:421
 msgid "Cannot read HEAD"
 msgstr "不能读取 HEAD"
 
-#: git-rebase.sh:391
+#: git-rebase.sh:424
 msgid ""
 "You must edit all merge conflicts and then\n"
 "mark them as resolved using git add"
@@ -15187,7 +16239,7 @@ msgstr ""
 "您必须编辑所有的合并冲突,然后通过 git add\n"
 "命令将它们标记为已解决"
 
-#: git-rebase.sh:435
+#: git-rebase.sh:468
 #, sh-format
 msgid ""
 "It seems that there is already a $state_dir_base directory, and\n"
@@ -15206,74 +16258,78 @@ msgstr ""
 "\t$cmd_clear_stale_rebase\n"
 "然后再重新执行变基操作。 为避免丢失重要数据,我已经停止当前操作。"
 
-#: git-rebase.sh:491
+#: git-rebase.sh:509
+msgid "error: cannot combine '--signoff' with '--preserve-merges'"
+msgstr "错误:不能组合参数 '--signoff' 和 '--preserve-merges'"
+
+#: git-rebase.sh:537
 #, sh-format
 msgid "invalid upstream '$upstream_name'"
 msgstr "无效的上游 '$upstream_name'"
 
-#: git-rebase.sh:515
+#: git-rebase.sh:561
 #, sh-format
 msgid "$onto_name: there are more than one merge bases"
 msgstr "$onto_name: 有一个以上的合并基准"
 
-#: git-rebase.sh:518 git-rebase.sh:522
+#: git-rebase.sh:564 git-rebase.sh:568
 #, sh-format
 msgid "$onto_name: there is no merge base"
 msgstr "$onto_name: 没有合并基准"
 
-#: git-rebase.sh:527
+#: git-rebase.sh:573
 #, sh-format
 msgid "Does not point to a valid commit: $onto_name"
 msgstr "没有指向一个有效的提交:$onto_name"
 
-#: git-rebase.sh:553
+#: git-rebase.sh:599
 #, sh-format
 msgid "fatal: no such branch/commit '$branch_name'"
 msgstr "严重错误:无此分支/提交 '$branch_name'"
 
-#: git-rebase.sh:586
+#: git-rebase.sh:632
 msgid "Cannot autostash"
 msgstr "无法 autostash"
 
-#: git-rebase.sh:591
+#: git-rebase.sh:637
 #, sh-format
 msgid "Created autostash: $stash_abbrev"
 msgstr "创建了 autostash: $stash_abbrev"
 
-#: git-rebase.sh:595
+#: git-rebase.sh:641
 msgid "Please commit or stash them."
 msgstr "请提交或贮藏修改。"
 
-#: git-rebase.sh:618
+#: git-rebase.sh:664
 #, sh-format
 msgid "HEAD is up to date."
 msgstr "HEAD 是最新的。"
 
-#: git-rebase.sh:620
+#: git-rebase.sh:666
 #, sh-format
 msgid "Current branch $branch_name is up to date."
 msgstr "当前分支 $branch_name 是最新的。"
 
-#: git-rebase.sh:628
+#: git-rebase.sh:674
 #, sh-format
 msgid "HEAD is up to date, rebase forced."
 msgstr "HEAD 是最新的,强制变基。"
 
-#: git-rebase.sh:630
+#: git-rebase.sh:676
 #, sh-format
 msgid "Current branch $branch_name is up to date, rebase forced."
 msgstr "当前分支 $branch_name 是最新的,强制变基。"
 
-#: git-rebase.sh:642
+#: git-rebase.sh:688
 #, sh-format
 msgid "Changes from $mb to $onto:"
 msgstr "变更从 $mb 到 $onto:"
 
-#: git-rebase.sh:651
+#: git-rebase.sh:697
 msgid "First, rewinding head to replay your work on top of it..."
 msgstr "首先,回退分支以便在上面重放您的工作..."
 
-#: git-rebase.sh:661
+#: git-rebase.sh:707
 #, sh-format
 msgid "Fast-forwarded $branch_name to $onto_name."
 msgstr "快进 $branch_name 至 $onto_name。"
@@ -15341,109 +16397,109 @@ msgstr "无法保存当前状态"
 msgid "Saved working directory and index state $stash_msg"
 msgstr "保存工作目录和索引状态 $stash_msg"
 
-#: git-stash.sh:340
+#: git-stash.sh:342
 msgid "Cannot remove worktree changes"
 msgstr "无法删除工作区变更"
 
-#: git-stash.sh:488
+#: git-stash.sh:490
 #, sh-format
 msgid "unknown option: $opt"
 msgstr "未知选项: $opt"
 
-#: git-stash.sh:501
+#: git-stash.sh:503
 msgid "No stash entries found."
 msgstr "未发现贮藏条目。"
 
-#: git-stash.sh:508
+#: git-stash.sh:510
 #, sh-format
 msgid "Too many revisions specified: $REV"
 msgstr "指定了太多的版本:$REV"
 
-#: git-stash.sh:523
+#: git-stash.sh:525
 #, sh-format
 msgid "$reference is not a valid reference"
 msgstr "$reference 不是一个有效的引用"
 
-#: git-stash.sh:551
+#: git-stash.sh:553
 #, sh-format
 msgid "'$args' is not a stash-like commit"
 msgstr "'$args' 不是贮藏式提交"
 
-#: git-stash.sh:562
+#: git-stash.sh:564
 #, sh-format
 msgid "'$args' is not a stash reference"
 msgstr "'$args' 不是一个贮藏引用"
 
-#: git-stash.sh:570
+#: git-stash.sh:572
 msgid "unable to refresh index"
 msgstr "无法刷新索引"
 
-#: git-stash.sh:574
+#: git-stash.sh:576
 msgid "Cannot apply a stash in the middle of a merge"
 msgstr "无法在合并过程应用贮藏"
 
-#: git-stash.sh:582
+#: git-stash.sh:584
 msgid "Conflicts in index. Try without --index."
 msgstr "索引中有冲突。尝试不使用 --index。"
 
-#: git-stash.sh:584
+#: git-stash.sh:586
 msgid "Could not save index tree"
 msgstr "不能保存索引树"
 
-#: git-stash.sh:593
+#: git-stash.sh:595
 msgid "Could not restore untracked files from stash entry"
 msgstr "无法从贮藏条目中恢复未跟踪文件"
 
-#: git-stash.sh:618
+#: git-stash.sh:620
 msgid "Cannot unstage modified files"
 msgstr "无法将修改的文件取消暂存"
 
-#: git-stash.sh:633
+#: git-stash.sh:635
 msgid "Index was not unstashed."
 msgstr "索引未从贮藏中恢复。"
 
-#: git-stash.sh:647
+#: git-stash.sh:649
 msgid "The stash entry is kept in case you need it again."
 msgstr "贮藏条目被保留以备您再次需要。"
 
-#: git-stash.sh:656
+#: git-stash.sh:658
 #, sh-format
 msgid "Dropped ${REV} ($s)"
 msgstr "丢弃了 ${REV} ($s)"
 
-#: git-stash.sh:657
+#: git-stash.sh:659
 #, sh-format
 msgid "${REV}: Could not drop stash entry"
 msgstr "${REV}:无法丢弃贮藏条目"
 
-#: git-stash.sh:665
+#: git-stash.sh:667
 msgid "No branch name specified"
 msgstr "未指定分支名"
 
-#: git-stash.sh:744
+#: git-stash.sh:746
 msgid "(To restore them type \"git stash apply\")"
 msgstr "(为恢复数据输入 \"git stash apply\")"
 
-#: git-submodule.sh:181
+#: git-submodule.sh:188
 msgid "Relative path can only be used from the toplevel of the working tree"
 msgstr "只能在工作区的顶级目录中使用相对路径"
 
-#: git-submodule.sh:191
+#: git-submodule.sh:198
 #, sh-format
 msgid "repo URL: '$repo' must be absolute or begin with ./|../"
 msgstr "仓库 URL:'$repo' 必须是绝对路径或以 ./|../ 起始"
 
-#: git-submodule.sh:210
+#: git-submodule.sh:217
 #, sh-format
 msgid "'$sm_path' already exists in the index"
 msgstr "'$sm_path' 已经存在于索引中"
 
-#: git-submodule.sh:213
+#: git-submodule.sh:220
 #, sh-format
 msgid "'$sm_path' already exists in the index and is not a submodule"
 msgstr "'$sm_path' 已经存在于索引中且不是一个子模组"
 
-#: git-submodule.sh:219
+#: git-submodule.sh:226
 #, sh-format
 msgid ""
 "The following path is ignored by one of your .gitignore files:\n"
@@ -15454,22 +16510,22 @@ msgstr ""
 "$sm_path\n"
 "如果您确实想添加它,使用 -f 参数。"
 
-#: git-submodule.sh:237
+#: git-submodule.sh:249
 #, sh-format
 msgid "Adding existing repo at '$sm_path' to the index"
 msgstr "添加位于 '$sm_path' 的现存仓库到索引"
 
-#: git-submodule.sh:239
+#: git-submodule.sh:251
 #, sh-format
 msgid "'$sm_path' already exists and is not a valid git repo"
 msgstr "'$sm_path' 已存在且不是一个有效的 git 仓库"
 
-#: git-submodule.sh:247
+#: git-submodule.sh:259
 #, sh-format
 msgid "A git directory for '$sm_name' is found locally with remote(s):"
 msgstr "本地发现 '$sm_name' 的一个 git 目录,与其对应的远程仓库:"
 
-#: git-submodule.sh:249
+#: git-submodule.sh:261
 #, sh-format
 msgid ""
 "If you want to reuse this local git directory instead of cloning again from\n"
@@ -15484,59 +16540,59 @@ msgstr ""
 "使用 '--force' 选项。如果本地 git 目录不是正确的仓库\n"
 "或者您不确定这里的含义,使用 '--name' 选项选择另外的名称。"
 
-#: git-submodule.sh:255
+#: git-submodule.sh:267
 #, sh-format
 msgid "Reactivating local git directory for submodule '$sm_name'."
 msgstr "激活本地 git 目录到子模组 '$sm_name'。"
 
-#: git-submodule.sh:267
+#: git-submodule.sh:279
 #, sh-format
 msgid "Unable to checkout submodule '$sm_path'"
 msgstr "不能检出子模组 '$sm_path'"
 
-#: git-submodule.sh:272
+#: git-submodule.sh:284
 #, sh-format
 msgid "Failed to add submodule '$sm_path'"
 msgstr "无法添加子模组 '$sm_path'"
 
-#: git-submodule.sh:281
+#: git-submodule.sh:293
 #, sh-format
 msgid "Failed to register submodule '$sm_path'"
 msgstr "无法注册子模组 '$sm_path'"
 
-#: git-submodule.sh:342
+#: git-submodule.sh:354
 #, sh-format
 msgid "Entering '$displaypath'"
 msgstr "正在进入 '$displaypath'"
 
-#: git-submodule.sh:362
+#: git-submodule.sh:374
 #, sh-format
 msgid "Stopping at '$displaypath'; script returned non-zero status."
 msgstr "停止于 '$displaypath';脚本返回非零值。"
 
-#: git-submodule.sh:584
+#: git-submodule.sh:600
 #, sh-format
 msgid "Unable to find current revision in submodule path '$displaypath'"
 msgstr "无法在子模组路径 '$displaypath' 中找到当前版本"
 
-#: git-submodule.sh:594
+#: git-submodule.sh:610
 #, sh-format
 msgid "Unable to fetch in submodule path '$sm_path'"
 msgstr "无法在子模组路径 '$sm_path' 中获取"
 
-#: git-submodule.sh:599
+#: git-submodule.sh:615
 #, sh-format
 msgid ""
 "Unable to find current ${remote_name}/${branch} revision in submodule path "
 "'$sm_path'"
 msgstr "无法在子模组路径 '$sm_path' 中找到当前版本 ${remote_name}/${branch}"
 
-#: git-submodule.sh:617
+#: git-submodule.sh:633
 #, sh-format
 msgid "Unable to fetch in submodule path '$displaypath'"
 msgstr "无法在子模组路径 '$displaypath' 中获取"
 
-#: git-submodule.sh:623
+#: git-submodule.sh:639
 #, sh-format
 msgid ""
 "Fetched in submodule path '$displaypath', but it did not contain $sha1. "
@@ -15544,74 +16600,74 @@ msgid ""
 msgstr ""
 "获取了子模组路径 '$displaypath',但是它没有包含 $sha1。直接获取该提交失败。"
 
-#: git-submodule.sh:630
+#: git-submodule.sh:646
 #, sh-format
 msgid "Unable to checkout '$sha1' in submodule path '$displaypath'"
 msgstr "无法在子模组路径 '$displaypath' 中检出 '$sha1'"
 
-#: git-submodule.sh:631
+#: git-submodule.sh:647
 #, sh-format
 msgid "Submodule path '$displaypath': checked out '$sha1'"
 msgstr "子模组路径 '$displaypath':检出 '$sha1'"
 
-#: git-submodule.sh:635
+#: git-submodule.sh:651
 #, sh-format
 msgid "Unable to rebase '$sha1' in submodule path '$displaypath'"
 msgstr "无法在子模组路径 '$displaypath' 中变基 '$sha1'"
 
-#: git-submodule.sh:636
+#: git-submodule.sh:652
 #, sh-format
 msgid "Submodule path '$displaypath': rebased into '$sha1'"
 msgstr "子模组路径 '$displaypath':变基至 '$sha1'"
 
-#: git-submodule.sh:641
+#: git-submodule.sh:657
 #, sh-format
 msgid "Unable to merge '$sha1' in submodule path '$displaypath'"
 msgstr "无法合并 '$sha1' 到子模组路径 '$displaypath' 中"
 
-#: git-submodule.sh:642
+#: git-submodule.sh:658
 #, sh-format
 msgid "Submodule path '$displaypath': merged in '$sha1'"
 msgstr "子模组路径 '$displaypath':已合并入 '$sha1'"
 
-#: git-submodule.sh:647
+#: git-submodule.sh:663
 #, sh-format
 msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'"
 msgstr "在子模组 '$displaypath' 中执行 '$command $sha1' 失败"
 
-#: git-submodule.sh:648
+#: git-submodule.sh:664
 #, sh-format
 msgid "Submodule path '$displaypath': '$command $sha1'"
 msgstr "子模组 '$displaypath':'$command $sha1'"
 
-#: git-submodule.sh:679
+#: git-submodule.sh:695
 #, sh-format
 msgid "Failed to recurse into submodule path '$displaypath'"
 msgstr "无法递归进子模组路径 '$displaypath'"
 
-#: git-submodule.sh:775
+#: git-submodule.sh:791
 msgid "The --cached option cannot be used with the --files option"
 msgstr "选项 --cached 不能和选项 --files 同时使用"
 
-#: git-submodule.sh:827
+#: git-submodule.sh:843
 #, sh-format
 msgid "unexpected mode $mod_dst"
 msgstr "意外的模式 $mod_dst"
 
 #  译者:注意保持前导空格
-#: git-submodule.sh:847
+#: git-submodule.sh:863
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_src"
 msgstr "  警告:$display_name 未包含提交 $sha1_src"
 
 #  译者:注意保持前导空格
-#: git-submodule.sh:850
+#: git-submodule.sh:866
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commit $sha1_dst"
 msgstr "  警告:$display_name 未包含提交 $sha1_dst"
 
 #  译者:注意保持前导空格
-#: git-submodule.sh:853
+#: git-submodule.sh:869
 #, sh-format
 msgid "  Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst"
 msgstr "  警告:$display_name 未包含提交 $sha1_src 和 $sha1_dst"
@@ -15621,38 +16677,50 @@ msgstr "  警告:$display_name 未包含提交 $sha1_src 和 $sha1_dst"
 msgid "See git-${cmd}(1) for details."
 msgstr "详见 git-${cmd}(1)。"
 
-#: git-rebase--interactive.sh:140
+#: git-rebase--interactive.sh:142
 #, sh-format
 msgid "Rebasing ($new_count/$total)"
 msgstr "变基中($new_count/$total)"
 
-#: git-rebase--interactive.sh:156
+#: git-rebase--interactive.sh:158
 msgid ""
 "\n"
 "Commands:\n"
-"p, pick = use commit\n"
-"r, reword = use commit, but edit the commit message\n"
-"e, edit = use commit, but stop for amending\n"
-"s, squash = use commit, but meld into previous commit\n"
-"f, fixup = like \"squash\", but discard this commit's log message\n"
-"x, exec = run command (the rest of the line) using shell\n"
-"d, drop = remove commit\n"
+"p, pick <commit> = use commit\n"
+"r, reword <commit> = use commit, but edit the commit message\n"
+"e, edit <commit> = use commit, but stop for amending\n"
+"s, squash <commit> = use commit, but meld into previous commit\n"
+"f, fixup <commit> = like \"squash\", but discard this commit's log message\n"
+"x, exec <command> = run command (the rest of the line) using shell\n"
+"d, drop <commit> = remove commit\n"
+"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"
 "\n"
 "These lines can be re-ordered; they are executed from top to bottom.\n"
 msgstr ""
 "\n"
 "命令:\n"
-"p, pick = 使用提交\n"
-"r, reword = 使用提交,但修改提交说明\n"
-"e, edit = 使用提交,但停止以便进行提交修补\n"
-"s, squash = 使用提交,但和前一个版本融合\n"
-"f, fixup = 类似于 \"squash\",但丢弃提交说明日志\n"
-"x, exec = 使用 shell 运行命令(此行剩余部分)\n"
-"d, drop = 删除提交\n"
+"p, pick <提交> = 使用提交\n"
+"r, reword <提交> = 使用提交,但修改提交说明\n"
+"e, edit <提交> = 使用提交,进入 shell 以便进行提交修补\n"
+"s, squash <提交> = 使用提交,但融合到前一个提交\n"
+"f, fixup <提交> = 类似于 \"squash\",但丢弃提交说明日志\n"
+"x, exec <命令> = 使用 shell 运行命令(此行剩余部分)\n"
+"d, drop <提交> = 删除提交\n"
+"l, label <label> = 为当前 HEAD 打上标记\n"
+"t, reset <label> = 重置 HEAD 到该标记\n"
+"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n"
+".       创建一个合并提交,并使用原始的合并提交说明(如果没有指定\n"
+".       原始提交,使用注释部分的 oneline 作为提交说明)。使用\n"
+".       -c <提交> 可以编辑提交说明。\n"
 "\n"
-"这些行可以被重新排序;它们会被从上至下地执行。\n"
+"可以对这些行重新排序,将从上至下执行。\n"
 
-#: git-rebase--interactive.sh:171
+#: git-rebase--interactive.sh:179
 msgid ""
 "\n"
 "Do not remove any line. Use 'drop' explicitly to remove a commit.\n"
@@ -15660,7 +16728,7 @@ msgstr ""
 "\n"
 "不要删除任意一行。使用 'drop' 显式地删除一个提交。\n"
 
-#: git-rebase--interactive.sh:175
+#: git-rebase--interactive.sh:183
 msgid ""
 "\n"
 "If you remove a line here THAT COMMIT WILL BE LOST.\n"
@@ -15668,7 +16736,7 @@ msgstr ""
 "\n"
 "如果您在这里删除一行,对应的提交将会丢失。\n"
 
-#: git-rebase--interactive.sh:213
+#: git-rebase--interactive.sh:221
 #, sh-format
 msgid ""
 "You can amend the commit now, with\n"
@@ -15687,83 +16755,83 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:238
+#: git-rebase--interactive.sh:246
 #, sh-format
 msgid "$sha1: not a commit that can be picked"
 msgstr "$sha1:不是一个可以被拣选的提交"
 
-#: git-rebase--interactive.sh:277
+#: git-rebase--interactive.sh:285
 #, sh-format
 msgid "Invalid commit name: $sha1"
 msgstr "无效的提交名:$sha1"
 
-#: git-rebase--interactive.sh:319
+#: git-rebase--interactive.sh:325
 msgid "Cannot write current commit's replacement sha1"
 msgstr "不能写入当前提交的替代 sha1"
 
-#: git-rebase--interactive.sh:371
+#: git-rebase--interactive.sh:376
 #, sh-format
 msgid "Fast-forward to $sha1"
 msgstr "快进到 $sha1"
 
-#: git-rebase--interactive.sh:373
+#: git-rebase--interactive.sh:378
 #, sh-format
 msgid "Cannot fast-forward to $sha1"
 msgstr "不能快进到 $sha1"
 
-#: git-rebase--interactive.sh:382
+#: git-rebase--interactive.sh:387
 #, sh-format
 msgid "Cannot move HEAD to $first_parent"
 msgstr "不能移动 HEAD 到 $first_parent"
 
-#: git-rebase--interactive.sh:387
+#: git-rebase--interactive.sh:392
 #, sh-format
 msgid "Refusing to squash a merge: $sha1"
 msgstr "拒绝压缩一个合并:$sha1"
 
-#: git-rebase--interactive.sh:405
+#: git-rebase--interactive.sh:410
 #, sh-format
 msgid "Error redoing merge $sha1"
 msgstr "无法重做合并 $sha1"
 
-#: git-rebase--interactive.sh:414
+#: git-rebase--interactive.sh:419
 #, sh-format
 msgid "Could not pick $sha1"
 msgstr "不能拣选 $sha1"
 
-#: git-rebase--interactive.sh:423
+#: git-rebase--interactive.sh:428
 #, sh-format
 msgid "This is the commit message #${n}:"
 msgstr "这是提交说明 #${n}:"
 
-#: git-rebase--interactive.sh:428
+#: git-rebase--interactive.sh:433
 #, sh-format
 msgid "The commit message #${n} will be skipped:"
 msgstr "提交说明 #${n} 将被跳过:"
 
-#: git-rebase--interactive.sh:439
+#: git-rebase--interactive.sh:444
 #, sh-format
 msgid "This is a combination of $count commit."
 msgid_plural "This is a combination of $count commits."
 msgstr[0] "这是一个 $count 个提交的组合。"
 msgstr[1] "这是一个 $count 个提交的组合。"
 
-#: git-rebase--interactive.sh:448
+#: git-rebase--interactive.sh:453
 #, sh-format
 msgid "Cannot write $fixup_msg"
 msgstr "不能写入 $fixup_msg"
 
-#: git-rebase--interactive.sh:451
+#: git-rebase--interactive.sh:456
 msgid "This is a combination of 2 commits."
 msgstr "这是一个 2 个提交的组合。"
 
-#: git-rebase--interactive.sh:492 git-rebase--interactive.sh:535
-#: git-rebase--interactive.sh:538
+#: git-rebase--interactive.sh:497 git-rebase--interactive.sh:540
+#: git-rebase--interactive.sh:543
 #, sh-format
 msgid "Could not apply $sha1... $rest"
 msgstr "不能应用 $sha1... $rest"
 
-#: git-rebase--interactive.sh:567
+#: git-rebase--interactive.sh:572
 #, sh-format
 msgid ""
 "Could not amend commit after successfully picking $sha1... $rest\n"
@@ -15776,32 +16844,32 @@ msgstr ""
 "这通常是因为空的提交说明,或者 pre-commit 钩子执行失败。如果是 pre-commit\n"
 "钩子执行失败,你可能需要在重写提交说明前解决这个问题。"
 
-#: git-rebase--interactive.sh:582
+#: git-rebase--interactive.sh:587
 #, sh-format
 msgid "Stopped at $sha1_abbrev... $rest"
 msgstr "停止在 $sha1_abbrev... $rest"
 
-#: git-rebase--interactive.sh:597
+#: git-rebase--interactive.sh:602
 #, sh-format
 msgid "Cannot '$squash_style' without a previous commit"
 msgstr "没有父提交的情况下不能 '$squash_style'"
 
-#: git-rebase--interactive.sh:639
+#: git-rebase--interactive.sh:644
 #, sh-format
 msgid "Executing: $rest"
 msgstr "执行:$rest"
 
-#: git-rebase--interactive.sh:647
+#: git-rebase--interactive.sh:652
 #, sh-format
 msgid "Execution failed: $rest"
 msgstr "执行失败:$rest"
 
-#: git-rebase--interactive.sh:649
+#: git-rebase--interactive.sh:654
 msgid "and made changes to the index and/or the working tree"
 msgstr "并且修改索引和/或工作区"
 
 #  译者:注意保持前导空格
-#: git-rebase--interactive.sh:651
+#: git-rebase--interactive.sh:656
 msgid ""
 "You can fix the problem, and then run\n"
 "\n"
@@ -15812,7 +16880,7 @@ msgstr ""
 "\tgit rebase --continue"
 
 #. TRANSLATORS: after these lines is a command to be issued by the user
-#: git-rebase--interactive.sh:664
+#: git-rebase--interactive.sh:669
 #, sh-format
 msgid ""
 "Execution succeeded: $rest\n"
@@ -15826,29 +16894,29 @@ msgstr ""
 "\n"
 "\tgit rebase --continue"
 
-#: git-rebase--interactive.sh:675
+#: git-rebase--interactive.sh:680
 #, sh-format
 msgid "Unknown command: $command $sha1 $rest"
 msgstr "未知命令:$command $sha1 $rest"
 
-#: git-rebase--interactive.sh:676
+#: git-rebase--interactive.sh:681
 msgid "Please fix this using 'git rebase --edit-todo'."
 msgstr "要修改请使用命令 'git rebase --edit-todo'。"
 
-#: git-rebase--interactive.sh:711
+#: git-rebase--interactive.sh:716
 #, sh-format
 msgid "Successfully rebased and updated $head_name."
 msgstr "成功变基并更新 $head_name。"
 
-#: git-rebase--interactive.sh:735
+#: git-rebase--interactive.sh:740
 msgid "could not detach HEAD"
 msgstr "不能检出为分离头指针"
 
-#: git-rebase--interactive.sh:771
+#: git-rebase--interactive.sh:778
 msgid "Could not remove CHERRY_PICK_HEAD"
 msgstr "不能删除 CHERRY_PICK_HEAD"
 
-#: git-rebase--interactive.sh:776
+#: git-rebase--interactive.sh:783
 #, sh-format
 msgid ""
 "You have staged changes in your working tree.\n"
@@ -15877,22 +16945,22 @@ msgstr ""
 "\n"
 "  git rebase --continue\n"
 
-#: git-rebase--interactive.sh:793
+#: git-rebase--interactive.sh:800
 msgid "Error trying to find the author identity to amend commit"
 msgstr "在修补提交中查找作者信息时遇到错误"
 
-#: git-rebase--interactive.sh:798
+#: git-rebase--interactive.sh:805
 msgid ""
 "You have uncommitted changes in your working tree. Please commit them\n"
 "first and then run 'git rebase --continue' again."
 msgstr ""
 "您的工作区中有未提交的变更。请先提交然后再次运行 'git rebase --continue'。"
 
-#: git-rebase--interactive.sh:803 git-rebase--interactive.sh:807
+#: git-rebase--interactive.sh:810 git-rebase--interactive.sh:814
 msgid "Could not commit staged changes."
 msgstr "不能提交暂存的修改。"
 
-#: git-rebase--interactive.sh:836
+#: git-rebase--interactive.sh:843
 msgid ""
 "\n"
 "You are editing the todo file of an ongoing interactive rebase.\n"
@@ -15906,57 +16974,59 @@ msgstr ""
 "    git rebase --continue\n"
 "\n"
 
-#: git-rebase--interactive.sh:844 git-rebase--interactive.sh:1008
+#: git-rebase--interactive.sh:851 git-rebase--interactive.sh:937
 msgid "Could not execute editor"
 msgstr "无法运行编辑器"
 
-#: git-rebase--interactive.sh:860
+#: git-rebase--interactive.sh:872
 #, sh-format
 msgid "Could not checkout $switch_to"
 msgstr "不能检出 $switch_to"
 
-#: git-rebase--interactive.sh:865
+#: git-rebase--interactive.sh:879
 msgid "No HEAD?"
 msgstr "没有 HEAD?"
 
-#: git-rebase--interactive.sh:866
+#: git-rebase--interactive.sh:880
 #, sh-format
 msgid "Could not create temporary $state_dir"
 msgstr "不能创建临时 $state_dir"
 
-#: git-rebase--interactive.sh:869
+#: git-rebase--interactive.sh:883
 msgid "Could not mark as interactive"
 msgstr "不能标记为交互式"
 
-#: git-rebase--interactive.sh:879 git-rebase--interactive.sh:884
-msgid "Could not init rewritten commits"
-msgstr "不能对重写提交进行初始化"
-
-#: git-rebase--interactive.sh:910
-msgid "Could not generate todo list"
-msgstr "无法生成待办列表"
-
-#: git-rebase--interactive.sh:986
+#: git-rebase--interactive.sh:915
 #, sh-format
 msgid "Rebase $shortrevisions onto $shortonto ($todocount command)"
 msgid_plural "Rebase $shortrevisions onto $shortonto ($todocount commands)"
 msgstr[0] "变基 $shortrevisions 到 $shortonto($todocount 个提交)"
 msgstr[1] "变基 $shortrevisions 到 $shortonto($todocount 个提交)"
 
-#: git-rebase--interactive.sh:991
+#: git-rebase--interactive.sh:920
 msgid ""
 "\n"
-"However, if you remove everything, the rebase will be aborted.\n"
+"\tHowever, if you remove everything, the rebase will be aborted.\n"
 "\n"
+"\t"
 msgstr ""
 "\n"
-"然而,如果您删除全部内容,变基操作将会终止。\n"
+"\t然而,如果您删除全部内容,变基操作将会终止。\n"
 "\n"
+"\t"
 
-#: git-rebase--interactive.sh:998
+#: git-rebase--interactive.sh:927
 msgid "Note that empty commits are commented out"
 msgstr "注意空提交已被注释掉"
 
+#: git-rebase--interactive.sh:980
+msgid "Could not generate todo list"
+msgstr "无法生成待办列表"
+
+#: git-rebase--interactive.sh:1001 git-rebase--interactive.sh:1006
+msgid "Could not init rewritten commits"
+msgstr "不能对重写提交进行初始化"
+
 #: git-sh-setup.sh:89 git-sh-setup.sh:94
 #, sh-format
 msgid "usage: $dashless $USAGE"
@@ -16028,107 +17098,107 @@ msgstr "缓存"
 msgid "unstaged"
 msgstr "未缓存"
 
-#: git-add--interactive.perl:246 git-add--interactive.perl:271
+#: git-add--interactive.perl:253 git-add--interactive.perl:278
 msgid "binary"
 msgstr "二进制"
 
-#: git-add--interactive.perl:255 git-add--interactive.perl:309
+#: git-add--interactive.perl:262 git-add--interactive.perl:316
 msgid "nothing"
 msgstr "无"
 
-#: git-add--interactive.perl:291 git-add--interactive.perl:306
+#: git-add--interactive.perl:298 git-add--interactive.perl:313
 msgid "unchanged"
 msgstr "没有修改"
 
-#: git-add--interactive.perl:602
+#: git-add--interactive.perl:609
 #, perl-format
 msgid "added %d path\n"
 msgid_plural "added %d paths\n"
 msgstr[0] "增加了 %d 个路径\n"
 msgstr[1] "增加了 %d 个路径\n"
 
-#: git-add--interactive.perl:605
+#: git-add--interactive.perl:612
 #, perl-format
 msgid "updated %d path\n"
 msgid_plural "updated %d paths\n"
 msgstr[0] "更新了 %d 个路径\n"
 msgstr[1] "更新了 %d 个路径\n"
 
-#: git-add--interactive.perl:608
+#: git-add--interactive.perl:615
 #, perl-format
 msgid "reverted %d path\n"
 msgid_plural "reverted %d paths\n"
 msgstr[0] "还原了 %d 个路径\n"
 msgstr[1] "还原了 %d 个路径\n"
 
-#: git-add--interactive.perl:611
+#: git-add--interactive.perl:618
 #, perl-format
 msgid "touched %d path\n"
 msgid_plural "touched %d paths\n"
 msgstr[0] "触碰了 %d 个路径\n"
 msgstr[1] "触碰了 %d 个路径\n"
 
-#: git-add--interactive.perl:620
+#: git-add--interactive.perl:627
 msgid "Update"
 msgstr "更新"
 
-#: git-add--interactive.perl:632
+#: git-add--interactive.perl:639
 msgid "Revert"
 msgstr "还原"
 
-#: git-add--interactive.perl:655
+#: git-add--interactive.perl:662
 #, perl-format
 msgid "note: %s is untracked now.\n"
 msgstr "说明:%s 现已成为未跟踪的。\n"
 
-#: git-add--interactive.perl:666
+#: git-add--interactive.perl:673
 msgid "Add untracked"
 msgstr "添加未跟踪的"
 
-#: git-add--interactive.perl:672
+#: git-add--interactive.perl:679
 msgid "No untracked files.\n"
 msgstr "没有未跟踪的文件。\n"
 
-#: git-add--interactive.perl:1026
+#: git-add--interactive.perl:1033
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for staging."
 msgstr "如果补丁能干净地应用,编辑块将立即标记为暂存。"
 
-#: git-add--interactive.perl:1029
+#: git-add--interactive.perl:1036
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for stashing."
 msgstr "如果补丁能干净地应用,编辑块将立即标记为贮藏。"
 
-#: git-add--interactive.perl:1032
+#: git-add--interactive.perl:1039
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for unstaging."
 msgstr "如果补丁能干净地应用,编辑块将立即标记为未暂存。"
 
-#: git-add--interactive.perl:1035 git-add--interactive.perl:1044
+#: git-add--interactive.perl:1042 git-add--interactive.perl:1051
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for applying."
 msgstr "如果补丁能干净地应用,编辑块将立即标记为应用。"
 
-#: git-add--interactive.perl:1038 git-add--interactive.perl:1041
+#: git-add--interactive.perl:1045 git-add--interactive.perl:1048
 msgid ""
 "If the patch applies cleanly, the edited hunk will immediately be\n"
 "marked for discarding."
 msgstr "如果补丁能干净地应用,编辑块将立即标记为丢弃。"
 
-#: git-add--interactive.perl:1078
+#: git-add--interactive.perl:1085
 #, perl-format
 msgid "failed to open hunk edit file for writing: %s"
 msgstr "无法写入块编辑文件:%s"
 
-#: git-add--interactive.perl:1079
+#: git-add--interactive.perl:1086
 msgid "Manual hunk edit mode -- see bottom for a quick guide.\n"
 msgstr "手动块编辑模式 -- 查看底部的快速指南。\n"
 
-#: git-add--interactive.perl:1085
+#: git-add--interactive.perl:1092
 #, perl-format
 msgid ""
 "---\n"
@@ -16142,7 +17212,7 @@ msgstr ""
 "以 %s 开始的行将被删除。\n"
 
 #. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages.
-#: git-add--interactive.perl:1093
+#: git-add--interactive.perl:1100
 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"
@@ -16151,7 +17221,7 @@ msgstr ""
 "如果不能干净地应用,您将有机会重新编辑。如果该块的全部内容删除,则\n"
 "此次编辑被终止,该块不会被修改。\n"
 
-#: git-add--interactive.perl:1107
+#: git-add--interactive.perl:1114
 #, perl-format
 msgid "failed to open hunk edit file for reading: %s"
 msgstr "无法读取块编辑文件:%s"
@@ -16162,12 +17232,12 @@ msgstr "无法读取块编辑文件:%s"
 #. 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:1206
+#: git-add--interactive.perl:1213
 msgid ""
 "Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? "
 msgstr "您的编辑块不能被应用。重新编辑(选择 \"no\" 丢弃!) [y/n]? "
 
-#: git-add--interactive.perl:1215
+#: git-add--interactive.perl:1222
 msgid ""
 "y - stage this hunk\n"
 "n - do not stage this hunk\n"
@@ -16181,7 +17251,7 @@ msgstr ""
 "a - 暂存该块和本文件中后面的全部块\n"
 "d - 不暂存该块和本文件中后面的全部块"
 
-#: git-add--interactive.perl:1221
+#: git-add--interactive.perl:1228
 msgid ""
 "y - stash this hunk\n"
 "n - do not stash this hunk\n"
@@ -16195,7 +17265,7 @@ msgstr ""
 "a - 贮藏该块和本文件中后面的全部块\n"
 "d - 不贮藏该块和本文件中后面的全部块"
 
-#: git-add--interactive.perl:1227
+#: git-add--interactive.perl:1234
 msgid ""
 "y - unstage this hunk\n"
 "n - do not unstage this hunk\n"
@@ -16209,7 +17279,7 @@ msgstr ""
 "a - 不暂存该块和本文件中后面的全部块\n"
 "d - 不要不暂存该块和本文件中后面的全部块"
 
-#: git-add--interactive.perl:1233
+#: git-add--interactive.perl:1240
 msgid ""
 "y - apply this hunk to index\n"
 "n - do not apply this hunk to index\n"
@@ -16223,7 +17293,7 @@ msgstr ""
 "a - 应用该块和本文件中后面的全部块\n"
 "d - 不要应用该块和本文件中后面的全部块"
 
-#: git-add--interactive.perl:1239
+#: git-add--interactive.perl:1246
 msgid ""
 "y - discard this hunk from worktree\n"
 "n - do not discard this hunk from worktree\n"
@@ -16237,7 +17307,7 @@ msgstr ""
 "a - 丢弃该块和本文件中后面的全部块\n"
 "d - 不要丢弃该块和本文件中后面的全部块"
 
-#: git-add--interactive.perl:1245
+#: git-add--interactive.perl:1252
 msgid ""
 "y - discard this hunk from index and worktree\n"
 "n - do not discard this hunk from index and worktree\n"
@@ -16251,7 +17321,7 @@ msgstr ""
 "a - 丢弃该块和本文件中后面的全部块\n"
 "d - 不要丢弃该块和本文件中后面的全部块"
 
-#: git-add--interactive.perl:1251
+#: git-add--interactive.perl:1258
 msgid ""
 "y - apply this hunk to index and worktree\n"
 "n - do not apply this hunk to index and worktree\n"
@@ -16265,7 +17335,7 @@ msgstr ""
 "a - 应用该块和本文件中后面的全部块\n"
 "d - 不要应用该块和本文件中后面的全部块"
 
-#: git-add--interactive.perl:1266
+#: git-add--interactive.perl:1273
 msgid ""
 "g - select a hunk to go to\n"
 "/ - search for a hunk matching the given regex\n"
@@ -16287,211 +17357,211 @@ msgstr ""
 "e - 手动编辑当前块\n"
 "? - 显示帮助\n"
 
-#: git-add--interactive.perl:1297
+#: git-add--interactive.perl:1304
 msgid "The selected hunks do not apply to the index!\n"
 msgstr "选中的块不能应用到索引!\n"
 
-#: git-add--interactive.perl:1298
+#: git-add--interactive.perl:1305
 msgid "Apply them to the worktree anyway? "
 msgstr "无论如何都要应用到工作区么?"
 
-#: git-add--interactive.perl:1301
+#: git-add--interactive.perl:1308
 msgid "Nothing was applied.\n"
 msgstr "未应用。\n"
 
-#: git-add--interactive.perl:1312
+#: git-add--interactive.perl:1319
 #, perl-format
 msgid "ignoring unmerged: %s\n"
 msgstr "忽略未合入的:%s\n"
 
-#: git-add--interactive.perl:1321
+#: git-add--interactive.perl:1328
 msgid "Only binary files changed.\n"
 msgstr "只有二进制文件被修改。\n"
 
-#: git-add--interactive.perl:1323
+#: git-add--interactive.perl:1330
 msgid "No changes.\n"
 msgstr "没有修改。\n"
 
-#: git-add--interactive.perl:1331
+#: git-add--interactive.perl:1338
 msgid "Patch update"
 msgstr "补丁更新"
 
-#: git-add--interactive.perl:1383
+#: git-add--interactive.perl:1390
 #, perl-format
 msgid "Stage mode change [y,n,q,a,d%s,?]? "
 msgstr "暂存模式变更 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1384
+#: git-add--interactive.perl:1391
 #, perl-format
 msgid "Stage deletion [y,n,q,a,d%s,?]? "
 msgstr "暂存删除动作 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1385
+#: git-add--interactive.perl:1392
 #, perl-format
 msgid "Stage this hunk [y,n,q,a,d%s,?]? "
 msgstr "暂存该块 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1388
+#: git-add--interactive.perl:1395
 #, perl-format
 msgid "Stash mode change [y,n,q,a,d%s,?]? "
 msgstr "贮藏模式变更 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1389
+#: git-add--interactive.perl:1396
 #, perl-format
 msgid "Stash deletion [y,n,q,a,d%s,?]? "
 msgstr "贮藏删除动作 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1390
+#: git-add--interactive.perl:1397
 #, perl-format
 msgid "Stash this hunk [y,n,q,a,d%s,?]? "
 msgstr "贮藏该块 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1393
+#: git-add--interactive.perl:1400
 #, perl-format
 msgid "Unstage mode change [y,n,q,a,d%s,?]? "
 msgstr "取消暂存模式变更 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1394
+#: git-add--interactive.perl:1401
 #, perl-format
 msgid "Unstage deletion [y,n,q,a,d%s,?]? "
 msgstr "取消暂存删除动作 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1395
+#: git-add--interactive.perl:1402
 #, perl-format
 msgid "Unstage this hunk [y,n,q,a,d%s,?]? "
 msgstr "取消暂存该块 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1398
+#: git-add--interactive.perl:1405
 #, perl-format
 msgid "Apply mode change to index [y,n,q,a,d%s,?]? "
 msgstr "将模式变更应用到索引 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1399
+#: git-add--interactive.perl:1406
 #, perl-format
 msgid "Apply deletion to index [y,n,q,a,d%s,?]? "
 msgstr "将删除应用到索引 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1400
+#: git-add--interactive.perl:1407
 #, perl-format
 msgid "Apply this hunk to index [y,n,q,a,d%s,?]? "
 msgstr "将该块应用到索引 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1403
+#: git-add--interactive.perl:1410
 #, perl-format
 msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? "
 msgstr "从工作区中丢弃模式变更 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1404
+#: git-add--interactive.perl:1411
 #, perl-format
 msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? "
 msgstr "从工作区中丢弃删除动作 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1405
+#: git-add--interactive.perl:1412
 #, perl-format
 msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? "
 msgstr "从工作区中丢弃该块 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1408
+#: git-add--interactive.perl:1415
 #, perl-format
 msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "从索引和工作区中丢弃模式变更 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1409
+#: git-add--interactive.perl:1416
 #, perl-format
 msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "从索引和工作区中丢弃删除 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1410
+#: git-add--interactive.perl:1417
 #, perl-format
 msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? "
 msgstr "从索引和工作区中丢弃该块 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1413
+#: git-add--interactive.perl:1420
 #, perl-format
 msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "将模式变更应用到索引和工作区 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1414
+#: git-add--interactive.perl:1421
 #, perl-format
 msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "将删除应用到索引和工作区 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1415
+#: git-add--interactive.perl:1422
 #, perl-format
 msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? "
 msgstr "将该块应用到索引和工作区 [y,n,q,a,d%s,?]? "
 
-#: git-add--interactive.perl:1515
+#: git-add--interactive.perl:1522
 msgid "No other hunks to goto\n"
 msgstr "没有其它可供跳转的块\n"
 
-#: git-add--interactive.perl:1522
+#: git-add--interactive.perl:1529
 msgid "go to which hunk (<ret> to see more)? "
 msgstr "跳转到哪个块(<回车> 查看更多)? "
 
-#: git-add--interactive.perl:1524
+#: git-add--interactive.perl:1531
 msgid "go to which hunk? "
 msgstr "跳转到哪个块?"
 
-#: git-add--interactive.perl:1533
+#: git-add--interactive.perl:1540
 #, perl-format
 msgid "Invalid number: '%s'\n"
 msgstr "无效数字:'%s'\n"
 
-#: git-add--interactive.perl:1538
+#: git-add--interactive.perl:1545
 #, perl-format
 msgid "Sorry, only %d hunk available.\n"
 msgid_plural "Sorry, only %d hunks available.\n"
 msgstr[0] "对不起,只有 %d 个可用块。\n"
 msgstr[1] "对不起,只有 %d 个可用块。\n"
 
-#: git-add--interactive.perl:1564
+#: git-add--interactive.perl:1571
 msgid "No other hunks to search\n"
 msgstr "没有其它可供查找的块\n"
 
-#: git-add--interactive.perl:1568
+#: git-add--interactive.perl:1575
 msgid "search for regex? "
 msgstr "使用正则表达式搜索?"
 
-#: git-add--interactive.perl:1581
+#: git-add--interactive.perl:1588
 #, perl-format
 msgid "Malformed search regexp %s: %s\n"
 msgstr "错误的正则表达式 %s:%s\n"
 
-#: git-add--interactive.perl:1591
+#: git-add--interactive.perl:1598
 msgid "No hunk matches the given pattern\n"
 msgstr "没有和给定模式相匹配的快\n"
 
-#: git-add--interactive.perl:1603 git-add--interactive.perl:1625
+#: git-add--interactive.perl:1610 git-add--interactive.perl:1632
 msgid "No previous hunk\n"
 msgstr "没有前一个块\n"
 
-#: git-add--interactive.perl:1612 git-add--interactive.perl:1631
+#: git-add--interactive.perl:1619 git-add--interactive.perl:1638
 msgid "No next hunk\n"
 msgstr "没有下一个块\n"
 
-#: git-add--interactive.perl:1637
+#: git-add--interactive.perl:1644
 msgid "Sorry, cannot split this hunk\n"
 msgstr "对不起,不能拆分这个块\n"
 
-#: git-add--interactive.perl:1643
+#: git-add--interactive.perl:1650
 #, perl-format
 msgid "Split into %d hunk.\n"
 msgid_plural "Split into %d hunks.\n"
 msgstr[0] "拆分为 %d 块。\n"
 msgstr[1] "拆分为 %d 块。\n"
 
-#: git-add--interactive.perl:1653
+#: git-add--interactive.perl:1660
 msgid "Sorry, cannot edit this hunk\n"
 msgstr "对不起,不能编辑这个块\n"
 
-#: git-add--interactive.perl:1699
+#: git-add--interactive.perl:1706
 msgid "Review diff"
 msgstr "检视 diff"
 
 #. TRANSLATORS: please do not translate the command names
 #. 'status', 'update', 'revert', etc.
-#: git-add--interactive.perl:1718
+#: git-add--interactive.perl:1725
 msgid ""
 "status        - show paths with changes\n"
 "update        - add working tree state to the staged set of changes\n"
@@ -16508,18 +17578,18 @@ msgstr ""
 "diff          - 显示 HEAD 和索引间差异\n"
 "add untracked - 添加未跟踪文件的内容至暂存列表\n"
 
-#: git-add--interactive.perl:1735 git-add--interactive.perl:1740
-#: git-add--interactive.perl:1743 git-add--interactive.perl:1750
-#: git-add--interactive.perl:1754 git-add--interactive.perl:1760
+#: git-add--interactive.perl:1742 git-add--interactive.perl:1747
+#: git-add--interactive.perl:1750 git-add--interactive.perl:1757
+#: git-add--interactive.perl:1761 git-add--interactive.perl:1767
 msgid "missing --"
 msgstr "缺失 --"
 
-#: git-add--interactive.perl:1756
+#: git-add--interactive.perl:1763
 #, perl-format
 msgid "unknown --patch mode: %s"
 msgstr "未知的 --patch 模式:%s"
 
-#: git-add--interactive.perl:1762 git-add--interactive.perl:1768
+#: git-add--interactive.perl:1769 git-add--interactive.perl:1775
 #, perl-format
 msgid "invalid argument %s, expecting --"
 msgstr "无效的参数 %s,期望是 --"
@@ -16725,7 +17795,7 @@ msgstr "如何处理这个地址?([q]uit|[d]rop|[e]dit):"
 msgid "CA path \"%s\" does not exist"
 msgstr "CA 路径 \"%s\" 不存在"
 
-#: git-send-email.perl:1395
+#: git-send-email.perl:1400
 msgid ""
 "    The Cc list above has been expanded by additional\n"
 "    addresses found in the patch commit message. By default\n"
@@ -16747,135 +17817,165 @@ msgstr ""
 "    sendemail.confirm auto'。\n"
 "\n"
 
-#. TRANSLATORS: Make sure to include [y] [n] [q] [a] in your
+#. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your
 #. translation. The program will only accept English input
 #. at this point.
-#: git-send-email.perl:1410
-msgid "Send this email? ([y]es|[n]o|[q]uit|[a]ll): "
-msgstr "发送邮件?([y]es|[n]o|[q]uit|[a]ll):"
+#: git-send-email.perl:1415
+msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
+msgstr "发送这封邮件?([y]es|[n]o|[e]dit|[q]uit|[a]ll): "
 
-#: git-send-email.perl:1413
+#: git-send-email.perl:1418
 msgid "Send this email reply required"
 msgstr "发送要求的邮件回复"
 
-#: git-send-email.perl:1439
+#: git-send-email.perl:1446
 msgid "The required SMTP server is not properly defined."
 msgstr "要求的 SMTP 服务器未被正确定义。"
 
-#: git-send-email.perl:1486
+#: git-send-email.perl:1493
 #, perl-format
 msgid "Server does not support STARTTLS! %s"
 msgstr "服务器不支持 STARTTLS!%s"
 
-#: git-send-email.perl:1491 git-send-email.perl:1495
+#: git-send-email.perl:1498 git-send-email.perl:1502
 #, perl-format
 msgid "STARTTLS failed! %s"
 msgstr "STARTTLS 失败!%s"
 
-#: git-send-email.perl:1505
+#: git-send-email.perl:1512
 msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug."
 msgstr "无法正确地初始化 SMTP。检查配置并使用 --smtp-debug。"
 
-#: git-send-email.perl:1523
+#: git-send-email.perl:1530
 #, perl-format
 msgid "Failed to send %s\n"
 msgstr "无法发送 %s\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Dry-Sent %s\n"
 msgstr "演习发送 %s\n"
 
-#: git-send-email.perl:1526
+#: git-send-email.perl:1533
 #, perl-format
 msgid "Sent %s\n"
 msgstr "正发送 %s\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "Dry-OK. Log says:\n"
 msgstr "演习成功。日志说:\n"
 
-#: git-send-email.perl:1528
+#: git-send-email.perl:1535
 msgid "OK. Log says:\n"
 msgstr "OK。日志说:\n"
 
-#: git-send-email.perl:1540
+#: git-send-email.perl:1547
 msgid "Result: "
 msgstr "结果:"
 
-#: git-send-email.perl:1543
+#: git-send-email.perl:1550
 msgid "Result: OK\n"
 msgstr "结果:OK\n"
 
-#: git-send-email.perl:1556
+#: git-send-email.perl:1568
 #, perl-format
 msgid "can't open file %s"
 msgstr "无法打开文件 %s"
 
-#: git-send-email.perl:1603 git-send-email.perl:1623
+#: git-send-email.perl:1615 git-send-email.perl:1635
 #, perl-format
 msgid "(mbox) Adding cc: %s from line '%s'\n"
 msgstr "(mbox) 添加 cc:%s 自行 '%s'\n"
 
-#: git-send-email.perl:1609
+#: git-send-email.perl:1621
 #, perl-format
 msgid "(mbox) Adding to: %s from line '%s'\n"
 msgstr "(mbox) 添加 to:%s 自行 '%s'\n"
 
-#: git-send-email.perl:1657
+#: git-send-email.perl:1674
 #, perl-format
 msgid "(non-mbox) Adding cc: %s from line '%s'\n"
 msgstr "(non-mbox) 添加 cc:%s 自行 '%s'\n"
 
-#: git-send-email.perl:1682
+#: git-send-email.perl:1699
 #, perl-format
 msgid "(body) Adding cc: %s from line '%s'\n"
 msgstr "(body) 添加 cc: %s 自行 '%s'\n"
 
-#: git-send-email.perl:1788
+#: git-send-email.perl:1817
 #, perl-format
 msgid "(%s) Could not execute '%s'"
 msgstr "(%s) 不能执行 '%s'"
 
-#: git-send-email.perl:1795
+#: git-send-email.perl:1824
 #, perl-format
 msgid "(%s) Adding %s: %s from: '%s'\n"
 msgstr "(%s) 添加 %s: %s 自:'%s'\n"
 
-#: git-send-email.perl:1799
+#: git-send-email.perl:1828
 #, perl-format
 msgid "(%s) failed to close pipe to '%s'"
 msgstr "(%s) 无法关闭管道至 '%s'"
 
-#: git-send-email.perl:1826
+#: git-send-email.perl:1855
 msgid "cannot send message as 7bit"
 msgstr "不能以 7bit 形式发送信息"
 
-#: git-send-email.perl:1834
+#: git-send-email.perl:1863
 msgid "invalid transfer encoding"
 msgstr "无效的传送编码"
 
-#: git-send-email.perl:1872 git-send-email.perl:1923 git-send-email.perl:1933
+#: git-send-email.perl:1901 git-send-email.perl:1952 git-send-email.perl:1962
 #, perl-format
 msgid "unable to open %s: %s\n"
 msgstr "不能打开 %s:%s\n"
 
-#: git-send-email.perl:1875
+#: git-send-email.perl:1904
 #, perl-format
 msgid "%s: patch contains a line longer than 998 characters"
 msgstr "%s:补丁包含一个超过 998 字符的行"
 
-#: git-send-email.perl:1891
+#: git-send-email.perl:1920
 #, perl-format
 msgid "Skipping %s with backup suffix '%s'.\n"
 msgstr "略过 %s 含备份后缀 '%s'。\n"
 
 #. TRANSLATORS: please keep "[y|N]" as is.
-#: git-send-email.perl:1895
+#: git-send-email.perl:1924
 #, perl-format
 msgid "Do you really want to send %s? [y|N]: "
 msgstr "您真的要发送 %s?[y|N]:"
 
+#~ msgid "Everyday Git With 20 Commands Or So"
+#~ msgstr "每一天 Git 常用的约 20 条命令"
+
+#~ msgid "Could not open '%s' for writing"
+#~ msgstr "无法打开 '%s' 进行写入"
+
+#~ msgid "BUG: returned path string doesn't match cwd?"
+#~ msgstr "BUG:返回的路径和当前路径不匹配?"
+
+#~ msgid "Error in object"
+#~ msgstr "对象中出错"
+
+#~ msgid ""
+#~ "unexpected 1st line of squash message:\n"
+#~ "\n"
+#~ "\t%.*s"
+#~ msgstr ""
+#~ "意外的压缩提交首行提交信息:\n"
+#~ "\n"
+#~ "\t%.*s"
+
+#~ msgid ""
+#~ "invalid 1st line of squash message:\n"
+#~ "\n"
+#~ "\t%.*s"
+#~ msgstr ""
+#~ "压缩提交的首行提交信息无效:\n"
+#~ "\n"
+#~ "\t%.*s"
+
 #~ msgid "To/Cc/Bcc fields are not interpreted yet, they have been ignored\n"
 #~ msgstr "To/Cc/Bcc 字段不解析,它们被忽略\n"
 
index f7ce4902301490d73bdd79bd396cf7bbe5f893ea..703fa6ff7bf297e9d0dd91586f951f715032e06a 100644 (file)
--- a/pretty.c
+++ b/pretty.c
@@ -549,7 +549,7 @@ static void add_merge_info(const struct pretty_print_context *pp,
                struct object_id *oidp = &parent->item->object.oid;
                strbuf_addch(sb, ' ');
                if (pp->abbrev)
-                       strbuf_add_unique_abbrev(sb, oidp->hash, pp->abbrev);
+                       strbuf_add_unique_abbrev(sb, oidp, pp->abbrev);
                else
                        strbuf_addstr(sb, oid_to_hex(oidp));
                parent = parent->next;
@@ -1156,15 +1156,16 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
                return 1;
        case 'h':               /* abbreviated commit hash */
                strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT));
-               strbuf_add_unique_abbrev(sb, commit->object.oid.hash,
+               strbuf_add_unique_abbrev(sb, &commit->object.oid,
                                         c->pretty_ctx->abbrev);
                strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET));
                return 1;
        case 'T':               /* tree hash */
-               strbuf_addstr(sb, oid_to_hex(&commit->tree->object.oid));
+               strbuf_addstr(sb, oid_to_hex(get_commit_tree_oid(commit)));
                return 1;
        case 't':               /* abbreviated tree hash */
-               strbuf_add_unique_abbrev(sb, commit->tree->object.oid.hash,
+               strbuf_add_unique_abbrev(sb,
+                                        get_commit_tree_oid(commit),
                                         c->pretty_ctx->abbrev);
                return 1;
        case 'P':               /* parent hashes */
@@ -1178,7 +1179,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
                for (p = commit->parents; p; p = p->next) {
                        if (p != commit->parents)
                                strbuf_addch(sb, ' ');
-                       strbuf_add_unique_abbrev(sb, p->item->object.oid.hash,
+                       strbuf_add_unique_abbrev(sb, &p->item->object.oid,
                                                 c->pretty_ctx->abbrev);
                }
                return 1;
index 126d09672738533b6ecc6b94b7405dff888bbaf6..a07845187233e429e00138cce7ade42e97a40d4b 100644 (file)
@@ -20,7 +20,7 @@ void prio_queue_reverse(struct prio_queue *queue)
        int i, j;
 
        if (queue->compare != NULL)
-               die("BUG: prio_queue_reverse() on non-LIFO queue");
+               BUG("prio_queue_reverse() on non-LIFO queue");
        for (i = 0; i < (j = (queue->nr - 1) - i); i++)
                swap(queue, i, j);
 }
index 43012b7eb6e18bc48d93e6b96a3f3f57fe8ef79f..5e636785d14f8ef5283561d4606fface080bf3c0 100644 (file)
@@ -8,6 +8,8 @@ static enum protocol_version parse_protocol_version(const char *value)
                return protocol_v0;
        else if (!strcmp(value, "1"))
                return protocol_v1;
+       else if (!strcmp(value, "2"))
+               return protocol_v2;
        else
                return protocol_unknown_version;
 }
index 1b2bc94a8d9f3c008bb76a0dfcdd640f99756fe3..2ad35e433c1e6f5f0d08c9d7500dc35782429f51 100644 (file)
@@ -5,6 +5,7 @@ enum protocol_version {
        protocol_unknown_version = -1,
        protocol_v0 = 0,
        protocol_v1 = 1,
+       protocol_v2 = 2,
 };
 
 /*
index 191ebe3e6a99d26913a510967a9545f53db58bc8..ffb976c33c6936a7b178c7c478bcf4cd2840d472 100644 (file)
@@ -11,6 +11,7 @@
 #include "list-objects.h"
 #include "packfile.h"
 #include "worktree.h"
+#include "object-store.h"
 
 struct connectivity_progress {
        struct progress *progress;
@@ -77,7 +78,7 @@ static void add_recent_object(const struct object_id *oid,
         * later processing, and the revision machinery expects
         * commits and tags to have been parsed.
         */
-       type = sha1_object_info(oid->hash, NULL);
+       type = oid_object_info(the_repository, oid, NULL);
        if (type < 0)
                die("unable to get object info for %s", oid_to_hex(oid));
 
index d614a3e8f3a92c14c5cbba4e5478eb399542b800..eaa2709414f06a1515a33e6119af7c49dde3498d 100644 (file)
@@ -185,7 +185,7 @@ static int ce_compare_link(const struct cache_entry *ce, size_t expected_size)
        if (strbuf_readlink(&sb, ce->name, expected_size))
                return -1;
 
-       buffer = read_sha1_file(ce->oid.hash, &type, &size);
+       buffer = read_object_file(&ce->oid, &type, &size);
        if (buffer) {
                if (size == sb.len)
                        match = memcmp(buffer, sb.buf, size);
@@ -1842,7 +1842,7 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
        if (verify_hdr(hdr, mmap_size) < 0)
                goto unmap;
 
-       hashcpy(istate->sha1, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz);
+       hashcpy(istate->oid.hash, (const unsigned char *)hdr + mmap_size - the_hash_algo->rawsz);
        istate->version = ntohl(hdr->hdr_version);
        istate->cache_nr = ntohl(hdr->hdr_entries);
        istate->cache_alloc = alloc_nr(istate->cache_nr);
@@ -1914,7 +1914,7 @@ int read_index_from(struct index_state *istate, const char *path,
        uint64_t start = getnanotime();
        struct split_index *split_index;
        int ret;
-       char *base_sha1_hex;
+       char *base_oid_hex;
        char *base_path;
 
        /* istate->initialized covers both .git/index and .git/sharedindex.xxx */
@@ -1925,7 +1925,7 @@ int read_index_from(struct index_state *istate, const char *path,
        trace_performance_since(start, "read cache %s", path);
 
        split_index = istate->split_index;
-       if (!split_index || is_null_sha1(split_index->base_sha1)) {
+       if (!split_index || is_null_oid(&split_index->base_oid)) {
                post_read_index_from(istate);
                return ret;
        }
@@ -1935,13 +1935,13 @@ int read_index_from(struct index_state *istate, const char *path,
        else
                split_index->base = xcalloc(1, sizeof(*split_index->base));
 
-       base_sha1_hex = sha1_to_hex(split_index->base_sha1);
-       base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_sha1_hex);
+       base_oid_hex = oid_to_hex(&split_index->base_oid);
+       base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_oid_hex);
        ret = do_read_index(split_index->base, base_path, 1);
-       if (hashcmp(split_index->base_sha1, split_index->base->sha1))
+       if (oidcmp(&split_index->base_oid, &split_index->base->oid))
                die("broken index, expect %s in %s, got %s",
-                   base_sha1_hex, base_path,
-                   sha1_to_hex(split_index->base->sha1));
+                   base_oid_hex, base_path,
+                   oid_to_hex(&split_index->base->oid));
 
        freshen_shared_index(base_path, 0);
        merge_base_index(istate);
@@ -2230,7 +2230,7 @@ static int verify_index_from(const struct index_state *istate, const char *path)
        if (n != the_hash_algo->rawsz)
                goto out;
 
-       if (hashcmp(istate->sha1, hash))
+       if (hashcmp(istate->oid.hash, hash))
                goto out;
 
        close(fd);
@@ -2304,7 +2304,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
 
        if (!istate->version) {
                istate->version = get_index_format_default();
-               if (getenv("GIT_TEST_SPLIT_INDEX"))
+               if (git_env_bool("GIT_TEST_SPLIT_INDEX", 0))
                        init_split_index(istate);
        }
 
@@ -2409,7 +2409,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
                        return -1;
        }
 
-       if (ce_flush(&c, newfd, istate->sha1))
+       if (ce_flush(&c, newfd, istate->oid.hash))
                return -1;
        if (close_tempfile_gently(tempfile)) {
                error(_("could not close '%s'"), tempfile->filename.buf);
@@ -2533,10 +2533,10 @@ static int write_shared_index(struct index_state *istate,
                return ret;
        }
        ret = rename_tempfile(temp,
-                             git_path("sharedindex.%s", sha1_to_hex(si->base->sha1)));
+                             git_path("sharedindex.%s", oid_to_hex(&si->base->oid)));
        if (!ret) {
-               hashcpy(si->base_sha1, si->base->sha1);
-               clean_shared_index_files(sha1_to_hex(si->base->sha1));
+               oidcpy(&si->base_oid, &si->base->oid);
+               clean_shared_index_files(oid_to_hex(&si->base->oid));
        }
 
        return ret;
@@ -2590,13 +2590,13 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
        if (!si || alternate_index_output ||
            (istate->cache_changed & ~EXTMASK)) {
                if (si)
-                       hashclr(si->base_sha1);
+                       oidclr(&si->base_oid);
                ret = do_write_locked_index(istate, lock, flags);
                goto out;
        }
 
-       if (getenv("GIT_TEST_SPLIT_INDEX")) {
-               int v = si->base_sha1[0];
+       if (git_env_bool("GIT_TEST_SPLIT_INDEX", 0)) {
+               int v = si->base_oid.hash[0];
                if ((v & 15) < 6)
                        istate->cache_changed |= SPLIT_INDEX_ORDERED;
        }
@@ -2611,7 +2611,7 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
 
                temp = mks_tempfile(git_path("sharedindex_XXXXXX"));
                if (!temp) {
-                       hashclr(si->base_sha1);
+                       oidclr(&si->base_oid);
                        ret = do_write_locked_index(istate, lock, flags);
                        goto out;
                }
@@ -2631,7 +2631,7 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
        /* Freshen the shared index only if the split-index was written */
        if (!ret && !new_shared_index) {
                const char *shared_index = git_path("sharedindex.%s",
-                                                   sha1_to_hex(si->base_sha1));
+                                                   oid_to_hex(&si->base_oid));
                freshen_shared_index(shared_index, 1);
        }
 
@@ -2729,7 +2729,7 @@ void *read_blob_data_from_index(const struct index_state *istate,
        }
        if (pos < 0)
                return NULL;
-       data = read_sha1_file(istate->cache[pos]->oid.hash, &type, &sz);
+       data = read_object_file(&istate->cache[pos]->oid, &type, &sz);
        if (!data || type != OBJ_BLOB) {
                free(data);
                return NULL;
index 45fc56216aaa8fd084a10514f6f4912878ab1627..01c1a82075eca737c2e3749e295ca24bbab870b6 100644 (file)
@@ -101,22 +101,38 @@ static struct used_atom {
 } *used_atom;
 static int used_atom_cnt, need_tagged, need_symref;
 
-static void color_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *color_value)
+/*
+ * Expand string, append it to strbuf *sb, then return error code ret.
+ * Allow to save few lines of code.
+ */
+static int strbuf_addf_ret(struct strbuf *sb, int ret, const char *fmt, ...)
+{
+       va_list ap;
+       va_start(ap, fmt);
+       strbuf_vaddf(sb, fmt, ap);
+       va_end(ap);
+       return ret;
+}
+
+static int color_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                            const char *color_value, struct strbuf *err)
 {
        if (!color_value)
-               die(_("expected format: %%(color:<color>)"));
+               return strbuf_addf_ret(err, -1, _("expected format: %%(color:<color>)"));
        if (color_parse(color_value, atom->u.color) < 0)
-               die(_("unrecognized color: %%(color:%s)"), color_value);
+               return strbuf_addf_ret(err, -1, _("unrecognized color: %%(color:%s)"),
+                                      color_value);
        /*
         * We check this after we've parsed the color, which lets us complain
         * about syntactically bogus color names even if they won't be used.
         */
        if (!want_color(format->use_color))
                color_parse("", atom->u.color);
+       return 0;
 }
 
-static void refname_atom_parser_internal(struct refname_atom *atom,
-                                        const char *arg, const char *name)
+static int refname_atom_parser_internal(struct refname_atom *atom, const char *arg,
+                                        const char *name, struct strbuf *err)
 {
        if (!arg)
                atom->option = R_NORMAL;
@@ -126,16 +142,18 @@ static void refname_atom_parser_internal(struct refname_atom *atom,
                 skip_prefix(arg, "strip=", &arg)) {
                atom->option = R_LSTRIP;
                if (strtol_i(arg, 10, &atom->lstrip))
-                       die(_("Integer value expected refname:lstrip=%s"), arg);
+                       return strbuf_addf_ret(err, -1, _("Integer value expected refname:lstrip=%s"), arg);
        } else if (skip_prefix(arg, "rstrip=", &arg)) {
                atom->option = R_RSTRIP;
                if (strtol_i(arg, 10, &atom->rstrip))
-                       die(_("Integer value expected refname:rstrip=%s"), arg);
+                       return strbuf_addf_ret(err, -1, _("Integer value expected refname:rstrip=%s"), arg);
        } else
-               die(_("unrecognized %%(%s) argument: %s"), name, arg);
+               return strbuf_addf_ret(err, -1, _("unrecognized %%(%s) argument: %s"), name, arg);
+       return 0;
 }
 
-static void remote_ref_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
+static int remote_ref_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                                 const char *arg, struct strbuf *err)
 {
        struct string_list params = STRING_LIST_INIT_DUP;
        int i;
@@ -145,9 +163,8 @@ static void remote_ref_atom_parser(const struct ref_format *format, struct used_
 
        if (!arg) {
                atom->u.remote_ref.option = RR_REF;
-               refname_atom_parser_internal(&atom->u.remote_ref.refname,
-                                            arg, atom->name);
-               return;
+               return refname_atom_parser_internal(&atom->u.remote_ref.refname,
+                                                   arg, atom->name, err);
        }
 
        atom->u.remote_ref.nobracket = 0;
@@ -170,29 +187,38 @@ static void remote_ref_atom_parser(const struct ref_format *format, struct used_
                        atom->u.remote_ref.push_remote = 1;
                } else {
                        atom->u.remote_ref.option = RR_REF;
-                       refname_atom_parser_internal(&atom->u.remote_ref.refname,
-                                                    arg, atom->name);
+                       if (refname_atom_parser_internal(&atom->u.remote_ref.refname,
+                                                        arg, atom->name, err)) {
+                               string_list_clear(&params, 0);
+                               return -1;
+                       }
                }
        }
 
        string_list_clear(&params, 0);
+       return 0;
 }
 
-static void body_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
+static int body_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                           const char *arg, struct strbuf *err)
 {
        if (arg)
-               die(_("%%(body) does not take arguments"));
+               return strbuf_addf_ret(err, -1, _("%%(body) does not take arguments"));
        atom->u.contents.option = C_BODY_DEP;
+       return 0;
 }
 
-static void subject_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
+static int subject_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                              const char *arg, struct strbuf *err)
 {
        if (arg)
-               die(_("%%(subject) does not take arguments"));
+               return strbuf_addf_ret(err, -1, _("%%(subject) does not take arguments"));
        atom->u.contents.option = C_SUB;
+       return 0;
 }
 
-static void trailers_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
+static int trailers_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                               const char *arg, struct strbuf *err)
 {
        struct string_list params = STRING_LIST_INIT_DUP;
        int i;
@@ -205,15 +231,20 @@ static void trailers_atom_parser(const struct ref_format *format, struct used_at
                                atom->u.contents.trailer_opts.unfold = 1;
                        else if (!strcmp(s, "only"))
                                atom->u.contents.trailer_opts.only_trailers = 1;
-                       else
-                               die(_("unknown %%(trailers) argument: %s"), s);
+                       else {
+                               strbuf_addf(err, _("unknown %%(trailers) argument: %s"), s);
+                               string_list_clear(&params, 0);
+                               return -1;
+                       }
                }
        }
        atom->u.contents.option = C_TRAILERS;
        string_list_clear(&params, 0);
+       return 0;
 }
 
-static void contents_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
+static int contents_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                               const char *arg, struct strbuf *err)
 {
        if (!arg)
                atom->u.contents.option = C_BARE;
@@ -225,16 +256,19 @@ static void contents_atom_parser(const struct ref_format *format, struct used_at
                atom->u.contents.option = C_SUB;
        else if (skip_prefix(arg, "trailers", &arg)) {
                skip_prefix(arg, ":", &arg);
-               trailers_atom_parser(format, atom, *arg ? arg : NULL);
+               if (trailers_atom_parser(format, atom, *arg ? arg : NULL, err))
+                       return -1;
        } else if (skip_prefix(arg, "lines=", &arg)) {
                atom->u.contents.option = C_LINES;
                if (strtoul_ui(arg, 10, &atom->u.contents.nlines))
-                       die(_("positive value expected contents:lines=%s"), arg);
+                       return strbuf_addf_ret(err, -1, _("positive value expected contents:lines=%s"), arg);
        } else
-               die(_("unrecognized %%(contents) argument: %s"), arg);
+               return strbuf_addf_ret(err, -1, _("unrecognized %%(contents) argument: %s"), arg);
+       return 0;
 }
 
-static void objectname_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
+static int objectname_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                                 const char *arg, struct strbuf *err)
 {
        if (!arg)
                atom->u.objectname.option = O_FULL;
@@ -244,16 +278,18 @@ static void objectname_atom_parser(const struct ref_format *format, struct used_
                atom->u.objectname.option = O_LENGTH;
                if (strtoul_ui(arg, 10, &atom->u.objectname.length) ||
                    atom->u.objectname.length == 0)
-                       die(_("positive value expected objectname:short=%s"), arg);
+                       return strbuf_addf_ret(err, -1, _("positive value expected objectname:short=%s"), arg);
                if (atom->u.objectname.length < MINIMUM_ABBREV)
                        atom->u.objectname.length = MINIMUM_ABBREV;
        } else
-               die(_("unrecognized %%(objectname) argument: %s"), arg);
+               return strbuf_addf_ret(err, -1, _("unrecognized %%(objectname) argument: %s"), arg);
+       return 0;
 }
 
-static void refname_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
+static int refname_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                              const char *arg, struct strbuf *err)
 {
-       refname_atom_parser_internal(&atom->u.refname, arg, atom->name);
+       return refname_atom_parser_internal(&atom->u.refname, arg, atom->name, err);
 }
 
 static align_type parse_align_position(const char *s)
@@ -267,7 +303,8 @@ static align_type parse_align_position(const char *s)
        return -1;
 }
 
-static void align_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
+static int align_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                            const char *arg, struct strbuf *err)
 {
        struct align *align = &atom->u.align;
        struct string_list params = STRING_LIST_INIT_DUP;
@@ -275,7 +312,7 @@ static void align_atom_parser(const struct ref_format *format, struct used_atom
        unsigned int width = ~0U;
 
        if (!arg)
-               die(_("expected format: %%(align:<width>,<position>)"));
+               return strbuf_addf_ret(err, -1, _("expected format: %%(align:<width>,<position>)"));
 
        align->position = ALIGN_LEFT;
 
@@ -286,49 +323,65 @@ static void align_atom_parser(const struct ref_format *format, struct used_atom
 
                if (skip_prefix(s, "position=", &s)) {
                        position = parse_align_position(s);
-                       if (position < 0)
-                               die(_("unrecognized position:%s"), s);
+                       if (position < 0) {
+                               strbuf_addf(err, _("unrecognized position:%s"), s);
+                               string_list_clear(&params, 0);
+                               return -1;
+                       }
                        align->position = position;
                } else if (skip_prefix(s, "width=", &s)) {
-                       if (strtoul_ui(s, 10, &width))
-                               die(_("unrecognized width:%s"), s);
+                       if (strtoul_ui(s, 10, &width)) {
+                               strbuf_addf(err, _("unrecognized width:%s"), s);
+                               string_list_clear(&params, 0);
+                               return -1;
+                       }
                } else if (!strtoul_ui(s, 10, &width))
                        ;
                else if ((position = parse_align_position(s)) >= 0)
                        align->position = position;
-               else
-                       die(_("unrecognized %%(align) argument: %s"), s);
+               else {
+                       strbuf_addf(err, _("unrecognized %%(align) argument: %s"), s);
+                       string_list_clear(&params, 0);
+                       return -1;
+               }
        }
 
-       if (width == ~0U)
-               die(_("positive width expected with the %%(align) atom"));
+       if (width == ~0U) {
+               string_list_clear(&params, 0);
+               return strbuf_addf_ret(err, -1, _("positive width expected with the %%(align) atom"));
+       }
        align->width = width;
        string_list_clear(&params, 0);
+       return 0;
 }
 
-static void if_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
+static int if_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                         const char *arg, struct strbuf *err)
 {
        if (!arg) {
                atom->u.if_then_else.cmp_status = COMPARE_NONE;
-               return;
+               return 0;
        } else if (skip_prefix(arg, "equals=", &atom->u.if_then_else.str)) {
                atom->u.if_then_else.cmp_status = COMPARE_EQUAL;
        } else if (skip_prefix(arg, "notequals=", &atom->u.if_then_else.str)) {
                atom->u.if_then_else.cmp_status = COMPARE_UNEQUAL;
-       } else {
-               die(_("unrecognized %%(if) argument: %s"), arg);
-       }
+       } else
+               return strbuf_addf_ret(err, -1, _("unrecognized %%(if) argument: %s"), arg);
+       return 0;
 }
 
-static void head_atom_parser(const struct ref_format *format, struct used_atom *atom, const char *arg)
+static int head_atom_parser(const struct ref_format *format, struct used_atom *atom,
+                           const char *arg, struct strbuf *unused_err)
 {
        atom->u.head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL);
+       return 0;
 }
 
 static struct {
        const char *name;
        cmp_type cmp_type;
-       void (*parser)(const struct ref_format *format, struct used_atom *atom, const char *arg);
+       int (*parser)(const struct ref_format *format, struct used_atom *atom,
+                     const char *arg, struct strbuf *err);
 } valid_atom[] = {
        { "refname" , FIELD_STR, refname_atom_parser },
        { "objecttype" },
@@ -387,7 +440,8 @@ struct ref_formatting_state {
 
 struct atom_value {
        const char *s;
-       void (*handler)(struct atom_value *atomv, struct ref_formatting_state *state);
+       int (*handler)(struct atom_value *atomv, struct ref_formatting_state *state,
+                      struct strbuf *err);
        uintmax_t value; /* used for sorting when not FIELD_STR */
        struct used_atom *atom;
 };
@@ -396,7 +450,8 @@ struct atom_value {
  * Used to parse format string and sort specifiers
  */
 static int parse_ref_filter_atom(const struct ref_format *format,
-                                const char *atom, const char *ep)
+                                const char *atom, const char *ep,
+                                struct strbuf *err)
 {
        const char *sp;
        const char *arg;
@@ -406,7 +461,8 @@ static int parse_ref_filter_atom(const struct ref_format *format,
        if (*sp == '*' && sp < ep)
                sp++; /* deref */
        if (ep <= sp)
-               die(_("malformed field name: %.*s"), (int)(ep-atom), atom);
+               return strbuf_addf_ret(err, -1, _("malformed field name: %.*s"),
+                                      (int)(ep-atom), atom);
 
        /* Do we have the atom already used elsewhere? */
        for (i = 0; i < used_atom_cnt; i++) {
@@ -432,7 +488,8 @@ static int parse_ref_filter_atom(const struct ref_format *format,
        }
 
        if (ARRAY_SIZE(valid_atom) <= i)
-               die(_("unknown field name: %.*s"), (int)(ep-atom), atom);
+               return strbuf_addf_ret(err, -1, _("unknown field name: %.*s"),
+                                      (int)(ep-atom), atom);
 
        /* Add it in, including the deref prefix */
        at = used_atom_cnt;
@@ -451,8 +508,8 @@ static int parse_ref_filter_atom(const struct ref_format *format,
                }
        }
        memset(&used_atom[at].u, 0, sizeof(used_atom[at].u));
-       if (valid_atom[i].parser)
-               valid_atom[i].parser(format, &used_atom[at], arg);
+       if (valid_atom[i].parser && valid_atom[i].parser(format, &used_atom[at], arg, err))
+               return -1;
        if (*atom == '*')
                need_tagged = 1;
        if (!strcmp(valid_atom[i].name, "symref"))
@@ -481,7 +538,8 @@ static void quote_formatting(struct strbuf *s, const char *str, int quote_style)
        }
 }
 
-static void append_atom(struct atom_value *v, struct ref_formatting_state *state)
+static int append_atom(struct atom_value *v, struct ref_formatting_state *state,
+                      struct strbuf *unused_err)
 {
        /*
         * Quote formatting is only done when the stack has a single
@@ -493,6 +551,7 @@ static void append_atom(struct atom_value *v, struct ref_formatting_state *state
                quote_formatting(&state->stack->output, v->s, state->quote_style);
        else
                strbuf_addstr(&state->stack->output, v->s);
+       return 0;
 }
 
 static void push_stack_element(struct ref_formatting_stack **stack)
@@ -527,7 +586,8 @@ static void end_align_handler(struct ref_formatting_stack **stack)
        strbuf_release(&s);
 }
 
-static void align_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
+static int align_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state,
+                             struct strbuf *unused_err)
 {
        struct ref_formatting_stack *new_stack;
 
@@ -535,6 +595,7 @@ static void align_atom_handler(struct atom_value *atomv, struct ref_formatting_s
        new_stack = state->stack;
        new_stack->at_end = end_align_handler;
        new_stack->at_end_data = &atomv->atom->u.align;
+       return 0;
 }
 
 static void if_then_else_handler(struct ref_formatting_stack **stack)
@@ -572,7 +633,8 @@ static void if_then_else_handler(struct ref_formatting_stack **stack)
        free(if_then_else);
 }
 
-static void if_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
+static int if_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state,
+                          struct strbuf *unused_err)
 {
        struct ref_formatting_stack *new_stack;
        struct if_then_else *if_then_else = xcalloc(sizeof(struct if_then_else), 1);
@@ -584,6 +646,7 @@ static void if_atom_handler(struct atom_value *atomv, struct ref_formatting_stat
        new_stack = state->stack;
        new_stack->at_end = if_then_else_handler;
        new_stack->at_end_data = if_then_else;
+       return 0;
 }
 
 static int is_empty(const char *s)
@@ -596,7 +659,8 @@ static int is_empty(const char *s)
        return 1;
 }
 
-static void then_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
+static int then_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state,
+                            struct strbuf *err)
 {
        struct ref_formatting_stack *cur = state->stack;
        struct if_then_else *if_then_else = NULL;
@@ -604,11 +668,11 @@ static void then_atom_handler(struct atom_value *atomv, struct ref_formatting_st
        if (cur->at_end == if_then_else_handler)
                if_then_else = (struct if_then_else *)cur->at_end_data;
        if (!if_then_else)
-               die(_("format: %%(then) atom used without an %%(if) atom"));
+               return strbuf_addf_ret(err, -1, _("format: %%(then) atom used without an %%(if) atom"));
        if (if_then_else->then_atom_seen)
-               die(_("format: %%(then) atom used more than once"));
+               return strbuf_addf_ret(err, -1, _("format: %%(then) atom used more than once"));
        if (if_then_else->else_atom_seen)
-               die(_("format: %%(then) atom used after %%(else)"));
+               return strbuf_addf_ret(err, -1, _("format: %%(then) atom used after %%(else)"));
        if_then_else->then_atom_seen = 1;
        /*
         * If the 'equals' or 'notequals' attribute is used then
@@ -624,9 +688,11 @@ static void then_atom_handler(struct atom_value *atomv, struct ref_formatting_st
        } else if (cur->output.len && !is_empty(cur->output.buf))
                if_then_else->condition_satisfied = 1;
        strbuf_reset(&cur->output);
+       return 0;
 }
 
-static void else_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
+static int else_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state,
+                            struct strbuf *err)
 {
        struct ref_formatting_stack *prev = state->stack;
        struct if_then_else *if_then_else = NULL;
@@ -634,24 +700,26 @@ static void else_atom_handler(struct atom_value *atomv, struct ref_formatting_st
        if (prev->at_end == if_then_else_handler)
                if_then_else = (struct if_then_else *)prev->at_end_data;
        if (!if_then_else)
-               die(_("format: %%(else) atom used without an %%(if) atom"));
+               return strbuf_addf_ret(err, -1, _("format: %%(else) atom used without an %%(if) atom"));
        if (!if_then_else->then_atom_seen)
-               die(_("format: %%(else) atom used without a %%(then) atom"));
+               return strbuf_addf_ret(err, -1, _("format: %%(else) atom used without a %%(then) atom"));
        if (if_then_else->else_atom_seen)
-               die(_("format: %%(else) atom used more than once"));
+               return strbuf_addf_ret(err, -1, _("format: %%(else) atom used more than once"));
        if_then_else->else_atom_seen = 1;
        push_stack_element(&state->stack);
        state->stack->at_end_data = prev->at_end_data;
        state->stack->at_end = prev->at_end;
+       return 0;
 }
 
-static void end_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state)
+static int end_atom_handler(struct atom_value *atomv, struct ref_formatting_state *state,
+                           struct strbuf *err)
 {
        struct ref_formatting_stack *current = state->stack;
        struct strbuf s = STRBUF_INIT;
 
        if (!current->at_end)
-               die(_("format: %%(end) atom used without corresponding atom"));
+               return strbuf_addf_ret(err, -1, _("format: %%(end) atom used without corresponding atom"));
        current->at_end(&state->stack);
 
        /*  Stack may have been popped within at_end(), hence reset the current pointer */
@@ -668,6 +736,7 @@ static void end_atom_handler(struct atom_value *atomv, struct ref_formatting_sta
        }
        strbuf_release(&s);
        pop_stack_element(&state->stack);
+       return 0;
 }
 
 /*
@@ -702,17 +771,21 @@ int verify_ref_format(struct ref_format *format)
 
        format->need_color_reset_at_eol = 0;
        for (cp = format->format; *cp && (sp = find_next(cp)); ) {
+               struct strbuf err = STRBUF_INIT;
                const char *color, *ep = strchr(sp, ')');
                int at;
 
                if (!ep)
                        return error(_("malformed format string %s"), sp);
                /* sp points at "%(" and ep points at the closing ")" */
-               at = parse_ref_filter_atom(format, sp + 2, ep);
+               at = parse_ref_filter_atom(format, sp + 2, ep, &err);
+               if (at < 0)
+                       die("%s", err.buf);
                cp = ep + 1;
 
                if (skip_prefix(used_atom[at].name, "color:", &color))
                        format->need_color_reset_at_eol = !!strcmp(color, "reset");
+               strbuf_release(&err);
        }
        if (format->need_color_reset_at_eol && !want_color(format->use_color))
                format->need_color_reset_at_eol = 0;
@@ -728,7 +801,7 @@ int verify_ref_format(struct ref_format *format)
 static void *get_obj(const struct object_id *oid, struct object **obj, unsigned long *sz, int *eaten)
 {
        enum object_type type;
-       void *buf = read_sha1_file(oid->hash, &type, sz);
+       void *buf = read_object_file(oid, &type, sz);
 
        if (buf)
                *obj = parse_object_buffer(oid, type, *sz, buf, eaten);
@@ -737,21 +810,21 @@ static void *get_obj(const struct object_id *oid, struct object **obj, unsigned
        return buf;
 }
 
-static int grab_objectname(const char *name, const unsigned char *sha1,
+static int grab_objectname(const char *name, const struct object_id *oid,
                           struct atom_value *v, struct used_atom *atom)
 {
        if (starts_with(name, "objectname")) {
                if (atom->u.objectname.option == O_SHORT) {
-                       v->s = xstrdup(find_unique_abbrev(sha1, DEFAULT_ABBREV));
+                       v->s = xstrdup(find_unique_abbrev(oid, DEFAULT_ABBREV));
                        return 1;
                } else if (atom->u.objectname.option == O_FULL) {
-                       v->s = xstrdup(sha1_to_hex(sha1));
+                       v->s = xstrdup(oid_to_hex(oid));
                        return 1;
                } else if (atom->u.objectname.option == O_LENGTH) {
-                       v->s = xstrdup(find_unique_abbrev(sha1, atom->u.objectname.length));
+                       v->s = xstrdup(find_unique_abbrev(oid, atom->u.objectname.length));
                        return 1;
                } else
-                       die("BUG: unknown %%(objectname) option");
+                       BUG("unknown %%(objectname) option");
        }
        return 0;
 }
@@ -775,7 +848,7 @@ static void grab_common_values(struct atom_value *val, int deref, struct object
                        v->s = xstrfmt("%lu", sz);
                }
                else if (deref)
-                       grab_objectname(name, obj->oid.hash, v, &used_atom[i]);
+                       grab_objectname(name, &obj->oid, v, &used_atom[i]);
        }
 }
 
@@ -815,7 +888,7 @@ static void grab_commit_values(struct atom_value *val, int deref, struct object
                if (deref)
                        name++;
                if (!strcmp(name, "tree")) {
-                       v->s = xstrdup(oid_to_hex(&commit->tree->object.oid));
+                       v->s = xstrdup(oid_to_hex(get_commit_tree_oid(commit)));
                }
                else if (!strcmp(name, "numparent")) {
                        v->value = commit_list_count(commit->parents);
@@ -1299,7 +1372,7 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
                else
                        *s = "";
        } else
-               die("BUG: unhandled RR_* enum");
+               BUG("unhandled RR_* enum");
 }
 
 char *get_head_description(void)
@@ -1309,10 +1382,14 @@ char *get_head_description(void)
        memset(&state, 0, sizeof(state));
        wt_status_get_state(&state, 1);
        if (state.rebase_in_progress ||
-           state.rebase_interactive_in_progress)
-               strbuf_addf(&desc, _("(no branch, rebasing %s)"),
-                           state.branch);
-       else if (state.bisect_in_progress)
+           state.rebase_interactive_in_progress) {
+               if (state.branch)
+                       strbuf_addf(&desc, _("(no branch, rebasing %s)"),
+                                   state.branch);
+               else
+                       strbuf_addf(&desc, _("(no branch, rebasing detached HEAD %s)"),
+                                   state.detached_from);
+       } else if (state.bisect_in_progress)
                strbuf_addf(&desc, _("(no branch, bisect started on %s)"),
                            state.branch);
        else if (state.detached_from) {
@@ -1354,28 +1431,30 @@ static const char *get_refname(struct used_atom *atom, struct ref_array_item *re
        return show_ref(&atom->u.refname, ref->refname);
 }
 
-static void get_object(struct ref_array_item *ref, const struct object_id *oid,
-                      int deref, struct object **obj)
+static int get_object(struct ref_array_item *ref, const struct object_id *oid,
+                      int deref, struct object **obj, struct strbuf *err)
 {
        int eaten;
+       int ret = 0;
        unsigned long size;
        void *buf = get_obj(oid, obj, &size, &eaten);
        if (!buf)
-               die(_("missing object %s for %s"),
-                   oid_to_hex(oid), ref->refname);
-       if (!*obj)
-               die(_("parse_object_buffer failed on %s for %s"),
-                   oid_to_hex(oid), ref->refname);
-
-       grab_values(ref->value, deref, *obj, buf, size);
+               ret = strbuf_addf_ret(err, -1, _("missing object %s for %s"),
+                                     oid_to_hex(oid), ref->refname);
+       else if (!*obj)
+               ret = strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"),
+                                     oid_to_hex(oid), ref->refname);
+       else
+               grab_values(ref->value, deref, *obj, buf, size);
        if (!eaten)
                free(buf);
+       return ret;
 }
 
 /*
  * Parse the object referred by ref, and grab needed value.
  */
-static void populate_value(struct ref_array_item *ref)
+static int populate_value(struct ref_array_item *ref, struct strbuf *err)
 {
        struct object *obj;
        int i;
@@ -1455,7 +1534,7 @@ static void populate_value(struct ref_array_item *ref)
                                v->s = xstrdup(buf + 1);
                        }
                        continue;
-               } else if (!deref && grab_objectname(name, ref->objectname.hash, v, atom)) {
+               } else if (!deref && grab_objectname(name, &ref->objectname, v, atom)) {
                        continue;
                } else if (!strcmp(name, "HEAD")) {
                        if (atom->u.head && !strcmp(ref->refname, atom->u.head))
@@ -1497,16 +1576,17 @@ static void populate_value(struct ref_array_item *ref)
                        break;
        }
        if (used_atom_cnt <= i)
-               return;
+               return 0;
 
-       get_object(ref, &ref->objectname, 0, &obj);
+       if (get_object(ref, &ref->objectname, 0, &obj, err))
+               return -1;
 
        /*
         * If there is no atom that wants to know about tagged
         * object, we are done.
         */
        if (!need_tagged || (obj->type != OBJ_TAG))
-               return;
+               return 0;
 
        /*
         * If it is a tag object, see if we use a value that derefs
@@ -1520,20 +1600,23 @@ static void populate_value(struct ref_array_item *ref)
         * is not consistent with what deref_tag() does
         * which peels the onion to the core.
         */
-       get_object(ref, tagged, 1, &obj);
+       return get_object(ref, tagged, 1, &obj, err);
 }
 
 /*
  * Given a ref, return the value for the atom.  This lazily gets value
  * out of the object by calling populate value.
  */
-static void get_ref_atom_value(struct ref_array_item *ref, int atom, struct atom_value **v)
+static int get_ref_atom_value(struct ref_array_item *ref, int atom,
+                             struct atom_value **v, struct strbuf *err)
 {
        if (!ref->value) {
-               populate_value(ref);
+               if (populate_value(ref, err))
+                       return -1;
                fill_missing_values(ref->value);
        }
        *v = &ref->value[atom];
+       return 0;
 }
 
 /*
@@ -1824,15 +1907,30 @@ static const struct object_id *match_points_at(struct oid_array *points_at,
        return NULL;
 }
 
-/* Allocate space for a new ref_array_item and copy the objectname and flag to it */
+/*
+ * Allocate space for a new ref_array_item and copy the name and oid to it.
+ *
+ * Callers can then fill in other struct members at their leisure.
+ */
 static struct ref_array_item *new_ref_array_item(const char *refname,
-                                                const unsigned char *objectname,
-                                                int flag)
+                                                const struct object_id *oid)
 {
        struct ref_array_item *ref;
+
        FLEX_ALLOC_STR(ref, refname, refname);
-       hashcpy(ref->objectname.hash, objectname);
-       ref->flag = flag;
+       oidcpy(&ref->objectname, oid);
+
+       return ref;
+}
+
+struct ref_array_item *ref_array_push(struct ref_array *array,
+                                     const char *refname,
+                                     const struct object_id *oid)
+{
+       struct ref_array_item *ref = new_ref_array_item(refname, oid);
+
+       ALLOC_GROW(array->items, array->nr + 1, array->alloc);
+       array->items[array->nr++] = ref;
 
        return ref;
 }
@@ -1927,12 +2025,11 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid,
         * to do its job and the resulting list may yet to be pruned
         * by maxcount logic.
         */
-       ref = new_ref_array_item(refname, oid->hash, flag);
+       ref = ref_array_push(ref_cbdata->array, refname, oid);
        ref->commit = commit;
-
-       REALLOC_ARRAY(ref_cbdata->array->items, ref_cbdata->array->nr + 1);
-       ref_cbdata->array->items[ref_cbdata->array->nr++] = ref;
+       ref->flag = flag;
        ref->kind = kind;
+
        return 0;
 }
 
@@ -2057,9 +2154,13 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru
        int cmp;
        cmp_type cmp_type = used_atom[s->atom].type;
        int (*cmp_fn)(const char *, const char *);
+       struct strbuf err = STRBUF_INIT;
 
-       get_ref_atom_value(a, s->atom, &va);
-       get_ref_atom_value(b, s->atom, &vb);
+       if (get_ref_atom_value(a, s->atom, &va, &err))
+               die("%s", err.buf);
+       if (get_ref_atom_value(b, s->atom, &vb, &err))
+               die("%s", err.buf);
+       strbuf_release(&err);
        cmp_fn = s->ignore_case ? strcasecmp : strcmp;
        if (s->version)
                cmp = versioncmp(va->s, vb->s);
@@ -2118,9 +2219,10 @@ static void append_literal(const char *cp, const char *ep, struct ref_formatting
        }
 }
 
-void format_ref_array_item(struct ref_array_item *info,
+int format_ref_array_item(struct ref_array_item *info,
                           const struct ref_format *format,
-                          struct strbuf *final_buf)
+                          struct strbuf *final_buf,
+                          struct strbuf *error_buf)
 {
        const char *cp, *sp, *ep;
        struct ref_formatting_state state = REF_FORMATTING_STATE_INIT;
@@ -2130,14 +2232,17 @@ void format_ref_array_item(struct ref_array_item *info,
 
        for (cp = format->format; *cp && (sp = find_next(cp)); cp = ep + 1) {
                struct atom_value *atomv;
+               int pos;
 
                ep = strchr(sp, ')');
                if (cp < sp)
                        append_literal(cp, sp, &state);
-               get_ref_atom_value(info,
-                                  parse_ref_filter_atom(format, sp + 2, ep),
-                                  &atomv);
-               atomv->handler(atomv, &state);
+               pos = parse_ref_filter_atom(format, sp + 2, ep, error_buf);
+               if (pos < 0 || get_ref_atom_value(info, pos, &atomv, error_buf) ||
+                   atomv->handler(atomv, &state, error_buf)) {
+                       pop_stack_element(&state.stack);
+                       return -1;
+               }
        }
        if (*cp) {
                sp = cp + strlen(cp);
@@ -2146,30 +2251,39 @@ void format_ref_array_item(struct ref_array_item *info,
        if (format->need_color_reset_at_eol) {
                struct atom_value resetv;
                resetv.s = GIT_COLOR_RESET;
-               append_atom(&resetv, &state);
+               if (append_atom(&resetv, &state, error_buf)) {
+                       pop_stack_element(&state.stack);
+                       return -1;
+               }
+       }
+       if (state.stack->prev) {
+               pop_stack_element(&state.stack);
+               return strbuf_addf_ret(error_buf, -1, _("format: %%(end) atom missing"));
        }
-       if (state.stack->prev)
-               die(_("format: %%(end) atom missing"));
        strbuf_addbuf(final_buf, &state.stack->output);
        pop_stack_element(&state.stack);
+       return 0;
 }
 
 void show_ref_array_item(struct ref_array_item *info,
                         const struct ref_format *format)
 {
        struct strbuf final_buf = STRBUF_INIT;
+       struct strbuf error_buf = STRBUF_INIT;
 
-       format_ref_array_item(info, format, &final_buf);
+       if (format_ref_array_item(info, format, &final_buf, &error_buf))
+               die("%s", error_buf.buf);
        fwrite(final_buf.buf, 1, final_buf.len, stdout);
+       strbuf_release(&error_buf);
        strbuf_release(&final_buf);
        putchar('\n');
 }
 
-void pretty_print_ref(const char *name, const unsigned char *sha1,
+void pretty_print_ref(const char *name, const struct object_id *oid,
                      const struct ref_format *format)
 {
        struct ref_array_item *ref_item;
-       ref_item = new_ref_array_item(name, sha1, 0);
+       ref_item = new_ref_array_item(name, oid);
        ref_item->kind = ref_kind_from_refname(name);
        show_ref_array_item(ref_item, format);
        free_array_item(ref_item);
@@ -2183,7 +2297,12 @@ static int parse_sorting_atom(const char *atom)
         */
        struct ref_format dummy = REF_FORMAT_INIT;
        const char *end = atom + strlen(atom);
-       return parse_ref_filter_atom(&dummy, atom, end);
+       struct strbuf err = STRBUF_INIT;
+       int res = parse_ref_filter_atom(&dummy, atom, end, &err);
+       if (res < 0)
+               die("%s", err.buf);
+       strbuf_release(&err);
+       return res;
 }
 
 /*  If no sorting option is given, use refname to sort as default */
index 0d98342b343196387c0f4e2dcd5978a9361d8edb..85c8ebc3b904e9b44bed8b164b9cdf62839d6dae 100644 (file)
@@ -110,9 +110,10 @@ int verify_ref_format(struct ref_format *format);
 /*  Sort the given ref_array as per the ref_sorting provided */
 void ref_array_sort(struct ref_sorting *sort, struct ref_array *array);
 /*  Based on the given format and quote_style, fill the strbuf */
-void format_ref_array_item(struct ref_array_item *info,
-                          const struct ref_format *format,
-                          struct strbuf *final_buf);
+int format_ref_array_item(struct ref_array_item *info,
+                         const struct ref_format *format,
+                         struct strbuf *final_buf,
+                         struct strbuf *error_buf);
 /*  Print the ref using the given format and quote_style */
 void show_ref_array_item(struct ref_array_item *info, const struct ref_format *format);
 /*  Parse a single sort specifier and add it to the list */
@@ -132,7 +133,15 @@ void setup_ref_filter_porcelain_msg(void);
  * Print a single ref, outside of any ref-filter. Note that the
  * name must be a fully qualified refname.
  */
-void pretty_print_ref(const char *name, const unsigned char *sha1,
+void pretty_print_ref(const char *name, const struct object_id *oid,
                      const struct ref_format *format);
 
+/*
+ * Push a single ref onto the array; this can be used to construct your own
+ * ref_array without using filter_refs().
+ */
+struct ref_array_item *ref_array_push(struct ref_array *array,
+                                     const char *refname,
+                                     const struct object_id *oid);
+
 #endif /*  REF_FILTER_H  */
diff --git a/refs.c b/refs.c
index 20ba82b4343ff2ef72cea32deec8a8d7fbd6def7..0eb379f9312fd9f167fea2e0f148c85c47cd2ff0 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -13,6 +13,8 @@
 #include "tag.h"
 #include "submodule.h"
 #include "worktree.h"
+#include "argv-array.h"
+#include "repository.h"
 
 /*
  * List of all available backends
@@ -206,7 +208,7 @@ char *refs_resolve_refdup(struct ref_store *refs,
 char *resolve_refdup(const char *refname, int resolve_flags,
                     struct object_id *oid, int *flags)
 {
-       return refs_resolve_refdup(get_main_ref_store(),
+       return refs_resolve_refdup(get_main_ref_store(the_repository),
                                   refname, resolve_flags,
                                   oid, flags);
 }
@@ -228,7 +230,7 @@ int refs_read_ref_full(struct ref_store *refs, const char *refname,
 
 int read_ref_full(const char *refname, int resolve_flags, struct object_id *oid, int *flags)
 {
-       return refs_read_ref_full(get_main_ref_store(), refname,
+       return refs_read_ref_full(get_main_ref_store(the_repository), refname,
                                  resolve_flags, oid, flags);
 }
 
@@ -301,7 +303,7 @@ enum peel_status peel_object(const struct object_id *name, struct object_id *oid
        struct object *o = lookup_unknown_object(name->hash);
 
        if (o->type == OBJ_NONE) {
-               int type = sha1_object_info(name->hash, NULL);
+               int type = oid_object_info(the_repository, name, NULL);
                if (type < 0 || !object_as_type(o, type, 0))
                        return PEEL_INVALID;
        }
@@ -375,7 +377,7 @@ int refs_for_each_tag_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 
 int for_each_tag_ref(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_tag_ref(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_tag_ref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
@@ -385,7 +387,7 @@ int refs_for_each_branch_ref(struct ref_store *refs, each_ref_fn fn, void *cb_da
 
 int for_each_branch_ref(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_branch_ref(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_branch_ref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
@@ -395,7 +397,7 @@ int refs_for_each_remote_ref(struct ref_store *refs, each_ref_fn fn, void *cb_da
 
 int for_each_remote_ref(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_remote_ref(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_remote_ref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int head_ref_namespaced(each_ref_fn fn, void *cb_data)
@@ -501,6 +503,19 @@ int refname_match(const char *abbrev_name, const char *full_name)
        return 0;
 }
 
+/*
+ * Given a 'prefix' expand it by the rules in 'ref_rev_parse_rules' and add
+ * the results to 'prefixes'
+ */
+void expand_ref_prefix(struct argv_array *prefixes, const char *prefix)
+{
+       const char **p;
+       int len = strlen(prefix);
+
+       for (p = ref_rev_parse_rules; *p; p++)
+               argv_array_pushf(prefixes, *p, len, prefix);
+}
+
 /*
  * *string and *len will only be substituted, and *string returned (for
  * later free()ing) if the string passed in is a magic short-hand form
@@ -600,7 +615,8 @@ int dwim_log(const char *str, int len, struct object_id *oid, char **log)
 static int is_per_worktree_ref(const char *refname)
 {
        return !strcmp(refname, "HEAD") ||
-               starts_with(refname, "refs/bisect/");
+               starts_with(refname, "refs/bisect/") ||
+               starts_with(refname, "refs/rewritten/");
 }
 
 static int is_pseudoref_syntax(const char *refname)
@@ -644,7 +660,7 @@ static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
 {
        const char *filename;
        int fd;
-       static struct lock_file lock;
+       struct lock_file lock = LOCK_INIT;
        struct strbuf buf = STRBUF_INIT;
        int ret = -1;
 
@@ -654,8 +670,7 @@ static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
        strbuf_addf(&buf, "%s\n", oid_to_hex(oid));
 
        filename = git_path("%s", pseudoref);
-       fd = hold_lock_file_for_update_timeout(&lock, filename,
-                                              LOCK_DIE_ON_ERROR,
+       fd = hold_lock_file_for_update_timeout(&lock, filename, 0,
                                               get_files_ref_lock_timeout_ms());
        if (fd < 0) {
                strbuf_addf(err, "could not open '%s' for writing: %s",
@@ -666,10 +681,21 @@ static int write_pseudoref(const char *pseudoref, const struct object_id *oid,
        if (old_oid) {
                struct object_id actual_old_oid;
 
-               if (read_ref(pseudoref, &actual_old_oid))
-                       die("could not read ref '%s'", pseudoref);
-               if (oidcmp(&actual_old_oid, old_oid)) {
-                       strbuf_addf(err, "unexpected sha1 when writing '%s'", pseudoref);
+               if (read_ref(pseudoref, &actual_old_oid)) {
+                       if (!is_null_oid(old_oid)) {
+                               strbuf_addf(err, "could not read ref '%s'",
+                                           pseudoref);
+                               rollback_lock_file(&lock);
+                               goto done;
+                       }
+               } else if (is_null_oid(old_oid)) {
+                       strbuf_addf(err, "ref '%s' already exists",
+                                   pseudoref);
+                       rollback_lock_file(&lock);
+                       goto done;
+               } else if (oidcmp(&actual_old_oid, old_oid)) {
+                       strbuf_addf(err, "unexpected object ID when writing '%s'",
+                                   pseudoref);
                        rollback_lock_file(&lock);
                        goto done;
                }
@@ -690,24 +716,28 @@ done:
 
 static int delete_pseudoref(const char *pseudoref, const struct object_id *old_oid)
 {
-       static struct lock_file lock;
        const char *filename;
 
        filename = git_path("%s", pseudoref);
 
        if (old_oid && !is_null_oid(old_oid)) {
+               struct lock_file lock = LOCK_INIT;
                int fd;
                struct object_id actual_old_oid;
 
                fd = hold_lock_file_for_update_timeout(
-                               &lock, filename, LOCK_DIE_ON_ERROR,
+                               &lock, filename, 0,
                                get_files_ref_lock_timeout_ms());
-               if (fd < 0)
-                       die_errno(_("Could not open '%s' for writing"), filename);
+               if (fd < 0) {
+                       error_errno(_("could not open '%s' for writing"),
+                                   filename);
+                       return -1;
+               }
                if (read_ref(pseudoref, &actual_old_oid))
                        die("could not read ref '%s'", pseudoref);
                if (oidcmp(&actual_old_oid, old_oid)) {
-                       warning("Unexpected sha1 when deleting %s", pseudoref);
+                       error("unexpected object ID when deleting '%s'",
+                             pseudoref);
                        rollback_lock_file(&lock);
                        return -1;
                }
@@ -730,7 +760,7 @@ int refs_delete_ref(struct ref_store *refs, const char *msg,
        struct strbuf err = STRBUF_INIT;
 
        if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
-               assert(refs == get_main_ref_store());
+               assert(refs == get_main_ref_store(the_repository));
                return delete_pseudoref(refname, old_oid);
        }
 
@@ -752,7 +782,7 @@ int refs_delete_ref(struct ref_store *refs, const char *msg,
 int delete_ref(const char *msg, const char *refname,
               const struct object_id *old_oid, unsigned int flags)
 {
-       return refs_delete_ref(get_main_ref_store(), msg, refname,
+       return refs_delete_ref(get_main_ref_store(the_repository), msg, refname,
                               old_oid, flags);
 }
 
@@ -928,7 +958,7 @@ struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs,
 
 struct ref_transaction *ref_transaction_begin(struct strbuf *err)
 {
-       return ref_store_transaction_begin(get_main_ref_store(), err);
+       return ref_store_transaction_begin(get_main_ref_store(the_repository), err);
 }
 
 void ref_transaction_free(struct ref_transaction *transaction)
@@ -944,10 +974,10 @@ void ref_transaction_free(struct ref_transaction *transaction)
                /* OK */
                break;
        case REF_TRANSACTION_PREPARED:
-               die("BUG: free called on a prepared reference transaction");
+               BUG("free called on a prepared reference transaction");
                break;
        default:
-               die("BUG: unexpected reference transaction state");
+               BUG("unexpected reference transaction state");
                break;
        }
 
@@ -969,7 +999,7 @@ struct ref_update *ref_transaction_add_update(
        struct ref_update *update;
 
        if (transaction->state != REF_TRANSACTION_OPEN)
-               die("BUG: update called for transaction that is not open");
+               BUG("update called for transaction that is not open");
 
        FLEX_ALLOC_STR(update, refname, refname);
        ALLOC_GROW(transaction->updates, transaction->nr + 1, transaction->alloc);
@@ -1019,7 +1049,7 @@ int ref_transaction_create(struct ref_transaction *transaction,
                           struct strbuf *err)
 {
        if (!new_oid || is_null_oid(new_oid))
-               die("BUG: create called without valid new_oid");
+               BUG("create called without valid new_oid");
        return ref_transaction_update(transaction, refname, new_oid,
                                      &null_oid, flags, msg, err);
 }
@@ -1031,7 +1061,7 @@ int ref_transaction_delete(struct ref_transaction *transaction,
                           struct strbuf *err)
 {
        if (old_oid && is_null_oid(old_oid))
-               die("BUG: delete called with old_oid set to zeros");
+               BUG("delete called with old_oid set to zeros");
        return ref_transaction_update(transaction, refname,
                                      &null_oid, old_oid,
                                      flags, msg, err);
@@ -1044,7 +1074,7 @@ int ref_transaction_verify(struct ref_transaction *transaction,
                           struct strbuf *err)
 {
        if (!old_oid)
-               die("BUG: verify called with old_oid set to NULL");
+               BUG("verify called with old_oid set to NULL");
        return ref_transaction_update(transaction, refname,
                                      NULL, old_oid,
                                      flags, NULL, err);
@@ -1060,7 +1090,7 @@ int refs_update_ref(struct ref_store *refs, const char *msg,
        int ret = 0;
 
        if (ref_type(refname) == REF_TYPE_PSEUDOREF) {
-               assert(refs == get_main_ref_store());
+               assert(refs == get_main_ref_store(the_repository));
                ret = write_pseudoref(refname, new_oid, old_oid, &err);
        } else {
                t = ref_store_transaction_begin(refs, &err);
@@ -1099,7 +1129,7 @@ int update_ref(const char *msg, const char *refname,
               const struct object_id *old_oid,
               unsigned int flags, enum action_on_err onerr)
 {
-       return refs_update_ref(get_main_ref_store(), msg, refname, new_oid,
+       return refs_update_ref(get_main_ref_store(the_repository), msg, refname, new_oid,
                               old_oid, flags, onerr);
 }
 
@@ -1132,8 +1162,8 @@ char *shorten_unambiguous_ref(const char *refname, int strict)
                for (i = 0; i < nr_rules; i++) {
                        assert(offset < total_len);
                        scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset;
-                       offset += snprintf(scanf_fmts[i], total_len - offset,
-                                          ref_rev_parse_rules[i], 2, "%s") + 1;
+                       offset += xsnprintf(scanf_fmts[i], total_len - offset,
+                                           ref_rev_parse_rules[i], 2, "%s") + 1;
                }
        }
 
@@ -1320,7 +1350,7 @@ int refs_head_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 
 int head_ref(each_ref_fn fn, void *cb_data)
 {
-       return refs_head_ref(get_main_ref_store(), fn, cb_data);
+       return refs_head_ref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 struct ref_iterator *refs_ref_iterator_begin(
@@ -1379,7 +1409,7 @@ int refs_for_each_ref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 
 int for_each_ref(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_ref(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_ref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int refs_for_each_ref_in(struct ref_store *refs, const char *prefix,
@@ -1390,7 +1420,7 @@ int refs_for_each_ref_in(struct ref_store *refs, const char *prefix,
 
 int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_ref_in(get_main_ref_store(), prefix, fn, cb_data);
+       return refs_for_each_ref_in(get_main_ref_store(the_repository), prefix, fn, cb_data);
 }
 
 int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken)
@@ -1399,7 +1429,7 @@ int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsig
 
        if (broken)
                flag = DO_FOR_EACH_INCLUDE_BROKEN;
-       return do_for_each_ref(get_main_ref_store(),
+       return do_for_each_ref(get_main_ref_store(the_repository),
                               prefix, fn, 0, flag, cb_data);
 }
 
@@ -1414,9 +1444,9 @@ int refs_for_each_fullref_in(struct ref_store *refs, const char *prefix,
        return do_for_each_ref(refs, prefix, fn, 0, flag, cb_data);
 }
 
-int for_each_replace_ref(each_ref_fn fn, void *cb_data)
+int for_each_replace_ref(struct repository *r, each_ref_fn fn, void *cb_data)
 {
-       return do_for_each_ref(get_main_ref_store(),
+       return do_for_each_ref(get_main_ref_store(r),
                               git_replace_ref_base, fn,
                               strlen(git_replace_ref_base),
                               DO_FOR_EACH_INCLUDE_BROKEN, cb_data);
@@ -1427,7 +1457,7 @@ int for_each_namespaced_ref(each_ref_fn fn, void *cb_data)
        struct strbuf buf = STRBUF_INIT;
        int ret;
        strbuf_addf(&buf, "%srefs/", get_git_namespace());
-       ret = do_for_each_ref(get_main_ref_store(),
+       ret = do_for_each_ref(get_main_ref_store(the_repository),
                              buf.buf, fn, 0, 0, cb_data);
        strbuf_release(&buf);
        return ret;
@@ -1441,7 +1471,7 @@ int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 
 int for_each_rawref(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_rawref(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_rawref(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int refs_read_raw_ref(struct ref_store *ref_store,
@@ -1547,7 +1577,7 @@ const char *refs_resolve_ref_unsafe(struct ref_store *refs,
 /* backend functions */
 int refs_init_db(struct strbuf *err)
 {
-       struct ref_store *refs = get_main_ref_store();
+       struct ref_store *refs = get_main_ref_store(the_repository);
 
        return refs->be->init_db(refs, err);
 }
@@ -1555,7 +1585,7 @@ int refs_init_db(struct strbuf *err)
 const char *resolve_ref_unsafe(const char *refname, int resolve_flags,
                               struct object_id *oid, int *flags)
 {
-       return refs_resolve_ref_unsafe(get_main_ref_store(), refname,
+       return refs_resolve_ref_unsafe(get_main_ref_store(the_repository), refname,
                                       resolve_flags, oid, flags);
 }
 
@@ -1607,9 +1637,6 @@ static struct ref_store_hash_entry *alloc_ref_store_hash_entry(
        return entry;
 }
 
-/* A pointer to the ref_store for the main repository: */
-static struct ref_store *main_ref_store;
-
 /* A hashmap of ref_stores, stored by submodule name: */
 static struct hashmap submodule_ref_stores;
 
@@ -1645,19 +1672,22 @@ static struct ref_store *ref_store_init(const char *gitdir,
        struct ref_store *refs;
 
        if (!be)
-               die("BUG: reference backend %s is unknown", be_name);
+               BUG("reference backend %s is unknown", be_name);
 
        refs = be->init(gitdir, flags);
        return refs;
 }
 
-struct ref_store *get_main_ref_store(void)
+struct ref_store *get_main_ref_store(struct repository *r)
 {
-       if (main_ref_store)
-               return main_ref_store;
+       if (r->refs)
+               return r->refs;
+
+       if (!r->gitdir)
+               BUG("attempting to get main_ref_store outside of repository");
 
-       main_ref_store = ref_store_init(get_git_dir(), REF_STORE_ALL_CAPS);
-       return main_ref_store;
+       r->refs = ref_store_init(r->gitdir, REF_STORE_ALL_CAPS);
+       return r->refs;
 }
 
 /*
@@ -1673,7 +1703,7 @@ static void register_ref_store_map(struct hashmap *map,
                hashmap_init(map, ref_store_hash_cmp, NULL, 0);
 
        if (hashmap_put(map, alloc_ref_store_hash_entry(name, refs)))
-               die("BUG: %s ref_store '%s' initialized twice", type, name);
+               BUG("%s ref_store '%s' initialized twice", type, name);
 }
 
 struct ref_store *get_submodule_ref_store(const char *submodule)
@@ -1726,7 +1756,7 @@ struct ref_store *get_worktree_ref_store(const struct worktree *wt)
        const char *id;
 
        if (wt->is_current)
-               return get_main_ref_store();
+               return get_main_ref_store(the_repository);
 
        id = wt->id ? wt->id : "/";
        refs = lookup_ref_store_map(&worktree_ref_stores, id);
@@ -1782,7 +1812,7 @@ int refs_peel_ref(struct ref_store *refs, const char *refname,
 
 int peel_ref(const char *refname, struct object_id *oid)
 {
-       return refs_peel_ref(get_main_ref_store(), refname, oid);
+       return refs_peel_ref(get_main_ref_store(the_repository), refname, oid);
 }
 
 int refs_create_symref(struct ref_store *refs,
@@ -1798,7 +1828,7 @@ int refs_create_symref(struct ref_store *refs,
 int create_symref(const char *ref_target, const char *refs_heads_master,
                  const char *logmsg)
 {
-       return refs_create_symref(get_main_ref_store(), ref_target,
+       return refs_create_symref(get_main_ref_store(the_repository), ref_target,
                                  refs_heads_master, logmsg);
 }
 
@@ -1819,7 +1849,7 @@ int ref_update_reject_duplicates(struct string_list *refnames,
                                    refnames->items[i].string);
                        return 1;
                } else if (cmp > 0) {
-                       die("BUG: ref_update_reject_duplicates() received unsorted list");
+                       BUG("ref_update_reject_duplicates() received unsorted list");
                }
        }
        return 0;
@@ -1835,13 +1865,13 @@ int ref_transaction_prepare(struct ref_transaction *transaction,
                /* Good. */
                break;
        case REF_TRANSACTION_PREPARED:
-               die("BUG: prepare called twice on reference transaction");
+               BUG("prepare called twice on reference transaction");
                break;
        case REF_TRANSACTION_CLOSED:
-               die("BUG: prepare called on a closed reference transaction");
+               BUG("prepare called on a closed reference transaction");
                break;
        default:
-               die("BUG: unexpected reference transaction state");
+               BUG("unexpected reference transaction state");
                break;
        }
 
@@ -1868,10 +1898,10 @@ int ref_transaction_abort(struct ref_transaction *transaction,
                ret = refs->be->transaction_abort(refs, transaction, err);
                break;
        case REF_TRANSACTION_CLOSED:
-               die("BUG: abort called on a closed reference transaction");
+               BUG("abort called on a closed reference transaction");
                break;
        default:
-               die("BUG: unexpected reference transaction state");
+               BUG("unexpected reference transaction state");
                break;
        }
 
@@ -1896,10 +1926,10 @@ int ref_transaction_commit(struct ref_transaction *transaction,
                /* Fall through to finish. */
                break;
        case REF_TRANSACTION_CLOSED:
-               die("BUG: commit called on a closed reference transaction");
+               BUG("commit called on a closed reference transaction");
                break;
        default:
-               die("BUG: unexpected reference transaction state");
+               BUG("unexpected reference transaction state");
                break;
        }
 
@@ -1980,7 +2010,7 @@ int refs_verify_refname_available(struct ref_store *refs,
        }
 
        if (ok != ITER_DONE)
-               die("BUG: error while iterating over references");
+               BUG("error while iterating over references");
 
        extra_refname = find_descendant_ref(dirname.buf, extras, skip);
        if (extra_refname)
@@ -2006,7 +2036,7 @@ int refs_for_each_reflog(struct ref_store *refs, each_ref_fn fn, void *cb_data)
 
 int for_each_reflog(each_ref_fn fn, void *cb_data)
 {
-       return refs_for_each_reflog(get_main_ref_store(), fn, cb_data);
+       return refs_for_each_reflog(get_main_ref_store(the_repository), fn, cb_data);
 }
 
 int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
@@ -2021,7 +2051,7 @@ int refs_for_each_reflog_ent_reverse(struct ref_store *refs,
 int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn,
                                void *cb_data)
 {
-       return refs_for_each_reflog_ent_reverse(get_main_ref_store(),
+       return refs_for_each_reflog_ent_reverse(get_main_ref_store(the_repository),
                                                refname, fn, cb_data);
 }
 
@@ -2034,7 +2064,7 @@ int refs_for_each_reflog_ent(struct ref_store *refs, const char *refname,
 int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn,
                        void *cb_data)
 {
-       return refs_for_each_reflog_ent(get_main_ref_store(), refname,
+       return refs_for_each_reflog_ent(get_main_ref_store(the_repository), refname,
                                        fn, cb_data);
 }
 
@@ -2045,7 +2075,7 @@ int refs_reflog_exists(struct ref_store *refs, const char *refname)
 
 int reflog_exists(const char *refname)
 {
-       return refs_reflog_exists(get_main_ref_store(), refname);
+       return refs_reflog_exists(get_main_ref_store(the_repository), refname);
 }
 
 int refs_create_reflog(struct ref_store *refs, const char *refname,
@@ -2057,7 +2087,7 @@ int refs_create_reflog(struct ref_store *refs, const char *refname,
 int safe_create_reflog(const char *refname, int force_create,
                       struct strbuf *err)
 {
-       return refs_create_reflog(get_main_ref_store(), refname,
+       return refs_create_reflog(get_main_ref_store(the_repository), refname,
                                  force_create, err);
 }
 
@@ -2068,7 +2098,7 @@ int refs_delete_reflog(struct ref_store *refs, const char *refname)
 
 int delete_reflog(const char *refname)
 {
-       return refs_delete_reflog(get_main_ref_store(), refname);
+       return refs_delete_reflog(get_main_ref_store(the_repository), refname);
 }
 
 int refs_reflog_expire(struct ref_store *refs,
@@ -2091,7 +2121,7 @@ int reflog_expire(const char *refname, const struct object_id *oid,
                  reflog_expiry_cleanup_fn cleanup_fn,
                  void *policy_cb_data)
 {
-       return refs_reflog_expire(get_main_ref_store(),
+       return refs_reflog_expire(get_main_ref_store(the_repository),
                                  refname, oid, flags,
                                  prepare_fn, should_prune_fn,
                                  cleanup_fn, policy_cb_data);
@@ -2114,7 +2144,7 @@ int refs_delete_refs(struct ref_store *refs, const char *msg,
 int delete_refs(const char *msg, struct string_list *refnames,
                unsigned int flags)
 {
-       return refs_delete_refs(get_main_ref_store(), msg, refnames, flags);
+       return refs_delete_refs(get_main_ref_store(the_repository), msg, refnames, flags);
 }
 
 int refs_rename_ref(struct ref_store *refs, const char *oldref,
@@ -2125,7 +2155,7 @@ int refs_rename_ref(struct ref_store *refs, const char *oldref,
 
 int rename_ref(const char *oldref, const char *newref, const char *logmsg)
 {
-       return refs_rename_ref(get_main_ref_store(), oldref, newref, logmsg);
+       return refs_rename_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
 }
 
 int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
@@ -2136,5 +2166,5 @@ int refs_copy_existing_ref(struct ref_store *refs, const char *oldref,
 
 int copy_existing_ref(const char *oldref, const char *newref, const char *logmsg)
 {
-       return refs_copy_existing_ref(get_main_ref_store(), oldref, newref, logmsg);
+       return refs_copy_existing_ref(get_main_ref_store(the_repository), oldref, newref, logmsg);
 }
diff --git a/refs.h b/refs.h
index 01be5ae32fb01298ff6c0738ac4adfe42643b682..cc2fb4c68c0e194dc51e3846192911c2c6949c6b 100644 (file)
--- a/refs.h
+++ b/refs.h
@@ -139,6 +139,13 @@ int resolve_gitlink_ref(const char *submodule, const char *refname,
  */
 int refname_match(const char *abbrev_name, const char *full_name);
 
+/*
+ * Given a 'prefix' expand it by the rules in 'ref_rev_parse_rules' and add
+ * the results to 'prefixes'
+ */
+struct argv_array;
+void expand_ref_prefix(struct argv_array *prefixes, const char *prefix);
+
 int expand_ref(const char *str, int len, struct object_id *oid, char **ref);
 int dwim_ref(const char *str, int len, struct object_id *oid, char **ref);
 int dwim_log(const char *str, int len, struct object_id *oid, char **ref);
@@ -300,7 +307,7 @@ int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data,
 int for_each_tag_ref(each_ref_fn fn, void *cb_data);
 int for_each_branch_ref(each_ref_fn fn, void *cb_data);
 int for_each_remote_ref(each_ref_fn fn, void *cb_data);
-int for_each_replace_ref(each_ref_fn fn, void *cb_data);
+int for_each_replace_ref(struct repository *r, each_ref_fn fn, void *cb_data);
 int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data);
 int for_each_glob_ref_in(each_ref_fn fn, const char *pattern,
                         const char *prefix, void *cb_data);
@@ -758,7 +765,7 @@ int reflog_expire(const char *refname, const struct object_id *oid,
 
 int ref_storage_backend_exists(const char *name);
 
-struct ref_store *get_main_ref_store(void);
+struct ref_store *get_main_ref_store(struct repository *r);
 /*
  * Return the ref_store instance for the specified submodule. For the
  * main repository, use submodule==NULL; such a call cannot fail. For
index bec8e30e9e3e2995739dfff7cc971f8de623610d..a9a066dcfb60d83a10e27d1c0d1131faf2ae97a4 100644 (file)
@@ -9,6 +9,7 @@
 #include "../lockfile.h"
 #include "../object.h"
 #include "../dir.h"
+#include "../chdir-notify.h"
 
 /*
  * This backend uses the following flags in `ref_update::flags` for
@@ -61,10 +62,6 @@ struct ref_lock {
        struct object_id old_oid;
 };
 
-/*
- * Future: need to be in "struct repository"
- * when doing a full libification.
- */
 struct files_ref_store {
        struct ref_store base;
        unsigned int store_flags;
@@ -106,6 +103,11 @@ static struct ref_store *files_ref_store_create(const char *gitdir,
        refs->packed_ref_store = packed_ref_store_create(sb.buf, flags);
        strbuf_release(&sb);
 
+       chdir_notify_reparent("files-backend $GIT_DIR",
+                             &refs->gitdir);
+       chdir_notify_reparent("files-backend $GIT_COMMONDIR",
+                             &refs->gitcommondir);
+
        return ref_store;
 }
 
@@ -119,7 +121,7 @@ static void files_assert_main_repository(struct files_ref_store *refs,
        if (refs->store_flags & REF_STORE_MAIN)
                return;
 
-       die("BUG: operation %s only allowed for main ref store", caller);
+       BUG("operation %s only allowed for main ref store", caller);
 }
 
 /*
@@ -135,13 +137,13 @@ static struct files_ref_store *files_downcast(struct ref_store *ref_store,
        struct files_ref_store *refs;
 
        if (ref_store->be != &refs_be_files)
-               die("BUG: ref_store is type \"%s\" not \"files\" in %s",
+               BUG("ref_store is type \"%s\" not \"files\" in %s",
                    ref_store->be->name, caller);
 
        refs = (struct files_ref_store *)ref_store;
 
        if ((refs->store_flags & required_flags) != required_flags)
-               die("BUG: operation %s requires abilities 0x%x, but only have 0x%x",
+               BUG("operation %s requires abilities 0x%x, but only have 0x%x",
                    caller, required_flags, refs->store_flags);
 
        return refs;
@@ -160,7 +162,7 @@ static void files_reflog_path(struct files_ref_store *refs,
                strbuf_addf(sb, "%s/logs/%s", refs->gitcommondir, refname);
                break;
        default:
-               die("BUG: unknown ref type %d of ref %s",
+               BUG("unknown ref type %d of ref %s",
                    ref_type(refname), refname);
        }
 }
@@ -178,7 +180,7 @@ static void files_ref_path(struct files_ref_store *refs,
                strbuf_addf(sb, "%s/%s", refs->gitcommondir, refname);
                break;
        default:
-               die("BUG: unknown ref type %d of ref %s",
+               BUG("unknown ref type %d of ref %s",
                    ref_type(refname), refname);
        }
 }
@@ -2004,7 +2006,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store,
 
        }
        if (!ret && sb.len)
-               die("BUG: reverse reflog parser had leftover data");
+               BUG("reverse reflog parser had leftover data");
 
        fclose(logfp);
        strbuf_release(&sb);
@@ -2082,7 +2084,7 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator)
 static int files_reflog_iterator_peel(struct ref_iterator *ref_iterator,
                                   struct object_id *peeled)
 {
-       die("BUG: ref_iterator_peel() called for reflog_iterator");
+       BUG("ref_iterator_peel() called for reflog_iterator");
 }
 
 static int files_reflog_iterator_abort(struct ref_iterator *ref_iterator)
@@ -2867,7 +2869,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
        assert(err);
 
        if (transaction->state != REF_TRANSACTION_OPEN)
-               die("BUG: commit called for transaction that is not open");
+               BUG("commit called for transaction that is not open");
 
        /* Fail if a refname appears more than once in the transaction: */
        for (i = 0; i < transaction->nr; i++)
@@ -2893,7 +2895,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
         */
        if (refs_for_each_rawref(&refs->base, ref_present,
                                 &affected_refnames))
-               die("BUG: initial ref transaction called with existing refs");
+               BUG("initial ref transaction called with existing refs");
 
        packed_transaction = ref_store_transaction_begin(refs->packed_ref_store, err);
        if (!packed_transaction) {
@@ -2906,7 +2908,7 @@ static int files_initial_transaction_commit(struct ref_store *ref_store,
 
                if ((update->flags & REF_HAVE_OLD) &&
                    !is_null_oid(&update->old_oid))
-                       die("BUG: initial ref transaction with old_sha1 set");
+                       BUG("initial ref transaction with old_sha1 set");
                if (refs_verify_refname_available(&refs->base, update->refname,
                                                  &affected_refnames, NULL,
                                                  err)) {
@@ -2989,7 +2991,7 @@ static int files_reflog_expire(struct ref_store *ref_store,
 {
        struct files_ref_store *refs =
                files_downcast(ref_store, REF_STORE_WRITE, "reflog_expire");
-       static struct lock_file reflog_lock;
+       struct lock_file reflog_lock = LOCK_INIT;
        struct expire_reflog_cb cb;
        struct ref_lock *lock;
        struct strbuf log_file_sb = STRBUF_INIT;
index bd35da4e622ca4016194177ce97594b46c5aafe7..2ac91ac3401c87108b9cdb4983acb7c165df82d9 100644 (file)
@@ -54,7 +54,7 @@ static int empty_ref_iterator_advance(struct ref_iterator *ref_iterator)
 static int empty_ref_iterator_peel(struct ref_iterator *ref_iterator,
                                   struct object_id *peeled)
 {
-       die("BUG: peel called for empty iterator");
+       BUG("peel called for empty iterator");
 }
 
 static int empty_ref_iterator_abort(struct ref_iterator *ref_iterator)
@@ -177,7 +177,7 @@ static int merge_ref_iterator_peel(struct ref_iterator *ref_iterator,
                (struct merge_ref_iterator *)ref_iterator;
 
        if (!iter->current) {
-               die("BUG: peel called before advance for merge iterator");
+               BUG("peel called before advance for merge iterator");
        }
        return ref_iterator_peel(*iter->current, peeled);
 }
@@ -338,7 +338,7 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator)
                         * trimming, report it as a bug:
                         */
                        if (strlen(iter->iter0->refname) <= iter->trim)
-                               die("BUG: attempt to trim too many characters");
+                               BUG("attempt to trim too many characters");
                        iter->base.refname = iter->iter0->refname + iter->trim;
                } else {
                        iter->base.refname = iter->iter0->refname;
index 65288c647278aa27790b13c0360f756686dadf7a..cec3fb9e00f78c1e0be9f24bd07aa756d56afc00 100644 (file)
@@ -5,6 +5,7 @@
 #include "packed-backend.h"
 #include "../iterator.h"
 #include "../lockfile.h"
+#include "../chdir-notify.h"
 
 enum mmap_strategy {
        /*
@@ -202,6 +203,8 @@ struct ref_store *packed_ref_store_create(const char *path,
        refs->store_flags = store_flags;
 
        refs->path = xstrdup(path);
+       chdir_notify_reparent("packed-refs", &refs->path);
+
        return ref_store;
 }
 
@@ -218,13 +221,13 @@ static struct packed_ref_store *packed_downcast(struct ref_store *ref_store,
        struct packed_ref_store *refs;
 
        if (ref_store->be != &refs_be_packed)
-               die("BUG: ref_store is type \"%s\" not \"packed\" in %s",
+               BUG("ref_store is type \"%s\" not \"packed\" in %s",
                    ref_store->be->name, caller);
 
        refs = (struct packed_ref_store *)ref_store;
 
        if ((refs->store_flags & required_flags) != required_flags)
-               die("BUG: unallowed operation (%s), requires %x, has %x\n",
+               BUG("unallowed operation (%s), requires %x, has %x\n",
                    caller, required_flags, refs->store_flags);
 
        return refs;
@@ -1033,7 +1036,7 @@ void packed_refs_unlock(struct ref_store *ref_store)
                        "packed_refs_unlock");
 
        if (!is_lock_file_locked(&refs->lock))
-               die("BUG: packed_refs_unlock() called when not locked");
+               BUG("packed_refs_unlock() called when not locked");
        rollback_lock_file(&refs->lock);
 }
 
@@ -1086,7 +1089,7 @@ static int write_with_updates(struct packed_ref_store *refs,
        char *packed_refs_path;
 
        if (!is_lock_file_locked(&refs->lock))
-               die("BUG: write_with_updates() called while unlocked");
+               BUG("write_with_updates() called while unlocked");
 
        /*
         * If packed-refs is a symlink, we want to overwrite the
@@ -1560,21 +1563,21 @@ static int packed_create_symref(struct ref_store *ref_store,
                               const char *refname, const char *target,
                               const char *logmsg)
 {
-       die("BUG: packed reference store does not support symrefs");
+       BUG("packed reference store does not support symrefs");
 }
 
 static int packed_rename_ref(struct ref_store *ref_store,
                            const char *oldrefname, const char *newrefname,
                            const char *logmsg)
 {
-       die("BUG: packed reference store does not support renaming references");
+       BUG("packed reference store does not support renaming references");
 }
 
 static int packed_copy_ref(struct ref_store *ref_store,
                           const char *oldrefname, const char *newrefname,
                           const char *logmsg)
 {
-       die("BUG: packed reference store does not support copying references");
+       BUG("packed reference store does not support copying references");
 }
 
 static struct ref_iterator *packed_reflog_iterator_begin(struct ref_store *ref_store)
@@ -1607,7 +1610,7 @@ static int packed_create_reflog(struct ref_store *ref_store,
                               const char *refname, int force_create,
                               struct strbuf *err)
 {
-       die("BUG: packed reference store does not support reflogs");
+       BUG("packed reference store does not support reflogs");
 }
 
 static int packed_delete_reflog(struct ref_store *ref_store,
index e90bd3e727fd0fcd5f6a99dde4fbac65b479f411..9b110c8494ff802fea730570f8c8f3b522292dbf 100644 (file)
@@ -23,7 +23,7 @@ struct ref_dir *get_ref_dir(struct ref_entry *entry)
        dir = &entry->u.subdir;
        if (entry->flag & REF_INCOMPLETE) {
                if (!dir->cache->fill_ref_dir)
-                       die("BUG: incomplete ref_store without fill_ref_dir function");
+                       BUG("incomplete ref_store without fill_ref_dir function");
 
                dir->cache->fill_ref_dir(dir->cache->ref_store, dir, entry->name);
                entry->flag &= ~REF_INCOMPLETE;
diff --git a/refspec.c b/refspec.c
new file mode 100644 (file)
index 0000000..78edc48
--- /dev/null
+++ b/refspec.c
@@ -0,0 +1,227 @@
+#include "cache.h"
+#include "argv-array.h"
+#include "refs.h"
+#include "refspec.h"
+
+static struct refspec_item s_tag_refspec = {
+       0,
+       1,
+       0,
+       0,
+       "refs/tags/*",
+       "refs/tags/*"
+};
+
+/* See TAG_REFSPEC for the string version */
+const struct refspec_item *tag_refspec = &s_tag_refspec;
+
+/*
+ * Parses the provided refspec 'refspec' and populates the refspec_item 'item'.
+ * Returns 1 if successful and 0 if the refspec is invalid.
+ */
+static int parse_refspec(struct refspec_item *item, const char *refspec, int fetch)
+{
+       size_t llen;
+       int is_glob;
+       const char *lhs, *rhs;
+       int flags;
+
+       is_glob = 0;
+
+       lhs = refspec;
+       if (*lhs == '+') {
+               item->force = 1;
+               lhs++;
+       }
+
+       rhs = strrchr(lhs, ':');
+
+       /*
+        * Before going on, special case ":" (or "+:") as a refspec
+        * for pushing matching refs.
+        */
+       if (!fetch && rhs == lhs && rhs[1] == '\0') {
+               item->matching = 1;
+               return 1;
+       }
+
+       if (rhs) {
+               size_t rlen = strlen(++rhs);
+               is_glob = (1 <= rlen && strchr(rhs, '*'));
+               item->dst = xstrndup(rhs, rlen);
+       } else {
+               item->dst = NULL;
+       }
+
+       llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
+       if (1 <= llen && memchr(lhs, '*', llen)) {
+               if ((rhs && !is_glob) || (!rhs && fetch))
+                       return 0;
+               is_glob = 1;
+       } else if (rhs && is_glob) {
+               return 0;
+       }
+
+       item->pattern = is_glob;
+       item->src = xstrndup(lhs, llen);
+       flags = REFNAME_ALLOW_ONELEVEL | (is_glob ? REFNAME_REFSPEC_PATTERN : 0);
+
+       if (fetch) {
+               struct object_id unused;
+
+               /* LHS */
+               if (!*item->src)
+                       ; /* empty is ok; it means "HEAD" */
+               else if (llen == GIT_SHA1_HEXSZ && !get_oid_hex(item->src, &unused))
+                       item->exact_sha1 = 1; /* ok */
+               else if (!check_refname_format(item->src, flags))
+                       ; /* valid looking ref is ok */
+               else
+                       return 0;
+               /* RHS */
+               if (!item->dst)
+                       ; /* missing is ok; it is the same as empty */
+               else if (!*item->dst)
+                       ; /* empty is ok; it means "do not store" */
+               else if (!check_refname_format(item->dst, flags))
+                       ; /* valid looking ref is ok */
+               else
+                       return 0;
+       } else {
+               /*
+                * LHS
+                * - empty is allowed; it means delete.
+                * - when wildcarded, it must be a valid looking ref.
+                * - otherwise, it must be an extended SHA-1, but
+                *   there is no existing way to validate this.
+                */
+               if (!*item->src)
+                       ; /* empty is ok */
+               else if (is_glob) {
+                       if (check_refname_format(item->src, flags))
+                               return 0;
+               }
+               else
+                       ; /* anything goes, for now */
+               /*
+                * RHS
+                * - missing is allowed, but LHS then must be a
+                *   valid looking ref.
+                * - empty is not allowed.
+                * - otherwise it must be a valid looking ref.
+                */
+               if (!item->dst) {
+                       if (check_refname_format(item->src, flags))
+                               return 0;
+               } else if (!*item->dst) {
+                       return 0;
+               } else {
+                       if (check_refname_format(item->dst, flags))
+                               return 0;
+               }
+       }
+
+       return 1;
+}
+
+void refspec_item_init(struct refspec_item *item, const char *refspec, int fetch)
+{
+       memset(item, 0, sizeof(*item));
+
+       if (!parse_refspec(item, refspec, fetch))
+               die("Invalid refspec '%s'", refspec);
+}
+
+void refspec_item_clear(struct refspec_item *item)
+{
+       FREE_AND_NULL(item->src);
+       FREE_AND_NULL(item->dst);
+       item->force = 0;
+       item->pattern = 0;
+       item->matching = 0;
+       item->exact_sha1 = 0;
+}
+
+void refspec_init(struct refspec *rs, int fetch)
+{
+       memset(rs, 0, sizeof(*rs));
+       rs->fetch = fetch;
+}
+
+void refspec_append(struct refspec *rs, const char *refspec)
+{
+       struct refspec_item item;
+
+       refspec_item_init(&item, refspec, rs->fetch);
+
+       ALLOC_GROW(rs->items, rs->nr + 1, rs->alloc);
+       rs->items[rs->nr++] = item;
+
+       ALLOC_GROW(rs->raw, rs->raw_nr + 1, rs->raw_alloc);
+       rs->raw[rs->raw_nr++] = xstrdup(refspec);
+}
+
+void refspec_appendn(struct refspec *rs, const char **refspecs, int nr)
+{
+       int i;
+       for (i = 0; i < nr; i++)
+               refspec_append(rs, refspecs[i]);
+}
+
+void refspec_clear(struct refspec *rs)
+{
+       int i;
+
+       for (i = 0; i < rs->nr; i++)
+               refspec_item_clear(&rs->items[i]);
+
+       FREE_AND_NULL(rs->items);
+       rs->alloc = 0;
+       rs->nr = 0;
+
+       for (i = 0; i < rs->raw_nr; i++)
+               free((char *)rs->raw[i]);
+       FREE_AND_NULL(rs->raw);
+       rs->raw_alloc = 0;
+       rs->raw_nr = 0;
+
+       rs->fetch = 0;
+}
+
+int valid_fetch_refspec(const char *fetch_refspec_str)
+{
+       struct refspec_item refspec;
+       int ret = parse_refspec(&refspec, fetch_refspec_str, REFSPEC_FETCH);
+       refspec_item_clear(&refspec);
+       return ret;
+}
+
+void refspec_ref_prefixes(const struct refspec *rs,
+                         struct argv_array *ref_prefixes)
+{
+       int i;
+       for (i = 0; i < rs->nr; i++) {
+               const struct refspec_item *item = &rs->items[i];
+               const char *prefix = NULL;
+
+               if (item->exact_sha1)
+                       continue;
+               if (rs->fetch == REFSPEC_FETCH)
+                       prefix = item->src;
+               else if (item->dst)
+                       prefix = item->dst;
+               else if (item->src && !item->exact_sha1)
+                       prefix = item->src;
+
+               if (prefix) {
+                       if (item->pattern) {
+                               const char *glob = strchr(prefix, '*');
+                               argv_array_pushf(ref_prefixes, "%.*s",
+                                                (int)(glob - prefix),
+                                                prefix);
+                       } else {
+                               expand_ref_prefix(ref_prefixes, prefix);
+                       }
+               }
+       }
+}
diff --git a/refspec.h b/refspec.h
new file mode 100644 (file)
index 0000000..3a93638
--- /dev/null
+++ b/refspec.h
@@ -0,0 +1,52 @@
+#ifndef REFSPEC_H
+#define REFSPEC_H
+
+#define TAG_REFSPEC "refs/tags/*:refs/tags/*"
+extern const struct refspec_item *tag_refspec;
+
+struct refspec_item {
+       unsigned force : 1;
+       unsigned pattern : 1;
+       unsigned matching : 1;
+       unsigned exact_sha1 : 1;
+
+       char *src;
+       char *dst;
+};
+
+#define REFSPEC_FETCH 1
+#define REFSPEC_PUSH 0
+
+#define REFSPEC_INIT_FETCH { .fetch = REFSPEC_FETCH }
+#define REFSPEC_INIT_PUSH { .fetch = REFSPEC_PUSH }
+
+struct refspec {
+       struct refspec_item *items;
+       int alloc;
+       int nr;
+
+       const char **raw;
+       int raw_alloc;
+       int raw_nr;
+
+       int fetch;
+};
+
+void refspec_item_init(struct refspec_item *item, const char *refspec, int fetch);
+void refspec_item_clear(struct refspec_item *item);
+void refspec_init(struct refspec *rs, int fetch);
+void refspec_append(struct refspec *rs, const char *refspec);
+void refspec_appendn(struct refspec *rs, const char **refspecs, int nr);
+void refspec_clear(struct refspec *rs);
+
+int valid_fetch_refspec(const char *refspec);
+
+struct argv_array;
+/*
+ * Determine what <prefix> values to pass to the peer in ref-prefix lines
+ * (see Documentation/technical/protocol-v2.txt).
+ */
+void refspec_ref_prefixes(const struct refspec *rs,
+                         struct argv_array *ref_prefixes);
+
+#endif /* REFSPEC_H */
index a7c4c9b5ff4822e36bfc43a59d113c624537297e..99b0bedc6ddc670cad6e74083dc33dc0aa4b595a 100644 (file)
@@ -1,10 +1,11 @@
 #include "cache.h"
 #include "config.h"
 #include "remote.h"
+#include "connect.h"
 #include "strbuf.h"
 #include "walker.h"
 #include "http.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "run-command.h"
 #include "pkt-line.h"
 #include "string-list.h"
@@ -13,6 +14,7 @@
 #include "credential.h"
 #include "sha1-array.h"
 #include "send-pack.h"
+#include "protocol.h"
 #include "quote.h"
 
 static struct remote *remote;
@@ -184,12 +186,13 @@ static int set_option(const char *name, const char *value)
 }
 
 struct discovery {
-       const char *service;
+       char *service;
        char *buf_alloc;
        char *buf;
        size_t len;
        struct ref *refs;
        struct oid_array shallow;
+       enum protocol_version version;
        unsigned proto_git : 1;
 };
 static struct discovery *last_discovery;
@@ -197,8 +200,31 @@ static struct discovery *last_discovery;
 static struct ref *parse_git_refs(struct discovery *heads, int for_push)
 {
        struct ref *list = NULL;
-       get_remote_heads(-1, heads->buf, heads->len, &list,
-                        for_push ? REF_NORMAL : 0, NULL, &heads->shallow);
+       struct packet_reader reader;
+
+       packet_reader_init(&reader, -1, heads->buf, heads->len,
+                          PACKET_READ_CHOMP_NEWLINE |
+                          PACKET_READ_GENTLE_ON_EOF);
+
+       heads->version = discover_version(&reader);
+       switch (heads->version) {
+       case protocol_v2:
+               /*
+                * Do nothing.  This isn't a list of refs but rather a
+                * capability advertisement.  Client would have run
+                * 'stateless-connect' so we'll dump this capability listing
+                * and let them request the refs themselves.
+                */
+               break;
+       case protocol_v1:
+       case protocol_v0:
+               get_remote_heads(&reader, &list, for_push ? REF_NORMAL : 0,
+                                NULL, &heads->shallow);
+               break;
+       case protocol_unknown_version:
+               BUG("unknown protocol version");
+       }
+
        return list;
 }
 
@@ -259,6 +285,7 @@ static void free_discovery(struct discovery *d)
                free(d->shallow.oid);
                free(d->buf_alloc);
                free_refs(d->refs);
+               free(d->service);
                free(d);
        }
 }
@@ -290,6 +317,19 @@ static int show_http_message(struct strbuf *type, struct strbuf *charset,
        return 0;
 }
 
+static int get_protocol_http_header(enum protocol_version version,
+                                   struct strbuf *header)
+{
+       if (version > 0) {
+               strbuf_addf(header, GIT_PROTOCOL_HEADER ": version=%d",
+                           version);
+
+               return 1;
+       }
+
+       return 0;
+}
+
 static struct discovery *discover_refs(const char *service, int for_push)
 {
        struct strbuf exp = STRBUF_INIT;
@@ -298,9 +338,12 @@ static struct discovery *discover_refs(const char *service, int for_push)
        struct strbuf buffer = STRBUF_INIT;
        struct strbuf refs_url = STRBUF_INIT;
        struct strbuf effective_url = STRBUF_INIT;
+       struct strbuf protocol_header = STRBUF_INIT;
+       struct string_list extra_headers = STRING_LIST_INIT_DUP;
        struct discovery *last = last_discovery;
        int http_ret, maybe_smart = 0;
        struct http_get_options http_options;
+       enum protocol_version version = get_protocol_version_config();
 
        if (last && !strcmp(service, last->service))
                return last;
@@ -317,11 +360,24 @@ static struct discovery *discover_refs(const char *service, int for_push)
                strbuf_addf(&refs_url, "service=%s", service);
        }
 
+       /*
+        * NEEDSWORK: If we are trying to use protocol v2 and we are planning
+        * to perform a push, then fallback to v0 since the client doesn't know
+        * how to push yet using v2.
+        */
+       if (version == protocol_v2 && !strcmp("git-receive-pack", service))
+               version = protocol_v0;
+
+       /* Add the extra Git-Protocol header */
+       if (get_protocol_http_header(version, &protocol_header))
+               string_list_append(&extra_headers, protocol_header.buf);
+
        memset(&http_options, 0, sizeof(http_options));
        http_options.content_type = &type;
        http_options.charset = &charset;
        http_options.effective_url = &effective_url;
        http_options.base_url = &url;
+       http_options.extra_headers = &extra_headers;
        http_options.initial_request = 1;
        http_options.no_cache = 1;
        http_options.keep_error = 1;
@@ -345,7 +401,7 @@ static struct discovery *discover_refs(const char *service, int for_push)
                warning(_("redirecting to %s"), url.buf);
 
        last= xcalloc(1, sizeof(*last_discovery));
-       last->service = service;
+       last->service = xstrdup(service);
        last->buf_alloc = strbuf_detach(&buffer, &last->len);
        last->buf = last->buf_alloc;
 
@@ -377,6 +433,9 @@ static struct discovery *discover_refs(const char *service, int for_push)
                        ;
 
                last->proto_git = 1;
+       } else if (maybe_smart &&
+                  last->len > 5 && starts_with(last->buf + 4, "version 2")) {
+               last->proto_git = 1;
        }
 
        if (last->proto_git)
@@ -390,6 +449,8 @@ static struct discovery *discover_refs(const char *service, int for_push)
        strbuf_release(&charset);
        strbuf_release(&effective_url);
        strbuf_release(&buffer);
+       strbuf_release(&protocol_header);
+       string_list_clear(&extra_headers, 0);
        last_discovery = last;
        return last;
 }
@@ -426,6 +487,7 @@ struct rpc_state {
        char *service_url;
        char *hdr_content_type;
        char *hdr_accept;
+       char *protocol_header;
        char *buf;
        size_t alloc;
        size_t len;
@@ -612,13 +674,17 @@ static int post_rpc(struct rpc_state *rpc)
        headers = curl_slist_append(headers, needs_100_continue ?
                "Expect: 100-continue" : "Expect:");
 
+       /* Add the extra Git-Protocol header */
+       if (rpc->protocol_header)
+               headers = curl_slist_append(headers, rpc->protocol_header);
+
 retry:
        slot = get_active_slot();
 
        curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
        curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
        curl_easy_setopt(slot->curl, CURLOPT_URL, rpc->service_url);
-       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "gzip");
+       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
 
        if (large_request) {
                /* The request body is large and the size cannot be predicted.
@@ -752,6 +818,11 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
        strbuf_addf(&buf, "Accept: application/x-%s-result", svc);
        rpc->hdr_accept = strbuf_detach(&buf, NULL);
 
+       if (get_protocol_http_header(heads->version, &buf))
+               rpc->protocol_header = strbuf_detach(&buf, NULL);
+       else
+               rpc->protocol_header = NULL;
+
        while (!err) {
                int n = packet_read(rpc->out, NULL, NULL, rpc->buf, rpc->alloc, 0);
                if (!n)
@@ -779,6 +850,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads)
        free(rpc->service_url);
        free(rpc->hdr_content_type);
        free(rpc->hdr_accept);
+       free(rpc->protocol_header);
        free(rpc->buf);
        strbuf_release(&buf);
        return err;
@@ -797,9 +869,6 @@ static int fetch_dumb(int nr_heads, struct ref **to_fetch)
                targets[i] = xstrdup(oid_to_hex(&to_fetch[i]->old_oid));
 
        walker = get_http_walker(url.buf);
-       walker->get_all = 1;
-       walker->get_tree = 1;
-       walker->get_history = 1;
        walker->get_verbosely = options.verbosity >= 3;
        walker->get_recover = 0;
        ret = walker_fetch(walker, nr_heads, targets, NULL, NULL);
@@ -1056,6 +1125,203 @@ static void parse_push(struct strbuf *buf)
        free(specs);
 }
 
+/*
+ * Used to represent the state of a connection to an HTTP server when
+ * communicating using git's wire-protocol version 2.
+ */
+struct proxy_state {
+       char *service_name;
+       char *service_url;
+       struct curl_slist *headers;
+       struct strbuf request_buffer;
+       int in;
+       int out;
+       struct packet_reader reader;
+       size_t pos;
+       int seen_flush;
+};
+
+static void proxy_state_init(struct proxy_state *p, const char *service_name,
+                            enum protocol_version version)
+{
+       struct strbuf buf = STRBUF_INIT;
+
+       memset(p, 0, sizeof(*p));
+       p->service_name = xstrdup(service_name);
+
+       p->in = 0;
+       p->out = 1;
+       strbuf_init(&p->request_buffer, 0);
+
+       strbuf_addf(&buf, "%s%s", url.buf, p->service_name);
+       p->service_url = strbuf_detach(&buf, NULL);
+
+       p->headers = http_copy_default_headers();
+
+       strbuf_addf(&buf, "Content-Type: application/x-%s-request", p->service_name);
+       p->headers = curl_slist_append(p->headers, buf.buf);
+       strbuf_reset(&buf);
+
+       strbuf_addf(&buf, "Accept: application/x-%s-result", p->service_name);
+       p->headers = curl_slist_append(p->headers, buf.buf);
+       strbuf_reset(&buf);
+
+       p->headers = curl_slist_append(p->headers, "Transfer-Encoding: chunked");
+
+       /* Add the Git-Protocol header */
+       if (get_protocol_http_header(version, &buf))
+               p->headers = curl_slist_append(p->headers, buf.buf);
+
+       packet_reader_init(&p->reader, p->in, NULL, 0,
+                          PACKET_READ_GENTLE_ON_EOF);
+
+       strbuf_release(&buf);
+}
+
+static void proxy_state_clear(struct proxy_state *p)
+{
+       free(p->service_name);
+       free(p->service_url);
+       curl_slist_free_all(p->headers);
+       strbuf_release(&p->request_buffer);
+}
+
+/*
+ * CURLOPT_READFUNCTION callback function.
+ * Attempts to copy over a single packet-line at a time into the
+ * curl provided buffer.
+ */
+static size_t proxy_in(char *buffer, size_t eltsize,
+                      size_t nmemb, void *userdata)
+{
+       size_t max;
+       struct proxy_state *p = userdata;
+       size_t avail = p->request_buffer.len - p->pos;
+
+
+       if (eltsize != 1)
+               BUG("curl read callback called with size = %"PRIuMAX" != 1",
+                   (uintmax_t)eltsize);
+       max = nmemb;
+
+       if (!avail) {
+               if (p->seen_flush) {
+                       p->seen_flush = 0;
+                       return 0;
+               }
+
+               strbuf_reset(&p->request_buffer);
+               switch (packet_reader_read(&p->reader)) {
+               case PACKET_READ_EOF:
+                       die("unexpected EOF when reading from parent process");
+               case PACKET_READ_NORMAL:
+                       packet_buf_write_len(&p->request_buffer, p->reader.line,
+                                            p->reader.pktlen);
+                       break;
+               case PACKET_READ_DELIM:
+                       packet_buf_delim(&p->request_buffer);
+                       break;
+               case PACKET_READ_FLUSH:
+                       packet_buf_flush(&p->request_buffer);
+                       p->seen_flush = 1;
+                       break;
+               }
+               p->pos = 0;
+               avail = p->request_buffer.len;
+       }
+
+       if (max < avail)
+               avail = max;
+       memcpy(buffer, p->request_buffer.buf + p->pos, avail);
+       p->pos += avail;
+       return avail;
+}
+
+static size_t proxy_out(char *buffer, size_t eltsize,
+                       size_t nmemb, void *userdata)
+{
+       size_t size;
+       struct proxy_state *p = userdata;
+
+       if (eltsize != 1)
+               BUG("curl read callback called with size = %"PRIuMAX" != 1",
+                   (uintmax_t)eltsize);
+       size = nmemb;
+
+       write_or_die(p->out, buffer, size);
+       return size;
+}
+
+/* Issues a request to the HTTP server configured in `p` */
+static int proxy_request(struct proxy_state *p)
+{
+       struct active_request_slot *slot;
+
+       slot = get_active_slot();
+
+       curl_easy_setopt(slot->curl, CURLOPT_ENCODING, "");
+       curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0);
+       curl_easy_setopt(slot->curl, CURLOPT_POST, 1);
+       curl_easy_setopt(slot->curl, CURLOPT_URL, p->service_url);
+       curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, p->headers);
+
+       /* Setup function to read request from client */
+       curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, proxy_in);
+       curl_easy_setopt(slot->curl, CURLOPT_READDATA, p);
+
+       /* Setup function to write server response to client */
+       curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, proxy_out);
+       curl_easy_setopt(slot->curl, CURLOPT_WRITEDATA, p);
+
+       if (run_slot(slot, NULL) != HTTP_OK)
+               return -1;
+
+       return 0;
+}
+
+static int stateless_connect(const char *service_name)
+{
+       struct discovery *discover;
+       struct proxy_state p;
+
+       /*
+        * Run the info/refs request and see if the server supports protocol
+        * v2.  If and only if the server supports v2 can we successfully
+        * establish a stateless connection, otherwise we need to tell the
+        * client to fallback to using other transport helper functions to
+        * complete their request.
+        */
+       discover = discover_refs(service_name, 0);
+       if (discover->version != protocol_v2) {
+               printf("fallback\n");
+               fflush(stdout);
+               return -1;
+       } else {
+               /* Stateless Connection established */
+               printf("\n");
+               fflush(stdout);
+       }
+
+       proxy_state_init(&p, service_name, discover->version);
+
+       /*
+        * Dump the capability listing that we got from the server earlier
+        * during the info/refs request.
+        */
+       write_or_die(p.out, discover->buf, discover->len);
+
+       /* Peek the next packet line.  Until we see EOF keep sending POSTs */
+       while (packet_reader_peek(&p.reader) != PACKET_READ_EOF) {
+               if (proxy_request(&p)) {
+                       /* We would have an err here */
+                       break;
+               }
+       }
+
+       proxy_state_clear(&p);
+       return 0;
+}
+
 int cmd_main(int argc, const char **argv)
 {
        struct strbuf buf = STRBUF_INIT;
@@ -1124,12 +1390,16 @@ int cmd_main(int argc, const char **argv)
                        fflush(stdout);
 
                } else if (!strcmp(buf.buf, "capabilities")) {
+                       printf("stateless-connect\n");
                        printf("fetch\n");
                        printf("option\n");
                        printf("push\n");
                        printf("check-connectivity\n");
                        printf("\n");
                        fflush(stdout);
+               } else if (skip_prefix(buf.buf, "stateless-connect ", &arg)) {
+                       if (!stateless_connect(arg))
+                               break;
                } else {
                        error("remote-curl: unknown command '%s' from git", buf.buf);
                        return 1;
index bcebb4c789567eb4017a3a0132ba55c59c427991..444d98059f681e21beeb3e66fe8539887cfb74d1 100644 (file)
@@ -3,7 +3,7 @@
 #include "remote.h"
 #include "strbuf.h"
 #include "url.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "run-command.h"
 #include "vcs-svn/svndump.h"
 #include "notes.h"
@@ -61,7 +61,7 @@ static char *read_ref_note(const struct object_id *oid)
        init_notes(NULL, notes_ref, NULL, 0);
        if (!(note_oid = get_note(NULL, oid)))
                return NULL;    /* note tree not found */
-       if (!(msg = read_sha1_file(note_oid->hash, &type, &msglen)))
+       if (!(msg = read_object_file(note_oid, &type, &msglen)))
                error("Empty notes tree. %s", notes_ref);
        else if (!msglen || type != OBJ_BLOB) {
                error("Note contains unusable content. "
@@ -108,7 +108,7 @@ static int note2mark_cb(const struct object_id *object_oid,
        enum object_type type;
        struct rev_note note;
 
-       if (!(msg = read_sha1_file(note_oid->hash, &type, &msglen)) ||
+       if (!(msg = read_object_file(note_oid, &type, &msglen)) ||
                        !msglen || type != OBJ_BLOB) {
                free(msg);
                return 1;
index c10d87c24615e9d6497b46a69a82a71d3c1735a6..abe80c13972c718bd5d738063a2f526f2d12ee87 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -2,6 +2,7 @@
 #include "config.h"
 #include "remote.h"
 #include "refs.h"
+#include "refspec.h"
 #include "commit.h"
 #include "diff.h"
 #include "revision.h"
 
 enum map_direction { FROM_SRC, FROM_DST };
 
-static struct refspec s_tag_refspec = {
-       0,
-       1,
-       0,
-       0,
-       "refs/tags/*",
-       "refs/tags/*"
-};
-
-/* See TAG_REFSPEC for the string version */
-const struct refspec *tag_refspec = &s_tag_refspec;
-
 struct counted_string {
        size_t len;
        const char *s;
@@ -88,33 +77,6 @@ static const char *alias_url(const char *url, struct rewrites *r)
        return xstrfmt("%s%s", r->rewrite[longest_i]->base, url + longest->len);
 }
 
-static void add_push_refspec(struct remote *remote, const char *ref)
-{
-       ALLOC_GROW(remote->push_refspec,
-                  remote->push_refspec_nr + 1,
-                  remote->push_refspec_alloc);
-       remote->push_refspec[remote->push_refspec_nr++] = ref;
-}
-
-static void add_fetch_refspec(struct remote *remote, const char *ref)
-{
-       ALLOC_GROW(remote->fetch_refspec,
-                  remote->fetch_refspec_nr + 1,
-                  remote->fetch_refspec_alloc);
-       remote->fetch_refspec[remote->fetch_refspec_nr++] = ref;
-}
-
-void add_prune_tags_to_fetch_refspec(struct remote *remote)
-{
-       int nr = remote->fetch_refspec_nr;
-       int bufsize = nr  + 1;
-       int size = sizeof(struct refspec);
-
-       remote->fetch = xrealloc(remote->fetch, size  * bufsize);
-       memcpy(&remote->fetch[nr], tag_refspec, size);
-       add_fetch_refspec(remote, xstrdup(TAG_REFSPEC));
-}
-
 static void add_url(struct remote *remote, const char *url)
 {
        ALLOC_GROW(remote->url, remote->url_nr + 1, remote->url_alloc);
@@ -186,9 +148,12 @@ static struct remote *make_remote(const char *name, int len)
        ret = xcalloc(1, sizeof(struct remote));
        ret->prune = -1;  /* unspecified */
        ret->prune_tags = -1;  /* unspecified */
+       ret->name = xstrndup(name, len);
+       refspec_init(&ret->push, REFSPEC_PUSH);
+       refspec_init(&ret->fetch, REFSPEC_FETCH);
+
        ALLOC_GROW(remotes, remotes_nr + 1, remotes_alloc);
        remotes[remotes_nr++] = ret;
-       ret->name = xstrndup(name, len);
 
        hashmap_entry_init(ret, lookup_entry.hash);
        replaced = hashmap_put(&remotes_hash, ret);
@@ -286,9 +251,9 @@ static void read_remotes_file(struct remote *remote)
                if (skip_prefix(buf.buf, "URL:", &v))
                        add_url_alias(remote, xstrdup(skip_spaces(v)));
                else if (skip_prefix(buf.buf, "Push:", &v))
-                       add_push_refspec(remote, xstrdup(skip_spaces(v)));
+                       refspec_append(&remote->push, skip_spaces(v));
                else if (skip_prefix(buf.buf, "Pull:", &v))
-                       add_fetch_refspec(remote, xstrdup(skip_spaces(v)));
+                       refspec_append(&remote->fetch, skip_spaces(v));
        }
        strbuf_release(&buf);
        fclose(f);
@@ -327,15 +292,19 @@ static void read_branches_file(struct remote *remote)
                frag = "master";
 
        add_url_alias(remote, strbuf_detach(&buf, NULL));
-       add_fetch_refspec(remote, xstrfmt("refs/heads/%s:refs/heads/%s",
-                                         frag, remote->name));
+       strbuf_addf(&buf, "refs/heads/%s:refs/heads/%s",
+                   frag, remote->name);
+       refspec_append(&remote->fetch, buf.buf);
 
        /*
         * Cogito compatible push: push current HEAD to remote #branch
         * (master if missing)
         */
-       add_push_refspec(remote, xstrfmt("HEAD:refs/heads/%s", frag));
+       strbuf_reset(&buf);
+       strbuf_addf(&buf, "HEAD:refs/heads/%s", frag);
+       refspec_append(&remote->push, buf.buf);
        remote->fetch_tags = 1; /* always auto-follow */
+       strbuf_release(&buf);
 }
 
 static int handle_config(const char *key, const char *value, void *cb)
@@ -420,12 +389,14 @@ static int handle_config(const char *key, const char *value, void *cb)
                const char *v;
                if (git_config_string(&v, key, value))
                        return -1;
-               add_push_refspec(remote, v);
+               refspec_append(&remote->push, v);
+               free((char *)v);
        } else if (!strcmp(subkey, "fetch")) {
                const char *v;
                if (git_config_string(&v, key, value))
                        return -1;
-               add_fetch_refspec(remote, v);
+               refspec_append(&remote->fetch, v);
+               free((char *)v);
        } else if (!strcmp(subkey, "receivepack")) {
                const char *v;
                if (git_config_string(&v, key, value))
@@ -499,158 +470,6 @@ static void read_config(void)
        alias_all_urls();
 }
 
-static struct refspec *parse_refspec_internal(int nr_refspec, const char **refspec, int fetch, int verify)
-{
-       int i;
-       struct refspec *rs = xcalloc(nr_refspec, sizeof(*rs));
-
-       for (i = 0; i < nr_refspec; i++) {
-               size_t llen;
-               int is_glob;
-               const char *lhs, *rhs;
-               int flags;
-
-               is_glob = 0;
-
-               lhs = refspec[i];
-               if (*lhs == '+') {
-                       rs[i].force = 1;
-                       lhs++;
-               }
-
-               rhs = strrchr(lhs, ':');
-
-               /*
-                * Before going on, special case ":" (or "+:") as a refspec
-                * for pushing matching refs.
-                */
-               if (!fetch && rhs == lhs && rhs[1] == '\0') {
-                       rs[i].matching = 1;
-                       continue;
-               }
-
-               if (rhs) {
-                       size_t rlen = strlen(++rhs);
-                       is_glob = (1 <= rlen && strchr(rhs, '*'));
-                       rs[i].dst = xstrndup(rhs, rlen);
-               }
-
-               llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
-               if (1 <= llen && memchr(lhs, '*', llen)) {
-                       if ((rhs && !is_glob) || (!rhs && fetch))
-                               goto invalid;
-                       is_glob = 1;
-               } else if (rhs && is_glob) {
-                       goto invalid;
-               }
-
-               rs[i].pattern = is_glob;
-               rs[i].src = xstrndup(lhs, llen);
-               flags = REFNAME_ALLOW_ONELEVEL | (is_glob ? REFNAME_REFSPEC_PATTERN : 0);
-
-               if (fetch) {
-                       struct object_id unused;
-
-                       /* LHS */
-                       if (!*rs[i].src)
-                               ; /* empty is ok; it means "HEAD" */
-                       else if (llen == GIT_SHA1_HEXSZ && !get_oid_hex(rs[i].src, &unused))
-                               rs[i].exact_sha1 = 1; /* ok */
-                       else if (!check_refname_format(rs[i].src, flags))
-                               ; /* valid looking ref is ok */
-                       else
-                               goto invalid;
-                       /* RHS */
-                       if (!rs[i].dst)
-                               ; /* missing is ok; it is the same as empty */
-                       else if (!*rs[i].dst)
-                               ; /* empty is ok; it means "do not store" */
-                       else if (!check_refname_format(rs[i].dst, flags))
-                               ; /* valid looking ref is ok */
-                       else
-                               goto invalid;
-               } else {
-                       /*
-                        * LHS
-                        * - empty is allowed; it means delete.
-                        * - when wildcarded, it must be a valid looking ref.
-                        * - otherwise, it must be an extended SHA-1, but
-                        *   there is no existing way to validate this.
-                        */
-                       if (!*rs[i].src)
-                               ; /* empty is ok */
-                       else if (is_glob) {
-                               if (check_refname_format(rs[i].src, flags))
-                                       goto invalid;
-                       }
-                       else
-                               ; /* anything goes, for now */
-                       /*
-                        * RHS
-                        * - missing is allowed, but LHS then must be a
-                        *   valid looking ref.
-                        * - empty is not allowed.
-                        * - otherwise it must be a valid looking ref.
-                        */
-                       if (!rs[i].dst) {
-                               if (check_refname_format(rs[i].src, flags))
-                                       goto invalid;
-                       } else if (!*rs[i].dst) {
-                               goto invalid;
-                       } else {
-                               if (check_refname_format(rs[i].dst, flags))
-                                       goto invalid;
-                       }
-               }
-       }
-       return rs;
-
- invalid:
-       if (verify) {
-               /*
-                * nr_refspec must be greater than zero and i must be valid
-                * since it is only possible to reach this point from within
-                * the for loop above.
-                */
-               free_refspec(i+1, rs);
-               return NULL;
-       }
-       die("Invalid refspec '%s'", refspec[i]);
-}
-
-int valid_fetch_refspec(const char *fetch_refspec_str)
-{
-       struct refspec *refspec;
-
-       refspec = parse_refspec_internal(1, &fetch_refspec_str, 1, 1);
-       free_refspec(1, refspec);
-       return !!refspec;
-}
-
-struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec)
-{
-       return parse_refspec_internal(nr_refspec, refspec, 1, 0);
-}
-
-struct refspec *parse_push_refspec(int nr_refspec, const char **refspec)
-{
-       return parse_refspec_internal(nr_refspec, refspec, 0, 0);
-}
-
-void free_refspec(int nr_refspec, struct refspec *refspec)
-{
-       int i;
-
-       if (!refspec)
-               return;
-
-       for (i = 0; i < nr_refspec; i++) {
-               free(refspec[i].src);
-               free(refspec[i].dst);
-       }
-       free(refspec);
-}
-
 static int valid_remote_nick(const char *name)
 {
        if (!name[0] || is_dot_or_dotdot(name))
@@ -705,9 +524,8 @@ const char *remote_ref_for_branch(struct branch *branch, int for_push,
                                pushremote_for_branch(branch, NULL);
                        struct remote *remote = remote_get(remote_name);
 
-                       if (remote && remote->push_refspec_nr &&
-                           (dst = apply_refspecs(remote->push,
-                                                 remote->push_refspec_nr,
+                       if (remote && remote->push.nr &&
+                           (dst = apply_refspecs(&remote->push,
                                                  branch->refname))) {
                                if (explicit)
                                        *explicit = 1;
@@ -744,8 +562,6 @@ static struct remote *remote_get_1(const char *name,
                add_url_alias(ret, name);
        if (!valid_remote(ret))
                return NULL;
-       ret->fetch = parse_fetch_refspec(ret->fetch_refspec_nr, ret->fetch_refspec);
-       ret->push = parse_push_refspec(ret->push_refspec_nr, ret->push_refspec);
        return ret;
 }
 
@@ -776,12 +592,6 @@ int for_each_remote(each_remote_fn fn, void *priv)
                struct remote *r = remotes[i];
                if (!r)
                        continue;
-               if (!r->fetch)
-                       r->fetch = parse_fetch_refspec(r->fetch_refspec_nr,
-                                                      r->fetch_refspec);
-               if (!r->push)
-                       r->push = parse_push_refspec(r->push_refspec_nr,
-                                                    r->push_refspec);
                result = fn(r, priv);
        }
        return result;
@@ -887,7 +697,9 @@ static int match_name_with_pattern(const char *key, const char *name,
        return ret;
 }
 
-static void query_refspecs_multiple(struct refspec *refs, int ref_count, struct refspec *query, struct string_list *results)
+static void query_refspecs_multiple(struct refspec *rs,
+                                   struct refspec_item *query,
+                                   struct string_list *results)
 {
        int i;
        int find_src = !query->src;
@@ -895,8 +707,8 @@ static void query_refspecs_multiple(struct refspec *refs, int ref_count, struct
        if (find_src && !query->dst)
                error("query_refspecs_multiple: need either src or dst");
 
-       for (i = 0; i < ref_count; i++) {
-               struct refspec *refspec = &refs[i];
+       for (i = 0; i < rs->nr; i++) {
+               struct refspec_item *refspec = &rs->items[i];
                const char *key = find_src ? refspec->dst : refspec->src;
                const char *value = find_src ? refspec->src : refspec->dst;
                const char *needle = find_src ? query->dst : query->src;
@@ -913,7 +725,7 @@ static void query_refspecs_multiple(struct refspec *refs, int ref_count, struct
        }
 }
 
-int query_refspecs(struct refspec *refs, int ref_count, struct refspec *query)
+int query_refspecs(struct refspec *rs, struct refspec_item *query)
 {
        int i;
        int find_src = !query->src;
@@ -923,8 +735,8 @@ int query_refspecs(struct refspec *refs, int ref_count, struct refspec *query)
        if (find_src && !query->dst)
                return error("query_refspecs: need either src or dst");
 
-       for (i = 0; i < ref_count; i++) {
-               struct refspec *refspec = &refs[i];
+       for (i = 0; i < rs->nr; i++) {
+               struct refspec_item *refspec = &rs->items[i];
                const char *key = find_src ? refspec->dst : refspec->src;
                const char *value = find_src ? refspec->src : refspec->dst;
 
@@ -944,23 +756,22 @@ int query_refspecs(struct refspec *refs, int ref_count, struct refspec *query)
        return -1;
 }
 
-char *apply_refspecs(struct refspec *refspecs, int nr_refspec,
-                    const char *name)
+char *apply_refspecs(struct refspec *rs, const char *name)
 {
-       struct refspec query;
+       struct refspec_item query;
 
-       memset(&query, 0, sizeof(struct refspec));
+       memset(&query, 0, sizeof(struct refspec_item));
        query.src = (char *)name;
 
-       if (query_refspecs(refspecs, nr_refspec, &query))
+       if (query_refspecs(rs, &query))
                return NULL;
 
        return query.dst;
 }
 
-int remote_find_tracking(struct remote *remote, struct refspec *refspec)
+int remote_find_tracking(struct remote *remote, struct refspec_item *refspec)
 {
-       return query_refspecs(remote->fetch, remote->fetch_refspec_nr, refspec);
+       return query_refspecs(&remote->fetch, refspec);
 }
 
 static struct ref *alloc_ref_with_prefix(const char *prefix, size_t prefixlen,
@@ -1167,7 +978,7 @@ static char *guess_ref(const char *name, struct ref *peer)
 }
 
 static int match_explicit_lhs(struct ref *src,
-                             struct refspec *rs,
+                             struct refspec_item *rs,
                              struct ref **match,
                              int *allocated_match)
 {
@@ -1193,7 +1004,7 @@ static int match_explicit_lhs(struct ref *src,
 
 static int match_explicit(struct ref *src, struct ref *dst,
                          struct ref ***dst_tail,
-                         struct refspec *rs)
+                         struct refspec_item *rs)
 {
        struct ref *matched_src, *matched_dst;
        int allocated_src;
@@ -1262,36 +1073,37 @@ static int match_explicit(struct ref *src, struct ref *dst,
 }
 
 static int match_explicit_refs(struct ref *src, struct ref *dst,
-                              struct ref ***dst_tail, struct refspec *rs,
-                              int rs_nr)
+                              struct ref ***dst_tail, struct refspec *rs)
 {
        int i, errs;
-       for (i = errs = 0; i < rs_nr; i++)
-               errs += match_explicit(src, dst, dst_tail, &rs[i]);
+       for (i = errs = 0; i < rs->nr; i++)
+               errs += match_explicit(src, dst, dst_tail, &rs->items[i]);
        return errs;
 }
 
-static char *get_ref_match(const struct refspec *rs, int rs_nr, const struct ref *ref,
-               int send_mirror, int direction, const struct refspec **ret_pat)
+static char *get_ref_match(const struct refspec *rs, const struct ref *ref,
+                          int send_mirror, int direction,
+                          const struct refspec_item **ret_pat)
 {
-       const struct refspec *pat;
+       const struct refspec_item *pat;
        char *name;
        int i;
        int matching_refs = -1;
-       for (i = 0; i < rs_nr; i++) {
-               if (rs[i].matching &&
-                   (matching_refs == -1 || rs[i].force)) {
+       for (i = 0; i < rs->nr; i++) {
+               const struct refspec_item *item = &rs->items[i];
+               if (item->matching &&
+                   (matching_refs == -1 || item->force)) {
                        matching_refs = i;
                        continue;
                }
 
-               if (rs[i].pattern) {
-                       const char *dst_side = rs[i].dst ? rs[i].dst : rs[i].src;
+               if (item->pattern) {
+                       const char *dst_side = item->dst ? item->dst : item->src;
                        int match;
                        if (direction == FROM_SRC)
-                               match = match_name_with_pattern(rs[i].src, ref->name, dst_side, &name);
+                               match = match_name_with_pattern(item->src, ref->name, dst_side, &name);
                        else
-                               match = match_name_with_pattern(dst_side, ref->name, rs[i].src, &name);
+                               match = match_name_with_pattern(dst_side, ref->name, item->src, &name);
                        if (match) {
                                matching_refs = i;
                                break;
@@ -1301,7 +1113,7 @@ static char *get_ref_match(const struct refspec *rs, int rs_nr, const struct ref
        if (matching_refs == -1)
                return NULL;
 
-       pat = rs + matching_refs;
+       pat = &rs->items[matching_refs];
        if (pat->matching) {
                /*
                 * "matching refs"; traditionally we pushed everything
@@ -1376,7 +1188,7 @@ static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***ds
                        continue; /* not a tag */
                if (string_list_has_string(&dst_tag, ref->name))
                        continue; /* they already have it */
-               if (sha1_object_info(ref->new_oid.hash, NULL) != OBJ_TAG)
+               if (oid_object_info(the_repository, &ref->new_oid, NULL) != OBJ_TAG)
                        continue; /* be conservative */
                item = string_list_append(&src_tag, ref->name);
                item->util = ref;
@@ -1443,22 +1255,20 @@ static void prepare_ref_index(struct string_list *ref_index, struct ref *ref)
  * but we can catch some errors early before even talking to the
  * remote side.
  */
-int check_push_refs(struct ref *src, int nr_refspec, const char **refspec_names)
+int check_push_refs(struct ref *src, struct refspec *rs)
 {
-       struct refspec *refspec = parse_push_refspec(nr_refspec, refspec_names);
        int ret = 0;
        int i;
 
-       for (i = 0; i < nr_refspec; i++) {
-               struct refspec *rs = refspec + i;
+       for (i = 0; i < rs->nr; i++) {
+               struct refspec_item *item = &rs->items[i];
 
-               if (rs->pattern || rs->matching)
+               if (item->pattern || item->matching)
                        continue;
 
-               ret |= match_explicit_lhs(src, rs, NULL, NULL);
+               ret |= match_explicit_lhs(src, item, NULL, NULL);
        }
 
-       free_refspec(nr_refspec, refspec);
        return ret;
 }
 
@@ -1471,32 +1281,29 @@ int check_push_refs(struct ref *src, int nr_refspec, const char **refspec_names)
  * dst (e.g. pushing to a new branch, done in match_explicit_refs).
  */
 int match_push_refs(struct ref *src, struct ref **dst,
-                   int nr_refspec, const char **refspec, int flags)
+                   struct refspec *rs, int flags)
 {
-       struct refspec *rs;
        int send_all = flags & MATCH_REFS_ALL;
        int send_mirror = flags & MATCH_REFS_MIRROR;
        int send_prune = flags & MATCH_REFS_PRUNE;
        int errs;
-       static const char *default_refspec[] = { ":", NULL };
        struct ref *ref, **dst_tail = tail_ref(dst);
        struct string_list dst_ref_index = STRING_LIST_INIT_NODUP;
 
-       if (!nr_refspec) {
-               nr_refspec = 1;
-               refspec = default_refspec;
-       }
-       rs = parse_push_refspec(nr_refspec, (const char **) refspec);
-       errs = match_explicit_refs(src, *dst, &dst_tail, rs, nr_refspec);
+       /* If no refspec is provided, use the default ":" */
+       if (!rs->nr)
+               refspec_append(rs, ":");
+
+       errs = match_explicit_refs(src, *dst, &dst_tail, rs);
 
        /* pick the remainder */
        for (ref = src; ref; ref = ref->next) {
                struct string_list_item *dst_item;
                struct ref *dst_peer;
-               const struct refspec *pat = NULL;
+               const struct refspec_item *pat = NULL;
                char *dst_name;
 
-               dst_name = get_ref_match(rs, nr_refspec, ref, send_mirror, FROM_SRC, &pat);
+               dst_name = get_ref_match(rs, ref, send_mirror, FROM_SRC, &pat);
                if (!dst_name)
                        continue;
 
@@ -1545,7 +1352,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
                                /* We're already sending something to this ref. */
                                continue;
 
-                       src_name = get_ref_match(rs, nr_refspec, ref, send_mirror, FROM_DST, NULL);
+                       src_name = get_ref_match(rs, ref, send_mirror, FROM_DST, NULL);
                        if (src_name) {
                                if (!src_ref_index.nr)
                                        prepare_ref_index(&src_ref_index, src);
@@ -1557,6 +1364,7 @@ int match_push_refs(struct ref *src, struct ref **dst,
                }
                string_list_clear(&src_ref_index, 0);
        }
+
        if (errs)
                return -1;
        return 0;
@@ -1753,7 +1561,7 @@ static const char *tracking_for_push_dest(struct remote *remote,
 {
        char *ret;
 
-       ret = apply_refspecs(remote->fetch, remote->fetch_refspec_nr, refname);
+       ret = apply_refspecs(&remote->fetch, refname);
        if (!ret)
                return error_buf(err,
                                 _("push destination '%s' on remote '%s' has no local tracking branch"),
@@ -1771,12 +1579,11 @@ static const char *branch_get_push_1(struct branch *branch, struct strbuf *err)
                                 _("branch '%s' has no remote for pushing"),
                                 branch->name);
 
-       if (remote->push_refspec_nr) {
+       if (remote->push.nr) {
                char *dst;
                const char *ret;
 
-               dst = apply_refspecs(remote->push, remote->push_refspec_nr,
-                                    branch->refname);
+               dst = apply_refspecs(&remote->push, branch->refname);
                if (!dst)
                        return error_buf(err,
                                         _("push refspecs for '%s' do not include '%s'"),
@@ -1819,7 +1626,7 @@ static const char *branch_get_push_1(struct branch *branch, struct strbuf *err)
                }
        }
 
-       die("BUG: unhandled push situation");
+       BUG("unhandled push situation");
 }
 
 const char *branch_get_push(struct branch *branch, struct strbuf *err)
@@ -1849,7 +1656,7 @@ static int ignore_symref_update(const char *refname)
  * local symbolic ref.
  */
 static struct ref *get_expanded_map(const struct ref *remote_refs,
-                                   const struct refspec *refspec)
+                                   const struct refspec_item *refspec)
 {
        const struct ref *ref;
        struct ref *ret = NULL;
@@ -1914,7 +1721,7 @@ static struct ref *get_local_ref(const char *name)
 }
 
 int get_fetch_map(const struct ref *remote_refs,
-                 const struct refspec *refspec,
+                 const struct refspec_item *refspec,
                  struct ref ***tail,
                  int missing_ok)
 {
@@ -2252,8 +2059,7 @@ struct ref *guess_remote_head(const struct ref *head,
 struct stale_heads_info {
        struct string_list *ref_names;
        struct ref **stale_refs_tail;
-       struct refspec *refs;
-       int ref_count;
+       struct refspec *rs;
 };
 
 static int get_stale_heads_cb(const char *refname, const struct object_id *oid,
@@ -2261,12 +2067,12 @@ static int get_stale_heads_cb(const char *refname, const struct object_id *oid,
 {
        struct stale_heads_info *info = cb_data;
        struct string_list matches = STRING_LIST_INIT_DUP;
-       struct refspec query;
+       struct refspec_item query;
        int i, stale = 1;
-       memset(&query, 0, sizeof(struct refspec));
+       memset(&query, 0, sizeof(struct refspec_item));
        query.dst = (char *)refname;
 
-       query_refspecs_multiple(info->refs, info->ref_count, &query, &matches);
+       query_refspecs_multiple(info->rs, &query, &matches);
        if (matches.nr == 0)
                goto clean_exit; /* No matches */
 
@@ -2294,7 +2100,7 @@ clean_exit:
        return 0;
 }
 
-struct ref *get_stale_heads(struct refspec *refs, int ref_count, struct ref *fetch_map)
+struct ref *get_stale_heads(struct refspec *rs, struct ref *fetch_map)
 {
        struct ref *ref, *stale_refs = NULL;
        struct string_list ref_names = STRING_LIST_INIT_NODUP;
@@ -2302,8 +2108,7 @@ struct ref *get_stale_heads(struct refspec *refs, int ref_count, struct ref *fet
 
        info.ref_names = &ref_names;
        info.stale_refs_tail = &stale_refs;
-       info.refs = refs;
-       info.ref_count = ref_count;
+       info.rs = rs;
        for (ref = fetch_map; ref; ref = ref->next)
                string_list_append(&ref_names, ref->name);
        string_list_sort(&ref_names);
@@ -2387,7 +2192,7 @@ static int remote_tracking(struct remote *remote, const char *refname,
 {
        char *dst;
 
-       dst = apply_refspecs(remote->fetch, remote->fetch_refspec_nr, refname);
+       dst = apply_refspecs(&remote->fetch, refname);
        if (!dst)
                return -1; /* no tracking ref for refname at remote */
        if (read_ref(dst, oid))
index f09c01969d6b0d701140ceb9cb2e8f9e68533c96..45ecc6cefafdea435d0fee39691f7458b940b877 100644 (file)
--- a/remote.h
+++ b/remote.h
@@ -3,6 +3,7 @@
 
 #include "parse-options.h"
 #include "hashmap.h"
+#include "refspec.h"
 
 enum {
        REMOTE_UNCONFIGURED = 0,
@@ -27,15 +28,9 @@ struct remote {
        int pushurl_nr;
        int pushurl_alloc;
 
-       const char **push_refspec;
-       struct refspec *push;
-       int push_refspec_nr;
-       int push_refspec_alloc;
+       struct refspec push;
 
-       const char **fetch_refspec;
-       struct refspec *fetch;
-       int fetch_refspec_nr;
-       int fetch_refspec_alloc;
+       struct refspec fetch;
 
        /*
         * -1 to never fetch tags
@@ -68,18 +63,6 @@ int for_each_remote(each_remote_fn fn, void *priv);
 
 int remote_has_url(struct remote *remote, const char *url);
 
-struct refspec {
-       unsigned force : 1;
-       unsigned pattern : 1;
-       unsigned matching : 1;
-       unsigned exact_sha1 : 1;
-
-       char *src;
-       char *dst;
-};
-
-extern const struct refspec *tag_refspec;
-
 struct ref {
        struct ref *next;
        struct object_id old_oid;
@@ -151,10 +134,19 @@ int check_ref_type(const struct ref *ref, int flags);
 void free_refs(struct ref *ref);
 
 struct oid_array;
-extern struct ref **get_remote_heads(int in, char *src_buf, size_t src_len,
+struct packet_reader;
+struct argv_array;
+struct string_list;
+extern struct ref **get_remote_heads(struct packet_reader *reader,
                                     struct ref **list, unsigned int flags,
                                     struct oid_array *extra_have,
-                                    struct oid_array *shallow);
+                                    struct oid_array *shallow_points);
+
+/* Used for protocol v2 in order to retrieve refs from a remote */
+extern struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
+                                   struct ref **list, int for_push,
+                                   const struct argv_array *ref_prefixes,
+                                   const struct string_list *server_options);
 
 int resolve_remote_symref(struct ref *ref, struct ref *list);
 int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid);
@@ -168,19 +160,12 @@ int ref_newer(const struct object_id *new_oid, const struct object_id *old_oid);
  */
 struct ref *ref_remove_duplicates(struct ref *ref_map);
 
-int valid_fetch_refspec(const char *refspec);
-struct refspec *parse_fetch_refspec(int nr_refspec, const char **refspec);
-extern struct refspec *parse_push_refspec(int nr_refspec, const char **refspec);
+int query_refspecs(struct refspec *rs, struct refspec_item *query);
+char *apply_refspecs(struct refspec *rs, const char *name);
 
-void free_refspec(int nr_refspec, struct refspec *refspec);
-
-extern int query_refspecs(struct refspec *specs, int nr, struct refspec *query);
-char *apply_refspecs(struct refspec *refspecs, int nr_refspec,
-                    const char *name);
-
-int check_push_refs(struct ref *src, int nr_refspec, const char **refspec);
+int check_push_refs(struct ref *src, struct refspec *rs);
 int match_push_refs(struct ref *src, struct ref **dst,
-                   int nr_refspec, const char **refspec, int all);
+                   struct refspec *rs, int flags);
 void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
        int force_update);
 
@@ -196,7 +181,7 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
  * missing_ok is usually false, but when we are adding branch.$name.merge
  * it is Ok if the branch is not at the remote anymore.
  */
-int get_fetch_map(const struct ref *remote_refs, const struct refspec *refspec,
+int get_fetch_map(const struct ref *remote_refs, const struct refspec_item *refspec,
                  struct ref ***tail, int missing_ok);
 
 struct ref *get_remote_ref(const struct ref *remote_refs, const char *name);
@@ -204,7 +189,7 @@ struct ref *get_remote_ref(const struct ref *remote_refs, const char *name);
 /*
  * For the given remote, reads the refspec's src and sets the other fields.
  */
-int remote_find_tracking(struct remote *remote, struct refspec *refspec);
+int remote_find_tracking(struct remote *remote, struct refspec_item *refspec);
 
 struct branch {
        const char *name;
@@ -214,7 +199,7 @@ struct branch {
        const char *pushremote_name;
 
        const char **merge_name;
-       struct refspec **merge;
+       struct refspec_item **merge;
        int merge_nr;
        int merge_alloc;
 
@@ -283,7 +268,7 @@ struct ref *guess_remote_head(const struct ref *head,
                              int all);
 
 /* Return refs which no longer exist on remote */
-struct ref *get_stale_heads(struct refspec *refs, int ref_count, struct ref *fetch_map);
+struct ref *get_stale_heads(struct refspec *rs, struct ref *fetch_map);
 
 /*
  * Compare-and-swap
@@ -306,8 +291,4 @@ extern int parseopt_push_cas_option(const struct option *, const char *arg, int
 extern int is_empty_cas(const struct push_cas_option *);
 void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *);
 
-#define TAG_REFSPEC "refs/tags/*:refs/tags/*"
-
-void add_prune_tags_to_fetch_refspec(struct remote *remote);
-
 #endif
diff --git a/replace-object.c b/replace-object.c
new file mode 100644 (file)
index 0000000..801b5c1
--- /dev/null
@@ -0,0 +1,73 @@
+#include "cache.h"
+#include "oidmap.h"
+#include "object-store.h"
+#include "replace-object.h"
+#include "refs.h"
+#include "repository.h"
+#include "commit.h"
+
+static int register_replace_ref(const char *refname,
+                               const struct object_id *oid,
+                               int flag, void *cb_data)
+{
+       /* Get sha1 from refname */
+       const char *slash = strrchr(refname, '/');
+       const char *hash = slash ? slash + 1 : refname;
+       struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
+
+       if (get_oid_hex(hash, &repl_obj->original.oid)) {
+               free(repl_obj);
+               warning("bad replace ref name: %s", refname);
+               return 0;
+       }
+
+       /* Copy sha1 from the read ref */
+       oidcpy(&repl_obj->replacement, oid);
+
+       /* Register new object */
+       if (oidmap_put(the_repository->objects->replace_map, repl_obj))
+               die("duplicate replace ref: %s", refname);
+
+       return 0;
+}
+
+static void prepare_replace_object(struct repository *r)
+{
+       if (r->objects->replace_map)
+               return;
+
+       r->objects->replace_map =
+               xmalloc(sizeof(*r->objects->replace_map));
+       oidmap_init(r->objects->replace_map, 0);
+
+       for_each_replace_ref(r, register_replace_ref, NULL);
+}
+
+/* We allow "recursive" replacement. Only within reason, though */
+#define MAXREPLACEDEPTH 5
+
+/*
+ * If a replacement for object oid has been set up, return the
+ * replacement object's name (replaced recursively, if necessary).
+ * The return value is either oid or a pointer to a
+ * permanently-allocated value.  This function always respects replace
+ * references, regardless of the value of check_replace_refs.
+ */
+const struct object_id *do_lookup_replace_object(struct repository *r,
+                                                const struct object_id *oid)
+{
+       int depth = MAXREPLACEDEPTH;
+       const struct object_id *cur = oid;
+
+       prepare_replace_object(r);
+
+       /* Try to recursively replace the object */
+       while (depth-- > 0) {
+               struct replace_object *repl_obj =
+                       oidmap_get(r->objects->replace_map, cur);
+               if (!repl_obj)
+                       return cur;
+               cur = &repl_obj->replacement;
+       }
+       die("replace depth too high for object %s", oid_to_hex(oid));
+}
diff --git a/replace-object.h b/replace-object.h
new file mode 100644 (file)
index 0000000..f996de3
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef REPLACE_OBJECT_H
+#define REPLACE_OBJECT_H
+
+#include "oidmap.h"
+#include "repository.h"
+#include "object-store.h"
+
+struct replace_object {
+       struct oidmap_entry original;
+       struct object_id replacement;
+};
+
+/*
+ * This internal function is only declared here for the benefit of
+ * lookup_replace_object().  Please do not call it directly.
+ */
+extern const struct object_id *do_lookup_replace_object(struct repository *r,
+                                                       const struct object_id *oid);
+
+/*
+ * If object sha1 should be replaced, return the replacement object's
+ * name (replaced recursively, if necessary).  The return value is
+ * either sha1 or a pointer to a permanently-allocated value.  When
+ * object replacement is suppressed, always return sha1.
+ */
+static inline const struct object_id *lookup_replace_object(struct repository *r,
+                                                           const struct object_id *oid)
+{
+       if (!check_replace_refs ||
+           (r->objects->replace_map &&
+            r->objects->replace_map->map.tablesize == 0))
+               return oid;
+       return do_lookup_replace_object(r, oid);
+}
+
+#endif /* REPLACE_OBJECT_H */
diff --git a/replace_object.c b/replace_object.c
deleted file mode 100644 (file)
index 3e49965..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-#include "cache.h"
-#include "sha1-lookup.h"
-#include "refs.h"
-#include "commit.h"
-
-/*
- * An array of replacements.  The array is kept sorted by the original
- * sha1.
- */
-static struct replace_object {
-       unsigned char original[20];
-       unsigned char replacement[20];
-} **replace_object;
-
-static int replace_object_alloc, replace_object_nr;
-
-static const unsigned char *replace_sha1_access(size_t index, void *table)
-{
-       struct replace_object **replace = table;
-       return replace[index]->original;
-}
-
-static int replace_object_pos(const unsigned char *sha1)
-{
-       return sha1_pos(sha1, replace_object, replace_object_nr,
-                       replace_sha1_access);
-}
-
-static int register_replace_object(struct replace_object *replace,
-                                  int ignore_dups)
-{
-       int pos = replace_object_pos(replace->original);
-
-       if (0 <= pos) {
-               if (ignore_dups)
-                       free(replace);
-               else {
-                       free(replace_object[pos]);
-                       replace_object[pos] = replace;
-               }
-               return 1;
-       }
-       pos = -pos - 1;
-       ALLOC_GROW(replace_object, replace_object_nr + 1, replace_object_alloc);
-       replace_object_nr++;
-       if (pos < replace_object_nr)
-               MOVE_ARRAY(replace_object + pos + 1, replace_object + pos,
-                          replace_object_nr - pos - 1);
-       replace_object[pos] = replace;
-       return 0;
-}
-
-static int register_replace_ref(const char *refname,
-                               const struct object_id *oid,
-                               int flag, void *cb_data)
-{
-       /* Get sha1 from refname */
-       const char *slash = strrchr(refname, '/');
-       const char *hash = slash ? slash + 1 : refname;
-       struct replace_object *repl_obj = xmalloc(sizeof(*repl_obj));
-
-       if (strlen(hash) != 40 || get_sha1_hex(hash, repl_obj->original)) {
-               free(repl_obj);
-               warning("bad replace ref name: %s", refname);
-               return 0;
-       }
-
-       /* Copy sha1 from the read ref */
-       hashcpy(repl_obj->replacement, oid->hash);
-
-       /* Register new object */
-       if (register_replace_object(repl_obj, 1))
-               die("duplicate replace ref: %s", refname);
-
-       return 0;
-}
-
-static void prepare_replace_object(void)
-{
-       static int replace_object_prepared;
-
-       if (replace_object_prepared)
-               return;
-
-       for_each_replace_ref(register_replace_ref, NULL);
-       replace_object_prepared = 1;
-       if (!replace_object_nr)
-               check_replace_refs = 0;
-}
-
-/* We allow "recursive" replacement. Only within reason, though */
-#define MAXREPLACEDEPTH 5
-
-/*
- * If a replacement for object sha1 has been set up, return the
- * replacement object's name (replaced recursively, if necessary).
- * The return value is either sha1 or a pointer to a
- * permanently-allocated value.  This function always respects replace
- * references, regardless of the value of check_replace_refs.
- */
-const unsigned char *do_lookup_replace_object(const unsigned char *sha1)
-{
-       int pos, depth = MAXREPLACEDEPTH;
-       const unsigned char *cur = sha1;
-
-       prepare_replace_object();
-
-       /* Try to recursively replace the object */
-       do {
-               if (--depth < 0)
-                       die("replace depth too high for object %s",
-                           sha1_to_hex(sha1));
-
-               pos = replace_object_pos(cur);
-               if (0 <= pos)
-                       cur = replace_object[pos]->replacement;
-       } while (0 <= pos);
-
-       return cur;
-}
index 4ffbe9bc94edc18314cb49c945038e2f20a40922..02fe884603df56ea0996121152b7640afb56a48f 100644 (file)
@@ -1,67 +1,73 @@
 #include "cache.h"
 #include "repository.h"
+#include "object-store.h"
 #include "config.h"
 #include "submodule-config.h"
 
 /* The main repository */
-static struct repository the_repo = {
-       NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &the_index, &hash_algos[GIT_HASH_SHA1], 0, 0
-};
-struct repository *the_repository = &the_repo;
+static struct repository the_repo;
+struct repository *the_repository;
 
-static char *git_path_from_env(const char *envvar, const char *git_dir,
-                              const char *path, int fromenv)
+void initialize_the_repository(void)
 {
-       if (fromenv) {
-               const char *value = getenv(envvar);
-               if (value)
-                       return xstrdup(value);
-       }
+       the_repository = &the_repo;
 
-       return xstrfmt("%s/%s", git_dir, path);
+       the_repo.index = &the_index;
+       the_repo.objects = raw_object_store_new();
+       repo_set_hash_algo(&the_repo, GIT_HASH_SHA1);
 }
 
-static int find_common_dir(struct strbuf *sb, const char *gitdir, int fromenv)
+static void expand_base_dir(char **out, const char *in,
+                           const char *base_dir, const char *def_in)
 {
-       if (fromenv) {
-               const char *value = getenv(GIT_COMMON_DIR_ENVIRONMENT);
-               if (value) {
-                       strbuf_addstr(sb, value);
-                       return 1;
-               }
-       }
-
-       return get_common_dir_noenv(sb, gitdir);
+       free(*out);
+       if (in)
+               *out = xstrdup(in);
+       else
+               *out = xstrfmt("%s/%s", base_dir, def_in);
 }
 
-static void repo_setup_env(struct repository *repo)
+static void repo_set_commondir(struct repository *repo,
+                              const char *commondir)
 {
        struct strbuf sb = STRBUF_INIT;
 
-       repo->different_commondir = find_common_dir(&sb, repo->gitdir,
-                                                   !repo->ignore_env);
        free(repo->commondir);
+
+       if (commondir) {
+               repo->different_commondir = 1;
+               repo->commondir = xstrdup(commondir);
+               return;
+       }
+
+       repo->different_commondir = get_common_dir_noenv(&sb, repo->gitdir);
        repo->commondir = strbuf_detach(&sb, NULL);
-       free(repo->objectdir);
-       repo->objectdir = git_path_from_env(DB_ENVIRONMENT, repo->commondir,
-                                           "objects", !repo->ignore_env);
-       free(repo->graft_file);
-       repo->graft_file = git_path_from_env(GRAFT_ENVIRONMENT, repo->commondir,
-                                            "info/grafts", !repo->ignore_env);
-       free(repo->index_file);
-       repo->index_file = git_path_from_env(INDEX_ENVIRONMENT, repo->gitdir,
-                                            "index", !repo->ignore_env);
 }
 
-void repo_set_gitdir(struct repository *repo, const char *path)
+void repo_set_gitdir(struct repository *repo,
+                    const char *root,
+                    const struct set_gitdir_args *o)
 {
-       const char *gitfile = read_gitfile(path);
+       const char *gitfile = read_gitfile(root);
+       /*
+        * repo->gitdir is saved because the caller could pass "root"
+        * that also points to repo->gitdir. We want to keep it alive
+        * until after xstrdup(root). Then we can free it.
+        */
        char *old_gitdir = repo->gitdir;
 
-       repo->gitdir = xstrdup(gitfile ? gitfile : path);
-       repo_setup_env(repo);
-
+       repo->gitdir = xstrdup(gitfile ? gitfile : root);
        free(old_gitdir);
+
+       repo_set_commondir(repo, o->commondir);
+       expand_base_dir(&repo->objects->objectdir, o->object_dir,
+                       repo->commondir, "objects");
+       free(repo->objects->alternate_db);
+       repo->objects->alternate_db = xstrdup_or_null(o->alternate_db);
+       expand_base_dir(&repo->graft_file, o->graft_file,
+                       repo->commondir, "info/grafts");
+       expand_base_dir(&repo->index_file, o->index_file,
+                       repo->gitdir, "index");
 }
 
 void repo_set_hash_algo(struct repository *repo, int hash_algo)
@@ -79,6 +85,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)
        int error = 0;
        char *abspath = NULL;
        const char *resolved_gitdir;
+       struct set_gitdir_args args = { NULL };
 
        abspath = real_pathdup(gitdir, 0);
        if (!abspath) {
@@ -93,7 +100,7 @@ static int repo_init_gitdir(struct repository *repo, const char *gitdir)
                goto out;
        }
 
-       repo_set_gitdir(repo, resolved_gitdir);
+       repo_set_gitdir(repo, resolved_gitdir, &args);
 
 out:
        free(abspath);
@@ -128,12 +135,14 @@ static int read_and_verify_repository_format(struct repository_format *format,
  * Initialize 'repo' based on the provided 'gitdir'.
  * Return 0 upon success and a non-zero value upon failure.
  */
-int repo_init(struct repository *repo, const char *gitdir, const char *worktree)
+int repo_init(struct repository *repo,
+             const char *gitdir,
+             const char *worktree)
 {
        struct repository_format format;
        memset(repo, 0, sizeof(*repo));
 
-       repo->ignore_env = 1;
+       repo->objects = raw_object_store_new();
 
        if (repo_init_gitdir(repo, gitdir))
                goto error;
@@ -167,7 +176,7 @@ int repo_submodule_init(struct repository *submodule,
        struct strbuf worktree = STRBUF_INIT;
        int ret = 0;
 
-       sub = submodule_from_cache(superproject, &null_oid, path);
+       sub = submodule_from_path(superproject, &null_oid, path);
        if (!sub) {
                ret = -1;
                goto out;
@@ -209,12 +218,14 @@ void repo_clear(struct repository *repo)
 {
        FREE_AND_NULL(repo->gitdir);
        FREE_AND_NULL(repo->commondir);
-       FREE_AND_NULL(repo->objectdir);
        FREE_AND_NULL(repo->graft_file);
        FREE_AND_NULL(repo->index_file);
        FREE_AND_NULL(repo->worktree);
        FREE_AND_NULL(repo->submodule_prefix);
 
+       raw_object_store_clear(repo->objects);
+       FREE_AND_NULL(repo->objects);
+
        if (repo->config) {
                git_configset_clear(repo->config);
                FREE_AND_NULL(repo->config);
@@ -227,7 +238,8 @@ void repo_clear(struct repository *repo)
 
        if (repo->index) {
                discard_index(repo->index);
-               FREE_AND_NULL(repo->index);
+               if (repo->index != &the_index)
+                       FREE_AND_NULL(repo->index);
        }
 }
 
index 0329e40c7f5e72dad3ba46328a8e3d6c29ed8e58..f2646f0c52aa83f6da8950cfd96c4308498cf417 100644 (file)
@@ -2,9 +2,10 @@
 #define REPOSITORY_H
 
 struct config_set;
+struct git_hash_algo;
 struct index_state;
+struct raw_object_store;
 struct submodule_cache;
-struct git_hash_algo;
 
 struct repository {
        /* Environment */
@@ -21,10 +22,12 @@ struct repository {
        char *commondir;
 
        /*
-        * Path to the repository's object store.
-        * Cannot be NULL after initialization.
+        * Holds any information related to accessing the raw object content.
         */
-       char *objectdir;
+       struct raw_object_store *objects;
+
+       /* The store in which the refs are held. */
+       struct ref_store *refs;
 
        /*
         * Path to the repository's graft file.
@@ -72,15 +75,6 @@ struct repository {
        const struct git_hash_algo *hash_algo;
 
        /* Configurations */
-       /*
-        * Bit used during initialization to indicate if repository state (like
-        * the location of the 'objectdir') should be read from the
-        * environment.  By default this bit will be set at the begining of
-        * 'repo_init()' so that all repositories will ignore the environment.
-        * The exception to this is 'the_repository', which doesn't go through
-        * the normal 'repo_init()' process.
-        */
-       unsigned ignore_env:1;
 
        /* Indicate if a repository has a different 'commondir' from 'gitdir' */
        unsigned different_commondir:1;
@@ -88,10 +82,27 @@ struct repository {
 
 extern struct repository *the_repository;
 
-extern void repo_set_gitdir(struct repository *repo, const char *path);
+/*
+ * Define a custom repository layout. Any field can be NULL, which
+ * will default back to the path according to the default layout.
+ */
+struct set_gitdir_args {
+       const char *commondir;
+       const char *object_dir;
+       const char *graft_file;
+       const char *index_file;
+       const char *alternate_db;
+};
+
+extern void repo_set_gitdir(struct repository *repo,
+                           const char *root,
+                           const struct set_gitdir_args *extra_args);
 extern void repo_set_worktree(struct repository *repo, const char *path);
 extern void repo_set_hash_algo(struct repository *repo, int algo);
-extern int repo_init(struct repository *repo, const char *gitdir, const char *worktree);
+extern void initialize_the_repository(void);
+extern int repo_init(struct repository *r,
+                    const char *gitdir,
+                    const char *worktree);
 extern int repo_submodule_init(struct repository *submodule,
                               struct repository *superproject,
                               const char *path);
index ea24d4c2f47ab6495d97f38245dd420a1ad38391..e0862e27786244b1a98723d09475223cc001dd62 100644 (file)
--- a/rerere.c
+++ b/rerere.c
@@ -703,10 +703,9 @@ out:
        return ret;
 }
 
-static struct lock_file index_lock;
-
 static void update_paths(struct string_list *update)
 {
+       struct lock_file index_lock = LOCK_INIT;
        int i;
 
        hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
@@ -979,8 +978,8 @@ static int handle_cache(const char *path, unsigned char *sha1, const char *outpu
                        break;
                i = ce_stage(ce) - 1;
                if (!mmfile[i].ptr) {
-                       mmfile[i].ptr = read_sha1_file(ce->oid.hash, &type,
-                                                      &size);
+                       mmfile[i].ptr = read_object_file(&ce->oid, &type,
+                                                        &size);
                        mmfile[i].size = size;
                }
        }
index b40f3173d3fe5ef5c06c00ff8994060a9078669d..fc5b3b83d9a08e9deed55ee15520387f147da626 100644 (file)
@@ -24,7 +24,7 @@ void record_resolve_undo(struct index_state *istate, struct cache_entry *ce)
        if (!lost->util)
                lost->util = xcalloc(1, sizeof(*ui));
        ui = lost->util;
-       hashcpy(ui->sha1[stage - 1], ce->oid.hash);
+       oidcpy(&ui->oid[stage - 1], &ce->oid);
        ui->mode[stage - 1] = ce->ce_mode;
 }
 
@@ -44,7 +44,7 @@ void resolve_undo_write(struct strbuf *sb, struct string_list *resolve_undo)
                for (i = 0; i < 3; i++) {
                        if (!ui->mode[i])
                                continue;
-                       strbuf_add(sb, ui->sha1[i], 20);
+                       strbuf_add(sb, ui->oid[i].hash, the_hash_algo->rawsz);
                }
        }
 }
@@ -55,6 +55,7 @@ struct string_list *resolve_undo_read(const char *data, unsigned long size)
        size_t len;
        char *endptr;
        int i;
+       const unsigned rawsz = the_hash_algo->rawsz;
 
        resolve_undo = xcalloc(1, sizeof(*resolve_undo));
        resolve_undo->strdup_strings = 1;
@@ -87,11 +88,11 @@ struct string_list *resolve_undo_read(const char *data, unsigned long size)
                for (i = 0; i < 3; i++) {
                        if (!ui->mode[i])
                                continue;
-                       if (size < 20)
+                       if (size < rawsz)
                                goto error;
-                       hashcpy(ui->sha1[i], (const unsigned char *)data);
-                       size -= 20;
-                       data += 20;
+                       oidread(&ui->oid[i], (const unsigned char *)data);
+                       size -= rawsz;
+                       data += rawsz;
                }
        }
        return resolve_undo;
@@ -145,7 +146,7 @@ int unmerge_index_entry_at(struct index_state *istate, int pos)
                struct cache_entry *nce;
                if (!ru->mode[i])
                        continue;
-               nce = make_cache_entry(ru->mode[i], ru->sha1[i],
+               nce = make_cache_entry(ru->mode[i], ru->oid[i].hash,
                                       name, i + 1, 0);
                if (matched)
                        nce->ce_flags |= CE_MATCHED;
index 46306455edddb94a554a7a2fcadf49a30861f599..87291904bd34e0e7f3a3601b6742f5345391824d 100644 (file)
@@ -3,7 +3,7 @@
 
 struct resolve_undo_info {
        unsigned int mode[3];
-       unsigned char sha1[3][20];
+       struct object_id oid[3];
 };
 
 extern void record_resolve_undo(struct index_state *, struct cache_entry *);
index b42c836d7a64a67779c587954bcab90d919aaffb..40fd91ff2b16bffc725f8602f45117279e27ba19 100644 (file)
@@ -6,6 +6,7 @@
 #include "diff.h"
 #include "refs.h"
 #include "revision.h"
+#include "repository.h"
 #include "graph.h"
 #include "grep.h"
 #include "reflog-walk.h"
@@ -51,12 +52,9 @@ static void mark_tree_contents_uninteresting(struct tree *tree)
 {
        struct tree_desc desc;
        struct name_entry entry;
-       struct object *obj = &tree->object;
 
-       if (!has_object_file(&obj->oid))
+       if (parse_tree_gently(tree, 1) < 0)
                return;
-       if (parse_tree(tree) < 0)
-               die("bad tree %s", oid_to_hex(&obj->oid));
 
        init_tree_desc(&desc, tree->buffer, tree->size);
        while (tree_entry(&desc, &entry)) {
@@ -94,50 +92,63 @@ void mark_tree_uninteresting(struct tree *tree)
        mark_tree_contents_uninteresting(tree);
 }
 
-void mark_parents_uninteresting(struct commit *commit)
+struct commit_stack {
+       struct commit **items;
+       size_t nr, alloc;
+};
+#define COMMIT_STACK_INIT { NULL, 0, 0 }
+
+static void commit_stack_push(struct commit_stack *stack, struct commit *commit)
 {
-       struct commit_list *parents = NULL, *l;
+       ALLOC_GROW(stack->items, stack->nr + 1, stack->alloc);
+       stack->items[stack->nr++] = commit;
+}
 
-       for (l = commit->parents; l; l = l->next)
-               commit_list_insert(l->item, &parents);
+static struct commit *commit_stack_pop(struct commit_stack *stack)
+{
+       return stack->nr ? stack->items[--stack->nr] : NULL;
+}
 
-       while (parents) {
-               struct commit *commit = pop_commit(&parents);
+static void commit_stack_clear(struct commit_stack *stack)
+{
+       FREE_AND_NULL(stack->items);
+       stack->nr = stack->alloc = 0;
+}
 
-               while (commit) {
-                       /*
-                        * A missing commit is ok iff its parent is marked
-                        * uninteresting.
-                        *
-                        * We just mark such a thing parsed, so that when
-                        * it is popped next time around, we won't be trying
-                        * to parse it and get an error.
-                        */
-                       if (!commit->object.parsed &&
-                           !has_object_file(&commit->object.oid))
-                               commit->object.parsed = 1;
+static void mark_one_parent_uninteresting(struct commit *commit,
+                                         struct commit_stack *pending)
+{
+       struct commit_list *l;
 
-                       if (commit->object.flags & UNINTERESTING)
-                               break;
+       if (commit->object.flags & UNINTERESTING)
+               return;
+       commit->object.flags |= UNINTERESTING;
+
+       /*
+        * Normally we haven't parsed the parent
+        * yet, so we won't have a parent of a parent
+        * here. However, it may turn out that we've
+        * reached this commit some other way (where it
+        * wasn't uninteresting), in which case we need
+        * to mark its parents recursively too..
+        */
+       for (l = commit->parents; l; l = l->next)
+               commit_stack_push(pending, l->item);
+}
 
-                       commit->object.flags |= UNINTERESTING;
+void mark_parents_uninteresting(struct commit *commit)
+{
+       struct commit_stack pending = COMMIT_STACK_INIT;
+       struct commit_list *l;
 
-                       /*
-                        * Normally we haven't parsed the parent
-                        * yet, so we won't have a parent of a parent
-                        * here. However, it may turn out that we've
-                        * reached this commit some other way (where it
-                        * wasn't uninteresting), in which case we need
-                        * to mark its parents recursively too..
-                        */
-                       if (!commit->parents)
-                               break;
+       for (l = commit->parents; l; l = l->next)
+               mark_one_parent_uninteresting(l->item, &pending);
 
-                       for (l = commit->parents->next; l; l = l->next)
-                               commit_list_insert(l->item, &parents);
-                       commit = commit->parents->item;
-               }
-       }
+       while (pending.nr > 0)
+               mark_one_parent_uninteresting(commit_stack_pop(&pending),
+                                             &pending);
+
+       commit_stack_clear(&pending);
 }
 
 static void add_pending_object_with_path(struct rev_info *revs,
@@ -440,8 +451,8 @@ static void file_change(struct diff_options *options,
 static int rev_compare_tree(struct rev_info *revs,
                            struct commit *parent, struct commit *commit)
 {
-       struct tree *t1 = parent->tree;
-       struct tree *t2 = commit->tree;
+       struct tree *t1 = get_commit_tree(parent);
+       struct tree *t2 = get_commit_tree(commit);
 
        if (!t1)
                return REV_TREE_NEW;
@@ -477,7 +488,7 @@ static int rev_compare_tree(struct rev_info *revs,
 static int rev_same_tree_as_empty(struct rev_info *revs, struct commit *commit)
 {
        int retval;
-       struct tree *t1 = commit->tree;
+       struct tree *t1 = get_commit_tree(commit);
 
        if (!t1)
                return 0;
@@ -615,7 +626,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
        if (!revs->prune)
                return;
 
-       if (!commit->tree)
+       if (!get_commit_tree(commit))
                return;
 
        if (!commit->parents) {
@@ -1285,7 +1296,7 @@ void add_reflogs_to_pending(struct rev_info *revs, unsigned flags)
 
        cb.all_revs = revs;
        cb.all_flags = flags;
-       cb.refs = get_main_ref_store();
+       cb.refs = get_main_ref_store(the_repository);
        for_each_reflog(handle_one_reflog, &cb);
 
        if (!revs->single_worktree)
@@ -1751,6 +1762,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
        const char *arg = argv[0];
        const char *optarg;
        int argcount;
+       const unsigned hexsz = the_hash_algo->hexsz;
 
        /* pseudo revision arguments */
        if (!strcmp(arg, "--all") || !strcmp(arg, "--branches") ||
@@ -2038,8 +2050,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->abbrev = strtoul(optarg, NULL, 10);
                if (revs->abbrev < MINIMUM_ABBREV)
                        revs->abbrev = MINIMUM_ABBREV;
-               else if (revs->abbrev > 40)
-                       revs->abbrev = 40;
+               else if (revs->abbrev > hexsz)
+                       revs->abbrev = hexsz;
        } else if (!strcmp(arg, "--abbrev-commit")) {
                revs->abbrev_commit = 1;
                revs->abbrev_commit_given = 1;
@@ -2107,7 +2119,7 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
                revs->ignore_missing = 1;
        } else if (!strcmp(arg, "--exclude-promisor-objects")) {
                if (fetch_if_missing)
-                       die("BUG: exclude_promisor_objects can only be used when fetch_if_missing is 0");
+                       BUG("exclude_promisor_objects can only be used when fetch_if_missing is 0");
                revs->exclude_promisor_objects = 1;
        } else {
                int opts = diff_opt_parse(&revs->diffopt, argv, argc, revs->prefix);
@@ -2173,10 +2185,10 @@ static int handle_revision_pseudo_opt(const char *submodule,
                 * supported right now, so stick to single worktree.
                 */
                if (!revs->single_worktree)
-                       die("BUG: --single-worktree cannot be used together with submodule");
+                       BUG("--single-worktree cannot be used together with submodule");
                refs = get_submodule_ref_store(submodule);
        } else
-               refs = get_main_ref_store();
+               refs = get_main_ref_store(the_repository);
 
        /*
         * NOTE!
@@ -3086,7 +3098,7 @@ enum commit_action get_commit_action(struct rev_info *revs, struct commit *commi
 {
        if (commit->object.flags & SHOWN)
                return commit_ignore;
-       if (revs->unpacked && has_sha1_pack(commit->object.oid.hash))
+       if (revs->unpacked && has_object_pack(&commit->object.oid))
                return commit_ignore;
        if (commit->object.flags & UNINTERESTING)
                return commit_ignore;
index a483d5904a3ec1acae8908dd2e699fa00bcaaa9d..84b883c2132bb07bc7fa21434368d64664587b8b 100644 (file)
@@ -1,6 +1,6 @@
 #include "cache.h"
 #include "run-command.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "sigchain.h"
 #include "argv-array.h"
 #include "thread-utils.h"
@@ -245,7 +245,7 @@ int sane_execvp(const char *file, char * const argv[])
 static const char **prepare_shell_cmd(struct argv_array *out, const char **argv)
 {
        if (!argv[0])
-               die("BUG: shell command is empty");
+               BUG("shell command is empty");
 
        if (strcspn(argv[0], "|&;<>()$`\\\"' \t\n*?[#~=%") != strlen(argv[0])) {
 #ifndef GIT_WINDOWS_NATIVE
@@ -383,7 +383,7 @@ static void child_err_spew(struct child_process *cmd, struct child_err *cerr)
 static void prepare_cmd(struct argv_array *out, const struct child_process *cmd)
 {
        if (!cmd->argv[0])
-               die("BUG: command is empty");
+               BUG("command is empty");
 
        /*
         * Add SHELL_PATH so in the event exec fails with ENOEXEC we can
@@ -471,15 +471,12 @@ struct atfork_state {
        sigset_t old;
 };
 
-#ifndef NO_PTHREADS
-static void bug_die(int err, const char *msg)
-{
-       if (err) {
-               errno = err;
-               die_errno("BUG: %s", msg);
-       }
-}
-#endif
+#define CHECK_BUG(err, msg) \
+       do { \
+               int e = (err); \
+               if (e) \
+                       BUG("%s: %s", msg, strerror(e)); \
+       } while(0)
 
 static void atfork_prepare(struct atfork_state *as)
 {
@@ -491,9 +488,9 @@ static void atfork_prepare(struct atfork_state *as)
        if (sigprocmask(SIG_SETMASK, &all, &as->old))
                die_errno("sigprocmask");
 #else
-       bug_die(pthread_sigmask(SIG_SETMASK, &all, &as->old),
+       CHECK_BUG(pthread_sigmask(SIG_SETMASK, &all, &as->old),
                "blocking all signals");
-       bug_die(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &as->cs),
+       CHECK_BUG(pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &as->cs),
                "disabling cancellation");
 #endif
 }
@@ -504,9 +501,9 @@ static void atfork_parent(struct atfork_state *as)
        if (sigprocmask(SIG_SETMASK, &as->old, NULL))
                die_errno("sigprocmask");
 #else
-       bug_die(pthread_setcancelstate(as->cs, NULL),
+       CHECK_BUG(pthread_setcancelstate(as->cs, NULL),
                "re-enabling cancellation");
-       bug_die(pthread_sigmask(SIG_SETMASK, &as->old, NULL),
+       CHECK_BUG(pthread_sigmask(SIG_SETMASK, &as->old, NULL),
                "restoring signal mask");
 #endif
 }
@@ -621,7 +618,7 @@ static void trace_run_command(const struct child_process *cp)
        if (!trace_want(&trace_default_key))
                return;
 
-       strbuf_addf(&buf, "trace: run_command:");
+       strbuf_addstr(&buf, "trace: run_command:");
        if (cp->dir) {
                strbuf_addstr(&buf, " cd ");
                sq_quote_buf_pretty(&buf, cp->dir);
@@ -967,7 +964,7 @@ int run_command(struct child_process *cmd)
        int code;
 
        if (cmd->out < 0 || cmd->err < 0)
-               die("BUG: run_command with a pipe can cause deadlock");
+               BUG("run_command with a pipe can cause deadlock");
 
        code = start_command(cmd);
        if (code)
@@ -1557,7 +1554,7 @@ static void pp_init(struct parallel_processes *pp,
 
        pp->data = data;
        if (!get_next_task)
-               die("BUG: you need to specify a get_next_task function");
+               BUG("you need to specify a get_next_task function");
        pp->get_next_task = get_next_task;
 
        pp->start_failure = start_failure ? start_failure : default_start_failure;
@@ -1619,7 +1616,7 @@ static int pp_start_one(struct parallel_processes *pp)
                if (pp->children[i].state == GIT_CP_FREE)
                        break;
        if (i == pp->max_processes)
-               die("BUG: bookkeeping is hard");
+               BUG("bookkeeping is hard");
 
        code = pp->get_next_task(&pp->children[i].process,
                                 &pp->children[i].err,
index 8d9190f5e7815c6b2f18afd266643a8c862e526e..19025a7aca82a7066b9a2d40d4d50406a9749a5f 100644 (file)
@@ -37,14 +37,14 @@ int option_parse_push_signed(const struct option *opt,
        die("bad %s argument: %s", opt->long_name, arg);
 }
 
-static void feed_object(const unsigned char *sha1, FILE *fh, int negative)
+static void feed_object(const struct object_id *oid, FILE *fh, int negative)
 {
-       if (negative && !has_sha1_file(sha1))
+       if (negative && !has_sha1_file(oid->hash))
                return;
 
        if (negative)
                putc('^', fh);
-       fputs(sha1_to_hex(sha1), fh);
+       fputs(oid_to_hex(oid), fh);
        putc('\n', fh);
 }
 
@@ -89,13 +89,13 @@ static int pack_objects(int fd, struct ref *refs, struct oid_array *extra, struc
         */
        po_in = xfdopen(po.in, "w");
        for (i = 0; i < extra->nr; i++)
-               feed_object(extra->oid[i].hash, po_in, 1);
+               feed_object(&extra->oid[i], po_in, 1);
 
        while (refs) {
                if (!is_null_oid(&refs->old_oid))
-                       feed_object(refs->old_oid.hash, po_in, 1);
+                       feed_object(&refs->old_oid, po_in, 1);
                if (!is_null_oid(&refs->new_oid))
-                       feed_object(refs->new_oid.hash, po_in, 0);
+                       feed_object(&refs->new_oid, po_in, 0);
                refs = refs->next;
        }
 
index f9d1001dee9ad10e243aaeafc46fbdd13597fce7..4034c0461b5022dad01b25d824cdc4f47ee09d13 100644 (file)
@@ -7,7 +7,7 @@
 #include "sequencer.h"
 #include "tag.h"
 #include "run-command.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "utf8.h"
 #include "cache-tree.h"
 #include "diff.h"
 #include "hashmap.h"
 #include "notes-utils.h"
 #include "sigchain.h"
+#include "unpack-trees.h"
+#include "worktree.h"
+#include "oidmap.h"
+#include "oidset.h"
+#include "alias.h"
 
 #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
 
@@ -74,13 +79,6 @@ static GIT_PATH_FUNC(rebase_path_message, "rebase-merge/message")
  * previous commit and from the first squash/fixup commit are written
  * to it. The commit message for each subsequent squash/fixup commit
  * is appended to the file as it is processed.
- *
- * The first line of the file is of the form
- *     # This is a combination of $count commits.
- * where $count is the number of commits whose messages have been
- * written to the file so far (including the initial "pick" commit).
- * Each time that a commit message is processed, this line is read and
- * updated. It is deleted just before the combined commit is made.
  */
 static GIT_PATH_FUNC(rebase_path_squash_msg, "rebase-merge/message-squash")
 /*
@@ -91,6 +89,11 @@ static GIT_PATH_FUNC(rebase_path_squash_msg, "rebase-merge/message-squash")
  * commit without opening the editor.)
  */
 static GIT_PATH_FUNC(rebase_path_fixup_msg, "rebase-merge/message-fixup")
+/*
+ * This file contains the list fixup/squash commands that have been
+ * accumulated into message-fixup or message-squash so far.
+ */
+static GIT_PATH_FUNC(rebase_path_current_fixups, "rebase-merge/current-fixups")
 /*
  * A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and
  * GIT_AUTHOR_DATE that will be used for the commit that is currently
@@ -120,6 +123,19 @@ static GIT_PATH_FUNC(rebase_path_stopped_sha, "rebase-merge/stopped-sha")
 static GIT_PATH_FUNC(rebase_path_rewritten_list, "rebase-merge/rewritten-list")
 static GIT_PATH_FUNC(rebase_path_rewritten_pending,
        "rebase-merge/rewritten-pending")
+
+/*
+ * The path of the file containig the OID of the "squash onto" commit, i.e.
+ * the dummy commit used for `reset [new root]`.
+ */
+static GIT_PATH_FUNC(rebase_path_squash_onto, "rebase-merge/squash-onto")
+
+/*
+ * The path of the file listing refs that need to be deleted after the rebase
+ * finishes. This is used by the `label` command to record the need for cleanup.
+ */
+static GIT_PATH_FUNC(rebase_path_refs_to_delete, "rebase-merge/refs-to-delete")
+
 /*
  * The following files are written by git-rebase just after parsing the
  * command-line (and are only consumed, not modified, by the sequencer).
@@ -127,6 +143,7 @@ static GIT_PATH_FUNC(rebase_path_rewritten_pending,
 static GIT_PATH_FUNC(rebase_path_gpg_sign_opt, "rebase-merge/gpg_sign_opt")
 static GIT_PATH_FUNC(rebase_path_orig_head, "rebase-merge/orig-head")
 static GIT_PATH_FUNC(rebase_path_verbose, "rebase-merge/verbose")
+static GIT_PATH_FUNC(rebase_path_signoff, "rebase-merge/signoff")
 static GIT_PATH_FUNC(rebase_path_head_name, "rebase-merge/head-name")
 static GIT_PATH_FUNC(rebase_path_onto, "rebase-merge/onto")
 static GIT_PATH_FUNC(rebase_path_autostash, "rebase-merge/autostash")
@@ -244,18 +261,35 @@ static const char *gpg_sign_opt_quoted(struct replay_opts *opts)
 
 int sequencer_remove_state(struct replay_opts *opts)
 {
-       struct strbuf dir = STRBUF_INIT;
+       struct strbuf buf = STRBUF_INIT;
        int i;
 
+       if (is_rebase_i(opts) &&
+           strbuf_read_file(&buf, rebase_path_refs_to_delete(), 0) > 0) {
+               char *p = buf.buf;
+               while (*p) {
+                       char *eol = strchr(p, '\n');
+                       if (eol)
+                               *eol = '\0';
+                       if (delete_ref("(rebase -i) cleanup", p, NULL, 0) < 0)
+                               warning(_("could not delete '%s'"), p);
+                       if (!eol)
+                               break;
+                       p = eol + 1;
+               }
+       }
+
        free(opts->gpg_sign);
        free(opts->strategy);
        for (i = 0; i < opts->xopts_nr; i++)
                free(opts->xopts[i]);
        free(opts->xopts);
+       strbuf_release(&opts->current_fixups);
 
-       strbuf_addstr(&dir, get_dir(opts));
-       remove_dir_recursively(&dir, 0);
-       strbuf_release(&dir);
+       strbuf_reset(&buf);
+       strbuf_addstr(&buf, get_dir(opts));
+       remove_dir_recursively(&buf, 0);
+       strbuf_release(&buf);
 
        return 0;
 }
@@ -282,7 +316,7 @@ struct commit_message {
 
 static const char *short_commit_name(struct commit *commit)
 {
-       return find_unique_abbrev(commit->object.oid.hash, DEFAULT_ABBREV);
+       return find_unique_abbrev(&commit->object.oid, DEFAULT_ABBREV);
 }
 
 static int get_message(struct commit *commit, struct commit_message *out)
@@ -345,12 +379,14 @@ static int write_message(const void *buf, size_t len, const char *filename,
        if (msg_fd < 0)
                return error_errno(_("could not lock '%s'"), filename);
        if (write_in_full(msg_fd, buf, len) < 0) {
+               error_errno(_("could not write to '%s'"), filename);
                rollback_lock_file(&msg_file);
-               return error_errno(_("could not write to '%s'"), filename);
+               return -1;
        }
        if (append_eol && write(msg_fd, "\n", 1) < 0) {
+               error_errno(_("could not write eol to '%s'"), filename);
                rollback_lock_file(&msg_file);
-               return error_errno(_("could not write eol to '%s'"), filename);
+               return -1;
        }
        if (commit_lock_file(&msg_file) < 0)
                return error(_("failed to finalize '%s'"), filename);
@@ -440,7 +476,8 @@ static int fast_forward_to(const struct object_id *to, const struct object_id *f
        transaction = ref_transaction_begin(&err);
        if (!transaction ||
            ref_transaction_update(transaction, "HEAD",
-                                  to, unborn ? &null_oid : from,
+                                  to, unborn && !is_rebase_i(opts) ?
+                                  &null_oid : from,
                                   0, sb.buf, &err) ||
            ref_transaction_commit(transaction, &err)) {
                ref_transaction_free(transaction);
@@ -499,8 +536,8 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
        o.show_rename_progress = 1;
 
        head_tree = parse_tree_indirect(head);
-       next_tree = next ? next->tree : empty_tree();
-       base_tree = base ? base->tree : empty_tree();
+       next_tree = next ? get_commit_tree(next) : empty_tree();
+       base_tree = base ? get_commit_tree(base) : empty_tree();
 
        for (xopt = opts->xopts; xopt != opts->xopts + opts->xopts_nr; xopt++)
                parse_merge_opt(&o, *xopt);
@@ -532,9 +569,23 @@ static int do_recursive_merge(struct commit *base, struct commit *next,
        return !clean;
 }
 
+static struct object_id *get_cache_tree_oid(void)
+{
+       if (!active_cache_tree)
+               active_cache_tree = cache_tree();
+
+       if (!cache_tree_fully_valid(active_cache_tree))
+               if (cache_tree_update(&the_index, 0)) {
+                       error(_("unable to update cache tree"));
+                       return NULL;
+               }
+
+       return &active_cache_tree->oid;
+}
+
 static int is_index_unchanged(void)
 {
-       struct object_id head_oid;
+       struct object_id head_oid, *cache_tree_oid;
        struct commit *head_commit;
 
        if (!resolve_ref_unsafe("HEAD", RESOLVE_REF_READING, &head_oid, NULL))
@@ -553,15 +604,10 @@ static int is_index_unchanged(void)
        if (parse_commit(head_commit))
                return -1;
 
-       if (!active_cache_tree)
-               active_cache_tree = cache_tree();
-
-       if (!cache_tree_fully_valid(active_cache_tree))
-               if (cache_tree_update(&the_index, 0))
-                       return error(_("unable to update cache tree"));
+       if (!(cache_tree_oid = get_cache_tree_oid()))
+               return -1;
 
-       return !oidcmp(&active_cache_tree->oid,
-                      &head_commit->tree->object.oid);
+       return !oidcmp(cache_tree_oid, get_commit_tree_oid(head_commit));
 }
 
 static int write_author_script(const char *message)
@@ -653,6 +699,52 @@ static char *get_author(const char *message)
        return NULL;
 }
 
+/* Read author-script and return an ident line (author <email> timestamp) */
+static const char *read_author_ident(struct strbuf *buf)
+{
+       const char *keys[] = {
+               "GIT_AUTHOR_NAME=", "GIT_AUTHOR_EMAIL=", "GIT_AUTHOR_DATE="
+       };
+       char *in, *out, *eol;
+       int i = 0, len;
+
+       if (strbuf_read_file(buf, rebase_path_author_script(), 256) <= 0)
+               return NULL;
+
+       /* dequote values and construct ident line in-place */
+       for (in = out = buf->buf; i < 3 && in - buf->buf < buf->len; i++) {
+               if (!skip_prefix(in, keys[i], (const char **)&in)) {
+                       warning("could not parse '%s' (looking for '%s'",
+                               rebase_path_author_script(), keys[i]);
+                       return NULL;
+               }
+
+               eol = strchrnul(in, '\n');
+               *eol = '\0';
+               sq_dequote(in);
+               len = strlen(in);
+
+               if (i > 0) /* separate values by spaces */
+                       *(out++) = ' ';
+               if (i == 1) /* email needs to be surrounded by <...> */
+                       *(out++) = '<';
+               memmove(out, in, len);
+               out += len;
+               if (i == 1) /* email needs to be surrounded by <...> */
+                       *(out++) = '>';
+               in = eol + 1;
+       }
+
+       if (i < 3) {
+               warning("could not parse '%s' (looking for '%s')",
+                       rebase_path_author_script(), keys[i]);
+               return NULL;
+       }
+
+       buf->len = out - buf->buf;
+       return buf->buf;
+}
+
 static const char staged_changes_advice[] =
 N_("you have staged changes in your working tree\n"
 "If these changes are meant to be squashed into the previous commit, run:\n"
@@ -672,6 +764,7 @@ N_("you have staged changes in your working tree\n"
 #define AMEND_MSG   (1<<2)
 #define CLEANUP_MSG (1<<3)
 #define VERIFY_MSG  (1<<4)
+#define CREATE_ROOT_COMMIT (1<<5)
 
 /*
  * If we are cherry-pick, and if the merge did not result in
@@ -691,6 +784,40 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
        struct child_process cmd = CHILD_PROCESS_INIT;
        const char *value;
 
+       if ((flags & CREATE_ROOT_COMMIT) && !(flags & AMEND_MSG)) {
+               struct strbuf msg = STRBUF_INIT, script = STRBUF_INIT;
+               const char *author = is_rebase_i(opts) ?
+                       read_author_ident(&script) : NULL;
+               struct object_id root_commit, *cache_tree_oid;
+               int res = 0;
+
+               if (!defmsg)
+                       BUG("root commit without message");
+
+               if (!(cache_tree_oid = get_cache_tree_oid()))
+                       res = -1;
+
+               if (!res)
+                       res = strbuf_read_file(&msg, defmsg, 0);
+
+               if (res <= 0)
+                       res = error_errno(_("could not read '%s'"), defmsg);
+               else
+                       res = commit_tree(msg.buf, msg.len, cache_tree_oid,
+                                         NULL, &root_commit, author,
+                                         opts->gpg_sign);
+
+               strbuf_release(&msg);
+               strbuf_release(&script);
+               if (!res) {
+                       update_ref(NULL, "CHERRY_PICK_HEAD", &root_commit, NULL,
+                                  REF_NO_DEREF, UPDATE_REFS_MSG_ON_ERR);
+                       res = update_ref(NULL, "HEAD", &root_commit, NULL, 0,
+                                        UPDATE_REFS_MSG_ON_ERR);
+               }
+               return res < 0 ? error(_("writing root commit")) : 0;
+       }
+
        cmd.git_cmd = 1;
 
        if (is_rebase_i(opts)) {
@@ -717,6 +844,8 @@ static int run_git_commit(const char *defmsg, struct replay_opts *opts,
                argv_array_pushf(&cmd.args, "-S%s", opts->gpg_sign);
        if (defmsg)
                argv_array_pushl(&cmd.args, "-F", defmsg, NULL);
+       else if (!(flags & EDIT_MSG))
+               argv_array_pushl(&cmd.args, "-C", "HEAD", NULL);
        if ((flags & CLEANUP_MSG))
                argv_array_push(&cmd.args, "--cleanup=strip");
        if ((flags & EDIT_MSG))
@@ -1112,14 +1241,14 @@ static int try_to_commit(struct strbuf *msg, const char *author,
                commit_list_insert(current_head, &parents);
        }
 
-       if (write_cache_as_tree(tree.hash, 0, NULL)) {
+       if (write_cache_as_tree(&tree, 0, NULL)) {
                res = error(_("git write-tree failed to write a tree"));
                goto out;
        }
 
        if (!(flags & ALLOW_EMPTY) && !oidcmp(current_head ?
-                                             &current_head->tree->object.oid :
-                                             &empty_tree_oid, &tree)) {
+                                             get_commit_tree_oid(current_head) :
+                                             the_hash_algo->empty_tree, &tree)) {
                res = 1; /* run 'git commit' to display error message */
                goto out;
        }
@@ -1148,6 +1277,8 @@ static int try_to_commit(struct strbuf *msg, const char *author,
                goto out;
        }
 
+       reset_ident_date();
+
        if (commit_tree_extended(msg->buf, msg->len, &tree, parents,
                                 oid, author, opts->gpg_sign, extra)) {
                res = error(_("failed to write commit object"));
@@ -1177,7 +1308,8 @@ static int do_commit(const char *msg_file, const char *author,
 {
        int res = 1;
 
-       if (!(flags & EDIT_MSG) && !(flags & VERIFY_MSG)) {
+       if (!(flags & EDIT_MSG) && !(flags & VERIFY_MSG) &&
+           !(flags & CREATE_ROOT_COMMIT)) {
                struct object_id oid;
                struct strbuf sb = STRBUF_INIT;
 
@@ -1216,12 +1348,12 @@ static int is_original_commit_empty(struct commit *commit)
                if (parse_commit(parent))
                        return error(_("could not parse parent commit %s"),
                                oid_to_hex(&parent->object.oid));
-               ptree_oid = &parent->tree->object.oid;
+               ptree_oid = get_commit_tree_oid(parent);
        } else {
                ptree_oid = the_hash_algo->empty_tree; /* commit is root */
        }
 
-       return !oidcmp(ptree_oid, &commit->tree->object.oid);
+       return !oidcmp(ptree_oid, get_commit_tree_oid(commit));
 }
 
 /*
@@ -1277,6 +1409,9 @@ enum todo_command {
        TODO_SQUASH,
        /* commands that do something else than handling a single commit */
        TODO_EXEC,
+       TODO_LABEL,
+       TODO_RESET,
+       TODO_MERGE,
        /* commands that do nothing but are counted for reporting progress */
        TODO_NOOP,
        TODO_DROP,
@@ -1295,6 +1430,9 @@ static struct {
        { 'f', "fixup" },
        { 's', "squash" },
        { 'x', "exec" },
+       { 'l', "label" },
+       { 't', "reset" },
+       { 'm', "merge" },
        { 0,   "noop" },
        { 'd', "drop" },
        { 0,   NULL }
@@ -1324,38 +1462,43 @@ static int is_fixup(enum todo_command command)
        return command == TODO_FIXUP || command == TODO_SQUASH;
 }
 
+/* Does this command create a (non-merge) commit? */
+static int is_pick_or_similar(enum todo_command command)
+{
+       switch (command) {
+       case TODO_PICK:
+       case TODO_REVERT:
+       case TODO_EDIT:
+       case TODO_REWORD:
+       case TODO_FIXUP:
+       case TODO_SQUASH:
+               return 1;
+       default:
+               return 0;
+       }
+}
+
 static int update_squash_messages(enum todo_command command,
                struct commit *commit, struct replay_opts *opts)
 {
        struct strbuf buf = STRBUF_INIT;
-       int count, res;
+       int res;
        const char *message, *body;
 
-       if (file_exists(rebase_path_squash_msg())) {
+       if (opts->current_fixup_count > 0) {
                struct strbuf header = STRBUF_INIT;
-               char *eol, *p;
+               char *eol;
 
-               if (strbuf_read_file(&buf, rebase_path_squash_msg(), 2048) <= 0)
+               if (strbuf_read_file(&buf, rebase_path_squash_msg(), 9) <= 0)
                        return error(_("could not read '%s'"),
                                rebase_path_squash_msg());
 
-               p = buf.buf + 1;
-               eol = strchrnul(buf.buf, '\n');
-               if (buf.buf[0] != comment_line_char ||
-                   (p += strcspn(p, "0123456789\n")) == eol)
-                       return error(_("unexpected 1st line of squash message:"
-                                      "\n\n\t%.*s"),
-                                    (int)(eol - buf.buf), buf.buf);
-               count = strtol(p, NULL, 10);
-
-               if (count < 1)
-                       return error(_("invalid 1st line of squash message:\n"
-                                      "\n\t%.*s"),
-                                    (int)(eol - buf.buf), buf.buf);
+               eol = buf.buf[0] != comment_line_char ?
+                       buf.buf : strchrnul(buf.buf, '\n');
 
                strbuf_addf(&header, "%c ", comment_line_char);
-               strbuf_addf(&header,
-                           _("This is a combination of %d commits."), ++count);
+               strbuf_addf(&header, _("This is a combination of %d commits."),
+                           opts->current_fixup_count + 2);
                strbuf_splice(&buf, 0, eol - buf.buf, header.buf, header.len);
                strbuf_release(&header);
        } else {
@@ -1378,10 +1521,8 @@ static int update_squash_messages(enum todo_command command,
                                     rebase_path_fixup_msg());
                }
 
-               count = 2;
                strbuf_addf(&buf, "%c ", comment_line_char);
-               strbuf_addf(&buf, _("This is a combination of %d commits."),
-                           count);
+               strbuf_addf(&buf, _("This is a combination of %d commits."), 2);
                strbuf_addf(&buf, "\n%c ", comment_line_char);
                strbuf_addstr(&buf, _("This is the 1st commit message:"));
                strbuf_addstr(&buf, "\n\n");
@@ -1398,13 +1539,14 @@ static int update_squash_messages(enum todo_command command,
        if (command == TODO_SQUASH) {
                unlink(rebase_path_fixup_msg());
                strbuf_addf(&buf, "\n%c ", comment_line_char);
-               strbuf_addf(&buf, _("This is the commit message #%d:"), count);
+               strbuf_addf(&buf, _("This is the commit message #%d:"),
+                           ++opts->current_fixup_count);
                strbuf_addstr(&buf, "\n\n");
                strbuf_addstr(&buf, body);
        } else if (command == TODO_FIXUP) {
                strbuf_addf(&buf, "\n%c ", comment_line_char);
                strbuf_addf(&buf, _("The commit message #%d will be skipped:"),
-                           count);
+                           ++opts->current_fixup_count);
                strbuf_addstr(&buf, "\n\n");
                strbuf_add_commented_lines(&buf, body, strlen(body));
        } else
@@ -1413,6 +1555,17 @@ static int update_squash_messages(enum todo_command command,
 
        res = write_message(buf.buf, buf.len, rebase_path_squash_msg(), 0);
        strbuf_release(&buf);
+
+       if (!res) {
+               strbuf_addf(&opts->current_fixups, "%s%s %s",
+                           opts->current_fixups.len ? "\n" : "",
+                           command_to_string(command),
+                           oid_to_hex(&commit->object.oid));
+               res = write_message(opts->current_fixups.buf,
+                                   opts->current_fixups.len,
+                                   rebase_path_current_fixups(), 0);
+       }
+
        return res;
 }
 
@@ -1474,13 +1627,20 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                 * that represents the "current" state for merge-recursive
                 * to work on.
                 */
-               if (write_cache_as_tree(head.hash, 0, NULL))
+               if (write_cache_as_tree(&head, 0, NULL))
                        return error(_("your index file is unmerged."));
        } else {
                unborn = get_oid("HEAD", &head);
-               if (unborn)
+               /* Do we want to generate a root commit? */
+               if (is_pick_or_similar(command) && opts->have_squash_onto &&
+                   !oidcmp(&head, &opts->squash_onto)) {
+                       if (is_fixup(command))
+                               return error(_("cannot fixup root commit"));
+                       flags |= CREATE_ROOT_COMMIT;
+                       unborn = 1;
+               } else if (unborn)
                        oidcpy(&head, the_hash_algo->empty_tree);
-               if (index_differs_from(unborn ? EMPTY_TREE_SHA1_HEX : "HEAD",
+               if (index_differs_from(unborn ? empty_tree_oid_hex() : "HEAD",
                                       NULL, 0))
                        return error_dirty_index(opts);
        }
@@ -1604,7 +1764,7 @@ static int do_pick_commit(enum todo_command command, struct commit *commit,
                }
        }
 
-       if (opts->signoff)
+       if (opts->signoff && !is_fixup(command))
                append_signoff(&msgbuf, 0, 0);
 
        if (is_rebase_i(opts) && write_author_script(msg.message) < 0)
@@ -1675,6 +1835,9 @@ fast_forward_edit:
        if (!res && final_fixup) {
                unlink(rebase_path_fixup_msg());
                unlink(rebase_path_squash_msg());
+               unlink(rebase_path_current_fixups());
+               strbuf_reset(&opts->current_fixups);
+               opts->current_fixup_count = 0;
        }
 
 leave:
@@ -1722,9 +1885,14 @@ static int read_and_refresh_cache(struct replay_opts *opts)
        return 0;
 }
 
+enum todo_item_flags {
+       TODO_EDIT_MERGE_MSG = 1
+};
+
 struct todo_item {
        enum todo_command command;
        struct commit *commit;
+       unsigned int flags;
        const char *arg;
        int arg_len;
        size_t offset_in_buf;
@@ -1759,6 +1927,8 @@ static int parse_insn_line(struct todo_item *item, const char *bol, char *eol)
        char *end_of_object_name;
        int i, saved, status, padding;
 
+       item->flags = 0;
+
        /* left-trim */
        bol += strspn(bol, " \t");
 
@@ -1800,13 +1970,29 @@ static int parse_insn_line(struct todo_item *item, const char *bol, char *eol)
                return error(_("missing arguments for %s"),
                             command_to_string(item->command));
 
-       if (item->command == TODO_EXEC) {
+       if (item->command == TODO_EXEC || item->command == TODO_LABEL ||
+           item->command == TODO_RESET) {
                item->commit = NULL;
                item->arg = bol;
                item->arg_len = (int)(eol - bol);
                return 0;
        }
 
+       if (item->command == TODO_MERGE) {
+               if (skip_prefix(bol, "-C", &bol))
+                       bol += strspn(bol, " \t");
+               else if (skip_prefix(bol, "-c", &bol)) {
+                       bol += strspn(bol, " \t");
+                       item->flags |= TODO_EDIT_MERGE_MSG;
+               } else {
+                       item->flags |= TODO_EDIT_MERGE_MSG;
+                       item->commit = NULL;
+                       item->arg = bol;
+                       item->arg_len = (int)(eol - bol);
+                       return 0;
+               }
+       }
+
        end_of_object_name = (char *) bol + strcspn(bol, " \t\n");
        saved = *end_of_object_name;
        *end_of_object_name = '\0';
@@ -1868,6 +2054,23 @@ static int count_commands(struct todo_list *todo_list)
        return count;
 }
 
+static int get_item_line_offset(struct todo_list *todo_list, int index)
+{
+       return index < todo_list->nr ?
+               todo_list->items[index].offset_in_buf : todo_list->buf.len;
+}
+
+static const char *get_item_line(struct todo_list *todo_list, int index)
+{
+       return todo_list->buf.buf + get_item_line_offset(todo_list, index);
+}
+
+static int get_item_line_length(struct todo_list *todo_list, int index)
+{
+       return get_item_line_offset(todo_list, index + 1)
+               -  get_item_line_offset(todo_list, index);
+}
+
 static ssize_t strbuf_read_file_or_whine(struct strbuf *sb, const char *path)
 {
        int fd;
@@ -2043,9 +2246,30 @@ static int read_populate_opts(struct replay_opts *opts)
                if (file_exists(rebase_path_verbose()))
                        opts->verbose = 1;
 
+               if (file_exists(rebase_path_signoff())) {
+                       opts->allow_ff = 0;
+                       opts->signoff = 1;
+               }
+
                read_strategy_opts(opts, &buf);
                strbuf_release(&buf);
 
+               if (read_oneliner(&opts->current_fixups,
+                                 rebase_path_current_fixups(), 1)) {
+                       const char *p = opts->current_fixups.buf;
+                       opts->current_fixup_count = 1;
+                       while ((p = strchr(p, '\n'))) {
+                               opts->current_fixup_count++;
+                               p++;
+                       }
+               }
+
+               if (read_oneliner(&buf, rebase_path_squash_onto(), 0)) {
+                       if (get_oid_hex(buf.buf, &opts->squash_onto) < 0)
+                               return error(_("unusable squash-onto"));
+                       opts->have_squash_onto = 1;
+               }
+
                return 0;
        }
 
@@ -2119,9 +2343,9 @@ static int save_head(const char *head)
        written = write_in_full(fd, buf.buf, buf.len);
        strbuf_release(&buf);
        if (written < 0) {
+               error_errno(_("could not write to '%s'"), git_path_head_file());
                rollback_lock_file(&head_lock);
-               return error_errno(_("could not write to '%s'"),
-                                  git_path_head_file());
+               return -1;
        }
        if (commit_lock_file(&head_lock) < 0)
                return error(_("failed to finalize '%s'"), git_path_head_file());
@@ -2242,29 +2466,27 @@ static int save_todo(struct todo_list *todo_list, struct replay_opts *opts)
        fd = hold_lock_file_for_update(&todo_lock, todo_path, 0);
        if (fd < 0)
                return error_errno(_("could not lock '%s'"), todo_path);
-       offset = next < todo_list->nr ?
-               todo_list->items[next].offset_in_buf : todo_list->buf.len;
+       offset = get_item_line_offset(todo_list, next);
        if (write_in_full(fd, todo_list->buf.buf + offset,
                        todo_list->buf.len - offset) < 0)
                return error_errno(_("could not write to '%s'"), todo_path);
        if (commit_lock_file(&todo_lock) < 0)
                return error(_("failed to finalize '%s'"), todo_path);
 
-       if (is_rebase_i(opts)) {
-               const char *done_path = rebase_path_done();
-               int fd = open(done_path, O_CREAT | O_WRONLY | O_APPEND, 0666);
-               int prev_offset = !next ? 0 :
-                       todo_list->items[next - 1].offset_in_buf;
+       if (is_rebase_i(opts) && next > 0) {
+               const char *done = rebase_path_done();
+               int fd = open(done, O_CREAT | O_WRONLY | O_APPEND, 0666);
+               int ret = 0;
 
-               if (fd >= 0 && offset > prev_offset &&
-                   write_in_full(fd, todo_list->buf.buf + prev_offset,
-                                 offset - prev_offset) < 0) {
-                       close(fd);
-                       return error_errno(_("could not write to '%s'"),
-                                          done_path);
-               }
-               if (fd >= 0)
-                       close(fd);
+               if (fd < 0)
+                       return 0;
+               if (write_in_full(fd, get_item_line(todo_list, next - 1),
+                                 get_item_line_length(todo_list, next - 1))
+                   < 0)
+                       ret = error_errno(_("could not write to '%s'"), done);
+               if (close(fd) < 0)
+                       ret = error_errno(_("failed to finalize '%s'"), done);
+               return ret;
        }
        return 0;
 }
@@ -2392,10 +2614,9 @@ static int error_with_patch(struct commit *commit,
 static int error_failed_squash(struct commit *commit,
        struct replay_opts *opts, int subject_len, const char *subject)
 {
-       if (rename(rebase_path_squash_msg(), rebase_path_message()))
-               return error(_("could not rename '%s' to '%s'"),
+       if (copy_file(rebase_path_message(), rebase_path_squash_msg(), 0666))
+               return error(_("could not copy '%s' to '%s'"),
                        rebase_path_squash_msg(), rebase_path_message());
-       unlink(rebase_path_fixup_msg());
        unlink(git_path_merge_msg());
        if (copy_file(git_path_merge_msg(), rebase_path_message(), 0666))
                return error(_("could not copy '%s' to '%s'"),
@@ -2448,6 +2669,377 @@ static int do_exec(const char *command_line)
        return status;
 }
 
+static int safe_append(const char *filename, const char *fmt, ...)
+{
+       va_list ap;
+       struct lock_file lock = LOCK_INIT;
+       int fd = hold_lock_file_for_update(&lock, filename,
+                                          LOCK_REPORT_ON_ERROR);
+       struct strbuf buf = STRBUF_INIT;
+
+       if (fd < 0)
+               return -1;
+
+       if (strbuf_read_file(&buf, filename, 0) < 0 && errno != ENOENT) {
+               error_errno(_("could not read '%s'"), filename);
+               rollback_lock_file(&lock);
+               return -1;
+       }
+       strbuf_complete(&buf, '\n');
+       va_start(ap, fmt);
+       strbuf_vaddf(&buf, fmt, ap);
+       va_end(ap);
+
+       if (write_in_full(fd, buf.buf, buf.len) < 0) {
+               error_errno(_("could not write to '%s'"), filename);
+               strbuf_release(&buf);
+               rollback_lock_file(&lock);
+               return -1;
+       }
+       if (commit_lock_file(&lock) < 0) {
+               strbuf_release(&buf);
+               rollback_lock_file(&lock);
+               return error(_("failed to finalize '%s'"), filename);
+       }
+
+       strbuf_release(&buf);
+       return 0;
+}
+
+static int do_label(const char *name, int len)
+{
+       struct ref_store *refs = get_main_ref_store(the_repository);
+       struct ref_transaction *transaction;
+       struct strbuf ref_name = STRBUF_INIT, err = STRBUF_INIT;
+       struct strbuf msg = STRBUF_INIT;
+       int ret = 0;
+       struct object_id head_oid;
+
+       if (len == 1 && *name == '#')
+               return error("Illegal label name: '%.*s'", len, name);
+
+       strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name);
+       strbuf_addf(&msg, "rebase -i (label) '%.*s'", len, name);
+
+       transaction = ref_store_transaction_begin(refs, &err);
+       if (!transaction) {
+               error("%s", err.buf);
+               ret = -1;
+       } else if (get_oid("HEAD", &head_oid)) {
+               error(_("could not read HEAD"));
+               ret = -1;
+       } else if (ref_transaction_update(transaction, ref_name.buf, &head_oid,
+                                         NULL, 0, msg.buf, &err) < 0 ||
+                  ref_transaction_commit(transaction, &err)) {
+               error("%s", err.buf);
+               ret = -1;
+       }
+       ref_transaction_free(transaction);
+       strbuf_release(&err);
+       strbuf_release(&msg);
+
+       if (!ret)
+               ret = safe_append(rebase_path_refs_to_delete(),
+                                 "%s\n", ref_name.buf);
+       strbuf_release(&ref_name);
+
+       return ret;
+}
+
+static const char *reflog_message(struct replay_opts *opts,
+       const char *sub_action, const char *fmt, ...);
+
+static int do_reset(const char *name, int len, struct replay_opts *opts)
+{
+       struct strbuf ref_name = STRBUF_INIT;
+       struct object_id oid;
+       struct lock_file lock = LOCK_INIT;
+       struct tree_desc desc;
+       struct tree *tree;
+       struct unpack_trees_options unpack_tree_opts;
+       int ret = 0, i;
+
+       if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0)
+               return -1;
+
+       if (len == 10 && !strncmp("[new root]", name, len)) {
+               if (!opts->have_squash_onto) {
+                       const char *hex;
+                       if (commit_tree("", 0, the_hash_algo->empty_tree,
+                                       NULL, &opts->squash_onto,
+                                       NULL, NULL))
+                               return error(_("writing fake root commit"));
+                       opts->have_squash_onto = 1;
+                       hex = oid_to_hex(&opts->squash_onto);
+                       if (write_message(hex, strlen(hex),
+                                         rebase_path_squash_onto(), 0))
+                               return error(_("writing squash-onto"));
+               }
+               oidcpy(&oid, &opts->squash_onto);
+       } else {
+               /* Determine the length of the label */
+               for (i = 0; i < len; i++)
+                       if (isspace(name[i]))
+                               len = i;
+
+               strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name);
+               if (get_oid(ref_name.buf, &oid) &&
+                   get_oid(ref_name.buf + strlen("refs/rewritten/"), &oid)) {
+                       error(_("could not read '%s'"), ref_name.buf);
+                       rollback_lock_file(&lock);
+                       strbuf_release(&ref_name);
+                       return -1;
+               }
+       }
+
+       memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
+       setup_unpack_trees_porcelain(&unpack_tree_opts, "reset");
+       unpack_tree_opts.head_idx = 1;
+       unpack_tree_opts.src_index = &the_index;
+       unpack_tree_opts.dst_index = &the_index;
+       unpack_tree_opts.fn = oneway_merge;
+       unpack_tree_opts.merge = 1;
+       unpack_tree_opts.update = 1;
+
+       if (read_cache_unmerged()) {
+               rollback_lock_file(&lock);
+               strbuf_release(&ref_name);
+               return error_resolve_conflict(_(action_name(opts)));
+       }
+
+       if (!fill_tree_descriptor(&desc, &oid)) {
+               error(_("failed to find tree of %s"), oid_to_hex(&oid));
+               rollback_lock_file(&lock);
+               free((void *)desc.buffer);
+               strbuf_release(&ref_name);
+               return -1;
+       }
+
+       if (unpack_trees(1, &desc, &unpack_tree_opts)) {
+               rollback_lock_file(&lock);
+               free((void *)desc.buffer);
+               strbuf_release(&ref_name);
+               return -1;
+       }
+
+       tree = parse_tree_indirect(&oid);
+       prime_cache_tree(&the_index, tree);
+
+       if (write_locked_index(&the_index, &lock, COMMIT_LOCK) < 0)
+               ret = error(_("could not write index"));
+       free((void *)desc.buffer);
+
+       if (!ret)
+               ret = update_ref(reflog_message(opts, "reset", "'%.*s'",
+                                               len, name), "HEAD", &oid,
+                                NULL, 0, UPDATE_REFS_MSG_ON_ERR);
+
+       strbuf_release(&ref_name);
+       return ret;
+}
+
+static int do_merge(struct commit *commit, const char *arg, int arg_len,
+                   int flags, struct replay_opts *opts)
+{
+       int run_commit_flags = (flags & TODO_EDIT_MERGE_MSG) ?
+               EDIT_MSG | VERIFY_MSG : 0;
+       struct strbuf ref_name = STRBUF_INIT;
+       struct commit *head_commit, *merge_commit, *i;
+       struct commit_list *bases, *j, *reversed = NULL;
+       struct merge_options o;
+       int merge_arg_len, oneline_offset, can_fast_forward, ret;
+       static struct lock_file lock;
+       const char *p;
+
+       if (hold_locked_index(&lock, LOCK_REPORT_ON_ERROR) < 0) {
+               ret = -1;
+               goto leave_merge;
+       }
+
+       head_commit = lookup_commit_reference_by_name("HEAD");
+       if (!head_commit) {
+               ret = error(_("cannot merge without a current revision"));
+               goto leave_merge;
+       }
+
+       oneline_offset = arg_len;
+       merge_arg_len = strcspn(arg, " \t\n");
+       p = arg + merge_arg_len;
+       p += strspn(p, " \t\n");
+       if (*p == '#' && (!p[1] || isspace(p[1]))) {
+               p += 1 + strspn(p + 1, " \t\n");
+               oneline_offset = p - arg;
+       } else if (p - arg < arg_len)
+               BUG("octopus merges are not supported yet: '%s'", p);
+
+       strbuf_addf(&ref_name, "refs/rewritten/%.*s", merge_arg_len, arg);
+       merge_commit = lookup_commit_reference_by_name(ref_name.buf);
+       if (!merge_commit) {
+               /* fall back to non-rewritten ref or commit */
+               strbuf_splice(&ref_name, 0, strlen("refs/rewritten/"), "", 0);
+               merge_commit = lookup_commit_reference_by_name(ref_name.buf);
+       }
+
+       if (!merge_commit) {
+               ret = error(_("could not resolve '%s'"), ref_name.buf);
+               goto leave_merge;
+       }
+
+       if (opts->have_squash_onto &&
+           !oidcmp(&head_commit->object.oid, &opts->squash_onto)) {
+               /*
+                * When the user tells us to "merge" something into a
+                * "[new root]", let's simply fast-forward to the merge head.
+                */
+               rollback_lock_file(&lock);
+               ret = fast_forward_to(&merge_commit->object.oid,
+                                      &head_commit->object.oid, 0, opts);
+               goto leave_merge;
+       }
+
+       if (commit) {
+               const char *message = get_commit_buffer(commit, NULL);
+               const char *body;
+               int len;
+
+               if (!message) {
+                       ret = error(_("could not get commit message of '%s'"),
+                                   oid_to_hex(&commit->object.oid));
+                       goto leave_merge;
+               }
+               write_author_script(message);
+               find_commit_subject(message, &body);
+               len = strlen(body);
+               ret = write_message(body, len, git_path_merge_msg(), 0);
+               unuse_commit_buffer(commit, message);
+               if (ret) {
+                       error_errno(_("could not write '%s'"),
+                                   git_path_merge_msg());
+                       goto leave_merge;
+               }
+       } else {
+               struct strbuf buf = STRBUF_INIT;
+               int len;
+
+               strbuf_addf(&buf, "author %s", git_author_info(0));
+               write_author_script(buf.buf);
+               strbuf_reset(&buf);
+
+               if (oneline_offset < arg_len) {
+                       p = arg + oneline_offset;
+                       len = arg_len - oneline_offset;
+               } else {
+                       strbuf_addf(&buf, "Merge branch '%.*s'",
+                                   merge_arg_len, arg);
+                       p = buf.buf;
+                       len = buf.len;
+               }
+
+               ret = write_message(p, len, git_path_merge_msg(), 0);
+               strbuf_release(&buf);
+               if (ret) {
+                       error_errno(_("could not write '%s'"),
+                                   git_path_merge_msg());
+                       goto leave_merge;
+               }
+       }
+
+       /*
+        * If HEAD is not identical to the first parent of the original merge
+        * commit, we cannot fast-forward.
+        */
+       can_fast_forward = opts->allow_ff && commit && commit->parents &&
+               !oidcmp(&commit->parents->item->object.oid,
+                       &head_commit->object.oid);
+
+       /*
+        * If the merge head is different from the original one, we cannot
+        * fast-forward.
+        */
+       if (can_fast_forward) {
+               struct commit_list *second_parent = commit->parents->next;
+
+               if (second_parent && !second_parent->next &&
+                   oidcmp(&merge_commit->object.oid,
+                          &second_parent->item->object.oid))
+                       can_fast_forward = 0;
+       }
+
+       if (can_fast_forward && commit->parents->next &&
+           !commit->parents->next->next &&
+           !oidcmp(&commit->parents->next->item->object.oid,
+                   &merge_commit->object.oid)) {
+               rollback_lock_file(&lock);
+               ret = fast_forward_to(&commit->object.oid,
+                                     &head_commit->object.oid, 0, opts);
+               goto leave_merge;
+       }
+
+       write_message(oid_to_hex(&merge_commit->object.oid), GIT_SHA1_HEXSZ,
+                     git_path_merge_head(), 0);
+       write_message("no-ff", 5, git_path_merge_mode(), 0);
+
+       bases = get_merge_bases(head_commit, merge_commit);
+       if (bases && !oidcmp(&merge_commit->object.oid,
+                            &bases->item->object.oid)) {
+               ret = 0;
+               /* skip merging an ancestor of HEAD */
+               goto leave_merge;
+       }
+
+       for (j = bases; j; j = j->next)
+               commit_list_insert(j->item, &reversed);
+       free_commit_list(bases);
+
+       read_cache();
+       init_merge_options(&o);
+       o.branch1 = "HEAD";
+       o.branch2 = ref_name.buf;
+       o.buffer_output = 2;
+
+       ret = merge_recursive(&o, head_commit, merge_commit, reversed, &i);
+       if (ret <= 0)
+               fputs(o.obuf.buf, stdout);
+       strbuf_release(&o.obuf);
+       if (ret < 0) {
+               error(_("could not even attempt to merge '%.*s'"),
+                     merge_arg_len, arg);
+               goto leave_merge;
+       }
+       /*
+        * The return value of merge_recursive() is 1 on clean, and 0 on
+        * unclean merge.
+        *
+        * Let's reverse that, so that do_merge() returns 0 upon success and
+        * 1 upon failed merge (keeping the return value -1 for the cases where
+        * we will want to reschedule the `merge` command).
+        */
+       ret = !ret;
+
+       if (active_cache_changed &&
+           write_locked_index(&the_index, &lock, COMMIT_LOCK)) {
+               ret = error(_("merge: Unable to write new index file"));
+               goto leave_merge;
+       }
+
+       rollback_lock_file(&lock);
+       if (ret)
+               rerere(opts->allow_rerere_auto);
+       else
+               /*
+                * In case of problems, we now want to return a positive
+                * value (a negative one would indicate that the `merge`
+                * command needs to be rescheduled).
+                */
+               ret = !!run_git_commit(git_path_merge_msg(), opts,
+                                    run_commit_flags);
+
+leave_merge:
+       strbuf_release(&ref_name);
+       rollback_lock_file(&lock);
+       return ret;
+}
+
 static int is_final_fixup(struct todo_list *todo_list)
 {
        int i = todo_list->current;
@@ -2538,9 +3130,20 @@ static const char *reflog_message(struct replay_opts *opts,
        return buf.buf;
 }
 
+static const char rescheduled_advice[] =
+N_("Could not execute the todo command\n"
+"\n"
+"    %.*s"
+"\n"
+"It has been rescheduled; To edit the command before continuing, please\n"
+"edit the todo list first:\n"
+"\n"
+"    git rebase --edit-todo\n"
+"    git rebase --continue\n");
+
 static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
 {
-       int res = 0;
+       int res = 0, reschedule = 0;
 
        setenv(GIT_REFLOG_ACTION, action_name(opts), 0);
        if (opts->allow_ff)
@@ -2583,6 +3186,11 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                                        opts, is_final_fixup(todo_list));
                        if (is_rebase_i(opts) && res < 0) {
                                /* Reschedule */
+                               advise(_(rescheduled_advice),
+                                      get_item_line_length(todo_list,
+                                                           todo_list->current),
+                                      get_item_line(todo_list,
+                                                    todo_list->current));
                                todo_list->current--;
                                if (save_todo(todo_list, opts))
                                        return -1;
@@ -2606,7 +3214,7 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                                        intend_to_amend();
                                return error_failed_squash(item->commit, opts,
                                        item->arg_len, item->arg);
-                       } else if (res && is_rebase_i(opts))
+                       } else if (res && is_rebase_i(opts) && item->commit)
                                return res | error_with_patch(item->commit,
                                        item->arg, item->arg_len, opts, res,
                                        item->command == TODO_REWORD);
@@ -2632,9 +3240,44 @@ static int pick_commits(struct todo_list *todo_list, struct replay_opts *opts)
                                /* `current` will be incremented below */
                                todo_list->current = -1;
                        }
+               } else if (item->command == TODO_LABEL) {
+                       if ((res = do_label(item->arg, item->arg_len)))
+                               reschedule = 1;
+               } else if (item->command == TODO_RESET) {
+                       if ((res = do_reset(item->arg, item->arg_len, opts)))
+                               reschedule = 1;
+               } else if (item->command == TODO_MERGE) {
+                       if ((res = do_merge(item->commit,
+                                           item->arg, item->arg_len,
+                                           item->flags, opts)) < 0)
+                               reschedule = 1;
+                       else if (item->commit)
+                               record_in_rewritten(&item->commit->object.oid,
+                                                   peek_command(todo_list, 1));
+                       if (res > 0)
+                               /* failed with merge conflicts */
+                               return error_with_patch(item->commit,
+                                                       item->arg,
+                                                       item->arg_len, opts,
+                                                       res, 0);
                } else if (!is_noop(item->command))
                        return error(_("unknown command %d"), item->command);
 
+               if (reschedule) {
+                       advise(_(rescheduled_advice),
+                              get_item_line_length(todo_list,
+                                                   todo_list->current),
+                              get_item_line(todo_list, todo_list->current));
+                       todo_list->current--;
+                       if (save_todo(todo_list, opts))
+                               return -1;
+                       if (item->commit)
+                               return error_with_patch(item->commit,
+                                                       item->arg,
+                                                       item->arg_len, opts,
+                                                       res, 0);
+               }
+
                todo_list->current++;
                if (res)
                        return res;
@@ -2761,19 +3404,16 @@ static int continue_single_pick(void)
        return run_command_v_opt(argv, RUN_GIT_CMD);
 }
 
-static int commit_staged_changes(struct replay_opts *opts)
+static int commit_staged_changes(struct replay_opts *opts,
+                                struct todo_list *todo_list)
 {
        unsigned int flags = ALLOW_EMPTY | EDIT_MSG;
+       unsigned int final_fixup = 0, is_clean;
 
        if (has_unstaged_changes(1))
                return error(_("cannot rebase: You have unstaged changes."));
-       if (!has_uncommitted_changes(0)) {
-               const char *cherry_pick_head = git_path_cherry_pick_head();
 
-               if (file_exists(cherry_pick_head) && unlink(cherry_pick_head))
-                       return error(_("could not remove CHERRY_PICK_HEAD"));
-               return 0;
-       }
+       is_clean = !has_uncommitted_changes(0);
 
        if (file_exists(rebase_path_amend())) {
                struct strbuf rev = STRBUF_INIT;
@@ -2786,19 +3426,107 @@ static int commit_staged_changes(struct replay_opts *opts)
                if (get_oid_hex(rev.buf, &to_amend))
                        return error(_("invalid contents: '%s'"),
                                rebase_path_amend());
-               if (oidcmp(&head, &to_amend))
+               if (!is_clean && oidcmp(&head, &to_amend))
                        return error(_("\nYou have uncommitted changes in your "
                                       "working tree. Please, commit them\n"
                                       "first and then run 'git rebase "
                                       "--continue' again."));
+               /*
+                * When skipping a failed fixup/squash, we need to edit the
+                * commit message, the current fixup list and count, and if it
+                * was the last fixup/squash in the chain, we need to clean up
+                * the commit message and if there was a squash, let the user
+                * edit it.
+                */
+               if (is_clean && !oidcmp(&head, &to_amend) &&
+                   opts->current_fixup_count > 0 &&
+                   file_exists(rebase_path_stopped_sha())) {
+                       const char *p = opts->current_fixups.buf;
+                       int len = opts->current_fixups.len;
+
+                       opts->current_fixup_count--;
+                       if (!len)
+                               BUG("Incorrect current_fixups:\n%s", p);
+                       while (len && p[len - 1] != '\n')
+                               len--;
+                       strbuf_setlen(&opts->current_fixups, len);
+                       if (write_message(p, len, rebase_path_current_fixups(),
+                                         0) < 0)
+                               return error(_("could not write file: '%s'"),
+                                            rebase_path_current_fixups());
+
+                       /*
+                        * If a fixup/squash in a fixup/squash chain failed, the
+                        * commit message is already correct, no need to commit
+                        * it again.
+                        *
+                        * Only if it is the final command in the fixup/squash
+                        * chain, and only if the chain is longer than a single
+                        * fixup/squash command (which was just skipped), do we
+                        * actually need to re-commit with a cleaned up commit
+                        * message.
+                        */
+                       if (opts->current_fixup_count > 0 &&
+                           !is_fixup(peek_command(todo_list, 0))) {
+                               final_fixup = 1;
+                               /*
+                                * If there was not a single "squash" in the
+                                * chain, we only need to clean up the commit
+                                * message, no need to bother the user with
+                                * opening the commit message in the editor.
+                                */
+                               if (!starts_with(p, "squash ") &&
+                                   !strstr(p, "\nsquash "))
+                                       flags = (flags & ~EDIT_MSG) | CLEANUP_MSG;
+                       } else if (is_fixup(peek_command(todo_list, 0))) {
+                               /*
+                                * We need to update the squash message to skip
+                                * the latest commit message.
+                                */
+                               struct commit *commit;
+                               const char *path = rebase_path_squash_msg();
+
+                               if (parse_head(&commit) ||
+                                   !(p = get_commit_buffer(commit, NULL)) ||
+                                   write_message(p, strlen(p), path, 0)) {
+                                       unuse_commit_buffer(commit, p);
+                                       return error(_("could not write file: "
+                                                      "'%s'"), path);
+                               }
+                               unuse_commit_buffer(commit, p);
+                       }
+               }
 
                strbuf_release(&rev);
                flags |= AMEND_MSG;
        }
 
-       if (run_git_commit(rebase_path_message(), opts, flags))
+       if (is_clean) {
+               const char *cherry_pick_head = git_path_cherry_pick_head();
+
+               if (file_exists(cherry_pick_head) && unlink(cherry_pick_head))
+                       return error(_("could not remove CHERRY_PICK_HEAD"));
+               if (!final_fixup)
+                       return 0;
+       }
+
+       if (run_git_commit(final_fixup ? NULL : rebase_path_message(),
+                          opts, flags))
                return error(_("could not commit staged changes."));
        unlink(rebase_path_amend());
+       if (final_fixup) {
+               unlink(rebase_path_fixup_msg());
+               unlink(rebase_path_squash_msg());
+       }
+       if (opts->current_fixup_count > 0) {
+               /*
+                * Whether final fixup or not, we just cleaned up the commit
+                * message...
+                */
+               unlink(rebase_path_current_fixups());
+               strbuf_reset(&opts->current_fixups);
+               opts->current_fixup_count = 0;
+       }
        return 0;
 }
 
@@ -2810,14 +3538,16 @@ int sequencer_continue(struct replay_opts *opts)
        if (read_and_refresh_cache(opts))
                return -1;
 
+       if (read_populate_opts(opts))
+               return -1;
        if (is_rebase_i(opts)) {
-               if (commit_staged_changes(opts))
+               if ((res = read_populate_todo(&todo_list, opts)))
+                       goto release_todo_list;
+               if (commit_staged_changes(opts, &todo_list))
                        return -1;
        } else if (!file_exists(get_todo_path(opts)))
                return continue_single_pick();
-       if (read_populate_opts(opts))
-               return -1;
-       if ((res = read_populate_todo(&todo_list, opts)))
+       else if ((res = read_populate_todo(&todo_list, opts)))
                goto release_todo_list;
 
        if (!is_rebase_i(opts)) {
@@ -2876,7 +3606,9 @@ int sequencer_pick_revisions(struct replay_opts *opts)
 
                if (!get_oid(name, &oid)) {
                        if (!lookup_commit_reference_gently(&oid, 1)) {
-                               enum object_type type = sha1_object_info(oid.hash, NULL);
+                               enum object_type type = oid_object_info(the_repository,
+                                                                       &oid,
+                                                                       NULL);
                                return error(_("%s: can't cherry-pick a %s"),
                                        name, type_name(type));
                        }
@@ -2986,6 +3718,348 @@ void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
        strbuf_release(&sob);
 }
 
+struct labels_entry {
+       struct hashmap_entry entry;
+       char label[FLEX_ARRAY];
+};
+
+static int labels_cmp(const void *fndata, const struct labels_entry *a,
+                     const struct labels_entry *b, const void *key)
+{
+       return key ? strcmp(a->label, key) : strcmp(a->label, b->label);
+}
+
+struct string_entry {
+       struct oidmap_entry entry;
+       char string[FLEX_ARRAY];
+};
+
+struct label_state {
+       struct oidmap commit2label;
+       struct hashmap labels;
+       struct strbuf buf;
+};
+
+static const char *label_oid(struct object_id *oid, const char *label,
+                            struct label_state *state)
+{
+       struct labels_entry *labels_entry;
+       struct string_entry *string_entry;
+       struct object_id dummy;
+       size_t len;
+       int i;
+
+       string_entry = oidmap_get(&state->commit2label, oid);
+       if (string_entry)
+               return string_entry->string;
+
+       /*
+        * For "uninteresting" commits, i.e. commits that are not to be
+        * rebased, and which can therefore not be labeled, we use a unique
+        * abbreviation of the commit name. This is slightly more complicated
+        * than calling find_unique_abbrev() because we also need to make
+        * sure that the abbreviation does not conflict with any other
+        * label.
+        *
+        * We disallow "interesting" commits to be labeled by a string that
+        * is a valid full-length hash, to ensure that we always can find an
+        * abbreviation for any uninteresting commit's names that does not
+        * clash with any other label.
+        */
+       if (!label) {
+               char *p;
+
+               strbuf_reset(&state->buf);
+               strbuf_grow(&state->buf, GIT_SHA1_HEXSZ);
+               label = p = state->buf.buf;
+
+               find_unique_abbrev_r(p, oid, default_abbrev);
+
+               /*
+                * We may need to extend the abbreviated hash so that there is
+                * no conflicting label.
+                */
+               if (hashmap_get_from_hash(&state->labels, strihash(p), p)) {
+                       size_t i = strlen(p) + 1;
+
+                       oid_to_hex_r(p, oid);
+                       for (; i < GIT_SHA1_HEXSZ; i++) {
+                               char save = p[i];
+                               p[i] = '\0';
+                               if (!hashmap_get_from_hash(&state->labels,
+                                                          strihash(p), p))
+                                       break;
+                               p[i] = save;
+                       }
+               }
+       } else if (((len = strlen(label)) == the_hash_algo->hexsz &&
+                   !get_oid_hex(label, &dummy)) ||
+                  (len == 1 && *label == '#') ||
+                  hashmap_get_from_hash(&state->labels,
+                                        strihash(label), label)) {
+               /*
+                * If the label already exists, or if the label is a valid full
+                * OID, or the label is a '#' (which we use as a separator
+                * between merge heads and oneline), we append a dash and a
+                * number to make it unique.
+                */
+               struct strbuf *buf = &state->buf;
+
+               strbuf_reset(buf);
+               strbuf_add(buf, label, len);
+
+               for (i = 2; ; i++) {
+                       strbuf_setlen(buf, len);
+                       strbuf_addf(buf, "-%d", i);
+                       if (!hashmap_get_from_hash(&state->labels,
+                                                  strihash(buf->buf),
+                                                  buf->buf))
+                               break;
+               }
+
+               label = buf->buf;
+       }
+
+       FLEX_ALLOC_STR(labels_entry, label, label);
+       hashmap_entry_init(labels_entry, strihash(label));
+       hashmap_add(&state->labels, labels_entry);
+
+       FLEX_ALLOC_STR(string_entry, string, label);
+       oidcpy(&string_entry->entry.oid, oid);
+       oidmap_put(&state->commit2label, string_entry);
+
+       return string_entry->string;
+}
+
+static int make_script_with_merges(struct pretty_print_context *pp,
+                                  struct rev_info *revs, FILE *out,
+                                  unsigned flags)
+{
+       int keep_empty = flags & TODO_LIST_KEEP_EMPTY;
+       int rebase_cousins = flags & TODO_LIST_REBASE_COUSINS;
+       struct strbuf buf = STRBUF_INIT, oneline = STRBUF_INIT;
+       struct strbuf label = STRBUF_INIT;
+       struct commit_list *commits = NULL, **tail = &commits, *iter;
+       struct commit_list *tips = NULL, **tips_tail = &tips;
+       struct commit *commit;
+       struct oidmap commit2todo = OIDMAP_INIT;
+       struct string_entry *entry;
+       struct oidset interesting = OIDSET_INIT, child_seen = OIDSET_INIT,
+               shown = OIDSET_INIT;
+       struct label_state state = { OIDMAP_INIT, { NULL }, STRBUF_INIT };
+
+       int abbr = flags & TODO_LIST_ABBREVIATE_CMDS;
+       const char *cmd_pick = abbr ? "p" : "pick",
+               *cmd_label = abbr ? "l" : "label",
+               *cmd_reset = abbr ? "t" : "reset",
+               *cmd_merge = abbr ? "m" : "merge";
+
+       oidmap_init(&commit2todo, 0);
+       oidmap_init(&state.commit2label, 0);
+       hashmap_init(&state.labels, (hashmap_cmp_fn) labels_cmp, NULL, 0);
+       strbuf_init(&state.buf, 32);
+
+       if (revs->cmdline.nr && (revs->cmdline.rev[0].flags & BOTTOM)) {
+               struct object_id *oid = &revs->cmdline.rev[0].item->oid;
+               FLEX_ALLOC_STR(entry, string, "onto");
+               oidcpy(&entry->entry.oid, oid);
+               oidmap_put(&state.commit2label, entry);
+       }
+
+       /*
+        * First phase:
+        * - get onelines for all commits
+        * - gather all branch tips (i.e. 2nd or later parents of merges)
+        * - label all branch tips
+        */
+       while ((commit = get_revision(revs))) {
+               struct commit_list *to_merge;
+               int is_octopus;
+               const char *p1, *p2;
+               struct object_id *oid;
+               int is_empty;
+
+               tail = &commit_list_insert(commit, tail)->next;
+               oidset_insert(&interesting, &commit->object.oid);
+
+               is_empty = is_original_commit_empty(commit);
+               if (!is_empty && (commit->object.flags & PATCHSAME))
+                       continue;
+
+               strbuf_reset(&oneline);
+               pretty_print_commit(pp, commit, &oneline);
+
+               to_merge = commit->parents ? commit->parents->next : NULL;
+               if (!to_merge) {
+                       /* non-merge commit: easy case */
+                       strbuf_reset(&buf);
+                       if (!keep_empty && is_empty)
+                               strbuf_addf(&buf, "%c ", comment_line_char);
+                       strbuf_addf(&buf, "%s %s %s", cmd_pick,
+                                   oid_to_hex(&commit->object.oid),
+                                   oneline.buf);
+
+                       FLEX_ALLOC_STR(entry, string, buf.buf);
+                       oidcpy(&entry->entry.oid, &commit->object.oid);
+                       oidmap_put(&commit2todo, entry);
+
+                       continue;
+               }
+
+               is_octopus = to_merge && to_merge->next;
+
+               if (is_octopus)
+                       BUG("Octopus merges not yet supported");
+
+               /* Create a label */
+               strbuf_reset(&label);
+               if (skip_prefix(oneline.buf, "Merge ", &p1) &&
+                   (p1 = strchr(p1, '\'')) &&
+                   (p2 = strchr(++p1, '\'')))
+                       strbuf_add(&label, p1, p2 - p1);
+               else if (skip_prefix(oneline.buf, "Merge pull request ",
+                                    &p1) &&
+                        (p1 = strstr(p1, " from ")))
+                       strbuf_addstr(&label, p1 + strlen(" from "));
+               else
+                       strbuf_addbuf(&label, &oneline);
+
+               for (p1 = label.buf; *p1; p1++)
+                       if (isspace(*p1))
+                               *(char *)p1 = '-';
+
+               strbuf_reset(&buf);
+               strbuf_addf(&buf, "%s -C %s",
+                           cmd_merge, oid_to_hex(&commit->object.oid));
+
+               /* label the tip of merged branch */
+               oid = &to_merge->item->object.oid;
+               strbuf_addch(&buf, ' ');
+
+               if (!oidset_contains(&interesting, oid))
+                       strbuf_addstr(&buf, label_oid(oid, NULL, &state));
+               else {
+                       tips_tail = &commit_list_insert(to_merge->item,
+                                                       tips_tail)->next;
+
+                       strbuf_addstr(&buf, label_oid(oid, label.buf, &state));
+               }
+               strbuf_addf(&buf, " # %s", oneline.buf);
+
+               FLEX_ALLOC_STR(entry, string, buf.buf);
+               oidcpy(&entry->entry.oid, &commit->object.oid);
+               oidmap_put(&commit2todo, entry);
+       }
+
+       /*
+        * Second phase:
+        * - label branch points
+        * - add HEAD to the branch tips
+        */
+       for (iter = commits; iter; iter = iter->next) {
+               struct commit_list *parent = iter->item->parents;
+               for (; parent; parent = parent->next) {
+                       struct object_id *oid = &parent->item->object.oid;
+                       if (!oidset_contains(&interesting, oid))
+                               continue;
+                       if (!oidset_contains(&child_seen, oid))
+                               oidset_insert(&child_seen, oid);
+                       else
+                               label_oid(oid, "branch-point", &state);
+               }
+
+               /* Add HEAD as implict "tip of branch" */
+               if (!iter->next)
+                       tips_tail = &commit_list_insert(iter->item,
+                                                       tips_tail)->next;
+       }
+
+       /*
+        * Third phase: output the todo list. This is a bit tricky, as we
+        * want to avoid jumping back and forth between revisions. To
+        * accomplish that goal, we walk backwards from the branch tips,
+        * gathering commits not yet shown, reversing the list on the fly,
+        * then outputting that list (labeling revisions as needed).
+        */
+       fprintf(out, "%s onto\n", cmd_label);
+       for (iter = tips; iter; iter = iter->next) {
+               struct commit_list *list = NULL, *iter2;
+
+               commit = iter->item;
+               if (oidset_contains(&shown, &commit->object.oid))
+                       continue;
+               entry = oidmap_get(&state.commit2label, &commit->object.oid);
+
+               if (entry)
+                       fprintf(out, "\n# Branch %s\n", entry->string);
+               else
+                       fprintf(out, "\n");
+
+               while (oidset_contains(&interesting, &commit->object.oid) &&
+                      !oidset_contains(&shown, &commit->object.oid)) {
+                       commit_list_insert(commit, &list);
+                       if (!commit->parents) {
+                               commit = NULL;
+                               break;
+                       }
+                       commit = commit->parents->item;
+               }
+
+               if (!commit)
+                       fprintf(out, "%s %s\n", cmd_reset,
+                               rebase_cousins ? "onto" : "[new root]");
+               else {
+                       const char *to = NULL;
+
+                       entry = oidmap_get(&state.commit2label,
+                                          &commit->object.oid);
+                       if (entry)
+                               to = entry->string;
+                       else if (!rebase_cousins)
+                               to = label_oid(&commit->object.oid, NULL,
+                                              &state);
+
+                       if (!to || !strcmp(to, "onto"))
+                               fprintf(out, "%s onto\n", cmd_reset);
+                       else {
+                               strbuf_reset(&oneline);
+                               pretty_print_commit(pp, commit, &oneline);
+                               fprintf(out, "%s %s # %s\n",
+                                       cmd_reset, to, oneline.buf);
+                       }
+               }
+
+               for (iter2 = list; iter2; iter2 = iter2->next) {
+                       struct object_id *oid = &iter2->item->object.oid;
+                       entry = oidmap_get(&commit2todo, oid);
+                       /* only show if not already upstream */
+                       if (entry)
+                               fprintf(out, "%s\n", entry->string);
+                       entry = oidmap_get(&state.commit2label, oid);
+                       if (entry)
+                               fprintf(out, "%s %s\n",
+                                       cmd_label, entry->string);
+                       oidset_insert(&shown, oid);
+               }
+
+               free_commit_list(list);
+       }
+
+       free_commit_list(commits);
+       free_commit_list(tips);
+
+       strbuf_release(&label);
+       strbuf_release(&oneline);
+       strbuf_release(&buf);
+
+       oidmap_free(&commit2todo, 1);
+       oidmap_free(&state.commit2label, 1);
+       hashmap_free(&state.labels, 1);
+       strbuf_release(&state.buf);
+
+       return 0;
+}
+
 int sequencer_make_script(FILE *out, int argc, const char **argv,
                          unsigned flags)
 {
@@ -2996,11 +4070,13 @@ int sequencer_make_script(FILE *out, int argc, const char **argv,
        struct commit *commit;
        int keep_empty = flags & TODO_LIST_KEEP_EMPTY;
        const char *insn = flags & TODO_LIST_ABBREVIATE_CMDS ? "p" : "pick";
+       int rebase_merges = flags & TODO_LIST_REBASE_MERGES;
 
        init_revisions(&revs, NULL);
        revs.verbose_header = 1;
-       revs.max_parents = 1;
-       revs.cherry_pick = 1;
+       if (!rebase_merges)
+               revs.max_parents = 1;
+       revs.cherry_mark = 1;
        revs.limited = 1;
        revs.reverse = 1;
        revs.right_only = 1;
@@ -3024,9 +4100,16 @@ int sequencer_make_script(FILE *out, int argc, const char **argv,
        if (prepare_revision_walk(&revs) < 0)
                return error(_("make_script: error preparing revisions"));
 
+       if (rebase_merges)
+               return make_script_with_merges(&pp, &revs, out, flags);
+
        while ((commit = get_revision(&revs))) {
+               int is_empty  = is_original_commit_empty(commit);
+
+               if (!is_empty && (commit->object.flags & PATCHSAME))
+                       continue;
                strbuf_reset(&buf);
-               if (!keep_empty && is_original_commit_empty(commit))
+               if (!keep_empty && is_empty)
                        strbuf_addf(&buf, "%c ", comment_line_char);
                strbuf_addf(&buf, "%s %s ", insn,
                            oid_to_hex(&commit->object.oid));
@@ -3113,8 +4196,16 @@ int transform_todos(unsigned flags)
                                          short_commit_name(item->commit) :
                                          oid_to_hex(&item->commit->object.oid);
 
+                       if (item->command == TODO_MERGE) {
+                               if (item->flags & TODO_EDIT_MERGE_MSG)
+                                       strbuf_addstr(&buf, " -c");
+                               else
+                                       strbuf_addstr(&buf, " -C");
+                       }
+
                        strbuf_addf(&buf, " %s", oid);
                }
+
                /* add all the rest */
                if (!item->arg_len)
                        strbuf_addch(&buf, '\n');
@@ -3294,8 +4385,7 @@ int skip_unnecessary_picks(void)
                oid = &item->commit->object.oid;
        }
        if (i > 0) {
-               int offset = i < todo_list.nr ?
-                       todo_list.items[i].offset_in_buf : todo_list.buf.len;
+               int offset = get_item_line_offset(&todo_list, i);
                const char *done_path = rebase_path_done();
 
                fd = open(done_path, O_CREAT | O_WRONLY | O_APPEND, 0666);
@@ -3390,7 +4480,7 @@ int rearrange_squash(void)
                struct subject2item_entry *entry;
 
                next[i] = tail[i] = -1;
-               if (item->command >= TODO_EXEC) {
+               if (!item->commit || item->command == TODO_DROP) {
                        subjects[i] = NULL;
                        continue;
                }
@@ -3475,12 +4565,10 @@ int rearrange_squash(void)
                                continue;
 
                        while (cur >= 0) {
-                               int offset = todo_list.items[cur].offset_in_buf;
-                               int end_offset = cur + 1 < todo_list.nr ?
-                                       todo_list.items[cur + 1].offset_in_buf :
-                                       todo_list.buf.len;
-                               char *bol = todo_list.buf.buf + offset;
-                               char *eol = todo_list.buf.buf + end_offset;
+                               const char *bol =
+                                       get_item_line(&todo_list, cur);
+                               const char *eol =
+                                       get_item_line(&todo_list, cur + 1);
 
                                /* replace 'pick', by 'fixup' or 'squash' */
                                command = todo_list.items[cur].command;
index e45b178dfc41d723bf186f20674c4515d7c7fa00..c5787c6b566bbc89caad1a099f4281fecba01766 100644 (file)
@@ -44,10 +44,18 @@ struct replay_opts {
        char **xopts;
        size_t xopts_nr, xopts_alloc;
 
+       /* Used by fixup/squash */
+       struct strbuf current_fixups;
+       int current_fixup_count;
+
+       /* placeholder commit for -i --root */
+       struct object_id squash_onto;
+       int have_squash_onto;
+
        /* Only used by REPLAY_NONE */
        struct rev_info *revs;
 };
-#define REPLAY_OPTS_INIT { -1 }
+#define REPLAY_OPTS_INIT { .action = -1, .current_fixups = STRBUF_INIT }
 
 /* Call this to setup defaults before parsing command line options */
 void sequencer_init_config(struct replay_opts *opts);
@@ -59,6 +67,13 @@ int sequencer_remove_state(struct replay_opts *opts);
 #define TODO_LIST_KEEP_EMPTY (1U << 0)
 #define TODO_LIST_SHORTEN_IDS (1U << 1)
 #define TODO_LIST_ABBREVIATE_CMDS (1U << 2)
+#define TODO_LIST_REBASE_MERGES (1U << 3)
+/*
+ * When rebasing merges, commits that do have the base commit as ancestor
+ * ("cousins") are *not* rebased onto the new base by default. If those
+ * commits should be rebased onto the new base, this flag needs to be passed.
+ */
+#define TODO_LIST_REBASE_COUSINS (1U << 4)
 int sequencer_make_script(FILE *out, int argc, const char **argv,
                          unsigned flags);
 
diff --git a/serve.c b/serve.c
new file mode 100644 (file)
index 0000000..bda085f
--- /dev/null
+++ b/serve.c
@@ -0,0 +1,258 @@
+#include "cache.h"
+#include "repository.h"
+#include "config.h"
+#include "pkt-line.h"
+#include "version.h"
+#include "argv-array.h"
+#include "ls-refs.h"
+#include "serve.h"
+#include "upload-pack.h"
+
+static int always_advertise(struct repository *r,
+                           struct strbuf *value)
+{
+       return 1;
+}
+
+static int agent_advertise(struct repository *r,
+                          struct strbuf *value)
+{
+       if (value)
+               strbuf_addstr(value, git_user_agent_sanitized());
+       return 1;
+}
+
+struct protocol_capability {
+       /*
+        * The name of the capability.  The server uses this name when
+        * advertising this capability, and the client uses this name to
+        * specify this capability.
+        */
+       const char *name;
+
+       /*
+        * Function queried to see if a capability should be advertised.
+        * Optionally a value can be specified by adding it to 'value'.
+        * If a value is added to 'value', the server will advertise this
+        * capability as "<name>=<value>" instead of "<name>".
+        */
+       int (*advertise)(struct repository *r, struct strbuf *value);
+
+       /*
+        * Function called when a client requests the capability as a command.
+        * The function will be provided the capabilities requested via 'keys'
+        * as well as a struct packet_reader 'request' which the command should
+        * use to read the command specific part of the request.  Every command
+        * MUST read until a flush packet is seen before sending a response.
+        *
+        * This field should be NULL for capabilities which are not commands.
+        */
+       int (*command)(struct repository *r,
+                      struct argv_array *keys,
+                      struct packet_reader *request);
+};
+
+static struct protocol_capability capabilities[] = {
+       { "agent", agent_advertise, NULL },
+       { "ls-refs", always_advertise, ls_refs },
+       { "fetch", upload_pack_advertise, upload_pack_v2 },
+       { "server-option", always_advertise, NULL },
+};
+
+static void advertise_capabilities(void)
+{
+       struct strbuf capability = STRBUF_INIT;
+       struct strbuf value = STRBUF_INIT;
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(capabilities); i++) {
+               struct protocol_capability *c = &capabilities[i];
+
+               if (c->advertise(the_repository, &value)) {
+                       strbuf_addstr(&capability, c->name);
+
+                       if (value.len) {
+                               strbuf_addch(&capability, '=');
+                               strbuf_addbuf(&capability, &value);
+                       }
+
+                       strbuf_addch(&capability, '\n');
+                       packet_write(1, capability.buf, capability.len);
+               }
+
+               strbuf_reset(&capability);
+               strbuf_reset(&value);
+       }
+
+       packet_flush(1);
+       strbuf_release(&capability);
+       strbuf_release(&value);
+}
+
+static struct protocol_capability *get_capability(const char *key)
+{
+       int i;
+
+       if (!key)
+               return NULL;
+
+       for (i = 0; i < ARRAY_SIZE(capabilities); i++) {
+               struct protocol_capability *c = &capabilities[i];
+               const char *out;
+               if (skip_prefix(key, c->name, &out) && (!*out || *out == '='))
+                       return c;
+       }
+
+       return NULL;
+}
+
+static int is_valid_capability(const char *key)
+{
+       const struct protocol_capability *c = get_capability(key);
+
+       return c && c->advertise(the_repository, NULL);
+}
+
+static int is_command(const char *key, struct protocol_capability **command)
+{
+       const char *out;
+
+       if (skip_prefix(key, "command=", &out)) {
+               struct protocol_capability *cmd = get_capability(out);
+
+               if (*command)
+                       die("command '%s' requested after already requesting command '%s'",
+                           out, (*command)->name);
+               if (!cmd || !cmd->advertise(the_repository, NULL) || !cmd->command)
+                       die("invalid command '%s'", out);
+
+               *command = cmd;
+               return 1;
+       }
+
+       return 0;
+}
+
+int has_capability(const struct argv_array *keys, const char *capability,
+                  const char **value)
+{
+       int i;
+       for (i = 0; i < keys->argc; i++) {
+               const char *out;
+               if (skip_prefix(keys->argv[i], capability, &out) &&
+                   (!*out || *out == '=')) {
+                       if (value) {
+                               if (*out == '=')
+                                       out++;
+                               *value = out;
+                       }
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
+enum request_state {
+       PROCESS_REQUEST_KEYS,
+       PROCESS_REQUEST_DONE,
+};
+
+static int process_request(void)
+{
+       enum request_state state = PROCESS_REQUEST_KEYS;
+       struct packet_reader reader;
+       struct argv_array keys = ARGV_ARRAY_INIT;
+       struct protocol_capability *command = NULL;
+
+       packet_reader_init(&reader, 0, NULL, 0,
+                          PACKET_READ_CHOMP_NEWLINE |
+                          PACKET_READ_GENTLE_ON_EOF);
+
+       /*
+        * Check to see if the client closed their end before sending another
+        * request.  If so we can terminate the connection.
+        */
+       if (packet_reader_peek(&reader) == PACKET_READ_EOF)
+               return 1;
+       reader.options = PACKET_READ_CHOMP_NEWLINE;
+
+       while (state != PROCESS_REQUEST_DONE) {
+               switch (packet_reader_peek(&reader)) {
+               case PACKET_READ_EOF:
+                       BUG("Should have already died when seeing EOF");
+               case PACKET_READ_NORMAL:
+                       /* collect request; a sequence of keys and values */
+                       if (is_command(reader.line, &command) ||
+                           is_valid_capability(reader.line))
+                               argv_array_push(&keys, reader.line);
+                       else
+                               die("unknown capability '%s'", reader.line);
+
+                       /* Consume the peeked line */
+                       packet_reader_read(&reader);
+                       break;
+               case PACKET_READ_FLUSH:
+                       /*
+                        * If no command and no keys were given then the client
+                        * wanted to terminate the connection.
+                        */
+                       if (!keys.argc)
+                               return 1;
+
+                       /*
+                        * The flush packet isn't consume here like it is in
+                        * the other parts of this switch statement.  This is
+                        * so that the command can read the flush packet and
+                        * see the end of the request in the same way it would
+                        * if command specific arguments were provided after a
+                        * delim packet.
+                        */
+                       state = PROCESS_REQUEST_DONE;
+                       break;
+               case PACKET_READ_DELIM:
+                       /* Consume the peeked line */
+                       packet_reader_read(&reader);
+
+                       state = PROCESS_REQUEST_DONE;
+                       break;
+               }
+       }
+
+       if (!command)
+               die("no command requested");
+
+       command->command(the_repository, &keys, &reader);
+
+       argv_array_clear(&keys);
+       return 0;
+}
+
+/* Main serve loop for protocol version 2 */
+void serve(struct serve_options *options)
+{
+       if (options->advertise_capabilities || !options->stateless_rpc) {
+               /* serve by default supports v2 */
+               packet_write_fmt(1, "version 2\n");
+
+               advertise_capabilities();
+               /*
+                * If only the list of capabilities was requested exit
+                * immediately after advertising capabilities
+                */
+               if (options->advertise_capabilities)
+                       return;
+       }
+
+       /*
+        * If stateless-rpc was requested then exit after
+        * a single request/response exchange
+        */
+       if (options->stateless_rpc) {
+               process_request();
+       } else {
+               for (;;)
+                       if (process_request())
+                               break;
+       }
+}
diff --git a/serve.h b/serve.h
new file mode 100644 (file)
index 0000000..fe65ba9
--- /dev/null
+++ b/serve.h
@@ -0,0 +1,15 @@
+#ifndef SERVE_H
+#define SERVE_H
+
+struct argv_array;
+extern int has_capability(const struct argv_array *keys, const char *capability,
+                         const char **value);
+
+struct serve_options {
+       unsigned advertise_capabilities;
+       unsigned stateless_rpc;
+};
+#define SERVE_OPTIONS_INIT { 0 }
+extern void serve(struct serve_options *options);
+
+#endif /* SERVE_H */
index 26a6c20b7d420f679d7cceaeba4acdb8ae8c00e7..7ce6dcd67b7bef92f79bc24c319b2e46150980a3 100644 (file)
@@ -1,9 +1,11 @@
 #include "cache.h"
+#include "repository.h"
 #include "refs.h"
 #include "object.h"
 #include "commit.h"
 #include "tag.h"
 #include "packfile.h"
+#include "object-store.h"
 
 /*
  * Create the file "path" by writing to a temporary file and renaming
@@ -90,8 +92,6 @@ static struct pack_info {
        int old_num;
        int new_num;
        int nr_alloc;
-       int nr_heads;
-       unsigned char (*head)[20];
 } **info;
 static int num_pack;
 static const char *objdir;
@@ -199,8 +199,7 @@ static void init_pack_info(const char *infofile, int force)
        objdir = get_object_directory();
        objdirlen = strlen(objdir);
 
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next) {
+       for (p = get_packed_git(the_repository); p; p = p->next) {
                /* we ignore things on alternate path since they are
                 * not available to the pullers in general.
                 */
@@ -210,7 +209,7 @@ static void init_pack_info(const char *infofile, int force)
        }
        num_pack = i;
        info = xcalloc(num_pack, sizeof(struct pack_info *));
-       for (i = 0, p = packed_git; p; p = p->next) {
+       for (i = 0, p = get_packed_git(the_repository); p; p = p->next) {
                if (!p->pack_local)
                        continue;
                info[i] = xcalloc(1, sizeof(struct pack_info));
@@ -224,12 +223,9 @@ static void init_pack_info(const char *infofile, int force)
        else
                stale = 1;
 
-       for (i = 0; i < num_pack; i++) {
-               if (stale) {
+       for (i = 0; i < num_pack; i++)
+               if (stale)
                        info[i]->old_num = -1;
-                       info[i]->nr_heads = 0;
-               }
-       }
 
        /* renumber them */
        QSORT(info, num_pack, compare_info);
diff --git a/setup.c b/setup.c
index 72877796420b06213665f5d357decb202e71fa91..b24c811c1c3129c8f11fa0fffa4e937705792e36 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -3,6 +3,7 @@
 #include "config.h"
 #include "dir.h"
 #include "string-list.h"
+#include "chdir-notify.h"
 
 static int inside_git_dir = -1;
 static int inside_work_tree = -1;
@@ -378,7 +379,7 @@ int is_inside_work_tree(void)
 
 void setup_work_tree(void)
 {
-       const char *work_tree, *git_dir;
+       const char *work_tree;
        static int initialized = 0;
 
        if (initialized)
@@ -388,10 +389,7 @@ void setup_work_tree(void)
                die(_("unable to set up work tree using invalid config"));
 
        work_tree = get_git_work_tree();
-       git_dir = get_git_dir();
-       if (!is_absolute_path(git_dir))
-               git_dir = real_path(get_git_dir());
-       if (!work_tree || chdir(work_tree))
+       if (!work_tree || chdir_notify(work_tree))
                die(_("this operation must be run in a work tree"));
 
        /*
@@ -401,7 +399,6 @@ void setup_work_tree(void)
        if (getenv(GIT_WORK_TREE_ENVIRONMENT))
                setenv(GIT_WORK_TREE_ENVIRONMENT, ".", 1);
 
-       set_git_dir(remove_leading_path(git_dir, work_tree));
        initialized = 1;
 }
 
@@ -542,7 +539,7 @@ void read_gitfile_error_die(int error_code, const char *path, const char *dir)
        case READ_GITFILE_ERR_NOT_A_REPO:
                die(_("not a git repository: %s"), dir);
        default:
-               die("BUG: unknown error code");
+               BUG("unknown error code");
        }
 }
 
@@ -1089,7 +1086,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
                      "Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)."),
                    dir.buf);
        default:
-               die("BUG: unhandled setup_git_directory_1() result");
+               BUG("unhandled setup_git_directory_1() result");
        }
 
        if (prefix)
@@ -1116,8 +1113,7 @@ const char *setup_git_directory_gently(int *nongit_ok)
                        const char *gitdir = getenv(GIT_DIR_ENVIRONMENT);
                        if (!gitdir)
                                gitdir = DEFAULT_GIT_DIR_ENVIRONMENT;
-                       repo_set_gitdir(the_repository, gitdir);
-                       setup_git_env();
+                       setup_git_env(gitdir);
                }
                if (startup_info->have_repository)
                        repo_set_hash_algo(the_repository, repo_fmt.hash_algo);
index 838b3bf8478cfdfcd78f866e69dc0f8c5cbf3c9e..265941fbf40d4a6c64bb1e77b2aef7a5950493a7 100644 (file)
@@ -41,9 +41,26 @@ void oid_array_clear(struct oid_array *array)
        array->sorted = 0;
 }
 
+
+int oid_array_for_each(struct oid_array *array,
+                      for_each_oid_fn fn,
+                      void *data)
+{
+       int i;
+
+       /* No oid_array_sort() here! See the api-oid-array.txt docs! */
+
+       for (i = 0; i < array->nr; i++) {
+               int ret = fn(array->oid + i, data);
+               if (ret)
+                       return ret;
+       }
+       return 0;
+}
+
 int oid_array_for_each_unique(struct oid_array *array,
-                               for_each_oid_fn fn,
-                               void *data)
+                             for_each_oid_fn fn,
+                             void *data)
 {
        int i;
 
index 04b0756334da7adf1e3eefb3f521f8c95d263046..232bf9501729696846f514e13ce5f23c425d9d27 100644 (file)
@@ -16,8 +16,11 @@ void oid_array_clear(struct oid_array *array);
 
 typedef int (*for_each_oid_fn)(const struct object_id *oid,
                               void *data);
+int oid_array_for_each(struct oid_array *array,
+                      for_each_oid_fn fn,
+                      void *data);
 int oid_array_for_each_unique(struct oid_array *array,
-                              for_each_oid_fn fn,
-                              void *data);
+                             for_each_oid_fn fn,
+                             void *data);
 
 #endif /* SHA1_ARRAY_H */
similarity index 85%
rename from sha1_file.c
rename to sha1-file.c
index 53f0a3693fef1e03659cf3b41d15246ad419911e..695e5c62764cf4befe09467f1a658b25c01baba1 100644 (file)
@@ -22,6 +22,8 @@
 #include "pack-revindex.h"
 #include "sha1-lookup.h"
 #include "bulk-checkin.h"
+#include "repository.h"
+#include "replace-object.h"
 #include "streaming.h"
 #include "dir.h"
 #include "list.h"
 #include "quote.h"
 #include "packfile.h"
 #include "fetch-object.h"
+#include "object-store.h"
+
+/* The maximum size for an object header. */
+#define MAX_HEADER_LEN 32
+
+
+#define EMPTY_TREE_SHA1_BIN_LITERAL \
+        "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
+        "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
+
+#define EMPTY_BLOB_SHA1_BIN_LITERAL \
+       "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \
+       "\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91"
 
 const unsigned char null_sha1[GIT_MAX_RAWSZ];
 const struct object_id null_oid;
-const struct object_id empty_tree_oid = {
+static const struct object_id empty_tree_oid = {
        EMPTY_TREE_SHA1_BIN_LITERAL
 };
-const struct object_id empty_blob_oid = {
+static const struct object_id empty_blob_oid = {
        EMPTY_BLOB_SHA1_BIN_LITERAL
 };
 
@@ -95,6 +110,18 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
        },
 };
 
+const char *empty_tree_oid_hex(void)
+{
+       static char buf[GIT_MAX_HEXSZ + 1];
+       return oid_to_hex_r(buf, the_hash_algo->empty_tree);
+}
+
+const char *empty_blob_oid_hex(void)
+{
+       static char buf[GIT_MAX_HEXSZ + 1];
+       return oid_to_hex_r(buf, the_hash_algo->empty_blob);
+}
+
 /*
  * This is meant to hold a *small* number of objects that you would
  * want read_sha1_file() to be able to return, but yet you do not want
@@ -102,7 +129,7 @@ const struct git_hash_algo hash_algos[GIT_HASH_NALGOS] = {
  * application).
  */
 static struct cached_object {
-       unsigned char sha1[20];
+       struct object_id oid;
        enum object_type type;
        void *buf;
        unsigned long size;
@@ -110,22 +137,22 @@ static struct cached_object {
 static int cached_object_nr, cached_object_alloc;
 
 static struct cached_object empty_tree = {
-       EMPTY_TREE_SHA1_BIN_LITERAL,
+       { EMPTY_TREE_SHA1_BIN_LITERAL },
        OBJ_TREE,
        "",
        0
 };
 
-static struct cached_object *find_cached_object(const unsigned char *sha1)
+static struct cached_object *find_cached_object(const struct object_id *oid)
 {
        int i;
        struct cached_object *co = cached_objects;
 
        for (i = 0; i < cached_object_nr; i++, co++) {
-               if (!hashcmp(co->sha1, sha1))
+               if (!oidcmp(&co->oid, oid))
                        return co;
        }
-       if (!hashcmp(sha1, empty_tree.sha1))
+       if (!oidcmp(oid, the_hash_algo->empty_tree))
                return &empty_tree;
        return NULL;
 }
@@ -136,7 +163,7 @@ static int get_conv_flags(unsigned flags)
        if (flags & HASH_RENORMALIZE)
                return CONV_EOL_RENORMALIZE;
        else if (flags & HASH_WRITE_OBJECT)
-         return global_conv_flags_eol;
+               return global_conv_flags_eol | CONV_WRITE_OBJECT;
        else
                return 0;
 }
@@ -319,9 +346,9 @@ static void fill_sha1_path(struct strbuf *buf, const unsigned char *sha1)
        }
 }
 
-void sha1_file_name(struct strbuf *buf, const unsigned char *sha1)
+void sha1_file_name(struct repository *r, struct strbuf *buf, const unsigned char *sha1)
 {
-       strbuf_addstr(buf, get_object_directory());
+       strbuf_addstr(buf, r->objects->objectdir);
        strbuf_addch(buf, '/');
        fill_sha1_path(buf, sha1);
 }
@@ -340,13 +367,12 @@ static const char *alt_sha1_path(struct alternate_object_database *alt,
        return buf->buf;
 }
 
-struct alternate_object_database *alt_odb_list;
-static struct alternate_object_database **alt_odb_tail;
-
 /*
  * Return non-zero iff the path is usable as an alternate object database.
  */
-static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
+static int alt_odb_usable(struct raw_object_store *o,
+                         struct strbuf *path,
+                         const char *normalized_objdir)
 {
        struct alternate_object_database *alt;
 
@@ -362,7 +388,7 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
         * Prevent the common mistake of listing the same
         * thing twice, or object directory itself.
         */
-       for (alt = alt_odb_list; alt; alt = alt->next) {
+       for (alt = o->alt_odb_list; alt; alt = alt->next) {
                if (!fspathcmp(path->buf, alt->path))
                        return 0;
        }
@@ -387,9 +413,11 @@ static int alt_odb_usable(struct strbuf *path, const char *normalized_objdir)
  * SHA1, an extra slash for the first level indirection, and the
  * terminating NUL.
  */
-static void read_info_alternates(const char * relative_base, int depth);
-static int link_alt_odb_entry(const char *entry, const char *relative_base,
-       int depth, const char *normalized_objdir)
+static void read_info_alternates(struct repository *r,
+                                const char *relative_base,
+                                int depth);
+static int link_alt_odb_entry(struct repository *r, const char *entry,
+       const char *relative_base, int depth, const char *normalized_objdir)
 {
        struct alternate_object_database *ent;
        struct strbuf pathbuf = STRBUF_INIT;
@@ -414,7 +442,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
        while (pathbuf.len && pathbuf.buf[pathbuf.len - 1] == '/')
                strbuf_setlen(&pathbuf, pathbuf.len - 1);
 
-       if (!alt_odb_usable(&pathbuf, normalized_objdir)) {
+       if (!alt_odb_usable(r->objects, &pathbuf, normalized_objdir)) {
                strbuf_release(&pathbuf);
                return -1;
        }
@@ -422,12 +450,12 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base,
        ent = alloc_alt_odb(pathbuf.buf);
 
        /* add the alternate entry */
-       *alt_odb_tail = ent;
-       alt_odb_tail = &(ent->next);
+       *r->objects->alt_odb_tail = ent;
+       r->objects->alt_odb_tail = &(ent->next);
        ent->next = NULL;
 
        /* recursively add alternates */
-       read_info_alternates(pathbuf.buf, depth + 1);
+       read_info_alternates(r, pathbuf.buf, depth + 1);
 
        strbuf_release(&pathbuf);
        return 0;
@@ -462,8 +490,8 @@ static const char *parse_alt_odb_entry(const char *string,
        return end;
 }
 
-static void link_alt_odb_entries(const char *alt, int sep,
-                                const char *relative_base, int depth)
+static void link_alt_odb_entries(struct repository *r, const char *alt,
+                                int sep, const char *relative_base, int depth)
 {
        struct strbuf objdirbuf = STRBUF_INIT;
        struct strbuf entry = STRBUF_INIT;
@@ -477,7 +505,7 @@ static void link_alt_odb_entries(const char *alt, int sep,
                return;
        }
 
-       strbuf_add_absolute_path(&objdirbuf, get_object_directory());
+       strbuf_add_absolute_path(&objdirbuf, r->objects->objectdir);
        if (strbuf_normalize_path(&objdirbuf) < 0)
                die("unable to normalize object directory: %s",
                    objdirbuf.buf);
@@ -486,13 +514,16 @@ static void link_alt_odb_entries(const char *alt, int sep,
                alt = parse_alt_odb_entry(alt, sep, &entry);
                if (!entry.len)
                        continue;
-               link_alt_odb_entry(entry.buf, relative_base, depth, objdirbuf.buf);
+               link_alt_odb_entry(r, entry.buf,
+                                  relative_base, depth, objdirbuf.buf);
        }
        strbuf_release(&entry);
        strbuf_release(&objdirbuf);
 }
 
-static void read_info_alternates(const char * relative_base, int depth)
+static void read_info_alternates(struct repository *r,
+                                const char *relative_base,
+                                int depth)
 {
        char *path;
        struct strbuf buf = STRBUF_INIT;
@@ -504,7 +535,7 @@ static void read_info_alternates(const char * relative_base, int depth)
                return;
        }
 
-       link_alt_odb_entries(buf.buf, '\n', relative_base, depth);
+       link_alt_odb_entries(r, buf.buf, '\n', relative_base, depth);
        strbuf_release(&buf);
        free(path);
 }
@@ -557,8 +588,9 @@ void add_to_alternates_file(const char *reference)
                fprintf_or_die(out, "%s\n", reference);
                if (commit_lock_file(&lock))
                        die_errno("unable to move new alternates file into place");
-               if (alt_odb_tail)
-                       link_alt_odb_entries(reference, '\n', NULL, 0);
+               if (the_repository->objects->alt_odb_tail)
+                       link_alt_odb_entries(the_repository, reference,
+                                            '\n', NULL, 0);
        }
        free(alts);
 }
@@ -569,15 +601,16 @@ void add_to_alternates_memory(const char *reference)
         * Make sure alternates are initialized, or else our entry may be
         * overwritten when they are.
         */
-       prepare_alt_odb();
+       prepare_alt_odb(the_repository);
 
-       link_alt_odb_entries(reference, '\n', NULL, 0);
+       link_alt_odb_entries(the_repository, reference,
+                            '\n', NULL, 0);
 }
 
 /*
  * Compute the exact path an alternate is at and returns it. In case of
  * error NULL is returned and the human readable error is added to `err`
- * `path` may be relative and should point to $GITDIR.
+ * `path` may be relative and should point to $GIT_DIR.
  * `err` must not be null.
  */
 char *compute_alternate_path(const char *path, struct strbuf *err)
@@ -654,8 +687,8 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
        struct alternate_object_database *ent;
        int r = 0;
 
-       prepare_alt_odb();
-       for (ent = alt_odb_list; ent; ent = ent->next) {
+       prepare_alt_odb(the_repository);
+       for (ent = the_repository->objects->alt_odb_list; ent; ent = ent->next) {
                r = fn(ent, cb);
                if (r)
                        break;
@@ -663,19 +696,15 @@ int foreach_alt_odb(alt_odb_fn fn, void *cb)
        return r;
 }
 
-void prepare_alt_odb(void)
+void prepare_alt_odb(struct repository *r)
 {
-       const char *alt;
-
-       if (alt_odb_tail)
+       if (r->objects->alt_odb_tail)
                return;
 
-       alt = getenv(ALTERNATE_DB_ENVIRONMENT);
+       r->objects->alt_odb_tail = &r->objects->alt_odb_list;
+       link_alt_odb_entries(r, r->objects->alternate_db, PATH_SEP, NULL, 0);
 
-       alt_odb_tail = &alt_odb_list;
-       link_alt_odb_entries(alt, PATH_SEP, NULL, 0);
-
-       read_info_alternates(get_object_directory(), 0);
+       read_info_alternates(r, r->objects->objectdir, 0);
 }
 
 /* Returns 1 if we have successfully freshened the file, 0 otherwise. */
@@ -702,42 +731,42 @@ int check_and_freshen_file(const char *fn, int freshen)
        return 1;
 }
 
-static int check_and_freshen_local(const unsigned char *sha1, int freshen)
+static int check_and_freshen_local(const struct object_id *oid, int freshen)
 {
        static struct strbuf buf = STRBUF_INIT;
 
        strbuf_reset(&buf);
-       sha1_file_name(&buf, sha1);
+       sha1_file_name(the_repository, &buf, oid->hash);
 
        return check_and_freshen_file(buf.buf, freshen);
 }
 
-static int check_and_freshen_nonlocal(const unsigned char *sha1, int freshen)
+static int check_and_freshen_nonlocal(const struct object_id *oid, int freshen)
 {
        struct alternate_object_database *alt;
-       prepare_alt_odb();
-       for (alt = alt_odb_list; alt; alt = alt->next) {
-               const char *path = alt_sha1_path(alt, sha1);
+       prepare_alt_odb(the_repository);
+       for (alt = the_repository->objects->alt_odb_list; alt; alt = alt->next) {
+               const char *path = alt_sha1_path(alt, oid->hash);
                if (check_and_freshen_file(path, freshen))
                        return 1;
        }
        return 0;
 }
 
-static int check_and_freshen(const unsigned char *sha1, int freshen)
+static int check_and_freshen(const struct object_id *oid, int freshen)
 {
-       return check_and_freshen_local(sha1, freshen) ||
-              check_and_freshen_nonlocal(sha1, freshen);
+       return check_and_freshen_local(oid, freshen) ||
+              check_and_freshen_nonlocal(oid, freshen);
 }
 
-int has_loose_object_nonlocal(const unsigned char *sha1)
+int has_loose_object_nonlocal(const struct object_id *oid)
 {
-       return check_and_freshen_nonlocal(sha1, 0);
+       return check_and_freshen_nonlocal(oid, 0);
 }
 
-static int has_loose_object(const unsigned char *sha1)
+static int has_loose_object(const struct object_id *oid)
 {
-       return check_and_freshen(sha1, 0);
+       return check_and_freshen(oid, 0);
 }
 
 static void mmap_limit_check(size_t length)
@@ -784,22 +813,22 @@ void *xmmap(void *start, size_t length,
  * With "map" == NULL, try reading the object named with "sha1" using
  * the streaming interface and rehash it to do the same.
  */
-int check_sha1_signature(const unsigned char *sha1, void *map,
-                        unsigned long size, const char *type)
+int check_object_signature(const struct object_id *oid, void *map,
+                          unsigned long size, const char *type)
 {
        struct object_id real_oid;
        enum object_type obj_type;
        struct git_istream *st;
        git_hash_ctx c;
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
        int hdrlen;
 
        if (map) {
                hash_object_file(map, size, type, &real_oid);
-               return hashcmp(sha1, real_oid.hash) ? -1 : 0;
+               return oidcmp(oid, &real_oid) ? -1 : 0;
        }
 
-       st = open_istream(sha1, &obj_type, &size, NULL);
+       st = open_istream(oid, &obj_type, &size, NULL);
        if (!st)
                return -1;
 
@@ -823,7 +852,7 @@ int check_sha1_signature(const unsigned char *sha1, void *map,
        }
        the_hash_algo->final_fn(real_oid.hash, &c);
        close_istream(st);
-       return hashcmp(sha1, real_oid.hash) ? -1 : 0;
+       return oidcmp(oid, &real_oid) ? -1 : 0;
 }
 
 int git_open_cloexec(const char *name, int flags)
@@ -861,22 +890,22 @@ int git_open_cloexec(const char *name, int flags)
  * Note that it may point to static storage and is only valid until another
  * call to sha1_file_name(), etc.
  */
-static int stat_sha1_file(const unsigned char *sha1, struct stat *st,
-                         const char **path)
+static int stat_sha1_file(struct repository *r, const unsigned char *sha1,
+                         struct stat *st, const char **path)
 {
        struct alternate_object_database *alt;
        static struct strbuf buf = STRBUF_INIT;
 
        strbuf_reset(&buf);
-       sha1_file_name(&buf, sha1);
+       sha1_file_name(r, &buf, sha1);
        *path = buf.buf;
 
        if (!lstat(*path, st))
                return 0;
 
-       prepare_alt_odb();
+       prepare_alt_odb(r);
        errno = ENOENT;
-       for (alt = alt_odb_list; alt; alt = alt->next) {
+       for (alt = r->objects->alt_odb_list; alt; alt = alt->next) {
                *path = alt_sha1_path(alt, sha1);
                if (!lstat(*path, st))
                        return 0;
@@ -889,7 +918,8 @@ static int stat_sha1_file(const unsigned char *sha1, struct stat *st,
  * Like stat_sha1_file(), but actually open the object and return the
  * descriptor. See the caveats on the "path" parameter above.
  */
-static int open_sha1_file(const unsigned char *sha1, const char **path)
+static int open_sha1_file(struct repository *r,
+                         const unsigned char *sha1, const char **path)
 {
        int fd;
        struct alternate_object_database *alt;
@@ -897,7 +927,7 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
        static struct strbuf buf = STRBUF_INIT;
 
        strbuf_reset(&buf);
-       sha1_file_name(&buf, sha1);
+       sha1_file_name(r, &buf, sha1);
        *path = buf.buf;
 
        fd = git_open(*path);
@@ -905,8 +935,8 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
                return fd;
        most_interesting_errno = errno;
 
-       prepare_alt_odb();
-       for (alt = alt_odb_list; alt; alt = alt->next) {
+       prepare_alt_odb(r);
+       for (alt = r->objects->alt_odb_list; alt; alt = alt->next) {
                *path = alt_sha1_path(alt, sha1);
                fd = git_open(*path);
                if (fd >= 0)
@@ -922,9 +952,8 @@ static int open_sha1_file(const unsigned char *sha1, const char **path)
  * Map the loose object at "path" if it is not NULL, or the path found by
  * searching for a loose object named "sha1".
  */
-static void *map_sha1_file_1(const char *path,
-                            const unsigned char *sha1,
-                            unsigned long *size)
+static void *map_sha1_file_1(struct repository *r, const char *path,
+                            const unsigned char *sha1, unsigned long *size)
 {
        void *map;
        int fd;
@@ -932,7 +961,7 @@ static void *map_sha1_file_1(const char *path,
        if (path)
                fd = git_open(path);
        else
-               fd = open_sha1_file(sha1, &path);
+               fd = open_sha1_file(r, sha1, &path);
        map = NULL;
        if (fd >= 0) {
                struct stat st;
@@ -951,9 +980,10 @@ static void *map_sha1_file_1(const char *path,
        return map;
 }
 
-void *map_sha1_file(const unsigned char *sha1, unsigned long *size)
+void *map_sha1_file(struct repository *r,
+                   const unsigned char *sha1, unsigned long *size)
 {
-       return map_sha1_file_1(NULL, sha1, size);
+       return map_sha1_file_1(r, NULL, sha1, size);
 }
 
 static int unpack_sha1_short_header(git_zstream *stream,
@@ -1142,15 +1172,15 @@ int parse_sha1_header(const char *hdr, unsigned long *sizep)
        return parse_sha1_header_extended(hdr, &oi, 0);
 }
 
-static int sha1_loose_object_info(const unsigned char *sha1,
-                                 struct object_info *oi,
-                                 int flags)
+static int sha1_loose_object_info(struct repository *r,
+                                 const unsigned char *sha1,
+                                 struct object_info *oi, int flags)
 {
        int status = 0;
        unsigned long mapsize;
        void *map;
        git_zstream stream;
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
        struct strbuf hdrbuf = STRBUF_INIT;
        unsigned long size_scratch;
 
@@ -1168,14 +1198,14 @@ static int sha1_loose_object_info(const unsigned char *sha1,
        if (!oi->typep && !oi->type_name && !oi->sizep && !oi->contentp) {
                const char *path;
                struct stat st;
-               if (stat_sha1_file(sha1, &st, &path) < 0)
+               if (stat_sha1_file(r, sha1, &st, &path) < 0)
                        return -1;
                if (oi->disk_sizep)
                        *oi->disk_sizep = st.st_size;
                return 0;
        }
 
-       map = map_sha1_file(sha1, &mapsize);
+       map = map_sha1_file(r, sha1, &mapsize);
        if (!map)
                return -1;
 
@@ -1222,17 +1252,19 @@ static int sha1_loose_object_info(const unsigned char *sha1,
 
 int fetch_if_missing = 1;
 
-int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi, unsigned flags)
+int oid_object_info_extended(struct repository *r, const struct object_id *oid,
+                            struct object_info *oi, unsigned flags)
 {
        static struct object_info blank_oi = OBJECT_INFO_INIT;
        struct pack_entry e;
        int rtype;
-       const unsigned char *real = (flags & OBJECT_INFO_LOOKUP_REPLACE) ?
-                                   lookup_replace_object(sha1) :
-                                   sha1;
+       const struct object_id *real = oid;
        int already_retried = 0;
 
-       if (is_null_sha1(real))
+       if (flags & OBJECT_INFO_LOOKUP_REPLACE)
+               real = lookup_replace_object(r, oid);
+
+       if (is_null_oid(real))
                return -1;
 
        if (!oi)
@@ -1259,28 +1291,33 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
        }
 
        while (1) {
-               if (find_pack_entry(real, &e))
+               if (find_pack_entry(r, real, &e))
                        break;
 
+               if (flags & OBJECT_INFO_IGNORE_LOOSE)
+                       return -1;
+
                /* Most likely it's a loose object. */
-               if (!sha1_loose_object_info(real, oi, flags))
+               if (!sha1_loose_object_info(r, real->hash, oi, flags))
                        return 0;
 
                /* Not a loose object; someone else may have just packed it. */
                if (!(flags & OBJECT_INFO_QUICK)) {
-                       reprepare_packed_git();
-                       if (find_pack_entry(real, &e))
+                       reprepare_packed_git(r);
+                       if (find_pack_entry(r, real, &e))
                                break;
                }
 
                /* Check if it is a missing object */
                if (fetch_if_missing && repository_format_partial_clone &&
-                   !already_retried) {
+                   !already_retried && r == the_repository) {
                        /*
-                        * TODO Investigate haveing fetch_object() return
+                        * TODO Investigate having fetch_object() return
                         * TODO error/success and stopping the music here.
+                        * TODO Pass a repository struct through fetch_object,
+                        * such that arbitrary repositories work.
                         */
-                       fetch_object(repository_format_partial_clone, real);
+                       fetch_object(repository_format_partial_clone, real->hash);
                        already_retried = 1;
                        continue;
                }
@@ -1294,10 +1331,10 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
                 * information below, so return early.
                 */
                return 0;
-       rtype = packed_object_info(e.p, e.offset, oi);
+       rtype = packed_object_info(r, e.p, e.offset, oi);
        if (rtype < 0) {
-               mark_bad_packed_object(e.p, real);
-               return sha1_object_info_extended(real, oi, 0);
+               mark_bad_packed_object(e.p, real->hash);
+               return oid_object_info_extended(r, real, oi, 0);
        } else if (oi->whence == OI_PACKED) {
                oi->u.packed.offset = e.offset;
                oi->u.packed.pack = e.p;
@@ -1309,14 +1346,16 @@ int sha1_object_info_extended(const unsigned char *sha1, struct object_info *oi,
 }
 
 /* returns enum object_type or negative */
-int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
+int oid_object_info(struct repository *r,
+                   const struct object_id *oid,
+                   unsigned long *sizep)
 {
        enum object_type type;
        struct object_info oi = OBJECT_INFO_INIT;
 
        oi.typep = &type;
        oi.sizep = sizep;
-       if (sha1_object_info_extended(sha1, &oi,
+       if (oid_object_info_extended(r, oid, &oi,
                                      OBJECT_INFO_LOOKUP_REPLACE) < 0)
                return -1;
        return type;
@@ -1325,13 +1364,16 @@ int sha1_object_info(const unsigned char *sha1, unsigned long *sizep)
 static void *read_object(const unsigned char *sha1, enum object_type *type,
                         unsigned long *size)
 {
+       struct object_id oid;
        struct object_info oi = OBJECT_INFO_INIT;
        void *content;
        oi.typep = type;
        oi.sizep = size;
        oi.contentp = &content;
 
-       if (sha1_object_info_extended(sha1, &oi, 0) < 0)
+       hashcpy(oid.hash, sha1);
+
+       if (oid_object_info_extended(the_repository, &oid, &oi, 0) < 0)
                return NULL;
        return content;
 }
@@ -1342,7 +1384,7 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
        struct cached_object *co;
 
        hash_object_file(buf, len, type_name(type), oid);
-       if (has_sha1_file(oid->hash) || find_cached_object(oid->hash))
+       if (has_sha1_file(oid->hash) || find_cached_object(oid))
                return 0;
        ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc);
        co = &cached_objects[cached_object_nr++];
@@ -1350,7 +1392,7 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
        co->type = type;
        co->buf = xmalloc(len);
        memcpy(co->buf, buf, len);
-       hashcpy(co->sha1, oid->hash);
+       oidcpy(&co->oid, oid);
        return 0;
 }
 
@@ -1359,65 +1401,65 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
  * deal with them should arrange to call read_object() and give error
  * messages themselves.
  */
-void *read_sha1_file_extended(const unsigned char *sha1,
-                             enum object_type *type,
-                             unsigned long *size,
-                             int lookup_replace)
+void *read_object_file_extended(const struct object_id *oid,
+                               enum object_type *type,
+                               unsigned long *size,
+                               int lookup_replace)
 {
        void *data;
        const struct packed_git *p;
        const char *path;
        struct stat st;
-       const unsigned char *repl = lookup_replace ? lookup_replace_object(sha1)
-                                                  : sha1;
+       const struct object_id *repl = lookup_replace ?
+               lookup_replace_object(the_repository, oid) : oid;
 
        errno = 0;
-       data = read_object(repl, type, size);
+       data = read_object(repl->hash, type, size);
        if (data)
                return data;
 
        if (errno && errno != ENOENT)
-               die_errno("failed to read object %s", sha1_to_hex(sha1));
+               die_errno("failed to read object %s", oid_to_hex(oid));
 
        /* die if we replaced an object with one that does not exist */
-       if (repl != sha1)
+       if (repl != oid)
                die("replacement %s not found for %s",
-                   sha1_to_hex(repl), sha1_to_hex(sha1));
+                   oid_to_hex(repl), oid_to_hex(oid));
 
-       if (!stat_sha1_file(repl, &st, &path))
+       if (!stat_sha1_file(the_repository, repl->hash, &st, &path))
                die("loose object %s (stored in %s) is corrupt",
-                   sha1_to_hex(repl), path);
+                   oid_to_hex(repl), path);
 
-       if ((p = has_packed_and_bad(repl)) != NULL)
+       if ((p = has_packed_and_bad(repl->hash)) != NULL)
                die("packed object %s (stored in %s) is corrupt",
-                   sha1_to_hex(repl), p->pack_name);
+                   oid_to_hex(repl), p->pack_name);
 
        return NULL;
 }
 
-void *read_object_with_reference(const unsigned char *sha1,
+void *read_object_with_reference(const struct object_id *oid,
                                 const char *required_type_name,
                                 unsigned long *size,
-                                unsigned char *actual_sha1_return)
+                                struct object_id *actual_oid_return)
 {
        enum object_type type, required_type;
        void *buffer;
        unsigned long isize;
-       unsigned char actual_sha1[20];
+       struct object_id actual_oid;
 
        required_type = type_from_string(required_type_name);
-       hashcpy(actual_sha1, sha1);
+       oidcpy(&actual_oid, oid);
        while (1) {
                int ref_length = -1;
                const char *ref_type = NULL;
 
-               buffer = read_sha1_file(actual_sha1, &type, &isize);
+               buffer = read_object_file(&actual_oid, &type, &isize);
                if (!buffer)
                        return NULL;
                if (type == required_type) {
                        *size = isize;
-                       if (actual_sha1_return)
-                               hashcpy(actual_sha1_return, actual_sha1);
+                       if (actual_oid_return)
+                               oidcpy(actual_oid_return, &actual_oid);
                        return buffer;
                }
                /* Handle references */
@@ -1431,15 +1473,15 @@ void *read_object_with_reference(const unsigned char *sha1,
                }
                ref_length = strlen(ref_type);
 
-               if (ref_length + 40 > isize ||
+               if (ref_length + GIT_SHA1_HEXSZ > isize ||
                    memcmp(buffer, ref_type, ref_length) ||
-                   get_sha1_hex((char *) buffer + ref_length, actual_sha1)) {
+                   get_oid_hex((char *) buffer + ref_length, &actual_oid)) {
                        free(buffer);
                        return NULL;
                }
                free(buffer);
                /* Now we have the ID of the referred-to object in
-                * actual_sha1.  Check again. */
+                * actual_oid.  Check again. */
        }
 }
 
@@ -1512,7 +1554,7 @@ static int write_buffer(int fd, const void *buf, size_t len)
 int hash_object_file(const void *buf, unsigned long len, const char *type,
                     struct object_id *oid)
 {
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
        int hdrlen = sizeof(hdr);
        write_object_file_prepare(buf, len, type, oid, hdr, &hdrlen);
        return 0;
@@ -1585,7 +1627,7 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
        static struct strbuf filename = STRBUF_INIT;
 
        strbuf_reset(&filename);
-       sha1_file_name(&filename, oid->hash);
+       sha1_file_name(the_repository, &filename, oid->hash);
 
        fd = create_tmpfile(&tmp_file, filename.buf);
        if (fd < 0) {
@@ -1646,15 +1688,15 @@ static int write_loose_object(const struct object_id *oid, char *hdr,
        return finalize_object_file(tmp_file.buf, filename.buf);
 }
 
-static int freshen_loose_object(const unsigned char *sha1)
+static int freshen_loose_object(const struct object_id *oid)
 {
-       return check_and_freshen(sha1, 1);
+       return check_and_freshen(oid, 1);
 }
 
-static int freshen_packed_object(const unsigned char *sha1)
+static int freshen_packed_object(const struct object_id *oid)
 {
        struct pack_entry e;
-       if (!find_pack_entry(sha1, &e))
+       if (!find_pack_entry(the_repository, oid, &e))
                return 0;
        if (e.p->freshened)
                return 1;
@@ -1667,14 +1709,14 @@ static int freshen_packed_object(const unsigned char *sha1)
 int write_object_file(const void *buf, unsigned long len, const char *type,
                      struct object_id *oid)
 {
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
        int hdrlen = sizeof(hdr);
 
        /* 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(buf, len, type, oid, hdr, &hdrlen);
-       if (freshen_packed_object(oid->hash) || freshen_loose_object(oid->hash))
+       if (freshen_packed_object(oid) || freshen_loose_object(oid))
                return 0;
        return write_loose_object(oid, hdr, hdrlen, buf, len, 0);
 }
@@ -1687,13 +1729,13 @@ int hash_object_file_literally(const void *buf, unsigned long len,
        int hdrlen, status = 0;
 
        /* type string, SP, %lu of the length plus NUL must fit this */
-       hdrlen = strlen(type) + 32;
+       hdrlen = strlen(type) + MAX_HEADER_LEN;
        header = xmalloc(hdrlen);
        write_object_file_prepare(buf, len, type, oid, header, &hdrlen);
 
        if (!(flags & HASH_WRITE_OBJECT))
                goto cleanup;
-       if (freshen_packed_object(oid->hash) || freshen_loose_object(oid->hash))
+       if (freshen_packed_object(oid) || freshen_loose_object(oid))
                goto cleanup;
        status = write_loose_object(oid, header, hdrlen, buf, len, 0);
 
@@ -1707,11 +1749,11 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
        void *buf;
        unsigned long len;
        enum object_type type;
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
        int hdrlen;
        int ret;
 
-       if (has_loose_object(oid->hash))
+       if (has_loose_object(oid))
                return 0;
        buf = read_object(oid->hash, &type, &len);
        if (!buf)
@@ -1725,10 +1767,12 @@ int force_object_loose(const struct object_id *oid, time_t mtime)
 
 int has_sha1_file_with_flags(const unsigned char *sha1, int flags)
 {
+       struct object_id oid;
        if (!startup_info->have_repository)
                return 0;
-       return sha1_object_info_extended(sha1, NULL,
-                                        flags | OBJECT_INFO_SKIP_CACHED) >= 0;
+       hashcpy(oid.hash, sha1);
+       return oid_object_info_extended(the_repository, &oid, NULL,
+                                       flags | OBJECT_INFO_SKIP_CACHED) >= 0;
 }
 
 int has_object_file(const struct object_id *oid)
@@ -1894,7 +1938,7 @@ static int index_stream(struct object_id *oid, int fd, size_t size,
                        enum object_type type, const char *path,
                        unsigned flags)
 {
-       return index_bulk_checkin(oid->hash, fd, size, type, path, flags);
+       return index_bulk_checkin(oid, fd, size, type, path, flags);
 }
 
 int index_fd(struct object_id *oid, int fd, struct stat *st,
@@ -1968,13 +2012,13 @@ int read_pack_header(int fd, struct pack_header *header)
        return 0;
 }
 
-void assert_sha1_type(const unsigned char *sha1, enum object_type expect)
+void assert_oid_type(const struct object_id *oid, enum object_type expect)
 {
-       enum object_type type = sha1_object_info(sha1, NULL);
+       enum object_type type = oid_object_info(the_repository, oid, NULL);
        if (type < 0)
-               die("%s is not a valid object", sha1_to_hex(sha1));
+               die("%s is not a valid object", oid_to_hex(oid));
        if (type != expect)
-               die("%s is not a valid '%s' object", sha1_to_hex(sha1),
+               die("%s is not a valid '%s' object", oid_to_hex(oid),
                    type_name(expect));
 }
 
@@ -2178,7 +2222,7 @@ static int check_stream_sha1(git_zstream *stream,
 }
 
 int read_loose_object(const char *path,
-                     const unsigned char *expected_sha1,
+                     const struct object_id *expected_oid,
                      enum object_type *type,
                      unsigned long *size,
                      void **contents)
@@ -2187,11 +2231,11 @@ int read_loose_object(const char *path,
        void *map = NULL;
        unsigned long mapsize;
        git_zstream stream;
-       char hdr[32];
+       char hdr[MAX_HEADER_LEN];
 
        *contents = NULL;
 
-       map = map_sha1_file_1(path, NULL, &mapsize);
+       map = map_sha1_file_1(the_repository, path, NULL, &mapsize);
        if (!map) {
                error_errno("unable to mmap %s", path);
                goto out;
@@ -2210,19 +2254,19 @@ int read_loose_object(const char *path,
        }
 
        if (*type == OBJ_BLOB && *size > big_file_threshold) {
-               if (check_stream_sha1(&stream, hdr, *size, path, expected_sha1) < 0)
+               if (check_stream_sha1(&stream, hdr, *size, path, expected_oid->hash) < 0)
                        goto out;
        } else {
-               *contents = unpack_sha1_rest(&stream, hdr, *size, expected_sha1);
+               *contents = unpack_sha1_rest(&stream, hdr, *size, expected_oid->hash);
                if (!*contents) {
                        error("unable to unpack contents of %s", path);
                        git_inflate_end(&stream);
                        goto out;
                }
-               if (check_sha1_signature(expected_sha1, *contents,
+               if (check_object_signature(expected_oid, *contents,
                                         *size, type_name(*type))) {
                        error("sha1 mismatch for %s (expected %s)", path,
-                             sha1_to_hex(expected_sha1));
+                             oid_to_hex(expected_oid));
                        free(*contents);
                        goto out;
                }
index 8d0b1db3e27c99b80faa2867565de237581802f4..796ab68da83c3a36ec87fa45bfa18f5d0508a947 100644 (file)
@@ -81,7 +81,7 @@ int sha1_pos(const unsigned char *sha1, void *table, size_t nr,
                                mi = (nr - 1) * (miv - lov) / (hiv - lov);
                                if (lo <= mi && mi < hi)
                                        break;
-                               die("BUG: assertion failed in binary search");
+                               BUG("assertion failed in binary search");
                        }
                }
        }
similarity index 94%
rename from sha1_name.c
rename to sha1-name.c
index 735c1c0b8ec032b3aac8b6a8976dcdb09ba5e91d..60d9ef3c7e7108c859647656972c171cce4e7d7f 100644 (file)
@@ -10,6 +10,8 @@
 #include "dir.h"
 #include "sha1-array.h"
 #include "packfile.h"
+#include "object-store.h"
+#include "repository.h"
 
 static int get_oid_oneline(const char *, struct object_id *, struct commit_list *);
 
@@ -104,7 +106,7 @@ static void find_short_object_filename(struct disambiguate_state *ds)
                 */
                fakeent = alloc_alt_odb(get_object_directory());
        }
-       fakeent->next = alt_odb_list;
+       fakeent->next = the_repository->objects->alt_odb_list;
 
        for (alt = fakeent; alt && !ds->ambiguous; alt = alt->next) {
                int pos;
@@ -150,31 +152,14 @@ static int match_sha(unsigned len, const unsigned char *a, const unsigned char *
 static void unique_in_pack(struct packed_git *p,
                           struct disambiguate_state *ds)
 {
-       uint32_t num, last, i, first = 0;
+       uint32_t num, i, first = 0;
        const struct object_id *current = NULL;
 
        if (open_pack_index(p) || !p->num_objects)
                return;
 
        num = p->num_objects;
-       last = num;
-       while (first < last) {
-               uint32_t mid = first + (last - first) / 2;
-               const unsigned char *current;
-               int cmp;
-
-               current = nth_packed_object_sha1(p, mid);
-               cmp = hashcmp(ds->bin_pfx.hash, current);
-               if (!cmp) {
-                       first = mid;
-                       break;
-               }
-               if (cmp > 0) {
-                       first = mid+1;
-                       continue;
-               }
-               last = mid;
-       }
+       bsearch_pack(&ds->bin_pfx, p, &first);
 
        /*
         * At this point, "first" is the location of the lowest object
@@ -194,8 +179,8 @@ static void find_short_packed_object(struct disambiguate_state *ds)
 {
        struct packed_git *p;
 
-       prepare_packed_git();
-       for (p = packed_git; p && !ds->ambiguous; p = p->next)
+       for (p = get_packed_git(the_repository); p && !ds->ambiguous;
+            p = p->next)
                unique_in_pack(p, ds);
 }
 
@@ -238,7 +223,7 @@ static int finish_object_disambiguation(struct disambiguate_state *ds,
 
 static int disambiguate_commit_only(const struct object_id *oid, void *cb_data_unused)
 {
-       int kind = sha1_object_info(oid->hash, NULL);
+       int kind = oid_object_info(the_repository, oid, NULL);
        return kind == OBJ_COMMIT;
 }
 
@@ -247,7 +232,7 @@ static int disambiguate_committish_only(const struct object_id *oid, void *cb_da
        struct object *obj;
        int kind;
 
-       kind = sha1_object_info(oid->hash, NULL);
+       kind = oid_object_info(the_repository, oid, NULL);
        if (kind == OBJ_COMMIT)
                return 1;
        if (kind != OBJ_TAG)
@@ -262,7 +247,7 @@ static int disambiguate_committish_only(const struct object_id *oid, void *cb_da
 
 static int disambiguate_tree_only(const struct object_id *oid, void *cb_data_unused)
 {
-       int kind = sha1_object_info(oid->hash, NULL);
+       int kind = oid_object_info(the_repository, oid, NULL);
        return kind == OBJ_TREE;
 }
 
@@ -271,7 +256,7 @@ static int disambiguate_treeish_only(const struct object_id *oid, void *cb_data_
        struct object *obj;
        int kind;
 
-       kind = sha1_object_info(oid->hash, NULL);
+       kind = oid_object_info(the_repository, oid, NULL);
        if (kind == OBJ_TREE || kind == OBJ_COMMIT)
                return 1;
        if (kind != OBJ_TAG)
@@ -286,7 +271,7 @@ static int disambiguate_treeish_only(const struct object_id *oid, void *cb_data_
 
 static int disambiguate_blob_only(const struct object_id *oid, void *cb_data_unused)
 {
-       int kind = sha1_object_info(oid->hash, NULL);
+       int kind = oid_object_info(the_repository, oid, NULL);
        return kind == OBJ_BLOB;
 }
 
@@ -351,7 +336,7 @@ static int init_object_disambiguation(const char *name, int len,
 
        ds->len = len;
        ds->hex_pfx[len] = '\0';
-       prepare_alt_odb();
+       prepare_alt_odb(the_repository);
        return 0;
 }
 
@@ -361,11 +346,10 @@ static int show_ambiguous_object(const struct object_id *oid, void *data)
        struct strbuf desc = STRBUF_INIT;
        int type;
 
-
        if (ds->fn && !ds->fn(oid, ds->cb_data))
                return 0;
 
-       type = sha1_object_info(oid->hash, NULL);
+       type = oid_object_info(the_repository, oid, NULL);
        if (type == OBJ_COMMIT) {
                struct commit *commit = lookup_commit(oid);
                if (commit) {
@@ -380,7 +364,7 @@ static int show_ambiguous_object(const struct object_id *oid, void *data)
        }
 
        advise("  %s %s%s",
-              find_unique_abbrev(oid->hash, DEFAULT_ABBREV),
+              find_unique_abbrev(oid, DEFAULT_ABBREV),
               type_name(type) ? type_name(type) : "unknown type",
               desc.buf);
 
@@ -388,6 +372,40 @@ static int show_ambiguous_object(const struct object_id *oid, void *data)
        return 0;
 }
 
+static int collect_ambiguous(const struct object_id *oid, void *data)
+{
+       oid_array_append(data, oid);
+       return 0;
+}
+
+static int sort_ambiguous(const void *a, const void *b)
+{
+       int a_type = oid_object_info(the_repository, a, NULL);
+       int b_type = oid_object_info(the_repository, b, NULL);
+       int a_type_sort;
+       int b_type_sort;
+
+       /*
+        * 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);
+
+       /*
+        * Between object types show tags, then commits, and finally
+        * trees and blobs.
+        *
+        * The object_type enum is commit, tree, blob, tag, but we
+        * want tag, commit, tree blob. Cleverly (perhaps too
+        * cleverly) do that with modulus, since the enum assigns 1 to
+        * commit, so tag becomes 0.
+        */
+       a_type_sort = a_type % 4;
+       b_type_sort = b_type % 4;
+       return a_type_sort > b_type_sort ? 1 : -1;
+}
+
 static int get_short_oid(const char *name, int len, struct object_id *oid,
                          unsigned flags)
 {
@@ -399,7 +417,7 @@ static int get_short_oid(const char *name, int len, struct object_id *oid,
                return -1;
 
        if (HAS_MULTI_BITS(flags & GET_OID_DISAMBIGUATORS))
-               die("BUG: multiple get_short_oid disambiguator flags");
+               BUG("multiple get_short_oid disambiguator flags");
 
        if (flags & GET_OID_COMMIT)
                ds.fn = disambiguate_commit_only;
@@ -419,6 +437,8 @@ static int get_short_oid(const char *name, int len, struct object_id *oid,
        status = finish_object_disambiguation(&ds, oid);
 
        if (!quietly && (status == SHORT_NAME_AMBIGUOUS)) {
+               struct oid_array collect = OID_ARRAY_INIT;
+
                error(_("short SHA1 %s is ambiguous"), ds.hex_pfx);
 
                /*
@@ -431,18 +451,17 @@ static int get_short_oid(const char *name, int len, struct object_id *oid,
                        ds.fn = NULL;
 
                advise(_("The candidates are:"));
-               for_each_abbrev(ds.hex_pfx, show_ambiguous_object, &ds);
+               for_each_abbrev(ds.hex_pfx, collect_ambiguous, &collect);
+               QSORT(collect.oid, collect.nr, sort_ambiguous);
+
+               if (oid_array_for_each(&collect, show_ambiguous_object, &ds))
+                       BUG("show_ambiguous_object shouldn't return non-zero");
+               oid_array_clear(&collect);
        }
 
        return status;
 }
 
-static int collect_ambiguous(const struct object_id *oid, void *data)
-{
-       oid_array_append(data, oid);
-       return 0;
-}
-
 int for_each_abbrev(const char *prefix, each_abbrev_fn fn, void *cb_data)
 {
        struct oid_array collect = OID_ARRAY_INIT;
@@ -480,7 +499,7 @@ struct min_abbrev_data {
        unsigned int init_len;
        unsigned int cur_len;
        char *hex;
-       const unsigned char *hash;
+       const struct object_id *oid;
 };
 
 static inline char get_hex_char_from_oid(const struct object_id *oid,
@@ -512,32 +531,16 @@ static void find_abbrev_len_for_pack(struct packed_git *p,
                                     struct min_abbrev_data *mad)
 {
        int match = 0;
-       uint32_t num, last, first = 0;
+       uint32_t num, first = 0;
        struct object_id oid;
+       const struct object_id *mad_oid;
 
        if (open_pack_index(p) || !p->num_objects)
                return;
 
        num = p->num_objects;
-       last = num;
-       while (first < last) {
-               uint32_t mid = first + (last - first) / 2;
-               const unsigned char *current;
-               int cmp;
-
-               current = nth_packed_object_sha1(p, mid);
-               cmp = hashcmp(mad->hash, current);
-               if (!cmp) {
-                       match = 1;
-                       first = mid;
-                       break;
-               }
-               if (cmp > 0) {
-                       first = mid + 1;
-                       continue;
-               }
-               last = mid;
-       }
+       mad_oid = mad->oid;
+       match = bsearch_pack(mad_oid, p, &first);
 
        /*
         * first is now the position in the packfile where we would insert
@@ -564,12 +567,11 @@ static void find_abbrev_len_packed(struct min_abbrev_data *mad)
 {
        struct packed_git *p;
 
-       prepare_packed_git();
-       for (p = packed_git; p; p = p->next)
+       for (p = get_packed_git(the_repository); p; p = p->next)
                find_abbrev_len_for_pack(p, mad);
 }
 
-int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len)
+int find_unique_abbrev_r(char *hex, const struct object_id *oid, int len)
 {
        struct disambiguate_state ds;
        struct min_abbrev_data mad;
@@ -596,14 +598,14 @@ int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len)
                        len = FALLBACK_DEFAULT_ABBREV;
        }
 
-       sha1_to_hex_r(hex, sha1);
+       oid_to_hex_r(hex, oid);
        if (len == GIT_SHA1_HEXSZ || !len)
                return GIT_SHA1_HEXSZ;
 
        mad.init_len = len;
        mad.cur_len = len;
        mad.hex = hex;
-       mad.hash = sha1;
+       mad.oid = oid;
 
        find_abbrev_len_packed(&mad);
 
@@ -621,13 +623,13 @@ int find_unique_abbrev_r(char *hex, const unsigned char *sha1, int len)
        return mad.cur_len;
 }
 
-const char *find_unique_abbrev(const unsigned char *sha1, int len)
+const char *find_unique_abbrev(const struct object_id *oid, int len)
 {
        static int bufno;
        static char hexbuffer[4][GIT_MAX_HEXSZ + 1];
        char *hex = hexbuffer[bufno];
        bufno = (bufno + 1) % ARRAY_SIZE(hexbuffer);
-       find_unique_abbrev_r(hex, sha1, len);
+       find_unique_abbrev_r(hex, oid, len);
        return hex;
 }
 
@@ -896,7 +898,7 @@ struct object *peel_to_type(const char *name, int namelen,
                if (o->type == OBJ_TAG)
                        o = ((struct tag*) o)->tagged;
                else if (o->type == OBJ_COMMIT)
-                       o = &(((struct commit *) o)->tree->object);
+                       o = &(get_commit_tree(((struct commit *)o))->object);
                else {
                        if (name)
                                error("%.*s: expected %s type, but the object "
@@ -1529,8 +1531,7 @@ static void diagnose_invalid_oid_path(const char *prefix,
        if (is_missing_file_error(errno)) {
                char *fullname = xstrfmt("%s%s", prefix, filename);
 
-               if (!get_tree_entry(tree_oid->hash, fullname,
-                                   oid.hash, &mode)) {
+               if (!get_tree_entry(tree_oid, fullname, &oid, &mode)) {
                        die("Path '%s' exists, but not '%s'.\n"
                            "Did you mean '%.*s:%s' aka '%.*s:./%s'?",
                            fullname,
@@ -1718,12 +1719,12 @@ static int get_oid_with_context_1(const char *name,
                        if (new_filename)
                                filename = new_filename;
                        if (flags & GET_OID_FOLLOW_SYMLINKS) {
-                               ret = get_tree_entry_follow_symlinks(tree_oid.hash,
-                                       filename, oid->hash, &oc->symlink_path,
+                               ret = get_tree_entry_follow_symlinks(&tree_oid,
+                                       filename, oid, &oc->symlink_path,
                                        &oc->mode);
                        } else {
-                               ret = get_tree_entry(tree_oid.hash, filename,
-                                                    oid->hash, &oc->mode);
+                               ret = get_tree_entry(&tree_oid, filename, oid,
+                                                    &oc->mode);
                                if (ret && only_to_die) {
                                        diagnose_invalid_oid_path(prefix,
                                                                   filename,
@@ -1731,7 +1732,6 @@ static int get_oid_with_context_1(const char *name,
                                                                   name, len);
                                }
                        }
-                       hashcpy(oc->tree, tree_oid.hash);
                        if (flags & GET_OID_RECORD_PATH)
                                oc->path = xstrdup(filename);
 
@@ -1762,6 +1762,6 @@ void maybe_die_on_misspelt_object_name(const char *name, const char *prefix)
 int get_oid_with_context(const char *str, unsigned flags, struct object_id *oid, struct object_context *oc)
 {
        if (flags & GET_OID_FOLLOW_SYMLINKS && flags & GET_OID_ONLY_TO_DIE)
-               die("BUG: incompatible flags for get_sha1_with_context");
+               BUG("incompatible flags for get_sha1_with_context");
        return get_oid_with_context_1(str, flags, NULL, oid, oc);
 }
index df4d44ea7a34a6d6bef119d1494f1c055614cbb1..9ff83cabcd3be2614f7ed770884ac237294b05e4 100644 (file)
--- a/shallow.c
+++ b/shallow.c
@@ -20,7 +20,7 @@ static char *alternate_shallow_file;
 void set_alternate_shallow_file(const char *path, int override)
 {
        if (is_shallow != -1)
-               die("BUG: is_repository_shallow must not be called before set_alternate_shallow_file");
+               BUG("is_repository_shallow must not be called before set_alternate_shallow_file");
        if (alternate_shallow_file && !override)
                return;
        free(alternate_shallow_file);
@@ -218,7 +218,7 @@ struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av,
 static void check_shallow_file_for_update(void)
 {
        if (is_shallow == -1)
-               die("BUG: shallow must be initialized by now");
+               BUG("shallow must be initialized by now");
 
        if (!stat_validity_check(&shallow_stat, git_path_shallow()))
                die("shallow file has changed since we read it");
@@ -353,7 +353,7 @@ void advertise_shallow_grafts(int fd)
  */
 void prune_shallow(int show_only)
 {
-       static struct lock_file shallow_lock;
+       struct lock_file shallow_lock = LOCK_INIT;
        struct strbuf sb = STRBUF_INIT;
        int fd;
 
@@ -446,7 +446,7 @@ static uint32_t *paint_alloc(struct paint_info *info)
        void *p;
        if (!info->pool_count || size > info->end - info->free) {
                if (size > POOL_SIZE)
-                       die("BUG: pool size too small for %d in paint_alloc()",
+                       BUG("pool size too small for %d in paint_alloc()",
                            size);
                info->pool_count++;
                REALLOC_ARRAY(info->pools, info->pool_count);
diff --git a/shell.c b/shell.c
index 234b2d4f16fe79e9260c8409bd4d7c964fe27e72..40084a30130ef844899bc1f3321285afdda82607 100644 (file)
--- a/shell.c
+++ b/shell.c
@@ -1,8 +1,9 @@
 #include "cache.h"
 #include "quote.h"
-#include "exec_cmd.h"
+#include "exec-cmd.h"
 #include "strbuf.h"
 #include "run-command.h"
+#include "alias.h"
 
 #define COMMAND_DIR "git-shell-commands"
 #define HELP_COMMAND COMMAND_DIR "/help"
index 6d7f943e4384fa90001fbb73cc5b63e2c0cfa639..325bf0e974ab9bd8c2c5b5483fbb619ac425531b 100644 (file)
@@ -13,7 +13,7 @@
  * the remote died unexpectedly.  A flush() concludes the stream.
  */
 
-#define PREFIX "remote: "
+#define DISPLAY_PREFIX "remote: "
 
 #define ANSI_SUFFIX "\033[K"
 #define DUMB_SUFFIX "        "
@@ -49,7 +49,7 @@ int recv_sideband(const char *me, int in_stream, int out)
                switch (band) {
                case 3:
                        strbuf_addf(&outbuf, "%s%s%s", outbuf.len ? "\n" : "",
-                                   PREFIX, buf + 1);
+                                   DISPLAY_PREFIX, buf + 1);
                        retval = SIDEBAND_REMOTE_ERROR;
                        break;
                case 2:
@@ -67,7 +67,7 @@ int recv_sideband(const char *me, int in_stream, int out)
                                int linelen = brk - b;
 
                                if (!outbuf.len)
-                                       strbuf_addstr(&outbuf, PREFIX);
+                                       strbuf_addstr(&outbuf, DISPLAY_PREFIX);
                                if (linelen > 0) {
                                        strbuf_addf(&outbuf, "%.*s%s%c",
                                                    linelen, b, suffix, *brk);
@@ -81,8 +81,8 @@ int recv_sideband(const char *me, int in_stream, int out)
                        }
 
                        if (*b)
-                               strbuf_addf(&outbuf, "%s%s",
-                                           outbuf.len ? "" : PREFIX, b);
+                               strbuf_addf(&outbuf, "%s%s", outbuf.len ?
+                                           "" : DISPLAY_PREFIX, b);
                        break;
                case 1:
                        write_or_die(out, buf + 1, len);
index 2ac43bbd282492e3c35c6ac5f96b14a541ed74c6..022677b6abaf918f51804a8fcbf18776aa3f2be5 100644 (file)
@@ -13,7 +13,7 @@ static struct sigchain_signal signals[SIGCHAIN_MAX_SIGNALS];
 static void check_signum(int sig)
 {
        if (sig < 1 || sig >= SIGCHAIN_MAX_SIGNALS)
-               die("BUG: signal out of range: %d", sig);
+               BUG("signal out of range: %d", sig);
 }
 
 int sigchain_push(int sig, sigchain_fun f)
index 3eb8ff1b43db284bddac643c270e2148114c4bbf..660c75f31fb970af06af3aad48b4ecc57e8cc136 100644 (file)
@@ -18,12 +18,12 @@ int read_link_extension(struct index_state *istate,
        struct split_index *si;
        int ret;
 
-       if (sz < 20)
+       if (sz < the_hash_algo->rawsz)
                return error("corrupt link extension (too short)");
        si = init_split_index(istate);
-       hashcpy(si->base_sha1, data);
-       data += 20;
-       sz -= 20;
+       hashcpy(si->base_oid.hash, data);
+       data += the_hash_algo->rawsz;
+       sz -= the_hash_algo->rawsz;
        if (!sz)
                return 0;
        si->delete_bitmap = ewah_new();
@@ -45,7 +45,7 @@ int write_link_extension(struct strbuf *sb,
                         struct index_state *istate)
 {
        struct split_index *si = istate->split_index;
-       strbuf_add(sb, si->base_sha1, 20);
+       strbuf_add(sb, si->base_oid.hash, the_hash_algo->rawsz);
        if (!si->delete_bitmap && !si->replace_bitmap)
                return 0;
        ewah_serialize_strbuf(si->delete_bitmap, sb);
index 43d66826eb712b9a9b6872458527266bd9818146..7a435ca2c970111b40ac9edba65726e79bd7941d 100644 (file)
@@ -1,12 +1,14 @@
 #ifndef SPLIT_INDEX_H
 #define SPLIT_INDEX_H
 
+#include "cache.h"
+
 struct index_state;
 struct strbuf;
 struct ewah_bitmap;
 
 struct split_index {
-       unsigned char base_sha1[20];
+       struct object_id base_oid;
        struct index_state *base;
        struct ewah_bitmap *delete_bitmap;
        struct ewah_bitmap *replace_bitmap;
index 0759590b3e56de0fab6ff34f25206fb4cdeca4c5..b0716ac585285a971c04952254c34a00aab9f0ef 100644 (file)
--- a/strbuf.c
+++ b/strbuf.c
@@ -1,5 +1,6 @@
 #include "cache.h"
 #include "refs.h"
+#include "string-list.h"
 #include "utf8.h"
 
 int starts_with(const char *str, const char *prefix)
@@ -11,6 +12,15 @@ int starts_with(const char *str, const char *prefix)
                        return 0;
 }
 
+int istarts_with(const char *str, const char *prefix)
+{
+       for (; ; str++, prefix++)
+               if (!*prefix)
+                       return 1;
+               else if (tolower(*str) != tolower(*prefix))
+                       return 0;
+}
+
 int skip_to_optional_arg_default(const char *str, const char *prefix,
                                 const char **arg, const char *def)
 {
@@ -171,6 +181,21 @@ struct strbuf **strbuf_split_buf(const char *str, size_t slen,
        return ret;
 }
 
+void strbuf_add_separated_string_list(struct strbuf *str,
+                                     const char *sep,
+                                     struct string_list *slist)
+{
+       struct string_list_item *item;
+       int sep_needed = 0;
+
+       for_each_string_list_item(item, slist) {
+               if (sep_needed)
+                       strbuf_addstr(str, sep);
+               strbuf_addstr(str, item->string);
+               sep_needed = 1;
+       }
+}
+
 void strbuf_list_free(struct strbuf **sbs)
 {
        struct strbuf **s = sbs;
@@ -309,12 +334,12 @@ void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap)
        len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, cp);
        va_end(cp);
        if (len < 0)
-               die("BUG: your vsnprintf is broken (returned %d)", len);
+               BUG("your vsnprintf is broken (returned %d)", len);
        if (len > strbuf_avail(sb)) {
                strbuf_grow(sb, len);
                len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
                if (len > strbuf_avail(sb))
-                       die("BUG: your vsnprintf is broken (insatiable)");
+                       BUG("your vsnprintf is broken (insatiable)");
        }
        strbuf_setlen(sb, sb->len + len);
 }
@@ -793,7 +818,18 @@ char *xstrdup_tolower(const char *string)
        result = xmallocz(len);
        for (i = 0; i < len; i++)
                result[i] = tolower(string[i]);
-       result[i] = '\0';
+       return result;
+}
+
+char *xstrdup_toupper(const char *string)
+{
+       char *result;
+       size_t len, i;
+
+       len = strlen(string);
+       result = xmallocz(len);
+       for (i = 0; i < len; i++)
+               result[i] = toupper(string[i]);
        return result;
 }
 
@@ -881,12 +917,12 @@ void strbuf_addftime(struct strbuf *sb, const char *fmt, const struct tm *tm,
        strbuf_setlen(sb, sb->len + len);
 }
 
-void strbuf_add_unique_abbrev(struct strbuf *sb, const unsigned char *sha1,
+void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid,
                              int abbrev_len)
 {
        int r;
        strbuf_grow(sb, GIT_SHA1_HEXSZ + 1);
-       r = find_unique_abbrev_r(sb->buf + sb->len, sha1, abbrev_len);
+       r = find_unique_abbrev_r(sb->buf + sb->len, oid, abbrev_len);
        strbuf_setlen(sb, sb->len + r);
 }
 
index e6cae5f4398c8eb4c4a53c7db226a920e32bfde9..60a35aef165ca1a1bdc20b005751ea70e3c49ee0 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -1,6 +1,8 @@
 #ifndef STRBUF_H
 #define STRBUF_H
 
+struct string_list;
+
 /**
  * strbuf's are meant to be used with all the usual C string and memory
  * APIs. Given that the length of the buffer is known, it's often better to
@@ -70,6 +72,12 @@ struct strbuf {
 extern char strbuf_slopbuf[];
 #define STRBUF_INIT  { .alloc = 0, .len = 0, .buf = strbuf_slopbuf }
 
+/*
+ * Predeclare this here, since cache.h includes this file before it defines the
+ * struct.
+ */
+struct object_id;
+
 /**
  * Life Cycle Functions
  * --------------------
@@ -531,6 +539,20 @@ static inline struct strbuf **strbuf_split(const struct strbuf *sb,
        return strbuf_split_max(sb, terminator, 0);
 }
 
+/*
+ * Adds all strings of a string list to the strbuf, separated by the given
+ * separator.  For example, if sep is
+ *   ', '
+ * and slist contains
+ *   ['element1', 'element2', ..., 'elementN'],
+ * then write:
+ *   'element1, element2, ..., elementN'
+ * to str.  If only one element, just write "element1" to str.
+ */
+extern void strbuf_add_separated_string_list(struct strbuf *str,
+                                            const char *sep,
+                                            struct string_list *slist);
+
 /**
  * Free a NULL-terminated list of strbufs (for example, the return
  * values of the strbuf_split*() functions).
@@ -542,7 +564,7 @@ extern void strbuf_list_free(struct strbuf **);
  * the strbuf `sb`.
  */
 extern void strbuf_add_unique_abbrev(struct strbuf *sb,
-                                    const unsigned char *sha1,
+                                    const struct object_id *oid,
                                     int abbrev_len);
 
 /**
@@ -610,6 +632,7 @@ __attribute__((format (printf,2,3)))
 extern int fprintf_ln(FILE *fp, const char *fmt, ...);
 
 char *xstrdup_tolower(const char *);
+char *xstrdup_toupper(const char *);
 
 /**
  * Create a newly allocated string using printf format. You can do this easily
index 5892b50bd89c3c66bdb541ca0100f0671834a542..d1e6b2dce6877cb1407ac9d38e65d8b2bae25daa 100644 (file)
@@ -3,6 +3,9 @@
  */
 #include "cache.h"
 #include "streaming.h"
+#include "repository.h"
+#include "object-store.h"
+#include "replace-object.h"
 #include "packfile.h"
 
 enum input_source {
@@ -14,7 +17,7 @@ enum input_source {
 
 typedef int (*open_istream_fn)(struct git_istream *,
                               struct object_info *,
-                              const unsigned char *,
+                              const struct object_id *,
                               enum object_type *);
 typedef int (*close_istream_fn)(struct git_istream *);
 typedef ssize_t (*read_istream_fn)(struct git_istream *, char *, size_t);
@@ -27,7 +30,7 @@ struct stream_vtbl {
 #define open_method_decl(name) \
        int open_istream_ ##name \
        (struct git_istream *st, struct object_info *oi, \
-        const unsigned char *sha1, \
+        const struct object_id *oid, \
         enum object_type *type)
 
 #define close_method_decl(name) \
@@ -105,7 +108,7 @@ ssize_t read_istream(struct git_istream *st, void *buf, size_t sz)
        return st->vtbl->read(st, buf, sz);
 }
 
-static enum input_source istream_source(const unsigned char *sha1,
+static enum input_source istream_source(const struct object_id *oid,
                                        enum object_type *type,
                                        struct object_info *oi)
 {
@@ -114,7 +117,7 @@ static enum input_source istream_source(const unsigned char *sha1,
 
        oi->typep = type;
        oi->sizep = &size;
-       status = sha1_object_info_extended(sha1, oi, 0);
+       status = oid_object_info_extended(the_repository, oid, oi, 0);
        if (status < 0)
                return stream_error;
 
@@ -130,14 +133,14 @@ static enum input_source istream_source(const unsigned char *sha1,
        }
 }
 
-struct git_istream *open_istream(const unsigned char *sha1,
+struct git_istream *open_istream(const struct object_id *oid,
                                 enum object_type *type,
                                 unsigned long *size,
                                 struct stream_filter *filter)
 {
        struct git_istream *st;
        struct object_info oi = OBJECT_INFO_INIT;
-       const unsigned char *real = lookup_replace_object(sha1);
+       const struct object_id *real = lookup_replace_object(the_repository, oid);
        enum input_source src = istream_source(real, type, &oi);
 
        if (src < 0)
@@ -335,7 +338,8 @@ static struct stream_vtbl loose_vtbl = {
 
 static open_method_decl(loose)
 {
-       st->u.loose.mapped = map_sha1_file(sha1, &st->u.loose.mapsize);
+       st->u.loose.mapped = map_sha1_file(the_repository,
+                                          oid->hash, &st->u.loose.mapsize);
        if (!st->u.loose.mapped)
                return -1;
        if ((unpack_sha1_header(&st->z,
@@ -486,7 +490,7 @@ static struct stream_vtbl incore_vtbl = {
 
 static open_method_decl(incore)
 {
-       st->u.incore.buf = read_sha1_file_extended(sha1, type, &st->size, 0);
+       st->u.incore.buf = read_object_file_extended(oid, type, &st->size, 0);
        st->u.incore.read_ptr = 0;
        st->vtbl = &incore_vtbl;
 
@@ -507,7 +511,7 @@ int stream_blob_to_fd(int fd, const struct object_id *oid, struct stream_filter
        ssize_t kept = 0;
        int result = -1;
 
-       st = open_istream(oid->hash, &type, &sz, filter);
+       st = open_istream(oid, &type, &sz, filter);
        if (!st) {
                if (filter)
                        free_stream_filter(filter);
index 73c1d156b352898c9b5661a3e480f579b80c5a00..32f46267710b4e88cd0fc90e1a5a6f6388361c61 100644 (file)
@@ -8,7 +8,7 @@
 /* opaque */
 struct git_istream;
 
-extern struct git_istream *open_istream(const unsigned char *, enum object_type *, unsigned long *, struct stream_filter *);
+extern struct git_istream *open_istream(const struct object_id *, enum object_type *, unsigned long *, struct stream_filter *);
 extern int close_istream(struct git_istream *);
 extern ssize_t read_istream(struct git_istream *, void *, size_t);
 
index 33c1b388e5d79bfec7db6c505444a42a98b7fe6d..91c9479cd39e93f631fdb7ad098993eb84bb2898 100644 (file)
@@ -44,7 +44,7 @@ static int config_path_cmp(const void *unused_cmp_data,
        const struct submodule_entry *b = entry_or_key;
 
        return strcmp(a->config->path, b->config->path) ||
-              hashcmp(a->config->gitmodules_sha1, b->config->gitmodules_sha1);
+              oidcmp(&a->config->gitmodules_oid, &b->config->gitmodules_oid);
 }
 
 static int config_name_cmp(const void *unused_cmp_data,
@@ -56,7 +56,7 @@ static int config_name_cmp(const void *unused_cmp_data,
        const struct submodule_entry *b = entry_or_key;
 
        return strcmp(a->config->name, b->config->name) ||
-              hashcmp(a->config->gitmodules_sha1, b->config->gitmodules_sha1);
+              oidcmp(&a->config->gitmodules_oid, &b->config->gitmodules_oid);
 }
 
 static struct submodule_cache *submodule_cache_alloc(void)
@@ -109,17 +109,17 @@ void submodule_cache_free(struct submodule_cache *cache)
        free(cache);
 }
 
-static unsigned int hash_sha1_string(const unsigned char *sha1,
-                                    const char *string)
+static unsigned int hash_oid_string(const struct object_id *oid,
+                                   const char *string)
 {
-       return memhash(sha1, 20) + strhash(string);
+       return memhash(oid->hash, the_hash_algo->rawsz) + strhash(string);
 }
 
 static void cache_put_path(struct submodule_cache *cache,
                           struct submodule *submodule)
 {
-       unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1,
-                                            submodule->path);
+       unsigned int hash = hash_oid_string(&submodule->gitmodules_oid,
+                                           submodule->path);
        struct submodule_entry *e = xmalloc(sizeof(*e));
        hashmap_entry_init(e, hash);
        e->config = submodule;
@@ -129,8 +129,8 @@ static void cache_put_path(struct submodule_cache *cache,
 static void cache_remove_path(struct submodule_cache *cache,
                              struct submodule *submodule)
 {
-       unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1,
-                                            submodule->path);
+       unsigned int hash = hash_oid_string(&submodule->gitmodules_oid,
+                                           submodule->path);
        struct submodule_entry e;
        struct submodule_entry *removed;
        hashmap_entry_init(&e, hash);
@@ -142,8 +142,8 @@ static void cache_remove_path(struct submodule_cache *cache,
 static void cache_add(struct submodule_cache *cache,
                      struct submodule *submodule)
 {
-       unsigned int hash = hash_sha1_string(submodule->gitmodules_sha1,
-                                            submodule->name);
+       unsigned int hash = hash_oid_string(&submodule->gitmodules_oid,
+                                           submodule->name);
        struct submodule_entry *e = xmalloc(sizeof(*e));
        hashmap_entry_init(e, hash);
        e->config = submodule;
@@ -151,14 +151,14 @@ static void cache_add(struct submodule_cache *cache,
 }
 
 static const struct submodule *cache_lookup_path(struct submodule_cache *cache,
-               const unsigned char *gitmodules_sha1, const char *path)
+               const struct object_id *gitmodules_oid, const char *path)
 {
        struct submodule_entry *entry;
-       unsigned int hash = hash_sha1_string(gitmodules_sha1, path);
+       unsigned int hash = hash_oid_string(gitmodules_oid, path);
        struct submodule_entry key;
        struct submodule key_config;
 
-       hashcpy(key_config.gitmodules_sha1, gitmodules_sha1);
+       oidcpy(&key_config.gitmodules_oid, gitmodules_oid);
        key_config.path = path;
 
        hashmap_entry_init(&key, hash);
@@ -171,14 +171,14 @@ static const struct submodule *cache_lookup_path(struct submodule_cache *cache,
 }
 
 static struct submodule *cache_lookup_name(struct submodule_cache *cache,
-               const unsigned char *gitmodules_sha1, const char *name)
+               const struct object_id *gitmodules_oid, const char *name)
 {
        struct submodule_entry *entry;
-       unsigned int hash = hash_sha1_string(gitmodules_sha1, name);
+       unsigned int hash = hash_oid_string(gitmodules_oid, name);
        struct submodule_entry key;
        struct submodule key_config;
 
-       hashcpy(key_config.gitmodules_sha1, gitmodules_sha1);
+       oidcpy(&key_config.gitmodules_oid, gitmodules_oid);
        key_config.name = name;
 
        hashmap_entry_init(&key, hash);
@@ -238,12 +238,12 @@ static int name_and_item_from_var(const char *var, struct strbuf *name,
 }
 
 static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache,
-               const unsigned char *gitmodules_sha1, const char *name)
+               const struct object_id *gitmodules_oid, const char *name)
 {
        struct submodule *submodule;
        struct strbuf name_buf = STRBUF_INIT;
 
-       submodule = cache_lookup_name(cache, gitmodules_sha1, name);
+       submodule = cache_lookup_name(cache, gitmodules_oid, name);
        if (submodule)
                return submodule;
 
@@ -261,7 +261,7 @@ static struct submodule *lookup_or_create_by_name(struct submodule_cache *cache,
        submodule->branch = NULL;
        submodule->recommend_shallow = -1;
 
-       hashcpy(submodule->gitmodules_sha1, gitmodules_sha1);
+       oidcpy(&submodule->gitmodules_oid, gitmodules_oid);
 
        cache_add(cache, submodule);
 
@@ -372,12 +372,12 @@ int parse_push_recurse_submodules_arg(const char *opt, const char *arg)
        return parse_push_recurse(opt, arg, 1);
 }
 
-static void warn_multiple_config(const unsigned char *treeish_name,
+static void warn_multiple_config(const struct object_id *treeish_name,
                                 const char *name, const char *option)
 {
        const char *commit_string = "WORKTREE";
        if (treeish_name)
-               commit_string = sha1_to_hex(treeish_name);
+               commit_string = oid_to_hex(treeish_name);
        warning("%s:.gitmodules, multiple configurations found for "
                        "'submodule.%s.%s'. Skipping second one!",
                        commit_string, name, option);
@@ -391,8 +391,8 @@ static void warn_command_line_option(const char *var, const char *value)
 
 struct parse_config_parameter {
        struct submodule_cache *cache;
-       const unsigned char *treeish_name;
-       const unsigned char *gitmodules_sha1;
+       const struct object_id *treeish_name;
+       const struct object_id *gitmodules_oid;
        int overwrite;
 };
 
@@ -415,7 +415,7 @@ static int parse_config(const char *var, const char *value, void *data)
                return 0;
 
        submodule = lookup_or_create_by_name(me->cache,
-                                            me->gitmodules_sha1,
+                                            me->gitmodules_oid,
                                             name.buf);
 
        if (!strcmp(item.buf, "path")) {
@@ -435,7 +435,7 @@ static int parse_config(const char *var, const char *value, void *data)
                }
        } else if (!strcmp(item.buf, "fetchrecursesubmodules")) {
                /* when parsing worktree configurations we can die early */
-               int die_on_error = is_null_sha1(me->gitmodules_sha1);
+               int die_on_error = is_null_oid(me->gitmodules_oid);
                if (!me->overwrite &&
                    submodule->fetch_recurse != RECURSE_SUBMODULES_NONE)
                        warn_multiple_config(me->treeish_name, submodule->name,
@@ -560,23 +560,23 @@ static const struct submodule *config_from(struct submodule_cache *cache,
 
        switch (lookup_type) {
        case lookup_name:
-               submodule = cache_lookup_name(cache, oid.hash, key);
+               submodule = cache_lookup_name(cache, &oid, key);
                break;
        case lookup_path:
-               submodule = cache_lookup_path(cache, oid.hash, key);
+               submodule = cache_lookup_path(cache, &oid, key);
                break;
        }
        if (submodule)
                goto out;
 
-       config = read_sha1_file(oid.hash, &type, &config_size);
+       config = read_object_file(&oid, &type, &config_size);
        if (!config || type != OBJ_BLOB)
                goto out;
 
        /* fill the submodule config into the cache */
        parameter.cache = cache;
-       parameter.treeish_name = treeish_name->hash;
-       parameter.gitmodules_sha1 = oid.hash;
+       parameter.treeish_name = treeish_name;
+       parameter.gitmodules_oid = &oid;
        parameter.overwrite = 0;
        git_config_from_mem(parse_config, CONFIG_ORIGIN_SUBMODULE_BLOB, rev.buf,
                        config, config_size, &parameter);
@@ -585,9 +585,9 @@ static const struct submodule *config_from(struct submodule_cache *cache,
 
        switch (lookup_type) {
        case lookup_name:
-               return cache_lookup_name(cache, oid.hash, key);
+               return cache_lookup_name(cache, &oid, key);
        case lookup_path:
-               return cache_lookup_path(cache, oid.hash, key);
+               return cache_lookup_path(cache, &oid, key);
        default:
                return NULL;
        }
@@ -616,7 +616,7 @@ static int gitmodules_cb(const char *var, const char *value, void *data)
 
        parameter.cache = repo->submodule_cache;
        parameter.treeish_name = NULL;
-       parameter.gitmodules_sha1 = null_sha1;
+       parameter.gitmodules_oid = &null_oid;
        parameter.overwrite = 1;
 
        return parse_config(var, value, &parameter);
@@ -668,31 +668,24 @@ static void gitmodules_read_check(struct repository *repo)
                repo_read_gitmodules(repo);
 }
 
-const struct submodule *submodule_from_name(const struct object_id *treeish_name,
+const struct submodule *submodule_from_name(struct repository *r,
+                                           const struct object_id *treeish_name,
                const char *name)
 {
-       gitmodules_read_check(the_repository);
-       return config_from(the_repository->submodule_cache, treeish_name, name, lookup_name);
+       gitmodules_read_check(r);
+       return config_from(r->submodule_cache, treeish_name, name, lookup_name);
 }
 
-const struct submodule *submodule_from_path(const struct object_id *treeish_name,
+const struct submodule *submodule_from_path(struct repository *r,
+                                           const struct object_id *treeish_name,
                const char *path)
 {
-       gitmodules_read_check(the_repository);
-       return config_from(the_repository->submodule_cache, treeish_name, path, lookup_path);
+       gitmodules_read_check(r);
+       return config_from(r->submodule_cache, treeish_name, path, lookup_path);
 }
 
-const struct submodule *submodule_from_cache(struct repository *repo,
-                                            const struct object_id *treeish_name,
-                                            const char *key)
+void submodule_free(struct repository *r)
 {
-       gitmodules_read_check(repo);
-       return config_from(repo->submodule_cache, treeish_name,
-                          key, lookup_path);
-}
-
-void submodule_free(void)
-{
-       if (the_repository->submodule_cache)
-               submodule_cache_clear(the_repository->submodule_cache);
+       if (r->submodule_cache)
+               submodule_cache_clear(r->submodule_cache);
 }
index 17e297022396d2b2b837187d6deaf8a42d45a0d6..ca1f94e2d2ed90f9ef4c588e27c0d8e15e1724ab 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef SUBMODULE_CONFIG_CACHE_H
 #define SUBMODULE_CONFIG_CACHE_H
 
+#include "cache.h"
 #include "hashmap.h"
 #include "submodule.h"
 #include "strbuf.h"
@@ -17,13 +18,13 @@ struct submodule {
        const char *ignore;
        const char *branch;
        struct submodule_update_strategy update_strategy;
-       /* the sha1 blob id of the responsible .gitmodules file */
-       unsigned char gitmodules_sha1[20];
+       /* the object id of the responsible .gitmodules file */
+       struct object_id gitmodules_oid;
        int recommend_shallow;
 };
 
 #define SUBMODULE_INIT { NULL, NULL, NULL, RECURSE_SUBMODULES_NONE, \
-       NULL, NULL, SUBMODULE_UPDATE_STRATEGY_INIT, {0}, -1 };
+       NULL, NULL, SUBMODULE_UPDATE_STRATEGY_INIT, { { 0 } }, -1 };
 
 struct submodule_cache;
 struct repository;
@@ -39,14 +40,13 @@ extern int parse_update_recurse_submodules_arg(const char *opt, const char *arg)
 extern int parse_push_recurse_submodules_arg(const char *opt, const char *arg);
 extern void repo_read_gitmodules(struct repository *repo);
 extern void gitmodules_config_oid(const struct object_id *commit_oid);
-extern const struct submodule *submodule_from_name(
-               const struct object_id *commit_or_tree, const char *name);
-extern const struct submodule *submodule_from_path(
-               const struct object_id *commit_or_tree, const char *path);
-extern const struct submodule *submodule_from_cache(struct repository *repo,
-                                                   const struct object_id *treeish_name,
-                                                   const char *key);
-extern void submodule_free(void);
+const struct submodule *submodule_from_name(struct repository *r,
+                                           const struct object_id *commit_or_tree,
+                                           const char *name);
+const struct submodule *submodule_from_path(struct repository *r,
+                                           const struct object_id *commit_or_tree,
+                                           const char *path);
+void submodule_free(struct repository *r);
 
 /*
  * Returns 0 if the name is syntactically acceptable as a submodule "name"
index e3aa8b642fc87cf504e208d3922bfd5da5e8470e..893083cbf043fd91def350cc6d2617b8cad4bc15 100644 (file)
@@ -21,6 +21,7 @@
 #include "remote.h"
 #include "worktree.h"
 #include "parse-options.h"
+#include "object-store.h"
 
 static int config_update_recurse_submodules = RECURSE_SUBMODULES_OFF;
 static struct string_list changed_submodule_names = STRING_LIST_INIT_DUP;
@@ -95,7 +96,7 @@ int update_path_in_gitmodules(const char *oldpath, const char *newpath)
        if (is_gitmodules_unmerged(&the_index))
                die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
 
-       submodule = submodule_from_path(&null_oid, oldpath);
+       submodule = submodule_from_path(the_repository, &null_oid, oldpath);
        if (!submodule || !submodule->name) {
                warning(_("Could not find section in .gitmodules where path=%s"), oldpath);
                return -1;
@@ -129,7 +130,7 @@ int remove_path_from_gitmodules(const char *path)
        if (is_gitmodules_unmerged(&the_index))
                die(_("Cannot change unmerged .gitmodules, resolve merge conflicts first"));
 
-       submodule = submodule_from_path(&null_oid, path);
+       submodule = submodule_from_path(the_repository, &null_oid, path);
        if (!submodule || !submodule->name) {
                warning(_("Could not find section in .gitmodules where path=%s"), path);
                return -1;
@@ -152,7 +153,8 @@ void stage_updated_gitmodules(struct index_state *istate)
                die(_("staging updated .gitmodules failed"));
 }
 
-static int add_submodule_odb(const char *path)
+/* TODO: remove this function, use repo_submodule_init instead. */
+int add_submodule_odb(const char *path)
 {
        struct strbuf objects_directory = STRBUF_INIT;
        int ret = 0;
@@ -173,7 +175,8 @@ done:
 void set_diffopt_flags_from_submodule_config(struct diff_options *diffopt,
                                             const char *path)
 {
-       const struct submodule *submodule = submodule_from_path(&null_oid, path);
+       const struct submodule *submodule = submodule_from_path(the_repository,
+                                                               &null_oid, path);
        if (submodule) {
                const char *ignore;
                char *key;
@@ -229,7 +232,7 @@ int is_submodule_active(struct repository *repo, const char *path)
        const struct string_list *sl;
        const struct submodule *module;
 
-       module = submodule_from_cache(repo, &null_oid, path);
+       module = submodule_from_path(repo, &null_oid, path);
 
        /* early return if there isn't a path->module mapping */
        if (!module)
@@ -540,9 +543,9 @@ static void show_submodule_header(struct diff_options *o, const char *path,
 
 output_header:
        strbuf_addf(&sb, "Submodule %s ", path);
-       strbuf_add_unique_abbrev(&sb, one->hash, DEFAULT_ABBREV);
+       strbuf_add_unique_abbrev(&sb, one, DEFAULT_ABBREV);
        strbuf_addstr(&sb, (fast_backward || fast_forward) ? ".." : "...");
-       strbuf_add_unique_abbrev(&sb, two->hash, DEFAULT_ABBREV);
+       strbuf_add_unique_abbrev(&sb, two, DEFAULT_ABBREV);
        if (message)
                strbuf_addf(&sb, " %s\n", message);
        else
@@ -673,7 +676,7 @@ const struct submodule *submodule_from_ce(const struct cache_entry *ce)
        if (!should_update_submodules())
                return NULL;
 
-       return submodule_from_path(&null_oid, ce->name);
+       return submodule_from_path(the_repository, &null_oid, ce->name);
 }
 
 static struct oid_array *submodule_commits(struct string_list *submodules,
@@ -730,13 +733,14 @@ static void collect_changed_submodules_cb(struct diff_queue_struct *q,
                if (!S_ISGITLINK(p->two->mode))
                        continue;
 
-               submodule = submodule_from_path(commit_oid, p->two->path);
+               submodule = submodule_from_path(the_repository,
+                                               commit_oid, p->two->path);
                if (submodule)
                        name = submodule->name;
                else {
                        name = default_name_or_path(p->two->path);
                        /* make sure name does not collide with existing one */
-                       submodule = submodule_from_name(commit_oid, name);
+                       submodule = submodule_from_name(the_repository, commit_oid, name);
                        if (submodule) {
                                warning("Submodule in commit %s at path: "
                                        "'%s' collides with a submodule named "
@@ -817,7 +821,7 @@ static int check_has_commit(const struct object_id *oid, void *data)
 {
        struct has_commit_data *cb = data;
 
-       enum object_type type = sha1_object_info(oid->hash, NULL);
+       enum object_type type = oid_object_info(the_repository, oid, NULL);
 
        switch (type) {
        case OBJ_COMMIT:
@@ -944,7 +948,7 @@ int find_unpushed_submodules(struct oid_array *commits,
                const struct submodule *submodule;
                const char *path = NULL;
 
-               submodule = submodule_from_name(&null_oid, name->string);
+               submodule = submodule_from_name(the_repository, &null_oid, name->string);
                if (submodule)
                        path = submodule->path;
                else
@@ -965,7 +969,7 @@ int find_unpushed_submodules(struct oid_array *commits,
 
 static int push_submodule(const char *path,
                          const struct remote *remote,
-                         const char **refspec, int refspec_nr,
+                         const struct refspec *rs,
                          const struct string_list *push_options,
                          int dry_run)
 {
@@ -988,8 +992,8 @@ static int push_submodule(const char *path,
                if (remote->origin != REMOTE_UNCONFIGURED) {
                        int i;
                        argv_array_push(&cp.args, remote->name);
-                       for (i = 0; i < refspec_nr; i++)
-                               argv_array_push(&cp.args, refspec[i]);
+                       for (i = 0; i < rs->raw_nr; i++)
+                               argv_array_push(&cp.args, rs->raw[i]);
                }
 
                prepare_submodule_repo_env(&cp.env_array);
@@ -1010,7 +1014,7 @@ static int push_submodule(const char *path,
  */
 static void submodule_push_check(const char *path, const char *head,
                                 const struct remote *remote,
-                                const char **refspec, int refspec_nr)
+                                const struct refspec *rs)
 {
        struct child_process cp = CHILD_PROCESS_INIT;
        int i;
@@ -1020,8 +1024,8 @@ static void submodule_push_check(const char *path, const char *head,
        argv_array_push(&cp.args, head);
        argv_array_push(&cp.args, remote->name);
 
-       for (i = 0; i < refspec_nr; i++)
-               argv_array_push(&cp.args, refspec[i]);
+       for (i = 0; i < rs->raw_nr; i++)
+               argv_array_push(&cp.args, rs->raw[i]);
 
        prepare_submodule_repo_env(&cp.env_array);
        cp.git_cmd = 1;
@@ -1040,7 +1044,7 @@ static void submodule_push_check(const char *path, const char *head,
 
 int push_unpushed_submodules(struct oid_array *commits,
                             const struct remote *remote,
-                            const char **refspec, int refspec_nr,
+                            const struct refspec *rs,
                             const struct string_list *push_options,
                             int dry_run)
 {
@@ -1066,8 +1070,7 @@ int push_unpushed_submodules(struct oid_array *commits,
 
                for (i = 0; i < needs_pushing.nr; i++)
                        submodule_push_check(needs_pushing.items[i].string,
-                                            head, remote,
-                                            refspec, refspec_nr);
+                                            head, remote, rs);
                free(head);
        }
 
@@ -1075,7 +1078,7 @@ int push_unpushed_submodules(struct oid_array *commits,
        for (i = 0; i < needs_pushing.nr; i++) {
                const char *path = needs_pushing.items[i].string;
                fprintf(stderr, "Pushing submodule '%s'\n", path);
-               if (!push_submodule(path, remote, refspec, refspec_nr,
+               if (!push_submodule(path, remote, rs,
                                    push_options, dry_run)) {
                        fprintf(stderr, "Unable to push submodule '%s'\n", path);
                        ret = 0;
@@ -1112,7 +1115,7 @@ static void calculate_changed_submodule_paths(void)
        const struct string_list_item *name;
 
        /* No need to check if there are no submodules configured */
-       if (!submodule_from_path(NULL, NULL))
+       if (!submodule_from_path(the_repository, NULL, NULL))
                return;
 
        argv_array_push(&argv, "--"); /* argv[0] program name */
@@ -1133,7 +1136,7 @@ static void calculate_changed_submodule_paths(void)
                const struct submodule *submodule;
                const char *path = NULL;
 
-               submodule = submodule_from_name(&null_oid, name->string);
+               submodule = submodule_from_name(the_repository, &null_oid, name->string);
                if (submodule)
                        path = submodule->path;
                else
@@ -1161,13 +1164,15 @@ int submodule_touches_in_range(struct object_id *excl_oid,
        int ret;
 
        /* No need to check if there are no submodules configured */
-       if (!submodule_from_path(NULL, NULL))
+       if (!submodule_from_path(the_repository, NULL, NULL))
                return 0;
 
        argv_array_push(&args, "--"); /* args[0] program name */
        argv_array_push(&args, oid_to_hex(incl_oid));
-       argv_array_push(&args, "--not");
-       argv_array_push(&args, oid_to_hex(excl_oid));
+       if (!is_null_oid(excl_oid)) {
+               argv_array_push(&args, "--not");
+               argv_array_push(&args, oid_to_hex(excl_oid));
+       }
 
        collect_changed_submodules(&subs, &args);
        ret = subs.nr;
@@ -1233,7 +1238,7 @@ static int get_next_submodule(struct child_process *cp,
                if (!S_ISGITLINK(ce->ce_mode))
                        continue;
 
-               submodule = submodule_from_cache(spf->r, &null_oid, ce->name);
+               submodule = submodule_from_path(spf->r, &null_oid, ce->name);
                if (!submodule) {
                        const char *name = default_name_or_path(ce->name);
                        if (name) {
@@ -1397,7 +1402,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked)
                    buf.buf[0] == '2') {
                        /* T = line type, XY = status, SSSS = submodule state */
                        if (buf.len < strlen("T XY SSSS"))
-                               die("BUG: invalid status --porcelain=2 line %s",
+                               BUG("invalid status --porcelain=2 line %s",
                                    buf.buf);
 
                        if (buf.buf[5] == 'S' && buf.buf[8] == 'U')
@@ -1566,7 +1571,7 @@ static void submodule_reset_index(const char *path)
                                   get_super_prefix_or_empty(), path);
        argv_array_pushl(&cp.args, "read-tree", "-u", "--reset", NULL);
 
-       argv_array_push(&cp.args, EMPTY_TREE_SHA1_HEX);
+       argv_array_push(&cp.args, empty_tree_oid_hex());
 
        if (run_command(&cp))
                die("could not reset submodule index");
@@ -1603,10 +1608,10 @@ int submodule_move_head(const char *path,
        if (old_head && !is_submodule_populated_gently(path, error_code_ptr))
                return 0;
 
-       sub = submodule_from_path(&null_oid, path);
+       sub = submodule_from_path(the_repository, &null_oid, path);
 
        if (!sub)
-               die("BUG: could not get submodule information for '%s'", path);
+               BUG("could not get submodule information for '%s'", path);
 
        if (old_head && !(flags & SUBMODULE_MOVE_HEAD_FORCE)) {
                /* Check if the submodule has a dirty index. */
@@ -1622,7 +1627,7 @@ int submodule_move_head(const char *path,
                } else {
                        char *gitdir = xstrfmt("%s/modules/%s",
                                    get_git_common_dir(), sub->name);
-                       connect_work_tree_and_git_dir(path, gitdir);
+                       connect_work_tree_and_git_dir(path, gitdir, 0);
                        free(gitdir);
 
                        /* make sure the index is clean as well */
@@ -1632,7 +1637,7 @@ int submodule_move_head(const char *path,
                if (old_head && (flags & SUBMODULE_MOVE_HEAD_FORCE)) {
                        char *gitdir = xstrfmt("%s/modules/%s",
                                    get_git_common_dir(), sub->name);
-                       connect_work_tree_and_git_dir(path, gitdir);
+                       connect_work_tree_and_git_dir(path, gitdir, 1);
                        free(gitdir);
                }
        }
@@ -1658,9 +1663,9 @@ int submodule_move_head(const char *path,
                argv_array_push(&cp.args, "-m");
 
        if (!(flags & SUBMODULE_MOVE_HEAD_FORCE))
-               argv_array_push(&cp.args, old_head ? old_head : EMPTY_TREE_SHA1_HEX);
+               argv_array_push(&cp.args, old_head ? old_head : empty_tree_oid_hex());
 
-       argv_array_push(&cp.args, new_head ? new_head : EMPTY_TREE_SHA1_HEX);
+       argv_array_push(&cp.args, new_head ? new_head : empty_tree_oid_hex());
 
        if (run_command(&cp)) {
                ret = -1;
@@ -1698,171 +1703,6 @@ out:
        return ret;
 }
 
-static int find_first_merges(struct object_array *result, const char *path,
-               struct commit *a, struct commit *b)
-{
-       int i, j;
-       struct object_array merges = OBJECT_ARRAY_INIT;
-       struct commit *commit;
-       int contains_another;
-
-       char merged_revision[42];
-       const char *rev_args[] = { "rev-list", "--merges", "--ancestry-path",
-                                  "--all", merged_revision, NULL };
-       struct rev_info revs;
-       struct setup_revision_opt rev_opts;
-
-       memset(result, 0, sizeof(struct object_array));
-       memset(&rev_opts, 0, sizeof(rev_opts));
-
-       /* get all revisions that merge commit a */
-       xsnprintf(merged_revision, sizeof(merged_revision), "^%s",
-                       oid_to_hex(&a->object.oid));
-       init_revisions(&revs, NULL);
-       rev_opts.submodule = path;
-       /* FIXME: can't handle linked worktrees in submodules yet */
-       revs.single_worktree = path != NULL;
-       setup_revisions(ARRAY_SIZE(rev_args)-1, rev_args, &revs, &rev_opts);
-
-       /* save all revisions from the above list that contain b */
-       if (prepare_revision_walk(&revs))
-               die("revision walk setup failed");
-       while ((commit = get_revision(&revs)) != NULL) {
-               struct object *o = &(commit->object);
-               if (in_merge_bases(b, commit))
-                       add_object_array(o, NULL, &merges);
-       }
-       reset_revision_walk();
-
-       /* Now we've got all merges that contain a and b. Prune all
-        * merges that contain another found merge and save them in
-        * result.
-        */
-       for (i = 0; i < merges.nr; i++) {
-               struct commit *m1 = (struct commit *) merges.objects[i].item;
-
-               contains_another = 0;
-               for (j = 0; j < merges.nr; j++) {
-                       struct commit *m2 = (struct commit *) merges.objects[j].item;
-                       if (i != j && in_merge_bases(m2, m1)) {
-                               contains_another = 1;
-                               break;
-                       }
-               }
-
-               if (!contains_another)
-                       add_object_array(merges.objects[i].item, NULL, result);
-       }
-
-       object_array_clear(&merges);
-       return result->nr;
-}
-
-static void print_commit(struct commit *commit)
-{
-       struct strbuf sb = STRBUF_INIT;
-       struct pretty_print_context ctx = {0};
-       ctx.date_mode.type = DATE_NORMAL;
-       format_commit_message(commit, " %h: %m %s", &sb, &ctx);
-       fprintf(stderr, "%s\n", sb.buf);
-       strbuf_release(&sb);
-}
-
-#define MERGE_WARNING(path, msg) \
-       warning("Failed to merge submodule %s (%s)", path, msg);
-
-int merge_submodule(struct object_id *result, const char *path,
-                   const struct object_id *base, const struct object_id *a,
-                   const struct object_id *b, int search)
-{
-       struct commit *commit_base, *commit_a, *commit_b;
-       int parent_count;
-       struct object_array merges;
-
-       int i;
-
-       /* store a in result in case we fail */
-       oidcpy(result, a);
-
-       /* we can not handle deletion conflicts */
-       if (is_null_oid(base))
-               return 0;
-       if (is_null_oid(a))
-               return 0;
-       if (is_null_oid(b))
-               return 0;
-
-       if (add_submodule_odb(path)) {
-               MERGE_WARNING(path, "not checked out");
-               return 0;
-       }
-
-       if (!(commit_base = lookup_commit_reference(base)) ||
-           !(commit_a = lookup_commit_reference(a)) ||
-           !(commit_b = lookup_commit_reference(b))) {
-               MERGE_WARNING(path, "commits not present");
-               return 0;
-       }
-
-       /* check whether both changes are forward */
-       if (!in_merge_bases(commit_base, commit_a) ||
-           !in_merge_bases(commit_base, commit_b)) {
-               MERGE_WARNING(path, "commits don't follow merge-base");
-               return 0;
-       }
-
-       /* Case #1: a is contained in b or vice versa */
-       if (in_merge_bases(commit_a, commit_b)) {
-               oidcpy(result, b);
-               return 1;
-       }
-       if (in_merge_bases(commit_b, commit_a)) {
-               oidcpy(result, a);
-               return 1;
-       }
-
-       /*
-        * Case #2: There are one or more merges that contain a and b in
-        * the submodule. If there is only one, then present it as a
-        * suggestion to the user, but leave it marked unmerged so the
-        * user needs to confirm the resolution.
-        */
-
-       /* Skip the search if makes no sense to the calling context.  */
-       if (!search)
-               return 0;
-
-       /* find commit which merges them */
-       parent_count = find_first_merges(&merges, path, commit_a, commit_b);
-       switch (parent_count) {
-       case 0:
-               MERGE_WARNING(path, "merge following commits not found");
-               break;
-
-       case 1:
-               MERGE_WARNING(path, "not fast-forward");
-               fprintf(stderr, "Found a possible merge resolution "
-                               "for the submodule:\n");
-               print_commit((struct commit *) merges.objects[0].item);
-               fprintf(stderr,
-                       "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",
-                       oid_to_hex(&merges.objects[0].item->oid), path);
-               break;
-
-       default:
-               MERGE_WARNING(path, "multiple merges found");
-               for (i = 0; i < merges.nr; i++)
-                       print_commit((struct commit *) merges.objects[i].item);
-       }
-
-       object_array_clear(&merges);
-       return 0;
-}
-
 int validate_submodule_git_dir(char *git_dir, const char *submodule_name)
 {
        size_t len = strlen(git_dir), suffix_len = strlen(submodule_name);
@@ -1926,7 +1766,7 @@ static void relocate_single_git_dir_into_superproject(const char *prefix,
 
        real_old_git_dir = real_pathdup(old_git_dir, 1);
 
-       sub = submodule_from_path(&null_oid, path);
+       sub = submodule_from_path(the_repository, &null_oid, path);
        if (!sub)
                die(_("could not lookup name for submodule '%s'"), path);
 
@@ -1986,11 +1826,11 @@ void absorb_git_dir_into_superproject(const char *prefix,
                * superproject did not rewrite the git file links yet,
                * fix it now.
                */
-               sub = submodule_from_path(&null_oid, path);
+               sub = submodule_from_path(the_repository, &null_oid, path);
                if (!sub)
                        die(_("could not lookup name for submodule '%s'"), path);
                connect_work_tree_and_git_dir(path,
-                       git_path("modules/%s", sub->name));
+                       git_path("modules/%s", sub->name), 0);
        } else {
                /* Is it already absorbed into the superprojects git dir? */
                char *real_sub_git_dir = real_pathdup(sub_git_dir, 1);
@@ -2009,7 +1849,7 @@ void absorb_git_dir_into_superproject(const char *prefix,
                struct strbuf sb = STRBUF_INIT;
 
                if (flags & ~ABSORB_GITDIR_RECURSE_SUBMODULES)
-                       die("BUG: we don't know how to pass the flags down?");
+                       BUG("we don't know how to pass the flags down?");
 
                strbuf_addstr(&sb, get_super_prefix_or_empty());
                strbuf_addstr(&sb, path);
@@ -2087,7 +1927,7 @@ const char *get_superproject_working_tree(void)
 
                if (super_sub_len > cwd_len ||
                    strcmp(&cwd[cwd_len - super_sub_len], super_sub))
-                       die (_("BUG: returned path string doesn't match cwd?"));
+                       BUG("returned path string doesn't match cwd?");
 
                super_wt = xstrdup(cwd);
                super_wt[cwd_len - super_sub_len] = '\0';
@@ -2132,7 +1972,7 @@ int submodule_to_gitdir(struct strbuf *buf, const char *submodule)
                strbuf_addstr(buf, git_dir);
        }
        if (!is_git_directory(buf->buf)) {
-               sub = submodule_from_path(&null_oid, submodule);
+               sub = submodule_from_path(the_repository, &null_oid, submodule);
                if (!sub) {
                        ret = -1;
                        goto cleanup;
index 51b9cf245a25f67c2d1ac2301d6727d8be175db9..17347ace2edf6ea7ac87692da58f1f451c9bdffa 100644 (file)
@@ -89,23 +89,24 @@ extern int submodule_uses_gitfile(const char *path);
 #define SUBMODULE_REMOVAL_IGNORE_UNTRACKED (1<<1)
 #define SUBMODULE_REMOVAL_IGNORE_IGNORED_UNTRACKED (1<<2)
 extern int bad_to_remove_submodule(const char *path, unsigned flags);
-extern int merge_submodule(struct object_id *result, const char *path,
-                          const struct object_id *base,
-                          const struct object_id *a,
-                          const struct object_id *b, int search);
 
-/* Checks if there are submodule changes in a..b. */
+int add_submodule_odb(const char *path);
+
+/*
+ * Checks if there are submodule changes in a..b. If a is the null OID,
+ * checks b and all its ancestors instead.
+ */
 extern int submodule_touches_in_range(struct object_id *a,
                                      struct object_id *b);
 extern int find_unpushed_submodules(struct oid_array *commits,
                                    const char *remotes_name,
                                    struct string_list *needs_pushing);
+struct refspec;
 extern int push_unpushed_submodules(struct oid_array *commits,
                                    const struct remote *remote,
-                                   const char **refspec, int refspec_nr,
+                                   const struct refspec *rs,
                                    const struct string_list *push_options,
                                    int dry_run);
-extern void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir);
 /*
  * Given a submodule path (as in the index), return the repository
  * path of that submodule in 'buf'. Return -1 on error or when the
index 24ddebfabf97be1251452fe5b6bba847597431fd..8373a27fea38b1ec111e80d203bf61f1143b7861 100644 (file)
--- a/t/README
+++ b/t/README
@@ -293,6 +293,28 @@ and know what setup is needed for it.  Or when you want to run
 everything up to a certain test.
 
 
+Running tests with special setups
+---------------------------------
+
+The whole test suite could be run to test some special features
+that cannot be easily covered by a few specific test cases. These
+could be enabled by running the test suite with correct GIT_TEST_
+environment set.
+
+GIT_TEST_SPLIT_INDEX=<boolean> forces split-index mode on the whole
+test suite. Accept any boolean values that are accepted by git-config.
+
+GIT_TEST_FULL_IN_PACK_ARRAY=<boolean> exercises the uncommon
+pack-objects code path where there are more than 1024 packs even if
+the actual number of packs in repository is below this limit. Accept
+any boolean values that are accepted by git-config.
+
+GIT_TEST_OE_SIZE=<n> exercises the uncommon pack-objects code path
+where we do not cache object size in memory and read it from existing
+packs on demand. This normally only happens when the object size is
+over 2GB. This variable forces the code path on any object larger than
+<n> bytes.
+
 Naming Tests
 ------------
 
index c211dc40eed98fc58c953d2e3b1f7ba752f98a02..2de880f7a5b0642e0bcfb6fad97a8ff462c29392 100644 (file)
@@ -1,6 +1,6 @@
 :
 
-sanitize_diff_raw='/^:/s/ '"\($_x40\)"' '"\($_x40\)"' \([A-Z]\)[0-9]*  / \1 \2 \3#     /'
+sanitize_diff_raw='/^:/s/ '"\($OID_REGEX\)"' '"\($OID_REGEX\)"' \([A-Z]\)[0-9]*        / \1 \2 \3#     /'
 compare_diff_raw () {
     # When heuristics are improved, the score numbers would change.
     # Ignore them while comparing.
@@ -12,7 +12,7 @@ compare_diff_raw () {
     test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2
 }
 
-sanitize_diff_raw_z='/^:/s/ '"$_x40"' '"$_x40"' \([A-Z]\)[0-9]*$/ X X \1#/'
+sanitize_diff_raw_z='/^:/s/ '"$OID_REGEX"' '"$OID_REGEX"' \([A-Z]\)[0-9]*$/ X X \1#/'
 compare_diff_raw_z () {
     # When heuristics are improved, the score numbers would change.
     # Ignore them while comparing.
index e760256406fa9c2fe0f9b2cde0ffb97ff11c6cab..aa22af48c2a6f48a81a6306a1850f5b5256fa319 100644 (file)
@@ -5,32 +5,43 @@
  *
  * The mtime can be changed to an absolute value:
  *
- *     test-chmtime =<seconds> file...
+ *     test-tool chmtime =<seconds> file...
  *
  * Relative to the current time as returned by time(3):
  *
- *     test-chmtime =+<seconds> (or =-<seconds>) file...
+ *     test-tool chmtime =+<seconds> (or =-<seconds>) file...
  *
  * Or relative to the current mtime of the file:
  *
- *     test-chmtime <seconds> file...
- *     test-chmtime +<seconds> (or -<seconds>) file...
+ *     test-tool chmtime <seconds> file...
+ *     test-tool chmtime +<seconds> (or -<seconds>) file...
  *
  * Examples:
  *
- * To just print the mtime use --verbose and set the file mtime offset to 0:
+ * To print the mtime and the file name use --verbose and set
+ * the file mtime offset to 0:
  *
- *     test-chmtime -v +0 file
+ *     test-tool chmtime -v +0 file
+ *
+ * To print only the mtime use --get:
+ *
+ *     test-tool chmtime --get file
  *
  * To set the mtime to current time:
  *
- *     test-chmtime =+0 file
+ *     test-tool chmtime =+0 file
+ *
+ * To set the file mtime offset to +1 and print the new value:
+ *
+ *     test-tool chmtime --get +1 file
  *
  */
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include <utime.h>
 
-static const char usage_str[] = "-v|--verbose (+|=|=+|=-|-)<seconds> <file>...";
+static const char usage_str[] =
+       "(-v|--verbose|-g|--get) (+|=|=+|=-|-)<seconds> <file>...";
 
 static int timespec_arg(const char *arg, long int *set_time, int *set_eq)
 {
@@ -46,7 +57,6 @@ static int timespec_arg(const char *arg, long int *set_time, int *set_eq)
        }
        *set_time = strtol(timespec, &test, 10);
        if (*test) {
-               fprintf(stderr, "Not a base-10 integer: %s\n", arg + 1);
                return 0;
        }
        if ((*set_eq && *set_time < 0) || *set_eq == 2) {
@@ -56,9 +66,10 @@ static int timespec_arg(const char *arg, long int *set_time, int *set_eq)
        return 1;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__chmtime(int argc, const char **argv)
 {
        static int verbose;
+       static int get;
 
        int i = 1;
        /* no mtime change by default */
@@ -68,18 +79,34 @@ int cmd_main(int argc, const char **argv)
        if (argc < 3)
                goto usage;
 
-       if (strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
+       if (strcmp(argv[i], "--get") == 0 || strcmp(argv[i], "-g") == 0) {
+               get = 1;
+               ++i;
+       } else if (strcmp(argv[i], "--verbose") == 0 || strcmp(argv[i], "-v") == 0) {
                verbose = 1;
                ++i;
        }
-       if (timespec_arg(argv[i], &set_time, &set_eq))
+
+       if (i == argc) {
+               goto usage;
+       }
+
+       if (timespec_arg(argv[i], &set_time, &set_eq)) {
                ++i;
-       else
+       } else {
+               if (get == 0) {
+                       fprintf(stderr, "Not a base-10 integer: %s\n", argv[i] + 1);
+                       goto usage;
+               }
+       }
+
+       if (i == argc)
                goto usage;
 
        for (; i < argc; i++) {
                struct stat sb;
                struct utimbuf utb;
+               uintmax_t mtime;
 
                if (stat(argv[i], &sb) < 0) {
                        fprintf(stderr, "Failed to stat %s: %s\n",
@@ -99,8 +126,10 @@ int cmd_main(int argc, const char **argv)
                utb.actime = sb.st_atime;
                utb.modtime = set_eq ? set_time : sb.st_mtime + set_time;
 
-               if (verbose) {
-                       uintmax_t mtime = utb.modtime < 0 ? 0: utb.modtime;
+               mtime = utb.modtime < 0 ? 0: utb.modtime;
+               if (get) {
+                       printf("%"PRIuMAX"\n", mtime);
+               } else if (verbose) {
                        printf("%"PRIuMAX"\t%s\n", mtime, argv[i]);
                }
 
index 1a7b8bd3d650fe1111c77115d2c68644b6ac9edb..214003d5b2f9bbe978d5aa4d9c9ab3f9b8a990da 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "config.h"
 #include "string-list.h"
@@ -32,7 +33,7 @@
  * Examples:
  *
  * To print the value with highest priority for key "foo.bAr Baz.rock":
- *     test-config get_value "foo.bAr Baz.rock"
+ *     test-tool config get_value "foo.bAr Baz.rock"
  *
  */
 
@@ -77,7 +78,7 @@ static int early_config_cb(const char *var, const char *value, void *vdata)
        return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__config(int argc, const char **argv)
 {
        int i, val;
        const char *v;
index bb72c47df570d9c07ae4567fd6d31ea49fe49656..92c4c2313e78a305dd0da1e7a853e58e325d2f84 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 
 static int rc;
@@ -28,7 +29,7 @@ static int is_in(const char *s, int ch)
 #define LOWER "abcdefghijklmnopqrstuvwxyz"
 #define UPPER "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 
-int cmd_main(int argc, const char **argv)
+int cmd__ctype(int argc, const char **argv)
 {
        TEST_CLASS(isdigit, DIGIT);
        TEST_CLASS(isspace, " \n\r\t");
index ac8368797073adfdf203f60d93df55a988443dbd..a0837371aba17956331ddcdb04847c6c9edeefd2 100644 (file)
@@ -1,13 +1,14 @@
+#include "test-tool.h"
 #include "cache.h"
 
 static const char *usage_msg = "\n"
-"  test-date relative [time_t]...\n"
-"  test-date show:<format> [time_t]...\n"
-"  test-date parse [date]...\n"
-"  test-date approxidate [date]...\n"
-"  test-date timestamp [date]...\n"
-"  test-date is64bit\n"
-"  test-date time_t-is64bit\n";
+"  test-tool date relative [time_t]...\n"
+"  test-tool date show:<format> [time_t]...\n"
+"  test-tool date parse [date]...\n"
+"  test-tool date approxidate [date]...\n"
+"  test-tool date timestamp [date]...\n"
+"  test-tool date is64bit\n"
+"  test-tool date time_t-is64bit\n";
 
 static void show_relative_dates(const char **argv, struct timeval *now)
 {
@@ -81,7 +82,7 @@ static void parse_approx_timestamp(const char **argv, struct timeval *now)
        }
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__date(int argc, const char **argv)
 {
        struct timeval now;
        const char *x;
index 591730adc4f3940940fdb4691da0afb81648e353..34c7259248760ff8bdea495ac5effd5de2b04ae3 100644 (file)
@@ -8,14 +8,15 @@
  * published by the Free Software Foundation.
  */
 
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "delta.h"
 #include "cache.h"
 
 static const char usage_str[] =
-       "test-delta (-d|-p) <from_file> <data_file> <out_file>";
+       "test-tool delta (-d|-p) <from_file> <data_file> <out_file>";
 
-int cmd_main(int argc, const char **argv)
+int cmd__delta(int argc, const char **argv)
 {
        int fd;
        struct stat st;
index f125192c97139caaf1e457e03b77f969de86802f..7b4278462bb7166522369aa9d74147fa36c03835 100644 (file)
@@ -1,6 +1,8 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 
 #if defined(GIT_WINDOWS_NATIVE)
+#include "lazyload.h"
 
 static int cmd_sync(void)
 {
@@ -84,8 +86,7 @@ static int cmd_dropcaches(void)
 {
        HANDLE hProcess = GetCurrentProcess();
        HANDLE hToken;
-       HMODULE ntdll;
-       DWORD(WINAPI *NtSetSystemInformation)(INT, PVOID, ULONG);
+       DECLARE_PROC_ADDR(ntdll.dll, DWORD, NtSetSystemInformation, INT, PVOID, ULONG);
        SYSTEM_MEMORY_LIST_COMMAND command;
        int status;
 
@@ -97,14 +98,8 @@ static int cmd_dropcaches(void)
 
        CloseHandle(hToken);
 
-       ntdll = LoadLibrary("ntdll.dll");
-       if (!ntdll)
-               return error("Can't load ntdll.dll, wrong Windows version?");
-
-       NtSetSystemInformation =
-               (DWORD(WINAPI *)(INT, PVOID, ULONG))GetProcAddress(ntdll, "NtSetSystemInformation");
-       if (!NtSetSystemInformation)
-               return error("Can't get function addresses, wrong Windows version?");
+       if (!INIT_PROC_ADDR(NtSetSystemInformation))
+               return error("Could not find NtSetSystemInformation() function");
 
        command = MemoryPurgeStandbyList;
        status = NtSetSystemInformation(
@@ -117,8 +112,6 @@ static int cmd_dropcaches(void)
        else if (status != STATUS_SUCCESS)
                error("Unable to execute the memory list command %d", status);
 
-       FreeLibrary(ntdll);
-
        return status;
 }
 
@@ -160,7 +153,7 @@ static int cmd_dropcaches(void)
 
 #endif
 
-int cmd_main(int argc, const char **argv)
+int cmd__drop_caches(int argc, const char **argv)
 {
        cmd_sync();
        return cmd_dropcaches();
index ebf3aab22d6c197b99b0203dbe9881ccf417be86..98a4891f1dc936a486075703de319affdacb1c78 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "tree.h"
 #include "cache-tree.h"
@@ -54,7 +55,7 @@ static int dump_cache_tree(struct cache_tree *it,
        return errs;
 }
 
-int cmd_main(int ac, const char **av)
+int cmd__dump_cache_tree(int ac, const char **av)
 {
        struct index_state istate;
        struct cache_tree *another = cache_tree();
index e44430b699db732252afa6fcb06686ec89b5811d..63c689d6ee9d018efd32aa228ee3cf784fa5b71d 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "split-index.h"
 #include "ewah/ewok.h"
@@ -7,19 +8,19 @@ static void show_bit(size_t pos, void *data)
        printf(" %d", (int)pos);
 }
 
-int cmd_main(int ac, const char **av)
+int cmd__dump_split_index(int ac, const char **av)
 {
        struct split_index *si;
        int i;
 
        do_read_index(&the_index, av[1], 1);
-       printf("own %s\n", sha1_to_hex(the_index.sha1));
+       printf("own %s\n", oid_to_hex(&the_index.oid));
        si = the_index.split_index;
        if (!si) {
                printf("not a split index\n");
                return 0;
        }
-       printf("base %s\n", sha1_to_hex(si->base_sha1));
+       printf("base %s\n", oid_to_hex(&si->base_oid));
        for (i = 0; i < the_index.cache_nr; i++) {
                struct cache_entry *ce = the_index.cache[i];
                printf("%06o %s %d\t%s\n", ce->ce_mode,
index d7c55c2355ec7067e15655e99df8077344ed78fa..bd92fb305a239cb4b96d38b4a07fe885e71bbeb3 100644 (file)
@@ -23,7 +23,7 @@ static void dump(struct untracked_cache_dir *ucd, struct strbuf *base)
        len = base->len;
        strbuf_addf(base, "%s/", ucd->name);
        printf("%s %s", base->buf,
-              sha1_to_hex(ucd->exclude_sha1));
+              oid_to_hex(&ucd->exclude_oid));
        if (ucd->recurse)
                fputs(" recurse", stdout);
        if (ucd->check_only)
index 90dc97a9d0444bc2dd8beaa1bfdd970f4280efb7..a20a6161e4fce156cc2e987f61f4253b1f00b397 100644 (file)
@@ -1,8 +1,9 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "object.h"
 #include "decorate.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__example_decorate(int argc, const char **argv)
 {
        struct decoration n;
        struct object_id one_oid = { {1} };
@@ -29,10 +30,10 @@ int cmd_main(int argc, const char **argv)
        two = lookup_unknown_object(two_oid.hash);
        ret = add_decoration(&n, one, &decoration_a);
        if (ret)
-               die("BUG: when adding a brand-new object, NULL should be returned");
+               BUG("when adding a brand-new object, NULL should be returned");
        ret = add_decoration(&n, two, NULL);
        if (ret)
-               die("BUG: when adding a brand-new object, NULL should be returned");
+               BUG("when adding a brand-new object, NULL should be returned");
 
        /*
         * When re-adding an already existing object, the old decoration is
@@ -40,10 +41,10 @@ int cmd_main(int argc, const char **argv)
         */
        ret = add_decoration(&n, one, NULL);
        if (ret != &decoration_a)
-               die("BUG: when readding an already existing object, existing decoration should be returned");
+               BUG("when readding an already existing object, existing decoration should be returned");
        ret = add_decoration(&n, two, &decoration_b);
        if (ret)
-               die("BUG: when readding an already existing object, existing decoration should be returned");
+               BUG("when readding an already existing object, existing decoration should be returned");
 
        /*
         * Lookup returns the added declarations, or NULL if the object was
@@ -51,14 +52,14 @@ int cmd_main(int argc, const char **argv)
         */
        ret = lookup_decoration(&n, one);
        if (ret)
-               die("BUG: lookup should return added declaration");
+               BUG("lookup should return added declaration");
        ret = lookup_decoration(&n, two);
        if (ret != &decoration_b)
-               die("BUG: lookup should return added declaration");
+               BUG("lookup should return added declaration");
        three = lookup_unknown_object(three_oid.hash);
        ret = lookup_decoration(&n, three);
        if (ret)
-               die("BUG: lookup for unknown object should return NULL");
+               BUG("lookup for unknown object should return NULL");
 
        /*
         * The user can also loop through all entries.
@@ -68,7 +69,7 @@ int cmd_main(int argc, const char **argv)
                        objects_noticed++;
        }
        if (objects_noticed != 2)
-               die("BUG: should have 2 objects");
+               BUG("should have 2 objects");
 
        return 0;
 }
index 8d11d22d98649900b6d558cc174e2af1dbff9948..99b8dc1e2d9cdc3a0e0f464fdeee0f94733d00d1 100644 (file)
@@ -4,9 +4,10 @@
  * Copyright (C) 2007 by Nicolas Pitre, licensed under the GPL version 2.
  */
 
+#include "test-tool.h"
 #include "git-compat-util.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__genrandom(int argc, const char **argv)
 {
        unsigned long count, next = 0;
        unsigned char *c;
index 9ae9281c071254019ccca3486b3a6762d9c0085f..23d2b172fe708f711a15613e906637cd948324ef 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "hashmap.h"
 #include "strbuf.h"
@@ -77,7 +78,7 @@ static unsigned int hash(unsigned int method, unsigned int i, const char *key)
 
 /*
  * Test performance of hashmap.[ch]
- * Usage: time echo "perfhashmap method rounds" | test-hashmap
+ * Usage: time echo "perfhashmap method rounds" | test-tool hashmap
  */
 static void perf_hashmap(unsigned int method, unsigned int rounds)
 {
@@ -144,7 +145,7 @@ static void perf_hashmap(unsigned int method, unsigned int rounds)
  *
  * perfhashmap method rounds -> test hashmap.[ch] performance
  */
-int cmd_main(int argc, const char **argv)
+int cmd__hashmap(int argc, const char **argv)
 {
        struct strbuf line = STRBUF_INIT;
        struct hashmap map;
index f569f6b7eff87227f82dbe6390fd31fb970a5fca..fcd10968cc10bdab8db146b8ba65080431e5ed24 100644 (file)
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__index_version(int argc, const char **argv)
 {
        struct cache_header hdr;
        int version;
index 297fb01d61eded5d83d02175199efcd217376738..b99a37080d935fa27df4e372e0e8cddd9fd08b3c 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "parse-options.h"
 
@@ -184,14 +185,14 @@ static void analyze_run(void)
        }
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__lazy_init_name_hash(int argc, const char **argv)
 {
        const char *usage[] = {
-               "test-lazy-init-name-hash -d (-s | -m)",
-               "test-lazy-init-name-hash -p [-c c]",
-               "test-lazy-init-name-hash -a a [--step s] [-c c]",
-               "test-lazy-init-name-hash (-s | -m) [-c c]",
-               "test-lazy-init-name-hash -s -m [-c c]",
+               "test-tool lazy-init-name-hash -d (-s | -m)",
+               "test-tool lazy-init-name-hash -p [-c c]",
+               "test-tool lazy-init-name-hash -a a [--step s] [-c c]",
+               "test-tool lazy-init-name-hash (-s | -m) [-c c]",
+               "test-tool lazy-init-name-hash -s -m [-c c]",
                NULL
        };
        struct option options[] = {
index 356d8edef1d25524abaae0f0fcb3bf072d229c30..96857f26ac8540cf22e74aed72bbd30bc8147f00 100644 (file)
@@ -1,7 +1,8 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "tree.h"
 
-int cmd_main(int ac, const char **av)
+int cmd__match_trees(int ac, const char **av)
 {
        struct object_id hash1, hash2, shifted;
        struct tree *one, *two;
index 335cf6b6264cdaf9563736fbcfa40e7a3006a432..c5cffaa4b73ff52b2f166231ceb4a77b24ee8cef 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "mergesort.h"
 
@@ -22,7 +23,7 @@ static int compare_strings(const void *a, const void *b)
        return strcmp(x->text, y->text);
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__mergesort(int argc, const char **argv)
 {
        struct line *line, *p = NULL, *lines = NULL;
        struct strbuf sb = STRBUF_INIT;
index 89d9b2f7bee05ff5c9fde31ba6798651ccee2947..229068894029338c52f5d0b9828c442658be67e5 100644 (file)
@@ -1,9 +1,10 @@
 /*
  * test-mktemp.c: code to exercise the creation of temporary files
  */
+#include "test-tool.h"
 #include "git-compat-util.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__mktemp(int argc, const char **argv)
 {
        if (argc != 2)
                usage("Expected 1 parameter defining the temporary file template");
index 06c09c6b886f843b2d3c6fdb8e00730afc7fe40b..8cb0d53840f3dc60d583fa1b72f95572d2148d11 100644 (file)
@@ -1,7 +1,8 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "thread-utils.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__online_cpus(int argc, const char **argv)
 {
        printf("%d\n", online_cpus());
        return 0;
index 8b3ce07860d4d5dfeca06041b811282a59ef40bb..e737a941d3bc1d58c768b2e2819d0759e17f83c2 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "string-list.h"
 #include "utf8.h"
@@ -269,7 +270,7 @@ static int protect_ntfs_hfs_benchmark(int argc, const char **argv)
        return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__path_utils(int argc, const char **argv)
 {
        if (argc == 3 && !strcmp(argv[1], "normalize_path_copy")) {
                char *buf = xmallocz(strlen(argv[2]));
diff --git a/t/helper/test-pkt-line.c b/t/helper/test-pkt-line.c
new file mode 100644 (file)
index 0000000..0f19e53
--- /dev/null
@@ -0,0 +1,64 @@
+#include "pkt-line.h"
+
+static void pack_line(const char *line)
+{
+       if (!strcmp(line, "0000") || !strcmp(line, "0000\n"))
+               packet_flush(1);
+       else if (!strcmp(line, "0001") || !strcmp(line, "0001\n"))
+               packet_delim(1);
+       else
+               packet_write_fmt(1, "%s", line);
+}
+
+static void pack(int argc, const char **argv)
+{
+       if (argc) { /* read from argv */
+               int i;
+               for (i = 0; i < argc; i++)
+                       pack_line(argv[i]);
+       } else { /* read from stdin */
+               char line[LARGE_PACKET_MAX];
+               while (fgets(line, sizeof(line), stdin)) {
+                       pack_line(line);
+               }
+       }
+}
+
+static void unpack(void)
+{
+       struct packet_reader reader;
+       packet_reader_init(&reader, 0, NULL, 0,
+                          PACKET_READ_GENTLE_ON_EOF |
+                          PACKET_READ_CHOMP_NEWLINE);
+
+       while (packet_reader_read(&reader) != PACKET_READ_EOF) {
+               switch (reader.status) {
+               case PACKET_READ_EOF:
+                       break;
+               case PACKET_READ_NORMAL:
+                       printf("%s\n", reader.line);
+                       break;
+               case PACKET_READ_FLUSH:
+                       printf("0000\n");
+                       break;
+               case PACKET_READ_DELIM:
+                       printf("0001\n");
+                       break;
+               }
+       }
+}
+
+int cmd_main(int argc, const char **argv)
+{
+       if (argc < 2)
+               die("too few arguments");
+
+       if (!strcmp(argv[1], "pack"))
+               pack(argc - 2, argv + 2);
+       else if (!strcmp(argv[1], "unpack"))
+               unpack();
+       else
+               die("invalid argument '%s'", argv[1]);
+
+       return 0;
+}
index ae58fff35972a09c08a47d2bc0abb67c96ba20eb..9807b649b14c0002bee6d10b200c27bb89a54812 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "prio-queue.h"
 
@@ -16,7 +17,7 @@ static void show(int *v)
        free(v);
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__prio_queue(int argc, const char **argv)
 {
        struct prio_queue pq = { intcmp };
 
index 48255eef31a1e83d9a2bbb01670ba089a11c91f8..d674c88ba092d60366a14eaeccc9f4bc6f32660c 100644 (file)
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__read_cache(int argc, const char **argv)
 {
        int i, cnt = 1;
        if (argc == 2)
index 7120634b04733bb8abe1f0622f0e1e9c8280b643..e9e0541276c50d1739b6d39f2c01ba8ecb782adc 100644 (file)
@@ -1,6 +1,9 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "refs.h"
 #include "worktree.h"
+#include "object-store.h"
+#include "repository.h"
 
 static const char *notnull(const char *arg, const char *name)
 {
@@ -21,7 +24,7 @@ static const char **get_store(const char **argv, struct ref_store **refs)
        if (!argv[0]) {
                die("ref store required");
        } else if (!strcmp(argv[0], "main")) {
-               *refs = get_main_ref_store();
+               *refs = get_main_ref_store(the_repository);
        } else if (skip_prefix(argv[0], "submodule:", &gitdir)) {
                struct strbuf sb = STRBUF_INIT;
                int ret;
@@ -274,7 +277,7 @@ static struct command commands[] = {
        { NULL, NULL }
 };
 
-int cmd_main(int argc, const char **argv)
+int cmd__ref_store(int argc, const char **argv)
 {
        struct ref_store *refs;
        const char *func;
index b5ea8a97c54e1737d91dec894c1cc02e1baf64e5..10284cc56fa9f69703aa69f242edef113d6a40de 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "gettext.h"
 
@@ -36,7 +37,7 @@ static int test_regex_bug(void)
        return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__regex(int argc, const char **argv)
 {
        const char *pat;
        const char *str;
@@ -47,8 +48,8 @@ int cmd_main(int argc, const char **argv)
        if (argc == 2 && !strcmp(argv[1], "--bug"))
                return test_regex_bug();
        else if (argc < 3)
-               usage("test-regex --bug\n"
-                     "test-regex <pattern> <string> [<options>]");
+               usage("test-tool regex --bug\n"
+                     "test-tool regex <pattern> <string> [<options>]");
 
        argv++;
        pat = *argv++;
index b8e6fe1d007449d30dd30ccd4319b26f151bbf23..4f8bc758213c47906d3dc1a4d4e02df2737c508d 100644 (file)
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include "test-tool.h"
 #include "cache.h"
 #include "commit.h"
 #include "diff.h"
@@ -45,7 +46,7 @@ static int run_revision_walk(void)
        return got_revision;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__revision_walking(int argc, const char **argv)
 {
        if (argc < 2)
                return 1;
index a701689bd5cb316afaba3b615c409d8a26cef88f..8579b1f7d13394b89dfff161b6f6558d498ac2f3 100644 (file)
@@ -8,6 +8,7 @@
  * published by the Free Software Foundation.
  */
 
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "run-command.h"
 #include "argv-array.h"
@@ -77,7 +78,7 @@ static int quote_stress_test(int argc, const char **argv)
                OPT_END()
        };
        const char * const usage[] = {
-               "test-run-command quote-stress-test <options>",
+               "test-tool run-command quote-stress-test <options>",
                NULL
        };
 
@@ -95,7 +96,7 @@ static int quote_stress_test(int argc, const char **argv)
                        argv_array_pushl(&args, "sh", "-c",
                                         "printf %s\\\\0 \"$@\"", "skip", NULL);
                else
-                       argv_array_pushl(&args, "test-run-command",
+                       argv_array_pushl(&args, "test-tool", "run-command",
                                         "quote-echo", NULL);
                arg_offset = args.argc;
 
@@ -177,7 +178,7 @@ static int quote_echo(int argc, const char **argv)
        return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__run_command(int argc, const char **argv)
 {
        struct child_process proc = CHILD_PROCESS_INIT;
        int jobs;
index d2a63bea4346fb76d38ba43508ee6e60599e41a9..393f1604ff954703a2a5e075fbda1e14d0827dc0 100644 (file)
@@ -1,12 +1,13 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "lockfile.h"
 #include "tree.h"
 #include "cache-tree.h"
 
-static struct lock_file index_lock;
-
-int cmd_main(int ac, const char **av)
+int cmd__scrap_cache_tree(int ac, const char **av)
 {
+       struct lock_file index_lock = LOCK_INIT;
+
        setup_git_directory();
        hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
        if (read_cache() < 0)
index edfd52d82aeca0bb9ba2c5b2ce18bc39d27e5a34..ad5e69f9d3b0e03442f0d23b3b559bbfc163ee7b 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "sha1-array.h"
 
@@ -7,7 +8,7 @@ static int print_oid(const struct object_id *oid, void *data)
        return 0;
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__sha1_array(int argc, const char **argv)
 {
        struct oid_array array = OID_ARRAY_INIT;
        struct strbuf line = STRBUF_INIT;
index a1c13f54eca0db7d11a5df134d565171d70b8cce..1ba0675c75f0d2dab281d054b577272cd45c39f9 100644 (file)
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int ac, const char **av)
+int cmd__sha1(int ac, const char **av)
 {
        git_SHA_CTX ctx;
        unsigned char sha1[20];
index 750b95a0a1c39b4d761b7f2f861f6df4c85ecb65..84594885c703887c3b09aceb51583b9895ac3b45 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 dd if=/dev/zero bs=1048576 count=100 2>/dev/null |
-/usr/bin/time t/helper/test-sha1 >/dev/null
+/usr/bin/time t/helper/test-tool sha1 >/dev/null
 
 while read expect cnt pfx
 do
@@ -11,7 +11,7 @@ do
                        test -z "$pfx" || echo "$pfx"
                        dd if=/dev/zero bs=1048576 count=$cnt 2>/dev/null |
                        perl -pe 'y/\000/g/'
-               } | ./t/helper/test-sha1 $cnt
+               } | ./t/helper/test-tool sha1 $cnt
        )
        if test "$expect" = "$actual"
        then
index b71edbd4429184b59b4bd1355d5cfb53970a1876..77ac5bc33f8eb635f78d8ba590c23bbbe4f29636 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "sigchain.h"
 
@@ -13,7 +14,7 @@ X(two)
 X(three)
 #undef X
 
-int cmd_main(int argc, const char **argv) {
+int cmd__sigchain(int argc, const char **argv) {
        sigchain_push(SIGTERM, one);
        sigchain_push(SIGTERM, two);
        sigchain_push(SIGTERM, three);
index e159c9a127f6854541ab497c8fd4b6efb9d4ea39..44e4a6d143e24cbd05b5d94404a5f5d4e732c880 100644 (file)
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__strcmp_offset(int argc, const char **argv)
 {
        int result;
        size_t offset;
index 829ec3d7d2f58b9538bb3bbab47213eddb9e62ec..2123dda85bf10033dcbf0d801028b3705e73a507 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "string-list.h"
 
@@ -41,7 +42,7 @@ static int prefix_cb(struct string_list_item *item, void *cb_data)
        return starts_with(item->string, prefix);
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__string_list(int argc, const char **argv)
 {
        if (argc == 5 && !strcmp(argv[1], "split")) {
                struct string_list list = STRING_LIST_INIT_DUP;
index f23db3b19a9911b554ca8eaf567cd0370d42af6e..e2692746dfdb0e6a5c3b1c748124059bcbdd5fae 100644 (file)
@@ -1,3 +1,4 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "config.h"
 #include "submodule-config.h"
@@ -10,7 +11,7 @@ static void die_usage(int argc, const char **argv, const char *msg)
        exit(1);
 }
 
-int cmd_main(int argc, const char **argv)
+int cmd__submodule_config(int argc, const char **argv)
 {
        const char **arg = argv;
        int my_argc = argc;
@@ -48,9 +49,11 @@ int cmd_main(int argc, const char **argv)
                        die_usage(argc, argv, "Commit not found.");
 
                if (lookup_name) {
-                       submodule = submodule_from_name(&commit_oid, path_or_name);
+                       submodule = submodule_from_name(the_repository,
+                                                       &commit_oid, path_or_name);
                } else
-                       submodule = submodule_from_path(&commit_oid, path_or_name);
+                       submodule = submodule_from_path(the_repository,
+                                                       &commit_oid, path_or_name);
                if (!submodule)
                        die_usage(argc, argv, "Submodule not found.");
 
@@ -64,7 +67,7 @@ int cmd_main(int argc, const char **argv)
                arg += 2;
        }
 
-       submodule_free();
+       submodule_free(the_repository);
 
        return 0;
 }
index 30c5765bfc3590421c21bc2350eed882752de3a0..92b69de635296d32d38d1f7d7589d5f8b6fbc296 100644 (file)
@@ -1,7 +1,8 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "run-command.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__subprocess(int argc, const char **argv)
 {
        struct child_process cp = CHILD_PROCESS_INIT;
        int nogit = 0;
diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c
new file mode 100644 (file)
index 0000000..805a45d
--- /dev/null
@@ -0,0 +1,63 @@
+#include "git-compat-util.h"
+#include "test-tool.h"
+
+struct test_cmd {
+       const char *name;
+       int (*fn)(int argc, const char **argv);
+};
+
+static struct test_cmd cmds[] = {
+       { "chmtime", cmd__chmtime },
+       { "config", cmd__config },
+       { "ctype", cmd__ctype },
+       { "date", cmd__date },
+       { "delta", cmd__delta },
+       { "drop-caches", cmd__drop_caches },
+       { "dump-cache-tree", cmd__dump_cache_tree },
+       { "dump-split-index", cmd__dump_split_index },
+       { "example-decorate", cmd__example_decorate },
+       { "genrandom", cmd__genrandom },
+       { "hashmap", cmd__hashmap },
+       { "index-version", cmd__index_version },
+       { "lazy-init-name-hash", cmd__lazy_init_name_hash },
+       { "match-trees", cmd__match_trees },
+       { "mergesort", cmd__mergesort },
+       { "mktemp", cmd__mktemp },
+       { "online-cpus", cmd__online_cpus },
+       { "path-utils", cmd__path_utils },
+       { "prio-queue", cmd__prio_queue },
+       { "read-cache", cmd__read_cache },
+       { "ref-store", cmd__ref_store },
+       { "regex", cmd__regex },
+       { "revision-walking", cmd__revision_walking },
+       { "run-command", cmd__run_command },
+       { "scrap-cache-tree", cmd__scrap_cache_tree },
+       { "sha1-array", cmd__sha1_array },
+       { "sha1", cmd__sha1 },
+       { "sigchain", cmd__sigchain },
+       { "strcmp-offset", cmd__strcmp_offset },
+       { "string-list", cmd__string_list },
+       { "submodule-config", cmd__submodule_config },
+       { "subprocess", cmd__subprocess },
+       { "urlmatch-normalization", cmd__urlmatch_normalization },
+       { "wildmatch", cmd__wildmatch },
+       { "write-cache", cmd__write_cache },
+};
+
+int cmd_main(int argc, const char **argv)
+{
+       int i;
+
+       BUG_exit_code = 99;
+       if (argc < 2)
+               die("I need a test name!");
+
+       for (i = 0; i < ARRAY_SIZE(cmds); i++) {
+               if (!strcmp(cmds[i].name, argv[1])) {
+                       argv++;
+                       argc--;
+                       return cmds[i].fn(argc, argv);
+               }
+       }
+       die("There is no test named '%s'", argv[1]);
+}
diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h
new file mode 100644 (file)
index 0000000..7116ddf
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __TEST_TOOL_H__
+#define __TEST_TOOL_H__
+
+int cmd__chmtime(int argc, const char **argv);
+int cmd__config(int argc, const char **argv);
+int cmd__ctype(int argc, const char **argv);
+int cmd__date(int argc, const char **argv);
+int cmd__delta(int argc, const char **argv);
+int cmd__drop_caches(int argc, const char **argv);
+int cmd__dump_cache_tree(int argc, const char **argv);
+int cmd__dump_split_index(int argc, const char **argv);
+int cmd__example_decorate(int argc, const char **argv);
+int cmd__genrandom(int argc, const char **argv);
+int cmd__hashmap(int argc, const char **argv);
+int cmd__index_version(int argc, const char **argv);
+int cmd__lazy_init_name_hash(int argc, const char **argv);
+int cmd__match_trees(int argc, const char **argv);
+int cmd__mergesort(int argc, const char **argv);
+int cmd__mktemp(int argc, const char **argv);
+int cmd__online_cpus(int argc, const char **argv);
+int cmd__path_utils(int argc, const char **argv);
+int cmd__prio_queue(int argc, const char **argv);
+int cmd__read_cache(int argc, const char **argv);
+int cmd__ref_store(int argc, const char **argv);
+int cmd__regex(int argc, const char **argv);
+int cmd__revision_walking(int argc, const char **argv);
+int cmd__run_command(int argc, const char **argv);
+int cmd__scrap_cache_tree(int argc, const char **argv);
+int cmd__sha1_array(int argc, const char **argv);
+int cmd__sha1(int argc, const char **argv);
+int cmd__sigchain(int argc, const char **argv);
+int cmd__strcmp_offset(int argc, const char **argv);
+int cmd__string_list(int argc, const char **argv);
+int cmd__submodule_config(int argc, const char **argv);
+int cmd__subprocess(int argc, const char **argv);
+int cmd__urlmatch_normalization(int argc, const char **argv);
+int cmd__wildmatch(int argc, const char **argv);
+int cmd__write_cache(int argc, const char **argv);
+
+#endif
index 49b6e836be257c0689601bf17138439cff0d61a0..8f4d67e646953c5b094b55ec8112f6ba3b9b9024 100644 (file)
@@ -1,9 +1,10 @@
+#include "test-tool.h"
 #include "git-compat-util.h"
 #include "urlmatch.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__urlmatch_normalization(int argc, const char **argv)
 {
-       const char usage[] = "test-urlmatch-normalization [-p | -l] <url1> | <url1> <url2>";
+       const char usage[] = "test-tool urlmatch-normalization [-p | -l] <url1> | <url1> <url2>";
        char *url1, *url2;
        int opt_p = 0, opt_l = 0;
 
index 66d33dfcfd1a0b3fa6b94a029aab9117a2511224..2c103d1824cfc7f035aea4a6453c9706f9b4491e 100644 (file)
@@ -1,6 +1,7 @@
+#include "test-tool.h"
 #include "cache.h"
 
-int cmd_main(int argc, const char **argv)
+int cmd__wildmatch(int argc, const char **argv)
 {
        int i;
        for (i = 2; i < argc; i++) {
index b7ee0396692b6143e852af16695dd5800c0044be..8837717d36a77c04346279b570e1a0a4506fe838 100644 (file)
@@ -1,22 +1,19 @@
+#include "test-tool.h"
 #include "cache.h"
 #include "lockfile.h"
 
-static struct lock_file index_lock;
-
-int cmd_main(int argc, const char **argv)
+int cmd__write_cache(int argc, const char **argv)
 {
-       int i, cnt = 1, lockfd;
+       struct lock_file index_lock = LOCK_INIT;
+       int i, cnt = 1;
        if (argc == 2)
                cnt = strtol(argv[1], NULL, 0);
        setup_git_directory();
        read_cache();
        for (i = 0; i < cnt; i++) {
-               lockfd = hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
-               if (0 <= lockfd) {
-                       write_locked_index(&the_index, &index_lock, COMMIT_LOCK);
-               } else {
-                       rollback_lock_file(&index_lock);
-               }
+               hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR);
+               if (write_locked_index(&the_index, &index_lock, COMMIT_LOCK))
+                       die("unable to write index file");
        }
 
        return 0;
index 8b4dbf22d2d140bef7ca0e106a389cb0ca1d4681..8d1e408bb58f5e097f242d5c1fd2c7bb036deb6e 100644 (file)
@@ -59,9 +59,11 @@ int main(int argc, char **argv)
 }
 EOF
 
-       cat >expect <<\EOF
+       file1=$(git rev-parse --short $(git hash-object file1))
+       file2=$(git rev-parse --short $(git hash-object file2))
+       cat >expect <<EOF
 diff --git a/file1 b/file2
-index 6faa5a3..e3af329 100644
+index $file1..$file2 100644
 --- a/file1
 +++ b/file2
 @@ -1,26 +1,25 @@
@@ -136,9 +138,11 @@ e
 f
 EOF
 
-       cat >expect <<\EOF
+       uniq1=$(git rev-parse --short $(git hash-object uniq1))
+       uniq2=$(git rev-parse --short $(git hash-object uniq2))
+       cat >expect <<EOF
 diff --git a/uniq1 b/uniq2
-index b414108..0fdf397 100644
+index $uniq1..$uniq2 100644
 --- a/uniq1
 +++ b/uniq2
 @@ -1,6 +1,6 @@
index 54fd5a6ca02757f77004d0f8babfcc6d616162c0..c27599474cf2f272b53e2e76997e5e38af0fe647 100644 (file)
@@ -39,7 +39,7 @@ native_path () {
        then
                path=$(cygpath --windows "$path")
        else
-               path=$(test-path-utils real_path "$path")
+               path=$(test-tool path-utils real_path "$path")
        fi &&
        echo "$path"
 }
index 4c1f81f1678d83ab8b9ee7704d400bdd47ea70f7..a8130f9119d629462efb6b52f91890c0352e4e85 100644 (file)
@@ -49,7 +49,7 @@ rawsvnrepo="$svnrepo"
 svnrepo="file://$svnrepo"
 
 poke() {
-       test-chmtime +1 "$1"
+       test-tool chmtime +1 "$1"
 }
 
 # We need this, because we should pass empty configuration directory to
index 4674899b30871f55894750b61b66020f0d16a646..c4d907a450a7863ff0fe32fe9aed7ef5c100dd3e 100644 (file)
@@ -97,7 +97,7 @@ pack_obj () {
 
 # Compute and append pack trailer to "$1"
 pack_trailer () {
-       test-sha1 -b <"$1" >trailer.tmp &&
+       test-tool sha1 -b <"$1" >trailer.tmp &&
        cat trailer.tmp >>"$1" &&
        rm -f trailer.tmp
 }
index 3f2d873fec9ed9e98b787cd708cd9e8e816e7573..b0ed4767e320e200c592e979dce0fa1e4cfd6ede 100644 (file)
@@ -4,11 +4,11 @@ mkdir -p .git/refs/tags
 
 >sed.script
 
-# Answer the sha1 has associated with the tag. The tag must exist in .git/refs/tags
+# Answer the sha1 has associated with the tag. The tag must exist under refs/tags
 tag () {
        _tag=$1
-       test -f ".git/refs/tags/$_tag" || error "tag: \"$_tag\" does not exist"
-       cat ".git/refs/tags/$_tag"
+       git rev-parse --verify "refs/tags/$_tag" ||
+       error "tag: \"$_tag\" does not exist"
 }
 
 # Generate a commit using the text specified to make it unique and the tree
index 821cf1498b78bbb5b43b2bda32bbcc88d580c31b..bc865160e7e3370f9462beda9d8b3866e3c2111b 100755 (executable)
@@ -4,6 +4,7 @@ use lib '../../perl/build/lib';
 use strict;
 use warnings;
 use JSON;
+use Getopt::Long;
 use Git;
 
 sub get_times {
@@ -36,34 +37,34 @@ sub format_times {
        return $out;
 }
 
+sub usage {
+       print <<EOT;
+./aggregate.perl [options] [--] [<dir_or_rev>...] [--] [<test_script>...] >
+
+  Options:
+    --codespeed          * Format output for Codespeed
+    --reponame    <str>  * Send given reponame to codespeed
+    --sort-by     <str>  * Sort output (only "regression" criteria is supported)
+    --subsection  <str>  * Use results from given subsection
+
+EOT
+       exit(1);
+}
+
 my (@dirs, %dirnames, %dirabbrevs, %prefixes, @tests,
-    $codespeed, $subsection, $reponame);
+    $codespeed, $sortby, $subsection, $reponame);
+
+Getopt::Long::Configure qw/ require_order /;
+
+my $rc = GetOptions("codespeed"     => \$codespeed,
+                   "reponame=s"    => \$reponame,
+                   "sort-by=s"     => \$sortby,
+                   "subsection=s"  => \$subsection);
+usage() unless $rc;
+
 while (scalar @ARGV) {
        my $arg = $ARGV[0];
        my $dir;
-       if ($arg eq "--codespeed") {
-               $codespeed = 1;
-               shift @ARGV;
-               next;
-       }
-       if ($arg eq "--subsection") {
-               shift @ARGV;
-               $subsection = $ARGV[0];
-               shift @ARGV;
-               if (! $subsection) {
-                       die "empty subsection";
-               }
-               next;
-       }
-       if ($arg eq "--reponame") {
-               shift @ARGV;
-               $reponame = $ARGV[0];
-               shift @ARGV;
-               if (! $reponame) {
-                       die "empty reponame";
-               }
-               next;
-       }
        last if -f $arg or $arg eq "--";
        if (! -d $arg) {
                my $rev = Git::command_oneline(qw(rev-parse --verify), $arg);
@@ -147,6 +148,11 @@ sub have_slash {
        return 0;
 }
 
+sub display_dir {
+       my ($d) = @_;
+       return exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d};
+}
+
 sub print_default_results {
        my %descrs;
        my $descrlen = 4; # "Test"
@@ -168,8 +174,7 @@ sub print_default_results {
        my %times;
        my @colwidth = ((0)x@dirs);
        for my $i (0..$#dirs) {
-               my $d = $dirs[$i];
-               my $w = length (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
+               my $w = length display_dir($dirs[$i]);
                $colwidth[$i] = $w if $w > $colwidth[$i];
        }
        for my $t (@subtests) {
@@ -188,8 +193,7 @@ sub print_default_results {
 
        printf "%-${descrlen}s", "Test";
        for my $i (0..$#dirs) {
-               my $d = $dirs[$i];
-               printf "   %-$colwidth[$i]s", (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
+               printf "   %-$colwidth[$i]s", display_dir($dirs[$i]);
        }
        print "\n";
        print "-"x$totalwidth, "\n";
@@ -206,6 +210,50 @@ sub print_default_results {
        }
 }
 
+sub print_sorted_results {
+       my ($sortby) = @_;
+
+       if ($sortby ne "regression") {
+               print "Only 'regression' is supported as '--sort-by' argument\n";
+               usage();
+       }
+
+       my @evolutions;
+       for my $t (@subtests) {
+               my ($prevr, $prevu, $prevs, $prevrev);
+               for my $i (0..$#dirs) {
+                       my $d = $dirs[$i];
+                       my ($r, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.times");
+                       if ($i > 0 and defined $r and defined $prevr and $prevr > 0) {
+                               my $percent = 100.0 * ($r - $prevr) / $prevr;
+                               push @evolutions, { "percent"  => $percent,
+                                                   "test"     => $t,
+                                                   "prevrev"  => $prevrev,
+                                                   "rev"      => $d,
+                                                   "prevr"    => $prevr,
+                                                   "r"        => $r,
+                                                   "prevu"    => $prevu,
+                                                   "u"        => $u,
+                                                   "prevs"    => $prevs,
+                                                   "s"        => $s};
+                       }
+                       ($prevr, $prevu, $prevs, $prevrev) = ($r, $u, $s, $d);
+               }
+       }
+
+       my @sorted_evolutions = sort { $b->{percent} <=> $a->{percent} } @evolutions;
+
+       for my $e (@sorted_evolutions) {
+               printf "%+.1f%%", $e->{percent};
+               print " " . $e->{test};
+               print " " . format_times($e->{prevr}, $e->{prevu}, $e->{prevs});
+               print " " . format_times($e->{r}, $e->{u}, $e->{s});
+               print " " . display_dir($e->{prevrev});
+               print " " . display_dir($e->{rev});
+               print "\n";
+       }
+}
+
 sub print_codespeed_results {
        my ($subsection) = @_;
 
@@ -260,6 +308,8 @@ binmode STDOUT, ":utf8" or die "PANIC on binmode: $!";
 
 if ($codespeed) {
        print_codespeed_results($subsection);
+} elsif (defined $sortby) {
+       print_sorted_results($sortby);
 } else {
        print_default_results();
 }
diff --git a/t/perf/bisect_regression b/t/perf/bisect_regression
new file mode 100755 (executable)
index 0000000..a94d995
--- /dev/null
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+# Read a line coming from `./aggregate.perl --sort-by regression ...`
+# and automatically bisect to find the commit responsible for the
+# performance regression.
+#
+# Lines from `./aggregate.perl --sort-by regression ...` look like:
+#
+# +100.0% p7821-grep-engines-fixed.1 0.04(0.10+0.03) 0.08(0.11+0.08) v2.14.3 v2.15.1
+# +33.3% p7820-grep-engines.1 0.03(0.08+0.02) 0.04(0.08+0.02) v2.14.3 v2.15.1
+#
+
+die () {
+       echo >&2 "error: $*"
+       exit 1
+}
+
+while [ $# -gt 0 ]; do
+       arg="$1"
+       case "$arg" in
+       --help)
+               echo "usage: $0 [--config file] [--subsection subsection]"
+               exit 0
+               ;;
+       --config)
+               shift
+               GIT_PERF_CONFIG_FILE=$(cd "$(dirname "$1")"; pwd)/$(basename "$1")
+               export GIT_PERF_CONFIG_FILE
+               shift ;;
+       --subsection)
+               shift
+               GIT_PERF_SUBSECTION="$1"
+               export GIT_PERF_SUBSECTION
+               shift ;;
+       --*)
+               die "unrecognised option: '$arg'" ;;
+       *)
+               die "unknown argument '$arg'"
+               ;;
+       esac
+done
+
+read -r regression subtest oldtime newtime oldrev newrev
+
+test_script=$(echo "$subtest" | sed -e 's/\(.*\)\.[0-9]*$/\1.sh/')
+test_number=$(echo "$subtest" | sed -e 's/.*\.\([0-9]*\)$/\1/')
+
+# oldtime and newtime are decimal number, not integers
+
+oldtime=$(echo "$oldtime" | sed -e 's/^\([0-9]\+\.[0-9]\+\).*$/\1/')
+newtime=$(echo "$newtime" | sed -e 's/^\([0-9]\+\.[0-9]\+\).*$/\1/')
+
+test $(echo "$newtime" "$oldtime" | awk '{ print ($1 > $2) }') = 1 ||
+       die "New time '$newtime' shoud be greater than old time '$oldtime'"
+
+tmpdir=$(mktemp -d -t bisect_regression_XXXXXX) || die "Failed to create temp directory"
+echo "$oldtime" >"$tmpdir/oldtime" || die "Failed to write to '$tmpdir/oldtime'"
+echo "$newtime" >"$tmpdir/newtime" || die "Failed to write to '$tmpdir/newtime'"
+
+# Bisecting must be performed from the top level directory (even with --no-checkout)
+(
+       toplevel_dir=$(git rev-parse --show-toplevel) || die "Failed to find top level directory"
+       cd "$toplevel_dir" || die "Failed to cd into top level directory '$toplevel_dir'"
+
+       git bisect start --no-checkout "$newrev" "$oldrev" || die "Failed to start bisecting"
+
+       git bisect run t/perf/bisect_run_script "$test_script" "$test_number" "$tmpdir"
+       res="$?"
+
+       git bisect reset
+
+       exit "$res"
+)
diff --git a/t/perf/bisect_run_script b/t/perf/bisect_run_script
new file mode 100755 (executable)
index 0000000..3ebaf15
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+script="$1"
+test_number="$2"
+info_dir="$3"
+
+# This aborts the bisection immediately
+die () {
+       echo >&2 "error: $*"
+       exit 255
+}
+
+bisect_head=$(git rev-parse --verify BISECT_HEAD) || die "Failed to find BISECT_HEAD ref"
+
+script_number=$(echo "$script" | sed -e "s/^p\([0-9]*\).*\$/\1/") || die "Failed to get script number for '$script'"
+
+oldtime=$(cat "$info_dir/oldtime") || die "Failed to access '$info_dir/oldtime'"
+newtime=$(cat "$info_dir/newtime") || die "Failed to access '$info_dir/newtime'"
+
+cd t/perf || die "Failed to cd into 't/perf'"
+
+result_file="$info_dir/perf_${script_number}_${bisect_head}_results.txt"
+
+GIT_PERF_DIRS_OR_REVS="$bisect_head"
+export GIT_PERF_DIRS_OR_REVS
+
+# Don't use codespeed
+GIT_PERF_CODESPEED_OUTPUT=
+GIT_PERF_SEND_TO_CODESPEED=
+export GIT_PERF_CODESPEED_OUTPUT
+export GIT_PERF_SEND_TO_CODESPEED
+
+./run "$script" >"$result_file" 2>&1 || die "Failed to run perf test '$script'"
+
+rtime=$(sed -n "s/^$script_number\.$test_number:.*\([0-9]\+\.[0-9]\+\)(.*).*\$/\1/p" "$result_file")
+
+echo "newtime: $newtime"
+echo "rtime: $rtime"
+echo "oldtime: $oldtime"
+
+# Compare ($newtime - $rtime) with ($rtime - $oldtime)
+# Times are decimal number, not integers
+
+if test $(echo "$newtime" "$rtime" "$oldtime" | awk '{ print ($1 - $2 > $2 - $3) }') = 1
+then
+       # Current commit is considered "good/old"
+       echo "$rtime" >"$info_dir/oldtime"
+       exit 0
+else
+       # Current commit is considered "bad/new"
+       echo "$rtime" >"$info_dir/newtime"
+       exit 1
+fi
index 9180ae9343a03824653e087aaa766b9d33e50a94..cdd105a5945239850a12479ff1138a5428e3b6d6 100755 (executable)
@@ -8,7 +8,7 @@ test_perf_default_repo
 
 count=1000
 test_perf "read_cache/discard_cache $count times" "
-       test-read-cache $count
+       test-tool read-cache $count
 "
 
 test_done
index 8de5a98cfc6c513bb35cd8355f3e831ab3a8007d..1afc08fe7f1990cdf7143f0dfd3cfaa66628ca73 100755 (executable)
@@ -7,8 +7,8 @@ test_perf_large_repo
 test_checkout_worktree
 
 test_expect_success 'verify both methods build the same hashmaps' '
-       test-lazy-init-name-hash --dump --single >out.single &&
-       if test-lazy-init-name-hash --dump --multi >out.multi
+       test-tool lazy-init-name-hash --dump --single >out.single &&
+       if test-tool lazy-init-name-hash --dump --multi >out.multi
        then
                test_set_prereq REPO_BIG_ENOUGH_FOR_MULTI &&
                sort <out.single >sorted.single &&
@@ -46,11 +46,11 @@ test_expect_success 'calibrate' '
 '
 
 test_perf "single-threaded, $desc" "
-       test-lazy-init-name-hash --single --count=$count
+       test-tool lazy-init-name-hash --single --count=$count
 "
 
 test_perf REPO_BIG_ENOUGH_FOR_MULTI "multi-threaded, $desc" "
-       test-lazy-init-name-hash --multi --count=$count
+       test-tool lazy-init-name-hash --multi --count=$count
 "
 
 test_done
index 261fe92fd93aaf65101dfe4d1b87741453985cbe..09595264f09fa4b1dc28b3e5d2a3d6482d998bcc 100755 (executable)
@@ -23,7 +23,7 @@ test_expect_success "setup repo" '
 
 count=3
 test_perf "write_locked_index $count times ($nr_files files)" "
-       test-write-cache $count
+       test-tool write-cache $count
 "
 
 test_done
index 7c9a35a646a6406e5c284a65748863a93098c2af..6e924f5fa3f900b4b82a55f282e810572a62f20b 100755 (executable)
@@ -16,7 +16,7 @@ test_perf 'sort(1)' '
 '
 
 test_perf 'string_list_sort()' '
-       test-string-list sort <unsorted >actual
+       test-tool string-list sort <unsorted >actual
 '
 
 test_expect_success 'string_list_sort() sorts like sort(1)' '
index 65e145c02d9eafc5a43d56c1fb30fef7be63d704..def7ecdbc786c6472e5b7909a97650a1034cecb2 100755 (executable)
@@ -118,7 +118,7 @@ test_expect_success "setup for fsmonitor" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -126,7 +126,7 @@ test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -134,7 +134,7 @@ test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status -uall (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -148,7 +148,7 @@ test_expect_success "setup without fsmonitor" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -156,7 +156,7 @@ test_perf "status (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
@@ -164,7 +164,7 @@ test_perf "status -uno (fsmonitor=$INTEGRATION_SCRIPT)" '
 '
 
 if test -n "$GIT_PERF_7519_DROP_CACHE"; then
-       test-drop-caches
+       test-tool drop-caches
 fi
 
 test_perf "status -uall (fsmonitor=$INTEGRATION_SCRIPT)" '
index 213da5d6b9437b7db7f3e5b824afea1df465d934..9aaa733c770fb97157e273b6c6d1efd38f9a630a 100755 (executable)
@@ -1,21 +1,34 @@
 #!/bin/sh
 
-case "$1" in
+die () {
+       echo >&2 "error: $*"
+       exit 1
+}
+
+while [ $# -gt 0 ]; do
+       arg="$1"
+       case "$arg" in
+       --)
+               break ;;
        --help)
-               echo "usage: $0 [--config file] [other_git_tree...] [--] [test_scripts]"
-               exit 0
-               ;;
+               echo "usage: $0 [--config file] [--subsection subsec] [other_git_tree...] [--] [test_scripts]"
+               exit 0 ;;
        --config)
                shift
                GIT_PERF_CONFIG_FILE=$(cd "$(dirname "$1")"; pwd)/$(basename "$1")
                export GIT_PERF_CONFIG_FILE
                shift ;;
-esac
-
-die () {
-       echo >&2 "error: $*"
-       exit 1
-}
+       --subsection)
+               shift
+               GIT_PERF_SUBSECTION="$1"
+               export GIT_PERF_SUBSECTION
+               shift ;;
+       --*)
+               die "unrecognised option: '$arg'" ;;
+       *)
+               break ;;
+       esac
+done
 
 run_one_dir () {
        if test $# -eq 0; then
@@ -172,9 +185,32 @@ get_subsections "perf" >test-results/run_subsections.names
 
 if test $(wc -l <test-results/run_subsections.names) -eq 0
 then
+       if test -n "$GIT_PERF_SUBSECTION"
+       then
+               if test -n "$GIT_PERF_CONFIG_FILE"
+               then
+                       die "no subsections are defined in config file '$GIT_PERF_CONFIG_FILE'"
+               else
+                       die "subsection '$GIT_PERF_SUBSECTION' defined without a config file"
+               fi
+       fi
        (
                run_subsection "$@"
        )
+elif test -n "$GIT_PERF_SUBSECTION"
+then
+       egrep "^$GIT_PERF_SUBSECTION\$" test-results/run_subsections.names >/dev/null ||
+               die "subsection '$GIT_PERF_SUBSECTION' not found in '$GIT_PERF_CONFIG_FILE'"
+
+       egrep "^$GIT_PERF_SUBSECTION\$" test-results/run_subsections.names | while read -r subsec
+       do
+               (
+                       GIT_PERF_SUBSECTION="$subsec"
+                       export GIT_PERF_SUBSECTION
+                       echo "======== Run for subsection '$GIT_PERF_SUBSECTION' ========"
+                       run_subsection "$@"
+               )
+       done
 else
        while read -r subsec
        do
index 7fd87dd5444040ad7273be51c29a56dea738a861..af61d083b452c7973a2a703ef35fb57b76af84da 100755 (executable)
@@ -839,7 +839,7 @@ test_expect_success 'writing tree out with git write-tree' '
 '
 
 # we know the shape and contents of the tree and know the object ID for it.
-test_expect_success 'validate object ID of a known tree' '
+test_expect_success SHA1 'validate object ID of a known tree' '
        test "$tree" = 7bb943559a305bdd6bdee2cef6e5df2413c3d30a
     '
 
@@ -882,7 +882,7 @@ test_expect_success 'showing stage with git ls-files --stage' '
        git ls-files --stage >current
 '
 
-test_expect_success 'validate git ls-files output for a known tree' '
+test_expect_success SHA1 'validate git ls-files output for a known tree' '
        cat >expected <<-\EOF &&
        100644 f87290f8eb2cbbea7857214459a0739927eab154 0       path0
        120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0       path0sym
@@ -900,7 +900,7 @@ test_expect_success 'writing tree out with git write-tree' '
        tree=$(git write-tree)
 '
 
-test_expect_success 'validate object ID for a known tree' '
+test_expect_success SHA1 'validate object ID for a known tree' '
        test "$tree" = 087704a96baf1c2d1c869a8b084481e121c88b5b
 '
 
@@ -908,7 +908,7 @@ test_expect_success 'showing tree with git ls-tree' '
     git ls-tree $tree >current
 '
 
-test_expect_success 'git ls-tree output for a known tree' '
+test_expect_success SHA1 'git ls-tree output for a known tree' '
        cat >expected <<-\EOF &&
        100644 blob f87290f8eb2cbbea7857214459a0739927eab154    path0
        120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01    path0sym
@@ -924,7 +924,7 @@ test_expect_success 'showing tree with git ls-tree -r' '
        git ls-tree -r $tree >current
 '
 
-test_expect_success 'git ls-tree -r output for a known tree' '
+test_expect_success SHA1 'git ls-tree -r output for a known tree' '
        cat >expected <<-\EOF &&
        100644 blob f87290f8eb2cbbea7857214459a0739927eab154    path0
        120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01    path0sym
@@ -943,7 +943,7 @@ test_expect_success 'showing tree with git ls-tree -r -t' '
        git ls-tree -r -t $tree >current
 '
 
-test_expect_success 'git ls-tree -r output for a known tree' '
+test_expect_success SHA1 'git ls-tree -r output for a known tree' '
        cat >expected <<-\EOF &&
        100644 blob f87290f8eb2cbbea7857214459a0739927eab154    path0
        120000 blob 15a98433ae33114b085f3eb3bb03b832b3180a01    path0sym
@@ -964,7 +964,7 @@ test_expect_success 'writing partial tree out with git write-tree --prefix' '
        ptree=$(git write-tree --prefix=path3)
 '
 
-test_expect_success 'validate object ID for a known tree' '
+test_expect_success SHA1 'validate object ID for a known tree' '
        test "$ptree" = 21ae8269cacbe57ae09138dcc3a2887f904d02b3
 '
 
@@ -972,7 +972,7 @@ test_expect_success 'writing partial tree out with git write-tree --prefix' '
        ptree=$(git write-tree --prefix=path3/subp3)
 '
 
-test_expect_success 'validate object ID for a known tree' '
+test_expect_success SHA1 'validate object ID for a known tree' '
        test "$ptree" = 3c5e5399f3a333eddecce7a9b9465b63f65f51e2
 '
 
@@ -1006,7 +1006,7 @@ test_expect_success 'git read-tree followed by write-tree should be idempotent'
        test "$newtree" = "$tree"
 '
 
-test_expect_success 'validate git diff-files output for a know cache/work tree state' '
+test_expect_success SHA1 'validate git diff-files output for a know cache/work tree state' '
        cat >expected <<\EOF &&
 :100644 100644 f87290f8eb2cbbea7857214459a0739927eab154 0000000000000000000000000000000000000000 M     path0
 :120000 120000 15a98433ae33114b085f3eb3bb03b832b3180a01 0000000000000000000000000000000000000000 M     path0sym
@@ -1033,21 +1033,21 @@ test_expect_success 'no diff after checkout and git update-index --refresh' '
 ################################################################
 P=087704a96baf1c2d1c869a8b084481e121c88b5b
 
-test_expect_success 'git commit-tree records the correct tree in a commit' '
+test_expect_success SHA1 'git commit-tree records the correct tree in a commit' '
        commit0=$(echo NO | git commit-tree $P) &&
        tree=$(git show --pretty=raw $commit0 |
                 sed -n -e "s/^tree //p" -e "/^author /q") &&
        test "z$tree" = "z$P"
 '
 
-test_expect_success 'git commit-tree records the correct parent in a commit' '
+test_expect_success SHA1 'git commit-tree records the correct parent in a commit' '
        commit1=$(echo NO | git commit-tree $P -p $commit0) &&
        parent=$(git show --pretty=raw $commit1 |
                sed -n -e "s/^parent //p" -e "/^author /q") &&
        test "z$commit0" = "z$parent"
 '
 
-test_expect_success 'git commit-tree omits duplicated parent in a commit' '
+test_expect_success SHA1 'git commit-tree omits duplicated parent in a commit' '
        commit2=$(echo NO | git commit-tree $P -p $commit0 -p $commit0) &&
             parent=$(git show --pretty=raw $commit2 |
                sed -n -e "s/^parent //p" -e "/^author /q" |
index 46042f1f1338f628d5256f0e932a4037e98b34ab..4c214bd11c48859f0c4e64dbbe2d783e744eb1d1 100755 (executable)
@@ -10,7 +10,7 @@ one
 EOF
 
 test_expect_success 'sigchain works' '
-       { test-sigchain >actual; ret=$?; } &&
+       { test-tool sigchain >actual; ret=$?; } &&
        {
                # Signal death by raise() on Windows acts like exit(3),
                # regardless of the signal number. So we must allow that
@@ -24,7 +24,7 @@ test_expect_success 'sigchain works' '
 test_expect_success !MINGW 'signals are propagated using shell convention' '
        # we use exec here to avoid any sub-shell interpretation
        # of the exit code
-       git config alias.sigterm "!exec test-sigchain" &&
+       git config alias.sigterm "!exec test-tool sigchain" &&
        test_expect_code 143 git sigterm
 '
 
@@ -36,7 +36,7 @@ large_git () {
 }
 
 test_expect_success 'create blob' '
-       test-genrandom foo 16384 >file &&
+       test-tool genrandom foo 16384 >file &&
        git add file
 '
 
index 7ac9466d5055e02179467fa9e41004bbc89df6dc..64ff86df8eb02aa635af1bad0b6d1f31578f222a 100755 (executable)
@@ -10,7 +10,7 @@ check_relative() {
        t=$(($TEST_DATE_NOW - $1))
        echo "$t -> $2" >expect
        test_expect_${3:-success} "relative date ($2)" "
-       test-date relative $t >actual &&
+       test-tool date relative $t >actual &&
        test_i18ncmp expect actual
        "
 }
@@ -35,7 +35,7 @@ check_show () {
        zone=$5
        test_expect_success $prereqs "show date ($format:$time)" '
                echo "$time -> $expect" >expect &&
-               TZ=${zone:-$TZ} test-date show:"$format" "$time" >actual &&
+               TZ=${zone:-$TZ} test-tool date show:"$format" "$time" >actual &&
                test_cmp expect actual
        '
 }
@@ -71,7 +71,7 @@ check_show iso-local "$FUTURE" "2152-06-19 22:24:56 +0000" TIME_IS_64BIT,TIME_T_
 check_parse() {
        echo "$1 -> $2" >expect
        test_expect_${4:-success} "parse date ($1${3:+ TZ=$3})" "
-       TZ=${3:-$TZ} test-date parse '$1' >actual &&
+       TZ=${3:-$TZ} test-tool date parse '$1' >actual &&
        test_cmp expect actual
        "
 }
@@ -92,7 +92,7 @@ check_parse '2008-02-14 20:30:45' '2008-02-14 20:30:45 -0500' EST5
 check_approxidate() {
        echo "$1 -> $2 +0000" >expect
        test_expect_${3:-success} "parse approxidate ($1)" "
-       test-date approxidate '$1' >actual &&
+       test-tool date approxidate '$1' >actual &&
        test_cmp expect actual
        "
 }
index 94045c3fad18d94e0e83acf757594cede066134b..e56dfce6680298c133bc2b2de12d9492fda66b7a 100755 (executable)
@@ -17,7 +17,7 @@ cat >expect <<'EOF'
 10
 EOF
 test_expect_success 'basic ordering' '
-       test-prio-queue 2 6 3 10 9 5 7 4 5 8 1 dump >actual &&
+       test-tool prio-queue 2 6 3 10 9 5 7 4 5 8 1 dump >actual &&
        test_cmp expect actual
 '
 
@@ -30,7 +30,7 @@ cat >expect <<'EOF'
 6
 EOF
 test_expect_success 'mixed put and get' '
-       test-prio-queue 6 2 4 get 5 3 get get 1 dump >actual &&
+       test-tool prio-queue 6 2 4 get 5 3 get get 1 dump >actual &&
        test_cmp expect actual
 '
 
@@ -43,7 +43,7 @@ NULL
 NULL
 EOF
 test_expect_success 'notice empty queue' '
-       test-prio-queue 1 2 get get get 1 2 get get get >actual &&
+       test-tool prio-queue 1 2 get get get 1 2 get get get >actual &&
        test_cmp expect actual
 '
 
index 9c217d948c14dfd75f73e27a0911fd194eb11bce..3f1f505e8937f391666a1b7e6d9b972a5f146974 100755 (executable)
@@ -4,7 +4,7 @@ test_description='test hashmap and string hash functions'
 . ./test-lib.sh
 
 test_hashmap() {
-       echo "$1" | test-hashmap $3 > actual &&
+       echo "$1" | test-tool hashmap $3 > actual &&
        echo "$2" > expect &&
        test_cmp expect actual
 }
@@ -232,7 +232,7 @@ test_expect_success 'grow / shrink' '
        echo value40 >> expect &&
        echo size >> in &&
        echo 64 39 >> expect &&
-       cat in | test-hashmap > out &&
+       cat in | test-tool hashmap > out &&
        test_cmp expect out
 
 '
index 487b92a5de3238821ed3d8aadadb1f07d35e0609..bc27df7f383d14fb5fea6266591469c32e562c4e 100755 (executable)
@@ -25,6 +25,15 @@ test_expect_success "setup" '
        EOF
 '
 
+# make sure to exercise these code paths, the output is a bit tricky
+# to verify
+test_expect_success 'basic help commands' '
+       git help >/dev/null &&
+       git help -a >/dev/null &&
+       git help -g >/dev/null &&
+       git help -av >/dev/null
+'
+
 test_expect_success "works for commands and guides by default" '
        configure_help &&
        git help status &&
@@ -49,8 +58,23 @@ test_expect_success "--help does not work for guides" "
        test_i18ncmp expect actual
 "
 
+test_expect_success 'git help' '
+       git help >help.output &&
+       test_i18ngrep "^   clone  " help.output &&
+       test_i18ngrep "^   add    " help.output &&
+       test_i18ngrep "^   log    " help.output &&
+       test_i18ngrep "^   commit " help.output &&
+       test_i18ngrep "^   fetch  " help.output
+'
+test_expect_success 'git help -g' '
+       git help -g >help.output &&
+       test_i18ngrep "^   attributes " help.output &&
+       test_i18ngrep "^   everyday   " help.output &&
+       test_i18ngrep "^   tutorial   " help.output
+'
+
 test_expect_success 'generate builtin list' '
-       git --list-builtins >builtins
+       git --list-cmds=builtins >builtins
 '
 
 while read builtin
index 6d655cb161b2ed39eda97bb4acb54d1cf74a826d..419f31a8f7d4cb20041f054d25ddb25c7d43e3fb 100755 (executable)
@@ -11,7 +11,7 @@ then
 fi
 
 test_expect_success 'test-sha1 detects shattered pdf' '
-       test_must_fail test-sha1 <"$TEST_DATA/shattered-1.pdf" 2>err &&
+       test_must_fail test-tool sha1 <"$TEST_DATA/shattered-1.pdf" 2>err &&
        test_i18ngrep collision err &&
        grep 38762cf7f55934b34d179ae6a4c80cadccbb7f0a err
 '
index 46f8e583c37da7d03d715ea5cb1a4ee5bbe0ca28..9479a4aaabc1a4187fc702f864642ac493508bb9 100755 (executable)
@@ -19,7 +19,7 @@ write_script rot13-filter.pl "$PERL_PATH" \
 generate_random_characters () {
        LEN=$1
        NAME=$2
-       test-genrandom some-seed $LEN |
+       test-tool genrandom some-seed $LEN |
                perl -pe "s/./chr((ord($&) % 26) + ord('a'))/sge" >"$TEST_ROOT/$NAME"
 }
 
@@ -267,7 +267,7 @@ test_expect_success 'filtering large input to small output should use little mem
 '
 
 test_expect_success 'filter that does not read is fine' '
-       test-genrandom foo $((128 * 1024 + 1)) >big &&
+       test-tool genrandom foo $((128 * 1024 + 1)) >big &&
        echo "big filter=epipe" >.gitattributes &&
        test_config filter.epipe.clean "echo xyzzy" &&
        git add big &&
diff --git a/t/t0028-working-tree-encoding.sh b/t/t0028-working-tree-encoding.sh
new file mode 100755 (executable)
index 0000000..12b8eb9
--- /dev/null
@@ -0,0 +1,245 @@
+#!/bin/sh
+
+test_description='working-tree-encoding conversion via gitattributes'
+
+. ./test-lib.sh
+
+GIT_TRACE_WORKING_TREE_ENCODING=1 && export GIT_TRACE_WORKING_TREE_ENCODING
+
+test_expect_success 'setup test files' '
+       git config core.eol lf &&
+
+       text="hallo there!\ncan you read me?" &&
+       echo "*.utf16 text working-tree-encoding=utf-16" >.gitattributes &&
+       printf "$text" >test.utf8.raw &&
+       printf "$text" | iconv -f UTF-8 -t UTF-16 >test.utf16.raw &&
+       printf "$text" | iconv -f UTF-8 -t UTF-32 >test.utf32.raw &&
+
+       # Line ending tests
+       printf "one\ntwo\nthree\n" >lf.utf8.raw &&
+       printf "one\r\ntwo\r\nthree\r\n" >crlf.utf8.raw &&
+
+       # BOM tests
+       printf "\0a\0b\0c"                         >nobom.utf16be.raw &&
+       printf "a\0b\0c\0"                         >nobom.utf16le.raw &&
+       printf "\376\777\0a\0b\0c"                 >bebom.utf16be.raw &&
+       printf "\777\376a\0b\0c\0"                 >lebom.utf16le.raw &&
+       printf "\0\0\0a\0\0\0b\0\0\0c"             >nobom.utf32be.raw &&
+       printf "a\0\0\0b\0\0\0c\0\0\0"             >nobom.utf32le.raw &&
+       printf "\0\0\376\777\0\0\0a\0\0\0b\0\0\0c" >bebom.utf32be.raw &&
+       printf "\777\376\0\0a\0\0\0b\0\0\0c\0\0\0" >lebom.utf32le.raw &&
+
+       # Add only UTF-16 file, we will add the UTF-32 file later
+       cp test.utf16.raw test.utf16 &&
+       cp test.utf32.raw test.utf32 &&
+       git add .gitattributes test.utf16 &&
+       git commit -m initial
+'
+
+test_expect_success 'ensure UTF-8 is stored in Git' '
+       test_when_finished "rm -f test.utf16.git" &&
+
+       git cat-file -p :test.utf16 >test.utf16.git &&
+       test_cmp_bin test.utf8.raw test.utf16.git
+'
+
+test_expect_success 're-encode to UTF-16 on checkout' '
+       test_when_finished "rm -f test.utf16.raw" &&
+
+       rm test.utf16 &&
+       git checkout test.utf16 &&
+       test_cmp_bin test.utf16.raw test.utf16
+'
+
+test_expect_success 'check $GIT_DIR/info/attributes support' '
+       test_when_finished "rm -f test.utf32.git" &&
+       test_when_finished "git reset --hard HEAD" &&
+
+       echo "*.utf32 text working-tree-encoding=utf-32" >.git/info/attributes &&
+       git add test.utf32 &&
+
+       git cat-file -p :test.utf32 >test.utf32.git &&
+       test_cmp_bin test.utf8.raw test.utf32.git
+'
+
+for i in 16 32
+do
+       test_expect_success "check prohibited UTF-${i} BOM" '
+               test_when_finished "git reset --hard HEAD" &&
+
+               echo "*.utf${i}be text working-tree-encoding=utf-${i}be" >>.gitattributes &&
+               echo "*.utf${i}le text working-tree-encoding=utf-${i}LE" >>.gitattributes &&
+
+               # Here we add a UTF-16 (resp. UTF-32) files with BOM (big/little-endian)
+               # but we tell Git to treat it as UTF-16BE/UTF-16LE (resp. UTF-32).
+               # In these cases the BOM is prohibited.
+               cp bebom.utf${i}be.raw bebom.utf${i}be &&
+               test_must_fail git add bebom.utf${i}be 2>err.out &&
+               test_i18ngrep "fatal: BOM is prohibited .* utf-${i}be" err.out &&
+               test_i18ngrep "use UTF-${i} as working-tree-encoding" err.out &&
+
+               cp lebom.utf${i}le.raw lebom.utf${i}be &&
+               test_must_fail git add lebom.utf${i}be 2>err.out &&
+               test_i18ngrep "fatal: BOM is prohibited .* utf-${i}be" err.out &&
+               test_i18ngrep "use UTF-${i} as working-tree-encoding" err.out &&
+
+               cp bebom.utf${i}be.raw bebom.utf${i}le &&
+               test_must_fail git add bebom.utf${i}le 2>err.out &&
+               test_i18ngrep "fatal: BOM is prohibited .* utf-${i}LE" err.out &&
+               test_i18ngrep "use UTF-${i} as working-tree-encoding" err.out &&
+
+               cp lebom.utf${i}le.raw lebom.utf${i}le &&
+               test_must_fail git add lebom.utf${i}le 2>err.out &&
+               test_i18ngrep "fatal: BOM is prohibited .* utf-${i}LE" err.out &&
+               test_i18ngrep "use UTF-${i} as working-tree-encoding" err.out
+       '
+
+       test_expect_success "check required UTF-${i} BOM" '
+               test_when_finished "git reset --hard HEAD" &&
+
+               echo "*.utf${i} text working-tree-encoding=utf-${i}" >>.gitattributes &&
+
+               cp nobom.utf${i}be.raw nobom.utf${i} &&
+               test_must_fail git add nobom.utf${i} 2>err.out &&
+               test_i18ngrep "fatal: BOM is required .* utf-${i}" err.out &&
+               test_i18ngrep "use UTF-${i}BE or UTF-${i}LE" err.out &&
+
+               cp nobom.utf${i}le.raw nobom.utf${i} &&
+               test_must_fail git add nobom.utf${i} 2>err.out &&
+               test_i18ngrep "fatal: BOM is required .* utf-${i}" err.out &&
+               test_i18ngrep "use UTF-${i}BE or UTF-${i}LE" err.out
+       '
+
+       test_expect_success "eol conversion for UTF-${i} encoded files on checkout" '
+               test_when_finished "rm -f crlf.utf${i}.raw lf.utf${i}.raw" &&
+               test_when_finished "git reset --hard HEAD^" &&
+
+               cat lf.utf8.raw | iconv -f UTF-8 -t UTF-${i} >lf.utf${i}.raw &&
+               cat crlf.utf8.raw | iconv -f UTF-8 -t UTF-${i} >crlf.utf${i}.raw &&
+               cp crlf.utf${i}.raw eol.utf${i} &&
+
+               cat >expectIndexLF <<-EOF &&
+                       i/lf    w/-text attr/text               eol.utf${i}
+               EOF
+
+               git add eol.utf${i} &&
+               git commit -m eol &&
+
+               # UTF-${i} with CRLF (Windows line endings)
+               rm eol.utf${i} &&
+               git -c core.eol=crlf checkout eol.utf${i} &&
+               test_cmp_bin crlf.utf${i}.raw eol.utf${i} &&
+
+               # Although the file has CRLF in the working tree,
+               # ensure LF in the index
+               git ls-files --eol eol.utf${i} >actual &&
+               test_cmp expectIndexLF actual &&
+
+               # UTF-${i} with LF (Unix line endings)
+               rm eol.utf${i} &&
+               git -c core.eol=lf checkout eol.utf${i} &&
+               test_cmp_bin lf.utf${i}.raw eol.utf${i} &&
+
+               # The file LF in the working tree, ensure LF in the index
+               git ls-files --eol eol.utf${i} >actual &&
+               test_cmp expectIndexLF actual
+       '
+done
+
+test_expect_success 'check unsupported encodings' '
+       test_when_finished "git reset --hard HEAD" &&
+
+       echo "*.set text working-tree-encoding" >.gitattributes &&
+       printf "set" >t.set &&
+       test_must_fail git add t.set 2>err.out &&
+       test_i18ngrep "true/false are no valid working-tree-encodings" err.out &&
+
+       echo "*.unset text -working-tree-encoding" >.gitattributes &&
+       printf "unset" >t.unset &&
+       git add t.unset &&
+
+       echo "*.empty text working-tree-encoding=" >.gitattributes &&
+       printf "empty" >t.empty &&
+       git add t.empty &&
+
+       echo "*.garbage text working-tree-encoding=garbage" >.gitattributes &&
+       printf "garbage" >t.garbage &&
+       test_must_fail git add t.garbage 2>err.out &&
+       test_i18ngrep "failed to encode" err.out
+'
+
+test_expect_success 'error if encoding round trip is not the same during refresh' '
+       BEFORE_STATE=$(git rev-parse HEAD) &&
+       test_when_finished "git reset --hard $BEFORE_STATE" &&
+
+       # Add and commit a UTF-16 file but skip the "working-tree-encoding"
+       # filter. Consequently, the in-repo representation is UTF-16 and not
+       # UTF-8. This simulates a Git version that has no working tree encoding
+       # support.
+       echo "*.utf16le text working-tree-encoding=utf-16le" >.gitattributes &&
+       echo "hallo" >nonsense.utf16le &&
+       TEST_HASH=$(git hash-object --no-filters -w nonsense.utf16le) &&
+       git update-index --add --cacheinfo 100644 $TEST_HASH nonsense.utf16le &&
+       COMMIT=$(git commit-tree -p $(git rev-parse HEAD) -m "plain commit" $(git write-tree)) &&
+       git update-ref refs/heads/master $COMMIT &&
+
+       test_must_fail git checkout HEAD^ 2>err.out &&
+       test_i18ngrep "error: .* overwritten by checkout:" err.out
+'
+
+test_expect_success 'error if encoding garbage is already in Git' '
+       BEFORE_STATE=$(git rev-parse HEAD) &&
+       test_when_finished "git reset --hard $BEFORE_STATE" &&
+
+       # Skip the UTF-16 filter for the added file
+       # This simulates a Git version that has no checkoutEncoding support
+       cp nobom.utf16be.raw nonsense.utf16 &&
+       TEST_HASH=$(git hash-object --no-filters -w nonsense.utf16) &&
+       git update-index --add --cacheinfo 100644 $TEST_HASH nonsense.utf16 &&
+       COMMIT=$(git commit-tree -p $(git rev-parse HEAD) -m "plain commit" $(git write-tree)) &&
+       git update-ref refs/heads/master $COMMIT &&
+
+       git diff 2>err.out &&
+       test_i18ngrep "error: BOM is required" err.out
+'
+
+test_expect_success 'check roundtrip encoding' '
+       test_when_finished "rm -f roundtrip.shift roundtrip.utf16" &&
+       test_when_finished "git reset --hard HEAD" &&
+
+       text="hallo there!\nroundtrip test here!" &&
+       printf "$text" | iconv -f UTF-8 -t SHIFT-JIS >roundtrip.shift &&
+       printf "$text" | iconv -f UTF-8 -t UTF-16 >roundtrip.utf16 &&
+       echo "*.shift text working-tree-encoding=SHIFT-JIS" >>.gitattributes &&
+
+       # SHIFT-JIS encoded files are round-trip checked by default...
+       GIT_TRACE=1 git add .gitattributes roundtrip.shift 2>&1 |
+               grep "Checking roundtrip encoding for SHIFT-JIS" &&
+       git reset &&
+
+       # ... unless we overwrite the Git config!
+       ! GIT_TRACE=1 git -c core.checkRoundtripEncoding=garbage \
+               add .gitattributes roundtrip.shift 2>&1 |
+               grep "Checking roundtrip encoding for SHIFT-JIS" &&
+       git reset &&
+
+       # UTF-16 encoded files should not be round-trip checked by default...
+       ! GIT_TRACE=1 git add roundtrip.utf16 2>&1 |
+               grep "Checking roundtrip encoding for UTF-16" &&
+       git reset &&
+
+       # ... unless we tell Git to check it!
+       GIT_TRACE=1 git -c core.checkRoundtripEncoding="UTF-16, UTF-32" \
+               add roundtrip.utf16 2>&1 |
+               grep "Checking roundtrip encoding for utf-16" &&
+       git reset &&
+
+       # ... unless we tell Git to check it!
+       # (here we also check that the casing of the encoding is irrelevant)
+       GIT_TRACE=1 git -c core.checkRoundtripEncoding="UTF-32, utf-16" \
+               add roundtrip.utf16 2>&1 |
+               grep "Checking roundtrip encoding for utf-16" &&
+       git reset
+'
+
+test_done
index 0c2fc81d7b0fa401db58c41cd2fed4469e80b058..04d474c84fd69121c686f5ca5adc40ce081f0e9d 100755 (executable)
@@ -291,7 +291,7 @@ test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' '
 test_expect_success 'OPT_CALLBACK() and callback errors work' '
        test_must_fail test-parse-options --no-length >output 2>output.err &&
        test_i18ncmp expect output &&
-       test_i18ncmp expect.err output.err
+       test_must_be_empty output.err
 '
 
 cat >expect <<\EOF
diff --git a/t/t0041-usage.sh b/t/t0041-usage.sh
new file mode 100755 (executable)
index 0000000..5b927b7
--- /dev/null
@@ -0,0 +1,107 @@
+#!/bin/sh
+
+test_description='Test commands behavior when given invalid argument value'
+
+. ./test-lib.sh
+
+test_expect_success 'setup ' '
+       test_commit "v1.0"
+'
+
+test_expect_success 'tag --contains <existent_tag>' '
+       git tag --contains "v1.0" >actual 2>actual.err &&
+       grep "v1.0" actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'tag --contains <inexistent_tag>' '
+       test_must_fail git tag --contains "notag" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'tag --no-contains <existent_tag>' '
+       git tag --no-contains "v1.0" >actual 2>actual.err  &&
+       test_line_count = 0 actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'tag --no-contains <inexistent_tag>' '
+       test_must_fail git tag --no-contains "notag" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'tag usage error' '
+       test_must_fail git tag --noopt >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "usage" actual.err
+'
+
+test_expect_success 'branch --contains <existent_commit>' '
+       git branch --contains "master" >actual 2>actual.err &&
+       test_i18ngrep "master" actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'branch --contains <inexistent_commit>' '
+       test_must_fail git branch --no-contains "nocommit" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'branch --no-contains <existent_commit>' '
+       git branch --no-contains "master" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'branch --no-contains <inexistent_commit>' '
+       test_must_fail git branch --no-contains "nocommit" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'branch usage error' '
+       test_must_fail git branch --noopt >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "usage" actual.err
+'
+
+test_expect_success 'for-each-ref --contains <existent_object>' '
+       git for-each-ref --contains "master" >actual 2>actual.err &&
+       test_line_count = 2 actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'for-each-ref --contains <inexistent_object>' '
+       test_must_fail git for-each-ref --no-contains "noobject" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'for-each-ref --no-contains <existent_object>' '
+       git for-each-ref --no-contains "master" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_line_count = 0 actual.err
+'
+
+test_expect_success 'for-each-ref --no-contains <inexistent_object>' '
+       test_must_fail git for-each-ref --no-contains "noobject" >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "error" actual.err &&
+       test_i18ngrep ! "usage" actual.err
+'
+
+test_expect_success 'for-each-ref usage error' '
+       test_must_fail git for-each-ref --noopt >actual 2>actual.err &&
+       test_line_count = 0 actual &&
+       test_i18ngrep "usage" actual.err
+'
+
+test_done
index 40db3e1e1adad57721087ee69af35224aa6eaad4..f7ab3d5d2f916824bff09994f9b2a2201a24a7ba 100755 (executable)
@@ -8,15 +8,15 @@ test_description='Test various path utilities'
 . ./test-lib.sh
 
 norm_path() {
-       expected=$(test-path-utils print_path "$2")
+       expected=$(test-tool path-utils print_path "$2")
        test_expect_success $3 "normalize path: $1 => $2" \
-       "test \"\$(test-path-utils normalize_path_copy '$1')\" = '$expected'"
+       "test \"\$(test-tool path-utils normalize_path_copy '$1')\" = '$expected'"
 }
 
 relative_path() {
-       expected=$(test-path-utils print_path "$3")
+       expected=$(test-tool path-utils print_path "$3")
        test_expect_success $4 "relative path: $1 $2 => $3" \
-       "test \"\$(test-path-utils relative_path '$1' '$2')\" = '$expected'"
+       "test \"\$(test-tool path-utils relative_path '$1' '$2')\" = '$expected'"
 }
 
 test_submodule_relative_url() {
@@ -37,7 +37,7 @@ test_git_path() {
 # On Windows, we are using MSYS's bash, which mangles the paths.
 # Absolute paths are anchored at the MSYS installation directory,
 # which means that the path / accounts for this many characters:
-rootoff=$(test-path-utils normalize_path_copy / | wc -c)
+rootoff=$(test-tool path-utils normalize_path_copy / | wc -c)
 # Account for the trailing LF:
 if test $rootoff = 2; then
        rootoff=        # we are on Unix
@@ -46,7 +46,7 @@ else
        # In MSYS2, the root directory "/" is translated into a Windows
        # directory *with* trailing slash. Let's test for that and adjust
        # our expected longest ancestor length accordingly.
-       case "$(test-path-utils print_path /)" in
+       case "$(test-tool path-utils print_path /)" in
        */) rootslash=1;;
        *) rootslash=0;;
        esac
@@ -61,7 +61,7 @@ ancestor() {
                expected=$(($expected+$rootoff))
        fi
        test_expect_success "longest ancestor: $1 $2 => $expected" \
-       "actual=\$(test-path-utils longest_ancestor_length '$1' '$2') &&
+       "actual=\$(test-tool path-utils longest_ancestor_length '$1' '$2') &&
         test \"\$actual\" = '$expected'"
 }
 
@@ -77,8 +77,8 @@ case $(uname -s) in
        ;;
 esac
 
-test_expect_success basename 'test-path-utils basename'
-test_expect_success dirname 'test-path-utils dirname'
+test_expect_success basename 'test-tool path-utils basename'
+test_expect_success dirname 'test-tool path-utils dirname'
 
 norm_path "" ""
 norm_path . ""
@@ -157,57 +157,57 @@ ancestor /foo/bar /foo:/bar 4
 ancestor /foo/bar /bar -1
 
 test_expect_success 'strip_path_suffix' '
-       test c:/msysgit = $(test-path-utils strip_path_suffix \
+       test c:/msysgit = $(test-tool path-utils strip_path_suffix \
                c:/msysgit/libexec//git-core libexec/git-core)
 '
 
 test_expect_success 'absolute path rejects the empty string' '
-       test_must_fail test-path-utils absolute_path ""
+       test_must_fail test-tool path-utils absolute_path ""
 '
 
 test_expect_success MINGW '<drive-letter>:\\abc is an absolute path' '
        for letter in : \" C Z 1 ä
        do
                path=$letter:\\abc &&
-               absolute="$(test-path-utils absolute_path "$path")" &&
+               absolute="$(test-tool path-utils absolute_path "$path")" &&
                test "$path" = "$absolute" || return 1
        done
 '
 
 test_expect_success 'real path rejects the empty string' '
-       test_must_fail test-path-utils real_path ""
+       test_must_fail test-tool path-utils real_path ""
 '
 
 test_expect_success POSIX 'real path works on absolute paths 1' '
        nopath="hopefully-absent-path" &&
-       test "/" = "$(test-path-utils real_path "/")" &&
-       test "/$nopath" = "$(test-path-utils real_path "/$nopath")"
+       test "/" = "$(test-tool path-utils real_path "/")" &&
+       test "/$nopath" = "$(test-tool path-utils real_path "/$nopath")"
 '
 
 test_expect_success 'real path works on absolute paths 2' '
        nopath="hopefully-absent-path" &&
        # Find an existing top-level directory for the remaining tests:
        d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-       test "$d" = "$(test-path-utils real_path "$d")" &&
-       test "$d/$nopath" = "$(test-path-utils real_path "$d/$nopath")"
+       test "$d" = "$(test-tool path-utils real_path "$d")" &&
+       test "$d/$nopath" = "$(test-tool path-utils real_path "$d/$nopath")"
 '
 
 test_expect_success POSIX 'real path removes extra leading slashes' '
        nopath="hopefully-absent-path" &&
-       test "/" = "$(test-path-utils real_path "///")" &&
-       test "/$nopath" = "$(test-path-utils real_path "///$nopath")" &&
+       test "/" = "$(test-tool path-utils real_path "///")" &&
+       test "/$nopath" = "$(test-tool path-utils real_path "///$nopath")" &&
        # Find an existing top-level directory for the remaining tests:
        d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-       test "$d" = "$(test-path-utils real_path "//$d")" &&
-       test "$d/$nopath" = "$(test-path-utils real_path "//$d/$nopath")"
+       test "$d" = "$(test-tool path-utils real_path "//$d")" &&
+       test "$d/$nopath" = "$(test-tool path-utils real_path "//$d/$nopath")"
 '
 
 test_expect_success 'real path removes other extra slashes' '
        nopath="hopefully-absent-path" &&
        # Find an existing top-level directory for the remaining tests:
        d=$(pwd -P | sed -e "s|^\([^/]*/[^/]*\)/.*|\1|") &&
-       test "$d" = "$(test-path-utils real_path "$d///")" &&
-       test "$d/$nopath" = "$(test-path-utils real_path "$d///$nopath")"
+       test "$d" = "$(test-tool path-utils real_path "$d///")" &&
+       test "$d/$nopath" = "$(test-tool path-utils real_path "$d///$nopath")"
 '
 
 test_expect_success SYMLINKS 'real path works on symlinks' '
@@ -218,35 +218,35 @@ test_expect_success SYMLINKS 'real path works on symlinks' '
        mkdir third &&
        dir="$(cd .git; pwd -P)" &&
        dir2=third/../second/other/.git &&
-       test "$dir" = "$(test-path-utils real_path $dir2)" &&
+       test "$dir" = "$(test-tool path-utils real_path $dir2)" &&
        file="$dir"/index &&
-       test "$file" = "$(test-path-utils real_path $dir2/index)" &&
+       test "$file" = "$(test-tool path-utils real_path $dir2/index)" &&
        basename=blub &&
-       test "$dir/$basename" = "$(cd .git && test-path-utils real_path "$basename")" &&
+       test "$dir/$basename" = "$(cd .git && test-tool path-utils real_path "$basename")" &&
        ln -s ../first/file .git/syml &&
        sym="$(cd first; pwd -P)"/file &&
-       test "$sym" = "$(test-path-utils real_path "$dir2/syml")"
+       test "$sym" = "$(test-tool path-utils real_path "$dir2/syml")"
 '
 
 test_expect_success SYMLINKS 'prefix_path works with absolute paths to work tree symlinks' '
        ln -s target symlink &&
-       test "$(test-path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink"
+       test "$(test-tool path-utils prefix_path prefix "$(pwd)/symlink")" = "symlink"
 '
 
 test_expect_success 'prefix_path works with only absolute path to work tree' '
        echo "" >expected &&
-       test-path-utils prefix_path prefix "$(pwd)" >actual &&
+       test-tool path-utils prefix_path prefix "$(pwd)" >actual &&
        test_cmp expected actual
 '
 
 test_expect_success 'prefix_path rejects absolute path to dir with same beginning as work tree' '
-       test_must_fail test-path-utils prefix_path prefix "$(pwd)a"
+       test_must_fail test-tool path-utils prefix_path prefix "$(pwd)a"
 '
 
 test_expect_success SYMLINKS 'prefix_path works with absolute path to a symlink to work tree having  same beginning as work tree' '
        git init repo &&
        ln -s repo repolink &&
-       test "a" = "$(cd repo && test-path-utils prefix_path prefix "$(pwd)/../repolink/a")"
+       test "a" = "$(cd repo && test-tool path-utils prefix_path prefix "$(pwd)/../repolink/a")"
 '
 
 relative_path /foo/a/b/c/      /foo/a/b/       c/
@@ -359,7 +359,7 @@ test_submodule_relative_url "(null)" "user@host:path/to/repo" "../subrepo" "user
 test_submodule_relative_url "(null)" "user@host:repo" "../subrepo" "user@host:subrepo"
 
 test_expect_success 'match .gitmodules' '
-       test-path-utils is_dotgitmodules \
+       test-tool path-utils is_dotgitmodules \
                .gitmodules \
                \
                .git${u200c}modules \
@@ -450,7 +450,7 @@ test_expect_success 'match .gitmodules' '
 '
 
 test_expect_success MINGW 'is_valid_path() on Windows' '
-       test-path-utils is_valid_path \
+       test-tool path-utils is_valid_path \
                win32 \
                "win32 x" \
                ../hello.txt \
index 24c92b6cd7b1c54eb6541a81abd7e5812b3b99b0..c887ed5b45e824d281343196c8781cbb6e85abed 100755 (executable)
@@ -14,13 +14,13 @@ EOF
 >empty
 
 test_expect_success 'start_command reports ENOENT' '
-       test-run-command start-command-ENOENT ./does-not-exist
+       test-tool run-command start-command-ENOENT ./does-not-exist
 '
 
 test_expect_success 'run_command can run a command' '
        cat hello-script >hello.sh &&
        chmod +x hello.sh &&
-       test-run-command run-command ./hello.sh >actual 2>err &&
+       test-tool run-command run-command ./hello.sh >actual 2>err &&
 
        test_cmp hello-script actual &&
        test_cmp empty err
@@ -31,7 +31,7 @@ test_expect_success !MINGW 'run_command can run a script without a #! line' '
        cat hello-script
        EOF
        chmod +x hello &&
-       test-run-command run-command ./hello >actual 2>err &&
+       test-tool run-command run-command ./hello >actual 2>err &&
 
        test_cmp hello-script actual &&
        test_cmp empty err
@@ -45,7 +45,7 @@ test_expect_success 'run_command does not try to execute a directory' '
        EOF
 
        PATH=$PWD/bin1:$PWD/bin2:$PATH \
-               test-run-command run-command greet >actual 2>err &&
+               test-tool run-command run-command greet >actual 2>err &&
        test_cmp bin2/greet actual &&
        test_cmp empty err
 '
@@ -62,7 +62,7 @@ test_expect_success POSIXPERM 'run_command passes over non-executable file' '
        EOF
 
        PATH=$PWD/bin1:$PWD/bin2:$PATH \
-               test-run-command run-command greet >actual 2>err &&
+               test-tool run-command run-command greet >actual 2>err &&
        test_cmp bin2/greet actual &&
        test_cmp empty err
 '
@@ -70,7 +70,7 @@ test_expect_success POSIXPERM 'run_command passes over non-executable file' '
 test_expect_success POSIXPERM 'run_command reports EACCES' '
        cat hello-script >hello.sh &&
        chmod -x hello.sh &&
-       test_must_fail test-run-command run-command ./hello.sh 2>err &&
+       test_must_fail test-tool run-command run-command ./hello.sh 2>err &&
 
        grep "fatal: cannot exec.*hello.sh" err
 '
@@ -104,17 +104,17 @@ World
 EOF
 
 test_expect_success 'run_command runs in parallel with more jobs available than tasks' '
-       test-run-command run-command-parallel 5 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+       test-tool run-command run-command-parallel 5 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'run_command runs in parallel with as many jobs as tasks' '
-       test-run-command run-command-parallel 4 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+       test-tool run-command run-command-parallel 4 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'run_command runs in parallel with more tasks than jobs available' '
-       test-run-command run-command-parallel 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+       test-tool run-command run-command-parallel 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
        test_cmp expect actual
 '
 
@@ -128,7 +128,7 @@ asking for a quick stop
 EOF
 
 test_expect_success 'run_command is asked to abort gracefully' '
-       test-run-command run-command-abort 3 false 2>actual &&
+       test-tool run-command run-command-abort 3 false 2>actual &&
        test_cmp expect actual
 '
 
@@ -137,15 +137,15 @@ no further jobs available
 EOF
 
 test_expect_success 'run_command outputs ' '
-       test-run-command run-command-no-jobs 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
+       test-tool run-command run-command-no-jobs 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual &&
        test_cmp expect actual
 '
 
 test_trace () {
        expect="$1"
        shift
-       GIT_TRACE=1 test-run-command "$@" run-command true 2>&1 >/dev/null | \
-               sed 's/.* run_command: //' >actual &&
+       GIT_TRACE=1 test-tool run-command "$@" run-command true 2>&1 >/dev/null | \
+               sed -e 's/.* run_command: //' -e '/trace: .*/d' >actual &&
        echo "$expect true" >expect &&
        test_cmp expect actual
 }
index 113c728e676679f8e8e8eb0fce433a84bbee8050..8e215867b8c197dedef32c569e1d1f632d22b631 100755 (executable)
@@ -26,7 +26,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'revision walking can be done twice' '
-       test-revision-walking run-twice >run_twice_actual &&
+       test-tool revision-walking run-twice >run_twice_actual &&
        test_cmp run_twice_expected run_twice_actual
 '
 
index dbfc05ebdc3990bf4ea5b0163afb4c6a9e698fa7..c6ee9f66b11d55f312ee673106ddf295c39bb50d 100755 (executable)
@@ -10,9 +10,9 @@ test_description='Test string list functionality'
 test_split () {
        cat >expected &&
        test_expect_success "split $1 at $2, max $3" "
-               test-string-list split '$1' '$2' '$3' >actual &&
+               test-tool string-list split '$1' '$2' '$3' >actual &&
                test_cmp expected actual &&
-               test-string-list split_in_place '$1' '$2' '$3' >actual &&
+               test-tool string-list split_in_place '$1' '$2' '$3' >actual &&
                test_cmp expected actual
        "
 }
@@ -61,31 +61,31 @@ test_split ":" ":" "-1" <<EOF
 EOF
 
 test_expect_success "test filter_string_list" '
-       test "x-" = "x$(test-string-list filter - y)" &&
-       test "x-" = "x$(test-string-list filter no y)" &&
-       test yes = "$(test-string-list filter yes y)" &&
-       test yes = "$(test-string-list filter no:yes y)" &&
-       test yes = "$(test-string-list filter yes:no y)" &&
-       test y1:y2 = "$(test-string-list filter y1:y2 y)" &&
-       test y2:y1 = "$(test-string-list filter y2:y1 y)" &&
-       test "x-" = "x$(test-string-list filter x1:x2 y)"
+       test "x-" = "x$(test-tool string-list filter - y)" &&
+       test "x-" = "x$(test-tool string-list filter no y)" &&
+       test yes = "$(test-tool string-list filter yes y)" &&
+       test yes = "$(test-tool string-list filter no:yes y)" &&
+       test yes = "$(test-tool string-list filter yes:no y)" &&
+       test y1:y2 = "$(test-tool string-list filter y1:y2 y)" &&
+       test y2:y1 = "$(test-tool string-list filter y2:y1 y)" &&
+       test "x-" = "x$(test-tool string-list filter x1:x2 y)"
 '
 
 test_expect_success "test remove_duplicates" '
-       test "x-" = "x$(test-string-list remove_duplicates -)" &&
-       test "x" = "x$(test-string-list remove_duplicates "")" &&
-       test a = "$(test-string-list remove_duplicates a)" &&
-       test a = "$(test-string-list remove_duplicates a:a)" &&
-       test a = "$(test-string-list remove_duplicates a:a:a:a:a)" &&
-       test a:b = "$(test-string-list remove_duplicates a:b)" &&
-       test a:b = "$(test-string-list remove_duplicates a:a:b)" &&
-       test a:b = "$(test-string-list remove_duplicates a:b:b)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:b:c)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:a:b:c)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:b:b:c)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:b:c:c)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:a:b:b:c:c)" &&
-       test a:b:c = "$(test-string-list remove_duplicates a:a:a:b:b:b:c:c:c)"
+       test "x-" = "x$(test-tool string-list remove_duplicates -)" &&
+       test "x" = "x$(test-tool string-list remove_duplicates "")" &&
+       test a = "$(test-tool string-list remove_duplicates a)" &&
+       test a = "$(test-tool string-list remove_duplicates a:a)" &&
+       test a = "$(test-tool string-list remove_duplicates a:a:a:a:a)" &&
+       test a:b = "$(test-tool string-list remove_duplicates a:b)" &&
+       test a:b = "$(test-tool string-list remove_duplicates a:a:b)" &&
+       test a:b = "$(test-tool string-list remove_duplicates a:b:b)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:b:c)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:a:b:c)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:b:b:c)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:b:c:c)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:a:b:b:c:c)" &&
+       test a:b:c = "$(test-tool string-list remove_duplicates a:a:a:b:b:b:c:c:c)"
 '
 
 test_done
index 50b31ffe756658dfa8ce435381ad7f48fee91462..67484502a007e3fed09fe381898bee52d21d07bb 100755 (executable)
@@ -18,7 +18,7 @@ test_expect_success 'ordered enumeration' '
        {
                echo20 append 88 44 aa 55 &&
                echo for_each_unique
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        test_cmp expect actual
 '
 
@@ -28,7 +28,7 @@ test_expect_success 'ordered enumeration with duplicate suppression' '
                echo20 append 88 44 aa 55 &&
                echo20 append 88 44 aa 55 &&
                echo for_each_unique
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        test_cmp expect actual
 '
 
@@ -36,7 +36,7 @@ test_expect_success 'lookup' '
        {
                echo20 append 88 44 aa 55 &&
                echo20 lookup 55
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -eq 1
 '
@@ -45,7 +45,7 @@ test_expect_success 'lookup non-existing entry' '
        {
                echo20 append 88 44 aa 55 &&
                echo20 lookup 33
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -lt 0
 '
@@ -55,7 +55,7 @@ test_expect_success 'lookup with duplicates' '
                echo20 append 88 44 aa 55 &&
                echo20 append 88 44 aa 55 &&
                echo20 lookup 55
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -ge 2 &&
        test "$n" -le 3
@@ -66,7 +66,7 @@ test_expect_success 'lookup non-existing entry with duplicates' '
                echo20 append 88 44 aa 55 &&
                echo20 append 88 44 aa 55 &&
                echo20 lookup 66
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -lt 0
 '
@@ -76,7 +76,7 @@ test_expect_success 'lookup with almost duplicate values' '
                echo "append 5555555555555555555555555555555555555555" &&
                echo "append 555555555555555555555555555555555555555f" &&
                echo20 lookup 55
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -eq 0
 '
@@ -85,7 +85,7 @@ test_expect_success 'lookup with single duplicate value' '
        {
                echo20 append 55 55 &&
                echo20 lookup 55
-       } | test-sha1-array >actual &&
+       } | test-tool sha1-array >actual &&
        n=$(cat actual) &&
        test "$n" -ge 0 &&
        test "$n" -le 1
index 7d6d21425f483c412bb6d42ea551aaf5eaef4aa0..91fa639c4a74ed69ed69ff7360728b2f1ab08a66 100755 (executable)
@@ -8,7 +8,7 @@ while read s1 s2 expect
 do
        test_expect_success "strcmp_offset($s1, $s2)" '
                echo "$expect" >expect &&
-               test-strcmp-offset "$s1" "$s2" >actual &&
+               test-tool strcmp-offset "$s1" "$s2" >actual &&
                test_cmp expect actual
        '
 done <<-EOF
index 991ed2a48dbf15fb4cb794a587ad900071391e11..23fbe6434abd3f05057d4916f70e5d5b30115b68 100755 (executable)
@@ -9,11 +9,11 @@ Verify wrappers and compatibility functions.
 . ./test-lib.sh
 
 test_expect_success 'character classes (isspace, isalpha etc.)' '
-       test-ctype
+       test-tool ctype
 '
 
 test_expect_success 'mktemp to nonexistent directory prints filename' '
-       test_must_fail test-mktemp doesnotexist/testXXXXXX 2>err &&
+       test_must_fail test-tool mktemp doesnotexist/testXXXXXX 2>err &&
        grep "doesnotexist/test" err
 '
 
@@ -21,7 +21,7 @@ test_expect_success POSIXPERM,SANITY 'mktemp to unwritable directory prints file
        mkdir cannotwrite &&
        chmod -w cannotwrite &&
        test_when_finished "chmod +w cannotwrite" &&
-       test_must_fail test-mktemp cannotwrite/testXXXXXX 2>err &&
+       test_must_fail test-tool mktemp cannotwrite/testXXXXXX 2>err &&
        grep "cannotwrite/test" err
 '
 
@@ -31,7 +31,7 @@ test_expect_success 'git_mkstemps_mode does not fail if fd 0 is not open' '
 
 test_expect_success 'check for a bug in the regex routines' '
        # if this test fails, re-build git with NO_REGEX=1
-       test-regex --bug
+       test-tool regex --bug
 '
 
 test_done
index adfd4f0b5eea1c0c438647d3d6567479acc5d495..0c61268fd22ade66c6cbd91ad743986b33af0d5d 100755 (executable)
@@ -8,13 +8,13 @@ cache-tree extension.
  . ./test-lib.sh
 
 cmp_cache_tree () {
-       test-dump-cache-tree | sed -e '/#(ref)/d' >actual &&
-       sed "s/$_x40/SHA/" <actual >filtered &&
+       test-tool dump-cache-tree | sed -e '/#(ref)/d' >actual &&
+       sed "s/$OID_REGEX/SHA/" <actual >filtered &&
        test_cmp "$1" filtered
 }
 
 # We don't bother with actually checking the SHA1:
-# test-dump-cache-tree already verifies that all existing data is
+# test-tool dump-cache-tree already verifies that all existing data is
 # correct.
 generate_expected_cache_tree_rec () {
        dir="$1${1:+/}" &&
@@ -47,7 +47,7 @@ test_cache_tree () {
 
 test_invalid_cache_tree () {
        printf "invalid                                  %s ()\n" "" "$@" >expect &&
-       test-dump-cache-tree |
+       test-tool dump-cache-tree |
        sed -n -e "s/[0-9]* subtrees//" -e '/#(ref)/d' -e '/^invalid /p' >actual &&
        test_cmp expect actual
 }
@@ -115,14 +115,14 @@ test_expect_success 'update-index invalidates cache-tree' '
 '
 
 test_expect_success 'write-tree establishes cache-tree' '
-       test-scrap-cache-tree &&
+       test-tool scrap-cache-tree &&
        git write-tree &&
        test_cache_tree
 '
 
-test_expect_success 'test-scrap-cache-tree works' '
+test_expect_success 'test-tool scrap-cache-tree works' '
        git read-tree HEAD &&
-       test-scrap-cache-tree &&
+       test-tool scrap-cache-tree &&
        test_no_cache_tree
 '
 
@@ -170,7 +170,7 @@ test_expect_success 'commit in child dir has cache-tree' '
 '
 
 test_expect_success 'reset --hard gives cache-tree' '
-       test-scrap-cache-tree &&
+       test-tool scrap-cache-tree &&
        git reset --hard &&
        test_cache_tree
 '
@@ -246,9 +246,9 @@ test_expect_success 'switching trees does not invalidate shared index' '
        git update-index --split-index &&
        >split &&
        git add split &&
-       test-dump-split-index .git/index | grep -v ^own >before &&
+       test-tool dump-split-index .git/index | grep -v ^own >before &&
        git commit -m "as-is" &&
-       test-dump-split-index .git/index | grep -v ^own >after &&
+       test-tool dump-split-index .git/index | grep -v ^own >after &&
        test_cmp before after
 '
 
index 410d5768ca11b1d7e322c135cf18f60f41685b68..f99529d83853e2c468b1c948f3ec4408a58fb919 100755 (executable)
@@ -9,172 +9,172 @@ tu="$TEST_DIRECTORY/t0110/url"
 # Note that only file: URLs should be allowed without a host
 
 test_expect_success 'url scheme' '
-       ! test-urlmatch-normalization "" &&
-       ! test-urlmatch-normalization "_" &&
-       ! test-urlmatch-normalization "scheme" &&
-       ! test-urlmatch-normalization "scheme:" &&
-       ! test-urlmatch-normalization "scheme:/" &&
-       ! test-urlmatch-normalization "scheme://" &&
-       ! test-urlmatch-normalization "file" &&
-       ! test-urlmatch-normalization "file:" &&
-       ! test-urlmatch-normalization "file:/" &&
-       test-urlmatch-normalization "file://" &&
-       ! test-urlmatch-normalization "://acme.co" &&
-       ! test-urlmatch-normalization "x_test://acme.co" &&
-       ! test-urlmatch-normalization "-test://acme.co" &&
-       ! test-urlmatch-normalization "0test://acme.co" &&
-       ! test-urlmatch-normalization "+test://acme.co" &&
-       ! test-urlmatch-normalization ".test://acme.co" &&
-       ! test-urlmatch-normalization "schem%6e://" &&
-       test-urlmatch-normalization "x-Test+v1.0://acme.co" &&
-       test "$(test-urlmatch-normalization -p "AbCdeF://x.Y")" = "abcdef://x.y/"
+       ! test-tool urlmatch-normalization "" &&
+       ! test-tool urlmatch-normalization "_" &&
+       ! test-tool urlmatch-normalization "scheme" &&
+       ! test-tool urlmatch-normalization "scheme:" &&
+       ! test-tool urlmatch-normalization "scheme:/" &&
+       ! test-tool urlmatch-normalization "scheme://" &&
+       ! test-tool urlmatch-normalization "file" &&
+       ! test-tool urlmatch-normalization "file:" &&
+       ! test-tool urlmatch-normalization "file:/" &&
+       test-tool urlmatch-normalization "file://" &&
+       ! test-tool urlmatch-normalization "://acme.co" &&
+       ! test-tool urlmatch-normalization "x_test://acme.co" &&
+       ! test-tool urlmatch-normalization "-test://acme.co" &&
+       ! test-tool urlmatch-normalization "0test://acme.co" &&
+       ! test-tool urlmatch-normalization "+test://acme.co" &&
+       ! test-tool urlmatch-normalization ".test://acme.co" &&
+       ! test-tool urlmatch-normalization "schem%6e://" &&
+       test-tool urlmatch-normalization "x-Test+v1.0://acme.co" &&
+       test "$(test-tool urlmatch-normalization -p "AbCdeF://x.Y")" = "abcdef://x.y/"
 '
 
 test_expect_success 'url authority' '
-       ! test-urlmatch-normalization "scheme://user:pass@" &&
-       ! test-urlmatch-normalization "scheme://?" &&
-       ! test-urlmatch-normalization "scheme://#" &&
-       ! test-urlmatch-normalization "scheme:///" &&
-       ! test-urlmatch-normalization "scheme://:" &&
-       ! test-urlmatch-normalization "scheme://:555" &&
-       test-urlmatch-normalization "file://user:pass@" &&
-       test-urlmatch-normalization "file://?" &&
-       test-urlmatch-normalization "file://#" &&
-       test-urlmatch-normalization "file:///" &&
-       test-urlmatch-normalization "file://:" &&
-       ! test-urlmatch-normalization "file://:555" &&
-       test-urlmatch-normalization "scheme://user:pass@host" &&
-       test-urlmatch-normalization "scheme://@host" &&
-       test-urlmatch-normalization "scheme://%00@host" &&
-       ! test-urlmatch-normalization "scheme://%%@host" &&
-       ! test-urlmatch-normalization "scheme://host_" &&
-       test-urlmatch-normalization "scheme://user:pass@host/" &&
-       test-urlmatch-normalization "scheme://@host/" &&
-       test-urlmatch-normalization "scheme://host/" &&
-       test-urlmatch-normalization "scheme://host?x" &&
-       test-urlmatch-normalization "scheme://host#x" &&
-       test-urlmatch-normalization "scheme://host/@" &&
-       test-urlmatch-normalization "scheme://host?@x" &&
-       test-urlmatch-normalization "scheme://host#@x" &&
-       test-urlmatch-normalization "scheme://[::1]" &&
-       test-urlmatch-normalization "scheme://[::1]/" &&
-       ! test-urlmatch-normalization "scheme://hos%41/" &&
-       test-urlmatch-normalization "scheme://[invalid....:/" &&
-       test-urlmatch-normalization "scheme://invalid....:]/" &&
-       ! test-urlmatch-normalization "scheme://invalid....:[/" &&
-       ! test-urlmatch-normalization "scheme://invalid....:["
+       ! test-tool urlmatch-normalization "scheme://user:pass@" &&
+       ! test-tool urlmatch-normalization "scheme://?" &&
+       ! test-tool urlmatch-normalization "scheme://#" &&
+       ! test-tool urlmatch-normalization "scheme:///" &&
+       ! test-tool urlmatch-normalization "scheme://:" &&
+       ! test-tool urlmatch-normalization "scheme://:555" &&
+       test-tool urlmatch-normalization "file://user:pass@" &&
+       test-tool urlmatch-normalization "file://?" &&
+       test-tool urlmatch-normalization "file://#" &&
+       test-tool urlmatch-normalization "file:///" &&
+       test-tool urlmatch-normalization "file://:" &&
+       ! test-tool urlmatch-normalization "file://:555" &&
+       test-tool urlmatch-normalization "scheme://user:pass@host" &&
+       test-tool urlmatch-normalization "scheme://@host" &&
+       test-tool urlmatch-normalization "scheme://%00@host" &&
+       ! test-tool urlmatch-normalization "scheme://%%@host" &&
+       ! test-tool urlmatch-normalization "scheme://host_" &&
+       test-tool urlmatch-normalization "scheme://user:pass@host/" &&
+       test-tool urlmatch-normalization "scheme://@host/" &&
+       test-tool urlmatch-normalization "scheme://host/" &&
+       test-tool urlmatch-normalization "scheme://host?x" &&
+       test-tool urlmatch-normalization "scheme://host#x" &&
+       test-tool urlmatch-normalization "scheme://host/@" &&
+       test-tool urlmatch-normalization "scheme://host?@x" &&
+       test-tool urlmatch-normalization "scheme://host#@x" &&
+       test-tool urlmatch-normalization "scheme://[::1]" &&
+       test-tool urlmatch-normalization "scheme://[::1]/" &&
+       ! test-tool urlmatch-normalization "scheme://hos%41/" &&
+       test-tool urlmatch-normalization "scheme://[invalid....:/" &&
+       test-tool urlmatch-normalization "scheme://invalid....:]/" &&
+       ! test-tool urlmatch-normalization "scheme://invalid....:[/" &&
+       ! test-tool urlmatch-normalization "scheme://invalid....:["
 '
 
 test_expect_success 'url port checks' '
-       test-urlmatch-normalization "xyz://q@some.host:" &&
-       test-urlmatch-normalization "xyz://q@some.host:456/" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:0" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:0000000" &&
-       test-urlmatch-normalization "xyz://q@some.host:0000001?" &&
-       test-urlmatch-normalization "xyz://q@some.host:065535#" &&
-       test-urlmatch-normalization "xyz://q@some.host:65535" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:65536" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:99999" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:100000" &&
-       ! test-urlmatch-normalization "xyz://q@some.host:100001" &&
-       test-urlmatch-normalization "http://q@some.host:80" &&
-       test-urlmatch-normalization "https://q@some.host:443" &&
-       test-urlmatch-normalization "http://q@some.host:80/" &&
-       test-urlmatch-normalization "https://q@some.host:443?" &&
-       ! test-urlmatch-normalization "http://q@:8008" &&
-       ! test-urlmatch-normalization "http://:8080" &&
-       ! test-urlmatch-normalization "http://:" &&
-       test-urlmatch-normalization "xyz://q@some.host:456/" &&
-       test-urlmatch-normalization "xyz://[::1]:456/" &&
-       test-urlmatch-normalization "xyz://[::1]:/" &&
-       ! test-urlmatch-normalization "xyz://[::1]:000/" &&
-       ! test-urlmatch-normalization "xyz://[::1]:0%300/" &&
-       ! test-urlmatch-normalization "xyz://[::1]:0x80/" &&
-       ! test-urlmatch-normalization "xyz://[::1]:4294967297/" &&
-       ! test-urlmatch-normalization "xyz://[::1]:030f/"
+       test-tool urlmatch-normalization "xyz://q@some.host:" &&
+       test-tool urlmatch-normalization "xyz://q@some.host:456/" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:0" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:0000000" &&
+       test-tool urlmatch-normalization "xyz://q@some.host:0000001?" &&
+       test-tool urlmatch-normalization "xyz://q@some.host:065535#" &&
+       test-tool urlmatch-normalization "xyz://q@some.host:65535" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:65536" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:99999" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:100000" &&
+       ! test-tool urlmatch-normalization "xyz://q@some.host:100001" &&
+       test-tool urlmatch-normalization "http://q@some.host:80" &&
+       test-tool urlmatch-normalization "https://q@some.host:443" &&
+       test-tool urlmatch-normalization "http://q@some.host:80/" &&
+       test-tool urlmatch-normalization "https://q@some.host:443?" &&
+       ! test-tool urlmatch-normalization "http://q@:8008" &&
+       ! test-tool urlmatch-normalization "http://:8080" &&
+       ! test-tool urlmatch-normalization "http://:" &&
+       test-tool urlmatch-normalization "xyz://q@some.host:456/" &&
+       test-tool urlmatch-normalization "xyz://[::1]:456/" &&
+       test-tool urlmatch-normalization "xyz://[::1]:/" &&
+       ! test-tool urlmatch-normalization "xyz://[::1]:000/" &&
+       ! test-tool urlmatch-normalization "xyz://[::1]:0%300/" &&
+       ! test-tool urlmatch-normalization "xyz://[::1]:0x80/" &&
+       ! test-tool urlmatch-normalization "xyz://[::1]:4294967297/" &&
+       ! test-tool urlmatch-normalization "xyz://[::1]:030f/"
 '
 
 test_expect_success 'url port normalization' '
-       test "$(test-urlmatch-normalization -p "http://x:800")" = "http://x:800/" &&
-       test "$(test-urlmatch-normalization -p "http://x:0800")" = "http://x:800/" &&
-       test "$(test-urlmatch-normalization -p "http://x:00000800")" = "http://x:800/" &&
-       test "$(test-urlmatch-normalization -p "http://x:065535")" = "http://x:65535/" &&
-       test "$(test-urlmatch-normalization -p "http://x:1")" = "http://x:1/" &&
-       test "$(test-urlmatch-normalization -p "http://x:80")" = "http://x/" &&
-       test "$(test-urlmatch-normalization -p "http://x:080")" = "http://x/" &&
-       test "$(test-urlmatch-normalization -p "http://x:000000080")" = "http://x/" &&
-       test "$(test-urlmatch-normalization -p "https://x:443")" = "https://x/" &&
-       test "$(test-urlmatch-normalization -p "https://x:0443")" = "https://x/" &&
-       test "$(test-urlmatch-normalization -p "https://x:000000443")" = "https://x/"
+       test "$(test-tool urlmatch-normalization -p "http://x:800")" = "http://x:800/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:0800")" = "http://x:800/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:00000800")" = "http://x:800/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:065535")" = "http://x:65535/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:1")" = "http://x:1/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:80")" = "http://x/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:080")" = "http://x/" &&
+       test "$(test-tool urlmatch-normalization -p "http://x:000000080")" = "http://x/" &&
+       test "$(test-tool urlmatch-normalization -p "https://x:443")" = "https://x/" &&
+       test "$(test-tool urlmatch-normalization -p "https://x:0443")" = "https://x/" &&
+       test "$(test-tool urlmatch-normalization -p "https://x:000000443")" = "https://x/"
 '
 
 test_expect_success 'url general escapes' '
-       ! test-urlmatch-normalization "http://x.y?%fg" &&
-       test "$(test-urlmatch-normalization -p "X://W/%7e%41^%3a")" = "x://w/~A%5E%3A" &&
-       test "$(test-urlmatch-normalization -p "X://W/:/?#[]@")" = "x://w/:/?#[]@" &&
-       test "$(test-urlmatch-normalization -p "X://W/$&()*+,;=")" = "x://w/$&()*+,;=" &&
-       test "$(test-urlmatch-normalization -p "X://W/'\''")" = "x://w/'\''" &&
-       test "$(test-urlmatch-normalization -p "X://W?'\!'")" = "x://w/?'\!'"
+       ! test-tool urlmatch-normalization "http://x.y?%fg" &&
+       test "$(test-tool urlmatch-normalization -p "X://W/%7e%41^%3a")" = "x://w/~A%5E%3A" &&
+       test "$(test-tool urlmatch-normalization -p "X://W/:/?#[]@")" = "x://w/:/?#[]@" &&
+       test "$(test-tool urlmatch-normalization -p "X://W/$&()*+,;=")" = "x://w/$&()*+,;=" &&
+       test "$(test-tool urlmatch-normalization -p "X://W/'\''")" = "x://w/'\''" &&
+       test "$(test-tool urlmatch-normalization -p "X://W?'\!'")" = "x://w/?'\!'"
 '
 
 test_expect_success !MINGW 'url high-bit escapes' '
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-1")")" = "x://q/%01%02%03%04%05%06%07%08%0E%0F%10%11%12" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-2")")" = "x://q/%13%14%15%16%17%18%19%1B%1C%1D%1E%1F%7F" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-3")")" = "x://q/%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-4")")" = "x://q/%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-5")")" = "x://q/%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-6")")" = "x://q/%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-7")")" = "x://q/%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-8")")" = "x://q/%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-9")")" = "x://q/%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF" &&
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-10")")" = "x://q/%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF"
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-1")")" = "x://q/%01%02%03%04%05%06%07%08%0E%0F%10%11%12" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-2")")" = "x://q/%13%14%15%16%17%18%19%1B%1C%1D%1E%1F%7F" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-3")")" = "x://q/%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-4")")" = "x://q/%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-5")")" = "x://q/%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-6")")" = "x://q/%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-7")")" = "x://q/%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-8")")" = "x://q/%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-9")")" = "x://q/%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF" &&
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-10")")" = "x://q/%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF"
 '
 
 test_expect_success 'url utf-8 escapes' '
-       test "$(test-urlmatch-normalization -p "$(cat "$tu-11")")" = "x://q/%C2%80%DF%BF%E0%A0%80%EF%BF%BD%F0%90%80%80%F0%AF%BF%BD"
+       test "$(test-tool urlmatch-normalization -p "$(cat "$tu-11")")" = "x://q/%C2%80%DF%BF%E0%A0%80%EF%BF%BD%F0%90%80%80%F0%AF%BF%BD"
 '
 
 test_expect_success 'url username/password escapes' '
-       test "$(test-urlmatch-normalization -p "x://%41%62(^):%70+d@foo")" = "x://Ab(%5E):p+d@foo/"
+       test "$(test-tool urlmatch-normalization -p "x://%41%62(^):%70+d@foo")" = "x://Ab(%5E):p+d@foo/"
 '
 
 test_expect_success 'url normalized lengths' '
-       test "$(test-urlmatch-normalization -l "Http://%4d%65:%4d^%70@The.Host")" = 25 &&
-       test "$(test-urlmatch-normalization -l "http://%41:%42@x.y/%61/")" = 17 &&
-       test "$(test-urlmatch-normalization -l "http://@x.y/^")" = 15
+       test "$(test-tool urlmatch-normalization -l "Http://%4d%65:%4d^%70@The.Host")" = 25 &&
+       test "$(test-tool urlmatch-normalization -l "http://%41:%42@x.y/%61/")" = 17 &&
+       test "$(test-tool urlmatch-normalization -l "http://@x.y/^")" = 15
 '
 
 test_expect_success 'url . and .. segments' '
-       test "$(test-urlmatch-normalization -p "x://y/.")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/./")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/.")" = "x://y/a" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./")" = "x://y/a/" &&
-       test "$(test-urlmatch-normalization -p "x://y/.?")" = "x://y/?" &&
-       test "$(test-urlmatch-normalization -p "x://y/./?")" = "x://y/?" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/.?")" = "x://y/a?" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./?")" = "x://y/a/?" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./b/.././../c")" = "x://y/c" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./b/../.././c/")" = "x://y/c/" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./b/.././../c/././.././.")" = "x://y/" &&
-       ! test-urlmatch-normalization "x://y/a/./b/.././../c/././.././.." &&
-       test "$(test-urlmatch-normalization -p "x://y/a/./?/././..")" = "x://y/a/?/././.." &&
-       test "$(test-urlmatch-normalization -p "x://y/%2e/")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/%2E/")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/a/%2e./")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/b/.%2E/")" = "x://y/" &&
-       test "$(test-urlmatch-normalization -p "x://y/c/%2e%2E/")" = "x://y/"
+       test "$(test-tool urlmatch-normalization -p "x://y/.")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/./")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/.")" = "x://y/a" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./")" = "x://y/a/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/.?")" = "x://y/?" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/./?")" = "x://y/?" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/.?")" = "x://y/a?" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./?")" = "x://y/a/?" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./b/.././../c")" = "x://y/c" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./b/../.././c/")" = "x://y/c/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./b/.././../c/././.././.")" = "x://y/" &&
+       ! test-tool urlmatch-normalization "x://y/a/./b/.././../c/././.././.." &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/./?/././..")" = "x://y/a/?/././.." &&
+       test "$(test-tool urlmatch-normalization -p "x://y/%2e/")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/%2E/")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/a/%2e./")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/b/.%2E/")" = "x://y/" &&
+       test "$(test-tool urlmatch-normalization -p "x://y/c/%2e%2E/")" = "x://y/"
 '
 
 # http://@foo specifies an empty user name but does not specify a password
 # http://foo  specifies neither a user name nor a password
 # So they should not be equivalent
 test_expect_success 'url equivalents' '
-       test-urlmatch-normalization "httP://x" "Http://X/" &&
-       test-urlmatch-normalization "Http://%4d%65:%4d^%70@The.Host" "hTTP://Me:%4D^p@the.HOST:80/" &&
-       ! test-urlmatch-normalization "https://@x.y/^" "httpS://x.y:443/^" &&
-       test-urlmatch-normalization "https://@x.y/^" "httpS://@x.y:0443/^" &&
-       test-urlmatch-normalization "https://@x.y/^/../abc" "httpS://@x.y:0443/abc" &&
-       test-urlmatch-normalization "https://@x.y/^/.." "httpS://@x.y:0443/"
+       test-tool urlmatch-normalization "httP://x" "Http://X/" &&
+       test-tool urlmatch-normalization "Http://%4d%65:%4d^%70@The.Host" "hTTP://Me:%4D^p@the.HOST:80/" &&
+       ! test-tool urlmatch-normalization "https://@x.y/^" "httpS://x.y:443/^" &&
+       test-tool urlmatch-normalization "https://@x.y/^" "httpS://@x.y:0443/^" &&
+       test-tool urlmatch-normalization "https://@x.y/^/../abc" "httpS://@x.y:0443/abc" &&
+       test-tool urlmatch-normalization "https://@x.y/^/.." "httpS://@x.y:0443/"
 '
 
 test_done
index 3c4d2d6045bf026cf164374a41ae759d08a69bf8..013c5a7bc32849eaa1c2fe7dea007d2788e3ea8a 100755 (executable)
@@ -128,7 +128,7 @@ cat >expected <<\EOF
 EOF
 
 check_result () {
-       git ls-files --stage | sed -e 's/ '"$_x40"' / X /' >current &&
+       git ls-files --stage | sed -e 's/ '"$OID_REGEX"' / X /' >current &&
        test_cmp expected current
 }
 
index 5ededd8e400e7e64faa1bd559d67251ecbf8608e..1057a96b2498d1a8abf87f21f90d108eee2c2f96 100755 (executable)
@@ -30,7 +30,7 @@ read_tree_twoway () {
 compare_change () {
        sed -n >current \
            -e '/^--- /d; /^+++ /d; /^@@ /d;' \
-           -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /p' \
+           -e 's/^\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\) '"$OID_REGEX"' /\1 X /p' \
            "$1"
        test_cmp expected current
 }
index 7ca2e65d102afd76dc4136a9f12c53a5ba0fce25..9c05f5e1f510664ca6ecce60eab5ffe1a30a58ef 100755 (executable)
@@ -16,7 +16,7 @@ compare_change () {
            -e '1{/^diff --git /d;}' \
            -e '2{/^index /d;}' \
            -e '/^--- /d; /^+++ /d; /^@@ /d;' \
-           -e 's/^\(.[0-7][0-7][0-7][0-7][0-7][0-7]\) '"$_x40"' /\1 X /' "$1"
+           -e 's/^\(.[0-7][0-7][0-7][0-7][0-7][0-7]\) '"$OID_REGEX"' /\1 X /' "$1"
        test_cmp expected current
 }
 
index b19f3326946203409fe0e428b9fc73d34134d756..13dd510b2ed8c4ce3b48666557bf68ad2aa03953 100755 (executable)
@@ -236,8 +236,8 @@ test_expect_success "--batch-check for an empty line" '
 '
 
 test_expect_success 'empty --batch-check notices missing object' '
-       echo "$_z40 missing" >expect &&
-       echo "$_z40" | git cat-file --batch-check="" >actual &&
+       echo "$ZERO_OID missing" >expect &&
+       echo "$ZERO_OID" | git cat-file --batch-check="" >actual &&
        test_cmp expect actual
 '
 
@@ -282,7 +282,7 @@ test_expect_success "--batch-check with multiple sha1s gives correct format" '
 '
 
 test_expect_success 'setup blobs which are likely to delta' '
-       test-genrandom foo 10240 >foo &&
+       test-tool genrandom foo 10240 >foo &&
        { cat foo; echo plus; } >foo-plus &&
        git add foo foo-plus &&
        git commit -m foo &&
@@ -294,8 +294,8 @@ test_expect_success 'setup blobs which are likely to delta' '
 
 test_expect_success 'confirm that neither loose blob is a delta' '
        cat >expect <<-EOF &&
-       $_z40
-       $_z40
+       $ZERO_OID
+       $ZERO_OID
        EOF
        git cat-file --batch-check="%(deltabase)" <blobs >actual &&
        test_cmp expect actual
index 532682f51c4f9cefc34a44cf7e7f4231c60b7f65..a37753047e084c9be40251e7c4286084bff6870a 100755 (executable)
@@ -9,13 +9,13 @@ echo_without_newline() {
 }
 
 test_blob_does_not_exist() {
-       test_expect_success 'blob does not exist in database' "
+       test_expect_success SHA1 'blob does not exist in database' "
                test_must_fail git cat-file blob $1
        "
 }
 
 test_blob_exists() {
-       test_expect_success 'blob exists in database' "
+       test_expect_success SHA1 'blob exists in database' "
                git cat-file blob $1
        "
 }
@@ -73,19 +73,19 @@ test_expect_success "Can't use --path with --no-filters" '
 
 push_repo
 
-test_expect_success 'hash a file' '
+test_expect_success SHA1 'hash a file' '
        test $hello_sha1 = $(git hash-object hello)
 '
 
 test_blob_does_not_exist $hello_sha1
 
-test_expect_success 'hash from stdin' '
+test_expect_success SHA1 'hash from stdin' '
        test $example_sha1 = $(git hash-object --stdin < example)
 '
 
 test_blob_does_not_exist $example_sha1
 
-test_expect_success 'hash a file and write to database' '
+test_expect_success SHA1 'hash a file and write to database' '
        test $hello_sha1 = $(git hash-object -w hello)
 '
 
@@ -161,7 +161,7 @@ pop_repo
 for args in "-w --stdin" "--stdin -w"; do
        push_repo
 
-       test_expect_success "hash from stdin and write to database ($args)" '
+       test_expect_success SHA1 "hash from stdin and write to database ($args)" '
                test $example_sha1 = $(git hash-object $args < example)
        '
 
@@ -176,14 +176,14 @@ example"
 sha1s="$hello_sha1
 $example_sha1"
 
-test_expect_success "hash two files with names on stdin" '
+test_expect_success SHA1 "hash two files with names on stdin" '
        test "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object --stdin-paths)"
 '
 
 for args in "-w --stdin-paths" "--stdin-paths -w"; do
        push_repo
 
-       test_expect_success "hash two files with names on stdin and write to database ($args)" '
+       test_expect_success SHA1 "hash two files with names on stdin and write to database ($args)" '
                test "$sha1s" = "$(echo_without_newline "$filenames" | git hash-object $args)"
        '
 
index c167f606ca7b8c1628ac8d00507d50f032278730..0c6f48f3024c81de765a8acb489e2d5e3ec42a56 100755 (executable)
@@ -15,8 +15,11 @@ test_description='sparse checkout tests
 . "$TEST_DIRECTORY"/lib-read-tree.sh
 
 test_expect_success 'setup' '
+       test_commit init &&
+       echo modified >>init.t &&
+
        cat >expected <<-EOF &&
-       100644 77f0ba1734ed79d12881f81b36ee134de6a3327b 0       init.t
+       100644 $(git hash-object init.t) 0      init.t
        100644 $EMPTY_BLOB 0    sub/added
        100644 $EMPTY_BLOB 0    sub/addedtoo
        100644 $EMPTY_BLOB 0    subsub/added
@@ -28,8 +31,6 @@ test_expect_success 'setup' '
        H subsub/added
        EOF
 
-       test_commit init &&
-       echo modified >>init.t &&
        mkdir sub subsub &&
        touch sub/added sub/addedtoo subsub/added &&
        git add init.t sub/added sub/addedtoo subsub/added &&
index a6a04b6b90d290a445ed7c33e5928a9a168ed28b..57f0770df1410ea2005d8637323ff0eeeb82d880 100755 (executable)
@@ -32,7 +32,7 @@ settree () {
 
 checkindex () {
        git ls-files -s |
-       sed "s|^[0-7][0-7]* $_x40 \([0-3]\)     |\1 |" >current &&
+       sed "s|^[0-7][0-7]* $OID_REGEX \([0-3]\)        |\1 |" >current &&
        cat >expect &&
        test_cmp expect current
 }
index 6fd264cff0d6de1961656c2cd1193d8ce37e9a1f..f9eb143f43420b0e2f2b864b4f83f78de7886a7b 100755 (executable)
@@ -103,9 +103,9 @@ test_expect_success 'packsize limit' '
                # mid1 and mid2 will fit within 256k limit but
                # appending mid3 will bust the limit and will
                # result in a separate packfile.
-               test-genrandom "a" $(( 66 * 1024 )) >mid1 &&
-               test-genrandom "b" $(( 80 * 1024 )) >mid2 &&
-               test-genrandom "c" $(( 128 * 1024 )) >mid3 &&
+               test-tool genrandom "a" $(( 66 * 1024 )) >mid1 &&
+               test-tool genrandom "b" $(( 80 * 1024 )) >mid2 &&
+               test-tool genrandom "c" $(( 128 * 1024 )) >mid3 &&
                git add mid1 mid2 mid3 &&
 
                count=0
similarity index 89%
rename from t/t1300-repo-config.sh
rename to t/t1300-config.sh
index 4f8e6f5fde3295cc91d2feb1fd85fa007e56016c..03c223708ebb428125dffb4a9ca273629936ff0c 100755 (executable)
@@ -108,6 +108,7 @@ bar = foo
 [beta]
 baz = multiple \
 lines
+foo = bar
 EOF
 
 test_expect_success 'unset with cont. lines' '
@@ -118,6 +119,7 @@ cat > expect <<\EOF
 [alpha]
 bar = foo
 [beta]
+foo = bar
 EOF
 
 test_expect_success 'unset with cont. lines is correct' 'test_cmp expect .git/config'
@@ -740,7 +742,7 @@ test_expect_success bool '
        do
            git config --bool --get bool.true$i >>result
            git config --bool --get bool.false$i >>result
-        done &&
+       done &&
        test_cmp expect result'
 
 test_expect_success 'invalid bool (--get)' '
@@ -914,7 +916,7 @@ test_expect_success 'get --expiry-date' '
        invalid1 = "abc"
        EOF
        cat >expect <<-EOF &&
-       $(test-date timestamp $rel)
+       $(test-tool date timestamp $rel)
        1275666415
        1510441871
        1510348087
@@ -931,6 +933,36 @@ test_expect_success 'get --expiry-date' '
        test_must_fail git config --expiry-date date.invalid1
 '
 
+test_expect_success 'get --type=color' '
+       rm .git/config &&
+       git config foo.color "red" &&
+       git config --get --type=color foo.color >actual.raw &&
+       test_decode_color <actual.raw >actual &&
+       echo "<RED>" >expect &&
+       test_cmp expect actual
+'
+
+cat >expect << EOF
+[foo]
+       color = red
+EOF
+
+test_expect_success 'set --type=color' '
+       rm .git/config &&
+       git config --type=color foo.color "red" &&
+       test_cmp expect .git/config
+'
+
+test_expect_success 'get --type=color barfs on non-color' '
+       echo "[foo]bar=not-a-color" >.git/config &&
+       test_must_fail git config --get --type=color foo.bar
+'
+
+test_expect_success 'set --type=color barfs on non-color' '
+       test_must_fail git config --type=color foo.color "not-a-color" 2>error &&
+       test_i18ngrep "cannot parse color" error
+'
+
 cat > expect << EOF
 [quote]
        leading = " test"
@@ -1411,7 +1443,7 @@ test_expect_success 'urlmatch with wildcard' '
 '
 
 # good section hygiene
-test_expect_failure 'unsetting the last key in a section removes header' '
+test_expect_success '--unset last key removes section (except if commented)' '
        cat >.git/config <<-\EOF &&
        # some generic comment on the configuration file itself
        # a comment specific to this "section" section.
@@ -1425,13 +1457,86 @@ test_expect_failure 'unsetting the last key in a section removes header' '
 
        cat >expect <<-\EOF &&
        # some generic comment on the configuration file itself
+       # a comment specific to this "section" section.
+       [section]
+       # some intervening lines
+       # that should also be dropped
+
+       # please be careful when you update the above variable
        EOF
 
        git config --unset section.key &&
-       test_cmp expect .git/config
+       test_cmp expect .git/config &&
+
+       cat >.git/config <<-\EOF &&
+       [section]
+       key = value
+       [next-section]
+       EOF
+
+       cat >expect <<-\EOF &&
+       [next-section]
+       EOF
+
+       git config --unset section.key &&
+       test_cmp expect .git/config &&
+
+       q_to_tab >.git/config <<-\EOF &&
+       [one]
+       Qkey = "multiline \
+       QQ# with comment"
+       [two]
+       key = true
+       EOF
+       git config --unset two.key &&
+       ! grep two .git/config &&
+
+       q_to_tab >.git/config <<-\EOF &&
+       [one]
+       Qkey = "multiline \
+       QQ# with comment"
+       [one]
+       key = true
+       EOF
+       git config --unset-all one.key &&
+       test_line_count = 0 .git/config &&
+
+       q_to_tab >.git/config <<-\EOF &&
+       [one]
+       Qkey = true
+       Q# a comment not at the start
+       [two]
+       Qkey = true
+       EOF
+       git config --unset two.key &&
+       grep two .git/config &&
+
+       q_to_tab >.git/config <<-\EOF &&
+       [one]
+       Qkey = not [two "subsection"]
+       [two "subsection"]
+       [two "subsection"]
+       Qkey = true
+       [TWO "subsection"]
+       [one]
+       EOF
+       git config --unset two.subsection.key &&
+       test "not [two subsection]" = "$(git config one.key)" &&
+       test_line_count = 3 .git/config
+'
+
+test_expect_success '--unset-all removes section if empty & uncommented' '
+       cat >.git/config <<-\EOF &&
+       [section]
+       key = value1
+       key = value2
+       EOF
+
+       git config --unset-all section.key &&
+       test_line_count = 0 .git/config
 '
 
-test_expect_failure 'adding a key into an empty section reuses header' '
+test_expect_success 'adding a key into an empty section reuses header' '
        cat >.git/config <<-\EOF &&
        [section]
        EOF
@@ -1587,10 +1692,10 @@ test_expect_success '--show-origin stdin with file include' '
 '
 
 test_expect_success !MINGW '--show-origin blob' '
-       cat >expect <<-\EOF &&
-               blob:a9d9f9e555b5c6f07cbe09d3f06fe3df11e09c08   user.custom=true
-       EOF
        blob=$(git hash-object -w "$CUSTOM_CONFIG_FILE") &&
+       cat >expect <<-EOF &&
+               blob:$blob      user.custom=true
+       EOF
        git config --blob=$blob --show-origin --list >output &&
        test_cmp expect output
 '
@@ -1611,4 +1716,88 @@ test_expect_success '--local requires a repo' '
        test_expect_code 128 nongit git config --local foo.bar
 '
 
+cat >.git/config <<-\EOF &&
+[core]
+foo = true
+number = 10
+big = 1M
+EOF
+
+test_expect_success 'identical modern --type specifiers are allowed' '
+       git config --type=int --type=int core.big >actual &&
+       echo 1048576 >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success 'identical legacy --type specifiers are allowed' '
+       git config --int --int core.big >actual &&
+       echo 1048576 >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success 'identical mixed --type specifiers are allowed' '
+       git config --int --type=int core.big >actual &&
+       echo 1048576 >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success 'non-identical modern --type specifiers are not allowed' '
+       test_must_fail git config --type=int --type=bool core.big 2>error &&
+       test_i18ngrep "only one type at a time" error
+'
+
+test_expect_success 'non-identical legacy --type specifiers are not allowed' '
+       test_must_fail git config --int --bool core.big 2>error &&
+       test_i18ngrep "only one type at a time" error
+'
+
+test_expect_success 'non-identical mixed --type specifiers are not allowed' '
+       test_must_fail git config --type=int --bool core.big 2>error &&
+       test_i18ngrep "only one type at a time" error
+'
+
+test_expect_success '--type allows valid type specifiers' '
+       echo "true" >expect &&
+       git config --type=bool core.foo >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success '--no-type unsets type specifiers' '
+       echo "10" >expect &&
+       git config --type=bool --no-type core.number >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'unset type specifiers may be reset to conflicting ones' '
+       echo 1048576 >expect &&
+       git config --type=bool --no-type --type=int core.big >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success '--type rejects unknown specifiers' '
+       test_must_fail git config --type=nonsense core.foo 2>error &&
+       test_i18ngrep "unrecognized --type argument" error
+'
+
+test_expect_success '--replace-all does not invent newlines' '
+       q_to_tab >.git/config <<-\EOF &&
+       [abc]key
+       QkeepSection
+       [xyz]
+       Qkey = 1
+       [abc]
+       Qkey = a
+       EOF
+       q_to_tab >expect <<-\EOF &&
+       [abc]
+       QkeepSection
+       [xyz]
+       Qkey = 1
+       [abc]
+       Qkey = b
+       EOF
+       git config --replace-all abc.key b &&
+       test_cmp .git/config expect
+'
+
 test_done
index f5422f1d33f5eac98e6f56ec4bf05f3f8d4c8be2..335d3f3211aa874fd3a8e0d0006dd9fc53a4e589 100755 (executable)
@@ -54,7 +54,7 @@ test_expect_success SETFACL 'Setup test repo' '
 
 test_expect_success SETFACL 'Objects creation does not break ACLs with restrictive umask' '
        # SHA1 for empty blob
-       check_perms_and_acl .git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391
+       check_perms_and_acl .git/objects/$(echo $EMPTY_BLOB | sed -e "s,^\(..\),\1/,")
 '
 
 test_expect_success SETFACL 'git gc does not break ACLs with restrictive umask' '
index d9d2f545a4ed735e02f7d5cd6ceee7d873fdec94..f035ee40a313ae25a13bdb6a838eed3b34fd5f9d 100755 (executable)
@@ -224,7 +224,7 @@ test_expect_success 'conditional include, early config reading' '
                echo "[includeIf \"gitdir:foo/\"]path=bar6" >>.git/config &&
                echo "[test]six=6" >.git/bar6 &&
                echo 6 >expect &&
-               test-config read_early_config test.six >actual &&
+               test-tool config read_early_config test.six >actual &&
                test_cmp expect actual
        )
 '
index eed31ffa30eebaa994b2fee569eb753e2a6a1477..37dc689d8c98fd776895e1ce6d18faee092001d3 100755 (executable)
@@ -73,4 +73,8 @@ test_expect_success 'can parse blob ending with CR' '
        test_cmp expect actual
 '
 
+test_expect_success 'config --blob outside of a repository is an error' '
+       test_must_fail nongit git config --blob=foo --list
+'
+
 test_done
index bafed5c9b88481992ca6cf4cd6c13596c7baf16b..3e00d1af01fb771bd3fd26dcb265a3d80da37934 100755 (executable)
@@ -18,7 +18,7 @@ check_config () {
        then
                printf "%s\n" "$@"
        fi >expect &&
-       test_expect_code $expect_code test-config "$op" "$key" >actual &&
+       test_expect_code $expect_code test-tool config "$op" "$key" >actual &&
        test_cmp expect actual
 }
 
@@ -125,7 +125,7 @@ test_expect_success 'find string value for a key' '
 '
 
 test_expect_success 'check line error when NULL string is queried' '
-       test_expect_code 128 test-config get_string case.foo 2>result &&
+       test_expect_code 128 test-tool config get_string case.foo 2>result &&
        test_i18ngrep "fatal: .*case\.foo.*\.git/config.*line 7" result
 '
 
@@ -155,13 +155,13 @@ test_expect_success 'find value from a configset' '
                baz = ball
        EOF
        echo silk >expect &&
-       test-config configset_get_value my.new config2 .git/config >actual &&
+       test-tool config configset_get_value my.new config2 .git/config >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'find value with highest priority from a configset' '
        echo hask >expect &&
-       test-config configset_get_value case.baz config2 .git/config >actual &&
+       test-tool config configset_get_value case.baz config2 .git/config >actual &&
        test_cmp expect actual
 '
 
@@ -173,20 +173,20 @@ test_expect_success 'find value_list for a key from a configset' '
        lama
        ball
        EOF
-       test-config configset_get_value case.baz config2 .git/config >actual &&
+       test-tool config configset_get_value case.baz config2 .git/config >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'proper error on non-existent files' '
        echo "Error (-1) reading configuration file non-existent-file." >expect &&
-       test_expect_code 2 test-config configset_get_value foo.bar non-existent-file 2>actual &&
+       test_expect_code 2 test-tool config configset_get_value foo.bar non-existent-file 2>actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'proper error on directory "files"' '
        echo "Error (-1) reading configuration file a-directory." >expect &&
        mkdir a-directory &&
-       test_expect_code 2 test-config configset_get_value foo.bar a-directory 2>output &&
+       test_expect_code 2 test-tool config configset_get_value foo.bar a-directory 2>output &&
        grep "^warning:" output &&
        grep "^Error" output >actual &&
        test_cmp expect actual
@@ -196,7 +196,7 @@ test_expect_success POSIXPERM,SANITY 'proper error on non-accessible files' '
        chmod -r .git/config &&
        test_when_finished "chmod +r .git/config" &&
        echo "Error (-1) reading configuration file .git/config." >expect &&
-       test_expect_code 2 test-config configset_get_value foo.bar .git/config 2>output &&
+       test_expect_code 2 test-tool config configset_get_value foo.bar .git/config 2>output &&
        grep "^warning:" output &&
        grep "^Error" output >actual &&
        test_cmp expect actual
@@ -207,14 +207,14 @@ test_expect_success 'proper error on error in default config files' '
        test_when_finished "mv .git/config.old .git/config" &&
        echo "[" >>.git/config &&
        echo "fatal: bad config line 34 in file .git/config" >expect &&
-       test_expect_code 128 test-config get_value foo.bar 2>actual &&
+       test_expect_code 128 test-tool config get_value foo.bar 2>actual &&
        test_i18ncmp expect actual
 '
 
 test_expect_success 'proper error on error in custom config files' '
        echo "[" >>syntax-error &&
        echo "fatal: bad config line 1 in file syntax-error" >expect &&
-       test_expect_code 128 test-config configset_get_value foo.bar syntax-error 2>actual &&
+       test_expect_code 128 test-tool config configset_get_value foo.bar syntax-error 2>actual &&
        test_i18ncmp expect actual
 '
 
@@ -267,7 +267,7 @@ test_expect_success 'iteration shows correct origins' '
        name=
        scope=cmdline
        EOF
-       GIT_CONFIG_PARAMETERS=$cmdline_config test-config iterate >actual &&
+       GIT_CONFIG_PARAMETERS=$cmdline_config test-tool config iterate >actual &&
        test_cmp expect actual
 '
 
index 3dda215e8e2f37c049a3169cecdb3e43ddea5dfb..413642aa5672800d1b7be448bc97d175add07ee4 100755 (executable)
@@ -6,7 +6,7 @@ test_description='Test read_early_config()'
 
 test_expect_success 'read early config' '
        test_config early.config correct &&
-       test-config read_early_config early.config >output &&
+       test-tool config read_early_config early.config >output &&
        test correct = "$(cat output)"
 '
 
@@ -15,7 +15,7 @@ test_expect_success 'in a sub-directory' '
        mkdir -p sub &&
        (
                cd sub &&
-               test-config read_early_config early.config
+               test-tool config read_early_config early.config
        ) >output &&
        test sub = "$(cat output)"
 '
@@ -27,7 +27,7 @@ test_expect_success 'ceiling' '
                GIT_CEILING_DIRECTORIES="$PWD" &&
                export GIT_CEILING_DIRECTORIES &&
                cd sub &&
-               test-config read_early_config early.config
+               test-tool config read_early_config early.config
        ) >output &&
        test -z "$(cat output)"
 '
@@ -42,7 +42,7 @@ test_expect_success 'ceiling #2' '
                GIT_CEILING_DIRECTORIES="$PWD" &&
                export GIT_CEILING_DIRECTORIES XDG_CONFIG_HOME &&
                cd sub &&
-               test-config read_early_config early.config
+               test-tool config read_early_config early.config
        ) >output &&
        test xdg = "$(cat output)"
 '
@@ -54,7 +54,7 @@ test_expect_success 'read config file in right order' '
        (
                cd foo &&
                echo "[test]source = repo" >>.git/config &&
-               GIT_CONFIG_PARAMETERS=$cmdline_config test-config \
+               GIT_CONFIG_PARAMETERS=$cmdline_config test-tool config \
                        read_early_config test.source >actual &&
                cat >expected <<-\EOF &&
                home
@@ -71,7 +71,7 @@ test_with_config () {
        (
                cd throwaway &&
                echo "$*" >.git/config &&
-               test-config read_early_config early.config
+               test-tool config read_early_config early.config
        )
 }
 
diff --git a/t/t1310-config-default.sh b/t/t1310-config-default.sh
new file mode 100755 (executable)
index 0000000..6049d91
--- /dev/null
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+test_description='Test git config in different settings (with --default)'
+
+. ./test-lib.sh
+
+test_expect_success 'uses --default when entry missing' '
+       echo quux >expect &&
+       git config -f config --default=quux core.foo >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'does not use --default when entry present' '
+       echo bar >expect &&
+       git -c core.foo=bar config --default=baz core.foo >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'canonicalizes --default with appropriate type' '
+       echo true >expect &&
+       git config -f config --default=yes --bool core.foo >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'dies when --default cannot be parsed' '
+       test_must_fail git config -f config --type=expiry-date --default=x --get \
+               not.a.section 2>error &&
+       test_i18ngrep "failed to format default config value" error
+'
+
+test_expect_success 'does not allow --default without --get' '
+       test_must_fail git config --default=quux --unset a.section >output 2>&1 &&
+       test_i18ngrep "\-\-default is only applicable to" output
+'
+
+test_done
index 664a3a4e4e9b81d3e017c22414b0bbe2ef25b83a..e1fd0f0ca8b5d731d79ccca1d6e6140683a3665f 100755 (executable)
@@ -6,7 +6,7 @@
 test_description='Test git update-ref and basic ref logging'
 . ./test-lib.sh
 
-Z=$_z40
+Z=$ZERO_OID
 
 m=refs/heads/master
 n_dir=refs/heads/gu
@@ -457,6 +457,66 @@ test_expect_success 'git cat-file blob master@{2005-05-26 23:42}:F (expect OTHER
        test OTHER = $(git cat-file blob "master@{2005-05-26 23:42}:F")
 '
 
+# Test adding and deleting pseudorefs
+
+test_expect_success 'given old value for missing pseudoref, do not create' '
+       test_must_fail git update-ref PSEUDOREF $A $B 2>err &&
+       test_path_is_missing .git/PSEUDOREF &&
+       grep "could not read ref" err
+'
+
+test_expect_success 'create pseudoref' '
+       git update-ref PSEUDOREF $A &&
+       test $A = $(cat .git/PSEUDOREF)
+'
+
+test_expect_success 'overwrite pseudoref with no old value given' '
+       git update-ref PSEUDOREF $B &&
+       test $B = $(cat .git/PSEUDOREF)
+'
+
+test_expect_success 'overwrite pseudoref with correct old value' '
+       git update-ref PSEUDOREF $C $B &&
+       test $C = $(cat .git/PSEUDOREF)
+'
+
+test_expect_success 'do not overwrite pseudoref with wrong old value' '
+       test_must_fail git update-ref PSEUDOREF $D $E 2>err &&
+       test $C = $(cat .git/PSEUDOREF) &&
+       grep "unexpected object ID" err
+'
+
+test_expect_success 'delete pseudoref' '
+       git update-ref -d PSEUDOREF &&
+       test_path_is_missing .git/PSEUDOREF
+'
+
+test_expect_success 'do not delete pseudoref with wrong old value' '
+       git update-ref PSEUDOREF $A &&
+       test_must_fail git update-ref -d PSEUDOREF $B 2>err &&
+       test $A = $(cat .git/PSEUDOREF) &&
+       grep "unexpected object ID" err
+'
+
+test_expect_success 'delete pseudoref with correct old value' '
+       git update-ref -d PSEUDOREF $A &&
+       test_path_is_missing .git/PSEUDOREF
+'
+
+test_expect_success 'create pseudoref with old OID zero' '
+       git update-ref PSEUDOREF $A $Z &&
+       test $A = $(cat .git/PSEUDOREF)
+'
+
+test_expect_success 'do not overwrite pseudoref with old OID zero' '
+       test_when_finished git update-ref -d PSEUDOREF &&
+       test_must_fail git update-ref PSEUDOREF $B $Z 2>err &&
+       test $A = $(cat .git/PSEUDOREF) &&
+       grep "already exists" err
+'
+
+# Test --stdin
+
 a=refs/heads/a
 b=refs/heads/b
 c=refs/heads/c
index 9e782a8122f84939156e2bb4e0f871d86399f938..a4ebb0b65fecfada915209cfbc994a1b8ddce439 100755 (executable)
@@ -65,7 +65,7 @@ reset_to_sane
 test_expect_success 'symbolic-ref fails to delete real ref' '
        echo "fatal: Cannot delete refs/heads/foo, not a symbolic ref" >expect &&
        test_must_fail git symbolic-ref -d refs/heads/foo >actual 2>&1 &&
-       test_path_is_file .git/refs/heads/foo &&
+       git rev-parse --verify refs/heads/foo &&
        test_cmp expect actual
 '
 reset_to_sane
index e8115df5bad8d9ef46542cfd3c96c32da0bfa4ad..a74c38b5fb22a6d274c26ed008c6bec355801e34 100755 (executable)
@@ -4,7 +4,7 @@ test_description='test main ref store api'
 
 . ./test-lib.sh
 
-RUN="test-ref-store main"
+RUN="test-tool ref-store main"
 
 test_expect_success 'pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)' '
        test_commit one &&
@@ -45,7 +45,7 @@ test_expect_success 'rename_refs(master, new-master)' '
 '
 
 test_expect_success 'for_each_ref(refs/heads/)' '
-       $RUN for-each-ref refs/heads/ | cut -c 42- >actual &&
+       $RUN for-each-ref refs/heads/ | cut -d" " -f 2- >actual &&
        cat >expected <<-\EOF &&
        master 0x0
        new-master 0x0
@@ -71,7 +71,7 @@ test_expect_success 'verify_ref(new-master)' '
 '
 
 test_expect_success 'for_each_reflog()' '
-       $RUN for-each-reflog | sort | cut -c 42- >actual &&
+       $RUN for-each-reflog | sort -k2 | cut -c 42- >actual &&
        cat >expected <<-\EOF &&
        HEAD 0x1
        refs/heads/master 0x0
index c32d4cc4652a4496ce8fa6aa1c10c797ae7d760a..e093782cc37c495a122eb8676797b1988b828c29 100755 (executable)
@@ -4,7 +4,7 @@ test_description='test submodule ref store api'
 
 . ./test-lib.sh
 
-RUN="test-ref-store submodule:sub"
+RUN="test-tool ref-store submodule:sub"
 
 test_expect_success 'setup' '
        git init sub &&
index 8842d0329fb7947e811d4ffccff3bba9e8885d5d..4623ae15c4fd45df64b4acb94308e5ac4ca8f1f5 100755 (executable)
@@ -4,8 +4,8 @@ test_description='test worktree ref store api'
 
 . ./test-lib.sh
 
-RWT="test-ref-store worktree:wt"
-RMAIN="test-ref-store worktree:main"
+RWT="test-tool ref-store worktree:wt"
+RMAIN="test-tool ref-store worktree:main"
 
 test_expect_success 'setup' '
        test_commit first &&
@@ -50,13 +50,13 @@ test_expect_success 'create_symref(FOO, refs/heads/master)' '
 '
 
 test_expect_success 'for_each_reflog()' '
-       echo $_z40 > .git/logs/PSEUDO-MAIN &&
+       echo $ZERO_OID > .git/logs/PSEUDO-MAIN &&
        mkdir -p     .git/logs/refs/bisect &&
-       echo $_z40 > .git/logs/refs/bisect/random &&
+       echo $ZERO_OID > .git/logs/refs/bisect/random &&
 
-       echo $_z40 > .git/worktrees/wt/logs/PSEUDO-WT &&
+       echo $ZERO_OID > .git/worktrees/wt/logs/PSEUDO-WT &&
        mkdir -p     .git/worktrees/wt/logs/refs/bisect &&
-       echo $_z40 > .git/worktrees/wt/logs/refs/bisect/wt-random &&
+       echo $ZERO_OID > .git/worktrees/wt/logs/refs/bisect/wt-random &&
 
        $RWT for-each-reflog | cut -c 42- | sort >actual &&
        cat >expected <<-\EOF &&
index 6ac7734d79be21a82feeadff10064bb4ca7ad47b..596907758d5d47ae8026098a2ce4acd8c01df6aa 100755 (executable)
@@ -10,6 +10,7 @@ test_expect_success 'setup' '
        git commit -m one
 '
 
+commit=$(git rev-parse --short HEAD)
 cat >expect <<'EOF'
 Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
 Reflog message: commit (initial): one
@@ -20,8 +21,8 @@ test_expect_success 'log -g shows reflog headers' '
        test_cmp expect actual
 '
 
-cat >expect <<'EOF'
-e46513e HEAD@{0}: commit (initial): one
+cat >expect <<EOF
+$commit HEAD@{0}: commit (initial): one
 EOF
 test_expect_success 'oneline reflog format' '
        git log -g -1 --oneline >actual &&
@@ -33,8 +34,8 @@ test_expect_success 'reflog default format' '
        test_cmp expect actual
 '
 
-cat >expect <<'EOF'
-commit e46513e
+cat >expect <<EOF
+commit $commit
 Reflog: HEAD@{0} (C O Mitter <committer@example.com>)
 Reflog message: commit (initial): one
 Author: A U Thor <author@example.com>
@@ -56,8 +57,8 @@ test_expect_success 'using @{now} syntax shows reflog date (multiline)' '
        test_cmp expect actual
 '
 
-cat >expect <<'EOF'
-e46513e HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
+cat >expect <<EOF
+$commit HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
 EOF
 test_expect_success 'using @{now} syntax shows reflog date (oneline)' '
        git log -g -1 --oneline HEAD@{now} >actual &&
@@ -82,8 +83,8 @@ test_expect_success 'using --date= shows reflog date (multiline)' '
        test_cmp expect actual
 '
 
-cat >expect <<'EOF'
-e46513e HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
+cat >expect <<EOF
+$commit HEAD@{Thu Apr 7 15:13:13 2005 -0700}: commit (initial): one
 EOF
 test_expect_success 'using --date= shows reflog date (oneline)' '
        git log -g -1 --oneline --date=default >actual &&
@@ -109,8 +110,8 @@ test_expect_success 'log.date does not invoke "--date" magic (multiline)' '
        test_cmp expect actual
 '
 
-cat >expect <<'EOF'
-e46513e HEAD@{0}: commit (initial): one
+cat >expect <<EOF
+$commit HEAD@{0}: commit (initial): one
 EOF
 test_expect_success 'log.date does not invoke "--date" magic (oneline)' '
        test_config log.date raw &&
index 33c955f912418cc0ec971c47ba73a3c561ca2d06..561a9b5c786dbbc5a6d73be376d74c79ad2e6686 100755 (executable)
@@ -714,7 +714,7 @@ test_expect_success 'fsck notices dangling objects' '
 
 test_expect_success 'fsck $name notices bogus $name' '
        test_must_fail git fsck bogus &&
-       test_must_fail git fsck $_z40
+       test_must_fail git fsck $ZERO_OID
 '
 
 test_expect_success 'bogus head does not fallback to all heads' '
@@ -724,7 +724,7 @@ test_expect_success 'bogus head does not fallback to all heads' '
        blob=$(git rev-parse :foo) &&
        test_when_finished "git rm --cached foo" &&
        remove_object $blob &&
-       test_must_fail git fsck $_z40 >out 2>&1 &&
+       test_must_fail git fsck $ZERO_OID >out 2>&1 &&
        ! grep $blob out
 '
 
index b06210ec5e8ffa30b59314b1c79ebc9bdb8f6476..afcdfafe45521872b0e2f1648da782c61d0cc1d5 100755 (executable)
@@ -238,10 +238,10 @@ test_expect_success '_gently() groks relative GIT_DIR & GIT_WORK_TREE' '
 
 test_expect_success 'diff-index respects work tree under .git dir' '
        cat >diff-index-cached.expected <<-EOF &&
-       :000000 100644 $_z40 $EMPTY_BLOB A      sub/dir/tracked
+       :000000 100644 $ZERO_OID $EMPTY_BLOB A  sub/dir/tracked
        EOF
        cat >diff-index.expected <<-EOF &&
-       :000000 100644 $_z40 $_z40 A    sub/dir/tracked
+       :000000 100644 $ZERO_OID $ZERO_OID A    sub/dir/tracked
        EOF
 
        (
@@ -257,7 +257,7 @@ test_expect_success 'diff-index respects work tree under .git dir' '
 
 test_expect_success 'diff-files respects work tree under .git dir' '
        cat >diff-files.expected <<-EOF &&
-       :100644 100644 $EMPTY_BLOB $_z40 M      sub/dir/tracked
+       :100644 100644 $EMPTY_BLOB $ZERO_OID M  sub/dir/tracked
        EOF
 
        (
@@ -341,7 +341,7 @@ test_expect_success 'make_relative_path handles double slashes in GIT_DIR' '
 
 test_expect_success 'relative $GIT_WORK_TREE and git subprocesses' '
        GIT_DIR=repo.git GIT_WORK_TREE=repo.git/work \
-       test-subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
+       test-tool subprocess --setup-work-tree rev-parse --show-toplevel >actual &&
        echo "$(pwd)/repo.git/work" >expected &&
        test_cmp expected actual
 '
@@ -360,7 +360,7 @@ test_expect_success 'GIT_DIR set (1)' '
        (
                cd work &&
                GIT_DIR=../gitfile git rev-parse --git-common-dir >actual &&
-               test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
+               test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
                test_cmp expect actual
        )
 '
@@ -371,7 +371,7 @@ test_expect_success 'GIT_DIR set (2)' '
        (
                cd work &&
                GIT_DIR=../gitfile git rev-parse --git-common-dir >actual &&
-               test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
+               test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
                test_cmp expect actual
        )
 '
@@ -382,7 +382,7 @@ test_expect_success 'Auto discovery' '
        (
                cd work &&
                git rev-parse --git-common-dir >actual &&
-               test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
+               test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
                test_cmp expect actual &&
                echo haha >data1 &&
                git add data1 &&
@@ -400,7 +400,7 @@ test_expect_success '$GIT_DIR/common overrides core.worktree' '
        (
                cd work &&
                git rev-parse --git-common-dir >actual &&
-               test-path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
+               test-tool path-utils real_path "$TRASH_DIRECTORY/repo.git" >expect &&
                test_cmp expect actual &&
                echo haha >data2 &&
                git add data2 &&
@@ -431,4 +431,16 @@ test_expect_success 'error out gracefully on invalid $GIT_WORK_TREE' '
        )
 '
 
+test_expect_success 'refs work with relative gitdir and work tree' '
+       git init relative &&
+       git -C relative commit --allow-empty -m one &&
+       git -C relative commit --allow-empty -m two &&
+
+       GIT_DIR=relative/.git GIT_WORK_TREE=relative git reset HEAD^ &&
+
+       git -C relative log -1 --format=%s >actual &&
+       echo one >expect &&
+       test_cmp expect actual
+'
+
 test_done
index 2ce68cc277a1ed742ce7b644de31a4a847e3529b..93c77eac45321cb24823431c4d89dc393049edbf 100755 (executable)
@@ -209,8 +209,9 @@ test_expect_success '@{u} works when tracking a local branch' '
        test refs/heads/master = "$(full_name @{u})"
 '
 
+commit=$(git rev-parse HEAD)
 cat >expect <<EOF
-commit 8f489d01d0cc65c3b0f09504ec50b5ed02a70bd5
+commit $commit
 Reflog: master@{0} (C O Mitter <committer@example.com>)
 Reflog message: branch: Created from HEAD
 Author: A U Thor <author@example.com>
@@ -224,7 +225,7 @@ test_expect_success 'log -g other@{u}' '
 '
 
 cat >expect <<EOF
-commit 8f489d01d0cc65c3b0f09504ec50b5ed02a70bd5
+commit $commit
 Reflog: master@{Thu Apr 7 15:17:13 2005 -0700} (C O Mitter <committer@example.com>)
 Reflog message: branch: Created from HEAD
 Author: A U Thor <author@example.com>
index e6854b828e2e68ad217721eb6139970b7c5958c0..972bd9c7859f52ac043b0a45500590fe182d4b6a 100755 (executable)
@@ -238,7 +238,6 @@ test_expect_success '#0: nonbare repo, no explicit configuration' '
 '
 
 test_expect_success '#1: GIT_WORK_TREE without explicit GIT_DIR is accepted' '
-       mkdir -p wt &&
        try_repo 1 "$here" unset unset "" unset \
                "$here/1/.git" "$here" "$here" 1/ \
                "$here/1/.git" "$here" "$here" 1/sub/ 2>message &&
index 711704ba5a052b15d94ff1ce958ada3fb86530a9..96fe3754c8c96fd65286d4eea44cb65b0edde343 100755 (executable)
@@ -22,6 +22,12 @@ one tagged as v1.0.0.  They all have one regular file each.
 
 . ./test-lib.sh
 
+if ! test_have_prereq SHA1
+then
+       skip_all='not using SHA-1 for objects'
+       test_done
+fi
+
 test_expect_success 'blob and tree' '
        test_tick &&
        (
@@ -361,4 +367,25 @@ test_expect_success 'core.disambiguate does not override context' '
                git -c core.disambiguate=committish rev-parse $sha1^{tree}
 '
 
+test_expect_success C_LOCALE_OUTPUT 'ambiguous commits are printed by type first, then hash order' '
+       test_must_fail git rev-parse 0000 2>stderr &&
+       grep ^hint: stderr >hints &&
+       grep 0000 hints >objects &&
+       cat >expected <<-\EOF &&
+       tag
+       commit
+       tree
+       blob
+       EOF
+       awk "{print \$3}" <objects >objects.types &&
+       uniq <objects.types >objects.types.uniq &&
+       test_cmp expected objects.types.uniq &&
+       for type in tag commit tree blob
+       do
+               grep $type objects >$type.objects &&
+               sort $type.objects >$type.objects.sorted &&
+               test_cmp $type.objects.sorted $type.objects
+       done
+'
+
 test_done
index 079d2411450ca960d3d82fb9c7d59921c4cbe60a..c4422312f4e482e38172b1ac8b87e29d8708af2e 100755 (executable)
@@ -68,7 +68,7 @@ test_expect_success 'GIT_INDEX_VERSION takes precedence over config' '
                git config --add index.version 2 &&
                git add a 2>&1 &&
                echo 4 >expect &&
-               test-index-version <.git/index >actual &&
+               test-tool index-version <.git/index >actual &&
                test_cmp expect actual
        )
 '
index 73cc9323cdc2a40105bd6218983381b8a72b381a..4171f1e14103135ef3e47a3b3df19d5a285b4a8a 100755 (executable)
@@ -4,7 +4,7 @@ test_description='test handling of bogus index entries'
 . ./test-lib.sh
 
 test_expect_success 'create tree with null sha1' '
-       tree=$(printf "160000 commit $_z40\\tbroken\\n" | git mktree)
+       tree=$(printf "160000 commit $ZERO_OID\\tbroken\\n" | git mktree)
 '
 
 test_expect_success 'read-tree refuses to read null sha1' '
index a66936fe9bde2ba20ab0e57400b6286b0710212a..1e81b33b2e3a23a135c9b9440787a6e0c0deaa22 100755 (executable)
@@ -11,8 +11,8 @@ sane_unset GIT_FSMONITOR_TEST
 test_expect_success 'enable split index' '
        git config splitIndex.maxPercentChange 100 &&
        git update-index --split-index &&
-       test-dump-split-index .git/index >actual &&
-       indexversion=$(test-index-version <.git/index) &&
+       test-tool dump-split-index .git/index >actual &&
+       indexversion=$(test-tool index-version <.git/index) &&
        if test "$indexversion" = "4"
        then
                own=432ef4b63f32193984f339431fd50ca796493569
@@ -39,7 +39,7 @@ test_expect_success 'add one file' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        base $base
        100644 $EMPTY_BLOB 0    one
@@ -57,8 +57,8 @@ test_expect_success 'disable split index' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       BASE=$(test-dump-split-index .git/index | grep "^own" | sed "s/own/base/") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^own" | sed "s/own/base/") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        not a split index
        EOF
@@ -73,7 +73,7 @@ test_expect_success 'enable split index again, "one" now belongs to base index"'
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -91,7 +91,7 @@ test_expect_success 'modify original file, base index untouched' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        q_to_tab >expect <<-EOF &&
        $BASE
        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
@@ -111,7 +111,7 @@ test_expect_success 'add another file, which stays index' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        q_to_tab >expect <<-EOF &&
        $BASE
        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
@@ -130,7 +130,7 @@ test_expect_success 'remove file not in base index' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        q_to_tab >expect <<-EOF &&
        $BASE
        100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
@@ -147,7 +147,7 @@ test_expect_success 'remove file in base index' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -165,7 +165,7 @@ test_expect_success 'add original file back' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        100644 $EMPTY_BLOB 0    one
@@ -195,7 +195,7 @@ test_expect_success 'unify index, two files remain' '
        EOF
        test_cmp ls-files.expect ls-files.actual &&
 
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        not a split index
        EOF
@@ -229,8 +229,8 @@ test_expect_success 'set core.splitIndex config variable to true' '
        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
        EOF
        test_cmp ls-files.expect ls-files.actual &&
-       BASE=$(test-dump-split-index .git/index | grep "^base") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -248,7 +248,7 @@ test_expect_success 'set core.splitIndex config variable to false' '
        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       two
        EOF
        test_cmp ls-files.expect ls-files.actual &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        not a split index
        EOF
@@ -259,8 +259,8 @@ test_expect_success 'set core.splitIndex config variable to true' '
        git config core.splitIndex true &&
        : >three &&
        git update-index --add three &&
-       BASE=$(test-dump-split-index .git/index | grep "^base") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -269,7 +269,7 @@ test_expect_success 'set core.splitIndex config variable to true' '
        test_cmp expect actual &&
        : >four &&
        git update-index --add four &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       four
@@ -283,8 +283,8 @@ test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
        git config --unset splitIndex.maxPercentChange &&
        : >five &&
        git update-index --add five &&
-       BASE=$(test-dump-split-index .git/index | grep "^base") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -293,7 +293,7 @@ test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
        test_cmp expect actual &&
        : >six &&
        git update-index --add six &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       six
@@ -307,8 +307,8 @@ test_expect_success 'check splitIndex.maxPercentChange set to 0' '
        git config splitIndex.maxPercentChange 0 &&
        : >seven &&
        git update-index --add seven &&
-       BASE=$(test-dump-split-index .git/index | grep "^base") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -317,8 +317,8 @@ test_expect_success 'check splitIndex.maxPercentChange set to 0' '
        test_cmp expect actual &&
        : >eight &&
        git update-index --add eight &&
-       BASE=$(test-dump-split-index .git/index | grep "^base") &&
-       test-dump-split-index .git/index | sed "/^own/d" >actual &&
+       BASE=$(test-tool dump-split-index .git/index | grep "^base") &&
+       test-tool dump-split-index .git/index | sed "/^own/d" >actual &&
        cat >expect <<-EOF &&
        $BASE
        replacements:
@@ -332,12 +332,12 @@ test_expect_success 'shared index files expire after 2 weeks by default' '
        git update-index --add ten &&
        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
        just_under_2_weeks_ago=$((5-14*86400)) &&
-       test-chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
        : >eleven &&
        git update-index --add eleven &&
        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
        just_over_2_weeks_ago=$((-1-14*86400)) &&
-       test-chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
        : >twelve &&
        git update-index --add twelve &&
        test $(ls .git/sharedindex.* | wc -l) -le 2
@@ -345,12 +345,12 @@ test_expect_success 'shared index files expire after 2 weeks by default' '
 
 test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
        git config splitIndex.sharedIndexExpire "16.days.ago" &&
-       test-chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
        : >thirteen &&
        git update-index --add thirteen &&
        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
        just_over_16_days_ago=$((-1-16*86400)) &&
-       test-chmtime =$just_over_16_days_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_over_16_days_ago .git/sharedindex.* &&
        : >fourteen &&
        git update-index --add fourteen &&
        test $(ls .git/sharedindex.* | wc -l) -le 2
@@ -359,13 +359,13 @@ test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
 test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
        git config splitIndex.sharedIndexExpire never &&
        just_10_years_ago=$((-365*10*86400)) &&
-       test-chmtime =$just_10_years_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_10_years_ago .git/sharedindex.* &&
        : >fifteen &&
        git update-index --add fifteen &&
        test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
        git config splitIndex.sharedIndexExpire now &&
        just_1_second_ago=-1 &&
-       test-chmtime =$just_1_second_ago .git/sharedindex.* &&
+       test-tool chmtime =$just_1_second_ago .git/sharedindex.* &&
        : >sixteen &&
        git update-index --add sixteen &&
        test $(ls .git/sharedindex.* | wc -l) -le 2
@@ -426,7 +426,7 @@ test_expect_success 'writing split index with null sha1 does not write cache tre
        git commit -m "commit" &&
        {
                git ls-tree HEAD &&
-               printf "160000 commit $_z40\\tbroken\\n"
+               printf "160000 commit $ZERO_OID\\tbroken\\n"
        } >broken-tree &&
        echo "add broken entry" >msg &&
 
@@ -435,7 +435,7 @@ test_expect_success 'writing split index with null sha1 does not write cache tre
        commit=$(git commit-tree $tree -p HEAD <msg) &&
        git update-ref HEAD "$commit" &&
        GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
-       (test-dump-cache-tree >cache-tree.out || true) &&
+       (test-tool dump-cache-tree >cache-tree.out || true) &&
        test_line_count = 0 cache-tree.out
 '
 
index c5501b008c8f56ac0712d9f475ebc460a0d4eea4..0e8d56aa7631cb30eebd468abe8d93f720d92913 100755 (executable)
@@ -15,7 +15,7 @@ test_expect_success 'checkout should not start branch from a tree' '
 '
 
 test_expect_success 'checkout master from invalid HEAD' '
-       echo $_z40 >.git/HEAD &&
+       echo $ZERO_OID >.git/HEAD &&
        git checkout master --
 '
 
index bb4f2e0c631f1de7421f50b9fa64f11276fe9645..1fa670625c5be87294eec9c5fe86bf2defff2ce2 100755 (executable)
@@ -189,8 +189,12 @@ test_expect_success 'no advice given for explicit detached head state' '
 # Detached HEAD tests for GIT_PRINT_SHA1_ELLIPSIS (new format)
 test_expect_success 'describe_detached_head prints no SHA-1 ellipsis when not asked to' "
 
+       commit=$(git rev-parse --short=12 master^) &&
+       commit2=$(git rev-parse --short=12 master~2) &&
+       commit3=$(git rev-parse --short=12 master~3) &&
+
        # The first detach operation is more chatty than the following ones.
-       cat >1st_detach <<-'EOF' &&
+       cat >1st_detach <<-EOF &&
        Note: checking out 'HEAD^'.
 
        You are in 'detached HEAD' state. You can look around, make experimental
@@ -202,18 +206,18 @@ test_expect_success 'describe_detached_head prints no SHA-1 ellipsis when not as
 
          git checkout -b <new-branch-name>
 
-       HEAD is now at 7c7cd714e262 three
+       HEAD is now at \$commit three
        EOF
 
        # The remaining ones just show info about previous and current HEADs.
-       cat >2nd_detach <<-'EOF' &&
-       Previous HEAD position was 7c7cd714e262 three
-       HEAD is now at 139b20d8e6c5 two
+       cat >2nd_detach <<-EOF &&
+       Previous HEAD position was \$commit three
+       HEAD is now at \$commit2 two
        EOF
 
-       cat >3rd_detach <<-'EOF' &&
-       Previous HEAD position was 139b20d8e6c5 two
-       HEAD is now at d79ce1670bdc one
+       cat >3rd_detach <<-EOF &&
+       Previous HEAD position was \$commit2 two
+       HEAD is now at \$commit3 one
        EOF
 
        reset &&
@@ -261,8 +265,12 @@ test_expect_success 'describe_detached_head prints no SHA-1 ellipsis when not as
 # Detached HEAD tests for GIT_PRINT_SHA1_ELLIPSIS (old format)
 test_expect_success 'describe_detached_head does print SHA-1 ellipsis when asked to' "
 
+       commit=$(git rev-parse --short=12 master^) &&
+       commit2=$(git rev-parse --short=12 master~2) &&
+       commit3=$(git rev-parse --short=12 master~3) &&
+
        # The first detach operation is more chatty than the following ones.
-       cat >1st_detach <<-'EOF' &&
+       cat >1st_detach <<-EOF &&
        Note: checking out 'HEAD^'.
 
        You are in 'detached HEAD' state. You can look around, make experimental
@@ -274,18 +282,18 @@ test_expect_success 'describe_detached_head does print SHA-1 ellipsis when asked
 
          git checkout -b <new-branch-name>
 
-       HEAD is now at 7c7cd714e262... three
+       HEAD is now at \$commit... three
        EOF
 
        # The remaining ones just show info about previous and current HEADs.
-       cat >2nd_detach <<-'EOF' &&
-       Previous HEAD position was 7c7cd714e262... three
-       HEAD is now at 139b20d8e6c5... two
+       cat >2nd_detach <<-EOF &&
+       Previous HEAD position was \$commit... three
+       HEAD is now at \$commit2... two
        EOF
 
-       cat >3rd_detach <<-'EOF' &&
-       Previous HEAD position was 139b20d8e6c5... two
-       HEAD is now at d79ce1670bdc... one
+       cat >3rd_detach <<-EOF &&
+       Previous HEAD position was \$commit2... two
+       HEAD is now at \$commit3... one
        EOF
 
        reset &&
index f46d0499bc6ea95236f7ca05060b8f8fbbdbbc50..fc3eb43b890977bf793f6ed70e6d6caed2902407 100755 (executable)
@@ -68,13 +68,13 @@ test_expect_success 'do not touch files that are already up-to-date' '
        git add file1 file2 &&
        git commit -m base &&
        echo modified >file1 &&
-       test-chmtime =1000000000 file2 &&
+       test-tool chmtime =1000000000 file2 &&
        git update-index -q --refresh &&
        git checkout HEAD -- file1 file2 &&
        echo one >expect &&
        test_cmp expect file1 &&
-       echo "1000000000        file2" >expect &&
-       test-chmtime -v +0 file2 >actual &&
+       echo "1000000000" >expect &&
+       test-tool chmtime --get file2 >actual &&
        test_cmp expect actual
 '
 
index d0d2e4f7ec3310ec51da7144fa87151129f393c0..d2e49f763263333e8e269051686d3b8b2cae44ba 100755 (executable)
@@ -198,13 +198,25 @@ test_expect_success '"add" with <branch> omitted' '
        test_cmp_rev HEAD bat
 '
 
-test_expect_success '"add" auto-vivify does not clobber existing branch' '
-       test_commit c1 &&
-       test_commit c2 &&
-       git branch precious HEAD~1 &&
-       test_must_fail git worktree add precious &&
-       test_cmp_rev HEAD~1 precious &&
-       test_path_is_missing precious
+test_expect_success '"add" checks out existing branch of dwimd name' '
+       git branch dwim HEAD~1 &&
+       git worktree add dwim &&
+       test_cmp_rev HEAD~1 dwim &&
+       (
+               cd dwim &&
+               test_cmp_rev HEAD dwim
+       )
+'
+
+test_expect_success '"add <path>" dwim fails with checked out branch' '
+       git checkout -b test-branch &&
+       test_must_fail git worktree add test-branch &&
+       test_path_is_missing test-branch
+'
+
+test_expect_success '"add --force" with existing dwimd name doesnt die' '
+       git checkout test-branch &&
+       git worktree add --force test-branch
 '
 
 test_expect_success '"add" no auto-vivify with --detach and <branch> omitted' '
@@ -465,7 +477,7 @@ post_checkout_hook () {
 test_expect_success '"add" invokes post-checkout hook (branch)' '
        post_checkout_hook &&
        {
-               echo $_z40 $(git rev-parse HEAD) 1 &&
+               echo $ZERO_OID $(git rev-parse HEAD) 1 &&
                echo $(pwd)/.git/worktrees/gumby &&
                echo $(pwd)/gumby
        } >hook.expect &&
@@ -476,7 +488,7 @@ test_expect_success '"add" invokes post-checkout hook (branch)' '
 test_expect_success '"add" invokes post-checkout hook (detached)' '
        post_checkout_hook &&
        {
-               echo $_z40 $(git rev-parse HEAD) 1 &&
+               echo $ZERO_OID $(git rev-parse HEAD) 1 &&
                echo $(pwd)/.git/worktrees/grumpy &&
                echo $(pwd)/grumpy
        } >hook.expect &&
@@ -494,7 +506,7 @@ test_expect_success '"add --no-checkout" suppresses post-checkout hook' '
 test_expect_success '"add" in other worktree invokes post-checkout hook' '
        post_checkout_hook &&
        {
-               echo $_z40 $(git rev-parse HEAD) 1 &&
+               echo $ZERO_OID $(git rev-parse HEAD) 1 &&
                echo $(pwd)/.git/worktrees/guppy &&
                echo $(pwd)/guppy
        } >hook.expect &&
@@ -506,7 +518,7 @@ test_expect_success '"add" in bare repo invokes post-checkout hook' '
        rm -rf bare &&
        git clone --bare . bare &&
        {
-               echo $_z40 $(git --git-dir=bare rev-parse HEAD) 1 &&
+               echo $ZERO_OID $(git --git-dir=bare rev-parse HEAD) 1 &&
                echo $(pwd)/bare/worktrees/goozy &&
                echo $(pwd)/goozy
        } >hook.expect &&
index a0f1e3bb800ec6943648eeffb9e7ca84e328fa41..b7d6d5d45adf6067ab2f39801f658f778f9b2855 100755 (executable)
@@ -78,10 +78,9 @@ test_expect_success 'not prune locked checkout' '
 
 test_expect_success 'not prune recent checkouts' '
        test_when_finished rm -r .git/worktrees &&
-       mkdir zz &&
-       mkdir -p .git/worktrees/jlm &&
-       echo "$(pwd)"/zz >.git/worktrees/jlm/gitdir &&
-       rmdir zz &&
+       git worktree add jlm HEAD &&
+       test -d .git/worktrees/jlm &&
+       rm -rf jlm &&
        git worktree prune --verbose --expire=2.days.ago &&
        test -d .git/worktrees/jlm
 '
index 720063bf0d09bb8c577b78e099187abfc7da71b0..bb6fb9b12cb7f41cea671a7df830ccc97c592e4f 100755 (executable)
@@ -116,7 +116,7 @@ test_expect_success 'broken main worktree still at the top' '
                git worktree add linked &&
                cat >expected <<-EOF &&
                worktree $(pwd)
-               HEAD $_z40
+               HEAD $ZERO_OID
 
                EOF
                cd linked &&
index 5d5b3632ba0a7cf5364ab4db1df8ca7ea285b4d5..5f7d45b7b7fa91a497d6f8d96a7235fc0024919e 100755 (executable)
@@ -72,12 +72,11 @@ test_expect_success 'move locked worktree' '
 '
 
 test_expect_success 'move worktree' '
-       toplevel="$(pwd)" &&
        git worktree move source destination &&
        test_path_is_missing source &&
        git worktree list --porcelain >out &&
-       grep "^worktree.*/destination" out &&
-       ! grep "^worktree.*/source" out &&
+       grep "^worktree.*/destination$" out &&
+       ! grep "^worktree.*/source$" out &&
        git -C destination log --format=%s >actual2 &&
        echo init >expected2 &&
        test_cmp expected2 actual2
@@ -93,7 +92,7 @@ test_expect_success 'move worktree to another dir' '
        test_when_finished "git worktree move some-dir/destination destination" &&
        test_path_is_missing destination &&
        git worktree list --porcelain >out &&
-       grep "^worktree.*/some-dir/destination" out &&
+       grep "^worktree.*/some-dir/destination$" out &&
        git -C some-dir/destination log --format=%s >actual2 &&
        echo init >expected2 &&
        test_cmp expected2 actual2
index c8bce8c2e4314aaf466019438818293102c12c9c..685ec45639a5e9a2bf929e10aa30976e9a4c456b 100755 (executable)
@@ -8,19 +8,20 @@ test_description='git update-index --again test.
 
 . ./test-lib.sh
 
-cat > expected <<\EOF
-100644 3b18e512dba79e4c8300dd08aeb37f8e728b8dad 0      file1
-100644 9db8893856a8a02eaa73470054b7c1c5a7c82e47 0      file2
-EOF
-test_expect_success 'update-index --add' \
-       'echo hello world >file1 &&
-        echo goodbye people >file2 &&
-        git update-index --add file1 file2 &&
-        git ls-files -s >current &&
-        cmp current expected'
+test_expect_success 'update-index --add' '
+       echo hello world >file1 &&
+       echo goodbye people >file2 &&
+       git update-index --add file1 file2 &&
+       git ls-files -s >current &&
+       cat >expected <<-EOF &&
+       100644 $(git hash-object file1) 0       file1
+       100644 $(git hash-object file2) 0       file2
+       EOF
+       cmp current expected
+'
 
-test_expect_success 'update-index --again' \
-       'rm -f file1 &&
+test_expect_success 'update-index --again' '
+       rm -f file1 &&
        echo hello everybody >file2 &&
        if git update-index --again
        then
@@ -29,25 +30,23 @@ test_expect_success 'update-index --again' \
        else
                echo happy - failed as expected
        fi &&
-        git ls-files -s >current &&
-        cmp current expected'
+       git ls-files -s >current &&
+       cmp current expected
+'
 
-cat > expected <<\EOF
-100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0      file2
-EOF
-test_expect_success 'update-index --remove --again' \
-       'git update-index --remove --again &&
-        git ls-files -s >current &&
-        cmp current expected'
+test_expect_success 'update-index --remove --again' '
+       git update-index --remove --again &&
+       git ls-files -s >current &&
+       cat >expected <<-EOF &&
+       100644 $(git hash-object file2) 0       file2
+       EOF
+       cmp current expected
+'
 
 test_expect_success 'first commit' 'git commit -m initial'
 
-cat > expected <<\EOF
-100644 53ab446c3f4e42ce9bb728a0ccb283a101be4979 0      dir1/file3
-100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0      file2
-EOF
-test_expect_success 'update-index again' \
-       'mkdir -p dir1 &&
+test_expect_success 'update-index again' '
+       mkdir -p dir1 &&
        echo hello world >dir1/file3 &&
        echo goodbye people >file2 &&
        git update-index --add file2 dir1/file3 &&
@@ -55,30 +54,38 @@ test_expect_success 'update-index again' \
        echo happy >dir1/file3 &&
        git update-index --again &&
        git ls-files -s >current &&
-       cmp current expected'
+       cat >expected <<-EOF &&
+       100644 $(git hash-object dir1/file3) 0  dir1/file3
+       100644 $(git hash-object file2) 0       file2
+       EOF
+       cmp current expected
+'
 
-cat > expected <<\EOF
-100644 d7fb3f695f06c759dbf3ab00046e7cc2da22d10f 0      dir1/file3
-100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0      file2
-EOF
-test_expect_success 'update-index --update from subdir' \
-       'echo not so happy >file2 &&
+file2=$(git hash-object file2)
+test_expect_success 'update-index --update from subdir' '
+       echo not so happy >file2 &&
        (cd dir1 &&
        cat ../file2 >file3 &&
        git update-index --again
        ) &&
        git ls-files -s >current &&
-       cmp current expected'
+       cat >expected <<-EOF &&
+       100644 $(git hash-object dir1/file3) 0  dir1/file3
+       100644 $file2 0 file2
+       EOF
+       test_cmp current expected
+'
 
-cat > expected <<\EOF
-100644 594fb5bb1759d90998e2bf2a38261ae8e243c760 0      dir1/file3
-100644 0f1ae1422c2bf43f117d3dbd715c988a9ed2103f 0      file2
-EOF
-test_expect_success 'update-index --update with pathspec' \
-       'echo very happy >file2 &&
+test_expect_success 'update-index --update with pathspec' '
+       echo very happy >file2 &&
        cat file2 >dir1/file3 &&
        git update-index --again dir1/ &&
        git ls-files -s >current &&
-       cmp current expected'
+       cat >expected <<-EOF &&
+       100644 $(git hash-object dir1/file3) 0  dir1/file3
+       100644 $file2 0 file2
+       EOF
+       cmp current expected
+'
 
 test_done
index cc830da58d920718b7b0a990a359afa9dd783b4c..7e2e7dd4ae5842bc49ccaf5dc116deb3b3d6b993 100755 (executable)
@@ -33,7 +33,7 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'index is at version 2' '
-       test "$(test-index-version < .git/index)" = 2
+       test "$(test-tool index-version < .git/index)" = 2
 '
 
 test_expect_success 'update-index --skip-worktree' '
@@ -42,7 +42,7 @@ test_expect_success 'update-index --skip-worktree' '
 '
 
 test_expect_success 'index is at version 3 after having some skip-worktree entries' '
-       test "$(test-index-version < .git/index)" = 3
+       test "$(test-tool index-version < .git/index)" = 3
 '
 
 test_expect_success 'ls-files -t' '
@@ -55,7 +55,7 @@ test_expect_success 'update-index --no-skip-worktree' '
 '
 
 test_expect_success 'index version is back to 2 when there is no skip-worktree entry' '
-       test "$(test-index-version < .git/index)" = 2
+       test "$(test-tool index-version < .git/index)" = 2
 '
 
 test_done
index 32ac6e09bdc81acfb8de5cf887302794d20c8ece..2242cd098ec4ee0b278c008220d8c2a678b174c7 100755 (executable)
@@ -37,7 +37,7 @@ test_expect_success '--cacheinfo does not accept blob null sha1' '
        echo content >file &&
        git add file &&
        git rev-parse :file >expect &&
-       test_must_fail git update-index --cacheinfo 100644 $_z40 file &&
+       test_must_fail git update-index --cacheinfo 100644 $ZERO_OID file &&
        git rev-parse :file >actual &&
        test_cmp expect actual
 '
@@ -47,7 +47,7 @@ test_expect_success '--cacheinfo does not accept gitlink null sha1' '
        (cd submodule && test_commit foo) &&
        git add submodule &&
        git rev-parse :submodule >expect &&
-       test_must_fail git update-index --cacheinfo 160000 $_z40 submodule &&
+       test_must_fail git update-index --cacheinfo 160000 $ZERO_OID submodule &&
        git rev-parse :submodule >actual &&
        test_cmp expect actual
 '
@@ -85,9 +85,9 @@ test_expect_success '--chmod=+x and chmod=-x in the same argument list' '
        >B &&
        git add A B &&
        git update-index --chmod=+x A --chmod=-x B &&
-       cat >expect <<-\EOF &&
-       100755 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       A
-       100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0       B
+       cat >expect <<-EOF &&
+       100755 $EMPTY_BLOB 0    A
+       100644 $EMPTY_BLOB 0    B
        EOF
        git ls-files --stage A B >actual &&
        test_cmp expect actual
index 954fc51e5b560af918661a0ee051521a43f4efba..a4eec0a3465bc02fb5c88e007ee4e32aa9c2794f 100755 (executable)
@@ -75,35 +75,35 @@ test_expect_success modify '
                git ls-tree -r HEAD |
                sed -e "s/^/:/" -e "
                        /       caskly/{
-                               s/      caskly/ $_z40 D&/
+                               s/      caskly/ $ZERO_OID D&/
                                s/blob/000000/
                        }
                        /       nitfol/{
-                               s/      nitfol/ $_z40 $T_letter&/
+                               s/      nitfol/ $ZERO_OID $T_letter&/
                                s/blob/100644/
                        }
                        /       rezrov.bozbar/{
-                               s/      rezrov.bozbar/ $_z40 D&/
+                               s/      rezrov.bozbar/ $ZERO_OID D&/
                                s/blob/000000/
                        }
                        /       xyzzy/{
-                               s/      xyzzy/ $_z40 D&/
+                               s/      xyzzy/ $ZERO_OID D&/
                                s/blob/000000/
                        }
                        /       yomin/{
-                           s/  yomin/ $_z40 T&/
+                           s/  yomin/ $ZERO_OID T&/
                                s/blob/160000/
                        }
                "
        } >expect &&
        {
                cat expect
-               echo ":100644 160000 $_empty $_z40 T    yonk"
-               echo ":100644 000000 $_empty $_z40 D    zifmia"
+               echo ":100644 160000 $_empty $ZERO_OID T        yonk"
+               echo ":100644 000000 $_empty $ZERO_OID D        zifmia"
        } >expect-files &&
        {
                cat expect
-               echo ":000000 160000 $_z40 $_z40 A      yonk"
+               echo ":000000 160000 $ZERO_OID $ZERO_OID A      yonk"
        } >expect-index &&
        {
                echo "100644 $_empty 0  nitfol"
index 78236dc7d851663c4488e7acae5e6997edd35f1c..04d840a5448567bf438688c4aebd7e94d63da4ec 100755 (executable)
@@ -27,12 +27,12 @@ test_expect_success 'git status' '
 
 test_expect_success 'git status with porcelain v2' '
        git status --porcelain=v2 | grep -v "^?" >actual &&
-       nam1=d00491fd7e5bb6fa28c517a0bb32b8b506539d4d &&
-       nam2=ce013625030ba8dba906f756967f9e9ca394464a &&
+       nam1=$(echo 1 | git hash-object --stdin) &&
+       nam2=$(git hash-object elif) &&
        cat >expect <<-EOF &&
-       1 DA N... 100644 000000 100644 $nam1 $_z40 1.t
-       1 A. N... 000000 100644 100644 $_z40 $nam2 elif
-       1 .A N... 000000 000000 100644 $_z40 $_z40 file
+       1 DA N... 100644 000000 100644 $nam1 $ZERO_OID 1.t
+       1 A. N... 000000 100644 100644 $ZERO_OID $nam2 elif
+       1 .A N... 000000 000000 100644 $ZERO_OID $ZERO_OID file
        EOF
        test_cmp expect actual
 '
@@ -181,7 +181,7 @@ test_expect_success 'rename detection finds the right names' '
                EOF
                test_cmp expected.2 actual.2 &&
 
-               hash=12f00e90b6ef79117ce6e650416b8cf517099b78 &&
+               hash=$(git hash-object third) &&
                git status --porcelain=v2 | grep -v "^?" >actual.3 &&
                cat >expected.3 <<-EOF &&
                2 .R N... 100644 100644 100644 $hash $hash R100 third   first
@@ -212,7 +212,7 @@ test_expect_success 'double rename detection in status' '
                EOF
                test_cmp expected.2 actual.2 &&
 
-               hash=12f00e90b6ef79117ce6e650416b8cf517099b78 &&
+               hash=$(git hash-object third) &&
                git status --porcelain=v2 | grep -v "^?" >actual.3 &&
                cat >expected.3 <<-EOF &&
                2 R. N... 100644 100644 100644 $hash $hash R100 second  first
index bdf5198b7eff11f9a7bfb57239f5905d92fe4bf7..08af596ba6c6b032eb1696c3beaba7c1776b4fd5 100755 (executable)
@@ -4,7 +4,7 @@ test_description='Test the lazy init name hash with various folder structures'
 
 . ./test-lib.sh
 
-if test 1 -eq $($GIT_BUILD_DIR/t/helper/test-online-cpus)
+if test 1 -eq $($GIT_BUILD_DIR/t/helper/test-tool online-cpus)
 then
        skip_all='skipping lazy-init tests, single cpu'
        test_done
@@ -21,7 +21,7 @@ test_expect_success 'no buffer overflow in lazy_init_name_hash' '
        ) |
        sed "s/^/100644 $EMPTY_BLOB     /" |
        git update-index --index-info &&
-       test-lazy-init-name-hash -m
+       test-tool lazy-init-name-hash -m
 '
 
 test_done
index b9c4028496f97bc9a620df89768e07c6a99bb07d..3d9fae68c41c85b4393e618cfe3706212d5c2dce 100755 (executable)
@@ -309,4 +309,22 @@ test_expect_success 'last wins in --find-renames=<m> --rename-threshold=<n>' '
        check_threshold_0
 '
 
+test_expect_success 'merge.renames disables rename detection' '
+       git read-tree --reset -u HEAD &&
+       git -c merge.renames=false merge-recursive $tail &&
+       check_no_renames
+'
+
+test_expect_success 'merge.renames defaults to diff.renames' '
+       git read-tree --reset -u HEAD &&
+       git -c diff.renames=false merge-recursive $tail &&
+       check_no_renames
+'
+
+test_expect_success 'merge.renames overrides diff.renames' '
+       git read-tree --reset -u HEAD &&
+       test_must_fail git -c diff.renames=false -c merge.renames=true merge-recursive $tail &&
+       $check_50
+'
+
 test_done
index c1fc6ca7301eaa9b15ef091ce592989956efc156..dce102130fb77ddda7cdc9aa9211507d9c2f2e09 100755 (executable)
@@ -79,12 +79,12 @@ match_with_function() {
        if test "$match_expect" = 1
        then
                test_expect_success "$match_function: match '$text' '$pattern'" "
-                       test-wildmatch $match_function '$text' '$pattern'
+                       test-tool wildmatch $match_function '$text' '$pattern'
                "
        elif test "$match_expect" = 0
        then
                test_expect_success "$match_function: no match '$text' '$pattern'" "
-                       test_must_fail test-wildmatch $match_function '$text' '$pattern'
+                       test_must_fail test-tool wildmatch $match_function '$text' '$pattern'
                "
        else
                test_expect_success "PANIC: Test framework error. Unknown matches value $match_expect" 'false'
@@ -148,7 +148,7 @@ match_with_ls_files() {
 match() {
        if test "$#" = 6
        then
-               # When test-wildmatch and git ls-files produce the same
+               # When test-tool wildmatch and git ls-files produce the same
                # result.
                match_glob=$1
                match_file_glob=$match_glob
@@ -204,19 +204,19 @@ match() {
                fi
        '
 
-       # $1: Case sensitive glob match: test-wildmatch & ls-files
+       # $1: Case sensitive glob match: test-tool wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_glob "wildmatch"
        match_with_ls_files "$text" "$pattern" $match_file_glob "wildmatch" " --glob-pathspecs"
 
-       # $2: Case insensitive glob match: test-wildmatch & ls-files
+       # $2: Case insensitive glob match: test-tool wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_iglob "iwildmatch"
        match_with_ls_files "$text" "$pattern" $match_file_iglob "iwildmatch" " --glob-pathspecs --icase-pathspecs"
 
-       # $3: Case sensitive path match: test-wildmatch & ls-files
+       # $3: Case sensitive path match: test-tool wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_pathmatch "pathmatch"
        match_with_ls_files "$text" "$pattern" $match_file_pathmatch "pathmatch" ""
 
-       # $4: Case insensitive path match: test-wildmatch & ls-files
+       # $4: Case insensitive path match: test-tool wildmatch & ls-files
        match_with_function "$text" "$pattern" $match_pathmatchi "ipathmatch"
        match_with_ls_files "$text" "$pattern" $match_file_pathmatchi "ipathmatch" " --icase-pathspecs"
 }
index 325114f8fee810ac9cf1836f50e060f69b5fe46e..18baf49a49c792952f3c8028cafc2d193d88cb5d 100755 (executable)
@@ -32,7 +32,7 @@ test_expect_success \
      echo $tree'
 
 test_output () {
-    sed -e "s/ $_x40   / X     /" <current >check
+    sed -e "s/ $OID_REGEX      / X     /" <current >check
     test_cmp expected check
 }
 
index 327ded4000b47cf3f4da42515fb803c47c0bd742..12bf31022a871c4d2e43866ec6053c55205a3476 100755 (executable)
@@ -40,7 +40,7 @@ test_expect_success 'setup' '
 '
 
 test_output () {
-       sed -e "s/ $_x40        / X     /" <current >check &&
+       sed -e "s/ $OID_REGEX   / X     /" <current >check &&
        test_cmp expected check
 }
 
index 09dcf043fdff1495dc4e0d1e56b9118c4f5feaeb..14520913afca8d1c980e4cd58d0b943a1a498611 100755 (executable)
@@ -17,7 +17,8 @@ test_expect_success 'setup' '
 '
 
 test_expect_success 'ls-tree fails with non-zero exit code on broken tree' '
-       rm -f .git/objects/5f/cffbd6e4c5c5b8d81f5e9314b20e338e3ffff5 &&
+       tree=$(git rev-parse HEAD:a) &&
+       rm -f .git/objects/$(echo $tree | sed -e "s,^\(..\),\1/,") &&
        test_must_fail git ls-tree -r HEAD
 '
 
index 6c0b7ea4addc8f1569b1b85f58dd3072fb863f33..08467982f61fd81f0614711b52b9806f2497f3eb 100755 (executable)
@@ -6,6 +6,7 @@
 test_description='git branch assorted tests'
 
 . ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
 
 test_expect_success 'prepare a trivial repository' '
        echo Hello >A &&
@@ -46,7 +47,7 @@ test_expect_success 'git branch HEAD should fail' '
 '
 
 cat >expect <<EOF
-$_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000        branch: Created from master
+$ZERO_OID $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000    branch: Created from master
 EOF
 test_expect_success 'git branch -l d/e/f should create a branch and a log' '
        GIT_COMMITTER_DATE="2005-05-26 23:30" \
@@ -233,34 +234,34 @@ test_expect_success 'git branch -M master2 master2 should work when master is ch
 
 test_expect_success 'git branch -v -d t should work' '
        git branch t &&
-       test_path_is_file .git/refs/heads/t &&
+       git rev-parse --verify refs/heads/t &&
        git branch -v -d t &&
-       test_path_is_missing .git/refs/heads/t
+       test_must_fail git rev-parse --verify refs/heads/t
 '
 
 test_expect_success 'git branch -v -m t s should work' '
        git branch t &&
-       test_path_is_file .git/refs/heads/t &&
+       git rev-parse --verify refs/heads/t &&
        git branch -v -m t s &&
-       test_path_is_missing .git/refs/heads/t &&
-       test_path_is_file .git/refs/heads/s &&
+       test_must_fail git rev-parse --verify refs/heads/t &&
+       git rev-parse --verify refs/heads/s &&
        git branch -d s
 '
 
 test_expect_success 'git branch -m -d t s should fail' '
        git branch t &&
-       test_path_is_file .git/refs/heads/t &&
+       git rev-parse refs/heads/t &&
        test_must_fail git branch -m -d t s &&
        git branch -d t &&
-       test_path_is_missing .git/refs/heads/t
+       test_must_fail git rev-parse refs/heads/t
 '
 
 test_expect_success 'git branch --list -d t should fail' '
        git branch t &&
-       test_path_is_file .git/refs/heads/t &&
+       git rev-parse refs/heads/t &&
        test_must_fail git branch --list -d t &&
        git branch -d t &&
-       test_path_is_missing .git/refs/heads/t
+       test_must_fail git rev-parse refs/heads/t
 '
 
 test_expect_success 'git branch --list -v with --abbrev' '
@@ -884,7 +885,7 @@ test_expect_success 'test --unset-upstream on a particular branch' '
        test_must_fail git config branch.my14.merge
 '
 
-test_expect_success '--set-upstream fails' '
+test_expect_success 'disabled option --set-upstream fails' '
     test_must_fail git branch --set-upstream origin/master
 '
 
@@ -900,7 +901,7 @@ test_expect_success '--set-upstream-to notices an error to set branch as own ups
 
 # Keep this test last, as it changes the current branch
 cat >expect <<EOF
-$_z40 $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000        branch: Created from master
+$ZERO_OID $HEAD $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1117150200 +0000    branch: Created from master
 EOF
 test_expect_success 'git checkout -b g/h/i -l should create a branch and a log' '
        GIT_COMMITTER_DATE="2005-05-26 23:30" \
@@ -1246,6 +1247,29 @@ test_expect_success '--merged is incompatible with --no-merged' '
        test_must_fail git branch --merged HEAD --no-merged HEAD
 '
 
+test_expect_success '--list during rebase' '
+       test_when_finished "reset_rebase" &&
+       git checkout master &&
+       FAKE_LINES="1 edit 2" &&
+       export FAKE_LINES &&
+       set_fake_editor &&
+       git rebase -i HEAD~2 &&
+       git branch --list >actual &&
+       test_i18ngrep "rebasing master" actual
+'
+
+test_expect_success '--list during rebase from detached HEAD' '
+       test_when_finished "reset_rebase && git checkout master" &&
+       git checkout master^0 &&
+       oid=$(git rev-parse --short HEAD) &&
+       FAKE_LINES="1 edit 2" &&
+       export FAKE_LINES &&
+       set_fake_editor &&
+       git rebase -i HEAD~2 &&
+       git branch --list >actual &&
+       test_i18ngrep "rebasing detached HEAD $oid" actual
+'
+
 test_expect_success 'tracking with unexpected .fetch refspec' '
        rm -rf a b c d &&
        git init a &&
index 86bf909ee3dfca78f678fdefe961772dcd78d6b1..61748088ebcbed700a570bc0e297f48435844340 100755 (executable)
@@ -22,7 +22,7 @@ test_expect_success 'setup: create a few commits with notes' '
        git commit -m 3rd &&
        COMMIT_FILE=.git/objects/5e/e1c35e83ea47cd3cc4f8cbee0568915fbbbd29 &&
        test -f $COMMIT_FILE &&
-       test-chmtime =+0 $COMMIT_FILE &&
+       test-tool chmtime =+0 $COMMIT_FILE &&
        git notes add -m "Note #3"
 '
 
index 3b905406df79187f70c828f72e9e2dc187f1be57..352a52e59d1a25d6fe50c5001ba3c84e2fc4a30c 100755 (executable)
@@ -711,13 +711,13 @@ test_expect_success 'rebase -i continue with unstaged submodule' '
 test_expect_success 'avoid unnecessary reset' '
        git checkout master &&
        git reset --hard &&
-       test-chmtime =123456789 file3 &&
+       test-tool chmtime =123456789 file3 &&
        git update-index --refresh &&
        HEAD=$(git rev-parse HEAD) &&
        set_fake_editor &&
        git rebase -i HEAD~4 &&
        test $HEAD = $(git rev-parse HEAD) &&
-       MTIME=$(test-chmtime -v +0 file3 | sed 's/[^0-9].*$//') &&
+       MTIME=$(test-tool chmtime --get file3) &&
        test 123456789 = $MTIME
 '
 
@@ -927,10 +927,8 @@ test_expect_success 'rebase --exec works without -i ' '
 test_expect_success 'rebase -i --exec without <CMD>' '
        git reset --hard execute &&
        set_fake_editor &&
-       test_must_fail git rebase -i --exec 2>tmp &&
-       sed -e "1d" tmp >actual &&
-       test_must_fail git rebase -h >expected &&
-       test_cmp expected actual &&
+       test_must_fail git rebase -i --exec 2>actual &&
+       test_i18ngrep "requires a value" actual &&
        git checkout master
 '
 
@@ -973,6 +971,16 @@ test_expect_success 'rebase -i --root fixup root commit' '
        test 0 = $(git cat-file commit HEAD | grep -c ^parent\ )
 '
 
+test_expect_success 'rebase -i --root reword root commit' '
+       test_when_finished "test_might_fail git rebase --abort" &&
+       git checkout -b reword-root-branch master &&
+       set_fake_editor &&
+       FAKE_LINES="reword 1 2" FAKE_COMMIT_MESSAGE="A changed" \
+       git rebase -i --root &&
+       git show HEAD^ | grep "A changed" &&
+       test -z "$(git show -s --format=%p HEAD^)"
+'
+
 test_expect_success C_LOCALE_OUTPUT 'rebase --edit-todo does not work on non-interactive rebase' '
        git reset --hard &&
        git checkout conflict-branch &&
@@ -1206,10 +1214,6 @@ test_expect_success 'drop' '
        test A = $(git cat-file commit HEAD^^ | sed -ne \$p)
 '
 
-cat >expect <<EOF
-Successfully rebased and updated refs/heads/missing-commit.
-EOF
-
 test_expect_success 'rebase -i respects rebase.missingCommitsCheck = ignore' '
        test_config rebase.missingCommitsCheck ignore &&
        rebase_setup_and_clean missing-commit &&
@@ -1217,7 +1221,9 @@ test_expect_success 'rebase -i respects rebase.missingCommitsCheck = ignore' '
        FAKE_LINES="1 2 3 4" \
                git rebase -i --root 2>actual &&
        test D = $(git cat-file commit HEAD | sed -ne \$p) &&
-       test_i18ncmp expect actual
+       test_i18ngrep \
+               "Successfully rebased and updated refs/heads/missing-commit" \
+               actual
 '
 
 cat >expect <<EOF
@@ -1229,15 +1235,24 @@ To avoid this message, use "drop" to explicitly remove a commit.
 Use 'git config rebase.missingCommitsCheck' to change the level of warnings.
 The possible behaviours are: ignore, warn, error.
 
+Rebasing (1/4)
+Rebasing (2/4)
+Rebasing (3/4)
+Rebasing (4/4)
 Successfully rebased and updated refs/heads/missing-commit.
 EOF
 
+cr_to_nl () {
+       tr '\015' '\012'
+}
+
 test_expect_success 'rebase -i respects rebase.missingCommitsCheck = warn' '
        test_config rebase.missingCommitsCheck warn &&
        rebase_setup_and_clean missing-commit &&
        set_fake_editor &&
        FAKE_LINES="1 2 3 4" \
-               git rebase -i --root 2>actual &&
+               git rebase -i --root 2>actual.2 &&
+       cr_to_nl <actual.2 >actual &&
        test_i18ncmp expect actual &&
        test D = $(git cat-file commit HEAD | sed -ne \$p)
 '
index 7c91a85f43a7a11295819adc5da5f8e5fca9e4ea..03bf1b8a3b3df2e44ed0f70dc176c25af9ac244a 100755 (executable)
@@ -24,7 +24,7 @@ test_expect_success 'interactive rebase --continue works with touched file' '
        git checkout master &&
 
        FAKE_LINES="edit 1" git rebase -i HEAD^ &&
-       test-chmtime =-60 F1 &&
+       test-tool chmtime =-60 F1 &&
        git rebase --continue
 '
 
@@ -36,7 +36,7 @@ test_expect_success 'non-interactive rebase --continue works with touched file'
        test_must_fail git rebase --onto master master topic &&
        echo "Resolved" >F2 &&
        git add F2 &&
-       test-chmtime =-60 F1 &&
+       test-tool chmtime =-60 F1 &&
        git rebase --continue
 '
 
@@ -88,6 +88,55 @@ test_expect_success 'rebase passes merge strategy options correctly' '
        git rebase --continue
 '
 
+test_expect_success '--skip after failed fixup cleans commit message' '
+       test_when_finished "test_might_fail git rebase --abort" &&
+       git checkout -b with-conflicting-fixup &&
+       test_commit wants-fixup &&
+       test_commit "fixup! wants-fixup" wants-fixup.t 1 wants-fixup-1 &&
+       test_commit "fixup! wants-fixup" wants-fixup.t 2 wants-fixup-2 &&
+       test_commit "fixup! wants-fixup" wants-fixup.t 3 wants-fixup-3 &&
+       test_must_fail env FAKE_LINES="1 fixup 2 squash 4" \
+               git rebase -i HEAD~4 &&
+
+       : now there is a conflict, and comments in the commit message &&
+       git show HEAD >out &&
+       grep "fixup! wants-fixup" out &&
+
+       : skip and continue &&
+       echo "cp \"\$1\" .git/copy.txt" | write_script copy-editor.sh &&
+       (test_set_editor "$PWD/copy-editor.sh" && git rebase --skip) &&
+
+       : the user should not have had to edit the commit message &&
+       test_path_is_missing .git/copy.txt &&
+
+       : now the comments in the commit message should have been cleaned up &&
+       git show HEAD >out &&
+       ! grep "fixup! wants-fixup" out &&
+
+       : now, let us ensure that "squash" is handled correctly &&
+       git reset --hard wants-fixup-3 &&
+       test_must_fail env FAKE_LINES="1 squash 4 squash 2 squash 4" \
+               git rebase -i HEAD~4 &&
+
+       : the first squash failed, but there are two more in the chain &&
+       (test_set_editor "$PWD/copy-editor.sh" &&
+        test_must_fail git rebase --skip) &&
+
+       : not the final squash, no need to edit the commit message &&
+       test_path_is_missing .git/copy.txt &&
+
+       : The first squash was skipped, therefore: &&
+       git show HEAD >out &&
+       test_i18ngrep "# This is a combination of 2 commits" out &&
+
+       (test_set_editor "$PWD/copy-editor.sh" && git rebase --skip) &&
+       git show HEAD >out &&
+       test_i18ngrep ! "# This is a combination" out &&
+
+       : Final squash failed, but there was still a squash &&
+       test_i18ngrep "# This is a combination of 2 commits" .git/copy.txt
+'
+
 test_expect_success 'setup rerere database' '
        rm -fr .git/rebase-* &&
        git reset --hard commit-new-file-F3-on-topic-branch &&
index 68fe2003ef5f74073cafa4741bee31ade85cf5c0..99b2aac9219da0e9a77e845509ca7b84c65ab88b 100755 (executable)
@@ -199,7 +199,7 @@ test_run_rebase () {
        "
 }
 test_run_rebase success ''
-test_run_rebase failure -m
+test_run_rebase success -m
 test_run_rebase success -i
 test_run_rebase failure -p
 
@@ -214,9 +214,10 @@ test_run_rebase () {
        "
 }
 test_run_rebase success ''
-test_run_rebase failure -m
-test_run_rebase failure -i
+test_run_rebase success -m
+test_run_rebase success -i
 test_run_rebase failure -p
+test_run_rebase success --rebase-merges
 
 #       m
 #      /
@@ -327,9 +328,9 @@ test_run_rebase () {
                test_cmp_rev c HEAD
        "
 }
-test_run_rebase failure ''
-test_run_rebase failure -m
-test_run_rebase failure -i
+test_run_rebase success ''
+test_run_rebase success -m
+test_run_rebase success -i
 test_run_rebase failure -p
 
 test_run_rebase () {
index 2afb56470184b18da19740f0a68abb31da96fd82..f6993b7e14d91617b337bfaefa717ec8591fb28f 100755 (executable)
@@ -12,6 +12,13 @@ cat >file <<EOF
 a
 EOF
 
+# Expected commit message for initial commit after rebase --signoff
+cat >expected-initial-signed <<EOF
+Initial empty commit
+
+Signed-off-by: $(git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/")
+EOF
+
 # Expected commit message after rebase --signoff
 cat >expected-signed <<EOF
 first
@@ -43,4 +50,35 @@ test_expect_success 'rebase --no-signoff does not add a sign-off line' '
        test_cmp expected-unsigned actual
 '
 
+test_expect_success 'rebase --exec --signoff adds a sign-off line' '
+       test_when_finished "rm exec" &&
+       git commit --amend -m "first" &&
+       git rebase --exec "touch exec" --signoff HEAD^ &&
+       test_path_is_file exec &&
+       git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+       test_cmp expected-signed actual
+'
+
+test_expect_success 'rebase --root --signoff adds a sign-off line' '
+       git commit --amend -m "first" &&
+       git rebase --root --keep-empty --signoff &&
+       git cat-file commit HEAD^ | sed -e "1,/^\$/d" >actual &&
+       test_cmp expected-initial-signed actual &&
+       git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+       test_cmp expected-signed actual
+'
+
+test_expect_success 'rebase -i --signoff fails' '
+       git commit --amend -m "first" &&
+       git rebase -i --signoff HEAD^ &&
+       git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+       test_cmp expected-signed actual
+'
+
+test_expect_success 'rebase -m --signoff fails' '
+       git commit --amend -m "first" &&
+       git rebase -m --signoff HEAD^ &&
+       git cat-file commit HEAD | sed -e "1,/^\$/d" >actual &&
+       test_cmp expected-signed actual
+'
 test_done
diff --git a/t/t3430-rebase-merges.sh b/t/t3430-rebase-merges.sh
new file mode 100755 (executable)
index 0000000..78f7c99
--- /dev/null
@@ -0,0 +1,332 @@
+#!/bin/sh
+#
+# Copyright (c) 2018 Johannes E. Schindelin
+#
+
+test_description='git rebase -i --rebase-merges
+
+This test runs git rebase "interactively", retaining the branch structure by
+recreating merge commits.
+
+Initial setup:
+
+    -- B --                   (first)
+   /       \
+ A - C - D - E - H            (master)
+       \       /
+         F - G                (second)
+'
+. ./test-lib.sh
+. "$TEST_DIRECTORY"/lib-rebase.sh
+
+test_cmp_graph () {
+       cat >expect &&
+       git log --graph --boundary --format=%s "$@" >output &&
+       sed "s/ *$//" <output >output.trimmed &&
+       test_cmp expect output.trimmed
+}
+
+test_expect_success 'setup' '
+       write_script replace-editor.sh <<-\EOF &&
+       mv "$1" "$(git rev-parse --git-path ORIGINAL-TODO)"
+       cp script-from-scratch "$1"
+       EOF
+
+       test_commit A &&
+       git checkout -b first &&
+       test_commit B &&
+       git checkout master &&
+       test_commit C &&
+       test_commit D &&
+       git merge --no-commit B &&
+       test_tick &&
+       git commit -m E &&
+       git tag -m E E &&
+       git checkout -b second C &&
+       test_commit F &&
+       test_commit G &&
+       git checkout master &&
+       git merge --no-commit G &&
+       test_tick &&
+       git commit -m H &&
+       git tag -m H H
+'
+
+test_expect_success 'create completely different structure' '
+       cat >script-from-scratch <<-\EOF &&
+       label onto
+
+       # onebranch
+       pick G
+       pick D
+       label onebranch
+
+       # second
+       reset onto
+       pick B
+       label second
+
+       reset onto
+       merge -C H second
+       merge onebranch # Merge the topic branch '\''onebranch'\''
+       EOF
+       test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
+       test_tick &&
+       git rebase -i -r A &&
+       test_cmp_graph <<-\EOF
+       *   Merge the topic branch '\''onebranch'\''
+       |\
+       | * D
+       | * G
+       * |   H
+       |\ \
+       | |/
+       |/|
+       | * B
+       |/
+       * A
+       EOF
+'
+
+test_expect_success 'generate correct todo list' '
+       cat >expect <<-\EOF &&
+       label onto
+
+       reset onto
+       pick d9df450 B
+       label E
+
+       reset onto
+       pick 5dee784 C
+       label branch-point
+       pick ca2c861 F
+       pick 088b00a G
+       label H
+
+       reset branch-point # C
+       pick 12bd07b D
+       merge -C 2051b56 E # E
+       merge -C 233d48a H # H
+
+       EOF
+
+       grep -v "^#" <.git/ORIGINAL-TODO >output &&
+       test_cmp expect output
+'
+
+test_expect_success '`reset` refuses to overwrite untracked files' '
+       git checkout -b refuse-to-reset &&
+       test_commit dont-overwrite-untracked &&
+       git checkout @{-1} &&
+       : >dont-overwrite-untracked.t &&
+       echo "reset refs/tags/dont-overwrite-untracked" >script-from-scratch &&
+       test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
+       test_must_fail git rebase -r HEAD &&
+       git rebase --abort
+'
+
+test_expect_success 'failed `merge` writes patch (may be rescheduled, too)' '
+       test_when_finished "test_might_fail git rebase --abort" &&
+       git checkout -b conflicting-merge A &&
+
+       : fail because of conflicting untracked file &&
+       >G.t &&
+       echo "merge -C H G" >script-from-scratch &&
+       test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
+       test_tick &&
+       test_must_fail git rebase -ir HEAD &&
+       grep "^merge -C .* G$" .git/rebase-merge/done &&
+       grep "^merge -C .* G$" .git/rebase-merge/git-rebase-todo &&
+       test_path_is_file .git/rebase-merge/patch &&
+
+       : fail because of merge conflict &&
+       rm G.t .git/rebase-merge/patch &&
+       git reset --hard &&
+       test_commit conflicting-G G.t not-G conflicting-G &&
+       test_must_fail git rebase --continue &&
+       ! grep "^merge -C .* G$" .git/rebase-merge/git-rebase-todo &&
+       test_path_is_file .git/rebase-merge/patch
+'
+
+test_expect_success 'with a branch tip that was cherry-picked already' '
+       git checkout -b already-upstream master &&
+       base="$(git rev-parse --verify HEAD)" &&
+
+       test_commit A1 &&
+       test_commit A2 &&
+       git reset --hard $base &&
+       test_commit B1 &&
+       test_tick &&
+       git merge -m "Merge branch A" A2 &&
+
+       git checkout -b upstream-with-a2 $base &&
+       test_tick &&
+       git cherry-pick A2 &&
+
+       git checkout already-upstream &&
+       test_tick &&
+       git rebase -i -r upstream-with-a2 &&
+       test_cmp_graph upstream-with-a2.. <<-\EOF
+       *   Merge branch A
+       |\
+       | * A1
+       * | B1
+       |/
+       o A2
+       EOF
+'
+
+test_expect_success 'do not rebase cousins unless asked for' '
+       git checkout -b cousins master &&
+       before="$(git rev-parse --verify HEAD)" &&
+       test_tick &&
+       git rebase -r HEAD^ &&
+       test_cmp_rev HEAD $before &&
+       test_tick &&
+       git rebase --rebase-merges=rebase-cousins HEAD^ &&
+       test_cmp_graph HEAD^.. <<-\EOF
+       *   Merge the topic branch '\''onebranch'\''
+       |\
+       | * D
+       | * G
+       |/
+       o H
+       EOF
+'
+
+test_expect_success 'refs/rewritten/* is worktree-local' '
+       git worktree add wt &&
+       cat >wt/script-from-scratch <<-\EOF &&
+       label xyz
+       exec GIT_DIR=../.git git rev-parse --verify refs/rewritten/xyz >a || :
+       exec git rev-parse --verify refs/rewritten/xyz >b
+       EOF
+
+       test_config -C wt sequence.editor \""$PWD"/replace-editor.sh\" &&
+       git -C wt rebase -i HEAD &&
+       test_must_be_empty wt/a &&
+       test_cmp_rev HEAD "$(cat wt/b)"
+'
+
+test_expect_success 'post-rewrite hook and fixups work for merges' '
+       git checkout -b post-rewrite &&
+       test_commit same1 &&
+       git reset --hard HEAD^ &&
+       test_commit same2 &&
+       git merge -m "to fix up" same1 &&
+       echo same old same old >same2.t &&
+       test_tick &&
+       git commit --fixup HEAD same2.t &&
+       fixup="$(git rev-parse HEAD)" &&
+
+       mkdir -p .git/hooks &&
+       test_when_finished "rm .git/hooks/post-rewrite" &&
+       echo "cat >actual" | write_script .git/hooks/post-rewrite &&
+
+       test_tick &&
+       git rebase -i --autosquash -r HEAD^^^ &&
+       printf "%s %s\n%s %s\n%s %s\n%s %s\n" >expect $(git rev-parse \
+               $fixup^^2 HEAD^2 \
+               $fixup^^ HEAD^ \
+               $fixup^ HEAD \
+               $fixup HEAD) &&
+       test_cmp expect actual
+'
+
+test_expect_success 'refuse to merge ancestors of HEAD' '
+       echo "merge HEAD^" >script-from-scratch &&
+       test_config -C wt sequence.editor \""$PWD"/replace-editor.sh\" &&
+       before="$(git rev-parse HEAD)" &&
+       git rebase -i HEAD &&
+       test_cmp_rev HEAD $before
+'
+
+test_expect_success 'root commits' '
+       git checkout --orphan unrelated &&
+       (GIT_AUTHOR_NAME="Parsnip" GIT_AUTHOR_EMAIL="root@example.com" \
+        test_commit second-root) &&
+       test_commit third-root &&
+       cat >script-from-scratch <<-\EOF &&
+       pick third-root
+       label first-branch
+       reset [new root]
+       pick second-root
+       merge first-branch # Merge the 3rd root
+       EOF
+       test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
+       test_tick &&
+       git rebase -i --force --root -r &&
+       test "Parsnip" = "$(git show -s --format=%an HEAD^)" &&
+       test $(git rev-parse second-root^0) != $(git rev-parse HEAD^) &&
+       test $(git rev-parse second-root:second-root.t) = \
+               $(git rev-parse HEAD^:second-root.t) &&
+       test_cmp_graph HEAD <<-\EOF &&
+       *   Merge the 3rd root
+       |\
+       | * third-root
+       * second-root
+       EOF
+
+       : fast forward if possible &&
+       before="$(git rev-parse --verify HEAD)" &&
+       test_might_fail git config --unset sequence.editor &&
+       test_tick &&
+       git rebase -i --root -r &&
+       test_cmp_rev HEAD $before
+'
+
+test_expect_success 'a "merge" into a root commit is a fast-forward' '
+       head=$(git rev-parse HEAD) &&
+       cat >script-from-scratch <<-EOF &&
+       reset [new root]
+       merge $head
+       EOF
+       test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
+       test_tick &&
+       git rebase -i -r HEAD^ &&
+       test_cmp_rev HEAD $head
+'
+
+test_expect_success 'A root commit can be a cousin, treat it that way' '
+       git checkout --orphan khnum &&
+       test_commit yama &&
+       git checkout -b asherah master &&
+       test_commit shamkat &&
+       git merge --allow-unrelated-histories khnum &&
+       test_tick &&
+       git rebase -f -r HEAD^ &&
+       ! test_cmp_rev HEAD^2 khnum &&
+       test_cmp_graph HEAD^.. <<-\EOF &&
+       *   Merge branch '\''khnum'\'' into asherah
+       |\
+       | * yama
+       o shamkat
+       EOF
+       test_tick &&
+       git rebase --rebase-merges=rebase-cousins HEAD^ &&
+       test_cmp_graph HEAD^.. <<-\EOF
+       *   Merge branch '\''khnum'\'' into asherah
+       |\
+       | * yama
+       |/
+       o shamkat
+       EOF
+'
+
+test_expect_success 'labels that are object IDs are rewritten' '
+       git checkout -b third B &&
+       test_commit I &&
+       third=$(git rev-parse HEAD) &&
+       git checkout -b labels master &&
+       git merge --no-commit third &&
+       test_tick &&
+       git commit -m "Merge commit '\''$third'\'' into labels" &&
+       echo noop >script-from-scratch &&
+       test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
+       test_tick &&
+       git rebase -i -r A &&
+       grep "^label $third-" .git/ORIGINAL-TODO &&
+       ! grep "^label $third$" .git/ORIGINAL-TODO
+'
+
+test_done
index 783bdbf59db07ebf2afac83165d31b86fd6b95db..d1c68af8c50e75255baa618ea297549b548c0fc2 100755 (executable)
@@ -86,7 +86,7 @@ test_expect_success 'cherry-pick on stat-dirty working tree' '
        (
                cd copy &&
                git checkout initial &&
-               test-chmtime +40 oops &&
+               test-tool chmtime +40 oops &&
                git cherry-pick added
        )
 '
@@ -141,7 +141,7 @@ test_expect_success 'cherry-pick "-" works with arguments' '
        test_cmp expect actual
 '
 
-test_expect_failure 'cherry-pick works with dirty renamed file' '
+test_expect_success 'cherry-pick works with dirty renamed file' '
        test_commit to-rename &&
        git checkout -b unrelated &&
        test_commit unrelated &&
@@ -150,9 +150,8 @@ test_expect_failure 'cherry-pick works with dirty renamed file' '
        test_tick &&
        git commit -m renamed &&
        echo modified >renamed &&
-       test_must_fail git cherry-pick refs/heads/unrelated >out &&
-       test_i18ngrep "Refusing to lose dirty file at renamed" out &&
-       test $(git rev-parse :0:renamed) = $(git rev-parse HEAD^:to-rename.t) &&
+       git cherry-pick refs/heads/unrelated >out &&
+       test $(git rev-parse :0:renamed) = $(git rev-parse HEAD~2:to-rename.t) &&
        grep -q "^modified$" renamed
 '
 
index 0acf4b14614c750d3c2324d8a941aa77d5c7ad56..b42cd66d3a574138148a311b34472506b433c286 100755 (executable)
@@ -122,7 +122,7 @@ test_expect_success '--quit keeps HEAD and conflicted index intact' '
        {
                git rev-list HEAD |
                git diff-tree --root --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual &&
        test_cmp expect actual
 '
@@ -220,7 +220,7 @@ test_expect_success 'cherry-pick still writes sequencer state when one commit is
        {
                git rev-list HEAD |
                git diff-tree --root --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual &&
        cat >expect <<-\EOF &&
        OBJID
@@ -247,9 +247,9 @@ test_expect_success '--abort after last commit in sequence' '
 test_expect_success 'cherry-pick does not implicitly stomp an existing operation' '
        pristine_detach initial &&
        test_expect_code 1 git cherry-pick base..anotherpick &&
-       test-chmtime -v +0 .git/sequencer >expect &&
+       test-tool chmtime --get .git/sequencer >expect &&
        test_expect_code 128 git cherry-pick unrelatedpick &&
-       test-chmtime -v +0 .git/sequencer >actual &&
+       test-tool chmtime --get .git/sequencer >actual &&
        test_cmp expect actual
 '
 
@@ -317,7 +317,7 @@ test_expect_success '--continue after resolving conflicts' '
        {
                git rev-list HEAD |
                git diff-tree --root --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual.log &&
        test_cmp expect foo &&
        test_cmp expect.log actual.log
@@ -334,7 +334,7 @@ test_expect_success '--continue after resolving conflicts and committing' '
        {
                git rev-list HEAD |
                git diff-tree --root --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual &&
        cat >expect <<-\EOF &&
        OBJID
index 46f15169f55c03742717f36f8d0e99241391b2ea..b8fbdefcdc34ffa6fb54fc1ad375a583a194fb38 100755 (executable)
@@ -232,7 +232,7 @@ test_expect_success 'Call "rm" from outside the work tree' '
 test_expect_success 'refresh index before checking if it is up-to-date' '
 
        git reset --hard &&
-       test-chmtime -86400 frotz/nitfol &&
+       test-tool chmtime -86400 frotz/nitfol &&
        git rm frotz/nitfol &&
        test ! -f frotz/nitfol
 
index 2748805642201d7c514792bab8d8b3940fb4086c..07af05d7aee65c51245431292a21ec38eef19f53 100755 (executable)
@@ -187,7 +187,7 @@ test_expect_success 'git add --refresh with pathspec' '
        echo >foo && echo >bar && echo >baz &&
        git add foo bar baz && H=$(git rev-parse :foo) && git rm -f foo &&
        echo "100644 $H 3       foo" | git update-index --index-info &&
-       test-chmtime -60 bar baz &&
+       test-tool chmtime -60 bar baz &&
        >expect &&
        git add --refresh bar >actual &&
        test_cmp expect actual &&
index 3cb74ca296d141a6bd248e527680f5f217608ca7..c6af7f82b58f606b3f6c7e2612931a1fc2af15c7 100755 (executable)
@@ -40,7 +40,6 @@ test_expect_success 'setup' '
 
 cat > expected-patch << EOF
 diff --git a/file b/file
-index b9834b5..9020acb 100644
 --- a/file
 +++ b/file
 @@ -1,11 +1,6 @@
@@ -80,7 +79,6 @@ EOF
 
 cat > expected << EOF
 diff --git a/file b/file
-index b9834b5..ef6e94c 100644
 --- a/file
 +++ b/file
 @@ -1,10 +1,12 @@
@@ -100,7 +98,7 @@ EOF
 
 echo "#!$SHELL_PATH" >fake-editor.sh
 cat >> fake-editor.sh <<\EOF
-mv -f "$1" orig-patch &&
+egrep -v '^index' "$1" >orig-patch &&
 mv -f patch "$1"
 EOF
 
@@ -113,7 +111,8 @@ test_expect_success 'add -e' '
        git add -e &&
        test_cmp second-part file &&
        test_cmp orig-patch expected-patch &&
-       git diff --cached > out &&
+       git diff --cached >actual &&
+       grep -v index actual >out &&
        test_cmp out expected
 
 '
index aefde7b1726bdc8d71d2b78e313e29daa2b31a24..1f871d3cca9aba4dcb32b5197b9b3d296fc5c1fa 100755 (executable)
@@ -726,7 +726,7 @@ test_expect_success 'store updates stash ref and reflog' '
        git reset --hard &&
        ! grep quux bazzy &&
        git stash store -m quuxery $STASH_ID &&
-       test $(cat .git/refs/stash) = $STASH_ID &&
+       test $(git rev-parse stash) = $STASH_ID &&
        git reflog --format=%H stash| grep $STASH_ID &&
        git stash pop &&
        grep quux bazzy
index bfde4057ad2afcdd3bd38cbb43ffa2ce241aaa67..597b0637d160be0cab4d3114aace598616e371fd 100755 (executable)
@@ -35,24 +35,26 @@ test_expect_success 'stash save --include-untracked cleaned the untracked files'
        test_cmp expect actual
 '
 
+tracked=$(git rev-parse --short $(echo 1 | git hash-object --stdin))
+untracked=$(git rev-parse --short $(echo untracked | git hash-object --stdin))
 cat > expect.diff <<EOF
 diff --git a/HEAD b/HEAD
 new file mode 100644
-index 0000000..d00491f
+index 0000000..$tracked
 --- /dev/null
 +++ b/HEAD
 @@ -0,0 +1 @@
 +1
 diff --git a/file2 b/file2
 new file mode 100644
-index 0000000..d00491f
+index 0000000..$tracked
 --- /dev/null
 +++ b/file2
 @@ -0,0 +1 @@
 +1
 diff --git a/untracked/untracked b/untracked/untracked
 new file mode 100644
-index 0000000..5a72eb2
+index 0000000..$untracked
 --- /dev/null
 +++ b/untracked/untracked
 @@ -0,0 +1 @@
@@ -109,10 +111,11 @@ test_expect_success 'stash save -u dirty index' '
        git stash -u
 '
 
+blob=$(git rev-parse --short $(echo 4 | git hash-object --stdin))
 cat > expect <<EOF
 diff --git a/file3 b/file3
 new file mode 100644
-index 0000000..b8626c4
+index 0000000..$blob
 --- /dev/null
 +++ b/file3
 @@ -0,0 +1 @@
@@ -228,4 +231,56 @@ test_expect_success 'stash previously ignored file' '
        test_path_is_file ignored.d/foo
 '
 
+test_expect_success 'stash -u -- <untracked> doesnt print error' '
+       >untracked &&
+       git stash push -u -- untracked 2>actual &&
+       test_path_is_missing untracked &&
+       test_line_count = 0 actual
+'
+
+test_expect_success 'stash -u -- <untracked> leaves rest of working tree in place' '
+       >tracked &&
+       git add tracked &&
+       >untracked &&
+       git stash push -u -- untracked &&
+       test_path_is_missing untracked &&
+       test_path_is_file tracked
+'
+
+test_expect_success 'stash -u -- <tracked> <untracked> clears changes in both' '
+       >tracked &&
+       git add tracked &&
+       >untracked &&
+       git stash push -u -- tracked untracked &&
+       test_path_is_missing tracked &&
+       test_path_is_missing untracked
+'
+
+test_expect_success 'stash --all -- <ignored> stashes ignored file' '
+       >ignored.d/bar &&
+       git stash push --all -- ignored.d/bar &&
+       test_path_is_missing ignored.d/bar
+'
+
+test_expect_success 'stash --all -- <tracked> <ignored> clears changes in both' '
+       >tracked &&
+       git add tracked &&
+       >ignored.d/bar &&
+       git stash push --all -- tracked ignored.d/bar &&
+       test_path_is_missing tracked &&
+       test_path_is_missing ignored.d/bar
+'
+
+test_expect_success 'stash -u -- <ignored> leaves ignored file alone' '
+       >ignored.d/bar &&
+       git stash push -u -- ignored.d/bar &&
+       test_path_is_file ignored.d/bar
+'
+
+test_expect_success 'stash -u -- <non-existant> shows no changes when there are none' '
+       git stash push -u -- non-existant >actual &&
+       echo "No local changes to save" >expect &&
+       test_i18ncmp expect actual
+'
+
 test_done
index a07816d5605f30ccb7f7ce6fe83288fff535538c..bf4030371a9fc8f5abe7e88d84c98a097b9821dd 100755 (executable)
@@ -138,6 +138,18 @@ test_expect_success 'favour same basenames over different ones' '
        test_i18ngrep "renamed: .*path1 -> subdir/path1" out
 '
 
+test_expect_success 'test diff.renames=true for git status' '
+       git -c diff.renames=true status >out &&
+       test_i18ngrep "renamed: .*path1 -> subdir/path1" out
+'
+
+test_expect_success 'test diff.renames=false for git status' '
+       git -c diff.renames=false status >out &&
+       test_i18ngrep ! "renamed: .*path1 -> subdir/path1" out &&
+       test_i18ngrep "new file: .*subdir/path1" out &&
+       test_i18ngrep "deleted: .*[^/]path1" out
+'
+
 test_expect_success 'favour same basenames even with minor differences' '
        git show HEAD:path1 | sed "s/15/16/" > subdir/path1 &&
        git status >out &&
index a5e8b830834f4b5feb531f8f4f4d08462325b1de..3a6c21e8251b84b2979ac7fc5d730a3155b624b4 100755 (executable)
@@ -131,7 +131,7 @@ cmp_diff_files_output () {
     # object ID for the changed files because it wants you to look at the
     # filesystem.
     sed <"$2" >.test-tmp \
-       -e '/^:000000 /d;s/'$_x40'\( [MCRNDU][0-9]*\)   /'$_z40'\1      /' &&
+       -e '/^:000000 /d;s/'$OID_REGEX'\( [MCRNDU][0-9]*\)      /'$ZERO_OID'\1  /' &&
     test_cmp "$1" .test-tmp
 }
 
index 76f643b2c2a2c7e307135de6942cf46743b6cbef..a8e01eccd158131118019ca7c9b05d08a65d07e3 100755 (executable)
@@ -8,7 +8,7 @@ test_description='Test mode change diffs.
 '
 . ./test-lib.sh
 
-sed_script='s/\(:100644 100755\) \('"$_x40"'\) \2 /\1 X X /'
+sed_script='s/\(:100644 100755\) \('"$OID_REGEX"'\) \2 /\1 X X /'
 
 test_expect_success 'setup' '
        echo frotz >rezrov &&
index dae327fabbfe390a3dc707ef2ebc665c9c6e3cb3..b187b7f6c66b8ade9d0ef73aa346a9205df153bc 100755 (executable)
@@ -17,6 +17,7 @@ test_expect_success 'prepare reference tree' '
        echo $tree
 '
 
+blob=$(git hash-object "$TEST_DIRECTORY/diff-lib/COPYING")
 test_expect_success 'prepare work tree' '
        cp path0/COPYING path1/COPYING &&
        git update-index --add --remove path0/COPYING path1/COPYING
@@ -26,8 +27,8 @@ test_expect_success 'prepare work tree' '
 # path1 both have COPYING and the latter is a copy of path0/COPYING.
 # Comparing the full tree with cache should tell us so.
 
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 C100  path0/COPYING   path1/COPYING
+cat >expected <<EOF
+:100644 100644 $blob $blob C100        path0/COPYING   path1/COPYING
 EOF
 
 test_expect_success 'copy detection' '
@@ -46,8 +47,8 @@ test_expect_success 'copy detection, cached' '
 # path1/COPYING suddenly appearing from nowhere, not detected as
 # a copy from path0/COPYING.
 
-cat >expected <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A     path1/COPYING
+cat >expected <<EOF
+:000000 100644 $ZERO_OID $blob A       path1/COPYING
 EOF
 
 test_expect_success 'copy, limited to a subtree' '
@@ -64,8 +65,8 @@ test_expect_success 'tweak work tree' '
 # path0/COPYING.  Showing the full tree with cache should tell us about
 # the rename.
 
-cat >expected <<\EOF
-:100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100  path0/COPYING   path1/COPYING
+cat >expected <<EOF
+:100644 100644 $blob $blob R100        path0/COPYING   path1/COPYING
 EOF
 
 test_expect_success 'rename detection' '
@@ -78,8 +79,8 @@ test_expect_success 'rename detection' '
 # path0/COPYING.  When we say we care only about path1, we should just
 # see path1/COPYING appearing from nowhere.
 
-cat >expected <<\EOF
-:000000 100644 0000000000000000000000000000000000000000 6ff87c4664981e4397625791c8ea3bbb5f2279a3 A     path1/COPYING
+cat >expected <<EOF
+:000000 100644 $ZERO_OID $blob A       path1/COPYING
 EOF
 
 test_expect_success 'rename, limited to a subtree' '
index 9dd1bc5e162bb0b8821337a1e43cd8ad85423507..b1ccd4102e09e27529eb09e873c2b4c2467a40db 100755 (executable)
@@ -27,29 +27,32 @@ Further, with -B and -M together, these should turn into two renames.
 test_expect_success setup '
        cat "$TEST_DIRECTORY"/diff-lib/README >file0 &&
        cat "$TEST_DIRECTORY"/diff-lib/COPYING >file1 &&
+       blob0_id=$(git hash-object file0) &&
+       blob1_id=$(git hash-object file1) &&
        git update-index --add file0 file1 &&
        git tag reference $(git write-tree)
 '
 
 test_expect_success 'change file1 with copy-edit of file0 and remove file0' '
        sed -e "s/git/GIT/" file0 >file1 &&
+       blob2_id=$(git hash-object file1) &&
        rm -f file0 &&
        git update-index --remove file0 file1
 '
 
 test_expect_success 'run diff with -B (#1)' '
        git diff-index -B --cached reference >current &&
-       cat >expect <<-\EOF &&
-       :100644 000000 548142c327a6790ff8821d67c2ee1eff7a656b52 0000000000000000000000000000000000000000 D      file0
-       :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 2fbedd0b5d4b8126e4750c3bee305e8ff79f80ec M100   file1
+       cat >expect <<-EOF &&
+       :100644 000000 $blob0_id $ZERO_OID D    file0
+       :100644 100644 $blob1_id $blob2_id M100 file1
        EOF
        compare_diff_raw expect current
 '
 
 test_expect_success 'run diff with -B and -M (#2)' '
        git diff-index -B -M reference >current &&
-       cat >expect <<-\EOF &&
-       :100644 100644 548142c327a6790ff8821d67c2ee1eff7a656b52 2fbedd0b5d4b8126e4750c3bee305e8ff79f80ec R100   file0   file1
+       cat >expect <<-EOF &&
+       :100644 100644 $blob0_id $blob2_id R100 file0   file1
        EOF
        compare_diff_raw expect current
 '
@@ -66,18 +69,18 @@ test_expect_success 'swap file0 and file1' '
 
 test_expect_success 'run diff with -B (#3)' '
        git diff-index -B reference >current &&
-       cat >expect <<-\EOF &&
-       :100644 100644 548142c327a6790ff8821d67c2ee1eff7a656b52 6ff87c4664981e4397625791c8ea3bbb5f2279a3 M100   file0
-       :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 548142c327a6790ff8821d67c2ee1eff7a656b52 M100   file1
+       cat >expect <<-EOF &&
+       :100644 100644 $blob0_id $blob1_id M100 file0
+       :100644 100644 $blob1_id $blob0_id M100 file1
        EOF
        compare_diff_raw expect current
 '
 
 test_expect_success 'run diff with -B and -M (#4)' '
        git diff-index -B -M reference >current &&
-       cat >expect <<-\EOF &&
-       :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 6ff87c4664981e4397625791c8ea3bbb5f2279a3 R100   file1   file0
-       :100644 100644 548142c327a6790ff8821d67c2ee1eff7a656b52 548142c327a6790ff8821d67c2ee1eff7a656b52 R100   file0   file1
+       cat >expect <<-EOF &&
+       :100644 100644 $blob1_id $blob1_id R100 file1   file0
+       :100644 100644 $blob0_id $blob0_id R100 file0   file1
        EOF
        compare_diff_raw expect current
 '
@@ -85,14 +88,15 @@ test_expect_success 'run diff with -B and -M (#4)' '
 test_expect_success 'make file0 into something completely different' '
        rm -f file0 &&
        test_ln_s_add frotz file0 &&
+       slink_id=$(printf frotz | git hash-object --stdin) &&
        git update-index file1
 '
 
 test_expect_success 'run diff with -B (#5)' '
        git diff-index -B reference >current &&
-       cat >expect <<-\EOF &&
-       :100644 120000 548142c327a6790ff8821d67c2ee1eff7a656b52 67be421f88824578857624f7b3dc75e99a8a1481 T      file0
-       :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 548142c327a6790ff8821d67c2ee1eff7a656b52 M100   file1
+       cat >expect <<-EOF &&
+       :100644 120000 $blob0_id $slink_id T    file0
+       :100644 100644 $blob1_id $blob0_id M100 file1
        EOF
        compare_diff_raw expect current
 '
@@ -103,9 +107,9 @@ test_expect_success 'run diff with -B -M (#6)' '
        # file0 changed from regular to symlink.  file1 is the same as the preimage
        # of file0.  Because the change does not make file0 disappear, file1 is
        # denoted as a copy of file0
-       cat >expect <<-\EOF &&
-       :100644 120000 548142c327a6790ff8821d67c2ee1eff7a656b52 67be421f88824578857624f7b3dc75e99a8a1481 T      file0
-       :100644 100644 548142c327a6790ff8821d67c2ee1eff7a656b52 548142c327a6790ff8821d67c2ee1eff7a656b52 C      file0   file1
+       cat >expect <<-EOF &&
+       :100644 120000 $blob0_id $slink_id T    file0
+       :100644 100644 $blob0_id $blob0_id C    file0   file1
        EOF
        compare_diff_raw expect current
 '
@@ -115,9 +119,9 @@ test_expect_success 'run diff with -M (#7)' '
 
        # This should not mistake file0 as the copy source of new file1
        # due to type differences.
-       cat >expect <<-\EOF &&
-       :100644 120000 548142c327a6790ff8821d67c2ee1eff7a656b52 67be421f88824578857624f7b3dc75e99a8a1481 T      file0
-       :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 548142c327a6790ff8821d67c2ee1eff7a656b52 M      file1
+       cat >expect <<-EOF &&
+       :100644 120000 $blob0_id $slink_id T    file0
+       :100644 100644 $blob1_id $blob0_id M    file1
        EOF
        compare_diff_raw expect current
 '
@@ -128,25 +132,26 @@ test_expect_success 'file1 edited to look like file0 and file0 rename-edited to
        git checkout-index -f -u -a &&
        sed -e "s/git/GIT/" file0 >file1 &&
        sed -e "s/git/GET/" file0 >file2 &&
+       blob3_id=$(git hash-object file2) &&
        rm -f file0 &&
        git update-index --add --remove file0 file1 file2
 '
 
 test_expect_success 'run diff with -B (#8)' '
        git diff-index -B reference >current &&
-       cat >expect <<-\EOF &&
-       :100644 000000 548142c327a6790ff8821d67c2ee1eff7a656b52 0000000000000000000000000000000000000000 D      file0
-       :100644 100644 6ff87c4664981e4397625791c8ea3bbb5f2279a3 2fbedd0b5d4b8126e4750c3bee305e8ff79f80ec M100   file1
-       :000000 100644 0000000000000000000000000000000000000000 69a939f651686f56322566e2fd76715947a24162 A      file2
+       cat >expect <<-EOF &&
+       :100644 000000 $blob0_id $ZERO_OID D    file0
+       :100644 100644 $blob1_id $blob2_id M100 file1
+       :000000 100644 $ZERO_OID $blob3_id A    file2
        EOF
        compare_diff_raw expect current
 '
 
 test_expect_success 'run diff with -B -C (#9)' '
        git diff-index -B -C reference >current &&
-       cat >expect <<-\EOF &&
-       :100644 100644 548142c327a6790ff8821d67c2ee1eff7a656b52 2fbedd0b5d4b8126e4750c3bee305e8ff79f80ec C095   file0   file1
-       :100644 100644 548142c327a6790ff8821d67c2ee1eff7a656b52 69a939f651686f56322566e2fd76715947a24162 R095   file0   file2
+       cat >expect <<-EOF &&
+       :100644 100644 $blob0_id $blob2_id C095 file0   file1
+       :100644 100644 $blob0_id $blob3_id R095 file0   file2
        EOF
        compare_diff_raw expect current
 '
index 13e7f621ab79f95cc7c3057d9de5710813049102..cf0f3a1ee75dd28c6b5ce2a5db7c3ad6afafd21f 100755 (executable)
@@ -73,7 +73,7 @@ test_expect_success 'diff identical, but newly created symlink and file' '
        >expected &&
        rm -f frotz nitfol &&
        echo xyzzy >nitfol &&
-       test-chmtime +10 nitfol &&
+       test-tool chmtime +10 nitfol &&
        if test_have_prereq SYMLINKS
        then
                ln -s xyzzy frotz
index 3f9a24fd56c801d1a75abb6cc4f4e8928c2dc427..f8d853595b99bfff64521a502ee062b7e5f35e5f 100755 (executable)
@@ -76,7 +76,7 @@ test_expect_success setup '
 
        mkdir dir3 &&
        cp dir/sub dir3/sub &&
-       test-chmtime +1 dir3/sub &&
+       test-tool chmtime +1 dir3/sub &&
 
        git config log.showroot false &&
        git commit --amend &&
index 482112ca339f05fc31e6f9c2c6168971a1121e87..028d5507a6b684208ba82292379ec74bc6628574 100755 (executable)
@@ -578,7 +578,11 @@ test_expect_success 'excessive subject' '
 
        rm -rf patches/ &&
        git checkout side &&
+       before=$(git hash-object file) &&
+       before=$(git rev-parse --short $before) &&
        for i in 5 6 1 2 3 A 4 B C 7 8 9 10 D E F; do echo "$i"; done >>file &&
+       after=$(git hash-object file) &&
+       after=$(git rev-parse --short $after) &&
        git update-index file &&
        git commit -m "This is an excessively long subject line for a message due to the habit some projects have of not having a short, one-line subject at the start of the commit message, but rather sticking a whole paragraph right at the start as the only thing in the commit message. It had better not become the filename for the patch." &&
        git format-patch -o patches/ master..side &&
@@ -586,7 +590,6 @@ test_expect_success 'excessive subject' '
 '
 
 test_expect_success 'cover-letter inherits diff options' '
-
        git mv file foo &&
        git commit -m foo &&
        git format-patch --no-renames --cover-letter -1 &&
@@ -616,7 +619,7 @@ test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '
 '
 
 cat > expect << EOF
-index 40f36c6..2dc5c23 100644
+index $before..$after 100644
 --- a/file
 +++ b/file
 @@ -13,4 +13,20 @@ C
@@ -640,7 +643,7 @@ test_expect_success 'format-patch respects -U' '
 cat > expect << EOF
 
 diff --git a/file b/file
-index 40f36c6..2dc5c23 100644
+index $before..$after 100644
 --- a/file
 +++ b/file
 @@ -14,3 +14,19 @@ C
@@ -1523,14 +1526,14 @@ test_expect_success 'cover letter auto user override' '
 test_expect_success 'format-patch --zero-commit' '
        git format-patch --zero-commit --stdout v2..v1 >patch2 &&
        grep "^From " patch2 | sort | uniq >actual &&
-       echo "From $_z40 Mon Sep 17 00:00:00 2001" >expect &&
+       echo "From $ZERO_OID Mon Sep 17 00:00:00 2001" >expect &&
        test_cmp expect actual
 '
 
 test_expect_success 'From line has expected format' '
        git format-patch --stdout v2..v1 >patch2 &&
        grep "^From " patch2 >from &&
-       grep "^From $_x40 Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
+       grep "^From $OID_REGEX Mon Sep 17 00:00:00 2001$" patch2 >filtered &&
        test_cmp from filtered
 '
 
@@ -1661,6 +1664,15 @@ test_expect_success 'format-patch --base with --attach' '
        test_write_lines 1 2 >expect &&
        test_cmp expect actual
 '
+test_expect_success 'format-patch --attach cover-letter only is non-multipart' '
+       test_when_finished "rm -fr patches" &&
+       git format-patch -o patches --cover-letter --attach=mimemime --base=HEAD~ -1 &&
+       ! egrep "^--+mimemime" patches/0000*.patch &&
+       egrep "^--+mimemime$" patches/0001*.patch >output &&
+       test_line_count = 2 output &&
+       egrep "^--+mimemime--$" patches/0001*.patch >output &&
+       test_line_count = 1 output
+'
 
 test_expect_success 'format-patch --pretty=mboxrd' '
        sp=" " &&
index 044620186d135fe5caeb9376665305af1c8acbe5..e009826fcbe5a893df748a47d162e010b95d758b 100755 (executable)
@@ -13,6 +13,8 @@ test_expect_success setup '
 
        test_tick &&
        echo second >file &&
+       before=$(git hash-object file) &&
+       before=$(git rev-parse --short $before) &&
        git add file &&
        git commit -m second &&
 
@@ -26,7 +28,7 @@ test_expect_success 'GIT_EXTERNAL_DIFF environment' '
                read path oldfile oldhex oldmode newfile newhex newmode &&
                test "z$path" = zfile &&
                test "z$oldmode" = z100644 &&
-               test "z$newhex" = "z$_z40" &&
+               test "z$newhex" = "z$ZERO_OID" &&
                test "z$newmode" = z100644 &&
                oh=$(git rev-parse --verify HEAD:file) &&
                test "z$oh" = "z$oldhex"
@@ -55,7 +57,7 @@ test_expect_success SYMLINKS 'typechange diff' '
                read path oldfile oldhex oldmode newfile newhex newmode &&
                test "z$path" = zfile &&
                test "z$oldmode" = z100644 &&
-               test "z$newhex" = "z$_z40" &&
+               test "z$newhex" = "z$ZERO_OID" &&
                test "z$newmode" = z120000 &&
                oh=$(git rev-parse --verify HEAD:file) &&
                test "z$oh" = "z$oldhex"
@@ -73,7 +75,7 @@ test_expect_success 'diff.external' '
                read path oldfile oldhex oldmode newfile newhex newmode &&
                test "z$path" = zfile &&
                test "z$oldmode" = z100644 &&
-               test "z$newhex" = "z$_z40" &&
+               test "z$newhex" = "z$ZERO_OID" &&
                test "z$newmode" = z100644 &&
                oh=$(git rev-parse --verify HEAD:file) &&
                test "z$oh" = "z$oldhex"
@@ -104,7 +106,7 @@ test_expect_success 'diff attribute' '
                read path oldfile oldhex oldmode newfile newhex newmode &&
                test "z$path" = zfile &&
                test "z$oldmode" = z100644 &&
-               test "z$newhex" = "z$_z40" &&
+               test "z$newhex" = "z$ZERO_OID" &&
                test "z$newmode" = z100644 &&
                oh=$(git rev-parse --verify HEAD:file) &&
                test "z$oh" = "z$oldhex"
@@ -137,7 +139,7 @@ test_expect_success 'diff attribute' '
                read path oldfile oldhex oldmode newfile newhex newmode &&
                test "z$path" = zfile &&
                test "z$oldmode" = z100644 &&
-               test "z$newhex" = "z$_z40" &&
+               test "z$newhex" = "z$ZERO_OID" &&
                test "z$newmode" = z100644 &&
                oh=$(git rev-parse --verify HEAD:file) &&
                test "z$oh" = "z$oldhex"
@@ -180,9 +182,13 @@ test_expect_success 'no diff with -diff' '
 echo NULZbetweenZwords | perl -pe 'y/Z/\000/' > file
 
 test_expect_success 'force diff with "diff"' '
+       after=$(git hash-object file) &&
+       after=$(git rev-parse --short $after) &&
        echo >.gitattributes "file diff" &&
        git diff >actual &&
-       test_cmp "$TEST_DIRECTORY"/t4020/diff.NUL actual
+       sed -e "s/^index .*/index $before..$after 100644/" \
+               "$TEST_DIRECTORY"/t4020/diff.NUL >expected-diff &&
+       test_cmp expected-diff actual
 '
 
 test_expect_success 'GIT_EXTERNAL_DIFF with more than one changed files' '
@@ -237,7 +243,7 @@ test_expect_success 'diff --cached' '
        git update-index --assume-unchanged file &&
        echo second >file &&
        git diff --cached >actual &&
-       test_cmp "$TEST_DIRECTORY"/t4020/diff.NUL actual
+       test_cmp expected-diff actual
 '
 
 test_expect_success 'clean up crlf leftovers' '
index cb51d9f9d47d61c5b73de78edeeedcc7652f262d..6d1c3d949c78bc8fd5a82dbaee519163a8653e86 100755 (executable)
@@ -13,6 +13,8 @@ test_expect_success setup '
          "nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM" \
          <"$TEST_DIRECTORY"/../COPYING >test &&
        echo "to be deleted" >test2 &&
+       blob=$(git hash-object test2) &&
+       blob=$(git rev-parse --short $blob) &&
        git add test2
 
 '
@@ -27,7 +29,7 @@ test_expect_success 'detect rewrite' '
 cat >expect <<EOF
 diff --git a/test2 b/test2
 deleted file mode 100644
-index 4202011..0000000
+index $blob..0000000
 --- a/test2
 +++ /dev/null
 @@ -1 +0,0 @@
@@ -43,7 +45,7 @@ test_expect_success 'show deletion diff without -D' '
 cat >expect <<EOF
 diff --git a/test2 b/test2
 deleted file mode 100644
-index 4202011..0000000
+index $blob..0000000
 EOF
 test_expect_success 'suppress deletion diff with -D' '
 
index 2ffd11a142d8c1d2f532f662951a27a90119a76e..6304130ad4737bfac1e2cf06fd8c600bb7b42f76 100755 (executable)
@@ -31,7 +31,7 @@ test_expect_success setup '
                cd sub &&
                git rev-list HEAD
        ) &&
-       echo ":160000 160000 $3 $_z40 M sub" >expect &&
+       echo ":160000 160000 $3 $ZERO_OID M     sub" >expect &&
        subtip=$3 subprev=$2
 '
 
@@ -250,7 +250,7 @@ test_expect_success 'conflicted submodule setup' '
        # 39 efs
        c=fffffffffffffffffffffffffffffffffffffff &&
        (
-               echo "000000 $_z40 0    sub" &&
+               echo "000000 $ZERO_OID 0        sub" &&
                echo "160000 1$c 1      sub" &&
                echo "160000 2$c 2      sub" &&
                echo "160000 3$c 3      sub"
@@ -265,7 +265,7 @@ index 2ffffff,3ffffff..0000000
 ++Subproject commit 0000000000000000000000000000000000000000'\'' &&
 
        hh=$(git rev-parse HEAD) &&
-       sed -e "s/$_z40/$hh/" expect.nosub >expect.withsub
+       sed -e "s/$ZERO_OID/$hh/" expect.nosub >expect.withsub
 
 '
 
index 3ccc237a8d4443bfc8763fbb9cb51033f846b0e8..32b6e9a4e76217d8de771b405dd3ce57c73643ad 100755 (executable)
@@ -6,7 +6,7 @@ test_description='diff honors config option, diff.suppressBlankEmpty'
 
 . ./test-lib.sh
 
-cat <<\EOF > exp ||
+cat <<\EOF >expected ||
 diff --git a/f b/f
 index 5f6a263..8cb8bae 100644
 --- a/f
@@ -18,22 +18,26 @@ index 5f6a263..8cb8bae 100644
 EOF
 exit 1
 
-test_expect_success \
-    "$test_description" \
-    'printf "\nx\n" > f &&
-     git add f &&
-     git commit -q -m. f &&
-     printf "\ny\n" > f &&
-     git config --bool diff.suppressBlankEmpty true &&
-     git diff f > actual &&
-     test_cmp exp actual &&
-     perl -i.bak -p -e "s/^\$/ /" exp &&
-     git config --bool diff.suppressBlankEmpty false &&
-     git diff f > actual &&
-     test_cmp exp actual &&
-     git config --bool --unset diff.suppressBlankEmpty &&
-     git diff f > actual &&
-     test_cmp exp actual
-     '
+test_expect_success "$test_description" '
+       printf "\nx\n" > f &&
+       before=$(git hash-object f) &&
+       before=$(git rev-parse --short $before) &&
+       git add f &&
+       git commit -q -m. f &&
+       printf "\ny\n" > f &&
+       after=$(git hash-object f) &&
+       after=$(git rev-parse --short $after) &&
+       sed -e "s/^index .*/index $before..$after 100644/" expected >exp &&
+       git config --bool diff.suppressBlankEmpty true &&
+       git diff f > actual &&
+       test_cmp exp actual &&
+       perl -i.bak -p -e "s/^\$/ /" exp &&
+       git config --bool diff.suppressBlankEmpty false &&
+       git diff f > actual &&
+       test_cmp exp actual &&
+       git config --bool --unset diff.suppressBlankEmpty &&
+       git diff f > actual &&
+       test_cmp exp actual
+'
 
 test_done
index aad6c7f78db34703b2f9b1ed72239cd3b4005016..4cb9f0e523d2218566554cdccd9c2e3929f3d05b 100755 (executable)
@@ -148,7 +148,8 @@ test_expect_success 'diffstat does not run textconv' '
 # restore working setup
 echo file diff=foo >.gitattributes
 
-cat >expect.typechange <<'EOF'
+symlink=$(git rev-parse --short $(printf frotz | git hash-object --stdin))
+cat >expect.typechange <<EOF
 --- a/file
 +++ /dev/null
 @@ -1,2 +0,0 @@
@@ -156,7 +157,7 @@ cat >expect.typechange <<'EOF'
 -1
 diff --git a/file b/file
 new file mode 120000
-index 0000000..67be421
+index 0000000..$symlink
 --- /dev/null
 +++ b/file
 @@ -0,0 +1 @@
index 2f1737fcef185486dc626d616c37fdadc11deba1..0352bf81a90a38adf14fb7a980c98600e1f650b2 100755 (executable)
@@ -147,7 +147,7 @@ test_expect_success 'git diff --ignore-all-space, both files outside repo' '
 '
 
 test_expect_success 'git diff --quiet ignores stat-change only entries' '
-       test-chmtime +10 a &&
+       test-tool chmtime +10 a &&
        echo modified >>b &&
        test_expect_code 1 git diff --quiet
 '
index 04a44d5c61495c4c87db6ada952f5652b8e17642..bf33aedf4b22868fd820330a460965d27e66cb91 100755 (executable)
@@ -15,9 +15,13 @@ test_expect_success 'setup' '
        echo bar content 1 >bar.bin &&
        git add . &&
        git commit -m one &&
+       foo1=$(git rev-parse --short HEAD:foo.bin) &&
+       bar1=$(git rev-parse --short HEAD:bar.bin) &&
        echo foo content 2 >foo.bin &&
        echo bar content 2 >bar.bin &&
        git commit -a -m two &&
+       foo2=$(git rev-parse --short HEAD:foo.bin) &&
+       bar2=$(git rev-parse --short HEAD:bar.bin) &&
        echo "*.bin diff=magic" >.gitattributes &&
        git config diff.magic.textconv ./helper &&
        git config diff.magic.cachetextconv true
@@ -25,14 +29,14 @@ test_expect_success 'setup' '
 
 cat >expect <<EOF
 diff --git a/bar.bin b/bar.bin
-index fcf9166..28283d5 100644
+index $bar1..$bar2 100644
 --- a/bar.bin
 +++ b/bar.bin
 @@ -1 +1 @@
 -converted: bar content 1
 +converted: bar content 2
 diff --git a/foo.bin b/foo.bin
-index d5b9fe3..1345db2 100644
+index $foo1..$foo2 100644
 --- a/foo.bin
 +++ b/foo.bin
 @@ -1 +1 @@
@@ -59,7 +63,7 @@ test_expect_success 'cached textconv does not run helper' '
 
 cat >expect <<EOF
 diff --git a/bar.bin b/bar.bin
-index fcf9166..28283d5 100644
+index $bar1..$bar2 100644
 --- a/bar.bin
 +++ b/bar.bin
 @@ -1,2 +1,2 @@
@@ -67,7 +71,7 @@ index fcf9166..28283d5 100644
 -converted: bar content 1
 +converted: bar content 2
 diff --git a/foo.bin b/foo.bin
-index d5b9fe3..1345db2 100644
+index $foo1..$foo2 100644
 --- a/foo.bin
 +++ b/foo.bin
 @@ -1,2 +1,2 @@
@@ -84,7 +88,7 @@ test_expect_success 'changing textconv invalidates cache' '
 
 cat >expect <<EOF
 diff --git a/bar.bin b/bar.bin
-index fcf9166..28283d5 100644
+index $bar1..$bar2 100644
 --- a/bar.bin
 +++ b/bar.bin
 @@ -1,2 +1,2 @@
@@ -92,7 +96,7 @@ index fcf9166..28283d5 100644
 -converted: bar content 1
 +converted: bar content 2
 diff --git a/foo.bin b/foo.bin
-index d5b9fe3..1345db2 100644
+index $foo1..$foo2 100644
 --- a/foo.bin
 +++ b/foo.bin
 @@ -1 +1 @@
index d5ce72be63a5515d270bd407da47fee9048d1d1b..647905e01fb963efce34cd30b351a31a671cbb5e 100755 (executable)
@@ -3,6 +3,12 @@
 test_description='test unique sha1 abbreviation on "index from..to" line'
 . ./test-lib.sh
 
+if ! test_have_prereq SHA1
+then
+       skip_all='not using SHA-1 for objects'
+       test_done
+fi
+
 cat >expect_initial <<EOF
 100644 blob 51d2738463ea4ca66f8691c91e33ce64b7d41bb1   foo
 EOF
index 6471a68701dd4bc140d43ba91ebb899036ae0d4d..36f8ed8a818714abc234ca940a59693f4be21046 100755 (executable)
@@ -8,6 +8,7 @@ test_expect_success 'setup' '
        echo content >file1 &&
        mkdir subdir &&
        echo other content >subdir/file2 &&
+       blob=$(git hash-object subdir/file2) &&
        git add . &&
        git commit -m one
 '
@@ -17,10 +18,11 @@ check_diff () {
        shift
        expect=$1
        shift
+       short_blob=$(git rev-parse --short $blob)
        cat >expected <<-EOF
        diff --git a/$expect b/$expect
        new file mode 100644
-       index 0000000..25c05ef
+       index 0000000..$short_blob
        --- /dev/null
        +++ b/$expect
        @@ -0,0 +1 @@
@@ -68,7 +70,7 @@ check_raw () {
        expect=$1
        shift
        cat >expected <<-EOF
-       :000000 100644 0000000000000000000000000000000000000000 25c05ef3639d2d270e7fe765a67668f098092bc5 A      $expect
+       :000000 100644 0000000000000000000000000000000000000000 $blob A $expect
        EOF
        test_expect_success "--raw $*" "
                git -C '$dir' diff --no-abbrev --raw $* HEAD^ >actual &&
index d0f14475ca99b596fbe4addb4f8c543d07944ea5..ff7cfd884a44ebe0844c7ac6a21f25ed8374e7d4 100755 (executable)
@@ -37,7 +37,7 @@ test_expect_success 'diff-files -0' '
        for path in $paths
        do
                >"$path" &&
-               echo ":000000 100644 $_z40 $_z40 U      $path"
+               echo ":000000 100644 $ZERO_OID $ZERO_OID U      $path"
        done >diff-files-0.expect &&
        git diff-files -0 >diff-files-0.actual &&
        test_cmp diff-files-0.expect diff-files-0.actual
@@ -47,9 +47,9 @@ test_expect_success 'diff-files -1' '
        for path in $paths
        do
                >"$path" &&
-               echo ":000000 100644 $_z40 $_z40 U      $path" &&
+               echo ":000000 100644 $ZERO_OID $ZERO_OID U      $path" &&
                case "$path" in
-               x??) echo ":100644 100644 $blob1 $_z40 M        $path"
+               x??) echo ":100644 100644 $blob1 $ZERO_OID M    $path"
                esac
        done >diff-files-1.expect &&
        git diff-files -1 >diff-files-1.actual &&
@@ -60,9 +60,9 @@ test_expect_success 'diff-files -2' '
        for path in $paths
        do
                >"$path" &&
-               echo ":000000 100644 $_z40 $_z40 U      $path" &&
+               echo ":000000 100644 $ZERO_OID $ZERO_OID U      $path" &&
                case "$path" in
-               ?x?) echo ":100644 100644 $blob2 $_z40 M        $path"
+               ?x?) echo ":100644 100644 $blob2 $ZERO_OID M    $path"
                esac
        done >diff-files-2.expect &&
        git diff-files -2 >diff-files-2.actual &&
@@ -75,9 +75,9 @@ test_expect_success 'diff-files -3' '
        for path in $paths
        do
                >"$path" &&
-               echo ":000000 100644 $_z40 $_z40 U      $path" &&
+               echo ":000000 100644 $ZERO_OID $ZERO_OID U      $path" &&
                case "$path" in
-               ??x) echo ":100644 100644 $blob3 $_z40 M        $path"
+               ??x) echo ":100644 100644 $blob3 $ZERO_OID M    $path"
                esac
        done >diff-files-3.expect &&
        git diff-files -3 >diff-files-3.actual &&
index 18f42c5fff9a6e3ccb56f9e3122c6c0469ad81a9..fcae82fffa7f74a65fc6b475cc5c3eeefda3029a 100755 (executable)
@@ -19,37 +19,37 @@ test_expect_success 'create tree with matching file' '
 '
 
 test_expect_success 'raw diff shows null sha1 (addition)' '
-       echo ":000000 100644 $_z40 $_z40 A      foo" >expect &&
+       echo ":000000 100644 $ZERO_OID $ZERO_OID A      foo" >expect &&
        git diff-tree $EMPTY_TREE $bogus_tree >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'raw diff shows null sha1 (removal)' '
-       echo ":100644 000000 $_z40 $_z40 D      foo" >expect &&
+       echo ":100644 000000 $ZERO_OID $ZERO_OID D      foo" >expect &&
        git diff-tree $bogus_tree $EMPTY_TREE >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'raw diff shows null sha1 (modification)' '
-       echo ":100644 100644 $blob $_z40 M      foo" >expect &&
+       echo ":100644 100644 $blob $ZERO_OID M  foo" >expect &&
        git diff-tree $good_tree $bogus_tree >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'raw diff shows null sha1 (other direction)' '
-       echo ":100644 100644 $_z40 $blob M      foo" >expect &&
+       echo ":100644 100644 $ZERO_OID $blob M  foo" >expect &&
        git diff-tree $bogus_tree $good_tree >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'raw diff shows null sha1 (reverse)' '
-       echo ":100644 100644 $_z40 $blob M      foo" >expect &&
+       echo ":100644 100644 $ZERO_OID $blob M  foo" >expect &&
        git diff-tree -R $good_tree $bogus_tree >actual &&
        test_cmp expect actual
 '
 
 test_expect_success 'raw diff shows null sha1 (index)' '
-       echo ":100644 100644 $_z40 $blob M      foo" >expect &&
+       echo ":100644 100644 $ZERO_OID $blob M  foo" >expect &&
        git diff-index $bogus_tree >actual &&
        test_cmp expect actual
 '
index 0a23242cb6aab7903aac9b767b0c4913208c044b..c24ee175ef0e9c5d1abf2c3e931a8df76c8cd4b4 100755 (executable)
@@ -59,12 +59,12 @@ test_expect_success 'create trees with duplicate entries' '
 
 test_expect_success 'diff-tree between trees' '
        {
-               printf ":000000 100644 $_z40 $blob_two A\touter/inner\n" &&
-               printf ":000000 100644 $_z40 $blob_two A\touter/inner\n" &&
-               printf ":000000 100644 $_z40 $blob_two A\touter/inner\n" &&
-               printf ":100644 000000 $blob_two $_z40 D\touter/inner\n" &&
-               printf ":100644 000000 $blob_two $_z40 D\touter/inner\n" &&
-               printf ":100644 000000 $blob_two $_z40 D\touter/inner\n"
+               printf ":000000 100644 $ZERO_OID $blob_two A\touter/inner\n" &&
+               printf ":000000 100644 $ZERO_OID $blob_two A\touter/inner\n" &&
+               printf ":000000 100644 $ZERO_OID $blob_two A\touter/inner\n" &&
+               printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" &&
+               printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n" &&
+               printf ":100644 000000 $blob_two $ZERO_OID D\touter/inner\n"
        } >expect &&
        git diff-tree -r --no-abbrev one two >actual &&
        test_cmp expect actual
index 1eccfb71d0c8e26f88708459f065dea622baf9d3..1ebc587f8fc0010713f52196206462fa915cbca5 100755 (executable)
@@ -140,8 +140,8 @@ test_expect_success setup '
                echo "# User $GIT_AUTHOR_NAME <$GIT_AUTHOR_EMAIL>" &&
                echo "# Date $test_tick 25200" &&
                echo "#      $(git show --pretty="%aD" -s second)" &&
-               echo "# Node ID $_z40" &&
-               echo "# Parent  $_z40" &&
+               echo "# Node ID $ZERO_OID" &&
+               echo "# Parent  $ZERO_OID" &&
                cat msg &&
                echo &&
                git diff-tree --no-commit-id -p second
index 16432781d2e0d52c33dfb1444fcce4459b417e8b..9d8d3c72e7efe68b8e0011c1ec9b77d9a0820b30 100755 (executable)
@@ -171,7 +171,7 @@ test_expect_success 'am --skip leaves index stat info alone' '
        git checkout -f --orphan skip-stat-info &&
        git reset &&
        test_commit skip-should-be-untouched &&
-       test-chmtime =0 skip-should-be-untouched.t &&
+       test-tool chmtime =0 skip-should-be-untouched.t &&
        git update-index --refresh &&
        git diff-files --exit-code --quiet &&
        test_must_fail git am 0001-*.patch &&
@@ -183,7 +183,7 @@ test_expect_success 'am --abort leaves index stat info alone' '
        git checkout -f --orphan abort-stat-info &&
        git reset &&
        test_commit abort-should-be-untouched &&
-       test-chmtime =0 abort-should-be-untouched.t &&
+       test-tool chmtime =0 abort-should-be-untouched.t &&
        git update-index --refresh &&
        git diff-files --exit-code --quiet &&
        test_must_fail git am 0001-*.patch &&
index d97d2bebc9850c8ba96a8263ed081fced2ecc153..8417e5a4b105a54a8de23af8bae2bdaf28c257cb 100755 (executable)
@@ -166,7 +166,7 @@ test_expect_success 'first postimage wins' '
        git commit -q -a -m "prefer first over second" &&
        test -f $rr/postimage &&
 
-       oldmtimepost=$(test-chmtime -v -60 $rr/postimage | cut -f 1) &&
+       oldmtimepost=$(test-tool chmtime --get -60 $rr/postimage) &&
 
        git checkout -b third master &&
        git show second^:a1 | sed "s/To die: t/To die! T/" >a1 &&
@@ -179,7 +179,7 @@ test_expect_success 'first postimage wins' '
 '
 
 test_expect_success 'rerere updates postimage timestamp' '
-       newmtimepost=$(test-chmtime -v +0 $rr/postimage | cut -f 1) &&
+       newmtimepost=$(test-tool chmtime --get $rr/postimage) &&
        test $oldmtimepost -lt $newmtimepost
 '
 
@@ -220,9 +220,9 @@ test_expect_success 'set up for garbage collection tests' '
        almost_60_days_ago=$((60-60*86400)) &&
        just_over_60_days_ago=$((-1-60*86400)) &&
 
-       test-chmtime =$just_over_60_days_ago $rr/preimage &&
-       test-chmtime =$almost_60_days_ago $rr/postimage &&
-       test-chmtime =$almost_15_days_ago $rr2/preimage
+       test-tool chmtime =$just_over_60_days_ago $rr/preimage &&
+       test-tool chmtime =$almost_60_days_ago $rr/postimage &&
+       test-tool chmtime =$almost_15_days_ago $rr2/preimage
 '
 
 test_expect_success 'gc preserves young or recently used records' '
@@ -232,8 +232,8 @@ test_expect_success 'gc preserves young or recently used records' '
 '
 
 test_expect_success 'old records rest in peace' '
-       test-chmtime =$just_over_60_days_ago $rr/postimage &&
-       test-chmtime =$just_over_15_days_ago $rr2/preimage &&
+       test-tool chmtime =$just_over_60_days_ago $rr/postimage &&
+       test-tool chmtime =$just_over_15_days_ago $rr2/preimage &&
        git rerere gc &&
        ! test -f $rr/preimage &&
        ! test -f $rr2/preimage
@@ -243,14 +243,14 @@ rerere_gc_custom_expiry_test () {
        five_days="$1" right_now="$2"
        test_expect_success "rerere gc with custom expiry ($five_days, $right_now)" '
                rm -fr .git/rr-cache &&
-               rr=.git/rr-cache/$_z40 &&
+               rr=.git/rr-cache/$ZERO_OID &&
                mkdir -p "$rr" &&
                >"$rr/preimage" &&
                >"$rr/postimage" &&
 
                two_days_ago=$((-2*86400)) &&
-               test-chmtime =$two_days_ago "$rr/preimage" &&
-               test-chmtime =$two_days_ago "$rr/postimage" &&
+               test-tool chmtime =$two_days_ago "$rr/preimage" &&
+               test-tool chmtime =$two_days_ago "$rr/postimage" &&
 
                find .git/rr-cache -type f | sort >original &&
 
@@ -512,7 +512,7 @@ test_expect_success 'multiple identical conflicts' '
        count_pre_post 2 0 &&
 
        # Pretend that the conflicts were made quite some time ago
-       find .git/rr-cache/ -type f | xargs test-chmtime -172800 &&
+       test-tool chmtime -172800 $(find .git/rr-cache/ -type f) &&
 
        # Unresolved entries have not expired yet
        git -c gc.rerereresolved=5 -c gc.rerereunresolved=5 rerere gc &&
@@ -568,7 +568,7 @@ test_expect_success 'multiple identical conflicts' '
        git rerere &&
 
        # Pretend that the resolutions are old again
-       find .git/rr-cache/ -type f | xargs test-chmtime -172800 &&
+       test-tool chmtime -172800 $(find .git/rr-cache/ -type f) &&
 
        # Resolved entries have not expired yet
        git -c gc.rerereresolved=5 -c gc.rerereunresolved=5 rerere gc &&
index da10478f59da1a301edf7def229d37fbc964dce9..58c27736762dde372408a4dacfb030f0e1a55b99 100755 (executable)
@@ -59,7 +59,7 @@ test_expect_success 'setup' '
 fuzz() {
        file=$1 &&
        sed "
-                       s/$_x40/OBJECT_NAME/g
+                       s/$OID_REGEX/OBJECT_NAME/g
                        s/$_x35/OBJID/g
                        s/^ \{6\}[CTa].*/      SUBJECT/g
                        s/^ \{8\}[^ ].*/        CONTINUATION/g
@@ -127,6 +127,11 @@ test_expect_success !MINGW 'shortlog can read --format=raw output' '
        test_cmp expect out
 '
 
+test_expect_success 'shortlog from non-git directory refuses extra arguments' '
+       test_must_fail env GIT_DIR=non-existing git shortlog foo 2>out &&
+       test_i18ngrep "too many arguments" out
+'
+
 test_expect_success 'shortlog should add newline when input line matches wraplen' '
        cat >expect <<\EOF &&
 A U Thor (2):
index 591f35daaf5825cfdcf8e7fccf4f52462bbf8f78..2052cadb1109d3644b0c3f82b707f8e8bb35f945 100755 (executable)
@@ -516,22 +516,22 @@ test_expect_success 'log decoration properly follows tag chain' '
        git commit --amend -m shorter &&
        git log --no-walk --tags --pretty="%H %d" --decorate=full >actual &&
        cat <<-EOF >expected &&
-       $head1  (tag: refs/tags/tag2)
        $head2  (tag: refs/tags/message-one)
        $old_head1  (tag: refs/tags/message-two)
+       $head1  (tag: refs/tags/tag2)
        EOF
-       sort actual >actual1 &&
+       sort -k3 actual >actual1 &&
        test_cmp expected actual1
 '
 
 test_expect_success 'clean log decoration' '
        git log --no-walk --tags --pretty="%H %D" --decorate=full >actual &&
        cat >expected <<-EOF &&
-       $head1 tag: refs/tags/tag2
        $head2 tag: refs/tags/message-one
        $old_head1 tag: refs/tags/message-two
+       $head1 tag: refs/tags/tag2
        EOF
-       sort actual >actual1 &&
+       sort -k3 actual >actual1 &&
        test_cmp expected actual1
 '
 
index a1705f70cffe2332fc65f670797539986f330f70..62f335b2d9fe7268f8f6cd878067de8528b5cb75 100755 (executable)
@@ -45,8 +45,9 @@ test_expect_success 'git log -- :' '
 '
 
 test_expect_success 'git log HEAD -- :/' '
+       initial=$(git rev-parse --short HEAD^) &&
        cat >expected <<-EOF &&
-       24b24cf initial
+       $initial initial
        EOF
        (cd sub && git log --oneline HEAD -- :/ >../actual) &&
        test_cmp expected actual
index fe2d4f15a73f082c516a03b1877c4cf82982138a..2a97b27b0a68f94ab7204764ced5fd1457da3d9c 100755 (executable)
@@ -101,7 +101,7 @@ test_expect_success \
      ten=0123456789 && hundred=$ten$ten$ten$ten$ten$ten$ten$ten$ten$ten &&
      echo long filename >a/four$hundred &&
      mkdir a/bin &&
-     test-genrandom "frotz" 500000 >a/bin/sh &&
+     test-tool genrandom "frotz" 500000 >a/bin/sh &&
      printf "A\$Format:%s\$O" "$SUBSTFORMAT" >a/substfile1 &&
      printf "A not substituted O" >a/substfile2 &&
      if test_have_prereq SYMLINKS; then
@@ -192,7 +192,7 @@ test_expect_success \
     'validate file modification time' \
     'mkdir extract &&
      "$TAR" xf b.tar -C extract a/a &&
-     test-chmtime -v +0 extract/a/a |cut -f 1 >b.mtime &&
+     test-tool chmtime --get extract/a/a >b.mtime &&
      echo "1117231200" >expected.mtime &&
      test_cmp expected.mtime b.mtime'
 
index 08c210f03586ab8cd26d69cb0761180ef5588f58..fca001eb9bb5767b1aff6439dbc98e49ed3aaef8 100755 (executable)
@@ -81,7 +81,7 @@ test_expect_success 'setup: two scripts for reading pull requests' '
        cat <<-EOT >fuzz.sed
        #!/bin/sed -nf
        s/$downstream_url_for_sed/URL/g
-       s/$_x40/OBJECT_NAME/g
+       s/$OID_REGEX/OBJECT_NAME/g
        s/A U Thor/AUTHOR/g
        s/[-0-9]\{10\} [:0-9]\{8\} [-+][0-9]\{4\}/DATE/g
        s/        [^ ].*/        SUBJECT/g
index 9c68b992511b7098df0570ca37e0add468a8a093..2336d09dcc45f3b808c5e5d6a7c43c8129e8cecc 100755 (executable)
@@ -16,8 +16,8 @@ test_expect_success \
      perl -e "print \"a\" x 4096;" > a &&
      perl -e "print \"b\" x 4096;" > b &&
      perl -e "print \"c\" x 4096;" > c &&
-     test-genrandom "seed a" 2097152 > a_big &&
-     test-genrandom "seed b" 2097152 > b_big &&
+     test-tool genrandom "seed a" 2097152 > a_big &&
+     test-tool genrandom "seed b" 2097152 > b_big &&
      git update-index --add a a_big b b_big c &&
      cat c >d && echo foo >>d && git update-index --add d &&
      tree=$(git write-tree) &&
@@ -311,8 +311,8 @@ test_expect_success 'unpacking with --strict' '
        rm -f .git/index &&
        tail -n 10 LIST | git update-index --index-info &&
        ST=$(git write-tree) &&
-       PACK5=$( git rev-list --objects "$LIST" "$LI" "$ST" | \
-               git pack-objects test-5 ) &&
+       git rev-list --objects "$LIST" "$LI" "$ST" >actual &&
+       PACK5=$( git pack-objects test-5 <actual ) &&
        PACK6=$( (
                        echo "$LIST"
                        echo "$LI"
@@ -358,8 +358,8 @@ test_expect_success 'index-pack with --strict' '
        rm -f .git/index &&
        tail -n 10 LIST | git update-index --index-info &&
        ST=$(git write-tree) &&
-       PACK5=$( git rev-list --objects "$LIST" "$LI" "$ST" | \
-               git pack-objects test-5 ) &&
+       git rev-list --objects "$LIST" "$LI" "$ST" >actual &&
+       PACK5=$( git pack-objects test-5 <actual ) &&
        PACK6=$( (
                        echo "$LIST"
                        echo "$LI"
@@ -421,6 +421,12 @@ test_expect_success 'index-pack <pack> works in non-repo' '
        test_path_is_file foo.idx
 '
 
+test_expect_success 'index-pack --strict <pack> works in non-repo' '
+       rm -f foo.idx &&
+       nongit git index-pack --strict ../foo.pack &&
+       test_path_is_file foo.idx
+'
+
 test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'index-pack --threads=N or pack.threads=N warns when no pthreads' '
        test_must_fail git index-pack --threads=2 2>err &&
        grep ^warning: err >warnings &&
@@ -457,6 +463,11 @@ test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'pack-objects --threads=N or pack.
        grep -F "no threads support, ignoring pack.threads" err
 '
 
+test_expect_success 'pack-objects in too-many-packs mode' '
+       GIT_TEST_FULL_IN_PACK_ARRAY=1 git repack -ad &&
+       git fsck
+'
+
 #
 # WARNING!
 #
@@ -466,9 +477,11 @@ test_expect_success !PTHREADS,C_LOCALE_OUTPUT 'pack-objects --threads=N or pack.
 
 test_expect_success \
     'fake a SHA1 hash collision' \
-    'test -f   .git/objects/c8/2de19312b6c3695c0c18f70709a6c535682a67 &&
-     cp -f     .git/objects/9d/235ed07cd19811a6ceb342de82f190e49c9f68 \
-               .git/objects/c8/2de19312b6c3695c0c18f70709a6c535682a67'
+    'long_a=$(git hash-object a | sed -e "s!^..!&/!") &&
+     long_b=$(git hash-object b | sed -e "s!^..!&/!") &&
+     test -f   .git/objects/$long_b &&
+     cp -f     .git/objects/$long_a \
+               .git/objects/$long_b'
 
 test_expect_success \
     'make sure index-pack detects the SHA1 collision' \
index cae8c2e8822ccc1e464e3f5b71c99c1f6b1c2323..76f9798ab958cae2414cbcc496bbb22af85f0ac5 100755 (executable)
@@ -12,7 +12,7 @@ test_expect_success \
      for i in a b c
      do
          echo $i >$i &&
-         test-genrandom "$i" 32768 >>$i &&
+        test-tool genrandom "$i" 32768 >>$i &&
          git update-index --add $i || return 1
      done &&
      echo d >d && cat c >>d && git update-index --add d &&
index d695a6082edf69c6ab377ea825519097f84162f3..bb9b8bb3097c05f6e28c37fa24fa27d5bb5b805d 100755 (executable)
@@ -15,17 +15,17 @@ test_expect_success \
      while test $i -le 100
      do
          iii=$(printf '%03i' $i)
-         test-genrandom "bar" 200 > wide_delta_$iii &&
-         test-genrandom "baz $iii" 50 >> wide_delta_$iii &&
-         test-genrandom "foo"$i 100 > deep_delta_$iii &&
-         test-genrandom "foo"$(expr $i + 1) 100 >> deep_delta_$iii &&
-         test-genrandom "foo"$(expr $i + 2) 100 >> deep_delta_$iii &&
+        test-tool genrandom "bar" 200 > wide_delta_$iii &&
+        test-tool genrandom "baz $iii" 50 >> wide_delta_$iii &&
+        test-tool genrandom "foo"$i 100 > deep_delta_$iii &&
+        test-tool genrandom "foo"$(expr $i + 1) 100 >> deep_delta_$iii &&
+        test-tool genrandom "foo"$(expr $i + 2) 100 >> deep_delta_$iii &&
          echo $iii >file_$iii &&
-         test-genrandom "$iii" 8192 >>file_$iii &&
+        test-tool genrandom "$iii" 8192 >>file_$iii &&
          git update-index --add file_$iii deep_delta_$iii wide_delta_$iii &&
          i=$(expr $i + 1) || return 1
      done &&
-     { echo 101 && test-genrandom 100 8192; } >file_101 &&
+     { echo 101 && test-tool genrandom 100 8192; } >file_101 &&
      git update-index --add file_101 &&
      tree=$(git write-tree) &&
      commit=$(git commit-tree $tree </dev/null) && {
index 5940ce2084a6e9cc935a0e5784ff8b6bff8e035d..3634e258f8bf66c2c1917c1598f6f21486c08684 100755 (executable)
@@ -19,14 +19,14 @@ test_description='resilience to pack corruptions with redundant objects'
 # 3) object header is always 2 bytes.
 
 create_test_files() {
-    test-genrandom "foo" 2000 > file_1 &&
-    test-genrandom "foo" 1800 > file_2 &&
-    test-genrandom "foo" 1800 > file_3 &&
+    test-tool genrandom "foo" 2000 > file_1 &&
+    test-tool genrandom "foo" 1800 > file_2 &&
+    test-tool genrandom "foo" 1800 > file_3 &&
     echo " base " >> file_1 &&
     echo " delta1 " >> file_2 &&
     echo " delta delta2 " >> file_3 &&
-    test-genrandom "bar" 150 >> file_2 &&
-    test-genrandom "baz" 100 >> file_3
+    test-tool genrandom "bar" 150 >> file_2 &&
+    test-tool genrandom "baz" 100 >> file_3
 }
 
 create_new_pack() {
index 6694c19a1eecf10117b843bbacbc5bb47924c9c8..f20f03c1039256f0bc674e3969176a2c592919dd 100755 (executable)
@@ -15,7 +15,7 @@ add_blob() {
        BLOB_FILE=.git/objects/$(echo $BLOB | sed "s/^../&\//") &&
        verbose test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
        test_path_is_file $BLOB_FILE &&
-       test-chmtime =+0 $BLOB_FILE
+       test-tool chmtime =+0 $BLOB_FILE
 }
 
 test_expect_success setup '
@@ -33,7 +33,7 @@ test_expect_success 'prune stale packs' '
        orig_pack=$(echo .git/objects/pack/*.pack) &&
        : > .git/objects/tmp_1.pack &&
        : > .git/objects/tmp_2.pack &&
-       test-chmtime =-86501 .git/objects/tmp_1.pack &&
+       test-tool chmtime =-86501 .git/objects/tmp_1.pack &&
        git prune --expire 1.day &&
        test_path_is_file $orig_pack &&
        test_path_is_file .git/objects/tmp_2.pack &&
@@ -47,7 +47,7 @@ test_expect_success 'prune --expire' '
        git prune --expire=1.hour.ago &&
        verbose test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
        test_path_is_file $BLOB_FILE &&
-       test-chmtime =-86500 $BLOB_FILE &&
+       test-tool chmtime =-86500 $BLOB_FILE &&
        git prune --expire 1.day &&
        verbose test $before = $(git count-objects | sed "s/ .*//") &&
        test_path_is_missing $BLOB_FILE
@@ -57,11 +57,11 @@ test_expect_success 'prune --expire' '
 test_expect_success 'gc: implicit prune --expire' '
 
        add_blob &&
-       test-chmtime =-$((2*$week-30)) $BLOB_FILE &&
+       test-tool chmtime =-$((2*$week-30)) $BLOB_FILE &&
        git gc &&
        verbose test $((1 + $before)) = $(git count-objects | sed "s/ .*//") &&
        test_path_is_file $BLOB_FILE &&
-       test-chmtime =-$((2*$week+1)) $BLOB_FILE &&
+       test-tool chmtime =-$((2*$week+1)) $BLOB_FILE &&
        git gc &&
        verbose test $before = $(git count-objects | sed "s/ .*//") &&
        test_path_is_missing $BLOB_FILE
@@ -141,7 +141,7 @@ test_expect_success 'prune: do not prune heads listed as an argument' '
 test_expect_success 'gc --no-prune' '
 
        add_blob &&
-       test-chmtime =-$((5001*$day)) $BLOB_FILE &&
+       test-tool chmtime =-$((5001*$day)) $BLOB_FILE &&
        git config gc.pruneExpire 2.days.ago &&
        git gc --no-prune &&
        verbose test 1 = $(git count-objects | sed "s/ .*//") &&
@@ -163,7 +163,7 @@ test_expect_success 'gc respects gc.pruneExpire' '
 test_expect_success 'gc --prune=<date>' '
 
        add_blob &&
-       test-chmtime =-$((5001*$day)) $BLOB_FILE &&
+       test-tool chmtime =-$((5001*$day)) $BLOB_FILE &&
        git gc --prune=5002.days.ago &&
        test_path_is_file $BLOB_FILE &&
        git gc --prune=5000.days.ago &&
@@ -205,7 +205,7 @@ test_expect_success 'prune --expire=never' '
 
 test_expect_success 'gc: prune old objects after local clone' '
        add_blob &&
-       test-chmtime =-$((2*$week+1)) $BLOB_FILE &&
+       test-tool chmtime =-$((2*$week+1)) $BLOB_FILE &&
        git clone --no-hardlinks . aclone &&
        (
                cd aclone &&
@@ -320,4 +320,14 @@ test_expect_success 'prune: handle HEAD reflog in multiple worktrees' '
        test_cmp expected actual
 '
 
+test_expect_success 'prune: handle expire option correctly' '
+       test_must_fail git prune --expire 2>error &&
+       test_i18ngrep "requires a value" error &&
+
+       test_must_fail git prune --expire=nyah 2>error &&
+       test_i18ngrep "malformed expiration" error &&
+
+       git prune --no-expire
+'
+
 test_done
index 156ae9e9d335029e63430a6cc7d0ec2fd0d68dd3..6845c1f3c3a3acc4540e1340627240d90d7bb145 100755 (executable)
@@ -4,6 +4,12 @@ test_description='handling of duplicate objects in incoming packfiles'
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-pack.sh
 
+if ! test_have_prereq SHA1
+then
+       skip_all='not using SHA-1 for objects'
+       test_done
+fi
+
 # The sha1s we have in our pack. It's important that these have the same
 # starting byte, so that they end up in the same fanout section of the index.
 # That lets us make sure we are exercising the binary search with both sets.
index 3e7861b075ffa54f0214aaa349df33be7a113d35..491556dad9792619974851ef255198c5d247af2f 100755 (executable)
@@ -4,6 +4,12 @@ test_description='test index-pack handling of delta cycles in packfiles'
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-pack.sh
 
+if ! test_have_prereq SHA1
+then
+       skip_all='not using SHA-1 for objects'
+       test_done
+fi
+
 # Two similar-ish objects that we have computed deltas between.
 A=01d7713666f4de822776c7622c10f1b07de280dc
 B=e68fe8129b546b101aee9510c5328e7f21ca1d18
index 20e2473a03b645d690b25598bc0cb2e421034b6c..2d22a17c4a7f9dcc402e89e73ce01c97ebd4ba48 100755 (executable)
@@ -264,9 +264,9 @@ test_expect_success 'pack with missing parent' '
 '
 
 test_expect_success JGIT 'we can read jgit bitmaps' '
-       git clone . compat-jgit &&
+       git clone --bare . compat-jgit.git &&
        (
-               cd compat-jgit &&
+               cd compat-jgit.git &&
                rm -f .git/objects/pack/*.bitmap &&
                jgit gc &&
                git rev-list --test-bitmap HEAD
@@ -274,9 +274,9 @@ test_expect_success JGIT 'we can read jgit bitmaps' '
 '
 
 test_expect_success JGIT 'jgit can read our bitmaps' '
-       git clone . compat-us &&
+       git clone --bare . compat-us.git &&
        (
-               cd compat-us &&
+               cd compat-us.git &&
                git repack -adb &&
                # jgit gc will barf if it does not like our bitmaps
                jgit gc
@@ -284,7 +284,7 @@ test_expect_success JGIT 'jgit can read our bitmaps' '
 '
 
 test_expect_success 'splitting packs does not generate bogus bitmaps' '
-       test-genrandom foo $((1024 * 1024)) >rand &&
+       test-tool genrandom foo $((1024 * 1024)) >rand &&
        git add rand &&
        git commit -m "commit with big file" &&
        git -c pack.packSizeLimit=500k repack -adb &&
@@ -331,4 +331,17 @@ test_expect_success 'pack reuse respects --incremental' '
        git show-index <empty.idx >actual &&
        test_cmp expect actual
 '
+
+test_expect_success 'truncated bitmap fails gracefully' '
+       git repack -ad &&
+       git rev-list --use-bitmap-index --count --all >expect &&
+       bitmap=$(ls .git/objects/pack/*.bitmap) &&
+       test_when_finished "rm -f $bitmap" &&
+       head -c 512 <$bitmap >$bitmap.tmp &&
+       mv -f $bitmap.tmp $bitmap &&
+       git rev-list --use-bitmap-index --count --all >actual 2>stderr &&
+       test_cmp expect actual &&
+       test_i18ngrep corrupt stderr
+'
+
 test_done
index 9372508c993e72ad99da004ca2400df81c721006..4fe4ad9d6166d9a82cb944fadfc0317b5052b973 100755 (executable)
@@ -163,8 +163,8 @@ test_expect_success 'bogus offset inside v2 extended table' '
 
 test_expect_success 'bogus OFS_DELTA in packfile' '
        # Generate a pack with a delta in it.
-       base=$(test-genrandom foo 3000 | git hash-object --stdin -w) &&
-       delta=$(test-genrandom foo 2000 | git hash-object --stdin -w) &&
+       base=$(test-tool genrandom foo 3000 | git hash-object --stdin -w) &&
+       delta=$(test-tool genrandom foo 2000 | git hash-object --stdin -w) &&
        do_pack "$base $delta" --delta-base-offset &&
        rm -f .git/objects/??/* &&
 
index f7dbdfb412f3ee139ce88e56d1cd8be166d3bbd2..f31995d3d28d9fcd590c91aed7686aef87e332af 100755 (executable)
@@ -73,7 +73,7 @@ make_pack () {
 }
 
 test_expect_success 'setup' '
-       test-genrandom base 4096 >base &&
+       test-tool genrandom base 4096 >base &&
        for i in one two
        do
                # we want shared content here to encourage deltas...
index 2ed479b712aed7a8f11c8495c0eba72788eb4f26..0f06c40eb13f31d8f06962dd1c88c5ff5810618f 100755 (executable)
@@ -47,7 +47,7 @@ test_description='pack-objects breaks long cross-pack delta chains'
 # repeatedly-modified file to generate the delta chain).
 
 test_expect_success 'create series of packs' '
-       test-genrandom foo 4096 >content &&
+       test-tool genrandom foo 4096 >content &&
        prev= &&
        for i in $(test_seq 1 10)
        do
diff --git a/t/t5318-commit-graph.sh b/t/t5318-commit-graph.sh
new file mode 100755 (executable)
index 0000000..a380419
--- /dev/null
@@ -0,0 +1,224 @@
+#!/bin/sh
+
+test_description='commit graph'
+. ./test-lib.sh
+
+test_expect_success 'setup full repo' '
+       mkdir full &&
+       cd "$TRASH_DIRECTORY/full" &&
+       git init &&
+       git config core.commitGraph true &&
+       objdir=".git/objects"
+'
+
+test_expect_success 'write graph with no packs' '
+       cd "$TRASH_DIRECTORY/full" &&
+       git commit-graph write --object-dir . &&
+       test_path_is_file info/commit-graph
+'
+
+test_expect_success 'create commits and repack' '
+       cd "$TRASH_DIRECTORY/full" &&
+       for i in $(test_seq 3)
+       do
+               test_commit $i &&
+               git branch commits/$i
+       done &&
+       git repack
+'
+
+graph_git_two_modes() {
+       git -c core.graph=true $1 >output
+       git -c core.graph=false $1 >expect
+       test_cmp output expect
+}
+
+graph_git_behavior() {
+       MSG=$1
+       DIR=$2
+       BRANCH=$3
+       COMPARE=$4
+       test_expect_success "check normal git operations: $MSG" '
+               cd "$TRASH_DIRECTORY/$DIR" &&
+               graph_git_two_modes "log --oneline $BRANCH" &&
+               graph_git_two_modes "log --topo-order $BRANCH" &&
+               graph_git_two_modes "log --graph $COMPARE..$BRANCH" &&
+               graph_git_two_modes "branch -vv" &&
+               graph_git_two_modes "merge-base -a $BRANCH $COMPARE"
+       '
+}
+
+graph_git_behavior 'no graph' full commits/3 commits/1
+
+graph_read_expect() {
+       OPTIONAL=""
+       NUM_CHUNKS=3
+       if test ! -z $2
+       then
+               OPTIONAL=" $2"
+               NUM_CHUNKS=$((3 + $(echo "$2" | wc -w)))
+       fi
+       cat >expect <<- EOF
+       header: 43475048 1 1 $NUM_CHUNKS 0
+       num_commits: $1
+       chunks: oid_fanout oid_lookup commit_metadata$OPTIONAL
+       EOF
+       git commit-graph read >output &&
+       test_cmp expect output
+}
+
+test_expect_success 'write graph' '
+       cd "$TRASH_DIRECTORY/full" &&
+       graph1=$(git commit-graph write) &&
+       test_path_is_file $objdir/info/commit-graph &&
+       graph_read_expect "3"
+'
+
+graph_git_behavior 'graph exists' full commits/3 commits/1
+
+test_expect_success 'Add more commits' '
+       cd "$TRASH_DIRECTORY/full" &&
+       git reset --hard commits/1 &&
+       for i in $(test_seq 4 5)
+       do
+               test_commit $i &&
+               git branch commits/$i
+       done &&
+       git reset --hard commits/2 &&
+       for i in $(test_seq 6 7)
+       do
+               test_commit $i &&
+               git branch commits/$i
+       done &&
+       git reset --hard commits/2 &&
+       git merge commits/4 &&
+       git branch merge/1 &&
+       git reset --hard commits/4 &&
+       git merge commits/6 &&
+       git branch merge/2 &&
+       git reset --hard commits/3 &&
+       git merge commits/5 commits/7 &&
+       git branch merge/3 &&
+       git repack
+'
+
+# Current graph structure:
+#
+#   __M3___
+#  /   |   \
+# 3 M1 5 M2 7
+# |/  \|/  \|
+# 2    4    6
+# |___/____/
+# 1
+
+test_expect_success 'write graph with merges' '
+       cd "$TRASH_DIRECTORY/full" &&
+       git commit-graph write &&
+       test_path_is_file $objdir/info/commit-graph &&
+       graph_read_expect "10" "large_edges"
+'
+
+graph_git_behavior 'merge 1 vs 2' full merge/1 merge/2
+graph_git_behavior 'merge 1 vs 3' full merge/1 merge/3
+graph_git_behavior 'merge 2 vs 3' full merge/2 merge/3
+
+test_expect_success 'Add one more commit' '
+       cd "$TRASH_DIRECTORY/full" &&
+       test_commit 8 &&
+       git branch commits/8 &&
+       ls $objdir/pack | grep idx >existing-idx &&
+       git repack &&
+       ls $objdir/pack| grep idx | grep -v --file=existing-idx >new-idx
+'
+
+# Current graph structure:
+#
+#      8
+#      |
+#   __M3___
+#  /   |   \
+# 3 M1 5 M2 7
+# |/  \|/  \|
+# 2    4    6
+# |___/____/
+# 1
+
+graph_git_behavior 'mixed mode, commit 8 vs merge 1' full commits/8 merge/1
+graph_git_behavior 'mixed mode, commit 8 vs merge 2' full commits/8 merge/2
+
+test_expect_success 'write graph with new commit' '
+       cd "$TRASH_DIRECTORY/full" &&
+       git commit-graph write &&
+       test_path_is_file $objdir/info/commit-graph &&
+       graph_read_expect "11" "large_edges"
+'
+
+graph_git_behavior 'full graph, commit 8 vs merge 1' full commits/8 merge/1
+graph_git_behavior 'full graph, commit 8 vs merge 2' full commits/8 merge/2
+
+test_expect_success 'write graph with nothing new' '
+       cd "$TRASH_DIRECTORY/full" &&
+       git commit-graph write &&
+       test_path_is_file $objdir/info/commit-graph &&
+       graph_read_expect "11" "large_edges"
+'
+
+graph_git_behavior 'cleared graph, commit 8 vs merge 1' full commits/8 merge/1
+graph_git_behavior 'cleared graph, commit 8 vs merge 2' full commits/8 merge/2
+
+test_expect_success 'build graph from latest pack with closure' '
+       cd "$TRASH_DIRECTORY/full" &&
+       cat new-idx | git commit-graph write --stdin-packs &&
+       test_path_is_file $objdir/info/commit-graph &&
+       graph_read_expect "9" "large_edges"
+'
+
+graph_git_behavior 'graph from pack, commit 8 vs merge 1' full commits/8 merge/1
+graph_git_behavior 'graph from pack, commit 8 vs merge 2' full commits/8 merge/2
+
+test_expect_success 'build graph from commits with closure' '
+       cd "$TRASH_DIRECTORY/full" &&
+       git tag -a -m "merge" tag/merge merge/2 &&
+       git rev-parse tag/merge >commits-in &&
+       git rev-parse merge/1 >>commits-in &&
+       cat commits-in | git commit-graph write --stdin-commits &&
+       test_path_is_file $objdir/info/commit-graph &&
+       graph_read_expect "6"
+'
+
+graph_git_behavior 'graph from commits, commit 8 vs merge 1' full commits/8 merge/1
+graph_git_behavior 'graph from commits, commit 8 vs merge 2' full commits/8 merge/2
+
+test_expect_success 'build graph from commits with append' '
+       cd "$TRASH_DIRECTORY/full" &&
+       git rev-parse merge/3 | git commit-graph write --stdin-commits --append &&
+       test_path_is_file $objdir/info/commit-graph &&
+       graph_read_expect "10" "large_edges"
+'
+
+graph_git_behavior 'append graph, commit 8 vs merge 1' full commits/8 merge/1
+graph_git_behavior 'append graph, commit 8 vs merge 2' full commits/8 merge/2
+
+test_expect_success 'setup bare repo' '
+       cd "$TRASH_DIRECTORY" &&
+       git clone --bare --no-local full bare &&
+       cd bare &&
+       git config core.commitGraph true &&
+       baredir="./objects"
+'
+
+graph_git_behavior 'bare repo, commit 8 vs merge 1' bare commits/8 merge/1
+graph_git_behavior 'bare repo, commit 8 vs merge 2' bare commits/8 merge/2
+
+test_expect_success 'write graph in bare repo' '
+       cd "$TRASH_DIRECTORY/bare" &&
+       git commit-graph write &&
+       test_path_is_file $baredir/info/commit-graph &&
+       graph_read_expect "11" "large_edges"
+'
+
+graph_git_behavior 'bare repo with graph, commit 8 vs merge 1' bare commits/8 merge/1
+graph_git_behavior 'bare repo with graph, commit 8 vs merge 2' bare commits/8 merge/2
+
+test_done
index d375d7110d102d6b3ea194e4f09a9b5f391ed496..911eae1bf7518485ace0fbd417e3ea0bbb18a9cf 100755 (executable)
@@ -180,7 +180,7 @@ test_expect_success 'receive-pack runs auto-gc in remote repo' '
            # And create a file that follows the temporary object naming
            # convention for the auto-gc to remove
            : >.git/objects/tmp_test_object &&
-           test-chmtime =-1209601 .git/objects/tmp_test_object
+           test-tool chmtime =-1209601 .git/objects/tmp_test_object
        ) &&
        (
            cd parent &&
index 2b8c0bac7db47ef7b37024ecea95ed0e37d5364f..2762f420bc2c670b42eaefa0c1d33bc397fb4b2f 100755 (executable)
@@ -56,7 +56,7 @@ test_expect_success 'deleted branches have their tracking branches removed' '
 test_expect_success 'already deleted tracking branches ignored' '
        git branch -d -r origin/b3 &&
        git push origin :b3 >output 2>&1 &&
-       ! grep error output
+       ! grep "^error: " output
 '
 
 test_done
index 0680dec808574fb334612163ebd43d31418a37d5..d4f435155f5c9350f196904b910e2b5466c3ffd6 100755 (executable)
@@ -30,7 +30,7 @@ add () {
        test_tick &&
        commit=$(echo "$text" | git commit-tree $tree $parents) &&
        eval "$name=$commit; export $name" &&
-       echo $commit > .git/refs/heads/$branch &&
+       git update-ref "refs/heads/$branch" "$commit" &&
        eval ${branch}TIP=$commit
 }
 
@@ -45,10 +45,10 @@ pull_to_client () {
 
                        case "$heads" in
                            *A*)
-                                   echo $ATIP > .git/refs/heads/A;;
+                                   git update-ref refs/heads/A "$ATIP";;
                        esac &&
                        case "$heads" in *B*)
-                           echo $BTIP > .git/refs/heads/B;;
+                           git update-ref refs/heads/B "$BTIP";;
                        esac &&
                        git symbolic-ref HEAD refs/heads/$(echo $heads \
                                | sed -e "s/^\(.\).*$/\1/") &&
@@ -92,8 +92,8 @@ test_expect_success 'setup' '
                cur=$(($cur+1))
        done &&
        add B1 $A1 &&
-       echo $ATIP > .git/refs/heads/A &&
-       echo $BTIP > .git/refs/heads/B &&
+       git update-ref refs/heads/A "$ATIP" &&
+       git update-ref refs/heads/B "$BTIP" &&
        git symbolic-ref HEAD refs/heads/B
 '
 
index da9ac0055721237f177d3d475e56ddb38b25eff1..e402aee6a22e64306c9f093ad1b529b3923fd65e 100755 (executable)
@@ -63,7 +63,7 @@ test_expect_success "fetch test" '
        git commit -a -m "updated by origin" &&
        cd two &&
        git fetch &&
-       test -f .git/refs/heads/one &&
+       git rev-parse --verify refs/heads/one &&
        mine=$(git rev-parse refs/heads/one) &&
        his=$(cd ../one && git rev-parse refs/heads/master) &&
        test "z$mine" = "z$his"
@@ -73,8 +73,8 @@ test_expect_success "fetch test for-merge" '
        cd "$D" &&
        cd three &&
        git fetch &&
-       test -f .git/refs/heads/two &&
-       test -f .git/refs/heads/one &&
+       git rev-parse --verify refs/heads/two &&
+       git rev-parse --verify refs/heads/one &&
        master_in_two=$(cd ../two && git rev-parse master) &&
        one_in_two=$(cd ../two && git rev-parse one) &&
        {
@@ -840,8 +840,8 @@ test_expect_success C_LOCALE_OUTPUT 'fetch aligned output' '
        test_commit looooooooooooong-tag &&
        (
                cd full-output &&
-               git -c fetch.output=full fetch origin 2>&1 | \
-                       grep -e "->" | cut -c 22- >../actual
+               git -c fetch.output=full fetch origin >actual 2>&1 &&
+               grep -e "->" actual | cut -c 22- >../actual
        ) &&
        cat >expect <<-\EOF &&
        master               -> origin/master
@@ -855,8 +855,8 @@ test_expect_success C_LOCALE_OUTPUT 'fetch compact output' '
        test_commit extraaa &&
        (
                cd compact &&
-               git -c fetch.output=compact fetch origin 2>&1 | \
-                       grep -e "->" | cut -c 22- >../actual
+               git -c fetch.output=compact fetch origin >actual 2>&1 &&
+               grep -e "->" actual | cut -c 22- >../actual
        ) &&
        cat >expect <<-\EOF &&
        master     -> origin/*
index 02106c9226605f3b241160a8b46e6dbf3a9d3fc0..6a949484d090ea2df02603f9d82bf4f203a799e9 100755 (executable)
@@ -10,6 +10,9 @@ test_expect_success setup '
        test_tick &&
        git commit -m initial &&
        git tag mark &&
+       git tag mark1.1 &&
+       git tag mark1.2 &&
+       git tag mark1.10 &&
        git show-ref --tags -d | sed -e "s/ /   /" >expected.tag &&
        (
                echo "$(git rev-parse HEAD)     HEAD"
@@ -39,6 +42,39 @@ test_expect_success 'ls-remote self' '
        test_cmp expected.all actual
 '
 
+test_expect_success 'ls-remote --sort="version:refname" --tags self' '
+       cat >expect <<-EOF &&
+       $(git rev-parse mark)   refs/tags/mark
+       $(git rev-parse mark1.1)        refs/tags/mark1.1
+       $(git rev-parse mark1.2)        refs/tags/mark1.2
+       $(git rev-parse mark1.10)       refs/tags/mark1.10
+       EOF
+       git ls-remote --sort="version:refname" --tags self >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'ls-remote --sort="-version:refname" --tags self' '
+       cat >expect <<-EOF &&
+       $(git rev-parse mark1.10)       refs/tags/mark1.10
+       $(git rev-parse mark1.2)        refs/tags/mark1.2
+       $(git rev-parse mark1.1)        refs/tags/mark1.1
+       $(git rev-parse mark)   refs/tags/mark
+       EOF
+       git ls-remote --sort="-version:refname" --tags self >actual &&
+       test_cmp expect actual
+'
+
+test_expect_success 'ls-remote --sort="-refname" --tags self' '
+       cat >expect <<-EOF &&
+       $(git rev-parse mark1.2)        refs/tags/mark1.2
+       $(git rev-parse mark1.10)       refs/tags/mark1.10
+       $(git rev-parse mark1.1)        refs/tags/mark1.1
+       $(git rev-parse mark)   refs/tags/mark
+       EOF
+       git ls-remote --sort="-refname" --tags self >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success 'dies when no remote specified and no default remotes found' '
        test_must_fail git ls-remote
 '
@@ -131,7 +167,7 @@ test_expect_success 'Report no-match with --exit-code' '
 
 test_expect_success 'Report match with --exit-code' '
        git ls-remote --exit-code other.git "refs/tags/*" >actual &&
-       git ls-remote . tags/mark >expect &&
+       git ls-remote . tags/mark* >expect &&
        test_cmp expect actual
 '
 
@@ -171,13 +207,17 @@ test_expect_success 'overrides work between mixed transfer/upload-pack hideRefs'
 '
 
 test_expect_success 'ls-remote --symref' '
-       cat >expect <<-\EOF &&
+       git fetch origin &&
+       cat >expect <<-EOF &&
        ref: refs/heads/master  HEAD
-       1bd44cb9d13204b0fe1958db0082f5028a16eb3a        HEAD
-       1bd44cb9d13204b0fe1958db0082f5028a16eb3a        refs/heads/master
-       1bd44cb9d13204b0fe1958db0082f5028a16eb3a        refs/remotes/origin/HEAD
-       1bd44cb9d13204b0fe1958db0082f5028a16eb3a        refs/remotes/origin/master
-       1bd44cb9d13204b0fe1958db0082f5028a16eb3a        refs/tags/mark
+       $(git rev-parse HEAD)   HEAD
+       $(git rev-parse refs/heads/master)      refs/heads/master
+       $(git rev-parse HEAD)   refs/remotes/origin/HEAD
+       $(git rev-parse refs/remotes/origin/master)     refs/remotes/origin/master
+       $(git rev-parse refs/tags/mark) refs/tags/mark
+       $(git rev-parse refs/tags/mark1.1)      refs/tags/mark1.1
+       $(git rev-parse refs/tags/mark1.10)     refs/tags/mark1.10
+       $(git rev-parse refs/tags/mark1.2)      refs/tags/mark1.2
        EOF
        git ls-remote --symref >actual &&
        test_cmp expect actual
index 177897ea0b1e00cc4ec0f0e43510411ab19f1681..a5077d8b7c596523a3b0e0e5e45385e5d7871b9e 100755 (executable)
@@ -94,6 +94,9 @@ mk_child() {
 }
 
 check_push_result () {
+       test $# -ge 3 ||
+       error "bug in the test script: check_push_result requires at least 3 parameters"
+
        repo_name="$1"
        shift
 
@@ -553,10 +556,7 @@ test_expect_success 'branch.*.pushremote config order is irrelevant' '
 test_expect_success 'push with dry-run' '
 
        mk_test testrepo heads/master &&
-       (
-               cd testrepo &&
-               old_commit=$(git show-ref -s --verify refs/heads/master)
-       ) &&
+       old_commit=$(git -C testrepo show-ref -s --verify refs/heads/master) &&
        git push --dry-run testrepo : &&
        check_push_result testrepo $old_commit heads/master
 '
@@ -612,7 +612,7 @@ test_expect_success 'push does not update local refs on failure' '
        chmod +x testrepo/.git/hooks/pre-receive &&
        (
                cd child &&
-               git pull .. master
+               git pull .. master &&
                test_must_fail git push &&
                test $(git rev-parse master) != \
                        $(git rev-parse remotes/origin/master)
@@ -634,7 +634,7 @@ test_expect_success 'pushing valid refs triggers post-receive and post-update ho
        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
        newmaster=$(git show-ref -s --verify refs/heads/master) &&
        orgnext=$(cd testrepo && git show-ref -s --verify refs/heads/next) &&
-       newnext=$_z40 &&
+       newnext=$ZERO_OID &&
        git push testrepo refs/heads/master:refs/heads/master :refs/heads/next &&
        (
                cd testrepo/.git &&
@@ -672,15 +672,15 @@ test_expect_success 'deleting dangling ref triggers hooks with correct args' '
        (
                cd testrepo/.git &&
                cat >pre-receive.expect <<-EOF &&
-               $_z40 $_z40 refs/heads/master
+               $ZERO_OID $ZERO_OID refs/heads/master
                EOF
 
                cat >update.expect <<-EOF &&
-               refs/heads/master $_z40 $_z40
+               refs/heads/master $ZERO_OID $ZERO_OID
                EOF
 
                cat >post-receive.expect <<-EOF &&
-               $_z40 $_z40 refs/heads/master
+               $ZERO_OID $ZERO_OID refs/heads/master
                EOF
 
                cat >post-update.expect <<-EOF &&
@@ -703,12 +703,12 @@ test_expect_success 'deletion of a non-existent ref is not fed to post-receive a
                cd testrepo/.git &&
                cat >pre-receive.expect <<-EOF &&
                $orgmaster $newmaster refs/heads/master
-               $_z40 $_z40 refs/heads/nonexistent
+               $ZERO_OID $ZERO_OID refs/heads/nonexistent
                EOF
 
                cat >update.expect <<-EOF &&
                refs/heads/master $orgmaster $newmaster
-               refs/heads/nonexistent $_z40 $_z40
+               refs/heads/nonexistent $ZERO_OID $ZERO_OID
                EOF
 
                cat >post-receive.expect <<-EOF &&
@@ -732,11 +732,11 @@ test_expect_success 'deletion of a non-existent ref alone does trigger post-rece
        (
                cd testrepo/.git &&
                cat >pre-receive.expect <<-EOF &&
-               $_z40 $_z40 refs/heads/nonexistent
+               $ZERO_OID $ZERO_OID refs/heads/nonexistent
                EOF
 
                cat >update.expect <<-EOF &&
-               refs/heads/nonexistent $_z40 $_z40
+               refs/heads/nonexistent $ZERO_OID $ZERO_OID
                EOF
 
                test_cmp pre-receive.expect pre-receive.actual &&
@@ -751,7 +751,7 @@ test_expect_success 'mixed ref updates, deletes, invalid deletes trigger hooks w
        orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) &&
        newmaster=$(git show-ref -s --verify refs/heads/master) &&
        orgnext=$(cd testrepo && git show-ref -s --verify refs/heads/next) &&
-       newnext=$_z40 &&
+       newnext=$ZERO_OID &&
        orgpu=$(cd testrepo && git show-ref -s --verify refs/heads/pu) &&
        newpu=$(git show-ref -s --verify refs/heads/master) &&
        git push testrepo refs/heads/master:refs/heads/master \
@@ -763,14 +763,14 @@ test_expect_success 'mixed ref updates, deletes, invalid deletes trigger hooks w
                $orgmaster $newmaster refs/heads/master
                $orgnext $newnext refs/heads/next
                $orgpu $newpu refs/heads/pu
-               $_z40 $_z40 refs/heads/nonexistent
+               $ZERO_OID $ZERO_OID refs/heads/nonexistent
                EOF
 
                cat >update.expect <<-EOF &&
                refs/heads/master $orgmaster $newmaster
                refs/heads/next $orgnext $newnext
                refs/heads/pu $orgpu $newpu
-               refs/heads/nonexistent $_z40 $_z40
+               refs/heads/nonexistent $ZERO_OID $ZERO_OID
                EOF
 
                cat >post-receive.expect <<-EOF &&
@@ -1121,6 +1121,25 @@ test_expect_success 'fetch exact SHA1' '
        )
 '
 
+test_expect_success 'fetch exact SHA1 in protocol v2' '
+       mk_test testrepo heads/master hidden/one &&
+       git push testrepo master:refs/hidden/one &&
+       git -C testrepo config transfer.hiderefs refs/hidden &&
+       check_push_result testrepo $the_commit hidden/one &&
+
+       mk_child testrepo child &&
+       git -C child config protocol.version 2 &&
+
+       # make sure $the_commit does not exist here
+       git -C child repack -a -d &&
+       git -C child prune &&
+       test_must_fail git -C child cat-file -t $the_commit &&
+
+       # fetching the hidden object succeeds by default
+       # NEEDSWORK: should this match the v0 behavior instead?
+       git -C child fetch -v ../testrepo $the_commit:refs/heads/copy
+'
+
 for configallowtipsha1inwant in true false
 do
        test_expect_success "shallow fetch reachable SHA1 (but not a ref), allowtipsha1inwant=$configallowtipsha1inwant" '
@@ -1418,7 +1437,7 @@ test_expect_success 'receive.denyCurrentBranch = updateInstead' '
                cd testrepo &&
                git reset --hard HEAD^ &&
                test $(git -C .. rev-parse HEAD^) = $(git rev-parse HEAD) &&
-               test-chmtime +100 path1
+               test-tool chmtime +100 path1
        ) &&
        git push testrepo master &&
        (
index 207899a99faa4ff8fb4d7226e930ba1e9803dc74..3b0cb98422930891548cb45344dd226911a8063f 100755 (executable)
@@ -27,7 +27,7 @@ test_expect_success 'suffix ref is ignored during fetch' '
 '
 
 test_expect_success 'try to create repo with absurdly long refname' '
-       ref240=$_z40/$_z40/$_z40/$_z40/$_z40/$_z40 &&
+       ref240=$ZERO_OID/$ZERO_OID/$ZERO_OID/$ZERO_OID/$ZERO_OID/$ZERO_OID &&
        ref1440=$ref240/$ref240/$ref240/$ref240/$ref240/$ref240 &&
        git init long &&
        (
index 21340e89c9650e43fda9a6176c6fe814360edb8b..a2af693068fa455838c97df1fefe38bd630ceb2e 100755 (executable)
@@ -377,5 +377,17 @@ test_expect_success 'push status output scrubs password' '
        grep "^To $HTTPD_URL/smart/test_repo.git" status
 '
 
+test_expect_success 'colorize errors/hints' '
+       cd "$ROOT_PATH"/test_repo_clone &&
+       test_must_fail git -c color.transport=always -c color.advice=always \
+               -c color.push=always \
+               push origin origin/master^:master 2>act &&
+       test_decode_color <act >decoded &&
+       test_i18ngrep "<RED>.*rejected.*<RESET>" decoded &&
+       test_i18ngrep "<RED>error: failed to push some refs" decoded &&
+       test_i18ngrep "<YELLOW>hint: " decoded &&
+       test_i18ngrep ! "^hint: " decoded
+'
+
 stop_httpd
 test_done
index 10cb0be2b7ea42e5a1767edcd3515f933e6ef4af..0b0e987fdb73fcd7d8f54c393ee7deb15a4b5b8c 100755 (executable)
@@ -44,7 +44,7 @@ test_pack_input_limit () {
 }
 
 test_expect_success "create known-size (1024 bytes) commit" '
-       test-genrandom foo 1024 >one-k &&
+       test-tool genrandom foo 1024 >one-k &&
        git add one-k &&
        test_commit one-k
 '
index 113c87007f31abced0d93b3702f0b54f50ff4679..faaa51ccc562545c18180410e68483019a80832d 100755 (executable)
@@ -39,7 +39,7 @@ test_expect_success 'push to repo path with path separator (colon)' '
        # so make it likely for us to generate a delta by having
        # a non-trivial file with multiple versions.
 
-       test-genrandom foo 4096 >file.bin &&
+       test-tool genrandom foo 4096 >file.bin &&
        git add file.bin &&
        git commit -m bin &&
 
index 8552184e741fe2465e746a3ac42d19edddb15576..6d7d88ccc906a4c73285550ec80cd3fe67a764ee 100755 (executable)
@@ -169,6 +169,17 @@ test_expect_success 'fetch changes via manual http-fetch' '
        test_cmp file clone2/file
 '
 
+test_expect_success 'manual http-fetch without -a works just as well' '
+       cp -R clone-tmpl clone3 &&
+
+       HEAD=$(git rev-parse --verify HEAD) &&
+       (cd clone3 &&
+        git http-fetch -w heads/master-new $HEAD $(git config remote.origin.url) &&
+        git checkout master-new &&
+        test $HEAD = $(git rev-parse --verify HEAD)) &&
+       test_cmp file clone3/file
+'
+
 test_expect_success 'http remote detects correct HEAD' '
        git push public master:other &&
        (cd clone &&
index f5721b4a59ea4a3333cc0e74d8ab9ad2f182dd5b..913089b14452976144878415c05a9a2c743d22bf 100755 (executable)
@@ -26,14 +26,14 @@ setup_askpass_helper
 cat >exp <<EOF
 > GET /smart/repo.git/info/refs?service=git-upload-pack HTTP/1.1
 > Accept: */*
-> Accept-Encoding: gzip
+> Accept-Encoding: ENCODINGS
 > Pragma: no-cache
 < HTTP/1.1 200 OK
 < Pragma: no-cache
 < Cache-Control: no-cache, max-age=0, must-revalidate
 < Content-Type: application/x-git-upload-pack-advertisement
 > POST /smart/repo.git/git-upload-pack HTTP/1.1
-> Accept-Encoding: gzip
+> Accept-Encoding: ENCODINGS
 > Content-Type: application/x-git-upload-pack-request
 > Accept: application/x-git-upload-pack-result
 > Content-Length: xxx
@@ -79,8 +79,13 @@ test_expect_success 'clone http repository' '
                /^< Date: /d
                /^< Content-Length: /d
                /^< Transfer-Encoding: /d
-       " >act &&
-       test_cmp exp act
+       " >actual &&
+       sed -e "s/^> Accept-Encoding: .*/> Accept-Encoding: ENCODINGS/" \
+                       actual >actual.smudged &&
+       test_cmp exp actual.smudged &&
+
+       grep "Accept-Encoding:.*gzip" actual >actual.gzip &&
+       test_line_count = 2 actual.gzip
 '
 
 test_expect_success 'fetch changes via http' '
index 90e0d6f0fe935970c0941bfef2af39bb15d2f959..84a955770a017e68d0cc1e928929e5a043d64e86 100755 (executable)
@@ -3,10 +3,16 @@
 test_description='test git-http-backend'
 . ./test-lib.sh
 . "$TEST_DIRECTORY"/lib-httpd.sh
+
+if ! test_have_prereq CURL; then
+       skip_all='skipping raw http-backend tests, curl not available'
+       test_done
+fi
+
 start_httpd
 
 GET() {
-       curl --include "$HTTPD_URL/$SMART/repo.git/$1" >out 2>/dev/null &&
+       curl --include "$HTTPD_URL/$SMART/repo.git/$1" >out &&
        tr '\015' Q <out |
        sed '
                s/Q$//
@@ -19,7 +25,7 @@ GET() {
 POST() {
        curl --include --data "$2" \
        --header "Content-Type: application/x-$1-request" \
-       "$HTTPD_URL/smart/repo.git/$1" >out 2>/dev/null &&
+       "$HTTPD_URL/smart/repo.git/$1" >out &&
        tr '\015' Q <out |
        sed '
                s/Q$//
index ba975bb3557b5e243deb2c40217dbe04ff4953ae..ac53d638695b69b67e18832846be8105864367de 100755 (executable)
@@ -78,8 +78,8 @@ test_expect_success 'push to default' '
 cat >expected <<EOF
 parent1
 repo1
-refs/tags/one $COMMIT1 refs/tags/tag1 $_z40
-HEAD~ $COMMIT2 refs/heads/prev $_z40
+refs/tags/one $COMMIT1 refs/tags/tag1 $ZERO_OID
+HEAD~ $COMMIT2 refs/heads/prev $ZERO_OID
 EOF
 
 test_expect_success 'push non-branches' '
@@ -90,7 +90,7 @@ test_expect_success 'push non-branches' '
 cat >expected <<EOF
 parent1
 repo1
-(delete) $_z40 refs/heads/prev $COMMIT2
+(delete) $ZERO_OID refs/heads/prev $COMMIT2
 EOF
 
 test_expect_success 'push delete' '
@@ -101,7 +101,7 @@ test_expect_success 'push delete' '
 cat >expected <<EOF
 repo1
 repo1
-HEAD $COMMIT3 refs/heads/other $_z40
+HEAD $COMMIT3 refs/heads/other $ZERO_OID
 EOF
 
 test_expect_success 'push to URL' '
index 321bd37deb3d32027c18f8184a9ad46aec9c96c7..f916729a12b24b75184144c2eaa9abdbf1c12639 100755 (executable)
@@ -132,4 +132,25 @@ test_expect_success 'pull rebase recursing fails with conflicts' '
        test_i18ngrep "locally recorded submodule modifications" err
 '
 
+test_expect_success 'branch has no merge base with remote-tracking counterpart' '
+       rm -rf parent child &&
+
+       test_create_repo a-submodule &&
+       test_commit -C a-submodule foo &&
+
+       test_create_repo parent &&
+       git -C parent submodule add "$(pwd)/a-submodule" &&
+       git -C parent commit -m foo &&
+
+       git clone parent child &&
+
+       # Reset master so that it has no merge base with
+       # refs/remotes/origin/master.
+       OTHER=$(git -C child commit-tree -m bar \
+               $(git -C child rev-parse HEAD^{tree})) &&
+       git -C child reset --hard "$OTHER" &&
+
+       git -C child pull --recurse-submodules --rebase
+'
+
 test_done
index 191d6d3a780325b6f3e294b6b42540569ef129d1..df822d9a3e9e7c7b4b7031ffa75716cd7ba6103a 100755 (executable)
@@ -21,7 +21,7 @@ test_expect_success CLONE_2GB 'setup' '
         do
                printf "Generating blob $i/$blobcount\r" >&2 &&
                printf "blob\nmark :$i\ndata $blobsize\n" &&
-               #test-genrandom $i $blobsize &&
+               #test-tool genrandom $i $blobsize &&
                printf "%-${blobsize}s" $i &&
                echo "M 100644 :$i $i" >> commit
                i=$(($i+1)) ||
diff --git a/t/t5701-git-serve.sh b/t/t5701-git-serve.sh
new file mode 100755 (executable)
index 0000000..75ec79e
--- /dev/null
@@ -0,0 +1,211 @@
+#!/bin/sh
+
+test_description='test git-serve and server commands'
+
+. ./test-lib.sh
+
+test_expect_success 'test capability advertisement' '
+       cat >expect <<-EOF &&
+       version 2
+       agent=git/$(git version | cut -d" " -f3)
+       ls-refs
+       fetch=shallow
+       server-option
+       0000
+       EOF
+
+       git serve --advertise-capabilities >out &&
+       test-pkt-line unpack <out >actual &&
+       test_cmp actual expect
+'
+
+test_expect_success 'stateless-rpc flag does not list capabilities' '
+       # Empty request
+       test-pkt-line pack >in <<-EOF &&
+       0000
+       EOF
+       git serve --stateless-rpc >out <in &&
+       test_must_be_empty out &&
+
+       # EOF
+       git serve --stateless-rpc >out &&
+       test_must_be_empty out
+'
+
+test_expect_success 'request invalid capability' '
+       test-pkt-line pack >in <<-EOF &&
+       foobar
+       0000
+       EOF
+       test_must_fail git serve --stateless-rpc 2>err <in &&
+       test_i18ngrep "unknown capability" err
+'
+
+test_expect_success 'request with no command' '
+       test-pkt-line pack >in <<-EOF &&
+       agent=git/test
+       0000
+       EOF
+       test_must_fail git serve --stateless-rpc 2>err <in &&
+       test_i18ngrep "no command requested" err
+'
+
+test_expect_success 'request invalid command' '
+       test-pkt-line pack >in <<-EOF &&
+       command=foo
+       agent=git/test
+       0000
+       EOF
+       test_must_fail git serve --stateless-rpc 2>err <in &&
+       test_i18ngrep "invalid command" err
+'
+
+# Test the basics of ls-refs
+#
+test_expect_success 'setup some refs and tags' '
+       test_commit one &&
+       git branch dev master &&
+       test_commit two &&
+       git symbolic-ref refs/heads/release refs/heads/master &&
+       git tag -a -m "annotated tag" annotated-tag
+'
+
+test_expect_success 'basics of ls-refs' '
+       test-pkt-line pack >in <<-EOF &&
+       command=ls-refs
+       0000
+       EOF
+
+       cat >expect <<-EOF &&
+       $(git rev-parse HEAD) HEAD
+       $(git rev-parse refs/heads/dev) refs/heads/dev
+       $(git rev-parse refs/heads/master) refs/heads/master
+       $(git rev-parse refs/heads/release) refs/heads/release
+       $(git rev-parse refs/tags/annotated-tag) refs/tags/annotated-tag
+       $(git rev-parse refs/tags/one) refs/tags/one
+       $(git rev-parse refs/tags/two) refs/tags/two
+       0000
+       EOF
+
+       git serve --stateless-rpc <in >out &&
+       test-pkt-line unpack <out >actual &&
+       test_cmp actual expect
+'
+
+test_expect_success 'basic ref-prefixes' '
+       test-pkt-line pack >in <<-EOF &&
+       command=ls-refs
+       0001
+       ref-prefix refs/heads/master
+       ref-prefix refs/tags/one
+       0000
+       EOF
+
+       cat >expect <<-EOF &&
+       $(git rev-parse refs/heads/master) refs/heads/master
+       $(git rev-parse refs/tags/one) refs/tags/one
+       0000
+       EOF
+
+       git serve --stateless-rpc <in >out &&
+       test-pkt-line unpack <out >actual &&
+       test_cmp actual expect
+'
+
+test_expect_success 'refs/heads prefix' '
+       test-pkt-line pack >in <<-EOF &&
+       command=ls-refs
+       0001
+       ref-prefix refs/heads/
+       0000
+       EOF
+
+       cat >expect <<-EOF &&
+       $(git rev-parse refs/heads/dev) refs/heads/dev
+       $(git rev-parse refs/heads/master) refs/heads/master
+       $(git rev-parse refs/heads/release) refs/heads/release
+       0000
+       EOF
+
+       git serve --stateless-rpc <in >out &&
+       test-pkt-line unpack <out >actual &&
+       test_cmp actual expect
+'
+
+test_expect_success 'peel parameter' '
+       test-pkt-line pack >in <<-EOF &&
+       command=ls-refs
+       0001
+       peel
+       ref-prefix refs/tags/
+       0000
+       EOF
+
+       cat >expect <<-EOF &&
+       $(git rev-parse refs/tags/annotated-tag) refs/tags/annotated-tag peeled:$(git rev-parse refs/tags/annotated-tag^{})
+       $(git rev-parse refs/tags/one) refs/tags/one
+       $(git rev-parse refs/tags/two) refs/tags/two
+       0000
+       EOF
+
+       git serve --stateless-rpc <in >out &&
+       test-pkt-line unpack <out >actual &&
+       test_cmp actual expect
+'
+
+test_expect_success 'symrefs parameter' '
+       test-pkt-line pack >in <<-EOF &&
+       command=ls-refs
+       0001
+       symrefs
+       ref-prefix refs/heads/
+       0000
+       EOF
+
+       cat >expect <<-EOF &&
+       $(git rev-parse refs/heads/dev) refs/heads/dev
+       $(git rev-parse refs/heads/master) refs/heads/master
+       $(git rev-parse refs/heads/release) refs/heads/release symref-target:refs/heads/master
+       0000
+       EOF
+
+       git serve --stateless-rpc <in >out &&
+       test-pkt-line unpack <out >actual &&
+       test_cmp actual expect
+'
+
+test_expect_success 'sending server-options' '
+       test-pkt-line pack >in <<-EOF &&
+       command=ls-refs
+       server-option=hello
+       server-option=world
+       0001
+       ref-prefix HEAD
+       0000
+       EOF
+
+       cat >expect <<-EOF &&
+       $(git rev-parse HEAD) HEAD
+       0000
+       EOF
+
+       git serve --stateless-rpc <in >out &&
+       test-pkt-line unpack <out >actual &&
+       test_cmp actual expect
+'
+
+test_expect_success 'unexpected lines are not allowed in fetch request' '
+       git init server &&
+
+       test-pkt-line pack >in <<-EOF &&
+       command=fetch
+       0001
+       this-is-not-a-command
+       0000
+       EOF
+
+       test_must_fail git -C server serve --stateless-rpc <in >/dev/null 2>err &&
+       grep "unexpected line: .this-is-not-a-command." err
+'
+
+test_done
diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh
new file mode 100755 (executable)
index 0000000..a4fe650
--- /dev/null
@@ -0,0 +1,431 @@
+#!/bin/sh
+
+test_description='test git wire-protocol version 2'
+
+TEST_NO_CREATE_REPO=1
+
+. ./test-lib.sh
+
+# Test protocol v2 with 'git://' transport
+#
+. "$TEST_DIRECTORY"/lib-git-daemon.sh
+start_git_daemon --export-all --enable=receive-pack
+daemon_parent=$GIT_DAEMON_DOCUMENT_ROOT_PATH/parent
+
+test_expect_success 'create repo to be served by git-daemon' '
+       git init "$daemon_parent" &&
+       test_commit -C "$daemon_parent" one
+'
+
+test_expect_success 'list refs with git:// using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+               ls-remote --symref "$GIT_DAEMON_URL/parent" >actual &&
+
+       # Client requested to use protocol v2
+       grep "git> .*\\\0\\\0version=2\\\0$" log &&
+       # Server responded using protocol v2
+       grep "git< version 2" log &&
+
+       git ls-remote --symref "$GIT_DAEMON_URL/parent" >expect &&
+       test_cmp actual expect
+'
+
+test_expect_success 'ref advertisment is filtered with ls-remote using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+               ls-remote "$GIT_DAEMON_URL/parent" master >actual &&
+
+       cat >expect <<-EOF &&
+       $(git -C "$daemon_parent" rev-parse refs/heads/master)$(printf "\t")refs/heads/master
+       EOF
+
+       test_cmp actual expect
+'
+
+test_expect_success 'clone with git:// using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+               clone "$GIT_DAEMON_URL/parent" daemon_child &&
+
+       git -C daemon_child log -1 --format=%s >actual &&
+       git -C "$daemon_parent" log -1 --format=%s >expect &&
+       test_cmp expect actual &&
+
+       # Client requested to use protocol v2
+       grep "clone> .*\\\0\\\0version=2\\\0$" log &&
+       # Server responded using protocol v2
+       grep "clone< version 2" log
+'
+
+test_expect_success 'fetch with git:// using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       test_commit -C "$daemon_parent" two &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -C daemon_child -c protocol.version=2 \
+               fetch &&
+
+       git -C daemon_child log -1 --format=%s origin/master >actual &&
+       git -C "$daemon_parent" log -1 --format=%s >expect &&
+       test_cmp expect actual &&
+
+       # Client requested to use protocol v2
+       grep "fetch> .*\\\0\\\0version=2\\\0$" log &&
+       # Server responded using protocol v2
+       grep "fetch< version 2" log
+'
+
+test_expect_success 'pull with git:// using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -C daemon_child -c protocol.version=2 \
+               pull &&
+
+       git -C daemon_child log -1 --format=%s >actual &&
+       git -C "$daemon_parent" log -1 --format=%s >expect &&
+       test_cmp expect actual &&
+
+       # Client requested to use protocol v2
+       grep "fetch> .*\\\0\\\0version=2\\\0$" log &&
+       # Server responded using protocol v2
+       grep "fetch< version 2" log
+'
+
+test_expect_success 'push with git:// and a config of v2 does not request v2' '
+       test_when_finished "rm -f log" &&
+
+       # Till v2 for push is designed, make sure that if a client has
+       # protocol.version configured to use v2, that the client instead falls
+       # back and uses v0.
+
+       test_commit -C daemon_child three &&
+
+       # Push to another branch, as the target repository has the
+       # master branch checked out and we cannot push into it.
+       GIT_TRACE_PACKET="$(pwd)/log" git -C daemon_child -c protocol.version=2 \
+               push origin HEAD:client_branch &&
+
+       git -C daemon_child log -1 --format=%s >actual &&
+       git -C "$daemon_parent" log -1 --format=%s client_branch >expect &&
+       test_cmp expect actual &&
+
+       # Client requested to use protocol v2
+       ! grep "push> .*\\\0\\\0version=2\\\0$" log &&
+       # Server responded using protocol v2
+       ! grep "push< version 2" log
+'
+
+stop_git_daemon
+
+# Test protocol v2 with 'file://' transport
+#
+test_expect_success 'create repo to be served by file:// transport' '
+       git init file_parent &&
+       test_commit -C file_parent one
+'
+
+test_expect_success 'list refs with file:// using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+               ls-remote --symref "file://$(pwd)/file_parent" >actual &&
+
+       # Server responded using protocol v2
+       grep "git< version 2" log &&
+
+       git ls-remote --symref "file://$(pwd)/file_parent" >expect &&
+       test_cmp actual expect
+'
+
+test_expect_success 'ref advertisment is filtered with ls-remote using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+               ls-remote "file://$(pwd)/file_parent" master >actual &&
+
+       cat >expect <<-EOF &&
+       $(git -C file_parent rev-parse refs/heads/master)$(printf "\t")refs/heads/master
+       EOF
+
+       test_cmp actual expect
+'
+
+test_expect_success 'server-options are sent when using ls-remote' '
+       test_when_finished "rm -f log" &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+               ls-remote -o hello -o world "file://$(pwd)/file_parent" master >actual &&
+
+       cat >expect <<-EOF &&
+       $(git -C file_parent rev-parse refs/heads/master)$(printf "\t")refs/heads/master
+       EOF
+
+       test_cmp actual expect &&
+       grep "server-option=hello" log &&
+       grep "server-option=world" log
+'
+
+
+test_expect_success 'clone with file:// using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -c protocol.version=2 \
+               clone "file://$(pwd)/file_parent" file_child &&
+
+       git -C file_child log -1 --format=%s >actual &&
+       git -C file_parent log -1 --format=%s >expect &&
+       test_cmp expect actual &&
+
+       # Server responded using protocol v2
+       grep "clone< version 2" log
+'
+
+test_expect_success 'fetch with file:// using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       test_commit -C file_parent two &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \
+               fetch origin &&
+
+       git -C file_child log -1 --format=%s origin/master >actual &&
+       git -C file_parent log -1 --format=%s >expect &&
+       test_cmp expect actual &&
+
+       # Server responded using protocol v2
+       grep "fetch< version 2" log
+'
+
+test_expect_success 'ref advertisment is filtered during fetch using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       test_commit -C file_parent three &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \
+               fetch origin master &&
+
+       git -C file_child log -1 --format=%s origin/master >actual &&
+       git -C file_parent log -1 --format=%s >expect &&
+       test_cmp expect actual &&
+
+       ! grep "refs/tags/one" log &&
+       ! grep "refs/tags/two" log &&
+       ! grep "refs/tags/three" log
+'
+
+test_expect_success 'server-options are sent when fetching' '
+       test_when_finished "rm -f log" &&
+
+       test_commit -C file_parent four &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \
+               fetch -o hello -o world origin master &&
+
+       git -C file_child log -1 --format=%s origin/master >actual &&
+       git -C file_parent log -1 --format=%s >expect &&
+       test_cmp expect actual &&
+
+       grep "server-option=hello" log &&
+       grep "server-option=world" log
+'
+
+test_expect_success 'upload-pack respects config using protocol v2' '
+       git init server &&
+       write_script server/.git/hook <<-\EOF &&
+               touch hookout
+               "$@"
+       EOF
+       test_commit -C server one &&
+
+       test_config_global uploadpack.packobjectshook ./hook &&
+       test_path_is_missing server/.git/hookout &&
+       git -c protocol.version=2 clone "file://$(pwd)/server" client &&
+       test_path_is_file server/.git/hookout
+'
+
+test_expect_success 'setup filter tests' '
+       rm -rf server client &&
+       git init server &&
+
+       # 1 commit to create a file, and 1 commit to modify it
+       test_commit -C server message1 a.txt &&
+       test_commit -C server message2 a.txt &&
+       git -C server config protocol.version 2 &&
+       git -C server config uploadpack.allowfilter 1 &&
+       git -C server config uploadpack.allowanysha1inwant 1 &&
+       git -C server config protocol.version 2
+'
+
+test_expect_success 'partial clone' '
+       GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 \
+               clone --filter=blob:none "file://$(pwd)/server" client &&
+       grep "version 2" trace &&
+
+       # Ensure that the old version of the file is missing
+       git -C client rev-list master --quiet --objects --missing=print \
+               >observed.oids &&
+       grep "$(git -C server rev-parse message1:a.txt)" observed.oids &&
+
+       # Ensure that client passes fsck
+       git -C client fsck
+'
+
+test_expect_success 'dynamically fetch missing object' '
+       rm "$(pwd)/trace" &&
+       GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \
+               cat-file -p $(git -C server rev-parse message1:a.txt) &&
+       grep "version 2" trace
+'
+
+test_expect_success 'partial fetch' '
+       rm -rf client "$(pwd)/trace" &&
+       git init client &&
+       SERVER="file://$(pwd)/server" &&
+       test_config -C client extensions.partialClone "$SERVER" &&
+
+       GIT_TRACE_PACKET="$(pwd)/trace" git -C client -c protocol.version=2 \
+               fetch --filter=blob:none "$SERVER" master:refs/heads/other &&
+       grep "version 2" trace &&
+
+       # Ensure that the old version of the file is missing
+       git -C client rev-list other --quiet --objects --missing=print \
+               >observed.oids &&
+       grep "$(git -C server rev-parse message1:a.txt)" observed.oids &&
+
+       # Ensure that client passes fsck
+       git -C client fsck
+'
+
+test_expect_success 'do not advertise filter if not configured to do so' '
+       SERVER="file://$(pwd)/server" &&
+
+       rm "$(pwd)/trace" &&
+       git -C server config uploadpack.allowfilter 1 &&
+       GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 \
+               ls-remote "$SERVER" &&
+       grep "fetch=.*filter" trace &&
+
+       rm "$(pwd)/trace" &&
+       git -C server config uploadpack.allowfilter 0 &&
+       GIT_TRACE_PACKET="$(pwd)/trace" git -c protocol.version=2 \
+               ls-remote "$SERVER" &&
+       grep "fetch=" trace >fetch_capabilities &&
+       ! grep filter fetch_capabilities
+'
+
+test_expect_success 'partial clone warns if filter is not advertised' '
+       rm -rf client &&
+       git -C server config uploadpack.allowfilter 0 &&
+       git -c protocol.version=2 \
+               clone --filter=blob:none "file://$(pwd)/server" client 2>err &&
+       test_i18ngrep "filtering not recognized by server, ignoring" err
+'
+
+test_expect_success 'even with handcrafted request, filter does not work if not advertised' '
+       git -C server config uploadpack.allowfilter 0 &&
+
+       # Custom request that tries to filter even though it is not advertised.
+       test-pkt-line pack >in <<-EOF &&
+       command=fetch
+       0001
+       want $(git -C server rev-parse master)
+       filter blob:none
+       0000
+       EOF
+
+       test_must_fail git -C server serve --stateless-rpc <in >/dev/null 2>err &&
+       grep "unexpected line: .filter blob:none." err &&
+
+       # Exercise to ensure that if advertised, filter works
+       git -C server config uploadpack.allowfilter 1 &&
+       git -C server serve --stateless-rpc <in >/dev/null
+'
+
+test_expect_success 'default refspec is used to filter ref when fetchcing' '
+       test_when_finished "rm -f log" &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -C file_child -c protocol.version=2 \
+               fetch origin &&
+
+       git -C file_child log -1 --format=%s three >actual &&
+       git -C file_parent log -1 --format=%s three >expect &&
+       test_cmp expect actual &&
+
+       grep "ref-prefix refs/heads/" log &&
+       grep "ref-prefix refs/tags/" log
+'
+
+# Test protocol v2 with 'http://' transport
+#
+. "$TEST_DIRECTORY"/lib-httpd.sh
+start_httpd
+
+test_expect_success 'create repo to be served by http:// transport' '
+       git init "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" &&
+       git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" config http.receivepack true &&
+       test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" one
+'
+
+test_expect_success 'clone with http:// using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" git -c protocol.version=2 \
+               clone "$HTTPD_URL/smart/http_parent" http_child &&
+
+       git -C http_child log -1 --format=%s >actual &&
+       git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
+       test_cmp expect actual &&
+
+       # Client requested to use protocol v2
+       grep "Git-Protocol: version=2" log &&
+       # Server responded using protocol v2
+       grep "git< version 2" log
+'
+
+test_expect_success 'fetch with http:// using protocol v2' '
+       test_when_finished "rm -f log" &&
+
+       test_commit -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" two &&
+
+       GIT_TRACE_PACKET="$(pwd)/log" git -C http_child -c protocol.version=2 \
+               fetch &&
+
+       git -C http_child log -1 --format=%s origin/master >actual &&
+       git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s >expect &&
+       test_cmp expect actual &&
+
+       # Server responded using protocol v2
+       grep "git< version 2" log
+'
+
+test_expect_success 'push with http:// and a config of v2 does not request v2' '
+       test_when_finished "rm -f log" &&
+       # Till v2 for push is designed, make sure that if a client has
+       # protocol.version configured to use v2, that the client instead falls
+       # back and uses v0.
+
+       test_commit -C http_child three &&
+
+       # Push to another branch, as the target repository has the
+       # master branch checked out and we cannot push into it.
+       GIT_TRACE_PACKET="$(pwd)/log" git -C http_child -c protocol.version=2 \
+               push origin HEAD:client_branch &&
+
+       git -C http_child log -1 --format=%s >actual &&
+       git -C "$HTTPD_DOCUMENT_ROOT_PATH/http_parent" log -1 --format=%s client_branch >expect &&
+       test_cmp expect actual &&
+
+       # Client didnt request to use protocol v2
+       ! grep "Git-Protocol: version=2" log &&
+       # Server didnt respond using protocol v2
+       ! grep "git< version 2" log
+'
+
+
+stop_httpd
+
+test_done
index 05ddc69cf2ad9470a125fda47fc450401f94902b..7504ba47511bf5df27dd54d7090fdd920285db07 100755 (executable)
@@ -110,4 +110,13 @@ do
        "
 
 done
+
+test_expect_success 'show advice that grafts are deprecated' '
+       git show HEAD 2>err &&
+       test_i18ngrep "git replace" err &&
+       test_config advice.graftFileDeprecated false &&
+       git show HEAD 2>err &&
+       test_i18ngrep ! "git replace" err
+'
+
 test_done
index 98be78b4a2123cad7e16911ae2eedff5695ba3d3..ec42c2f7797c38f39bb3420402d975a94217d1f4 100755 (executable)
@@ -447,8 +447,8 @@ test_expect_success '--abbrev' '
        git log -1 --format="%h %h %h" HEAD >actual1 &&
        git log -1 --abbrev=5 --format="%h %h %h" HEAD >actual2 &&
        git log -1 --abbrev=5 --format="%H %H %H" HEAD >actual3 &&
-       sed -e "s/$_x40/LONG/g" -e "s/$_x05/SHORT/g" <actual2 >fuzzy2 &&
-       sed -e "s/$_x40/LONG/g" -e "s/$_x05/SHORT/g" <actual3 >fuzzy3 &&
+       sed -e "s/$OID_REGEX/LONG/g" -e "s/$_x05/SHORT/g" <actual2 >fuzzy2 &&
+       sed -e "s/$OID_REGEX/LONG/g" -e "s/$_x05/SHORT/g" <actual3 >fuzzy3 &&
        test_cmp expect2 fuzzy2 &&
        test_cmp expect3 fuzzy3 &&
        ! test_cmp actual1 actual2
index 31db7b5f9125ed346450d7bfe29d8bb5fac0460a..aa2d360ce35940a176a0ef04ca7ba8560adefb23 100755 (executable)
@@ -34,7 +34,7 @@ doit () {
 
        commit=$(echo $NAME | git commit-tree $T $PARENTS) &&
 
-       echo $commit >.git/refs/tags/$NAME &&
+       git update-ref "refs/tags/$NAME" "$commit" &&
        echo $commit
 }
 
index 2a0fbb87b1d63f1a07f8a3934e1546c695a73f56..b5a1190ffe63b53d8b637b39a15d3d94b3efa6cd 100755 (executable)
@@ -9,7 +9,7 @@ note () {
 }
 
 unnote () {
-       git name-rev --tags --stdin | sed -e "s|$_x40 (tags/\([^)]*\)) |\1 |g"
+       git name-rev --tags --stdin | sed -e "s|$OID_REGEX (tags/\([^)]*\)) |\1 |g"
 }
 
 test_expect_success setup '
index c01f721f13dba71fae681d6ba5100e02e58de4d8..b760c223c6a56609b7dace5353671aec8243b85d 100755 (executable)
@@ -247,7 +247,7 @@ test_expect_success 'merge of identical changes in a renamed file' '
        git reset --hard HEAD^ &&
        git checkout change &&
        GIT_MERGE_VERBOSITY=3 git merge change+rename >out &&
-       test_i18ngrep "^Skipped B" out
+       test_i18ngrep "^Skipped B" out
 '
 
 test_expect_success 'setup for rename + d/f conflicts' '
@@ -635,10 +635,9 @@ test_expect_success 'setup avoid unnecessary update, normal rename' '
 
 test_expect_success 'avoid unnecessary update, normal rename' '
        git checkout -q avoid-unnecessary-update-1^0 &&
-       test-chmtime =1000000000 rename &&
-       test-chmtime -v +0 rename >expect &&
+       test-tool chmtime --get =1000000000 rename >expect &&
        git merge merge-branch-1 &&
-       test-chmtime -v +0 rename >actual &&
+       test-tool chmtime --get rename >actual &&
        test_cmp expect actual # "rename" should have stayed intact
 '
 
@@ -668,10 +667,9 @@ test_expect_success 'setup to test avoiding unnecessary update, with D/F conflic
 
 test_expect_success 'avoid unnecessary update, with D/F conflict' '
        git checkout -q avoid-unnecessary-update-2^0 &&
-       test-chmtime =1000000000 df &&
-       test-chmtime -v +0 df >expect &&
+       test-tool chmtime --get =1000000000 df >expect &&
        git merge merge-branch-2 &&
-       test-chmtime -v +0 df >actual &&
+       test-tool chmtime --get df >actual &&
        test_cmp expect actual # "df" should have stayed intact
 '
 
@@ -700,10 +698,9 @@ test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' '
 
 test_expect_success 'avoid unnecessary update, dir->(file,nothing)' '
        git checkout -q master^0 &&
-       test-chmtime =1000000000 df &&
-       test-chmtime -v +0 df >expect &&
+       test-tool chmtime --get =1000000000 df >expect &&
        git merge side &&
-       test-chmtime -v +0 df >actual &&
+       test-tool chmtime --get df >actual &&
        test_cmp expect actual # "df" should have stayed intact
 '
 
@@ -730,10 +727,9 @@ test_expect_success 'setup avoid unnecessary update, modify/delete' '
 
 test_expect_success 'avoid unnecessary update, modify/delete' '
        git checkout -q master^0 &&
-       test-chmtime =1000000000 file &&
-       test-chmtime -v +0 file >expect &&
+       test-tool chmtime --get =1000000000 file >expect &&
        test_must_fail git merge side &&
-       test-chmtime -v +0 file >actual &&
+       test-tool chmtime --get file >actual &&
        test_cmp expect actual # "file" should have stayed intact
 '
 
@@ -759,10 +755,9 @@ test_expect_success 'setup avoid unnecessary update, rename/add-dest' '
 
 test_expect_success 'avoid unnecessary update, rename/add-dest' '
        git checkout -q master^0 &&
-       test-chmtime =1000000000 newfile &&
-       test-chmtime -v +0 newfile >expect &&
+       test-tool chmtime --get =1000000000 newfile >expect &&
        git merge side &&
-       test-chmtime -v +0 newfile >actual &&
+       test-tool chmtime --get newfile >actual &&
        test_cmp expect actual # "file" should have stayed intact
 '
 
diff --git a/t/t6043-merge-rename-directories.sh b/t/t6043-merge-rename-directories.sh
new file mode 100755 (executable)
index 0000000..2e28f29
--- /dev/null
@@ -0,0 +1,3998 @@
+#!/bin/sh
+
+test_description="recursive merge with directory renames"
+# includes checking of many corner cases, with a similar methodology to:
+#   t6042: corner cases with renames but not criss-cross merges
+#   t6036: corner cases with both renames and criss-cross merges
+#
+# The setup for all of them, pictorially, is:
+#
+#      A
+#      o
+#     / \
+#  O o   ?
+#     \ /
+#      o
+#      B
+#
+# To help make it easier to follow the flow of tests, they have been
+# divided into sections and each test will start with a quick explanation
+# of what commits O, A, and B contain.
+#
+# Notation:
+#    z/{b,c}   means  files z/b and z/c both exist
+#    x/d_1     means  file x/d exists with content d1.  (Purpose of the
+#                     underscore notation is to differentiate different
+#                     files that might be renamed into each other's paths.)
+
+. ./test-lib.sh
+
+
+###########################################################################
+# SECTION 1: Basic cases we should be able to handle
+###########################################################################
+
+# Testcase 1a, Basic directory rename.
+#   Commit O: z/{b,c}
+#   Commit A: y/{b,c}
+#   Commit B: z/{b,c,d,e/f}
+#   Expected: y/{b,c,d,e/f}
+
+test_expect_success '1a-setup: Simple directory rename detection' '
+       test_create_repo 1a &&
+       (
+               cd 1a &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo d >z/d &&
+               mkdir z/e &&
+               echo f >z/e/f &&
+               git add z/d z/e/f &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '1a-check: Simple directory rename detection' '
+       (
+               cd 1a &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 4 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e/f &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    B:z/d    B:z/e/f &&
+               test_cmp expect actual &&
+
+               git hash-object y/d >actual &&
+               git rev-parse B:z/d >expect &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse HEAD:z/d &&
+               test_must_fail git rev-parse HEAD:z/e/f &&
+               test_path_is_missing z/d &&
+               test_path_is_missing z/e/f
+       )
+'
+
+# Testcase 1b, Merge a directory with another
+#   Commit O: z/{b,c},   y/d
+#   Commit A: z/{b,c,e}, y/d
+#   Commit B: y/{b,c,d}
+#   Expected: y/{b,c,d,e}
+
+test_expect_success '1b-setup: Merge a directory with another' '
+       test_create_repo 1b &&
+       (
+               cd 1b &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir y &&
+               echo d >y/d &&
+               git add z y &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               echo e >z/e &&
+               git add z/e &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv z/b y &&
+               git mv z/c y &&
+               rmdir z &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '1b-check: Merge a directory with another' '
+       (
+               cd 1b &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 4 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    O:y/d    A:z/e &&
+               test_cmp expect actual &&
+               test_must_fail git rev-parse HEAD:z/e
+       )
+'
+
+# Testcase 1c, Transitive renaming
+#   (Related to testcases 3a and 6d -- when should a transitive rename apply?)
+#   (Related to testcases 9c and 9d -- can transitivity repeat?)
+#   (Related to testcase 12b -- joint-transitivity?)
+#   Commit O: z/{b,c},   x/d
+#   Commit A: y/{b,c},   x/d
+#   Commit B: z/{b,c,d}
+#   Expected: y/{b,c,d}  (because x/d -> z/d -> y/d)
+
+test_expect_success '1c-setup: Transitive renaming' '
+       test_create_repo 1c &&
+       (
+               cd 1c &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir x &&
+               echo d >x/d &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/d z/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '1c-check: Transitive renaming' '
+       (
+               cd 1c &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:y/d &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    O:x/d &&
+               test_cmp expect actual &&
+               test_must_fail git rev-parse HEAD:x/d &&
+               test_must_fail git rev-parse HEAD:z/d &&
+               test_path_is_missing z/d
+       )
+'
+
+# Testcase 1d, Directory renames (merging two directories into one new one)
+#              cause a rename/rename(2to1) conflict
+#   (Related to testcases 1c and 7b)
+#   Commit O. z/{b,c},        y/{d,e}
+#   Commit A. x/{b,c},        y/{d,e,m,wham_1}
+#   Commit B. z/{b,c,n,wham_2}, x/{d,e}
+#   Expected: x/{b,c,d,e,m,n}, CONFLICT:(y/wham_1 & z/wham_2 -> x/wham)
+#   Note: y/m & z/n should definitely move into x.  By the same token, both
+#         y/wham_1 & z/wham_2 should too...giving us a conflict.
+
+test_expect_success '1d-setup: Directory renames cause a rename/rename(2to1) conflict' '
+       test_create_repo 1d &&
+       (
+               cd 1d &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir y &&
+               echo d >y/d &&
+               echo e >y/e &&
+               git add z y &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z x &&
+               echo m >y/m &&
+               echo wham1 >y/wham &&
+               git add y &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv y x &&
+               echo n >z/n &&
+               echo wham2 >z/wham &&
+               git add z &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) conflict' '
+       (
+               cd 1d &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (rename/rename)" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 8 out &&
+               git ls-files -u >out &&
+               test_line_count = 2 out &&
+               git ls-files -o >out &&
+               test_line_count = 3 out &&
+
+               git rev-parse >actual \
+                       :0:x/b :0:x/c :0:x/d :0:x/e :0:x/m :0:x/n &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  O:y/d  O:y/e  A:y/m  B:z/n &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse :0:x/wham &&
+               git rev-parse >actual \
+                       :2:x/wham :3:x/wham &&
+               git rev-parse >expect \
+                        A:y/wham  B:z/wham &&
+               test_cmp expect actual &&
+
+               test_path_is_missing x/wham &&
+               test_path_is_file x/wham~HEAD &&
+               test_path_is_file x/wham~B^0 &&
+
+               git hash-object >actual \
+                       x/wham~HEAD x/wham~B^0 &&
+               git rev-parse >expect \
+                       A:y/wham    B:z/wham &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 1e, Renamed directory, with all filenames being renamed too
+#   (Related to testcases 9f & 9g)
+#   Commit O: z/{oldb,oldc}
+#   Commit A: y/{newb,newc}
+#   Commit B: z/{oldb,oldc,d}
+#   Expected: y/{newb,newc,d}
+
+test_expect_success '1e-setup: Renamed directory, with all files being renamed too' '
+       test_create_repo 1e &&
+       (
+               cd 1e &&
+
+               mkdir z &&
+               echo b >z/oldb &&
+               echo c >z/oldc &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               mkdir y &&
+               git mv z/oldb y/newb &&
+               git mv z/oldc y/newc &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo d >z/d &&
+               git add z/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '1e-check: Renamed directory, with all files being renamed too' '
+       (
+               cd 1e &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/newb HEAD:y/newc HEAD:y/d &&
+               git rev-parse >expect \
+                       O:z/oldb    O:z/oldc    B:z/d &&
+               test_cmp expect actual &&
+               test_must_fail git rev-parse HEAD:z/d
+       )
+'
+
+# Testcase 1f, Split a directory into two other directories
+#   (Related to testcases 3a, all of section 2, and all of section 4)
+#   Commit O: z/{b,c,d,e,f}
+#   Commit A: z/{b,c,d,e,f,g}
+#   Commit B: y/{b,c}, x/{d,e,f}
+#   Expected: y/{b,c}, x/{d,e,f,g}
+
+test_expect_success '1f-setup: Split a directory into two other directories' '
+       test_create_repo 1f &&
+       (
+               cd 1f &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               echo d >z/d &&
+               echo e >z/e &&
+               echo f >z/f &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               echo g >z/g &&
+               git add z/g &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               mkdir y &&
+               mkdir x &&
+               git mv z/b y/ &&
+               git mv z/c y/ &&
+               git mv z/d x/ &&
+               git mv z/e x/ &&
+               git mv z/f x/ &&
+               rmdir z &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '1f-check: Split a directory into two other directories' '
+       (
+               cd 1f &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 6 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:x/d HEAD:x/e HEAD:x/f HEAD:x/g &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    O:z/d    O:z/e    O:z/f    A:z/g &&
+               test_cmp expect actual &&
+               test_path_is_missing z/g &&
+               test_must_fail git rev-parse HEAD:z/g
+       )
+'
+
+###########################################################################
+# Rules suggested by testcases in section 1:
+#
+#   We should still detect the directory rename even if it wasn't just
+#   the directory renamed, but the files within it. (see 1b)
+#
+#   If renames split a directory into two or more others, the directory
+#   with the most renames, "wins" (see 1c).  However, see the testcases
+#   in section 2, plus testcases 3a and 4a.
+###########################################################################
+
+
+###########################################################################
+# SECTION 2: Split into multiple directories, with equal number of paths
+#
+# Explore the splitting-a-directory rules a bit; what happens in the
+# edge cases?
+#
+# Note that there is a closely related case of a directory not being
+# split on either side of history, but being renamed differently on
+# each side.  See testcase 8e for that.
+###########################################################################
+
+# Testcase 2a, Directory split into two on one side, with equal numbers of paths
+#   Commit O: z/{b,c}
+#   Commit A: y/b, w/c
+#   Commit B: z/{b,c,d}
+#   Expected: y/b, w/c, z/d, with warning about z/ -> (y/ vs. w/) conflict
+test_expect_success '2a-setup: Directory split into two on one side, with equal numbers of paths' '
+       test_create_repo 2a &&
+       (
+               cd 2a &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               mkdir y &&
+               mkdir w &&
+               git mv z/b y/ &&
+               git mv z/c w/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo d >z/d &&
+               git add z/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '2a-check: Directory split into two on one side, with equal numbers of paths' '
+       (
+               cd 2a &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT.*directory rename split" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:w/c :0:z/d &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  B:z/d &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 2b, Directory split into two on one side, with equal numbers of paths
+#   Commit O: z/{b,c}
+#   Commit A: y/b, w/c
+#   Commit B: z/{b,c}, x/d
+#   Expected: y/b, w/c, x/d; No warning about z/ -> (y/ vs. w/) conflict
+test_expect_success '2b-setup: Directory split into two on one side, with equal numbers of paths' '
+       test_create_repo 2b &&
+       (
+               cd 2b &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               mkdir y &&
+               mkdir w &&
+               git mv z/b y/ &&
+               git mv z/c w/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               mkdir x &&
+               echo d >x/d &&
+               git add x/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '2b-check: Directory split into two on one side, with equal numbers of paths' '
+       (
+               cd 2b &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 >out &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:w/c :0:x/d &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  B:x/d &&
+               test_cmp expect actual &&
+               test_i18ngrep ! "CONFLICT.*directory rename split" out
+       )
+'
+
+###########################################################################
+# Rules suggested by section 2:
+#
+#   None; the rule was already covered in section 1.  These testcases are
+#   here just to make sure the conflict resolution and necessary warning
+#   messages are handled correctly.
+###########################################################################
+
+
+###########################################################################
+# SECTION 3: Path in question is the source path for some rename already
+#
+# Combining cases from Section 1 and trying to handle them could lead to
+# directory renaming detection being over-applied.  So, this section
+# provides some good testcases to check that the implementation doesn't go
+# too far.
+###########################################################################
+
+# Testcase 3a, Avoid implicit rename if involved as source on other side
+#   (Related to testcases 1c, 1f, and 9h)
+#   Commit O: z/{b,c,d}
+#   Commit A: z/{b,c,d} (no change)
+#   Commit B: y/{b,c}, x/d
+#   Expected: y/{b,c}, x/d
+test_expect_success '3a-setup: Avoid implicit rename if involved as source on other side' '
+       test_create_repo 3a &&
+       (
+               cd 3a &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               echo d >z/d &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_tick &&
+               git commit --allow-empty -m "A" &&
+
+               git checkout B &&
+               mkdir y &&
+               mkdir x &&
+               git mv z/b y/ &&
+               git mv z/c y/ &&
+               git mv z/d x/ &&
+               rmdir z &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '3a-check: Avoid implicit rename if involved as source on other side' '
+       (
+               cd 3a &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:x/d &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    O:z/d &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 3b, Avoid implicit rename if involved as source on other side
+#   (Related to testcases 5c and 7c, also kind of 1e and 1f)
+#   Commit O: z/{b,c,d}
+#   Commit A: y/{b,c}, x/d
+#   Commit B: z/{b,c}, w/d
+#   Expected: y/{b,c}, CONFLICT:(z/d -> x/d vs. w/d)
+#   NOTE: We're particularly checking that since z/d is already involved as
+#         a source in a file rename on the same side of history, that we don't
+#         get it involved in directory rename detection.  If it were, we might
+#         end up with CONFLICT:(z/d -> y/d vs. x/d vs. w/d), i.e. a
+#         rename/rename/rename(1to3) conflict, which is just weird.
+test_expect_success '3b-setup: Avoid implicit rename if involved as source on current side' '
+       test_create_repo 3b &&
+       (
+               cd 3b &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               echo d >z/d &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               mkdir y &&
+               mkdir x &&
+               git mv z/b y/ &&
+               git mv z/c y/ &&
+               git mv z/d x/ &&
+               rmdir z &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               mkdir w &&
+               git mv z/d w/ &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '3b-check: Avoid implicit rename if involved as source on current side' '
+       (
+               cd 3b &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep CONFLICT.*rename/rename.*z/d.*x/d.*w/d out &&
+               test_i18ngrep ! CONFLICT.*rename/rename.*y/d out &&
+
+               git ls-files -s >out &&
+               test_line_count = 5 out &&
+               git ls-files -u >out &&
+               test_line_count = 3 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:y/c :1:z/d :2:x/d :3:w/d &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  O:z/d  O:z/d  O:z/d &&
+               test_cmp expect actual &&
+
+               test_path_is_missing z/d &&
+               git hash-object >actual \
+                       x/d   w/d &&
+               git rev-parse >expect \
+                       O:z/d O:z/d &&
+               test_cmp expect actual
+       )
+'
+
+###########################################################################
+# Rules suggested by section 3:
+#
+#   Avoid directory-rename-detection for a path, if that path is the source
+#   of a rename on either side of a merge.
+###########################################################################
+
+
+###########################################################################
+# SECTION 4: Partially renamed directory; still exists on both sides of merge
+#
+# What if we were to attempt to do directory rename detection when someone
+# "mostly" moved a directory but still left some files around, or,
+# equivalently, fully renamed a directory in one commmit and then recreated
+# that directory in a later commit adding some new files and then tried to
+# merge?
+#
+# It's hard to divine user intent in these cases, because you can make an
+# argument that, depending on the intermediate history of the side being
+# merged, that some users will want files in that directory to
+# automatically be detected and renamed, while users with a different
+# intermediate history wouldn't want that rename to happen.
+#
+# I think that it is best to simply not have directory rename detection
+# apply to such cases.  My reasoning for this is four-fold: (1) it's
+# easiest for users in general to figure out what happened if we don't
+# apply directory rename detection in any such case, (2) it's an easy rule
+# to explain ["We don't do directory rename detection if the directory
+# still exists on both sides of the merge"], (3) we can get some hairy
+# edge/corner cases that would be really confusing and possibly not even
+# representable in the index if we were to even try, and [related to 3] (4)
+# attempting to resolve this issue of divining user intent by examining
+# intermediate history goes against the spirit of three-way merges and is a
+# path towards crazy corner cases that are far more complex than what we're
+# already dealing with.
+#
+# Note that the wording of the rule ("We don't do directory rename
+# detection if the directory still exists on both sides of the merge.")
+# also excludes "renaming" of a directory into a subdirectory of itself
+# (e.g. /some/dir/* -> /some/dir/subdir/*).  It may be possible to carve
+# out an exception for "renaming"-beneath-itself cases without opening
+# weird edge/corner cases for other partial directory renames, but for now
+# we are keeping the rule simple.
+#
+# This section contains a test for a partially-renamed-directory case.
+###########################################################################
+
+# Testcase 4a, Directory split, with original directory still present
+#   (Related to testcase 1f)
+#   Commit O: z/{b,c,d,e}
+#   Commit A: y/{b,c,d}, z/e
+#   Commit B: z/{b,c,d,e,f}
+#   Expected: y/{b,c,d}, z/{e,f}
+#   NOTE: Even though most files from z moved to y, we don't want f to follow.
+
+test_expect_success '4a-setup: Directory split, with original directory still present' '
+       test_create_repo 4a &&
+       (
+               cd 4a &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               echo d >z/d &&
+               echo e >z/e &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               mkdir y &&
+               git mv z/b y/ &&
+               git mv z/c y/ &&
+               git mv z/d y/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo f >z/f &&
+               git add z/f &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '4a-check: Directory split, with original directory still present' '
+       (
+               cd 4a &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 5 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:y/d HEAD:z/e HEAD:z/f &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    O:z/d    O:z/e    B:z/f &&
+               test_cmp expect actual
+       )
+'
+
+###########################################################################
+# Rules suggested by section 4:
+#
+#   Directory-rename-detection should be turned off for any directories (as
+#   a source for renames) that exist on both sides of the merge.  (The "as
+#   a source for renames" clarification is due to cases like 1c where
+#   the target directory exists on both sides and we do want the rename
+#   detection.)  But, sadly, see testcase 8b.
+###########################################################################
+
+
+###########################################################################
+# SECTION 5: Files/directories in the way of subset of to-be-renamed paths
+#
+# Implicitly renaming files due to a detected directory rename could run
+# into problems if there are files or directories in the way of the paths
+# we want to rename.  Explore such cases in this section.
+###########################################################################
+
+# Testcase 5a, Merge directories, other side adds files to original and target
+#   Commit O: z/{b,c},       y/d
+#   Commit A: z/{b,c,e_1,f}, y/{d,e_2}
+#   Commit B: y/{b,c,d}
+#   Expected: z/e_1, y/{b,c,d,e_2,f} + CONFLICT warning
+#   NOTE: While directory rename detection is active here causing z/f to
+#         become y/f, we did not apply this for z/e_1 because that would
+#         give us an add/add conflict for y/e_1 vs y/e_2.  This problem with
+#         this add/add, is that both versions of y/e are from the same side
+#         of history, giving us no way to represent this conflict in the
+#         index.
+
+test_expect_success '5a-setup: Merge directories, other side adds files to original and target' '
+       test_create_repo 5a &&
+       (
+               cd 5a &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir y &&
+               echo d >y/d &&
+               git add z y &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               echo e1 >z/e &&
+               echo f >z/f &&
+               echo e2 >y/e &&
+               git add z/e z/f y/e &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv z/b y/ &&
+               git mv z/c y/ &&
+               rmdir z &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '5a-check: Merge directories, other side adds files to original and target' '
+       (
+               cd 5a &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT.*implicit dir rename" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 6 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:y/c :0:y/d :0:y/e :0:z/e :0:y/f &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  O:y/d  A:y/e  A:z/e  A:z/f &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 5b, Rename/delete in order to get add/add/add conflict
+#   (Related to testcase 8d; these may appear slightly inconsistent to users;
+#    Also related to testcases 7d and 7e)
+#   Commit O: z/{b,c,d_1}
+#   Commit A: y/{b,c,d_2}
+#   Commit B: z/{b,c,d_1,e}, y/d_3
+#   Expected: y/{b,c,e}, CONFLICT(add/add: y/d_2 vs. y/d_3)
+#   NOTE: If z/d_1 in commit B were to be involved in dir rename detection, as
+#         we normaly would since z/ is being renamed to y/, then this would be
+#         a rename/delete (z/d_1 -> y/d_1 vs. deleted) AND an add/add/add
+#         conflict of y/d_1 vs. y/d_2 vs. y/d_3.  Add/add/add is not
+#         representable in the index, so the existence of y/d_3 needs to
+#         cause us to bail on directory rename detection for that path, falling
+#         back to git behavior without the directory rename detection.
+
+test_expect_success '5b-setup: Rename/delete in order to get add/add/add conflict' '
+       test_create_repo 5b &&
+       (
+               cd 5b &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               echo d1 >z/d &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git rm z/d &&
+               git mv z y &&
+               echo d2 >y/d &&
+               git add y/d &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               mkdir y &&
+               echo d3 >y/d &&
+               echo e >z/e &&
+               git add y/d z/e &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '5b-check: Rename/delete in order to get add/add/add conflict' '
+       (
+               cd 5b &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (add/add).* y/d" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 5 out &&
+               git ls-files -u >out &&
+               test_line_count = 2 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:y/c :0:y/e :2:y/d :3:y/d &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  B:z/e  A:y/d  B:y/d &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse :1:y/d &&
+               test_path_is_file y/d
+       )
+'
+
+# Testcase 5c, Transitive rename would cause rename/rename/rename/add/add/add
+#   (Directory rename detection would result in transitive rename vs.
+#    rename/rename(1to2) and turn it into a rename/rename(1to3).  Further,
+#    rename paths conflict with separate adds on the other side)
+#   (Related to testcases 3b and 7c)
+#   Commit O: z/{b,c}, x/d_1
+#   Commit A: y/{b,c,d_2}, w/d_1
+#   Commit B: z/{b,c,d_1,e}, w/d_3, y/d_4
+#   Expected: A mess, but only a rename/rename(1to2)/add/add mess.  Use the
+#             presence of y/d_4 in B to avoid doing transitive rename of
+#             x/d_1 -> z/d_1 -> y/d_1, so that the only paths we have at
+#             y/d are y/d_2 and y/d_4.  We still do the move from z/e to y/e,
+#             though, because it doesn't have anything in the way.
+
+test_expect_success '5c-setup: Transitive rename would cause rename/rename/rename/add/add/add' '
+       test_create_repo 5c &&
+       (
+               cd 5c &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir x &&
+               echo d1 >x/d &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               echo d2 >y/d &&
+               git add y/d &&
+               git mv x w &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/d z/ &&
+               mkdir w &&
+               mkdir y &&
+               echo d3 >w/d &&
+               echo d4 >y/d &&
+               echo e >z/e &&
+               git add w/ y/ z/e &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '5c-check: Transitive rename would cause rename/rename/rename/add/add/add' '
+       (
+               cd 5c &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*z/d" out &&
+               test_i18ngrep "CONFLICT (add/add).* y/d" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 9 out &&
+               git ls-files -u >out &&
+               test_line_count = 6 out &&
+               git ls-files -o >out &&
+               test_line_count = 3 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:y/c :0:y/e &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  B:z/e &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse :1:y/d &&
+               git rev-parse >actual \
+                       :2:w/d :3:w/d :1:x/d :2:y/d :3:y/d :3:z/d &&
+               git rev-parse >expect \
+                        O:x/d  B:w/d  O:x/d  A:y/d  B:y/d  O:x/d &&
+               test_cmp expect actual &&
+
+               git hash-object >actual \
+                       w/d~HEAD w/d~B^0 z/d &&
+               git rev-parse >expect \
+                       O:x/d    B:w/d   O:x/d &&
+               test_cmp expect actual &&
+               test_path_is_missing x/d &&
+               test_path_is_file y/d &&
+               grep -q "<<<<" y/d  # conflict markers should be present
+       )
+'
+
+# Testcase 5d, Directory/file/file conflict due to directory rename
+#   Commit O: z/{b,c}
+#   Commit A: y/{b,c,d_1}
+#   Commit B: z/{b,c,d_2,f}, y/d/e
+#   Expected: y/{b,c,d/e,f}, z/d_2, CONFLICT(file/directory), y/d_1~HEAD
+#   Note: The fact that y/d/ exists in B makes us bail on directory rename
+#         detection for z/d_2, but that doesn't prevent us from applying the
+#         directory rename detection for z/f -> y/f.
+
+test_expect_success '5d-setup: Directory/file/file conflict due to directory rename' '
+       test_create_repo 5d &&
+       (
+               cd 5d &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               echo d1 >y/d &&
+               git add y/d &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               mkdir -p y/d &&
+               echo e >y/d/e &&
+               echo d2 >z/d &&
+               echo f >z/f &&
+               git add y/d/e z/d z/f &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '5d-check: Directory/file/file conflict due to directory rename' '
+       (
+               cd 5d &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (file/directory).*y/d" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 6 out &&
+               git ls-files -u >out &&
+               test_line_count = 1 out &&
+               git ls-files -o >out &&
+               test_line_count = 2 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:y/c :0:z/d :0:y/f :2:y/d :0:y/d/e &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  B:z/d  B:z/f  A:y/d  B:y/d/e &&
+               test_cmp expect actual &&
+
+               git hash-object y/d~HEAD >actual &&
+               git rev-parse A:y/d >expect &&
+               test_cmp expect actual
+       )
+'
+
+###########################################################################
+# Rules suggested by section 5:
+#
+#   If a subset of to-be-renamed files have a file or directory in the way,
+#   "turn off" the directory rename for those specific sub-paths, falling
+#   back to old handling.  But, sadly, see testcases 8a and 8b.
+###########################################################################
+
+
+###########################################################################
+# SECTION 6: Same side of the merge was the one that did the rename
+#
+# It may sound obvious that you only want to apply implicit directory
+# renames to directories if the _other_ side of history did the renaming.
+# If you did make an implementation that didn't explicitly enforce this
+# rule, the majority of cases that would fall under this section would
+# also be solved by following the rules from the above sections.  But
+# there are still a few that stick out, so this section covers them just
+# to make sure we also get them right.
+###########################################################################
+
+# Testcase 6a, Tricky rename/delete
+#   Commit O: z/{b,c,d}
+#   Commit A: z/b
+#   Commit B: y/{b,c}, z/d
+#   Expected: y/b, CONFLICT(rename/delete, z/c -> y/c vs. NULL)
+#   Note: We're just checking here that the rename of z/b and z/c to put
+#         them under y/ doesn't accidentally catch z/d and make it look like
+#         it is also involved in a rename/delete conflict.
+
+test_expect_success '6a-setup: Tricky rename/delete' '
+       test_create_repo 6a &&
+       (
+               cd 6a &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               echo d >z/d &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git rm z/c &&
+               git rm z/d &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               mkdir y &&
+               git mv z/b y/ &&
+               git mv z/c y/ &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '6a-check: Tricky rename/delete' '
+       (
+               cd 6a &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (rename/delete).*z/c.*y/c" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 2 out &&
+               git ls-files -u >out &&
+               test_line_count = 1 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :3:y/c &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 6b, Same rename done on both sides
+#   (Related to testcases 6c and 8e)
+#   Commit O: z/{b,c}
+#   Commit A: y/{b,c}
+#   Commit B: y/{b,c}, z/d
+#   Expected: y/{b,c}, z/d
+#   Note: If we did directory rename detection here, we'd move z/d into y/,
+#         but B did that rename and still decided to put the file into z/,
+#         so we probably shouldn't apply directory rename detection for it.
+
+test_expect_success '6b-setup: Same rename done on both sides' '
+       test_create_repo 6b &&
+       (
+               cd 6b &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv z y &&
+               mkdir z &&
+               echo d >z/d &&
+               git add z/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '6b-check: Same rename done on both sides' '
+       (
+               cd 6b &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:z/d &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    B:z/d &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 6c, Rename only done on same side
+#   (Related to testcases 6b and 8e)
+#   Commit O: z/{b,c}
+#   Commit A: z/{b,c} (no change)
+#   Commit B: y/{b,c}, z/d
+#   Expected: y/{b,c}, z/d
+#   NOTE: Seems obvious, but just checking that the implementation doesn't
+#         "accidentally detect a rename" and give us y/{b,c,d}.
+
+test_expect_success '6c-setup: Rename only done on same side' '
+       test_create_repo 6c &&
+       (
+               cd 6c &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_tick &&
+               git commit --allow-empty -m "A" &&
+
+               git checkout B &&
+               git mv z y &&
+               mkdir z &&
+               echo d >z/d &&
+               git add z/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '6c-check: Rename only done on same side' '
+       (
+               cd 6c &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:z/d &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    B:z/d &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 6d, We don't always want transitive renaming
+#   (Related to testcase 1c)
+#   Commit O: z/{b,c}, x/d
+#   Commit A: z/{b,c}, x/d (no change)
+#   Commit B: y/{b,c}, z/d
+#   Expected: y/{b,c}, z/d
+#   NOTE: Again, this seems obvious but just checking that the implementation
+#         doesn't "accidentally detect a rename" and give us y/{b,c,d}.
+
+test_expect_success '6d-setup: We do not always want transitive renaming' '
+       test_create_repo 6d &&
+       (
+               cd 6d &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir x &&
+               echo d >x/d &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_tick &&
+               git commit --allow-empty -m "A" &&
+
+               git checkout B &&
+               git mv z y &&
+               git mv x z &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '6d-check: We do not always want transitive renaming' '
+       (
+               cd 6d &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:z/d &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    O:x/d &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 6e, Add/add from one-side
+#   Commit O: z/{b,c}
+#   Commit A: z/{b,c} (no change)
+#   Commit B: y/{b,c,d_1}, z/d_2
+#   Expected: y/{b,c,d_1}, z/d_2
+#   NOTE: Again, this seems obvious but just checking that the implementation
+#         doesn't "accidentally detect a rename" and give us y/{b,c} +
+#         add/add conflict on y/d_1 vs y/d_2.
+
+test_expect_success '6e-setup: Add/add from one side' '
+       test_create_repo 6e &&
+       (
+               cd 6e &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_tick &&
+               git commit --allow-empty -m "A" &&
+
+               git checkout B &&
+               git mv z y &&
+               echo d1 > y/d &&
+               mkdir z &&
+               echo d2 > z/d &&
+               git add y/d z/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '6e-check: Add/add from one side' '
+       (
+               cd 6e &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 4 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:y/d HEAD:z/d &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    B:y/d    B:z/d &&
+               test_cmp expect actual
+       )
+'
+
+###########################################################################
+# Rules suggested by section 6:
+#
+#   Only apply implicit directory renames to directories if the other
+#   side of history is the one doing the renaming.
+###########################################################################
+
+
+###########################################################################
+# SECTION 7: More involved Edge/Corner cases
+#
+# The ruleset we have generated in the above sections seems to provide
+# well-defined merges.  But can we find edge/corner cases that either (a)
+# are harder for users to understand, or (b) have a resolution that is
+# non-intuitive or suboptimal?
+#
+# The testcases in this section dive into cases that I've tried to craft in
+# a way to find some that might be surprising to users or difficult for
+# them to understand (the next section will look at non-intuitive or
+# suboptimal merge results).  Some of the testcases are similar to ones
+# from past sections, but have been simplified to try to highlight error
+# messages using a "modified" path (due to the directory rename).  Are
+# users okay with these?
+#
+# In my opinion, testcases that are difficult to understand from this
+# section is due to difficulty in the testcase rather than the directory
+# renaming (similar to how t6042 and t6036 have difficult resolutions due
+# to the problem setup itself being complex).  And I don't think the
+# error messages are a problem.
+#
+# On the other hand, the testcases in section 8 worry me slightly more...
+###########################################################################
+
+# Testcase 7a, rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file
+#   Commit O: z/{b,c}
+#   Commit A: y/{b,c}
+#   Commit B: w/b, x/c, z/d
+#   Expected: y/d, CONFLICT(rename/rename for both z/b and z/c)
+#   NOTE: There's a rename of z/ here, y/ has more renames, so z/d -> y/d.
+
+test_expect_success '7a-setup: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
+       test_create_repo 7a &&
+       (
+               cd 7a &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               mkdir w &&
+               mkdir x &&
+               git mv z/b w/ &&
+               git mv z/c x/ &&
+               echo d > z/d &&
+               git add z/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '7a-check: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
+       (
+               cd 7a &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (rename/rename).*z/b.*y/b.*w/b" out &&
+               test_i18ngrep "CONFLICT (rename/rename).*z/c.*y/c.*x/c" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 7 out &&
+               git ls-files -u >out &&
+               test_line_count = 6 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       :1:z/b :2:y/b :3:w/b :1:z/c :2:y/c :3:x/c :0:y/d &&
+               git rev-parse >expect \
+                        O:z/b  O:z/b  O:z/b  O:z/c  O:z/c  O:z/c  B:z/d &&
+               test_cmp expect actual &&
+
+               git hash-object >actual \
+                       y/b   w/b   y/c   x/c &&
+               git rev-parse >expect \
+                       O:z/b O:z/b O:z/c O:z/c &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 7b, rename/rename(2to1), but only due to transitive rename
+#   (Related to testcase 1d)
+#   Commit O: z/{b,c},     x/d_1, w/d_2
+#   Commit A: y/{b,c,d_2}, x/d_1
+#   Commit B: z/{b,c,d_1},        w/d_2
+#   Expected: y/{b,c}, CONFLICT(rename/rename(2to1): x/d_1, w/d_2 -> y_d)
+
+test_expect_success '7b-setup: rename/rename(2to1), but only due to transitive rename' '
+       test_create_repo 7b &&
+       (
+               cd 7b &&
+
+               mkdir z &&
+               mkdir x &&
+               mkdir w &&
+               echo b >z/b &&
+               echo c >z/c &&
+               echo d1 > x/d &&
+               echo d2 > w/d &&
+               git add z x w &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               git mv w/d y/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/d z/ &&
+               rmdir x &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '7b-check: rename/rename(2to1), but only due to transitive rename' '
+       (
+               cd 7b &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (rename/rename)" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 4 out &&
+               git ls-files -u >out &&
+               test_line_count = 2 out &&
+               git ls-files -o >out &&
+               test_line_count = 3 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:y/c :2:y/d :3:y/d &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  O:w/d  O:x/d &&
+               test_cmp expect actual &&
+
+               test_path_is_missing y/d &&
+               test_path_is_file y/d~HEAD &&
+               test_path_is_file y/d~B^0 &&
+
+               git hash-object >actual \
+                       y/d~HEAD y/d~B^0 &&
+               git rev-parse >expect \
+                       O:w/d    O:x/d &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 7c, rename/rename(1to...2or3); transitive rename may add complexity
+#   (Related to testcases 3b and 5c)
+#   Commit O: z/{b,c}, x/d
+#   Commit A: y/{b,c}, w/d
+#   Commit B: z/{b,c,d}
+#   Expected: y/{b,c}, CONFLICT(x/d -> w/d vs. y/d)
+#   NOTE: z/ was renamed to y/ so we do want to report
+#         neither CONFLICT(x/d -> w/d vs. z/d)
+#         nor CONFLiCT x/d -> w/d vs. y/d vs. z/d)
+
+test_expect_success '7c-setup: rename/rename(1to...2or3); transitive rename may add complexity' '
+       test_create_repo 7c &&
+       (
+               cd 7c &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir x &&
+               echo d >x/d &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               git mv x w &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/d z/ &&
+               rmdir x &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '7c-check: rename/rename(1to...2or3); transitive rename may add complexity' '
+       (
+               cd 7c &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*y/d" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 5 out &&
+               git ls-files -u >out &&
+               test_line_count = 3 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:y/c :1:x/d :2:w/d :3:y/d &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  O:x/d  O:x/d  O:x/d &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 7d, transitive rename involved in rename/delete; how is it reported?
+#   (Related somewhat to testcases 5b and 8d)
+#   Commit O: z/{b,c}, x/d
+#   Commit A: y/{b,c}
+#   Commit B: z/{b,c,d}
+#   Expected: y/{b,c}, CONFLICT(delete x/d vs rename to y/d)
+#   NOTE: z->y so NOT CONFLICT(delete x/d vs rename to z/d)
+
+test_expect_success '7d-setup: transitive rename involved in rename/delete; how is it reported?' '
+       test_create_repo 7d &&
+       (
+               cd 7d &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir x &&
+               echo d >x/d &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               git rm -rf x &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/d z/ &&
+               rmdir x &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '7d-check: transitive rename involved in rename/delete; how is it reported?' '
+       (
+               cd 7d &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+               git ls-files -u >out &&
+               test_line_count = 1 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:y/c :3:y/d &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  O:x/d &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 7e, transitive rename in rename/delete AND dirs in the way
+#   (Very similar to 'both rename source and destination involved in D/F conflict' from t6022-merge-rename.sh)
+#   (Also related to testcases 9c and 9d)
+#   Commit O: z/{b,c},     x/d_1
+#   Commit A: y/{b,c,d/g}, x/d/f
+#   Commit B: z/{b,c,d_1}
+#   Expected: rename/delete(x/d_1->y/d_1 vs. None) + D/F conflict on y/d
+#             y/{b,c,d/g}, y/d_1~B^0, x/d/f
+
+#   NOTE: The main path of interest here is d_1 and where it ends up, but
+#         this is actually a case that has two potential directory renames
+#         involved and D/F conflict(s), so it makes sense to walk through
+#         each step.
+#
+#         Commit A renames z/ -> y/.  Thus everything that B adds to z/
+#         should be instead moved to y/.  This gives us the D/F conflict on
+#         y/d because x/d_1 -> z/d_1 -> y/d_1 conflicts with y/d/g.
+#
+#         Further, commit B renames x/ -> z/, thus everything A adds to x/
+#         should instead be moved to z/...BUT we removed z/ and renamed it
+#         to y/, so maybe everything should move not from x/ to z/, but
+#         from x/ to z/ to y/.  Doing so might make sense from the logic so
+#         far, but note that commit A had both an x/ and a y/; it did the
+#         renaming of z/ to y/ and created x/d/f and it clearly made these
+#         things separate, so it doesn't make much sense to push these
+#         together.  Doing so is what I'd call a doubly transitive rename;
+#         see testcases 9c and 9d for further discussion of this issue and
+#         how it's resolved.
+
+test_expect_success '7e-setup: transitive rename in rename/delete AND dirs in the way' '
+       test_create_repo 7e &&
+       (
+               cd 7e &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir x &&
+               echo d1 >x/d &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               git rm x/d &&
+               mkdir -p x/d &&
+               mkdir -p y/d &&
+               echo f >x/d/f &&
+               echo g >y/d/g &&
+               git add x/d/f y/d/g &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/d z/ &&
+               rmdir x &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '7e-check: transitive rename in rename/delete AND dirs in the way' '
+       (
+               cd 7e &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 5 out &&
+               git ls-files -u >out &&
+               test_line_count = 1 out &&
+               git ls-files -o >out &&
+               test_line_count = 2 out &&
+
+               git rev-parse >actual \
+                       :0:x/d/f :0:y/d/g :0:y/b :0:y/c :3:y/d &&
+               git rev-parse >expect \
+                        A:x/d/f  A:y/d/g  O:z/b  O:z/c  O:x/d &&
+               test_cmp expect actual &&
+
+               git hash-object y/d~B^0 >actual &&
+               git rev-parse O:x/d >expect &&
+               test_cmp expect actual
+       )
+'
+
+###########################################################################
+# SECTION 8: Suboptimal merges
+#
+# As alluded to in the last section, the ruleset we have built up for
+# detecting directory renames unfortunately has some special cases where it
+# results in slightly suboptimal or non-intuitive behavior.  This section
+# explores these cases.
+#
+# To be fair, we already had non-intuitive or suboptimal behavior for most
+# of these cases in git before introducing implicit directory rename
+# detection, but it'd be nice if there was a modified ruleset out there
+# that handled these cases a bit better.
+###########################################################################
+
+# Testcase 8a, Dual-directory rename, one into the others' way
+#   Commit O. x/{a,b},   y/{c,d}
+#   Commit A. x/{a,b,e}, y/{c,d,f}
+#   Commit B. y/{a,b},   z/{c,d}
+#
+# Possible Resolutions:
+#   w/o dir-rename detection: y/{a,b,f},   z/{c,d},   x/e
+#   Currently expected:       y/{a,b,e,f}, z/{c,d}
+#   Optimal:                  y/{a,b,e},   z/{c,d,f}
+#
+# Note: Both x and y got renamed and it'd be nice to detect both, and we do
+# better with directory rename detection than git did without, but the
+# simple rule from section 5 prevents me from handling this as optimally as
+# we potentially could.
+
+test_expect_success '8a-setup: Dual-directory rename, one into the others way' '
+       test_create_repo 8a &&
+       (
+               cd 8a &&
+
+               mkdir x &&
+               mkdir y &&
+               echo a >x/a &&
+               echo b >x/b &&
+               echo c >y/c &&
+               echo d >y/d &&
+               git add x y &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               echo e >x/e &&
+               echo f >y/f &&
+               git add x/e y/f &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv y z &&
+               git mv x y &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '8a-check: Dual-directory rename, one into the others way' '
+       (
+               cd 8a &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 6 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/a HEAD:y/b HEAD:y/e HEAD:y/f HEAD:z/c HEAD:z/d &&
+               git rev-parse >expect \
+                       O:x/a    O:x/b    A:x/e    A:y/f    O:y/c    O:y/d &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 8b, Dual-directory rename, one into the others' way, with conflicting filenames
+#   Commit O. x/{a_1,b_1},     y/{a_2,b_2}
+#   Commit A. x/{a_1,b_1,e_1}, y/{a_2,b_2,e_2}
+#   Commit B. y/{a_1,b_1},     z/{a_2,b_2}
+#
+#   w/o dir-rename detection: y/{a_1,b_1,e_2}, z/{a_2,b_2}, x/e_1
+#   Currently expected:       <same>
+#   Scary:                    y/{a_1,b_1},     z/{a_2,b_2}, CONFLICT(add/add, e_1 vs. e_2)
+#   Optimal:                  y/{a_1,b_1,e_1}, z/{a_2,b_2,e_2}
+#
+# Note: Very similar to 8a, except instead of 'e' and 'f' in directories x and
+# y, both are named 'e'.  Without directory rename detection, neither file
+# moves directories.  Implement directory rename detection suboptimally, and
+# you get an add/add conflict, but both files were added in commit A, so this
+# is an add/add conflict where one side of history added both files --
+# something we can't represent in the index.  Obviously, we'd prefer the last
+# resolution, but our previous rules are too coarse to allow it.  Using both
+# the rules from section 4 and section 5 save us from the Scary resolution,
+# making us fall back to pre-directory-rename-detection behavior for both
+# e_1 and e_2.
+
+test_expect_success '8b-setup: Dual-directory rename, one into the others way, with conflicting filenames' '
+       test_create_repo 8b &&
+       (
+               cd 8b &&
+
+               mkdir x &&
+               mkdir y &&
+               echo a1 >x/a &&
+               echo b1 >x/b &&
+               echo a2 >y/a &&
+               echo b2 >y/b &&
+               git add x y &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               echo e1 >x/e &&
+               echo e2 >y/e &&
+               git add x/e y/e &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv y z &&
+               git mv x y &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '8b-check: Dual-directory rename, one into the others way, with conflicting filenames' '
+       (
+               cd 8b &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 6 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/a HEAD:y/b HEAD:z/a HEAD:z/b HEAD:x/e HEAD:y/e &&
+               git rev-parse >expect \
+                       O:x/a    O:x/b    O:y/a    O:y/b    A:x/e    A:y/e &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 8c, modify/delete or rename+modify/delete?
+#   (Related to testcases 5b, 8d, and 9h)
+#   Commit O: z/{b,c,d}
+#   Commit A: y/{b,c}
+#   Commit B: z/{b,c,d_modified,e}
+#   Expected: y/{b,c,e}, CONFLICT(modify/delete: on z/d)
+#
+#   Note: It could easily be argued that the correct resolution here is
+#         y/{b,c,e}, CONFLICT(rename/delete: z/d -> y/d vs deleted)
+#         and that the modifed version of d should be present in y/ after
+#         the merge, just marked as conflicted.  Indeed, I previously did
+#         argue that.  But applying directory renames to the side of
+#         history where a file is merely modified results in spurious
+#         rename/rename(1to2) conflicts -- see testcase 9h.  See also
+#         notes in 8d.
+
+test_expect_success '8c-setup: modify/delete or rename+modify/delete?' '
+       test_create_repo 8c &&
+       (
+               cd 8c &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               test_seq 1 10 >z/d &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git rm z/d &&
+               git mv z y &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo 11 >z/d &&
+               test_chmod +x z/d &&
+               echo e >z/e &&
+               git add z/d z/e &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '8c-check: modify/delete or rename+modify/delete' '
+       (
+               cd 8c &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               test_i18ngrep "CONFLICT (modify/delete).* z/d" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 5 out &&
+               git ls-files -u >out &&
+               test_line_count = 2 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :0:y/c :0:y/e :1:z/d :3:z/d &&
+               git rev-parse >expect \
+                        O:z/b  O:z/c  B:z/e  O:z/d  B:z/d &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse :2:z/d &&
+               git ls-files -s z/d | grep ^100755 &&
+               test_path_is_file z/d &&
+               test_path_is_missing y/d
+       )
+'
+
+# Testcase 8d, rename/delete...or not?
+#   (Related to testcase 5b; these may appear slightly inconsistent to users;
+#    Also related to testcases 7d and 7e)
+#   Commit O: z/{b,c,d}
+#   Commit A: y/{b,c}
+#   Commit B: z/{b,c,d,e}
+#   Expected: y/{b,c,e}
+#
+#   Note: It would also be somewhat reasonable to resolve this as
+#             y/{b,c,e}, CONFLICT(rename/delete: x/d -> y/d or deleted)
+#
+#   In this case, I'm leaning towards: commit A was the one that deleted z/d
+#   and it did the rename of z to y, so the two "conflicts" (rename vs.
+#   delete) are both coming from commit A, which is illogical.  Conflicts
+#   during merging are supposed to be about opposite sides doing things
+#   differently.
+
+test_expect_success '8d-setup: rename/delete...or not?' '
+       test_create_repo 8d &&
+       (
+               cd 8d &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               test_seq 1 10 >z/d &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git rm z/d &&
+               git mv z y &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo e >z/e &&
+               git add z/e &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '8d-check: rename/delete...or not?' '
+       (
+               cd 8d &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:y/e &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    B:z/e &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 8e, Both sides rename, one side adds to original directory
+#   Commit O: z/{b,c}
+#   Commit A: y/{b,c}
+#   Commit B: w/{b,c}, z/d
+#
+# Possible Resolutions:
+#   w/o dir-rename detection: z/d, CONFLICT(z/b -> y/b vs. w/b),
+#                                  CONFLICT(z/c -> y/c vs. w/c)
+#   Currently expected:       y/d, CONFLICT(z/b -> y/b vs. w/b),
+#                                  CONFLICT(z/c -> y/c vs. w/c)
+#   Optimal:                  ??
+#
+# Notes: In commit A, directory z got renamed to y.  In commit B, directory z
+#        did NOT get renamed; the directory is still present; instead it is
+#        considered to have just renamed a subset of paths in directory z
+#        elsewhere.  Therefore, the directory rename done in commit A to z/
+#        applies to z/d and maps it to y/d.
+#
+#        It's possible that users would get confused about this, but what
+#        should we do instead?  Silently leaving at z/d seems just as bad or
+#        maybe even worse.  Perhaps we could print a big warning about z/d
+#        and how we're moving to y/d in this case, but when I started thinking
+#        about the ramifications of doing that, I didn't know how to rule out
+#        that opening other weird edge and corner cases so I just punted.
+
+test_expect_success '8e-setup: Both sides rename, one side adds to original directory' '
+       test_create_repo 8e &&
+       (
+               cd 8e &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv z w &&
+               mkdir z &&
+               echo d >z/d &&
+               git add z/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '8e-check: Both sides rename, one side adds to original directory' '
+       (
+               cd 8e &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep CONFLICT.*rename/rename.*z/c.*y/c.*w/c out &&
+               test_i18ngrep CONFLICT.*rename/rename.*z/b.*y/b.*w/b out &&
+
+               git ls-files -s >out &&
+               test_line_count = 7 out &&
+               git ls-files -u >out &&
+               test_line_count = 6 out &&
+               git ls-files -o >out &&
+               test_line_count = 2 out &&
+
+               git rev-parse >actual \
+                       :1:z/b :2:y/b :3:w/b :1:z/c :2:y/c :3:w/c :0:y/d &&
+               git rev-parse >expect \
+                        O:z/b  O:z/b  O:z/b  O:z/c  O:z/c  O:z/c  B:z/d &&
+               test_cmp expect actual &&
+
+               git hash-object >actual \
+                       y/b   w/b   y/c   w/c &&
+               git rev-parse >expect \
+                       O:z/b O:z/b O:z/c O:z/c &&
+               test_cmp expect actual &&
+
+               test_path_is_missing z/b &&
+               test_path_is_missing z/c
+       )
+'
+
+###########################################################################
+# SECTION 9: Other testcases
+#
+# This section consists of miscellaneous testcases I thought of during
+# the implementation which round out the testing.
+###########################################################################
+
+# Testcase 9a, Inner renamed directory within outer renamed directory
+#   (Related to testcase 1f)
+#   Commit O: z/{b,c,d/{e,f,g}}
+#   Commit A: y/{b,c}, x/w/{e,f,g}
+#   Commit B: z/{b,c,d/{e,f,g,h},i}
+#   Expected: y/{b,c,i}, x/w/{e,f,g,h}
+#   NOTE: The only reason this one is interesting is because when a directory
+#         is split into multiple other directories, we determine by the weight
+#         of which one had the most paths going to it.  A naive implementation
+#         of that could take the new file in commit B at z/i to x/w/i or x/i.
+
+test_expect_success '9a-setup: Inner renamed directory within outer renamed directory' '
+       test_create_repo 9a &&
+       (
+               cd 9a &&
+
+               mkdir -p z/d &&
+               echo b >z/b &&
+               echo c >z/c &&
+               echo e >z/d/e &&
+               echo f >z/d/f &&
+               echo g >z/d/g &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               mkdir x &&
+               git mv z/d x/w &&
+               git mv z y &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo h >z/d/h &&
+               echo i >z/i &&
+               git add z &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '9a-check: Inner renamed directory within outer renamed directory' '
+       (
+               cd 9a &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 7 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:y/i &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    B:z/i &&
+               test_cmp expect actual &&
+
+               git rev-parse >actual \
+                       HEAD:x/w/e HEAD:x/w/f HEAD:x/w/g HEAD:x/w/h &&
+               git rev-parse >expect \
+                       O:z/d/e    O:z/d/f    O:z/d/g    B:z/d/h &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 9b, Transitive rename with content merge
+#   (Related to testcase 1c)
+#   Commit O: z/{b,c},   x/d_1
+#   Commit A: y/{b,c},   x/d_2
+#   Commit B: z/{b,c,d_3}
+#   Expected: y/{b,c,d_merged}
+
+test_expect_success '9b-setup: Transitive rename with content merge' '
+       test_create_repo 9b &&
+       (
+               cd 9b &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir x &&
+               test_seq 1 10 >x/d &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               test_seq 1 11 >x/d &&
+               git add x/d &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               test_seq 0 10 >x/d &&
+               git mv x/d z/d &&
+               git add z/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '9b-check: Transitive rename with content merge' '
+       (
+               cd 9b &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+
+               test_seq 0 11 >expected &&
+               test_cmp expected y/d &&
+               git add expected &&
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:y/d &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    :0:expected &&
+               test_cmp expect actual &&
+               test_must_fail git rev-parse HEAD:x/d &&
+               test_must_fail git rev-parse HEAD:z/d &&
+               test_path_is_missing z/d &&
+
+               test $(git rev-parse HEAD:y/d) != $(git rev-parse O:x/d) &&
+               test $(git rev-parse HEAD:y/d) != $(git rev-parse A:x/d) &&
+               test $(git rev-parse HEAD:y/d) != $(git rev-parse B:z/d)
+       )
+'
+
+# Testcase 9c, Doubly transitive rename?
+#   (Related to testcase 1c, 7e, and 9d)
+#   Commit O: z/{b,c},     x/{d,e},    w/f
+#   Commit A: y/{b,c},     x/{d,e,f,g}
+#   Commit B: z/{b,c,d,e},             w/f
+#   Expected: y/{b,c,d,e}, x/{f,g}
+#
+#   NOTE: x/f and x/g may be slightly confusing here.  The rename from w/f to
+#         x/f is clear.  Let's look beyond that.  Here's the logic:
+#            Commit B renamed x/ -> z/
+#            Commit A renamed z/ -> y/
+#         So, we could possibly further rename x/f to z/f to y/f, a doubly
+#         transient rename.  However, where does it end?  We can chain these
+#         indefinitely (see testcase 9d).  What if there is a D/F conflict
+#         at z/f/ or y/f/?  Or just another file conflict at one of those
+#         paths?  In the case of an N-long chain of transient renamings,
+#         where do we "abort" the rename at?  Can the user make sense of
+#         the resulting conflict and resolve it?
+#
+#         To avoid this confusion I use the simple rule that if the other side
+#         of history did a directory rename to a path that your side renamed
+#         away, then ignore that particular rename from the other side of
+#         history for any implicit directory renames.
+
+test_expect_success '9c-setup: Doubly transitive rename?' '
+       test_create_repo 9c &&
+       (
+               cd 9c &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               mkdir x &&
+               echo d >x/d &&
+               echo e >x/e &&
+               mkdir w &&
+               echo f >w/f &&
+               git add z x w &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z y &&
+               git mv w/f x/ &&
+               echo g >x/g &&
+               git add x/g &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/d z/d &&
+               git mv x/e z/e &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '9c-check: Doubly transitive rename?' '
+       (
+               cd 9c &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 >out &&
+               test_i18ngrep "WARNING: Avoiding applying x -> z rename to x/f" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 6 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e HEAD:x/f HEAD:x/g &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    O:x/d    O:x/e    O:w/f    A:x/g &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 9d, N-fold transitive rename?
+#   (Related to testcase 9c...and 1c and 7e)
+#   Commit O: z/a, y/b, x/c, w/d, v/e, u/f
+#   Commit A:  y/{a,b},  w/{c,d},  u/{e,f}
+#   Commit B: z/{a,t}, x/{b,c}, v/{d,e}, u/f
+#   Expected: <see NOTE first>
+#
+#   NOTE: z/ -> y/ (in commit A)
+#         y/ -> x/ (in commit B)
+#         x/ -> w/ (in commit A)
+#         w/ -> v/ (in commit B)
+#         v/ -> u/ (in commit A)
+#         So, if we add a file to z, say z/t, where should it end up?  In u?
+#         What if there's another file or directory named 't' in one of the
+#         intervening directories and/or in u itself?  Also, shouldn't the
+#         same logic that places 't' in u/ also move ALL other files to u/?
+#         What if there are file or directory conflicts in any of them?  If
+#         we attempted to do N-way (N-fold? N-ary? N-uple?) transitive renames
+#         like this, would the user have any hope of understanding any
+#         conflicts or how their working tree ended up?  I think not, so I'm
+#         ruling out N-ary transitive renames for N>1.
+#
+#   Therefore our expected result is:
+#     z/t, y/a, x/b, w/c, u/d, u/e, u/f
+#   The reason that v/d DOES get transitively renamed to u/d is that u/ isn't
+#   renamed somewhere.  A slightly sub-optimal result, but it uses fairly
+#   simple rules that are consistent with what we need for all the other
+#   testcases and simplifies things for the user.
+
+test_expect_success '9d-setup: N-way transitive rename?' '
+       test_create_repo 9d &&
+       (
+               cd 9d &&
+
+               mkdir z y x w v u &&
+               echo a >z/a &&
+               echo b >y/b &&
+               echo c >x/c &&
+               echo d >w/d &&
+               echo e >v/e &&
+               echo f >u/f &&
+               git add z y x w v u &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z/a y/ &&
+               git mv x/c w/ &&
+               git mv v/e u/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo t >z/t &&
+               git mv y/b x/ &&
+               git mv w/d v/ &&
+               git add z/t &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '9d-check: N-way transitive rename?' '
+       (
+               cd 9d &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 >out &&
+               test_i18ngrep "WARNING: Avoiding applying z -> y rename to z/t" out &&
+               test_i18ngrep "WARNING: Avoiding applying y -> x rename to y/a" out &&
+               test_i18ngrep "WARNING: Avoiding applying x -> w rename to x/b" out &&
+               test_i18ngrep "WARNING: Avoiding applying w -> v rename to w/c" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 7 out &&
+               git ls-files -o >out &&
+               test_line_count = 1 out &&
+
+               git rev-parse >actual \
+                       HEAD:z/t \
+                       HEAD:y/a HEAD:x/b HEAD:w/c \
+                       HEAD:u/d HEAD:u/e HEAD:u/f &&
+               git rev-parse >expect \
+                       B:z/t    \
+                       O:z/a    O:y/b    O:x/c    \
+                       O:w/d    O:v/e    A:u/f &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 9e, N-to-1 whammo
+#   (Related to testcase 9c...and 1c and 7e)
+#   Commit O: dir1/{a,b}, dir2/{d,e}, dir3/{g,h}, dirN/{j,k}
+#   Commit A: dir1/{a,b,c,yo}, dir2/{d,e,f,yo}, dir3/{g,h,i,yo}, dirN/{j,k,l,yo}
+#   Commit B: combined/{a,b,d,e,g,h,j,k}
+#   Expected: combined/{a,b,c,d,e,f,g,h,i,j,k,l}, CONFLICT(Nto1) warnings,
+#             dir1/yo, dir2/yo, dir3/yo, dirN/yo
+
+test_expect_success '9e-setup: N-to-1 whammo' '
+       test_create_repo 9e &&
+       (
+               cd 9e &&
+
+               mkdir dir1 dir2 dir3 dirN &&
+               echo a >dir1/a &&
+               echo b >dir1/b &&
+               echo d >dir2/d &&
+               echo e >dir2/e &&
+               echo g >dir3/g &&
+               echo h >dir3/h &&
+               echo j >dirN/j &&
+               echo k >dirN/k &&
+               git add dir* &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               echo c  >dir1/c &&
+               echo yo >dir1/yo &&
+               echo f  >dir2/f &&
+               echo yo >dir2/yo &&
+               echo i  >dir3/i &&
+               echo yo >dir3/yo &&
+               echo l  >dirN/l &&
+               echo yo >dirN/yo &&
+               git add dir* &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv dir1 combined &&
+               git mv dir2/* combined/ &&
+               git mv dir3/* combined/ &&
+               git mv dirN/* combined/ &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success C_LOCALE_OUTPUT '9e-check: N-to-1 whammo' '
+       (
+               cd 9e &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 >out &&
+               grep "CONFLICT (implicit dir rename): Cannot map more than one path to combined/yo" out >error_line &&
+               grep -q dir1/yo error_line &&
+               grep -q dir2/yo error_line &&
+               grep -q dir3/yo error_line &&
+               grep -q dirN/yo error_line &&
+
+               git ls-files -s >out &&
+               test_line_count = 16 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 2 out &&
+
+               git rev-parse >actual \
+                       :0:combined/a :0:combined/b :0:combined/c \
+                       :0:combined/d :0:combined/e :0:combined/f \
+                       :0:combined/g :0:combined/h :0:combined/i \
+                       :0:combined/j :0:combined/k :0:combined/l &&
+               git rev-parse >expect \
+                        O:dir1/a      O:dir1/b      A:dir1/c \
+                        O:dir2/d      O:dir2/e      A:dir2/f \
+                        O:dir3/g      O:dir3/h      A:dir3/i \
+                        O:dirN/j      O:dirN/k      A:dirN/l &&
+               test_cmp expect actual &&
+
+               git rev-parse >actual \
+                       :0:dir1/yo :0:dir2/yo :0:dir3/yo :0:dirN/yo &&
+               git rev-parse >expect \
+                        A:dir1/yo  A:dir2/yo  A:dir3/yo  A:dirN/yo &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 9f, Renamed directory that only contained immediate subdirs
+#   (Related to testcases 1e & 9g)
+#   Commit O: goal/{a,b}/$more_files
+#   Commit A: priority/{a,b}/$more_files
+#   Commit B: goal/{a,b}/$more_files, goal/c
+#   Expected: priority/{a,b}/$more_files, priority/c
+
+test_expect_success '9f-setup: Renamed directory that only contained immediate subdirs' '
+       test_create_repo 9f &&
+       (
+               cd 9f &&
+
+               mkdir -p goal/a &&
+               mkdir -p goal/b &&
+               echo foo >goal/a/foo &&
+               echo bar >goal/b/bar &&
+               echo baz >goal/b/baz &&
+               git add goal &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv goal/ priority &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo c >goal/c &&
+               git add goal/c &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '9f-check: Renamed directory that only contained immediate subdirs' '
+       (
+               cd 9f &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 4 out &&
+
+               git rev-parse >actual \
+                       HEAD:priority/a/foo \
+                       HEAD:priority/b/bar \
+                       HEAD:priority/b/baz \
+                       HEAD:priority/c &&
+               git rev-parse >expect \
+                       O:goal/a/foo \
+                       O:goal/b/bar \
+                       O:goal/b/baz \
+                       B:goal/c &&
+               test_cmp expect actual &&
+               test_must_fail git rev-parse HEAD:goal/c
+       )
+'
+
+# Testcase 9g, Renamed directory that only contained immediate subdirs, immediate subdirs renamed
+#   (Related to testcases 1e & 9f)
+#   Commit O: goal/{a,b}/$more_files
+#   Commit A: priority/{alpha,bravo}/$more_files
+#   Commit B: goal/{a,b}/$more_files, goal/c
+#   Expected: priority/{alpha,bravo}/$more_files, priority/c
+
+test_expect_success '9g-setup: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' '
+       test_create_repo 9g &&
+       (
+               cd 9g &&
+
+               mkdir -p goal/a &&
+               mkdir -p goal/b &&
+               echo foo >goal/a/foo &&
+               echo bar >goal/b/bar &&
+               echo baz >goal/b/baz &&
+               git add goal &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               mkdir priority &&
+               git mv goal/a/ priority/alpha &&
+               git mv goal/b/ priority/beta &&
+               rmdir goal/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo c >goal/c &&
+               git add goal/c &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_failure '9g-check: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' '
+       (
+               cd 9g &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 4 out &&
+
+               git rev-parse >actual \
+                       HEAD:priority/alpha/foo \
+                       HEAD:priority/beta/bar  \
+                       HEAD:priority/beta/baz  \
+                       HEAD:priority/c &&
+               git rev-parse >expect \
+                       O:goal/a/foo \
+                       O:goal/b/bar \
+                       O:goal/b/baz \
+                       B:goal/c &&
+               test_cmp expect actual &&
+               test_must_fail git rev-parse HEAD:goal/c
+       )
+'
+
+# Testcase 9h, Avoid implicit rename if involved as source on other side
+#   (Extremely closely related to testcase 3a)
+#   Commit O: z/{b,c,d_1}
+#   Commit A: z/{b,c,d_2}
+#   Commit B: y/{b,c}, x/d_1
+#   Expected: y/{b,c}, x/d_2
+#   NOTE: If we applied the z/ -> y/ rename to z/d, then we'd end up with
+#         a rename/rename(1to2) conflict (z/d -> y/d vs. x/d)
+test_expect_success '9h-setup: Avoid dir rename on merely modified path' '
+       test_create_repo 9h &&
+       (
+               cd 9h &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               printf "1\n2\n3\n4\n5\n6\n7\n8\nd\n" >z/d &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_tick &&
+               echo more >>z/d &&
+               git add z/d &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               mkdir y &&
+               mkdir x &&
+               git mv z/b y/ &&
+               git mv z/c y/ &&
+               git mv z/d x/ &&
+               rmdir z &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '9h-check: Avoid dir rename on merely modified path' '
+       (
+               cd 9h &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+
+               git rev-parse >actual \
+                       HEAD:y/b HEAD:y/c HEAD:x/d &&
+               git rev-parse >expect \
+                       O:z/b    O:z/c    A:z/d &&
+               test_cmp expect actual
+       )
+'
+
+###########################################################################
+# Rules suggested by section 9:
+#
+#   If the other side of history did a directory rename to a path that your
+#   side renamed away, then ignore that particular rename from the other
+#   side of history for any implicit directory renames.
+###########################################################################
+
+###########################################################################
+# SECTION 10: Handling untracked files
+#
+# unpack_trees(), upon which the recursive merge algorithm is based, aborts
+# the operation if untracked or dirty files would be deleted or overwritten
+# by the merge.  Unfortunately, unpack_trees() does not understand renames,
+# and if it doesn't abort, then it muddies up the working directory before
+# we even get to the point of detecting renames, so we need some special
+# handling, at least in the case of directory renames.
+###########################################################################
+
+# Testcase 10a, Overwrite untracked: normal rename/delete
+#   Commit O: z/{b,c_1}
+#   Commit A: z/b + untracked z/c + untracked z/d
+#   Commit B: z/{b,d_1}
+#   Expected: Aborted Merge +
+#       ERROR_MSG(untracked working tree files would be overwritten by merge)
+
+test_expect_success '10a-setup: Overwrite untracked with normal rename/delete' '
+       test_create_repo 10a &&
+       (
+               cd 10a &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git rm z/c &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv z/c z/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '10a-check: Overwrite untracked with normal rename/delete' '
+       (
+               cd 10a &&
+
+               git checkout A^0 &&
+               echo very >z/c &&
+               echo important >z/d &&
+
+               test_must_fail git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep "The following untracked working tree files would be overwritten by merge" err &&
+
+               git ls-files -s >out &&
+               test_line_count = 1 out &&
+               git ls-files -o >out &&
+               test_line_count = 4 out &&
+
+               echo very >expect &&
+               test_cmp expect z/c &&
+
+               echo important >expect &&
+               test_cmp expect z/d &&
+
+               git rev-parse HEAD:z/b >actual &&
+               git rev-parse O:z/b >expect &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 10b, Overwrite untracked: dir rename + delete
+#   Commit O: z/{b,c_1}
+#   Commit A: y/b + untracked y/{c,d,e}
+#   Commit B: z/{b,d_1,e}
+#   Expected: Failed Merge; y/b + untracked y/c + untracked y/d on disk +
+#             z/c_1 -> z/d_1 rename recorded at stage 3 for y/d +
+#       ERROR_MSG(refusing to lose untracked file at 'y/d')
+
+test_expect_success '10b-setup: Overwrite untracked with dir rename + delete' '
+       test_create_repo 10b &&
+       (
+               cd 10b &&
+
+               mkdir z &&
+               echo b >z/b &&
+               echo c >z/c &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git rm z/c &&
+               git mv z/ y/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv z/c z/d &&
+               echo e >z/e &&
+               git add z/e &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '10b-check: Overwrite untracked with dir rename + delete' '
+       (
+               cd 10b &&
+
+               git checkout A^0 &&
+               echo very >y/c &&
+               echo important >y/d &&
+               echo contents >y/e &&
+
+               test_must_fail git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep "CONFLICT (rename/delete).*Version B\^0 of y/d left in tree at y/d~B\^0" out &&
+               test_i18ngrep "Error: Refusing to lose untracked file at y/e; writing to y/e~B\^0 instead" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+               git ls-files -u >out &&
+               test_line_count = 2 out &&
+               git ls-files -o >out &&
+               test_line_count = 5 out &&
+
+               git rev-parse >actual \
+                       :0:y/b :3:y/d :3:y/e &&
+               git rev-parse >expect \
+                       O:z/b  O:z/c  B:z/e &&
+               test_cmp expect actual &&
+
+               echo very >expect &&
+               test_cmp expect y/c &&
+
+               echo important >expect &&
+               test_cmp expect y/d &&
+
+               echo contents >expect &&
+               test_cmp expect y/e
+       )
+'
+
+# Testcase 10c, Overwrite untracked: dir rename/rename(1to2)
+#   Commit O: z/{a,b}, x/{c,d}
+#   Commit A: y/{a,b}, w/c, x/d + different untracked y/c
+#   Commit B: z/{a,b,c}, x/d
+#   Expected: Failed Merge; y/{a,b} + x/d + untracked y/c +
+#             CONFLICT(rename/rename) x/c -> w/c vs y/c +
+#             y/c~B^0 +
+#             ERROR_MSG(Refusing to lose untracked file at y/c)
+
+test_expect_success '10c-setup: Overwrite untracked with dir rename/rename(1to2)' '
+       test_create_repo 10c &&
+       (
+               cd 10c &&
+
+               mkdir z x &&
+               echo a >z/a &&
+               echo b >z/b &&
+               echo c >x/c &&
+               echo d >x/d &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               mkdir w &&
+               git mv x/c w/c &&
+               git mv z/ y/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/c z/ &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)' '
+       (
+               cd 10c &&
+
+               git checkout A^0 &&
+               echo important >y/c &&
+
+               test_must_fail git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep "CONFLICT (rename/rename)" out &&
+               test_i18ngrep "Refusing to lose untracked file at y/c; adding as y/c~B\^0 instead" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 6 out &&
+               git ls-files -u >out &&
+               test_line_count = 3 out &&
+               git ls-files -o >out &&
+               test_line_count = 3 out &&
+
+               git rev-parse >actual \
+                       :0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :3:y/c &&
+               git rev-parse >expect \
+                        O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  O:x/c &&
+               test_cmp expect actual &&
+
+               git hash-object y/c~B^0 >actual &&
+               git rev-parse O:x/c >expect &&
+               test_cmp expect actual &&
+
+               echo important >expect &&
+               test_cmp expect y/c
+       )
+'
+
+# Testcase 10d, Delete untracked w/ dir rename/rename(2to1)
+#   Commit O: z/{a,b,c_1},        x/{d,e,f_2}
+#   Commit A: y/{a,b},            x/{d,e,f_2,wham_1} + untracked y/wham
+#   Commit B: z/{a,b,c_1,wham_2}, y/{d,e}
+#   Expected: Failed Merge; y/{a,b,d,e} + untracked y/{wham,wham~B^0,wham~HEAD}+
+#             CONFLICT(rename/rename) z/c_1 vs x/f_2 -> y/wham
+#             ERROR_MSG(Refusing to lose untracked file at y/wham)
+
+test_expect_success '10d-setup: Delete untracked with dir rename/rename(2to1)' '
+       test_create_repo 10d &&
+       (
+               cd 10d &&
+
+               mkdir z x &&
+               echo a >z/a &&
+               echo b >z/b &&
+               echo c >z/c &&
+               echo d >x/d &&
+               echo e >x/e &&
+               echo f >x/f &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z/c x/wham &&
+               git mv z/ y/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/f z/wham &&
+               git mv x/ y/ &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
+       (
+               cd 10d &&
+
+               git checkout A^0 &&
+               echo important >y/wham &&
+
+               test_must_fail git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep "CONFLICT (rename/rename)" out &&
+               test_i18ngrep "Refusing to lose untracked file at y/wham" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 6 out &&
+               git ls-files -u >out &&
+               test_line_count = 2 out &&
+               git ls-files -o >out &&
+               test_line_count = 4 out &&
+
+               git rev-parse >actual \
+                       :0:y/a :0:y/b :0:y/d :0:y/e :2:y/wham :3:y/wham &&
+               git rev-parse >expect \
+                        O:z/a  O:z/b  O:x/d  O:x/e  O:z/c     O:x/f &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse :1:y/wham &&
+
+               echo important >expect &&
+               test_cmp expect y/wham &&
+
+               git hash-object >actual \
+                       y/wham~B^0 y/wham~HEAD &&
+               git rev-parse >expect \
+                       O:x/f      O:z/c &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 10e, Does git complain about untracked file that's not in the way?
+#   Commit O: z/{a,b}
+#   Commit A: y/{a,b} + untracked z/c
+#   Commit B: z/{a,b,c}
+#   Expected: y/{a,b,c} + untracked z/c
+
+test_expect_success '10e-setup: Does git complain about untracked file that is not really in the way?' '
+       test_create_repo 10e &&
+       (
+               cd 10e &&
+
+               mkdir z &&
+               echo a >z/a &&
+               echo b >z/b &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z/ y/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo c >z/c &&
+               git add z/c &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_failure '10e-check: Does git complain about untracked file that is not really in the way?' '
+       (
+               cd 10e &&
+
+               git checkout A^0 &&
+               mkdir z &&
+               echo random >z/c &&
+
+               git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep ! "following untracked working tree files would be overwritten by merge" err &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 3 out &&
+
+               git rev-parse >actual \
+                       :0:y/a :0:y/b :0:y/c &&
+               git rev-parse >expect \
+                        O:z/a  O:z/b  B:z/c &&
+               test_cmp expect actual &&
+
+               echo random >expect &&
+               test_cmp expect z/c
+       )
+'
+
+###########################################################################
+# SECTION 11: Handling dirty (not up-to-date) files
+#
+# unpack_trees(), upon which the recursive merge algorithm is based, aborts
+# the operation if untracked or dirty files would be deleted or overwritten
+# by the merge.  Unfortunately, unpack_trees() does not understand renames,
+# and if it doesn't abort, then it muddies up the working directory before
+# we even get to the point of detecting renames, so we need some special
+# handling.  This was true even of normal renames, but there are additional
+# codepaths that need special handling with directory renames.  Add
+# testcases for both renamed-by-directory-rename-detection and standard
+# rename cases.
+###########################################################################
+
+# Testcase 11a, Avoid losing dirty contents with simple rename
+#   Commit O: z/{a,b_v1},
+#   Commit A: z/{a,c_v1}, and z/c_v1 has uncommitted mods
+#   Commit B: z/{a,b_v2}
+#   Expected: ERROR_MSG(Refusing to lose dirty file at z/c) +
+#             z/a, staged version of z/c has sha1sum matching B:z/b_v2,
+#             z/c~HEAD with contents of B:z/b_v2,
+#             z/c with uncommitted mods on top of A:z/c_v1
+
+test_expect_success '11a-setup: Avoid losing dirty contents with simple rename' '
+       test_create_repo 11a &&
+       (
+               cd 11a &&
+
+               mkdir z &&
+               echo a >z/a &&
+               test_seq 1 10 >z/b &&
+               git add z &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z/b z/c &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo 11 >>z/b &&
+               git add z/b &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '11a-check: Avoid losing dirty contents with simple rename' '
+       (
+               cd 11a &&
+
+               git checkout A^0 &&
+               echo stuff >>z/c &&
+
+               test_must_fail git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep "Refusing to lose dirty file at z/c" out &&
+
+               test_seq 1 10 >expected &&
+               echo stuff >>expected &&
+               test_cmp expected z/c &&
+
+               git ls-files -s >out &&
+               test_line_count = 2 out &&
+               git ls-files -u >out &&
+               test_line_count = 1 out &&
+               git ls-files -o >out &&
+               test_line_count = 4 out &&
+
+               git rev-parse >actual \
+                       :0:z/a :2:z/c &&
+               git rev-parse >expect \
+                        O:z/a  B:z/b &&
+               test_cmp expect actual &&
+
+               git hash-object z/c~HEAD >actual &&
+               git rev-parse B:z/b >expect &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 11b, Avoid losing dirty file involved in directory rename
+#   Commit O: z/a,         x/{b,c_v1}
+#   Commit A: z/{a,c_v1},  x/b,       and z/c_v1 has uncommitted mods
+#   Commit B: y/a,         x/{b,c_v2}
+#   Expected: y/{a,c_v2}, x/b, z/c_v1 with uncommitted mods untracked,
+#             ERROR_MSG(Refusing to lose dirty file at z/c)
+
+
+test_expect_success '11b-setup: Avoid losing dirty file involved in directory rename' '
+       test_create_repo 11b &&
+       (
+               cd 11b &&
+
+               mkdir z x &&
+               echo a >z/a &&
+               echo b >x/b &&
+               test_seq 1 10 >x/c &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv x/c z/c &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv z y &&
+               echo 11 >>x/c &&
+               git add x/c &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '11b-check: Avoid losing dirty file involved in directory rename' '
+       (
+               cd 11b &&
+
+               git checkout A^0 &&
+               echo stuff >>z/c &&
+
+               git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep "Refusing to lose dirty file at z/c" out &&
+
+               grep -q stuff z/c &&
+               test_seq 1 10 >expected &&
+               echo stuff >>expected &&
+               test_cmp expected z/c &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -m >out &&
+               test_line_count = 0 out &&
+               git ls-files -o >out &&
+               test_line_count = 4 out &&
+
+               git rev-parse >actual \
+                       :0:x/b :0:y/a :0:y/c &&
+               git rev-parse >expect \
+                        O:x/b  O:z/a  B:x/c &&
+               test_cmp expect actual &&
+
+               git hash-object y/c >actual &&
+               git rev-parse B:x/c >expect &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 11c, Avoid losing not-up-to-date with rename + D/F conflict
+#   Commit O: y/a,         x/{b,c_v1}
+#   Commit A: y/{a,c_v1},  x/b,       and y/c_v1 has uncommitted mods
+#   Commit B: y/{a,c/d},   x/{b,c_v2}
+#   Expected: Abort_msg("following files would be overwritten by merge") +
+#             y/c left untouched (still has uncommitted mods)
+
+test_expect_success '11c-setup: Avoid losing not-uptodate with rename + D/F conflict' '
+       test_create_repo 11c &&
+       (
+               cd 11c &&
+
+               mkdir y x &&
+               echo a >y/a &&
+               echo b >x/b &&
+               test_seq 1 10 >x/c &&
+               git add y x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv x/c y/c &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               mkdir y/c &&
+               echo d >y/c/d &&
+               echo 11 >>x/c &&
+               git add x/c y/c/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '11c-check: Avoid losing not-uptodate with rename + D/F conflict' '
+       (
+               cd 11c &&
+
+               git checkout A^0 &&
+               echo stuff >>y/c &&
+
+               test_must_fail git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep "following files would be overwritten by merge" err &&
+
+               grep -q stuff y/c &&
+               test_seq 1 10 >expected &&
+               echo stuff >>expected &&
+               test_cmp expected y/c &&
+
+               git ls-files -s >out &&
+               test_line_count = 3 out &&
+               git ls-files -u >out &&
+               test_line_count = 0 out &&
+               git ls-files -m >out &&
+               test_line_count = 1 out &&
+               git ls-files -o >out &&
+               test_line_count = 3 out
+       )
+'
+
+# Testcase 11d, Avoid losing not-up-to-date with rename + D/F conflict
+#   Commit O: z/a,         x/{b,c_v1}
+#   Commit A: z/{a,c_v1},  x/b,       and z/c_v1 has uncommitted mods
+#   Commit B: y/{a,c/d},   x/{b,c_v2}
+#   Expected: D/F: y/c_v2 vs y/c/d) +
+#             Warning_Msg("Refusing to lose dirty file at z/c) +
+#             y/{a,c~HEAD,c/d}, x/b, now-untracked z/c_v1 with uncommitted mods
+
+test_expect_success '11d-setup: Avoid losing not-uptodate with rename + D/F conflict' '
+       test_create_repo 11d &&
+       (
+               cd 11d &&
+
+               mkdir z x &&
+               echo a >z/a &&
+               echo b >x/b &&
+               test_seq 1 10 >x/c &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv x/c z/c &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv z y &&
+               mkdir y/c &&
+               echo d >y/c/d &&
+               echo 11 >>x/c &&
+               git add x/c y/c/d &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '11d-check: Avoid losing not-uptodate with rename + D/F conflict' '
+       (
+               cd 11d &&
+
+               git checkout A^0 &&
+               echo stuff >>z/c &&
+
+               test_must_fail git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep "Refusing to lose dirty file at z/c" out &&
+
+               grep -q stuff z/c &&
+               test_seq 1 10 >expected &&
+               echo stuff >>expected &&
+               test_cmp expected z/c
+
+               git ls-files -s >out &&
+               test_line_count = 4 out &&
+               git ls-files -u >out &&
+               test_line_count = 1 out &&
+               git ls-files -o >out &&
+               test_line_count = 5 out &&
+
+               git rev-parse >actual \
+                       :0:x/b :0:y/a :0:y/c/d :3:y/c &&
+               git rev-parse >expect \
+                        O:x/b  O:z/a  B:y/c/d  B:x/c &&
+               test_cmp expect actual &&
+
+               git hash-object y/c~HEAD >actual &&
+               git rev-parse B:x/c >expect &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 11e, Avoid deleting not-up-to-date with dir rename/rename(1to2)/add
+#   Commit O: z/{a,b},      x/{c_1,d}
+#   Commit A: y/{a,b,c_2},  x/d, w/c_1, and y/c_2 has uncommitted mods
+#   Commit B: z/{a,b,c_1},  x/d
+#   Expected: Failed Merge; y/{a,b} + x/d +
+#             CONFLICT(rename/rename) x/c_1 -> w/c_1 vs y/c_1 +
+#             ERROR_MSG(Refusing to lose dirty file at y/c)
+#             y/c~B^0 has O:x/c_1 contents
+#             y/c~HEAD has A:y/c_2 contents
+#             y/c has dirty file from before merge
+
+test_expect_success '11e-setup: Avoid deleting not-uptodate with dir rename/rename(1to2)/add' '
+       test_create_repo 11e &&
+       (
+               cd 11e &&
+
+               mkdir z x &&
+               echo a >z/a &&
+               echo b >z/b &&
+               echo c >x/c &&
+               echo d >x/d &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z/ y/ &&
+               echo different >y/c &&
+               mkdir w &&
+               git mv x/c w/ &&
+               git add y/c &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/c z/ &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rename(1to2)/add' '
+       (
+               cd 11e &&
+
+               git checkout A^0 &&
+               echo mods >>y/c &&
+
+               test_must_fail git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep "CONFLICT (rename/rename)" out &&
+               test_i18ngrep "Refusing to lose dirty file at y/c" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 7 out &&
+               git ls-files -u >out &&
+               test_line_count = 4 out &&
+               git ls-files -o >out &&
+               test_line_count = 4 out &&
+
+               echo different >expected &&
+               echo mods >>expected &&
+               test_cmp expected y/c &&
+
+               git rev-parse >actual \
+                       :0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :2:y/c :3:y/c &&
+               git rev-parse >expect \
+                        O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  A:y/c  O:x/c &&
+               test_cmp expect actual &&
+
+               git hash-object >actual \
+                       y/c~B^0 y/c~HEAD &&
+               git rev-parse >expect \
+                       O:x/c   A:y/c &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 11f, Avoid deleting not-up-to-date w/ dir rename/rename(2to1)
+#   Commit O: z/{a,b},        x/{c_1,d_2}
+#   Commit A: y/{a,b,wham_1}, x/d_2, except y/wham has uncommitted mods
+#   Commit B: z/{a,b,wham_2}, x/c_1
+#   Expected: Failed Merge; y/{a,b} + untracked y/{wham~B^0,wham~B^HEAD} +
+#             y/wham with dirty changes from before merge +
+#             CONFLICT(rename/rename) x/c vs x/d -> y/wham
+#             ERROR_MSG(Refusing to lose dirty file at y/wham)
+
+test_expect_success '11f-setup: Avoid deleting not-uptodate with dir rename/rename(2to1)' '
+       test_create_repo 11f &&
+       (
+               cd 11f &&
+
+               mkdir z x &&
+               echo a >z/a &&
+               echo b >z/b &&
+               test_seq 1 10 >x/c &&
+               echo d >x/d &&
+               git add z x &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv z/ y/ &&
+               git mv x/c y/wham &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv x/d z/wham &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rename(2to1)' '
+       (
+               cd 11f &&
+
+               git checkout A^0 &&
+               echo important >>y/wham &&
+
+               test_must_fail git merge -s recursive B^0 >out 2>err &&
+               test_i18ngrep "CONFLICT (rename/rename)" out &&
+               test_i18ngrep "Refusing to lose dirty file at y/wham" out &&
+
+               git ls-files -s >out &&
+               test_line_count = 4 out &&
+               git ls-files -u >out &&
+               test_line_count = 2 out &&
+               git ls-files -o >out &&
+               test_line_count = 4 out &&
+
+               test_seq 1 10 >expected &&
+               echo important >>expected &&
+               test_cmp expected y/wham &&
+
+               test_must_fail git rev-parse :1:y/wham &&
+               git hash-object >actual \
+                       y/wham~B^0 y/wham~HEAD &&
+               git rev-parse >expect \
+                       O:x/d      O:x/c &&
+               test_cmp expect actual &&
+
+               git rev-parse >actual \
+                       :0:y/a :0:y/b :2:y/wham :3:y/wham &&
+               git rev-parse >expect \
+                        O:z/a  O:z/b  O:x/c     O:x/d &&
+               test_cmp expect actual
+       )
+'
+
+###########################################################################
+# SECTION 12: Everything else
+#
+# Tests suggested by others.  Tests added after implementation completed
+# and submitted.  Grab bag.
+###########################################################################
+
+# Testcase 12a, Moving one directory hierarchy into another
+#   (Related to testcase 9a)
+#   Commit O: node1/{leaf1,leaf2}, node2/{leaf3,leaf4}
+#   Commit A: node1/{leaf1,leaf2,node2/{leaf3,leaf4}}
+#   Commit B: node1/{leaf1,leaf2,leaf5}, node2/{leaf3,leaf4,leaf6}
+#   Expected: node1/{leaf1,leaf2,leaf5,node2/{leaf3,leaf4,leaf6}}
+
+test_expect_success '12a-setup: Moving one directory hierarchy into another' '
+       test_create_repo 12a &&
+       (
+               cd 12a &&
+
+               mkdir -p node1 node2 &&
+               echo leaf1 >node1/leaf1 &&
+               echo leaf2 >node1/leaf2 &&
+               echo leaf3 >node2/leaf3 &&
+               echo leaf4 >node2/leaf4 &&
+               git add node1 node2 &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv node2/ node1/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               echo leaf5 >node1/leaf5 &&
+               echo leaf6 >node2/leaf6 &&
+               git add node1 node2 &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '12a-check: Moving one directory hierarchy into another' '
+       (
+               cd 12a &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 6 out &&
+
+               git rev-parse >actual \
+                       HEAD:node1/leaf1 HEAD:node1/leaf2 HEAD:node1/leaf5 \
+                       HEAD:node1/node2/leaf3 \
+                       HEAD:node1/node2/leaf4 \
+                       HEAD:node1/node2/leaf6 &&
+               git rev-parse >expect \
+                       O:node1/leaf1    O:node1/leaf2    B:node1/leaf5 \
+                       O:node2/leaf3 \
+                       O:node2/leaf4 \
+                       B:node2/leaf6 &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 12b, Moving two directory hierarchies into each other
+#   (Related to testcases 1c and 12c)
+#   Commit O: node1/{leaf1, leaf2}, node2/{leaf3, leaf4}
+#   Commit A: node1/{leaf1, leaf2, node2/{leaf3, leaf4}}
+#   Commit B: node2/{leaf3, leaf4, node1/{leaf1, leaf2}}
+#   Expected: node1/node2/node1/{leaf1, leaf2},
+#             node2/node1/node2/{leaf3, leaf4}
+#   NOTE: Without directory renames, we would expect
+#                   node2/node1/{leaf1, leaf2},
+#                   node1/node2/{leaf3, leaf4}
+#         with directory rename detection, we note that
+#             commit A renames node2/ -> node1/node2/
+#             commit B renames node1/ -> node2/node1/
+#         therefore, applying those directory renames to the initial result
+#         (making all four paths experience a transitive renaming), yields
+#         the expected result.
+#
+#         You may ask, is it weird to have two directories rename each other?
+#         To which, I can do no more than shrug my shoulders and say that
+#         even simple rules give weird results when given weird inputs.
+
+test_expect_success '12b-setup: Moving one directory hierarchy into another' '
+       test_create_repo 12b &&
+       (
+               cd 12b &&
+
+               mkdir -p node1 node2 &&
+               echo leaf1 >node1/leaf1 &&
+               echo leaf2 >node1/leaf2 &&
+               echo leaf3 >node2/leaf3 &&
+               echo leaf4 >node2/leaf4 &&
+               git add node1 node2 &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv node2/ node1/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv node1/ node2/ &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '12b-check: Moving one directory hierarchy into another' '
+       (
+               cd 12b &&
+
+               git checkout A^0 &&
+
+               git merge -s recursive B^0 &&
+
+               git ls-files -s >out &&
+               test_line_count = 4 out &&
+
+               git rev-parse >actual \
+                       HEAD:node1/node2/node1/leaf1 \
+                       HEAD:node1/node2/node1/leaf2 \
+                       HEAD:node2/node1/node2/leaf3 \
+                       HEAD:node2/node1/node2/leaf4 &&
+               git rev-parse >expect \
+                       O:node1/leaf1 \
+                       O:node1/leaf2 \
+                       O:node2/leaf3 \
+                       O:node2/leaf4 &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 12c, Moving two directory hierarchies into each other w/ content merge
+#   (Related to testcase 12b)
+#   Commit O: node1/{       leaf1_1, leaf2_1}, node2/{leaf3_1, leaf4_1}
+#   Commit A: node1/{       leaf1_2, leaf2_2,  node2/{leaf3_2, leaf4_2}}
+#   Commit B: node2/{node1/{leaf1_3, leaf2_3},        leaf3_3, leaf4_3}
+#   Expected: Content merge conflicts for each of:
+#               node1/node2/node1/{leaf1, leaf2},
+#               node2/node1/node2/{leaf3, leaf4}
+#   NOTE: This is *exactly* like 12c, except that every path is modified on
+#         each side of the merge.
+
+test_expect_success '12c-setup: Moving one directory hierarchy into another w/ content merge' '
+       test_create_repo 12c &&
+       (
+               cd 12c &&
+
+               mkdir -p node1 node2 &&
+               printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf1\n" >node1/leaf1 &&
+               printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf2\n" >node1/leaf2 &&
+               printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf3\n" >node2/leaf3 &&
+               printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf4\n" >node2/leaf4 &&
+               git add node1 node2 &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv node2/ node1/ &&
+               for i in `git ls-files`; do echo side A >>$i; done &&
+               git add -u &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv node1/ node2/ &&
+               for i in `git ls-files`; do echo side B >>$i; done &&
+               git add -u &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '12c-check: Moving one directory hierarchy into another w/ content merge' '
+       (
+               cd 12c &&
+
+               git checkout A^0 &&
+
+               test_must_fail git merge -s recursive B^0 &&
+
+               git ls-files -u >out &&
+               test_line_count = 12 out &&
+
+               git rev-parse >actual \
+                       :1:node1/node2/node1/leaf1 \
+                       :1:node1/node2/node1/leaf2 \
+                       :1:node2/node1/node2/leaf3 \
+                       :1:node2/node1/node2/leaf4 \
+                       :2:node1/node2/node1/leaf1 \
+                       :2:node1/node2/node1/leaf2 \
+                       :2:node2/node1/node2/leaf3 \
+                       :2:node2/node1/node2/leaf4 \
+                       :3:node1/node2/node1/leaf1 \
+                       :3:node1/node2/node1/leaf2 \
+                       :3:node2/node1/node2/leaf3 \
+                       :3:node2/node1/node2/leaf4 &&
+               git rev-parse >expect \
+                       O:node1/leaf1 \
+                       O:node1/leaf2 \
+                       O:node2/leaf3 \
+                       O:node2/leaf4 \
+                       A:node1/leaf1 \
+                       A:node1/leaf2 \
+                       A:node1/node2/leaf3 \
+                       A:node1/node2/leaf4 \
+                       B:node2/node1/leaf1 \
+                       B:node2/node1/leaf2 \
+                       B:node2/leaf3 \
+                       B:node2/leaf4 &&
+               test_cmp expect actual
+       )
+'
+
+test_done
diff --git a/t/t6046-merge-skip-unneeded-updates.sh b/t/t6046-merge-skip-unneeded-updates.sh
new file mode 100755 (executable)
index 0000000..fcefffc
--- /dev/null
@@ -0,0 +1,761 @@
+#!/bin/sh
+
+test_description="merge cases"
+
+# The setup for all of them, pictorially, is:
+#
+#      A
+#      o
+#     / \
+#  O o   ?
+#     \ /
+#      o
+#      B
+#
+# To help make it easier to follow the flow of tests, they have been
+# divided into sections and each test will start with a quick explanation
+# of what commits O, A, and B contain.
+#
+# Notation:
+#    z/{b,c}   means  files z/b and z/c both exist
+#    x/d_1     means  file x/d exists with content d1.  (Purpose of the
+#                     underscore notation is to differentiate different
+#                     files that might be renamed into each other's paths.)
+
+. ./test-lib.sh
+
+
+###########################################################################
+# SECTION 1: Cases involving no renames (one side has subset of changes of
+#            the other side)
+###########################################################################
+
+# Testcase 1a, Changes on A, subset of changes on B
+#   Commit O: b_1
+#   Commit A: b_2
+#   Commit B: b_3
+#   Expected: b_2
+
+test_expect_success '1a-setup: Modify(A)/Modify(B), change on B subset of A' '
+       test_create_repo 1a &&
+       (
+               cd 1a &&
+
+               test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '1a-check-L: Modify(A)/Modify(B), change on B subset of A' '
+       test_when_finished "git -C 1a reset --hard" &&
+       test_when_finished "git -C 1a clean -fd" &&
+       (
+               cd 1a &&
+
+               git checkout A^0 &&
+
+               test-tool chmtime =31337 b &&
+               test-tool chmtime -v +0 b >expected-mtime &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
+
+               test_i18ngrep "Skipped b" out &&
+               test_must_be_empty err &&
+
+               test-tool chmtime -v +0 b >actual-mtime &&
+               test_cmp expected-mtime actual-mtime &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 1 index_files &&
+
+               git rev-parse >actual HEAD:b &&
+               git rev-parse >expect A:b &&
+               test_cmp expect actual &&
+
+               git hash-object b   >actual &&
+               git rev-parse   A:b >expect &&
+               test_cmp expect actual
+       )
+'
+
+test_expect_success '1a-check-R: Modify(A)/Modify(B), change on B subset of A' '
+       test_when_finished "git -C 1a reset --hard" &&
+       test_when_finished "git -C 1a clean -fd" &&
+       (
+               cd 1a &&
+
+               git checkout B^0 &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
+
+               test_i18ngrep "Auto-merging b" out &&
+               test_must_be_empty err &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 1 index_files &&
+
+               git rev-parse >actual HEAD:b &&
+               git rev-parse >expect A:b &&
+               test_cmp expect actual &&
+
+               git hash-object b   >actual &&
+               git rev-parse   A:b >expect &&
+               test_cmp expect actual
+       )
+'
+
+
+###########################################################################
+# SECTION 2: Cases involving basic renames
+###########################################################################
+
+# Testcase 2a, Changes on A, rename on B
+#   Commit O: b_1
+#   Commit A: b_2
+#   Commit B: c_1
+#   Expected: c_2
+
+test_expect_success '2a-setup: Modify(A)/rename(B)' '
+       test_create_repo 2a &&
+       (
+               cd 2a &&
+
+               test_seq 1 10 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_seq 1 11 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv b c &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '2a-check-L: Modify/rename, merge into modify side' '
+       test_when_finished "git -C 2a reset --hard" &&
+       test_when_finished "git -C 2a clean -fd" &&
+       (
+               cd 2a &&
+
+               git checkout A^0 &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
+
+               test_i18ngrep ! "Skipped c" out &&
+               test_must_be_empty err &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 1 index_files &&
+
+               git rev-parse >actual HEAD:c &&
+               git rev-parse >expect A:b &&
+               test_cmp expect actual &&
+
+               git hash-object c   >actual &&
+               git rev-parse   A:b >expect &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse HEAD:b &&
+               test_path_is_missing b
+       )
+'
+
+test_expect_success '2a-check-R: Modify/rename, merge into rename side' '
+       test_when_finished "git -C 2a reset --hard" &&
+       test_when_finished "git -C 2a clean -fd" &&
+       (
+               cd 2a &&
+
+               git checkout B^0 &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
+
+               test_i18ngrep ! "Skipped c" out &&
+               test_must_be_empty err &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 1 index_files &&
+
+               git rev-parse >actual HEAD:c &&
+               git rev-parse >expect A:b &&
+               test_cmp expect actual &&
+
+               git hash-object c   >actual &&
+               git rev-parse   A:b >expect &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse HEAD:b &&
+               test_path_is_missing b
+       )
+'
+
+# Testcase 2b, Changed and renamed on A, subset of changes on B
+#   Commit O: b_1
+#   Commit A: c_2
+#   Commit B: b_3
+#   Expected: c_2
+
+test_expect_success '2b-setup: Rename+Mod(A)/Mod(B), B mods subset of A' '
+       test_create_repo 2b &&
+       (
+               cd 2b &&
+
+               test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
+               git add b &&
+               git mv b c &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '2b-check-L: Rename+Mod(A)/Mod(B), B mods subset of A' '
+       test_when_finished "git -C 2b reset --hard" &&
+       test_when_finished "git -C 2b clean -fd" &&
+       (
+               cd 2b &&
+
+               git checkout A^0 &&
+
+               test-tool chmtime =31337 c &&
+               test-tool chmtime -v +0 c >expected-mtime &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
+
+               test_i18ngrep "Skipped c" out &&
+               test_must_be_empty err &&
+
+               test-tool chmtime -v +0 c >actual-mtime &&
+               test_cmp expected-mtime actual-mtime &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 1 index_files &&
+
+               git rev-parse >actual HEAD:c &&
+               git rev-parse >expect A:c &&
+               test_cmp expect actual &&
+
+               git hash-object c   >actual &&
+               git rev-parse   A:c >expect &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse HEAD:b &&
+               test_path_is_missing b
+       )
+'
+
+test_expect_success '2b-check-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
+       test_when_finished "git -C 2b reset --hard" &&
+       test_when_finished "git -C 2b clean -fd" &&
+       (
+               cd 2b &&
+
+               git checkout B^0 &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
+
+               test_i18ngrep "Auto-merging c" out &&
+               test_must_be_empty err &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 1 index_files &&
+
+               git rev-parse >actual HEAD:c &&
+               git rev-parse >expect A:c &&
+               test_cmp expect actual &&
+
+               git hash-object c   >actual &&
+               git rev-parse   A:c >expect &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse HEAD:b &&
+               test_path_is_missing b
+       )
+'
+
+# Testcase 2c, Changes on A, rename on B
+#   Commit O: b_1
+#   Commit A: b_2, c_3
+#   Commit B: c_1
+#   Expected: rename/add conflict c_2 vs c_3
+#
+#   NOTE: Since A modified b_1->b_2, and B renamed b_1->c_1, the threeway
+#         merge of those files should result in c_2.  We then should have a
+#         rename/add conflict between c_2 and c_3.  However, if we note in
+#         merge_content() that A had the right contents (b_2 has same
+#         contents as c_2, just at a different name), and that A had the
+#         right path present (c_3 existed) and thus decides that it can
+#         skip the update, then we're in trouble.  This test verifies we do
+#         not make that particular mistake.
+
+test_expect_success '2c-setup: Modify b & add c VS rename b->c' '
+       test_create_repo 2c &&
+       (
+               cd 2c &&
+
+               test_seq 1 10 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_seq 1 11 >b &&
+               echo whatever >c &&
+               git add b c &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv b c &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '2c-check: Modify b & add c VS rename b->c' '
+       (
+               cd 2c &&
+
+               git checkout A^0 &&
+
+               GIT_MERGE_VERBOSITY=3 test_must_fail git merge -s recursive B^0 >out 2>err &&
+
+               test_i18ngrep "CONFLICT (rename/add): Rename b->c" out &&
+               test_i18ngrep ! "Skipped c" out &&
+               test_must_be_empty err
+
+               # FIXME: rename/add conflicts are horribly broken right now;
+               # when I get back to my patch series fixing it and
+               # rename/rename(2to1) conflicts to bring them in line with
+               # how add/add conflicts behave, then checks like the below
+               # could be added.  But that patch series is waiting until
+               # the rename-directory-detection series lands, which this
+               # is part of.  And in the mean time, I do not want to further
+               # enforce broken behavior.  So for now, the main test is the
+               # one above that err is an empty file.
+
+               #git ls-files -s >index_files &&
+               #test_line_count = 2 index_files &&
+
+               #git rev-parse >actual :2:c :3:c &&
+               #git rev-parse >expect A:b  A:c  &&
+               #test_cmp expect actual &&
+
+               #git cat-file -p A:b >>merged &&
+               #git cat-file -p A:c >>merge-me &&
+               #>empty &&
+               #test_must_fail git merge-file \
+               #       -L "Temporary merge branch 1" \
+               #       -L "" \
+               #       -L "Temporary merge branch 2" \
+               #       merged empty merge-me &&
+               #sed -e "s/^\([<=>]\)/\1\1\1/" merged >merged-internal &&
+
+               #git hash-object c               >actual &&
+               #git hash-object merged-internal >expect &&
+               #test_cmp expect actual &&
+
+               #test_path_is_missing b
+       )
+'
+
+
+###########################################################################
+# SECTION 3: Cases involving directory renames
+#
+# NOTE:
+#   Directory renames only apply when one side renames a directory, and the
+#   other side adds or renames a path into that directory.  Applying the
+#   directory rename to that new path creates a new pathname that didn't
+#   exist on either side of history.  Thus, it is impossible for the
+#   merge contents to already be at the right path, so all of these checks
+#   exist just to make sure that updates are not skipped.
+###########################################################################
+
+# Testcase 3a, Change + rename into dir foo on A, dir rename foo->bar on B
+#   Commit O: bq_1, foo/whatever
+#   Commit A: foo/{bq_2, whatever}
+#   Commit B: bq_1, bar/whatever
+#   Expected: bar/{bq_2, whatever}
+
+test_expect_success '3a-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+       test_create_repo 3a &&
+       (
+               cd 3a &&
+
+               mkdir foo &&
+               test_seq 1 10 >bq &&
+               test_write_lines a b c d e f g h i j k >foo/whatever &&
+               git add bq foo/whatever &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_seq 1 11 >bq &&
+               git add bq &&
+               git mv bq foo/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               git mv foo/ bar/ &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '3a-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+       test_when_finished "git -C 3a reset --hard" &&
+       test_when_finished "git -C 3a clean -fd" &&
+       (
+               cd 3a &&
+
+               git checkout A^0 &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
+
+               test_i18ngrep ! "Skipped bar/bq" out &&
+               test_must_be_empty err &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 2 index_files &&
+
+               git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
+               git rev-parse >expect A:foo/bq    A:foo/whatever &&
+               test_cmp expect actual &&
+
+               git hash-object bar/bq   bar/whatever   >actual &&
+               git rev-parse   A:foo/bq A:foo/whatever >expect &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
+               test_path_is_missing bq foo/bq foo/whatever
+       )
+'
+
+test_expect_success '3a-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+       test_when_finished "git -C 3a reset --hard" &&
+       test_when_finished "git -C 3a clean -fd" &&
+       (
+               cd 3a &&
+
+               git checkout B^0 &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
+
+               test_i18ngrep ! "Skipped bar/bq" out &&
+               test_must_be_empty err &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 2 index_files &&
+
+               git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
+               git rev-parse >expect A:foo/bq    A:foo/whatever &&
+               test_cmp expect actual &&
+
+               git hash-object bar/bq   bar/whatever   >actual &&
+               git rev-parse   A:foo/bq A:foo/whatever >expect &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
+               test_path_is_missing bq foo/bq foo/whatever
+       )
+'
+
+# Testcase 3b, rename into dir foo on A, dir rename foo->bar + change on B
+#   Commit O: bq_1, foo/whatever
+#   Commit A: foo/{bq_1, whatever}
+#   Commit B: bq_2, bar/whatever
+#   Expected: bar/{bq_2, whatever}
+
+test_expect_success '3b-setup: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+       test_create_repo 3b &&
+       (
+               cd 3b &&
+
+               mkdir foo &&
+               test_seq 1 10 >bq &&
+               test_write_lines a b c d e f g h i j k >foo/whatever &&
+               git add bq foo/whatever &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               git mv bq foo/ &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               test_seq 1 11 >bq &&
+               git add bq &&
+               git mv foo/ bar/ &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '3b-check-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+       test_when_finished "git -C 3b reset --hard" &&
+       test_when_finished "git -C 3b clean -fd" &&
+       (
+               cd 3b &&
+
+               git checkout A^0 &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
+
+               test_i18ngrep ! "Skipped bar/bq" out &&
+               test_must_be_empty err &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 2 index_files &&
+
+               git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
+               git rev-parse >expect B:bq        A:foo/whatever &&
+               test_cmp expect actual &&
+
+               git hash-object bar/bq bar/whatever   >actual &&
+               git rev-parse   B:bq   A:foo/whatever >expect &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
+               test_path_is_missing bq foo/bq foo/whatever
+       )
+'
+
+test_expect_success '3b-check-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
+       test_when_finished "git -C 3b reset --hard" &&
+       test_when_finished "git -C 3b clean -fd" &&
+       (
+               cd 3b &&
+
+               git checkout B^0 &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
+
+               test_i18ngrep ! "Skipped bar/bq" out &&
+               test_must_be_empty err &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 2 index_files &&
+
+               git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
+               git rev-parse >expect B:bq        A:foo/whatever &&
+               test_cmp expect actual &&
+
+               git hash-object bar/bq bar/whatever   >actual &&
+               git rev-parse   B:bq   A:foo/whatever >expect &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
+               test_path_is_missing bq foo/bq foo/whatever
+       )
+'
+
+###########################################################################
+# SECTION 4: Cases involving dirty changes
+###########################################################################
+
+# Testcase 4a, Changed on A, subset of changes on B, locally modified
+#   Commit O: b_1
+#   Commit A: b_2
+#   Commit B: b_3
+#   Working copy: b_4
+#   Expected: b_2 for merge, b_4 in working copy
+
+test_expect_success '4a-setup: Change on A, change on B subset of A, dirty mods present' '
+       test_create_repo 4a &&
+       (
+               cd 4a &&
+
+               test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+# NOTE: For as long as we continue using unpack_trees() without index_only
+#   set to true, it will error out on a case like this claiming the the locally
+#   modified file would be overwritten by the merge.  Getting this testcase
+#   correct requires doing the merge in-memory first, then realizing that no
+#   updates to the file are necessary, and thus that we can just leave the path
+#   alone.
+test_expect_failure '4a-check: Change on A, change on B subset of A, dirty mods present' '
+       test_when_finished "git -C 4a reset --hard" &&
+       test_when_finished "git -C 4a clean -fd" &&
+       (
+               cd 4a &&
+
+               git checkout A^0 &&
+               echo "File rewritten" >b &&
+
+               test-tool chmtime =31337 b &&
+               test-tool chmtime -v +0 b >expected-mtime &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
+
+               test_i18ngrep "Skipped b" out &&
+               test_must_be_empty err &&
+
+               test-tool chmtime -v +0 b >actual-mtime &&
+               test_cmp expected-mtime actual-mtime &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 1 index_files &&
+
+               git rev-parse >actual :0:b &&
+               git rev-parse >expect A:b &&
+               test_cmp expect actual &&
+
+               git hash-object b >actual &&
+               echo "File rewritten" | git hash-object --stdin >expect &&
+               test_cmp expect actual
+       )
+'
+
+# Testcase 4b, Changed+renamed on A, subset of changes on B, locally modified
+#   Commit O: b_1
+#   Commit A: c_2
+#   Commit B: b_3
+#   Working copy: c_4
+#   Expected: c_2
+
+test_expect_success '4b-setup: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
+       test_create_repo 4b &&
+       (
+               cd 4b &&
+
+               test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "O" &&
+
+               git branch O &&
+               git branch A &&
+               git branch B &&
+
+               git checkout A &&
+               test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
+               git add b &&
+               git mv b c &&
+               test_tick &&
+               git commit -m "A" &&
+
+               git checkout B &&
+               test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
+               git add b &&
+               test_tick &&
+               git commit -m "B"
+       )
+'
+
+test_expect_success '4b-check: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
+       test_when_finished "git -C 4b reset --hard" &&
+       test_when_finished "git -C 4b clean -fd" &&
+       (
+               cd 4b &&
+
+               git checkout A^0 &&
+               echo "File rewritten" >c &&
+
+               test-tool chmtime =31337 c &&
+               test-tool chmtime -v +0 c >expected-mtime &&
+
+               GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
+
+               test_i18ngrep "Skipped c" out &&
+               test_must_be_empty err &&
+
+               test-tool chmtime -v +0 c >actual-mtime &&
+               test_cmp expected-mtime actual-mtime &&
+
+               git ls-files -s >index_files &&
+               test_line_count = 1 index_files &&
+
+               git rev-parse >actual :0:c &&
+               git rev-parse >expect A:c &&
+               test_cmp expect actual &&
+
+               git hash-object c >actual &&
+               echo "File rewritten" | git hash-object --stdin >expect &&
+               test_cmp expect actual &&
+
+               test_must_fail git rev-parse HEAD:b &&
+               test_path_is_missing b
+       )
+'
+
+test_done
index c630aba657e9c78b6dee4a72be34ed3bd03c01ee..aa3e24963967ba4be2394ceeab26f8317fb31b4b 100755 (executable)
@@ -4,8 +4,6 @@
 #
 test_description='Tests replace refs functionality'
 
-exec </dev/null
-
 . ./test-lib.sh
 . "$TEST_DIRECTORY/lib-gpg.sh"
 
@@ -444,4 +442,32 @@ test_expect_success GPG '--graft on a commit with a mergetag' '
        git replace -d $HASH10
 '
 
+test_expect_success '--convert-graft-file' '
+       git checkout -b with-graft-file &&
+       test_commit root2 &&
+       git reset --hard root2^ &&
+       test_commit root1 &&
+       test_commit after-root1 &&
+       test_tick &&
+       git merge -m merge-root2 root2 &&
+
+       : add and convert graft file &&
+       printf "%s\n%s %s\n\n# comment\n%s\n" \
+               $(git rev-parse HEAD^^ HEAD^ HEAD^^ HEAD^2) \
+               >.git/info/grafts &&
+       git replace --convert-graft-file &&
+       test_path_is_missing .git/info/grafts &&
+
+       : verify that the history is now "grafted" &&
+       git rev-list HEAD >out &&
+       test_line_count = 4 out &&
+
+       : create invalid graft file and verify that it is not deleted &&
+       test_when_finished "rm -f .git/info/grafts" &&
+       echo $EMPTY_BLOB $EMPTY_TREE >.git/info/grafts &&
+       test_must_fail git replace --convert-graft-file 2>err &&
+       test_i18ngrep "$EMPTY_BLOB $EMPTY_TREE" err &&
+       test_i18ngrep "$EMPTY_BLOB $EMPTY_TREE" .git/info/grafts
+'
+
 test_done
index 8c617981a3a06c1ff49f03a2914bfdc31c0e293c..7683e4a1142a6ee31a1f1fd51b774b19fc2c7401 100755 (executable)
@@ -214,4 +214,12 @@ test_expect_success 'rev-list merge^-1x (garbage after ^-1)' '
        test_must_fail git rev-list merge^-1x
 '
 
+test_expect_success 'rev-parse $garbage^@ does not segfault' '
+       test_must_fail git rev-parse $EMPTY_TREE^@
+'
+
+test_expect_success 'rev-parse $garbage...$garbage does not segfault' '
+       test_must_fail git rev-parse $EMPTY_TREE...$EMPTY_BLOB
+'
+
 test_done
index 32474c23d3e53beda92477c5f126322901f68c53..4244638285bbf97a7e5f47e4efcd4bd3717cf49f 100755 (executable)
@@ -20,7 +20,7 @@ note () {
 }
 
 unnote () {
-       git name-rev --tags --stdin | sed -e "s|$_x40 (tags/\([^)]*\))\([       ]\)|\1\2|g"
+       git name-rev --tags --stdin | sed -e "s|$OID_REGEX (tags/\([^)]*\))\([  ]\)|\1\2|g"
 }
 
 test_expect_success setup '
index bae78c4e89e2402d5ab37e3b7cd094dde41d69b3..84dd1cb6907d583ec4019f1bb5b949865beac6cb 100755 (executable)
@@ -383,7 +383,7 @@ test_expect_success 'describe complains about tree object' '
 '
 
 test_expect_success 'describe complains about missing object' '
-       test_must_fail git describe $_z40
+       test_must_fail git describe $ZERO_OID
 '
 
 test_done
index 295d1475bde0151df65e0098e6e4a169193906ed..48379aa0ee874b0250e2348d47eded09713a0a79 100755 (executable)
@@ -310,7 +310,7 @@ test_expect_success 'exercise strftime with odd fields' '
        echo >expected &&
        git for-each-ref --format="%(authordate:format:)" refs/heads >actual &&
        test_cmp expected actual &&
-       long="long format -- $_z40$_z40$_z40$_z40$_z40$_z40$_z40" &&
+       long="long format -- $ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID" &&
        echo $long >expected &&
        git for-each-ref --format="%(authordate:format:$long)" refs/heads >actual &&
        test_cmp expected actual
index c734ce2388a79d15692875eae81e323c63ad2300..49cc65bb58dd2b81de8f6eebd39ed1649752709d 100755 (executable)
@@ -4,7 +4,7 @@ test_description='for-each-ref errors for broken refs'
 
 . ./test-lib.sh
 
-ZEROS=$_z40
+ZEROS=$ZERO_OID
 MISSING=abababababababababababababababababababab
 
 test_expect_success setup '
index 41b0be575d523071152c19a224a7ef914ce2ee1a..818435f04e49b50965cd674bf046eb3d494fa939 100755 (executable)
@@ -5,6 +5,13 @@ test_description='basic git gc tests
 
 . ./test-lib.sh
 
+test_expect_success 'setup' '
+       # do not let the amount of physical memory affects gc
+       # behavior, make sure we always pack everything to one pack by
+       # default
+       git config gc.bigPackThreshold 2g
+'
+
 test_expect_success 'gc empty repository' '
        git gc
 '
@@ -43,6 +50,31 @@ test_expect_success 'gc is not aborted due to a stale symref' '
        )
 '
 
+test_expect_success 'gc --keep-largest-pack' '
+       test_create_repo keep-pack &&
+       (
+               cd keep-pack &&
+               test_commit one &&
+               test_commit two &&
+               test_commit three &&
+               git gc &&
+               ( cd .git/objects/pack && ls *.pack ) >pack-list &&
+               test_line_count = 1 pack-list &&
+               BASE_PACK=.git/objects/pack/pack-*.pack &&
+               test_commit four &&
+               git repack -d &&
+               test_commit five &&
+               git repack -d &&
+               ( cd .git/objects/pack && ls *.pack ) >pack-list &&
+               test_line_count = 3 pack-list &&
+               git gc --keep-largest-pack &&
+               ( cd .git/objects/pack && ls *.pack ) >pack-list &&
+               test_line_count = 2 pack-list &&
+               test_path_is_file $BASE_PACK &&
+               git fsck
+       )
+'
+
 test_expect_success 'auto gc with too many loose objects does not attempt to create bitmaps' '
        test_config gc.auto 3 &&
        test_config gc.autodetach false &&
@@ -87,7 +119,7 @@ test_expect_success 'background auto gc does not run if gc.log is present and re
        test_must_fail git gc --auto 2>err &&
        test_i18ngrep "^error:" err &&
        test_config gc.logexpiry 5.days &&
-       test-chmtime =-345600 .git/gc.log &&
+       test-tool chmtime =-345600 .git/gc.log &&
        test_must_fail git gc --auto &&
        test_config gc.logexpiry 2.days &&
        run_and_wait_for_auto_gc &&
index 394b169eada7968875e931c5a43f25a808cfc18f..033871ee5f35c1a143aec6d2b30c5116bf3f94f5 100755 (executable)
@@ -72,8 +72,7 @@ for repack in '' true; do
        '
 
        test_expect_success "simulate time passing ($title)" '
-               find .git/objects -type f |
-               xargs test-chmtime -v -86400
+               test-tool chmtime --get -86400 $(find .git/objects -type f)
        '
 
        test_expect_success "start writing new commit with old blob ($title)" '
@@ -103,8 +102,7 @@ for repack in '' true; do
 
        test_expect_success "abandon objects again ($title)" '
                git reset --hard HEAD^ &&
-               find .git/objects -type f |
-               xargs test-chmtime -v -86400
+               test-tool chmtime --get -86400 $(find .git/objects -type f)
        '
 
        test_expect_success "start writing new commit with same tree ($title)" '
index d4e6485a26eef8985856413a1bf977c95f6ec345..cc3fd2baf2b80817ffc39ab67a988dcf31dbc537 100755 (executable)
@@ -21,8 +21,8 @@ test_expect_success \
 
 test_expect_success \
     'checking the commit' \
-    'git diff-tree -r -M --name-status  HEAD^ HEAD | \
-    grep "^R100..*path0/COPYING..*path1/COPYING"'
+    'git diff-tree -r -M --name-status  HEAD^ HEAD >actual &&
+    grep "^R100..*path0/COPYING..*path1/COPYING" actual'
 
 test_expect_success \
     'moving the file back into subdirectory' \
@@ -35,8 +35,8 @@ test_expect_success \
 
 test_expect_success \
     'checking the commit' \
-    'git diff-tree -r -M --name-status  HEAD^ HEAD | \
-    grep "^R100..*path1/COPYING..*path0/COPYING"'
+    'git diff-tree -r -M --name-status  HEAD^ HEAD >actual &&
+    grep "^R100..*path1/COPYING..*path0/COPYING" actual'
 
 test_expect_success \
     'mv --dry-run does not move file' \
@@ -122,10 +122,9 @@ test_expect_success \
 
 test_expect_success \
     'checking the commit' \
-    'git diff-tree -r -M --name-status  HEAD^ HEAD | \
-     grep "^R100..*path0/COPYING..*path2/COPYING" &&
-     git diff-tree -r -M --name-status  HEAD^ HEAD | \
-     grep "^R100..*path0/README..*path2/README"'
+    'git diff-tree -r -M --name-status  HEAD^ HEAD >actual &&
+     grep "^R100..*path0/COPYING..*path2/COPYING" actual &&
+     grep "^R100..*path0/README..*path2/README" actual'
 
 test_expect_success \
     'succeed when source is a prefix of destination' \
@@ -141,10 +140,9 @@ test_expect_success \
 
 test_expect_success \
     'checking the commit' \
-    'git diff-tree -r -M --name-status  HEAD^ HEAD | \
-     grep "^R100..*path2/COPYING..*path1/path2/COPYING" &&
-     git diff-tree -r -M --name-status  HEAD^ HEAD | \
-     grep "^R100..*path2/README..*path1/path2/README"'
+    'git diff-tree -r -M --name-status  HEAD^ HEAD >actual &&
+     grep "^R100..*path2/COPYING..*path1/path2/COPYING" actual &&
+     grep "^R100..*path2/README..*path1/path2/README" actual'
 
 test_expect_success \
     'do not move directory over existing directory' \
@@ -497,7 +495,7 @@ test_expect_success 'moving a submodule in nested directories' '
        test_cmp expect actual
 '
 
-test_expect_failure 'moving nested submodules' '
+test_expect_success 'moving nested submodules' '
        git commit -am "cleanup commit" &&
        mkdir sub_nested_nested &&
        (cd sub_nested_nested &&
index 7cb60799be1a109e2210350137c8754a5bc4bb7d..ec4b160ddb9f966044e729f35cc1edfcc79eed14 100755 (executable)
@@ -187,7 +187,8 @@ test_expect_success 'author information is preserved' '
                        test \$GIT_COMMIT != $(git rev-parse master) || \
                        echo Hallo" \
                preserved-author) &&
-       test 1 = $(git rev-list --author="B V Uips" preserved-author | wc -l)
+       git rev-list --author="B V Uips" preserved-author >actual &&
+       test_line_count = 1 actual
 '
 
 test_expect_success "remove a certain author's commits" '
@@ -205,7 +206,8 @@ test_expect_success "remove a certain author's commits" '
        cnt1=$(git rev-list master | wc -l) &&
        cnt2=$(git rev-list removed-author | wc -l) &&
        test $cnt1 -eq $(($cnt2 + 1)) &&
-       test 0 = $(git rev-list --author="B V Uips" removed-author | wc -l)
+       git rev-list --author="B V Uips" removed-author >actual &&
+       test_line_count = 0 actual
 '
 
 test_expect_success 'barf on invalid name' '
@@ -258,7 +260,8 @@ test_expect_success 'Subdirectory filter with disappearing trees' '
        git commit -m "Re-adding foo" &&
 
        git filter-branch -f --subdirectory-filter foo &&
-       test $(git rev-list master | wc -l) = 3
+       git rev-list master >actual &&
+       test_line_count = 3 actual
 '
 
 test_expect_success 'Tag name filtering retains tag message' '
@@ -470,4 +473,18 @@ test_expect_success 'tree-filter deals with object name vs pathname ambiguity' '
        git show HEAD:$ambiguous
 '
 
+test_expect_success 'rewrite repository including refs that point at non-commit object' '
+       test_when_finished "git reset --hard original" &&
+       tree=$(git rev-parse HEAD^{tree}) &&
+       test_when_finished "git replace -d $tree" &&
+       echo A >new &&
+       git add new &&
+       new_tree=$(git write-tree) &&
+       git replace $tree $new_tree &&
+       git tag -a -m "tag to a tree" treetag $new_tree &&
+       git reset --hard HEAD &&
+       git filter-branch -f -- --all >filter-output 2>&1 &&
+       ! fgrep fatal filter-output
+'
+
 test_done
index 2aac77af701989dc16980268155d6e40500354bb..d7b319e919c83ca677737840f70075c173364209 100755 (executable)
@@ -363,7 +363,7 @@ test_expect_success 'tag -l <pattern> -l <pattern> works, as our buggy documenta
 '
 
 test_expect_success 'listing tags in column' '
-       COLUMNS=40 git tag -l --column=row >actual &&
+       COLUMNS=41 git tag -l --column=row >actual &&
        cat >expected <<\EOF &&
 a1      aa1     cba     t210    t211
 v0.2.1  v1.0    v1.0.1  v1.1.3
@@ -1056,7 +1056,18 @@ test_expect_success GPG \
        git tag -s -F sigblanknonlfile blanknonlfile-signed-tag &&
        get_tag_msg blanknonlfile-signed-tag >actual &&
        test_cmp expect actual &&
-       git tag -v signed-tag
+       git tag -v blanknonlfile-signed-tag
+'
+
+test_expect_success GPG 'signed tag with embedded PGP message' '
+       cat >msg <<-\EOF &&
+       -----BEGIN PGP MESSAGE-----
+
+       this is not a real PGP message
+       -----END PGP MESSAGE-----
+       EOF
+       git tag -s -F msg confusing-pgp-message &&
+       git tag -v confusing-pgp-message
 '
 
 # messages with commented lines for signed tags:
index 29e5043b9452b9c32a0d8ad437fb33745b296ac6..b2ca77b3384c97954991eae9c5af89c4d8d8035e 100755 (executable)
@@ -111,14 +111,8 @@ do
        '
 done
 
-if echo 'echo space > "$1"' > "e space.sh"
-then
-       # FS supports spaces in filenames
-       test_set_prereq SPACES_IN_FILENAMES
-fi
-
-test_expect_success SPACES_IN_FILENAMES 'editor with a space' '
-
+test_expect_success 'editor with a space' '
+       echo "echo space >\$1" >"e space.sh" &&
        chmod a+x "e space.sh" &&
        GIT_EDITOR="./e\ space.sh" git commit --amend &&
        test space = "$(git show -s --pretty=format:%s)"
@@ -126,7 +120,7 @@ test_expect_success SPACES_IN_FILENAMES 'editor with a space' '
 '
 
 unset GIT_EDITOR
-test_expect_success SPACES_IN_FILENAMES 'core.editor with a space' '
+test_expect_success 'core.editor with a space' '
 
        git config core.editor \"./e\ space.sh\" &&
        git commit --amend &&
index a8d9ec498778b5a597fd5751f811c8bf0b0ab926..9ba9f24ad2fb4bd2c38a722e62577789fe36f09a 100755 (executable)
@@ -12,7 +12,7 @@ test_expect_success 'setup: base commits' '
 test_expect_success 'setup: a commit with a bogus null sha1 in the tree' '
        {
                git ls-tree HEAD &&
-               printf "160000 commit $_z40\\tbroken\\n"
+               printf "160000 commit $ZERO_OID\\tbroken\\n"
        } >broken-tree &&
        echo "add broken entry" >msg &&
 
index 84f41451ec4e34b6438313545ca886fbef75f34d..37525cae3af303dd60531226d885c72725b0ae53 100755 (executable)
@@ -118,7 +118,7 @@ test_expect_success 'grep with skip-worktree file' '
        test "$(git grep --no-ext-grep test)" = "1:test"
 '
 
-echo ":000000 100644 $_z40 $EMPTY_BLOB A       1" > expected
+echo ":000000 100644 $ZERO_OID $EMPTY_BLOB A   1" > expected
 test_expect_success 'diff-index does not examine skip-worktree absent entries' '
        setup_absent &&
        git diff-index HEAD -- 1 > result &&
index 8f795327a00f6c1b751b82e7e395c8387543d388..b9a86d3347acb4051a212e2c9e3573a2c6e9fe7a 100755 (executable)
@@ -46,11 +46,11 @@ test_expect_success 'before initial commit, things added' '
        cat >expect <<-EOF &&
        # branch.oid (initial)
        # branch.head master
-       1 A. N... 000000 100644 100644 $_z40 $OID_A dir1/file_a
-       1 A. N... 000000 100644 100644 $_z40 $OID_B dir1/file_b
-       1 A. N... 000000 100644 100644 $_z40 $OID_X file_x
-       1 A. N... 000000 100644 100644 $_z40 $OID_Y file_y
-       1 A. N... 000000 100644 100644 $_z40 $OID_Z file_z
+       1 A. N... 000000 100644 100644 $ZERO_OID $OID_A dir1/file_a
+       1 A. N... 000000 100644 100644 $ZERO_OID $OID_B dir1/file_b
+       1 A. N... 000000 100644 100644 $ZERO_OID $OID_X file_x
+       1 A. N... 000000 100644 100644 $ZERO_OID $OID_Y file_y
+       1 A. N... 000000 100644 100644 $ZERO_OID $OID_Z file_z
        ? actual
        ? expect
        EOF
@@ -63,11 +63,11 @@ test_expect_success 'before initial commit, things added (-z)' '
        lf_to_nul >expect <<-EOF &&
        # branch.oid (initial)
        # branch.head master
-       1 A. N... 000000 100644 100644 $_z40 $OID_A dir1/file_a
-       1 A. N... 000000 100644 100644 $_z40 $OID_B dir1/file_b
-       1 A. N... 000000 100644 100644 $_z40 $OID_X file_x
-       1 A. N... 000000 100644 100644 $_z40 $OID_Y file_y
-       1 A. N... 000000 100644 100644 $_z40 $OID_Z file_z
+       1 A. N... 000000 100644 100644 $ZERO_OID $OID_A dir1/file_a
+       1 A. N... 000000 100644 100644 $ZERO_OID $OID_B dir1/file_b
+       1 A. N... 000000 100644 100644 $ZERO_OID $OID_X file_x
+       1 A. N... 000000 100644 100644 $ZERO_OID $OID_Y file_y
+       1 A. N... 000000 100644 100644 $ZERO_OID $OID_Z file_z
        ? actual
        ? expect
        EOF
@@ -128,7 +128,7 @@ test_expect_success 'after first commit, stage existing changes' '
        # branch.oid $H0
        # branch.head master
        1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
-       1 D. N... 100644 000000 000000 $OID_Z $_z40 file_z
+       1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z
        ? actual
        ? expect
        EOF
@@ -145,7 +145,7 @@ test_expect_success 'rename causes 2 path lines' '
        # branch.oid $H0
        # branch.head master
        1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
-       1 D. N... 100644 000000 000000 $OID_Z $_z40 file_z
+       1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z
        2 R. N... 100644 100644 100644 $OID_Y $OID_Y R100 renamed_yQfile_y
        ? actual
        ? expect
@@ -163,7 +163,7 @@ test_expect_success 'rename causes 2 path lines (-z)' '
        # branch.oid $H0
        # branch.head master
        1 M. N... 100644 100644 100644 $OID_X $OID_X1 file_x
-       1 D. N... 100644 000000 000000 $OID_Z $_z40 file_z
+       1 D. N... 100644 000000 000000 $OID_Z $ZERO_OID file_z
        2 R. N... 100644 100644 100644 $OID_Y $OID_Y R100 renamed_yQfile_y
        ? actual
        ? expect
@@ -246,8 +246,8 @@ test_expect_success 'verify --intent-to-add output' '
        git add --intent-to-add intent1.add intent2.add &&
 
        cat >expect <<-EOF &&
-       1 .A N... 000000 000000 100644 $_z40 $_z40 intent1.add
-       1 .A N... 000000 000000 100644 $_z40 $_z40 intent2.add
+       1 .A N... 000000 000000 100644 $ZERO_OID $ZERO_OID intent1.add
+       1 .A N... 000000 000000 100644 $ZERO_OID $ZERO_OID intent2.add
        EOF
 
        git status --porcelain=v2 >actual &&
@@ -280,7 +280,7 @@ test_expect_success 'verify AA (add-add) conflict' '
        cat >expect <<-EOF &&
        # branch.oid $HM
        # branch.head AA_M
-       u AA N... 000000 100644 100644 100644 $_z40 $OID_AA_B $OID_AA_A conflict.txt
+       u AA N... 000000 100644 100644 100644 $ZERO_OID $OID_AA_B $OID_AA_A conflict.txt
        EOF
 
        git status --porcelain=v2 --branch --untracked-files=all >actual &&
@@ -373,7 +373,7 @@ test_expect_success 'verify upstream fields in branch header' '
                ## Test upstream-gone case. Fake this by pointing origin/master at
                ## a non-existing commit.
                OLD=$(git rev-parse origin/master) &&
-               NEW=$_z40 &&
+               NEW=$ZERO_OID &&
                mv .git/packed-refs .git/old-packed-refs &&
                sed "s/$OLD/$NEW/g" <.git/old-packed-refs >.git/packed-refs &&
 
@@ -469,8 +469,8 @@ test_expect_success 'create and add submodule, submodule appears clean (A. S...)
                # branch.head master
                # branch.upstream origin/master
                # branch.ab +0 -0
-               1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
-               1 A. S... 000000 160000 160000 $_z40 $HSUB sub1
+               1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
+               1 A. S... 000000 160000 160000 $ZERO_OID $HSUB sub1
                EOF
 
                git status --porcelain=v2 --branch --untracked-files=all >actual &&
@@ -494,8 +494,8 @@ test_expect_success 'untracked changes in added submodule (AM S..U)' '
                # branch.head master
                # branch.upstream origin/master
                # branch.ab +0 -0
-               1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
-               1 AM S..U 000000 160000 160000 $_z40 $HSUB sub1
+               1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
+               1 AM S..U 000000 160000 160000 $ZERO_OID $HSUB sub1
                EOF
 
                git status --porcelain=v2 --branch --untracked-files=all >actual &&
@@ -519,8 +519,8 @@ test_expect_success 'staged changes in added submodule (AM S.M.)' '
                # branch.head master
                # branch.upstream origin/master
                # branch.ab +0 -0
-               1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
-               1 AM S.M. 000000 160000 160000 $_z40 $HSUB sub1
+               1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
+               1 AM S.M. 000000 160000 160000 $ZERO_OID $HSUB sub1
                EOF
 
                git status --porcelain=v2 --branch --untracked-files=all >actual &&
@@ -546,8 +546,8 @@ test_expect_success 'staged and unstaged changes in added (AM S.M.)' '
                # branch.head master
                # branch.upstream origin/master
                # branch.ab +0 -0
-               1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
-               1 AM S.M. 000000 160000 160000 $_z40 $HSUB sub1
+               1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
+               1 AM S.M. 000000 160000 160000 $ZERO_OID $HSUB sub1
                EOF
 
                git status --porcelain=v2 --branch --untracked-files=all >actual &&
@@ -573,8 +573,8 @@ test_expect_success 'staged and untracked changes in added submodule (AM S.MU)'
                # branch.head master
                # branch.upstream origin/master
                # branch.ab +0 -0
-               1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
-               1 AM S.MU 000000 160000 160000 $_z40 $HSUB sub1
+               1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
+               1 AM S.MU 000000 160000 160000 $ZERO_OID $HSUB sub1
                EOF
 
                git status --porcelain=v2 --branch --untracked-files=all >actual &&
@@ -600,8 +600,8 @@ test_expect_success 'commit within the submodule appears as new commit in super
                # branch.head master
                # branch.upstream origin/master
                # branch.ab +0 -0
-               1 A. N... 000000 100644 100644 $_z40 $HMOD .gitmodules
-               1 AM SC.. 000000 160000 160000 $_z40 $HSUB sub1
+               1 A. N... 000000 100644 100644 $ZERO_OID $HMOD .gitmodules
+               1 AM SC.. 000000 160000 160000 $ZERO_OID $HSUB sub1
                EOF
 
                git status --porcelain=v2 --branch --untracked-files=all >actual &&
index 76c223c9675cd1531ac078fa9e0c1f8cc4e09781..ab9da61da391f1b6040076dda2454f602adef7d2 100755 (executable)
@@ -65,7 +65,7 @@ test_expect_success setup '
 test_expect_success "checkout from non-existing branch" '
 
        git checkout -b delete-me master &&
-       rm .git/refs/heads/delete-me &&
+       git update-ref -d --no-deref refs/heads/delete-me &&
        test refs/heads/delete-me = "$(git symbolic-ref HEAD)" &&
        git checkout master &&
        test refs/heads/master = "$(git symbolic-ref HEAD)"
index a39e69a3ebd1c39ddf8feb861f8a39c8315aa7f8..812db137b8db2f6f8457ccb5d6ab27e0215dbe1a 100755 (executable)
@@ -126,6 +126,24 @@ test_expect_success 'submodule add' '
        test_cmp empty untracked
 '
 
+test_expect_success 'setup parent and one repository' '
+       test_create_repo parent &&
+       test_commit -C parent one
+'
+
+test_expect_success 'redirected submodule add does not show progress' '
+       git -C addtest submodule add "file://$submodurl/parent" submod-redirected \
+               2>err &&
+       ! grep % err &&
+       test_i18ngrep ! "Checking connectivity" err
+'
+
+test_expect_success 'redirected submodule add --progress does show progress' '
+       git -C addtest submodule add --progress "file://$submodurl/parent" \
+               submod-redirected-progress 2>err && \
+       grep % err
+'
+
 test_expect_success 'submodule add to .gitignored path fails' '
        (
                cd addtest-ignore &&
@@ -821,6 +839,21 @@ test_expect_success 'moving the superproject does not break submodules' '
        )
 '
 
+test_expect_success 'moving the submodule does not break the superproject' '
+       (
+               cd addtest2 &&
+               git submodule status
+       ) >actual &&
+       sed -e "s/^ \([^ ]* repo\) .*/-\1/" <actual >expect &&
+       mv addtest2/repo addtest2/repo.bak &&
+       test_when_finished "mv addtest2/repo.bak addtest2/repo" &&
+       (
+               cd addtest2 &&
+               git submodule status
+       ) >actual &&
+       test_cmp expect actual
+'
+
 test_expect_success 'submodule add --name allows to replace a submodule with another at the same path' '
        (
                cd addtest2 &&
index ceb5eed6e1bb4134d2efc72ed924a5b20ce359e0..9a9dff5dea322d98e5c63e88bc430e35708630f5 100755 (executable)
@@ -65,7 +65,7 @@ test_expect_success 'setup a submodule tree' '
         git commit -m "none"
        ) &&
        git clone . recursivesuper &&
-       ( cd recursivesuper
+       ( cd recursivesuper &&
         git submodule add ../super super
        )
 '
@@ -245,13 +245,13 @@ test_expect_success 'submodule update --remote should fetch upstream changes wit
        (
                cd super &&
                git submodule update --remote --force submodule &&
-               git -C submodule log -1 --oneline >actual
-               git -C ../submodule log -1 --oneline master >expect
+               git -C submodule log -1 --oneline >actual &&
+               git -C ../submodule log -1 --oneline master >expect &&
                test_cmp expect actual &&
                git checkout -b test-branch &&
                git submodule update --remote --force submodule &&
-               git -C submodule log -1 --oneline >actual
-               git -C ../submodule log -1 --oneline test-branch >expect
+               git -C submodule log -1 --oneline >actual &&
+               git -C ../submodule log -1 --oneline test-branch >expect &&
                test_cmp expect actual &&
                git checkout master &&
                git branch -d test-branch &&
@@ -907,7 +907,7 @@ test_expect_success 'submodule update properly revives a moved submodule' '
         rm -rf submodule2 &&
         mkdir -p "moved/sub module" &&
         git update-index --add --cacheinfo 160000 $H "moved/sub module" &&
-        git config -f .gitmodules submodule.submodule2.path "moved/sub module"
+        git config -f .gitmodules submodule.submodule2.path "moved/sub module" &&
         git commit -am "post move" &&
         git submodule update &&
         git status | sed "s/$H2/XXX/" >actual &&
index e159fc5035d08eee2c1577afd2ac792ddce2934c..08d9add05e0868980f1b59412997e4598e5f9576 100755 (executable)
@@ -59,6 +59,16 @@ test_expect_success 'submodule add --reference uses alternates' '
        test_alternate_is_used super/.git/modules/sub/objects/info/alternates super/sub
 '
 
+test_expect_success 'submodule add --reference with --dissociate does not use alternates' '
+       (
+               cd super &&
+               git submodule add --reference ../B --dissociate "file://$base_dir/A" sub-dissociate &&
+               git commit -m B-super-added &&
+               git repack -ad
+       ) &&
+       test_path_is_missing super/.git/modules/sub-dissociate/objects/info/alternates
+'
+
 test_expect_success 'that reference gets used with add' '
        (
                cd super/sub &&
@@ -82,6 +92,13 @@ test_expect_success 'updating superproject keeps alternates' '
        test_alternate_is_used super-clone/.git/modules/sub/objects/info/alternates super-clone/sub
 '
 
+test_expect_success 'updating superproject with --dissociate does not keep alternates' '
+       test_when_finished "rm -rf super-clone" &&
+       git clone super super-clone &&
+       git -C super-clone submodule update --init --reference ../B --dissociate &&
+       test_path_is_missing super-clone/.git/modules/sub/objects/info/alternates
+'
+
 test_expect_success 'submodules use alternates when cloning a superproject' '
        test_when_finished "rm -rf super-clone" &&
        git clone --reference super --recursive super super-clone &&
index 46c09c77654597b2ee501271b4688cc6137df8f1..0bde5850ac547c90dadd9e21341ebad80a1471e6 100755 (executable)
@@ -41,7 +41,7 @@ test_expect_success 'configuration parsing with error' '
        EOF
        (
                cd repo &&
-               test_must_fail test-submodule-config "" s 2>actual &&
+               test_must_fail test-tool submodule-config "" s 2>actual &&
                test_i18ngrep "bad config" actual
        )
 '
@@ -55,7 +55,7 @@ EOF
 
 test_expect_success 'test parsing and lookup of submodule config by path' '
        (cd super &&
-               test-submodule-config \
+               test-tool submodule-config \
                        HEAD^ a \
                        HEAD b \
                        HEAD^ submodule \
@@ -67,7 +67,7 @@ test_expect_success 'test parsing and lookup of submodule config by path' '
 
 test_expect_success 'test parsing and lookup of submodule config by name' '
        (cd super &&
-               test-submodule-config --name \
+               test-tool submodule-config --name \
                        HEAD^ a \
                        HEAD a \
                        HEAD^ submodule \
@@ -89,7 +89,7 @@ test_expect_success 'error in one submodule config lets continue' '
                git add .gitmodules &&
                mv .gitmodules.bak .gitmodules &&
                git commit -m "add error" &&
-               test-submodule-config \
+               test-tool submodule-config \
                        HEAD b \
                        HEAD submodule \
                                >actual &&
@@ -100,7 +100,7 @@ test_expect_success 'error in one submodule config lets continue' '
 test_expect_success 'error message contains blob reference' '
        (cd super &&
                sha1=$(git rev-parse HEAD) &&
-               test-submodule-config \
+               test-tool submodule-config \
                        HEAD b \
                        HEAD submodule \
                                2>actual_err &&
@@ -114,9 +114,9 @@ test_expect_success 'using different treeishs works' '
                git tag new_tag &&
                tree=$(git rev-parse HEAD^{tree}) &&
                commit=$(git rev-parse HEAD^{commit}) &&
-               test-submodule-config $commit b >expect &&
-               test-submodule-config $tree b >actual.1 &&
-               test-submodule-config new_tag b >actual.2 &&
+               test-tool submodule-config $commit b >expect &&
+               test-tool submodule-config $tree b >actual.1 &&
+               test-tool submodule-config new_tag b >actual.2 &&
                test_cmp expect actual.1 &&
                test_cmp expect actual.2
        )
@@ -130,7 +130,7 @@ test_expect_success 'error in history in fetchrecursesubmodule lets continue' '
                git config --unset -f .gitmodules \
                        submodule.submodule.fetchrecursesubmodules &&
                git commit -m "add error in fetchrecursesubmodules" &&
-               test-submodule-config \
+               test-tool submodule-config \
                        HEAD b \
                        HEAD submodule \
                                >actual &&
index 717d708bcdba1bdd78a3a3f31b33e8b6a8068af3..31d1e2d51242bb5b2dcd822bceb032c5b23ad019 100755 (executable)
@@ -122,6 +122,16 @@ test_expect_success 'transfer.fsckObjects handles odd pack (index)' '
        test_must_fail git -C dst.git index-pack --strict --stdin <odd.pack
 '
 
+test_expect_success 'index-pack --strict works for non-repo pack' '
+       rm -rf dst.git &&
+       git init --bare dst.git &&
+       cp odd.pack dst.git &&
+       test_must_fail git -C dst.git index-pack --strict odd.pack 2>output &&
+       # Make sure we fail due to bad gitmodules content, not because we
+       # could not read the blob in the first place.
+       grep gitmodulesName output
+'
+
 test_expect_success 'fsck detects symlinked .gitmodules file' '
        git init symlink &&
        (
@@ -135,13 +145,10 @@ test_expect_success 'fsck detects symlinked .gitmodules file' '
                tricky="[foo]bar=true" &&
                content=$(git hash-object -w ../.gitmodules) &&
                target=$(printf "$tricky" | git hash-object -w --stdin) &&
-               tree=$(
-                       {
-                               printf "100644 blob $content\t$tricky\n" &&
-                               printf "120000 blob $target\t.gitmodules\n"
-                       } | git mktree
-               ) &&
-               commit=$(git commit-tree $tree) &&
+               {
+                       printf "100644 blob $content\t$tricky\n" &&
+                       printf "120000 blob $target\t.gitmodules\n"
+               } | git mktree &&
 
                # Check not only that we fail, but that it is due to the
                # symlink detector; this grep string comes from the config
@@ -151,6 +158,24 @@ test_expect_success 'fsck detects symlinked .gitmodules file' '
        )
 '
 
+test_expect_success 'fsck detects non-blob .gitmodules' '
+       git init non-blob &&
+       (
+               cd non-blob &&
+
+               # As above, make the funny tree directly to avoid index
+               # restrictions.
+               mkdir subdir &&
+               cp ../.gitmodules subdir/file &&
+               git add subdir/file &&
+               git commit -m ok &&
+               git ls-tree HEAD | sed s/subdir/.gitmodules/ | git mktree &&
+
+               test_must_fail git fsck 2>output &&
+               grep gitmodulesBlob output
+       )
+'
+
 test_expect_success MINGW 'prevent git~1 squatting on Windows' '
        git init squatting &&
        (
index fa61b1a4ee4a1d5ba457cb30e5cc045f724ed503..9dbbd01fc07724e378a864e3fe735269665a9bc3 100755 (executable)
@@ -52,6 +52,18 @@ test_expect_success PERL 'can use paths with --interactive' '
        git reset --hard HEAD^
 '
 
+test_expect_success 'removed files and relative paths' '
+       test_when_finished "rm -rf foo" &&
+       git init foo &&
+       >foo/foo.txt &&
+       git -C foo add foo.txt &&
+       git -C foo commit -m first &&
+       git -C foo rm foo.txt &&
+
+       mkdir -p foo/bar &&
+       git -C foo/bar commit -m second ../foo.txt
+'
+
 test_expect_success 'using invalid commit with -C' '
        test_must_fail git commit --allow-empty -C bogus
 '
index 9edf6572ed3b8f04ef1169f545043fcb2e09fe21..b4b74dbe29dd53ae8029cec20be4b6fef2cd6a1e 100755 (executable)
@@ -18,7 +18,7 @@ test_create_repo_with_commit () {
 }
 
 sanitize_output () {
-       sed -e "s/$_x40/HASH/" -e "s/$_x40/HASH/" output >output2 &&
+       sed -e "s/$OID_REGEX/HASH/" -e "s/$OID_REGEX/HASH/" output >output2 &&
        mv output2 output
 }
 
index 50052e28727dab74037a115003b6083256d7f344..18a40257fbb3226a328fdd520231972c111e6265 100755 (executable)
@@ -1672,12 +1672,12 @@ test_expect_success '"Initial commit" should not be noted in commit template' '
 '
 
 test_expect_success '--no-optional-locks prevents index update' '
-       test-chmtime =1234567890 .git/index &&
+       test-tool chmtime =1234567890 .git/index &&
        git --no-optional-locks status &&
-       test-chmtime -v +0 .git/index >out &&
+       test-tool chmtime --get .git/index >out &&
        grep ^1234567890 out &&
        git status &&
-       test-chmtime -v +0 .git/index >out &&
+       test-tool chmtime --get .git/index >out &&
        ! grep ^1234567890 out
 '
 
diff --git a/t/t7525-status-rename.sh b/t/t7525-status-rename.sh
new file mode 100755 (executable)
index 0000000..ef8b1b3
--- /dev/null
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+test_description='git status rename detection options'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+       echo 1 >original &&
+       git add . &&
+       git commit -m"Adding original file." &&
+       mv original renamed &&
+       echo 2 >> renamed &&
+       git add . &&
+       cat >.gitignore <<-\EOF
+       .gitignore
+       expect*
+       actual*
+       EOF
+'
+
+test_expect_success 'status no-options' '
+       git status >actual &&
+       test_i18ngrep "renamed:" actual
+'
+
+test_expect_success 'status --no-renames' '
+       git status --no-renames >actual &&
+       test_i18ngrep "deleted:" actual &&
+       test_i18ngrep "new file:" actual
+'
+
+test_expect_success 'status.renames inherits from diff.renames false' '
+       git -c diff.renames=false status >actual &&
+       test_i18ngrep "deleted:" actual &&
+       test_i18ngrep "new file:" actual
+'
+
+test_expect_success 'status.renames inherits from diff.renames true' '
+       git -c diff.renames=true status >actual &&
+       test_i18ngrep "renamed:" actual
+'
+
+test_expect_success 'status.renames overrides diff.renames false' '
+       git -c diff.renames=true -c status.renames=false status >actual &&
+       test_i18ngrep "deleted:" actual &&
+       test_i18ngrep "new file:" actual
+'
+
+test_expect_success 'status.renames overrides from diff.renames true' '
+       git -c diff.renames=false -c status.renames=true status >actual &&
+       test_i18ngrep "renamed:" actual
+'
+
+test_expect_success 'status status.renames=false' '
+       git -c status.renames=false status >actual &&
+       test_i18ngrep "deleted:" actual &&
+       test_i18ngrep "new file:" actual
+'
+
+test_expect_success 'status status.renames=true' '
+       git -c status.renames=true status >actual &&
+       test_i18ngrep "renamed:" actual
+'
+
+test_expect_success 'commit honors status.renames=false' '
+       git -c status.renames=false commit --dry-run >actual &&
+       test_i18ngrep "deleted:" actual &&
+       test_i18ngrep "new file:" actual
+'
+
+test_expect_success 'commit honors status.renames=true' '
+       git -c status.renames=true commit --dry-run >actual &&
+       test_i18ngrep "renamed:" actual
+'
+
+test_expect_success 'status config overridden' '
+       git -c status.renames=true status --no-renames >actual &&
+       test_i18ngrep "deleted:" actual &&
+       test_i18ngrep "new file:" actual
+'
+
+test_expect_success 'status score=100%' '
+       git status -M=100% >actual &&
+       test_i18ngrep "deleted:" actual &&
+       test_i18ngrep "new file:" actual &&
+
+       git status --find-rename=100% >actual &&
+       test_i18ngrep "deleted:" actual &&
+       test_i18ngrep "new file:" actual
+'
+
+test_expect_success 'status score=01%' '
+       git status -M=01% >actual &&
+       test_i18ngrep "renamed:" actual &&
+
+       git status --find-rename=01% >actual &&
+       test_i18ngrep "renamed:" actual
+'
+
+test_expect_success 'copies not overridden by find-rename' '
+       cp renamed copy &&
+       git add copy &&
+
+       git -c status.renames=copies status -M=01% >actual &&
+       test_i18ngrep "copied:" actual &&
+       test_i18ngrep "renamed:" actual &&
+
+       git -c status.renames=copies status --find-rename=01% >actual &&
+       test_i18ngrep "copied:" actual &&
+       test_i18ngrep "renamed:" actual
+'
+
+test_done
index 9c422bcd7cc8c1b2525579ca3a7ffa6ee412ba42..dd8ab7ede182fc3c3da840fee083bf23a94ce13c 100755 (executable)
@@ -92,7 +92,7 @@ test_expect_success 'will not overwrite removed file with staged changes' '
        test_cmp important c1.c
 '
 
-test_expect_failure 'will not overwrite unstaged changes in renamed file' '
+test_expect_success 'will not overwrite unstaged changes in renamed file' '
        git reset --hard c1 &&
        git mv c1.c other.c &&
        git commit -m rename &&
index 6061a04147a06dba0d049cbb5d31f8049c2210d0..6162e2a8e66f6f0e42e0a8ba6ee3b728e8e84918 100755 (executable)
@@ -4,6 +4,12 @@ test_description='git repack works correctly'
 
 . ./test-lib.sh
 
+commit_and_pack() {
+       test_commit "$@" >/dev/null &&
+       SHA1=$(git pack-objects --all --unpacked --incremental .git/objects/pack/pack </dev/null) &&
+       echo pack-${SHA1}.pack
+}
+
 test_expect_success 'objects in packs marked .keep are not repacked' '
        echo content1 > file1 &&
        echo content2 > file2 &&
@@ -194,7 +200,26 @@ test_expect_success 'objects made unreachable by grafts only are kept' '
        git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&
        git repack -a -d &&
        git cat-file -t $H1
-       '
+'
+
+test_expect_success 'repack --keep-pack' '
+       test_create_repo keep-pack &&
+       (
+               cd keep-pack &&
+               P1=$(commit_and_pack 1) &&
+               P2=$(commit_and_pack 2) &&
+               P3=$(commit_and_pack 3) &&
+               P4=$(commit_and_pack 4) &&
+               ls .git/objects/pack/*.pack >old-counts &&
+               test_line_count = 4 old-counts &&
+               git repack -a -d --keep-pack $P1 --keep-pack $P4 &&
+               ls .git/objects/pack/*.pack >new-counts &&
+               grep -q $P1 new-counts &&
+               grep -q $P4 new-counts &&
+               test_line_count = 3 new-counts &&
+               git fsck
+       )
+'
 
 test_done
 
index 987573c41fcd4aee3d5f8fd8aa587c97551c1872..48261ba0805cd21e64bdf471f2835a7075782a6c 100755 (executable)
@@ -55,8 +55,8 @@ test_expect_success '-A with -d option leaves unreachable objects unpacked' '
 
 compare_mtimes ()
 {
-       read tref rest &&
-       while read t rest; do
+       read tref &&
+       while read t; do
                test "$tref" = "$t" || return 1
        done
 }
@@ -90,7 +90,7 @@ test_expect_success 'unpacked objects receive timestamp of pack file' '
        tmppack=".git/objects/pack/tmp_pack" &&
        ln "$packfile" "$tmppack" &&
        git repack -A -l -d &&
-       test-chmtime -v +0 "$tmppack" "$fsha1path" "$csha1path" "$tsha1path" \
+       test-tool chmtime --get "$tmppack" "$fsha1path" "$csha1path" "$tsha1path" \
                > mtimes &&
        compare_mtimes < mtimes
 '
@@ -103,7 +103,7 @@ test_expect_success 'do not bother loosening old objects' '
        git prune-packed &&
        git cat-file -p $obj1 &&
        git cat-file -p $obj2 &&
-       test-chmtime =-86400 .git/objects/pack/pack-$pack2.pack &&
+       test-tool chmtime =-86400 .git/objects/pack/pack-$pack2.pack &&
        git repack -A -d --unpack-unreachable=1.hour.ago &&
        git cat-file -p $obj1 &&
        test_must_fail git cat-file -p $obj2
@@ -117,7 +117,7 @@ test_expect_success 'keep packed objects found only in index' '
        git reset HEAD^ &&
        git reflog expire --expire=now --all &&
        git add file &&
-       test-chmtime =-86400 .git/objects/pack/* &&
+       test-tool chmtime =-86400 .git/objects/pack/* &&
        git gc --prune=1.hour.ago &&
        git cat-file blob :file
 '
index 0059a1f837882c504e717135c9c92bc5b1d7f62c..0c685d35986eebf4dd72861b650c82fb6b515b51 100755 (executable)
@@ -12,7 +12,7 @@ test_expect_success GETTEXT_LOCALE 'setup' '
 '
 
 test_have_prereq GETTEXT_LOCALE &&
-test-regex "HALLÓ" "Halló" ICASE &&
+test-tool regex "HALLÓ" "Halló" ICASE &&
 test_set_prereq REGEX_LOCALE
 
 test_expect_success REGEX_LOCALE 'grep literal string, no -F' '
diff --git a/t/t8012-blame-colors.sh b/t/t8012-blame-colors.sh
new file mode 100755 (executable)
index 0000000..ed38f74
--- /dev/null
@@ -0,0 +1,48 @@
+#!/bin/sh
+
+test_description='colored git blame'
+. ./test-lib.sh
+
+PROG='git blame -c'
+. "$TEST_DIRECTORY"/annotate-tests.sh
+
+test_expect_success 'colored blame colors contiguous lines' '
+       git -c color.blame.repeatedLines=yellow blame --color-lines --abbrev=12 hello.c >actual.raw &&
+       git -c color.blame.repeatedLines=yellow -c blame.coloring=repeatedLines blame --abbrev=12 hello.c >actual.raw.2 &&
+       test_cmp actual.raw actual.raw.2 &&
+       test_decode_color <actual.raw >actual &&
+       grep "<YELLOW>" <actual >darkened &&
+       grep "(F" darkened > F.expect &&
+       grep "(H" darkened > H.expect &&
+       test_line_count = 2 F.expect &&
+       test_line_count = 3 H.expect
+'
+
+test_expect_success 'color by age consistently colors old code' '
+       git blame --color-by-age hello.c >actual.raw &&
+       git -c blame.coloring=highlightRecent blame hello.c >actual.raw.2 &&
+       test_cmp actual.raw actual.raw.2 &&
+       test_decode_color <actual.raw >actual &&
+       grep "<BLUE>" <actual >colored &&
+       test_line_count = 10 colored
+'
+
+test_expect_success 'blame color by age: new code is different' '
+       cat >>hello.c <<-EOF &&
+               void qfunc();
+       EOF
+       git add hello.c &&
+       GIT_AUTHOR_DATE="" git commit -m "new commit" &&
+
+       git -c color.blame.highlightRecent="yellow,1 month ago, cyan" blame --color-by-age hello.c >actual.raw &&
+       test_decode_color <actual.raw >actual &&
+
+       grep "<YELLOW>" <actual >colored &&
+       test_line_count = 10 colored &&
+
+       grep "<CYAN>" <actual >colored &&
+       test_line_count = 1 colored &&
+       grep qfunc colored
+'
+
+test_done
index b28a028f5503508a4a09c6a07950027d253a1846..7e8894a4a70648fd12d3ab4425f1beac2c3e4641 100755 (executable)
@@ -4,7 +4,7 @@ test_description='check that example code compiles and runs'
 . ./test-lib.sh
 
 test_expect_success 'decorate' '
-       test-example-decorate
+       test-tool example-decorate
 '
 
 test_done
index 8eaaca6f9906879f16f3658b0e04796086d4c435..0b20b07e689897326c0060ec2181f6a09fca9797 100755 (executable)
@@ -473,7 +473,7 @@ test_expect_failure 'change file mode but keep old content' '
        {
                git rev-list HEAD |
                git diff-tree --root --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual &&
        git show HEAD:greeting >actual.blob &&
        git show HEAD^:greeting >actual.target &&
@@ -573,7 +573,7 @@ test_expect_success 'NUL in log message, file content, and property name' '
        {
                git rev-list HEAD |
                git diff-tree --root --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual &&
        {
                git cat-file commit HEAD | nul_to_q &&
@@ -659,7 +659,7 @@ test_expect_success 'change file mode and reiterate content' '
        {
                git rev-list HEAD |
                git diff-tree --root --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual &&
        git show HEAD:greeting >actual.blob &&
        git show HEAD^:greeting >actual.target &&
@@ -792,7 +792,7 @@ test_expect_success 'property deltas supported' '
        {
                git rev-list HEAD |
                git diff-tree --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual &&
        test_cmp expect actual
 '
@@ -846,7 +846,7 @@ test_expect_success 'properties on /' '
        {
                git rev-list HEAD |
                git diff-tree --root --always --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual &&
        test_cmp expect actual
 '
@@ -931,7 +931,7 @@ test_expect_success 'deltas for typechange' '
        {
                git rev-list HEAD |
                git diff-tree --root --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual &&
        test_cmp expect actual
 '
@@ -1030,7 +1030,7 @@ test_expect_success 'deltas need not consume the whole preimage' '
        {
                git rev-list HEAD |
                git diff-tree --root --stdin |
-               sed "s/$_x40/OBJID/g"
+               sed "s/$OID_REGEX/OBJID/g"
        } >actual &&
        test_cmp expect actual &&
        git show HEAD:postimage >actual.3 &&
index 8a8ba65a2ae583aa5d0b0526e604a8f9613b5a5e..c937330a5f3a7f6b5c4d8e406564bd88dd0c889b 100755 (executable)
@@ -288,12 +288,12 @@ test_expect_success 'able to dcommit to a subdirectory' '
 
 test_expect_success 'dcommit should not fail with a touched file' '
        test_commit "commit-new-file-foo2" foo2 &&
-       test-chmtime =-60 foo &&
+       test-tool chmtime =-60 foo &&
        git svn dcommit
 '
 
 test_expect_success 'rebase should not fail with a touched file' '
-       test-chmtime =-60 foo &&
+       test-tool chmtime =-60 foo &&
        git svn rebase
 '
 
index cd480edf1606fda8d973ee3decb8e18e03356153..9c49b6c1fe24335c6bcae777d60e14cdf96fd306 100755 (executable)
@@ -33,8 +33,8 @@ test_expect_success 'init and fetch a moved directory' '
        git svn fetch -i thunk &&
        test "$(git rev-parse --verify refs/remotes/thunk@2)" \
           = "$(git rev-parse --verify refs/remotes/thunk~1)" &&
-       test "$(git cat-file blob refs/remotes/thunk:readme |\
-                sed -n -e "3p")" = goodbye &&
+       git cat-file blob refs/remotes/thunk:readme >actual &&
+       test "$(sed -n -e "3p" actual)" = goodbye &&
        test -z "$(git config --get svn-remote.svn.fetch \
                 "^trunk:refs/remotes/thunk@2$")"
        '
@@ -48,8 +48,8 @@ test_expect_success 'init and fetch from one svn-remote' '
         git svn fetch -i svn/thunk &&
        test "$(git rev-parse --verify refs/remotes/svn/trunk)" \
           = "$(git rev-parse --verify refs/remotes/svn/thunk~1)" &&
-       test "$(git cat-file blob refs/remotes/svn/thunk:readme |\
-                sed -n -e "3p")" = goodbye
+       git cat-file blob refs/remotes/svn/thunk:readme >actual &&
+       test "$(sed -n -e "3p" actual)" = goodbye
         '
 
 test_expect_success 'follow deleted parent' '
@@ -107,7 +107,8 @@ test_expect_success 'follow deleted directory' '
        git svn init --minimize-url -i glob "$svnrepo"/glob &&
        git svn fetch -i glob &&
        test "$(git cat-file blob refs/remotes/glob:blob/bye)" = hi &&
-       test "$(git ls-tree refs/remotes/glob | wc -l )" -eq 1
+       git ls-tree refs/remotes/glob >actual &&
+       test_line_count = 1 actual
        '
 
 # ref: r9270 of the Subversion repository: (http://svn.collab.net/repos/svn)
@@ -204,8 +205,9 @@ test_expect_success "follow-parent is atomic" '
 test_expect_success "track multi-parent paths" '
        svn_cmd cp -m "resurrect /glob" "$svnrepo"/r9270 "$svnrepo"/glob &&
        git svn multi-fetch &&
-       test $(git cat-file commit refs/remotes/glob | \
-              grep "^parent " | wc -l) -eq 2
+       git cat-file commit refs/remotes/glob >actual &&
+       grep "^parent " actual >actual2 &&
+       test_line_count = 2 actual2
        '
 
 test_expect_success "multi-fetch continues to work" "
@@ -213,7 +215,8 @@ test_expect_success "multi-fetch continues to work" "
        "
 
 test_expect_success "multi-fetch works off a 'clean' repository" '
-       rm -r "$GIT_DIR/svn" "$GIT_DIR/refs/remotes" "$GIT_DIR/logs" &&
+       rm -rf "$GIT_DIR/svn" "$GIT_DIR/refs/remotes" &&
+       git reflog expire --all --expire=all &&
        mkdir "$GIT_DIR/svn" &&
        git svn multi-fetch
        '
index a94286c8ec89823805989f4363072417e9c20165..6990f64364200c75f46d9f6ee3d67ebea3549d5b 100755 (executable)
@@ -47,8 +47,8 @@ test_expect_success 'test refspec globbing' '
        git config --add svn-remote.svn.tags\
                         "tags/*/src/a:refs/remotes/tags/*" &&
        git svn multi-fetch &&
-       git log --pretty=oneline refs/remotes/tags/end | \
-           sed -e "s/^.\{41\}//" > output.end &&
+       git log --pretty=oneline refs/remotes/tags/end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.end &&
        test_cmp expect.end output.end &&
        test "$(git rev-parse refs/remotes/tags/end~1)" = \
                "$(git rev-parse refs/remotes/branches/start)" &&
@@ -75,14 +75,16 @@ test_expect_success 'test left-hand-side only globbing' '
                svn_cmd commit -m "try to try"
        ) &&
        git svn fetch two &&
-       test $(git rev-list refs/remotes/two/tags/end | wc -l) -eq 6 &&
-       test $(git rev-list refs/remotes/two/branches/start | wc -l) -eq 3 &&
+       git rev-list refs/remotes/two/tags/end >actual &&
+       test_line_count = 6 actual &&
+       git rev-list refs/remotes/two/branches/start >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/two/branches/start~2) = \
             $(git rev-parse refs/remotes/two/trunk) &&
        test $(git rev-parse refs/remotes/two/tags/end~3) = \
             $(git rev-parse refs/remotes/two/branches/start) &&
-       git log --pretty=oneline refs/remotes/two/tags/end | \
-           sed -e "s/^.\{41\}//" > output.two &&
+       git log --pretty=oneline refs/remotes/two/tags/end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.two &&
        test_cmp expect.two output.two
        '
 
index 8d99e848d47634ea340885fde48bc798a2c0b7a2..c1e7542a371330ecd6b27899cf3f6d4d07d78a29 100755 (executable)
@@ -47,8 +47,8 @@ test_expect_success 'test refspec globbing' '
        git config --add svn-remote.svn.tags\
                         "tags/*/src/a:refs/remotes/tags/*" &&
        git svn multi-fetch &&
-       git log --pretty=oneline refs/remotes/tags/end | \
-           sed -e "s/^.\{41\}//" > output.end &&
+       git log --pretty=oneline refs/remotes/tags/end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.end &&
        test_cmp expect.end output.end &&
        test "$(git rev-parse refs/remotes/tags/end~1)" = \
                "$(git rev-parse refs/remotes/branches/v1/start)" &&
@@ -75,14 +75,16 @@ test_expect_success 'test left-hand-side only globbing' '
                svn_cmd commit -m "try to try"
        ) &&
        git svn fetch two &&
-       test $(git rev-list refs/remotes/two/tags/end | wc -l) -eq 6 &&
-       test $(git rev-list refs/remotes/two/branches/v1/start | wc -l) -eq 3 &&
+       git rev-list refs/remotes/two/tags/end >actual &&
+       test_line_count = 6 actual &&
+       git rev-list refs/remotes/two/branches/v1/start >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/two/branches/v1/start~2) = \
             $(git rev-parse refs/remotes/two/trunk) &&
        test $(git rev-parse refs/remotes/two/tags/end~3) = \
             $(git rev-parse refs/remotes/two/branches/v1/start) &&
-       git log --pretty=oneline refs/remotes/two/tags/end | \
-           sed -e "s/^.\{41\}//" > output.two &&
+       git log --pretty=oneline refs/remotes/two/tags/end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.two &&
        test_cmp expect.two output.two
        '
 cat > expect.four <<EOF
@@ -124,14 +126,16 @@ test_expect_success 'test another branch' '
        git config --add svn-remote.four.tags \
                         "tags/*:refs/remotes/four/tags/*" &&
        git svn fetch four &&
-       test $(git rev-list refs/remotes/four/tags/next | wc -l) -eq 5 &&
-       test $(git rev-list refs/remotes/four/branches/v2/start | wc -l) -eq 3 &&
+       git rev-list refs/remotes/four/tags/next >actual &&
+       test_line_count = 5 actual &&
+       git rev-list refs/remotes/four/branches/v2/start >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/four/branches/v2/start~2) = \
             $(git rev-parse refs/remotes/four/trunk) &&
        test $(git rev-parse refs/remotes/four/tags/next~2) = \
             $(git rev-parse refs/remotes/four/branches/v2/start) &&
-       git log --pretty=oneline refs/remotes/four/tags/next | \
-           sed -e "s/^.\{41\}//" > output.four &&
+       git log --pretty=oneline refs/remotes/four/tags/next >actual &&
+       sed -e "s/^.\{41\}//" actual >output.four &&
        test_cmp expect.four output.four
        '
 
index dde0a3c2229abab27d1592e740db35ebfed544aa..ad37d980c91dd303ba975bc501748e05fd82efe5 100755 (executable)
@@ -21,37 +21,37 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89
 
 bar_url=http://mayonaise/svnrepo/bar
 test_expect_success 'verify metadata for /bar' "
-       git cat-file commit refs/remotes/bar | \
-          grep '^git-svn-id: $bar_url@12 $uuid$' &&
-       git cat-file commit refs/remotes/bar~1 | \
-          grep '^git-svn-id: $bar_url@11 $uuid$' &&
-       git cat-file commit refs/remotes/bar~2 | \
-          grep '^git-svn-id: $bar_url@10 $uuid$' &&
-       git cat-file commit refs/remotes/bar~3 | \
-          grep '^git-svn-id: $bar_url@9 $uuid$' &&
-       git cat-file commit refs/remotes/bar~4 | \
-          grep '^git-svn-id: $bar_url@6 $uuid$' &&
-       git cat-file commit refs/remotes/bar~5 | \
-          grep '^git-svn-id: $bar_url@1 $uuid$'
+       git cat-file commit refs/remotes/bar >actual &&
+       grep '^git-svn-id: $bar_url@12 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~1 >actual &&
+       grep '^git-svn-id: $bar_url@11 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~2 >actual &&
+       grep '^git-svn-id: $bar_url@10 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~3 >actual &&
+       grep '^git-svn-id: $bar_url@9 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~4 >actual &&
+       grep '^git-svn-id: $bar_url@6 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~5 >actual &&
+       grep '^git-svn-id: $bar_url@1 $uuid$' actual
        "
 
 e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e
 test_expect_success 'verify metadata for /dir/a/b/c/d/e' "
-       git cat-file commit refs/remotes/e | \
-          grep '^git-svn-id: $e_url@1 $uuid$'
+       git cat-file commit refs/remotes/e >actual &&
+       grep '^git-svn-id: $e_url@1 $uuid$' actual
        "
 
 dir_url=http://mayonaise/svnrepo/dir
 test_expect_success 'verify metadata for /dir' "
-       git cat-file commit refs/remotes/dir | \
-          grep '^git-svn-id: $dir_url@2 $uuid$' &&
-       git cat-file commit refs/remotes/dir~1 | \
-          grep '^git-svn-id: $dir_url@1 $uuid$'
+       git cat-file commit refs/remotes/dir >actual &&
+       grep '^git-svn-id: $dir_url@2 $uuid$' actual &&
+       git cat-file commit refs/remotes/dir~1 >actual &&
+       grep '^git-svn-id: $dir_url@1 $uuid$' actual
        "
 
 test_expect_success 'find commit based on SVN revision number' "
-        git svn find-rev r12 |
-           grep $(git rev-parse HEAD)
+       git svn find-rev r12 >actual &&
+       grep $(git rev-parse HEAD) actual
         "
 
 test_expect_success 'empty rebase' "
index 22b6e5ee7d8c274b7fe60c9f10de45eaf4d3c385..6c9307355137fe86ed16552113f0d60b007e3eca 100755 (executable)
@@ -20,32 +20,32 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89
 
 bar_url=http://mayonaise/svnrepo/bar
 test_expect_success 'verify metadata for /bar' "
-       git cat-file commit refs/remotes/bar | \
-          grep '^git-svn-id: $bar_url@12 $uuid$' &&
-       git cat-file commit refs/remotes/bar~1 | \
-          grep '^git-svn-id: $bar_url@11 $uuid$' &&
-       git cat-file commit refs/remotes/bar~2 | \
-          grep '^git-svn-id: $bar_url@10 $uuid$' &&
-       git cat-file commit refs/remotes/bar~3 | \
-          grep '^git-svn-id: $bar_url@9 $uuid$' &&
-       git cat-file commit refs/remotes/bar~4 | \
-          grep '^git-svn-id: $bar_url@6 $uuid$' &&
-       git cat-file commit refs/remotes/bar~5 | \
-          grep '^git-svn-id: $bar_url@1 $uuid$'
+       git cat-file commit refs/remotes/bar >actual &&
+       grep '^git-svn-id: $bar_url@12 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~1 >actual &&
+       grep '^git-svn-id: $bar_url@11 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~2 >actual &&
+       grep '^git-svn-id: $bar_url@10 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~3 >actual &&
+       grep '^git-svn-id: $bar_url@9 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~4 >actual &&
+       grep '^git-svn-id: $bar_url@6 $uuid$' actual &&
+       git cat-file commit refs/remotes/bar~5 >actual &&
+       grep '^git-svn-id: $bar_url@1 $uuid$' actual
        "
 
 e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e
 test_expect_success 'verify metadata for /dir/a/b/c/d/e' "
-       git cat-file commit refs/remotes/e | \
-          grep '^git-svn-id: $e_url@1 $uuid$'
+       git cat-file commit refs/remotes/e >actual &&
+       grep '^git-svn-id: $e_url@1 $uuid$' actual
        "
 
 dir_url=http://mayonaise/svnrepo/dir
 test_expect_success 'verify metadata for /dir' "
-       git cat-file commit refs/remotes/dir | \
-          grep '^git-svn-id: $dir_url@2 $uuid$' &&
-       git cat-file commit refs/remotes/dir~1 | \
-          grep '^git-svn-id: $dir_url@1 $uuid$'
+       git cat-file commit refs/remotes/dir >actual &&
+       grep '^git-svn-id: $dir_url@2 $uuid$' actual &&
+       git cat-file commit refs/remotes/dir~1 >actual &&
+       grep '^git-svn-id: $dir_url@1 $uuid$' actual
        "
 
 test_done
index 50bca62def6b0632cd89d1c0cfb2d98b76e6aa1d..32317d6bca5f45314a46082ecd9aa68061853904 100755 (executable)
@@ -68,7 +68,8 @@ test_debug 'gitk --all & sleep 1'
 test_expect_success 'verify pre-merge ancestry' "
        test x\$(git rev-parse --verify refs/heads/svn^2) = \
             x\$(git rev-parse --verify refs/heads/merge) &&
-       git cat-file commit refs/heads/svn^ | grep '^friend$'
+       git cat-file commit refs/heads/svn^ >actual &&
+       grep '^friend$' actual
        "
 
 test_expect_success 'git svn dcommit merges' "
@@ -82,12 +83,13 @@ test_expect_success 'verify post-merge ancestry' "
             x\$(git rev-parse --verify refs/remotes/origin/trunk) &&
        test x\$(git rev-parse --verify refs/heads/svn^2) = \
             x\$(git rev-parse --verify refs/heads/merge) &&
-       git cat-file commit refs/heads/svn^ | grep '^friend$'
+       git cat-file commit refs/heads/svn^ >actual &&
+       grep '^friend$' actual
        "
 
 test_expect_success 'verify merge commit message' "
-       git rev-list --pretty=raw -1 refs/heads/svn | \
-         grep \"    Merge branch 'merge' into svn\"
+       git rev-list --pretty=raw -1 refs/heads/svn >actual &&
+       grep \"    Merge branch 'merge' into svn\" actual
        "
 
 test_done
index 41264818ccdd85abb4b0a17c8a508d4bcbfe57f5..d8262854bbee335aec293b8f75b9979e60b91171 100755 (executable)
@@ -26,11 +26,12 @@ test_expect_success 'start import with incomplete authors file' '
 test_expect_success 'imported 2 revisions successfully' '
        (
                cd x
-               test "$(git rev-list refs/remotes/git-svn | wc -l)" -eq 2 &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn | \
-                 grep "^author BBBBBBB BBBBBBB <bb@example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 | \
-                 grep "^author AAAAAAA AAAAAAA <aa@example\.com> "
+               git rev-list refs/remotes/git-svn >actual &&
+               test_line_count = 2 actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn >actual &&
+               grep "^author BBBBBBB BBBBBBB <bb@example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 >actual &&
+               grep "^author AAAAAAA AAAAAAA <aa@example\.com> " actual
        )
        '
 
@@ -43,11 +44,12 @@ test_expect_success 'continues to import once authors have been added' '
        (
                cd x
                git svn fetch --authors-file=../svn-authors &&
-               test "$(git rev-list refs/remotes/git-svn | wc -l)" -eq 4 &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn | \
-                 grep "^author DDDDDDD DDDDDDD <dd@example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 | \
-                 grep "^author CCCCCCC CCCCCCC <cc@example\.com> "
+               git rev-list refs/remotes/git-svn >actual &&
+               test_line_count = 4 actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn >actual &&
+               grep "^author DDDDDDD DDDDDDD <dd@example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 >actual &&
+               grep "^author CCCCCCC CCCCCCC <cc@example\.com> " actual
        )
        '
 
@@ -102,12 +104,28 @@ test_expect_success !MINGW 'fresh clone with svn.authors-file in config' '
                test x"$HOME"/svn-authors = x"$(git config svn.authorsfile)" &&
                git svn clone "$svnrepo" gitconfig.clone &&
                cd gitconfig.clone &&
-               nr_ex=$(git log | grep "^Author:.*example.com" | wc -l) &&
-               nr_rev=$(git rev-list HEAD | wc -l) &&
+               git log >actual &&
+               nr_ex=$(grep "^Author:.*example.com" actual | wc -l) &&
+               git rev-list HEAD >actual &&
+               nr_rev=$(wc -l <actual) &&
                test $nr_rev -eq $nr_ex
        )
 '
 
+cat >> svn-authors <<EOF
+ff = FFFFFFF FFFFFFF <>
+EOF
+
+test_expect_success 'authors-file imported user without email' '
+       svn_cmd mkdir -m aa/branches/ff --username ff "$svnrepo/aa/branches/ff" &&
+       (
+               cd aa-work &&
+               git svn fetch --authors-file=../svn-authors &&
+               git rev-list -1 --pretty=raw refs/remotes/origin/ff | \
+                 grep "^author FFFFFFF FFFFFFF <> "
+       )
+       '
+
 test_debug 'GIT_DIR=gitconfig.clone/.git git log'
 
 test_done
index 7d7e9d46bc6bf40f52efffede6b369f052c46843..93ef44fae8f28149344b9125530807ed49727e68 100755 (executable)
@@ -9,7 +9,9 @@ test_description='git svn authors prog tests'
 
 write_script svn-authors-prog "$PERL_PATH" <<-\EOF
        $_ = shift;
-       if (s/-sub$//)  {
+       if (s/-hermit//) {
+               print "$_ <>\n";
+       } elsif (s/-sub$//)  {
                print "$_ <$_\@sub.example.com>\n";
        } else {
                print "$_ <$_\@example.com>\n";
@@ -37,44 +39,67 @@ test_expect_success 'import authors with prog and file' '
 test_expect_success 'imported 6 revisions successfully' '
        (
                cd x
-               test "$(git rev-list refs/remotes/git-svn | wc -l)" -eq 6
+               git rev-list refs/remotes/git-svn >actual &&
+               test_line_count = 6 actual
        )
 '
 
 test_expect_success 'authors-prog ran correctly' '
        (
                cd x
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 | \
-                 grep "^author ee-foo <ee-foo@example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~2 | \
-                 grep "^author dd <dd@sub\.example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~3 | \
-                 grep "^author cc <cc@sub\.example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~4 | \
-                 grep "^author bb <bb@example\.com> " &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn~5 | \
-                 grep "^author aa <aa@example\.com> "
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~1 >actual &&
+               grep "^author ee-foo <ee-foo@example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~2 >actual &&
+               grep "^author dd <dd@sub\.example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~3 >actual &&
+               grep "^author cc <cc@sub\.example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~4 >actual &&
+               grep "^author bb <bb@example\.com> " actual &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn~5 >actual &&
+               grep "^author aa <aa@example\.com> " actual
        )
 '
 
 test_expect_success 'authors-file overrode authors-prog' '
        (
                cd x
-               git rev-list -1 --pretty=raw refs/remotes/git-svn | \
-                 grep "^author FFFFFFF FFFFFFF <fFf@other\.example\.com> "
+               git rev-list -1 --pretty=raw refs/remotes/git-svn >actual &&
+               grep "^author FFFFFFF FFFFFFF <fFf@other\.example\.com> " actual
        )
 '
 
 git --git-dir=x/.git config --unset svn.authorsfile
 git --git-dir=x/.git config --unset svn.authorsprog
 
+test_expect_success 'authors-prog imported user without email' '
+       svn mkdir -m gg --username gg-hermit "$svnrepo"/gg &&
+       (
+               cd x &&
+               git svn fetch --authors-prog=../svn-authors-prog &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn | \
+                 grep "^author gg <> "
+       )
+'
+
+test_expect_success 'imported without authors-prog and authors-file' '
+       svn mkdir -m hh --username hh "$svnrepo"/hh &&
+       (
+               uuid=$(svn info "$svnrepo" |
+                       sed -n "s/^Repository UUID: //p") &&
+               cd x &&
+               git svn fetch &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn | \
+                 grep "^author hh <hh@$uuid> "
+       )
+'
+
 test_expect_success 'authors-prog handled special characters in username' '
        svn mkdir -m bad --username "xyz; touch evil" "$svnrepo"/bad &&
        (
                cd x &&
                git svn --authors-prog=../svn-authors-prog fetch &&
-               git rev-list -1 --pretty=raw refs/remotes/git-svn |
-               grep "^author xyz; touch evil <xyz; touch evil@example\.com> " &&
+               git rev-list -1 --pretty=raw refs/remotes/git-svn >actual &&
+               grep "^author xyz; touch evil <xyz; touch evil@example\.com> " actual &&
                ! test -f evil
        )
 '
index 372ef156850098928ac1ed402ab2228460af3c00..8cb2b5c69cfc89c4613fc3f7e4f2153a251433c7 100755 (executable)
@@ -16,10 +16,10 @@ test_expect_success 'load svn repo' "
        "
 
 test_expect_success 'verify uuid' "
-       git cat-file commit refs/remotes/git-svn~0 | \
-          grep '^git-svn-id: .*@2 $uuid$' &&
-       git cat-file commit refs/remotes/git-svn~1 | \
-          grep '^git-svn-id: .*@1 $uuid$'
+       git cat-file commit refs/remotes/git-svn~0 >actual &&
+       grep '^git-svn-id: .*@2 $uuid$' actual &&
+       git cat-file commit refs/remotes/git-svn~1 >actual &&
+       grep '^git-svn-id: .*@1 $uuid$' actual
        "
 
 test_done
index 8b22f2272cca47cd9187accdaed3ce1f12b6c9e1..bdf6e849993bff79a5e04c5b8a1d7df77118091f 100755 (executable)
@@ -48,8 +48,8 @@ test_expect_success 'test refspec prefixed globbing' '
        git config --add svn-remote.svn.tags\
                         "tags/t_*/src/a:refs/remotes/tags/t_*" &&
        git svn multi-fetch &&
-       git log --pretty=oneline refs/remotes/tags/t_end | \
-           sed -e "s/^.\{41\}//" >output.end &&
+       git log --pretty=oneline refs/remotes/tags/t_end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.end &&
        test_cmp expect.end output.end &&
        test "$(git rev-parse refs/remotes/tags/t_end~1)" = \
                "$(git rev-parse refs/remotes/branches/b_start)" &&
@@ -78,14 +78,16 @@ test_expect_success 'test left-hand-side only prefixed globbing' '
                svn_cmd commit -m "try to try"
        ) &&
        git svn fetch two &&
-       test $(git rev-list refs/remotes/two/tags/t_end | wc -l) -eq 6 &&
-       test $(git rev-list refs/remotes/two/branches/b_start | wc -l) -eq 3 &&
+       git rev-list refs/remotes/two/tags/t_end >actual &&
+       test_line_count = 6 actual &&
+       git rev-list refs/remotes/two/branches/b_start >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/two/branches/b_start~2) = \
             $(git rev-parse refs/remotes/two/trunk) &&
        test $(git rev-parse refs/remotes/two/tags/t_end~3) = \
             $(git rev-parse refs/remotes/two/branches/b_start) &&
-       git log --pretty=oneline refs/remotes/two/tags/t_end | \
-           sed -e "s/^.\{41\}//" >output.two &&
+       git log --pretty=oneline refs/remotes/two/tags/t_end >actual &&
+       sed -e "s/^.\{41\}//" actual >output.two &&
        test_cmp expect.two output.two
        '
 
@@ -118,14 +120,16 @@ test_expect_success 'test prefixed globs match just prefix' '
                svn_cmd up
        ) &&
        git svn fetch three &&
-       test $(git rev-list refs/remotes/three/branches/b_ | wc -l) -eq 2 &&
-       test $(git rev-list refs/remotes/three/tags/t_ | wc -l) -eq 3 &&
+       git rev-list refs/remotes/three/branches/b_ >actual &&
+       test_line_count = 2 actual &&
+       git rev-list refs/remotes/three/tags/t_ >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/three/branches/b_~1) = \
             $(git rev-parse refs/remotes/three/trunk) &&
        test $(git rev-parse refs/remotes/three/tags/t_~1) = \
             $(git rev-parse refs/remotes/three/branches/b_) &&
-       git log --pretty=oneline refs/remotes/three/tags/t_ | \
-           sed -e "s/^.\{41\}//" >output.three &&
+       git log --pretty=oneline refs/remotes/three/tags/t_ >actual &&
+       sed -e "s/^.\{41\}//" actual >output.three &&
        test_cmp expect.three output.three
        '
 
@@ -186,14 +190,16 @@ test_expect_success 'test globbing in the middle of the word' '
                svn_cmd up
        ) &&
        git svn fetch five &&
-       test $(git rev-list refs/remotes/five/branches/abcde | wc -l) -eq 2 &&
-       test $(git rev-list refs/remotes/five/tags/fghij | wc -l) -eq 3 &&
+       git rev-list refs/remotes/five/branches/abcde >actual &&
+       test_line_count = 2 actual &&
+       git rev-list refs/remotes/five/tags/fghij >actual &&
+       test_line_count = 3 actual &&
        test $(git rev-parse refs/remotes/five/branches/abcde~1) = \
             $(git rev-parse refs/remotes/five/trunk) &&
        test $(git rev-parse refs/remotes/five/tags/fghij~1) = \
             $(git rev-parse refs/remotes/five/branches/abcde) &&
-       git log --pretty=oneline refs/remotes/five/tags/fghij | \
-           sed -e "s/^.\{41\}//" >output.five &&
+       git log --pretty=oneline refs/remotes/five/tags/fghij >actual &&
+       sed -e "s/^.\{41\}//" actual >output.five &&
        test_cmp expect.five output.five
        '
 
index 7eb08941cfb9e10006072ea44782b9e5e80091df..c4a06c587f7ad9f7d524420628a5c86475bfe390 100755 (executable)
@@ -1185,7 +1185,7 @@ test_expect_success PIPE 'N: empty directory reads as missing' '
        test_cmp expect.response response &&
        git rev-list read-empty |
        git diff-tree -r --root --stdin |
-       sed "s/$_x40/OBJNAME/g" >actual &&
+       sed "s/$OID_REGEX/OBJNAME/g" >actual &&
        test_cmp expect actual
 '
 
@@ -1271,7 +1271,7 @@ test_expect_success 'N: delete directory by copying' '
        git fast-import <input &&
        git rev-list N-delete |
                git diff-tree -r --stdin --root --always |
-               sed -e "s/$_x40/OBJID/g" >actual &&
+               sed -e "s/$OID_REGEX/OBJID/g" >actual &&
        test_cmp expect actual
 '
 
@@ -2632,7 +2632,7 @@ test_expect_success 'R: terminating "done" within commit' '
        EOF
        git rev-list done-ends |
        git diff-tree -r --stdin --root --always |
-       sed -e "s/$_x40/OBJID/g" >actual &&
+       sed -e "s/$OID_REGEX/OBJID/g" >actual &&
        test_cmp expect actual
 '
 
@@ -2684,7 +2684,7 @@ test_expect_success 'R: corrupt lines do not mess marks file' '
 ##
 test_expect_success 'R: blob bigger than threshold' '
        blobsize=$((2*1024*1024 + 53)) &&
-       test-genrandom bar $blobsize >expect &&
+       test-tool genrandom bar $blobsize >expect &&
        cat >input <<-INPUT_END &&
        commit refs/heads/big-file
        committer $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> $GIT_COMMITTER_DATE
index 15b167d29d9acff7d48070d6f73e62099b63106d..ef1e01805be86a4574ec8ea84bfc123baa9d67f5 100755 (executable)
@@ -43,20 +43,20 @@ test_expect_success 'fast-export | fast-import' '
        MUSS=$(git rev-parse --verify muss) &&
        mkdir new &&
        git --git-dir=new/.git init &&
-       git fast-export --all |
+       git fast-export --all >actual &&
        (cd new &&
         git fast-import &&
         test $MASTER = $(git rev-parse --verify refs/heads/master) &&
         test $REIN = $(git rev-parse --verify refs/tags/rein) &&
         test $WER = $(git rev-parse --verify refs/heads/wer) &&
-        test $MUSS = $(git rev-parse --verify refs/tags/muss))
+        test $MUSS = $(git rev-parse --verify refs/tags/muss)) <actual
 
 '
 
 test_expect_success 'fast-export master~2..master' '
 
-       git fast-export master~2..master |
-               sed "s/master/partial/" |
+       git fast-export master~2..master >actual &&
+       sed "s/master/partial/" actual |
                (cd new &&
                 git fast-import &&
                 test $MASTER != $(git rev-parse --verify refs/heads/partial) &&
@@ -74,11 +74,12 @@ test_expect_success 'iso-8859-1' '
        test_tick &&
        echo rosten >file &&
        git commit -s -m den file &&
-       git fast-export wer^..wer |
-               sed "s/wer/i18n/" |
+       git fast-export wer^..wer >iso8859-1.fi &&
+       sed "s/wer/i18n/" iso8859-1.fi |
                (cd new &&
                 git fast-import &&
-                git cat-file commit i18n | grep "Áéí óú")
+                git cat-file commit i18n >actual &&
+                grep "Áéí óú" actual)
 
 '
 test_expect_success 'import/export-marks' '
@@ -87,20 +88,14 @@ test_expect_success 'import/export-marks' '
        git fast-export --export-marks=tmp-marks HEAD &&
        test -s tmp-marks &&
        test_line_count = 3 tmp-marks &&
-       test $(
-               git fast-export --import-marks=tmp-marks\
-               --export-marks=tmp-marks HEAD |
-               grep ^commit |
-               wc -l) \
-       -eq 0 &&
+       git fast-export --import-marks=tmp-marks \
+               --export-marks=tmp-marks HEAD >actual &&
+       test $(grep ^commit actual | wc -l) -eq 0 &&
        echo change > file &&
        git commit -m "last commit" file &&
-       test $(
-               git fast-export --import-marks=tmp-marks \
-               --export-marks=tmp-marks HEAD |
-               grep ^commit\  |
-               wc -l) \
-       -eq 1 &&
+       git fast-export --import-marks=tmp-marks \
+               --export-marks=tmp-marks HEAD >actual &&
+       test $(grep ^commit\  actual | wc -l) -eq 1 &&
        test_line_count = 4 tmp-marks
 
 '
@@ -184,7 +179,7 @@ test_expect_success 'submodule fast-export | fast-import' '
        rm -rf new &&
        mkdir new &&
        git --git-dir=new/.git init &&
-       git fast-export --signed-tags=strip --all |
+       git fast-export --signed-tags=strip --all >actual &&
        (cd new &&
         git fast-import &&
         test "$SUBENT1" = "$(git ls-tree refs/heads/master^ sub)" &&
@@ -192,7 +187,7 @@ test_expect_success 'submodule fast-export | fast-import' '
         git checkout master &&
         git submodule init &&
         git submodule update &&
-        cmp sub/file ../sub/file)
+        cmp sub/file ../sub/file) <actual
 
 '
 
@@ -367,12 +362,14 @@ test_expect_success 'path limiting with import-marks does not lose unmodified fi
        echo more content >> file &&
        test_tick &&
        git commit -mnext file &&
-       git fast-export --import-marks=marks simple -- file file0 | grep file0
+       git fast-export --import-marks=marks simple -- file file0 >actual &&
+       grep file0 actual
 '
 
 test_expect_success 'full-tree re-shows unmodified files'        '
        git checkout -f simple &&
-       test $(git fast-export --full-tree simple | grep -c file0) -eq 3
+       git fast-export --full-tree simple >actual &&
+       test $(grep -c file0 actual) -eq 3
 '
 
 test_expect_success 'set-up a few more tags for tag export tests' '
@@ -506,8 +503,8 @@ test_expect_success 'refs are updated even if no commits need to be exported' '
 '
 
 test_expect_success 'use refspec' '
-       git fast-export --refspec refs/heads/master:refs/heads/foobar master | \
-               grep "^commit " | sort | uniq > actual &&
+       git fast-export --refspec refs/heads/master:refs/heads/foobar master >actual2 &&
+       grep "^commit " actual2 | sort | uniq >actual &&
        echo "commit refs/heads/foobar" > expected &&
        test_cmp expected actual
 '
@@ -535,10 +532,29 @@ test_expect_success 'when using -C, do not declare copy when source of copy is a
        git -C src commit -m 2nd_commit &&
 
        test_create_repo dst &&
-       git -C src fast-export --all -C | git -C dst fast-import &&
+       git -C src fast-export --all -C >actual &&
+       git -C dst fast-import <actual &&
        git -C src show >expected &&
        git -C dst show >actual &&
        test_cmp expected actual
 '
 
+test_expect_success 'merge commit gets exported with --import-marks' '
+       test_create_repo merging &&
+       (
+               cd merging &&
+               test_commit initial &&
+               git checkout -b topic &&
+               test_commit on-topic &&
+               git checkout master &&
+               test_commit on-master &&
+               test_tick &&
+               git merge --no-ff -m Yeah topic &&
+
+               echo ":1 $(git rev-parse HEAD^^)" >marks &&
+               git fast-export --import-marks=marks master >out &&
+               grep Yeah out
+       )
+'
+
 test_done
index eb9a8ed197b4c6383a4c688f5e5c3a3fcb102b12..1fc9b33aeb5f095816fba72e85c94f0455994418 100755 (executable)
@@ -237,7 +237,7 @@ test_expect_success 'ignore apple' '
        build_gendouble &&
        (
                cd "$cli" &&
-               test-genrandom apple 1024 >double.png &&
+               test-tool genrandom apple 1024 >double.png &&
                "$PYTHON_PATH" "$TRASH_DIRECTORY/gendouble.py" >%double.png &&
                p4 add -t apple double.png &&
                p4 submit -d appledouble
index d950c7d665498c484f83d127cd2363def5169a89..d5c367510049607ce33db73ffc1869a0652fe663 100755 (executable)
@@ -28,7 +28,7 @@ test_expect_success 'shell metachars in filenames' '
                echo f2 >"file with spaces" &&
                git add "file with spaces" &&
                git commit -m "add files" &&
-               P4EDITOR="test-chmtime +5" git p4 submit
+               P4EDITOR="test-tool chmtime +5" git p4 submit
        ) &&
        (
                cd "$cli" &&
@@ -47,7 +47,7 @@ test_expect_success 'deleting with shell metachars' '
                git rm foo\$bar &&
                git rm file\ with\ spaces &&
                git commit -m "remove files" &&
-               P4EDITOR="test-chmtime +5" git p4 submit
+               P4EDITOR="test-tool chmtime +5" git p4 submit
        ) &&
        (
                cd "$cli" &&
index 71cae2874d935e16b951160c9a3fa0014fe2db27..2325599ee60f5bf9b179f4a33ccbe866458c0740 100755 (executable)
@@ -155,6 +155,46 @@ test_expect_success 'allow submit from branch with same revision but different n
        )
 '
 
+# make two commits, but tell it to apply only one
+
+test_expect_success 'submit --commit one' '
+       test_when_finished cleanup_git &&
+       git p4 clone --dest="$git" //depot &&
+       (
+               cd "$git" &&
+               test_commit "file9" &&
+               test_commit "file10" &&
+               git config git-p4.skipSubmitEdit true &&
+               git p4 submit --commit HEAD
+       ) &&
+       (
+               cd "$cli" &&
+               test_path_is_missing "file9.t" &&
+               test_path_is_file "file10.t"
+       )
+'
+
+# make three commits, but tell it to apply only range
+
+test_expect_success 'submit --commit range' '
+       test_when_finished cleanup_git &&
+       git p4 clone --dest="$git" //depot &&
+       (
+               cd "$git" &&
+               test_commit "file11" &&
+               test_commit "file12" &&
+               test_commit "file13" &&
+               git config git-p4.skipSubmitEdit true &&
+               git p4 submit --commit HEAD~2..HEAD
+       ) &&
+       (
+               cd "$cli" &&
+               test_path_is_missing "file11.t" &&
+               test_path_is_file "file12.t" &&
+               test_path_is_file "file13.t"
+       )
+'
+
 #
 # Basic submit tests, the five handled cases
 #
index bda222aa0270f3a93fa494b308aa174ebc942eca..783c6ad1653142d174e4ddc6d49e1f631121be51 100755 (executable)
@@ -53,7 +53,7 @@ test_expect_success 'preserve users' '
                git commit --author "Alice <alice@example.com>" -m "a change by alice" file1 &&
                git commit --author "Bob <bob@example.com>" -m "a change by bob" file2 &&
                git config git-p4.skipSubmitEditCheck true &&
-               P4EDITOR="test-chmtime +5" P4USER=alice P4PASSWD=secret &&
+               P4EDITOR="test-tool chmtime +5" P4USER=alice P4PASSWD=secret &&
                export P4EDITOR P4USER P4PASSWD &&
                git p4 commit --preserve-user &&
                p4_check_commit_author file1 alice &&
@@ -71,7 +71,7 @@ test_expect_success 'refuse to preserve users without perms' '
                git config git-p4.skipSubmitEditCheck true &&
                echo "username-noperms: a change by alice" >>file1 &&
                git commit --author "Alice <alice@example.com>" -m "perms: a change by alice" file1 &&
-               P4EDITOR="test-chmtime +5" P4USER=bob P4PASSWD=secret &&
+               P4EDITOR="test-tool chmtime +5" P4USER=bob P4PASSWD=secret &&
                export P4EDITOR P4USER P4PASSWD &&
                test_must_fail git p4 commit --preserve-user &&
                ! git diff --exit-code HEAD..p4/master
@@ -89,7 +89,7 @@ test_expect_success 'preserve user where author is unknown to p4' '
                git commit --author "Bob <bob@example.com>" -m "preserve: a change by bob" file1 &&
                echo "username-unknown: a change by charlie" >>file1 &&
                git commit --author "Charlie <charlie@example.com>" -m "preserve: a change by charlie" file1 &&
-               P4EDITOR="test-chmtime +5" P4USER=alice P4PASSWD=secret &&
+               P4EDITOR="test-tool chmtime +5" P4USER=alice P4PASSWD=secret &&
                export P4EDITOR P4USER P4PASSWD &&
                test_must_fail git p4 commit --preserve-user &&
                ! git diff --exit-code HEAD..p4/master &&
index 8840a183acfa907eb4659aa5b47ec5bcfbc10e61..ce7cb22ad37165c6976b4484f6b39a49747d4485 100755 (executable)
@@ -129,6 +129,7 @@ test_expect_success 'Create a repo with multiple depot paths' '
 '
 
 test_expect_success 'Clone repo with multiple depot paths' '
+       test_when_finished cleanup_git &&
        (
                cd "$git" &&
                git p4 clone --changes-block-size=4 //depot/pathA@all //depot/pathB@all \
@@ -138,6 +139,13 @@ test_expect_success 'Clone repo with multiple depot paths' '
        )
 '
 
+test_expect_success 'Clone repo with self-sizing block size' '
+       test_when_finished cleanup_git &&
+       git p4 clone --changes-block-size=1000000 //depot@all --destination="$git" &&
+       git -C "$git" log --oneline >log &&
+       test_line_count \> 10 log
+'
+
 test_expect_success 'kill p4d' '
        kill_p4d
 '
index 6dc6df032ec0c15b39dccd24ade52580fc115add..3c22f74bd436b7c6d94d5c29d5b2e3e3510d58e6 100755 (executable)
@@ -26,7 +26,7 @@ test_expect_success 'EDITOR with options' '
                cd "$git" &&
                echo change >file1 &&
                git commit -m "change" file1 &&
-               P4EDITOR=": >\"$git/touched\" && test-chmtime +5" git p4 submit &&
+               P4EDITOR=": >\"$git/touched\" && test-tool chmtime +5" git p4 submit &&
                test_path_is_file "$git/touched"
        )
 '
diff --git a/t/t9832-unshelve.sh b/t/t9832-unshelve.sh
new file mode 100755 (executable)
index 0000000..48ec767
--- /dev/null
@@ -0,0 +1,138 @@
+#!/bin/sh
+
+last_shelved_change () {
+       p4 changes -s shelved -m1 | cut -d " " -f 2
+}
+
+test_description='git p4 unshelve'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+       start_p4d
+'
+
+test_expect_success 'init depot' '
+       (
+               cd "$cli" &&
+               echo file1 >file1 &&
+               p4 add file1 &&
+               p4 submit -d "change 1" &&
+               : >file_to_delete &&
+               p4 add file_to_delete &&
+               p4 submit -d "file to delete"
+       )
+'
+
+test_expect_success 'initial clone' '
+       git p4 clone --dest="$git" //depot/@all
+'
+
+test_expect_success 'create shelved changelist' '
+       (
+               cd "$cli" &&
+               p4 edit file1 &&
+               echo "a change" >>file1 &&
+               echo "new file" >file2 &&
+               p4 add file2 &&
+               p4 delete file_to_delete &&
+               p4 opened &&
+               p4 shelve -i <<EOF
+Change: new
+Description:
+       Test commit
+
+       Further description
+Files:
+       //depot/file1
+       //depot/file2
+       //depot/file_to_delete
+EOF
+
+       ) &&
+       (
+               cd "$git" &&
+               change=$(last_shelved_change) &&
+               git p4 unshelve $change &&
+               git show refs/remotes/p4/unshelved/$change | grep -q "Further description" &&
+               git cherry-pick refs/remotes/p4/unshelved/$change &&
+               test_path_is_file file2 &&
+               test_cmp file1 "$cli"/file1 &&
+               test_cmp file2 "$cli"/file2 &&
+               test_path_is_missing file_to_delete
+       )
+'
+
+test_expect_success 'update shelved changelist and re-unshelve' '
+       test_when_finished cleanup_git &&
+       (
+               cd "$cli" &&
+               change=$(last_shelved_change) &&
+               echo "file3" >file3 &&
+               p4 add -c $change file3 &&
+               p4 shelve -i -r <<EOF &&
+Change: $change
+Description:
+       Test commit
+
+       Further description
+Files:
+       //depot/file1
+       //depot/file2
+       //depot/file3
+       //depot/file_to_delete
+EOF
+               p4 describe $change
+       ) &&
+       (
+               cd "$git" &&
+               change=$(last_shelved_change) &&
+               git p4 unshelve $change &&
+               git diff refs/remotes/p4/unshelved/$change.0 refs/remotes/p4/unshelved/$change | grep -q file3
+       )
+'
+
+# This is the tricky case where the shelved changelist base revision doesn't
+# match git-p4's idea of the base revision
+#
+# We will attempt to unshelve a change that is based on a change one commit
+# ahead of p4/master
+
+test_expect_success 'create shelved changelist based on p4 change ahead of p4/master' '
+       git p4 clone --dest="$git" //depot/@all &&
+       (
+               cd "$cli" &&
+               p4 revert ... &&
+               p4 edit file1 &&
+               echo "foo" >>file1 &&
+               p4 submit -d "change:foo" &&
+               p4 edit file1 &&
+               echo "bar" >>file1 &&
+               p4 shelve -i <<EOF &&
+Change: new
+Description:
+       Change to be unshelved
+Files:
+       //depot/file1
+EOF
+               change=$(last_shelved_change) &&
+               p4 describe -S $change | grep -q "Change to be unshelved"
+       )
+'
+
+# Now try to unshelve it. git-p4 should refuse to do so.
+test_expect_success 'try to unshelve the change' '
+       test_when_finished cleanup_git &&
+       (
+               change=$(last_shelved_change) &&
+               cd "$git" &&
+               test_must_fail git p4 unshelve $change 2>out.txt &&
+               grep -q "cannot unshelve" out.txt
+       )
+'
+
+test_expect_success 'kill p4d' '
+       kill_p4d
+'
+
+test_done
diff --git a/t/t9833-errors.sh b/t/t9833-errors.sh
new file mode 100755 (executable)
index 0000000..9ba892d
--- /dev/null
@@ -0,0 +1,78 @@
+#!/bin/sh
+
+test_description='git p4 errors'
+
+. ./lib-git-p4.sh
+
+test_expect_success 'start p4d' '
+       start_p4d
+'
+
+test_expect_success 'add p4 files' '
+       (
+               cd "$cli" &&
+               echo file1 >file1 &&
+               p4 add file1 &&
+               p4 submit -d "file1"
+       )
+'
+
+# after this test, the default user requires a password
+test_expect_success 'error handling' '
+       git p4 clone --dest="$git" //depot@all &&
+       (
+               cd "$git" &&
+               P4PORT=: test_must_fail git p4 submit 2>errmsg
+       ) &&
+       p4 passwd -P newpassword &&
+       (
+               P4PASSWD=badpassword test_must_fail git p4 clone //depot/foo 2>errmsg &&
+               grep -q "failure accessing depot.*P4PASSWD" errmsg
+       )
+'
+
+test_expect_success 'ticket logged out' '
+       P4TICKETS="$cli/tickets" &&
+       echo "newpassword" | p4 login &&
+       (
+               cd "$git" &&
+               test_commit "ticket-auth-check" &&
+               p4 logout &&
+               test_must_fail git p4 submit 2>errmsg &&
+               grep -q "failure accessing depot" errmsg
+       )
+'
+
+test_expect_success 'create group with short ticket expiry' '
+       P4TICKETS="$cli/tickets" &&
+       echo "newpassword" | p4 login &&
+       p4_add_user short_expiry_user &&
+       p4 -u short_expiry_user passwd -P password &&
+       p4 group -i <<-EOF &&
+       Group: testgroup
+       Timeout: 3
+       Users: short_expiry_user
+       EOF
+
+       p4 users | grep short_expiry_user
+'
+
+test_expect_success 'git operation with expired ticket' '
+       P4TICKETS="$cli/tickets" &&
+       P4USER=short_expiry_user &&
+       echo "password" | p4 login &&
+       (
+               cd "$git" &&
+               git p4 sync &&
+               sleep 5 &&
+               test_must_fail git p4 sync 2>errmsg &&
+               grep "failure accessing depot" errmsg
+       )
+'
+
+test_expect_success 'kill p4d' '
+       kill_p4d
+'
+
+
+test_done
index b7f5b1e632fb27a0448239361d6b4207be4b9908..a28640ce1accd604bd32fdc95fd172119f6c3741 100755 (executable)
@@ -13,7 +13,7 @@ complete ()
        return 0
 }
 
-# Be careful when updating this list:
+# Be careful when updating these lists:
 #
 # (1) The build tree may have build artifact from different branch, or
 #     the user's $PATH may have a random executable that may begin
@@ -30,7 +30,8 @@ complete ()
 #     completion for "git <TAB>", and a plumbing is excluded.  "add",
 #     "filter-branch" and "ls-files" are listed for this.
 
-GIT_TESTING_COMMAND_COMPLETION='add checkout check-attr filter-branch ls-files'
+GIT_TESTING_ALL_COMMAND_LIST='add checkout check-attr filter-branch ls-files'
+GIT_TESTING_PORCELAIN_COMMAND_LIST='add checkout filter-branch'
 
 . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash"
 
@@ -84,10 +85,11 @@ test_completion ()
        then
                printf '%s\n' "$2" >expected
        else
-               sed -e 's/Z$//' >expected
+               sed -e 's/Z$//' |sort >expected
        fi &&
        run_completion "$1" &&
-       test_cmp expected out
+       sort out >out_sorted &&
+       test_cmp expected out_sorted
 }
 
 # Test __gitcomp.
@@ -179,7 +181,7 @@ test_expect_success '__git_find_repo_path - cwd is a .git directory' '
 test_expect_success '__git_find_repo_path - parent is a .git directory' '
        echo "$ROOT/.git" >expected &&
        (
-               cd .git/refs/heads &&
+               cd .git/objects &&
                __git_find_repo_path &&
                echo "$__git_repo_path" >"$actual"
        ) &&
@@ -400,6 +402,46 @@ test_expect_success '__gitdir - remote as argument' '
        test_cmp expected "$actual"
 '
 
+
+test_expect_success '__git_dequote - plain unquoted word' '
+       __git_dequote unquoted-word &&
+       verbose test unquoted-word = "$dequoted_word"
+'
+
+# input:    b\a\c\k\'\\\"s\l\a\s\h\es
+# expected: back'\"slashes
+test_expect_success '__git_dequote - backslash escaped' '
+       __git_dequote "b\a\c\k\\'\''\\\\\\\"s\l\a\s\h\es" &&
+       verbose test "back'\''\\\"slashes" = "$dequoted_word"
+'
+
+# input:    sin'gle\' '"quo'ted
+# expected: single\ "quoted
+test_expect_success '__git_dequote - single quoted' '
+       __git_dequote "'"sin'gle\\\\' '\\\"quo'ted"'" &&
+       verbose test '\''single\ "quoted'\'' = "$dequoted_word"
+'
+
+# input:    dou"ble\\" "\"\quot"ed
+# expected: double\ "\quoted
+test_expect_success '__git_dequote - double quoted' '
+       __git_dequote '\''dou"ble\\" "\"\quot"ed'\'' &&
+       verbose test '\''double\ "\quoted'\'' = "$dequoted_word"
+'
+
+# input: 'open single quote
+test_expect_success '__git_dequote - open single quote' '
+       __git_dequote "'\''open single quote" &&
+       verbose test "open single quote" = "$dequoted_word"
+'
+
+# input: "open double quote
+test_expect_success '__git_dequote - open double quote' '
+       __git_dequote "\"open double quote" &&
+       verbose test "open double quote" = "$dequoted_word"
+'
+
+
 test_expect_success '__gitcomp_direct - puts everything into COMPREPLY as-is' '
        sed -e "s/Z$//g" >expected <<-EOF &&
        with-trailing-space Z
@@ -1168,6 +1210,124 @@ test_expect_success 'teardown after ref completion' '
        git remote remove other
 '
 
+
+test_path_completion ()
+{
+       test $# = 2 || error "bug in the test script: not 2 parameters to test_path_completion"
+
+       local cur="$1" expected="$2"
+       echo "$expected" >expected &&
+       (
+               # In the following tests calling this function we only
+               # care about how __git_complete_index_file() deals with
+               # unusual characters in path names.  By requesting only
+               # untracked files we dont have to bother adding any
+               # paths to the index in those tests.
+               __git_complete_index_file --others &&
+               print_comp
+       ) &&
+       test_cmp expected out
+}
+
+test_expect_success 'setup for path completion tests' '
+       mkdir simple-dir \
+             "spaces in dir" \
+             árvíztűrő &&
+       touch simple-dir/simple-file \
+             "spaces in dir/spaces in file" \
+             "árvíztűrő/Сайн яваарай" &&
+       if test_have_prereq !MINGW &&
+          mkdir BS\\dir \
+                '$'separators\034in\035dir'' &&
+          touch BS\\dir/DQ\"file \
+                '$'separators\034in\035dir/sep\036in\037file''
+       then
+               test_set_prereq FUNNYNAMES
+       else
+               rm -rf BS\\dir '$'separators\034in\035dir''
+       fi
+'
+
+test_expect_success '__git_complete_index_file - simple' '
+       test_path_completion simple simple-dir &&  # Bash is supposed to
+                                                  # add the trailing /.
+       test_path_completion simple-dir/simple simple-dir/simple-file
+'
+
+test_expect_success \
+    '__git_complete_index_file - escaped characters on cmdline' '
+       test_path_completion spac "spaces in dir" &&  # Bash will turn this
+                                                     # into "spaces\ in\ dir"
+       test_path_completion "spaces\\ i" \
+                            "spaces in dir" &&
+       test_path_completion "spaces\\ in\\ dir/s" \
+                            "spaces in dir/spaces in file" &&
+       test_path_completion "spaces\\ in\\ dir/spaces\\ i" \
+                            "spaces in dir/spaces in file"
+'
+
+test_expect_success \
+    '__git_complete_index_file - quoted characters on cmdline' '
+       # Testing with an opening but without a corresponding closing
+       # double quote is important.
+       test_path_completion \"spac "spaces in dir" &&
+       test_path_completion "\"spaces i" \
+                            "spaces in dir" &&
+       test_path_completion "\"spaces in dir/s" \
+                            "spaces in dir/spaces in file" &&
+       test_path_completion "\"spaces in dir/spaces i" \
+                            "spaces in dir/spaces in file"
+'
+
+test_expect_success '__git_complete_index_file - UTF-8 in ls-files output' '
+       test_path_completion á árvíztűrő &&
+       test_path_completion árvíztűrő/С "árvíztűrő/Сайн яваарай"
+'
+
+test_expect_success FUNNYNAMES \
+    '__git_complete_index_file - C-style escapes in ls-files output' '
+       test_path_completion BS \
+                            BS\\dir &&
+       test_path_completion BS\\\\d \
+                            BS\\dir &&
+       test_path_completion BS\\\\dir/DQ \
+                            BS\\dir/DQ\"file &&
+       test_path_completion BS\\\\dir/DQ\\\"f \
+                            BS\\dir/DQ\"file
+'
+
+test_expect_success FUNNYNAMES \
+    '__git_complete_index_file - \nnn-escaped characters in ls-files output' '
+       test_path_completion sep '$'separators\034in\035dir'' &&
+       test_path_completion '$'separators\034i'' \
+                            '$'separators\034in\035dir'' &&
+       test_path_completion '$'separators\034in\035dir/sep'' \
+                            '$'separators\034in\035dir/sep\036in\037file'' &&
+       test_path_completion '$'separators\034in\035dir/sep\036i'' \
+                            '$'separators\034in\035dir/sep\036in\037file''
+'
+
+test_expect_success FUNNYNAMES \
+    '__git_complete_index_file - removing repeated quoted path components' '
+       test_when_finished rm -r repeated-quoted &&
+       mkdir repeated-quoted &&      # A directory whose name in itself
+                                     # would not be quoted ...
+       >repeated-quoted/0-file &&
+       >repeated-quoted/1\"file &&   # ... but here the file makes the
+                                     # dirname quoted ...
+       >repeated-quoted/2-file &&
+       >repeated-quoted/3\"file &&   # ... and here, too.
+
+       # Still, we shold only list the directory name only once.
+       test_path_completion repeated repeated-quoted
+'
+
+test_expect_success 'teardown after path completion tests' '
+       rm -rf simple-dir "spaces in dir" árvíztűrő \
+              BS\\dir '$'separators\034in\035dir''
+'
+
+
 test_expect_success '__git_get_config_variables' '
        cat >expect <<-EOF &&
        name-1
@@ -1191,17 +1351,6 @@ test_expect_success '__git_pretty_aliases' '
        test_cmp expect actual
 '
 
-test_expect_success '__git_aliases' '
-       cat >expect <<-EOF &&
-       ci
-       co
-       EOF
-       test_config alias.ci commit &&
-       test_config alias.co checkout &&
-       __git_aliases >actual &&
-       test_cmp expect actual
-'
-
 test_expect_success 'basic' '
        run_completion "git " &&
        # built-in
@@ -1365,6 +1514,7 @@ test_expect_success 'complete files' '
 
        echo "expected" > .gitignore &&
        echo "out" >> .gitignore &&
+       echo "out_sorted" >> .gitignore &&
 
        git add .gitignore &&
        test_completion "git commit " ".gitignore" &&
@@ -1454,6 +1604,12 @@ test_expect_success 'completion used <cmd> completion for alias: !f() { : git <c
        EOF
 '
 
+test_expect_success 'completion without explicit _git_xxx function' '
+       test_completion "git version --" <<-\EOF
+       --build-options Z
+       EOF
+'
+
 test_expect_failure 'complete with tilde expansion' '
        git init tmp && cd tmp &&
        test_when_finished "cd .. && rm -rf tmp" &&
@@ -1504,13 +1660,6 @@ test_expect_success 'sourcing the completion script clears cached commands' '
        verbose test -z "$__git_all_commands"
 '
 
-test_expect_success 'sourcing the completion script clears cached porcelain commands' '
-       __git_compute_porcelain_commands &&
-       verbose test -n "$__git_porcelain_commands" &&
-       . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
-       verbose test -z "$__git_porcelain_commands"
-'
-
 test_expect_success !GETTEXT_POISON 'sourcing the completion script clears cached merge strategies' '
        __git_compute_merge_strategies &&
        verbose test -n "$__git_merge_strategies" &&
index 8f5c811dd7d627ea5a0611be5161cea98deedb95..c3b89ae783d0b5511718be6d6b9d9978dd9131cd 100755 (executable)
@@ -148,7 +148,7 @@ test_expect_success 'prompt - inside .git directory' '
 test_expect_success 'prompt - deep inside .git directory' '
        printf " (GIT_DIR!)" >expected &&
        (
-               cd .git/refs/heads &&
+               cd .git/objects &&
                __git_ps1 >"$actual"
        ) &&
        test_cmp expected "$actual"
index b895366feef6027ac00bf47271b2530e8b7e7162..2b2181dca09089ed36d10ee8f6f67eedda8cf352 100644 (file)
@@ -145,12 +145,28 @@ test_pause () {
        "$SHELL_PATH" <&6 >&5 2>&7
 }
 
-# Wrap git in gdb. Adding this to a command can make it easier to
-# understand what is going on in a failing test.
+# Wrap git with a debugger. Adding this to a command can make it easier
+# to understand what is going on in a failing test.
 #
-# Example: "debug git checkout master".
+# Examples:
+#     debug git checkout master
+#     debug --debugger=nemiver git $ARGS
+#     debug -d "valgrind --tool=memcheck --track-origins=yes" git $ARGS
 debug () {
-        GIT_TEST_GDB=1 "$@" <&6 >&5 2>&7
+       case "$1" in
+       -d)
+               GIT_DEBUGGER="$2" &&
+               shift 2
+               ;;
+       --debugger=*)
+               GIT_DEBUGGER="${1#*=}" &&
+               shift 1
+               ;;
+       *)
+               GIT_DEBUGGER=1
+               ;;
+       esac &&
+       GIT_DEBUGGER="${GIT_DEBUGGER}" "$@" <&6 >&5 2>&7
 }
 
 # Call test_commit with the arguments
@@ -278,8 +294,20 @@ write_script () {
 # The single parameter is the prerequisite tag (a simple word, in all
 # capital letters by convention).
 
+test_unset_prereq () {
+       ! test_have_prereq "$1" ||
+       satisfied_prereq="${satisfied_prereq% $1 *} ${satisfied_prereq#* $1 }"
+}
+
 test_set_prereq () {
-       satisfied_prereq="$satisfied_prereq$1 "
+       case "$1" in
+       !*)
+               test_unset_prereq "${1#!}"
+               ;;
+       *)
+               satisfied_prereq="$satisfied_prereq$1 "
+               ;;
+       esac
 }
 satisfied_prereq=" "
 lazily_testable_prereq= lazily_tested_prereq=
@@ -782,11 +810,8 @@ verbose () {
 # otherwise.
 
 test_must_be_empty () {
-       if ! test -f "$1"
-       then
-               echo "'$1' is missing"
-               return 1
-       elif test -s "$1"
+       test_path_is_file "$1" &&
+       if test -s "$1"
        then
                echo "'$1' is not empty, it contains:"
                cat "$1"
index 7740d511d289f44bb1313308fe49d5894f64b3c2..28315706be709d28c85785e389b381a8617337e3 100644 (file)
@@ -184,6 +184,8 @@ _x40="$_x35$_x05"
 # Zero SHA-1
 _z40=0000000000000000000000000000000000000000
 
+OID_REGEX="$_x40"
+ZERO_OID=$_z40
 EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904
 EMPTY_BLOB=e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
 
@@ -195,7 +197,7 @@ LF='
 # when case-folding filenames
 u200c=$(printf '\342\200\214')
 
-export _x05 _x35 _x40 _z40 LF u200c EMPTY_TREE EMPTY_BLOB
+export _x05 _x35 _x40 _z40 LF u200c EMPTY_TREE EMPTY_BLOB ZERO_OID OID_REGEX
 
 # Each test should start with something like this, after copyright notices:
 #
@@ -963,10 +965,10 @@ test -d "$GIT_BUILD_DIR"/templates/blt || {
        error "You haven't built things yet, have you?"
 }
 
-if ! test -x "$GIT_BUILD_DIR"/t/helper/test-chmtime
+if ! test -x "$GIT_BUILD_DIR"/t/helper/test-tool
 then
-       echo >&2 'You need to build test-chmtime:'
-       echo >&2 'Run "make t/helper/test-chmtime" in the source (toplevel) directory'
+       echo >&2 'You need to build test-tool:'
+       echo >&2 'Run "make t/helper/test-tool" in the source (toplevel) directory'
        exit 1
 fi
 
@@ -1106,12 +1108,7 @@ test_lazy_prereq UTF8_NFD_TO_NFC '
        auml=$(printf "\303\244")
        aumlcdiar=$(printf "\141\314\210")
        >"$auml" &&
-       case "$(echo *)" in
-       "$aumlcdiar")
-               true ;;
-       *)
-               false ;;
-       esac
+       test -f "$aumlcdiar"
 '
 
 test_lazy_prereq AUTOIDENT '
@@ -1206,5 +1203,16 @@ test_lazy_prereq LONG_IS_64BIT '
        test 8 -le "$(build_option sizeof-long)"
 '
 
-test_lazy_prereq TIME_IS_64BIT 'test-date is64bit'
-test_lazy_prereq TIME_T_IS_64BIT 'test-date time_t-is64bit'
+test_lazy_prereq TIME_IS_64BIT 'test-tool date is64bit'
+test_lazy_prereq TIME_T_IS_64BIT 'test-tool date time_t-is64bit'
+
+test_lazy_prereq CURL '
+       curl --version
+'
+
+# SHA1 is a test if the hash algorithm in use is SHA-1.  This is both for tests
+# which will not work with other hash algorithms and tests that work but don't
+# test anything meaningful (e.g. special values which cause short collisions).
+test_lazy_prereq SHA1 '
+       test $(git hash-object /dev/null) = e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
+'
diff --git a/tag.c b/tag.c
index 66210fd4772778ac4c95925ec4670717dd27da62..3d37c1bd251c5f8c5eb06ede72ab57b323888709 100644 (file)
--- a/tag.c
+++ b/tag.c
@@ -41,20 +41,20 @@ int gpg_verify_tag(const struct object_id *oid, const char *name_to_report,
        unsigned long size;
        int ret;
 
-       type = sha1_object_info(oid->hash, NULL);
+       type = oid_object_info(the_repository, oid, NULL);
        if (type != OBJ_TAG)
                return error("%s: cannot verify a non-tag object of type %s.",
                                name_to_report ?
                                name_to_report :
-                               find_unique_abbrev(oid->hash, DEFAULT_ABBREV),
+                               find_unique_abbrev(oid, DEFAULT_ABBREV),
                                type_name(type));
 
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf)
                return error("%s: unable to read file.",
                                name_to_report ?
                                name_to_report :
-                               find_unique_abbrev(oid->hash, DEFAULT_ABBREV));
+                               find_unique_abbrev(oid, DEFAULT_ABBREV));
 
        ret = run_gpg_verify(buf, size, flags);
 
@@ -182,7 +182,7 @@ int parse_tag(struct tag *item)
 
        if (item->object.parsed)
                return 0;
-       data = read_sha1_file(item->object.oid.hash, &type, &size);
+       data = read_object_file(&item->object.oid, &type, &size);
        if (!data)
                return error("Could not read %s",
                             oid_to_hex(&item->object.oid));
index 68d62d5446d963dc69006ad9a83907c6690f92c1..6a756416384c210ada2631f17862f5c01fffa478 100755 (executable)
@@ -12,7 +12,7 @@ then
        against=HEAD
 else
        # Initial commit: diff against an empty tree object
-       against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
+       against=$(git hash-object -t tree /dev/null)
 fi
 
 # If you want to allow non-ASCII filenames set this variable to true.
index b2d9280f104aec7095dd2b37ff1f7165355b5388..91c00567f4d63367d6766808b0ff90f6faa08765 100644 (file)
@@ -6,6 +6,7 @@
 #include "strbuf.h"
 #include "argv-array.h"
 #include "quote.h"
+#include "object-store.h"
 
 struct tmp_objdir {
        struct strbuf path;
@@ -126,7 +127,7 @@ struct tmp_objdir *tmp_objdir_create(void)
        struct tmp_objdir *t;
 
        if (the_tmp_objdir)
-               die("BUG: only one tmp_objdir can be used at a time");
+               BUG("only one tmp_objdir can be used at a time");
 
        t = xmalloc(sizeof(*t));
        strbuf_init(&t->path, 0);
diff --git a/trace.c b/trace.c
index 7f3b08e148044c6c94cbef03ae265e134391357a..fc623e91fdd7ed8268922ae0460cfbd6903f3800 100644 (file)
--- a/trace.c
+++ b/trace.c
@@ -26,6 +26,7 @@
 
 struct trace_key trace_default_key = { "GIT_TRACE", 0, 0, 0 };
 struct trace_key trace_perf_key = TRACE_KEY_INIT(PERFORMANCE);
+struct trace_key trace_setup_key = TRACE_KEY_INIT(SETUP);
 
 /* Get a trace file descriptor from "key" env variable. */
 static int get_trace_fd(struct trace_key *key)
@@ -300,11 +301,10 @@ static const char *quote_crnl(const char *path)
 /* FIXME: move prefix to startup_info struct and get rid of this arg */
 void trace_repo_setup(const char *prefix)
 {
-       static struct trace_key key = TRACE_KEY_INIT(SETUP);
        const char *git_work_tree;
        char *cwd;
 
-       if (!trace_want(&key))
+       if (!trace_want(&trace_setup_key))
                return;
 
        cwd = xgetcwd();
@@ -315,11 +315,11 @@ void trace_repo_setup(const char *prefix)
        if (!prefix)
                prefix = "(null)";
 
-       trace_printf_key(&key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
-       trace_printf_key(&key, "setup: git_common_dir: %s\n", quote_crnl(get_git_common_dir()));
-       trace_printf_key(&key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
-       trace_printf_key(&key, "setup: cwd: %s\n", quote_crnl(cwd));
-       trace_printf_key(&key, "setup: prefix: %s\n", quote_crnl(prefix));
+       trace_printf_key(&trace_setup_key, "setup: git_dir: %s\n", quote_crnl(get_git_dir()));
+       trace_printf_key(&trace_setup_key, "setup: git_common_dir: %s\n", quote_crnl(get_git_common_dir()));
+       trace_printf_key(&trace_setup_key, "setup: worktree: %s\n", quote_crnl(git_work_tree));
+       trace_printf_key(&trace_setup_key, "setup: cwd: %s\n", quote_crnl(cwd));
+       trace_printf_key(&trace_setup_key, "setup: prefix: %s\n", quote_crnl(prefix));
 
        free(cwd);
 }
diff --git a/trace.h b/trace.h
index 88055abef7342ee638f6597a6628bcdf4baeace9..2b6a1bc17c2cc1a8642d8c7bd460808638f28d77 100644 (file)
--- a/trace.h
+++ b/trace.h
@@ -15,6 +15,7 @@ extern struct trace_key trace_default_key;
 
 #define TRACE_KEY_INIT(name) { "GIT_TRACE_" #name, 0, 0, 0 }
 extern struct trace_key trace_perf_key;
+extern struct trace_key trace_setup_key;
 
 extern void trace_repo_setup(const char *prefix);
 extern int trace_want(struct trace_key *key);
index c508c9b7521b48c18f1b373ada9b9f2e5b02681d..4e309460d1367a7b35b61c2391525a165a3645e3 100644 (file)
--- a/trailer.c
+++ b/trailer.c
@@ -298,7 +298,7 @@ static void apply_arg_if_exists(struct trailer_item *in_tok,
                        free_arg_item(arg_tok);
                break;
        default:
-               die("BUG: trailer.c: unhandled value %d",
+               BUG("trailer.c: unhandled value %d",
                    arg_tok->conf.if_exists);
        }
 }
@@ -323,7 +323,7 @@ static void apply_arg_if_missing(struct list_head *head,
                        list_add(&to_add->list, head);
                break;
        default:
-               die("BUG: trailer.c: unhandled value %d",
+               BUG("trailer.c: unhandled value %d",
                    arg_tok->conf.if_missing);
        }
 }
@@ -557,7 +557,7 @@ static int git_trailer_config(const char *conf_key, const char *value, void *cb)
                        warning(_("unknown value '%s' for key '%s'"), value, conf_key);
                break;
        default:
-               die("BUG: trailer.c: unhandled type %d", type);
+               BUG("trailer.c: unhandled type %d", type);
        }
        return 0;
 }
index ecd4c69090156e92d09f33f99ef63a157db72796..959376be28b964ccea17889f0e376175ce3fcb6c 100644 (file)
@@ -11,7 +11,9 @@
 #include "sigchain.h"
 #include "argv-array.h"
 #include "refs.h"
+#include "refspec.h"
 #include "transport-internal.h"
+#include "protocol.h"
 
 static int debug;
 
@@ -26,6 +28,7 @@ struct helper_data {
                option : 1,
                push : 1,
                connect : 1,
+               stateless_connect : 1,
                signed_tags : 1,
                check_connectivity : 1,
                no_disconnect_req : 1,
@@ -33,8 +36,7 @@ struct helper_data {
        char *export_marks;
        char *import_marks;
        /* These go from remote name (as in "list") to private name */
-       struct refspec *refspecs;
-       int refspec_nr;
+       struct refspec rs;
        /* Transport options for fetch-pack/send-pack (should one of
         * those be invoked).
         */
@@ -49,7 +51,7 @@ static void sendline(struct helper_data *helper, struct strbuf *buffer)
                die_errno("Full write to remote helper failed");
 }
 
-static int recvline_fh(FILE *helper, struct strbuf *buffer, const char *name)
+static int recvline_fh(FILE *helper, struct strbuf *buffer)
 {
        strbuf_reset(buffer);
        if (debug)
@@ -67,7 +69,7 @@ static int recvline_fh(FILE *helper, struct strbuf *buffer, const char *name)
 
 static int recvline(struct helper_data *helper, struct strbuf *buffer)
 {
-       return recvline_fh(helper->out, buffer, helper->name);
+       return recvline_fh(helper->out, buffer);
 }
 
 static void write_constant(int fd, const char *str)
@@ -104,9 +106,6 @@ static struct child_process *get_helper(struct transport *transport)
        struct helper_data *data = transport->data;
        struct strbuf buf = STRBUF_INIT;
        struct child_process *helper;
-       const char **refspecs = NULL;
-       int refspec_nr = 0;
-       int refspec_alloc = 0;
        int duped;
        int code;
 
@@ -136,6 +135,7 @@ static struct child_process *get_helper(struct transport *transport)
 
        data->helper = helper;
        data->no_disconnect_req = 0;
+       refspec_init(&data->rs, REFSPEC_FETCH);
 
        /*
         * Open the output as FILE* so strbuf_getline_*() family of
@@ -181,13 +181,12 @@ static struct child_process *get_helper(struct transport *transport)
                        data->export = 1;
                else if (!strcmp(capname, "check-connectivity"))
                        data->check_connectivity = 1;
-               else if (!data->refspecs && skip_prefix(capname, "refspec ", &arg)) {
-                       ALLOC_GROW(refspecs,
-                                  refspec_nr + 1,
-                                  refspec_alloc);
-                       refspecs[refspec_nr++] = xstrdup(arg);
+               else if (skip_prefix(capname, "refspec ", &arg)) {
+                       refspec_append(&data->rs, arg);
                } else if (!strcmp(capname, "connect")) {
                        data->connect = 1;
+               } else if (!strcmp(capname, "stateless-connect")) {
+                       data->stateless_connect = 1;
                } else if (!strcmp(capname, "signed-tags")) {
                        data->signed_tags = 1;
                } else if (skip_prefix(capname, "export-marks ", &arg)) {
@@ -202,14 +201,7 @@ static struct child_process *get_helper(struct transport *transport)
                            capname);
                }
        }
-       if (refspecs) {
-               int i;
-               data->refspec_nr = refspec_nr;
-               data->refspecs = parse_fetch_refspec(refspec_nr, refspecs);
-               for (i = 0; i < refspec_nr; i++)
-                       free((char *)refspecs[i]);
-               free(refspecs);
-       } else if (data->import || data->bidi_import || data->export) {
+       if (!data->rs.nr && (data->import || data->bidi_import || data->export)) {
                warning("This remote helper should implement refspec capability.");
        }
        strbuf_release(&buf);
@@ -373,8 +365,7 @@ static int release_helper(struct transport *transport)
 {
        int res = 0;
        struct helper_data *data = transport->data;
-       free_refspec(data->refspec_nr, data->refspecs);
-       data->refspecs = NULL;
+       refspec_clear(&data->rs);
        res = disconnect_helper(transport);
        free(transport->data);
        return res;
@@ -532,8 +523,8 @@ static int fetch_with_import(struct transport *transport,
                if (posn->status & REF_STATUS_UPTODATE)
                        continue;
                name = posn->symref ? posn->symref : posn->name;
-               if (data->refspecs)
-                       private = apply_refspecs(data->refspecs, data->refspec_nr, name);
+               if (data->rs.nr)
+                       private = apply_refspecs(&data->rs, name);
                else
                        private = xstrdup(name);
                if (private) {
@@ -546,14 +537,13 @@ static int fetch_with_import(struct transport *transport,
        return 0;
 }
 
-static int process_connect_service(struct transport *transport,
-                                  const char *name, const char *exec)
+static int run_connect(struct transport *transport, struct strbuf *cmdbuf)
 {
        struct helper_data *data = transport->data;
-       struct strbuf cmdbuf = STRBUF_INIT;
-       struct child_process *helper;
-       int r, duped, ret = 0;
+       int ret = 0;
+       int duped;
        FILE *input;
+       struct child_process *helper;
 
        helper = get_helper(transport);
 
@@ -569,44 +559,61 @@ static int process_connect_service(struct transport *transport,
        input = xfdopen(duped, "r");
        setvbuf(input, NULL, _IONBF, 0);
 
+       sendline(data, cmdbuf);
+       if (recvline_fh(input, cmdbuf))
+               exit(128);
+
+       if (!strcmp(cmdbuf->buf, "")) {
+               data->no_disconnect_req = 1;
+               if (debug)
+                       fprintf(stderr, "Debug: Smart transport connection "
+                               "ready.\n");
+               ret = 1;
+       } else if (!strcmp(cmdbuf->buf, "fallback")) {
+               if (debug)
+                       fprintf(stderr, "Debug: Falling back to dumb "
+                               "transport.\n");
+       } else {
+               die("Unknown response to connect: %s",
+                       cmdbuf->buf);
+       }
+
+       fclose(input);
+       return ret;
+}
+
+static int process_connect_service(struct transport *transport,
+                                  const char *name, const char *exec)
+{
+       struct helper_data *data = transport->data;
+       struct strbuf cmdbuf = STRBUF_INIT;
+       int ret = 0;
+
        /*
         * Handle --upload-pack and friends. This is fire and forget...
         * just warn if it fails.
         */
        if (strcmp(name, exec)) {
-               r = set_helper_option(transport, "servpath", exec);
+               int r = set_helper_option(transport, "servpath", exec);
                if (r > 0)
                        warning("Setting remote service path not supported by protocol.");
                else if (r < 0)
                        warning("Invalid remote service path.");
        }
 
-       if (data->connect)
+       if (data->connect) {
                strbuf_addf(&cmdbuf, "connect %s\n", name);
-       else
-               goto exit;
-
-       sendline(data, &cmdbuf);
-       if (recvline_fh(input, &cmdbuf, name))
-               exit(128);
-
-       if (!strcmp(cmdbuf.buf, "")) {
-               data->no_disconnect_req = 1;
-               if (debug)
-                       fprintf(stderr, "Debug: Smart transport connection "
-                               "ready.\n");
-               ret = 1;
-       } else if (!strcmp(cmdbuf.buf, "fallback")) {
-               if (debug)
-                       fprintf(stderr, "Debug: Falling back to dumb "
-                               "transport.\n");
-       } else
-               die("Unknown response to connect: %s",
-                       cmdbuf.buf);
+               ret = run_connect(transport, &cmdbuf);
+       } else if (data->stateless_connect &&
+                  (get_protocol_version_config() == protocol_v2) &&
+                  !strcmp("git-upload-pack", name)) {
+               strbuf_addf(&cmdbuf, "stateless-connect %s\n", name);
+               ret = run_connect(transport, &cmdbuf);
+               if (ret)
+                       transport->stateless_rpc = 1;
+       }
 
-exit:
        strbuf_release(&cmdbuf);
-       fclose(input);
        return ret;
 }
 
@@ -795,11 +802,11 @@ static int push_update_refs_status(struct helper_data *data,
                if (push_update_ref_status(&buf, &ref, remote_refs))
                        continue;
 
-               if (flags & TRANSPORT_PUSH_DRY_RUN || !data->refspecs || data->no_private_update)
+               if (flags & TRANSPORT_PUSH_DRY_RUN || !data->rs.nr || data->no_private_update)
                        continue;
 
                /* propagate back the update to the remote namespace */
-               private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name);
+               private = apply_refspecs(&data->rs, ref->name);
                if (!private)
                        continue;
                update_ref("update by helper", private, &ref->new_oid, NULL,
@@ -919,7 +926,7 @@ static int push_refs_with_export(struct transport *transport,
        struct string_list revlist_args = STRING_LIST_INIT_DUP;
        struct strbuf buf = STRBUF_INIT;
 
-       if (!data->refspecs)
+       if (!data->rs.nr)
                die("remote-helper doesn't support push; refspec needed");
 
        set_common_push_options(transport, data->name, flags);
@@ -936,7 +943,7 @@ static int push_refs_with_export(struct transport *transport,
                char *private;
                struct object_id oid;
 
-               private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name);
+               private = apply_refspecs(&data->rs, ref->name);
                if (private && !get_oid(private, &oid)) {
                        strbuf_addf(&buf, "^%s", private);
                        string_list_append_nodup(&revlist_args,
@@ -1032,7 +1039,8 @@ static int has_attribute(const char *attrs, const char *attr) {
        }
 }
 
-static struct ref *get_refs_list(struct transport *transport, int for_push)
+static struct ref *get_refs_list(struct transport *transport, int for_push,
+                                const struct argv_array *ref_prefixes)
 {
        struct helper_data *data = transport->data;
        struct child_process *helper;
@@ -1045,7 +1053,7 @@ static struct ref *get_refs_list(struct transport *transport, int for_push)
 
        if (process_connect(transport, for_push)) {
                do_take_over(transport);
-               return transport->vtable->get_refs_list(transport, for_push);
+               return transport->vtable->get_refs_list(transport, for_push, ref_prefixes);
        }
 
        if (data->push && for_push)
index 3c1a29d7274465b977d9285781673f235e66ad21..1cde6258a73bcf8582b0746d1c44a23b30115dc9 100644 (file)
@@ -3,6 +3,7 @@
 
 struct ref;
 struct transport;
+struct argv_array;
 
 struct transport_vtable {
        /**
@@ -17,11 +18,19 @@ struct transport_vtable {
         * the transport to try to share connections, for_push is a
         * hint as to whether the ultimate operation is a push or a fetch.
         *
+        * If communicating using protocol v2 a list of prefixes can be
+        * provided to be sent to the server to enable it to limit the ref
+        * advertisement.  Since ref filtering is done on the server's end, and
+        * only when using protocol v2, this list will be ignored when not
+        * using protocol v2 meaning this function can return refs which don't
+        * match the provided ref_prefixes.
+        *
         * If the transport is able to determine the remote hash for
         * the ref without a huge amount of effort, it should store it
         * in the ref's old_sha1 field; otherwise it should be all 0.
         **/
-       struct ref *(*get_refs_list)(struct transport *transport, int for_push);
+       struct ref *(*get_refs_list)(struct transport *transport, int for_push,
+                                    const struct argv_array *ref_prefixes);
 
        /**
         * Fetch the objects for the given refs. Note that this gets
index 00d48b5b565b0edfa826a8c426e76cfc60a2f0a1..a32da30dee6f4e38433b68d7c9f7e9404aa58858 100644 (file)
@@ -11,6 +11,7 @@
 #include "bundle.h"
 #include "dir.h"
 #include "refs.h"
+#include "refspec.h"
 #include "branch.h"
 #include "url.h"
 #include "submodule.h"
 #include "sha1-array.h"
 #include "sigchain.h"
 #include "transport-internal.h"
+#include "protocol.h"
+#include "object-store.h"
+#include "color.h"
+
+static int transport_use_color = -1;
+static char transport_colors[][COLOR_MAXLEN] = {
+       GIT_COLOR_RESET,
+       GIT_COLOR_RED           /* REJECTED */
+};
+
+enum color_transport {
+       TRANSPORT_COLOR_RESET = 0,
+       TRANSPORT_COLOR_REJECTED = 1
+};
+
+static int transport_color_config(void)
+{
+       const char *keys[] = {
+               "color.transport.reset",
+               "color.transport.rejected"
+       }, *key = "color.transport";
+       char *value;
+       int i;
+       static int initialized;
+
+       if (initialized)
+               return 0;
+       initialized = 1;
+
+       if (!git_config_get_string(key, &value))
+               transport_use_color = git_config_colorbool(key, value);
+
+       if (!want_color_stderr(transport_use_color))
+               return 0;
+
+       for (i = 0; i < ARRAY_SIZE(keys); i++)
+               if (!git_config_get_string(keys[i], &value)) {
+                       if (!value)
+                               return config_error_nonbool(keys[i]);
+                       if (color_parse(value, transport_colors[i]) < 0)
+                               return -1;
+               }
+
+       return 0;
+}
+
+static const char *transport_get_color(enum color_transport ix)
+{
+       if (want_color_stderr(transport_use_color))
+               return transport_colors[ix];
+       return "";
+}
 
 static void set_upstreams(struct transport *transport, struct ref *refs,
        int pretend)
@@ -71,7 +124,9 @@ struct bundle_transport_data {
        struct bundle_header header;
 };
 
-static struct ref *get_refs_from_bundle(struct transport *transport, int for_push)
+static struct ref *get_refs_from_bundle(struct transport *transport,
+                                       int for_push,
+                                       const struct argv_array *ref_prefixes)
 {
        struct bundle_transport_data *data = transport->data;
        struct ref *result = NULL;
@@ -117,6 +172,7 @@ struct git_transport_data {
        struct child_process *conn;
        int fd[2];
        unsigned got_remote_heads : 1;
+       enum protocol_version version;
        struct oid_array extra_have;
        struct oid_array shallow;
 };
@@ -196,16 +252,35 @@ static int connect_setup(struct transport *transport, int for_push)
        return 0;
 }
 
-static struct ref *get_refs_via_connect(struct transport *transport, int for_push)
+static struct ref *get_refs_via_connect(struct transport *transport, int for_push,
+                                       const struct argv_array *ref_prefixes)
 {
        struct git_transport_data *data = transport->data;
-       struct ref *refs;
+       struct ref *refs = NULL;
+       struct packet_reader reader;
 
        connect_setup(transport, for_push);
-       get_remote_heads(data->fd[0], NULL, 0, &refs,
-                        for_push ? REF_NORMAL : 0,
-                        &data->extra_have,
-                        &data->shallow);
+
+       packet_reader_init(&reader, data->fd[0], NULL, 0,
+                          PACKET_READ_CHOMP_NEWLINE |
+                          PACKET_READ_GENTLE_ON_EOF);
+
+       data->version = discover_version(&reader);
+       switch (data->version) {
+       case protocol_v2:
+               get_remote_refs(data->fd[1], &reader, &refs, for_push,
+                               ref_prefixes, transport->server_options);
+               break;
+       case protocol_v1:
+       case protocol_v0:
+               get_remote_heads(&reader, &refs,
+                                for_push ? REF_NORMAL : 0,
+                                &data->extra_have,
+                                &data->shallow);
+               break;
+       case protocol_unknown_version:
+               BUG("unknown protocol version");
+       }
        data->got_remote_heads = 1;
 
        return refs;
@@ -216,7 +291,7 @@ static int fetch_refs_via_pack(struct transport *transport,
 {
        int ret = 0;
        struct git_transport_data *data = transport->data;
-       struct ref *refs;
+       struct ref *refs = NULL;
        char *dest = xstrdup(transport->url);
        struct fetch_pack_args args;
        struct ref *refs_tmp = NULL;
@@ -241,18 +316,30 @@ static int fetch_refs_via_pack(struct transport *transport,
        args.from_promisor = data->options.from_promisor;
        args.no_dependents = data->options.no_dependents;
        args.filter_options = data->options.filter_options;
-
-       if (!data->got_remote_heads) {
-               connect_setup(transport, 0);
-               get_remote_heads(data->fd[0], NULL, 0, &refs_tmp, 0,
-                                NULL, &data->shallow);
-               data->got_remote_heads = 1;
+       args.stateless_rpc = transport->stateless_rpc;
+       args.server_options = transport->server_options;
+
+       if (!data->got_remote_heads)
+               refs_tmp = get_refs_via_connect(transport, 0, NULL);
+
+       switch (data->version) {
+       case protocol_v2:
+               refs = fetch_pack(&args, data->fd, data->conn,
+                                 refs_tmp ? refs_tmp : transport->remote_refs,
+                                 dest, to_fetch, nr_heads, &data->shallow,
+                                 &transport->pack_lockfile, data->version);
+               break;
+       case protocol_v1:
+       case protocol_v0:
+               refs = fetch_pack(&args, data->fd, data->conn,
+                                 refs_tmp ? refs_tmp : transport->remote_refs,
+                                 dest, to_fetch, nr_heads, &data->shallow,
+                                 &transport->pack_lockfile, data->version);
+               break;
+       case protocol_unknown_version:
+               BUG("unknown protocol version");
        }
 
-       refs = fetch_pack(&args, data->fd, data->conn,
-                         refs_tmp ? refs_tmp : transport->remote_refs,
-                         dest, to_fetch, nr_heads, &data->shallow,
-                         &transport->pack_lockfile);
        close(data->fd[0]);
        close(data->fd[1]);
        if (finish_connect(data->conn))
@@ -304,7 +391,7 @@ int transport_refs_pushed(struct ref *ref)
 
 void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
 {
-       struct refspec rs;
+       struct refspec_item rs;
 
        if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
                return;
@@ -338,7 +425,13 @@ static void print_ref_status(char flag, const char *summary,
                else
                        fprintf(stdout, "%s\n", summary);
        } else {
-               fprintf(stderr, " %c %-*s ", flag, summary_width, summary);
+               const char *red = "", *reset = "";
+               if (push_had_errors(to)) {
+                       red = transport_get_color(TRANSPORT_COLOR_REJECTED);
+                       reset = transport_get_color(TRANSPORT_COLOR_RESET);
+               }
+               fprintf(stderr, " %s%c %-*s%s ", red, flag, summary_width,
+                       summary, reset);
                if (from)
                        fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
                else
@@ -367,7 +460,7 @@ static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_widt
                char type;
                const char *msg;
 
-               strbuf_add_unique_abbrev(&quickref, ref->old_oid.hash,
+               strbuf_add_unique_abbrev(&quickref, &ref->old_oid,
                                         DEFAULT_ABBREV);
                if (ref->forced_update) {
                        strbuf_addstr(&quickref, "...");
@@ -378,7 +471,7 @@ static void print_ok_ref_status(struct ref *ref, int porcelain, int summary_widt
                        type = ' ';
                        msg = NULL;
                }
-               strbuf_add_unique_abbrev(&quickref, ref->new_oid.hash,
+               strbuf_add_unique_abbrev(&quickref, &ref->new_oid,
                                         DEFAULT_ABBREV);
 
                print_ref_status(type, quickref.buf, ref, ref->peer_ref, msg,
@@ -461,7 +554,7 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count,
 static int measure_abbrev(const struct object_id *oid, int sofar)
 {
        char hex[GIT_MAX_HEXSZ + 1];
-       int w = find_unique_abbrev_r(hex, oid->hash, DEFAULT_ABBREV);
+       int w = find_unique_abbrev_r(hex, oid, DEFAULT_ABBREV);
 
        return (w < sofar) ? sofar : w;
 }
@@ -487,6 +580,9 @@ void transport_print_push_status(const char *dest, struct ref *refs,
        char *head;
        int summary_width = transport_summary_width(refs);
 
+       if (transport_color_config() < 0)
+               warning(_("could not parse transport.color.* config"));
+
        head = resolve_refdup("HEAD", RESOLVE_REF_READING, NULL, NULL);
 
        if (verbose) {
@@ -524,43 +620,17 @@ void transport_print_push_status(const char *dest, struct ref *refs,
        free(head);
 }
 
-void transport_verify_remote_names(int nr_heads, const char **heads)
-{
-       int i;
-
-       for (i = 0; i < nr_heads; i++) {
-               const char *local = heads[i];
-               const char *remote = strrchr(heads[i], ':');
-
-               if (*local == '+')
-                       local++;
-
-               /* A matching refspec is okay.  */
-               if (remote == local && remote[1] == '\0')
-                       continue;
-
-               remote = remote ? (remote + 1) : local;
-               if (check_refname_format(remote,
-                               REFNAME_ALLOW_ONELEVEL|REFNAME_REFSPEC_PATTERN))
-                       die("remote part of refspec is not a valid name in %s",
-                               heads[i]);
-       }
-}
-
 static int git_transport_push(struct transport *transport, struct ref *remote_refs, int flags)
 {
        struct git_transport_data *data = transport->data;
        struct send_pack_args args;
-       int ret;
+       int ret = 0;
 
-       if (!data->got_remote_heads) {
-               struct ref *tmp_refs;
-               connect_setup(transport, 1);
+       if (transport_color_config() < 0)
+               return -1;
 
-               get_remote_heads(data->fd[0], NULL, 0, &tmp_refs, REF_NORMAL,
-                                NULL, &data->shallow);
-               data->got_remote_heads = 1;
-       }
+       if (!data->got_remote_heads)
+               get_refs_via_connect(transport, 1, NULL);
 
        memset(&args, 0, sizeof(args));
        args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
@@ -582,8 +652,18 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
        else
                args.push_cert = SEND_PACK_PUSH_CERT_NEVER;
 
-       ret = send_pack(&args, data->fd, data->conn, remote_refs,
-                       &data->extra_have);
+       switch (data->version) {
+       case protocol_v2:
+               die("support for protocol v2 not implemented yet");
+               break;
+       case protocol_v1:
+       case protocol_v0:
+               ret = send_pack(&args, data->fd, data->conn, remote_refs,
+                               &data->extra_have);
+               break;
+       case protocol_unknown_version:
+               BUG("unknown protocol version");
+       }
 
        close(data->fd[1]);
        close(data->fd[0]);
@@ -635,7 +715,7 @@ void transport_take_over(struct transport *transport,
        struct git_transport_data *data;
 
        if (!transport->smart_options)
-               die("BUG: taking over transport requires non-NULL "
+               BUG("taking over transport requires non-NULL "
                    "smart_options field.");
 
        data = xcalloc(1, sizeof(*data));
@@ -760,7 +840,7 @@ int is_transport_allowed(const char *type, int from_user)
                return from_user;
        }
 
-       die("BUG: invalid protocol_allow_config type");
+       BUG("invalid protocol_allow_config type");
 }
 
 void transport_check_allowed(const char *type)
@@ -991,11 +1071,13 @@ static int run_pre_push_hook(struct transport *transport,
 }
 
 int transport_push(struct transport *transport,
-                  int refspec_nr, const char **refspec, int flags,
+                  struct refspec *rs, int flags,
                   unsigned int *reject_reasons)
 {
        *reject_reasons = 0;
-       transport_verify_remote_names(refspec_nr, refspec);
+
+       if (transport_color_config() < 0)
+               return -1;
 
        if (transport->vtable->push_refs) {
                struct ref *remote_refs;
@@ -1006,11 +1088,17 @@ int transport_push(struct transport *transport,
                int porcelain = flags & TRANSPORT_PUSH_PORCELAIN;
                int pretend = flags & TRANSPORT_PUSH_DRY_RUN;
                int push_ret, ret, err;
+               struct argv_array ref_prefixes = ARGV_ARRAY_INIT;
 
-               if (check_push_refs(local_refs, refspec_nr, refspec) < 0)
+               if (check_push_refs(local_refs, rs) < 0)
                        return -1;
 
-               remote_refs = transport->vtable->get_refs_list(transport, 1);
+               refspec_ref_prefixes(rs, &ref_prefixes);
+
+               remote_refs = transport->vtable->get_refs_list(transport, 1,
+                                                              &ref_prefixes);
+
+               argv_array_clear(&ref_prefixes);
 
                if (flags & TRANSPORT_PUSH_ALL)
                        match_flags |= MATCH_REFS_ALL;
@@ -1021,10 +1109,8 @@ int transport_push(struct transport *transport,
                if (flags & TRANSPORT_PUSH_FOLLOW_TAGS)
                        match_flags |= MATCH_REFS_FOLLOW_TAGS;
 
-               if (match_push_refs(local_refs, &remote_refs,
-                                   refspec_nr, refspec, match_flags)) {
+               if (match_push_refs(local_refs, &remote_refs, rs, match_flags))
                        return -1;
-               }
 
                if (transport->smart_options &&
                    transport->smart_options->cas &&
@@ -1053,7 +1139,7 @@ int transport_push(struct transport *transport,
 
                        if (!push_unpushed_submodules(&commits,
                                                      transport->remote,
-                                                     refspec, refspec_nr,
+                                                     rs,
                                                      transport->push_options,
                                                      pretend)) {
                                oid_array_clear(&commits);
@@ -1116,10 +1202,13 @@ int transport_push(struct transport *transport,
        return 1;
 }
 
-const struct ref *transport_get_remote_refs(struct transport *transport)
+const struct ref *transport_get_remote_refs(struct transport *transport,
+                                           const struct argv_array *ref_prefixes)
 {
        if (!transport->got_remote_refs) {
-               transport->remote_refs = transport->vtable->get_refs_list(transport, 0);
+               transport->remote_refs =
+                       transport->vtable->get_refs_list(transport, 0,
+                                                        ref_prefixes);
                transport->got_remote_refs = 1;
        }
 
index 3c68d73b215bbabc81a75a810b1083697bfd6329..7792b08582c132e18b495a21b700d9113727c7eb 100644 (file)
@@ -59,12 +59,24 @@ struct transport {
         */
        unsigned cloning : 1;
 
+       /*
+        * Indicates that the transport is connected via a half-duplex
+        * connection and should operate in stateless-rpc mode.
+        */
+       unsigned stateless_rpc : 1;
+
        /*
         * These strings will be passed to the {pre, post}-receive hook,
         * on the remote side, if both sides support the push options capability.
         */
        const struct string_list *push_options;
 
+       /*
+        * These strings will be passed to the remote side on each command
+        * request, if both sides support the server-option capability.
+        */
+       const struct string_list *server_options;
+
        char *pack_lockfile;
        signed verbose : 3;
        /**
@@ -191,10 +203,20 @@ void transport_set_verbosity(struct transport *transport, int verbosity,
 #define REJECT_NEEDS_FORCE     0x10
 
 int transport_push(struct transport *connection,
-                  int refspec_nr, const char **refspec, int flags,
+                  struct refspec *rs, int flags,
                   unsigned int * reject_reasons);
 
-const struct ref *transport_get_remote_refs(struct transport *transport);
+/*
+ * Retrieve refs from a remote.
+ *
+ * Optionally a list of ref prefixes can be provided which can be sent to the
+ * server (when communicating using protocol v2) to enable it to limit the ref
+ * advertisement.  Since ref filtering is done on the server's end (and only
+ * when using protocol v2), this can return refs which don't match the provided
+ * ref_prefixes.
+ */
+const struct ref *transport_get_remote_refs(struct transport *transport,
+                                           const struct argv_array *ref_prefixes);
 
 int transport_fetch_refs(struct transport *transport, struct ref *refs);
 void transport_unlock_pack(struct transport *transport);
@@ -211,8 +233,6 @@ int transport_helper_init(struct transport *transport, const char *name);
 int bidirectional_transfer_loop(int input, int output);
 
 /* common methods used by transport.c and builtin/send-pack.c */
-void transport_verify_remote_names(int nr_heads, const char **heads);
-
 void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose);
 
 int transport_refs_pushed(struct ref *ref);
index 3966b0ae44a5136a5a48ed14ed745fa73b0de93a..766131039b7fbafef713565dc601a47b7ce27ca7 100644 (file)
@@ -90,8 +90,7 @@ void *fill_tree_descriptor(struct tree_desc *desc, const struct object_id *oid)
        void *buf = NULL;
 
        if (oid) {
-               buf = read_object_with_reference(oid->hash, tree_type, &size,
-                                                NULL);
+               buf = read_object_with_reference(oid, tree_type, &size, NULL);
                if (!buf)
                        die("unable to read tree %s", oid_to_hex(oid));
        }
@@ -112,7 +111,7 @@ static void entry_extract(struct tree_desc *t, struct name_entry *a)
 static int update_tree_entry_internal(struct tree_desc *desc, struct strbuf *err)
 {
        const void *buf = desc->buffer;
-       const unsigned char *end = desc->entry.oid->hash + 20;
+       const unsigned char *end = desc->entry.oid->hash + the_hash_algo->rawsz;
        unsigned long size = desc->size;
        unsigned long len = end - (const unsigned char *)buf;
 
@@ -495,10 +494,10 @@ int traverse_trees(int n, struct tree_desc *t, struct traverse_info *info)
 struct dir_state {
        void *tree;
        unsigned long size;
-       unsigned char sha1[20];
+       struct object_id oid;
 };
 
-static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char *result, unsigned *mode)
+static int find_tree_entry(struct tree_desc *t, const char *name, struct object_id *result, unsigned *mode)
 {
        int namelen = strlen(name);
        while (t->size) {
@@ -517,7 +516,7 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char
                if (cmp < 0)
                        break;
                if (entrylen == namelen) {
-                       hashcpy(result, oid->hash);
+                       oidcpy(result, oid);
                        return 0;
                }
                if (name[entrylen] != '/')
@@ -525,27 +524,27 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char
                if (!S_ISDIR(*mode))
                        break;
                if (++entrylen == namelen) {
-                       hashcpy(result, oid->hash);
+                       oidcpy(result, oid);
                        return 0;
                }
-               return get_tree_entry(oid->hash, name + entrylen, result, mode);
+               return get_tree_entry(oid, name + entrylen, result, mode);
        }
        return -1;
 }
 
-int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned char *sha1, unsigned *mode)
+int get_tree_entry(const struct object_id *tree_oid, const char *name, struct object_id *oid, unsigned *mode)
 {
        int retval;
        void *tree;
        unsigned long size;
-       unsigned char root[20];
+       struct object_id root;
 
-       tree = read_object_with_reference(tree_sha1, tree_type, &size, root);
+       tree = read_object_with_reference(tree_oid, tree_type, &size, &root);
        if (!tree)
                return -1;
 
        if (name[0] == '\0') {
-               hashcpy(sha1, root);
+               oidcpy(oid, &root);
                free(tree);
                return 0;
        }
@@ -555,7 +554,7 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
        } else {
                struct tree_desc t;
                init_tree_desc(&t, tree, size);
-               retval = find_tree_entry(&t, name, sha1, mode);
+               retval = find_tree_entry(&t, name, oid, mode);
        }
        free(tree);
        return retval;
@@ -583,20 +582,20 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
  * See the code for enum follow_symlink_result for a description of
  * the return values.
  */
-enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_sha1, const char *name, unsigned char *result, struct strbuf *result_path, unsigned *mode)
+enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode)
 {
        int retval = MISSING_OBJECT;
        struct dir_state *parents = NULL;
        size_t parents_alloc = 0;
        size_t i, parents_nr = 0;
-       unsigned char current_tree_sha1[20];
+       struct object_id current_tree_oid;
        struct strbuf namebuf = STRBUF_INIT;
        struct tree_desc t;
        int follows_remaining = GET_TREE_ENTRY_FOLLOW_SYMLINKS_MAX_LINKS;
 
        init_tree_desc(&t, NULL, 0UL);
        strbuf_addstr(&namebuf, name);
-       hashcpy(current_tree_sha1, tree_sha1);
+       oidcpy(&current_tree_oid, tree_oid);
 
        while (1) {
                int find_result;
@@ -605,22 +604,22 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s
 
                if (!t.buffer) {
                        void *tree;
-                       unsigned char root[20];
+                       struct object_id root;
                        unsigned long size;
-                       tree = read_object_with_reference(current_tree_sha1,
+                       tree = read_object_with_reference(&current_tree_oid,
                                                          tree_type, &size,
-                                                         root);
+                                                         &root);
                        if (!tree)
                                goto done;
 
                        ALLOC_GROW(parents, parents_nr + 1, parents_alloc);
                        parents[parents_nr].tree = tree;
                        parents[parents_nr].size = size;
-                       hashcpy(parents[parents_nr].sha1, root);
+                       oidcpy(&parents[parents_nr].oid, &root);
                        parents_nr++;
 
                        if (namebuf.buf[0] == '\0') {
-                               hashcpy(result, root);
+                               oidcpy(result, &root);
                                retval = FOUND;
                                goto done;
                        }
@@ -670,21 +669,21 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s
 
                /* We could end up here via a symlink to dir/.. */
                if (namebuf.buf[0] == '\0') {
-                       hashcpy(result, parents[parents_nr - 1].sha1);
+                       oidcpy(result, &parents[parents_nr - 1].oid);
                        retval = FOUND;
                        goto done;
                }
 
                /* Look up the first (or only) path component in the tree. */
                find_result = find_tree_entry(&t, namebuf.buf,
-                                             current_tree_sha1, mode);
+                                             &current_tree_oid, mode);
                if (find_result) {
                        goto done;
                }
 
                if (S_ISDIR(*mode)) {
                        if (!remainder) {
-                               hashcpy(result, current_tree_sha1);
+                               oidcpy(result, &current_tree_oid);
                                retval = FOUND;
                                goto done;
                        }
@@ -694,7 +693,7 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s
                                      1 + first_slash - namebuf.buf);
                } else if (S_ISREG(*mode)) {
                        if (!remainder) {
-                               hashcpy(result, current_tree_sha1);
+                               oidcpy(result, &current_tree_oid);
                                retval = FOUND;
                        } else {
                                retval = NOT_DIR;
@@ -720,8 +719,8 @@ enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_s
                         */
                        retval = DANGLING_SYMLINK;
 
-                       contents = read_sha1_file(current_tree_sha1, &type,
-                                                 &link_len);
+                       contents = read_object_file(&current_tree_oid, &type,
+                                                   &link_len);
 
                        if (!contents)
                                goto done;
index b6bd1b4ccfbb8bb69c464ea687c63a2058a424b8..805f58f00f6f0d4c9e6f6f05520bd1cd62d5f661 100644 (file)
@@ -64,7 +64,7 @@ enum follow_symlinks_result {
                       */
 };
 
-enum follow_symlinks_result get_tree_entry_follow_symlinks(unsigned char *tree_sha1, const char *name, unsigned char *result, struct strbuf *result_path, unsigned *mode);
+enum follow_symlinks_result get_tree_entry_follow_symlinks(struct object_id *tree_oid, const char *name, struct object_id *result, struct strbuf *result_path, unsigned *mode);
 
 struct traverse_info {
        const char *traverse_path;
@@ -79,7 +79,7 @@ struct traverse_info {
        int show_all_errors;
 };
 
-int get_tree_entry(const unsigned char *, const char *, unsigned char *, unsigned *);
+int get_tree_entry(const struct object_id *, const char *, struct object_id *, unsigned *);
 extern char *make_traverse_path(char *path, const struct traverse_info *info, const struct name_entry *n);
 extern void setup_traverse_info(struct traverse_info *info, const char *base);
 
diff --git a/tree.c b/tree.c
index b224115e0f4d61368560eba406a04f0259b7c4f0..244eb5e665e931a6b735366d74b5ed2bcbce4c9b 100644 (file)
--- a/tree.c
+++ b/tree.c
@@ -10,7 +10,7 @@
 const char *tree_type = "tree";
 
 static int read_one_entry_opt(struct index_state *istate,
-                             const unsigned char *sha1,
+                             const struct object_id *oid,
                              const char *base, int baselen,
                              const char *pathname,
                              unsigned mode, int stage, int opt)
@@ -31,16 +31,16 @@ static int read_one_entry_opt(struct index_state *istate,
        ce->ce_namelen = baselen + len;
        memcpy(ce->name, base, baselen);
        memcpy(ce->name + baselen, pathname, len+1);
-       hashcpy(ce->oid.hash, sha1);
+       oidcpy(&ce->oid, oid);
        return add_index_entry(istate, ce, opt);
 }
 
-static int read_one_entry(const unsigned char *sha1, struct strbuf *base,
+static int read_one_entry(const struct object_id *oid, struct strbuf *base,
                          const char *pathname, unsigned mode, int stage,
                          void *context)
 {
        struct index_state *istate = context;
-       return read_one_entry_opt(istate, sha1, base->buf, base->len, pathname,
+       return read_one_entry_opt(istate, oid, base->buf, base->len, pathname,
                                  mode, stage,
                                  ADD_CACHE_OK_TO_ADD|ADD_CACHE_SKIP_DFCHECK);
 }
@@ -49,12 +49,12 @@ static int read_one_entry(const unsigned char *sha1, struct strbuf *base,
  * This is used when the caller knows there is no existing entries at
  * the stage that will conflict with the entry being added.
  */
-static int read_one_entry_quick(const unsigned char *sha1, struct strbuf *base,
+static int read_one_entry_quick(const struct object_id *oid, struct strbuf *base,
                                const char *pathname, unsigned mode, int stage,
                                void *context)
 {
        struct index_state *istate = context;
-       return read_one_entry_opt(istate, sha1, base->buf, base->len, pathname,
+       return read_one_entry_opt(istate, oid, base->buf, base->len, pathname,
                                  mode, stage,
                                  ADD_CACHE_JUST_APPEND);
 }
@@ -83,7 +83,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
                                continue;
                }
 
-               switch (fn(entry.oid->hash, base,
+               switch (fn(entry.oid, base,
                           entry.path, entry.mode, stage, context)) {
                case 0:
                        continue;
@@ -109,7 +109,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base,
                                    oid_to_hex(entry.oid),
                                    base->buf, entry.path);
 
-                       oidcpy(&oid, &commit->tree->object.oid);
+                       oidcpy(&oid, get_commit_tree_oid(commit));
                }
                else
                        continue;
@@ -219,7 +219,7 @@ int parse_tree_gently(struct tree *item, int quiet_on_missing)
 
        if (item->object.parsed)
                return 0;
-       buffer = read_sha1_file(item->object.oid.hash, &type, &size);
+       buffer = read_object_file(&item->object.oid, &type, &size);
        if (!buffer)
                return quiet_on_missing ? -1 :
                        error("Could not read %s",
@@ -248,7 +248,7 @@ struct tree *parse_tree_indirect(const struct object_id *oid)
                if (obj->type == OBJ_TREE)
                        return (struct tree *) obj;
                else if (obj->type == OBJ_COMMIT)
-                       obj = &(((struct commit *) obj)->tree->object);
+                       obj = &(get_commit_tree(((struct commit *)obj))->object);
                else if (obj->type == OBJ_TAG)
                        obj = ((struct tag *) obj)->tagged;
                else
diff --git a/tree.h b/tree.h
index 744e6dc2ac883adfa0e079f5f84f45a45e22b59d..e2a80be4ef87e35d895e8591a0f8a75df347d347 100644 (file)
--- a/tree.h
+++ b/tree.h
@@ -27,7 +27,7 @@ void free_tree_buffer(struct tree *tree);
 struct tree *parse_tree_indirect(const struct object_id *oid);
 
 #define READ_TREE_RECURSIVE 1
-typedef int (*read_tree_fn_t)(const unsigned char *, struct strbuf *, const char *, unsigned int, int, void *);
+typedef int (*read_tree_fn_t)(const struct object_id *, struct strbuf *, const char *, unsigned int, int, void *);
 
 extern int read_tree_recursive(struct tree *tree,
                               const char *base, int baselen,
similarity index 100%
rename from unicode_width.h
rename to unicode-width.h
index 88a0b5d250ef1da36747fe0b736df4305979977d..a733555defb5e7726028fdc90ff37732611356b7 100644 (file)
@@ -1,5 +1,6 @@
 #define NO_THE_INDEX_COMPATIBILITY_MACROS
 #include "cache.h"
+#include "argv-array.h"
 #include "repository.h"
 #include "config.h"
 #include "dir.h"
@@ -103,6 +104,8 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
        const char **msgs = opts->msgs;
        const char *msg;
 
+       argv_array_init(&opts->msgs_to_free);
+
        if (!strcmp(cmd, "checkout"))
                msg = advice_commit_before_merge
                      ? _("Your local changes to the following files would be overwritten by checkout:\n%%s"
@@ -119,7 +122,7 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
                          "Please commit your changes or stash them before you %s.")
                      : _("Your local changes to the following files would be overwritten by %s:\n%%s");
        msgs[ERROR_WOULD_OVERWRITE] = msgs[ERROR_NOT_UPTODATE_FILE] =
-               xstrfmt(msg, cmd, cmd);
+               argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd);
 
        msgs[ERROR_NOT_UPTODATE_DIR] =
                _("Updating the following directories would lose untracked files in them:\n%s");
@@ -139,7 +142,8 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
                      ? _("The following untracked working tree files would be removed by %s:\n%%s"
                          "Please move or remove them before you %s.")
                      : _("The following untracked working tree files would be removed by %s:\n%%s");
-       msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = xstrfmt(msg, cmd, cmd);
+       msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] =
+               argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd);
 
        if (!strcmp(cmd, "checkout"))
                msg = advice_commit_before_merge
@@ -156,7 +160,8 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
                      ? _("The following untracked working tree files would be overwritten by %s:\n%%s"
                          "Please move or remove them before you %s.")
                      : _("The following untracked working tree files would be overwritten by %s:\n%%s");
-       msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = xstrfmt(msg, cmd, cmd);
+       msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] =
+               argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd);
 
        /*
         * Special case: ERROR_BIND_OVERLAP refers to a pair of paths, we
@@ -179,6 +184,12 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
                opts->unpack_rejects[i].strdup_strings = 1;
 }
 
+void clear_unpack_trees_porcelain(struct unpack_trees_options *opts)
+{
+       argv_array_clear(&opts->msgs_to_free);
+       memset(opts->msgs, 0, sizeof(opts->msgs));
+}
+
 static int do_add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
                         unsigned int set, unsigned int clear)
 {
@@ -290,7 +301,7 @@ static void load_gitmodules_file(struct index_state *index,
                if (!state && ce->ce_flags & CE_WT_REMOVE) {
                        repo_read_gitmodules(the_repository);
                } else if (state && (ce->ce_flags & CE_UPDATE)) {
-                       submodule_free();
+                       submodule_free(the_repository);
                        checkout_entry(ce, state, NULL);
                        repo_read_gitmodules(the_repository);
                }
@@ -398,7 +409,7 @@ static int check_updates(struct unpack_trees_options *o)
 
                if (ce->ce_flags & CE_UPDATE) {
                        if (ce->ce_flags & CE_WT_REMOVE)
-                               die("BUG: both update and delete flags are set on %s",
+                               BUG("both update and delete flags are set on %s",
                                    ce->name);
                        display_progress(progress, ++cnt);
                        ce->ce_flags &= ~CE_UPDATE;
@@ -1284,10 +1295,21 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
        o->result.timestamp.sec = o->src_index->timestamp.sec;
        o->result.timestamp.nsec = o->src_index->timestamp.nsec;
        o->result.version = o->src_index->version;
-       o->result.split_index = o->src_index->split_index;
-       if (o->result.split_index)
+       if (!o->src_index->split_index) {
+               o->result.split_index = NULL;
+       } else if (o->src_index == o->dst_index) {
+               /*
+                * o->dst_index (and thus o->src_index) will be discarded
+                * and overwritten with o->result at the end of this function,
+                * so just use src_index's split_index to avoid having to
+                * create a new one.
+                */
+               o->result.split_index = o->src_index->split_index;
                o->result.split_index->refcount++;
-       hashcpy(o->result.sha1, o->src_index->sha1);
+       } else {
+               o->result.split_index = init_split_index(&o->result);
+       }
+       oidcpy(&o->result.oid, &o->src_index->oid);
        o->merge_size = len;
        mark_all_ce_unused(o->src_index);
 
@@ -1401,7 +1423,6 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
                }
        }
 
-       o->src_index = NULL;
        ret = check_updates(o) ? (-2) : 0;
        if (o->dst_index) {
                if (!ret) {
@@ -1412,12 +1433,13 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options
                                                  WRITE_TREE_SILENT |
                                                  WRITE_TREE_REPAIR);
                }
-               move_index_extensions(&o->result, o->dst_index);
+               move_index_extensions(&o->result, o->src_index);
                discard_index(o->dst_index);
                *o->dst_index = o->result;
        } else {
                discard_index(&o->result);
        }
+       o->src_index = NULL;
 
 done:
        clear_exclude_list(&el);
@@ -1509,8 +1531,8 @@ static int verify_uptodate_1(const struct cache_entry *ce,
                add_rejected_path(o, error_type, ce->name);
 }
 
-static int verify_uptodate(const struct cache_entry *ce,
-                          struct unpack_trees_options *o)
+int verify_uptodate(const struct cache_entry *ce,
+                   struct unpack_trees_options *o)
 {
        if (!o->skip_sparse_checkout && (ce->ce_flags & CE_NEW_SKIP_WORKTREE))
                return 0;
index 6c48117b845fbf7b983852be302e4472c5e6d651..c2b434c60648fb0e287c100a32d9346a765ab74f 100644 (file)
@@ -1,7 +1,8 @@
 #ifndef UNPACK_TREES_H
 #define UNPACK_TREES_H
 
-#include "string-list.h"
+#include "tree-walk.h"
+#include "argv-array.h"
 
 #define MAX_UNPACK_TREES 8
 
@@ -32,6 +33,11 @@ enum unpack_trees_error_types {
 void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
                                  const char *cmd);
 
+/*
+ * Frees resources allocated by setup_unpack_trees_porcelain().
+ */
+void clear_unpack_trees_porcelain(struct unpack_trees_options *opts);
+
 struct unpack_trees_options {
        unsigned int reset,
                     merge,
@@ -56,6 +62,7 @@ struct unpack_trees_options {
        struct pathspec *pathspec;
        merge_fn_t fn;
        const char *msgs[NB_UNPACK_TREES_ERROR_TYPES];
+       struct argv_array msgs_to_free;
        /*
         * Store error messages in an array, each case
         * corresponding to a error message type
@@ -78,6 +85,9 @@ struct unpack_trees_options {
 extern int unpack_trees(unsigned n, struct tree_desc *t,
                struct unpack_trees_options *options);
 
+int verify_uptodate(const struct cache_entry *ce,
+                   struct unpack_trees_options *o);
+
 int threeway_merge(const struct cache_entry * const *stages,
                   struct unpack_trees_options *o);
 int twoway_merge(const struct cache_entry * const *src,
index 4a82602be5d0ab111a805a2f2456f382ae7a7364..87c6722ea58207a9b369e75f7cf7ac16a705330b 100644 (file)
@@ -6,7 +6,6 @@
 #include "tag.h"
 #include "object.h"
 #include "commit.h"
-#include "exec_cmd.h"
 #include "diff.h"
 #include "revision.h"
 #include "list-objects.h"
 #include "sigchain.h"
 #include "version.h"
 #include "string-list.h"
-#include "parse-options.h"
 #include "argv-array.h"
 #include "prio-queue.h"
 #include "protocol.h"
 #include "quote.h"
-
-static const char * const upload_pack_usage[] = {
-       N_("git upload-pack [<options>] <dir>"),
-       NULL
-};
+#include "upload-pack.h"
+#include "serve.h"
 
 /* Remember to update object flag allocation in object.h */
 #define THEY_HAVE      (1u << 11)
@@ -64,7 +59,6 @@ static int keepalive = 5;
  * otherwise maximum packet size (up to 65520 bytes).
  */
 static int use_sideband;
-static int advertise_refs;
 static int stateless_rpc;
 static const char *pack_objects_hook;
 
@@ -450,7 +444,7 @@ static int get_common_commits(void)
                                break;
                        default:
                                got_common = 1;
-                               memcpy(last_hex, oid_to_hex(&oid), 41);
+                               oid_to_hex_r(last_hex, &oid);
                                if (multi_ack == 2)
                                        packet_write_fmt(1, "ACK %s common\n", last_hex);
                                else if (multi_ack)
@@ -492,7 +486,7 @@ static int do_reachable_revlist(struct child_process *cmd,
                "rev-list", "--stdin", NULL,
        };
        struct object *o;
-       char namebuf[42]; /* ^ + SHA-1 + LF */
+       char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */
        int i;
 
        cmd->argv = argv;
@@ -561,15 +555,17 @@ static int get_reachable_list(struct object_array *src,
        struct child_process cmd = CHILD_PROCESS_INIT;
        int i;
        struct object *o;
-       char namebuf[42]; /* ^ + SHA-1 + LF */
+       char namebuf[GIT_MAX_HEXSZ + 2]; /* ^ + hash + LF */
+       const unsigned hexsz = the_hash_algo->hexsz;
 
        if (do_reachable_revlist(&cmd, src, reachable) < 0)
                return -1;
 
-       while ((i = read_in_full(cmd.out, namebuf, 41)) == 41) {
+       while ((i = read_in_full(cmd.out, namebuf, hexsz + 1)) == hexsz + 1) {
                struct object_id sha1;
+               const char *p;
 
-               if (namebuf[40] != '\n' || get_oid_hex(namebuf, &sha1))
+               if (parse_oid_hex(namebuf, &sha1, &p) || *p != '\n')
                        break;
 
                o = lookup_object(sha1.hash);
@@ -734,7 +730,6 @@ static void deepen(int depth, int deepen_relative,
        }
 
        send_unshallow(shallows);
-       packet_flush(1);
 }
 
 static void deepen_by_rev_list(int ac, const char **av,
@@ -746,7 +741,122 @@ static void deepen_by_rev_list(int ac, const char **av,
        send_shallow(result);
        free_commit_list(result);
        send_unshallow(shallows);
-       packet_flush(1);
+}
+
+/* Returns 1 if a shallow list is sent or 0 otherwise */
+static int send_shallow_list(int depth, int deepen_rev_list,
+                            timestamp_t deepen_since,
+                            struct string_list *deepen_not,
+                            struct object_array *shallows)
+{
+       int ret = 0;
+
+       if (depth > 0 && deepen_rev_list)
+               die("git upload-pack: deepen and deepen-since (or deepen-not) cannot be used together");
+       if (depth > 0) {
+               deepen(depth, deepen_relative, shallows);
+               ret = 1;
+       } else if (deepen_rev_list) {
+               struct argv_array av = ARGV_ARRAY_INIT;
+               int i;
+
+               argv_array_push(&av, "rev-list");
+               if (deepen_since)
+                       argv_array_pushf(&av, "--max-age=%"PRItime, deepen_since);
+               if (deepen_not->nr) {
+                       argv_array_push(&av, "--not");
+                       for (i = 0; i < deepen_not->nr; i++) {
+                               struct string_list_item *s = deepen_not->items + i;
+                               argv_array_push(&av, s->string);
+                       }
+                       argv_array_push(&av, "--not");
+               }
+               for (i = 0; i < want_obj.nr; i++) {
+                       struct object *o = want_obj.objects[i].item;
+                       argv_array_push(&av, oid_to_hex(&o->oid));
+               }
+               deepen_by_rev_list(av.argc, av.argv, shallows);
+               argv_array_clear(&av);
+               ret = 1;
+       } else {
+               if (shallows->nr > 0) {
+                       int i;
+                       for (i = 0; i < shallows->nr; i++)
+                               register_shallow(&shallows->objects[i].item->oid);
+               }
+       }
+
+       shallow_nr += shallows->nr;
+       return ret;
+}
+
+static int process_shallow(const char *line, struct object_array *shallows)
+{
+       const char *arg;
+       if (skip_prefix(line, "shallow ", &arg)) {
+               struct object_id oid;
+               struct object *object;
+               if (get_oid_hex(arg, &oid))
+                       die("invalid shallow line: %s", line);
+               object = parse_object(&oid);
+               if (!object)
+                       return 1;
+               if (object->type != OBJ_COMMIT)
+                       die("invalid shallow object %s", oid_to_hex(&oid));
+               if (!(object->flags & CLIENT_SHALLOW)) {
+                       object->flags |= CLIENT_SHALLOW;
+                       add_object_array(object, NULL, shallows);
+               }
+               return 1;
+       }
+
+       return 0;
+}
+
+static int process_deepen(const char *line, int *depth)
+{
+       const char *arg;
+       if (skip_prefix(line, "deepen ", &arg)) {
+               char *end = NULL;
+               *depth = (int)strtol(arg, &end, 0);
+               if (!end || *end || *depth <= 0)
+                       die("Invalid deepen: %s", line);
+               return 1;
+       }
+
+       return 0;
+}
+
+static int process_deepen_since(const char *line, timestamp_t *deepen_since, int *deepen_rev_list)
+{
+       const char *arg;
+       if (skip_prefix(line, "deepen-since ", &arg)) {
+               char *end = NULL;
+               *deepen_since = parse_timestamp(arg, &end, 0);
+               if (!end || *end || !deepen_since ||
+                   /* revisions.c's max_age -1 is special */
+                   *deepen_since == -1)
+                       die("Invalid deepen-since: %s", line);
+               *deepen_rev_list = 1;
+               return 1;
+       }
+       return 0;
+}
+
+static int process_deepen_not(const char *line, struct string_list *deepen_not, int *deepen_rev_list)
+{
+       const char *arg;
+       if (skip_prefix(line, "deepen-not ", &arg)) {
+               char *ref = NULL;
+               struct object_id oid;
+               if (expand_ref(arg, strlen(arg), &oid, &ref) != 1)
+                       die("git upload-pack: ambiguous deepen-not: %s", line);
+               string_list_append(deepen_not, ref);
+               free(ref);
+               *deepen_rev_list = 1;
+               return 1;
+       }
+       return 0;
 }
 
 static void receive_needs(void)
@@ -770,61 +880,26 @@ static void receive_needs(void)
                if (!line)
                        break;
 
-               if (skip_prefix(line, "shallow ", &arg)) {
-                       struct object_id oid;
-                       struct object *object;
-                       if (get_oid_hex(arg, &oid))
-                               die("invalid shallow line: %s", line);
-                       object = parse_object(&oid);
-                       if (!object)
-                               continue;
-                       if (object->type != OBJ_COMMIT)
-                               die("invalid shallow object %s", oid_to_hex(&oid));
-                       if (!(object->flags & CLIENT_SHALLOW)) {
-                               object->flags |= CLIENT_SHALLOW;
-                               add_object_array(object, NULL, &shallows);
-                       }
+               if (process_shallow(line, &shallows))
                        continue;
-               }
-               if (skip_prefix(line, "deepen ", &arg)) {
-                       char *end = NULL;
-                       depth = strtol(arg, &end, 0);
-                       if (!end || *end || depth <= 0)
-                               die("Invalid deepen: %s", line);
+               if (process_deepen(line, &depth))
                        continue;
-               }
-               if (skip_prefix(line, "deepen-since ", &arg)) {
-                       char *end = NULL;
-                       deepen_since = parse_timestamp(arg, &end, 0);
-                       if (!end || *end || !deepen_since ||
-                           /* revisions.c's max_age -1 is special */
-                           deepen_since == -1)
-                               die("Invalid deepen-since: %s", line);
-                       deepen_rev_list = 1;
+               if (process_deepen_since(line, &deepen_since, &deepen_rev_list))
                        continue;
-               }
-               if (skip_prefix(line, "deepen-not ", &arg)) {
-                       char *ref = NULL;
-                       struct object_id oid;
-                       if (expand_ref(arg, strlen(arg), &oid, &ref) != 1)
-                               die("git upload-pack: ambiguous deepen-not: %s", line);
-                       string_list_append(&deepen_not, ref);
-                       free(ref);
-                       deepen_rev_list = 1;
+               if (process_deepen_not(line, &deepen_not, &deepen_rev_list))
                        continue;
-               }
+
                if (skip_prefix(line, "filter ", &arg)) {
                        if (!filter_capability_requested)
                                die("git upload-pack: filtering capability not negotiated");
                        parse_list_objects_filter(&filter_options, arg);
                        continue;
                }
+
                if (!skip_prefix(line, "want ", &arg) ||
-                   get_oid_hex(arg, &oid_buf))
+                   parse_oid_hex(arg, &oid_buf, &features))
                        die("git upload-pack: protocol error, "
-                           "expected to get sha, not '%s'", line);
-
-               features = arg + 40;
+                           "expected to get object ID, not '%s'", line);
 
                if (parse_feature_request(features, "deepen-relative"))
                        deepen_relative = 1;
@@ -881,40 +956,10 @@ static void receive_needs(void)
 
        if (depth == 0 && !deepen_rev_list && shallows.nr == 0)
                return;
-       if (depth > 0 && deepen_rev_list)
-               die("git upload-pack: deepen and deepen-since (or deepen-not) cannot be used together");
-       if (depth > 0)
-               deepen(depth, deepen_relative, &shallows);
-       else if (deepen_rev_list) {
-               struct argv_array av = ARGV_ARRAY_INIT;
-               int i;
 
-               argv_array_push(&av, "rev-list");
-               if (deepen_since)
-                       argv_array_pushf(&av, "--max-age=%"PRItime, deepen_since);
-               if (deepen_not.nr) {
-                       argv_array_push(&av, "--not");
-                       for (i = 0; i < deepen_not.nr; i++) {
-                               struct string_list_item *s = deepen_not.items + i;
-                               argv_array_push(&av, s->string);
-                       }
-                       argv_array_push(&av, "--not");
-               }
-               for (i = 0; i < want_obj.nr; i++) {
-                       struct object *o = want_obj.objects[i].item;
-                       argv_array_push(&av, oid_to_hex(&o->oid));
-               }
-               deepen_by_rev_list(av.argc, av.argv, &shallows);
-               argv_array_clear(&av);
-       }
-       else
-               if (shallows.nr > 0) {
-                       int i;
-                       for (i = 0; i < shallows.nr; i++)
-                               register_shallow(&shallows.objects[i].item->oid);
-               }
-
-       shallow_nr += shallows.nr;
+       if (send_shallow_list(depth, deepen_rev_list, deepen_since,
+                             &deepen_not, &shallows))
+               packet_flush(1);
        object_array_clear(&shallows);
 }
 
@@ -1004,33 +1049,6 @@ static int find_symref(const char *refname, const struct object_id *oid,
        return 0;
 }
 
-static void upload_pack(void)
-{
-       struct string_list symref = STRING_LIST_INIT_DUP;
-
-       head_ref_namespaced(find_symref, &symref);
-
-       if (advertise_refs || !stateless_rpc) {
-               reset_timeout();
-               head_ref_namespaced(send_ref, &symref);
-               for_each_namespaced_ref(send_ref, &symref);
-               advertise_shallow_grafts(1);
-               packet_flush(1);
-       } else {
-               head_ref_namespaced(check_ref, NULL);
-               for_each_namespaced_ref(check_ref, NULL);
-       }
-       string_list_clear(&symref, 1);
-       if (advertise_refs)
-               return;
-
-       receive_needs();
-       if (want_obj.nr) {
-               get_common_commits();
-               create_pack_file();
-       }
-}
-
 static int upload_pack_config(const char *var, const char *value, void *unused)
 {
        if (!strcmp("uploadpack.allowtipsha1inwant", var)) {
@@ -1061,58 +1079,371 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
        return parse_hide_refs_config(var, value, "uploadpack");
 }
 
-int cmd_main(int argc, const char **argv)
+void upload_pack(struct upload_pack_options *options)
 {
-       const char *dir;
-       int strict = 0;
-       struct option options[] = {
-               OPT_BOOL(0, "stateless-rpc", &stateless_rpc,
-                        N_("quit after a single request/response exchange")),
-               OPT_BOOL(0, "advertise-refs", &advertise_refs,
-                        N_("exit immediately after initial ref advertisement")),
-               OPT_BOOL(0, "strict", &strict,
-                        N_("do not try <directory>/.git/ if <directory> is no Git directory")),
-               OPT_INTEGER(0, "timeout", &timeout,
-                           N_("interrupt transfer after <n> seconds of inactivity")),
-               OPT_END()
-       };
+       struct string_list symref = STRING_LIST_INIT_DUP;
 
-       packet_trace_identity("upload-pack");
-       check_replace_refs = 0;
+       stateless_rpc = options->stateless_rpc;
+       timeout = options->timeout;
+       daemon_mode = options->daemon_mode;
 
-       argc = parse_options(argc, argv, NULL, options, upload_pack_usage, 0);
+       git_config(upload_pack_config, NULL);
 
-       if (argc != 1)
-               usage_with_options(upload_pack_usage, options);
+       head_ref_namespaced(find_symref, &symref);
 
-       if (timeout)
-               daemon_mode = 1;
+       if (options->advertise_refs || !stateless_rpc) {
+               reset_timeout();
+               head_ref_namespaced(send_ref, &symref);
+               for_each_namespaced_ref(send_ref, &symref);
+               advertise_shallow_grafts(1);
+               packet_flush(1);
+       } else {
+               head_ref_namespaced(check_ref, NULL);
+               for_each_namespaced_ref(check_ref, NULL);
+       }
+       string_list_clear(&symref, 1);
+       if (options->advertise_refs)
+               return;
+
+       receive_needs();
+       if (want_obj.nr) {
+               get_common_commits();
+               create_pack_file();
+       }
+}
+
+struct upload_pack_data {
+       struct object_array wants;
+       struct oid_array haves;
 
-       setup_path();
+       struct object_array shallows;
+       struct string_list deepen_not;
+       int depth;
+       timestamp_t deepen_since;
+       int deepen_rev_list;
+       int deepen_relative;
 
-       dir = argv[0];
+       unsigned stateless_rpc : 1;
 
-       if (!enter_repo(dir, strict))
-               die("'%s' does not appear to be a git repository", dir);
+       unsigned use_thin_pack : 1;
+       unsigned use_ofs_delta : 1;
+       unsigned no_progress : 1;
+       unsigned use_include_tag : 1;
+       unsigned done : 1;
+};
+
+static void upload_pack_data_init(struct upload_pack_data *data)
+{
+       struct object_array wants = OBJECT_ARRAY_INIT;
+       struct oid_array haves = OID_ARRAY_INIT;
+       struct object_array shallows = OBJECT_ARRAY_INIT;
+       struct string_list deepen_not = STRING_LIST_INIT_DUP;
+
+       memset(data, 0, sizeof(*data));
+       data->wants = wants;
+       data->haves = haves;
+       data->shallows = shallows;
+       data->deepen_not = deepen_not;
+}
+
+static void upload_pack_data_clear(struct upload_pack_data *data)
+{
+       object_array_clear(&data->wants);
+       oid_array_clear(&data->haves);
+       object_array_clear(&data->shallows);
+       string_list_clear(&data->deepen_not, 0);
+}
+
+static int parse_want(const char *line)
+{
+       const char *arg;
+       if (skip_prefix(line, "want ", &arg)) {
+               struct object_id oid;
+               struct object *o;
+
+               if (get_oid_hex(arg, &oid))
+                       die("git upload-pack: protocol error, "
+                           "expected to get oid, not '%s'", line);
+
+               o = parse_object(&oid);
+               if (!o) {
+                       packet_write_fmt(1,
+                                        "ERR upload-pack: not our ref %s",
+                                        oid_to_hex(&oid));
+                       die("git upload-pack: not our ref %s",
+                           oid_to_hex(&oid));
+               }
+
+               if (!(o->flags & WANTED)) {
+                       o->flags |= WANTED;
+                       add_object_array(o, NULL, &want_obj);
+               }
+
+               return 1;
+       }
+
+       return 0;
+}
+
+static int parse_have(const char *line, struct oid_array *haves)
+{
+       const char *arg;
+       if (skip_prefix(line, "have ", &arg)) {
+               struct object_id oid;
+
+               if (get_oid_hex(arg, &oid))
+                       die("git upload-pack: expected SHA1 object, got '%s'", arg);
+               oid_array_append(haves, &oid);
+               return 1;
+       }
+
+       return 0;
+}
+
+static void process_args(struct packet_reader *request,
+                        struct upload_pack_data *data)
+{
+       while (packet_reader_read(request) != PACKET_READ_FLUSH) {
+               const char *arg = request->line;
+               const char *p;
+
+               /* process want */
+               if (parse_want(arg))
+                       continue;
+               /* process have line */
+               if (parse_have(arg, &data->haves))
+                       continue;
+
+               /* process args like thin-pack */
+               if (!strcmp(arg, "thin-pack")) {
+                       use_thin_pack = 1;
+                       continue;
+               }
+               if (!strcmp(arg, "ofs-delta")) {
+                       use_ofs_delta = 1;
+                       continue;
+               }
+               if (!strcmp(arg, "no-progress")) {
+                       no_progress = 1;
+                       continue;
+               }
+               if (!strcmp(arg, "include-tag")) {
+                       use_include_tag = 1;
+                       continue;
+               }
+               if (!strcmp(arg, "done")) {
+                       data->done = 1;
+                       continue;
+               }
+
+               /* Shallow related arguments */
+               if (process_shallow(arg, &data->shallows))
+                       continue;
+               if (process_deepen(arg, &data->depth))
+                       continue;
+               if (process_deepen_since(arg, &data->deepen_since,
+                                        &data->deepen_rev_list))
+                       continue;
+               if (process_deepen_not(arg, &data->deepen_not,
+                                      &data->deepen_rev_list))
+                       continue;
+               if (!strcmp(arg, "deepen-relative")) {
+                       data->deepen_relative = 1;
+                       continue;
+               }
+
+               if (allow_filter && skip_prefix(arg, "filter ", &p)) {
+                       parse_list_objects_filter(&filter_options, p);
+                       continue;
+               }
+
+               /* ignore unknown lines maybe? */
+               die("unexpected line: '%s'", arg);
+       }
+}
+
+static int process_haves(struct oid_array *haves, struct oid_array *common)
+{
+       int i;
+
+       /* Process haves */
+       for (i = 0; i < haves->nr; i++) {
+               const struct object_id *oid = &haves->oid[i];
+               struct object *o;
+               int we_knew_they_have = 0;
+
+               if (!has_object_file(oid))
+                       continue;
+
+               oid_array_append(common, oid);
+
+               o = parse_object(oid);
+               if (!o)
+                       die("oops (%s)", oid_to_hex(oid));
+               if (o->type == OBJ_COMMIT) {
+                       struct commit_list *parents;
+                       struct commit *commit = (struct commit *)o;
+                       if (o->flags & THEY_HAVE)
+                               we_knew_they_have = 1;
+                       else
+                               o->flags |= THEY_HAVE;
+                       if (!oldest_have || (commit->date < oldest_have))
+                               oldest_have = commit->date;
+                       for (parents = commit->parents;
+                            parents;
+                            parents = parents->next)
+                               parents->item->object.flags |= THEY_HAVE;
+               }
+               if (!we_knew_they_have)
+                       add_object_array(o, NULL, &have_obj);
+       }
+
+       return 0;
+}
+
+static int send_acks(struct oid_array *acks, struct strbuf *response)
+{
+       int i;
+
+       packet_buf_write(response, "acknowledgments\n");
+
+       /* Send Acks */
+       if (!acks->nr)
+               packet_buf_write(response, "NAK\n");
+
+       for (i = 0; i < acks->nr; i++) {
+               packet_buf_write(response, "ACK %s\n",
+                                oid_to_hex(&acks->oid[i]));
+       }
+
+       if (ok_to_give_up()) {
+               /* Send Ready */
+               packet_buf_write(response, "ready\n");
+               return 1;
+       }
+
+       return 0;
+}
+
+static int process_haves_and_send_acks(struct upload_pack_data *data)
+{
+       struct oid_array common = OID_ARRAY_INIT;
+       struct strbuf response = STRBUF_INIT;
+       int ret = 0;
+
+       process_haves(&data->haves, &common);
+       if (data->done) {
+               ret = 1;
+       } else if (send_acks(&common, &response)) {
+               packet_buf_delim(&response);
+               ret = 1;
+       } else {
+               /* Add Flush */
+               packet_buf_flush(&response);
+               ret = 0;
+       }
+
+       /* Send response */
+       write_or_die(1, response.buf, response.len);
+       strbuf_release(&response);
+
+       oid_array_clear(&data->haves);
+       oid_array_clear(&common);
+       return ret;
+}
+
+static void send_shallow_info(struct upload_pack_data *data)
+{
+       /* No shallow info needs to be sent */
+       if (!data->depth && !data->deepen_rev_list && !data->shallows.nr &&
+           !is_repository_shallow())
+               return;
+
+       packet_write_fmt(1, "shallow-info\n");
+
+       if (!send_shallow_list(data->depth, data->deepen_rev_list,
+                              data->deepen_since, &data->deepen_not,
+                              &data->shallows) && is_repository_shallow())
+               deepen(INFINITE_DEPTH, data->deepen_relative, &data->shallows);
+
+       packet_delim(1);
+}
+
+enum fetch_state {
+       FETCH_PROCESS_ARGS = 0,
+       FETCH_SEND_ACKS,
+       FETCH_SEND_PACK,
+       FETCH_DONE,
+};
+
+int upload_pack_v2(struct repository *r, struct argv_array *keys,
+                  struct packet_reader *request)
+{
+       enum fetch_state state = FETCH_PROCESS_ARGS;
+       struct upload_pack_data data;
 
        git_config(upload_pack_config, NULL);
 
-       switch (determine_protocol_version_server()) {
-       case protocol_v1:
-               /*
-                * v1 is just the original protocol with a version string,
-                * so just fall through after writing the version string.
-                */
-               if (advertise_refs || !stateless_rpc)
-                       packet_write_fmt(1, "version 1\n");
-
-               /* fallthrough */
-       case protocol_v0:
-               upload_pack();
-               break;
-       case protocol_unknown_version:
-               BUG("unknown protocol version");
+       upload_pack_data_init(&data);
+       use_sideband = LARGE_PACKET_MAX;
+
+       while (state != FETCH_DONE) {
+               switch (state) {
+               case FETCH_PROCESS_ARGS:
+                       process_args(request, &data);
+
+                       if (!want_obj.nr) {
+                               /*
+                                * Request didn't contain any 'want' lines,
+                                * guess they didn't want anything.
+                                */
+                               state = FETCH_DONE;
+                       } else if (data.haves.nr) {
+                               /*
+                                * Request had 'have' lines, so lets ACK them.
+                                */
+                               state = FETCH_SEND_ACKS;
+                       } else {
+                               /*
+                                * Request had 'want's but no 'have's so we can
+                                * immedietly go to construct and send a pack.
+                                */
+                               state = FETCH_SEND_PACK;
+                       }
+                       break;
+               case FETCH_SEND_ACKS:
+                       if (process_haves_and_send_acks(&data))
+                               state = FETCH_SEND_PACK;
+                       else
+                               state = FETCH_DONE;
+                       break;
+               case FETCH_SEND_PACK:
+                       send_shallow_info(&data);
+
+                       packet_write_fmt(1, "packfile\n");
+                       create_pack_file();
+                       state = FETCH_DONE;
+                       break;
+               case FETCH_DONE:
+                       continue;
+               }
        }
 
+       upload_pack_data_clear(&data);
        return 0;
 }
+
+int upload_pack_advertise(struct repository *r,
+                         struct strbuf *value)
+{
+       if (value) {
+               int allow_filter_value;
+               strbuf_addstr(value, "shallow");
+               if (!repo_config_get_bool(the_repository,
+                                        "uploadpack.allowfilter",
+                                        &allow_filter_value) &&
+                   allow_filter_value)
+                       strbuf_addstr(value, " filter");
+       }
+       return 1;
+}
diff --git a/upload-pack.h b/upload-pack.h
new file mode 100644 (file)
index 0000000..cab2178
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef UPLOAD_PACK_H
+#define UPLOAD_PACK_H
+
+struct upload_pack_options {
+       int stateless_rpc;
+       int advertise_refs;
+       unsigned int timeout;
+       int daemon_mode;
+};
+
+void upload_pack(struct upload_pack_options *options);
+
+struct repository;
+struct argv_array;
+struct packet_reader;
+extern int upload_pack_v2(struct repository *r, struct argv_array *keys,
+                         struct packet_reader *request);
+
+struct strbuf;
+extern int upload_pack_advertise(struct repository *r,
+                                struct strbuf *value);
+
+#endif /* UPLOAD_PACK_H */
diff --git a/usage.c b/usage.c
index cdd534c9dfc4bd38ce112da62643ab2dc7b4fbe9..cc803336bd5e6761b7fd50c33dba5aa9f734c4ba 100644 (file)
--- a/usage.c
+++ b/usage.c
@@ -148,6 +148,7 @@ static const char *fmt_with_err(char *buf, int n, const char *fmt)
                }
        }
        str_error[j] = 0;
+       /* Truncation is acceptable here */
        snprintf(buf, n, "%s: %s", fmt, str_error);
        return buf;
 }
@@ -210,6 +211,9 @@ void warning(const char *warn, ...)
        va_end(params);
 }
 
+/* Only set this, ever, from t/helper/, when verifying that bugs are caught. */
+int BUG_exit_code;
+
 static NORETURN void BUG_vfl(const char *file, int line, const char *fmt, va_list params)
 {
        char prefix[256];
@@ -221,6 +225,8 @@ static NORETURN void BUG_vfl(const char *file, int line, const char *fmt, va_lis
                snprintf(prefix, sizeof(prefix), "BUG: ");
 
        vreportf(prefix, fmt, params);
+       if (BUG_exit_code)
+               exit(BUG_exit_code);
        abort();
 }
 
diff --git a/utf8.c b/utf8.c
index f04c24409b4e95d69ccd08473ef4c43d408d6d86..d55e20c6415cb53ef66e1edd0a5e7dc470e18052 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -81,7 +81,7 @@ static int git_wcwidth(ucs_char_t ch)
        /*
         * Sorted list of non-overlapping intervals of non-spacing characters,
         */
-#include "unicode_width.h"
+#include "unicode-width.h"
 
        /* test for 8-bit control characters */
        if (ch == 0)
@@ -401,18 +401,40 @@ out:
        strbuf_release(&sb_dst);
 }
 
+/*
+ * Returns true (1) if the src encoding name matches the dst encoding
+ * name directly or one of its alternative names. E.g. UTF-16BE is the
+ * same as UTF16BE.
+ */
+static int same_utf_encoding(const char *src, const char *dst)
+{
+       if (istarts_with(src, "utf") && istarts_with(dst, "utf")) {
+               /* src[3] or dst[3] might be '\0' */
+               int i = (src[3] == '-' ? 4 : 3);
+               int j = (dst[3] == '-' ? 4 : 3);
+               return !strcasecmp(src+i, dst+j);
+       }
+       return 0;
+}
+
 int is_encoding_utf8(const char *name)
 {
        if (!name)
                return 1;
-       if (!strcasecmp(name, "utf-8") || !strcasecmp(name, "utf8"))
+       if (same_utf_encoding("utf-8", name))
                return 1;
        return 0;
 }
 
 int same_encoding(const char *src, const char *dst)
 {
-       if (is_encoding_utf8(src) && is_encoding_utf8(dst))
+       static const char utf8[] = "UTF-8";
+
+       if (!src)
+               src = utf8;
+       if (!dst)
+               dst = utf8;
+       if (same_utf_encoding(src, dst))
                return 1;
        return !strcasecmp(src, dst);
 }
@@ -538,6 +560,45 @@ char *reencode_string_len(const char *in, int insz,
 }
 #endif
 
+static int has_bom_prefix(const char *data, size_t len,
+                         const char *bom, size_t bom_len)
+{
+       return data && bom && (len >= bom_len) && !memcmp(data, bom, bom_len);
+}
+
+static const char utf16_be_bom[] = {0xFE, 0xFF};
+static const char utf16_le_bom[] = {0xFF, 0xFE};
+static const char utf32_be_bom[] = {0x00, 0x00, 0xFE, 0xFF};
+static const char utf32_le_bom[] = {0xFF, 0xFE, 0x00, 0x00};
+
+int has_prohibited_utf_bom(const char *enc, const char *data, size_t len)
+{
+       return (
+         (same_utf_encoding("UTF-16BE", enc) ||
+          same_utf_encoding("UTF-16LE", enc)) &&
+         (has_bom_prefix(data, len, utf16_be_bom, sizeof(utf16_be_bom)) ||
+          has_bom_prefix(data, len, utf16_le_bom, sizeof(utf16_le_bom)))
+       ) || (
+         (same_utf_encoding("UTF-32BE",  enc) ||
+          same_utf_encoding("UTF-32LE", enc)) &&
+         (has_bom_prefix(data, len, utf32_be_bom, sizeof(utf32_be_bom)) ||
+          has_bom_prefix(data, len, utf32_le_bom, sizeof(utf32_le_bom)))
+       );
+}
+
+int is_missing_required_utf_bom(const char *enc, const char *data, size_t len)
+{
+       return (
+          (same_utf_encoding(enc, "UTF-16")) &&
+          !(has_bom_prefix(data, len, utf16_be_bom, sizeof(utf16_be_bom)) ||
+            has_bom_prefix(data, len, utf16_le_bom, sizeof(utf16_le_bom)))
+       ) || (
+          (same_utf_encoding(enc, "UTF-32")) &&
+          !(has_bom_prefix(data, len, utf32_be_bom, sizeof(utf32_be_bom)) ||
+            has_bom_prefix(data, len, utf32_le_bom, sizeof(utf32_le_bom)))
+       );
+}
+
 /*
  * Returns first character length in bytes for multi-byte `text` according to
  * `encoding`.
diff --git a/utf8.h b/utf8.h
index da19b431143ec125428c74fbaafac167548372c2..db73a2d8d374e7570471627693ecddc87d998f10 100644 (file)
--- a/utf8.h
+++ b/utf8.h
@@ -75,4 +75,32 @@ typedef enum {
 void strbuf_utf8_align(struct strbuf *buf, align_type position, unsigned int width,
                       const char *s);
 
+/*
+ * If a data stream is declared as UTF-16BE or UTF-16LE, then a UTF-16
+ * BOM must not be used [1]. The same applies for the UTF-32 equivalents.
+ * The function returns true if this rule is violated.
+ *
+ * [1] http://unicode.org/faq/utf_bom.html#bom10
+ */
+int has_prohibited_utf_bom(const char *enc, const char *data, size_t len);
+
+/*
+ * If the endianness is not defined in the encoding name, then we
+ * require a BOM. The function returns true if a required BOM is missing.
+ *
+ * The Unicode standard instructs to assume big-endian if there in no
+ * BOM for UTF-16/32 [1][2]. However, the W3C/WHATWG encoding standard
+ * used in HTML5 recommends to assume little-endian to "deal with
+ * deployed content" [3].
+ *
+ * Therefore, strictly requiring a BOM seems to be the safest option for
+ * content in Git.
+ *
+ * [1] http://unicode.org/faq/utf_bom.html#gen6
+ * [2] http://www.unicode.org/versions/Unicode10.0.0/ch03.pdf
+ *     Section 3.10, D98, page 132
+ * [3] https://encoding.spec.whatwg.org/#utf-16le
+ */
+int is_missing_required_utf_bom(const char *enc, const char *data, size_t len);
+
 #endif
index 3fd047a8b82b1c2a6b32ec0a5ded3d67913b5be0..b5b8913cb0f2ceae60c18123d979e2948c568151 100644 (file)
@@ -320,7 +320,8 @@ const char *fast_export_read_path(const char *path, uint32_t *mode_out)
        err = fast_export_ls(path, mode_out, &buf);
        if (err) {
                if (errno != ENOENT)
-                       die_errno("BUG: unexpected fast_export_ls error");
+                       BUG("unexpected fast_export_ls error: %s",
+                           strerror(errno));
                /* Treat missing paths as directories. */
                *mode_out = S_IFDIR;
                return NULL;
@@ -338,7 +339,8 @@ void fast_export_copy(uint32_t revision, const char *src, const char *dst)
        err = fast_export_ls_rev(revision, src, &mode, &data);
        if (err) {
                if (errno != ENOENT)
-                       die_errno("BUG: unexpected fast_export_ls_rev error");
+                       BUG("unexpected fast_export_ls_rev error: %s",
+                           strerror(errno));
                fast_export_delete(dst);
                return;
        }
index dffb9c8e37c220e71e108060dc5a81bc21f8370c..0b162a09b95a3eadeef47f3e6d314d386215cc9f 100644 (file)
--- a/walker.c
+++ b/walker.c
@@ -72,6 +72,8 @@ static struct commit_list *complete = NULL;
 
 static int process_commit(struct walker *walker, struct commit *commit)
 {
+       struct commit_list *parents;
+
        if (parse_commit(commit))
                return -1;
 
@@ -86,19 +88,14 @@ static int process_commit(struct walker *walker, struct commit *commit)
 
        walker_say(walker, "walk %s\n", oid_to_hex(&commit->object.oid));
 
-       if (walker->get_tree) {
-               if (process(walker, &commit->tree->object))
+       if (process(walker, &get_commit_tree(commit)->object))
+               return -1;
+
+       for (parents = commit->parents; parents; parents = parents->next) {
+               if (process(walker, &parents->item->object))
                        return -1;
-               if (!walker->get_all)
-                       walker->get_tree = 0;
-       }
-       if (walker->get_history) {
-               struct commit_list *parents = commit->parents;
-               for (; parents; parents = parents->next) {
-                       if (process(walker, &parents->item->object))
-                               return -1;
-               }
        }
+
        return 0;
 }
 
index a869013e85110a0b64d8fe344c8bd67f5e8f7f09..6d8ae00e5b995f6565fab8b617e4629788c3c0c7 100644 (file)
--- a/walker.h
+++ b/walker.h
@@ -9,9 +9,6 @@ struct walker {
        void (*prefetch)(struct walker *, unsigned char *sha1);
        int (*fetch)(struct walker *, unsigned char *sha1);
        void (*cleanup)(struct walker *);
-       int get_tree;
-       int get_history;
-       int get_all;
        int get_verbosely;
        int get_recover;
 
index 28989cf06ef4bd15b3b97f86ae9fd32c4b78401f..97cda5f97bbc10b2f5690b945ab42d2beef74e2e 100644 (file)
@@ -338,7 +338,7 @@ void update_worktree_location(struct worktree *wt, const char *path_)
        struct strbuf path = STRBUF_INIT;
 
        if (is_main_worktree(wt))
-               die("BUG: can't relocate main worktree");
+               BUG("can't relocate main worktree");
 
        strbuf_realpath(&path, path_, 1);
        if (fspathcmp(wt->path, path.buf)) {
index 5842408817aa7e5c584f244a7625cf458882d568..95851b85b6b7181130f0cd441c2bd7ac0bfb89da 100644 (file)
@@ -20,10 +20,17 @@ PATH='@@BUILD_DIR@@/bin-wrappers:'"$PATH"
 
 export GIT_EXEC_PATH GITPERLLIB PATH GIT_TEXTDOMAINDIR
 
-if test -n "$GIT_TEST_GDB"
-then
-       unset GIT_TEST_GDB
-       exec gdb --args "${GIT_EXEC_PATH}/@@PROG@@" "$@"
-else
+case "$GIT_DEBUGGER" in
+'')
        exec "${GIT_EXEC_PATH}/@@PROG@@" "$@"
-fi
+       ;;
+1)
+       unset GIT_DEBUGGER
+       exec gdb --args "${GIT_EXEC_PATH}/@@PROG@@" "$@"
+       ;;
+*)
+       GIT_DEBUGGER_ARGS="$GIT_DEBUGGER"
+       unset GIT_DEBUGGER
+       exec ${GIT_DEBUGGER_ARGS} "${GIT_EXEC_PATH}/@@PROG@@" "$@"
+       ;;
+esac
index 1fd5e33ea8f5c8cb4e6720b0bec74acf09232e3c..e4fa9d84cd076770306114ff4f284155a5cdd2a1 100644 (file)
--- a/wrapper.c
+++ b/wrapper.c
@@ -643,9 +643,9 @@ int xsnprintf(char *dst, size_t max, const char *fmt, ...)
        va_end(ap);
 
        if (len < 0)
-               die("BUG: your snprintf is broken");
+               BUG("your snprintf is broken");
        if (len >= max)
-               die("BUG: attempt to snprintf into too-small buffer");
+               BUG("attempt to snprintf into too-small buffer");
        return len;
 }
 
similarity index 100%
rename from write_or_die.c
rename to write-or-die.c
index 66f4234af1149618b47786f3b623916be7c02c74..d1c05145a4bded06a7fccc60543193d2f5181953 100644 (file)
@@ -138,6 +138,9 @@ void wt_status_prepare(struct wt_status *s)
        s->show_stash = 0;
        s->ahead_behind_flags = AHEAD_BEHIND_UNSPECIFIED;
        s->display_comment_prefix = 0;
+       s->detect_rename = -1;
+       s->rename_score = -1;
+       s->rename_limit = -1;
 }
 
 static void wt_longstatus_print_unmerged_header(struct wt_status *s)
@@ -264,7 +267,7 @@ static const char *wt_status_unmerged_status_string(int stagemask)
        case 7:
                return _("both modified:");
        default:
-               die("BUG: unhandled unmerged status %x", stagemask);
+               BUG("unhandled unmerged status %x", stagemask);
        }
 }
 
@@ -377,7 +380,7 @@ static void wt_longstatus_print_change_data(struct wt_status *s,
                status = d->worktree_status;
                break;
        default:
-               die("BUG: unhandled change_type %d in wt_longstatus_print_change_data",
+               BUG("unhandled change_type %d in wt_longstatus_print_change_data",
                    change_type);
        }
 
@@ -395,7 +398,7 @@ static void wt_longstatus_print_change_data(struct wt_status *s,
        status_printf(s, color(WT_STATUS_HEADER, s), "\t");
        what = wt_status_diff_status_string(status);
        if (!what)
-               die("BUG: unhandled diff status %c", status);
+               BUG("unhandled diff status %c", status);
        len = label_width - utf8_strwidth(what);
        assert(len >= 0);
        if (one_name != two_name)
@@ -470,7 +473,7 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q,
                case DIFF_STATUS_COPIED:
                case DIFF_STATUS_RENAMED:
                        if (d->rename_status)
-                               die("BUG: multiple renames on the same target? how?");
+                               BUG("multiple renames on the same target? how?");
                        d->rename_source = xstrdup(p->one->path);
                        d->rename_score = p->score * 100 / MAX_SCORE;
                        d->rename_status = p->status;
@@ -484,7 +487,7 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q,
                        break;
 
                default:
-                       die("BUG: unhandled diff-files status '%c'", p->status);
+                       BUG("unhandled diff-files status '%c'", p->status);
                        break;
                }
 
@@ -547,7 +550,7 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q,
                case DIFF_STATUS_COPIED:
                case DIFF_STATUS_RENAMED:
                        if (d->rename_status)
-                               die("BUG: multiple renames on the same target? how?");
+                               BUG("multiple renames on the same target? how?");
                        d->rename_source = xstrdup(p->one->path);
                        d->rename_score = p->score * 100 / MAX_SCORE;
                        d->rename_status = p->status;
@@ -569,7 +572,7 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q,
                        break;
 
                default:
-                       die("BUG: unhandled diff-index status '%c'", p->status);
+                       BUG("unhandled diff-index status '%c'", p->status);
                        break;
                }
        }
@@ -592,6 +595,9 @@ static void wt_status_collect_changes_worktree(struct wt_status *s)
        }
        rev.diffopt.format_callback = wt_status_collect_changed_cb;
        rev.diffopt.format_callback_data = s;
+       rev.diffopt.detect_rename = s->detect_rename >= 0 ? s->detect_rename : rev.diffopt.detect_rename;
+       rev.diffopt.rename_limit = s->rename_limit >= 0 ? s->rename_limit : rev.diffopt.rename_limit;
+       rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
        copy_pathspec(&rev.prune_data, &s->pathspec);
        run_diff_files(&rev, 0);
 }
@@ -603,7 +609,7 @@ static void wt_status_collect_changes_index(struct wt_status *s)
 
        init_revisions(&rev, NULL);
        memset(&opt, 0, sizeof(opt));
-       opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;
+       opt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;
        setup_revisions(0, NULL, &rev, &opt);
 
        rev.diffopt.flags.override_submodule_config = 1;
@@ -625,9 +631,9 @@ static void wt_status_collect_changes_index(struct wt_status *s)
        rev.diffopt.output_format |= DIFF_FORMAT_CALLBACK;
        rev.diffopt.format_callback = wt_status_collect_updated_cb;
        rev.diffopt.format_callback_data = s;
-       rev.diffopt.detect_rename = DIFF_DETECT_RENAME;
-       rev.diffopt.rename_limit = 200;
-       rev.diffopt.break_opt = 0;
+       rev.diffopt.detect_rename = s->detect_rename >= 0 ? s->detect_rename : rev.diffopt.detect_rename;
+       rev.diffopt.rename_limit = s->rename_limit >= 0 ? s->rename_limit : rev.diffopt.rename_limit;
+       rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
        copy_pathspec(&rev.prune_data, &s->pathspec);
        run_diff_index(&rev, 1);
 }
@@ -981,11 +987,13 @@ static void wt_longstatus_print_verbose(struct wt_status *s)
        rev.diffopt.ita_invisible_in_index = 1;
 
        memset(&opt, 0, sizeof(opt));
-       opt.def = s->is_initial ? EMPTY_TREE_SHA1_HEX : s->reference;
+       opt.def = s->is_initial ? empty_tree_oid_hex() : s->reference;
        setup_revisions(0, NULL, &rev, &opt);
 
        rev.diffopt.output_format |= DIFF_FORMAT_PATCH;
-       rev.diffopt.detect_rename = DIFF_DETECT_RENAME;
+       rev.diffopt.detect_rename = s->detect_rename >= 0 ? s->detect_rename : rev.diffopt.detect_rename;
+       rev.diffopt.rename_limit = s->rename_limit >= 0 ? s->rename_limit : rev.diffopt.rename_limit;
+       rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score;
        rev.diffopt.file = s->fp;
        rev.diffopt.close_file = 0;
        /*
@@ -1188,7 +1196,7 @@ static void abbrev_sha1_in_line(struct strbuf *line)
                strbuf_trim(split[1]);
                if (!get_oid(split[1]->buf, &oid)) {
                        strbuf_reset(split[1]);
-                       strbuf_add_unique_abbrev(split[1], oid.hash,
+                       strbuf_add_unique_abbrev(split[1], &oid,
                                                 DEFAULT_ABBREV);
                        strbuf_addch(split[1], ' ');
                        strbuf_reset(line);
@@ -1350,7 +1358,7 @@ static void show_cherry_pick_in_progress(struct wt_status *s,
                                        const char *color)
 {
        status_printf_ln(s, color, _("You are currently cherry-picking commit %s."),
-                       find_unique_abbrev(state->cherry_pick_head_sha1, DEFAULT_ABBREV));
+                       find_unique_abbrev(&state->cherry_pick_head_oid, DEFAULT_ABBREV));
        if (s->hints) {
                if (has_unmerged(s))
                        status_printf_ln(s, color,
@@ -1369,7 +1377,7 @@ static void show_revert_in_progress(struct wt_status *s,
                                        const char *color)
 {
        status_printf_ln(s, color, _("You are currently reverting commit %s."),
-                        find_unique_abbrev(state->revert_head_sha1, DEFAULT_ABBREV));
+                        find_unique_abbrev(&state->revert_head_oid, DEFAULT_ABBREV));
        if (s->hints) {
                if (has_unmerged(s))
                        status_printf_ln(s, color,
@@ -1422,7 +1430,7 @@ static char *get_branch(const struct worktree *wt, const char *path)
                ;
        else if (!get_oid_hex(sb.buf, &oid)) {
                strbuf_reset(&sb);
-               strbuf_add_unique_abbrev(&sb, oid.hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&sb, &oid, DEFAULT_ABBREV);
        } else if (!strcmp(sb.buf, "detached HEAD")) /* rebase */
                goto got_nothing;
        else                    /* bisect */
@@ -1459,7 +1467,7 @@ static int grab_1st_switch(struct object_id *ooid, struct object_id *noid,
        if (!strcmp(cb->buf.buf, "HEAD")) {
                /* HEAD is relative. Resolve it to the right reflog entry. */
                strbuf_reset(&cb->buf);
-               strbuf_add_unique_abbrev(&cb->buf, noid->hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(&cb->buf, noid, DEFAULT_ABBREV);
        }
        return 1;
 }
@@ -1489,10 +1497,10 @@ static void wt_status_get_detached_from(struct wt_status_state *state)
                state->detached_from = xstrdup(from);
        } else
                state->detached_from =
-                       xstrdup(find_unique_abbrev(cb.noid.hash, DEFAULT_ABBREV));
-       hashcpy(state->detached_sha1, cb.noid.hash);
+                       xstrdup(find_unique_abbrev(&cb.noid, DEFAULT_ABBREV));
+       oidcpy(&state->detached_oid, &cb.noid);
        state->detached_at = !get_oid("HEAD", &oid) &&
-                            !hashcmp(oid.hash, state->detached_sha1);
+                            !oidcmp(&oid, &state->detached_oid);
 
        free(ref);
        strbuf_release(&cb.buf);
@@ -1551,13 +1559,13 @@ void wt_status_get_state(struct wt_status_state *state,
        } else if (!stat(git_path_cherry_pick_head(), &st) &&
                        !get_oid("CHERRY_PICK_HEAD", &oid)) {
                state->cherry_pick_in_progress = 1;
-               hashcpy(state->cherry_pick_head_sha1, oid.hash);
+               oidcpy(&state->cherry_pick_head_oid, &oid);
        }
        wt_status_check_bisect(NULL, state);
        if (!stat(git_path_revert_head(), &st) &&
            !get_oid("REVERT_HEAD", &oid)) {
                state->revert_in_progress = 1;
-               hashcpy(state->revert_head_sha1, oid.hash);
+               oidcpy(&state->revert_head_oid, &oid);
        }
 
        if (get_detached_from)
@@ -2158,7 +2166,7 @@ static void wt_porcelain_v2_print_unmerged_entry(
        case 6: key = "AA"; break; /* both added */
        case 7: key = "UU"; break; /* both modified */
        default:
-               die("BUG: unhandled unmerged status %x", d->stagemask);
+               BUG("unhandled unmerged status %x", d->stagemask);
        }
 
        /*
@@ -2185,7 +2193,7 @@ static void wt_porcelain_v2_print_unmerged_entry(
                sum |= (1 << (stage - 1));
        }
        if (sum != d->stagemask)
-               die("BUG: observed stagemask 0x%x != expected stagemask 0x%x", sum, d->stagemask);
+               BUG("observed stagemask 0x%x != expected stagemask 0x%x", sum, d->stagemask);
 
        if (s->null_termination)
                path_index = it->string;
@@ -2289,7 +2297,7 @@ void wt_status_print(struct wt_status *s)
                wt_porcelain_v2_print(s);
                break;
        case STATUS_FORMAT_UNSPECIFIED:
-               die("BUG: finalize_deferred_config() should have been called");
+               BUG("finalize_deferred_config() should have been called");
                break;
        case STATUS_FORMAT_NONE:
        case STATUS_FORMAT_LONG:
index ea2456daf24a4a74b3d85b041527ce5f99dc2695..1673d146fa2f1e15eabccd1c6b12d0e74b5f0870 100644 (file)
@@ -89,7 +89,9 @@ struct wt_status {
        int show_stash;
        int hints;
        enum ahead_behind_flags ahead_behind_flags;
-
+       int detect_rename;
+       int rename_score;
+       int rename_limit;
        enum wt_status_format status_format;
        unsigned char sha1_commit[GIT_MAX_RAWSZ]; /* when not Initial */
 
@@ -118,9 +120,9 @@ struct wt_status_state {
        char *branch;
        char *onto;
        char *detached_from;
-       unsigned char detached_sha1[20];
-       unsigned char revert_head_sha1[20];
-       unsigned char cherry_pick_head_sha1[20];
+       struct object_id detached_oid;
+       struct object_id revert_head_oid;
+       struct object_id cherry_pick_head_oid;
 };
 
 size_t wt_status_locate_end(const char *s, size_t len);
index 770e1f7f8185e05f2618c261b70a5773041432fb..9315bc0ede11ba0377e27d711e37b6a0ae555c43 100644 (file)
@@ -191,7 +191,7 @@ void read_mmblob(mmfile_t *ptr, const struct object_id *oid)
                return;
        }
 
-       ptr->ptr = read_sha1_file(oid->hash, &type, &size);
+       ptr->ptr = read_object_file(oid, &type, &size);
        if (!ptr->ptr || type != OBJ_BLOB)
                die("unable to read blob object %s", oid_to_hex(oid));
        ptr->size = size;
diff --git a/zlib.c b/zlib.c
index 4223f1a8c57a281d5e41c329a4f983a7bb3b57a0..d594cba3fc9d82d94b9277e886f2bee265e552f6 100644 (file)
--- a/zlib.c
+++ b/zlib.c
@@ -52,9 +52,9 @@ static void zlib_post_call(git_zstream *s)
        bytes_consumed = s->z.next_in - s->next_in;
        bytes_produced = s->z.next_out - s->next_out;
        if (s->z.total_out != s->total_out + bytes_produced)
-               die("BUG: total_out mismatch");
+               BUG("total_out mismatch");
        if (s->z.total_in != s->total_in + bytes_consumed)
-               die("BUG: total_in mismatch");
+               BUG("total_in mismatch");
 
        s->total_out = s->z.total_out;
        s->total_in = s->z.total_in;