border=0

"176.59.111.119 - 176.59.111.119"

Hoe samenvoegconflicten in git op te lossen

Is er een goede manier om uit te leggen hoe je samenvoegconflicten kunt oplossen in git?

4274
02 окт. Spoike set 02 oct. 2008-10-02 14:31 '08 om 14.31 uur 2008-10-02 14:31 uur
@ 37 antwoorden
  • 1
  • 2

Probeer: git mergetool

Het opent de grafische interface die door elk conflict loopt en u kunt kiezen hoe u combineert. Soms vereist dit achteraf een beetje handmatig bewerken, maar meestal is het voldoende op zich. Dit is veel beter dan alles handmatig te doen.

Volgens de opmerking van @JoshGlover:

De opdracht opent niet noodzakelijk de GUI als u deze niet installeert. Het uitvoeren van git mergetool voor mij leidde tot het gebruik van vimdiff . Je kunt een van de volgende hulpmiddelen installeren om het te gebruiken: meld , opendiff , tkdiff , xxdiff , xxdiff , tortoisemerge , gvimdiff , diffuse , ecmerge , p4merge , araxis , vimdiff , emerge .

Hieronder ziet u een voorbeeld van de procedure voor het gebruik van vimdiff om samenvoegconflicten op te lossen. Via deze link

Stap 1 : Voer de volgende opdrachten uit in uw terminal

 git config merge.tool vimdiff git config merge.conflictstyle diff3 git config mergetool.prompt false 

Hiermee wordt vimdiff ingesteld als het standaard samenvoeghulpprogramma.

Stap 2 : Voer de volgende opdracht uit in de terminal

 git mergetool 

Stap 3 : U ziet het vimdiff-scherm in het volgende formaat.

  +----------------------+ | | | | |LOCAL |BASE |REMOTE | | | | | +----------------------+ | MERGED | | | +----------------------+ 

Deze 4 soorten

LOCAL is het bestand van de huidige branch.

BASE - een gemeenschappelijke voorouder, hoe het bestand er vóór beide wijzigingen uitzag

REMOTE - een bestand dat u samenvoegt in uw filiaal

SAMENGESTELD - het resultaat van de fusie, dit is wat is opgeslagen in de repo

U kunt tussen deze weergaven navigeren met ctrl+w U kunt rechtstreeks naar de SAMENGESTELDE weergave gaan met ctrl+w en j .

Meer informatie over vimdiff-navigatie hier en hier.

Stap 4 U kunt de MERGED als volgt bewerken.

Als u wijzigingen wilt ontvangen van REMOTE

 :diffg RE 

Als u wijzigingen wilt ontvangen van BASE

 :diffg BA 

Als u wijzigingen wilt ontvangen van LOCAL

 :diffg LO 

Stap 5 Opslaan, afsluiten, vergrendelen en wissen

:wqa opslaan en afsluiten vi

git commit -m "message"

git clean Verwijder extra bestanden (bijvoorbeeld * .orig) gemaakt met het diff-hulpmiddel.

2535
02 окт. antwoord wordt gegeven door Peter Burns 02 okt. 2008-10-02 20:50 '08 om 20:50 uur 2008-10-02 20:50

Hier is een waarschijnlijk precedent, van boven:

U gaat enkele wijzigingen aanbrengen, maar helaas weet u niet:

 git fetch origin git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Updating a030c3a..ee25213 error: Entry 'filename.c' not uptodate. Cannot merge. 

Dus je update en probeer het opnieuw, maar je hebt een conflict:

 git add filename.c git commit -m "made some wild and crazy changes" git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Auto-merging filename.c CONFLICT (content): Merge conflict in filename.c Automatic merge failed; fix conflicts and then commit the result. 

Dus besloot je om de veranderingen te bekijken:

 git mergetool 

Oh, ik, oh, mijn, stroomopwaarts heeft sommige dingen veranderd, maar gewoon om mijn veranderingen te gebruiken ... nee ... hun veranderingen ...

 git checkout --ours filename.c git checkout --theirs filename.c git add filename.c git commit -m "using theirs" 

En dan proberen we de laatste keer.

 git pull origin master From ssh://gitosis@example.com:22/projectname * branch master -> FETCH_HEAD Already up-to-date. 

Ta-da!

1625
04 авг. het antwoord wordt gegeven door CoolAJ86 04 aug. 2010-08-04 20:04 '10 om 20:04 uur 2010-08-04 20:04

