Git, GitHub ja töövoog
Selles peatükis vaatame kõigepealt, mis asi on versioonihaldus, siis Git-i põhikäske ja alles pärast seda GitHubi.
Loogika
Git-i põhimõte ei ole lihtsalt "saada failid GitHubi". Loogika on tavaliselt:
- tööta lokaalselt
- salvesta muutused commit'idena
- sünkroniseeri need kaugserveriga
See on põhjus, miks Git ja GitHub tuleb lahus hoida:
- Git on lokaalne versioonihaldus
- GitHub on koht, kus seda repot jagada ja arutada
Mis on versioonihaldus
Versioonihaldus tähendab, et faili või projekti muutused talletatakse ajalooks.
Praktiline kasu on selles, et saad:
- näha, mis muutus
- minna mõttes või käsuga tagasi eelmise seisu juurde
- eristada üksteisest loogilisi muudatusi
- jagada sama projekti teistega
Ilma selle mõtteta jäävad ka Git-i käsud kergesti lihtsalt mehaaniliseks loeteluks.
Kiirspikker
git statusnäitab tööpuu seisugit addlisab muudatused stage'igit commit -m '...'teeb commit'igit pulltoob muudatusedgit pushsaadab muudatused serverisse
Kõige tavalisemad käsud alguses:
git statusgit diffgit add failgit commit -m '...'git log --oneline --graph --decorate
Käivita need käsud
mkdir -p ~/tmp/git-naide
cd ~/tmp/git-naide
git init
printf 'esimene rida\n' > naide.txt
git status
git add naide.txt
git commit -m 'Lisa naidefail'
git log --oneline
Kui repol on juba GitHubi aadress ja sa tahad selle enda masinasse tõmmata, siis tüüpiline algus on:
git clone git@github.com:kasutaja/projekt.git
cd projekt
git status
git diff
git log --oneline --graph --decorate -n 10
Kõige tavalisem töövoog
Kui töötad igapäevaselt, siis see katab suure osa vajadusest:
git status
git pull --rebase
git checkout -b parandus
tee muudatused, siis:
git diff
git add fail1 fail2
git commit -m 'Paranda näited peatükis SSH'
git push -u origin parandus
Selle loogika tugevus on:
- enne tõmbad värske seisu
- töötad eraldi harus
- vaatad muudatused üle enne commit'i
Mis on haru
haru ehk branch on eraldi töölõng sama projekti sees.
Kõige tavalisem mõtteviis on:
mainvõimasteron põhirida- väike parandus või uus mõte tehakse eraldi harus
- hiljem saab selle põhireaga ühendada
Sellepärast on käsk:
git checkout -b parandus
tegelikult kaks asja korraga:
git checkoutliigub teise haru peale-bütleb, et see haru luuakse kohe samal ajal
add, commit, pull, push omavahel
git addütleb, millised muudatused lähevad järgmisse commit'igit commitsalvestab selle loogilise muudatuse lokaalseltgit pulltoob teised muudatused sinu masinassegit pushsaadab sinu commit'id serverisse
See järjekord aitab vältida tunnet, et Git on "müstiline".
Miks git diff on üks tähtsamaid käske
Kui git status ütleb, et midagi on muutunud, siis git diff näitab, mis täpselt muutus.
See on väga oluline, sest Git-i juures ei piisa ainult teadmisest:
- "fail muutus"
Sageli on vaja näha:
- mis read muutusid
- kas muudatus on loogiline
- kas midagi läks kogemata kaasa
Hea tööharjumus on:
- tee muudatus
- vaata
git diff - alles siis tee
git add
Kõige tavalisemad diff-i kujud
Need kolm katavad suure osa igapäevavajadusest:
git diff
git diff --cached
git diff HEAD
Nende loogika on:
git diffnäitab veel stage'imata muudatusigit diff --cachednäitab seda, mis on juba stage'is ja läheks järgmisse commit'igit diff HEADnäitab kõiki muudatusi võrreldes viimase commit'iga
See on üks Git-i parimaid "aha" kohti, sest siis saad aru, et tööpuul, stage'il ja commit'il on eri roll.
Väike praktiline näide
printf 'esimene rida\n' > naide.txt
git add naide.txt
git commit -m 'Lisa naidefail'
printf 'teine rida\n' >> naide.txt
git diff
Siis näed, et git diff näitab ainult viimast muutust võrreldes viimase commit'iga.
Kui nüüd teha:
git add naide.txt
git diff --cached
siis näed juba seda versiooni, mis on valmis commit'i minema.
Kuidas muudatus tagasi võtta ilma paanikata
See on üks Git-i kõige praktilisemaid osi.
Kui tahad tööpuus oleva muudatuse tagasi võtta:
git restore naide.txt
Kui tahad faili stage'ist maha võtta, aga mitte selle sisu ära kaotada:
git restore --staged naide.txt
See tähendab:
git restore failmuudab tööpuudgit restore --staged failmuudab stage'i
Need on väga head käsud just selleks, et mitte sattuda kohe raskemate või hävitavamate käskude juurde.
.gitignore
Kõiki faile ei tasu Git-i panna.
Tüüpilised näited:
.venv/__pycache__/dist/- ajutised logifailid
Lihtne näide:
cat > .gitignore <<'EOF'
.venv/
__pycache__/
dist/
*.log
EOF
Põhimõte on:
- kui fail on genereeritud, ajutine või masinapõhine, siis ta ei peaks tavaliselt versioonihalduses olema
Kui fail on juba Git-i lisatud, siis ainult .gitignore hiljem üksi ei eemalda teda automaatselt repost.
Kuidas diff-i lugeda
Alguses piisab väga lihtsast mõtteviisist:
- rida märgiga
-tähendab eemaldatud rida - rida märgiga
+tähendab lisatud rida - ülejäänud read annavad ümbruse ehk konteksti
Näide:
-vana rida
+uus rida
veel üks uus rida
See tähendab:
- üks vana rida eemaldati
- asemele tuli uus sisu
Sa ei pea alguses kogu diff-formaati detailideni teadma. Tähtis on, et oskad enne commit'i muudatuse sisuliselt üle vaadata.
Miks see GitHubi jaoks ka tähtis on
GitHubi pull request'i keskne vaade on sisuliselt diff.
See tähendab:
- kui teed lokaalselt
git diff-i vaatamise harjumuseks - siis on ka GitHubi review palju loogilisem
Hea rusikareegel on:
- enne
git add:git diff - enne
git commit:git diff --cached - enne pull request'i: veel kord kontrolli kogu muudatust
Päris näide: väike repo nullist
Kui tahad Git-i töövoogu rahulikult harjutada ilma päris projekti puutumata, tee väike testirepo:
mkdir -p ~/tmp/git-naide
cd ~/tmp/git-naide
git init
printf 'esimene rida\n' > naide.txt
git add naide.txt
git commit -m 'Lisa naidefail'
printf 'teine rida\n' >> naide.txt
git diff
Seejärel:
git add naide.txt
git diff --cached
git commit -m 'Lisa teine rida'
git log --oneline --graph --decorate
See on hea "päris näide", sest siin saad ühe väikese faili peal läbi teha:
- tööpuu muutuse
- diff'i
- stage'i
- commit'i
- ajaloo
Päris näide: uus haru väikese paranduse jaoks
git checkout -b parandus
printf 'kolmas rida\n' >> naide.txt
git diff
git add naide.txt
git commit -m 'Lisa kolmas rida'
git log --oneline --graph --decorate -n 5
Siin on väga hästi näha, miks haru on kasulik:
- saad teha ühe loogilise paranduse eraldi
- ajalugu jääb selgem
- hiljem on seda lihtsam GitHubi pushida või pull request'iks teha
Päris näide: restore ja .gitignore
printf 'ajutine rida\n' >> naide.txt
git diff
git restore naide.txt
printf 'testlogi\n' > debug.log
cat > .gitignore <<'EOF'
debug.log
EOF
git status
Siin:
git restore naide.txtvõtab tööpuu muudatuse tagasi.gitignoreaitab vältida seda, et ajutine fail üldse Git-i satuks
See on palju rahulikum töövoog kui pimesi "proovin midagi reset'ida".
Mõistlikud alias'ed
Kui kasutad Git-i palju, võivad need olla head:
alias gs='git status'
alias ga='git add'
alias gd='git diff'
alias gdc='git diff --cached'
alias gc='git commit'
alias gp='git pull'
alias gph='git push'
alias gl='git log --oneline --graph --decorate'
Need võiks panna samasse shelli config-faili, kus ll.
GitHubi seos SSH-ga
Kui kasutad GitHubi aadressi kujul:
git clone git@github.com:kasutaja/projekt.git
siis kasutab Git taustal SSH-d. Seetõttu on GitHubi töövoog tihedalt seotud peatükiga SSH ja võtmed.
GitHubi töövoog lühidalt
- tee repo koopia või klooni see
- loo eraldi haru
- tee muudatused
- commit'i väikeste loogiliste sammudena
- push'i haru GitHubi
- ava pull request
Minitest
- Vaata käsu
git statusväljundit mõnes repos. - Uuri, mis vahe on
git pulljagit fetch. - Pane kirja, miks on kasulik töötada eraldi harus.
- Käivita
git log --oneline --graph --decorate -n 5mõnes repos. - Muuda üht faili, vaata
git diff, seejärel stage'i see ja vaatagit diff --cached.