% Für die Nutzungsbedingungen siehe die Folie am Ende des Vortrags.
% © Jörg Sommer 2007
%
% Powerdot creates the .bm file and it's important to watch on it.
% rubber: clean $base.bm $base.vrb
% rubber: watch $base.bm $base.toc

\RequirePackage[english,ngerman]{babel}
\PassOptionsToPackage{draft=false,breaklinks}{hyperref}

\documentclass[mode=present,style=fyma,english,ngerman]{powerdot}
  % mode=present: generate a presentation
  % mode=handout: generate a handout (no visual effect)
  % mode=print: generate a document for printing with the slides
  % nopagebreak: allow more than two slides per page on handout
  % display=slidesnotes: include slides + notes in output
  % display=slides: output only slides
  % display=notes: output only notes
  % clock: insert a clock on slides
  % style: the layout style

\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{fixltx2e}
\usepackage[draft=false]{microtype}
\usepackage{fancyvrb}
\usepackage{dingbat}
\usepackage{pst-ob3d}
\usepackage{textcomp}
\usepackage[weather]{ifsym}
\usepackage[intlimits,leqno]{amsmath}

\pdsetup{lf={-- Erstellt mit Jörg's\LaTeX{}mode -- Schriftsatz und Effekte
  von powerdot und \LaTeX{} --},list={itemsep=1em}}

% alle Verbatim mit kleiner Schrift
\fvset{fontsize=\footnotesize}

