Vad är sammanslagningskonflikter?
Här diskuterar vi hur lösning av sammanslagningskonflikter hjälper utvecklare att skapa det bästa resultatet från två överlappande källor.
GitHub-flödet
GitHub är inte bara en plattform för samarbete inom programvaruutveckling utan erbjuder även ett föreskrivet arbetsflöde som utformats för att optimera användningen av de olika funktionerna i GitHub. Även om den här lektionen specifikt omfattar sammanslagningskonflikter rekommenderar vi att du först läser Förstå GitHub-flödet.
Slå samman grenar
Tänk dig ett scenario där en utvecklare skapar en gren med namnet feature-branch
som bybber på main
och skapar två incheckningar. När det här inträffar slår någon annan samman en orelaterad pull-begäran till main
. Vad händer när vår utvecklare försöker sammanfoga feature-branch
tillbaka till main
?
Svaret: det beror på.
Även om feature-branch
skapades från main
, baserades den inte på själva grenen. I stället var det baserat på HEAD-incheckningen för main
vid tidpunkten. Den känner inte till main
alla incheckningar som har tillämpats på sedan dess. De incheckningar som den för närvarande spårar, kommer inte nödvändigtvis att vika in i det aktuella tillståndet för grenen utan att skriva över de senaste ändringarna.
Om det visar sig att incheckningarna feature-branch
inte överlappar parallella incheckningar som gjorts main
sedan grenen skapades finns det inga problem. Nya filer kan läggas till. Det går att ta bort oförändrade filer. Rader med kod som ändrades i main
kan ändras i feature-branch
så länge det parallella arbetet inte ändrades sedan feature-branch
skapades.
Men vad händer om båda uppsättningarna i incheckningen inkluderar ändringar av samma rader med kod? Detta sammanslagningsförsök skulle misslyckas på grund av en sammanslagningskonflikt.
Vad är sammanslagningskonflikter?
Sammanslagningskonflikter sker när en utvecklare försöker sammanslå ändringar som oavsiktligt skriver över parallella ändringar. Det spelar ingen roll hur de andra ändringarna slogs samman i basgrenen. Git skriver inte automatiskt över en uppsättning ändringar till förmån för en annan. I stället pekar den ut dem på den person som försöker slå samman så att de kan lösa dem på jämförelsegrenen innan de försöker slå samman igen.
Lösa sammanslagningskonflikter
För att hjälpa dig att lösa sammanslagningskonflikter genererar GitHub en tillfällig hybridfil som innehåller skillnaderna från varje gren. Konventionen är att texten från jämförelsegrenen visas ovanför basgrenen, separerad med en rad likhetstecken (=======
).
Du kan använda den här vyn för att redigera filen direkt om ändringarna är mindre. Om du bestämmer dig för att behålla den checkas slutresultatet in i jämförelsegrenen. Om sammanfogningen är mer involverad kanske du föredrar att arbeta med den med hjälp av andra utvecklingsverktyg. Hur som helst måste du komma ihåg att ta bort eventuella förgreningar från koden innan du genomför det. Om du glömmer att ta bort dessa markörer när du genomför konfliktlösningen finns de kvar i filen och kommenteras inte ut.
Kommentar
I den här lektionen beskrivs hur du löser sammanslagningskonflikter i ett webbläsarsammanhang. Det finns också många utvecklingsplattformar, till exempel Visual Studio, som erbjuder integrerade lösningar på sammanslagningskonflikter.
När alla sammanslagningskonflikter har lösts på din gren kan du försöka slå samman igen.
Undvika sammanslagningskonflikter
Vissa sammanslagningskonflikter kan undvikas. Alla sammanslagningar kan potentiellt generera sammanslagningskonflikter för andra pull-begäranden som väntar på att godkännas. Ett effektivt sätt att minska komplexiteten i sammanslagningskonflikter är dock att hämta din gren ofta.
Hämta tidigt och ofta
Kommandot git pull
hämtar alla basgrens incheckningar som ännu inte har tillämpats på din aktuella gren. Det är konceptuellt likt kommandot Hämta senaste som många versionskontrollsystem använder för att du ska kunna uppdatera din lokala kod till den senaste versionen. När du hämtar uppdateringar för din gren sammanfogar du alla ändringar som har inträffat sedan grenen skapades (eller senast hämtades).
Om du hämtar uppdateringar av din gren kan det leda till sammanslagningskonflikter, men det är okej. Du skulle få dem senare ändå, och genom att få dem tidigare är de ofta lättare att ta itu med.
Förutom att minska effekten av sammanslagningskonflikter kan du genom att hämta uppdateringar också integrera genomförda ändringar i din gren när du arbetar. På så sätt kan du lösa eventuella problem tidigare. Det kan till exempel finnas klassdefinitionsändringar i andra filer som gör att koden inte längre kompileras. Den här ändringen skulle inte orsaka en sammanslagningskonflikt när du sammanfogade senare, men den skulle bryta versionen om du inte testade den först. Vi rekommenderar att du hämtar uppdateringar ofta för att hålla din gren så nära dess bas som möjligt.
Städa historik med git-ombasering
Kommandot git rebase
(eller git pull --rebase
) skriver om din grenhistorik för att använda den aktuella HEAD-incheckningen för basgrenen som bas. Med andra ord uppdateras din gren så att den fungerar som om den bara förgrenades från basgrenens aktuella tillstånd. Den här ombasen innebär att alla dina ändringar jämförs med det senaste tillståndet för basgrenen och inte den ursprungliga incheckningen som du ursprungligen förgrenade från. Ombasering kan göra det enklare att spåra historiken efter den slutliga sammanfogningen, eftersom dina incheckningar följer de tidigare parallella incheckningarna linjärt. Det är en bra idé att ombasera grenen direkt innan du slår samman uppströms.
Läs mer om git-ombasering och att lösa sammanslagningkonflikter efter en git-ombasering.