Git hooky a agenti

Pre-commit hook, který mlčí, když je čisto, a formát bare pro nástroje a agenty, kteří potřebují vědět, které soubory se přepsaly.

Pre-commit

Hook má být rychlý a tichý: zkontrolovat jen soubory, které jdou do commitu, a při čistém stavu nevypsat nic. Formát bare je pro to stavěný a --stdin umožňuje kontrolovat obsah z indexu, ne z pracovního stromu, který se může lišit:

#!/bin/sh
status=0
for file in $(git diff --cached --name-only --diff-filter=ACM -- '*.php'); do
	git show ":$file" | vendor/bin/dresscode check --stdin "$file" -f bare || status=1
done
exit $status

Uložte jako .git/hooks/pre-commit a nastavte spustitelný bit. Když je vše v pořádku, hook nic nevypíše a commit projde; jinak vypíše soubor a pod ním porušení s řádkem, zprávou a pravidlem, bez hlavičky a shrnutí, a commit zastaví.

Kdo chce hook, který rovnou opravuje, pustí fix nad pracovním stromem a opravené soubory přidá do indexu; je to pohodlné, ale znamená to, že commit obsahuje změny, které vývojář neviděl. Já mám radši první variantu a opravu na jedno stisknutí v editoru.

S nástrojem pre-commit je to jeden záznam:

repos:
  - repo: local
    hooks:
      - id: dresscode
        name: DressCode
        entry: vendor/bin/dresscode check -f bare
        language: system
        types: [php]

Agenti

Kdo nechává kód psát agenta, potřebuje, aby se soubor po každém zápisu srovnal podle standardu, a zároveň aby se agent dozvěděl, že se soubor pod ním změnil. Jinak nastane známá smyčka: agent zapíše use, hook ho jako nepoužitý smaže, agent přidá kód, který ten import potřeboval, a diví se.

Formát bare na to odpovídá jedním řádkem:

vendor/bin/dresscode fix src/Cart.php -f bare
src/Cart.php  rewritten

Řádek rewritten říká agentovi, že si má soubor znovu přečíst, než na něj sáhne; porušení, která zůstala, dostane ve stejném výpisu a může je opravit sám. Čistý soubor nevypíše nic, takže hook nezahlcuje kontext. Přesně tak je zapojený hook v pluginu Nette pro Claude Code a stejný tvar funguje pro jakýkoli nástroj, který umí spustit příkaz po zápisu souboru.

verze: 1.0