Article was written by Ian Miell, author of the Educative course “Learn Git the Hard Way”.
Git can be utterly bewildering to someone who uses it casually or is not interested in things like directed acyclic graphs.
It’s difficult to get started, but you’ll find git has many useful tricks and layers that can bring your project to the next level. The best way to learn is with the help of an expert who started where you are now.
Today, I’ll briefly go through five things I wish someone had explained to me before I started using git.
Here’s what we’ll cover today:
CVS had two states of data:
Whereas git has four states:
If like me, you use
git commit -am "checkin message" to commit your work, then the second “adding/staging” state is more or less invisible to you. Instead, the
-a does it for you. It’s for this reason that I encourage new users to drop the
-a flag and
git add by hand, so that they understand these distinctions.
One subtlety is that the
-a flag doesn’t add new files to the content tracked by git – it just adds changes made.
These states exist so that people can work independently and offline, syncing later. This was the driving force behind the development of git.
From this comes another key point: all git repositories are created equal.
My clone of your repository is not dependent on yours for its existence. Each repository stands on its own, and is only related to others if you configure it so. This is another key difference between git and more traditional (nay, obsolete) client/server models of content history management.
This results in a far more flexible but potentially more complicated workflow. The workflow now looks more like this:
Git docs and blogs keep talking about references, but what is a reference?
A reference is just that: a pointer to a commit. And a commit is a unique reference to a new state of the content.
Once you understand this, a few other concepts make more sense.
HEAD is a reference to “where you are” in the content history. It’s the content you’re currently looking at in your git repo.
git commit, the
HEAD moves to the new commit.
git tag reference is one that can have arbitrary text, and does not move when a new commit is seen.
git branch is a reference that moves with the
HEAD whenever you commit a new change.
A couple of other confusing things then become clearer. For example, a
detached HEAD is nothing to panic about despite its scary name – it just means that your
HEAD is not pointed at a branch.
Take a look at this diagram:
It represents a series of commits.
Confusingly, with git diagrams, the arrows go backwards in time.
A is the first commit, then
B, and so on to the latest commit (
There are three
master (which is pointed at
experimental, which is pointed at
HEAD, which is also pointed at
HEAD essentially means “where we are”.
Now that you understand what a
HEAD reference is, understanding what a fast-forward is pretty simple.
Usually, when you merge two branches together, you get a new commit:
In the above diagram,
I is a commit that represents the merging of
G from its common ancestor (
D). The changes made on both branches are applied together from
D and the resulting state of the content after the commit is stored in a new state (
But consider the diagram we saw above:
There we have two branches, but no changes were made on one of them. Let’s say we want to merge the changes on
master – we’ve experimented, and the experiment was successful.
In this case, merging
H into master requires no changes from
H, since there are no
G changes that need to be merged together with
H. They are all in one line of changes.
Such a merge only requires that the
master reference is picked up and moved from
H. This is a “fast-forward” – the reference just needed moving along, and no content needed to be reconciled.
My manual page for git rebase says:
“Reapply commits on top of another base tip.”
This is more understandable than previous versions of this main page, but will still confuse many people.
A visual example makes it much clearer.
You could merge
feature1 into the
master branch, and you’d end up with a new commit (
G), which makes the tree look like this:
You can see that you’ve retained the chronology, as both branches keep their history and order of commits.
git rebase takes a different approach. It ‘picks up’ the changes on our branch (commit
feature1 in this case) and applies it to the end of the branch we are on (
HEAD is at
This looks a lot neater, doesn’t it? master can now be ‘fast-forwarded’ to where
feature1 is by moving
master‘s pointer along to
The downside is that we’ve lost something a slight organizational benefit by doing this. It no longer reflects the order things happened in chronologically. This is a trade-off you’ll have to consider on a case-by-case basis.
The above concepts are all interesting, but how can you use these in your day-to-day work?
For this, I highly recommend getting to grips with git’s native log command. While there are many GUIs that can display history, they all have their own opinions on how things should be displayed, and moreover are not available everywhere. As a source of truth, git log is unimpeachable and transparent.
I wrote about this in more depth here, but to give yourself a flavor, try these two commands on a repo of your choice. They cover 90% of my git log usage day-to-day:
$ git log --oneline --graph $ git log --oneline --graph --simplify-by-decoration --all
onelinedirects the log to only show the commit id and comment per-commit
graphprovides a visual of the structure right in your terminal
simplify-by-decorationtrims all minor changes from git history, allowing you to see all big developments across a project’s history
I hope these tips smooth your learning curve with Git and gave you one or more new tools for your next project. You’ll also need hands-on practice to make sure you’re ready to use Git professionally when the time comes.
To help you practice, I’ve adapted my book into an interactive Educative course, called Learn Git the Hard Way. This course starts off with fundamental concepts like repositories and commits and helps build your knowledge by exploring Git stash, pushing code, and more. By the end, you’ll have all the Git skills employers are looking for and a certificate to prove it.
Join a community of 500,000 monthly readers. A free, bi-monthly email with a roundup of Educative's top articles and coding tips.