Skip to content

Commit cbddee1

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 cbddee1

File tree

1 file changed

+154
-0
lines changed

1 file changed

+154
-0
lines changed

docs/technical/architecture.md

+154
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,157 @@ 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+
Note that this flow requires a `minCreationToken`: a creationToken value used to
157+
avoid redundant downloads of old bundles. This value depends on whether the
158+
algorithm is called from `git clone` or `git fetch`. Details on how this value
159+
is determined can be found in later sections.
160+
161+
### `git clone`
162+
163+
When performing an initial clone from a remote repository, the `--bundle-uri`
164+
option can point to a bundle list (recommended with this server) or to a single
165+
base bundle. In the case of a bundle list, the bundle URI will be stored along
166+
with a `minCreationToken` value in the repository config for subsequent fetches.
167+
168+
```mermaid
169+
%%{ init: { 'flowchart': { 'curve': 'monotoneX' } } }%%
170+
flowchart TB;
171+
user((User))
172+
subgraph git
173+
direction TB
174+
175+
setBundleUri["Set <code>bundleUri</code> to the value of --bundle-uri"]
176+
downloadUri["Download from <code>bundleUri</code>"]
177+
downloadType{{"What is downloaded?"}}
178+
unbundle["Unbundle response"]
179+
setCreationToken["Set <code>minCreationToken</code> to 0"]
180+
downloadAndUnbundle(["Download and unbundle from list"])
181+
bundleSuccess{{"Bundles downloaded and unpacked successfully?"}}
182+
saveUri["Set fetch.bundleUri to <code>bundleUri</code>"]
183+
saveCreationToken["Set fetch.bundleCreationToken to highest\nunbundled creationToken"]
184+
incrementalFetch["Incremental fetch from origin"]
185+
186+
style downloadAndUnbundle fill:#288654,color:#000000
187+
end
188+
bundleServer[(Bundle Server)]
189+
origin[(Remote host)]
190+
191+
user --> |"git clone --bundle-uri URI"| setBundleUri
192+
downloadUri <--> bundleServer
193+
setBundleUri --> downloadUri --> downloadType
194+
downloadType --> |Single bundle| unbundle
195+
unbundle --> incrementalFetch
196+
downloadType --> |Other| incrementalFetch
197+
downloadType --> |Bundle list| setCreationToken
198+
setCreationToken --> downloadAndUnbundle --> bundleSuccess
199+
bundleSuccess --> |Yes| saveUri
200+
downloadAndUnbundle <---> bundleServer
201+
bundleSuccess --> |No| incrementalFetch
202+
saveUri --> saveCreationToken --> incrementalFetch
203+
incrementalFetch <--> origin
204+
```
205+
206+
### `git fetch`
207+
208+
After successfully cloning with a bundle list URI (recommended) or manually
209+
setting `fetch.bundleUri`, `git fetch` will try to download and unpack recent
210+
bundles containing new commits.
211+
212+
```mermaid
213+
%%{ init: { 'flowchart': { 'curve': 'monotoneX' } } }%%
214+
flowchart TB;
215+
user((User))
216+
subgraph git
217+
direction TB
218+
219+
bundleUriExists{{"fetch.bundleUri config is set?"}}
220+
setBundleUri["Set <code>bundleUri</code> to the value of fetch.bundleUri"]
221+
creationTokenExists{{"fetch.bundleCreationToken config is set?"}}
222+
setCreationToken["Set <code>minCreationToken</code> to the value\nof fetch.bundleCreationToken"]
223+
setCreationTokenZero["Set <code>creationToken</code> to 0"]
224+
downloadAndUnbundle(["Download and unbundle from list"])
225+
bundleSuccess{{"Bundles downloaded and unpacked successfully?"}}
226+
saveCreationToken["Set fetch.bundleCreationToken to highest\nunbundled creationToken"]
227+
incrementalFetch["Incremental fetch from origin"]
228+
229+
style downloadAndUnbundle fill:#288654,color:#000000
230+
end
231+
bundleServer[(Bundle Server)]
232+
origin[(Remote host)]
233+
234+
user --> |"git fetch"| bundleUriExists
235+
bundleUriExists --> |Yes| setBundleUri
236+
bundleUriExists --> |No| incrementalFetch
237+
setBundleUri --> creationTokenExists
238+
creationTokenExists --> |Yes| setCreationToken
239+
creationTokenExists --> |No| setCreationTokenZero
240+
setCreationToken & setCreationTokenZero --> downloadAndUnbundle
241+
downloadAndUnbundle <--> bundleServer
242+
downloadAndUnbundle --> bundleSuccess
243+
bundleSuccess --> |Yes| saveCreationToken
244+
bundleSuccess --> |No| incrementalFetch
245+
saveCreationToken --> incrementalFetch
246+
incrementalFetch <--> origin
247+
```

0 commit comments

Comments
 (0)