-
1. Kom igång
- 1.1 Om versionshantering
- 1.2 En kort historik om Git
- 1.3 Vad är Git?
- 1.4 Kommandoraden
- 1.5 Installera Git
- 1.6 Första gången med Git
- 1.7 Få hjälp
- 1.8 Sammanfattning
-
2. Grunderna i Git
- 2.1 Att få tag i ett Git‑kodförråd
- 2.2 Spara ändringar i kodförrådet
- 2.3 Visa incheckningshistoriken
- 2.4 Ångra saker
- 2.5 Arbeta med fjärrkodförråd
- 2.6 Att tagga
- 2.7 Git-alias
- 2.8 Sammanfattning
-
3. Git-grenar
- 3.1 Grenar i korthet
- 3.2 Grundläggande gren- och sammanfogningsarbete
- 3.3 Grenhantering
- 3.4 Arbetsflöden med grenar
- 3.5 Fjärrgrenar
- 3.6 Ombasering
- 3.7 Sammanfattning
-
4. Git på servern
- 4.1 Protokollen
- 4.2 Konfigurera Git på en server
- 4.3 Generera din publika SSH-nyckel
- 4.4 Konfigurera servern
- 4.5 Git-demon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Tredjepartsalternativ
- 4.10 Sammanfattning
-
5. Distribuerat Git
-
6. GitHub
-
7. Git-verktyg
- 7.1 Revisionsurval
- 7.2 Interaktiv köläggning
- 7.3 Lägga undan och städa
- 7.4 Signera ditt arbete
- 7.5 Sökning
- 7.6 Skriva om historik
- 7.7 Nollställning förklarad
- 7.8 Avancerad sammanslagning
- 7.9 Rerere
- 7.10 Felsöka med Git
- 7.11 Undermoduler
- 7.12 Bunta
- 7.13 Ersätt
- 7.14 Lagring av inloggningsuppgifter
- 7.15 Sammanfattning
-
8. Anpassa Git
- 8.1 Git‑konfiguration
- 8.2 Git‑attribut
- 8.3 Git‑krokar
- 8.4 Ett exempel på Git‑upprätthållen policy
- 8.5 Sammanfattning
-
9. Git och andra system
- 9.1 Git som klient
- 9.2 Migrera till Git
- 9.3 Sammanfattning
-
10. Git bakom kulisserna
- 10.1 Lågnivådel och användardel
- 10.2 Git-objekt
- 10.3 Git-referenser
- 10.4 Packfiler
- 10.5 Refspecen
- 10.6 Överföringsprotokoll
- 10.7 Underhåll och dataåterställning
- 10.8 Miljövariabler
- 10.9 Sammanfattning
-
A1. Bilaga A: Git i andra miljöer
- A1.1 Grafiska gränssnitt
- A1.2 Git i Visual Studio
- A1.3 Git i Visual Studio Code
- A1.4 Git i IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git i Sublime Text
- A1.6 Git i Bash
- A1.7 Git i Zsh
- A1.8 Git i PowerShell
- A1.9 Sammanfattning
-
A2. Bilaga B: Bädda in Git i dina applikationer
- A2.1 Git på kommandoraden
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Bilaga C: Git-kommandon
- A3.1 Uppstart och konfiguration
- A3.2 Skaffa och skapa projekt
- A3.3 Grundläggande ögonblicksbilder
- A3.4 Grening och sammanslagning
- A3.5 Dela och uppdatera projekt
- A3.6 Inspektion och jämförelse
- A3.7 Felsökning
- A3.8 Patchning
- A3.9 E‑post
- A3.10 Externa system
- A3.11 Administration
- A3.12 Lågnivåkommandon
7.9 Git-verktyg - Rerere
Rerere
Funktionen git rerere är lite av en dold finess.
Namnet står för "reuse recorded resolution" (återanvänd sparad lösning) och, som namnet antyder, låter den dig be Git komma ihåg hur du löste en konflikt i ett diffstycke så att nästa gång den ser samma konflikt kan Git lösa den åt dig automatiskt.
Det finns flera scenarier där detta kan vara riktigt användbart.
Ett av exemplen som nämns i dokumentationen är när du vill se till att en långlivad ämnesgren till sist sammanfogas rent, men du inte vill ha en massa mellanliggande sammanslagningsincheckningar som skräpar ned din historik.
Med rerere aktiverat kan du göra enstaka sammanslagningar, lösa konflikterna och sedan backa ur sammanslagningen.
Om du gör detta kontinuerligt ska den slutliga sammanslagningen vara enkel eftersom rerere kan göra allt åt dig automatiskt.
Samma taktik kan användas om du vill hålla en gren ombaserad så att du inte behöver hantera samma ombaseringskonflikter varje gång du gör det. Eller om du vill ta en gren som du sammanfogade och löste en massa konflikter i och sedan bestämma dig för att ombasera den i stället — du kommer sannolikt inte behöva lösa alla samma konflikter igen.
En annan användning av rerere är när du sammanfogar ett gäng utvecklande ämnesgrenar till ett testbart huvud då och då, precis som Git-projektet ofta gör.
Om testerna fallerar kan du spola tillbaka sammanfogningarna och göra om dem utan ämnesgrenen som fick testerna att fallera, utan att behöva lösa konflikterna igen.
För att aktivera rerere behöver du bara köra denna konfigurationsinställning:
$ git config --global rerere.enabled true
Du kan också slå på det genom att skapa katalogen .git/rr-cache i ett specifikt kodförråd, men konfigurationsinställningen är tydligare och aktiverar funktionen globalt för dig.
Nu ska vi titta på ett enkelt exempel, likt det vi såg tidigare.
Säg att vi har en fil som heter hello.rb som ser ut så här:
#! /usr/bin/env ruby
def hello
puts 'hello world'
end
I den ena grenen ändrar vi ordet “hello” till “hola”, och i en annan gren ändrar vi “world” till “mundo”, precis som tidigare.
När vi sammanfogar de två grenarna får vi en sammanslagningskonflikt:
$ git merge i18n-world
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Recorded preimage for 'hello.rb'
Automatic merge failed; fix conflicts and then commit the result.
Du bör lägga märke till den nya raden Recorded preimage for FILE där.
Annars ser det exakt ut som en vanlig sammanslagningskonflikt.
Här kan rerere tala om några saker.
Normalt skulle du köra git status här för att se vad som är i konflikt:
$ git status
# On branch master
# Unmerged paths:
# (use "git reset HEAD <file>..." to unstage)
# (use "git add <file>..." to mark resolution)
#
# both modified: hello.rb
#
Men git rerere kan också tala om vad den har registrerat för för‑sammanslagningsläge med git rerere status:
$ git rerere status
hello.rb
Och git rerere diff visar det aktuella läget för lösningen — vad du började med att lösa och vad du har löst det till.
$ git rerere diff
--- a/hello.rb
+++ b/hello.rb
@@ -1,11 +1,11 @@
#! /usr/bin/env ruby
def hello
-<<<<<<<
- puts 'hello mundo'
-=======
+<<<<<<< HEAD
puts 'hola world'
->>>>>>>
+=======
+ puts 'hello mundo'
+>>>>>>> i18n-world
end
Dessutom (och detta är inte egentligen relaterat till rerere) kan du använda git ls-files -u för att se konfliktfilerna och versionerna före, vänster och höger:
$ git ls-files -u
100644 39804c942a9c1f2c03dc7c5ebcd7f3e3a6b97519 1 hello.rb
100644 a440db6e8d1fd76ad438a49025a9ad9ce746f581 2 hello.rb
100644 54336ba847c3758ab604876419607e9443848474 3 hello.rb
Nu kan du lösa det så att det bara blir puts 'hola mundo' och köra git rerere diff igen för att se vad rerere kommer att komma ihåg:
$ git rerere diff
--- a/hello.rb
+++ b/hello.rb
@@ -1,11 +1,7 @@
#! /usr/bin/env ruby
def hello
-<<<<<<<
- puts 'hello mundo'
-=======
- puts 'hola world'
->>>>>>>
+ puts 'hola mundo'
end
Det betyder i praktiken att när Git ser en diffstyckeskonflikt i en hello.rb‑fil som har “hello mundo” på ena sidan och “hola world” på den andra, kommer den att lösa den till “hola mundo”.
Nu kan vi markera den som löst och checka in den:
$ git add hello.rb
$ git commit
Recorded resolution for 'hello.rb'.
[master 68e16e5] Merge branch 'i18n'
Du kan se att den skrev "Recorded resolution for FILE".
Nu ska vi ångra den sammanslagningen och sedan ombasera den ovanpå vår master‑gren i stället.
Vi kan flytta tillbaka vår gren med git reset som vi såg i Nollställning förklarad.
$ git reset --hard HEAD^
HEAD is now at ad63f15 i18n the hello
Sammanslagningen är ångrad. Nu ombaserar vi ämnesgrenen.
$ git checkout i18n-world
Switched to branch 'i18n-world'
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: i18n one word
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Resolved 'hello.rb' using previous resolution.
Failed to merge in the changes.
Patch failed at 0001 i18n one word
Nu fick vi samma sammanslagningskonflikt som förväntat, men titta på raden Resolved FILE using previous resolution.
Om vi tittar på filen ser vi att den redan är löst; det finns inga konfliktmarkörer i den.
#! /usr/bin/env ruby
def hello
puts 'hola mundo'
end
Dessutom visar git diff hur den automatiskt löstes igen:
$ git diff
diff --cc hello.rb
index a440db6,54336ba..0000000
--- a/hello.rb
+++ b/hello.rb
@@@ -1,7 -1,7 +1,7 @@@
#! /usr/bin/env ruby
def hello
- puts 'hola world'
- puts 'hello mundo'
++ puts 'hola mundo'
end
Du kan också återskapa konfliktläget för filen med git checkout:
$ git checkout --conflict=merge hello.rb
$ cat hello.rb
#! /usr/bin/env ruby
def hello
<<<<<<< ours
puts 'hola world'
=======
puts 'hello mundo'
>>>>>>> theirs
end
Vi såg ett exempel på detta i Avancerad sammanslagning.
Men för tillfället löser vi den igen genom att helt enkelt köra git rerere:
$ git rerere
Resolved 'hello.rb' using previous resolution.
$ cat hello.rb
#! /usr/bin/env ruby
def hello
puts 'hola mundo'
end
Vi har nu löst filen automatiskt igen med den mellanlagrade lösningen i rerere.
Du kan nu lägga till och fortsätta ombaseringen för att slutföra den.
$ git add hello.rb
$ git rebase --continue
Applying: i18n one word
Så om du gör många omsammanfogningar, eller vill hålla en ämnesgren uppdaterad med din master‑gren utan en massa sammanslagningar, eller om du ofta ombaserar, kan du slå på rerere för att göra livet lite enklare.