Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > General Coding > Coding Tutorials
You last visited: Today at 22:42

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[Tutorial] Git Grundlagen

Discussion on [Tutorial] Git Grundlagen within the Coding Tutorials forum part of the General Coding category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Feb 2009
Posts: 1,120
Received Thanks: 550
[Tutorial] Git Grundlagen

Mir war langweilig und mir ist aufgefallen das es hier kein Tutorial zu VCS gibt, obwohl es für Programmierer extrem hilfreich sein kann

Erst mal was ist ein Versionskontrollsystem VCS. Ein VCS erlaubt es Code änderungen zu versionieren und damit zu dokumentieren. Zum einen erlaubt das änderungen zu backupen und allein das ist schon grund genug ein VCS zu benutzen. Wer ohne Git oder SVN oder Mercurial, etc. programmiert sollte ganz schnell damit anfangen, undzwar für jedes Projekt. Github, Gitlab oder Bitbucket bieten einem dabei Server dienste zum Backupen des Codes und Teilen mit anderen an. Ein weiteres Feature von VCS ist es das man Änderungen, dardurch das sie in einzelne Versionen unterteilt sind, ganz einfach im Detail betrachten kann, und so wenn man bugs sucht, einfach alte versionen auschecken kann. Zu guter letzt erlauben es VCS mit anderen zusammen an einem Projekt zu arbeiten, sodass die Commits von jedem einzelnen einfach und strukturiert zusammengefügt werden können, ohne das zusätzlicher overhead erzeugt wird.

Das VCS system was die Versionskontrollkriege gewonnen hat ist Git (mostly weils vom Torvald ist und sein name Gewicht hat, nicht unbedingt weils das beste ist) und daher muss jeder Programmierer der was auf sich hält sich zumindest mal grundlegend damit auseinander setzen.

Git basiert auf einem Graphen. Die Knoten des Graphen sind so genannte Commits. Diese bezeichnen Momentaufnahmen (Snapshots) des aktuellen Code Status und bestehen im wesentlichen aus drei Dingen:
1. Allen Vorgänger-Commits auf denen es aufbaut, welche die Kanten im Graphen darstellen
2. Meta Informationen, wer den Commit verfasst hat (Name, E-Mail), wann der Commit getätigt wurde sowie eine kleine Nachricht (Message) was der Commit denn macht
3. Die Code Änderungen zu den Vorgängern
Über diese 3 Sachen wird dann ein Hash gebildet, über den jeder Commit eindeutig identifiziert werden kann.

Ein kleines Beispiel, ich arbeite an einem Git Projekt und habe grade eine Funktion hinzugefügt. Dann würde ich einen neuen Commit erstellen, welcher diese Funktion enthält, eine Message wie "Adding Function XXX" zusammen mit meinem Namen, den aktuellen Datum und einer Referenz was die Version war mit der ich angefangen habe.

Die Commits die sich gegenseitig Verlinken (da jeder Commit einen Verweis auf den vorrigen Commit enthält) bilden damit den oben erwähnten Graphen. Ein Git repository speichert nun diesen Graphen und stellt eine akutelle Arbeitsversion, den Working Tree, bereit. Der Working Tree basiert dabei auf einem Commit, der wird HEAD genannt, also der aktuelle Commit den wir betrachten. Wenn wir einen neuen Commit hinzufügen, wird der aktuelle HEAD als Vorgänger in dem Commit vermerkt.
Während Git zwar jeden Commit einzeln über einen Hash addressieren kann, arbeitet man für gewöhnlich auf so genannten Branchen. Ein Branch ist eine Serie an Commits der man praktisch einen Namen gibt. Der Branch selbst bezeichnet dann praktisch den letzen Commit in der Serie. Der Standard-Branch ist der "master" Branch, den es in jedem Repository gibt.
Doch mal zum praktischen Teil. Wenn man Git installiert hat (), kann man das git programm einfach über die Kommandozeile bedienen (für Windows wird eine eigene "Git-Bash" mitgeliefert, die die grundlegenden Unix-Shell funktionen zur Verfügung stellt). Sagen wir mal wir haben ein Projekt in einem Ordner, so müssen wir erst mal ein Git Repository dafür in diesem Ordner erstellen. Dafür navigieren wir unsere Shell in den Projektordner und rufen "git init" auf:

Das Kommando "git status" berichtet über den aktuellen Status des Git repositories. In dem Bild oben können wir sehen, dass zunächst einmal der master Branch erzeugt wurde, dieser branch aber noch keinen Commit enthält. Außerdem sagt git uns das es die Datei tutorial.txt, an der ich grade schreibe, in dem Ordner gibt, allerdings diese nicht im git repository hinzugefügt ist, also "untracked" (Änderungen werden nicht verfolgt) ist. Das wollen wir schnell mal ändern, und fügen einen ersten Commit hinzu, mit dem Inhalt den ich bis jetzt geschrieben habe.
Dafür müssen wir git zunächst einmal sagen welche dateien wir denn Commiten wollen. Das geht über "git add Dateiname1 [Dateiname2 [...]]" (für die Leute die ungewohnt mit der typischen schreibweise für Kommandozeilen Manuals sind, was in "[" und "]" steht ist optional, oben das bedeutet also das man beliebig viele Dateinamen angeben kann). Wenn man alle Dateien hinzufügen möchte die als untracked gekennzeichnet sind (im git status), kann man einfach "git add -A" verwenden. In meinem Fall führe ich also jetzt "git add tutorial.txt" aus:

