English ▾ Themen ▾ Neueste Version ▾ gitprotocol-v2 zuletzt aktualisiert in 2.52.0

NAME

gitprotocol-v2 - Git Wire Protocol, Version 2

SYNOPSIS

<over-the-wire-protocol>

BESCHREIBUNG

Dieses Dokument präsentiert eine Spezifikation für Version 2 von Git's Wire Protocol. Protokoll v2 wird v1 in folgenden Punkten verbessern:

  • Anstelle mehrerer Servicenamen werden mehrere Befehle von einem einzigen Dienst unterstützt.

  • Leicht erweiterbar, da Fähigkeiten in ihren eigenen Abschnitt des Protokolls verlagert werden und nicht mehr hinter einem NUL-Byte versteckt und durch die Größe einer Paketzeile begrenzt sind.

  • Andere Informationen, die hinter NUL-Bytes versteckt sind, werden separat behandelt (z. B. Agent-String als Fähigkeit und Symrefs können mit ls-refs angefordert werden).

  • Referenzanzeige wird weggelassen, es sei denn, sie wird explizit angefordert.

  • ls-refs-Befehl, um explizit einige Refs anzufordern.

  • Entwickelt mit http und stateless-rpc im Sinn. Mit klaren Flush-Semantiken kann der http-Remote-Helper einfach als Proxy fungieren.

In Protokoll v2 ist die Kommunikation befehlsorientiert. Bei der ersten Kontaktaufnahme mit einem Server wird eine Liste von Fähigkeiten angezeigt. Einige dieser Fähigkeiten sind Befehle, die ein Client ausführen lassen kann. Sobald ein Befehl abgeschlossen ist, kann ein Client die Verbindung wiederverwenden und andere Befehle ausführen lassen.

Paketzeilen-Framing

Die gesamte Kommunikation erfolgt über Paketzeilen-Framing, genau wie in v1. Weitere Informationen finden Sie unter gitprotocol-pack[5] und gitprotocol-common[5].

In Protokoll v2 haben diese speziellen Pakete folgende Semantiken:

  • 0000 Flush-Paket (flush-pkt) - zeigt das Ende einer Nachricht an

  • 0001 Trennpaket (delim-pkt) - trennt Abschnitte einer Nachricht

  • 0002 Antwort-Ende-Paket (response-end-pkt) - zeigt das Ende einer Antwort für zustandslose Verbindungen an

Erste Client-Anfrage

Im Allgemeinen kann ein Client die Version 2 des Protokolls anfordern, indem er version=2 über den jeweiligen Seitenkanal für den verwendeten Transport sendet, was letztendlich GIT_PROTOCOL setzt. Weitere Informationen finden Sie unter gitprotocol-pack[5] und gitprotocol-http[5] sowie in der GIT_PROTOCOL-Definition in git[1]. In allen Fällen ist die Antwort des Servers die Anzeige der Fähigkeiten.

Git-Transport

Bei Verwendung des git://-Transports können Sie Protokoll v2 anfordern, indem Sie "version=2" als zusätzlichen Parameter senden.

003egit-upload-pack /project.git\0host=myserver.com\0\0version=2\0

SSH- und Datei-Transport

Bei Verwendung des ssh://- oder file://-Transports muss die Umgebungsvariable GIT_PROTOCOL explizit auf "version=2" gesetzt werden. Der Server muss möglicherweise konfiguriert werden, um die Weitergabe dieser Umgebungsvariable zu ermöglichen.

HTTP-Transport

Bei Verwendung des http://- oder https://-Transports sendet ein Client eine "smarte" info/refs-Anfrage, wie in gitprotocol-http[5] beschrieben, und fordert v2 an, indem "version=2" im Git-Protocol-Header angegeben wird.

C: GET $GIT_URL/info/refs?service=git-upload-pack HTTP/1.0
C: Git-Protocol: version=2

Ein v2-Server würde antworten

S: 200 OK
S: <Some headers>
S: ...
S:
S: 000eversion 2\n
S: <capability-advertisement>

Nachfolgende Anfragen werden dann direkt an den Dienst $GIT_URL/git-upload-pack gerichtet. (Dies funktioniert auch für git-receive-pack).

Verwendet die Option --http-backend-info-refs von git-upload-pack[1].

Der Server muss möglicherweise so konfiguriert werden, dass er die Inhalte dieses Headers über die Variable GIT_PROTOCOL weitergibt. Siehe die Diskussion in git-http-backend[1].

Fähigkeitsanzeige

Ein Server, der sich entscheidet, mit Protokollversion 2 zu kommunizieren (basierend auf einer Anfrage eines Clients), benachrichtigt den Client, indem er eine Versionszeichenfolge in seiner anfänglichen Antwort sendet, gefolgt von einer Anzeige seiner Fähigkeiten. Jede Fähigkeit ist ein Schlüssel mit einem optionalen Wert. Clients müssen alle unbekannten Schlüssel ignorieren. Die Semantik unbekannter Werte ist der Definition jedes Schlüssels überlassen. Einige Fähigkeiten beschreiben Befehle, die vom Client angefordert werden können.

capability-advertisement = protocol-version
      capability-list
      flush-pkt
