Ohjelmointi 2 ja Git

Git on hajautettu versiohallintaohjelmisto. Versionhallintaohjelmiston ideana on tarjota säilytyspaikka yhteisesti käytettävälle tiedolle ja pitää kirjaa tietoon tehdyistä muutoksista. Ohjelmistotyössä ollaan yleensä pisimmällä tiedon yhteiskäytössä.

1. Tapoja käyttää Git:iä

Aloita tekemällä kohdat asentaminen ja config ohjeesta: Git ja komentorivi

Aluksi ehdottomasti suositeltavin tapa on pääteohjaus 1:ssä harjoiteltu Git ja komentorivi.

Kaikkia alla mainittuja tapoja (työkaluja) voit kuitenkin käyttää ristiin sekä kotona että mikroluokissa. Kannattaa kokeilla eri tapoja.

Asenna em kohdista ainakin komentoriviin liittyvät asiat. Voit asentaa myös muita jos siltä tuntuu.

✅ Nyt saat ruksia asennetuksi kohdan: Git

# gitshort

2. Versionhallinnan käyttö lyhyesti

  • Yhden kerran: luodaan oma remote repository (kurssilla: fork).

  • Jos mennään koneelle, jossa sisältöä ei vielä ole, kloonataan remote omaan koneeseen:

    git clone https://gitlab.jyu.fi/Anonymous/ohj2.git .
  • Jos mennään koneelle jossa sisältö jo on, haetaan työn aluksi aina uusin sisältö remotesta:

    git pull
  • Kun työ lopetetaan, lisätään (stage) muuttuneet/uudet tiedostot:

    git add --all

    ja sitten siirretään ne lokaaliin varastoon:

    git commit -m "muutoksia kuvaava viesti"

    ja lopuksi siirretään talteen etävarastoon:

    git push

Gitin yksi oleellinen ero esimerkiksi SVN:ään on se, että varastoista (repository) voi olla useita kopioita lokaalisti ja etänä. Lokaalivarasto voidaan kopioida etävarastoon (remote repository) ja sieltä edelleen toiseen lokaaliin varastoon. Lisäksi etävarastojakin voi olla useita. Tämän takia komentoja on enemmän svn:ään verrattuna.

Gitissä on 4 tärkeää "tilaa", joiden välillä tietoa liikutetaan: working directory, index/stage, local repository ja remote repository. Alla olevassa kuvassa on esitetty tärkeimmät komennot tähän liikutteluun. Kaikista tärkeimmät niistä punaisilla nuolilla. Kuvassa keltaisella on merkitty omassa koneessa olevia tiloja ja sinisellä viitataan edellisen kuvan palvelimeen.

# umlGIT
HUOM! Tätä kuvaa ei pidä tulkita UML:än sekvenssikaavioksi!working directoryindex/stagelocal repositoryremote repositoryworking directoryindex/stagelocal repositoryremote repositoryclone <osoite>Annetaan kerran/koneadd --allKun tiedostot muuttuneetcommit -mpushpull or rebaseKun tasataan kaverin kanssafetchmergecheckout HEADcheckoutdiff HEADdiff
# terms

2.1 Git termejä:

  • repository = (tieto)varasto, paikka jossa versioitava tieto tallennetaan, voi olla lokaali (local) tai etä (remote), kumpiakin voi gitissä olla useita. local repository on käytännössä hakemistossa oleva .git-hakemisto. Repository koostuu loogisesti "commiteista", jotka muodostavat kokoelman projektin eri vaiheista, haaroista ja tageistä. Näin mihin tahansa commitoituun kohtaan voidaan viitata tai palata.
  • origin = lyhenne käytettävän etävaraston osoitteelle (remote repository)
  • project = jokin selkeä projekti, joka tähtää esimerkiksi jonkin yhden ohjelmatuotteen tekemiseen
  • working directory = työhakemisto (workspace joissakin dokumeteissa), lokaalin koneen työhakemisto (kaikki tiedostot ja versiot löytyvät tämän alla olevasta .git -hakemistosta, jos ne on koneelle haettu (fetch))
  • index = varastoon seuraavalla commitilla siirrettävien tiedostojen luettelo (versioitavien, staging area joissakin lähteissä, koska tiedosto laitetaan "näytille"). Käytännössä tiedosto .git/index.
  • main = projektin päähaara, joka pyritään pitämään toimivana koodina (ennen oli master)
  • branch = kehityshaara jossa kehitetään uutta koodia. Kehityshaaroja voi olla useita. Kun koodi on hyväksi todettu, se voidaan yhdistää (merge) päähaaraan.
  • tag = jäädytetty haara (esimerkiksi ohjelman tietty versio), jota ei aktiivisesti kehitetä, mutta johon voi tulla esimerkiksi tietoturvapäivityksiä
  • fork = projektista tehty "kopiohaara", joka elää omaa elämäänsä (tällä kurssilla). Fork ei ole Gitin toiminto, mutta useat ulkoiset Git- palvelimet (kuten GitHub ja GitLab) tarjoavat tämän toiminnon.
  • HEAD = viite aktiivisen haaran "päähän" tietyssä lokaalissa