Das "git status" sagt uns nun das eine änderung zum Commit vorgemerkt wurde, die erstellung der datei tutorial.txt (außerdem erkennt git den Screenshot von oben als neue Datei, den will ich aber nicht commiten). Diese vorgemerkten Änderungen nennt man stage. Das wichtige dabei ist, es wird die Datei so vorgemerkt wie zu dem Zeitpunkt des "git add". Die Änderungen die ich seit dem gemacht hab sind da nicht drin, wie ein weiteres "git status" nach ein paar Änderungen zeigt:



Der nächste Schritt ist das Erstellen des eigentlichen commits. Doch bevor wir commiten können, müssen wir git erst einmal sagen wer wir sind. Das geht via "git config".
[code=text]$> git config --global user.name "Vorname Nachname"
$> git config --global user.email ""[/code]
Das --global setzt diese Einstellung für den Benutzer dieses PC's, wenn man es weg lässt wird es nur für dieses Repositroy gesetzt (z.B. wenn man eine Firmenmail hat und eine Private Mail).
Nachdem wir git gesagt haben wer wir sind, können wir nun mit "git commit" commiten. Wenn man git commit ohne weitere Argumente aufruft, öffnet sich der für Git eingestellte Editor (Vim oder Nano standardmäßig) um eine Commit Nachricht einzutragen:

Als Nachricht habe ich "Initial Commit" gewählt, da das die standardmäßige Nachricht ist die bekannte Git plattformen wie GitHub oder GitLab für neue repositories immer wählen. Zeilen die mit einem "#" anfangen sind auskommentiert, und werden nicht als Commit Message betrachtet. Diese geben nochmal grundlegend die Zusammenfassung die einem git status anzeigt. Dann speichert und schließt man den Editor einfach. Wenn man den Commit abbrechen will, schreibt man einfach nichts rein (also eine Leere Commit Message/nur kommentare drin) und speichert und schließt den Editor (z.B. wenn man bei der Zusammenfassung in den Kommentaren merkt das man was commited was eigentlich nicht commited werden soll, wie Debug Code).
Der "git commit" Befehl kann noch einige Argumente nehmen. "git commit -a" z.B. staged automatisch alle modifikationen in getrackted files (also alles was im "git status" unter "changes not staged for commit" fällt, nicht die "untracked files") vor dem Commit, kann also alle Änderungen gleich mit commiten, ohne das man ein "git add" vorher machen muss. Außerdem gibt es noch die -m Option, mit der man direkt die Commit Message übergeben kann, also z.B. "git commit -m "Initial Commit". Davon würde ich aber strikt abraten aus zwei Gründen. Zum einen fehlt einem die Übersicht im Commit Editor (über was commited wird, was untracked ist, etc.), sowie die möglichkeit abzubrechen, wenn man das nicht Commiten möchte. Grade zusammen mit der -a Option, kann es sehr leicht passieren das man außversehen Debug Code o.ä. mit Commited den man eigentlich draußen lassen würde, und ein schnelles drüberschauen über die Kommentare im Editor kann einem aufwändiges zurücksetzen im Nachinein ersparen. Zum anderen haben Plattformen wie GitHub oder GitLab syntaktische hervorhebung für Code über "``". D.h. wenn man einen Ausdruck als Code markieren will, setzt man den in ``, z.B. wenn man eine Funktion hinzufügt könnte die Message so aussehen: "Adding Function `FunctionThatDoesSomeStuff`", um klarzustellen das der Funktionsnamen im Source FunctionThatDoesSomeStuff ist. Das Problem ist nun das `` in Bash einen Befehl kennzeichnen der Ausgeführt werden soll. Wenn man also z.b. sowas schreibt: git commit -m "Adding description for `rm -rf /`" hat man schwup die wupp sein gesammtes Linux system gelöscht, da die Bash dumm wie sie ist, einfach "rm -rf /" ausführt. Daher empfehle ich nicht -m zu benutzen.

Jetzt nach meinem Commit habe ich ein gutes Stück weiter an diesem Tutorial gearbeitet, und würde gerne die neuen Änderungen commiten. Das geht jetzt ganz einfach über "git commit -a" wie oben beschrieben. Nun möchte ich meine bisherigen 2 Commits sehen. Dafür gibt es den Befehl "git log" (da ich nicht möchte das irgendwer der diesen Beitrag findet mir einfach so Mails schickt habe ich meine E-Mail addresse zensiert):

