Skip to content

Commit f485740

Browse files
vdyederrickstolee
andcommitted
docs: add bundle URI download flowcharts
Add flowcharts documenting how the bundle URI feature in Git downloads from the bundle server. Co-authored-by: Derrick Stolee <[email protected]> Signed-off-by: Victoria Dye <[email protected]>
1 parent a67c4c1 commit f485740

File tree

1 file changed

+156
-0
lines changed

1 file changed

+156
-0
lines changed

docs/technical/architecture.md

+156
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,159 @@ bundles][bundle-uri-fetch] according to the `creationToken` heuristic before
9191
fetching from the origin remote.
9292

9393
[bundle-uri-fetch]: https://git-scm.com/docs/bundle-uri#_fetching_with_bundle_uris
94+
95+
## Use with `git`
96+
97+
Although the contents of the bundle server can be downloaded manually, the
98+
intended use case of the bundle server is to supplement clones & fetches in Git.
99+
100+
In the following diagrams, we will be assuming use of characteristics matching
101+
_this_ bundle server implementation, namely the `creationToken` heuristic.
102+
Behavior in Git may differ if using a different server implementation.
103+
104+
### Downloading and unpacking a bundle list
105+
106+
The recommended use of this bundle server is as a source for a "bundle list": an
107+
ordered list of base and incremental bundles that, in order, can be downloaded
108+
and unbundled to populate the requested commits in a fetch or clone. At the core
109+
of the bundle URI code in both `git clone` and `git fetch` is a common process
110+
for downloading and unpacking the contents of a bundle list. The process is as
111+
follows:
112+
113+
```mermaid
114+
%%{ init: { 'flowchart': { 'curve': 'monotoneX' } } }%%
115+
flowchart TB;
116+
start{"Start"}
117+
subgraph downloadAndUnbundle["Download and unbundle from list"]
118+
direction TB
119+
120+
parse["Parse bundle list"]
121+
sort["Sort bundles by creationToken,\nhigh to low, select bundle with\nhighest creationToken"]
122+
creationToken{{"Current creationToken >= <code>minCreationToken</code>?"}}
123+
reqBundle["Request bundle from server"]
124+
downloadSuccess{{"Download successful?"}}
125+
markUnbundled["Mark unbundled"]
126+
markUnbundledSkip["Mark unbundled to\navoid retrying later"]
127+
moveDeeper{{"Are there more not-yet-unbundled bundles\nwith <i>lower</i> creationTokens?"}}
128+
unbundleReq["Unbundle downloaded bundle"]
129+
moveShallower{{"Are there more not-yet-unbundled bundles\nwith <i>higher</i> creationTokens?"}}
130+
unbundleSuccess{{"Successfully unbundled? (not\nmissing any required commits)"}}
131+
end
132+
bundleServer[(Bundle Server)]
133+
done{"Done"}
134+
135+
style downloadAndUnbundle fill:#28865477
136+
137+
start --> parse --> sort --> creationToken
138+
creationToken --> |No| done
139+
creationToken --> |Yes| reqBundle
140+
reqBundle --> downloadSuccess
141+
downloadSuccess --> |No| markUnbundledSkip
142+
markUnbundledSkip --> moveDeeper
143+
moveDeeper --> |Yes, select next as\ncurrent bundle| creationToken
144+
moveDeeper --> |No| done
145+
reqBundle <--> bundleServer
146+
147+
downloadSuccess --> |Yes| unbundleReq
148+
unbundleReq --> unbundleSuccess
149+
unbundleSuccess ----> |No| moveDeeper
150+
unbundleSuccess --> |Yes| markUnbundled --> moveShallower
151+
moveShallower --> |No| done
152+
moveShallower --> |Yes, select next as\ncurrent bundle| unbundleReq
153+
154+
```
155+
156+
157+
158+
Note that this flow requires a `minCreationToken`: a creationToken value used to
159+
avoid redundant downloads of old bundles. This value depends on whether the
160+
algorithm is called from `git clone` or `git fetch`. Details on how this value
161+
is determined can be found in later sections.
162+
163+
### `git clone`
164+
165+
When performing an initial clone from a remote repository, the `--bundle-uri`
166+
option can point to a bundle list (recommended with this server) or to a single
167+
base bundle. In the case of a bundle list, the bundle URI will be stored along
168+
with a `minCreationToken` value in the repository config for subsequent fetches.
169+
170+
```mermaid
171+
%%{ init: { 'flowchart': { 'curve': 'monotoneX' } } }%%
172+
flowchart TB;
173+
user((User))
174+
subgraph git
175+
direction TB
176+
177+
setBundleUri["Set <code>bundleUri</code> to the value of --bundle-uri"]
178+
downloadUri["Download from <code>bundleUri</code>"]
179+
downloadType{{"What is downloaded?"}}
180+
unbundle["Unbundle response"]
181+
setCreationToken["Set <code>minCreationToken</code> to 0"]
182+
downloadAndUnbundle(["Download and unbundle from list"])
183+
bundleSuccess{{"Bundles downloaded and unpacked successfully?"}}
184+
saveUri["Set fetch.bundleUri to <code>bundleUri</code>"]
185+
saveCreationToken["Set fetch.bundleCreationToken to highest\nunbundled creationToken"]
186+
incrementalFetch["Incremental fetch from origin"]
187+
188+
style downloadAndUnbundle fill:#288654,color:#000000
189+
end
190+
bundleServer[(Bundle Server)]
191+
origin[(Remote host)]
192+
193+
user --> |"git clone --bundle-uri URI"| setBundleUri
194+
downloadUri <--> bundleServer
195+
setBundleUri --> downloadUri --> downloadType
196+
downloadType --> |Single bundle| unbundle
197+
unbundle --> incrementalFetch
198+
downloadType --> |Other| incrementalFetch
199+
downloadType --> |Bundle list| setCreationToken
200+
setCreationToken --> downloadAndUnbundle --> bundleSuccess
201+
bundleSuccess --> |Yes| saveUri
202+
downloadAndUnbundle <---> bundleServer
203+
bundleSuccess --> |No| incrementalFetch
204+
saveUri --> saveCreationToken --> incrementalFetch
205+
incrementalFetch <--> origin
206+
```
207+
208+
### `git fetch`
209+
210+
After successfully cloning with a bundle list URI (recommended) or manually
211+
setting `fetch.bundleUri`, `git fetch` will try to download and unpack recent
212+
bundles containing new commits.
213+
214+
```mermaid
215+
%%{ init: { 'flowchart': { 'curve': 'monotoneX' } } }%%
216+
flowchart TB;
217+
user((User))
218+
subgraph git
219+
direction TB
220+
221+
bundleUriExists{{"fetch.bundleUri config is set?"}}
222+
setBundleUri["Set <code>bundleUri</code> to the value of fetch.bundleUri"]
223+
creationTokenExists{{"fetch.bundleCreationToken config is set?"}}
224+
setCreationToken["Set <code>minCreationToken</code> to the value\nof fetch.bundleCreationToken"]
225+
setCreationTokenZero["Set <code>creationToken</code> to 0"]
226+
downloadAndUnbundle(["Download and unbundle from list"])
227+
bundleSuccess{{"Bundles downloaded and unpacked successfully?"}}
228+
saveCreationToken["Set fetch.bundleCreationToken to highest\nunbundled creationToken"]
229+
incrementalFetch["Incremental fetch from origin"]
230+
231+
style downloadAndUnbundle fill:#288654,color:#000000
232+
end
233+
bundleServer[(Bundle Server)]
234+
origin[(Remote host)]
235+
236+
user --> |"git fetch"| bundleUriExists
237+
bundleUriExists --> |Yes| setBundleUri
238+
bundleUriExists --> |No| incrementalFetch
239+
setBundleUri --> creationTokenExists
240+
creationTokenExists --> |Yes| setCreationToken
241+
creationTokenExists --> |No| setCreationTokenZero
242+
setCreationToken & setCreationTokenZero --> downloadAndUnbundle
243+
downloadAndUnbundle <--> bundleServer
244+
downloadAndUnbundle --> bundleSuccess
245+
bundleSuccess --> |Yes| saveCreationToken
246+
bundleSuccess --> |No| incrementalFetch
247+
saveCreationToken --> incrementalFetch
248+
incrementalFetch <--> origin
249+
```

0 commit comments

Comments
 (0)