branching.tex 14 KB
Newer Older
Vermaat's avatar
Vermaat committed
1
2
\documentclass[slidestop]{beamer}

Laros's avatar
Laros committed
3
4
\input{../shared/shared.tex}

Laros's avatar
Laros committed
5
\author{Martijn Vermaat}
Laros's avatar
Laros committed
6
7
\title{\courseTitle}
\providecommand{\mySubTitle}{Working with branches in Git}
Laros's avatar
Laros committed
8
\providecommand{\myConference}{\courseTitle}
Laros's avatar
Laros committed
9
\providecommand{\myGroup}{}
Vermaat's avatar
Vermaat committed
10
11
\providecommand{\myDepartment}{Department of Human Genetics}
\providecommand{\myCenter}{Center for Human and Clinical Genetics}
Laros's avatar
Laros committed
12

Vermaat's avatar
Vermaat committed
13
14
\usetheme{lumc}

Vermaat's avatar
Vermaat committed
15
16
17
18
19
20
21
22
23
24
25
26
\lstset{
  basicstyle=\ttfamily,
  language=none,
  frame=none,
  numbers=none,
  numbersep=0
}

\AtBeginSection[]
{
  \begin{frame}
    \frametitle{Table of contents}
Laros's avatar
Laros committed
27
    \tableofcontents[currentsection, subsectionstyle=hide/hide]
Vermaat's avatar
Vermaat committed
28
29
30
  \end{frame}
}

Vermaat's avatar
Vermaat committed
31
32
33
34
35
36
\begin{document}

% This disables the \pause command, handy in the editing phase.
%\renewcommand{\pause}{}

% Make the title page.
Laros's avatar
Laros committed
37
\makeTitleSlide{\includegraphics[width=3.5cm]{git_logo}}
Vermaat's avatar
Vermaat committed
38

Vermaat's avatar
Vermaat committed
39
\section{The Git commit graph}
Laros's avatar
Laros committed
40
41
42
43
\subsection{A linear history}
\begin{pframe}
  \includegraphics[width=10cm]{linear}
  \smallskip
Vermaat's avatar
Vermaat committed
44

Vermaat's avatar
Vermaat committed
45
  \begin{itemize}
Vermaat's avatar
Vermaat committed
46
47
    \item Every commit has a parent.
    \item {\em Committing} creates a new commit on top of the current one.
Vermaat's avatar
Vermaat committed
48
  \end{itemize}
Laros's avatar
Laros committed
49
50
51
52
53
54
\end{pframe}

\subsection{The default \lstinline{master} branch}
\begin{pframe}
  \includegraphics[width=10cm]{master}
  \smallskip
Vermaat's avatar
Vermaat committed
55

Vermaat's avatar
Vermaat committed
56
  \begin{itemize}
Vermaat's avatar
Vermaat committed
57
    \item A {\em branch} is a pointer to a commit.
Laros's avatar
Laros committed
58
    \item By default there is one branch: \lstinline{master}.
Vermaat's avatar
Vermaat committed
59
  \end{itemize}
Laros's avatar
Laros committed
60
\end{pframe}
Vermaat's avatar
Vermaat committed
61

Laros's avatar
Laros committed
62
63
\subsection{The current commit: \lstinline{HEAD}}
\begin{pframe}
Vermaat's avatar
Vermaat committed
64
  \begin{itemize}
Laros's avatar
Laros committed
65
66
    \item The current commit is called \lstinline{HEAD} (shown in blue here).
    \item \lstinline{HEAD} is actually a pointer to the current branch.
Vermaat's avatar
Vermaat committed
67
68
    \item (Or to the current commit if there is no current branch -- this is
      called detached head state.)
Vermaat's avatar
Vermaat committed
69
  \end{itemize}
Laros's avatar
Laros committed
70
71
72
73
  \bigskip

  \includegraphics[width=10cm]{head}
\end{pframe}
Vermaat's avatar
Vermaat committed
74

Laros's avatar
Laros committed
75
76
\subsection{Committing moves \lstinline{HEAD} and the current branch}
\begin{pframe}
Vermaat's avatar
Vermaat committed
77
  \begin{itemize}
Vermaat's avatar
Vermaat committed
78
    \item Committing moves the current branch to the new commit.
Laros's avatar
Laros committed
79
80
    \item Of course, \lstinline{HEAD} moves with it.
    \item (In detached head state, only \lstinline{HEAD} moves.)
Vermaat's avatar
Vermaat committed
81
  \end{itemize}
