Git og GitHub

Bilde av Yancy Min fra Unsplash

Bilde av Yancy Min fra Unsplash

De aller fleste som har drevet med prosjekter har på ett eller annet tidspunkt endt opp med en mappe struktur for dokumenter som ser omtrent slikt ut.

ls -ltr
total 0
-rw-rw-r-- 1 stanley stanley 0 mai   15 17:42 prosjektSuper
-rw-rw-r-- 1 stanley stanley 0 mai   15 17:42 prosjektSuper.v2
-rw-rw-r-- 1 stanley stanley 0 mai   15 17:42 prosjektSuper.v3
-rw-rw-r-- 1 stanley stanley 0 mai   15 17:42 prosjektSuper.v4
-rw-rw-r-- 1 stanley stanley 0 mai   15 17:43 prosjektSuper.ferdig
-rw-rw-r-- 1 stanley stanley 0 mai   15 17:44 prosjektSuper.ferdig2
-rw-rw-r-- 1 stanley stanley 0 mai   15 17:44 prosjektSuper.Overlevert

Dette er på mange måter ikke noe feil med å ha lagret flere revisjoner av filer på denne måten. Men det er noen problemer.

For det første kan et prosjekt potensielt ta veldig stor plass på diskene dine.

For det andre kan det fort bli uoversiktlig hva som faktisk er den siste versjonen av filene.

Om man er den eneste som jobber med filene i ett prosjekt kan dette sikkert gå greit siden man stort sett klarer å holde oversikt i sitt eget rot. Men det store problemet oppstår når flere personer i ett team skal samarbeide på de samme filene i ett prosjekt. Da blir det for mye rot og dårlig stemning.

Git prøver å løse problemet med revisjoner på en smidig måte. I stedet for å lagre en ny kopi av filen som ble endret, tar git å lagrer endringene som ble gjort på en fil siden sist gang den ble lagret som en revisjon. Dette er spesielt nyttig på software prosjekter med kildekode, siden det stort sett bare er noen linjer med kode som blir endret fra revisjon til revisjon.

Siden man i tillegg kun lagrer endringene fra gang til gang, er det veldig raskt å gjøre en endring. Hvis det vise seg at man angrer på denne endringen er det like lett å gå tilbake til forrige revisjon.

Installasjon og konfigurasjon

For å starte å bruke git er det noen ting som må på plass.

  1. Du må installere git
  2. Git må konfigureres med hvem du er

Når dette er på plass kan starte å jobbe på ett prosjekt og du koble prosjekte opp mot github, bitlab, bitbucket eller lignende for arkivering og for at andre skal kunne bidra på prosjektet.

I denne guiden tar vi utgangspunkt i at det utvikles på en Ubuntu Linux maskin. Men bortsett ifra selve installasjonen er bruken av git lik for alle operativsystem, inkludert Windows.

Vi starter med å installere git:

sudo apt install git

Når git er installert kan du verifisere med hvilken versjon du har installert.

git --version
git version 2.25.1

Nå må du legge inn ditt navn og din epost i de globale git instillingene for din bruker på datamaskinen.

git config --global user.name "Stanley Skarshaug"
git config --global user.email "stanley.skarshaug@gmail.com"

For å kontrollere at innstillingene ble registrert kan du kjøre denne kommandoen

git config --list
user.email=stanley.skarshaug@gmail.com
user.name=Stanley Skarshaug

Da er det bare å starte bruke git.

Ditt første git prosjekt

Å lære å gå før man kan løpe

Vi starter dette lille demo prosjektet ved å opprette en mappe i home folderen, og navigerer inn i den mappen.

mkdir /home/stanley/gitDemo
cd /home/stanley/gitDemo

Denne mappen blir roten i git prosjektet vårt. Git vil følge med på endringer som skjer i filene og undermappene til denne rot mappen.

For at git skal fungere må det initialiseres i denne mappen.

git init
Initialized empty Git repository in /home/stanley/gitDemo/.git/

Dette oppretter en skjult mappes som heter .git. Denne mappen inneholder alle de nødvendige filene som må til for at git skal fungere. Filene i denne mappen skal du ikke gjøre noe med direkte. De vil bli oppdatert automatisk når du bruker git kommandoer. Derfor kan du i stor grad bare late som om den ikke eksisterer.

