I’m doing development on a WordPress plugin. My development directory contains a lot of development-specific stuff (e.g. Grunt files, Sass files, the git repository itself, etc.).
Obviously, I don’t want to distribute this folder containing all of those development files; people don’t want a few MB of Grunt files when they download my WordPress plugin.
Up until now, though, my “release” process has been cumbersome:
- Commit the Git changes
- Zip the entire folder
- Open the zip file and delete the .git folder, grunt files, and all the other development-specific files
- Release the new zip
I don’t know the best way to accomplish this, but I’m very vaguely familiar with Git hooks, and I had this thought: could I set up a Git hook that would zip ONLY the needed production files into a ZIP file and store it with the repo? That way, every time I commit it would automatically create a new release ZIP.
Is that possible? If so, could someone point me in the right direction?
Oh also, I’m on Windows (ã»_ã»;). So I’m hoping that there’s a way to do it on Windows.
I can’t speak for Windows, but:
A pre-commit hook that modifies “what you will commit” is annoying (if nothing else, it violates the “rule of least astonishment”, where your version control system simply stores the versions you tell it to store). Apart from that, storing large pre-compressed binaries interferes with git’s attempt to save space in pack files, and will cause rapid repository bloat, poor performance, running out of memory, and so on. A ZIP-archive is a pre-compressed binary and hence will behave badly.
In general, a more reasonable “hook-y” way to handle releases is to set up a “release server” to which you push new releases, and have the push trigger the archive-generation. (There are ways to do this without a separate server / repository, and you can do it in a more pull-style fashion, but the push-style is easy to illustrate.)
[Edit: I had originally considered
git archive
but did not realize you could get it to exclude files conveniently, so wrote up the below instead. So, jthill’s answer is better and should be one’s first resort. I’ll leave this in place as an alternative for some case where for some reason,git archive
might not do.]For instance, here’s a server-side
post-receive
hook code fragment that checks whether a branch whose name matchesrelease*
has been pushed-to, and if so, invokes a shell function with the name of the branch (once for each such branch):(much of the above is boilerplate, which I have stripped down to essentials). You would have to write the
do_release
function, which might resemble (totally untested):There’s actually a command for this,
git archive
.See the
EXAMPLES
section, you can select paths, add prefixes to them, define custom postprocessing by output extension, and some more minor tweaks.Also see the
ATTRIBUTES
section: you can give files — arbitrary patterns, really — anexport-ignore
attribute to exclude them from archives.It’s got a bunch more handy-dandies, you can get archives from remote repos, expand arbitrary
git log --pretty=format:
placeholders, the git manpages are definitely worth whatever time you can invest in them.