Можно ли кэшировать учетные данные 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, чтобы инициировать изменения, а не изменять файлы на сервере самостоятельно.