如何将不同的本地 Git 分支推送到 Heroku/master

474

Heroku有一个忽略所有分支但'master'的政策。

虽然我相信Heroku的设计师对于这个政策有着很好的理由(我猜测是为了存储和性能优化),作为开发者,对我来说,结果就是无论我在本地工作的是哪个主题分支,我都希望有一种简单的方式可以切换Heroku的主分支到本地的主题分支,并执行"git push heroku -f"来覆盖Heroku上的master分支。

通过阅读http://progit.org/book/ch9-5.html中的"Pushing Refspecs"部分,我得到的方法是:

git push -f heroku local-topic-branch:refs/heads/master

我真正希望的是能够通过配置文件来设置这个操作,这样每次执行"git push heroku"时都会执行上述命令,将local-topic-branch替换为当前分支的名称。如果有人知道如何实现,请告诉我!

当然,这个前提是只有我一个人能够推送到Heroku应用/仓库。测试或QA团队可能会管理这样一个仓库,以尝试不同的候选分支,但他们必须协调一致,以便在任何给定的日子里都同意将分支推送到该仓库。
不用说,最好还是有一个单独的远程仓库(比如GitHub),没有这个限制,可以备份所有内容。我会把它称为"origin",并使用"heroku"来表示Heroku,这样"git push"总是将所有内容备份到origin,而"git push heroku"则将我当前所在的分支推送到Heroku的主分支,如果需要的话会覆盖它。
这样行得通吗?
[remote "heroku"]
    url = git@heroku.com:my-app.git
    push = +refs/heads/*:refs/heads/master
在开始实验之前,我想听听更有经验的人的意见,虽然我想我可以在Heroku上创建一个虚拟应用程序进行实验。
至于获取数据,对于Heroku仓库是否只读,我并不在意。我仍然有一个单独的仓库,比如GitHub,用于备份和克隆我的所有工作。
注:这个问题与Good Git deployment using branches strategy with Heroku?类似,但并不完全相同。

1
目前票数最高的答案是这个问题的惯用方法(在我看来也是真正正确的答案)。 - Selali Adobor
一个关于推送 refspecs 的备选 https 资源:git scm 关于推送 refspecs 的文档 - Dylan Landry
12个回答

1694

37
可能需要使用-f参数强制执行。 - Scott Stafford
3
@DaveMeehan,这仍然有效。你试图执行 git push :master,这会通过将其覆盖为空来删除主分支而不是用另一个分支覆盖它,这与使用另一个分支覆盖它不同。Heroku可能已经采取了保障措施来防止删除主分支。 - Dennis
1
这是一个很棒的解决方案。 - Ajay Kumar
2
除非你的分支落后于主分支并且你想要覆盖Heroku上的当前代码,否则它不会生效。 - ricks
有没有办法做到这一点,但是将分支部署在不同的URL上(以便不影响站点的生产版本)? - stevec
显示剩余2条评论

147

使用通配符时,必须在refspec的两侧都存在,因此+refs/heads/*:refs/heads/master无法工作。但您可以使用+HEAD:refs/heads/master

git config remote.heroku.push +HEAD:refs/heads/master

此外,您可以直接使用 git push 完成此操作:

git push heroku +HEAD:master
git push -f heroku HEAD:master

4
这两个命令有什么不同,还是我们需要执行两个命令? - Saad Masood
2
@SaadMasood:最后两个 git push 命令的作用是相同的。请参阅 git push --help 以了解 -f 选项和 refspec 中的 + 的含义。 - Chris Johnsen
4
@Chris Johnson:你能告诉我们“-f”参数的含义,而不是在这里让别人去查阅文档吗?请用通俗易懂的语言解释。 - AHH
@AHH -f 代表 强制。我使用了 jassa 的答案,它对我有效。 - Mr. Tao
@Chris Johnson:HEAD 是否仅用于推送应用程序的最新版本,而不是整个历史记录? - Cameron Wilby
1
@Cameron Wilby HEAD 指的是你所在分支的最后一个提交(分支的头),由于 Git 的工作方式,它将包括该点之前的所有提交。 - Wes Mason

80
git push -f heroku local_branch_name:master

4
注意,这里使用了 -f--force,在强制推送之前最好确保你知道自己在做什么。请注意风险。 - MiFiHiBye
@tomasz-mazur 为什么需要使用 -f? - nxmohamad
是的,在某些情况下,我们可能需要使用-f选项,比如在处理多个进行中的分支并替换heroku中的任何内容以及测试工作分支时,请告知是否有其他更好的测试方法。 - Fahad
它在我的电脑上运行,感谢您的答案,实际上这个语法在普通的Github存储库中有效吗? - Luk Aron

18

对我来说,它有效。

git push -f heroku otherBranch:master

推荐使用-f(强制标志)以避免与其他开发人员的推送冲突。由于您没有将Git用作修订控制,而仅用作传输工具,因此使用强制标志是合理的做法。
来源:官方文档

13

将不同的本地Git分支推送到Heroku/master最安全的命令。

git push -f heroku branch_name:master

注意:虽然您可以不使用 -f 参数进行 push 操作,但建议使用 -f (force 标志)以避免与其他开发者的 push 冲突。


4
你不觉得先不加"-f"选项更好吗?如果有冲突的话,先确认可以覆盖它们再进行操作。 - nxmohamad
不要盲目地执行“-f”! - pixelearth

6
请注意,如果您正在使用Git Flow系统,您的功能分支可能被称为
feature/mobile_additions

如果你的git远程仓库名称为stagingtwo,那么推送到Heroku的命令将是:
git push stagingtwo feature/mobile_additions:master

5
git push heroku $(git branch --show-current):master

或者,另外:

git push heroku HEAD:master

4

我建议您查看heroku_san,它可以很好地解决这个问题。

例如,您可以:

git checkout BRANCH
rake qa deploy

它还可以轻松地启动新的Heroku实例,将主题分支部署到新服务器上。
git checkout BRANCH
# edit config/heroku.yml with new app instance and shortname
rake shortname heroku:create deploy # auto creates deploys and migrates

当然,如果你频繁地执行某些操作,你可以编写更简单的rake任务。

2

现在已经迁移到http://jqr.github.com/2010/08/27/easy-heroku-deploys-with-heroku-san.html。 - slothbear

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接