Kurssilla käytettäviä Git-komentoja:

git config --global user.name "Anonymous"
git config --global user.email "None"    
git clone https://gitlab.jyu.fi/Anonymous/ohj2.git .
git status  # tätä komentoa kannattaa käyttää ahkeraan vaikka joka välissä
git log     # samoin tätä, kunhan opit lukemaan sen sisältöä
# tee tarvittavia muutoksia
git add --all
git commit -m "Vaihe 1, kuvat"
git push    # kaverin pitää kotona tehdä git pull
# näytä ohjaajalle, jos muutoksia jatka kohdasta "tee tarvittavia"
git tag -a vaihe1
git push --tags 

# seuraava_vaihe:
  git branch tyo2
  # tehdään vaihetta
    git checkout tyo2
    git push -u origin tyo2 
    # tee uutta koodia, pidä huoli että .gitignore on olemassa
      git add --all
      git add -f kerho.jar  # pakotetaan käytetyn .jar:in lisäys
      git commit -m "vaihe 2 selitys"
      git push     # kaverin pitää kotona tehdä git pull ja git checkout tyo2
      # jos vaihe ei vielä valmis, jatka kohdasta "tee uutta koodia"
    git checkout main
    git merge tyo2
    git push       # kaverin pitää kotona tehdä git pull ja git checkout main
    # näytä ohjaajalle, jos muutoksia jatka kohdasta "tehdään vaihetta"
  git tag -a vaihe2
  git push --tags  # kaverin pitää kotona tehdä git pull 
  # Jatka kohdasta "seuraava_vaihe", kasvata vaiheen numeroa (eli käytä 2 tilalle
    toista numeroa)

Eli pitääkö tehdä uusi haara vaihetta kaksi varten?

VL: Joo, ja sitten mergetä se päähaaraan kun on hyväksytty. Hajroitellaan tätä mitä oikeatsi pitää osata tehdä.

25 Jan 24 (edited 25 Jan 24)

2.2 Lähteitä

# fork

3. Aloita tekemällä remote repository pohjaprojektista, eli fork

Fork on projektista tehtävä itsenäinen "haara", joka jatkaa omaa elämäänsä, mutta josta on viite alkuperäiseen projektiin ja alkuperäisestä voi seurata mitä "forkkeja" siitä on tehty. Forkin ansiosta saadaan uuteen projektiin samat alkuasetukset.

  1. Kirjaudu gitlabiin https://gitlab.jyu.fi/ JY:n tunnuksilla

  2. Mene JY:n gitlabin Ohj2-pohjaan: https://gitlab.jyu.fi/tie/ohj2/2024k/ohj2

    • seuraavat vaihtoehdot jos et voi joistakin syystä kirjautua JY:n GitLabiin tai haluat tehdä tunnetuimmissa paikoissa esimerkiksi oman portfoliosi takia. Tosin JY:n Gitissäkin tehdyn voi pushata tunnetumpiin sitten kun se on likellä valmista.
  3. Valitse oikeasta ylänurkasta fork (näkyy vain jos on kirjautunut) Image

  4. Jos tulee valittavaksi useampia namespaceja (ryhmiä), valitse omaa tunnustasi vastaava.

  5. Jos teet ryhmässä, niin lisää vielä Project Information/Members/Invite member-kohdasta muiden ryhmäläisten käyttäjätunnukset ja vastaavasti oikeuksiksi Maintainer. Ryhmäläisten pitää olla ensin kirjaantunut ainakin kerran gitlabiin.

  6. Avaa vasemmasta laidasta Settings/General laajenna valintoja otsikon alta Visibility, project features, permissions ja tarkista että projektilla on julkinen näkyvyys.

  7. Projektisi remote repository on nyt 
    https://gitlab.jyu.fi/Anonymous/ohj2.git

    Käytä tätä nimeä tulevissa ohjeissa. Muista lisätä tämä polku projektisi suunnitelmaan, niin ohjaajat löytävät sen.

  8. Jatka tekemällä tästä lokaali klooni (local repository) koneeseesi: clone

Antaa seuraavaa erroria, vaikka en ole vielä tehnyt forkkia: **You tried to fork tie / ohj2 / 2021k / ohj2 but it failed for the following reason:

