Is it possible to include submodules when using the following code in a post-update hook?
GIT_WORK_TREE=/path/to/directory git checkout -f What other options would I have to distribute code, including submodules from a post-update hook?
Thanks.
The question "Using git submodule update --init on a post hook" mentions the error message you could see if using this in your post-update hook:
GIT_WORK_TREE=/path/to/directory git submodule update --init That would give a:
remote: You need to run this command from the toplevel of the working tree. So it is best to cd directly in the target repo and run your command from there:
export GIT_DIR=$(pwd) cd /path/to/target/workingtree git checkout -f master git submodule update --init --recursive However, as shown in "How do I init/update a git submodule in a working tree after pushing to a bare working directory?":
It looks like when your running "git submodule update" you can't set the
GIT_WORK_TREE:
it will try to use this as the working tree for the submodule, not for the super project.
The blog post "Git push with submodules: a how-to guide" by Aaron Adams describe similar error messages as the OP iliveinapark shows in the comments:
Sadly, this doesn't work, I suspect because my repo is a bare repo.
The error that I get following these commands is:
fatal: This operation must be run in a work tree If, to overcome the above error, I use something like:
git --git-dir=<my bare repo> --work-tree=<where I export to> submodule update --init --recursive I get:
fatal: working tree '<where I export to>' already exists. Clone of '<submodule repo>' into submodule path '<submodule path>' failed The blog post mentioned above suggests an approach based on a non-bare repo (which usually isn't recommended for pushing to, but is necessary in this case) :
First, let’s create a universal post-receive hook, one that I won’t need to change on a per-repository basis:
[aaron@aaronadams]$ cat > /usr/local/share/git-core/templates/hooks/post-receive.sample #!/bin/sh # # An example hook script to update the working tree, including its # submodules, after receiving a push. # # This hook requires core.worktree to be explicitly set, and # receive.denyCurrentBranch to be set to false. # # To enable this hook, rename this file to "post-receive". # Read standard input or hook will fail while read oldrev newrev refname do : done # Unset GIT_DIR or the universe will implode unset GIT_DIR # Change directory to the working tree; exit on failure cd `git config --get core.worktree` || exit # Force checkout git checkout --force # Force update submodules git submodule update --init --recursive --force [aaron@aaronadams]$ chmod +x /usr/local/share/git-core/templates/hooks/post-receive.sample Now let’s go ahead and break all the rules.
We’re going to:
- initialize a non-bare Git repository, right in our website directory;
- make sure it can receive from git push;
- explicitly set its working tree to its parent directory;
- and enable our hook we just created.
[aaron@aaronadams]$ cd /var/www/vhosts/aaronadams.ca/sites/staging.aaronadams.ca [aaron@aaronadams]$ git init && git config --bool receive.denyCurrentBranch false && git config --path core.worktree ../ && mv .git/hooks/post-receive.sample .git/hooks/post-receive Initialized empty Git repository in /var/www/vhosts/aaronadams.ca/sites/staging.aaronadams.ca/.git/
Finally, on our local machine, we’ll change our remote to reflect the location of our new repository, and push.
[aaron@aaronadams]$ git remote set-url staging [email protected]:sites/staging.aaronadams.ca [aaron@aaronadams]$ git push staging master remote: Submodule 'codeigniter' (git://github.com/EllisLab/CodeIgniter.git) registered for path 'codeigniter' remote: Cloning into 'codeigniter'... remote: Submodule path 'codeigniter': checked out 'fd24adf31255822d6aa9a5d2dce9010ad2ee4cf0' To [email protected]:sites/staging.aaronadams.ca * [new branch] master -> master Holy crap, it worked!
Not only is this method compatible with submodules, it also requires just one command to set up a new remote repository (which, okay, consists of four commands).
It also keeps the repository and the working tree in the same place; and with no absolute paths required in our configuration or hook files, it’s now completely portable as well.
The OP iliveinapark mentions though:
This became a bit too fiddly, though, so I went with a simple forced checkout, and will manage updating my submodules manually.
fatal: This operation must be run in a work treegit --git-dir=<my bare repo> --work-tree=<where I export to> submodule update --init --recursive I get: fatal: working tree '<where I export to>' already exists. Clone of '<submodule repo>' into submodule path '<submodule path>' failed