Nå kan vi opprette prosjektets aller første fil:

nano test.txt
test.txt
Hei, dette er en test av git! :)
Dette er andre linje i filen som ble skrevet.

Nå er filen opprettet, men hvis vi sjekker status på git prosjektet kan vi se at filen ikke er lagt til i prosjektet.

git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	test.txt

nothing added to commit but untracked files present (use "git add" to track)

Som du kan les utifta terminaldumpen over er filen untracked. Det vil si at endringer i denne filen blir ikke overvåket av git. For at denne filen skal bli overvåket må den legges til i git prosjektet.

For å legge til alle nye filer i prosjektmappen til i prosjektet kjør følgende kommando:

git add -A

Hvis vi sjekker statusen til git, vil vi se at filen er lagt til i prosjektet og er klar til å bli committet.

git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   test.txt

Utifra teminal dumpen over kan vi ved å lese nedreste linje se at filen er lagt til i "staging" og er klar for å bli committed. Å commite er git sjargong for arkivering.

Alle filer som blir lagt til i en mappe som er under git revisjons kontroll må bli lagt til i git prosjektet. Blir de ikke lagt til i prosjektet vil ikke git få med seg endringer i filene.

Husk derfor å legge alle filer som skal være en del av prosjektet inn i git.

For å commite filen skriver vi denne kommandoen:

git commit -m "Første commit!"
[master (root-commit) 711aa0c] Første commit!
 1 file changed, 2 insertions(+)
 create mode 100644 test.txt

Gratulerer! Du har gjort din aller første commit! Hvis vi sjekker status på git prosjektet vil vi se at det ikke er noen nye endringer siden forrige commit.

git status
On branch master
nothing to commit, working tree clean

Andre commit

Endring av en fil

For å demonstrere hvordan git fungerer sletter vi den andre linjer og legge til en ny linje med tekst.

nano test.txt
test.txt
Hei, dette er en test av git! :)
Dette er den tredje linjen som ble skrevet.

Hvis vi nå sjekker status på prosjektet kan vi se at git har registrert at filen har blitt endret siden forrige commit.

git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   test.txt

no changes added to commit (use "git add" and/or "git commit -a")

For å se nøyaktig hva som ble endret kjøres denne kommandoen:

git diff test.txt
diff --git a/test.txt b/test.txt
index 77808a5..e4f62a7 100644
--- a/test.txt
+++ b/test.txt
@@ -1,2 +1,2 @@
 Hei, dette er en test av git! :)
-Dette er andre linje i filen som ble skrevet.
+Dette er den tredje linjen som ble skrevet.

Over kan vi se nøyaktig hva som har blitt endret siden forrige commit. Linjen med minus foran har blitt fjernet og linjen meg pluss foran har blitt lagt til.

Nå kan vi commite denne endringen:

git commit -am "Forandre på filen"
[master 04192b0] Forandre på filen
 1 file changed, 1 insertion(+), 1 deletion(-)

Som du ser av terminal dumpen over vil du få ett sammendrag av hva som ble endret i denne commiten.

GitHub

Arkivering, samarbeid og snikskryt

Github er en populær plattform for gratis arkivering av prosjekter. I tillegg er det en fin måte samarbeide om ett prosjekt på.

Noe av styrkene til git er at det er skreddersydd for at mange personer kan samarbeide på samme prosjekt. Som ett bevis på hvor effektivt det er å jobbe med prosjekter i git vil jeg nevne at Linux blir utviklet ved hjelp av git.

På Linux prosjektet er det flere tusen personer som bidrar. Faktisk ble git utviklet fordi Linus Torvalds, mannen og "Sjefen" bak Linux trengte ett bedre revisjonskontroll system enn det han og teamet brukte tidligere.

Git repoet for linux prosjektet kan du finne her

Måten man bruker git på er ikke så veldig intuitivt i starten. Men jo mer man bruker git og jo flere prosjekter man jobber på med git, jo mer skjønner man hvorfor det er designet som det er og hvor genialt det faktisk er.

