81

The following was the status of my repo.

[~/rails_apps/jekyll_apps/nepalonrails (design)⚡] ➔ gst
# On branch design
# Changed but not updated:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   _layouts/default.html
#   deleted:    _site/blog/2010/04/07/welcome-to-niraj-blog/index.html
#   deleted:    _site/blog/2010/04/08/the-code-syntax-highlight/index.html
#   deleted:    _site/blog/2010/05/01/showing-demo-to-kalyan/index.html
#   deleted:    _site/config.ru
#   deleted:    _site/index.html
#   deleted:    _site/static/css/style.css
#   deleted:    _site/static/css/syntax.css
#   modified:   static/css/style.css
#
no changes added to commit (use "git add" and/or "git commit -a")

Accedently, I did git checkout -f and now the changes are gone which I wasnt supposed to do.

[~/rails_apps/jekyll_apps/nepalonrails (design)⚡] ➔ git co -f
[~/rails_apps/jekyll_apps/nepalonrails (design)] ➔ gst
# On branch design
nothing to commit (working directory clean)
[~/rails_apps/jekyll_apps/nepalonrails (design)] ➔ 

Can I get back the changes back?

millisami
  • 9,931
  • 15
  • 70
  • 112

15 Answers15

91

Another thing you can look at is through your IDE. I accidentally checkout 2 files and was able to bring back the changes through the 'local history' of my IDE (Netbeans). What a blessing!

If you're using Eclipse, do this by right clicking on the file and going to Team->Show Local History.

joeljpa
  • 317
  • 2
  • 13
gigi2
  • 1,996
  • 1
  • 17
  • 22
  • 4
    You can also do this in Eclipse by right clicking on the file and going to `Team->Show Local History`. – donturner Nov 05 '13 at 22:17
  • 17
    You just saved my life! To do this in JetBrains go to the VCS menu > Local Histroy – Michael Bates Nov 12 '13 at 05:59
  • It happened to me too, Eclipse refreshed the content of the text automatically; but hitting ctrl+Z a few times brought back my modifications, thankfully! – Arnaud A Sep 10 '14 at 15:23
  • it is also good if u add other IDE's that support this... e.g IntelliJ IDEA and alike support local history – Amanuel Nega Feb 08 '15 at 08:42
  • phpstorm local history is a life saver - I thought my local history was broken as the loading spinner was displaying for ages but luckily it just involved waiting a few minutes. – Carlton Feb 16 '15 at 17:59
  • 4
    Using Sublime Text 3, ctrl+z in the files I'd lost was enough to recover them. – Madbreaks Aug 17 '15 at 17:45
  • Using Visual Studio Code, ctrl + z was enough to bring back file I accidently checked out. – Mike Kellogg Jun 14 '18 at 18:11
  • gigi2 & @MichaelBates Thank you soooo much. :') I can't stop my tears of happiness. I wrote some 31 test cases yesterday which I checked out by mistake. Just got those back.! – A_G Nov 15 '18 at 18:03
  • Thank you. In Android Studio, local history saved my time. in Android Studio , VCS -> Local History -> Show History. – Deep Aug 09 '19 at 06:04
  • This just helped so much! – claus Apr 02 '20 at 13:49
  • 2
    Just Cmd+Z and "Reload Undo from Disk" saved me in IntelliJ Idea – Sergey Shcherbakov May 20 '20 at 18:33
  • You saved my day. I'm using IntelliJ, it has all the local changed versions I can revert to. The lesson is `git checkout .` is extremely dangerous command without warning which is the same as `rm -rf .` – Jianwu Chen Aug 15 '20 at 01:40
62

I don't think you can recover those private data ("private" as in "not added in the index, nor committed", so unknown to git), unless you have other backup process in place for your current working directory.

Even if this is not proposed in the Git Aliases page, I would argue for some kind alias for checkout (like there is the alias rm /bin/rm -i usage):

