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
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.
However, when working with Git apart from commits we keep on using following things:
- Tags (we won't be talking about this today)
- Branches
- HEAD
All these 3 things - Tags
, Branches
and 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.
Branches
As you can see in the above diagram there are 2 refs of local branches develop
and 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.
HEAD
Checkout 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
Credit to Nina Zakharenko's course on Git In-Depth on FrontendMasters where i learned this concept couple of yrs back.
Git Push
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!
Git Push using HEAD
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. :)
Command:
> 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
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.
> gpush
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. :)