Zastosowanie git do rozwoju NuWro

Czym jest Git?

Szybki start

Wstępna konfiguracja

Na każdym komputerze gdzie używamy gita należy skonfigrować swoje dane:
git config --global user.name "Cezary Juszczak"		# imię i nazwisko
git config --global user.email cjusz@ift.uni.wroc.pl	# adres e-mail
Można też zdefiniować programy pomocnicze:
git config --global core.editor mcedit   # edytor do redagowanie opisów wersji
git config --global merge.tool meld	 # program do rozwiązywania konfliktów
Te informacje wprowadzamy tylko raz i są zapamiętywane w pliku $HOME/.gitconfig:

$HOME/.gitconfig

[user] name = Cezary Juszczak email = cjusz@ift.uni.wroc.pl [core] editor = mcedit [merge] tool = meld
Można je też zweryfikować za pomocą polecenia:

git config --list

user.name=Cezary Juszczak user.email=cjusz@ift.uni.wroc.pl core.editor=mcedit merge.tool=meld

Inicjalizuj puste repozytorium

mkdir projekt			# Utwórz now katalog
cd projekt			# i wejdż do niego
git init			# Utwórz w nim puste repozytorium
Repozytorium jest tworzone w katalogu projekt/.git

Stwórz repozytorium dla swojego projektu

cd projekt			# i wejdż do niego
git init			# Utwórz w nim puste repozytorium
git add .                       # Dodaj bieżący katalog z całą zawartością do 'przechowalni'
git commit -m 'Wersja 0'	# Wykonaj pierwszy zapis do repozytorium

Dołącz do pracy nad projektem

git clone "url do repozytorium" folder	# Wykonaj kopię repozytorium w folderze
cd folder				# Zacznij pracę nad projektem

Typowe użycie w NuWro

git clone git@borg.ift.uni.wroc.pl:nuwro  # pobierz z serwera najnowszą wersję nuwro wraz z całym repozytorium
cd nuwro/src				  # wejdź do folderu ze źródłami

geany 					  # Edytuj piki 
make					  # kompiluj
bin/nuwro				  # i testuj	

git commit -a -m 'Opis zmian'		  # zapisz zmiany w lokalnym repozytorium
git push				  # wyślij zmiany na serwer	
Istotne jest, że git push może być bardzo odsunięte w czasie.

Jeśli nie ma dostępu do sieci można przez długi czas pracować na lokalnym repozytorium, wykonując do niego kolejne zapisy.

Jeśli jednak w międzyczasie na serwerze pojawią się nowe wersje to git push się nie powiedzie. Należy wtedy wykonać:

git pull		# pobierz z serwera najnowsze poprawki i połącz automatycznie z własnymi
git push		# wyślij połącznoną wersję na serwer
Jeśli mamy już sklonowane repozytorium nuwro wystarczy:
cd nuwro			          # wejdź do folderu nuwro 
git pull			          # aktualizuj 
#Edytuj piki i testuj 
git commit -a -m 'Opis zmian'		  # zatwierdź zmiany
git push				  # wyślij poprawki na serwer
Historię zmian można śledzić poleceniem
git log

git log

commit f40de2d788b42dd2b277c4a034cc38434ee44d06 Author: Cezary Juszczak Date: Fri Mar 22 17:29:50 2013 +0100 Simpler intranuclear cascade initialization. commit 5e6e62f4459501de36129162d2f6f39b45a99961 Author: Cezary Juszczak Date: Thu Mar 21 14:01:11 2013 +0100 Some cleanups. commit 628611551717fded3579de2e495c67d70d88320e Author: Cezary Juszczak Date: Thu Mar 21 12:00:53 2013 +0100 empty isotope bug removed; mec will not happen on Hydrogen anymore commit ac26ff4d5cce10dfbf983746129fb5e9507d62b5 Author: Cezary Juszczak Date: Tue Feb 19 10:38:56 2013 +0100 save_test_events=2 saves test events with nonzero weight to weighted.eventsout.root commit f4f3974d39d9079ef2c72c9631becce98abf08d0 Author: Cezary Juszczak Date: Sun Feb 17 16:21:28 2013 +0100 param.h: more informative input error messages ....

