Showing posts with label source control. Show all posts
Showing posts with label source control. Show all posts

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

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.

Thursday, June 29, 2006

The force of Perforce

INTRO: Kick start


I'm a new colleague and I do not know how to start with Perforce. Can you explain me just the basics steps?
* Install Perforce
* Second you have to setup your client. Client in Perforce world is your workstatation, your workspase.
--- Open P4V this is a GUI for Perforce. Then Connections -> Open New Connection
Now you have to fill fields. Here is some terms:
Client:
The client name. The name of your workspace.
Owner:
The user who created this client.
Root:
The root directory of the client file workspace, under which all client files will be placed. Here is mine:
C:\src\mainline

Options:
Just use default...
View:

A mapping from the files in the depot to files in the client workspace.
A new view takes effect on the next 'p4 sync'.
See view(mapping) example:
//depot/mainline/... //ZLATOZAR/...

So //depot/mainline/... will be mapped to my root.
--- Get things from depot. Depot is the repository. Type in workspace(root) command prompt:
p4 sync

* Before you start change file you have to declare that you want to edit it. Weird indeed but don't forget it.
All other knows that you are going to change this file. Your file is in changelist.
p4 edit //depot/mainline/Project1/MyFile.cs


* When you finish submit your changelist
p4 submit

or file by file
p4 submit TelephoneComponentHandler.cs

That is. Now more details.

PART ONE: The depot


1. Filespec Syntax
Perforce provides its own uniform syntax for referring to workspace and depot contents. This syntax is known as a file specifier, or "filespec."
Its converts filespecs to native file references for local operations. Depots, where Perforce keeps master file content, and workspaces, where users work on files, are hierarchical structures of directories and files.

A filespec uses "//" to indicate the root of the hierarchy, and "/" as a directory path and file name separator.
For example:
//depot/mainline/Project1/MyNewFile.cs

IMPORTANT !
File names are case insensitive or case sensitive it depends from instalation.
Just check it and remeber.
//depot/mainline/project1/mynewfile.cs
is the same? And also spaces in filenames and pathnames have to be quoted when they are referenced in views
-- It is possible to use wild cards
//depot/mainline/Project*/ComponentHandler.cs

--- Use "dot-dot-dot"
The "..." wildcard matches filename characters at or below a directory level.
//depot/.../SomeInnerProject/...

2. File and directory revisions
IMPORTANT !
Perforce's filespecs always refer to files, not directories. In fact there are no Perforce commands that operate on directories.
Use wild cards to refer directories.
Note:
I will describe a lot of commands, but for more information use command prompt help. Just type:
p4 help

then
p4 help [some of subjects]
p4 help [command that you are interested]

Perforce stores file versions in a sequence of numbered revisions. A filespec can refer to an absolute, numbered file revision, prefixed with #.
Filespecs can also refer to dates and labels, prefixed with @. And also label can be used to refer to file revisions to which it has been applied.
Examples:
--- displays all files in Project1
p4 files //depot/mainline/Project1/*
............
//depot/mainline/Project1/MyFile.cs#15 - edit change 5401 (text)
............

--- display revisions of files for a specific version
p4 files //depot/mainline/Project1/*#15

--- display files using date and first letter of the file name
p4 files //depot/mainline/Project1/M*@5/16/2006

3. Changes and changelists
Perforce uses changelists to track changes submitted to the depot. Every changelist commit number is a snapshot of the depot (It is similar to tags in CVS). Versioning numbers are global
See my ASCII graphic:
Date:           05/05/2006  07/05/2006      23/05/2006
|          |               |
|    |        |            |    |
file1 -----------| #1 |--------|------------| #2 |------
|    |        |            |    |
|          |               |
|        |    |            |
file2 -----------------------| #1 |----------------------
|        |    |            |         
|          |               |
|    |        |               |
file3 -----------| #1 |---------------------------------
|    |        |               |
|          |               |
Changelist trak:   @102       @109             @114


4. Browsing the file tree
See examples:
--- to list all depots
p4 depots

(or p4 dirs "//*")
--- to list all dirs and subdirs
p4 dirs "//depot/*"

--- see file changes history
p4 changes -m5 //depot/mainline/Project1/TheFile.cs

Note:: The -m5 flag restricts the output to the five most recent changes. Each change is identified with a changelist number and the first 30-odd characters of a description. If you want to see entire descriptions, use changes -l.
--- what is on the default change list when I commit my files
p4 describe -s 5401

--- shows file revision numbers and the action (add, delete, etc.) that took place at each revision
p4 filelog //depot/mainline/Project1/TheHandler.cs

--- to see all changes and changelist
p4 annotate -c //depot/mainline/Project1/TheHandler.cs | more

