如何仅将git repo的子目录部署/推送到Heroku?


121

我有一个使用Serve的项目,并且使用Git进行了版本控制。服务创建了一个output文件夹,其中包含要部署到Heroku的静态文件。

我不想自己部署Serve项目,因为Heroku Cedar堆栈似乎不太喜欢它,但是最重要的是,我想利用Heroku对静态网站的强大支持。

有没有一种方法可以将子文件夹部署到git远程?我应该在output文件夹中创建一个Git存储库(听起来很错误),然后将其推送到Heroku吗?


1
您可能正在寻找子模块:book.git-scm.com/5_submodules.html
greg0ire 2011年

Answers:


220

通过git-subtree有一个更简单的方法。假设您要将文件夹“输出”作为根目录推送到Heroku,可以执行以下操作:

git subtree push --prefix output heroku master

目前看来git-subtree已包含在git-core中,但是我不知道该版本的git-core是否已经发布。


1
是的,但是仍然没有通过git installer包含子树(从1.8.0.2版本开始)。幸运的是,从源代码进行安装是快速而直接的,此页面在Mac上对我有用。
dribnet

14
如果需要--force,请使用git push heroku `git subtree split --prefix output master`:master --force。请参阅stackoverflow.com/a/15623469/2066546
fiedl 2014年

2
但是,推送特定标签的正确方法是什么。我以为应该git subtree push --prefix output heroku +refs/tags/v1.0.0:refs/heads/master。但这是行不通的,然后又回来了+refs/tags/v1.0.0:refs/heads/master does not look like a ref。我需要这种功能,以便稍后能够回角色到特定标签。正确的做法是什么?
denis 2014年

1
我收到错误消息“由于推送的分支提示位于其远程后面,因此更新被拒绝”
Ally

2
@ and-dev @Eric Burel我成功地将output只存在于我的develop分支上的文件夹推到了heroku master分支,而无需指定develop:master,因此显然它将它推到了您从当前已签出分支指定的目标分支。
cprcrack

9

我有一个类似的问题。就我而言,销毁heroku存储库中的所有内容并将其替换为我的子目录中的内容从来没有问题。如果是这种情况,可以使用以下bash脚本。只需将其放在您的Rails应用目录中即可。

#!/bin/bash

#change to whichever directory this lives in
cd "$( dirname "$0" )"

#create new git repository and add everything
git init
git add .
git commit -m"init"
git remote add heroku git@heroku.com:young-rain-5086.git

#pull heroku but then checkback out our current local master and mark everything as merged
git pull heroku master
git checkout --ours .
git add -u
git commit -m"merged"

#push back to heroku, open web browser, and remove git repository
git push heroku master
heroku open
rm -fr .git

#go back to wherever we started.
cd -

我敢肯定有很多方法可以改善这一点-请随时告诉我如何做!


+1谢谢。如果您不关心Heroku上的git日志,则此解决方案非常有用。在要部署的应用程序子路径中,如果有一些文件夹要忽略,可以对脚本进行微调。例如,我不想spec在heroku上使用文件夹。示例要点
ch4nd4n 2012年

+1但您可以简化操作,而不是将其拉入并合并到heroku master中,而是简单地进行操作git push --force heroku master
MK Safi

9

我从约翰·贝里曼(John Berryman)的观点开始,但实际上,如果您根本不关心heroku git的历史,它可能会更简单。

cd bin
git init
git add .
git commit -m"deploy"
git push git@heroku.com:your-project-name.git -f
rm -fr .git

我猜官方git subtree是最好的答案,但是我在让子树在Mac上工作时遇到了问题。


4

经过漫长而艰苦的一个月,尝试各种不同的事物并每次被我咬到,

仅仅因为Heroku使用git仓库作为部署机制,所以您不应将其视为git仓库

它也可能已经rsync了,他们去了git,不要因为这个而分心

如果这样做,您会遭受各种伤害。所有上述解决方案在某处都惨遭失败:

  1. 它需要每次或定期执行某项操作,或者发生意外情况(推动子模块,同步子树等)。
  2. 例如,如果您使用引擎对代码进行模块化,那么Bundler会让您生死,无法描述我在寻求一个好的解决方案的过程中对该项目感到沮丧的程度
    • 您尝试将引擎添加为git repo链接+ bundle deploy-失败,您每次都需要捆绑更新
    • 您尝试将引擎添加为:path+ bundle deploy-失败,开发团队认为该:path选项为“您没有将此Bundler与该gem选项一起使用”,因此它不会捆绑用于生产
    • 同样,引擎的每次刷新都希望更新您的rails堆栈-_-
  3. 我发现的唯一解决方案是将引擎用作/vendor开发中的符号链接,并实际复制文件以进行生产

解决方案

有问题的应用在git root中有4个项目:

  1. api-根据配置文件将在2个不同的heroku主机上运行-上传和api
  2. 网站-网站
  3. 旧网站-旧网站,仍在迁移中
  4. 通用-引擎中提取的通用组件

所有项目都有一个vendor/common符号链接,这些符号链接着眼于common引擎的根源。在编译用于部署到heroku的源代码时,我们需要删除symlink并将其代码rsync物理上放置在每个单独主机的供应商文件夹中。

  1. 接受主机名列表作为参数
  2. 在您的开发仓库中运行git push,然后在单独的文件夹中运行干净的git pull,确保没有脏的(未提交的)更改被自动推送到主机
  3. 并行部署主机-提取每个heroku git repo,将新代码重新同步到正确的位置,并在git commit注释中提交基本的推送信息,
  4. 最后,我们发送一个带有卷曲的ping命令,告诉嗜好主机醒来并尾随日志,看看是否都喝了酒
  5. 也与jenkins一起玩:D(成功测试后自动将代码推送到测试服务器)

6个月以来,在野外工作非常好,几乎没有(没有?)问题

这是脚本https://gist.github.com/bbozo/fafa2bbbf8c7b12d923f

更新1

@AdamBuczynski,这从未如此简单。

首先,您将始终至少拥有一个生产和测试环境-最坏的情况是一堆特定于功能的集群-突然,一个文件夹需要作为一个非常基本的需求映射到n个heroku项目,并且都需要以某种方式进行组织,以便该脚本“知道”您要在何处部署的源,

第二,您将要在项目之间共享代码-现在到了这一sync_common部分,开发中带有符号链接的shennanigans被Heroku上的实际rsync代码替换了,因为Heroku需要某种文件夹结构,并且bundler和rubygems确实真的使事情变得很糟,如果您想要将通用线程提取到宝石中

第三,您将需要插入CI,它会稍微改变子文件夹和git repo的组织方式,最后,在最简单的用例中,您会遇到上述要点。

在其他项目中,我需要插入Java版本,将软件出售给多个客户端时,您需要根据安装要求和其他条件过滤要安装的模块,

我真的应该考虑将事物捆绑到Rakefile或其他东西中,然后以这种方式做所有事情...


@bbozo,您好,您是否介意将您的解决方案浓缩一下,使其针对将一个特定的子文件夹部署到一个特定的Heroku项目中的用例,并取出不需要/特定于Heroku的所有内容?
亚当·里斯

感谢您更新答案。我想我只是硬着头皮,将我的客户端和服务器端代码拆分到单独的存储库中。对于我们的情况而言,这不是理想的选择,但是它将击败我们现在必须执行的强制子树推送,并且从我的收集中,这比尝试使用符号链接要简单得多。
亚当·里斯

不要害怕“部署脚本”,它会
有所
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.