Das log zeigt die Commits, sortiert nach der Reihenfolge im Graphen, mit der Message, Datum, Committer Name und E-Mail, sowie eindeutigem Hash an. Außerdem markiert uns git log noch welche Branches auf welche Commits zeigen. In meinem Fall ist master = HEAD und sie zeigen auf den neusten Commit den ich grade gemacht hab.
Jetzt möchte ich aber bevor ich commite sehen was genau commited wird. Dafür gibt es "git diff". Ohne weitere Argumente zeigt "git diff" die Anderungen an den getrackten Dateien gegen HEAD an. In meinem Fall also alles was ich an der tutorial.txt seit dem Letzten commit geändert habe:

Das rote sind die Zeilen die gelöscht wurden, das grüne die Zeilen die hinzugefügt wurden, und das graue die Zeilen die gleich geblieben sind. Das diff basiert dabei auf Zeilenbasis, eine änderung in einem Wort, führt also dazu das diese Zeile in der alten Fassung gelöscht wurde (also rot erscheint) und in der neuen Fassung direkt drunter hinzugefügt wurde (also in grün).

Ich kann mir aber auch die unterschiede zu einzelnen Commits anzeigen lassen "git log 2ef5dba7c" zeigt mir z.B. die unterschiede zwischen meiner akutellen Arbeitskopie und dem Initialen Commit 2ef5dba7ca056e1803aa492b23aed060ab8777a4 (kann für die Befehle abgekürzt werden auf die ersten paar zeichen des Hashs) an. Die Unterschiede zwischen zwei Commits lassen sich via "git diff commitID1 commitID2" anzeigen lassen, wobei das git diff die änderungen von Commit1 zu Commit2 anzeigt (wenn man also die beiden vertauscht ist das was vorher rot war grün und anders rum, da die änderungen praktisch dann die Rückgänigmachung wären).
Man kann Commits auch relativ zu anderen Commits identifizieren. Dafür kann man über ~ in der Historie zurückgehen. "02501047d9~1" bezeichnet damit den ersten commit vor "02501047d9". "git diff 02501047d9~1 02501047d9" zeigt also die unterschiede an die der Commit 02501047d9 hinzugefügt hat (also die unterschiede Zwischen dem Initial Commit und dem zweiten Commit). Außerdem können Commits auch über Branch Namen angesprochen werden. "git diff HEAD~2" gibt mir also die änderungen der letzten 2 commits zurück.

Nun, da wir wissen wie wir Commits erstellen, uns die Historie anschauen und Änderungen im Detail betrachten können, kommen wir zu den etwas komplexeren Themen. Sagen wir mal wir haben in unserer Software einen Bug festgestellt der vorher noch nicht da war, und wollen feststellen wann dieser dazu kam, du möchtest also zurück zu einer älteren Version gehen. Das geht über "git checkout" Wenn wir unser Repository als Graph betrachten, so ist unser aktuelles Arbeitsverzeichnis eine Instanz einer Commits. Der Commit den wir uns aktuell betrachten wird über den HEAD markiert. Wenn wir jetzt also ein "git checkout" machen wird der HEAD auf einen anderen Commit gesetzt, und damit dieser Commit in unser Arbeitsverzeichnis geschrieben. Für dieses Beispiel checken wir doch einfach mal den "Initial Commit" aus


Zunächst einmal gibt uns Git hier ne ganze Menge text. Der Grund dafür ist, das nun unser HEAD auf einen Commit zeigt, und nicht mehr Teil eines Branches ist. Der Commit liegt zwar auf dem "master" branch, aber wir sind dennoch jetzt im detached HEAD mode, was heißt, das jeder Commit den wir jetzt machen würden, zu keinem Branch hinzugefügt werden würde. Wenn wir also was anderes auschecken, gibt es keinen Branch, und damit keinen Namen, mit dem wir den Commit wieder finden würden, und damit ist dieser Commit verloren. Wir haben keine Möglichkeit den wieder zu finden, daher sagt uns diese Nachricht wie wir in solchen Fällen agieren können.

Die letzte Zeile, die ich markiert habe, sagt uns nun das wir den Commit 2ef5dba Initial Commit wiederhergestellt haben, und unser Arbeitsverzeichnis in dem Zustand dieses Commits ist. Jetzt könnten wir z.B. unsere Anwendung testen, ob der Bug immernoch vorkommt. Und wenn wir damit fertig sind, und auf dem "master" Branch weiterarbeiten wollen, müssen wir den wieder Auschecken mittels "git checkout master".
Wenn man nur einzelne Dateien zurücksetzen möchte, geht das über "git checkout -- PFADE". z.B. "git checkout HEAD~1 -- tutorial.txt" würde die tutorial.txt auf die version vor dem letzten Commit zurücksetzen. Das ist oft Hilfreich wenn man änderungen die man gemacht hat verwefen will, einfach "git checkout HEAD -- pfad/zu/einer/Datei" eintippen und die Datei pfad/zu/einer/Datei wird dann wieder auf den Zustand des letzten Commits zurückgesetzt.

