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

如何在不需要强制推送的情况下使用git rebase?,git,git-rebase,Git,Git Rebase,为了实现git nirvana,我花了一整天的时间学习如何在当前合并的情况下利用重基 当我运行一个我认为是Git 101流(下面我拼出来)的时候,我必须把代码>推——力当把我的更改推回到原点。 我不是唯一一个-我知道这是一个覆盖的地面(见,,,,),我理解为什么需要一个力的技术原因。我的问题是——有许多(许多)博客文章赞扬了rebase以及它如何改变了他们的生活(见,,,列举了一些),但没有一个提到推——力是他们的流程的一部分。然而,对于现有的stackoverflow问题,几乎每个答案都会说“

为了实现git nirvana,我花了一整天的时间学习如何在当前合并的情况下利用重基

当我运行一个我认为是Git 101流(下面我拼出来)的时候,我必须把代码>推——力当把我的更改推回到原点。 我不是唯一一个-我知道这是一个覆盖的地面(见,,,,),我理解为什么需要一个力的技术原因。我的问题是——有许多(许多)博客文章赞扬了rebase以及它如何改变了他们的生活(见,,,列举了一些),但没有一个提到推——力是他们的流程的一部分。然而,对于现有的stackoverflow问题,几乎每个答案都会说“是的,如果要重新设置基础,就必须使用

push--force

考虑到再基础倡导者的数量和宗教信仰,我不得不相信,使用“推——力”并不是再基础流程中固有的一部分,如果一个人经常被迫推,那么他们就做错了

push--force
是一种强制力

这就是我的流程我怎样才能在没有外力的情况下达到同样的效果?

简单示例

两个分支机构:

  • v1.0-发布分支,仅包含补丁
  • 掌握下一个主要版本的所有内容
我有一些补丁提交和下一版本的一些提交

我想将这些补丁合并到我的主程序中,这样它们就不会在下一版本中丢失。启蒙运动之前,我只想:

git checkout master
git merge v1.0
但现在我正在努力

git checkout master
git rebase v1.0
现在我在这里:

时间:

git push

没有骰子

如果您重新设置了基础,并且已经发布了更改,则必须强制推送,对吗

我使用了大量的重新设置基址,但我要么发布到强制推送无关紧要的私有内容(例如:我自己在GitHub上的克隆,作为拉取请求的一部分),要么在第一次推送之前重新设置基址


这是工作流程的核心,您可以使用重基,但不要强制推送太多:在准备好之前不要发布内容,推送后不要重基。

重基是一个很好的工具,但当您使用它为主控上的主题分支创建快进合并时效果最好。例如,您可以根据master重新设置addnewwidget分支的基础:

git checkout add-new-widget
git rebase -i master
在执行分支到主分支的快进合并之前。例如:

git checkout master
git merge --ff-only add-new-widget
这样做的好处是,您的历史记录不会有太多复杂的合并提交或合并冲突,因为在合并之前,您的所有更改都将重新设置到主控端。第二个好处是您已经重新设置了基址,但您不必使用
git push--force
,因为您不会在主分支上破坏历史记录


这当然不是rebase的唯一用例,也不是唯一的工作流,但这是我见过的对它更合理的使用之一。YMMV.

@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的新分支,将该新分支移动到主分支上,然后将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 push--force的看法是正确的:只有当你犯了错误并推送了你不想要的东西时,你才应该使用它。

我认为这种再基然后强制推送模式有一个很好的用例,它不是错误推送的结果:你自己从多个位置(计算机)处理一个功能分支。我经常这样做,因为我有时在办公室的桌面上工作,有时在笔记本电脑的家庭/客户站点上工作。我需要时不时地重新设置基址,以跟上主分支和/或使合并更干净,但当我离开一台机器去另一台机器上工作时,我还需要强制推动(我只是拉动)。只要我是唯一一个在分支上工作的人,它就会像一个符咒一样工作。

以下是我使用的工具(假设您的分支名为foobar):


tl;dr与共享分支合并,与单个分支重设基础<代码>--带租约的强制力是强制力的一种更安全的替代方案,应该可以帮助你在没有强制力破坏性的情况下实现git涅盘

我看到的适用于各种团队工作流的一般经验法则是,对共享分支(即主分支或开发分支)使用
合并
,在处理您自己的功能分支时使用
重基
。以下是功能分支的典型生命周期

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
我们在这里所做工作的简单英文版本:

  • 在master的基础上创建了一个新分支
  • 在分支上完成工作并推送到远程
  • 母版的重定基面
  • 使用
    强制使用租约将工作推至远程
  • 使用一个非常干净的git日志合并到master中,减少来自共享分支的多次合并所造成的混乱,从而使我们的分支“赶上”最新的master(共享分支)
  • 第四步非常重要,也是我开始提倡使用rebase的主要原因之一
    force with lease
    检查远程服务器,查看是否添加了任何新提交。如果你的
    git推送被证明是破坏性的,它就不会推


    我希望这能让其他人更有信心使用rebase。

    谢谢Dan。你能告诉我如何实现上述目标吗?这难道不是一个应用重基的场景吗?如果您将所有工作都隔离到主题分支,那么它就为重基设置了一个好的场景。您可以
    rebase
    new将更改拉入主题分支,但是当您完成该分支的更改后,您将
    merge
    该分支返回到主开发分支中。问题是您已经发布了该分支-因此您需要
    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