@@ -127,6 +127,65 @@ Design Details
127
127
helpful for these clones, anyway. The commit-graph will not be read or
128
128
written when shallow commits are present.
129
129
130
+ Commit Graphs Chains
131
+ --------------------
132
+
133
+ Typically, repos grow with near-constant velocity (commits per day). Over time,
134
+ the number of commits added by a fetch operation is much smaller than the
135
+ number of commits in the full history. By creating a "chain" of commit-graphs,
136
+ we enable fast writes of new commit data without rewriting the entire commit
137
+ history -- at least, most of the time.
138
+
139
+ ## File Layout
140
+
141
+ A commit-graph chain uses multiple files, and we use a fixed naming convention
142
+ to organize these files. Each commit-graph file has a name
143
+ `$OBJDIR/info/commit-graphs/graph-{hash}.graph` where `{hash}` is the hex-
144
+ valued hash stored in the footer of that file (which is a hash of the file's
145
+ contents before that hash). For a chain of commit-graph files, a plain-text
146
+ file at `$OBJDIR/info/commit-graphs/commit-graph-chain` contains the
147
+ hashes for the files in order from "lowest" to "highest".
148
+
149
+ For example, if the `commit-graph-chain` file contains the lines
150
+
151
+ ```
152
+ {hash0}
153
+ {hash1}
154
+ {hash2}
155
+ ```
156
+
157
+ then the commit-graph chain looks like the following diagram:
158
+
159
+ +-----------------------+
160
+ | graph-{hash2}.graph |
161
+ +-----------------------+
162
+ |
163
+ +-----------------------+
164
+ | |
165
+ | graph-{hash1}.graph |
166
+ | |
167
+ +-----------------------+
168
+ |
169
+ +-----------------------+
170
+ | |
171
+ | |
172
+ | |
173
+ | graph-{hash0}.graph |
174
+ | |
175
+ | |
176
+ | |
177
+ +-----------------------+
178
+
179
+ Let X0 be the number of commits in `graph-{hash0}.graph`, X1 be the number of
180
+ commits in `graph-{hash1}.graph`, and X2 be the number of commits in
181
+ `graph-{hash2}.graph`. If a commit appears in position i in `graph-{hash2}.graph`,
182
+ then we interpret this as being the commit in position (X0 + X1 + i), and that
183
+ will be used as its "graph position". The commits in `graph-{hash2}.graph` use these
184
+ positions to refer to their parents, which may be in `graph-{hash1}.graph` or
185
+ `graph-{hash0}.graph`. We can navigate to an arbitrary commit in position j by checking
186
+ its containment in the intervals [0, X0), [X0, X0 + X1), [X0 + X1, X0 + X1 +
187
+ X2).
188
+
130
189
Related Links
131
190
-------------
132
191
[0] https://bugs.chromium.org/p/git/issues/detail?id=8
0 commit comments