1

When searching for ways to export a specific commit (specified by its sha) to a directory, I get very many pointers, each with very many answers.

Possibly, that's because such questions are under specified, making multiple answers possible.

Here is what I do not want to do:

  • I don't want to clone my multi-gigabyte repo and then checkout. I'd like to checkout to a directory from the present repo.
  • The sha I'd like to extract is marked by neither a tag nor a branch. In fact, the sha I want is still hazy. Several are candidates.

Indeed simply running git show a1b2c3c:path/to/file/myfile.c (which extracts a specific file from a specific commit) already does what I want, except that:

  • I'd like to extract a full tree (from root), not just one file.
  • git show sends files to the terminal. I'd like to save to /tmp.

My question then is: How do I extract all files in a sha to /tmp?

To provide motivation, let me mention a few use cases for this questions. These are my problem; they're not the question!

  • I gave an improvised demo in the (perhaps distant) past and I'd like to determine the point the project was at.
  • I had omitted to add a given file to the repo, and it sometimes takes quite a while to notice that a file was not added. I'd like to track when the file went missing.
Calaf
  • 10,113
  • 15
  • 57
  • 120
  • 1
    The very first question you linked to shows how to use `git archive` to do that, what's wrong with that? How does that fail to meet your requirements? – Joachim Sauer Aug 13 '20 at 17:28
  • @JoachimSauer Is `git archive sha` an option, and not just `git archive | ` and `git archive master`? Let me confirm whether it's harmless to experiment, and then experiment on my side. – Calaf Aug 13 '20 at 17:32
  • @JoachimSauer Thanks for the hint. It's all simple enough, of course, but since I keep looking in my "git cheatsheet" for exactly this Q&A, I've written (at least for my own reference, if not everyone's) the answer rather than delete the question. I couldn't find a formal confirmation that `git archive` does indeed leave the repo immutable, but from experiments in a fresh/isolated repo, nothing in the `.git` directory is modified, so the answer seems to be yes. – Calaf Aug 13 '20 at 18:25

1 Answers1

0

As Joachim suggested, this answer almost solves the problem.

To add another use case, you may be scratching your head asking yourself: I was testing for specifically this case; how did this test pass at that commit!?.

In such scenarios, it's handy to run:

mkdir /tmp/new_dir
git archive a1b2c3 | tar -x -C /tmp/new_dir

and run the test in complete isolation.

A few points to note in contrast with the almost-does-it answer:

  • If you're not interested in a bzip/gzip/zip archive, but (despite the archive in git archive) rather want a straight-forward directory copy in /tmp, you need to create the root for extraction first.
  • In case you were wondering what exactly <tree-ish> means, you can indeed specify a sha to git archive. In other words, a sha is <tree-ish>.
  • tar is usually fussy about the trailing /, producing different outcomes depending on whether it's present. Luckily, in this case it makes no difference whether a trailing slash is present.

For completeness, the -x makes tar extract, not archive, and the -C is the prefix necessary to specify a directory.

Calaf
  • 10,113
  • 15
  • 57
  • 120