Skip to content

Установка и настройка SVN

В этом посте рассмотрим установку и настройку одной из моих любимых систем контроля версий SVN на линуксе.

Создаем пользователя svn

Сначала создадим пользователя svn через который будем создавать репозиторий, а так же запускать и проч.

sudo useradd -d /home/svn -U svn

ключ -d означает домашняя директория.

Замечание
Замечание. Если появится такое сообщение (может появиться на ubuntu-server), значит что-то не в порядке с samba-PAM:
no talloc stackframe at ../source3/param/loadparm.c:4864, leaking memory
Решений всего может быть два:
1. Удалить его
sudo apt-get remove libpam-smbpass
2. Обновить его
sudo pam-auth-update

После того как юзер создан зададим ему пассворд:

sudo passwd svn
Введите новый пароль UNIX: 
Повторите ввод нового пароля UNIX: 
passwd: пароль успешно обновлён

Назначим svn судоером:

sudo adduser svn sudo
Добавляется пользователь «svn» в группу «sudo» ...
Добавление пользователя svn в группу sudo
Готово.

Чтобы проверить, что юзер svn стал сюдоером можно открыть файл /etc/group и найти в нем строку: sudo:x:27:#####,#####,svn
Если файл /etc/group слишком длинный, то для быстрого поиска можно пропустить его через фильтр:

cat /etc/group | grep sudo
sudo:x:27:####,####,svn

Или переключиться в юзера svn и ввести команду (как переключаться в другого юзера, чуть дальше):

sudo whoami
Password: 
root

Если команда whoami вернет root значит юзер svn стал сюдоером. Поясню почему команда whoami возвращает рута, а не svn, потому что когда запускается какая-нибудь команда с sudo, это значит, что она запускается от имени рута, соответственно команда sudo whoami запускается как рут и результат будет пользователь рут.

Теперь создадим домашний каталог для юзера svn:

sudo mkdir /home/svn

Назначем владельца каталога юзера svn:

sudo chown svn /home/svn

Теперь переключимся в пользователя svn и перейдем в его домашний каталог:

su svn
Пароль:
cd

И создадим каталог куда поместим репозиторий:

mkdir repos

Установка subversion

На этом шаге установим систему контроля версий subversion

sudo apt-get install subversion
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following extra packages will be installed:
  libapr1 libaprutil1 libserf1 libsvn1
Suggested packages:
  subversion-tools db5.1-util
The following NEW packages will be installed:
  libapr1 libaprutil1 libserf1 libsvn1 subversion
0 upgraded, 5 newly installed, 0 to remove and 288 not upgraded.
Need to get 1 586 kB of archives.
After this operation, 4 580 kB of additional disk space will be used.
Do you want to continue [Y/n]? Y
Get:1 http://archive.ubuntu.com/ubuntu/ saucy/main libapr1 i386 1.4.8-1ubuntu1 [96,8 kB]
Get:2 http://archive.ubuntu.com/ubuntu/ saucy/main libaprutil1 i386 1.5.2-1 [92,3 kB]
Get:3 http://archive.ubuntu.com/ubuntu/ saucy/main libserf1 i386 1.1.0-2ubuntu1 [44,2 kB]
Get:4 http://archive.ubuntu.com/ubuntu/ saucy/main libsvn1 i386 1.7.9-1+nmu6ubuntu3 [1 074 kB]
Get:5 http://archive.ubuntu.com/ubuntu/ saucy/main subversion i386 1.7.9-1+nmu6ubuntu3 [279 kB]
Fetched 1 586 kB in 2s (620 kB/s)
Selecting previously unselected package libapr1.
(Reading database ... 147869 files and directories currently installed.)
Unpacking libapr1 (from .../libapr1_1.4.8-1ubuntu1_i386.deb) ...
Selecting previously unselected package libaprutil1.
Unpacking libaprutil1 (from .../libaprutil1_1.5.2-1_i386.deb) ...
Selecting previously unselected package libserf1:i386.
Unpacking libserf1:i386 (from .../libserf1_1.1.0-2ubuntu1_i386.deb) ...
Selecting previously unselected package libsvn1:i386.
Unpacking libsvn1:i386 (from .../libsvn1_1.7.9-1+nmu6ubuntu3_i386.deb) ...
Selecting previously unselected package subversion.
Unpacking subversion (from .../subversion_1.7.9-1+nmu6ubuntu3_i386.deb) ...
Processing triggers for man-db ...
Setting up libapr1 (1.4.8-1ubuntu1) ...
Setting up libaprutil1 (1.5.2-1) ...
Setting up libserf1:i386 (1.1.0-2ubuntu1) ...
Setting up libsvn1:i386 (1.7.9-1+nmu6ubuntu3) ...
Setting up subversion (1.7.9-1+nmu6ubuntu3) ...
Processing triggers for libc-bin ...

