-
1. Введение
- 1.1 О системе контроля версий
- 1.2 Краткая история Git
- 1.3 Что такое Git?
- 1.4 Командная строка
- 1.5 Установка Git
- 1.6 Первоначальная настройка Git
- 1.7 Как получить помощь?
- 1.8 Заключение
-
2. Основы Git
-
3. Ветвление в Git
- 3.1 О ветвлении в двух словах
- 3.2 Основы ветвления и слияния
- 3.3 Управление ветками
- 3.4 Работа с ветками
- 3.5 Удалённые ветки
- 3.6 Перебазирование
- 3.7 Заключение
-
4. Git на сервере
- 4.1 Протоколы
- 4.2 Установка Git на сервер
- 4.3 Генерация открытого SSH ключа
- 4.4 Настраиваем сервер
- 4.5 Git-демон
- 4.6 Умный HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Git-хостинг
- 4.10 Заключение
-
5. Распределённый Git
-
6. GitHub
-
7. Инструменты Git
- 7.1 Выбор ревизии
- 7.2 Интерактивное индексирование
- 7.3 Припрятывание и очистка
- 7.4 Подпись
- 7.5 Поиск
- 7.6 Перезапись истории
- 7.7 Раскрытие тайн reset
- 7.8 Продвинутое слияние
- 7.9 Rerere
- 7.10 Обнаружение ошибок с помощью Git
- 7.11 Подмодули
- 7.12 Создание пакетов
- 7.13 Замена
- 7.14 Хранилище учётных данных
- 7.15 Заключение
-
8. Настройка Git
- 8.1 Конфигурация Git
- 8.2 Атрибуты Git
- 8.3 Хуки в Git
- 8.4 Пример принудительной политики Git
- 8.5 Заключение
-
9. Git и другие системы контроля версий
- 9.1 Git как клиент
- 9.2 Переход на Git
- 9.3 Заключение
-
10. Git изнутри
- 10.1 Сантехника и Фарфор
- 10.2 Объекты Git
- 10.3 Ссылки в Git
- 10.4 Pack-файлы
- 10.5 Спецификации ссылок
- 10.6 Протоколы передачи данных
- 10.7 Обслуживание репозитория и восстановление данных
- 10.8 Переменные окружения
- 10.9 Заключение
-
A1. Приложение A: Git в других окружениях
- A1.1 Графические интерфейсы
- A1.2 Git в Visual Studio
- A1.3 Git в Visual Studio Code
- A1.4 Git в Eclipse
- A1.5 Git в IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.6 Git в Sublime Text
- A1.7 Git в Bash
- A1.8 Git в Zsh
- A1.9 Git в PowerShell
- A1.10 Заключение
-
A2. Приложение B: Встраивание Git в ваши приложения
- A2.1 Git из командной строки
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Приложение C: Команды Git
- A3.1 Настройка и конфигурация
- A3.2 Клонирование и создание репозиториев
- A3.3 Основные команды
- A3.4 Ветвление и слияния
- A3.5 Совместная работа и обновление проектов
- A3.6 Осмотр и сравнение
- A3.7 Отладка
- A3.8 Внесение исправлений
- A3.9 Работа с помощью электронной почты
- A3.10 Внешние системы
- A3.11 Администрирование
- A3.12 Низкоуровневые команды
7.14 Инструменты Git - Хранилище учётных данных
Хранилище учётных данных
Если для подключения к удалённым серверам вы используете протокол SSH, то вы можете использовать ключ вместо пароля, что позволит вам безопасно передавать данные без ввода логина и пароля. Однако, это невозможно при использовании HTTP-протоколов — каждое подключение требует пары логин, пароль. Всё ещё сложнее для систем с двухфакторной аутентификацией, когда выражение, которое вы используете в качестве пароля, генерируется случайно и его сложно воспроизвести.
К счастью, в Git есть система управления учётными данными, которая может помочь в этом. В Git «из коробки» есть несколько опций:
-
По умолчанию Git не кеширует учётные данные совсем. Каждое подключение будет запрашивать у вас логин и пароль.
-
В режиме «cache» учётные данные сохраняются в памяти в течение определённого периода времени. Ни один из паролей никогда не сохраняется на диск и все они удаляются из кеша через 15 минут.
-
В режиме «store» учётные данные сохраняются на неограниченное время в открытом виде в файле на диске. Это значит что, до тех пор пока вы не измените пароль к Git-серверу, вам не потребуется больше вводить ваши учётные данные. Недостатком такого подхода является то, что ваш пароль хранится в открытом виде в файле в вашем домашнем каталоге.
-
На случай если вы используете Mac, в Git есть режим «osxkeychain», при использовании которого учётные данные хранятся в защищённом хранилище, привязанному к вашему системному аккаунту. В этом режиме учётные данные сохраняются на диск на неограниченное время, но они шифруются с использованием той же системы, с помощью которой сохраняются HTTPS-сертификаты и автозаполнения для Safari.
-
В случае если вы используете Windows, то можете включить использование «Git Credential Manager» во время установки Git для Windows или установить крайнюю версию GCM как отдельный сервис. Он похож на «osxkeychain», описанный выше, но для управления секретной информацией использует Windows Credential Store. Его так же можно использовать в WSL1 и WSL2. Больше имнформации об установке и настройке GCM можно найти на странице проекта на GitHub.
Вы можете выбрать один из этих методов, изменив настройки Git:
$ git config --global credential.helper cache
Некоторые из этих помощников имеют опции.
Помощник «store» может принимать аргумент --file <path>
, который определяет где будет хранится файл с открытыми учётными данный (по умолчанию используется ~/.git-credentials
).
Помощник «cache» принимает опцию --timeout <seconds>
, которая изменяет промежуток времени, в течение которого демон остаётся запущенным (по умолчанию «900», или 15 минут).
Ниже приведён пример как вы можете настроить помощник «store» на использование определённого файла:
$ git config --global credential.helper 'store --file ~/.my-credentials'
Git позволяет настраивать сразу несколько помощников.
При поиске учётных данных для конкретного сервера, Git будет по порядку запрашивать у них учётные данные и остановится при получении первого ответа.
При сохранении учётных данных, Git отправит их всем помощникам в списке, которые уже в свою очередь могут решить, что с этими данными делать.
Ниже приведено как будет выглядеть .gitconfig
, если у вас есть файл с учётными данными на флэш-диске, но, на случай его отсутствия, вы хотите дополнительно использовать кеширование в оперативной памяти.
[credential]
helper = store --file /mnt/thumbdrive/.git-credentials
helper = cache --timeout 30000
Под капотом
Как же это всё работает?
Корневой командой Git для системы помощников авторизации является git credential
, которая принимает команду через аргумент, а все остальные входные данные через стандартный поток ввода.
Возможно, это проще понять на примере.
Допустим, помощник авторизации был настроен и в нём сохранены учётные данные для mygithost
.
Ниже приведена рабочая сессия, в которой используется команда «fill», вызываемая Git при попытке найти учётные данные для сервера:
$ git credential fill (1)
protocol=https (2)
host=mygithost
(3)
protocol=https (4)
host=mygithost
username=bob
password=s3cre7
$ git credential fill (5)
protocol=https
host=unknownhost
Username for 'https://unknownhost': bob
Password for 'https://bob@unknownhost':
protocol=https
host=unknownhost
username=bob
password=s3cre7
-
Это команда, которая начинает взаимодействие.
-
После этого Git-credential ожидает данные из стандартного потока ввода. Мы передаём ему то, что знаем: протокол и имя сервера.
-
Пустая строка обозначает, что ввод закончен и система управления учётными данными должна ответить, что ей известно.
-
После этого Git-credential выполняет какую-то работу и выводит обнаруженную информацию.
-
Если учётные данные не найдены, Git спрашивает у пользователя логин/пароль, и выводит их обратно в задействованный поток вывода (в данном примере это одна и та же консоль).
В действительности, система управления учётными данными вызывает программы, отделённые от самого Git; какие и как зависит в том числе и от настроек credential.helper
.
Существует несколько вариантов вызова:
Настройки | Поведение |
---|---|
|
Выполняется |
|
Выполняется |
|
Выполняется |
|
Код после символа |
Итак, помощники, описанные выше на самом деле называются git-credential-cache
, git-credential-store
и т. д. и мы можем настроить их на приём аргументов командной строки.
Общая форма для этого git-credential-foo [args] <action>
.
Протокол ввода/вывода такой же как и у git-credential, но они используют немного другой набор операций:
-
get
запрос логина и пароля. -
store
запрос на сохранение учётных данных в памяти помощника. -
erase
удаляет учётные данные для заданных параметров из памяти используемого помощника.
Для операций store
и erase
не требуется ответа (в любом случае Git его игнорирует).
Однако, для Git очень важно, что помощник ответит на операцию get
.
Если помощник не знает что-либо полезного, он может просто завершить работу не выводя ничего, но если знает — он должен добавить к введённой информации имеющуюся у него информацию.
Вывод обрабатывается как набор операций присваивания; выведенные значения заменят те, что Git знал до этого.
Ниже приведён пример, используемый ранее, но вместо git-credential напрямую вызывается git-credential-store:
$ git credential-store --file ~/git.store store (1)
protocol=https
host=mygithost
username=bob
password=s3cre7
$ git credential-store --file ~/git.store get (2)
protocol=https
host=mygithost
username=bob (3)
password=s3cre7
-
Здесь мы просим
git-credential-store
сохранить некоторые учётные данные: логин «bob» и пароль «s3cre7», которые будут использоваться при доступе кhttps://mygithost
. -
Теперь мы извлечём эти учётные данные. Мы передаём часть уже известных нам параметров подключения (
https://mygithost
) и пустую строку. -
git-credential-store
возвращает логин и пароль, которые мы сохранили ранее.
Ниже приведено содержимое файла ~/git.store
:
https://bob:s3cre7@mygithost
Это просто набор строк, каждая из которых содержит URL, включающий в себя учётные данные.
Помощники osxkeychain
и wincred
используют форматы, лежащие в основе их хранилищ, а cache
использует его собственный формат хранения во внутренней памяти (который другие процессы прочитать не могут).
Собственное хранилище учётных данных
Поскольку git-credential-store
и подобные ей утилиты являются отдельными от Git программами, не сложно сделать так, чтобы любая программа могла быть помощником авторизации Git.
Помощники, предоставляемые Git, покрывают наиболее распространённые варианты использования, но не все.
Для примера допустим, что ваша команда имеет некоторые учётные данные, совместно используемые всей командой, например, для развёртывания.
Эти данные хранятся в общедоступном каталоге, но вы не хотите копировать их в ваше собственное хранилище учётных данных, так как они часто изменяются.
Ни один из существующих помощников не покрывает этот случай; давайте посмотрим, что будет стоить написать свой собственный.
Есть несколько ключевых особенностей, которым должна удовлетворять эта программа:
-
Мы должны уделить внимание только одной операции
get
;store
иerase
являются операциями записи, поэтому мы не будем ничего делать при их получении. -
Формат файла с совместно используемыми учётными данными такой же как и у
git-credential-store
. -
Расположение этого файла более-менее стандартное, но, на всякий случай, мы должны позволять пользователям передавать свой собственный путь.
Мы снова напишем расширение на Ruby, но подойдёт любой язык, так как Git может использовать всё, что сможет запустить на выполнение. Ниже приведён полный исходный код нашего нового помощника авторизации:
#!/usr/bin/env ruby
require 'optparse'
path = File.expand_path '~/.git-credentials' # (1)
OptionParser.new do |opts|
opts.banner = 'USAGE: git-credential-read-only [options] <action>'
opts.on('-f', '--file PATH', 'Specify path for backing store') do |argpath|
path = File.expand_path argpath
end
end.parse!
exit(0) unless ARGV[0].downcase == 'get' # (2)
exit(0) unless File.exists? path
known = {} # (3)
while line = STDIN.gets
break if line.strip == ''
k,v = line.strip.split '=', 2
known[k] = v
end
File.readlines(path).each do |fileline| # (4)
prot,user,pass,host = fileline.scan(/^(.*?):\/\/(.*?):(.*?)@(.*)$/).first
if prot == known['protocol'] and host == known['host'] and user == known['username'] then
puts "protocol=#{prot}"
puts "host=#{host}"
puts "username=#{user}"
puts "password=#{pass}"
exit(0)
end
end
-
Здесь мы разбираем аргументы командной строки, позволяя указывать пользователям входной файл. По умолчанию это
~/.git-credentials
. -
Эта программа отвечает только если операцией является
get
и файл хранилища существует. -
В цикле считываются данные из стандартного ввода, до тех пор пока не будет прочитана пустая строка. Введённые данные для дальнейшего использования сохраняются в отображении
known
. -
Этот цикл читает содержимое файла хранилища, выполняя поиск соответствия. Если протокол и сервер из
known
соответствуют текущей строке, программа выводит результат и завершает работу.
Мы сохраним нашего помощника как git-credential-read-only
, поместим его в один из каталогов, содержащихся в списке PATH
, а так же сделаем его исполняемым.
Ниже приведено на что будет похож сеанс взаимодействия:
$ git credential-read-only --file=/mnt/shared/creds get
protocol=https
host=mygithost
protocol=https
host=mygithost
username=bob
password=s3cre7
Так как его имя начинается с «git-», мы можем использовать простой синтаксис для настройки:
$ git config --global credential.helper 'read-only --file /mnt/shared/creds'
Как вы видите, расширять эту систему довольно просто и это позволяет решить некоторые общие проблемы, которые могут возникнуть у вас и вашей команды.