Gå til indholdet

Git og Github

Git og GitHub er meget brugt i moderne softwareudvikling, uanset hvilket programmeringssprog der bruges. I C#-udvikling kan de være yderst effektive til at håndtere versionskontrol, samarbejde, og kode deling.

Information til undervisere

Afhængig af kursisten formål med at lære C# kan denne sektion måske springes over. Hvis du tager det med så forbered et eksempel som kursisterne kan være i (pull, branch, push, pull request).

Git

Hvad er Git?

Git er et essentielt værktøj i moderne softwareudvikling, der fungerer som et avanceret versionskontrolsystem. Forestil dig at arbejde på et komplekst projekt, hvor du konstant tilføjer, ændrer og fjerner kode. Hvordan holder du styr på alle disse ændringer, og hvordan sikrer du, at du kan vende tilbage til en tidligere, velfungerende tilstand, hvis noget går galt?

Det er præcis det problem, Git løser. Git er et versionskontrolsystem, der systematisk sporer alle ændringer i dit projekt. Hver gang du gemmer en ny version af dit arbejde med en ‘commit’, opretter Git et ‘øjebliksbillede’ (snapshot) af hele dit projekt. Dette giver dig en række afgørende fordele:

  • Historik og Gendannelse: Du får en komplet historik over alle ændringer, hvilket gør det muligt at gå tilbage til enhver tidligere version af din kode.
  • Eksperimentering og Stabilitet: Du kan arbejde på nye funktioner eller rettelser i isolerede ‘grene’ (branches), uden at risikere stabiliteten i din hovedkodebase. Når arbejdet er færdigt og testet, kan det sikkert flettes ind i hovedprojektet.
  • Effektivt Samarbejde: Git er designet til at gøre det nemt for flere udviklere at arbejde på det samme projekt samtidigt. Systemet hjælper med at håndtere og flette ændringer fra forskellige teammedlemmer.

Kort sagt er Git et fundamentalt værktøj, der sikrer kodens integritet, muliggør parallel udvikling og forenkler samarbejde. Selvom der er en indlæringskurve, er de grundlæggende funktioner i Git en kernekompetence for enhver udvikler.

Installation af Git

For at bruge Git skal du installere det på din computer. Git er tilgængelig for Windows, Mac og Linux. Du kan downloade den seneste version af Git fra Git’s officielle hjemmeside. Det er typisk allerede installeret på en Linux og Mac maskine, ligesom en Windows maskine brugt i undervisningslokaler også vil have det installeret. Alternativt kan downloade og installere det fra her til Windows. En installation til Windows vil typisk også installere Git Bash, som er en terminal til Windows, der giver en emulering af en Bash-oplevelse i en Windows-miljø.

Første gang du benytter git

Hvis det er første gang du benytter git på en maskine skal du tilføje et user name og email. I princippet er det underordnet hvad du skriver her hvis det kun er dig der bruger det pågældende repository, men du kan angive dine personlige oplysninger hvis du vil.

  • Åbn en terminal
  • Skriv følgende kommandoer:
git config --global user.name "Dit navn"
git config --global user.email "Din email"

Prøv det selv

Nu hvor du har en grundlæggende forståelse af, hvad Git er, er det tid til at prøve det i praksis. Følgende trin guider dig igennem oprettelsen af dit første lokale Git-repository. Alt, hvad vi gør her, foregår udelukkende på din egen computer.

1. Opret en projektmappe

Start med at oprette en ny, tom mappe til dit projekt. Du kan gøre dette via din stifinder eller i en terminal.

mkdir MitFoersteProjekt
cd MitFoersteProjekt

2. Initialiser Git

Nu skal vi fortælle Git, at denne mappe skal være et repository. Det gør du med kommandoen git init.

git init

Denne kommando opretter en skjult undermappe ved navn .git. Det er her, Git gemmer al sin magi: hele historikken og alle versioner af dit projekt. Du skal normalt aldrig røre ved filerne i denne mappe direkte.

3. Opret en .gitignore fil

