Konverzia zo Subversion do Gitu

Nedávno som dostal do spravy existujúci projekt a jednou z prvých veci, ktoré som sa rozhodol urobiť bol prechod na použitie Gitu namiesto Subversion. Pritom som, samozrejme, potreboval konvertovať existujúcu históriu zmien. Projekt nebol veľký, takže celý proces bol pomerne jednoduchý. Svoje postrehy a riešenia problémov som zhrnul v tomto článku.

Celý proces konverzie sa skladal z dvoch krokov:

  1. prevodu repozitára pomocou git-svn a
  2. „upratania“ výsledného repozitára.

Príkaz git svn umožňuje používať Git ako klient pre Subversion. Je teda možné vytvoriť lokálny Git repozitár, ktorý bude kópiou Subversion repozitára a zmeny urobené v Gite je možné nahrať naspäť do Subversion.

Pritom musíte brať do úvahy to, že model ukladania histórie v Subversion je vo viacerých ohľadoch odlišný od Gitu. Napríklad, zatiaľ čo Git používa na označenie autorov revízii ich meno a e-mailovú adresu, Subversion zaznamenáva len ich prihlasovacie mena.

Na základný prevod som teda použil príkaz v tvare:

git svn clone -s -A authors.txt <svn-repository-url> \
        <local-repository-path>

Prepínač -s alebo --stdlayout označuje to, že repozitár používa štandardné rozloženie s podadresármi trunk, tags a branches a tie sa použijú pre správnu konverziu vetiev a značiek. Za prepínačom -A alebo --authors-file= je uvedený súbor s priradením mien a e-mailových adries autorov ich prihlasovacím menám v Subversion. Záznamy v tomto súbore sú v tváre:

svn-login = Meno <email>

Po tomto je repozitár konvertovaný a je možné začať jeho čistenie. Keďže git-svn zabezpečuje obojsmernú konverziu, do každej revízie sú zaznamenané informácie identifikujúce zodpovedajúcu revíziu v Subversion. Tie sú súčasťou komentára a začínajú reťazcom „git-svn-id:“. Ja som neplánoval ďalej používať Subversion, takže tieto identifikátory boli pre mňa zbytočné. Na druhej strane som chcel zachovať pôvodné číslo revízie. Inšpirovaný článkom Treya Hunnera som ich nahradil za značky v tváre svn: <číslo revízíe> pomocou príkazu:

git filter-branch -f --msg-filter \
        'sed -E "s/^git-svn-id:.*@([0-9]*).*$/svn: \1/"'

Príkaz git filter-branch prechádza všetky revízie a upravuje ich komentáre pomocou zadaného programu. V dánom prípade je to jednoduché nahradenie textu pomocou regulárneho výrazu.

Pôvodné čísla revízii majú nielen historickú hodnotu. Subversion totiž podporuje aj revízie bez komentára a v danom projekte takýchto revízii bolo viacero. Tieto revízie teraz získali aspoň komentár s poradovým číslom v starom systéme.