Можно ли кэшировать учетные данные git для каждого проекта?
Несколько человек работают над несколькими проектами на одном веб-сервере через сетевой ресурс. Каждый проект имеет свой собственный репозиторий git. При запуске проекта у нас есть отдельная среда разработки для разработчиков, работающих над проектом, и промежуточная среда для каждого проекта. Все файлы принадлежат www-data
, потому что это пользователь, которого использует Apache.
Чтобы избежать необходимости вводить имя пользователя и пароль несколько раз, когда вы тянете, нажав и переключитесь на новую ветку, мы в настоящее время используем кеш учетных данных (как найдено здесь).
$ git config --global credential.helper
cache --timeout=900
Проблема, с которой мы сталкиваемся, заключается в том, что, когда кто-то (пользователь 1) выполняет аутентифицированное действие git, они вводят свои учетные данные. В течение таймаута кто-то еще (пользователь 2) выполняет аутентифицированное действие git в своем собственном репозитории, в котором используются учетные данные пользователя 1. Это приведет к одной из двух вещей:
- Пользователь 2 получает сообщение об ошибке, что репозиторий не существует. Это связано с тем, что пользователь 1 не имеет прав на выполнение действий в репозитории пользователя 2.
- Пользователь 2 подталкивает фиксацию (вместе с ними как автор), используя учетную запись пользователя 1. Нажатие отображается в истории пользователя 1.
Я думаю, что эту проблему можно частично смягчить, добавив имя пользователя в URL-адрес репозитория git (например, имя пользователя @git.domain.ext/repo/name.git), но это работает только на начальных этапах, у нас есть индивидуальные среды разработки для каждого пользователя. К промежуточной среде необходимо обращаться несколькими людьми, поэтому мы не можем жестко указать имя пользователя. После того, как мы сделали начальную разработку, и проект пошел вживую, мы очищаем среду разработки, потому что у нас нет бесконечного пространства. Если нам нужно внести изменения после того, как мы очистили среду персонального развития, мы обычно используем промежуточную среду для этого, что приведет к той же проблеме.
Команда git config --global credential.helper
заставляет учетные данные храниться на сервере. Понижение тайм-аута помогает только так. Можем ли мы кэшировать учетные данные для среды разработки?
Ответы
Ответ 1
Часть проблемы может быть решена с помощью git config --global credential.useHttpPath true
. Он избавляется от ошибки в том, что репозиторий не существует, потому что у нас нет людей, у которых есть разрешение на выгрузку репозитория, но нет прав на его продвижение. Два человека, работающие с одним и тем же репозиторием в разных каталогах, все же могут случайно нажимать, как и другой пользователь.
Eis 'ответ - солидный совет, когда вы работаете над проектами, которые вы легко можете использовать. В моем случае многие проекты не легко посеяны, что делает его несколько менее идеальным решением.
Натан, вероятно, является самым чистым решением и, вероятно, будет работать с более широким набором систем, чем следующее решение.
В моем случае я решил пойти с подходом, вдохновленным VonC. git-credential-cache позволяет использовать два параметра, а именно параметр timeout
и параметр socket
. В настоящее время мы используем исключительно bash, который предоставляет переменную $BASHPID
, содержащую pid текущей оболочки. Мы, к сожалению, не можем использовать переменную непосредственно в значении конфигурации, но, используя предложение VonC для теневой команды git, мы можем сделать псевдоним вместо этого.
Я добавил дополнительную строку в файл ~/.bashrc
пользователя www-data и добавил:
alias git="/usr/bin/git -c credential.helper='cache --timeout=7200 --socket=/var/www/.git-credential-cache/socket_$BASHPID'"
Примечание: сокет должен быть абсолютным путем, а домашний каталог пользователя www-data
оказался /var/www/
Я удалил глобальную конфигурацию вспомогательных учетных данных:
git config --global --unset credential.helper
Теперь он использует отдельный сокет в оболочке bash. Самое приятное в этом подходе заключается в том, что он по-прежнему использует механизм кэширования git, который означает, что он, вероятно, не будет разорван в ближайшее время. Недостатком является то, что затенение команды вводит магическое поведение (в конфигурации ничего не установлено, но оно работает независимо... как?), Что может смутить коллег в будущем.
Ответ 2
Я не мог найти вариант, чтобы точно соответствовать тому, что вам нужно, поэтому я написал один: помощник учетных данных git, который хранит учетные данные на для каждой оболочки.
Он устанавливает временный ключ шифрования и временный каталог данных для входа в систему, использует их для хранения имени пользователя и пароля, заданного git в фазе store
credential helper process, затем возвращает их в фазу get
.
Предостережения:
- Я тестировал его, но только довольно ограниченным образом. Он работает: две отдельные оболочки входа для одного и того же пользователя могут иметь отдельные кэшированные учетные данные.
- Он довольно наивный: он игнорирует любое имя пользователя и URL-адрес репо, заданный git при хранении и получении учетных данных.
- Он оставит за собой временную директорию с несколькими небольшими файлами для каждого входа.
- Он хранит учетные данные в зашифрованном виде, но я не утверждаю, насколько это безопасно на практике.
- Для этого требуется Python 3.6, pycrypto и bash; Я тестировал его на linux и macOS. Его нужно довольно легко адаптировать для других настроек.
Откройте проблему, если у вас возникнут проблемы, и я увижу, что я могу сделать.
Ответ 3
Одно смягчающее решение, которое я видел в этой общей среде, - это иметь оболочку-оболочку script с именем "git", которая будет:
- затмить фактическую команду
git
- запускается специальной учетной записью (через sudo -u xxx)
- читать учетные данные из временного файла с именем ps id (файл, принадлежащий xxx, не читаемый исходным пользователем)
- если этот временный файл не существует (при первом вызове git), он создает и сохраняет имя пользователя/пароль.
- используйте этот вспомогательный помощник для команд pull/push/clone, с командой-local config
/usr/bin/git -c credential.helper 'store --file=/path/to/temp/credentials' ...
, снова выполняемый оберткой как xxx
.
Тот же script может не только запрашивать учетные данные, но также запрашивать имя автора/адрес электронной почты и добавлять его к своей команде git, настройки local GIT_AUTHOR_NAME
/EMAIL
для каждого вызова /usr/bin/git
.
Идея состоит в том, чтобы сделать команду git с локальными конфигурациями (локально для самой команды git)
Ответ 4
Вот два возможных решения вашей проблемы:
1 - иметь одного пользователя ОС на разработчика.
Это более чистый вариант: каждый из разработчиков подключится к другой учетной записи пользователя. Добавьте этих пользователей в группу www-data
и установите соответствующие параметры файла: разрешите чтение и запись членами группы.
Каждая аутентификация пользователей будет управляться независимо.
2 - сохранить конфигурацию для каждого проекта
В настоящее время хранилище учетных данных пользователя --global
выполняется на уровне пользователя ОС. Вместо этого вы можете использовать --local
, чтобы сохранить учетные данные на уровне проекта.
Это позволит решить описанную проблему между пользователями 1 и 2. Однако вам по-прежнему может не хватать некоторой прослеживаемости: в случае, если два разработчика работают над одним и тем же проектом, если пользователь2 подталкивает некоторые изменения вскоре после пользователя1, данные аутентификации user1 будут и он будет выглядеть так, как будто это человек, который сделал нажатие, тогда как пользователь2.
Прочтите git config --help
для получения подробной информации о параметрах --local и местах хранения данных.
Ответ 5
Прекратить использование общего сетевого ресурса. Попросите пользователей клонировать репозиторий на своих машинах и делать изменения таким образом. Никакие файлы не должны меняться непосредственно в промежуточной среде, даже через сетевые ресурсы.
Пользователи могут иметь локальные установки Apache, если они хотят немедленно увидеть их изменения и поэкспериментировать с этим.
Кроме того, вы можете подумать о размещении своих репозиториев на отдельном сервере и выполнить развертывание из этих репозиториев в промежуточную среду с помощью инструмента развертывания, поскольку git не является инструментом развертывания. Это может быть автоматизировано. Однако самое главное, что вы должны сделать, это прекратить использование сетевого ресурса и использовать git push
, чтобы инициировать изменения, а не изменять файлы на сервере самостоятельно.