|
|
|
\documentclass[aspectratio=169]{beamer}
|
|
|
|
|
|
|
|
\usepackage{pgfpages}
|
|
|
|
%showNotes%\setbeameroption{show notes on second screen=right}
|
|
|
|
%\setbeamertemplate{note page}{\pagecolor{yellow!5}\insertnote}
|
|
|
|
%showNotes%\setbeamertemplate{note page}{%
|
|
|
|
%showNotes%\setlength{\parskip}{12pt}\pagecolor{yellow!5}\vfill\insertnote\vfill}
|
|
|
|
%onlyNotes%\setbeameroption{show only notes}
|
|
|
|
%onlyNotes%\setbeamertemplate{note page}{%
|
|
|
|
%onlyNotes%\begin{center} \insertslideintonotes{0.3} \end{center}
|
|
|
|
%onlyNotes%\setlength{\parskip}{12pt} \pagecolor{yellow!5} \tiny\insertnote }
|
|
|
|
\setlength{\parskip}{12pt}
|
|
|
|
\usepackage{palatino}
|
|
|
|
\usepackage[utf8]{inputenc}
|
|
|
|
\usepackage{amsmath}
|
|
|
|
\usepackage{pdfpages}
|
|
|
|
\usepackage{tikz}
|
|
|
|
\usepackage[UKenglish]{babel}%
|
|
|
|
\usetikzlibrary{shapes.geometric, arrows}
|
|
|
|
\tikzstyle{commit} = [circle, text centered, line width=2,
|
|
|
|
minimum size=1.5cm, draw=blue, fill=blue!80, text=white]
|
|
|
|
\tikzstyle{branch} = [ellipse, text centered, text=green]
|
|
|
|
\tikzstyle{arrow} = [thick, <-, draw=blue]
|
|
|
|
|
|
|
|
\usepackage{dirtree}
|
|
|
|
\usepackage{csquotes}
|
|
|
|
%\usepackage{gitdags}
|
|
|
|
\usepackage{minted}
|
|
|
|
\setminted{%
|
|
|
|
autogobble,
|
|
|
|
fontsize=\footnotesize,
|
|
|
|
breaklines
|
|
|
|
}
|
|
|
|
|
|
|
|
\usetheme{default}
|
|
|
|
\beamertemplatenavigationsymbolsempty
|
|
|
|
\hypersetup{%
|
|
|
|
colorlinks=true,
|
|
|
|
urlcolor=blue,
|
|
|
|
%pdfpagemode=UseNone
|
|
|
|
} % don't show bookmarks on initial view
|
|
|
|
|
|
|
|
%\lstset{%
|
|
|
|
% breaklines=true,
|
|
|
|
% postbreak=\mbox{$\hookrightarrow$\space},
|
|
|
|
% basicstyle=\footnotesize,
|
|
|
|
% %keywordstyle=\color{blue},
|
|
|
|
% morekeywords=git
|
|
|
|
%}
|
|
|
|
\usepackage{graphicx}
|
|
|
|
\graphicspath{ {./auto-images/} }
|
|
|
|
|
|
|
|
\makeatletter
|
|
|
|
\def\input@path{{auto-images/}}
|
|
|
|
%or: \def\input@path{{/path/to/folder/}{/path/to/other/folder/}}
|
|
|
|
\makeatother
|
|
|
|
|
|
|
|
%Information to be included in the title page:
|
|
|
|
\title{Git}
|
|
|
|
\author{Jonathan Hodgson (Archie)}
|
|
|
|
\date{\today}
|
|
|
|
|
|
|
|
%\titlegraphic{\includegraphics[width=1cm,keepaspectratio]{auto-xkcd-1597.png})
|
|
|
|
\institute{
|
|
|
|
\includegraphics[width=\textwidth,height=.5\textheight,keepaspectratio]{auto-xkcd-1597.png}%
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
\begin{document}
|
|
|
|
|
|
|
|
\frame{
|
|
|
|
\titlepage
|
|
|
|
\note{%
|
|
|
|
A few people recently have asked me about Git.
|
|
|
|
|
|
|
|
Git has a reputation for being hard. I think this is (at least partly) because so much of
|
|
|
|
its inner workings are abstracted away making the interface feel like magic. Not to mention
|
|
|
|
videos with titles like "Learn git in 15 minutes"
|
|
|
|
|
|
|
|
I think that understanding a bit about how Git works under the hood will help de-mistily it.
|
|
|
|
It certainly did for me.
|
|
|
|
|
|
|
|
Git's data model is actually quite simple (beautiful even). Understanding the basics of this
|
|
|
|
can really help.
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{What is Git}
|
|
|
|
|
|
|
|
A very versatile Version Control System
|
|
|
|
|
|
|
|
\begin{itemize}
|
|
|
|
\item Keep track of source code (or other folders and files) and its history
|
|
|
|
\item Facilitate collaboration
|
|
|
|
\item Distributed
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
|
|
|
|
It keeps track by maintaining a series of snapshots containing all of the files and folders
|
|
|
|
at each point.
|
|
|
|
|
|
|
|
It's useful even if you're working on things by your self. This presentation is version
|
|
|
|
controlled.
|
|
|
|
|
|
|
|
You can use it to find out when something broke. I won't be covering it today but there is a
|
|
|
|
tool called git bisect that can take a unit test (or script) to analyse when something broke
|
|
|
|
using a binary search.
|
|
|
|
|
|
|
|
Being distributed means you can work on repositories offline (Unlike SVN).
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{What is Git}
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
\Huge Git $\ne$ Github
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Although the names are similar, Git and Github are separate projects. Github is a Microsoft
|
|
|
|
owned, closed source company that is a remote repository for Git projects.
|
|
|
|
|
|
|
|
There are others such as Bitbucket, Gitlab, Gitea
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Naïve Approach}
|
|
|
|
\begin{columns}
|
|
|
|
\begin{column}{0.5\textwidth}
|
|
|
|
\dirtree{%
|
|
|
|
.1 Project.
|
|
|
|
.2 draft.
|
|
|
|
.3 some.
|
|
|
|
.3 files.
|
|
|
|
.2 final-draft.
|
|
|
|
.3 some.
|
|
|
|
.3 files.
|
|
|
|
.2 final.
|
|
|
|
.3 some.
|
|
|
|
.3 files.
|
|
|
|
}
|
|
|
|
\end{column}
|
|
|
|
\begin{column}{0.5\textwidth}
|
|
|
|
\textbf{Pros}
|
|
|
|
\begin{itemize}
|
|
|
|
\item Simple
|
|
|
|
\item No dependencies
|
|
|
|
\item No Learning curve
|
|
|
|
\end{itemize}
|
|
|
|
\vspace{1em}
|
|
|
|
\textbf{Cons}
|
|
|
|
\begin{itemize}
|
|
|
|
\item Difficult to collaborate
|
|
|
|
\item Lot's of wasted disk space
|
|
|
|
\item Hard to find particular versions of files
|
|
|
|
\end{itemize}
|
|
|
|
\end{column}
|
|
|
|
\end{columns}
|
|
|
|
\note{%
|
|
|
|
There are many approaches you could take to version control
|
|
|
|
|
|
|
|
I think, being honest, we have all done this. This sort of works, if you're working on
|
|
|
|
something by yourself. Once you start collaborating on software, you are going to have a bad
|
|
|
|
time.
|
|
|
|
|
|
|
|
You could add time stamps and zip up changes when you need to collaborate.
|
|
|
|
|
|
|
|
Git has a well thought out model that allows us to address these problems.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Files and Folders}
|
|
|
|
|
|
|
|
\textbf{Blob} In Git, a file is called a blob.
|
|
|
|
|
|
|
|
\textbf{Tree} In Git, a directory is called a tree.
|
|
|
|
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Git needs a way of modeling files and folders in a file system independent way.
|
|
|
|
|
|
|
|
These concepts are pretty familiar. A tree can contain other trees or blobs.
|
|
|
|
|
|
|
|
At its core, Git is a content addressed storage tool. All files and folders are addressed by
|
|
|
|
a (hardened) sha1 hash.
|
|
|
|
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Commits}
|
|
|
|
\framesubtitle{(Snapshots)}
|
|
|
|
\begin{center}
|
|
|
|
\begin{tikzpicture}
|
|
|
|
%\draw (-1.5,-1.5) rectangle (7.5,1.5);
|
|
|
|
%\node at (-2.5,0) {master};
|
|
|
|
\node[commit,minimum size=2cm] at (0,0) (commit1) {Draft};
|
|
|
|
\node[commit,minimum size=2cm] at (3,0) (commit2) {Final Draft};
|
|
|
|
\node[commit,minimum size=2cm,draw=red] at (6,0) (commit3) {Final};
|
|
|
|
\draw[arrow] (commit1) -- (commit2);
|
|
|
|
\draw[arrow] (commit2) -- (commit3);
|
|
|
|
\node[draw,text width=1.8cm,anchor=north,align=center] at (0, -1.5) {\small \vdots\\[0.1cm] };
|
|
|
|
\node[draw,text width=1.8cm,anchor=north,align=center] at (3, -1.5) {\small \vdots\\[0.1cm] Draft };
|
|
|
|
\node[draw,text width=1.8cm,anchor=north,align=center] at (6, -1.5) {\small \vdots\\[0.1cm] Final Draft };
|
|
|
|
\end{tikzpicture}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
\begin{itemize}
|
|
|
|
\item We could then think of history as a linear series of snapshots.
|
|
|
|
\item Each circle here represents a snapshot.
|
|
|
|
\item The previous snapshot is referenced somewhere in each snapshot.
|
|
|
|
\item We then just need to record the most recent version somewhere.
|
|
|
|
\end{itemize}
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Commits}
|
|
|
|
\begin{center}
|
|
|
|
\begin{tikzpicture}
|
|
|
|
%\draw (-1.5,-1.5) rectangle (7.5,1.5);
|
|
|
|
%\node at (-2.5,0) {master};
|
|
|
|
\node[commit] at (0,0) (commit1) {93e4d3d\ldots};
|
|
|
|
\node[commit] at (3,0) (commit2) {2557962\ldots};
|
|
|
|
\node[commit,draw=red] at (6,0) (commit3) {od68560\ldots};
|
|
|
|
\draw[arrow] (commit1) -- (commit2);
|
|
|
|
\draw[arrow] (commit2) -- (commit3);
|
|
|
|
\node[draw,text width=1.8cm,anchor=north,align=center] at (0, -1.5) {\small \vdots\\[0.1cm] };
|
|
|
|
\node[draw,text width=1.8cm,anchor=north,align=center] at (3, -1.5) {\small \vdots\\[0.1cm] 93e4d3d\ldots };
|
|
|
|
\node[draw,text width=1.8cm,anchor=north,align=center] at (6, -1.5) {\small \vdots\\[0.1cm] 2557962\ldots };
|
|
|
|
\end{tikzpicture}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
\begin{itemize}
|
|
|
|
\item Rather than human readable names, Git references each snapshot (called a commit)
|
|
|
|
by a cryptographic hash. Currently using a hardened sha1 but there is an effort to
|
|
|
|
move to sha256.
|
|
|
|
\item Similarly to the model above, each commit references the previous (except the
|
|
|
|
first obviously)
|
|
|
|
\item The commit also includes meta information such as the committer, a timestamp and a
|
|
|
|
message.
|
|
|
|
\item We will look at this in more detail a bit later.
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Install}
|
|
|
|
|
|
|
|
\begin{minted}{bash}
|
|
|
|
# Ubuntu / Debian / Kali
|
|
|
|
sudo apt install git
|
|
|
|
|
|
|
|
# Centos / Fedora / Red Hat
|
|
|
|
sudo dnf install git
|
|
|
|
|
|
|
|
# Arch / Antergos / Manjaro
|
|
|
|
sudo pacman -S git
|
|
|
|
|
|
|
|
# Mac
|
|
|
|
brew install git
|
|
|
|
|
|
|
|
# Get the Version
|
|
|
|
git --version
|
|
|
|
\end{minted}
|
|
|
|
|
|
|
|
Git for Windows: \href{https://gitforwindows.org/}{https://gitforwindows.org/}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Git is probably already installed if you are on a Linux system. However, if not, it will
|
|
|
|
definitely be in your standard repositories.
|
|
|
|
|
|
|
|
There is a version of Git provided with xcode, but it is old. Most of the stuff we cover
|
|
|
|
today should still work but (for example) some things need to be run from the root directory
|
|
|
|
in old versions of git that don't in newer versions.
|
|
|
|
|
|
|
|
If you have the misfortune to be using windows, I've heard good things about Git for Windows
|
|
|
|
but have not used it personally. It includes Bash emulation.
|
|
|
|
|
|
|
|
Hopefully you have a version greater than 2.23.0 - if not, it's not the end of the world.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Setting It Up}
|
|
|
|
\framesubtitle{User}
|
|
|
|
|
|
|
|
\begin{minted}{bash}
|
|
|
|
git config --global user.name "Jonathan Hodgson"
|
|
|
|
git config --global user.email "git@jonathanh.co.uk"
|
|
|
|
\end{minted}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Hopefully you have Git installed. I will be running it on Linux although the commands should
|
|
|
|
all be the same for Windows and Mac.
|
|
|
|
|
|
|
|
Note that I am not using my primary email address. The email address you provide here will
|
|
|
|
be available to anyone with access to repositories you work on.
|
|
|
|
|
|
|
|
These settings are stored in \mintinline{bash}{~/.gitconfig}.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Setting It Up}
|
|
|
|
\framesubtitle{Editor}
|
|
|
|
|
|
|
|
\textbf{Pick One}
|
|
|
|
\begin{minted}{bash}
|
|
|
|
# Set editor to vim
|
|
|
|
git config --global core.editor "vim"
|
|
|
|
|
|
|
|
# Set editor to nano
|
|
|
|
git config --global core.editor "nano"
|
|
|
|
|
|
|
|
# Set editor to VS Code
|
|
|
|
git config --global core.editor "code -w"
|
|
|
|
|
|
|
|
# Set editor to Sublime
|
|
|
|
git config --global core.editor "subl -w"
|
|
|
|
\end{minted}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
There are several times that Git will need to open a text editor. By default, it will use
|
|
|
|
\mintinline{bash}{EDITOR}. If neither is set, it will use VI.
|
|
|
|
|
|
|
|
Note that if you are using a GUI editor, you might have to set the wait flag. This makes it
|
|
|
|
so the executable doesn't return until you close it.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Create a repository}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-git-init.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
Do this in a live terminal. MAKE SURE YOU MAKE YOUR FONT BIGGER
|
|
|
|
|
|
|
|
Show that the \mintinline{bash}{.git} folder has been created and do a tree to show what is
|
|
|
|
in it.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Create a repository}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-tree-empty-git.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
Do this in a live terminal. MAKE SURE YOU MAKE YOUR FONT BIGGER
|
|
|
|
|
|
|
|
Show that the \mintinline{bash}{.git} folder has been created and do a tree to show what is
|
|
|
|
in it.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Git status}
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-touch-git-status.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
Create repo and create a file called greeting.py. Make sure to mark it as executable.
|
|
|
|
|
|
|
|
Here we see the branch we are on (Master), we are told that there are no commits yet and we
|
|
|
|
see that Git can see the file we've just made but it isn't tracking it.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Staging Area}
|
|
|
|
\begin{itemize}
|
|
|
|
\item Sometimes called the git index
|
|
|
|
\item An intermediate area in which you can pick files to be included in the next commit.
|
|
|
|
\item Also allows you to exclude some files from your version history.
|
|
|
|
\begin{itemize}
|
|
|
|
\item Log files
|
|
|
|
\item Binary files
|
|
|
|
\item Minified files
|
|
|
|
\end{itemize}
|
|
|
|
\end{itemize}
|
|
|
|
\note{%
|
|
|
|
This is the last thing before we start actually doing stuff (promise).
|
|
|
|
|
|
|
|
This is particularly useful if you have multiple logically unrelated changes and want to
|
|
|
|
make separate snapshots for each.
|
|
|
|
|
|
|
|
Also useful if when programming you write your tests along side your code, you would
|
|
|
|
normally want those to be separate snapshots.
|
|
|
|
|
|
|
|
We will talk about .gitignore later which is another way of ignoring files
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Staging Area}
|
|
|
|
\begin{minted}{bash}
|
|
|
|
# Add files / or directories
|
|
|
|
git add <file|directory> [<file|directory>...]
|
|
|
|
# Add everything not in gitignore
|
|
|
|
git add -A
|
|
|
|
\end{minted}
|
|
|
|
\note{%
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Staging Area}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-show-staging-area.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
Here can use git status to see what is in the staging area. They are listed in the ``Changes
|
|
|
|
to be committed" section. By default, they will also be green if you have colour switched
|
|
|
|
on.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Committing}
|
|
|
|
|
|
|
|
\begin{itemize}
|
|
|
|
\item First line should be concise summary around 50 chars
|
|
|
|
\item Body Should be wrapped to around 70 chars
|
|
|
|
\item There should be an empty line separating summary from body
|
|
|
|
\item If contributing to a project, check per-project guidelines
|
|
|
|
\begin{itemize}
|
|
|
|
\item Normally in contributing.md or similar
|
|
|
|
\end{itemize}
|
|
|
|
\item Use the imperative: ``Fix bug" and not ``Fixed bug" or ``Fixes bug."
|
|
|
|
\end{itemize}
|
|
|
|
\note{%
|
|
|
|
First line is often shown by various tools
|
|
|
|
|
|
|
|
70 chars allows for good email etiquette. Allowing for 80 char hard wrap with after a few
|
|
|
|
reply indents
|
|
|
|
|
|
|
|
Generally you will want to write in imperative as this is what automatic commits like merge
|
|
|
|
do.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{When should you commit?}
|
|
|
|
\framesubtitle{Commit early, commit often}
|
|
|
|
\begin{itemize}
|
|
|
|
\item Every time you complete a small change or fix a bug
|
|
|
|
\item For each point on a detailed to-do list
|
|
|
|
\item You don't normally want to commit broken code (intentionally at least)
|
|
|
|
\item In some instances you might want to auto-commit - but probably not too often.
|
|
|
|
\begin{itemize}
|
|
|
|
\item Normally this works if changes can't break something. E.g. Password Manager
|
|
|
|
\end{itemize}
|
|
|
|
\end{itemize}
|
|
|
|
\note{%
|
|
|
|
Unfortunately, this doesn't have one simple answer.
|
|
|
|
|
|
|
|
Some examples of auto-committing are for your password manager.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Commit Messages}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-xkcd-1296.png}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
In case you hadn't noticed, I quite like Randall Munroe.
|
|
|
|
|
|
|
|
I am bad for this, particularly on personal projects.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Commit}
|
|
|
|
\begin{minted}{bash}
|
|
|
|
# Open editor for message
|
|
|
|
git commit
|
|
|
|
# Read message from file
|
|
|
|
git commit -F <file or - for stdin>
|
|
|
|
# Provide message directly
|
|
|
|
git commit -m "<message>"
|
|
|
|
\end{minted}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-first-commit.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
Running git commit will open your editor.
|
|
|
|
|
|
|
|
I only really use -F if I am doing so from a script
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Diff}
|
|
|
|
\begin{minted}{bash}
|
|
|
|
# Diff between last commit and current state
|
|
|
|
git diff
|
|
|
|
# Diff between 2 commits or references
|
|
|
|
git diff commit1..commit2
|
|
|
|
# Same as above but on a single file
|
|
|
|
git diff a/file
|
|
|
|
\end{minted}
|
|
|
|
\note{%
|
|
|
|
Diff is pretty smart. It will normally work for whatever combinations of commits, references
|
|
|
|
(more on that later) or files.
|
|
|
|
|
|
|
|
Change Hello to Hello World
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Diff}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-first-diff.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
These are hopefully quite easy to understand. Red lines mean a line was removed, green means
|
|
|
|
a line was added.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Log}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-second-commit-with-log.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
Here we see a commit done with the -m flag. I generally only use -m if it is a trivial
|
|
|
|
change like this and there is no need to have a body.
|
|
|
|
|
|
|
|
You can see that the log shows a list of the two commits we have made on this project.
|
|
|
|
|
|
|
|
The git log command has a lot of flags. We will see some of them later.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Under the hood}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-first-cat-commit-file.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
I said earlier that we would be looking at how all this works at quite a low level. This is
|
|
|
|
where that starts.
|
|
|
|
|
|
|
|
We can also use the cat-file command built into git to do the same thing. We can see that
|
|
|
|
Commits, trees and blobs are all stored in the same way.
|
|
|
|
|
|
|
|
You will also see that you can often use a prefix of the first 4 or more characters of a
|
|
|
|
hash. It is quite common to use the first 7 or 8.
|
|
|
|
|
|
|
|
Hopefully you will see from this that the inner workings of git isn't that complicated.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{.gitignore}
|
|
|
|
This file tells git which files not to track.
|
|
|
|
\begin{minted}{bash}
|
|
|
|
*.log
|
|
|
|
*.doc
|
|
|
|
*.pem
|
|
|
|
*.docx
|
|
|
|
*.jpg
|
|
|
|
*.jpeg
|
|
|
|
*.pdf
|
|
|
|
*.png
|
|
|
|
.DS_Store/
|
|
|
|
*.min.css
|
|
|
|
*.min.js
|
|
|
|
dist/
|
|
|
|
\end{minted}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
This will not stop git tracking a file if it's already being tracked.
|
|
|
|
|
|
|
|
If you start tracking large binary files, git isn't going to be able to compress them. This
|
|
|
|
will result in a massive repo and a headache for everyone. If at all possible, don't track
|
|
|
|
large files, especially if they are going to be changed. Remember, git stores each version
|
|
|
|
of each file. With text, this is fine as it can be compressed efficiently. If it's not text,
|
|
|
|
it can't.
|
|
|
|
|
|
|
|
You should probably also try to avoid including minified files as git won't be able to merge
|
|
|
|
them automatically.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{References}
|
|
|
|
\begin{itemize}
|
|
|
|
\item We have just seen that commits are simply (compressed) text files, addressed by a
|
|
|
|
hash.
|
|
|
|
\item References are a way of addressing them without remembering the hash.
|
|
|
|
\item Unlike the hashes, references can change - and they do change.
|
|
|
|
\end{itemize}
|
|
|
|
\note{%
|
|
|
|
We've seen a couple of these (sort of)
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{References}
|
|
|
|
\begin{itemize}
|
|
|
|
\item Branches
|
|
|
|
\begin{itemize}
|
|
|
|
\item Parallel development
|
|
|
|
\end{itemize}
|
|
|
|
\item Tags
|
|
|
|
\begin{itemize}
|
|
|
|
\item Special points in history (Release versions)
|
|
|
|
\end{itemize}
|
|
|
|
\item HEAD
|
|
|
|
\begin{itemize}
|
|
|
|
\item Current position in history
|
|
|
|
\end{itemize}
|
|
|
|
\end{itemize}
|
|
|
|
\note{%
|
|
|
|
Branches allow for parallel development, individually or multiple people. We well look at
|
|
|
|
these in more detail in a minute.
|
|
|
|
|
|
|
|
Tags allow you to mark special commits. Normally this is used for release versions or
|
|
|
|
similar.
|
|
|
|
|
|
|
|
HEAD refers to the commit or branch you are currently looking at. We will see in a minute
|
|
|
|
that you can revert a whole project to a previous point in time. This is how git knows
|
|
|
|
where (when?) you are.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{References}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-log-with-decoration.pdf}
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
There are two references we can see here, master and HEAD.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{References}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-cat-master-and-head.pdf}
|
|
|
|
\end{center}
|
|
|
|
\begin{itemize}
|
|
|
|
\item References are stored in the \mintinline{bash}{.git/refs} folder
|
|
|
|
\item The \mintinline{bash}{heads} folder contains references to the heads (or tips) of all
|
|
|
|
local branches
|
|
|
|
\end{itemize}
|
|
|
|
\note{%
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Branches}
|
|
|
|
|
|
|
|
\begin{itemize}
|
|
|
|
\item By default Git will create a branch called Master (maybe?).
|
|
|
|
\item Allows multiple features to be developed in parallel without interference.
|
|
|
|
\item Allows multiple people to collaborate easily.
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
So, when I originally wrote this slide, git would create a branch called master by default.
|
|
|
|
The convention was that this was your "main" branch. Currently on my system it still does
|
|
|
|
although there is a movement to switch the default to main or primary or something similar.
|
|
|
|
|
|
|
|
I have no intentions to make this a political talk so make of it what you want.
|
|
|
|
}
|
|
|
|
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Commits / Branches}
|
|
|
|
\begin{center}
|
|
|
|
\begin{tikzpicture}
|
|
|
|
%\draw (-1.5,-1.5) rectangle (7.5,1.5);
|
|
|
|
%\node at (-2.5,0) {master};
|
|
|
|
\node[commit] at (0,0) (commit1) {};
|
|
|
|
\node[commit] at (2,0) (commit2) {A};
|
|
|
|
\node[commit] at (4,0) (commit3) {B};
|
|
|
|
\node[commit] at (4,-2) (commit3b) {C};
|
|
|
|
\node[anchor=west] at (4.5,0.5) {+Bugfix};
|
|
|
|
\node[anchor=west] at (4.5,-2.5) {+Feature};
|
|
|
|
\draw[arrow] (commit1) -- (commit2);
|
|
|
|
\draw[arrow] (commit2) -- (commit3);
|
|
|
|
\draw[arrow] (commit2) -- (commit3b);
|
|
|
|
\draw[draw=red] (-1,1) rectangle (6.5,-0.99);
|
|
|
|
\node[fill=red,text=white,anchor=north west] at (-1,1) {Branch 1};
|
|
|
|
\draw[draw=green] (-1,-1) rectangle (6.5,-3);
|
|
|
|
\node[fill=green,text=white,anchor=north west] at (-1,-1) {Branch 2};
|
|
|
|
\end{tikzpicture}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
The linear graph we just saw is an overly simplistic representation. In reality, Git
|
|
|
|
represents history using a Directed acyclic graph which allows parents to be shared my
|
|
|
|
multiple commits. This is useful because it allows for Branches.
|
|
|
|
|
|
|
|
It is good practice to develop features on a separate branch. This allows for multiple
|
|
|
|
people to work on a project as well as allowing things like bug-fixes to be deployed without
|
|
|
|
having to worry about interference from a new feature.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Commits / Branches}
|
|
|
|
\begin{center}
|
|
|
|
\begin{tikzpicture}
|
|
|
|
%\draw (-1.5,-1.5) rectangle (7.5,1.5);
|
|
|
|
%\node at (-2.5,0) {master};
|
|
|
|
\node[commit] at (0,0) (commit1) {};
|
|
|
|
\node[commit] at (2,0) (commit2) {};
|
|
|
|
\node[commit] at (5,0) (commit4) {A};
|
|
|
|
\node[commit] at (8,0) (commit5) {C};
|
|
|
|
\node[commit] at (4,-2) (commit3b) {};
|
|
|
|
\node[commit] at (6,-2) (commit4b) {B};
|
|
|
|
\node[anchor=west] at (5.5,0.5) {+Bugfix};
|
|
|
|
\node[anchor=west] at (6.5,-2.5) {+Feature};
|
|
|
|
\node[anchor=south west] at (8.7,-0.2) {\parbox{\textwidth}{+Bugfix \\ +Feature}};
|
|
|
|
\draw[arrow] (commit1) -- (commit2);
|
|
|
|
\draw[arrow] (commit2) -- (commit4);
|
|
|
|
\draw[arrow] (commit4) -- (commit5);
|
|
|
|
\draw[arrow] (commit2) -- (commit3b);
|
|
|
|
\draw[arrow] (commit3b) -- (commit4b);
|
|
|
|
\draw[arrow] (commit4b) -- (commit5);
|
|
|
|
\draw[draw=red] (-1,1) rectangle (10.5,-0.99);
|
|
|
|
\node[fill=red,text=white,anchor=north west] at (-1,1) {Branch 1};
|
|
|
|
\draw[draw=green] (-1,-1) rectangle (10.5,-3);
|
|
|
|
\node[fill=green,text=white,anchor=north west] at (-1,-1) {Branch 2};
|
|
|
|
\end{tikzpicture}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
As well as 2 commits' ability to share a parent, the opposite is also true, Here, we see
|
|
|
|
that a commit is able to have multiple parents.
|
|
|
|
|
|
|
|
This is called a merge commit - because it merges two branches. In a lot of situations git
|
|
|
|
is smart enough to auto-merge branches although at times human intervention is necessary.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\begin{minted}{bash}
|
|
|
|
# List Branches
|
|
|
|
git branch # -v adds more info
|
|
|
|
|
|
|
|
# Create a branch called test
|
|
|
|
git branch test # or
|
|
|
|
cp ~/.git/refs/heads/master ~/.git/refs/heads/test
|
|
|
|
|
|
|
|
# Switch to new branch
|
|
|
|
git switch test # or
|
|
|
|
git checkout test
|
|
|
|
|
|
|
|
# Create and switch in one go
|
|
|
|
git switch -c test # or
|
|
|
|
git checkout -b test
|
|
|
|
\end{minted}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Branches are represented in git as references in the heads folder.
|
|
|
|
|
|
|
|
They can be created by simply creating a file there.
|
|
|
|
|
|
|
|
The git checkout command does A LOT of stuff. It can be confusing so it's functionality has
|
|
|
|
been split up into several smaller commands. If you have git 2.23.0 or newer, you will be
|
|
|
|
able to use it.
|
|
|
|
|
|
|
|
Be aware that a lot of tutorials etc. will use the checkout command. Version 2.23.0 was
|
|
|
|
released in August 2019.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Branches}
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-create-first-branch.pdf}
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
As we saw, there are numerous ways to create the commit.
|
|
|
|
|
|
|
|
What is interesting to note here is that both are still currently pointing at the same
|
|
|
|
commit.
|
|
|
|
|
|
|
|
Head is pointing at test so any new commits will be on this branch.
|
|
|
|
|
|
|
|
Also take note of the git log command. \mintinline{bash}{--on-line} shows a short version
|
|
|
|
and \mintinline{bash}{--all} shows all branches.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Differing Branches}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-differing-branches-simple.pdf}
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Differing Branches}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-branch-diff.pdf}
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
This shows what would be needed to take you from master to test.
|
|
|
|
|
|
|
|
Notice the \mintinline{bash}{--graph} flag which adds the drawing to the left
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Simple Merge}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-simple-merge.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
After working on septate branches, you will probably want to merge them eventually.
|
|
|
|
|
|
|
|
In this situation, Git was able to work everything out itself.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Tidy Up}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-delete-test-branch.pdf}
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Now that we have finished with that branch, we can delete it.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{More Complex merge}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-complex-merge.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
At times, git won't be able to merge automatically.
|
|
|
|
|
|
|
|
Dealing with merges is something that there are around a million different tools you can use but
|
|
|
|
I think they over complicate what is actually quite a simple process.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{More Complex merge}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-cat-complex-merge.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
Here you can see that the bit(s) git couldn't work out are delimited by
|
|
|
|
\mintinline{bash}{<<<<<<<} and \mintinline{bash}{>>>>>>>} and separated by
|
|
|
|
\mintinline{bash}{=======}.
|
|
|
|
|
|
|
|
All you (the programmer) needs to do is fix it.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{More Complex merge}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-fix-complex-merge.pdf}
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Time Travel}
|
|
|
|
\begin{minted}{bash}
|
|
|
|
# Print a version of a file
|
|
|
|
git show <commit or reference>:<file>
|
|
|
|
# Restore a file from a previous version
|
|
|
|
git restore -s <commit or reference> file # or
|
|
|
|
git checkout <commit or reference> -- file
|
|
|
|
# Go back in time to a commit
|
|
|
|
git switch --detach <commit or reference> # or
|
|
|
|
git checkout <commit or reference>
|
|
|
|
\end{minted}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Note that for the show command, you need to provide the full path (relative to the root of
|
|
|
|
the project), not the relative path
|
|
|
|
|
|
|
|
Both the restore command and the switch command can also be achieved with checkout on older
|
|
|
|
versions of git.
|
|
|
|
|
|
|
|
In the case of restore and checkout, they are not identical. Checkout will also stage the
|
|
|
|
file whereas restore wont (without an additional flag)
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Remotes}
|
|
|
|
\begin{itemize}
|
|
|
|
\item The majority of Git commands only affect your local repository.
|
|
|
|
\item Git has a concept called remotes which you can think of as other instances of the same
|
|
|
|
repository
|
|
|
|
\item Git has a selection of commands that are used to communicate with these remote
|
|
|
|
repositories
|
|
|
|
\item It can communicate on multiple protocols including
|
|
|
|
\begin{itemize}
|
|
|
|
\item HTTP(S)
|
|
|
|
\item SSH
|
|
|
|
\item Local Filesystem
|
|
|
|
\end{itemize}
|
|
|
|
\end{itemize}
|
|
|
|
\note{%
|
|
|
|
The most common public remote is Git hub. This is one of many options.
|
|
|
|
|
|
|
|
The most common protocols are HTTP and SSH, both offering advantages over the other.
|
|
|
|
|
|
|
|
HTTP is easier to use and allows for anonymous access (useful for public repositories)
|
|
|
|
|
|
|
|
SSH allows for easier authentication but there is no anonymous authentication.
|
|
|
|
|
|
|
|
For ease of automating screen shots, I will be using local file system although all commands
|
|
|
|
are the same.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Adding a remote}
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-add-remote.pdf}
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
In this example, I am using a local folder as a URL but you can use anything.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Pushing your code}
|
|
|
|
\framesubtitle{Long Way}
|
|
|
|
|
|
|
|
|
|
|
|
\begin{minted}{bash}
|
|
|
|
git push <remote> <local-branch>:<remote-branch>
|
|
|
|
# E.g.
|
|
|
|
git push origin master:master
|
|
|
|
\end{minted}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Although this is usable, it is a bit annoying since you will normally want to create a 1 to
|
|
|
|
1 correspondence between your local branches and the remote branches.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Pushing your code}
|
|
|
|
\framesubtitle{Easy way}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-set-upstream-push.pdf}
|
|
|
|
\end{center}
|
|
|
|
\note{%
|
|
|
|
Admittedly, this looks like a longer way. However, the first command only needs to be run
|
|
|
|
the once. Git will then remember that the remote branch origin/master should be linked with
|
|
|
|
the local branch master.
|
|
|
|
|
|
|
|
As you can see from the git-status now, it tells us that the current branch is up to date
|
|
|
|
with the remote branch.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Retrieving changes from the remote}
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-fetch-merge-pull.pdf}
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Here another user has pushed changes to the master branch.
|
|
|
|
|
|
|
|
You can see here that the git fetch command downloads the required information. However, it
|
|
|
|
doesn't change your working tree.
|
|
|
|
|
|
|
|
In order to update our local master, we can simply do a git merge
|
|
|
|
|
|
|
|
Also note that after the git fetch command, the git status gives us some useful information.
|
|
|
|
This is another advantage of setting the corresponding upstream branch.
|
|
|
|
\begin{itemize}
|
|
|
|
\item We are 1 commit behind the remote version
|
|
|
|
\item The branch can be fast forwarded.
|
|
|
|
\end{itemize}
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Git Pull}
|
|
|
|
\framesubtitle{Shortcut}
|
|
|
|
|
|
|
|
\begin{minted}{bash}
|
|
|
|
git pull
|
|
|
|
git pull <remote> <branch>
|
|
|
|
\end{minted}
|
|
|
|
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Git has a command called pull which does the equivalent of a fetch then a merge.
|
|
|
|
|
|
|
|
The short version will only work if you have the local branch linked with a remote branch.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}[fragile]
|
|
|
|
\frametitle{Cloning}
|
|
|
|
|
|
|
|
\begin{minted}{bash}
|
|
|
|
# Clone a repository into a folder
|
|
|
|
git clone <URL> <folder>
|
|
|
|
|
|
|
|
# Clone a repository into a folder on a specific branch
|
|
|
|
git clone --branch <branch> <URL> <folder>
|
|
|
|
|
|
|
|
# Shallow clone a repository into a folder
|
|
|
|
git clone --shallow <URL> <folder>
|
|
|
|
\end{minted}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
If you would like to start from an existing remote repository, you can use the git clone
|
|
|
|
command.
|
|
|
|
|
|
|
|
This will automatically set up the link between the local and remote branches.
|
|
|
|
|
|
|
|
A shallow clone doesn't download all of the history.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Issues}
|
|
|
|
\begin{itemize}
|
|
|
|
\item Not part of Git, rather something most Git hosting providers offer.
|
|
|
|
\item You can normally reference issues in commit messages using \# symbol.
|
|
|
|
\end{itemize}
|
|
|
|
\note{%
|
|
|
|
Demonstrate this in a browser using Github
|
|
|
|
}
|
|
|
|
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Pull Requests}
|
|
|
|
\framesubtitle{Merge Requests}
|
|
|
|
|
|
|
|
\begin{enumerate}
|
|
|
|
\item Fork
|
|
|
|
\item Clone
|
|
|
|
\item Branch
|
|
|
|
\item Commit
|
|
|
|
\item Push
|
|
|
|
\end{enumerate}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
\begin{itemize}
|
|
|
|
\item Not part of Git, rather something most Git hosting providers offer.
|
|
|
|
\item It allows for people to contribute code to repositories that they don't have
|
|
|
|
write access to
|
|
|
|
\end{itemize}
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Useful supporting tools}
|
|
|
|
\framesubtitle{Shell Integration}
|
|
|
|
Git ships with completion for bash, zsh and tcsh. You may need to source it in the relevant rc
|
|
|
|
file.
|
|
|
|
|
|
|
|
Prompt customisation is available out of the box for bash and zsh.
|
|
|
|
\note{%
|
|
|
|
If you haven't ever tried zsh, give it a shot. Tab completion is so much more useful than
|
|
|
|
Bach's.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Useful supporting tools}
|
|
|
|
\framesubtitle{Editor Plugin}
|
|
|
|
\begin{itemize}
|
|
|
|
\item Git Gutters
|
|
|
|
\item Easy staging of parts of a file
|
|
|
|
\item Merge Conflict Resolution
|
|
|
|
\end{itemize}
|
|
|
|
\note{%
|
|
|
|
There are obviously hundreds of editors so find one that works well with yours.
|
|
|
|
|
|
|
|
I think Atom and VS Code have built in integration.
|
|
|
|
|
|
|
|
I use vim-fugitive. I've heard good things about magit for emacs.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Useful supporting tools}
|
|
|
|
\framesubtitle{BFG Repo Cleaner}
|
|
|
|
You'll need something like this when you realise you have just committed your ssh keys
|
|
|
|
|
|
|
|
\href{https://rtyley.github.io/bfg-repo-cleaner/}{https://rtyley.github.io/bfg-repo-cleaner/}
|
|
|
|
\note{%
|
|
|
|
For the time that you accidentally commit your ssh keys.
|
|
|
|
|
|
|
|
I accidentally committed a database for an Woocommerce site.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Useful supporting tools}
|
|
|
|
\framesubtitle{Git Crypt}
|
|
|
|
|
|
|
|
For storing sensitive information in a git repository.
|
|
|
|
|
|
|
|
\href{https://github.com/AGWA/git-crypt}{https://github.com/AGWA/git-crypt}
|
|
|
|
\note{%
|
|
|
|
This will encrypt files with gpg key(s) and transparently decrypt them on the file system.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Useful supporting tools}
|
|
|
|
\framesubtitle{Git Large File Storage}
|
|
|
|
|
|
|
|
A solution to the issue of storing binary files
|
|
|
|
|
|
|
|
\href{https://git-lfs.github.com/}{https://git-lfs.github.com/}
|
|
|
|
\note{%
|
|
|
|
As mentioned, git is not good at storing binary files because they can't be compressed or
|
|
|
|
diff-ed or merged.
|
|
|
|
|
|
|
|
This allows you to store links to large files and transparently add them to the file system
|
|
|
|
as though they were normal git blobs.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Useful supporting tools}
|
|
|
|
\framesubtitle{Bat}
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-download-aHR0cHM6Ly9jYW1vLmdpdGh1YnVzZXJjb250ZW50LmNvbS82N2U0NGY0YTY4MTUwMzI1Zjc0YjNhNDY4MjBiNzQ3M2ZmN2I5MWE2LzY4NzQ3NDcwNzMzYTJmMmY2OTJlNjk2ZDY3NzU3MjJlNjM2ZjZkMmYzMjZjNTM1NzM0NTI0NTJlNzA2ZTY3.png}
|
|
|
|
\end{center}
|
|
|
|
\href{https://github.com/sharkdp/bat}{https://github.com/sharkdp/bat}
|
|
|
|
\note{%
|
|
|
|
Bat is described as cat with wings.
|
|
|
|
|
|
|
|
It adds syntax highlighting to files. Useful even if you're not using Git
|
|
|
|
|
|
|
|
As this is a git talk, it shows lines that have changed since the last commit
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Useful supporting tools}
|
|
|
|
\framesubtitle{RipGrep / Fd / Exa}
|
|
|
|
|
|
|
|
\textbf{FD} replaces find
|
|
|
|
|
|
|
|
\href{https://github.com/sharkdp/fd}{https://github.com/sharkdp/fd}
|
|
|
|
|
|
|
|
\textbf{RigGrep} replaces grep
|
|
|
|
|
|
|
|
\href{https://github.com/BurntSushi/ripgrep}{https://github.com/BurntSushi/ripgrep}
|
|
|
|
|
|
|
|
\textbf{Exa} replaces ls
|
|
|
|
|
|
|
|
\href{https://github.com/ogham/exa}{https://github.com/ogham/exa}
|
|
|
|
\note{%
|
|
|
|
|
|
|
|
Fd and RipGrep will respect your gitignore by default.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Useful supporting tools}
|
|
|
|
\framesubtitle{Pass}
|
|
|
|
|
|
|
|
\begin{itemize}
|
|
|
|
\item Password Manager
|
|
|
|
\item Uses Git for keeping track of history
|
|
|
|
\item Syncs using Git
|
|
|
|
\item Everything is encrypted with a GPG key
|
|
|
|
\item Has compatible android, ios and browser apps.
|
|
|
|
\end{itemize}
|
|
|
|
|
|
|
|
\href{https://www.passwordstore.org/}{https://www.passwordstore.org/}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
A password manager that uses Git for sync and history.
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Useful supporting tools}
|
|
|
|
\framesubtitle{tldr}
|
|
|
|
|
|
|
|
The man page for git pull is over 700 lines.
|
|
|
|
|
|
|
|
\begin{center}
|
|
|
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-shell-tldr.pdf}
|
|
|
|
\end{center}
|
|
|
|
|
|
|
|
\href{https://github.com/tldr-pages/tldr}{https://github.com/tldr-pages/tldr}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Sometimes incredibly thorough documentation isn't what you want. Sometimes you know the
|
|
|
|
command you need but you can't remember exactly how to use it.
|
|
|
|
|
|
|
|
This is not specific to git commands, it covers a LOT.
|
|
|
|
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\begin{frame}
|
|
|
|
\frametitle{Questions}
|
|
|
|
|
|
|
|
You can find this presentation here:
|
|
|
|
|
|
|
|
\href{https://git.jonathanh.co.uk/jab2870/Git-Presentation}{https://git.jonathanh.co.uk/jab2870/Git-Presentation}
|
|
|
|
|
|
|
|
\note{%
|
|
|
|
Yes, this presentation uses git for version control
|
|
|
|
}
|
|
|
|
\end{frame}
|
|
|
|
|
|
|
|
\end{document}
|