Git HEAD: The Definitive Guide
This is the most complete guide about Git HEAD.
So if you want to Learn :
- Git HEAD and how to view Git HEAD
- Git reset HEAD
- Git detached HEAD
- and about Git merge HEAD and more...
then you’ll love this detailed guide.
Let’s dive right in.
Don't have time to read
the full Guide!
No Problem, I've created a pdf so you can read when it's convenient. And to get the PDF version of this guide, click on the button below.
Contents
CHAPTER 1 :
Git HEAD Fundamentals
Git Head is an important term (everything has a head).
In this chapter, you will learn about -
So let's start.
What is Git HEAD?
The Git HEAD is a pointer to the last commit snapshot.
HEAD is a direct or indirect reference (symbolic reference) to the current commit.
In simple words - HEAD is a special pointer. And it points to that local branch in which you are currently working.
The HEAD identifies the most recent commit in the current checkout branch.
What is the current HEAD in Git ?
When using Git, You may switch to any branch.
And the checkout branch is known as the HEAD branch. Also known as the "active" or "current" branch.
I will cover how you can view the Git HEAD in the next chapter.
And this chapter is all about the fundamentals of Git HEAD and other related terms.
Git HEAD^ (caret) and HEAD~ (tilde)
In Git, you can use any of the signs - caret or tilde to go backward.
You can use the caret sign for the merge commits (as there may be two or more parents of a commit).
Use the tilde sign most of the time to go back in a straight line.
Git HEAD^
In Git HEAD^, the caret sign (^) denotes the parent of a specific commit.
The parent of the current HEAD commit is referred to as HEAD^.
You can optionally include a number after the caret sign (^) to indicate which parent you want.
And HEAD^ is shorthand for HEAD^1.
HEAD^2 is NOT equivalent to HEAD^^
This technique is only helpful for merge commits with more than one parent.
Here is the two-parent of the merge commit.
Git HEAD~
Most of the time, you can use a tilde sign to go back several generations.
HEAD~ (with a tilde sign) appears virtually linear and wishes to travel backward in a straight path.
You may get the parents of any commit, not only the HEAD.
You can use the tilde sign with a branch to find its parent.
For example, feature_branch~2 refers to the grandparent of the feature_branch.
Git HEAD^ vs. HEAD~
Most of the time, you can use ~ (tilde sign). It refers to previous commits to the current branch.
And ^ (caret) refers to parent.
HEAD~ is always the same as HEAD^
HEAD~~ is always the same as HEAD^^
HEAD~~~ is always the same as HEAD^^^
HEAD~~~~ is always the same as HEAD^^^^
and so on…
But HEAD~2 is not the same as HEAD^2.
When there are several carets (^) in a row, the tilde (~) is a shortcut character.
HEAD~2 is equivalent to HEAD^^
HEAD~3 is equivalent to HEAD^^^
HEAD~4 is equivalent to HEAD^^^^
and so on…
I prefer to use the tilde(~) is best practices over the caret (^), like HEAD~2, HEAD~3, etc.
Git HEAD vs Git index
Git Head and Git Index are different concepts.
From Git’s point of view the journey of a file goes from three areas.
- Working directory
- Staging area and
- Repository
When you use git add command, you can say you have added files in the Git index area or Git staging area.
Git HEAD
You already know about the Git HEAD; It's a special pointer.
And it points to that local branch in which you are currently working.
Git Index (or Staging area)
The Git index is a staging region that sits between your working directory and your repository.
Technically, it's a file called index, which you can see in your special folder - .git (it's a hidden folder starting with a dot).
The Git Index is an area where you put files that you want to commit to your git repository.
It is a final preview to add and remove files before your changes go into your local repository.
Git HEAD vs Git Origin
There is a concept of remote in Git.
And you can connect with several remote repositories.
Origin is the default name of your default remote repository. Origin is the repository from where you have cloned your local copy (of your repo).
How does Git know about your local and remote repositories?
From .git/config.
The. git folder contains all of the information required for your project's version control. It also records information on commits, remote repository addresses, and so on.
You can check the list of how many remotes you have set up in your local repository with the git remote -v command.
Git HEAD vs. Main(or Master)
Master is the name of the default branch that Git creates when you first create a repository.
In simple words - master is the principal branch.
GitHub recently changed the master branch to main. (in case you have old repo still you can rename your branch to main)
So master and main is a name of your primary Git branch.
CHAPTER 2 :
View Git HEAD
This chapter is all about how you can view Git HEAD.
In this chapter, I will show you how you can view the Git HEAD of your remote and local branch.
Also, I will show you how you can view the detached HEAD.
So let's dive in.
In the previous chapter I shared about head (lowercase) and HEAD (uppercase).
There can be many heads but only one HEAD.
And again - HEAD is a special pointer to the current branch in which you are working)
You can check the status of HEAD with a few simple git commands.
1. Git branch
You can simply run the git branch command and it will display your local branches.
But It will mark the active branch on which you are currently working on with an asterisk.
Here is the syntax and a screen shot.
Syntax - $ git branch
2. Git branch --show-current
If you want to display only your current branch name you can use --show-current flag with your Git branch command.
The - -show-current option will simply tell you your active branch.
Syntax: $git branch --show-current
3. Git name-rev
You can use the git name-rev command to find the HEAD
This command will find symbolic names appropriate for human digestion.
Syntax: $git name-rev --name-only HEAD
4. Git symbolic-ref
Another quick and easy approach is to use the git-symbolic-ref command to show a brief symbolic reference to the current branch's HEAD, which is simply the current branch name.
Syntax : $git symbolic-ref --short HEAD
5. git show HEAD
You can check the status of a HEAD with a simple command. Also, the command will tell you the status of HEAD.
$ git show HEAD
And you can get a view of something like this
You can see the commit id of the HEAD.
And also, you can see the branch name to which HEAD is currently pointing to.
In this case, the HEAD points to the main branch.
6. Git show-ref
This command is super helpful if you need the current commit Id of HEAD.
You can view the Git HEAD SHA of all your local branches with the following command.
$ git show-ref --head
Here the --head option shows the HEAD reference
In the above output windows, the last line shows the commit Id of remote HEAD (refs/remotes)
7. View Detached HEAD
You can see what HEAD points to by
cat .git/HEAD
And normally you will get something like this (branch name)
ref: refs/heads/bug-login-page-css
But if you are in detached head mode you will get hash value
70460b4b4aece5915caf5c68d12f560a9fe3e4
It tells you that the HEAD is pointing to a commit ( instead of a branch).
How can you fix detached HEAD issues? I have covered everything in the next lesson.
And for now, how you can check if you are running in the detached HEAD issue.
CHAPTER 3 :
Git HEAD reset
In this chapter, I will share with you what the purpose of Git HEAD reset is?
Why you need a detached HEAD in the first place, and How you can fix it.
Also, later in this chapter, you will learn about Git hard and soft reset with examples.
So let's dive in.
Why do you need to use Git reset command?
Git reset is a powerful command.
The primary purpose of the Git reset command is -
In simple words, Git reset command will fix un-committed mistakes.
Git Reset
There are three Git reset options that you can use for your three trees.
Before I dive in, let me explain what are the three trees in Git.
Now back to three Git reset options -
- 1Soft
- 2Hard
- 3Mixed (default option)
Git Reset Soft
Git reset soft option only changes the HEAD.
And it does not change staged files in the index or in the working directory.
When can you use Git reset soft in the real world?
Imagine you need to undo your last commit.
You can use git reset with the soft option.
$ git reset --soft HEAD~1
This command will move the head to the one before the current revision.
And all your changes will stay. And you can check your changes with the Git status command.
Once you execute the Git reset command with the soft option. You can see your changes in your working directory.
Also, you can see the changes still exist in your index. So you can commit your changes if you want. Git reset command only removed your last commit.
Git Reset Hard
Git reset HARD option will move the HEAD and update index and working directory.
It might cause data loss.
Let's try to remove the last commit with the HARD option.
$ git reset --hard HEAD~1
As mentioned, it will remove all your changes from your working directory and index.
After executing this command, you try to view git status. You will get a message like nothing to commit, working tree clean.
Git Reset Mixed
Git reset mixed option will move the HEAD.
It also updated the index (where HEAD points).
Git reset mixed is the default option.
It means if you write only Git reset, it will execute with the mixed option.
Let's take the same scenario, undo your last commit with the default option (--mixed)
$ git reset --mixed HEAD~1
Git reset mixed command will remove your change from the Git index. But you still can see your changes in the working directory.
Later in this chapter I will share how Git reset is different Git revert and from Git rebase. But for now let's try to understand a little bit deeper about Git Reset.
Git reset HEAD delete files
Sometimes you want to remove all your changes.
It's easy with Git reset HARD
$ git reset --HARD
It will delete all of your local changes in your current branch.
Reset a local branch to match remote repository HEAD
You might need to do it often.
Why?
You made some changes in a branch. And in the meanwhile, your teammates push changes in the same branch.
Now you want to discard your changes and make sure you are in sync with the remote repository.
It is a two-step process
Here main is the name of your default primary branch. It might be a master for your project.
In case you want to save your changes before you fetch, you can set up your local branch.
$ git commit -a -m "Saving temp work."
$ git branch your-temp-work
And after saving your work, you can reset your local branch.
Git reset HEAD vs. Git revert
You can use both of these commands to undo some work, but they work differently.
Git revert
As I mentioned earlier, git revert used to undo your changes. It adds a new commit that undoes the changes from a previous commit.
This command adds a new history to your project.
When will you use Git revert?
Let’s say you made a change in your project repository. And later, you figure out the commit is not valid.
Then you can use the Git revert command to undo the modifications added by the bad commit. And Git revert command to record a new undo commit in the history.
Git revert commit
With the Git revert, you can undo your single commit or set of commits.
It's super easy to undo your commit on the CLI with the following command.
$ git revert <your unwanted commit hash>
There is another way as well. You can use the branch name with the tilde sign ~, followed by a number that indicates commit behind the head commit.
$ git revert main~3
In this example, the target commit is three, behind the head commit on the main branch (your checked-out branch).
How do you revert multiple commits in Git?
You can use two dots to select multiple commits.
When you revert multiple commits, the older commit should come first and then the newer commit.
For example
$ git revert HEAD~7..HEAD~3
The above command will revert these two commits. And also every other commit in between them.
Git reset
If you use Git reset command, it might alter the history.
Let’s take an example - you made a lousy commit in your local repository (and did not share with others). And now you want to get rid of that lousy commit.
In this case, you can use the Git reset command. And it will remove that commit from history.
This is about Git HEAD reset, Its time dive deeper in more advanced concepts.
CHAPTER 4 :
Git Rebase vs. Git Merge (HEAD)
In this chapter you will learn two more advanced concepts
Also, you will learn where Git merge head and how you can remove it.
So let's dive in.
Git Merge and MERGE_HEAD in Git
Before going into the MERGE_HEAD explanation, let's understand what Git merge.
Git Merge
Git merge is a command that allows you to merge branches in Git. When you do git merge, only the target branch will change.
Git merge adds your current branch changes into the target branch.
MERGE_HEAD
Linux Kernel Git documentation for Git revisions says. MERGE_HEAD records the commit(s) you are merging into your branch when you run git merge.
In simple words, - While doing a merge, MERGE_HEAD is the SHA of the branch, you are merging into your changes.
While doing a merge, ORIG_HEAD is the SHA of the branch you are merging from your changes.
What is HEAD in Git Rebase
Git rebase command also tries to integrate changes from one branch to another branch.
Git rebase command, with the example, is in the Git commands post. So here we will dive deeper to understand HEAD in the Git rebase.
When you use git rebase, you have two option for the new base
- The features parent branch (example - main branch)
- Earlier commit in your feature branch
The following command begins an interactive rebase
$ git checkout feature git rebase -i HEAD~3
Here you are specifying the HEAD~3 as the new base.
You are not moving the feature branch but rewriting four commits that follow it.
You may also run into the detached HEAD when you are rebasing. And you may check out a specific commit.
I have covered the detached HEAD in detail in the next chapter. For now, let's see if you run into a problem while rebasing what you can do.
If you feel something went wrong with Git rebase, you can cancel it with the following command.
$ Git rebase --abort
It will abort the rebase without doing anything.
Git Rebase vs. Git Merge
Git rebase and git merge; both commands help you integrate your changes. Both take changes from one branch to another.
The real difference is how they do.
They both use different ways to do the same thing.
Let's see how Git Merge command work
Rebase move/combine sequence of commit to a new base commit.
In the public repo, do not use Git rebase. It is a good option if you are working alone or in a small team.
CHAPTER 5 :
Detached HEAD
In this last chapter, you will learn about the detached HEAD.
First I will share what is detached HEAD, why it happens for you in the first place and then how you can get rid of detached HEAD problems.
So let's dive into more details.
What is detached HEAD in Git
Most of the time, the head points to the latest commit in your current branch. But keep in mind that is not the case all the time.
Suppose Git HEAD is pointing only to a commit ( and not branch associated). And when HEAD pointing to a commit, it's known as a detached head state.
A detached HEAD means you are not on any branch.
In this mode, you can not update any branch as no active branch with HEAD.
How to enter in a detached HEAD state?
A detached HEAD does not mean you did something wrong. Also, it does not say that you break your code or repository.
There are a few common scenarios why you might have detached HEAD issues.
Let's try to understand with an example.
As you can see, after running the Git log command, I am in the main branch, and I have a few commits.
Now to check out a commit dfb57db, where I’ve updated the index file.
After executing that command, you can see the message says -
You are in a 'detached HEAD' state.
Why do you need detached HEAD?
Most of the time, you do not need it. It might happen accidentally with you.
And if you need, you can enter into the detached HEAD state yourself as mentioned above.
There are a few reasons behind that.
Most of the time, developers check out an older commit to test the project state at that point.
How do you fix a detached HEAD?
There are few quick ways to fix the detached HEAD issue.
Case 1: If you want to delete changes associated with detached HEAD
The easiest way is to check out some branch, and it will move the HEAD to that branch.
$ git checkout <branch name>
And in this case, your changes will be lost (if you made some).
If you entered into the detached HEAD by mistake, chances are you have some changes.
And to keep those, and you can use the next case.
Case 2: If you want to keep changes associated with a detached HEAD
To keep changes that you have made while in a detached HEAD state are not hard.
You can use the following steps.
- 1Git branch <new branch name>
$ git branch temp
This git command will save your changes in the temp branch - 2Switch to some other branch or to main branch
$ git checkout master - 3And if you want to incorporate your changes into the main branch you can merge those changes.
Run the command $ git merge temp from your main branch.
Conclusion
In this definitive guide, I share all the important aspects of Git HEAD.
Now you know all the core concepts about git HEAD.
What Do you like about Git?
Did I miss anything?
Either way, share your thought.