protocol-version = PKT-LINE("version 2" LF)
capability-list = *capability
capability = PKT-LINE(key[=value] LF)
key = 1*(ALPHA | DIGIT | "-_")
value = 1*(ALPHA | DIGIT | " -_.,?\/{}[]()<>!@#$%^&*+=:;")

Befehlsanfrage

Nach Erhalt der Fähigkeitsanzeige kann ein Client eine Anfrage stellen, um den gewünschten Befehl mit den jeweiligen Fähigkeiten oder Argumenten auszuwählen. Es gibt dann einen optionalen Abschnitt, in dem der Client befhelsspezifische Parameter oder Abfragen angeben kann. Es kann jeweils nur ein Befehl angefordert werden.

request = empty-request | command-request
empty-request = flush-pkt
command-request = command
    capability-list
    delim-pkt
    command-args
    flush-pkt
command = PKT-LINE("command=" key LF)
command-args = *command-specific-arg
command-specific-args are packet line framed arguments defined by
each individual command.

Der Server prüft dann, ob die Anfrage des Clients aus einem gültigen Befehl sowie gültigen angezeigten Fähigkeiten besteht. Wenn die Anfrage gültig ist, führt der Server den Befehl aus. Ein Server MUSS warten, bis er die gesamte Anfrage des Clients erhalten hat, bevor er eine Antwort gibt. Das Format der Antwort wird durch den ausgeführten Befehl bestimmt, aber in allen Fällen zeigt ein flush-pkt das Ende der Antwort an.

Wenn ein Befehl beendet ist und der Client die gesamte Antwort des Servers erhalten hat, kann der Client entweder einen weiteren Befehl anfordern oder die Verbindung beenden. Ein Client kann optional eine leere Anfrage senden, die nur aus einem flush-pkt besteht, um anzuzeigen, dass keine weiteren Anfragen gestellt werden.

Fähigkeiten

Es gibt zwei verschiedene Arten von Fähigkeiten: normale Fähigkeiten, die verwendet werden können, um Informationen zu übermitteln oder das Verhalten einer Anfrage zu ändern, und Befehle, die die Kernaktionen sind, die ein Client ausführen möchte (fetch, push usw.).

Protokollversion 2 ist standardmäßig zustandslos. Das bedeutet, dass alle Befehle nur einen einzelnen Durchgang dauern und aus Sicht der Serverseite zustandslos sein müssen, es sei denn, der Client hat eine Fähigkeit angefordert, die angibt, dass der Zustand vom Server beibehalten werden soll. Clients DÜRFEN die Zustandsverwaltung auf der Serverseite nicht benötigen, um korrekt zu funktionieren. Dies ermöglicht eine einfache Round-Robin-Lastverteilung auf der Serverseite, ohne sich um die Zustandsverwaltung kümmern zu müssen.

agent

Der Server kann die Fähigkeit agent mit dem Wert X (in der Form agent=X) anzeigen, um den Client darüber zu informieren, dass der Server die Version X ausführt. Der Client kann optional seinen eigenen Agenten-String senden, indem er die Fähigkeit agent mit dem Wert Y (in der Form agent=Y) in seine Anfrage an den Server aufnimmt (er DARF dies jedoch NICHT tun, wenn der Server die Agenten-Fähigkeit nicht angezeigt hat). Die Zeichenfolgen X und Y können beliebige druckbare ASCII-Zeichen außer Leerzeichen enthalten (d. h. den Byte-Bereich 33 <= x <= 126) und sind typischerweise im Format "package/version-os" (z. B. "git/1.8.3.1-Linux"), wobei os der Name des Betriebssystems ist (z. B. "Linux"). X und Y können über die Umgebungsvariable GIT_USER_AGENT konfiguriert werden und haben Vorrang. Das os wird über das Feld sysname des Systemaufrufs uname(2) oder sein Äquivalent abgerufen. Die Agenten-Strings sind rein informativ für Statistik- und Debuggingzwecke und DÜRFEN nicht verwendet werden, um programmgesteuert das Vorhandensein oder Fehlen bestimmter Funktionen anzunehmen.

ls-refs

ls-refs ist der Befehl, der in v2 zur Anforderung einer Referenzanzeige verwendet wird. Im Gegensatz zur aktuellen Referenzanzeige nimmt ls-refs Argumente entgegen, die verwendet werden können, um die vom Server gesendeten Refs zu begrenzen.

Zusätzliche Funktionen, die im Basisbefehl nicht unterstützt werden, werden als Wert des Befehls in der Fähigkeitsanzeige in Form einer durch Leerzeichen getrennten Liste von Merkmalen angezeigt: "<Befehl>=<Merkmal-1> <Merkmal-2>"

ls-refs nimmt die folgenden Argumente entgegen

   symrefs
In addition to the object pointed by it, show the underlying ref
pointed by it when showing a symbolic ref.
   peel
Show peeled tags.
   ref-prefix <prefix>
When specified, only references having a prefix matching one of
the provided prefixes are displayed. Multiple instances may be
given, in which case references matching any prefix will be
shown. Note that this is purely for optimization; a server MAY
show refs not matching the prefix if it chooses, and clients
should filter the result themselves.

Wenn das Merkmal unborn angezeigt wird, kann das folgende Argument in die Client-Anfrage aufgenommen werden.

   unborn
