Tuesday, June 05, 2007

Daily thoughts - 2

    Макар че съм работил доста с Subversion днес ми се наложи да направя merge и доста се поизпотих. Инсталацията и простичкия commit, update не са всичко. Сценария е trunk, branch-1.2.0 и много учудващо branch-1.2, които е бранч на branch-1.2.0 (не знам кои го е измислил така). Картинката е следната:

+-----------------> branch-1.2
|   Merge ^
|         |
+--------------------------> branch-1.2.0
|
|
trunk --------------------------------------------->


    Задачата? Промените от branch-1.2.0 да идат в branch-1.2, но от всичко а от определен момент (commit). Един ден четох как да го направя от команден ред и днес се престраших да експериментирам.

Подготвям си нещата като вземам последните версии на "моя" и "чуждия" branch.
svn update --show-updates


Добре е да има застраховка и затова слагам един таг.
svn copy -m "Tag before merge with branch 1.2.0"  https://svn.company.com/product/branches/1.2  https://svn.company.com/product/tags/release-1.2-M01


После отивам в директорията на "чуждия" branch и искам да видя всички промени от самото създаване на branch-a до сега:
svn log --stop-on-copy -v > changes.log


Същото правя и за "моя" branch, като тука по-специялно ме интересува кога точно в създаден. Най-отдолу пише:
------------------------------------------------------------------------
r3777 | someone | 2007-04-04 18:20:31 +0300 (Wed, 04 Apr 2007) | 1 line
Changed paths:
A /branches/1.2 (from /branches/1.2.0:3776)

Creating branch for development of 1.2.x versions
------------------------------------------------------------------------


Отварям си културно changes.log и почвам да разглеждам. Ахааа ето и версията, от която нататък трябва да взема промените - r3785

Изводите. До r3777 двата branch-a са си еднакви и игнорирам промените. Намирам си версията от която нататък ми трябват промените и се готвя за merge. Все забравям, че HEAD е последната версия а не trunk-a, който е с CVS минало ще ме разбере :)
За merge се задава диапазона и после откъде да се вземе този диапазон. Плахо проверявам с --dry-run от r3785 до сега т.е. HEAD.
cd 
svn merge --dry-run -r3785:HEAD https://svn.company.com/product/branches/1.2.0

А това значи: Дай ми всички промени в branch-1.2.0 от версия 3785 до последната и ги приложи в текущия branch (1.2)

Виждам каво ме чака и се хвърлям в огъня.
svn merge -r3785:HEAD https://svn.company.com/product/branches/1.2.0

U    administration/webroot/waf/layout/porduct/core/services/assets/model/Asset.jsp
U    lib/plica-waf.jar
U    lib/plica-waf-web.jar
U    lib/plica-waf-src.jar
C    core/webroot/skin/i18n/en.js
U    core/webroot/skin/basic2/main.css
A    core/webroot/skin/adb
A    core/webroot/skin/adb/main.css
U    core/webroot/skin/super/main.css
U    core/src/java/product/extensions/reminders/model/display.properties
U    core/src/java/product/core/services/subscriptions/model/display.properties
A    core/src/js/box/adb.js
U    core/src/js/PlaybackManager.js
U    core/src/js/widgets/config.js
U    core/src/js/widgets/epg.js
U    core/src/js/widgets/reminders.js
U    core/src/js/widgets/broadcast.js
?    dir_conflicts.prej


Ух само един конфликт и нещо странно в директорията - dir_conflicts.prej. Лесно се справам с програмния конфликт.
svn resolved core/webroot/skin/i18n/en.js

Как обаче да подходя с dir_conflicts.prej? Първо какво значи това - станало е конфликт в svn properties. Ето и лекарството:
# see what we have
svn proplist .

# see the problem
less dir_conflicts.prej

# find the problem - it was in svn:ignore
svn propedit svn:ignore .

# change svn:ignore (add or remove something). In my case I have to add.
svn propset svn:ignore bin .

# do it
svn resolved .

Съвесно проверявам статуса и разликите:
svn status --show-updates
svn diff |colordiff

изтрелвам всичко
svn commit -m "Merged branch 1.2.0 to branch 1.2"


Все още не мога да свикна с Subversion, защото винаги правя аналогии с CVS-a. Много по-добър от CVS-а! Вижда ми се малко прекалено, ако разбира се ако забравим преименуването на файловете. Другото дразнещо нещо е merge-a. Ако ви се наложи да правите постоянен merge с trunk-a да речем, тогава вие и само вие трябва да държите списък за това от къде до къде сте направили merge. Какво имам в предвид. Ако в понеделник сте направили:
svn merge -r5238:HEAD http://svn.company.com/product/trunk
svm commit -m "merge commit"
Commit at 5302

Трябва да запомните това число 5302 и във вторник да почните точно от там.
svn merge -r5302:HEAD http://svn.company.com/product/trunk

Иначе ще получите много конфликти и пак ще се наложи да ги оправяте ръчно. Subversion просто не държи списък на направените merges и до къде са направени. Запазете вяра обаче в версия 1.5 това ще бъде коригирано. До тогава може да ползвате svnmerge и тези напътствия.
   И сега най-инересната част. След като синхронизирам branch-a 3 седмици с trunk и отделно активно се добавя код branch-a идва обратната задача - всичко от този branch да иде обратно в trunk. Много глупаво и напрактика двойна работа, ама нищо приемам го като предизвикателство.
cd trunk
svn merge http://svn.company.com/product/trunk http://svn.company.com/product/branches/1.2 .

с други думи всички разлики(HEAD:HEAD) в текущата директория, която е всъщност trunk-a.

No comments:

algorithms (1) cpp (3) cv (1) daily (4) emacs (2) freebsd (4) java (3) javascript (1) JSON (1) linux (2) Lisp (7) misc (8) programming (16) Python (4) SICP (1) source control (4) sql (1) думи (8)