Hallo,
wie oft committet ihr so in Git? Nur wenn alles läuft, oder immer, wenn
ein Task / Subtask fertig ist.
Gerade bei den kleinen Verbesserungen wie hier ein Name einer Variable
angepasst, etc. frage ich mich, ob ich dann direkt committen soll oder
nicht.
Wie handhabt ihr das?
Gruß
PS: Mein Workflow ist meistens, ein neues Feature kommt auf einen
eigenen Branch und wenn der fertig ist, wird er in den Master-Branch
gemergt.
Wie oft du das machst, musst du selbst entscheiden. Sinnvoll ist es
normalerweise, logisch zusammenhängende Dinge auch zusammenhängend zu
committen. Manchmal committe ich auch mal (auf einem Branch) völlig
unfertiges Zeug, einfach, damit ich es pushen kann und auf einem zweiten
Computer weiter bearbeiten. Klar könnte man auch die remote URL dafür
temporär ändern, aber das macht's auch nicht ernsthaft einfacher.
Der wesentliche Punkt von DVCS im Vergleich zum zentralisierten VCS ist
es ja, dass ein Commit keine weiteren Ressourcen als den lokalen
Computer braucht, weshalb man gut und gern auch kleinere Häppchen
committen kann als bei einem, wo man eine Serververbindung zwingend
haben muss.
Commited wird so oft wie möglich, mindestens einmal am Tag.
Dabei gelten folgende Voraussetzungen:
- der Compiler läuft ohne Fehler durch
- die JUnit-Tests sind alle grün.
Wenn du nur alleine im Repository arbeitest, kannst du das machen, wie
du willst. Allerdings ist es sinnvoll, immer abgeschlossene und
fehlerfreie Tasks zu committen.
PS: Ich empfinde Mergen als Strafe und handhabe das mit den Branches
immer anders. Branchen nur, wenn's wirklich nicht anders geht.
Bedeutet: entwickeln auf dem Master (Head). Und falls
Produktionsprobleme parallel zur neuen Entwicklung behoben werden
müssen, mache ich einen extra Branch ausgehend von der gelieferten
Version (Tag) auf, fix den Fehler dort, liefer von diesem Branch und
merge die Änderungen auf den Master zurück.
Das hat den Vorteil, dass man nur die Bugfix-Änderungen zurück mergen
muss.
Gruß Klatschnass
Für jede Aufgabe habe ich einen Branch. Das ist praktisch, weil man
wechseln kann, wenn sich die Prioritäten verändern.
Auf meine Branch commite ich jeden Einzelschritt, den ich erfolgreich
durchgeführt habe. Im Prinzip entspricht das dann meinen kleinen
Schritten, die mich zur Umsetzung der Aufgabe bringen. Für mich hat das
den Vorteil, dass ich während der Entwicklung immer Checkpoints
(Commits) habe, mit denen ich vergleichen kann, wenn ich Fehler mache.
Am Ende fasse ich die Commits dann mit interactive rebase sinnvoll
zusammen, bevor ich das ganze in den Hauptzweig merge. Hiermit lassen
sich auch Commits umsortieren, wenn man z.B. erst nach mehreren Commits
feststellt, dass man bei einem Commmit einen Fehler gemacht hat.
Laufende Arbeit comitte ich mindestens einmal am Tag, jetzt grade wo ich
ein noch nicht lauffertiges Projekt habe natürlich auch in
uncompilierbarem Zustand.
Wenn Branch "develop" so weit its, wird er auf "test" gemerged, wenn
"test" durch ist, wird das auf "produktion" gemerged.
Ich denke, wie oft man committet, hängt sehr stark davon ab
a) wieviele Leute im gleichen Repo arbeiten und
b) ob alle am Trunk arbeiten oder ob ein "branch & merge"-Workflow
gepflegt wird
Ich nutze nicht GIT, sondern Subversion, und an den wenigen Tagen, an
denen ich massiv mit Software arbeite, committe ich manchmal im
5-Minuten-Takt (wenn ich voneinander unabhängige kleine Themchen
angreife, die separat sinnvoll sind) und manchmal erst am Ende des
Tages. Manchmal wird auch nicht-Lauffähiges committed (mit
entsprechender Bemerkung im Log), um am anderen Rechner weiterarbeiten
zu können oder einfach weil es am Ende des Tages nicht wieder lauffähig
geworden ist.
Manchmal steht die Anzahl der Unit-Test-Fehler im Log, manchmal nicht.
Anhänger des kleinteiligen Refaktoring halten es sogar für sinnvoll,
selbst kleinste Änderungen zu committen, was bei Mehrnutzerrepos
natürlich dann einen "branch & merge"-Workflow geradezu erzwingt.
Lange Rede kurzer Sinn: Das hängt vom eigenen Vorgehen ab, wie oft man
committet. Der Vorgang ist schnell und billig, und man kann ihn sooft
machen, wie man will.
Nach jedem für sich fehlerfreien Einzelschritt, das kann auch mal alle
paar Minuten sein. Mindestens jedoch einmal täglich, dann sollte es nach
Möglichkeit zumindest compilierbar bleiben.
Gebrancht wird für fast jeden Task, damit er vor dem Merge schonmal auf
dem Buildserver compiliert und getestet wurd. Sind die Tasks
klein/unabhängig genug definiert, macht das mergen auch keine
Bauchschmerzen. Der Trunk muss immer compilierbar und stabil sein.
P. P. schrieb:> Ich empfinde Mergen als Strafe und handhabe das mit den Branches> immer anders. Branchen nur, wenn's wirklich nicht anders geht.
Wenn derjenige der den Branch pflegt auch immer regelmäßig (und nicht
zu spät) seinen Branch auf den aktuellen master rebased (oder den master
in seinen Branch hinein merged) dann ist das überhaupt kein Problem,
dann häufen sich auch keine Berge von potentiellen Konflikten unbemerkt
an und wenn ein Konflikt auftritt dann ist die Erinnerung noch frisch,
vor allem aber ist derjenige der der die konfliktbehaftete Änderung in
seinem Branch gemacht hat auch derjenige der am besten weiß wie man sie
mit dem master in Einklang bringt, also soll und kann der auch seinen
Branch jederzeit in einem Zustand halten in dem er problemlos wieder in
den master gemerged werden kann.
Um Konflikte zu lösen nehm ich meld, das geht sehr angenehm und
intuitiv.
Bernd K. schrieb:> Wenn derjenige der den Branch pflegt auch immer regelmäßig (und nicht zu> spät) seinen Branch auf den aktuellen master rebased
Wenn man etwas komplett umkrempelt, ist das in aller Regel wenig
praktikabel. Dann bleibt es nur, in den sauren Apfel zu beißen, und
hinterher die Konflikte aufzulösen, das ist bei git halt nicht
einfacher, als es schon bei CVS oder SVN war.
Wenn man nicht alles umkrempelt, ist es wiederum Geschmackssache (und
eine Frage, wie viel man mit anderen zusammenarbeiten muss), ob man
überhaupt erst einen Branch braucht. Gründe wie das angesprochene
separate CI auf dem Branch können natürlich zusätzlich dafür sprechen.
Jörg W. schrieb:> Wenn man etwas komplett umkrempelt, ist das in aller Regel wenig> praktikabel.
Dann sollte man - wenn möglich - ein Side-by-Side Refactoring anstreben,
Dinge auf Obsolete setzen und regelmäßig zurück integrieren, so Big-Bang
Refactorings machen aus Integratorsicht keinen Spaß.
...und man kann auch nachträglich noch viele Änderungen in kleine
Commits aufteilen. Ich bin gestern über git add -p gestolpert und habe
gleich alle chaotischen Änderungen vom Wochenende in meinem Working Tree
in logisch zusammenhängende Commits aufgeteilt.
Denn ich arbeite oft so, dass ich hier an einem Feature arbeite, dann
merke, dass mir dafür dort noch die Voraussetzungen fehlen,
zwischendurch einen Bug finde und behebe...
Nicht besonders professionell, aber ich verdiene ja auch kein Geld damit
:)
MfG, Arno
Jörg W. schrieb:> Wenn die Praxis nur immer so schön einfach und geradlining wäre …
Zweifelsohne. Gut, wir sind noch auf TFVC unterwegs, dort sind Branches
schwergewichtiger als in Git, dementsprechend haben wir nur einen Main
Branch und jeweils einen pro Team und man versucht so wenig wie möglich
abzuweichen, daher frequente Forward und Reverse Integrations.
Jörg W. schrieb:> ob man> überhaupt erst einen Branch braucht.
Ich hab auch oftmals sehr kurzlebige Branches, da schöne an git (im
Gegensatz zu svn) ist ja daß ein neuer Branch ja nicht viel mehr ist als
mal eben ein zusätzliches Lesezeichen zu setzen und keinerlei Ressourcen
kostet, so daß man für jeden experimentellen oder unfertigen Exkurs mal
eben einen Branch machen kann.
Ich glaube erst wenn einem das völlig unbedarfte Branchen *locker von
der Hand* geht, das dauert durchaus ne Weile wenn man neu mit git ist,
am Anfang ist man versucht weiterhin wie früher ganz linear zu arbeiten
und benutzt es nur um bei Bedarf in die Vergangenheit blicken zu können,
erst dann wenn man merkt daß man eigentlich fliegen kann, daß man die
eine Dimension der linearen Zeitlinie mühelos verlassen und sich frei
zwischen beliebigen Realitäten hin und her bewegen kann ohne die
geringste Kraft aufzuwenden, man muß nur daran denken und schon ist man
dort und mit einem Fingerschnipp neue Alternativen erschaffen und auch
wieder zerstören oder ineinander überführen kann, erst dann kommt der
Moment wo man wirklich spürt wie die Macht von git durch einen
hindurchströmt!
Auch wenn ein Branch praktisch nichts kostet, hat es nicht viel Sinn,
nur des Branchens wegen einen anzulegen.
git ist doch keine Religion. Es will ein DVCS sein, und auch da ist es
beileibe nicht das einzige (und auch in den Alternativen sind Branches
übrigens nicht teurer). Inwiefern es das beste ist, selbst das ist noch
Geschmackssache. Aber da wird es dann ganz schnell religiös …
Jörg W. schrieb:> Auch wenn ein Branch praktisch nichts kostet, hat es nicht viel Sinn,> nur des Branchens wegen einen anzulegen.
Es geht nicht darum die Branches nur der Branche wegen anzulegen sondern
darum daß sie nützlich sind.
Wenn Du zum ersten mal nach zig Jahren merkst daß man nicht nur vorwärts
und rückwärts gehen kannst sondern auch nach Belieben links und rechts
ohne vorher einen Antrag in 3-facher Ausfertigung auf das Anlegen eines
neuen Weges zu stellen wirst Du natürlich erstmal mehrere Tage nur noch
abseits der alten Wege unterwegs sein um die neue Freiheit zu erkunden.
Irgendwann bewegst Du Dich aber völlig natürlich frei im Raum so wie Du
es brauchst ohne darüber nachzudenken.
Wenn dann einer zu Dir sagt: "Du biegst ab nur um des Abbiegens willen",
"Abbiegen ist doch keine Religion" wirst Du nur noch den Kopf schütteln.
So wie ich jetzt.
Bernd K. schrieb:> Es geht nicht darum die Branches nur der Branche wegen anzulegen sondern> darum daß sie nützlich sind.
Wenn sich in der Zwischenzeit auf dem Rest nichts tut, welchen Nutzen
haben sie dann? Du hast ihnen vorübergehend einen Namen gegeben, aber
der löst sich dann auch wieder in Wohlgefallen auf. Für mich sind sie
damit allerdings nicht irgendwie „nützlich“, für dich wahrscheinlich
schon.
Aber ist egal, kann ja jeder machen, wie er gern lustig ist. Ich
hatte/habe auch in CVS oder Subversion keine Probleme, einen Branch
anzulegen, wenn ich einen brauche. Bei CVS werden lediglich die
Versionsnummern dann irgendwie unhandlich.
Jörg W. schrieb:> Wenn sich in der Zwischenzeit auf dem Rest nichts tut, welchen Nutzen> haben sie dann?
Du gewöhnst Dich daran Deine unvollendete Arbeit in getrennte und
wohldefinierte Pakete zu verpacken und zu isolieren. Manchmal vielleicht
auch mehrere gleichzeitig, das wird plötzlich möglich denn jetzt kann
man mühelos die Übersicht behalten. Du weißt auch vorher nicht ob sich
zwischenzeitlich auf dem master nicht doch irgendwas tun wird oder getan
werden muß was absoluten Vorrang hat vor irgendwelchen unvollendeten
Features und Du weißt nicht immer wann das woran Du gerade arbeitest
wirklich fertig sein wird.
Und da ein Branch exakt nichts kostet außer einer Sekunde Zeit um sich
nen Namen dafür auszudenken weiß ich auch nicht warum man darüber
überhaupt diskutieren muß als wäre es etwas bedeutsames oder gewichtiges
das man abwägen muß.
Bernd K. schrieb:> das wird plötzlich möglich
Ich mag diese sagenhaften Übertreibungen einfach nicht.
Deshalb schrieb ich, das git keine Religion ist. git macht vieles anders
als andere (*), aber es gibt nur ganz wenige Dinge, die man nicht hätte
ohne git bereits ganz genauso hätte handhaben können, wenn man nur
gewollt hätte – und Branches sind nun wahrhaftig keine Erfindung von
git, auch leichtgewichtige Branches sind es nicht. "git add -e" würde
ich da schon eher drunter zählen, wenngleich ich auch das Pendant dazu
bereits ohne git erledigt habe, wenn es mal nötig war.
(*) Wobei man sich dabei streiten kann, ob das nun wirklich sinnvoll,
nützlich oder gut ist.
Jörg W. schrieb:> Bernd K. schrieb:>> das wird plötzlich möglich>> Ich mag diese sagenhaften Übertreibungen einfach nicht.
Da war nichts sagenhaftes dran. Ich schrieb sinngemäß: Wenn Du alle
angefangenen Sachen in separate Schachteln legst und beschriftete Zettel
dranmachst kannst Du mehrere davon haben und trotzdem die Übersicht
behalten. Ich weiß nicht was daran "sagenhaft" sein soll. Ich halte das
für ein völlig triviales Konzept, manche nennen es Ordnung, es wundert
mich daß Dich das so aus der Fassung bringst und Du das mit Religion
assoziierst.
> Deshalb schrieb ich, das git keine Religion ist.
Ich weiß nicht was Du immer mit Deiner Religion hast. Git ist ein
mächtiges Werkzeug zur Herstellung von Ordnung und Überblick. Genauso
wie damals die Erfindung des Dateisystems mit Ordnern und Dateien, da
denkt heute keiner mehr drüber nach, wenn Du nen Ordner brauchst legst
Du schnell einen an. Fertig. Da kommt keiner mit "Religion" oder "leg
keine Ordner an um der Ordner willen". Völlig absurd! Die ganze
Diskussion ist absurd.
Bernd K. schrieb:>> Deshalb schrieb ich, das git keine Religion ist.>> Ich weiß nicht was Du immer mit Deiner Religion hast.
Dass du es so präsentierst, als wäre es die wichtigste Erfindung seit
geschnittenem Brot.
> Git ist ein> mächtiges Werkzeug zur Herstellung von Ordnung und Überblick.
Ja. Eins. Von vielen.
> Genauso> wie damals die Erfindung des Dateisystems mit Ordnern und Dateien
Schon wieder so eine Übertreibung – also nicht das hierarchische
Dateisystem, sondern die Darstellung, git wäre in seiner Bedeutung damit
gleichzusetzen.
Aber lass uns damit aufhören, wir werden uns nicht einig. Ich benutze
git, weil es an den Stellen, wo ich es benutze, halt das
Kollaborationswerkzeug ist. Ich tu aber nicht so, als könnte ich nicht
auch das gleiche in SVN oder Mercurial (oder wahrscheinlich Bazaar, das
kenne ich nicht näher) erledigen können. Letztlich läuft die
Entwicklung auch mit git (oder Mercurial) in praktisch allen Szenarien,
die ich bislang gesehen habe, auf einen "Master" hinaus der als Quelle
bzw. Senke für pull / push benutzt wird. Das ist kein wirklich
dramatischer Unterschied zum zentralen Server, der halt bei SVN zwingend
war außer, dass man Commits erstmal lokal machen kann (und muss). git
macht vielleicht ein paar Dinge schöner (git add -e nannte ich schon),
andere Sachen macht es nicht so schön. Warum man bspw. den Fehler von
CVS wiederholen musste, dass Verzeichnisse nicht versionierbar sind
(sodass man wieder mit Platzhaltern a la .gitkeepme anfangen muss), wird
mir ein Rätsel bleiben.
Jörg W. schrieb:>> wie damals die Erfindung des Dateisystems mit Ordnern und Dateien>> Schon wieder so eine Übertreibung – also nicht das hierarchische> Dateisystem, sondern die Darstellung, git wäre in seiner Bedeutung damit> gleichzusetzen.
Ist es auch.
Git (hier stellvertretend als verbreitetstes DVCS, nicht jedoch zentrale
serverbasierte) fügt jedem lokalen hierarchischen Dateisystem sofort
zwei weitere Dimensionen hinzu (eine Dimension ist die Zeit und eine
weitere Dimension sind beliebig viele alternative Zeitlinien) durch die
man genauso mühelos navigieren kann wie durch Ordnerstrukturen.
Du hast also zusätzlich zu deinem verzweigten Dateibaum auch einen
verzweigten Zeitbaum und zusammen spannen die einen Raum auf in dem
massenhaft Platz ist um Zustände und Vorgänge abzubilden die ohne das
nicht möglich wären oder nur unvollkommen und umständlich nachzubilden
wären hätte man das nicht.
Das muss man sich nur zunutze machen. So kann man seine verschiedenen
Arbeiten und angefangene Teilaufgaben übersichtlicher vor einem
ausbreiten und ordnen und voneinander isolieren. Vor allem sich in der
zweiten genannten Dimension vollkommen mühelos bewegen zu können
erleichtert vieles und lässt alte eindimensionale SVN-Gewohnheiten
verkrampft und unendlich umständlich und zeitraubend erscheinen.
Ich habe schon oft gesehen, dass für alles mögliche Branches angelegt
werden.
In größeren Teams ist das Mergen dann eine richtige Herausforderung. Der
Merger weiß meistens ja nicht, welche Version von welchem Branch jetzt
für die Zukunft übernommen werden muss.
Für viele Sachen braucht man gar keine eigenen Branches, da reichen auch
Tags.
Dahin kann man zurückrollen, wenn man sich verrannt hat. Oder zum
Beispiel auch im Nachhinein Branches auf früheren Produktionslieferungen
erstellen, wenn man wirklich mal was fixen muss. Oder man legt Tags an,
um später vergleichen zu können.
https://git-scm.com/book/en/v2/Git-Basics-Tagging