%&git
\begin{document}
\begin{frame}
	\titlepage
\end{frame}

\section{What is GIT}
\subsection{Who am I?}
\begin{frame}
	\frametitle{Who am I?}
	\begin{itemize}
		\item Mart Lubbers
		\item Bachelors in Artificial Intelligence
		\item 1th year master Software science
		\item
			{\tiny\url{https://ygdrassil.martlubbers.net/git/gitflashtalk.git}}
		\item SHA of the commit of this presentation:
			{\tiny\GITAbrHash}
	\end{itemize}
\end{frame}

\subsection{What is git}
\begin{frame}
	\frametitle{History of version control}
	\begin{block}{What is version control?}
		\begin{itemize}
			\item Text files
			\item Collaboration
			\item Possibly centralized or distributed
		\end{itemize}
	\end{block}

	\begin{block}{History}
		\begin{tabular}{lllp{6em}l}
			\toprule
			Gen & Networking & Operations & Concurrency & Examples\\
			\midrule
			1 & None & One file & Locks & RCS, SCSS\\
			2 & Centralized & Multi-file & Merge before commit & CVS, SVN\\
			3 & Distributed & Changeset & Commit before merge &
				Git, Mercurial\\
			\bottomrule
		\end{tabular}
		{\tiny Table from \url{%
			http://ericsink.com/vcbe/html/history_of_version_control.html}}
	\end{block}
\end{frame}

\begin{frame}[fragile]
	\frametitle{What is Git}
	\begin{block}{Origins}
		\begin{itemize}
			\item Pronounce: \textipa{[g\'\i t]}
			\item 2005 because \textit{Bitkeeper} changed terms
			\item Linux kernel
		\end{itemize}
	\end{block}

	\begin{block}{Initial \texttt{readme} from 2005}
		\begin{minted}{text}
	GIT - the stupid content tracker

"git" can mean anything, depending on your mood.

 - random three-letter combination that is pronounceable, and not
   actually used by any common UNIX command.  The fact that it is a
   mispronounciation of "get" may or may not be relevant.
 - stupid. contemptible and despicable. simple. Take your pick from the
   dictionary of slang.
 - "global information tracker": you're in a good mood, and it actually
   works for you. Angels sing, and a light suddenly fills the room.
 - "goddamn idiotic truckload of sh*t": when it breaks
		\end{minted}
	\end{block}
\end{frame}

\begin{frame}
	\frametitle{Why Git?}
	\begin{block}{Pros}
		\begin{itemize}
			\item Fast
			\item Scaleable
			\item Simple
			\item Support for non linear development
			\item Intermediate stage between committing and pushing
		\end{itemize}
	\end{block}

	\begin{block}{Cons}
		\begin{itemize}
			\item Binary files
			\item Intermediate stage between committing and pushing
		\end{itemize}
	\end{block}
\end{frame}

\begin{frame}
	\frametitle{Before we start}
	\pause
	\huge Git is not Github
\end{frame}

\section{Introduction}
\subsection{Installation}
\begin{frame}[fragile]
	\begin{block}{{\Large\Smiley\Smiley} Linux}
		Depending on the distribution you may have to do:\\
		\mint{console}{# apt-get install git}
		\mint{console}{# pacman -S git}
		\mint{console}{# yum install git}
		\mint{console}{# emerge --ask dev-vcs/git}
		Etc\ldots
	\end{block}

	\begin{block}{{\Large\Frowny\Smiley} Mac}
		Install via XCode tools. Just run \mintinline{console}{|\$| git} and
		when Git is not installed it will prompt you with instructions.
	\end{block}

	\begin{block}{{\Large\Frowny\Frowny} Windows}
		Downoad the binary from \url{http://git-scm.com/download/win} and
		install.
	\end{block}
\end{frame}

\begin{frame}[fragile]
	\begin{block}{Linux/Mac}
		\begin{itemize}
			\item[Step 1.] Open your favourite terminal.
			\item[Step 2.]
				\begin{minted}{console}
|\$| git --version
git version 2.7.2
				\end{minted}
		\end{itemize}
	\end{block}

	\begin{block}{Windows}
		\begin{itemize}
			\item[Step 1.] Open \texttt{git-bash}. \texttt{git-bash} is a UNIX
				like environment with all the necessary tools.
			\item[Step 2.]
				\begin{minted}{console}
frobnicator@frobmachine MINGW64 ~
|\$| git --version
git version 2.7.2.windows.1
				\end{minted}
		\end{itemize}
	\end{block}
\end{frame}

\subsection{Repositories}
\begin{frame}[fragile]
	\frametitle{Create your first repository}
	\begin{block}{Command}
		\begin{minted}{console}
|\$| cd projects
|\$| git init myfirstproject
Initialized empty Git repository in /home/frobnicator/projects/myfirstproject/.git/
		\end{minted}
	\end{block}

	\begin{block}{Filesystem}
		\begin{minted}{console}
|\$| ls -a myfirstproject
.  ..  .git
|\$| ls myfirstproject/.git
branches  config  description  HEAD  hooks  info  objects  refs
		\end{minted}
	\end{block}
\end{frame}

\subsection{Workflow}
\begin{frame}
	\frametitle{Four (five) stages}
	\begin{itemize}
		\item (Stash)
		\item Workspace
		\item Index
		\item Local repo
		\item Upstream repo
	\end{itemize}
\end{frame}

\begin{frame}
	\frametitle{Connect the stages}
	\includegraphics[width=\linewidth]{workflow.png}
\end{frame}

\section{Local}
\begin{frame}
	\frametitle{Everything is a commit}
	\begin{block}{Forget what you have learned. These things are commits:}
		\begin{itemize}
			\item commit
			\item tag
			\item branch
			\item \texttt{HEAD}
		\end{itemize}
	\end{block}
	\begin{block}{Commits are structured in a tree}
	\end{block}
	\pause
	\begin{block}{From now on: Tag along}
	\end{block}
\end{frame}

\subsection{Add \& Commit}
\begin{frame}[fragile]
	\frametitle{Add (1)}
	\begin{block}{Command}
		\mintinline{bash}{git add [opts] [<pathspec>...]}
	\end{block}
	\begin{block}{Example: Shopping list}
		\begin{minted}{console}
|\$| git init shoppinglist
Initialized empty Git repository in
	/home/frobnicator/projects/shoppinglist/.git/
|\$| cd shoppinglist/
|\$| echo "milk" > shopping.txt
|\$| echo "eggs" >> shopping.txt
|\$| echo "ham" >> shopping.txt
|\$| cat shopping.txt
milk
eggs
ham
		\end{minted}
	\end{block}
	\begin{block}{Where is the data?}
		\pause
		Workspace
	\end{block}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Add (2)}
	\begin{minted}{console}
|\$| git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

  	shopping.txt

nothing added to commit but untracked files present (use "git add" to track)
|\$| git add shopping.txt #git add .
|\$| git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

  	new file:   shopping.txt
	\end{minted}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Commit (1)}
	\begin{minted}{console}
|\$| export EDITOR=vim # nano, emacs, ed, ex, etc...
|\$| git commit        # Editor opens

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
#
# Initial commit
#
# Changes to be committed:
#	new file:   shopping.txt
#
[master (root-commit) ae90376] Initial shopping list
 1 file changed, 3 insertions(+)
 create mode 100644 shopping.txt
	\end{minted}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Commit (2)}
	\begin{block}{Results}
		\begin{minted}{console}
|\$| git status
On branch master
nothing to commit, working directory clean
|\$| ls -a
.  ..  .git  shopping.txt
		\end{minted}
	\end{block}

	\begin{block}{Where is the data}
		\pause
		Workspace + Local repository
	\end{block}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Add \& Commit some more}
	\begin{block}{We forgot the bread!}
		\begin{minted}{console}
|\$| echo "Bread" >> shopping.txt
|\$| git add .
|\$| git commit -m "We forgot the bread, oops"
[master 8cb1d9b] We forgot the bread, oops
 1 file changed, 1 insertion(+)
 		\end{minted}
	\end{block}

	\begin{block}{Even quicker, let's add beer}
		\begin{minted}{console}
|\$| echo "Grolsch" >> shopping.txt
|\$| git commit -am "Beer added"
[master 99d65a3] Beer added
 1 file changed, 1 insertion(+)
 		\end{minted}
	\end{block}
\end{frame}

\subsection{Administration}
\begin{frame}[fragile]
	\frametitle{Log}
	\begin{minted}{console}
|\$| git log
commit 99d65a34c02f5766ffa8e04b7c7121dfe41136ec
Author: Frob Nicator <frob@nicat.or>
Date:   Tue Mar 15 19:15:05 2016 +0100

    Beer added

commit 8cb1d9bf8e4b45355b38600367a841fe9ceaae40
Author: Frob Nicator <frob@nicat.or>
Date:   Tue Mar 15 19:13:55 2016 +0100

    We forgot the bread, oops

commit ae903769895cbb7c24b096e17049d20a8456953c
Author: Frob Nicator <frob@nicat.or>
Date:   Tue Mar 15 19:04:40 2016 +0100

    Initial shopping list
	\end{minted}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Checkout (1)}
	\begin{minted}{console}
|\$| git log --oneline --decorate --graph --all
* 99d65a3 (HEAD, master) Beer added
* 8cb1d9b We forgot the bread, oops
* ae90376 Initial shopping list
|\$| cat shopping.txt
milk
eggs
ham
Bread
Grolsch
|\$| git checkout ae90376
Note: checking out 'ae90376'.

... # long error about detached head state

HEAD is now at ae90376... Initial shopping list
	\end{minted}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Checkout (2)}
	\begin{minted}{console}
|\$| git log --oneline --decorate --graph --all
* 99d65a3 (master) Beer added
* 8cb1d9b We forgot the bread, oops
* ae90376 (HEAD) Initial shopping list
|\$| cat shopping.txt   # We got our old shopping list back!
milk
eggs
ham
|\$| git checkout master # or 99d65a3
Previous HEAD position was ae90376... Initial shopping list
Switched to branch 'master'
|\$| git log --oneline --decorate --graph --all
* 99d65a3 (HEAD, master) Beer added
* 8cb1d9b We forgot the bread, oops
* ae90376 Initial shopping list
	\end{minted}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Differences (1)}
	\begin{block}{Behaviour}
		\begin{itemize}
			\item\mintinline{console}{git diff HASH}\\
				Compare index to said hash
			\item\mintinline{console}{git diff HASH1 HASH2}\\
				Compare the hashes
		\end{itemize}
	\end{block}

	\begin{minted}{console}
|\$| git diff ae90376
diff --git a/shopping.txt b/shopping.txt
index 1e19791..c41e7e5 100644
--- a/shopping.txt
+++ b/shopping.txt
@@ -1,3 +1,5 @@
milk
eggs
ham
+Bread
+Grolsch
	\end{minted}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Differences (2)}
	\begin{minted}{console}
|\$| git diff master
|\$| vi shopping.txt # remove bread
|\$| git diff master
diff --git a/shopping.txt b/shopping.txt
index c41e7e5..47c3623 100644
--- a/shopping.txt
+++ b/shopping.txt
@@ -1,5 +1,4 @@
 milk
 eggs
 ham
-Bread
 Grolsch
	\end{minted}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Oops we didn't want to remove the bread}
	\begin{minted}[escapeinside=]{console}
$ git stash
Saved working directory and index state WIP on master: 99d65a3 Beer added
HEAD is now at 99d65a3 Beer added
$ git log --oneline --decorate --graph --all
*   2c395dd (refs/stash) WIP on master: 99d65a3 Beer added
|\  
| * 149d864 index on master: 99d65a3 Beer added
|/  
* 99d65a3 (HEAD, master) Beer added
* 8cb1d9b We forgot the bread, oops
* ae90376 Initial shopping list
	\end{minted}
	\begin{block}{Stash}
		This is material for an advanced git course.\\
		Just remember you can checkout all hashes.
	\end{block}
\end{frame}

\subsection{Branching}
\begin{frame}[fragile]
	\frametitle{Branching}
	\begin{block}{Let's start from scratch}
		\begin{minted}{console}
|\$| git rm shopping.txt
rm 'shopping.txt'
|\$| echo -e "ham\nmilk\neggs" > list.txt
|\$| git add .
|\$| git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

  	renamed:    shopping.txt -> list.txt
		\end{minted}
	\end{block}
	\pause
	\begin{block}{Wait a minute, we removed that...}
		\begin{minted}{console}
|\$| git commit -m "Start from scratch"
[master 33dff03] Start from scratch
 1 file changed, 1 insertion(+), 3 deletions(-)
 rename shopping.txt => list.txt (50%)
  		\end{minted}
	\end{block}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Branching \& Merging (1) }
	\begin{minted}[escapeinside=]{console}
$ git checkout -b vega # or git branch vega; git checkout vega
$ vi list.txt          # change ham to tofu, add beans
$ cat list.txt
tofu
milk
eggs
beans
$ git commit -am "Added tofu and beans"
[vega e74256e] Added tofu and beans
 1 file changed, 2 insertions(+), 1 deletion(-)
$ git log --oneline --decorate --graph --all
* e74256e (HEAD, vega) Added tofu and beans
* 33dff03 (master) Start from scratch
| *   2c395dd (refs/stash) WIP on master: 99d65a3 Beer added
| |\  
|/ /  
| * 149d864 index on master: 99d65a3 Beer added
|/  
* 99d65a3 Beer added
* 8cb1d9b We forgot the bread, oops
* ae90376 Initial shopping list
	\end{minted}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Branching \& Merging (2) }
	\begin{minted}[escapeinside=]{console}
$ git checkout master
$ cat list.txt
ham
milk
eggs
$ git log --oneline --decorate --graph --all
* e74256e (vega) Added tofu and beans
* 33dff03 (HEAD, master) Start from scratch
| *   2c395dd (refs/stash) WIP on master: 99d65a3 Beer added
| |\  
|/ /  
| * 149d864 index on master: 99d65a3 Beer added
|/  
* 99d65a3 Beer added
* 8cb1d9b We forgot the bread, oops
* ae90376 Initial shopping list
	\end{minted}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Branching \& Merging (2) }
	\begin{minted}[escapeinside=]{console}
$ vi list.txt          # change ham to cheese
$ cat list.txt
cheese
milk
eggs
$ git commit -am "Change ham to cheese"
[master a77f1e5] Change ham to cheese
 1 file changed, 1 insertion(+), 1 deletion(-)
$ git log --oneline --decorate --graph --all
* a77f1e5 (HEAD, master) Change ham to cheese
| * e74256e (vega) Added tofu and beans
|/  
* 33dff03 Start from scratch
| *   2c395dd (refs/stash) WIP on master: 99d65a3 Beer added
| |\  
|/ /  
| * 149d864 index on master: 99d65a3 Beer added
|/  
* 99d65a3 Beer added
* 8cb1d9b We forgot the bread, oops
* ae90376 Initial shopping list
	\end{minted}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Merging (1)}
	\begin{block}{Noes, conflicts}
		\begin{minted}{console}
|\$| git merge vega
Auto-merging list.txt
CONFLICT (content): Merge conflict in list.txt
Automatic merge failed; fix conflicts and then commit the result.
		\end{minted}
	\end{block}
	\begin{block}{Contents of \texttt{list.txt}}
		\begin{minted}{text}
<<<<<<< HEAD
cheese
=======
tofu
>>>>>>> vega
milk
eggs
beans
		\end{minted}
	\end{block}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Merging (2)}
	\begin{block}{Resolving merge conflicts}
		\begin{itemize}
			\item Open all files listed
			\item Remove all \texttt{<<<<< \ldots} and \texttt{>>>> \ldots}
		\end{itemize}
	\end{block}
	\begin{block}{Contents of commit when you have done that}
		\begin{minted}{console}
Merge branch 'vega'

Conflicts:
	list.txt
# ... 

# ...
# On branch master
# All conflicts fixed but you are still merging.
#
# Changes to be committed:
#	modified:   list.txt
#
		\end{minted}
	\end{block}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Merging (3)}
	\begin{block}{And done!}
		\begin{minted}[escapeinside=]{console}
$ git commit -a
[master 10a9e9e] Merge branch 'vega'
$ git tree
*   10a9e9e (HEAD, master) Merge branch 'vega'
|\  
| * e74256e (vega) Added tofu and beans
* | a77f1e5 Change ham to cheese
|/  
* 33dff03 Start from scratch
| *   2c395dd (refs/stash) WIP on master: 99d65a3 Beer added
| |\  
|/ /  
| * 149d864 index on master: 99d65a3 Beer added
|/  
* 99d65a3 Beer added
* 8cb1d9b We forgot the bread, oops
* ae90376 Initial shopping list
		\end{minted}
	\end{block}
\end{frame}

\subsection{Notes}
\begin{frame}
	\frametitle{Some notes}
	\begin{itemize}
		\item Make short commits, per feature
		\item Try to only commit working code
		\item No generatable stuff in the repo
		\item Commit messages formatten:
			\begin{itemize}
				\item 72 Chars title
				\item Enter, Enter
				\item Body of the message in \emph{Imperative Present Tense}
					\emph{change}, not \emph{changed} or \emph{changes}
			\end{itemize}
		\item Master contains only major releases
		\item Develop contains development release
		\item Feature branches
	\end{itemize}
