Archiv der Kategorie: git

Git Tip of the Day – Spiel das Commit Game

Manchmal ist es ganz interessant zu sehen, wer wie viel comitted, wer also der „fleissigste“ ist (Sarkasmus Ende.).

Sehen kann man das ganz einfach mit folgendem Befehl:


git shortlog --numbered --summary

Ich habe das mal testweise im Wicket-Source-Repository gemacht, mit folgendem Ergebnis.


2932  Eelco Hillenius
2816  Igor Vaynberg
1867  Juegen Donnerstag
1780  Martin Tzvetanov Grigorov
1484  Johan Compagner
1321  Jonathan Locke
963  Matej Knopp
899  Martijn Dashorst
422  Alastair Maw
352  Peter Ertl
277  Jean-Baptiste Quenot
235  Frank Bille Jensen
218  Janne Hietamaki
205  Gerolf Seitz
98  martin-g
94  Sven Meier
91  Emond Papegaaij
76  Pedro Henrique Oliveira dos Santos
69  svenmeier
62  Gwyn Richard Evans
51  Jeremy Ryan Thomerson
42  Timo Heikki Rantalaiho
40  sourceforge-skipoles
16  Carl-Eric Menzel
14  Ate Douma
12  Maurice Marrink
8  Jan Blok
4  Jeremy Thomerson
2  Jesse Long
1  Thomas Götz
1  Pedro Santos
1  cvs2svn
1  Joe Schaefer
1  robert mcguinness
1  slowery
1  Michael Mosmann
1  Bertrand Guay-Paquet
1  Sven

Folien zu „Besser Gits nicht – Best Practices mit GIT“ sind jetzt auf Slideshare verfügbar

Die Folien zum Talk beim Herbstcampus 2012 in Nürnberg sind hier zu finden:


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

„Besser Gits nicht“ live auf dem Herbstcampus

Auf dem diesjährigen Herbstcampus erzähle ich live ein wenig aus meiner täglichen Arbeit mit GIT und zeige nützliche und praktische Beispiele – aus der Praxis für die Praxis. Das ganze basiert auf dem gleichnamigen Artikel, der dieses Jahr im Java-Magazin erschienen ist.

U.a. zeige ich:

  • Wie kann man Commits sauber strukturieren
  • Wie kann und sollte mit Branches gearbeitet werden
  • Wie kann man parallel mit Subversion und Git arbeiten
  • Wie wird mit Remote Repositories gearbeitet
  • Welche GUI Clients gibt es hierfür?
  • Git Flow

Ich habe schon mehrfach Vorträge zum Thema GIT gehalten, u.a. hier.


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

Git Flow – einfaches Arbeiten mit dem perfekten Git Workflow

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

Git Talk @ mobileX Ag in München

Ich habe heute einen Git-Talk bei der mobileX-AG in München gegeben.

Hat sehr viel Spaß gemacht, erstaunlich viel Interesse und Fragen zum Thema.

Vielen Dank für den netten Abend und den gut gefüllten Kühlschrank voller Bier:).


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

Besser Gits Nicht – Git Artikel im Java Magazin

Hallo,

wie bereits angedroht ist im aktuellen Java Magazin ein Artikel von mir erschienen, der auch hier hier gelesen werden kann.

Da ich leider heute krank im Bett liege habe ich die Zeit genutzt, diesen nochmal zu lesen. Ich finde, er ist sehr lesenswert.

Viel Spaß damit.


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

Git Artikel im nächsten Java Magazin

Hallo zusammen,
im nächsten Java Magazin wird ein Artikel von mir zum Thema GIT erscheinen mit dem Titel „Besser Gits nicht!“

Der Artikel ist inhaltlich relativ locker, aber ich hoffe lesenswert geschrieben.

Ich freue mich über Kommentare.


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

Git Format Patch mit einem einzigen File

Manchmal hat man das Problem, dass mehrere Commits auf einmal gepatched werden sollen, um diese beispielsweise per Email zu verschicken, das geht auch in einem einzigen File, und zwar so (in diesem Fall für die letzten 5 commits von HEAD aus):


git format-patch HEAD~5 --stdout > mypatchfile.patch

Das File kann man jetzt auf einem anderen branch einfach über


git apply mypatchfile.patch

wieder hinzufügen.


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

Gute GIT Referenz zum Einstieg

Hallo zusammen,

ich bin regelmässiger Hörer des Chariot Tech Casts, hier hab ich einen sehr guten Hinweis zu hören bekommen, und zwar existiert eine wirklich sehr gute GIT-Referenz unter GitRef, dies eignet sich gerade zum Einstieg sehr gut!

Wenn jemand weitere Links zum Thema GIT kennt, würde ich mich über Kommentare freuen.


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

Git Internals

Hi zusammen,

primär für mich zur Dokumentation und zum besseren Verständnis versuche ich in diesem Artikel ein wenig die GIT-Internals zu beleuchten. Ich werde den Artikel bei Bedarf nach und nach ergänzen, damit ich immer weiß, wo ich meine Referenz finden kann.

Bitte beachtet auch, dass sich der Artikel aktuell in einer sehr frühen Phase befindet, es können also durchaus noch einige Fehler und Unvollständigkeiten vorhanden sein.

