Git-Flow und das JGit-Flow Plugin für Maven

In diesem Artikel wird Git-Flow erläutert, wobei dabei allgemein das Konzept dahinter aufgegriffen wird. Der eigentliche Umgang mit den Git-Flow-Befehlen wird mit Hilfe des JGit-Flow Plugin für Maven gezeigt. Zusätzlich werden dennoch auch die Git- und Git-Flow-Befehle, die sich dahinter verstecken gezeigt.

Das JGit-Flow Maven Plugin

Das JGit-Flow Plugin für Maven bildet die Git-Flow Befehle als Maven Goals ab, sodass es mit diesem Plugin möglich ist die später beschriebenen Branches anzulegen ohne Git-Flow installiert zu haben. So kann dieses Plugin beispielsweise in eine Parent-POM eingebettet werden, sodass jedes abgeleitete Projekt automatisch die JGit-Flow-Befehle nutzen kann. So kann darauf verzichtet werden auf jedem Entwickler-Rechner Git-Flow zu installieren.

Einbinden des JGit-Flow Plugins

Zum Einbinden wird folgendes Plugin in die POM des Maven-Projektes hinzugefügt:

<build>
   <plugins>
      <plugin>
         <groupId>external.atlassian.jgitflow</groupId>
         <artifactId>jgitflow-maven-plugin</artifactId>
         <version>1.0-m5.1</version>
         <configuration>
            <username>username</username>
            <password>password</password>
            <pushFeatures>true</pushFeatures>
            <pushRelease>true</pushRelease>
            <pushHotfixes>true</pushHotfixes>
            <flowInitContext>
               <masterBranchName>master</masterBranchName>
               <developBranchName>develop</developBranchName>
               <featureBranchPrefix>feature-</featureBranchPrefix>
               <releaseBranchPrefix>release-</releaseBranchPrefix>
               <hotfixBranchPrefix>hotfix-</hotfixBranchPrefix>
               <versionTagPrefix>${project.artifactId}-</versionTagPrefix>
            </flowInitContext>
         </configuration>
      </plugin>
   </plugins>
</build>

In der Konfiguration können z.B. der Username und das Passwort zum Git Repository angegeben werden, sodass bei Erstellung eines neuen feature-, release-, oder hotfix-Branches die Branches direkt ins Repository gepusht werden ohne das die Credentials jedes Mal manuell angegeben werden müssen. Im flowInitContext werden Namen und Prefixes von bestimmten Branches definiert.

Git-Flow Grundlagen

Git-Flow beschreibt Abläufe zum Umgang mit Git und dem dort einfach zu nutzendem Branching. In Git-Flow sind fünf verschiedene Branch-Typen definiert:

  • master
  • develop
  • feature
  • release
  • hotfix

Im Folgenden werden die einzelnen Branches beschrieben und erklärt, welche Befehle zum Erstellen und wieder zusammenführen der einzelnen Branches verwendet werden. Zudem ist zu sehen welche einzelnen Git-Befehle sich aus den Git-Flow-/JGit-Flow-Befehlen ableiten lassen.

Die Hauptbranches  master und develop

Die Branches master und develop sind die einzigen Branches im Git-Flow, die beständig sind und nie gelöscht werden. Hierbei enthält der master meist die aktuell releaste Version oder eine für den Release bereite Version. Der develop-Branch enthält die aktuellen Änderungen aus der Entwicklung für das nächste Release z.B. ein neues Feature.

Die unterstützenden Branches

Der feature-Branch

Wie der Name schon sagt, werden feature-Branches genutzt, um neue Features für folgende Releases zu entwickeln. Typischerweise bestehen diese Branches nur in den Repositories der Entwickler und werden nicht in das Origin Repo gepusht. Dies bedeutet natürlich nicht, dass Entwickler nur alleine an einem Feature arbeiten sollen. Zum Zweck des Austausches zwischen Entwicklern die zusammen in kleineren Gruppen arbeiten, werden weitere Git remotes zwischen den zusammenarbeitenden Personen eingerichtet. Falls doch in einem Repository alle feature-Branches enthalten sind, muss darauf geachtet werden, dass immer auf dem passenden Branch gearbeitet wird und nicht versehentlich Arbeiten von anderen verändert werden. GitLab zum Beispiel ermöglicht die Berechtigungssteuerung für einzelne Branches, was bei großen Projekten evtl. Sinn macht, da das versehentliche arbeiten auf einem falschen Branch nicht erst passieren kann.

