Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reattach a detached HEAD in GIT

(I can see there are many questions about this but I haven't found one that solves my exact problem).

I'm running gitlab-ci and when the runner checks out my code it does so as a detached head. Here is what I get when running a git status command in the runners directory.

git status
# HEAD detached at 847fe59
nothing to commit, working directory clean

What I need to do for what I am working on is to re-attach this head back to my develop branch and then git pull in the full repo for use in a docker container. I guess gitlab ci only checks out the last commit to save cloning down the full repo which is understandable.

In my .gitlab-ci.yml file I've tried the following...

- git checkout origin/$CI_BUILD_REF_NAME
- git pull

Which gives the following output in the console...

    $ git checkout $CI_BUILD_REF_NAME
    Switched to a new branch 'develop'
    Branch develop set up to track remote branch develop from origin.
$ git pull
You are not currently on a branch. Please specify which
branch you want to merge with. See git-pull(1) for details.

Is there an easy way to reattach the head? Most of the solutions I've seen deal with the fact a change has been committed onto the detached head however this isn't the case for me. I just want to get my full develop branch in my docker container with all of my git history.

Or if there is a way to stop gitlab ci from checking out the detached head that would also be great.

like image 793
Remotec Avatar asked Nov 07 '17 09:11

Remotec


People also ask

How do I fix a detached head in git?

If you want to keep changes made with a detached HEAD, just create a new branch and switch to it. You can create it right after arriving at a detached HEAD or after creating one or more commits. The result is the same. The only restriction is that you should do it before returning to your normal branch.

How do I get my git head back?

To hard reset files to HEAD on Git, use the “git reset” command with the “–hard” option and specify the HEAD. The purpose of the “git reset” command is to move the current HEAD to the commit specified (in this case, the HEAD itself, one commit before HEAD and so on).

What is head detached in git?

In Git, HEAD refers to the currently checked-out branch's latest commit. However, in a detached HEAD state, the HEAD does not point to any branch, but a specific commit or the remote repository. Below is a diagram of the Git HEAD in a normal state, pointing to the latest commit in the main branch.

How do you stop a detached head?

The command git switch (added in Git v2. 23) was added to only work at branch level (and not at commit level), so a good way to avoid detached heads, is to use git switch instead of git checkout to switch between branches, so this will prevent you to make your HEAD point to a commit unintentionally.


1 Answers

A detached HEAD is simply a HEAD containing the raw hash ID of a commit. As noted in the comments, it's generally pretty reasonable to use this for a build system, whether that's some sort of continuous integration or not: you might check out a specific commit by hash ID, or check out a tag name, but either way HEAD winds up containing the commit hash ID and is now guaranteed to be steady.

If you do want to have an "attached" (not-detached) HEAD, though, all you have to do in Git terms is to run git checkout <branch-name>. This writes the name of the branch into HEAD, and now HEAD is attached to that branch. This means that it's not HEAD at all, but rather the branch name, that determines which commit is current. Anything that updates the branch name, changes the current commit.

Note that this property only applies to branch names, i.e., with names that live in the refs/heads/ name-space. The name origin/branch is typically shorthand for refs/remotes/origin/branch, which is not a branch name; it's a remote-tracking name (sometimes called a remote-tracking branch, which is a poor set of words because that sure sounds like "branch", doesn't it?). Supplying any name to git checkout that can be resolved to a commit, but is not a branch name, results in a detached HEAD (if the checkout works at all, anyway).

If you want to have an attached HEAD, it must be attached to a branch name, i.e., a reference whose name starts with refs/heads/.

like image 73
torek Avatar answered Sep 18 '22 17:09

torek