{
    "content": [
        {
            "type": "text",
            "text": "# GITPROTOCOL-V2 (man)\n\n## NAME\n\ngitprotocol-v2 - Git Wire Protocol, Version 2\n\n## SYNOPSIS\n\n<over-the-wire-protocol>\n\n## DESCRIPTION\n\nThis document presents a specification for a version 2 of Git’s wire protocol. Protocol v2\nwill improve upon v1 in the following ways:\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION**\n- **PACKET-LINE FRAMING**\n- **INITIAL CLIENT REQUEST** (3 subsections)\n- **CAPABILITY ADVERTISEMENT**\n- **COMMAND REQUEST**\n- **CAPABILITIES** (12 subsections)\n- **GIT**\n- **NOTES**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "GITPROTOCOL-V2",
        "section": "",
        "mode": "man",
        "summary": "gitprotocol-v2 - Git Wire Protocol, Version 2",
        "synopsis": "<over-the-wire-protocol>",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 3,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 24,
                "subsections": []
            },
            {
                "name": "PACKET-LINE FRAMING",
                "lines": 12,
                "subsections": []
            },
            {
                "name": "INITIAL CLIENT REQUEST",
                "lines": 6,
                "subsections": [
                    {
                        "name": "Git Transport",
                        "lines": 5
                    },
                    {
                        "name": "SSH and File Transport",
                        "lines": 4
                    },
                    {
                        "name": "HTTP Transport",
                        "lines": 24
                    }
                ]
            },
            {
                "name": "CAPABILITY ADVERTISEMENT",
                "lines": 18,
                "subsections": []
            },
            {
                "name": "COMMAND REQUEST",
                "lines": 29,
                "subsections": []
            },
            {
                "name": "CAPABILITIES",
                "lines": 11,
                "subsections": [
                    {
                        "name": "agent",
                        "lines": 9
                    },
                    {
                        "name": "ls-refs",
                        "lines": 41
                    },
                    {
                        "name": "fetch",
                        "lines": 266
                    },
                    {
                        "name": "server-option",
                        "lines": 6
                    },
                    {
                        "name": "object-format",
                        "lines": 6
                    },
                    {
                        "name": "session-id=<session id>",
                        "lines": 8
                    },
                    {
                        "name": "object-info",
                        "lines": 27
                    },
                    {
                        "name": "bundle-uri",
                        "lines": 13
                    },
                    {
                        "name": "DISCUSSION of bundle-uri",
                        "lines": 15
                    },
                    {
                        "name": "PROTOCOL for bundle-uri",
                        "lines": 13
                    },
                    {
                        "name": "bundle-uri CLIENT AND SERVER EXPECTATIONS",
                        "lines": 83
                    },
                    {
                        "name": "bundle-uri PROTOCOL FEATURES",
                        "lines": 36
                    }
                ]
            },
            {
                "name": "GIT",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "NOTES",
                "lines": 4,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "gitprotocol-v2 - Git Wire Protocol, Version 2\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "<over-the-wire-protocol>\n\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "This document presents a specification for a version 2 of Git’s wire protocol. Protocol v2\nwill improve upon v1 in the following ways:\n\n•   Instead of multiple service names, multiple commands will be supported by a single\nservice\n\n•   Easily extendable as capabilities are moved into their own section of the protocol, no\nlonger being hidden behind a NUL byte and limited by the size of a pkt-line\n\n•   Separate out other information hidden behind NUL bytes (e.g. agent string as a capability\nand symrefs can be requested using ls-refs)\n\n•   Reference advertisement will be omitted unless explicitly requested\n\n•   ls-refs command to explicitly request some refs\n\n•   Designed with http and stateless-rpc in mind. With clear flush semantics the http remote\nhelper can simply act as a proxy\n\nIn protocol v2 communication is command oriented. When first contacting a server a list of\ncapabilities will be advertised. Some of these capabilities will be commands which a client\ncan request be executed. Once a command has completed, a client can reuse the connection and\nrequest that other commands be executed.\n",
                "subsections": []
            },
            "PACKET-LINE FRAMING": {
                "content": "All communication is done using packet-line framing, just as in v1. See gitprotocol-pack(5)\nand gitprotocol-common(5) for more information.\n\nIn protocol v2 these special packets will have the following semantics:\n\n•   0000 Flush Packet (flush-pkt) - indicates the end of a message\n\n•   0001 Delimiter Packet (delim-pkt) - separates sections of a message\n\n•   0002 Response End Packet (response-end-pkt) - indicates the end of a response for\nstateless connections\n",
                "subsections": []
            },
            "INITIAL CLIENT REQUEST": {
                "content": "In general a client can request to speak protocol v2 by sending version=2 through the\nrespective side-channel for the transport being used which inevitably sets GITPROTOCOL. More\ninformation can be found in gitprotocol-pack(5) and gitprotocol-http(5), as well as the\nGITPROTOCOL definition in git.txt. In all cases the response from the server is the\ncapability advertisement.\n",
                "subsections": [
                    {
                        "name": "Git Transport",
                        "content": "When using the git:// transport, you can request to use protocol v2 by sending \"version=2\" as\nan extra parameter:\n\n003egit-upload-pack /project.git\\0host=myserver.com\\0\\0version=2\\0\n"
                    },
                    {
                        "name": "SSH and File Transport",
                        "content": "When using either the ssh:// or file:// transport, the GITPROTOCOL environment variable must\nbe set explicitly to include \"version=2\". The server may need to be configured to allow this\nenvironment variable to pass.\n"
                    },
                    {
                        "name": "HTTP Transport",
                        "content": "When using the http:// or https:// transport a client makes a \"smart\" info/refs request as\ndescribed in gitprotocol-http(5) and requests that v2 be used by supplying \"version=2\" in the\nGit-Protocol header.\n\nC: GET $GITURL/info/refs?service=git-upload-pack HTTP/1.0\nC: Git-Protocol: version=2\n\nA v2 server would reply:\n\nS: 200 OK\nS: <Some headers>\nS: ...\nS:\nS: 000eversion 2\\n\nS: <capability-advertisement>\n\nSubsequent requests are then made directly to the service $GITURL/git-upload-pack. (This\nworks the same for git-receive-pack).\n\nUses the --http-backend-info-refs option to git-upload-pack(1).\n\nThe server may need to be configured to pass this header’s contents via the GITPROTOCOL\nvariable. See the discussion in git-http-backend.txt.\n"
                    }
                ]
            },
            "CAPABILITY ADVERTISEMENT": {
                "content": "A server which decides to communicate (based on a request from a client) using protocol\nversion 2, notifies the client by sending a version string in its initial response followed\nby an advertisement of its capabilities. Each capability is a key with an optional value.\nClients must ignore all unknown keys. Semantics of unknown values are left to the definition\nof each key. Some capabilities will describe commands which can be requested to be executed\nby the client.\n\ncapability-advertisement = protocol-version\ncapability-list\nflush-pkt\n\nprotocol-version = PKT-LINE(\"version 2\" LF)\ncapability-list = *capability\ncapability = PKT-LINE(key[=value] LF)\n\nkey = 1*(ALPHA | DIGIT | \"-\")\nvalue = 1*(ALPHA | DIGIT | \" -.,?\\/{}[]()<>!@#$%^&*+=:;\")\n",
                "subsections": []
            },
            "COMMAND REQUEST": {
                "content": "After receiving the capability advertisement, a client can then issue a request to select the\ncommand it wants with any particular capabilities or arguments. There is then an optional\nsection where the client can provide any command specific parameters or queries. Only a\nsingle command can be requested at a time.\n\nrequest = empty-request | command-request\nempty-request = flush-pkt\ncommand-request = command\ncapability-list\ndelim-pkt\ncommand-args\nflush-pkt\ncommand = PKT-LINE(\"command=\" key LF)\ncommand-args = *command-specific-arg\n\ncommand-specific-args are packet line framed arguments defined by\neach individual command.\n\nThe server will then check to ensure that the client’s request is comprised of a valid\ncommand as well as valid capabilities which were advertised. If the request is valid the\nserver will then execute the command. A server MUST wait till it has received the client’s\nentire request before issuing a response. The format of the response is determined by the\ncommand being executed, but in all cases a flush-pkt indicates the end of the response.\n\nWhen a command has finished, and the client has received the entire response from the server,\na client can either request that another command be executed or can terminate the connection.\nA client may optionally send an empty request consisting of just a flush-pkt to indicate that\nno more requests will be made.\n",
                "subsections": []
            },
            "CAPABILITIES": {
                "content": "There are two different types of capabilities: normal capabilities, which can be used to\nconvey information or alter the behavior of a request, and commands, which are the core\nactions that a client wants to perform (fetch, push, etc).\n\nProtocol version 2 is stateless by default. This means that all commands must only last a\nsingle round and be stateless from the perspective of the server side, unless the client has\nrequested a capability indicating that state should be maintained by the server. Clients MUST\nNOT require state management on the server side in order to function correctly. This permits\nsimple round-robin load-balancing on the server side, without needing to worry about state\nmanagement.\n",
                "subsections": [
                    {
                        "name": "agent",
                        "content": "The server can advertise the agent capability with a value X (in the form agent=X) to notify\nthe client that the server is running version X. The client may optionally send its own agent\nstring by including the agent capability with a value Y (in the form agent=Y) in its request\nto the server (but it MUST NOT do so if the server did not advertise the agent capability).\nThe X and Y strings may contain any printable ASCII characters except space (i.e., the byte\nrange 32 < x < 127), and are typically of the form \"package/version\" (e.g., \"git/1.8.3.1\").\nThe agent strings are purely informative for statistics and debugging purposes, and MUST NOT\nbe used to programmatically assume the presence or absence of particular features.\n"
                    },
                    {
                        "name": "ls-refs",
                        "content": "ls-refs is the command used to request a reference advertisement in v2. Unlike the current\nreference advertisement, ls-refs takes in arguments which can be used to limit the refs sent\nfrom the server.\n\nAdditional features not supported in the base command will be advertised as the value of the\ncommand in the capability advertisement in the form of a space separated list of features:\n\"<command>=<feature 1> <feature 2>\"\n\nls-refs takes in the following arguments:\n\nsymrefs\nIn addition to the object pointed by it, show the underlying ref\npointed by it when showing a symbolic ref.\npeel\nShow peeled tags.\nref-prefix <prefix>\nWhen specified, only references having a prefix matching one of\nthe provided prefixes are displayed. Multiple instances may be\ngiven, in which case references matching any prefix will be\nshown. Note that this is purely for optimization; a server MAY\nshow refs not matching the prefix if it chooses, and clients\nshould filter the result themselves.\n\nIf the unborn feature is advertised the following argument can be included in the client’s\nrequest.\n\nunborn\nThe server will send information about HEAD even if it is a symref\npointing to an unborn branch in the form \"unborn HEAD\nsymref-target:<target>\".\n\nThe output of ls-refs is as follows:\n\noutput = *ref\nflush-pkt\nobj-id-or-unborn = (obj-id | \"unborn\")\nref = PKT-LINE(obj-id-or-unborn SP refname *(SP ref-attribute) LF)\nref-attribute = (symref | peeled)\nsymref = \"symref-target:\" symref-target\npeeled = \"peeled:\" obj-id\n"
                    },
                    {
                        "name": "fetch",
                        "content": "fetch is the command used to fetch a packfile in v2. It can be looked at as a modified\nversion of the v1 fetch where the ref-advertisement is stripped out (since the ls-refs\ncommand fills that role) and the message format is tweaked to eliminate redundancies and\npermit easy addition of future extensions.\n\nAdditional features not supported in the base command will be advertised as the value of the\ncommand in the capability advertisement in the form of a space separated list of features:\n\"<command>=<feature 1> <feature 2>\"\n\nA fetch request can take the following arguments:\n\nwant <oid>\nIndicates to the server an object which the client wants to\nretrieve.  Wants can be anything and are not limited to\nadvertised objects.\n\nhave <oid>\nIndicates to the server an object which the client has locally.\nThis allows the server to make a packfile which only contains\nthe objects that the client needs. Multiple 'have' lines can be\nsupplied.\n\ndone\nIndicates to the server that negotiation should terminate (or\nnot even begin if performing a clone) and that the server should\nuse the information supplied in the request to construct the\npackfile.\n\nthin-pack\nRequest that a thin pack be sent, which is a pack with deltas\nwhich reference base objects not contained within the pack (but\nare known to exist at the receiving end). This can reduce the\nnetwork traffic significantly, but it requires the receiving end\nto know how to \"thicken\" these packs by adding the missing bases\nto the pack.\n\nno-progress\nRequest that progress information that would normally be sent on\nside-band channel 2, during the packfile transfer, should not be\nsent.  However, the side-band channel 3 is still used for error\nresponses.\n\ninclude-tag\nRequest that annotated tags should be sent if the objects they\npoint to are being sent.\n\nofs-delta\nIndicate that the client understands PACKv2 with delta referring\nto its base by position in pack rather than by an oid.  That is,\nthey can read OBJOFSDELTA (aka type 6) in a packfile.\n\nIf the shallow feature is advertised the following arguments can be included in the clients\nrequest as well as the potential addition of the shallow-info section in the server’s\nresponse as explained below.\n\nshallow <oid>\nA client must notify the server of all commits for which it only\nhas shallow copies (meaning that it doesn't have the parents of\na commit) by supplying a 'shallow <oid>' line for each such\nobject so that the server is aware of the limitations of the\nclient's history.  This is so that the server is aware that the\nclient may not have all objects reachable from such commits.\n\ndeepen <depth>\nRequests that the fetch/clone should be shallow having a commit\ndepth of <depth> relative to the remote side.\n\ndeepen-relative\nRequests that the semantics of the \"deepen\" command be changed\nto indicate that the depth requested is relative to the client's\ncurrent shallow boundary, instead of relative to the requested\ncommits.\n\ndeepen-since <timestamp>\nRequests that the shallow clone/fetch should be cut at a\nspecific time, instead of depth.  Internally it's equivalent to\ndoing \"git rev-list --max-age=<timestamp>\". Cannot be used with\n\"deepen\".\n\ndeepen-not <rev>\nRequests that the shallow clone/fetch should be cut at a\nspecific revision specified by '<rev>', instead of a depth.\nInternally it's equivalent of doing \"git rev-list --not <rev>\".\nCannot be used with \"deepen\", but can be used with\n\"deepen-since\".\n\nIf the filter feature is advertised, the following argument can be included in the client’s\nrequest:\n\nfilter <filter-spec>\nRequest that various objects from the packfile be omitted\nusing one of several filtering techniques. These are intended\nfor use with partial clone and partial fetch operations. See\n`rev-list` for possible \"filter-spec\" values. When communicating\nwith other processes, senders SHOULD translate scaled integers\n(e.g. \"1k\") into a fully-expanded form (e.g. \"1024\") to aid\ninteroperability with older receivers that may not understand\nnewly-invented scaling suffixes. However, receivers SHOULD\naccept the following suffixes: 'k', 'm', and 'g' for 1024,\n1048576, and 1073741824, respectively.\n\nIf the ref-in-want feature is advertised, the following argument can be included in the\nclient’s request as well as the potential addition of the wanted-refs section in the server’s\nresponse as explained below.\n\nwant-ref <ref>\nIndicates to the server that the client wants to retrieve a\nparticular ref, where <ref> is the full name of a ref on the\nserver.\n\nIf the sideband-all feature is advertised, the following argument can be included in the\nclient’s request:\n\nsideband-all\nInstruct the server to send the whole response multiplexed, not just\nthe packfile section. All non-flush and non-delim PKT-LINE in the\nresponse (not only in the packfile section) will then start with a byte\nindicating its sideband (1, 2, or 3), and the server may send \"0005\\2\"\n(a PKT-LINE of sideband 2 with no payload) as a keepalive packet.\n\nIf the packfile-uris feature is advertised, the following argument can be included in the\nclient’s request as well as the potential addition of the packfile-uris section in the\nserver’s response as explained below.\n\npackfile-uris <comma-separated list of protocols>\nIndicates to the server that the client is willing to receive\nURIs of any of the given protocols in place of objects in the\nsent packfile. Before performing the connectivity check, the\nclient should download from all given URIs. Currently, the\nprotocols supported are \"http\" and \"https\".\n\nIf the wait-for-done feature is advertised, the following argument can be included in the\nclient’s request.\n\nwait-for-done\nIndicates to the server that it should never send \"ready\", but\nshould wait for the client to say \"done\" before sending the\npackfile.\n\nThe response of fetch is broken into a number of sections separated by delimiter packets\n(0001), with each section beginning with its section header. Most sections are sent only when\nthe packfile is sent.\n\noutput = acknowledgements flush-pkt |\n[acknowledgments delim-pkt] [shallow-info delim-pkt]\n[wanted-refs delim-pkt] [packfile-uris delim-pkt]\npackfile flush-pkt\n\nacknowledgments = PKT-LINE(\"acknowledgments\" LF)\n(nak | *ack)\n(ready)\nready = PKT-LINE(\"ready\" LF)\nnak = PKT-LINE(\"NAK\" LF)\nack = PKT-LINE(\"ACK\" SP obj-id LF)\n\nshallow-info = PKT-LINE(\"shallow-info\" LF)\n*PKT-LINE((shallow | unshallow) LF)\nshallow = \"shallow\" SP obj-id\nunshallow = \"unshallow\" SP obj-id\n\nwanted-refs = PKT-LINE(\"wanted-refs\" LF)\n*PKT-LINE(wanted-ref LF)\nwanted-ref = obj-id SP refname\n\npackfile-uris = PKT-LINE(\"packfile-uris\" LF) *packfile-uri\npackfile-uri = PKT-LINE(40*(HEXDIGIT) SP *%x20-ff LF)\n\npackfile = PKT-LINE(\"packfile\" LF)\n*PKT-LINE(%x01-03 *%x00-ff)\n\nacknowledgments section\n* If the client determines that it is finished with negotiations by\nsending a \"done\" line (thus requiring the server to send a packfile),\nthe acknowledgments sections MUST be omitted from the server's\nresponse.\n\n•   Always begins with the section header \"acknowledgments\"\n\n•   The server will respond with \"NAK\" if none of the object ids sent as have lines were\ncommon.\n\n•   The server will respond with \"ACK obj-id\" for all of the object ids sent as have lines\nwhich are common.\n\n•   A response cannot have both \"ACK\" lines as well as a \"NAK\" line.\n\n•   The server will respond with a \"ready\" line indicating that the server has found an\nacceptable common base and is ready to make and send a packfile (which will be found in\nthe packfile section of the same response)\n\n•   If the server has found a suitable cut point and has decided to send a \"ready\" line, then\nthe server can decide to (as an optimization) omit any \"ACK\" lines it would have sent\nduring its response. This is because the server will have already determined the objects\nit plans to send to the client and no further negotiation is needed.\n\nshallow-info section\n* If the client has requested a shallow fetch/clone, a shallow\nclient requests a fetch or the server is shallow then the\nserver's response may include a shallow-info section.  The\nshallow-info section will be included if (due to one of the\nabove conditions) the server needs to inform the client of any\nshallow boundaries or adjustments to the clients already\nexisting shallow boundaries.\n\n•   Always begins with the section header \"shallow-info\"\n\n•   If a positive depth is requested, the server will compute the set of commits which are no\ndeeper than the desired depth.\n\n•   The server sends a \"shallow obj-id\" line for each commit whose parents will not be sent\nin the following packfile.\n\n•   The server sends an \"unshallow obj-id\" line for each commit which the client has\nindicated is shallow, but is no longer shallow as a result of the fetch (due to its\nparents being sent in the following packfile).\n\n•   The server MUST NOT send any \"unshallow\" lines for anything which the client has not\nindicated was shallow as a part of its request.\n\nwanted-refs section\n* This section is only included if the client has requested a\nref using a 'want-ref' line and if a packfile section is also\nincluded in the response.\n\n•   Always begins with the section header \"wanted-refs\".\n\n•   The server will send a ref listing (\"<oid> <refname>\") for each reference requested using\nwant-ref lines.\n\n•   The server MUST NOT send any refs which were not requested using want-ref lines.\n\npackfile-uris section\n* This section is only included if the client sent\n'packfile-uris' and the server has at least one such URI to\nsend.\n\n•   Always begins with the section header \"packfile-uris\".\n\n•   For each URI the server sends, it sends a hash of the pack’s contents (as output by git\nindex-pack) followed by the URI.\n\n•   The hashes are 40 hex characters long. When Git upgrades to a new hash algorithm, this\nmight need to be updated. (It should match whatever index-pack outputs after \"pack\\t\" or\n\"keep\\t\".\n\npackfile section\n* This section is only included if the client has sent 'want'\nlines in its request and either requested that no more\nnegotiation be done by sending 'done' or if the server has\ndecided it has found a sufficient cut point to produce a\npackfile.\n\n•   Always begins with the section header \"packfile\"\n\n•   The transmission of the packfile begins immediately after the section header\n\n•   The data transfer of the packfile is always multiplexed, using the same semantics of the\nside-band-64k capability from protocol version 1. This means that each packet, during the\npackfile data stream, is made up of a leading 4-byte pkt-line length (typical of the\npkt-line format), followed by a 1-byte stream code, followed by the actual data.\n\nThe stream code can be one of:\n1 - pack data\n2 - progress messages\n3 - fatal error message just before stream aborts\n"
                    },
                    {
                        "name": "server-option",
                        "content": "If advertised, indicates that any number of server specific options can be included in a\nrequest. This is done by sending each option as a \"server-option=<option>\" capability line in\nthe capability-list section of a request.\n\nThe provided options must not contain a NUL or LF character.\n"
                    },
                    {
                        "name": "object-format",
                        "content": "The server can advertise the object-format capability with a value X (in the form\nobject-format=X) to notify the client that the server is able to deal with objects using hash\nalgorithm X. If not specified, the server is assumed to only handle SHA-1. If the client\nwould like to use a hash algorithm other than SHA-1, it should specify its object-format\nstring.\n"
                    },
                    {
                        "name": "session-id=<session id>",
                        "content": "The server may advertise a session ID that can be used to identify this process across\nmultiple requests. The client may advertise its own session ID back to the server as well.\n\nSession IDs should be unique to a given process. They must fit within a packet-line, and must\nnot contain non-printable or whitespace characters. The current implementation uses trace2\nsession IDs (see \u001b[34mapi-trace2[1] for details), but this may change and users of the session ID\nshould not rely on this fact.\n"
                    },
                    {
                        "name": "object-info",
                        "content": "object-info is the command to retrieve information about one or more objects. Its main\npurpose is to allow a client to make decisions based on this information without having to\nfully fetch objects. Object size is the only information that is currently supported.\n\nAn object-info request takes the following arguments:\n\nsize\nRequests size information to be returned for each listed object id.\n\noid <oid>\nIndicates to the server an object which the client wants to obtain\ninformation for.\n\nThe response of object-info is a list of the requested object ids and associated requested\ninformation, each separated by a single space.\n\noutput = info flush-pkt\n\ninfo = PKT-LINE(attrs) LF)\n*PKT-LINE(obj-info LF)\n\nattrs = attr | attrs SP attrs\n\nattr = \"size\"\n\nobj-info = obj-id SP obj-size\n"
                    },
                    {
                        "name": "bundle-uri",
                        "content": "If the bundle-uri capability is advertised, the server supports the ‘bundle-uri’ command.\n\nThe capability is currently advertised with no value (i.e. not \"bundle-uri=somevalue\"), a\nvalue may be added in the future for supporting command-wide extensions. Clients MUST ignore\nany unknown capability values and proceed with the 'bundle-uri` dialog they support.\n\nThe bundle-uri command is intended to be issued before fetch to get URIs to bundle files (see\ngit-bundle(1)) to \"seed\" and inform the subsequent fetch command.\n\nThe client CAN issue bundle-uri before or after any other valid command. To be useful to\nclients it’s expected that it’ll be issued after an ls-refs and before fetch, but CAN be\nissued at any time in the dialog.\n"
                    },
                    {
                        "name": "DISCUSSION of bundle-uri",
                        "content": "The intent of the feature is optimize for server resource consumption in the common case\nby changing the common case of fetching a very large PACK during git-clone(1) into a\nsmaller incremental fetch.\n\nIt also allows servers to achieve better caching in combination with an\nuploadpack.packObjectsHook (see git-config(1)).\n\nBy having new clones or fetches be a more predictable and common negotiation against the\ntips of recently produces *.bundle file(s). Servers might even pre-generate the results\nof such negotiations for the uploadpack.packObjectsHook as new pushes come in.\n\nOne way that servers could take advantage of these bundles is that the server would\nanticipate that fresh clones will download a known bundle, followed by catching up to the\ncurrent state of the repository using ref tips found in that bundle (or bundles).\n"
                    },
                    {
                        "name": "PROTOCOL for bundle-uri",
                        "content": "A bundle-uri request takes no arguments, and as noted above does not currently advertise\na capability value. Both may be added in the future.\n\nWhen the client issues a command=bundle-uri request, the response is a list of key-value\npairs provided as packet lines with value <key>=<value>. Each <key> should be interpreted\nas a config key from the bundle.* namespace to construct a list of bundles. These keys\nare grouped by a bundle.<id>. subsection, where each key corresponding to a given <id>\ncontributes attributes to the bundle defined by that <id>. See git-config(1) for the\nspecific details of these keys and how the Git client will interpret their values.\n\nClients MUST parse the line according to the above format, lines that do not conform to\nthe format SHOULD be discarded. The user MAY be warned in such a case.\n"
                    },
                    {
                        "name": "bundle-uri CLIENT AND SERVER EXPECTATIONS",
                        "content": "URI CONTENTS\nThe content at the advertised URIs MUST be one of two types.\n\nThe advertised URI may contain a bundle file that git bundle verify would accept.\nI.e. they MUST contain one or more reference tips for use by the client, MUST\nindicate prerequisites (in any) with standard \"-\" prefixes, and MUST indicate their\n\"object-format\", if applicable.\n\nThe advertised URI may alternatively contain a plaintext file that git config --list\nwould accept (with the --file option). The key-value pairs in this list are in the\nbundle.*  namespace (see git-config(1)).\n\nbundle-uri CLIENT ERROR RECOVERY\nA client MUST above all gracefully degrade on errors, whether that error is because\nof bad missing/data in the bundle URI(s), because that client is too dumb to e.g.\nunderstand and fully parse out bundle headers and their prerequisite relationships,\nor something else.\n\nServer operators should feel confident in turning on \"bundle-uri\" and not worry if\ne.g. their CDN goes down that clones or fetches will run into hard failures. Even if\nthe server bundle(s) are incomplete, or bad in some way the client should still end\nup with a functioning repository, just as if it had chosen not to use this protocol\nextension.\n\nAll subsequent discussion on client and server interaction MUST keep this in mind.\n\nbundle-uri SERVER TO CLIENT\nThe ordering of the returned bundle uris is not significant. Clients MUST parse their\nheaders to discover their contained OIDS and prerequisites. A client MUST consider\nthe content of the bundle(s) themselves and their header as the ultimate source of\ntruth.\n\nA server MAY even return bundle(s) that don’t have any direct relationship to the\nrepository being cloned (either through accident, or intentional \"clever\"\nconfiguration), and expect a client to sort out what data they’d like from the\nbundle(s), if any.\n\nbundle-uri CLIENT TO SERVER\nThe client SHOULD provide reference tips found in the bundle header(s) as have lines\nin any subsequent fetch request. A client MAY also ignore the bundle(s) entirely if\ndoing so is deemed worse for some reason, e.g. if the bundles can’t be downloaded, it\ndoesn’t like the tips it finds etc.\n\nWHEN ADVERTISED BUNDLE(S) REQUIRE NO FURTHER NEGOTIATION\nIf after issuing bundle-uri and ls-refs, and getting the header(s) of the bundle(s)\nthe client finds that the ref tips it wants can be retrieved entirely from advertised\nbundle(s), the client MAY disconnect from the Git server. The results of such a clone\nor fetch should be indistinguishable from the state attained without using\nbundle-uri.\n\nEARLY CLIENT DISCONNECTIONS AND ERROR RECOVERY\nA client MAY perform an early disconnect while still downloading the bundle(s)\n(having streamed and parsed their headers). In such a case the client MUST gracefully\nrecover from any errors related to finishing the download and validation of the\nbundle(s).\n\nI.e. a client might need to re-connect and issue a fetch command, and possibly fall\nback to not making use of bundle-uri at all.\n\nThis \"MAY\" behavior is specified as such (and not a \"SHOULD\") on the assumption that\na server advertising bundle uris is more likely than not to be serving up a\nrelatively large repository, and to be pointing to URIs that have a good chance of\nbeing in working order. A client MAY e.g. look at the payload size of the bundles as\na heuristic to see if an early disconnect is worth it, should falling back on a full\n\"fetch\" dialog be necessary.\n\nWHEN ADVERTISED BUNDLE(S) REQUIRE FURTHER NEGOTIATION\nA client SHOULD commence a negotiation of a PACK from the server via the \"fetch\"\ncommand using the OID tips found in advertised bundles, even if’s still in the\nprocess of downloading those bundle(s).\n\nThis allows for aggressive early disconnects from any interactive server dialog. The\nclient blindly trusts that the advertised OID tips are relevant, and issues them as\nhave lines, it then requests any tips it would like (usually from the \"ls-refs\"\nadvertisement) via want lines. The server will then compute a (hopefully small) PACK\nwith the expected difference between the tips from the bundle(s) and the data\nrequested.\n\nThe only connection the client then needs to keep active is to the concurrently\ndownloading static bundle(s), when those and the incremental PACK are retrieved they\nshould be inflated and validated. Any errors at this point should be gracefully\nrecovered from, see above.\n"
                    },
                    {
                        "name": "bundle-uri PROTOCOL FEATURES",
                        "content": "The client constructs a bundle list from the <key>=<value> pairs provided by the server.\nThese pairs are part of the bundle.* namespace as documented in git-config(1). In this\nsection, we discuss some of these keys and describe the actions the client will do in\nresponse to this information.\n\nIn particular, the bundle.version key specifies an integer value. The only accepted value\nat the moment is 1, but if the client sees an unexpected value here then the client MUST\nignore the bundle list.\n\nAs long as bundle.version is understood, all other unknown keys MAY be ignored by the\nclient. The server will guarantee compatibility with older clients, though newer clients\nmay be better able to use the extra keys to minimize downloads.\n\nAny backwards-incompatible addition of pre-URI key-value will be guarded by a new\nbundle.version value or values in bundle-uri capability advertisement itself, and/or by\nnew future bundle-uri request arguments.\n\nSome example key-value pairs that are not currently implemented but could be implemented\nin the future include:\n\n•   Add a \"hash=<val>\" or \"size=<bytes>\" advertise the expected hash or size of the\nbundle file.\n\n•   Advertise that one or more bundle files are the same (to e.g. have clients\nround-robin or otherwise choose one of N possible files).\n\n•   A \"oid=<OID>\" shortcut and \"prerequisite=<OID>\" shortcut. For expressing the common\ncase of a bundle with one tip and no prerequisites, or one tip and one prerequisite.\n\nThis would allow for optimizing the common case of servers who’d like to provide one\n\"big bundle\" containing only their \"main\" branch, and/or incremental updates thereof.\n\nA client receiving such a a response MAY assume that they can skip retrieving the\nheader from a bundle at the indicated URI, and thus save themselves and the server(s)\nthe request(s) needed to inspect the headers of that bundle or bundles.\n"
                    }
                ]
            },
            "GIT": {
                "content": "Part of the git(1) suite\n",
                "subsections": []
            },
            "NOTES": {
                "content": "1. api-trace2\nfile:///usr/share/doc/git/html/technical/api-trace2.html\n\nGit 2.43.0                                   07/02/2025                            GITPROTOCOL-V2(5)",
                "subsections": []
            }
        }
    }
}