Warum Git besser als X ist

spacer
Diese Seite existiert weil ich in letzter Zeit oft Gitster gegen Vorwürfe von Fanboyismus, Mitläufertum und "koolaid-Durst" verteidigen musste. Darum hab ich eine Liste mit Gründen zusammengestellt weshalb Leute von X zu Git wechseln und warum du vielleicht auch wechseln willst. Klicke einfach auf einen Grund um ihn anzuschauen.
Alle ausklappen | Alle einklappen
hg bzr svn perforce

Leichtgewichtige lokale Branches

Eines der wahrscheinlich verlockendsten Features von Git, welches es auch von so ziemlich allen anderen SCMs abhebt. Es unterscheidet sich komplett von den anderen Modellen mit denen ich es hier vergleiche, bei denen meistens ein kompletter Klon des Repositories in einem neuen Verzeichnis als beste Branching-Strategie empfohlen wird.
Git arbeitet anders. Git erlaubt es dir mehrere lokale Branches zu haben, die voneinander komplett unabhängig sein können. Erzeugen, Zusammenführen und Löschen von diesen Entwicklungssträngen geht schnell vonstatten.
Dadurch kann man Dinge machen wie:
  • Eine Idee in einem eigenen Branch ausprobieren, ein paar Commits machen, zum Ursprungsbranch zurück wechseln, einen Patch einspielen, wieder zum Ideenbranch wechseln und ihn dann mergen.
  • Einen Branch haben der alles beinhaltet was in Produktion gehen soll, einen wo man neue Features zum Austesten einspielt und viele kleinere für die tägliche Arbeit.
  • Für jedes neue Feature an dem du arbeitest einen eigenen Branch erzeugen, damit du nahtlos zwischen ihnen wechseln kannst, ohne dass sich die Branches ins Gehege kommen und sie dann einfach zu löschen wenn sie in den Hauptbranch eingespielt wurden.
  • Ein Experiment in einem Branch ausprobieren, entdecken dass es nicht funktioniert und den Branch einfach löschen — ohne dass jemand anders diesen Branch jemals zu Gesicht bekommt (auch wenn du in der Zwischenzeit andere Branches gepusht hast).
spacer
Wichtig: Wenn du zu einem entfernten Repository pushst, musst du nicht alle deine lokalen Branches pushen. Du kannst auch nur einen Branch veröffentlichen, und die anderen lokal lassen. Das gibt dir die Freiheit neue Ideen auszuprobieren ohne dir darüber Gedanken zu machen wie und wo du sie mit anderen Branches zusammenführst oder sie mit anderen Leuten teilst.
Du kannst Wege finden all das auch mit anderen Systemen zu machen, aber das bedeutet meistens mehr Arbeit und höhere Fehleranfälligkeit. Git macht diesen Prozess unglaublich einfach, was die Arbeitsweise der meisten Entwickler ändert wenn sie Git lernen.
spacer spacer spacer spacer spacer
svn perforce

Alles ist lokal

Grundsätzlich arbeiten alle dezentralen SCMs lokal, aber nach meiner Erfahrung ist das bei Git noch viel mehr der Fall. Nur wenige Kommandos ausser 'fetch', 'pull' und 'push' nehmen mit der Aussenwelt Kontakt auf, meistens wird nur die Festplatte beansprucht.
Das macht nicht nur die meisten Operationen um einiges schneller als du es vielleicht gewöhnt bist, aber es erlaubt dir auch komplett offline zu arbeiten. Das klingt jetzt vielleicht nicht sehr aufregend, aber ich bin immer wieder erstaunt wie oft ich eigentlich offline arbeiten muss. Die Fähigkeit neue Branches anlegen oder zusammenführen zu können oder die History des Projektes anzusehen während ich im Flugzeug oder im Zug sitze ist sehr praktisch.
spacer
Selbst in Mercurial nehmen oft genutzte Kommandos wie 'incoming' und 'outgoing' Kontakt mit dem Server auf, während man in Git mit einem 'fetch' alle Daten holen kann bevor man offline geht und dann Vergleiche, Merges oder History mit den Daten macht, die schon auf dem Server sind aber noch nicht in den lokalen Branches.
Das bedeutet dass es sehr einfach ist Kopien nicht nur von den eigenen Branches zu haben, sondern auch denen von jedem anderen der mit dir im Git-Repository arbeitet, ohne dass du dein eigenes Zeug durcheinander bringen musst.
bzr svn perforce

