When I checkout a specific commit hash, it goes to detached mode where HEAD POINTER can't point to a recent commit.
What are the things we can do and what is the use of going detached head state in Git?
DevOps Stack Exchange is a question and answer site for software engineers working on automated testing, continuous delivery, service integration and monitoring, and building SDLC infrastructure. It only takes a minute to sign up.
Sign up to join this communityThe "normal" way of working with GIT is by checking out branches. HEAD is a "pointer" to the latest commit in that branch, and GIT will allow you to commit new changes after that pointer.
However, as you figured out, it is possible to check out a specific commit hash, if you want to. In this situation, if you make changes and try to commit them, you will be unable to do so, since you are not at HEAD, and GIT will not allow you to commit your changes.
Most of the time, detached HEAD (checking out an older commit) is used if you want to test how your project ran at a certain point in time.
If you need to make changes to the code or need to build it using Jenkins MultiBranch Pipelines, for example, it is also possible to create a new branch from that specific commit by running:
git branch my_new_fancy_branch 7y8u33ii
or
git checkout -b my_new_fancy_branch 7y8u33ii
... where 7y8u33ii
is the hash you provided in the question. For this new branch, 7y8u33ii
will be HEAD, so you will be able to commit new changes. If you need to get your code into the branch from which you created this new branch from, you will need to do a merge, but this is another discussion altogether.
HEAD
is a special reference in Git that always points to "the thing" you have currently checked out. This "thing" can either be a local branch (HEAD
is in attached mode) or a specific commit (HEAD
is in detached mode).
In attached mode HEAD
is tied to the branch it references. The current commit is determined by the position of this branch. If you move your HEAD
around (e.g. by committing or resetting), in reality HEAD
is unmodified and still just pointing to the branch and the branch is moved instead.
If you switch to detached mode (e.g. by git checkout --detach
or checking out a specific commit, tag or remote branch), HEAD
is pointing directly to the commit hash. You can continue to use Git as you did before but no branch is modified when you move your HEAD
around. This time HEAD
is modified directly on each such operation.
So to answer your specific question "what are the things we can do": In detached mode we can do anything we could do in attached mode (commit, merge, reset, push…) but without the need to first create a branch. We need to be careful though: When checking out another commit, nothing references the original commit anymore and it is lost*.
The more difficult question to answer is "what is the use of it". As rasebo already stated in his answer, often to quickly check out an older commit to see how the project looked like at this time. But there are more use cases. Detached mode is used during an interactive rebase, for example. Also I use it often in my personal workflow to quickly create throwaway snapshots during prototyping or experiments. I could also use temporary branches for this, but I guess it comes down to personal taste and habits.
To get a better feeling for this whole topic it can help to play around and observe how .git/HEAD
and the branches in .git/refs/heads/
are modified after executing different Git commands.
* Well, not really lost, just inaccessible. It could be restored e.g. by looking up the hash in the reflog and then checking it out. It is only irreversibly deleted after a (manual or automatic) garbage collection 90 days (default) in the future.