Salvestusloend
Git stash salvestab töökausta ja indeksi muudatused, et saaksid liikuda teise ülesande juurde ja need hiljem taastada. Pitmaster rakendab stash'i, kasutades refs/stash ja reflog'i, järgides git salvestuspaigutust. Meetodil Repository pole stash-funktsiooni; kasuta allpool olevat klassi Stash.
Teada on kaks probleemi: mitme kirje korral jätab drop() (ja seega ka pop()) kirje loendisse (#10), ning apply() kirjutab üle kinnitamata muudatused failides, mida salvestusloend ei puuduta (#11). Rakendage salvestusloendi kirjeid puhtas tööpuus.
Salvestusloendi toimimine
Iga salvestusloendi kirje on kahe vanemaga commit:
- Vanem 0: HEAD-i commit salvestamise ajal (baasolek)
- Vanem 1: indeksi oleku (lavastatud muudatuste) jäädvustav commit
Salvestusloendi commiti enda puu jäädvustab tööpuu oleku (sh lavastamata muudatused).
Salvestusloendi „pinu” on asukoha refs/stash reflog. Kõige uuem salvestusloend on refs/stash ise. Vanemad kirjed on reflogi kirjed: stash@{0}, stash@{1} jne.
refs/stash -> stash commit (worktree state)
parent[0] -> HEAD at time of stash
parent[1] -> index state commit
parent[0] -> HEAD at time of stash
Salvestusloendi objekti loomine
use Pitmaster\Stash\Stash;
$stash = new Stash(
$repo->objectDatabase(),
$repo->refDatabase(),
$repo->gitDir(),
$repo->workDir(),
);
Lükake peale (salvestage muudatused)
// public function push(string $message = '', bool $includeUntracked = false): ObjectId
$stashId = $stash->push('Work in progress on login');
echo "Saved: {$stashId->hex}\n";
// Also stash untracked files
$stashId = $stash->push('With new files', includeUntracked: true);
Pealelükkamine teeb järgmist:
- Loeb praeguse HEAD-i commiti
- Koostab praegusest indeksist puu (lavastatud olek)
- Loob „indeksi commiti”, mille vanem on HEAD
- Koostab praegusest töökataloogist puu (sh lavastamata muudatused)
- Loob salvestusloendi commiti (tööpuu puu, vanemad = HEAD + indeksi commit)
- Uuendab väärtuse
refs/stashsalvestusloendi commitile - Lisab pinule reflogi kirje
- Lähtestab tööpuu ja indeksi HEAD-i olekusse
Pärast push'i vastavad jälgitavad failid HEAD-ile. Jälgimata failid jäävad alles, kui pole määratud includeUntracked; sel juhul need eemaldatakse ja salvestatakse stash-kinnituse oma puusse (git salvestab need hoopis kolmandasse eellasse, seega git näeb neid jälgitavate muudatustena). push() loob kirje ka siis, kui midagi pole muutunud; sel juhul teatab git „No local changes to save”.
Vaikesõnumiga
$stashId = $stash->push();
// Message: "WIP on <branch>: <short hash> <HEAD subject>"
// With a message: "On <branch>: <message>"
Eraldatud HEAD-i korral on <branch> väärtus HEAD.
Pop (rakendage ja eemaldage)
$stash->pop();
Rakendab ülemise salvestusloendi kirje töökausta ja eemaldab selle pinust. Samaväärne toiminguga apply(), millele järgneb drop().
Kindla kirje pop-toiming
$stash->pop(1); // Pop stash@{1}
Rakenda (taasta eemaldamata)
$stash->apply(); // Apply stash@{0}
$stash->apply(2); // Apply stash@{2}
Rakendamine ühendab salvestusloendi praeguse HEAD-i failidega ükshaaval (salvestusloendi baas, praegune HEAD, salvestusloendi puu). Kirje jääb pinusse ja indeksit ei puudutata. Konfliktide korral lisatakse failidesse märgenditega Updated upstream ja Stashed changes markerid ning tekib viga Pitmaster\Exceptions\MergeConflictException; pop() jätab seejärel kirje alles. Rakendamine ei kontrolli enne kohalikke muudatusi (vt ülal olevat märkust).
Kirjete loetlemine
$entries = $stash->listEntries();
foreach ($entries as $entry) {
echo "stash@{{$entry['index']}}: {$entry['message']}\n";
// stash@{0}: On main: Work in progress on login
// stash@{1}: WIP on main: f707601 Add login form
}
Iga kirje sisaldab:
index: salvestusloendi asukoht (0 = kõige uuem)message: salvestusloendi sõnumhash: salvestusloendi commiti räsi
Eemaldamine (eemalda rakendamata)
$stash->drop(); // Drop stash@{0}
$stash->drop(1); // Drop stash@{1}
Ainsa kirje eemaldamisel kustutatakse refs/stash ja selle reflog. Kui kirjeid on rohkem, liigutab drop() praegu ainult väärtust refs/stash ega muuda reflogi, mistõttu kirje jääb asukohta listEntries() (#10).
Salvestuse üksikasjad
Salvestusloendi commiti struktuur
commit <hash>
tree <worktree-tree-hash>
parent <HEAD-hash>
parent <index-commit-hash>
author <current identity>
committer <current identity>
<stash message>
Indeksi commiti struktuur
commit <hash>
tree <index-tree-hash>
parent <HEAD-hash>
author <current identity>
committer <current identity>
index on <branch>: <short hash> <HEAD subject>
Identiteet pärineb hoidla konfiguratsioonis esmalt väärtusest GIT_COMMITTER_NAME, seejärel GIT_AUTHOR_NAME, siis user.name ja lõpuks Pitmaster (sama järjekord kehtib e-posti puhul ning lõpus on pitmaster@example.invalid). Kuupäev pärineb esmalt väärtusest GIT_COMMITTER_DATE, seejärel GIT_AUTHOR_DATE ja lõpuks praegusest kellaajast. Erinevalt commitidest ei loe salvestusloend väärtusi PITMASTER_*.
Reflog-i salvestus
Salvestusloendi kirjed asuvad asukohas .git/logs/refs/stash:
0000000000000000000000000000000000000000 abc123... Name <email> 1700000000 +0000 WIP on main: f707601 Add login form
abc123... def456... Name <email> 1700000001 +0000 On main: Work in progress on login
Reflogi loetakse kronoloogilises järjekorras. Salvestusloendi loend pöörab selle ümber (uusim ees). Salvestusloendi reflog kirjutatakse olenemata väärtusest core.logallrefupdates.
CLI kasutamine
# Save current changes
./vendor/bin/pitmaster stash
./vendor/bin/pitmaster stash push
./vendor/bin/pitmaster stash push "Work in progress on login"
# Apply and remove top entry
./vendor/bin/pitmaster stash pop
# Apply without removing
./vendor/bin/pitmaster stash apply
# List all entries
./vendor/bin/pitmaster stash list
# Remove top entry without applying
./vendor/bin/pitmaster stash drop
Sõnum on argument pärast push (või save); -m pole toetatud. pop, apply ja drop toimivad alati asukohas stash@{0}; CLI-il pole väärtust --include-untracked.
Piirangud
- Ainult kogu töökausta salvestamine (ilma
--keep-index-ta); jälgimata failid ainult väärtusepush($message, includeUntracked: true)kaudu --patchrežiimi pole (interaktiivne tükkide valik)- Pop/rakendamine taastab tööpuu oleku, kuid ei taasta indeksit. Lavastatud muudatused taastuvad lavastamata muudatustena ja äsja lavastatud failid jälgimata failidena
stash@{n}ei aktsepteeriRepository::resolve()- Salvestusloendi kasutamine lingitud tööpuus rakendab vale konfiguratsiooni- ja reflogiasukohta (#14)