статья на основе письма raorn
raorn@
Как вы все наверно знаете, наш mutt1.5 это такой mutt2ng-new с большим количеством «левых» патчей. Из-за такого количества каждое обновление версии превращается в изощрённую пытку для мантейнера. По идее git должен бы помочь решить подобные проблемы...
Сначала я посмотрел на kernel-image. Там каждый патч живёт в отдельном бранче, перед релизом всё мержится в master. Примерно так:
master * merge-C /| / * merge-B / /| / / * merge-A / / /| / / / * merge-upstream / / / /| * | | | | patchC | * | | | patchB | | * | | patchA \ \ \| | ±±* | upstream | |
По каждому патчу конфликт разруливается сначала в patchX, потом в merge-X. При обновлении версии upstream и/или patchX приходится делать маленький закат солнца вручную с повторным разруливаением всех конфликтов. Это не ядро и патчи имеют обыкновение пересекаться во множестве мест.
Результат этого изврата ещё некоторое время можно будет наблюдать в моём mutt1.5.git.
Есть второй способ, который посоветовал мне voins (на примере его stklos.git и Window Maker?.git). upstream мержится в patchA, patchA в patchB и так далее. При этом конфликты разруливаются практически только один раз при мерже patchN-1 в patchN.
Картинко будет примерно такое:
master * |\ | * patchC | |\ | | * patchB | | |\ | | | * patchA | | | |\ | | | | * upstream | | | | |
Что делать при обновлении upstream и/или patchX?
1. upstream
patchA <– upstream
patchB <– patchA
...
master <– patchZ
2. patchX
branch patchX-tmp upstream
накладываем новый patchX в patchX-tmp
patchX-tmp <– patch(X-1)
patchX <– patchX-tmp
branch -d patchX-tmp
patch(X+1) <– patchX
...
master <– patchZ
3. patchX и upstream
До patch(X-1) поступаем аналогично 1., потом аналогично 2.
Автоматизировать процесс можно с помощью утилиты gear-merge. Утилита довольно простая. Краткий синтаксис правил описан в заголовке (vim /usr/bin/gear-merge), опции описаны в man-странице.
Вот так выглядит файл правил для мёржа на примере inn.git: