Michael Contento

Softwareentwickler | Azure-Cloud-Ninja | Imker | Dad

Gestückeltes git-push nach Azure DevOps

2022-10-20 2 Min. lesen Development Cloud

Die Tage hatte ich ein lustiges kleines Problem bei dem Versuch ein großes Git Repository nach Azure DevOps zu importieren:

Sehr große Pushs verwenden viele Ressourcen, blockieren oder verlangsamen andere Teile des Diensts. Solche Pushs werden häufig nicht zu normalen Softwareentwicklungsaktivitäten zugeordnet. Jemand hat möglicherweise versehentlich in Buildausgaben oder ein VM-Image eingecheckt, z. B. Aus diesen Gründen und mehr sind Pushs auf 5 GB zu einem Zeitpunkt beschränkt.

Azure DevOps Dokumentation (hervorhebung von mir)

Also .. uhm .. naja, das ist nun doof, da mein Repository halt größer ist als 5GB 😢

❌ Lösung: Web Import

Welche Lösung schlägt Microsoft hier vor? Man soll das Git Repository einfach über ein web import laufen lassen!

Leider war das keine Option, da das Quellsystem (auf dem das Git Repository primär gehosted ist) für Azure DevOps nicht direkt erreichbar war (Firewall und so) 😢 😢

✅ Lösung: Gestückeltes git push

Nun, wenn man die Dokumentation aufmerksam liest, dann merkt man das ein einzelnes git push nicht größer sein darf als 5GB. Das komplette Repository kann aber bis auf 250GB anwachsen.

Ha! Hier können wir also ansetzen! Wir schieben unser Repository einfach in kleinen Stücken nach Azure DevOps, bleiben immer unter den 5GB und nach einigen Runden git push haben wir alles drüben 😎

Mit einem bisschen bash klappt das wie folgt:

 1$ # Ensure we're starting from the master branch
 2$ git checkout master
 3
 4$ # First we need to count the total amount of commits
 5$ TOTAL_COMMITS=$(git log --pretty=oneline | wc -l)
 6
 7$ # How many commits should be in a single chunk?
 8$ COMMITS_PER_CHUNK=50
 9
10$ # Push our commits in small chunks
11$ for CURSOR in $(seq $TOTAL_COMMITS -$COMMITS_PER_CHUNK 0); do \
12    git push origin master~$CURSOR:master;  \
13  done
14
15$ # And finally push the missing rest (tags, etc.)
16$ git push --mirror origin

In meinem Fall war es ausreichend das ganze einmal auf dem master Branch laufen zu lassen, da sich das finale git push --mirror um den ganzen fehlenden Rest (tags und andere Branches) gekümmert hat.

Das letzte git push --mirror kann auch in die 5GB Grenze laufen, wenn es viele / große Commits außerhalb von dem master branch gibt! In dem Fall wiederholt man die Schritte in einem anderen Branch bis git push --mirror dann ebenfalls durchläuft.