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. Если понадобится использовать верстальщику ветки, то надо будет немного доделать хуки.
Комментарии 5
Архив обсуждения. Новые комментарии закрыты.
А я вот так настраивал: https://www.zagirov.name/restriction-access-users-in-git/
Рустам, так получается что “@testers” все равно видят все каталоги в репоизтории, только писать в них не могут. Или у тебя получилось сделать так, что при clone появятся только каталоги которые разрешены?
Нет, видеть могут всё, но писать не могут
Ну да, так в gitolite можно сделать, а вот чтобы только некоторые каталоги были доступны - нельзя, поэтому пришлось выкручиваться
в svn это делается очень просто, вплоть до указания прав доступа к одному файлу.