Git cookbook

News Site news RSS

Latest articles New articles RSS

Latest news from Twitter Follow Secretkeeper4 and www.svesoftware.com on Twitter

Git cookbook

1. Inicijalizacija repozitorija


1) # mkdir lgit
2) # cd lgit
3) # git init
4) # git remote add origin https://nezic@bitbucket.org/nezic/lgit.git

Želimo li inicijalizirati "bare" repozitorij, koristimo naredbu:

5) # git init --bare

"Bare" repozitorij ne sadrži radnu kopiju, samo povijest promjena koda, pa stoga služi samo za dijeljenje koda.

2. Dodavanje datoteka (staging)

Kreirajmo novi source file u folderu 'lgit':

6) # echo "print 'Hello.'" > hello.py

 
Pogledajmo izlaz naredbe 'git status':

7) # git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# hello.py
nothing added to commit but untracked files present (use "git add" to track)

Dodajmo 'hello.py' u slijedeći 'commit':

8) # git add hello.py

Ukoliko smo zabunom dodali datoteku 'hello.py' te je želimo ukloniti s diska i iz promjena namijenjenih 'commitu':

9) # git rm --cached hello.py

Kreirajmo ponovno datoteku 'hello.py', naredbom 6).
Ako želimo obrisati datoteku iz radnog repozitorija koja nije dodana u 'stage' za slijedeći commit, upotrijebiti ćemo sljedeće naredbe:

10) # git clean -n
Would remove hello.py

Opcija '-n' označava dry run. Ukoliko stvarno želimo ukloniti datoteku, koristiti ćemo opciju '-f':

11) # git clean -f
Removing hello.py

Ponovimo naredbe 6) i 8) kako bi opet dodali datoteku hello.py u 'stage' za sljedeći 'commit'.
Nakon toga izvršimo commit naredbu:

12) # git commit -m "Prvi commit"
[master (root-commit) ba5360f] Prvi commit
1 file changed, 1 insertion(+)
create mode 100644 hello.py

Potom možemo napraviti 'push' promjena na remote repozitorij. Remote repozitorij se zove 'origin', a glavni 'branch' master.

13) # git push origin master

Pogledajmo nakon izvršene naredbe status radnog direktorija:

14) # git status
# On branch master nothing to commit, working directory clean

3. Brisanje promjena

Git omogućuje dvije naredbe za brisanje commit-ova:
 - git reset
 - git revert
Osnovna razlika između ove dvije komande je ta što je naredba 'revert' sigurnija, jer se prilikom brisanja kreira
novi commit u kojemu su obrisane promjene, a naredba 'reset' u cijelosti uklanja 'commit'. To je problem ukoliko korisnik ukloni commit
na osnovu kojega neki drugi korisnik bazira svoje promjene. Nije preporučljivo koristiti 'reset' naredbu na već commitanim promjenama stavljenima na dijeljeni repozitorij.
Git omogućuje i brisanje commitova koji se nalaze na remote repozitoriju, ali ovu temu nećemo obrađivati. Bitno je znati da je i to moguće, ali opasno.

3a. Scenariji korištenja - 'git reset'

a) Želimo napraviti 'unstage', ali bez da obrišemo datoteku s diska
Kreirajmo datoteku i dodajmo u 'stage'.

15) # echo "print 'Reset me.'" > reset.py
16) # git add reset.py 17) # git status

Uklonimo datoteku iz 'stagea':

18) # git reset HEAD reset.py

b) Želimo sve promjene vratiti na posljednji 'commit'

19) # git reset HEAD --hard

c) Želimo ukloniti commit koji smo učinili u radnoj kopiji, te nije još na dijeljenom repozitoriju
Izvršimo naredbu 'reflog':

20) # git reflog

Odaberimo 'commit' na koji želimo vratiti stanje radne kopije:

21) # git reset ba5360f

3b. Scenariji korištenja - 'git revert'

a) Želimo poništiti nevaljani commit
Kreirajmo datoteku i napravimo push na remote repozitorij.

22) # echo "print 'Helllllo.'" > hello.py
23) # git add hello.py
24) # git commit -m "Commit s tipfelerom"
25) # echo "print 'This is ok.'" > ok.py
26) # git add ok.py
27) # git commit -m "Commit koji je ispravan"
28) # git push origin master

Primjetimo da smo učinili pogrešku i želimo je ponišiti.
Upotrijebimo naredbu 'log' ili 'reflog':

29) # git log
commit afe3f5c6bb961ac41e438abbab98023436127887
Author: dnezic <drazen.nezic@svesoftware.com>
Date: Sun Sep 22 14:38:34 2013 +0200
Commit koji je ispravan

