两天前,我在为同样的问题苦苦挣扎时偶然发现了这个帖子。在终于找到了一个不错、整洁的解决方案后,我在这里写了一篇关于它的文章:
Git push with submodules: a how-to guide
我意识到,如果我要去 push 到一个裸仓库,只使用 post-receive 到 pull 到一个非裸仓库,我还不如保持简单和直接 push到非裸存储库。这是一个明显的案例,其中仅推送到裸仓库的“最佳实践”只会增加复杂性。
如果链接失效,我将在此处粘贴我的解决方案,跳过我确定遇到的所有相同问题的部分。
首先,让我们创建一个 通用 post-receive 挂钩,我不需要在每个存储库的基础上进行更改:
[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
现在让我们继续打破所有规则。
我们将在我们的网站目录中初始化一个 non-bare Git 存储库;确保它可以从git push 接收;将其工作树显式设置为其父目录;并启用我们刚刚创建的钩子。
[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/
最后,在我们的本地机器上,我们将更改远程以反映我们新存储库的位置,然后推送。
[aaron@aaronadams]$ git remote set-url staging aaron@aaronadams.ca: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 aaron@aaronadams.ca:sites/staging.aaronadams.ca
* [new branch] master -> master
天哪,它成功了!
这种方法不仅与子模块兼容,还只需要一个命令来设置一个新的远程存储库(好吧,由四个命令组成)。它还将存储库和工作树保持在同一位置;而且我们的配置或挂钩文件中不需要绝对路径,现在它也完全可移植。
我希望这个答案对某人有所帮助,就像其他人的 Stack Exchange 帖子在过去两天对我有所帮助一样!