1 \usetheme{default}
2 \setbeamertemplate{navigation symbols}{}
4 \mode<beamer>
5 {
6 \setbeamercolor{background canvas}{bg=black!10}
7 }
8 \setbeamercolor*{block body}{fg=black,bg=white}
9 \setbeamercolor*{block title}{use=titlelike,fg=titlelike.fg!80!black,bg=black!10}
11 \usepackage{ngerman}
12 \usepackage[utf8]{inputenc}
14 \usepackage{listings}
15 \usepackage{xcolor}
16 \definecolor{darkgreen}{rgb}{0,0.39,0}
18 \usepackage{graphicx}
19 \usepackage{icomma}
20 \usepackage[normalem]{ulem}
22 \usepackage{multirow}
24 \usepackage[overlay,absolute]{textpos}
26 \usepackage{tikz}
27 \usetikzlibrary{shadows}
28 \usetikzlibrary{decorations.pathreplacing}
29 \usetikzlibrary{shapes.geometric}
31 \usepackage{wasysym}
33 \title[Versionierung für OpenSourcler]{{\small Verteilte Versionskontrolle mit Git}\\
34 \LARGE Versionierung für OpenSourcler}
36 \author[Sebastian "`tokkee"' Harl]{Sebastian "`tokkee"' Harl\\
37 $<$tokkee@debian.org$>$}
38 %\institute{Debian RRDtool Team}
40 \date[ORR 2010]{\textbf{OpenRheinRuhr 2010}\\ 14.\ November 2010}
42 \subject{Versionierung für OpenSourcler}
44 \titlegraphic{
45 \vspace*{-10mm}
46 \begin{minipage}[c]{19mm}
47 \includegraphics[height=20mm]{orr-logo.pdf}
48 \end{minipage}
49 \hfill
50 \begin{minipage}[c]{13mm}
51 \includegraphics[height=25mm]{gitlogo.pdf}
52 \end{minipage}
53 }
55 % This is rather a hack, but it's easier than defining custom beamer themes
56 % for now.
57 \setbeamertemplate{frametitle}{}
58 \newenvironment{frameframe}[1]
59 {
60 \begin{frame}[fragile,environment=frameframe]
61 % width of a slide is 128 mm
62 \begin{textblock*}{116mm}(6mm,4mm)
63 \begin{tikzpicture}[x=1mm,y=1mm]
64 \filldraw[fill=white,rounded corners=2mm,very thick]
65 (0,0) rectangle (116,75);
66 \draw[thin] (58,75) node [fill=white,drop shadow,draw]
67 { \usebeamerfont*{frametitle}\usebeamercolor[fg]{frametitle}#1 };
68 \draw (58,78) node {};
69 \end{tikzpicture}
70 \end{textblock*}
71 \begin{textblock*}{122mm}(3mm,85mm)
72 \begin{minipage}[c]{8mm}
73 \includegraphics[width=8mm]{orr-logo.pdf}
74 \end{minipage}
75 \hfill
76 \begin{minipage}[c]{105mm}
77 \centering
78 {\tiny \insertshorttitle{}
79 \hspace{3mm}---\hspace{3mm}
80 \insertshortauthor{}
81 \hspace{3mm}---\hspace{3mm}
82 \insertframenumber\,/\,\inserttotalframenumber}
83 \end{minipage}
84 \hfill
85 \begin{minipage}[c]{5mm}
86 \includegraphics[width=5mm]{gitlogo.pdf}
87 \end{minipage}
88 \end{textblock*}
89 \begin{textblock*}{\textwidth}(10mm,12mm)
90 % even hackier ... ;-)
91 % vertically center the text in the frame
92 \begin{minipage}[c]{-1pt}\rule{0mm}{71mm}
93 \end{minipage}\begin{minipage}[c]{\textwidth}
94 }
95 {
96 \end{minipage}
97 \end{textblock*}
98 \end{frame}
99 }
101 \AtBeginSection[]
102 {
103 \begin{frame}
104 % width of a slide is 128 mm
105 \begin{textblock*}{116mm}(6mm,4mm)
106 \begin{tikzpicture}[x=1mm,y=1mm]
107 \filldraw[fill=white,rounded corners=2mm,very thick]
108 (0,0) rectangle (116,75);
109 \draw (58,78) node {};
110 \end{tikzpicture}
111 \end{textblock*}
112 \begin{textblock*}{122mm}(3mm,85mm)
113 \begin{minipage}[c]{8mm}
114 \includegraphics[width=8mm]{orr-logo.pdf}
115 \end{minipage}
116 \hfill
117 \begin{minipage}[c]{105mm}
118 \centering
119 {\tiny \insertshorttitle{}
120 \hspace{3mm}---\hspace{3mm}
121 \insertshortauthor{}
122 \hspace{3mm}---\hspace{3mm}
123 \insertframenumber\,/\,\inserttotalframenumber}
124 \end{minipage}
125 \hfill
126 \begin{minipage}[c]{5mm}
127 \includegraphics[width=5mm]{gitlogo.pdf}
128 \end{minipage}
129 \end{textblock*}
130 \begin{textblock*}{\textwidth}(10mm,14mm)
131 \tableofcontents[currentsection,hideothersubsections]
132 \end{textblock*}
133 \end{frame}
134 }
136 \begin{document}
138 \lstset{%
139 basicstyle=\scriptsize,%
140 language=C,%
141 identifierstyle=\color{black}\bfseries,%
142 keywordstyle=\color{darkgreen}\bfseries,%
143 commentstyle=\color{teal},%
144 stringstyle=\color{red},
145 showstringspaces=false,%
146 tabsize=4%
147 }
149 \begin{frame}
150 % width of a slide is 128 mm
151 \begin{textblock*}{116mm}(6mm,6mm)
152 \begin{tikzpicture}[x=1mm,y=1mm]
153 \filldraw[fill=white,rounded corners=2mm,very thick]
154 (0,0) rectangle (116,84);
155 \end{tikzpicture}
156 \end{textblock*}
157 \begin{textblock*}{\textwidth}(10mm,16mm)
158 \titlepage
159 \end{textblock*}
160 \end{frame}
162 \begin{frameframe}{Statistiken: Wer seid ihr?}
163 \begin{itemize}
164 \item<+-> Wer bezeichnet sich als Programmierer?
165 \item<+-> Wer arbeitet an einem OpenSource-Projekt?
166 \begin{itemize}
167 \item<+-> … mit mehr als 1 Entwickler?
168 \item<+-> … mit mehr als 10 Entwicklern?
169 \item<+-> … mit mehr als 100 Entwicklern?
170 \item<+-> … mit mehr als 1000 Entwicklern?
171 \end{itemize}
172 \item<+-> Wer hat schon ein Versionsverwaltungssystem (VCS) verwendet?
173 \item<+-> Wer hat schon ein zentrales VCS (CVS, SVN, …) verwendet?
174 \item<+-> Wer hat schon ein dezentrales VCS (Git, bzr, Mercurial, …)
175 verwendet?
176 \item<+-> Wer hat schon mit Git gearbeitet?
177 \end{itemize}
178 \end{frameframe}
180 \section{Grundlagen: Was ist Versionskontrolle?}
181 \begin{frameframe}{Grundlagen: Was ist Versionskontrolle?}
182 \begin{itemize}
183 \item technisch gesehen: ein Haufen Dateien mit Meta-Informationen und
184 irgendwelchen Beziehungen untereinander \smiley{}
186 \vspace{5mm}
188 \uncover<2>{
189 \item Protokollieren von Änderungen an (Quell-)text
190 \item Archivierung mit "`Rücksetz-Operation"'
191 \item koordinierter Zugriff
192 \item parallele Entwicklungszweige (neue Features, alte Releases)
193 }
194 \end{itemize}
195 \end{frameframe}
197 \begin{frameframe}{Grundlagen: Typen von VCSen}
198 \begin{textblock*}{\textwidth}(10mm,30mm)
199 \begin{itemize}
200 \item lock/modify/write
201 \item copy/modify/merge
203 \vspace{5mm}
205 \uncover<2->{
206 \item \alert<2>{lokale Versionierung}
207 \item \alert<3>{zentrale Versionierung}
208 \item \alert<5>{dezentrale Versionierung}
209 }
210 \end{itemize}
211 \end{textblock*}
213 \only<4>{
214 \begin{textblock*}{\textwidth}(10mm,20mm)
215 \centering
216 \begin{tikzpicture}[x=1mm,y=1mm]
217 \filldraw[fill=white,color=white] (-52,-27) rectangle (52,27);
218 \draw (0,0) node[thin,rounded corners=2mm,draw]
219 (repo) { zentrales Repo };
220 \draw (-30, 10) node[rounded corners,fill=yellow,draw]
221 (c0) { Committer 0 };
222 \draw (0, 20) node[rounded corners,fill=yellow,draw]
223 (c1) { Committer 1 };
224 \draw (30, 10) node[rounded corners,fill=yellow,draw]
225 (c2) { Committer 2 };
226 \draw (30, -10) node[rounded corners,fill=yellow,draw]
227 (c3) { Committer 3 };
228 \draw (0, -20) node { \LARGE … };
229 \draw [->] (c0.south east) -- (repo.north west);
230 \draw [->] (c1.south) -- (repo.north);
231 \draw [->] (c2.south west) -- (repo.north east);
232 \draw [->] (c3.north west) -- (repo.south east);
233 \end{tikzpicture}
234 \end{textblock*}
235 }
236 \end{frameframe}
238 \section{Dezentrale Versionskontrolle}
239 \begin{frameframe}{Workflow in OpenSource Projekten}
240 \begin{textblock*}{\textwidth}(10mm,30mm)
241 \begin{itemize}
242 \item üblicherweise ein/wenige Hauptentwickler/Projektleiter
243 \item viele Mitwirkende (versch.\ Umfang/Arbeitsgebiet)
244 \item ggf.\ Subsystem-Verantwortliche;\newline
245 Entwickler mit mehreren Arbeitsrechnern
246 \item ein "`zentraler"'/"`offizielles"' Repository
247 \item temporäre und Feature-Branches
248 \end{itemize}
249 \end{textblock*}
251 \only<2>{
252 \begin{textblock*}{\textwidth}(10mm,20mm)
253 \centering
254 \begin{tikzpicture}[x=1mm,y=1mm]
255 \filldraw[fill=white,color=white] (-52,-27) rectangle (52,27);
256 \draw (0,0) node[thin,rounded corners=2mm,draw]
257 (r0) { Repo 0 };
258 \draw (-25, 10) node[rounded corners,fill=yellow,draw]
259 (r1) { Repo 1 };
260 \draw (0, 20) node[rounded corners,fill=yellow,draw]
261 (r2) { Repo 2 };
262 \draw (-30, 27) node[rounded corners,fill=yellow,draw]
263 (r3) { Repo 3 };
264 \draw (30, 10) node[rounded corners,fill=yellow,draw]
265 (r4) { Repo 4 };
266 \draw (30, -10) node[rounded corners,fill=yellow,draw]
267 (r5) { Repo 5 };
268 \draw (0, -20) node { \LARGE … };
269 \draw [<->] (r1.south east) -- (r0.west);
270 \draw [<->] (r2.south west) -- (r1.north east);
271 \draw [<->] (r3.south) -- (r1.north);
272 \draw [<->] (r3.east) -- (r2.north west);
273 \draw [<->] (r4.south west) -- (r0.north east);
274 \draw [<->] (r5.north west) -- (r0.south east);
275 \draw [<->] (r5.north) -- (r4.south);
276 \end{tikzpicture}
277 \end{textblock*}
278 }
279 \end{frameframe}
281 \begin{frameframe}{Grundlagen von dezentralen VCSen}
282 \begin{itemize}
283 \item "`Peer-to-Peer"' Ansatz
284 \item jede Arbeitskopie bringt ein komplettes Repository mit (Klon)
285 \item gearbeitet wird auf lokalem Repository\newline
286 $\Rightarrow$ kein Netzwerk-Zugriff nötig\newline
287 $\Rightarrow$ Operationen schnell\newline
288 $\Rightarrow$ Offline-Arbeit möglich
289 \item automatisches "`Backup"' durch Repository-Klons
290 \item Zusammenführen meist auf Basis eines "`Web-of-Trust"'
291 \end{itemize}
292 \end{frameframe}
294 \begin{frameframe}{Arbeitsweise}
295 {
296 \vspace*{-5mm}
297 \hspace*{10mm}
298 \begin{tikzpicture}[x=1mm,y=1mm]
299 \node[cylinder,draw,shape border rotate=90,black,%
300 minimum width=25mm, minimum height=10mm,%
301 cylinder uses custom fill,cylinder end fill=yellow!90,%
302 cylinder body fill=yellow!60] at (0,0) {};
303 \draw (25, 0) node[anchor=west] { Repository };
304 \node[cylinder,draw,shape border rotate=90,black,%
305 minimum width=25mm, minimum height=10mm,%
306 cylinder uses custom fill,cylinder end fill=orange!90,%
307 cylinder body fill=orange!60] at (0,20) {};
308 \draw (25, 20) node[anchor=west] { Arbeitskopie };
310 \uncover<2,7>{
311 \draw[thick,->] (12.5, 5) -- (12.5, 17);
312 \draw (15,11) node[anchor=west] { \ttfamily checkout };
313 }
315 \uncover<3,7>{
316 \draw[thick,->] (0,25) .. controls (7,35) and (-7,35) .. (0,25);
317 \draw (0, 37.5) node { \ttfamily modify };
318 }
320 \uncover<4,7>{
321 \draw[thick,->] (-12.5, 17) -- (-12.5, 5);
322 \draw (-10,11) node[anchor=west] { \ttfamily commit };
323 }
325 \only<5->{
326 \node[cylinder,draw,shape border rotate=90,black,%
327 minimum width=25mm, minimum height=10mm,%
328 cylinder uses custom fill,cylinder end fill=yellow!90,%
329 cylinder body fill=yellow!60] at (0,-20) {};
330 \draw (25, -20) node[anchor=west] { anderes Repository };
332 \uncover<6>{
333 \draw[thick,->] (12.5, -15) -- (12.5, -3);
334 \draw (15,-9) node[anchor=west] { \ttfamily fetch };
335 }
337 \uncover<8>{
338 \draw[thick,->] (-12.5, -3) -- (-12.5, -15);
339 \draw (-10,-9) node[anchor=west] { \ttfamily push };
340 }
341 }
342 \end{tikzpicture}
343 }
344 \end{frameframe}
346 % TODO - Datenhaltung in Git (-> Git for Computer Scientists)
348 \section{Arbeiten mit Git}
349 \begin{frameframe}{Git: Übersicht}
350 \begin{itemize}
351 \item \url{http://www.git.or.cz/}
352 \item VCS (Version Control System)
353 \item 2005 von Linus Torvalds initiiert\newline
354 (aktueller Maintainer: Junio C. Hamano)
355 \item dezentral
356 \item schnell und effizient
357 \item kryptographisch gesichert
358 \item "`Toolkit design"'
359 \item OpenSource (GPLv2)
360 \item weit verbreitet im Einsatz (z.B.\ Linux Kernel, Ruby on Rails, Perl,
361 WINE, X.org, GNOME, Qt, Debian, …)
362 \end{itemize}
363 \end{frameframe}
365 \begin{frameframe}{Arbeiten mit Git: Grundlagen}
366 \begin{itemize}
367 \item $>>$ 100 einzelne Befehle
368 \item "`Porcelains"' und "`Plumbing"'
369 \item Dokumentation als Manpages - \texttt{git(7)}
370 \item \texttt{git help}, \texttt{git $<$command$>$ -h}
371 \item Benutzer Handbuch:
372 \url{http://www.kernel.org/pub/software/scm/git/docs/user-manual.html}
373 \end{itemize}
374 \end{frameframe}
376 \begin{frameframe}{Datenhaltung: Git Objektdatenbank}
377 \begin{itemize}
378 \item DAG (directed acyclic graph)
379 \item Objekte identifiziert durch SHA-1 Summe
380 \end{itemize}
382 \hspace*{15mm}
383 \begin{tikzpicture}[x=1mm,y=1mm]
384 \draw (0,0) node[thin,rounded corners=2mm,draw]
385 (blob) { blob };
387 \uncover<2->{
388 \draw (0, 20) node[thin,rounded corners=2mm,draw]
389 (tree) { tree };
390 \draw [->] (tree.south) -- (blob.north);
391 \draw (2,10) node[anchor=west] { \footnotesize name, mode };
392 \draw [->] (tree.north east) .. controls (10,25) and (10,15)
393 .. (tree.south east);
394 \draw (10, 20) node[anchor=west] { \footnotesize subdir };
395 }
397 \uncover<3->{
398 \draw (0,40) node[thin,rounded corners=2mm,draw]
399 (commit) { commit };
400 \draw [->] (commit.south) -- (tree.north);
401 \draw [->] (commit.north east) .. controls (15,45) and (15,35)
402 .. (commit.south east);
403 \draw (15,40) node[anchor=west] { \footnotesize parents };
404 }
406 \uncover<4->{
407 \draw (-20,40) node[thin,draw,fill=yellow]
408 (branch) { branch };
409 \draw [->] (branch.east) -- (commit.west);
410 \draw (-20,30) node[thin,draw,fill=yellow]
411 (head) { HEAD };
412 \draw[dashed,->] (head.north) -- (branch.south);
413 }
415 \uncover<5->{
416 \draw (-20,10) node[thin,draw,fill=orange]
417 (tag) { tag };
418 \draw [->] (tag.north east) -- (commit.south west);
419 \draw (-20, 3) node { \footnotesize name, message };
420 }
421 \end{tikzpicture}
422 \end{frameframe}
424 \begin{frameframe}{Git konfigurieren}
425 \begin{block}{Sich Git vorstellen}
426 \begin{itemize}
427 \item \texttt{git config --global user.name $<$Dein Name$>$}
428 \item \texttt{git config --global user.email $<$du@deine-domain.tld$>$}
429 \item $\rightarrow$ Benutzerinformationen für Commit-Metadaten
430 \end{itemize}
431 \end{block}
433 \uncover<2>{
434 \begin{block}{Bunt und in Farbe}
435 \begin{itemize}
436 \item \texttt{git config --global color.ui auto}
437 \item $\rightarrow$ farbige \texttt{branch}, \texttt{diff}, \texttt{grep},
438 \texttt{status} Ausgaben
439 \end{itemize}
440 \end{block}
441 }
442 \end{frameframe}
444 \begin{frameframe}{Repositories erstellen}
445 \begin{block}{Neues, leeres Repository}
446 \ttfamily
447 \footnotesize
448 \$ mkdir project\newline
449 \$ cd project\newline
450 \$ git init\newline
451 Initialized empty Git\newline
452 repository in .../.git/
453 \end{block}
455 \vspace{5mm}
457 \uncover<2>{
458 \begin{block}{Bestehendes Repository "`klonen"'}
459 \ttfamily
460 \footnotesize
461 \$ git clone $<$rep$>$\newline
462 ...
463 \end{block}
464 }
465 \end{frameframe}
467 \begin{frameframe}{Änderungen vornehmen}
468 \begin{block}{Ändern}
469 {\ttfamily
470 \footnotesize
471 \$ vim foo bar\newline
472 \$ git add foo bar
473 }
475 \begin{itemize}
476 \item \texttt{add}, \texttt{rm}, \texttt{mv}
477 \end{itemize}
478 \end{block}
480 \uncover<2>{
481 \begin{block}{Geschichte fortführen/ändern}
482 {\ttfamily
483 \footnotesize
484 \$ git commit
485 }
487 \vspace{5mm}
489 {\ttfamily
490 \footnotesize
491 \$ git reset --hard HEAD\textasciicircum
492 }
494 \begin{itemize}
495 \item \texttt{reset}, \texttt{revert}, \texttt{checkout}
496 \end{itemize}
497 \end{block}
498 }
499 \end{frameframe}
501 \begin{frameframe}{Exkurs: Commit Meldungen schreiben}
502 \begin{itemize}
503 \item Einzeilige, kurze ($<$ 80, optimal $<$ 50 Zeichen)
504 Zusammenfassung
505 \item Leerzeile
506 \item Detaillierte Beschreibung/Erklärung
507 \item nicht vorgeschrieben, aber "`common practice"' und von vielen
508 Tools erwartet
509 \end{itemize}
510 \end{frameframe}
512 \begin{frameframe}{Exkurs: Commit Meldungen schreiben}
513 \footnotesize
514 \begin{verbatim}
515 git-remote: do not use user input in a printf format string
517 'git remote show' substituted the remote name into a string that
518 was later used as a printf format string. If a remote name contains
519 a printf format specifier like this:
521 $ git remote add foo%sbar .
523 then the command
525 $ git remote show foo%sbar
527 would print garbage (if you are lucky) or crash. This fixes it.
528 \end{verbatim}
529 \end{frameframe}
531 \begin{frameframe}{Aus der Geschichte lernen}
532 \begin{block}{Status der Arbeitskopie}
533 \ttfamily
534 \footnotesize
535 \$ git status\newline
536 \$ git diff
537 \end{block}
539 \uncover<2->{
540 \begin{block}{Historie betrachten}
541 \ttfamily
542 \footnotesize
543 \$ git log\newline
544 \$ tig
545 \end{block}
546 }
548 \uncover<3->{
549 \begin{block}{Objekte betrachten}
550 {\ttfamily
551 \footnotesize
552 \$ git show\newline
553 \$ git show HEAD:foo
554 }
556 \begin{itemize}
557 \item Commits, Trees, Blobs, Tags
558 \end{itemize}
559 \end{block}
560 }
561 \end{frameframe}
563 \begin{frameframe}{Tags}
564 {\ttfamily
565 \footnotesize
566 \$ git tag -m ``$<$Beschreibung$>$'' $<$Name$>$ $<$Commit$>$\newline
567 \$ git tag -l
568 }
570 \vspace{5mm}
572 \begin{itemize}
573 \item "`Zeiger"' auf einen Commit\newline
574 optional mit Metadaten ("'annotated tag"')
575 \item Kennzeichnung von bestimmten Entwicklungsständen (insb.\ Releases)
576 \item "`annotated tag"': Autor, Datum, Beschreibung, optional GnuPG
577 Signatur
578 \end{itemize}
579 \end{frameframe}
581 \begin{frameframe}{Branching und Merging}
582 \begin{itemize}
583 \item Branch: "`automatischer"' Zeiger auf eine Reihe von Commits
584 \item \texttt{HEAD}: Zeiger auf den aktuellen Branch
585 \item \texttt{master}: "`Standard"'-Branch
586 \item Merge: Zusammenführen von zwei Entwicklungssträngen
587 \end{itemize}
589 \begin{block}{Branch erzeugen}
590 \ttfamily
591 \footnotesize
592 \$ git checkout -b $<$Name$>$
594 \vspace{5mm}
596 \uncover<2>{
597 \$ git branch\newline
598 \hspace*{1em}master\newline
599 * new-branch
600 }
601 \end{block}
602 \end{frameframe}
604 \begin{frameframe}{Branching und Merging}
605 \begin{block}{Branches zusammenführen}
606 \ttfamily
607 \footnotesize
608 \$ git merge master\newline
609 \$ git rebase master
610 \end{block}
612 \uncover<2>{
613 \begin{block}{Konflikte auflösen}
614 \begin{itemize}
615 \item Konflikte entstehen, wenn die gleiche Stelle unterschiedlich
616 geändert wurde\newline
617 $\Rightarrow$ manuelles Eingreifen nötig
618 \item Commit-Erzeugung wird unterbrochen
619 \item Konfliktanzeiger in den betroffenen Dateien
620 \item manuelle Entscheidung, wie beide Änderungen zusammengeführt werden
621 \end{itemize}
622 \end{block}
623 }
624 \end{frameframe}
626 \begin{frameframe}{Arbeiten mit anderen Repositories}
627 \begin{block}{Repository klonen}
628 \ttfamily
629 \footnotesize
630 \$ git clone <rep>
631 \end{block}
633 \begin{block}{Austauschen von Änderungen}
634 {\ttfamily
635 \footnotesize
636 \$ git pull\newline
637 \$ git push
638 }
640 \vspace{5mm}
642 Alternativ:
643 \begin{itemize}
644 \item \texttt{git format-patch}, \texttt{git send-mail}
645 \end{itemize}
646 \end{block}
647 \end{frameframe}
649 \begin{frameframe}{Arbeiten mit anderen Repositories}
650 \begin{itemize}
651 \item "`remote"': Repository, dessen Änderungen verfolgt werden
652 \item "`remote branch"': Branch, welcher der Zustand in einem anderen
653 Repository wiederspiegelt
654 \item technisch: Branch in einem anderen Namensraum mit anderer Semantik
655 \end{itemize}
657 \vspace{5mm}
659 \begin{block}{Arbeiten mit "`remotes"'}
660 \ttfamily
661 \footnotesize
662 \$ git remote add $<$Name$>$ URL\newline
663 \$ git remote update $<$Name$>$
664 \end{block}
665 \end{frameframe}
667 \begin{frameframe}{Repository URLs}
668 \begin{itemize}
669 \item lokal: \texttt{/path/to/repository/}
670 \item http: \texttt{http://domain.tld/repository.git}
671 \item git: \texttt{git://domain.tld/repository.git}
672 \item ssh: \texttt{domain.tld:path/to/repository/}
673 \end{itemize}
674 \end{frameframe}
676 \begin{frameframe}{Frontends}
677 \begin{itemize}
678 \item \texttt{tig} (ncurses)
679 \item \texttt{gitk} (Tk, read-only)
680 \item \texttt{qgit} (Qt)
681 \item \texttt{magit} (emacs)
682 \end{itemize}
683 \end{frameframe}
685 \begin{frameframe}{Goodies}
686 \begin{itemize}
687 \item<+-> \texttt{git reflog}
688 \item<+-> \texttt{git rebase -i}
689 \item<+-> \texttt{git commit --amend}
690 \item<+-> \texttt{git add -p}
691 \item<+-> \texttt{git stash}
692 \item<+-> \texttt{git bisect}
693 \item<+-> \texttt{git cherry} / \texttt{git-wtf}
694 \item<+-> \texttt{git diff color-words}
695 \item<+-> \texttt{git svn}
696 \end{itemize}
697 \end{frameframe}
699 \begin{frameframe}{\insertshorttitle{}}
700 \begin{center}
701 Vielen Dank für die Aufmerksamkeit!
703 \vspace{10mm}
705 {\Large Gibt es Fragen?}
707 \vspace{10mm}
709 Kontakt:\\
710 Sebastian "`tokkee"' Harl\\
711 $<$tokkee@debian.org$>$
712 \end{center}
713 \end{frameframe}
715 \end{document}
717 % vim: set shiftwidth=2 softtabstop=2 tabstop=8 spelllang=de_de :