-
1. Aan de slag
- 1.1 Over versiebeheer
- 1.2 Een kort historisch overzicht van Git
- 1.3 Wat is Git?
- 1.4 De commando-regel
- 1.5 Git installeren
- 1.6 Git klaarmaken voor eerste gebruik
- 1.7 Hulp krijgen
- 1.8 Samenvatting
-
2. Git Basics
-
3. Branchen in Git
- 3.1 Branches in vogelvlucht
- 3.2 Eenvoudig branchen en mergen
- 3.3 Branch-beheer
- 3.4 Branch workflows
- 3.5 Branches op afstand (Remote branches)
- 3.6 Rebasen
- 3.7 Samenvatting
-
4. Git op de server
- 4.1 De protocollen
- 4.2 Git op een server krijgen
- 4.3 Je publieke SSH sleutel genereren
- 4.4 De server opzetten
- 4.5 Git Daemon
- 4.6 Slimme HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Hosting oplossingen van derden
- 4.10 Samenvatting
-
5. Gedistribueerd Git
-
6. GitHub
-
7. Git Tools
- 7.1 Revisie Selectie
- 7.2 Interactief stagen
- 7.3 Stashen en opschonen
- 7.4 Je werk tekenen
- 7.5 Zoeken
- 7.6 Geschiedenis herschrijven
- 7.7 Reset ontrafeld
- 7.8 Mergen voor gevorderden
- 7.9 Rerere
- 7.10 Debuggen met Git
- 7.11 Submodules
- 7.12 Bundelen
- 7.13 Vervangen
- 7.14 Het opslaan van inloggegevens
- 7.15 Samenvatting
-
8. Git aanpassen
- 8.1 Git configuratie
- 8.2 Git attributen
- 8.3 Git Hooks
- 8.4 Een voorbeeld van Git-afgedwongen beleid
- 8.5 Samenvatting
-
9. Git en andere systemen
- 9.1 Git als een client
- 9.2 Migreren naar Git
- 9.3 Samenvatting
-
10. Git Binnenwerk
- 10.1 Binnenwerk en koetswerk (plumbing and porcelain)
- 10.2 Git objecten
- 10.3 Git Referenties
- 10.4 Packfiles
- 10.5 De Refspec
- 10.6 Uitwisseling protocollen
- 10.7 Onderhoud en gegevensherstel
- 10.8 Omgevingsvariabelen
- 10.9 Samenvatting
-
A1. Bijlage A: Git in andere omgevingen
- A1.1 Grafische interfaces
- A1.2 Git in Visual Studio
- A1.3 Git in Visual Studio Code
- A1.4 Git in Eclipse
- A1.5 Git in Sublime Text
- A1.6 Git in Bash
- A1.7 Git in Zsh
- A1.8 Git in PowerShell
- A1.9 Samenvatting
-
A2. Bijlage B: Git in je applicaties inbouwen
- A2.1 Commando-regel Git
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Bijlage C: Git Commando’s
- A3.1 Setup en configuratie
- A3.2 Projecten ophalen en maken
- A3.3 Basic Snapshotten
- A3.4 Branchen en mergen
- A3.5 Projecten delen en bijwerken
- A3.6 Inspectie en vergelijking
- A3.7 Debuggen
- A3.8 Patchen
- A3.9 Email
- A3.10 Externe systemen
- A3.11 Beheer
- A3.12 Binnenwerk commando’s (plumbing commando’s)
7.9 Git Tools - Rerere
Rerere
De functionaliteit van git rerere
is een beetje onbekend.
De naam staat voor “reuse recorded resolution” (hergebruik opgenomen resoluties/oplossingen) en zoals de naam al aangeeft, stelt het je in staat om Git te vragen te onthouden hoe je een bepaald deel van een conflict hebt opgelost zodat Git, als het de volgende keer een vergelijkbaar conflict ziet, deze automatisch voor je kan oplossen.
Er zijn een aantal scenarios waarin deze functionaliteit erg handig zou kunnen zijn.
Een van de voorbeelden dat in de documentatie wordt genoemd is dat je ervoor wilt zorgen dat een langlevende topic branch netjes zal mergen maar dat je niet een berg tussenliggende merge commits hoeft te maken die je historie vervuilen.
Met rerere
ingeschakeld kan je af en toe mergen, de conflicten oplossen en dan de merge terugdraaien.
Als je dit doorlopend doet, zou de laatste merge eenvoudig moeten zijn omdat rerere
alles gewoon automatisch voor je kan doen.
Deze zelfde taktiek kan gebruikt worden als je een branch rebased wilt houden zodat je niet elke keer met dezelfde rebasing conflicten te maken krijgt elke keer als je dit doet. Of als je een branch hebt die je hebt gemerged en daar een bergje conflicten hebt opgelost en dan besluit om deze toch maar te rebasen — je zult waarschijnlijk niet dezelfde conflicten willen doorlopen.
Een andere toepassing van rerere
is er een waar je een af en toe aantal in ontwikkeling zijnde topic branches wilt mergen in een testbare head, zoals in het Git project zelf ook vaark gebeurt.
Als de tests falen, kan je de merges terugdraaien en ze weer doen zonder de topic branch die de tests liet falen zonder de conflicten opnieuw te moeten oplossen.
Om de rerere
functionaliteit in te schakelen, kan je eenvoudigweg de volgende configuratie setting aanroepen:
$ git config --global rerere.enabled true
Je kunt het ook inschakelen door de .git/rr-cache
directory in een specifieke repository aan te maken, maar de configuratie setting is duidelijker en het kan globaal gedaan worden.
Laten we nu eens een eenvoudig voorbeeld bekijken, vergelijkbaar met de vorige. Laten we zeggen dat we een bestand hebben dat er als volgt uitziet:
#! /usr/bin/env ruby
def hello
puts 'hello world'
end
In de ene branch hebben we het woord “hello” in “hola” gewijzigd, en daarna in de andere branch veranderen we “world” in “mundo”, net zoals eerder.
Als we de twee branches mergen, zullen we een merge conflict krijgen:
$ 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.
Je zult de nieuwe regel Recorded preimage for FILE
hier opmerken.
Verder zou het er precies als een normale merge conflict uit moeten zien.
Op dit moment kan rerere
ons een aantal dingen vertellen.
Normaalgesproken zou je een git status
kunnen aanroepen om te zien waar de conflicten zitten:
$ 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
#
Echter, git rerere
zal je ook vertellen waar het de pre-merge status voor heeft opgenomen met git rerere status
:
$ git rerere status
hello.rb
En git rerere diff
zal ons de huidige staat van de resolutie laten zien — waar je mee begonnen bent met oplossen en waar je het in hebt opgelost.
$ 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
Daarnaast (en dit is eigenlijk niet gerelateerd aan rerere
), kan je ls-files -u
gebruiken om de conflicterende bestanden en de voor, links en rechts versies te zien:
$ git ls-files -u
100644 39804c942a9c1f2c03dc7c5ebcd7f3e3a6b97519 1 hello.rb
100644 a440db6e8d1fd76ad438a49025a9ad9ce746f581 2 hello.rb
100644 54336ba847c3758ab604876419607e9443848474 3 hello.rb
Je kunt het oplossen zodat het alleen puts 'hola mundo'
wordt en je kunt het rerere diff
commando nog een keer aanroepen om te zien wat rerere zal onthouden:
$ 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
Dit zegt eigenlijk dat, wanneer Git een conflict in een deel van een hello.rb
bestand ziet waar “hello mundo” aan de ene en “hola world” aan de andere kant staat, het zal oplossen naar “hola mundo”.
Nu kunnen we het als opgelost markeren en committen:
$ git add hello.rb
$ git commit
Recorded resolution for 'hello.rb'.
[master 68e16e5] Merge branch 'i18n'
Je kunt zien aan de boodschap "Recorded resolution for FILE" zien dat het de resolutie voor het bestand heeft opgeslagen.
Laten we nu die merge eens ongedaan maken, en in plaats daarvan deze op onze master branch gaan rebasen.
We kunnen onze branch terugzetten door reset
te gebruiken zoals we zagen in Reset ontrafeld.
$ git reset --hard HEAD^
HEAD is now at ad63f15 i18n the hello
Onze merge is ongedaan gemaakt. Laten we de topic branch gaan rebasen.
$ 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
We hebben nu dezelfde merge conflict zoals verwacht, maar kijk eens naar de regel met Resolved FILE using previous resolution
.
Als we nu het bestand bekijken zullen we zien dat het al is opgelost, er staan geen merge conflict markeringen in.
#! /usr/bin/env ruby
def hello
puts 'hola mundo'
end
Ook zal git diff
je laten zien hoe het automatisch opnieuw was opgelost:
$ 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
Je kunt ook de staat van het conflicterende bestand opnieuw creeëren met het git checkout
commando:
$ git checkout --conflict=merge hello.rb
$ cat hello.rb
#! /usr/bin/env ruby
def hello
<<<<<<< ours
puts 'hola world'
=======
puts 'hello mundo'
>>>>>>> theirs
end
We zagen hier eerder een voorbeeld van in Mergen voor gevorderden.
Voor nu echter, laten we het opnieuw oplossen door eenvoudigweg weer rerere
aan te roepen:
$ git rerere
Resolved 'hello.rb' using previous resolution.
$ cat hello.rb
#! /usr/bin/env ruby
def hello
puts 'hola mundo'
end
We hebben het bestand automatisch her-opgelost door de opgeslagen rerere
resolutie te gebruiken.
Je kunt het nu toevoegen en de rebase vervolgen om het te voltooien.
$ git add hello.rb
$ git rebase --continue
Applying: i18n one word
Dus, als je vaak opnieuw merget, of je wilt een topic branch up-to-date houden met je master branch zonder talloze merges, of als je vaak rebaset, kan je rerere
aanzetten om je leven wat aangenamer te maken.