De aller fleste git prosjekter har ett origin, eller ett hovedsted det arkiveres. I denne guiden skal vi bruke GitHub, men det finnes mange alternativer som GitLab og BitBucket. Alle har sine styrker og svakheter. Her har jeg valgt å bruke GitHub siden det er gratis og kanskje lettest å komme i gang med.

Når du blir med i ett team som jobber med ett prosjekt starter man med å laste ned en kopi, eller en klone av prosjektet. Navnet som bruker på prosjektene er er repo, som er kort for repository. Etter hvert som man jobber på ett prosjekt må man "pulle", eller hente ned endringene som de andre i teamet har gjort fra origin (GitHub) til din datamaskin før man kan bidra med endringer.

Når du er ferdig med endringene man ønsket å gjøre på prosjektet må du "pushe" eller sende endringene dine til origin (GitHub) slik at de andre i prosjektet kan får tilgang til endringene du bidro med.

Om man ikke ønsker eller trenger å samarbeide med andre utviklere på ett prosjekt er git i kombinasjon med GitHub en fantastisk måte å ta backup av av prosjekter på.

Å vise frem prosjektene dine kan være en fin måte å vise frem ferdighetsnivået ditt, og hvordan du velger å løse problemer på.

Mange utviklere bruker GitHub som en form for sosialt media for å vise frem hvilke prosjekter de jobber med på fritiden. Det er mange grunner til at man gjør dette. En av de er for å vise frem prosjekter til venner og kolleger. Å vise frem prosjektene dine kan være en fin måte å vise frem ferdighetsnivået ditt, og hvordan du velger å løse problemer på.

GitHub repository

Arkivering online

Når du har opprettet en bruker på GitHub kan opprette ett repo der som vi kan bruke som orgin til det lille prosjektet vårt.

Det første du gjør er å opprette ett nytt repo som du gir ett meningsfullt navn, og velger om skal være privat, eller offentlig.

I mange tilfeller velge man å gjøre repository'et privat fordi det skal inneholde filer med databasepassord osv. Men det finnes metoder som gjøre at du ikke trenger å publisere sensitiv informasjon med ett repo. Dette utenfor scopet til denne guiden, så det vil jeg ikke skrive noe om her.

Screenshot fra github

Oppretting av nytt repository på github.

Når du har gått videre vil GitHub vil presentere tips for hvordan du kan få github repoet satt som origin til det lokale repoet. Denne guiden er ikke helt rett.

Screenshot fra github

Repoet er klart til å motta data.

For å definere hva som er origin til prosjektet kjører vi starter vi helt enkelt med å kopiere den første kommandoen GitHub foreslår:

git remote add origin https://github.com/mEsUsah/first_step.git

Nå er det bare å pushe det lokale repoet til origin, som i dette tilfelle er github repoet vårt.

git push --set-upstream origin master
Username for 'https://github.com': mEsUsah
Password for 'https://mEsUsah@github.com': 
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 2 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 550 bytes | 550.00 KiB/s, done.
Total 6 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/mEsUsah/first_step.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

Første gang man skal pushe til origin fra en local branch må man definere hva som er upstream for den lokale git branchen. I dette tilfellet vil det si at den lokale master branchen skal bruke master branchen hos origin som upstream.

Når man pusher til github må man autentisere ved å oppgi brukernavn og passord. Når GitHub har godkjent autentiseringen vil git fullføre pushet til origin.

Hvis vi laster på nutt GitHub siden vi var på, vil du se att filen nå ligger på GitHub.

Screenshot fra github

Nå kan vi se filen i git repoet på GitHub

Da har du et komplett prosjekt med localt repo og origin repo, som du kan jobbe med!

Push / Pull

Praktisk arbeid med git

Hele poenget med GitHub er at man kan bruke det som en backup løsning, eller som et verktøy for samarbeid.

For at origin som ligger på GitHub skal bli oppdatert må man "pushe" de lokale endringene til GitHub, slik at repoet der blir oppdatert.

Dette kan vi teste med å legge til en ny linje på filen vår

nano test.txt
test.txt
Hei, dette er en test av git! :)
Dette er den tredje linjen som ble skrevet.
Fjerde linje

Så committer vi endringen til filen

git commit -am "legge til fjerde linje"
[master ab8873e] legge til fjerde linje
 1 file changed, 1 insertion(+)

Så kan vi pushe endringene slik at de havner på GitHub.

git push
Username for 'https://github.com': mEsUsah
Password for 'https://mEsUsah@github.com': 
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 2 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 296 bytes | 296.00 KiB/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1), completed with 1 local object.
To https://github.com/mEsUsah/first_step.git
   83a6c14..ab8873e  master -> master

Hvis vi nå tar en titt på filen på GitHub, vil du kunne se endringene.

Screenshot fra github

GitHub repoet er oppdatert med de siste endringene.

På denne måten kan du fortsette med prosjektet ditt. Du endrer på filer, committer endringene til ditt lokale repo, og pusher det lokale repoet slik at GitHub repoet blir oppdatert.

Hvis det er noen andre som deltar på prosjektet pusher endringer til GitHub må du oppdatere ditt lokale repo (slik at det er likt med det som ligger på GitHub), før du kan pushe endringene du har lokalt til GitHub.

git pull
Username for 'https://github.com': mEsUsah
Password for 'https://mEsUsah@github.com': 
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/mEsUsah/first_step
   ab8873e..56b9355  master     -> origin/master
Updating ab8873e..56b9355
Fast-forward
 test.txt | 1 +
 1 file changed, 1 insertion(+)

Som vi kan se utifra terminal dumpen var den en ny linje som var lagt til. Leser du du filen nå, vil du se at den er oppdatert.

cat test.txt 
Hei, dette er en test av git! :)
Dette er den tredje linjen som ble skrevet.
Fjerde linje
Femte linje, som ble endret ett annet sted enn lokalt

Logg, og historikk

En av de store fordelene med å jobbe på GitHub og andre lignende plattformer er at det er veldig lett å få oversikt over hva som er gjort på prosjektet. Hvis du trykker på commits knappen i github kommer du til loggen over commits på prosjektet.

Screenshot fra github

Hvor man finner commit loggen i GitHub

Her kan man se hele commit loggen til git repoet.

Screenshot fra github

Liste over alle commits på repoet

Hvis du trykker på committen kan se nøyaktig hva som ble endret i den committen.

Screenshot fra github

Detaljer over endringer som ble gjort i committen.

Her kan du se nøyaktig hvilken linje det ble gjort endringer på. I dette tilfellet ble det lagt til en ny linje.

Praktiske råd

git er fantastisk, men bare hvis det brukes rett!

Mye av det som gjør git så populært er at man kan gå tilbake i tid, til en tidligere versjon av en fil. Men for at det skal være lettvint på prosjekter med mange commits er det noen regler som bør følges.

  1. La en commit kun inneholde en endring. Det vil si at hvis du skal endre footeren på en webside bør du committe hver del av den jobben. En commit kan være å flytte på noe tekst, en annen commit kan være å endre farge på den teksten.
  2. Skriv gode og beskrivende commit beskjeder. Tenk over at du og andre skal kunne finne en endring i prosjektet ved å lete i commit loggen og finne endringen basert på commit beskjeder. En commit beskjed alá: "oppdaterte footer" gir lite mening når footeren på nettsiden har blitt oppdatert mange ganger iløpet av prosjektets levetid. Fortell nøyaktig hva som ble endret i footeren alá "footer: endre farge på linker"
  3. Skriv i commit beskjeder i nåtid. En commit inneholder en endring. Tenk over at når du leter git commit loggen for å finne enn commit vil du lese det som "denne commiten gjorde 'denne' endringen på prosjektet".

Når det er flere som skal samarbeide på ett prosjekt er det lurt å avklare arbeidsoppgaver slik at dere ikke jobber på samme fil samtidig. Hvis man ikke følger dette rådet blir det fort problemer når man skal flette sammen endringene. I praksis vil det si at ett prosjekt må deles opp i filer som tar seg av spesifikke deler av prosjektet.

Når man jobber med prosjekter i git skjønner man fort hvorfor det er en fordel å ha prosjektet delt opp i små filer for å sikre god prosjektflyt. Ved at hver fil inneholder kun en spesifikk del av prosjektet reduserer man sannsynligheten for at man må vente på hverandre eller at man får problemer med å flette sammen commitene. Dette er noe man uansett er tjent med siden det også blir lettere å lese koden.