Git og GitHub

Git

I disse moduler bliver du introduceret til et helt centralt samarbejdsredskab indenfor software udvikling: git. Git er et værktøj til source control. Når man programmerer og laver større it-projekter i det hele taget, er det supervigtigt at have styr på hvilke ændringer i koden der er lavet i hvilken rækkefølge, og af hvem. Det skal være muligt at gå tilbage til tidligere versioner, hvis noget viser sig at være forkert, og man skal sikre sig at de rettelser man laver ikke bliver overskrevet af andre, der også arbejder på projektet og som arbejder på andre dele af koden. Git er altså et versionsstyrings redskab, og et sådant ud over det sædvanlige.

Grundprincipper og sprogbrug

Grundprincippet i git er, at man har et repository – i daglig tale et repo – som overvåges af git. Alle ændringer registreres i rækkefølge og efter hvem der laver dem. Man arbejder på filerne som normalt, og retter og gemmer undervejs, men når man på et tidspunkt er færdig, så fortæller man git, at “her er noget du skal huske” – man committer ændringerne til git (og man committer sig til ændringerne). Nu laver git en note om hvem og hvornår, samt en liste over forskellene mellem den gamle og den nye version.

Github

Det smarte med git er i virkeligheden at bruge det sammen med GitHub . Mens git kan holde styr på mapper og filer lokalt på din computer, tager GitHub funktionaliteten ud på nettet. Du kan tænke på GitHub som en slags dropbox for programmører. Men I kan ikke kun dele jeres filer i skyen. Med git og GitHub har I fuld kontrol over hvem der retter og ændrer dem, hvornår de gør det og ikke mindst hvorfor. Og I er sikre på, at hvis der er konflikt mellem ændringsforslag, så bliver det opdaget – I kommer ikke til at slette hinandens arbejde ved et uheld.

Når man bruger GitHub, har man sit repo på nettet, på en GitHub-konto. Det kaldes origin eller remote, mens den mappe lokalt på maskinen, som man arbejder i, kaldes local. Git holder styr på, om filerne i den lokale mappe er identiske med origin eller om de er forud eller bagud for rettelser på GitHub.

Push og Pull

Det man arbejder på er i reglen filerne i den lokale mappe. Der hekser man rundt, retter og prøver sig frem, indtil man er tilfreds. Imens gemmer man hele tiden mellemresultaterne – men de skal jo ikke op til andre. Først når man har noget, der virker tilstrækkelig godt, vil man have nye filer og ændringer lagt op. Så laver man et commit, og skriver samtidig en lille note om, hvad det er for en ændring. GitHub noterer, at disse filer skal lægges op på origin. Man siger, at ændringerne er staged – altså sat i scene, lagt til rette for at blive uploaded.

Når du har rodet med dit repo lokalt og staged dine forbedringer, og derpå vil lægge det hele ud til andre på GitHub.com, kaldes det at pushe. Der er altså generelt tre trin i den samlede proces, og i konsollen ville det se således ud:

git add --all   // Læg eventuelle nye filer ind i projektet
git commit --all -m"Jeg har gjort dit og dat"   // stage
git push   // Læg filerne ud på GitHub

Eftersom GitHub ligger på nettet, er det ofte sådan at nogle andre har modificeret koden, eller du har måske selv arbejdet med den på en anden computer. Derfor er det ofte en god idé at starte med et pull, hver gang du starter, før du arbejder videre lokalt. På den måde er du sikker på dine lokale filer svarer til filerne på GitHub.

Kom i gang

Gå ind på github.com og opret en konto, før du går videre. Du har nu en tom GitHub konto. Næste skridt er at få etableret dit første repo, enten ved at linke kontoen op til de filer på lokalt på din maskine, som du vil have som dit lokale git-repository eller ved at skabe et repo på GitHub, som du derefter cloner ned til din egen maskine.

Der er mange forskellige måder at komme til at arbejde med git og GitHub på. Mange arbejder i en “shell”, altså et konsolvindue med tekstkoder direkte til maskinen, men de fleste foretrækker at bruge et program med et interface – jeg gør. Et sådant interface er GitHub Desktop, som vi kigger på her. Visual Studio Code kan også sættes op til at integrere med GitHub så ændringerne trackes og synkroniseres med filerne på nettet, men VSCode bruger i virkeligheden GitHub Desktop “bagved”. Unity kan sådan set også integrere med GitHub, men deres system er ikke blevet opdateret i flere år.

