git-quick-start

an introduction to Git version control
git clone git://src.adamsgaard.dk/git-quick-start # fast
git clone https://src.adamsgaard.dk/git-quick-start.git # slow
Log | Files | Refs | README | LICENSE Back to index

git-quick-start.tex (13381B)


      1 %\documentclass[11pt,a4paper]{article}
      2 \documentclass[11pt]{article}
      3 
      4 %\usepackage{a4wide}
      5 \usepackage[margin=1.4in]{geometry}
      6 
      7 \usepackage{graphicx}
      8 %\usepackage[german, english]{babel}
      9 %\usepackage{tabularx}
     10 %\usepackage{cancel}
     11 %\usepackage{multirow}
     12 %\usepackage{supertabular}
     13 %\usepackage{algorithmic}
     14 %\usepackage{algorithm}
     15 %\usepackage{amsthm}
     16 %\usepackage{float}
     17 %\usepackage{subfig}
     18 %\usepackage{rotating}
     19 \usepackage{amsmath}
     20 
     21 \usepackage[T1]{fontenc} % Font encoding
     22 \usepackage{charter} % Serif body font
     23 \usepackage[charter]{mathdesign} % Math font
     24 \usepackage[scale=0.9]{sourcecodepro} % Monospaced fontenc
     25 \usepackage[lf]{FiraSans} % Sans-serif font
     26 
     27 \usepackage{listings}
     28 \lstset{
     29     basicstyle=\ttfamily
     30 }
     31 \usepackage{hyperref}
     32 
     33 \usepackage{soul} % for st strikethrough command
     34 
     35 %\usepackage[round]{natbib}
     36 \usepackage[natbib=true, style=authoryear, bibstyle=authoryear-comp, 
     37 maxbibnames=10,
     38 maxcitenames=2, backend=bibtex8]{biblatex}
     39 \bibliography{/Users/adamsgaard/articles/own/BIBnew.bib}
     40 
     41 
     42 \begin{document}
     43 
     44 \title{A quick-start guide to Git}
     45 
     46 \author{Anders Damsgaard\\\url{https://adamsgaard.dk}, \url{andersd@riseup.net}}
     47 \date{{\small Last revision: \today}}
     48 
     49 \maketitle
     50 
     51 \section{What is Git?}
     52 Git is the most popular command-line tool for version control.  It is most 
     53 commonly used to track changes to plain-text files such as source code.  When a 
     54 software project is initialized as a Git \emph{repository}, the history of the 
     55 tracked files are recorded through a series of changes.  When the user performs 
     56 changes to the tracked files, she can choose to \emph{commit} these changes.  
     57 Git repositories can be managed through online services such as 
     58 Github\footnote{\url{https://github.com}}, which allows the changes to be 
     59 synchronized between multiple contributers and end users.  The same repository 
     60 can contain multiple versions of the same files.  These coexisting versions are 
     61 called \emph{branches}.
     62 
     63 Git usage is typically very verbose and by design weighs explicitness over 
     64 convenience.  This ensures that its default behavior does not lead to unintended 
     65 outcomes.
     66 
     67 \section{Installation}
     68 Please refer to the official documentation\footnote{%
     69 \url{https://git-scm.com/book/en/v2/Getting-Started-Installing-Git}} for 
     70 platform-specific instructions on how to install Git.
     71 My prefered installation method on OS X is through 
     72 Homebrew\footnote{\url{http://brew.sh}}:
     73 \begin{lstlisting}
     74     $ brew install git
     75 \end{lstlisting}
     76 On Debian-based systems, Git can be installed through the advanced package tool:
     77 \begin{lstlisting}
     78     $ apt-get install git
     79 \end{lstlisting}
     80 
     81 Git has excellent built-in documentation through its man page (i.e.
     82 \lstinline{man git}).  For documentation on a sub-command such as
     83 \lstinline{git add}, see its documentation with \lstinline{man git-add}. For 
     84 more complex tasks, I recommend referring to a Git handbook or searching the web 
     85 (in that order).
     86 
     87 \section{Getting started}
     88 Before using Git for version control, it is a good idea to record some 
     89 information about yourself. This makes it is easy to see who specific commits 
     90 can be attributed to when working on projects with multiple contributors.  The 
     91 user information is stored in a plain-text file in the home directory 
     92 (\lstinline{~/.gitconfig}), and can be created with the following commands:
     93 \begin{lstlisting}
     94     $ git config --global user.name "John Doe"
     95     $ git config --global user.email "john-doe-farms@aol.com"
     96 \end{lstlisting}
     97 
     98 \section{Initializing a repository}
     99 In order to track changes to files in a directory, the directory needs to be 
    100 initialized as a repository.  Let's say that we want to track the changes to a 
    101 file \lstinline{arithmetic.c} which located in the directory 
    102 \lstinline{~/src/calculator}.  We start off by initializing the directory as a 
    103 repository:
    104 \begin{lstlisting}
    105     $ cd ~/src/calculator
    106     $ git init
    107     Initialized empty Git repository in ~/src/calculator/.git/
    108 \end{lstlisting}
    109 Git lets us know that the directory is initialized as a new repository, and that 
    110 the hidden sub-directory \lstinline{.git} is used for the files related to the 
    111 version control\footnote{This directory contains many interesting files, and I 
    112     encourage you to explore it when you are more familiar with Git.}.
    113 
    114 It is important to realize that just because you initialize a directory as a Git 
    115 repository, the files and subdirectories are \emph{not automatically tracked}!  
    116 You need to manually specify which files inside of the directory you want to 
    117 include in the version control system.  There are several important reasons for 
    118 this.  As an example, during the compilation step many compilers create object 
    119 files which are linked together to create the final executable binaries.  These 
    120 object files are created in machine code, and can have a significant size on the 
    121 file system.  If Git automatically recorded the changes and versions to all 
    122 files inside of the repository, it would save all changes in the binary object 
    123 files, which are of no use since they can be readily reconstructed from the 
    124 source code.
    125 
    126 \section{Creating a local copy of an online repository}
    127 If you want to create a local copy of an online repository you can download a 
    128 clone of it in its current stage to your local file system:
    129 \begin{lstlisting}
    130     $ git clone git://github.com/john-doe/tractor-simulation
    131 \end{lstlisting}
    132 This will checkout the online repository on Github into a corresponding 
    133 directory in the local directory.  You can also choose to clone over other 
    134 protocols such as SSH or HTTPS if you prefer.
    135 
    136 The local repository will remember where it was cloned from.  If you have write 
    137 permissions to the online repository, you can upload your local commits using 
    138 \lstinline{git push}.
    139 
    140 \section{Adding files and commiting changes}
    141 To add a file to the version-control system inside a repository, use the 
    142 following command:
    143 \begin{lstlisting}
    144     $ git add arithmetic.c
    145 \end{lstlisting}
    146 
    147 One or more changes to the tracked files in a repository must be accompanied by 
    148 a \emph{commit message}.  The commit message should ideally be short and 
    149 descriptive of the changes that are contained in the commit.  The commit 
    150 messages are logged.  It should be easy for a user to glance through the log of 
    151 commit messages and understand the changes without reading the changes to the 
    152 files themselves.  This is what sets version-control systems aside from 
    153 automatic backups.  Only the user herself has the ability to identify when a set 
    154 of changes are complete and significant, and can formulate a meaningful 
    155 description of the changes in their respective context.
    156 
    157 In case you have forgotten what you have changed in a file, use the following 
    158 command:
    159 \begin{lstlisting}
    160     $ git diff -- arithmetic.c
    161 \end{lstlisting}
    162 
    163 To commit all files which have been added to the repository, you can use the 
    164 following command:
    165 \begin{lstlisting}
    166     $ git commit -m "First commit of arithmetic.c"
    167 \end{lstlisting}
    168 If you ommit the \lstinline{-m} flag and message string (i.e. simply type 
    169 \lstinline{git commit}), Git will open your favorite command-line 
    170 editor\footnote{You can set which editor you want to use using the 
    171     \texttt{EDITOR} environment variable in e.g.  
    172     \texttt{\textasciitilde/.bashrc}.}.  You then write the commit message in 
    173 the editor, and finalize the commit by saving and exiting the file.
    174 
    175 If you perform subsequent edits to the file, you need to commit the new changes 
    176 once again.  We can either once again add the file and commit the changes:
    177 \begin{lstlisting}
    178     $ git add arithmetic.c
    179     $ git commit -m "Implemented multiplication"
    180 \end{lstlisting}
    181 Alternatively, since the file \lstinline{arithmetic.c} is already added to the 
    182 repository, you can commit \emph{all} changes to \emph{all} tracked files in the 
    183 repository with a single command:
    184 \begin{lstlisting}
    185     $ git commit -a -m "Implemented multiplication"
    186 \end{lstlisting}
    187 Are you not sure which files changed since the last commit? Git can show you an 
    188 overview of the current state:
    189 \begin{lstlisting}
    190     $ git status
    191 \end{lstlisting}
    192 
    193 \section{Inspecting repository changes and reverting to a previous commit}
    194 Git can show you an overview of all recorded changes in the repository:
    195 \begin{lstlisting}
    196     $ git log
    197     commit 2745f1e3b4803f1c8728089667a18f3178cd18dc
    198     Author: John Doe <john-doe-farms@aol.com>
    199     Date:   Fri Sep  2 10:22:59 2016 -0700
    200 
    201         Implemented multiplication
    202 
    203     commit 3329dfa1b6bfecc00353d1e9db50bcab9fb41521
    204     Author: John Doe <john-doe-farms@aol.com>
    205     Date:   Fri Sep  2 10:22:13 2016 -0700
    206 
    207         First commit of arithmetic.c
    208 
    209 \end{lstlisting}
    210 Git can show the changes to the files between any two commits:
    211 \begin{lstlisting}
    212     $ git diff 3329dfa1b 2745f1e3b
    213     diff --git a/arithmetic.c b/arithmetic.c
    214     index e69de29..523d72b 100644
    215     --- a/arithmetic.c
    216     +++ b/arithmetic.c
    217     @@ -0,0 +1,4 @@
    218     +double multiply(double x, double y)
    219     +{
    220     +    return x * y;
    221     +}
    222 \end{lstlisting}
    223 
    224 In case you want to roll back your most recent changes and revert the repository 
    225 to a stage corresponding to an earlier commit.  Each commit has an uniquely 
    226 identifying string which is shown with the above command.  To revert you need to 
    227 supply the first 9 characters of this string:
    228 \begin{lstlisting}
    229     $ git checkout 3329dfa1b
    230 \end{lstlisting}
    231 This will revert any changes contained in subsequent commits.  In case you 
    232 change your mind and want to go back to the most recent commit, use:
    233 \begin{lstlisting}
    234     $ git revert HEAD
    235 \end{lstlisting}
    236 The special string \lstinline{HEAD} refers to the most recent commit, and the 
    237 commit before that is referred to by \lstinline{HEAD^}, while the third-most 
    238 recent commit is \lstinline{HEAD^^}.  These special strings are convenient, for 
    239 example when you want to see what changed during the most recent commit, which 
    240 can be done with the command \lstinline{git diff HEAD^ HEAD filename}.
    241 
    242 \section{Branching and merging}
    243 Git allows you to have multiple versions (branches) of the same repository.  The 
    244 first step is to create a new branch and give it a suitable name:
    245 \begin{lstlisting}
    246     $ git checkout -b new_interface
    247 \end{lstlisting}
    248 Subsequent commits are staged to the new branch \lstinline{new\_interface}.  You 
    249 can see which branches are present in the repository with \lstinline{git branch}:
    250 \begin{lstlisting}
    251     $ git branch
    252       master
    253     * new_interface
    254 \end{lstlisting}
    255 where \lstinline{master} is the original branch.  The asterisk denotes what current 
    256 branch is active.  You can switch between branches, which will automatically 
    257 apply all relevant patches to the affected files:
    258 \begin{lstlisting}
    259     $ git checkout master
    260 \end{lstlisting}
    261 To delete a branch, use \lstinline{git branch -d new\_interface}.  To merge another 
    262 branch into your current active branch, use:
    263 \begin{lstlisting}
    264     $ git merge new_interface
    265 \end{lstlisting}
    266 When merging, all commits and file changes performed in a branch are applied to 
    267 the currently active branch.
    268 
    269 \section{Ignoring files}
    270 Many compilers create auxillary files which are never relevant to track in a 
    271 version-control system, but clutter your repository overview when using commands 
    272 such as \lstinline{git status} or \lstinline{git commit -a}.  You can specify which 
    273 files Git should ignore by their filename in a file at the root of the 
    274 repository in a file named \lstinline{.gitignore}.
    275 For a repository containing C code, an example \lstinline{.gitignore} file could 
    276 contain:
    277 \begin{lstlisting}
    278     *.o
    279 \end{lstlisting}
    280 This will ignore all object files.  For a \LaTeX~repository the file could 
    281 contain:
    282 \begin{lstlisting}
    283     *.aux
    284     *.glo
    285     *.idx
    286     *.log
    287     *.toc
    288     *.ist
    289     *.acn
    290     *.acr
    291     *.alg
    292     *.bbl
    293     *.blg
    294     *.dvi
    295     *.glg
    296     *.gls
    297     *.ilg
    298     *.ind
    299     *.lof
    300     *.lot
    301     *.maf
    302     *.mtc
    303     *.mtc1
    304     *.out
    305     *.xdy
    306     *.synctex.gz
    307 \end{lstlisting}
    308 It is up to you to specify the contents of the \lstinline{.gitignore} file.  Maybe 
    309 your program generates output files, which should not be tracked. Simply add 
    310 their names or file type to the \lstinline{.gitignore} file and never encounter 
    311 them in your Git workflow again.
    312 
    313 \section{Extra: Useful shell aliases}
    314 I like to bind short aliases to the most commonly Git commands. I do this by 
    315 appending the following to the \lstinline{rc} file of my shell 
    316 (\lstinline{~/.zshrc} or \lstinline{~/.bashrc}):
    317 \begin{lstlisting}
    318     alias gs='git status | less'
    319     alias gl='git log --graph --oneline --decorate --all'
    320     alias ga='git add'
    321     alias gd='git diff --'
    322     alias gc='git commit -v'
    323     alias gca='git commit --all --verbose'
    324     alias gp='git push'
    325     alias gpu='git pull'
    326     alias gcgp='git commit --verbose && git push'
    327     alias gcagp='git commit --all --verbose && git push'
    328 \end{lstlisting}
    329 Using these aliases I can quickly add a file (\lstinline{ga file.c}).  
    330 Alternatively, I can quickly commit all changes to all files that are already 
    331 tracked in the repository (\lstinline{gca}).
    332 With \lstinline{gl} I can quickly see the commit tags and commit messages in short 
    333 form, and scroll up and down with \lstinline{j} and \lstinline{k} or the arrow keys.  
    334 \lstinline{gs} gives me a quick overview of the changes in the current repository, 
    335 and uses the same keys as \lstinline{gl} for scrolling.
    336 
    337 \end{document}
    338