26 июня 2015 г. Gitolite Git

Git. Разграничения прав по каталогам в репозитории

Из-за соображений безопасности и простоты работы с репозиторием для фрилансеров-верстальщиков, необходимо разграничить права по каталогам. Решить этот вопрос с помощью gitolite никак не получилось, он всеравно оставляет права на чтение файлов. Пришлось создавать два репозитория и через хук гита post-update симметрично обновлять оба репозитория.

Создаем дополнительный репозиторий

В gitolite это выглядит так:

repo example
    RW+                 = developer

repo example_markup
    RW+                 = freelancer

Локально клонируем репозиторий example_markup.git, копируем в него из example.git нужные каталоги и коммитим всё это добро.

Подключаемся на сервер с gitolite и создаем хуки

Переходим в каталог репозитория example_markup.git и клонируем туда оба репозитория, для того, чтобы можно было удобно из них коммитить:

sudo su - git
cd ~/repositories/example_markup.git
git clone file:///home/git/repositories/example_markup.git
git clone file:///home/git/repositories/example.git
Если вы до этого не настраивали git под пользователем "git", то вам необходимо указать как минимум почту и имя для коммитов, а также воркфлоу при пушинге (я выбрал "simple", детальнее можете ознакомиться в "man git-config"):
git config --global user.email "git@example.org"
git config --global user.name "Mr. Git"
git config --global push.default simple

После чего, создадим хук post-update:

sudo su - git
cd ~/repositories/example_markup.git/hooks
touch post-update
chmod +x post-update
emacs post-update

Помещаем туда следующее содержимое:

#!/bin/sh
GIT=`/usr/bin/which git`
echo "Update example_markup.git..."
unset GIT_DIR
cd example_markup/ && $GIT pull && cd -
echo "Copy files from example_markup.git to example.git..."
cp -R example_markup/* example/
echo "Сommit and push changes to example.git"
unset GIT_DIR
cd example && $GIT add . && $GIT commit -am "Auto-update from example_markup.git" && $GIT push
echo "Finished!"
exec git-update-server-info

Теперь противоположные действия для репозитория example.git:

sudo su - git
cd ~/repositories/example.git/hooks
touch post-update
chmod +x post-update
emacs post-update

Помещаем туда следующее содержимое:

#!/bin/sh
GIT=`/usr/bin/which git`
echo "Update example.git..."
unset GIT_DIR
cd ../example_markup.git/example && $GIT pull && cd -
echo "Copy files from example_markup.git to example.git..."
cp -R ../example_markup.git/example/templates/* ../example_markup.git/example_markup/templates/
cp -R ../example_markup.git/example/static/* ../example_markup.git/example_markup/static/
echo "Сommit and push changes to example_markup.git"
unset GIT_DIR
cd ../example_markup.git/example_markup && $GIT add . && $GIT commit -am "Auto-update from example.git" && $GIT push
echo "Finished!"
exec git-update-server-info

Попробуем локально что-нибудь пушнуть в example_markup.git:

Counting objects: 4, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 362 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote: Update example_markup.git...
remote: From file:///home/git/repositories/example_markup
remote:    840b8e9..2a9be4e  master     -> origin/master
remote: Updating 840b8e9..2a9be4e
remote: Fast-forward
remote:  README | 0
remote:  1 file changed, 0 insertions(+), 0 deletions(-)
remote:  create mode 100644 README
remote: /home/git/repositories/example_markup.git
remote: Copy files from example_markup.git to example.git...
remote: Сommit and push changes to example.git
remote: [master 2dbf0be] Auto-update from example_markup.git
remote:  5 files changed, 104 insertions(+), 250 deletions(-)
remote: remote: Update example.git...        
remote: remote: From file:///home/git/repositories/example        
remote: remote:    663fee4..2dbf0be  master     -> origin/master        
remote: remote: Already up-to-date.        
remote: remote: /home/git/repositories/example.git        
remote: remote: Copy files from example_markup.git to example.git...        
remote: remote: Сommit and push changes to example_markup.git        
remote: remote: On branch master        
remote: remote: Your branch is up-to-date with 'origin/master'.        
remote: remote: 
remote: remote: nothing to commit, working directory clean        
remote: remote: Finished!        
remote: To file:///home/git/repositories/example.git
remote:    663fee4..2dbf0be  master -> master
remote: Finished!
To git@git.example.org:example_markup
   840b8e9..2a9be4e  master -> master

Ну всё, теперь верстальщик сможет изменять только свои файлы, коммитить их, а остальные участники проекта будут автоматически наблюдать изменения в своем репозитории, без необходимости вручную копировать изменения.

Если знаете более правильный способ разграничить права по файлам или как настроить gitolite, то пишите комментарии, всегда рад конструктиву!

ps. Способ подразумевает работу только с установленой веткой, в нашем случае master. Если понадобится использовать верстальщику ветки, то надо будет немного доделать хуки.

Комментарии

А я вот так настраивал: https://www.zagirov.name/restriction-access-users-in-git/

Рустам, так получается что "@testers" все равно видят все каталоги в репоизтории, только писать в них не могут. Или у тебя получилось сделать так, что при clone появятся только каталоги которые разрешены?

Нет, видеть могут всё, но писать не могут

Ну да, так в gitolite можно сделать, а вот чтобы только некоторые каталоги были доступны - нельзя, поэтому пришлось выкручиваться

Нет, видеть могут всё, но писать не могут

в svn это делается очень просто, вплоть до указания прав доступа к одному файлу.

Оставьте свой комментарий

Markdown