% ----------------------------
\subsection{Git Basics}

% ----------------------------
\begin{frame}[fragile]{What is Git?}
\begin{itemize}
\item version control system (VCS)
\item snapshot store (no diffs)
\item fully distributed
\item full local history
\item optimized for non-linear development
\item measured code integrity (Merkle-Tree)
\end{itemize}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Components I}
\begin{itemize}
\item Working Tree
 \begin{itemize}
 \item all files of a snapshot
 \item checkout of a commit history (branch, tag, detached)
 \end{itemize}
\item Staging Area
 \begin{itemize}
 \item preparation for commit
 \item Working Tree -> Staging Area -> Commit
 \end{itemize}
\item Commit
 \begin{itemize}
 \item ID: unique identifier
 \item changeset with description
 \end{itemize}
\item Branch
 \begin{itemize}
 \item Local: separate list of commits
 \item Remote: pointer to a commit
 \end{itemize}
\end{itemize}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Components II}
\begin{itemize}
\item Tags
 \begin{itemize}
 \item reference to a commit ID
 \item annotated: with own description
 \end{itemize}
\item Objects
 \begin{itemize}
 \item storage containers
 \item hashed versions of files
 \end{itemize}
\item HEAD
 \begin{itemize}
 \item pointer to top-level commit of branch or working tree
 \end{itemize}
\item Stash
 \begin{itemize}
 \item store for non-committed changes
 \end{itemize}
\end{itemize}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Collaboration}
\begin{itemize}
\item pull/push changes from/to other repositories
\item between local user repositories (file-system)
\item web-server based repositories (read-only)
\item user access control (e.g. with git or ssh)
\item protocols
 \begin{itemize}
 \item \texttt{file://}
 \item \texttt{http://}
 \item \texttt{https://}
 \item \texttt{git://}
 \item \texttt{ssh://}
 \item etc.
 \end{itemize}
\end{itemize}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{File States in Working Tree}
\begin{figure}[h]
\centering
\includegraphics[width=8cm]{images/git_file_states.png}
\end{figure}
\end{frame}

% ----------------------------
\subsection{Best Practice}

% ----------------------------
\begin{frame}[fragile]{General Guidelines}
\begin{itemize}
\item use local repositories (also keep track of small, local projects)
\item commit functional changes
\item split commits into separate, functional entities
\item separate branch for feature
\item push frequently to remote repositories
\item write significant commit messages
 \begin{itemize}
 \item problem/motivation
 \item problem context
 \item fix/feature description
 \item use commit ID to refer to other commits
 \end{itemize}
\end{itemize}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Bad Commit Messages}
\begin{itemize}
\item non-existing commit message
\item mix functional changes
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Bad Example I}
\begin{scriptsize}
\begin{verbatim}
commit 009e0d048028f2265555aeb1575b495f0cb4da9c
Author: Holger Dengler <dengler@linutronix.de>
Date:   Mon Feb 26 13:00:00 2018 +0100

    fix
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\begin{beamerboxesrounded}[shadow=true]{Bad Example II}
\begin{scriptsize}
\begin{verbatim}
commit 8ca31a793d9805a12304f85ae0a063e4c7dac4b0
Author: root <root@build.local>
Date:   Fri Feb 23 16:00:00 2018 +0100

    Various fixes of this week, still work in progress. TGIF and
    have a nice weekend!

\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Better Commit Messages}
\begin{beamerboxesrounded}[shadow=true]{Bad Example}
\begin{scriptsize}
\begin{verbatim}
commit 03f5942e8d9ae7bad608a9bcda8067f2f40f7840 (HEAD -> master)
Author: Holger Dengler <dengler@linutronix.de>
Date:   Mon Feb 26 13:00:00 2018 +0100

    Initialize the XYZ Control Register with 0x15. This resolves the hang
    during boot on my device.
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\begin{beamerboxesrounded}[shadow=true]{Better Example}
\begin{scriptsize}
\begin{verbatim}
commit 7de69687544549cc2e077663a1e58f05b91d6990 (HEAD -> master)
Author: Holger Dengler <dengler@linutronix.de>
Date:   Mon Feb 26 13:00:00 2018 +0100

    imx: Initialize XYZ_CTRL during device probe

    After a warm reboot, the control register of the XYZ Component is not
    set to the correct reset values, as described in the Reference
    Manual. This causes non-deterministic race conditions during the probe
    of the device.

    Setting the control register to the power-on reset values triggers an
    internal reset of the component. The device can be probed in a proper
    way in all reboot cases (POR and warm reset).

    See: Reference Manual, Page 4711, XYZ Device Initialization and
    Control Register.

    Signed-off-by: Holger Dengler <dengler@linutronix.de>
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\subsection{Local Git Repositories}

% ----------------------------
\begin{frame}[fragile]{Create an Empty Repository}
\begin{itemize}
\item create a top-level directory
\item initialize the repository configuration and history
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Example: Create Empty Repository}
\begin{scriptsize}
\begin{verbatim}
# create top-level directory of repo
mkdir myrepo

# initialize repository
cd ./myrepo
git init

# alternative: initialize repository without working tree
git init --bare
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Git Configuration}
\begin{itemize}
\item system-wide configuration (scope of distribution)
 \begin{itemize}
 \item location: \texttt{/etc/gitconfig}
 \end{itemize}