Ofte har projekter filer, som vi ikke vil have med i versionsstyringen. Det kan være midlertidige filer, logfiler eller filer med personlige indstillinger (som obj og bin mapper i .NET). Til dette formål bruger vi en .gitignore fil.

Opret en fil ved navn .gitignore og tilføj navne på filer eller mapper, der skal ignoreres.

# Ignorer bygge-mapper fra .NET
/bin
/obj

4. Tilføj filer til ‘staging’ og lav et commit

Lad os nu oprette en fil og fortælle Git, at den skal spores.

Først, opret en fil:

echo "Hello, Git!" > readme.md

Nu har vi to nye filer: readme.md og .gitignore. Før vi går videre, er det en god idé at tjekke, hvad Git ser.

Tjek status:

git status

Du vil se output lignende dette:

On branch main

No commits yet

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

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

Git fortæller os, at der er to “untracked” filer - filer som Git endnu ikke holder øje med. For at inkludere dem i vores næste version (commit), skal vi først tilføje dem til et midlertidigt “staging area”. Det kan ses som en indkøbskurv, hvor du samler de ændringer, du vil gemme.

git add .
Kommandoen git add . tilføjer alle nye og ændrede filer i mappen til staging.

Lad os tjekke status igen:

git status

Nu vil du se:

On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   .gitignore
        new file:   readme.md

Filerne er nu “staged” og klar til at blive committet. Bemærk at Git også fortæller dig, hvordan du kan fjerne filer fra staging hvis du fortryder.

Se præcis hvad der ændres:

Før du committer er det ofte nyttigt at se nøjagtigt hvad der er ændret. Det gør du med git diff:

git diff --staged

--staged flaget viser forskelle for filer, der er tilføjet til staging area. Du vil se noget lignende:

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cbbd0b5
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+/bin
+/obj

diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..8d0e412
--- /dev/null
+++ b/readme.md
@@ -0,0 +1 @@
+Hello, Git!

Linjer der starter med + er nye linjer. Senere, når du ændrer eksisterende filer, vil du også se - for slettede linjer. Dette giver dig fuld kontrol over, hvad der er ved at blive committet.

Nu er vi klar til at gemme vores første version med git commit.

git commit -m "Første commit: Tilføjet readme og gitignore"
-m flaget lader dig tilføje en besked, der beskriver, hvad denne commit indeholder. Gode commit-beskeder er korte, men beskrivende.

Tjek status en sidste gang:

git status

Du vil nu se:

On branch main
nothing to commit, working tree clean

Dette betyder, at alle dine ændringer er gemt i et commit, og der er ingen nye ændringer i din working directory.

Tillykke! Du har nu oprettet dit første lokale Git-repository og lavet dit første commit.

5. Lav en ændring og se historikken

En af de største styrker ved Git er at kunne spore ændringer over tid. Lad os prøve at ændre readme.md filen.

echo "En ekstra linje til readme." >> readme.md
(Bemærk brugen af >> som tilføjer tekst til filen, i stedet for > som overskriver den).

Nu har vi en ændring. Vi følger samme procedure som før for at gemme den:

git add readme.md
git commit -m "Opdateret readme med en ekstra linje"

Nu har vi to commits i vores historik. For at se historikken kan du bruge kommandoen git log:

git log

Du vil nu se en liste over alle de commits, du har lavet, med den seneste øverst. Hver log-entry viser commit-ID (en lang hash-streng), forfatter, dato og commit-beskeden. Dette er dit projekts historie, og du kan altid vende tilbage til et af disse punkter.

Alt dit arbejde er stadig gemt sikkert på din egen computer. Senere kan du vælge at koble dette lokale repository til en fjern server som GitHub for at dele dit arbejde og samarbejde med andre.

Hvad er GitHub?

