-
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)
3.2 Branchen in Git - Eenvoudig branchen en mergen
Eenvoudig branchen en mergen
Laten we eens door een eenvoudig voorbeeld van branchen en mergen stappen met een workflow die je zou kunnen gebruiken in de echte wereld. Je zult deze stappen volgen:
-
Werken aan een website.
-
Een branch aanmaken voor een nieuw verhaal waar je aan werkt.
-
Wat werk doen in die branch.
Dan ga je een telefoontje krijgen dat je een ander probleem direct moet repareren; je moet een snelle reparatie (hotfix) maken. Je zult het volgende doen:
-
Switchen naar je productie-branch.
-
Een branch aanmaken om de hotfix toe te voegen.
-
Nadat het getest is de hotfix-branch mergen, en dat naar productie pushen.
-
Terugswitchen naar je originele verhaal en doorgaan met werken.
Eenvoudig branchen
Als eerste, laten we zeggen dat je aan je project werkt en al een paar commits hebt gemaakt op de master
-branch.
Je hebt besloten dat je gaat werken aan probleem #53 in wat voor systeem je bedrijf ook gebruikt om problemen te registreren.
Om een branch aan te maken en er meteen naartoe te schakelen, kun je het git checkout
commando uitvoeren met de -b
optie:
$ git checkout -b iss53
Switched to a new branch "iss53"
Dit is een afkorting voor:
$ git branch iss53
$ git checkout iss53
Je doet wat werk aan je website en doet wat commits.
Door dat te doen beweegt de iss53
-branch vooruit, omdat je het uitgecheckt hebt (dat wil zeggen, je HEAD
wijst ernaar):
$ vim index.html
$ git commit -a -m 'added a new footer [issue 53]'
iss53
-branch is naar voren verplaatst met je werkNu krijg je het telefoontje dat er een probleem is met de website, en je moet het meteen repareren.
Met Git hoef je de reparatie niet tegelijk uit te leveren met de iss53
wijzigingen die je gemaakt hebt, en je hoeft ook niet veel moeite te doen om die wijzigingen terug te draaien voordat je kunt werken aan het toepassen van je reparatie in productie.
Het enige wat je moet doen is terugschakelen naar je master
-branch.
Maar voordat je dat doet, weet dat als je werk-directory of staging area wijzigingen bevatten die nog niet gecommit zijn en conflicteren met de branch die je gaat uitchecken, Git je niet laat omschakelen.
Het beste is om een schone werkstatus te hebben als je tussen branches gaat schakelen.
Er zijn manieren om hier mee om te gaan (te weten, stashen en commit ammending) die we later gaan behandelen in Stashen en opschonen.
Voor nu laten we aannemen dat je alle wijzigingen gecommit hebt, zodat je kunt switchen naar je master
-branch:
$ git checkout master
Switched to branch 'master'
Hierna is je project-werk-directory precies zoals het was voordat je begon te werken aan probleem #53, en je kunt je concentreren op je hotfix. Dit is een belangrijk punt om te onthouden: als je van branch overschakelt, herstelt Git je werk-directory zodanig dat deze eruit ziet als het toen je voor de laatste keer daarnaar hebt gecommit. Het voegt automatisch bestanden toe, verwijdert en wijzigt ze om er zeker van te zijn dat je werkkopie eruit ziet zoals de branch eruit zag toen je er voor het laatst op committe.
Vervolgens heb je een hotfix te doen.
Laten we een hotfix
-branch maken om op te werken totdat het af is:
$ git checkout -b hotfix
Switched to a new branch 'hotfix'
$ vim index.html
$ git commit -a -m 'fixed the broken email address'
[hotfix 1fb7853] fixed the broken email address
1 file changed, 2 insertions(+)
master
Je kunt je tests draaien, jezelf ervan verzekeren dat de hotfix is wat je wilt, en uiteindelijk de hotfix
-branch mergen in je master-branch en het naar productie uitrollen.
Je doet dit met het git merge
commando:
$ git checkout master
$ git merge hotfix
Updating f42c576..3a0874c
Fast-forward
index.html | 2 ++
1 file changed, 2 insertions(+)
Je zult de uitdrukking “Fast forward” zien in die merge.
Omdat de commit C4
waar de branch hotfix
die je in-mergede naar wees direct voor de commit C2
ligt, waar je op staat, zet Git simpelweg de pointer naar voren.
Om het op een andere manier te zeggen: als je een commit probeert te mergen met een commit die bereikt kan worden door de historie van eerste commit te volgen, zal Git de dingen vereenvoudigen door de verwijzing vooruit te verplaatsen omdat er geen afwijkend werk is om te mergen; dit wordt een “fast forward” genoemd.
Je wijziging zit nu in de snapshot van de commit waar de master
-branch naar wijst, en je kunt je wijziging uitrollen.
master
is fast-forwarded naar hotfix
Nadat je super-belangrijke reparatie uitgerold is, ben je klaar om terug te schakelen naar het werk dat je deed voordat je onderbroken werd.
Maar, eerst ga je de hotfix
-branch verwijderen, omdat je die niet langer nodig hebt - de master
-branch wijst naar dezelfde plek.
Je kunt het verwijderen met de -d
optie op git branch
:
$ git branch -d hotfix
Deleted branch hotfix (3a0874c).
Nu kun je switchen naar je werk-in-uitvoering-branch voor probleem #53 en doorgaan met daaraan te werken.
$ git checkout iss53
Switched to branch "iss53"
$ vim index.html
$ git commit -a -m 'finished the new footer [issue 53]'
[iss53 ad82d7a] finished the new footer [issue 53]
1 file changed, 1 insertion(+)
iss53
Het is nuttig om hier op te merken dat het werk dat je in de hotfix
-branch gedaan hebt, niet in de bestanden van je iss53
-branch zit.
Als je dat binnen moet halen, dan kun je de master
-branch in de iss53
-branch mergen door git merge master
uit te voeren, of je kunt wachten met die wijzigingen te integreren tot het moment dat je het besluit neemt de iss53
-branch in de master
te trekken.
Eenvoudig mergen (samenvoegen)
Stel dat je besloten hebt dat je probleem #53 werk gereed is en klaar bent om het te mergen in de master
-branch.
Om dat te doen, zul je de iss53
-branch mergen zoals je die hotfix
-branch eerder hebt gemerged.
Het enige dat je hoeft te doen is de branch uit te checken waar je in wenst te mergen en dan het git merge
commando uit te voeren:
$ git checkout master
Switched to branch 'master'
$ git merge iss53
Merge made by the 'recursive' strategy.
index.html | 1 +
1 file changed, 1 insertion(+)
Dit ziet er iets anders uit dan de hotfix
merge die je eerder gedaan hebt.
In dit geval is je ontwikkelhistorie afgeweken van een eerder punt.
Omdat de commit op de branch waar je op zit geen directe voorouder is van de branch waar je in merget, moet Git wat werk doen.
In dit geval doet Git een eenvoudige drieweg-merge, gebruikmakend van de twee snapshots waarnaar gewezen wordt door de uiteinden van de branch en de gezamenlijke voorouder van die twee.
In plaats van de branch-pointer alleen maar vooruit te verplaatsen, maakt Git een nieuw snapshot dat het resultaat is van deze drieweg-merge en maakt automatisch een nieuwe commit die daarnaar wijst. Dit wordt een merge-commit genoemd, en is bijzonder in die zin dat het meer dan één ouder heeft.
Nu dat je werk gemerged is, is er geen verdere noodzaak meer voor de iss53
-branch.
Je kunt deze verwijderen en daarna handmatig de ticket in het ticket-volgsysteem sluiten:
$ git branch -d iss53
Eenvoudige merge conflicten
Af en toe verloopt dit proces niet zo soepel.
Als je hetzelfde gedeelte van hetzelfde bestand op een andere manier hebt gewijzigd in twee branches die je merget, dan zal Git niet in staat zijn om ze netjes te mergen.
Als je reparatie voor probleem #53 hetzelfde gedeelte van een bestand heeft gewijzigd als de hotfix
, dan krijg je een merge conflict dat er ongeveer zo uit ziet:
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
Git heeft niet automatisch een nieuwe merge-commit gemaakt.
Het heeft het proces gepauzeerd zolang jij het conflict aan het oplossen bent.
Als je wilt zien welke bestanden nog niet zijn gemerged op enig punt na een merge conflict, dan kun je git status
uitvoeren:
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
Alles wat merge-conflicten heeft en wat nog niet is opgelost wordt getoond als unmerged. Git voegt standaard conflict-oplossingsmarkeringen toe aan de bestanden die conflicten hebben, zodat je ze handmatig kunt openen en die conflicten kunt oplossen. Je bestand bevat een sectie die er zo ongeveer uit ziet:
<<<<<<< HEAD:index.html
<div id="footer">contact : email.support@github.com</div>
=======
<div id="footer">
please contact us at support@github.com
</div>
>>>>>>> iss53:index.html
Dit betekent dat de versie in HEAD
(jouw master
-branch, omdat dat degene was die je uitgecheckt had toen je het merge-commando uitvoerde) is het bovenste gedeelte van dat blok (alles boven de ======
), terwijl de versie in je iss53
-branch eruit ziet zoals alles in het onderste gedeelte.
Om het conflict op te lossen, moet je één van de twee gedeeltes kiezen of de inhoud zelf mergen.
Je zou bijvoorbeeld dit conflict op kunnen lossen door het hele blok met dit te vervangen:
<div id="footer">
please contact us at email.support@github.com
</div>
Deze oplossing bevat een stukje uit beide secties, en de <<<<<<<
, =======
, en >>>>>>>
regels zijn volledig verwijderd.
Nadat je elk van deze secties opgelost hebt in elk conflicterend bestand, voer dan git add
uit voor elk van die bestanden om het als opgelost te markeren.
Het bestand stagen markeert het als opgelost in Git.
Als je een grafische applicatie wil gebruiken om deze problemen op te lossen, kun je git mergetool
uitvoeren, wat een toepasselijk grafische merge-applicatie opstart dat je door de conflicten heen leidt:
$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html
Normal merge conflict for 'index.html':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (opendiff):
Als je een andere dan de standaard merge-tool wilt gebruiken (Git koos opendiff
in dit geval, omdat het commando uitgevoerd werd op een Mac), dan kun je alle ondersteunde applicaties opgesomd zien na “one of the following tools.”
Type de naam van de applicatie die je liever gebruikt.
Noot
|
Als je een meer geavanceerde applicatie wilt gebruiken om ingewikkelde merge conflicten op te lossen: we behandelen merging uitgebreider in Mergen voor gevorderden. |
Nadat je de merge applicatie afsluit, vraagt Git je of de merge succesvol was.
Als je het script vertelt dat dit het geval is, dan staget dit script het bestand voor je om het als opgelost te markeren.
Je kunt git status
nogmaals uitvoeren om je ervan te verzekeren dat alle conflicten opgelost zijn:
$ git status
On branch master
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
modified: index.html
Als je het daar mee eens bent, en je gecontroleerd hebt dat alles waar conflicten in zaten gestaged is, dan kun je git commit
typen om de merge-commit af te ronden.
Het commit-bericht ziet er standaard ongeveer zo uit:
Merge branch 'iss53'
Conflicts:
index.html
#
# It looks like you may be committing a merge.
# If this is not correct, please remove the file
# .git/MERGE_HEAD
# and try again.
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
# modified: index.html
#
Je kunt dat bericht aanpassen met details over hoe je het conflict opgelost hebt, als je denkt dat dat behulpzaam zal zijn voor anderen die in de toekomst naar deze merge kijken - waarom je hebt gedaan wat je gedaan hebt, als dat niet vanzelfsprekend is.