Es kommt öfter als man möchte vor, das man etwas commited hat was man nicht möchte, oder einfach einen Commit komplett löschen will. Dafür gibt es den befehl "git reset COMMIT". Dieser setzt den aktuellen Branch auf einen neuen Commit. Man unterscheidet hierbei zwischen Soft- und Hard-Reset. Bei einem Soft Reset wird der Commit zwar vom Branch entfernt, aber die Änderungen bleiben lokal erhalten. Sagen wir mal du hast eine Datei commited die du eigentlich nicht drin haben willst und merkst das erst nach dem Commit z.B. habe ich jetzt die Git-Init.jpg commited und sehe das dann an der Nachricht beim git commit. Dann kann ich einfach mittels soft reset das ganze zurücksetzen und nochmal neu, richtig commiten, ohne irgendwelche daten zu verlieren:

Der Hard Reset resettet auch das Arbeitsverzeichnis, und löscht die Änderungen damit permanent. Damit sollte man sehr vorsichtig sein. Den macht man mit "git reset --hard COMMIT".

Es kommt öfter mal vor das man vor einem "git checkout" oder "git reset" bereits einige änderungen an seinem Code gemacht hat, die aber noch nicht soweit sind das man einen eigenen Commit dafür machen will. Um solche änderungen zwischen zu speichern, bevor man eventuell größere Änderungen an dem Repository vornimmt, kann man diese änderungen im stash zwischenspeichern. Der stash ist ein Stack von Arbeitsänderungen. Ich kann auf den stash pushen, mit "git stash push" oder kurz "git stash", und den letzten Stash mit "git stash pop" wiederherstellen. Wenn ich also jetzt in der Commit historie zurückgehen will, ohne einen neuen commit zu machen, würde ich meine änderungen zu erst Stashen, dann den checkout machen, und dann wieder unstashen:

Eine weitere schöne eigenschaft von git stash ist, wenn ich z.B. grade ein Feature entwickle und plötzlich ein Bug auftritt, kann ich meine änderungen einfach stashen, schauen ob sie durch die aktuellen Änderungen kamen und wenn ja, kann ich den stash wieder popen und die Fehlerquelle suchen. Mit -- kann man auch einfach einzelne Dateien stashen:
[code=text]$> git stash push -- tutorial.txt
...
$> git stash pop[/code]

Damit wären so die grundlegenden Basics der git Versionskontrolle abgedeckt, kommen wir zu etwas komplexeren Dingen. Wie bereits erwähnt gibt es Branches, die praktisch eine reihe an Commits bezeichnen. Branches haben mehrere Gründe. Zum einen wird Git Plattformen wie GitHub oft zum veröffentlichen von Software verwendet. Dabei will man dann sicherstellen das der master branch immer eine halbwegs stabile version ist, bzw. zumindest sollte der master branch immer Kompilieren. Wenn man ein solches Projekt am laufen hat und ein neues Feature entwickeln will, möchte man trozdem seine Arbeit auf dem Server sichern. Um den master Branch stabil zu halten, sollte man daher auf einem neuen Branch arbeiten. Ein anderer Einsatzweck für Branches ist wenn man mit mehreren Leuten an einem Projekt arbeiten, möchte man nicht unbedingt immer jede Änderung von jedem Teammitglied immer synchronisieren müssen. Dafür kann jedes Teammitglied einen eigenen Branch für seine Zwecke erzeugen, dieser basiert dann auf dem neusten master commit zu der Zeit zu der der Branch erzeugt wurde und somit arbeitet jeder für sich, und am ende müssen dann nur einmal alle Branches synchronisiert (gemerged) werden.
Um einen branch zu erzeugen kann man "git checkout -b branchName" verwenden, das erzeugt einen Branch und wechselt direkt zu diesem. Sagen wir mal ich hätte jetzt einen Korrekturleser, der dieses Tutorial gegen ließt und einige rechtschreibfehler korrigieren möchte:

Hier wird ein neuer Branch corrections erstellt, auf dem dann ein neuer Commit mit Typo Fixes erstellt wird. Im git Log ist dann zu sehen das sich dieser branch um einen Commit von master unterscheidet.

Wenn ich nun diese Änderungen auf master übernehmen will mache ich einen so genannten merge, mit "git merge":

Dafür gehe ich zu erst wieder auf den master branch (in den ich ja reinmergen möchte), und sage dann "git merge corrections". Jetzt übernimmt git automatisch die Änderungen vom branch corrections und wendet sie auf master an. Den branch corrections kann ich dann nach dem merge mittels "git branch -D corrections" löschen.
Wenn es bei einem Merge zu einem Konflikt kommt, z.B. wurde auf dem master branch weiteres bearbeitet, wovon corrections nichts weiß, so versucht git diese beim merge automatisch aufzulösen. Wenn das schief geht muss man das per hand machen. Das geht aber für dieses Tutorial zu weit, da dieses Tutorial vorerst nur an Leute gerichtet ist die alleine git verwenden und das eher ein Team problem ist.

