Skip to content

Introduktion till Git

chilmers edited this page Jun 14, 2012 · 35 revisions

Git är ett distriburerat versionshanteringssystem (DVCS - Distributed Version Control System) vilket innebär en betydande skillnad jämfört med till exempel Subversion. Den största konceptuella skillnaden är man som utvecklare klonar original-repositoryt till sin egen maskin vilket betyder att alla har var sitt fullvärdigt repository. Det finns tekniskt sett ingen skillnad på original-repositoryt och vilket som helst av de repositoryn som finns ute på utvecklarnas maskiner. Man brukar dock bygga en hierarki där vissa repositoryn innehåller den kod som är giltig för produkten man utvecklar.

Repository-hierarkier

I open source-projekt på Github brukar det finnas ett huvud-repository för varje projekt. Detta huvudprojekt kan sedan klonas till ett eget repository (kallas Fork på Github). Detta klonade projekt (som fortfarande ligger på Github) kan sedan klonas ned på varje enskild utvecklares dator. Vill man återföra förändringar till huvudprojektet så gör man det på Github med något som heter pull requests. En pull request pekar ut ett antal förändringar i din fork som man ber huvudprojektet att merga in i sitt repository. I mindre och closed source-projekt så är det vanligt att man har ett huvudprojekt och klonar direkt från det ned till utvecklarnas datorer för att på så sätt få en lite mindre overhead än den som beskrivs ovan.

Vanliga kommandon

git clone

Klonar ett repository och lägger till en referens till original-repositoryt. Referensen till original-repositoryt läggs automatiskt till som ett fjärr-repository (kör git remote -v för att inspektera fjärrepositoryn) som får namnet origin. Det är också möjligt att ha mer än ett fjärr-repositoryn vilket är smidigt i vissa specialfall.

Exempel på använding av git clone:

git clone https://github.com/chilmers/chilmers.github.com.git

git fetch

Hämtar hem information om ändringar från ett fjärr-repository. Om inget annat anges så hämtas information från fjärr-repositoryt som heter origin. Koden på din lokala maskin förändras inte av git fetch, den hämtar information från fjärr-repositoryt och lagrar som fjärr-förändringar i ditt lokala repository. Dessa ändringar kan sedan mergas (se git merge) in i din lokala kodbas.

git merge

Sammanfogar fjärrförändringar med din lokala kodbas. Detta kommando försöker automatiskt att lyfta in förändringar från den branch på det fjärr-repository du anger. I vissa fall klarar den av att lösa upp enkla konflikter själv och i andra fall så får du en lista på konflikter som måste åtgärdas innan du kan slutföra sammanfogningen.

Exempel:

git merge origin/master

git pull

Detta kommando gör samma sak som git fetch följt av git merge origin/master

git status

Visar status för det lokala repot, vilka nya filer som lagts till, vilka ändringar som gjorts samt vad som är valt för nästa comitt och om det finns något att pusha till master-branchen på origin-fjärrrepositoryt.

git checkout -- <file>

Rullar tillbaka förändringar på en fil som ej är comittade.

git diff

Visar differensen av gjorda ändringar. Exempel som l'gger till en fil med ursprungligt innehåll och sedan uppdaterar innehållet och visar förändringen med git diff:

[~/git-repos/chilmers.github.com]$ echo "example content" > example.txt
[~/git-repos/chilmers.github.com]$ git add example.txt 
[~/git-repos/chilmers.github.com]$ git commit -m"added example.txt"
[master 12f2118] added example.txt
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 example.txt
[~/git-repos/chilmers.github.com]$ echo "other content" > example.txt
[~/git-repos/chilmers.github.com]$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   example.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[~/git-repos/chilmers.github.com]$ git diff example.txt 
diff --git a/example.txt b/example.txt
index 0bc73a7..25c05ef 100644
--- a/example.txt
+++ b/example.txt
@@ -1 +1 @@
-example content
+other content

git add

Lägger till en ändring till den aktuella ändringsmängden (change set). Man kan lägga till en eller flera ändringar innan man väljer att committa ändringsmängden. Detta ger en möjlighet att skapa fingranulära committer som enbart innehåller sammanhängande, relevanta ändringar.

git reset HEAD <file>

Tar bort en fil från aktuell förändringsmängd.

git rm

Tar bort en fil från disk och från repositoryt.

git commit

Lägger till en förändringsmängd i det lokala repositoryt.

Exempel:

git commit -m"Updated this and that to get a better something"

git push

Skickar upp committade förändringar till ett fjärr-repository, om inget annat anges så skickas förändringarna till det fjärr-repository som heter origin. Innan man gör en git push kan det vara bra att foga in eventuella ändringar från fjärr-repositoryt genom att köra git pull för att ta hand om eventuella konflikter.

Exempel

git status utan ändringar

[~/git-repos/chilmers.github.com]$ git status
# On branch master
nothing to commit (working directory clean)

git status med en ny fil

