Kwestia synchronizacji plików na serwerze www z lokalnym repozytorium Git’a była dla mnie problemem od kiedy rozpocząłem pracę z tym systemem kontroli wersji. Jak wiadomo prace związane z webdevelopmentem zdecydowanie łatwiej jest wykonywać na serwerze szczególnie w fazie nanoszenia poprawek na działającej już stronie.

Kopiowanie zmodyfikowanych plików po każdej naniesionej zmianie to zadanie dość czasochłonne i poziom irytacji tym procesem wzrasta wraz z ilością plików, które należy przenieść a następnie wysłać na repozytorium nie zapominając przy tym o opisaniu zmian itd.

Podejmowałem wiele prób rozwiązania tego problemu poprzez zamontowanie serwera FTP jako dysku w systemie OS X za pomocą aplikacji Transmit a następnie synchronizacji Forklift’em ale niestety częste utraty połączenia skutecznie utrudniały ten proces. Dodatkowo każdorazowo niezbędne było otworzenie okna terminala lub aplikacji GitHub’a i zrobienie commit’a na repozytorium więc nie oszczędzało to zbyt wiele czasu (naprawdę łatwo też pomylić wtedy kierunek synchronizacji co bywa tragiczne w skutkach…).

Rsync

Ostatecznym i najlepszych rozwiązaniem okazało się skorzystanie z protokołu synchronizacji Rsync, który w OS X jako systemie UNIX’owym dostępny jest bez żadnych dodatkowych instalacji. Jeśli połączymy funkcjonalność rsync z SSH oraz komendami Git’a w łatwy sposób możemy stworzyć skrypt, który zsynchronziuje pliki z serwerem, następnie doda pliki do repozytorium i wykona operację commit oraz push. Całość rozwiązania ogranicza się właściwie do 6-7 linii kodu.

Jak działa Rsync?

Polecenie rsync w moim przypadku wygląda następująco:

rsync -avz -e ssh login@serwer.com:public_html/katalog/do/synchronizacji ścieżka/lokalna/repozytorium/git

Rozpoczynamy od komendy rsync z następującymi modyfikatorami :

  • -a – skrót od archive; oznacza, że pliki będą kopiowane wraz z podkatalogami (rekursywnie) i zachowaniem wszelkich uprawnień, czasów, symbolicznych linków itd. Odsyłam do dokładnej dokumentacji tutaj
  • -v – skrót od verbose, który pozwala na pokazanie nazw plików podczas synchronizacji
  • -z – aby kompresować dane podczas transmisji
  • -e – określa, że pliki będą synchronizowane ze zdalnym serwerem
  • –delete – opcja, której ja akurat nie potrzebowałem ale może być przydatna – dodanie tego modyfikatora usunie pliki lokalnie, których nie będzie na serwerze (rzadko spotykany przypadek i raczej niezalecane w fazie testów :)

Kolejnym krokiem jest podanie źródła plików do synchronizacji czyli połączenie SSH. Z uwagi na fakt, że SSH skonfigurowałem tak, że hasło nie jest wymagane wystarczy jedynie podać login i adres serwera wraz z lokalizacją katalogu, który zamierzamy synchronizować:

ssh login@serwer.com:public_html/katalog/do/synchronizacji

Ostatnim parametrem jest już tylko lokalna ścieżka do repozytorium Git’a :

ścieżka/lokalna/repozytorium/git

Po wykonaniu tej operacji powinniśmy zobaczyć listing plików które aktualnie są pobierane z serwera i porównywane, dlatego też zdecydowanie warto skorzystać z kompresji danych. Sam proces jest zdecydowanie szybszy niż przesyłanie danych poprzez FTP, nie wspominając już nawet o fakcie, że nie wymaga skakania po katalogach w celu znalezienia zmodyfikowanych plików.

Rsync + Git

Git CLI listing

Jeśli korzystasz z synchronizacji w celu naniesienia zmian na repozytorium pomocne będą także następujące komendy, które do minimum ograniczą Twój wkład w cały ten proces:

#!/bin/bash 
cd "ścieżka/lokalna/repozytorium/git"
git checkout master
sleep 5s
rsync -avz -e ssh login@serwer.com:public_html/katalog/do/synchronizacji ścieżka/lokalna/repozytorium/git
git add .
git commit -a
git push

A teraz po kolei :

  • cd „ścieżka/lokalna/repozytorium/git” – przechodzimy lokalnie do katalogu repozytorum
  • git checkout master – wybieramy branch, w moim przypadku master
  • sleep 5s – dodajemy pięć sekund opóźnienia aby mieć pewność, że pliki odświeżyły się lokalnie – przydatne jeśli posiadasz więcej niż jeden branch
  • rsync -avz -e ssh login@serwer.com:public_html/katalog/do/synchronizacji ścieżka/lokalna/repozytorium/git – przeprowadzamy synchronizację plików z serwerem poprzez połączenie SSH
  • git add . – dodajemy zmiany do repozytorium
  • git commit -a – commit’ujemy zmiany
  • git push – wykonujemy push do repozytorium

Celowo nie korzystam z polecenia git commit -m aby nie definiować, krótkiej wiadomości do commit’a. Wykonanie polecenia bez parametru -m pozwoli na otworzenie domyślnego edytora (vim,nano) i wpisanie wiadomości dotyczącej naniesionych zmian. Pierwsza linia to zawsze nagłówek a każda kolejna wyląduje w polu description.

Skopiowanie powyższego kodu do pliku z rozszerzeniem .sh stworzy skrypt, który przeprowadzi synchronizację plików bezpośrednio z okna Terminala – pozostaje jeszcze jedynie przypiąć skrót klawiszowy do uruchamiania tego procesu i zapomnieć o czasach gdy praca z repozytorium była pracochłonna.

Zdjęcie w nagłówki pochodzi z świetnego projektu o nazwie FRAME

w dniu .

Back to top