git log --pretty=oneline

f40de2d788b42dd2b277c4a034cc38434ee44d06 Simpler intranuclear cascade initialization. 5e6e62f4459501de36129162d2f6f39b45a99961 Some cleanups. 628611551717fded3579de2e495c67d70d88320e empty isotope bug removed; mec will not happen on Hydrogen anymore ac26ff4d5cce10dfbf983746129fb5e9507d62b5 save_test_events=2 saves test events with nonzero weight to weighted.eventsout. f4f3974d39d9079ef2c72c9631becce98abf08d0 param.h: more informative input error messages 386ec9401267969b9752bdbc1f5e388995ca445e new parameter save_test_events=1 causes test events to be stored as weighted.ev 069cc61655ceb49e712c6fc288a11c4103ec2d91 Enable multichannel analysis for miniboone. 876fd3e5767f5b34f0d61ad7b8046371f84745bd Miniboone analyser fixes 92ab1aade7513cda4ff60087a0bed5a8b01fefec mec: improved interpolation in Nieves model 7891fbb8743d1c809a9e12d97616db2a8a290826 Merge branch 'master' of borg.ift.uni.wroc.pl:nuwro 0491fe0d1f8b1c2f00d4c8dd51c501672c3b85c9 user_events must be 0 most of the time 4d132f93cf3619f4fa1a3f105dc32455aa2d0eb7 mec: fixed defaults 747ea8111b47ab351f424fba5bb190104f8743ce mec: fixed defaults 726f2a3e74b082cecb4d8c8cd9f37a838ce0d2c3 Merge branch 'JZ' 0a7577efe9f12ede6ce0be2b4ca5809930e51387 mec: Nieves model implemented by J. Zmuda 72ce0f175efd4cd9d98f20c722b6903084f348ff params.xml validation implemented. 39d54a618736a263320b9540d124a4a5cefe9859 Merge branch 'master' of git@borg.ift.uni.wroc.pl:nuwro 2148ba9f23ed341e351668a8d15d351578810896 Analyser rewrite. a79a2c3061e642218fb1f1c70dc759e31d81945a MEC flag update correction and destructor for kaskada class added. b95ece902c9f4e31a6b1cf6c8f581939d727a6d1 MEC for neutral current ac82749c810f972bfdbc23837fdfe323a709fabd Merge branch 'master' of borg.ift.uni.wroc.pl:nuwro 4b897a17a8a3556e00417c7311722d8e56033ae2 correction of nucleons energy from MEC conservation in cascade .....
lub w trybie graficznym za pomocą programu gitk. Nie jest to tego potrzebny dostęp do serwera.
 gitk

Uzyskiwanie pomocy

Jeśli kiedykolwiek będziesz potrzebować pomocy podczas pracy z Git, istnieją trzy sposoby wyświetlenia strony podręcznika dla każdego z poleceń Git:
git help 
git  --help
man git-

Filozofia git-a

Repozytorium gita jest podobne do dużej ilości zzipowanych wersji programu. Każde polecenie git commit zapisuje taka nową wersję automatycznie nadając jej unikalny 40 znakowy identyfikator. Odbywa się to jednak w sposób bardzo efektywny. Pliki np. które się nie zmieniły nie są zapisywane ponownie. W rzeczywistości rozmiar repozytorium .git jest z reguły dużo mniejszy niż rozmiar równoważnego repozytorium svn.

Jeśli chcemy przejść do konkretnej wersji piszemy

git checkout wersja
powrót do najnowszej wersji wykonujemy tak:
git checkout master
Każda wersja zawiera wskaźnik na wersję poprzednią.

HEAD jest referencją do rewizji (wersji) nad którą pracujęmy (jest ona aktualnie rozzipakowana w katalogu roboczym). master wskazuje na koniec głównej gałąź czyli szczyt pnia (w svn trunk).

