summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2021-02-22 16:57:12 -0800
committerJunio C Hamano <gitster@pobox.com>2021-02-22 16:57:12 -0800
commita70c988a0584e1197ffd19b26c28e9790da32363 (patch)
treeeb0f2dd1584011f40e4589c81288ac3b9f3d7c61
parentb4fc8e8cbb4fa1443a8546bdff0b1e5cd06f15fd (diff)
downloadgit-htmldocs-a70c988a0584e1197ffd19b26c28e9790da32363.tar.gz
Autogenerated HTML docs for v2.30.1-602-g966e6
-rw-r--r--RelNotes/2.31.0.txt65
-rw-r--r--config.txt2
-rw-r--r--git-config.html47
-rw-r--r--git-maintenance.html13
-rw-r--r--git-maintenance.txt6
-rw-r--r--git-mergetool--lib.html11
-rw-r--r--git-mergetool--lib.txt4
-rw-r--r--git-range-diff.html43
-rw-r--r--git-range-diff.txt20
-rw-r--r--git-shortlog.html5
-rw-r--r--git-shortlog.txt4
-rw-r--r--git-stash.html10
-rw-r--r--git-stash.txt8
-rw-r--r--howto/keep-canonical-history-correct.html2
-rw-r--r--howto/maintain-git.html2
-rw-r--r--howto/new-command.html2
-rw-r--r--howto/rebase-from-internal-branch.html2
-rw-r--r--howto/rebuild-from-update-hook.html2
-rw-r--r--howto/recover-corrupted-blob-object.html2
-rw-r--r--howto/recover-corrupted-object-harder.html2
-rw-r--r--howto/revert-a-faulty-merge.html2
-rw-r--r--howto/revert-branch-rebase.html2
-rw-r--r--howto/separating-topic-branches.html2
-rw-r--r--howto/setup-git-server-over-http.html2
-rw-r--r--howto/update-hook-example.html2
-rw-r--r--howto/use-git-daemon.html2
-rw-r--r--howto/using-merge-subtree.html2
-rw-r--r--howto/using-signed-tag-in-pull-request.html2
-rw-r--r--technical/commit-graph-format.txt28
-rw-r--r--technical/commit-graph.txt77
-rw-r--r--technical/hash-function-transition.html607
-rw-r--r--technical/hash-function-transition.txt293
-rw-r--r--technical/protocol-v2.html14
-rw-r--r--technical/protocol-v2.txt11
34 files changed, 913 insertions, 385 deletions
diff --git a/RelNotes/2.31.0.txt b/RelNotes/2.31.0.txt
index aae920466..1d2dba2c8 100644
--- a/RelNotes/2.31.0.txt
+++ b/RelNotes/2.31.0.txt
@@ -60,6 +60,35 @@ UI, Workflows & Features
locked and prunable attributes in --porcelain mode, and gained
a --verbose option.
+ * "git clone" tries to locally check out the branch pointed at by
+ HEAD of the remote repository after it is done, but the protocol
+ did not convey the information necessary to do so when copying an
+ empty repository. The protocol v2 learned how to do so.
+
+ * There are other ways than ".." for a single token to denote a
+ "commit range", namely "<rev>^!" and "<rev>^-<n>", but "git
+ range-diff" did not understand them.
+
+ * The "git range-diff" command learned "--(left|right)-only" option
+ to show only one side of the compared range.
+
+ * "git mergetool" feeds three versions (base, local and remote) of
+ a conflicted path unmodified. The command learned to optionally
+ prepare these files with unconflicted parts already resolved.
+
+ * The .mailmap is documented to be read only from the root level of a
+ working tree, but a stray file in a bare repository also was read
+ by accident, which has been corrected.
+
+ * "git maintenance" tool learned a new "pack-refs" maintenance task.
+
+ * The error message given when a configuration variable that is
+ expected to have a boolean value has been improved.
+
+ * Signed commits and tags now allow verification of objects, whose
+ two object names (one in SHA-1, the other in SHA-256) are both
+ signed.
+
Performance, Internal Implementation, Development Support etc.
@@ -139,6 +168,14 @@ Performance, Internal Implementation, Development Support etc.
* Introduce an on-disk file to record revindex for packdata, which
traditionally was always created on the fly and only in-core.
+ * The commit-graph learned to use corrected commit dates instead of
+ the generation number to help topological revision traversal.
+
+ * Piecemeal of rewrite of "git bisect" in C continues.
+
+ * When a pager spawned by us exited, the trace log did not record its
+ exit status correctly, which has been corrected.
+
Fixes since v2.30
-----------------
@@ -209,5 +246,33 @@ Fixes since v2.30
command line arguments.
(merge 5c327502db tb/precompose-prefix-too later to maint).
+ * Even though invocations of "die()" were logged to the trace2
+ system, "BUG()"s were not, which has been corrected.
+ (merge 0a9dde4a04 jt/trace2-BUG later to maint).
+
+ * "git grep --untracked" is meant to be "let's ALSO find in these
+ files on the filesystem" when looking for matches in the working
+ tree files, and does not make any sense if the primary search is
+ done against the index, or the tree objects. The "--cached" and
+ "--untracked" options have been marked as mutually incompatible.
+ (merge 0c5d83b248 mt/grep-cached-untracked later to maint).
+
+ * Fix "git fsck --name-objects" which apparently has not been used by
+ anybody who is motivated enough to report breakage.
+ (merge e89f89361c js/fsck-name-objects-fix later to maint).
+
+ * Avoid individual tests in t5411 from getting affected by each other
+ by forcing them to use separate output files during the test.
+ (merge 822ee894f6 jx/t5411-unique-filenames later to maint).
+
+ * Test to make sure "git rev-parse one-thing one-thing" gives
+ the same thing twice (when one-thing is --since=X).
+ (merge a5cdca4520 ew/rev-parse-since-test later to maint).
+
+ * When certain features (e.g. grafts) used in the repository are
+ incompatible with the use of the commit-graph, we used to silently
+ turned commit-graph off; we now tell the user what we are doing.
+ (merge c85eec7fc3 js/commit-graph-warning later to maint).
+
* Other code cleanup, docfix, build fix, etc.
(merge e3f5da7e60 sg/t7800-difftool-robustify later to maint).
diff --git a/config.txt b/config.txt
index 6ba50b110..d08e83a14 100644
--- a/config.txt
+++ b/config.txt
@@ -398,6 +398,8 @@ include::config/interactive.txt[]
include::config/log.txt[]
+include::config/lsrefs.txt[]
+
include::config/mailinfo.txt[]
include::config/mailmap.txt[]
diff --git a/git-config.html b/git-config.html
index c7ea36497..81392d89e 100644
--- a/git-config.html
+++ b/git-config.html
@@ -6820,7 +6820,7 @@ init.defaultBranch
<dd>
<p>
Allows overriding the default branch name e.g. when initializing
- a new repository or when cloning an empty repository.
+ a new repository.
</p>
</dd>
<dt class="hdlist1">
@@ -6994,6 +6994,21 @@ log.mailmap
</p>
</dd>
<dt class="hdlist1">
+lsrefs.unborn
+</dt>
+<dd>
+<p>
+ May be "advertise" (the default), "allow", or "ignore". If "advertise",
+ the server will respond to the client sending "unborn" (as described in
+ protocol-v2.txt) and will advertise support for this feature during the
+ protocol v2 capability advertisement. "allow" is the same as
+ "advertise" except that the server will not advertise support for this
+ feature; this is useful for load-balanced servers that cannot be
+ updated atomically (for example), since the administrator could
+ configure "allow", then after a delay, configure "advertise".
+</p>
+</dd>
+<dt class="hdlist1">
mailinfo.scissors
</dt>
<dd>
@@ -7064,8 +7079,9 @@ maintenance.strategy
<p>
<code>incremental</code>: This setting optimizes for performing small maintenance
activities that do not delete any data. This does not schedule the <code>gc</code>
- task, but runs the <code>prefetch</code> and <code>commit-graph</code> tasks hourly and the
- <code>loose-objects</code> and <code>incremental-repack</code> tasks daily.
+ task, but runs the <code>prefetch</code> and <code>commit-graph</code> tasks hourly, the
+ <code>loose-objects</code> and <code>incremental-repack</code> tasks daily, and the <code>pack-refs</code>
+ task weekly.
</p>
</li>
</ul></div>
@@ -7571,6 +7587,16 @@ mergetool.&lt;tool&gt;.cmd
</p>
</dd>
<dt class="hdlist1">
+mergetool.&lt;tool&gt;.hideResolved
+</dt>
+<dd>
+<p>
+ Allows the user to override the global <code>mergetool.hideResolved</code> value
+ for a specific tool. See <code>mergetool.hideResolved</code> for the full
+ description.
+</p>
+</dd>
+<dt class="hdlist1">
mergetool.&lt;tool&gt;.trustExitCode
</dt>
<dd>
@@ -7613,6 +7639,21 @@ mergetool.meld.useAutoMerge
</p>
</dd>
<dt class="hdlist1">
+mergetool.hideResolved
+</dt>
+<dd>
+<p>
+ During a merge Git will automatically resolve as many conflicts as
+ possible and write the <em>MERGED</em> file containing conflict markers around
+ any conflicts that it cannot resolve; <em>LOCAL</em> and <em>REMOTE</em> normally
+ represent the versions of the file from before Git&#8217;s conflict
+ resolution. This flag causes <em>LOCAL</em> and <em>REMOTE</em> to be overwriten so
+ that only the unresolved conflicts are presented to the merge tool. Can
+ be configured per-tool via the <code>mergetool.&lt;tool&gt;.hideResolved</code>
+ configuration variable. Defaults to <code>true</code>.
+</p>
+</dd>
+<dt class="hdlist1">
mergetool.keepBackup
</dt>
<dd>
diff --git a/git-maintenance.html b/git-maintenance.html
index 428672808..639b907bd 100644
--- a/git-maintenance.html
+++ b/git-maintenance.html
@@ -961,6 +961,17 @@ incremental-repack
into a single pack-file.
</p>
</dd>
+<dt class="hdlist1">
+pack-refs
+</dt>
+<dd>
+<p>
+ The <code>pack-refs</code> task collects the loose reference files and
+ collects them into a single file. This speeds up operations that
+ need to iterate across many references. See <a href="git-pack-refs.html">git-pack-refs(1)</a>
+ for more information.
+</p>
+</dd>
</dl></div>
</div>
</div>
@@ -1175,7 +1186,7 @@ custom tasks.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-01-25 15:29:19 PST
+ 2021-02-22 16:54:23 PST
</div>
</div>
</body>
diff --git a/git-maintenance.txt b/git-maintenance.txt
index 3b432171d..80ddd33ce 100644
--- a/git-maintenance.txt
+++ b/git-maintenance.txt
@@ -145,6 +145,12 @@ incremental-repack::
which is a special case that attempts to repack all pack-files
into a single pack-file.
+pack-refs::
+ The `pack-refs` task collects the loose reference files and
+ collects them into a single file. This speeds up operations that
+ need to iterate across many references. See linkgit:git-pack-refs[1]
+ for more information.
+
OPTIONS
-------
--auto::
diff --git a/git-mergetool--lib.html b/git-mergetool--lib.html
index b23438380..258a1aac3 100644
--- a/git-mergetool--lib.html
+++ b/git-mergetool--lib.html
@@ -799,6 +799,15 @@ get_merge_tool_path
</p>
</dd>
<dt class="hdlist1">
+initialize_merge_tool
+</dt>
+<dd>
+<p>
+ bring merge tool specific functions into scope so they can be used or
+ overridden.
+</p>
+</dd>
+<dt class="hdlist1">
run_merge_tool
</dt>
<dd>
@@ -823,7 +832,7 @@ run_merge_tool
<div id="footer">
<div id="footer-text">
Last updated
- 2020-03-10 08:03:13 PDT
+ 2021-02-22 16:54:23 PST
</div>
</div>
</body>
diff --git a/git-mergetool--lib.txt b/git-mergetool--lib.txt
index 4da9d2409..3e8f59ac0 100644
--- a/git-mergetool--lib.txt
+++ b/git-mergetool--lib.txt
@@ -38,6 +38,10 @@ get_merge_tool_cmd::
get_merge_tool_path::
returns the custom path for a merge tool.
+initialize_merge_tool::
+ bring merge tool specific functions into scope so they can be used or
+ overridden.
+
run_merge_tool::
launches a merge tool given the tool name and a true/false
flag to indicate whether a merge base is present.
diff --git a/git-range-diff.html b/git-range-diff.html
index 0d52b7093..b6232ce15 100644
--- a/git-range-diff.html
+++ b/git-range-diff.html
@@ -751,6 +751,7 @@ git-range-diff(1) Manual Page
<div class="verseblock">
<pre class="content"><em>git range-diff</em> [--color=[&lt;when&gt;]] [--no-color] [&lt;diff-options&gt;]
[--no-dual-color] [--creation-factor=&lt;factor&gt;]
+ [--left-only | --right-only]
( &lt;range1&gt; &lt;range2&gt; | &lt;rev1&gt;&#8230;&lt;rev2&gt; | &lt;base&gt; &lt;rev1&gt; &lt;rev2&gt; )</pre>
<div class="attribution">
</div></div>
@@ -769,6 +770,28 @@ patches' size. See ``Algorithm`` below for details.</p></div>
<div class="paragraph"><p>Finally, the list of matching commits is shown in the order of the
second commit range, with unmatched commits being inserted just after
all of their ancestors have been shown.</p></div>
+<div class="paragraph"><p>There are three ways to specify the commit ranges:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+<code>&lt;range1&gt; &lt;range2&gt;</code>: Either commit range can be of the form
+ <code>&lt;base&gt;..&lt;rev&gt;</code>, <code>&lt;rev&gt;^!</code> or <code>&lt;rev&gt;^-&lt;n&gt;</code>. See <code>SPECIFYING RANGES</code>
+ in <a href="gitrevisions.html">gitrevisions(7)</a> for more details.
+</p>
+</li>
+<li>
+<p>
+<code>&lt;rev1&gt;...&lt;rev2&gt;</code>. This is equivalent to
+ <code>&lt;rev2&gt;..&lt;rev1&gt; &lt;rev1&gt;..&lt;rev2&gt;</code>.
+</p>
+</li>
+<li>
+<p>
+<code>&lt;base&gt; &lt;rev1&gt; &lt;rev2&gt;</code>: This is equivalent to <code>&lt;base&gt;..&lt;rev1&gt;
+ &lt;base&gt;..&lt;rev2&gt;</code>.
+</p>
+</li>
+</ul></div>
</div>
</div>
<div class="sect1">
@@ -810,6 +833,24 @@ to revert to color all lines according to the outer diff markers
</p>
</dd>
<dt class="hdlist1">
+--left-only
+</dt>
+<dd>
+<p>
+ Suppress commits that are missing from the first specified range
+ (or the "left range" when using the <code>&lt;rev1&gt;...&lt;rev2&gt;</code> format).
+</p>
+</dd>
+<dt class="hdlist1">
+--right-only
+</dt>
+<dd>
+<p>
+ Suppress commits that are missing from the second specified range
+ (or the "right range" when using the <code>&lt;rev1&gt;...&lt;rev2&gt;</code> format).
+</p>
+</dd>
+<dt class="hdlist1">
--[no-]notes[=&lt;ref&gt;]
</dt>
<dd>
@@ -1041,7 +1082,7 @@ found in this case will look like this:</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2020-03-10 08:03:13 PDT
+ 2021-02-22 16:54:23 PST
</div>
</div>
</body>
diff --git a/git-range-diff.txt b/git-range-diff.txt
index 9701c1e5f..fe350d7f4 100644
--- a/git-range-diff.txt
+++ b/git-range-diff.txt
@@ -10,6 +10,7 @@ SYNOPSIS
[verse]
'git range-diff' [--color=[<when>]] [--no-color] [<diff-options>]
[--no-dual-color] [--creation-factor=<factor>]
+ [--left-only | --right-only]
( <range1> <range2> | <rev1>...<rev2> | <base> <rev1> <rev2> )
DESCRIPTION
@@ -28,6 +29,17 @@ Finally, the list of matching commits is shown in the order of the
second commit range, with unmatched commits being inserted just after
all of their ancestors have been shown.
+There are three ways to specify the commit ranges:
+
+- `<range1> <range2>`: Either commit range can be of the form
+ `<base>..<rev>`, `<rev>^!` or `<rev>^-<n>`. See `SPECIFYING RANGES`
+ in linkgit:gitrevisions[7] for more details.
+
+- `<rev1>...<rev2>`. This is equivalent to
+ `<rev2>..<rev1> <rev1>..<rev2>`.
+
+- `<base> <rev1> <rev2>`: This is equivalent to `<base>..<rev1>
+ <base>..<rev2>`.
OPTIONS
-------
@@ -57,6 +69,14 @@ to revert to color all lines according to the outer diff markers
See the ``Algorithm`` section below for an explanation why this is
needed.
+--left-only::
+ Suppress commits that are missing from the first specified range
+ (or the "left range" when using the `<rev1>...<rev2>` format).
+
+--right-only::
+ Suppress commits that are missing from the second specified range
+ (or the "right range" when using the `<rev1>...<rev2>` format).
+
--[no-]notes[=<ref>]::
This flag is passed to the `git log` program
(see linkgit:git-log[1]) that generates the patches.
diff --git a/git-shortlog.html b/git-shortlog.html
index 89a5e6710..e46788ebc 100644
--- a/git-shortlog.html
+++ b/git-shortlog.html
@@ -1940,6 +1940,9 @@ commits are marked as TREESAME (subject to be simplified away).</p></div>
<h2 id="_mapping_authors">MAPPING AUTHORS</h2>
<div class="sectionbody">
<div class="paragraph"><p>See <a href="gitmailmap.html">gitmailmap(5)</a>.</p></div>
+<div class="paragraph"><p>Note that if <code>git shortlog</code> is run outside of a repository (to process
+log contents on standard input), it will look for a <code>.mailmap</code> file in
+the current directory.</p></div>
</div>
</div>
<div class="sect1">
@@ -1953,7 +1956,7 @@ commits are marked as TREESAME (subject to be simplified away).</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-01-25 15:29:19 PST
+ 2021-02-22 16:54:23 PST
</div>
</div>
</body>
diff --git a/git-shortlog.txt b/git-shortlog.txt
index c16cc3b60..c9c7f3065 100644
--- a/git-shortlog.txt
+++ b/git-shortlog.txt
@@ -113,6 +113,10 @@ MAPPING AUTHORS
See linkgit:gitmailmap[5].
+Note that if `git shortlog` is run outside of a repository (to process
+log contents on standard input), it will look for a `.mailmap` file in
+the current directory.
+
GIT
---
Part of the linkgit:git[1] suite
diff --git a/git-stash.html b/git-stash.html
index 444a667b8..148879c44 100644
--- a/git-stash.html
+++ b/git-stash.html
@@ -749,8 +749,8 @@ git-stash(1) Manual Page
<h2 id="_synopsis">SYNOPSIS</h2>
<div class="sectionbody">
<div class="verseblock">
-<pre class="content"><em>git stash</em> list [&lt;options&gt;]
-<em>git stash</em> show [&lt;options&gt;] [&lt;stash&gt;]
+<pre class="content"><em>git stash</em> list [&lt;log-options&gt;]
+<em>git stash</em> show [&lt;diff-options&gt;] [&lt;stash&gt;]
<em>git stash</em> drop [-q|--quiet] [&lt;stash&gt;]
<em>git stash</em> ( pop | apply ) [--index] [-q|--quiet] [&lt;stash&gt;]
<em>git stash</em> branch &lt;branchname&gt; [&lt;stash&gt;]
@@ -819,7 +819,7 @@ save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q
</p>
</dd>
<dt class="hdlist1">
-list [&lt;options&gt;]
+list [&lt;log-options&gt;]
</dt>
<dd>
<p>
@@ -838,7 +838,7 @@ stash@{1}: On master: 9cc0589... Add git-stash</code></pre>
command to control what is shown and how. See <a href="git-log.html">git-log(1)</a>.</p></div>
</dd>
<dt class="hdlist1">
-show [&lt;options&gt;] [&lt;stash&gt;]
+show [&lt;diff-options&gt;] [&lt;stash&gt;]
</dt>
<dd>
<p>
@@ -1231,7 +1231,7 @@ xargs git log --merges --no-walk --grep=WIP</code></pre>
<div id="footer">
<div id="footer-text">
Last updated
- 2020-03-10 08:03:13 PDT
+ 2021-02-22 16:54:23 PST
</div>
</div>
</body>
diff --git a/git-stash.txt b/git-stash.txt
index 31f1beb65..f1197d641 100644
--- a/git-stash.txt
+++ b/git-stash.txt
@@ -8,8 +8,8 @@ git-stash - Stash the changes in a dirty working directory away
SYNOPSIS
--------
[verse]
-'git stash' list [<options>]
-'git stash' show [<options>] [<stash>]
+'git stash' list [<log-options>]
+'git stash' show [<diff-options>] [<stash>]
'git stash' drop [-q|--quiet] [<stash>]
'git stash' ( pop | apply ) [--index] [-q|--quiet] [<stash>]
'git stash' branch <branchname> [<stash>]
@@ -67,7 +67,7 @@ save [-p|--patch] [-k|--[no-]keep-index] [-u|--include-untracked] [-a|--all] [-q
Instead, all non-option arguments are concatenated to form the stash
message.
-list [<options>]::
+list [<log-options>]::
List the stash entries that you currently have. Each 'stash entry' is
listed with its name (e.g. `stash@{0}` is the latest entry, `stash@{1}` is
@@ -83,7 +83,7 @@ stash@{1}: On master: 9cc0589... Add git-stash
The command takes options applicable to the 'git log'
command to control what is shown and how. See linkgit:git-log[1].
-show [<options>] [<stash>]::
+show [<diff-options>] [<stash>]::
Show the changes recorded in the stash entry as a diff between the
stashed contents and the commit back when the stash entry was first
diff --git a/howto/keep-canonical-history-correct.html b/howto/keep-canonical-history-correct.html
index 5ba6c53c4..667a7b22f 100644
--- a/howto/keep-canonical-history-correct.html
+++ b/howto/keep-canonical-history-correct.html
@@ -938,7 +938,7 @@ tip of your <em>master</em> again and redo the two merges:</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:47 PST
+ 2021-02-22 16:55:16 PST
</div>
</div>
</body>
diff --git a/howto/maintain-git.html b/howto/maintain-git.html
index f1b6fb827..12aa1b503 100644
--- a/howto/maintain-git.html
+++ b/howto/maintain-git.html
@@ -1469,7 +1469,7 @@ $ git update-ref -d $mf/ai/topic</code></pre>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:47 PST
+ 2021-02-22 16:55:16 PST
</div>
</div>
</body>
diff --git a/howto/new-command.html b/howto/new-command.html
index 92ebbe119..f22e860db 100644
--- a/howto/new-command.html
+++ b/howto/new-command.html
@@ -863,7 +863,7 @@ letter [PATCH 0/n].
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:44 PST
+ 2021-02-22 16:55:13 PST
</div>
</div>
</body>
diff --git a/howto/rebase-from-internal-branch.html b/howto/rebase-from-internal-branch.html
index 7d34a28fe..216b67d3d 100644
--- a/howto/rebase-from-internal-branch.html
+++ b/howto/rebase-from-internal-branch.html
@@ -895,7 +895,7 @@ the #1' commit.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:47 PST
+ 2021-02-22 16:55:16 PST
</div>
</div>
</body>
diff --git a/howto/rebuild-from-update-hook.html b/howto/rebuild-from-update-hook.html
index 7d29851d8..572e3966c 100644
--- a/howto/rebuild-from-update-hook.html
+++ b/howto/rebuild-from-update-hook.html
@@ -847,7 +847,7 @@ This is still crude and does not protect against simultaneous
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:47 PST
+ 2021-02-22 16:55:16 PST
</div>
</div>
</body>
diff --git a/howto/recover-corrupted-blob-object.html b/howto/recover-corrupted-blob-object.html
index a6440b6c1..72cdd156f 100644
--- a/howto/recover-corrupted-blob-object.html
+++ b/howto/recover-corrupted-blob-object.html
@@ -880,7 +880,7 @@ thing.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:46 PST
+ 2021-02-22 16:55:16 PST
</div>
</div>
</body>
diff --git a/howto/recover-corrupted-object-harder.html b/howto/recover-corrupted-object-harder.html
index 8894a12bb..33c935f7f 100644
--- a/howto/recover-corrupted-object-harder.html
+++ b/howto/recover-corrupted-object-harder.html
@@ -1189,7 +1189,7 @@ int main(int argc, char **argv)
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:47 PST
+ 2021-02-22 16:55:16 PST
</div>
</div>
</body>
diff --git a/howto/revert-a-faulty-merge.html b/howto/revert-a-faulty-merge.html
index b5058f70c..0d892f88b 100644
--- a/howto/revert-a-faulty-merge.html
+++ b/howto/revert-a-faulty-merge.html
@@ -1025,7 +1025,7 @@ P---o---o---M---x---x---W---x---M2
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:46 PST
+ 2021-02-22 16:55:15 PST
</div>
</div>
</body>
diff --git a/howto/revert-branch-rebase.html b/howto/revert-branch-rebase.html
index caa16066f..1b1508f71 100644
--- a/howto/revert-branch-rebase.html
+++ b/howto/revert-branch-rebase.html
@@ -907,7 +907,7 @@ Committed merge 7fb9b7262a1d1e0a47bbfdcbbcf50ce0635d3f8f
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:44 PST
+ 2021-02-22 16:55:13 PST
</div>
</div>
</body>
diff --git a/howto/separating-topic-branches.html b/howto/separating-topic-branches.html
index c68ca2d36..ad05f2ad0 100644
--- a/howto/separating-topic-branches.html
+++ b/howto/separating-topic-branches.html
@@ -841,7 +841,7 @@ o---o"master"</code></pre>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:46 PST
+ 2021-02-22 16:55:15 PST
</div>
</div>
</body>
diff --git a/howto/setup-git-server-over-http.html b/howto/setup-git-server-over-http.html
index 0be7e8b39..fae795771 100644
--- a/howto/setup-git-server-over-http.html
+++ b/howto/setup-git-server-over-http.html
@@ -1071,7 +1071,7 @@ help diagnosing the problem, but removes security checks.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:45 PST
+ 2021-02-22 16:55:14 PST
</div>
</div>
</body>
diff --git a/howto/update-hook-example.html b/howto/update-hook-example.html
index 078cb8875..975b5b6ab 100644
--- a/howto/update-hook-example.html
+++ b/howto/update-hook-example.html
@@ -930,7 +930,7 @@ that JC can make non-fast-forward pushes on it.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:45 PST
+ 2021-02-22 16:55:14 PST
</div>
</div>
</body>
diff --git a/howto/use-git-daemon.html b/howto/use-git-daemon.html
index 0ed84baa9..8a437ef2f 100644
--- a/howto/use-git-daemon.html
+++ b/howto/use-git-daemon.html
@@ -791,7 +791,7 @@ a good practice to put the paths after a "--" separator.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:45 PST
+ 2021-02-22 16:55:14 PST
</div>
</div>
</body>
diff --git a/howto/using-merge-subtree.html b/howto/using-merge-subtree.html
index 4260ec68f..ab2e8add6 100644
--- a/howto/using-merge-subtree.html
+++ b/howto/using-merge-subtree.html
@@ -848,7 +848,7 @@ Please note that if the other project merges from you, then it will
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:44 PST
+ 2021-02-22 16:55:13 PST
</div>
</div>
</body>
diff --git a/howto/using-signed-tag-in-pull-request.html b/howto/using-signed-tag-in-pull-request.html
index acc00d585..ab9be010e 100644
--- a/howto/using-signed-tag-in-pull-request.html
+++ b/howto/using-signed-tag-in-pull-request.html
@@ -952,7 +952,7 @@ as part of the merge commit.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2021-02-12 14:44:44 PST
+ 2021-02-22 16:55:14 PST
</div>
</div>
</body>
diff --git a/technical/commit-graph-format.txt b/technical/commit-graph-format.txt
index b3b58880b..b6658eff1 100644
--- a/technical/commit-graph-format.txt
+++ b/technical/commit-graph-format.txt
@@ -4,11 +4,7 @@ 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 generation number of the commit.
- The root tree OID.
@@ -86,13 +82,33 @@ CHUNK DATA:
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 Extra Edge List chunk.
- * The next 8 bytes store the generation number of the commit and
+ * The next 8 bytes store the topological level (generation number v1)
+ 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.
+ Generation Data (ID: {'G', 'D', 'A', 'T' }) (N * 4 bytes) [Optional]
+ * This list of 4-byte values store corrected commit date offsets for the
+ commits, arranged in the same order as commit data chunk.
+ * If the corrected commit date offset cannot be stored within 31 bits,
+ the value has its most-significant bit on and the other bits store
+ the position of corrected commit date into the Generation Data Overflow
+ chunk.
+ * Generation Data chunk is present only when commit-graph file is written
+ by compatible versions of Git and in case of split commit-graph chains,
+ the topmost layer also has Generation Data chunk.
+
+ Generation Data Overflow (ID: {'G', 'D', 'O', 'V' }) [Optional]
+ * This list of 8-byte values stores the corrected commit date offsets
+ for commits with corrected commit date offsets that cannot be
+ stored within 31 bits.
+ * Generation Data Overflow chunk is present only when Generation Data
+ chunk is present and atleast one corrected commit date offset cannot
+ be stored within 31 bits.
+
Extra 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
diff --git a/technical/commit-graph.txt b/technical/commit-graph.txt
index f14a7659a..f05e7bda1 100644
--- a/technical/commit-graph.txt
+++ b/technical/commit-graph.txt
@@ -38,14 +38,31 @@ A consumer may load the following info for a commit from the graph:
Values 1-4 satisfy the requirements of parse_commit_gently().
-Define the "generation number" of a commit recursively as follows:
+There are two definitions of generation number:
+1. Corrected committer dates (generation number v2)
+2. Topological levels (generation nummber v1)
- * A commit with no parents (a root commit) has generation number one.
+Define "corrected committer date" of a commit recursively as follows:
- * A commit with at least one parent has generation number one more than
- the largest generation number among its parents.
+ * A commit with no parents (a root commit) has corrected committer date
+ equal to its committer date.
-Equivalently, the generation number of a commit A is one more than the
+ * A commit with at least one parent has corrected committer date equal to
+ the maximum of its commiter date and one more than the largest corrected
+ committer date among its parents.
+
+ * As a special case, a root commit with timestamp zero has corrected commit
+ date of 1, to be able to distinguish it from GENERATION_NUMBER_ZERO
+ (that is, an uncomputed corrected commit date).
+
+Define the "topological level" of a commit recursively as follows:
+
+ * A commit with no parents (a root commit) has topological level of one.
+
+ * A commit with at least one parent has topological level one more than
+ the largest topological level among its parents.
+
+Equivalently, the topological level 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:
@@ -60,6 +77,9 @@ is easier to use for computation and observing the following property:
generation numbers, then we always expand the boundary commit with highest
generation number and can easily detect the stopping condition.
+The property applies to both versions of generation number, that is both
+corrected committer dates and topological levels.
+
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:
@@ -67,7 +87,9 @@ 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
+In absence of corrected commit dates (for example, old versions of Git or
+mixed generation graph chains),
+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").
@@ -77,7 +99,7 @@ in the commit graph. We can treat these commits as having "infinite"
generation number and walk until reaching commits with known generation
number.
-We use the macro GENERATION_NUMBER_INFINITY = 0xFFFFFFFF to mark commits not
+We use the macro GENERATION_NUMBER_INFINITY to mark commits not
in the commit-graph file. If a commit-graph file was written by a version
of Git that did not compute generation numbers, then those commits will
have generation number represented by the macro GENERATION_NUMBER_ZERO = 0.
@@ -93,12 +115,12 @@ fully-computed generation numbers. Using strict inequality may result in
walking a few extra commits, but the simplicity in dealing with commits
with generation number *_INFINITY or *_ZERO is valuable.
-We use the macro GENERATION_NUMBER_MAX = 0x3FFFFFFF to for commits whose
-generation numbers are computed to be at least this value. We limit at
-this value since it is the largest value that can be stored in the
-commit-graph file using the 30 bits available to generation numbers. This
-presents another case where a commit can have generation number equal to
-that of a parent.
+We use the macro GENERATION_NUMBER_V1_MAX = 0x3FFFFFFF for commits whose
+topological levels (generation number v1) are computed to be at least
+this value. We limit at this value since it is the largest value that
+can be stored in the commit-graph file using the 30 bits available
+to topological levels. This presents another case where a commit can
+have generation number equal to that of a parent.
Design Details
--------------
@@ -267,6 +289,35 @@ The merge strategy values (2 for the size multiple, 64,000 for the maximum
number of commits) could be extracted into config settings for full
flexibility.
+## Handling Mixed Generation Number Chains
+
+With the introduction of generation number v2 and generation data chunk, the
+following scenario is possible:
+
+1. "New" Git writes a commit-graph with the corrected commit dates.
+2. "Old" Git writes a split commit-graph on top without corrected commit dates.
+
+A naive approach of using the newest available generation number from
+each layer would lead to violated expectations: the lower layer would
+use corrected commit dates which are much larger than the topological
+levels of the higher layer. For this reason, Git inspects the topmost
+layer to see if the layer is missing corrected commit dates. In such a case
+Git only uses topological level for generation numbers.
+
+When writing a new layer in split commit-graph, we write corrected commit
+dates if the topmost layer has corrected commit dates written. This
+guarantees that if a layer has corrected commit dates, all lower layers
+must have corrected commit dates as well.
+
+When merging layers, we do not consider whether the merged layers had corrected
+commit dates. Instead, the new layer will have corrected commit dates if the
+layer below the new layer has corrected commit dates.
+
+While writing or merging layers, if the new layer is the only layer, it will
+have corrected commit dates when written by compatible versions of Git. Thus,
+rewriting split commit-graph as a single file (`--split=replace`) creates a
+single layer with corrected commit dates.
+
## Deleting graph-{hash} files
After a new tip file is written, some `graph-{hash}` files may no longer
diff --git a/technical/hash-function-transition.html b/technical/hash-function-transition.html
index a07c127f7..0c3904b18 100644
--- a/technical/hash-function-transition.html
+++ b/technical/hash-function-transition.html
@@ -787,14 +787,8 @@ researchers. On 23 February 2017 the SHAttered attack
(<a href="https://shattered.io">https://shattered.io</a>) demonstrated a practical SHA-1 hash collision.</p></div>
<div class="paragraph"><p>Git v2.13.0 and later subsequently moved to a hardened SHA-1
implementation by default, which isn&#8217;t vulnerable to the SHAttered
-attack.</p></div>
-<div class="paragraph"><p>Thus Git has in effect already migrated to a new hash that isn&#8217;t SHA-1
-and doesn&#8217;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.</p></div>
-<div class="paragraph"><p>Regardless, it&#8217;s considered prudent to move past any variant of SHA-1
+attack, but SHA-1 is still weak.</p></div>
+<div class="paragraph"><p>Thus it&#8217;s considered prudent to move past any variant of SHA-1
to a new hash. There&#8217;s no guarantee that future attacks on SHA-1 won&#8217;t
be published in the future, and those attacks may not have viable
mitigations.</p></div>
@@ -809,6 +803,50 @@ that are believed to be cryptographically secure.</p></div>
</div>
</div>
<div class="sect1">
+<h2 id="_choice_of_hash">Choice of Hash</h2>
+<div class="sectionbody">
+<div class="paragraph"><p>The hash to replace the hardened SHA-1 should be stronger than SHA-1
+was: we would like it to be trustworthy and useful in practice for at
+least 10 years.</p></div>
+<div class="paragraph"><p>Some other relevant properties:</p></div>
+<div class="olist arabic"><ol class="arabic">
+<li>
+<p>
+A 256-bit hash (long enough to match common security practice; not
+ excessively long to hurt performance and disk usage).
+</p>
+</li>
+<li>
+<p>
+High quality implementations should be widely available (e.g., in
+ OpenSSL and Apple CommonCrypto).
+</p>
+</li>
+<li>
+<p>
+The hash function&#8217;s properties should match Git&#8217;s needs (e.g. Git
+ requires collision and 2nd preimage resistance and does not require
+ length extension resistance).
+</p>
+</li>
+<li>
+<p>
+As a tiebreaker, the hash should be fast to compute (fortunately
+ many contenders are faster than SHA-1).
+</p>
+</li>
+</ol></div>
+<div class="paragraph"><p>There were several contenders for a successor hash to SHA-1, including
+SHA-256, SHA-512/256, SHA-256x16, K12, and BLAKE2bp-256.</p></div>
+<div class="paragraph"><p>In late 2018 the project picked SHA-256 as its successor hash.</p></div>
+<div class="paragraph"><p>See 0ed8d8da374 (doc hash-function-transition: pick SHA-256 as
+NewHash, 2018-08-04) and numerous mailing list threads at the time,
+particularly the one starting at
+<a href="https://lore.kernel.org/git/20180609224913.GC38834@genre.crustytoothpaste.net/">https://lore.kernel.org/git/20180609224913.GC38834@genre.crustytoothpaste.net/</a>
+for more information.</p></div>
+</div>
+</div>
+<div class="sect1">
<h2 id="_goals">Goals</h2>
<div class="sectionbody">
<div class="olist arabic"><ol class="arabic">
@@ -924,7 +962,7 @@ Skip fetching some submodules of a project into a SHA-256
<div class="sectionbody">
<div class="paragraph"><p>We introduce a new repository format extension. Repositories with this
extension enabled use SHA-256 instead of SHA-1 to name their objects.
-This affects both object names and object content --- both the names
+This affects both object names and object content&#8201;&#8212;&#8201;both the names
of objects and all references to other objects within an object are
switched to the new hash function.</p></div>
<div class="paragraph"><p>SHA-256 repositories cannot be read by older versions of Git.</p></div>
@@ -934,14 +972,14 @@ locally and can be verified using "git fsck". Object lookups use this
mapping to allow naming objects using either their SHA-1 and SHA-256 names
interchangeably.</p></div>
<div class="paragraph"><p>"git cat-file" and "git hash-object" gain options to display an object
-in its sha1 form and write an object given its sha1 form. This
+in its SHA-1 form and write an object given its SHA-1 form. This
requires all objects referenced by that object to be present in the
object database so that they can be named using the appropriate name
(using the bidirectional hash mapping).</p></div>
<div class="paragraph"><p>Fetches from a SHA-1 based server convert the fetched objects into
SHA-256 form and record the mapping in the bidirectional mapping table
(see below for details). Pushes to a SHA-1 based server convert the
-objects being pushed into sha1 form so the server does not have to be
+objects being pushed into SHA-1 form so the server does not have to be
aware of the hash function the client is using.</p></div>
</div>
</div>
@@ -981,34 +1019,34 @@ repository extensions.</p></div>
</div>
<div class="sect2">
<h3 id="_object_names">Object names</h3>
-<div class="paragraph"><p>Objects can be named by their 40 hexadecimal digit sha1-name or 64
-hexadecimal digit sha256-name, plus names derived from those (see
+<div class="paragraph"><p>Objects can be named by their 40 hexadecimal digit SHA-1 name or 64
+hexadecimal digit SHA-256 name, plus names derived from those (see
gitrevisions(7)).</p></div>
-<div class="paragraph"><p>The sha1-name of an object is the SHA-1 of the concatenation of its
-type, length, a nul byte, and the object&#8217;s sha1-content. This is the
+<div class="paragraph"><p>The SHA-1 name of an object is the SHA-1 of the concatenation of its
+type, length, a nul byte, and the object&#8217;s SHA-1 content. This is the
traditional &lt;sha1&gt; used in Git to name objects.</p></div>
-<div class="paragraph"><p>The sha256-name of an object is the SHA-256 of the concatenation of its
-type, length, a nul byte, and the object&#8217;s sha256-content.</p></div>
+<div class="paragraph"><p>The SHA-256 name of an object is the SHA-256 of the concatenation of its
+type, length, a nul byte, and the object&#8217;s SHA-256 content.</p></div>
</div>
<div class="sect2">
<h3 id="_object_format">Object format</h3>
<div class="paragraph"><p>The content as a byte sequence of a tag, commit, or tree object named
-by sha1 and sha256 differ because an object named by sha256-name refers to
-other objects by their sha256-names and an object named by sha1-name
-refers to other objects by their sha1-names.</p></div>
-<div class="paragraph"><p>The sha256-content of an object is the same as its sha1-content, except
-that objects referenced by the object are named using their sha256-names
-instead of sha1-names. Because a blob object does not refer to any
-other object, its sha1-content and sha256-content are the same.</p></div>
-<div class="paragraph"><p>The format allows round-trip conversion between sha256-content and
-sha1-content.</p></div>
+by SHA-1 and SHA-256 differ because an object named by SHA-256 name refers to
+other objects by their SHA-256 names and an object named by SHA-1 name
+refers to other objects by their SHA-1 names.</p></div>
+<div class="paragraph"><p>The SHA-256 content of an object is the same as its SHA-1 content, except
+that objects referenced by the object are named using their SHA-256 names
+instead of SHA-1 names. Because a blob object does not refer to any
+other object, its SHA-1 content and SHA-256 content are the same.</p></div>
+<div class="paragraph"><p>The format allows round-trip conversion between SHA-256 content and
+SHA-1 content.</p></div>
</div>
<div class="sect2">
<h3 id="_object_storage">Object storage</h3>
<div class="paragraph"><p>Loose objects use zlib compression and packed objects use the packed
format described in Documentation/technical/pack-format.txt, just like
-today. The content that is compressed and stored uses sha256-content
-instead of sha1-content.</p></div>
+today. The content that is compressed and stored uses SHA-256 content
+instead of SHA-1 content.</p></div>
</div>
<div class="sect2">
<h3 id="_pack_index">Pack index</h3>
@@ -1020,7 +1058,7 @@ network byte order):</p></div>
<p>
A header appears at the beginning and consists of the following:
</p>
-</li>
+<div class="ulist"><ul>
<li>
<p>
The 4-byte pack index signature: <em>\377t0c</em>
@@ -1051,7 +1089,7 @@ The 4-byte pack index signature: <em>\377t0c</em>
<p>
For each object format:
</p>
-</li>
+<div class="ulist"><ul>
<li>
<p>
4-byte format identifier (e.g., <em>sha1</em> for SHA-1)
@@ -1070,6 +1108,8 @@ For each object format:
are stored in this index file, as an offset from the beginning.
</p>
</li>
+</ul></div>
+</li>
<li>
<p>
4-byte offset to the trailer from the beginning of this file.
@@ -1084,6 +1124,8 @@ Zero or more additional key/value pairs (4-byte key, 4-byte
unrecognized keys.
</p>
</li>
+</ul></div>
+</li>
<li>
<p>
Zero or more NUL bytes. This can optionally be used to improve the
@@ -1094,7 +1136,7 @@ Zero or more NUL bytes. This can optionally be used to improve the
<p>
Tables for the first object format:
</p>
-</li>
+<div class="ulist"><ul>
<li>
<p>
A sorted table of shortened object names. These are prefixes of
@@ -1117,12 +1159,9 @@ A table of 4-byte values mapping object name order to pack order.
For an object in the table of sorted shortened object names, the
value at the corresponding index in this table is the index in the
previous table for that same object.
+ This can be used to look up the object in reachability bitmaps or
+ to look up its name in another object format.
</p>
-<div class="literalblock">
-<div class="content">
-<pre><code>This can be used to look up the object in reachability bitmaps or
-to look up its name in another object format.</code></pre>
-</div></div>
</li>
<li>
<p>
@@ -1150,6 +1189,8 @@ A table of 8-byte offset entries (empty for pack files less than
this table.
</p>
</li>
+</ul></div>
+</li>
<li>
<p>
Zero or more NUL bytes.
@@ -1170,7 +1211,7 @@ Zero or more NUL bytes.
<p>
The trailer consists of the following:
</p>
-</li>
+<div class="ulist"><ul>
<li>
<p>
A copy of the 20-byte SHA-256 checksum at the end of the
@@ -1183,6 +1224,8 @@ A copy of the 20-byte SHA-256 checksum at the end of the
</p>
</li>
</ul></div>
+</li>
+</ul></div>
</div>
<div class="sect2">
<h3 id="_loose_object_index">Loose object index</h3>
@@ -1252,32 +1295,32 @@ Rename to replace loose-object-idx, releasing the lock.
</div>
<div class="sect2">
<h3 id="_translation_table">Translation table</h3>
-<div class="paragraph"><p>The index files support a bidirectional mapping between sha1-names
-and sha256-names. The lookup proceeds similarly to ordinary object
-lookups. For example, to convert a sha1-name to a sha256-name:</p></div>
+<div class="paragraph"><p>The index files support a bidirectional mapping between SHA-1 names
+and SHA-256 names. The lookup proceeds similarly to ordinary object
+lookups. For example, to convert a SHA-1 name to a SHA-256 name:</p></div>
<div class="olist arabic"><ol class="arabic">
<li>
<p>
Look for the object in idx files. If a match is present in the
- idx&#8217;s sorted list of truncated sha1-names, then:
+ idx&#8217;s sorted list of truncated SHA-1 names, then:
</p>
<div class="olist loweralpha"><ol class="loweralpha">
<li>
<p>
-Read the corresponding entry in the sha1-name order to pack
+Read the corresponding entry in the SHA-1 name order to pack
name order mapping.
</p>
</li>
<li>
<p>
-Read the corresponding entry in the full sha1-name table to
+Read the corresponding entry in the full SHA-1 name table to
verify we found the right object. If it is, then
</p>
</li>
<li>
<p>
-Read the corresponding entry in the full sha256-name table.
- That is the object&#8217;s sha256-name.
+Read the corresponding entry in the full SHA-256 name table.
+ That is the object&#8217;s SHA-256 name.
</p>
</li>
</ol></div>
@@ -1299,9 +1342,9 @@ the new objects to the corresponding index, this mapping is possible
for all objects in the object store.</p></div>
</div>
<div class="sect2">
-<h3 id="_reading_an_object_8217_s_sha1_content">Reading an object&#8217;s sha1-content</h3>
-<div class="paragraph"><p>The sha1-content of an object can be read by converting all sha256-names
-its sha256-content references to sha1-names using the translation table.</p></div>
+<h3 id="_reading_an_object_8217_s_sha_1_content">Reading an object&#8217;s SHA-1 content</h3>
+<div class="paragraph"><p>The SHA-1 content of an object can be read by converting all SHA-256 names
+of its SHA-256 content references to SHA-1 names using the translation table.</p></div>
</div>
<div class="sect2">
<h3 id="_fetch">Fetch</h3>
@@ -1323,7 +1366,7 @@ the following steps:</p></div>
index-pack: inflate each object in the packfile and compute its
SHA-1. Objects can contain deltas in OBJ_REF_DELTA format against
objects the client has locally. These objects can be looked up
- using the translation table and their sha1-content read as
+ using the translation table and their SHA-1 content read as
described above to resolve the deltas.
</p>
</li>
@@ -1340,16 +1383,16 @@ topological sort: starting at the "want"s from the negotiation
</li>
<li>
<p>
-convert to sha256: open a new (sha256) packfile. Read the topologically
+convert to SHA-256: open a new SHA-256 packfile. Read the topologically
sorted list just generated. For each object, inflate its
- sha1-content, convert to sha256-content, and write it to the sha256
- pack. Record the new sha1&lt;&#8594;sha256 mapping entry for use in the idx.
+ SHA-1 content, convert to SHA-256 content, and write it to the SHA-256
+ pack. Record the new SHA-1&#8592;&#8594;SHA-256 mapping entry for use in the idx.
</p>
</li>
<li>
<p>
sort: reorder entries in the new pack to match the order of objects
- in the pack the server generated and include blobs. Write a sha256 idx
+ in the pack the server generated and include blobs. Write a SHA-256 idx
file
</p>
</li>
@@ -1377,22 +1420,36 @@ experimenting to get this to perform well.</p></div>
<div class="sect2">
<h3 id="_push">Push</h3>
<div class="paragraph"><p>Push is simpler than fetch because the objects referenced by the
-pushed objects are already in the translation table. The sha1-content
+pushed objects are already in the translation table. The SHA-1 content
of each object being pushed can be read as described in the "Reading
-an object&#8217;s sha1-content" section to generate the pack written by git
+an object&#8217;s SHA-1 content" section to generate the pack written by git
send-pack.</p></div>
</div>
<div class="sect2">
<h3 id="_signed_commits">Signed Commits</h3>
<div class="paragraph"><p>We add a new field "gpgsig-sha256" to the commit object format to allow
signing commits without relying on SHA-1. It is similar to the
-existing "gpgsig" field. Its signed payload is the sha256-content of the
+existing "gpgsig" field. Its signed payload is the SHA-256 content of the
commit object with any "gpgsig" and "gpgsig-sha256" fields removed.</p></div>
-<div class="paragraph"><p>This means commits can be signed
-1. using SHA-1 only, as in existing signed commit objects
-2. using both SHA-1 and SHA-256, by using both gpgsig-sha256 and gpgsig
+<div class="paragraph"><p>This means commits can be signed</p></div>
+<div class="olist arabic"><ol class="arabic">
+<li>
+<p>
+using SHA-1 only, as in existing signed commit objects
+</p>
+</li>
+<li>
+<p>
+using both SHA-1 and SHA-256, by using both gpgsig-sha256 and gpgsig
fields.
-3. using only SHA-256, by only using the gpgsig-sha256 field.</p></div>
+</p>
+</li>
+<li>
+<p>
+using only SHA-256, by only using the gpgsig-sha256 field.
+</p>
+</li>
+</ol></div>
<div class="paragraph"><p>Old versions of "git verify-commit" can verify the gpgsig signature in
cases (1) and (2) without modifications and view case (3) as an
ordinary unsigned commit.</p></div>
@@ -1401,20 +1458,34 @@ ordinary unsigned commit.</p></div>
<h3 id="_signed_tags">Signed Tags</h3>
<div class="paragraph"><p>We add a new field "gpgsig-sha256" to the tag object format to allow
signing tags without relying on SHA-1. Its signed payload is the
-sha256-content of the tag with its gpgsig-sha256 field and "-----BEGIN PGP
+SHA-256 content of the tag with its gpgsig-sha256 field and "-----BEGIN PGP
SIGNATURE-----" delimited in-body signature removed.</p></div>
-<div class="paragraph"><p>This means tags can be signed
-1. using SHA-1 only, as in existing signed tag objects
-2. using both SHA-1 and SHA-256, by using gpgsig-sha256 and an in-body
+<div class="paragraph"><p>This means tags can be signed</p></div>
+<div class="olist arabic"><ol class="arabic">
+<li>
+<p>
+using SHA-1 only, as in existing signed tag objects
+</p>
+</li>
+<li>
+<p>
+using both SHA-1 and SHA-256, by using gpgsig-sha256 and an in-body
signature.
-3. using only SHA-256, by only using the gpgsig-sha256 field.</p></div>
+</p>
+</li>
+<li>
+<p>
+using only SHA-256, by only using the gpgsig-sha256 field.
+</p>
+</li>
+</ol></div>
</div>
<div class="sect2">
<h3 id="_mergetag_embedding">Mergetag embedding</h3>
-<div class="paragraph"><p>The mergetag field in the sha1-content of a commit contains the
-sha1-content of a tag that was merged by that commit.</p></div>
-<div class="paragraph"><p>The mergetag field in the sha256-content of the same commit contains the
-sha256-content of the same tag.</p></div>
+<div class="paragraph"><p>The mergetag field in the SHA-1 content of a commit contains the
+SHA-1 content of a tag that was merged by that commit.</p></div>
+<div class="paragraph"><p>The mergetag field in the SHA-256 content of the same commit contains the
+SHA-256 content of the same tag.</p></div>
</div>
<div class="sect2">
<h3 id="_submodules">Submodules</h3>
@@ -1505,7 +1576,7 @@ make appropriate choices about which packs to coalesce.</p></div>
<div class="sectionbody">
<div class="sect2">
<h3 id="_invalid_objects">Invalid objects</h3>
-<div class="paragraph"><p>The conversion from sha1-content to sha256-content retains any
+<div class="paragraph"><p>The conversion from SHA-1 content to SHA-256 content retains any
brokenness in the original object (e.g., tree entry modes encoded with
leading 0, tree objects whose paths are not sorted correctly, and
commit objects without an author or committer). This is a deliberate
@@ -1523,15 +1594,15 @@ allow lifting this restriction.</p></div>
</div>
<div class="sect2">
<h3 id="_alternates">Alternates</h3>
-<div class="paragraph"><p>For the same reason, a sha256 repository cannot borrow objects from a
-sha1 repository using objects/info/alternates or
+<div class="paragraph"><p>For the same reason, a SHA-256 repository cannot borrow objects from a
+SHA-1 repository using objects/info/alternates or
$GIT_ALTERNATE_OBJECT_REPOSITORIES.</p></div>
</div>
<div class="sect2">
<h3 id="_git_notes">git notes</h3>
-<div class="paragraph"><p>The "git notes" tool annotates objects using their sha1-name as key.
+<div class="paragraph"><p>The "git notes" tool annotates objects using their SHA-1 name as key.
This design does not describe a way to migrate notes trees to use
-sha256-names. That migration is expected to happen separately (for
+SHA-256 names. That migration is expected to happen separately (for
example using a file at the root of the notes tree to describe which
hash it uses).</p></div>
</div>
@@ -1567,7 +1638,7 @@ tagger Junio C Hamano &lt;gitster@pobox.com&gt; 1487962205 -0800</code></pre>
<div class="content">
<pre><code>Git 2.12</code></pre>
</div></div>
-<div class="paragraph"><p>Does this mean Git v2.12.0 is the commit with sha1-name
+<div class="paragraph"><p>Does this mean Git v2.12.0 is the commit with SHA-1 name
e7e07d5a4fcc2a203d9873968ad3e6bd4d7419d7 or the commit with
new-40-digit-hash-name e7e07d5a4fcc2a203d9873968ad3e6bd4d7419d7?</p></div>
<div class="paragraph"><p>Fortunately SHA-256 and SHA-1 have different lengths. If Git starts
@@ -1620,93 +1691,151 @@ supports four different modes of operation:</p></div>
<div class="paragraph"><p>The user can also explicitly specify which format to use for a
particular revision specifier and for output, overriding the mode. For
example:</p></div>
-<div class="paragraph"><p></p></div>
+<div class="literalblock">
+<div class="content">
+<pre><code>git --output-format=sha1 log abac87a^{sha1}..f787cac^{sha256}</code></pre>
+</div></div>
</div>
</div>
</div>
<div class="sect1">
-<h2 id="_choice_of_hash">Choice of Hash</h2>
+<h2 id="_transition_plan">Transition plan</h2>
<div class="sectionbody">
-<div class="paragraph"><p>In early 2005, around the time that Git was written, Xiaoyun Wang,
-Yiqun Lisa Yin, and Hongbo Yu announced an attack finding SHA-1
-collisions in 2^69 operations. In August they published details.
-Luckily, no practical demonstrations of a collision in full SHA-1 were
-published until 10 years later, in 2017.</p></div>
-<div class="paragraph"><p>Git v2.13.0 and later subsequently moved to a hardened SHA-1
-implementation by default that mitigates the SHAttered attack, but
-SHA-1 is still believed to be weak.</p></div>
-<div class="paragraph"><p>The hash to replace this hardened SHA-1 should be stronger than SHA-1
-was: we would like it to be trustworthy and useful in practice for at
-least 10 years.</p></div>
-<div class="paragraph"><p>Some other relevant properties:</p></div>
-<div class="olist arabic"><ol class="arabic">
+<div class="paragraph"><p>Some initial steps can be implemented independently of one another:</p></div>
+<div class="ulist"><ul>
<li>
<p>
-A 256-bit hash (long enough to match common security practice; not
- excessively long to hurt performance and disk usage).
+adding a hash function API (vtable)
</p>
</li>
<li>
<p>
-High quality implementations should be widely available (e.g., in
- OpenSSL and Apple CommonCrypto).
+teaching fsck to tolerate the gpgsig-sha256 field
</p>
</li>
<li>
<p>
-The hash function&#8217;s properties should match Git&#8217;s needs (e.g. Git
- requires collision and 2nd preimage resistance and does not require
- length extension resistance).
+excluding gpgsig-* from the fields copied by "git commit --amend"
</p>
</li>
<li>
<p>
-As a tiebreaker, the hash should be fast to compute (fortunately
- many contenders are faster than SHA-1).
+annotating tests that depend on SHA-1 values with a SHA1 test
+ prerequisite
</p>
</li>
-</ol></div>
-<div class="paragraph"><p>We choose SHA-256.</p></div>
-</div>
-</div>
-<div class="sect1">
-<h2 id="_transition_plan">Transition plan</h2>
-<div class="sectionbody">
-<div class="paragraph"><p>Some initial steps can be implemented independently of one another:
-- adding a hash function API (vtable)
-- teaching fsck to tolerate the gpgsig-sha256 field
-- excluding gpgsig-* from the fields copied by "git commit --amend"
-- annotating tests that depend on SHA-1 values with a SHA1 test
- prerequisite
-- using "struct object_id", GIT_MAX_RAWSZ, and GIT_MAX_HEXSZ
+<li>
+<p>
+using "struct object_id", GIT_MAX_RAWSZ, and GIT_MAX_HEXSZ
consistently instead of "unsigned char *" and the hardcoded
constants 20 and 40.
-- introducing index v3
-- adding support for the PSRC field and safer object pruning</p></div>
+</p>
+</li>
+<li>
+<p>
+introducing index v3
+</p>
+</li>
+<li>
+<p>
+adding support for the PSRC field and safer object pruning
+</p>
+</li>
+</ul></div>
<div class="paragraph"><p>The first user-visible change is the introduction of the objectFormat
-extension (without compatObjectFormat). This requires:
-- teaching fsck about this mode of operation
-- using the hash function API (vtable) when computing object names
-- signing objects and verifying signatures
-- rejecting attempts to fetch from or push to an incompatible
- repository</p></div>
-<div class="paragraph"><p>Next comes introduction of compatObjectFormat:
-- implementing the loose-object-idx
-- translating object names between object formats
-- translating object content between object formats
-- generating and verifying signatures in the compat format
-- adding appropriate index entries when adding a new object to the
+extension (without compatObjectFormat). This requires:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+teaching fsck about this mode of operation
+</p>
+</li>
+<li>
+<p>
+using the hash function API (vtable) when computing object names
+</p>
+</li>
+<li>
+<p>
+signing objects and verifying signatures
+</p>
+</li>
+<li>
+<p>
+rejecting attempts to fetch from or push to an incompatible
+ repository
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>Next comes introduction of compatObjectFormat:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+implementing the loose-object-idx
+</p>
+</li>
+<li>
+<p>
+translating object names between object formats
+</p>
+</li>
+<li>
+<p>
+translating object content between object formats
+</p>
+</li>
+<li>
+<p>
+generating and verifying signatures in the compat format
+</p>
+</li>
+<li>
+<p>
+adding appropriate index entries when adding a new object to the
object store
-- --output-format option
-- configuration to specify default input and output format (see
- "Object names on the command line" above)</p></div>
-<div class="paragraph"><p>The next step is supporting fetches and pushes to SHA-1 repositories:
-- allow pushes to a repository using the compat format
-- generate a topologically sorted list of the SHA-1 names of fetched
+</p>
+</li>
+<li>
+<p>
+--output-format option
+</p>
+</li>
+<li>
+<p>
+</p>
+</li>
+<li>
+<p>
+configuration to specify default input and output format (see
+ "Object names on the command line" above)
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>The next step is supporting fetches and pushes to SHA-1 repositories:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+allow pushes to a repository using the compat format
+</p>
+</li>
+<li>
+<p>
+generate a topologically sorted list of the SHA-1 names of fetched
objects
-- convert the fetched packfile to sha256 format and generate an idx
+</p>
+</li>
+<li>
+<p>
+convert the fetched packfile to SHA-256 format and generate an idx
file
-- re-sort to match the order of objects in the fetched packfile</p></div>
+</p>
+</li>
+<li>
+<p>
+re-sort to match the order of objects in the fetched packfile
+</p>
+</li>
+</ul></div>
<div class="paragraph"><p>The infrastructure supporting fetch also allows converting an existing
repository. In converted repositories and new clones, end users can
gain support for the new hash function without any visible change in
@@ -1759,44 +1888,78 @@ adoption.</p></div>
<div class="paragraph"><p>(e.g. <a href="https://lore.kernel.org/git/22708.8913.864049.452252@chiark.greenend.org.uk/">https://lore.kernel.org/git/22708.8913.864049.452252@chiark.greenend.org.uk/</a> )
Objects newly created would be addressed by the new hash, but inside
such an object (e.g. commit) it is still possible to address objects
-using the old hash function.
-* You cannot trust its history (needed for bisectability) in the
+using the old hash function.</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+You cannot trust its history (needed for bisectability) in the
future without further work
-* Maintenance burden as the number of supported hash functions grows
+</p>
+</li>
+<li>
+<p>
+Maintenance burden as the number of supported hash functions grows
(they will never go away, so they accumulate). In this proposal, by
- comparison, converted objects lose all references to SHA-1.</p></div>
+ comparison, converted objects lose all references to SHA-1.
+</p>
+</li>
+</ul></div>
</div>
<div class="sect2">
<h3 id="_signed_objects_with_multiple_hashes">Signed objects with multiple hashes</h3>
<div class="paragraph"><p>Instead of introducing the gpgsig-sha256 field in commit and tag objects
-for sha256-content based signatures, an earlier version of this design
-added "hash sha256 &lt;sha256-name&gt;" fields to strengthen the existing
-sha1-content based signatures.</p></div>
+for SHA-256 content based signatures, an earlier version of this design
+added "hash sha256 &lt;SHA-256 name&gt;" fields to strengthen the existing
+SHA-1 content based signatures.</p></div>
<div class="paragraph"><p>In other words, a single signature was used to attest to the object
-content using both hash functions. This had some advantages:
-* Using one signature instead of two speeds up the signing process.
-* Having one signed payload with both hashes allows the signer to
- attest to the sha1-name and sha256-name referring to the same object.
-* All users consume the same signature. Broken signatures are likely
- to be detected quickly using current versions of git.</p></div>
-<div class="paragraph"><p>However, it also came with disadvantages:
-* Verifying a signed object requires access to the sha1-names of all
+content using both hash functions. This had some advantages:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+Using one signature instead of two speeds up the signing process.
+</p>
+</li>
+<li>
+<p>
+Having one signed payload with both hashes allows the signer to
+ attest to the SHA-1 name and SHA-256 name referring to the same object.
+</p>
+</li>
+<li>
+<p>
+All users consume the same signature. Broken signatures are likely
+ to be detected quickly using current versions of git.
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>However, it also came with disadvantages:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+Verifying a signed object requires access to the SHA-1 names of all
objects it references, even after the transition is complete and
translation table is no longer needed for anything else. To support
- this, the design added fields such as "hash sha1 tree &lt;sha1-name&gt;"
- and "hash sha1 parent &lt;sha1-name&gt;" to the sha256-content of a signed
+ this, the design added fields such as "hash sha1 tree &lt;SHA-1 name&gt;"
+ and "hash sha1 parent &lt;SHA-1 name&gt;" to the SHA-256 content of a signed
commit, complicating the conversion process.
-* Allowing signed objects without a sha1 (for after the transition is
+</p>
+</li>
+<li>
+<p>
+Allowing signed objects without a SHA-1 (for after the transition is
complete) complicated the design further, requiring a "nohash sha1"
- field to suppress including "hash sha1" fields in the sha256-content
- and signed payload.</p></div>
+ field to suppress including "hash sha1" fields in the SHA-256 content
+ and signed payload.
+</p>
+</li>
+</ul></div>
</div>
<div class="sect2">
<h3 id="_lazily_populated_translation_table">Lazily populated translation table</h3>
<div class="paragraph"><p>Some of the work of building the translation table could be deferred to
push time, but that would significantly complicate and slow down pushes.
-Calculating the sha1-name at object creation time at the same time it is
-being streamed to disk and having its sha256-name calculated should be
+Calculating the SHA-1 name at object creation time at the same time it is
+being streamed to disk and having its SHA-256 name calculated should be
an acceptable cost.</p></div>
</div>
</div>
@@ -1807,46 +1970,116 @@ an acceptable cost.</p></div>
<div class="paragraph"><p>2017-03-03
<a href="mailto:bmwill@google.com">bmwill@google.com</a>, <a href="mailto:jonathantanmy@google.com">jonathantanmy@google.com</a>, <a href="mailto:jrnieder@gmail.com">jrnieder@gmail.com</a>,
<a href="mailto:sbeller@google.com">sbeller@google.com</a></p></div>
-<div class="paragraph"><p>Initial version sent to
-<a href="http://lore.kernel.org/git/20170304011251.GA26789@aiede.mtv.corp.google.com">http://lore.kernel.org/git/20170304011251.GA26789@aiede.mtv.corp.google.com</a></p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+Initial version sent to <a href="https://lore.kernel.org/git/20170304011251.GA26789@aiede.mtv.corp.google.com">https://lore.kernel.org/git/20170304011251.GA26789@aiede.mtv.corp.google.com</a>
+</p>
+</li>
+</ul></div>
<div class="paragraph"><p>2017-03-03 <a href="mailto:jrnieder@gmail.com">jrnieder@gmail.com</a>
-Incorporated suggestions from jonathantanmy and sbeller:
-* describe purpose of signed objects with each hash type
-* redefine signed object verification using object content under the
- first hash function</p></div>
-<div class="paragraph"><p>2017-03-06 <a href="mailto:jrnieder@gmail.com">jrnieder@gmail.com</a>
-* Use SHA3-256 instead of SHA2 (thanks, Linus and brian m. carlson).[1][2]
-* Make sha3-based signatures a separate field, avoiding the need for
+Incorporated suggestions from jonathantanmy and sbeller:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+Describe purpose of signed objects with each hash type
+</p>
+</li>
+<li>
+<p>
+Redefine signed object verification using object content under the
+ first hash function
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>2017-03-06 <a href="mailto:jrnieder@gmail.com">jrnieder@gmail.com</a></p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+Use SHA3-256 instead of SHA2 (thanks, Linus and brian m. carlson).[1][2]
+</p>
+</li>
+<li>
+<p>
+Make SHA3-based signatures a separate field, avoiding the need for
"hash" and "nohash" fields (thanks to peff[3]).
-* Add a sorting phase to fetch (thanks to Junio for noticing the need
+</p>
+</li>
+<li>
+<p>
+Add a sorting phase to fetch (thanks to Junio for noticing the need
for this).
-* Omit blobs from the topological sort during fetch (thanks to peff).
-* Discuss alternates, git notes, and git servers in the caveats
+</p>
+</li>
+<li>
+<p>
+Omit blobs from the topological sort during fetch (thanks to peff).
+</p>
+</li>
+<li>
+<p>
+Discuss alternates, git notes, and git servers in the caveats
section (thanks to Junio Hamano, brian m. carlson[4], and Shawn
Pearce).
-* Clarify language throughout (thanks to various commenters,
- especially Junio).</p></div>
-<div class="paragraph"><p>2017-09-27 <a href="mailto:jrnieder@gmail.com">jrnieder@gmail.com</a>, <a href="mailto:sbeller@google.com">sbeller@google.com</a>
-* use placeholder NewHash instead of SHA3-256
-* describe criteria for picking a hash function.
-* include a transition plan (thanks especially to Brandon Williams
+</p>
+</li>
+<li>
+<p>
+Clarify language throughout (thanks to various commenters,
+ especially Junio).
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>2017-09-27 <a href="mailto:jrnieder@gmail.com">jrnieder@gmail.com</a>, <a href="mailto:sbeller@google.com">sbeller@google.com</a></p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+Use placeholder NewHash instead of SHA3-256
+</p>
+</li>
+<li>
+<p>
+Describe criteria for picking a hash function.
+</p>
+</li>
+<li>
+<p>
+Include a transition plan (thanks especially to Brandon Williams
for fleshing these ideas out)
-* define the translation table (thanks, Shawn Pearce[5], Jonathan
+</p>
+</li>
+<li>
+<p>
+Define the translation table (thanks, Shawn Pearce[5], Jonathan
Tan, and Masaya Suzuki)
-* avoid loose object overhead by packing more aggressively in
- "git gc --auto"</p></div>
+</p>
+</li>
+<li>
+<p>
+Avoid loose object overhead by packing more aggressively in
+ "git gc --auto"
+</p>
+</li>
+</ul></div>
<div class="paragraph"><p>Later history:</p></div>
+<div class="ulist"><ul>
+<li>
+<p>
+See the history of this file in git.git for the history of subsequent
+ edits. This document history is no longer being maintained as it
+ would now be superfluous to the commit log
+</p>
+</li>
+</ul></div>
+<div class="paragraph"><p>References:</p></div>
<div class="literalblock">
<div class="content">
-<pre><code>See the history of this file in git.git for the history of subsequent
-edits. This document history is no longer being maintained as it
-would now be superfluous to the commit log</code></pre>
+<pre><code>[1] https://lore.kernel.org/git/CA+55aFzJtejiCjV0e43+9oR3QuJK2PiFiLQemytoLpyJWe6P9w@mail.gmail.com/
+[2] https://lore.kernel.org/git/CA+55aFz+gkAsDZ24zmePQuEs1XPS9BP_s8O7Q4wQ7LV7X5-oDA@mail.gmail.com/
+[3] https://lore.kernel.org/git/20170306084353.nrns455dvkdsfgo5@sigill.intra.peff.net/
+[4] https://lore.kernel.org/git/20170304224936.rqqtkdvfjgyezsht@genre.crustytoothpaste.net
+[5] https://lore.kernel.org/git/CAJo=hJtoX9=AyLHHpUJS7fueV9ciZ_MNpnEPHUz8Whui6g9F0A@mail.gmail.com/</code></pre>
</div></div>
-<div class="paragraph"><p>[1] <a href="http://lore.kernel.org/git/CA+55aFzJtejiCjV0e43+<a href="mailto:9oR3QuJK2PiFiLQemytoLpyJWe6P9w@mail.gmail.com">9oR3QuJK2PiFiLQemytoLpyJWe6P9w@mail.gmail.com</a>/">http://lore.kernel.org/git/CA+55aFzJtejiCjV0e43+<a href="mailto:9oR3QuJK2PiFiLQemytoLpyJWe6P9w@mail.gmail.com">9oR3QuJK2PiFiLQemytoLpyJWe6P9w@mail.gmail.com</a>/</a>
-[2] <a href="http://lore.kernel.org/git/CA+55aFz+<a href="mailto:gkAsDZ24zmePQuEs1XPS9BP_s8O7Q4wQ7LV7X5-oDA@mail.gmail.com">gkAsDZ24zmePQuEs1XPS9BP_s8O7Q4wQ7LV7X5-oDA@mail.gmail.com</a>/">http://lore.kernel.org/git/CA+55aFz+<a href="mailto:gkAsDZ24zmePQuEs1XPS9BP_s8O7Q4wQ7LV7X5-oDA@mail.gmail.com">gkAsDZ24zmePQuEs1XPS9BP_s8O7Q4wQ7LV7X5-oDA@mail.gmail.com</a>/</a>
-[3] <a href="http://lore.kernel.org/git/20170306084353.nrns455dvkdsfgo5@sigill.intra.peff.net/">http://lore.kernel.org/git/20170306084353.nrns455dvkdsfgo5@sigill.intra.peff.net/</a>
-[4] <a href="http://lore.kernel.org/git/20170304224936.rqqtkdvfjgyezsht@genre.crustytoothpaste.net">http://lore.kernel.org/git/20170304224936.rqqtkdvfjgyezsht@genre.crustytoothpaste.net</a>
-[5] <a href="https://lore.kernel.org/git/CAJo=hJtoX9=<a href="mailto:AyLHHpUJS7fueV9ciZ_MNpnEPHUz8Whui6g9F0A@mail.gmail.com">AyLHHpUJS7fueV9ciZ_MNpnEPHUz8Whui6g9F0A@mail.gmail.com</a>/">https://lore.kernel.org/git/CAJo=hJtoX9=<a href="mailto:AyLHHpUJS7fueV9ciZ_MNpnEPHUz8Whui6g9F0A@mail.gmail.com">AyLHHpUJS7fueV9ciZ_MNpnEPHUz8Whui6g9F0A@mail.gmail.com</a>/</a></p></div>
</div>
</div>
</div>
@@ -1854,7 +2087,7 @@ would now be superfluous to the commit log</code></pre>
<div id="footer">
<div id="footer-text">
Last updated
- 2020-08-19 16:37:10 PDT
+ 2021-02-22 16:54:23 PST
</div>
</div>
</body>
diff --git a/technical/hash-function-transition.txt b/technical/hash-function-transition.txt
index 6fd20ebbc..7c1630bf8 100644
--- a/technical/hash-function-transition.txt
+++ b/technical/hash-function-transition.txt
@@ -33,16 +33,9 @@ researchers. On 23 February 2017 the SHAttered attack
Git v2.13.0 and later subsequently moved to a hardened SHA-1
implementation by default, which isn't vulnerable to the SHAttered
-attack.
+attack, but SHA-1 is still weak.
-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
+Thus 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.
@@ -57,6 +50,38 @@ SHA-1 still possesses the other properties such as fast object lookup
and safe error checking, but other hash functions are equally suitable
that are believed to be cryptographically secure.
+Choice of Hash
+--------------
+The hash to replace the hardened SHA-1 should be stronger than SHA-1
+was: we would like it to be trustworthy and useful in practice for at
+least 10 years.
+
+Some other relevant properties:
+
+1. A 256-bit hash (long enough to match common security practice; not
+ excessively long to hurt performance and disk usage).
+
+2. High quality implementations should be widely available (e.g., in
+ OpenSSL and Apple CommonCrypto).
+
+3. The hash function's properties should match Git's needs (e.g. Git
+ requires collision and 2nd preimage resistance and does not require
+ length extension resistance).
+
+4. As a tiebreaker, the hash should be fast to compute (fortunately
+ many contenders are faster than SHA-1).
+
+There were several contenders for a successor hash to SHA-1, including
+SHA-256, SHA-512/256, SHA-256x16, K12, and BLAKE2bp-256.
+
+In late 2018 the project picked SHA-256 as its successor hash.
+
+See 0ed8d8da374 (doc hash-function-transition: pick SHA-256 as
+NewHash, 2018-08-04) and numerous mailing list threads at the time,
+particularly the one starting at
+https://lore.kernel.org/git/20180609224913.GC38834@genre.crustytoothpaste.net/
+for more information.
+
Goals
-----
1. The transition to SHA-256 can be done one local repository at a time.
@@ -94,7 +119,7 @@ Overview
--------
We introduce a new repository format extension. Repositories with this
extension enabled use SHA-256 instead of SHA-1 to name their objects.
-This affects both object names and object content --- both the names
+This affects both object names and object content -- both the names
of objects and all references to other objects within an object are
switched to the new hash function.
@@ -107,7 +132,7 @@ mapping to allow naming objects using either their SHA-1 and SHA-256 names
interchangeably.
"git cat-file" and "git hash-object" gain options to display an object
-in its sha1 form and write an object given its sha1 form. This
+in its SHA-1 form and write an object given its SHA-1 form. This
requires all objects referenced by that object to be present in the
object database so that they can be named using the appropriate name
(using the bidirectional hash mapping).
@@ -115,7 +140,7 @@ object database so that they can be named using the appropriate name
Fetches from a SHA-1 based server convert the fetched objects into
SHA-256 form and record the mapping in the bidirectional mapping table
(see below for details). Pushes to a SHA-1 based server convert the
-objects being pushed into sha1 form so the server does not have to be
+objects being pushed into SHA-1 form so the server does not have to be
aware of the hash function the client is using.
Detailed Design
@@ -151,38 +176,38 @@ repository extensions.
Object names
~~~~~~~~~~~~
-Objects can be named by their 40 hexadecimal digit sha1-name or 64
-hexadecimal digit sha256-name, plus names derived from those (see
+Objects can be named by their 40 hexadecimal digit SHA-1 name or 64
+hexadecimal digit SHA-256 name, plus names derived from those (see
gitrevisions(7)).
-The sha1-name of an object is the SHA-1 of the concatenation of its
-type, length, a nul byte, and the object's sha1-content. This is the
+The SHA-1 name of an object is the SHA-1 of the concatenation of its
+type, length, a nul byte, and the object's SHA-1 content. This is the
traditional <sha1> used in Git to name objects.
-The sha256-name of an object is the SHA-256 of the concatenation of its
-type, length, a nul byte, and the object's sha256-content.
+The SHA-256 name of an object is the SHA-256 of the concatenation of its
+type, length, a nul byte, and the object's SHA-256 content.
Object format
~~~~~~~~~~~~~
The content as a byte sequence of a tag, commit, or tree object named
-by sha1 and sha256 differ because an object named by sha256-name refers to
-other objects by their sha256-names and an object named by sha1-name
-refers to other objects by their sha1-names.
+by SHA-1 and SHA-256 differ because an object named by SHA-256 name refers to
+other objects by their SHA-256 names and an object named by SHA-1 name
+refers to other objects by their SHA-1 names.
-The sha256-content of an object is the same as its sha1-content, except
-that objects referenced by the object are named using their sha256-names
-instead of sha1-names. Because a blob object does not refer to any
-other object, its sha1-content and sha256-content are the same.
+The SHA-256 content of an object is the same as its SHA-1 content, except
+that objects referenced by the object are named using their SHA-256 names
+instead of SHA-1 names. Because a blob object does not refer to any
+other object, its SHA-1 content and SHA-256 content are the same.
-The format allows round-trip conversion between sha256-content and
-sha1-content.
+The format allows round-trip conversion between SHA-256 content and
+SHA-1 content.
Object storage
~~~~~~~~~~~~~~
Loose objects use zlib compression and packed objects use the packed
format described in Documentation/technical/pack-format.txt, just like
-today. The content that is compressed and stored uses sha256-content
-instead of sha1-content.
+today. The content that is compressed and stored uses SHA-256 content
+instead of SHA-1 content.
Pack index
~~~~~~~~~~
@@ -191,21 +216,21 @@ hash functions. They have the following format (all integers are in
network byte order):
- A header appears at the beginning and consists of the following:
- - The 4-byte pack index signature: '\377t0c'
- - 4-byte version number: 3
- - 4-byte length of the header section, including the signature and
+ * The 4-byte pack index signature: '\377t0c'
+ * 4-byte version number: 3
+ * 4-byte length of the header section, including the signature and
version number
- - 4-byte number of objects contained in the pack
- - 4-byte number of object formats in this pack index: 2
- - For each object format:
- - 4-byte format identifier (e.g., 'sha1' for SHA-1)
- - 4-byte length in bytes of shortened object names. This is the
+ * 4-byte number of objects contained in the pack
+ * 4-byte number of object formats in this pack index: 2
+ * For each object format:
+ ** 4-byte format identifier (e.g., 'sha1' for SHA-1)
+ ** 4-byte length in bytes of shortened object names. This is the
shortest possible length needed to make names in the shortened
object name table unambiguous.
- - 4-byte integer, recording where tables relating to this format
+ ** 4-byte integer, recording where tables relating to this format
are stored in this index file, as an offset from the beginning.
- - 4-byte offset to the trailer from the beginning of this file.
- - Zero or more additional key/value pairs (4-byte key, 4-byte
+ * 4-byte offset to the trailer from the beginning of this file.
+ * Zero or more additional key/value pairs (4-byte key, 4-byte
value). Only one key is supported: 'PSRC'. See the "Loose objects
and unreachable objects" section for supported values and how this
is used. All other keys are reserved. Readers must ignore
@@ -213,37 +238,36 @@ network byte order):
- Zero or more NUL bytes. This can optionally be used to improve the
alignment of the full object name table below.
- Tables for the first object format:
- - A sorted table of shortened object names. These are prefixes of
+ * A sorted table of shortened object names. These are prefixes of
the names of all objects in this pack file, packed together
without offset values to reduce the cache footprint of the binary
search for a specific object name.
- - A table of full object names in pack order. This allows resolving
+ * A table of full object names in pack order. This allows resolving
a reference to "the nth object in the pack file" (from a
reachability bitmap or from the next table of another object
format) to its object name.
- - A table of 4-byte values mapping object name order to pack order.
+ * A table of 4-byte values mapping object name order to pack order.
For an object in the table of sorted shortened object names, the
value at the corresponding index in this table is the index in the
previous table for that same object.
-
This can be used to look up the object in reachability bitmaps or
to look up its name in another object format.
- - A table of 4-byte CRC32 values of the packed object data, in the
+ * A table of 4-byte CRC32 values of the packed object data, in the
order that the objects appear in the pack file. This is to allow
compressed data to be copied directly from pack to pack during
repacking without undetected data corruption.
- - A table of 4-byte offset values. For an object in the table of
+ * A table of 4-byte offset values. For an object in the table of
sorted shortened object names, the value at the corresponding
index in this table indicates where that object can be found in
the pack file. These are usually 31-bit pack file offsets, but
large offsets are encoded as an index into the next table with the
most significant bit set.
- - A table of 8-byte offset entries (empty for pack files less than
+ * A table of 8-byte offset entries (empty for pack files less than
2 GiB). Pack files are organized with heavily used objects toward
the front, so most object references should not need to refer to
this table.
@@ -252,10 +276,10 @@ network byte order):
up to and not including the table of CRC32 values.
- Zero or more NUL bytes.
- The trailer consists of the following:
- - A copy of the 20-byte SHA-256 checksum at the end of the
+ * A copy of the 20-byte SHA-256 checksum at the end of the
corresponding packfile.
- - 20-byte SHA-256 checksum of all of the above.
+ * 20-byte SHA-256 checksum of all of the above.
Loose object index
~~~~~~~~~~~~~~~~~~
@@ -288,18 +312,18 @@ To remove entries (e.g. in "git pack-refs" or "git-prune"):
Translation table
~~~~~~~~~~~~~~~~~
-The index files support a bidirectional mapping between sha1-names
-and sha256-names. The lookup proceeds similarly to ordinary object
-lookups. For example, to convert a sha1-name to a sha256-name:
+The index files support a bidirectional mapping between SHA-1 names
+and SHA-256 names. The lookup proceeds similarly to ordinary object
+lookups. For example, to convert a SHA-1 name to a SHA-256 name:
1. Look for the object in idx files. If a match is present in the
- idx's sorted list of truncated sha1-names, then:
- a. Read the corresponding entry in the sha1-name order to pack
+ idx's sorted list of truncated SHA-1 names, then:
+ a. Read the corresponding entry in the SHA-1 name order to pack
name order mapping.
- b. Read the corresponding entry in the full sha1-name table to
+ b. Read the corresponding entry in the full SHA-1 name table to
verify we found the right object. If it is, then
- c. Read the corresponding entry in the full sha256-name table.
- That is the object's sha256-name.
+ c. Read the corresponding entry in the full SHA-256 name table.
+ That is the object's SHA-256 name.
2. Check for a loose object. Read lines from loose-object-idx until
we find a match.
@@ -313,10 +337,10 @@ Since all operations that make new objects (e.g., "git commit") add
the new objects to the corresponding index, this mapping is possible
for all objects in the object store.
-Reading an object's sha1-content
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The sha1-content of an object can be read by converting all sha256-names
-its sha256-content references to sha1-names using the translation table.
+Reading an object's SHA-1 content
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The SHA-1 content of an object can be read by converting all SHA-256 names
+of its SHA-256 content references to SHA-1 names using the translation table.
Fetch
~~~~~
@@ -339,7 +363,7 @@ the following steps:
1. index-pack: inflate each object in the packfile and compute its
SHA-1. Objects can contain deltas in OBJ_REF_DELTA format against
objects the client has locally. These objects can be looked up
- using the translation table and their sha1-content read as
+ using the translation table and their SHA-1 content read as
described above to resolve the deltas.
2. topological sort: starting at the "want"s from the negotiation
phase, walk through objects in the pack and emit a list of them,
@@ -348,12 +372,12 @@ the following steps:
(This list only contains objects reachable from the "wants". If the
pack from the server contained additional extraneous objects, then
they will be discarded.)
-3. convert to sha256: open a new (sha256) packfile. Read the topologically
+3. convert to SHA-256: open a new SHA-256 packfile. Read the topologically
sorted list just generated. For each object, inflate its
- sha1-content, convert to sha256-content, and write it to the sha256
- pack. Record the new sha1<->sha256 mapping entry for use in the idx.
+ SHA-1 content, convert to SHA-256 content, and write it to the SHA-256
+ pack. Record the new SHA-1<-->SHA-256 mapping entry for use in the idx.
4. sort: reorder entries in the new pack to match the order of objects
- in the pack the server generated and include blobs. Write a sha256 idx
+ in the pack the server generated and include blobs. Write a SHA-256 idx
file
5. clean up: remove the SHA-1 based pack file, index, and
topologically sorted list obtained from the server in steps 1
@@ -378,19 +402,20 @@ experimenting to get this to perform well.
Push
~~~~
Push is simpler than fetch because the objects referenced by the
-pushed objects are already in the translation table. The sha1-content
+pushed objects are already in the translation table. The SHA-1 content
of each object being pushed can be read as described in the "Reading
-an object's sha1-content" section to generate the pack written by git
+an object's SHA-1 content" section to generate the pack written by git
send-pack.
Signed Commits
~~~~~~~~~~~~~~
We add a new field "gpgsig-sha256" to the commit object format to allow
signing commits without relying on SHA-1. It is similar to the
-existing "gpgsig" field. Its signed payload is the sha256-content of the
+existing "gpgsig" field. Its signed payload is the SHA-256 content of the
commit object with any "gpgsig" and "gpgsig-sha256" fields removed.
This means commits can be signed
+
1. using SHA-1 only, as in existing signed commit objects
2. using both SHA-1 and SHA-256, by using both gpgsig-sha256 and gpgsig
fields.
@@ -404,10 +429,11 @@ Signed Tags
~~~~~~~~~~~
We add a new field "gpgsig-sha256" to the tag object format to allow
signing tags without relying on SHA-1. Its signed payload is the
-sha256-content of the tag with its gpgsig-sha256 field and "-----BEGIN PGP
+SHA-256 content of the tag with its gpgsig-sha256 field and "-----BEGIN PGP
SIGNATURE-----" delimited in-body signature removed.
This means tags can be signed
+
1. using SHA-1 only, as in existing signed tag objects
2. using both SHA-1 and SHA-256, by using gpgsig-sha256 and an in-body
signature.
@@ -415,11 +441,11 @@ This means tags can be signed
Mergetag embedding
~~~~~~~~~~~~~~~~~~
-The mergetag field in the sha1-content of a commit contains the
-sha1-content of a tag that was merged by that commit.
+The mergetag field in the SHA-1 content of a commit contains the
+SHA-1 content of a tag that was merged by that commit.
-The mergetag field in the sha256-content of the same commit contains the
-sha256-content of the same tag.
+The mergetag field in the SHA-256 content of the same commit contains the
+SHA-256 content of the same tag.
Submodules
~~~~~~~~~~
@@ -494,7 +520,7 @@ Caveats
-------
Invalid objects
~~~~~~~~~~~~~~~
-The conversion from sha1-content to sha256-content retains any
+The conversion from SHA-1 content to SHA-256 content retains any
brokenness in the original object (e.g., tree entry modes encoded with
leading 0, tree objects whose paths are not sorted correctly, and
commit objects without an author or committer). This is a deliberate
@@ -513,15 +539,15 @@ allow lifting this restriction.
Alternates
~~~~~~~~~~
-For the same reason, a sha256 repository cannot borrow objects from a
-sha1 repository using objects/info/alternates or
+For the same reason, a SHA-256 repository cannot borrow objects from a
+SHA-1 repository using objects/info/alternates or
$GIT_ALTERNATE_OBJECT_REPOSITORIES.
git notes
~~~~~~~~~
-The "git notes" tool annotates objects using their sha1-name as key.
+The "git notes" tool annotates objects using their SHA-1 name as key.
This design does not describe a way to migrate notes trees to use
-sha256-names. That migration is expected to happen separately (for
+SHA-256 names. That migration is expected to happen separately (for
example using a file at the root of the notes tree to describe which
hash it uses).
@@ -555,7 +581,7 @@ unclear:
Git 2.12
-Does this mean Git v2.12.0 is the commit with sha1-name
+Does this mean Git v2.12.0 is the commit with SHA-1 name
e7e07d5a4fcc2a203d9873968ad3e6bd4d7419d7 or the commit with
new-40-digit-hash-name e7e07d5a4fcc2a203d9873968ad3e6bd4d7419d7?
@@ -598,44 +624,12 @@ The user can also explicitly specify which format to use for a
particular revision specifier and for output, overriding the mode. For
example:
-git --output-format=sha1 log abac87a^{sha1}..f787cac^{sha256}
-
-Choice of Hash
---------------
-In early 2005, around the time that Git was written, Xiaoyun Wang,
-Yiqun Lisa Yin, and Hongbo Yu announced an attack finding SHA-1
-collisions in 2^69 operations. In August they published details.
-Luckily, no practical demonstrations of a collision in full SHA-1 were
-published until 10 years later, in 2017.
-
-Git v2.13.0 and later subsequently moved to a hardened SHA-1
-implementation by default that mitigates the SHAttered attack, but
-SHA-1 is still believed to be weak.
-
-The hash to replace this hardened SHA-1 should be stronger than SHA-1
-was: we would like it to be trustworthy and useful in practice for at
-least 10 years.
-
-Some other relevant properties:
-
-1. A 256-bit hash (long enough to match common security practice; not
- excessively long to hurt performance and disk usage).
-
-2. High quality implementations should be widely available (e.g., in
- OpenSSL and Apple CommonCrypto).
-
-3. The hash function's properties should match Git's needs (e.g. Git
- requires collision and 2nd preimage resistance and does not require
- length extension resistance).
-
-4. As a tiebreaker, the hash should be fast to compute (fortunately
- many contenders are faster than SHA-1).
-
-We choose SHA-256.
+ git --output-format=sha1 log abac87a^{sha1}..f787cac^{sha256}
Transition plan
---------------
Some initial steps can be implemented independently of one another:
+
- adding a hash function API (vtable)
- teaching fsck to tolerate the gpgsig-sha256 field
- excluding gpgsig-* from the fields copied by "git commit --amend"
@@ -647,9 +641,9 @@ Some initial steps can be implemented independently of one another:
- introducing index v3
- adding support for the PSRC field and safer object pruning
-
The first user-visible change is the introduction of the objectFormat
extension (without compatObjectFormat). This requires:
+
- teaching fsck about this mode of operation
- using the hash function API (vtable) when computing object names
- signing objects and verifying signatures
@@ -657,6 +651,7 @@ extension (without compatObjectFormat). This requires:
repository
Next comes introduction of compatObjectFormat:
+
- implementing the loose-object-idx
- translating object names between object formats
- translating object content between object formats
@@ -669,10 +664,11 @@ Next comes introduction of compatObjectFormat:
"Object names on the command line" above)
The next step is supporting fetches and pushes to SHA-1 repositories:
+
- allow pushes to a repository using the compat format
- generate a topologically sorted list of the SHA-1 names of fetched
objects
-- convert the fetched packfile to sha256 format and generate an idx
+- convert the fetched packfile to SHA-256 format and generate an idx
file
- re-sort to match the order of objects in the fetched packfile
@@ -734,6 +730,7 @@ Using hash functions in parallel
Objects newly created would be addressed by the new hash, but inside
such an object (e.g. commit) it is still possible to address objects
using the old hash function.
+
* You cannot trust its history (needed for bisectability) in the
future without further work
* Maintenance burden as the number of supported hash functions grows
@@ -743,36 +740,38 @@ using the old hash function.
Signed objects with multiple hashes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Instead of introducing the gpgsig-sha256 field in commit and tag objects
-for sha256-content based signatures, an earlier version of this design
-added "hash sha256 <sha256-name>" fields to strengthen the existing
-sha1-content based signatures.
+for SHA-256 content based signatures, an earlier version of this design
+added "hash sha256 <SHA-256 name>" fields to strengthen the existing
+SHA-1 content based signatures.
In other words, a single signature was used to attest to the object
content using both hash functions. This had some advantages:
+
* Using one signature instead of two speeds up the signing process.
* Having one signed payload with both hashes allows the signer to
- attest to the sha1-name and sha256-name referring to the same object.
+ attest to the SHA-1 name and SHA-256 name referring to the same object.
* All users consume the same signature. Broken signatures are likely
to be detected quickly using current versions of git.
However, it also came with disadvantages:
-* Verifying a signed object requires access to the sha1-names of all
+
+* Verifying a signed object requires access to the SHA-1 names of all
objects it references, even after the transition is complete and
translation table is no longer needed for anything else. To support
- this, the design added fields such as "hash sha1 tree <sha1-name>"
- and "hash sha1 parent <sha1-name>" to the sha256-content of a signed
+ this, the design added fields such as "hash sha1 tree <SHA-1 name>"
+ and "hash sha1 parent <SHA-1 name>" to the SHA-256 content of a signed
commit, complicating the conversion process.
-* Allowing signed objects without a sha1 (for after the transition is
+* Allowing signed objects without a SHA-1 (for after the transition is
complete) complicated the design further, requiring a "nohash sha1"
- field to suppress including "hash sha1" fields in the sha256-content
+ field to suppress including "hash sha1" fields in the SHA-256 content
and signed payload.
Lazily populated translation table
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Some of the work of building the translation table could be deferred to
push time, but that would significantly complicate and slow down pushes.
-Calculating the sha1-name at object creation time at the same time it is
-being streamed to disk and having its sha256-name calculated should be
+Calculating the SHA-1 name at object creation time at the same time it is
+being streamed to disk and having its SHA-256 name calculated should be
an acceptable cost.
Document History
@@ -782,18 +781,19 @@ Document History
bmwill@google.com, jonathantanmy@google.com, jrnieder@gmail.com,
sbeller@google.com
-Initial version sent to
-http://lore.kernel.org/git/20170304011251.GA26789@aiede.mtv.corp.google.com
+* Initial version sent to https://lore.kernel.org/git/20170304011251.GA26789@aiede.mtv.corp.google.com
2017-03-03 jrnieder@gmail.com
Incorporated suggestions from jonathantanmy and sbeller:
-* describe purpose of signed objects with each hash type
-* redefine signed object verification using object content under the
+
+* Describe purpose of signed objects with each hash type
+* Redefine signed object verification using object content under the
first hash function
2017-03-06 jrnieder@gmail.com
+
* Use SHA3-256 instead of SHA2 (thanks, Linus and brian m. carlson).[1][2]
-* Make sha3-based signatures a separate field, avoiding the need for
+* Make SHA3-based signatures a separate field, avoiding the need for
"hash" and "nohash" fields (thanks to peff[3]).
* Add a sorting phase to fetch (thanks to Junio for noticing the need
for this).
@@ -805,23 +805,26 @@ Incorporated suggestions from jonathantanmy and sbeller:
especially Junio).
2017-09-27 jrnieder@gmail.com, sbeller@google.com
-* use placeholder NewHash instead of SHA3-256
-* describe criteria for picking a hash function.
-* include a transition plan (thanks especially to Brandon Williams
+
+* Use placeholder NewHash instead of SHA3-256
+* Describe criteria for picking a hash function.
+* Include a transition plan (thanks especially to Brandon Williams
for fleshing these ideas out)
-* define the translation table (thanks, Shawn Pearce[5], Jonathan
+* Define the translation table (thanks, Shawn Pearce[5], Jonathan
Tan, and Masaya Suzuki)
-* avoid loose object overhead by packing more aggressively in
+* Avoid loose object overhead by packing more aggressively in
"git gc --auto"
Later history:
- See the history of this file in git.git for the history of subsequent
- edits. This document history is no longer being maintained as it
- would now be superfluous to the commit log
+* See the history of this file in git.git for the history of subsequent
+ edits. This document history is no longer being maintained as it
+ would now be superfluous to the commit log
+
+References:
-[1] http://lore.kernel.org/git/CA+55aFzJtejiCjV0e43+9oR3QuJK2PiFiLQemytoLpyJWe6P9w@mail.gmail.com/
-[2] http://lore.kernel.org/git/CA+55aFz+gkAsDZ24zmePQuEs1XPS9BP_s8O7Q4wQ7LV7X5-oDA@mail.gmail.com/
-[3] http://lore.kernel.org/git/20170306084353.nrns455dvkdsfgo5@sigill.intra.peff.net/
-[4] http://lore.kernel.org/git/20170304224936.rqqtkdvfjgyezsht@genre.crustytoothpaste.net
-[5] https://lore.kernel.org/git/CAJo=hJtoX9=AyLHHpUJS7fueV9ciZ_MNpnEPHUz8Whui6g9F0A@mail.gmail.com/
+ [1] https://lore.kernel.org/git/CA+55aFzJtejiCjV0e43+9oR3QuJK2PiFiLQemytoLpyJWe6P9w@mail.gmail.com/
+ [2] https://lore.kernel.org/git/CA+55aFz+gkAsDZ24zmePQuEs1XPS9BP_s8O7Q4wQ7LV7X5-oDA@mail.gmail.com/
+ [3] https://lore.kernel.org/git/20170306084353.nrns455dvkdsfgo5@sigill.intra.peff.net/
+ [4] https://lore.kernel.org/git/20170304224936.rqqtkdvfjgyezsht@genre.crustytoothpaste.net
+ [5] https://lore.kernel.org/git/CAJo=hJtoX9=AyLHHpUJS7fueV9ciZ_MNpnEPHUz8Whui6g9F0A@mail.gmail.com/
diff --git a/technical/protocol-v2.html b/technical/protocol-v2.html
index 0bc472ea8..b97acb87a 100644
--- a/technical/protocol-v2.html
+++ b/technical/protocol-v2.html
@@ -975,12 +975,22 @@ ref-prefix &lt;prefix&gt;
When specified, only references having a prefix matching one of
the provided prefixes are displayed.</code></pre>
</div></div>
+<div class="paragraph"><p>If the <em>unborn</em> feature is advertised the following argument can be
+included in the client&#8217;s request.</p></div>
+<div class="literalblock">
+<div class="content">
+<pre><code>unborn
+ The server will send information about HEAD even if it is a symref
+ pointing to an unborn branch in the form "unborn HEAD
+ symref-target:&lt;target&gt;".</code></pre>
+</div></div>
<div class="paragraph"><p>The output of ls-refs is as follows:</p></div>
<div class="literalblock">
<div class="content">
<pre><code>output = *ref
flush-pkt
-ref = PKT-LINE(obj-id SP refname *(SP ref-attribute) LF)
+obj-id-or-unborn = (obj-id | "unborn")
+ref = PKT-LINE(obj-id-or-unborn SP refname *(SP ref-attribute) LF)
ref-attribute = (symref | peeled)
symref = "symref-target:" symref-target
peeled = "peeled:" obj-id</code></pre>
@@ -1402,7 +1412,7 @@ the session ID should not rely on this fact.</p></div>
<div id="footer">
<div id="footer-text">
Last updated
- 2020-12-08 16:10:07 PST
+ 2021-02-22 16:54:23 PST
</div>
</div>
</body>
diff --git a/technical/protocol-v2.txt b/technical/protocol-v2.txt
index 85daeb5d9..f772d90ea 100644
--- a/technical/protocol-v2.txt
+++ b/technical/protocol-v2.txt
@@ -192,11 +192,20 @@ ls-refs takes in the following arguments:
When specified, only references having a prefix matching one of
the provided prefixes are displayed.
+If the 'unborn' feature is advertised the following argument can be
+included in the client's request.
+
+ unborn
+ The server will send information about HEAD even if it is a symref
+ pointing to an unborn branch in the form "unborn HEAD
+ symref-target:<target>".
+
The output of ls-refs is as follows:
output = *ref
flush-pkt
- ref = PKT-LINE(obj-id SP refname *(SP ref-attribute) LF)
+ obj-id-or-unborn = (obj-id | "unborn")
+ ref = PKT-LINE(obj-id-or-unborn SP refname *(SP ref-attribute) LF)
ref-attribute = (symref | peeled)
symref = "symref-target:" symref-target
peeled = "peeled:" obj-id