Как я могу поделиться репозиторием Git с несколькими пользователями на машине?

216

У меня есть Git-репозиторий на промежуточном сервере, к которому должны иметь возможность работать несколько разработчиков. git-initкажется, флаг очень близок к тому, что я ищу: --sharedза исключением того, что я хотел бы, чтобы несколько человек также обращались к этому хранилищу. git-clone«S --sharedфлаг делает что - то совершенно другое.

Какой самый простой способ изменить разрешения существующего репозитория?

Андрей Федоров
источник
Я использую «Github для Windows» и переключаюсь между двумя учетными записями Github: stackoverflow.com/questions/18565876/…
Алиса

Ответы:

186

Разрешения являются вредителями.

По сути, вам нужно убедиться, что все эти разработчики могут писать обо всем в репозитории git.

Перейдите к Решению New-Wave для превосходного метода предоставления возможности записи группе разработчиков.

Стандартное решение

Если вы поместите всех разработчиков в специально созданную группу, вы в принципе можете просто:

chgrp -R <whatever group> gitrepo
chmod -R g+swX gitrepo

Затем измените umaskдля пользователей значение 002так, чтобы новые файлы создавались с правами на запись в группы.

Проблемы с этим легион; Если вы находитесь в дистрибутиве, в котором предполагается наличие umaskодного 022(например, наличие общей usersгруппы, в которую по умолчанию входят все), это может вызвать проблемы с безопасностью в других местах. И рано или поздно что-то испортит вашу тщательно разработанную схему разрешений, выводя репо из строя до тех пор, пока вы не получите rootдоступ и не исправите его (то есть повторно запустите вышеуказанные команды).

Новая волна Решение

Превосходящее решение - хотя и менее понятное и требующее немного большей поддержки ОС / инструментов - это использование расширенных атрибутов POSIX. Я только пришел в эту область сравнительно недавно, поэтому мои знания здесь не так жарко, как могло бы быть. Но в основном расширенный ACL - это возможность устанавливать разрешения не только для 3-х слотов по умолчанию (пользователь / группа / другое).

Итак, еще раз, создайте свою группу, затем запустите:

setfacl -R -m g:<whatever group>:rwX gitrepo
find gitrepo -type d | xargs setfacl -R -m d:g:<whatever group>:rwX

Это устанавливает расширенный ACL для группы, чтобы члены группы могли читать / записывать / получать доступ к любым файлам, которые там уже есть (первая строка); затем также скажите всем существующим каталогам, что к новым файлам должен применяться тот же ACL (вторая строка).

Надеюсь, это поможет вам.

romble
источник
62
В git init есть параметр --shared, который устанавливает переменную core.sharedRepository для групповой работы. Вы также можете установить переменную в существующем хранилище. Это избавляет от необходимости вручную устанавливать umask, так как git установит для него нормальное значение, прежде чем манипулировать файлами.
Птман
6
+1 за расширенные атрибуты POSIX - для меня новость!
RobM
5
Когда я это сделал chmod -R g+swX, это сделало Git очень несчастным, и он решил, что это больше не git-репозиторий («репозиторий не является git-репозиторием»). Я должен был chmod gs все файлы . Чтобы просто установить бит setgid для каталогов , попробуйте find /path/to/repo -type d -print0 | xargs -0 chmod g+s. Все еще делаю chgrp -R thegroup /path/to/repo.
rescdsk
10
chmod -R g+swX gitrepoбудет применять бит setguid к файлам, что представляет угрозу безопасности. Вместо этого вы можете использовать find . -type d -exec chmod g+s {} +его только для каталогов.
Ян Данн
1
В ACL (setfacl) отсутствует настройка setgid для принудительного применения новых файлов и подкаталогов, созданных в каталоге, для наследования идентификатора его группы. Поэтому вы должны установить setgid отдельно через chmod. Опция --shared в Git ( git-scm.com/docs/git-init ), однако, позволяет вам установить и переопределить umask пользователя.
Погоня Т.
121

если вы создали хранилище (или клонировали новое голое хранилище из существующего) с

$ git init --shared=group 

или же

$ git init --shared=0NNN

Git должен обрабатывать разрешения сверх того, что предоставляет ваш umask по умолчанию. Наконец, это верно для моей версии Git (1.6.3). Конечно, это предполагает, что ваши пользователи находятся в одной группе.

