Understanding HEAD in Git
Do you know how we can use
HEAD in Git to reduce keystrokes when doing
git push to remote?
But before we talk about it we need to first understand what exactly is HEAD in Git.
Note : If you're using GUI tools(even i use them) to do git push then this tip might not be that helpful. But, i think it is important to just understand the fundamentals concepts like
HEADto 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.
However, when working with Git apart from commits we keep on using following things:
- Tags (we won't be talking about this today)
All these 3 things -
HEAD are nothing but pointers(references) to our commits(each one in a slightly different way).
To understand it more clearly let's look closely at
.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.
As you can see in the above diagram there are 2 refs of local branches
master. If you check their content using
cat command like following:
> cat ./git/refs/heads/master 12de9b3658d9b4424efe03c3ac3281facf288c13 > cat ./git/refs/heads/develop dlk0erflke13658d9b4424ef2o2p3po3281fa232
You can see that they contain which "commit" the "branch" points to.
develop branch locally and run following command:
> cat .git/HEAD ref: refs/heads/develop # HEAD points to "develop" branch
Let's switch to
master branch and run above command again:
> cat .git/HEAD ref: refs/heads/master # HEAD points to "master" branch
As you can see
HEAD always(except in some case) points to your currently checked out branch locally. It is a pointer to the currently checked out branch. So, overall these are just references to one another.
HEAD -> Branch -> Commit
We now know what HEAD is, right? 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 simply run
git push and it works most of the time.
You're right. However, it doesn't works when you try to push some local branch for first time to remote. This is because it doesn't works until upstream branch has been set first.
Every time you run git push for first time on a 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!
But, now we know what
HEAD is! It points to our branch which in turn points to our latest commit on it. 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 pushduring the first push.
- No need to type your branch name as well.
E.x. - git push origin chore/config-changes
You can even set alias for it in
.rc files of your default system shell.
alias gpush="git push origin HEAD"
Then whenever you want to push anything to remote simply run below command without worrying about typing branch names or dealing with errors during first push.
That's it. Hope that was useful. I think despite using GUI tools for all such git tasks it is helpful to know small things like this because it can help understand how things work under the hood. So, whenever it is needed you can use them.
As always let me know if there is a better way of doing same thing in comments below. :)