Ik merk dat samenvoegingshulpprogramma's me zelden helpen conflicten of oplossingen te begrijpen. Ik kijk gewoonlijk meer naar conflictmarkers in een teksteditor en gebruik git log als een aanvulling.

Hier zijn enkele tips:

Raad één

De beste die ik heb gevonden is om de diff3-merge-conflictstijl te gebruiken:

git config merge.conflictstyle diff3

Het creëert conflictmarkers zoals dit:

 <<<<<<< Changes made on the branch that is being merged into. In most cases, this is the branch that I have currently checked out (ie HEAD). ||||||| The common ancestor version. ======= Changes made on the branch that is being merged in. This is often a feature/topic branch. >>>>>>> 

Het middelste deel is hoe de gemeenschappelijke voorouder er uitzag. Dit is handig omdat je het kunt vergelijken met de bovenste en onderste versies om beter te begrijpen wat er in elke tak is veranderd, waardoor je een beter idee krijgt van wat het doel van elke verandering is.

Als het conflict uit slechts enkele regels bestaat, maakt dit het conflict in de regel heel duidelijk. (Weten hoe je een conflict oplost, is heel anders: je moet weten waar andere mensen aan werken. Als je in de war bent, is het het beste om deze persoon gewoon in je kamer te bellen zodat ze kunnen zien waarnaar je op zoek bent.)

Als het conflict >

Vervolgens kan ik de volgende opdrachten uitvoeren om twee situaties te bekijken die het conflict hebben veroorzaakt:

 diff common mine diff common theirs 

Dit is niet hetzelfde als het gebruik van de samenvoeg-tool, omdat de samenvoeg-tool alle niet-conflicterende diff-hunks zal bevatten. Ik vind het storend.

Tip twee

Iemand heeft dit al genoemd, maar het begrijpen van de intentie achter elk woordverschil is meestal nuttig om te begrijpen waar het conflict vandaan komt en hoe ermee om te gaan.

 git log --merge -p <name of file> 

Dit toont alle commits die betrekking hebben op dit bestand tussen de gemeenschappelijke voorouder en de twee hoofden die u samenvoegt. (Dus het bevat niet de commits die al bestaan ​​in beide takken voor de samenvoeging.) Dit helpt om verschillen te negeren die duidelijk geen factor zijn in je huidige conflict.

Tip drie

Controleer uw wijzigingen met geautomatiseerde hulpmiddelen.

Als u geautomatiseerde tests hebt, voert u deze uit. Als u pluksel hebt , voert u het uit. Als het een bouwproject is, moet het worden gebouwd voordat je het voltooit, enz. In alle gevallen moet u een beetje testen om ervoor te zorgen dat uw wijzigingen niet worden verbroken. (Heck, zelfs samenvoegen zonder conflicten kan de werkende code doorbreken.)

Tip vier

Plan vooruit; communiceren met collega's.

Door vooruit te plannen en het besef dat anderen werken, kan fusieconflicten worden voorkomen en / of kunnen ze eerder worden opgelost - terwijl de details nog steeds relevant zijn.

Als u bijvoorbeeld weet dat u en een andere persoon aan verschillende refactorings werken die dezelfde reeks bestanden beïnvloeden, moet u ruim van tevoren met elkaar praten en beter begrijpen welke soorten wijzigingen iedereen van u aan het doen is. U kunt veel tijd en moeite besparen als u de geplande wijzigingen beurtelings uitvoert en niet parallel.

Voor grote refactorings die een groot stuk code kruisen, zou je serieus moeten overwegen om sequentieel te werken: iedereen stopt met werken aan dit gebied van code, en één persoon voert een volledige refactoring uit.

Als je niet consequent kunt werken (vanwege tijdelijke druk), dan zal praten over verwachte fusieconflicten je op zijn minst helpen om problemen eerder op te lossen, terwijl de details nog vers zijn. Als een werknemer bijvoorbeeld binnen een week een destructieve serie commits maakt, kunt u deze tak een of twee keer per dag deze week samenvoegen / opnieuw inpakken. Op die manier kunt u, als u samenvoegingen vindt / omleidt, deze sneller oplossen dan wanneer u een paar weken wacht om alles samen te voegen tot één groot stuk.

Tip vijf

Als je niet zeker bent van de fusie, forceer het dan niet.

Een samenvoeging kan overweldigend zijn, vooral wanneer er veel conflicterende bestanden zijn en conflictmarkeringen honderden regels overspannen. Bij het evalueren van softwareprojecten houden we vaak onvoldoende rekening met toeslagen, zoals het verwerken van een gekke fusie, dus het voelt als een echte weerstand om verschillende uren te besteden aan het analyseren van elk conflict.

