Create git archive from repo without a commit

1.1k Views Asked by At

There is the git archive command - is there a way to create a tarball from a repo without making a commit? Essentially I just want to create tarball of the existing files (more importantly honoring gitignore). I assume git archive is looking for a commit - but I just want a snapshot of the code even for uncommitted changes.

Another way to do this would just be to write a program that will tar all the files and ignore what's in gitignore, but that would require writing that program.

3

There are 3 best solutions below

0
bk2204 On

git archive requires a treeish to use, which means you need a tree, commit, or tag. There's nothing preventing you from creating a temporary branch and a commit with the contents you want and archiving that.

Alternatively, if you're certain you don't care about the ignored files, you can run git clean -dffx and then use tar --exclude-vcs to package your archive. You could also skip the git clean invocation and try tar --exclude-vcs --exclude-vcs-ignores.

4
torek On

The simple and easy and obviously correct way to do it is: just make a commit (as bk2204 suggests).

But, since git archive takes a <tree-ish>, you can do this without making a commit. Just make the tree part of a commit, which is half (or more) of an actual commit, and then use that:

git archive [additional options] $(git write-tree)

The issue here is that git write-tree will write whatever is in the index right now. This means you need to add all updated files to the index, even if you're not going to make a commit. You could do that with a temporary index, if you want to get extra fancy, but it's easier to just add -u first:

git add -u
git archive [additional options] $(git write-tree)

Another way to get the work-tree files into a commit, without making a commit yourself, is to use git stash to do the job. This will write the current work-tree to a new commit. Hence:

git stash push
git archive [additional options] refs/stash
git stash pop --index

would do the job, more or less. The less occurs when there is nothing to stash, in which case git stash push does nothing and you should not run git stash pop. In this particular case, you can archive HEAD—but it's annoying to detect whether git stash push did anything. You can add more layers of scripting to deal with that, but really, what's wrong with just committing now?

0
VonC On

In addition of making a commit, consider git bundle: it is like git archive... but with history.

You get one file (a bundle file), that you can copy around, and then clone back from.
See "Fully backup a git repo?" for more.