我们有一个工作流程,只有一个团队成员可以在多个功能分支上工作。工作是这样的,每个下一个分支都依赖于他以前的分支。默认分支为develop
。
让我们说这个场景:
featureA
分支,完成工作,推动分支,并在GitHub上创建PR featureB
分支(基于featureA
一个分支),做了工作并做了推广featureC
分支,(基于featureB
)完成了工作并将其推广featureD
分支,(基于featureC
)完成了工作并将其推广尚未合并任何公关。
现在,项目经理介入并开始合并。合并这样:
featureA
合并到开发开发人员在他身边做:
git checkout develop
git fetch origin
git rebase origin/develop
git checkout featureB
git rebase origin/develop
git push origin featureB
此时我们收到错误:
machine /c/Work/ (featureB)
$ git push origin featureB
To https://github.com/x.git
! [rejected] featureB -> featureB (non-fast-forward)
error: failed to push some refs to 'https://github.com/x.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
为什么会这样?
我们认为featureB
上的origin/develop
(现在合并后包含featureA
)会使featureB
准备推送。但显然我们看错了。
答案 0 :(得分:4)
解释所发生事情的最简单方法是查看您的回购历史。以下是您的历史看起来像合并前的(简略版本):
*--*--*--* [develop, origin/develop]
\
*--*--* [featureA, origin/featureA]
\
A--B--C [featureB, origin/featureB]
合并后:
*--*--*--*---------* [develop, origin/develop]
\ /
*--*--*
\
A--B--C [featureB, origin/featureB]
然后,您将featureB
重新定位到develop
:
*--*--*--*---------* [develop, origin/develop]
\ / \
*--*--* A'--B'--C' [featureB]
\
A--B--C [origin/featureB]
此处,A'
,B'
和C'
分别包含与A
,B
和C
相同的更改, 但它们不是相同的提交,因为A'
具有不同的父提交。
因此,在每次rebase之后,你必须强制推动重新分支的分支:
git push --force-with-lease origin featureB
(--force-with-lease
确保自上次提取以来没有新的提交被推送。虽然这里可能没有严格要求,但养成使用{{1}的习惯是很好的。 }}。)
如我上一张图所示,只要分支(例如--force
)及其远程跟踪分支(例如featureB
)发生分歧,就必须强制推送。因此,只要您已经将已经推送到遥控器的分支重新定位,就需要这样做。