\usetheme{default}
\setbeamertemplate{navigation symbols}{}

\mode<beamer>
{
  \setbeamercolor{background canvas}{bg=black!10}
}
\setbeamercolor*{block body}{fg=black,bg=white}
\setbeamercolor*{block title}{use=titlelike,fg=titlelike.fg!80!black,bg=black!10}

\usepackage{ngerman}
\usepackage[utf8]{inputenc}

\usepackage{listings}
\usepackage{xcolor}
\definecolor{darkgreen}{rgb}{0,0.39,0}

\usepackage{graphicx}
\usepackage{icomma}
\usepackage[normalem]{ulem}

\usepackage{multirow}

\usepackage[overlay,absolute]{textpos}

\usepackage{tikz}
\usetikzlibrary{shadows}
\usetikzlibrary{decorations.pathreplacing}
\usetikzlibrary{shapes.geometric}

\usepackage{wasysym}

\title[Versionierung für OpenSourcler]{{\small Verteilte Versionskontrolle mit Git}\\
  \LARGE Versionierung für OpenSourcler}

\author[Sebastian "`tokkee"' Harl]{Sebastian "`tokkee"' Harl\\
  $<$tokkee@debian.org$>$}
%\institute{Debian RRDtool Team}

\date[ORR 2010]{\textbf{OpenRheinRuhr 2010}\\ 14.\ November 2010}

\subject{Versionierung für OpenSourcler}

\titlegraphic{
  \vspace*{-10mm}
  \begin{minipage}[c]{19mm}
    \includegraphics[height=20mm]{orr-logo.pdf}
  \end{minipage}
  \hfill
  \begin{minipage}[c]{13mm}
    \includegraphics[height=25mm]{gitlogo.pdf}
  \end{minipage}
}

% This is rather a hack, but it's easier than defining custom beamer themes
% for now.
\setbeamertemplate{frametitle}{}
\newenvironment{frameframe}[1]
  {
    \begin{frame}[fragile,environment=frameframe]
    % width of a slide is 128 mm
    \begin{textblock*}{116mm}(6mm,4mm)
      \begin{tikzpicture}[x=1mm,y=1mm]
	\filldraw[fill=white,rounded corners=2mm,very thick]
	  (0,0) rectangle (116,75);
	\draw[thin] (58,75) node [fill=white,drop shadow,draw]
	  { \usebeamerfont*{frametitle}\usebeamercolor[fg]{frametitle}#1 };
	\draw (58,78) node {};
      \end{tikzpicture}
    \end{textblock*}
    \begin{textblock*}{122mm}(3mm,85mm)
      \begin{minipage}[c]{8mm}
	\includegraphics[width=8mm]{orr-logo.pdf}
      \end{minipage}
      \hfill
      \begin{minipage}[c]{105mm}
	\centering
	{\tiny \insertshorttitle{}
	 \hspace{3mm}---\hspace{3mm}
	 \insertshortauthor{}
	 \hspace{3mm}---\hspace{3mm}
	 \insertframenumber\,/\,\inserttotalframenumber}
      \end{minipage}
      \hfill
      \begin{minipage}[c]{5mm}
	\includegraphics[width=5mm]{gitlogo.pdf}
      \end{minipage}
    \end{textblock*}
    \begin{textblock*}{\textwidth}(10mm,12mm)
      % even hackier ... ;-)
      % vertically center the text in the frame
      \begin{minipage}[c]{-1pt}\rule{0mm}{71mm}
      \end{minipage}\begin{minipage}[c]{\textwidth}
  }
  {
      \end{minipage}
    \end{textblock*}
    \end{frame}
  }

\AtBeginSection[]
{
  \begin{frame}
    % width of a slide is 128 mm
    \begin{textblock*}{116mm}(6mm,4mm)
      \begin{tikzpicture}[x=1mm,y=1mm]
	\filldraw[fill=white,rounded corners=2mm,very thick]
	  (0,0) rectangle (116,75);
	\draw (58,78) node {};
      \end{tikzpicture}
    \end{textblock*}
    \begin{textblock*}{122mm}(3mm,85mm)
      \begin{minipage}[c]{8mm}
	\includegraphics[width=8mm]{orr-logo.pdf}
      \end{minipage}
      \hfill
      \begin{minipage}[c]{105mm}
	\centering
	{\tiny \insertshorttitle{}
	 \hspace{3mm}---\hspace{3mm}
	 \insertshortauthor{}
	 \hspace{3mm}---\hspace{3mm}
	 \insertframenumber\,/\,\inserttotalframenumber}
      \end{minipage}
      \hfill
      \begin{minipage}[c]{5mm}
	\includegraphics[width=5mm]{gitlogo.pdf}
      \end{minipage}
    \end{textblock*}
    \begin{textblock*}{\textwidth}(10mm,14mm)
      \tableofcontents[currentsection,hideothersubsections]
    \end{textblock*}
  \end{frame}
}

