I staged a grand number of files for commit.
Then I realized it was better to commit only two of the files, and then commit the remaining ones in a separate commit.
git reset <filename>
unstages filename
I wanted to unstage everything,
then restage two files, and commit.
Then stage all remainging files and commit again.
As: "git add .
" (adds all files to staging area)
and "git reset <filename>
" (removes filename from staging area)
"git reset .
" (seemed to make sense to unstage all files)
oops..!
That reverted my working directory to the last committed version,
- I lost ALL File Edits that I had made! :-(
Anyway to "undo" "git reset .
" ??
I've not found any documentation on this.
In fact I do not find any documentation on "git reset .
" at all.
My best guess is that git took the ".
" to be the value for an option, other than the filename option.
But is this undoable ?
Yes!, It turns out, You Can !!
Here is why: git interprets git reset .
as git reset --hard
So that deleted all changes in my working directory, reverting everything to the state of my last commit.
There is no built in way to recover the file edits I had lost.
However, git add .
saved a copy of each file that had those edits in them.
We, just need to get a handle on where/how git
saved the state of said files.
In short, do perform the following steps:
(1):
git fsck --cache --unreachable $(git for-each-ref --format="%(objectname)") \
$(egrep commit all | cut -d ' ' -f 3) > stagedNotCommitted
This will find and put a list of files that git has indexed (because they had been staged),
but that have never been committed, into a file named
stagedNotCommitted
Since git does not know the file names for these files, stagedNotCommitted
will be a listing of the indexed files' hashes.
looking something like
`369c722e8df1c83b6ebfc0dc2d426aa612535203
63282280da679aa19d6a2a71e08bed8487f7e688
6a540aa36ee558611528176dbf87ad8e39475222
9c8ce87dd8aff2abc78d8a5dbe976473c6fea3de
9e20a6530229dac42cb87dc0a7153edb4bad96b5
abec86bc81f8b473e5ea8f0320589619d5e726b2
b830a382cd30308782a1df12e553227100b47ba4
c8bc4788fee301c8c88ed29739927689742c55bf
f87c9f32da264e5e0b9de3d1818e291a687adab9`
...
(2):
From here you can open each file in your text editor (I used Sublime),
and save the ones you wish to recover under the correct name.
The way I went about this was by saving each "unreachable blog" into a temp file as such:
(you can use just the first few digits for each file)
$ git show 89f45 > _02_89f45
$ git show 07f9c > _03_07f9c
$ git show 23ad5 > _04_23ad5
...
From there opening all these files in sublime was easy.
Just re-save with the appropriate name.
Done !! :-)
Note, this only works because I had already Staged All the Files I wanted to recover.
Had I not Staged (all) them, I'd outta luck. (or could only recover some of them.)
For more information please visit the following links I found useful on StackOverflow:
This one is Particularly Useful, with a great explanation!
Undo git reset --hard with uncommitted files in the staging area
Others:
Good, well explained info:
How can I undo git reset --hard HEAD~1?
This one also has a post linking a plugin that claims to do it for you:
Recovering added file after doing git reset --hard HEAD^
Finally, here is an interesting table:
https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting/summary
Command Scope Common use cases
git reset Commit-level Discard commits in a private branch or throw away uncommited changes
git reset File-level Unstage a file
git checkout Commit-level Switch between branches or inspect old snapshots
git checkout File-level Discard changes in the working directory
git revert Commit-level Undo commits in a public branch
git revert File-level (N/A)