GitHub er en webbaseret platform for versionskontrol og samarbejde, der gør det muligt for udviklere at arbejde sammen om projekter. Mens Git er et kommandolinjeværktøj, leverer GitHub et webbaseret grafisk interface. Det giver også adgang til flere samarbejdsfunktioner, såsom opgavestyring, fejlsporing og projektstyring, samt funktioner, der bygger videre på Git. GitHub er ejet af Microsoft.

Arbejdsmåder i GitHub

GitHub tilbyder flere måder at arbejde med projekter på:

  1. Eget repository: Når du opretter dit eget repository (projekt) på GitHub, har du fuld kontrol over det. Du kan tilføje filer, lave ændringer og push’e (overføre) dem direkte til hovedgrenen (eller en anden gren) i dit repository. Andre udviklere kan bidrage til dit projekt ved at oprette pull requests eller issues (fejlrapporter eller forslag).

  2. Fork og Pull Requests: Hvis du vil bidrage til et projekt, som du ikke ejer, kan du “forke” (kopiere) det. Når du har forket projektet til din egen GitHub-konto, kan du lave ændringer lokalt og derefter sende en “pull request” (PR) til det originale repository. Repository-ejeren kan herefter gennemgå dine ændringer og vælge, om de skal flettes ind i hovedprojektet. Dette er en central arbejdsgang i open source-projekter.

  3. Collaborator-modellen: I nogle projekter kan repository-ejeren give andre udviklere rettigheder til direkte at push’e ændringer til et repository. Dette er almindeligt i teams, hvor flere medlemmer arbejder sammen på lige fod uden behov for PR’er for hver eneste ændring.

Da vi i forbindelse med undervisning ofte arbejder med små projekter, vil vi ofte benytte den første model, hvor du har fuld kontrol over dit eget repository, og andre kan bidrage ved at oprette pull requests. Da undervisningen typisk foregår på en fremmed maskine, vil vi også benytte SSH-nøgler til at logge ind på GitHub. På den måde kan du arbejde med dit repository uden at risikere at efterlade login-informationer på en fremmed maskine fordi du har brugt et browser token. Det kan være noget rod at rydde op i bagefter.

Den helt simple upload til GitHub

  • Sørg for at arbejde i en mappe (eksempelvis \kursus) så alle projekter er placeret her
  • Kør eventuelt følgende powershell script for at slette alle \obj og \bin foldere som typisk ikke skal med op på GitHub
    • Get-ChildItem -Recurse -Directory | Where-Object { $_.Name -in 'bin', 'obj' } | Remove-Item -Recurse -Force
  • Opret et repository
  • Upload samtlige mappe manuelt gennem browseren

Brug et SSH token

Her er en trin-for-trin guide til at oprette et SSH token på en fremmed maskine:

Generer en ny SSH-nøgle

Åbn Git Bash og indtast følgende kommando (erstat ‘din_email@example.com’ med din egen e-mailadresse):

ssh-keygen -t ed25519 -C "din_email@example.com"

Når du bliver bedt om at “Enter a file in which to save the key,” kan du trykke Enter. Dette accepterer den standardfilplacering. Indtast derefter en sikker adgangskode, når du bliver bedt om det.

Om Ed25519 SSH-nøgler

Ed25519 er en moderne, sikker kryptografisk algoritme til SSH-nøgler, der anbefales frem for ældre algoritmer som RSA.

Fordele:

  • Sikkerhed: Stærkere kryptering end RSA-2048 med kortere nøgler
  • Performance: Meget hurtigere at generere og verificere
  • Størrelse: Kompakte nøgler (68 tegn vs. RSA’s 544+ tegn)

Ed25519 er den moderne standard og understøttes af GitHub, GitLab, Bitbucket og de fleste moderne systemer.

Start ssh-agent

I Git Bash, start ssh-agent i baggrunden ved at indtaste:

eval "$(ssh-agent -s)"

Tilføj SSH nøgle

Tilføj derefter din SSH private nøgle til ssh-agenten ved at indtaste:

ssh-add ~/.ssh/id_ed25519

Tilføj den nye SSH-nøgle til din GitHub-konto

Kopier indholdet af SSH-nøglen (id_ed25519.pub filen) til din udklipsholder ved at indtaste:

