Github ved UiO

Dette dokumentet beskriver UiOs lokale Github-tjeneste. Det er også en introduksjon til bruk av Git, samt litt generell informasjon om Git-kommandoer.

1   Litt om GitHub

GitHub er en fullverdig Git-tjeneste samt at den har et visuelt grensesnitt som lar deg enkelt behandle og bla i gjennom kode og informasjon som har blitt lastet opp av deg selv og andre.

1.1   Hvorfor GitHub ved UiO

Git er det mest populære systemet for revisjonskontroll, ihvertfall innen fri programvare. Git har flere kararteristikker som er svært tiltalende. Her er de viktigste:

God støtte for ikke-linjær utvikling
Git støtter enkelt å raskt lage nye grener i utviklingen (branching) og sammensmelting av grener (merging). Git har spesielle verktøy for å visualisere og navigere en ikke-linjær utviklingshistorikk. En gren (branch) i Git er svært lettvekt, den er kun en referanse til en enkelt commit. Hele grenstrukturen kan bli konstruert ved å se bakover på slike referanser.
Distribuert utvikling
Som endel andre tilsvarende verktøy for versjonskontroll (men ulikt Subversion og CVS), gir Git hver utvikler en lokal kopi av hele utviklingshistorikken. Endringer kan kopieres fra ett slikt repository til et annet. Disse endringene importeres som ekstra grener (branches), og kan smeltes sammen (merges) på samme måte som en lokalt utviklet gren (branch).
Kompabilitet med eksisterende systemer og protokoller
Repositories kan bli publisert via kjente protokoller som HTTP, FTP og rsync. I tillegg finnes det en egen Git-protokoll som enten kan brukes over en vanlig socket eller via ssh. Git har også støtte for å kunne brukes sammen med Subversion eller CVS.
Effektiv behandling av store prosjekter
Git har et svært godt rykte for å være effektiv og rask, også når det handler om store prosjekter med svært mange filer og komplisert utviklingshistorikk. Git blir ikke tregere etter hvert som historikken blir større.
Kryptografisk autentisering av historikk
Git-historikken lagres på en slik måte at navnet på en revisjon (dvs. en commit) avhenger av den komplette historikken som leder opp til denne enkelte commit'en. Når historikken er publisert, er det teoretisk umulig å endre eldre versjoner uten at det kan bli lagt merke til.

2   Hvordan ta i bruk GitHub

Straks du logger deg inn på nettsiden https://github.uio.no vil du ha fått opprettet en bruker og kan ta i bruk GitHub. For å kunne laste ned et repository til din datamaskin må du først ha lagt inn en SSH-nøkkel. Nedenfor følger en instruksjon til hvordan du tar dette i bruk.

For IT-ansatte ved UiO anbefales å det lese følgende dokument: .. _Github for IT-ansatte: https://www.uio.no/tjenester/it/lagring-samarbeid/versjonskontroll/github-for-it-ansatte.md

NB. Hvis du har reservert deg mot at din e-post skal være synlig for andre ved UiO så vil dette ikke fungere i GitHub, din e-post vil være synlig for andre brukere i GitHub så lenge de er innlogget på GitHub.

2.1   SSH-nøkler

GitHub bruker SSH-nøkler for å autentisere brukere som vil koble seg til Git-tjenesten.

  1. Hvis du ikke har en RSA-nøkkel fra før, lag en ny slik:

    ssh-keygen -t rsa -b 4096
    

Du vil her bli spurt om hvor du vil lagre id_rsa-filen, og i tillegg om en passordfrase. Ved UiO må alle SSH-nøkler beskyttes med passordfrase, så det er ikke lov å velge en tom passordfrase.

  1. Når du har denne nøkkelen klar, så laster du opp .pub-filen som ble opprettet, eller som du allerede har tilknyttet din SSH-nøkkel. Dette gjør du ved å logge deg inn på github.uio.no og så trykker på bildeikonet tilhørende din profil i høyre hjørne. Du vil da få opp en meny hvor du kan velge "Settings". Når du da har navigert videre til "Settings" finnes det en lenke kalt "SSH keys". Trykk så på "Add SSH key" og du vil få opp et skjema hvor du vil kunne lime inn innholdet fra din pub-fil. Veldig viktig her at du limer inn fra filen kalt id_rsa.pub og ikke fra id_rsa, da sistnevnte er din private nøkkel som du ikke skal dele med noen andre.

2.2   Opprette et nytt repository

Du oppretter et nytt repository ved å enten trykke oppe i høyre hjørne på pluss-ikonet og velge "create new repository" eller ved å gå til https://github.uio.no/new . Her vil du kunne velge om det skal være et offentlig repository som er tilgjengelig for alle ved UiO som er innlogget, eller et privat repository som bare du har tilgang til.

