Git LFS
Git Lielo failu krātuve (LFS) aizstāj lielus failus repozitorijā ar maziem rādītāja failiem. Faktiskais failu saturs tiek glabāts atsevišķā LFS serverī. Pitmaster var parsēt un izveidot LFS rādītājus, kā arī sazināties ar LFS serveriem, izmantojot pakešu API. Tas nelasa .gitattributes un nedarbina LFS clean un smudge filtrus: add() glabā failus nemainītus, bet checkout() raksta rādītāja failus. Faktiskā satura iegūšana ir jūsu koda ziņā, kā parādīts tālāk.
LFS rādītāja faili
Ja fails tiek pārvaldīts ar LFS, git saglabā rādītāja failu faktiskā satura vietā:
version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 12345
Rādītājā ir:
version: LFS specifikācijas versija URLoid: faktiskā faila satura SHA-256 jaucējvērtība (ar prefiksusha256:)size: faktiskā faila lielums baitos
Rādītāju parsēšana
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() atgriež null, ja trūkst version, oid sha256: vai size rindas. Tas nepārbauda vērtību derīgumu (tiek pieņemts arī neheksadecimāls OID vai nen skaitlisks lielums).
Rādītāju noteikšana
if (LfsPointer::isPointer($blobContent)) {
// This blob is an LFS pointer, not actual file content
$pointer = LfsPointer::parse($blobContent);
}
isPointer() pārbauda, vai ir versijas URL, oid sha256: un size lauki, neveicot pilnu parsēšanu.
Rādītāju izveide
// 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
Rādītāju serializēšana
$content = $pointer->serialize();
// "version https://git-lfs.github.com/spec/v1\noid sha256:4d7a21...\nsize 12345\n"
LFS klients
LfsClient sazinās ar LFS serveriem, izmantojot pakešu API (POST uz <url>/objects/batch).
Klienta izveide
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);
Metode fromRemoteUrl() darbojas atbilstoši standarta konvencijai: pievieno /info/lfs git URL (ja tā nav, pievienojot .git). Izmantojamas LFS URL nodrošina tikai attālo repozitoriju URL ar HTTP(S); SCP stila attālie repozitoriji SSH (git@host:repo.git) neder.
LfsClient izmanto PHP HTTP straumes apvalku (jābūt iespējotam allow_url_fopen). Tas nesūta akreditācijas datus un ignorē header karti, kas tiek atgriezta kopā ar katru darbību, tāpēc tas darbojas tikai ar LFS serveriem un krātuves URL, kuriem nav vajadzīga autentifikācija. Tas nav piesaistīts repozitorija objektam, tāpēc veic tīkla pieprasījumus arī tad, ja strādājat ar repozitoriju, kas atvērts ar Pitmaster::processFreeOptions().
Failu lejupielāde
// Single file download
$content = $client->download($pointer->oid, $pointer->size);
file_put_contents('large-file.bin', $content);
Aizkulisēs download():
- Nosūta pakešu pieprasījumu
downloaddarbībai - Saņem no servera lejupielādes URL
- Iegūst faila saturu no šī URL
Lejupielādētie baiti netiek pārbaudīti pret OID vai lielumu.
Pakešu lejupielāde
$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']
}
}
Failu augšupielāde
$client->upload($pointer->oid, $pointer->size, $fileContent);
Augšupielāde nosūta pakešu pieprasījumu upload darbībai. Ja serverim objekts jau ir, tas neatgriež augšupielādes URL, un darbība neko nedara. Pats augšupielādes pieprasījuma rezultāts netiek pārbaudīts, tāpēc par neveiksmīgu augšupielādi netiek ziņots un verify darbība netiek izsaukta.
Pakešu augšupielāde
$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
}
Pakešu API protokols
LFS pakešu API izmanto JSON, izmantojot HTTP:
Pieprasījums
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}
]
}
Atbilde
{
"objects": [
{
"oid": "abc123...",
"size": 12345,
"actions": {
"download": {
"href": "https://storage.example.com/abc123...",
"header": {
"Authorization": "Bearer token"
}
}
}
}
]
}
LFS integrēšana repozitorija darbībās
Lasot repozitoriju, kas izmanto LFS, blob saturs var būt LFS rādītāji, nevis faktiskie faila dati. Lai iegūtu īsto saturu:
$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;
}
Kļūdu apstrāde
Neveiksmīgs vai nederīgs pakešu pieprasījums un neveiksmīgs lejupielādes pieprasījums izraisa ProtocolException. download() arī izraisa kļūdu, ja serveris objektam neatgriež lejupielādes URL, neiekļaujot servera kļūdas ziņojumu. batchDownload() un batchUpload() neizraisa kļūdu atsevišķu objektu kļūdu gadījumā; tās atgriež kļūdas laukā 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 rādītāju īpašības
Klase LfsPointer ir tikai lasāma:
$pointer->oid; // string: SHA-256 hash (hex)
$pointer->size; // int: file size in bytes
$pointer->version; // string: spec version URL