clip < ~/.ssh/id_ed25519.pub

Det vil kopiere indholdet af din offentlige nøgle til udklipsholderen.

Login på GitHub i din webbrowser (brug Incognito hvis du er på en ekstern maskine) og klik på Settings (under dit navn i øveste højre hjørne) -> SSH og GPG nøgler -> Ny SSH nøgle. Giv nøglen en titel og indsæt den offentlige nøgle i “Key” feltet. Tryk “Add SSH key” for at tilføje nøglen.

Nu kan du bruge SSH til at interagere med GitHub.

Opret et nyt repository på GitHub

Det nemmeeste er at oprette et repository på GitHub og derefter clone det til din lokale maskine. Her er trinene:

  • Gå til GitHub (Incognito) og log ind
  • Vælg “New repository”.
  • Giv dit repository et navn, en beskrivelse og vælg om det skal være offentligt eller privat. Du bør vælge at initialisere dit repository med en README-fil og en .gitignore-fil (vælg Visual Studio på listen).

Klon dit repository til en fremmed maskine

Når du har oprettet dit repository kan du klikke på den store grønne knap på forsiden til repositoriet. Her skal du vælge at klone via SSH og kopiere URL’en til udklipsholderen.

Åbn ny en terminal og naviger til den mappe, hvor du vil klone dit repository. Indtast følgende kommando:

git clone din_repository_ssh_url

Din Windows-maskine har nu adgang til dit private GitHub-repository, og du kan både push og pull. Husk at fjerne SSH-nøglen fra din GitHub-konto, når du er færdig med at bruge den fremmede maskine.

Adgang til enkelte repos

Hvis du vil begrænse adgangen til kun et bestemt repository, kan du overveje at bruge “Deploy keys”. En “Deploy key” er en SSH-nøgle, der er knyttet til et specifikt repository i stedet for en brugerkonto, og den har kun adgang til det repository, den er knyttet til.

Her er trinnene for at tilføje en Deploy key:

  1. Generer en ny SSH-nøgle på den fremmede maskine, som du gjorde før jvf. ovennævnte
  2. Kopier den offentlige nøgle til din udklipsholder.
  3. Gå til dit repository på GitHub.
  4. Klik på “Settings” i den øverste menu.
  5. Klik på “Deploy keys” i den venstre sidebjælke.
  6. Klik på “Add deploy key”.
  7. Giv nøglen en titel, indsæt den offentlige nøgle i “Key” feltet og tryk “Add key”.

Nu vil denne nøgle kun have adgang til det specifikke repository, den er knyttet til, og ikke alle dine repositorier. Men vær opmærksom på, at en deploy key kun kan læse data som standard. Hvis du også vil kunne skrive (push) til repository, skal du markere “Allow write access” når du tilføjer nøglen.

Info

SSH (Secure Shell) og GPG (GNU Privacy Guard) er begge kryptografiske netværksprotokoller, men de bruges til forskellige formål:

  1. SSH (Secure Shell): SSH bruges til at skabe en sikker forbindelse mellem to systemer. Dette gør det muligt at eksekvere kommandoer på en fjernserver eller overføre filer mellem to systemer over en sikret forbindelse. SSH-nøgler er ofte brugt til at autentificere brugere til servere, og kan bruges til at erstatte password-baseret autentificering. Når du tilføjer en SSH-nøgle til din GitHub-konto, kan du interagere med GitHub (clone, push, pull osv.) uden at skulle indtaste dit brugernavn og password hver gang.

  2. GPG (GNU Privacy Guard): GPG er en fri implementering af OpenPGP standarden, der bruges til at kryptere og dekryptere indhold og til at skabe digitale signaturer. GPG-nøgler kan bruges til at “signere” git commits eller tags, hvilket giver en verificerbar garanti for, at det indhold, du har sendt, faktisk kommer fra dig og ikke er blevet ændret undervejs. Når du tilføjer en GPG-nøgle til din GitHub-konto, kan dine commits have en “Verified” label på GitHub.

