blob: 48084b510c6880c0af8223b19516a66c04c109ac [file] [log] [blame]
Junio C Hamano04495a12022-08-18 21:13:081<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3 "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
5<head>
6<meta http-equiv="Content-Type" content="application/xhtml+xml; charset=UTF-8" />
7<meta name="generator" content="AsciiDoc 10.2.0" />
8<title>gitformat-commit-graph(5)</title>
9<style type="text/css">
10/* Shared CSS for AsciiDoc xhtml11 and html5 backends */
11
12/* Default font. */
13body {
14 font-family: Georgia,serif;
15}
16
17/* Title font. */
18h1, h2, h3, h4, h5, h6,
19div.title, caption.title,
20thead, p.table.header,
21#toctitle,
22#author, #revnumber, #revdate, #revremark,
23#footer {
24 font-family: Arial,Helvetica,sans-serif;
25}
26
27body {
28 margin: 1em 5% 1em 5%;
29}
30
31a {
32 color: blue;
33 text-decoration: underline;
34}
35a:visited {
36 color: fuchsia;
37}
38
39em {
40 font-style: italic;
41 color: navy;
42}
43
44strong {
45 font-weight: bold;
46 color: #083194;
47}
48
49h1, h2, h3, h4, h5, h6 {
50 color: #527bbd;
51 margin-top: 1.2em;
52 margin-bottom: 0.5em;
53 line-height: 1.3;
54}
55
56h1, h2, h3 {
57 border-bottom: 2px solid silver;
58}
59h2 {
60 padding-top: 0.5em;
61}
62h3 {
63 float: left;
64}
65h3 + * {
66 clear: left;
67}
68h5 {
69 font-size: 1.0em;
70}
71
72div.sectionbody {
73 margin-left: 0;
74}
75
76hr {
77 border: 1px solid silver;
78}
79
80p {
81 margin-top: 0.5em;
82 margin-bottom: 0.5em;
83}
84
85ul, ol, li > p {
86 margin-top: 0;
87}
88ul > li { color: #aaa; }
89ul > li > * { color: black; }
90
91.monospaced, code, pre {
92 font-family: "Courier New", Courier, monospace;
93 font-size: inherit;
94 color: navy;
95 padding: 0;
96 margin: 0;
97}
98pre {
99 white-space: pre-wrap;
100}
101
102#author {
103 color: #527bbd;
104 font-weight: bold;
105 font-size: 1.1em;
106}
107#email {
108}
109#revnumber, #revdate, #revremark {
110}
111
112#footer {
113 font-size: small;
114 border-top: 2px solid silver;
115 padding-top: 0.5em;
116 margin-top: 4.0em;
117}
118#footer-text {
119 float: left;
120 padding-bottom: 0.5em;
121}
122#footer-badges {
123 float: right;
124 padding-bottom: 0.5em;
125}
126
127#preamble {
128 margin-top: 1.5em;
129 margin-bottom: 1.5em;
130}
131div.imageblock, div.exampleblock, div.verseblock,
132div.quoteblock, div.literalblock, div.listingblock, div.sidebarblock,
133div.admonitionblock {
134 margin-top: 1.0em;
135 margin-bottom: 1.5em;
136}
137div.admonitionblock {
138 margin-top: 2.0em;
139 margin-bottom: 2.0em;
140 margin-right: 10%;
141 color: #606060;
142}
143
144div.content { /* Block element content. */
145 padding: 0;
146}
147
148/* Block element titles. */
149div.title, caption.title {
150 color: #527bbd;
151 font-weight: bold;
152 text-align: left;
153 margin-top: 1.0em;
154 margin-bottom: 0.5em;
155}
156div.title + * {
157 margin-top: 0;
158}
159
160td div.title:first-child {
161 margin-top: 0.0em;
162}
163div.content div.title:first-child {
164 margin-top: 0.0em;
165}
166div.content + div.title {
167 margin-top: 0.0em;
168}
169
170div.sidebarblock > div.content {
171 background: #ffffee;
172 border: 1px solid #dddddd;
173 border-left: 4px solid #f0f0f0;
174 padding: 0.5em;
175}
176
177div.listingblock > div.content {
178 border: 1px solid #dddddd;
179 border-left: 5px solid #f0f0f0;
180 background: #f8f8f8;
181 padding: 0.5em;
182}
183
184div.quoteblock, div.verseblock {
185 padding-left: 1.0em;
186 margin-left: 1.0em;
187 margin-right: 10%;
188 border-left: 5px solid #f0f0f0;
189 color: #888;
190}
191
192div.quoteblock > div.attribution {
193 padding-top: 0.5em;
194 text-align: right;
195}
196
197div.verseblock > pre.content {
198 font-family: inherit;
199 font-size: inherit;
200}
201div.verseblock > div.attribution {
202 padding-top: 0.75em;
203 text-align: left;
204}
205/* DEPRECATED: Pre version 8.2.7 verse style literal block. */
206div.verseblock + div.attribution {
207 text-align: left;
208}
209
210div.admonitionblock .icon {
211 vertical-align: top;
212 font-size: 1.1em;
213 font-weight: bold;
214 text-decoration: underline;
215 color: #527bbd;
216 padding-right: 0.5em;
217}
218div.admonitionblock td.content {
219 padding-left: 0.5em;
220 border-left: 3px solid #dddddd;
221}
222
223div.exampleblock > div.content {
224 border-left: 3px solid #dddddd;
225 padding-left: 0.5em;
226}
227
228div.imageblock div.content { padding-left: 0; }
229span.image img { border-style: none; vertical-align: text-bottom; }
230a.image:visited { color: white; }
231
232dl {
233 margin-top: 0.8em;
234 margin-bottom: 0.8em;
235}
236dt {
237 margin-top: 0.5em;
238 margin-bottom: 0;
239 font-style: normal;
240 color: navy;
241}
242dd > *:first-child {
243 margin-top: 0.1em;
244}
245
246ul, ol {
247 list-style-position: outside;
248}
249ol.arabic {
250 list-style-type: decimal;
251}
252ol.loweralpha {
253 list-style-type: lower-alpha;
254}
255ol.upperalpha {
256 list-style-type: upper-alpha;
257}
258ol.lowerroman {
259 list-style-type: lower-roman;
260}
261ol.upperroman {
262 list-style-type: upper-roman;
263}
264
265div.compact ul, div.compact ol,
266div.compact p, div.compact p,
267div.compact div, div.compact div {
268 margin-top: 0.1em;
269 margin-bottom: 0.1em;
270}
271
272tfoot {
273 font-weight: bold;
274}
275td > div.verse {
276 white-space: pre;
277}
278
279div.hdlist {
280 margin-top: 0.8em;
281 margin-bottom: 0.8em;
282}
283div.hdlist tr {
284 padding-bottom: 15px;
285}
286dt.hdlist1.strong, td.hdlist1.strong {
287 font-weight: bold;
288}
289td.hdlist1 {
290 vertical-align: top;
291 font-style: normal;
292 padding-right: 0.8em;
293 color: navy;
294}
295td.hdlist2 {
296 vertical-align: top;
297}
298div.hdlist.compact tr {
299 margin: 0;
300 padding-bottom: 0;
301}
302
303.comment {
304 background: yellow;
305}
306
307.footnote, .footnoteref {
308 font-size: 0.8em;
309}
310
311span.footnote, span.footnoteref {
312 vertical-align: super;
313}
314
315#footnotes {
316 margin: 20px 0 20px 0;
317 padding: 7px 0 0 0;
318}
319
320#footnotes div.footnote {
321 margin: 0 0 5px 0;
322}
323
324#footnotes hr {
325 border: none;
326 border-top: 1px solid silver;
327 height: 1px;
328 text-align: left;
329 margin-left: 0;
330 width: 20%;
331 min-width: 100px;
332}
333
334div.colist td {
335 padding-right: 0.5em;
336 padding-bottom: 0.3em;
337 vertical-align: top;
338}
339div.colist td img {
340 margin-top: 0.3em;
341}
342
343@media print {
344 #footer-badges { display: none; }
345}
346
347#toc {
348 margin-bottom: 2.5em;
349}
350
351#toctitle {
352 color: #527bbd;
353 font-size: 1.1em;
354 font-weight: bold;
355 margin-top: 1.0em;
356 margin-bottom: 0.1em;
357}
358
359div.toclevel0, div.toclevel1, div.toclevel2, div.toclevel3, div.toclevel4 {
360 margin-top: 0;
361 margin-bottom: 0;
362}
363div.toclevel2 {
364 margin-left: 2em;
365 font-size: 0.9em;
366}
367div.toclevel3 {
368 margin-left: 4em;
369 font-size: 0.9em;
370}
371div.toclevel4 {
372 margin-left: 6em;
373 font-size: 0.9em;
374}
375
376span.aqua { color: aqua; }
377span.black { color: black; }
378span.blue { color: blue; }
379span.fuchsia { color: fuchsia; }
380span.gray { color: gray; }
381span.green { color: green; }
382span.lime { color: lime; }
383span.maroon { color: maroon; }
384span.navy { color: navy; }
385span.olive { color: olive; }
386span.purple { color: purple; }
387span.red { color: red; }
388span.silver { color: silver; }
389span.teal { color: teal; }
390span.white { color: white; }
391span.yellow { color: yellow; }
392
393span.aqua-background { background: aqua; }
394span.black-background { background: black; }
395span.blue-background { background: blue; }
396span.fuchsia-background { background: fuchsia; }
397span.gray-background { background: gray; }
398span.green-background { background: green; }
399span.lime-background { background: lime; }
400span.maroon-background { background: maroon; }
401span.navy-background { background: navy; }
402span.olive-background { background: olive; }
403span.purple-background { background: purple; }
404span.red-background { background: red; }
405span.silver-background { background: silver; }
406span.teal-background { background: teal; }
407span.white-background { background: white; }
408span.yellow-background { background: yellow; }
409
410span.big { font-size: 2em; }
411span.small { font-size: 0.6em; }
412
413span.underline { text-decoration: underline; }
414span.overline { text-decoration: overline; }
415span.line-through { text-decoration: line-through; }
416
417div.unbreakable { page-break-inside: avoid; }
418
419
420/*
421 * xhtml11 specific
422 *
423 * */
424
425div.tableblock {
426 margin-top: 1.0em;
427 margin-bottom: 1.5em;
428}
429div.tableblock > table {
430 border: 3px solid #527bbd;
431}
432thead, p.table.header {
433 font-weight: bold;
434 color: #527bbd;
435}
436p.table {
437 margin-top: 0;
438}
439/* Because the table frame attribute is overridden by CSS in most browsers. */
440div.tableblock > table[frame="void"] {
441 border-style: none;
442}
443div.tableblock > table[frame="hsides"] {
444 border-left-style: none;
445 border-right-style: none;
446}
447div.tableblock > table[frame="vsides"] {
448 border-top-style: none;
449 border-bottom-style: none;
450}
451
452
453/*
454 * html5 specific
455 *
456 * */
457
458table.tableblock {
459 margin-top: 1.0em;
460 margin-bottom: 1.5em;
461}
462thead, p.tableblock.header {
463 font-weight: bold;
464 color: #527bbd;
465}
466p.tableblock {
467 margin-top: 0;
468}
469table.tableblock {
470 border-width: 3px;
471 border-spacing: 0px;
472 border-style: solid;
473 border-color: #527bbd;
474 border-collapse: collapse;
475}
476th.tableblock, td.tableblock {
477 border-width: 1px;
478 padding: 4px;
479 border-style: solid;
480 border-color: #527bbd;
481}
482
483table.tableblock.frame-topbot {
484 border-left-style: hidden;
485 border-right-style: hidden;
486}
487table.tableblock.frame-sides {
488 border-top-style: hidden;
489 border-bottom-style: hidden;
490}
491table.tableblock.frame-none {
492 border-style: hidden;
493}
494
495th.tableblock.halign-left, td.tableblock.halign-left {
496 text-align: left;
497}
498th.tableblock.halign-center, td.tableblock.halign-center {
499 text-align: center;
500}
501th.tableblock.halign-right, td.tableblock.halign-right {
502 text-align: right;
503}
504
505th.tableblock.valign-top, td.tableblock.valign-top {
506 vertical-align: top;
507}
508th.tableblock.valign-middle, td.tableblock.valign-middle {
509 vertical-align: middle;
510}
511th.tableblock.valign-bottom, td.tableblock.valign-bottom {
512 vertical-align: bottom;
513}
514
515
516/*
517 * manpage specific
518 *
519 * */
520
521body.manpage h1 {
522 padding-top: 0.5em;
523 padding-bottom: 0.5em;
524 border-top: 2px solid silver;
525 border-bottom: 2px solid silver;
526}
527body.manpage h2 {
528 border-style: none;
529}
530body.manpage div.sectionbody {
531 margin-left: 3em;
532}
533
534@media print {
535 body.manpage div#toc { display: none; }
536}
537
538
539</style>
540<script type="text/javascript">
541/*<![CDATA[*/
542var asciidoc = { // Namespace.
543
544/////////////////////////////////////////////////////////////////////
545// Table Of Contents generator
546/////////////////////////////////////////////////////////////////////
547
548/* Author: Mihai Bazon, September 2002
549 * http://students.infoiasi.ro/~mishoo
550 *
551 * Table Of Content generator
552 * Version: 0.4
553 *
554 * Feel free to use this script under the terms of the GNU General Public
555 * License, as long as you do not remove or alter this notice.
556 */
557
558 /* modified by Troy D. Hanson, September 2006. License: GPL */
559 /* modified by Stuart Rackham, 2006, 2009. License: GPL */
560
561// toclevels = 1..4.
562toc: function (toclevels) {
563
564 function getText(el) {
565 var text = "";
566 for (var i = el.firstChild; i != null; i = i.nextSibling) {
567 if (i.nodeType == 3 /* Node.TEXT_NODE */) // IE doesn't speak constants.
568 text += i.data;
569 else if (i.firstChild != null)
570 text += getText(i);
571 }
572 return text;
573 }
574
575 function TocEntry(el, text, toclevel) {
576 this.element = el;
577 this.text = text;
578 this.toclevel = toclevel;
579 }
580
581 function tocEntries(el, toclevels) {
582 var result = new Array;
583 var re = new RegExp('[hH]([1-'+(toclevels+1)+'])');
584 // Function that scans the DOM tree for header elements (the DOM2
585 // nodeIterator API would be a better technique but not supported by all
586 // browsers).
587 var iterate = function (el) {
588 for (var i = el.firstChild; i != null; i = i.nextSibling) {
589 if (i.nodeType == 1 /* Node.ELEMENT_NODE */) {
590 var mo = re.exec(i.tagName);
591 if (mo && (i.getAttribute("class") || i.getAttribute("className")) != "float") {
592 result[result.length] = new TocEntry(i, getText(i), mo[1]-1);
593 }
594 iterate(i);
595 }
596 }
597 }
598 iterate(el);
599 return result;
600 }
601
602 var toc = document.getElementById("toc");
603 if (!toc) {
604 return;
605 }
606
607 // Delete existing TOC entries in case we're reloading the TOC.
608 var tocEntriesToRemove = [];
609 var i;
610 for (i = 0; i < toc.childNodes.length; i++) {
611 var entry = toc.childNodes[i];
612 if (entry.nodeName.toLowerCase() == 'div'
613 && entry.getAttribute("class")
614 && entry.getAttribute("class").match(/^toclevel/))
615 tocEntriesToRemove.push(entry);
616 }
617 for (i = 0; i < tocEntriesToRemove.length; i++) {
618 toc.removeChild(tocEntriesToRemove[i]);
619 }
620
621 // Rebuild TOC entries.
622 var entries = tocEntries(document.getElementById("content"), toclevels);
623 for (var i = 0; i < entries.length; ++i) {
624 var entry = entries[i];
625 if (entry.element.id == "")
626 entry.element.id = "_toc_" + i;
627 var a = document.createElement("a");
628 a.href = "#" + entry.element.id;
629 a.appendChild(document.createTextNode(entry.text));
630 var div = document.createElement("div");
631 div.appendChild(a);
632 div.className = "toclevel" + entry.toclevel;
633 toc.appendChild(div);
634 }
635 if (entries.length == 0)
636 toc.parentNode.removeChild(toc);
637},
638
639
640/////////////////////////////////////////////////////////////////////
641// Footnotes generator
642/////////////////////////////////////////////////////////////////////
643
644/* Based on footnote generation code from:
645 * http://www.brandspankingnew.net/archive/2005/07/format_footnote.html
646 */
647
648footnotes: function () {
649 // Delete existing footnote entries in case we're reloading the footnodes.
650 var i;
651 var noteholder = document.getElementById("footnotes");
652 if (!noteholder) {
653 return;
654 }
655 var entriesToRemove = [];
656 for (i = 0; i < noteholder.childNodes.length; i++) {
657 var entry = noteholder.childNodes[i];
658 if (entry.nodeName.toLowerCase() == 'div' && entry.getAttribute("class") == "footnote")
659 entriesToRemove.push(entry);
660 }
661 for (i = 0; i < entriesToRemove.length; i++) {
662 noteholder.removeChild(entriesToRemove[i]);
663 }
664
665 // Rebuild footnote entries.
666 var cont = document.getElementById("content");
667 var spans = cont.getElementsByTagName("span");
668 var refs = {};
669 var n = 0;
670 for (i=0; i<spans.length; i++) {
671 if (spans[i].className == "footnote") {
672 n++;
673 var note = spans[i].getAttribute("data-note");
674 if (!note) {
675 // Use [\s\S] in place of . so multi-line matches work.
676 // Because JavaScript has no s (dotall) regex flag.
677 note = spans[i].innerHTML.match(/\s*\[([\s\S]*)]\s*/)[1];
678 spans[i].innerHTML =
679 "[<a id='_footnoteref_" + n + "' href='#_footnote_" + n +
680 "' title='View footnote' class='footnote'>" + n + "</a>]";
681 spans[i].setAttribute("data-note", note);
682 }
683 noteholder.innerHTML +=
684 "<div class='footnote' id='_footnote_" + n + "'>" +
685 "<a href='#_footnoteref_" + n + "' title='Return to text'>" +
686 n + "</a>. " + note + "</div>";
687 var id =spans[i].getAttribute("id");
688 if (id != null) refs["#"+id] = n;
689 }
690 }
691 if (n == 0)
692 noteholder.parentNode.removeChild(noteholder);
693 else {
694 // Process footnoterefs.
695 for (i=0; i<spans.length; i++) {
696 if (spans[i].className == "footnoteref") {
697 var href = spans[i].getElementsByTagName("a")[0].getAttribute("href");
698 href = href.match(/#.*/)[0]; // Because IE return full URL.
699 n = refs[href];
700 spans[i].innerHTML =
701 "[<a href='#_footnote_" + n +
702 "' title='View footnote' class='footnote'>" + n + "</a>]";
703 }
704 }
705 }
706},
707
708install: function(toclevels) {
709 var timerId;
710
711 function reinstall() {
712 asciidoc.footnotes();
713 if (toclevels) {
714 asciidoc.toc(toclevels);
715 }
716 }
717
718 function reinstallAndRemoveTimer() {
719 clearInterval(timerId);
720 reinstall();
721 }
722
723 timerId = setInterval(reinstall, 500);
724 if (document.addEventListener)
725 document.addEventListener("DOMContentLoaded", reinstallAndRemoveTimer, false);
726 else
727 window.onload = reinstallAndRemoveTimer;
728}
729
730}
731asciidoc.install();
732/*]]>*/
733</script>
734</head>
735<body class="manpage">
736<div id="header">
737<h1>
738gitformat-commit-graph(5) Manual Page
739</h1>
740<h2>NAME</h2>
741<div class="sectionbody">
742<p>gitformat-commit-graph -
Junio C Hamanoe8c74d82022-11-12 07:59:36743 Git commit-graph format
Junio C Hamano04495a12022-08-18 21:13:08744</p>
745</div>
746</div>
747<div id="content">
748<div class="sect1">
749<h2 id="_synopsis">SYNOPSIS</h2>
750<div class="sectionbody">
751<div class="verseblock">
752<pre class="content">$GIT_DIR/objects/info/commit-graph
753$GIT_DIR/objects/info/commit-graphs/*</pre>
754<div class="attribution">
755</div></div>
756</div>
757</div>
758<div class="sect1">
759<h2 id="_description">DESCRIPTION</h2>
760<div class="sectionbody">
Junio C Hamanoe8c74d82022-11-12 07:59:36761<div class="paragraph"><p>The Git commit-graph stores a list of commit OIDs and some associated
Junio C Hamano04495a12022-08-18 21:13:08762metadata, including:</p></div>
763<div class="ulist"><ul>
764<li>
765<p>
766The generation number of the commit.
767</p>
768</li>
769<li>
770<p>
771The root tree OID.
772</p>
773</li>
774<li>
775<p>
776The commit date.
777</p>
778</li>
779<li>
780<p>
781The parents of the commit, stored using positional references within
782 the graph file.
783</p>
784</li>
785<li>
786<p>
787The Bloom filter of the commit carrying the paths that were changed between
788 the commit and its first parent, if requested.
789</p>
790</li>
791</ul></div>
792<div class="paragraph"><p>These positional references are stored as unsigned 32-bit integers
793corresponding to the array position within the list of commit OIDs. Due
794to some special constants we use to track parents, we can store at most
795(1 &lt;&lt; 30) + (1 &lt;&lt; 29) + (1 &lt;&lt; 28) - 1 (around 1.8 billion) commits.</p></div>
796</div>
797</div>
798<div class="sect1">
Junio C Hamanoe8c74d82022-11-12 07:59:36799<h2 id="_commit_graph_files_have_the_following_format">Commit-graph files have the following format:</h2>
Junio C Hamano04495a12022-08-18 21:13:08800<div class="sectionbody">
801<div class="paragraph"><p>In order to allow extensions that add extra data to the graph, we organize
802the body into "chunks" and provide a binary lookup table at the beginning
803of the body. The header includes certain values, such as number of chunks
804and hash type.</p></div>
805<div class="paragraph"><p>All multi-byte numbers are in network byte order.</p></div>
806<div class="sect2">
807<h3 id="_header">HEADER:</h3>
808<div class="literalblock">
809<div class="content">
810<pre><code>4-byte signature:
811 The signature is: {'C', 'G', 'P', 'H'}</code></pre>
812</div></div>
813<div class="literalblock">
814<div class="content">
815<pre><code>1-byte version number:
816 Currently, the only valid version is 1.</code></pre>
817</div></div>
818<div class="literalblock">
819<div class="content">
820<pre><code>1-byte Hash Version
821 We infer the hash length (H) from this value:
822 1 =&gt; SHA-1
823 2 =&gt; SHA-256
824 If the hash type does not match the repository's hash algorithm, the
825 commit-graph file should be ignored with a warning presented to the
826 user.</code></pre>
827</div></div>
828<div class="literalblock">
829<div class="content">
830<pre><code>1-byte number (C) of "chunks"</code></pre>
831</div></div>
832<div class="literalblock">
833<div class="content">
834<pre><code>1-byte number (B) of base commit-graphs
835 We infer the length (H*B) of the Base Graphs chunk
836 from this value.</code></pre>
837</div></div>
838</div>
839<div class="sect2">
840<h3 id="_chunk_lookup">CHUNK LOOKUP:</h3>
841<div class="literalblock">
842<div class="content">
843<pre><code>(C + 1) * 12 bytes listing the table of contents for the chunks:
844 First 4 bytes describe the chunk id. Value 0 is a terminating label.
845 Other 8 bytes provide the byte-offset in current file for chunk to
846 start. (Chunks are ordered contiguously in the file, so you can infer
847 the length using the next chunk position if necessary.) Each chunk
848 ID appears at most once.</code></pre>
849</div></div>
850<div class="literalblock">
851<div class="content">
852<pre><code>The CHUNK LOOKUP matches the table of contents from
853the chunk-based file format, see linkgit:gitformat-chunk[5]</code></pre>
854</div></div>
855<div class="literalblock">
856<div class="content">
857<pre><code>The remaining data in the body is described one chunk at a time, and
858these chunks may be given in any order. Chunks are required unless
859otherwise specified.</code></pre>
860</div></div>
861</div>
862<div class="sect2">
863<h3 id="_chunk_data">CHUNK DATA:</h3>
864<div class="sect3">
865<h4 id="_oid_fanout_id_em_o_em_em_i_em_em_d_em_em_f_em_256_4_bytes">OID Fanout (ID: {<em>O</em>, <em>I</em>, <em>D</em>, <em>F</em>}) (256 * 4 bytes)</h4>
866<div class="literalblock">
867<div class="content">
868<pre><code>The ith entry, F[i], stores the number of OIDs with first
869byte at most i. Thus F[255] stores the total
870number of commits (N).</code></pre>
871</div></div>
872</div>
873<div class="sect3">
874<h4 id="_oid_lookup_id_em_o_em_em_i_em_em_d_em_em_l_em_n_h_bytes">OID Lookup (ID: {<em>O</em>, <em>I</em>, <em>D</em>, <em>L</em>}) (N * H bytes)</h4>
875<div class="literalblock">
876<div class="content">
877<pre><code>The OIDs for all commits in the graph, sorted in ascending order.</code></pre>
878</div></div>
879</div>
880<div class="sect3">
881<h4 id="_commit_data_id_em_c_em_em_d_em_em_a_em_em_t_em_n_h_16_bytes">Commit Data (ID: {<em>C</em>, <em>D</em>, <em>A</em>, <em>T</em> }) (N * (H + 16) bytes)</h4>
882<div class="ulist"><ul>
883<li>
884<p>
885The first H bytes are for the OID of the root tree.
886</p>
887</li>
888<li>
889<p>
890The next 8 bytes are for the positions of the first two parents
891 of the ith commit. Stores value 0x70000000 if no parent in that
892 position. If there are more than two parents, the second value
893 has its most-significant bit on and the other bits store an array
894 position into the Extra Edge List chunk.
895</p>
896</li>
897<li>
898<p>
899The next 8 bytes store the topological level (generation number v1)
900 of the commit and
901 the commit time in seconds since EPOCH. The generation number
902 uses the higher 30 bits of the first 4 bytes, while the commit
903 time uses the 32 bits of the second 4 bytes, along with the lowest
904 2 bits of the lowest byte, storing the 33rd and 34th bit of the
905 commit time.
906</p>
907</li>
908</ul></div>
909</div>
910<div class="sect3">
911<h4 id="_generation_data_id_em_g_em_em_d_em_em_a_em_em_2_em_n_4_bytes_optional">Generation Data (ID: {<em>G</em>, <em>D</em>, <em>A</em>, <em>2</em> }) (N * 4 bytes) [Optional]</h4>
912<div class="ulist"><ul>
913<li>
914<p>
915This list of 4-byte values store corrected commit date offsets for the
916 commits, arranged in the same order as commit data chunk.
917</p>
918</li>
919<li>
920<p>
921If the corrected commit date offset cannot be stored within 31 bits,
922 the value has its most-significant bit on and the other bits store
923 the position of corrected commit date into the Generation Data Overflow
924 chunk.
925</p>
926</li>
927<li>
928<p>
929Generation Data chunk is present only when commit-graph file is written
930 by compatible versions of Git and in case of split commit-graph chains,
931 the topmost layer also has Generation Data chunk.
932</p>
933</li>
934</ul></div>
935</div>
936<div class="sect3">
937<h4 id="_generation_data_overflow_id_em_g_em_em_d_em_em_o_em_em_2_em_optional">Generation Data Overflow (ID: {<em>G</em>, <em>D</em>, <em>O</em>, <em>2</em> }) [Optional]</h4>
938<div class="ulist"><ul>
939<li>
940<p>
941This list of 8-byte values stores the corrected commit date offsets
942 for commits with corrected commit date offsets that cannot be
943 stored within 31 bits.
944</p>
945</li>
946<li>
947<p>
948Generation Data Overflow chunk is present only when Generation Data
949 chunk is present and atleast one corrected commit date offset cannot
950 be stored within 31 bits.
951</p>
952</li>
953</ul></div>
954</div>
955<div class="sect3">
956<h4 id="_extra_edge_list_id_em_e_em_em_d_em_em_g_em_em_e_em_optional">Extra Edge List (ID: {<em>E</em>, <em>D</em>, <em>G</em>, <em>E</em>}) [Optional]</h4>
957<div class="literalblock">
958<div class="content">
959<pre><code>This list of 4-byte values store the second through nth parents for
960all octopus merges. The second parent value in the commit data stores
961an array position within this list along with the most-significant bit
962on. Starting at that array position, iterate through this list of commit
963positions for the parents until reaching a value with the most-significant
964bit on. The other bits correspond to the position of the last parent.</code></pre>
965</div></div>
966</div>
967<div class="sect3">
968<h4 id="_bloom_filter_index_id_em_b_em_em_i_em_em_d_em_em_x_em_n_4_bytes_optional">Bloom Filter Index (ID: {<em>B</em>, <em>I</em>, <em>D</em>, <em>X</em>}) (N * 4 bytes) [Optional]</h4>
969<div class="ulist"><ul>
970<li>
971<p>
972The ith entry, BIDX[i], stores the number of bytes in all Bloom filters
973 from commit 0 to commit i (inclusive) in lexicographic order. The Bloom
974 filter for the i-th commit spans from BIDX[i-1] to BIDX[i] (plus header
975 length), where BIDX[-1] is 0.
976</p>
977</li>
978<li>
979<p>
980The BIDX chunk is ignored if the BDAT chunk is not present.
981</p>
982</li>
983</ul></div>
984</div>
985<div class="sect3">
986<h4 id="_bloom_filter_data_id_em_b_em_em_d_em_em_a_em_em_t_em_optional">Bloom Filter Data (ID: {<em>B</em>, <em>D</em>, <em>A</em>, <em>T</em>}) [Optional]</h4>
987<div class="ulist"><ul>
988<li>
989<p>
990It starts with header consisting of three unsigned 32-bit integers:
991</p>
992<div class="ulist"><ul>
993<li>
994<p>
995Version of the hash algorithm being used. We currently only support
996 value 1 which corresponds to the 32-bit version of the murmur3 hash
997 implemented exactly as described in
998 <a href="https://en.wikipedia.org/wiki/MurmurHash#Algorithm">https://en.wikipedia.org/wiki/MurmurHash#Algorithm</a> and the double
999 hashing technique using seed values 0x293ae76f and 0x7e646e2 as
1000 described in <a href="https://doi.org/10.1007/978-3-540-30494-4_26">https://doi.org/10.1007/978-3-540-30494-4_26</a> "Bloom Filters
1001 in Probabilistic Verification"
1002</p>
1003</li>
1004<li>
1005<p>
1006The number of times a path is hashed and hence the number of bit positions
1007 that cumulatively determine whether a file is present in the commit.
1008</p>
1009</li>
1010<li>
1011<p>
1012The minimum number of bits <em>b</em> per entry in the Bloom filter. If the filter
1013 contains <em>n</em> entries, then the filter size is the minimum number of 64-bit
1014 words that contain n*b bits.
1015</p>
1016</li>
1017</ul></div>
1018</li>
1019<li>
1020<p>
1021The rest of the chunk is the concatenation of all the computed Bloom
1022 filters for the commits in lexicographic order.
1023</p>
1024</li>
1025<li>
1026<p>
1027Note: Commits with no changes or more than 512 changes have Bloom filters
1028 of length one, with either all bits set to zero or one respectively.
1029</p>
1030</li>
1031<li>
1032<p>
1033The BDAT chunk is present if and only if BIDX is present.
1034</p>
1035</li>
1036</ul></div>
1037</div>
1038<div class="sect3">
1039<h4 id="_base_graphs_list_id_em_b_em_em_a_em_em_s_em_em_e_em_optional">Base Graphs List (ID: {<em>B</em>, <em>A</em>, <em>S</em>, <em>E</em>}) [Optional]</h4>
1040<div class="literalblock">
1041<div class="content">
1042<pre><code>This list of H-byte hashes describe a set of B commit-graph files that
1043form a commit-graph chain. The graph position for the ith commit in this
1044file's OID Lookup chunk is equal to i plus the number of commits in all
1045base graphs. If B is non-zero, this chunk must exist.</code></pre>
1046</div></div>
1047</div>
1048</div>
1049<div class="sect2">
1050<h3 id="_trailer">TRAILER:</h3>
1051<div class="literalblock">
1052<div class="content">
1053<pre><code>H-byte HASH-checksum of all of the above.</code></pre>
1054</div></div>
1055</div>
1056</div>
1057</div>
1058<div class="sect1">
1059<h2 id="_historical_notes">Historical Notes:</h2>
1060<div class="sectionbody">
1061<div class="paragraph"><p>The Generation Data (GDA2) and Generation Data Overflow (GDO2) chunks have
1062the number <em>2</em> in their chunk IDs because a previous version of Git wrote
1063possibly erroneous data in these chunks with the IDs "GDAT" and "GDOV". By
1064changing the IDs, newer versions of Git will silently ignore those older
1065chunks and write the new information without trusting the incorrect data.</p></div>
1066</div>
1067</div>
1068<div class="sect1">
1069<h2 id="_git">GIT</h2>
1070<div class="sectionbody">
1071<div class="paragraph"><p>Part of the <a href="git.html">git(1)</a> suite</p></div>
1072</div>
1073</div>
1074</div>
1075<div id="footnotes"><hr /></div>
1076<div id="footer">
1077<div id="footer-text">
1078Last updated
Junio C Hamano918a6972023-10-29 23:44:111079 2022-11-12 16:55:30 JST
Junio C Hamano04495a12022-08-18 21:13:081080</div>
1081</div>
1082</body>
1083</html>