-
1. ZaÄetek
- 1.1 O nadzoru razliÄic
- 1.2 Kratka zgodovina Gita
- 1.3 Kaj je Git?
- 1.4 Ukazna vrstica
- 1.5 Namestitev Gita
- 1.6 Prva nastavitev Gita
- 1.7 Pridobivanje pomoÄi
- 1.8 Povzetek
-
2. Osnove Git
- 2.1 Pridobivanje repozitorija Git
- 2.2 Snemanje sprememb v repozitorij
- 2.3 Pregled zgodovine potrditev
- 2.4 Razveljavljanje stvari
- 2.5 Delo z daljavami
- 2.6 OznaÄevanje
- 2.7 Aliasi Git
- 2.8 Povzetek
-
3. Veje Git
- 3.1 Veje na kratko
- 3.2 Osnove vej in združevanja
- 3.3 Upravljanje vej
- 3.4 Poteki dela z vejami
- 3.5 Oddaljene veje
- 3.6 Ponovno baziranje
- 3.7 Povzetek
-
4. Git na strežniku
- 4.1 Protokoli
- 4.2 Pridobitev Gita na strežniku
- 4.3 Generiranje vaÅ”ih javnih kljuÄev SSH
- 4.4 Nastavitev strežnika
- 4.5 Prikriti proces Git
- 4.6 Pametni HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Možnosti gostovanja pri tretjih ponudnikih
- 4.10 Povzetek
-
5. Porazdeljeni Git
- 5.1 Porazdeljeni poteki dela
- 5.2 Prispevek k projektu
- 5.3 Vzdrževanje projekta
- 5.4 Povzetek
-
6. GitHub
-
7. Orodja Git
- 7.1 Izbira revizije
- 7.2 Interaktivno pripravljanje
- 7.3 Shranjevanje na varno (angl. stashing) in ÄiÅ”Äenje
- 7.4 Podpisovanje vaŔega dela
- 7.5 Iskanje
- 7.6 Prepisovanje zgodovine
- 7.7 Demistifikacija ponastavitve
- 7.8 Napredno združevanje
- 7.9 Rerere
- 7.10 RazhroÅ”Äevanje z Gitom
- 7.11 Podmoduli
- 7.12 Povezovanje v pakete
- 7.13 Zamenjava
- 7.14 Shramba poverilnic
- 7.15 Povzetek
-
8. Prilagoditev Gita
- 8.1 Konfiguracija Git
- 8.2 Atributi Git
- 8.3 Kljuke Git
- 8.4 Primer pravilnika, ki ga uveljavlja Git
- 8.5 Povzetek
-
9. Git in ostali sistemi
- 9.1 Git kot odjemalec
- 9.2 Migracija na Git
- 9.3 Povzetek
-
10. Notranjost Gita
- 10.1 Napeljava in keramika
- 10.2 Objekti Git
- 10.3 Reference Git
- 10.4 Packfiles (datoteke zmanjŔanih podatkov)
- 10.5 Refspec
- 10.6 Protokoli prenosa
- 10.7 Vzdrževanje in obnovitev podatkov
- 10.8 Spremenljivke okolja
- 10.9 Povzetek
-
A1. Dodatek A: Git v drugih okoljih
- A1.1 GrafiÄni vmesniki
- A1.2 Git v Visual Studio
- A1.3 Git v Visual Studio Code
- A1.4 Git v IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git v Sublime Text
- A1.6 Git v Bashu
- A1.7 Git v Zsh
- A1.8 Git v Powershellu
- A1.9 Povzetek
-
A2. Dodatek B: Vdelava Gita v vaŔo aplikacijo
- A2.1 Git v ukazni vrstici
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Dodatek C: Ukazi Git
- A3.1 Nastavitev in konfiguracija
- A3.2 Pridobivanje in ustvarjanje projektov
- A3.3 Osnove posnetkov
- A3.4 Veje in združevanje
- A3.5 Deljenje in posodabljanje projektov
- A3.6 Pregled in primerjava
- A3.7 RazhroÅ”Äevanje
- A3.8 Popravljanje
- A3.9 E-poŔta
- A3.10 Zunanji sistemi
- A3.11 Administracija
- A3.12 Orodja za sisteme napeljave
7.7 Orodja Git - Demistifikacija ponastavitve
Demistifikacija ponastavitve
Preden se premaknemo na bolj specializirana orodja, se pogovorimo o Gitovih ukazih reset
in checkout
.
Ta ukaza sta ena izmed najbolj zmedenih delov Gita, ko se z njima prviÄ sreÄate.
Naredita toliko stvari, da se zdi obupno poskusiti jih dejansko razumeti in pravilno uporabiti.
Za to priporoÄamo preprosto metaforo.
Tri drevesa
Lažji naÄin razmiÅ”ljanja o reset
in checkout
je skozi mentalni okvir Gita kot vsebinskega upravitelja treh razliÄnih dreves.
S pojmom »drevo« tukaj dejansko mislimo na »zbirko datotek«, ne nujno na podatkovno strukturo.
Obstajajo nekateri primeri, kjer indeks ne deluje toÄno kot drevo, vendar je za naÅ”e namene za zdaj lažje razmiÅ”ljati o njem na ta naÄin.
Git v svojem normalnem delovanju kot sistem upravlja in manipulira s tremi drevesi:
Drevo | Vloga |
---|---|
HEAD |
Zadnji posnetek potrditve, naslednja nadrejena |
Indeks |
Predlagan posnetek naslednje potrditve |
Delovni direktorij |
Peskovnik |
HEAD
HEAD je kazalec na trenutno vejno referenco, ki pa je sama po sebi kazalec na zadnjo potrditev, narejeno na tej veji. To pomeni, da bo HEAD nadrejeni naslednje ustvarjene potrditve. Na sploŔno je najpreprosteje razmiŔljati o HEAD-u kot o posnetku vaŔe zadnje potrditve na tej veji.
Dejansko je precej enostavno videti, kako je ta posnetek videti. Tukaj je primer pridobivanja dejanskega seznama direktorijev in kontrolnih vsot SHA-1 za vsako datoteko v posnetku HEAD:
$ git cat-file -p HEAD
tree cfda3bf379e4f8dba8717dee55aab78aef7f4daf
author Scott Chacon 1301511835 -0700
committer Scott Chacon 1301511835 -0700
initial commit
$ git ls-tree -r HEAD
100644 blob a906cb2a4a904a152... README
100644 blob 8f94139338f9404f2... Rakefile
040000 tree 99f1a6d12cb4b6f19... lib
Gitova ukaza cat-file
in ls-tree
sta ukaza Ā»napeljaveĀ«, ki se uporabljata za stvari nižje ravni in nista resniÄno uporabljena v vsakodnevnem delu, vendar nam pa pomagata videti, kaj se dogaja tukaj.
Indeks
Indeks je vaŔa naslednja predlagana potrditev.
To zasnovo smo oznaÄevali tudi kot Gitovo Ā»podroÄje pripraveĀ«, saj si ga Git ogleda, ko zaženete ukaz git commit
.
Git napolni ta indeks s seznamom vsebine datotek, ki so bile nazadnje izvleÄene v vaÅ” delovni direktorij, in kako so bile videti, ko so bile prvotno izvleÄene.
Nato nekatere od teh datotek nadomestite z novimi razliÄicami in git commit
to pretvori v drevo za novo potrditev.
$ git ls-files -s
100644 a906cb2a4a904a152e80877d4088654daad0c859 0 README
100644 8f94139338f9404f26296befa88755fc2598c289 0 Rakefile
100644 47c6340d6459e05787f644c2447d2595f5d3a54b 0 lib/simplegit.rb
Tukaj ponovno uporabljamo git ls-files
, ki je bolj ukaz v zakulisju in vam prikaže, kako je trenutno videti vaŔ indeks.
Indeks tehniÄno gledano ni drevesna strukturaāāādejansko je implementiran kot sploÅ”Äen manifestāāāvendar za naÅ”e namene je dovolj blizu.
Delovni direktorij
Nazadnje imate vaŔ delovni direktorij (ki se pogosto imenuje tudi »delovno drevo«).
Drugi dve drevesi shranjujeta svojo vsebino na uÄinkovit, vendar nepraktiÄen naÄin v direktoriju .git
.
Delovni direktorij jih razpakira v dejanske datoteke, kar vam omogoÄa lažje urejanje.
Delovni direktorij si lahko predstavljate kot peskovnik, kjer lahko preizkusite spremembe, preden jih potrdite v podroÄje priprave (indeks) in nato v zgodovino.
$ tree
.
āāā README
āāā Rakefile
āāā lib
āāā simplegit.rb
1 directory, 3 files
Potek dela
ObiÄajni naÄin dela z Gitom je zabeležiti posnetke vaÅ”ega projekta v zaporedno boljÅ”a stanja z manipulacijo teh treh dreves.