Der feature-Branch entsteht aus dem develop-Branch und wird nach der Fertigstellung des Features wieder in diesen gemerged. Als Namenskonvention sollte dieser Branch einen Namen wie feature- oder feature/ bekommen. Auf keinen Fall darf der Namen master, develop, release-* (release/) oder hotfix- (hotfix/*) heißen, da diese Namen für andere Branches vorgesehen sind.

Mit Hilfe der folgenden Befehle von Git-Flow oder JGit-Flow kann ein neuer Feature-Branch erstellt werden:

Git-Flow:

$ git flow feature start featurename

JGit-Flow Plugin:

mvn -B jgitflow:feature-start -DfeatureName=featurename -DenableFeatureVersions=true

Dahinter verbirgt sich in diesem Fall:

$ git checkout -b featurename develop

Dadurch wird lediglich ein Branch mit dem Namen „myfeature“ aus dem Branch „develop erzeugt. Anhand von feature-start sind noch keine Vorteile von Git-Flow zu erkennen, da der eigentliche Befehl nur aus einer Zeile besteht. Das JGit-Flow Plugin hingegen sorgt durch die Option -DenableFeatureVersions=true zusätzlich dafür, dass die Version in der POM für den feature-Branch angepasst wird. Heißt das Feature „newfeature“ wird die Version z.B. in „1.0.0-newfeature-SNAPSHOT“ geändert. Leider wird diese Versionsnummer bei dem Beenden des Features mit in die POM des develop-Branches übernommen. Wird von diesem develop-Branch erneut ein feature-Branch abgeleitet, so wird der Featurename wieder an die Version konkateniert, sodass die Version nach vielen entwickelten Features sehr lang und unübersichtlich wird.
-DfeatureName=featurename legt den Namen des Features fest. Normalerweise muss der Name bei der Durchführung des Goals bestätigt werden, dies kann verhindert werden, wenn wie oben zu sehen mit mvn -B der Batchmode aktiviert wird. So kann der Name ohne weitere Interaktion festgelegt werden.

Wenn ein Feature-Branch mit

Git-Flow:

$ git flow feature finish featurename

oder

JGit-Flow Plugin:

mvn jgitflow:feature-finish -DfeatureName=featurename

beendet wird, stecken mehrere Befehle dahinter:

$ git checkout develop
$ git merge --no-ff featurename
$ git branch -d featurename
$ git push origin develop

Zum Beenden eines Features muss zuerst in den develop-branch gewechselt werden. Danach wird das entwickelte Feature in den Branch gemerged und der feature-branch gelöscht. Zuletzt wird der develop-Branch ins Git-Repository gepusht. An diesem Beispiel ist zu sehen wie Git-Flow/JGit-Flow den Aufwand zum Beenden eines Features minimiert. Statt vier Befehlen muss lediglich einer ausgeführt werden.

Der release-Branch

Der release-Branch wird aus dem develop-Branch erzeugt, sobald dieser einen releasebereiten Status erreicht hat. Sobald ein release-Branch erzeugt wurde, fließen alle neuen Features oder Änderungen an dem develop-Branch in das darauffolgende Release ein. In dem release-Branch sind lediglich Bugfixes zulässig. Außerdem ist dies der Branch der am Ausgiebigsten getestet werden sollte, da dieser in den master gemerged wird und sich dort nur fertige, zum Release geeignete Versionen befinden sollten. Beim Start des release-Branches wird die Releasenummer festgelegt, die nach intern definierten Regeln gesetzt wird. Benannt wird diese Art von Branches mit dem Prefix release- oder release/.

Mit Hilfe der folgenden Befehle von Git-Flow oder JGit-Flow kann ein neuer Feature-Branch erstellt werden:

Git-Flow:

git flow release start 1.0.0

JGit-Flow Plugin:

mvn -B jgitflow:release-start -DreleaseVersion=1.0.0

Hinter diesen Befehlen stecken die Befehle:

$ git checkout -b release-1.0.0 develop
$ ./version-anpassen.sh 1.0.0
$ git commit -a -m "Versionsnummer auf 1.0.0 geändert"

Zuerst wird der release-Branch aus dem aktuellen develop-Branch erstellt. Die nächste Zeile besteht aus einem fiktiven Skript, das die Versionsnummer für die Releaseversion setzt. Nachdem die Änderung commited wurde, kann mit dem release-Branch gearbeitet werden.

Das Beenden des release-Branches sieht dann folgendermaßen aus:

Git-Flow:

git flow release finish 1.0.0

JGit-Flow Plugin:

mvn jgitflow:release-finish

Dahinter verbergen sich die Befehle:

$ git checkout master
$ git merge --no-ff release-1.2
$ git tag -a 1.2

Als erstes wird der release-Branch in den master gemerged. Danach bekommt die Version noch ein Tag.

$ git checkout develop
$ git merge --no-ff release-1.2

Zusätzlich muss der release-Branch in den develop-Branch überführt werden, um ggf. behobene Fehler auch in diesem zu beseitigen.

$ git branch -d release-1.2

Zum Schluss wird der nicht mehr benötigte release-Branch gelöscht.

Der hotfix-Branch

Der hotfix-Branch ist der einzige Branch der seinen Ursprung im master-Branch hat. Benannt wird diese Art von Branch mit dem Prefix hotfix- oder hotfix/. Dieser Branchtyp ähnelt dem release-Branch. Er dient zur Vorbereitung eines Produktions-Release, aber sind im Gegensatz zu release-Branches unplanmäßig. Genutzt wird dieser Typ, wenn in einer Live-Version kritische Fehler schnellstmöglich behoben werden müssen, der develop-Branch aber noch zu instabil ist, um produktiv zu gehen.

Git-Flow:

git flow hotfix start 1.0.1

JGit-Flow Plugin:

mvn -B jgitflow:hotfix-start -DreleaseVersion=1.0.1

Dahinter verbergen sich die Befehle:

$ git checkout -b hotfix-1.0.1 master
$./version-anpassen.sh 1.0.1
$ git commit -a -m "Versionsnummer auf 1.0.1 geändert"

Es ist zu erkennen, dass die Befehle, die genutzt werden identisch mit denen zum Erstellen eines release-Branches sind.

Beenden des release-Branches:

Git-Flow:

git flow hotfix finish 1.0.1

JGit-Flow Plugin:

mvn jgitflow:hotfix-finish

Dahinter verbergen sich die Befehle:

$ git checkout master
$ git merge --no-ff release-1.0.1
$ git tag -a 1.0.1
$ git checkout develop
$ git merge --no-ff release-1.0.1

Auch das Beenden eines hotfix-Branches gleicht dem eines release-Branches. Zuerst wird der Hotfix in den master gemerged und mit einem Tag versehen. Danach muss der hotfix-Branch wieder zusätzlich in den develop-Branch gemerged werden.

Fazit

Git-Flow/JGit-Flow vereinfachen das Arbeiten durch definierte Abläufe und einfachen Befehlen, sodass weniger Fehler beim Erstellen von neuen Branches auftreten können. Auch wenn nicht direkt Git-Flow mit deinen Befehlen genutzt wird sondern nur die Arbeitsweise mit der Brancherstellung übernommen wird, wird ein guter Leitfaden zum Arbeiten mit Git geliefert.

In Maven-Projekten ist der Einsatz des JGit-Flow Plugin praktisch, da nicht auf jedem Entwickler-Rechner Git-Flow installiert werden muss. Zudem wurde Git-Flow für Linux konzipiert und ist beispielsweise unter Windows ohne Cygwin nicht nutzbar. Wird stattdessen das JGit-Flow Plugin genutzt, so hat jeder Entwickler nach dem Klonen des Projektes die passende Git-Flow Konfiguration. Zudem werden die Versionen der einzelnen Branches automatisch angepasst, wenn dies so konfiguriert ist.

Advertisements

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: