25

我已经设置了我的环境,所以我可以推送到远程裸存储库。我使用这些命令来设置远程存储库:

$ mkdir ~/website.git && cd ~/website.git
$ git init --bare

$ cat > hooks/post-receive

#!/bin/sh
GIT_WORK_TREE=/var/www/website git checkout -f

$ chmod +x hooks/post-receive

在我的本地环境中:

$ git remote add web ssh://website.com/home/website.git
$ git push web +master:refs/heads/master

现在我可以使用 部署到这个远程git push web,一切都很好..

问题:子模块

我的项目中有一些子模块没有在远程存储库中初始化/更新。我不能git submodule update在裸机上运行,​​因为它是裸机,我不能在/var/www/website文件夹上运行它,因为它只是文件的副本而不是 git repo。

4

3 回答 3

12

我想出了另一个对我来说看起来相当干净的解决方案。只需为 git 提供执行子模块所需的所有信息:

$ cd /path/to/your/git_work_tree
$ git --git-dir=/path/to/your/bare_repo.git --work-tree=. submodule init
$ git --git-dir=/path/to/your/bare_repo.git --work-tree=. submodule update
于 2015-07-25T13:39:27.250 回答
11

一种可能的方法可能是:

换句话说:
从裸仓库中提取而不是尝试从裸仓库中结帐:非裸仓库应该能够适应该git submodule update步骤。

示例脚本可能看起来像

#!/bin/sh

# Get the latest code
cd /path/to/bare/repo

# Set git variables
GIT_WORK_TREE=/var/www/website
GIT_DIR=/var/www/website/.git

# Go to website and pull
cd /var/www/website
git pull /path/to/bare/repo
git submodule update --init --recursive

# Run additional build stuff here
于 2012-02-25T22:46:14.190 回答
6

两天前,当我在同一个问题上苦苦挣扎时,我偶然发现了这个线程。在终于找到一个不错的、整洁的解决方案后,我在这里写了一篇关于它的文章:

带有子模块的 Git 推送:操作指南

我意识到,如果我要去push一个裸仓库,只是为了使用post-receivepull一个非裸仓库,我还不如保持简单,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

现在让我们继续打破所有规则。

我们将在我们的网站目录中初始化一个非裸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 帖子在过去两天里帮助我一样帮助别人!

于 2012-12-07T03:46:32.080 回答