Koukkukohdat
Git-koukut ovat suoritettavia komentosarjoja paikassa .git/hooks/, ja ne suoritetaan tietyissä git-toimintojen vaiheissa. Pitmaster tunnistaa ja käynnistää koukut hyödyntämällä PHP-prosessinhallintaa (proc_open).
Koukkuja suoritetaan oletusarvoisesti
Varastotoiminnot suorittavat automaattisesti koukut, jotka on lueteltu kohdassa Koukut, jotka Pitmaster suorittaa. Voit poistaa ne käytöstä varastokahvaa varten antamalla asetukset sitä avattaessa:
use Pitmaster\Pitmaster;
// Skip .git/hooks scripts for this handle
$repo = Pitmaster::open('/path/to/project', ['hooks' => false]);
// Start no processes at all: hooks, the fsmonitor hook, clone/fetch/push, and SSH are disabled
$repo = Pitmaster::open('/path/to/project', Pitmaster::processFreeOptions());
$repo->hooksEnabled(); // false
$repo->processesEnabled(); // false for the second handle
Sekä Pitmaster::init() että Pitmaster::clone() hyväksyvät samat asetukset. Koukun suorittaminen vaatii toiminnon proc_open(); ympäristöissä, joissa se on poistettu käytöstä, avaa varastot asetuksella ['hooks' => false]. CLI avaa varaston aina koukut käytössä.
Pitmaster etsii koukkuja vain kohteesta <gitDir>/hooks. Se ohittaa kohteen core.hooksPath, ja linkitetyssä työpuussa se etsii kohteesta .git/worktrees/<name>/hooks, joten jaetut .git/hooks-komentosarjat eivät suoritu siellä (#12).
Alla kuvattu HookRunner ohittaa nämä asetukset: sen suora kutsuminen suorittaa koukun aina.
HookRunner
use Pitmaster\Hooks\HookRunner;
$hooks = new HookRunner($repo->gitDir());
Tarkista, onko koukku olemassa
if ($hooks->exists('pre-commit')) {
echo "pre-commit hook is installed\n";
}
Koukku on olemassa, jos tiedosto on kohteessa .git/hooks/<name> ja suoritettavissa.
Suorita koukku
$result = $hooks->run('pre-commit');
echo $result['exitCode']; // 0 = success
echo $result['stdout']; // Hook's standard output
echo $result['stderr']; // Hook's standard error
Argumenteilla
$result = $hooks->run('commit-msg', ['/path/to/COMMIT_EDITMSG']);
Vakiosyötteellä
$result = $hooks->run('pre-push', ['origin', 'https://github.com/user/repo.git'], $stdinData);
pre-push-koukku saa viitetiedot vakiosyötteestä.
Tarkista onnistuminen
if ($hooks->runAndCheck('pre-commit')) {
// Hook passed (exit code 0), proceed with commit
} else {
// Hook rejected the operation
}
runAndCheck() on apumenetelmä, joka suorittaa koukun ja palauttaa arvon true, jos poistumiskoodi on 0. Jos koukkua ei ole olemassa, se palauttaa arvon true (koukun puuttuminen ei estä toimintoa).
Luettele asennetut koukut
$installed = $hooks->listHooks();
// ['pre-commit', 'commit-msg', 'post-checkout']
Luettelee kaikki kohteessa .git/hooks/ olevat suoritettavat tiedostot (ohittaa tiedostot .sample).
Jos koukkua ei ole tai se ei ole suoritettavissa, run() palauttaa poistumiskoodin 0 ja tyhjän tulosteen. Jos prosessia ei voi käynnistää, se palauttaa poistumiskoodin 1 ja kirjoittaa arvon Failed to start hook vakiovirtaan.
Asenna koukku
$hooks->install('pre-commit', "#!/bin/bash\nphp vendor/bin/phpcs --standard=PSR12 .\n");
Kirjoittaa komentosarjan sisällön kohteeseen .git/hooks/<name> ja asettaa suoritusoikeuden (chmod 0755).
// Install a PHP hook
$hooks->install('pre-commit', <<<'HOOK'
#!/usr/bin/env php
<?php
// Run static analysis before commit
$output = [];
$returnCode = 0;
exec('php vendor/bin/phpstan analyse --no-progress 2>&1', $output, $returnCode);
if ($returnCode !== 0) {
echo "PHPStan found errors:\n";
echo implode("\n", $output) . "\n";
exit(1);
}
HOOK);
Koukkujen suoritus kohteessa Pitmaster
HookRunner voi suorittaa minkä tahansa koukun nimen perusteella. Repository suorittaa nämä automaattisesti:
| Koukku | Suorittaja | Argumentit | Voiko keskeyttää? |
|---|---|---|---|
pre-commit |
commit() |
ei mitään | Kyllä (muu kuin nolla -poistumiskoodi) |
prepare-commit-msg |
commit() |
viestitiedosto, sitten message (tai merge yhdistämisen valmistuessa) |
Kyllä |
commit-msg |
commit() |
viestitiedosto (.git/COMMIT_EDITMSG); tiedostoon tehdyt muutokset otetaan käyttöön |
Kyllä (muu kuin nolla -poistumiskoodi) |
post-commit |
commit() |
ei mitään | Ei (vain tiedoksi) |
pre-rebase |
rebase() |
ylävirran revisio | Kyllä |
post-checkout |
checkout() |
vanha HEAD, uusi HEAD, 1 |
Ei (vain tiedoksi) |
post-merge |
merge(), mergeOctopus(), mergeContinue() |
0 |
Ei (vain tiedoksi) |
pre-push |
push() ja sen muunnelmat |
etänimi, URL; viiterivit vakiosyötteessä | Kyllä (muu kuin nolla -poistumiskoodi) |
Epäonnistunut koukku aiheuttaa toiminnon keskeyttävän RuntimeException('<name> hook failed')-poikkeuksen; koukun tulostetta ei sisällytetä siihen. Commit-koukut suoritetaan vain kohteesta commit(): kohteen merge() luomat yhdistämiscommitit eivät suorita niitä. post-checkout ei suoritu kohteille addWorktree(), reset() eikä restore().
Palvelinpuolen koukkuja (pre-receive, update, post-receive, post-update), pre-auto-gc-koukkua eikä post-rewrite-koukkua suoriteta koskaan automaattisesti.
Koukkuympäristö
Kun Pitmaster suorittaa koukun, se välittää sille tämän ympäristön:
$env = [
'GIT_DIR' => $this->gitDir,
'GIT_WORK_TREE' => dirname($this->gitDir),
];
Nämä ovat ainoat muuttujat, jotka koukku saa: muuttujia PATH ja HOME eikä mitään muita PHP-prosessin muuttujia välitetä (#13). Käytä koukkukomentosarjoissa absoluuttisia polkuja tai aseta PATH komentosarjan sisällä; #!/usr/bin/env php-shebang löytää tulkit vain järjestelmän oletuspolusta.
Koukku suoritetaan kohteessa dirname($gitDir), joka on tavallisen .git-hakemiston työpuu.
Koukkukomentosarjan muoto
Koukkuja voi kirjoittaa millä tahansa kielellä. Ensimmäisen rivin on oltava shebang:
#!/bin/bash
# Bash hook
#!/usr/bin/env php
<?php
// PHP hook
#!/usr/bin/env python3
# Python hook
Esimerkki: pre-commit ja Pitmaster
commit() suorittaa jo kohteet pre-commit, prepare-commit-msg, commit-msg ja post-commit, joten sovelluskoodin tarvitsee vain käsitellä epäonnistuminen:
try {
$commitId = $repo->commit('Add feature');
} catch (\RuntimeException $e) {
echo $e->getMessage(); // "pre-commit hook failed"
}
Kutsu HookRunner itse vain kahvalla, joka on avattu asetuksella ['hooks' => false], tai niiden koukkujen kohdalla, joita Pitmaster ei suorita.
Esimerkkikoukut
Git alustaa varastot .sample-koukkutiedostoilla; Pitmaster::init() luo tyhjän hooks/-hakemiston. Kohteen Pitmaster listHooks() ohittaa tiedostot .sample:
.git/hooks/
pre-commit.sample (excluded from listHooks)
commit-msg.sample (excluded from listHooks)
pre-commit (included - installed by user)