\begin{document}

\lstset{%
  basicstyle=\scriptsize,%
  language=C,%
  identifierstyle=\color{black}\bfseries,%
  keywordstyle=\color{darkgreen}\bfseries,%
  commentstyle=\color{teal},%
  stringstyle=\color{red},
  showstringspaces=false,%
  tabsize=4%
}

\begin{frame}
  % width of a slide is 128 mm
  \begin{textblock*}{116mm}(6mm,6mm)
    \begin{tikzpicture}[x=1mm,y=1mm]
      \filldraw[fill=white,rounded corners=2mm,very thick]
	(0,0) rectangle (116,84);
    \end{tikzpicture}
  \end{textblock*}
  \begin{textblock*}{\textwidth}(10mm,16mm)
    \titlepage
  \end{textblock*}
\end{frame}

\begin{frameframe}{Statistiken: Wer seid ihr?}
  \begin{itemize}
    \item<+-> Wer bezeichnet sich als Programmierer?
    \item<+-> Wer arbeitet an einem OpenSource-Projekt?
    \begin{itemize}
      \item<+-> … mit mehr als 1 Entwickler?
      \item<+-> … mit mehr als 10 Entwicklern?
      \item<+-> … mit mehr als 100 Entwicklern?
      \item<+-> … mit mehr als 1000 Entwicklern?
    \end{itemize}
    \item<+-> Wer hat schon ein Versionsverwaltungssystem (VCS) verwendet?
    \item<+-> Wer hat schon ein zentrales VCS (CVS, SVN, …) verwendet?
    \item<+-> Wer hat schon ein dezentrales VCS (Git, bzr, Mercurial, …)
      verwendet?
    \item<+-> Wer hat schon mit Git gearbeitet?
  \end{itemize}
\end{frameframe}

\section{Grundlagen: Was ist Versionskontrolle?}
\begin{frameframe}{Grundlagen: Was ist Versionskontrolle?}
  \begin{itemize}
    \item technisch gesehen: ein Haufen Dateien mit Meta-Informationen und
      irgendwelchen Beziehungen untereinander \smiley{}

    \vspace{5mm}

    \uncover<2>{
    \item Protokollieren von Änderungen an (Quell-)text
    \item Archivierung mit "`Rücksetz-Operation"'
    \item koordinierter Zugriff
    \item parallele Entwicklungszweige (neue Features, alte Releases)
    }
  \end{itemize}
\end{frameframe}

\begin{frameframe}{Grundlagen: Typen von VCSen}
  \begin{textblock*}{\textwidth}(10mm,30mm)
    \begin{itemize}
      \item lock/modify/write
      \item copy/modify/merge

      \vspace{5mm}

      \uncover<2->{
      \item \alert<2>{lokale Versionierung}
      \item \alert<3>{zentrale Versionierung}
      \item \alert<5>{dezentrale Versionierung}
      }
    \end{itemize}
  \end{textblock*}

  \only<4>{
    \begin{textblock*}{\textwidth}(10mm,20mm)
      \centering
      \begin{tikzpicture}[x=1mm,y=1mm]
	\filldraw[fill=white,color=white] (-52,-27) rectangle (52,27);
	\draw (0,0) node[thin,rounded corners=2mm,draw]
	  (repo) { zentrales Repo };
	\draw (-30, 10) node[rounded corners,fill=yellow,draw]
	  (c0) { Committer 0 };
	\draw (0, 20) node[rounded corners,fill=yellow,draw]
	  (c1) { Committer 1 };
	\draw (30, 10) node[rounded corners,fill=yellow,draw]
	  (c2) { Committer 2 };
	\draw (30, -10) node[rounded corners,fill=yellow,draw]
	  (c3) { Committer 3 };
	\draw (0, -20) node { \LARGE … };
	\draw [->] (c0.south east) -- (repo.north west);
	\draw [->] (c1.south) -- (repo.north);
	\draw [->] (c2.south west) -- (repo.north east);
	\draw [->] (c3.north west) -- (repo.south east);
      \end{tikzpicture}
    \end{textblock*}
  }
