5

Intro and search

So I think I have made a grave mistake and I am concerned. I have parsed the forums for detached heads and I have come close to finding an answer, but the scenarios are too specific and not applicable to where I am at. If you find a specific thread that answers my question, please do link me.

For example: How can I reconcile detached HEAD with master/origin?

The guy has already done git rebase -i, which I have not. I've tried rebasing, but it didn't solve my issue.

Little background:

  • I am new to git; I use git only by myself
  • I own the remote repository
  • Needed old set of code, and it was time-sensitive issue
  • I picked up a little programming and am using it at workplace where no one else codes (so I can't quite ask for help)

Issue:

To access the old commit with working code, I did (probably the wrong thing):

git log
git checkout <hash-of-desired-old-commit>

I proceeded to finish the code. Thank goodness for version control! But shoot, why is git so complicated? How do I save this work? I am now in a detached head. Origin/Master is in some future commits that preferably should all be deleted.

What I have tried:

  • copied and pasted the entire folder elsewhere just for back-up
  • git add -A followed with git commit -m "oh shit, detached head commit" and git rebase master
  • git reset --hard HEAD~3 per recommendation here: Checkout old commit and make it a new commit

Question: How do I reconcile my detached head with origin/master? Once reconciled, do I need to git push --force or something (specifically with the --force flag)? There is work at this detached head, and I've read that the longer I wait, garbage collection may come and eat my lost branch. Sorry, I do lack any formal training in git... I am almost ready to just check out origin master and then rewrite the code.

Thank you in advance.

2
  • Have you tried a graphical UI like SourceTree, Tortoise or GitHub Desktop? Although they don't have all the power of the command line, sometimes they may shed some light on the situation.
    – GolezTrol
    Commented Feb 14, 2018 at 22:38
  • I have Golez! I know exactly where my HEAD is at (pointing to the old commit where I checked out). I just don't know how to update my tree to reflect the current detached HEAD as my desired origin/master.
    – Jennings
    Commented Feb 14, 2018 at 22:41

1 Answer 1

4

If you are on a detached HEAD and you want to save whatever state that HEAD is currently in, just create a branch:

git branch save-this-head

Now, you have a branch pointing to that exact detached HEAD, so you can check that out safely without losing stuff:

git checkout save-this-head

And now, you are no longer in a detached HEAD state. You and your changes are safe! If you have any pending changes, you should commit those now, so we can move around freely.

Afterwards, you can just rebase this new branch onto something else, e.g. the master branch:

git rebase master

That should replay the commits that are missing on master on top of it. So changes made since the detached HEAD will be recovered.

If you instead just want to stay on that save-this-head state, and throw away the previous master, you can just checkout master and then reset it to the saves state:

git checkout master
git reset --hard save-this-head

This will make master equivalent to save-this-head, throwing away all other changes on master. If you want to push this, you will likely have to force push then in order to remove the commits from the remote.


I've read that the longer I wait, garbage collection may come and eat my lost branch

First of all, as long as you stay in that state, the HEAD will pointer will keep looking at that commit object (which is why it’s called “detached HEAD” in the first place). This will prevent any garbage collection from removing that commit object (and all its parents).

Even if you accidentally left the detached HEAD state, making the commit you were referring a “dangling” commit, Git will keep the objects around for multiple weeks before even considering to allow the object being garbage collected. And just because it is subject to garbage collection that does not mean that the GC will actually run, especially when you otherwise don’t interact with the repository.


Btw. in the future, whenever you want to go back to a commit in your history and expect to do something (other than just looking), you should just create a branch. Even if it’s just a temporary one, having it will allow you to move around more freely and you won’t be discouraged from doing anything by that detached HEAD state:

git checkout -b fix-something <some-old-hash>
4
  • POKE. Thank you!! You answered my question and more. That additional code you provided is exactly what I intended to do, but I did not have the time to figure it out. Your answer is very clear. Thank you, thank you.
    – Jennings
    Commented Feb 14, 2018 at 22:52
  • 1
    @Jennings I’m glad I could help you! :) – Please remember to accept the answer if this answers the question to mark it as resolved.
    – poke
    Commented Feb 14, 2018 at 23:03
  • I see a similar answer in the other thread now, which was praised for it's brevity. Didn't want to try it since there plenty comments warning about losing work. Thank you for the thorough explanation.
    – Jennings
    Commented Feb 14, 2018 at 23:09
  • 3
    An important thing to remember is that it’s actually pretty difficult to lose work with Git. Once you have committed something, you are pretty safe, so you don’t need to be scared about it. It’s just sometimes more complicated to recover than other times. But by creating branches, you can very easily create backup pointers for you to recover easily later one in case you need it :)
    – poke
    Commented Feb 14, 2018 at 23:15

Not the answer you're looking for? Browse other questions tagged or ask your own question.