What **is** Git? 🤷🏼‍♀️
Published: 2021-04-25 14:21:23

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.

#### The general idea:

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:

essayintro1.doc
essayintro2.doc
essayintro3.doc
essayconclude1.doc

and so on...

Maybe you tested out parts of the essay in this way and then put all of your final thoughts together in:

essayMAIN.doc

This is essentially version control, and although messy, it works for 1 person...

####The problem:

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)

###Git saves the day

> "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 `branch`.

##Branch?

**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.


![A tree with thick branches](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2y5c8fb2q0cpmrchkecw.jpeg)

The main trunk of the tree is called the `main` or `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!)

## The three states

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.

#### The working directory

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.

#### The index
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

#### HEAD
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
``` bash
$ git checkout -b Some-new-changes!
// Switched to a new branch "Some-new-changes!"
```
2.Make your changes
![Github desktop showing some changes on a ](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/webdikcyl1plplb8w7gl.png)

3.`Add` your changed files to the index (your draft area)

4.`Commit` your changed files with a message about what you did

``` bash
git commit -m "commit message"
```

5.`Push` your changes to your branch
```bash
git push
```
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.

#### 😱 Detached HEAD 💀

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 
```bash
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.


###Recommended resources
I'm not affiliated with these links or resources in any way, but I found them useful in my own learning journey.


[Real-life references Youtube](https://www.youtube.com/watch?v=USjZcfj8yxE)

[Detached HEAD explanation and examples](https://www.git-tower.com/learn/git/faq/detached-head-when-checkout-commit/)

[Command line git messages reminder](https://www.atlassian.com/git/tutorials/saving-changes/git-commit)

[]()