views:

231

answers:

1

This probably very simple, but I can't seem to find clear instructions (and I'm new to Linux/Git); Is there a simple way to export / archive only the changed files from a given commit or series of commits in git?

I am using msysgit, and for the most part I'm fine with deploying entire repositories but in many cases it's much more efficient to deploy small fixes a few files at a time.

Pushing/Pulling/Installing git on the remote servers isn't really an option as my level of access varies between projects and clients.

Is there a straight-forward way to (rough guess) pipe 'diff --names-only' to 'git-archive'?

Cheers in advance!

+3  A: 

I don't think there's any need to involve git-archive. Using --name-only, you could tar up the files:

tar czf new-files.tar.gz `git diff --name-only [diff options]`

Since you're new to Linux, this might need some explanation:

The backticks in the command line cause the shell to first execute the command within the backticks, then substitute the output of that command into the command line of tar. So the git diff is run first, which generates a list of filenames, one on each line. The newlines are collapsed to spaces and the whole list of files is placed on the tar command line. Then tar is run to create the given archive. Note that this can generate quite long command lines, so if you have a very large number of changed files you may need a different technique.

Greg Hewgill
Just for posterities sake, that different technique would be something like: `git diff --name-only [diff options] | xargs tar -czf files.tar.gz`
jason
With `xargs`, you have a different problem because `xargs` will run `tar` more than once if there are too many files to put them all on a single command line. This will cause `tar` to create a new .tar file overwriting the previous one, so it will only contain the files for the last batch.
Greg Hewgill
Thanks for explaining the syntax! The backticks are what I needed :) This works perfectly in bash commandline that comes with msysgit except where there are spaces in filenames (windows...). Is there a way to escape them automatically?
AKS
Greg, that can easily be fixed by using `-rvf` instead of `-cvf` as arguments to `tar`.
jason
@jason: Good idea. You'd have to add a second step to compress the archive later, because -r only works on uncompressed archives.
Greg Hewgill
Right, hence why I left the compressing off there. I'm not sure why, but adding `v` is so deeply ingraned in my muscle memory when taring/untaring things.
jason
Using zip you can archive and compress in one go: `git diff -–name-only commit1 commit2 | zip changes.zip –@`. If you use UnxTools or cygwin this will work on windows too.
Marnix van Valen
How would you make a diff ignoring files which only has modified permissions?
Cesar