11.05.2021, von Christian Glahn
Git ist ein extrem leistungsfähiges Werkzeug für die Versionsverwaltung von komplexen Projekten. Es ist kaum noch aus dem Projektmanagement von IT- und Data-Science-Projekten wegzudenken. Manchmal müssen wir unsere Projekte aber reorganisieren und auf einen anderen Server umziehen. Das kann passieren, weil wir ein Projekt von GitHub.com auf unsere GitHub Enterprise Instanz aus Datenschutzgründen verschieben müssen oder ein Projekt auf GitLab veröffentlichen möchten, damit wir deren Auto-DevOps-Funktionen nutzen können. In solchen Fällen wollen wir die Versionsgeschichte und die Projektkonfigurationen behalten und unsere bisherige Arbeit nicht einfach löschen. In diesem Beitrag erkläre ich, wie ein Git-Repository leicht von einem Repository-Server auf einen anderen umgezogen wird.
Einleitung
Git ist ein freies, verteiltes Versionsmanagementsystem, das heute praktisch der Industriestandard für IT- und Data-Science-Projekte ist. Git wird von vielen bekannten Open-Source- und kommerziellen Projekten verwendet. Das Wort “Verteilt” in “verteiltes Versionsmanagement” bedeutet, dass es keine zentralen Server geben muss, auf dem alle Daten zusammenlaufen. Vielmehr hat jedes Teammitglied ein eigenes vollwertiges Original der Projektgeschichte (einen sog. Klon). Dadurch ist eine grösstmögliche Sicherheit und Flexibilität bei der Entwicklung von digitalen Lösungen sichergestellt. Das bedeutet auch, dass ein Projekt nicht an eine Plattform wie z.B. GitHub oder GitLab gebunden ist. Die Entscheidung wo und wie wir unseren Code und unsere Daten ablegen wollen, liegt also bei uns. Deshalb können wir uns auch entscheiden, Code auf mehreren Plattformen gleichzeitig abzulegen und so anbieterunabhängige Backups unserer Projekte zu erstellen.
Grundbegriffe
Ich gehe davon aus, dass schon erste Schritte mit Git gemacht wurden und auch die Authentifizierung an GitHub oder GitLab persistent konfiguriert ist, daher werde ich hier nicht auf Einzelheiten zum Projekt-Management eingehen. Für das Umziehen sind nur die folgenden Begriffe und Befehle wichtig.
- Git - ein freies, verteiltes Versionsmanagementsystem (engl. Version-control system (VCS))
- Repository - Ein Repository bildet die Code- bzw. Datenbasis eines Projekts zusammen mit der Geschichte aller Änderungen ab.
- Git-Server - Ein Server auf und von dem wir Git-Repositorien laden können. Sie bilden das Herzstück für die Teamzusammenarbeit.
- GitHub - Eine Plattform zum Verwalten und gemeinsames Betreiben von Git-Repositories.
- Klon (engl. clone) - eine vollständige und eigenständige Fassung des gleichen Git-Repositories.
- Remote - Die URL eines bekannten anderen Klons des gleichen Git-Repositories. Remotes können gemeinsame Repositories auf GitHub sein, die mehrere Teammitglieder zum Austausch ihrer Änderungen nutzen.
git fetch
- Befehl zum Downloaden der Änderungen aus anderen Git-Repositorien.git pull
- Befehl, um Änderung eines anderen Git-Repositories in den eigenen Klon des Git-Repositories zu holen.git push
- Befehl, um Änderungen des eigenen Git-Repositories an einen anderen Klon zu schieben.
Das Beispiel
Ich verwende hier das Projektrepository unseres Moodle Autopiloten. Ich werde dieses Repository auf unseren internen GitHub-Enterprise-Server verschieben und zusätzlich eine Kopie auf meinem privaten Git-Server anlegen.
Git-Remotes verwalten
Git funktioniert deshalb so flexibel, weil jeder Klon eines Repositories wie ein eigenständiges Orginal funktioniert. Damit wir zusammenarbeiten können, müssen wir die Klone eines Git-Repositories noch verbinden. Das geschieht in der Regel über die Herkunft eines Klons, dem sog. origin
. Diese Herkunft ist in unseren Git-Repositorien als remote
abgelegt. Das können wir mit git remote
und git remote get-url origin
abfragen.
Ein Git-Repository kann aber auch mehr als ein Remote-Repository haben, damit wir Verbindungen zu mehreren Git-Servern halten können. Damit wir die Verbindungen auseinanderhalten können, sind die Verbindungen benannt. Diese Namen können wir uns ausdenken. Weil wir unser Repository umziehen wollen, bennenn wir es mit neworigin
.
Wir erstellen eine neue Verbindung zu einem Git-Server (in unserem Fall der ZHAW GitHub Instanz) mit dem folgenden Kommando:
git remote add neworigin https://github.zhaw.ch/dxiai/moodle-autopilot.git
Das spannende an diesem Befehl ist, dass die das entfernte Repository noch nicht existieren muss. Wichtig ist nur, dass ich ein neues Repository in dem angegebenen Bereich (dxiai
) anlegen darf.
Weil es so schön ist, lege ich gleich noch ein Remote auf meinen privaten Git-Server an:
git remote add homeoffice https://git.0xff.li/phish108/moodle-autopilot.git
Das Ergebnis können wir wieder mit git remote
abfragen.
Mein Repository hat jetzt 3 Remotes.
Bevor ich weitermache, sichere ich mich noch ab, dass ich auch alle Änderungen vom originalen Server geholt habe. Das erreiche ich mit den folgenden Kommandos:
git fetch origin
git pull origin master
Ein Git-Repository auf einem Git-Server bereitstellen
Mit diesen beiden neuen Remotes sind wir schon fast fertig mit dem Umzug. Jetzt muss nur noch das lokale Repository auf den entfernten Git-Server geschoben werden. Ein einfaches git push
reicht hier nicht. Wir müssen zusätzlich noch die Option --all
anfügen, damit Git das gesamte Repository mit allen Code-Zweigen auf die Server schiebt und ich keine Daten verliere. Ausserdem muss ich das Ziel der Aktion angeben, damit Git weiss, wohin die Daten sollen.
Diesen Schritt wiederhole ich für alle neuen Remotes.
Achtung An dieser Stelle kann es vorkommen, dass immer wieder nach Passwörtern gefragt wird. Das ist ein Indiz dafür, dass Git nicht vollständig für die Remote konfiguriert wurde. Dabei gilt es zu beachten, dass Git via HTTPS oder SSH ein Repository von einem Remote-Server laden kann. Ich verwende in diesem Beispiele immer HTTPS und habe das Protokoll entsprechend für GitHub und GitLab konfiguriert. Falls SSH-Schlüssel für den Remote-Server konfiguriert wurden, dann muss auch SSH als Protokoll verwendet werden. Natürlich können auch beide Methoden konfiguriert werden, falls das gewünscht ist.
GitHub ist nicht (nur) Git!
Beim Umziehen von einem Projekt auf GitHub oder auf einen GitHub-Enterprise-Server merken wir, dass GitHub nicht das gleiche wie Git ist, denn wir können nicht einfach mit git push --all
ein Git-Repository zu GitHub schieben. Stattdessen erhalten wir einen Fehler.
Der Fehler wird dadurch verursacht, dass GitHub zwingend ein bestehendes Projekt auf dem Server benötigt, dass ein Repository aufnimmt. Bevor wir also ein Git-Repository zu GitHub oder zu einem GitHub-Enterprise-Server umziehen können, müssen wir ein (leeres) Projekt erstellen.
Mit der GitHub CLI geht das ganz einfach. Der Befehl folgt der folgenden Syntax.
gh repo create [org/]repository-name
Bevor ich also das Projekt moodle-autopilot
auf unser ZHAW-GitHub-Enterprise umziehen kann, muss ich das Repository wie folgt erstellen:
GH_HOST=github.zhaw.ch gh repo create dxiai/moodle-autopilot
Nicht alle haben die GitHub CLI installiert. Für diese Leute gibt es auch die Möglichkeit, ein Projekt ganz normal über die Web-Oberfläche zu erstellen. Dazu geht man auf die Seite mit den eigenen Repositories bzw. den Repositories der eigenen Organisation.
Dort wählt man “New”.
Daraufhin erscheint ein Formular für die Basisinformationen des Projekts. Hier müssen wir nur den Namen eingeben. Die Auswahlboxen im unteren Teil des Formulars müssen wir unbedingt leer lassen!
.
Diesen Schritt schliessen wir ab, indem wir auf Create repository
klicken.
Erst jetzt dürfen wir das lokale Repository mit git push --all neworigin
auf den Server schieben.
Umzug beenden und die alte Verbindung kappen
Nachdem mein Repository auf den neuen Server geschoben wurde, können wir die alte Verbindung kappen und die neue Verbindung als origin
für alle zukünfitgen Git-Operationen setzen.
Das erreiche ich mit den folgenden Kommandos:
git remote remove origin
git remote rename neworigin origin
Jetzt ist mein lokales Repository mit einem neuen Git-Server verbunden und alle Änderungen werden von jetzt ab auf dem internen Server landen. Ich kann ausserdem Sicherungen aus meinem Homeoffice auf meinem eigenen Server anlegen. Das ist sehr praktisch.
Ich habe das alte Git-Repository auf GitHub übrigens nicht gelöscht. D.h. meine alten Änderungen sind dort immer noch verfügbar. Jede neue Anpassung des Codes wird jedoch nicht mehr in dieses Repository einfliessen. Wenn ich mir ganz sicher wäre, könnte ich jetzt das alte Repository auf GitHub löschen.
Fazit
Git-Repositories auf einen anderen Server umzuziehen ist denkbar einfach. Die Funktionen von git remote
erfordern nur wenige Schritte. Git spielt dabei die Vorteile des verteilten Versionsmanagement voll aus, so dass bei einem solchen Umzug keine Information verloren geht. Die Lösung in diesem Beitrag bezieht sich ausschliesslich auf das eigentliche Git-Repository. Wenn andere Funktionen von GitHub oder GitLab für das Projektmanagement verwendet werden, dann müssen diese Elemente ebenfalls umgezogen werden. Das gilt insbesondere für Issues
und Pull-Requests
, die separat umgezogen werden müssen, weil es sich dabei um keine Information aus dem Git-Repository handelt.