The server will send information about HEAD even if it is a symref
pointing to an unborn branch in the form "unborn HEAD
symref-target:<target>".

Die Ausgabe von ls-refs ist wie folgt:

output = *ref
  flush-pkt
obj-id-or-unborn = (obj-id | "unborn")
ref = PKT-LINE(obj-id-or-unborn SP refname *(SP ref-attribute) LF)
ref-attribute = (symref | peeled)
symref = "symref-target:" symref-target
peeled = "peeled:" obj-id

fetch

fetch ist der Befehl, der in v2 zum Abrufen eines Packfiles verwendet wird. Er kann als modifizierte Version des v1-Fetch betrachtet werden, bei der die Ref-Anzeige entfernt wurde (da der Befehl ls-refs diese Rolle erfüllt) und das Nachrichtenformat angepasst wurde, um Redundanzen zu eliminieren und die einfache Hinzufügung zukünftiger Erweiterungen zu ermöglichen.

Zusätzliche Funktionen, die im Basisbefehl nicht unterstützt werden, werden als Wert des Befehls in der Fähigkeitsanzeige in Form einer durch Leerzeichen getrennten Liste von Merkmalen angezeigt: "<Befehl>=<Merkmal-1> <Merkmal-2>"

Eine fetch-Anfrage kann die folgenden Argumente entgegennehmen:

   want <oid>
Indicates to the server an object which the client wants to
retrieve.  Wants can be anything and are not limited to
advertised objects.
   have <oid>
Indicates to the server an object which the client has locally.
This allows the server to make a packfile which only contains
the objects that the client needs. Multiple 'have' lines can be
supplied.
   done
Indicates to the server that negotiation should terminate (or
not even begin if performing a clone) and that the server should
use the information supplied in the request to construct the
packfile.
   thin-pack
Request that a thin pack be sent, which is a pack with deltas
which reference base objects not contained within the pack (but
are known to exist at the receiving end). This can reduce the
network traffic significantly, but it requires the receiving end
to know how to "thicken" these packs by adding the missing bases
to the pack.
   no-progress
Request that progress information that would normally be sent on
side-band channel 2, during the packfile transfer, should not be
sent.  However, the side-band channel 3 is still used for error
responses.
   include-tag
Request that annotated tags should be sent if the objects they
point to are being sent.
   ofs-delta
Indicate that the client understands PACKv2 with delta referring
to its base by position in pack rather than by an oid.  That is,
they can read OBJ_OFS_DELTA (aka type 6) in a packfile.

Wenn das Merkmal shallow angezeigt wird, können die folgenden Argumente in die Client-Anfrage sowie die potenzielle Hinzufügung des Abschnitts shallow-info in der Serverantwort, wie unten erläutert, aufgenommen werden.

   shallow <oid>
A client must notify the server of all commits for which it only
has shallow copies (meaning that it doesn't have the parents of
a commit) by supplying a 'shallow <oid>' line for each such
object so that the server is aware of the limitations of the
client's history.  This is so that the server is aware that the
client may not have all objects reachable from such commits.
   deepen <depth>
Requests that the fetch/clone should be shallow having a commit
depth of <depth> relative to the remote side.
   deepen-relative
Requests that the semantics of the "deepen" command be changed
to indicate that the depth requested is relative to the client's
current shallow boundary, instead of relative to the requested
commits.
   deepen-since <timestamp>
Requests that the shallow clone/fetch should be cut at a
specific time, instead of depth.  Internally it's equivalent to
doing "git rev-list --max-age=<timestamp>". Cannot be used with
"deepen".
   deepen-not <rev>
Requests that the shallow clone/fetch should be cut at a
specific revision specified by '<rev>', instead of a depth.
Internally it's equivalent of doing "git rev-list --not <rev>".
Cannot be used with "deepen", but can be used with
"deepen-since".

Wenn das Merkmal filter angezeigt wird, kann das folgende Argument in die Client-Anfrage aufgenommen werden.

   filter <filter-spec>
Request that various objects from the packfile be omitted
using one of several filtering techniques. These are intended
for use with partial clone and partial fetch operations. See
`rev-list` for possible "filter-spec" values. When communicating
with other processes, senders SHOULD translate scaled integers
(e.g. "1k") into a fully-expanded form (e.g. "1024") to aid
interoperability with older receivers that may not understand
newly-invented scaling suffixes. However, receivers SHOULD
accept the following suffixes: 'k', 'm', and 'g' for 1024,
1048576, and 1073741824, respectively.

Wenn das Merkmal ref-in-want angezeigt wird, kann das folgende Argument in die Client-Anfrage aufgenommen werden, ebenso wie die potenzielle Hinzufügung des Abschnitts wanted-refs in der Serverantwort, wie unten erläutert.

   want-ref <ref>
Indicates to the server that the client wants to retrieve a
particular ref, where <ref> is the full name of a ref on the
server.  It is a protocol error to send want-ref for the
same ref more than once.

Wenn das Merkmal sideband-all angezeigt wird, kann das folgende Argument in die Client-Anfrage aufgenommen werden.

   sideband-all
Instruct the server to send the whole response multiplexed, not just
the packfile section. All non-flush and non-delim PKT-LINE in the
response (not only in the packfile section) will then start with a byte
indicating its sideband (1, 2, or 3), and the server may send "0005\2"
(a PKT-LINE of sideband 2 with no payload) as a keepalive packet.

