Samenvoegingsconflicten in Git
Versiebeheersystemen hebben alles te maken met het beheren van bijdragen tussen meerdere gedistribueerde auteurs (meestal ontwikkelaars). Soms proberen meerdere ontwikkelaars dezelfde inhoud te bewerken. Als ontwikkelaar A probeert code te bewerken die ontwikkelaar B aan het bewerken is, kan er een conflict optreden. Om het optreden van conflicten te verlichten, zullen ontwikkelaars in afzonderlijke geïsoleerde branches werken. De primaire verantwoordelijkheid van de git merge
-opdracht is het combineren van afzonderlijke branches en het oplossen van eventuele tegenstrijdige bewerkingen.
Samenvoegingsconflicten begrijpen
Conflicten ontstaan over het algemeen wanneer twee mensen dezelfde regels in een bestand hebben gewijzigd, of als een ontwikkelaar een bestand heeft verwijderd terwijl een andere ontwikkelaar het wijzigde. In deze gevallen kan Git niet automatisch bepalen wat juist is. Conflicten hebben alleen invloed op de ontwikkelaar die de samenvoeging uitvoert: de rest van het team is zich niet bewust van het conflict. Git zal het bestand markeren als conflicterend en het samenvoegingsproces stoppen. Het is dan de verantwoordelijkheid van de ontwikkelaars om het conflict op te lossen.
Soorten samenvoegingsconflicten
Een samenvoeging kan op twee afzonderlijke punten tot een conflicterende status leiden: bij het starten en tijdens een samenvoegingsproces. Hieronder volgt een bespreking van hoe elk van deze conflictscenario's moet worden aangepakt.
Git slaagt er niet in om het samenvoegen te starten
Een samenvoeging zal niet starten wanneer Git ziet dat er wijzigingen zijn in de werkmap of in het staging-gedeelte van het huidige project. Git slaagt er niet in om de samenvoeging te starten omdat deze openstaande wijzigingen kunnen worden overgeschreven door de commits die worden samengevoegd. Wanneer dit gebeurt, komt dit niet door conflicten met andere ontwikkelaars, maar door conflicten met openstaande lokale wijzigingen. De lokale staat moet worden gestabiliseerd met behulp van git stash
, git checkout
, git commit
of git reset
. Bij een samenvoegingsfout bij het starten zal het volgende foutbericht worden weergegeven:
error: Entry '<fileName>' not uptodate. Cannot merge. (Changes in working directory)
Git krijgt een storing tijdens de samenvoeging
Een fout TIJDENS een samenvoeging duidt op een conflict tussen de huidige lokale branch en de branch die wordt samengevoegd. Dit duidt op een conflict met een andere ontwikkelaarscode. Git zal zijn best doen om de bestanden samen te voegen, maar laat zaken openstaan die je handmatig kunt oplossen in de conflicterende bestanden. Bij een fout halverwege de samenvoeging zal het volgende foutbericht worden weergegeven:
gerelateerd materiaal
Uitgebreid Git log
Oplossing bekijken
Git leren met Bitbucket Cloud
error: Entry '<fileName>' would be overwritten by merge. Cannot merge. (Changes in staging area)
Een samenvoegingsconflict creëren
Om echt vertrouwd te raken met samenvoegingsconflicten, simuleert de volgende sectie een conflict dat moet worden onderzocht en opgelost. Het voorbeeld maakt gebruik van een Unix-achtige Git-opdrachtregelinterface om de voorbeeldsimulatie uit te voeren.
$ mkdir git-merge-test
$ cd git-merge-test
$ git init .
$ echo "this is some content to mess with" > merge.txt
$ git add merge.txt
$ git commit -am"we are commiting the inital content"
[main (root-commit) d48e74c] we are commiting the inital content
1 file changed, 1 insertion(+)
create mode 100644 merge.txt
Dit codevoorbeeld voert een reeks opdrachten uit met het volgende resultaat:
- Maak een nieuwe map met de naam
git-merge-test
, ga naar die map en initialiseer deze als een nieuwe Git-repo; - Maak een nieuw tekstbestand
merge.txt
met wat inhoud; - Voeg
merge.txt
toe aan de repo en maak een commit.
Nu hebben we een nieuwe repo met één branch, main
, en een bestand merge.txt
met inhoud. Vervolgens zullen we een nieuwe branch maken die zal worden gebruikt als tegenstrijdige samenvoeging.
$ git checkout -b new_branch_to_merge_later
$ echo "totally different content to merge later" > merge.txt
$ git commit -am"edited the content of merge.txt to cause a conflict"
[new_branch_to_merge_later 6282319] edited the content of merge.txt to cause a conflict
1 file changed, 1 insertion(+), 1 deletion(-)
De volgorde van de voorgaande opdracht bereikt het volgende:
- maak en bekijk een nieuwe branch genaamd
new_branch_to_merge_later
; - overschrijf de inhoud in
merge.txt
; - commit de nieuwe inhoud.
Met deze nieuwe branch (new_branch_to_merge_later
) hebben we een commit gemaakt die de inhoud van merge.txt
overschrijft.
git checkout main
Switched to branch 'main'
echo "content to append" >> merge.txt
git commit -am"appended content to merge.txt"
[main 24fbe3c] appended content to merge.tx
1 file changed, 1 insertion(+)
Deze reeks commando's controleert de main
-branch, voegt inhoud toe aan merge.txt
en maakt een commit. Dit brengt onze voorbeeld-repo nu in een staat waarin we 2 nieuwe commits hebben: één in de main
-branch en één in de branch new_branch_to_merge_later
. Voer op dit moment git merge new_branch_to_merge_later
uit en kijk wat er gebeurt!
$ git merge new_branch_to_merge_later
Auto-merging merge.txt
CONFLICT (content): Merge conflict in merge.txt
Automatic merge failed; fix conflicts and then commit the result.
BOEM 💥. Er ontstaat een conflict. Bedankt dat je ons dit laat weten Git!
Samenvoegingsconflicten herkennen
Zoals we uit het voorgaande voorbeeld hebben ervaren, zal Git een beschrijving produceren die ons laat weten dat er een CONFLICT heeft plaatsgevonden. We kunnen meer inzicht krijgen door de opdracht git status uit te voeren
$ git status
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: merge.txt
De uitvoer van git status
geeft aan dat er niet-samengevoegde paden zijn als gevolg van een conflict. Het bestand merge.text
wordt nu weergegeven met een gewijzigde staat. Laten we het bestand bekijken en kijken wat er is gewijzigd.
$ cat merge.txt
<<<<<<< HEAD
this is some content to mess with
content to append
=======
totally different content to merge later
>>>>>>> new_branch_to_merge_later
Hier hebben we de opdracht cat
gebruikt om de inhoud van het merge.txt
uit te voeren. We kunnen een aantal vreemde nieuwe toevoegingen zien.
<<<<<<< HEAD
=======
>>>>>>> new_branch_to_merge_later
Je moet deze nieuwe regels zien als 'scheiders in een conflict'. De regel =======
is het 'middelpunt' van het conflict. Alle inhoud tussen het midden en de regel <<<<<<< HEAD
is inhoud die bestaat in de huidige branch 'main' waarnaar de HEAD
-verwijzing verwijst. Als alternatief is alle inhoud tussen het midden en >>>>>>> new_branch_to_merge_later
inhoud die aanwezig is in onze branch voor samenvoeging.
Samenvoegingsconflicten oplossen met behulp van de opdrachtregel
De meest directe manier om een samenvoegingsconflict op te oplossen, is door het conflicterende bestand te bewerken. Open het bestand merge.txt
in je favoriete editor. Laten we in ons voorbeeld eenvoudig alle conflictscheidingstekens verwijderen. De gewijzigde inhoud van merge.txt
moet er dan als volgt uitzien:
this is some content to mess with
content to append
totally different content to merge later
Zodra het bestand is bewerkt, moet je git add merge.txt
gebruiken om de nieuwe samengevoegde inhoud op te voeren. Om de samenvoeging te voltooien, maak je een nieuwe commit door het volgende uit te voeren:
git commit -m "merged and resolved the conflict in merge.txt"
Git zal zien dat het conflict is opgelost en maakt een nieuwe merge-commit om de samenvoeging af te ronden.
Git-opdrachten die kunnen helpen bij het oplossen van samenvoegingsconflicten
Algemene hulpmiddelen
git status
De opdracht 'status' wordt veelvuldig gebruikt wanneer je met Git werkt en zal tijdens een samenvoeging helpen bij het identificeren van conflicterende bestanden.
git log --merge
Als je het argument --merge
doorgeeft aan de git log
-opdracht levert dit een logboek op met een lijst van commits die conflicteren tussen de samengevoegde branches.
git diff
diff
helpt bij het vinden van verschillen tussen statussen van een repository/bestanden. Dit is nuttig bij het voorspellen en voorkomen van samenvoegingsconflicten.
Hulpmiddelen voor wanneer git er niet in slaagt om een samenvoeging te starten
git checkout
checkout
kan worden gebruikt voor het ongedaan maken van wijzigingen in bestanden of voor het wijzigen van branches
git reset --mixed
reset
kan worden gebruikt om wijzigingen in de werkmap en het staging-gedeelte ongedaan te maken.
Hulpmiddelen voor wanneer git conflicten ontstaan tijdens een samenvoeging
git merge --abort
Het uitvoeren van git merge
met de optie --abort
zal het samenvoegingsproces verlaten en de branch terugbrengen naar de status voordat de merge begon.
git reset
Git reset
kan worden gebruikt tijdens een samenvoegingsconflict om conflicterende bestanden terug te zetten naar een bekende, goede, staat
Samenvatting
Samenvoegingsconflicten kunnen een intimiderende ervaring zijn. Gelukkig biedt Git krachtige hulpmiddelen die helpen bij het laveren door en oplossen van conflicten. Git kan de meeste samenvoegingen zelfstandig afhandelen met automatische samenvoegingsfuncties. Er ontstaat een conflict wanneer twee afzonderlijke branches bewerkingen bevatten van dezelfde regel in een bestand of wanneer een bestand is verwijderd in de ene branch maar in de andere is bewerkt. Er zullen waarschijnlijk conflicten optreden wanneer u in een teamomgeving werkt.
Er zijn veel hulpmiddelen om samenvoegingsconflicten op te lossen. Git heeft tal van opdrachtregelhulpprogramma's die we hier hebben besproken. Ga voor meer gedetailleerde informatie over deze hulpprogramma's naar de specifieke pagina's voor git log, git reset, git status, git checkout en git reset. Naast Git bieden veel hulpprogramma's van externe partijen gestroomlijnde ondersteuningsfuncties voor samenvoegingsconflicten.
Deel dit artikel
Volgend onderwerp
Aanbevolen artikelen
Bookmark deze resources voor meer informatie over soorten DevOps-teams of voor voortdurende updates over DevOps bij Atlassian.