(P4V's Time-lapse View is generated from the output of the annotate command.)
--- if you want to take a file(some revision) and pass it to another file
p4 print -q //depot/mainline/Project1/TheHandler.cs > newTCH.txt

--- compare revisions
p4 diff2 //depot/mainline/Project1/TheHandler.cs#14
//depot/mainline/IProject1/TheHandler.cs#15 | more

(p4 diff [old revision] [new revision])
In P4V the Tools -> Diff files command can be used to diff any two files or revisions. It shows only different lines! Eclipse diff wins...
The same command can be used to compare any two revisions of a directory. That is realy impressive. Keep in mind that Perforce can compare and merge onky text files.
--- discover file types
See:
p4 help filetypes

+x
The workspace file is executable.
+w
The file is writable as soon as it's copied to the workspace. (Normally you have to open files to make them writable.)
+k
RCS-like keywords in the file are expanded when the file is copied to the workspace.
+l
The file is exclusively locked when opened so that only one person can have it open at a time.
+m
The file's modification time is propagated with the file so that it shows up in the timestamp of synchronized copies.
+S
Only one revision (the head revision) of the file is stored in the depot.
(This is useful for files generated and submitted by nightly builds, for example.)

Commbinations are also posible:
binary+lw
etc.

PART TWO: Files, workspace and change list


1. Creating workspace. Working with local files
The first thing you do before you can work on files is define a client workspace for yourself. A client workspace specification, or client spec, tells Perforce where in your local filesystem you want your workspace to be rooted. It has a view that defines the areas of the depot you want access to, and maps them to directories beneath the workspace root.
--- set up new
Note:: If P4CLIENT is not set, the name of your host machine will be used as the current workspace name.

For example, say you want to configure a workspace named Zlatozar-BG. First, you open up a client form in default editor:
p4 client Zlatozar-BG

An easy way: In P4V with the Connection -> Open Connection. Fill fields.
--- synchronyze workspace. Current dir.
p4 sync

--- get only one part
p4 sync //depot/mainline/Project1/

--- view all changes that are made after my commit
p4 changes "@>5401"

How to rewrite all my current changes?
* Check all files that you have changed
p4 diff -sa

* Reverting files is how you discard changes you've made to local files, rather than submitting them
p4 revert //depot/[path to the file]

How to restore localy removed files?
* Find them
p4 diff -sd

* List the files Perforce thinks you have with the have command
p4 have //.../Project1/...

* Restore(force) them
p4 sync -f //.../Project1/...

Note:: Workspace files are under your control and there's nothing to stop you or the programs you run from erasing files Perforce put there. But because Perforce thinks you have them already, you won't be able to replace them with a simple sync. So force it.
2. Working with local files
When you synchronize your workspace with depot files, Perforce normally puts read-only files on your local disk. To make files writable, you have to open them. You also have to open files you plan to add to or delete from the depot.Remember, in Perforce, an "open file" is a file you plan to submit to the depot. Don't confuse Perforce's meaning of "open" with the idea of opening files in an application.
--- open for edit
p4 edit //depot/mainline/Project1/TheHandler.cs

Now file is writable and in changelist. Team knows that you are working on that file if they type:
p4 opened -a //.../Project1/...

How many programers can work(open) on the same file?
All programers but first commiter wins. Rest of them have to resolve possible conflicts.
When you open file Perforce worns you thst another programmer works on it. Somthing like:
... - also opened by gosho@...

(Read more about p4 resolve....it is not so easy.)
--- add files to depot
There is no need to open file to add it. You can open files only if they're in your workspace view.
p4 add //.../Project1/SofiaHandler.cs
p4 submit

--- delete files from depot
p4 delete //.../Project1/StrangeHandler.cs
p4 submit

As you open files, they are associated with a pending changelist. Your local changes don't affect the depot until you submit your files. What you submit to the depot is not individual files, really, but the entire pending changelist.
IMOPRTANT !
Remove all uchenged files first or commit files one by one
p4 revert -a
p4 submit

This is a weak point realy... be careful. It is posible to commit unchanged files. Realy realy weak point. Sorry. You can use this script:
# throw away (opened but) unchanged files
# (in Perforce it's a little bit too easy
# to checkin unchanged files)

p4 diff -sr | p4 -x - revert

Hi. I'm very creative programmer and I work on many differen tasks. How can I separate my works?
* The answear is - create different changelist for diffrent tasks an gave them proper names.
p4 change

This command brings up a spec form, just like submit. The form will list all the files opened in your default changelist. Simply fill in a description and save the form to move files to the new changelist.
* Open for edit in the right changelist
p4 edit -c dt-456

* Submit right changelist (eg. "dt-456")
p4 submit -c dt-456

* Empty pending changelists can be deleted
p4 change -d dt-456

PART THREE: Misc


1. Snapshots
Every time a user submits files to Perforce, a snapshot of the depot is created automatically. The changelist number created at submit time is effectively a global revision number. It can be use to reference any file or set of files in the depot snapshot. Don't forget that.
For example when submit change list:
p4 submit
..........
Change 5401 submitted.

As you see the submit number is global. So you can refer it. If you want to take spesific change list (actually this is a snapshot):
p4 sync //depot/mainline/...@5401

or
p4 diff2 -q //depot/mainline/...@5400 //depot/mainline/...@5401

(and I found out all my changes)
or just use P4V's Folder Diff tool to compare snapshots...
2. Labels
In Perforce, as in many SCM systems, you can tag files with a label. To give names to snapshots. A label lets you use memorable names like REL2.0.1 to refer to specific configurations of file revisions.
--- see all labels maded from karl
p4 labels |grep alex

--- applying a label to files
p4 tag -l rel-2.0.1 //depot/mainline/...

--- referring label
p4 sync @rel-2.0.1

--- all files in label
p4 files @rel-2.0.1


3. Jobs
A job is an object in the Perforce database that can be used to tie development activity to external information. Jobs can be used for anything—requirements, project plans, to-do lists — but their most common use is for defect tracking.

PART FOUR: Resolving and merging (advanced level)


PART FIVE: Branching and merging (black belts)


To be continued...

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. Така ще видите какво ще стане след изпълнението, без да счупите нищо.

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

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)