I'm using a Git GUI for quite a while now (Sourcetree mainly) and with the most frequently used actions I understand what is going on. But when I have to do things that I use less frequently and are more complex I am relying on the GUI to help out.
Although a GUI makes it easier it also hides what is exactly going on when executing the tasks. Therefore, to strengthen my understanding I started using the command line instead of the GUI. This forces me to gather the knowledge to take the correct course of action myself.
This article will cover what I have learned about the basic technical workings of Git. In another article I will go into my most frequently used command-line commands.
So let's start…what is Git?
…at its core Git is a collection of snapshots of the directory's content and basically, everything revolves around commits. A commit is a pointer to a specific snapshot of the directory. Simplified this would look something like this: The snapshots reference the blob-objects that are part of the snapshot and a commit references (aka is a pointer to) a snapshot. When a file is for example deleted or added a new snapshot is created and after committing this change the new commit references both the new snapshot and the previous commit (and as such creating a history of commits).
But wasn't git all about branches?
When working with git the concept of branches also plays a big part. In short, a branch is a pointer to a certain commit. The default branch is called 'master'. Another pointer that is of importance is called HEAD which is a pointer to the last commit of the current branch. The branch and HEAD can point to the same commit, but don't have to. This might sound really confusing so I have visualized this process to try to make it more understandable. In the diagram, a second branch is also shown (named 'develop') to show how the branches and HEAD relate to each other.
That can't be all...
Now it's a bit clear how git deals with changes under the hood it's time to understand what the 'git-environment' looks like. Information moves around in this 'git-environment' and can consist of the following parts:
- Remote repository;
- Local repository;
- Working directory;
- Index (staging area).
What do these parts do?
Remote repository The "other" place where the Git directory is stored and optionally shared with others (most of the time another server).
Although most of the time I have a remote repository set up (for backup and/or sharing) it's possible to discard this part and setup Git only in the local environment. That way you still have the commit history to work with. Of course, then the starting point is not a clone of a remote repository but a
git initin your local project folder. So it's quite possible to use a large part of Git without a remote repository.
Local repository The directory where Git (meta)data is stored. The files are in the .git folder which is in the same directory as the working directory.
Working directory The directory where the uncompressed version of the Git directory (files) is placed and available to work with. There are two states the files can be in:
- Tracked files: files that Git is aware of;
- Untracked files: files that have not been added and as such Git has no knowledge of.
Index (staging area) A file where information is saved about what will go in the next commit.
How do these parts come together?
Like I mentioned, information moves between these parts. Assuming there is a remote repository present, the process starts with cloning the information from the remote repository to the local environment. Cloning will create the local repository and the working directory. Working with git is a repeating process of:
- change files
- stage files
- commit files
- push files
Clone a repository
When you clone a repository the working directory and local repository get updated. The default name for remote is
When you want to update the remote repository with your changes, these changes move through all parts of your local environment and are pushed from the local repository to the remote repository. To make the files git-aware use the
Get updates from a repository
In case there are changes in the remote repository that don't originate from your local repository these changes are not in your local repository. When you want to get updates from the remote repository you fetch or pull the remote repository. When you
fetch, only the local repository gets updated.
pull also updates the working directory by merging the changes.
That sums up a global overview of the basics of how git works.