Laros's avatar
Laros committed
82
83
84
85
86
87
88
89
90
  \bigskip

  \includegraphics[width=10cm]{commit}
\end{pframe}

\subsection{A non-linear history}
\begin{pframe}
  \includegraphics[width=10cm]{nonlinear}
  \smallskip
Vermaat's avatar
Vermaat committed
91
92

  \begin{itemize}
Vermaat's avatar
Vermaat committed
93
94
    \item The commit graph can become non-linear.
    \item Usually by committing from the same commit twice.
Vermaat's avatar
Vermaat committed
95
  \end{itemize}
Laros's avatar
Laros committed
96
\end{pframe}
Vermaat's avatar
Vermaat committed
97

Laros's avatar
Laros committed
98
99
\subsection{Use branches to keep track of different code paths}
\begin{pframe}
Vermaat's avatar
Vermaat committed
100
  \begin{itemize}
Vermaat's avatar
Vermaat committed
101
102
    \item Branch names are easier to remember than commit hashes.
    \item Branch names make it clear what commits are about.
Vermaat's avatar
Vermaat committed
103
  \end{itemize}
Laros's avatar
Laros committed
104
  \bigskip
Vermaat's avatar
Vermaat committed
105

Laros's avatar
Laros committed
106
107
108
109
110
  \includegraphics[width=6cm]{branches}
\end{pframe}

\subsection{Different code paths may later join}
\begin{pframe}
Vermaat's avatar
Vermaat committed
111
  \begin{itemize}
Vermaat's avatar
Vermaat committed
112
113
    \item Commits from different branches can be brought together.
    \item We call this {\em merging}.
Vermaat's avatar
Vermaat committed
114
  \end{itemize}
Laros's avatar
Laros committed
115
  \bigskip
Vermaat's avatar
Vermaat committed
116

Laros's avatar
Laros committed
117
118
  \includegraphics[width=6cm]{merge}
\end{pframe}
Vermaat's avatar
Vermaat committed
119

Vermaat's avatar
Vermaat committed
120
\section{Inspecting the commit graph}
Laros's avatar
Laros committed
121
122
123
124
\subsection{An example repository}
\begin{pframe}
  \includegraphics[width=8cm]{example}
  \smallskip
Vermaat's avatar
Vermaat committed
125

Vermaat's avatar
Vermaat committed
126
  \begin{itemize}
Laros's avatar
Laros committed
127
128
129
130
131
    \item Branches \lstinline{license} and \lstinline{interface} diverged from
      \lstinline{master}.
    \item Only \lstinline{license} has been merged back into
      \lstinline{master}.
    \item Current branch is \lstinline{master}.
Vermaat's avatar
Vermaat committed
132
  \end{itemize}
Laros's avatar
Laros committed
133
\end{pframe}
Vermaat's avatar
Vermaat committed
134

Laros's avatar
Laros committed
135
136
\subsection{Showing the current branch: \lstinline{git status}}
\begin{pframe}
Vermaat's avatar
Vermaat committed
137
138
139
140
141
142
  \begin{lstlisting}
$ git status
# On branch master
nothing to commit (working directory clean)
  \end{lstlisting}

Laros's avatar
Laros committed
143
144
145
146
147
  Remember: you cannot type \lstinline{git status} enough!
\end{pframe}

\subsection{Listing branches: \lstinline{git branch}}
\begin{pframe}
Vermaat's avatar
Vermaat committed
148
149
150
151
152
153
  \begin{lstlisting}
$ git branch
  interface
  license
* master
  \end{lstlisting}
Laros's avatar
Laros committed
154
155

  Three branches, current branch is \lstinline{master}.
Vermaat's avatar
Vermaat committed
156
  \pause
Laros's avatar
Laros committed
157

Vermaat's avatar
Vermaat committed
158
159
160
161
162
163
164
  \begin{lstlisting}
$ git branch -v
  interface 8fc25c1 Trivial Python interface
  license   0fbe3e3 Add MIT license
* master    c7f3bd9 Add .gitignore file
  \end{lstlisting}

Laros's avatar
Laros committed
165
166
167
168
169
  \lstinline{-v}: Shows the commit each branch points to.
\end{pframe}

\subsection{The commit log: \lstinline{git log}}
\begin{pframe}
Vermaat's avatar
Vermaat committed
170
171
172
173
174
175
176
177
178
  \begin{lstlisting}
$ git log --oneline --decorate
c7f3bd9 (HEAD, master) Add .gitignore file
4a44c4e Merge branch 'license'
64af1ee Add course teachers to README
0fbe3e3 (license) Add MIT license
d1c7fd7 Initial commit with README
  \end{lstlisting}

Laros's avatar
Laros committed
179
180
181
182
  \lstinline{--oneline}: Shows commit summary on one line.

  \lstinline{--decorate}: Adds branch information.
\end{pframe}
Vermaat's avatar
Vermaat committed
183

Laros's avatar
Laros committed
184
185
\subsection{The commit log as a graph: \lstinline{git log}}
\begin{pframe}
Vermaat's avatar
Vermaat committed
186
187
188
189
190
191
192
193
194
195
196
197
198
  \begin{lstlisting}
$ git log --oneline --decorate --graph --all
* 8fc25c1 (interface) Trivial Python interface
| * c7f3bd9 (HEAD, master) Add .gitignore file
|/
*   4a44c4e Merge branch 'license'
|\
| * 0fbe3e3 (license) Add MIT license
* | 64af1ee Add course teachers to README
|/
* d1c7fd7 Initial commit with README
  \end{lstlisting}

Laros's avatar
Laros committed
199
200
201
202
  \lstinline{--graph}: Shows the commit graph.

  \lstinline{--all}: Includes all branches instead of just the current.
\end{pframe}
Vermaat's avatar
Vermaat committed
203

Laros's avatar
Laros committed
204
205
\subsection{Switching to another branch: \lstinline{git checkout}}
\begin{pframe}
Vermaat's avatar
Vermaat committed
206
207
208
209
  \begin{lstlisting}
$ git checkout interface
Switched to branch 'interface'
  \end{lstlisting}
Laros's avatar
Laros committed
210
211

  This points \lstinline{HEAD} to the named branch and updates your working
Vermaat's avatar
Vermaat committed
212
213
  directory.
  \pause
Laros's avatar
Laros committed
214

Vermaat's avatar
Vermaat committed
215
216
217
218
  \begin{lstlisting}
$ git status
# On branch interface
nothing to commit (working directory clean)
Vermaat's avatar
Vermaat committed
219
  \end{lstlisting}
Laros's avatar
Laros committed
220
\end{pframe}
Vermaat's avatar
Vermaat committed
221
222

\section{Manipulating the commit graph}
Laros's avatar
Laros committed
223
224
225
226
\subsection{An example repository}
\begin{pframe}
  \includegraphics[width=8cm]{example}
  \smallskip
Vermaat's avatar
Vermaat committed
227

Vermaat's avatar
Vermaat committed
228
  \begin{itemize}
Laros's avatar
Laros committed
229
230
231
232
233
    \item Branches \lstinline{license} and \lstinline{interface} diverged from
      \lstinline{master}.
    \item Only \lstinline{license} has been merged back into
      \lstinline{master}.
    \item Current branch is \lstinline{master}.
Vermaat's avatar
Vermaat committed
234
  \end{itemize}
Laros's avatar
Laros committed
235
\end{pframe}
Vermaat's avatar
Vermaat committed
236

Laros's avatar
Laros committed
237
238
\subsection{Creating a new branch: \lstinline{git branch}}
\begin{pframe}
Vermaat's avatar
Vermaat committed
239
240
241
  \begin{lstlisting}
$ git branch lib
  \end{lstlisting}
Laros's avatar
Laros committed
242
243

  Creates branch \lstinline{lib} at \lstinline{HEAD}.
Vermaat's avatar
Vermaat committed
244
  \pause
Laros's avatar
Laros committed
245

Vermaat's avatar
Vermaat committed
246
247
248
  \begin{lstlisting}
$ git checkout lib
Switched to branch 'lib'
Vermaat's avatar
Vermaat committed
249
  \end{lstlisting}
Vermaat's avatar
Vermaat committed
250
  \pause
Laros's avatar
Laros committed
251

Vermaat's avatar
Vermaat committed
252
253
254
255
256
  Or, for Git pro's, in one command:
  \begin{lstlisting}
$ git checkout -b lib
Switched to a new branch 'lib'
  \end{lstlisting}
Laros's avatar
Laros committed
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

  At this point, \lstinline{lib} is just a label to the same commit as
  \lstinline{master}.
\end{pframe}

\subsection{Our example repository}
\begin{pframe}
  \includegraphics[width=8cm]{example-branched}
  \smallskip

  Created branch \lstinline{lib} from \lstinline{master}.
\end{pframe}

