August 28th, 2009

Post scriptum k setkání na téma verzovací systémy

Včerejší Open Meeting na téma „verzovací systémy“ potvrdil, že se v tomto punktu u nás začínají věci hýbat a VCS se stává důležitou a cennou součástí vývojového cyklu.

Napadlo mně pár poznámek, které bych chtěl ex post uvést.

Rychlost a flexibilita

Jednak je třeba zopakovat, že důraz na rychlost u Gitu neznamená prostě a hloupě to, že „operace probíhají rychle“. (Debaty o „rychlosti“ u mně vždy vyvolávají asociace na tyhle pěkné reklamy s Peterem Stormarem.) Důležité je, že je vůbec někdo dělá, a to platí typicky pro ústřední koncept: branching a merging. Jestliže je obojí v Gitu za a) jednoduché a za b) rychlé, mnohokrát to zvyšuje pravděpodobnost, že se obojí používá. Podobně to platí i pro zobrazování historie, přepínání mezi branchemi, zobrazování historické verze celého projektu či jednotlivého souboru, apod apod.

Mnohokrát také bylo zmíněno, zejména Ladislavem Prskavcem, že Mercurial oproti Gitu představuje mírnější krok, spíše evoluci než revoluci. To rozhodně platí, a kdo si chce vyzkoušet distribuovaný verzovací systém a přechází (typicky) ze Subversion, v Mercurialu se bude cítit daleko víc doma než v Gitu.

Git je totiž docela specifickým zástupcem „verzovacího systému“. Ne nadarmo je jeho přízvisko „the stupid content tracker“. Linus Torvalds stále opakuje, že lze nad Gitem postavit „tradiční verzovací systém“, ale že Git sám o sobě je prostě souborový systém s verzováním.

To má také pravděpodobně za následek, že mnoho věcí není tak intuitivních jako např. ve zmíněném Mercurialu, „ke všemu je spousta přepínačů“, „nesouvisející operace se dělají stejným příkazem“, a tak dále. (Známá stížnost je, že např. nevinně vypadající příkaz git checkout je drsně destruktivní: git checkout file_with_lots_of_work.txt vám tu spoustu práce práce hezky a nenávratně smázne.)

Git jako toolkit

Znamená to ale také, že Git lze považovat za velmi silný a flexibilní toolkit pro iplementaci verzování kdekoliv. Pokud např. potřebujete v aplikaci pracovat s verzovanými daty, zobrazovat jejich rozdíly, udržovat jejich historii, atd. Git může poskytnout obrovskou škálu funkcionality jen co jej „vybalíte z krabice“.

Petr „pasky“ Baudiš, jeden z autorů Gitu, na setkání mluvil o využití Gitu jako toolkitu pro implementaci správy verzí matematických modelů při výzkumu a vývoji léčiv. Já mohu také přispět příkladem „netradičního využití verzovacího systému“.

Kamarád nedávno potřeboval svému klientovi dodat jednoduchý systém na verzování textových dokumentů v podobě webové aplikace. Bylo třeba sledovat revize textu i vložených obrázků, bylo třeba implementovat rozdíl mezi úpravou dokumentu (revizí, kterou může udělat kdokoliv) a platnou verzí, kterou může vytvořit pouze oprávněná osoba, bylo třeba přehledně vypsat diffy mezi jednotlivými revizemi, atd atd. A volba logicky padla na Git jako na toolkit či backend, který podporuje téměř veškerou potřebnou funkcionalitu:

  • Zvládá verzovat cokoliv a pochopitelně velmi dobře textový obsah
  • Poskytuje obrovskou flexibilitu: např. při commitování, kdy umožňuje pomocí přepínače --author jako autora revize uložit přihlášeného uživatele.
  • Pomocí wrapperu Grit lze ušetřit spoustu práce kupříkladu při parsování atributů revize
  • Tagy v Gitu lze využít jako ideální základ pro funkcionalitu „platná verze“, kdy lze opět např. pomocí export GIT_AUTHOR_NAME ovládat parametry commitu tagu
  • Výsledné úložiště je naprosto transparentní a umožnuje prohlížet si jej (případně s ním manipulovat) pomocí obvyklých i neobvyklých Git nástrojů (např. pomocí git filter-branch opravit autora commitů, pokud se vám při vývoji preview verze povede něco pokazit)
  • Díky své architektuře Git znemožňuje změnu v repositáři, aniž by prošla nepovšimnuta. Historii tedy lze „měnit“, ale na podobné hrátky se rychle přijde.
  • Díky distribuované architektuře zcela odstraňuje jedno z nejslabších míst podobných systémů, tzv. single point of failure, kdy existuje jedno autoritativní úložiště dat „k nezaplacení“. Pomocí post-receive hooku se všechny změny automaticky posílají (git push backup --mirror) do vzdáleného repositáře, případně lze naprosto triviálně implementovat další zálohovací operace pomocí pravidelného git pull, a tak dále.

Aplikaci jsme zpracovali jako běžnou Ruby on Rails aplikaci, která data ukládá do databáze „jako normálně“ a pomocí hooks pro ActiveRecord pak vytváří revize, platné verze, atd.:

class Document < ActiveRecord::Base
    # ...
    after_save :create_new_revision, :invalidate_cache
    after_destroy :create_last_revision, :invalidate_cache
    # ...
 
    private
 
    def create_new_revision
      Revision.create(self, @current_revision_author, nil, @current_revision_message)
    end
 
    def create_last_revision
      Revision.delete(self, @current_revision_author, nil, @current_revision_message)
    end
 
    # ...
end
 

Dokumentu pak odpovídá složka nazvaná podle jeho ID a každému (verzovanému) atributu dokumentu pak soubor, obrázky jsou ukládány do podsložky assets. Několikanásobně jednodušší implementaci něčeho podobného si můžete prohlédout v pluginu pro Ruby On Rails acts_as_git.

Ve screenshotech pak aplikace vypadá nějak takto (klikněte pro zobrazení větší verze):

Záhlaví dokumentu (datum, autor poslední revize, apod)

git_toolkit_01

Ukázka jednoduchého diffu revize

git_toolkit_02

Ukázka zobrazení „platné verze“ dokumentu

git_toolkit_03

Git log „jak jsme zvyklí“

git_toolkit_04

Průhlednost implementace — prostě a jednoduše „adresáře a soubory“

git_toolkit_05


Samozřejmě, nic není bez ostrých rohů, a tak se například u podobného projektu můžete docela zapotit nad tím, že HTML a WYSIWYG editor vám nahážou hodně klacků pod nohy co se rozumného zobrazení diffu týče. Ale za to už Git nemůže :)

blog comments powered by Disqus