pl  |  en

Żeby było git

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

  • przemo_li

    Jak wpleść w to githuba?
    Lokalny komp
    git push — wysyła na github
    magiczna_komenda — wysyła na wasz serwer (git push megiteam ???)

    Wasz serwer
    restart -app nazwa_aplikacji

  • przemo_li

    Jak wpleść w to githuba?
    Lokalny komp
    git push — wysyła na github
    magiczna_komenda — wysyła na wasz serwer (git push megiteam ???)

    Wasz serwer
    restart -app nazwa_aplikacji

  • gnosek

    @przemo_li:

    Sklonowałeś swój projekt z githuba i chcesz go uruchomić na megiteam? No to tak:
    1. Na swoim koncie na megiteam załóż nowe puste repo (git init)
    2. Lokalnie dodaj nowego remote’a (git remote add megiteam ssh://user@user.megiteam.pl/sciezka.do/repo)
    3. Wyłącz ostrzeżenie od gita o pchaniu do bieżącej gałęzi i przy okazji skonfiguruj restart aplikacji po deployu*

    git config receive.denyCurrentBranch ignore
    cat > .git/hooks/post-receive << EOF
    #!/bin/sh

    export GIT_DIR=.git
    git checkout -f

    restart-app nazwa_aplikacji
    EOF
    chmod +x .git/hooks/post-receive

    (piszę w locie więc uważaj na literówki)

    4. Wepchnij zmiany (git push megiteam master:refs/heads/master bodajże; kolejne pushe nie będą wymagały podania gałęzi)
    5. Napisz gdzie się pomyliłem i co nie robi 😉

    * disclaimer: różne są zdania na temat czy tak jest ładnie, ale jak zapewnisz spójność repo i katalogu roboczego (chociażby tym checkoutem w post-receive) to nic nie powinno wybuchnąć.

  • gnosek

    @przemo_li:

    Sklonowałeś swój projekt z githuba i chcesz go uruchomić na megiteam? No to tak:
    1. Na swoim koncie na megiteam załóż nowe puste repo (git init)
    2. Lokalnie dodaj nowego remote’a (git remote add megiteam ssh://user@user.megiteam.pl/sciezka.do/repo)
    3. Wyłącz ostrzeżenie od gita o pchaniu do bieżącej gałęzi i przy okazji skonfiguruj restart aplikacji po deployu*

    git config receive.denyCurrentBranch ignore
    cat > .git/hooks/post-receive << EOF
    #!/bin/sh

    export GIT_DIR=.git
    git checkout -f

    restart-app nazwa_aplikacji
    EOF
    chmod +x .git/hooks/post-receive

    (piszę w locie więc uważaj na literówki)

    4. Wepchnij zmiany (git push megiteam master:refs/heads/master bodajże; kolejne pushe nie będą wymagały podania gałęzi)
    5. Napisz gdzie się pomyliłem i co nie robi 😉

    * disclaimer: różne są zdania na temat czy tak jest ładnie, ale jak zapewnisz spójność repo i katalogu roboczego (chociażby tym checkoutem w post-receive) to nic nie powinno wybuchnąć.

  • Działa bosko. Tutaj tak ładnie jest opisany git w przykładzie dla zupełnych lamerów jak jak (przynajmnie jak byłem 🙂

    https://railstutorial.org/book?version=2.3#sec:version_control.

    Pytanie. Jak szybko przenieść repo z svn? Wiem, że jest takie narzędzie w gicie. Chce się pozbyć tech wstrętnych .svn raz na zawsze 🙂

  • Działa bosko. Tutaj tak ładnie jest opisany git w przykładzie dla zupełnych lamerów jak jak (przynajmnie jak byłem 🙂

    https://railstutorial.org/book?version=2.3#sec:version_control.

    Pytanie. Jak szybko przenieść repo z svn? Wiem, że jest takie narzędzie w gicie. Chce się pozbyć tech wstrętnych .svn raz na zawsze 🙂

  • gnosek
  • gnosek
  • gnosek
  • RR

    Tutaj jest opis jak postawić GIT korzystając z chmury Amazon, a dokładnie usługi CodeCommit.

    https://blog.projekty-informatyczne.pl/blog/2016/06/26/hosting-git-amazon-codecommit/