Så mens begge er kryptografiske protokoller, bruges SSH normalt til sikre forbindelser mellem systemer og password-fri autentificering, mens GPG typisk bruges til at kryptere/dekryptere indhold og lave digitale signaturer.

Ressourcer om Git

GitHub’s Learning Lab er en god måde at lære Git og GitHub på. Det er en samling af kurser, der er designet til at hjælpe dig med at lære Git og GitHub ved at bruge GitHub. Du kan tage kurserne i dit eget tempo, og de er gratis at bruge.

Han viser det faktisk også meget godt:

Microsoft har også lavet en rigtig god Youtube serie omkring Git og brug i VS:

Spørgsmål til AI

For at få mest muligt ud af AI-værktøjer som ChatGPT, er det vigtigt at stille klare og præcise spørgsmål (og skabe det rigtige kontekst - se her). Her er nogle spørgsmål til denne side:

Grundlæggende spørgsmål til AI

  • Hvad er Git og hvorfor skal jeg bruge versionsstyring?
  • Hvad er forskellen mellem Git og GitHub?
  • Hvordan opretter jeg et nyt Git repository?
  • Hvad betyder kommandoerne git add, git commit og git push?
  • Hvad er en pull request og hvordan bruger jeg det?
  • Hvordan kloner jeg et eksisterende repository?
  • Hvad er en branch i Git og hvornår skal jeg bruge det?
  • Hvordan håndterer jeg merge konflikter?
  • Hvad er .gitignore filen til?
  • Hvad er SSH-nøgler og hvorfor bruger jeg dem med GitHub?

Reference: Git-terminologi

Som nybegynder i Git er her en oversigt over de mest almindelige begreber.

Begreb Forklaring
Repository (Repo) Et “repository” er et opbevaringssted for et software projekt. Det indeholder alle filer til projektet og holder styr på hver ændring lavet til disse filer.
Commit En “commit” er en ændring til et projekt, der er gemt i en Git repository. Den repræsenterer et øjebliksbillede af projektet på et bestemt tidspunkt. Hver commit har en unik ID (ofte kaldet en “commit hash”), som bruges til at holde styr på ændringerne.
Branch En “branch” er en parallel version af et repository. Den er adskilt fra “main” linjen af udvikling og bruges til at arbejde isoleret på en feature eller en bug fix. Når arbejdet er færdigt, kan branchen flettes tilbage til main linjen.
Merge At “merge” er at tage ændringer fra en branch og inkorporere dem ind i en anden branch. Dette er ofte hvordan du får dine ændringer ind i projektet efter du har arbejdet på dem i en separat branch.
Clone At “clone” et repository betyder at skabe en lokal kopi af et fjernrepository på din egen computer. Dette giver dig mulighed for at arbejde på projektet lokalt.
Pull “Pull” er en operation, der henter data fra en fjernserver. I Git-sammenhæng bruges “pull” til at hente den nyeste version af et repository fra en fjernserver og flette den med din lokale version.
Push “Push” er operationen, der sender dine lokale ændringer til fjernserveren. Hvis du har lavet nogle commits lokalt, som du vil dele med resten af dit team, vil du “pushe” dem til fjernserveren (for eksempel GitHub), så de bliver synlige for alle.
Fork En “fork” er en kopi af et repository. At forke et repository giver dig mulighed for at eksperimentere med ændringer uden at påvirke det originale projekt.
Pull Request En “pull request” (ofte forkortet PR) er en metode til at foreslå ændringer til et projekt på GitHub. Når du åbner en pull request, foreslår du, at dine ændringer skal flettes ind i den originale repository. Pull requests gør det muligt for andre at gennemgå og diskutere dine ændringer, før de bliver integreret i projektet.
Issue Et “issue” er en måde at holde styr på opgaver, forbedringer og bugs for dit projekt på GitHub. De kan være så simple som to-do lister, eller de kan være komplekse boards med labels, tildelinger og milestones.