Re: git-archive and submodules
- From
CJ van den Berg <cj@vdbonline.com>
- Date
- Mar 29, 2008, 21:05 UTC
- Message-ID
- <20080329210557.GA4837@prefect.vdbonline.net>
- In-Reply-To
- <20080329135202.GR4759@spearce.org>
On Sat, Mar 29, 2008 at 09:52:02AM -0400, Shawn O. Pearce wrote:
Show 13 quoted lines
> Whit Armstrong <armstrong.whit@gmail.com> wrote: > > Is there a way to ask git-archive to archive the submodules of the > > project as well? > > > > I have a project that needs it's submoduels distributed with it. > > No. > > Patches welcome. :-) > > We've talked about supporting it, and wouldn't mind having the > tool do it for exactly the reason you mention, but thus far a > patch has not been written to implement that.
Here's a script I use at work that calls git-archive recursively for submodules and builds a single tarball for everything. If there is interest in having something like this in git proper I could put some work into cleaning it up for general use. Perhaps something like this should be integrated into git-archive directly. Comments and suggestions are welcome.
--
CJ van den Berg
mailto:cj@vdbonline.com
xmpp:cj@vdbonline.com
#!/bin/bash
set -e
TMP_DIR=$(mktemp -t -d $(basename $0).$USER.XXXXX)
GITMODULES_FILE=${TMP_DIR}/gitmodules
THIS_TAR=${TMP_DIR}/this.tar
SUBMODULE_TAR=${TMP_DIR}/submodule.tar
function cleanup() {
rm -rf $TMP_DIR
}
function die() {
cleanup
exit 1
}
trap die SIGINT
trap die SIGHUP
trap die SIGTERM
trap die SIGQUIT
trap die ERR
trap cleanup EXIT
function usage() {
echo "Build an archive of a repository and all submodules." >&2
echo "" >&2
echo "usage: $(basename $0) [-r n] repo treeish [prefix]" >&2
echo " repo Repository path or URL." >&2
echo " treeish Version to archive." >&2
echo " -r n Maximum recursion level. Default is 1." >&2
echo " -h Show this message." >&2
echo "" >&2
exit 1
}
while [ "${1:0:1}" == "-" ]
do
if [ "$1" == "-h" ] ; then
usage
fi
if [ "$1" == "-r" ] ; then
LEVEL=$2
shift
if [ -z "$LEVEL" ] ; then
usage
fi
if [ ! $LEVEL -lt 0 ] ; then
echo -n "" >&2
else
usage
fi
fi
shift
done
if [ $# -lt 2 -o $# -gt 3 ] ; then
usage
fi
export GIT_DIR=$1
REV="$2"
PREFIX="$3"
if [ -z "$LEVEL" ] ; then
LEVEL=1
fi
if echo $GIT_DIR | grep -q ":"
then
REMOTE_HOST=$(echo $GIT_DIR | cut -d ":" -f 1)
REMOTE_PATH=$(echo $GIT_DIR | cut -d ":" -f 2)
if [ "$REMOTE_HOST" == "$(hostname)" ] ; then
export GIT_DIR=${REMOTE_PATH}
else
exec ssh -n $REMOTE_HOST $(basename $0) -r $LEVEL $REMOTE_PATH $REV $PREFIX
fi
fi
if [ "${GIT_DIR:0:2}" == "~/" ] ; then
export GIT_DIR=/home/${USER}/${GIT_DIR#\~/}
elif [ "${GIT_DIR:0:1}" == "~" ] ; then
export GIT_DIR=/home/${GIT_DIR#\~}
fi
REV_NAME=$(git describe ${REV} 2> /dev/null || true)
if [ -z "$REV_NAME" ] ; then
REV_NAME=$(git rev-parse ${REV})
fi
if [ -z "$PREFIX" ] ; then
PREFIX=$REV_NAME
fi
echo >&2 ${PREFIX} from $(git-make-repo-url) \(${REV_NAME}\)
git archive --prefix=${PREFIX}/ $REV > $THIS_TAR
mkdir -p $TMP_DIR/$PREFIX
echo ${REV_NAME}> $TMP_DIR/$PREFIX/GITVERSION
echo $(git-make-repo-url)> $TMP_DIR/$PREFIX/GITSOURCE
(
cd $TMP_DIR
tar -rf $THIS_TAR $PREFIX
)
if [ $LEVEL -gt 0 ]
then
if git show $REV:.gitmodules > $GITMODULES_FILE 2> /dev/null
then
LEVEL=$(($LEVEL - 1))
git ls-tree -r "$REV" | grep '^160000 ' |
while read mode type sha1 path
do
(
submodule_name=$(git config --file $GITMODULES_FILE --list | \
grep "^submodule\..*\.path=$path" | cut -d . -f 2)
if [ -z "$submodule_name" ] ; then
echo >&2 -n "fatal: No submodule mapping found in .gitmodules "
echo >&2 "for path '$path'"
exit 1
fi
url=$(git config --file $GITMODULES_FILE \
submodule."$submodule_name".url || exit 1)
$(basename $0) -r $LEVEL $url $sha1 $PREFIX/$path > $SUBMODULE_TAR || exit 1
tar --concatenate --file=$THIS_TAR $SUBMODULE_TAR || exit 1
) < /dev/null
done
fi
fi
cat $THIS_TAR