Git: Difference between revisions

From Peters wiki
Jump to navigation Jump to search
Created page with "__NOTOC__ __NUMBEREDHEADINGS__ This article describes some use-cases with [http://www.gitscm.org/ Git]. __TOC__ == Configure == Configurations can be global or per reposi..."
 
mNo edit summary
 
(67 intermediate revisions by the same user not shown)
Line 1: Line 1:
__NOTOC__
__NOTOC__
__NUMBEREDHEADINGS__


This article describes some use-cases with [http://www.gitscm.org/ Git].
Denna artikel beskriver några kommandon och användarfall med [http://www.gitscm.org/ git].


__TOC__
__TOC__
   
   
== Configure ==
== Inställningar ==


Configurations can be global or per repository (saved inside the .git folder in your repo). The global settings are saved in ~/.gitconfig. You can always look and edit your ~/.gitconfig file manually, or use the {{Ic|git config --global}} command. Some examples how to set, unset or get settings:
Git inställningar kan var global eller per repository (sparade under .git mappen i ett repository). Globala inställningar är sparade i filen ~/.gitconfig. Det går att läsa och editera filen ~/.gitconfig manuellt, eller använda kommandot {{Ic|git config --global}}. Några exempel hur man sätter, tar bort och läser inställningar:
{{Cmd|git config --global core.pager cat|git config --global --unset core.pager|git config --global --get core.pager}}
{{Cmd|git config --global core.pager cat|git config --global --unset core.pager|git config --global --get core.pager}}


{{Note|Repository settings are only temporary stored in the repository. They are e.g. not included when you clone a repository.}}
{{Note|Inställningar sparade i repositoryt är bara temporära. Dom inkluderas inte när du t.ex. klonar ett repository.}}


=== Who are you? ===
=== Vem är du? ===


Setup your name and email address:
Ställ in namn och email adress:
{{Cmd|git config --global user.name "Your Name"|git config --global user.email your_email@whatever.com}}
{{Cmd|git config --global user.name "Förnamn Efternamn"|git config --global user.email fornamn.efternamn@exempel.com}}


=== Pager ===
=== Pager ===


You can specify which pager (e.g. more, less, cat) Git should use. Run this if you want to use cat:
Du kan välja vilken 'pager' (t.ex. more, less, cat) Git ska använda. Kör detta kommando om du vill att Git ska använda cat:
{{Cmd|git config --global core.pager cat}}
{{Cmd|git config --global core.pager cat}}


=== Pretty log ===
=== Snyggare log ===


To create aliases in Git, like a compact log when running 'git hist', run:
För att skapa alias i Git, som t.ex. att skriva ut en kompakt och snygg log med kommandot {{Ic|git hist}}, kör kommandot:
{{Cmd|<nowiki>git config --global alias.hist 'log --pretty=tformat:"%h %ad | %s%d [%an]" --graph --date=short'</nowiki>}}
{{Cmd|<nowiki>git config --global alias.hist 'log --pretty=tformat:"%h %ad | %s%d [%an]" --graph --date=short'</nowiki>}}
tformat has been used instead of format to get the ending carriage return in case you use cat as your pager. The output from 'git hist' will look like this:
Vi använder tformat istället för format för att få med ett avslutande 'carriage return' ifall du använder cat som din pager. Utskriften från {{Ic|git hist}} kommer att se ut så här:
{{Bc|
{{Bc|
<nowiki>* 40ec614 2012-12-10 | The best commit ever (HEAD, master) [erakerw]
<nowiki>* 40ec614 2012-12-10 | The best commit ever (HEAD, master) [Peter Kerwien]
* 4b732d0 2012-12-10 | Initial commit [erakerw]</nowiki>
* 4b732d0 2012-12-10 | Initial commit [Peter Kerwien]</nowiki>
}}
}}


== Repository ==
== Repository ==


=== Skapa ett repository ===
 
=== Create repo ===
 
To create a git repository in a non-existing directory:


För att skapa ett repository i en icke-existerande katalog, kör:
{{Cmd|git init repo}}
{{Cmd|git init repo}}
 
Eller om du vill skapa ett repository i nuvarande katalog:
Or if you want to create a repository in the already existing directory:
 
{{Cmd|cd <path>/repo|git init}}
{{Cmd|cd <path>/repo|git init}}
 
Båda kommandona kommer skapa en dold katalog som heter .git. Dessa repositoryn kan också innehålla filerna som man jobbar med dvs ett 'workspace'. Om du vill skapa ett repository som ska fungera som ett centralt repository eller dela mellan flera användare och alla ska kunna pusha till repositoryt så måste man skapa ett s.k. bare repository. Ett bare repository saknar workspace och alla git-filer ligger synliga direkt i repositoryt och inte i en katalog som heter .git. För att skapa ett bare repository, kör::
Both commands will create a hidden directory named .git. These kind of repositories can also have a working tree, i.e. a workspace. If you want to create a repository and only use it as a central or shared repository between users, you should create a bare repository. A bare repository does not have a working tree, and all administration files are visible and not placed in a .git directory. To create a bare repository run:
 
{{Cmd|git init --bare repo.git}}
{{Cmd|git init --bare repo.git}}
Namnkonventionen är att bare repositorys slutar med ändelsen .git i namnet.


The naming convention for bare repositories is to add .git in the end of the name.
=== Klona ett repository ===
 
=== Clone repo ===
 
To clone a repository, i.e. to get a copy of all its versions, run the command:


För att klona ett repository, dvs skapa en kopia av alla dess versioner, kör:
{{Cmd|git clone repo dir}}
{{Cmd|git clone repo dir}}
 
Det spelar ingen roll om du klonar ett vanligt eller bare repository, du kommer få en klon med ett workspace. Men om du vill klona utan ett workspace, kör kommandot:
It does not matter if you clone a regular or bare repository, you will get a clone with a working tree. However, if you want a clone, and that clone should not have a working tree, then do a bare clone:
 
{{Cmd|git clone --bare repo dir}}
{{Cmd|git clone --bare repo dir}}
Din klon med namnet dir kommer nu inte innehålla något workspace.


Your clone in dir will now be a bare repository.
== Rensa workspace ==
 
 
== Clean working directory ==
 
 
Your working directory will after some work, contain both version controlled files, modified files but also generated files, backup files etc. Some of the non-version controlled files are listed with the {{Ic|git status}} command, but many files could be ignored via so called .gitignore files. To clean your whole working directory from non-version controlled files, go to the top-directory in the repo, and run:
 
{{Cmd|git clean -fdx}}
 
The command will remove all non-version controlled files, i.e. even ignored files. Use the -n option to just list which files the command will remove.
 
 
== Track, commit and untrack changes ==


   
Efter en del arbete kommer ditt workspace innehålla versionshanterade, ändrade men också genererade och backup-filer. En del av de icke-versionshanterade filerna listas med {{Ic|git status}}, men en del filer ignoreras via en .gitignore fil. För att rensa hela ditt workspace från alla icke-versionshanterade inklusive ignorerade filer, gå till toppen av repositoryt och kör:
  {{Cmd|git clean -fdx}}
Använd -n optionen för att endast lista vilka filer som skulle ha raderats.


=== Track changes ===
== Versionshantera, komitta och sluta versionshantera förändringar ==


To add one or several files to git, run:
=== Versionshantera förändringar ===


För att addera en eller flera filer till git, kör:
{{Cmd|git add <pattern>}}
{{Cmd|git add <pattern>}}
 
Om en fil redan versionshanteras, kommer kommandot att addera förändringar till index. Om du vill addera alla gjorda förändringar till index, kör kommandot:
If a file is already tracked, the command will add the changes to the index. If you want to add all changes made to already tracked files to the index, run:
 
{{Cmd|git add -u}}
{{Cmd|git add -u}}


=== Commit:a förändringar ===
 
=== Commit changes ===
 
To commit changes added to the index, run:


För att commit:a förändringar redan adderade till index, kör:
{{Cmd|git commit -m "Commit message"}}
{{Cmd|git commit -m "Commit message"}}
 
Om man vill commit:a alla ändringar som är gjorda i redan versionshanterade filer, men ej adderade till index, kör kommandot:
If you also want to commit all changes made in already tracked files, but not yet added to the index, run:
 
{{Cmd|git commit -am "Commit message"}}
{{Cmd|git commit -am "Commit message"}}


=== Sluta versionshantera förändringar ===
 
=== Untrack changes ===
 
To remove one or several files from the working tree and index, run:


För att ta bort en eller flera filer från workspace och index, kör kommandot:
{{Cmd|git rm <pattern>}}
{{Cmd|git rm <pattern>}}
Filerna kommer att tas bort från repositoryt när du commit:ar till repositoryt.


The files will be removed from the repository when you do the commit.
== Diff ==
 
 
== Diff changes ==
 
 
=== Diff working directory ===


To look at the changes you have in your working directory which are not yet added to the index, run the command:
=== Diff:a workspace mot index ===


För att lista förändringar du har gjort i workspace, men som inte än är adderade till index, kör kommandot:
{{Cmd|git diff}}
{{Cmd|git diff}}


För att lista förändringar mellan ditt index och HEAD, dvs versionen du ser i repositoryt, kör kommandot:
 
To look at the changes between your index and HEAD, run:
 
{{Cmd|git diff --cached}}
{{Cmd|git diff --cached}}


Om du vill se alla dina icke-commit:ade förändringar (både adderade till index eller inte), kör kommandot:
 
If you want to see all your non-committed changes (staged and non-staged), run:
 
{{Cmd|git diff HEAD}}
{{Cmd|git diff HEAD}}


==== Använda meld som grafiskt diff-verktyg ====


==== Graphical diff using meld ====
För att använda meld som diff-verktyg när man kör kommandot {{Ic|git difftool -g}} kör följande kommandon:
{{Cmd|git config --global diff.tool meld|git config --global difftool.prompt false}}


If you have set up meld as your graphical diff-tool (See [[BBI Git#Using meld as graphical diff and merge tool (Optional)]]), you can perform graphical diff by running:
Man kan nu få upp grafiska jämförelser mellan versioner m.m. genom kommandot:
{{Cmd|git difftool}}
Ersätt {{Ic|git diff}} med {{Ic|git difftool}} i exemplen ovan. En diff med meld kan se ut så här:


{{Cmd|git difftool -g}}
[[File:meld-diff1.png|500px]]


Just replace {{Ic|git diff}} with {{Ic|git difftool -g}} in the examples above. A diff with meld can look like this:
(Äldre versionen visas till vänster och den nya till höger.)


=== Diff:a commits ===
 
[[Image:meld-diff1.png|500px]]
 
 
(To the left we have the original version and to the right our modified Makefile).
 
 
=== Diff commits ===
 
Assume we have the following history:


Antag att vi har följande historia:
{{Bc|<nowiki>
{{Bc|<nowiki>
 
* 2634685 2012-12-18 | Commit 4 (HEAD, master) [Peter Kerwien]
* 2634685 2012-12-18 | Commit 4 (HEAD, master) [erakerw]
* d0afcbd 2012-12-18 | Commit 3 [Peter Kerwien]
 
* aaa2574 2012-12-18 | Commit 2 [Peter Kerwien]
* d0afcbd 2012-12-18 | Commit 3 [erakerw]
* b61568c 2012-12-18 | Initial commit [Peter Kerwien]
 
* aaa2574 2012-12-18 | Commit 2 [erakerw]
 
* b61568c 2012-12-18 | Initial commit [erakerw]
 
</nowiki>}}
</nowiki>}}


To look at the changes made in Commit 2 to 3 you can run:
För att visa alla förändringar mellan commit 2 och 3, kör:
 
{{Cmd|git diff b61568c d0afcbd}}
{{Cmd|git diff b61568c d0afcbd}}
 
Du kan också köra kommandot:
Or you can also run:
 
{{Cmd|git diff HEAD~3 HEAD~1}}
{{Cmd|git diff HEAD~3 HEAD~1}}


== Välja revision ==
 
== Revision Selection ==
 
 
=== Ancestry References ===


Assume we have the following history:
=== Släkt-referenser ===


Antag att vi har följande historia:
{{Bc|<nowiki>
{{Bc|<nowiki>
 
* 5b38862 2013-01-16 | Commit 5 (HEAD, master) [Peter Kerwien]
* 5b38862 2013-01-16 | Commit 5 (HEAD, master) [erakerw]
*  9940a50 2013-01-16 | Commit 4 [Peter Kerwien]
 
*  9940a50 2013-01-16 | Commit 4 [erakerw]
 
|\  
|\  
 
| * fc796ce 2013-01-16 | Commit on test (test) [Peter Kerwien]
| * fc796ce 2013-01-16 | Commit on test (test) [erakerw]
* | f7935db 2013-01-16 | Commit 3 [Peter Kerwien]
 
* | f7935db 2013-01-16 | Commit 3 [erakerw]
 
|/  
|/  
 
* dc53825 2013-01-16 | Commit 2 [Peter Kerwien]
* dc53825 2013-01-16 | Commit 2 [erakerw]
* bea9676 2013-01-16 | Initial commit [Peter Kerwien]
 
* bea9676 2013-01-16 | Initial commit [erakerw]
 
</nowiki>}}
</nowiki>}}


Istället för att ange hela hashen för att välja version, kan man ange släkt-referenser genom att addera ^ eller ~ efter versionen. HEAD^ betyder den första föräldern till HEAD (=9940a50). Commit:en 9940a50 har två föräldrar, därför väljer 9940a50^ den föräldern som finns på nuvarande branch. Om vi är på master så kommer 9940a50^ välja commit:en f7935db. 9940a50^2 kommer välja den andre föräldern, i detta fall fc796ce. Man kan också lägga till flera ^ efter varandra. HEAD^^ kommer välja commit f7935db.
 
Instead of using the full hash to select version, you can use ancestry references by adding ^ and ~ after the version. HEAD^ means the first parent to HEAD (=9940a50). The commit 9940a50 however has two parents, so 9940a50^ will select the one on current branch. If we are master, 9940a50^ will select the commit f7935db. 9940a50^2 will select the second parent, in this case fc796ce. You can also add several ^ after each other. HEAD^^ will select the commit f7935db.
 
 
~ always means the first parent of a commit. So HEAD~ and HEAD^ means the same thing. However, HEAD~2 means the ''first parent of the first parent'', so 9940a50~2 selects the commit dc53825, which is not the same as 9940a50^2.
 
 
You can combine these two into something like HEAD~^2. This means ''the second parent of the first parent of HEAD'' i.e. the commit fc796ce.
 


== Undo ==
~ däremot betyder alltid den första föräldern av en commit. Så följande exempel väljer alltid samma commit:
* HEAD^ och HEAD~
* HEAD^^^ och HEAD~3
HEAD~2 betyder "första föräldern till första föräldern", så 9940a50~2 väljer commit:en dc53825. Detta är inte samma sak som 9940a50^2.


{{Note|Do not change or remove commits that you have shared with someone. It is only safe to re-write history if it only affects yourself.}}
Man kan kombinera dessa två, t.ex. HEAD~^2. Detta betyder "den andra föräldern till den första föräldern till HEAD", dvs commit:en fc796ce.


== Ångra och ändra ==


=== Undo not yet staged change ===
{{Note|Ändra inte eller ta bort commit:s som du redan har delat med andra. Det är bara säkert att ändra historien om det bara påverkar dig själv.}}


To undo changes that you have not yet been staged, run:
=== Ångra ändringar som inte har adderats till index ===


För att ångra ändringar som inte har adderats till index, kör kommandot:
{{Cmd|<nowiki>git checkout -- <file></nowiki>}}
{{Cmd|<nowiki>git checkout -- <file></nowiki>}}


=== Ångra ändringar som har adderats till index ===
 
=== Undo a staged change ===
 
To undo staged changes, run:


För att ångra ändringar som har adderats till index, kör:
{{Cmd|<nowiki>git reset HEAD <file></nowiki>}}
{{Cmd|<nowiki>git reset HEAD <file></nowiki>}}
Reset kommandot återställer index till vad som pekas ut av HEAD. Reset kommandot återståller inte workspace. Så workspace kan fortfarande innehålla oönskade ändringar.


The reset command resets the staging area to be whatever is in HEAD. This clears the staging area of the change we just staged. The reset command (by default) doesn’t change the working directory. So the working directory still has the unwanted comment in it.
=== Rätta senaste commit ===
 
 
=== Correct the last commit ===
 
If you realize that something was missing in the last commit and you do not want to make another, you can correct your mistakes and then run:


Om du upptäcker att någonting saknas i den senaste commit:en och du vill inte göra en ny, då kan du rätta till ditt misstag med kommandot:
{{Cmd|git commit --amend -m "..."}}
{{Cmd|git commit --amend -m "..."}}
Du måste dock först addera vad du saknade till index innan du kör kommandot ovan.


=== Ångra en commit ===
 
=== Undo a commit ===
 
To undo a committed change, we need to generate a commit that removes the changes introduced by our unwanted commit. To revert last commit run:


För att ångra en commit kan vi skapa en commit som tar bort dom förändringar som gjordes i den oönskade commit:en. För att ånga den senaste gjorda commit:en kör kommandot:
{{Cmd|git revert HEAD}}
{{Cmd|git revert HEAD}}
Om du vill ångra någon annan commit, ersätt HEAD med hashen. Använd optionen --no-edit om du vill acceptera standard commit meddelandet för en revert.


If you want to revert any commit, replace HEAD with the commit hash. Use the option --no-edit if you want to accept to default revert message.
=== Ta bort en commit på en branch ===
 
 
=== Remove commits from branch ===
 
When undoing a commit with {{Ic|git revert}}, both the incorrect and the revert commit are still visible in the history. If want to undo things and erase the commits from the history, you can move the HEAD pointer back to an earlier commit and start over. Assume you have a history like this:


När man ångrar en commit med {{Ic|git revert}} kommer både den felaktiga och återställningen synas i historien. Om man vill ångra commit:en och radera den från historien kan man flytta HEAD pekaren tillbaka till commit:en före den felaktiga och börja om från början. Antag att man har en historia som ser ut så här:
{{Bc|
{{Bc|
 
<nowiki>* e5f1c95 2012-12-10 | Another good commit (HEAD, master) [Peter Kerwien]
<nowiki>* e5f1c95 2012-12-10 | Another good commit (HEAD, master) [erakerw]
* e491e6d 2012-12-10 | Good commit [Peter Kerwien]
 
* ba30da7 2012-12-10 | Bad commit [Peter Kerwien]
* e491e6d 2012-12-10 | Good commit [erakerw]
* 4b732d0 2012-12-10 | Initial commit [Peter Kerwien]
 
</nowiki>}}
* ba30da7 2012-12-10 | Bad commit [erakerw]
Om man vill slänga bort dom 3 senaste commit:erna kan man flytta HEAD till commit 4b732d0 med kommandot:
 
* 4b732d0 2012-12-10 | Initial commit [erakerw]</nowiki>
 
}}
 
If you want to throw away the 3 last commits, you can move HEAD to the initial commit by:
 
{{Cmd|git reset --hard 4b732d0|output=HEAD is now at 4b732d0 Initial commit}}
{{Cmd|git reset --hard 4b732d0|output=HEAD is now at 4b732d0 Initial commit}}
 
När man sen genomför en ny commit, kommer historien se ut så här:
When you then perform a new commit, your history will look like:
 
{{Bc|
{{Bc|
 
<nowiki>* 40ec614 2012-12-10 | The best commit ever (HEAD, master) [Peter Kerwien]
<nowiki>* 40ec614 2012-12-10 | The best commit ever (HEAD, master) [erakerw]
* 4b732d0 2012-12-10 | Initial commit [Peter Kerwien]</nowiki>
 
* 4b732d0 2012-12-10 | Initial commit [erakerw]</nowiki>
 
}}
}}


{{Ic|git reset --hard}} will also erase all your non-committed changes in your working directory. If you want to keep both your non-staged and staged changes, use instead the --soft option. The commits that were discarded, are still available until the system runs the garbage collection. If can either use a tag before you do reset for easier access, or use the command {{Ic|git reflog}} to see where your HEAD have been earlier.
{{Ic|git reset --hard}} kommer även radera ev. icke-commit:ade ändringar i workspace. Om du vill spara alla förändringar (oavsett om de adderats till index eller inte), använd istället --soft optionen. De commit:s som blev slängda kommer fortfarande finnas kvar tills man städar repositoryt. Man kommer åt dessa commit:s via deras hash eller taggar. Man kan köra kommandot {{Ic|git reflog}} för att se var HEAD varit den senaste tiden.
 


== Branch ==
== Branch ==


=== Skapa och byta branch ===
 
=== Create and switch to branch ===
 
If you want to create and switch to a branch called test, run:


Om man vill skapa och byta till en branch som heter test, kör kommandot:
{{Cmd|git checkout -b test}}
{{Cmd|git checkout -b test}}
Man kan också specifiera en annan branchnings punkt än HEAD via:
{{Cmd|git checkout -b test <tag>}}
Eller:
{{Cmd|git checkout -b test <hash>}}


You can also specify another starting point than HEAD by:
=== Lista brancher ===
 
{{Cmd|git checkout -b test tag|hash}}
 
 
=== List branches ===
 
To list all local branches, run:


För att lista alla lokala brancher, kör:
{{Cmd|git branch}}
{{Cmd|git branch}}
 
Den aktuella branchen är markerad med *. Om man också vill se remote brancher, kör:
The asterisk (*) marks current branch. If you also want to see remote branches, run:
 
{{Cmd|git branch --all}}
{{Cmd|git branch --all}}
 
Om man bara vill lista alla lokala brancher som börjar på te, kör kommandot:
If you want to list all local branches that starts with te, run:
 
{{Cmd|git branch --list te*}}
{{Cmd|git branch --list te*}}


=== Växla mellan branch:er ===
 
=== Switch between branches ===
 
It is very easy to switch between branches, just run:


Det är väldigt enkelt att växla mellan branch:er, kör bara kommandot:
{{Cmd|git checkout <branch name>}}
{{Cmd|git checkout <branch name>}}
Git kommer att varna och stoppa dig om du har förändringar i workspace som inte är commit:ade.


Git will warn you and stop if you have local changes that are not committed when you try to switch branches.
=== Byta namn på en branch ===
 
 
=== Rename a branch ===
 
To rename the branch test to dev, run:


För att döpa om branch:en test till dev, kör kommandot:
{{Cmd|git branch -m test dev}}
{{Cmd|git branch -m test dev}}


=== Radera en branch ===
 
=== Delete a branch ===
 
To delete a branch called test, run:


För att radera en branch som heter test, kör:
{{Cmd|git branch -d test}}
{{Cmd|git branch -d test}}
 
Git kommer varna dig om branch:en inte har merge:ats ordentligt till annan branch. För att radera den trots detta, kör kommandot:
Git will warn you if the branch has not been fully merged. To delete even if not merged, just run:
 
{{Cmd|git branch -D test}}
{{Cmd|git branch -D test}}


=== Följa en lokal branch i ett annat repository ===
 
=== Track a local branch from another repo ===
 
Two users have cloned the same repository (helloworld.git). User A creates a local branch called test:


Två användare har klonat samma repository (helloworld.git). Användare A skapar en lokal branch som heter test:
{{Cmd|git checkout -b test}}
{{Cmd|git checkout -b test}}
 
Sen skapar A en ändring och commit:ar den till sitt repository:
Then performs a change and commits it:
{{Cmd|git commit -am "Commit made on test branch"}}
 
Nu vill B följa denna branch. B måste då först lägga till As repository som en remote:
{{Cmd|git commit -a -m "Commit made on test branch"}}
 
Now user B wants to follow / track this branch. B must first add A's repository as a remote:
 
{{Cmd|git remote add <local name> <url>}}
{{Cmd|git remote add <local name> <url>}}
 
I detta exempel kommer B kalla As repository för hello_a och URL:en är en absolut sökväg till repositoryt:
In this example B will call the remote hello_a (helloworld from user A) and the URL is just the absolute path to the repository):
{{Cmd|git remote add hello_a /home/a/git/helloworld}}
 
Visa detaljer om hello_a med kommandot:
{{Cmd|git remote add hello_a /home/erakerw/git/helloworld}}
 
Display the details about remote hello_a with the command:
 
{{Cmd|git remote show hello_a}}
{{Cmd|git remote show hello_a}}
{{Bc|1=
{{Bc|1=
* remote hello_a
* remote hello_a
 
   Fetch URL: /home/a/git/helloworld
   Fetch URL: /home/erakerw/git/helloworld
   Push  URL: /home/a/git/helloworld
 
   Push  URL: /home/erakerw/git/helloworld
 
   HEAD branch: test
   HEAD branch: test
   Remote branches:
   Remote branches:
     master new (next fetch will store in remotes/hello_a)
     master new (next fetch will store in remotes/hello_a)
     test  new (next fetch will store in remotes/hello_a)
     test  new (next fetch will store in remotes/hello_a)
   Local ref configured for 'git push':
   Local ref configured for 'git push':
     master pushes to master (up to date)
     master pushes to master (up to date)
}}
}}


Before B can track the test branch, B must fetch heads, tags and objects from A's repository:
Innan B kan följa test branch:en, måste B hämta heads, taggar, och objekt från As repository:
 
{{Cmd|git fetch hello_a}}
{{Cmd|git fetch hello_a}}
{{Bc|1=
{{Bc|1=
remote: Counting objects: 5, done.
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
Unpacking objects: 100% (3/3), done.
 
From /home/a/git/helloworld
From /home/erakerw/git/helloworld
 
* [new branch]      master    -> hello_a/master
* [new branch]      master    -> hello_a/master
* [new branch]      test      -> hello_a/test
* [new branch]      test      -> hello_a/test
}}
}}


B can now create a local branch called test which tracks A's test branch:
B kan nu skapa en lokal branch som B också kallar test som följer As test branch:
 
{{Cmd|git branch --track test hello_a/test|output=Branch test set up to track remote branch test from hello_a.}}
{{Cmd|git branch --track test hello_a/test|output=Branch test set up to track remote branch test from hello_a.}}
 
Byt till test branchen:
Switch to the test branch:
 
{{Cmd|git checkout test}}
{{Cmd|git checkout test}}


== Merge ==
== Merge ==


=== Olika typer av merge i git ===


=== Different merges in git ===
I följande exempel har vi gjort 2 commit:s på en branch som heter test:
 
In the following examples we have made 2 commits on branch called test:
 


[[Image:git-merge-before.png]]
[[Image:git-merge-before.png]]


==== Ingen merge behövs (standard) ====
 
==== No merge needed (default) ====


If no commits have been made on the master branch, git will use a so-called fast-forward (default) if we merge test to master:
Om ingen commit har gjorts på master branch:en sen test skapades, kommer git göra en s.k. fast-forward merge om vi merge:ar test till master:
 
{{Cmd|git merge test}}
   
{{Bc|1=
<nowiki>Updating e124053..8a48fa7
Fast-forward
Makefile |  21 +++++++++++++++++++++
  1 file changed, 21 insertions(+)
create mode 100644 Makefile
</nowiki>}}


[[Image:git-merge-ff.png]]
[[Image:git-merge-ff.png]]


Git bara flyttar HEAD framåt. Så alla commit:s vi har gjort på test branch:en kommer "flyttas" till master. Om vi pushar till origin kommer vi push:a två commit:s.


It only moves HEAD forward. So all commits we have made on test branch, is only "moved" to master. If we push to origin, we will push 2 commits.
==== Ingen merge behövs men med optionen --no-ff ====


Om ingen commit har gjorts på master branch:en sen test skapades, kommer git göra en s.k. fast-forward merge om vi merge:ar test till master. Men i detta fall använder vi --no-ff optionen:
 
{{Cmd|git merge --no-ff test}}
==== No merge needed but with --no-ff ====
{{Bc|1=
 
<nowiki>
If no commits have been made on the master branch, git will use a so-called fast-forward (default), but in this case we add the --no-ff option during merge:
Merge made by the 'recursive' strategy.
 
Makefile |  21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
create mode 100644 Makefile
</nowiki>}}


[[Image:git-merge-no-ff.png]]
[[Image:git-merge-no-ff.png]]


Git skapar nu en merge-commit på master.
{{Note|Om vi push:ar master till origin, kommer vi inte bara push:a denna merge-commit, utan vi kommer push:a tre commit:s.}}


Git now creates a merge commit on master.
==== Merge behövs ====


{{Note|If you push master to origin, you will '''not''' push one commit, you will push 3 commits (your two commits made on test branch and the merge commit.}}
Antag att någon har commit:at till master efter att vi branch:ade:
 
 
==== Merge needed ====
 
Assume that someone has made a new commit on master after we branched:
 


[[Image:git-merge-needed.png]]
[[Image:git-merge-needed.png]]


I detta fall måste git göra en vanlig merge, så vi behöver inte ange --no-ff optionen:
 
{{Cmd|git merge test}}
In this case, git must do a regular merge, so we do not have to provide the --no-ff option:
{{Bc|1=
 
<nowiki>
   
Merge made by the 'recursive' strategy.
Makefile |  21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
  create mode 100644 Makefile
</nowiki>}}


[[Image:git-merge.png]]
[[Image:git-merge.png]]


Git skapar nu en merge-commit master.
 
{{Note|Om vi push:ar master till origin, kommer vi inte bara push:a denna merge-commit, utan vi kommer push:a tre commit:s.}}
Git now creates a merge commit on master.
 
{{Note|If you push master to origin, you will '''not''' push one commit, you will push 3 commits (your two commits made on test branch and the merge commit.}}


=== Lösa merge-konflikter med meld ===


=== Resolve merge conflicts with meld ===
För att använda meld som grafisk merge-verktyg, kör följande kommandon:


If you have set up meld as your graphical merge-tool (See [[BBI Git#Using meld as graphical diff and merge tool (Optional)]]), you can perform graphical merge by running:
{{Cmd|git config --global merge.tool meld|git config --global merge.conflictstyle diff3|git config --global mergetool.prompt false}}
 
{{Cmd|git mergetool}}
 
 
Example: After a merge from test branch to master, git prints out the following:


Exempel: Efter en merge från test branch:en till master får vi följande utskrift:
{{Bc|
{{Bc|
Auto-merging main.c
Auto-merging main.c
CONFLICT (content): Merge conflict in main.c
CONFLICT (content): Merge conflict in main.c
 
Auto-merging .gitignore
Auto-merging Makefile
 
CONFLICT (content): Merge conflict in Makefile
 
Automatic merge failed; fix conflicts and then commit the result.
Automatic merge failed; fix conflicts and then commit the result.
}}
}}


Start the graphical merge:
Starta grafisk merge med meld:
 
{{Cmd|git mergetool}}
{{Cmd|git mergetool}}
 
Varje fil med konflikter kommer öppnas i meld. Meld-fönstret är uppdelat i 3 delar, från vänster till höger har vi:
Each file will be opened in meld for resolving the conflicts. With the configuration where meld is given 4 arguments, it will resolve all non-conflicting changes, and then leave the rest for the user to resolve. The meld window is divided into three parts. From left to right we have:
three parts. From left to right we have:
 
* Versionen från master branch:en
* The version on master branch (to-version)
* Merge resultatet
 
* Versionen från test branch:en
* The merge result
 
* The version on test branch (from-version)
 


[[Image:meld-merge1.png|600px]]
[[Image:meld-merge1.png|600px]]


Lös merge:n genom att välja in ändringar antingen från vänster eller höger till vårt resultat i mitten. Du kan också editera koden i mitten för att skapa rätt merge resultat. Börja med att fixa alla icke-konflikter genom att i meld välja Changes => Merge all non-conflicting. TBD:Detta kan git/meld gör automatiskt med andra inställingar.


Resolve the merge by selecting the code from the left or right section into the middle section. You can also edit the code in the middle section to create the correct merge result. When done save the result.
[[Image:meld-merge2.png|600px]]


Lös sedan den kvarvarande konflikten genom att välja ändringen från test branch:en.


When you have resolved the conflicts, commit the merge result.
[[Image:meld-merge3.png|600px]]


Spara filen och stäng meld. Nu är alla konflikter lösta och vi kan commit:a merge-resultatet till master.


== Rebase ==
== Rebase ==


Rebase is a way to forward-port your commits to a new upstream HEAD. Assume we have made 2 commits on a test branch. After we branched, someone has made a new commit on master:
Rebase är ett sätt att framåt-porta dina commit:s till en nyare HEAD. Antag att vi har skapat 2 commit:s på en branch som heter test. Efter att vi branch:at så har någon annan gjort en ny commit master:
 


[[Image:git-rebase-before.png]]
[[Image:git-rebase-before.png]]


Istället för att merga:a från master till test, vi kan rebase:a våra 2 commit:s. När man är på test branch:en, kör kommandot:
 
Instead of merging from master to test, we can forward-port our 2 commits. While on test branch, run the command:
 
{{Cmd|git rebase master}}
{{Cmd|git rebase master}}
 
I detta exempel uppstår inga merge-konflikter, git kommer automatiskt göra rebase:en åt oss:
In this example we will not have any merge conflicts, so git will automatically do the rebase for us:
 
{{Bc|1=
{{Bc|1=
First, rewinding head to replay your work on top of it...
First, rewinding head to replay your work on top of it...
 
Applying: Add Makefile
Applying: Added unused attribute on argc & argv
Applying: Minor edits in Makefile
 
Applying: Replaced __attribute__((unused)) with -Wno-unused-parameter
 
}}
}}


Our 2 commits have now been modified and based on the new HEAD on master:
Våra 2 commit:s har nu blivit modifierade och baseras nu på den nya HEAD master.
 


[[Image:git-rebase-after.png]]
[[Image:git-rebase-after.png]]


{{Warning|Gör inte rebase på commit:s som du push:at till delat repository eller på branch som du delar med annan användare!}}
 
Men en rebase på en lokal branch är att föredra framför en merge, eftersom du kommer skapa en renare historia. Det spelar ingen roll om du merge:ar eller rebase:ar, varje konflikt måste lösas ändå. Om vi nu merge:ar till master, så kommer git default att göra en fast-forward merge.
{{Warning|Do not rebase commits that you have pushed to a public repository!}}
 
However, rebasing your local branch is preferred over merge, since you will create a cleaner history tree. It does not matter if you merge or rebase, any conflicts have to be resolved. If we now do a merge on master from test, git will default do a fast-forward merge (see [[#No merge needed (default)]]
 


== Cherry-pick ==
== Cherry-pick ==


=== Enkel cherry-picking utan konflikt ===
 
=== Simple cherry-picking without conflict ===


If you want to apply changes from one branch to another, but you want to select exactly which commits to choose, you can do a so called cherry-pick. Assume we have the following history:
Om man vill merge:a commit:s från en branch till en annan, och vill exakt kunna peka ut enskilda commit:s som ska tas med, då kan man göra en sk. cherry-pick. Antag att vi har följande historia:


{{Bc|<nowiki>
{{Bc|<nowiki>
 
* b5df0bb 2012-12-17 | Added main() header (HEAD, test) [Peter Kerwien]
* b5df0bb 2012-12-17 | Added main() header (HEAD, test) [erakerw]
| * 12ad7c3 2012-12-17 | Whitespace edit in main.c (master) [Peter Kerwien]
 
| * f39ba2f 2012-12-14 | Add some file headers [Peter Kerwien]
| * 12ad7c3 2012-12-17 | Whitespace edit in main.c (master) [erakerw]
| * 02d1638 2012-12-14 | Change hello message [Peter Kerwien]
 
| * f39ba2f 2012-12-14 | Add some file headers [erakerw]
 
| * 02d1638 2012-12-14 | Change hello message [erakerw]
 
|/  
|/  
 
* 0e1085d 2012-12-14 | Made some cleanup [Peter Kerwien]
* 0e1085d 2012-12-14 | Made some cleanup [erakerw]
* 10213e2 2012-12-14 | Initial commit [Peter Kerwien]
 
* 10213e2 2012-12-14 | Initial commit [erakerw]
 
</nowiki>}}
</nowiki>}}


We want to apply the commit f39ba2f to our test branch. To do that, switch to the test branch and run:
Vi vill nu applicera commit f39ba2f på vår test branch. För att göra det, byt till test branch:en och kör kommandot:


{{Cmd|git cherry-pick f39ba2f}}
{{Cmd|git cherry-pick f39ba2f}}
{{Bc|<nowiki>
{{Bc|<nowiki>
[test 81d9476] Add some file headers
[test 81d9476] Add some file headers
2 files changed, 4 insertions(+)
2 files changed, 4 insertions(+)
</nowiki>}}
</nowiki>}}


The history will now look like:
Historien vill nu se ut så här:


{{Bc|<nowiki>
{{Bc|<nowiki>
 
* 81d9476 2012-12-14 | Add some file headers (HEAD, test) [Peter Kerwien]
* 81d9476 2012-12-14 | Add some file headers (HEAD, test) [erakerw]
* b5df0bb 2012-12-17 | Added main() header [Peter Kerwien]
 
| * 12ad7c3 2012-12-17 | Whitespace edit in main.c (master) [Peter Kerwien]
* b5df0bb 2012-12-17 | Added main() header [erakerw]
| * f39ba2f 2012-12-14 | Add some file headers [Peter Kerwien]
 
| * 02d1638 2012-12-14 | Change hello message [Peter Kerwien]
| * 12ad7c3 2012-12-17 | Whitespace edit in main.c (master) [erakerw]
 
| * f39ba2f 2012-12-14 | Add some file headers [erakerw]
 
| * 02d1638 2012-12-14 | Change hello message [erakerw]
 
|/  
|/  
 
* 0e1085d 2012-12-14 | Made some cleanup [Peter Kerwien]
* 0e1085d 2012-12-14 | Made some cleanup [erakerw]
* 10213e2 2012-12-14 | Initial commit [Peter Kerwien]
 
* 10213e2 2012-12-14 | Initial commit [erakerw]
 
</nowiki>}}
</nowiki>}}


Note that the commit f39ba2f is called 81d9476 on our test branch.
Notera att commit f39ba2f har hashen 81d9476 test branch:en.
 


=== Multiple cherry-picking with conflict ===
=== Multipla cherry-picking med konflikt ===


During cherry-picking, conflicts might have to be resolved. In this example, we will cherry-pick two commits, where the first one will conflict with our changes on the test branch. Assume the following history:
Under cherry-picking, kan konflikter uppstå som måste lösas. I detta exempel kommer vi cherry-pick:a två commit:s, där den första kommer att ha konflikt med våra commit:s på test branch:en. Antag att vi har följande historia:


{{Bc|<nowiki>
{{Bc|<nowiki>
 
* e108d4a 2012-12-17 | Hello test! (HEAD, test) [Peter Kerwien]
* e108d4a 2012-12-17 | Hello test! (HEAD, test) [erakerw]
| * fdb65d7 2012-12-17 | Return EXIT_SUCCESS instead of 0 (master) [Peter Kerwien]
 
| * 69e7150 2012-12-17 | Added argc & argv parameters to main() [Peter Kerwien]
| * fdb65d7 2012-12-17 | Return EXIT_SUCCESS instead of 0 (master) [erakerw]
| * 413565e 2012-12-17 | Changed hello message [Peter Kerwien]
 
| * 69e7150 2012-12-17 | Added argc & argv parameters to main() [erakerw]
 
| * 413565e 2012-12-17 | Changed hello message [erakerw]
 
|/  
|/  
 
* 3ff2e68 2012-12-17 | Initial commit [Peter Kerwien]
* 3ff2e68 2012-12-17 | Initial commit [erakerw]
 
</nowiki>}}
</nowiki>}}


Switch to the test branch, and cherry-pick commits 413565e and fdb65d7. The first one will conflict with our commit e108d4a:
Byt till test branch:en och cherry-pick:a commit:s 413565e och fdb65d7. Den första kommer ha konflikter med commit e108d4a:  


{{Cmd|git cherry-pick 413565e fdb65d7}}
{{Cmd|git cherry-pick 413565e fdb65d7}}
{{Bc|
{{Bc|
error: could not apply 413565e... Changed hello message
error: could not apply 413565e... Changed hello message
hint: after resolving the conflicts, mark the corrected paths
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
hint: and commit the result with 'git commit'
}}
}}


Resolve the conflict and commit the merge result. Now, to continue the cherry-picking, run the command:
Lös konflikterna och commit:a merge resultatet. Nu kan vi återuppta cherry-picking med kommandot:
 
{{Cmd|git cherry-pick --continue}}
{{Cmd|git cherry-pick --continue}}
{{Bc|<nowiki>
{{Bc|<nowiki>
 
$ git cherry-pick --continue
esekilxxen1924> git cherry-pick --continue
 
[test 9eac083] Return EXIT_SUCCESS instead of 0
[test 9eac083] Return EXIT_SUCCESS instead of 0
1 file changed, 2 insertions(+), 1 deletion(-)
1 file changed, 2 insertions(+), 1 deletion(-)
</nowiki>}}
</nowiki>}}


Now our history looks like:
Nu ser vår historia ut så här:


{{Bc|<nowiki>
{{Bc|<nowiki>
 
* 9eac083 2012-12-17 | Return EXIT_SUCCESS instead of 0 (HEAD, test) [Peter Kerwien]
* 9eac083 2012-12-17 | Return EXIT_SUCCESS instead of 0 (HEAD, test) [erakerw]
* bfc1ad9 2012-12-17 | Changed hello message [Peter Kerwien]
 
* e108d4a 2012-12-17 | Hello test! [Peter Kerwien]
* bfc1ad9 2012-12-17 | Changed hello message [erakerw]
| * fdb65d7 2012-12-17 | Return EXIT_SUCCESS instead of 0 (master) [Peter Kerwien]
 
| * 69e7150 2012-12-17 | Added argc & argv parameters to main() [Peter Kerwien]
* e108d4a 2012-12-17 | Hello test! [erakerw]
| * 413565e 2012-12-17 | Changed hello message [Peter Kerwien]
 
| * fdb65d7 2012-12-17 | Return EXIT_SUCCESS instead of 0 (master) [erakerw]
 
| * 69e7150 2012-12-17 | Added argc & argv parameters to main() [erakerw]
 
| * 413565e 2012-12-17 | Changed hello message [erakerw]
 
|/  
|/  
 
* 3ff2e68 2012-12-17 | Initial commit [Peter Kerwien]
* 3ff2e68 2012-12-17 | Initial commit [erakerw]
 
</nowiki>}}
</nowiki>}}


We have now applied the two commits, with the new hash values bfc1ad9 and 9eac083.
Vi har nu applicerat de två commit:sen och deras nya hashvärden på branch:en är bfc1ad9 respektive 9eac083.
 


== Squash ==
== Squash ==


When doing a push, several commits might be pushed. This is not always a wanted behaviour, since it might be a lot of commits from our local development branch. If you push to a central repository, all you intermediate commits will be visible to others that clones this repository. If you want to push a feature as one single commit, you can use squashing. A squash will create a new commit which is the summary of several commits.
När man gör en push kommer ev. flera commit:s att push:as. Det är inte alltid man vill att detta ska ske, eftersom man kanske har många commit:s på en lokal utvecklingsbranch. När man push:ar till en centralt repository kommer alla dessa commit:s att bli synliga för alla andra som klonar repositoryt. Om man istället vill push:a en feature som en enda kommit så kan man använda sig av squash:ing. En squash kan skapa en ny commit av flera andra commit:s.
 
 
Assume we have developed a feature on a branch called test. Everything is rebased to latest commit on master:


Antag att vi har utvecklat en feature på en branch som heter test. Allt är rebase:at till senaste commit på master:


[[Image:git-squash-1.png]]
[[Image:git-squash-1.png]]


Skapa en ny branch från master som heter test-squash (samma branch punkt som test branchen):
 
Create a new branch from master called test-squashed:
 
{{Cmd|git checkout -B test-squash master}}
{{Cmd|git checkout -B test-squash master}}
 
Merga:a alla commit:s från test, men tryck ihop dom till en enda commit:
Merge all commits made on test, but create one single commit of them:
 
{{Cmd|git merge --squash test}}
{{Cmd|git merge --squash test}}
 
Commit:a till test-squash:
Commit the changes:
{{Cmd|git commit -am "Squash commits on test"}}
 
Vi har nu skapat en enda commit test-squash branch:en som innehåller summan av alla commit:s gjorda på test branch:en:
{{Cmd|git commit -am "Added input arguments to main()"}}
 
We have now created one commit on the test-squash branch, which has the complete contents of the commits on the test branch:
 


[[Image:git-squash-2.png]]
[[Image:git-squash-2.png]]


Byt till master branch:en och merge:a från test-squash (fast-forward merge):
 
Switch to master and merge from test-squash (fast-forward merge):
 
{{Cmd|git checkout master|git merge test-squash}}
{{Cmd|git checkout master|git merge test-squash}}


[[Image:git-squash-3.png]]
[[Image:git-squash-3.png]]


Om vi nu push:ar master till origin/master kommer endast en commit att adderas.
 
If we push to origin/master, only one commit will be added:
 
 
[[Image:git-squash-4.png]]
 
 
== Terminology ==


== Terminologi ==


{| class="wikitable sortable" border="1" cellpadding="2" cellspacing="0"
{| class="wikitable sortable" border="1" cellpadding="2" cellspacing="0"
!|Term
!|Term
!class="unsortable"|Description
!class="unsortable"|Beskrivning
|-
|-
| Bare repository
| Bare repository
| A Git repository without a working directory
| Ett git repository utan workspace. Ett repository där du inte kan arbeta med filerna som versionshanteras.
|-
|-
| Clone
| Klon
| A copy of a repository. The clone will contain all existing versions.
| En kopia av ett repository. En klon innehåller normalt alla versioner av repot.
|-
|-
| Working directory
| Workspace
| The directory containing your checked out files. Where you can edit and commit your changes.
| Arean där du kan jobba med alla filer. Det är här man kan editera, skapa nya filer och commit:a sina ändringar. Den delen av ett vanligt repo som inte ligger i .git katalogen.  
|-
|-
| HEAD
| HEAD
| A pointer to the currently selected commit in your repository
| En pekare som pekar ut den just nu valda versionen av repositoryt.
|-
|-
| Staged
| Staged
| Added to the index, not yet committed
| (Saknar bra svensk översättning). Adderad till index men inte commit:ad.
|-
|-
| Cached
| Cached
| See staged
| (Saknar bra svenska översättning). Se staged.
|-
|-
| Tracked file
| Versionshanterad fil
| A file that is added and version controlled in git
| En fil i workspace som är adderad och versionshanterad i git repositoryt.
|-
|-
| Untracked file
| Icke-versionshanterad fil
| A file that is not version controlled in git
| En fil i workspace som inte är adderad och versionshanterad i git repositoryt.
|-
|-
| Index
| Index
| The content of tracked files that will be committed if you run the git commit command.
| Innehåller alla förändringar i versionshanterade filer som kommer commit:as när man kör kommandot git commit.
|}
|}
[[Category:Guide]]

Latest revision as of 12:38, 27 September 2020


Denna artikel beskriver några kommandon och användarfall med git.

Inställningar

Git inställningar kan var global eller per repository (sparade under .git mappen i ett repository). Globala inställningar är sparade i filen ~/.gitconfig. Det går att läsa och editera filen ~/.gitconfig manuellt, eller använda kommandot git config --global. Några exempel hur man sätter, tar bort och läser inställningar:

user $ git config --global core.pager cat
user $
git config --global --unset core.pager
user $
git config --global --get core.pager


Notering: Inställningar sparade i repositoryt är bara temporära. Dom inkluderas inte när du t.ex. klonar ett repository.


Vem är du?

Ställ in namn och email adress:

user $ git config --global user.name "Förnamn Efternamn"
user $
git config --global user.email fornamn.efternamn@exempel.com

Pager

Du kan välja vilken 'pager' (t.ex. more, less, cat) Git ska använda. Kör detta kommando om du vill att Git ska använda cat:

user $ git config --global core.pager cat

Snyggare log

För att skapa alias i Git, som t.ex. att skriva ut en kompakt och snygg log med kommandot git hist, kör kommandot:

user $ git config --global alias.hist 'log --pretty=tformat:"%h %ad | %s%d [%an]" --graph --date=short'

Vi använder tformat istället för format för att få med ett avslutande 'carriage return' ifall du använder cat som din pager. Utskriften från git hist kommer att se ut så här:

* 40ec614 2012-12-10 | The best commit ever (HEAD, master) [Peter Kerwien]
* 4b732d0 2012-12-10 | Initial commit [Peter Kerwien]

Repository

Skapa ett repository

För att skapa ett repository i en icke-existerande katalog, kör:

user $ git init repo

Eller om du vill skapa ett repository i nuvarande katalog:

user $ cd <path>/repo
user $
git init

Båda kommandona kommer skapa en dold katalog som heter .git. Dessa repositoryn kan också innehålla filerna som man jobbar med dvs ett 'workspace'. Om du vill skapa ett repository som ska fungera som ett centralt repository eller dela mellan flera användare och alla ska kunna pusha till repositoryt så måste man skapa ett s.k. bare repository. Ett bare repository saknar workspace och alla git-filer ligger synliga direkt i repositoryt och inte i en katalog som heter .git. För att skapa ett bare repository, kör::

user $ git init --bare repo.git

Namnkonventionen är att bare repositorys slutar med ändelsen .git i namnet.

Klona ett repository

För att klona ett repository, dvs skapa en kopia av alla dess versioner, kör:

user $ git clone repo dir

Det spelar ingen roll om du klonar ett vanligt eller bare repository, du kommer få en klon med ett workspace. Men om du vill klona utan ett workspace, kör kommandot:

user $ git clone --bare repo dir

Din klon med namnet dir kommer nu inte innehålla något workspace.

Rensa workspace

Efter en del arbete kommer ditt workspace innehålla versionshanterade, ändrade men också genererade och backup-filer. En del av de icke-versionshanterade filerna listas med git status, men en del filer ignoreras via en .gitignore fil. För att rensa hela ditt workspace från alla icke-versionshanterade inklusive ignorerade filer, gå till toppen av repositoryt och kör:

user $ git clean -fdx

Använd -n optionen för att endast lista vilka filer som skulle ha raderats.

Versionshantera, komitta och sluta versionshantera förändringar

Versionshantera förändringar

För att addera en eller flera filer till git, kör:

user $ git add <pattern>

Om en fil redan versionshanteras, kommer kommandot att addera förändringar till index. Om du vill addera alla gjorda förändringar till index, kör kommandot:

user $ git add -u

Commit:a förändringar

För att commit:a förändringar redan adderade till index, kör:

user $ git commit -m "Commit message"

Om man vill commit:a alla ändringar som är gjorda i redan versionshanterade filer, men ej adderade till index, kör kommandot:

user $ git commit -am "Commit message"

Sluta versionshantera förändringar

För att ta bort en eller flera filer från workspace och index, kör kommandot:

user $ git rm <pattern>

Filerna kommer att tas bort från repositoryt när du commit:ar till repositoryt.

Diff

Diff:a workspace mot index

För att lista förändringar du har gjort i workspace, men som inte än är adderade till index, kör kommandot:

user $ git diff

För att lista förändringar mellan ditt index och HEAD, dvs versionen du ser i repositoryt, kör kommandot:

user $ git diff --cached

Om du vill se alla dina icke-commit:ade förändringar (både adderade till index eller inte), kör kommandot:

user $ git diff HEAD

Använda meld som grafiskt diff-verktyg

För att använda meld som diff-verktyg när man kör kommandot git difftool -g kör följande kommandon:

user $ git config --global diff.tool meld
user $
git config --global difftool.prompt false

Man kan nu få upp grafiska jämförelser mellan versioner m.m. genom kommandot:

user $ git difftool

Ersätt git diff med git difftool i exemplen ovan. En diff med meld kan se ut så här:

(Äldre versionen visas till vänster och den nya till höger.)

Diff:a commits

Antag att vi har följande historia:

* 2634685 2012-12-18 | Commit 4 (HEAD, master) [Peter Kerwien]
* d0afcbd 2012-12-18 | Commit 3 [Peter Kerwien]
* aaa2574 2012-12-18 | Commit 2 [Peter Kerwien]
* b61568c 2012-12-18 | Initial commit [Peter Kerwien]

För att visa alla förändringar mellan commit 2 och 3, kör:

user $ git diff b61568c d0afcbd

Du kan också köra kommandot:

user $ git diff HEAD~3 HEAD~1

Välja revision

Släkt-referenser

Antag att vi har följande historia:

* 5b38862 2013-01-16 | Commit 5 (HEAD, master) [Peter Kerwien]
*   9940a50 2013-01-16 | Commit 4 [Peter Kerwien]
|\ 
| * fc796ce 2013-01-16 | Commit on test (test) [Peter Kerwien]
* | f7935db 2013-01-16 | Commit 3 [Peter Kerwien]
|/ 
* dc53825 2013-01-16 | Commit 2 [Peter Kerwien]
* bea9676 2013-01-16 | Initial commit [Peter Kerwien]

Istället för att ange hela hashen för att välja version, kan man ange släkt-referenser genom att addera ^ eller ~ efter versionen. HEAD^ betyder den första föräldern till HEAD (=9940a50). Commit:en 9940a50 har två föräldrar, därför väljer 9940a50^ den föräldern som finns på nuvarande branch. Om vi är på master så kommer 9940a50^ välja commit:en f7935db. 9940a50^2 kommer välja den andre föräldern, i detta fall fc796ce. Man kan också lägga till flera ^ efter varandra. HEAD^^ kommer välja commit f7935db.

~ däremot betyder alltid den första föräldern av en commit. Så följande exempel väljer alltid samma commit:

  • HEAD^ och HEAD~
  • HEAD^^^ och HEAD~3

HEAD~2 betyder "första föräldern till första föräldern", så 9940a50~2 väljer commit:en dc53825. Detta är inte samma sak som 9940a50^2.

Man kan kombinera dessa två, t.ex. HEAD~^2. Detta betyder "den andra föräldern till den första föräldern till HEAD", dvs commit:en fc796ce.

Ångra och ändra

Notering: Ändra inte eller ta bort commit:s som du redan har delat med andra. Det är bara säkert att ändra historien om det bara påverkar dig själv.


Ångra ändringar som inte har adderats till index

För att ångra ändringar som inte har adderats till index, kör kommandot:

user $ git checkout -- <file>

Ångra ändringar som har adderats till index

För att ångra ändringar som har adderats till index, kör:

user $ git reset HEAD <file>

Reset kommandot återställer index till vad som pekas ut av HEAD. Reset kommandot återståller inte workspace. Så workspace kan fortfarande innehålla oönskade ändringar.

Rätta senaste commit

Om du upptäcker att någonting saknas i den senaste commit:en och du vill inte göra en ny, då kan du rätta till ditt misstag med kommandot:

user $ git commit --amend -m "..."

Du måste dock först addera vad du saknade till index innan du kör kommandot ovan.

Ångra en commit

För att ångra en commit kan vi skapa en commit som tar bort dom förändringar som gjordes i den oönskade commit:en. För att ånga den senaste gjorda commit:en kör kommandot:

user $ git revert HEAD

Om du vill ångra någon annan commit, ersätt HEAD med hashen. Använd optionen --no-edit om du vill acceptera standard commit meddelandet för en revert.

Ta bort en commit på en branch

När man ångrar en commit med git revert kommer både den felaktiga och återställningen synas i historien. Om man vill ångra commit:en och radera den från historien kan man flytta HEAD pekaren tillbaka till commit:en före den felaktiga och börja om från början. Antag att man har en historia som ser ut så här:

* e5f1c95 2012-12-10 | Another good commit (HEAD, master) [Peter Kerwien]
* e491e6d 2012-12-10 | Good commit [Peter Kerwien]
* ba30da7 2012-12-10 | Bad commit [Peter Kerwien]
* 4b732d0 2012-12-10 | Initial commit [Peter Kerwien]

Om man vill slänga bort dom 3 senaste commit:erna kan man flytta HEAD till commit 4b732d0 med kommandot:

user $ git reset --hard 4b732d0
HEAD is now at 4b732d0 Initial commit

När man sen genomför en ny commit, kommer historien se ut så här:

* 40ec614 2012-12-10 | The best commit ever (HEAD, master) [Peter Kerwien]
* 4b732d0 2012-12-10 | Initial commit [Peter Kerwien]

git reset --hard kommer även radera ev. icke-commit:ade ändringar i workspace. Om du vill spara alla förändringar (oavsett om de adderats till index eller inte), använd istället --soft optionen. De commit:s som blev slängda kommer fortfarande finnas kvar tills man städar repositoryt. Man kommer åt dessa commit:s via deras hash eller taggar. Man kan köra kommandot git reflog för att se var HEAD varit den senaste tiden.

Branch

Skapa och byta branch

Om man vill skapa och byta till en branch som heter test, kör kommandot:

user $ git checkout -b test

Man kan också specifiera en annan branchnings punkt än HEAD via:

user $ git checkout -b test <tag>

Eller:

user $ git checkout -b test <hash>

Lista brancher

För att lista alla lokala brancher, kör:

user $ git branch

Den aktuella branchen är markerad med *. Om man också vill se remote brancher, kör:

user $ git branch --all

Om man bara vill lista alla lokala brancher som börjar på te, kör kommandot:

user $ git branch --list te*

Växla mellan branch:er

Det är väldigt enkelt att växla mellan branch:er, kör bara kommandot:

user $ git checkout <branch name>

Git kommer att varna och stoppa dig om du har förändringar i workspace som inte är commit:ade.

Byta namn på en branch

För att döpa om branch:en test till dev, kör kommandot:

user $ git branch -m test dev

Radera en branch

För att radera en branch som heter test, kör:

user $ git branch -d test

Git kommer varna dig om branch:en inte har merge:ats ordentligt till annan branch. För att radera den trots detta, kör kommandot:

user $ git branch -D test

Följa en lokal branch i ett annat repository

Två användare har klonat samma repository (helloworld.git). Användare A skapar en lokal branch som heter test:

user $ git checkout -b test

Sen skapar A en ändring och commit:ar den till sitt repository:

user $ git commit -am "Commit made on test branch"

Nu vill B följa denna branch. B måste då först lägga till As repository som en remote:

user $ git remote add <local name> <url>

I detta exempel kommer B kalla As repository för hello_a och URL:en är en absolut sökväg till repositoryt:

user $ git remote add hello_a /home/a/git/helloworld

Visa detaljer om hello_a med kommandot:

user $ git remote show hello_a
* remote hello_a
  Fetch URL: /home/a/git/helloworld
  Push  URL: /home/a/git/helloworld
  HEAD branch: test
  Remote branches:
    master new (next fetch will store in remotes/hello_a)
    test   new (next fetch will store in remotes/hello_a)
  Local ref configured for 'git push':
    master pushes to master (up to date)

Innan B kan följa test branch:en, måste B hämta heads, taggar, och objekt från As repository:

user $ git fetch hello_a
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/a/git/helloworld
* [new branch]      master     -> hello_a/master
* [new branch]      test       -> hello_a/test

B kan nu skapa en lokal branch som B också kallar test som följer As test branch:

user $ git branch --track test hello_a/test
Branch test set up to track remote branch test from hello_a.

Byt till test branchen:

user $ git checkout test

Merge

Olika typer av merge i git

I följande exempel har vi gjort 2 commit:s på en branch som heter test:

Ingen merge behövs (standard)

Om ingen commit har gjorts på master branch:en sen test skapades, kommer git göra en s.k. fast-forward merge om vi merge:ar test till master:

user $ git merge test
Updating e124053..8a48fa7
Fast-forward
 Makefile |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 Makefile

Git bara flyttar HEAD framåt. Så alla commit:s vi har gjort på test branch:en kommer "flyttas" till master. Om vi pushar till origin kommer vi push:a två commit:s.

Ingen merge behövs men med optionen --no-ff

Om ingen commit har gjorts på master branch:en sen test skapades, kommer git göra en s.k. fast-forward merge om vi merge:ar test till master. Men i detta fall använder vi --no-ff optionen:

user $ git merge --no-ff test
Merge made by the 'recursive' strategy.
 Makefile |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 Makefile

Git skapar nu en merge-commit på master.

Notering: Om vi push:ar master till origin, kommer vi inte bara push:a denna merge-commit, utan vi kommer push:a tre commit:s.


Merge behövs

Antag att någon har commit:at till master efter att vi branch:ade:

I detta fall måste git göra en vanlig merge, så vi behöver inte ange --no-ff optionen:

user $ git merge test
Merge made by the 'recursive' strategy.
 Makefile |   21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)
 create mode 100644 Makefile

Git skapar nu en merge-commit på master.

Notering: Om vi push:ar master till origin, kommer vi inte bara push:a denna merge-commit, utan vi kommer push:a tre commit:s.


Lösa merge-konflikter med meld

För att använda meld som grafisk merge-verktyg, kör följande kommandon:

user $ git config --global merge.tool meld
user $
git config --global merge.conflictstyle diff3
user $
git config --global mergetool.prompt false

Exempel: Efter en merge från test branch:en till master får vi följande utskrift:

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

Starta grafisk merge med meld:

user $ git mergetool

Varje fil med konflikter kommer öppnas i meld. Meld-fönstret är uppdelat i 3 delar, från vänster till höger har vi: three parts. From left to right we have:

  • Versionen från master branch:en
  • Merge resultatet
  • Versionen från test branch:en

Lös merge:n genom att välja in ändringar antingen från vänster eller höger till vårt resultat i mitten. Du kan också editera koden i mitten för att skapa rätt merge resultat. Börja med att fixa alla icke-konflikter genom att i meld välja Changes => Merge all non-conflicting. TBD:Detta kan git/meld gör automatiskt med andra inställingar.

Lös sedan den kvarvarande konflikten genom att välja ändringen från test branch:en.

Spara filen och stäng meld. Nu är alla konflikter lösta och vi kan commit:a merge-resultatet till master.

Rebase

Rebase är ett sätt att framåt-porta dina commit:s till en nyare HEAD. Antag att vi har skapat 2 commit:s på en branch som heter test. Efter att vi branch:at så har någon annan gjort en ny commit på master:

Istället för att merga:a från master till test, vi kan rebase:a våra 2 commit:s. När man är på test branch:en, kör kommandot:

user $ git rebase master

I detta exempel uppstår inga merge-konflikter, så git kommer automatiskt göra rebase:en åt oss:

First, rewinding head to replay your work on top of it...
Applying: Add Makefile
Applying: Minor edits in Makefile

Våra 2 commit:s har nu blivit modifierade och baseras nu på den nya HEAD på master.


Varning: Gör inte rebase på commit:s som du push:at till delat repository eller på branch som du delar med annan användare!

Men en rebase på en lokal branch är att föredra framför en merge, eftersom du kommer skapa en renare historia. Det spelar ingen roll om du merge:ar eller rebase:ar, varje konflikt måste lösas ändå. Om vi nu merge:ar till master, så kommer git default att göra en fast-forward merge.

Cherry-pick

Enkel cherry-picking utan konflikt

Om man vill merge:a commit:s från en branch till en annan, och vill exakt kunna peka ut enskilda commit:s som ska tas med, då kan man göra en sk. cherry-pick. Antag att vi har följande historia:

* b5df0bb 2012-12-17 | Added main() header (HEAD, test) [Peter Kerwien]
| * 12ad7c3 2012-12-17 | Whitespace edit in main.c (master) [Peter Kerwien]
| * f39ba2f 2012-12-14 | Add some file headers [Peter Kerwien]
| * 02d1638 2012-12-14 | Change hello message [Peter Kerwien]
|/ 
* 0e1085d 2012-12-14 | Made some cleanup [Peter Kerwien]
* 10213e2 2012-12-14 | Initial commit [Peter Kerwien]

Vi vill nu applicera commit f39ba2f på vår test branch. För att göra det, byt till test branch:en och kör kommandot:

user $ git cherry-pick f39ba2f
[test 81d9476] Add some file headers
2 files changed, 4 insertions(+)

Historien vill nu se ut så här:

* 81d9476 2012-12-14 | Add some file headers (HEAD, test) [Peter Kerwien]
* b5df0bb 2012-12-17 | Added main() header [Peter Kerwien]
| * 12ad7c3 2012-12-17 | Whitespace edit in main.c (master) [Peter Kerwien]
| * f39ba2f 2012-12-14 | Add some file headers [Peter Kerwien]
| * 02d1638 2012-12-14 | Change hello message [Peter Kerwien]
|/ 
* 0e1085d 2012-12-14 | Made some cleanup [Peter Kerwien]
* 10213e2 2012-12-14 | Initial commit [Peter Kerwien]

Notera att commit f39ba2f har hashen 81d9476 på test branch:en.

Multipla cherry-picking med konflikt

Under cherry-picking, kan konflikter uppstå som måste lösas. I detta exempel kommer vi cherry-pick:a två commit:s, där den första kommer att ha konflikt med våra commit:s på test branch:en. Antag att vi har följande historia:

* e108d4a 2012-12-17 | Hello test! (HEAD, test) [Peter Kerwien]
| * fdb65d7 2012-12-17 | Return EXIT_SUCCESS instead of 0 (master) [Peter Kerwien]
| * 69e7150 2012-12-17 | Added argc & argv parameters to main() [Peter Kerwien]
| * 413565e 2012-12-17 | Changed hello message [Peter Kerwien]
|/ 
* 3ff2e68 2012-12-17 | Initial commit [Peter Kerwien]

Byt till test branch:en och cherry-pick:a commit:s 413565e och fdb65d7. Den första kommer ha konflikter med commit e108d4a:

user $ git cherry-pick 413565e fdb65d7
error: could not apply 413565e... Changed hello message
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

Lös konflikterna och commit:a merge resultatet. Nu kan vi återuppta cherry-picking med kommandot:

user $ git cherry-pick --continue
$ git cherry-pick --continue
[test 9eac083] Return EXIT_SUCCESS instead of 0
1 file changed, 2 insertions(+), 1 deletion(-)

Nu ser vår historia ut så här:

* 9eac083 2012-12-17 | Return EXIT_SUCCESS instead of 0 (HEAD, test) [Peter Kerwien]
* bfc1ad9 2012-12-17 | Changed hello message [Peter Kerwien]
* e108d4a 2012-12-17 | Hello test! [Peter Kerwien]
| * fdb65d7 2012-12-17 | Return EXIT_SUCCESS instead of 0 (master) [Peter Kerwien]
| * 69e7150 2012-12-17 | Added argc & argv parameters to main() [Peter Kerwien]
| * 413565e 2012-12-17 | Changed hello message [Peter Kerwien]
|/ 
* 3ff2e68 2012-12-17 | Initial commit [Peter Kerwien]

Vi har nu applicerat de två commit:sen och deras nya hashvärden på branch:en är bfc1ad9 respektive 9eac083.

Squash

När man gör en push kommer ev. flera commit:s att push:as. Det är inte alltid man vill att detta ska ske, eftersom man kanske har många commit:s på en lokal utvecklingsbranch. När man push:ar till en centralt repository kommer alla dessa commit:s att bli synliga för alla andra som klonar repositoryt. Om man istället vill push:a en feature som en enda kommit så kan man använda sig av squash:ing. En squash kan skapa en ny commit av flera andra commit:s.

Antag att vi har utvecklat en feature på en branch som heter test. Allt är rebase:at till senaste commit på master:

Skapa en ny branch från master som heter test-squash (samma branch punkt som test branchen):

user $ git checkout -B test-squash master

Merga:a alla commit:s från test, men tryck ihop dom till en enda commit:

user $ git merge --squash test

Commit:a till test-squash:

user $ git commit -am "Squash commits on test"

Vi har nu skapat en enda commit på test-squash branch:en som innehåller summan av alla commit:s gjorda på test branch:en:

Byt till master branch:en och merge:a från test-squash (fast-forward merge):

user $ git checkout master
user $
git merge test-squash

Om vi nu push:ar master till origin/master kommer endast en commit att adderas.

Terminologi

Term Beskrivning
Bare repository Ett git repository utan workspace. Ett repository där du inte kan arbeta med filerna som versionshanteras.
Klon En kopia av ett repository. En klon innehåller normalt alla versioner av repot.
Workspace Arean där du kan jobba med alla filer. Det är här man kan editera, skapa nya filer och commit:a sina ändringar. Den delen av ett vanligt repo som inte ligger i .git katalogen.
HEAD En pekare som pekar ut den just nu valda versionen av repositoryt.
Staged (Saknar bra svensk översättning). Adderad till index men inte commit:ad.
Cached (Saknar bra svenska översättning). Se staged.
Versionshanterad fil En fil i workspace som är adderad och versionshanterad i git repositoryt.
Icke-versionshanterad fil En fil i workspace som inte är adderad och versionshanterad i git repositoryt.
Index Innehåller alla förändringar i versionshanterade filer som kommer commit:as när man kör kommandot git commit.