如何在不需要强制推送的情况下使用git rebase?
为了实现git涅</s>,我花了一天的时间学习如何在我现在合并的情况下利用rebase。
当运行我认为是git 101stream(我在下面详细说明)时,我必须在将更改推回到原点时push --force
执行。
我不是唯一一个 – 我知道这是被掩盖的(见1,2,3,4,5 ),我也明白为什么一支部队是必要的技术原因。 我的问题是这样的 – 有很多(许多)博客文章赞美rebase以及它是如何改变他们的生活的(见1,2,3,4列出的),但没有一个提到push --force
是他们stream动的一部分。 然而,对于现有的stackoverflow问题,几乎所有的答案都是这样的:“是啊,如果你要重新定位,你必须使用push --force
”。
考虑到亚特兰蒂斯倡导者的数量和宗教性, 我必须相信,使用“推力”并不是亚基stream动的固有组成部分,而且如果经常要迫使他们推动,他们就会做错事 。
push --force
是一件坏事 。
所以这是我的stream程。 我怎样才能在没有武力的情况下取得同样的结果?
简单的例子
两个分支:
- v1.0 – 发行版分支,只包含补丁
- 掌握 – 下一个主要版本的一切。
我有几个补丁提交和下一个版本的一些提交。
我想将这些补丁合并到我的主文件中,以便在下一个版本中不会丢失。 启蒙之前我只是简单地说:
git checkout master git merge v1.0
但现在我正在尝试
git checkout master git rebase v1.0
所以现在我在这里:
的时间:
git push
没有骰子。
重新分页是一个很好的工具,但是当您使用它来创build主题分支的快速合并时,效果最好。 例如,您可能会将您的add-new-widget分支绑定到master:
git checkout add-new-widget git rebase -i master
然后执行分支快进合并到主。 例如:
git checkout master git merge --ff-only add-new-widget
这样做的好处是,您的历史不会有太多复杂的合并提交或合并冲突,因为所有的更改将在合并之前重新发布到master的顶端。 第二个好处是你已经重新升级,但是你不必使用git push --force
-force,因为你并不是在主分支上打破历史。
这当然不是rebase的唯一用例,也不是唯一的工作stream程,但这是我见过的更合理的用法之一。 因人而异。
@CodeGnome是对的。 你不应该在v1.0分支上重新分配master,而应该在master上分配v1.0分支,这样做会有所不同。
git checkout -b integrate_patches v1.0 git rebase master git checkout master git merge integrate_patches
创build一个指向v1.0的新分支,将新分支移到主分支上,然后将新版本的V1.0补丁集成到主分支。 你会最终得到像这样的东西:
o [master] [integrate_patches] Another patch on v1.0 o A patch on v1.0 o Another change for the next major release o Working on the next major release | o [v1.0] Another path on v1.0 | o A patch on v1.0 | / o Time for the release
官方的git文档推荐使用这种方法来使用rebase。
我认为你对git push --force
是正确的:如果你犯了一个错误,你应该只使用它,并推送你不想要的东西。
你必须强制推动,如果你rebase,你已经发表了你的改变,对吗?
我使用rebase一大堆,但是我要么发布到一个私人的地方强制推无所谓(例如:我自己的克隆在GitHub上,作为拉请求的一部分),或者我推出之前,我第一次rebase。
这是使用rebase的工作stream程的核心,但不要强制推送:在准备好之前不要发布,不要在推送后重新绑定。
我认为,这种基于转换 – 然后强制推动的模式并不是错误推动的结果:自己在多个位置(计算机)上运行特性分支。 我经常这样做,因为我有时在我的桌面办公室工作,有时在我的笔记本电脑上工作在家里/客户现场。 为了跟上主要分支和/或使合并变得更干净,我需要偶尔进行更新。但是,当我离开一台机器去另一台机器上工作时,我也需要强行推送。 工作就像一个魅力,只要我是唯一一个在分支上工作的人。
这是我使用的(假设你的分支名称是foobar ):
git checkout master # switch to master git rebase foobar # rebase with branch git merge -s ours origin/master # do a basic merge -- but this should be empty git push origin master # aaand this should work