[alias]
co = !sh -c 'git stash; git stash apply; git checkout "$@"'

, with the 'git stash; git stash apply' being the "checkpoint technique" used by Brian Campbell in his answer.

stason proposes in the comments:

co = "!git stash push -m \"co backup\"; git stash apply; git checkout \"$@\"" 

Note, I added a message to tell backup stashes from others. –

This issue reminds me of a debate on this behavior on ycombinator (extracts):


I've lost plenty of data with git.
Most of it has to do with innocuous-sounding commands that don't ask for confirmation when deleting data.
For example, git checkout filename is equivalent to svn revert filename.
Of course git checkout branchname does something completely different.
If a branch and a file share the same name, git will default to switching branches, but that doesn't stop bash autocomplete from ruining the day.

Here's a crazy idea: If you have an innocuous action and a dangerous action, do not label them with the same command.


Annoying, maybe, but this is user error, not design error. With git, if I want to losslessly discard my working copy, I can just "git stash".
By your logic, "rm" is flawed because it doesn't ask for confirmation when you pass -f instead of -i. Well, yeah. Sorry.


Your analogy would be more accurate if rm somename was the equivalent of apt-get update, and rm othername was rm -fr othername.
Still, it can't be right that "get checkout foo" does one of two COMPLETELY different things depending on whether or not there is a file called foo in the current directory


Here's another crazy idea: don't run 'git checkout ...' on a dirty work tree. Problem solved.
Another one: don't reuse filenames as branch-names.
To be honest: I have the same problem with careless invocations of 'rm' ruining my day but when I'm muttering curses it is at my lazyness/stupidity and not at bash completions or the behavior of 'rm'

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • On git 1.7.9.5 for me, the above alias errors out with 'unexpected EOF'. Tried replacing ';' with '&&'. Tried "$@" instead of "$*": strace says the arguments are not passed to execve. Tried a "f() {...}; f". No success. Does the above work for everybody else? – alexei Oct 08 '14 at 20:15
  • @alexei I didn't use that in ages. I'll have to update it in light of http://blogs.atlassian.com/2014/10/advanced-git-aliases/ – VonC Oct 08 '14 at 20:24
  • 1
    This alias seems to work: `co = "!git stash push -m \"co backup\"; git stash apply; git checkout \"$*\""` Note, I added a message to tell backup stashes from others. – stason Nov 19 '18 at 04:07
  • 1
    @stason Thank you. I have included your comment in the answer for more visibility. – VonC Nov 19 '18 at 05:32
  • 1
    @VonC, I have a correction: Please replace `$*` with `$@` both in your original solution and in my update. `$*` will not work if you use `git co entry1 entry2` - it will complain `error: pathspec 'entry1 entry2' did not match any file(s) known to git`. It should be instead: `co = "!git stash push -m \"co backup\"; git stash apply; git checkout \"$@\""` Thanks. – stason Dec 06 '18 at 19:42
29

Unless you have ever used git add or git stash with those files previously, then unfortunately no. If you have added or stashed them, then you should be able to find their hashes through git reflog.

I've never been comfortable with this destructive behaviour of git checkout. Perhaps a useful enhancement would be to have this sort of git checkout automatically create a stash (so that files are captured through the reflog) before overwriting your work.

Greg Hewgill
  • 951,095
  • 183
  • 1,149
  • 1,285
  • 4
    I really wish git did this. I find it annoying that I have to bother stashing my work when I switch branches. I'd like to be able to type "git checkout foo; git checkout bar" and, assuming I started on branch bar, end up with my index and working directory in exactly the same state it was before the command, regardless of what I have modified, what I've already added to the index, etc. – divegeek Apr 01 '11 at 19:03
  • So you want git to automatically version control files and changes without you needing to tell it to? – Dennis Estenson Nov 27 '15 at 18:50
  • as of the latest git version, all checkout are recorded in reflog – Raj May 11 '16 at 05:24
  • It makes sense for the state (commited or not) in a local env to be saved, even if branches are switched. @DennisEstenson – M.K Jan 16 '23 at 12:25