Однако, если бы мне нужно было управление пользователями в нескольких группах с разной степенью чтения / записи, я бы пошел на хитоз. Я также слышал упоминание о gitolite ( http://github.com/sitaramc/gitolite ), вилке gitosis, которая, как предполагается, предоставляет разрешения на уровне ветвей, хотя я не могу сказать, что каждый использовал ее лично.

Домик на пляже
источник
9
Это определенно правильный ответ.
ELLIOTTCABLE
4
У меня была эта проблема, и это, безусловно, лучший ответ. Единственная проблема заключается в том, что --sharedаргумент принимает восьмеричное, а не шестнадцатеричное значение. Я подтвердил это в источнике Git 1.7.8, и второй пример должен быть git init --shared=0NNN.
qpingu
3
Что NNNтакое маска разрешений, номер группы или что-то еще?
Крейг МакКуин
20
Кстати, "группа" выше - это ключевое слово, а не заполнитель для имени вашей группы. Вы назначаете группу с помощью команды chgrp. Для нового репо это git init --bare --shared=group myprojгде myproj - это имя вашего репо, а затем chgrp -R mygroup myprojmygroup - это имя вашей группы.
Лабрадорт
2
На первый взгляд, если ваши пользователи совершают коммиты, когда их группа по умолчанию отличается от той, которая должна быть, это может испортить ситуацию. Чтобы решить эту проблему, вам нужно, чтобы каждый пользователь выполнил chgrp для каждого файла в репо в нужную группу. Это повторится, если только вы не поймете, как заставить всех создавать / переключать новые файлы в / в нужную группу перед фиксацией и нажатием.
ragerdl
55

Этого не было сказано, поэтому я хочу быстро добавить его.

Чтобы убедиться, что проблемы с разрешениями не обрезают их уродливую голову, убедитесь, что в файле конфигурации вашего общего git-репозитория установлено следующее:

[core]
    sharedRepository = true

Это обеспечит соблюдение настроек umask вашей системы.

Нильс Жубер
источник
6
В соответствии с git-config (1) ( kernel.org/pub/software/scm/git/docs/git-config.html ) core.sharedRepository, вам нужно установить для этого значение "umask" или "false", чтобы иметь уважение git Umask пользователя.
Дэвид Шмитт
14
Это и user35117 ответ правильный. Обратите внимание, что «true» - это то же самое, что и «group», и это можно установить с помощью команды git config core.sharedRepository true.
ColinM
Изменяет ли оно владение файлом при удалении?
Дык Тран
2
Если вы хотите установить это при клонировании, а не после факта, эквивалентно git init --sharedis git clone --config core.sharedRepository=true. Странно использовать git --sharedдля таких разных значений в таких похожих командах.
stevek_mcc
21

Руководство пользователя Git описывает , как разделить хранилище нескольких способов.

Более сложными, но полнофункциональными способами обмена репозиториями являются:

Мы используем GitHub для команды из 6 разработчиков.

jtimberman
источник
1
Мне нравится Gitosis. Это довольно эффективный способ управления доступом на основе открытых ключей.
Майк Мазур
Как какое-либо из этих решений решает проблему «я бы хотел, чтобы в этот репозиторий обратились несколько человек»?
Уомбл
взглянуть на Gitosis. это решает вашу проблему.
Пилиф
3
Когда вы поделитесь репозиторием, люди смогут извлечь из него данные. Они, вероятно, должны будут клонировать его или добавить удаленную ветку. Документация, на которую я ссылаюсь, очень ясно поможет вам решить вашу проблему; Я использовал все описанные методы, чтобы помочь разработчикам сотрудничать с Git. Насколько мне известно, ServerFault не предназначен для удержания рук.
Jtimberman
3
Я должен согласиться с использованием Gitosis. Он решает проблему с разрешениями, используя одну учетную запись, аутентифицированную несколькими ключами SSH. Он также полностью управляется с помощью git commit.
Джереми Бауз
9

Также посмотрите на gitolite для размещения вашего git-репозитория. Гитоз, по-видимому, больше не развивается.

MT3
источник
4

Один из способов исправить разрешения в общем репозитории, чтобы у пользователей не возникало проблем с разрешениями при нажатии, - это создать скрипт перехвата после обновления, который будет делать именно это. Это должно работать в любой версии git.

Предположим, у вас есть общий репозиторий в /myrepo.git. Все файлы в этом хранилище принадлежат, скажем, mysharedgroup . Все пользователи, загружающие данные в этот репозиторий, также должны принадлежать к mysharedgroup . Теперь создайте следующий файл (изменив mysharedgroup на ваши предпочтения):

/myrepo.git/hooks/post-update

#!/bin/sh
chmod -R g+w . 2>/dev/null
chgrp -R mysharedgroup . 2>/dev/null
bkmks
источник
правильный ответ, когда у пользователей разные группы по умолчанию
Pat
Установка бита setgid для каталога приведет к тому, что файлы, создаваемые пользователями, наследуют то же владение группой, что и каталог (если пользователи принадлежат этой группе). Даже если это не группа пользователей по умолчанию. Тогда этот крючок не нужен. Вот что делает ответ @ womble (и мой комментарий к нему).
rescdsk
На моей машине centos7, после попытки каждого решения, перечисленного на этой странице, вариант решения @ bkmks, описанного выше, был единственным вариантом, который действительно работал (устанавливая хуки post-merge и post-checkout вместо post-update, как описано выше).
Майк Годин
Я считаю плохим советом продвигать решение, которое передает сообщения об ошибках или предупреждения на STDER /dev/null. Пожалуйста, дайте пользователю сначала увидеть эти сообщения, а затем решайте сами.
Даниэль Бёмер
3

Чтобы собрать воедино полезные советы из различных ответов и комментариев о создании нового репо:

Если вы настраиваете совершенно новый репозиторий myrepoв /srv/gitдля группы mygroup, это то , что вы хотите:

mkdir /srv/git/myrepo.git
chgrp mygroup /srv/git/myrepo.git
git init --bare --shared /srv/git/myrepo.git
  1. первая строка создает директорию репо
  2. вторая строка устанавливает свою группу mygroup
  3. третья строка инициализирует голое репо со следующей конфигурацией:
    1. core.bare = trueсделать репо
    2. core.sharedrepository = 1(так же, как core.sharedrepository = group): каталог репо и все последующие созданные в нем каталоги будут управляться git для предоставления разрешений на mygroupчтение, запись и выполнение (также с установленным битом sgid), чтобы работать с пользователями, для которых они mygroupне являются основная группа)
    3. receive.denyNonFastforwards = 1: отрицать не перемотки вперед в репо

