Rescuing files and commits from "no branch" in git

Solution 1:

You can use git reflog to find the "lost" commits:

$ cd submodule_dir
$ git reflog          # Find the commit
$ git checkout master
$ git cherry-pick $SHA_OF_MISSING_CMMIT

Solution 2:

The “no branch” state is called a detached HEAD. It is called this because the HEAD ref is not attached to any branch, instead it is pointing directly at a commit. To attach HEAD to a branch that points to the current HEAD commit, use git checkout -b branchname.

You can safely update an existing branch to include the commits at HEAD with this sequence:

git branch temp
git checkout branchname
git merge temp
git branch -d temp

Or, equivalently, using the reflog notation HEAD@{1} to avoid having to make the temporary branch:

git checkout branchname
git merge HEAD@{1}

Using the temporary branch would be a good idea if you were not going to do the merge immediately.

If you want to forcibly overwrite an existing branch to point to the commit at HEAD you can use git branch -f branchname && git checkout branchname. If the commit at HEAD is not based on the current tip of branchname this will result in a non-fast-forward change to branchname which you usually want to avoid (it is viewed as rewriting history).