\documentclass[pdf]{prosper}
\usepackage[toc,highlight,clifford,notes,hlsections]{HA-prosper}

\usepackage{svn}
\SVNdate $Date: 2007-09-19 11:19:34 +0200 (Wed, 19 Sep 2007) $

\title{Sourcecode Management mit GIT}
\subtitle{}
\author{Clifford Wolf\\
\institution{ROCK Linux - \href{http://www.rocklinux.org/}{http://www.rocklinux.org/}}\\
\institution{Csync2 - \href{http://oss.linbit.com/csync2/}{http://oss.linbit.com/csync2/}}\\
\institution{STFL - \href{http://www.clifford.at/stfl/}{http://www.clifford.at/stfl/}}\\
\institution{SPL - \href{http://www.clifford.at/spl/}{http://www.clifford.at/spl/}}}

\DefaultTransition{Wipe}
\TitleSlideNav{FullScreen}
\NormalSlideNav{ShowBookmarks}
\LeftFoot{\href{http://www.clifford.at}{Clifford Wolf}, \today}
\RightFoot{\href{http://www.clifford.at/}{http://www.clifford.at/}}

\begin{document}

\maketitle

% ============================================================================

\tsectionandpart{Einleitung}


\begin{slide}{Inhalt}
\begin{itemize}

\item Einleitung

\vspace*{0.5cm}

\item GIT Datenstrukturen (Repository)

\vspace*{0.5cm}

\item GIT Workflow (committen, branchen, mergen, etc.)

\vspace*{0.5cm}

\item Kollaboration (Pull, Push, Patches, etc.)

\vspace*{0.5cm}

\item GIT Server Administration

\vspace*{0.5cm}

\item History Manipulation (rebase, filter-branch)

\vspace*{0.5cm}

\item Subversion Integration

\vspace*{0.5cm}

\item Programmier-Interfaces

\end{itemize}
\end{slide}


\begin{slide}{Nicht-Inhalt}
\begin{itemize}

\item Kommando-Referenz (es sind \"uber 150 Kommandos!)

\vspace*{0.5cm}

\item Integration mit CVS / Quilt / Arch

\vspace*{0.5cm}

\item Step-by-Step Migration zu GIT

\end{itemize}
\end{slide}


\begin{slide}{Pitfalls}
\begin{itemize}

\item Wie jedes umfangreiche Projekt hat auch GIT seine eigene Nomenklatur
entwickelt.

\vspace*{0.2cm}

\item Leider ist diese jedoch nicht eindeutig. \\
So wurde der ``index'' z. Bsp. fr\"uher ``cache'' genannt.

\vspace*{0.7cm}

\item GIT beinhaltet Low-level-Tools zum Modifizieren der GIT-Datenstrukturen
sowie High-level-Wrapper f\"ur diese Tools.

\vspace*{0.2cm}

\item Daher gibt es bei GIT oft verschiedene Wege ein und dasselbe zu tun.

\vspace*{0.2cm}

\item Bei der Benennung der Tools und der Optionen macht sich eine "gewachsene
Struktur" bemerkbar.

\vspace*{0.7cm}

\item Anders als z. Bsp. bei Subversion ist es bei GIT m\"oglich, einmal
committete Daten nachtr\"aglich zu ver\"andern oder auch wieder zu l\"oschen.

\end{itemize}
\end{slide}


\begin{slide}{Benefits}
\begin{itemize}

\item Dezentraler Ansatz:
\begin{itemize}
\item Arbeiten von unterwegs
\item Lokale Branches zum Rumprobieren
\item Lokale Branches f\"ur lokale Modifikationen
\item Keine Commit-Rechte notwendig
\end{itemize}

\vspace*{0.5cm}

\item Geschwindigkeit:
\begin{itemize}
\item GIT ist unglaublich schnell
\item Dadurch \"andert sich auch der pers\"onliche Umgang mit dem Tool
\end{itemize}

\vspace*{0.5cm}

\item Transparenz:
\begin{itemize}
\item Es ist sehr klar was wie gespeichert wird
\item Es ist sehr klar wie die Tools arbeiten
\end{itemize}

\vspace*{0.5cm}

\item Flexibilit\"at:
\begin{itemize}
\item Mit GIT l\"asst sich praktisch jeder Workflow abbilden.
\end{itemize}

\end{itemize}
\end{slide}


\begin{slide}{Kommandos}
\begin{itemize}

\item Alle GIT-Kommandos beginnen mit {\tt git-}. \\
Z.Bsp.: {\tt git-init}, {\tt git-checkout} und {\tt git-rev-parse}

\vspace*{0.5cm}

\item Es gibt auch den Wrapper {\tt git} zum Starten dieser Kommandos. \\
Z.Bsp.: {\tt git init}, {\tt git checkout} und {\tt git rev-parse}

\vspace*{0.5cm}

\item Es wird zwischen {\it plumbing} (Low-Level) und {\it porcelain} (High-Level)
Kommandos unterschieden.

\vspace*{0.5cm}

\item Kommando\"ubersicht: {\tt man git}

\end{itemize}
\end{slide}


\begin{slide}{Dokumentation}
\begin{itemize}

\item Jedes Kommando hat eine Manpage. \\
Z.Bsp.: {\tt man git-init}

\vspace*{0.5cm}

\item Einige dieser Manpages behandeln ``nebenbei'' auch grundlegende Konzepte
von GIT.

\vspace*{0.5cm}

\item Das ``GIT User's Manual'' beinhaltet eine Step-by-step-Einf\"uhrung in
GIT.

\vspace*{1cm}

\item Die Manpages und das Manual sind auch online verf\"ugbar.

\vspace*{0.5cm}

\item Das Erzeugen der Dokumentation aus den GIT-Sourcen ist nur mit Hilfe
einiger exotischerer Tools m\"oglich..

\end{itemize}
\end{slide}


\begin{slide}{Arbeitsumgebung}
\begin{itemize}

\item Jede GIT-Anwenderin arbeitet mit einem lokalen GIT-Repository. 

\vspace*{0.5cm}

\item So ein GIT-Repository ist ein Directory, in dem eine Working Copy (die
``ausgecheckten Sourcen'') liegt, und das zus\"atzlich die gesamte Projekt-History
plus einigen Metadaten im Unterverzeichnis {\tt .git} beinhaltet.

\vspace*{0.5cm}

\item Ein neues GIT-Repository wird mit dem Kommando {\tt git-init} erstellt.

\vspace*{0.5cm}

\item Eine lokale Kopie eines bestehenden Repositorys wird mit dem Kommando
{\tt git-clone} erstellt.

\vspace*{0.5cm}

\item Alle anderen GIT-Kommandos werden in einem bestehenden Repository
gestartet.

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{Repository}


\begin{slide}{Einleitung}
\begin{itemize}

\item Ein GIT-Repository beinhaltet die vollst\"andige Geschichte des Projekts.

\vspace*{0.5cm}

\item Das bedeutet:
\begin{itemize}
\item Jede Version des Sourcecodes die zum derzeitigen Stand gef\"uhrt hat.
\item Die Metainformation welche Version von welcher anderen Version abstammt.
\end{itemize}

\vspace*{0.5cm}

\item GIT verwaltet dabei das Projekt als ganzes, und nicht einzelne Dateien.

\vspace*{0.2cm}

\item Es ist also z. Bsp. nicht direkt m\"oglich zu sehen in welchen Versionen
eine bestimmte Datei ver\"andert wurde.

\vspace*{0.5cm}

\item Branches, die verworfen wurden, werden von GIT nicht weiter beachtet und
k\"onnen auch gel\"oscht werden.

\end{itemize}
\end{slide}


\begin{slide}{Objekte}
\begin{itemize}

\item GIT verwaltet ``Objekte'', die jeweils auf andere Objekte verweisen
k\"onnen.

\vspace*{0.5cm}

\item Es gibt folgende Objekttypen:
\begin{itemize}
\vspace*{0.2cm}
\item Blops: Dateiinhalte ohne weitere Metadaten

\vspace*{0.2cm}
\item Trees: entsprechen Verzeichnissen, verweisen auf Blops f\"ur die Dateien
und auf weitere Trees f\"ur Subdirectorys

\vspace*{0.2cm}
\item Commits: Verweisen auf Vorg\"anger-Commits sowie auf das entsprechende
Tree-Objekt

\vspace*{0.2cm}
\item Tags: Verweisen auf Commits und beinhalten optional eine PGP/GPG Signatur
\end{itemize}

\vspace*{0.5cm}

\item Au\ss{}erhalb dieses Objektbaumes gibt es ``Referenzen'', die auf jene
Objekte zeigen, die als ``Einsprungspunkte'' in diesen Graphen dienen.

\end{itemize}
\end{slide}


\begin{slide}{Object Tree}
\includegraphics[scale=0.35]{objtree.eps}
\end{slide}


\begin{slide}{SHA-1 Pr\"ufsummen}
\begin{itemize}

\item Als Bezeichner f\"ur GIT-Objekte dienen SHA-1 Pr\"ufsummen \"uber
Objekttyp und Inhalt.

\vspace*{0.5cm}

\item SHA-1 garantiert praktisch Kollisionssicherheit (es gibt
$\approx 1,4615 \cdot 10^{48} $ m\"ogliche SHA-1 Pr\"ufsummen).
% ~1,4615 * 10^48 entspricht etwa der Masse unserer Sonne.. in Femtogramm!

\vspace*{0.5cm}

\item Die Pr\"ufsumme wird bei jedem Laden eines Objekts \"uberpr\"uft. Damit
ist ein Objektbaum {\bf eindeutig} und {\bf f\"alschungssicher} \"uber eine
einzelne SHA-1 Pr\"ufsumme ansprechbar.

\vspace*{0.5cm}

\item Zwei Objekte gleichen Inhalts erhalten automatisch die gleiche
Objektbezeichnung.

\end{itemize}
\end{slide}


\begin{slide}{Referenzen (1/2)}
\begin{itemize}

\item GIT-Objekte k\"onnen direkt \"uber ihren SHA-1 Key angesprochen werden.

\vspace*{0.2cm}

\item Die ersten paar Zeichen des SHA-1 Keys reichen ebenfalls aus, wenn sie
eindeutig sind.

\vspace*{0.5cm}

\item Dar\"uber hinaus k\"onnen beliebige Dateinamen im {\tt .git} Directory
verwendet werden, die den entsprechenden Key beinhalten. Insbesondere:

\vspace*{0.5cm}

\begin{tabular}{ll}
{\tt HEAD}                                  & Der Stand der Working Copy \\
{\tt ORIG\_HEAD}                            & Der letzte Stand der Working Copy \\
{\tt refs/heads/\it branch}                 & Die lokalen Branches \\
{\tt refs/remote/\it remote\tt /\it branch} & Die remote Branches \\
{\tt refs/tags/\it tag}                     & Die Tags
\end{tabular}

\end{itemize}
\end{slide}


\begin{slide}{Referenzen (2/2)}
\begin{itemize}

\item Wenn der Dateiname relativ zu {\tt .git} nicht existiert werden weitere
Directorys durchsucht:

\begin{itemize}
\item {\tt .git/refs/\it name}
\item {\tt .git/refs/tags/\it name}
\item {\tt .git/refs/heads/\it name}
\item {\tt .git/refs/remotes/\it name}
\item {\tt .git/refs/remotes/\it name\tt /HEAD}
\end{itemize}

\vspace*{0.5cm}

\item Dar\"uber hinaus gibt es von jeder dieser "Referenz-Dateien" Logfiles, so
dass es immer auch m\"oglich ist, alte Versionen wiederherzustellen.

\vspace*{0.5cm}

\item Alle diese Dateien sind einfache Textfiles.

\vspace*{0.5cm}

\item Objekte k\"onnen zus\"atzlich auch \"uber den ``Index''
referenziert werden.

\end{itemize}
\end{slide}


\begin{slide}{Referenz Lookups}
\begin{itemize}

\item Referenz-Namen k\"onnen auch spezielle Zeichen f\"ur weitere Lookups
beinhalten.

\vspace*{0.4cm}

\item Beispiele:
\begin{tabular}{ll}
{\it name\tt \textasciicircum{}}                     & Der Parent des Commits \\
{\it name\tt \textasciicircum{}$n$}                  & Der $n$te Parent des Commits (bei Merges) \\
{\it name\tt \textasciicircum{}\textasciicircum{}}   & Der Parent des Parents \\
{\it name\tt $\sim$3}                                & Der Parent des Parents des Parents \\
{\it name\tt @\{1\}}                                 & Der Wert vor der letzten \"Anderung (Log) \\
{\it name\tt @\{2.hours\}}                           & Der Wert vor zwei Stunden (aus dem Log)
\end{tabular}

\vspace*{0.4cm}

\item Die meisten Tools erzeugen automatisch sinvolle Namen mit
\textasciicircum{} und $\sim$ bei der Ausgabe.

\vspace*{0.4cm}

\item Dokumentation zur vollst\"andigen Syntax: \\
{\tt man git-rev-parse}

\end{itemize}
\end{slide}


\begin{slide}{Reflogs}
\begin{itemize}

\item Jede \"Anderung einer Referenz wird in einem Logfile gespeichert, 
\item dazu der Zeitpunkt sowie eine Log-Message.

\vspace*{0.5cm}

\item Das erm\"oglicht zum Beispiel ein einfaches Zur\"ucksetzen auf einen
alten Wert.

\vspace*{0.5cm}

\item Die Log-Files liegen im Directory {\tt .git/logs}.

\vspace*{0.5cm}

\item Es sind einfache Textdateien mit einer Zeile pro Log-Message.

\vspace*{0.5cm}

\item Tool zum Arbeiten mit Reflogs: {\tt git-reflog}

\end{itemize}
\end{slide}


\begin{slide}{Config}
\begin{itemize}

\item Jedes Repository hat ein {\tt .ini}-style Config-File ({\tt .git/config}).

\vspace*{0.5cm}

\item Globale Einstellungen k\"onnen in {\tt \textasciitilde{}/.gitconfig} eingetragen werden.

\vspace*{0.5cm}

\item Im Config-File kann das Verhalten der GIT-Tools parametriert werden, und hier kann auch 
der Workflow eingestellt werden.

\vspace*{0.5cm}

\item Zum Beispiel werden im Config-File die ``Branch-Pfade'' eingestellt,
also festgelegt, welcher Branch von welchen anderen Branches merged.

\vspace*{0.5cm}

\item Dokumentation: {\tt man git-config}

\end{itemize}
\end{slide}


\begin{slide}{Global Config}
\begin{itemize}

\item Globale Einstellungen k\"onnen in {\tt \textasciitilde{}/.gitconfig} gespeichert werden.

\vspace*{0.5cm}

\item F\"ur die globale config hat {\tt git-config} die Option {\tt --global}.

\vspace*{0.5cm}

\item Beispiele:
\begin{verbatim}
git-config --global user.email "clifford@clifford.at"
git-config --global user.name "Clifford Wolf"

git-config --global alias.co "checkout"
git-config --global http.proxy "http://proxy:port"
\end{verbatim}

\end{itemize}
\end{slide}


\begin{slide}{Repository-Administration}
\begin{itemize}

\item Das Kommando {\tt git-gc} muss regelm\"a\ss{}ig gestartet werden.

\vspace*{0.5cm}

\item In der Regel geschieht dies automatisch durch andere GIT Kommandos.

\vspace*{0.5cm}

\item Das Kommando {\tt git-gc} f\"uhrt folgende Operation aus:
\begin{itemize}
\item Kompression der Objekt-Datenbank
\item Expiren alter Reflog Eintr\"age
\item L\"oschen alter unreferenzierter Objekte
\end{itemize}

\vspace*{0.5cm}

\item Das Kommando {\tt git-prune} l\"oscht alle unreferenzierten Objekte.

\vspace*{0.5cm}

\item Dokumentation: {\tt man git-gc}, {\tt man git-prune}

\end{itemize}
\end{slide}


\begin{slide}{Repository Browsing}
\begin{itemize}

\item Typ eines Objekts bestimmen: {\tt git-cat-file -t}

\vspace*{0.5cm}

\item Blop/Commit/Tag anzeigen: {\tt git-cat-file}
\item Tree anzeigen: {\tt git-ls-tree}
\item High-Level Tool: {\tt git-show}

\vspace*{0.5cm}

\item Liste aller Referenzen: {\tt git-show-ref}

\vspace*{0.5cm}

\item Commit-Graph anzeigen: {\tt git-show-branch}

\vspace*{0.5cm}

\item Grafischer Repository Browser: {\tt gitk}

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{Working Copy und Index}

\begin{slide}{Einleitung}
\begin{itemize}

\item F\"ur ein neues Commit ben\"otigt man ein (neues) Top-level-tree-Objekt.

\vspace*{0.5cm}

\item Dieses neue Top-level-tree-Objekt wird im ``Index'' vorbereitet.
\item Dieser ``Index'' ist lediglich eine Liste von (blop) Objekten und
den dazugeh\"origen Dateinamen.

\vspace*{0.5cm}

\item Ein neuer Tree wird wie folgt im Index aufgebaut:
\begin{itemize}
\item Der alte Zustand wird mit {\tt git-checkout} in den Index geladen.
\item Mit {\tt git-add} werden neue blop-Objekte erzeugt und in den Index eingef\"ugt.
\item Mit {\tt git-rm} k\"onnen Eintr\"age aus dem Index entfern werden.
\end{itemize}

\vspace*{0.5cm}

\item Schlussendlich werden mit {\tt git-commit} ein neues Tree-Objekt und ein
neues Commit-Objekt erzeugt.

\end{itemize}
\end{slide}

\begin{slide}{Workcycle}
\includegraphics[scale=0.28]{workcycle.eps}
\end{slide}


\begin{slide}{Weitere Kommandos}
\begin{itemize}

\item Index anzeigen: {\tt git-ls-files --stage}

\vspace*{0.5cm}

\item Nur manche \"Anderungen zum Index: {\tt git-add --patch}

\vspace*{0.5cm}

\item Low-level Index Updates: {\tt git-update-index}

\vspace*{0.5cm}

\item Updaten einer Referenz: {\tt git-update-ref} \\
(Wird auch automatisch von {\tt git-commit} gemacht.)

\vspace*{0.5cm}

\item \"Anderungen zwischen Working Tree, Index und HEAD Referenz:
{\tt git-status}, {\tt git-diff}

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{Branchen und Mergen}


\begin{slide}{Branch (1/2)}
\begin{itemize}

\item Ein Commit kann mehrere Nachkommen haben.
\item Diese nennt man dann {\it Branches}.

\vspace*{0.5cm}

\item Mit {\tt git-commit} wird auch die aktuelle Referenz geupdatet.
\item F\"ur mehrere Branches werden mehrere Referenzen ben\"otigt.

\vspace*{0.5cm}

\item Branches k\"onnen angelegt werden mit: \\
{\tt git-branch \it Neuer-Branch [Alter-Branch]} \hspace{0.5cm} bzw. \\
{\tt git-checkout -b \it Neuer-Branch [Alter-Branch]}

\vspace*{0.5cm}

\item Zwischen Branches kann gewechselt werden (Working Copy und Index) mittels: \\
{\tt git-checkout \it Branch-Name}

\vspace*{0.5cm}

\item Alle Branches auflisten: {\tt git-branch}

\end{itemize}
\end{slide}


\begin{slide}{Branch (2/2)}
\includegraphics[scale=0.35]{branch.eps}
\end{slide}


\begin{slide}{Merge (1/2)}
\begin{itemize}

\item Ein Commit kann mehrere Vorfahren haben.
\item Diese nennt man dann {\it Merges}.

\vspace*{0.5cm}

\item Die \"Anderungen aus einem Branch in den aktuellen Branch mergen: \\
{\tt git-merge \it Anderer-Branch}

\vspace*{0.5cm}

\item Manchmal m\"ochte man auch mehrere Branches gleichzeitig mergen: \\
{\tt git-merge \it Anderer-Branch1 Anderer-Branch2 ...}

\vspace*{0.5cm}

\item H\"aufig m\"ochte man anschlie\ss{}end den gemergten Branch l\"oschen: \\
{\tt git-branch -d Anderer-Branch}

\end{itemize}
\end{slide}


\begin{slide}{Merge (2/2)}
\includegraphics[scale=0.35]{merge.eps}
\end{slide}


\begin{slide}{Rebase (1/2)}
\begin{itemize}

\item Manchmal m\"ochte man einen Branch auch mit einem neuen Ursprungspunkt
neu erzeugen.
\item Dieser Prozess wird {\it Rebase} genannt.

\vspace*{0.5cm}

\item Dazu wird im betroffenen Branch ausgef\"uhrt: \\
{\tt git-rebase \it Upstream-Branch}

\vspace*{0.5cm}

\item Das ist speziell dann interessant, wenn man Branches f\"ur Upstream-Repositorys warten oder aufbereiten m\"ochte.

\vspace*{0.5cm}

\item Der urspr\"ungliche Branch wird dadurch dereferenziert,
\item Aber \"uber das Reflog kann er noch gefunden werden.

\end{itemize}
\end{slide}


\begin{slide}{Rebase (2/2)}
\includegraphics[scale=0.35]{rebase.eps}
\end{slide}


\begin{slide}{Konflikte}
\begin{itemize}

\item Beim Mergen und Rebasen k\"onnen Konflikte auftreten.

\vspace*{0.5cm}

\item Dann wird das Kommando mit einem Fehler abgebrochen und die am Konflikt
beteiligten Dateien werden im Index referenziert.

\vspace*{0.5cm}

\item Ein solcher Index kann nicht zu einem Tree umgewandelt werden.

\vspace*{0.5cm}

\item Dateien, f\"ur die der Konflikt aufgel\"ost wurde, werden mit
{\tt git-add} markiert.

\vspace*{0.5cm}

\item Nachdem alle Konflikte aufgel\"ost wurden:
\begin{tabular}{ll}
{\tt git-commit} & (bei einem Merge) \\
{\tt git-rebase --continue} & (bei einem Rebase)
\end{tabular}

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{Kollaboration}


\begin{slide}{Einleitung}
\begin{itemize}

\item Grundlage f\"ur kollaboratives Arbeiten bildet die M\"oglichkeit zu
branchen und zu mergen (bzw. rebasen).

\vspace*{0.5cm}

\item Dann braucht nur noch jede Entwicklerin ihre Branches - und die
\"Anderungen k\"onnen via Merge von einem Branch in einen anderen \"ubernommen
werden.

\vspace*{0.5cm}

\item GIT erlaubt es, Branches zwischen Repositorys zu spiegeln.

\vspace*{0.5cm}

\item Das bedeutet, jede Entwicklerin kann ihr eigenes Repository f\"ur ihre
eigenen Branches betreiben.

\end{itemize}
\end{slide}


\begin{slide}{Protokolle}
\begin{itemize}

\item Der Zugriff auf andere Repositorys ist \"uber mehrere Protokolle
m\"oglich:

\begin{small}
\begin{itemize}
\item {\tt rsync://host.xz/path/to/repo.git/}
\item {\tt http://host.xz/path/to/repo.git/}
\item {\tt https://host.xz/path/to/repo.git/}
\item {\tt git://host.xz/path/to/repo.git/}
\item {\tt git://host.xz/\textasciitilde{}user/path/to/repo.git/}
\item {\tt ssh://[user@]host.xz[:port]/path/to/repo.git/}
\item {\tt ssh://[user@]host.xz/path/to/repo.git/}
\item {\tt ssh://[user@]host.xz/\textasciitilde{}user/path/to/repo.git/}
\item {\tt ssh://[user@]host.xz/\textasciitilde{}/path/to/repo.git}
\item {\tt file:///path/to/repo.git/}
\end{itemize}
\end{small}

\vspace*{0.5cm}

\item Einige k\"urzere Formen sind m\"oglich. Zum Beispiel:

\begin{small}
\begin{itemize}
\item {\tt [user@]host.xz/path/to/repo.git/} \hspace{0.5cm} (ssh)
\item {\tt /path/to/repo.git/} \hspace{0.5cm} (lokale files)
\end{itemize}
\end{small}

\end{itemize}
\end{slide}


\begin{slide}{Fetch (1/2)}
\begin{itemize}

\item Mit dem Kommando {\tt git-fetch} k\"onnen Branches (Referenzen) aus
einem anderen Repository importiert werden.

\vspace*{0.5cm}

\item Alle von der Referenz erreichbaren Objekte werden gegebenenfalls ebenfalls
importiert.

\vspace*{0.5cm}

\item Beispiel: \\
{\tt git-fetch git://git.kernel.org/pub/scm/\textcolor{red}{\dots} \\
\hspace{0.5cm}\textcolor{red}{\dots}linux/kernel/git/torvalds/linux-2.6.git \\
\hspace{0.5cm}'+refs/heads/*:refs/remotes/linus/*'}

\vspace*{0.5cm}

\item Solche {\it remote branches} benutzen in der Regel Referenz-Namen nach
dem Muster {\tt refs/remotes/\it short-rep-name\tt /\it branch-name}.

\end{itemize}
\end{slide}


\begin{slide}{Fetch (2/2)}
\begin{itemize}

\item Per Default macht {\tt git-fetch} nur {\it fast-forward} Updates.

\vspace*{0.5cm}

\item Das bedeutet, die alte Referenz muss von der neuen aus erreichbar sein.

\vspace*{0.5cm}

\item Die Option {\tt -f} bzw. ein f\"uhrendes {\tt +} in der {\it refspec}
\"uberschreiben diesen Check.

\vspace*{1cm}

\item {\tt git-fetch} ist ein {\it plumbing} (low-level) Tool.

\vspace*{0.5cm}

\item Normalerweise wird das High-level-Tool {\tt git-pull} verwendet.

\end{itemize}
\end{slide}


\begin{slide}{Pull}
\begin{itemize}

\item Das (porcelain) Kommando {\tt git-pull} ist eine Kombination aus
{\tt git-fetch} und {\tt git-merge}.

\vspace*{0.5cm}

\item In der Regel wird die zu verfolgende Referenz in die Datei
{\tt .git/config} geschrieben.

\vspace*{0.5cm}

\item {\tt git-pull} kann auch so konfiguriert werden, dass es {\tt git-rebase}
statt {\tt git-merge} verwendet.

\vspace*{0.5cm}

\item {\tt git-pull} wird wie {\tt git-merge} in der Working Copy des zu
aktualisierenden Branches gestartet.

\vspace*{1cm}

\item {\tt git-pull} entspricht von der typischen Verwendung her dem {\tt svn up}
bzw. {\tt cvs up} aus Subversion bzw. CVS.

\end{itemize}
\end{slide}


\begin{slide}{Push}
\begin{itemize}

\item {\tt git-push} wird zum Updaten von Remote Repositorys verwendet.

\vspace*{0.5cm}

\item Per Default macht {\tt git-push} nur {\it fast-forward} Updates.

\vspace*{0.5cm}

\item In der Regel wird in {\tt .git/config} eingestellt, welche lokalen
Branches in welche Remote-Branches gepushed werden sollen.

\vspace*{0.5cm}

\item Als Parameter erwartet {\tt git-push} den Namen des Remote Repositorys.

\vspace*{1cm}

\item Pushes \"uber das Netzwerk werden in der Praxis fast ausschlie\ss{}lich
per SSH Protokoll erlaubt.

\end{itemize}
\end{slide}


\begin{slide}{Example .git/config}
\begin{verbatim}
[remote "origin"]
url = git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
fetch = +refs/heads/*:refs/remotes/origin/*

[remote "gitorious"]
url = git@gitorious.org:linux-cw/mainline.git
push = +refs/heads/*:refs/heads/*

[branch "master"]
remote = origin
merge = refs/heads/master

[branch "feature-proc-rlim"]
remote = origin
merge = refs/heads/master
rebase = true
\end{verbatim}
\end{slide}


\begin{slide}{Clonen}
\begin{itemize}

\item Die meisten GIT-Repositorys beinhalten lokale Branches zu bereits
vorhandenen Netzwerk-Repositories.

\vspace*{0.5cm}

\item Zum Erstellen solcher Repositorys gibt es das Porcelain-Tool {\tt git-clone}.

\vspace*{0.5cm}

\item Beispiel: \\
{\tt \small git-clone git://git.kernel.org/pub/scm/linux/\textcolor{red}{\dots} \\
\hspace{0.5cm}\textcolor{red}{\dots}kernel/git/torvalds/linux-2.6.git linux-26}

\vspace*{0.5cm}

\item {\tt git-clone} erzeugt ein lokales Repository mit einer
passenden {\tt .git/config} Datei, f\"uhrt das initiale {\tt git-fetch}
durch und erzeugt einen localen Branch {\tt master} vom gleichnamigen
Branch im Remote-Repository.

\end{itemize}
\end{slide}


\begin{slide}{Patches}
\begin{itemize}

\item Ungeachtet der M\"oglichkeit Branches zu pullen m\"ochte man oft
den ``traditionellen'' Weg \"uber Patches und Emails gehen.

\vspace*{0.5cm}

\item Daf\"ur gibt es einige spezielle Porcelain-Tools.

\vspace*{1cm}

\item {\tt git-format-patch} erzeugt fertige E-Mail Texte mit Patches.

\vspace*{0.3cm}

\item {\tt git-send-email} versendet diese Patches per E-Mail.

\vspace*{0.3cm}

\item {\tt git-am} applied Patches aus einem Mailbox-File.

\end{itemize}
\end{slide}


\begin{slide}{Linear Development}
\begin{itemize}

\item GIT wird in der Regel mit {\it Non-Linear Development} in Verbindung
gebracht.

\vspace*{0.3cm}

\item Aber mit GIT ist ebenso ein linearer Workflow umsetzbar:

\vspace*{1cm}

\item Alle Entwicklerinnen pushen in ein gemeinsames Upstream-Repository.

\vspace*{0.5cm}

\item Nur Fast-forward-Updates sind erlaubt. \\
(Das kann mit einem {\tt .git/hooks/update} Script erzwungen werden.)

\vspace*{0.5cm}

\item Das hei\ss{}t, es kann nur pushen wer zuerst den aktuellen HEAD gepulled
hat.

\end{itemize}
\end{slide}


\begin{slide}{Bisect}
\begin{itemize}

\item Fehlersuche in gro\ss{}en Projekten kann aufwendig sein.

\vspace*{0.5cm}

\item Das Tool {\tt git-bisect} implementiert eine bin\"are Suche nach jenem
Commit, der den Fehler eingef\"uhrt hat.

\vspace*{0.5cm}

\item Workflow:
\begin{itemize}
\item {\tt git bisect start [<bad> [<good>]]}
\item {\tt git bisect \{ bad | good | skip \} [<rev>]}
\item {\tt git bisect \{ log | visualize \}}
\item {\tt git bisect reset}
\end{itemize}

\vspace*{0.5cm}

\item Automatisiertes Bisect mit Script: \\
{\tt git bisect run my\_script}

\end{itemize}
\end{slide}


\begin{slide}{Bare Repositorys}
\begin{itemize}

\item Bei Netzwerk Repositorys wird keine Working Copy ben\"otigt.

\vspace*{0.5cm}

\item Daher gibt es auch {\it Bare Repositorys}.

\vspace*{0.5cm}

\item Solche {\it Bare Repositorys} sind Directorys mit der Dateiendung
{\tt .git}, die nur die Dateien aus dem {\tt .git} Directory beinhalten.

\vspace*{0.5cm}

\item Daher enden die GIT-URLs auch meistens mit {\tt .git}.

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{GIT Server}


\begin{slide}{GIT via SSH}
\begin{itemize}

\item Um per SSH auf ein Repository zugreifen zu k\"onnen ist kein eigener
Serverprozess notwendig.

\vspace*{0.5cm}

\item F\"ur Pushes wird am Server das Programm {\tt git-receive-pack}
aufgerufen.

\vspace*{0.5cm}

\item F\"ur Pulls wird am Server {\tt git-upload-pack} aufgerufen.

\vspace*{0.5cm}

\item Restricted SSH login Shell f\"ur GIT: {\tt git-shell}

\vspace*{0.5cm}

\item Beispiel: \\
{\tt git-clone ssh://clifford@clifford.at/\textasciitilde{}/\textcolor{red}{\dots} \\
\hspace{0.5cm}\textcolor{red}{\dots}gitdata/linux-2.6 linux-2.6}

\end{itemize}
\end{slide}


\begin{slide}{git-daemon}
\begin{itemize}

\item Als Server f\"ur world-readable GIT Repositorys gibt es {\tt git-daemon}.

\vspace*{0.5cm}

\item {\tt git-daemon} kann als Stand-alone-Daemon oder unter {\tt inetd}
laufen.

\vspace*{0.5cm}

\item {\tt git-daemon} exportiert per Default nur Repositorys mit der Datei
{\tt git-daemon-export-ok}.

\vspace*{1cm}

\item Dokumentation: {\tt man git-daemon}

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{Rewriting History}


\begin{slide}{Interactive Rebase (1/2)}
\begin{itemize}

\item {\tt git-rebase} erlaubt das Ersetzten einer Commit-Reihe durch eine
andere.

\vspace*{0.4cm}

\item Beim {\it interactive rebase} kann nicht nur die Base-Revision sondern
auch die Commit-Reihe selbst ver\"andert werden:

\vspace*{0.2cm}
\hspace*{1cm} {\tt git-rebase -i \it base-revision}

\vspace*{0.4cm}

\item Beim interactive Rebase \"offnet {\tt git-rebase} einen Text-Editor mit
den Commits in der betroffenen Commit-Reihe.

\vspace*{0.4cm}

\item Durch Editieren dieses Textes kann die Commit-Reihe ver\"andert werden:
\begin{itemize}
\item Entfernen von Commits.
\item \"Andern der Reihenfolge.
\item Ver\"andern von Commits.
\item Zusammenf\"ugen von Commits.
\end{itemize}

\end{itemize}
\end{slide}


\begin{slide}{Interactive Rebase (1/2)}
\begin{verbatim}

pick b87fba1 Erster Patch im Rebase
pick 054f700 Zweiter Patch im Rebase
pick 4683128 Dritter Patch im Rebase

# Rebase b6c4c9a..4683128 onto b6c4c9a
#
# Commands:
#  pick = use commit
#  edit = use commit, but stop for amending
#  squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will
# be aborted.
#

\end{verbatim}

Mehr Informationen: {\tt man git-rebase}

\end{slide}


\begin{slide}{git-reset}
\begin{itemize}

\item Mit {\tt git-reset} kann eine Referenz auf einen (alten) Commit
(zur\"uck-)gesetzt werden.

\vspace*{0.5cm}

\item Nur die HEAD Referenz setzen: \\
\hspace*{1.0cm} {\tt git-reset --soft \it commit}

\vspace*{0.5cm}

\item Die HEAD Referenz und den Index setzen: \\
\hspace*{1.0cm} {\tt git-reset --mixed \it commit}
\hspace*{1.0cm} (default)

\vspace*{0.5cm}

\item Die HEAD Referenz, Index und Working-Copy setzen: \\
\hspace*{1.0cm} {\tt git-reset --hard \it commit}

\vspace*{0.7cm}

\item Beispiel:
\begin{verbatim}
git branch topic/wip
git reset --hard HEAD~3
git checkout topic/wip
\end{verbatim}

\end{itemize}
\end{slide}


\begin{slide}{git-filter-branch}
\begin{itemize}

\item Mit {\tt git-filter-branch} kann man automatisiert ganze Branches
ver\"andern.

\vspace*{0.5cm}

\item Nat\"urlich wird es dadurch unter Umst\"anden sehr erschwert, \"Anderungen 
einfach zu pullen, zu mergen und zu pushen.

\vspace*{0.5cm}

\item Beispiel (Script in der Working Copy): \\
{\tt git-filter-branch --tree-filter 'rm\textcolor{red}{\dots} \\
\hspace{0.5cm}\textcolor{red}{\dots} filename' HEAD}

\vspace*{0.5cm}

\item Beispiel (Script direkt mit dem Index): \\
{\tt git-filter-branch --index-filter 'git-\textcolor{red}{\dots} \\
\hspace{0.5cm}\textcolor{red}{\dots}update-index --remove filename' HEAD}

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{Subversion Integration}


\begin{slide}{git-svn}
\begin{itemize}

\item Mit {\tt git-svn} k\"onnen SVN Repositorys in lokale GIT Repositorys
gecloned werden.

\vspace*{0.5cm}

\item Lokale Commits k\"onnen auch ins SVN Repository committet werden.

\vspace*{0.5cm}

\item Neue Revisions im Subversion k\"onnen auch ins lokale Repository
importiert werden.

\vspace*{1cm}

\item Dokumentation: {\tt man git-svn}

\end{itemize}
\end{slide}


\begin{slide}{Example}
\begin{verbatim}
$ git-svn clone http://svn.clifford.at/stfl/trunk stfl
$ cd stfl

# do some work
$ git-commit ...

# instead of 'svn up':
$ git-svn rebase

# pushing changes to SVN repository:
$ git-svn dcommit

# import svn:ignore properties:
$ git-svn show-ignore >> .git/info/exclude
\end{verbatim}
\end{slide}


\begin{slide}{git-svnimport}
\begin{itemize}

\item Das alte Tool {\tt git-svnimport} importierte ganze SVN Repositorys.

\vspace*{0.5cm}

\item Ein Zur\"uckpropagieren zu SVN war nicht m\"oglich.

\vspace*{0.5cm}

\item Die bei Subversion \"ubliche Verzeichnisstruktur ({\tt /trunk},
{\tt /branches}, {\tt /tags}, etc.) wurde vorausgesetzt.

\vspace*{0.5cm}

\item {\tt git-svnimport} ist seit Oktober 2007 deprecated.

\vspace*{0.5cm}

\item Das Script kann aber noch unter {\tt /contrib/examples/} in den GIT
Sourcen gefunden werden.

\end{itemize}
\end{slide}


% ============================================================================

\tsectionandpart{Eigene Tools}


\begin{slide}{Shell Scripts}
\begin{itemize}

\item Viele der GIT (Porcelain-)Tools sind als Shell-Scripte implementiert.

\vspace*{0.5cm}

\item Diese Tools benutzen andere GIT-Kommandos f\"ur Low-Level-Aufgaben.

\vspace*{0.5cm}

\item Es bietet sich daher an, bei Bedarf eigene (Porcelain-)Tools als
Shell-Scripts zu implementieren.

\vspace*{1cm}

\item Beispiele f\"ur GIT Tools, die als Shell-Scripte implementiert sind: \\
{\tt git-bisect}, {\tt git-clone}, {\tt git-merge}, {\tt git-pull},
{\tt git-rebase}, {\tt git-stash}, ...

\end{itemize}
\end{slide}


\begin{slide}{Tipps}
\begin{itemize}

\item Files im {\tt .git} Directory nur direkt angreifen, wenn es kein
entsprechendes Tool gibt. \\
Siehe zum Beispiel: {\tt git-update-ref}, {\tt git-rev-parse}, {\tt git-config}, ...

\vspace*{0.5cm}

\item GIT Kommandos sollten von Scripts immer mit '{\tt git \it kommando}'
statt '{\tt git-\it kommando}' gestartet werden.

\vspace*{0.5cm}

\item Parsen von Argumenten und Optionen: \\
{\tt git-rev-parse --parseopt}

\vspace*{0.5cm}

\item Initialisieren von Scripten: {\tt git-sh-setup}

\end{itemize}
\end{slide}


\begin{slide}{git-sh-setup}
\begin{itemize}

\item Mit '{\tt . git-sh-setup}' kann ein GIT Shell-Script bequem initialisiert
werden.

\vspace*{0.3cm}

\item {\tt git-sh-setup} definiert einige praktische Funktionen.
\item Davor sind einige Shell Variablen zu setzen.

\vspace*{0.3cm}

\item Dokumentation: {\tt man git-sh-setup}

\end{itemize}

\vspace*{0.5cm}

Usage Example: \\
\begin{verbatim}
USAGE='[  | save | list | clear | create ]'
SUBDIRECTORY_OK=Yes
OPTIONS_SPEC=
. git-sh-setup
require_work_tree
cd_to_toplevel
\end{verbatim}

\end{slide}

% ============================================================================

\tsectionandpart{Weitere Tools}


\begin{slide}{git-stash}
\begin{itemize}

\item {\tt git-stash} comittet lokale Changes nach {\tt refs/stash} und
resettet den Working-Tree.

\vspace*{0.5cm}

\item {\tt git-stash apply} spielt diese \"Anderungen wieder im Working-Tree
ein.

\vspace*{0.5cm}

\item Das ist vor allem n\"utzlich um 'mal schnell' die aktuelle Arbeit beseite
stellen zu k\"onnen um z. Bsp. einen Hotfix zu schreiben.


\end{itemize}

\vspace*{0.5cm}

Usage Example: \\
\begin{verbatim}
$ git-stash
<edit emergency fix>
$ git-commit -a -m "Fix in a hurry"
$ git-stash apply
\end{verbatim}

\end{slide}


\begin{slide}{git-clean}
\begin{itemize}

\item {\tt git-clean} entfernt Dateien aus dem Working-Tree die nicht
unter der Kontrolle von git stehen.

\vspace*{0.5cm}

\item Damit erf\"ullt {\tt git-clean} eine \"ahnliche Funktion wie das
{\tt make clean}, das die meisten Makefiles implementieren.

\vspace*{0.5cm}

\item Lokale \"Anderungen k\"onnen mit {\tt git-checkout} r\"uckg\"angig gemacht
werden.

\vspace*{0.5cm}

\item Lokale \"Anderungen, die dem Index hinzugef\"ugt wurden, k\"onnen mit
{\tt git-reset} und {\tt git-checkout -f} r\"uckg\"angig gemacht werden.

\vspace*{0.5cm}

\item Dokumentation: {\tt man git-clean}, {\tt man git-checkout}, {\tt man git-reset}

\end{itemize}
\end{slide}


\begin{slide}{git-tag}
\begin{itemize}

\item Mit {\tt git-tag} k\"onnen Tags erzeugt und abgefragt werden.

\vspace*{0.5cm}

\item Tags sind Referenzen und k\"onnen z. Bsp. ganz normal mit {\tt
git-checkout} ausgecheckt werden.

\vspace*{0.5cm}

\item Bei Bedarf wird ein eigenes Tag-Objekt erzeugt, das eine Message
sowie eine GPG-Signatur beinhalten kann.

\vspace*{0.5cm}

\item Dokumentation: {\tt man git-tag}

\end{itemize}
\end{slide}


\begin{slide}{git-blame}
\begin{itemize}

\item {\tt git-blame} gibt eine Datei zeilenweise aus und f\"ugt jeder
Zeile Informationen zur letzten \"Anderung hinzu.

\vspace*{0.5cm}

\item Erleichtert es die ``Schuldige'' f\"ur einen Bug zu finden.

\vspace*{0.5cm}

\item Oder einfach nur den gr\"o\ss{}eren Kontext einer \"Anderung zu ermitteln.

\vspace*{0.5cm}

\item F\"ur die Weiterverarbeitung gibt es ein eigenes ``porcelain''
Ausgabeformat (Option {\tt -p}).

\vspace*{0.5cm}

\item Dokumentation: {\tt man git-blame}

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{URLs}


\begin{slide}{GIT}
\begin{itemize}

\item GIT Homepage \\
{\tt http://git.or.cz/}

\vspace*{0.5cm}

\item GIT Manpages \\
{\tt http://www.kernel.org/pub/software/scm/git/docs/}

\vspace*{0.5cm}

\item GIT User's Manual \\
{\tt http://www.kernel.org/pub/software \\
\hspace{0.5cm} /scm/git/docs/user-manual.html}

\end{itemize}
\end{slide}


\begin{slide}{Diese Pr\"asentation}
\begin{itemize}

\item Cliffords Tools \\
{\tt http://svn.clifford.at/tools/trunk/}

\vspace*{1cm}

\item Clifford Wolf \\
{\tt http://www.clifford.at/}

\vspace*{0.5cm}

\item Weitere Pr\"asentationen \\
{\tt http://www.clifford.at/papers/}

\vspace*{0.5cm}

\item Diese Pr\"asentation \\
{\tt http://www.clifford.at/papers/2008/git/}

\end{itemize}
\end{slide}

% ============================================================================

\end{document}