Wenn man mehrere Branches hat, kann man die sachen die oben mit commits gemacht wurden natürlich auch mit branches machen. So kann man z.B. master auf den aktuellen commit von corrections setzen via "git reset [--hard] corrections".

Zum Schluss möchte ich noch kurz auf Online Repositories zu sprechen kommen. Ob man nun git verwendet um seinen Code auf GitHub o.ä. zu veröffentlichen, oder einfach ein online Backup haben möchte, so muss man sein git Repository mit einem Online Repository, einem so genannten Remote, verbinden.
Wenn man z.B. auf GitHub ein Repository hat, ein frisch erstelltes, oder ein bereits bestehendes, so findet man (meist irgendwo oben auf der Startseite des Repos) eine "clone URL". Diese gibt es für SSH oder HTTPS, zwei protokolle die git kann. Auf die beiden Methoden werde ich später nochmal genauer eingehen. Zunächst einmal arbeiten wir aber mit der HTTPS URL.
Gehen wir jetzt erst mal von dem Fall aus das wir unser Repository auf GitHub hochladen wollen. Dann erstellen wir zunächst einmal ein Leeres Repository auf GitHub (wichtig, weder ReadMe noch gitignore erzeugen lassen)
Da sehen wir dann auch schon kurze Erklärung wie es weiter geht. Oben finden wir unsere clone URL . Nun fügen wir diese als remote zu unserem repository hinzu via "git remote add origin URL". Damit können wir jetzt immer origin statt der URL schreiben.
Nun müssen wir unseren master branch nur noch auf den server hochladen. Um das Lokale repository auf den server hochzuladen gibt es das Kommando "git push". Bei der ersten benutzung müssen wir git aber noch sagen welcher remote branch dem aktuellen branch entsprechen soll, wir müssen also in git sprech den lokalen branch einen remote branch tracken lassen.

Der push befehl gibt uns dann ein bisschen was an Text zurück, über den Status des Hochladens. Da wir HTTPS benutzen werden wir bei jedem Push nach einem Passwort gefragt, das müssen wir dann eingeben.
Die letzte Zeile in der push ausgabe sagt uns dann das der branch master nun origin master folgt (trackt) und damit benötigen wir für folgende pushs jetzt nicht mehr das "--set-upstream ..." Wenn wir jetzt lokal weiter gearbeitet haben, ein paar commits gemacht haben, und die am ende des Tages zum Backup hochladen wollen, machen wir nur noch ein "git push" und alles ist synchronisiert


Wenn man GitLab benutzt muss man nicht vorher ein Repo erstellen, "git push --set-upstream URL master" erzeugt automatisch ein repository mit dem Namen der in der URL angegeben wird, solang die URL die typische GitLab URL form hat.

Wenn wir nun auf einem Zweiten rechner das git Repository runterladen wollen, können wir das über "git clone URL [ordner]" machen. Wenn ein (Ziel-)Ordner angegeben wird, dann wird der Ordner mit diesem Namen erstellt und da rein geklont, ansonsten wird ein neuer Ordner mit dem Namen des Repositories erstellt. Das git clone erzeugt direkt den lokalen master branch und trackt den gegen origin/master.
Die serverseitigen sachen werden praktisch als eigene Branches von git gehandhabt. Der Branch "master" der im online repo origin liegt, wird mit origin/master addressiert. Wenn du also die Änderungen deines Lokalen branches mit dem Server vergleichen willst kannst du das via "git diff origin/master" machen:

Generell kannst du origin/branch genauso verwenden wie Commit Hashs, nicht wie branches. D.h. wenn du z.b. "git checkout origin/master" machst landest du wieder im detached HEAD mode, und befindest dich praktisch auf keinem branch.

Wenn du jetzt online updates lokal synchronisieren möchtest, müssen zu erst die Updates runtergeladen werden. Das geht mittels "git fetch [remote]". Wenn du keinen remote angibst wird origin geupdated. Die änderungen müssen danach gemerged werden mittels "git merge origin/master" (oder ein anderer Branch Name, wenn du auf einem anderen Branch bist). Allerdings bietet git dafür eine einheitliche funktion die bereits beides macht: "git pull". Das führt zu erst ein fetch aus, und danach ein merge auf den aktuellen Branch. Während pull das ist was man meist machen will, wenn mehrere Leute an einem projekt Arbeiten, und du lokale änderungen machst, willst du vielleicht zu erst schauen ob es konflikte geben kann, bevor der merge ausgeführt wird, da das sonst echt hässlich werden kann. Dann sollte man zunächst ein "git fetch" machen, und dann per hand mergen:

