Git
Chapters ▾ 2nd Edition

8.1 Prilagođavanje Gita - Konfiguracija Gita

Dosad smo prešli osnove Gita i kako se on koristi, a zatim smo se upoznali sa velikim brojem alata koje nudi Git koji omogućavaju jednostavno i efikasno korišćenje. U ovom poglavlju ćemo videti kako možete da prilagodite Git svojim potrebama, tako što ćete podesiti nekoliko važnih stavki u konfiguracionim podešavanjima i huk sistemima. Pomoću ovih alata, lako je podesiti da Git radi baš onakako kako vi, vaša kompanija ili vaša grupa to želi.

Konfiguracija Gita

Kao što ste nakratko videli u Početak, možete specificirati konfigruaciona podešavanja Gita komandom git config. Jedna od prvih stvari koje ste podesili su bili vaše ime i mejl adresa:

$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com

Sada ćete naučiti još nekoliko zanimljivih opcija koje možete podesiti na ovaj način kako biste prilagodili Git svojim potrebama.

Prvo, kratak rezime: Git koristi niz konfiguracionih datoteka kojim određuje nepodrazumevana podešavanja koja ste mu nametnuli. Prvo mesto na kome Git traži ove vrednosti su u datoteci /etc/gitconfig, koja sadrži vrednosti za svakog korisnika na sistemu i za sve njihove repozitorijume. Ako komandi git config prosledite opciju --system, Git će vršiti upis i čitanje iz ove datoteke.

Sledeće mesto gde Git gleda je datoteka ~/.gitconfig (ili ~/.config/git/config), koja je posebna za svakog korisnika. Možete primorati Git da čita i piše odavde prosleđivanjem opcije --global.

I na kraju, Git gleda konfiguracione vrednosti u konfiguracionoj datoteci u Git direktorijumu (.git/config) onog repozitorijuma koji trenutno koristite. Ove vrednosti su specifične samo za taj jedan repozitorijum.

Svaki od ovih "nivoa" (sistemski, globalni, lokalni) piše preko vrednosti iz prethodnog nivoa, što znači da će, na primer, vrednosti u .git/config adutirati one iz /etc/gitconfig.

Note

Gitove konfiguracione datoteke se čuvaju kao običan tekst, što znači da sve vrednosti možete podesiti i ručno izmenom datoteke, vodeći računa o tome da sintaksa bude ispravna. Ipak, češće je jednostavnije pokrenuti komandu git config.

Osnovna konfiguracija klijenta

Konfiguracione opcije koje Git porepoznaje se mogu svrstati u dve kategorije: klijentske i serverske. Većina opcija je na strani klijenta — konfiguracija ličnih radnih podešavanja. Podržano je mnogo, mnogo konfiguracionih opcija, ali veliki deo njih je korisno samo u određenim krajnjim slučajevima. Ovde ćemo pokriti samo one najčešće i najkorisnije. Ako želite da pogledatu listu svih opcija koje vaša verzija Gita podržava, možete da pokrenete sledeću komandu.

$ man git-config

Ova komanda će izlistati sve dostupne opcije, i to dosta detaljno. Ovaj materijal možete naći i na http://git-scm.com/docs/git-config.html.

core.editor

Po podrazumevanim podešavanjima, Git koristi štagod mu postavite kao podrazumevani tekst editor ($VISUAL ili $EDITOR), a inače koristi editor vi za kreiranje i izmenu komit i tag poruka. Da promenite to podrazumevano podešavanje na nešto drugo, možete da promenite podešavanje core.editor:

$ git config --global core.editor emacs

Sada, štagod da je podešeno kao podrazumevani editor u šelu, Git će pokrenuti Emacs za izmenu poruka.

commit.template

Ako podesite ovo kao putanju do datoteke na svom sistemu, Git će koristiti to kao podrazumevanu poruku kada komitujete. Na primer, recimo da napravite šablon u datoteci ~/gitmessage.txt koji izgleda ovako:

subject line

what happened

[ticket: X]

Kako biste rekli Gitu da treba da koristi ovo kao podrazumevanu poruku koja se pojavljuje u editoru kada pokrenete git commit, treba da podesite konfiguracioni vrednost commit.template:

$ git config --global commit.template ~/.gitmessage.txt
$ git commit

Sada će vaš editor otvoriti nešto ovako kada uradite komit:

subject line

what happened

[ticket: X]
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
# modified:   lib/test.rb
#
~
~
".git/COMMIT_EDITMSG" 14L, 297C

