Git Part 1: Introduction
In this post I wanted to share a little bit of what I learned so far using the version control tool Git.
Git was probably the most abstract and misunderstood point when I was studying software development. And as well in my experience as a teacher assistant for the coding bootcamp Ironhack in Berlin, it was really hard to keep things simple when using Git or teaching the basic of its usage without some layers of abstraction.
I am not going to cover the installation and setting up of Git, neither cloning or pulling a .git repository and a moderate experience with git is necessary to fully understand this post. Instead I will focus on the usage of Git on a local level, from the initialisation of a local git repository, what’s in the the .git folder and what it is for, adding files, modifying files, committing, branching, merging, rebasing and so on.
Git can be simpler to understand if we put some time to dig in, with a little bit of practice and clear explanations.
Let’s start by creating a new, empty git repository.
$ git init git_project
If we list the content of the new repository with $ ls git_project/
we don’t have anything since the new git_project repository is empty, but it contains a cached folder :
$ ls -a git_project/
. .. .git
Now let’s have a look at this directory.
$ cd git_project
$ tree .git
.git
├── HEAD
├── config
├── description
├── hooks
│ ├── ...
│ ...
├── info
│ └── exclude
├── objects
│ ├── info
│ └── pack
└── refs
├── heads
└── tags
config
are the settings for the repository. All the .git config
.
description
is used by Gitweb to display a description of the repository. We don’t really care about that.
hooks
. Git comes with a set of scrips that run before or after every action like commit, rebase, pull etc.
info
is used to exclude files we don’t want to “track”. It’s like the .gitignore
file.
To explain what is HEAD
, we first need to understand what are commits in Git and how Git stores the data.
When we are working with Git, we track our files and we regularly take pictures of our project. Git stores the data as a series of those snapshots.
Every time we take a picture, Git stores a reference to that picture. If we only change some files in our project, Git won’t store the unchanged files again but will store a link to the previous snapshot of those files.
When we create a new file and track it, ($ git add <file>
) Git compresses it and stores it. The compressed version has a unique name (a hash) and is stored in the objects/
directory. When the picture is taken, it will be as well compressed and stored in the same directory.
We take those pictures by committing.
Let’s create a file file
, add it and commit it with the comment “first commit”:
$ touch file
$ git add file
$ git commit -m “first commit”
Now lets take a look at our objects/
directory:
$ tree .git/objects/
.git/objects/
├── df
│ └── 2b8fc99e1c1d4dbc0a854d9f72157f1d6ea078
├── e6
│ └── 9de29bb2d1d6434b8b29ae775ad8c2e48c5391
├── e8
│ └── 8549a71c1749f239a1dfd499243d7703d0785e
├── info
└── pack
We have a few subdirectories under objects/
. Actually, when Git compresses an object under a hash, for example e88549a71c17…
, it will name it 8549a71c17…
and stores it under a subdirectory e8/
.
The first hash is for the file when we create it. The second hash is the snapshot, and the third one is the commit itself.
The commit is composed of a name (hash), a comment, informations about the committer, and the hash of the parent commit if it exist. (None here since this is our first commit).
$ cd .git/objects
$ git cat-file -p e88549a71c1749f239a1dfd499243d7703d0785e
tree df2b8fc99e1c1d4dbc0a854d9f72157f1d6ea078
author Pierre [...]
committer Pierre [...]first commit
HEAD
refers to the hip of our current branch. (Master branch here)
$ cd ..
$ cat HEAD
ref: refs/heads/master$ cat refs/heads/master
e88549a71c1749f239a1dfd499243d7703d0785e
$ cat HEAD
prints out the path refs/heads/master
and $ cat refs/heads/master
prints out the hash of our commit.
In the second part of this series I will explain a few things about “the 3 states of git” : Modified — Staged — Committed.
To be continued…