Leider bekommt man viel zu selten die Möglichkeit mit einem Projekt „auf der grünen Wiese“ zu beginnen. Statt dessen gibt es meistens ein System, dass es zu verbessern und zu erweitern gilt. Wenn man ganz viel Glück hat, wird der vorhandene Code bereits mit git verwaltet. Um nicht auf Peer Review zu verzichten muss der Code natürlich in Gerrit importiert werden. Doch wie bekommt man das existierende git-Repository mit seiner Versionshistorie in Gerrit?
Vorneweg: Wem Gerrit kein Begriff ist kann meinen Artikel Gerrit – Review vor dem Commit lesen, um zu verstehen wovon dieser Artikel handelt.
TL;DR;
- Code lokal auschecken git clone <oldrepo>
- Neues, leeres Projekt in Gerrit anlegen
- Zusätzliche Rechte direkt auf die Reference refs/heads/master vergeben:
- Create Reference
- Forge Author Identity
- Forge Committer Identity
- Push
- Push Merge Commits
- Push Annoteded Tag
- Lokal das Gerrit-Repository als neues remote hinzufügen git remote add gerrit ssh://user@gerritserver/projekt
- Code direkt in den master pushen git push gerrit HEAD:refs/heads/master
- Rechte wieder entfernen
- Fertig
Nochmal langsam
Ich setze voraus, dass die Grundlagen im Umgang mit git bekannt sind und gehe darauf an dieser Stelle nicht ein. Um zu verstehen, was ich hier tue und warum spezielle Rechte zu vergeben sind, muss ich allerdings kurz auf die interne Struktur von Gerrit eingehen. Kurz; versprochen!
Gerrit hat zusätzlich zu der in git üblichen Reference-Struktur refs/heads/* zwei weitere zur Verwaltung von Drafts und Changes: refs/drafts/* und refs/publish/*. Normalerweise dürfen Entwickler nur in diese beiden Strukturen pushen. Alles was in Drafts (z.B. refs/drafts/master) gepusht wird, ist privat und gilt als unfertig. Alles was in refs/publish/* gepusht wird, ist bereit zum Review. Mit Publish wandert der Commit von refs/drafts/* nach refs/publish/* und mit einem Submit nach refs/heads/*. Das übernimmt jeweils Gerrit. Es ist für einen Entwickler normalerweise unnötig direkt in refs/heads/* zu pushen, weil man damit das Review umgeht.
Der importierende Nutzer braucht also eine Reihe von Rechten, die man normalerweise nicht hat.
- Create Reference erlaubt es, neue References für branches zu erzeugen. Nur so können Merge Commits übernommen werden.
- Forge Author Identity und Forge Committer Identity ermöglichen es die Änderungen von Nutzern, die es in Gerrit nicht gibt, zu übernehmen.
- Push erlaubt es, normale Commits zu pushen.
- Push Merge Commits erlaubt es, Merge Commits zu pushen.
- Push Annoteded Tag erlaubt es, Tags zu pushen.
Damit ist es jetzt möglich die komplette Historie mit allen tags, merges usw. zu erhalten.
Zuerst muss also ein neues, leeres Projekt (ohne initial commit!) in Gerrit angelegt und neben den normalen Rechten mit den Sonderrechten für den Importeur versehen werden. Im bestehenden lokalen git-Repository fügt man das neue Repository als zweites remote hinzu und pusht den aktuellen Stand direkt nach refs/heads/master. Jetzt können die anderen Entwickler das Projekt ganz normal clonen und wie gewohnt arbeiten.
Abschließend sollte man die erweiterten Rechte wieder entfernen, da sie eine unnötige Bresche in Gerrit schlagen.