git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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
Previous: Whit Armstrong
Message 4 of 4 in “git-archive and submodules”
  1. Whit ArmstrongMar 29, 2008
  2. Shawn O. PearceMar 29, 2008
  3. Whit ArmstrongMar 29, 2008
  4. CJ van den BergMar 29, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.