Let's say I have files A
, B
, C
, D
in my repo. All of them has been modified from the last commit, but not staged yet. Due to a syncing bug, A
and B
are deleted. I understand that changes in them are gone, but at least I want to recover them from the last commit. Is there a way to git reset --hard
only deleted files while keeping existing files intact? Assuming there are many of them, so I can't git checkout
individual files or folders.
Instead of a git reset --hard
, a git ls-files -d
might help (coupled with git restore
, if you are using Git 2.23+):
git ls-files --deleted | xargs -I {} git restore --source=HEAD -- {}
# For older Git, pre 2.23, before Q3 2019:
git ls-files --deleted | xargs -I {} git checkout HEAD -- {}
it seems that
git ls-files
only reads files from the working tree and stage?
What about a specific commit?
For listing deleted files from a given commit, you would use git log
with a diff-filter
, and an empty format:
git log --diff-filter=D --first-parent --pretty=format: --name-only -1 <commit>
In your case, to restore those files from that commit:
git log --diff-filter=D --first-parent --pretty=format: --name-only -1 <commit> | \
xargs -I {} git restore --source=<commit> -- {}
Or, as LeGEC mentions in the comments, using the same diff-filter
with git diff
:
git diff --diff-filter=D --name-only <commit>~ <commit> | \
xargs -I {} git restore --source=<commit> -- {}
if I need to list all the files having been deleted in the last 5 commits, what should I do?
git diff --diff-filter=D --name-only @~5