Hier kann ich am git fetch sehen das master geupdated wurde. Da ich aktuell auf master ein paar Änderungen mache will ich nicht direkt mergen, sondern mache zu erst ein stash, um meine Arbeitskopie zu sichern. Dann mach ich den merge gegen origin, um dann mit dem git stash pop meine neuen Änderungen reinzubringen. Git stash hat den Vorteil, das wenn es Konflikte gab die Änderungen immernoch im Stash bleiben, es geht also nix verloren. Ich kann dann einfach einen neuen Branch erzeugen, und dort den stash popen um dann auf dem neuen Branch weiter zu machen.
Um meine Lokalen änderungen zu verwerfen könnte ich jetzt einfach "git reset --hard origin/master" statt git merge machen, wenn ich mir sicher bin das ich die lokalen Änderungen nicht mehr brauche.


So... Das waren die absoluten Grundlagen von Git. Ursprünglich wollte ich ein vollständiges Tutorial machen, also mit so sachen wie Rebase, Konfliktresolution, History rewrite, LFS, Pull Requests, etc., aber wenn ich mir die bisherige Länge ansehe, soll das vorerst reichen. Fall interresse besteht, fragt einfach, ich würde auch einen Zweiten Teil schreiben. Zu guter letzt kommen jetzt noch ein paar tipps zu git.

Git ist für Source versionierung gemacht. Git mag binäre dateien überhaupt nicht und vor allem große Binäre datien können Git komplett lahmlegen. Der Grund dafür ist das git statt diff's (wie SVN) die unterschiedlichen Dateien einfach in ihrer gesamtheit, dafür Komprimiert speichert. Die Komprimierung ist beschissen für Binäre Dateien, was das clonen von Repositories mit Binären dateien extrem langsam werden lässt. Dafür gibt es aber , was sich darum kümmert.
Damit zusammen hängt auch, man möchte einige sachen einfach nicht in sein git Repositroy commiten. Dazu gehören executeables, DLL's, etc.. Damit man nicht ausversehen bei einem "git add -A" die dateien trozdem reinkommen, gibt es dafür die .gitignore. Das ist einfach eine Datei die git sagt, welche Dateien nicht beachtet/ignoriert werden sollen. Es gibt auf GitHub ein Repository von GitHub selbst, was gitignroes für die meißten größeren IDE's und Pragrammiersprachen hat . Einfach im Projektverzeichnis eine neue Textdatei .gitignore anlegen und dort die Dateien reinschreiben die ignoriert werden sollen, bzw. einfach den Inhalt einer der Vorgefertigten gitignores reinkopieren.

Ein weiterer Punkt ist SSH URLS. Git kann sowohl HTTPS als auch SSH als protokolle zum synchronisieren mit dem Server. HTTPS benötigt Passworteingabe bei jedem Fetch/Pull und Push. Außerdem sind Passwörter nicht unbedingt die sicherste Lösung. Daher kann man SSH nehmen, wofür man dann einen Private und Public Key braucht. Mehr dazu gibt es

Wenn man nicht auf online Services wie GitHub oder GitLab zurückgreifen will, aber trozdem ein Backup mit so einem tollen Webinterface haben möchte, kann auf einem eigenen Server (oder Raspberry pi lokal) eine eigene oder, wenn man eher ein Fan vom GitHub layout ist, hosten. Gitlab braucht ne menge Resourcen (Unter 8 GB RAM würd ichs nicht versuchen), aber Gitea läuft super auch auf der schwächsten Hardware, und erlaubt problemlos das Hosten auch auf Hardware wie dem Raspberry pi. Natürlich sollte man sich dann ein etwas sichereres Medium als eine SD Karte besorgen, ist aber ne Kostengünstige Option wenn man seinen Code nicht auf fremden Servern hosten möchte.



warfley is offline  
Thanks
5 Users
Old 11/18/2019, 23:35   #2
Moderator



 
elite*gold: 0
The Black Market: 235/0/0
Join Date: Apr 2011
Posts: 9,658
Received Thanks: 2,232
Ich habe nur ein Teil des Tutorials gelesen, das liegt daran das das Tutorial nicht ordentlich Formatiert wurde.
Es ist extrem anstrengend immer diese kleine Schrift zu lesen ohne Absätze, Überschriften, etc.

Sollte also etwas in deinem Text stehen was ich gleich "kritisiere" bitte bescheid geben !

Quote:
Wer ohne[...]SVN [...] programmiert sollte ganz schnell damit anfangen, undzwar für jedes Projekt
Natürlich ist es besser mit SVN zu arbeiten als ohne VCS, aber ich würde jeden empfehlen nicht SVN zu nutzen.

Quote:
Wenn man alle Dateien hinzufügen möchte die als untracked gekennzeichnet sind (im git status), kann man einfach "git add -A" verwenden
Der Parameter -A (genauso wie git commit - a usw.) ist der Parameter den ich am wenigsten empfehlen würde! Dadurch schleichen sich sehr schnell Fehler ein.
Beim committen sollte man noch einmal drüber schauen was genau man committet, daher empfehle ich jeden den Paramater -p zu nutzen. Dieser Parameter erlaubt dir jede Änderung einzelnt noch einmal anzuschauen, nun hat man die Wahl ob man das comitten will oder nicht!