2.3   Opprette en organisasjon

Om du skal samarbeide om flere prosjekter med en gruppe mennesker så kan det være fint å bruke en organisasjon for å organisere sammen flere repositories på en enkel måte. Ved å trykke på pluss-ikonet i høyre hjørne vil du kunne velge "Create new organization" og bli ledet til skjemaet for opprettelse av dette.

Rettighetsstyring innenfor her kan foregå på et granulært nivå, slik at man kan for eksempel ha både offentlige og private repositories, som både er tilgjengelig for alle UiO-brukere, og kun for en liste over brukere som du selv har definert.

Et konkret eksempel på hvordan man kan ta dette i bruk er ved å bruke det i klasseromsammenheng. Der vil man kanskje ha et repository som kun er tilgjengelig for gruppelærere, og et kun tilgjengelig for studenter.

2.4   Videre dokumentasjon

GitHub sitt utviklingslag har dokumentert deres applikasjon GitHub Enterprise ganske godt så om det er noe man lurer på så finner man det meste forklart både i applikasjonen og eventuelt ved å søke det opp på dokumentasjonssidene som man finner her: https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories https://docs.github.com/en/free-pro-team@latest/github/using-git

3   Enkel bruk av git

Her forutsettes det at aktiv katalog er mittrepo.

3.1   Legge til en fil lokalt

For å legge til en fil:

git add <filnavn>

Filen må eksistere fra før.

Se for øvrig git-add(1).

3.2   Sjekke inn endringer lokalt

For å sjekke inn endringer:

git add [filer...]
git commit [filer...]

Hvis man ikke vil kontrollere hvilke filer det gjelder trenger man ikke spesifisere filer. Da vil git søke gjennom hele katalogen for å finne ut hva som er endret. Det vil komme opp en editor der man skal skrive commit-melding. Man kan isteden angi denne på kommandolinjen:

git commit -m '<melding>' [filer...]

Man kan også velge å gjøre "add" i samme prosess, dvs. at man slipper å gjøre en egen "git add", men kun hvis filen finnes i git fra før:

git commit -a [filer...]

Ting kan kombineres:

git commit -a -m '<melding>' [filer...]

Se for øvrig git-commit(1).

3.3   Pushe endringer til sentralt repo

En "git commit" vil kun sjekke inn endringer lokalt, i ditt lokale repository. For å få dette inn på git-serveren må man bruke push:

git push

Se for øvrig git-push(1).

3.4   Hent endringer fra sentralt repo

Man kan oppdatere sitt lokale repo fra det sentrale ved å bruke pull:

git pull

Se for øvrig git-pull(1).

4   Enkel bruk av branching

Den normale måten å utvikle på med Subversion og CVS er noe slikt som dette:

Linjær utviklingsmodell

Git sin commit-historikk er mer kompleks enn det man finner i Subversion, CVS og tilsvarende systemer. I Git kan en commit ha flere foreldre og flere barn (rettet asyklisk graf). Dette betyr at man ikke er nødt til å redigere på siste revisjon av koden. Man kan lage en commit basert på en hvilken som helst commit og lage en gren av den. Når man så ønsker å smelte disse sammen (merge), lager man en commit som er et barn av to commits. Slike barn kalles "merge commits".

Den vanligste måten å bruke branching er til eksperimentelle features i et prosjekt, ev. til back-porting av endringer til en stabil branch.

Ettersom branching i Git er såpass effektivt og enkelt er det naturlig å følge en utviklingsmodell som ser slik ut:

Grenet utviklingsmodell

For å se hvilke grener som er tilgjengelig, og hvilken som er aktiv (angitt med stjerne "*"):

$ git branch
* main

Før man lager en ny branch, burde man kjøre en git pull for å få de nyeste endringene. For å lage en ny branch:

$ git branch test

$ git branch
* main
  test

For å endre aktiv branch:

$ git checkout test
Switched to branch 'test'

$ git branch
  main
* test

Man kan også ta en snarvei og spesifisere ny branch ved checkout:

$ git checkout -b test2
Switched to a new branch 'test2'

$ git branch
  main
  test
* test2

4.1   PR (Pull Request)

System Message: WARNING/2 ({DAVSYNC3}github-ved-uio.rst, line 253)

Title underline too short.

PR (Pull Request)
----------------

Dersom man er fornøyd med endringene som er utført i en branch, kan man gjøre merge av denne inn til en annen, f.eks. fra en test-branch til en prod-branch. I eksemplet gjør vi merge av innholdet i test inn i main.