\end{frameframe}

\section{Dezentrale Versionskontrolle}
\begin{frameframe}{Workflow in OpenSource Projekten}
  \begin{textblock*}{\textwidth}(10mm,30mm)
    \begin{itemize}
      \item üblicherweise ein/wenige Hauptentwickler/Projektleiter
      \item viele Mitwirkende (versch.\ Umfang/Arbeitsgebiet)
      \item ggf.\ Subsystem-Verantwortliche;\newline
	Entwickler mit mehreren Arbeitsrechnern
      \item ein "`zentraler"'/"`offizielles"' Repository
      \item temporäre und Feature-Branches
    \end{itemize}
  \end{textblock*}

  \only<2>{
    \begin{textblock*}{\textwidth}(10mm,20mm)
      \centering
      \begin{tikzpicture}[x=1mm,y=1mm]
	\filldraw[fill=white,color=white] (-52,-27) rectangle (52,27);
	\draw (0,0) node[thin,rounded corners=2mm,draw]
	  (r0) { Repo 0 };
	\draw (-25, 10) node[rounded corners,fill=yellow,draw]
	  (r1) { Repo 1 };
	\draw (0, 20) node[rounded corners,fill=yellow,draw]
	  (r2) { Repo 2 };
	\draw (-30, 27) node[rounded corners,fill=yellow,draw]
	  (r3) { Repo 3 };
	\draw (30, 10) node[rounded corners,fill=yellow,draw]
	  (r4) { Repo 4 };
	\draw (30, -10) node[rounded corners,fill=yellow,draw]
	  (r5) { Repo 5 };
	\draw (0, -20) node { \LARGE … };
	\draw [<->] (r1.south east) -- (r0.west);
	\draw [<->] (r2.south west) -- (r1.north east);
	\draw [<->] (r3.south) -- (r1.north);
	\draw [<->] (r3.east) -- (r2.north west);
	\draw [<->] (r4.south west) -- (r0.north east);
	\draw [<->] (r5.north west) -- (r0.south east);
	\draw [<->] (r5.north) -- (r4.south);
      \end{tikzpicture}
    \end{textblock*}
  }
\end{frameframe}

\begin{frameframe}{Grundlagen von dezentralen VCSen}
  \begin{itemize}
    \item "`Peer-to-Peer"' Ansatz
    \item jede Arbeitskopie bringt ein komplettes Repository mit (Klon)
    \item gearbeitet wird auf lokalem Repository\newline
      $\Rightarrow$ kein Netzwerk-Zugriff nötig\newline
      $\Rightarrow$ Operationen schnell\newline
      $\Rightarrow$ Offline-Arbeit möglich
    \item automatisches "`Backup"' durch Repository-Klons
    \item Zusammenführen meist auf Basis eines "`Web-of-Trust"'
  \end{itemize}
\end{frameframe}

\begin{frameframe}{Arbeitsweise}
  {
  \vspace*{-5mm}
  \hspace*{10mm}
  \begin{tikzpicture}[x=1mm,y=1mm]
    \node[cylinder,draw,shape border rotate=90,black,%
      minimum width=25mm, minimum height=10mm,%
      cylinder uses custom fill,cylinder end fill=yellow!90,%
      cylinder body fill=yellow!60] at (0,0) {};
    \draw (25, 0) node[anchor=west] { Repository };
    \node[cylinder,draw,shape border rotate=90,black,%
      minimum width=25mm, minimum height=10mm,%
      cylinder uses custom fill,cylinder end fill=orange!90,%
      cylinder body fill=orange!60] at (0,20) {};
    \draw (25, 20) node[anchor=west] { Arbeitskopie };

    \uncover<2,7>{
      \draw[thick,->] (12.5, 5) -- (12.5, 17);
      \draw (15,11) node[anchor=west] { \ttfamily checkout };
    }

    \uncover<3,7>{
      \draw[thick,->] (0,25) .. controls (7,35) and (-7,35) .. (0,25);
      \draw (0, 37.5) node { \ttfamily modify };
    }

    \uncover<4,7>{
      \draw[thick,->] (-12.5, 17) -- (-12.5, 5);
      \draw (-10,11) node[anchor=west] { \ttfamily commit };
    }

    \only<5->{
      \node[cylinder,draw,shape border rotate=90,black,%
	minimum width=25mm, minimum height=10mm,%
	cylinder uses custom fill,cylinder end fill=yellow!90,%
	cylinder body fill=yellow!60] at (0,-20) {};
      \draw (25, -20) node[anchor=west] { anderes Repository };

      \uncover<6>{
	\draw[thick,->] (12.5, -15) -- (12.5, -3);
	\draw (15,-9) node[anchor=west] { \ttfamily fetch };
      }

      \uncover<8>{
	\draw[thick,->] (-12.5, -3) -- (-12.5, -15);
	\draw (-10,-9) node[anchor=west] { \ttfamily push };
      }
    }
  \end{tikzpicture}
  }
