27
marca
2009
Git jest jak Railsy, trendy, jazzy i w ogóle cool, chociaż samo mówienie cool już nie jest cool. Dlatego też chciałem spróbować zmierzyć się z przeniesieniem jednego z moich projektów (o którym już niedługo napiszę też tutaj) na Gita. Tyle, że nie tak po prostu na Gita, ale tylko wersję lokalną, gdyż całość jest hostowana na code.google.com i nie mam póki co zamiaru tego zmieniać (Tak, wiem, że GitHub istniejei fajny jest). W tym wpisie postanowiłem przedstawić migrację na Gita ale tylko na poziomie workspace'a z SVNem w tle jako głównym zcentralizowanym repozytorium.
Dlaczego tak? Ano dlatego, że Git jest reprezentantem DVCS, czyli Decentralized Version Control System. Czyli, nie potrzebujesz internetu aby na nim pracować, gdyż wszystkie commity zostają na twoim komputerze, oraz nie ma centralnego repozytorium kodu, gdzie wszyscy popychają swoje zmiany. Z początku pomysł wydaje się być szalony, ale właśnie dlatego połączenie Gita i SVNa brzmi sensownie. Jakie jeszcze plusy? Np. bardzo lekkie branche, w których przełączanie jest błyskawiczne - podobnie jak i mergowanie (bez zapamiętywania numerku ostatniej rewizji merge'a jak to np. miejsce jeszcze niedawno w SVN1.4).
Wracając jednak do zmuszenia do współpracy Gita i SVNa, to spróbuję opisać w tym wpisie krok po kroku jak tego dokonać. Oczywiście zakładam, że już zainstalowałeś Gita na swoim ulubionym systemie operacyjnym oraz, że komenda: git --version wygląda podobnie jak u mnie:
$ git --version
git version 1.6.1.3
Kolejnym krokiem jest zaimportowanie źródeł z SVNa do repozytorium Gita (możesz to zrozumieć jako svn checkout). Służy do tego komenda git svn clone:
$ git svn clone -s http://sciezka.do.naszego.repo/svn/
Co trzeba wyjaśnić, to to, że argument -s sprawia, że skrypt importujący katalogów zawierających źródła trunka, czy branchy i tagów szuka zgodnie z domyślnymi zasadami SVNa, czyli w katalogu trunk, branch i tags. Oczywiście, jeśli nasze repozytorium przyjęło inne zasady, to można po poszczególnych argumentach nadać te ustawienia: -T [sciezka do trunka] -b [sciezka do branchy] -t [sciezka do tagow]
Po wpisaniu komendy git-svn będzie pobierał poszczególne komity z naszego repozytorium w SVNie i dodawał je do Gita, co może wyglądać np. tak:
...
M examples/test.html
r7 = d4342ca4d3a36035f1a11b03f77dd994ac805de2 (trunk)
M examples/test.html
M examples/ajax.html
r8 = 49aa2467f603cb41f0282eee65223998dabd7222 (trunk)
M file.js
r9 = 483fa801237cf024cf841c8b382f1aaaa901f8c5 (trunk)
M file.js
M examples/prototype.js
r10 = e28b348ee1fd1f08a27c8896864d865c5c3584bd (trunk)
M file.js
...
Jeśli nasze repo zawiera kilka/-naście tysięcy zmian może to potrwać nawet dłuższą chwilę. Jeśli nie chcemy w Gitcie przechowywać całej historii zmian, które i tak już są w svnie, możemy poprosić go aby np. pobrał tylko ostatnią(lub dowolną inną) rewizję i z niej stworzył nowe repozytorium Gita. Uwaga, parametr -rNumerRewizji nie zaczyna pobierania od tej rewizji, tylko na jej podstawie buduje projekt. Aby zaktualizować je o nowsze rewizje trzeba wykonać już ręcznie git svn rebase, co wyjaśnię później. Tak więc, przykład komendy tworzącej repozytorium z 21 rewizji naszego projektu wygląda mniej więcej tak:
$ git svn clone -s http://sciezka.do.naszego.repo/svn/ -r21 katalog_z_projektem
Aby szybko podejrzeć, jakie zmiany zostały zapisane w repozytorium moża posłużyć się komendą git log wewnątrz katalogu z repozytorium. Pokaże ona wszystkie commity wraz z wiadomościami się nich tyczącymi
Dobrze, pobraliśmy już nasze repozytorium, i jeśli mieliśmy naprawdę dużo zmian, to nasze repozytorium pęka w szwach. Aby nieco skompresować dane przechowywane przez Gita posłużymy się komendą git gc, której wynik na moim mini projekcie prezentuję poniżej. Przy czym ls -a | xargs du -hs pokazuje listę plików w biezacym katalogu wraz z ich rozmiarami.
$ ls -a | xargs du -hs
888K .
1,9M ..
636K .git
4,0K file.css
16K file.js
12K file.min.js
216K examples
4,0K test_file
$ git gc
Counting objects: 98, done.
Compressing objects: 100% (95/95), done.
Writing objects: 100% (98/98), done.
Total 98 (delta 48), reused 0 (delta 0)
$ ls -a | xargs du -hs
428K .
1,5M ..
176K .git
4,0K file.css
16K file.js
12K file.min.js
216K examples
4,0K test_file
Zysk z kompresji jak widać jest. Mój projekt ma tylko 23 commity 8 plików i nieskompresowane repozytorium osiągnęło prawie 700KB, po kompresji tylko 170KB.
Tak przygotowany projekt jest gotowy do pracy. Możemy do woli edytować kod, tworzyć nowe pliki i co nam się tylko żywnie podoba, łącznie z commitowaniem plików do Gita, tworzeniem branchy, tagów importowaniem innych Git repozytoriów i co tylko. A jeśli najdzie nas ochota na zaktualizowanie kodu o dane z svna, czyli wykonanie tradycyjnego svn up, wystarczy, że wywołamy komendę git svn rebase:
$ git svn rebase
Current branch master is up to date.
Zapytacie, no dobrze, scommitowałem swoje pliki lokalnie, ale chcesz się nimi też podzielić z głównym repozytorium kodu (SVNem), co zrobić? Do tego wystarczy równeż pojedyńcze polecenie:git svn dcommit. Ja w moim przykładzie użyłem dodatkowo ścieżki do które commit ma pójść, gdyż bez tego code.google nie chciało domyślnie przyjąć mojego commitu. Było to związane ze sposobem uwierzytelniania po stronie google'a (httpsem). Jednak, w przypadku protokołu http://, czy svn:// wszystko powinna załatwić komenda bez dodatkowych parametrów.
$ git svn dcommit --commit-url https://test_git_proj.googlecode.com/svn/trunk/
Committing to https://test_git_proj.googlecode.com/svn/trunk/ ...
Authentication realm: <https://test_git_proj.googlecode.com:443> Google Code
Subversion Repository
Password for 'ravbaker':
A test_file
Committed r24
A test_file
r24 = 74b1158cb274861ac4f5aa1c6ea703f6a0686a7c (trunk)
No changes between current HEAD and refs/remotes/trunk
Resetting to the latest refs/remotes/trunk
Co robi dcommit? Wysyła wszystkie stworzone przez nas commity do SVNa i każdy z nich zapisuje tak, jak jest, z identycznym komentarzem. Proste, prawda?
To w zasadzie tyle, jeśli chodzi o przejście na system zarządzania wersjonowaniem Git z SVNa. Na zakończenie dopowiem tylko, że nie jestem jakimśtam guru od Gita, po prostu postanowiłem gdzieś spisać wynik wieczoru w nadziei, że i komuś jeszcze spodoba się Git.
Jeśli ktoś nie wie jeszcze niczego o branchach, tagach i commitowaniu w Gitcie, to polecam zbiór artykułów na ten temat zebrany przez gości z 37signals (https://37s.backpackit.com/pub/1465067, a szczególnie http://git.or.cz/course/svn.html opisujący jak komendy w SVNie mają się do tych w Gitcie, a także Intro to Git for Web Designers - bardzo fajny artykuł z wczoraj. A sam jeszcze jestem pod wrażeniem książki od PragProg pod tytułem: Pragmatic Version Control Using Git. Również mogę szczerze polecić. Dobrej zabawy z Gitem.
(Komentarz zmodyfikowany 01.04.2009 o 01:19)
Praca z Gitem lokalnie a z SVNem globalnie, cz. 2 - uprzyjemnianie pracy
W poprzednim wpisie poruszyłem temat podstawowej migracji na hybrydę: Git lokalnie, SVN zdalnie. W dzisiejszym wpisie czas na nieco bardziej szczegółowe zagłębienie się w niuanse codziennej pracy za Gitem. Spróbuję poruszyć tematy takie ja[...]
Eee a po co do tego svn dopychac ?
@teamon:czyli już załapałeś jak to działa? ;-)
Mianowicie, SVN w tle potrzebny jest, gdyż daje w prosty sposób( bez stawiania nowego serwera kodu dla juz istniejacego projektu) możliwość prowadzenia projektu lokalnie na Gitcie, mamy załatwioną sprawę autentykacji dodawanych zmian, a także jest to najmniej bolesny sposób na przejście z SVNa na Gita. Nawet gdy Twój szef jest sceptyczny. Bo możesz sobie zaimportować projekt do lokalnego Gita i potem po prostu bawić się do woli tym co on daje. A gdy najdzie Cię ochota, żeby podzielić się czymś ze światem, przepychasz wszystkie commity do centralnego repo w svnie. ;-)
Muszę jeszcze rozkminić obsługę branchy w takim repo, ale spoko - jak zgłębię temat to będzie kolejny wpis.
Czekam na kolejne wpisy o GIT w takim razie. Ostatnio próbowałem z niego korzystać, ale jak zwykle command line mnie odstraszył :(
Jakoś za bardzo przyzwyczaiłem się do TortoiseSVN, przez co gubię się nieco we wszystkim kiedy chcę coś z konsoli zrobić ..
Co do podawania ścieżki przy dcommit: Wystarczy przy klonowaniu podać odpowiedni adres (tj. z https), a jeżeli już się sklonowało ze złym adresem zawsze można go poprawić w .git/config w sekcji [svn-remote „svn”].
№ 6
23 maja 2009, 16:57:40
dc1
Tylko w Polsce mowienie „cool” nie jest cool. W USA i UK to slowo nadal ma „moc”.