Pāriet uz saturu

Indeksa formāts

Indeksa fails (.git/index) ir sagatavošanas apgabals. Tajā tiek reģistrēti faili, kas tiks iekļauti nākamajā komitā, kā arī metadati efektīvai statusa aprēķināšanai. Pitmaster nolasa indeksa 2., 3. un 4. versiju un raksta 2. un 3. versiju. Ierakstot indeksu, kas nolasīts kā 4. versija, tiek izveidots git nelasāms fails (#15), tāpēc pirms rakstīšanas ar Pitmaster pārveidojiet šādus repozitorijus, izmantojot git update-index --index-version 2.

Indeksa nolasīšana

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');

Index::open() atgriež tukšu indeksu, ja fails neeksistē. entries() atgriež tikai 0. posma ierakstus; allEntries() iekļauj konfliktu posmus, bet paths() uzskaita izsekotos ceļus.

IndexEntry

Katrs indeksa ieraksts ir tikai lasāms vērtības objekts:

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

Ierakstu izveide

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);

Indeksa modificēšana

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() un removeEntries() vienā reizē apstrādā vairākus ierakstus vai ceļus. Jebkuras izmaiņas ierakstos dzēš saglabātos paplašinājumus (sk. tālāk).

Indeksa ierakstīšana

PHP
use Pitmaster\Index\IndexWriter;

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

Vai arī ar repozitorija starpniecību (tas to apstrādā automātiski):

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

Binārais formāts

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

Ieraksta formāts (v2)

Katrs ieraksts ir šāds:

Kods
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

Karodziņu lauks:

    1. bits: pieņemt kā derīgu karodziņu
  • 13.–12. biti: sapludināšanas posms (0–3)
  • 11.–0. biti: ceļa nosaukuma garums vai 0xFFF, ja ceļš ir vismaz 4095 baitu garš (tad lasītājs meklē NUL)

Versiju atšķirības

2. versija: iepriekš aprakstītais pamatformāts. Visizplatītākā.

3. versija: pievieno paplašinātos karodziņus (2 papildu baiti pēc parastajiem karodziņiem). Atbalsta bitus skip-worktree un intent-to-add. Tiek izmantota, ja kādam ierakstam nepieciešami paplašinātie karodziņi.

4. versija: pievieno ceļu prefiksu saspiešanu. Pilnu ceļu vietā katrā ierakstā tiek norādīts, cik baitu jānoņem no iepriekšējā ieraksta ceļa, un pēc tam jaunais sufikss. Tas ievērojami samazina indeksa izmēru dziļi ligzdotos kokos.

Konfliktu posmi

Sapludināšanas konflikta laikā vienam ceļam var būt vairāki indeksa ieraksti dažādos posmos:

Posms Nozīme
0 Parasts (bez konflikta)
1 Bāzes versija (kopīgais priekštecis)
2 Mūsu versija (pašreizējais zars)
3 Viņu versija (sapludināmais zars)
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]

Indeksa paplašinājumi

Paplašinājumi tiek pievienoti pēc ierakstiem un pirms kontrolsummas. Katram paplašinājumam ir 4 baitu paraksts, 4 baitu izmērs un mainīga garuma dati.

Pitmaster saglabā paplašinājumu blokus kā neapstrādātus baitus ($index->extensions() atgriež signature un data pārus) un ieraksta tos atpakaļ bez izmaiņām, ja ieraksti nav skarti. Tas nevienu paplašinājumu neinterpretē un neģenerē, un jebkuras izmaiņas ierakstos tos visus dzēš; git vajadzības gadījumā tos pieņem un izveido no jauna. Turpmāk ir aprakstīti git izmantotie paplašinājumi.

TREE paplašinājums

Kešatmiņā saglabā direktoriju iepriekš aprēķinātos koka objektus. Paātrina git status un git commit, jo nav atkārtoti jāaprēķina koki, ja mainījies tikai indekss.

Paraksts: TREE (0x54524545)

REUC paplašinājums

Reģistrē informāciju par konflikta atrisināšanas atsaukšanu. Pēc konflikta atrisināšanas sākotnējie 1./2./3. posma ieraksti tiek pārvietoti šeit, lai tos varētu atjaunot ar git checkout -m.

Paraksts: REUC (0x52455543)

Citi paplašinājumi

git raksta arī:

  • EOIE (indeksa ieraksta beigas): norāda, kur beidzas ieraksti un sākas paplašinājumi
  • IEOT (indeksa ierakstu nobīžu tabula): nodrošina paralēlu indeksa ielādi
  • link (sadalīts indekss): lieliem repozitorijiem, kuros izmantots sadalīts indekss

git formātā paplašinājumi, kuru paraksts sākas ar lielo burtu, nav obligāti, bet tie, kas sākas ar mazo burtu, ir obligāti. Pitmaster pieņem abus veidus bez pārbaudes. Sadalīts indekss (link) netiek ielādēts, tāpēc repozitoriji, kuros tas tiek izmantots, netiek atbalstīti.

Kontrolsumma

Indeksa faila beigās ir visu iepriekšējo baitu kontrolsumma, kas aprēķināta, izmantojot repozitorija jaucējalgoritmu (20 baiti SHA-1 gadījumā, 32 baiti SHA-256 gadījumā). Pitmaster to ieraksta saglabājot, bet nepārbauda lasīšanas laikā.

Index::open() un Index::parse() izmet IndexParseException, ja trūkst DIRC paraksta vai ir neatbalstīta versija.

Indekss un statuss

Indekss ir būtisks statusa aprēķināšanai. WorkingTreeStatus salīdzina:

  1. HEAD koku ar indeksu: nosaka indeksētās izmaiņas
  2. Indeksu ar darba koku: nosaka neindeksētās izmaiņas

Statistikas lauki (ctime, mtime, dev, ino, size, mode, uid, gid) ļauj ātri pārbaudīt, vai fails ir mainījies, nenolasot tā saturu. Ja statistikas lauki sakrīt un fails ir pēdējo reizi mainīts pirms statusa skenēšanas sākuma, tiek pieņemts, ka fails nav mainīts. Atšķirīgs izmērs uzreiz norāda uz izmaiņām. Pretējā gadījumā Pitmaster nolasa failu un aprēķina tā jaucējvērtību, lai pārbaudītu, vai saturs tiešām ir mainījies.

Pieņemt kā derīgu karodziņš

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

Šis karodziņš liek git statusa pārbaudes laikā izlaist failu, pat ja statistikas lauki ir mainījušies (git update-index --assume-unchanged). Pitmaster saglabā šo bitu, pārrakstot ierakstus, taču tā statusa komanda to neņem vērā un joprojām salīdzina failu.