2042

I was doing some work in my repository and noticed a file had local changes. I didn't want them anymore so I deleted the file, thinking I can just checkout a fresh copy. I wanted to do the Git equivalent of

svn up .

Using git pull didn't seem to work. Some random searching led me to a site where someone recommended doing

git checkout HEAD^ src/

(src is the directory containing the deleted file).

Now I find out I have a detached head. I have no idea what that is. How can I undo?

Mus
  • 7,290
  • 24
  • 86
  • 130
Daniel
  • 23,365
  • 10
  • 36
  • 34
  • 135
    `git checkout master` will get you back on the master branch. If you wanted to clear out any working copy changes, you probably wanted to do `git reset --hard`. – Abe Voelker Apr 19 '12 at 13:13
  • 5
    See also [Why did my Git repo enter a detached HEAD state?](http://stackoverflow.com/q/3965676/456814). –  May 30 '14 at 05:14
  • if you haven't committed you could've done `git checkout -- src/` – geekay May 07 '15 at 14:28
  • 1
    Try this: [link](http://learnwebtutorials.com/you-are-in-detached-head-state-how-fix). In short `create temp branch - checkout temp branch - checkout master - delete temp branch` – fidev Jun 02 '17 at 09:20
  • @AbeVoelker What did you mean in the comments by `working copy changes`? Are you referring to the changes you made to files after checking out another commit (i.e., the changes you made while in a detached head state)? – Minh Tran Dec 07 '17 at 19:05
  • I lost my my current files after I did `git checkout master` – multigoodverse May 05 '20 at 12:25
  • 1
    If your branch is called `main` instead of `master`, use `git checkout main` to get back to it latest commit on that branch. – neuhaus Jun 02 '23 at 13:06

30 Answers30

2927

Detached head means you are no longer on a branch, you have checked out a single commit in the history (in this case the commit previous to HEAD, i.e. HEAD^).

If you want to keep your changes associated with the detached HEAD

  1. Run git branch tmp - this will save your changes in a new branch called tmp.
  2. Run git checkout master
  3. If you would like to incorporate the changes you made into master, run git merge tmp from the master branch. You should be on the master branch after running git checkout master.

If you want to delete your changes associated with the detached HEAD

You only need to checkout the branch you were on, e.g.

git checkout master

Next time you have changed a file and want to restore it to the state it is in the index, don't delete the file first, just do

git checkout -- path/to/foo

This will restore the file foo to the state it is in the index.

Chai T. Rex
  • 2,972
  • 1
  • 15
  • 33
rtn
  • 127,556
  • 20
  • 111
  • 121
  • 6
    "This will restore the file foo to the state it was before you made any changes to it." --> it will restore it to the state it is in the _index_ - please edit – Mr_and_Mrs_D Jul 18 '13 at 21:39
  • `git checkout path/to/foo` could conflict with `git checkout some-branch`, so it would be better to use `git checkout -- path/to/foo` to avoid these conflicts. – Diego Dec 18 '13 at 09:26
  • 136
    Why does this error occur in the first place? This is one of the things I hate git for - totally random behavior at times. Never had such problems with Mercurial. – Violet Giraffe Oct 07 '14 at 20:36
  • 136
    @VioletGiraffe It is neither an error nor something random -- it is simply the state your repository goes into when you checkout a previous commit. The "Detached Head" serves as a warning that you may also want to create or point to a branch if you intend to do any work from that point. But If you simply wish to view that tag or commit, there is nothing wrong with being in a detached head state. – Neil Neyman Nov 25 '14 at 17:09
  • 27
    Don't do this if you have committed to the detached head, see other answers. If do, you can checkout the previous head git mentions in `Previous HEAD position was 7426948...` – KCD Jan 20 '16 at 23:46
  • 1
    just in case any noobs make a mistake: path/to/foo is not a literal path - you want to replace your folder path with the path/to/foo folder path. – BenKoshy Feb 09 '16 at 12:39
  • 2
    @nottinhill Why are you committing with a detached head...? There's an explicit warning *not* to do that without first creating a branch. – Dan Bechard Dec 06 '16 at 16:15
  • 1
    This was not the answer for me at all. I was absolutely on a branch but I wasn't on a trackable branch. I did git checkout remote/branch and I needed to do git checkout origin/branch - or something similar. – fIwJlxSzApHEZIl Dec 15 '16 at 21:58
  • 1
    @ralphtheninja Hello, Having read your answer, I have a little question: When in SourceTree I double click on a previous commit (in order to check it out) I get the same message that this would cause a detached head, so I wonder what it means when people say you can simple roll back to any previous state with git? How do I roll back to a particular commit then? Thanks –  Sep 03 '17 at 14:37
  • 1
    @Joshua Not sure what you mean by "roll back". If you have made a commit you can always check out that commit. – rtn Sep 03 '17 at 19:56
  • 1
    @ralphtheninja Thanks for your reply. By "roll back" I mean going bak to the state of the project at a particular commit/revision. I know I can check out any commit, but when I do so, I get a warning that my checking out would cause a detached head. So, I wonder how I can go back to the state of a project, say, two commits ago if I cannot simply check it out? –  Sep 04 '17 at 06:09
  • 2
    @Joshua If you want to go back to any commit you previously checked out (either 1, 2, or 3 etc steps) then you can take a look at `git reflog` – rtn Sep 04 '17 at 11:32
  • Here is a great visual explanation of a similar case that may help people understand what is going on: https://stackoverflow.com/a/34994175/5040168 – AndyO Jun 09 '18 at 22:21
  • 2
    To not loose wour work, backup your folder first (that's what I did). – Antônio Medeiros Jul 24 '18 at 04:30
  • 1
    When you run `git checkout master`, Git advises you: `Warning: you are leaving 1 commit behind, not connected to any of your branches [...] If you want to keep it by creating a new branch, this may be a good time to do so with: git branch `. I don't believe following this answer *ipsis litteris* causes lose of work. But in any situation, a backup is always a good precaution. – Antônio Medeiros Jul 24 '18 at 04:35
  • 3
    By the end, assure your commit is on `master` and you may delete the `tmp` local branch: `git branch -d tmp` – Antônio Medeiros Jul 24 '18 at 04:38
  • Visual Studio 2017 displayed the detached status in the branch selector in the status bar. I simply selected "master" and was re-attached without losing the changes I had made when detached. – Olivier Jacot-Descombes Sep 14 '18 at 14:21
  • 29
    @VioletGiraffe: you have a mental model of what's happening based on Mercurial, but you're using Git. If you are unwilling to adjust your mental model to fit Git's model, then things will continue to appear random. It's like you're walking around outside with VR goggles on, and you think you're flying a plane but you're really crossing the street. You're gonna get hit by cars. – iconoclast Nov 12 '18 at 17:26
  • 1
    You can skip the branch bit, and just do `git merge ` directly. I don't know why you'd want to create a branch here. – Fake Name Dec 04 '18 at 01:13
  • Please add change the order of two 'bold' secitons. In a hurry I checkout out the master. I can hence no longer access the logs from the detached head. Amazing post. – vineeshvs Mar 20 '19 at 08:39
  • This works, but it's missing a step where the head is still not in sync with the master branch. I edited the answer to include it. – kp123 Aug 14 '19 at 17:59
  • How can this be right? I didn't checkout a single commit. I did `git branch -a`, then checked out one of those branches and I'm in a 'detached HEAD' state. There are no changes associated with the detached HEAD state. The checkout worked fine and all my files match what was in that commit. – Vince Apr 24 '20 at 06:21
  • 1
    @ralphtheninja, I've simplified the instructions that JamesKo added to your answer before. Feel free to roll back, of course. :) – ANeves Apr 30 '20 at 17:58
  • `git:(2020_04_21) git checkout origin/2020_05_05` `Note: checking out 'origin/2020_05_05'.` `You are in 'detached HEAD' state.` Yeah maybe a little bit, kind of, maybe random? – Ben Racicot May 01 '20 at 19:00
  • 2
    @BenRacicot: That's not random either -- `origin/2020_05_05` is a remote branch, which can't be checked out directly. If you're not sure why that is, consider that you don't actually control a remote branch, as it's on a different computer -- so you can't commit to or edit it without a network connection, and Git only requires a network connection on fetch/push/pull operations. Instead you have to make the changes on a local branch and then push them. You probably wanted just `git checkout 2020_05_05`, which will create a local branch (which you can edit) that tracks the remote branch. – Soren Bjornstad Oct 04 '20 at 16:12
  • 2
    @iconoclast Rather than berating Violet Giraffe for having the wrong mental model, it would be great if you could offer some hints about how to adopt the correct mental model for git. I've never used Mercurial, but I'm as frustrated as Violet Giraffe is. Not only is git's behavior frequently inexplicably random, but 90% of the explanations I read are completely incomprehensible. Everyone says you have to have the right mental model, but no one explains what it is. Newbies are expected to reverse engineer that model from incomprehensible explanations — a nearly impossible task. – Steve Summit Nov 05 '21 at 17:13
  • @SteveSummit It's very interesting that (on the one hand) when I explain to Violet Giraffe the underlying cause of the problem (the wrong mental model), you decide I'm "berating" them, and that it's my responsibility to (1) spend time understanding the Mercurial model, and (2) explain the differences between them, BUT (on the other hand) you don't see any problem with criticizing Git simply for being based on a different model. I don't know but I'm willing to bet that the different model is because Git was designed to easily do things that are hard or impossible out of the box with Mercurial. – iconoclast Nov 05 '21 at 18:13
  • @SteveSummit there is an endless supply of Git Tutorials, and many of them explain not just how to USE Git, but what Git is doing under the hood. Here's one: https://missing.csail.mit.edu/2020/version-control/ and here's another: http://www-cs-students.stanford.edu/~blynn/gitmagic/ch08.html . Both deal with Git's data model, which should inform your mental model of what you're doing when you use Git. – iconoclast Nov 05 '21 at 18:21
  • 1
    In the second case I prefer `git reset --hard tmp` instead of `git merge tmp`, to not clutter the git commit history. – user2340939 Mar 27 '22 at 12:42
  • for the uninitiated, master needs to be replaced with whatever you named your "main branch" - master is not a variable understood by git – Sam Weisenthal Sep 15 '22 at 18:04
  • For me works on git version 2.39 with the command: `git checkout main` I found 'main' name on `git reflog`: `"789456 (HEAD -> , , main)` – Sergio Perez Feb 09 '23 at 18:10
  • @iconoclast there is no mental model that can explain every git intricacies. – Shautieh Mar 03 '23 at 12:40
  • @Shautieh: perhaps there is no _simplified_ model—like a metaphor. But you can always conform your way of thinking to _what Git actually does_. Plenty of Git tutorials explain how and where Git saves its data. If you find the metaphors unsatisfying, then you can learn what it's actually doing. – iconoclast Mar 03 '23 at 20:38
  • @iconoclast I am not disagreeing here that it is the way to go to truly use git, but myself and many others just want to save files in a tree and branches, and share those. Rarely do I shoot myself in the foot, and learning git's internals is not worth it for me. – Shautieh Mar 08 '23 at 20:39
571

If you have changed files you don't want to lose, you can push them. I have committed them in the detached mode and after that you can move to a temporary branch to integrate later in master.

git commit -m "....."
git branch my-temporary-work
git checkout master
git merge my-temporary-work

Extracted from:

What to do with commit made in a detached head

Community
  • 1
  • 1
Toni Gamez
  • 6,819
  • 1
  • 23
  • 18
  • 30
    I find this to be the preferred solution - especially if you want to keep the changes you made when you checked out the individual version. – adswebwork Mar 20 '14 at 15:43
  • 11
    @adswebwork: I agree. All the other answers suggest reverting to a previous state and losing changes made locally in the detached head state. – Sk8erPeter Mar 26 '14 at 14:24
  • 10
    why not `git stash` ? As that is the first thing that comes to my mind. creating a new branch will be an overkill. – geekay May 07 '15 at 14:29
  • 3
    you could also `git rebase my-temporary-work` and then delete the branch `git branch -d my-temporary-work` so it appears as if you committed to the right branch in the first place. – Zoltán May 12 '15 at 16:17
  • @geekay `git stash` does sound like the perfect tool for this case. Could you please write an answer with the suggested steps to achieve that? – Zoltán May 12 '15 at 16:19
  • @Zoltán Replace `git branch ..` with `git stash` and `git merge ..` with `git stash apply`. – Dan Bechard Dec 06 '16 at 16:18
  • Well, this is what I did and it works . `$git reflog` (look for the SHA of the HEAD you want to restore) . `$git checkout HEAD_SHA` (you should on this detached head now) . `$git branch BRANCH_NAME` (you merge change from HEAD to a new branch by doing this) . Then with this new branch you can merge, rebase, cherry-pick do whatever you'd like to – infinity_coding7 Sep 13 '18 at 13:37
  • THis is all so much more difficult with github. Would this checkout master be my fork of the master or the upstream master? Can I even create a branch on upstream master? – Antti Rytsölä Nov 14 '22 at 11:14
  • 1.Check out of the headless state `git checkout `. This will save the detached head to this branch. 2. Check into a branch which is tracking an origin head correctly `git checkout ` this is any branch of your choice, including main (master). 3. In this branch merge `git merge ` the detached head now tracks the branch you have switched to. If you don't want changes delete `git delete ` this is a destructive command.[More](https://sumisastri.medium.com/git-and-git-heads-f1f8c3d9c7df) – Sumi Jan 17 '23 at 14:16
203

A solution with no temporary branch or merge commit

How to exit (“fix”) detached HEAD state when you already changed something in this mode and, optionally, want to save your changes:

  1. Commit changes you want to keep. If you want to take over any of the changes you made in detached HEAD state, commit them. For example:

    git commit -a -m "your commit message"
    
  2. Discard changes you do not want to keep. The hard reset will discard any uncommitted changes that you made in detached HEAD state:

    git reset --hard
    

    (Without this, step 3 would fail, complaining about modified uncommitted files in the detached HEAD.)

  3. Check out your branch. Exit detached HEAD state by checking out the branch you worked on before, for example:

    git checkout master
    
  4. Take over your commits. You can now take over the commits you made in detached HEAD state by cherry-picking, as shown in my answer to another question.

    git reflog
    git cherry-pick <hash1> <hash2> <hash3> ...
    
tanius
  • 14,003
  • 3
  • 51
  • 63
  • 1
    The `git reset --hard` was exactly was I needed, because I want the upstream to be the source and the local changes should be removed. – Markus Zeller Dec 11 '19 at 10:41
  • 1
    I almost down-voted this solution, until i see the step 4. What a panic (i followed till step 3 and ...). Thanks for the solution. – fchen Feb 10 '22 at 06:34
  • 1
    This should be top answer. No additional merge info in branch history. – lord5et Feb 27 '23 at 15:22
162

HEAD is a pointer, and it points — directly or indirectly — to a particular commit:

Attached  HEAD means that it is attached to some branch (i.e. it points to a branch).
Detached HEAD means that it is not attached to any branch, i.e. it points directly to some commit.

enter image description here

In other words:

  • If it points to a commit directly, the HEAD is detached.
  • If it points to a commit indirectly, (i.e. it points to a branch, which in turn points to a commit), the HEAD is attached.

To better understand situations with attached / detached HEAD, let's show the steps leading to the quadruplet of pictures above.

We begin with the same state of the repository (pictures in all quadrants are the same):

enter image description here


Now we want to perform git checkout — with different targets in the individual pictures (commands on top of them are dimmed to emphasize that we are only going to apply those commands):

enter image description here


This is the situation after performing those commands:

enter image description here

As you can see, the HEAD points to the target of the git checkout command — to a branch (first 3 images of the quadruplet), or (directly) to a commit (the last image of the quadruplet).

The content of the working directory is changed, too, to be in accordance with the appropriate commit (snapshot), i.e. with the commit pointed (directly or indirectly) by the HEAD.


So now we are in the same situation as in the start of this answer:

enter image description here

MarianD
  • 13,096
  • 12
  • 42
  • 54
  • 2
    What is missing is: "When I checkout a numeric commit that also is the top of some branch, will it result in a detached head, or will the associated branch be used instead?" My guess is: "No detached head then" – U. Windl Jul 27 '20 at 12:26
  • @U.Windl, answer yourself — will then HEAD point to a branch (which in turn will point to a commit), or will then HEAD point *directly* to a commit? See the start of my answer after your answer. – MarianD Jul 27 '20 at 21:12
  • I understand that it *is* possible to directly check out a revision without checking out a branch that happens to be pointing to it. Logically: two or more branches can point to the same revision. If you then check out a revision by its hash, which branch would the command choose? – Mike Rosoft May 25 '21 at 07:20
  • @Mike, NO branch will be chosen, all branches (as pointers to commits) will stay unchanged - you may see it in all pictures of my answer (the brown boxes). **Only the HEAD** will point not to a branch, but directly to a commit, so you will finish with the "Detached HEAD" state - see the last (the right bottom) picture. - **In spite of 2 branches pointed to the same commit, if you select this commit by the hash, the HEAD will point NOT to one of these 2 branches, but *directly* to the commit.** – MarianD May 25 '21 at 17:47
  • @MarianD I think there was a bit of misunderstanding - I was explaining why you can't expect Git to checkout a branch when you select a revision by its hash. – Mike Rosoft May 25 '21 at 17:51
  • @Mike, you may either check out a **branch** - the HEAD moves to the branch - or check out a **commit** - the HEAD moves to a commit. No other changes in these pointers. The answer to your question *"If you then check out a revision by its hash, which branch would the command choose?"* is: "**No branch. You selected a commit, so the command chooses a commit, totally ignoring branches.**" – MarianD May 25 '21 at 18:02
  • @MarianD I am not disputing any of this. It was a rhetorical question - I wasn't seriously asking which branch would Git choose; I was asking it to explain why you couldn't expect Git to choose a branch. – Mike Rosoft May 29 '21 at 06:02
158

Detached head means:

  1. You are no longer on a branch,
  2. You have checked out a single commit in the history

If you have no changes: you can switch to master by applying the following command

  git checkout master

If you have changes that you want to keep:

In case of a detached HEAD, commits work like normal, except no named branch gets updated. To get master branch updated with your committed changes, make a temporary branch where you are (this way the temporary branch will have all the committed changes you have made in the detached HEAD), then switch to the master branch and merge the temporary branch with the master.

git branch  temp
git checkout master
git merge temp
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Razan Paul
  • 13,618
  • 3
  • 69
  • 61
  • 2
    perfect, then after remove branch temp – Davi Menezes Feb 24 '18 at 13:06
  • To switch from one branch to another, git now accepts the verb switch: https://git-scm.com/docs/git-switch . Apart from which verb you might prefer, checkout has the disadvantage that it is used for a variety of other purposes https://git-scm.com/docs/git-checkout. – Francis Aug 14 '20 at 07:28
104

If you made changes and then realized that you are on a detached head, you can do: stash -> checkout master -> stash pop:

git stash
git checkout master   # Fix the detached head state
git stash pop         # Or for extra safety use 'stash apply' then later 
                      #   after fixing everything do 'stash drop'

You will have your uncommited changes and normal "attached" HEAD, like nothing happened.

mojuba
  • 11,842
  • 9
  • 51
  • 72
  • 4
    Have bookmarked this bad boy - saves making a temp branch. Worked a treat. – Tim Tyler Jul 11 '18 at 12:25
  • 3
    I often end up in a detached HEAD state after checking out a git submodule, then making changes to it. I find that this is the best and easiest solution to get things fixed so I can preserve my changes. – user5359531 Oct 31 '18 at 16:01
  • 3
    This doesn't work if you have already commited changes in a detached state? – Danijel Sep 18 '19 at 06:21
  • 1
    LIFE SAVIOR!!! None of the previous solutions worked when I just ended up stuck in the same loop. This is dead simple!! Ty – testing_22 Sep 14 '22 at 02:08
84

Here's what I just did after I realized I was on a detached head and had already made some changes.

I committed the changes.

$ git commit -m "..."
[detached HEAD 1fe56ad] ...

I remembered the hash (1fe56ad) of the commit. Then I checked out the branch I should have been on.

$ git checkout master
Switched to branch 'master'

Finally I applied the changes of the commit to the branch.

$ git cherry-pick 1fe56ad
[master 0b05f1e] ...

I think this is a bit easier than creating a temporary branch.

Philippe Gerber
  • 17,457
  • 6
  • 45
  • 40
  • 3
    This should be the answer. It gets back your nuked files. – BlindWanderer Oct 12 '14 at 02:43
  • 2
    Yes, this really is the simplest thing to do — simple enough to remember without searching the web the next time it happens. Commit, note hash, return to branch you meant to commit to, and `git cherry-pick `. – Mason Feb 25 '16 at 12:08
  • Thanks for the solution. This helped. May I also add that I had to do a "git push origin master" so that my master and origin/master were pointing to the same commit. – turnip424 May 21 '18 at 06:12
  • 1
    This is essentially [tanius' answer](https://stackoverflow.com/questions/10228760/fix-a-git-detached-head/17045215#17045215) (posted more than a year prior). – Peter Mortensen Aug 20 '18 at 15:11
  • Thanks this cheery pick revert the last detach head changes – Abdullah Khan Jan 13 '20 at 15:34
  • This also prevents you having to have an additional 'merge' commit to clean up, if you go the temporary branch route. – RGD2 Mar 24 '22 at 06:00
47

When you check out a specific commit in git, you end up in a detached head state...that is, your working copy no longer reflects the state of a named reference (like "master"). This is useful for examining the past state of the repository, but not what you want if you're actually trying to revert changes.

If you have made changes to a particular file and you simply want to discard them, you can use the checkout command like this:

git checkout myfile

This will discard any uncommitted changes and revert the file to whatever state it has in the head of your current branch. If you want to discard changes that you have already committed, you may want to use the reset command. For example, this will reset the repository to the state of the previous commit, discarding any subsequent changes:

git reset --hard HEAD^

However, if you are sharing the repository with other people, a git reset can be disruptive (because it erases a portion of the repository history). If you have already shared changes with other people, you generally want to look at git revert instead, which generates an "anticommit" -- that is, it creates a new commit that "undoes" the changes in question.

The Git Book has more details.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • 2
    As I said in @ralphtheninja's answer, `git checkout path/to/foo` could conflict with `git checkout some-branch`, so it would be better to use `git checkout -- path/to/foo` to avoid these conflicts. – Diego Dec 18 '13 at 09:27
33

Since "detached head state" has you on a temp branch, just use git checkout - which puts you on the last branch you were on.

yyny
  • 1,623
  • 18
  • 20
Mike
  • 1,884
  • 2
  • 24
  • 42
  • 2
    be careful, you will loose any commits you made when you were on detached head state. – Ajak6 Aug 25 '17 at 23:20
  • 2
    @Ajak6 You don't really lose those commits. They are still available via `git reflog` and can be taken over into a new branch or via `git cherry-pick` into an existing branch. See [this question](https://stackoverflow.com/q/9984223). – tanius Sep 18 '18 at 22:37
  • 1
    However, after a period of time any revision which isn't being pointed to by a branch or a tag (or isn't a current working revision), or isn't an ancestor of such a revision, is liable to be permanently deleted. – Mike Rosoft May 25 '21 at 07:24
  • @tanius. You are a live saver. You just saved us a lot of work. – kv1dr Aug 31 '23 at 13:46
17

you probably did git reset --hard origin/your-branch.

Try to just git checkout your-branch

Johnny Cage
  • 5,526
  • 2
  • 11
  • 7
15

Being in "detached head" means that HEAD refers to a specific unnamed commit (as opposite to a named branch) (cf: https://git-scm.com/docs/git-checkout section Detached head). In reality, this means that you have checked out a commit but there is no branch name associated with it.

You may choose to only create a new branch associated with your commit by

git branch new-branch-name.

This allows you to save your current state in a new branch named new-branch-name and not be in a detached head state anymore.

Or if you would like to come back to the previous state, you need to select the branch that was selected before by

git checkout @{-1}

Pat. ANDRIA
  • 2,330
  • 1
  • 13
  • 27
11

To further clarify @Philippe Gerber's answer, here it is:

git cherry-pick

Before cherry-pick, a git checkout master is necessary in this case. Furthermore, it is only needed with a commit in detached head.

Timo
  • 2,922
  • 3
  • 29
  • 28
8

Addendum

If the branch to which you wish to return was the last checkout that you had made, you can simply use checkout @{-1}. This will take you back to your previous checkout.

Further, you can alias this command with, for example, git global --config alias.prev so that you just need to type git prev to toggle back to the previous checkout.

David Brower
  • 2,888
  • 2
  • 25
  • 31
  • 1
    what I needed was a way to get back my HEAD before I rebased my branch. This solved my issue! Thanks a bunch :) – 0xe1λ7r Nov 30 '21 at 22:50
8

Detached head means you have not checked out your branch properly or you have just checked out a single commit.

If you encounter such an issue then first stash your local changes so that you won't lose your changes.

After that... checkout your desired branch using the command:

Let's say you want branch MyOriginalBranch:

git checkout -b someName origin/MyOriginalBranch

Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
Dhirendra Gautam
  • 737
  • 8
  • 16
8

To add to @ralphtheninja's answer. If you get this message after using git checkout master:

Please commit your changes or stash them before you switch branches. Aborting

Then you can simply force the checkout using the -f flag as follows:

git checkout -f master

Apparently this will result in losing all the changes made in the detached mode. So be careful when using it.

Souhaib
  • 119
  • 1
  • 6
7

This approach will potentially discard part of the commit history, but it is easier in case the merge of the old master branch and the current status is tricky, or you simply do not mind losing part of the commit history.

To simply keep things as currently are, without merging, turning the current detached HEAD into the master branch:

  1. Manually back up the repository, in case things go unexpectedly wrong.
  2. Commit the last changes you would like to keep.
  3. Create a temporary branch (let's name it detached-head) that will contain the files in their current status:
git checkout -b detached-head
  1. (a) Delete the master branch if you do not need to keep it
git branch -D master
  1. (b) OR rename if you want to keep it
git branch -M master old-master
  1. Rename the temporary branch as the new master branch
git branch -M detached-head master

Credit: adapted from this Medium article by Gary Lai.

alexhg
  • 690
  • 7
  • 11
6

Git told me how to do it.

if you typed:

git checkout <some-commit_number>

Save the status

git add .
git commit -m "some message"

Then:

 git push origin HEAD:<name-of-remote-branch>
Sterling Diaz
  • 3,789
  • 2
  • 31
  • 35
  • In my case I already committed the changes. That last line allowed me to push changes to the remote master manually, then I changed my local branch to master so it's no longer detached, then sync'd again to be sure. Everything seems good now. – James Wilkins Oct 04 '22 at 07:53
6

I was in a similar situation.
For some reason I ended up with a detached head - I had made commits on the same path as the branch I thought I was on - eg HEAD was a child of the branch tag but for some reason the branch tag had stayed back at a historic commit... possibly because I had pushed??

It wouldn't let me push because I wasn't considered to be on the branch I thought I was on.

I didn't want to change any of my history or do any cherry picking and I'd just spent about 8 weeks working on the branch so reset --hard was making me a bit nervous!

The solution was just to do the following:

git branch -f myStuckBranch HEAD
git checkout myStuckBranch

You need to do the checkout even though HEAD and myStuckBranch are now pointing at the same thing because you are still considered to be in the detached head state (not on a branch)

I'm not an expert with git (having mostly used mercurial which would never create this weird situation) but my understanding of this command is that it just says "change myStuckBranch to point at HEAD".

I routinely find myself using this command to merge in changes from master after fetching without having to swap my working directory - otherwise it tries to use the old (uninteresting) version of master:

git fetch
git branch -f master origin/master  -- err yeah don't just ignore what's been going on remotely - eg point my master at the real master
git merge master -- merge the changes into my local branch

It's a bit annoying to have to manually have to do that all the time but still better than having to change your working directory just to update another branch in order to merge in changes from it.

JonnyRaa
  • 7,559
  • 6
  • 45
  • 49
  • Your first set of commands is exactly the scenario I was in. I also came from Mercurial and it is surprising how hard it is to reattach one’s head compared to how easily it is detached. For your second set of commands, you should just checkout `master` locally—`git pull` already does `git fetch` and `git merge` for you. No point in making things pointlessly more complicated (though it is always nice to have an understanding of what is going on)! – binki Apr 10 '22 at 04:23
  • Yeah I'm just about getting used to git now but I still find that a bit quirky. Btw you can one line that first command with `git checkout -B myStuckBranch` – JonnyRaa Jul 18 '22 at 11:10
  • With that second one the intention is to not swap branch at all and just merge master into the current branch. If you checked out master then you'd have to pull and then checkout you original branch again to do the merge. I tend to have a build that watches file changes open and so like to avoid churning the working directory when I'm not actually doing anything – JonnyRaa Jul 18 '22 at 11:13
  • With the second group of commands, you can just do the following when you have your secondary branch checked out: `git pull origin master`. That will not update your local repository’s `master` branch, but it will fetch and then merge `origin/master` into the current branch. You could also do `git fetch; git merge origin/master` (which does not update your local `master` branch). Or even `git fetch origin master:master; git merge master` (which updates your local `master` branch like your snippet does but requires more typing). Again, it’s more important to do what you understand! – binki Jul 18 '22 at 15:18
  • @binki that's interesting, not seen the `git pull` one before, so many different ways of doing things! I just have the fetch/branch update as a bash function so it doesn't bother me any more. I think if you do the `git merge origin/master` it gives a less nice commit message – JonnyRaa Aug 09 '23 at 11:17
5

Git : You are not currently on a branch.

Time to time Git shows :

To push the history leading to the current (detached HEAD) state now, use

git push origin HEAD:<name-of-remote-branch>

It means :

To fix that run 2 commands :

  1. git branch -f {{your_working_branch}} HEAD -- set branch to your head
  2. git checkout {{your_working_branch}} -- checkout==switch branch
Bruno
  • 6,623
  • 5
  • 41
  • 47
4

Normally HEAD points to a branch. When it is not pointing to a branch instead when it points to a commit hash like 69e51 it means you have a detached HEAD. You need to point it two a branch to fix the issue. You can do two things to fix it.

  1. git checkout other_branch // Not possible when you need the code in that commit hash
  2. create a new branch and point the commit hash to the newly created branch.

HEAD must point to a branch, not a commit hash is the golden rule.

Krishnadas PC
  • 5,981
  • 2
  • 53
  • 54
  • this is why I had this very error. I checked out to a revision and then checked out back again to the current/latest revision instead of checking out to the branch, which would have attached the head properly. Thanks for the help. – Rahul Thakur Mar 28 '20 at 22:01
4

This was a confusing thing to me when I started to work with git and later I figure out why this is happening and what is the best way to deal with such a situation.

The root cause for such occurrence is that normally git HEAD is always pointing to some branch and when you try to point the HEAD to some specific commit, you put HEAD into a detached HEAD state.

When HEAD is attached state -

cat .git/HEAD     # output--> ref: refs/heads/master or ref: refs/heads/main

When HEAD is detached state -

cat .git/HEAD     # output--> b96660a90cad75867453ebe1b8d11754bbb68b0e <commit hash>

Solution -

git stash           # Temporarily shelves (or stashes) changes
git branch          # Find your default branch
git switch master   # Point HEAD to master or main branch
git stash pop       # Apply all the changes you had previously
Aravinda Meewalaarachchi
  • 2,551
  • 1
  • 27
  • 24
3

I wanted to keep my changes so, I just fix this doing...

git add .
git commit -m "Title" -m "Description"
(so i have a commit now example: 123abc)
git checkout YOURCURRENTBRANCH
git merge 123abc
git push TOYOURCURRENTBRANCH

that work for me

Paul Rooney
  • 20,879
  • 9
  • 40
  • 61
CRLZXO
  • 49
  • 4
3

When you're in a detached head situation and created new files, first make sure that these new files are added to the index, for example with:

git add .

But if you've only changed or deleted existing files, you can add (-a) and commit with a message (-m) at the the same time via:

git commit -a -m "my adjustment message"

Then you can simply create a new branch with your current state with:

git checkout -b new_branch_name

You'll have a new branch and all your adjustments will be there in that new branch. You can then continue to push to the remote and/or checkout/pull/merge as you please.

DZet
  • 539
  • 3
  • 10
3

Realizing I had a detached head without knowing how I managed to get it (like three commits away), I also found out that trying to merge, rebase or cherry-pick triggered hundreds of merge-conflicts, so I took a different approach:

  1. (Assuming everything is committed (working tree is "clean"))

  2. Save my commit messages: git log > /tmp/log

  3. Save my working tree: mkdir /tmp/backup && cp -a all_my files_and_directories /tmp/backup

  4. Revert to master: git checkout master

  5. Remove all the working files and directories: rm ...

  6. Use the backup: cp -a /tmp/backup/. .

  7. git add and git commit using messages from saved /tmp/log, maybe repeating it with different sub-sets of files...

The disadvantage is that you loose your commit history if one file was changed multiple times since master, but in the end I had a clean master.

U. Windl
  • 3,480
  • 26
  • 54
2

The detached HEAD means that you are currently not on any branch. If you want to KEEP your current changes and simply create a new branch, this is what you do:

git commit -m "your commit message"
git checkout -b new_branch

Afterwards, you potentially want to merge this new branch with other branches. Always helpful is the git "a dog" command:

git log --all --decorate --oneline --graph
gebbissimo
  • 2,137
  • 2
  • 25
  • 35
2

If you hate head and wanna go back to main instead:

git checkout main

If you love head but just wish main tracked it:

git checkout -B main HEAD

(This works with any branch name, not just main, and for any commit pointer, not just HEAD.)

(If you have uncommitted changes that you want to commit, commit them first.)

Sandra
  • 229
  • 3
  • 7
2

I came here because I had the HEAD detached at... message.

In my case it wasn't due to some local changes because, on that system I never do any changes.

The reason for my message was: I accidently checked out origin/myBranch instead of myBranch.

So when checking out myBranch everything returned to normal.

Skeeve
  • 7,188
  • 2
  • 16
  • 26
1

This works for me, It will assign a new branch for detached head :

git checkout new_branch_name detached_head_garbage_name

lenooh
  • 10,364
  • 5
  • 58
  • 49
Alok Gupta
  • 1,806
  • 22
  • 21
1

With git rebase you can move your HEAD to the desired commit

Suppose you have your branch in a detached state, like this:

* bfcb8f9 Commit 4
* 540a123 Commit 3
* 4356d64 Commit 2
| * fecb8d2 Commit 2
|/
| * 8012f45 Commit 2x
|/
| * 6676d15 (HEAD -> master) Commit 2 --amend
|/
* 1818f91 Commit 1

The detached head was created by rebasing by mistake, pointing to a detached commit, which was created previously due a git commit --amend command.

If you want to move your HEAD ref to the most recent commit, apply a rebase with the desired HASH commit you want to point to. In this example, the hash is of the most recent commit:

git rebase bfcb8f9

and this will leave your branch with its HEAD poiting to the desired commit (the most recent in this case):

* bfcb8f9 (HEAD -> master) Commit 4
* 540a123 Commit 3
* 4356d64 Commit 2 --amend
| * fecb8d2 Commit 2
|/
| * 8012f45 Commit 2x
|/
| * 6676d15 Commit 2
|/
* 1818f91 Commit 1
0
git pull origin master

worked for me. It was just about giving remote and branch name explicitly.