\documentclass{lug} \usepackage{csquotes} \MakeOuterQuote{"} \usepackage{listings} \title{Git} \author{Sumner Evans} \begin{document} \section{Introduction} \begin{frame} \frametitle{What is Git?} \begin{itemize}[<+->] \item Git is a system which tracks changes made to a code base. \item Git was created by Linus Torvalds to help facilitate Linux kernel development. \item Linus's motto when he built Git was to take Concurrent Version System (CVS) as an example of what \textit{not} to do and if in doubt, make the opposite decision. \footnotemark \end{itemize} \uncover<3>{\footnotetext[1]{https://en.wikipedia.org/wiki/Git}} \end{frame} \begin{frame} \frametitle{Why use Version Control? I} Example Scenario: \begin{enumerate}[<+->] \item You start a project called "my-proj" and write a ton of code. \item You finally get it to (kinda) work. \item You decide to make a copy of "my-proj" for backup purposes. \item You continue development on "my-proj" but then screw something up really bad. \item You decide to revert back to your copy. \item Then you realize your copy doesn't have a bug fix that you actually wanted. \item You then proceed to manually compare the files in the backup to those in your new code and figure out what you still want to have. \end{enumerate} \uncover<8>{This is terrible.} \end{frame} \begin{frame} \frametitle{Why use Version Control? II} Another Scenario: \begin{enumerate}[<+->] \item You start working on a project with a partner. \item You write a bunch of code. \item You email the code in a .zip file, then go home for the weekend. \item You and your partner had decided to work on two separate tasks over the weekend so you make some changes to the code and your partner makes some changes to the code. \item You come together and start copying files. Then you realize you both modified \texttt{main()}. \item You then manually determine what changed in both files and reconcile them. \end{enumerate} \uncover<7>{This is awful.} \end{frame} \begin{frame} \frametitle{Why use Version Control? III} How Version Control Systems (VCS) solve this: \begin{itemize}[<+->] \item VCS keeps track of \textit{revisions}, changes in the code in entities called \textit{changesets} or \textit{commits}. \item Most VCS allow version merging. That means multiple people can be working on the same file and resolve discrepancies later. Git is very elegant in handling merge conflicts such as this. \end{itemize} \end{frame} \begin{frame} \frametitle{Why use Git?} Git is a VCS so it solves all of the issues I've described. So why use Git over some other VCS?\footnotemark \begin{itemize}[<+->] \item It's a \textit{distributed} VCS. That means that you have a full copy of the code and every change ever made by anyone to that code on your local machine. A beneficial side effect of this is that you can work offline. \item It's faster. \item Git rarely fully deletes anything, this is good because you can undo most actions. \item Everyone else is using it. \end{itemize} \footnotetext[2]{List inspired by \url{https://www.git-tower.com/blog/8-reasons-for-switching-to-git}} \end{frame} \begin{frame} \frametitle{How to Get Git} Git is awesome! How do I get it? \textbf{Good news: Git is cross platform.} \begin{itemize} \item \textbf{Linux:} Install the \texttt{git} package using your distribution's package manager \item \textbf{OS X:} I recommend using Homebrew: \texttt{brew install git} (\url{http://brew.sh/}) \item \textbf{Windows:} Download the installer from \url{https://git-scm.com/} \end{itemize} If you need a GUI, check out SourceTree or GitKraken. You should also setup SSH which is extremely easy, but I will not cover that here as this is a talk about Git not SSH. \end{frame} \begin{frame} \frametitle{Hot to use Git (locally)} \begin{itemize} \item Initialize (\texttt{git init}): Initializes a Git \textit{repository} on your local machine in the current \textit{working directory}. \item Add (\texttt{git add}): Marks files to include in the next \textit{commit}, an entity which stores the state of the repository at a given time. \item Reset (\texttt{git reset}): Opposite of \texttt{add}; marks the file as not included in the next commit. \item Commit (\texttt{git commit}): Creates a commit. \item Log (\texttt{git log}): Shows the history of your repository. \item Diff (\texttt{git diff [file]}): Determines the difference between the file's current state and its state at the last commit. \item Git ignore (modify the \texttt{.gitignore} file): Any file that matches one of the patterns in \texttt{.gitignore} will not be tracked by Git. \end{itemize} \end{frame} \begin{frame} \frametitle{How to use Git with a remote} \begin{itemize} \item Add Remote (\texttt{git remote add [name] [url]}): Adds a \textit{remote}, a version of the repository hosted externally from your local machine. Most likely on something like Github or an company's internal network. \item Push (\texttt{git push -u origin master}): Pushes all changes on the given branch to the remote. \item Clone (\texttt{git clone}): Copies the entire repository to the location. \item Fetch (\texttt{git fetch}): Retrieves changes from the remote. \item Merge (\texttt{git merge}): Merges a branch into another branch. (More on branches later, but in this case, we are merging the \texttt{origin/master} into our local \texttt{master} branch.) \item Pull (\texttt{git pull}): Retrieves any new changes from the remote and merges them with your local changes. \end{itemize} \end{frame} \begin{frame} \frametitle{Undoing Things} \begin{itemize} \item Undo the last $n$ commits (given that you haven't pushed them yet) \texttt{git reset --hard HEAD\textasciitilde n} \item Undo the $n^{th}$ to last commit by creating a new commit that reverts all of the changes \texttt{git revert HEAD\textasciitilde n} \item Somebody's done it before. Just Google it. \end{itemize} \end{frame} \begin{frame} \frametitle{Merging Changes I} What happens if multiple developers make changes to the same file? This will cause \textit{merge conflicts}.\\ There are plenty of tools which you can use to \textit{resolve} such conflicts. None of them are that good because merge conflicts are just terrible in general.\\ Play around with a bunch of them and see which one you like best. Here are a few to get you started: \texttt{Meld}, \texttt{KDiff3}, and \texttt{vimdiff}.\\ \end{frame} \begin{frame} \frametitle{Merging Changes II} Invoking the \textit{mergetool}: use \texttt{git mergetool}.\\ For each \textit{conflict}, you can choose to take their version, your version, a combination of the two or neither.\\ Most UIs will give you three panes: one for the \textit{remote} version of the file, one for the \textit{local} version of the file and one for the merged version of the file. \end{frame} \begin{frame} \frametitle{Branches I} Branches allow you to separate develop a given functionality without affecting the original code base.\\ For example, if you have an established product and you want to add a feature but you are uncertain about its viability, you can create a branch and build a prototype on that branch. If it fails, you can delete the branch and never see it again or if it works, you can \textit{merge} the branch back into \texttt{master}. \end{frame} \begin{frame} \frametitle{Branches\footnotemark II} Branches can be thought of as \textit{bookmarks} pointing to a specific changeset. \begin{center} \includegraphics[width=60mm]{graphics/branching1.png} \end{center} \textit{Note, \texttt{HEAD} is pointer to the current branch.} \footnotetext[3]{Info in the rest of the \textit{Branches} section is mainly from \url{https://git-scm.com/book/en/v1/Git-Branching-What-a-Branch-Is}} \end{frame} \begin{frame} \frametitle{Branches III} To switch branches, use \texttt{git checkout [branch]}. This moves \texttt{HEAD} to point to your new branch. \begin{center} \includegraphics[width=65mm]{graphics/branching2.png} \end{center} \end{frame} \begin{frame} \frametitle{Branches IV} If you commit something to your new branch, the branch pointer moves to the new commit. The pointer to \texttt{master} will not move. \begin{center} \includegraphics[width=65mm]{graphics/branching3.png} \end{center} \end{frame} \begin{frame} \frametitle{Branches V} Of course, you can always switch back to \texttt{master} using \texttt{git checkout master}. \begin{center} \includegraphics[width=65mm]{graphics/branching4.png} \end{center} \end{frame} \begin{frame} \frametitle{Branches VI} If you make a commit on the master branch, the \texttt{master} pointer moves to that new commit. At this point, the branch histories have diverged. \begin{center} \includegraphics[width=65mm]{graphics/branching5.png} \end{center} \end{frame} \begin{frame} \frametitle{Branches VII: How to actually do it} \begin{itemize} \item \textbf{Create a Branch:} \texttt{git branch [branch\_name]} \item \textbf{Switch to a branch:} \texttt{git checkout [branch\_name]} \item \textbf{Create a new branch and switch to it:}\\ \texttt{git checkout -b [branch\_name]} \item \textbf{List branches:} \texttt{git branch} \item \textbf{Push branch to remote:} \texttt{git push -u [remote\_name] [branch\_name]} \end{itemize} \end{frame} \begin{frame} \frametitle{Merging Changes: Branch Edition} If you want changes from a different branch in your current branch, you can use \texttt{git merge [other branch]}.\\ When you merge changes from another branch, one of two things will happen\footnotemark: \begin{enumerate} \item Your branch will be fast-forwarded to the other branch.\\ This means that there are no changes in your current branch that are not in the other branch. \item A merge commit will be created and your branch pointer will be updated to point to this commit.\\ This happens when there are changes in the current branch that are not in the other branch. \end{enumerate} \footnotetext[4]{These are the only ones I can thing of off the top of my head. You can force either of these functionalities with their respective command line options.} \end{frame} \begin{frame} \frametitle{Branch and Development Workflow} Branches are extremely scalable so you can ignore them, or use them for everything, it's your choice.\\ One methodology used by companies in the industry is \texttt{Git Flow}. This is a system whereby new branches are created for every bugfix, new feature, release, and hotfix. If you want to learn more about it, look at this website: \url{http://nvie.com/posts/a-successful-git-branching-model/} \end{frame} \begin{frame} \frametitle{The Random Stuff: Stashing} When you have changes in your working directory, merges and switching branches (sometimes) doesn't work. You have two main options here: \begin{enumerate} \item Commit your changes. If you can do this, you should. \item Occasionally you just don't want to commit. In this case, you will want to \textit{stash} your changes using\\ \texttt{git stash [save [stash\_name]]}. \item To un-stash, use \texttt{git stash pop}. You may have to resolve merge conflicts. \end{enumerate} \end{frame} \begin{frame} \frametitle{The Random Stuff: Submodules} \textbf{What is a submodule?} It is literally a repository inside of another repository.\\ \textbf{Why is this useful?} If you have a custom library shared between many projects, you can place that library in a standalone Git repository. Then you can add it as a submodule to your products via \texttt{git submodule add [clone\_url]}. The submodule is its own repository so it can be contributed to independently, but it can also be modified and contributed to as a submodule. \end{frame} \begin{frame} \frametitle{The Random Stuff: Rebasing} \textbf{What is it good for?} If you want to keep your graph clean, you can use rebasing to avoid merge commits.\\ \textbf{Why would you use this?} I don't know. I never have and I normally want to see all of the changes in a graph, but it's a thing that you can do in Git and if you want to learn more, read the docs. \end{frame} \begin{frame} \frametitle{The Random Stuff: Aliases} As one would expect from something designed and built by Linus Torvalds, Git supports the concept of \textit{aliasing} one git command to another name.\\ For example, you might want to alias \texttt{checkout} to \texttt{co}. This particular alias can be achieved using \\ \texttt{git config --global alias.co checkout}.\\ Now you can invoke \texttt{git checkout} using \texttt{git co}.\\ Another option is using your shell's alias functionality. This is often more powerful, but that isn't part of this talk. \end{frame} \begin{frame} \frametitle{The Random Stuff: Resources/Tips} I obviously was unable to tell you about everything you can do with Git. I've really only scratched the surface. \begin{itemize} \item \texttt{man git *}: The man pages on Git are good. Use them as your first line of defense. \item \texttt{git-scm.com/book/en/v2}: A huge resource about how to do everything Git. \item \texttt{gitignore.io}: Generates a \texttt{.gitignore} file for a given project type, OS, and IDE. \item \texttt{git reset --hard HEAD}: Undoes all changes since the last commit. \item \texttt{git diff HEAD:file1 file2}: Shows the difference between \texttt{file1} and \texttt{file2}. \end{itemize} \end{frame} \begin{frame} \frametitle{Where to Go from Here?} \begin{itemize}[<+->] \item If you haven't ever used Git, start by using it locally and with Github. \item If you know the basics, start exploring branches. Learn about them and find a flow which works best for you. \item If you know most things about Git, just keep using it. Try and start remembering how to do certain things that you find yourself often Googleing for. \end{itemize} Become the person everyone asks for Git advice. It's used in the industry, so many companies will want to see knowledge of this tool. \end{frame} \end{document}