You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1301 lines
59 KiB
1301 lines
59 KiB
\documentclass[german,a4paper]{report}
|
|
|
|
\usepackage[german]{babel}
|
|
\usepackage{graphicx} % Benoetigt, um Grafiken einzubinden
|
|
\usepackage{longtable}
|
|
\usepackage{float}
|
|
\usepackage{german}
|
|
\usepackage{ae}
|
|
\usepackage{alltt}
|
|
\usepackage{amssymb}
|
|
|
|
\usepackage[utf8]{inputenc} % Umlaute und dt. Zeichen Kodieren
|
|
|
|
% ae.sty verwenden!
|
|
\usepackage[T1]{fontenc} % ec* Schriftarten verwenden
|
|
|
|
\usepackage{times} % Times-Schriftart (pdf)
|
|
\usepackage{calc}
|
|
\usepackage{lmodern}
|
|
|
|
\setcounter{secnumdepth}{4}
|
|
\setcounter{tocdepth}{4}
|
|
|
|
\begin{document}
|
|
|
|
\title{GIT - Eine Einf"uhrung}
|
|
\author{Hauke Z"uhl <hzuehl@hauke-zuehl.de>}
|
|
|
|
\maketitle
|
|
|
|
\tableofcontents
|
|
|
|
\chapter{Was ist GIT?}
|
|
GIT ist ein sogenanntes ``Versionskontrollsystem'' von Dateien in Projekten, das heisst,
|
|
man kann die Ver"anderungen, die an Dateien im Laufe der Zeit durchgef"uhrt werden,
|
|
nachvollziehen. Dabei werden nicht nur Zeitstempel gespeichert, sondern auch welcher
|
|
Benutzer die "Anderungen durchgef"uhrt hat. Dies ist dann ein Versionsstand eines
|
|
Projektes.
|
|
|
|
GIT speichert also nur Ver"anderungen. Gut, bei sog. ``Bin"ardateien'', also zum Beispiel
|
|
LibreOffice-Dokumenten, geht das nicht, aber das ist ein anderes Thema. Immerhin kann
|
|
man aber auch LO-Dokumente speichern, wie man an und f"ur sich alles, was eine Datei ist,
|
|
in GIT gespeichert werden kann.
|
|
|
|
Was GIT besonders macht, ist die Tatsache, dass es dezentral ist. Das bedeutet, dass jeder,
|
|
der ein Projekt aus GIT herunterl"adt (man sagt auch ``auschecken'' dazu) den kompletten
|
|
Versionsverlauf auf seinem Rechner als lokale Kopie verliegen hat.
|
|
|
|
Im ersten Moment mag das ein Nachteil sein, denn man will ja nicht die Dateiversionen
|
|
haben, die Max Mustermann vor 10 Jahren in GIT hochgeladen hat, aber keine Sorge, GIT
|
|
arbeitet recht platzsparend.
|
|
|
|
Der Vorteil dieser Methode ist, dass man dadurch mindestens eine Sicherheitskopie auf
|
|
einem Rechner hat.
|
|
Arbeiten mehrere Leute an einem Projekt, kommen so diverse Sicherheitskopien zustande.
|
|
|
|
Diese Einf"uhrung soll mit einfachen Worten und Beispielen an GIT heranf"uhren. Ich
|
|
konzentriere mich dabei auf die Konsole, denn nur auf der Konsole kann man meiner Meinung
|
|
nach die Arbeitsweise von GIT verinnerlichen. Grafische Clients kann man sp"ater immer
|
|
noch einsetzen!
|
|
|
|
\chapter{Fachbegriffe}
|
|
Ohne Fachbegriffe, die "uberwiegend in Englisch sind, kommt man leider bei der Benutzung
|
|
und der Erkl"arung von GIT nicht aus, deshalb hier die grundlegenden Fachbegriffe:
|
|
|
|
``Repository'':
|
|
|
|
Man kann es als ``Projekt'' bezeichnen. Im Repository (verk"urzt auch nur ``Repo'' genannt)
|
|
findet man die Verzeichnnisse und Dateien des Projektes wieder.
|
|
|
|
``Einchecken'':
|
|
|
|
Neue Dateien, die zum Repo hinzugef"ugt werden, werden ``eingecheckt'', aber wenn auch
|
|
"Anderungen an Dateien dem Repo hinzugef"ugt werden, spricht man von ``einchecken''. Auch
|
|
``commit'' genannt.
|
|
|
|
``Auschecken'' / ``Klonen'':
|
|
|
|
Unter ``Auschecken'' versteht man umgangssprachlich(!) das Herunterladen eines GIT-Repositories.
|
|
Korrekterweise bedeutet ``auschecken'', dass sog. ``Zweige'' auscheckt. Der Begriff des Zweiges
|
|
wird sp"ater genauer erl"autert. An dieser Stelle sei nur sovierl dazu gesagt, dass man mit Zweigen
|
|
Projekte weiter unterteilen kann.
|
|
|
|
Wenn man ein Repository klont, dann bezieht sich das auf das GIT-Kommando, um ein Repository
|
|
von einem GIT-Server herunterzuladen.
|
|
|
|
``Branch'':
|
|
|
|
Ein ``Branch'' ist ein Zweig eines Projektes. Dazu sp"ater mehr.
|
|
|
|
``Merge'':
|
|
|
|
Das Zusammenf"uhren zweier Zweige wird als ``merge'' bezeichnet.
|
|
|
|
\chapter{Erste Schritte mit GIT}
|
|
|
|
Um mit GIT zu arbeiten, braucht man erst einmal das Programm.\\
|
|
Unter Linux kann man sich GIT mit Hilfe des distributionseigenen Installationsprogrammes
|
|
installieren. Unter Debian oder Ubuntu zum Beispiel per \textit{aptitude install git}, bzw. per
|
|
\textit{apt-get install git}. RedHat oder CentOS liefert GIT per \textit{yum install git}
|
|
auf die Platte. Und unter MacOS d"urfte \textit{brew install git} zum Erfolg f"uhren. Mangels
|
|
MAC kann ich das nicht pr"ufen.\\
|
|
Ein Tip: Vergiss erst einmal grafische Clients, das ist Bl"odsinn, denn damit lernt man nicht
|
|
mit GIT umzugehen und zu verstehen! Denk auch nicht an irgendwelche Server oder gar an GitHub!
|
|
Wir fangen einfach an und das ist lokal bei dir auf deinem Computer.\\
|
|
\\
|
|
Los geht's!\\
|
|
\\
|
|
"Offne eine Konsole deiner Wahl. Bash, zsh, ksh, egal. Irgendwas, wo du mit Hilfe deiner
|
|
Tastatur deinem Rechner Kommandos senden kannst\footnote{Manche Shells ben"otigen den
|
|
Befehl \textit{rehash}, wenn neue Software hinzugekommen ist}.\\
|
|
Es empfiehlt sich, f"ur Git-Repos ein eigenes Verzeichnis anzulegen. Zum Beispiel \textit{git}
|
|
oder \textit{projekte}, oder, oder, oder.\\
|
|
Ich selbst verwende \textit{git}.\\
|
|
\\
|
|
Also: \textit{mkdir git}, dann \textit{cd git}.\\
|
|
\\
|
|
Jetzt legen wir ein Verzeichnis f"ur unser erstes Projekt an. Lass uns das Projekt ``Welt''
|
|
nennen: \textit{mkdir Welt}. Per \textit{cd Welt} wechseln wir in das neue Verzeichnis.\\
|
|
Jetzt wird es ernst, wir erzeugen unser erstes GIT-Repository: \textit{git init}. Yes!\\
|
|
Wenn man nun per \textit{ls -oha} nachguckt, sollte das Verzeichnis so aussehen:
|
|
\begin{verbatim}
|
|
insgesamt 12K
|
|
drwxrwxr-x 3 hauke 4,0K Mar 22 13:03 .
|
|
drwxrwxr-x 18 hauke 4,0K Mar 22 13:03 ..
|
|
drwxrwxr-x 7 hauke 4,0K Mar 22 13:03 .git
|
|
\end{verbatim}
|
|
Das Verzeichnis .git ist ein verstecktes Verzeichnis, dort stehen Informationen f"ur GIT in
|
|
diversen Dateien.\\
|
|
\\
|
|
Wir k"onnen nun loslegen, Dateien anzulegen. Fangen wir erst einmal einfach an und legen
|
|
eine Datei LIESMICH an. Ich verwende an dieser Stelle den Editor vi, wenn du aber einen
|
|
anderen Editor verwenden magst, nutze diesen; es geht nur darum, Text in eine einfache
|
|
Datei zu schreiben (Officeprogramme scheiden also aus!).\\
|
|
Der Inhalt der Datei soll ganz einfach sein:
|
|
\begin{verbatim}
|
|
Projekt Welt
|
|
\end{verbatim}
|
|
Abspeichern nicht vergessen!\\
|
|
Jetzt sieht unser Verzeichnis (\textit{ls -oha}) so aus:
|
|
\begin{verbatim}
|
|
insgesamt 16K
|
|
drwxrwxr-x 3 hauke 4,0K Mar 22 13:20 .
|
|
drwxrwxr-x 18 hauke 4,0K Mar 22 13:03 ..
|
|
drwxrwxr-x 7 hauke 4,0K Mar 22 13:06 .git
|
|
-rw-rw-r-- 1 hauke 14 Mar 22 13:20 LIESMICH
|
|
\end{verbatim}
|
|
Jetzt fragen wir mal GIT, was es davon h"alt, dass in dem Repository eine Datei neu
|
|
angelegt wurde. Dazu geben wir \textit{git status} ein. Das Ergebnis sollte in etwa so aussehen:
|
|
\begin{verbatim}
|
|
Auf Branch master
|
|
|
|
Initialer Commit
|
|
|
|
Unversionierte Dateien:
|
|
(benutzen Sie "git add <Datei>...", um die Aenderungen
|
|
zum Commit vorzumerken)
|
|
|
|
LIESMICH
|
|
|
|
nichts zum Commit vorgemerkt, aber es gibt unversionierte
|
|
Dateien
|
|
(benutzen Sie "git add" zum Versionieren)
|
|
\end{verbatim}
|
|
GIT gibt uns einige Informationen:\\
|
|
Wir sind auf dem Branch (Zweig) ``master''. Dazu - wie gesagt - sp"ater mehr.\\
|
|
Unser erstes Einchecken (commit) steht bevor; es ist der initiale Commit.\\
|
|
Git hat festgestellt, dass es Dateien gibt, "uber die es nichts weiss. Unversionierte
|
|
Dateien also. Die Datei(en) wird/werden aufgez"ahlt und es gibt - zumindest bei mir -
|
|
einen hilfreichen Tip, was man machen sollte (\textit{git add ...}).\\
|
|
Also, ran an den Speck und die Datei per \textit{git add LIESMICH} zum Einchecken vormerken.
|
|
Ein \textit{git status} sollte nun folgendes ergeben:
|
|
\begin{verbatim}
|
|
Auf Branch master
|
|
|
|
Initialer Commit
|
|
|
|
zum Commit vorgemerkte Aenderungen:
|
|
(benutzen Sie "git rm --cached <Datei>..." zum
|
|
Entfernen aus der Staging-Area)
|
|
|
|
new file: LIESMICH
|
|
\end{verbatim}
|
|
Prima, das sieht schon anders, besser aus!\\
|
|
Jetzt kann ich nat"urlich weitere Dateien anlegen und per \textit{git add ...} vormerken,
|
|
oder ich kann diese eine Datei in das Repository "ubernehmen, den ``commit'' also
|
|
durchf"uhren. \textit{git commit LIESMICH} f"uhrt den Commit auf die Datei LIESMICH aus.
|
|
Es sollte sich ein Editorfenster "offnen, denn GIT bietet dir jetzt an, in einem
|
|
Kommentar kurz zu erl"autern,
|
|
was du gemacht hast. Dieser Text taucht dann in der Historie des Projektes sp"ater auf.
|
|
Beispiel: ``LIESMICH angelegt''. Kurz und knackig sollte der Kommentar sein, aber auch
|
|
so geschrieben, dass du sp"ater noch weisst, was du seinerzeit gemacht hast.\\
|
|
GIT gibt dir auch hier wieder eine R"uckmeldung:
|
|
\begin{verbatim}
|
|
[master (Basis-Commit) 19a30b3] LIESMICH angelegt
|
|
1 file changed, 2 insertions(+)
|
|
create mode 100644 LIESMICH
|
|
\end{verbatim}
|
|
In der ersten Zeile wird der Branch angezigt, der Commit-Hash (ist auch an dieser Stelle
|
|
nicht weiter wichtig, ich erw"ahne es aber dennoch, der "Ubersicht halber) und dein
|
|
Kommentar. In der zweite Zeile wird die Anzahl der ver"anderten Dateien, sowie hinzugekommene
|
|
Zeilen (insertions) und (hier noch nicht sichtbar) die Anzahl der entfernten Zeilen.
|
|
In der dritten Zeile stehen dann noch Information bzgl. des Modus der Datei (create), die
|
|
Dateirechte und der Dateiname.\\
|
|
Super, damit ist die erste Version des Projektes ``Welt'' im GIT-Repository angekommen.
|
|
|
|
Am Beispiel einer weiteren Datei zeige ich dir nun auch erste ``Vereinfachungen'', denn mal
|
|
angenommen, du hast auf einem Satz mehrere Dutzend Dateien neu in deinem Projekt, dann
|
|
wirst du nicht per \textit{git add datei1}, \textit{git add datei2}, usw. jede einzelne
|
|
Datei vormerken. Die Sache ginge ja dann so sp"ater beim commit weiter. Also, eher wird
|
|
der BER fertig, als dass du mit deinem Projekt weiterkommst!\\
|
|
Als Beispiel gibt es jetzt das Shellskript ``welt.sh'':
|
|
\begin{verbatim}
|
|
#!/bin/sh
|
|
|
|
echo "Hallo Welt"
|
|
\end{verbatim}
|
|
Jetzt kommt das ``add'' mal etwas anders: \textit{git add .} Du hast den Punkt hinter ``add''
|
|
bemerkt? Gut! Damit hast du jetzt alle neuen Dateien in diesem Verzeichnis (Unterverzeichnisse,
|
|
sofern vorhanden mit eingeschlossen) zum einchecken vorgemerkt. \textit{git status} wird
|
|
dir das anzeigen.\\
|
|
Jetzt das tats"achliche Einchecken in das Repository und da verrate ich dir den n"achsten
|
|
Trick: Den Kommentar direkt angeben, ohne dass ein Editor erst "offnet: \textit{git commit -a
|
|
-m 'Projekt erweitert, neue Dateien hinzugefuegt'}.\\
|
|
Das erkl"are ich mal genauer:\\
|
|
-a bedeutet, dass alle (-a = all) Dateien, die vorher per \textit{git add .}, bzw. per
|
|
\textit{git add dateiname} vorgemerkt wurden nun in das Repo "ubernommen werden sollen. Du siehst:
|
|
Man kann auch erst einmal ``sammeln''.\\
|
|
-m bedeutet, dass nun ein Kommentar kommt (-m = message). Der Text sollte in Anf"uhrungszeichen
|
|
stehen, sonst macht die Shell "Arger.\\
|
|
Und damit hast du bereits die ersten Schritte gemacht.\\
|
|
Hier noch mal zusammengefasst die Schritte, die im Wesentlichen immer wieder wiederholt
|
|
werden, nachdem man das Projektverzeichnis angelegt und GIT initialisiert hat:
|
|
\begin{itemize}
|
|
\item Datei anlegen
|
|
\item git add
|
|
\item git commit
|
|
\item Datei anlegen
|
|
\item git add
|
|
\item git commit
|
|
\item ...
|
|
\end{itemize}
|
|
Oder aber man macht:
|
|
\begin{itemize}
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item git add .
|
|
\item git commit -a
|
|
\item Datei anlegen
|
|
\item ...
|
|
\end{itemize}
|
|
|
|
\chapter{GIT konfigurieren}
|
|
Oftmals sehen die Logs von GIT ziemlich d"amllich aus, was meistens daran liegt, dass
|
|
die Benutzer ihr GIT nicht ordentlich konfiguriert haben. F"ur eine vern"unftige
|
|
Konfiguration bedarf es des korrekten Namens und der Mailadresse.\\
|
|
Dies geschieht per \textit{git config ...}. Beispiel:
|
|
\textit{git config user.name 'Max Mustermann'}, um den Namen festzulegen und
|
|
\textit{git config user.email 'mmuster@exampel.kom} f"ur die Mailadresse.\\
|
|
Damit sind Name und Mailadresse f"ur dieses eine Projekt festgelegt. Damit das
|
|
f"ur alle GIT-Repositories gilt, f"ugt man die Option \textit{--global} hinzu, also
|
|
\textit{git config --global user.name 'Max Mustermann'} und
|
|
\textit{git config --global user.email 'mmuster@exampel.kom}.\\
|
|
Man kann nat"urlich noch eine Menge mehr konfigurieren, aber hier geht es um die Grundlagen.
|
|
|
|
\chapter{Zweige}
|
|
Bisher haben wir uns geradlinig auf dem Zeitstrahl bewegt, aber wenn man im Team an
|
|
einem gro"sen Projekt arbeitet, dann erledigt jeder, bzw. jede entsprechende Unteraufgaben.
|
|
Um solche Unteraufgaben zu organisieren, nutzt man in Versionskontrollsystemen sog.
|
|
``Zweige''. Leider kann man das nicht direkt mit einem Baum vergleichen, denn zwar
|
|
gibt es sowohl beim Baum als auch in GIT einen Hauptzweig/Stamm und (mehr oder weniger)
|
|
viele Zweige, bei einem Baum werden die Zweige aber nicht wieder zum Stamm zur"uckgef"uhrt.
|
|
Bei Versionskontrollsystemen jedoch werden Zweige fr"uher oder sp"ater wieder in den Hauptzweig
|
|
"uberf"uhrt.\\
|
|
\\
|
|
Am Anfang befindet man sich immer auf dem Hauptzweig, dem sog. ``Masterbranch''. Du hast das
|
|
bereits in diversen Meldungen von GIT gesehen.\\
|
|
Das sieht dann so aus:
|
|
\begin{verbatim}
|
|
master A--B--C--D--E--F
|
|
\end{verbatim}
|
|
Um nun einen neuen Zweig zu erzeugen, gibt man
|
|
\textit{git checkout -b <Zweigname>}\footnote{-b bedeutet, dass der Zweig erzeugt und sofort
|
|
ausgecheckt wird, d.h. man befindet sich sofort auf diesem Zweig} ein.
|
|
Angenommen, ich will als Unteraufgabe zum Projekt ``Welt'' ein ``Hallo'' programmieren,
|
|
dann erzeuge ich den Zweig ``Hallo'' per \textit{git checkout -b hallo}. Wir sind nun im Zweig
|
|
``hallo''. Um das zu "uberpr"ufen gibt es \textit{git branch}:
|
|
\begin{verbatim}
|
|
* hallo
|
|
master
|
|
\end{verbatim}
|
|
Der kleine Stern in der ersten Spalte zeigt den Zweig an, in dem wir uns aktuell befinden.\\
|
|
Will ich auf den Zwei ``master'' zur"uckwechslen, gebe ich \textit{git checkout master} ein.
|
|
Wichtig: Hier wird kein ``-b'' verwendet, da es den Zweig ``master'' bereits gibt!\\
|
|
\\
|
|
Bist du also im Zweig ``hallo'', gehst du wieder wie immer vor: Datei(en) anlegen, vormerken,
|
|
einchecken.\\
|
|
Das sieht dann so aus:
|
|
\begin{verbatim}
|
|
master A--B--C--D--E--F
|
|
\
|
|
hallo G--H--I--J--K
|
|
\end{verbatim}
|
|
Das sollte soweit klar sein, aber irgendwann kommt der Punkt, an dem du den
|
|
Zweig ``hallo'' wieder in den Zweig ``master'' zur"uckf"uhren willst/musst.\\
|
|
Dazu wechselst du erst einmal in den Zweig ``master'' zur"uck. Nun sagst du GIT, dass du den
|
|
Zweig ``hallo'' in den Masterbranch ``mergen'' willst: \textit{git merge hallo}.
|
|
Es "offnet sich wieder ein Editor, indem (meistens) bereits eine Information vorgegeben ist:
|
|
\begin{verbatim}
|
|
Merge branch 'hallo'
|
|
\end{verbatim}
|
|
Hinweis: Es muss(!) ein Kommentar angegeben werden, und sei es nur der vorgegebene
|
|
Standardkommentar!\\
|
|
Wenn alles gutgegangen ist, sind nun alle Dateien des ``hallo''-Zweiges im Masterbranch.\\
|
|
Das sieht dann so aus:
|
|
\begin{verbatim}
|
|
master A--B--C--D--E--F---L
|
|
\ /
|
|
hallo G--H--I--J--K
|
|
\end{verbatim}
|
|
In der Softwareentwicklung wird generell mit mehreren Zweigen gearbeitet, um zu verhindern,
|
|
dass ungetestete und in der Entwicklung befindliche Dateien Einzug in das fertige Projekt
|
|
nehmen. Es gibt daher einmal nat"urlich den Zweig ``master'', in dem das fertige Produkt
|
|
liegt, dann den Zweig ``develop'', in dem entwickelt wird und von dem weitere Zweige mit
|
|
weiteren Unteraufgaben abgeleitet werden. Wenn in ``develop'' alles ordentllich l"auft, dann
|
|
wird dieser in den Masterbranch gemergt und das Produkt wird ver"offentlicht.
|
|
Dadurch ergibt sich mit der Zeit eine durchaus recht breite Struktur, die aber dem Team
|
|
hilft, dass man sich nicht in die Quere kommt und letztendlich auch den "Uberblick
|
|
beh"alt.
|
|
|
|
\chapter{Ein erstes Fazit}
|
|
Du solltest nun in der Lage sein, lokal auf deinem Rechner GIT-Repositories anzulegen,
|
|
Dateien hinzuzuf"ugen und diese auch in das Repo zu laden. Ausserdem solltest du dir
|
|
auch "uber Zweige klar sein und diese verwenden k"onnen, denn mit Hilfe von Zweigen wird
|
|
eine koordinierte Teamarbeit in einem Projekt erst m"oglich, aber auch wenn du alleine
|
|
an einem Projekt arbeitest, solltest du dir angew"ohnen, f"ur jede Teilaufgabe einen eigenen
|
|
Zweig anzulegen.
|
|
|
|
\chapter{Dateien l"oschen und umbenennen}
|
|
Dateien anlegen kannst du jetzt schon fl"ussig, was aber ist, wenn du eine versionierte Datei
|
|
nicht mehr brauchst, oder wenn du dich beim Namen vertippt hast?\\
|
|
Keine Panik, auch das geht mit GIT.\\
|
|
Um eine Datei zu l"oschen, die im GIT-Repository ist, verwendest du den Removebefehl:
|
|
\textit{git rm <dateiname>}. Danach f"uhrst du ein \textit{git commit -m 'Kommentar'} aus und die
|
|
Datei ist von jetzt an nicht mehr vorhanden.\\
|
|
Umbenennen geht ebenfalls sehr einfach: \textit{git mv <alter name> <neuer name>}. Auch danach
|
|
wieder ein \textit{git commit -m 'Kommentar'} und die Datei hat von nun an einen neuen
|
|
Namen.\\
|
|
Moment mal, was soll das heissen ``von nun an''?\\
|
|
Ganz einfach: Da man mit GIT auch "altere Versionen des Repositories auschecken kann, hat in
|
|
fr"uheren Versionen die Datei nat"urlich noch ihren alten Namen, bzw. ist im Repo noch
|
|
vorhanden! Wie man fr"uhere Versionen auscheckt, erkl"are ich aber sehr viel sp"ater.
|
|
|
|
\chapter{GIT-Server}
|
|
|
|
\section{Einstieg}
|
|
So, jetzt kommt der sog. ``heisse Scheiss''! GIT in Verwendung mit einem GIT-Server!\\
|
|
Bisher hast du deine Repositories lokal auf deinem Rechner gehabt und das ist am Anfang
|
|
auch gut so, aber stelle dir vor, deine Festplatte zerlegt sich und dein echt tolles
|
|
Projekt wird damit geschreddert. Dann n"utzt dir auch GIT nichts mehr. Gut, du h"attest
|
|
regelm"a"sig eine Sicherung deines Repos auf DVD, CD, USB-Stick oder wo auch immer anlegen
|
|
k"onnenen, aber mal ehrlich, das ist nicht Sinn und Zweck von GIT. Ausserdem funktioniert
|
|
so die Teamarbeit an einem Projekt nicht.
|
|
Also ben"otigt man externen Speicherplatz. Auf einem GIT-Server.\\
|
|
Als Plattform kannst du "offentliche Server nehmen. GitHub sei hier erw"ahnt.\\
|
|
Du kannst dir einen GIT-Server auch auf einem kleinen Raspberry Pi in deinem Heimnetzwerk
|
|
einrichten. Oder du mietest dir einen eigenen Rootserver und packst dort deinen GIT-Server
|
|
drauf. Alles kein Problem!
|
|
|
|
\section{GitHub}
|
|
GitHub ist eine - f"ur nichtkommerzielle Projekte - kostenlose Plattform, die GIT anbietet.
|
|
Man kann nat"urlich Geld zahlen, dann bekommt man etwas mehr an ``Features'' auf der Plattform,
|
|
aber f"ur den Hausgebrauch reicht die kostenlose Variante.\\
|
|
Du meldest dich bei GitHub an und hinterlegst dort deinen "offentlichen
|
|
SSH-Schl"ussel\footnote{Wie man SSH-Schl"ussel erstellt, m"ogest du bitte im WWW selbst"andig
|
|
suchen}.\\
|
|
Du kannst dort deine Projekte komplett verwalten, die Seite ist sehr "ubersichtlich
|
|
aufgebaut und es gibt auch eine Hilfefunktion.
|
|
|
|
\section{GIT-Server im Heimnetzwerk}
|
|
F"ur einen GIT-Server im eigenen Heimnetzwerk eignet sich ein Raspberry Pi wunderbar. Der
|
|
sollte nat"urlich "uber LAN (und nicht via WLAN) mit dem Netz verbunden sein, damit die
|
|
Daten"ubertragung m"oglichst hastig erfolgen kann. Eine FritzBox zum Beispiel hat
|
|
Gigabitinterfaces, da kann man schon mal gut was "uber die Leitung jagen (wobei des Raspberries
|
|
Interface langsamer ist).\\
|
|
Als GIT-Serversoftware empfehle ich an dieser Stelle gitea\footnote{https://gitea.io/}.\\
|
|
Wenn du dich damit besch"aftigen willst, solltest du aber "uber gute Linuxkenntnisse
|
|
verf"ugen.\\
|
|
Mit gitea hast du eine Weboberfl"ache, "ahnlich wie bei GitHub, unter der du deine Projekte
|
|
recht einfach verwalten kannst. Du hast auch die M"oglichkeit, private Projekte dort anzulegen
|
|
und mit Hilfe der Benutzerverwaltung kannst du auch Einfluss darauf nehmen, was deine Teammitgleider
|
|
alles so d"urfen.
|
|
|
|
\subsection{gitea}
|
|
Gitea ist ein kleines, aber feines Projekt, das ein Webfrontend f"ur einen git-Server bereitstellt.
|
|
Es ist in der Programmiersprache go geschrieben und ben"otigt nur minimale Resourcen.
|
|
|
|
\subsubsection{Vorbereiten der Datenbank}
|
|
Bevor du dir gitea herunterl"adst und installierst, solltest du das Datenbanksystem
|
|
ausw"ahlen, das gitea sp"ater benutzen soll. Du kannst zwischen MariaDB/MySQL und PostgreSQL
|
|
w"ahlen. Gut, es gibt noch SQLite, MSSQL oder TiDB nutzen, aber die ersten beiden will man
|
|
nicht wirklich und TiDB ist wohl noch zu speziell. Achte darauf, dass MySQL/MariaDB auch
|
|
tats"achlich auf dem Netzwerkinterface horcht, das du bei der Installation angibst!\\
|
|
|
|
\paragraph{PostgreSQL}
|
|
|
|
Am einfachsten loggst du dich per ``sudo su - postgres'' als Benutzer postgres in deiner
|
|
Shell auf deinem GIT-Server ein, dann erzeugst du per ``createuser -P -d gitea'' einen Benutzer
|
|
f"ur die Datenbank ``gitea''.\\
|
|
Im n"achsten Schritt loggst du dich auf der Shell per ``psql -h localhost template1 gitea''
|
|
in das Datenbanksystem ein. Hier reicht nun ein ``CREATE DATABASE gitea;'', um die Datenbank
|
|
f"ur gitea anzulegen.
|
|
|
|
\paragraph{MariaDB/MySQL}
|
|
|
|
Du loggst dich mit dem administrativen Benutzer in MariaDB/MySQL, den du bei der Installation
|
|
eingerichtet hast, in das Datenbanksystem ein. Das ist oft der Datenbankbenutzer ``root''
|
|
(nicht zu verwechseln mit dem Systembenutzer ``root''). Also ``mysql -p -u root''. Nun
|
|
erfolgt ein ``GRANT ALL PRIVILEGES ON gitea.* to 'gitea'@'localhost' IDENTIFIED BY
|
|
'geheimes passwort';''. Dann loggst du dich aus, loggst dich per ``mysql -p -u gitea''
|
|
wieder ein und f"uhrst ein ``CREATE DATABASE gitea CHARACTER SET utf8mb4;'' aus,
|
|
um die Datenbank f"ur gitea anzulegen.
|
|
\\
|
|
\textbf{Hinweis:} Sollte bei Benutzung von MariaDB w"ahrend der Installation im
|
|
Webbrowser die Fehlermeldung ``Datenbankeinstellungen sind nicht korrekt: Error 1071: Specified key was too long; max key length is 767 bytes'', dann folgende Befehle in der
|
|
MariaDB-Kommandozeile ausf"uhren:
|
|
\begin{verbatim}
|
|
set global innodb_large_prefix=on;
|
|
set global innodb_file_format=Barracuda;
|
|
\end{verbatim}
|
|
|
|
\subsubsection{Installation}
|
|
Bevor du dir gleich die Software runterl"adst, lege bitte einen Benutzer ``git'' auf deinem
|
|
Server an, sofern der Benutzer noch nicht existiert.\\
|
|
Von https://gitea.io/ l"adt man sich die passende Version
|
|
f"ur seinen Server runter und entpackt diese. Das entstandene Verzeichnis wird dann in das
|
|
Benutzerverzeichnis des Benutzers ``git'' verschoben und diesem zu eigen gemacht (chown).\\
|
|
Um gitea beim Systemstart zu starten, benötigst du die passenden Skripte.\\
|
|
Nat"urlich solltest du die Dateien entsprechend f"ur dein System anpassen, sonst stimmen
|
|
die Pfade unter Umst"anden nicht.
|
|
|
|
\paragraph{systemd}
|
|
In ``/etc/systemd/system/'' legst du (z.B. mit vim) die Datei ``gitea.service'' mit
|
|
folgendem Inhalt an:
|
|
|
|
\begin{verbatim}
|
|
[Unit]
|
|
Description=Gitea
|
|
After=syslog.target
|
|
After=network.target
|
|
After=mariadb.service mysqld.service postgresql.service
|
|
After=memcached.service redis.service
|
|
|
|
[Service]
|
|
# Modify these two values and uncomment them if you have
|
|
# repos with lots of files and get an HTTP error 500 because
|
|
# of that
|
|
###
|
|
#LimitMEMLOCK=infinity
|
|
#LimitNOFILE=65535
|
|
Type=simple
|
|
User=git
|
|
Group=git
|
|
WorkingDirectory=/home/git/gitea
|
|
ExecStart=/home/git/gitea/gitea web
|
|
Restart=always
|
|
Environment=USER=git HOME=/home/git
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
\end{verbatim}
|
|
|
|
Dann folgen ein ``systemctl enable gitea'', danach ein ``systemctl start gitea''.
|
|
|
|
\paragraph{SystemV init}
|
|
|
|
Es gibt ja immer noch Puristen, die das alte init-System
|
|
von SystemV verwenden. Dafür benötigt man die Datei
|
|
``/etc/init.d/gitea'', die Executrechte benötigt.
|
|
|
|
\begin{verbatim}
|
|
#! /bin/sh
|
|
### BEGIN INIT INFO
|
|
# Provides: gitea
|
|
# Required-Start: $syslog $network
|
|
# Required-Stop: $syslog
|
|
# Should-Start: mysql postgresql
|
|
# Should-Stop: mysql postgresql
|
|
# Default-Start: 2 3 4 5
|
|
# Default-Stop: 0 1 6
|
|
# Short-Description: A self-hosted Git service written in Go.
|
|
# Description: A self-hosted Git service written in Go.
|
|
### END INIT INFO
|
|
|
|
# Author: Danny Boisvert
|
|
|
|
# Do NOT "set -e"
|
|
|
|
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
|
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
|
DESC="Gitea"
|
|
NAME=gitea
|
|
SERVICEVERBOSE=yes
|
|
PIDFILE=/var/run/$NAME.pid
|
|
SCRIPTNAME=/etc/init.d/$NAME
|
|
WORKINGDIR=/home/git/gitea
|
|
DAEMON=$WORKINGDIR/$NAME
|
|
DAEMON_ARGS="web"
|
|
USER=git
|
|
|
|
# Read configuration variable file if it is present
|
|
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
|
|
|
|
# Exit if the package is not installed
|
|
[ -x "$DAEMON" ] || exit 0
|
|
|
|
# Load the VERBOSE setting and other rcS variables
|
|
. /lib/init/vars.sh
|
|
|
|
# Define LSB log_* functions.
|
|
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
|
# and status_of_proc is working.
|
|
. /lib/lsb/init-functions
|
|
|
|
#
|
|
# Function that starts the daemon/service
|
|
#
|
|
do_start()
|
|
{
|
|
# Return
|
|
# 0 if daemon has been started
|
|
# 1 if daemon was already running
|
|
# 2 if daemon could not be started
|
|
sh -c "USER=$USER start-stop-daemon --start --quiet \\
|
|
--pidfile $PIDFILE --make-pidfile \\
|
|
--test --chdir $WORKINGDIR --chuid $USER \\
|
|
--exec $DAEMON -- $DAEMON_ARGS > /dev/null \\
|
|
|| return 1"
|
|
sh -c "USER=$USER start-stop-daemon --start --quiet \\
|
|
--pidfile $PIDFILE --make-pidfile \\
|
|
--background --chdir $WORKINGDIR --chuid $USER \\
|
|
--exec $DAEMON -- $DAEMON_ARGS \\
|
|
|| return 2"
|
|
}
|
|
|
|
#
|
|
# Function that stops the daemon/service
|
|
#
|
|
do_stop()
|
|
{
|
|
# Return
|
|
# 0 if daemon has been stopped
|
|
# 1 if daemon was already stopped
|
|
# 2 if daemon could not be stopped
|
|
# other if a failure occurred
|
|
start-stop-daemon --stop --quiet --retry=TERM/1/KILL/5 \\
|
|
--pidfile $PIDFILE --name $NAME
|
|
RETVAL="$?"
|
|
[ "$RETVAL" = 2 ] && return 2
|
|
start-stop-daemon --stop --quiet --oknodo \\
|
|
--retry=0/1/KILL/5 --exec $DAEMON
|
|
[ "$?" = 2 ] && return 2
|
|
# Many daemons don't delete their pidfiles when they exit.
|
|
rm -f $PIDFILE
|
|
return "$RETVAL"
|
|
}
|
|
|
|
case "$1" in
|
|
start)
|
|
[ "$SERVICEVERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
|
|
do_start
|
|
case "$?" in
|
|
0|1) [ "$SERVICEVERBOSE" != no ] && log_end_msg 0 ;;
|
|
2) [ "$SERVICEVERBOSE" != no ] && log_end_msg 1 ;;
|
|
esac
|
|
;;
|
|
stop)
|
|
[ "$SERVICEVERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
|
|
do_stop
|
|
case "$?" in
|
|
0|1) [ "$SERVICEVERBOSE" != no ] && log_end_msg 0 ;;
|
|
2) [ "$SERVICEVERBOSE" != no ] && log_end_msg 1 ;;
|
|
esac
|
|
;;
|
|
status)
|
|
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
|
|
;;
|
|
restart|force-reload)
|
|
log_daemon_msg "Restarting $DESC" "$NAME"
|
|
do_stop
|
|
case "$?" in
|
|
0|1)
|
|
do_start
|
|
case "$?" in
|
|
0) log_end_msg 0 ;;
|
|
1) log_end_msg 1 ;; # Old process is still running
|
|
*) log_end_msg 1 ;; # Failed to start
|
|
esac
|
|
;;
|
|
*)
|
|
# Failed to stop
|
|
log_end_msg 1
|
|
;;
|
|
esac
|
|
;;
|
|
*)
|
|
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
|
exit 3
|
|
;;
|
|
esac
|
|
|
|
\end{verbatim}
|
|
|
|
Um das Skript zu aktivieren, führt man ``update-rc.d gitea defaults'' aus und
|
|
startet gitea per ``/etc/init.d/gitea start''.
|
|
|
|
\subsubsection{Konfigurationsdatei}
|
|
Um sp"ater noch ein wenig Feintuning vorzunehmen, kann man im Verzeichnis ``custom/conf''
|
|
die Datei ``app.ini'' "andern, die bei der Installation automatisch angelegt wird.\\
|
|
Ein Beispiel f"ur eine app.ini:
|
|
|
|
\begin{verbatim}
|
|
APP_NAME = Gitea
|
|
RUN_USER = git
|
|
RUN_MODE = prod
|
|
|
|
[repository]
|
|
ROOT = /home/git/repositories
|
|
|
|
[database]
|
|
DB_TYPE = postgres
|
|
HOST = 127.0.0.1:5432
|
|
NAME = gitea
|
|
USER = gitea
|
|
PASSWD = GEHEIM
|
|
SSL_MODE = disable
|
|
PATH = data/gitea.db
|
|
|
|
[server]
|
|
DOMAIN = git.hauke-zuehl.de
|
|
HTTP_PORT = 3000
|
|
ROOT_URL = https://git.hauke-zuehl.de/
|
|
DISABLE_SSH = false
|
|
SSH_PORT = 22
|
|
START_SSH_SERVER = false
|
|
OFFLINE_MODE = false
|
|
|
|
[mailer]
|
|
ENABLED = false
|
|
|
|
[service]
|
|
REGISTER_EMAIL_CONFIRM = true
|
|
ENABLE_NOTIFY_MAIL = true
|
|
DISABLE_REGISTRATION = true
|
|
ENABLE_CAPTCHA = true
|
|
REQUIRE_SIGNIN_VIEW = true
|
|
|
|
[picture]
|
|
DISABLE_GRAVATAR = false
|
|
ENABLE_FEDERATED_AVATAR = true
|
|
|
|
[session]
|
|
PROVIDER = file
|
|
|
|
[log]
|
|
MODE = file
|
|
LEVEL = Info
|
|
ROOT_PATH = /home/git/gitea/log
|
|
|
|
[security]
|
|
INSTALL_LOCK = true
|
|
\end{verbatim}
|
|
Bitte daran denken, dass diese Datei als Eigent"umer den Benutzer ``git'' haben muss!
|
|
Wenn du aber bei der Installation oben alles korrekt eingetragen hast, sollte
|
|
es keine Probleme geben.\\
|
|
In diesem Beispiel habe ich "ubrigens PostgreSQL als Datenbanksystem verwendet, du
|
|
kannst aber gerne MariaDB oder MySQL verwenden.
|
|
|
|
\subsubsection{Der erste Start}
|
|
|
|
Du startest gitea zun"achst "uber die Kommandozeil per ``./gitea web'' und gibst dann in
|
|
deinem Webbrowser die URL ``http://localhost:3000'' ein.\\
|
|
Du wirst nun durch die Konfiguration der Datenbank und von gitea gef"uhrt. Bei der Domain
|
|
solltest du den Server- oder einen ordentlichen Domainnamen eingeben. Hast du also zum
|
|
Beispiel einen kleinen RaspberryPi zu Hause, auf dem gitea laufen soll, und dieser heisst
|
|
``pi.deinzuhause.net'' dann gibst du eben diesen Namen bei der Domain und der Application
|
|
URL ein.\\
|
|
Den Datenbankbenutzer f"ur gitea und die entsprechende Datenbank solltest du nun auch
|
|
anlegen, sonst kracht es bei der Einrichtung der Tabellen.\\
|
|
Hast du soweit alles eingetragen, kannst du dich anmelden und deine Projekte mit gitea
|
|
verwalten.\\
|
|
Der erste Benutzer, der sich registriert bei gitea, wird "ubrigens als Administrator
|
|
angelegt, also Obacht! Von nun kannst du gitea in aller Ruhe erforschen und
|
|
eigene Repositores anlegen, Organisationen und Teams erzeugen, usw.!
|
|
|
|
\subsection{Gogs}
|
|
|
|
Gitea ist ein sog. ``fork'' von gogs, d.h, jemand fand die Entwicklung von gogs nicht so
|
|
toll, hat das Projekt geklont und fortgeführt.\\
|
|
\\
|
|
Gogs dagegen ist zur Zeit ein wenig eingeschlafen, sodass hier nicht weiter darauf eingegangen wird.
|
|
Wer aber gogs verwenden möge, kann dies nach der Installationsanleitung von
|
|
gitea durchführen.
|
|
|
|
\section{GIT from scratch}
|
|
Ich habe keine bessere "Uberschrift gefunden, aber wenn du keine Lust auf GitHub oder gogs oder
|
|
wie auch immer das coole (Web-)Frontend heisst, dann reicht auch...git.\\
|
|
Dann legst du als Benutzer ``root'' einen Benutzer ``git'' an. Hast du das erledigt, wirst
|
|
du zum Benutzer ``git'' und legst ein Verzeichnis ``.ssh'' im Benutzerverzeichnis von ``git''
|
|
an. In das Verzeichnis ``.ssh'' kommen in die Datei ``authorized\_keys'' die "offentlichen
|
|
SSH-Schl"ussel der Benutzer, die git benutzen d"urfen.\\
|
|
Warum wird das mit den Schl"usseln gemacht?\\
|
|
Ganz einfach: Ansonsten m"usstest du jedem Teammitglied das Passwort des Benutzers ``git''
|
|
verraten und das willst du wirklich nicht!\\
|
|
Also:
|
|
\begin{verbatim}
|
|
sudo adduser git
|
|
su git
|
|
mkdir .ssh
|
|
chmod 700 .ssh
|
|
\end{verbatim}
|
|
Jetzt kannst du - als Benutzer ``git'' anfangen, Repositories anzulegen:
|
|
\begin{verbatim}
|
|
mkdir Welt.git
|
|
cd Welt.git
|
|
git --bare init
|
|
\end{verbatim}
|
|
Du siehst hier wieder den ``init''-Befehl, diesmal jedoch mit der Option ``--bare''. Diese
|
|
Option sorgt daf"ur, dass kein sog. ``Arbeitsverzeichnis'' angelegt wird, d.h. es fehlt das
|
|
.git-Verzeichnis, daf"ur sind dort andere Dateien und Verzeichnisse erzeugt werden, die
|
|
zur Verwaltung eines GIT-Repositories n"otig sind (guck einfach mal per \textit{ls -oha} nach).
|
|
Okay, du hast keine Lust? So sieht das Verzeichnis dann aus:
|
|
\begin{verbatim}
|
|
drwxrwxr-x 7 git 4,0K Mar 22 18:11 .
|
|
drwxrwxr-x 19 git 4,0K Mar 22 18:11 ..
|
|
drwxrwxr-x 2 git 4,0K Mar 22 18:11 branches
|
|
-rw-rw-r-- 1 git 66 Mar 22 18:11 config
|
|
-rw-rw-r-- 1 git 73 Mar 22 18:11 description
|
|
-rw-rw-r-- 1 git 23 Mar 22 18:11 HEAD
|
|
drwxrwxr-x 2 git 4,0K Mar 22 18:11 hooks
|
|
drwxrwxr-x 2 git 4,0K Mar 22 18:11 info
|
|
drwxrwxr-x 4 git 4,0K Mar 22 18:11 objects
|
|
drwxrwxr-x 4 git 4,0K Mar 22 18:11 refs
|
|
\end{verbatim}
|
|
Falls du es dir noch nicht gedacht hast: Du kannst das lokal auf deinem Rechner machen! Damit
|
|
wird dein Rechner zum GIT-Server! Und was auf deinem Rechner funktioniert, klappt auch auf
|
|
einem Raspberry Pi, der in deinem Keller oder auf dem Dachboden rumliegt oder auf dem
|
|
dicken Server, der irgendwo in einem Rechenzentrum in Deutschland steht.
|
|
|
|
\chapter{Projekt ``Welt'' auf den Server bringen}
|
|
Nachdem du also einen GIT-Server irgendwie ans Laufen gebracht hast, oder du dich bei GitHub
|
|
angemeldet hast, deinen "offentlichen SSH-Schl"ussel auf den Server geladen hast, soll das
|
|
``Welt''-Projekt nun auf den entfernten Server gebracht werden.
|
|
|
|
Ob dein GIT-Server nun auf deinem Raspberry oder auf deinem lokalen Server l"auft, der Unterschied
|
|
liegt in der Benennung des Rechners. Ich erkl"are dir die folgenden Schritte unter der Annahme,
|
|
dass du den GIT-Server auf deinem Rechner installiert hast. Die Transferleistung hin zum
|
|
Raspberry Pi oder einem Rootserver "uberlasse ich dir.\\
|
|
Um dein Projekt auf den Server hochzuladen, musst du dich im Repoverzeichnis befinden, wo wir uns am
|
|
Anfang dieses Papiers aufgehalten haben. Also \textit{cd ~/git/Welt}. Zu Beginn wollen wir
|
|
den Masterbranch hochladen, also zur Sicherheit ein \textit{git checkout master} machen.\\
|
|
Achtung, jetzt geht es los:\\
|
|
\begin{verbatim}
|
|
git remote add origin git@localhost:Welt.git
|
|
git push origin master
|
|
\end{verbatim}
|
|
Damit hast du deinen Masterbranch auf den Masterbranch des GIT-Servers geladen, wobei der Server
|
|
daf"ur sorgt, dass deine "Anderungen mit dem bereits bestehenden Branch ``gemergt'' werden.
|
|
Bei einem krachneuen Branch ist das nat"urlich nicht n"otig, aber sp"ater einmal, wenn du
|
|
ein ganzes Team an deinem Projekt mitwerkeln l"asst, dann ist das wichtig.\\
|
|
\\
|
|
Also, mal die Erkl"arung:\\
|
|
Mit der ersten Zeile hast du deinem Repository gesagt, dass unter dem Namen ``origin'' ein
|
|
entferntes (remote) Repo existiert. Und zwar beim Benutzer ``git'' auf dem Rechner ``localhost''
|
|
im Repository ``Welt.git''.\\
|
|
Mit der zweite Zeile hast du dann den aktuellen Branch hochgeladen (push) und zwar zu dem
|
|
entfernten Repository ``origin'' in dessen Branch ``master''.\\
|
|
Die Bezeichnung ``origin'' f"ur ein entferntes Repository ist Standard. Du h"attest es auch
|
|
``Pizza'' oder ``Koeln'' nennen k"onnen, Namen sind Schall und Rauch. Dein ``push'' w"are dann
|
|
\textit{git push Pizza master}, bzw. \textit{git push Koeln master}. Es ist nur ein Name f"ur die
|
|
Verbindungsdaten zum Server (git@localhost:Welt.git).\\
|
|
\\
|
|
Jetzt hat sich deine Arbeitsweise etwas erweitert:
|
|
\begin{itemize}
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item git add .
|
|
\item git commit -a
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item Datei anlegen
|
|
\item git add .
|
|
\item git commit -a
|
|
\item git push origin master
|
|
\item ...
|
|
\end{itemize}
|
|
(Gesetzt den Fall, du bist im Masterbranch)
|
|
|
|
\chapter{Arbeiten im Team}
|
|
Du hast bisher alleine mit GIT gearbeitet, hast aber das Projekt, bzw.
|
|
die Projekte mit einem GIT-Server verwaltet.\\
|
|
Dann ist der Schritt hin zur Teamarbeit f"ur dich recht leicht, denn
|
|
du weisst ja, dass du mit \textit{git push ...} Ver"anderungen
|
|
hochl"adst.\\
|
|
Da aber deine Kolleginnen und Kollegen auch fleissig waren, solltest
|
|
du deren "Anderungen mindestestens einmal am Tag herunterladen
|
|
und deine Arbeitskopie damit aktuell halten.\\
|
|
Das gilt besonders f"ur die Zweige, die regelm"a"sigen "Anderungen
|
|
unterworfen sind. Dies sind meistens
|
|
\begin{itemize}
|
|
\item master
|
|
\item develop
|
|
\item testing
|
|
\end{itemize}
|
|
Um deine Arbeitskopie zu aktualisieren, wechselst du in den entsprechenden
|
|
Zweig (zum Beispiel ``develop'') und f"uhrst dort \textit{git pull} aus.\\
|
|
Damit werden die "Anderungen vom Server heruntergeladen und in deinen Zweig
|
|
eingepflegt.\\
|
|
\\
|
|
Ein Beispiel aus dem realen Leben:\\
|
|
Wenn man in einer Software einen Fehler findet, wird erst einmal ein
|
|
Bericht geschrieben und dieser Bericht bekommt eine sog. ``Ticketnummer''.
|
|
Zum Beispiel 4711.\\
|
|
Du sollst nun Ticket 4711 bearbeiten. Es wird immer (meistens) aus dem
|
|
Zweig ``develop'' ein neuer Zweig erstellt. Das heisst, du wechselst
|
|
per \textit{git checkout develop} in den Entwicklungszweig und
|
|
f"uhrst hier \textit{git pull} aus. Damit ist dein Zweig aktuell und
|
|
du kannst mit \textit{git checkout -b bug-4711} den Zweig erzeugen,
|
|
um den Fehler zu beheben.\\
|
|
Bist du irgendwann fertig damit (und hast immer wieder \textit{git
|
|
pull origin bug-4711} gemacht, kannst du deinen Zweig wieder in
|
|
den Developbranch ``zur"uckmergen'', bzw ``zur"uckmergen'' lassen.
|
|
``Lassen'' deshalb, weil in der Regel ein anderer Programmierer
|
|
erst deinen Code testet und f"ur den Merge freigibt, aber das ist
|
|
abh"angig von den Regeln der jeweiligen IT-Abteilung.
|
|
|
|
\chapter{"Altere Version auschecken}
|
|
Es wird selten gebraucht, aber manchmal denkt man: ``Verdammt,
|
|
an dem Punkt da vor ein paar Tagen/Wochen/Monaten, da lief
|
|
das System besser!''\\
|
|
Besonders, wenn man mal ``was ausprobieren'' will, ist es
|
|
ganz nett, wenn man eine ``uralte'' Version des Projektes
|
|
auschecken kann.\\
|
|
Geht recht einfach!\\
|
|
Na gut, man muss ein wenig arbeiten, denn zuerst muss man
|
|
den richtigen Commit wiederfinden. Um das Log eines GIT-Projektes
|
|
anzuzeigen, verwendet man \textit{git log}.\\
|
|
Das sieht zum Beispiel so aus:
|
|
\begin{verbatim}
|
|
commit 43632ef9d9ed259a33d030d2e71549bba752e97b
|
|
Author: Max Mustermann <hzuehl@phone-talk.net>
|
|
Date: Tue Mar 27 18:10:22 2018 +0200
|
|
|
|
blah => blubb
|
|
|
|
commit 90845d50545e2bb7069622dbe0c645241f25e9d2
|
|
Merge: 19a30b3 201d71f
|
|
Author: Max Mustermann <hzuehl@phone-talk.net>
|
|
Date: Thu Mar 22 15:08:02 2018 +0100
|
|
|
|
Merge branch 'hallo'
|
|
|
|
commit 201d71f352307d88b98aa4d1c5d5892b468948e7
|
|
Author: Max Mustermann <hzuehl@phone-talk.net>
|
|
Date: Thu Mar 22 15:07:54 2018 +0100
|
|
|
|
Blah
|
|
|
|
commit 19a30b330ab250a6d3ab3f0a9ecf1c6d9b2d9fd5
|
|
Author: Hauke Zühl <hzuehl@phone-talk.net>
|
|
Date: Thu Mar 22 13:40:59 2018 +0100
|
|
|
|
LIESMICH angelegt
|
|
\end{verbatim}
|
|
Zur Info: Ich bin zur Zeit im Masterbranch.\\
|
|
\begin{verbatim}
|
|
-rw-rw-r-- 1 hauke 0 Mar 22 15:08 blubb
|
|
-rw-rw-r-- 1 hauke 14 Mar 22 13:20 LIESMICH
|
|
\end{verbatim}
|
|
Jetzt will ich die Version vom 22.3, 13:40:59 auschecken.
|
|
Das ist der Commit\\
|
|
19a30b330ab250a6d3ab3f0a9ecf1c6d9b2d9fd5.
|
|
Dann mal los: \textit{git checkout\\
|
|
19a30b330ab250a6d3ab3f0a9ecf1c6d9b2d9fd5}\\
|
|
Das ist verdammt lang, oder?\\
|
|
An dieser Stelle ein Hinweis: Es reichen die eersten 7 Zeichen
|
|
des Hashes des Commits, also ein \textit{git checkout 19a30b3}
|
|
h"atte es auch getan!\\
|
|
Wie dem auch sein, das Verzeichnis sieht jetzt so aus:
|
|
\begin{verbatim}
|
|
-rw-rw-r-- 1 hauke 14 Mar 22 13:20 LIESMICH
|
|
\end{verbatim}
|
|
Es fehlt also eine Datei (``blubb'')! Logisch, die gab es zu diesem
|
|
Zeitpunkt noch nicht.\\
|
|
Aber Vorsicht: Es muss nicht sein, dass du dich dann noch in dem
|
|
gew"unschten Zweig befindest; du kannst an jeder Stelle jede
|
|
"Anderung auschecken und von da an weitermachen!\\
|
|
Tip: Das solltest du ein wenig "uben und noch ein Tip: An
|
|
dieser Stelle sind grafische GIT-Clients sehr n"utzlich, um
|
|
dir eine gute "Ubersicht "uber dein Projekt zu geben.\\
|
|
Wenn du aber tapfer bist und auf der Konsole bleiben willst,
|
|
bitte sch"on: \textit{git log --graph} zaubert
|
|
ein sch"ones Log auf den Bildschirm. Und wenn du die Kurzform
|
|
der Commits haben willst, dann bringt dich
|
|
\textit{git log --abbrev-commit --graph} ans Ziel.
|
|
|
|
\chapter{Ignorieren von Dateien}
|
|
Ich starte mal mit einem Beispiel, um zu zeigen, was das Problem ist:\\
|
|
Wir gehen jetzt davon aus, dass wir ein C++-Projekt compilieren, d.h.
|
|
aus dem Quellcode ein Programm ``basteln'' wollen. Wenn du dich damit
|
|
nicht auskennst, ist das nicht schlimm, es geht um Dateien und nicht um
|
|
irgendwelche freakigen Sachen.\\
|
|
Zuerst der Verzeichnisbaum eines ``frischen'' Repos:
|
|
\begin{alltt}
|
|
hauke@apollo:~/git/Lara$ tree .
|
|
.
|
|
\textbar\textendash\textendash CMakeLists.txt
|
|
\textbar\textendash\textendash Doxyfile
|
|
\textbar\textendash\textendash README.md
|
|
\textbar\textendash\textendash sql
|
|
\textbar\ \ \textbar\textendash\textendash address.sql
|
|
\textbar\ \ \(\llcorner\)\textendash\textendash customer.sql
|
|
\(\llcorner\)\textendash\textendash src
|
|
\textbar\textendash\textendash addons
|
|
\textbar\ \ \textbar\textendash\textendash Address
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash AddressAddon.cc
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash AddressAddon.h
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash AddressMainWindow.cc
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash AddressMainWindow.h
|
|
\textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash CMakeLists.txt
|
|
\textbar\ \ \(\llcorner\)\textendash\textendash CMakeLists.txt
|
|
\textbar\textendash\textendash CMakeLists.txt
|
|
\textbar\textendash\textendash core
|
|
\textbar\ \ \textbar\textendash\textendash Addon.h
|
|
\textbar\ \ \textbar\textendash\textendash Base.cc
|
|
\textbar\ \ \textbar\textendash\textendash Base.h
|
|
\textbar\ \ \textbar\textendash\textendash CMakeLists.txt
|
|
\textbar\ \ \textbar\textendash\textendash Config.cc
|
|
\textbar\ \ \textbar\textendash\textendash Config.h
|
|
\textbar\ \ \textbar\textendash\textendash Convert.cc
|
|
\textbar\ \ \textbar\textendash\textendash Convert.h
|
|
\textbar\ \ \textbar\textendash\textendash Database.cc
|
|
\textbar\ \ \textbar\textendash\textendash Database.h
|
|
\textbar\ \ \textbar\textendash\textendash Files.cc
|
|
\textbar\ \ \textbar\textendash\textendash Files.h
|
|
\textbar\ \ \textbar\textendash\textendash IDatabase.cc
|
|
\textbar\ \ \textbar\textendash\textendash IDatabase.h
|
|
\textbar\ \ \textbar\textendash\textendash Lara.cc
|
|
\textbar\ \ \textbar\textendash\textendash Lara.h
|
|
\textbar\ \ \textbar\textendash\textendash Loader.cc
|
|
\textbar\ \ \textbar\textendash\textendash Loader.h
|
|
\textbar\ \ \textbar\textendash\textendash Map.cc
|
|
\textbar\ \ \textbar\textendash\textendash Map.h
|
|
\textbar\ \ \textbar\textendash\textendash models
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash Address.h
|
|
\textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash Customer.h
|
|
\textbar\ \ \(\llcorner\)\textendash\textendash UserData.h
|
|
\textbar\textendash\textendash GUI
|
|
\textbar\ \ \textbar\textendash\textendash CMakeLists.txt
|
|
\textbar\ \ \textbar\textendash\textendash MainWindow.cc
|
|
\textbar\ \ \(\llcorner\)\textendash\textendash MainWindow.h
|
|
\(\llcorner\)\textendash\textendash main.cc
|
|
|
|
7 directories, 39 files
|
|
\end{alltt}
|
|
Ein ``git status'' s"ahe so aus:
|
|
\begin{verbatim}
|
|
hauke@apollo:~/git/Lara$ git status
|
|
Auf Branch develop
|
|
Ihr Branch ist auf dem selben Stand wie 'origin/develop'.
|
|
nichts zu committen, Arbeitsverzeichnis unverändert
|
|
hauke@apollo:~/git/Lara$
|
|
\end{verbatim}
|
|
|
|
Um dieses Projekt zu compilieren, muss ich folgende Schritte
|
|
durchf"uhren:
|
|
\begin{itemize}
|
|
\item mkdir build
|
|
\item cd build
|
|
\item cmake ../
|
|
\item make
|
|
\end{itemize}
|
|
Das heisst, ich erzeuge ein neues Verzeichnis namens ``build'',
|
|
wechsele in das dortige Verzeichnis, f"uhre ein wenig Magie aus
|
|
und am Ende f"allt das fertige Programm im Unterverzeichnis ``src''
|
|
raus.\\
|
|
Wenn ich das alles gemacht habe, sieht der Verzeichnisbaum so aus:
|
|
\begin{alltt}
|
|
.
|
|
\textbar\textendash\textendash build
|
|
\textbar\ \ \textbar\textendash\textendash CMakeCache.txt
|
|
\textbar\ \ \textbar\textendash\textendash CMakeFiles
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash 2.8.12.2
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeCCompiler.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeCXXCompiler.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeDetermineCompilerABI\_C.bin
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeDetermineCompilerABI\_CXX.bin
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeSystem.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CompilerIdC
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash a.out
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash CMakeCCompilerId.c
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash CompilerIdCXX
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash a.out
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash CMakeCXXCompilerId.cpp
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash cmake.check\_cache
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeDirectoryInformation.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeOutput.log
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeTmp
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash Makefile2
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash Makefile.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash progress.marks
|
|
\textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash TargetDirectories.txt
|
|
\textbar\ \ \textbar\textendash\textendash cmake\_install.cmake
|
|
\textbar\ \ \textbar\textendash\textendash Makefile
|
|
\textbar\ \ \(\llcorner\)\textendash\textendash src
|
|
\textbar\ \ \textbar\textendash\textendash addons
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash Address
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash address.so
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeFiles
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash address.dir
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash AddressAddon.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash AddressMainWindow.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash build.make
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash cmake_clean.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CXX.includecache
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash DependInfo.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash depend.internal
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash depend.make
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash flags.make
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash link.txt
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash progress.make
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeDirectoryInformation.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash progress.marks
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash cmake\_install.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash Makefile
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeFiles
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeDirectoryInformation.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash progress.marks
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash cmake\_install.cmake
|
|
\textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash Makefile
|
|
\textbar\ \ \textbar\textendash\textendash CMakeFiles
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash CMakeDirectoryInformation.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash lara.dir
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash build.make
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash cmake\_clean.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash core
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash Base.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash Config.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash Convert.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash Database.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash Files.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash IDatabase.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash Lara.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash Loader.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash Map.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash CXX.includecache
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash DependInfo.cmake
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash depend.internal
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash depend.make
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash flags.make
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash GUI
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash MainWindow.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash link.txt
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \textbar\textendash\textendash main.cc.o
|
|
\textbar\ \ \textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash progress.make
|
|
\textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash progress.marks
|
|
\textbar\ \ \textbar\textendash\textendash cmake\_install.cmake
|
|
\textbar\ \ \textbar\textendash\textendash lara
|
|
\textbar\ \ \(\llcorner\)\textendash\textendash Makefile
|
|
\textbar\textendash\textendash CMakeLists.txt
|
|
\textbar\textendash\textendash Doxyfile
|
|
\textbar\textendash\textendash README.md
|
|
\textbar\textendash\textendash sql
|
|
\textbar\ \ \textbar\textendash\textendash address.sql
|
|
\textbar\ \ \(\llcorner\)\textendash\textendash customer.sql
|
|
\(\llcorner\)\textendash\textendash src
|
|
\textbar\textendash\textendash addons
|
|
\textbar\ \ \textbar\textendash\textendash Address
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash AddressAddon.cc
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash AddressAddon.h
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash AddressMainWindow.cc
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash AddressMainWindow.h
|
|
\textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash CMakeLists.txt
|
|
\textbar\ \ \(\llcorner\)\textendash\textendash CMakeLists.txt
|
|
\textbar\textendash\textendash CMakeLists.txt
|
|
\textbar\textendash\textendash core
|
|
\textbar\ \ \textbar\textendash\textendash Addon.h
|
|
\textbar\ \ \textbar\textendash\textendash Base.cc
|
|
\textbar\ \ \textbar\textendash\textendash Base.h
|
|
\textbar\ \ \textbar\textendash\textendash CMakeLists.txt
|
|
\textbar\ \ \textbar\textendash\textendash Config.cc
|
|
\textbar\ \ \textbar\textendash\textendash Config.h
|
|
\textbar\ \ \textbar\textendash\textendash Convert.cc
|
|
\textbar\ \ \textbar\textendash\textendash Convert.h
|
|
\textbar\ \ \textbar\textendash\textendash Database.cc
|
|
\textbar\ \ \textbar\textendash\textendash Database.h
|
|
\textbar\ \ \textbar\textendash\textendash Files.cc
|
|
\textbar\ \ \textbar\textendash\textendash Files.h
|
|
\textbar\ \ \textbar\textendash\textendash IDatabase.cc
|
|
\textbar\ \ \textbar\textendash\textendash IDatabase.h
|
|
\textbar\ \ \textbar\textendash\textendash Lara.cc
|
|
\textbar\ \ \textbar\textendash\textendash Lara.h
|
|
\textbar\ \ \textbar\textendash\textendash Loader.cc
|
|
\textbar\ \ \textbar\textendash\textendash Loader.h
|
|
\textbar\ \ \textbar\textendash\textendash Map.cc
|
|
\textbar\ \ \textbar\textendash\textendash Map.h
|
|
\textbar\ \ \textbar\textendash\textendash models
|
|
\textbar\ \ \textbar\ \ \textbar\textendash\textendash Address.h
|
|
\textbar\ \ \textbar\ \ \(\llcorner\)\textendash\textendash Customer.h
|
|
\textbar\ \ \(\llcorner\)\textendash\textendash UserData.h
|
|
\textbar\textendash\textendash GUI
|
|
\textbar\ \ \textbar\textendash\textendash CMakeLists.txt
|
|
\textbar\ \ \textbar\textendash\textendash MainWindow.cc
|
|
\textbar\ \ \(\llcorner\)\textendash\textendash MainWindow.h
|
|
\(\llcorner\)\textendash\textendash main.cc
|
|
|
|
23 directories, 103 files
|
|
\end{alltt}
|
|
|
|
Du siehst den Unterschied!\\
|
|
|
|
Git w"urde jetzt also alle ``neuen'' Dateien unterhalb von build finden
|
|
und nat"urlich daraus schliessen, dass man diese auch ins Repo
|
|
aufnehmen will:
|
|
\begin{verbatim}
|
|
Auf Branch develop
|
|
Ihr Branch ist auf dem selben Stand wie 'origin/develop'.
|
|
Unversionierte Dateien:
|
|
(benutzen Sie "git add <Datei>...", um die Änderungen zum Commit vorzumerken)
|
|
|
|
build/
|
|
|
|
keine Änderungen zum Commit vorgemerkt (benutzen Sie "git add" und/oder "git commit -a")
|
|
\end{verbatim}
|
|
|
|
Nein! Will man nicht!\\
|
|
Man h"atte jetzt den ganzen unn"utzen ``M"ull'' f"ur eine bestimmte
|
|
Plattform und das ist nicht Sinn eines Quellcode Repositories.\\
|
|
Ergo m"ussen wir daf"ur sorgen, dass git nicht nervt, wenn wir auf
|
|
unserem Rechner das Programm bauen wollen. Dazu soll git also das
|
|
gesamte Verzeichnis ``build'', mit allen Dateien und Unterverzeichnissen
|
|
ignorieren.\\
|
|
Dazu erstellen wir im Hauptverzeichnis unseres Repos die Datei
|
|
``.gitignore'' (man beachte den Punkt vor dem Dateinamen). Die
|
|
sieht dann so aus:
|
|
\begin{verbatim}
|
|
build/
|
|
\end{verbatim}
|
|
|
|
Wenn wir jetzt ``git status'' machen, sieht das so aus:
|
|
\begin{verbatim}
|
|
Auf Branch develop
|
|
Ihr Branch ist auf dem selben Stand wie 'origin/develop'.
|
|
nichts zu committen, Arbeitsverzeichnis unverändert
|
|
\end{verbatim}
|
|
|
|
Cool! Genau das, was wir haben wollen! Das Verzeichnis ``build'' wird
|
|
von git ignoriert.\\
|
|
\\
|
|
Ein weiteres Beispiel:\\
|
|
Unter MacOS wird gerne die Datei ``.DS\_Store'' angelegt. Da diese
|
|
Datei f"ur Nutzer anderer Systeme uninteressant, ja sogar nervig
|
|
ist, sollte man also, wenn Maccies mit im Team sind, in die
|
|
.gitignore die Datei aufnehmen. Dann sieht also die .gitignore
|
|
f"ur unser C++-Projekt so aus:
|
|
\begin{verbatim}
|
|
build/
|
|
.DS_Store
|
|
\end{verbatim}
|
|
|
|
Je nach Projekt, Programmiersprache, verwendetem Editor, oder
|
|
verwendeter IDE gibt es noch weitere Dateien, die f"ur andere
|
|
uninteressant oder unwichtig sind. Diese k"onnen dann nach
|
|
und nach in die .gitignore aufgenommen werden, wobei nat"urlich
|
|
auch Wildcards verwendet werden k"onnen.
|
|
|
|
\chapter{Ein paar kleinere Tricks}
|
|
|
|
\section{Wenn es schnell gehen muss}
|
|
Es gibt durchaus Situationen, in denen man alle Branches in einem Rutsch
|
|
auf den git-Server pushen will, dann verwende man ``git push --all origin''.
|
|
|
|
Für Tags gilt analog ``git push --tags origin''.
|
|
|
|
\section{Repository von einem Server zu einem anderen umziehen}
|
|
Manchmal ändert sich der Name des Servers, auf dem die Repos gepackt
|
|
werden, z.B. wenn der Name des Unternehmens sich ändert, oder wenn
|
|
man von GitHub zu einem eigenen git-Server migriert. Gründe gibt
|
|
es genug.
|
|
|
|
Jedenfalls muss man erst einmal dafür Sorge tragen, dass das Repo auf
|
|
dem alten Server vollständig ist und keiner im Team mehr dorthin
|
|
einen Push durchführt. Ausserdem muss das eigene Repo ebenfalls komplett
|
|
auf dem aktuellsten Stand sein. Der Umzug geht dann ganz unspektakulär
|
|
per ``git git remote set-url origin <neue URL>'' von sich. Ein aktuelles
|
|
Beispiel für dieses Repo:
|
|
\begin{verbatim}
|
|
git remote set-url origin opengit@opengit.hauke-zuehl.de: \
|
|
hauke/Git-Einfuehrung.git
|
|
\end{verbatim}
|
|
|
|
\chapter{GIT in IDEs}
|
|
Die meisten IDEs bringen inzwischen Unterst"utzung f"ur GIT mit.\\
|
|
|
|
\section{Geany}
|
|
Geany ist eine kleine, erweiterbare IDE, die kostenlos f"ur diverse
|
|
Plattformen angeboten wird.\\
|
|
Mit Hilfe eines Plugins kann die Verbindung zu GIT installiert werden.
|
|
Nach der Aktivierung des Plugins steht dann unter dem Menü ``Werkzeuge''
|
|
der Eintrag ``Versionskontrolle'' zur Verfügung. Hier kann dann
|
|
GIT für die zur Zeit bearbeitete Datei oder für das gesamte Projektverzeichnis
|
|
verwendet werden.\\
|
|
\\
|
|
\textbf{Tip:}\\
|
|
Geany legt individuelle Projektdateien in einem eigenen Verzeichnis an.
|
|
Dies sollte, wenn möglich, nicht im Verzeichnis des GIT-Repos liegen, da
|
|
es sonst Probleme mit anderen Teammitgliedern geben kann!
|
|
|
|
\section{NetBeans}
|
|
NetBeans ist eine recht verbreitete IDE, die kostenlos f"ur diverse
|
|
Plattformen angeboten wird.\\
|
|
Die Verbindung von NetBeans zu GIT kann "uber ein Plugin ggf.
|
|
nachinstalliert werden.\\
|
|
Startet man NetBeans, hat man unter Team->Git die M"oglichkeit,
|
|
GIT-Repos zu verwenden.\\
|
|
Als Beispiel verwende ich nun das Repository unter
|
|
https://github.com/hauke68/LibTgBotPP, das jedoch das C-/C++-Plugin
|
|
voraussetzt.\\
|
|
Um dies anonym auszuchecken und in ein NetzBeans-Projekt zu packen,
|
|
geht man wie folgt vor:\\
|
|
Unter Team->Git->Clone wird die obige URL eingetragen. Benutzer
|
|
und Passwort bleiben leer. Im n"achsten Schritt kann man die
|
|
Zweige ausw"ahlen, die ausgecheckt werden sollen. Ich empfehle,
|
|
erst einmal alle auszuchecken. Im dritten Schritt lassen wir alles
|
|
so, wie es ist.\\
|
|
Ist alles ordnugsgem"a"s ausgecheckt, sollten wir im Git Repository
|
|
Browser bereits das GIT-Repo sehen. Nun fehlt noch das NetBeans-Projekt.\\
|
|
Dazu auf File->New Project klicken und ein neues C-/C++-Projekt anlegen.
|
|
Dabei darauf achten, dass im Fenster ``Projects'' ``C/C++ Project with
|
|
existing sources'' ausgew"ahlt ist. Im zweiten Schritt w"ahlen wir
|
|
das Verzeichnis aus, in dem die Quellen des Repos sind. Das ist nat"urlich
|
|
das vorhin erzeugte Verzeichnis vom GIT-Repo.\\
|
|
Da das hier nur ein Beispiel ist, w"ahlen wir als Configuration Mode
|
|
``custom'' aus. Jetzt nur noch auf ``Next'' klicken, bis nur noch
|
|
``Finish'' m"oglich ist. Voila, das NetBeans-Projekt existiert und
|
|
man kann auch GIT als Versionskontrollsystem verwenden.\\
|
|
Wenn du nun eine Datei l"adst, "anderst und speicherst, kannst du
|
|
unter ``Team'' sehen, dass es mehr Auswahlm"oglichkeiten in Bezug
|
|
auf GIT gibt.\\
|
|
Spiele hier einfach mal ein wenig rum. Da du das Repo anonym
|
|
ausgecheckt hast, kannst du nichts kaputt machen. Etwas anderes
|
|
w"are es nat"urlich, wenn du unser Einstiegsprojekt ``Welt'' mit
|
|
Hilfe von NetBeans bearbeiten willst. Ich wei"s aber nicht, in
|
|
welche Kategorie dieses ``Projekt'' f"allt.\\
|
|
\\
|
|
\textbf{Tip:}\\
|
|
Da NetBeans im Verzeichnis des Quellcodes gerne das Verzeichnis ``nbproject''
|
|
anlegt, sollte dies in die .gitignore aufgenommen werden, das es sonst
|
|
zu Konflikten mit dem nbproject anderer Teammitglieder kommen kann.
|
|
Noch besser w"are es, nbproject ganz woanders hin auszulagern (Zum
|
|
Beispiel in das eigene Benutzerverzeichnis).
|
|
|
|
\chapter{Zum Ende noch ein paar Ideen und Worte}
|
|
Zum Ende hin noch ein paar Anregungen bzgl. der Einsatzzwecke
|
|
von GIT.\\
|
|
Man kann GIT alleine nutzen, kein Problem. Das f"angt mit den
|
|
eigenen Skripten und Programmen an, geht "uber Korrespondenz
|
|
bis hin zu Konfigurationsdateien des Rechners (bzw. der Rechner).
|
|
Nimm dir zum Beispiel einen Raspberry Pi als GIT- und Puppetserver,
|
|
dann kannst du deine Linuxb"uchsen ganz einfach per Puppet
|
|
konfigurieren.\\
|
|
Oder du willst dir nicht gleich einen Cloudserver einrichten, dann
|
|
kannst du deine pers"onlichen Dateien mit Hilfe von GIT verwalten.\\
|
|
\\
|
|
Ich hoffe, ich konnte dir einen kleinen Einblick in die Arbeitsweise
|
|
von GIT vermitteln. Es ist ein wenig "Ubung n"otig, aber mit der Zeit
|
|
hast du die Grundkommandos verinnerlicht und solltest keine Probleme
|
|
mehr haben.\\
|
|
Tip: Committe oft! Damit ist nicht nur das ``commit'' gemeint, sondern
|
|
durchaus auch das ``push''. ``push'' sollte aber definitiv immer kurz
|
|
vor Feierabend gemacht werden.\\
|
|
Mit dieser Einstellung sorgst du daf"ur, dass man deine "Anderungen
|
|
bessser nachvollziehen kann; es ist einfacher, zwei oder drei Zeilen
|
|
sp"ater nachzuvollziehen, als wenn du 234 Zeilen in 20 Dateien
|
|
"anderst und man diese "Anderungen sp"ater nachvollziehen will.
|
|
\\
|
|
Viel Spa"s mit GIT.
|
|
|
|
\end{document}
|
|
|