lmo523
lmo523

Reputation: 489

Can't 'reattach' detached HEAD git

I had a branch bug-fix that was cut off of another branch develop

After merging my changes from bug-fix into develop, I deleted the branch through github, however I believe I was still checked into the branch when I deleted it.

I also had one untracked file in the branch bug-fix

After bug-fix was supposedly deleted I checked out out develop and saw HEAD detached at develop

Here's everything I've tried to fix the detached head:

1) First of all the branch bug-fix that was deleted and no longer appears on github still shows up when I run git branch So I tried doing git fetch to update it. Still shows up

2) I checked out bug-fix and deleted the untracked file

3) I tried creating a new branch temp and then deleting it

Upvotes: 1

Views: 2114

Answers (1)

torek
torek

Reputation: 487755

If you saw the literal text string:

HEAD detached at develop

(e.g., in git status output), this means that the name develop is not a branch. (More precisely, it is not a branch name—the term "branch" is ambiguous, in Git. See What exactly do we mean by "branch"?)

For instance, in this Git repository for Git, if I run:

$ git checkout v2.10.0
Note: checking out 'v2.10.0'.
[snip]
HEAD is now at 6ebdac1... Git 2.10
$ git status
HEAD detached at v2.10.0
nothing to commit, working tree clean

This is because the name v2.10.0 is a tag, not a branch.

To get back onto master (which is a branch name) I just:

$ git checkout master
Previous HEAD position was 6ebdac1... Git 2.10
Switched to branch 'master'
Your branch is up-to-date with 'origin/master'.

Branch names, in Git, are really not very important in the long run. In the short run (while you're working) they are important and useful, but eventually a branch like fix-bug-1234 or test-new-feature either works out, and gets incorporated into a long-lived development or release branch and hence gets deleted, or it turns out to be a failure and either gets deleted entirely, or gets "ignore merged" to terminate it as a dead end, and then has its name deleted.

What matters are the commits

In Git, the only thing that really matters are the commits themselves.

A branch name simply serves as a way to find commits. The same is true of a tag name. Each name lets Git find one commit—the name stores the big ugly hashes like 6ebdac1...—and the commits themselves let Git find earlier commits.

The key difference between a branch name and a tag name is that a branch name is supposed to move, and in fact, will automatically move as you make new commits on the branch. To that end, git checkout branch-name puts you "on" the branch, so that Git knows to move the branch when you run git commit.

Any other name, Git mostly treats as a name for the raw hash ID. These give you a "detached HEAD". For git status purposes, Git tries to remember the name you used to get into this "detached HEAD" state. But it's the ID that really matters.

When you delete a branch name, the commits themselves stick around for a while—usually at least 30 days. You can find their IDs in Git's "reflogs". This is kind of a pain in the butt, because if you run git reflog you get a ton of stuff that is hard to search through. But the commits are still in there. You just have to find the one(s) you care about (use, e.g., git show 08bb350 to see commit 08bb350) and "resurrect" them:

$ git branch zombie 08bb350

for instance, if the commit you want back, as a branch, is 08bb350.

Upvotes: 6

Related Questions