ChatGPT解决这个技术问题 Extra ChatGPT

Get back the changes after accidental checkout?

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?


j
joeljpa

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.


You can also do this in Eclipse by right clicking on the file and going to Team->Show Local History.
You just saved my life! To do this in JetBrains go to the VCS menu > Local Histroy
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!
Using Sublime Text 3, ctrl+z in the files I'd lost was enough to recover them.
Just Cmd+Z and "Reload Undo from Disk" saved me in IntelliJ Idea
V
VonC

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'


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?
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 Thank you. I have included your comment in the answer for more visibility.
@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 Thank you. I have edited the answer accordingly.
G
Greg Hewgill

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.


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.
So you want git to automatically version control files and changes without you needing to tell it to?
as of the latest git version, all checkout are recorded in reflog
s
swedishtea

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


Feeling like tony stark after using infinity stones to bring back my code, almost lost a day of work, cheers!
П
Писаренко Алексей

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.


The question has no mention of IntelliJ Idea, so this is unlikely to be a helpful answer.
it was useful for me :)
You save me. Thank you very much. That was a great idea. I lost my files and could not remember the path of the files to revert them by local history, but this advice has helped me to remember the structure and names.
J
Jonathan

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.


a
alexei

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.


D
Deep

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.


O
Oscar Zhang

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


Basically undoing your things will get you back in your ide. One just has to hope it was a small commit.
B
Behnam Tajadini

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.


S
ShankarDaruga

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.


B
BIS Tech

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


R
Reinhard

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.


S
Sushil88

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.