Fremgangsmåde: GitHub Desktop

Gå ind og hent programmet GitHub Desktop her. Herefter er der tre forskellige situationer, der kan være aktuelle:

  1. Du kan ønske at uploade et projekt, du allerede er i gang med, til GitHub. Det kan være et git-repo i forvejen, lokalt på din maskine, eller det kan være en mappe som du nu ønsker at bruge git på og eventuelt dele med andre
  2. Du kan ønske at hente et projekt fra GitHub, som allerede er i gang, og som du gerne vil bidrage til
  3. Du kan ønske at starte et nyt projekt fra bunden og lade git holde styr på det helt fra start

1. Create/add

I GitHub Desktop skal du først sørge for at være logget på din GitHub konto, derefter kan du tilføje dit lokale repository. Vælg add/create new repository for at lave et nyt git-repo ud af en projektmappe (add/add existing repository, hvis git allerede er i brug, men det finder Desktop selv ud af).

Du kan nu “committe” til dit GitHub repository, dele det med andre og i det hele taget arbejde videre som vanligt.

Git ignore (.gitignore)?

Du kan lade git vælge at ignorere visse filer, som altså ikke bliver lagt ud på nettet, men bare bliver lokalt på computeren.

Hvis du har arbejdet med node.js, python eller andre større programmeringssprog, ved du at de ofte har pakker og biblioteker som skal installeres, før et program kan fungere. I node.js projekter ligger der for eksempel altid en fil som hedder package.json, som fortæller nøjagtig hvilke biblioteker projektet er afhængig af (dependencies).

I stedet for at uploade alle disse filer til GitHub, er det meget smartere at lade andre der har downloadet din kode kigge i package.json før de går i gang – og så hente filerne når der er brug for dem. Derfor er det god stil at fortælle git, at dit repo er eksempelvis et “node” projekt, et “unity” projekt eller et “python” projekt, så springer det automatisk over alle de filer, som andre kan hente selv.

På GitHub selv er der faktisk en side dedikeret netop til .gitignore: https://github.com/github/gitignore, som har templates til .gitignore-filer for stort set alle former for IT-udvikling. Processing, Node og Unity er med – og listen er meget lang. Forneden på denne GitHub-side er der mere information.

Hvad med licens?

Git og GitHub er faktisk ikke kun til open-source projekter. Man kan oprette private repos og bruge dem til proprietær kode, og der er også betalingsmodeller tilknyttet GitHub.

Når du uploader et nyt repo til GitHub er det derfor helt centralt at du beslutter dig for hvilken licens du vil bruge. Licenser er der mange af, og det kan være svært at vide hvad man skal vælge. Jeg bruger selv MIT License. Det er en meget liberal software licens, som faktisk tillader andre at bruge min kode kommercielt – så længe de bare sørger for at putte samme licens på deres software.

Hvorvidt denne liberale software opfattelse bliver ved med at holde i det 21. århundrede, kan man dog have sin tvivl om. Men indtil videre…

2. Clone/Fork

Når du henter et eller andet, kaldes det at “clone” et repository. At clone er den mindst invasive måde at hente noget på – det betyder bare: giv mig en lokal kopi, jeg kan gøre hvad jeg vil med. Prøv at clone det her repo fra GitHub. Det stammer fra Daniel Shiffmans fremragende præsentation af GitHub, som du forresten også kan vælge at se i stedet for at læse alt dette.

Github er fantastisk fordi du lynhurtigt kan snuppe andres kode, og se hvordan alt muligt fungerer. Du kan for eksempel hente den fuldkommen åbne kode til Linux. Eller til et hav af andre projekter. Skulle du have en dag i overskud, kan man sagtens få tid til at gå med bare at sidde og hente GitHub projekter og sætte dem op på sin egen computer.

Og tænke over hvordan du kunne modificere koden. Afhængig af licensen – som meget ofte er forskellige udgaver af liberale opensource paradigmer – kan du for det meste downloade alt hvad du finder og bruge det frit i dine egne projekter. I det øjeblik du vil tjene penge på det, skal du dog tjekke licensen en ekstra gang.

