I have previously written articles that cover the basics commands of Git. In this article, I will go a little more in-depth about the working of Git which helped me a lot in my understanding of what commands to use.
Snapshots and commits
I defined Git before as a system that maintains snapshots of the directory's content and all about commits. But what does this mean? Git stores files as blob objects. When you commit files a snapshot is taken. The commit references this snapshot, while the snapshot takes care of references the blob-objects. This way of storing objects makes Git a very efficient system since a blob object can be referenced by multiple snapshots and Git doesn't have to store duplicates (which is the case with other version control systems). So the amount of needed storage is efficient but also the speed when switching branches.
So what will this look like when I delete a file, add a file and commit these changes? Obviously, a new commit is created and since every commit references its own specific snapshot a new snapshot is also created. This new snapshot will reference the blob objects representing the files that are part of the snapshot. To preserve commit history the second commit also references the first commit (which is now its parent commit).
Now the basics of how the tree works are clear, let's put it to use in common scenarios.
Branches and HEAD
When you cloned a repository a default branch is created with the name "master". This branch is merely a pointer to the last commit on this branch. When a new commit is made the pointer moves to this new commit. This current branch is referenced by the HEAD.
A repository can have many branches. If I want to start working on a new branch to make some changes in isolation I can create this:
git branch <branch-name> git checkout <branch-name>
The first line will create the new branch and the second command will switch the HEAD to the new branch so you can start to work on the branch. It's possible to do the same with only one command:
git checkout -b <branch-name>
Branches master and develop now point to the same commit, but the HEAD has moved to the branch you switched to and a new commit would affect only the branch I'm on.
The new branch was created in the local environment and is only present there. To be able to push to the remote repository it needs to be connected to an upstream branch:
git push --set-upstream origin <branch-name>
git push -u origin <branch-name>
To see what branches are available get a list of the branches. To see remote branches as well add the
git branches git branches -a
git <branch> -d git <branch> -D
The difference between the 2 commands is when using a capital
D it is read as a forceful delete. So even when for example the branch is not considered fully merged, it can be deleted while
d will not delete the branch in that case.