0

I made some changes to file a.py and created two new files b.py and c.py and then committed the changes, but got a warning:

The Git repository at the following path is in the detached HEAD state

I ignored it and committed the changes anyway. Let's refer to this commit as commit X.

Then I did a checkout and boom, the a.py and b.py files disappeared and so did the changes I made to a.py. Now commit X doesn't show in the list of commits.

I only had a master branch, so this is not because I am in a different branch.

I don't understand Git and I am using the graphical interface of PyCharm. How can I get back the files?

multigoodverse
  • 7,638
  • 19
  • 64
  • 106
  • 1
    https://stackoverflow.com/questions/5772192/how-can-i-reconcile-detached-head-with-master-origin – rustyMagnet Apr 20 '20 at 17:36
  • Does this answer your question? [How can I reconcile detached HEAD with master/origin?](https://stackoverflow.com/questions/5772192/how-can-i-reconcile-detached-head-with-master-origin) – phd Apr 20 '20 at 19:15

2 Answers2

2

You were in a detached HEAD state, meaning you had a state similar to this, where HEAD wasn't pointing at any reference:

A <--master
|
B <--HEAD
|
C

Then you added some files and committed them, something like this:

touch new_file.txt

git add new_file.txt

git commit -m "your detached HEAD commit"

At that point, this was what your tree looked like:

master --> A  
           |  D <--HEAD
           |  |
           B / 
           |
           C

Since D was not pointing to a branch or other reference (you were "detached"), when you checked out master again, git had no way to reference D and so it was "lost":

A <--master (HEAD)
|
B 
|
C

To find D, use git reflog and look for something like this:

0abce (HEAD -> master) HEAD@{0}: checkout: moving from b214e to master
b214e HEAD@{1}: commit: your detached HEAD commit

be14e is the name of the commit you're looking for, so git checkout be14e to get this again (you could also git checkout the files directly into master, but that's a different lesson):

master --> A  
           |  D <--HEAD
           |  |
           B / 
           |
           C

Now you can view your lost files. You should probably create a branch at this point so your files no longer get lost when you switch branches. So do git checkout -b new_branch to get this:

master --> A  
           |  D <--new_branch (HEAD)
           |  |
           B / 
           |
           C
symlink
  • 11,984
  • 7
  • 29
  • 50
  • 1
    That got my files back! Thank you so much for the solution and for the lesson! I don't want this to happen again. Is there something I should have done when I realized I was in a detached head and while I still had the current files in my local project? Should I have attached the head somehow? – multigoodverse Apr 21 '20 at 09:33
  • @multigoodverse Yes, you want to "reattach" HEAD when that happens. You can do this with git checkout -b new_branch to create a new branch where your detached HEAD is. If you are in detached HEAD state but you haven't committed anything yet, like in the first diagram where HEAD is on B and the master branch tip is on A, you can just use git checkout master to move HEAD to master. Then your next commits will be tracked by master. The underlying principle is that you want a branch to be pointing at HEAD (another way of saying, you want HEAD to be "attached"). – symlink Apr 21 '20 at 14:15
0

Usually you checkout the branch name you want to work on, for example:

git checkout master
git checkout develop

But you can also checkout a specific commit by using its SHA1 hash:

git checkout 54e8cd9354

When do that, you are in a detached state, which basically means that your next commit won't be added at the end of an existing branch

You can check your last commit this way:

git log -1
HermitCrab
  • 3,194
  • 1
  • 11
  • 10