Pereiti prie turinio

Indekso formatas

Indekso failas (.git/index) yra paruošimo sritis. Jame įrašomi failai, kurie bus įtraukti į kitą commit, ir metaduomenys, padedantys efektyviai apskaičiuoti būseną. Pitmaster skaito 2, 3 ir 4 versijų indeksus, o rašo 2 ir 3 versijų indeksus. Įrašius indeksą, kuris buvo nuskaitytas kaip 4 versija, sukuriamas Git neskaitomas failas (#15), todėl prieš rašydami per Pitmaster tokias saugyklas konvertuokite naudodami git update-index --index-version 2.

Indekso skaitymas

PHP
use Pitmaster\Index\Index;

$index = Index::open('/path/to/.git/index');   // pass 32 as the second argument for SHA-256

// Or through the repository
$index = $repo->index();

// Entry count (all stages)
echo $index->count();

// Iterate stage 0 entries, keyed by path
foreach ($index->entries() as $path => $entry) {
    echo "{$entry->path} {$entry->hash->hex}\n";
}

// Look up a specific entry
$entry = $index->entry('src/File.php');

Jei failo nėra, Index::open() grąžina tuščią indeksą. entries() grąžina tik 0 etapo įrašus; allEntries() įtraukia konfliktų etapus, o paths() pateikia sekamus kelius.

IndexEntry

Kiekvienas indekso įrašas yra tik skaitymui skirtas reikšmės objektas:

PHP
use Pitmaster\Index\IndexEntry;

$entry->path;          // File path relative to repo root
$entry->hash;          // ObjectId of the blob
$entry->mode;          // File mode as an int (0100644, 0100755, 0120000, 0160000)
$entry->fileSize;      // File size in bytes
$entry->ctimeSec;      // Metadata change time (seconds)
$entry->ctimeNsec;     // Metadata change time nanoseconds
$entry->mtimeSec;      // Modification time (seconds)
$entry->mtimeNsec;     // Modification time nanoseconds
$entry->dev;           // Device number
$entry->ino;           // Inode number
$entry->uid;           // User ID
$entry->gid;           // Group ID
$entry->flags;         // Raw flags field
$entry->extendedFlags; // v3 extended flags (skip-worktree, intent-to-add)
$entry->stage();       // Conflict stage (0 = normal, 1 = base, 2 = ours, 3 = theirs)
$entry->assumeValid(); // Assume-valid bit
$entry->skipWorktree(); // Skip-worktree bit

Įrašų kūrimas

PHP
// From file stat
$entry = IndexEntry::fromStat('src/File.php', $blobId, '/full/path/to/src/File.php');

// Minimal (no stat info)
$entry = IndexEntry::create('src/File.php', $blobId);

// With explicit mode
$entry = IndexEntry::create('deploy.sh', $blobId, 0100755);

Indekso keitimas

PHP
// Add or replace an entry
$index->addEntry($entry);

// Remove an entry
$index->removeEntry('src/OldFile.php');

// Replace all stages of a conflicted path with one resolved entry
$index->resolveConflict('src/File.php', $entry);

addEntries() ir removeEntries() vienu veiksmu apdoroja kelis įrašus ar kelius. Pakeitus įrašus, išsaugoti plėtiniai pašalinami (žr. toliau).

Indekso įrašymas

PHP
use Pitmaster\Index\IndexWriter;

IndexWriter::write($index, '/path/to/.git/index');

Arba per saugyklą (kuri tai atlieka automatiškai):

PHP
$repo->add('src/File.php');    // Reads file, creates blob, updates index, writes
$repo->remove('--cached', 'old-file.txt'); // Removes from index only, writes

Dvejetainis formatas

Kodas
Signature:   DIRC (4 bytes, ASCII)
Version:     4 bytes, big-endian (2, 3, or 4)
Entry count: 4 bytes, big-endian

Įrašo formatas (v2)

Kiekvieną įrašą sudaro:

Kodas
ctime seconds:     4 bytes, big-endian
ctime nanoseconds: 4 bytes, big-endian
mtime seconds:     4 bytes, big-endian
mtime nanoseconds: 4 bytes, big-endian
dev:               4 bytes, big-endian
ino:               4 bytes, big-endian
mode:              4 bytes, big-endian
uid:               4 bytes, big-endian
gid:               4 bytes, big-endian
file size:         4 bytes, big-endian
object hash:       20 bytes SHA-1 or 32 bytes SHA-256 (raw binary)
flags:             2 bytes, big-endian
path:              variable length, NUL-terminated
padding:           1-8 NUL bytes to align to 8-byte boundary

Vėliavų laukas:

  • Bitas 15: galiojimo laikoma vėliava
  • Bitai 13-12: suliejimo etapas (0-3)
  • Bitai 11-0: kelio pavadinimo ilgis arba 0xFFF, jei kelias yra 4095 baitų ar ilgesnis (tuomet skaitytuvas ieško NUL)

Versijų skirtumai

2 versija: aukščiau aprašytas bazinis formatas. Dažniausiai naudojama.

3 versija: pridedamos išplėstinės vėliavos (2 papildomi baitai po įprastų vėliavų). Palaikomi bitai skip-worktree ir intent-to-add. Naudojama, kai kuriam nors įrašui reikia išplėstinių vėliavų.

4 versija: pridedamas kelių prefiksų glaudinimas. Užuot saugojus visus kelius, kiekviename įraše saugoma, kiek baitų pašalinti iš ankstesnio įrašo kelio, o tada – nauja priesaga. Gerokai sumažina indekso dydį, kai medžiai giliai įdėti.

Konfliktų etapai

Kilęs suliejimo konfliktas gali sukurti vienam keliui kelis skirtingų etapų indekso įrašus:

Etapas Reikšmė
0 Įprastas (konflikto nėra)
1 Bazinė versija (bendras protėvis)
2 Mūsų (dabartinė šaka)
3 Jų (suliejama šaka)
PHP
// During a conflict, entries have non-zero stages
foreach ($index->allEntries() as $entry) {
    if ($entry->stage() > 0) {
        echo "Conflict: {$entry->path} (stage {$entry->stage()})\n";
    }
}

$index->hasUnmerged();            // true while conflicts remain
$index->unmergedPaths();          // conflicted paths
$index->stageEntries('a.txt');    // [1 => base, 2 => ours, 3 => theirs]

Indekso plėtiniai

Plėtiniai pridedami po įrašų, prieš kontrolinę sumą. Kiekvieną plėtinį sudaro 4 baitų parašas, 4 baitų dydis ir kintamo ilgio duomenys.

Pitmaster plėtinių blokus saugo kaip neapdorotus baitus ($index->extensions() grąžina signature ir data poras) ir, jei įrašai nepakeisti, juos įrašo atgal nepakeistus. Jis neinterpretuoja ir negeneruoja jokių plėtinių, o pakeitus įrašus visi jie pašalinami; git tai priima ir prireikus atkuria. Toliau pateikiamas naudojamų plėtinių git aprašas.

TREE plėtinys

Katalogams talpykloje saugomi iš anksto apskaičiuoti medžių objektai. Paspartina git status ir git commit, nes išvengiama pakartotinio medžio skaičiavimo, kai pasikeitė tik indeksas.

Parašas: TREE (0x54524545)

REUC plėtinys

Įrašo atšaukimo informaciją. Išsprendus konfliktą, pradiniai 1/2/3 etapo įrašai perkeliami čia, kad juos būtų galima atkurti naudojant git checkout -m.

Parašas: REUC (0x52455543)

Kiti plėtiniai

git taip pat įrašo:

  • EOIE (indekso įrašo pabaiga): nurodo, kur baigiasi įrašai ir prasideda plėtiniai
  • IEOT (indekso įrašų poslinkių lentelė): leidžia lygiagrečiai įkelti indeksą
  • link (padalytas indeksas): labai didelėms saugykloms, naudojančioms padalytą indeksą

git formate plėtiniai, kurių parašas prasideda didžiąja raide, yra pasirenkami, o prasidedantys mažąja – privalomi. Pitmaster priima abiejų rūšių plėtinius jų netikrindama. Padalytas indeksas (link) neįkeliamas, todėl saugyklos, kuriose jis naudojamas, nepalaikomos.

Kontrolinė suma

Indekso failo pabaigoje įrašoma visų ankstesnių baitų kontrolinė suma, apskaičiuota pagal saugyklos maišos algoritmą (20 baitų SHA-1, 32 baitai SHA-256). Pitmaster ją įrašo išsaugant, bet skaitydama netikrina.

Index::open() ir Index::parse() iškelia IndexParseException, jei trūksta DIRC parašo arba nurodyta nepalaikoma versija.

Indeksas ir būsena

Indeksas yra pagrindinis būsenos apskaičiavimo elementas. WorkingTreeStatus lygina:

  1. HEAD medį su indeksu: aptinka paruoštus pakeitimus
  2. Indeksą su darbiniu medžiu: aptinka neparuoštus pakeitimus

Statistikos laukai (ctime, mtime, dev, ino, size, mode, uid, gid) leidžia greitai patikrinti, ar failas pasikeitė, neskaitant jo turinio. Jei statistikos laukai sutampa, o failas buvo paskutinį kartą pakeistas prieš pradedant būsenos tikrinimą, laikoma, kad jis nepasikeitė. Jei dydis skiriasi, failas iškart pažymimas kaip pakeistas. Kitu atveju Pitmaster perskaito failą ir apskaičiuoja jo maišą, kad patikrintų, ar turinys iš tikrųjų pasikeitė.

Galiojančio failo žyma

PHP
if ($entry->assumeValid()) {
    // Entry has assume-valid set (flags & 0x8000)
}

Ši žyma nurodo git netikrinti failo būsenos tikrinimo metu, net jei statistikos laukai pasikeitė (git update-index --assume-unchanged). Pitmaster išsaugo šį bitą perrašydama įrašus, bet būsenos tikrinimo metu į jį neatsižvelgia ir vis tiek palygina failą.