Iteam
GitHub

Reintegrate merge i Subversion

Subversion är en väldigt bra källkodshanteringsplattform på många olika sätt, men en stor nackdel är det dåliga stödet för merge. Medan det är väldigt lätt och resurssnålt att göra en ny branch är det inte helt enkelt att göra en merge igen. Problemet har varit att det inte funnits något bra sätt att få med all historik. Oftast resulterar detta i att när mergen väl görs så sker det med en enda stor commit där de tidigare incheckningarnas logg är inkopierad. Det här gör att det är väldigt svårt i efterhand att se exakt när en viss förändring gjordes och av vem.

Med version 1.5 av Subversion som kom i somras så har emellertid detta till viss del åtgärdas, främst genom det nya stödet för ”reintegrate merge”. Typfallet för denna sorts merge är när man som utvecklare skall göra en större förändring i koden och därför skapar en separat branch för denna förändring (en s.k. ”topic branch”). När förändringen är klar skall denna mergas in i huvudkoden. Oftast är sådana här branches ganska kortlivade; när den väl är integrerad i huvudbranchen så tas den bort.

Det är här som ”reintegrate merge” kommer in i bilden. Genom att använda denna funktion kan Subversion själv ta hand om att se till att alla loggmeddelanden hanteras på rätt sätt, så att när man efteråt går igenom loggen ser de ursprungliga incheckningarna istället för en enda stor.

I det här exemplet kommer vi att använda TortioseSvn, men kommandoraden fungerar precis lika bra. Det krävs att man har version 1.5+ av TortoiseSvn.

Vi har i vårt repository en trunk, från vilken en branch vid namn ”integrate_demo” har skapats. I denna branch har vi sedan gjort några ändringar som vi nu vill få in i trunken.

Vi högerklickar därför på ”trunk”-katalogen och väljer ”Merge”, varpå detta fönster visas. Här väljer vi det mittersta valet, ”Reintegrate a branch”. För att kunna använda denna måste vi dock först se till att den lokala trunken som vi skall göra en merge in i inte har några oincheckade ändringar i sig.

I nästa dialog så anger vi varifrån vi vill göra vår merge, vilket i det här fallet är branchen ”integrate_demo”.

Den tredje och sista dialogen erbjuder ett flertal olika valmöjligheter; i vårt fall så nöjer vi oss dock med standardvärdena. Kom ihåg att alltid göra en ”Test merge” först för att se om några problem uppstår.

Om allt ser bra ut så är det bara att trycka på ”Merge” varpå själva mergen utförs. Det enda som nu återstår är att göra en commit på den lokala trunken. Vad som då skiljer sig här gentemot det tidigare sättet som man gjorde merge är att man nu inte behöver ta med kopior av alla de logg-meddelanden som fanns i branchen: allt detta tar subversion själv hand om. Det räcker således med ett dylikt meddelande:

Det här fungerar hur bra som helst i de flesta fall, men ibland så händer det att man får detta felmeddelandet:

Error: Cannot reintegrate from <branch> yet
Error: Some revisions have been merged under it that have not been merged
Error: into the reintegration target; merge them first, then retry.

Väldigt kryptiskt och tyvärr felvisande eftersom lösningen oftast inte är den som föreslås. Detta kommer nämligen av att problem uppstår om subversion själv tror att det gjorts en merge in i topic-branchen. Anledningen till att den tror detta är att den hittar flaggan ”merge-info” i branchen. Detta är en ny flagga som tillkommit iomed det nya merge-stödet i 1.5. Genom användandet av denna flagga kan subversion själv hålla reda på vilka revisioner som blivit mergade och på så sätt undvika att samma revision blir integrerade flera gånger. Problemet är bara att denna flagga även sätts vid vissa andra operationer såsom kopiering eller omdöpning av filer. Detta är en känd bugg som Subversions /Utvecklingsgrupp själva håller på att lösa till version 1.5.1. Tills dess att detta är löst så är dock lösningen på detta problemet att se till att denna flagga tas bort överallt där den är satt i topic-branchen, förutom i roten på branchen. För att göra detta kan man antingen använda TortoiseSVN och manuellt hitta alla filer eller kataloger med denna flagga och ta bort den, eller använda kommandotolken. Eftersom det ju kan röra sig om ganska många filer är nog det senare att föredra.

I vårt exempel ovan innebär det då att vi först går in i roten på vår topic-branch, dvs.

cd C:\demo\checkedout\branches\integrate_demo

Därefter kör vi följande kommando vilket kommer att ta bort alla instanser av ”merge-info”-flaggan (OBS! Gör bara det här om du inte har gjort en merge in till topicbranchen. Om så är fallet så bör du göra såsom felmeddelandet anger och göra en merge av dessa in till trunken först.)

svn propdel -R svn:mergeinfo *

Efter att detta är gjort är det bara att göra en commit, ex.

svn commit –m ”Removed bogus merge info before integrating.”

och se fortsätta med reintegrate merge.

Mer info om detta finns på

http://subversion.tigris.org/svn_1.5_releasenotes.html#merge-tracking

http://www.svnforum.org/2017/viewtopic.php?t=6718

Erik Hjortsberg
2008-11-14