Esta biblioteca permite usar o Amazon S3 como um servidor git remoto e LFS.
Ele fornece uma implementação de um auxiliar remoto git para usar o S3 como um servidor Git sem servidor.
Ele também fornece uma implementação da transferência personalizada git-lfs para permitir o envio de arquivos gerenciados pelo LFS para o mesmo bucket S3 usado como remoto.
git-remote-s3 é um script Python e funciona com qualquer versão do Python >= 3.9.
Correr:
pip install git-remote-s3
Antes de poder usar git-remote-s3 , você deve:
Conclua a configuração inicial:
Crie um bucket AWS S3 (ou já tenha um) em sua conta AWS.
Anexe uma política mínima a esse usuário/função que permita o bucket S3:
{
"Sid" : " S3Access " ,
"Effect" : " Allow " ,
"Action" : [ " s3:PutObject " , " s3:GetObject " , " s3:ListBucket " ],
"Resource" : [ " arn:aws:s3:::<BUCKET> " , " arn:aws:s3:::*/* " ]
}Opcional (mas recomendado) - use chaves de bucket SSE-KMS para criptografar o conteúdo do bucket, certifique-se de que o usuário/função criado anteriormente tenha permissão para acessar e usar a chave.
{
"Sid" : " KMSAccess " ,
"Effect" : " Allow " ,
"Action" : [ " kms:Decrypt " , " kms:GenerateDataKey " ],
"Resource" : [ " arn:aws:kms:<REGION>:<ACCOUNT>:key/<KEY_ID> " ]
}Todos os dados são criptografados em repouso e em trânsito por padrão. Para adicionar uma camada adicional de segurança, você pode usar chaves KMS gerenciadas pelo cliente para criptografar os dados em repouso no bucket S3. Recomendamos usar chaves de bucket para minimizar os custos de KMS.
O controlo de acesso ao remoto é assegurado através de permissões IAM, podendo ser controlado em:
Os controles remotos S3 são identificados pelo prefixo s3:// e, no mínimo, especificam o nome do bucket. Você também pode fornecer um prefixo de chave como em s3://my-git-bucket/my-repo e um perfil s3://my-profile@my-git-bucket/myrepo .
mkdir my-repo
cd my-repo
git init
git remote add origin s3://my-git-bucket/my-repoVocê pode então adicionar um arquivo, confirmar e enviar as alterações para o controle remoto:
echo " Hello " > hello.txt
git add -A
git commit -a -m " hello "
git push --set-upstream origin main O HEAD remoto está configurado para rastrear a ramificação que foi enviada primeiro para o repositório remoto. Para alterar a ramificação HEAD remota, exclua o objeto HEAD s3://<bucket>/<prefix>/HEAD e execute git-remote-s3 doctor s3://<bucket>/<prefix> .
Para clonar o repositório para outra pasta, basta usar a sintaxe normal do git usando o URI s3 como remoto:
git clone s3://my-git-bucket/my-repo my-repo-cloneCriar ramificações e enviá-las funciona normalmente:
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 Todas as operações git que não dependem de comunicação com o servidor devem funcionar normalmente (por exemplo, git merge )
Para usar o LFS você precisa primeiro instalar o git-lfs. Você pode consultar a documentação oficial sobre como fazer isso em seu sistema.
Em seguida, você precisa habilitar a integração S3 executando o seguinte comando na pasta repo:
lfs-s3-py installque é um atalho para:
git config --add lfs.customtransfer.lfs-s3-py.path lfs-s3-py
git config --add lfs.standalonetransferagent lfs-s3-pyVamos supor que queremos armazenar o arquivo TIFF no 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 mainUm URI do Amazon S3 para um bucket válido e um prefixo arbitrário que não contém a estrutura correta é considerado válido.
git ls-remote retorna uma lista vazia e git clone clona um repositório vazio para o qual o URI S3 está definido como origem remota.
% 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)
Dica : Este comportamento pode ser usado para criar rapidamente um novo repositório git.
Devido à natureza distribuída do git , pode haver casos (embora raros) em que 2 ou mais git push são executados ao mesmo tempo por usuários diferentes com sua própria modificação do mesmo branch.
O comando git executa o push em 2 etapas:
git-remote-s3 que grava o pacote no bucket S3 no caminho refs/heads/<branch> Caso dois (ou mais) comandos git push sejam executados ao mesmo tempo em clientes diferentes, na etapa 1 a mesma referência válida é buscada, portanto, ambos os clientes prosseguem com a etapa 2, resultando no armazenamento de vários pacotes no S3.
A ramificação agora tem várias referências head e qualquer git push subsequente falha com o erro:
error: dst refspec refs/heads/<branch>> matches more than one
error: failed to push some refs to 's3://<bucket>/<prefix>'
Para corrigir esse problema, execute o comando git-remote-s3 doctor <s3-uri> . Por padrão, ele criará uma nova ramificação para cada pacote configurável que não deve ser retido. O usuário pode então fazer check-out do branch localmente e mesclá-lo ao branch original. Se você quiser remover o pacote, especifique --delete-bundle .
Ao clonar um repositório usando o controle remoto S3 para LFS, git-lfs não sabe como buscar os arquivos, pois ainda precisamos adicionar a configuração.
Envolve 2 etapas extras.
% 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
...Para corrigir:
cd lfs-repo-clone
lfs-s3-py install
git reset --hard main Para remover ramificações remotas que não são mais usadas, você pode usar o comando git-s3 delete-branch <s3uri> -b <branch_name> . Este comando exclui os objetos de pacote configurável do Amazon S3 no caminho da ramificação.
Para proteger/desproteger uma ramificação, execute git s3 protect <remote> <branch-name> respectivamente git s3 unprotect <remote> <branch-name> .
Os pacotes são armazenados no bucket S3 como <prefix>/<ref>/<sha>.bundle .
Ao listar a ref remota (por exemplo, explicitamente via git ls-remote ), listamos todas as chaves presentes no arquivo .
Ao enviar uma nova ref (por exemplo, um commit), obtemos o sha da ref, empacotamos a ref via git bundle create <sha>.bundle <ref> e armazenamos no S3 de acordo com o esquema acima.
Se o push for bem-sucedido, o código removerá o pacote anterior associado à ref.
Se dois usuários enviarem simultaneamente um commit com base no mesmo branch atual para o remoto, ambos os pacotes serão gravados no repositório e o pacote atual será removido. Nenhum dado será perdido, mas nenhum push adicional será possível até que todos os pacotes, exceto um, sejam removidos. Para isso você pode usar o comando git s3 doctor <remote> .
A integração LFS armazena o arquivo no bucket definido pelo URI remoto, sob uma chave <prefix>/lfs/<oid> , onde oid é o identificador exclusivo atribuído pelo git-lfs ao arquivo.
Se já existir um objeto com a mesma chave, git-lfs-s3 não o carrega novamente.
Use o sinalizador --verbose para imprimir algumas informações de depuração ao executar operações git. Os logs serão colocados em stderr.
Para operações LFS, você pode ativar e desativar o log de depuração via git-lfs-s3 enable-debug e git-lfs-s3 disable-debug respectivamente. Os logs são colocados em .git/lfs/tmp/git-lfs-s3.log no repositório.
A integração do git S3 foi inspirada no trabalho de Bryan Gahagan no git-remote-s3.
A implementação do LFS se beneficiou do lfs-s3 de @nicolas-graves. Se você não precisa usar o transporte git-remote-s3, você deve usar esse projeto.