commit b8405e1b2c8f8b878a38a49a1d5bce6f63080ee8
Author: dnezic <drazen.nezic@svesoftware.com>
Date: Sun Sep 22 14:38:17 2013 +0200
Commit s tipfelerom

Ili naredbom 'reflog':

30) # git reflog
afe3f5c HEAD@{0}: commit: Commit koji je ispravan
b8405e1 HEAD@{1}: commit (initial): Commit s tipfelerom

Učinimo 'revert':

31) # git revert b8405e1
32) # git log
commit 5bd8a527e43e78aed58b3f3b489bb2f62be2b4a9
Author: dnezic <drazen.nezic@svesoftware.com>
Date: Sun Sep 22 14:41:38 2013 +0200
Revert "Commit s tipfelerom"
This reverts commit b8405e1b2c8f8b878a38a49a1d5bce6f63080ee8.

commit afe3f5c6bb961ac41e438abbab98023436127887
Author: dnezic <drazen.nezic@svesoftware.com>
Date: Sun Sep 22 14:38:34 2013 +0200
Commit koji je ispravan

commit b8405e1b2c8f8b878a38a49a1d5bce6f63080ee8
Author: dnezic <drazen.nezic@svesoftware.com>
Date: Sun Sep 22 14:38:17 2013 +0200
Commit s tipfelerom

Pošaljimo promjene na remote repozitorij:

33) # git push origin master

4. Branches

Ukoliko želimo saznati u kojem se trenutno branchu nalazimo upotrijebiti ćemo naredbu 'branch'

34) # git branch

Lokalne i remote brancheve dohvatiti ćemo opcijom 'branch -a'

35) # git branch -a * master remotes/origin/master

Kreirajmo novi lokalni branch 'feature':

36) # git branch feature

Premjestimo se u novi branch naredbom 'checkout'.

37) # git checkout feature

ili jednom naredbom:

38) # git checkout -b feature

provjerimo u kojem smo sada branchu:

39) # git branch * feature master

5. Checkout

Naredba 'checkout' omogućuje da se prebacujemo iz brancha u branch ili na neki 'commit' kako bi vidjeli što se u njemu nalazi.
Kada koristimo naredbu u ovom obliku:

40) # git checkout <commit>

naša radna kopija naći će se u stanju 'detached HEAD'. U ovom stanju ne bi se smjelo ništa novo commitati ili napraviti push na remote repozitorij.
Preporučljivo je napraviti novi branch.
Ukoliko želimo dohvatiti neku datoteku iz nekog drugog commita i dodati je u 'stage' našeg brancha 'feature':

41) # git checkout <commit> file

Ukoliko se datoteka istog imena već nalazi u 'stage' fazi radne kopije brancha 'feature' biti će prepisana.

6. Rebase

Napravili smo branch 'feature', a potom smo u branchu 'master' kreirali neke promjene i commitali.

42) # git checkout master
43) # echo "Master change" > master.txt
44) # git add master.txt
45) # git commit -m "Dodan master.txt"

Na isti način kreirajmo i commitajmo datoteku 'feature.txt' u feature branch.
Sada želimo sve promjene iz master brancha koje su učinjene dok smo radili na feature branchu povući.
To ćemo najlakše napraviti opcijom 'rebase'.

46) # git rebase master
First, rewinding head to replay your work on top of it...
Applying: feature

 
U slučaju da je došlo do konflikta, potrebno je iste razriješiti. U tom slučaju radi se 3-way marge.

47) # git mergetool

Ukoliko ima još konflikata, idemo na slijedeći konflikt:

49) # git rebase --continue

Ukoliko nema više konflikata, možemo obrisati .orig datoteke:

50) # git clean -f
51) # git commit -m "My work in branch"

Ako želimo napraviti push na remote repozitorij, moramo povući promjene s --rebase opcijom

52) # git pull --rebase origin feature
53) # git push origin feature

7. Amend commit

Ovu se naredbu može koristiti na lokalnoj radnoj kopiji.
Ukoliko smo zaboravili dodati u 'stage' datoteku, a napravili smo commit, onda možemo napraviti ispravak na slijedeći način:

51) # git add hello.py
52) # git commit

Zaboravili smo dodati main.py

53) # git add main.py
54) # git commit --amend --no-edit

8. Switch to remote branch

54) # git fetch origin remote-branch-name:local-branch-name
55) # git checkout local-branch-name
Brisanje remote brancha
56) # git push origin :<branch>

9. Čišćenje

57) # git gc --prune=now