Når du har clonet et repo, kommer det over i din lokale git-mappe. Se om du kan få hentet, ændret og committet og pushet et eller andet til din egen GitHub, før du går videre. Men duhar ikke nødvendigvis skriverettigheder på det repo, du har clonet fra. Hvis du har – eller får – rettigheder til det, fx. fordi det er en af dine gruppekammeraters repo og jeres fælles projekt, så kan du pulle, committe og pushe som før. Hvis ikke du har rettigheder, kan du i stedet oprette en fork af repo’et – altså en kopi, som ligger på din GitHub på nettet, og som du kan modificere som det passer dig. Det er det, I skal gøre, når vi linker til skolens eller fagets GitHub til materialer, I skal hente.

Pull request

Lad os sige du havde rodet med noget kode fra et GitHub repo du har klonet og forket. På et tidspunkt finder du så en fejl. Du retter den! Hvordan kan du nu hjælpe koderen til at få fejlen rettet i det oprindelige repo? Du opretter en pull-request, som er en anmodning til ejeren af koden og det oprindelige repo om, at han/hun skal pull’e dine ændringer. Ejeren får så en notifikation og med mindre han/hun tror du er terrorrist, får du lov til at få en (begrænset) adgang. Du kan nu rette fejlen i koden, og forsøge at committe koden tilbage til den originale version. Nu vil ejeren så have mulighed for at kigge din rettelse igennem (review), og eventuelt “merge” den ind i sin egen kode.

Samarbejde

GitHub er også et samarbejdsværktøj. Hvis I er flere i en gruppe, kan I arbejde i et fælles repo på en af jeres GitHub-kontoer, og ejeren af den konto kan invitere jer andre gitHub-brugere som “collaborators” så I alle kan pushe ændringer op. Der er også værktøjer til projektstyring, til at tracke issues og meget andet.

Bemærk, at man IKKE kan clone et repo fra GitHub ned i en lokal mappe, hvor der allerede ligger filer. Man kan altså ikke “supplere” sin egen projektmappe med filer fra andres GitHub repo ved at clone. I stedet kan man eventuelt downloade repo’et som en zip-fil og pille de filer ud, man skal bruge.

Branches

Det er ikke uden risiko, hvis alle bare kan pushe ændringer op til det fælles projekt uden videre. Man risikerer, at ændringer et sted breaker noget et andet sted, sådan at det, der kørte i går, pludselig ikke længere duer. Derfor arbejder man gerne med branches, dvs. “grene” eller “varianter”af koden, hvor man opretter en branch til at arbejde med specifikke aspekter – UI, netværk, modeller, platforme – men sørger for at have en “stabil” version: master branch, som fungerer, og som man først retter i, når man er sikker på at rettelserne duer. Det vil sige at man pusher til en branch på GitHub, og når rettelserne er set igennem (reviewed) kan man vælge at oprette en pull request for at merge denne branch ind i master. På den måde kan mange personer arbejde på mange forskellige dele af projektet uden at gå i vejen for hinanden.

Man vælger hvilken branch man vil pushe til (eller pulle fra) i GitHub Desktop. Teknisk set er det så denne branch, ikke repo’et som sådan, der er “origin“. Og det kan være en god ide at sætte GitHub repo’et op sådan at det simpelthen ikke er muligt at pushe direkte til master, således at rettelser i master kun kan forekomme efter review og merge.

3. Et helt nyt projekt

Hvis man skal til at starte et helt nyt projekt, bliver tingene nemmere hvis man starter med at sætte GitHub-repo’et op. Hvert repo har sin egen mappe på jeres GitHub konto, så hvis man skal starte et projekt fra grunden er en måde at oprette et nyt næsten tomt repo på GitHub og så clone det. Man kan også gøre det lokalt fra GitHub Desktop ved at oprette et nyt repo hvor man så angiver både local og remote placering/sti.

Lidt mere lingo

Et repo er en mappe hvor git holder øje med ændringer

At committe er at fortælle git, at nu er man klar med sine rettelser, og git skal føje dem til projektet

At forke er at kopiere en andens projekt ind i din egen konto på GitHub

At clone er at kopiere et projekt fra GitHub ned på sin egen computer

At fetche er at hente forandringer – men UDEN at ændre dine filer lokalt

En branch er en udgave af et repo der er blevet clonet lokalt

En remote branch er dette repo når den ligger på GitHub (kendes lokalt som origin)

At merge er at flette en branch ind i en anden

En konflikt er når man vil pulle noget ned, som ikke svarer til det man har lokalt, og hvor der er modsat rettede ændringer i de samme kodelinjer