Git-vinkkejä
Tällä sivulla on vinkkejä Gitin käyttämiseen tämän kurssin projektissa. Oletuksena on, että projekti on GitHubissa ja se on kloonattu omalle koneelle.
Lähtökohta
Kun projektia kehitetään, omalla koneella on paikallinen projektin työhakemisto sekä siihen liittyvä repositorio. Kun työhakemiston muutokset halutaan talteen repositorioon, tiedostot valitaan ensin komennolla git add
ja sitten suoritetaan komento git commit
.
Tämän lisäksi GitHubissa on toinen repositorio, jonka sisällön on tarkoitus olla sama kuin oman koneen repositoriossa. Komento git push
siirtää muutoksia omalta koneelta GitHubiin, ja komento git pull
puolestaan siirtää muutoksia GitHubista omalle koneelle.
Commitin tekeminen
Commitin tekeminen tarkoittaa, että haluamme tallentaa työhakemistoon tehtyjä muutoksia repositorioon. Tässä on muutamia vaiheita, joiden merkitys kannattaa ymmärtää.
Komento git status
kertoo repositorion tilanteen, ja sitä kannattaa käyttää usein. Komento kertoo, mitä muutoksia työhakemistoon on tehty. Komennon suoritus voi näyttää vaikkapa seuraavalta:
$ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: apina.txt
modified: banaani.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
cembalo.txt
no changes added to commit (use "git add" and/or "git commit -a")
Tämä tarkoittaa, että tiedostot apina.txt
ja banaani.txt
ovat repositoriossa, mutta niitä on muutettu työhakemistossa. Lisäksi työhakemistoon on luotu uusi tiedosto cembalo.txt
, jota ei vielä ole lainkaan repositoriossa.
Kun haluamme viedä muutokset repositorioon, teemme uuden commitin. Voimme valita komennolla git add
tiedostot, jotka tulevat mukaan commitiin. Esimerkiksi voimme valita tiedostot apina.txt
ja cembalo.txt
näin:
$ git add apina.txt
$ git add cembalo.txt
Tämän jälkeen git status
näyttää muuttuneen tilanteen:
$ git status
On branch main
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: apina.txt
new file: cembalo.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: banaani.txt
Tässä tiedostot apinat.txt
ja cembalo.txt
on valittu commitiin. Näemme edelleen, että tiedostoa banaani.txt
on muokattu, mutta se ei ole menossa commitiin.
Seuraava vaihe on suorittaa komento git commit
, joka suorittaa commitin. Tässä yhteydessä annetaan viesti, joka kertoo, mitä muutoksia kyseinen commit tekee repositorioon.
$ git commit -m "Update apina and create cembalo"
[main 7cfdfab] Update apina and create cembalo
2 files changed, 1 insertion(+)
create mode 100644 cembalo.txt
Tämän jälkeen repositorion tilanne näyttää tältä:
$ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: banaani.txt
no changes added to commit (use "git add" and/or "git commit -a")
Muutettu tiedosto banaani.txt
näkyy edelleen tässä, mutta listalla ei ole enää muita tiedostoja, koska niiden uusin versio on nyt repositoriossa.
Tässä vaiheessa muutokset on jo tehty repositorioon, mutta vasta paikallisesti. Prosessin viimeistelee komento git push
, joka siirtää muutokset GitHubiin:
$ git push
Miten tehdä hyvä commit?
Commitin tekijän on päätettävä kaksi asiaa: mitä tiedostoja commitiin tulee mukaan ja mikä on commitin viesti. Huonoin ratkaisu on laittaa mukaan sokkona kaikki muutetut tiedostot ja viestiksi “Some changes” tai vastaavaa.
Commitissa tulisi olla muutoksia, jotka todella halutaan kaikkien näkyville repositorioon ja jotka liittyvät tiettyyn yksittäiseen asiaan (kuten uuden ominaisuuden toteutus tai jonkin bugin korjaus). Tämän vuoksi on hyvä katsoa komennolla git status
, mitä on tapahtunut, ja valita commitiin oikeat tiedostot. Jos muokkaat samaa tiedostoa, muista tehdä tallennus ja commit, ennen kuin siirryt työskentelemään seuraavan asian parissa.
Commit-viestien kirjoittaminen on oma taiteenlajinsa. Viestin tulisi kertoa selkeästi, mitä muutoksia kyseinen commit aiheuttaa ja miksi se tehdään. Esimerkiksi Chris Beamsin ohje on hyvää luettavaa ihanteista, joihin voi pyrkiä.
Kun commitit on tehty hyvin, projektia on mukava katsella myöhemmin GitHubissa. Viesteistä voi seurata, miten projekti on kehittynyt ja mitä muutoksia on tehty milloinkin.
Muutosten peruminen
Paikallisen muutoksen peruminen
Tarkastellaan vielä tilannetta, jossa tiedostoa banaani.txt
on muutettu:
$ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: banaani.txt
no changes added to commit (use "git add" and/or "git commit -a")
Saattaa olla, että muutos oli erehdys ja haluaisimme perua sen. Voimme noudattaa yllä olevaa neuvoa ja perua muutoksen näin:
$ git checkout banaani.txt
Tämä komento hakee tiedoston banaani.txt
repositoriosta ja korvaa sillä muutetun tiedoston. Nyt työhakemiston tiedoston sisältö on taas sama kuin repositoriossa:
$ git status
On branch main
nothing to commit, working tree clean
Tiedosto pois commitista
Entä jos laitamme muokatun tiedoston vahingossa mukaan commitiin, mutta emme haluakaan tehdä commitia? Silloin tilanne näyttää seuraavalta:
$ git add banaani.txt
$ git status
On branch main
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: banaani.txt
Tässäkin tapauksessa voimme seurata komennon antamaa neuvoa:
$ git reset HEAD banaani.txt
Tämän seurauksena tiedosto banaani.txt
poistetaan commitista ja se näkyy taas muokattuna:
$ git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: banaani.txt
no changes added to commit (use "git add" and/or "git commit -a")
Vastaavasti komento git reset HEAD
ilman tiedostoa poistaa kaikki commitiin lisätyt tiedostot ja voimme aloittaa puhtaalta pöydältä commitin valmistelut.
Commitin peruminen
Seuraavassa tilanteessa olemme vieneet commitin loppuun ja tajuamme vasta sitten, että commit oli virhe:
$ git add banaani.txt
$ git commit -m "Change banaani"
[main eff67d3] Change banaani
1 file changed, 1 insertion(+)
Tässä vaiheessa commit näkyy jo tehtyjen commitien listalla:
$ git log
commit eff67d3743e37837e99b278c3843b30280e86925 (HEAD -> main)
Author: Antti Laaksonen <ahslaaks@cs.helsinki.fi>
Date: Tue Jul 14 19:18:55 2020 +0300
Change banaani
commit 7cfdfabca6b021bbe314d77b1ff0718cc415b9d5
Author: Antti Laaksonen <ahslaaks@cs.helsinki.fi>
Date: Tue Jul 14 17:36:10 2020 +0300
Update apina and create cembalo
...
Kuitenkin kun commit on tehty vasta paikallisesti, pystymme perumaan sen näin:
$ git reset HEAD~1
Tämä komento siirtää repositorion tilan yhtä askelta aiemmaksi ja kaikki on taas hyvin:
$ git log
commit 7cfdfabca6b021bbe314d77b1ff0718cc415b9d5 (HEAD -> main)
Author: Antti Laaksonen <ahslaaks@cs.helsinki.fi>
Date: Tue Jul 14 17:36:10 2020 +0300
Update apina and create cembalo
...
Kuitenkin jos muutos on viety jo eteenpäin (git push
), niin sama konsti ei toimi, koska joku toinen on saattanut käydä hakemassa tehdyn muutoksen ja peruminen siinä vaiheessa sekoittaisi pahasti asioita. Tällöin ratkaisu on tehdä uusi commit, joka peruuttaa edellisen commitin.