简体   繁体   中英

How can I use git-archive to include submodules from a bare repository

I'm in the process of setting up a deployment script. The basic process is:

  1. Push changes to a bare repository on the server
  2. Then based on new tags will create a new folder for the release.
  3. Use git archive to move the files into the release directory
  4. Runs some migrations scripts and puts it live (if all is successful).

The issue is my repository contains a submodule, which doesn't get put in the archive, and therefore doesn't get put in the release directory.

I've seen git-archive-all , but that doesn't work on a bare repository.

If its not possible, I'm considering,

  1. making the repository not bare, and updating the working copy, which would allow me to use git-archive-all. Or
  2. having a second bare repository of the submodule on the server, which I could get an archive from (would have to look into this to make sure I'm getting the right revision).

I use this python package https://github.com/Kentzo/git-archive-all . You can install it by using

pip install git-archive-all

On OSX, you can install it also using brew install git-archive-all

If your submodule is in a repo accessible from the server, I would rather have a post-receive hook which would

  • update a full non-bare repo (so a second repo beside your original bare one), including the submodule ( git submodule update --init )
  • git archive from that second repo (you would be sure to get the right version since the non-bare repo would reference the right version of the submodule)
    Since the non-bare repo would contain the parent repo and its submodules, git archive-all would be able to detect the .git subdirectories and would archive everything .

If the submodule isn't accessible from the server, that means:

  • it needs to be pushed in its own repo on the server
  • the submodule in the parent repo needs to be reference with a relative path, in order for the parent repo to still be able to retrieve said submodule once pushed on the server.

Here it is as a few-liner:

prefix=$(basename "$(pwd -P)")
{
  git ls-files
  git submodule foreach --recursive --quiet \
                'git ls-files --with-tree="$sha1" | sed "s#^#$path/#"'
} | sed "s#^#$prefix/#" | xargs tar -c -C.. -f "$prefix.tar.xz" --

Run the following after the regular archive command:
git submodule foreach 'cd REPO_ROOT/$path && git archive HEAD | tar -x -C TARGET_ROOT/$path'

Here the REPO_ROOT is where your repo stands and the TARGET_ROOT is where you put your archived version. (I assume that you have a TARGET_ROOT folder where the expanded version of the first git archive call. If you want a final zip/tar, you can tar/zip the final folder)

git submodule foreach provides the $path variable. See git help submodule foreach section for more details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM