Understanding HEAD in Git
In this post, we will learn about HEAD
in Git & how we can use it to reduce keystrokes when doing git push
to remote.
Note: If you're using GUI tools to do a git push, this tip might not be that helpful. However, IMO it is essential to understand the fundamentals concepts like
HEAD
to know how things work in Git and use it whenever required.
In Git, a Commit is the smallest unit representing our code snapshot at a particular point in Git history. We all are aware of commits in Git. However, besides commits in Git, there are three other useful things.
- Tags (we won't be talking about this today)
- Branches
- HEAD
All these three things - Tags
, Branches
and HEAD
are nothing but pointers to our commits.
To understand it more clearly, let's look closely at the .git
folder of a project containing develop and master branches.
> tree .git
.git
|__ HEAD
|__ refs
|__ heads
| |__ master
| |__ develop
|__ remotes
| |__ origin
|__ develop
|__ master
|__ tags
# There are other imp folders too. Removed them here for brevity.
Branches
As you can see in the above diagram, there are two refs of local branches, develop
and master
.
> cat ./git/refs/heads/master
12de9b3658d9b4424efe03c3ac3281facf288c13
> cat ./git/refs/heads/develop
dlk0erflke13658d9b4424ef2o2p3po3281fa232
If you check their content using the cat
command like the above, you will see that they contain which "commit" the "branch" points to.
HEAD
Let's check what HEAD
contains. Checkout to develop
branch locally and run the following command:
> cat .git/HEAD
ref: refs/heads/develop # HEAD points to "develop" branch
Switchig to master
branch and running the above command again:
> cat .git/HEAD
ref: refs/heads/master # HEAD points to "master" branch
As you can see, HEAD
always points to your currently checked-out branch locally. It is a pointer to the now checked-out branch. In other words, these are just references to one another.
HEAD -> Branch -> Commit
Credit to Nina Zakharenko's course on Git In-Depth on FrontendMasters where i learned this concept couple of yrs back.
Git Push using HEAD
We now know what HEAD is! Considering it points to your current branch, why not use it to push your current local branch to remote?
You must be thinking, why even use HEAD
? I can run git push
, and it works most of the time.
You're right. However, it doesn't work when you try to push some local branch to remote for the first time. That is because it only works after the upstream branch has been set.
Every time you run git push
for the first time on any new branch, you see the following error:
> git push
fatal: The current branch chore/config-changes has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin chore/config-changes
And then you go ahead and run command it suggests. This is fine! 😅
As per our recent learning, HEAD
points to our currently checked-out branch. So, why not use one of the variant of git push
involving HEAD
where we don't have to see the same error again. :)
> git push origin HEAD
Yup, that's it 🎉
- No more errors as
git push
during the first push. - No need to type your branch name as well.
E.x. - git push origin chore/config-changes
To reduce keystrokes even further, you can set an alias in the .rc
files of your default system shell.
alias gpush="git push origin HEAD"
Now, you can run the below command whenever you want to push anything to the remote without worrying about typing long branch names or dealing with errors during the first push.
> gpush
Despite using GUI tools for all such git tasks, knowing small things like this is helpful because it can help understand how things work under the hood. So, whenever needed, we can use them. I hope that was useful. Thanks for reading 🙂