该库允许使用 Amazon S3 作为 git 远程和 LFS 服务器。
它提供了 git 远程帮助程序的实现,以将 S3 用作无服务器 Git 服务器。
它还提供了 git-lfs 自定义传输的实现,以将 LFS 托管文件推送到用作远程的同一 S3 存储桶。
git-remote-s3
是一个 Python 脚本,适用于任何 >= 3.9 的 Python 版本。
跑步:
pip install git-remote-s3
在使用git-remote-s3
之前,您必须:
完成初始配置:
在您的 AWS 账户中创建一个 AWS S3 存储桶(或已有一个)。
向该用户/角色附加一个允许 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 语法,并使用 s3 URI 作为远程:
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。您可以参考官方文档了解如何在您的系统上执行此操作。
接下来,您需要通过在 repo 文件夹中运行以下命令来启用 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
假设我们要在 LFS 中存储 TIFF 文件。
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
有效存储桶的 Amazon S3 URI 和其下不包含正确结构的任意前缀被视为有效。
git ls-remote
返回一个空列表,并且git clone
克隆一个空存储库,其中 S3 URI 设置为远程源。
% 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
命令,该命令将包写入refs/heads/<branch>
路径处的 S3 存储桶如果从不同的客户端同时执行两个(或多个) 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
。
当使用 LFS 的 S3 远程克隆存储库时, 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>
。
捆绑包以<prefix>/<ref>/<sha>.bundle
形式存储在 S3 存储桶中。
当列出远程引用时(例如通过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 集成的灵感来自于 Bryan Gahagan 在 git-remote-s3 上的工作。
LFS 的实现受益于 @nicolas-graves 的 lfs-s3。如果您不需要使用 git-remote-s3 传输,则应该使用该项目。