| Packfile URIs |
| ============= |
| |
| This feature allows servers to serve part of their packfile response as URIs. |
| This allows server designs that improve scalability in bandwidth and CPU usage |
| (for example, by serving some data through a CDN), and (in the future) provides |
| some measure of resumability to clients. |
| |
| This feature is available only in protocol version 2. |
| |
| Protocol |
| -------- |
| |
| The server advertises the `packfile-uris` capability. |
| |
| If the client then communicates which protocols (HTTPS, etc.) it supports with |
| a `packfile-uris` argument, the server MAY send a `packfile-uris` section |
| directly before the `packfile` section (right after `wanted-refs` if it is |
| sent) containing URIs of any of the given protocols. The URIs point to |
| packfiles that use only features that the client has declared that it supports |
| (e.g. ofs-delta and thin-pack). See linkgit:gitprotocol-v2[5] for the documentation of |
| this section. |
| |
| Clients should then download and index all the given URIs (in addition to |
| downloading and indexing the packfile given in the `packfile` section of the |
| response) before performing the connectivity check. |
| |
| Server design |
| ------------- |
| |
| The server can be trivially made compatible with the proposed protocol by |
| having it advertise `packfile-uris`, tolerating the client sending |
| `packfile-uris`, and never sending any `packfile-uris` section. But we should |
| include some sort of non-trivial implementation in the Minimum Viable Product, |
| at least so that we can test the client. |
| |
| This is the implementation: a feature, marked experimental, that allows the |
| server to be configured by one or more `uploadpack.blobPackfileUri= |
| <object-hash> <pack-hash> <uri>` entries. Whenever the list of objects to be |
| sent is assembled, all such blobs are excluded, replaced with URIs. As noted |
| in "Future work" below, the server can evolve in the future to support |
| excluding other objects (or other implementations of servers could be made |
| that support excluding other objects) without needing a protocol change, so |
| clients should not expect that packfiles downloaded in this way only contain |
| single blobs. |
| |
| Client design |
| ------------- |
| |
| The client has a config variable `fetch.uriprotocols` that determines which |
| protocols the end user is willing to use. By default, this is empty. |
| |
| When the client downloads the given URIs, it should store them with "keep" |
| files, just like it does with the packfile in the `packfile` section. These |
| additional "keep" files can only be removed after the refs have been updated - |
| just like the "keep" file for the packfile in the `packfile` section. |
| |
| The division of work (initial fetch + additional URIs) introduces convenient |
| points for resumption of an interrupted clone - such resumption can be done |
| after the Minimum Viable Product (see "Future work"). |
| |
| Future work |
| ----------- |
| |
| The protocol design allows some evolution of the server and client without any |
| need for protocol changes, so only a small-scoped design is included here to |
| form the MVP. For example, the following can be done: |
| |
| * On the server, more sophisticated means of excluding objects (e.g. by |
| specifying a commit to represent that commit and all objects that it |
| references). |
| * On the client, resumption of clone. If a clone is interrupted, information |
| could be recorded in the repository's config and a "clone-resume" command |
| can resume the clone in progress. (Resumption of subsequent fetches is more |
| difficult because that must deal with the user wanting to use the repository |
| even after the fetch was interrupted.) |
| |
| There are some possible features that will require a change in protocol: |
| |
| * Additional HTTP headers (e.g. authentication) |
| * Byte range support |
| * Different file formats referenced by URIs (e.g. raw object) |