Āķi
Git āķi ir izpildāmi skripti .git/hooks/, kas darbojas noteiktos git darbību brīžos. Pitmaster nosaka un izsauc āķus, izmantojot PHP procesu vadību (proc_open).
Āķi tiek palaisti pēc noklusējuma
Repozitorija darbības automātiski palaiž āķus, kas uzskaitīti sadaļā Āķi Pitmaster izpilda. Lai tos izslēgtu repozitorija tvērumam, norādiet opcijas, to atverot:
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
Pitmaster::init() un Pitmaster::clone() pieņem vienas un tās pašas opcijas. Āķa palaišanai nepieciešams proc_open(); vidēs, kur tas ir atspējots, atveriet repozitorijus ar ['hooks' => false]. CLI vienmēr atver repozitoriju ar ieslēgtiem āķiem.
Pitmaster meklē āķus tikai mapē <gitDir>/hooks. Tas ignorē core.hooksPath, bet saistītā darbkokā meklē mapē .git/worktrees/<name>/hooks, tāpēc koplietotie skripti .git/hooks tur nedarbojas (#12).
HookRunner, kas aprakstīts tālāk, ignorē šīs opcijas: izsaucot to tieši, āķis vienmēr tiek palaists.
HookRunner
use Pitmaster\Hooks\HookRunner;
$hooks = new HookRunner($repo->gitDir());
Pārbaude, vai āķis pastāv
if ($hooks->exists('pre-commit')) {
echo "pre-commit hook is installed\n";
}
Āķis pastāv, ja fails atrodas šeit: .git/hooks/<name>, un ir izpildāms.
Āķa palaišana
$result = $hooks->run('pre-commit');
echo $result['exitCode']; // 0 = success
echo $result['stdout']; // Hook's standard output
echo $result['stderr']; // Hook's standard error
Ar argumentiem
$result = $hooks->run('commit-msg', ['/path/to/COMMIT_EDITMSG']);
Ar stdin
$result = $hooks->run('pre-push', ['origin', 'https://github.com/user/repo.git'], $stdinData);
Āķis pre-push saņem ref informāciju, izmantojot stdin.
Veiksmīgas izpildes pārbaude
if ($hooks->runAndCheck('pre-commit')) {
// Hook passed (exit code 0), proceed with commit
} else {
// Hook rejected the operation
}
runAndCheck() ir palīgfunkcija, kas palaiž āķi un atgriež true, ja izejas kods ir 0. Ja āķa nav, tā atgriež true (ja āķa nav, tas nav iebildums).
Instalēto āķu saraksts
$installed = $hooks->listHooks();
// ['pre-commit', 'commit-msg', 'post-checkout']
Uzskaita visus izpildāmos failus mapē .git/hooks/ (izņemot .sample failus).
run() neesošam vai neizpildāmam āķim atgriež 0 izejas kodu un tukšu izvadi. Ja procesu nevar palaist, tas atgriež 1 izejas kodu un izvada Failed to start hook uz stderr.
Āķa instalēšana
$hooks->install('pre-commit', "#!/bin/bash\nphp vendor/bin/phpcs --standard=PSR12 .\n");
Ieraksta skripta saturu failā .git/hooks/<name> un iestata izpildes atļauju (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);
Āķi, ko izpilda Pitmaster
HookRunner var izpildīt jebkuru āķi pēc nosaukuma. Repository automātiski izpilda šos āķus:
| Āķis | Izpilda | Argumenti | Var pārtraukt? |
|---|---|---|---|
pre-commit |
commit() |
nav | Jā (izejas kods nav nulle) |
prepare-commit-msg |
commit() |
ziņojuma fails, pēc tam message (vai merge, pabeidzot sapludināšanu) |
Jā |
commit-msg |
commit() |
ziņojuma fails (.git/COMMIT_EDITMSG); faila izmaiņas tiek izmantotas |
Jā (izejas kods nav nulle) |
post-commit |
commit() |
nav | Nē (informatīvs) |
pre-rebase |
rebase() |
augšupējā versija | Jā |
post-checkout |
checkout() |
vecais HEAD, jaunais HEAD, 1 |
Nē (informatīvs) |
post-merge |
merge(), mergeOctopus(), mergeContinue() |
0 |
Nē (informatīvs) |
pre-push |
push() un tā varianti |
attālā repozitorija nosaukums, URL; ref rindas stdin ievadē | Jā (izejas kods nav nulle) |
Ja āķa izpilde neizdodas, darbība izraisa RuntimeException('<name> hook failed'); āķa izvade netiek iekļauta. Commit āķi tiek palaisti tikai no commit(): merge() izveidoti sapludināšanas komiti tos nepalaiž. post-checkout netiek palaists, ja izmanto addWorktree(), reset() vai restore().
Servera puses āķi (pre-receive, update, post-receive, post-update), pre-auto-gc un post-rewrite nekad netiek palaisti automātiski.
Āķa vide
Kad Pitmaster palaiž āķi, tas nodod šādu vidi:
$env = [
'GIT_DIR' => $this->gitDir,
'GIT_WORK_TREE' => dirname($this->gitDir),
];
Šie ir vienīgie mainīgie, ko saņem āķis: PATH, HOME un visi pārējie PHP procesa mainīgie netiek nodoti tālāk (#13). Āķa skriptos izmantojiet absolūtos ceļus vai iestatiet PATH pašā skriptā; #!/usr/bin/env php shebang atrod interpretatorus tikai sistēmas noklusējuma ceļā.
Āķis darbojas mapē dirname($gitDir), kas parastam .git direktorijam ir darbkoks.
Āķa skripta formāts
Āķus var rakstīt jebkurā valodā. Pirmajai rindai jābūt shebang rindai:
#!/bin/bash
# Bash hook
#!/usr/bin/env php
<?php
// PHP hook
#!/usr/bin/env python3
# Python hook
Piemērs: pre-commit ar Pitmaster
commit() jau izpilda pre-commit, prepare-commit-msg, commit-msg un post-commit, tāpēc lietotnes kodam jāapstrādā tikai kļūmes gadījums:
try {
$commitId = $repo->commit('Add feature');
} catch (\RuntimeException $e) {
echo $e->getMessage(); // "pre-commit hook failed"
}
Izsauciet HookRunner paši tikai ar apstrādātāju, kas atvērts ar ['hooks' => false], vai āķiem, ko Pitmaster nepalaiž.
Āķu piemēri
Git inicializē repozitorijus ar .sample āķu failiem; Pitmaster::init() izveido tukšu hooks/ direktoriju. Pitmaster listHooks() ignorē .sample failus:
.git/hooks/
pre-commit.sample (excluded from listHooks)
commit-msg.sample (excluded from listHooks)
pre-commit (included - installed by user)