Praca z plikami

git status

# On branch master # Changes not staged for commit: # (use "git add ..." to update what will be committed) # (use "git checkout -- ..." to discard changes in working directory) # # modified: src/Nieves_MEC_CC_C12.h # modified: src/mecevent_Nieves.cc # # Untracked files: # (use "git add ..." to include in what will be committed) # # wyk1-600 # wyk1mc-600 # wyk2-600 no changes added to commit (use "git add" and/or "git commit -a")

Cztery "rodzaje" stany plików

Jak zmienić stan pliku?

untracked (poza repozytorium)
git add 'plik'↓↑ git rm --cached 'plik'
unmodified (nie zmieniony)
Edycja↓↑ git checkout -- 'plik'
modified (zmieniony)
git add 'plik'↓↑ git reset HEAD 'plik'
staged (w poczekalni)
git commit↓↑
unmodified (zmiany zarejestrowane w nowej wersji)

Cofanie zmian

Poprawka do ostatniej rewizji

Jeden z częstych przypadków to zbyt pochopne wykonanie rewizji i pominięcie w niej części plików, lub też pomyłka w notce do zmian. Jeśli chcesz poprawić wcześniejszą, błędną rewizję, wystarczy uruchomić git commit raz jeszcze, tym razem, z opcją --amend (popraw):
git commit --amend
Czas na przykład. Zatwierdziłeś zmiany a następnie zdałeś sobie sprawę, że zapomniałeś dodać do poczekalni pliku, który chciałeś oryginalnie umieścić w wykonanej rewizji. Wystarczy, że wykonasz następujące polecenie:
git commit -m 'initial commit'
git add forgotten_file
git commit --amend 
Wszystkie trzy polecenia zakończą się jedną rewizją - druga operacja commit zastąpi wynik pierwszej.

Porównanie z svn

W svn każda rewizja wykonana przez svn commit jest od razu wysyłana na serwer. Nie istniaje możliwość cofnięcia lub poprawy wysłanej rewizji.

Usuwanie pliku z poczekalni

Jeśli pochopnie dodałeś plik do poczekalni (plik jest zmieniony, ale jeszcze nie nadajes się do publikacji) możesz go stamtąd usinąć poleceniem:
git reset HEAD 'plik'
Zmiany wprowadzone w pliku nie zostaną stracone (plik na dysku nie zmieni się), tylko nie będą opublikowane przy najbliżym git commit.

Nadpisanie pliku poprzednią wersją

Jeśli zmiany wprowadzone w pliku nam się nie podobają (np. skasowaliśmy całą zawartość pliku) możemy przywróć wersję z bieżącej rewizji (HEAD) za pomocą polecenia:
git checkout -- 'plik'

.gitignore - Ignorancja jest siłą

W każdym folderze projektu można stworzyć plik .gitignore określający jakie pliki mają być ignorowane przez polecenia git status oraz git commit

nuwro/.gitignore

*.root *.txt random_seed nuwro.geany

nuwro/src/.gitignore

*.o *.d event1dict.*

nuwro/bin/.gitignore

# Ignore everything in this directory * # Except this file
To bardzo wygodne ponieważ nie ma konieczności czyszczenia folderów make clean przed wykonaniem git commit. W svn było to niemożliwe. Brak 'poczekalni' w svn powodował również, że svn commit rejestrował wszystkie zmiany wprowadzane w folderze a nie tylko te, które dojrzały do publikacji.

Tagowanie (etykietowanie)

Pokaż etykiety:

git tag

nuwro11c nuwro11d nuwro11e nuwro11f nuwro11g nuwro11h nuwro11i nuwro11j nuwro11k
Tworzenie i usuwanie etykiet:
git tag nuwro11l			# Dodaj etykietę nuwro11l
git tag -d nuwro11l			# Usuń etykietę nuwro11l
git tag nuwro11l -m 'wersja nuwro11l'	# Dodaj etykietę z opisem 
Można ich używać zamiast sztucznie wygenerowanych identyfikatorów. Aby przesłać etykietę nuwro11k do głownego repozyrotium:
git push origin nuwro11k
Aby przesłać wszystkie etykiety do głównego repozytorium należy:
git push --tags
W git etykiety nie zajmują praktycznie miejsca, podczas gdy w svn są to wersje repozytorium znajdujące się w folderze tags.