Создаем репозиторий

В созданом каталоге repos добавим утилитой svnadmin каталог repo1 куда будет помещен наш репозиторий:

svnadmin create /home/svn/repos/repo1

Правим конфигурационные файлы

Переходим в каталог /home/svn/repos/repo1/conf и правим там три файла.

Открываем на редактирование файл svnserve.conf и раскоментируем там строки 12, 13, 20 и 27 (на FF 29.0 в ubuntu номера строк чуть-чуть не попадают на сами строки, это баг фаирфокса):

Файл svnserve.conf

### This file controls the configuration of the svnserve daemon, if you
### use it to allow access to this repository.  (If you only allow
### access through http: and/or file: URLs, then this file is
### irrelevant.)

### Visit http://subversion.tigris.org/ for more information.

[general]
### These options control access to the repository for unauthenticated
### and authenticated users.  Valid values are "write", "read",
### and "none".  The sample settings below are the defaults.
anon-access = none
auth-access = write
### The password-db option controls the location of the password
### database file.  Unless you specify a path starting with a /,
### the file's location is relative to the directory containing
### this configuration file.
### If SASL is enabled (see below), this file will NOT be used.
### Uncomment the line below to use the default password file.
password-db = passwd
### The authz-db option controls the location of the authorization
### rules for path-based access control.  Unless you specify a path
### starting with a /, the file's location is relative to the the
### directory containing this file.  If you don't specify an
### authz-db, no path-based access control is done.
### Uncomment the line below to use the default authorization file.
authz-db = authz
### This option specifies the authentication realm of the repository.
### If two repositories have the same authentication realm, they should
### have the same password database, and vice versa.  The default realm
### is repository's uuid.
# realm = My First Repository

[sasl]
### This option specifies whether you want to use the Cyrus SASL
### library for authentication. Default is false.
### This section will be ignored if svnserve is not built with Cyrus
### SASL support; to check, run 'svnserve --version' and look for a line
### reading 'Cyrus SASL authentication is available.'
# use-sasl = true
### These options specify the desired strength of the security layer
### that you want SASL to provide. 0 means no encryption, 1 means
### integrity-checking only, values larger than 1 are correlated
### to the effective key length for encryption (e.g. 128 means 128-bit
### encryption). The values below are the defaults.
# min-encryption = 0
# max-encryption = 256

В предыдущем исправлении поста значение anon-access было установлено в read из-за этого у меня были проблемы настроить subversion в teamcity. Когда к teamcity я подключил репозиторий svn, первый чекаут был успешным, но после того как на другой машине я сделал изменения и закоммитил их на svn, teamcity подтянуть изменения уже не мог и выдавал такой эксцепшен:

