Die Frage steht immer noch im Raum, wie sieht der perfekte Git-Workflow aus?
Eine genaue Beschreibung zum Git-Workflow, der meiner Ansicht nach am besten ist findet man hier bei nvie.
Ich gehe hier nicht näher auf den Workflow an sich ein, weil dieser im Artikel schon sehr ausführlich und verständlich beschrieben wird.
Vielmehr möchte ich in diesem Artikel eine einfache Möglichkeit beschreiben, den Workflow zu verwenden und zwar über GIT-FLOW.
Im Folgenden versuche ich zu beschreiben, wie man am einfachsten mit git-flow arbeitet.
Installation
Die Installation von git-flow ist hier beschrieben. Im Prinzip handelt es sich hier nur um eine Menge von Skripten, die in einem Git-Repo ausgeliefert werden.
Schaut man sich das Verzeichnis nach der Installation an, sieht das ungefähr so aus:
.
├── AUTHORS
├── bump-version
├── Changes.mdown
├── contrib
│ ├── gitflow-installer.sh
│ └── msysgit-install.cmd
├── git-flow
├── gitflow-common
├── git-flow-feature
├── git-flow-hotfix
├── git-flow-init
├── git-flow-release
├── gitflow-shFlags -> shFlags/src/shflags
├── git-flow-support
├── git-flow-version
├── LICENSE
├── Makefile
├── README.mdown
└── shFlags
├── bin
│ └── gen_test_results.sh
├── doc
│ ├── CHANGES-1.0.txt
│ ├── coding_standards.txt
│ ├── contributors.txt
│ ├── LGPL-2.1
│ ├── LICENSE.shunit2
│ ├── RELEASE_NOTES-1.0.0.txt
│ ├── RELEASE_NOTES-1.0.1.txt
│ ├── RELEASE_NOTES-1.0.2.txt
│ ├── RELEASE_NOTES-1.0.3.txt
│ ├── rst2html.css
│ └── TODO.txt
├── examples
│ ├── debug_output.sh
│ ├── hello_world.sh
│ └── write_date.sh
├── lib
│ ├── shunit2
│ └── versions
├── README.html
├── README.txt
└── src
├── shflags
├── shflags_test_defines.sh
├── shflags_test_helpers
├── shflags_test_parsing.sh
├── shflags_test_private.sh
├── shflags_test_public.sh
└── shflags_test.sh
Initialisierung von git-flow
Zunächst mal legen wir uns ein leeres Git-Repository an.
git init
Initialized empty Git repository in /home/madi/development/git/.git/
Das Repository muss für git-flow enabled werden:
git flow init
Die erste Frage die git-flow stellt ist, welcher Branch für Produktions-Releases verwendet werden soll.
Branch name for production releases: [master]
Wir definieren hierfür einfach mal master-release.
Die nächste Frage die gestellt wird ist, welches ist der Branch für zukünftige Entwicklungen?
Branch name for "next release" development: [develop]
Wir nennen den Branch einfach mal next.
Dann möchte git-flow wissen, mit welchem Prefix Feature-Branches beginnen sollen:
How to name your supporting branch prefixes?
Feature branches? [feature/]
Das passt soweit.
git-flow möchte wissen, welches Prefix Release-Branches haben sollen:
Release branches? [release/]
Auch das passt.
Jetzt möchte git-flow wissen, welches Prefix Bugfix-Branches erhalten sollen?
Hotfix branches? [hotfix/]
Auch das passt soweit.
Damit ist git-flow vollständig initialisiert (alle Restlichen Fragen sind für uns momentan uninteressant und können einfach bestätigt werden).
git-flow hat im leeren Repository automatisch die Branches master-release (den Produktions-Branch und den next-Branch erzeugt).
git branch -a
master-release
* next
Verwendung von Git-Flow
Man kann sich alle Feature Branches mit git flow feature ausgeben lassen.
git flow feature
No feature branches exist.
You can start a new feature branch:
git flow feature start <name> [<base>]
Aktuell sind noch keine Features vorhanden, nehmen wir an, wir möchten gerne das Feature „Validierung von Kundendaten“ entwickeln.
git flow feature start "validate-customerdata"
git-flow ist so freundlich, und beschreibt genau, was jetzt passiert ist.
Summary of actions:
- A new branch 'feature/validate-customerdata' was created, based on 'next'
- You are now on branch 'feature/validate-customerdata'
Now, start committing on your feature. When done, use:
git flow feature finish validate-customerdata
Wir machen einen Commit auf dem aktuellen Branch
git diff HEAD~1
diff --git a/validate-customerdata.txt b/validate-customerdata.txt
new file mode 100644
index 0000000..d2eef98
--- /dev/null
+++ b/validate-customerdata.txt
@@ -0,0 +1 @@
+this feature validates customerdata
Genau wie von git-flow vorgeschlagen, ist damit das Feature beendet und wir machen folgendes:
git flow feature finish validate-customerdata
Switched to branch 'next'
Updating 95a7f6a..2c1d9a4
Fast-forward
validate-customerdata.txt | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 validate-customerdata.txt
Deleted branch feature/validate-customerdata (was 2c1d9a4).
Summary of actions:
- The feature branch 'feature/validate-customerdata' was merged into 'next'
- Feature branch 'feature/validate-customerdata' has been removed
- You are now on branch 'next'
Ok, was macht git-flow, es reintegriert ein fertiges Feature automatisch in den next-Branch, löscht den Feature Branch und das alles vollautomatisch.
Wir versuchen jetzt nochmal dasselbe aber ohne Fast-Forward-Merge. Damit simulieren wir quasi, dass im Remote-Repository ein anderer Entwickler bereits ein wenig vorgearbeitet hat.
Ok, nehmen wir an, wir möchten gerne an einem Feature Performance-Improvement arbeiten.
git flow feature start "performance-improvement"
git-flow erzeugt erneut automatisch einen neuen Feature-Branch:
git branch
* feature/performance-improvement
master-release
next
Hier ein kurzes Transkript der Performance-Verbesserung:
git commit -m "better performance"
[feature/performance-improvement 1a42f54] better performance
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 performance.txt
git (feature/performance-improvement)]$git checkout next
Switched to branch 'next'
git (next)]$vim new-development.txt
git (next)]$git add new-development.txt
git (next)]$git commit -m "new development"
[next fe76679] new development
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 new-development.txt
Wir haben die Änderungen so gemacht, dass es beim Zurückführen des Feature-Branches einen Merge-Konflikt gibt:
CONFLICT (content): Merge conflict in performance.txt
Automatic merge failed; fix conflicts and then commit the result.
There were merge conflicts. To resolve the merge conflict manually, use:
git mergetool
git commit
You can then complete the finish by running it again:
git flow feature finish performance-improvement
Ok, nehmen wir an, wir möchten ein Release machen, nichts einfacher als das.
git flow release
No release branches exist.
You can start a new release branch:
git flow release start <name> [<base>]
Selbes Spiel wie zuvor, zunächst nutzen wir git-flow um einen Release-Branch anzulegen:
git flow release start 1.o
Switched to a new branch 'release/1.o'
Summary of actions:
- A new branch 'release/1.o' was created, based on 'next'
- You are now on branch 'release/1.o'
Follow-up actions:
- Bump the version number now!
- Start committing last-minute fixes in preparing your release
- When done, run:
git flow release finish '1.o'
Ein Release-Branch wird quasi zu dem Zeitpunkt gezogen, an dem ein Release vorbereitet wird. Der Release-Branch wird gezogen und ab diesem Zeitpunkt werden keine neuen Features mehr in den Release-Branch mit aufgenommen. Neue Features werden nur noch auf dem next-Branch entwickelt. (Kann alles in der Beschreibung des Git-Flow nachgelesen werden).
git flow release finish 1.o
Switched to branch 'master-release'
Merge made by recursive.
hotfix.txt | 2 ++
new-development.txt | 1 +
performance.txt | 4 ++++
validate-customerdata.txt | 1 +
4 files changed, 8 insertions(+), 0 deletions(-)
create mode 100644 hotfix.txt
create mode 100644 new-development.txt
create mode 100644 performance.txt
create mode 100644 validate-customerdata.txt
Switched to branch 'next'
Merge made by recursive.
hotfix.txt | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 hotfix.txt
Deleted branch release/1.o (was 9fbb1ad).
Summary of actions:
- Latest objects have been fetched from 'origin'
- Release branch has been merged into 'master-release'
- The release was tagged '1.o'
- Release branch has been back-merged into 'next'
- Release branch 'release/1.o' has been deleted
Ok, was macht git-flow, wenn wir ein Release machen?
git-flow merged alles von master-release in den release-branch, und führt dann alles auf den master-release branch zurück.
git flow setzt außerdem automatisch einen Tag und merged den Release-Branch letztendlich automatisch in den next-Branch.
Cool, oder?
Ok, das kratzt mehr oder weniger an der Oberfläche, anschließend noch einige Links zum Thema:
Git Flow Command Line Argumente
Git Branching Model auf NVIE
Git Best Practices
War dieser Blogeintrag für Sie interessant? Evtl. kann ich noch mehr für Sie tun.
Trainings & Know-How aus der Praxis zu
- Apache Wicket 1.4.x, 1.5.x, 1.6.x
- GIT – Best Practices, Einsatz, Methoden
- Spring
- Java
- Scrum & Kanban
- Agiles Arbeiten
|
Consulting & Softwareentwicklung
- Requirements Engineering
- Qualitätssicherung
- Software-Entwicklung
- Architektur
- Scrum & Kanban
|