De fleste repoer krever at man lager en Pull Request (PR) for å gjøre en merge. Dette gjøres ved å gå til nettsiden til repoet og trykke på "New Pull Request" under Pull Requests.

Man kan også gjøre dette via kommandolinjen. --fill gjør at commit-meldingen brukes som overskrivt på PR. Dette gjøres slik:

$ gh pr create --fill

4.2   Squash

Git squash er en funksjon som tillater en å kombinere flere git-commits til én enkelt commit. Dette gjør at historikken til prosjektet blir mer ryddig og oversiktlig. Ved å bruke git squash kan en enkelt kombinere flere små commits til én større og mer meningsfull commit, som gjør at det blir enklere å følge med på endringshistorikken og samtidig opprettholde kvalitetskravene til git commits. Dette er spesielt nyttig når en arbeider på en git-gren og ønsker å kombinere flere mindre endringer før de merges til hovedgrenen.

Kommonandoen for å squash commits er, der X er antall commits:

$ git rebase -i HEAD~X

Dette vil åpne en editor med en liste over de siste X commits. Commiten man ønsker å beholde som den er, markeres med pick/p. De andre endres til squash/s. Når man er ferdig med å redigere, lagres og lukkes filen. Dette vil gi en ny commit med alle endringene fra de valgte commits.

Til slutt må man pushe på nytt ved:

$ git push --force-with-lease

4.3   Merging

I eksemplet gjør vi merge av innholdet i test inn i main:

  1. Sørg for at aktiv branch er den som det skal merges inn i:

    $ git checkout main
    Switched to branch 'main'
    
  2. Kjør git merge:

    $ git merge test
    Updating bdebdfc..10c644c
    Fast-forward
     minfil.txt |    1 +
     1 files changed, 1 insertions(+), 0 deletions(-)
    

    Dersom du får en konflikt ser det slik ut:

    Auto-merging minfil.txt
    CONFLICT (content): Merge conflict in minfil.txt
    Automatic merge failed; fix conflicts and then commit the result.
    

    Ev. konflikter må løses før en merge kan fullføres.

  3. Til slutt gjøres commit:

    $ git commit -a -m 'melding'
    [el6 5ad8e86] melding
    

For mer informasjon, se git-merge(1).

4.4   Slette en branch

Dette gjøres slik:

$ git branch -d test
Deleted branch test (was 8f08040).

Dette forutsetter at man har gjort git merge først. Dersom endringene i 'test' skal kastes uten videre, bruk git branch -D test.

For mer informasjon, se git-branch(1).

5   Tips og triks

5.1   Farger i diff og annen output

For å få farger fra git diff og andre Git-kommandoer kan man sette følgende i ~/.gitconfig:

[color]
        ui = auto

Dette kan også settes vha. git config:

git config --global color.ui auto

5.2   Aliaser til Git-kommandoer

Man kan sette aliaser for Git-kommandoer på denne måten:

[alias]
        <alias> = <kommando>

Eksempel:

[alias]
        co = checkout

Dette kan også settes med git config (eksempel):

git config --global alias.co checkout

5.3   Bruke meld som verktøy for merging

Meld er et GUI-program (GNOME) for å visualisere og hjelpe med merging. Dersom man ønsker at Git i tilfelle konflikt ved merge skal starte Meld automatisk, kan man sette i ~/.gitconfig:

[merge]
        tool = meld

Eller med git config:

git config --global merge.tool meld

Husk å også installere Meld:

sudo yum -y install meld

5.4   Vise aktiv branch i prompt

For å få bash til å vise aktiv branch i prompet kan man sette PS1 på følgende måte i ~/.bashrc:

if [ -f /etc/bash_completion.d/git ]; then
    source /etc/bash_completion.d/git
    export GIT_PS1_SHOWDIRTYSTATE=true
    export GIT_PS1_SHOWUNTRACKEDFILES=true
fi
export PS1='[\u@\h \W$(declare -F __git_ps1 &>/dev/null && __git_ps1 " (%s)")]\$ '

Dette vil sørge for at bash-prompten ser slik ut:

[user@host directory-name (main)]$

I tillegg til å vise hvilken branch man jobber på, vil dette også vise om men er i en merge eller rebase:

[user@host directory-name (main*)]$
[user@host directory-name (main+)]$
[user@host directory-name (main%)]$
  • På den første linjen er en fil endret
  • På den andre linjen er en fil endret og man har gjort git add men ikke git commit
  • På den tredje linjen er det laget en ny fil som ikke er i git

Disse vil naturligvis kombineres.

Av Safet Amedov
Publisert 23. juli 2024 14:46