\end{frame}

\section{Remote}
\begin{frame}
	\frametitle{Clone (1)}
	\begin{itemize}
		\item Github(you can get 5 free repos via student mail)
		\item BitBucket
		\item Gitlab(runs on science servers)
		\item \mintinline{console}{git clone CLONEURL}
	\end{itemize}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Clone (2)}
	\begin{block}{Clone}
		\begin{minted}{console}
|\$| git clone https://github.com/githubuser/reponame # With optional folder
Cloning into 'reponame'...
remote: Counting objects: 44, done.
remote: Total 44 (delta 0), reused 0 (delta 0), pack-reused 44
Unpacking objects: 100% (44/44), done.
Checking connectivity... done.
		\end{minted}
	\end{block}
\end{frame}

\begin{frame}[fragile]
	\frametitle{Push \& Pull}
	\begin{block}{Pull}
		Basically a merge of the remote branch with your \texttt{HEAD}. This
		can lead to merge conflict. Only pull when you have committed
		everything.
		\begin{minted}{console}
|\$| git pull origin BRANCHNAME
		\end{minted}
	\end{block}

	\begin{block}{Push}
		Push your changes to the remote. You have to pull first.
		\begin{minted}{console}
|\$| git push origin BRANCHNAME
		\end{minted}
	\end{block}
