Μετάβαση στο περιεχόμενο

Πρωτόκολλα

Το Pitmaster υποστηρίζει πολλαπλά πρωτόκολλα μεταφοράς δικτύου για επικοινωνία με διακομιστές git. Το smart HTTP είναι το κύριο transport. Διατίθενται επιπλέον πρωτόκολλα για ευρύτερη συμβατότητα.

Smart HTTP (κύριο)

Το προτεινόμενο transport. Λειτουργεί μέσω HTTPS και είναι το ευρύτερα χρησιμοποιούμενο πρωτόκολλο. Δεν υπάρχει API για προσαρμοσμένες κεφαλίδες ή διαπιστευτήρια· τα διαπιστευτήρια μπορούν να περαστούν μόνο στο URL (https://user:token@host/repo.git), το οποίο το PHP στέλνει ως βασικό έλεγχο ταυτότητας. Το clone() αποθηκεύει το URL, μαζί με τα διαπιστευτήρια, ως remote.origin.url στο .git/config. Τα αιτήματα χρησιμοποιούν τα stream wrappers του PHP, επομένως πρέπει να είναι ενεργοποιημένο το allow_url_fopen.

PHP
use Pitmaster\Protocol\SmartHttpClient;

$http = new SmartHttpClient(timeout: 30);
$discovery = $http->discoverRefs('https://github.com/user/repo.git');

Για όλες τις λεπτομέρειες, δείτε το Smart HTTP.

Πρωτόκολλο v1

Το παραδοσιακό πρωτόκολλο smart HTTP. Όλα τα refs αποστέλλονται κατά τον εντοπισμό και η διαπραγμάτευση χρησιμοποιεί γραμμές want/have/done.

PHP
use Pitmaster\Protocol\ProtocolV1;

Πρωτόκολλο v2

Το νεότερο πρωτόκολλο με δομημένες εντολές (ls-refs, fetch). Είναι αποδοτικότερο για αποθετήρια με πολλά refs, επειδή ο πελάτης μπορεί να φιλτράρει τη λίστα refs.

Τα clone() και fetch() χρησιμοποιούν πάντα το πρωτόκολλο v1. Το πρωτόκολλο v2 είναι διαθέσιμο ρητά μέσω smart HTTP με τα SmartHttpClient::discoverRefsV2() και UploadPackClient::fetchV2().

Απλοϊκό HTTP

Εναλλακτική λύση για διακομιστές που δεν υποστηρίζουν το πρωτόκολλο smart HTTP. Το dumb πρωτόκολλο ανακτά αντικείμενα και pack μεμονωμένα μέσω απλών αιτημάτων GET HTTP.

PHP
use Pitmaster\Protocol\DumbHttpClient;

$client = new DumbHttpClient();

Περιορισμοί του dumb HTTP:

  • Δεν υπάρχει διαπραγμάτευση (ο πελάτης πρέπει να κατεβάσει τα πάντα)
  • Δεν γίνεται συμπίεση delta κατά τη μεταφορά
  • Είναι σημαντικά πιο αργό από το smart HTTP
  • Ορισμένοι διακομιστές (GitHub, GitLab) δεν το υποστηρίζουν

Το dumb πρωτόκολλο ανακτά:

  1. GET /info/refs (απλό κείμενο, χωρίς pkt-line)
  2. GET /HEAD (προεπιλεγμένο branch)
  3. GET /objects/info/packs (λίστα διαθέσιμων pack)
  4. GET /objects/pack/pack-<hash>.pack και .idx (κάθε καταχωρισμένο pack και το index του)
  5. GET /objects/<xx>/<rest> (μεμονωμένα loose αντικείμενα, με περιήγηση από τις κορυφές των refs)

Το βήμα 5 εκτελείται μόνο όταν ο διακομιστής δεν καταχωρίζει κανένα pack. Όταν καταχωρίζει pack, δεν λαμβάνονται αντικείμενα που υπάρχουν μόνο ως loose αρχεία στον διακομιστή (#18). Ο dumb πελάτης δέχεται μόνο αναγνωριστικά αντικειμένων 40 χαρακτήρων (SHA-1). Τα clone() και fetch() επιστρέφουν στο dumb HTTP όταν αποτυγχάνει η ανταλλαγή smart HTTP.

SSH

Το transport SSH χρησιμοποιεί την επέκταση ssh2 PHP όταν είναι φορτωμένη. Διαφορετικά εκκινεί τον πελάτη συστήματος ssh μέσω proc_open(). Και στις δύο περιπτώσεις εκτελεί το git-upload-pack ή το git-receive-pack στο απομακρυσμένο σύστημα.

PHP
use Pitmaster\Protocol\SshClient;

$client = new SshClient();

Διευθύνσεις URL SSH:

Κώδικας
git@github.com:user/repo.git
ssh://git@github.com/user/repo.git

Δεν απαιτείται επέκταση. Οι δύο διαδρομές λειτουργούν διαφορετικά:

Πελάτης συστήματος ssh (χρησιμοποιείται όταν δεν είναι φορτωμένο το ssh2). Το Pitmaster εκτελεί το ssh -o BatchMode=yes -o ConnectTimeout=30 -p <port> <user>@<host> <command>, επομένως ο έλεγχος ταυτότητας και ο έλεγχος κλειδιού host ακολουθούν τη διαμόρφωση SSH και τον agent σας. Αυτές οι μεταβλητές περιβάλλοντος προσαρμόζουν την εντολή:

Μεταβλητή Επίδραση
PITMASTER_SSH_COMMAND Εκτελέσιμο αρχείο που εκτελείται αντί του ssh
PITMASTER_SSH_IDENTITY_FILE Περνά ως -i <file>
PITMASTER_SSH_KNOWN_HOSTS Περνά ως -o UserKnownHostsFile=<file>
PITMASTER_SSH_STRICT_HOST_KEY_CHECKING Περνά ως -o StrictHostKeyChecking=<value>

Αυτή η διαδρομή εκκινεί διεργασία, επομένως δεν είναι διαθέσιμη σε handles που ανοίχτηκαν με ['processes' => false].

Επέκταση ssh2 (προτιμάται πάντα όταν είναι φορτωμένη). Το Pitmaster πραγματοποιεί έλεγχο ταυτότητας με ~/.ssh/id_rsa και έπειτα με ~/.ssh/id_ed25519 αν το κλειδί RSA υπάρχει αλλά απορρίφθηκε, και διαφορετικά με τον agent SSH. Οι μεταβλητές PITMASTER_SSH_* αγνοούνται και το κλειδί host του διακομιστή δεν επαληθεύεται σε αυτή τη διαδρομή (#22).

Το transport SSH εκτελεί το git-upload-pack ή το git-receive-pack ως απομακρυσμένη εντολή και επικοινωνεί μέσω του καναλιού SSH, χρησιμοποιώντας το ίδιο πρωτόκολλο pkt-line με το smart HTTP.

Πρωτόκολλο Git (TCP)

Το εγγενές πρωτόκολλο git επικοινωνεί μέσω της θύρας TCP 9418 χρησιμοποιώντας sockets PHP. Το GitProtocolClient υλοποιεί τον εντοπισμό refs και το upload-pack (ανάκτηση)· δεν μπορεί να κάνει push. Τα clone() και fetch() δεν δρομολογούν διευθύνσεις URL git:// προς αυτό, επομένως χρησιμοποιήστε απευθείας τον πελάτη.

PHP
use Pitmaster\Protocol\GitProtocolClient;

$client = new GitProtocolClient();

Διευθύνσεις URL Git:

Κώδικας
git://github.com/user/repo.git

Χαρακτηριστικά:

  • Δεν υπάρχει έλεγχος ταυτότητας (στην πράξη μόνο για ανάγνωση)
  • Δεν υπάρχει κρυπτογράφηση
  • Έχει καταργηθεί από τους περισσότερους παρόχους φιλοξενίας
  • Χρησιμοποιεί την ίδια πλαισίωση pkt-line με το smart HTTP

Το πρωτόκολλο git στέλνει το όνομα της υπηρεσίας και τη διαδρομή του αποθετηρίου ως αρχικό αίτημα και έπειτα συνεχίζει με τον τυπικό εντοπισμό refs pkt-line και τη διαπραγμάτευση pack.

Πακέτα

Τα bundles Git είναι offline αρχεία pack με πληροφορίες refs. Επιτρέπουν τη μεταφορά δεδομένων αποθετηρίου χωρίς σύνδεση δικτύου.

PHP
use Pitmaster\Protocol\Bundle;

// Read a bundle file
$bundle = Bundle::open('/path/to/repo.bundle');
$refs = $bundle->refs();
$packData = $bundle->packData();
$prerequisites = $bundle->prerequisites();

// Create one
$bundle = Bundle::create(['refs/heads/main' => $commitId], $packData);
$bundle->writeTo('/path/to/out.bundle');

Το Pitmaster διαβάζει κεφαλίδες bundle v2 και v3. Δεν υπάρχει μέθοδος Repository για εισαγωγή bundle: γράψτε το packData() στο .git/objects/pack/, δημιουργήστε το index του με το PackIndexer::writeIndex() και ενημερώστε μόνοι σας τα refs.

Μορφή bundle:

Κώδικας
# v2 git bundle\n
-<prerequisite hash>\n    (zero or more)
<hash> <refname>\n        (one or more)
\n
<pack data>               (standard pack file format)

Τα bundles είναι χρήσιμα για:

  • Μεταφορές μέσω φυσικών μέσων (μονάδες USB)
  • Σταδιακά αντίγραφα ασφαλείας
  • Προετοιμασία clone σε περιβάλλοντα χωρίς σύνδεση δικτύου

Ρηχοί κλώνοι

Το Pitmaster υποστηρίζει shallow clones, όπου ανακτάται μόνο περιορισμένο βάθος ιστορικού commit.

PHP
use Pitmaster\Protocol\ShallowClone;

Περάστε ένα βάθος στο Pitmaster::clone($url, $path, $depth) ή στο $repo->fetch($remote, $depth). Το αίτημα προσθέτει τη δυνατότητα shallow και μια γραμμή deepen:

Κώδικας
want <hash>
deepen <depth>

Ο διακομιστής αποκρίνεται με γραμμές shallow <hash> που υποδεικνύουν πού περικόπηκε το ιστορικό. Το Pitmaster υπολογίζει το ρηχό όριο από το ίδιο το βάθος και χρησιμοποιεί τις γραμμές shallow του διακομιστή όταν ο υπολογισμός δεν βρίσκει τίποτα· το αποτέλεσμα αποθηκεύεται στο .git/shallow. Τα ShallowClone::readShallow(), writeShallow() και isShallow() λειτουργούν απευθείας με αυτό το αρχείο.

Σύγκριση πρωτοκόλλων

Πρωτόκολλο Έλεγχος ταυτότητας Κρυπτογράφηση Αποστολή δεδομένων Συνήθης χρήση
Έξυπνο HTTP Διαπιστευτήρια στο URL HTTPS Ναι Κύριο μέσο μεταφοράς
Απλό HTTP Διαπιστευτήρια στο URL HTTPS Όχι Εναλλακτική για παλαιότερα συστήματα
SSH Κλειδιά SSH ή agent SSH Ναι Ιδιωτικά αποθετήρια, CI
Git (TCP) Κανένα Κανένα Όχι Αντίγραφα μόνο για ανάγνωση
Bundle Δεν εφαρμόζεται Δεν εφαρμόζεται Δεν εφαρμόζεται Μεταφορά εκτός σύνδεσης

Επιλογή μέσου μεταφοράς

Τα Pitmaster::clone(), $repo->fetch() και $repo->push() επιλέγουν το μέσο μεταφοράς από το URL:

Μοτίβο URL Μέσο μεταφοράς
ssh://... SSH
user@host:path SSH
Οτιδήποτε άλλο (https://..., http://...) Έξυπνο HTTP· τα clone και fetch επιστρέφουν στο απλό HTTP

Οι διευθύνσεις URL git:// και οι τοπικές διαδρομές δεν υποστηρίζονται από αυτές τις μεθόδους: αποστέλλονται στον πελάτη έξυπνου HTTP και αποτυγχάνουν. Χρησιμοποιήστε απευθείας το GitProtocolClient για git://. Ένα HTTPS URL που περιέχει και χρήστη και θύρα (https://user@host:8443/repo.git) εκλαμβάνεται προς το παρόν εσφαλμένα ως SSH URL (#17).