Если вы хотите точно настроить права пользователя, группы или других пользователей, используйте --shared=0NNN, где NNNнаходятся стандартные пользовательские, групповые и другие биты для файлов (биты execute и sgid в каталогах будут соответствующим образом управляться git). Например, это разрешает пользователю доступ для чтения и записи, а также доступ только для чтения к группе (и нет доступа к другим):

git init --bare --shared=0640 /srv/git/myrepo.git

Это позволяет читать и записывать доступ для пользователя и группы (и не иметь доступа к другим):

git init --bare --shared=0660 /srv/git/myrepo.git

Это дает доступ на чтение и запись для пользователя и группы, а также доступ только для чтения к другим:

git init --bare --shared=0664 /srv/git/myrepo.git

Обратите внимание, что если вы не собираетесь разрешать доступ для записи в группу, убедитесь, что сначала используете, chownчтобы установить владельца репо, а затем выполните git initкоманду от имени этого пользователя (чтобы убедиться, что репозиторий инициализирован с правильным владельцем для все исходные файлы и подкаталоги).

Джастин людвиг
источник
Правильнее, чем ответы с более высоким голосом.
XO01
1

Выполнение именно этого сработало для меня, для существующего хранилища. Для этого нужны советы из нескольких ответов и комментариев:

Из родительского каталога вашего хранилища на сервере:

chgrp -R <whatever group> gitrepo
chmod -R g+wX gitrepo
cd gitrepo
find . -type d -exec chmod g+s {} +
git config core.sharedRepository group
Луис де Аркер
источник
0

Ответ @stevek_mcc - тот, который я искал, когда гуглил этот вопрос

git clone --config core.sharedRepository=true
ragerdl
источник