405

Using git I made something like this

git clone
git checkout {a rev number tree rev before} (here I started to be in a detached head state)
//hacking
git commit
//hacking
git commit
(some commit where made on origin/master)
git pull (which does complete because there was some error due to the fact that I'm no more on master)

Because it said to me that I can still commit when in a detached head state, I did so. But now I want to like merge my detached head branch and my local master branch, and then push my bunch of changes to origin/master.

So my question is how could I merge the master branch with my actual state (detached head)

Bilaal Rashid
  • 828
  • 2
  • 13
  • 21
benzen
  • 6,204
  • 4
  • 25
  • 37
  • possible duplicate of [Git: HEAD has disappeared, want to merge it into master](http://stackoverflow.com/questions/2519031/git-head-has-disappeared-want-to-merge-it-into-master) – Karl Bielefeldt Aug 19 '11 at 17:10
  • 1
    I you could add a screenshot of a commit tree in this state (how a commit on a detached head actually looks like in gitk or SourceTree), that would make this question even better. – florisla May 06 '15 at 11:41
  • Unfortunalty at the moment i can't but if you can provide on, i'll be happy to see it here. Even if It's must a draw, it will make it clearer – benzen May 06 '15 at 15:11

12 Answers12

663

Create a branch where you are, then switch to master and merge it:

git branch my-temporary-work
git checkout master
git merge my-temporary-work
Ryan Stewart
  • 126,015
  • 21
  • 180
  • 199
  • 22
    how does one avoid detaching heads in the future? – ycomp Mar 04 '16 at 04:17
  • I did this and found myself ahead of origin by 5 commits. In that case do you just do git push origin? – Winnemucca Apr 05 '16 at 23:31
  • 8
    strange, I get "Already up-to-date." when merging the my-temporary-work – Robert Sinclair Sep 22 '16 at 17:37
  • 15
    Don't forget to delete my-temporary-work with "git branch -d my-temporary-work" – Captain Lepton Feb 27 '17 at 16:57
  • 6
    @ycomp "detached head" happens when you edit the files of an old commit and then commit those without a branch to reference this new commit later. To avoid detached head, don't checkout old commits. If you still want all the files from there, but as a new commit, then you could checkout the directory from the commit, instead of the commit itself. [See this answer](https://stackoverflow.com/a/9671161/2550406) – lucidbrot Dec 03 '17 at 10:35
  • @RobertSinclair you get the `up-to-date` message because you did a `pull` before and therefore are `uptodate` when checking out(=switching to) `master`. – Timo May 19 '21 at 18:05
  • This was the answer I was looking for. Worked perfectly in 2021. – Eric Hepperle - CodeSlayer2010 Nov 23 '21 at 11:52
144

You could do something like this.

# Create temporary branch for your detached head
git branch tmp

# Go to master
git checkout master

# Merge in commits from previously detached head
git merge tmp

# Delete temporary branch
git branch -d tmp

Even simpler would be

git checkout master
git merge HEAD@{1}

but this has the slight danger that if you do make a mistake it can be a little harder to recover the commits made on the detached head.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
  • 4
    I know this is years later, but thanks for this answer. I didn't consider myself done searching with the accepted answer here because I didn't want to leave around a temporary branch and this answer has the command to delete it. – Jeremy Pridemore Mar 04 '14 at 23:26
  • 10
    If you decide to use the command `git merge HEAD@{1}` you should probably ensure that is the one you want to use by using `git reflog` – Michael Stramel Feb 03 '15 at 18:46
  • 4
    Being able to merge HEAD@{1} saved my life since I had already checked out master preemptively. – juil Jul 13 '16 at 21:44
39

This is what I did:

Basically, think of the detached HEAD as a new branch, without name. You can commit into this branch just like any other branch. Once you are done committing, you want to push it to the remote.

So the first thing you need to do is give this detached HEAD a name. You can easily do it like, while being on this detached HEAD:

git checkout -b some-new-branch

Now you can push it to remote like any other branch.

In my case, I also wanted to fast-forward this branch to master along with the commits I made in the detached HEAD (now some-new-branch). All I did was:

git checkout master

git pull # to make sure my local copy of master is up to date

git checkout some-new-branch

git merge master # this added the current state of master to my changes

Of course, I merged it later to master.

That's about it.

MrConorAE
  • 23
  • 1
  • 8
Bhushan
  • 18,329
  • 31
  • 104
  • 137
  • 2
    This answer worked for me where the others didn't. `git checkout -b new-branch` worked for me. The other suggestions called for `git branch new-branch`, but that left me still in detatched head and the new branch didn't pick up my changes. – Jesse Patel May 03 '18 at 20:59
  • 1
    @JessePatel That's because you only create a branch with "git branch new-branch" you have to move HEAD (the current place you're looking at/working in) to that branch by doing "git checkout new-branch". The "-b" flag in "git checkout -b new-branch", means you create a branch before you move HEAD to that branch. Like 2 commands in one. – Postermaestro Jan 25 '22 at 08:30
24

You can just do git merge <commit-number> or git cherry-pick <commit> <commit> ...

As suggested by Ryan Stewart you may also create a branch from the current HEAD:

git branch brand-name

Or just a tag:

git tag tag-name
Arnaud Le Blanc
  • 98,321
  • 23
  • 206
  • 194
17

Alternatively, you could cherry-pick the commit-id onto your branch.

<commit-id> made in detached head state

git checkout master

git cherry-pick <commit-id>

No temporary branches, no merging.

Nate Wilson
  • 170
  • 1
  • 4
12

I see everyone almost everyone has suggested a solution where a temporary branch is being created. Now, one needs to admit that whenever this "committed in a detached state" issue arises, it's generally detected after one commit. And creating one whole branch for that one puny commit - Sounds too much, right? Especially in projects where you are already jumping around among too many branches.

What's the easy way then? Use the commit hash!

How do I get that?

  1. Do a git log. You would see something like this:
commit 10bf8fe4d17bb7de59586a7abb6db321f0786bb3 (HEAD)
Author: Someone <someone@something.com>
Date:   So/me/day SO:ME:TI:ME 

    A commit message that doesn't mean much

commit a3cd1cedf1962916cdc2945f2bd2b271ec8b919d (origin/master, master)
Author: Someone <someone@something.com>
Date:   Some/other/day SOME:OTHER:TIME 

    Another commit message that doesn't mean much

commit 1bfabbe09c70419070fe29ff1ed276c0207bbe10
Author: Someone <someone@something.com>
Date:   Thu Jul 8 08:38:12 2021 +0530

    Enough reading the example, focus on the answer!! 

Now, although it looks like a normal case, but when you do a git push it would say "Everything up-to-date".

A careful person would see that it's not "up-to-date". HEAD is somewhere other than the master.

  1. So, what next? Just copy the initial chars of the hash 10bf8fe4d1. And first, do a git checkout master. This would move you to master branch. And now since you have already copied the hash. You can do a git merge <hash>. Do a git log now

And VOILA:

commit 10bf8fe4d17bb7de59586a7abb6db321f0786bb3 (HEAD -> master)
Author: Someone <someone@something.com>
Date:   S/om/eday SO:ME:TI:ME 

    A commit message that doesn't mean much

commit a3cd1cedf1962916cdc2945f2bd2b271ec8b919d (origin/master)
Author: Someone <someone@something.com>
Date:   Some/other/day SOME:OTHER:TIME 

    Another commit message that doesn't mean much

commit 1bfabbe09c70419070fe29ff1ed276c0207bbe10
Author: Someone <someone@something.com>
Date:   Thu Jul 8 08:38:12 2021 +0530

    Enough reading the example, focus on the answer!! 

Now, the HEAD seems to be in a proper place.

Someone might ask, "What if I don't have the hash? I didn't know anything about the dangling commit and just did a git checkout master." Don't worry, I've got you covered. You can find the commit hash in two places:

  1. When you did the git checkout master, git had warned you like this
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  10bf8fe A commit message that doesn't mean much

If you want to keep it by creating a new branch, this may be a good time
to do so with:

 git branch <new-branch-name> 10bf8fe

Switched to branch 'master'

You can see your treasure (hash), right?

  1. Don't tell me you can't find it. It's right there. But if you really can't, then you can do a git reflog. It will show you something like this:
a3cd1ce (HEAD -> master, origin/master) HEAD@{0}: checkout: moving from 10bf8fe4d17bb7de59586a7abb6db321f0786bb3 to master
10bf8fe HEAD@{1}: commit:  A commit message that doesn't mean much

You see that there's the treasure you were looking for... The hash.

I guess this covers all possible scenarios that could happen in a detached state with a dangling commit. Beware next time!!

paradocslover
  • 2,932
  • 3
  • 18
  • 44
7

In case of 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
Razan Paul
  • 13,618
  • 3
  • 69
  • 61
3

An easy fix is to just create a new branch for that commit and checkout to it: git checkout -b <branch-name> <commit-hash>.

In this way, all the changes you made will be saved in that branch. In case you need to clean up your master branch from leftover commits be sure to run git reset --hard master.

With this, you will be rewriting your branches so be sure not to disturb anyone with these changes. Be sure to take a look at this article for a better illustration of detached HEAD state.

Nesha Zoric
  • 6,218
  • 42
  • 34
3

checkout actual-branch

git merge {{commit-hash}}

3

i will give a proper step until push if you in that condition (the commit being detached). the detached mean is when your commit is not is not associated with any branches, it is only associated with the "detached head" state.

First u must to make a new branch, the detached commit will be automatically associated with the new branch

git branch temporaryWork

And go to checkout to master so u can merge that "temporaryWork". Please consider to check it the list of branch name, to avoiding some error

git checkout master
git merge temporaryWork

And git will said your file may be conflicted, go to look back your code text editor, and delete the code that you not need.

And commit that change

git add .
git commit -am "merging temporaryWork" 

then delete the "temporaryWork"

get branch -d temporaryWork

and push it into github.

git push origin master
1

Maybe not the best solution, (will rewrite history) but you could also do git reset --hard <hash of detached head commit>.

rookie
  • 2,783
  • 5
  • 29
  • 43
1

When I did the checkout leading to detached head, git actually tells me what to do in such a case:

git switch -c <new-branch-name>

If you do this, it leaves the HEAD branch as it was before detaching the head. It creates a new branch with all the commits made while working in the detached head state, as if you had done git checkout <new-branch-name> from the HEAD location. Afterwards, HEAD will be the head of the new branch, as you would expect.

To reproduce/test/understand in more details:

  1. creating a testrepo with two commits:
~/gittest$ git log --oneline 
17c34c0 (HEAD -> master) 2
5975930 1
  1. checkout previous commit 1

~/gittest$ git checkout 5975930

In German, the response from git is:

Hinweis: Wechsle zu '5975930'.

Sie befinden sich im Zustand eines 'losgelösten HEAD'. Sie können sich umschauen, experimentelle Änderungen vornehmen und diese committen, und Sie können alle möglichen Commits, die Sie in diesem Zustand machen, ohne Auswirkungen auf irgendeinen Branch verwerfen, indem Sie zu einem anderen Branch wechseln.

Wenn Sie einen neuen Branch erstellen möchten, um Ihre erstellten Commits zu behalten, können Sie das (jetzt oder später) durch Nutzung von 'switch' mit der Option -c tun. Beispiel:

git switch -c \<neuer-Branchname>

Oder um diese Operation rückgängig zu machen: git switch -

Sie können diesen Hinweis ausschalten, indem Sie die Konfigurationsvariable 'advice.detachedHead' auf 'false' setzen.

HEAD ist jetzt bei 5975930 1

In English, the response from git is:

Note: switching to '5975930'.

You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching to a branch.

If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example:

git switch -c <new-branch-name>.

Or to undo this operation with:

git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 5975930 1

Paul Masri-Stone
  • 2,843
  • 3
  • 29
  • 51
Simeon
  • 748
  • 1
  • 9
  • 26