Ako vaš tim ima polisu o formatu komit poruka, postavljanje šablona za tu polisu na sistemu i konfiguracija Gita da ga uvek koristi kao podrazumevanu poruku može pomoći da povećate šanse da se ta polisa poštuje redovnije.

core.pager

Ovo podešavanje određuje koji pejdžer se koristi kada it straniči izlaze kao što su log i diff. Možete da ga podesite more ili na vaš omiljeni pejdžer (podrazumevano je less), ili ga možete isključiti tako što ćete ga pdoesiti na prazan string:

$ git config --global core.pager ''

Ako uradite to, Git će celu stranicu odštampati izjedna na izlazu, ma koliko ona duga bila.

user.signingkey

Ako pravite potpisane označene tagove (kojima smo se bavili u Signing Your Work), postavka GPG ključa za potpisivanje kao podešavanje u konfiguraciji će učiniti proces mnogo jednostavnijim. Podesite svoj ključ ID na sledeći način:

$ git config --global user.signingkey <gpg-key-id>

Sada možete da potpišete tagove ne specificirajući ključ svaki pot pomoću komande git tag:

$ git tag -s <tag-name>

core.excludesfile

Možete staviti obrasce u datoteci .gitignore u svom projektu kako ih Git ne bi video kao nepraćene fajlove i kako ne bi probao da ih doda na stejdž kada pokrenete git add and njima, kao što smo videli u Ignorisanje fajlova.

Ali nekad želite da ignorišete određene datoteke za sve repozitorijume na kojima radite. Ako imate Mac OS X, verovatno znate za datoteke .DS_store. Ako koristite Emacs ili Vim, znate za imena datoteka koje se završavaju sa ~ ili .swp.

Ovo podešavanje vam omogućava da napišete neku vrstu globalne .gitignore datoteke. Ako kreirate datoteku ~/.gitignore_global sa sledećim sadržajem,

*~
.*.swp
.DS_Store

i pokrenete git config --global core.excludesfile ~/.gitignore_global, Git vam nikad više neće praviti probleme sa tim datotekama.

help.autocorrect

Ako pogrešno ukucate komandu, Git vam pokazuje nešto nalik ovome:

$ git chekcout master
git: 'chekcout' is not a git command. See 'git --help'.

Did you mean this?
    checkout

Git se trudi da vam pomogne time što pokušava da shvati koju ste komandu želeli da ukucate, ali ipak odbija da je izvrši. Ako podesite help.autocorrect na 1, Git će automatski pokrenuti ovu komandu za vas.

$ git chekcout master
WARNING: You called a Git command named 'chekcout', which does not exist.
Continuing under the assumption that you meant 'checkout'
in 0.1 seconds automatically...

Obratite pažnju na čekanje o "0.1 sekunde". help.autocorrect je zapravo prirodan broj koji predstavlja desetinke. Ako ga podesite na 50, git će vam dati pet sekundi da se predomislite pre nego što izvrši komandu koju je automatski ispravio.

Boje u Gitu

Git u potpunosti podržava obojeni izlaz terminala, što dosta pomaže u tome da vizuelno brže i lakše parsirate izlaz koji vam daje. Postoji veliki broj opcija koji će vam pomoći da podesite boje u skladu sa svojim potrebama.

color.ui

Git automatski boji većinu izlaza, ali postoji glavni prekidač koji možete iskoristiti ukoliko vam se ovaj način prikaza ne dopada. Da ugasite sav obojeni Gitov izlaz na terminalu, učinite sledeće:

$ git config --global color.ui false

Podrazumevano podešavanje je auto, i tada se izlaz boji kada se štampa direktno na terminal, ali ne sadrži kontronle kodove za boje kada se prosleđuje u datavod ili datoteku.

Možete ga namestiti i na always ako želite da ignorišete razliku između terminala i datavoda. Ovo ćete retko koristiti; u većini slučajeva, ako želite kodove za boje u preusmerenom izlazu, možete da prosledite zastavicu --color Git komandi da ga primorate da koristi i kodove za boje. Podarzumevano podešavanje je skoro uvek ono što će vam trebati.

color.*

Ako želite da bude određeniji o tome koje komande će biti obojete i kako, Git nudi posebna podešavanja za boje. Svaki od ovih se može podesiti na true, false ili always.

color.branch
color.diff
color.interactive
color.status

Sem toga, svaki od ovih ima pod-podešavanja koje možete da koristite da odredite boju za deo izlaza, ako želite da preklopite svaku boju. Na primer, da meta-informatiju u diff izlazu budu plaba slova na crnoj pozadini, boldirani, možete da pokrenete sledeće.