Git ist Schnell

Git ist schnell. Jeder, selbst Hardcore-Benutzer anderer SCMs, geben generell Git diesen Titel. Verglichen mit SVN und Perforce ist Git so schnell weil beinahe alle Operationen lokal passieren. Aber selbst verglichen mit anderen verteilten SCMs ist Git ziemlich schnell.
Ein Grund dafür ist, dass Git dazu gebaut wurde um am Linux-Kernel zu arbeiten, wodurch es von Beginn an effektiv mit grossen Repositories umgehen musste. Ein anderer Grund ist, dass Git in C geschrieben ist und noch ein weiterer Grund ist, dass die primären Entwickler Effizienz zu einem Designziel der Applikation gemacht haben.
Im folgenden sind ein paar Benchmarks die ich mit drei Kopien des Django Sourcecodes in 3 verschiedenen SCMs gemacht habe: Git, Mercurial und Bazaar. Ich hab einiges von dem auch in SVN getestet, aber glaub mir, es ist langsamer — nimm die Zahlen von Bazaar und füge Netzwerklatenz hinzu...
Das Endresultat war, dass Git in allem ausser dem Hinzufügen von neuen Dateien am schnellsten war (Mercurial liegt bei sehr grossen Commits gleichauf, aber der Commit mit dem ich getestet habe war so gross dass es unwahrscheinlich ist dass du jemals etwas ähnlich grosses comitten wirst — normale Commits sind viel schneller in Git)
Git Hg Bzr
Init 0.024s 0.059s 0.600s
Add 8.535s 0.368s 2.381s
Status 0.451s 1.946s 14.744s
Diff 0.543s 2.189s 14.248s
Tag 0.056s 1.201s 1.892s
Log 0.711s 2.650s 9.055s
Commit (Large) 12.480s 12.500s 23.002s
Commit (Small) 0.086s 0.517s 1.139s
Branch (Cold) 1.161s 94.681s 82.249s
Branch (Hot) 0.070s 12.300s 39.411s
Die kalten und warmen Branching-Werte sind die Zahlen für das erste und das zweite erstellen eines neuen Branches - die zweite Zahl ist ein neuer Branch mit einem warmen Festplatten-Cache.
Es sollte angemerkt werden, dass, obwohl die 'add'-Werte um einiges langsamer sind, dies für eine wirklich massive 'add'-Operation war — über 2000 Dateien. Für den Großteil von dem was die meisten Leute täglich machen werden sind 'add'-Operationen in allen diesen Systemen innerhalb eines Bruchteils einer Sekunde erledigt. Alle anderen Operationen die hier getestet wurden (ausser dem grossen Commit vielleicht) sind ein Hinweis auf die Dinge die man vielleicht auch täglich macht.
Die Zahlen sind nicht wirklich schwer zu reproduzieren: einfach das Django-Projekt in jedem dieser Systeme klonen und die gleichen Kommandos in jedem ausprobieren.
  • git clone git://github.com/brosner/django.git dj-git
  • hg clone hg.dpaste.com/django/trunk dj-hg
  • bzr branch lp:django dj-bzr
  • svn checkout code.djangoproject.com/svn/django/trunk dj-svn
svn

Git ist klein

Git ist wirklich gut darin Platz zu sparen. Dein Git-Verzeichnis wird (im Allgemeinen) kaum grösser als ein SVN Checkout sein - in manchen Fällen sogar kleiner (anscheinend kann ganz schön viel in diese .svn-Verzeichnisse gepackt werden).
Die folgenden Zahlen wurden von den Klonen des Django-Projekts genommen: aus jedem der semi-offiziellen gespiegelten Repositories am gleichen Punkt in dessen History.
Git Hg Bzr Bzr* SVN
Repo Alone 24M 34M 45M 89M
Entire Directory 43M 53M 64M 108M 61M
* der zweite Bzr-Wert kam nach dem Ausführen von 'bzr pack' zustande, nachdem ich dachte, dass es das Repository kleiner machen würde. Aus irgend einem Grund wurde es aber viel, viel größer.
hg bzr svn perforce

Die Staging Area