– Name has already been taken**

VL: Sulla näyttäisi jo olevan tyhjö repo: https://gitlab.jyu.fi/SUNTUNNUS/ohj2. Mene tuonne ja tuhoa se.

17 Jan 21 (edited 17 Jan 21)

Olen tehnyt forkin gitissä viime keväänä. Jouduin kuitenkin siirtämään kurssille osallistumisen tähän kevääseen. Tuleeko tuo git asennus tehdä alusta uudelleen ohj2 kevät23-pohjasta? HT:n eka vaihe on tehty ja hyväksytty, mutta aion sitä kyllä muuttaa.

VL: eipä siinä mitään oleellisesti erilaista ole. Tee kuitenkin se TIMissä oleva sivu uusiksi vaikka pätkiä vanhasta kopioimalla.

12 Jan 23 (edited 12 Jan 23)

En löydä Gitistä kesän 2023 pohjaa (https://gitlab.jyu.fi/tie/ohj2/2023kesa/ohj2), mutta kevään pohja toki löytyy. Tämä varmaan ok.

On ok -JK

09 Jun 23 (edited 12 Jun 23)

4. Harjoitustöiden hakemistohierarkia

  • Hakemistorakenne koneen levyllä pitää olla tyyliin:

      c:\kurssit\ohj2\ht   Mac/Lnux:  ~/kurssit/ohj2/ht
                       .git
                       .gitignore
                       README.md
                       src 
                         kerho
                           Jasen.java
                           Jasenet.java
                           ...
                       kuvat
                         paaikkuna.png
                         ...

Harjoittelin nyt tätä pääteohjaus 1 git-tehtäviä parilla uudella koneella. Olisi kysymys tuosta .git polkurakenteessa. kaikki menee muuten kuten mallirakenteessa mutta .git ei näy. Missä vaiheessa sen olisi pitänyt tulla? Tuo lokaali klooni jne teki vain .gitignore

VL: katso työkalujen pääsivulta miten laitetan piilotoedostot näkyviin. Ne ei Windowsin oletuksilla näy.

10 Jan 20 (edited 11 Jan 20)
  • Jokainen tekee oman haaransa ja sen alle jokaista vaihetta varten oman haaran.

  • Alla olevassa mallissa tehty "projektille" vesal (korvaa vesal omalla tunnuksellasi ja tietysti kerho, Jasen jne oman työsi vastaavilla nimillä).

    gitlab.jyu.fi/vesal/ohj2
      main
          .gitignore
          README.md
          src 
            kerho
              Jasen.java
              Jasenet.java
              ...
          kuvat
            paaikkuna.png
            ...
          files.txt
      tags
          vaihe1
          vaihe2
          vaihe3
          vaihe4
          vaihe5
          vaihe6
          vaihe7
          jsp

    Joku haara (branch) on se missä tehdään koko ajan hommia. Sen alla on tarvittavat paketit (esimerkissä vain kerho, mutta niitä voi olla enempikin ja niitä voi olla sisäkkäin).

    Kun vaihe tulee valmiiksi, tehdään siitä vaihetta vastaava tag eli mainkopioidaan sen vaiheen haaraan. Vaihe tarkistetaan aina main-haarasta HT:tä näytettäessä ja kun vaihe on hyväksytty, tehdään se tag.

# references

5. Gitin commitit ja viitteet

Tässä luvussa pyritään kuvaamaan hieman enemmän Gitin sisäistä toimintaa.

Muistetaan että kukin commit on "kopio sen hetkisestä työhakemiston sisällöstä". Tai tarkemmin stagessa (index) commitointi hetkellä oleesta sisällöstä. Commitissa syntyy tiedostoista kopiot .git/objects hakemistoon. Itse commitit sisältävät viitteitä näihin kopioihin. Jokaisesta commitista on myös viite edelliseen committiin. Rinnakkaisten haarojen yhdistämisen jälkeen taakseviitteitä voi olla useampiakin.

Komennot switch (uudemmissa Giteissä) tai checkout siirtävät tietyn commitin sisällön työhakemistoon.

Alla työn vaiheet kuvaavat Ohj2 kurssin työvaiheita silloin, kun ei pääse syntymään rinnakaisia haaroja. Niistä erikseen kuvia muualla.

Seuraavissa kuvissa on vihreillä laatikoilla merkitty committeja (nimetty c1, c2 ja c3) ja soikeilla laatikoilla nimettyjä viitteitä. Kuvissa ei pyritä kuvaamaan kopioitujen tiedostojen sisältöjä, vaan kukin commit ajatellaan, että se tavalla tai toisella sisältää tiedot kopioiduista tiedostoista.

"Mystiset" kirjainsarjat laatikoissa kuvaavat committia vastaavan hash-arvon alkuosaa. Näitä hash-arvoja voit katsoa esim kutsulla:

git log

tai ehkä vielä paremmin näkee missä HEAD ja haarat ovat:

git log --graph --abbrev-commit --decorate 

Hash-arvot tulevat, kun lasketaan sha1-hash -arvo committiin liittyvistä identifioivista tekijöistä (mm. sisältö, tekoaika ja tekijä).

5.1 commit

Esimerkiksi kahden commitin jälkeen local repository (.git-hakemisto) voisi olla loogisesti alla olevan näköinen.

commit c1 34ac2 c2 f30ab c2->c1 HEAD HEAD main main HEAD->main main->c2

5.2 branch

Oletuksilla toistaiseksi käytössä on vain yksi haara (main) ja HEAD viittaa siihen.

Jos luodaan uusi haara (vaikkapa tyo2), mutta ei vielä tehdä mitään muuta, niin HEAD säilyy päähaarassa.

git branch tyo2
branch c1 34ac2 c2 f30ab c2->c1 HEAD HEAD main main HEAD->main main->c2 work2 tyo2 work2->c2

5.3 switch

Komennolla

git switch tyo2

viite HEAD siirtyy työhaaraan

Mikäli sinulla on käytössä vanhempi versio gitistä josta switch-komento puuttuu, käytä komentoa

git checkout tyo2
switch c1 34ac2 c2 f30ab c2->c1 HEAD HEAD work2 tyo2 HEAD->work2 main main main->c2 work2->c2

5.4 Haaran commit

Kun commitoidaan jotakin uutta, syntyy uusi commit, jota työhaara oletuksena seuraa (jos se on aktiivinen haara)

git commit -m "Korjattu selostusta"
commit c1 34ac2 c2 f30ab c2->c1 c3 92a6b c3->c2 HEAD HEAD work2 tyo2 HEAD->work2 main main main->c2 work2->c3

5.5 Siirtyminen mainiin

Jos siirrytään takaisin main-haaraan, siirtyy HEAD sinne:

git switch main
switch c1 34ac2 c2 f30ab c2->c1 c3 92a6b c3->c2 HEAD HEAD main main HEAD->main main->c2 work2 tyo2 work2->c3

5.6 tag

Jos ennen main-haaran muuttamista tehdään tagi, se jää osoittamaan tähän kohtaan

git tag vaihe1
tag c1 34ac2 c2 f30ab c2->c1 c3 92a6b c3->c2 HEAD HEAD main main HEAD->main main->c2 work2 tyo2 work2->c3 vaihe1 vaihe1 vaihe1->c2

5.7 merge

Kun työhaara yhdistetään main-haaraan, on kaikki taas samassa paikassa (ellei johonkin ole lisätty välillä jotakin uutta):

git merge tyo2
merge c1 34ac2 c2 f30ab c2->c1 c3 92a6b c3->c2 HEAD HEAD main main HEAD->main main->c3 work2 tyo2 work2->c3 vaihe1 vaihe1 vaihe1->c2

Lokaalin repositoryn puskeminen (push) tekee tästä kopion remote repositoryyn tai päivittää sitä, jos se on jo olemassa.

Vastaavasti remote repositoryn clone tekee siitä kopion toiseen lokaaliin repositoryyn.

Komennot pull ja fetch vastaavasti päivittävät kerran kloonatun repositoryn sisältöä. Työhakemiston sisältö riippuu siitä, missä kohti HEAD on menossa. Eli välttämättä työhakemiston sisältö ei muutu, kun lokaali repository päivitetään.

6. fetch

Oletetaan että kaveri on hakenut remotesta itselleen tuon edellisen kuvan mukaisen tilanteen

  • tehnyt mainiin yhden commitin
  • tehnyt uuden haaran
  • siihen 2 committia
  • lopuksi pushannut

Kun tilanne haetaan omaan lokaaliin komennolla

git fetch 

on kuva suuripiirtein seuraavan näköinen:

fetch c1 34ac2 c2 f30ab c2->c1 c3 92a6b c3->c2 c4 4bd34 c4->c3 c5 8d2bc c5->c4 c6 1a3de c6->c5 HEAD HEAD main main HEAD->main FETCH_HEAD FETCH_HEAD origmain origin/main FETCH_HEAD->origmain main->c3 origmain->c4 work2 tyo2 work2->c3 vaihe1 vaihe1 vaihe1->c2 origwork2 origin/tyo2 origwork2->c3 origwork3 origin/work3 origwork3->c6

These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.