Żeby było git
« Zmiany w MegiTeam | Obsługujemy PHP »
1 Listopad 2009
Co jakiś czas otrzymujemy pytania dotyczące popularnego rozproszonego systemu kontroli wersji, tj. gita. Postanowiliśmy opisać nasze doświadczenia i wypracowane wzorce postępowania, w typowej sytuacji, czyli repozytorium nie-aż-tak rozproszonego.
Ten post zakłada, że umiesz już pracować z gitem na własnym komputerze a teraz chcesz wypłynąć na szersze wody. Zakładamy też, że masz już repozytorium, które chcesz opublikować. Jeżeli nie -- zakasaj rękawy i do roboty :)
Jak zacząć
Przede wszystkim warto zaopatrzyć się w dość współczesną wersję gita. Wersje starsze niż 1.5 miały zupełnie inną obsługę zdalnych repozytoriów, nie do końca dopasowaną do filozofii gita, co niestety było widać przy co większych akrobacjach. Zdążyliśmy już zapomnieć, jak używa się wersji 1.4 i starszych, i bardzo nam z tym dobrze.
Ten pierwszy raz
Opublikowanie repozytorium, które do tej pory istniało tylko na Twoim komputerze, jest możliwe na kilka sposobów. Żeby nie propagować złych nawyków, podamy tylko ten dobry.
- na serwerze w wybranym katalogu załóż repozytorium. Uwaga: nie będzie to katalog z którego docelowo będzie uruchamiana aplikacja.
user@megiteam:~$ mkdir -p repo/moja-aplikacja.git
user@megiteam:~$ cd repo/moja-aplikacja.git
user@megiteam:~/repo/moja-aplikacja$ git --bare init
- na lokalnym komputerze skonfiguruj zdalne repozytorium, żeby git na Twoim komputerze wiedział, gdzie ma opublikować zmiany:
user@domek:~/moje-repo$ git remote add origin ssh://user@user.megiteam.pl/home/user/www/repo/moja-aplikacja.git
user@domek:~/moje-repo$ git config branch.master.remote origin
user@domek:~/moje-repo$ git config branch.master.merge refs/heads/master
- opublikuj zmiany i pobierz informację o (nowo utworzonej) zdalnej gałęzi:
user@domek:~/moje-repo$ git push origin master
user@domek:~/moje-repo$ git fetch
Od tej pory możesz już poleceniem git push publikować zmiany, a poleceniem git pull je pobierać (np. po szybkich poprawkach w serwisie produkcyjnym, które i tak się prędzej czy później pojawią). Ale jeżeli zajrzysz do katalogu z repozytorium na serwerze, nie zobaczysz tam żadnych plików, z których mogłaby się uruchomić Twoja aplikacja. Do tego potrzebujesz kopii roboczej.
Kopia robocza, czyli tam i z powrotem
Żeby stworzyć katalog, z którego można uruchomić aplikację, po prostu sklonuj repozytorium (na serwerze):
user@megiteam:~$ git clone $HOME/repo/moja-aplikacja.git moja-aplikacja
Teraz w podkatalogu $HOME/moja-aplikacja dysponujesz identycznym repozytorium, jak w $HOME/repo/moja-aplikacja.git. Różni się jedynie tym, że katalog zawiera cały Twój projekt, a dane z repozytorium leżą w podkatalogu .git.
Ten drugi raz
Zmiany, które wprowadzisz w lokalnym repozytorium i opublikujesz, nie trafią automatycznie do kopii roboczej na serwerze. Żeby weszły w życie, musisz ją samodzielnie zaktualizować (i zapewne uruchomić aplikację ponownie):
user@megiteam:~/moja-aplikacja$ git pull
user@megiteam:~/moja-aplikacja$ restart-app nazwa-aplikacji
Takie zachowanie może być pożądane (jeżeli nad projektem pracuje więcej osób, mogą użyć repozytorium na serwerze do współpracy) lub nie (jeżeli współpraca jest rozwiązywana w inny sposób, a w tym repozytorium znajduje się zawsze najnowsza wersja produkcyjna).
Szczypta automatyzacji
Jeżeli chcesz, żeby Twoja kopia robocza była zawsze aktualna w stosunku do głównego repozytorium, zastąp (w głównym repozytorium) plik hooks/post-update treścią zbliżoną do poniższej:
#!/bin/sh unset GIT_DIR cd ~/moja-aplikacja git pull restart-app nazwa-aplikacji
i nadaj mu prawo do wykonywania (chmod +x post-update)
I po co to było?
Być może zastanawiasz się, po co ta kombinacja z trzema repozytoriami. Czy nie wystarczyłoby założyć ~/repo/moja-aplikacja.git bez opcji --bare a później zrobić tam git checkout? Otóż nie, a objawy mogą być na pierwszy rzut oka mylące ("zrobiłem git push i nie widzę zmian, zepsuło się"). Zmiany jak najbardziej zostałyby w repozytorium zapisane, ale nie wpłynęłoby to nijak na zawartość katalogu ~/repo/moja-aplikacja.git (zmieniłaby się tylko zawartość jego podkatalogu .git). Jest to sytuacja analogiczna jak z trzema repozytoriami i można ją identycznie rozwiązać za pomocą post-update hooka, natomiast autorzy gita uznali, że dość już nieporozumień z tym związanych i w przyszłych wersjach nie będzie możliwe opublikowanie zmian do repozytorium, które zawiera katalog roboczy (w pewnym uproszczeniu). Dlatego lepiej już teraz się przyzwyczaić żeby uniknąć nieprzyjemnej niespodzianki w przyszłości.
Dodał: Grzegorz Nosek
Tagi: git