$ git config --global color.diff.meta "blue black bold"

Možete da podesite boju na bilo koju od sledećih vrednosti: normal, black (crna), red (crvena), green (zelena), yellow (žuta), blue (plava), magenta (jarko roze), cyan (tirkizna), ili white (bela). Ako želite da dodate i atribut kao što je bold u prethodnom primeru, možete da izaberete neki od sledećih: bold (boldirano, zadebljano), dim (mutno), ul (podvučeno), blink (treperi) i reverse (zamena boje teksta i boje pozadine).

Spoljni alati za spajanje i pregled razlika

Mada Git ima svoju unutrašnju implementaciju diff-a, koju smo dosad pokazivali u ovoj knjigi, možete da pdoesite i spoljni alat umesto njega. Možete da podesite i grafički alat za razrešenje konflikta i spajanje, umesto da ih ručno rešavate. Demonstriraćemo podešavanje Perforce Visual Merge Tool (P4Merge) za pregled razlika i rešenje konflikata, pošto je dobar graički alat i besplatan je.

Ako želite da probate ovo, P4Merge radi na svim većim platformama i trebalo bi da uspete da ga podesite. Nadalje ćemo koristiti imena putanji koji odgovaraju Meku i Liniksu; za Vindouz ćete morati da promenite /usr/local/bin u izvršnu putanju svog okruženja.

Za početak, preuzmite P4Merge sa Perforce. Zatim ćete podesiti skripte koje će delovati kao spoljni omotač pre kojih ćete pokretati komande. Koristićemo Mek putanju za izvršnu datoteku; u drugim sistemima, ona će biti tamo gde je binarna datoteka p4merge instalirana. Podesite skriptu-omotač koju možete nazvati extMerge, koja zove binarni fajl zajedno sa svim prosleđenim argumentima.

$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/p4merge.app/Contents/MacOS/p4merge $*

Omotač za pregled razlike proverava da li je prosleđeno sedam argumenata i dva od njih prosleđuje skripti za spajanje. Po podrazumevanim podešavanjima, Git prosleđuje sledeće argumente programu za pregled razlika:

path old-file old-hex old-mode new-file new-hex new-mode

Pošto vam trebaju samo argumenti old-file i new-file, koristimo skriptu-omotač da prosledimo samo one koji nam trebaju.