Im Gegensatz zu anderen Systemen hat git etwas namens "Staging Area" oder "Index". Das ist eine Zwischenschicht in dem du deinen nächsten Commit genau so vorbereiten kannst, wie du ihn haben willst.
Das coole an der Staging Area und was Git von diesen anderen Werkzeugen unterscheidet ist, dass du ganz einfach nur einzelne Dateien in die Staging Area geben und diese dann ganz einfach committen kannst ohne die anderen modifizierten Dateien in deinem Arbeitsverzeichnis mit comitten zu müssen. Du musst auch nicht jede Datei einzeln auf der Kommandozeile angeben, wenn du einen Commit erstellst
spacer
Das erlaubt es dir auch nur Teile der Modifikationen in die Staging Area zu geben. Du kannst zum Beispiel nur die Änderungen im oberen Teil der Datei an der du gerade arbeitest in die Staging Area geben, aber nicht die Änderungen im unteren Teil.
Git macht es natürlich auch einfach dieses Feature zu ignorieren wenn du diese feine Kontrolle nicht benötigst — einfach ein '-a' an das Commit-Kommando anhängen.
spacer
svn perforce

Verteilt

Eines der coolsten Features eines jeden verteilten SCMs, inklusive Git, ist, dass es verteilt ist. Das bedeutet dass man statt einem "checkout" des aktuellsten Stand des Source Codes einen kompletten "Klon" des ganzen Repositories macht.
Dadurch hat jeder User, selbst wenn man einen zentralisierten Arbeitsablauf verwendet, essentiell ein komplettes Backup des Hauptservers, von dem jedes dazu verwendet kann den Hauptserver zu ersetzen falls dieser wegen eines Crashes oder Datenkorruption ausfallen sollte. Es gibt deshalb mit Git grundsätzlich keinen "Single Point of Failure" mehr, ausser man hat nur einen Punkt.
Das macht es aber nicht langsamer. Im Durchschnitt ist ein SVN Checkout schneller als jedes der SCMs, aber nicht um viel. Des weiteren war Git das schnellste von allen DSCMs in meinen Tests.
Git 1m 59s
Hg 2m 24s
Bzr 5m 11s
SVN 1m 4s
svn perforce

Beliebige Arbeitsabläufe

Eines der erstaunlichen Dinge ist, dass man wegen Gits verteilter Natur und tollen Branching-System relativ einfach so ziemlich jeden beliebigen Arbeitsablauf realisieren kann den man haben will.

Arbeitsablauf im Subversion-Stil

Ein sehr gebräuchlicher Arbeitsablauf in Git, insbesondere von Leuten die gerade den Übergang von einem zentralisierten System machen, ist der zentralisierte. Git erlaubt es dir deine Commits nicht zu pushen wenn jemand anderes seit dem letzen Update gepusht hat. Deshalb funktioniert das zentralisierte Modell, wo alle Entwickler zu einem zentralen Server pushen ohne Probleme
spacer

Arbeitsablauf für Integrationsmanager

Ein anderer gebräuchlicher Arbeitsablauf ist der eines Integrationsmanagers — einer einzelnen Person, die in ein 'geweihtes' Repository committet, von dem dann die anderen Entwickler klonen, ihre Änderungen in ihre eigenen, unabhängigen Repositories pushen und dann den Manager bitten ihre Änderungen zu ziehen. Diese Art von Entwicklungsmodell sieht man oft in Open Source oder GitHub Repositories.
spacer

Arbeitsablauf im Diktator-und-Leutnant Stil

Für massive Projekte empfiehlt sich ein Arbeitsablauf wie er sich im Linux Kernel findet, wo jemand für ein gewisses Subsystem verantwortlich ist ('Leutnant') und alle Änderungen, die dieses Subsystem betreffen, in sein Repository mergt. Dann kann ein anderer Integrator (der 'Diktator') nur von seinen Leutnants Änderungen ziehen und integrieren, die er dann in sein 'geweihtes' Repository pusht, von dem dann jeder andere klonen oder updaten kann.
spacer

Git ist sehr flexibel was den gewünschten Arbeitsablauf angeht. Man kann also seinen Arbeitsablauf ganz nach seinen Wünschen gestalten.
hg bzr svn perforce

GitHub