\subsection{Working on a branch: \lstinline{git commit}}
\begin{pframe}
  We can extend the \lstinline{lib} branch by adding commits.
Vermaat's avatar
Vermaat committed
273
274
275
276
277
278
  \begin{lstlisting}
$ echo 'VERSION=1' > testlib.py
$ git add testlib.py
$ git commit -m 'Add empty testlib'
  \end{lstlisting}
  \pause
Laros's avatar
Laros committed
279

Vermaat's avatar
Vermaat committed
280
281
282
283
284
285
286
287
288
289
290
  \begin{lstlisting}
$ git log --oneline --decorate --graph --all
* 251a51b (HEAD, lib) Add empty testlib
* c7f3bd9 (master) Add .gitignore file
| * 8fc25c1 (interface) Trivial Python interface
|/
*   4a44c4e Merge branch 'license'
|\
| * 0fbe3e3 (license) Add MIT license
...
  \end{lstlisting}
Laros's avatar
Laros committed
291
292
293
294
295
296
297
298
299
300
301
302
303
\end{pframe}

\subsection{Our example repository}
\begin{pframe}
  \includegraphics[width=8cm]{example-committed}
  \smallskip

  Extended branch \lstinline{lib}.
\end{pframe}

\subsection{Fast forward merging: \lstinline{git merge}}
\begin{pframe}
  Let's merge our work on \lstinline{lib} back into \lstinline{master}.
Vermaat's avatar
Vermaat committed
304
305
306
307
308
309
310
311
312
313
  \begin{lstlisting}
$ git checkout master
Switched to branch 'master'
$ git merge lib
Updating c7f3bd9..251a51b
Fast-forward
 testlib.py |    1 +
 1 file changed, 1 insertion(+)
 create mode 100644 testlib.py
  \end{lstlisting}
Laros's avatar
Laros committed
314

Vermaat's avatar
Vermaat committed
315
  This merge was easy:
Vermaat's avatar
Vermaat committed
316
  \begin{itemize}
Laros's avatar
Laros committed
317
318
319
    \item \lstinline{lib} was directly upstream of \lstinline{master}.
    \item Git just moves \lstinline{HEAD} and \lstinline{master} to point to
      \lstinline{lib}.
Vermaat's avatar
Vermaat committed
320
    \item This is called a {\em fast forward merge}.
Vermaat's avatar
Vermaat committed
321
  \end{itemize}
Laros's avatar
Laros committed
322
323
324
325
326
327
328
329
330
331
332
333
334
\end{pframe}

\subsection{Our example repository}
\begin{pframe}
  \includegraphics[width=8cm]{example-merged-ff}
  \smallskip

  Merged branch \lstinline{lib} into \lstinline{master} (fast forward).
\end{pframe}

\subsection{Three-way merging: \lstinline{git merge}}
\begin{pframe}
  Let's merge our work on \lstinline{interface} back into \lstinline{master}.
Vermaat's avatar
Vermaat committed
335
336
337
338
339
340
341
  \begin{lstlisting}
$ git merge interface
Merge made by the 'recursive' strategy.
 interface.py |    3 +++
 1 file changed, 3 insertions(+)
 create mode 100755 interface.py
  \end{lstlisting}
Laros's avatar
Laros committed
342
343
  \vspace{-0.25cm}

Vermaat's avatar
Vermaat committed
344
345
  This merge was harder:
  \begin{itemize}
Laros's avatar
Laros committed
346
347
348
349
    \item \lstinline{interface} and \lstinline{master} had diverged.
    \item Git determines changes in \lstinline{interface} and
      \lstinline{master} since their most recent common ancestor and creates a
      new commit from that.
Vermaat's avatar
Vermaat committed
350
351
352
    \item This is called a {\em recursive three-way merge} and the resulting
      merge a {\em merge commit}.
  \end{itemize}
Laros's avatar
Laros committed
353
354
355
356
357
358
\end{pframe}

\subsection{Our example repository}
\begin{pframe}
  \includegraphics[width=8cm]{example-merged}
  \smallskip
Vermaat's avatar
Vermaat committed
359

Laros's avatar
Laros committed
360
361
  Merged branch \lstinline{interface} into \lstinline{master}.
\end{pframe}
Vermaat's avatar
Vermaat committed
362

Laros's avatar
Laros committed
363
364
\subsection{Deleting branches: \lstinline{git branch}}
\begin{pframe}
Vermaat's avatar
Vermaat committed
365
366
367
368
369
  Old branches that have been merged can be deleted.
  \begin{lstlisting}
