/ git

Exporting a Git History at a Specific Commit

I had a need today to take an existing git repo that has commits, and move the history as of one of those commits into a different git repo.

So my two requirements were:

  • Show the content as of <sha>
  • No .git repo or any ignored files in the export

It took a few minutes to find the right incantation so I thought I'd blog it here mostly for my future self. Maybe it will help someone else out there.

I should note that there are many ways to accomplish things in git, so if you have a better way I'm all ears.

We start by finding the sha that we want to export:

~/projects/repo $ git log --oneline
f8de9f7 (HEAD -> master) execute shell commands and capture output
d3a8363 Add Files package
5b9242d Initial command line setup

I'm interested in the first commit, 5b9242d.

We can run git archive to get an archive of the repo in a given format. The available formats can be listed:

~/projects/repo $ git archive -l

I don't need any compression, so tar will do, and this happens to be the default. If you want to specify a format you can do so with --format.

So we start by exporting into a tar file, whose filename is specified with the -o option:

~/projects/repo $ git archive -o git.tar 5b9242d

Now I have the tar file, I can go to the destination folder and untar it:

~/projects/other $ tar xvf ~/projects/repo/git.tar
x .gitignore
x .nova/
x .nova/Tasks/
x .nova/Tasks/Swift Build.json
x Package.resolved
x Package.swift
x Sources/
x Sources/swift-encode/
x Sources/swift-encode/main.swift
x Tests/
x Tests/LinuxMain.swift
x Tests/swift-encodeTests/
x Tests/swift-encodeTests/XCTestManifests.swift
x Tests/swift-encodeTests/swift_encodeTests.swift

If there were files you didn't want included in the destination folder, like the .nova folder for instance, you can specify that in the untar step:

~/projects/other $ tar xvf ~/projects/repo/git.tar --exclude .nova

And if we want to combine these commands into one we can avoid the intermediary tar file:

~/projects/repo $ git archive 5b9242d | tar x --exclude .nova --directory ~/projects/other

I'm sure I'll need to look this up again, but handy to know!