Diese Bibliothek ermöglicht die Verwendung von Amazon S3 als Git-Remote- und LFS-Server.
Es bietet eine Implementierung eines Git-Remote-Helfers zur Verwendung von S3 als serverlosen Git-Server.
Es bietet außerdem eine Implementierung der benutzerdefinierten git-lfs-Übertragung, um das Pushen von LFS-verwalteten Dateien in denselben S3-Bucket zu ermöglichen, der als Remote verwendet wird.
git-remote-s3
ist ein Python-Skript und funktioniert mit jeder Python-Version >= 3.9.
Laufen:
pip install git-remote-s3
Bevor Sie git-remote-s3
verwenden können, müssen Sie:
Komplette Erstkonfiguration:
Erstellen Sie einen AWS S3-Bucket (oder verfügen Sie bereits über einen) in Ihrem AWS-Konto.
Fügen Sie diesem Benutzer/dieser Rolle eine minimale Richtlinie hinzu, die den Zugriff auf den S3-Bucket ermöglicht:
{
"Sid" : " S3Access " ,
"Effect" : " Allow " ,
"Action" : [ " s3:PutObject " , " s3:GetObject " , " s3:ListBucket " ],
"Resource" : [ " arn:aws:s3::: " , " arn:aws:s3:::*/* " ]
}
Optional (aber empfohlen) – verwenden Sie SSE-KMS-Bucket-Schlüssel, um den Inhalt des Buckets zu verschlüsseln. Stellen Sie sicher, dass der Benutzer/die erstellte Rolle zuvor die Berechtigung hat, auf den Schlüssel zuzugreifen und ihn zu verwenden.
{ "Sid" : " KMSAccess " , "Effect" : " Allow " , "Action" : [ " kms:Decrypt " , " kms:GenerateDataKey " ], "Resource" : [ " arn:aws:kms:: ] }:key/ "
Alle Daten werden im Ruhezustand und während der Übertragung standardmäßig verschlüsselt. Um eine zusätzliche Sicherheitsebene hinzuzufügen, können Sie vom Kunden verwaltete KMS-Schlüssel verwenden, um die ruhenden Daten im S3-Bucket zu verschlüsseln. Wir empfehlen die Verwendung von Bucket-Schlüsseln, um die KMS-Kosten zu minimieren.
Die Zugriffskontrolle auf die Fernbedienung wird über IAM-Berechtigungen sichergestellt und kann gesteuert werden unter:
S3-Remotes werden durch das Präfix s3://
identifiziert und geben mindestens den Namen des Buckets an. Sie können auch ein Schlüsselpräfix wie in s3://my-git-bucket/my-repo
und ein Profil s3://my-profile@my-git-bucket/myrepo
angeben.
mkdir my-repo
cd my-repo
git init
git remote add origin s3://my-git-bucket/my-repo
Anschließend können Sie eine Datei hinzufügen, festschreiben und die Änderungen auf die Fernbedienung übertragen:
echo " Hello " > hello.txt
git add -A
git commit -a -m " hello "
git push --set-upstream origin main
Der Remote-HEAD ist so eingestellt, dass er den Zweig verfolgt, der zuerst an das Remote-Repository gepusht wurde. Um den Remote-HEAD-Zweig zu ändern, löschen Sie das HEAD-Objekt s3://
und führen Sie dann git-remote-s3 doctor s3://
aus.
Um das Repo in einen anderen Ordner zu klonen, verwenden Sie einfach die normale Git-Syntax und verwenden Sie den s3-URI als Remote:
git clone s3://my-git-bucket/my-repo my-repo-clone
Das Erstellen und Verschieben von Zweigen funktioniert wie gewohnt:
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
Alle Git-Operationen, die nicht auf die Kommunikation mit dem Server angewiesen sind, sollten wie gewohnt funktionieren (z. B. git merge
).
Um LFS verwenden zu können, müssen Sie zuerst git-lfs installieren. Informationen dazu, wie Sie dies auf Ihrem System durchführen, finden Sie in der offiziellen Dokumentation.
Als nächstes müssen Sie die S3-Integration aktivieren, indem Sie den folgenden Befehl im Repo-Ordner ausführen:
lfs-s3-py install
Das ist eine Abkürzung für:
git config --add lfs.customtransfer.lfs-s3-py.path lfs-s3-py
git config --add lfs.standalonetransferagent lfs-s3-py
Nehmen wir an, wir möchten eine TIFF-Datei in LFS speichern.
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
Ein Amazon S3-URI für einen gültigen Bucket und ein beliebiges Präfix, das nicht die richtige Struktur darunter enthält, gelten als gültig.
git ls-remote
gibt eine leere Liste zurück und git clone
klont ein leeres Repository, für das der S3-URI als Remote-Ursprung festgelegt ist.
% 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)
Tipp : Dieses Verhalten kann verwendet werden, um schnell ein neues Git-Repo zu erstellen.
Aufgrund der verteilten Natur von git
kann es Fälle (wenn auch selten) geben, in denen zwei oder mehr git push
gleichzeitig von verschiedenen Benutzern mit ihren eigenen Änderungen am gleichen Zweig ausgeführt werden.
Der Git-Befehl führt den Push in 2 Schritten aus:
git-remote-s3
aufgerufen, der das Bundle in den S3-Bucket im Pfad refs/heads/
schreibt Falls zwei (oder mehr) git push
-Befehle gleichzeitig von verschiedenen Clients ausgeführt werden, wird bei Schritt 1 die gleiche gültige Referenz abgerufen, daher fahren beide Clients mit Schritt 2 fort, was dazu führt, dass mehrere Bundles in S3 gespeichert werden.
Der Zweig hat jetzt mehrere Head-Referenzen und jeder nachfolgende git push
schlägt mit der Fehlermeldung fehl:
error: dst refspec refs/heads/> matches more than one
error: failed to push some refs to 's3:///'
Um dieses Problem zu beheben, führen Sie den Befehl git-remote-s3 doctor
aus. Standardmäßig wird für jedes Bundle, das nicht beibehalten werden soll, ein neuer Zweig erstellt. Der Benutzer kann den Zweig dann lokal auschecken und mit dem ursprünglichen Zweig zusammenführen. Wenn Sie stattdessen das Bundle entfernen möchten, geben Sie --delete-bundle
an.
Beim Klonen eines Repos mit der S3-Remote für LFS kann git-lfs
nicht wissen, wie die Dateien abgerufen werden, da wir die Konfiguration noch hinzufügen müssen.
Es sind zwei zusätzliche Schritte erforderlich.
% 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
...
Zur Behebung:
cd lfs-repo-clone
lfs-s3-py install
git reset --hard main
Um entfernte Zweige zu entfernen, die nicht mehr verwendet werden, können Sie den Befehl git-s3 delete-branch
verwenden. Dieser Befehl löscht die Bundle-Objekte aus Amazon S3 unter dem Verzweigungspfad.
Um einen Zweig zu schützen bzw. den Schutz aufzuheben, führen Sie git s3 protect
bzw. git s3 unprotect
aus.
Bundles werden im S3-Bucket als
gespeichert.
Beim Auflisten von Remote-Referenzen (z. B. explizit über git ls-remote
) listen wir alle Schlüssel auf, die unter der angegebenen vorhanden sind.
Beim Pushen einer neuen Referenz (z. B. eines Commits) erhalten wir den SHA der Referenz, bündeln die Referenz über git bundle create
und speichern sie gemäß dem obigen Schema in S3.
Wenn der Push erfolgreich ist, entfernt der Code das vorherige Bundle, das der Referenz zugeordnet ist.
Wenn zwei Benutzer gleichzeitig einen Commit basierend auf demselben aktuellen Zweigkopf an die Remote-Seite senden, werden beide Bundles in das Repo geschrieben und das aktuelle Bundle entfernt. Es gehen keine Daten verloren, aber es ist kein weiterer Push möglich, bis alle Bundles bis auf eines entfernt wurden. Hierfür können Sie den Befehl git s3 doctor
verwenden.
Die LFS-Integration speichert die Datei in dem durch den Remote-URI definierten Bucket unter einem Schlüssel
, wobei oid die eindeutige Kennung ist, die git-lfs der Datei zugewiesen hat.
Wenn bereits ein Objekt mit demselben Schlüssel vorhanden ist, lädt git-lfs-s3 es nicht erneut hoch.
Verwenden Sie das Flag --verbose
, um einige Debug-Informationen auszudrucken, wenn Sie Git-Operationen ausführen. Protokolle werden in stderr abgelegt.
Für LFS-Vorgänge können Sie die Debug-Protokollierung über git-lfs-s3 enable-debug
bzw. git-lfs-s3 disable-debug
aktivieren und deaktivieren. Protokolle werden im Repository unter .git/lfs/tmp/git-lfs-s3.log
abgelegt.
Die Git-S3-Integration wurde von der Arbeit von Bryan Gahagan an git-remote-s3 inspiriert.
Die LFS-Implementierung profitierte von lfs-s3 von @nicolas-graves. Wenn Sie den Transport git-remote-s3 nicht benötigen, sollten Sie dieses Projekt verwenden.