Mustand: sisu ei ole veel tehniliselt ega keeleliselt täielikult kontrollitud ega toimetatud.

Peatüki vaade

Linux/Unix/macOS käsurea kiirõpik

Praegu loed peatükki Git, GitHub ja töövoog, mis kuulub osasse Osa V: Arendus ja töövood.

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:

  1. vaata, mis seisus repo on
  2. vaata, mis täpselt muutus
  3. vali järgmise commit'i sisu
  4. salvesta loogiline muutus commit'ina
  5. sünkrooni vajadusel kaugrepoga

Git ja GitHub ei ole sama asi:

  • Git on versioonihaldus sinu masinas
  • GitHub on teenus, kus repot jagada, arutada ja üle vaadata

Kiirülevaade

KäskMilleksMida tavaliselt näed
git statusvaata repo seisumuutunud, stage'is ja jälgimata failid
git diffvaata tööpuu muutusi- ja + read jälgitud failides
git add failpane fail stage'iedukal juhul sageli vaikne
git diff --cachedvaata stage'i sisujärgmisse commit'i minev diff
git commit -m '...'salvesta commitcommit'i lühikood ja kokkuvõte
git log --onelinevaata ajalugucommit'id ühe rea kaupa
git restore failviska tööpuu muudatus ärafail läheb tagasi viimase commit'i seisu
git restore --staged failvõta fail stage'ist mahasisu jääb alles, stage muutub
git switch -c haruloo ja ava uus haruliigud uuele harule
git pull --ff-onlyuuenda puhas haru serveristfast-forward või selge keeldumine
git push -u origin harusaada haru GitHubiüleslaadimise kokkuvõte

Tüüpilised algaja vead

  • tehakse git add enne, kui muudatus on üle vaadatud
  • arvatakse, et git diff näitab ka täiesti uusi ehk jälgimata faile
  • aetakse segi tööpuu, stage ja commit
  • tehakse git pull määrdunud tööpuuga
  • töötatakse otse main harus, kuigi muudatus võiks olla eraldi harus
  • kasutatakse git push --force ilma 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.

KohtTähendusKontrollkäsk
tööpuusinu failid praegu kettalgit status, git diff
stagejärgmise commit'i ettevalmistusgit diff --cached
commitsalvestatud loogiline muutusgit 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 status näitab, kas tööpuu on puhas
  • git pull --ff-only uuendab põhirea ainult siis, kui seda saab teha sirgelt
  • git switch -c parandus hoiab muudatuse eraldi harus
  • git diff ja git diff --cached vä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:

  • main on 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 branch näitab harusid; tärn näitab praegust haru
  • git switch -c nimi loob uue haru ja liigub sinna
  • git switch main liigub olemasolevale harule
  • git branch -d nimi kustutab 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.

TegevusMõteMillal kasutada
mergesäilitab mõlema haru ajaloovalmis haru ühendamisel
rebasetõstab sinu commit'id teise haru lõppuoma 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 main haru 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:

  • <<<<<<< HEAD all on sinu praeguse haru versioon
  • ======= eraldab kaks varianti
  • >>>>>>> origin/main all 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:

  1. ava fail redaktoris
  2. tee valmis õige lõpptekst
  3. kustuta konfliktimärgid
  4. kontrolli faili sisu
  5. 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 --hard
  • git clean -fd
  • git push --force
  • git branch -D haru

Rahulikum kontrolljärjekord on:

  1. git status
  2. git diff
  3. git diff --cached
  4. 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:

  • issue on ülesanne, bugi või aruteluteema
  • pull request on konkreetne muudatusettepanek
  • review on teiste tagasiside pull request'i kohta
  • checklist on 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:

  1. vali issue või kirjuta probleem lühidalt lahti
  2. loo selle jaoks haru, näiteks fix-cat-less
  3. tee väike loogiline muudatus
  4. commit'i selge sõnumiga
  5. push'i haru GitHubi
  6. ava pull request
  7. vasta review kommentaaridele uute commit'idega
  8. 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

  1. Selgita, mis vahe on tööpuul, stage'il ja commit'il.
  2. Miks ei näita git diff uue jälgimata faili sisu?
  3. Millal vaatad git diff --cached?
  4. Miks on git switch -c parandus algajale selgem kui git checkout -b parandus?
  5. Mis vahe on git fetch ja git pull --ff-only vahel?
  6. Millal kasutaksid git restore --staged fail.txt?
  7. 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 seis
  • git diffmuutused tööpuus
  • git diff --cachedmuutused stage'is
  • git add fail.txtpane stage'i
  • git commit -m '...'tee commit
  • git switch -c parandusloo haru
  • git pull --ff-onlyuuenda puhtalt
  • git push -u origin parandussaada haru
  • git restore --staged fail.txtvõta stage'ist

Olulisemad lipud, märgid ja kiirnupud

  • HEADpraegune tipp
  • mainpõhirida
  • originkaugrepo
  • stagejärgmine commit