\end{frame}

\begin{frame}
	\frametitle{Add your shopping list to the repo!}
	\begin{block}{List your username and I'll give you write access}
		\url{https://github.com/dopefishh/gitworkshop}
	\end{block}
\end{frame}

\begin{frame}
	\frametitle{Tags}
	\begin{itemize}
		\item \mintinline{console}{git tag TAGNAME}
		\item Github interprets them as releases
		\item Easy for releases
		\item Literally a named commit
		\item Push only tags:
			\mintinline{console}{git push --tags origin master}
	\end{itemize}
\end{frame}


\section{Post scriptum}
\subsection{Questions \& Conclusion}
\begin{frame}
	\frametitle{Questions}
	\begin{center}{\Huge?}\end{center}
	\pause
	\begin{block}{If you want to be an expert}
		Read: \emph{Git from the bottom up}~\footnote{\url{%
		http://ftp.newartisans.com/pub/git.from.bottom.up.pdf}}
	\end{block}
\end{frame}

\subsection{Aliasing}
\begin{frame}[fragile]
	\frametitle{Aliasing}
	\begin{minted}{console}
|\$| cat ~/.gitconfig
[user]
name = Frob Nicator
email = frob@nicat.or

[alias]
tree = log --decorate --oneline --graph --all
pushm = push origin master
pushd = push origin develop
|\$| git tree
	\end{minted}
\end{frame}

\subsection{Gitignore}
\begin{frame}[fragile]
	\frametitle{Ignore certain files}
	\begin{minted}{console}
|\$| cat ~/projects/somelatexproject/.gitignore
*.aux
*.fmt
*.log
*.out
*.pdf
	\end{minted}
\end{frame}

\subsection{What is the difference betweeen all the clone urls?}
\begin{frame}
	\frametitle{SSH or HTTPS}
	\begin{itemize}
		\item SSH preferred over HTTPS due to security issues
		\item SSH saves you from entering the password all the time
		\item For a how-to about setting up SSH checkout the github tutorial
		\item HTTPS easy for onetime checkout
	\end{itemize}
\end{frame}

\subsection{Host your own git server}
\begin{frame}[fragile]
	\frametitle{Host your own git server}
	\begin{block}{SSH (Easy)}
		\begin{minted}{console}
# adduser --shell /usr/bin/git-shell git}
# su git -s /bin/bash
|\$| mkdir .ssh
|\$| chmod 700 .ssh
|\$| touch .ssh/authorized_keys # Put public keys in here
|\$| chmod 600 .ssh/*
|\$| git init --bare newrepo.git
		\end{minted}
	\end{block}

	\begin{block}{HTTP webinterface (Medium)}
		GitList\footnote{\url{http://gitlist.org/}}
		This presentation:
		{\tiny\url{https://ygdrassil.martlubbers.net/git/ai-gitworkshop.git/}}
	\end{block}

	\begin{block}{HTTP+SSH (Hard)}
		GitLab\footnote{\url{gitlab.com}}
	\end{block}
\end{frame}

\end{document}
