Wo wir sind, ist vorne, Folge 25, heute geht's um Git.
Herzlich willkommen bei Wo wir sind, ist vorne.
Frontend-Fakten-Frotzeleien.
Der Late-Night-Frontend-Talkshow rund um Webdesign und Entwicklung.
Es reden sich um Head und Kragen, HTML-Fundamentalist Moritz Gießmann und JavaScript-Jongleur Konstantin Groß.
Heute zu Gast, Webworker und Git-Versteher Michael van Engelshoven.
Herzlich willkommen bei Wo wir sind, ist vorne, Folge 25.
Wir haben das Viertelhundert voll gemacht oder keine Ahnung, ob man das so nennt.
Wie man das so sagt, ja.
Ja, genau.
Heute zu Gast, wie ihr schon gehört habt, Michael van Engelshoven.
Hi.
So, und wir reden heute über Git, weil wir haben ja in den vergangenen Folgen schon öfter mal gesagt, wir sind beide Git-Anwender, der Konstantin und ich, aber wir haben immer mal wieder das ein oder andere Problem gehabt und wir haben uns heute Verstärkung geholt, um da mal ein bisschen drüber zu sprechen, ein bisschen Licht in unser Git-Dunkel zu bringen.
Hoffentlich.
Ja, auf jeden Fall.
Wir haben große Hoffnungen in dich.
Genau.
So, sollen wir direkt zum Getränk voranschreiten.
Ja, was hast du denn, erzähl mal.
Ja, ich habe mal wieder ein Augustiner-Helles. Das habe ich jetzt öfter, weil es ist eine ganze Kiste bei mir angekommen und ich trinke ja nur beim Podcast oder beim Stream Bier und auch nicht immer und deswegen hält das jetzt die nächste.
Okay, also bis zu Folge 29.
Ja, stimmt. Vielleicht, ich weiß nicht, ob ich bei jedem Stream, naja, wie auch immer.
Ach nee, im Podcast 29, da sieht man meine mathematische Kenntnisse wieder.
Ja.
25 und 24 ist 29.
Genau.
So, Konstantin, was trinkst du?
Ich trinke heute Wasser und Almdudler.
Ja.
Ich habe das blöde Gefühl, schon wieder krank zu werden und da wollte ich meinem Körper nicht noch zusätzlich Alkohol zumuten.
Okay, gut. Michael?
Hast du auch was?
Ich bin ja hier im Kölner Heizdrucksgebiet und darum trinke ich in Kölsch.
Ah, okay.
Es war heute ein Mühl in Kölsch von der Malzmühle.
Sehr gut. Habe ich auch noch nie gehört. Also, dann zum Roll oder so?
Zum Roll.
Zack.
Und, äh.
Dazu brauchen wir mal eine zweite Lasche. Das ist der Soundeffekt.
Remote, ja.
Ja.
Ich überbrücke mal.
Man könnte den Eindruck gewinnen, dass wir
nur Gäste und Gästinnen mit Fun im Namen oder mit Verwandtschaftsverhältnis einladen.
Was ja fast dasselbe ist.
Ach so, die müssen nicht miteinander verwandt sein, aber mit einem von uns.
Weil wir hatten jetzt Gerrit van Aken, meinen Bruder und jetzt dich.
Aber dem ist natürlich nicht so. Also, es darf auch jemand anders mal kommen.
Vielleicht stimmt's ja auch.
Das müssen wir jetzt durchziehen.
Müssen alle anderen wieder ausladen, die wir vielleicht schon eingeladen haben.
Wer weiß.
Könnte früher oder später zu einer Herausforderung werden.
Ja.
Oder wir müssen halt dann auf holländisch senden.
Da gibt's, glaube ich, mehr Auswahl an Fans, wenn wir dann holländische Gäste einladen.
Ja.
Mensch, ja.
Wollen wir mal zur Retro kommen?
Oder hast du noch was zur Begrüßung?
Nee, noch nicht.
Es steht noch was.
Es steht noch was im Trello in unserem Geheimen.
Ja.
Ich muss hier auf einem Bildschirm hin und her switchen.
Ach ja, genau.
Mensch, Michael, erzähl doch mal kurz irgendwie, was du so tust, dass man dich so ein bisschen
einordnen kann für die, die dich jetzt irgendwie noch nicht kennen. Also, was machst du? Was
tust du? Wer bist du?
Ja, ich bin der Michael von Engelshofen. Ich bin JavaScript-Entwickler bei der Brambits GmbH
in Köln und bin da angestellt als Lead-Entwickler. Mach eigentlich hauptsächlich Frontend-Arbeiten
von morgens bis abends. Und ja, um das auch schön mit meinen Kollegen zu teilen,
benutze ich da auch regelmäßig Git.
Cool. Okay, das sind ja super Voraussetzungen für unsere heutige Git-Folge. Und dann können
wir jetzt zur D-Retro.
Ja, wir werden jedes Mal, ich würde nicht sagen, besser anders von der Grammatik her.
Naja.
Ja, Mensch.
Ich fang an, ne?
Ja.
Haben wir jetzt rumgeschoben. Ich bin heute so verstrahlt und verplant. Und der Grund kommt
jetzt auch gleich als erster Retro-Punkt. Mein Computer ist kaputt. Also mein Arbeitsrechner
hier im Homeoffice, den ich also sowohl zum Arbeiten als auch für unsere Streamer-Reihen
und Podcaster-Reihen brauche. Und der hat sich nach unserem letzten Stream letzten Freitag
hat er sich einfach verabschiedet am nächsten Morgen. Fuhr er nicht mehr hoch, hat nur einmal
kurz geklackert. Und dann erscheint 0-0 auf dem Mainboard und dann macht er das gleiche
Spiel von vorne und das macht er so lange bis...
Der vorletzte.
Das war der vorletzte.
Der vorletzte.
Ach, wir haben ja am Mittwoch nochmal gestreamt. Ja, stimmt. Ja, sonst ging es ja gar nicht.
Sonst wäre der nächste Retro-Punkt gar nicht entstanden. Genau. Ja, und jetzt ist immer
diese blöde Frage. Alles natürlich abgekabelt und rausgebaut und versucht hochzufahren.
Entweder Mainboard oder CPU. Es werden noch Wetten angenommen, aber es ist immer so blöd
zu debuggen, wenn man jetzt nicht gerade selber irgendwie das durchmessen kann und so.
Ja, und ich kann auf jeden Fall sagen, was der Konstantin selbst nicht sieht, gerade, weil
er in meine Richtung guckt, ist, hinter ihm steht der Rechner auch. Ich kann ihn sehen.
Komplett ausgehöhlt, ausgeweidet.
Power, genau. Man kann reingucken. Sieht nicht so gesund aus gerade.
Nee, ist auch nichts. Ist nichts mehr drin.
Ja, genau. War es, war es? Bist du damit...
Ja, das war... Also mehr hat sich in meinem Leben irgendwie nicht ergeben, die letzten zwei Wochen.
Sonst war einfach gar nichts. Es ist nichts passiert, außer dass der Rechner kaputt gegangen ist.
Okay, na, das ist ja auch ein okayes Leben, glaube ich, wenn man sonst keine Probleme hat.
Wenn es sonst nichts gibt, oder? Ja.
Ja, mein...
Ist ja schon drama genug.
Ja, richtig.
Ja, stimmt. Das kann schon durchaus sehr dramatisch sein, je nachdem, wie wichtig das als Arbeitsgerät ist.
Ja, also in unserer Branche, würde ich mal sagen. Also ich kann es auch auf Papier schreiben, aber...
Naja, du hast ja offenbar noch ein Ersatzgerät, sonst könnten wir gerade nicht aufnehmen.
Den Laptop. Den Laptop, von dem ich letztens schon erzählt habe, dass er mir fast abgeraucht wäre.
Naja, noch lebt er.
Deswegen hoffe ich mal erhält. Aber deswegen bin ich heute so ein bisschen gehandicapt.
Habe halt nur einen Bildschirm, der auch noch relativ klein ist und muss hier zwischen Trello und Jitsi und Studio Link und Reaper und allem hin und her schalten.
Also ich bin, also ja, wie gesagt, ein bisschen durch den Wind.
Was auch gehandicapt war, war, Achtung, krasse Überleitung, mein MacBook beim letzten Stream, nämlich dadurch, dass Konstantins Rechner, der immer unseren Stream so schön gemacht hat, mit seiner wahrscheinlich dicken Grafikkarte drin, kaputt ist, mussten wir jetzt umsteigen auf mein Gerät.
Ich habe den MacBook Air mit Apple Silicon M1 Prozessor zum ersten Mal an die Grenzen gebracht, wo ich dann dachte, okay, jetzt ist irgendwie Ende, weil wir wollten streamen und wir haben da mehrere Stunden damit verbracht, das einzurichten und hatten sehr große Probleme damit, den Stream stabil zu kriegen.
Vor allem der Sound hat große Probleme gemacht, hat immer wieder rumgeknackst. Und das war wohl später im Stream auch nochmal so, aber immer dann, wenn ich irgendwie noch ein extra Browserfenster aufgemacht habe.
Also es war wohl wirklich ein Ressourcenproblem, so Rendering-seitig.
Aber ist doch mal ein schönes Benchmark, oder? So ein neues Gerät und dann erstmal austesten, wo liegen denn die Grenzen?
Ja, also Live-Video-Rendering scheint, also auf dem Prozessor, scheint irgendwie schwierig zu sein. Ich rendere sonst irgendwie nicht viel Video, also das ist ein Fall, den hätte ich jetzt sonst nicht getestet.
Aber es gibt vielleicht Abhilfe, weil, wie ich gerade gesagt habe, auf dem Prozessor, die aktuelle OBS-Version, die wir da einsetzen, die hat das, die unterstützt noch nicht den M1-Prozessor.
Das heißt, man kann kein Hardware-Video-Rendering machen, sondern es läuft halt echt alles auf der CPU.
Aber der aktuelle Release-Candidate von OBS, 27 ist das, glaube ich, Release-Candidate 2, da kann man das wieder einschalten.
Und wir haben es jetzt noch nicht getestet, aber sind guter Dinge, dass das vielleicht was bringt dann am Ende.
Also mein erster Test war von 20% CPU beim Recording runter auf 6 oder 7.
Allerdings im Stream haben wir es noch nicht getestet. Wir müssen mal gucken, vielleicht geht es ja dann trotzdem.
Und ich meine, dann ist dem Spaß ja wieder keine Grenze gesetzt, weil dann wird das Ding so verwendet, wie man es verwenden soll und die Hardware wird ausgenutzt und dann kann man damit doch streamen.
Also wir werden es sehen.
Ansonsten, vielleicht läuft ja bis zum übernächsten Stream mein Rechner wieder tatsächlich.
Und für den nächsten Stream, vielleicht kann man das auch schon vorwegnehmen, haben wir ja nicht irgendwelches Codesharing geplant, sondern dann machen wir was anderes.
Sollen wir es schon spoilern, was wir vorhaben?
Ja, du kannst es ruhig spoilern, ich habe es schon vergessen.
Achso, wir streamen ja am Dienstag statt am Mittwoch nächste Woche.
Achso, das wusste ich noch gar nicht.
Nein, nein, nein.
Da hast du mich doch gefragt.
Ich habe dich gefragt, aber du hast gesagt, du musst das noch abklären.
Ich habe doch gesagt, das passt, habe ich nicht gesagt.
Also Moritz, das passt.
Okay, das wird ein bisschen verrückt, weil ich, ja, das müssen wir auf jeden Fall erzählen, weil ich als mittlerweile sehr, sehr neuer Apple-Fanboy und früher Apple-Kritiker, wir haben uns überlegt, wir könnten die Apple-Keynote am Dienstag kommentieren.
Und der Konstantin, und es ergibt sich eine interessante Geschichte draus, weil, wie gesagt, ich bin ein frischgebackener Fanboy.
Und der Konstantin ist immer noch sehr Apple-kritisch.
Und ich glaube, das könnte interessant werden.
Aber auch nicht mehr so kritisch wie früher.
Wie wir da drauf reagieren.
Allerdings, ich glaube, streamen dürfen wir es nicht.
Wir dürfen es nicht einblenden oder so.
Wir können quasi nur drauf reagieren.
Machen wir einen Live-Kommentar.
WWSV-Reacts.
Und vielleicht interessiert es jemanden, vielleicht interessiert es auch einfach gar niemanden.
Es macht nichts.
Dann sind wir einen Tag näher am Affiliate bei Twitch.
Das könnte vielleicht ganz witzig werden.
Also, ich glaube, gerade weil nicht nur Fans dann zuschauen, sondern eben auch du dann als Kritiker, sage ich mal, könnte das durchaus interessant werden, wie unterschiedlich die Reaktionen zu bestimmten Sachen ausfallen.
Oder du sagst, what the fuck, was ist das für ein Quatsch?
Und dann sage ich, ah, das ist total geil, weil du musst hier, das ist total super.
Gucken wir mal.
Schauen wir mal.
Vielleicht wartet der Konstantin mit seinem neuen Rechner oder seinen Reparaturen dann noch bis nach der Keynote.
Ach so, ach so.
Ja, ich habe ihm auch schon gesagt, das ist jetzt ein super Zeitpunkt, um es richtig zu kaufen.
Ja, mal gucken.
Mal gucken.
Ja, okay, gut.
Dann, äh, Michael, du hast auch einen Retro-Punkt mitgebracht.
Ich habe auch einen Retro-Punkt mitgebracht.
Wir sind gerade ein bisschen dabei, unsere Website von Bootstrap-Utilities auf Tailwind umzubauen.
Nicht nur, weil es hip ist.
Ich glaube auch fest daran, dass alles besser werden wird.
Gerade diese Mischung aus, das gibt es als Bootstrap-Utility, das nicht.
Und dann habe ich jetzt so CSS und Utility-Klassen gemischt.
Darum geht es mir aber nicht.
Davon wollen wir einfach weg und haben jetzt schon einen Haufen Utility-Klassen angepasst.
Und du scrollst durch die Seite und denkst dir, hm, sieht das noch alles richtig aus oder nicht?
Dann habe ich mir gedacht, boah, was echt cool wäre, wäre jetzt so ein Visual Regression-Test.
Aber ich habe jetzt keine Lust, hier tagelangen Aufwand rein zu investieren.
Kriege ich das nicht irgendwie schnell hin?
Ich weiß, dass andere Teams bei uns sowas in der Art schon mal gemacht haben, aber die nutzen eine Plattform dafür und das war mir alles ein bisschen zu aufwendig.
Und dann habe ich ein bisschen rumgegoogelt und Puppeteer kennt ihr wahrscheinlich, nehme ich an.
Das ist halt ein Headless Chromium quasi, den ich mit JavaScript steuern kann.
Und der ist ja auch in der Lage, Screenshots zu machen.
Mit dem Parameter Full Page True kann ich mir sogar ein Screenshot von der gesamten langen Seite machen lassen.
Also nicht nur von der Bildschirmgröße.
Und dann bin ich auf eine Extension für Jest gestoßen.
Jest, das ist so ein Testrunner.
Die nennt sich Jest Image Snapshot.
Und auch wenn ich jetzt kein großer Fan von Snapshot-Testing bin, was Image Snapshot quasi machen kann, ist, dass er sich diesen Buffer nimmt,
also den Puppet, den er gemacht hat, und den er als Bild ablegt.
Und in einem erneuten Durchlauf kann er das quasi nochmal machen und zeigt mir dann ein Diff an zwischen Stand Alt und Stand Neu.
Und dann war es plötzlich total easy, Unterschiede an der Seite zu finden, tatsächlich auch noch Wax zu finden,
wo Klassen nicht richtig transformiert worden sind und ja, große Angst erst gehabt.
Und dann, ich glaube innerhalb von einer Stunde oder so, hatte ich ein Skript, was mir das vergleichen konnte.
Cool.
Ja, große Erleichterung.
Zwei Probleme gab es.
Selbst geschrieben?
Selbst, ja, es ist, keine Ahnung, 30 Zeilen Testdatei.
Okay.
Letztendlich gehe ich einfach hin und schnappe mir die Sitemate-XML, die generiert da rumliegt.
Also, es ist eine statische Seite mit Gatsby und dann nehme ich mir einfach die Sitemate-XML,
parse dann mir alle URLs raus und rufe dann eine nach der anderen auf und mache den Vergleich.
Cool.
Also, ich kenne das aus Beyond Compare.
Kennt ihr das, Beyond Compare?
Oh ja, tatsächlich.
Also, es ist zum Dateien vergleichen.
Also, natürlich hauptsächlich irgendwie Textdateien.
Ich habe zwei verschiedene Codestände und vergleiche die dann miteinander und kriege dann so die Diffs angezeigt,
wie bei Git oder wie so GOEs für Git auch.
Und man kann das aber auch benutzen für sogar Audiodateien und für Bilder.
Und da habe ich das auch schon genutzt, eben eine Seite von einem auf ein anderes System, ich weiß gar nicht mehr, was es war, umgestellt und dann das miteinander verglichen.
Also, das ist echt ganz praktisch, wenn man sowas hat.
Ja.
Aber cool.
Zwei Probleme gab es letztendlich.
Wir haben auf einer der Unterseiten haben wir so eine Durchlaufanimation, wo so ein Text durchläuft.
Der hat natürlich nicht immer exakt die gleichen Animationsframe.
Das heißt, häufig hast du dann so ein False Positive, nein, False Negative, wo der sagt, oh, die Seite ist kaputt und da guckst du rein und dann siehst du nur, dass der Text irgendwie so vier Pixel weiter oben ist oder so.
Und dann weißt du Bescheid, okay.
Kannst du da irgendwie so einen Threshold einstellen vielleicht, dass der das dann gar nicht bemerkt?
Ja, du kannst tausend Sachen einstellen.
Ich habe mich aber aufgrund des Zeitdrucks da nicht wirklich tief mit beschäftigt.
Also, du kannst ihm sagen, wie viele Pixel abweichen dürfen, ganz prozentual angeben.
Aber mir ging es halt wirklich darum, erstmal alles zu sehen, weil ich habe zum Beispiel auch die Underlines von den Links, die sind in den Pixel nach unten gewandert und das wollte ich schon sehen,
an welchen Seiten da vielleicht was kaputt gegangen ist, etc.
Ja, und bei uns werden alle Bilder gelazy loaded, also wenn das scrollt, sind die erst so geblurrt und werden dann nachgeladen.
Das sorgt auch dafür, dass der Papettierer nicht immer exakt dasselbe Bild sieht.
Also hast du dann häufig so bei den Bildern, dass du sagst, guck mal, das ist nur ein Ticken unscharf und das schon nicht mehr.
Und da hast du dann auch so ein paar Fehler, die eigentlich keine sind.
Aber ansonsten hat es super geklappt, also ich war echt erleichtert.
Cool. Darf ich kurz fragen, wie macht ihr das mit dem, dass es erst geblurrt dargestellt wird?
Weil da habe ich mal irgendwie so eine API gesehen, die das quasi für einen macht, die dann irgendwie so irgendwie nur 3, 4 kW groß oder sowas war das Bild dann quasi.
Es sind quasi vier Pixel, die dann aufgespannt werden.
Oder ist es ein eigenes Request oder in der Seite mit drin?
Letztendlich, also wir machen das nicht, das bringt Gatsby quasi mit.
Aber was die machen, ist, wie du schon sagst, die machen eine verkleinerte Version des Bildes, die ist, ich glaube, 5x5 Pixel oder so.
Und die wird dann tatsächlich schon als Base64 ins HTML entledet.
Ah, okay, Base64.
Das heißt, du hast eigentlich gar keinen Request, wenn die Seite lädt.
Okay, perfekt.
Und wenn du dann da hinscrollst, geht dann, ja letztendlich ist es eine Rated Componential, die das macht, geht dann hin und lädt dann das richtige Bild nach.
Cool.
Ja, dann übernehme ich nochmal.
Oder warst du fertig?
Ich bin fertig.
Sehr gut.
Genau.
Ich habe noch einen zweiten Retropunkt.
Ich weiß, es ist immer schwierig, über sich selbst was Gutes zu sagen.
Ich tue mir da immer schwer damit.
Es ist irgendwie zu cool, als es irgendwie ein bisschen zurückzuhalten.
Ich bin in den Dankesbereich eines Web-Development-Buchs gelandet, also im Vorwort sozusagen.
Und das könnt ihr euch ja mal anschauen.
Und zwar ist es das Web-Development-Glossary von Jens Meiert.
Und da habe ich irgendwann letztes Jahr mal, also es ist schon länger her, ich habe jetzt erst herausgefunden, dass ich da drin bin.
Also tatsächlich, ich glaube, es kam letztes Jahr schon raus.
Und zwar habe ich da Glossar-Einträge hinzubeigesteuert über Twitter, die mit Y beginnen.
Danach wurde gesucht.
Mir sind da relativ viele eingefallen.
Ich habe da zum Beispiel geschrieben, Jan, YQL, YSlow.
Vielleicht erinnert sich der eine oder andere noch dran.
Also Jan ist ja jetzt gar nicht so alt, aber YQL und YSlow sind schon eher ältere Sachen.
Genau.
Und da habe ich ein bisschen Dank dafür bekommen.
Es hat mich sehr gefreut.
Und da könnt ihr mal reinschauen.
Also es hat mich, ja, ich bin gerührt.
Und ich habe das mit dem Jens auch geschrieben über Twitter und da hat er gemeint, ah, das ist wie es zum ersten Mal.
Ja, nach dem ersten Mal, das zweite Mal, das lässt er nicht so lange auf sich warten, hat er gemeint.
Jetzt bin ich gespannt, was für Bücher ihr schreibt und wie ich euch dabei unterstützen kann.
Genau.
Ja, cool.
Dann?
Vielleicht?
Kommt, vielleicht?
Die Property der Woche.
Hat sogar gepasst, Mensch.
Ja, ich gebe mir Mühe.
Also es ist mit der Grammatik, das, naja.
Ja, die Property der Woche hat dieses Mal unser Gast mitgebracht.
Schieß los.
Ja, wahrscheinlich schlagen viele den Hände beim Kopf zusammen.
Die Hände beim Kopf zusammen.
Sehr gut.
Für mich war es tatsächlich Object Punkt Entries.
Gefühlt bin ich eigentlich immer am Bleeding Edge der Mascript Releases und nutze, was nur geht und lasse es halt vom Babel transpilieren.
Aber in einem Code Review bin ich über Object Punkt Entries gestolpert.
Auf den ersten Blick habe ich es gar nicht wahrgenommen.
Ich dachte nur, was macht der Mensch da?
Der muss doch irgendwie noch auf den Key zugreifen.
Wieso geht das nicht?
Was ich dann irgendwann gesehen habe, der macht gar nicht Object Keys, der macht Object Entries.
Und da kriege ich statt einfach nur den Key und ich muss mein Value dann selbst nochmal über den Property Namen accessen, bekomme ich einfach beide reingereicht.
Wie ich das jetzt aus RAM da mit To-Pairs und From-Pairs oder so kenne.
Und da habe ich erstmal recherchiert.
Seit wann gibt es das denn?
Und ja, das gibt es tatsächlich seit erst 2017.
Ist quasi im selben Release gekommen wie die Object Punkt Values.
Und ja, ist somit auch gut supported und ja, werde ich jetzt nur noch benutzen.
Spart einem viel Arbeit.
Ja cool, man lernt immer wieder was Neues dazu.
Auch wenn man denkt irgendwie, man kennt schon alles.
Da hatten wir es auch, ich bin jetzt echt immer verwirrt, war das im Stream oder im letzten Podcast, wo wir es auch darüber hatten.
Oder war es vielleicht sogar nur im Vor- und Nachgeplänkel, wo wir uns drüber unterhalten haben.
Ich glaube, das war wegen Overflow X und Y im Stream, wo ich auch gesagt habe, da dachte ich, das kenne ich schon.
Das kommt übrigens vielleicht demnächst nochmal als Property der Woche.
Jetzt heute nicht, weil der Michael dankenswerterweise was mitgebracht hat.
Und ihr kriegt bei uns immer nur eine Property pro Woche und dann müsst ihr ja wieder zwei Wochen warten, bis ihr die nächste kriegt.
Mit Spenden könnte man das übrigens vielleicht verkürzen.
Vielleicht, vielleicht gibt es dann auch wieder einen Spam-Spot, man munkelt.
Obwohl, wir haben eine Spende gekriegt, ne?
Ach, echt haben wir wieder?
Ja, vielleicht reicht die ja für einen Spam-Spot. Wir haben ein Bier gesponsert bekommen.
Okay, okay, dann, ja, wer weiß. Vielleicht sind es zwei Wochen.
Jetzt kriege ich keinen hin.
Was?
So spontan.
Nein, nein, nein, das machen wir ja, das machen wir nicht.
Das machen wir vielleicht im Stream mal.
Genau.
Genau, übrigens, wenn ihr euch wundert, worüber wir reden beim Stream, wir sind seit einer Weile bei Twitch unter twitch.tv slash www.iv.
Gerne mal vorbeischauen und da streamen wir ein- bis zweimal die Woche so ein bisschen Frontend, Afterwork, Aftershow-Party.
Ja, ja, genau, das habe ich jetzt mal gesagt. Der Stream ist so ein bisschen die Aftershow-Party des Podcasts, habe ich so das Gefühl.
Wir nehmen uns immer vor, wir machen irgendwie, oh, hier, Live-Coding und hier und da und am Schluss reden wir dann irgendwie über Entwicklersorgen und machen Gruppentherapie und kriegen private Fragen gestellt und so.
Ist aber auch mal ganz gut.
Ja, doch, finde ich auch. Also macht Spaß, den Austausch da zu haben.
Okay.
Dann können wir jetzt, oh, Mensch, sind wir schnell heute. Bisschen über 20 Minuten und wir kommen jetzt weit unter der Schrie.
Hier ist WWS IV mit dem Tagesthema.
Zur Grammatik.
Jetzt habe ich den, habe ich den, äh, den, äh, den Jingle in dich reingespielt, sorry.
Ich habe in den Jingle genommen.
Also, so rum. Ja, gut.
Mit der Verzögerung ist das verzeihbar.
Was, Verzögerung?
Ja, wir haben ja mit Sicherheit irgendwie, wir sind nicht exakt live mit Soundfordern.
Circa 4 Millisekunden.
Ja, wir haben es ausgemacht.
Also, die spiele ich für mich.
Genau, also, jetzt aber Thema. Und zwar, heute geht es um Git.
Und zwar, äh, wie ich vorhin schon gesagt habe, ähm, wir haben immer mal wieder unsere kleinen oder größeren Problemchen gehabt mit Git.
Und, ähm, der Michael ist heute da, um uns ein bisschen tiefer in die Materie einzuführen.
Und ich glaube, wenn ich so richtige Erinnerungen habe, wollte er auch am Anfang so ein bisschen, äh, so die Grundkonzepte, ähm, mal ein bisschen näher drauf eingehen.
Habe ich das richtig verstanden, Michael?
Ja, ich habe mir gedacht, das ist ein guter Einstieg. Ähm, ich wollte jetzt aber keinen Frontalvortrag halten.
Ich dachte, wir unterhalten uns einfach ein bisschen drüber und, ähm, gucken mal so, wem welche Konzepte bewusst sind.
Also, ich denke mal, bekannt sind die meisten Sachen wahrscheinlich irgendwie jedem.
Ähm, aber mir persönlich hat es einfach geholfen, den Zusammenhang so ein bisschen zu verstehen.
Und dann haben sich einfach so ein paar Sachen für mich erschlossen, warum Sachen gehen können oder nicht gehen können oder warum ich in gewissen Situationen Fehler bekomme.
Und, ja, deswegen dachte ich, wäre das vielleicht ein guter Einstieg.
Ja, sehr gerne. Also, hilft uns bestimmt auch sehr weiter.
Ja, das ist ja das Ziel heute, ne?
Genau.
Das ist ja quasi eine Art Therapiestunde.
Genau, mal wieder.
Ja, letztendlich sind wir ja dazu gekommen, ihr hattet in irgendeiner Folge, ich glaube, es war auch in einer Retrospektive, Rebase-Probleme gehabt.
Und als ich das gehört habe, habe ich gedacht, Moment mal, die Situation kenne ich.
Die haben wir bei uns in der Firma auch sehr häufig.
Und, ähm, da kann man was gegen tun.
Äh, also nicht, ähm, ich helfe dir, das Problem zu lösen, sondern, ähm, wir reden mal darüber.
Das Verständnis zu schaffen, was das Problem eigentlich ist.
Das Verständnis, genau.
Ja, lass einfach anfangen.
Äh, ich schmeiß direkt mal so ein Konzept in den Raum, ähm, und zwar, das ist das Thema Hashing.
Mhm.
Könnt ihr mit dem Begriff was anfangen?
Ähm, äh, das ist das, was man auch sieht bei den Commits, dieser, ja, Commit-Hash halt, der da, diese, diese, äh, alphanumerischen Zeichenketten, die quasi einen Commit bezeichnen, eindeutig.
Äh, genau.
Ähm, und auch die Dateien an sich werden im Hintergrund irgendwie gehasht, ne, und sind dann da in dieser, in diesem Index als Hash abgelegt.
Äh, genau.
Richtig?
Ähm, aber die Frage ist halt, wie kommt so ein Hash zusammen?
Ja, also man, man spricht auch teilweise so vom kryptografischen Hashen, ähm, da gibt's verschiedene Algorithmen, äh, den SH1 oder SH256 Algorithmus, ähm, der Clou an dem Ding ist eigentlich, ähm, dass ich, ähm, wenn ich denselben Input in das Ding reinschiebe,
dann bekomme ich immer exakt denselben Output aus dem Teil raus, ja, das heißt, wenn ich jetzt, ähm, mal mit einem Objekttyp anfange, und zwar mit dem Blob-Objekt, was wir so in Git haben, äh, das ist quasi meine Datei, also mein Dateienhalt, und der wird quasi durch die, die Hash-Funktion von Git gejagt, und dann kommt da so ein eindeutiger Hash raus.
Und, ähm, solange die Datei dieselbe ist, ist auch der Hash immer derselbe.
Gehe ich aber hin und ändere wirklich nur ein Zeichen, mache einen Zeilenumbruch weg, lösche ein Leerfeld raus, irgendwas total Triviales, ändert sich dieser Hash komplett.
Ja, und, ähm, so kann ich quasi dann halt auch die Objekte quasi ablegen, indem ich die einfach hashe und den Hash quasi als Dateinamen benutze.
Ja, ähm, wenn man zum Beispiel mal das Git-Verzeichnis mal reingucken würde, ähm, und, äh, jetzt nicht in der Situation ist, wo alles schon gepackt ist, sondern in einem relativ frischen Repository, ähm, dann sieht man quasi, dass da einfach Dateien angelegt werden, die haben den Hash als Dateinamen.
Und, ähm, ja, wenn man direkt mal im Editor reinguckt, dann sind die schon ein bisschen komprimiert, ähm, aber es gibt einen Git-Befehl, mit dem kann man die sich dann quasi auslesen, ähm, und, ja, so legt quasi Git unsere Dateien ab.
Was, äh, weißt du das, ähm, was nutzen die denn intern? Ist das SHA-1? Weil das sieht mir relativ kurz aus, das sind ja, glaube ich, 40, äh, Zeichen, ne?
Ja, genau, es ist, es ist, glaube ich, noch SHA-1, äh, die sind aber dabei, ähm, auf, äh, den 256er zu wechseln.
Ich meine aber, das ist noch nicht durch, weil da müsste eigentlich der Commit-Hash auch länger sein.
Es ist halt ein relativ schwieriges Thema, weil wenn du natürlich den Algorithmus umstellst, dann sind die Hashes alle anderen.
Ja, klar.
Und, ähm, ich hab da mal so ein bisschen recherchiert, wie es da aussieht, und da gibt's dann irgendwie Übersetzungstabellen von altem Hash auf neuem Hash, die dann in den Repositories noch gelegt werden müssen.
Ah, ich glaube, da steht uns eine spaßige Zeit bevor.
Klingt, als könnte da viel kaputt gehen auch dabei.
Wie ist das mit der Kollision bei SHA-1?
Weil irgendwo hab ich, hab ich so im Vorrecherchieren gelesen, so von denen, ja, das ist quasi total unwahrscheinlich, dass zwei gleiche Dateien denselben Hash, äh, zwei unterschiedliche Dateien denselben Hash erzeugen.
Aber ich meine, bei 40 Zeichen, irgendwo sind ja auch Grenzen, und da kann's ja schon Kollisionen auch geben, theoretisch, oder?
Ja, ich kann dir jetzt die Wahrscheinlichkeit der Kollision nicht nennen, aber, ähm, man hat ja irgendwann gesagt, äh, SHA-1 ist nicht mehr kryptographisch sicher, weil die Wahrscheinlichkeit zu hoch ist, ähm, und dann kann natürlich potenziell ein Risiko bestehen, ne?
Weil, wenn jetzt jemand hingeht und eine Datei manipuliert und das auf diese Weise schafft, dass exakt wieder derselbe Hash rauskommt, ne?
Ähm, ähm, und hab dann da halt Chart, äh, Chartcode eingefügt. Ähm, was ich mir jetzt schon extrem komplex vorstelle, die Datei so zu editieren, dass ich funktionalen Chartcode da eingebaut habe, der auch nicht direkt erkannt wird, aber die Datei auch nicht unten einfach ein gigantisches Kommentar mit irgendwelchen Random-Zeichen hat, damit ich nachher wieder auf diesen Hash rauskomme.
Ähm, weil es würde ja auch direkt auffallen, ähm, aber das Potenzial ist da, und da haben wir gesagt, das wollen wir nicht, ähm, eingehen, das Risiko.
Wenn wir jetzt aufs, aufs, aufs Quantum, Quantum Computing, äh, drauf zusteuern, dann wird's halt vielleicht doch leichter, sowas berechnen zu lassen, also ein Skript, das quasi so lange den Code verändert, bis der Code noch funktional ist, aber trotzdem diesen Hash ergibt.
Genau, und nach der KI da drauf sitzen hast, die nur sagt, der Code sieht gut aus.
Genau.
Ja, ach, wer will das schon, diese ganze Moderna-Technik, ne?
Ja, ähm, wenn ich jetzt auch so eine Datei gehashed hab, äh, das bezieht sich ja nur auf den Content, da hab ich ja gar keinen Dateinamen drin, und, ähm, das fand ich eigentlich ganz witzig, äh, dass die Dateinamen erstmal nichts mit dem Dateinhalt zu tun haben.
Ja, ähm, quasi das nächste Level von Objekten, weil gibt es quasi das Tree-Objekt, und das Tree-Objekt repräsentiert quasi ein Verzeichnis, ne?
Und das, ähm, müsst ihr euch vorstellen wie einfach eine Liste von Hashes, und, ähm, da steht noch ein Typ dran, und zwar ob es ein Blob ist oder ein Tree, und somit kann ich jetzt quasi auch verschachteln, wenn ein Tree-Objekt auf ein anderes verweist, kann ich quasi, ja, auf andere Ordner verweisen.
Und, ähm, ja, da steht dann quasi der Hash des entsprechenden Objekts, und dahinter steht dann der Dateiname, und, ähm, so merkt sich Git quasi, wie sieht das Verzeichnis aus, und, ähm, über den Link auf das Blob-Objekt mit Hash-XY zum Beispiel, ähm, würde, ähm,
, ähm, eher dann jetzt zum Beispiel den Inhalt der Index-HTML mit dem Dateinamen Index-HTML referenzieren, ne?
Was dann im Umcash-Loss halt auch bedeutet, wenn ich irgendwo in einem Unterordner noch eine Datei habe, die exakt den gleichen Inhalt hat wie die Index-HTML, dann, ähm, haben die auch den gleichen Hash.
Und somit habe ich die Datei auch nur einmal in der Repository.
Mhm, ah ja.
Ne?
Also gerade so diese ganzen, gut, Git-Keep-Dateien haben sowieso keinen Inhalt, aber, äh, was, was könnte es denn noch geben?
Also irgendwie, ich habe die HT-Access-Dateien vielleicht, die verzeichnete sperren, und da habe ich 20.000 davon in meinem Projekt, dann hätte ich die trotzdem aber in Git nur einmal.
Und die belegen dann auch nur einmal den Speicher. Also klar, die Dateien existieren trotzdem mehrfach, ne? Aber ich habe sie nicht noch 20.000 Mal zusätzlich in diesem Git-Ordner drin.
Praktisch.
Ähm, genau, das hast du nicht. Ähm, der Clue ist natürlich, äh, du machst jetzt Änderungen in deinem Verzeichnis, dann ändert sich deine Datei, hat einen neuen Block, äh, einen neuen Hash-Dead-Block-Objekt, und, ähm, der steht dann als Ersatz in dem Tree-Objekt, ähm, aber alle anderen Referenzen verweisen halt immer an.
und auf die gleichen Block-Objekte, ne? So hast du nicht mit jedem Commit, äh, ein linear wachsendes, ähm, ein linear wachsendes, ähm, ein linear wachsendes Speicherverbrauch, ne?
Ja, ja.
Du speicherst nur das neu, was sich wirklich geändert hat, ne? Ja, also hast du eigentlich immer einen Diff, ne? Also du speicherst nur das Diff, nur den Unterschied.
Äh, äh, genau das tue ich nicht. Ähm, ich speicher wirklich die Block-Objekte, ne?
Okay.
Du nimmst den Dateienhalt, hashst den, speicherst das Ding ab und referenziert das in ein Tree-Objekt. Und dieses Tree-Objekt, das ist quasi einfach Text,
kannst du dir vorstellen, wie wenn du LSA machst, so eine Art von Liste. Äh, äh, dieses Tree-Objekt wird quasi auch wieder gehashed,
und somit habe ich auch hier wieder mein eindeutig referenzierbares Objekt, ne?
Und der Clou ist dann halt, wenn ich jetzt meine Datei ändere, nur ein Zeichen, habe ich ja gerade schon gesagt, ändert sich ja der komplette
Hash, der ja dann in dem Tree-Objekt aktualisiert wird, welches wieder gehashed wird, und somit ändert sich auch dieser Hash komplett, ne?
Aber so bist du halt, ja, auf der sicheren Seite, dass du halt nichts überschreibst, wenn du die Kollision nicht triffst.
Ja, würde mich mal interessieren, ob das schon, ob das bekannt ist, ob das irgendwo in einem Git-Projekt schon mal passiert ist.
Wäre, glaube ich, ein schwer zu findender Fehler wahrscheinlich.
Ja, am besten noch so ein Git-Körnel, äh, ein Linux-Körnel oder sowas.
Auch, ja.
Hat 30 Jahre keiner gemerkt.
Ja, letzter Objekt, lass mich doch kurz auf den letzten Objekt-Typen kommen, dann sind wir mit dem Thema Hashing eigentlich durch.
Das ist wirklich das Objekt, was jetzt jeder kennt, und zwar ist das das Commit-Objekt.
Das Commit-Objekt zum Beispiel verweist dann auf ein Tree-Objekt.
Und so weiß ich, hey, bei dem Commit XY war der Dateistand folgender, weil ich habe das Tree-Objekt, was eindeutig verwiesen ist.
In dem Tree-Objekt habe ich mein Blob-Objekt, was eindeutig verwiesen ist.
In dem Commit-Objekt habe ich dann noch andere Sachen, wie zum Beispiel den Autor des Commits, der dann da mit Name und Mail-Adresse drin steht.
Und dem Timestamp, wann der Commit gemacht worden ist.
Ich habe aber auch einen Committer da drin stehen.
Ja, also in den meisten Fällen steht da zweimal Michael drin.
Okay.
Und ich habe den Eltern-Commit drin stehen, ja, der vor dem Commit quasi liegt.
Und dann natürlich unsere schöne Commit-Message, die sehr aussagekräftig ist.
Hoffentlich.
Ja, das Ding wird dann halt quasi auch wieder gehasht.
Und ja, das ist quasi das, was wir als Commit-Hashter sehen.
Das ist wirklich der gehasht-Inhalt dieses GIP-Commit-Objekts.
Wer da mal Bock hat, mal reinzuschauen, ihr könnt einfach in eurer Git-Repository reingehen.
Mit dem Befehl git cat-file und dem Parameter pay-for-print und dann einfach mal ein Commit-Hash angeben.
Dann seht ihr den Inhalt des Commit-Objekts.
Und da könnt ihr euch dann einfach durchhangeln.
Dann nehmt ihr einfach mal, ihr werdet dann einen Tree sehen.
Dann nehmt ihr einfach mal den Hash von dem Tree-Objekt.
Führt den gleichen Befehl aus mit dem Hash vom Tree-Objekt.
Dann seht ihr mal den Inhalt von so einem Tree-Objekt.
Und so kann man sich bis in die kleinste Spitze von euren Dateibaum hangeln und da mal so reinschauen.
Und ja, was ich halt interessant fand, da sind einfach Textdateien.
Die sind jetzt komprimiert, damit sie halt nicht so viel Platz verschlucken.
Auch wenn man da reinguckt, das ist echt dann irgendwie gar nicht mehr so komplex.
Wenn man sieht, was für eine Macht-Git mit dieser simplen Struktur irgendwie dann schafft.
Wer sich das ausgedacht hat, ein Genie.
Ja, ich bin immer wieder fasziniert, ja.
Ja, Linus, oder?
Ja.
Oder hat sich das, glaube ich, ausgedacht?
Linus Pauls, ja.
Tatsächlich, ja.
Ja.
Okay, was kommt denn als nächstes? Hast du noch was?
Ich habe.
Ich weiß nicht, wie wir jetzt genau vorgehen.
Ja, genau, wir haben ja irgendwann noch so einen Fragenblock, sage ich mal.
Aber wir wollten ja erstmal so ein bisschen die Konzepte machen.
Genau.
Also ich hätte jetzt noch zwei Konzepte, die jetzt aber, glaube ich, relativ schnell durchgehen.
Da würde ich jetzt noch weitermachen.
Ja, ja, klar.
Wir müssen gar nicht viel moderieren. Sehr gut.
Ich sage mal, die Fragen haben wir uns im Vorhinein schon mal angeguckt, die so existieren.
Und ich habe schon irgendwie versucht, die überall so ein bisschen in meinen Notizen einzubauen.
Kommen wir dann hoffentlich auch dran vorbei.
Sehr gut.
Ja, nächstes Konzept, was ich als wichtig empfinde.
Das ist der sogenannte DAG.
D-A-G.
Okay, hast du noch nie gehört?
Nee, habe ich noch nie gehört.
Also das Akronym war mir nie bewusst.
Was das ausgeschrieben bedeutet, ist Directed Acyclic Graph.
Auch das habe ich nie gehört.
Ein gerichteter, a-züglicher Graph.
Das ist ein Graph.
Ihr kennt nur Graph Zahl, aber das ist es nicht.
Nein, ein Graph im Sinne von verknüpften Knoten.
Also eine Tree-Struktur ist euch sicherlich bekannt.
Ein Baum und ein Graph hat den Unterschied, dass es auch wieder zusammenwachsen können.
Also ich habe quasi so ein Netz.
Und das ist quasi die Art und Weise, wie Git quasi die Commits organisiert.
Jeder Commit zeigt zum Beispiel zu seinem Parent Commit.
Und so baut sich dann halt nachher dieser Graph auf.
Ich habe mehrere Commits, die auf dasselbe Eltern-Elemente zeigen können.
Das ist, wenn ich zum Beispiel eine Branch anfange.
Ja, weil ich den ersten Commit in der Branch mache.
Da habe ich dem originalen Zweig einen Commit habe und eine Branch einmache.
Da habe ich zwei Commits, die auf dasselbe Eltern-Elemente zeigen.
Ah, okay.
Und so weiß ich dann, wann das abgezweigt ist von dem Main-Branch zum Beispiel.
Ja, genau.
Du weißt erst mal, wann das abgezweigt worden ist.
Und wenn wir uns noch mal an das Hashing zurückerinnern,
in dem Commit-Objekt steht ja auch der Parent-Commit drin.
Das heißt, wenn ich da einen anderen Hash eintrage,
dann ist auch der Commit-Hash von meinem Commit auch plötzlich wieder ein ganz anderer.
Und ja, ich habe auch tatsächlich die Möglichkeit, dass ein Commit auf mehrere Parents verweisen kann.
Und zwar ist das die Situation, wenn ich einen Merch-Commit mache.
Dann habe ich zwei Eltern-Elemente, weil ich zwei Branches zusammengeführt habe.
Er verweist dann nachher wieder nur noch auf ein Tree-Objekt,
weil da hat er dann den Verzeichnisbaum zusammengelegt.
Aber ich habe zwei Eltern-Commit.
Interessant.
Also das habe ich mir echt noch nie so, nicht mal versucht vor Augen zu führen.
Man nutzt es einfach irgendwie und sieht es so und irgendwie macht man sich gar keine Gedanken, wie das funktioniert.
Aber ich finde es echt interessant, das mal so zu erfahren.
Ich glaube, ich muss die Folge hinterher noch mal anhören, um es richtig zu verstehen.
Und dann mal deine Commits angucken.
Genau.
Ja, genau, quasi noch mal mitmachen.
Also währenddessen in den Git-Repository reinschauen, während dem Hören und dann das noch mal nachvollziehen.
Das kann ich jetzt natürlich nicht nebenher machen.
Ich habe es eben schon versucht, aber...
Ich auch, aber ich bin auch gescheitert.
Sonst kann ich nicht mehr zuhören.
Genau, aber das mache ich im Anschluss vielleicht echt noch mal.
Wenn wir die Folge veröffentlicht haben, höre ich es mir noch mal an und versuche es noch mal nachzuvollziehen.
Also es ist auf jeden Fall...
Ich glaube, man muss es dann auch mal anfühlen.
Wichtig ist hier einfach, oder was ich als wichtig empfinde, ist halt einfach sich bewusst zu sein,
wenn ich eine Datei verändere, dann kriegt die einen neuen Hash.
Ja, der neue Hash muss in den Tree-Objekt stehen, weil sonst ist die Datei nicht verwiesen.
Ja, damit ändert sich definitiv der Hash des Tree-Objekts.
Und da der Hash wiederum im Commit steht, ändert sich auch der Hash des Commits.
Und so entstehen halt Situationen, wie ich plötzlich andere Commits habe, wenn ich ein Rebase gemacht habe.
oder ich Commits meinen Kollegen vielleicht auch mal unterm Hintern wegziehe,
weil der plötzlich auf einem ganz anderen Hash unterwegs ist, als ich, der irgendwie gedacht hat,
hey, ich rebase den Branch mal schnell.
Und der Konstantin hat das aber nicht mitgekriegt und guckt noch schön auf die alten Hashes drauf und verweist da drauf.
Und ja, da komme ich dann halt nachher in eine ganz blöde Situation.
Ich glaube, über Rebase sprechen wir nachher auch nochmal, ne?
Ja, definitiv.
Da haben wir schon aufgeschrieben.
Ja, genau.
Ja, Hashes sind schön und gut, kann sich nur keine Sau merken.
Ja, deswegen letztes Konzept, was ich so habe.
Ich habe es jetzt hier als Referenzen stehen.
Ich glaube, mit geht heißt es auch wirklich Refs.
Ich stelle mir das einfach immer vor als Etiketten, die an Commits dranhängen,
damit ich mich an die Commits erinnere.
Und das sind letztendlich die Namen unserer Branches zum Beispiel.
Ja, weil ich Master habe.
Dann ist es einfach nur ein Label, was auf Commit A, B, 2, 5 verweist.
Und wenn ich jetzt hingehe und einen neuen Commit mache,
dann gibt es nichts weiter, wie die Commit zu erzeugen mit dem neuen Hash.
Und dann nimmt er das Label und klebt das an den neuen Commit dran.
Das heißt auch, wenn ich jetzt hingehe und auf irgendeine Branch bin
und aus dem jetzt einen neuen Branch ableite,
dann ist das letztendlich erstmal auch ein Etikett
und die hängen alle an dem selben Commit dran,
solange ich noch keine Commits in der Fall gemacht habe.
In der Vorstellung hat man so einen Branch so als eigenes Ding.
Und eigentlich ist es aber, klebt der Branch nur da und markiert.
Hier, ich bin der Main-Branch und ich bin der Feature-Branch.
Okay, interessant.
Und ich finde, wenn du das jetzt weißt,
dann gehst du vielleicht auch einfach mal hin und missbrauchst so einen Branch,
um einfach dir irgendwo einen Label dran zu hängen,
wo du sagst, hey, das Ding möchte ich mir mal kurz merken.
Falls ich hier jetzt was kaputt mache, dann kann ich da immer noch zurückgeben.
Ja.
Also wie ein Tag dann, oder?
Das ist so mein Escape-Hatch.
Okay, aber wie ein Tag, oder?
Ein Tag ist auch nichts anderes.
Es gibt aber die, ich glaube, sie heißen einen Annotated Tag,
wo du dann auch wieder einen Hash hast, um das zu signieren.
Habe ich, ehrlich gesagt, noch nie benutzt oder wenn unbewusst.
Aber ja, auch ein Tag ist quasi ein Label.
Genau.
Aber auch der Branch eines Remotes zum Beispiel ist auch nur ein Label.
Wenn du zum Beispiel hingehst und sagst, gib Fetch,
dann geht er ja hin und zieht sich alle Objekte von deinem Remote in dein Repository rein.
Und dann siehst du zum Beispiel sowas wie origin slash master.
Und das ist auch quasi einfach nur ein Etikett, was auf den Commit verweist,
wo der Master, der das Remote gesagt hat, hey, da ist gerade mein Master-Branch.
Und da kannst du quasi auch einfach hingehen und sagen,
okay, jetzt gehe ich hin und möchte meinen Master-Etikett
an den selben Commit dran kleben.
Und das ist das, was man letztendlich mit dem Befehl git reset macht.
Das hört sich irgendwie so an, als würde ich irgendwas kaputt machen
und zurücksetzen.
Aber git reset ist quasi der Befehl, der das Label, auf dem du gerade bist,
irgendwo anders dran kleben kann.
Ah, okay.
Ja, jetzt ist gleich schon Licht aufgegangen jetzt so von der Vorstellung her.
War das immer so ein Buch mit sieben Siegeln?
Jetzt ist mir das schon klarer mit dem Reset.
Genau.
Git reset hat noch so drei Parameter.
Du kannst ja sagen, git reset hard, soft oder mixt.
Mixt ist der Standardfall.
Wenn du hart sagst, dann schmeißt du halt alles weg und setzt das Ding zurück.
Das ist was, was ich ganz gerne nutze, wenn ich sage, hey, ich weiß,
das, was mein Master hier lokal hat, das ist komplett veraltet.
Und ich habe auch sicherlich da nichts drin gemacht.
Da gehe ich eigentlich immer hin und mache dann ein git reset hard
dann auf den Region Master.
wenn man kein Merch, äh, kein Problem machen kann.
Ja.
Und, ähm, manchmal brauchst du aber auch, ähm, nochmal den Stand, ähm, von deinen Änderungen.
Du willst ihn nicht wegwerfen, sondern willst einfach nur mal das Label in Schritte zurück machen.
Dann würdest du sagen, irgendwie git reset hat tilde eins zum Beispiel,
weil du sagst vom hat einen Commit zurück.
Und, ähm, tilde eins.
Ich möchte aber die ganzen geänderten Dateien, ähm, ich möchte die nicht verwerfen,
sondern ich möchte die vielleicht nochmal einzeln committen oder so.
Weil ich festgestellt habe, hey, was ich gerade committet habe,
wollte ich nicht als einen großen Commit machen.
Ah, und da kommen wir nämlich dann schon zu meiner großen Problematik
mit dem Squashen, glaube ich auch so, ne?
Es ist nochmal ein bisschen was anderes, aber eben genau dieses,
äh, ich will da nochmal zurück und, und ich hab da was falsch gemacht
und ich kann das eben, ich kann das wieder richten.
Weil das war bei mir, das hat bei mir nämlich eine Zeit lang gedauert,
äh, dass ich verstanden habe, okay, wenn ich was kaputt gemacht habe
und falsch, äh, committet habe, das ist dann nicht einfach,
das ist dann in der Datenbank und das kann ich nie wieder ändern, ja,
sondern, sondern ich kann da halt wirklich wieder zurück taggen
und das verwerfen und wenn ich das dann wieder einchecke,
dann ist es auch tatsächlich in GitHub zum Beispiel dann geändert.
Oder ich hatte mal den Fall, dass ich, äh, nachträglich, ähm,
den, den Namen und die E-Mail-Adresse, die da eingestanden, äh,
da war halt die falsche eingestellt in dem, in dem GUI, das ich genutzt habe
und ich wollte nicht, dass die private E-Mail-Adresse da, äh, in dem Repository getaggt ist
und selbst das ließ sich dann alles rückwirkend nochmal überschreiben
und das war, äh, ja, hat, ja, hat eben gedauert zu wissen, dass das so funktioniert
und dass das nicht unwiederbringlich ist, was ich da war.
Ja, genau, letztendlich lässt sich alles überschreiben, ne?
Also, du kannst ja auch, wenn du ein Commit absetzt, kannst du mit dem, ähm,
ähm, ähm, Parameter, minus minus author, also Autor, ähnlicher Autor,
kannst du angeben, wer der, der Commit, ähm, Autor ist, ne?
Das, ähm, nutze ich hin und wieder mal, wenn, keine Ahnung, der Chef reinkommt
und sagt, ändere mal hier den Text, dann gehe ich hin und sage,
ja, gut, das habe nicht ich mir ausgedacht, dass der Text geändert wird.
Ah, okay.
Und dann kann ich auch da mal jemand anders da dran schreiben.
Ah, ja.
Ich stehe trotzdem als Committer drin, ne?
Eben bei den Hash-Geschichten habe ich ja gesagt,
im Committer-Objekt steht Autor und Committer drin.
Ich bin trotzdem der Committer, also man sieht, dass ich das Committed habe,
aber ich habe die Möglichkeit zu sagen, ja, aber geschrieben hat es ein anderer.
Ja, cool.
Es trifft mir aber total ab, wir waren beim Thema Referenzen.
Ich habe jetzt gerade auch schon nach dem Head gesprochen.
Head ist so ein Spezialfall und zwar repräsentiert Head quasi,
wo ich gerade bin auf meiner Platte.
Also wenn ich jetzt einen Branch auschecke,
da zeigt Head auf dem Branch-Namen drauf.
Und Head hat aber die Besonderheit,
der muss nicht immer auf dem Branch zeigen,
sondern der kann auch auf dem Commit zeigen.
Ich kann ja auch sagen, get check out und durch den Commit-Hash,
wo dann Gitte mal sagt, Achtung, du bist im Detached-Hash-Status.
Ach, das ist das dann, okay.
Das ist dann, wenn mein Head gerade auf dem Commit zeigt.
Es wird deshalb gewarnt, weil wenn ich jetzt einen neuen Commit mache,
dann wird der zwar an diesem Commit, auf dem ich gerade bin, drangehangen,
also der Commit, auf dem jetzt gerade der Head ist,
wird dann als Eltern-Element in dem neuen Commit eingetragen.
Aber es hängt kein Label dran.
Und wenn ich jetzt wieder sage, get check out Master zum Beispiel,
dann habe ich mir den Hash hoffentlich irgendwo hingeschrieben.
Weil den musst du nicht schnell wiederfinden.
Gibt es aber auch Tricks, kommen wir vielleicht gleich nochmal zu.
Ja, Master ist wie jeder andere Branch-Name auch einfach nur ein Branch, ein Label.
Wir hatten die Frage über Twitter, was ist mit dem Namen Master, Main, muss er jetzt Main heißen, darf er Main heißen?
Politisch haben wir gesagt, gehen wir da jetzt gar nicht drauf ein, bevor wir uns die Finger verbrennen.
Aber was hat das denn für Implikationen?
Muss ich da irgendwas berücksichtigen, wenn ich es dann doch umbenennen will?
Erstmal ist es nur ein Label, das heißt machen, warum nicht? Kannst du machen.
Du kannst dann bei GitHub und Co. einstellen, was so der Default-Branch ist,
dass wenn das dann jemand klont oder auf dein Repository geht,
das dann auch direkt dann auf den neuen Branch-Namen ist.
Wo man halt mal drüber nachdenken muss, ist, was man sonst noch so für Tools einsetzt.
Und ob in diesen Tools vielleicht irgendwo Master hardgecodet ist,
weil das ja bislang immer schon der Tag-Name war für den Haupt-Branch.
Ja.
Also ich habe bei mir auf der Platte schon das ein oder andere Shell-Script oder Git-Alias,
wo ich wirklich dann, keine Ahnung, lösche Branches, die schon gemerged sind.
Wenn du aber sagst, Git-Branch ist minus minus Merge,
also dann listet der ja auf, was alles gemerged ist,
dann listet der auch den Master auf, weil der keine losen Comments mehr hat,
die noch nicht im Master sind quasi.
Und da wissen wir natürlich nicht, dass der gelöscht wird.
Und ja, da habe ich dann halt...
Also mir ist bewusst, dass ich einige Spezialfälle habe,
die auf dieses Master-Tag zielen.
Bevor man halt diese Umstellung macht, muss man halt sicher gehen,
dass man nicht irgendwelche Tools abkoppelt.
Ja, bei GitHub zum Beispiel ist es jetzt auch mittlerweile Standard,
dass sie den Branch Main nennen.
Genau, also nochmal zusammengefasst.
Also es steht dem eigentlich überhaupt nichts im Wege,
weil es eigentlich nur ein Name ist,
außer man hat irgendwas Externes, was eben darauf unter Umständen zugreift.
Also keine Ahnung, wenn ich jetzt irgendwie automatisch irgendwas mit Branches mache
oder so und mit Jenkins oder keine Ahnung, was für ein Tool irgendwie dranhängt
und das einen bestimmten Branch auscheckt und damit was tut,
dann sollte man natürlich da schauen, dass das da dann auch überall glatt gezogen wird.
Aber ich denke, das wird man dann sofort merken, wenn der Bild fehlschlägt.
Oder keiner mehr passiert.
Oder dann ein Commit, den du in den Master gemacht hast, zu keinem neuen Release führt,
weil die Pipeline immer guckt, bin ich im Master-Branch, wenn ich einen Release machen will.
Aber nein, ich bin im Main-Branch, also muss ich nichts tun.
Genau.
Okay, nee, aber das klingt ja schon mal echt gut, weil das heißt, so Git-seitig gibt's überhaupt gar kein Problem.
Eigentlich ist es nur mehr so das Drumherum, was man sich eventuell drumherum gestrickt hat.
Ja.
Ja, cool.
Genau.
Das heißt, kann man einfach umstellen, wenn man möchte.
Was ist denn der Befehl dafür, dass wir das kurz genannt haben,
falls jetzt jemand sagt, oh ja, muss ich gleich machen?
Ähm.
Sorry, aber jetzt überfall ich dich hier.
Nee, aber es gibt keinen Befehl für, hey, ich stelle vom Master auf Main um.
Du checkst den Master-Branch aus und leitest davon einen neuen Branch ab, den du Main nennst.
Und dann ist das ja erstmal ein zweites Label, was am selben Commit klebt.
Achso, und dann löscht du einfach den Master-Branch.
Ah, okay.
Ich dachte, da gibt's vielleicht irgendwie so ein Renaming oder so irgendwie Rename-Command,
das das dann automatisch macht.
Aber wenn das nicht an Bord ist, könnte ja in der Tat sein.
Das ist ein Git-Branch.
Mal gucken.
Minus-MV oder so, weiß ich jetzt gerade nicht.
Ich hab ehrlich gesagt, das ist noch nicht sehr häufig, Branch ist unbenannt.
Äh, Git-Branch-M und dann neuer Name.
Ja, ja.
Sehe ich jetzt gerade hier.
Ich hab's vermutet.
Gut, also sogar noch einfacher.
Da hättest du noch so darauf gestoßen, hey, das hättest du auch in sechs Commands lösen können.
Statt?
Also etwas in Git zu machen, wo ich mir immer denke, ja, klar ist es immer cool,
alle Argumente zu wissen und dann in zwei Commands irgendwo zu landen, anstatt in fünf.
Okay.
Na gut, aber sechs Commands sind ja auch schon viel.
Was war denn dann vorher?
Ein eigenes Shell-Skript, oder?
Ähm, das war ja so ein Training-Ding.
Da ging's darum, dass du drei Feature-Branches hast und du sollst die alle drei nacheinander
ge-rebased in das Remote bewegen.
Und er hat dann gesagt, ja, super, du hast es in zwölf Kommandos geschafft.
Äh, das geht aber auch in sechs.
Ich denke mal, ja, cool, die Herausforderung ist interessant, aber letztendlich das Wichtige
ist einfach, dass ich zum Ziel komme, nichts kaputt mache und zum Schluss.
Ja, solange der Weg nicht ewig dauert, genau, ist es, glaube ich, wichtig, dass man zum Ziel
kommt und nicht, äh, wie kurz der Weg da ist, weil ich glaube, so ein langer Weg ist vielleicht
auch okay, vielleicht auch dann für das eigene Hirn ein bisschen verständlicher.
Man muss auch nicht alles auswendig kennen, jeden, wie du gerade schon gesagt hast, irgendwie
jedes, äh, jeden Parameter.
Wobei es nicht schlecht ist, wenn man jeden Parameter kennt, ne?
Ja, ich, ich fürchte, bei Git musst du sehr viel kennen.
Ja.
Ja, äh, da auch nochmal meine, meine Empfehlung, äh, die Seite git-scm.com, also Git-Source-Control-Management
heißt es, glaube ich, ausgesprochen, äh, das ist so die Hauptseite für Git, ähm, da gibt's
einmal die Dokumentation, wenn ich auf Slash-Doc gehe und, äh, die haben auch ein Buch,
aus Slash-Book, das gibt's sogar, manche Deutsch, für Leute, die sich vielleicht vor Englisch
scheuen, äh, das ist auf jeden Fall sehr informativ.
Und, äh, da kann ich auf jeden Fall empfehlen, mal reinzuschauen, wenn man sich fragt, ähm,
wie war nochmal das richtige Argument oder halt das Git-Buch halt, wenn man generell nochmal
das verstehen möchte, wie das alles funktioniert.
Cool.
Ja, da landet man auch automatisch schon drauf, wenn man, äh, Git-Sachen googelt, also finde
ich, landet man relativ häufig da, ja.
Ja, aber ich finde, das ist halt auch wirklich eine, eine gute Dokumentation.
Also, da bin ich immer fündig geworden.
äh, ich sag mal so, Man-Pages hab ich immer so ein bisschen Angst vor, weil, ja, das finde
ich nie, was ich suche, ähm, oder es ist, es ist mir nicht so direkt eingängig.
Ja, manchmal hat man ja so der Anspruch, hey, ich möchte drauf, so als Entwickler, als
scrollt man eh nur durch und guckt sich die Exempels an, ähm, das finde ich geht bei Man-Pages
immer schwierig, aber ich finde, die Git-Dokumentation sehr gelungen.
Ja, ich möchte so Doku eigentlich auch nicht, also ich meine, gut, Man-Pages gibt's auch im Web, aber
der klassische Befehl ist ja Man und dann, äh, den Befehl, zu dem man was wissen will und das
auf der Kommandozeile zu lesen, das ist sehr mühselig. Also, da google ich lieber danach und lande
genau auf dem Spezialartikel, der sich um meinen Befehl dreht.
Also, da bist du direkt im Stack-Overflow, wo du die Kommandozeile einfach probieren kannst.
Ja, richtig. Genau, das ist doch das Schönste.
Das, äh, habt ihr übrigens in eurer Visual Studio Code-Folge verpasst, das, äh, die wichtige
Extension, ähm, in der man einfach einen Suchbegriff eingeben kann und dann sucht er bei Stack-Overflow
und pastet automatisch von der beantworteten Antwort den Code in deinen Visual-Folge.
Echt? Weißt du, weißt du gerade, wie die heißt?
Nee, leider nicht.
Dann können wir so verlinken. Okay, finden wir raus.
Aber das fand ich sehr bezeichnend.
Oh ja.
Es gibt ja tatsächlich, äh, Menschen, die so vorgehen.
Ja, ähm, was ich immer gut finde, ist, ähm, wenn ich Dinge visualisieren kann, ähm, am liebsten
im Kopf, äh, jetzt gerade so ein Graph, wo sind jetzt Commits, wo zweigt was ab oder so, ähm,
und wenn nicht, dann auch gerne auf dem Bildschirm, ähm, das machen ja die, die Tools, die Guis, die man so
verwenden kann, ähm, das ist ja auch schon ganz gut, ähm, wer sich so ein bisschen vor den Guis scheut, äh, kann das aber auch auf der Konsole erreichen.
Und zwar kann ich, wenn ich, wenn ich git log sage, ähm, kann ich zum Beispiel mit Minus Minus Graf, kann ich mir quasi, ja, ja, den Eskiart Grafen anzeigen lassen, der Commits.
Wenn ich das dann noch kombiniere mit Minus Minus One Line, damit ich nicht die kompletten Commit Messages immer sehe,
sondern wirklich nur in einem Zeiler, das ist dann in einem Graph tatsächlich übersichtlicher, ähm, dann ist das schon sehr hilfreich.
Und dann am besten noch mit dem Parameter Minus Minus All, dass ich nicht nur ab dem Commit, auf dem ich gerade bin, weiter nach unten alles sehe,
sondern wirklich alle Zweige, die auch neben mir liegen oder vielleicht schon weiter vorne sind, äh, dann finde ich persönlich das immer sehr hilfreich, wenn ich da mal so gerade reingucke, wo bin ich gerade, was hat mein Kollege gepusht, ähm, sind da Commits drin, die ich
zufällig auch schon habe, ähm, oder, ähm, gerne hätte, das finde ich immer sehr hilfreich. Ähm, da kommen wir auch vielleicht in die Show Notes, ich hab so ein Kind alias, der heißt bei mir einfach HIST wie HISTORY, äh, der ist noch mit einem anderen
ähm, Format ein bisschen ausgestattet, vielleicht packt man den einfach an die Show Notes mit dabei. Ja, gerne. Ähm, dann ist es ein bisschen praktischer, wenn man sich nicht
einen Wolf tippt, sondern, ich sag einfach bei mir immer, GIT HIST, das ist irgendwie der zweitäufigste Befehl nach GIT-Status, ähm, ja, finde ich zum Beispiel sehr hilfreich.
Ja, gerade schon mal, ähm,
drauf angesprochen, die Geschichte, die ich da mit dem, hey, das hättest du auch in sechs Commits schaffen können,
hatte, ähm, es gibt, ähm, so zwei Lerntools, die ich ganz cool finde im Web, ähm,
äh, das ist einmal
learngitbranching.js.org, ähm, das ist quasi
so ein Ding mit so Lernaufgaben,
also da werden dir quasi Herausforderungen gestellt,
das wird aber halt auch sehr schön visualisiert.
Das ist kein echtes GIT, was da läuft,
sondern die simulieren das so ein bisschen,
also du musst jetzt zum Beispiel nichts adden
und keinen Text schreiben, sondern du sagst einfach
git commit, dann ist da ein neuer commit zum Beispiel,
ähm, aber das ist ganz gut, wenn man
sich einfach mal dann diesen Branch zeigen lassen
kann, wenn ich ein Merch mache, was passiert,
wenn ich Rebase mache, was passiert, ähm,
das finde ich sehr, sehr schön gelöst.
Das kommt mir bekannt vor, das habe ich schon mal gesehen,
ich glaube, das ist vielleicht sogar in unserer
Geilteile-Liste, äh,
schon mit drin, muss ich
gerade mal kurz gucken, oder habe ich es vielleicht
sogar schon mal erwähnt, ich weiß nicht genau,
aber das, das habe ich vor kurzem, äh,
mal gesehen, das ist an mir vorbeigescrollt, ja.
Das Coole ist, das bringt halt auch so ein
Sandbox-Modus mit, das heißt, wenn ich irgendwie
einem Kollegen was erkläre oder so, kann man
das auch sehr gut mal dafür nutzen, um das so
während ich erkläre, zu visualisieren.
Cool.
Ja, und dann gibt es so noch ein Git-School,
Visualizing-Git heißt das, das funktioniert sehr
ähnlich, hat halt nicht so dieses Aufgaben-Prinzip,
ähm, was ich da finde, ist, dass es mit den
Remotes so ein bisschen hübscher,
ansehlicher ist,
besser verständlich.
Ha, muss man einfach mal reingucken.
Ja.
Schauen wir mal rein.
Und ihr auch.
Okay.
So, ähm, das waren die Konzepte,
habe ich das richtig verstanden?
Also, wir sind schon, wir sind schon ein bisschen
weitergegangen, genau.
Ähm, sollen wir mal auf die eine oder andere
Frage, äh, eingehen, die wir hatten oder die aus
der Community kamen? Wir haben ja eine jetzt auch
schon beantwortet, mindestens eine. Ähm, wir haben
jetzt schon so ein bisschen über Tools gesprochen
und GUIs, ähm, und vielleicht kommen wir mal
zur ersten Frage, äh, das ist eine, die ich mir
gestellt habe, ähm, und ich stelle sie jetzt auch
nochmal, also, was würdest, was für ein Tool
beziehungsweise welchen Workflow würdest du
empfehlen, so für Dummies, ähm, wenn man
möglichst wenig kaputt machen können will, sozusagen?
Also, wenn man, wenn man möglichst wenig
Ärger haben will, was für ein Git-Workflow
würdest du empfehlen und was für ein Tool
würdest du, ähm, empfehlen?
Ja, es kommt halt immer so ein bisschen drauf an,
was ich machen will. Es gibt sehr viele
GUIs da draußen mittlerweile, äh,
Sostree, Git-Kraken, äh,
keine Ahnung, fallen jetzt gerade
nicht alle ein. Ähm, was ich bei denen immer so
schwierig finde, also ich habe früher auch immer
nur auf die Teile abgezielt, ähm, fand das dann
aber immer ein bisschen schwierig, wie das zu
nutzen ist und dann sind halt auch so Sachen wie
ein Rebass dann gerne in die Hose gegangen, weil
ich nicht verstanden habe, was passiert. Ähm, seit
ich mich ein bisschen tiefer damit beschäftigt
habe, bevorzuge ich in der Tat dann doch die
Konsole, weil das wirklich so, ja, so nah am
Konzept ist. Es ist alles so verständlich und
auch wenn man ein bisschen mehr tippen muss,
finde ich, ist, ähm, nachvollziehbarer, was
passiert, weil man halt nicht irgendeinen
GUI hat, was das alles so ein bisschen verschleiert und
unter der Haube dann zehn Kommandos ausführt, ähm, und
du weißt dann nicht, was alles passiert ist. Ähm, wenn
ich aber jetzt z.B. relativ Einsteiger bin und erst mal einfach was committen will, weil ich gerade, keine Ahnung, in einem GitHub Repository mitmachen möchte, um mich da so ein bisschen zu beteiligen, dann finde ich in der Tat die GitHub for Desktop App ganz gut. Die kann nicht viel, also so ein, keine Ahnung, interaktiven Rebase oder so, kriegst du damit nicht hin. Aber ich sag so, für die Basics funktioniert die super. Und das ist ja letztendlich Dateien adden in die Stage, dann kommit daraus erzeugen.
und dann kommit daraus erzeugen, das irgendwo hin pushen und wieder pullen. Und gerade für Einsteiger finde ich es auch völlig legitim, wenn man dann mit Merge-Commits arbeitet, um sein Repository auf den aktuellen Stand zu bringen. Da muss man auch nicht der krasse Rebase-er sein, der sagt hier, so eine feine Linie ist meine History. Ist das nicht schön?
Das wäre jetzt witzigerweise meine nächste Frage gewesen, Rebase oder Merge-Commits? Also ich glaube auch, das Einfachere sind Merge-Commits, wenn einen der Graph nicht interessiert.
Du musst weniger nachdenken und ja, deswegen, du kannst dich auch erst mal dann auch wirklich auf die wichtigen Themen konzentrieren, nämlich dich irgendwo daran beteiligen und den Commit auf das Remote bringen.
Vielleicht können wir die Begriffe nochmal abgrenzen, so für Dummies wie mich. Was ist jetzt genau mit Merge-Commit gemeint und gegen Rebase?
Genau, also der Unterschied ist, Merge-Commit-Rebase. Bei dem Merge-Commit, also sagen wir, die Grundsituation ist, ich habe hier zwei verschiedene Stände und ich möchte zusammenführen.
Ich habe zum Beispiel, mein Kollege hat in der Master-Branch auf dem zentralen Repository was hingepusht und ich möchte das jetzt bei mir drin haben.
Da kann ich einfach erst mal hingehen und sagen, ich mache ein Git-Pull.
Und was Git-Pull letztendlich unter der Haupte macht, ist, der macht erst mal ein Git-Fetch.
Git-Fetch kopiert mir quasi die ganzen Objekte vom Remote in meinem Repository, was ich lokal habe.
Und macht dann automatisch ein Merge zwischen mir und dem Remote.
Und dann habe ich quasi ein Merge-Commit.
Wenn Git feststellt, hey, da sind gar keine Änderungen, dann macht Git automatisch sowas, was dir ein Fast-Forward-Merge nennt.
Dann nimmt er einfach dein Label und schiebt das ganz vorne einfach an den neuesten Commit dran.
Wenn du zum Beispiel noch keinen einzigen Commit gemacht hast.
Und bei einem Git-Rebase gehst du quasi hin und sagst, hey, ich habe hier schon zwei, drei Commits lokal gemacht.
Konstantin hat auch schon gepusht.
Ich möchte aber nicht diese ganze Verästelung haben, weil das irgendwann einfach total unübersichtlich wird.
Und ich nicht mehr so einfach nachvollziehen kann, wo kommt jetzt welche Änderung her.
Deswegen entscheide ich mich und entscheidet sich das Team dazu und sagt, hey, wir wollen möglichst eine lineare Historie haben.
Dann musst du dann mit einem Rebase arbeiten.
Und dann Git quasi Git hin und nimmt deine Commits und spielt die dann auf dem letzten Commit in dem Remote quasi wieder.
Aber dadurch hast du halt diese Verzweigung nicht mehr.
Also du hast keinen Merge-Commit, der dann zwei Eltern-Element hat, sondern du hast wirklich neue Commits, die dann nachfolgend dem letzten Commit, den du gefetscht hast, dann ablaufen.
Ja, an der Stelle natürlich die Frage, wie, wenn wir jetzt schon bei Rebacen sind, ich habe ja mal dieses Problem beschrieben, was du jetzt auch schon so ein bisschen angerissen hast, dieser Konflikte, die bei mir auftreten, obwohl ich gar keine, obwohl ich die Files vielleicht gar nicht angefasst habe.
Also ich muss so mehrfach diesen Prozess durchlaufen beim Rebase.
Im Prinzip so für jeden Commit einzeln habe ich das Gefühl, also ich weiß nicht genau, wie ich in diesen Zustand gekommen bin, aber ich hatte dann jedes Mal wieder Konflikte bei jedem einzelnen Commit, der von außen reinkam, aber die gar nicht meine Files waren.
Ja.
Kannst du mir sagen, wie ich da hingekommen bin und wie ich da nicht mehr hinkomme?
Natürlich nicht. Es gibt wahrscheinlich tausend Situationen, wie du da hingekommen bist.
Ich kann mir was vorstellen, was wahrscheinlich ist, aber ich kann es ja nicht mit Sicherheit sagen, weil ich halt nicht dabei war.
Ich würde da erst noch mal ein bisschen drüber eingehen, wie funktioniert Rebase überhaupt?
Also Rebase, die Anwendungsförderung haben wir uns ja gerade schon so ein bisschen angeguckt.
Meistens mache ich das halt, um meine Änderungen auf den aktuellsten Stand zu bringen.
Ich kann Rebase aber auch nutzen, um aufzuräumen.
Kommen wir später nochmal zu.
Was macht Rebase, wenn ich den Befehl ausführe?
Ich muss ja ein Ziel angeben, wohin ich Rebasen möchte.
Und was Git dann letztendlich macht, der sucht den letzten gemeinsamen Commit zwischen meinem aktuellen Head, wo ich gerade drauf bin, und dem Ziel, was ich angegeben habe.
Das heißt, er geht meine Linie runter und sucht den Commit, den unsere beiden Zweige gemeinsam haben.
Und dann nimmt er alle Commits, die er gefunden hat in meinem Zweig und legt quasi für alle einen Patch an.
Also wirklich das Patch-File-Format.
Wir haben ja festgestellt, Git speichert keine Diffs, sondern speichert ja den absoluten Stand.
Und jetzt brauche ich aber gerade quasi einen Diff, den ich anwenden kann.
Und deswegen macht er für jeden Commit einen Patch.
Und was er dann macht, ist, der nimmt die Patches wieder von vorne nach hinten und auf dem Ziel, wo ich hin möchte, bepleitet die alle.
Nach und nach.
Ah, okay.
Jetzt geht der Konstantin hin und ändert aus irgendeinem Grund die Commits, keine Ahnung, ändert nochmal eine Datei, hat eine Konsole-Lock rausgelöscht, gehört da ja nicht rein.
Hat er dann schön mit einem interaktiven Rebase gemacht.
Guckst du mir heimlich zu?
Ich kann auch keine Ahnung, einen anderen Namen ausdrücken.
Nee, nee, ist schon okay.
Schon okay.
Ich fühle mich nur ein bisschen ertappt.
Jetzt pusht er die ganze Geschichte nach vorne und somit hat er quasi eine neue Historie erzeugt, weil er hat jetzt die Commit-Hashes verändert durch seine Änderung an einer Datei irgendwo in der Historie.
Der Mopeds hat jetzt aber noch die alten Commits bei sich.
Und wenn der Mopeds jetzt einfach hingeht und sagt, gib Rebase, Regen, unser Feature, dann sucht er ja den gemeinsamen Commit von unseren beiden Zweigen.
Was er dann zwangsläufig bei mir finden wird oder bei Mopeds, sind halt auch die alten Commits von Konstantin.
Und die versucht er jetzt auch wieder alle anzuwenden.
Wenn jetzt der Konstantin aber diese Dateien verändert hat, kann das natürlich dazu führen, dass du dann die ganze Zeit Konflikte bekommst.
Obwohl du an diesen Dateien eigentlich gar nichts gemacht hast.
Weil du quasi die Commits, die eigentlich Konstantin gemacht hatte, vor 1-2 Wochen, jetzt anfängst auf Konstantins neue Historie anzuwenden.
Da ist es quasi sinnvoll, wenn du so ein Rebase machst, dass du einfach beschränkst, was möchtest du rebasen.
Du kannst dann bei dem Rebase-Kommando, wenn du es in der Konsole eintippst, kannst du sagen, du möchtest mit dem Parameter onto, gibst du dann den Branch an, wo du hin möchtest.
Und dann kannst du als Argument angeben, wie viele Commits du, welche Commits du bis wohin dir nehmen möchtest.
Ich mache dann immer so Sachen wie hat tilde 5, was so ein Shorthand dafür ist, vom aktuellen hat 5 Commits zurück.
Weil ich weiß, ich habe 5 Commits gemacht.
Ich kann ja hier mit Gitist mal schnell in die Historie gucken, dann sehe ich, aha, 5 Commits.
Ich kann mir auch den absoluten Hash daraus kopieren.
Dann muss ich aber den vor meinem letzten Commit nehmen, weil der Hash, den ich angebe, das ist immer exklusive.
Und dann kann ich sagen, hey, ich möchte nur die 5 Commits rebasen, die ich selber gemacht habe.
Und damit kann man das Thema schon so einen guten Schritt entschärfen.
Genau.
Wichtig ist einfach immer, hey, was macht Git?
Der sucht erstmal den Schnittpunkt von uns beiden.
Und wenn ich natürlich rebase und das Zeug pushe, dann sind das natürlich andere Commits.
Und somit findet Git die dann auch nicht oder denkt fälschlicherweise, dass er die auch rebasen soll.
Genau.
Bringt auf jeden Fall ein bisschen mehr Licht in mein Git-Dunkel.
Werde ich auf jeden Fall mal drauf achten.
Ich bin jetzt tatsächlich aber dazu übergegangen und wir haben das jetzt auch projektweit so beschlossen, dass wir Merge-Commits machen.
Und damit, seitdem ist das Problem auch nicht mehr aufgetaucht, logischerweise.
Aber ich weiß gar nicht, ich glaube, irgendwie Git macht aber unter der Haube manchmal auch noch Rebases, wo man gar nicht selbst Rebase jetzt getriggert hat, oder?
Ist das nicht irgendwie auch so implizit in irgendwelchen Sachen mit drin?
Weil es gibt ja quasi so, manche Git-Befehle sind ja so Aliases, die dann verschiedene andere Git-Befehle ausführen.
Ich überlege gerade.
Also, was du machen kannst, ist, dass du Git konfigurieren kannst, was passieren soll, wenn du Pult sagst, dass er dann Rebase versucht.
Es ist halt häufig dann nicht möglich und dann fängst du an, dann selbst das Problem zu lösen.
Ja, das ist hart belassen.
Genau, also das habe ich dann auch ausgeschaltet, dass das nicht passiert, beziehungsweise auf Merge umgestellt.
Der Standard ist ja dann Merge.
Oder man kann die Standard einstellen.
Ja, es ist definitiv die Variante mit weniger Fehlerpotenzial.
Ja, ich persönlich mag es, wenn die Historie aber auch geil aussieht.
Also nicht nur der Code geil aussieht, sondern auch die Historie.
Und wir sind bei uns eigentlich, ich glaube mittlerweile auch im ganzen Unternehmen, also ich mache bei uns auch hier und da mal so einen Vortrag-Workshop zum Thema Git.
Und ich glaube, bei uns sind mittlerweile alle Teams fleißig am Rebasen.
Aber die Probleme, wie du so beschrieben hast, kommen halt auch, ganz ehrlich, die passieren auch mir.
Und auch ich sitze manchmal da und denke, warum schlägt das jetzt viel?
Was noch ein ganz wichtiger Punkt ist, wenn du Konflikte löst in einem Rebase, du musst immer den Konflikt so lösen, wie der zu diesem Zeitpunkt sein soll.
Also wir machen ja unsere Patchs, macht ja Git-Rebays und wendet die an.
Und wenn dann so ein Patch fehlschlägt, also die Anwendung des Patches fehlschlägt, dann kriegst du ja diesen Merge-Konflikt.
Und dann darfst du nicht hingehen und sagen, ja, ich weiß, zum Schluss muss das so aussehen.
Das darfst du nicht machen.
Du musst hingehen und sagen, hey, zu diesem Zeitpunkt muss es so und so aussehen.
Ich weiß, dass das gleich noch geändert wird.
Das ist total schwierig.
Also erstmal die ganzen Commits im Kopf zu verarbeiten.
Was ich da ganz gerne mache, Git, wenn der den Merge versaut hat, dann sagt er, hey, ich konnte dem den Commit nicht anwenden.
Wenn ich es überhaupt nicht hinkriege, dann gehe ich auch manchmal hin und sage dann einfach Git-Show auf diesen Commit-Hash.
Und dann sehe ich, was dieser Commit eigentlich machen möchte.
Und dann kann man meistens einfach daraus schließen, ach ja, er will nur diese Klasse ändern in meinem HTML.
Ich habe aber noch zwei, drei weitere Klassen hinzugefügt.
Ja gut, dann nehme ich einfach diese Klasse und ändere die gerade manuell nochmal.
Okay, weil das ist nämlich dann der Grund, warum sonst genau das passiert, was Moritz gesagt hat.
Dass du immer wieder Konflikte und den nächsten Konflikt und den nächsten Konflikt, weil das eben diesen Rattenschwanz hinter sich her zieht, weil du es nicht zu dem Zeitpunkt geändert hast, sondern wieder irgendwas anderes noch drin hast.
Git macht ja diese Patches und in dem Patch steht ja quasi immer drin, welche Zeile wird gelöscht, welche wird dafür eingefügt.
Und der findet einfach dann nicht mehr diese Zeile, wie sie gelöscht wird, weil du die schon irgendwas ganz anderes geändert hast.
Das ist auch super wichtig, dass man da die Kontrolle behält und nicht versucht, das schnell zu fixen, sondern dann einfach nochmal kurz nachdenkt.
Ich meine auch, dass man sich diesen letzten Commit, den er nicht anwenden konnte, mit rebase hat anzeigen lassen kann.
Also git show rebase tiefstrich hat.
Ich meine, das ist der Commit, den er nicht anwenden konnte.
Da muss man nicht immer im Text nach der Commit-Message suchen.
Genau.
Ja, und wichtig ist halt, wenn man halt mit rebase arbeitet, dass man seine Kollegen nicht abhängt.
Also ich kann nicht einfach hingehen und die ganze History dann ins Remote pushen und meine Kollegen kriegen das nicht mit.
Also da ist es dann halt sinnvoll, eine Strategie zu wählen, wie das möglichst vermieden wird.
Was wir ja mal in einem Projekt gemacht haben, wo wir sehr viele Leute immer an einem Feature gearbeitet haben.
Wir haben einfach mehrere Branches gemacht für dieses Feature.
Wir hatten quasi eine Feature-Branch.
Da haben wir gesagt, hey, an diesem darf niemand rebasen.
Und von diesem Feature-Branch abzweigend hat dann jeder sein Mini-Feature gemacht.
Ich baue eine Komponente ein, ich ändere was an der State-Behandlung, wie auch immer.
Und in seinem eigenen Branch konnte man dann rebasen, wie man möchte.
Und wenn man fertig war, hat man einen Pull-Request aufgemacht in diesem eigentlichen Feature-Branch.
Und wenn man dann gesagt hat, okay, das ganze Team ist jetzt fertig, das Feature steht kurz vor Merch in den Master,
dann kann man nochmal hingehen, okay, alle Finger weg.
Okay.
Zwei Leute setzen sich hin und räumen da dann nochmal die letzte Historie auf.
Ist in der Firma natürlich besser abzusprechen, als es bei einem Open-Source-Projekt,
wenn ich da irgendwie anfange, was zu rebasen und dann mache ich allen anderen was kaputt.
Definitiv, aber bei einem Open-Source-Projekt, zumindest wie es mir bislang gegangen ist,
ist es ja meistens so, dass du allein in einem Branch arbeitest.
Ja, ja.
Wenn du jetzt mit GitHub arbeitest, ja auch in deinem eigenen Repository.
Und da kannst du ja erstmal rumrebasen, bis du schwachzwirst.
Und kannst dann nachher dann in deinem Pull-Request, kannst du dann nachher dann den finalen Stand machen.
Das wäre eine gute Überleitung zum Gesquasche.
Zum Gesquasche, ja.
Ich hätte noch eine Frage vorher.
Weil mir das jetzt gerade wieder eingefallen ist.
Ich hatte das auch mal auf der Liste drauf, habe es dann wieder weg.
Hat das irgendwie was mit dem Befehl, also bringt da irgendwie, da gibt Befehl Re Re Re was.
Weil ich habe das irgendwo bei mir im Hinterkopf, ich weiß nicht, ob ich dich jetzt eiskalt erwische.
Total.
Re Re Re schon gesehen, aber ohne Scheiß, ich weiß nicht, was er macht.
Ich habe gerade nochmal nachgelesen, was es überhaupt heißt.
Also es ist tatsächlich, es ist kein Quatsch.
Reuse Recorded Resolution of Conflicted Mergers.
Okay, dann müssen wir da jetzt auch nicht tiefer drauf einsteigen.
Ich weiß, dass irgendjemand mal zu mir kam, ein Developer sagt, was, du hast hier das Problem
hier mit bla und dann macht so, mach mal mal Git Re Re Re.
Und ich so, das klingt jetzt erst mal wie ein Witz, also ein Befehl, der Re Re Re heißt.
Ehrlich jetzt?
Und das gibt es dann wirklich.
Und okay, gut, dann können wir ja mal, das packen wir einfach mal, den Link dazu packen wir
einfach mal in die Shownotes.
Das könnt ihr dann in den Shownotes nachlesen und lernen, dass das genau macht.
Dann nutze ich den Link nämlich mal, um zu verstehen.
Also ich frage mich gerade, wann recordet er halt die Resolution?
Aber ja, vielleicht hilft das.
Also vielleicht merkt er ja, dass ich immer diese Klassennamen, die ich da fälschlicherweise
geändert habe, anpassen muss.
Und dann checkt er, dass er das einfach direkt macht.
Also ich kann ja mal kurz den ersten Satz aus der Description vorlesen davon.
Also in a workflow employing relatively long-lived Topic Branches, der Developer sometimes needs
to resolve the same conflicts over and over again until the Topic Branches are done.
Klingt irgendwie schon ein bisschen ähnlich.
Nach dem, was ich vorhin beschrieben habe.
Vielleicht ist das auch, müssen wir mal gucken.
Können wir im Nachgang mal schauen.
Genau, das schieben wir dann hinterher, nächste Folge.
Genau, das schieben wir hinterher vielleicht irgendwann mal, nächste Folge oder so.
Okay, gut, jetzt kommen wir zum Squashing, oder, Konstantin?
Ich hatte das jetzt schon öfter, dass ich eben an irgendeinem GitHub-Repository mitgearbeitet
habe und manche haben da, also manche akzeptieren das auch, wenn du da irgendwie zwölf Commits
in einem Pull-Request hast und andere fahren halt knallhart die Linie, nee, ein Pull-Request,
dann machen wir einen einzelnen Commit, der alles, also das komplette Feature dann enthält.
Und da hatte ich jetzt dann eigentlich jedes Mal das Problem, das hinzubekommen mit dem Squashen.
Also, dass ich eben mehrere Commits nehme und die zusammenpacke und dann nur noch ein Commit
habe mit allen Änderungen, die die gemacht haben.
Ja.
Und ich weiß nicht so ganz, was ich da immer falsch mache.
Also, man wählt ja dann aus, vielleicht, aber vorhin habe ich schon gedacht, als du gemeint
hast, man muss, wenn man mit dieses Hat-5, also dass man fünf Commits zurückgeht, dass das
eben exklusiv ist und dass da eben der letzte, also ich muss dann den da vornehmen, den Commit.
Und das kann natürlich sein, dass das vielleicht auch schon mein Problem war, dass sonst halt
irgendwelche Sachen nicht drin waren und ich dann den ersten Commit dann doch noch als
einzelstehenden Commit hatte.
Also, wenn das dein Problem ist, dass der erste Commit einzelstehend immer noch da war,
dann ist das das Problem.
Ja.
Aber du hattest ja auch mal ...
Ich hatte es aber auch schon so, dass ich ...
Oder mal das Problem hast, dass Dinge dann einfach irgendwie kaputt gehen.
Ja, also, es waren dann irgendwie alle Commits noch da und zusätzlich ein Commit, der dann
die Commit-Message hatte, wo ich reingeschrieben habe, squashed everything together oder so, ja.
Und der war dann aber noch da und ich weiß aber nicht, was in dem dann passiert ist, weil
eigentlich war da sonst nichts geändert und die anderen Commits waren trotzdem noch
da gestanden.
Was ich dann gemacht habe, ich habe das Pro-Request zugemacht, weil ich mir nicht anders zu helfen
wusste, habe das nochmal in einen neuen Feature-Branch angelegt bei mir, wo wirklich nur die Änderung
drin war und nochmal committed.
So blöd es ist, aber genau, richtig.
Also, ja, weil ich mir einfach nicht anders zu helfen wusste, weil ich da nicht durchsteige,
was da so passiert.
Also, ich habe ja auch mal so ein Demo-Repository angelegt, da habe ich dir vorhin den Link geschickt,
wo einfach irgendwie, das ist nur eine Readme in dem Repository und da habe ich fünf Commits
gemacht mit Änderungen, wo ich eine Zeit hinzugefügt habe.
Ich kann ja mal versuchen, was würde ich denn jetzt, normalerweise arbeite ich mit Source-Tree
als GUI, aber wir können das gerne mal einfach über die, was die Command-Line machen.
Du hast mich ja vor, im Moment, nicht vorgewarnt, du hast mich vorhin informiert, als wir darüber
gesprochen hatten schon mal, dass du Source-Tree benutzt, da habe ich ja, weißt du was, ich
da habe mir jetzt noch Source-Tree benutzt, da habe ich mal gerade, was der Konstantin da
falsch gemacht hat.
Ich habe es nicht hingekriegt, dann Squash zu machen.
Okay.
Es tut mir leid.
Ich wüsste, tatsächlich ist das auch so.
Ding, ich, manche Sachen mache ich nämlich dann auch tatsächlich über die Command-Line,
weil ich einfach nicht weiß, wie man es in Source-Tree hingekriegt, weil das ist genau
dieses Ding, du hast da schöne Menüsen so, das macht erstmal alles einfacher, aber du
weißt halt nicht, was im Hintergrund passiert und du weißt manchmal auch nicht, wo du eben
was findest, wenn du das Feature brauchst.
Und es kann sein, dass ich das gar nicht über Source-Tree gemacht hatte, weil ich sehe
da tatsächlich auch kein, wahrscheinlich habe ich eben, weil ich halt nicht wusste, was Rebase
so genau macht.
Vielleicht habe ich es auch versucht, über den Rebase zu machen und habe deswegen dann Sachen
kaputt gemacht.
Also mein Ansatz wäre auch tatsächlich ein Rebase.
Wüsste nicht anders, wie ich die Sachen zusammen
squashen könnte, ohne ein Rebase zu machen, ehrlich gesagt.
Aber mein Ansatz wäre tatsächlich ein interaktiver Rebase, in dem Fall.
Das machst du mit git rebase minus i und ja, dann kommt halt darauf an, wie sauber die
Historie schon ist, aber jetzt in deinem Fall zum Beispiel, wenn du jetzt für so ein Open-Source-Projekt
mit einem Pull-Request aufmachst, dann ist ja meistens kein anderer Branch da oder du hast
keine Commits, die ein anderer gerebased hat und so und es ist alles schön sauber.
Dann gehe ich meistens hin und sage dann git rebase minus i und dann keine Ahnung, origin slash master.
Also nicht mal mein lokalen Master, weil ich weiß nicht, ob ich den jetzt mal aktualisiert habe.
Ich nehme da immer sowas wie origin master.
Ich probiere das einfach mal.
Wenn du jetzt ein GitHub-Fork hast, dann hast du ja wahrscheinlich so ein Upstream-Remote
noch hinzugefügt.
Das ist ja einfach ein zweites Remote mit einem anderen Namen, nichts weiter.
Dann würde ich jetzt sagen, git rebase minus i, upstream slash master zum Beispiel.
Was dann passiert ist, es geht dein in Git-konfigurierter Editor auf, standardmäßig vim und vi.
Da auch nochmal mein Tipp für alle, die mit vi nicht so gerne arbeiten, weil sie ihn nicht mehr
verlassen können.
Das kann man konfigurieren und zwar mit git config minus minus global für, ich möchte
das für meinen ganzen Rechner tun, core.editor und dann kann ich einfach einen anderen Editor
angeben.
Bei mir ist es zum Beispiel Sublime, den müsste ich dann aber mit Parameter minus w angeben,
weil dann git wartet, bis ich Sublime wieder geschlossen habe, beziehungsweise die Dateien
in Sublime geschlossen habe.
Ich wusste gar nicht, dass man da, das ist cool zu wissen, weil ich wusste nicht, dass man
da Editoren angeben kann, die nicht auf der Kommandozeile laufen.
Also ich habe da bei mir Nano angegeben, aber wenn man dann mit minus w und das, ah, das
ist wirklich cool zu wissen, weil da kann ich da auch mein Vs Code nehmen oder sowas.
Ja genau, ich bin ja ein Atommensch, aber ich habe ihn nicht genommen, weil er mir, auch
wenn er relativ schlank ist, dann trotzdem so lange startet.
Also da ist Sublime gefühlt immer noch umgeschlagen im schnellen Starten.
Ich habe aber auch Sublime nur noch für diesen einen anwendungsvollen Rechner.
Wenn ich auch ganz schnell irgendwo was hinschreiben will als Notiz, dann mache ich das auch
schnell in Sublime.
Genau, dann hatten wir es in unserer Editor-Folge auch, dass wir das auch so handhaben zum Teil.
400 geöffnete Tabs.
Ja genau, richtig.
Ich habe jetzt hier gerade mal meinen Bildschirm geschert, beziehungsweise das Command-Fenster.
Und das ist jetzt eben, also ich weiß gar nicht, ist das auch tatsächlich Wim, was
da GIT unter Windows mitbringt oder irgendwie nur was, was so aussieht?
Weiß gar nicht, wie das intern läuft oder ist das irgendwie über Sequen?
Ja gut, okay.
Aber es sieht jedenfalls so aus, wie so ein Wim-Fenster auch aussieht.
Und was mache ich denn da jetzt genau?
Was auch immer, wie du den Editor konfiguriert hast, es geht in den Editor auf und du siehst
jetzt ganz viele Zeilen, in denen vorne immer Pick steht.
Genau, Pick, dann der Hash und die Combit-Message.
Die Combits, die er jetzt gefunden hat.
Also in der Range, die du wie auch immer angegeben hast, hat er jetzt genau diese Combits
gefunden.
Genau, also ich sage nochmal kurz, was ich gemacht habe, um da hinzukommen.
Also wie du es gesagt hast, ich hatte Git, Rebase, Midus-E und dann Origin-Main.
Genau.
Und was er jetzt quasi macht, ist erstmal, er pickt einfach alle Combits.
Das ist quasi wie ein Cherry-Pick, was er da macht.
Er geht jetzt quasi auf dein Ziel und wendet jetzt jeden dieser Combits da drauf an.
Wenn du das jetzt nicht möchtest, kannst du jetzt das Kommando, was vorne steht, also
das Pick, kannst du dann quasi ändern.
Wenn der Editor aufgeht, unter den Combits drunter steht eine Liste von allem möglichen
Kram, den man machen kann.
Ich sage mal so, die häufigsten Sachen, die man da macht, ist halt Pick.
Das ist halt der Standardfall.
Dann gibt es sowas wie Reword, wenn ich die Commit-Message nochmal editieren will.
Es gibt Edit, also quasi das Editieren des Commits.
Da passiert nichts weiter, wie, dass der Rebase an der Stelle anhält.
Und dann könntest du zum Beispiel nochmal irgendwie eine Datei ändern und mit Git-Commit-Amand,
damit kannst du ja den letzten Commit, den du gemacht hast, nochmal anpassen, kannst du
den nochmal ein bisschen fixen und kannst du den Log rauslöschen oder so.
Und dann sagst du, Git-Rebase-Continue, dann geht es weiter.
Dann kommt dann Squash.
Das ist das, was du jetzt gerade vielleicht machen willst.
Es gibt aber auch Fix-Up.
Und Fix-Up ist nichts weiter wie Squash, nur, dass du nicht nochmal eine neue Commit-Message
angeben musst.
Das heißt, wenn du ohnehin die Commit-Message im ersten Commit schon passend hast und danach
kommt nur noch Remove-Konsole-Log und Tests.
Ja, ja, vor Gott, du Commit so und so.
Ich habe auch einen Bug gefixt, den ich vorher nicht gesehen habe.
Dann machst du vielleicht auch einfach einen Fix-Up.
Und dann kannst du jetzt einfach hingehen in die Zeilen, die er dir oben reingeschrieben
hat, vorne das Pick einfach wegmachen und dann das andere gewünschte Commando da hinschreiben.
Also du kannst jetzt zum Beispiel aus allen
ein F machen für Fix-Up
oder Fix-Up hinschreiben.
Wenn du gerne tischst.
Den ersten musst du allerdings lassen, weil
irgendeinen Commit müssen wir ja picken, den wir dann
Ah, das ist dann der, den er
Ah, jetzt habe ich schon wieder irgendwas
irgendwas war jetzt gerade versaut, weil ich wahrscheinlich
hier Einfügen aus Versehen aktiviert habe.
Und jetzt habe ich glaube ich den Hash
gerade kaputt gemacht.
Solche Sachen passieren mir dann eben.
Wenn man es versaut hat, der Escape-Hatch ist einfach alles löschen und Fenster schließen
und dann gesagt, warte mal, da ist ja gar nichts zu tun.
Okay, machen wir doch direkt mal.
Man kann ich hier nicht, äh, ich kann, oh, ja, jetzt komme ich hier als, als
Wimbleger, Szeniger, äh, ich kann nicht mal
Steuerung A oder so, also, ähm,
ihre Verbindung wird gehalten.
Wenn ich übrigens sage, alles löschen, dann meine ich natürlich nur die
Kommandos löschen.
Also, okay, also das wäre, wäre wurscht.
Okay, ich dachte, die muss dann leer sein quasi.
Und jetzt würde ich, äh,
so.
Jetzt muss ich, äh, hier,
äh,
Q-Ausrufzeichen, ne, wie war es?
Ausrufzeichen Q?
VQ.
Schreiben.
Okay, jetzt machen wir das noch.
Jetzt macht er nichts zu tun, sagt er an GitHub.
Okay.
Weil ich quasi alle Kommandos, es ist quasi,
mach folgende Kommandos, ne, das ist eine Kommandoliste.
Oder bei GitHub nennt sich das sogar To-Do-Liste.
Ah ja.
Du kannst es tatsächlich sogar auch noch editieren, wenn du schon mitten im
Rebase drin bist.
Kannst du dann, gibt's Rebase, Edit, To-Do, und dann kriegst du noch die
restlichen Kommandos, die noch ausstehen, und kannst dann noch mal
welche dabei schreiben oder doch noch mal ändern.
Kannst du die wildsten Sachen machen.
Jetzt hab ich hier zum Beispiel das Problem, ich kann, ich kann kein F eintippen.
Warum kann ich das einfach?
Kannst du erst drücken oder so, ne, zum Einfügen.
Ach so, ist das, ah, ah, ah, ah, aha, okay.
Also ich glaube, ich werde mir,
gegen Software etwas getauscht.
Ja, ich werde tatsächlich auch genau das tun.
Okay.
So.
Und so müsste das jetzt aussehen.
Genau.
Ja?
Ja, genau.
Also was du jetzt quasi, ich hast es dann quasi in der ersten Zeit, da steht Pick,
ich hab mein Feature gefixt, und darunter steht dann F oder Fix Up,
Commit Hash, hab Konsole Lock gelöscht, hab noch Tests geschrieben, etc.
Genau.
Und dann speicherst du die Datei quasi und spendest deinen Editor und jetzt startet dann los.
Und speichern mit, also schließen mit Speichern ist?
WQ.
Auch nochmal WQ?
Ja, ich dachte, das war, ach so, ah, okay.
Wir haben ja alles rausgelöscht, deswegen hat die Treebase gesagt, das ist nix.
Ich guck mal kurz, wie es in SourceTree jetzt aussieht, da müsste ich ja jetzt schon sehen.
Oder?
Und wenn ich das jetzt, äh, nee, warte mal, kann ich das jetzt einfach pushen?
Nee.
Äh, ja, klar.
Doch.
Könntest du tun.
Wenn du allerdings schon Commits von denen gepusht hast, die du jetzt weggekillt hast,
dann musst du einen sogenannten Force-Push machen.
Das ist das, wo alle immer sagen, Achtung, weil wenn du jetzt Force-Pushst und Commits
verschwinden, die irgendein Kollege noch in seiner Historie drin hat, dann führt das halt
zu Effekten, dass die wieder dann irgendwann wieder auftauchen.
Also, wenn man Force-Pusht, muss man auf jeden Fall mit seinen Kollegen sprechen.
Ja, okay.
Und das ist auch so ein Stolperstein wieder, ich weiß nicht, woran das liegt, das müsste
die neueste Source-Tree-Version sein, da ist Force-Push ausgegraut.
Und ich weiß nicht, wieso.
Und deswegen mache ich das dann auch immer, wenn ich irgendwas forcen muss, also manchmal
auch Tags überschreiben.
Dann muss ich das immer über die Command-Line machen, weil ich nicht weiß, wie das, warum das ist.
Aber da geht es auch vorstanden.
Genau, das funktioniert der Problem.
Ich weiß nicht, was das, das muss irgendein Bug eigentlich in Source-Tree sein.
Oder vielleicht kann es mir auch jemand erklären, dann gerne.
Vielleicht musst du das auch mit, du musst erst den Namen des Repositories eintippen, erst
anlocken oder sowas.
Vielleicht, ja.
Vielleicht ist das wirklich ein Sicherheitsfeed.
Das kann sein, ja.
Okay, und jetzt gucken wir mal in das Pull-Request.
Yay!
Cool.
Ha, gut, dann kann ich das in Zukunft auch.
Ich habe mir echt, ich habe mir schon Tutorials durchgelesen und irgendwie aus dieser Kombination
an Wim und nicht so ganz wissen, was man da tut, bin ich dann echt gescheitert.
Aber das freut mich jetzt, dass ich das jetzt hier bekomme.
Was man da halt auch machen kann, wir hatten ja diese ganzen Pick-Kommandos, du kannst
quasi auch die Reihenfolge von Commits ändern, ne, wenn du das tauschst einfach.
Was da halt wichtig ist, dass du einen Commit nicht nach vorne schiebst, obwohl der auf
andere Änderungen angewiesen ist.
Ja, klar, sonst habe ich wieder diese ...
Weil die Änderungen weg sind, weil die erst später reinkommen, ne.
Das ist ganz wichtig.
Das ist aber jetzt halt auch so ein Thema, an dem wir jetzt sind, wo es heißt, okay,
da kannst du jetzt aber ganz schön viel falsch machen.
Wenn du jetzt Commits löscht, dann verschwinden die plötzlich.
Also wenn du jetzt eine Pick-Zeile löschen würdest, dann wird der nicht mehr gepickt, dann
ist der weg, der Commit.
Und da wird häufig dann von abgeraten, dass man es bitte nicht tun sollte, weil man viel
kaputt machen kann.
Aber in Git kannst du gar nicht so viel kaputt machen.
Weil nur weil dein Label ja jetzt auf einen anderen Commit zeigt, heißt das noch lange
nicht, dass der Commit nicht mehr da ist.
Also der alte Commit, den du jetzt irgendwo reingesquasht hast, ist in der Datenbank immer
noch da.
Der wird erst bei so einer Garbage-Collection, die, keine Ahnung, alle zwei Wochen mal ausgeführt
wird intern, wird der halt wirklich gelöscht.
Und wenn du jetzt nicht mega viel Unglück hast, passiert das nicht jetzt in diesem Moment.
Und das Ding ist halt noch da.
Es gibt einen Befehl, der nennt sich Git RevLog.
Der ist sehr hilfreich, weil RevLog ist quasi ein Log.
Das zeigt dir an, wo dein Head gewesen ist.
Und wenn du das jetzt bei dir ausführen würdest nach einem Rebase, dann siehst du die ganzen
Sachen, die er für den Rebase gemacht hat.
Und der Rebase fängt eigentlich immer mit dem Checkout an von der Zielbranche.
Und wenn du jetzt den Commit da vornimmst, das ist quasi dein Stand, wie er vorher mal
war.
Oder dein Head war ja an diesem Punkt.
Das ist quasi das, was da steht.
Und jetzt könntest du zum Beispiel einfach hingehen und sagen, hey, alles war blöd.
Da machst du Git Reset minus minus hart, weil du willst doch keine Änderungen behalten.
Und gibst dann einfach den Commit Hash an und dann ist alles wieder so wie früher.
Also es ist nicht so, dass du dich da komplett zerstörst.
Cool.
Das für mich ist auch nochmal so ein Ding, wo man sagt, ah, okay, wenn ich zurück
kann, dann experimentiere ich auch gerne mal.
Ja, das ist gut zu wissen, dass man einfach auch ein bisschen die Angst davor verliert,
irgendwie was komplett zu zerstören.
Genau.
Ja, ich mache dann immer einen neuen Branch.
Bitte?
Ich schmeiße dann immer den Branch weg und mache nochmal neu.
Ja, klar.
Es ist halt blöd, wenn man das Pull-Request schon gestellt hat.
Ja, es geht, ja, sowieso.
Und das geht auch nicht immer, das ist dann manchmal eklig und dann speichere ich Changes irgendwo
in einem anderen Editor und so.
Das ist alles.
Also empfehlen kann ich das nicht, aber das ist so the last resort bei mir.
Ich glaube, wenn man sich ein bisschen tiefer auskennt im Git, dann muss man das vielleicht
nicht.
Deswegen, ich gelobe Besserung.
Ja, aber zum Schluss zählt nur das Ergebnis, dass die richtigen Commits bei deinen Kollegen
landen oder im Master Branch, damit das Projekt deployed werden kann.
Wenn sie dann noch schön und aufgeräumt sind, das ist dann nochmal das Sternchen.
Führt mich zu dem Punkt, wofür wir diesen ganzen Bums überhaupt machen.
Wofür machen wir Versionsverwaltung eigentlich?
Ich glaube, viele sehen das so als so ein Backup.
Hey, das ist ein Backup, falls mal was schief geht.
Aber eigentlich ist es ja viel mehr.
Dokumentiere damit ja quasi die Geschichte unseres Projekts von der Software.
Wie hat sich das entwickelt?
Warum ist das so, wie es ist?
Warum hat der das dahin gebaut?
Und nicht anders.
Da ist es halt wichtig, in meinen Augen wirklich zu gucken, dass auch die Historie halt sauber
ist.
Weil wenn sie sauber ist, kann man das auch gut nachvollziehen.
Wenn ihr zum Beispiel Git-Blancen, wie ihr das Code nutzt, ist es cool, wenn da ein
sinnvoller Commit-Summer steht und nicht nur Fixed-Bug.
Ja, klar.
Wenn du das jetzt zwar ja, dann wurde ein Bug gefixt, aber du weißt nicht, welcher.
Was macht so eine gute Commit-Message aus?
Ja, erzähl doch mal.
Was du so verbreitet hast?
Witzigerweise habe ich das jetzt, ich habe es jetzt gerade aufgeschrieben als Thema.
Super, dann sprechen wir einfach gleich drüber.
Was macht eine gute Commit-Message aus?
Naja, also ich kann ja mal sagen, wie wir das bei uns machen.
Oder ich weiß nicht, ob wir super diszipliniert sind an der Stelle, ob jede Commit-Message
genauso aussieht, ob die immer dem Schema folgt.
Aber wir schreiben die so, also wir schreiben an den Anfang der Commit-Message eigentlich immer
die Ticket-Nummer, was für ein Ticket wir bearbeiten.
Und wenn man ein cooles Tool hat, wie zum Beispiel Bitbucket oder GitLab, dann kann das auch
direkt dann zu dem Ticket verlinken.
Und dann bin ich von dem Ticket nur einen Klick entfernt.
Also irgendwie Ticket-Nummer.
Und dann beginne ich normalerweise mit einem Verb und sage halt, was habe ich denn gemacht?
Also fix oder, keine Ahnung, add oder remove und so weiter.
Also für uns da auch schon diese imperative Stimmung quasi.
Irgendjemand hat mal gesagt, ich soll das so machen in der Vergangenheit.
Ich weiß gar nicht mehr genau, wie ich dazu kam.
Aber es gibt da ja tatsächlich einige Artikel im Netz, die einem genau die Grammatik vorgeben,
wie so eine Commit-Message auszusehen hat.
Ich weiß jetzt nicht, ob wir uns so streng daran halten, aber das hilft durchaus, wenn man sich an so ein gewisses Schema hält.
Dann kann man auch sehr schnell erkennen, was hat der andere da gemacht.
Und ja, es gibt bei mir aber auch Commit-Messages, die heißen einfach nur fix oder ha, ha, ha, wer das liest, ist doof.
Ich meine, gerade wenn man so mitten in der Entwicklung von einem Feature ist und man eigentlich nur so einen Zwischenstand mal abspeichern will,
bevor man in den Feierabend geht und man gar nicht so genau sagen kann, was man da jetzt gemacht hat,
dann sind die auch nicht immer so aussagekräftig, bin ich ganz ehrlich.
Weil die heißen dann auch immer WIP für Work and Progress.
Weil das kann man einfach Gitcommit-M, WIP, damit brauche ich nicht mal, dass der Editor aufgeht, einfach raus damit.
Aber jetzt, Moritz, jetzt weißt du, dass du das fix abbenutzen kannst, um das ...
Und wie ich auch gelernt habe, ist WIP kennt GitLab offenbar auch und kann da und triggert dann keine neuen, also Pipelines oder irgendwie sowas.
Irgendwie sowas gibt es da.
Also wenn man GitLab verwendet, wir sind jetzt gerade dabei, darauf umzusteigen, habe ich jetzt gerade heute gehört,
dass das irgendwie, wenn man WIP davor schreibt, dass er dann, glaube ich, dass das dann darauf reagieren kann und sagen kann,
hey, dann triggere ich die Pipeline nicht, weil das ist ja dann Inno-Work-in-Progress, interessiert mich nicht.
Es gibt ja auch, je nach Buildchain, wird dann der Change-Log entsprechend gefüttert, je nachdem, was da für Verben drinstehen.
Wird das dann irgendwie gruppiert nach Fix und nach Features und so.
Deswegen ist natürlich, wenn man sowas nutzt, muss man sich natürlich auch was auf ein System einigen.
Ja, was sich da durchgesetzt hat, ist dieses Semantic Release nennt sich das, beziehungsweise das setzt auf etwas auf, was sich Conventional Commits schimpft.
Dass man halt so eine Konvention einhält, dass man zum Beispiel mit Fix-Doppelpunkt anfängt, wenn man was gefixt hat.
Oder mit Feed-for-Feature-Doppelpunkt, wenn man ein neues Feature einbaut.
Oder halt unten im Code sowas sagt wie, Achtung, das ist ein Fat-Breaking-Change.
Weil dann kann zum Beispiel deine Pipeline hingehen und automatisch Releases davon erstellen, nach dem Semantic-Versioning.
Also, dass du wirklich weißt, muss ich jetzt hinten den Patch-Release hochzählen oder muss ich einen Feature, wie heißt das, Minor-Release hochzählen, die Minor-Version.
Weil der halt einfach die Commit-Messages durchgehen kann und der weiß halt, wenn da Fix steht, wurde im Bug gefixt.
Und damit kann man halt sehr viel automatisieren.
Gerade mal geschaut hier, conventionalcommits.org, da wird das ein bisschen beschrieben.
Würdest du das empfehlen, setzt ihr das bei euch ein?
Wir setzen das mittlerweile sehr häufig bei uns ein in Projekten.
Also wir haben auch mittlerweile einige Pipelines, die halt wirklich dann die Releases einfach raushauen, sobald was im Master ist.
Und da setzen wir das dann halt ein, um zu entscheiden, was für eine Versionsnummer gemacht wird.
Ah, cool. Also komplett automatisiert dann.
Ja, aber es ist nicht immer komplett automatisierbar, weil du das vielleicht dann doch nicht auf Produktion schieben möchtest, weil der Kunde vielleicht auch nochmal drüber gucken möchte.
Aber wir sind zumindest so weit, dass wir dann einen Release gemacht haben, das deployen wir dann auf Staging.
Und wenn das dann freigegeben ist, kann das Release dann auf Produktion deployed werden.
Aber ihr habt da gute Erfahrungen mitgemacht mit dem conventionalcommits, weil das sieht jetzt ein bisschen anders aus, als das, was ich so kannte.
Aber es sieht durchaus sinnvoll aus, gerade wenn man so automatisiert bestimmte Dinge tun will, wie du gerade gesagt hast.
Bestimmte Versionsnummern hochzählen.
Bei Breaking Changes wird es dann wahrscheinlich mindestens eine Minor-Version oder Major, ich weiß es gar nicht genau.
Genau, in Breaking Change machst du das Major-Version.
Eine Major-Version.
Kommt bestimmt aber auch nochmal darauf an, wie du es dir konfigurierst.
Das ist ja letztendlich auch eine Toolchain-Geschichte, wie du es dann nutzt.
Habt ihr da Tools, die einen dran hindern, eine falsche, in Anführungsstrichen, Commit-Message zu schreiben?
Oder also die irgendwie das prüfen?
Okay, also man kann auch quatschen.
Also Husky zum Beispiel, damit kannst du es lösen.
Husky ist ja so ein Commit-Hook-Ding auf JavaScript-Basis.
Da kannst du das checken, setzen wir aber noch nicht ein.
Also vielleicht mal, weil es, ja, es gehen auch manchmal so ein paar Sachen schief, dass dann man vielleicht fix geschrieben hat, obwohl es ein Feature ist.
Oder umgekehrt.
Und dann passiert halt ein falsches Release, was man nicht möchte.
Ah, Husky, könnte ich auch noch nicht.
Mensch, wir lernen noch so viel.
Ja, ich führe auch so ein bisschen Buch gerade.
Nur, dass du Bescheid weißt.
Haben wir vielleicht Doppelungen am Ende, aber macht nichts.
Wir sind auch bei der Commit-Message stehen geblieben.
Genau.
Ja, das mit dem Verb, imperative Stimmung oder wie man es nennen möchte, hat sich durchgesetzt.
Also bei mir im Kopf kommt immer so ein This Commit will...
Und dann geht es auf der Tastatur weiter, Add, was auch immer.
Das ist so meine Gedankenstütze, die ich mir immer mache, damit ich das dann halt richtig formuliere.
Was ich aber halt auch wichtig finde ist, also man spricht ja bei dieser ersten Zeile von der sogenannten Summary und wenn man freundlich zu Leuten ist, die Terminals benutzen, die nur 80 Zeichen bereit sind, dann guckt man, dass man sich auf 80 Zeichen beschränkt.
Da wird es dann mit Ticketnummern davor schon wieder eng, weil die nehmen dann irgendwie einen wertvollen Platz weg.
Und das ist dann auch die Commit-Geschichte, da denke ich manchmal so, hey, zähle ich jetzt 80 nach dem Fix-Doppelpunkt oder von ganz vorne, dann fängt man dann doch an, ein bisschen das aufzuweichen.
Aber wie es Code hilft einem da ganz gut, das sagt nämlich Bescheid, ich weiß nicht genau, ob das jetzt genau 80 Zeichen zählt, aber ab einer gewissen Zeichenanzahl sagt es, hey, wenn du jetzt noch weiterschreibst, dann musst du zumindest mal in die nächste Zeile gehen, sonst wird das zu lang.
Also ich könnte mir vorstellen, dass das in die ähnliche Richtung zielt.
Bist du dir denn sicher, dass das dann noch als Summary gewertet wird?
Das weiß ich nicht, ehrlich gesagt.
Also dieses Format, was sich da so ein bisschen durchgesetzt hat, ist ja, dass du eine Zeile schreibst mit einer Summary, dann lässt du eine Leerzeile und darunter schreibst du dann eine ausführliche Beschreibung, warum du das gemacht hast.
Warum du den Bug auf die Art und Weise löst, weil, ich sag mal, was ich gemacht habe, das kann ich auch sehen, wenn ich einen Diff auf der Summary machen, dann sehe ich, was du geändert hast.
Aber manchmal ist auch die Frage, warum hast du es genau so geändert?
Gibt es dann einen Grund für?
Dann wäre es cool, wenn du den reinschreibst, damit der nächste, der das vielleicht dann wieder ändern wird, weiß, dass das bitte nicht umbaut auf eine andere Variante, mit der du schon gescheitert bist.
Und dann quasi die gleichen Fehler nochmal wiederholt.
Deswegen ist es ganz cool, wenn man da dann so eine Beschreibung macht und GitHub zum Beispiel oder auch GitLab, die verstehen das quasi.
Die können die Commit Message entsprechend zerlegen und im Log zeigen die zum Beispiel nur dieses Summary an.
Und in der Detailansicht siehst du dann auch diese Description.
Und ich glaube, die kann dann sogar marktortformatiert sein, wenn ich mich nicht irre.
Also da kann man sich in der Theorie, wenn man sich die Zeit nehmen möchte, kann man sich da richtig auslassen.
Das ist interessant, so eine Information über dieses Warum und mit welchen Lösungen ich schon gescheitert bin, würde ich jetzt tatsächlich in den Code als Kommentar reinschreiben.
Aber es in die Commit Message zu packen, ist auch ein interessanter Ansatz.
Wäre nur mir vielleicht ein bisschen zu versteckt, dann tatsächlich beim einen oder anderen.
Das ist, glaube ich, gut, wenn es direkt beim Code dabei steht.
Ja, das ist auch wieder, ja, Ansichtssache.
Also ich weiß gar nicht, ob ich überhaupt noch Kommentare in meinem Code habe, die nicht ESLint sagen, dass er da jetzt mal bitte nicht meckern soll.
Also ich persönlich finde immer so, Code dokumentiert sich selbst ganz gut, wenn du von einem Fliegelfunktionsnamen machst, ganz schön aufreißt.
Ja, manchmal macht es dann wahrscheinlich Sinn zu sagen, hier bitte das nicht löschen, sonst geht es kaputt.
Und ich weiß nicht warum.
Haben wir ja alle schon getragen.
Ja, dieser Klassiker, was irgendwie vor einigen Jahren mal durchs Web ging, irgendwie so mit so einer Strichliste, wie viele Leute jetzt schon, also hier so bitte nicht anfassen, das versteht außer dem Autor keiner mehr und der ist schon lange nicht mehr im Unternehmen und dann so eine Strichliste, wie viele Leute es schon angefasst haben und daran gescheitert sind.
Ja, genau.
Ja, ich mache mir halt immer so den Gedanken, wenn jetzt jemand GitBlame verwenden würde, oder halt GitLens macht ja auch nichts anderes, bringt ihm das weiter, was ich hier schreibe.
Das ist so, was ich mich dann so frage, wenn ich einen Commit mache.
Und was ich dann halt versuche, ist keine überflüssigen Commits zu machen.
Also wenn ich irgendeine Änderung mache, die ich zwei Commits später wieder rausschmeiße oder an Console.log rauslösche, was ich vergessen habe.
Das sind so die Sachen, wo ich dann sage, hey, da habe ich auch mich selbst in Anspruch, das einfach dann mit einem Fix-Up dann zu beheben direkt.
Also der Commit, der nachher in dem Projekt landet, schon gar kein Console.log mehr drin hat.
Oder die Tests direkt mit in der Commit sind, der auch den Code einführt, der getestet wird.
Also jetzt, wo ich weiß, wie das funktioniert, werde ich das mit Sicherheit auch sehr oft nutzen in Zukunft.
Da bin ich dir echt dankbar, dass dieses Mysterium für mich jetzt gelöst ist.
Was auch ganz praktisch ist, das praktizieren wir bei uns sehr häufig, das sind die sogenannten Fix-Up-Commits.
Du kannst sagen, git commit – fix up und dann den Hash von dem Commit, den du fix upen möchtest.
Was der dann macht, ist erstmal nur ein Commit.
Der hat einen speziellen Namen, der fängt nämlich dann mit Fix-Up-Ausrufezeichen an und dann kommt die Message von dem Commit, den du gerne fix upen möchtest.
Aber es ist erstmal nur ein Commit. Den kannst du pushen, dann hast du nichts gerebased, hackst deine Kollegen nicht ab, etc.
Und dann kannst du zum Schluss hingehen und sagen, okay, du gehst jetzt hin und hast ein Get-Rebase-i, um aufzuräumen.
Und der Parameter Auto-Squash geht dann hin und findet alle Fix-Ups und sortiert die direkt in die richtige Reihenfolge und schreibt vorne das F dran, für den Fix-Up zu machen.
Und da werden die quasi alle in ihr Ziel-Commit erst dann reingestampft.
Somit kannst du diesen Prozess des Rebase, der potenziell Kollegen abhängen kann, weit nach hinten schieben.
Disclaimer, um zu weit nach hinten schiebst, desto höher ist natürlich wieder die Vakantität, desto auf Änderungen basierst die, weil du änderst ja dann die Reihenfolge, nicht das Einsortieren der Fix-Ups, dass das dann auch mal nach hinten losgehen kann.
Aber gerade für so einen Konzonen-Lock-Löschen und so, funktioniert das super.
Cool.
Genau.
Oh Gott.
Ich muss gerade lachen. Ich habe gerade nochmal nach diesem Kommentar gegoogelt, den ich dann auch in Erinnerung hatte. Ich glaube, ich habe ihn gefunden.
Dear Maintainer, once you are done trying to optimize this routine and have realized what a terrible mistake that was, please increment the following counter as a warning to the next guy.
Und dann steht da, total hours wasted here, 42.
Nach so einer Validierung, die ich mir ja immer so ein bisschen mitnehme, kann ich hingehen und einen zufälligen Commit-Name ihn auschecken und ist das Projekt dann lauffähig.
Wisst ihr, was ich meine?
Nee.
Das wegt die Stille.
Ja, du guckst dir dein Instagram an, ja, pickst zufällig irgendeinen Commit-Hash und funktioniert das Projekt dann.
Also wenn du zum Beispiel deine Tests laufen lässt, laufen die durch.
Mhm.
Oder scheitern die, weil später erst ein Commit kommt, der die Tests anpasst oder so.
Okay.
Also das ist für dich dann quasi so die, um herauszufinden, ob du ein Fix abmachen solltest, weil das an sich alleine keinen Sinn macht, der Commit, oder?
Ähm, quasi, ja.
Okay.
Genau.
Was ich halt auch wichtig finde, oder was mir hilft, mir und meinen Kollegen ist, zu überlegen, was mache ich gerade für eine Änderung.
Ich sag mal, wir kennen das ja alle, wir wollen ein Feature irgendwo einbauen und stellen fest, ja, das geht ja gar nicht, weil die Voraussetzung nicht geschaffen ist, dass ich da, keine Ahnung, was einbauen kann.
Und dann fängst du an, erst mal Teile deiner App umzubauen, um dann das neue Feature einbauen zu können, ne?
Und da gehe ich eigentlich ganz gerne hin und mache dann erst mal einen Refactor-Commit, der erst mal die App erweitert, also die Funktion bleibt dieselbe, aber die App ist jetzt in der Lage, das neue Feature aufzunehmen.
Und dann mache ich einen zweiten Commit, der dann das neue Feature einführt.
Okay.
Hatte ich genau heute diesen Fall, ja.
Interessant, ja.
Ich sag mal, im besten Fall braucht halt ein Kollege, der an demselben Feature vielleicht arbeitet oder vielleicht sogar an einem anderen Feature arbeitet, auch genau diese Änderung.
Und dann kann er einfach hingehen, git cherrypick nimmt sich diesen Commit und alle sind glücklich.
Wenn du das alles in einen fetten Commit reinmachst, hast du erst mal das Problem, dass du Merch-Konflikte kriegen kannst, vermehrt, weil du halt umso mehr Änderungen du in einem Commit hast, desto höher ist die Wahrscheinlichkeit, dass der Konflikte kann durch Kollegen,
Änderungen meiner Kollegen.
Ja, und du hast halt voneinander isoliert.
Das finde ich immer sehr praktisch.
Ja, auf jeden Fall.
Unsere Checkliste lichtet sich.
Da habe ich noch...
Ja, sagen wir mal noch.
Ja, als nächsten Punkt hier.
Das gehört eigentlich in einen eigenen Commit.
Das war sowas, was aufkam bei uns im Vorgespräch und wie man das dann nachträglich anstellen würde.
Und fixe das Ding jetzt wieder auseinander.
Genau, also quasi der umgekehrte Fall von dem Squashen, sondern jetzt habe ich das eingecheckt und eigentlich stelle ich fest eben sowas, was du jetzt gesagt hast.
Jetzt habe ich dann diesen Batzen eingecheckt und stelle eigentlich fest, das war jetzt blöd.
Was mache ich denn dann?
Ja, also wahrscheinlich gibt es 20 Lösungen, die das fixen.
Meine Standardlösung ist da mal wieder der interaktive Rebase.
Dann gehe ich an den Commit, der aufgeteilt werden soll, mache dann ein E dran für Edit.
Dann geht Rebase hin, spult bis zu diesem Commit, bleibt dann stehen und ich bin auf der Kommandozeile.
Und dann gehe ich hin, ich habe es eben schon mal erwähnt, ich mache ein Git Reset und setze mich ein Commit weiter zurück.
Aber dann halt mit dem Standardverhalten, Minus Minus Mixed, der dann die ganzen Änderungen bei mir in meinen Working Directory legt.
Und dann kann ich hingehen und kann dann die Sachen einzeln adden und dann den ersten Commit machen und dann adde ich den Rest und mache dann den zweiten.
Man kann dann hingehen und sagen, ja, aber ich will ja doch die Commit Message behalten, weil das habe eigentlich nicht ich committet, sondern der Moritz.
Und da soll jetzt nicht Michael dran stehen, weil ich möchte den Credit dem Moritz aber lassen.
Dann kannst du mit Git Commit Minus Minus Reuse Message quasi den ursprünglichen Hash angeben und dann ist die ursprüngliche Message wieder drin, der Autor, das Datum, quasi eigentlich alles, was du so brauchst.
Und ja, wenn man es so hart sehen möchte.
Cool.
Was auch sehr hilfreich ist, ich weiß nicht, wir haben es noch nicht erwähnt, du hast ja häufig das Ding, hey, die Sachen sollen in getrennte Commits, aber die sind beide in einer Datei.
Ich sage mal, so GUIs, wie jetzt zum Beispiel auch GitHub Desktop, da hast du ja die Möglichkeit, so Dateien zu markieren, die Zeilen zu markieren, die du committen möchtest.
Das ist natürlich auf der Konsole schwierig.
Was da existiert, ist ein Modus, der nennt sich Patch für Git Add.
Also du kannst sagen, Git Add minus P steht für Patch.
Und was dann passiert, ist, dass quasi so ein interaktiver Client quasi aufgeht in deiner Kommandozeile, wo du jeden einzelnen Hang quasi siehst.
Und kannst dann immer mit Y und N entscheiden, möchte ich den adden oder möchte ich ihn nicht adden.
Und kannst dann so halt Teile der Datei auch adden.
Im Endeffekt, die GUIs basieren wahrscheinlich darauf, nehme ich mal an, dass die sich halt das da raussaugen, anstatt da eigene Algorithmen, also über die Diffs darüber zu gehen.
Könnte ich mir jetzt vorstellen.
Wahrscheinlich, aber letztendlich ist es ja auch nur das Hinzufügen eines neuen Lobobjekts.
Und ich sage mal, wenn du schon so einen GUI-Client hast, ich sage mal, dann die Hälfte eines Textes über einen anderen Text drüber zu kopieren und das zu adden, ist wahrscheinlich dann auch nicht mehr die Schwierigkeit.
Ich weiß nicht, ob die jetzt git-add-p intern ausführen, könnte ich dir nicht sagen.
Aber das nutze ich zum Beispiel auch sehr häufig, dass ich dann nur gewisse Sachen adde.
Also zum Beispiel so, du baust irgendwie eine Methode ein und siehst 15 Zeilen weiter oben, hier ist ja der Code-Style gar nicht eingehalten.
Das ist so für mich der Klassiker, wo ich dann einfach nur einen Commit mache, fix Code-Style.
Und dann kommt aber der eigentliche Commit, der dann das neue Feature einbringt.
Okay.
Gehen wir noch einen Schritt weiter in der Liste oder hast du noch was dazu, Michael?
Nee, ich wollte nur gerade nochmal darauf eingehen, ist es jetzt, sieht man es jetzt zu genau, wenn ich jetzt sage, hey, den Code-Style fix, den kommite ich jetzt einfach mit dem Feature mit.
Was soll's, ne?
Das ist nur die eine Zeile, die ich ändere.
Was man sich da vor Augen führen muss, ist, wenn einer genau diese Zeile nachher blämt, steht dann da, hey, ich habe ein neues Feature implementiert.
Obwohl diese Zeile mit diesem neuen Feature gar nichts zu tun hat.
Und da finde ich es einfach besser, wenn er auch einfach nur da steht, Code-Style fix, weil dann weißt du, okay, ich muss noch weiter zurück in die Historie.
Ja, das habe ich schon öfter gehabt.
Und mich nicht wundern, was hat denn das mit diesem Feature zu tun?
Ja, genau.
Ja, sollen wir noch einen Punkt aus der Liste angehen?
Ich glaube, wir haben noch was, wir haben noch zwei Sachen.
Eine Sache, die sich so ein bisschen mit Organisation auch beschäftigt, war die Frage, die kam auch über Twitter.
Wie stellt man ein alteingesessenes Team von einem File-Checkout-Check-In-Prozess auf einen Branch-Git-basierten Prozess um?
Wo ich halt auch so erstmal dachte, das ist eigentlich ein Organisationsproblem und gar kein Git-Problem.
Aber vielleicht können wir ja trotzdem kurz mal drüber reden.
Also wie würdest du jetzt Git in einem Team einführen, das vorher was komplett anderes verwendet hat, um Versionsverwaltung zu machen?
Vielleicht können wir uns so der Frage ein bisschen nähern.
Also keine Ahnung, die machen halt vorher.
Wurde das hier angegeben?
Surround-SCM?
Kenne ich nicht.
Habe ich auch noch nie gehört.
Ich kenne nur sonst SVN.
Ja, genau.
Wie die meisten, die bei Git gelandet sind, die kamen von SVN.
Ich finde es schwierig zu beantworten.
Also wenn ich jetzt mal an den Umstieg von SVN auf Git nachdenke.
Ich sage mal, der Workflow, das Branching, war glaube ich das geringere.
Also was erstmal verwirrend ist, ist, warum habe ich keine Version, keine Revisionsnummern mehr?
Git hat ja so eine laufende Nummer.
Da sind wir ja gerade schon drauf eingegangen.
Das ist das Hashing.
Ich denke, wichtig ist, das Team erstmal irgendwie so ein bisschen auf Git einzuüben,
bevor man mit dem Projekt startet, also mit der Migration des Projekts startet.
Dass man da halt erstmal guckt, dass jeder zumindest grundlegend weiß, wie ist der Git-Workflow.
Dass ich Sachen in die Stage adde, daraus dann ein Commit mache.
Wie funktioniert Branching?
Das sind nur Labels und Commits etc.
Aber ob jetzt der Prozess wirklich anders sein muss, wenn ich mit Branches arbeite.
Also wenn ich jetzt einen langlaufenden Branch habe und da Risiko laufe, Merch-Konflikt zu bekommen,
habe ich den nicht in Git genauso, wie ich ihn auch in SVN hätte?
Ja, wahrscheinlich schon.
Ja, jetzt meine Vermutung.
Also letzten Endes ein Konflikt ist ein Konflikt.
Also wenn du an der gleichen Coachstelle, wenn zwei Leute an der gleichen Coachstelle was machen,
ist es egal, glaube ich, was du machst.
Du wirst einen Konflikt haben.
Also der muss gelöst werden.
Und ja, also ich weiß es auch nicht.
Ich habe auch mal die Transition mitgemacht von SVN zu Git.
Und ich glaube, was mir geholfen hätte, wäre, wenn, also ich habe mir schwer getan damals damit,
weil ich hatte den Eindruck, SVN nimmt einem ein bisschen mehr ab.
Ich kann jetzt nicht genau sagen, woran ich das festmache,
aber das Tooling, was ich damals verwendet habe, habe ich so gedacht,
da muss ich weniger drüber nachdenken.
Und bei Git sind dann halt so diese Rebase-Geschichten passiert,
die ich jetzt auch gerade schon beschrieben habe.
Das ist damals auch schon passiert, wo man dann so davor sitzt und erst mal so denkt,
Okay, ich verstehe jetzt gerade gar nicht, was passiert.
Und ich glaube, wahrscheinlich wäre so ein bisschen Theorie-Schulung am Anfang eine gute Idee,
sodass man die Grundkonzepte versteht.
Dann kommen auch diese Momente, wo man dann sagt,
Moment, scheiße, was ist denn jetzt passiert?
Ich komme mir hier ziemlich blöd vor und verzweifle irgendwie.
Die kommen dann vielleicht auch weniger.
Das ist jetzt einfach so ein Gedanke, den ich jetzt noch dazu hatte.
Also mit SVN hatte ich das auch schon, dass dann irgendwie noch ein Clean-Up geholfen hat,
weil sich irgendwas festgefahren hatte.
Also da weiß ich, ob das jetzt seltener vorkam mit SVN.
Von daher, ich glaube, das gibt sich nicht viel.
Ja, also ich hatte auch, bei mir war der Umstieg auch erst mal schwierig,
weil man nicht versteht, was man wirklich tun muss.
Ich dachte auch, ich hätte Probleme mit Ad gehabt,
aber jetzt hatte ich da nochmal nachgeguckt und SVN hatte eigentlich auch schon das Adden von Dateien.
Deswegen hatte ich das gewundert, wo ich da Probleme hatte.
Aber was mir letztendlich wirklich geholfen hat, war wirklich, wie schon Moritz sagt,
mit der Materie mal auseinanderzusetzen.
Wie funktioniert die Theorie?
Ich weiß nicht, kann ich eine Buchempfehlung raushauen?
Ja, klar.
Auch wenn das Buch, ich glaube, das letzte Mal 2012 aktualisiert wurde.
Solange der Inhalt immer noch aktuell ist.
Ja, ein paar Kommandos haben sich ein bisschen geändert.
Du musst ja zum Beispiel nicht mehr alles mit Checkout machen,
da gibt es ja mittlerweile Switch und Restore und sowas.
Aber das sind halt Details.
Aber ich fand, die haben halt auch das mit den Tree-Objekten so ein bisschen ganz gut erklärt.
Das war das Buch Version Control with Git von dem O'Reilly Verlag.
Das fand ich eigentlich sehr gut.
Und ich bin eigentlich alles andere als ein Bücherwurm.
Und lesen ist echt nicht mein Ding.
Aber das ist auch tatsächlich eins der wenigen Bücher,
die ich von vorne bis hinten gelesen habe.
Also es ist auch nicht so, dass es total trocken ist und einen langweilt.
Das hat mir sehr gut geholfen.
Und für die Leute, die es dann richtig wissen wollen,
was ich ganz cool fand, war ein Vortrag,
den hatte ich auf YouTube gesehen, von Tim Berglund.
Der war damals bei GitHub.
Ich glaube, da ist er heute nicht mehr.
Der heißt Git from the bits up.
Und da erklärt er auch so ein bisschen,
wie die Internas funktionieren mit dem Hashing und so.
Und da hat man auch so ein paar Aha-Effekte,
wo man sagt, jetzt verstehe ich, wohin der Hase läuft.
Und ich finde, dann funktioniert halt auch alles viel einfacher,
weil man einfach versteht, was da jetzt hinten passiert.
Aber einen wichtigen Punkt, finde ich, den wir noch nennen sollten für so einen Umstieg.
Ich weiß nicht, wie es Surround-SCM macht,
aber bei SVN war es ja so, dass man da ein zentrales Repository hat.
Und das ist ja bei Git dann der krasse Unterschied,
dass du da verteilte Repositories hast.
Da hat ja jeder auf seinem Rechner ein Klon und zwar komplett des Repositories.
Das heißt, wenn ich sage Git clone und irgendein Remote angebe,
dann zieht er auch alle Dateien, die jemals existiert haben und packt die bei mir auf die Platte.
Der schöne Nebeneffekt ist dann halt, ich kann sogar in Deutschland mit der Bahn fahren und kann mal einen Branch auschecken oder Commits machen, etc.
Weil ich nicht angewiesen bin, dass ich eine Verbindung zu dem Remote haben muss.
Und wenn die Verbindung wieder da ist, dann kann ich dahin pushen.
Also ein Git Remote muss nicht direkt auch ein GitHub sein.
Das kann theoretisch einfach ein Verzeichnis auf der Festplatte sein.
Also ich könnte theoretisch hingehen und sagen, Git clone, irgendein Verzeichnis auf der Festplatte angeben
und dann habe ich quasi ein Remote geklont und kann dann so auch vielleicht mal Experimente machen.
Was mir vorher noch eingefallen ist, ist bei SVN, korrigiert mich, wenn ich falsch liege,
aber da gab es auch keine Staging Area, oder?
Also das bin ich zu hundertprozentig sicher, aber ich glaube, das war mehr so,
Das war nämlich was, was ich erst lernen musste bei Git.
Das ist das, was diese Staging Area ist, dass es quasi so ein Zwischenzustand ist.
Ich markiere etwas, was ich jetzt committen möchte und das ist aber dann noch nicht committed.
Also so ein Zwischenschritt, also im Vergleich zu SVN ein Zwischenschritt.
Also das war für mich, glaube ich, wichtig, auch um irgendwie so ein bisschen zu verstehen, wie das Ganze funktioniert.
Ja, das war auch meine Erinnerung.
Ich habe nur die Tage nochmal ein bisschen rumgegoogelt und dann dachte ich, Moment, es gibt da ein SVN-Ad.
Und dann habe ich gedacht, ich verstehe es nicht.
Gab es das früher, gab es nicht? Es ist einfach schon so lange her.
Also ich habe ja letztens erzählt, dass ich wieder SVN nutzen musste wegen unserem WordPress-Plugin,
weil das da in deren Struktur immer noch benutzt wird.
Aber ich habe dann auch tatsächlich Tortoise-Git als Client genutzt, als GOI und da gibt es, ich bin mir sicher, es ist wieder eine Woche her, dass ich es genutzt habe und schon wieder vergessen.
Aber ich glaube, da gibt es keine Staging.
Also du wählst dann halt die Dateien aus und dann, wenn du dir dann eincheckst, dann gehen die direkt auch zum Server.
Also da gibt es nicht nochmal einen Zwischenschritt.
Ja, aber ich finde, da merkt man auch so ein bisschen, dass Git da die Möglichkeit schafft, dass du wirklich deine Commits designen kannst.
Dass du wirklich überlegst, okay, welche Erinnerung packe ich da jetzt wirklich rein?
Und dann nachher dann deine Commit-Message dazu schreibst.
Das finde ich, fand ich anfangs schwierig mit dieser Staging-Area.
Ich habe es auch nicht verstanden.
Aber mittlerweile mag ich das sehr, das Konzept.
Also ja, wenn man es mal verstanden hat, dann hilft es einem sehr.
Eben genau, was du gerade gesagt hast, Commits Design.
Ich habe jetzt vielleicht hier irgendwie fünf Files angepasst, weiß aber, dass die einzelnen, ich möchte eigentlich unterschiedlich beschreiben,
weil ich mache unterschiedliche Sachen eigentlich und das kann ich dann nochmal auseinanderklamüsern.
Ziemlich einfach, indem ich einfach nur die ersten, ja.
Du vermeidest das, was wir vorhin besprochen haben, dass du feststellst, ah, das hätte ich vielleicht doch lieber so.
Weil du guckst dir nochmal genau an, bevor du dann wirklich auf Commit klickst, schaust nochmal durch die Datei.
Dann stellst du fest, ah, okay, da ist jetzt nochmal ein Hang drin, den sollte ich nochmal rausmachen und so.
Also das hilft wirklich, ja, dann auch sauberer zu arbeiten und schöner zu arbeiten.
Ja, was vielleicht auch nochmal ein guter Hinweis ist, er hat ja irgendwie gesagt, langlaufende Feature-Branches.
Es ist ein Modell, das habe ich jetzt schon ewig nicht mehr benutzt und zwar nennt sich das Successful-Git-Branching-Modell.
Das ist eigentlich, das ist ein Artikel und da ist Git-Flow raus entwachsen, so eine Skript-Sammlung.
Weil das ist quasi so ein Modell, wie kann man mit Feature-Branches umgehen.
Man hat dann so einen Develop-Branch, der quasi der aktuelle Entwicklungszweig ist.
Daraus bilden sich quasi dann die Features, die wieder in den Develop reingemerged werden.
Daraus wird dann wieder ein Release-Branch gemacht, wo dann das Release dann gestaltet wird.
Da kann man dann hingehen und sagen, okay, ich mache nochmal Commits für dieses Release.
Und zum großen Finale wird das dann in den Master-Branch gemerged und da getaggt, wenn man dann das Release abschließt.
Und das wird dann auch nochmal in den Develop gemerged.
Das kann man vielleicht auch nochmal verlinken, vielleicht hilft das dem einen oder anderen.
Obwohl das heutzutage nicht mehr so häufig benutzt wird, weil die meisten mittlerweile nach diesem GitHub-Flow gehen.
Du zweigst vom Master ab, machst dein Feature fertig und mergst den Master zurück.
Also das sieht man ja sehr häufig mittlerweile, dass die Projekte eigentlich direkt in den Master mergen.
anstatt noch Releases zu designen und so.
Aber ich kann mir gut vorstellen, gerade bei großer Software, wo man vielleicht auch noch alte Versionen supporten muss,
dass da dieses Branching-Modell hilft.
Okay, dann kommen wir eigentlich schon zum allerletzten Punkt auf der Liste.
Gibt es noch irgendwelche geheimen oder unbekannten, wenig genutzten Commands, die praktisch sind und die wir jetzt noch nicht besprechen?
Ich hoffe, ich habe sie alle strategisch gut verteilt gehabt.
Ich wollte gerade sagen, also ich habe schon ganz viel.
Der Punkt ist eigentlich überflüssig, weil ich habe schon so viel gelernt und für mich war vieles unbekannt.
Ich scrolle gerade nochmal durch meine Notizen, ob wir irgendwas übersprungen haben, weil es jetzt im Gesprächsfluss so entstanden ist.
Aber ich denke, all die Sachen sind gekommen.
Also ich finde halt so dieses Git-Add-P für das Partially-Adden für mich eine ganz gute Sache.
Fix-Up-Commits finde ich eine super Sache.
Dann halt interaktiver Read-Base mit dem Editieren von Commits.
Das sind so die Dinge, wo ich denke, ja.
Dann hätte ich vielleicht an der Stelle noch eine kleine Sache, die mir wieder eingefallen ist, die ich ein einziges Mal verwendet habe, die ein Kollege von mir mir gezeigt hat.
Und zwar Git-Bisect.
Ja, ich habe super nachgedacht, ob ich es noch erwähnen soll.
Das ist geil, oder?
Wie gesagt, ich habe es noch einmal gebraucht und es hat damals auch mein Problem tatsächlich nicht gelöst.
Das weiß ich noch.
Ich weiß auch nicht genau, warum nicht, weil eigentlich hätte es mein Problem lösen müssen.
Möchtest du oder soll ich?
Ich kann es nur ganz grob auf einem sehr hohen Level, also von sehr weit oben erzählen.
Du weißt vielleicht besser, wie es funktioniert.
Ich nutze es jetzt auch nicht jeden Tag.
Nein, ich bin ehrlich, ich habe es schon sehr lange nicht mehr genutzt.
Aber was es letztendlich macht, ist, also der Job dieses Commands ist es eigentlich, einen Commit zu finden, der was kaputt gemacht hat.
Und was du letztendlich machst, ist, du gibst ihm die Range an, die er checken soll, indem du sagst, hey, da hinten, da weiß ich noch, da hat es funktioniert.
Und kleiner Funfact am Rande, wie ich dieses Head-Tilde-1 angeben kann.
Da kann ich auch, glaube ich, mit Head, ich meine, ich muss ein Head-Zeichen machen und geschweifte Klammern, da kann ich sogar eine Time-Range angeben.
Das ist jetzt in meinen Recherchen, ich kannte das vorher auch nicht, aber ich dachte, wofür brauche ich das?
Wo du sagen kannst, hey, vor fünf Tagen, also five days ago und so.
Ja, aber es ergibt total Sinn.
Vielleicht darfst du, dass du weißt, gestern ging es noch.
Da hat es doch noch funktioniert.
Ja, genau, genau.
Total logisch.
Also letztendlich, du markierst einen Commit, wo es nicht mehr ging, wo es noch ging und hast halt den Commit heute, wo es nicht mehr geht.
Und was der quasi macht, ist, der checkt dann für dich aus.
Und zwar ist das, glaube ich, eine Binary-Search, die hat am Macht, deswegen heißt es wahrscheinlich auch BISEC.
Genau, ja, so steht es in der Doku.
Und du gehst dann halt immer hin und sagst dem Kommando, ob es jetzt auf diesem Commit geht oder nicht geht.
Und du checkt ja für dich was Neues aus, dann sagst du wieder geht, geht nicht.
Ja, cool.
Und im Optimalfall landest du dann zum Schluss bei dem einen Commit, der den fehlerhaften Code dann hingeführt hat.
Du kannst sogar so weit gehen, dass du es nicht manuell machst, sondern ihm noch einen Command mitgibst,
was er ausführen soll.
Also wenn du zum Beispiel fleißig Tests geschrieben hast, könntest du quasi das Laufen deiner Tests quasi mit angeben.
Und dann, je nachdem, was er für den Statuscode zurückgibt, 1 oder 0, weißt dann BISEC, ob das erfolgreich war oder nicht.
Und dann musst du dich eigentlich nur zurücklehnen und zugucken.
Und irgendwann sagt er dir hier, das ist der Commit, wo der Fehler reingekommen ist.
Oder es ist der erste Commit, bei dem deine Tests fehlschlagen.
Genau, das ist nämlich noch der Punkt und das ist auch das, warum ich vermute, dass es bei mir damals,
nicht zum Ergebnis geführt hat, ist, man kann ja etwas über mehrere Commits hinweg kaputt machen.
Und dann gibt es einen Punkt, wo es dann kaputt geht, also wo dann quasi der Test fehlschlägt.
Aber vielleicht haben andere Sachen vorher schon dazu geführt, dass es dann irgendwie langsam kaputt gegangen ist.
Das war dann nur so quasi das eine Bit, das quasi gekippt ist, was dann den Test hat fehlschlagen lassen oder das Feature kaputt gemacht hat.
Aber ja, genau. Aber das ist, das fand ich einmal, das fand ich extrem krass, dass es sowas gibt und irgendwie eine sehr, sehr gute Idee.
Weil das ist bei der Fehlersuche immer interessant, auch mal zu gucken, wo ist das denn jetzt überhaupt kaputt gegangen.
Auf jeden Fall, coole Idee, das Kommando. Also ich finde es, ja, macht total Spaß, sowas zu sehen.
Ja.
Aber man muss erst mal wissen, dass es das gibt. Da hätte ich nie, also wenn ich, wenn das nicht ein Kollege von mir gesagt hätte, ah ja, macht doch mal Git Bisect, wäre ich nie drauf, ich hätte nicht mal danach gesucht, ob es sowas gibt.
Ja, klar.
Ja.
Es ist so ein typisch verstecktes Kommando, wo man erst mal, wo man vielleicht gar nicht drauf kommt, dass es sowas geben könnte. Also jetzt wisst ihr es.
Es ist doch schön, dass wir jetzt dazu beitragen konnten, dass es in die Welt getragen wird, oder?
Genau, hier. Morgen drucken wir Fanshirts. Git Bisects-Fangruppe, ja.
Ja, demnächst in unserem Merchandising-Shop.
Was ich noch ganz cool finde, das ist wahrscheinlich auch nichts, was jeder braucht. Es gibt, das ist aber ein Skript, was du dir dazu installieren kannst, und zwar nennt sich das Git-Filter-Repo. Ich schiebe dir gleich mal den Link, Boris.
Das ist ganz cool, wenn man mal in der Situation war, dass man gesagt hat, boah, Mono-Repo, das ist doch das Ding. Und irgendwann denkt man sich, ja, war doch nicht so das Ding. Ich hätte das doch ganz gerne wieder aufgeteilt.
Vielleicht möchte man ja seine History behalten. Und dieses Git-Filter-Repo ist so eine Skriptsammlung letztendlich, wo du dann einfach die Möglichkeit hast, zu sagen, was für Commits sollen rausgefiltert werden.
Da kann der Verzeichnisse noch neu schreiben, dass du zum Beispiel das, was vorher unter Packages, Slash, was auch immer lag, dann direkt im Root liegt und so Geschichten.
Ja, das habe ich jetzt schon so zwei-, dreimal eingesetzt, wo man dann Repositories zerlegt hat, weil man sie jetzt doch vielleicht in GitHub einzelt haben möchte, damit dann die Pipelines besser funktionieren.
Oder man das direkt nach Netlify pushen kann, das weiß ich nicht. Ja, das fand ich auch eigentlich ganz cool.
Cool. Dann sind wir, glaube ich, so weit durch, oder?
Mensch, das war ein Ritt. Ich glaube, das muss ich mir noch dreimal anhören, um alles zu verstehen.
Ja, ich habe noch nie so viel gelernt in unserer eigenen Folge wie diesmal. Ja, echt cool.
Danke kurz, sehr kurz zur Sendung.
Bitte? Sehr kurze Sendung. Aber wir sind jetzt bei zwei Stunden zehn gleich.
Etwas über zwei Stunden schon, ja.
Gut, dann, ich würde jetzt, ich muss seit ungefähr einer Stunde schon, ganz dringend mal wohin, entweder macht ihr weiter oder wir machen eine kurze Pause und machen dann mit dem nächsten Punkt weiter.
Guck mal, spiel doch den Jingle ein und geh dann und dann macht Michael das, was dann kommt.
Okay, und ich beeile mich, weil das will ich nämlich natürlich auch noch hören.
Genau, dann beeile dich.
Bin ich gleich wieder da.
Ja, der Michael hat ein Geilteil mitgebracht und wir wissen gar nicht, was es ist und wir lassen uns jetzt einfach davon überraschen.
Ja, also ein ganz persönlicher Geilteil. Das ist ja bei vielen Leuten sehr unterschiedlich, was sie geil finden.
Bei mir war es ein YouTube-Video von einem YouTuber, der sich Sebastian, ich glaube, man spricht das Lake aus, Largway geschrieben.
Der macht eigentlich so Unity-Zeug.
Ich gucke denen aber immer total gerne zu, auch wenn ich nie was mit Unity mache.
Einfach, um zu sehen, wie er es macht und wie er mit Algorithmen da rangeht und so.
Und er hat jetzt letztens eine Ameisensimulation gebaut und ich war total fasziniert, wie nachher diese Ameisen, also er simuliert quasi, wie die mit Pheromonen umgehen, wenn sie auf der Suche nach Nahrung sind, wenn sie Nahrung gefunden haben.
Und wie sich dann plötzlich dieses System entwickelt von 500 Ameisen, die dann nachher alle gezielt zu Nahrungsplätzen laufen, fand ich total faszinierend.
Und ja, packen wir auf jeden Fall die Shownotes.
Genau, ich schaue es mir gerade an.
Also ich habe gerade mal den Anfangsscreen mir angeschaut.
Das sieht schon faszinierend aus.
Und wenn ich das richtig sehe, codet er so einmal durch, diese ganze Geschichte.
Oh ja, das wird sehr interessant, wenn man mal ein bisschen weiterklickt.
Ich bin jetzt gerade mal irgendwie so bei zu neun Minuten gesprungen.
Da wird das schon interessant, weil die dann, man sieht da ganz viele Ameisen rumwuseln in so einem Bereich, der beschränkt ist.
Also so irgendwie so eine Art Ameisenbau.
Und dann sieht man auch, die laufen irgendwo hin und sammeln da was ein und bringen es woanders hin.
Und also man sieht irgendwie so eine Ameisenstraße und das scheint irgendwie alles da mit Code realisiert zu sein.
Echt sehr faszinierend.
Stimmt.
An der ich mich selbst wiedergesehen habe, war, du erzählst gerade so einen Ameisenbau.
Und er erzählt so, dass er das in einem älteren Projekt schon mal gemacht hat.
Und er hat jetzt diesen Code entsprechend angepasst und auch noch eingebaut,
dass man jetzt mit einem Pinsel noch was hinzufügen kann in das Labyrinth und rausnehmen kann.
Und ja, er weiß, er hätte das in Paint in zwei Minuten malen können, aber ...
Ja, aber dann wäre es nicht so geil.
An der Stelle sei nochmal verwiesen auf eine Folge, ich weiß nicht mehr genau, welche Nummer das war,
wo ich auch mal ein bisschen was über Unity erzählt habe, weil wir haben,
ich habe auch mal ein bisschen was mit Unity gebastelt, einfach mal so, um ein bisschen auszuprobieren.
Vielleicht weiß da Konstantin, der uns, der wieder da ist, vielleicht noch, welche Folge das war.
Ich suche schnell in unserer geheimen Suche nach Unity und habe aber gleich, ich habe ganz viele.
Nummer drei, Nummer vier, Nummer fünfzehn, Nummer achtzehn, Nummer neunzehn.
Nein, das kann nicht sein.
Das kann nicht sein. Die Suche muss kaputt sein.
Das kann nicht sein.
Ich hätte jetzt vermutet, es ist zwei Folgen her, wo du das erzählt hast.
Ich glaube, es ist noch länger.
Und für dich wäre wahrscheinlich auch der Rest des Kanadens interessant.
Unity Engine Nummer achtzehn.
Nummer achtzehn, ja.
Genau, wir sind jetzt bei 25, es ist noch ein bisschen länger her.
Also ich erinnere mich, also es muss auf jeden Fall im November gewesen sein, letztes Jahr.
Genau, das kommt hin, ja.
Folge Nummer achtzehn.
Ja, jetzt hast du es leider schon verpasst.
Ja, ich freue mich jetzt aufs nochmal durchhören, was ich ja eh immer mache.
Und jetzt nehme ich dann auch sogar noch neue Informationen mit, während ich das tue.
Ich glaube, es ist was für dich.
Auf jeden Fall.
Ich weiß nämlich, du hast schon öfter coole Sachen empfohlen und Sachen, die vielleicht
in eine ähnliche Richtung gehen.
Ich glaube, das könnte was für dich sein.
Ich bin gespannt.
Ja, dann soll ich mit meinem Geilteil noch weitermachen?
Ja, bitte.
Seid ihr am Ende.
Ja, meins greift auch nochmal direkt auf das Thema GitHub zurück.
Und da bin ich zufällig gar nicht mal aktiv auf der Suche, sondern zufällig über Twitter
drauf gestoßen.
Und zwar ist das, also erstmal, es ist von Mary Rose Cook.
Der Name hat mir vorher nichts gesagt.
Und die hat zunächst mal in 600 Worten beschrieben, was Git ist.
Also ganz kurz zusammengefasst mit einem Beispiel, quasi auf dem Dateisystem, was da so passiert.
Gibt aber auch noch einen längeren Artikel dazu.
Und im Anschluss hat sie in tausend Zeilen JavaScript Git nachprogrammiert.
Quasi.
What?
Ja, und zwar nicht, um das jetzt irgendwie abzulösen und da was Eigenes zu bauen und das produktiv
einzusetzen, sondern um es selbst zu verstehen und aber eben halt auch jetzt kommentiert, also
wirklich super kommentiert den Code für andere, um zu verstehen, was da auf dem Code ist.
auf Dateiebene stattfindet.
Also schon die Funktionsnamen, so wie die Git-Commands auch tatsächlich lauten.
Nur, dass du halt genau siehst, welche Datei wird da angepackt und was genau wird da reingeschrieben
und so.
Also das fand ich ziemlich cool.
Ich habe es jetzt noch nicht komplett durchgearbeitet, aber es sieht sehr cool aus und sehr clean.
Auch rechts den Code und links dann die Kommentare dazu, was da genau passiert.
Also sieht es sehr interessant aus.
Und die lange Version, also das kommt natürlich auch alles in die Shownotes rein, die lange Version
aus 6.000 Wörtern, die nennt sich Git from the inside out und die gibt es einmal als Text
zum Nachlesen, aber auch als Talk auf YouTube und das packe ich natürlich auch rein.
Ja, das ist nicht, also es geht nicht ganz so identif wie jetzt Rebase und Squash und so,
ist da glaube ich jetzt nicht enthalten, aber so, also was da in dem Git-Ordner zum Beispiel
passiert, wo wir es jetzt ja auch vorhin drüber hatten mit den Hashes und sowas, auch da geht
sie drauf ein und das ist ein sehr interessanter Ansatz, um sowas zu erläutern, finde ich.
Also kenne ich jetzt auch noch nicht von was anderem.
Also das wirklich anhand von Code nachgeschrieben, sich anzuschauen.
Ich glaube, das führt schon dazu, dass man ein relativ tiefes Verständnis bekommt, was
da abläuft.
Ja, das war es auch schon.
Ich habe gerade herausgefunden, warum in unserer Suche nach Unity so viele Ergebnisse kommen.
Wegen Community?
Wegen Community, genau.
Ja, also eigentlich funktioniert die Suche ja dann schon ganz gut.
Ich hätte halt dann nur erwartet, dass das, wo Unity wirklich alleine steht, dann ganz
oben kommt.
So cool ist die WordPress-Suche dann offenbar doch nicht.
Vielleicht kommt aber auch dann da Community zweimal vor bei dem ersten Ergebnis und ...
Nee, ich glaube, die sortiert tatsächlich einfach nur nach Folge aufsteigend.
Also beziehungsweise absteigend.
Ja, das kommt tatsächlich nur einmal.
Okay, gut, ja.
Ach so, stimmt, klar, natürlich die neueste zuerst sozusagen.
Deswegen, ja, genau.
Alright.
Dann kommt jetzt unser fehlender ...
Schluss-Jingle, ja.
Und dann ziehen wir jetzt echt durch.
Zwei Stunden 15.
Mensch, Michael, vielen Dank, dass du dabei warst.
Ja, das war eine große Freude.
Also ich glaube, du hast uns auf jeden Fall sehr weitergeholfen, vielleicht auch dem
ein oder anderen Hörer oder Hörerin.
Ja, davon gehe ich draus.
Hoffen wir mal.
Ich glaube, es ist keine Schande, deine Ausführungen mehrfach zu hören, behaupte ich jetzt mal,
bis man es vielleicht verstanden hat und sich noch ein bisschen Literatur
nebenher zurechtzulegen, weil das, ich glaube, es geht teilweise schon ziemlich in die Tiefe
von Git.
Aber ich glaube, es lohnt sich, wenn man ein bisschen tiefer einsteigt, um eben genauso komische
Probleme zu vermeiden, die, wie ich es schon beschrieben habe, die bei mir immer auftauchen.
Und dann, dass man am Ende auch einen schönen Git-Graph kriegt.
Das ist ja scheinbar die große Kunst, ist am Ende die gerade Linie zu haben.
Nein, nein, nein, nein, nein, ich wollte gerade sagen, es ist kein Graph, eine Linie.
Ja, genau.
Also bei Git-Graph kommt die Linie am Ende.
Ja, Mensch, hast du noch was?
Irgendwas noch vergessen, was du noch sagen willst?
Deine Mutter grüßen?
Genau, also der Gast hat das letzte Wort.
Ich fürchte, Mama weiß nicht, was ein Podcast ist.
Ich bin ruhig, habe alles gesagt, was ich sagen wollte, hat mich total gefreut, mal dabei
zu sein, nicht immer nur am anderen Ende zu sitzen und zuzuhören und ja, hat mir sehr
viel Spaß gemacht.
Uns auch?
Cool.
Dann.
Vielen Dank.
Lass dich schon mal die Outro-Musik einplätschern und bis zum nächsten Mal.
Bis dann.
Ciao.
Tschüss.