Patch is broken, can be found in file: /home/user/bin/TeamCity/buildAgent/temp/globalTmp/temp769001021308885078patch_16
[13:33:37]Failed to build patch for build #8 {build id=16, buildTypeId=Build1_Build1}, VCS root: "svn" {instance id=11, parent internal id=1, parent id=Build1_Svn, description: "svn: svn://repository-machine/repo1/simple-bad-app"}, due to error: org.tmatesoft.svn.core.SVNAuthenticationException: svn: E220000: Not authorized to open root of edit operation
[13:33:37]
jetbrains.buildServer.agent.impl.patch.PatchDownloaderImpl$1: Server was not able to build correct patch, most likely due to VCS errors
	at jetbrains.buildServer.agent.impl.patch.PatchDownloaderImpl.throwError(PatchDownloaderImpl.java:118)
	at jetbrains.buildServer.agent.impl.patch.PatchDownloaderImpl.checkPatch(PatchDownloaderImpl.java:108)
	at jetbrains.buildServer.agent.impl.patch.PatchDownloaderImpl.copyPatchAndCheck(PatchDownloaderImpl.java:69)
	at jetbrains.buildServer.agent.impl.patch.UpdateSourcesPatcherBase.copyPatchToTempFile(UpdateSourcesPatcherBase.java:71)
	at jetbrains.buildServer.agent.impl.patch.UpdateSourcesFromServer.updateSources(UpdateSourcesFromServer.java:60)
	at jetbrains.buildServer.agent.impl.patch.UpdateSourcesBuildStageBase.doSourceUpdate(UpdateSourcesBuildStageBase.java:91)
	at jetbrains.buildServer.agent.impl.patch.UpdateSourcesBuildStageBase.doRecoverableStage(UpdateSourcesBuildStageBase.java:59)
	at jetbrains.buildServer.agent.impl.buildStages.startStages.RecoverableBuildStage.doLastAttempt(RecoverableBuildStage.java:112)
	at jetbrains.buildServer.agent.impl.buildStages.startStages.RecoverableBuildStage.doBuildStage(RecoverableBuildStage.java:70)
	at jetbrains.buildServer.agent.impl.buildStages.BuildStagesExecutor$1.callStage(BuildStagesExecutor.java:31)
	at jetbrains.buildServer.agent.impl.buildStages.BuildStagesExecutor$1.callStage(BuildStagesExecutor.java:24)
	at jetbrains.buildServer.agent.impl.buildStages.StagesExecutor.callRunStage(StagesExecutor.java:78)
	at jetbrains.buildServer.agent.impl.buildStages.StagesExecutor.doStages(StagesExecutor.java:37)
	at jetbrains.buildServer.agent.impl.buildStages.BuildStagesExecutor.doStages(BuildStagesExecutor.java:24)
	at jetbrains.buildServer.agent.impl.BuildRunActionImpl.doStages(BuildRunActionImpl.java:70)
	at jetbrains.buildServer.agent.impl.BuildRunActionImpl.runBuild(BuildRunActionImpl.java:50)
	at jetbrains.buildServer.agent.impl.BuildAgentImpl.doActualBuild(BuildAgentImpl.java:266)
	at jetbrains.buildServer.agent.impl.BuildAgentImpl.access$100(BuildAgentImpl.java:51)
	at jetbrains.buildServer.agent.impl.BuildAgentImpl$1.run(BuildAgentImpl.java:231)
	at java.lang.Thread.run(Thread.java:745)
Caused by: jetbrains.buildServer.vcs.patches.UnsuccessfulPatchException: Failed to build patch for build #8 {build id=16, buildTypeId=Build1_Build1}, VCS root: "svn" {instance id=11, parent internal id=1, parent id=Build1_Svn, description: "svn: svn://172.22.193.87/repo1/simple-bad-app"}, due to error: org.tmatesoft.svn.core.SVNAuthenticationException: svn: E220000: Not authorized to open root of edit operation
	at jetbrains.buildServer.vcs.patches.AbstractPatcher$1.fail(AbstractPatcher.java:93)
	at jetbrains.buildServer.vcs.patches.LowLevelPatcher.readPatchStream(LowLevelPatcher.java:165)
	at jetbrains.buildServer.vcs.patches.LowLevelPatcher.applyPatch(LowLevelPatcher.java:88)
	at jetbrains.buildServer.vcs.patches.AbstractPatcher.applyPatch(AbstractPatcher.java:42)
	at jetbrains.buildServer.agent.impl.patch.PatchApplierImpl.applyPatch(PatchApplierImpl.java:18)
	at jetbrains.buildServer.agent.impl.patch.PatchDownloaderImpl.checkPatchInFileIsCompleted(PatchDownloaderImpl.java:88)
	at jetbrains.buildServer.agent.impl.patch.PatchDownloaderImpl.checkPatch(PatchDownloaderImpl.java:98)
	... 18 more

Проблема была вызвана именно в значении read параметра anon-access в файле svnserve.conf.

Файл passwd

Регистрируем пользователей svn. Открываем на редактирование файл passwd и добавляем туда пользователей репозитория:

### This file is an example password file for svnserve.
### Its format is similar to that of svnserve.conf. As shown in the
### example below it contains one section labelled [users].
### The name and password for each user follow, one account per line.

[users]
# harry = harryssecret
# sally = sallyssecret

user = password