Quote:
Gitlab braucht ne menge Resourcen (Unter 8 GB RAM würd ichs nicht versuchen),
Da die meisten die es hier lesen es alleine nutzen werden oder evtl. mit ein paar Bekannten teilen sind die empfohlenen 8GB Schwachsinnig.
In der offiziellen Dokumentation steht auch das 4 GB für 100(!) Benutzer ausreicht.
Ich selber benutze auch ein selfhosted Gitlab und das läuft flüssig mit 3GB Ram!


Was ich mir noch gewünscht hätte wären ein paar Tipps und Tricks, wie z.B. Git alias.
Ich persönlich nutze zu 99% nur noch aliase, ein paar Beispiele hier :
Code:
ci = commit -v
co = checkout
br = branch -v
fork-master = !git co master && git pull && git co -b
map = !git graph --all
push-u = "!f() { BRANCH=$(git rev-parse --abbrev-ref HEAD); git push ${1-origin} -u $BRANCH; }; f"
st = status -sb
Git map würde z.B. den von die angesprochenen Graphen anzeigen:


Von dem was ich ansonsten gelesen habe, stimmt soweit alles (wie Git intern funktioniert).


False is online now  
Old 11/28/2019, 00:37   #3
 
elite*gold: 0
Join Date: Feb 2009
Posts: 1,120
Received Thanks: 550
Quote:
Originally Posted by False View Post
Ich habe nur ein Teil des Tutorials gelesen, das liegt daran das das Tutorial nicht ordentlich Formatiert wurde.
Es ist extrem anstrengend immer diese kleine Schrift zu lesen ohne Absätze, Überschriften, etc.
Ja in meinem BB-Code editor sah es besser aus, wenn ich demnächst mal zeit hab verbesser ich es

Quote:
Originally Posted by False View Post
Natürlich ist es besser mit SVN zu arbeiten als ohne VCS, aber ich würde jeden empfehlen nicht SVN zu nutzen.
Ich wollte mich bei dem Tutorial eigentlich auf diese diskussion nicht einlassen. Wenn man ein zentralisiertes VCS verwenden will ist SVN immernoch state of the art. Gibt diverse Projekte die sich bis heute gegen dezentrale VCS wehren, und die haben auch ihre Gründe. Persönlich bin ich da ganz deiner Meinung, aber Grundsätzlich will ich mich aus dieser Debatte raushalten. In diesem Tutorial geht es um die benutzung von Git, ich glaube kaum das jemand dieses Tutorial liest und sich danach denkt: "Boah ich sollte anfangen SVN zu benutzen", und wenn doch, mir egal. Wie du schon festgestellt hast, besser als kein VCS isses alle mal. Außerdem sind wir mal ehrlich, hat man noch groß ne Wahl was anderes außer Git zu benutzen?

Quote:
Originally Posted by False View Post
Der Parameter -A (genauso wie git commit - a usw.) ist der Parameter den ich am wenigsten empfehlen würde! Dadurch schleichen sich sehr schnell Fehler ein.
Beim committen sollte man noch einmal drüber schauen was genau man committet, daher empfehle ich jeden den Paramater -p zu nutzen. Dieser Parameter erlaubt dir jede Änderung einzelnt noch einmal anzuschauen, nun hat man die Wahl ob man das comitten will oder nicht!
Ich stimm dir da eigentlich zu, werde es wenn ich es Formatiere nochmal reinschreiben, aber zumindest commit -a benutze ich gerne, denn bei meinem Workflow passt das soweit ganz gut rein. Nachdem ich was gearbeitet habe mache ich immer erst mal ein git diff. Dabei lese ich alle Änderungen durch und fixe kleinigkeiten (Formatierungen, spaces am zeilenende, etc.). Danach weiß ich eh das ich alles mit -a committen kann. Am ende brauch ich eh ein cleanes directory, d.h. changes die ich nicht committen will müssen eh gestasht sein, da ich nach dem commit, vor dem push auf jeden fall einmal einen Clean Build und die Tests laufen lassen muss, d.h. wenn in meinem Diff änderungen vorkommen die nicht commited werden sollen, muss ich die zu erst stashen damit die die Tests nicht beinflussen können, somit ist garantiert das -a nix unerwünschtes Commited.
Wenn man add -A benutzen will sollte man natürlich doppelt checken ob es keine dateien gibt die man nicht haben will. Manchmal ists aber einfach die angenehmste Art. Und man kann im Commit Message Editor ja eh nochmal nachschauen was commited wird (Schreib ich ja auch das man das auf jeden fall checken sollte vor dem Commit)


