Distributed Version Control Systems (DVCS) haben im letzen Jahr einiges an Aufmerksamkeit bekommen. Glaubt man Linus Torvalds, dann sind Subversion-User Idioten und Git das einzige DVCS Wert verwendet zu werden. Grund genug sich das mal genauer anzuschauen - und wenn es nur geschieht um nicht zu den von Torvalds erwähnten Subversion-Idioten zu gehören.
So ziemlich jeder Paketmanager hat Git im Angebot (manchmal auch unter dem Namen “git-core” bekannt). Andernfalls kann man sich die aktuellen Sourcen von http://git.or.cz ziehen und von Hand installieren:
wget http://kernel.org/pub/software/scm/git/git-1.5.3.7.tar.gz tar xzf git-1.5.3.7.tar.gz cd git-1.5.3.7.tar.gz make sudo make install
Windows-User können sich an dem msysgit-Installer versuchen, der eine komplette MSYS-Umgebung für Git (und Git selbst natürlich auch) installiert.
(Anmerkung: Nachdem man im Internet für Kommandos beide Schreibweisen finden wird: git-help und git help machen beide das gleiche, aber die erstere Schreibweise gilt als veraltet und wird mit 1.6 wahrscheinlich entfernt werden)
Zuerst sollte man sich Git vorstellen:
git config --global user.name "Your Name Comes Here" git config --global user.email you@yourdomain.example.com
Damit weiss Git mit welchen Namen und welcher eMail Commits und Patches signiert werden sollen.
Alles fängt mal klein an:
mkdir mein-erstes-repo cd mein-erstes-repo git init
Nicht gerade spektakulär, oder?
Will man kein neues Repository erzeugen, sondern ein bestehendes kopieren, klont man sich es einfach:
git clone git://git.rubini.us/code Rubinius
Um was commiten zu können, brauchen wir etwas Inhalt. Dazu erzeugen wir eine Datei namens mein-erster-commit.txt in unserem gerade erstellten Verzeichnis und befüllen diese mit etwas Inhalt. Dann:
git add mein-erster-commit.txt git commit -m 'Noch bin ich nicht verloren!'
Wenn man den m-Parameter weglässt, wird sich stattdessen der Lieblingseditor öffnen, wo man seine Commit-Nachricht schreiben kann.
Anstatt all unsere Änderungen immer in einen Topf zu werfen, können wir sie auch auf verschiedene Entwicklungszweige (Branches) verteilen. Dazu müssen wir zuerst einen neuen Branch erzeugen:
git branch mein-erster-branch
Mit git branch bekommen wir eine Liste mit allen verfügbaren Branches. Der Branch auf dem wir uns aktuell befinden ist mit einem * markiert, in unserem Fall also master (der vorhin erwähnte Topf). Nachdem wir uns gerade einen schönen neuen Branch erzeugt haben, wollen wir ihn auch verwenden:
git checkout mein-erster-branch
Hier können wir nach Herzenslust herumprobieren und editieren, alle anderen Branches bleiben von den Änderungen verschont (Der Branch erzeugen und auschecken-Schritt kann auch in einem gemacht werden: git checkout -b mein-erster-branch).
Aber irgendwann werden wir mal auch was sinnvolles produzieren, und noch später haben wir vielleicht ein paar Branches die wir zu einem verschmelzen wollen. Auch hier hilft uns Git weiter:
git merge der-andere-branch
Damit werden die Änderungen aus der-andere-branch in den aktuellen Branch gemergt (man kann auch mehr als einen Branch angeben).
Kein Problem! Git kann nicht nur Subversion-Repositories klonen, sondern auch Änderungen an Subversion-Repositories schicken! git svn heisst das magische Kommando, das aber nicht immer von Haus aus inkludiert ist. In diesem Fall reicht es meistens entsprechende Settings im Packetmanager zu ändern dass Subversion-Support inkludiert wird (MacPorts-User tippen z.b. sudo port install git-core +svn, Gentoo-User aktivieren die svn-Useflag, etc.).
Dann geht folgendes:
git svn clone http://svn.ruby-lang.org/repos/ruby/trunk Ruby
Je nach Grösse des Repositories und der Netzwerkgeschwindigkeit kann das eine ganze Weile dauern.
Wenn wir Commit-Rechte für das Ruby-Repository hätten, dann könnten wir (nach ein paar Commits gegen das lokale Git-Repository) unsere Änderungen (aus dem aktuellen Branch) ans Subversion-Repository schicken:
git svn dcommit
Und damit kennt man auch schon alle grundlegenden Kommandos von Git. git help listet diese und andere wichtige Kommandos auf, mit git help <command> kriegt man zu einem speziellen Kommando Hilfe. Mehr Lesestoff gibts auf englisch mit diesem Tutorial sowie der Einführung Everday Git with 20 Commands or so. Das Git Wiki hat auch einige Links parat. Für git svn gibts einen Crash Kurs und eine etwas ausführlichere Einführung. Eine ausführliche Erklärung wie Git arbeitet bietet Git for Computer Scientists.
Kommentar schreiben
Kommentare
Moin! Linus mag zwar ein begnadeter Hacker sein, aber mit seinem Diskussionsstil wird der bei mir nichts (Jaja, ich weiß, "schön erfrischend direkt" werden seine Jünger jetzt einwerfen). Vielleicht habe ich mir deshalb git nie genauer angesehen (auch wenn ich mir letztens ein Projekt damit auschecken musste). Trotzdem danke! Gruß, Johannes
Ich könnte mit dem Disskusionsstil leben - als Präsentator wär er aber nicht gegeignet... Er zeigt zwar schön die Vorzüge auf - aber was kostet denn dann ein Pull oder ein Push?
@Johannes: Meiner Erfahrung nach sind pushs/pulls sehr vom Netzwerk abhängig (wie bei Subversion). Einen Unterschied macht allerdings auch wie das Repository nach aussen hin sichtbar gemacht wird. Wenn das ganze über http/WebDAV geschieht ist das deutlich langsamer als über git-server/ssh.
@iGEL: Ja, über seinen Diskussionstil kann man, nun, diskutieren :) Aber davon hängt ja nicht ab wie gut ein Tool ist - und nachdem Git mittlerweile auch von einer viel netteren Person maintained wird (Junio Harmano), kannst du dich vielleicht auch mit Git anfreunden. Es ist auf jeden Fall kein Fehler sich damit etwas auszukennen, auch wenn man ein anderens (D)VCS verwendet.
@Johannes: Kleiner Nachtrag: Wenn das andere Repo auf dem gleichen Rechner liegt, dann gehts verdammt schnell, da er im Prinzip nur die Packs kopieren muss, d.h. (fast) so schnell wie deine Festplatte lesen/schreiben kann.
Ich verwende seit längerer Zeit für meine persönlichen Entwicklungen ausschließlich git. Insbesondere haben mich die leichtgewichtigen Branches überzeugt: Zum herumspielen mit einem neuen Feature einen neuen Branch anlegen und darin entwickeln. Wenn es gefällt verschmilzt man es mit dem master-Branch und kann den temporären Branch anschließend löschen; wenn es nicht gefällt, löscht man den temporären Branch einfach so. Der Vorteil dabei ist, dass der temporäre Branch nicht mehr im Repository existiert, ich habe es also nicht durch meine Spielerei "verdorben".
Manchmal habe ich sogar mehrere solcher temporärer Branches gleichzeitig und mache zwischendurch dann auch noch ein Bugfix im Master...Sehr schön. Was ich mich gerade frage, gibt es ein Equivalent zu "svn export". Also eine Möglichkeit ein entferntes Repository ohne History auf den eigenen Rechner zu kopieren? MfG Daniel
@bovi:
Das ist aber wahrscheinlich nicht ganz das, was Du gesucht hast, oder? ;)git clone git://git.rubini.us/code Rubiniuscd Rubiniusrm -rf .git@bovi: Ein direktes Equivalent zu "svn export" kenn ich nicht, aber mit git archive kann man sowas aehnliches machen: git archive --prefix=rubinius/ HEAD | (cd /mein/pfad/ && tar xf -) (Vorausgesetzt du befindest dich in deinem lokalen Klon des Rubinius-Repo) Dann kriegst du unter /mein/pfad/rubinius/ eine Kopie von HEAD aus dem Rubinius-Repo. `archive` nimmt auch einen remote-Parameter, wo man ein (entferntes) Git-Repo angeben kann. Alternativ dazu kannst auch `git clone --depth 1 ` verwenden, damit bekommst du zwar ein normales Git-Repo, aber es wird nur eine sogenannte Shallow Copy erzeugt wo eben nur der aktuellste Stand als History verfuegbar ist. Dann einfach .git/ löschen, fertig.
Hi janfri. Nein eigentlich nicht (-; Mein Problem hier in Beijing ist nämlich seit langem, dass die Internetverbindungen unterdurchschnittlich langsam sind. Bei subversion hilft es deutlich, wenn nur der Head exportiert wird. Ich hatte gehofft einen solchen Geschwindigkeitsvorteil auch bei git zu erreichen.
Mist. Die Formatierung ist irgendwo verlorengegangen. Ich hoff man kanns dennoch lesen.
@janfri Na Branches sind bei SVN aber auch günstig. Und im SVNBOOK haben sie auch sehr detailiert beschrieben, wie man Branches mergt. @cypher & Rest Wie steht's mit anderen dscm? So wie z.B. darcs?
@Johannes: Das Problem mit svn-branches ist nicht wie schnell sie erzeugt werden können (Die Subversion-Entwickler geben die Performance korrekt mit O(1) an, aber wie jemand anderer auch mal bemerkt hat ist es eine sehr grosse 1 ;), sondern das mergen nachher wo Subversion wirklich versagt. Einen Branch zu mergen der schon länger in Entwicklung ist kann eine etwas traumatisierende Erfahrung sein.
Zu den anderem DVCS: Ich persönlich hab neben Git auch Darcs, Mercurial und Bazaar ausprobiert, aber mir hat dann eben Git am Ende am besten gefallen, weshalb ich mich damit auch auskenne. Feature-mässig ist für mich (neben Git natürlich) Darcs mit seiner "Theory of Patches" sehr interessant, und ich werd die Entwicklung da sicher im Auge behalten.
Falls wer eine Einführung für eines dieser Systeme schreiben will, können wir sicherlich für die Veröffentlichung dieser auf der Mine arrangieren.
Wobei ich hier einwenden muss, dass das alles eine Sache der Übung und des verwendens von svnmerge ist. Merge Tracking ist übrigens das große + in der nächsten Version von Subversion. An Git nervt mich das wenig nutzerfreundliche Konsoleninterface. Nach einem git clone kriege ich erstmal lange Kolonnen Hashes - ein svn checkout gibt mir eine sehr verständliche Liste von Dateien.
Ach, es sagt mir doch bitte keiner, dass man sich nicht auch mit git sein REPO bei einem mißglückten Merge zerschießen kann. svn revert gibt's auch. Hält man sich an das SVNBOOK und die best practices dann geht's doch auch. Hole ich mir oft die Änderungen aus dem Trunk in meinen Branch, dann muss ich nur noch "meine" Änderungen später in den Trunk einpflegen... Ach es kommt halt ganz drauf an. Selbst bei darcs hatte ich es öfters geschafft mir mein Repo auf lustigste Weise zu knicken.. Bei SVN aber auch. Ich mein, es kommt IMMER drauf an, wie man mit dem Zeug arbeitet. Für Torvalds ist's wohl am wichtigsten, dass er keinen zentralen Server hat, dem er vertrauen muss und für den er diverse GB an Zugriffsrechten pflegen muss. Imho gibt's aber auch bei ihm eine zentrale Stelle: SEIN Repo. :-þ
@Johannes (08.01. 19:33): Ich fand es immer ziemlich umständlich einen Branch in svn zu erzeugen, ich habe es ganz selten mal gemacht. Bei git einfach ein
Außerdem ist ein Branch in svn eben immer ein Teil der Historie und kann nicht nur temporär existieren. Ich mache so ziemlich für alles was ich neu entwickle zunächst mal einen neuen Branch (manchmal mehrere pro Tag). So kann ich von Anfang an mit Versionskontrolle weiterentwickeln aber trotzdem im Falle, dass mir die Idee, die spezielle Umsetzung etc. nicht gefällt, den Branch komplett (ohne Spuren im Repository zu hinterlassen) löschen:git checkout -b some_crazy_idea, fertig.git branch -D some_crazy_idea. Manchmal probiere ich auf diese Weise auch verschiedene Implementierungen einer Funktionalität aus und entscheide mich erst dann, welche ich behalten will.@Johannes "Ach, es sagt mir doch bitte keiner, dass man sich nicht auch mit git sein REPO bei einem mißglückten Merge zerschießen kann."
Natürlich kann man sich in Git auch sein Repo zerschiessen, das ist allerdings nicht was ich meinte. Merging in Subversion ist definitiv nicht unmöglich, und wird auch verwendet, aber in Git funktionierts meiner Erfahrung nach halt einfach besser.
Ich will ja auch nicht sagen das wir alle Subversion sofort über Bord werfen sollen. Ich hab an meiner FH zwei Knowledge Nights gehalten (Vorträge über spezielle Themen), einmal zu Versionsverwaltung allgemein (mit Beispielen in Subversion) und einmal eine Einführung in DVCS mit Git. Bei beiden Vorträgen war ich erstaunt wie viele Leute noch nicht mal mit irgendeiner Versionsverwaltung arbeiten und bin deshalb meistens schon froh wenn irgend ein System eingesetzt wird (und Subversion gehört, was zentrale Systeme angeht, sicherlich zu den besten). Ich persönlich verwende halt Git wo es nur geht, weil mir das System eben am besten gefällt.
Worauf ich hinaus will: Ein Nur-Subversion User sollte auch mal den Blick über den Tellerrand wagen. Wenn ihm die Systeme nicht gefallen, dann hat er sie wenigstens probiert, und sich eine Meinung darüber gebildet, was auf jeden Fall besser ist als DVCS pauschal als unbrauchbar abzustempel.
"Imho gibt's aber auch bei ihm eine zentrale Stelle: SEIN Repo."
Natürlich. Aber: Er kann auch lokal mehrere Repos haben. Er kann auf jedem einzelnen Rechner den er besitzt ein Repo haben. Und Torvalds hat selber gesagt dass es auch bei DVCS immer zentrale Server geben wird (z.b. kernel.org), aber aus einer technischen Notwendigkeit, sondern weil sie einfach praktisch sind ("Public watering hole").
"... aber NICHT aus einer technischen Notwendigkeit..."
Nun, ich sage ja nicht, dass dSCM schlecht sind.. Ich mag mich nur nicht damit abfinden, dass man SVN zuspricht unbenutzbar zu sein. (Auch bei SVN kann man Branches wieder komplett löschen..) Aber gut - es ist schon verlockend einen Branch schon komplett außerhalb der Historie in einer neuen Historie anzulegen... Naja, ich hab mich erst vor kurzem mehr mit SVN beschäftigt. Davor bin ich von nix zu darcs und jetzt eben bei SVN. Ich weiß im Moment aber auch nimmer genau, warum ich jetzt kein darcs mehr nutze.. Aber irgendwie gefällt mir die Idee eines zentralen Servers schon. Aber ich sehe schon - git muss ich einmal ausprobieren. Gibt es hierzu auch ein "bestpractices" Buch? Mit was werden hier eigentlich die Kommentare formatiert? Ich mag nicht immer einen BLOCK an Kommentar abgeben! (Obwohl ich mir etwas Mühe gegeben hab.)
Nja, wie janfri schon erwähnt hat sind Branches in SVN eben immer in der Historie vorhanden und für jeden einsehbar, der auch Lesezugriff auf das Repo hat.
"Gibt es hierzu auch ein "bestpractices" Buch?"
Nicht das ich wüsste.
ad formatierung: Etwas HTML ist anscheinend erlaubt (z.b. br). Mir wär auch Markdown oder sowas lieber, aber so isses nun halt mal..
Gut - du bekommst ja wenigstens schon mal Absätze hin. Es gibt wohl so eine Art "EveryDay GIT": http://www.kernel.org/pub/software/scm/git/docs/everyday.html Zum Rest geb ich dir Recht.
@cypher: Ja, das sind sie. Aber das ist für die Philosophie von Subversion notwendig. Ob man das jetzt unpraktisch findet... daran aufhängen würde ich mich nicht. (Im übrigen ist das eine häufige Beschwerde von Leuten, die von CVS wechseln ;)). Zum Branching: ich weiss jetzt nicht, was daran umständlich ist: svn commit trunk -m "commitmessage vor branch" svn cp http://mein.sub.repos/trunk/ http://mein.sub.repos/branches/mybranch svn update Viele Leute machen das lokal: und dann wird diese Operation wirklich langsam und nervig.