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?
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.
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'
co = "!git stash push -m \"co backup\"; git stash apply; git checkout \"$*\""
Note, I added a message to tell backup stashes from others.
$*
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.
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.
Using VS Code it was smooth sailing getting the local changes from disk back, via CTRL+Z. So try using the IDE.
If you use IntelliJ Idea you can click a right button mouse on a selected project folder -> Lokal History -> you can see all the files.
if you use Eclipse as IDE and EGit, you have onto your file the Team-menu:
right click on your file from within 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.
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.
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.
I'm using Intellij. CTRL + z works for me, it will prompt you "reload changes from disk", then hit Yes.
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.
https://i.stack.imgur.com/nnH7y.jpg
3-Revert any change you want .
I hope it helps Sorry for any mistakes, English is not my native language.
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.
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
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.
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.
Success story sharing
Team->Show Local History
.