协慌网

登录 贡献 社区

功能分支 rebase 后 Git 推送被拒绝

好吧,我认为这是一个简单的 git 场景,我错过了什么?

我有一个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工作的远程备份。到目前为止,我们很好。

但现在我要重订feature在上面F--G上主承诺,所以我git checkout featuregit rebase master 。还好。现在我们有:

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

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

我讨厌使用--force而不确定我是否需要它。那么,我需要它吗?请问垫底一定意味着未来push应该是--force FUL?

这个功能分支不与任何其他开发者共享,所以我事实上没有问题,推力,我不会丢失任何数据,问题更具概念性。

答案

问题是git push假定远程分支可以快速转发到你的本地分支,也就是说本地和远程分支之间的所有区别都在本地有一些新的提交,如下所示:

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

当您执行git rebase提交时,D 和 E 将应用于新的基础并创建新的提交。这意味着在 rebase 之后你会有类似的东西:

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

为什么?因为它检查远程分支的更改,这绝对是个好主意。让我们想象一下,詹姆斯和丽莎正在研究同一个功能分支,丽莎已经推动了提交。詹姆斯现在重新调整他的当地分支,并在试图推动时被拒绝。当然,詹姆斯认为这是因为改变并使用 --force 并且会改写所有 Lisa 的变化。如果詹姆斯曾经使用过 --force-with-lease,那么他会收到一个警告,告知其他人已做过提交。我不明白为什么有人会在推销一个 rebase 之后使用 --force 而不是 --force-with-lease。

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

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

当您删除时,阻止推入包含不同 SHA ID 的现有分支。在这种情况下,我只删除远程分支。