Friday, February 25, 2011

Mercurial for team members collaboration

В моя екип често се налага да се работи от двама или трима за реализация на нова фукционалност.

Фирмата политика е да се ползва Subversion, така че за да се обмени временен код е необходимо
да се миние през "централния" Subversion, да се обменят файлове или patches.
Това може и да сработи ако са двама човека, но става много по-трудно ако са повече. Да не говорим, че по този начин много лесно се пополират бъгове.
Затова погледахме към дистрибутивните системи за версии (DVCS), каквито са Git и Mercurial.
Каква ни беше целта?

1. Лесно да обменяме промени в кода.
2. Лесно да поправяме кода на другия
3. Лесен merge
4. Работа от вкъщи
5. В Subversion да отиват само неща, които са напълно завършени.
6. QA екипа да може да взема временен код от всеки от нас.


Да, това е възможно. Mercurial ни се видя по-интуитивен и затова избрахме него.
Ето и инфраструктурата, която направихме.

1. Направихме клон на Subversion проекта с hgsubversion и го кръстихме Develop

На определен за целта сървър инсталираме Mercurial и правим потребител с това име.
В неговата директория .hgrc конфигурирана ето така:
[ui]
username = Mercurial Administrator  (mercurial@example.com)
merge = internal:merge

[auth]
project.prefix = url to Subversion repository
project.username = subversion user name
project.password = subversion user password

[web]
contact = develop_admin@example.com
description = Develop Mercurial Repository
style = gitweb
allow_archive = bz2 gz
allow_push = *
push_ssl = false

[alias]
tip = log -r tip
. = summary

[extensions]
pretxnchangegroup.forbid_2heads = path to where "forbid_2head.py" is located
fetch =
rebase =
bookmarks =
progress =
color =
hgext.mq =
hgext.extdiff =
hgext.graphlog =
hgsubversion = path to where hgsubversion was build

[defaults]
diff = --unified 5
cdiff = -q
commit = -v

[diff]
git=True
showfunc = 1
unified = 8

[extdiff]
cmd.cdiff = colordiff
opts.cdiff = -uprN

[bookmarks]
track.current = True

[hooks]
changegroup=hg diff --stat -r $HG_NODE -r tip
# Prevent "hg pull" if MQ patches are applied.
prechangegroup.mq-no-pull = ! hg qtop > /dev/null 2>&1
# Prevent "hg push" if MQ patches are applied.
preoutgoing.mq-no-push = ! hg qtop > /dev/null 2>&1
# Prevent "hg update" if MQ patches are applied.
preupdate.mq-no-update = ! hg qtop > /dev/null 2>&1
Няколко неща трябва да бъдат инсталирани - colordiff и hgsubversion. За да "сервира" нещата не използаме вградения сервер в Mercurial, а пускаме Apache. Подобна конфигурация може да видите тук Картинката изглежда ето така:
Master всъшност е Subversion trunk. По този начин избягваме неприятнатa операция merge през Subversion. От тук нататък всичко става в Mercurial и само готови и проверени неща отиват в Subversion. Много много важно нещо да не забравя да кажа - Master не трябва да има "разклонения" т.е. трябва да се забрани "dual head". За целта слагаме "forbid_2head.py" 2. Всеки от екипа прави клониниг от Develop Ето как изглежда работата ни:
За целта всеки от нас си настройва локален Mercurial сървър.
[ui]
username = zlatozar (zlatozar@example.com)

[alias]
tip = log -r tip
. = summary
, = glog -l15 --template '\033[33;40m{rev} \033[37;40m{desc|firstline|fill68} \033[1;30;40m({date|age} by {author|person})\033[0;37;40m \033[33;40m{tags}\033[37;40m \033[35;40m{branches}\033[37;40m\n\n'

[web]
contact = zlatozar@example.com
description = Zlatozar's Public Repository
style = gitweb
#allow_push = *
push_ssl = false
allow_archive = bz2 gz

[extensions]
fetch =
rebase =
bookmarks =
progress =
color =
hgext.mq =
hgext.extdiff =
hgext.graphlog =

[defaults]
diff = --unified 5
cdiff = -q
commit = -v

[diff]
git=True
showfunc = 1
unified = 8

[extdiff]
cmd.kdiff3 =

[bookmarks]
track.current = True

[merge-tools]
kdiff3.args = $base $local $other -o $output

[hooks]
changegroup=hg diff --stat -r $HG_NODE -r tip
# Prevent "hg pull" if MQ patches are applied.
prechangegroup.mq-no-pull = ! hg qtop > /dev/null 2>&1
# Prevent "hg push" if MQ patches are applied.
preoutgoing.mq-no-push = ! hg qtop > /dev/null 2>&1
# Prevent "hg update" if MQ patches are applied.
preupdate.mq-no-update = ! hg qtop > /dev/null 2>&1
На локалната машина трябва да се инсталира - mercurial, colordiff и kdiff3. 3. Всеки от екипа има публично хранилище, от което може да се вземат промените. Скрипта, с който всеки си пуска сървъра е следния:
#!/bin/sh
#
# Startup script for local mercurial server
#
APP_BIN=/usr/bin/hg

#
# Change following lines
#
SRC=path to cloned Develop repository that user works on
SRCNAME="project name (Zlatozar's repository)"

# Path to PID file of running mercurial process.
PID_FILE=${SRC}/hg.pid

state=$1
case "$state" in
    'start')
        echo "Mecurial Server service starting..."
        (cd ${SRC} ;${APP_BIN} serve --name "${SRCNAME}"  -d  -p 1111 --pid-file ${PID_FILE})
        ;;

    'stop')
        if [ -f "${PID_FILE}" ]; then
            PID=`cat "${PID_FILE}"`
            if [ "${PID}" -gt 1 ]; then
                kill -TERM ${PID}
                echo "Stopping the Mercurial service PID=${PID}."
            else
                echo Bad PID for Mercurial -- \"${PID}\"
            fi
        else
            echo No PID file recorded for mercurial
        fi
        ;;

    *)
        echo "$0 {start|stop}"
        exit 1
        ;;
esac
Уговорката е локалния Mercurial да е на порт 1111. Забележка:Тук може да има проблем ако IP се получава през DHCP. Тогава трява всеки от екипа да има хранилище на Mercurial сървъра. Един вид публично хранилище, на което може да се слага код, когато някоя работа изисква повече от един човек. И това е! Може свободно да обменяме. А ако възникни пороблем, по който работят повече хора правим отделен клон и работим. Като свършим просто го прекратяваме.
Почти сме преключили, сега е време да изменим мисленето си и стила си на работа с дистрибутивните сорс системи. Ето тук има такъв. Happy hacking! Joel tutorial Practical Example Official Mercurial Guide Mercurial Definitive guide Mercurial Cheatsheet

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)