\newcommand*{\todo}[1]{\textcolor{red}{todo: #1}}
\newcommand*{\vrbcomment}[1]{\textnormal{\bfseries#1}}
\newcommand*{\vrblinecomment}[1]{\hfill\ensuremath{\leftarrow} \vrbcomment{#1}}

\begin{document}

\title{Versionsverwaltungssysteme und eine Einführung in GIT}
\author{Jörg Sommer
  \href{mailto:joerg@alea.gnuu.de}{\nolinkurl{<joerg@alea.gnuu.de>}}\\
  \url{http://www.lug-jena.de/veranstaltungen/\jobname.pdf}}
\date{2007-12-06}

\maketitle

\section[toc=Versionsverwaltung]{Worum geht's bei Versionsverwaltung?}

\begin{slide}[toc={Die Ziele}]{Was soll eine Versionsverwaltung leisten?}
  \begin{itemize}[itemsep=0em]
   \item unabhängig vom normalen Arbeitsablauf, d.\,h. abgesehen von der
    Versionierung arbeitet man wie immer
   \item einfaches Archivieren der Historie und einfacher Zugriff darauf
    \pause
   \item Gemeinschaftsarbeit mehrerer Benutzer fördern:
    \begin{itemize}[itemsep=0em,topsep=0em]
     \item Verteilung von Daten/""Publizieren von Änderungen
     \item Zusammenführen von gemeinsamen Änderungen
     \item Behandlung von Konflikten (=~unterschiedl. Änderungen am selben
      Obj.) $\rightarrow$ vorher Sperren o. Auflösen von Hand
     \item Zugriffskontrolle
    \end{itemize}
    \pause
   \item Zusätze:
    \begin{itemize}[itemsep=0em,topsep=0em]
     \item Automatisierung (Hooks): Qualitätssicherung (autom. Prüfung von
      Standards), autom. Übersetzen von Programmen, Meldungen an
      Mailinglisten/""BTS, Aktualisierung von Web"~Seiten, \ldots{}
     \item Integritätssicherung (Signierung)
     \item Code"=Review
    \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}{Archivierung für Arme}
  \begin{enumerate}
   \item \texttt{cp datei /var/backups/datei-\$(date)}
   \item \texttt{editor datei}
   \item uups, da war was falsch:\\
    \texttt{cp /var/backups/datei-\$(date) datei}
   \item was haben wir damals geändert:\\
    \texttt{diff datei-1 datei-2}
  \end{enumerate}
  \pause
  \bigskip
  \begin{center}
    \Large \emph{einfach ist was anderes}
  \end{center}
\end{slide}

\begin{slide}[toc=Probleme]{Das reicht nicht}
  \begin{itemize}
   \item Dokumentation/""Metainformationen der Änderung (warum haben wir das
    geändert) nicht vorhanden/""müsste gesondert gepflegt werden
   \item Änderungen an mehreren Dateien lassen sich damit schlecht archivieren
   \item Gemeinschaftsarbeit wird überhaupt nicht unterstützt;
    unterschiedlichen Suffix für jeden, keine Änderungen an einer Datei zur
    gleichen Zeit
  \end{itemize}
  \pause
  \bigskip
  \begin{center}
    \Large \emph{\texttt{cp} und \texttt{diff} sind keine Lösung}
  \end{center}
\end{slide}

\begin{slide}[toc=Systeme]{Welche Systeme gibt es?}
  beispielhaft einige Versionsverwaltungssysteme~\cite{cmp-vcs}:
  \begin{itemize}[itemsep=0.1em]
   \item \href{http://www.gnu.org/software/rcs/rcs.html}
    {Revision Control System (RCS)}~\cite{rcs}
    -- einfaches System zur Verwaltung von \emph{einzelnen} Dateien, Anfang
    der 1980er

   \item \href{http://www.nongnu.org/cvs/}{Concurrent Versions System
    (CVS)}~\cite{cvs} -- Server/""Client"=System, C, von 1986

   \item \href{http://subversion.tigris.org}{Subversion (SVN)}~\cite{svn}
    -- Weiterentwicklung von CVS, C, von 2000

   \item \href{http://svk.elixus.org/}{SVK}~\cite{svk}
    -- Erweiterung von Subversion um Offline-Fähigkeit, Perl, von 2003

   \item \href{http://git.or.cz/}{GIT}~\cite{git}
    -- entstanden bei der Linux-Kernel-Entwicklung, Shell und C, von 2005

   % \item BitKeeper~\cite{bitkeeper} -- kommerzielles, propritäres System

   \item \href{http://www.bazaar-vcs.org/}{Bazaar (bzr)}~\cite{bzr}
    -- entwickelt von Canonical Ltd. (Ubuntu), Python, von 2005

   \item \href{http://www.selenic.com/mercurial/}{Mercurial}~\cite{mercu}
    -- Parallelentwicklung von Git, Python und C, von 2005

   % \item darcs~\cite{darcs} -- Haskel, von 2003

   \item \ldots{}
  \end{itemize}
\end{slide}

\section{SVN}

\begin{slide}{Aufbau}
  \begin{center}
    \begin{pspicture}(-0.3,-0.2)(6,2)
      \psset{OnlyVisibleFaces=true,linewidth=0.2pt,fillstyle=solid,%
        viewpoint=1 -4 1,linecolor=black}
      \rput(2.6,1.2){
        \rput(0,0){\PstCube[fillcolor=white]{.6}{.6}{.2}}
        \rput(0,0.2){\PstCube[fillcolor=white]{.6}{.6}{.2}}
        \rput(0,0.4){\PstCube[fillcolor=white]{.6}{.6}{.2}}
        \rput[l](0.3,0.9){Server}
      }

      \newcommand*{\PstObjectsThreeDFaceA}{\rput(.3,.1){\tiny HEAD}}
      \rput(2.6,1.8){\PstCube[fillcolor=red]{.6}{.6}{.2}}
      \rput[t](-.2,0.05){Client~1}
        \rput(0,0.2){\PstCube[fillcolor=red]{.6}{.6}{.2}}
      \rput[t](2.2,-0.15){Client~2}
        \rput(2.4,0){\PstCube[fillcolor=red]{.6}{.6}{.2}}
      \rput[t](4.6,0.05){Client~3}
        \rput(4.8,0.2){\PstCube[fillcolor=red]{.6}{.6}{.2}}

      \onslide*{2}{
        \psset{linewidth=0.4pt,arrowsize=2pt 2}
        \psline{->}(0,.6)(2,1.5)
        \rput[l](.5,.7){\footnotesize commit}
        \psline{<-}(-.3,.6)(2,1.7)
        \rput[r](1,1.4){\footnotesize update}

        \psline{<-}(2.1,.4)(2.2,1.1)
        \psline{->}(2.4,.4)(2.5,1.1)
        \psline{<-}(4.5,.6)(2.8,1.5)
        \psline{->}(4.8,.6)(2.8,1.7)
      }
    \end{pspicture}
  \end{center}

  \begin{itemize}
   \item zentraler Server mit vollständiger Historie und Metainformationen%
   \item Clients mit Kopie des aktuellen Zustands (HEAD)\pause
   \item Client \ldots{}
    \begin{itemize}
     \item bezieht aktuellen Zustand vom Server (update)
     \item arbeitet lokal (ohne Verbindung zum Server)
     \item überträgt seine Änderungen zum Server (commit)
    \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}{Arbeiten mit SVN}
  \renewcommand*{\descriptionlabel}[1]{%
    \hspace\labelsep\normalfont\bfseries svn #1:}
  \begin{description}[itemsep=0.2em]
   \item[checkout] initiales Kopieren des aktuellen Zustands vom Server

   \item[add, rm, mkdir] hinzufügen, entfernen von
    Dateien/""Verzeichnissen zur Verwaltung

   \item[cp, mv] Kopieren/""Umbenennen von Objekten

   \item[status, diff] Zustand und Änderungen an der Kopie anzeigen

   \item[commit] Änderungen zum Server übertragen
    --~dabei wird eine Beschreibung abgefragt

   \item[update] Kopie aktualisieren/""Änderungen der Anderen von Server holen

   \item[prop{\large\textasteriskcentered{}}] Bearbeiten von Metainformationen wie
    Dateityp, Ausführbarkeit, Zeilenendezeichen, \ldots{}

   \item[lock, unlock] Sperren/""Freigeben von Objekten

   \item[merge] Einarbeiten von Änderungen aus anderen SVN"~Archiven;
    =~\texttt{svn diff | patch -p} mit \texttt{svn add}
  \end{description}
\end{slide}

\begin{slide}[method=direct,toc={Zugriff auf die Historie}]{Zugriff auf die Historie (1)}
  \renewcommand*{\descriptionlabel}[1]{%
    \hspace\labelsep\normalfont\bfseries svn #1:}
  \begin{description}
   \item[log] Beschreibungen der vorangegangenen Änderungen anzeigen
    \begin{Verbatim}[gobble=4]
    % svn log -r1199:HEAD
    ----------------------------------------------------
    r1199 | joergs | 2007-11-15 22:02:40 [...] | 2 lines

    Rechtschreibfehler in der Erklärung von Authori[...]
    -----------------------------------------------------
    r1200 | joergs | 2007-11-15 22:03:27 [...] | 2 lines

    Hinweis zur Lösung des Problems mit dem [...]
    -----------------------------------------------------
    r1201 | kubijens | 2007-11-16 16:23:29 [...] | 1 line

    - Vorlesung vom 2007-11-16
    -----------------------------------------------------
    \end{Verbatim}
  \end{description}
\end{slide}

\begin{slide}[method=direct,toc=]{Zugriff auf die Historie (2)}
  \renewcommand*{\descriptionlabel}[1]{%
    \hspace\labelsep\normalfont\bfseries svn #1:}
  \begin{description}
   \item[blame] Versionsnummer der letzten Änderung für jede Zeile einer Datei
    anzeigen
    \begin{Verbatim}[gobble=4]
    % svn blame statistik
     446   joergs BEGIN
     446   joergs {
    1098   joergs     # Um Bots zu bestimmen:
    1098   joergs     #  sed '/^From /,/^$/d; /skripte[...]
    1098   joergs     #      old-logs | sort -u
    1098   joergs
    1098   joergs     # alle Bots, die am Anfang ihre [...]
    1198   joergs     $bots_beg=qr/(Exa|Google|IRL|MJ1[...]
    [...]
     446   joergs     }
     472   joergs     our (%PDF_ACCESS, %PDF_UNI_ACCES[...]
     557   joergs     our (%PS_ACCESS, %PS_UNI_ACCESS,[...]
     557   joergs     our (%TGZ_ACCESS, %TGZ_UNI_ACCES[...]
     446   joergs }
    \end{Verbatim}
  \end{description}
\end{slide}

\begin{slide}[toc=Konflikte,method=file]{Behandlung von Konflikten}
  \begin{Verbatim}[gobble=2,commandchars]
  % svn update
  C      changelog
  % svn status
  C      changelog
  ?      changelog.r292
  ?      changelog.mine
  ?      changelog.r312
  % cat changelog
  <<<<<<< .mine
  * ich will es so \vrblinecomment{lokale Änderung}
  =======
  * ich will es anders \vrblinecomment{zwischenzeitl. Änderung auf dem Server}
  >>>>>>> .r312 \pause
  % editor changelog \vrblinecomment{Benutzer muss Konflikt selbst auflösen}
  % svn \vrbcomment{resolved} changelog
  Konflikt von »changelog« aufgelöst
  % ls changelog*
  changelog
  \end{Verbatim}
\end{slide}

\begin{slide}[toc=CVS-Nachfolger]{SVN als Nachfolger von CVS}
  \begin{itemize}
   \item häufige Operationen können ohne Verbindung zum Server durchgeführt
    werden: diff, status, info
   \item Hooks wurden eingeführt
   \item Code"=Verzweigungen (Branches) und Markierungen (Tags) wurden
    vereinfacht -- \textsl{Zweige und Markierungen kommen später
    nochmal genauer}
   \item bessere Unterstützung für Symlinks und Binärdateien
   \item Unterstützung von Umbenennen und Verschieben von Objekten
  \end{itemize}
\end{slide}

\begin{slide}{Bewertung}
  \begin{itemize}[itemsep=0em,topsep=0em]
   \item[\Sun] unabhängig vom normalen Arbeitsablauf
   \item[\Sun] einfaches Archivieren der Historie und einfacher Zugriff darauf
    \pause
   \item[\SunCloud] Gemeinschaftsarbeit mehrerer Benutzer fördern:
    \begin{itemize}[itemsep=0em,topsep=0em]
     \item[\Sun] Verteilung von Daten/""Publizieren von Änderungen
     \item[\Cloud] Zusammenführen von gemeinsamen Änderungen -- kein
      sinnvolles Eingliedern von Zweigen/""Patch"=Sammlungen; mit merge geht
      Historie verloren
     \item[\Sun] Behandlung von Konflikten
     \item[\Sun] Zugriffskontrolle -- über Hooks möglich
    \end{itemize}
    \pause
   \item[\WeakRainCloud] Zusätze:
    \begin{itemize}[itemsep=0em,topsep=0em]
     \item[\Sun] Automatisierung (Hooks)
     \item[\RainCloud] Integritätssicherung (Signierung)
     \item[\RainCloud] Code"=Review
    \end{itemize}
    \pause
   \item[\Sun{}] kann beliebige Metainformationen für Objekte speichern
   \item[\RainCloud] keine Manpages
   \item[\Cloud] Verbindung zu Server für einige Befehle noch notwendig
  \end{itemize}
\end{slide}

\section{SVK}

\begin{slide}[toc={Änderungen zu SVN},bm={Was kann SVK anderes?}]{Was kann
  SVK anderes? \cite{svk-lnx-mag}\cite{svk-tutorial}\cite{svk-vortrag}}
  \begin{itemize}
   \item Erweiterung von SVN für Offline-Fähigkeit
    \begin{center}
      \begin{pspicture}(-0.3,-0.5)(6.5,2.2)
        \psset{OnlyVisibleFaces=true,linewidth=0.2pt,fillstyle=solid,%
          viewpoint=1 -4 1,linecolor=black}
        \rput(5.6,1.2){
          \rput(0,0){\PstCube[fillcolor=white]{.6}{.6}{.2}}
          \rput(0,0.2){\PstCube[fillcolor=white]{.6}{.6}{.2}}
          \rput(0,0.4){\PstCube[fillcolor=white]{.6}{.6}{.2}}
          \newcommand*{\PstObjectsThreeDFaceA}{\rput(.3,.1){\tiny HEAD}}
          \rput(0,0.6){\PstCube[fillcolor=red]{.6}{.6}{.2}}
          \rput[l](0.3,0.9){Server}
        }

        \rput(3.8,0.6){
          \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(0,0)(1.4,0.5)
          \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(0,0.4)(1.1,0.7)
          \rput[l](.7,.1){\footnotesize sync}
          \rput[r](.9,.8){\footnotesize commit}
        }

        \rput(3.6,0.4){
          \rput(0,0){\PstCube[fillcolor=white]{.6}{.6}{.2}}
          \rput(0,0.2){\PstCube[fillcolor=white]{.6}{.6}{.2}}
          \rput(0,0.4){\PstCube[fillcolor=white]{.6}{.6}{.2}}
          \newcommand*{\PstObjectsThreeDFaceA}{\rput(.3,.1){\tiny HEAD}}
          \rput(0,0.6){\PstCube[fillcolor=red]{.6}{.6}{.2}}
        }

        \rput[b](2.4,.9){\footnotesize smerge}
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(1.8,0.8)(2.9,0.8)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(1.8,1.7)(4.9,1.8)
        \rput[b](3.6,1.85){\footnotesize push}

        \rput(1.6,0.4){
          \rput(0,0){\PstCube[fillcolor=white]{.6}{.6}{.2}}
          \rput(0,0.2){\PstCube[fillcolor=white]{.6}{.6}{.2}}
          \rput(0,0.4){\PstCube[fillcolor=white]{.6}{.6}{.2}}
          \rput(0,0.6){\PstCube[fillcolor=red]{.6}{.6}{.2}}
          \psset{linestyle=dashed,dash=2pt 3pt}
          \rput(0,0.8){\PstCube[fillcolor=teal]{.6}{.6}{.2}}
          \rput(0,1){\PstCube[fillcolor=teal]{.6}{.6}{.2}}
          \newcommand*{\PstObjectsThreeDFaceA}{\rput(.3,.1){\tiny HEAD}}
          \rput(0,1.2){\PstCube[fillcolor=lime]{.6}{.6}{.2}}
        }

        \rput[l](.2,.3){\footnotesize update}
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(0.1,0.6)(1,1)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(-.3,0.6)(1,1.3)
        \rput[r](.5,1.2){\footnotesize commit}

        \newcommand*{\PstObjectsThreeDFaceA}{\rput(.3,.1){\tiny HEAD}}
        \rput(0.05,0.2){\PstCube[fillcolor=lime]{.6}{.6}{.2}}

        \psellipse[fillstyle=none,linestyle=dashed](1.6,0.8)(2.4,1.35)
        \rput[r](3,-0.1){Client}
      \end{pspicture}
    \end{center}

    Benutzer hat komplette Kopie vom Server, erstellt davon lokal weitere
    Kopie, benutzt diese als "`Server"' für Arbeitskopie
    \pause

   \item kann patch-Sets verwalten
   \item Signatur von Änderungen (Commits)
   \item vor Version 2.0 konnte SVK auch mit CVS und P4 arbeiten
  \end{itemize}
\end{slide}

\begin{slide}[method=file,toc={Arbeiten mit SVK}]{Arbeiten mit SVK (1)}
  \begin{Verbatim}[gobble=2,commandchars]
  % svk depotmap --init
  Repository /home/joerg/.svk/local does not exist, create?[...]

  % svk mirror https://svn.lug-jena.de/repos/[...] //mirror/lug
  [...]initialized. Run svk sync //mirror/lug to start mirroring

  % svk mirror --list
  Path           Source
  =============================================================
  //mirror/lug   https://svn.lug-jena.de/repos/[...] \pause{}

  % svk sync //mirror/lug \vrblinecomment{Spiegel aktualisieren}

  % svk co //mirror/lug lug-www \vrblinecomment{Arbeitskopie erstellen}
  Syncing //mirror/lug(/mirror/lug) in [...]/lug-www to 396.
  A   lug-www/python
  A   lug-www/python/lugjena
  A   lug-www/python/lugjena/stammtisch.py
  ...
  \end{Verbatim}
\end{slide}

\begin{slide}[method=file,toc=]{Arbeiten mit SVK (2)}
  Direkt mit SVK auf dem Spiegel eines Archivs zu arbeiten, bringt keinen
  Vorteil, da jeder Commit direkt zum SVN"~Archiv übertragen wird.

  \begin{Verbatim}[gobble=2,commandchars]
  % svk cp //mirror/lug //local/lug \vrblinecomment{lokalen Zweig anlegen}
  \pause{}
  \vrbcomment{Mit dem lokalen Zweig arbeiten:}
  % svk checkout //local/lug
  % svk commit \vrblinecomment{Änderungen zum Spiegel übertragen}
  % svk update \vrblinecomment{vom Spiegel in die Arbeitskopie}
  % svk pull \vrblinecomment{Änderungen vom Ursprungsserver holen}
  % svk push \vrbcomment{oder} smerge \vrblinecomment{Änd. zum Ursprungsserver übertragen}
  \end{Verbatim}
\end{slide}

\begin{slide}{Bewertung}
  \begin{itemize}[itemsep=0.5em]
   \item[\Sun] positive Eigenschaften von SVN bleiben
   \item[\Sun] Integritätssicherung (Signierung)
   \item[\Sun] Verbindung zum Server nur für Veröffentlichung notwendig
   \item[\Sun] kann Patch"=Sammlungen verwalten; sinnvolles Eingliedern von
    Zweigen (zerstört nicht die Historie)
   \item[\Cloud] Code"=Review über Austausch von Patches möglich
   \item[\RainCloud] keine Manpages
    \pause
   \item[\Sun{}] legt eigene Daten in \texttt{\$HOME} ab, keine \texttt{.svk}
    im Arbeitsverz.
   \item[\SunCloud{}] funktioniert nur noch mit SVN
   \item[\WeakRainCloud] man muss kopieren, bevor man offline arbeiten kann
   \item[\RainCloud] grottenlangsam
  \end{itemize}
\end{slide}

\section[toc={Verteilte VCS}]{Verteilte Versionsverwaltungssysteme}

\begin{slide}[toc={Unabhängigkeit}]{Auf dem Weg in die Unabhängigkeit}
  \begin{center}
    \begin{pspicture}(0,0)(9.5,4)
      \psset{OnlyVisibleFaces=true,linewidth=0.2pt,fillstyle=solid,%
        viewpoint=1 -4 1,linecolor=black}
      \newcommand*{\Schicht}[2][]{%
        \newcommand*{\PstObjectsThreeDFaceA}{\rput(.3,.1){\tiny #1}}
        \PstCube[fillcolor=#2]{.6}{.6}{.2}
      }
      \newcommand*{\ServerStapel}{
        \rput(0,0){\Schicht{white}}
        \rput(0,0.2){\Schicht{white}}
        \rput(0,0.4){\Schicht[HEAD]{red}}
      }

      \onslide{1,2}{
        \rput(4.6,3.4){
          \ServerStapel
          \rput[l](0.3,0.7){Server}
        }
      }

      \rput(0.8,0.6){
        \rput[l](0.2,0.1){Client~1}
        \onslide*{1}{\rput(0,0.4){\Schicht[HEAD]{red}}}
        \onslide*{2}{
          \rput(0,0.4){\Schicht[HEAD]{lime}}
          \rput(2,0.4){\ServerStapel}
        }
        \onslide*{2,3}{
          \rput(1,0.4){
            \rput(0,0){\Schicht{white}}
            \rput(0,0.2){\Schicht{white}}
            \rput(0,0.4){\Schicht{red}}
            \rput(0,0.6){\Schicht{teal}}
            \rput(0,0.8){\Schicht{teal}}
            \rput(0,1){\Schicht[HEAD]{lime}}
          }
        }
      }

      \onslide*{1}{
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(0.4,1.4)(3.9,3.8)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(0.7,1.4)(3.9,3.6)
      }
      \onslide*{2}{
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(0.4,1.4)(1.1,2)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(0.7,1.4)(1.1,1.7)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(1.6,2.4)(3.9,3.9)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(1.9,1.4)(2.15,1.4)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(2.4,1.8)(3.9,3.7)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(2.7,1.8)(3.9,3.5)
      }
      \onslide*{2,3}{
        \pscurve[linewidth=0.4pt,arrowsize=2pt 2,fillstyle=none,linestyle=dashed]{->}%
          (1.4,2.4)(4.5,3.3)(8.3,2.2)
      }
      \onslide*{3}{
        \pscurve[linewidth=0.4pt,arrowsize=2pt 2,fillstyle=none,linestyle=dashed]{<-}%
          (1.7,2.4)(4.5,3.1)(8,2.2)
      }

      \rput(4,0){
        \rput[l](0.2,0.1){Client~2}
        \onslide*{1,2}{\rput(0,0.4){\Schicht[HEAD]{red}}}
        \onslide*{2}{\rput(2,0.4){\ServerStapel}}
        \onslide*{2,3}{
          \rput(1,0.4){
            \rput(0,0){\Schicht{white}}
            \rput(0,0.2){\Schicht{white}}
            \rput(0,0.4){\Schicht[HEAD]{red}}
          }
        }
      }

      \onslide*{1}{
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(3.6,0.8)(4.1,3.3)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(3.9,0.8)(4.4,3.3)
      }
      \onslide*{2}{
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(3.6,0.8)(4.3,1)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(4,0.8)(4.3,0.85)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(4.7,1.2)(4.1,3.4)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(5.1,0.8)(5.35,0.8)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(5.6,1.2)(4.3,3.3)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(5.9,1.2)(4.4,3.3)
      }
      \onslide*{2,3}{
        \pscurve[linewidth=0.4pt,arrowsize=2pt 2,fillstyle=none,linestyle=dashed]{->}%
          (1.9,1.9)(3.1,2)(4.7,1.2)
      }
      \onslide*{3}{
        \pscurve[linewidth=0.4pt,arrowsize=2pt 2,fillstyle=none,linestyle=dashed]{<-}%
          (1.9,1.7)(3,1.8)(4.5,1.2)
      }

      \rput(7.4,0.6){
        \rput[l](0.2,0.1){Client~3}
        \onslide*{1}{\rput(0,0.4){\Schicht[HEAD]{red}}}
        \onslide*{2}{
          \rput(2,0.4){\ServerStapel}
          \rput(0,0.4){\Schicht[HEAD]{pink}}
        }
        \onslide*{2,3}{
          \rput(1,0.4){
            \rput(0,0){\Schicht{white}}
            \rput(0,0.2){\Schicht{white}}
            \rput(0,0.4){\Schicht{red}}
            \rput(0,0.6){\Schicht{orange}}
            \rput(0,0.8){\Schicht[HEAD]{pink}}
          }
        }
      }

      \onslide*{1}{
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(7,1.4)(4.6,3.6)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(7.3,1.4)(4.6,3.8)
      }
      \onslide*{2}{
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(7,1.4)(7.7,1.9)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(7.3,1.4)(7.7,1.7)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{->}(8,2.2)(4.8,3.5)
        \psline[linewidth=0.4pt,arrowsize=2pt 2]{<-}(8.5,1.4)(8.75,1.4)
        \pscurve[linewidth=0.4pt,arrowsize=2pt 2,fillstyle=none]{->}%
          (9,1.8)(8.4,2.3)(4.8,3.7)
        \pscurve[linewidth=0.4pt,arrowsize=2pt 2,fillstyle=none]{<-}%
          (9.3,1.8)(8.4,2.5)(4.8,3.9)
      }
      \onslide*{2,3}{
        \pscurve[linewidth=0.4pt,arrowsize=2pt 2,fillstyle=none,linestyle=dashed]{->}%
          (4.8,1.2)(5.8,1.9)(7.7,2.1)
      }
      \onslide*{3}{
        \pscurve[linewidth=0.4pt,arrowsize=2pt 2,fillstyle=none,linestyle=dashed]{<-}%
          (5,1.2)(6,1.8)(7.7,2)
      }
    \end{pspicture}
    % PSTricks stellt die ursprüngliche Einstellung für die Farbe nicht wieder
    % her.
    \color[rgb]{.14,.34,.55}
    \LARGE
    \onslide*{1}{SVN}
    \onslide*{2}{SVK}
    \onslide*{3}{GIT}\\
    \normalsize
    \begin{itemize}
     \item \onslide*{1,2}{Server/""Client"=System (zentral)}
      \onslide*{2}{+ Nebenkanäle} \onslide*{3}{verteiltes System (dezentral)}
     \item Clients verfügen \onslide*{1}{nur über einen Teil
      der}\onslide*{2,3}{über alle} Informationen
     \item<2,3> Clients können \onslide*{2}{sich}\onslide*{3}{nur}
      untereinander über Patches
      \onslide*{2}{austauschen}\onslide*{3}{kommunizieren}
    \end{itemize}
  \end{center}
\end{slide}

\begin{slide}[toc={Verteilte VCS}]{Verteilte Versionsverwaltungssysteme}
  \begin{itemize}
   \item es gibt keinen Server (Single Point of Failure), alle Clients sind
    \emph{unabhängig}, \emph{gleichwertig} und \emph{voll einsatzbereit}
    (sollte die Verbindung zum Server fehlen)

   \item ein Client sollte Ton angeben/""Original verwalten --~aber rein
    technisch ist er nur Client, Auszeichnung rein logisch
    \pause

   \item unidirektionale Kommunikation: jeder Client bestimmt selbst, was in
    seinem Archiv liegt, \emph{holt} Änderungen von anderen Cl.

   \item daraus ergibt sich \emph{anderer Arbeitsablauf}:
    \vspace{-1ex}
    \begin{enumerate}
     \item Entwickler arbeiten lokal mit ihrem Archiv
     \item Entwickler stellen ihre Änderungen z.\,B. auf einer Mailingliste
      zur Diskussion $\Rightarrow$ Code"=Review
     \item wenn i.\,O. übernimmt Verwalter sie ins Original
    \end{enumerate}
  \end{itemize}
\end{slide}

\begin{slide}{Ein Commit \ldots{}}
  \begin{itemize}[itemsep=0.5em]
   \item \ldots{} ist eine Momentaufnahme/""ein Zustand des Archivs

   \item \ldots{} sollte das Archiv von einem \emph{konsistenten} Zustand
    (Programm kompiliert) in neuen \emph{konsistenten} Zustand überführen

   \item \ldots{} sollte \emph{eine} logische Änderung umfassen
    \begin{itemize}[itemsep=0.5em]
     \item problematisch mit servergebundenen Systemen; wenn Leitung weg, dann
      ruht die Arbeit
     \item schwierig zu sagen, was kleinste logische Einheit ist --~in
      \LaTeX{}, bei einer Grafik
    \end{itemize}

   \item \ldots{} ist eine Zusammenfassung aus Änderung, (sinnvolle)
    Beschreibung der Änderung, Informationen über den Autor, Zeitpunkt,
    Signatur usw.

   \item \ldots{} kann einen Name/""Kennzeichnung (Tag) haben: v2.6.23,
    alpha1, Ausgabe2007
  \end{itemize}
\end{slide}

\begin{slide}[toc=Verzweigungen]{Verzweigungen (Branches)}
  \begin{itemize}
   \item existiert auch in Server/""Client"~VCS

   \item Idee: logisch abgeschlossene Aufgabenteile werden auf Kopien des
    Projekts erarbeitet; ist die Arbeit abgeschlossen, wird die Einheit
    komplett in den Hauptzweig übernommen

    \begin{center}
      \begin{pspicture}(0,0)(6,1.3)
        \newcommand*{\commit}{\psline(0,0.1)(0.4,0.1)\pscircle(0.5,0.1){0.1}}
        \pscircle(0.1,0.1){0.1}
        \rput(0.2,0){\commit}
        \rput(0.8,0){\commit}
        \rput(1.4,0){\psline(-0.1,0.2)(0.1,0.5)(0.4,0.5)\pscircle(0.5,0.5){0.1}}
          \rput(2,0.4){\commit}
          \rput(2.6,0.4){\psline(-0.1,0.2)(0.1,0.5)(0.4,0.5)
            \pscircle(0.5,0.5){0.1}}
          \rput(2.6,0.4){\commit}
          \rput(3.2,0.4){\commit}
          \rput(3.8,0.4){\commit}
        \rput(1.4,0){\psline(-0.1,0.2)(0.1,1.3)(0.4,1.3)\pscircle(0.5,1.3){0.1}}
          \rput(2,1.2){\commit}
          \rput(2.6,1.2){\commit}
          \rput(3.2,1.2){\commit}
        \rput(1.4,0){\commit}
        \rput(2,0){\commit}
        \rput(2.6,0){\commit}
        % \rput(3.2,0){\commit}
        % \rput(3.8,0){\commit}

        \rput[r](5.5,0.1){1}
        \rput[r](5.5,0.5){2}
        \rput[r](5.5,0.9){3}
        \rput[r](5.5,1.3){4}
      \end{pspicture}\\
      1: Hauptzweig, 2: Umstellung auf GTK~2, 3: Umstellung auf Tabellen statt
      Listen, 4: neues Dateiformat
    \end{center}
    \pause
    \vspace{-2ex}

   \item Vorteil: Unabhängigkeit der Zweige, jeder Zweig ist Spielwiese einer
    Entwicklergruppe

   \item wenn Entwicklung schief gegangen ist, Zweig wegwerfen; bei
    Nichtverzweigung: alle Änderungen rückgängig machen

   % \item im verteilten VCS könnte jeder Client als Zweig des Originals
   %  betrachtet werden
  \end{itemize}
\end{slide}

\begin{slide}[method=file,toc={Problem: merge}]{Probleme mit Verzweigungen:
  Eingliederung}
  \begin{itemize}
   \item Historie der Änderungen sollte bei der Eingliederung (merge)
    übernommen werden

    \begin{Verbatim}[gobble=4,commandchars]
    trunk% svn diff -r ANFANG:ENDE ../branch/a | patch -p0
    trunk% cp -fr ../branch/a . \vrblinecomment{oder die brutale Variante}
    trunk% svn commit -m "Eingliederung von Zweig a"
    \end{Verbatim}
    \vspace{-3ex}
    \begin{center}
      \Large so nicht!
    \end{center}
    \vspace{-2ex}
    \pause

   \item leider macht \texttt{svn merge} das (im Wesentlichen) so, Historie
    unterbrochen

   \item damit sind \texttt{log} und \texttt{blame} (fast) nutzlos
    \pause

   \item wird bei SVK umgangen, da Änderungen vom lokalen Zweig direkt auf
    Original auf Server geschrieben werden --~sozusagen verzögerter Commit,
    Verzweigung nie auf Server
  \end{itemize}
\end{slide}

\begin{slide}[method=direct,toc={Problem: rebase}]{Probleme mit Verzweigungen:
  Parallele Änderungen}
  \begin{itemize}
   \item in einem Zweig u.\,U. Änderungen am gleichen Objekt wie im Hauptzweig

   \item Änderungen aus Hauptzweig übernehmen (merge) $\rightarrow$ beim
    Eingliedern ist die Änderung zweimal in der Historie
    \vspace{-1ex}
    \begin{center}
      \begin{pspicture}(0,0)(6,1.3)
        \newcommand*{\commit}{\psline(0,0.1)(0.4,0.1)\pscircle(0.5,0.1){0.1}}
        \pscircle(0.1,0.1){0.1}
        \rput(0.2,0){\commit}
        \rput(0.8,0){\commit}
        \rput(1.4,0){\commit}
        \rput(2,0){\psline(0,0.1)(0.4,0.1)\pscircle[linecolor=red](0.5,0.1){0.1}}
        \rput(2.6,0){\commit}

        \psline[linecolor=red](2.5,0.2)(3,0.7)
        \rput(1.4,0){\psline(-0.1,0.2)(0.1,0.7)(0.4,0.7)\pscircle(0.5,0.7){0.1}}
          \rput(2,0.6){\commit}
          \rput(2.6,0.6){\psline(0,0.1)(0.4,0.1)
            \pscircle[linecolor=red](0.5,0.1){0.1}}
          \rput(3.2,0.6){\psline(0,0.1)(0.4,0.1)
            \pscircle[linecolor=blue](0.5,0.1){0.1}}

        \psset{linecolor=gray}
          \psline[linestyle=dashed](3.9,0.7)(4.5,0.7)
          \pscircle(4.6,0.7){0.1}
        \psline(4.6,0.6)(5,0.1)
        \psline[linestyle=dashed](3.2,0.1)(5,0.1)
        \pscircle(5.1,0.1){0.1}
      \end{pspicture}
    \end{center}
    bei späteren Eingliedern Änderung (rot) zweimal in der Historie
    \pause

   \item daher besser Neuaufsetzen (rebase) des Zweigs
    \vspace{-1ex}
    \begin{center}
      \begin{pspicture}(0,0)(6,1.3)
        \newcommand*{\commit}{\psline(0,0.1)(0.4,0.1)\pscircle(0.5,0.1){0.1}}
        \pscircle(0.1,0.1){0.1}
        \rput(0.2,0){\commit}
        \rput(0.8,0){\commit}
        \rput(1.4,0){\commit}
        \rput(2,0){\psline(0,0.1)(0.4,0.1)\pscircle[linecolor=red](0.5,0.1){0.1}}
        \rput(2.6,0){\commit}

        \rput(2.6,0){\psline(-0.1,0.2)(0.1,0.7)(0.4,0.7)\pscircle(0.5,0.7){0.1}}
          \rput(3.2,0.6){\commit}
          \rput(3.8,0.6){\psline(0,0.1)(0.4,0.1)
            \pscircle[linecolor=blue](0.5,0.1){0.1}}

        \psset{linecolor=gray}
          \psline[linestyle=dashed](4.4,0.7)(5,0.7)
          \pscircle(5.1,0.7){0.1}
        \psline(5.1,0.6)(5.5,0.1)
        \psline[linestyle=dashed](3.2,0.1)(5.5,0.1)
        \pscircle(5.6,0.1){0.1}
      \end{pspicture}
    \end{center}
  \end{itemize}
\end{slide}

\section[toc={GIT -- Teil~1}]{GIT}

\begin{slide}[toc={Was kann GIT?}]{Was kann GIT? (1)}
  \begin{itemize}
   \item Verteiltes VCS, Server/""Client"=System auch möglich

   \item kompaktes, mächtiges Datenmodell; formale Grundlage für Operationen
    $\rightarrow$ Flexibilität

   \item ermöglicht Zugriff auf CVS und SVN

   \item kleine Menge von Grundbefehlen (für harte Kerle), Befehle für
    Endanwender bauen darauf auf $\rightarrow$ leicht erweiterbar

   \item schöne/""intuitive Befehle mit umfangreichen Optionen --~von
    Anwendern gemacht

   \item intelligentes Merge, kann Konflikte teilweise selbst auflösen

   \item Einstellungen zum Ignorieren können lokal gemacht werden

   \item nur \texttt{.git}"~Verz. auf oberster Ebene (bei CVS/SVN in jedem V.)
  \end{itemize}
\end{slide}

\begin{slide}[toc=]{Was kann GIT? (2)}
  \begin{itemize}
   \item Veröffentlichung des Archivs kann per HTTP geschehen

   \item Bearbeiten von Commits möglich -- perfekter Patch

   \item kann Zweige ordentlich Zusammenführen und Neuaufsetzen

   \item Syntax gleicht der von SVN/CVS: \texttt{git UNTERBEFEHL}

   \item \texttt{git} nur Rahmenprogramm, ruft \texttt{git-UNTERBEFEHL} auf

   \item hat manpages, \texttt{git help UB} oder \texttt{git UB -{}-help} ruft
    man

   \item für viele Ausgaben wird automatisch \texttt{\$PAGER} geöffnet; kein
    \texttt{git UB | less} notwendig

   \item keine Keywords (\$Id\$, \$Date\$) -- gefeiert als
    Befreiung~\cite{git-keine-keywords}

   \item nur vordefinierte Metainformationen möglich (keine Zugriffsrechte,
    Eigentümer für Dateien)
  \end{itemize}
\end{slide}

\begin{slide}[method=direct]{Kurznamen}
  \begin{itemize}
   \item GIT hat keine Kurzschreibweisen wie co, ci, up, st bei SVN

   \item aber man kann sie sich selbst festlegen
    \vspace{-1ex}
    \begin{Verbatim}[gobble=4]
    % cat ~/.gitconfig
    [alias]
            ci = commit
            co = checkout
            st = status
    \end{Verbatim}

   \item oder mit \texttt{git config}
    \vspace{-1ex}
    \begin{Verbatim}[gobble=4]
    % git config --global alias.ca "commit --all"
    % git config --global alias.dc "diff --color"
    % git config --global alias.sa stash
    \end{Verbatim}
    ohne \verb+--global+: nur Konfiguration des aktuellen Projekts

   \item noch mehr (z.\,B. Aufruf von ext. Befehlen) siehe
    \href{http://git.or.cz/gitwiki/Aliases}{GIT-Wiki}~\cite{git-alias}

   \item daher lieber \texttt{git UB} statt \texttt{git-UB} verwenden
  \end{itemize}
\end{slide}

\begin{slide}{Umgang mit Dateien}
  \begin{itemize}[itemsep=0.4em]
   \item katalogisiert nicht Dateien und Verzeichnisse wie SVN, sondern
    betrachtet Inhalt der Dateien und verwendet
    Heuristik:
    \begin{enumerate}[itemsep=0.3em,topsep=0pt]
     \item Vorgänger einer Datei ist eine Datei mit dem selben Namen im
      vorherigen Commit. Trifft dies nicht zu, dann wird

     \item nach einer Datei gesucht, die vom Inhalt her ähnlich ist.
      Kandidaten sind Dateien im letzten Commit, die nicht Vorgänger einer
      anderen Datei sind.
    \end{enumerate}

   \item daher kann GIT auch Teile von Dateien verfolgen; kein Abriss der
    Historie bei Verschieben (z.\,B. \foreignlanguage{english}{Refactoring});
    \texttt{git blame} zeigt wann Zeile wirklich verändert, nicht wann
    neu eingefügt

   \item Objekte müssen für den Commit markiert werden: \texttt{git add} merkt
    den aktuellen Zustand des Objekts für den nächsten Commit vor; oder man
    nimmt \texttt{git commit -a}

   \item dennoch gibt es \texttt{git mv} und \texttt{git rm} zur
    Arbeitserleichterung (\texttt{mv/rm \$DATEI} + markieren für Commit)
  \end{itemize}
\end{slide}

\begin{slide}[toc={git commit}]{git commit (1)}
  \begin{itemize}
   \item geschieht zweistufig:
    \begin{enumerate}
     \item Zustand der Objekte wird für Commit registriert:
      \texttt{git~add/mv/rm}, \texttt{git update-index}
      --~Zwischenstufe heißt Index

     \item durchführen des Commits: \texttt{git commit}
    \end{enumerate}

   \item Registr. kann schrittweise/""für jedes Objekt einzeln geschehen

   \item Objekte können nach Restrierung verändert werden, danach neu
    registrieren oder nur registrierte Version verwenden

   \item \texttt{commit} arbeitet global auf ganzem Baum (bei SVN nur ab
    aktuellen Verzeichnis abwärts)

   \item über Index können gezielt Objekte für nächsten Commit ausgewählt
    werden; kann bei Aufruf überschrieben werden
  \end{itemize}
\end{slide}

\begin{slide}[toc=]{git commit (2)}
  \begin{itemize}
   \item \texttt{-a|-{}-all} = \texttt{git add} für alle bekannten Objekte +
    \texttt{git~commit}

   \item Editor öffnet sich zum Verfassen einer Beschreibung: sollte in der
    ersten Zeile 50~Zeichen haben, dann Leerzeile, dann Text --~vorteilhaft
    bei der Verwendung von \texttt{git-format-patch}

   \item \texttt{-{}-amend}: ersetzt den letzten Commit (HEAD);
    praktisch, wenn man noch einen Fehler im letzten Commit findet;
    Metainformationen vom alten Commit übernommen, Editor wird erneut geöffnet
  \end{itemize}
\end{slide}

\begin{slide}[method=direct,toc={Verwalt. v. Commits}]{Verwaltung von Commits}
  \begin{itemize}
   \item arbeitet mit einem Haufen (mathm. Menge) von Commits, die zu
    entsprechenden Zweigen aneinander gereiht werden

   \item daher keine fortlaufende Nummer, sondern SHA1"=Hashwert,
    i.\,d.\,R. reichen führende 6~Stellen (Skript: \texttt{git-common-hash})
    \begin{Verbatim}[gobble=4,fontsize=\small]
    commit a0b31592498ddd223a8b83de15f7542e3eca268c
    Author: Jörg Sommer <joerg@alea.gnuu.de>
    Date:   Mon Nov 19 14:11:21 2007 +0100

        Neue Folie über Neuaufsetzen von Zweigen.
    \end{Verbatim}

   \item Vorteil: Bearbeiten von Patches möglich, Umordnen der Commits möglich
    (ohne Verlust der Metainformationen)

   \item Nachteil: beim Hin- und Herrücken entsteht Abfall, \texttt{git gc}
    zum Saubermachen
  \end{itemize}
\end{slide}

\begin{slide}[toc={Referenzierung v. C.}]{Referenzierung von Commits}
  \begin{itemize}[itemsep=0em,topsep=0em]
   \item Tags und Branches nur zusätzliche, einfachere Namen; Tag fest an
    Commit gebunden, Branch letzter Commit im Zweig

   \item Commits können indirekt angesprochen werden:
    \begin{description}[itemsep=0em,topsep=0em]
     \item[ref\textasciicircum{}\{X\}] der X.~Vater von $\mathit{ref}$,
      notwendig bei Merge (hat mehr als einen Vorgänger),
      ref\textasciicircum{} = ref\textasciicircum{}\{1\},
      ref\textasciicircum{}\{0\} = ref

     \item[ref\textasciitilde{}\{X\}] der X.~Vorgänger in der Geschichte von
      $\mathit{ref}$, bei Merge wird immer 1.~Vater genommen,\\
      z.\,B. der vorvorletzte Commit \texttt{git show HEAD\textasciitilde{}2}

     \item[:/Text] letzter C. vor $ref$, dessen Meldung mit $\mathit{Text}$
      beginnt

     \item[ref@\{Datum\}] letzter Zustand von $\mathit{ref}$ vor dem
      Zeitpunkt oder dem Schritt, GIT führt Buch über veränderliche Referenzen
      (HEAD, master), siehe \texttt{git reflog},\\
      z.\,B. {\small\texttt{log master@\{7 days ago\}..};
      \texttt{show HEAD@\{4\}}}
    \end{description}
    \pause

   \item Mengenoperationen, einfachste Form
    $A..B := \text{Vorgänger}(B)\setminus\text{Vorgänger}(A)$

   \item es gibt noch mehr: \texttt{man git-rev-parse}
  \end{itemize}
\end{slide}

\begin{slide}[method=file]{git show}
  \begin{itemize}[itemsep=0.5em]
   \item zeigt GIT"~Objekte (commit, tags, blob, tree) an

   \item startet automatisch \texttt{less}

   \item den letzten Commit mit Patch: \texttt{git show}

   \item \texttt{-{}-shortstat}/\texttt{-{}-stat} zeigt Statistik statt Patch
    \begin{Verbatim}[gobble=4]
    % git show --stat
    commit 22ab847d5eae7be1e12eb299478e99838c1c6da3
    Author: Jörg Sommer <joerg@alea.gnuu.de>
    Date:   Mon Nov 26 18:55:10 2007 +0100

        Neue Folien über git commit

     [...]tungen/vcs-vortrag.ltx         |   39 +++++++[...]
     1 files changed, 39 insertions(+), 0 deletions(-)
    \end{Verbatim}

   \item \texttt{-{}-all} zeigt die letzten Commits in allen Zweigen
    \pause

   \item die Datei \texttt{alpha} im vorletzten Commit im Zweig master:\\
    \texttt{git show master\textasciicircum{}:alpha}
  \end{itemize}
\end{slide}

\begin{slide}[toc={git log}]{git log (1)}
  \begin{itemize}
   \item zeigt die Commit"=Meldungen an

   \item ohne Argumente alle Commits vom aktuellen zurück zum Anfang für den
    aktuellen Zweig

   \item als Argument die Menge der Commits: alle Commits, die noch nicht im
    Zweig master sind \texttt{git log master..HEAD}

   \item \texttt{-g} zeigt die Veränderungen/""alten Zustände des
    "`Zweigzeigers"' an; Erinnerung an Referenzierung v. Commits: ref@\{\ldots{}\}
    \pause

   \item \texttt{-{}-since=}/\texttt{-{}-before=} Einschränkung des Zeitraums

   \item \texttt{-{}-grep=TEXT} nur Commits deren Meldung TEXT enthält

   \item \texttt{-STEXT} nur Commits deren Änderungen TEXT enthält
  \end{itemize}
\end{slide}

\begin{slide}[method=file,toc=]{git log (2)}
  \begin{itemize}
   \item \texttt{-{}-pretty=} verschiedene Formate: oneline, email, \ldots{}
    \begin{Verbatim}[gobble=4]
    % git log --pretty=oneline 'HEAD~6..HEAD~3'
    c1bd[...] Neue Folie über GITs Umgang mit Dateien.
    32f8[...] Die Folie für'n Schluss.
    771f[...] Neue Folie mit Lesetipps für Git. [...]
    \end{Verbatim}

   \item \texttt{-p} zeigt zusätzlich den Patch zum Commit

   \item \texttt{-{}-shortstat}/\texttt{-{}-stat} zeigt zus. Statistik über
    Änderungen

   \item \texttt{-{}-name-only} zeigt zusätzl. Namen der geänderten Dateien

   \item \texttt{-{}-name-status} wie \texttt{svn status} (zusätzlich)

   \item \texttt{-{}-relative-date} macht relative Zeitangaben
  \end{itemize}
\end{slide}

\begin{slide}{git diff}
  \begin{itemize}
   \item zeigt Änderungen seit der letzten Registrierung (\texttt{git~add})

   \item \texttt{-{}-cached} zeigt die registrierten Änderungen/""was geht in
    nächsten Commit

   \item \texttt{-{}-color} für farbige Ausgabe, markiert Leerzeichen am Ende;
    Variable \texttt{LESS=-R} setzen

   \item \texttt{-{}-color-words} für farbiger Unterschiede wortweise
    (nicht zeilenweise)

   \item \texttt{-{}-stat} für eine kurze Statusübersicht

   \item etwas anderes Format als normaler diff um Zweistufigkeit und
    Zusammenführungen darzustellen
  \end{itemize}
\end{slide}

\begin{slide}[method=direct,toc={blame, status, gitk}]{git blame, git status, gitk}
  \begin{itemize}
   \item \texttt{git blame} wie bei SVN, zeigt für jede Zeile einer Datei den
    letzten Commit an, in dem sie geändert wurde

   \item \texttt{git status} wie bei SVN, aber anderes Format:
    \begin{Verbatim}[gobble=4,fontsize=\scriptsize]
    % git status
    # On branch vcs-vortrag
    # Changed but not updated:
    #   (use "git add <file>..." to update what will be committed)
    #
    #       modified:   www.lug-jena.de/static/veranstaltunge[...]
    #
    # Untracked files:
    #   (use "git add <file>..." to include in what will be c[...]
    #
    #       www.lug-jena.de/static/veranstaltungen/vcs-vortrag.ps
    #       www.lug-jena.de/static/veranstaltungen/vcs-vortrag.vrb
    no changes added to commit (use "git add" and/or "git com[...]
    \end{Verbatim}

   \item \texttt{gitk} zur Visualisierung der Historie, zeigt mit
    \texttt{-{}-all} alle Zweige
  \end{itemize}
\end{slide}

\section[slide=false]{GIT -- Teil~2}

\begin{slide}[method=direct]{Verzweigungen}
  \begin{itemize}[itemsep=0em]
   \item Standardzweig heißt master

   \item \texttt{git branch} (ohne Argumente) zeigt lokale Zweige an

   \item \texttt{git branch -a} zeigt lokale und entfernte Zweige an
    \begin{Verbatim}[gobble=4,commandchars]
    % git branch -a
      master
    * vcs-vortrag \vrblinecomment{aktueller Zweig}
      git-svn
    \end{Verbatim}

   \item \texttt{git branch Z} erzeugt neuen Zweig~Z ab aktueller
    Stelle (HEAD)
    \pause

   \item \texttt{git checkout Z} wechselt zum Zweig~Z (oder Commit~Z)

   \item \texttt{git checkout -b Z} = \texttt{branch Z} + \texttt{checkout Z}

   \item Z = symbolischer Name für letzten Commit im Zweig~Z

   \item \texttt{git branch -d} löscht einen Zweig

   \item \texttt{git merge} führt Zweige zusammen

   \item \texttt{git rebase} setzt einen Zweig neu auf; Vorsicht: kann zu
    Problemen führen~\cite{git-rebase-problem}
  \end{itemize}
\end{slide}

\begin{slide}[toc={Fehl. Änder. beheben}]{Fehlerhafte Änderungen beheben}
  \begin{itemize}
   \item den letzten Commit mit \texttt{git commit -{}-amend} ersetzen

   \item \texttt{git revert} erzeugt \emph{neuen} Commit um alten rückgängig
    (\texttt{patch -R}) zu machen, Vorsicht: nicht wie \texttt{svn revert}

   \item \texttt{git reset -{}-hard HEAD\textasciitilde{}3} wirft die letzten
    3~Com. weg

   \item mit Kombination aus \texttt{checkout}, \texttt{commit -{}-amend} und
    \texttt{rebase} kann man beliebigen Commit verändern; \emph{Vorsicht: das
    hat weitreichende Folgen!} prüfen mit \texttt{gitk}

   \item Änderungen im Arbeitsverzeichnis zurücksetzen:
    \begin{itemize}
     \item \texttt{git reset -{}-hard HEAD} = \texttt{svn revert}

     \item \texttt{git reset HEAD Datei \&\& git checkout Datei}
      =~\texttt{svn revert Datei}
    \end{itemize}
  \end{itemize}
\end{slide}

\begin{slide}[toc={Weiter Befehle}]{Weitere Befehle zum Arbeiten}
  \begin{itemize}
   \item \texttt{git clean} löscht unbekannte Dateien
    (\texttt{\textasteriskcentered{}.o}, \texttt{\textasteriskcentered{}.aux},
    \ldots{}), \texttt{-x}~löscht auch ignorierte Dateien

   \item \texttt{git cherry-pick} fügt einzelnen Commit (aus dem großen
    Haufen) in aktuellen Zweig ein

   \item \texttt{git bisect} unterstützt bei der binären Suchen nach
    fehlerhaften Commit

   \item \texttt{git grep} sucht nach Dateien, mächtiger als \texttt{grep},\\
    \texttt{git grep foo -{}-not foot master\textasciitilde{}3 -{}-
      \textbackslash{}\textasteriskcentered{}.html}
  \end{itemize}
\end{slide}

\begin{slide}[toc={Kleine Unterbrechung}]{Eine kleine Unterbrechung}
  \begin{itemize}
   \item \texttt{git stash} stellt den aktuellen Zustand des
    Arbeitsverzeichnisses zurück

   \item nützlich, wenn man kurz die Arbeit unterbrechen muss
    \begin{itemize}[itemsep=0em]
     \item \texttt{editor}, grübel, grübel, tipp, tipp
     \item Anruf: Hi, in Datei~X fehlt ein "`wubwub"'
     \item \texttt{git stash}
     \item \texttt{editor X}, tipp, tipp
     \item \texttt{git commit -a}
     \item \texttt{git stash apply}
     \item weiter geht's: grübel, grübel, tipp, tipp, \ldots{}
    \end{itemize}

   \item \texttt{git stash apply} stellt letzten Arbeitszustand wieder her

   \item \texttt{git stash list} listet alle zurückgestellen Zustände auf

   % \item \texttt{git stash show} zeigt zurückgestellten Zustand an

   \item \texttt{git stash clear} macht mal wieder sauber
  \end{itemize}
\end{slide}

\begin{slide}{Hausputz}
  \begin{itemize}
   \item \texttt{git gc} räumt auf, bessert interne Strukturen auf

   \item \texttt{git count-objects} meldet die Anzahl der vagabundierenden
    Objekte

   \item es entstehen ständig Objekte, die nicht genutzt werden:
    \texttt{reset}, \texttt{stash}, \texttt{merge}, \ldots{} $\rightarrow$
    \texttt{git gc -{}-prune} löscht diese

   \item \texttt{git fsck} prüft die Konsistenz des Archivs
  \end{itemize}
\end{slide}

\begin{slide}[method=direct]{Ein neues Archiv}
  \begin{itemize}
   \item \texttt{git config} zum einfacheren Ändern der Konfiguration, es
    funktioniert aber auch der Editor

   \item vor Beginn sämtlicher Arbeit sollte man
    \begin{Verbatim}[gobble=4]
    % git config --global user.name "Jörg Sommer"
    % git config --global user.email "joerg@alea.gnuu.de"
    \end{Verbatim}
    (ändert \texttt{\textasciitilde{}/.gitconfig})

   \item \texttt{git init} legt \texttt{.git} an/""erzeugt neues Archiv

   \item \texttt{git clone} wie \texttt{svn co}/""kopiert öffentliches Archiv

   \item \texttt{git clone -{}-depth=4} holt nur die aktuelle Version und die
    letzten 4~Commits

   \item \texttt{git fetch} holt Änderungen vom öffentlichen Archiv, müssen
    mit \texttt{merge} eingebunden werden,
    \texttt{git pull} = \texttt{fetch} + \texttt{merge}
  \end{itemize}
\end{slide}

\begin{slide}[method=file]{Zugriff auf CVS}
  \begin{Verbatim}[gobble=2,commandchars]
  % mkdir jedmodes; cd jedmodes
  % git cvsimport -p-Z,9 -d:pserver:anonymous@jedmodes.cvs.\carriagereturn{}
                    sf.net:/cvsroot/jedmodes -k -m -u -v mode
  [...] \vrblinecomment{Ausgabe von CVS wegen -v}
  Initialized empty Git repository in [...]/git/jedmodes/.git/
  Generating pack...
  Done counting 2447 objects.
  Deltifying 2447 objects...
  100% (2447/2447) done
  Writing 2447 objects...
  100% (2447/2447) done
  Total 2447 (delta 1092), reused 0 (delta 0)
  Pack pack-30ae64074db0ee64f5f96464954513b569beec43 created.
  Removing unused objects 100%...
  Done. \pause{}
  % du -sh cvs/jedmodes git/jedmodes
  2,3M    cvs/jedmodes
  3,2M    git/jedmodes \vrblinecomment{alle Zweige mit der gesamten Historie}
  \end{Verbatim}
  \vspace{-1ex}
  zum Aktualisieren: im master"=Zweig gleichen Befehl verwenden
\end{slide}

\begin{slide}[method=file]{Zugriff auf SVN}
  \begin{Verbatim}[gobble=2,commandchars]
  % git svn clone https://svn.lug-jena.de/repos/public/jjm
  Initialized empty Git repository in .git/
  A       latex_cmds.sl
  A       doc/latex-jed.rc
  [...]
  r3 = 699df935930fab5fb32740c9c74610c41adaf994 (git-svn)
  M       latex_external.sl
  r4 = 3ba18898121a11f5154a5aceec7036dd9ec31928 (git-svn)
  M       read_with_description.sl
  r5 = 5a3dc3a0657d9f4baba9d8c7a502e68f27387e37 (git-svn)
  [...]
  r226 = 1fc03e4e2e120964628856dbfeb762c01cc77d6e (git-svn)
  Checked out HEAD:
  https://svn.lug-jena.de/repos/public/jjm r226
  % du -sh git/jjm svn/lug-public/jjm
  6,0M    git/jjm
  3,2M    svn/lug-public/jjm \pause{}

  % git svn rebase \vrblinecomment{zum Aktualisieren}
  % git svn dcommit \vrblinecomment{zum Senden der Änderungen}
  \end{Verbatim}
\end{slide}

\begin{slide}[method=direct,toc={Zugriff sauberes SVN}]%
  {Zugriff auf ein sauberes SVN-Archiv}
  \begin{Verbatim}[gobble=2,commandchars,fontsize=\small]
  % git svn clone -q \emph{--stdlayout} file:///svn/deborphan
  Initialized empty Git repository in .git/
  r1 = a61685  [...]  dec9a126c908bda (trunk)
  r2 = fe6269  [...]  3a78562b7daf15d (source-dist)
  r3 = e716ae  [...]  8326f05b0255abb (upstream)
  r5 = b471e0  [...]  cc9a3ee110d2bab (trunk)
  [...]
  r629 = 6d88  [...]  151da0bdfaabda9ed (deborphan-2.0)
  Checked out HEAD:
    file:///svn/deborphan/branches/deborphan-2.0 r629
  % git branch -r
  deborphan-2.0
  source-dist
  tags/debian_version_0_1_11-1
  tags/debian_version_0_1_11-2
  tags/debian_version_0_1_11-3
  [...]
  trunk
  \end{Verbatim}
\end{slide}

\begin{slide}[toc=Meinungen]{Meinungen zu GIT + CVS/SVN}
  \paragraph{Vorzüge}
  \begin{itemize}
   \item man hat einen Großteil der Vorzüge von GIT: Unabhängigkeit, suchen in
    der Historie, die Programme von GIT (\texttt{bisect}, \texttt{stash}),
    Verzweigen (solange man diese nicht sendet)

   \item GIT erkennt bei CVS durch die Heuristik Umbenennungen
  \end{itemize}

  \paragraph{Probleme}
  \begin{itemize}
   \item da Commits irgendwann wieder ins CVS/SVN müssen, gehen die Uhrzeiten
    verloren

   \item da CVS/SVN keine Namen und E"~Mailadressen kennt, fehlen diese; Datei
    mit der Liste "`Login=Name \nolinkurl{<E@Mail>}"' anlegen und
    \texttt{git cvsimport} beim ersten Mal bzw. \texttt{git svn clone} mit
    \texttt{-A Datei} aufrufen
  \end{itemize}
\end{slide}

\begin{slide}[toc={SVN"~Migration},method=direct]%
  {Migration eines \emph{sauberen} SVN-Archivs}
  \begin{Verbatim}[gobble=2,commandchars,fontsize=\small]
  % cat svn-authors
  joerg=Jörg Sommer <joerg@alea.gnuu.de>
  % git svnimport -A svn-authors -C bootchart -o master\carriagereturn{}
        -m file://$HOME/.svnroot/bootchart
  Initialized empty Git repository in [...]otchart/.git/
  Generating pack...
  Done counting 255 objects.
  Deltifying 255 objects...
   100% (255/255) done
  Writing 255 objects...
   100% (255/255) done
  Total 255 (delta 110), reused 0 (delta 0)
  Pack pack-2e4abaeed3e14ceb245fda228bf7033bca82160d [...]
  Removing unused objects 100%...
  Done.
  % du -sh git/bootchart .svnroot/bootchart svn/bootchart
  155K    git/bootchart
  298K    .svnroot/bootchart
  150K    svn/bootchart
  \end{Verbatim}
\end{slide}

\begin{slide}{Literatur für GIT}
  \begin{itemize}
   \item eine kurze Einführung:
    "`\href{http://www.kernel.org/pub/software/scm/git/docs/tutorial.html}%
           {A tutorial introduction to git}"'~\cite{git-tut}

   \item eine kurze Übersicht der Befehle:
    "`\href{http://www.kernel.org/pub/software/scm/git/docs/everyday.html}%
           {Everyday GIT With 20 Commands Or So}"'~\cite{git-day}

    \begin{center}
      kann man in weniger als einer Stunde lesen
    \end{center}

   \item einen kleinen Einblick in die internen Datenstrukturen und
    Arbeitsweise:
    "`\href{http://eagain.net/articles/git-for-computer-scientists/}%
           {Git for Computer Scientists}"'~\cite{git-for-sci}

   \item \href{http://git.or.cz/gitwiki/FrontPage}{GIT"~Wiki}~\cite{git-wiki}
   \item \href{http://git.or.cz/gitwiki/GitFaq}{GIT"~FAQ}~\cite{git-faq}
  \end{itemize}
\end{slide}

\section{Abspann}

\begin{slide}[toc=Ende]{}
  \centering
  \Huge
  \vspace{6ex}
  Das Ende
\end{slide}

\begin{slide}[toc=Literaturverzeichnis]{Literaturverzeichnis (1)}
  \begin{thebibliography}{99}
   \bibitem{cmp-vcs} "`Comparison of revision control software - Wikipedia,
    the free encyclopedia"',
    \href{http://en.wikipedia.org/wiki/Comparison_of_revision_control_software}%
         {\nolinkurl{http://en.wikipedia.org/wiki/}}\carriagereturn{}
    \href{http://en.wikipedia.org/wiki/Comparison_of_revision_control_software}%
         {\nolinkurl{Comparison_of_revision_control_software}}

   % \bibitem{bitkeeper} "`BitKeeper - The Scalable Distributed Software
   %  Configuration Management System"', \url{http://www.bitkeeper.com/}

   \bibitem{bzr} "`Welcome - Bazaar Version Control"',
    \url{http://www.bazaar-vcs.org/}

   \bibitem{cvs} "`CVS - Open Source Version Control"',
    \url{http://www.nongnu.org/cvs/}

   % \bibitem{darcs} "`"', \url{http://darcs.net/}

   \bibitem{git} "`Git - Fast Version Control System"', \url{http://git.or.cz/}

   \bibitem{mercu} "`Mercurial - Mercurial"',
    \url{http://www.selenic.com/mercurial/}

   \bibitem{rcs} "`RCS - GNU Project - Free Software Foundation (FSF)"',
    \url{http://www.gnu.org/software/rcs/rcs.html}
  \end{thebibliography}
\end{slide}

\begin{slide}[toc=]{Literaturverzeichnis (2)}
  \begin{thebibliography}{99}
    \setcounter{enumiv}{6}
   \bibitem{svk} "`HomePage - SVK Wiki"', \url{http://svk.elixus.org/}

   \bibitem{svn} "`subversion.tigris.org"', \url{http://subversion.tigris.org}

   \bibitem{svk-nocvs} "`[svk-devel] is svk mirror off cvs or perforce (p4)
    repos supposed to be working in svk 2.0?"',
    {\footnotesize
      \href{http://lists.bestpractical.com/pipermail/svk-devel/2007-February/000604.html}%
           {\nolinkurl{http://lists.bestpractical.com}}\carriagereturn{}
      \href{http://lists.bestpractical.com/pipermail/svk-devel/2007-February/000604.html}%
           {\nolinkurl{/pipermail/svk-devel/2007-February/000604.html}}
    }

   \bibitem{svk-lnx-mag} "`Revisionskontrolle für unterwegs mit SVK « 07 «
    2006 « Ausgaben « ABO \& ARCHIV « Linux-Magazin Online"',
    {\tiny
      \url{http://www.linux-magazin.de/heft_abo/ausgaben/2006/07/eric_geht_essen}}

   \bibitem{svk-tutorial} "`SVK Tutorials | Bieber Labs"',
    {\small\url{http://www.bieberlabs.com/wordpress/svk-tutorials}}

   \bibitem{svk-vortrag} "`Versionskontrolle mit SVK"', Ingo Blechschmidt
    \href{mailto:iblech@web.de}{\nolinkurl{<iblech@web.de>}}, LUGA,
    1.~Februar~2006,
    {\small\url{http://www.luga.de/Angebote/Vortraege/SVK/SVK.pdf}}
  \end{thebibliography}
\end{slide}

\begin{slide}[toc=]{Literaturverzeichnis (3)}
  \begin{thebibliography}{99}
    \setcounter{enumiv}{12}
   \bibitem{git-tut} "`A tutorial introduction to git"',
    \href{http://www.kernel.org/pub/software/scm/git/docs/tutorial.html}%
         {\nolinkurl{http://www.kernel.org/}}\carriagereturn{}
    \href{http://www.kernel.org/pub/software/scm/git/docs/tutorial.html}%
         {\nolinkurl{pub/software/scm/git/docs/tutorial.html}}

   \bibitem{git-day} "`Everyday GIT With 20 Commands Or So"',
    \href{http://www.kernel.org/pub/software/scm/git/docs/everyday.html}%
         {\nolinkurl{http://www.kernel.org/pub/software/scm/git/}}\carriagereturn{}
    \href{http://www.kernel.org/pub/software/scm/git/docs/everyday.html}%
         {\nolinkurl{docs/everyday.html}}

   \bibitem{git-wiki} "`FrontPage - GitWiki"',
    \url{http://git.or.cz/gitwiki/FrontPage}

   \bibitem{git-faq} "`GitFaq - GitWiki"',
    \url{http://git.or.cz/gitwiki/GitFaq}

   \bibitem{git-alias} "`Aliases - GitWiki"',
    \url{http://git.or.cz/gitwiki/Aliases}

   \bibitem{git-keine-keywords} Linus Torvalds: "`Re: Does GIT has vc keywords
    like CVS/Subversion?"', \url{git@vger.kernel.org} (Mailingliste),
    2006-10-09 16:13:14, \url{http://marc.info/?l=git&m=116041062619824&w=2}
  \end{thebibliography}
\end{slide}

\begin{slide}[toc=]{Literaturverzeichnis (4)}
  \begin{thebibliography}{99}
    \setcounter{enumiv}{18}
   \bibitem{git-rebase-problem} Cyrill Gorcunov: "`git-pull several branches
    merge conflict resolved"', \url{git@vger.kernel.org} (Mailingliste),
    2008-01-04 09:03:22, \url{http://marc.info/?l=git&m=119943743006341&w=2}

   \bibitem{git-for-sci} "`Tv's cobweb: Git for Computer Scientists"',
    \href{http://eagain.net/articles/git-for-computer-scientists/}%
         {\nolinkurl{http://eagain.net/articles/}}\carriagereturn{}
    \href{http://eagain.net/articles/git-for-computer-scientists/}%
         {\nolinkurl{git-for-computer-scientists/}}
  \end{thebibliography}
\end{slide}

\begin{slide}[toc=Nutzungsbedingung.]{Nutzungsbedingungen}
  Dieses Dokument sowie die \LaTeX{}"~Quellen dafür und alle zugehörigen
  Dateien dürfen in Teilen oder als Ganzes unter Angabe der Quelle, des Names
  und der E"~Mailadresse des Autors kopiert, verändert und weitergegeben
  werden.

  \bigskip
  \copyright{} 2007, Jörg Sommer
  \href{mailto:joerg@alea.gnuu.de}{\nolinkurl{<joerg@alea.gnuu.de>}}
\end{slide}

\end{document}

