如何在不需要强制推送的情况下使用git rebase?

时间:2012-06-15 21:18:31

标签: git git-rebase

为了实现git nirvana,我花了一天时间学习如何在我目前合并的情况下利用rebase。

当我通过我认为是git 101流程(我在下面拼写)时,我必须push --force将我的更改推回到原点。

我不是唯一的一个 - 我知道这是覆盖的(见12345) ,我理解技术原因为什么需要一支部队。我的问题是这样的 - 有很多(很多)博客文章赞美篮板以及它如何改变了他们的生活(见123,{{3}列举一些),但没有一个提到push --force是他们流程的一部分。但是,几乎现有的stackoverflow问题的每一个答案都说“是的,如果你要反思,你必须使用push --force”。

鉴于rebase倡导者的数量和宗教信仰,我必须相信使用'push -force'并不是rebase流的固有部分,如果经常不得不强迫他们推动,他们'做错了

push --force4

所以这是我的流程。 如果没有武力,我能用什么方式获得相同的结果?

简单示例

两个分支:

  • v1.0 - 发布分支,仅包含补丁
  • master - 下一个主要版本的所有内容。

我有一些补丁提交和一些提交下一个版本。

premerge

我想将补丁合并到我的主人身上,这样他们就不会在下一个版本中丢失。启蒙前我只是简单地说:

git checkout master
git merge v1.0

但现在我正在尝试

git checkout master
git rebase v1.0

所以现在我在这里:

enter image description here

时间:

git push

没有骰子。

6 个答案:

答案 0 :(得分:37)

Rebasing是一个很棒的工具,但是当您使用它来创建主题分支到master的快进合并时,它最有效。例如,您可以针对master修改add-new-widget分支:

git checkout add-new-widget
git rebase -i master

在执行分支到主服务器的快速合并之前。例如:

git checkout master
git merge --ff-only add-new-widget

这样做的好处是您的历史记录不会有很多复杂的合并提交或合并冲突,因为所有更改都将在合并之前重新定位到master的tip上。第二个好处是您已经重新定位,但您不必使用git push --force,因为您没有在主分支上破坏历史记录。

这肯定不是rebase的唯一用例,也不是唯一的工作流程,但它是我见过的更明智的用途之一。 YMMV。

答案 1 :(得分:22)

@CodeGnome是对的。你不应该在v1.0分支上修改master,而在master上修改v1.0分支,这将会产生重大影响。

git checkout -b integrate_patches v1.0
git rebase master
git checkout master
git merge integrate_patches

创建一个指向v1.0的新分支,将该新分支移到master之上,然后将新版本的V1.0补丁集成到master分支。 你最终会得到类似的东西:

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

the official git documentation建议使用这种方式来使用rebase。

我认为你对git push --force是对的:如果你犯了一个错误并推了一些你不想要的东西,你应该只使用它。

答案 2 :(得分:13)

你必须强行推送,如果你已经发布你的更改,对吗?

我使用rebase一大堆,但是我发布到一个私有的东西,其中强制推送无关紧要(例如:我自己的克隆在GitHub上,作为拉取请求的一部分),或者我在推动之前进行了反转第一次。

这是使用rebase的工作流程的核心,但不要强行推送:在准备好之前不要发布内容,在推送之后不要重新发布。

答案 3 :(得分:4)

我认为这个rebase-then-force-push模式的良好用例不是错误推送的结果:自己从多个位置(计算机)处理功能分支。我经常这样做,因为我有时在桌面办公室工作,有时在笔记本电脑上的家庭/客户现场工作。我需要偶尔重新调整以跟上主分支和/或使合并更清晰,但是当我离开一台机器去另一台机器上工作时我也需要强制推送(我只是拉动)。就像魅力一样,只要我是唯一一个在分支机构工作的人。

答案 4 :(得分:2)

这是我使用的(假设你的分支名称是 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

答案 5 :(得分:0)

tl; dr与共享分支合并,对单个分支进行基础调整。 --force-with-lease是一种更安全的替代武力的选择,应该可以帮助您实现上述的绝境,而不会破坏武力。

我见过各个团队工作流程的一般经验法则是将merge用于共享分支(即,掌握或开发),并在使用自己的功能时使用rebase科。这是要素分支的典型生命周期

git checkout master
git checkout -b new-feature
git commit -am "commit new work"
git push -u origin new-feature
# have code reviewed, run CI, etc.,
# meanwhile master has new commits
git checkout master
git pull
git rebase -i master # -i for interactive rebase allows you to squash intermediate commits
git push --force-with-lease
git merge master

我们在这里所做的工作的纯英文版本:

  1. 从master分支创建新分支
  2. 完成分支​​工作并推送到远程
  3. 基于母版
  4. 使用force-with-lease将工作推送到远程
  5. 通过一个非常干净的git日志合并到master中,从而减少了来自共享分支的多次合并带来的混乱,从而使分支与最新的master(共享分支)“追上了”

第四步非常重要,这也是我开始提倡使用rebase的主要原因之一。 force-with-lease检查遥控器以查看是否添加了任何新的提交。如果您的git push被证明具有破坏性,它将不会继续!

我希望这能给人更多使用rebase的信心。