Op de >

696
29 сент. Antwoord gegeven door Mark E. Haase 29 september 2011-09-29 00:08 '11 om 0:08 2011-09-29 00:08
  • Bepaal welke bestanden in conflict zijn (Git zou je dit moeten vertellen).

  • Open elk bestand en leer de verschillen kennen; Git markeert ze. Ik hoop dat het duidelijk zal zijn welke versie van elk blok moet worden bewaard. Mogelijk moet u dit bespreken met andere ontwikkelaars die de code hebben voltooid.

  • Zodra je het conflict in het git add the_file bestand hebt opgelost, git add the_file .

  • Zodra je alle conflicten hebt opgelost, start je git rebase --continue of een commando dat Git zei wanneer je klaar bent.

326
02 окт. het antwoord is davetron5000 02 okt gegeven. 2008-10-02 15:41 '08 om 15:41 uur 2008-10-02 15:41

Controleer de antwoorden in de Cancel Git Cancel- vraag, met name Charles Bailey's Answer , die laat zien hoe verschillende versies van een probleembestand te bekijken, bijvoorbeeld

100
03 окт. antwoord gegeven door Pat Notz op 03 oktober 2008-10-03 18:15 '08 om 18:15 uur 2008-10-03 18:15

Conflicten samenvoegen vindt plaats wanneer tegelijkertijd wijzigingen in een bestand worden aangebracht. Hier is hoe het op te lossen.

git CLI

Hier zijn de eenvoudige stappen die u moet nemen als u zich in een conflicttoestand bevindt:

  • Let op de lijst met conflicterende bestanden: git status (in de sectie Unmerged paths ).
  • Los conflicten afzonderlijk op voor elk bestand met een van de volgende benaderingen:

    • Gebruik de GUI om conflicten op te lossen: git mergetool (de gemakkelijkste manier).

    • Om een ​​externe / andere versie te accepteren, gebruikt u: git checkout --theirs path/file . Hiermee worden lokale wijzigingen die u in dit bestand hebt aangebracht, geweigerd.

    • Om de lokale / onze versie te accepteren, gebruik je: git checkout --ours path/file

      U moet echter voorzichtig zijn, omdat de verwijderde wijzigingen om de een of andere reden zijn verwijderd.

      Gerelateerd: Wat is de exacte betekenis van "de onze" en "zij" in git?

    • Bewerk de conflicterende bestanden handmatig en zoek het codeblok tussen <<<<< / >>>>> , selecteer vervolgens de versie hierboven of hieronder ===== . Zie: Hoe conflicten worden gepresenteerd .

    • Pad- en bestandsnaamconflicten kunnen worden opgelost met git add / git rm .

  • Tot slot, bekijk de bestanden klaar voor commit met behulp van: git status .

    Als je nog steeds bestanden onder Unmerged paths en je hebt het conflict handmatig opgelost, laat Git dan weten dat je het hebt opgelost: git add path/file .

  • Als alle conflicten met succes zijn opgelost, kopieer de wijzigingen: git commit -a en klik zoals gewoonlijk op de verwijderde.

Zie ook: Een samenvoegconflict oplossen vanaf de opdrachtregel in GitHub

DiffMerge

Ik heb met succes DiffMerge gebruikt, waarmee bestanden visueel kunnen worden vergeleken en samengevoegd in Windows, macOS en Linux / Unix.

Het toont grafisch veranderingen tussen 3 bestanden en maakt automatisch samenvoegen mogelijk (wanneer het veilig is) en volledige controle over de bewerking van het resulterende bestand.

2019

05 авг. het antwoord is gegeven kenorb 05 aug. 2015-08-05 17:29 '15 om 17:29 2015-08-05 17:29

Als je regelmatig kleine commits maakt, begin dan met het bekijken van commit opmerkingen met git log --merge . Dan zal git diff je conflicten laten zien.

Voor conflicten met meerdere regels is het gemakkelijker om te zien wat er in de externe GUI-tool gebeurt. Ik hou van opendiff - Git ondersteunt ook vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff, emerge out of the box en je kunt anderen installeren: git config merge.tool "your.tool" je gekozen tool installeren en dan git mergetool na mislukkende samenvoegen toont u verschillen in context.

