\tikzstyle{branch} = [ellipse, text centered, text=green]
\tikzstyle{branch} = [ellipse, text centered, text=green]
\tikzstyle{arrow} = [thick, <-, draw=blue]
\tikzstyle{arrow} = [thick, <-, draw=blue]
@ -84,12 +88,13 @@
Being distributed means you can work on repositories offline (Unlike SVN).
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.
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.
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}
\end{frame}
@ -103,13 +108,17 @@
Git has a reputation for being hard.
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 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.
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.
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.
Git's data model is actually quite simple (beautiful even). Understanding the basics of this
can really help.
}
}
\end{frame}
\end{frame}
@ -136,11 +145,15 @@
\href{https://gitforwindows.org/}{Git for Windows: https://gitforwindows.org/}
\href{https://gitforwindows.org/}{Git for Windows: https://gitforwindows.org/}
\note{%
\note{%
Git is probably already installed if you are on a Linux system. However, if not, it will definitely be in your standard repositories.
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.
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.
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.
Hopefully you have a version greater than 2.23.0 - if not, it's not the end of the world.
}
}
@ -156,13 +169,16 @@
\end{minted}
\end{minted}
\note{%
\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.
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.
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}.
These settings are stored in \mintinline{bash}{~/.gitconfig}.
}
}
\end{frame}
\end{frame}
\begin{frame}[fragile]
\begin{frame}[fragile]
\frametitle{Setting It Up}
\frametitle{Setting It Up}
\framesubtitle{Editor}
\framesubtitle{Editor}
@ -183,9 +199,11 @@
\end{minted}
\end{minted}
\note{%
\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.
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.
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}
\end{frame}
@ -210,7 +228,9 @@
\end{minted}
\end{minted}
\note{%
\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.
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.
Take note of the incorrect spelling of colour.
@ -228,10 +248,13 @@
\textbf{Commit} A snapshot of your code
\textbf{Commit} A snapshot of your code
All of these are referenced by a hash and stored in the \mintinline{bash}{.git/objects/} directory.
All of these are referenced by a hash and stored in the \mintinline{bash}{.git/objects/}
directory.
\note{%
\note{%
Most Git tutorials I have come across focus on memorizing commands. This way, the commands feel like magic and there is never really any understanding of what the commands do under the hood.
Most Git tutorials I have come across focus on memorizing commands. This way, the commands
feel like magic and there is never really any understanding of what the commands do under
the hood.
}
}
\end{frame}
\end{frame}
@ -257,7 +280,9 @@
.3 files.
.3 files.
}
}
\note{%
\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.
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.
However, this is a simple approach and not a million miles from what Git does internally.
@ -283,8 +308,10 @@
\end{center}
\end{center}
\note{%
\note{%
\begin{itemize}
\begin{itemize}
\item This is a simple representation of the folder structure we saw, although for simplicity, I'm only showing 3 revisions.
\item This is a simple representation of the folder structure we saw, although for
\item Notice that so the computer knows the order, somewhere in each ``snapshot", we include a reference to the previous snapshot
simplicity, I'm only showing 3 revisions.
\item Notice that so the computer knows the order, somewhere in each ``snapshot", we
include a reference to the previous snapshot
\end{itemize}
\end{itemize}
}
}
\end{frame}
\end{frame}
@ -309,9 +336,13 @@
\end{center}
\end{center}
\note{%
\note{%
\begin{itemize}
\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 Rather than human readable names, Git references each snapshot (called a commit)
\item Similarly to the model above, each commit references the previous (except the first obviously)
by a cryptographic hash. Currently using a hardened sha1 but there is an effort to
\item The commit also includes meta information such as the committer, a timestamp and a message.
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.
\item We will look at this in more detail a bit later.
\end{itemize}
\end{itemize}
@ -334,9 +365,14 @@
\end{tikzpicture}
\end{tikzpicture}
\end{center}
\end{center}
\note{%
\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.
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.
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}
\end{frame}
@ -361,9 +397,11 @@
\end{tikzpicture}
\end{tikzpicture}
\end{center}
\end{center}
\note{%
\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.
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.
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.
By default, git creates a branch called Master when you create a repository.
}
}
@ -378,7 +416,8 @@
\note{%
\note{%
Do this in a live terminal. MAKE SURE YOU MAKE YOUR FONT BIGGER
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.
Show that the \mintinline{bash}{.git} folder has been created and do a tree to show what is
in it.
}
}
\end{frame}
\end{frame}
@ -391,7 +430,8 @@
\note{%
\note{%
Create repo and create a file called greeting.py. Make sure to mark it as executable.
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.
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}
\end{frame}
@ -407,7 +447,10 @@
\note{%
\note{%
The staging area is where you put things that you want to be committed.
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.
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.
We will talk about \mintinline{bash}{.gitignore} in a bit.
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.
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}
\end{frame}
@ -443,9 +488,11 @@
\note{%
\note{%
First line is often shown by various tools
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
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.
Generally you will want to write in imperative as this is what automatic commits like merge
do.
}
}
\end{frame}
\end{frame}
@ -499,6 +546,38 @@
}
}
\end{frame}
\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]
\begin{frame}[fragile]
\frametitle{Diff}
\frametitle{Diff}
\begin{minted}{bash}
\begin{minted}{bash}
@ -510,7 +589,8 @@
git diff a/file
git diff a/file
\end{minted}
\end{minted}
\note{%
\note{%
Diff is pretty smart. It will normally work for whatever combinations of commits, references (more on that later) or files.
Diff is pretty smart. It will normally work for whatever combinations of commits, references
I said earlier that we would be looking at how all this works at quite a low level. This is where that starts.
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.
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.
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.
Hopefully you will see from this that the inner workings of git isn't that complicated.
}
}
@ -557,7 +642,8 @@
\begin{frame}
\begin{frame}
\frametitle{References}
\frametitle{References}
\begin{itemize}
\begin{itemize}
\item We have just seen that commits are simply (compressed) text files, addressed by a hash.
\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 References are a way of addressing them without remembering the hash.
\item Unlike the hashes, references can change - and they do change.
\item Unlike the hashes, references can change - and they do change.
\end{itemize}
\end{itemize}
@ -586,7 +672,8 @@
\end{center}
\end{center}
\begin{itemize}
\begin{itemize}
\item References are stored in the \mintinline{bash}{.git/refs} folder
\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
\item The \mintinline{bash}{heads} folder contains references to the heads (or tips) of all
local branches
\end{itemize}
\end{itemize}
\note{%
\note{%
}
}
@ -604,39 +691,12 @@
\note{%
\note{%
Not sure why it is not in refs folder
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.
If it refers directly to a commit, the repository is in what is called a ``detached head"
state.
}
}
\end{frame}
\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]
\begin{frame}[fragile]
\frametitle{Branches}
\frametitle{Branches}
@ -664,9 +724,12 @@
They can be created by simply creating a file there.
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.
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.
Be aware that a lot of tutorials etc. will use the checkout command. Version 2.23.0 was
released in August 2019.
}
}
\end{frame}
\end{frame}
@ -680,11 +743,13 @@
\note{%
\note{%
As we saw, there are numerous ways to create the commit.
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.
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.
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.
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}
\end{frame}
@ -742,7 +807,8 @@
\note{%
\note{%
At times, git won't be able to merge automatically.
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.
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.
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}{=======}.
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.
All you (the programmer) needs to do is fix it.
}
}
@ -768,6 +836,31 @@
}
}
\end{frame}
\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}
\begin{frame}
\frametitle{Git $\ne$ GitHub}
\frametitle{Git $\ne$ GitHub}
\begin{itemize}
\begin{itemize}
@ -778,6 +871,7 @@
\item It it very popular
\item It it very popular
\end{itemize}
\end{itemize}
\note{%
\note{%
By this point, we have covered a lot of the day-to-day stuff about Git.
}
}
\end{frame}
\end{frame}
@ -843,5 +937,16 @@
}
}
\end{frame}
\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}
\end{document}
%\textbf{Staging area} Waiting area before a commit
%\textbf{Staging area} Waiting area before a commit