Ein interessanter Aspekt, der mir bisher auch mehr oder weniger unbekannt war sind die das Blob-Format und die GIT-Packfiles.

Zunächst interessiert uns hier, wie GIT überhaupt die Objekte speichert (BLOB). Ich habe eine Weile gegoogelt, bis ich zu dem Ergebnis gekommen bin, dass es sich hier lediglich um auf eine bestimmte Artgezippte Files handelt.

GIT verwendet Pack-Files, um einerseits die Dateigrösse des Repositories zu minimieren und andererseits, um einen effizienten Zugriff auch auf ältere BLOBs zu ermöglichen. Zusätzlich bieten Pack files GIT die Möglichkeit, statt jeweils kompletter Objekte nur die jeweiligen Deltas zu speichern.

Stellt man sich vor, man hat eine Datei mit 1500 Zeilen und ändert nur eine Zeile würde GIT per Default ein zweites Blob Objekt anlegen und so die Daten redundant ablegen. Das Ganze würde also auf Dauer sehr groß und ineffizient werden.

Hierfür bietet GIT das Format der Packfiles, die Packfiles dienen quasi u.a. dazu, die Deltas des zweiten, um eine Zeile veränderten Objektes zu speichern. Git würde also wirklich nur die veränderte Zeile speichern und hierzu eine Referenz auf das erste File speichern.

Siehe hierzu noch Kommentar weiter unten.

Wo findet man nun diese Pack-Files? In einem frisch erzeugten Repository erstmal gar nicht. Git scannt periodisch das Repository und erzeugt die entsprechenden Pack-Files. Damit wir was haben womit wir arbeiten können kann man GIT auch zwingen ein bestehendes Repository zu packen mit


git gc

Interessant sind auch

git repack

und

git unpack-objects

Mit diesen Befehlen kann das Repository erneut packen und so auf eventuelle Änderungen reagieren. Man kann so auch die bereits gepackten Objekte wieder entpacken.

Dann schaut man direkt mal in


repo-path/.git/objects/packs

Hier sollte man jetzt mindestens 2 Files vorfinden, und zwar ein xxx.idx und ein xxx.pack. Das idx-File ist ein Index in das Packfile, das einen schnellen Zugriff ermöglicht. Das Packfile selbst beinhaltet die entsprechenden Inhalte.

Ein weiterhin interessante Info ist, dass diejenigen Objekte, die nun in dem Packfile gelandet sind physikalisch aus dem Objekt-Speicher des GIT-Repositories gelöscht worden sind, was man direkt sehen kann, wenn man in


repo-path/.git/objects

nachschaut.

Primär betrachte ich hier das Packfile Format selbst:

Zunächst befindet sich in einem Packfile das Wort „PACK“ (die ersten 4 Byte = 50 41 40 4B), dies dient lediglich dazu, den richtigen Anfang zu finden.

Die nächsten 4Byte sind die Versionsnummer des Packfiles (die wird in git ab 1.5.4 typischerweise 2 = 00 00 00 02 sein, siehe Referenz am Ende des Artikels für weitere Infos)

Die nächsten 4Byte geben die Anzahl der Einträge im Packfile an (in meinem Beispiel wäre das 64 = 00 00 00 3F)

Nachfolgend sind die einzelnen Objekte aufgelistet (jeweils HEADER + CONTENT) in einem speziellen Format. Jedes Byte im HEADER besteht tatsächlich aus 7 Bit (das erste Bit jedes Bytes gibt an, ob nachfolgend bereits der Content anfängt (=0), oder ob weitere Header-Informationen folgen (=1).

Das erste Byte in meinem Beispiel ist folgendes:


1 001 0111

Das erste Bit (1) gibt an, dass weitere HEADER-Informationen folgen.

Die folgenden 3 Bit (001) geben an, was der folgende Content für einen Typ hat (001 = Commit, siehe hierzu die exzellente Referenz weiter unten)

Die letzten 4Bit des ersten Byte und alle darauffolgenden bis zum Content (bis das erste Bit 0 ist) geben die Größe des Contents an (in entpackter Form).


1 001 0111 0001 0000

Schliessen wir die Kennungsbits aus, ergibt sich folgender Content:


001 0111 001 0000

Nehmen wir den Typ noch weg, ergibt sich folgender Inhalt:


0111 001 0000

Die Größe wird gelesen, in dem die 4 Bits des ersten Byte an das darauffolgende Byte angehängt werden:


001 0000 0111

Das bedeutet, das nachfolgende Commit-Objekt hat eine Größe von 263 Bytes, wenn es entpackt wird. Gepackt sind die Objekte im ZLIB-Algorithmus.

Interessant hierbei sind noch die beiden Typen


110 - Objekt Referenz

und


111 - Objekt Delta

Diese beiden Typen werden für die weiter oben bereits angesprochende Speicherung von Delta-Informationen verwendet.
Objekt-Delta ist der 20Byte-SHA1 Hashcode des Objektes, das referenziert wird (und das sich übrigens im gleichen Packfile befinden muss).

Referenzen:

Packfiles

Blobs


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