Predstavljajmo si ta proces: recimo, da vstopite v nov direktorij, ki vsebuje eno samo datoteko.
To imenujemo v1 datoteke in jo bomo oznaÄili z modro barvo.
Sedaj zaženemo git init
, kar bo ustvarilo repozitorij Git z referenco glave (HEAD), ki kaže na nerojeno vejo master
.

V tem trenutku ima vsebino le drevo delovnega direktorija.
Zdaj želimo potrditi to datoteko, zato uporabimo git add
, da vsebino v delovnem direktoriju kopiramo v indeks.

git add
kopira datoteko v indeksNato zaženemo git commit
, ki sprejme vsebino indeksa in jo shrani kot trajni posnetek, ustvari objekt potrditve, ki kaže na ta posnetek, in posodobi master
, da kaže na to potrditev.

git commit
Äe zaženemo git status
, ne bomo videli sprememb, saj so vsa tri drevesa enaka.
Sedaj želimo spremeniti to datoteko in jo potrditi. Gremo skozi enak postopek; najprej spremenimo datoteko v svojem delovnem direktoriju. Imenujmo jo v2 datoteke in jo oznaÄimo z rdeÄo barvo.

Äe zdaj zaženemo git status
, bomo videli datoteko v rdeÄi barvi z napisom Ā»Changes not staged for commitĀ«, ker se ta vnos razlikuje med indeksom in delovnim direktorijem.
Nato zaženemo git add
, da jo damo v podroÄje priprave (v naÅ” indeks).

Äe zaženemo git status
, bomo trenutno videli datoteko v zeleni barvi pod Ā»Changes to be committedĀ«, ker se indeks in HEAD razlikujetaāāāto pomeni, da se naÅ”a naslednja predlagana potrditev razlikuje od naÅ”e zadnje potrditve.
Na koncu zaženemo git commit
, da zakljuÄimo potrjevanje.

git commit
s spremenjeno datotekoZdaj nam git status
ne bo dal nobenega izpisa, saj so vsa tri drevesa spet enaka.
Preklapljanje vej in kloniranje gresta skozi podoben proces. Ko preklopite na vejo, se spremeni HEAD, da kaže na novo referenco veje, vaŔ indeks se napolni s posnetkom te potrditve, nato pa se vsebina indeksa kopira v vaŔ delovni direktorij.
Vloga ponastavitve
Ukaz reset
ima veÄ smisla, Äe ga gledamo v tem kontekstu.
Za namene teh primerov recimo, da smo spet spremenili datoteko file.txt
in jo tretjiÄ potrdili.
Tako je sedaj videti naŔa zgodovina:

Sedaj si poglejmo, kaj reset
toÄno naredi, ko ga pokliÄemo.
Neposredno spreminja ta tri drevesa na preprost in predvidljiv naÄin.
Izvede do tri osnovne operacije.
1. korak: Premikanje HEAD
Prva stvar, ki jo reset
naredi, je premik tistega, na kar kaže HEAD.
To ni enako spreminjanju samega HEAD (to naredi ukaz checkout
); reset
premakne vejo, na katero kaže HEAD.
To pomeni, da Äe je HEAD nastavljen na vejo master
(torej se trenutno nahajate na veji master
), bo izvajanje ukaza git reset 9e5e6a4
najprej spremenilo master
, da kaže na 9e5e6a4
.

