3

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.

allstar
  • 1,155
  • 4
  • 13
  • 29

4 Answers4

4

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.

torek
  • 448,244
  • 59
  • 642
  • 775
3

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.

1

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

Francesco
  • 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
0
git checkout HEAD -- files

or

git checkout <commit_id> -- files

copies files from the latest commit to both the stage and the working directory.

asm0dey
  • 2,841
  • 2
  • 20
  • 33
  • 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