spacer
Ich mag hier parteiisch sein, weil ich für GitHub arbeite, aber ich habe diese Sektion dennoch hinzugefügt nachdem so viele Leute GitHub als speziellen Grund angeführt haben weshalb sie Git auswählten.
GitHub ist ein Grund für viele Leute Git zu verwenden, weil es mehr ein soziales Netzwerk als eine einfache Code-Hosting Seite ist. Es ist leicht andere Personen oder Projekte zu finden die ähnliche Interessen und Fähigkeiten haben wie du. Diese können dann einfach forken und eigene Änderungen beitragen. So entsteht eine sehr lebhafte Gemeinschaft um Git und die Projekte in denen es verwendet wird.
Es gibt auch andere Services für Git und die anderen SCMs, aber wenige sind so Benuzterorientiert oder sozial ausgerichtet und keines hat auch nur annähernd so viele Benutzer. Dieser soziale Aspekt von GitHub ist ein Mörderfeature und all das kombiniert mit den möglichen, obigen Features macht das Arbeiten mit Git und GitHub zu einer großartigen Kombination zum schnellen Entwickeln von Open Source Projekten.
Diese Art der Gemeinschaft findet man einfach nicht in anderen SCMs.
spacer spacer
perforce

Einfach zu lernen

Dies war nicht immer wahr — in den frühen Lebensjahren von Git war es weniger ein SCM, als mehr eine Ansammlung von Tools die es einem ermöglichten mit einem versioniertem Dateisystem auf eine verteilte Art und Weise zu arbeiten. Heute jedoch ist der Kommando-Satz und die Lernkurve von Git ziemlich ähnlich zu jedem anderen SCM und sogar besser als manch anderes.
Nachdem es schwer ist, ohne eine Studie etwas objektiv nachzuweisen, zeige ich nur die Unterschiede zwischen den Standardausgaben der Hilfekommandos von Mercurial und Git. Ich habe Kommandos hervorgehoben die in beiden Systemen gleich oder beinahe gleich funktionieren. (In Mercurial bekommt man eine Liste mit ca. 40 Kommandos wenn man 'hg help' tippt.)

Mercurial Help

add		add the specified files ...
annotate	show changeset informati...
clone		make a copy of an existi...
commit		commit the specified fil...
diff		diff repository (or sele...
export	   dump the header and diff...
init		create a new repository ...
log		show revision history of...
merge		merge working directory ...
parents	   show the parents of the ...
pull		pull changes from the sp...
push		push changes to the spec...
remove		remove the specified fil...
serve	   export the repository vi...
status		show changed files in th...
update	   update working directory

Git Help

add		Add file contents to the index
bisect		Find the change that introduce...
branch		List, create, or delete branches
checkout   Checkout a branch or paths to ...
clone		Clone a repository into a new ...
commit		Record changes to the repository
diff		Show changes between commits, ...
fetch	   Download objects and refs from...
grep	   Print lines matching a pattern
init		Create an empty git repository
log		Show commit logs
merge		Join two or more development h...
mv		   Move or rename a file, a direc...
pull		Fetch from and merge with anot...
push		Update remote refs along with ...
rebase	   Forward-port local commits to ...
reset	   Reset current HEAD to the spec...
rm			Remove files from the working ...
show	   Show various types of objects
status		Show the working tree status
tag		Create, list, delete or verify...
Vor Git 1.6 waren alle Git Kommandos im ausführbaren Pfad, was für einige Leute sehr verwirrend war. Obwohl Git noch immer all diese Kommandos kennt, ist das einzige Kommando das noch im ausführbaren Pfad ist 'git'. Wenn man also Mercurial und Git vergleicht, sieht man, dass es einen beinahe identischen Kommando-Satz und ein sehr änliches Hilfe-System gibt. Es gibt also aus der UI-Sicht für einen Anfäger kaum Unterschiede.
Heutzutage ist es ziemlich schwer zu argumentieren, dass Mercurial oder Bazaar leichter zu lernen sind als Git.
Alle ausklappen | Alle einklappen

Diese Seite ist von Scott Chacon gebaut worden, einem GitHubber.
Übersetzung ins Deutsche durch Markus Prinz und Lennart Koopmann.
Wenn du aus gutem Grund mit irgendetwas auf dieser Seite nicht einverstanden bist, schreibe bitte eine email an mich (in Englisch), damit ich es beheben kann.
Den Sourcecode für diese Seite findest du auf GitHub — Patches sind jederzeit Willkommen, wenn du Verbesserungen hast.
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.