Quote:
Originally Posted by False View Post
Da die meisten die es hier lesen es alleine nutzen werden oder evtl. mit ein paar Bekannten teilen sind die empfohlenen 8GB Schwachsinnig.
In der offiziellen Dokumentation steht auch das 4 GB für 100(!) Benutzer ausreicht.
Ich selber benutze auch ein selfhosted Gitlab und das läuft flüssig mit 3GB Ram!
Das ist schön und gut was die in ihrer Dokumentation schreiben, ich hab aber auf meinem Server mit literally 5 Nutzeraccounts nachgeschaut, da nimmt das 6-8 GB in anspruch. Vielleicht läuft es mit 3 GB, aber auf meinem Server nimmt es sich auf jeden Fall 6-8. Ich mein juckt mich nicht, mein Server hat genug Speicher, da das aber meine einzige verifizierbare Erfahrung ist, schreib ich sie hier rein! Nicht das jemand gitlab aufsetzt und sich wundert warum er plötzlich viel mehr RAM verbrauch hat



Quote:
Originally Posted by False View Post
Was ich mir noch gewünscht hätte wären ein paar Tipps und Tricks, wie z.B. Git alias.
Ich persönlich nutze zu 99% nur noch aliase, ein paar Beispiele hier :
Kann ich noch hinzufügen, wollte eigentlich ne ganze reihe an Sachen mehr machen, doch nach 4 stunden oder so schreiben hatte ich dann keine Lust mehr mehr Sachen hinzuzufügen.
Persönlich benutz ich aber keine git aliase, sonder shell aliase, da die mir mehr flexibilität geben, sowie ein Einheitliches interface. Wenn ich dann aliase für andere Programme schreiben will hab ich alles an einem Ort, in meiner shell config, die ich eh synchronisiere

Außerdem, am Rand:
Code:
fork-master = !git co master && git pull && git co -b
wenn du lokale Änderungen auf master hast kann das konflikte geben (z.B. wenn man vorher ausversehen mal was auf master commited hatte), ich würde es so benutzen:
Code:
fork-master = "!f() { git checkout -b $1 && git fetch && git reset --hard origin/master }"
Quote:
Originally Posted by False View Post
Git map würde z.B. den von die angesprochenen Graphen anzeigen:
Stimmt habe ich komplett beim schreiben vergessen. Bietet sich eigentlich an zur visualisierung.

Danke
warfley is offline  
Thanks
1 User
Old 11/28/2019, 09:44   #4
Moderator



 
elite*gold: 0
The Black Market: 235/0/0
Join Date: Apr 2011
Posts: 9,658
Received Thanks: 2,232
Quote:
wenn du lokale Änderungen auf master hast kann das konflikte geben (z.B. wenn man vorher ausversehen mal was auf master commited hatte), ich würde es so benutzen:
Auf den Master sollte nie comited werden, ist bei Gitlab normalerweise auch protected.


False is online now  
Old 11/28/2019, 14:10   #5
 
elite*gold: 0
Join Date: Feb 2009
Posts: 1,120
Received Thanks: 550
Quote:
Originally Posted by False View Post
Auf den Master sollte nie comited werden, ist bei Gitlab normalerweise auch protected.
Ja das schon, das heist aber nicht das man es lokal nicht manchmal trozdem macht. Z.b. Hatte ich demletzt das so gehabt das ich eigentlich Master Forken wollte dann committed, hab’s aber ausversehen in falscher Reihenfolge gemacht, und dann gammelt halt ein commit auf Master Lokal rum. Fixen tu ich das dann immer erst wenn der pull auf Master failed, z.b. Wenn ich mich am nächsten Tag oder so morgens wieder dran setze und erst mal alles pulle


warfley is offline  
Reply



« Selenium in Python nützen ( IDE = PyCharm ) | - »

Similar Threads
SVN & GIT ADRESSEN: Most Wanted
11/06/2015 - WoW Private Server - 20 Replies
Acronyms CTDB: Community Trinity Core Database IFDB: Unknown LHDB: Light Hope Database MMM: Massive Mangos Mall PSMDB: Project Silvermoon Database SADB: Sandshroud Aspire Database TDB: Trinity Database UDB: Unified Database YTDB: Unknown
suche aktuellsten git auf v3.3.5a
07/30/2014 - WoW Private Server - 1 Replies
suche den aktuellsten/teilweise bugfreien Git auf der Version 3.3.5a, Bitte melden!
[B]Hl2Ep2/6 Kohle/50%Valve Gutschein[S]Terraria Git oder 2,50€ PSC
12/28/2011 - Steam Trading - 5 Replies
Titel sagt alles...
Git es hier Angebote für accs?
12/01/2010 - CrossFire - 1 Replies
ich will gerne mein acc tauschen oder einen kaufen aber ichweiß nich ob es so was hier gibt:confused:
im starting to git how do do this
03/22/2006 - GunZ - 0 Replies
any 1 have a bypass for abnormal behavior i finly figured out how to do the xtrap 1 now i jest giting abnormal behavior errors



All times are GMT +1. The time now is 22:42.


Powered by vBulletin®
Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.

BTC: 33E6kMtxYa7dApCFzrS3Jb7U3NrVvo8nsK
ETH: 0xc6ec801B7563A4376751F33b0573308aDa611E05

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2019 elitepvpers All Rights Reserved.