From 18fd5c03c806c71286129cb282fb02214bfdb602 Mon Sep 17 00:00:00 2001 From: EuAndreh Date: Fri, 14 Aug 2020 13:02:35 -0300 Subject: Add TIL on git checkout --- ...browse-a-git-repository-at-a-specific-commit.md | 72 ++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 _tils/2020-08-14-browse-a-git-repository-at-a-specific-commit.md diff --git a/_tils/2020-08-14-browse-a-git-repository-at-a-specific-commit.md b/_tils/2020-08-14-browse-a-git-repository-at-a-specific-commit.md new file mode 100644 index 0000000..ad7be6d --- /dev/null +++ b/_tils/2020-08-14-browse-a-git-repository-at-a-specific-commit.md @@ -0,0 +1,72 @@ +--- +title: Browse a git repository at a specific commit +date: 2020-08-13 +layout: til +lang: en +ref: browse-a-git-repository-at-a-specific-commit +--- + +I commonly use tools like `git log` together with `git show` when inspecting +past changes in a repository: + +```shell +git log +# search for a the commit I'm looking for +git show +# 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: + +```shell +git clone /tmp/tmp-repo-clone +cd /tmp-repo-clone +git checkout +``` + +But git itself allows we to specific the directory of the checkout by using the +`--work-tree` global git flag[^src]. This is what `man git` says about it: + +```txt +--work-tree= + 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/`: + +```shell +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: + +```shell +git --work-tree= checkout -- . +``` + +There's an extra `-- .` at the end, which initally looks like we're sending +morse signals to git, but we're actually saying to `git-checkout` which subdir +of `` we want to look at. Which means we can do something like: + +```shell +git --work-tree= checkout -- src/ +``` + +And with that `` will only contain what was inside `src/` at ``. + +After any of those checkouts, you have to `git reset .` to reset your current +staging area back to what it was before the checkout. + +[^src]: I found out about this with [this StackOverflow answer][0]. + +[0]: https://stackoverflow.com/questions/5283262/what-is-git-work-tree-why-have-i-never-needed-to-set-this-env-var-why-now -- cgit v1.2.3