$ git branch -d interface
Deleted branch interface (was 8fc25c1).
  \end{lstlisting}
Laros's avatar
Laros committed
370

Vermaat's avatar
Vermaat committed
371
372
373
374
375
376
  \begin{lstlisting}
$ git branch -d lib license
Deleted branch lib (was 251a51b).
Deleted branch license (was 0fbe3e3).
  \end{lstlisting}

Laros's avatar
Laros committed
377
378
  No history is lost, just labels removed.
\end{pframe}
Vermaat's avatar
Vermaat committed
379

Vermaat's avatar
Vermaat committed
380
\section{Basic merge conflicts}
Laros's avatar
Laros committed
381
382
\subsection{Merge conflicts}
\begin{pframe}
Vermaat's avatar
Vermaat committed
383
384
385
386
387
388
389
  Git is pretty good at merging:
  \begin{itemize}
    \item The changes might have been in different files.
    \item Or in different parts of the same file.
    \item Git tries to figure out a sensible result.
  \end{itemize}
  \bigskip
Laros's avatar
Laros committed
390
391
  \pause

Vermaat's avatar
Vermaat committed
392
393
394
  Sometimes this is not possible:
  \begin{itemize}
    \item The changes might be incompatible.
Laros's avatar
Laros committed
395
    \item When we try \lstinline{git merge}, Git gives up.
Vermaat's avatar
Vermaat committed
396
397
    \item This situation is called a {\em merge conflict}.
  \end{itemize}
Laros's avatar
Laros committed
398
\end{pframe}
Vermaat's avatar
Vermaat committed
399

Laros's avatar
Laros committed
400
401
\subsection{Setting the stage (1/3)}
\begin{pframe}
Vermaat's avatar
Vermaat committed
402
403
404
405
406
407
408
409
  \begin{lstlisting}
$ git log --oneline --decorate --graph --all
* 9d2ad27 (HEAD, master) State character preference
| * 374ab60 (simpsons) State character preference
|/
* 4012f4f Initial commit
  \end{lstlisting}

Laros's avatar
Laros committed
410
411
412
413
414
415
  We'd like to merge branch \lstinline{simpsons} into \lstinline{master}.
\end{pframe}

\subsection{Setting the stage (2/3)}
\begin{pframe}
  The last commit on \lstinline{master}:
Vermaat's avatar
Vermaat committed
416
417
418
419
420
421
422
423
424
425
426
427
428
  \begin{lstlisting}
$ git show --oneline
9d2ad27 State character preference
diff --git a/README b/README
index de15194..ef40359 100644
--- a/README
+++ b/README
@@ -1,2 +1,4 @@
 Facts about television series
 =============================
+
+My favorite character is Eric Cartman.
  \end{lstlisting}
Laros's avatar
Laros committed
429
\end{pframe}
Vermaat's avatar
Vermaat committed
430

Laros's avatar
Laros committed
431
432
433
\subsection{Setting the stage (3/3)}
\begin{pframe}
  The last commit on \lstinline{simpsons}:
Vermaat's avatar
Vermaat committed
434
435
436
437
438
439
440
441
442
443
444
445
446
  \begin{lstlisting}
$ git show --oneline simpsons
374ab60 State character preference
diff --git a/README b/README
index de15194..9dd729b 100644
--- a/README
+++ b/README
@@ -1,2 +1,4 @@
 Facts about television series
 =============================
+
+My favorite character is Homer Simpson.
  \end{lstlisting}
Laros's avatar
Laros committed
447
\end{pframe}
Vermaat's avatar
Vermaat committed
448

Laros's avatar
Laros committed
449
450
451
\subsection{Creating a merge conflict}
\begin{pframe}
  \vspace{-0.5cm}
Vermaat's avatar
Vermaat committed
452
453
454
455
456
457
  \begin{lstlisting}
$ git merge simpsons
Auto-merging README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then
commit the result.
Laros's avatar
Laros committed
458

Vermaat's avatar
Vermaat committed
459
460
461
462
463
464
465
466
467
468
469
$ git status
# On branch master
# Unmerged paths:
#   (use "git add/rm <file>.." as appropriate to
#    mark resolution)
#
#              both modified:      README
#
no changes added to commit (use "git add" and/or
"git commit -a")
  \end{lstlisting}
Laros's avatar
Laros committed
470
\end{pframe}
Vermaat's avatar
Vermaat committed
471

Laros's avatar
Laros committed
472
473
\subsection{Resolving a merge conflict (1/2)}
\begin{pframe}
Vermaat's avatar
Vermaat committed
474
475
476
477
478
479
480
481
482
483
484
  \begin{lstlisting}
