How to prevent commit in detached HEAD


Why does git allow you to commit to a detached head? Is there any pre commit hook that can disable it? What is the purpose? Many new developers do this and I'd like to find a way to disable it.


This can be only prevented by a local git pre-commit hook, so developers would need to create it. Add the your-local-project/.git/hooks/pre-commit file with the following contents:

#!/bin/sh if ! git symbolic-ref HEAD &> /dev/null; then echo "You are in a detached head state! Commit has been blocked. (Use --no-verify to bypass this check.)" exit 1 fi

Make sure it's executable. <a href="https://gist.github.com/svachalek/5437407" rel="nofollow">Credits go to svachalek</a>

Why should git prevent commiting in detached HEAD? Detached HEAD means <em>only</em> that there is no pointer to the repository state you are working on. It assumes that you know what you are doing.

I would rather investigate why <em>many developers</em> in your team enter this state? Maybe they apply some weird worklow?


git checkout $commit-sha1 can lead to a detached HEAD. So does git checkout FETCH_HEAD. A detached HEAD could be considered as a branch without a name. If it does not confuse you, you could just ignore it. As @fracz said, you could prevent it by pre-commit. You could also make it a branch with a name with git checkout -b some_name. A post-checkout hook may help you to detect the detached HEAD state and make it a branch.


Git uses this internally for many operations. The detached HEAD mode simply gets you on the (one, single, special) anonymous branch, and the anonymous branch can be given a name later.

This is, for instance, how git rebase manages to copy the commits from their original chain to a new chain. First it checks out the --onto target commit (--onto defaults to the <upstream>) using this detached HEAD mode. Then, for each commit that is to be copied, it copies that commit (with git cherry-pick or something equivalent: the details vary depending on interactive vs non-interactive rebase, and if interactive, many more details). Last, it moves the existing branch label so that it points to the final copied commit.


  • Issue with parameters in Modelsim
  • Casting a type (interface) via map to observable
  • Modal QMessageBox does not behave like native Windows dialogs
  • AngularJS component with externally hosted templateUrl?
  • Concurrent requests limited to 10 in .Net MVC / Web Api
  • Does Control.Invoke pump messages?
  • 'SOCK_RAW' option in 'socket' system call
  • Cross-Origin Request Blocked with CORS headers present
  • Not able to catch SIGINT signal while using select()
  • How to preserve alias property while signing app?
  • How to create a thread in a class?
  • NSTimer and updating UI
  • how to use asyncio with boost.python?
  • PHP OOXML Libraries? [closed]
  • TensorFlow C++, runtime issue
  • How can I make a right-click behave as a left-click for the purpose of selecting or focusing an obje
  • How to package a jar and all dependencies within a new jar with maven
  • Unable to run SDL program in Eclipse but able to do so in Windows Explorer
  • How to send control C to Mac Terminal using python?
  • Regex for nested values
  • Is there a Windows socket API call / option to “block” a range of ports à la SO_EXCLUSIVEADDRUSE
  • Aptana 3 remove bundle (jquery)
  • Using JRuby with Rails 3.2
  • Code in Job's Script Block after Start-Process Does not Execute
  • How to add git credentials to the build so it would be able to be used within a shell code?
  • Installing iPhone App to iPhone
  • Email verification using google app script and google forms
  • How to avoid particles glitching together in an elastic particle collision simulator?
  • Recording logins for password protected directories
  • Installing Hadoop, Java Exception about illegal characters at index 7?
  • Splitting given String into two variables - php
  • Obtain ObjectIdHex value from mgo query
  • Check if a string to interpolate provides expected placeholders
  • Display Images one by one with next and previous functionality
  • Upload files with Ajax and Jquery
  • RestKit - RKRequestDelegate does not exist
  • Arrays break string types in Julia
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • LevelDB C iterator
  • How can i traverse a binary tree from right to left in java?