16

If you use IntelliJ Idea you can click a right button mouse on a selected project folder -> Local History -> you can see all the files.

Gastón Saillén
  • 12,319
  • 5
  • 67
  • 77
10

Using VS Code it was smooth sailing getting the local changes from disk back, via CTRL+Z. So try using the IDE.

swedishtea
  • 149
  • 1
  • 7
  • 1
    Feeling like tony stark after using infinity stones to bring back my code, almost lost a day of work, cheers! – collo54 Jun 13 '22 at 00:42
5

The following may apply in case you are using vim on Linux.

  • If files are open in an active buffer then you've got the file content as long as you don't reload the file in vim, and can restore by saving it. .

  • If files are not open in an active buffer, but are dirty, then there should be an .swp file in the source directory which also has a copy of the content that is recoverable via vim -r file.swp.

  • If the files are neither open in antive buffer nor dirty, and if your working copy is on an ext3 or ext4 partition, then extundelete might be able to find the recently deleted .swp files and/or an older version of the source files. Remount the partition as read-only, e.g. mount -o remount,ro /mnt/point, and run

    extundelete --recover-directory /path/to/working/copy /dev/sdaX
    

    If the partition that contains the working copy is the root partition, it may refuse to remount, then try killing all services, and if still no go, then shutdown and boot using a Live CD/USB/PXE, like GRML, and run the above. I was successful in recovering one out of three lost files this way.

alexei
  • 2,031
  • 1
  • 26
  • 28
5

if you use Eclipse as IDE and EGit, you have onto your file the Team-menu:

  1. right click on your file from within
  2. List item "Team" -> "Show Local History"

you will see all the version save locally without any saving name, in my case but, you can easily check all the untracked changes out of git features and restore your missing code.

Jonathan
  • 595
  • 5
  • 10
3

If IDE is Android Studio then open the file that has been changed and go to VCS -> Local History -> Show History. Opened file will be shown there.

Deep
  • 303
  • 2
  • 9
3

you can use vscode file timeline just right click file

enter image description here

walkman
  • 1,743
  • 2
  • 10
  • 10
2

I'm using Intellij. CTRL + z works for me, it will prompt you "reload changes from disk", then hit Yes.

ychz
  • 533
  • 2
  • 7
  • 15
2

Just as @VonC mentioned, the ambiguity of git checkout is the root cause here. But creating checkpoints might leave your stash with a huge mess and eventually not usable if not well maintained.

I end up just using git switch instead of git checkout for branch switching. Yes, you need to change your habit, but that's the ultimate solution from my point of view.

Reinhard
  • 100
  • 12
1

1) git reflog

you can see like below output

f7de337 (HEAD -> master, origin/master) HEAD@{0}: checkout: moving from b0b3175f8890950218bba8906ffab0d6f84bf to master

2) git checkout b0b3175f8890950218bba8906ffab0d6f84bf

BIS Tech
  • 17,000
  • 12
  • 99
  • 148
1

If you use android studio the best way to recover your changes (that saved me) is :

1-Right click on your root project directory (your package name) . 2-Local History -> Show History.

enter image description here.

3-Revert any change you want .

I hope it helps Sorry for any mistakes, English is not my native language.

0

If you are using IDE and if it has undo option, simply undo the changes, it'll undo the reload from disk which will bring back your changes. Most IDEs / editors have this option.

ShankarDaruga
  • 164
  • 1
  • 5
-1

There is nothing you can do with git commands but if you are using IDE then you can recover your changes. I am using PhpStorm where we can see file changes history. Simply right-click on file and click on show local history. Under External changes tab, you can find your local changes which you have accidentally removed.

Sushil88
  • 7
  • 2