Ne glede na to, katero obliko reset
z doloÄeno potrditvijo uporabite, je to prva stvar, ki jo bo vedno poskusil narediti.
Z uporabo reset --soft
se bo postopek tam preprosto ustavil.
Sedaj si vzemite trenutek in si oglejte ta diagram ter ugotovite, kaj se je zgodilo: v bistvu se je preklical zadnji ukaz git commit
.
Ko zaženete git commit
, Git ustvari novo potrditev in nanjo premakne vejo, na katero kaže HEAD.
Ko se z ukazom reset
vrnete na HEAD~
(na nadrejeno od HEAD
), premaknete vejo nazaj na prejŔnje mesto, pri tem pa ne spremenite indeksa ali delovnega direktorija.
Sedaj lahko posodobite indeks in znova zaženete git commit
, da dosežete to, kar bi naredil git commit --amend
(glejte Spreminjanje zadnje potrditve).
2. korak: Posodobitev indeksa (--mixed
)
Opazite lahko, da boste z zagonom ukaza git status
sedaj videli v zeleni barvi razliko med indeksom in tem, kam kaže novi HEAD.
Naslednja stvar, ki jo bo reset
naredil, je posodobitev indeksa z vsebino posnetka, na katerega sedaj kaže HEAD.

Äe doloÄite možnost --mixed
, se bo postopek ukaza reset
ustavil na tem koraku.
To je tudi privzeta možnost, zato Äe ne navedete nobene možnosti (v tem primeru le git reset HEAD~
), se bo ukaz konÄal tukaj.
Sedaj si vzemite Ŕe eno sekundo, da si ogledate ta diagram in ugotovite, kaj se je zgodilo: Ŕe vedno ste preklicali zadnji ukaz commit
, vendar ste tudi premaknili vse spremembe iz indeksa v delovni direktorij.
Vrnili ste se na stanje pred zagonom ukazov git add
in git commit
.
3. korak: Posodobitev delovnega direktorija (--hard
)
Tretja stvar, ki jo bo reset
naredil, je, da bo delovni direktorij videti tako kot indeks.
Äe uporabite možnost --hard
, se bo nadaljeval na tej stopnji.

Razmislimo o tem, kaj se je pravkar zgodilo.
Preklicali ste zadnjo potrditev, ukaza git add
in git commit
ter vso delo, ki ste ga opravili v svojem delovnem direktoriju.
Pomembno je opozoriti, da je ta zastavica (--hard
) edini naÄin, da je ukaz reset
nevaren, in eden izmed zelo redkih primerov, ko Git dejansko uniÄi podatke.
Katerakoli drugaÄna uporaba ukaza reset
se lahko precej enostavno razveljavi, ne pa možnost --hard
, saj silovito prepiŔe datoteke v delovnem direktoriju.
V tem posebnem primeru imamo Å”e vedno razliÄico v3 naÅ”e datoteke v potrditvi v naÅ”i bazi podatkov Git in jo lahko dobimo nazaj s pogledom v naÅ” reflog, vendar bi jo Git Å”e vedno prepisal, Äe je ne bi potrdili, in postala bi nepopravljivo izgubljena.
Povzetek
Ukaz reset
prepisuje ta tri drevesa v doloÄenem vrstnem redu in se ustavi, ko mu to sporoÄite:
-
Premakne vejo, na katero kaže HEAD (ustavi se tu, Äe je izbrana možnost
--soft
). -
Posodobi indeks, da ustreza trenutnemu stanju HEAD-a (ustavi se tu, razen Äe je izbrana možnost
--hard
). -
Posodobi delovni direktorij tako, da ustreza indeksu.
Ponastavitev s potjo
To zajema obnaŔanje ukaza reset
v njegovi osnovni obliki, vendar pa mu lahko podate tudi pot, na kateri naj deluje.
Äe navedete pot, bo reset
preskoÄil korak 1 in omejil preostanek svojih dejanj na doloÄeno datoteko ali niz datotek.
To dejansko ima smiselāāāHEAD je le kazalec in ne morete kazati na del ene potrditve in del druge.
Vendar pa se lahko indeks in delovno okolje delno posodobita, zato reset
nadaljuje s korakoma 2 in 3.
Zato predpostavimo, da zaženemo git reset file.txt
.
Ta oblika (ker niste navedli SHA-1 ali veje in niste navedli --soft
ali --hard
) je kratka oblika git reset --mixed HEAD file.txt
, ki bo:
-
Premaknila vejo, na katero kaže HEAD (preskoÄeno).
-
Naredi, da indeks izgleda kot HEAD (ustavi se tukaj).
Tako preprosto kopira file.txt
iz HEAD-a v indeks.

