The solution is simple:
git checkout <treeish> -- /path/to/dir
That will bring back the directory from the given “treeish” for the
/path/to/dir. Let’s go through an example of this:
First off, let’s remove a directory and then merge in a ton of changes (for future reference, this is going off a refactoring branch of Jekyll, the static blog engine that generates this site).
Here’s how the history looks:
Hopefully this isn’t too confusing. Basically the commit we just made is pretty far down in history, which most likely will be the case you’re in if you need to restore a directory. First off, we need to get the reference to the commit that has the directory you want to pull. In this case, we know the last commit was the merge and the commit before that we deleted the directory. So, the commit we want to reference is the third commit in history, or
HEAD~2. You could also reference this by the branch name (
test~2) or even go one back from the SHA of the deletion (
In any case, if you try to checkout a directory from a revision where it doesn’t exist, you’ll get this nice message:
$ git checkout test~1 -- bin/ error: pathspec 'bin' did not match any file(s) known to git.
So, let’s check out the correct revision and finally get our directory back where it belongs:
Great, now we’re back in business. From here you can add or commit the file as needed.
If you’re in this situation you might want to consider reverting the commit, which could restore the files that were deleted as well. However, this isn’t always possible and may not be the best way to pull the directory you’re missing back out of history.