Wenn das Merkmal packfile-uris angezeigt wird, kann das folgende Argument in die Client-Anfrage aufgenommen werden, ebenso wie die potenzielle Hinzufügung des Abschnitts packfile-uris in der Serverantwort, wie unten erläutert. Beachten Sie, dass höchstens eine Zeile packfile-uris an den Server gesendet werden kann.

   packfile-uris <comma-separated-list-of-protocols>
Indicates to the server that the client is willing to receive
URIs of any of the given protocols in place of objects in the
sent packfile. Before performing the connectivity check, the
client should download from all given URIs. Currently, the
protocols supported are "http" and "https".

Wenn das Merkmal wait-for-done angezeigt wird, kann das folgende Argument in die Client-Anfrage aufgenommen werden.

   wait-for-done
Indicates to the server that it should never send "ready", but
should wait for the client to say "done" before sending the
packfile.

Die Antwort von fetch ist in mehrere Abschnitte unterteilt, die durch Trennpakete (0001) getrennt sind, wobei jeder Abschnitt mit seinem Abschnittsheader beginnt. Die meisten Abschnitte werden nur gesendet, wenn das Packfile gesendet wird.

output = acknowledgements flush-pkt |
  [acknowledgments delim-pkt] [shallow-info delim-pkt]
  [wanted-refs delim-pkt] [packfile-uris delim-pkt]
  packfile flush-pkt
acknowledgments = PKT-LINE("acknowledgments" LF)
    (nak | *ack)
    (ready)
ready = PKT-LINE("ready" LF)
nak = PKT-LINE("NAK" LF)
ack = PKT-LINE("ACK" SP obj-id LF)
shallow-info = PKT-LINE("shallow-info" LF)
 *PKT-LINE((shallow | unshallow) LF)
shallow = "shallow" SP obj-id
unshallow = "unshallow" SP obj-id
wanted-refs = PKT-LINE("wanted-refs" LF)
*PKT-LINE(wanted-ref LF)
wanted-ref = obj-id SP refname
packfile-uris = PKT-LINE("packfile-uris" LF) *packfile-uri
packfile-uri = PKT-LINE(40*(HEXDIGIT) SP *%x20-ff LF)
packfile = PKT-LINE("packfile" LF)
    *PKT-LINE(%x01-03 *%x00-ff)
   acknowledgments section
* If the client determines that it is finished with negotiations by
  sending a "done" line (thus requiring the server to send a packfile),
  the acknowledgments sections MUST be omitted from the server's
  response.
  • Beginnt immer mit dem Abschnittsheader "acknowledgments"

  • Der Server antwortet mit "NAK", wenn keine der als "have"-Zeilen gesendeten Objekt-IDs übereinstimmend war.

  • Der Server antwortet mit "ACK obj-id" für alle als "have"-Zeilen gesendeten Objekt-IDs, die übereinstimmend waren.

  • Eine Antwort kann nicht sowohl "ACK"-Zeilen als auch eine "NAK"-Zeile enthalten.

  • Der Server antwortet mit einer "ready"-Zeile, die anzeigt, dass der Server eine akzeptable gemeinsame Basis gefunden hat und bereit ist, ein Packfile zu erstellen und zu senden (das sich im Packfile-Abschnitt derselben Antwort befindet).

  • Wenn der Server einen geeigneten Schnittpunkt gefunden hat und beschlossen hat, eine "ready"-Zeile zu senden, kann der Server (als Optimierung) darauf verzichten, alle "ACK"-Zeilen zu senden, die er während seiner Antwort gesendet hätte. Dies liegt daran, dass der Server bereits die Objekte bestimmt hat, die er an den Client senden möchte, und keine weitere Aushandlung erforderlich ist.

       shallow-info section
    * If the client has requested a shallow fetch/clone, a shallow
      client requests a fetch or the server is shallow then the
      server's response may include a shallow-info section.  The
      shallow-info section will be included if (due to one of the
      above conditions) the server needs to inform the client of any
      shallow boundaries or adjustments to the clients already
      existing shallow boundaries.
  • Beginnt immer mit dem Abschnittsheader "shallow-info"

  • Wenn eine positive Tiefe angefordert wird, berechnet der Server die Menge der Commits, die nicht tiefer als die gewünschte Tiefe sind.

  • Der Server sendet für jeden Commit, dessen Eltern im folgenden Packfile nicht gesendet werden, eine "shallow obj-id"-Zeile.

  • Der Server sendet eine "unshallow obj-id"-Zeile für jeden Commit, den der Client als flach angegeben hat, der aber aufgrund des Fetches nicht mehr flach ist (da seine Eltern im folgenden Packfile gesendet werden).

  • Der Server darf keine "unshallow"-Zeilen für etwas senden, das der Client nicht als Teil seiner Anfrage als flach angegeben hat.

       wanted-refs section
    * This section is only included if the client has requested a
      ref using a 'want-ref' line and if a packfile section is also
      included in the response.
  • Beginnt immer mit dem Abschnittsheader "wanted-refs".

  • Der Server sendet eine Ref-Liste ("<oid> <refname>") für jede über want-ref-Zeilen angeforderte Referenz.

  • Der Server darf keine Refs senden, die nicht über want-ref-Zeilen angefordert wurden.

       packfile-uris section
    * This section is only included if the client sent
      'packfile-uris' and the server has at least one such URI to
      send.
  • Beginnt immer mit dem Abschnittsheader "packfile-uris".

  • Für jede gesendete URI sendet der Server einen Hash des Pack-Inhalts (wie von git index-pack ausgegeben), gefolgt von der URI.

  • Die Hashes sind 40 Hexadezimalzeichen lang. Wenn Git auf einen neuen Hash-Algorithmus aktualisiert wird, muss dies möglicherweise aktualisiert werden. (Es sollte dem entsprechen, was index-pack nach "pack\t" oder "keep\t" ausgibt).

       packfile section
    * This section is only included if the client has sent 'want'
      lines in its request and either requested that no more
      negotiation be done by sending 'done' or if the server has
      decided it has found a sufficient cut point to produce a
      packfile.
  • Beginnt immer mit dem Abschnittsheader "packfile"

  • Die Übertragung des Packfiles beginnt unmittelbar nach dem Abschnittsheader.

  • Die Datenübertragung des Packfiles ist immer gemultiplext und verwendet dieselbe Semantik wie die sideband-64k-Fähigkeit aus Protokollversion 1. Das bedeutet, dass jedes Paket während des Packfile-Datenstroms aus einer führenden 4-Byte-Paketzeilenlänge (typisch für das Paketzeilenformat), gefolgt von einem 1-Byte-Stream-Code und dann den eigentlichen Daten besteht.

     The stream code can be one of:
    1 - pack data
    2 - progress messages
    3 - fatal error message just before stream aborts

