Silver Server

Silver Server


Domaincheck! Internet-Adressen einrichten und verwalten.

SILVER 21

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

git -- verteilte versionskontrolle

$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

 

 

 

Kontakt