dee*_* zg 2 git github git-rebase
我们有一个工作流程,其中只有一名团队成员在多个功能分支上工作。工作是这样的,下一个分支都依赖于他之前所做的分支。默认分支是develop.
我们来说说这个场景:
featureA分支,完成工作,推送分支,并在 GitHub 上创建 PRfeatureB分支(基于featureA一个分支),进行工作并进行公关featureC分支,(基于featureB)做工作并公关它featureD分支,(基于featureC)做工作并公关它尚未合并任何 PR。
现在,项目经理介入并开始合并。合并走这样的路:
featureA开发他这边的开发人员这样做:
git checkout develop
git fetch origin
git rebase origin/develop
git checkout featureB
git rebase origin/develop
git push origin featureB
Run Code Online (Sandbox Code Playgroud)此时我们得到错误:
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.
Run Code Online (Sandbox Code Playgroud)
为什么会出现这种情况?
我们认为变featureB基origin/develop(现在合并后包含featureA)将为featureB推送做好准备。但显然我们看到了一些问题。
解释发生的情况的最简单方法是查看存储库的历史记录。这是合并前您的历史记录(的删节版本):
*--*--*--* [develop, origin/develop]
\
*--*--* [featureA, origin/featureA]
\
A--B--C [featureB, origin/featureB]
Run Code Online (Sandbox Code Playgroud)
以及合并后:
*--*--*--*---------* [develop, origin/develop]
\ /
*--*--*
\
A--B--C [featureB, origin/featureB]
Run Code Online (Sandbox Code Playgroud)
然后你重新featureB基于develop:
*--*--*--*---------* [develop, origin/develop]
\ / \
*--*--* A'--B'--C' [featureB]
\
A--B--C [origin/featureB]
Run Code Online (Sandbox Code Playgroud)
这里,A'、B'、 、分别包含与、、 和C'相同的更改,但它们不是相同的提交,因为具有不同的父提交。ABCA'
因此,在每次变基之后,您必须强制推送变基分支:
git push --force-with-lease origin featureB
Run Code Online (Sandbox Code Playgroud)
(这--force-with-lease确保自上次获取以来没有推送任何新提交。虽然这里可能并不严格需要它,但最好养成使用它的习惯--force。)
正如我的上一张图所示,只要分支(例如featureB)及其远程跟踪分支(例如origin/featureB)出现分歧,您就必须强制推送。因此,每当您重新定位已推送到远程的分支时,您都需要执行此操作。