Jak psát kód: Commit musí repozitář udržet stabilní

Školení, která pořádám

Já se snažím software vyvíjet tak, že jde kdykoliv vydat. Aplikace je po každém commitu stabilní a plně funkční. Tohle je obzvlášť důležité, pokud na projektu pracuje víc lidí. Pokud něco rozbijete, tak tím téměř vždy blokujete ostatní. Navíc můžete zapomenout na to, že jste něco ještě chtěli opravit.

Tohle pravidlo je velmi důležité u refaktoringu nebo při změně API. Měníte nějakou funkci, která je volaná z mnoha míst? Ve stejném commitu změňte i všechna volání. Je volání hodně a chcete commit rozdělit, aby byly změny přehlednější? To je chvályhodné. Rozdělte ho v tom případě na tři:

  1. Uvedení nové funkce. Starou funkci můžete přepsat tak, aby novou funkci využívala, a označit ji jako zastaralou.
  2. Změna všech volání ze staré funkce na novou.
  3. Odstranění staré funkce.

Pokud je měněná funkce veřejná a vy nemáte pod kontrolou všechna místa, ze kterých se volá, tak mezi prvním a třetím bodem může být třeba měsíc nebo rok. Často je pak lepší udělat změnu zpětně kompatibilní i za cenu kompromisu.

Pokud smažete všechna volání nějaké funkce, tak byste obvykle měli smazat i tuto funkci. Neplatí to vždy – pokud např. chcete mít metody, které z objektu vytáhnou jeho jednotlivé vlastnosti, tak metodu nesmažete jen proto, že ji zrovna nikdo nevolá. Zvažte ale, jestli takové metody opravdu pro všechny vlastnosti potřebujete.

Pravidlo samozřejmě platí nejenom pro PHP. Do HTML nesmíte přidat odkaz, který nikam nevede. V JavaScriptu nesmíte použít konstrukci, která nefunguje ve všech podporovaných prohlížečích.

Než někam jdete, tak odevzdejte změny, které jste provedli. Ostatní můžou váš kód potřebovat nebo ho chtít upravit. To může být v rozporu s požadavkem na udržení stabilního repozitáře. V tom případě změny commitněte do branche. Snažte se práci ale spíš organizovat tak, aby to byla posloupnost malých, snadno pochopitelných změn než jedna velká změna jednou za čas. I z velké změny se dá obvykle vyčlenit několik stabilních přípravných fází.

K dodržování tohoto pravidla mi mimojiné pomáhá to, že se před každým commitem podívám na diff toho, co odevzdávám. Občas si do kódu při vývoji přidám např. sleep(1), abych nasimuloval chování na pomalé síti, a diff mi pomáhá v tom, abych ho nezapomněl zase odstranit.

Jakub Vrána, Dobře míněné rady, 27.5.2013, diskuse: 3 (nové: 0)

Diskuse

David:

Perfektni prispevek, jen k te posledni casti:
Nebylo by lepsi podporovat latency injection primo na platforme a ridit jej pomoci nejakeho configu? Tim by se pak dalo simulovat chovani vsech komponent systemu, kdyz jedna ma increased latency.  Davat hardcoded sleep and nasledne jej rucne oddelavat pote, co me na nej diff upozorni, si dle meho zadelava na human error.

ikona Jakub Vrána OpenID:

Záleží na tom, jakou mám k dispozici abstrakci. Třeba v Admineru jich po ruce moc nemám a dodělat je by bylo dost komplikované, protože z kompilované verze bych je chtěl zase odstranit. Ani v běžném systému není abstrakce na lagy moc běžná, když to obvykle potřebuji vyzkoušet jen jednou za čas jednorázově.

Navíc stejně jako můžu zapomenout sleep(1) v kódu, můžu zapomenout lag=1 v configu.

Honza Hommer:

Na lag=1 sice zapomenout můžeš, ale nějaký obyčejnější deploy ti hodnotu může automaticky přepsat na lag=0 a ty to nemusíš řešit :-)

Každopádně taky ujíždim na sleep(1).

Diskuse je zrušena z důvodu spamu.

avatar © 2005-2024 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.