server-option

Wenn angezeigt, zeigt dies an, dass eine beliebige Anzahl serverspezifischer Optionen in eine Anfrage aufgenommen werden kann. Dies geschieht durch Senden jeder Option als "server-option=<option>"-Fähigkeitszeile im Fähigkeitslistenabschnitt einer Anfrage.

Die bereitgestellten Optionen dürfen kein NUL- oder LF-Zeichen enthalten.

object-format

Der Server kann die Fähigkeit object-format mit dem Wert X (in der Form object-format=X) anzeigen, um den Client darüber zu informieren, dass der Server Objekte mit dem Hash-Algorithmus X verarbeiten kann. Wenn nicht angegeben, wird angenommen, dass der Server nur SHA-1 unterstützt. Wenn der Client einen anderen Hash-Algorithmus als SHA-1 verwenden möchte, sollte er seine Objektformat-Zeichenfolge angeben.

session-id=<session-id>

Der Server kann eine Sitzungs-ID anzeigen, die verwendet werden kann, um diesen Prozess über mehrere Anfragen hinweg zu identifizieren. Der Client kann auch seine eigene Sitzungs-ID an den Server zurückgeben.

Sitzungs-IDs sollten für einen gegebenen Prozess eindeutig sein. Sie müssen in eine Paketzeile passen und dürfen keine nicht druckbaren Zeichen oder Leerzeichen enthalten. Die aktuelle Implementierung verwendet trace2-Sitzungs-IDs (siehe api-trace2 für Details), aber dies kann sich ändern, und Benutzer der Sitzungs-ID sollten sich nicht darauf verlassen.

object-info

object-info ist der Befehl zum Abrufen von Informationen über ein oder mehrere Objekte. Sein Hauptzweck ist es, dem Client zu ermöglichen, Entscheidungen auf der Grundlage dieser Informationen zu treffen, ohne die Objekte vollständig abrufen zu müssen. Die Objektgröße ist die einzige derzeit unterstützte Information.

Eine object-info-Anfrage nimmt die folgenden Argumente entgegen:

size
Requests size information to be returned for each listed object id.
oid <oid>
Indicates to the server an object which the client wants to obtain
information for.

Die Antwort von object-info ist eine Liste der angeforderten Objekt-IDs und zugehörigen angeforderten Informationen, jeweils durch ein einzelnes Leerzeichen getrennt.

output = info flush-pkt
info = PKT-LINE(attrs) LF)
	*PKT-LINE(obj-info LF)
attrs = attr | attrs SP attrs
attr = "size"
obj-info = obj-id SP obj-size

bundle-uri

Wenn die Fähigkeit bundle-uri angezeigt wird, unterstützt der Server den Befehl 'bundle-uri'.

Die Fähigkeit wird derzeit ohne Wert angezeigt (d. h. nicht "bundle-uri=somevalue"). Ein Wert kann in Zukunft für die Unterstützung von Befehls-weiten Erweiterungen hinzugefügt werden. Clients MÜSSEN unbekannte Fähigkeitswerte ignorieren und mit dem 'bundle-uri'-Dialog fortfahren, den sie unterstützen.

Der Befehl bundle-uri ist dazu gedacht, vor fetch ausgegeben zu werden, um URIs zu Bundle-Dateien (siehe git-bundle[1]) zu erhalten, um den nachfolgenden fetch-Befehl zu "seeden" und zu informieren.

Der Client KANN bundle-uri vor oder nach jedem anderen gültigen Befehl ausgeben. Um für Clients nützlich zu sein, wird erwartet, dass er nach einem ls-refs und vor einem fetch ausgegeben wird, kann aber jederzeit im Dialog ausgegeben werden.

