Get back the changes after accidental checkout?

Solution 1:

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!

Solution 2:

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'

Solution 3:

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.

Solution 4:

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