Liigu sisu juurde

Git LFS

Git Large File Storage (LFS) asendab hoidlas suured failid väikeste osutifailidega. Tegelikku failisisu hoitakse eraldi LFS-serveris. Pitmaster saab parsida ja luua LFS-osutiviiteid ning suhelda LFS-serveritega pakktöötluse API kaudu. See ei loe .gitattributes ega käivita LFS-i puhastus- ja taastefiltreid: add() salvestab failid muutmata kujul ja checkout() kirjutab osutifaile. Tegeliku sisu hankimise eest vastutab teie kood, nagu allpool näidatud.

LFS-i osutifailid

Kui fail on LFS-iga jälgitav, salvestab git tegeliku sisu asemel viitefaili:

Kood
version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 12345

Osuti sisaldab:

  • version: LFS-i spetsifikatsiooni versioon URL
  • oid: tegeliku faili sisu räsi SHA-256 (eesliitega sha256:)
  • size: tegeliku faili suurus baitides

Osutite parsimine

PHP
use Pitmaster\Lfs\LfsPointer;

$content = file_get_contents('.git-lfs-tracked-file');
$pointer = LfsPointer::parse($content);

if ($pointer !== null) {
    echo "OID: {$pointer->oid}\n";
    echo "Size: {$pointer->size}\n";
    echo "Version: {$pointer->version}\n";
}

parse() tagastab null, kui rida version, oid sha256: või size puudub. Väärtusi ei valideerita (mittekuueteistkümnendkoodiline OID või mittenumbriline suurus sobib).

Osutite tuvastamine

PHP
if (LfsPointer::isPointer($blobContent)) {
    // This blob is an LFS pointer, not actual file content
    $pointer = LfsPointer::parse($blobContent);
}

isPointer() kontrollib väljade version URL, oid sha256: ja size olemasolu, ilma kogu sisu parsimata.

Osutite loomine

PHP
// From known OID and size
$pointer = new LfsPointer(
    oid: '4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393',
    size: 12345,
);

// From file content (computes SHA-256 hash)
$pointer = LfsPointer::forContent($actualFileContent);

echo $pointer->oid;   // SHA-256 hash
echo $pointer->size;  // Content length

Osutite serialiseerimine

PHP
$content = $pointer->serialize();
// "version https://git-lfs.github.com/spec/v1\noid sha256:4d7a21...\nsize 12345\n"

LFS-klient

LfsClient suhtleb LFS-serveritega pakktöötluse API kaudu (POST aadressile <url>/objects/batch).

Kliendi loomine

PHP
use Pitmaster\Lfs\LfsClient;

// From a git remote URL (appends /info/lfs)
$client = LfsClient::fromRemoteUrl('https://github.com/user/repo.git');
// LFS URL: https://github.com/user/repo.git/info/lfs

// Direct URL
$client = new LfsClient('https://lfs.example.com/repo', timeout: 60);

Meetod fromRemoteUrl() järgib standardset tava: lisab /info/lfs git URL-ile (lisades .git, kui see puudub). Kasutatava LFS URL annavad ainult HTTP(S) kaug-URL-id; SCP-stiilis SSH kaugallikad (git@host:repo.git) seda ei võimalda.

LfsClient kasutab PHP voopuhvrit HTTP (allow_url_fopen peab olema lubatud). See ei saada autentimisandmeid ja eirab iga toiminguga tagastatud kaarti header, mistõttu töötab ainult autentimist mittevajavate LFS-serverite ja salvestus-URL-idega. See ei ole seotud hoidla käepidemega, seega teeb võrgupäringuid ka siis, kui töötate suvandiga Pitmaster::processFreeOptions() avatud hoidlas.

Failide allalaadimine

PHP
// Single file download
$content = $client->download($pointer->oid, $pointer->size);
file_put_contents('large-file.bin', $content);

Taustal toimib download() järgmiselt:

  1. Saadab toimingu download jaoks pakipäringu
  2. Saab serverilt allalaadimise URL
  3. Hangib failisisu sellest URL-st

Allalaaditud baite ei kontrollita OID ega suuruse suhtes.

Pakiga allalaadimine

PHP
$results = $client->batchDownload([
    ['oid' => 'abc123...', 'size' => 12345],
    ['oid' => 'def456...', 'size' => 67890],
]);

foreach ($results as $result) {
    if ($result['error'] !== null) {
        echo "Error: {$result['error']}\n";
        continue;
    }

    if ($result['href'] !== null) {
        // Download from $result['href']
    }
}

Failide üleslaadimine

PHP
$client->upload($pointer->oid, $pointer->size, $fileContent);

Üleslaadimisel saadetakse toimingu upload jaoks pakipäring. Kui objekt on serveris juba olemas, ei tagasta see üleslaadimise URL ja toimingut ei tehta. Üleslaadimispäringu tulemust ennast ei kontrollita, seega ebaõnnestunud üleslaadimisest ei teatata ning toimingut verify ei kutsuta välja.

Pakiga üleslaadimine

PHP
$results = $client->batchUpload([
    ['oid' => 'abc123...', 'size' => 12345],
]);

foreach ($results as $result) {
    if ($result['href'] !== null) {
        // Server needs this object, upload to $result['href']
    }
    // No href means server already has it
}

Pakktöötluse API protokoll

LFS-i pakktöötluse API kasutab protokolli JSON üle HTTP:

Päring

Kood
POST <lfs-url>/objects/batch
Content-Type: application/vnd.git-lfs+json
Accept: application/vnd.git-lfs+json

{
    "operation": "download",
    "transfers": ["basic"],
    "objects": [
        {"oid": "abc123...", "size": 12345}
    ]
}

Vastus

JSON
{
    "objects": [
        {
            "oid": "abc123...",
            "size": 12345,
            "actions": {
                "download": {
                    "href": "https://storage.example.com/abc123...",
                    "header": {
                        "Authorization": "Bearer token"
                    }
                }
            }
        }
    ]
}

LFS-i sidumine hoidla toimingutega

LFS-i kasutavas hoidlas võib ploki sisu olla tegelike failiandmete asemel LFS-osutiviide. Tegeliku sisu saamiseks:

PHP
$blob = $repo->readObject($hash);

if (LfsPointer::isPointer($blob->content)) {
    $pointer = LfsPointer::parse($blob->content);
    $remoteUrl = $repo->config()->get('remote.origin.url');
    $client = LfsClient::fromRemoteUrl($remoteUrl);
    $realContent = $client->download($pointer->oid, $pointer->size);
} else {
    $realContent = $blob->content;
}

Vigade käsitlemine

Ebaõnnestunud või vigane pakipäring ja ebaõnnestunud allalaadimispäring põhjustavad vea ProtocolException. download() põhjustab samuti vea, kui server ei tagasta objekti jaoks allalaadimise URL-t, kuid serveri veateadet ei lisata. batchDownload() ja batchUpload() ei põhjusta objekti kaupa vigade korral tõrget, vaid tagastavad need väljal error.

PHP
use Pitmaster\Exceptions\ProtocolException;

try {
    $content = $client->download($oid, $size);
} catch (ProtocolException $e) {
    // Server unreachable, invalid response, no download URL
    echo "LFS error: {$e->getMessage()}\n";
}

LFS-osutiviite atribuudid

Klass LfsPointer on kirjutuskaitstud:

PHP
$pointer->oid;      // string: SHA-256 hash (hex)
$pointer->size;     // int: file size in bytes
$pointer->version;  // string: spec version URL