Ruby on rails 如何通过git push将多个分支部署到不同的目录?
在生产中,我维护两个站点-beta和release。每个都通过软链接指向不同的目录(例如) 我是svn的长期用户,正在使用git。我习惯于通过svn更新部署和更改新分支上的软链接,事情非常简单 现在我要转到git。我仍然需要两个软链接(这是一个使用Passenger的Rails应用程序),不过现在我希望它们指向两个不同的git分支(“beta”和“release”)。我希望能够通过git push(或git pull)更新它们 问题1:我不确定最好的方法 我开始这样做的方式是只部署到两个不同的远程设备,例如Ruby on rails 如何通过git push将多个分支部署到不同的目录?,ruby-on-rails,git,Ruby On Rails,Git,在生产中,我维护两个站点-beta和release。每个都通过软链接指向不同的目录(例如) 我是svn的长期用户,正在使用git。我习惯于通过svn更新部署和更改新分支上的软链接,事情非常简单 现在我要转到git。我仍然需要两个软链接(这是一个使用Passenger的Rails应用程序),不过现在我希望它们指向两个不同的git分支(“beta”和“release”)。我希望能够通过git push(或git pull)更新它们 问题1:我不确定最好的方法 我开始这样做的方式是只部署到两个不同的远
git push ssh://scott@x.com/home/scott/myapp-beta beta
git push ssh://scott@x.com/home/scott/myapp-release release
但这不起作用,因为默认情况下推送不会更新工作树
因此,我进入远程目录并运行git reset——第一次很难,它会拉动工作树。但是我再推一次,我无法得到新的推动-它只是停留在最初的一个
(顺便说一句,请注意,我似乎无法推到“myapp beta.git”-如果失败,我必须推到目录名。我担心这是问题的一部分,但我不知道我在这里做错了什么。)
所以,如果问题1的答案是我的方法很好,问题2:我实际做的有什么问题?如果有我应该用的钩子,有人能指给我看吗
(对问题1的回答是“运行这七个手动步骤”并不是一个非常有用的答案,因为svn checkout+ln-s是两个步骤。)
谢谢。我想继续写代码。这篇文章对一个类似的问题进行了有趣的讨论
其解决方案和结论之一涉及:
- 生产服务器上的裸存储库
- 一个克隆的存储库,带有一个钩子,可以将推到裸存储库中的内容拉出来
- 一个简单的回购协议,你可以在上面推测试版和发布分支
- 两个克隆的回购“beta”和“release”,用钩子从裸回购中拉出各自的分支
gitpush
。不再需要管理链接(因为目录不再代表Git中的分支,与SVN不同)
关于挂钩部分,裸回购协议中的a可能就是你所需要的 看 注:
post receive
钩子以设置为repo/.GIT
文件夹的GIT\u DIR
环境变量开始,因此无论您将“cd
”放入哪个路径,都将始终尝试在那里运行任何以下GIT命令。解决这个问题只需取消设置
GIT\u目录
:它完全忽略继承的环境,只使用提供的变量和值。我使用类似的
post receive
来发布我的网站,因为Git在推送时不接触工作目录。远程存储库是非裸存储库,即它有一个工作目录
if [ -n $GIT_DIR ]; then
# Current dir is "<reporoot>/.git/", but we need to run reset at "<reporoot>/".
# Clearing GIT_DIR is needed, or reset will fail with "fatal: Not a git repository: '.'"
unset GIT_DIR
cd ..
fi
git reset --hard
if[-n$GIT_DIR];然后
#当前目录为“/.git/”,但我们需要在“/”处运行重置。
#需要清除GIT_DIR,否则重置将失败并显示“致命:不是GIT存储库:”
未设置GIT_目录
光盘
fi
git重置——硬
(顺便说一句,请注意,我似乎无法推到“myapp beta.git”-如果失败,我必须推到目录名。我担心这是问题的一部分,但我不知道我在这里做错了什么。)
创建没有工作目录的裸Git存储库(
Git init--bare
)时,通常将目录命名为“something.Git”。当拥有非裸存储库时,存储库实际上位于“.git”子目录中,因此完整路径为“something/.git”。似乎在这两种情况下,您都可以省略“.git”部分,git将自动检测到它。我并不反对其他解决方案,但我认为有一种不太老练的“git方式”可以做到这一点。下面是我要做的:
解决方案是推送到单个存储库,该存储库将采用
update
或post-receive
有几种不同的方法可以创建两个签出,可以在hook(服务器上)中使用。从最轻的开始:
- 如果您不需要这两个签出目录(签出版本)实际上是git存储库,那么只需使用导出两个快照(两个分支)
其中,“master”和“devel”是您希望签出的分支的名称。请注意,严格来说,
不是必需的,因为tar格式是“git归档”的默认格式。您可能还希望删除旧内容(“--format=tar
,在第一行“rm-rf public_html/”
”之前,加上“tar xf-
”,第二行也是如此) 导出文件的另一种方法是使用低级命令“&&&
”(将树写入索引)和“git read tree
”(将文件从索引复制到工作区) 在这个解决方案中,您推入的存储库可以(而且应该)是空的,即没有工作目录本身git checkout index
- 另一个解决方案是,您推入的存储库中有两个工作目录,可以使用
c中的脚本创建
$ cd bare $ chmod +x .git/hooks/post-receive with a post-receive hook like #!/bin/sh cd ../../beta env -i git reset --hard cd ../../release env -i git reset --hard
if [ -n $GIT_DIR ]; then # Current dir is "<reporoot>/.git/", but we need to run reset at "<reporoot>/". # Clearing GIT_DIR is needed, or reset will fail with "fatal: Not a git repository: '.'" unset GIT_DIR cd .. fi git reset --hard
git archive --format=tar --prefix=public_html/ master | (cd /var/www/html && tar xf -) git archive --format=tar --prefix=beta_public_html/ devel | (cd /var/www/html && tar xf -)