summaryrefslogtreecommitdiff
path: root/Documentation
diff options
context:
space:
mode:
Diffstat (limited to 'Documentation')
-rw-r--r--Documentation/CodingGuidelines7
-rw-r--r--Documentation/Makefile1
-rw-r--r--Documentation/RelNotes/2.27.0.txt24
-rw-r--r--Documentation/RelNotes/2.28.0.txt118
-rw-r--r--Documentation/SubmittingPatches5
-rw-r--r--Documentation/config/diff.txt4
-rw-r--r--Documentation/config/feature.txt4
-rw-r--r--Documentation/config/protocol.txt3
-rw-r--r--Documentation/date-formats.txt3
-rw-r--r--Documentation/diff-options.txt5
-rw-r--r--Documentation/git-bugreport.txt3
-rw-r--r--Documentation/git-commit-graph.txt9
-rw-r--r--Documentation/git-credential.txt16
-rw-r--r--Documentation/git-diff.txt20
-rw-r--r--Documentation/git-fast-import.txt9
-rw-r--r--Documentation/git-sparse-checkout.txt32
-rw-r--r--Documentation/git-worktree.txt4
-rw-r--r--Documentation/git.txt13
-rw-r--r--Documentation/gitfaq.txt2
-rw-r--r--Documentation/gitremote-helpers.txt4
-rw-r--r--Documentation/rev-list-options.txt35
-rw-r--r--Documentation/technical/http-protocol.txt2
-rw-r--r--Documentation/technical/pack-protocol.txt6
-rw-r--r--Documentation/technical/protocol-v2.txt2
-rw-r--r--Documentation/technical/reftable.txt1083
25 files changed, 1349 insertions, 65 deletions
diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines
index 227f46a..45465bc 100644
--- a/Documentation/CodingGuidelines
+++ b/Documentation/CodingGuidelines
@@ -489,16 +489,11 @@ For Python scripts:
- We follow PEP-8 (http://www.python.org/dev/peps/pep-0008/).
- - As a minimum, we aim to be compatible with Python 2.6 and 2.7.
+ - As a minimum, we aim to be compatible with Python 2.7.
- Where required libraries do not restrict us to Python 2, we try to
also be compatible with Python 3.1 and later.
- - When you must differentiate between Unicode literals and byte string
- literals, it is OK to use the 'b' prefix. Even though the Python
- documentation for version 2.6 does not mention this prefix, it has
- been supported since version 2.6.0.
-
Error Messages
- Do not end error messages with a full stop.
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 15d9d04..ecd0b34 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -93,6 +93,7 @@ TECH_DOCS += technical/protocol-capabilities
TECH_DOCS += technical/protocol-common
TECH_DOCS += technical/protocol-v2
TECH_DOCS += technical/racy-git
+TECH_DOCS += technical/reftable
TECH_DOCS += technical/send-pack-pipeline
TECH_DOCS += technical/shallow
TECH_DOCS += technical/signature-format
diff --git a/Documentation/RelNotes/2.27.0.txt b/Documentation/RelNotes/2.27.0.txt
index e3121d0..15518d0 100644
--- a/Documentation/RelNotes/2.27.0.txt
+++ b/Documentation/RelNotes/2.27.0.txt
@@ -24,6 +24,10 @@ Backward compatibility notes
users may find annoying---those who prefer not to rebase need to
set the variable to false to squelch the warning.
+ * The transport protocol version 2, which was promoted to the default
+ in Git 2.26 release, turned out to have some remaining rough edges,
+ so it has been demoted from the default.
+
UI, Workflows & Features
@@ -178,6 +182,11 @@ Performance, Internal Implementation, Development Support etc.
start_progress() and the stop_progress() calls as a "region" to be
traced.
+ * Instead of downloading Windows SDK for CI jobs for windows builds
+ from an external site (wingit.blob.core.windows.net), use the one
+ created in the windows-build job, to work around quota issues at
+ the external site.
+
Fixes since v2.26
-----------------
@@ -470,6 +479,21 @@ Fixes since v2.26
name. This has been corrected.
(merge 9068cfb20f rs/fsck-duplicate-names-in-trees later to maint).
+ * Code clean-up by removing a compatibility implementation of a
+ function we no longer use.
+ (merge 84b0115f0d cb/no-more-gmtime later to maint).
+
+ * When a binary file gets modified and renamed on both sides of history
+ to different locations, both files would be written to the working
+ tree but both would have the contents from "ours". This has been
+ corrected so that the path from each side gets their original content.
+
+ * Fix for a copy-and-paste error introduced during 2.20 era.
+ (merge e68a5272b1 ds/multi-pack-verify later to maint).
+
+ * Update an unconditional use of "grep -a" with a perl script in a test.
+ (merge 1eb7371236 dd/t5703-grep-a-fix later to maint).
+
* Other code cleanup, docfix, build fix, etc.
(merge 564956f358 jc/maintain-doc later to maint).
(merge 7422b2a0a1 sg/commit-slab-clarify-peek later to maint).
diff --git a/Documentation/RelNotes/2.28.0.txt b/Documentation/RelNotes/2.28.0.txt
new file mode 100644
index 0000000..55903d8
--- /dev/null
+++ b/Documentation/RelNotes/2.28.0.txt
@@ -0,0 +1,118 @@
+Git 2.28 Release Notes
+======================
+
+Updates since v2.27
+-------------------
+
+Backward compatibility notes
+
+ * "feature.experimental" configuration variable is to let volunteers
+ easily opt into a set of newer features, which use of the v2
+ transport protocol is now a part of.
+
+
+UI, Workflows & Features
+
+ * The commands in the "diff" family learned to honor "diff.relative"
+ configuration variable.
+
+ * The check in "git fsck" to ensure that the tree objects are sorted
+ still had corner cases it missed unsorted entries.
+
+ * The interface to redact sensitive information in the trace output
+ has been simplified.
+
+
+Performance, Internal Implementation, Development Support etc.
+
+ * Code optimization for a common case.
+ (merge 8777616e4d an/merge-single-strategy-optim later to maint).
+
+ * We've adopted a convention that any on-stack structure can be
+ initialized to have zero values in all fields with "= { 0 }",
+ even when the first field happens to be a pointer, but sparse
+ complained that a null pointer should be spelled NULL for a long
+ time. Start using -Wno-universal-initializer option to squelch
+ it (the latest sparse has it on by default).
+
+ * "git log -L..." now takes advantage of the "which paths are touched
+ by this commit?" info stored in the commit-graph system.
+
+ * As FreeBSD is not the only platform whose regexp library reports
+ a REG_ILLSEQ error when fed invalid UTF-8, add logic to detect that
+ automatically and skip the affected tests.
+
+ * "git bugreport" learns to report what shell is in use.
+
+ * Support for GIT_CURL_VERBOSE has been rewritten in terms of
+ GIT_TRACE_CURL.
+
+ * Preliminary clean-ups around refs API, plus file format
+ specification documentation for the reftable backend.
+
+ * Workaround breakage in MSVC build, where "curl-config --cflags"
+ gives settings appropriate for GCC build.
+
+
+Fixes since v2.27
+-----------------
+
+ * The "--prepare-p4-only" option of "git p4" is supposed to stop
+ after replaying one changeset, but kept going (by mistake?)
+
+ * The error message from "git checkout -b foo -t bar baz" was
+ confusing.
+
+ * Some repositories in the wild have commits that record nonsense
+ committer timezone (e.g. rails.git); "git fast-import" learned an
+ option to pass these nonsense timestamps intact to allow recreating
+ existing repositories as-is.
+ (merge d42a2fb72f en/fast-import-looser-date later to maint).
+
+ * The command line completion script (in contrib/) tried to complete
+ "git stash -p" as if it were "git stash push -p", but it was too
+ aggressive and also affected "git stash show -p", which has been
+ corrected.
+ (merge fffd0cf520 vs/complete-stash-show-p-fix later to maint).
+
+ * On-the-wire protocol v2 easily falls into a deadlock between the
+ remote-curl helper and the fetch-pack process when the server side
+ prematurely throws an error and disconnects. The communication has
+ been updated to make it more robust.
+
+ * "git checkout -p" did not handle a newly added path at all.
+ (merge 2c8bd8471a js/checkout-p-new-file later to maint).
+
+ * The code to parse "git bisect start" command line was lax in
+ validating the arguments.
+ (merge 4d9005ff5d cb/bisect-helper-parser-fix later to maint).
+
+ * Reduce memory usage during "diff --quiet" in a worktree with too
+ many stat-unmatched paths.
+ (merge d2d7fbe129 jk/diff-memuse-optim-with-stat-unmatch later to maint).
+
+ * The reflog entries for "git clone" and "git fetch" did not
+ anonymize the URL they operated on.
+ (merge 46da295a77 js/reflog-anonymize-for-clone-and-fetch later to maint).
+
+ * The behaviour of "sparse-checkout" in the state "git clone
+ --no-checkout" left was changed accidentally in 2.27, which has
+ been corrected.
+
+ * Use of negative pathspec, while collecting paths including
+ untracked ones in the working tree, was broken.
+
+ * The same worktree directory must be registered only once, but
+ "git worktree move" allowed this invariant to be violated, which
+ has been corrected.
+ (merge 810382ed37 es/worktree-duplicate-paths later to maint).
+
+ * The effect of sparse checkout settings on submodules is documented.
+ (merge e7d7c73249 en/sparse-with-submodule-doc later to maint).
+
+ * Other code cleanup, docfix, build fix, etc.
+ (merge 2c31a7aa44 jx/pkt-line-doc-count-fix later to maint).
+ (merge d63ae31962 cb/t5608-cleanup later to maint).
+ (merge 788db145c7 dl/t-readme-spell-git-correctly later to maint).
+ (merge 45a87a83bb dl/python-2.7-is-the-floor-version later to maint).
+ (merge b75a219904 es/advertise-contribution-doc later to maint).
diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches
index 4515cab..ecf9438 100644
--- a/Documentation/SubmittingPatches
+++ b/Documentation/SubmittingPatches
@@ -3,8 +3,9 @@ Submitting Patches
== Guidelines
-Here are some guidelines for people who want to contribute their code
-to this software.
+Here are some guidelines for people who want to contribute their code to this
+software. There is also a link:MyFirstContribution.html[step-by-step tutorial]
+available which covers many of these same guidelines.
[[base-branch]]
=== Decide what to base your work on.
diff --git a/Documentation/config/diff.txt b/Documentation/config/diff.txt
index ff09f1c..c3ae136 100644
--- a/Documentation/config/diff.txt
+++ b/Documentation/config/diff.txt
@@ -105,6 +105,10 @@ diff.mnemonicPrefix::
diff.noprefix::
If set, 'git diff' does not show any source or destination prefix.
+diff.relative::
+ If set to 'true', 'git diff' does not show changes outside of the directory
+ and show pathnames relative to the current directory.
+
diff.orderFile::
File indicating how to order files within a diff.
See the '-O' option to linkgit:git-diff[1] for details.
diff --git a/Documentation/config/feature.txt b/Documentation/config/feature.txt
index 4e3a5c0..28c3360 100644
--- a/Documentation/config/feature.txt
+++ b/Documentation/config/feature.txt
@@ -22,6 +22,10 @@ existing commit-graph file(s). Occasionally, these files will merge and the
write may take longer. Having an updated commit-graph file helps performance
of many Git commands, including `git merge-base`, `git push -f`, and
`git log --graph`.
++
+* `protocol.version=2` speeds up fetches from repositories with many refs by
+allowing the client to specify which refs to list before the server lists
+them.
feature.manyFiles::
Enable config options that optimize for repos with many files in the
diff --git a/Documentation/config/protocol.txt b/Documentation/config/protocol.txt
index 0b40141..c46e9b3 100644
--- a/Documentation/config/protocol.txt
+++ b/Documentation/config/protocol.txt
@@ -48,7 +48,8 @@ protocol.version::
If set, clients will attempt to communicate with a server
using the specified protocol version. If the server does
not support it, communication falls back to version 0.
- If unset, the default is `0`.
+ If unset, the default is `0`, unless `feature.experimental`
+ is enabled, in which case the default is `2`.
Supported versions:
+
--
diff --git a/Documentation/date-formats.txt b/Documentation/date-formats.txt
index 7e7eaba..f1097fa 100644
--- a/Documentation/date-formats.txt
+++ b/Documentation/date-formats.txt
@@ -22,8 +22,7 @@ ISO 8601::
`2005-04-07T22:13:13`. The parser accepts a space instead of the
`T` character as well. Fractional parts of a second will be ignored,
for example `2005-04-07T22:13:13.019` will be treated as
- `2005-04-07T22:13:13`
-
+ `2005-04-07T22:13:13`.
+
NOTE: In addition, the date part is accepted in the following formats:
`YYYY.MM.DD`, `MM/DD/YYYY` and `DD.MM.YYYY`.
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index bb31f0c..7987d72 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -643,15 +643,18 @@ ifndef::git-format-patch[]
-R::
Swap two inputs; that is, show differences from index or
on-disk file to tree contents.
+endif::git-format-patch[]
--relative[=<path>]::
+--no-relative::
When run from a subdirectory of the project, it can be
told to exclude changes outside the directory and show
pathnames relative to it with this option. When you are
not in a subdirectory (e.g. in a bare repository), you
can name which subdirectory to make the output relative
to by giving a <path> as an argument.
-endif::git-format-patch[]
+ `--no-relative` can be used to countermand both `diff.relative` config
+ option and previous `--relative`.
-a::
--text::
diff --git a/Documentation/git-bugreport.txt b/Documentation/git-bugreport.txt
index 7fe9aef..66e88c2 100644
--- a/Documentation/git-bugreport.txt
+++ b/Documentation/git-bugreport.txt
@@ -29,6 +29,7 @@ The following information is captured automatically:
- uname sysname, release, version, and machine strings
- Compiler-specific info string
- A list of enabled hooks
+ - $SHELL
This tool is invoked via the typical Git setup process, which means that in some
cases, it might not be able to launch - for example, if a relevant config file
@@ -46,7 +47,7 @@ OPTIONS
--suffix <format>::
Specify an alternate suffix for the bugreport name, to create a file
named 'git-bugreport-<formatted suffix>'. This should take the form of a
- link:strftime[3] format string; the current local time will be used.
+ strftime(3) format string; the current local time will be used.
GIT
---
diff --git a/Documentation/git-commit-graph.txt b/Documentation/git-commit-graph.txt
index 53a6502..8ca1764 100644
--- a/Documentation/git-commit-graph.txt
+++ b/Documentation/git-commit-graph.txt
@@ -47,8 +47,10 @@ with `--stdin-commits` or `--reachable`.)
+
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` or `--reachable`.)
+of OIDs in hex, one OID per line. OIDs that resolve to non-commits
+(either directly, or by peeling tags) are silently ignored. OIDs that
+are malformed, or do not exist generate an error. (Cannot be combined
+with `--stdin-packs` or `--reachable`.)
+
With the `--reachable` option, generate the new commit graph by walking
commits starting at all refs. (Cannot be combined with `--stdin-commits`
@@ -58,7 +60,7 @@ With the `--append` option, include all commits that are present in the
existing commit-graph file.
+
With the `--changed-paths` option, compute and write information about the
-paths changed between a commit and it's first parent. This operation can
+paths changed between a commit and its first parent. This operation can
take a while on large repositories. It provides significant performance gains
for getting history of a directory or a file with `git log -- <path>`.
+
@@ -68,6 +70,7 @@ chain of multiple commit-graph files stored in
strategy and other splitting options. The new commits not already in the
commit-graph are added in a new "tip" file. This file is merged with the
existing file if the following merge conditions are met:
++
* If `--split=no-merge` is specified, a merge is never performed, and
the remaining options are ignored. `--split=replace` overwrites the
existing chain with a new one. A bare `--split` defers to the remaining
diff --git a/Documentation/git-credential.txt b/Documentation/git-credential.txt
index 8d990e9..31c81c4 100644
--- a/Documentation/git-credential.txt
+++ b/Documentation/git-credential.txt
@@ -151,11 +151,11 @@ Git understands the following attributes:
were read (e.g., `url=https://example.com` would behave as if
`protocol=https` and `host=example.com` had been provided). This
can help callers avoid parsing URLs themselves.
-
- Note that specifying a protocol is mandatory and if the URL
- doesn't specify a hostname (e.g., "cert:///path/to/file") the
- credential will contain a hostname attribute whose value is an
- empty string.
-
- Components which are missing from the URL (e.g., there is no
- username in the example above) will be left unset.
++
+Note that specifying a protocol is mandatory and if the URL
+doesn't specify a hostname (e.g., "cert:///path/to/file") the
+credential will contain a hostname attribute whose value is an
+empty string.
++
+Components which are missing from the URL (e.g., there is no
+username in the example above) will be left unset.
diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index 37781cf..1018110 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -11,15 +11,17 @@ SYNOPSIS
[verse]
'git diff' [<options>] [<commit>] [--] [<path>...]
'git diff' [<options>] --cached [<commit>] [--] [<path>...]
-'git diff' [<options>] <commit> <commit> [--] [<path>...]
+'git diff' [<options>] <commit> [<commit>...] <commit> [--] [<path>...]
+'git diff' [<options>] <commit>...<commit> [--] [<path>...]
'git diff' [<options>] <blob> <blob>
'git diff' [<options>] --no-index [--] <path> <path>
DESCRIPTION
-----------
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.
+between the index and a tree, changes between two trees, changes resulting
+from a merge, changes between two blob objects, or changes between two
+files on disk.
'git diff' [<options>] [--] [<path>...]::
@@ -67,6 +69,15 @@ two blob objects, or changes between two files on disk.
one side is omitted, it will have the same effect as
using HEAD instead.
+'git diff' [<options>] <commit> [<commit>...] <commit> [--] [<path>...]::
+
+ This form is to view the results of a merge commit. The first
+ listed <commit> must be the merge itself; the remaining two or
+ more commits should be its parents. A convenient way to produce
+ the desired set of revisions is to use the {caret}@ suffix.
+ For instance, if `master` names a merge commit, `git diff master
+ master^@` gives the same combined diff as `git show master`.
+
'git diff' [<options>] <commit>\...<commit> [--] [<path>...]::
This form is to view the changes on the branch containing
@@ -196,7 +207,8 @@ linkgit:git-difftool[1],
linkgit:git-log[1],
linkgit:gitdiffcore[7],
linkgit:git-format-patch[1],
-linkgit:git-apply[1]
+linkgit:git-apply[1],
+linkgit:git-show[1]
GIT
---
diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt
index 77c6b3d..7d9aad2 100644
--- a/Documentation/git-fast-import.txt
+++ b/Documentation/git-fast-import.txt
@@ -293,7 +293,14 @@ by users who are located in the same location and time zone. In this
case a reasonable offset from UTC could be assumed.
+
Unlike the `rfc2822` format, this format is very strict. Any
-variation in formatting will cause fast-import to reject the value.
+variation in formatting will cause fast-import to reject the value,
+and some sanity checks on the numeric values may also be performed.
+
+`raw-permissive`::
+ This is the same as `raw` except that no sanity checks on
+ the numeric epoch and local offset are performed. This can
+ be useful when trying to filter or import an existing history
+ with e.g. bogus timezone values.
`rfc2822`::
This is the standard email format as described by RFC 2822.
diff --git a/Documentation/git-sparse-checkout.txt b/Documentation/git-sparse-checkout.txt
index 1a3ace6..a0eeaeb 100644
--- a/Documentation/git-sparse-checkout.txt
+++ b/Documentation/git-sparse-checkout.txt
@@ -70,7 +70,7 @@ C-style quoted strings.
`core.sparseCheckoutCone` is enabled, the given patterns are interpreted
as directory names as in the 'set' subcommand.
-'reapply::
+'reapply'::
Reapply the sparsity pattern rules to paths in the working tree.
Commands like merge or rebase can materialize paths to do their
work (e.g. in order to show you a conflict), and other
@@ -200,10 +200,32 @@ directory.
SUBMODULES
----------
-If your repository contains one or more submodules, then those submodules will
-appear based on which you initialized with the `git submodule` command. If
-your sparse-checkout patterns exclude an initialized submodule, then that
-submodule will still appear in your working directory.
+If your repository contains one or more submodules, then submodules
+are populated based on interactions with the `git submodule` command.
+Specifically, `git submodule init -- <path>` will ensure the submodule
+at `<path>` is present, while `git submodule deinit [-f] -- <path>`
+will remove the files for the submodule at `<path>` (including any
+untracked files, uncommitted changes, and unpushed history). Similar
+to how sparse-checkout removes files from the working tree but still
+leaves entries in the index, deinitialized submodules are removed from
+the working directory but still have an entry in the index.
+
+Since submodules may have unpushed changes or untracked files,
+removing them could result in data loss. Thus, changing sparse
+inclusion/exclusion rules will not cause an already checked out
+submodule to be removed from the working copy. Said another way, just
+as `checkout` will not cause submodules to be automatically removed or
+initialized even when switching between branches that remove or add
+submodules, using `sparse-checkout` to reduce or expand the scope of
+"interesting" files will not cause submodules to be automatically
+deinitialized or initialized either.
+
+Further, the above facts mean that there are multiple reasons that
+"tracked" files might not be present in the working copy: sparsity
+pattern application from sparse-checkout, and submodule initialization
+state. Thus, commands like `git grep` that work on tracked files in
+the working copy may return results that are limited by either or both
+of these restrictions.
SEE ALSO
diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index 85d92c9..4796c3c 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -126,7 +126,9 @@ OPTIONS
locked working tree path, specify `--force` twice.
+
`move` refuses to move a locked working tree unless `--force` is specified
-twice.
+twice. If the destination is already assigned to some other working tree but is
+missing (for instance, if `<new-path>` was deleted manually), then `--force`
+allows the move to proceed; use --force twice if the destination is locked.
+
`remove` refuses to remove an unclean working tree unless `--force` is used.
To remove a locked working tree, specify `--force` twice.
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 9d6769e..3e50065 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -493,7 +493,7 @@ double-quotes and respecting backslash escapes. E.g., the value
details. This variable has lower precedence than other path
variables such as GIT_INDEX_FILE, GIT_OBJECT_DIRECTORY...
-`GIT_DEFAULT_HASH_ALGORITHM`::
+`GIT_DEFAULT_HASH`::
If this variable is set, the default hash algorithm for new
repositories will be set to this value. This value is currently
ignored when cloning; the setting of the remote repository
@@ -721,8 +721,6 @@ of clones and fetches.
Enables a curl full trace dump of all incoming and outgoing data,
including descriptive information, of the git transport protocol.
This is similar to doing curl `--trace-ascii` on the command line.
- This option overrides setting the `GIT_CURL_VERBOSE` environment
- variable.
See `GIT_TRACE` for available trace output options.
`GIT_TRACE_CURL_NO_DATA`::
@@ -777,11 +775,10 @@ for full details.
See `GIT_TRACE2` for available trace output options and
link:technical/api-trace2.html[Trace2 documentation] for full details.
-`GIT_REDACT_COOKIES`::
- This can be set to a comma-separated list of strings. When a curl trace
- is enabled (see `GIT_TRACE_CURL` above), whenever a "Cookies:" header
- sent by the client is dumped, values of cookies whose key is in that
- list (case-sensitive) are redacted.
+`GIT_TRACE_REDACT`::
+ By default, when tracing is activated, Git redacts the values of
+ cookies, the "Authorization:" header, and the "Proxy-Authorization:"
+ header. Set this variable to `0` to prevent this redaction.
`GIT_LITERAL_PATHSPECS`::
Setting this variable to `1` will cause Git to treat all
diff --git a/Documentation/gitfaq.txt b/Documentation/gitfaq.txt
index 370d62d..9cd7a59 100644
--- a/Documentation/gitfaq.txt
+++ b/Documentation/gitfaq.txt
@@ -223,7 +223,7 @@ a file checked into the repository which is a template or set of defaults which
can then be copied alongside and modified as appropriate. This second, modified
file is usually ignored to prevent accidentally committing it.
-[[files-in-.gitignore-are-tracked]]
+[[files-in-gitignore-are-tracked]]
I asked Git to ignore various files, yet they are still tracked::
A `gitignore` file ensures that certain file(s) which are not
tracked by Git remain untracked. However, sometimes particular
diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt
index f48a031..93baeeb 100644
--- a/Documentation/gitremote-helpers.txt
+++ b/Documentation/gitremote-helpers.txt
@@ -405,7 +405,9 @@ Supported if the helper has the "connect" capability.
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
+ PKT-LINEs, terminating in a flush packet. Response messages will
+ then have a response end packet after the flush packet to
+ indicate the end of a response. The client must not
expect the server to store any state in between request-response
pairs. After the connection ends, the remote helper exits.
+
diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 04ad7dd..b01b2b6 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -581,12 +581,12 @@ option does. Applied to the 'D..M' range, it results in:
Before discussing another option, `--show-pulls`, we need to
create a new example history.
-+
+
A common problem users face when looking at simplified history is that a
commit they know changed a file somehow does not appear in the file's
simplified history. Let's demonstrate a new example and show how options
such as `--full-history` and `--simplify-merges` works in that case:
-+
+
-----------------------------------------------------------------------
.-A---M-----C--N---O---P
/ / \ \ \/ / /
@@ -595,7 +595,7 @@ such as `--full-history` and `--simplify-merges` works in that case:
\ / /\ /
`---X--' `---Y--'
-----------------------------------------------------------------------
-+
+
For this example, suppose `I` created `file.txt` which was modified by
`A`, `B`, and `X` in different ways. The single-parent commits `C`, `Z`,
and `Y` do not change `file.txt`. The merge commit `M` was created by
@@ -607,19 +607,19 @@ the contents of `file.txt` at `X`. Hence, `R` is TREESAME to `X` but not
contents of `file.txt` at `R`, so `N` is TREESAME to `R` but not `C`.
The merge commits `O` and `P` are TREESAME to their first parents, but
not to their second parents, `Z` and `Y` respectively.
-+
+
When using the default mode, `N` and `R` both have a TREESAME parent, so
those edges are walked and the others are ignored. The resulting history
graph is:
-+
+
-----------------------------------------------------------------------
I---X
-----------------------------------------------------------------------
-+
+
When using `--full-history`, Git walks every edge. This will discover
the commits `A` and `B` and the merge `M`, but also will reveal the
merge commits `O` and `P`. With parent rewriting, the resulting graph is:
-+
+
-----------------------------------------------------------------------
.-A---M--------N---O---P
/ / \ \ \/ / /
@@ -628,21 +628,21 @@ merge commits `O` and `P`. With parent rewriting, the resulting graph is:
\ / /\ /
`---X--' `------'
-----------------------------------------------------------------------
-+
+
Here, the merge commits `O` and `P` contribute extra noise, as they did
not actually contribute a change to `file.txt`. They only merged a topic
that was based on an older version of `file.txt`. This is a common
issue in repositories using a workflow where many contributors work in
parallel and merge their topic branches along a single trunk: manu
unrelated merges appear in the `--full-history` results.
-+
+
When using the `--simplify-merges` option, the commits `O` and `P`
disappear from the results. This is because the rewritten second parents
of `O` and `P` are reachable from their first parents. Those edges are
removed and then the commits look like single-parent commits that are
TREESAME to their parent. This also happens to the commit `N`, resulting
in a history view as follows:
-+
+
-----------------------------------------------------------------------
.-A---M--.
/ / \
@@ -651,18 +651,18 @@ in a history view as follows:
\ / /
`---X--'
-----------------------------------------------------------------------
-+
+
In this view, we see all of the important single-parent changes from
`A`, `B`, and `X`. We also see the carefully-resolved merge `M` and the
not-so-carefully-resolved merge `R`. This is usually enough information
to determine why the commits `A` and `B` "disappeared" from history in
the default view. However, there are a few issues with this approach.
-+
+
The first issue is performance. Unlike any previous option, the
`--simplify-merges` option requires walking the entire commit history
before returning a single result. This can make the option difficult to
use for very large repositories.
-+
+
The second issue is one of auditing. When many contributors are working
on the same repository, it is important which merge commits introduced
a change into an important branch. The problematic merge `R` above is
@@ -671,10 +671,13 @@ important branch. Instead, the merge `N` was used to merge `R` and `X`
into the important branch. This commit may have information about why
the change `X` came to override the changes from `A` and `B` in its
commit message.
+
+--show-pulls::
+ In addition to the commits shown in the default history, show
+ each merge commit that is not TREESAME to its first parent but
+ is TREESAME to a later parent.
+
-The `--show-pulls` option helps with both of these issues by adding more
-merge commits to the history results. If a merge is not TREESAME to its
-first parent but is TREESAME to a later parent, then that merge is
+When a merge commit is included by `--show-pulls`, the merge is
treated as if it "pulled" the change from another branch. When using
`--show-pulls` on this example (and no other options) the resulting
graph is:
diff --git a/Documentation/technical/http-protocol.txt b/Documentation/technical/http-protocol.txt
index 9c5b6f0..51a79e6 100644
--- a/Documentation/technical/http-protocol.txt
+++ b/Documentation/technical/http-protocol.txt
@@ -216,7 +216,7 @@ smart server reply:
S: 001e# service=git-upload-pack\n
S: 0000
S: 004895dcfa3633004da0049d3d0fa03f80589cbcaf31 refs/heads/maint\0multi_ack\n
- S: 0042d049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n
+ S: 003fd049f6c27a2244e12041955e262a404c7faba355 refs/heads/master\n
S: 003c2cb58b79488a98d2721cea644875a8dd0026b115 refs/tags/v1.0\n
S: 003fa3c2e2402b99163d1d59756e5f207ae21cccba4c refs/tags/v1.0^{}\n
S: 0000
diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt
index d5ce4ee..a4573d1 100644
--- a/Documentation/technical/pack-protocol.txt
+++ b/Documentation/technical/pack-protocol.txt
@@ -96,7 +96,7 @@ Basically what the Git client is doing to connect to an 'upload-pack'
process on the server side over the Git protocol is this:
$ echo -e -n \
- "0039git-upload-pack /schacon/gitbook.git\0host=example.com\0" |
+ "003agit-upload-pack /schacon/gitbook.git\0host=example.com\0" |
nc -v example.com 9418
@@ -171,9 +171,9 @@ with a version number (if "version=1" is sent as an Extra Parameter),
and a listing of each reference it has (all branches and tags) along
with the object name that each reference currently points to.
- $ echo -e -n "0044git-upload-pack /schacon/gitbook.git\0host=example.com\0\0version=1\0" |
+ $ echo -e -n "0045git-upload-pack /schacon/gitbook.git\0host=example.com\0\0version=1\0" |
nc -v example.com 9418
- 000aversion 1
+ 000eversion 1
00887217a7c7e582c46cec22a130adf4b9d7d950fba0 HEAD\0multi_ack thin-pack
side-band side-band-64k ofs-delta shallow no-progress include-tag
00441d3fcd5ced445d1abc402225c0b8a1299641f497 refs/heads/integration
diff --git a/Documentation/technical/protocol-v2.txt b/Documentation/technical/protocol-v2.txt
index f9f4e4d..5852f49 100644
--- a/Documentation/technical/protocol-v2.txt
+++ b/Documentation/technical/protocol-v2.txt
@@ -33,6 +33,8 @@ 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
+ * '0002' Message Packet (response-end-pkt) - indicates the end of a response
+ for stateless connections
Initial Client Request
----------------------
diff --git a/Documentation/technical/reftable.txt b/Documentation/technical/reftable.txt
new file mode 100644
index 0000000..2951840
--- /dev/null
+++ b/Documentation/technical/reftable.txt
@@ -0,0 +1,1083 @@
+reftable
+--------
+
+Overview
+~~~~~~~~
+
+Problem statement
+^^^^^^^^^^^^^^^^^
+
+Some repositories contain a lot of references (e.g. android at 866k,
+rails at 31k). The existing packed-refs format takes up a lot of space
+(e.g. 62M), and does not scale with additional references. Lookup of a
+single reference requires linearly scanning the file.
+
+Atomic pushes modifying multiple references require copying the entire
+packed-refs file, which can be a considerable amount of data moved
+(e.g. 62M in, 62M out) for even small transactions (2 refs modified).
+
+Repositories with many loose references occupy a large number of disk
+blocks from the local file system, as each reference is its own file
+storing 41 bytes (and another file for the corresponding reflog). This
+negatively affects the number of inodes available when a large number of
+repositories are stored on the same filesystem. Readers can be penalized
+due to the larger number of syscalls required to traverse and read the
+`$GIT_DIR/refs` directory.
+
+
+Objectives
+^^^^^^^^^^
+
+* Near constant time lookup for any single reference, even when the
+repository is cold and not in process or kernel cache.
+* Near constant time verification if an object name is referred to by at least
+one reference (for allow-tip-sha1-in-want).
+* Efficient enumeration of an entire namespace, such as `refs/tags/`.
+* Support atomic push with `O(size_of_update)` operations.
+* Combine reflog storage with ref storage for small transactions.
+* Separate reflog storage for base refs and historical logs.
+
+Description
+^^^^^^^^^^^
+
+A reftable file is a portable binary file format customized for
+reference storage. References are sorted, enabling linear scans, binary
+search lookup, and range scans.
+
+Storage in the file is organized into variable sized blocks. Prefix
+compression is used within a single block to reduce disk space. Block
+size and alignment is tunable by the writer.
+
+Performance
+^^^^^^^^^^^
+
+Space used, packed-refs vs. reftable:
+
+[cols=",>,>,>,>,>",options="header",]
+|===============================================================
+|repository |packed-refs |reftable |% original |avg ref |avg obj
+|android |62.2 M |36.1 M |58.0% |33 bytes |5 bytes
+|rails |1.8 M |1.1 M |57.7% |29 bytes |4 bytes
+|git |78.7 K |48.1 K |61.0% |50 bytes |4 bytes
+|git (heads) |332 b |269 b |81.0% |33 bytes |0 bytes
+|===============================================================
+
+Scan (read 866k refs), by reference name lookup (single ref from 866k
+refs), and by SHA-1 lookup (refs with that SHA-1, from 866k refs):
+
+[cols=",>,>,>,>",options="header",]
+|=========================================================
+|format |cache |scan |by name |by SHA-1
+|packed-refs |cold |402 ms |409,660.1 usec |412,535.8 usec
+|packed-refs |hot | |6,844.6 usec |20,110.1 usec
+|reftable |cold |112 ms |33.9 usec |323.2 usec
+|reftable |hot | |20.2 usec |320.8 usec
+|=========================================================
+
+Space used for 149,932 log entries for 43,061 refs, reflog vs. reftable:
+
+[cols=",>,>",options="header",]
+|================================
+|format |size |avg entry
+|$GIT_DIR/logs |173 M |1209 bytes
+|reftable |5 M |37 bytes
+|================================
+
+Details
+~~~~~~~
+
+Peeling
+^^^^^^^
+
+References stored in a reftable are peeled, a record for an annotated
+(or signed) tag records both the tag object, and the object it refers
+to. This is analogous to storage in the packed-refs format.
+
+Reference name encoding
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Reference names are an uninterpreted sequence of bytes that must pass
+linkgit:git-check-ref-format[1] as a valid reference name.
+
+Key unicity
+^^^^^^^^^^^
+
+Each entry must have a unique key; repeated keys are disallowed.
+
+Network byte order
+^^^^^^^^^^^^^^^^^^
+
+All multi-byte, fixed width fields are in network byte order.
+
+Varint encoding
+^^^^^^^^^^^^^^^
+
+Varint encoding is identical to the ofs-delta encoding method used
+within pack files.
+
+Decoder works such as:
+
+....
+val = buf[ptr] & 0x7f
+while (buf[ptr] & 0x80) {
+ ptr++
+ val = ((val + 1) << 7) | (buf[ptr] & 0x7f)
+}
+....
+
+Ordering
+^^^^^^^^
+
+Blocks are lexicographically ordered by their first reference.
+
+Directory/file conflicts
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+The reftable format accepts both `refs/heads/foo` and
+`refs/heads/foo/bar` as distinct references.
+
+This property is useful for retaining log records in reftable, but may
+confuse versions of Git using `$GIT_DIR/refs` directory tree to maintain
+references. Users of reftable may choose to continue to reject `foo` and
+`foo/bar` type conflicts to prevent problems for peers.
+
+File format
+~~~~~~~~~~~
+
+Structure
+^^^^^^^^^
+
+A reftable file has the following high-level structure:
+
+....
+first_block {
+ header
+ first_ref_block
+}
+ref_block*
+ref_index*
+obj_block*
+obj_index*
+log_block*
+log_index*
+footer
+....
+
+A log-only file omits the `ref_block`, `ref_index`, `obj_block` and
+`obj_index` sections, containing only the file header and log block:
+
+....
+first_block {
+ header
+}
+log_block*
+log_index*
+footer
+....
+
+in a log-only file the first log block immediately follows the file
+header, without padding to block alignment.
+
+Block size
+^^^^^^^^^^
+
+The file's block size is arbitrarily determined by the writer, and does
+not have to be a power of 2. The block size must be larger than the
+longest reference name or log entry used in the repository, as
+references cannot span blocks.
+
+Powers of two that are friendly to the virtual memory system or
+filesystem (such as 4k or 8k) are recommended. Larger sizes (64k) can
+yield better compression, with a possible increased cost incurred by
+readers during access.
+
+The largest block size is `16777215` bytes (15.99 MiB).
+
+Block alignment
+^^^^^^^^^^^^^^^
+
+Writers may choose to align blocks at multiples of the block size by
+including `padding` filled with NUL bytes at the end of a block to round
+out to the chosen alignment. When alignment is used, writers must
+specify the alignment with the file header's `block_size` field.
+
+Block alignment is not required by the file format. Unaligned files must
+set `block_size = 0` in the file header, and omit `padding`. Unaligned
+files with more than one ref block must include the link:#Ref-index[ref
+index] to support fast lookup. Readers must be able to read both aligned
+and non-aligned files.
+
+Very small files (e.g. a single ref block) may omit `padding` and the ref
+index to reduce total file size.
+
+Header (version 1)
+^^^^^^^^^^^^^^^^^^
+
+A 24-byte header appears at the beginning of the file:
+
+....
+'REFT'
+uint8( version_number = 1 )
+uint24( block_size )
+uint64( min_update_index )
+uint64( max_update_index )
+....
+
+Aligned files must specify `block_size` to configure readers with the
+expected block alignment. Unaligned files must set `block_size = 0`.
+
+The `min_update_index` and `max_update_index` describe bounds for the
+`update_index` field of all log records in this file. When reftables are
+used in a stack for link:#Update-transactions[transactions], these
+fields can order the files such that the prior file's
+`max_update_index + 1` is the next file's `min_update_index`.
+
+Header (version 2)
+^^^^^^^^^^^^^^^^^^
+
+A 28-byte header appears at the beginning of the file:
+
+....
+'REFT'
+uint8( version_number = 2 )
+uint24( block_size )
+uint64( min_update_index )
+uint64( max_update_index )
+uint32( hash_id )
+....
+
+The header is identical to `version_number=1`, with the 4-byte hash ID
+("sha1" for SHA1 and "s256" for SHA-256) append to the header.
+
+For maximum backward compatibility, it is recommended to use version 1 when
+writing SHA1 reftables.
+
+First ref block
+^^^^^^^^^^^^^^^
+
+The first ref block shares the same block as the file header, and is 24
+bytes smaller than all other blocks in the file. The first block
+immediately begins after the file header, at position 24.
+
+If the first block is a log block (a log-only file), its block header
+begins immediately at position 24.
+
+Ref block format
+^^^^^^^^^^^^^^^^
+
+A ref block is written as:
+
+....
+'r'
+uint24( block_len )
+ref_record+
+uint24( restart_offset )+
+uint16( restart_count )
+
+padding?
+....
+
+Blocks begin with `block_type = 'r'` and a 3-byte `block_len` which
+encodes the number of bytes in the block up to, but not including the
+optional `padding`. This is always less than or equal to the file's
+block size. In the first ref block, `block_len` includes 24 bytes for
+the file header.
+
+The 2-byte `restart_count` stores the number of entries in the
+`restart_offset` list, which must not be empty. Readers can use
+`restart_count` to binary search between restarts before starting a
+linear scan.
+
+Exactly `restart_count` 3-byte `restart_offset` values precedes the
+`restart_count`. Offsets are relative to the start of the block and
+refer to the first byte of any `ref_record` whose name has not been
+prefix compressed. Entries in the `restart_offset` list must be sorted,
+ascending. Readers can start linear scans from any of these records.
+
+A variable number of `ref_record` fill the middle of the block,
+describing reference names and values. The format is described below.
+
+As the first ref block shares the first file block with the file header,
+all `restart_offset` in the first block are relative to the start of the
+file (position 0), and include the file header. This forces the first
+`restart_offset` to be `28`.
+
+ref record
+++++++++++
+
+A `ref_record` describes a single reference, storing both the name and
+its value(s). Records are formatted as:
+
+....
+varint( prefix_length )
+varint( (suffix_length << 3) | value_type )
+suffix
+varint( update_index_delta )
+value?
+....
+
+The `prefix_length` field specifies how many leading bytes of the prior
+reference record's name should be copied to obtain this reference's
+name. This must be 0 for the first reference in any block, and also must
+be 0 for any `ref_record` whose offset is listed in the `restart_offset`
+table at the end of the block.
+
+Recovering a reference name from any `ref_record` is a simple concat:
+
+....
+this_name = prior_name[0..prefix_length] + suffix
+....
+
+The `suffix_length` value provides the number of bytes available in
+`suffix` to copy from `suffix` to complete the reference name.
+
+The `update_index` that last modified the reference can be obtained by
+adding `update_index_delta` to the `min_update_index` from the file
+header: `min_update_index + update_index_delta`.
+
+The `value` follows. Its format is determined by `value_type`, one of
+the following:
+
+* `0x0`: deletion; no value data (see transactions, below)
+* `0x1`: one object name; value of the ref
+* `0x2`: two object names; value of the ref, peeled target
+* `0x3`: symbolic reference: `varint( target_len ) target`
+
+Symbolic references use `0x3`, followed by the complete name of the
+reference target. No compression is applied to the target name.
+
+Types `0x4..0x7` are reserved for future use.
+
+Ref index
+^^^^^^^^^
+
+The ref index stores the name of the last reference from every ref block
+in the file, enabling reduced disk seeks for lookups. Any reference can
+be found by searching the index, identifying the containing block, and
+searching within that block.
+
+The index may be organized into a multi-level index, where the 1st level
+index block points to additional ref index blocks (2nd level), which may
+in turn point to either additional index blocks (e.g. 3rd level) or ref
+blocks (leaf level). Disk reads required to access a ref go up with
+higher index levels. Multi-level indexes may be required to ensure no
+single index block exceeds the file format's max block size of
+`16777215` bytes (15.99 MiB). To achieve constant O(1) disk seeks for
+lookups the index must be a single level, which is permitted to exceed
+the file's configured block size, but not the format's max block size of
+15.99 MiB.
+
+If present, the ref index block(s) appears after the last ref block.
+
+If there are at least 4 ref blocks, a ref index block should be written
+to improve lookup times. Cold reads using the index require 2 disk reads
+(read index, read block), and binary searching < 4 blocks also requires
+<= 2 reads. Omitting the index block from smaller files saves space.
+
+If the file is unaligned and contains more than one ref block, the ref
+index must be written.
+
+Index block format:
+
+....
+'i'
+uint24( block_len )
+index_record+
+uint24( restart_offset )+
+uint16( restart_count )
+
+padding?
+....
+
+The index blocks begin with `block_type = 'i'` and a 3-byte `block_len`
+which encodes the number of bytes in the block, up to but not including
+the optional `padding`.
+
+The `restart_offset` and `restart_count` fields are identical in format,
+meaning and usage as in ref blocks.
+
+To reduce the number of reads required for random access in very large
+files the index block may be larger than other blocks. However, readers
+must hold the entire index in memory to benefit from this, so it's a
+time-space tradeoff in both file size and reader memory.
+
+Increasing the file's block size decreases the index size. Alternatively
+a multi-level index may be used, keeping index blocks within the file's
+block size, but increasing the number of blocks that need to be
+accessed.
+
+index record
+++++++++++++
+
+An index record describes the last entry in another block. Index records
+are written as:
+
+....
+varint( prefix_length )
+varint( (suffix_length << 3) | 0 )
+suffix
+varint( block_position )
+....
+
+Index records use prefix compression exactly like `ref_record`.
+
+Index records store `block_position` after the suffix, specifying the
+absolute position in bytes (from the start of the file) of the block
+that ends with this reference. Readers can seek to `block_position` to
+begin reading the block header.
+
+Readers must examine the block header at `block_position` to determine
+if the next block is another level index block, or the leaf-level ref
+block.
+
+Reading the index
++++++++++++++++++
+
+Readers loading the ref index must first read the footer (below) to
+obtain `ref_index_position`. If not present, the position will be 0. The
+`ref_index_position` is for the 1st level root of the ref index.
+
+Obj block format
+^^^^^^^^^^^^^^^^
+
+Object blocks are optional. Writers may choose to omit object blocks,
+especially if readers will not use the object name to ref mapping.
+
+Object blocks use unique, abbreviated 2-32 object name keys, mapping to
+ref blocks containing references pointing to that object directly, or as
+the peeled value of an annotated tag. Like ref blocks, object blocks use
+the file's standard block size. The abbrevation length is available in
+the footer as `obj_id_len`.
+
+To save space in small files, object blocks may be omitted if the ref
+index is not present, as brute force search will only need to read a few
+ref blocks. When missing, readers should brute force a linear search of
+all references to lookup by object name.
+
+An object block is written as:
+
+....
+'o'
+uint24( block_len )
+obj_record+
+uint24( restart_offset )+
+uint16( restart_count )
+
+padding?
+....
+
+Fields are identical to ref block. Binary search using the restart table
+works the same as in reference blocks.
+
+Because object names are abbreviated by writers to the shortest unique
+abbreviation within the reftable, obj key lengths have a variable length. Their
+length must be at least 2 bytes. Readers must compare only for common prefix
+match within an obj block or obj index.
+
+obj record
+++++++++++
+
+An `obj_record` describes a single object abbreviation, and the blocks
+containing references using that unique abbreviation:
+
+....
+varint( prefix_length )
+varint( (suffix_length << 3) | cnt_3 )
+suffix
+varint( cnt_large )?
+varint( position_delta )*
+....
+
+Like in reference blocks, abbreviations are prefix compressed within an
+obj block. On large reftables with many unique objects, higher block
+sizes (64k), and higher restart interval (128), a `prefix_length` of 2
+or 3 and `suffix_length` of 3 may be common in obj records (unique
+abbreviation of 5-6 raw bytes, 10-12 hex digits).
+
+Each record contains `position_count` number of positions for matching
+ref blocks. For 1-7 positions the count is stored in `cnt_3`. When
+`cnt_3 = 0` the actual count follows in a varint, `cnt_large`.
+
+The use of `cnt_3` bets most objects are pointed to by only a single
+reference, some may be pointed to by a couple of references, and very
+few (if any) are pointed to by more than 7 references.
+
+A special case exists when `cnt_3 = 0` and `cnt_large = 0`: there are no
+`position_delta`, but at least one reference starts with this
+abbreviation. A reader that needs exact reference names must scan all
+references to find which specific references have the desired object.
+Writers should use this format when the `position_delta` list would have
+overflowed the file's block size due to a high number of references
+pointing to the same object.
+
+The first `position_delta` is the position from the start of the file.
+Additional `position_delta` entries are sorted ascending and relative to
+the prior entry, e.g. a reader would perform:
+
+....
+pos = position_delta[0]
+prior = pos
+for (j = 1; j < position_count; j++) {
+ pos = prior + position_delta[j]
+ prior = pos
+}
+....
+
+With a position in hand, a reader must linearly scan the ref block,
+starting from the first `ref_record`, testing each reference's object names
+(for `value_type = 0x1` or `0x2`) for full equality. Faster searching by
+object name within a single ref block is not supported by the reftable format.
+Smaller block sizes reduce the number of candidates this step must
+consider.
+
+Obj index
+^^^^^^^^^
+
+The obj index stores the abbreviation from the last entry for every obj
+block in the file, enabling reduced disk seeks for all lookups. It is
+formatted exactly the same as the ref index, but refers to obj blocks.
+
+The obj index should be present if obj blocks are present, as obj blocks
+should only be written in larger files.
+
+Readers loading the obj index must first read the footer (below) to
+obtain `obj_index_position`. If not present, the position will be 0.
+
+Log block format
+^^^^^^^^^^^^^^^^
+
+Unlike ref and obj blocks, log blocks are always unaligned.
+
+Log blocks are variable in size, and do not match the `block_size`
+specified in the file header or footer. Writers should choose an
+appropriate buffer size to prepare a log block for deflation, such as
+`2 * block_size`.
+
+A log block is written as:
+
+....
+'g'
+uint24( block_len )
+zlib_deflate {
+ log_record+
+ uint24( restart_offset )+
+ uint16( restart_count )
+}
+....
+
+Log blocks look similar to ref blocks, except `block_type = 'g'`.
+
+The 4-byte block header is followed by the deflated block contents using
+zlib deflate. The `block_len` in the header is the inflated size
+(including 4-byte block header), and should be used by readers to
+preallocate the inflation output buffer. A log block's `block_len` may
+exceed the file's block size.
+
+Offsets within the log block (e.g. `restart_offset`) still include the
+4-byte header. Readers may prefer prefixing the inflation output buffer
+with the 4-byte header.
+
+Within the deflate container, a variable number of `log_record` describe
+reference changes. The log record format is described below. See ref
+block format (above) for a description of `restart_offset` and
+`restart_count`.
+
+Because log blocks have no alignment or padding between blocks, readers
+must keep track of the bytes consumed by the inflater to know where the
+next log block begins.
+
+log record
+++++++++++
+
+Log record keys are structured as:
+
+....
+ref_name '\0' reverse_int64( update_index )
+....
+
+where `update_index` is the unique transaction identifier. The
+`update_index` field must be unique within the scope of a `ref_name`.
+See the update transactions section below for further details.
+
+The `reverse_int64` function inverses the value so lexicographical
+ordering the network byte order encoding sorts the more recent records
+with higher `update_index` values first:
+
+....
+reverse_int64(int64 t) {
+ return 0xffffffffffffffff - t;
+}
+....
+
+Log records have a similar starting structure to ref and index records,
+utilizing the same prefix compression scheme applied to the log record
+key described above.
+
+....
+ varint( prefix_length )
+ varint( (suffix_length << 3) | log_type )
+ suffix
+ log_data {
+ old_id
+ new_id
+ varint( name_length ) name
+ varint( email_length ) email
+ varint( time_seconds )
+ sint16( tz_offset )
+ varint( message_length ) message
+ }?
+....
+
+Log record entries use `log_type` to indicate what follows:
+
+* `0x0`: deletion; no log data.
+* `0x1`: standard git reflog data using `log_data` above.
+
+The `log_type = 0x0` is mostly useful for `git stash drop`, removing an
+entry from the reflog of `refs/stash` in a transaction file (below),
+without needing to rewrite larger files. Readers reading a stack of
+reflogs must treat this as a deletion.
+
+For `log_type = 0x1`, the `log_data` section follows
+linkgit:git-update-ref[1] logging and includes:
+
+* two object names (old id, new id)
+* varint string of committer's name
+* varint string of committer's email
+* varint time in seconds since epoch (Jan 1, 1970)
+* 2-byte timezone offset in minutes (signed)
+* varint string of message
+
+`tz_offset` is the absolute number of minutes from GMT the committer was
+at the time of the update. For example `GMT-0800` is encoded in reftable
+as `sint16(-480)` and `GMT+0230` is `sint16(150)`.
+
+The committer email does not contain `<` or `>`, it's the value normally
+found between the `<>` in a git commit object header.
+
+The `message_length` may be 0, in which case there was no message
+supplied for the update.
+
+Contrary to traditional reflog (which is a file), renames are encoded as
+a combination of ref deletion and ref creation. A deletion is a log
+record with a zero new_id, and a creation is a log record with a zero old_id.
+
+Reading the log
++++++++++++++++
+
+Readers accessing the log must first read the footer (below) to
+determine the `log_position`. The first block of the log begins at
+`log_position` bytes since the start of the file. The `log_position` is
+not block aligned.
+
+Importing logs
+++++++++++++++
+
+When importing from `$GIT_DIR/logs` writers should globally order all
+log records roughly by timestamp while preserving file order, and assign
+unique, increasing `update_index` values for each log line. Newer log
+records get higher `update_index` values.
+
+Although an import may write only a single reftable file, the reftable
+file must span many unique `update_index`, as each log line requires its
+own `update_index` to preserve semantics.
+
+Log index
+^^^^^^^^^
+
+The log index stores the log key
+(`refname \0 reverse_int64(update_index)`) for the last log record of
+every log block in the file, supporting bounded-time lookup.
+
+A log index block must be written if 2 or more log blocks are written to
+the file. If present, the log index appears after the last log block.
+There is no padding used to align the log index to block alignment.
+
+Log index format is identical to ref index, except the keys are 9 bytes
+longer to include `'\0'` and the 8-byte `reverse_int64(update_index)`.
+Records use `block_position` to refer to the start of a log block.
+
+Reading the index
++++++++++++++++++
+
+Readers loading the log index must first read the footer (below) to
+obtain `log_index_position`. If not present, the position will be 0.
+
+Footer
+^^^^^^
+
+After the last block of the file, a file footer is written. It begins
+like the file header, but is extended with additional data.
+
+....
+ HEADER
+
+ uint64( ref_index_position )
+ uint64( (obj_position << 5) | obj_id_len )
+ uint64( obj_index_position )
+
+ uint64( log_position )
+ uint64( log_index_position )
+
+ uint32( CRC-32 of above )
+....
+
+If a section is missing (e.g. ref index) the corresponding position
+field (e.g. `ref_index_position`) will be 0.
+
+* `obj_position`: byte position for the first obj block.
+* `obj_id_len`: number of bytes used to abbreviate object names in
+obj blocks.
+* `log_position`: byte position for the first log block.
+* `ref_index_position`: byte position for the start of the ref index.
+* `obj_index_position`: byte position for the start of the obj index.
+* `log_index_position`: byte position for the start of the log index.
+
+The size of the footer is 68 bytes for version 1, and 72 bytes for
+version 2.
+
+Reading the footer
+++++++++++++++++++
+
+Readers must first read the file start to determine the version
+number. Then they seek to `file_length - FOOTER_LENGTH` to access the
+footer. A trusted external source (such as `stat(2)`) is necessary to
+obtain `file_length`. When reading the footer, readers must verify:
+
+* 4-byte magic is correct
+* 1-byte version number is recognized
+* 4-byte CRC-32 matches the other 64 bytes (including magic, and
+version)
+
+Once verified, the other fields of the footer can be accessed.
+
+Empty tables
+++++++++++++
+
+A reftable may be empty. In this case, the file starts with a header
+and is immediately followed by a footer.
+
+Binary search
+^^^^^^^^^^^^^
+
+Binary search within a block is supported by the `restart_offset` fields
+at the end of the block. Readers can binary search through the restart
+table to locate between which two restart points the sought reference or
+key should appear.
+
+Each record identified by a `restart_offset` stores the complete key in
+the `suffix` field of the record, making the compare operation during
+binary search straightforward.
+
+Once a restart point lexicographically before the sought reference has
+been identified, readers can linearly scan through the following record
+entries to locate the sought record, terminating if the current record
+sorts after (and therefore the sought key is not present).
+
+Restart point selection
++++++++++++++++++++++++
+
+Writers determine the restart points at file creation. The process is
+arbitrary, but every 16 or 64 records is recommended. Every 16 may be
+more suitable for smaller block sizes (4k or 8k), every 64 for larger
+block sizes (64k).
+
+More frequent restart points reduces prefix compression and increases
+space consumed by the restart table, both of which increase file size.
+
+Less frequent restart points makes prefix compression more effective,
+decreasing overall file size, with increased penalties for readers
+walking through more records after the binary search step.
+
+A maximum of `65535` restart points per block is supported.
+
+Considerations
+~~~~~~~~~~~~~~
+
+Lightweight refs dominate
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The reftable format assumes the vast majority of references are single
+object names valued with common prefixes, such as Gerrit Code Review's
+`refs/changes/` namespace, GitHub's `refs/pulls/` namespace, or many
+lightweight tags in the `refs/tags/` namespace.
+
+Annotated tags storing the peeled object cost an additional object name per
+reference.
+
+Low overhead
+^^^^^^^^^^^^
+
+A reftable with very few references (e.g. git.git with 5 heads) is 269
+bytes for reftable, vs. 332 bytes for packed-refs. This supports
+reftable scaling down for transaction logs (below).
+
+Block size
+^^^^^^^^^^
+
+For a Gerrit Code Review type repository with many change refs, larger
+block sizes (64 KiB) and less frequent restart points (every 64) yield
+better compression due to more references within the block compressing
+against the prior reference.
+
+Larger block sizes reduce the index size, as the reftable will require
+fewer blocks to store the same number of references.
+
+Minimal disk seeks
+^^^^^^^^^^^^^^^^^^
+
+Assuming the index block has been loaded into memory, binary searching
+for any single reference requires exactly 1 disk seek to load the
+containing block.
+
+Scans and lookups dominate
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Scanning all references and lookup by name (or namespace such as
+`refs/heads/`) are the most common activities performed on repositories.
+Object names are stored directly with references to optimize this use case.
+
+Logs are infrequently read
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Logs are infrequently accessed, but can be large. Deflating log blocks
+saves disk space, with some increased penalty at read time.
+
+Logs are stored in an isolated section from refs, reducing the burden on
+reference readers that want to ignore logs. Further, historical logs can
+be isolated into log-only files.
+
+Logs are read backwards
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Logs are frequently accessed backwards (most recent N records for master
+to answer `master@{4}`), so log records are grouped by reference, and
+sorted descending by update index.
+
+Repository format
+~~~~~~~~~~~~~~~~~
+
+Version 1
+^^^^^^^^^
+
+A repository must set its `$GIT_DIR/config` to configure reftable:
+
+....
+[core]
+ repositoryformatversion = 1
+[extensions]
+ refStorage = reftable
+....
+
+Layout
+^^^^^^
+
+A collection of reftable files are stored in the `$GIT_DIR/reftable/`
+directory:
+
+....
+00000001-00000001.log
+00000002-00000002.ref
+00000003-00000003.ref
+....
+
+where reftable files are named by a unique name such as produced by the
+function `${min_update_index}-${max_update_index}.ref`.
+
+Log-only files use the `.log` extension, while ref-only and mixed ref
+and log files use `.ref`. extension.
+
+The stack ordering file is `$GIT_DIR/reftable/tables.list` and lists the
+current files, one per line, in order, from oldest (base) to newest
+(most recent):
+
+....
+$ cat .git/reftable/tables.list
+00000001-00000001.log
+00000002-00000002.ref
+00000003-00000003.ref
+....
+
+Readers must read `$GIT_DIR/reftable/tables.list` to determine which
+files are relevant right now, and search through the stack in reverse
+order (last reftable is examined first).
+
+Reftable files not listed in `tables.list` may be new (and about to be
+added to the stack by the active writer), or ancient and ready to be
+pruned.
+
+Backward compatibility
+^^^^^^^^^^^^^^^^^^^^^^
+
+Older clients should continue to recognize the directory as a git
+repository so they don't look for an enclosing repository in parent
+directories. To this end, a reftable-enabled repository must contain the
+following dummy files
+
+* `.git/HEAD`, a regular file containing `ref: refs/heads/.invalid`.
+* `.git/refs/`, a directory
+* `.git/refs/heads`, a regular file
+
+Readers
+^^^^^^^
+
+Readers can obtain a consistent snapshot of the reference space by
+following:
+
+1. Open and read the `tables.list` file.
+2. Open each of the reftable files that it mentions.
+3. If any of the files is missing, goto 1.
+4. Read from the now-open files as long as necessary.
+
+Update transactions
+^^^^^^^^^^^^^^^^^^^
+
+Although reftables are immutable, mutations are supported by writing a
+new reftable and atomically appending it to the stack:
+
+1. Acquire `tables.list.lock`.
+2. Read `tables.list` to determine current reftables.
+3. Select `update_index` to be most recent file's
+`max_update_index + 1`.
+4. Prepare temp reftable `tmp_XXXXXX`, including log entries.
+5. Rename `tmp_XXXXXX` to `${update_index}-${update_index}.ref`.
+6. Copy `tables.list` to `tables.list.lock`, appending file from (5).
+7. Rename `tables.list.lock` to `tables.list`.
+
+During step 4 the new file's `min_update_index` and `max_update_index`
+are both set to the `update_index` selected by step 3. All log records
+for the transaction use the same `update_index` in their keys. This
+enables later correlation of which references were updated by the same
+transaction.
+
+Because a single `tables.list.lock` file is used to manage locking, the
+repository is single-threaded for writers. Writers may have to busy-spin
+(with backoff) around creating `tables.list.lock`, for up to an
+acceptable wait period, aborting if the repository is too busy to
+mutate. Application servers wrapped around repositories (e.g. Gerrit
+Code Review) can layer their own lock/wait queue to improve fairness to
+writers.
+
+Reference deletions
+^^^^^^^^^^^^^^^^^^^
+
+Deletion of any reference can be explicitly stored by setting the `type`
+to `0x0` and omitting the `value` field of the `ref_record`. This serves
+as a tombstone, overriding any assertions about the existence of the
+reference from earlier files in the stack.
+
+Compaction
+^^^^^^^^^^
+
+A partial stack of reftables can be compacted by merging references
+using a straightforward merge join across reftables, selecting the most
+recent value for output, and omitting deleted references that do not
+appear in remaining, lower reftables.
+
+A compacted reftable should set its `min_update_index` to the smallest
+of the input files' `min_update_index`, and its `max_update_index`
+likewise to the largest input `max_update_index`.
+
+For sake of illustration, assume the stack currently consists of
+reftable files (from oldest to newest): A, B, C, and D. The compactor is
+going to compact B and C, leaving A and D alone.
+
+1. Obtain lock `tables.list.lock` and read the `tables.list` file.
+2. Obtain locks `B.lock` and `C.lock`. Ownership of these locks
+prevents other processes from trying to compact these files.
+3. Release `tables.list.lock`.
+4. Compact `B` and `C` into a temp file
+`${min_update_index}-${max_update_index}_XXXXXX`.
+5. Reacquire lock `tables.list.lock`.
+6. Verify that `B` and `C` are still in the stack, in that order. This
+should always be the case, assuming that other processes are adhering to
+the locking protocol.
+7. Rename `${min_update_index}-${max_update_index}_XXXXXX` to
+`${min_update_index}-${max_update_index}.ref`.
+8. Write the new stack to `tables.list.lock`, replacing `B` and `C`
+with the file from (4).
+9. Rename `tables.list.lock` to `tables.list`.
+10. Delete `B` and `C`, perhaps after a short sleep to avoid forcing
+readers to backtrack.
+
+This strategy permits compactions to proceed independently of updates.
+
+Each reftable (compacted or not) is uniquely identified by its name, so
+open reftables can be cached by their name.
+
+Alternatives considered
+~~~~~~~~~~~~~~~~~~~~~~~
+
+bzip packed-refs
+^^^^^^^^^^^^^^^^
+
+`bzip2` can significantly shrink a large packed-refs file (e.g. 62 MiB
+compresses to 23 MiB, 37%). However the bzip format does not support
+random access to a single reference. Readers must inflate and discard
+while performing a linear scan.
+
+Breaking packed-refs into chunks (individually compressing each chunk)
+would reduce the amount of data a reader must inflate, but still leaves
+the problem of indexing chunks to support readers efficiently locating
+the correct chunk.
+
+Given the compression achieved by reftable's encoding, it does not seem
+necessary to add the complexity of bzip/gzip/zlib.
+
+Michael Haggerty's alternate format
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Michael Haggerty proposed
+link:https://lore.kernel.org/git/CAMy9T_HCnyc1g8XWOOWhe7nN0aEFyyBskV2aOMb_fe%2BwGvEJ7A%40mail.gmail.com/[an
+alternate] format to reftable on the Git mailing list. This format uses
+smaller chunks, without the restart table, and avoids block alignment
+with padding. Reflog entries immediately follow each ref, and are thus
+interleaved between refs.
+
+Performance testing indicates reftable is faster for lookups (51%
+faster, 11.2 usec vs. 5.4 usec), although reftable produces a slightly
+larger file (+ ~3.2%, 28.3M vs 29.2M):
+
+[cols=">,>,>,>",options="header",]
+|=====================================
+|format |size |seek cold |seek hot
+|mh-alt |28.3 M |23.4 usec |11.2 usec
+|reftable |29.2 M |19.9 usec |5.4 usec
+|=====================================
+
+JGit Ketch RefTree
+^^^^^^^^^^^^^^^^^^
+
+https://dev.eclipse.org/mhonarc/lists/jgit-dev/msg03073.html[JGit Ketch]
+proposed
+link:https://lore.kernel.org/git/CAJo%3DhJvnAPNAdDcAAwAvU9C4RVeQdoS3Ev9WTguHx4fD0V_nOg%40mail.gmail.com/[RefTree],
+an encoding of references inside Git tree objects stored as part of the
+repository's object database.
+
+The RefTree format adds additional load on the object database storage
+layer (more loose objects, more objects in packs), and relies heavily on
+the packer's delta compression to save space. Namespaces which are flat
+(e.g. thousands of tags in refs/tags) initially create very large loose
+objects, and so RefTree does not address the problem of copying many
+references to modify a handful.
+
+Flat namespaces are not efficiently searchable in RefTree, as tree
+objects in canonical formatting cannot be binary searched. This fails
+the need to handle a large number of references in a single namespace,
+such as GitHub's `refs/pulls`, or a project with many tags.
+
+LMDB
+^^^^
+
+David Turner proposed
+https://lore.kernel.org/git/1455772670-21142-26-git-send-email-dturner@twopensource.com/[using
+LMDB], as LMDB is lightweight (64k of runtime code) and GPL-compatible
+license.
+
+A downside of LMDB is its reliance on a single C implementation. This
+makes embedding inside JGit (a popular reimplementation of Git)
+difficult, and hoisting onto virtual storage (for JGit DFS) virtually
+impossible.
+
+A common format that can be supported by all major Git implementations
+(git-core, JGit, libgit2) is strongly preferred.