You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1127 lines
32 KiB
1127 lines
32 KiB
\documentclass{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} |
|
\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{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} |
|
|
|
|
|
|
|
\begin{document} |
|
|
|
\frame{\titlepage} |
|
|
|
\note{% |
|
A few people recently have asked me about Git. |
|
|
|
Git has become the de-facto for most situations. |
|
|
|
Microsoft recently moved to git for version controlling Windows and Office. |
|
|
|
I will not be able to cover everything relating to Git, it is an incredibly powerful tool. |
|
However, hopefully I will be able to give you enough to get started and at least understand the |
|
official documentation. |
|
} |
|
|
|
\begin{frame} |
|
\frametitle{Aims} |
|
I am obviously not going to be able to go over everything that git does. |
|
\begin{itemize} |
|
\item I don't know everything Git does |
|
\item Git does LOADS of stuff |
|
\end{itemize} |
|
Hopefully after this you will be able to use Git well for most day-to-day tasks. Git has very |
|
compressive documentation. I hope that this will also give you enough of a background to |
|
understand the documentation. |
|
\note{% |
|
} |
|
\end{frame} |
|
|
|
\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{% |
|
Git is still being developed. |
|
|
|
Being distributed means you can work on repositories offline (Unlike SVN). |
|
|
|
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. |
|
} |
|
\end{frame} |
|
|
|
|
|
\begin{frame} |
|
\frametitle{Obligitary XKCD Comic} |
|
\begin{center} |
|
\includegraphics[width=\textwidth,height=0.8\textheight,keepaspectratio]{auto-xkcd-1597.png} |
|
\end{center} |
|
\note{% |
|
I have done this |
|
|
|
Git has a reputation for being hard. |
|
|
|
It's interface abstracts away a lot of the work, meaning it's commands can feel like magic. |
|
When it works, this is fine but unfortunately when things go wrong, you can be left - like |
|
in this comic - with no idea how to proceed. |
|
|
|
It's interface can be confusing, there are some commands that do a lot (checkout) and there |
|
are often multiple ways to achieve something. |
|
|
|
I think that understanding a bit about how Git works under the hood will help de-mistily it. |
|
|
|
Git's data model is actually quite simple (beautiful even). Understanding the basics of this |
|
can really help. |
|
} |
|
\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} |
|
|
|
\href{https://gitforwindows.org/}{Git for Windows: 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}[fragile] |
|
% \frametitle{Setting It Up} |
|
% \framesubtitle{Preferences} |
|
% |
|
% \textbf{Pick One} |
|
% \begin{minted}{bash} |
|
% # No colour |
|
% git config --global color.ui never |
|
% |
|
% # Auto colour |
|
% git config --global color.ui auto |
|
% |
|
% # Force colour |
|
% git config --global color.ui always |
|
% |
|
% # Overide for a command |
|
% git -c color.ui=always status > ~/some-file |
|
% |
|
% \end{minted} |
|
% |
|
% \note{% |
|
% On Linux systems, this is set to auto by default. Might be different on a Mac. Generally |
|
% auto is probably what you want. It will be coloured unless you are piping the output to a |
|
% file or another process. |
|
% |
|
% Take note of the incorrect spelling of colour. |
|
% |
|
% You can override all configuration options on an individual command basis if you like. |
|
% } |
|
%\end{frame} |
|
|
|
\begin{frame} |
|
\frametitle{Terminology} |
|
\framesubtitle{Objects} |
|
|
|
\textbf{Blob} In Git, a file is called a blob. |
|
|
|
\textbf{Tree} In Git, a directory is called a tree. |
|
|
|
\textbf{Commit} A snapshot of your code |
|
|
|
% All of these are referenced by a hash and stored in the \mintinline{bash}{.git/objects/} |
|
% directory. |
|
|
|
\note{% |
|
Technically, a blob is kind of like an inode on the file system so also represents symbolic |
|
links. |
|
|
|
There are some other types such as submodules but I won't be addressing them in this |
|
presentation. |
|
} |
|
\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. |
|
% .2 real-final. |
|
% .3 some. |
|
% .3 files. |
|
% .2 actual-real-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 Can be difficult to work out chronological order |
|
\end{itemize} |
|
\end{column} |
|
\end{columns} |
|
\note{% |
|
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. |
|
|
|
However, this is a simple approach and not a million miles from what Git does internally. |
|
} |
|
\end{frame} |
|
|
|
\begin{frame} |
|
\frametitle{Model it} |
|
\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 This is a simple representation of the folder structure we saw. |
|
\item Notice that so the computer knows the order, somewhere in each ``snapshot", we |
|
include a reference to the previous 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] 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} |
|
\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}; |
|
\draw[arrow] (commit1) -- (commit2); |
|
\draw[arrow] (commit2) -- (commit3); |
|
\draw[arrow] (commit2) -- (commit3b); |
|
\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. We will look at these a bit |
|
more later. |
|
|
|
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}; |
|
\draw[arrow] (commit1) -- (commit2); |
|
\draw[arrow] (commit2) -- (commit4); |
|
\draw[arrow] (commit4) -- (commit5); |
|
\draw[arrow] (commit2) -- (commit3b); |
|
\draw[arrow] (commit3b) -- (commit4b); |
|
\draw[arrow] (commit4b) -- (commit5); |
|
\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. |
|
|
|
By default, git creates a branch called Master when you create a repository. |
|
} |
|
\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}[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}[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{% |
|
The staging area is where you put things that you want to be committed. |
|
|
|
It can often be useful to manually split changes up into different commits. You might be |
|
working on feature A and feature B simultaneously. It is good practice to have each feature |
|
as a separate commit so you could add feature A to the staging area, commit it, then do the |
|
same for feature B. |
|
|
|
We will talk about \mintinline{bash}{.gitignore} in a bit. |
|
} |
|
\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}[fragile] |
|
\frametitle{Committing} |
|
\begin{minted}{bash} |
|
git commit |
|
\end{minted} |
|
|
|
\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 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{.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}[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. |
|
} |
|
\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} |
|
\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) |
|
|
|
Master and Head |
|
} |
|
\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{References} |
|
\framesubtitle{HEAD} |
|
\begin{itemize} |
|
\item The HEAD references is directly in the \mintinline{bash}{.git} folder. |
|
\item It refers to the ``current" commit. It is how git knows where you are. |
|
\item This normally refers to a branch's head commit. |
|
\item In some situations it will refer to a commit directly. |
|
\end{itemize} |
|
\note{% |
|
Not sure why it is not in refs folder |
|
|
|
If it refers directly to a commit, the repository is in what is called a ``detached head" |
|
state. |
|
} |
|
\end{frame} |
|
|
|
|
|
\begin{frame}[fragile] |
|
\frametitle{Branches} |
|
|
|
\begin{itemize} |
|
\item Allows multiple features to be developed in parallel without interference. |
|
\item Allows multiple people to collaborate easily. |
|
\end{itemize} |
|
|
|
\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 GIT |
|
\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{Git $\ne$ GitHub} |
|
\begin{itemize} |
|
\item GitHub is one of many services that offer hosting for git remotes |
|
\item It is owned by Microsoft now |
|
\item It is not open source |
|
\item You can't self host it |
|
\item It it very popular |
|
\end{itemize} |
|
\note{% |
|
} |
|
\end{frame} |
|
|
|
\begin{frame} |
|
\frametitle{Useful supporting tools} |
|
\framesubtitle{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{RigGrep / Fd} |
|
\note{% |
|
Alternatives to grep and find |
|
|
|
Fd, in particular, is not a full replacement for find but does most of what you want |
|
|
|
Both (by default) will respect your gitignore file. |
|
} |
|
\end{frame} |
|
|
|
\begin{frame} |
|
\frametitle{Useful supporting tools} |
|
\framesubtitle{Delta} |
|
\note{% |
|
This is a tool that can make your diff output look better. |
|
} |
|
\end{frame} |
|
|
|
\begin{frame} |
|
\frametitle{Useful supporting tools} |
|
\framesubtitle{Shell Integration} |
|
\note{% |
|
Takes 2 forms. Prompt and completion |
|
} |
|
\end{frame} |
|
|
|
\begin{frame} |
|
\frametitle{Useful supporting tools} |
|
\framesubtitle{Pass} |
|
\note{% |
|
Password manager |
|
} |
|
\end{frame} |
|
|
|
\begin{frame} |
|
\frametitle{Useful supporting tools} |
|
\framesubtitle{BFG Repo Cleaner} |
|
\begin{itemize} |
|
\item You'll need something like this when you realise you have just committed your ssh keys |
|
\item Mistakes happen |
|
\end{itemize} |
|
\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{tldr} |
|
Git's built in help is very thorough - sometimes you don't want that though. |
|
\note{% |
|
For the time that you accidentally commit your ssh keys. |
|
|
|
I accidentally committed a database for an Woocommerce site. |
|
} |
|
\end{frame} |
|
|
|
\end{document}
|
|
|