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

Posted

技术标签:

【中文标题】如何仅将 git 存储库的子目录部署/推送到 Heroku?【英文标题】:How can I deploy/push only a subdirectory of my git repo to Heroku? 【发布时间】:2011-11-24 06:14:16 【问题描述】:

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

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

有没有办法将子文件夹部署到 git 远程? 我是否应该在 output 文件夹中创建一个 Git 存储库(这听起来不对)并将其推送到 Heroku?

【问题讨论】:

您可能正在寻找子模块:book.git-scm.com/5_submodules.html 【参考方案1】:

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

git subtree push --prefix output heroku master

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

【讨论】:

是的,但是子树仍然是(截至 1.8.0.2)not included via the git installer。幸运的是,从源代码安装既快速又简单,this page 在 mac 上为我工作。 如果您需要--force,请使用git push heroku `git subtree split --prefix output master`:master --force。见***.com/a/15623469/2066546。 但是推送特定标签的正确方法是什么。我认为应该是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。我需要这种功能以便以后能够回滚到特定的标签。这样做的正确方法是什么? 我收到错误“更新被拒绝,因为推送的分支提示位于其远程后面” @and-dev @Eric Burel 我成功地将仅存在于我的develop 分支上的output 文件夹推送到heroku master 分支,而无需指定develop:master,显然它从当前签出的分支推送到您指定的目标分支。【参考方案2】:

我从 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 上工作时遇到了问题。

【讨论】:

在这种情况下,'bin' 是您的目标子文件夹?【参考方案3】:

我遇到了类似的问题。就我而言,将 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 日志,此解决方案非常有用。如果要在要部署的应用程序子路径中忽略某些文件夹,可以调整上面的脚本。例如,我不希望 heroku 上的 spec 文件夹。 Example Gist +1 但您可以通过不拉入和合并到 heroku master 来简化,而只需 git push --force heroku master【参考方案4】:

经过漫长而艰难的一个月尝试不同的事情,每次我意识到都会被咬,

仅仅因为 Heroku 使用 git 存储库作为部署机制,你不应该将其视为 git 存储库

也可以是 rsync,他们选择了 git,不要因此而分心

如果你这样做,你就会对各种伤害敞开心扉。所有上述解决方案都在某处惨遭失败:

    它需要每次或定期执行某些操作,或发生意外事件(推送子模块、同步子树……) 如果你使用引擎来模块化你的代码,Bundler 会把你活活吃掉,无法描述我在寻找一个好的解决方案的过程中对该项目的挫败感 您尝试将引擎添加为 git repo 链接 + bundle deploy - 失败,您需要每次都捆绑更新 您尝试将引擎添加为 :path + bundle deploy - 失败,开发团队将 :path 选项视为“您没有使用带有此 gem 选项的 Bundler”,因此它不会捆绑用于生产 此外,引擎的每次刷新都希望更新您的 Rails 堆栈 -_- 我找到的唯一解决方案是在开发中使用引擎作为/vendor 符号链接,并实际复制文件以用于生产

解决方案

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

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

所有项目都有一个vendor/common 符号链接,指向common 引擎的根。在编译源代码以部署到 heroku 时,我们需要删除符号链接并将其代码同步到物理上位于每个单独主机的供应商文件夹中。

    接受主机名列表作为参数 在您的开发存储库中运行 git push,然后在单独的文件夹中运行干净的 git pull,确保不会自动将脏(未提交的)更改推送到主机 并行部署主机 - 提取每个 heroku git repo,将新代码同步到正确的位置,在 git commit 注释中提交基本推送信息, 最后,我们发送一个带有 curl 的 ping 来告诉爱好主机醒来并跟踪日志以查看是否一切正常 与 jenkins 也很好玩 :D(成功测试后自动将代码推送到测试服务器)

现在 6 个月在野外工作得非常好,问题很少(不是?)

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

更新 1

@AdamBuczynski,从未如此简单。

首先,您至少将始终拥有一个生产和测试环境 - 更糟糕的是一堆特定于功能的集群 - 突然 1 个文件夹需要映射到 n 个 heroku 项目,这是一个非常基本的要求,而且这一切都需要组织起来不知何故,脚本“知道”你想在哪里部署什么源,

第二个你会想要在项目之间共享代码 - 现在是sync_common 部分,开发中的符号链接的恶作剧被 Heroku 上的实际 rsynced 代码取代,因为 Heroku 需要一定的文件夹结构和捆绑器和 ruby​​gems 真的真的真的如果您想将公共线程提取到 gem 中,事情会非常糟糕

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

在我需要插入 Java 构建的其他项目中,当向多个客户销售软件时,您需要根据安装要求等过滤安装的模块,

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

【讨论】:

嗨@bbozo,您是否介意稍微压缩一下您的解决方案,并使其特定于将一个特定子文件夹部署到一个特定heroku项目的用例,并取出所有不需要/特定的东西到 Heroku? 感谢您更新您的答案。我想我会咬紧牙关,将我的客户端和服务器端代码拆分为单独的存储库。不适合我们的情况,但它会击败我们现在必须做的强制子树推送,而且据我所知,它也比尝试使用符号链接简单得多。 不要害怕“部署脚本”,它有回报【参考方案5】:

或者,您可以使用 git subtree 在 GitHub 上创建一个 heroku 分支,然后您可以使用 Heroku 按钮将其部署到 Heroku:

    app.json 添加到您的服务器 目录,如here 所述。

    将以下标记添加到README.md

    [![Deploy](https://www.herokucdn.com/deploy/button.png)](https://heroku.com/deploy?template=https://github.com/username/repository/tree/heroku)
    

    将您的更改推送到heroku 分支:

    git subtree push --prefix server origin heroku
    

【讨论】:

以上是关于如何仅将 git 存储库的子目录部署/推送到 Heroku?的主要内容,如果未能解决你的问题,请参考以下文章

是否有限制代码推送到 Git 存储库的首选做法? [关闭]

如何将本地更改推送到 Bitbucket 上的远程 Git 存储库

如何将现有的非空目录转换为 Git 工作目录并将文件推送到远程存储库

如何将 git 子模块推送到 AWS Elastic Beanstalk?

Git没有编辑远程存储库的访问权限

sh 如何使用Git初始推送到远程存储库