Thursday, January 26, 2006

Synchronize yourself

Eclipse foreverСлучвало ли ви се е най-добрите идеи по "страничния" проект да идват на работното място? Как може да направите проекта достояние на други? Е, ще се опитам да ви опиша инсталирането на subversion, направата на repository и как да имаме лесен оталечен достъп до кода. Има много version control system, но може да се каже, че subversion е една от най-добрите.
И така да започваме. Операционата система разбира се е FreeBSD!
Web достъпa до нашето repository ще гарантира Apache server.

cd /usr/ports/www/apache20
make install WITH_BERKELEYDB=db42 && make clean


За да се стартира автоматично напишете следното в /etc/rc.conf:
apache2_enable="YES"

Имаме работещ web server, компилиран така, че да се сработи с subversion. Ето и следващата стъпка:
cd /usr/ports/devel/subversion
make install -DWITH_MOD_DAV_SVN && make clean

Създаваме и мястото, където ще се съхраняват и нашите проекти.
mkdir -p /home/svn/repos

От тук нататък subversion поема нещата в свои ръце:
svnadmin create --fs-type fsfs /home/svn/repos/<името>/

Знайте, че може да имате повече от едно хранилище! Командата по-горе можете да изпълните многократно, само с различни имена на хранилището. Писали сте нещо, което е важно за вас? Бързо се погрижете за него:
cd <пътя до проекта>
svn import . file:///home/svn/repos/името --message 'Initial repository layout'

Време е Apache да разбере за съществуването на хранилището.
Довряваме му се изцяло:
chown -R www:www /home/svn/

Забележка: Пускайте тази команда винаги, когато правите нещо "зад гърба" на Apache, за да нямате проблеми с правата на файловете.
Напишете следното в /usr/local/etc/apache2/httpd.conf:
# Subversion settings
<Location /repos>
DAV svn

SVNParentPath /home/svn/repos
SVNIndexXSLT "/svnindex.xsl"

AuthzSVNAccessFile /home/svn/svn-authz-access

AuthType Basic
AuthName "Subversion repository"
AuthUserFile /home/svn/svn-auth-file

Satisfy Any
Require valid-user
</Location>

svnindex.xsl прави интерфейса много по-приятен. Намерете го и го поставете на правилното място - корена на хранилищата:
locate subversion |grep xsl
cp /usr/local/share/subversion/xslt/* /home/svn/repos/



View result


Редовете:
AuthUserFile /home/svn/svn-auth-file
Require valid-user

изискват от нас на създадем валидни потребители. За целта:
htpasswd -cmb /home/svn/svn-auth-file <user> <password>

Аз лично малко задълбочавам нещата, като давам достъп до определени директории(предполага се, че имаме повече от едно хранилище). Реда:
AuthzSVNAccessFile /home/svn/svn-authz-access

ни задължава да създадем файла /home/svn/svn-authz-access. Ето и неговото съдържание:
# Directory access /home/svn/svn-authz-access
# directory specific authorization control

[groups]
owner = zlatozar
codedelight-developers = zlatozar
algorithms-developers = zlatozar

[/]
@owner = rw

[codedelight:/]
@codedelight-developers = rw
* = r

[algorithms:/]
@algorithms-developers = rw
* = r

Забележка: В групите, потребителите се изброяват с запетая.

Без да се впускам в подробности, това е накратко конфигурацията. Вече можете спокойно да си изтеглите кода.
svn checkout http://<domain_name>/repos/<repository_name>/

Приятна работа! Опааа! Не забравите, че сте компилирали приложенията с параметри, така че ще трябва да се "пипне" и /usr/local/etc/pkgtools.conf. Преговор за това как се прави update можете да направите тук

Защото subversion все още не е популярна, ще внеса и малко допълнителни бележки. Да предположим, че ще трябва да се грижим за някакъв голям проект, по който ще работят много програмисти. Конфигурациите за Apache сървара описани по-горе важат с пълна сила. Особености има в самата организация на repository-то. Какво имам впредвид. Subversion няма вградена подръжка на branches и tags! Вместо това използва копия. За да се разграничават се създават три допълнителни директории - trunk, branches и tags. Сега "зачеването" ще е малко по-различно. Текущата(или работната) версия ще е в trunk.
$ mkdir Project
$ mkdir Project/trunk
$ mkdir Project/branches
$ mkdir Project/tags

$ ls Project
branches tags trunk

$ mv hello.c Project/trunk/
$ mv Makefile Project/trunk/

$ ls Project/trunk/
Makefile hello.c

Това му е по-различното. Само да не се забравя, че пътя е пълен. Пример:

1. Импортва ме (примерно)
$ svn import --message "Initial import" http://domain/repos/името
Adding     Project/trunk
Adding     Project/trunk/hello.c
Adding     Project/branches
Adding     Project/tags

Committed revision 1.

Забележете, че се импортват всички допълнителни директории (trunk, branches, tags).

2. Ако ще теглим текущата версия
$ svn checkout file:///home/svn/repos/името/trunk
A hello.c
A Makefile
Checked out revision 1.

Появява се и един служебен файл - .svn. Там е служебната информация.
Ако ни трябва branch или tag указваме пътя до тях. Много от нещата в subversion са същите като в CVS.
svn status името_на_файла
svn log името_на_файла
svn commit името_на_файла
svn update името_на_файла

За създаването на тагове нещата са различни доста обаче. Subversion създава т.н. "lightweight copies" в tags директорията. Ето и как се създават:
svn copy file:///път/trunk file://път/tags/ver_1_0/

Абсолютно същото е при branches:
svn copy file://път/trunk/ file:///път/branches/ver_1_0_RELEASE

И сега има една много готина хватка с превкючвания между версиите.
svn switch file:///път/branches/ver_1_0_RELEASE

Супер! И така си бачкам с която версия си искам.
Друга особенност е работата с конфликтите. При конфликт subversion създава два допълнителни файла - единия е с локалните промени и другия е файла преди локалните промени. След като разрешим конфликтите задължително пишем командата:
svn resolved името_на_файла

Особеност при subversion e, че когато се сложат новите промени (svn commit) subversion увеличава с еденица revision number на целия проект! И така се прави много лесен snapshot на проекта, не е нужно да се слага tag както в CVS-a.
Subversion има запазени думи (alias) за определени версии на файлове (revisions).
A те са HEAD, BASE, COMMITTED и PREV. HEAD e последната версия на файла. При BASE нещата са малко по-сложни. BASE е последната версия, която сте взели от хранилището т.е. от където сте тръгнали. Пример. Да предположим, че сте направили update сутринта и версията на файла е 3497. Тогава BASE e 3497. След като направите промените и сложите файла обратно да речем под номер 3583. За този файл BASE e 3583, но за всички останали е още 3497. Ако сега вече направим повторен update и останалите ще станат 3583. Просто ви дава ви отместването от преди промените. COMMITTED сочи към последния commit, a PREV е преди този последен commit.

Добре е да се знае, че много от командите имат опция --dry-run. Така ще видите какво ще стане след изпълнението, без да счупите нищо.

Това са в общи линии базовите операции. Разбира се искат се тренировки.

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)