To ima praktiÄni uÄinek dajanja datoteke izven podroÄja priprave.
Äe si ogledamo diagram za ta ukaz in razmislimo o tem, kaj naredi git add
, sta si natanÄno nasprotna.

To je razlog, zakaj nam izhod ukaza git status
predlaga, naj za preklic dajanja datoteke v podroÄje priprave uporabimo ta ukaz (za veÄ informacij glejte razdelek Povrnitev datoteke iz podroÄja priprave).
Enako lahko dosežemo tudi tako, da Gitu ne dovolimo, da smo mislili Ā»povleci podatke iz HEADĀ«, tako da navedemo specifiÄno potrditev, od koder želimo povleÄi datoteko.
Tako bi lahko zagnali nekaj podobnega git reset eb43bf file.txt
.

To dejansko naredi enako, kot Äe bi v delovnem direktoriju vsebino datoteke pripeljali nazaj na v1, na njej uporabili git add
in jo nato spet vrnili na v3 (ne da bi dejansko Ŕli skozi vse te korake).
Äe zdaj poženemo git commit
, bo zabeležil spremembo, ki vrne datoteko nazaj na v1, Äeprav je dejansko nikoli nismo imeli v svojem delovnem direktoriju.
Zanimivo je tudi omeniti, da kot pri git add
, lahko tudi ukaz reset
sprejme možnost --patch
, da premakne vsebine iz podroÄja priprave po kosih.
Tako lahko izbirate katero vsebino želite pustiti izven podroÄja priprave, ali jo obrniti.
Stiskanje skupaj
Poglejmo, kako lahko s tem novo pridobljenim orodjem naredimo nekaj zanimivegaāāāstisnemo potrdive skupaj (angl. squashing).
Recimo, da imate vrsto potrditev s sporoÄili, kot so Ā»ups.Ā«, Ā»WIPĀ« in Ā»forgot this fileĀ«.
Uporabite lahko reset
, da jih hitro in enostavno združite v eno samo potrditev, kar vas bo naredilo pametnejŔega.
V razdelku Stiskanje potrditev skupaj je prikazan Å”e en naÄin, kako to storiti, vendar bo v tem primeru lažje uporabiti reset
.
Recimo, da imate projekt, kjer prva potrditev vsebuje eno datoteko, druga pa je dodala novo datoteko in spremenila prvo, tretja potrditev pa je ponovno spremenila prvo datoteko. Druga potrditev je bilo delo v napredku in ga želite stisniti skupaj.

Za premikanje glavne veje na starejŔo potrditev (zadnjo potrditev, ki jo želite obdržati), lahko zaženete ukaz git reset --soft HEAD~2
:

In nato enostavno ponovno poženete git commit
:

Sedaj lahko vidite, da vaŔa dosegljiva zgodovina, zgodovina, ki bi jo potisnili, zdaj kaže, kot da imate eno potrditev s file-a.txt
v1, nato drugo, ki je spremenila file-a.txt
na v3 in dodala file-b.txt
.
Potrditve z razliÄico datoteke v2 ni veÄ v zgodovini.
IzvleÄenje
KonÄno se morda spraÅ”ujete, kakÅ”na je razlika med ukazoma checkout
in reset
.
Podobno kot reset
, checkout
manipulira s tremi drevesi, in je nekoliko drugaÄen glede na to, ali mu podate pot do datoteke ali ne.
Brez poti
Izvedba git checkout [branch]
je precej podobna izvedbi git reset --hard [branch]
, saj posodobi vsa tri drevesa tako, da so videti kot [branch]
, vendar obstajata dve pomembni razliki.
PrviÄ, glede na reset --hard
je checkout
varnejŔi glede delovnega direktorija; preveri, da ne briŔe datotek, ki so že spremenjene.
Pravzaprav je malce pametnejÅ”i od tegaāāāposkuÅ”a narediti trivialno združevanje v delovnem direktoriju, zato bodo vse datoteke, ki jih niste spremenili, posodobljene.
reset --hard
pa preprosto nadomesti vse preko celega nabora brez preverjanja.
Druga pomembna razlika je, kako checkout
posodobi HEAD.
Kjer reset
premakne vejo, na katero kaže HEAD, checkout
premakne sam HEAD, da kaže na drugo vejo.
Na primer, recimo, da imamo veji master
in develop
, ki kažeta na razliÄni potrditvi, in smo trenutno na veji develop
(tako da kaže HEAD nanjo).
Äe izvedemo git reset master
, se bo develop
sama premaknila na isto potrditev kot master
.
Äe pa izvedemo git checkout master
, se develop
ne premakne, premakne se sam HEAD.
HEAD bo sedaj kazal na master
.
V obeh primerih premikamo HEAD, da kaže na potrditev A, vendar je naÄin, kako to storimo, zelo drugaÄen.
reset
premakne vejo, na katero kaže HEAD, checkout
pa premakne sam HEAD.

git checkout
in git reset
S potmi
Drugi naÄin izvedbe ukaza checkout
je s potjo do datoteke, kar, tako kot pri reset
, ne premakne HEAD-a.
Gre za isto kot git reset [branch] file
, saj posodobi indeks z datoteko v tej potrditvi in prepiŔe datoteko v delovnem direktoriju.
Gre za popolnoma enako reÄ, kot je git reset --hard [branch] file
(Äe bi lahko to izvedli z reset
)āāāni varno za delovni direktorij in ne premakne HEAD-a.
Podobno kot pri git reset
in git add
, tudi checkout
sprejme možnost --patch
, s katero lahko izberete, katere vsebine datoteke želite selektivno povrniti po koÅ”Äkih.
Povzetek
Upamo, da zdaj razumete ukaz reset
in se z njim poÄutite bolj domaÄe, vendar ste pa verjetno Å”e vedno malo zmedeni glede tega, kako se toÄno razlikuje od checkout
in si ne morete zapomniti vseh pravil za razliÄne klice.
Tu je plonk listek za ukaze, ki vplivajo na drevesa.
Stolpec HEAD
prebere REF
, Äe ta ukaz premakne referenco (vejo), na katero kaže HEAD, in HEAD
, Äe premakne sam HEAD.
Posebno pozornost posvetite stolpcu Ā»Varno za delovni direktorij?Ā«āāāÄe piÅ”e NE, premislite Å”e enkrat, preden zaženete ta ukaz.
HEAD | Indeks | Delovni direktorij | Varno za delovni direktorij? | |
---|---|---|---|---|
Nivo potrditve |
||||
|
REF |
NE |
NE |
DA |
|
REF |
DA |
NE |
DA |
|
REF |
DA |
DA |
NE |
|
HEAD |
DA |
DA |
DA |
Nivo datoteke |
||||
|
NE |
DA |
NE |
DA |
|
NE |
DA |
DA |
NE |