好的,我认为这是一个简单的git场景,我错过了什么?
我有一个主分支和一个特征分支。我在master上做了一些工作,在feature上做了一些工作,然后在master上做了一些工作。我最终得到了这样的东西(字典顺序暗示了提交的顺序):
A--B--C------F--G (master)
\
D--E (feature)
我对git push origin master来保持远程master的更新没有问题,也没有git push origin feature(当在特性上时)来维护我的特性工作的远程备份。到目前为止,我们都很好。
但现在我想在master上的F- G提交的基础上rebase feature,所以我git checkout feature和git rebase master。还好。现在我们有:
A--B--C------F--G (master)
\
D'--E' (feature)
问题:当我想备份新的基于git的推源特性分支的重基特性时,推被拒绝了,因为树已经因为重基而改变了。这只能用git的push -force origin特性来解决。
我讨厌在不确定自己是否需要的情况下使用武力。那么,我需要它吗?调整基地是否意味着下一步的行动应该是强有力的?
这个功能分支并没有与其他开发者共享,所以事实上我对强制推送没有任何问题,我不会丢失任何数据,问题更多的是概念性的。
问题是git push假设远程分支可以快进到你的本地分支,也就是说,本地分支和远程分支之间的所有区别都是在本地有一些新的提交,就像这样:
Z--X--R <- origin/some-branch (can be fast-forwarded to Y commit)
\
T--Y <- some-branch
当你执行git rebase commit时,D和E会被应用到新的base并创建新的提交。这意味着在调整后,你会有这样的东西:
A--B--C------F--G--D'--E' <- feature-branch
\
D--E <- origin/feature-branch
在这种情况下,远程分支不能快进到本地。虽然,理论上本地分支可以合并到远程分支(显然在这种情况下你不需要它),但由于git push只执行快进合并,它会抛出一个错误。
force选项的作用是忽略remote branch的state并将它设置为你推入的commit。所以git push——force origin feature-branch只是用local feature-branch覆盖了origin/feature-branch。
在我看来,只要你是唯一在这个分支上工作的人,就可以在master的基础上重新构建特性分支,并强制将它们推回远程存储库。
git在特性分支上的合并主有什么问题?这将保留您的工作,同时使其与主线分支分离。
A--B--C------F--G
\ \
D--E------H
编辑:啊,对不起,没有读你的问题声明。当你执行重基时,你将需要力量。所有修改历史记录的命令都需要——force参数。这是防止您丢失工作的故障保险(旧的D和E将丢失)。
所以你执行了一个git rebase,使树看起来像这样(尽管部分隐藏,因为D和E不再在一个命名的分支中):
A--B--C------F--G
\ \
D--E D'--E'
所以,当你试图推动你的新特征分支(其中有D'和E')时,你会失去D和E。