Zum Inhalt. Zum Hauptmenü. Zum Untermenü.

Domaincheck! Internet-Adressen einrichten und verwalten.
Oktober 2009
Inhalt der Ausgabe
SILVER erscheint vierteljährlich auch in gedruckter Form. Bestellen Sie ein kostenloses Abo per E-Mail an:
silver@sil.at
$Id: sysad-artikel-021.txt,v 1.1 2009/09/13 20:58:35 rhonda Exp $
Q: was ist git?
A: git[1] ist ein werkzeug zur versionskontrolle. es speichert die
historie von dateien, um die aenderungen verfolgen zu koennen und
gegebenenfalls auf fruehere versionen zurueckgreifen zu koennen.
Q: irgendwie kommt mir das schrecklich bekannt vor?
A: ja, in SILVER #7[2] wurde bereits ueber bazaar geschrieben. git ist
jedoch anders, in mehrerlei hinsicht.
etwas, das mich an bazaar immer gestoert hat, war die geschwindigkeit.
git ist schnell. wirklich schnell. man passt recht bald seine
arbeitsweise an und fuehrt immer wieder mal auch zwischendurch einen
commit durch, um nicht im notfall in die verlegenheit zu tappen, eine
fruehere version nicht mehr zur verfuegung zu haben.
ein weiterer punkt ist es, dass sich der unterbau von git noch nie
geaendert hat, waehrend der von bazaar schon mehrere aenderungen hinter
sich hat. dadurch wird der austausch einfacher, und man muss nicht darauf
warten, dass ein entferntes repository ein update des datenspeichers
durchfuehrt.
git ist auszerdem enorm flexibel. es bietet schnittstellen, ueber die
eigene befehle hinzugefuegt werden koennen, oder aber auch hooks, durch
die zu unterschiedlichsten zeiten waehrend der uebertragung von daten
sowohl lokal als auch entfernt eingegriffen werden kann. dadurch ist git
wunderbar erweiterbar.
durch die verwendung von sha1 pruefsummen fuer die commit-objekte, die
sich aus dem inhalt, der historie und der commit-meldung ergeben, hat
man zusaetzlich einen enormen vorteil: eine integrierte
integritaetspruefung.
Q: aber mit jeder neuen versionsverwaltung neue tools lernen ...
A: damit koennte durch git ein ende in sicht sein. einige leute haben
sich an die arbeit gemacht, obige beschriebene flexibilitaet und
erweiterbarkeit zu nutzen und bieten somit sowohl import als auch export
tools fuer zumindest CVS, SVN, Arch (alle inzwischen direkt bei git mit
dabei) und bazaar[4].
Q: koennen wir bitte endlich anfangen?
A: gerne doch. mit "git init" wird im aktuellen verzeichnis ein git
repository initialisiert. mit "git add" wird eine (geaenderte) datei
fuer den naechsten "git commit" vorgemerkt – hier ist anzumerken, dass
jeweils nur die aktuelle aenderungen der datei hinzugefuegt werden.
falls man die datei spaeter noch mal aendert und diese aenderungen
ebenfalls uebergeben will, ist nochmals ein "git add" durchzufuehren,
damit sie beim "git commit" ebenfalls mituebergeben werden.
mit "git diff" kann man sich die noch nicht vorgemerkten aenderungen
anzeigen lassen – falls man die zur uebergabe vorgemerkten aenderungen
ansehen moechte, ist dazu die option "--cached" notwendig. um eine
vorgemerkte aenderung einer datei doch nicht zu uebergeben, gibt es den
befehl "git rm --cached" – hier bitte aufpassen, ohne die option
--cached wuerde "git rm" die datei auch aus dem aktuellen verzeichnis
loeschen. dadurch sollte das zweischichtige prinzip von git ein wenig
klar werden: aenderungen werden zuerst in einem so genannten index
(cache) abgelegt und erst beim tatsaechlichen commit uebertragen.
eine sache, die in git sehr einfach und ebenfalls enorm schnell
funktioniert, ist das arbeiten mit branches. mit "git checkout -b
mybranch" kann man vom aktuellen zustand ausgehend in einem neuem branch
namens mybranch arbeiten, was den vorteil bringt, dass man gewisse dinge
einfach mal ausprobieren kann und trotzdem nicht auf die versionierung
verzichten muss, bis man damit fertig ist.
wenn sich im hauptzweig die sachen weiterentwickeln, kann man diese
einfach mittels "git merge master" in den branch uebernehmen und daran
weiterarbeiten (master ist der name des hauptzweiges). allermeist gibt
es dabei keinerlei probleme – falls doch, korrigiert man den konflikt in
den entsprechenden dateien, fuegt die aenderung mit "git add" hinzu und
schlieszt mit einem "git commit" ab, um den merge zu beenden.
eine andere strategie, die git hier etwas abhebt, ist ein "git rebase".
damit kann man einen entwicklungszweig, der von einer bestimmten version
abgespalten wurde, auf die neueste version in dem zweig basieren lassen.
auch dabei kommt im zweifelsfall das konflikthandling von vorhin zum
tragen, so notwendig.
wenn man mit den aenderungen im branch fertig ist, macht man dann
lediglich ein "git checkout master" und ein "git merge mybranch", um die
aenderungen des branches in den hauptzweig zu uebernehmen.
Q: gut, wie sieht hier jedoch das einbinden von remotes an?
A: beim arbeiten mit remotes beginnt man in der regel mit einem
"git clone" und der URL des entfernten repository. das kann auf
vielfaeltigste art und weise passieren, wie z.b. ueber rsync, ssh, http,
https oder das git-eigene git protokoll. das klonen holt sich vom
entfernten repository die gesamte historie samt allen zugehoerigen
informationen wie branches und tags und macht einen checkout des
hauptbranches. mit "git branch -a" sowie "git tag" kann man sich diese
informationen alle anzeigen lassen.
updates holt man sich mittels "git pull" (wobei hier auch
gegebenenfalls eine konfliktloesung notwendig sein kann), und wenn man
schreibrechte auf das remote hat, schiebt man seine aenderungen mittels
"git push" retour. tags werden nicht automatisch gepusht, dazu ist die
option --tags notwendig, und falls man mehrere remote branches
ausgecheckt hat (z.b. mittels "git checkout -b patchbranch
remotes/origin/patchbranch"), sollte man dem push die option --all mit
auf den weg geben, um nicht alle branches einzeln angeben zu muessen.
wenn man die sachen, bevor man sie ins entfernte repository schiebt,
noch etwas aufbereiten will, laesst sich das ebenfalls tun. zum beispiel
mittels dem bereits erwaehnten rebase tool und dessen interaktivem
modus: man ruft "git rebase -i referenz-zum-ersten-commit" auf und kann
in der angezeigten liste einzelne commits zum editieren auswaehlen oder
mehrere zusammenfuehren, indem man bei allen bis auf den ersten in der
liste das schluesselwort durch "squash" ersetzt.
es lassen sich auch mehrere entfernte repositories mittels dem befehl
"git remote add" hinzufuegen. hier merkt man den verteilten ansatz von
git, da dies einem ermoeglicht, aenderungen von verschiedensten
leuten bei sich zusammenzufuehren, zu testen und dann auch wieder
weiterzuverbreiten.
Q: gibt es eine besonderheit, die bei git gerne verwendet wird?
A: ja, "git bisect". damit kann man, wenn man einen fehler hat, sehr
huebsch auf die suche gehen, wann dieser hinzugefuegt wurde. man beginnt
in der regel damit, dass man nach einem "git bisect start" die aktuelle
version mit "git bisect bad" als schlecht markiert. anschlieszend
markiert man eine version, von der man weisz, dass sie den fehler noch
nicht hatte, als gut: "git bisect good v1.2.3.4". git bisect sucht sich
nun die mitte der commits dazwischen und fuehrt ein checkout davon
durch. mit diesem testet man auf den fehler, und wenn man herausgefunden
hat, ob sich der fehler hier befindet oder nicht, setzt man mittels "git
bisect good" bzw. "git bisect bad" die suche solange fort, bis sich der
kreis der verdaechtigen commits auf nur einen eingeschraenkt hat. in
diesem laesst sich dann in der regel recht einfach der fehler entdecken,
ohne dass man den gesamten rest der aenderungen seit der letztbekannten
version durchgehen muss.
Q: alles gut und schoen, aber git hat sicher auch einschraenkungen und
nachteile?
A: das ist richtig – diese muessen von projekt zu projekt entsprechend
abgewaegt werden. ein groszer vorteil, dass die komplette historie samt
commit-meldungen und allem drum und dran in die sha1-pruefsumme fuer den
commit eingerechnet wird (was unter anderem eine gute
integritaetspruefung bietet), wird auch zu einem doch nicht
unerheblichem nachteil: es ist nicht (bzw. nicht ohne probleme)
moeglich, lediglich einen teil der historie auszuchecken und damit zu
arbeiten. als argument wird hier recht gerne erwaehnt, dass git sehr gut
komprimiert und der platz daher nicht explodiert. auf der anderen seite
jedoch kann git dadurch beim arbeiten mit logs ein wenig zaeh wirken –
insbesondere, wenn sich auch binaerdateien im repository befinden.
eine andere sache, die sich ebenfalls durch die sha1-pruefsumme fuer
den commit ergibt, ist die unmoeglichkeit, nur das eine oder andere
unterverzeichnis auszuchecken. es gibt zwar mit dem ansatz von
submodulen, bei dem unterverzeichnisse fuer sich alleinstehend bewertet
werden und darueber gelegt das hauptrepository arbeitet, einen ansatz,
das zu ermoeglichen, jedoch ist das handling davon nicht ganz einfach
und birgt ein paar stolperfallen.
[1] git:
http://git-scm.com/
[2] bazaar http://www.sil.at/aktuelles/magazin/magazin-nr-7/seite-27/>
[3] verschiedene ansaetze, der funktionsfaehigste setzt aber von der
bazaar-Seite her aus an:
https://launchpad.net/bzr-git