Browse a git repository at a specific commit

Posted on August 14, 2020

I commonly use tools like git log together with git show when inspecting past changes in a repository:

1
2
3
4
git log
# search for a the commit I'm looking for
git show <my-commit>
# see the diff for the commit

But I also wanted to not only be able to look at the diff of a specific commit, but to browse the whole repository at that specific commit.

I used to accomplish it the “brute force” way: clone the whole repository in another folder and checkout the commit there:

1
2
3
git clone <original-repo> /tmp/tmp-repo-clone
cd /tmp-repo-clone
git checkout <my-commit>

But git itself allows we to specific the directory of the checkout by using the --work-tree global git flag. This is what man git says about it:

--work-tree=<path>
    Set the path to the working tree. It can be an absolute path or a path relative to the current working
    directory. This can also be controlled by setting the GIT_WORK_TREE environment variable and the
    core.worktree configuration variable (see core.worktree in git-config(1) for a more detailed
    discussion).

So it allows us to set the desired path of the working tree. So if we want to copy the contents of the current working tree into copy/:

1
2
mkdir copy
git --work-tree=copy/ checkout .

After that copy/ will contain a replica of the code in HEAD. But to checkout a specific, we need some extra parameters:

1
git --work-tree=<dir> checkout <my-commit> -- .

There’s an extra -- . at the end, which initially looks like we’re sending Morse signals to git, but we’re actually saying to git-checkout which sub directory of <my-commit> we want to look at. Which means we can do something like:

1
git --work-tree=<dir> checkout <my-commit> -- src/

And with that <dir> will only contain what was inside src/ at <commit>.

After any of those checkouts, you have to git reset . to reset your current staging area back to what it was before the checkout.

References

  1. GIT: Checkout to a specific folder (StackOverflow)