Chomikowanie - mój przyjaciel Staś

Jeśli twoje zmiany nie dojrzały jeszcze do publikacji (git commit) a chcesz być na bieżąco ze zmianami wprowadzanymy przez innych to:
git stash		# zapamiętaj zmiany plików w schowku
git pull		# pobierz newe wersje plików z serwera
git stash apply		# nanieś moje porawki na nową wersje plików

Gałęzie

Pojęcie gałęzi służy do tego by w jednym repozytorum można było przechowywać różne warianty projektu. Tak więc w dowolnej rewizji można wyprowadzić nową gałąź . Gałęzie (branch) to specyficzne etykiety, które wskazują na wersje, które nia mają jeszcze. W momencie gdy dla rewizji które przesuwają się tak, by zawsze wskazywać na najnowaszą wersje (Głowę). Jest tylko
git branch testing	# utwórz gałąź testing
git checkout testing	# przejdź do gałęzi testing
edit files
git commit -a -m 'Nowa wersja testowa' # zapisz nową wersje w gałęzi testing
git checkout master 	# powrót do pnia
edit files
git commit -a -m 'Nowa wersja stabilna' # zapisz nową wersję 
git merge testing	# dołącz poprawkę z gałezi testing do pnia
git branch -d test	# usuń zbędną już etykietę (gałąź) testing 

Praca na wielu gałęziach

git branch iss53	# Utwórz gałąź iss53
edit files
git commit -a -m 'Nowa wersja iss53' # zapisz nową wersję 
git checkout -b hotfix master 	  # wróć do pnia tworząc nową gałąź i uczyń ją aktywną
edit files
git commit -a -m 'nagła poprawka' # zapisz nową wersję 
git checkout master	# wróć do pnia
git merge hotfix	# dołącz  hotfix do pnia
git branch -d hotfix	# usuń gałąź hotfix
git merge iss53
Zostatanie wyszukany wsþólny przodek wersji C4 i C5 (jest nim C2) i one będzie punktem wyjścia przy scalaniu.
Po scaleniu pojawia się nowa wersja C6 która ma dwóch przodków:

Praca ze zdalnym repozytorium

Zdalne repozytorium musi być zainicjoane jako 'gołe' tzn bez plików roboczych.
git init --bare
ponieważ tylko do takich repozytoriów można pchać (git push) zmiany wykonywane w repozotoriach lokalnych. Komenda git clone automatycznie zapisuje w kopii adres kopiowanego repozytorium pod nazwą origin. Można jednak określić dowolną liczbę zdalnych repozytoriów.
git remote add pb git://github.com/paulboone/ticgit.git

git remote -v

origin git@borg.ift.uni.wroc.pl:nuwro (fetch) origin git@borg.ift.uni.wroc.pl:nuwro (push)
Domyślnie przyjmowany jest protokół ssh tak więc można mieć repozytorium na serwerze instytutowym
ssh borg.ift.uni.wroc.pl
mkdir repo.git
cd repo.git 
git init --bare
exit
a łączyć się z nim z jednego lub więcej komputerów
git clone borg.ift.uni.wroc.pl:repo
cd repo 
...
git commit
git push
Jesli repozytorium ma być widoczne publicznie można je udostępnić za pomocą protokołu git (skomplikowane) lub (http) prostsze lub skopiować na github.com (najłatwiejsze ale wymaga dodatkowych uaktualnienić git push ...)

fetch i pull

Należy zauważy że git fetch aktualizuje nasze kokalne repozytorium ale nie zmienia plików roboczych (Nie przesuwa HEAD) natomiast git pull jest skrótem od dwóch poleceń
git fetch		# aktualizuj repozyturium
git merge origin master	# scal