$ cat /usr/local/bin/extDiff
#!/bin/sh
[ $# -eq 7 ] && /usr/local/bin/extMerge "$2" "$5"

Sem toga, ovim alatima moramo i da dozvolimo pokretanje:

$ sudo chmod +x /usr/local/bin/extMerge
$ sudo chmod +x /usr/local/bin/extDiff

Sada možete podesiti konfiguracionu datoteku tako da koristi alate za rešavanje konflikta i pregled promena koje ste izabrali. Treba postaviti nekoliko podešavanja: merge.tool će reći Gitu koju strategiju da koristi, mergetool.<tool>.cmd će odrediti koja komanda treba da se pokrene, mergetool.<tool>.trustExitCode će reći Gitu da li izlazni kod iz programa govori o uspešnosti izvršenja spoja ili ne, a diff.external će reći Gitu koju komandu da pokrene za pregled promena. Dakle, možete da pokrenete četiri komande za konfgiuraciju

$ git config --global merge.tool extMerge
$ git config --global mergetool.extMerge.cmd \
  'extMerge \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"'
$ git config --global mergetool.extMerge.trustExitCode false
$ git config --global diff.external extDiff

ili da izmenite datoteku ~/.gitconfig dodavanjem sledećih linija:

[merge]
  tool = extMerge
[mergetool "extMerge"]
  cmd = extMerge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"
  trustExitCode = false
[diff]
  external = extDiff

Kada sve ovo podesite, možete da pokrenete komandu za pregled razlika ovako:

$ git diff 32d1776b1^ 32d1776b1

Umesto da dobijete izlaz razlike u komandnoj liniji, Git pokreće P4Merge, što izgleda nekako ovako.

P4Merge.
Figure 143. P4Merge.

Ako probate da spojite dve grane i kao posledicu toga imate konflikt pri spoju, možete da pokrenete komangu git mergetool; ona pokreće P4Merge i dozvoljava vam da rešite konflikt preko GUI alata.

Dobra stvar oko ovog omotača je to što lako možete da promenite laate za spajanje i pregled razlika. Na primer, ako želite da promenite alate extDiff i extMerge i postavite ih tako da pokreći KDiff3, samo treba da promenite datoteku extMerge:

$ cat /usr/local/bin/extMerge
#!/bin/sh
/Applications/kdiff3.app/Contents/MacOS/kdiff3 $*

Git će sada koristiti alat KDiff3 za pregled promena i rešavanje konflikta pri spoju.

Git dolazi sa velikim brojem već podešenih drugih alata za razrešenje konflikta za koje ne morate da podešavate konfiguraciju iz komandne linije. Da biste videli spisak alata koji su podržani, probajte ovo:

$ git mergetool --tool-help
'git mergetool --tool=<tool>' may be set to one of the following:
        emerge
        gvimdiff
        gvimdiff2
        opendiff
        p4merge
        vimdiff
        vimdiff2

The following tools are valid, but not currently available:
        araxis
        bc3
        codecompare
        deltawalker
        diffmerge
        diffuse
        ecmerge
        kdiff3
        meld
        tkdiff
        tortoisemerge
        xxdiff

Some of the tools listed above only work in a windowed
environment. If run in a terminal-only session, they will fail.

Ako ne želite da koristite KDiff3 za pregled razlika, već želite da ga koristite samo za razrešenje konflikta, a komanda kdiff3 vam je podešena u putanji, možete pokrenuti sledeće.

$ git config --global merge.tool kdiff3

Ako pokrenete ovo umesto da podešavate datoteke extMerge i extDiff, Git će koristiti KDiff3 za razrešenje konflikta, a za pregled razlika uobičajeni Gitov alat za to namenjen.

Formatiranje i znaci beline

Formatiranje i znaci beline su neki od suptilnih problema koji znaju da vam pojedu živce na koji developeri često nailazi kada sarađuju, pogotovo kada te rade svi na istoj platformi. Veoma je lako da zakrpe i druge proizvode kolaborativnog rada dovedu to neprimetnih promena u znacima beline jer ih editori uvode u tišini, i ako vam fajlovi ikad dodaktnu Vindouz, znaci za novi redovi će biti prebrisani. Git ima nekoliko konfiguracionih opcija koji mogu pomoći sa ovim problemima.

core.autocrlf

Ako programirate na Vindouzu i radite sa ljudima koji ga ne koriste (ili obrnuto), verovatno ćete u nekom trenutku naići na probleme oko novih redova. Razlog za ovo je Vindouz koji koristi dva karaktera za prelazak u novi red: CR (carriage-return) i LF (linefeed). S druge strane, Mek i Linuks sistemi koriste samo karakter LF. Ovo je mala razlika ali ume da bude izuzetno frustrirajuća prilikom kolaboracije ljudi koji imaju različite platforme; mnogi editori na Vindouzu neprimetno zamenjuju postojeće karaktere LF u CRLF.

Git ima podršku za automatsko konvertovanje karaktera CRLF u LF kada dodate fajl na stejdž, i obrnuto kada čekautujete kod na svoj datotečni sistem. Možete da uključiti ovu funkcionalnost koristeći podešavanje core.autocrlf. Ako ste na Vindouz mašini, podesite ga na true — ovo će konvertovati sve LF u CRLF kada čekautujete kod:

$ git config --global core.autocrlf true

Ako ste na Linuksu ili Meku koji koriste karakter LF za prelazak u novi red, onda ne želite da ih Git automatski konvertuje kada čekautujete datoteke; međutim, ako se slučajno nađe fajl sa karakterima CRLF za prelazak u novi red, onda biste možda želeli da ih Git automatski ispravi. Možete da kažete Gitu da konvertuje CRLF u LF kada komitujete, ali ne i obrnuto tako što ćete opciju core.autocrlf podesiti na input.

$ git config --global core.autocrlf input

S ovakvim podešavanje ćete imati CRLF prelakse u novi red na Vindouz čekautima, ali LF prelaske na Meku, Liniksu i u repozitorijumu.

Ako ste Vindouz programer koji radi na projektu koji je namenjen samo Vindouzu, možete da isključite ovu functionalnost, čuvajući CRLF završetke i na repozitorijumu, tako što ćete podesite konfiguracioni promenljivu na false:

$ git config --global core.autocrlf false

core.whitespace

Git može i da detektuje i reši neke probleme sa znacima beline. Može da nadgleda šest osnovna problema sa znacima beline — tri su podrazumevano uključena i mogu se ugasiti, a tri su podrazumevano isključena ali se mogu upaliti.

Tri koja su podrazumevano uključena su blank-at-eol, što traži beline ne kraju linije; blank-at-eof, što primećuje prazne redove na kraju fajla; i space-before-tab, što traži razmake ispred tabova na početku linije.

Tri podrazumevano isključena koja se mogu uključiti su indent-with-non-tab, koji traže linije koje počinju razmacima umesto tabocima (i kontroliše se opcijom tabwidth); tab-in-indent, koji nadgleda tabove u delu za indentaciju linije; i cr-at-eol, koje govori Gitu da je u redu da postoje CR karakteri na krajevima linija.

Možete reći Gitu koje od ovih želite da uključite tako što ćete podesiti core.whietspace na vrednosti koje želite uključene ili isključene, odvojene zarezima. Podešavanje možete isključiti ili ne navodeći ga u stringu podešavanja, ili dodavanjem znaka - ispred vrednosti. Na primer, ako želite da podesite sve osim cr-at-eol, možete uraditi sledeće:

$ git config --global core.whitespace \
    trailing-space,space-before-tab,indent-with-non-tab

Git će detektovati ove probleme kada pokrenete komandu git diff i probaće da ih oboji tako da možete da ih rešite pre nego što komitujete. Takođe će koristiti ove vrednosti da vam pomogne kada lepite zakrpe komandom git apply. Kada lepite zakrpe, možete da zamolite Git da vas upozori ako lepite zakrpe koje imaju specificirane probleme sa znacima beline.

$ git apply --whitespace=warn <patch>

Ili možete da naredite Gitu da automatski reši probleme pre nego što primeni zakrpu.

$ git apply --whitespace=fix <patch>

Ove opcije se mogu primeniti i na komandu git rebase. Ako ste napravili komit u kome postoje problemi sa znacima beline, ali još ih niste gurnuli uzvodno, možete da pokrenete git rebase --whitespace=fix i Git će automatski srediti probleme sa znacima beline kao da piše preko zakrpa.

Konfiguracija servera

Ni približno ovoliko konfiguracionih opcija postoje za serversku stranu Gita, ali ima nekoliko zanimljivig koji biste možda želeli da zapamtite.

receive.fsckObjects

Git se stara o tome da svaki objekat koji primi tokom guranja i dalje odgovara SHA-1 kontrolnoj sumi i pokazuje na validne objekte. Ipak, ovo ne radi po podrazumevanim podešavanjima; radi se o prilično skupoj operaciji, i može da uspori procese, pogotovo na velikim repozitorijuma ili pri guranju velike količine podataka. Ako želite da Git proverava konzistentnost objekata prilikom svakog guranja problema, možete ga primorati da uradi to tako što ćete podesiti receive.fsckObjects na true:

$ git config --system receive.fsckObjects true

Sada će Git proveriti integritet repozitorijuma pre nego što se svako guranje promena prihvati da bi se obezbedilo da klijtenti ne podmićuju neispravne poadtke.

receive.denyNonFastForwards

Ako rebazirate komitove koje ste već gurnuli i onda pokušate da ih opet gurnete, ili na neki drugi način pokušate da gurnete komit na udaljenu granu koja ne sadrži komit na koji trenutno pokazuje udaljena grana, ta operacija vamneće biti odobrena. Ovo je u opštem slučaju dobra polisa; ali u slučaju rebaziranja, postoje situacije kada znate šta radite i možete da primorate operaciju da bude izvršena na udaljenoj grani tako što ćete komandi za guranje proslediti zastavicu -f.

Kako biste rekli Gitu da odbija i ovakvo forisano guranje, podesite receive.denyNonFastForwards:

$ git config --system receive.denyNonFastForwards true

Drugi način na koji ovo možete uraditi na strani servera jeste pomoću hukova, što ćemo obraditi uskoro. Takav pristup vam nudi mogućnost da uradite i neke složenije stvari kao što je odbijanje komitova koji ne koriste tehniku motanja unapred za određeni podskup korisnika.

receive.denyDeletes

Jedno od zaobilaznih rešenja za polisu denyNonFastForwards je da korisnik obriše granu i onda je ponovo gurne nazad sa novom referencom. Da biste onemogućili ovo, podesite receive.denyDeletes na true.

$ git config --system receive.denyDeletes true

Ovo onemogućuje briasnje grana i tagova — nijedan korisnik ne može da uradi to. Da obrišete udaljene grane, morate da obrišete referentne datoteke iz servera manuelno. Ima i zanimljivijih načina da se ovo uradi na nivou korisnika pomoću ACL-ova, kao što ćete videti u Primer polise sprovedene od strane Gita.