\end{frameframe}

% TODO - Datenhaltung in Git (-> Git for Computer Scientists)

\section{Arbeiten mit Git}
\begin{frameframe}{Git: Übersicht}
  \begin{itemize}
    \item \url{http://www.git.or.cz/}
    \item VCS (Version Control System)
    \item 2005 von Linus Torvalds initiiert\newline
      (aktueller Maintainer: Junio C. Hamano)
    \item dezentral
    \item schnell und effizient
    \item kryptographisch gesichert
    \item "`Toolkit design"'
    \item OpenSource (GPLv2)
    \item weit verbreitet im Einsatz (z.B.\ Linux Kernel, Ruby on Rails, Perl,
      WINE, X.org, GNOME, Qt, Debian, …)
  \end{itemize}
\end{frameframe}

\begin{frameframe}{Arbeiten mit Git: Grundlagen}
  \begin{itemize}
    \item $>>$ 100 einzelne Befehle
    \item "`Porcelains"' und "`Plumbing"'
    \item Dokumentation als Manpages - \texttt{git(7)}
    \item \texttt{git help}, \texttt{git $<$command$>$ -h}
    \item Benutzer Handbuch:
      \url{http://www.kernel.org/pub/software/scm/git/docs/user-manual.html}
  \end{itemize}
\end{frameframe}

\begin{frameframe}{Datenhaltung: Git Objektdatenbank}
  \begin{itemize}
    \item DAG (directed acyclic graph)
    \item Objekte identifiziert durch SHA-1 Summe
  \end{itemize}

  \hspace*{15mm}
  \begin{tikzpicture}[x=1mm,y=1mm]
    \draw (0,0) node[thin,rounded corners=2mm,draw]
      (blob) { blob };

    \uncover<2->{
      \draw (0, 20) node[thin,rounded corners=2mm,draw]
	(tree) { tree };
      \draw [->] (tree.south) -- (blob.north);
      \draw (2,10) node[anchor=west] { \footnotesize name, mode };
      \draw [->] (tree.north east) .. controls (10,25) and (10,15)
	.. (tree.south east);
      \draw (10, 20) node[anchor=west] { \footnotesize subdir };
    }

    \uncover<3->{
      \draw (0,40) node[thin,rounded corners=2mm,draw]
	(commit) { commit };
      \draw [->] (commit.south) -- (tree.north);
      \draw [->] (commit.north east) .. controls (15,45) and (15,35)
	.. (commit.south east);
      \draw (15,40) node[anchor=west] { \footnotesize parents };
    }

    \uncover<4->{
      \draw (-20,40) node[thin,draw,fill=yellow]
	(branch) { branch };
      \draw [->] (branch.east) -- (commit.west);
      \draw (-20,30) node[thin,draw,fill=yellow]
	(head) { HEAD };
      \draw[dashed,->] (head.north) -- (branch.south);
    }

    \uncover<5->{
      \draw (-20,10) node[thin,draw,fill=orange]
	(tag) { tag };
      \draw [->] (tag.north east) -- (commit.south west);
      \draw (-20, 3) node { \footnotesize name, message };
    }
  \end{tikzpicture}
\end{frameframe}

\begin{frameframe}{Git konfigurieren}
  \begin{block}{Sich Git vorstellen}
  \begin{itemize}
    \item \texttt{git config --global user.name $<$Dein Name$>$}
    \item \texttt{git config --global user.email $<$du@deine-domain.tld$>$}
    \item $\rightarrow$ Benutzerinformationen für Commit-Metadaten
  \end{itemize}
  \end{block}

  \uncover<2>{
  \begin{block}{Bunt und in Farbe}
  \begin{itemize}
    \item \texttt{git config --global color.ui auto}
    \item $\rightarrow$ farbige \texttt{branch}, \texttt{diff}, \texttt{grep},
      \texttt{status} Ausgaben
  \end{itemize}
  \end{block}
  }
\end{frameframe}

\begin{frameframe}{Repositories erstellen}
  \begin{block}{Neues, leeres Repository}
    \ttfamily
    \footnotesize
    \$ mkdir project\newline
    \$ cd project\newline
    \$ git init\newline
    Initialized empty Git\newline
    repository in .../.git/
  \end{block}

  \vspace{5mm}

  \uncover<2>{
  \begin{block}{Bestehendes Repository "`klonen"'}
    \ttfamily
    \footnotesize
    \$ git clone $<$rep$>$\newline
    ...
  \end{block}
  }
\end{frameframe}

\begin{frameframe}{Änderungen vornehmen}
  \begin{block}{Ändern}
    {\ttfamily
    \footnotesize
    \$ vim foo bar\newline
    \$ git add foo bar
    }

    \begin{itemize}
      \item \texttt{add}, \texttt{rm}, \texttt{mv}
    \end{itemize}
  \end{block}

  \uncover<2>{
  \begin{block}{Geschichte fortführen/ändern}
    {\ttfamily
    \footnotesize
    \$ git commit
    }

    \vspace{5mm}

    {\ttfamily
    \footnotesize
    \$ git reset --hard HEAD\textasciicircum
    }

    \begin{itemize}
      \item \texttt{reset}, \texttt{revert}, \texttt{checkout}
    \end{itemize}
  \end{block}
  }
\end{frameframe}

\begin{frameframe}{Exkurs: Commit Meldungen schreiben}
  \begin{itemize}
    \item Einzeilige, kurze ($<$ 80, optimal $<$ 50 Zeichen)
        Zusammenfassung
    \item Leerzeile
    \item Detaillierte Beschreibung/Erklärung
    \item nicht vorgeschrieben, aber "`common practice"' und von vielen
        Tools erwartet
  \end{itemize}
\end{frameframe}

\begin{frameframe}{Exkurs: Commit Meldungen schreiben}
    \footnotesize
    \begin{verbatim}
git-remote: do not use user input in a printf format string

'git remote show' substituted the remote name into a string that
was later used as a printf format string. If a remote name contains
a printf format specifier like this:

   $ git remote add foo%sbar .

then the command

   $ git remote show foo%sbar

would print garbage (if you are lucky) or crash. This fixes it.
    \end{verbatim}
\end{frameframe}

\begin{frameframe}{Aus der Geschichte lernen}
  \begin{block}{Status der Arbeitskopie}
    \ttfamily
    \footnotesize
    \$ git status\newline
    \$ git diff
  \end{block}

  \uncover<2->{
  \begin{block}{Historie betrachten}
    \ttfamily
    \footnotesize
    \$ git log\newline
    \$ tig
  \end{block}
  }

  \uncover<3->{
  \begin{block}{Objekte betrachten}
    {\ttfamily
    \footnotesize
    \$ git show\newline
    \$ git show HEAD:foo
    }

    \begin{itemize}
      \item Commits, Trees, Blobs, Tags
    \end{itemize}
  \end{block}
  }
\end{frameframe}

\begin{frameframe}{Tags}
  {\ttfamily
  \footnotesize
  \$ git tag -m ``$<$Beschreibung$>$'' $<$Name$>$ $<$Commit$>$\newline
  \$ git tag -l
  }

  \vspace{5mm}

  \begin{itemize}
    \item "`Zeiger"' auf einen Commit\newline
      optional mit Metadaten ("'annotated tag"')
    \item Kennzeichnung von bestimmten Entwicklungsständen (insb.\ Releases)
    \item "`annotated tag"': Autor, Datum, Beschreibung, optional GnuPG
      Signatur
  \end{itemize}
\end{frameframe}

\begin{frameframe}{Branching und Merging}
  \begin{itemize}
    \item Branch: "`automatischer"' Zeiger auf eine Reihe von Commits
    \item \texttt{HEAD}: Zeiger auf den aktuellen Branch
    \item \texttt{master}: "`Standard"'-Branch
    \item Merge: Zusammenführen von zwei Entwicklungssträngen
  \end{itemize}

  \begin{block}{Branch erzeugen}
    \ttfamily
    \footnotesize
    \$ git checkout -b $<$Name$>$

    \vspace{5mm}

    \uncover<2>{
    \$ git branch\newline
    \hspace*{1em}master\newline
    * new-branch
    }
  \end{block}
\end{frameframe}

\begin{frameframe}{Branching und Merging}
  \begin{block}{Branches zusammenführen}
    \ttfamily
    \footnotesize
    \$ git merge master\newline
    \$ git rebase master
  \end{block}

  \uncover<2>{
  \begin{block}{Konflikte auflösen}
    \begin{itemize}
      \item Konflikte entstehen, wenn die gleiche Stelle unterschiedlich
	geändert wurde\newline
	$\Rightarrow$ manuelles Eingreifen nötig
      \item Commit-Erzeugung wird unterbrochen
      \item Konfliktanzeiger in den betroffenen Dateien
      \item manuelle Entscheidung, wie beide Änderungen zusammengeführt werden
    \end{itemize}
  \end{block}
  }
\end{frameframe}

\begin{frameframe}{Arbeiten mit anderen Repositories}
  \begin{block}{Repository klonen}
    \ttfamily
    \footnotesize
    \$ git clone <rep>
  \end{block}

  \begin{block}{Austauschen von Änderungen}
    {\ttfamily
    \footnotesize
    \$ git pull\newline
    \$ git push
    }

    \vspace{5mm}

    Alternativ:
    \begin{itemize}
      \item \texttt{git format-patch}, \texttt{git send-mail}
    \end{itemize}
  \end{block}
\end{frameframe}

\begin{frameframe}{Arbeiten mit anderen Repositories}
  \begin{itemize}
    \item "`remote"': Repository, dessen Änderungen verfolgt werden
    \item "`remote branch"': Branch, welcher der Zustand in einem anderen
      Repository wiederspiegelt
    \item technisch: Branch in einem anderen Namensraum mit anderer Semantik
  \end{itemize}

  \vspace{5mm}

  \begin{block}{Arbeiten mit "`remotes"'}
    \ttfamily
    \footnotesize
    \$ git remote add $<$Name$>$ URL\newline
    \$ git remote update $<$Name$>$
  \end{block}
\end{frameframe}

\begin{frameframe}{Repository URLs}
  \begin{itemize}
    \item lokal: \texttt{/path/to/repository/}
    \item http: \texttt{http://domain.tld/repository.git}
    \item git: \texttt{git://domain.tld/repository.git}
    \item ssh: \texttt{domain.tld:path/to/repository/}
  \end{itemize}
\end{frameframe}

\begin{frameframe}{Frontends}
  \begin{itemize}
    \item \texttt{tig} (ncurses)
    \item \texttt{gitk} (Tk, read-only)
    \item \texttt{qgit} (Qt)
    \item \texttt{magit} (emacs)
  \end{itemize}
\end{frameframe}

\begin{frameframe}{Goodies}
  \begin{itemize}
    \item<+-> \texttt{git reflog}
    \item<+-> \texttt{git rebase -i}
    \item<+-> \texttt{git commit --amend}
    \item<+-> \texttt{git add -p}
    \item<+-> \texttt{git stash}
    \item<+-> \texttt{git bisect}
    \item<+-> \texttt{git cherry} / \texttt{git-wtf}
    \item<+-> \texttt{git diff color-words}
    \item<+-> \texttt{git svn}
  \end{itemize}
\end{frameframe}

\begin{frameframe}{\insertshorttitle{}}
  \begin{center}
    Vielen Dank für die Aufmerksamkeit!

    \vspace{10mm}

    {\Large Gibt es Fragen?}

    \vspace{10mm}

    Kontakt:\\
    Sebastian "`tokkee"' Harl\\
    $<$tokkee@debian.org$>$
  \end{center}
\end{frameframe}

\end{document}

% vim: set shiftwidth=2 softtabstop=2 tabstop=8 spelllang=de_de :
