Workflow & Begriffe
Angenommen, man hat einen Ordner, der von Git versioniert werden soll:
> cd /Pfad/zu/Projekt/Ordner > git init > ls -------------------------- + /Pfad/zu/Projekt/Ordner/ <- working directory |- .git/ <- git directory / repository |- Datei1 -------------------------- |- Datei2
Von nun an ist jede Datei in einem der vier Stadien:
Zu Begin sind alle Dateien nicht versioniert (also untracked).
Des Weiteren gibt es drei Orte, in/zwischen denen sich die Aktionen abspielen können:
+---------------------+ +---------------------+ +----------------------+ | working | | staging | | git directory | | directory | | area | | (repository) | +---------------------+ +---------------------+ +----------------------+ Datei1 stage Datei1 v1 ----> v1 Datei2 stage Datei2 commit (5b27c3e) v1 ----> v1 -----> Datei1, Datei2 v1 v1 v Datei2 stage Datei2 commit (fz93gb2) v2 ----> v2 -----> Datei1, Datei2 v1 v2 ------------------------------------------------------------------------ Datei1, Datei2 checkout (5b27c3e) v1 v1 <----------------------------- Datei1, Datei2 v1 v1
working directory / Arbeitskopie:
commit:
(fz93gb2) ... (5b27c3e) (k1621kb) o————o————o————o————o ^ master HEAD
checkout:
HEAD & master:
Branches: (Gits killer-feature)
Rücksetzen/Checkout (HEAD zeigt nicht mehr auf den selben commit, wie master)
(fz93gb2) ... (5b27c3e) (k1621kb) o————o————o————o————o HEAD master
Branch setzen (Nicht vergessen auch auf den branch zu wechseln!)
(fz93gb2) ... (5b27c3e) (k1621kb) o————o————o————o————o HEAD master myBranch
Ändern & Commiten (Beachte: mybranch läuft mit)
mybranch
HEAD mybranch o / o————o————o————o————o master
HEAD mybranch o————o————o / o————o————o————o————o master
checkout master
mybranch o————o————o / o————o————o————o————o master HEAD
weiterarbeiten (optional)
mybranch o————o————o / o————o————o————o————o————o master HEAD
merge (neuer commit wird angelegt)
mybranch o——————o——————o / \ o————o————o————o————o———o———o master HEAD
beliebig verzweigbar
branch2 (81fokva) o branch1 / (pa203jk) (fz93gb2) o————o————o————o (5b27c3e) ../ o————o————o————o————o HEAD master
Angenommen wir wechseln auf einen neuen branch
o————o————o HEAD master mybranch
HEAD mybranch o / o————o————o master
HEAD mybranch o————o / o————o————o master
Fast-Forward
HEAD mybranch master o————o————o————o————o
detached State
(fz93gb2) ... (5b27c3e) (k1621kb) o————o————o————o————o master HEAD
(fz93gb2) ... (5b27c3e) (k1621kb) o————o————o————o————o HEAD master mybranch <-------------- HEAD ist aber detached, also zwar auf dem commit, folgt aber nicht dem branch "mybranch"
HEAD o / o————o————o————o————o mybranch master
reparierbar durch merge:
Einsetzen von Branches als Stabilitätsmarker: (vorallem bei größeren Projekten ... nicht unbedingt in der Übungsgruppe)
master o————o————o \ develop o————o————o————o————o \ proposed o————o————o
Hauptbranches:
Ist genug Stabilität oder die Aufgabenverteilung gewährleistet, werden die Marker verschoben / Branches gemerged. (Die Begriffe und anzahl an Abstufungen sind von Projekt zu Projekt unterschiedlich)
clone:
(fz93gb2) ... (5b27c3e) (k1621kb) o————o————o————o————o origin/master master HEAD
(fz93gb2) ... (5b27c3e) (k1621kb) o————o————o————o————o————o————o————o master origin/master HEAD
origin/master o————o————o / o————o————o————o————o————o ^ master alter origin/master HEAD
remote Repositories:
erinnerung merge:
vorher: d, branch o a b / o————o————o————o c f, master
nachher: d, branch —— o————— |> (könnte gelöscht werden) a b / \ —— o————o————o————o———o c f g, master ^merge commit
nun zum Rebase Ein Rebase ermittelt, was im ersten Branch geändert wurde und wiederholt die Änderungen der commits für den zweiten Branch.
nach dem rebase:
a b o————o————o————o———o c f d',branch master
nun fast-forward / merge
client o————o / / server o————o————o————o / / o————o————o————o————o master
Problem: Für verschieden (Haupt-)Programmteile "client" und "server" wurden an verschiedenen Stellen im Projekt Änderungen vorgenommen.
Angenommen der Branch "client" ist fertig, "server" jedoch noch nicht. Wie könnte man die Änderungen "sauber" commiten?
Ein Merge ist zwar meist einfacher, dennoch nicht immer angebracht, denn dadurch würde ein Verzweigter, meist unübersichtlicher Baum enstehen.
Der Rebase ermöglicht in diesem Fall die Änderungen, die seit dem Abzweigen des "master" entstanden, neu anzuwenden als wäre nie gebrancht worden.
server o————o————o————o / / client o————o————o————o————o————o————o master
Angenommen "server" ist doch fertig. Auch dessen Änderungen können neu auf client angewendet werden.
client server o————o————o————o————o————o————o————o————o————o————o————o————o master
Rebase keine Commits die Du in ein öffentliches Repository hochgeladen hast. Wenn Du diesem Ratschlag folgst ist alles in Ordnung. Falls nicht, werden die Leute Dich hassen und Du wirst von Deinen Freunden und Deiner Familie verachtet. Wenn Du rebasing als Weg behandelst um aufzuräumen und mit Commits zu arbeiten, bevor Du sie hochlädst und wenn Du nur Commits rebased, die noch nie publiziert wurden, dann fährst Du goldrichtig. Wenn Du Commits rebased die bereits veröffentlicht wurden und Leute vielleicht schon ihre Arbeit darauf aufgebaut haben, dann bist Du vielleicht für frustrierenden Ärger verantwortlich. Quelle: progit: Kapitel 3.6