The abundance of commands and features can terrify anyone new to git. Git is a multi-functional tool with an incredible number of features. But do you need to know them all? And how do you remember them? How do you even learn to use it efficientlyy?
The truth is that almost no one knows git thoroughly, and developers regularly discover new things within it, and they're also constantly googling its commands or checking "man" (the command that opens up the manual on any command or utility you need). The only way to learn git is to be using it all the time. And the greatest result can be achieved if you work with git as a team. Individual development in this sense is strongly inferior, because it does not address many of the complex situations that arise only when people work together on the same code.
On the other hand, to understand git, you have to understand how it's built and what ideas it's based on. Things will get easier from there, as it turns out that the vast majority of commands are simply things that wrap up very simple concepts. In this lesson, we're going to dig a little bit in what git itself is.
Let us output the commits of our hexlet-git project in a special view, which we activate the --graph
option:
git log --graph
# Incomplete output so as not to distract from the point
* commit e7bb5e51f96e572084f6c04ba3312e32ce6b8c0f (HEAD -> main, origin/main, origin/HEAD)
|
| update README.md
|
* commit 65a8ef7fd56c7356dcee35c2d05b4400f4467ca8
|
| Revert "remove PEOPLE.md"
|
| This reverts commit aa600a43cb164408e4ad87d216bc679d097f1a6c.
|
* commit 5120bea3e5528c29f8d1da43731cbe895892eb6d
|
| add new content
|
* commit e6f625cf8433c8b1f1aaed58cd2b437ec8a60f27
|
| add INFO.md
|
* commit 273f81cf2117044f1973ea80ce1067a94bea3f80
|
| remove NEW.md
Note the line on the left. It reflects the relationships between commits. Each new commit is based on the code of the previous commit. In computer science terms, commits are lined up in what is known as a singly-linked list. In lists like these, each item links to the previous one. The last element in this case is called the head of the list.
In git, the items in the list are the commits themselves. And just as in a singly-linked list, the new commit (as an item) links back to the old (previous) one, and the previous one links back to its previous one, and so on and so forth until the first commit, which does not link to anything because it is the first. The concept of list "HEAD" in git is explicit and actively used for various operations. For example, deleting the last commit looks like this:
# HEAD~1 means: take a head and delete one commit, starting from that head
# That is, only the last commit
git reset --hard HEAD~1
The list of commits itself also has a name, you have already seen it, that's what main is. In git terminology, lists like these are called branches. This is why the command to show the current position in the history is called the git branch
:
git branch
* main
Git's main "job" is to generate a singly-linked list consisting of commits. This is a key for understanding what git is. The vast majority of the git commands are just small programs that know how to go through this list and retrieve the information you want. In fact, it all comes down to wandering back and forth through the list and changing it, including adding new commits.
Branches
If you look further, you'll see that the commit chain in git is not just a singly-linked list - it's a set of singly-linked lists (a directed acyclic graph) woven together.
Imagine that at the same time, two different people have to do some long tasks that require several days of development or even more. In this case the main branch must remain operational, i.e. you cannot commit intermediate changes to it, as it would break it. But you still need to commit, because it's just not safe to accumulate changes in the working directory without sending them to git. What should you do in this situation?
Git allows you to branch off from the main list to form further branches. That is, it creates a separate list of commits that goes past the main one. At the end of development, all the commits from such a branch will be merged back into the main branch.
Branching in git is a huge thing that deserves its own course. We're only telling you about them here because it's impossible to work with git and not hear about them.