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:
version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 12345
Osuti sisaldab:
version: LFS-i spetsifikatsiooni versioon URLoid: tegeliku faili sisu räsi SHA-256 (eesliitegasha256:)size: tegeliku faili suurus baitides
Osutite parsimine
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
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
// 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
$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
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
// Single file download
$content = $client->download($pointer->oid, $pointer->size);
file_put_contents('large-file.bin', $content);
Taustal toimib download() järgmiselt:
- Saadab toimingu
downloadjaoks pakipäringu - Saab serverilt allalaadimise URL
- Hangib failisisu sellest URL-st
Allalaaditud baite ei kontrollita OID ega suuruse suhtes.
Pakiga allalaadimine
$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
$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
$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
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
{
"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:
$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.
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:
$pointer->oid; // string: SHA-256 hash (hex)
$pointer->size; // int: file size in bytes
$pointer->version; // string: spec version URL