Эта библиотека позволяет использовать Amazon S3 в качестве удаленного сервера git и LFS.
Он предоставляет реализацию удаленного помощника git для использования S3 в качестве бессерверного сервера Git.
Он также обеспечивает реализацию пользовательской передачи git-lfs, позволяющую отправлять управляемые файлы LFS в ту же корзину S3, которая используется в качестве удаленной.
git-remote-s3
— это скрипт Python, работающий с любой версией Python >= 3.9.
Бегать:
pip install git-remote-s3
Прежде чем вы сможете использовать git-remote-s3
, вы должны:
Полная первоначальная настройка:
Создайте корзину AWS S3 (или уже создайте ее) в своем аккаунте AWS.
Прикрепите к этому пользователю/роли минимальную политику, которая разрешает доступ к корзине S3:
{
"Sid" : " S3Access " ,
"Effect" : " Allow " ,
"Action" : [ " s3:PutObject " , " s3:GetObject " , " s3:ListBucket " ],
"Resource" : [ " arn:aws:s3:::<BUCKET> " , " arn:aws:s3:::*/* " ]
}
Необязательно (но рекомендуется): используйте ключи корзины SSE-KMS для шифрования содержимого корзины, убедитесь, что ранее созданный пользователь/роль имеет разрешение на доступ и использование ключа.
{
"Sid" : " KMSAccess " ,
"Effect" : " Allow " ,
"Action" : [ " kms:Decrypt " , " kms:GenerateDataKey " ],
"Resource" : [ " arn:aws:kms:<REGION>:<ACCOUNT>:key/<KEY_ID> " ]
}
По умолчанию все данные при хранении и передаче шифруются. Чтобы добавить дополнительный уровень безопасности, вы можете использовать ключи KMS, управляемые клиентом, для шифрования данных, хранящихся в корзине S3. Мы рекомендуем использовать ключи Bucket, чтобы минимизировать затраты на KMS.
Контроль доступа к пульту обеспечивается с помощью разрешений IAM и может контролироваться по адресу:
Пульты S3 идентифицируются префиксом s3://
и как минимум указывают имя сегмента. Вы также можете указать префикс ключа, например s3://my-git-bucket/my-repo
, и профиль s3://my-profile@my-git-bucket/myrepo
.
mkdir my-repo
cd my-repo
git init
git remote add origin s3://my-git-bucket/my-repo
Затем вы можете добавить файл, зафиксировать и отправить изменения на удаленный компьютер:
echo " Hello " > hello.txt
git add -A
git commit -a -m " hello "
git push --set-upstream origin main
Удаленный HEAD настроен на отслеживание ветки, которая была первой отправлена в удаленный репозиторий. Чтобы изменить удаленную ветку HEAD, удалите объект HEAD s3://<bucket>/<prefix>/HEAD
, а затем запустите git-remote-s3 doctor s3://<bucket>/<prefix>
.
Чтобы клонировать репозиторий в другую папку, просто используйте обычный синтаксис git, используя URI s3 в качестве удаленного:
git clone s3://my-git-bucket/my-repo my-repo-clone
Создание ветвей и их отправка работает как обычно:
cd my-repo
git checkout -b new_branch
touch new_file.txt
git add -A
git commit -a -m " new file "
git push origin new_branch
Все операции git, которые не полагаются на связь с сервером, должны работать как обычно (например, git merge
).
Чтобы использовать LFS, вам необходимо сначала установить git-lfs. Вы можете обратиться к официальной документации о том, как это сделать в вашей системе.
Далее вам необходимо включить интеграцию S3, выполнив следующую команду в папке репо:
lfs-s3-py install
что является сокращением для:
git config --add lfs.customtransfer.lfs-s3-py.path lfs-s3-py
git config --add lfs.standalonetransferagent lfs-s3-py
Предположим, мы хотим сохранить файл TIFF в LFS.
mkdir lfs-repo
cd lfs-repo
git init
git lfs install
lfs-s3-py install
git lfs track " *.tiff "
git add .gitattributes
< put file.tiff in the repo >
git add file.tiff
git commit -a -m " my first tiff file "
git remote add origin s3://my-git-bucket/lfs-repo
git push --set-upstream origin main
URI Amazon S3 для допустимого сегмента и произвольный префикс, который не содержит подходящей структуры, считается действительным.
git ls-remote
возвращает пустой список, а git clone
клонирует пустой репозиторий, для которого URI S3 установлен в качестве удаленного источника.
% git clone s3://my-git-bucket/this-is-a-new-repo
Cloning into 'this-is-a-new-repo'...
warning: You appear to have cloned an empty repository.
% cd this-is-a-new-repo
% git remote -v
origin s3://my-git-bucket/this-is-a-new-repo (fetch)
origin s3://my-git-bucket/this-is-a-new-repo (push)
Совет . Такое поведение можно использовать для быстрого создания нового репозитория git.
Из-за распределенного характера git
могут быть случаи (хотя и редкие), когда 2 или более git push
выполняются одновременно разными пользователями с собственной модификацией одной и той же ветки.
Команда git выполняет отправку в два этапа:
git-remote-s3
, которая записывает пакет в корзину S3 по пути refs/heads/<branch>
. Если две (или более) команды git push
выполняются одновременно от разных клиентов, на шаге 1 извлекается одна и та же действительная ссылка, поэтому оба клиента переходят к шагу 2, в результате чего в S3 сохраняется несколько пакетов.
Ветка теперь имеет несколько ссылок на заголовки, и любое последующее git push
завершается с ошибкой:
error: dst refspec refs/heads/<branch>> matches more than one
error: failed to push some refs to 's3://<bucket>/<prefix>'
Чтобы устранить эту проблему, запустите команду git-remote-s3 doctor <s3-uri>
. По умолчанию будет создана новая ветка для каждого пакета, который не следует сохранять. Затем пользователь может извлечь ветку локально и объединить ее с исходной веткой. Если вы хотите вместо этого удалить пакет, укажите --delete-bundle
.
При клонировании репозитория с помощью пульта S3 для LFS git-lfs
не может знать, как получить файлы, поскольку нам еще предстоит добавить конфигурацию.
Это включает в себя 2 дополнительных шага.
% git clone s3://my-git-bucket/lfs-repo lfs-repo-clone
Error downloading object: file.tiff (54238cf): Smudge error: Error downloading file.tiff (54238cfaaaa42dda05da0e12bf8ee3156763fa35296085ccdef63b13a87837c5): batch request: ssh: Could not resolve hostname s3: Name or service not known: exit status 255
...
Чтобы исправить:
cd lfs-repo-clone
lfs-s3-py install
git reset --hard main
Чтобы удалить удаленные ветки, которые больше не используются, вы можете использовать команду git-s3 delete-branch <s3uri> -b <branch_name>
. Эта команда удаляет объекты пакета из Amazon S3 по пути ветки.
Чтобы защитить/снять защиту ветки, запустите git s3 protect <remote> <branch-name>
соответственно git s3 unprotect <remote> <branch-name>
.
Пакеты хранятся в корзине S3 как <prefix>/<ref>/<sha>.bundle
.
При перечислении удаленной ссылки (например, явно через git ls-remote
) мы перечисляем все ключи, присутствующие в данном файле .
При отправке новой ссылки (например, коммита) мы получаем sha ссылки, связываем ссылку с помощью git bundle create <sha>.bundle <ref>
и сохраняем ее на S3 в соответствии со схемой выше.
Если отправка прошла успешно, код удаляет предыдущий пакет, связанный со ссылкой.
Если два пользователя одновременно отправят фиксацию на основе одного и того же текущего заголовка ветки на удаленный компьютер, оба пакета будут записаны в репозиторий, а текущий пакет будет удален. Никакие данные не теряются, но дальнейшая передача будет невозможна, пока не будут удалены все пакеты, кроме одного. Для этого вы можете использовать команду git s3 doctor <remote>
.
Интеграция LFS сохраняет файл в корзине, определенной удаленным URI, под ключом <prefix>/lfs/<oid>
, где oid — это уникальный идентификатор, присвоенный файлу git-lfs.
Если объект с таким ключом уже существует, git-lfs-s3 не загружает его повторно.
Используйте флаг --verbose
для вывода некоторой отладочной информации при выполнении операций git. Журналы будут помещены в stderr.
Для операций LFS вы можете включать и отключать ведение журнала отладки с помощью git-lfs-s3 enable-debug
и git-lfs-s3 disable-debug
соответственно. Журналы помещаются в .git/lfs/tmp/git-lfs-s3.log
в репозитории.
Интеграция git S3 была вдохновлена работой Брайана Гахагана над git-remote-s3.
В реализации LFS использовался lfs-s3 от @nicolas-graves. Если вам не нужно использовать транспорт git-remote-s3, вам следует использовать этот проект.