Diskussion zu bundle-uri

Die Absicht der Funktion ist es, den Ressourcenverbrauch des Servers im häufigen Fall zu optimieren, indem der häufige Fall des Abrufens eines sehr großen PACKS während git-clone[1] in einen kleineren inkrementellen Fetch umgewandelt wird.

Es ermöglicht den Servern auch eine bessere Caching in Kombination mit einem uploadpack.packObjectsHook (siehe git-config[1]).

Indem neue Klone oder Fetches eine vorhersagbarere und häufigere Aushandlung gegen die Spitzen kürzlich produzierter *.bundle-Dateien darstellen, könnten Server sogar die Ergebnisse solcher Aushandlungen für den uploadpack.packObjectsHook vorab generieren, wenn neue Pushes eintreffen.

Eine Möglichkeit, wie Server diese Bundles nutzen könnten, ist, dass der Server davon ausgeht, dass frische Klone ein bekanntes Bundle herunterladen, gefolgt von einem Nachholen des aktuellen Zustands des Repositorys mithilfe der Ref-Spitzen, die in diesem Bundle (oder Bundles) gefunden werden.

PROTOKOLL für bundle-uri

Eine bundle-uri-Anfrage nimmt keine Argumente entgegen und bewirbt, wie oben erwähnt, derzeit keinen Fähigkeitswert. Beide können in Zukunft hinzugefügt werden.

Wenn der Client eine command=bundle-uri-Anfrage ausgibt, ist die Antwort eine Liste von Schlüssel-Wert-Paaren, die als Paketzeilen mit dem Wert <key>=<value> bereitgestellt werden. Jeder <key> sollte als Konfigurationsschlüssel aus dem Namensraum bundle.* interpretiert werden, um eine Liste von Bundles zu erstellen. Diese Schlüssel sind nach einer bundle.<id>.-Untersektion gruppiert, wobei jeder Schlüssel, der einem bestimmten <id> entspricht, Attribute zu dem durch dieses <id> definierten Bundle beiträgt. Siehe git-config[1] für die spezifischen Details dieser Schlüssel und wie der Git-Client ihre Werte interpretieren wird.

Clients MÜSSEN die Zeile gemäß dem obigen Format parsen, Zeilen, die nicht dem Format entsprechen, SOLLTEN verworfen werden. Der Benutzer KANN in einem solchen Fall gewarnt werden.

bundle-uri CLIENT- UND SERVERERWARTUNGEN

URI-INHALTE

Der Inhalt an den angezeigten URIs muss eine der beiden folgenden Arten sein.

Die angezeigte URI kann eine Bundle-Datei enthalten, die git bundle verify akzeptieren würde. D. h., sie MUSS eine oder mehrere Referenzspitzen für die Verwendung durch den Client enthalten, MUSS Voraussetzungen (falls vorhanden) mit Standard- "-" Präfixen angeben und MUSS ihr "object-format", falls zutreffend, angeben.

Die angezeigte URI kann alternativ eine Klartextdatei enthalten, die git config --list akzeptieren würde (mit der Option --file). Die Schlüssel-Wert-Paare in dieser Liste befinden sich im Namensraum bundle.* (siehe git-config[1]).

bundle-uri CLIENT FEHLERBEHEBUNG

Ein Client muss vor allem Fehler elegant abbauen, sei es aufgrund schlechter fehlender Daten im Bundle-URI, weil der Client zu dumm ist, z. B. Bundle-Header und ihre Voraussetzungsbeziehungen zu verstehen und vollständig zu parsen, oder aus anderen Gründen.

Serverbetreiber können zuversichtlich sein, "bundle-uri" zu aktivieren und sich keine Sorgen zu machen, wenn z. B. ihr CDN ausfällt, und Klone oder Fetches auf harte Fehler stoßen. Selbst wenn die Server-Bundles unvollständig oder in irgendeiner Weise fehlerhaft sind, sollte der Client immer noch ein funktionierendes Repository erhalten, als ob er dieses Protokollerweiterung nicht verwendet hätte.

Alle nachfolgenden Diskussionen über Client- und Serverinteraktion MÜSSEN dies berücksichtigen.

bundle-uri SERVER ZU CLIENT

Die Reihenfolge der zurückgegebenen Bundle-URIs ist nicht signifikant. Clients MÜSSEN ihre Header parsen, um ihre enthaltenen OIDs und Voraussetzungen zu entdecken. Ein Client MUSS den Inhalt der Bundle(s) selbst und ihren Header als ultimative Wahrheitsquelle betrachten.

Ein Server KANN sogar Bundles zurückgeben, die keine direkte Beziehung zu dem geklonten Repository haben (entweder versehentlich oder durch absichtliche "clevere" Konfiguration) und erwarten, dass ein Client sortiert, welche Daten er aus den Bundle(s) haben möchte, falls überhaupt.

bundle-uri CLIENT ZU SERVER

Der Client SOLLTE Referenzspitzen aus dem Bundle-Header an den nachfolgenden fetch-Anfragen als have-Zeilen bereitstellen. Ein Client KANN die Bundles auch vollständig ignorieren, wenn dies aus irgendeinem Grund als schlechter erachtet wird, z. B. wenn die Bundles nicht heruntergeladen werden können, ihm die gefundenen Spitzen nicht gefallen etc.