Назначем права для зарегистрированных пользователей. Открываем на редактирование файл authz и добавляем туда права:

Файл authz

### This file is an example authorization file for svnserve.
### Its format is identical to that of mod_authz_svn authorization
### files.
### As shown below each section defines authorizations for the path and
### (optional) repository specified by the section name.
### The authorizations follow. An authorization line can refer to:
###  - a single user,
###  - a group of users defined in a special [groups] section,
###  - an alias defined in a special [aliases] section,
###  - all authenticated users, using the '$authenticated' token,
###  - only anonymous users, using the '$anonymous' token,
###  - anyone, using the '*' wildcard.
###
### A match can be inverted by prefixing the rule with '~'. Rules can
### grant read ('r') access, read-write ('rw') access, or no access
### ('').

[aliases]
# joe = /C=XZ/ST=Dessert/L=Snake City/O=Snake Oil, Ltd./OU=Research Institute/CN=Joe Average

[groups]
# harry_and_sally = harry,sally
# harry_sally_and_joe = harry,sally,&joe

# [/foo/bar]
# harry = rw
# &joe = r
# * =

# [repository:/baz/fuz]
# @harry_and_sally = rw
# * = r

[/]
user = rw
* = 

Запускаем svn сервер

svnserve -d -r /home/svn/repos

где опция -r запрещает серверу искать репозитории выше указанной директории

Test svn

svn info svn://localhost/repo1
Путь: 'repo1'
URL: svn://localhost/repo1
Корень репозитория: svn://localhost/repo1
UUID репозитория: 102ec2d4-b318-4302-8cff-729214c3edaa
Редакция: 0
Вид узла: каталог
Редакция последнего изменения: 0
Дата последнего изменения: 2014-06-12 22:02:55 +0300 (Чтв, 12 Июн 2014)

Остановка сервиса svn

Чтобы остановить сервис svn, нужно прибить процесс килом:

ps -ef  | grep svnserve
svn      11795     1  0 23:00 ?        00:00:00 svnserve -d -r /home/svn/repos
svn      11848 11748  0 23:05 pts/2    00:00:00 grep svnserve
sudo kill 11795

Добавим в репозиторий тестовый проект

Теперь добавим в репозиторий проект:

svn checkout svn://localhost/repo1
Checked out revision 0.

Создадим в текущем каталоге проект взятый из поста Простое spring приложение:

simple-bad-app
    ├──src
    │   ├─Figure.java     
    |   ├─Circle.java
    |   ├─Rectangle.java
    |   ├─Print.java
    |   └─Execute.java
    └──build.sh

И скажем SVN о появлении нового каталога:

svn add simple-bad-app
A         simple-bad-app
A         simple-bad-app/src
A         simple-bad-app/src/Execute.java
A         simple-bad-app/src/Rectangle.java
A         simple-bad-app/src/Print.java
A         simple-bad-app/src/Figure.java
A         simple-bad-app/src/Circle.java
A         simple-bad-app/build.sh

Закомитим проект в репозиторий:

svn commit -m "add project"
Adding         simple-bad-app
Adding         simple-bad-app/build.sh
Adding         simple-bad-app/src
Adding         simple-bad-app/src/Circle.java
Adding         simple-bad-app/src/Execute.java
Adding         simple-bad-app/src/Figure.java
Adding         simple-bad-app/src/Print.java
Adding         simple-bad-app/src/Rectangle.java
Transmitting file data ......
Committed revision 1.

Теперь перейдем в другой каталог и попробуем сделать чекаут проекта:

svn checkout svn://localhost/repo1/simple-bad-app
A    simple-bad-app/src
A    simple-bad-app/src/Print.java
A    simple-bad-app/src/Circle.java
A    simple-bad-app/src/Figure.java
A    simple-bad-app/src/Execute.java
A    simple-bad-app/src/Rectangle.java
A    simple-bad-app/build.sh
Checked out revision 6.

Линки

Как разрешить доступ пользователю к команде sudo?
Установка и настройка SVN (сервер+клиент)
Установка svn (Subversion) на хостинг с CPanel
Система контроля версий в ubuntu
Настройка групп и прав в Subversion

Поделиться в социальных сетях

Опубликовать в Google Plus
Опубликовать в LiveJournal
Опубликовать в Мой Мир
Опубликовать в Одноклассники
Опубликовать в Яндекс