\item global configuration (defaults for all repositories of a user)
 \begin{itemize}
 \item location: \texttt{\~{}/.gitconfig}
 \end{itemize}
\item local configuration (repository-local)
 \begin{itemize}
 \item location: \texttt{<repo-dir>/.git/config}
 \end{itemize}
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Example: Configure Git}
\begin{scriptsize}
\begin{verbatim}
# set name and e-mail address of the user
git config --global --add user.name "Jo Developer"
git config --global --add user.email "devel@acme.com"
git config --global --add core.editor "pluma"

# other e-mail address for some repositories
cd <repo-dir>
git config --local --add user.email "devel@private-mail.eu"
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Add/Change Files}
\begin{itemize}
\item create (or edit) files
\item check changes
\item stage changes
\item commit changes
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Example: Add File to Repository}
\begin{scriptsize}
\begin{verbatim}
# add or edit files
echo "hello world" > myfile

# check unstaged changes
git status
git diff

# stage changes
git add myfile

# check staged changes
git status
git diff --cached

# commit staged changes (opens editor for the commit message)
git commit -s
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Cleanup}
\begin{itemize}
\item clean untracked files
\item reset unstaged changes (reset to repository version)
\item remove files from stage area (reset to unstaged state)
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Examples: Cleanup}
\begin{scriptsize}
\begin{verbatim}
# delete untracked files
git clean

# rollback file changes
git checkout -- path/to/file

# remove file from stage area
git reset HEAD path/to/file
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Exclude Files from Version Tracking}
\begin{itemize}
\item list of ignored files (<repo-dir>/.gitignore)
\item specific list for each directory possible
\item allow wildcards
\item wildcard exceptions start with "!"
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Example: Ignore List}
\begin{scriptsize}
\begin{verbatim}
# fill ignore List
cat > .gitignore << 'EOF'
.*
!.gitignore
*.o
*.exe
EOF

# check status
git status

# commit intial ignore list
git add .gitignore
git commit -s -m "initial repository ignore list"
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Branches}
\begin{itemize}
\item Create a new branch from:
 \begin{itemize}
 \item commit (ID)
 \item tag
 \item existing branch
 \end{itemize}
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Example: Branches}
\begin{scriptsize}
\begin{verbatim}
# create a new branch (no changes to working tree)
git branch <new-branch> [<commit/branch/tag>]

# create a new branch and checkout to working tree
git checkout -b <new-branch> [<commit/branch/tag>]
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\subsection{Working with Remote Git Repositories}

% ----------------------------
\begin{frame}[fragile]{Clone Repository}
\begin{itemize}
\item clone a remote repository
\item creates a local clone (copy) of another repository (with complete
history)
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Example: Clone Repository}
\begin{scriptsize}
\begin{verbatim}
# clone Linux kernel repository from Github
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

# check content
cd linux
ls -l
git log

# clone Linux kernel repository from Github without working tree
git clone --bare https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

# no checkouts, but history is available
cd linux.git
ls -l
git log
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Add Remote Repositories}
\begin{itemize}
\item multiple remotes possible
\item e.g. pull from development repository and push to release repository
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Examples: Remote}
\begin{scriptsize}
\begin{verbatim}
# check all remotes (with URL)
git remote -v

# add a new remote
git remote add linus https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Synchronize/Get Changes from Remote}
\begin{itemize}
\item fetch: update repository history
\item pull: update repository and working tree
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Examples: Fetch/Pull}
\begin{scriptsize}
\begin{verbatim}
# update history from mainline repository
git fetch linus

# update history of all remote repositories
git fetch --all

# synchronize the local master working tree with master branch
# of remote "linus"
git checkout master
git pull linus master
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\begin{frame}[fragile]{Synchronize/Put Changes to Remote}
\begin{itemize}
\item push changes to another repository
\item requires write-access
\end{itemize}
\begin{beamerboxesrounded}[shadow=true]{Examples: Push}
\begin{scriptsize}
\begin{verbatim}
# prepare the push-branch
git checkout -b release-v1.0 master

# pull from development repository
git pull devel-repo prepare_master-v1.0

# push release branch to release repository
# (creates new branch in remote repository)
git push release-repo release-v1.0
\end{verbatim}
\end{scriptsize}
\end{beamerboxesrounded}
\end{frame}

% ----------------------------
\subsubsection*{References}

% ----------------------------
\begin{frame}[fragile]{References}
\begin{itemize}
\item Git Webpage (\url{https://git-scm.com/})
\item ProGit (\url{https://git-scm.com/book/en/v2})
\end{itemize}
\end{frame}
