Maybe you recognize this scenario. You have 10+ Stack Overflow tabs open and are running Git commands that you don't really understand. I've been there. Several times, and I hated it.
I needed a better mental model of how Git worked. This is the article I would have written to safe myself from a lot of uncertainty. Together we'll build a concise mental model of Git. So when things do go south, you know why you'll have to run certain commands to fix things. Let's dive in!
Let's start with the command
git init to add Git to this project.
We can see that there is a
.git folder created in our repository. Let's
create an empty text file. We do this with the command
touch. Let's run the
Awesome! We now have created an empty text file called
text.txt. Let's see
what Git thinks of this newly created file by running the command
The status command tells us that the
text.txt file is untracked. Files
in our repository can be tracked and untracked. We just created the
text.txt file, so we need to inform Git of its existence. We do this by
running the command
git add text.txt.
Awesome, Git now knows of the existence of our file. Conceptually we have added it from our working directory to the staging area. This is the place where we add the changes that we would like to save to the repository. We can save our progress with a commit. But before we do that, let's look further into what just happened.
When we ran
git add text.txt Git copied the file to the .git/objects directory. But it didn't just copied the text.txt file. It has been transformed to a Blob, which stands for binary large object. A format used to store files. Blobs are one of four types that Git uses. The other types are trees, commits and annotated tags. The most important are the blobs, trees and commits. We will explore these in depth. So, back to our newly created Blob!
In the objects folder a new folder has appeared. It has
e6 as a name and in it is our blob file called
9de29bb2d1d6434b8b29ae775ad8c2e48c5391. Now the folder and file name are not random. Git uses a Secure Hash Algorithm (SHA) to hash the content of our text.txt file. The output is a 40 character string. The first two characters become the folder and the rest of the string become the filename.
The output of a SHA is always consistent. The same input will always get you the same output. Try commiting an empty file in your own Git project and you will end up with the exact same folder and file name. We will see further on why this is important.
So let's run
git status again to see how Git is feeling about our new file.
So Git tells us that we have a new file to commit. A commit takes all the changes in our staging area and saves them to our repository. It saves the state of our reposity with a snapshot of the whole project.
So our staging area is like a place for the rough drafts that we make. When we are sure of the changes we can commit the changes.
So let's do that by running the command
git commit -m "your commit message".
- Explaining what happened under the hood when we just ran
- When we ran git commit we made a snapshot that captures the state of our entire project in this exact moment.
- Show what object have been added (tree and commit) and how we can check what they contain (plumbing commands)
- Git is divided in plumbing and porcelain command. You are probably familiar with the porcelain commands. The plumbing commands are the ones giving insight into the inner workings of git. Other more user-friendly commands are made by stringing these together (like git pull, which is git fetch and git merge together).
- I also want to clearify these concepts
- What is a remote?
- What is an origin?
- What is a HEAD?
- How does branching work?