WENN ANGEZEIGTE BUNDLE(S) KEINE WEITERE VERHANDLUNG ERFORDERN

Wenn der Client nach der Ausgabe von bundle-uri und ls-refs und dem Erhalt der Header der Bundle(s) feststellt, dass die gewünschten Ref-Spitzen vollständig aus den angezeigten Bundle(s) abgerufen werden können, KANN der Client die Verbindung zum Git-Server trennen. Die Ergebnisse eines solchen clone- oder fetch-Vorgangs sollten vom Zustand, der ohne die Verwendung von bundle-uri erreicht wurde, nicht zu unterscheiden sein.

FRÜHE CLIENT-TRENNUNGEN UND FEHLERWIEDERHERSTELLUNG

Ein Client KANN eine frühe Trennung durchführen, während er noch die Bundle(s) herunterlädt (nachdem er ihre Header gestreamt und geparst hat). In einem solchen Fall MUSS der Client Fehler bei der Fertigstellung des Downloads und der Validierung der Bundle(s) elegant wiederherstellen.

Das heißt, ein Client muss möglicherweise eine erneute Verbindung herstellen und einen fetch-Befehl ausgeben und möglicherweise darauf zurückgreifen, die bundle-uri überhaupt nicht zu verwenden.

Dieses "MAY"-Verhalten ist so spezifiziert (und nicht "SHOULD"), unter der Annahme, dass ein Server, der Bundle-URIs anzeigt, wahrscheinlich ein relativ großes Repository bedient und auf URIs verweist, die eine gute Chance haben, in funktionierendem Zustand zu sein. Ein Client KANN z. B. die Nutzlastgröße der Bundles als Heuristik betrachten, um zu sehen, ob eine frühe Trennung sinnvoll ist, falls ein Fallback auf einen vollständigen "fetch"-Dialog erforderlich ist.

WENN ANGEZEIGTE BUNDLE(S) WEITERE VERHANDLUNGEN ERFORDERN

Ein Client SOLLTE eine Aushandlung eines PACKS vom Server über den Befehl "fetch" unter Verwendung der OID-Spitzen aus den angezeigten Bundles beginnen, auch wenn er noch dabei ist, diese Bundle(s) herunterzuladen.

Dies ermöglicht aggressive frühe Trennungen von jedem interaktiven Server-Dialog. Der Client vertraut blind darauf, dass die angezeigten OID-Spitzen relevant sind, und gibt sie als have-Zeilen aus. Er fordert dann alle Spitzen an, die er wünscht (normalerweise aus der "ls-refs"-Anzeige) über want-Zeilen. Der Server berechnet dann ein (hoffentlich kleines) PACK mit der erwarteten Differenz zwischen den Spitzen aus den Bundle(s) und den angeforderten Daten.

Die einzige Verbindung, die der Client aktiv halten muss, ist die zu den gleichzeitig heruntergeladenen statischen Bundle(s). Wenn diese und das inkrementelle PACK abgerufen wurden, sollten sie entpackt und validiert werden. Alle Fehler zu diesem Zeitpunkt sollten elegant wiederhergestellt werden, siehe oben.

bundle-uri PROTOKOLL-FUNKTIONEN

Der Client erstellt eine Bundle-Liste aus den von Server bereitgestellten Schlüssel-Wert-Paaren (<key>=<value>). Diese Paare sind Teil des Namensraums bundle.*, wie in git-config[1] dokumentiert. In diesem Abschnitt besprechen wir einige dieser Schlüssel und beschreiben die Aktionen, die der Client als Reaktion auf diese Informationen ausführt.

Insbesondere der Schlüssel bundle.version gibt einen ganzzahligen Wert an. Der einzige akzeptierte Wert ist derzeit 1. Wenn der Client hier jedoch einen unerwarteten Wert sieht, MUSS der Client die Bundle-Liste ignorieren.

Solange bundle.version verstanden wird, können alle anderen unbekannten Schlüssel vom Client ignoriert werden. Der Server garantiert die Kompatibilität mit älteren Clients, neuere Clients können jedoch möglicherweise die zusätzlichen Schlüssel besser nutzen, um Downloads zu minimieren.

Jede rückwärtsinkompatible Hinzufügung von vor-URI-Schlüssel-Wert-Paaren wird durch einen neuen bundle.version-Wert oder Werte in der bundle-uri-Fähigkeitsanzeige selbst und/oder durch neue zukünftige bundle-uri-Anfrageargumente geschützt.

Einige Beispiel-Schlüssel-Wert-Paare, die derzeit nicht implementiert sind, aber in Zukunft implementiert werden könnten, sind:

  • Fügen Sie einen "hash=<val>" oder "size=<bytes>" hinzu, um den erwarteten Hash oder die Größe der Bundle-Datei anzuzeigen.

  • Anzeigen, dass eine oder mehrere Bundle-Dateien gleich sind (damit Clients z. B. Round-Robin oder anderweitig eine von N möglichen Dateien auswählen).

  • Eine "oid=<OID>"-Abkürzung und eine "prerequisite=<OID>"-Abkürzung. Zur Darstellung des häufigen Falls eines Bundles mit einer Spitze und keinen Voraussetzungen oder einer Spitze und einer Voraussetzung.

    Dies würde es ermöglichen, den häufigen Fall von Servern zu optimieren, die ein "großes Bundle" mit nur ihrem "Hauptzweig" und/oder inkrementellen Updates davon bereitstellen möchten.

    Ein Client, der eine solche Antwort erhält, KANN davon ausgehen, dass er das Abrufen des Headers aus einem Bundle an der angegebenen URI überspringen kann und sich und den Server(n) somit die Anfragen ersparen kann, die zur Inspektion der Header dieses oder dieser Bundles erforderlich sind.

