@@ -91,3 +91,159 @@ bundles][bundle-uri-fetch] according to the `creationToken` heuristic before
9191fetching 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+ deeperExists{{"Are there more not-yet-unbundled bundles\nwith creationToken <i>less than</i> current?"}}
128+ moveDeeper["Select next bundle with\ncreationToken less than current"]
129+ unbundleReq["Unbundle downloaded bundle"]
130+ shallowerExists{{"Are there more not-yet-unbundled bundles\nwith creationToken <i>greater than</i> current?"}}
131+ moveShallower["Select next bundle with\ncreationToken greater than current"]
132+ unbundleSuccess{{"Successfully unbundled? (not\nmissing any required commits)"}}
133+ end
134+ bundleServer[(Bundle Server)]
135+ done{"Done"}
136+
137+ style downloadAndUnbundle fill:#28865477
138+
139+ start --> parse --> sort --> creationToken
140+ creationToken ----------> |No| done
141+ creationToken --> |Yes| reqBundle
142+ reqBundle --> downloadSuccess
143+ downloadSuccess --> |No| markUnbundledSkip
144+ markUnbundledSkip --> deeperExists
145+ deeperExists --> |No| done
146+ deeperExists --> |Yes| moveDeeper --> creationToken
147+ reqBundle <--> bundleServer
148+
149+ downloadSuccess --> |Yes| unbundleReq
150+ unbundleReq --> unbundleSuccess
151+ unbundleSuccess ----> |No| deeperExists
152+ shallowerExists --> |No| done
153+ unbundleSuccess --> |Yes| markUnbundled --> shallowerExists
154+ shallowerExists --> |Yes| moveShallower --> unbundleReq
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