Ideally, you could refer the whole world — or at least, the significant portion thereof that want your code — to your (public mirror) Git repository. But unfortunately, the whole world does not (yet) use Git (“I know it was you Fredo, I know it was you, and it breaks my heart.“). Sad. Sooooo sad. But true. So the only recourse is for you to send these tortured souls an archived snapshot of your code via e-mail. I’ll pause now to let you finish retching/sobbing/lamenting/venting. …
Back?
Anyway, Git has a neat “archive
” command that helps you create the required archive, but perhaps it does not have the most friendliest interface in the world. I’ve written some scripts to wrap the Git command to facilitate its use, which I share here.
Update 2011-07-07: I have re-written the original three scripts
previously described here as a single script, incorporating some of the
excellent suggestions that kind folks provided in the comments.
Immediately below this is the new, unified,
all-bells-and-whistles-included script. Simply name it something like
“git-makedist”, switch on its executable bit, and place it somewhere
on your system path. Reasonable names, filepaths, prefixes, etc. are all
provided if you do not explicitly specify them. All of which means that,
in most cases, once installed, simply invoking the command
“git makedist
” without any options or arguments from within a Git
repository “just works ™”, resulting in a sensibly-named compressed
archive of the current HEAD ready for distribution. At the same time,
various flags and options allow you to fine-tune the operations, e.g.
determine the compression/archive method, the path prefixes, the archive
name, etc.
Update 2011-07-22, Excluding Files: Sometimes, not all files need to
make it out to an archive. You can use the “.gitattributes
” file to
control which files get archived. Simply add the paths/names/globs of
the files or directories you would like to exclude, and add a
“export-ignore
” after it. For example:
.gitattributes export-ignore
.gitignore export-ignore
*.tmp export-ignore
Note that the “.gitattributes
” file has to be committed for it to
have an effect.
#! /bin/bash
compose_name()
function usage
NOPREFIX=0
while [ -n $1 ]; do
case $1 in
-f|--format)
FORMAT=$2
shift 2
;;
-r|--revision)
REVISION=$2
shift 2
;;
--no-prefix)
NOPREFIX=1
shift
;;
-p|--prefix)
PREFIX=$2
shift 2
;;
-n|--name)
REPONAME=$2
shift 2
;;
-o|--output)
OUTPUTDIR=$2
shift 2
;;
-h|--help)
usage
;;
*)
break
;;
esac
done
if [[ -z $FORMAT ]]
then
FORMAT="targz"
fi
if [[ -z "$REVISION" ]]
then
REVISION="HEAD"
fi
if [[ -z $REPONAME ]]
then
REPONAME=$(compose_name)
if [[ -z $REPONAME ]]
then
echo "FATAL: not a Git repository, or could not parse repository name (supply using '-p'/'--prefix' flag)"
exit 1
fi
fi
if [[ -z "$OUTPUTDIR" ]]
then
OUTPUTDIR="."
fi
if [[ $FORMAT == "zip" ]]
then
GITARCHIVEFORMAT="zip"
EXT=".zip"
else
GITARCHIVEFORMAT="tar"
if [[ $FORMAT == "tarbz" ]]
then
EXT=".tar.bz2"
COMPRESS="bzip2"
elif [[ $FORMAT == "targz" ]]
then
EXT=".tar.gz"
COMPRESS="gzip"
else
echo "FATAL: Unrecognized format '$FORMAT'"
exit 1
fi
fi
if [[ $NOPREFIX == 1 ]]
then
PREFIXCOMMAND=""
elif [[ -z "$PREFIX" ]]
then
PREFIXCOMMAND="--prefix=$REPONAME/"
else
PREFIXCOMMAND="--prefix=$PREFIX/"
fi
ARCHIVEBASENAME="$REPONAME-$(git describe --always)"
OUTPUTPATH="$OUTPUTDIR/$ARCHIVEBASENAME$EXT"
if [[ $FORMAT == "zip" ]]
then
git archive --format="$GITARCHIVEFORMAT" $PREFIXCOMMAND $REVISION > $OUTPUTPATH
else
git archive --format="$GITARCHIVEFORMAT" $PREFIXCOMMAND $REVISION | $COMPRESS >$OUTPUTPATH
fi