Is there a git command that copies files from the commit history to the working directory without also copying to the staging area? Checkout copies to both. Maybe there isn't a common enough use case for this to warrant a command, I'm asking more as a curiosity than because I have a specific application.
4 Answers
Is there a git command that copies files from the commit history to the working directory without also copying to the staging area?
No—but you can synthesize one. Both git show
and git cat-file -p
can copy a blob object to standard output. Hence, by writing the commit hash once and the path name twice—once to find the blob hash ID, and again to redirect the output of the command—you can get what you want:
git cat-file -p $rev:$path > $path
or:
git show $rev:$path > $path
Repeat for every file in every directory, and you have gotten close enough—with one caveat: these commands, by default, do not apply end of line and output filter conversions (per .gitattributes
and the various autcrlf and EOL modifiers).
If you add --textconv
, you can convince git cat-file
to apply text conversions. This should work for git show
as well but I have not tried it.

- 448,244
- 59
- 642
- 775
Easiest way to do this is to use git reset
and the reflog:
First, apply the filesystem state from the commit (or branch) to your working directory, staging area, and branch.
git reset --hard [commit/branch]
Then reset the staging area and branch to previous state, without modifying the working directory (a '--mixed' reset, which is the default):
git reset HEAD@{1}
The files from that commit are in your working directory and nothing else. Note that if you modify HEAD in between step 1 and step 2 then HEAD@{1}
most likely won't be the correct ref, you can use git reflog
to find it.

- 31
- 2
You can achieve something with git stash --keep-index
which stashes changes leaving the index as is.
This works for you if the commit you want is HEAD. But It has the side effect of stashing the changes
You can define an alias to stash and drop

- 4,052
- 2
- 21
- 29
-
This does not extract files from a commit: it keeps the index as-is, as you mention. So it has the same effect as `git checkout -- .` from the top level, more or less. – torek Aug 07 '17 at 02:30
git checkout HEAD -- files
or
git checkout <commit_id> -- files
copies files from the latest commit to both the stage and the working directory.

- 2,841
- 2
- 20
- 33

- 31
- 3
-
Yes, but it also changes HEAD to `HEAD detached at` state; UNLESS you have specified files - see https://stackoverflow.com/a/51817015/6197439 – sdbbs Mar 13 '23 at 07:20