Git推特性分支rebase后拒绝

好吧,我认为这是一个简单的混帐scheme,我错过了什么?

我有一个master分支和一个feature分支。 我做了一些关于master工作,一些关于feature ,然后一些关于master 。 我结束了这样的事情(字典顺序意味着提交顺序):

 A--B--C------F--G (master) \ D--E (feature) 

我没有问题, git push origin master保持远程master更新,也没有与git push origin feature (当feature ),以维持我的feature工作的远程备份。 到目前为止,我们很好。

但是现在我想在主人的F--G提交上重新设置git checkout feature ,所以我可以使用git checkout featuregit rebase master 。 还好。 现在我们有:

 A--B--C------F--G (master) \ D'--E' (feature) 

问题:当我想备份使用git push origin feature feature分支的新的基础feature推送被拒绝了,因为树已经由于重新变化而改变了。 这只能通过git push --force origin feature来解决。

我讨厌使用--force而不确定我需要它。 那么,我需要它吗? 重新装订是否意味着下一步的push应该是有效的?

这个function分支并不与其他任何开发者共享,所以我在强制推动下事实上没有问题,我不会丢失任何数据,问题更具概念性。

问题是git push假定远程分支可以被快速转发到你的本地分支,那就是本地和远程分支之间的所有区别在本地有一些新的提交,就像那样:

 Z--X--R <- origin/some-branch (can be fast-forwarded to Y commit) \ T--Y <- some-branch 

当你执行git rebase commit时,D和E被应用到新的基础上并创build新的提交。 这意味着你有这样的事情后,

 A--B--C------F--G--D'--E' <- feature-branch \ D--E <- origin/feature-branch 

在这种情况下,远程分支不能被快速转发到本地。 虽然,理论上本地分支可以合并到远程(显然你不需要它在这种情况下),但由于git push只执行快进合并投掷和错误。

而且--force选项所做的只是忽略远程分支的状态,并将其设置为您要推入的提交。 所以git push --force origin feature-branch只是用本地feature-branch覆盖origin/feature-branch feature-branch

在我看来,只要你是唯一一个在这个分支上工作的人,那么在master重新分配特性分支并强制将它们推回到远程仓库是可以的。

而不是使用-f或–force开发者应该使用的

 --force-with-lease 

为什么? 因为它检查远程分支的变化,这绝对是一个好主意。 让我们想象一下,James和Lisa正在使用同一个function分支,而Lisa已经推送了一个提交。 詹姆斯现在重新分配他的本地分支,并试图推动时被拒绝。 当然,詹姆斯认为这是由于rebase和使用力,并会重写所有Lisa的变化。 如果詹姆斯使用“强制租赁”的方式,他会收到警告,说有别人提交了。 我不明白为什么有人会在推出rebase之后使用–force而不是–force-with-lease。

解决这个问题的方法就是做msysGit的rebasing merge脚本 – 在rebase之后,将旧的头部元素合并到-s ours 。 你最终的提交图:

 A--B--C------F--G (master) \ \ \ D'--E' (feature) \ / \ -- \ / D--E (old-feature) 

…和你的feature推动将是一个快速前进。

换句话说,你可以这样做:

 git checkout feature git branch old-feature git rebase master git merge -s ours old-feature git push origin feature 

(没有testing,但我认为是正确的…)

我会用“checkout -b”来代替,这样更容易理解。

 git checkout myFeature git rebase master git push origin --delete myFeature git push origin myFeature 

当你删除你阻止推入包含不同SHA ID的退出分支。 我在这种情况下只删除远程分支。

这个分支上只有一个开发人员可能会也可能不会这样,即现在(分配之后)不与内容/元素内联。

因此,我build议使用以下顺序:

 git rebase master git checkout -b feature_branch_2 git push origin feature_branch_2 

是的,新的分支,这应该解决这个没有力量,我认为这通常是一个主要的Git缺点。

其他人已经回答了你的问题。 如果您重新设置分支,则需要强制推送该分支。

Rebase和共享库通常不会相处。 这是重写历史。 如果其他人正在使用该分支或从该分支分支,那么rebase将是相当不愉快的。

一般来说,分期付款在当地分行pipe理方面效果良好。 远程分支pipe理最好使用显式合并(–no-ff)。

我们也避免将主人合并到一个function分支。 相反,我们重新掌握,但有一个新的分支名称(例如添加版本后缀)。 这可以避免共享存储库中重新绑定的问题。

feature分支上的git merge master有什么错误? 这将保持你的工作,同时保持它与主线分支分开。

 A--B--C------F--G \ \ D--E------H 

编辑:啊抱歉没有读你的问题陈述。 你执行rebase需要强制。 所有修改历史logging的命令都需要--force参数。 这是一个安全防止你失去工作(老DE会丢失)。

所以你执行了一个git rebase ,使树看起来像(虽然部分隐藏,因为DE不再在一个命名的分支):

 A--B--C------F--G \ \ D--E D'--E' 

所以,当试图推动你的新feature分支(与D'E'在其中),你会失去DE

以下为我工作:

git push -f origin branch_name

它不会删除我的任何代码。

但是,如果你想避免这一点,那么你可以做到以下几点:

 git checkout master git pull --rebase git checkout -b new_branch_name 

那么你可以select你所有的提交到新的分支。 git cherry-pick COMMIT ID ,然后推新的分支。

由于OP确实了解这个问题,只是寻找一个更好的解决scheme…

这个怎么样呢?

  • 在实际的function开发分支(你从来没有改变和强制推动,所以你的同胞function开发人员不恨你)。 在这里,定期从主合并中抓取这些变化。 梅西耶的历史 ,是的,但生活很简单,没有人在他的工作中被中断。

  • 还有第二个function – 开发分支,其中一个function团队成员regulary推动所有function提交,实际上是重新启动,确实被迫。 所以几乎干净地基于最近的主提交。 function完成后,将该分支推到主设备上。

这个方法可能有一个模式名称。

我避免推动力的方法是创build一个新的分支,继续在这个新的分支上工作,经过一些稳定之后,删除重新分配的旧分支:

  • 在本地重新签出分支
  • 从重新设置的分支分支到新的分支
  • 将该分支作为新分支推送到远程。 并删除远程的旧分支