promisor-remote=<pr-info>

Der Server kann einige Promisor-Remotes anzeigen, die er verwendet oder von denen er weiß, die ein Client als seine Promisor-Remotes verwenden kann, anstelle dieses Repositorys. In diesem Fall sollte <pr-info> die Form haben

pr-info = pr-fields | pr-info ";" pr-fields
pr-fields = pr-field | pr-fields "," pr-field
pr-field = field-name "=" field-value

wobei alle Feldname und Feldwert in einem gegebenen pr-fields Feldnamen und Werte für ein einzelnes Promisor-Remote sind. Ein bestimmter Feldname darf in den gegebenen pr-fields nicht mehr als einmal vorkommen.

Der Server MUSS mindestens die Feldnamen "name" und "url" zusammen mit den zugehörigen Feldwerten anzeigen, die der Name eines gültigen Remotes und seine URL sind, in jedem pr-fields. Die Felder "name" und "url" MÜSSEN zuerst in jedem pr-fields in dieser Reihenfolge erscheinen.

Nach diesen obligatorischen Feldern KANN der Server die folgenden optionalen Felder in beliebiger Reihenfolge anzeigen:

partialCloneFilter

Die vom Remote verwendete Filter-Spezifikation. Clients können dies verwenden, um festzustellen, ob die Filterstrategie des Remotes mit ihren Anforderungen kompatibel ist (z. B. Prüfung, ob beide "blob:none" verwenden). Dies entspricht der Konfigurationseinstellung "remote.<name>.partialCloneFilter".

token

Ein Authentifizierungstoken, das Clients beim Verbinden mit dem Remote verwenden können. Dies entspricht der Konfigurationseinstellung "remote.<name>.token".

Andere Felder sind derzeit nicht im Protokoll definiert. Feldnamen sind Groß-/Kleinschreibung-sensitiv und MÜSSEN genau wie oben angegeben übertragen werden. Clients MÜSSEN unbekannte Felder ignorieren, um zukünftige Protokollerweiterungen zu ermöglichen.

Für den Moment kann der Client nur die über diese Felder übertragenen Informationen verwenden, um zu entscheiden, ob er den beworbenen Promisor Remote akzeptiert. In Zukunft könnten diese Informationen jedoch für andere Zwecke verwendet werden.

Feldwerte MÜSSEN urlcodiert sein.

Wenn der Client beschließt, einen oder mehrere von dem Server beworbene Promisor Remotes zu verwenden, kann er mit "promisor-remote=<pr-names>" antworten, wobei <pr-names> die Form haben sollte

pr-names = pr-name | pr-names ";" pr-name

wobei pr-name der urlcodierte Name eines vom Server beworbenen Promisor Remotes ist, den der Client akzeptiert.

Beachten Sie, dass in diesem Dokument die Zeichen ; und , überall kodiert sein MÜSSEN, wenn sie in pr-name oder field-value vorkommen.

Wenn der Server keine Promisor Remotes kennt, die für einen Client nützlich sein könnten, oder wenn er es vorzieht, dass ein Client keine Promisor Remotes verwendet oder kennt, sollte er die "promisor-remote"-Funktion überhaupt nicht bewerben.

In diesem Fall oder wenn der Client keine vom Server beworbenen Promisor Remotes verwenden möchte, sollte der Client die "promisor-remote"-Funktion in seiner Antwort überhaupt nicht bewerben.

Auf der Serverseite können die Konfigurationsoptionen "promisor.advertise" und "promisor.sendFields" verwendet werden, um zu steuern, was beworben wird. Auf der Clientseite kann die Konfigurationsoption "promisor.acceptFromServer" verwendet werden, um zu steuern, was akzeptiert wird. Weitere Informationen finden Sie in der Dokumentation dieser Konfigurationsoptionen.

Beachten Sie, dass es in Zukunft schön wäre, wenn das "promisor-remote"-Protokollmerkmal vom Server verwendet werden könnte, um bei der Beantwortung von git fetch oder git clone besser vernetzte Remotes zu bewerben, die der Client als Promisor Remotes verwenden kann, anstelle dieses Repositorys, damit der Client Objekte von diesen anderen besser vernetzten Remotes faul abrufen kann. Dies würde erfordern, dass der Server in seiner Antwort die Objekte weglässt, die auf den vom Client akzeptierten besser vernetzten Remotes verfügbar sind. Dies wurde jedoch noch nicht implementiert. Für den Moment ist diese "promisor-remote"-Funktion also nur dann nützlich, wenn der Server einige Promisor Remotes bewirbt, von denen er bereits Objekte ausleiht.

GIT

Teil der git[1] Suite