$ cat README
Facts about television series
=============================

<<<<<<< HEAD
My favorite character is Eric Cartman.
=======
My favorite character is Homer Simpson.
>>>>>>> simpsons
  \end{lstlisting}
Laros's avatar
Laros committed
485
486
487

  What we had is under \lstinline{HEAD}, what \lstinline{simpsons} had is above
  \lstinline{simpsons}.
Vermaat's avatar
Vermaat committed
488
  \pause
Laros's avatar
Laros committed
489

Vermaat's avatar
Vermaat committed
490
491
492
  \begin{lstlisting}
$ emacs README
  \end{lstlisting}
Laros's avatar
Laros committed
493
\end{pframe}
Vermaat's avatar
Vermaat committed
494

Laros's avatar
Laros committed
495
496
\subsection{Resolving a merge conflict (2/2)}
\begin{pframe}
Vermaat's avatar
Vermaat committed
497
498
499
500
501
502
503
504
505
506
  We resolve the conflict by hand.
  \begin{lstlisting}
$ cat README
Facts about television series
=============================

My favorite characters are Eric Cartman
and Homer Simpson.
  \end{lstlisting}
  \pause
Laros's avatar
Laros committed
507

Vermaat's avatar
Vermaat committed
508
509
510
511
512
513
  And can now finish the merge commit.
  \begin{lstlisting}
$ git add README
$ git commit
[master 1e496cb] Merge branch 'simpsons'
  \end{lstlisting}
Laros's avatar
Laros committed
514
\end{pframe}
Vermaat's avatar
Vermaat committed
515

Laros's avatar
Laros committed
516
517
\subsection{Aborting a merge}
\begin{pframe}
Vermaat's avatar
Vermaat committed
518
  If you don't feel like resolving the merge conflict, you can go back with
Laros's avatar
Laros committed
519
  \lstinline{git merge --abort}.
Vermaat's avatar
Vermaat committed
520
521
522
523
524
525
526
  \begin{lstlisting}
$ git merge simpsons
Auto-merging README
CONFLICT (content): Merge conflict in README
Automatic merge failed; fix conflicts and then
commit the result.
  \end{lstlisting}
Laros's avatar
Laros committed
527

Vermaat's avatar
Vermaat committed
528
529
530
  \begin{lstlisting}
$ git merge --abort
  \end{lstlisting}
Laros's avatar
Laros committed
531

Vermaat's avatar
Vermaat committed
532
533
534
535
536
  \begin{lstlisting}
$ git status
# On branch master
nothing to commit (working directory clean)
  \end{lstlisting}
Laros's avatar
Laros committed
537
\end{pframe}
Vermaat's avatar
Vermaat committed
538

Laros's avatar
Laros committed
539
540
\subsection{Resolving conflicts with \lstinline{git mergetool}}
\begin{pframe}
Vermaat's avatar
Vermaat committed
541
542
543
544
545
546
547
548
549
550
551
552
  We can also use graphical merge tools such as {\em Meld}.
  \begin{lstlisting}
$ git mergetool
merge tool candidates: meld opendiff kdiff3 ...
Merging:
README

Normal merge conflict for 'README':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (meld):
  \end{lstlisting}
Laros's avatar
Laros committed
553
\end{pframe}
Vermaat's avatar
Vermaat committed
554

Laros's avatar
Laros committed
555
556
557
558
\subsection{Meld example}
\begin{pframe}
  \includegraphics[width=11cm]{meld}
  \smallskip
Vermaat's avatar
Vermaat committed
559

Laros's avatar
Laros committed
560
561
  Tools like Meld provide an editable three-way diff.
\end{pframe}
Vermaat's avatar
Vermaat committed
562

Laros's avatar
Laros committed
563
564
565
566
567
\makeAcknowledgementsSlide{
  \begin{tabular}{l}
    \acknowledgements
  \end{tabular}
  \bigskip
Vermaat's avatar
Vermaat committed
568

Laros's avatar
Laros committed
569
  \hfill\includegraphics[width=3.5cm]{git_logo}
Vermaat's avatar
Vermaat committed
570

Laros's avatar
Laros committed
571
572
573
574
575
  \begin{tabular}{l}
    \small\url{http://git-scm.com/book}\\
    \small\url{https://www.atlassian.com/git}
  \end{tabular}
}
Vermaat's avatar
Vermaat committed
576
577

\end{document}