Git, GitHub ja töövoog
Loogika
Git ei ole lihtsalt viis faile GitHubi saata. Git hoiab projekti muutuste ajalugu.
Kõige tähtsam töövoog on:
- vaata, mis seisus repo on
- vaata, mis täpselt muutus
- vali järgmise commit'i sisu
- salvesta loogiline muutus commit'ina
- sünkrooni vajadusel kaugrepoga
Git ja GitHub ei ole sama asi:
Giton versioonihaldus sinu masinasGitHubon teenus, kus repot jagada, arutada ja üle vaadata
Kiirülevaade
| Käsk | Milleks | Mida tavaliselt näed |
|---|---|---|
git status | vaata repo seisu | muutunud, stage'is ja jälgimata failid |
git diff | vaata tööpuu muutusi | - ja + read jälgitud failides |
git add fail | pane fail stage'i | edukal juhul sageli vaikne |
git diff --cached | vaata stage'i sisu | järgmisse commit'i minev diff |
git commit -m '...' | salvesta commit | commit'i lühikood ja kokkuvõte |
git log --oneline | vaata ajalugu | commit'id ühe rea kaupa |
git restore fail | viska tööpuu muudatus ära | fail läheb tagasi viimase commit'i seisu |
git restore --staged fail | võta fail stage'ist maha | sisu jääb alles, stage muutub |
git switch -c haru | loo ja ava uus haru | liigud uuele harule |
git pull --ff-only | uuenda puhas haru serverist | fast-forward või selge keeldumine |
git push -u origin haru | saada haru GitHubi | üleslaadimise kokkuvõte |
Tüüpilised algaja vead
- tehakse
git addenne, kui muudatus on üle vaadatud - arvatakse, et
git diffnäitab ka täiesti uusi ehk jälgimata faile - aetakse segi tööpuu, stage ja commit
- tehakse
git pullmäärdunud tööpuuga - töötatakse otse
mainharus, kuigi muudatus võiks olla eraldi harus - kasutatakse
git push --forceilma aru saamata, kelle ajalugu see muudab
Mis on versioonihaldus
Versioonihaldus tähendab, et projekti muutused talletatakse ajalooks.
Praktiliselt annab see neli võimet:
- näha, mis muutus
- salvestada loogilisi vaheetappe
- minna vajadusel eelmise seisu juurde tagasi
- jagada sama projekti teistega
Ilma selle mõtteta jäävad Giti käsud lihtsalt mehaaniliseks loeteluks.
Kolm kohta: tööpuu, stage ja commit
Giti õppimine läheb palju lihtsamaks, kui eristad kolme kohta.
| Koht | Tähendus | Kontrollkäsk |
|---|---|---|
| tööpuu | sinu failid praegu kettal | git status, git diff |
| stage | järgmise commit'i ettevalmistus | git diff --cached |
| commit | salvestatud loogiline muutus | git log --oneline |
Tavaline rütm on:
git status
git diff
git add fail.txt
git diff --cached
git commit -m 'Selge sõnum'
git add ei tähenda veel “saada GitHubi”. See tähendab ainult: “see muudatus läheb järgmisse commit'i”.
Esimene harjutusrepo
Harjutamiseks tee eraldi ajutine repo. Nii ei puutu sa päris projekti.
mkdir -p ~/tmp/git-naide
cd ~/tmp/git-naide
git init
printf 'esimene rida\n' > naide.txt
git status
git add naide.txt
git diff --cached
git commit -m 'Lisa naidefail'
git log --oneline
Pane tähele: uus fail naide.txt on alguses jälgimata. Seetõttu ei näita tavaline git diff veel selle sisu. Pärast git add naide.txt näitab git diff --cached, mis läheb esimesse commit'i.
Kui git commit kaebab autori identiteedi üle, seadista nimi ja e-post:
git config --global user.name "Eesnimi Perenimi"
git config --global user.email "nimi@example.com"
Seejärel proovi git commit uuesti.
Muudatuse ülevaatamine
Kui fail on juba Git-is jälgimisel, näitab git diff tööpuu muutust.
printf 'teine rida\n' >> naide.txt
git status
git diff
Diffi lugemise algreegel:
-tähendab eemaldatud rida+tähendab lisatud rida- ülejäänud read on ümbrus ehk kontekst
Enne commit'i kontrolli ka stage'i:
git add naide.txt
git diff --cached
git commit -m 'Lisa teine rida'
Hea harjumus:
- enne
git add:git diff - enne
git commit:git diff --cached - enne pull request'i: vaata kogu muudatus veel kord üle
Igapäevane põhivoog
Kui repo on juba olemas ja töötad GitHubiga, on rahulik põhivoog selline:
git status
git switch main
git pull --ff-only
git switch -c parandus
Kui sinu repo kasutab põhireana nime master, kasuta nendes näidetes main asemel master.
Seejärel tee muudatused. Enne commit'i:
git status
git diff
git add fail1 fail2
git diff --cached
git commit -m 'Paranda näited Git peatükis'
git push -u origin parandus
Miks just nii:
git statusnäitab, kas tööpuu on puhasgit pull --ff-onlyuuendab põhirea ainult siis, kui seda saab teha sirgeltgit switch -c parandushoiab muudatuse eraldi harusgit diffjagit diff --cachedvähendavad juhusliku commit'i riski
Kui git pull --ff-only keeldub, ära lisa kohe keerulisemaid lippe. Tee esmalt git status ja vaata, kas sul on kohalikke commit'e või pooleliolevaid muudatusi.
Haru ehk branch
Haru ehk branch on eraldi töölõng sama projekti sees.
Tüüpiline mõtteviis:
mainon põhirida- väike parandus tehakse eraldi harus
- hiljem ühendatakse valmis haru pull request'i kaudu põhireaga
Põhikäsud:
git branch
git switch -c parandused-logides
git switch main
git branch -d parandused-logides
Siin:
git branchnäitab harusid; tärn näitab praegust harugit switch -c nimiloob uue haru ja liigub sinnagit switch mainliigub olemasolevale harulegit branch -d nimikustutab kohaliku haru, kui see on ühendatud
Vanemates juhendites näed sageli kuju:
git checkout -b parandus
See tähendab sama, mis git switch -c parandus, aga switch on algajale selgem: see ütleb otse, et vahetad haru.
Kaugrepo: clone, fetch, pull, push
Kaugrepo on sama repo serveris, näiteks GitHubis. Vaikimisi nimi on sageli origin.
Kui sul ei ole repot veel kohalikus masinas:
git clone git@github.com:kasutaja/projekt.git
cd projekt
git status
See kuju kasutab SSH-d. Kui SSH võtmed ei ole veel seadistatud, pakub GitHub sama repo jaoks ka https://... algusega klooniaadressi.
Kui tahad ainult teada saada, mis serveris muutus, kasuta:
git fetch origin
git log --oneline --graph --decorate --all -n 20
git fetch uuendab infot kaugrepo kohta, aga ei muuda sinu praegust tööharu.
Kui tahad puhta kohaliku haru serveriga samasse seisu tuua:
git pull --ff-only
Kui sul on oma haru valmis ja tahad selle GitHubi saata:
git push -u origin parandus
Kui tööpuu pole puhas
Enne haru vahetamist, pull'i või rebase'i kontrolli:
git status
Kui tahad tööpuu muudatuse ära visata:
git restore fail.txt
Kui tahad faili stage'ist maha võtta, aga sisu alles jätta:
git restore --staged fail.txt
Kui tahad poolelioleva töö korraks kõrvale panna:
git stash push -m 'pooleli enne pulli'
git pull --ff-only
git stash pop
stash on ajutine sahtel, mitte pikaajaline hoiukoht. Kui töö on sisuline, on commit tavaliselt parem kui nädalateks stashi jätmine.
.gitignore
Kõiki faile ei tasu Git-i panna.
Tüüpiliselt jäetakse välja:
- virtuaalkeskkonnad, näiteks
.venv/ - vahemälud, näiteks
__pycache__/ - buildi väljundid, näiteks
dist/ - ajutised logid, näiteks
*.log
Lihtne näide:
cat > .gitignore <<'EOF'
.venv/
__pycache__/
dist/
*.log
EOF
git status
Kui fail on juba Git-i lisatud, siis ainult .gitignore ei eemalda teda automaatselt repost. .gitignore takistab eelkõige uute sobivate failide juhuslikku lisamist.
merge ja rebase
merge ja rebase panevad kaks ajalugu uuesti kokku, aga teevad seda eri moodi.
| Tegevus | Mõte | Millal kasutada |
|---|---|---|
merge | säilitab mõlema haru ajaloo | valmis haru ühendamisel |
rebase | tõstab sinu commit'id teise haru lõppu | oma parandusharu korrastamisel |
Näide: oled harus parandus ja tahad võtta sisse värske main haru:
git fetch origin
git switch parandus
git rebase origin/main
Näide: tahad valmis haru main sisse ühendada:
git switch main
git pull --ff-only
git merge parandus
Meeskonnareegel:
- oma isiklikku parandusharu võib enne pull request'i sageli rebase'ida
- ära rebase'i haru, mille peale teised juba oma tööd ehitavad, kui see ei ole kokku lepitud
- ühise
mainharu ajalugu tuleb käsitleda eriti ettevaatlikult
Konfliktid
Konflikt tekib siis, kui Git ei oska kahte muudatust ise kokku panna.
Failis võib olla selline koht:
<<<<<<< HEAD
minu praegune tekst
=======
teisest harust tulnud tekst
>>>>>>> origin/main
See tähendab:
<<<<<<< HEADall on sinu praeguse haru versioon=======eraldab kaks varianti>>>>>>> origin/mainall on teise haru versioon
Päris konfliktis algavad need märgid tavaliselt rea algusest. Siin on nad taandatud, et õpiku enda Git ei peaks näidet lahendamata konfliktiks.
Lahendamine:
- ava fail redaktoris
- tee valmis õige lõpptekst
- kustuta konfliktimärgid
- kontrolli faili sisu
- lisa fail stage'i
Näiteks:
git status
nano fail.txt
git add fail.txt
Kui konflikt tekkis merge'i ajal:
git commit
Kui konflikt tekkis rebase'i ajal:
git rebase --continue
Kui läksid valesse suunda, katkesta ainult käimasolev tegevus:
git merge --abort
git rebase --abort
Kasuta neist ainult seda käsku, mis vastab parasjagu käimasolevale tegevusele.
Mida mitte teha pimesi
Need käsud võivad olla õiged, aga neid ei tasu kasutada paanikas:
git reset --hardgit clean -fdgit push --forcegit branch -D haru
Rahulikum kontrolljärjekord on:
git statusgit diffgit diff --cached- vajadusel küsi abi või tee koopia enne hävitavat käsku
Kui force-push on päriselt vajalik, peaks see olema meeskonnas kokku lepitud ja tavaliselt omaenda parandusharu peal, mitte ühisel main harus.
GitHub: issue ja pull request
GitHubis seotakse muudatus tavaliselt arutelukoha või ülesandega.
Põhimõisted:
issueon ülesanne, bugi või aruteluteemapull requeston konkreetne muudatusettepanekreviewon teiste tagasiside pull request'i kohtacheckliston Markdowni märkeruutudega loend
Lihtne issue kirjeldus:
## Probleem
Peatükis 09 on `cat` ja `less` vahe liiga uduselt seletatud.
## Oodatud tulemus
Lugeja saab aru, millal kasutada `cat` ja millal `less`.
## Kontroll
- [ ] näide on peatükis parandatud
- [ ] build läheb läbi
Hea pull request vastab kolmele küsimusele:
- mis probleem lahendati
- kuidas seda lahendati
- kuidas kontrolliti, et lahendus töötab
Tüüpiline GitHubi töövoog:
- vali issue või kirjuta probleem lühidalt lahti
- loo selle jaoks haru, näiteks
fix-cat-less - tee väike loogiline muudatus
- commit'i selge sõnumiga
- push'i haru GitHubi
- ava pull request
- vasta review kommentaaridele uute commit'idega
- pärast ühendamist kustuta tööharu
Commit'i või pull request'i kirjelduses saab issue'le viidata:
Fixes #12
Closes #12
Refs #12
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 seotud peatükiga Kauglogimine ja SSH.
Väike lõppharjutus
Tee ajutises repos üks väike töövoog läbi:
cd ~/tmp/git-naide
git switch -c kolmas-rida
printf 'kolmas rida\n' >> naide.txt
git diff
git add naide.txt
git diff --cached
git commit -m 'Lisa kolmas rida'
git log --oneline --graph --decorate -n 5
Kui tahad harjutusrepo hiljem lihtsalt ära unustada, jäta see ~/tmp alla või kustuta siis, kui oled kindel, et seal pole vajalikku tööd.
Minitest
- Selgita, mis vahe on tööpuul, stage'il ja commit'il.
- Miks ei näita
git diffuue jälgimata faili sisu? - Millal vaatad
git diff --cached? - Miks on
git switch -c parandusalgajale selgem kuigit checkout -b parandus? - Mis vahe on
git fetchjagit pull --ff-onlyvahel? - Millal kasutaksid
git restore --staged fail.txt? - Kirjuta pull request'i lühikirjeldus kujul: probleem, lahendus, kontroll.
Lisalugemine
Selle teema usaldusväärsemad viited leiad lisast Lisa E: usaldusväärsed viited ja lisalugemine.
Peatüki täisspikker
Edasijõudnu
Eesmärk
Git hoiab muutuste ajalugu; erista tööpuud, stage'i ja commit'i ning vaata diff enne üle.
Põhikujud
git statusvaata seisgit diffmuutused tööpuusgit diff --cachedmuutused stage'isgit add fail.txtpane stage'igit commit -m '...'tee commitgit switch -c parandusloo harugit pull --ff-onlyuuenda puhtaltgit push -u origin parandussaada harugit restore --staged fail.txtvõta stage'ist
Olulisemad lipud, märgid ja kiirnupud
HEADpraegune tippmainpõhiridaoriginkaugrepostagejärgmine commit