Telkens wanneer u een bestand bewerkt om een ​​conflict op te lossen, wordt de index door git add filename bijgewerkt en wordt uw diff niet meer weergegeven. Wanneer alle conflicten zijn verwerkt en hun bestanden zijn git add -ed, zal git commit de samenvoeging voltooien.

75
02 окт. het antwoord is gegeven Paul 02 oct. 2008-10-02 19:11 '08 om 19:11 uur 2008-10-02 19:11

Zie Hoe conflicten worden gepresenteerd of in Git, de git merge documentatie git merge , om te begrijpen wat conflictconflictmarkers zijn.

Bovendien wordt in de sectie Conflicten oplossen beschreven hoe conflicten kunnen worden opgelost:

Na het bekijken van het conflict, kunt u twee dingen doen:

  • Besluit om niet samen te voegen. De enige schoonmakers die u nodig hebt, zijn een resetindexbestand voor het fixeren van de HEAD voor de inverse transformatie 2. en voor het wissen van de wijzigingen in het werkdorp die zijn aangebracht in 2. en 3; git merge --abort kan hiervoor worden gebruikt.

  • Los conflicten op. Git markeert conflicten in de werkboom. Bewerk de bestanden in het formulier en git add ze toe aan de index. Gebruik git commit om een ​​deal af te sluiten.

Je kunt in conflict komen met verschillende tools:

  • Gebruik mergetool. git mergetool om een ​​grafische mergetool uit te voeren die door een samenvoeging zal werken.

  • Kijk naar de verschillen. git diff geeft een driezijdige diff weer, waarbij veranderingen in zowel MERGE_HEAD als MERGE_HEAD .

  • Kijk naar de verschillen tussen elke tak. git log --merge -p <path> zal diff eerst tonen voor de HEAD versie en vervolgens de MERGE_HEAD versie.

  • Kijk naar de originelen. git show :1:filename toont de gemeenschappelijke voorouder, git show :2:filename toont de versie van HEAD en git show :3:filename toont de versie van MERGE_HEAD .

Je kunt ook meer lezen over het merk van het samenvoegconflict en hoe je ze kunt oplossen in het gedeelte Pro Git Main Merge Conflicts.

43
14 июля '13 в 21:34 2013-07-14 21:34 het antwoord wordt gegeven door user456814 14 juli 13 om 21:34 2013-07-14 21:34

Voor Emacs gebruikers die semi-handmatige samenvoegconflicten willen oplossen:

 git diff --name-status --diff-filter=U 

Geeft alle bestanden weer die een conflictoplossing vereisen.

Open elk van deze bestanden één voor één of allemaal tegelijk:

 emacs $(git diff --name-only --diff-filter=U) 

Wanneer je een buffer bezoekt die bewerkt moet worden in Emacs, voer je in

 ALT+x vc-resolve-conflicts 

Dit opent drie buffers (mine, hen en outputbuffer). Navigeer door op "n" (volgende gebied), "p" (voorspellingsgebied) te drukken. Druk op "a" en "b" om mijn of uw gebied naar de uitvoerbuffer respectievelijk te kopiëren. En / of bewerk de uitvoerbuffer direct.

Wanneer u klaar bent: druk op "q". Emacs vraagt ​​je of je deze buffer wilt opslaan: ja. Wanneer de buffer is voltooid, markeert u deze als opgelost bij het starten vanaf de caster:

 git add FILENAME 

Na het werken met alle soorten buffers

 git commit 

om de samenvoeging te voltooien.

36
23 февр. het antwoord is gegeven eci 23 feb. 2013-02-23 02:04 '13 om 2:04 2013-02-23 02:04

Ik wil mijn versie of hun versie volledig, of ik wil de individuele wijzigingen zien en een beslissing nemen voor elk van hen.

Accepteer mijn of hun versie volledig :

Accepteer mijn versie (lokaal, onze):

 git checkout --ours -- <filename> git add <filename> # Marks conflict as resolved git commit -m "merged bla bla" # An "empty" commit 

Accepteer hun versie (verwijder ze):

 git checkout --theirs -- <filename> git add <filename> git commit -m "merged bla bla" 

Als u het voor alle conflictbestanden wilt doen , voert u het volgende uit:

 git merge --strategy-option ours 

of

 git merge --strategy-option theirs 

Bekijk alle wijzigingen en accepteer ze afzonderlijk.

  1. git mergetool
  2. Bekijk de wijzigingen en accepteer elke versie voor elk van hen.
  3. git add <filename>
  4. git commit -m "merged bla bla"

