Git is an extremely useful tool for developers. It is also quite abstract and tricky to learn.
I learned about git by reading, watching videos, viewing images, and trying out using it.
I've highlighted some of my favourite resources at the bottom of this article.
Have you ever worked on something, maybe an essay for school etc, where you were undecided about how you wanted the intro to be, so you made:
and so on...
Maybe you tested out parts of the essay in this way and then put all of your final thoughts together in:
This is essentially version control, and although messy, it works for 1 person...
Now imagine that you had multiple people writing and making edits on this essay...this would get very confusing very quickly and it would be pretty impossible to ever finish the essay (project)
"Version control is a system that records changes to a file or set of files over time so that you can recall specific versions later."
A Version Control System is an invisible system that holds copies of your files and records changes so you can switch back to a previous version. It also means that you can work together with two or more people on a document and you won't save over each other's work.
With large codebases such as those needed for organizations or product-building companies, there are inevitable issues that trying to keep track of changes, proposals or bugs would cause when multiple people are trying to work on it.
Imagine trying to build a house with 40 other people while blindfolded and with no communication. The likelihood is that you would end up crashing into each other, you'd build over other people's work and you'd probably break stuff...
A version control system such as Git means that you can keep track of changes and do your own work on your own
Imagine Git as like a tree * ...
*The metaphor of git as a 'tree' is an abstraction to help some people visualize, but also it can be thought of as different versions of a file.
The main trunk of the tree is called the
master branch, and this should always be the source of truth of the code; the production-ready, correct, and most up-to-date version. You can create a branch from the main branch, which means that you have created a copy of whatever is on the main branch.
Now you can make changes to your own branch as if you've put tracing paper over the original code. Now you can make the changes you want to that code with no worry about breaking anything. You can test the code like this in a dev environment. When you are happy with the changes you have made, you can merge your branch back into the main branch. If you are collaborating on a project rather than working on your own, this is done via a PR, or Pull Request. Merging your branch means that Git puts all of your changes back into the original branch - now your changes are on the main branch! You've put your version into the codebase and now your new changes or updates are possibly in production (live!)
There are actually three 'trees', or states of git, used for creating and retrieving commits (saves):
- the working directory
- the index
- something called "HEAD" for creating and retrieving commits.
Files whose content you can change are in your working directory. These are the files that you are able to put into your code editor and make changes to. The working directory represents a particular
commit (save) and is the version that
HEAD is pointing at.
Also called the staging area, the cache, the staged cache, stages files or directory cache...
The index can be seen as an area to store your drafts, or an area that you can see all of your changes and choose which files you want to
commit to your repo. It's a holding area for your changes
The HEAD is a reference point that shows you where you are along your commit line. It points to the currently checked out branch and to the last file that you committed (saved) onto that branch. This means that it frequently changes (and can be hard to keep track of...leading to a
detached HEAD state - more on this later 🧟♀️)
The flow of updating the main branch in a git repository would be like this:
1.Make a new branch from main and switch to the new branch
$ git checkout -b Some-new-changes! // Switched to a new branch "Some-new-changes!"
Add your changed files to the index (your draft area)
Commit your changed files with a message about what you did
git commit -m "commit message"
Push your changes to your branch
6.Happy with your changes and checked everything? Create a Pull Request detailing what changes you've made.
7.When your PR is accepted, this means that your changes have been
merged into the main files of the project.
The HEAD would move through points 1-4 here in turn and follows around what you are doing.
This sounds like a ⚠️horrific error⚠️ and pretty terrible.
I'm here to tell you it's not.
In fact, it is sometimes necessary to use this state to test out a feature.
Say you suddenly think of a different way that you could have solved something, or a different idea entirely that you could have approached your change or addition...if only you could go back in time to a few commits ago to test your new theory out...
What you need is a time machine
You can't have a time machine, but what you can do is point your HEAD marker to a few commits ago (via the hash of the commit), or whenever you want to start testing your new idea and create a temporary branch to use. With a detached HEAD, the changes do not belong to any specific branch and so you need to be careful that you don't lose your changes if you want to keep your new work.
The easiest way to get to a detached HEAD state is to
git checkout <the commit SHA(abcdef123)>
TL;DR: Detached HEAD state is sometimes used if you want to make experimental changes to an earlier commit. Not a horrific error. Don't panic.
I'm not affiliated with these links or resources in any way, but I found them useful in my own learning journey.