Git Essentials - Part 1
Table of Contents
Introduction
When I started to work in my first company they were changing the Version Control System (VCS) [1] from Apache Subversion (SVN) [2] to Git [3]. I quickly started to become the expert of the company since I was the last joiner and I had the opportunity to spend time learning the basics. I had also the advantage of not knowing other VCSs (like SVN) so I didn’t have a biased vision of how things were supposed to work.
After years of work I have met some people really struggling with it. It is not related to the age, the seniority or the smartness of a person, but using git looks like a binary skill: you either have developed it or not.
With this article I will explain what is, in my opinion, the most important (and often hidden) thing about Git. I hope that by starting with it you will be able to overcome any insecurity and start seeing the value of using Git as a tool that allows you to relax. Not another thing you need to worry about.
The basic configuration
Before beginning our discussion on how to properly learn it, let’s review the basic configurations starting from scratch. You just have installed Git.
In order to be able to create a new commit you need to configure your name and email. Be careful with the email. If you publish your code on a public repository (like GitHub) you might expose a working email and some scammers (or some bot programmed by them) will start sending you unwanted emails. So, unless your code will stay in a private repository of a company, it is advisable to put a fake email or something like “noreply@domain.com”. My configuration is:
git config --global user.name "BSDrulez"
git config --global user.email "noreply@bsdrulez.neocities.org"
The flag --global
tells Git to store that configuration in the
global config file of your user in that particular machine
($HOME/.gitconfig
on a Unix-like OS). If you remove this parameter
it will use the file .git/config
in your current project.
Git has been designed to be used from the command line and even if you are not used to using it, it’s better to start learning from there. Then you can move to use a standalone UI or the integration with your favorite IDE. In my experience, if you start from the latter you will be more confused.
That being said the commands of Git can be a little bit too long to
type every time, so it is important to take advantage of the
autocompletion of the shell (if available) or of the concept of
alias (always available because it is built-in in Git). With an
alias, we can just type git st
in the terminal instead of the long
version git status -s
. This might seem a little bit overkill, but
you are going to love using those aliases.
This is my list (don’t worry if you don’t understand them all right now):
git config --global alias.br "branch"
git config --global alias.st "status -s"
git config --global alias.co "checkout"
git config --global alias.df "diff --raw"
git config --global alias.lo "log --all --oneline --graph --decorate"
The most effective way of learning it: develop a simple project
To learn how to use Git it is better to start practicing with an
example. There is no need to involve source code, just regular text
files are ok. For this reason, let’s say you want to improve your
vocabulary so you want to keep track of words and meanings in a
regular text file. Create an empty folder and create a file with your
favorite text editor and put some words in it (call the file
eng.txt
):
house = place where you live
pizza = traditional Italian food (dough, tomato sauce and mozzarella)
Every day you add new words, review the list and correct mistakes. Why would you use Git in the first place? Some initial benefits are:
- you want to save the state of your project so in case you make unwanted changes you will be able to revert to a previous state
- you want a convenient method to review the changes you did before saving the state
To tell Git that it must take care of your new project you can open
the terminal in your project’s folder and execute git init
. This
will create the folder .git
(hidden by default in Unix-like OS) and
some configuration files (like .git/config
). Now you have converted
the folder of the project into a Git Repository (a local repository
just on your laptop). What does it mean? In practice when you run Git
commands from this folder the VCS will save your project and its
evolution over time in the folder .git
. With appropriate commands,
you will be able to restore a saved state of your project, jump to
another state, show the differences between two states, etc.
We need to be familiar with these concepts:
- working directory: the content of the project’s folder except for
.git
and.gitignore
- commit: a snapshot of the project
- staging area: changes that are meant to be saved in the next commit
A file in the working directory can be:
- untracked: the file is in the working directory but we never included it in any commit
- modified: we have changed the content of a file that was previously saved in a commit (and it is not ready to be saved in the next commit)
- staged: a file we have flagged to be saved in the next commit
- ignored: if a file has never been saved in any commit and the
file name matches a pattern in
.gitignore
, Git will pretend this file does not exist
Type git st
and check the output:
?? eng.txt
the couple of red question marks (??
) means Git is seeing one untracked file in
the working directory. Every new file we create will
start from the status untracked. Run the following two commands to
stage the file and save its content in the new commit.
git add eng.txt
git commit -m "English dictionary - day 1"
Add a new word and repeat the previous two commands
changing the number of the day in the commit message (you need to
repeat also git add
because otherwise git will ignore your new
changes). Do it once more so
we have simulated our work up to day 3. The content of my file is now:
house = place where you live
pizza = traditional Italian food (dough, tomato sauce and mozzarella)
cat = a popular pet especially among software developers
withdraw = remove from a group or from consideration
You can develop a better understanding of how the status of eng.txt
changes when edited, staged and committed by running git st
before
and after every operation. You should be able to see when a file is
modified (a red M in the output of git st
) and when it is staged
(a green M). After the commit, the status of the working directory is
the same as the last commit so the output will be an empty line.
The most important piece of the puzzle
To fully understand Git you need to be able to check the status of the
repository and imagine how it changes after every operation. In
practice you need to check and understand the tree of commits that is
shown by git log --all --oneline --graph --decorate
. If you run this
command in your project you will see a stream of three commits similar
to the following:
* 39cd015 (HEAD -> master) English dictionary - day 3
* 26ea295 English dictionary - day 2
* f62b56e English dictionary - day 1
This is a linear sequence of the three commits we created so far. The sequence is in reverse chronological order therefore the most recent commit is at the beginning. Even though it might not be evident in a simple case like this, the asterisks represent the dots in a graph: the status of a repository. All the rest of the data in the same line help to identify which commit is and a few other details.
Take time to learn in-depth about everything you see in this graph.
Let me explain the main details in our graph:
- as already said, each asterisk is a commit
- the hexadecimal value close to the asterisk is an identifier for that commit
- the rest of the line shows the commit message
- at the moment you can ignore the words
HEAD
andmaster
(they will be explained in detail in the next article) - in more complicated graphs, you will see some connections between the asterisks
- the connections represent the relationships between the commits: internally Git saves only the changes between states so the graph is its internal map to rebuild the full status of a project at a given commit
- when there is no connection between two asterisks it means the upper is a child of the lower; if all the connections were shown the graph would be:
* 39cd015 (HEAD -> master) English dictionary - day 3
|
* 26ea295 English dictionary - day 2
|
* f62b56e English dictionary - day 1
- HEAD tell us what is the current commit (a new commit will be a child of this one)
- master is the name of a local branch (ignore this at the moment)
In case you haven’t guessed it, yes, you can use the handy short
command git lo
to display the same graph (thanks to the alias we
defined at the beginning of this article).
This graph is so useful that I don’t know why
there isn’t a simple command already implemented.
To practice your understanding proceed with the following exercise:
- create a new folder for a new project
- open the shell in the folder
- initialize the git repository:
git init
- before and after every command check the status of the repo with:
git st
andgit lo
- create/edit/save a text file
For example:
git init
git st
git lo
# create a text file called newfile.txt
git st
git lo
git add newfile.txt
git st
git lo
git commit -m "add first text file"
git st
git lo
# edit the content of newfile.txt
git st
git lo
git add newfile.txt
git st
git lo
git commit -m "added/modified content to text file"
git st
git lo
Running git st
and git lo
like that looks a little bit pedantic,
but it is a very effective way of understanding how git works.
To verify your understanding, the next exercise is to guess what will
be the output of git st
and git lo
before running it:
- in the same project as the previous exercise, create a new file
- try to guess what will be the output of
git st
- run
git st
- guess the output of
git lo
- run
git lo
- edit the first text file (created in the previous exercise)
- make your guess and then run
git st
- do the same for
git lo
- continue like that with different combinations of the following
operations
- add a file with
git add
- edit one of the files
- create a commit
- add a file with
Conclusions
Let me break here for today. In this article we saw how to start using Git and how we can learn step by step with a simple exercise. In the next articles we will talk about branches, how to jump from one state to another, how to check the differences and much more.
That being said the most important piece of the puzzle is to start
understanding the commit’s graph shown by git lo
. Start using
git st
and git lo
before and after every operation. Then challenge
yourself and try to guess what is the output of the command before
running it. When you are able to foresee the changes to the
graph in your head you will have mastered Git. In the following
articles we explain the graph even further and we will add new pieces
of it.
References
[1] https://betterexplained.com/articles/a-visual-guide-to-version-control