Git LFS
Git Large File Storage (LFS) velike datoteke v repozitoriju nadomesti z majhnimi datotekami kazalcev. Dejanska vsebina datotek je shranjena na ločenem strežniku LFS. Pitmaster lahko razčleni in ustvari kazalce LFS ter komunicira s strežniki LFS prek paketnega API. Ne bere .gitattributes in ne izvaja filtrov LFS clean in smudge: add() datoteke shrani nespremenjene, checkout() pa zapiše datoteke kazalcev. Pridobivanje dejanske vsebine prepusti vaši kodi, kot je prikazano spodaj.
Datoteke kazalcev LFS
Ko datoteko sledi LFS, git namesto dejanske vsebine shrani datoteko kazalca:
version https://git-lfs.github.com/spec/v1
oid sha256:4d7a214614ab2935c943f9e0ff69d22eadbb8f32b1258daaa5e2ca24d17e2393
size 12345
Kazalec vsebuje:
version: različico specifikacije LFS URLoid: zgoščeno vrednost SHA-256 dejanske vsebine datoteke (s predponosha256:)size: dejansko velikost datoteke v bajtih
Razčlenjevanje kazalcev
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() vrne null, če manjka vrstica version, oid sha256: ali size. Vrednosti ne preverja (sprejme nešestnajstiški OID ali nenumerično velikost).
Zaznavanje kazalcev
if (LfsPointer::isPointer($blobContent)) {
// This blob is an LFS pointer, not actual file content
$pointer = LfsPointer::parse($blobContent);
}
isPointer() brez popolnega razčlenjevanja preveri prisotnost polj različice URL, oid sha256: in size.
Ustvarjanje kazalcev
// 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
Serializacija kazalcev
$content = $pointer->serialize();
// "version https://git-lfs.github.com/spec/v1\noid sha256:4d7a21...\nsize 12345\n"
Odjemalec LFS
LfsClient komunicira s strežniki LFS prek paketnega API (POST na <url>/objects/batch).
Ustvarjanje odjemalca
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);
Metoda fromRemoteUrl() sledi običajni konvenciji: doda /info/lfs k git URL (in po potrebi doda .git). Uporaben LFS URL je mogoče pridobiti samo iz oddaljenih URL-jev HTTP(S); oddaljeni repozitoriji v slogu SCP SSH (git@host:repo.git) ne delujejo.
LfsClient uporablja ovoj toka HTTP iz PHP (mora biti omogočen allow_url_fopen). Ne pošilja poverilnic in prezre preslikavo header, vrnjeno z vsakim dejanjem, zato deluje samo s strežniki LFS in URL-ji za shranjevanje, ki ne zahtevajo preverjanja pristnosti. Ni vezan na ročico repozitorija, zato izvaja omrežne zahteve tudi pri delu z repozitorijem, odprtim z Pitmaster::processFreeOptions().
Prenos datotek
// Single file download
$content = $client->download($pointer->oid, $pointer->size);
file_put_contents('large-file.bin', $content);
V ozadju download():
- Pošlje paketno zahtevo za operacijo
download - Od strežnika prejme URL za prenos
- Iz tega URL pridobi vsebino datoteke
Preneseni bajti se ne preverijo glede na OID ali velikost.
Paketni prenos
$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']
}
}
Nalaganje datotek
$client->upload($pointer->oid, $pointer->size, $fileContent);
Nalaganje pošlje paketno zahtevo za operacijo upload. Če strežnik objekt že ima, ne vrne URL za nalaganje in operacija ne naredi ničesar. Rezultat same zahteve za nalaganje se ne preveri, zato neuspešno nalaganje ni sporočeno, dejanje verify pa ni poklicano.
Paketno nalaganje
$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
}
Protokol paketnega API
Paketni LFS API uporablja JSON prek HTTP:
Zahteva
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}
]
}
Odgovor
{
"objects": [
{
"oid": "abc123...",
"size": 12345,
"actions": {
"download": {
"href": "https://storage.example.com/abc123...",
"header": {
"Authorization": "Bearer token"
}
}
}
}
]
}
Povezovanje LFS z operacijami repozitorija
Pri branju repozitorija, ki uporablja LFS, je lahko vsebina bloba kazalec LFS namesto dejanskih podatkov datoteke. Za pridobitev dejanske vsebine:
$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;
}
Obravnava napak
Neuspešna ali neveljavna paketna zahteva in neuspešna zahteva za prenos sprožijo ProtocolException. Tudi download() sproži napako, če strežnik za objekt ne vrne URL za prenos, pri čemer ne poda sporočila o napaki strežnika. batchDownload() in batchUpload() ne sprožita napake za napake posameznih objektov, temveč jih vrneta v polju 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";
}
Lastnosti kazalca LFS
Razred LfsPointer je samo za branje:
$pointer->oid; // string: SHA-256 hash (hex)
$pointer->size; // int: file size in bytes
$pointer->version; // string: spec version URL