Liigu sisu juurde

Klooni, too, saada

Pitmaster toetab kolme põhilist giti võrgutoimingut: kloonimist (esialgne allalaadimine), toomist (täiendav allalaadimine) ja saatmist (üleslaadimine). URL-id SSH (ssh://..., user@host:path) kasutavad transporti SSH; muud URL-id kasutavad nutikat HTTP-i ning kloonimine ja toomine lähevad nutika andmevahetuse nurjumisel üle lihtsustatud HTTP-ile (vt Protokollid).

Kõik kolm käivitavad võrgutranspordid ja seetõttu tekitavad erindi RuntimeException, kui käepide avati valikuga ['processes' => false] või Pitmaster::processFreeOptions().

Kloonimine

PHP
use Pitmaster\Pitmaster;

// public static function clone(string $url, string $path, ?int $depth = null, array $options = []): Repository
$repo = Pitmaster::clone('https://github.com/user/repo.git', '/path/to/destination');
$repo = Pitmaster::clone('https://github.com/user/repo.git', '/path/to/shallow', 1);

Uus hoidla kasutab alati SHA-1-i. Kui kloonimine nurjub ja sihtkohta polnud varem olemas, eemaldatakse osaliselt loodud kataloog.

Kloonimise käik

  1. Initsialiseeri: loo sihtkoha teele uus tühi hoidla
  2. Seadista kaughoidla: salvesta URL väärtusena remote.origin.url ja seadista toomise viitespetsifikatsioon
  3. Tuvasta viited: uuri käsuga GET /info/refs?service=git-upload-pack, mida serveris leidub
  4. Lepi kokku: saada kõigi kaugviidete kohta want read (räsi alusel duplikaadid eemaldatud)
  5. Võta pakifail vastu: laadi alla pakifail, mis sisaldab kõiki taotletud objekte
  6. Kirjuta pakifail: salvesta pakifail asukohta .git/objects/pack/
  7. Indekseeri pakifail: loo kiirete otsingute jaoks fail .idx
  8. Seadista viited: loo kaugjälgitavad harud (refs/remotes/origin/*) ja sildid
  9. Seadista HEAD: suuna HEAD vaikimisi harule (serveri võimaluse symref=HEAD:... alusel või väärtusele refs/heads/main, kui server ei saada võimalusi) ning määra branch.<name>.remote ja branch.<name>.merge
  10. Võta välja: võta see haru välja, kirjutades tööpuu ja registri

Vigu viimase väljavõtmise ajal püütakse kinni ja eiratakse, seega võib kloonimisel tagastuda tühi või osaline tööpuu (#19).

PHP
$repo = Pitmaster::clone($url, $path);
$head = $repo->head();
echo $head->message;

$branches = $repo->branches();
$files = $repo->status();

Tööpuu loomine

Pärast pakifaili vastuvõtmist kutsub Pitmaster vaikimisi haru jaoks välja $repo->checkout(). See kirjutab HEAD-sissekande puust kõik failid töökataloogi ja koostab registri puukirjete põhjal, nii et status() teatab puhtast tööpuust.

Toomine

PHP
// public function fetch(string $remote = 'origin', ?int $depth = null): void
$repo->fetch();              // Fetch from 'origin'
$repo->fetch('upstream');    // Fetch from a named remote
$repo->fetch('origin', 1);   // Shallow fetch

Toomise käik

  1. Loe kaughoidla URL: failist .git/config (remote.<name>.url)
  2. Tuvasta viited: hangi kõigi kaugviidete hetkeseis
  3. Lepi kokku taotletavate ja olemasolevate objektide üle:
    • Taotletavad: kaugviited, mis vastavad viitespetsifikatsioonidele remote.<name>.fetch (vaikimisi +refs/heads/*:refs/remotes/<name>/*) ja mille objekte pole kohalikus hoidlas (määratud sügavuse korral kõik vastavad viited)
    • Olemasolevad: iga kohaliku viite tipp
  4. Võta pakifail vastu: laadi alla ainult uued objektid
  5. Kirjuta pakifail: salvesta asukohta .git/objects/pack/ ja loo selle indeks
  6. Uuenda jälgimisviiteid: uuenda iga sobiva kaug-haru jaoks refs/remotes/<remote>/<branch> ning kirjuta kõik teatatud sildiviited. Sildiobjekte eraldi ei taotleta, seega võib uus märkustega silt viidata objektile, mida alla ei laaditud (#24)
PHP
// Fetch is incremental: only downloads what's new
$repo->fetch();

// After fetching, merge or rebase to incorporate changes (use the full ref name)
$result = $repo->merge('refs/remotes/origin/main');

resolve() otsib nimesid kujul refs/heads/<name>, refs/tags/<name> ja nime enda kujul, seega lühivormi origin/main ei leita.

Pitmaster taotleb õhukesi pakifaile, mida see veel indekseerida ei oska (#16). Kui server vastab täiendavale toomisele õhukese pakifailiga, tekitab fetch() erindi PackParseException.

Kõik on ajakohane

Kui kõik objektid, millele kaugviited osutavad, on juba kohalikus hoidlas olemas, pakifaili ei taotleta ja fetch() naaseb pärast viidete tuvastamist. Sel juhul ei uuendata ka jälgimisviiteid, isegi kui kaug-harud liikusid sissekannetele, mis teil juba olemas on (#23).

Saatmine

PHP
$repo->push();                        // Push current branch to 'origin'
$repo->push('origin', 'main');        // Push a specific branch
$repo->push('upstream', 'feature');   // Push to a named remote

Saatmise käik

  1. Loe kaughoidla URL: failist .git/config
  2. Määra saadetav sisu: lahenda kohalik haru sissekande räsiks
  3. Tuvasta kaugviited: hangi kaug-haru hetkeseis (vana räsi arvutamiseks)
  4. Kontrolli edasiliikumist: kui kaug-haru pole kohaliku haru eellane, tekita enne millegi saatmist erind RuntimeException("Push rejected: non-fast-forward update to <branch>")
  5. Saada viite uuendus: <old-hash> <new-hash> refs/heads/<branch>
  6. Saada pakifaili andmed: pakifail objektidega, mida kaughoidla vajab
  7. Kontrolli tulemust: server vastab iga viite kohta õnnestumise või nurjumisega

Enne uuenduse saatmist käivitub hook pre-push, kui hookid pole keelatud.

PHP
// Push the current branch
$repo->push();

// Push a specific branch to a specific remote
$repo->push('origin', 'feature/login');

Saatmise nõuded

  • Praegune haru peab kohalikus hoidlas olemas olema
  • Kaughoidlal peab olema seadistatud URL
  • Kaughoidla peab saatmise vastu võtma (autentimine, õigused, kiire edasiliikumise poliitikad)

Sundsaatmine

Pitmaster saadab kaugviite reklaamitud hetkeseisu vana räsi ja push() keeldub kohalikult uuendustest, mis pole kiired edasiliikumised. Kaug-haru ülekirjutamiseks kasutage sundimist koos kontrolliga:

PHP
// Lease defaults to refs/remotes/<remote>/<branch>; pass an ObjectId to set it explicitly
$repo->pushForceWithLease('origin', 'main');
$repo->pushForceWithLease('origin', 'main', $repo->resolve('refs/remotes/origin/main'));

// Update several branches in one atomic request
$repo->pushAtomic('origin', ['main', 'release']);

// Make the remote mirror local refs (also deletes remote refs that no longer exist locally)
$repo->pushMirror('origin');

UploadPackClient (toomise siseosad)

PHP
use Pitmaster\Protocol\UploadPackClient;
use Pitmaster\Protocol\SmartHttpClient;

$http = new SmartHttpClient();
$uploadPack = new UploadPackClient($http);

// Fetch with explicit wants and haves
$packData = $uploadPack->fetch($url, $wants, $haves);

Taotletavate ja olemasolevate objektide läbirääkimisel koostatakse pkt-line-päring:

Kood
want <hash1> <capabilities>\n
want <hash2>\n
deepen <depth>\n        (only when a depth is given)
0000
have <hash3>\n
have <hash4>\n
done\n

Server vastab kinnitustega ja seejärel pakifaili andmetega (võimalik, et side-band-vormingus).

ReceivePackClient (saatmise siseosad)

PHP
use Pitmaster\Protocol\ReceivePackClient;
use Pitmaster\Protocol\SmartHttpClient;

$http = new SmartHttpClient();
$receivePack = new ReceivePackClient($http);

$receivePack->push($url, [
    [
        'old' => $oldId,      // Current remote hash (or zero hash for new branch)
        'new' => $localId,    // Local commit hash to push
        'ref' => 'refs/heads/main',
    ],
], $packData);

Saatmispäringu vorming:

Kood
<old-hash> <new-hash> refs/heads/main\0<capabilities>\n
0000
PACK<pack data>

Vigade käsitlemine

PHP
use Pitmaster\Exceptions\ProtocolException;

try {
    $repo->fetch();
} catch (ProtocolException $e) {
    // Network unreachable, auth failed, server error, etc.
    echo $e->getMessage();
}

try {
    $repo->push();
} catch (\RuntimeException $e) {
    // Remote not configured, not on a branch, branch not found, non-fast-forward
    echo $e->getMessage();
}

fetch() võib tekitada ka tavalise RuntimeException (tundmatu kaughoidla, protsessivaba käepide) või PackParseException (pakifaili ei saa indekseerida). Nii ProtocolException kui ka PackParseException laiendavad klassi \RuntimeException, seega hõlmab nende püüdmist \RuntimeException.

Kaughoidla seadistus

Kaughoidlad salvestatakse asukohta .git/config:

Ini
[remote "origin"]
    url = https://github.com/user/repo.git
    fetch = +refs/heads/*:refs/remotes/origin/*

Juurdepääs konfiguratsiooni API kaudu:

PHP
$config = $repo->config();
$url = $config->get('remote.origin.url');
$config->set('remote.upstream.url', 'https://github.com/other/repo.git');
$config->set('remote.upstream.fetch', '+refs/heads/*:refs/remotes/upstream/*');

// set() changes the in-memory config only; write it to persist the change
$config->writeToFile($repo->commonGitDir() . '/config');

Saatmise pakifaili andmed

Praegu kogub Pitmaster saatmiseks valitud sissekannetest lähtuvad objektid, mida kaughoidla praegused viited ei hõlma, ning kirjutab need algobjektidena (ilma delta-tihenduseta) pakifaili. See on funktsionaalselt korrektne, kuid loob suuremad pakifailid kui git push. Delta-tihenduse lisamine pakifailide kirjutamisel on kavandatud optimeerimine.