Standaard werkt mergetool op de opdrachtregel . Het gebruik van de opdrachtregel mergetool moet een afzonderlijk probleem zijn.

U kunt hier ook een visuele tool voor installeren, bijvoorbeeld meld en run

 git mergetool -t meld 

De lokale (onze), "basis" of "uniforme" versie (het huidige resultaat van de samenvoeging) en de afstandsbediening (en) worden geopend. Sla de samengevoegde versie op als je klaar bent, voer git mergetool -t meld tot je "geen bestanden meer hoeft samen te voegen", ga dan naar stap 3. en 4.

28
29 сент. Het antwoord wordt gegeven door Noidea 29 september . 2016-09-29 16:02 '16 om 16:02 uur 2016-09-29 16:02

Voer de volgende stappen uit om samenvoegconflicten in Git op te lossen:

  1. Controleer Git Status : Git Status

  2. Verkrijg de patch set: git fetch (controleer de juiste patch van je git commit)

  3. Pak de lokale vertakking uit (in mijn voorbeeld is dit temp1): git checkout -b temp1

  4. Extract recente inhoud van master: git pull --rebase originamaster

  5. Voer mergetool uit, controleer de conflicten en herstel ze ... en controleer de wijzigingen in de externe branch met uw huidige branch: git mergetool

  6. Controleer de status opnieuw: git-status

  7. Verwijder overbodige bestanden die lokaal zijn gemaakt met mergetool, meestal maakt mergetool een extra bestand met de extensie * .orig. Verwijder dit bestand, want het is slechts een duplicaat, corrigeer de wijzigingen lokaal en voeg de juiste versie van uw bestanden toe. git voeg #your_changed_correct_files toe

  8. Controleer de status opnieuw: git-status

  9. Zet de wijzigingen in dezelfde identifier (dit vermijdt een nieuwe afzonderlijke set van fixes): git commit --amend

  10. Push to master -tak: git push (naar je Git-repository)

28
16 апр. Het antwoord is gegeven door Chhabilal 16 apr. 2015-04-16 10:02 '15 om 10:02 2015-04-16 10:02

Simpel gezegd, als u goed weet dat wijzigingen in een van de archieven niet be>

 git checkout . --ours 

laat veranderingen toe ten gunste van je repository , of

 git checkout . --theirs 

laat veranderingen toe ten gunste van een andere of hoofdrepository .

Of misschien moet u de GUI-samenvoegtoepassing gebruiken om door de bestanden te p4merge , bijvoorbeeld de p4merge samenvoegfunctie of een naam schrijven die u al hebt ingesteld.

 git mergetool -t p4merge 

en na het voltooien van het bestand moet je opslaan en sluiten om de volgende te openen.

27
26 янв. Antwoord gegeven door Mohamed Selim op 26 jan. 2016-01-26 20:42 '16 om 20:42 uur 2016-01-26 20:42

U kunt samenvoegconflicten op verschillende manieren oplossen, zoals anderen hebben uitgelegd.

Ik denk dat de echte sleutel is om te weten hoe veranderingen met lokale en externe opslagplaatsen verlopen. De sleutel tot dit is het begrijpen van de tracking-takken. Ik vond dat ik de tracking-tak beschouw als het "ontbrekende deel in het midden" tussen mij, mijn lokale, daadwerkelijke bestandsdirectory en de afstandsbediening, gedefinieerd als oorsprong.

Ik persoonlijk gewend geraakt aan twee dingen om dit te voorkomen.

In plaats van:

 git add . git commit -m"some msg" 

Wat heeft twee nadelen -

a) Alle nieuwe / gewijzigde bestanden zijn toegevoegd en kunnen enkele ongewenste wijzigingen bevatten.
b) U kunt de bestandslijst niet eerst bekijken.

Dus in plaats daarvan:

 git add file,file2,file3... git commit # Then type the files in the editor and save-quit. 

Op deze manier bespreek je bewuster welke bestanden worden toegevoegd en kun je ook door de lijst bladeren en een beetje meer nadenken met de editor voor het bericht. Ik merk dat het ook mijn commit-berichten verbetert wanneer ik de editor voor volledig scherm gebruik, in plaats van de -m optie.

[Update - naarmate de tijd verstreek, schakelde ik meer over naar:

 git status # Make sure I know whats going on git add . git commit # Then use the editor 

]

Ook (en meer passend voor uw situatie), probeer ik te vermijden:

 git pull 

of

 git pull origin master.