Enhver innføring i terminalen forutsetter ett verktøy før alle andre: git. Installeringsguidene begynner med «clone the repository», og før eller siden står det en terminal der og venter på at du skal kunne git. Denne guiden holder seg bevisst frakoblet: det felles lagrepunktet lenger ut er en mappe på din egen disk, ingen hostingtjeneste er involvert. Alt nedenfor er kjørt på git 2.53.0 (Ubuntu 26.04) og 2.56.0 (Fedora 44, Arch), identisk på begge versjoner.
Hva git faktisk gjør
git er en protokollfører. Peker du den på en mappe, kan den ta et
snapshot av hele mappen, nøyaktig slik den ligger, når som helst du ber
om det. Hvert snapshot er en commit med et kort navn som bc11b6c, og
samlet lar commitene deg gå tilbake til enhver tidligere tilstand:
lagrepunkter, i spilleforstand. Et repository er bare en mappe med en
.git-katalog inni seg, og hver commit lagrer hele prosjektet, så du kan
rekonstruere tirsdag morgen og ikke bare filen du angrer på at du rørte.
Installer og presenter deg
Sjekk med git --version om det er der. På Ubuntu betyr dette noe:
serverbildet avhenger av git, så en server har det alltid, men en fersk
skrivebords- eller minimalinstallasjon mangler det. Fedoras
workstation-sett merker det som en standardpakke, og Archs lille
base-sett tar det ikke med. Mangler den:
$ sudo apt install git # Ubuntu, Debian
$ sudo dnf install git # Fedora
$ sudo pacman -S git # Arch
Før første commit vil git vite hvem du er. Den stempler et navn og en adresse inn i hver commit, slik at en historie fortsatt betyr noe når flere personer har skrevet deler av den:
$ git config --global user.email "[email protected]"
$ git config --global user.name "Vera Flyer"
Adressen blir ikke sjekket mot noe, og git sender aldri post til noen.
Den hogger bare det du taster inn i hver commit. Begge innstillingene
lander i ~/.gitconfig, og --global gjør at de gjelder for hvert
repository på denne maskinen.
Kjører du en commit uten identitet på fil, stopper git deg. Verdt å se én gang:
Author identity unknown
*** Please tell me who you are.
Run
git config --global user.email "[email protected]"
git config --global user.name "Your Name"
to set your account's default identity.
Omit --global to set the identity only in this repository.
fatal: unable to auto-detect email address (got 'you@mycomputer.(none)')
Den siste linjen innrømmer at git prøvde å gjette en adresse ut fra vertsnavnet og ga opp.
Ditt første repository
Enhver mappe kan bli et repository. Lag én og slå på git:
$ mkdir projects
$ cd projects
$ git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: will change to "main" in Git 3.0. To configure the initial branch name
hint: to use in all of your new repositories, which will suppress this warning,
hint: call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
hint:
hint: Disable this message with "git config set advice.defaultBranchName false"
Initialized empty Git repository in /home/you/projects/.git/
Hintene kaller branchen master og sier at denne standarden endres til
«main» i Git 3.0. Det er gits ordlyd, ikke et løfte om at navnet varer,
så les main der denne guiden skriver master når den dagen kommer.
Linjen som betyr noe, kommer sist: repositoryet finnes, i
.git-katalogen git nettopp opprettet. Spør den hvordan det går:
$ git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
Hvert ord der er vokabular: tre tilstander, tre ord. En fil er
untracked når git ser den, men du ikke har bedt git om å føre
protokoll over den, staged når git add har markert tilstanden dens
for neste commit, og committed når det finnes et snapshot som
inneholder den. git status er kartet over hvor hver fil står.
Den daglige løkken
Løkken du kommer til å taste tusen ganger, er add, så commit. Start med en navngitt fil, og la deretter prikken overta:
$ echo "backup plan: rsync to the Pi" > notes.txt
$ git add notes.txt
$ git commit -m "First commit"
[master (root-commit) bc11b6c] First commit
1 file changed, 1 insertion(+)
create mode 100644 notes.txt
$ mkdir src
$ echo "# Scripts" > README.md
$ git add .
$ git commit -m "Add src and readme"
$ git log --oneline
09aecf2 Add src and readme
bc11b6c First commit
$ git log
commit 09aecf24b6f75067a6453a79752811861fb847d3
Author: Vera Flyer <[email protected]>
Date: Mon Oct 12 07:15:35 2026 +0000
Add src and readme
git add stager og flytter en fil til kartets mellomtilstand. Prikken
stager alt som ligger løst, og det er slik søppel sniker seg inn i
historien (avsnittet om ignorering har filteret). Tomme kataloger er
usynlige for git, så src kommer inn i historien bare gjennom filene
sine. git commit -m fotograferer alt som er staget, og den første
commiten er en root-commit med utdata som navngir branchen og den nye
korte hashen. --oneline klemmer hver commit inn til hash og melding,
nyeste først, og fullformen legger til forfatteren og datoen konfigen
din stemplet inn. Hashene her tilhører testkjøringen. Dine er
annerledes hver gang, og det er normalt. Én runde til, nå med redigering
av en eksisterende fil:
$ nano notes.txt
$ git add notes.txt
$ git commit -m "Edit notes"
[master dc6d8fc] Edit notes
1 file changed, 1 insertion(+), 1 deletion(-)
Sammendraget teller nå slettinger også. Det er hele løkken: git status
for å se, git add for å stage, git commit -m for å føre på
protokoll, git log for å lese tilbake.
Se på endringer
Tre vinduer mot endring, ved tre anledninger. git diff skriver ut
redigeringene du har gjort, men ennå ikke staget, arbeidet en commit
akkurat nå ville utelate. git diff --staged skriver ut den andre
halvdelen: alt en commit akkurat nå ville tatt med. Før du committer,
forteller den første deg hva du lar ligge igjen, og den andre hva du
skriver ned. git show HEAD skriver ut selve nyeste commit, melding og
endringer sammen, der HEAD er gits kortform for nettopp den nyeste
commiten.
Angre ting
Kommandoen du vil ønske deg mest, er også den du skal håndtere med
forsiktighet. git restore FILE setter en fil tilbake til sin sist
registrerte tilstand og kaster bort redigeringene du ikke har committet.
Dette sletter arbeidet ditt, og det finnes ingen papirkurv å fiske det
ut av. På en fil git aldri har sett, nekter den å gjette:
$ echo "scrapped plan" > notes.txt
$ git restore notes.txt
$ git restore extra.txt
error: pathspec 'extra.txt' did not match any file(s) known to git
Skaden er borte, og notes.txt leser seg slik den gjorde ved siste
commit. Feilmeldingen er nøyaktig: restore virker på filer git kjenner,
og extra.txt kom aldri inn i en commit eller en add. Ett punkt med
liten skrift: som standard henter restore kopien sin fra
staging-området, ikke fra siste commit. Er ingenting staget, er de to
like, og det er derfor den enkle beskrivelsen holder. En halvstaget fil
gjør dem ulike, og den blandingen er der manualen begynner.
Den milde undoen ruller tilbake en staging-beslutning. Du kjørte
git add TODO.md i fart og bestemte deg for at filen ikke er klar.
git restore --staged TODO.md angrer nøyaktig det. Bare stagingen
forsvinner. Redigeringene blir liggende på disken, og neste commit
slutter bare å ta dem med. Der vanlig restore kaster arbeid bort, endrer
--staged meningen din.
Den tredje undoen reparerer selve commiten. Commit en liste med ett element, og kom så på det andre elementet:
$ echo "milk" > list.txt
$ git add list.txt
$ git commit -m "Add list with one item"
$ echo "eggs" >> list.txt
$ git add list.txt
$ git commit --amend -m "Add list with two items"
[master 70a66be] Add list with two items
Date: Mon Oct 12 07:17:57 2026 +0000
1 file changed, 2 insertions(+)
create mode 100644 list.txt
--amend erstatter nyeste commit med en ny, bygget fra den gamle
commiten pluss det som er staget nå. Hashen er ny, 70a66be, for dette
er en annen commit som bærer den korrigerte meldingen. Den skriver til
og med ut en Date:-linje, noe en vanlig commit aldri viser. Amend
omskriver historien, så å gjøre det mot noe som allerede er pushet,
omskriver historie som andre kopier kan holde. Amend er for commits som
fortsatt er helt dine.
Branches uten frykt
En branch er et navn på en arbeidslinje, og fire kommandoer dekker det.
git branch feature oppretter én og sier ingenting (i git betyr
stillhet at det gikk bra), mens git branch alene lister dem alle og
merker der du står med en stjerne:
$ git branch feature
$ git branch
feature
* master
Ingenting flyttet seg: å opprette en branch skrev bare navnet ned. Å
bytte er et eget steg, og -c oppretter og bytter i én bevegelse:
$ git switch feature
Switched to branch 'feature'
$ git switch -c hotfix
Switched to a new branch 'hotfix'
Meldingene skiller seg med to ord. Eldre tutorialer skriver
git checkout for dette. git switch er den moderne erstatteren, og
begge skriver ut Switched to a new branch 'NAME'. Nå kommer gevinsten.
Commit på en branch, vend tilbake til master, merge:
$ echo "new thing" > feature.txt
$ git add feature.txt
$ git commit -m "Add feature"
$ git switch master
Switched to branch 'master'
$ git merge feature
Updating dc6d8fc..f4354cb
Fast-forward
feature.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 feature.txt
Fast-forward er det glade tilfellet: master lagde ingen egne commits
mens feature var ute, så mergen skyver master opp til features nyeste
commit. Updating-linjen navngir de to posisjonene som hasher.
Én vegg er ekte: endret begge branches de samme linjene i samme fil, stopper git mergen og ber deg bestemme hva resultatet skal si. Å redde ut den knuten, en mergekonflikt, er en ferdighet for seg og utenfor denne guiden.
Ignorere filer
Enhver arbeidsmappe samler filer som er dine, men ikke prosjektets:
logger fra testkjøringer, byggutdata, editorrester. En .gitignore i
repositoryroten lister opp det git skal se bort fra:
# test runs leave these behind
*.log
build/
Linjer som begynner med # er kommentarer, *.log matcher alle navn
som slutter på .log, og build/ med skråstreken bakerst matcher
byggkatalogen.
Nå til fellen: .gitignore påvirker bare filer git ikke allerede
sporer. Commit debug.log, og skriv *.log etterpå, og git fortsetter
å spore den som om ingenting hendte. Redigeringer dukker fortsatt opp
som endringer og seiler inn i hver commit, mens en helt ny logg ved
siden av ville blitt ignorert. Listen styrer hva git plukker opp
fremover. Den gjør ingenting usett.
Å få git til å glemme en fil den sporer, krever git rm --cached FILE,
som slutter å spore den og lar filen ligge på disken. For i dag er det
nok å vite at fellen finnes.
Remotes på egen disk
Ekte team lar det delte repositoryet sitt ligge hos en hostingtjeneste, og de samme kommandoene kjører mot en URL i stedet for en bane når du blir med i en. Å bli på egen disk er poenget: det lærer deg grepene, og et lagrepunkt på en ekstern stasjon er en ekte sikkerhetskopi.
Pusher du til en vanlig mappe, nekter git:
remote: error: refusing to update checked out branch: refs/heads/master
To /tmp/vfygit/demo
! [remote rejected] master -> master (branch is currently checked out)
error: failed to push some refs to '/tmp/vfygit/demo'
(remote:-linjene bærer etterfølgende mellomrom i ekte utdata, fjernet
her, og gits nektelsesmelding fortsetter utover dette utdraget.)
Grunnen står i første linje: branchen i målet er checked out, så det
kan stå noen i den mappen og redigere akkurat de filene et push
ville erstattet. git beskytter den arbeidskopien.
Fiksen er et bart repository: ingen arbeidstre, ingen som redigerer
inni det, ingenting å beskytte, pushes er velkomne. Etter konvensjon
slutter navnet på .git. Fem linjer utgjør hele den frakoblede
arbeidsflyten:
git init --bare /path/to/savepoints.git # the shared save point (bare = no working tree, accepts pushes)
git remote add origin /path/to/savepoints.git
git push -u origin master
git clone /path/to/savepoints.git
git pull
origin er et kallenavn for den banen, ikke mer. -u på første push
ber git huske koblingen, så hver push etter den kan være en vanlig
git push. En første push fra testkjøringen, med tomt lagrepunkt:
To /tmp/vfygit/savepoints.git
* [new branch] master -> master
branch 'master' set up to track 'origin/master'.
Sporingslinjen er -u som gjør jobben sin: origin/master er posten
din over hvor master befinner seg på lagrepunktet. Pusher du igjen uten
noe nytt, er svaret kort: Everything up-to-date.
En annen maskin, eller en annen mappe på den samme, starter fra lagrepunktet med clone, og git har allerede skrevet ned hvor kopien kom fra:
$ git clone /tmp/vfygit/savepoints.git laptop
Cloning into 'laptop'...
done.
$ git remote -v
origin /tmp/vfygit/savepoints.git (fetch)
origin /tmp/vfygit/savepoints.git (push)
Commiten som kommer inn, ble redigert, addet, committet og pushet fra
den første mappen, så denne pullen har noe å hente. Pullens
From-linje skriver ut banen uten .git, mens git remote -v viser
den med:
$ git pull
From /tmp/vfygit/savepoints
347bcf7..9723a2e master -> origin/master
Updating 347bcf7..9723a2e
Fast-forward
notes.txt | 2 ++
1 file changed, 2 insertions(+)
Pull hentet den nyeste tilstanden og foldet den inn. Fast-forward igjen,
for denne klonen hadde ikke laget noen egne commits. Er ingenting i vente:
Already up to date.
To fotnoter. De samme kommandoene virker mot you@server:/path/repo.git
over SSH. SSH-guiden dekker
nøkkelautentisering. Og receive.denyCurrentBranch=updateInstead lar et
ikke-bart repository ta imot pushes og oppdatere arbeidstreet sitt.
Avslutningsprosjekt — en versjonert skriptmappe
Kjør hele buen i én omgang. Materialet er skriptene fra
bash-skriptguiden: den
voksne backup.sh, pluss check.sh-utdraget fra guidens testseksjon,
for planlagte skript er det første som er verdt å versjonere.
Automatiseringskapittelet er
der de møter cron.
Lagre den endelige backup.sh fra den guiden i en ny ~/scripts-mappe
først, og presenter deg som i installasjonsavsnittet hvis denne
maskinen ikke har møtt deg før. Så:
$ cd ~/scripts
$ git init
$ git add backup.sh
$ git commit -m "Track the backup script"
[master (root-commit) 730adaa] Track the backup script
1 file changed, 19 insertions(+)
create mode 100644 backup.sh
Nytt arbeid legges på en branch først, alltid. Opprett én, lagre
guidens check.sh i mappen, stage, commit, og fold deretter branchen
tilbake inn i master:
$ git switch -c add-check
Switched to a new branch 'add-check'
$ git add check.sh
$ git commit -m "Add check script"
$ git switch master
Switched to branch 'master'
$ git merge add-check
Updating 730adaa..127d7c0
Fast-forward
check.sh | 5 +++++
1 file changed, 5 insertions(+)
create mode 100644 check.sh
Med skriptene inne, vokt deg mot søppel før det finnes noe: en
.gitignore med mønstrene fra avsnittet om ignorering, laget med nano.
Commit den så:
$ git add .gitignore
$ git commit -m "Ignore test logs"
[master dcf3ec5] Ignore test logs
1 file changed, 3 insertions(+)
create mode 100644 .gitignore
Siste steg, selve lagrepunktet. Et bart repository på samme disk er en fotokopi i det samme brennende bygget, men riktig form for en ekstern stasjon eller en annen maskin:
$ git init --bare /home/you/savepoints.git
$ git remote add origin /home/you/savepoints.git
$ git push -u origin master
To /home/you/savepoints.git
* [new branch] master -> master
branch 'master' set up to track 'origin/master'.
$ git push
Everything up-to-date
Det andre pushet beviser at lagrepunktet stemmer med mappen. Fra hvor
som helst annet henter git clone /home/you/savepoints.git work ned
alle tre commitene, og git pull holder dem oppdaterte.
Hvor du står nå
Du kan versjonere en mappe fra ende til annen: init, add, commit,
branch, merge, restore, ignorere, og pushe til et bart repository på
egen disk. Fire vaner bærer det meste av vekten. Kjør git status når
du er usikker, og git diff --staged før du committer. Rekk etter
restore --staged før vanlig restore når du hadde tenkt å beholde
arbeidet. Og amend aldri en commit som allerede er pushet.
Bevisst hoppet over: mergekonflikter, git stash, hostingplattformer og
alt som følger med dem, og gits dypere historiekirurgi. Alt venter til
et ekte prosjekt krever det.
To referanser, begge offisielle og stabile:
- Git-dokumentasjonen — manualen for hver kommando brukt her
- Pro Git — hele boken, gratis å lese på nett