[~/git-repos/chilmers.github.com]$ echo "example content" > example.txt

[~/git-repos/chilmers.github.com]$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#	example.txt
nothing added to commit but untracked files present (use "git add" to track)

Här ser man att git säger att det finns en fil som ännu inte är versionshanterad. Man får också ett förslag på hur man kan hantera filen med git add.

git status efter att ha lagt till en ändring

[~/git-repos/chilmers.github.com]$ git add example.txt

[~/git-repos/chilmers.github.com]$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   example.txt
#

Nu ser vi att det finns en förändring att committa till det lokala repositoryt. Man kan nu lägga till fler förändringar innan man väljer att comitta eller committa direkt.

git statusefter att ha lagt till ytterligare en fil för committ och comittat ändringarna.

[~/git-repos/chilmers.github.com]$ git add example2.txt
[~/git-repos/chilmers.github.com]$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	new file:   example.txt
#	new file:   example2.txt
#
[:~/git-repos/chilmers.github.com]$ git commit -m"Added example files"
[master a868e31] Added example files
 2 files changed, 2 insertions(+), 0 deletions(-)
 create mode 100644 example.txt
 create mode 100644 example2.txt
[~/git-repos/chilmers.github.com]$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)

git statusefter att ha ändrat en befintlig fil

[~/git-repos/chilmers.github.com]$ echo "other content" > example.txt

[~/git-repos/chilmers.github.com]$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   example.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

Committa förändring och pusha till fjärr-repository

[~/git-repos/chilmers.github.com]$ git add example.txt 
[~/git-repos/chilmers.github.com]$ git commit -m"Updated content of example file number one"
[master ba13412] Updated content of example file number one
 1 files changed, 1 insertions(+), 1 deletions(-)

[~/git-repos/chilmers.github.com]$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 2 commits.
#
nothing to commit (working directory clean)

[~/git-repos/chilmers.github.com]$ git push
Username:
Password:
Counting objects: 8, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (7/7), 649 bytes, done.
Total 7 (delta 1), reused 0 (delta 0)
To https://github.com/chilmers/chilmers.github.com.git
   a6e6125..ba13412  master -> master

[~/git-repos/chilmers.github.com]$ git status
# On branch master
nothing to commit (working directory clean)

Ta bort exempelfilerna

[~/git-repos/chilmers.github.com]$ git rm example.txt 
rm 'example.txt'
[~/git-repos/chilmers.github.com]$ git rm example2.txt 
rm 'example2.txt'

[~/git-repos/chilmers.github.com]$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#	deleted:    example.txt
#	deleted:    example2.txt
#

[~/git-repos/chilmers.github.com]$ git commit -m"Removed example files"
[master 092a267] Removed example files
 2 files changed, 0 insertions(+), 2 deletions(-)
 delete mode 100644 example.txt
 delete mode 100644 example2.txt
[~/git-repos/chilmers.github.com]$ git push
Username:
Password:
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 242 bytes, done.
Total 2 (delta 1), reused 0 (delta 0)
To https://github.com/chilmers/chilmers.github.com.git
   ba13412..092a267  master -> master

Lägg till fil med innehåll, uppdatera och använd git diffför att visa förändringen

Exempel som l'gger till en fil med ursprungligt innehåll och sedan uppdaterar innehållet och visar förändringen med git diff:

[~/git-repos/chilmers.github.com]$ echo "example content" > example.txt
[~/git-repos/chilmers.github.com]$ git add example.txt 
[~/git-repos/chilmers.github.com]$ git commit -m"second round"
[master 12f2118] second round
 1 files changed, 1 insertions(+), 0 deletions(-)
 create mode 100644 example.txt
[~/git-repos/chilmers.github.com]$ echo "other content" > example.txt
[~/git-repos/chilmers.github.com]$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#	modified:   example.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
[~/git-repos/chilmers.github.com]$ git diff example.txt 
diff --git a/example.txt b/example.txt
index 0bc73a7..25c05ef 100644
--- a/example.txt
+++ b/example.txt
@@ -1 +1 @@
-example content
+other content

Git i Eclipse

Om man vill integrera Git i Eclipse istället för att enbart arbeta med Git från kommandoraden så finns det en plugin att installera. Starta Eclipse, Gå till Help-menyn -> Eclipse Marketplace... Sök på git och välj install på EGit - Git Team Provider och följ sedan instruktionerna för att installera.

Det finns också en GitHub Mylyn connector om man vill arbeta med githubs issue tracking direkt i Eclipse.

När EGit är installerat går det att högerklicka på ett projekt, välja Team/Share Project... och sedan välja Git ut listan. I nästa steg väljer man Use or create repository in parent folder of project.

Fortsättning

Om du vill få en riktig kickstart in i Git-världen rekommenderar jag att kolla in tutorialen nedan.

Tutorial hos Callista Enterprise: Tutorial - Introduktion till distribuerad versionshantering med Git

Den officiella git-dokumentationen