# Praca z GIT
Dokumentacja sprządzona dnia 22 sierpna 2018
Modyfikacja: 06 sierpień 2019
Autor: Michał Bahn
Wersja 1.2
Do poprawy:
Do uzupełnienia:
---
* [Konfiguracja i dostosowanie](#Konfiguracja-i-dostosowanie)
* [Aliasy](#Aliasy)
* [Ładne logi](#Ładne-logi)
* [Zbiór różnych trików z GIT-em](#Zbiór-różnych-trików-z-GITem)
* [Operacje na historii](#Operacje-na-historii)
* [Ograniczanie historii](#Ograniczanie-historii)
* [Pobieranie płytkiego clona](#Pobieranie-płytkiego-clona)
* [Łączenie branchy](#Łączenie-branchy)
* [Merge squash](#Merge-squash)
* [Rebase](#Rebase)
* [Paczka z ostanimi modyfikacjami](#Przygotowanie-paczki-z-ostanimi-zmianami)
Konfiguracja i dostosowanie
---
### Aliasy
Aby uprościć wpisywanie komend można skorzystać z aliasów. Są to skróty jake chcemy przyspisać zadanym komendom.
```
git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.br branch
```
Niezłym pomysłem może być stworznei aliasu do listowania utworzonych aliasów. Wywołamy go komendą `gt alias`.
```
git config --global alias.alias "! git config --get-regexp ^alias\. | sed -e s/^alias\.// -e s/\ /\ =\ /"
```
### Ładne logi
Git nie zawsze w sposób czytelny prezentuje prezentuje logi. Można temu zaradzić definiujac formatowanie logów.
```shell
git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
```
Co więcej można to ustawienie wprowadzić na stałe tworząc wpis w pliku konfiguracynym. Możana to zrobić automatycznie używjac komendy:
```shell
git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"
```
Teraz można komendą `git lg` lub ` git lg -p` wyświetlić w sposób ładnie sformatowany historię dotychczasowych komitów wraz ze zmianami.
### Zabezpieczenie katalogu repozytorium
Bardzo ważne by katalog repozytorium nie był dostępny z zewnątrz. Sprawdzamy to wywpłując w przegladarce `moja_domena.pl/.git` oraz (nie lub) `moja_domena.pl/.git/config` oraz `moje_ip/.git` oraz `moje_ip/.git/config` . We wszytkich przypadkach powinniśmy otrzymać komunikat `Forbidden`. Jeśl nie, należy dodatkowo zabepieczyć katalogi wpisując w konfiguracje apache, lub lokalny .htaccess, następujacy fragment:
```
<DirectoryMatch "^/.*/\.git/">
Require all denied
</DirectoryMatch>
```
:::info
Dodatkowo warto zabepieczyć serwer przed listowaniem katalogów. Parz "Zbiór dobrych praktyk" sekcja "Zabezpieczenie katalogu" w szczegółności kod dotyczący listowania katalogów, wykorzystujaca dyrektywę `Options` z parametrem `-Indexes`:
https://hackmd.io/m-GyoFnOTEmqwmpDMljTyQ?view#Zabezpieczenie-katalogu
:::
Używane branche
---
W projektach używamy następujecego zestawu branchy:
* master
* hot-fix
* release
* develop
* features
* staging
**master** - wersja produkcyjna kodu. Branch ten powienien być 1:1 z wersją na serwerze produkcyjnym.
**hot-fix** - branch pozwaljacy na nanoszenie szybkich poprawek na produkcję i do wyrównywania stanów na branchu developerskim.
**release** - branch przygotowujący nowe wydanie, z tego branch są tworzone nowe merge dla master i staging.
**develop** - podstawowy branch developerski. Można doń mergować lokalne/indywidualne branche członków zespołu.
**features** - nieformalna nazwa dla zbioru baranchy indywidualnych lub rozwijających określoną funkcjonalność.
**staging** - branch powstajacy z barancha develop lub release dla potrzeb testów na serwerze stagingowym.
:::success
Szczegóły practy z repozytorium opisane w tym dokumencie:
https://docs.google.com/presentation/d/1w2Nm3t1LfWtf6LknKB9RUewokAtXxpQulUpF0PuiRys/edit?usp=sharing
:::
Zbiór różnych trików z GITem
---
https://github.com/git-tips/tips
Operacje na historii
---
### Ograniczanie historii
Gdy istnieje potrzba odfiltorwania histori tylko do ostatnich commitów. Podając po myśłniku liczbę, określasz ile commitów wstecz ma być wyświetlane.
```
git lg -2
```
lub
```
git log -2
```
### Pobieranie płytkiego clona
Gdy zależy ci na płytkim clonie bez kompletnej historii możesz instrukcję klonowania rozszerzyć o parametr `--depth`. Parametr ten ogranicza pobranie historii do `n` commitów wstecz. Im większa liczba tym większa/dłuższa będzie historia.
```bash=
git clone --depth=2
```
Jeśli chcesz lokalnie obciąć historię już istniejacego projektu możesz zastosować parametr `--depth` dla konendy `ferch`.
```bash=
git fetch --depth=2
```
Łączenie branchy
---
Różne sposoby mergowania prac w róznych branchach.
### Merge squash
Pobiera do `master` zmiany z `features` ==nie pobierając historii==, a jedynie wstawiajac pliki do indexu kolejki. Fajne i przydatne ale nie utrzymuje zgodności hash commitów z innymi branchami. Zmianę musisz ostatecznie zacommitować.
````bash=
git co master
git merge --squash features
````
Możesz tego użyć np. gdy na niezależnym tymczasowym branchu prowadzisz zmiany, czesto commitujesz poprawki, komentarze commitów się powtarzają, prcujesz nad jedną funkcjonalnością. Na koniec chcesz wpiąć zmiany do głównego brancha i opisać je jednym commitem, nie bacząc na dalszy los tymczasowego.
#### Rebase
Opcja `-i` wymusza tryb interaktywny w którym decydujesz o zamianach. Najsprostrzą metodą jest rebase do jendego hash commitów poprzedzajacych.
```bash=
git lg
git rebase -i <that_commit_id>
```
Pojawi się okienko edycji z listą commitów w kolejnosci odwrotnej do historii powstawania. Najnowszy na dole listy, najstarszy u gówry. Przykładowo:
> pick 89731fb Add folder for app
pick cef3286 Disallow inexed working directories by googlebot and other
pick bc0a877 Minor fixes for README file
pick 218b5d4 To jest nanjnowsza poprawka
>Rebase eb5619c..218b5d4 onto eb5619c (4 commands)
> Commands:
p, pick = use commit
r, reword = use commit, but edit the commit message
e, edit = use commit, but stop for amending
s, squash = use commit, but meld into previous commit
f, fixup = like "squash", but discard this commit's log message
x, exec = run command (the rest of the line) using shell
d, drop = remove commit
>These lines can be re-ordered; they are executed from top to bottom.
If you remove a line here THAT COMMIT WILL BE LOST.
However, if you remove everything, the rebase will be aborted.
Note that empty commits are commented out
Jak sugeruje podpowiedź, mamy kilka opcji komend do wyboru:
* p, pick = utrzymuje commit
* r, reword = zmienia komentarz commita
* e, edit = use commit, but stop for amending
* s, squash = łączy commit z wcześniejszym (u góry) nadając swoją nazwę
* f, fixup = łączy commit z wcześniejszym, zostawiajac nazwę wcześniejszego
* d, drop = usuwa commit
Zmieniamy w naszej liscie commitów wyraz `pick` na `fixup`, lub gdy chemy zachować nazwę komentarza użyjemy `squash`. Zapisujemy zmianę `Ctr+o` i zamykamy dialog `ctrl+z`. Po tej operacji następuje rebase commitów i historia zawiera połączone zmiany.
Przygotowanie paczki z ostanimi zmianami
---
Jeśli chcemy wykonać paczkę z ostaniego commitu możemy użyć genialnego polecenia ktore przygotuje wyfiltrowane zmiany, zachowując całą strukturę katalogów potrzbna do wgrania zdmian w deploymentach ręcznych.
```bash=
git archive -o "_Paczka_$(date '+%F').zip" HEAD $(git diff --name-only HEAD^)
```
lub
```bash=
git archive -o "_Paczka_$(date '+%F').zip" HEAD $(git diff --name-only [nr_rewizji])
```
gdze `[nr_rewizji]` pozycujmey z `git lg`.