好吧,我以为这是一个简单的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
工作维护远程备份。到目前为止,我们都很好。
但现在我想在主服务器上F--G
提交的基础上重新设置feature
的基数,因此我选择git checkout feature
和git rebase master
。还是很好。现在我们有:
A--B--C------F--G (master)
D'--E' (feature)
**问题:**当我想备份git push origin feature
分支的新改基feature
时,推送被拒绝,因为改基导致树发生了变化。这只能用git push --force origin feature
解决。
我讨厌在不确定自己是否需要的情况下使用--force
。那么,我需要它吗?重新设定基准是否“必然”意味着下一个push
应该是e1d19d1ful?
这个功能分支不会与任何其他开发人员共享,所以我对强制推送没有问题,我不会丢失任何数据,问题更多的是概念性的。
14条答案
按热度按时间xoefb8l81#
问题是,
git push
假设远程分支可以快进到您的本地分支,也就是说,本地分支和远程分支之间的所有区别在于本地分支在末尾有一些新的提交,如下所示:当您执行
git rebase
提交时,D和E将应用于新的基并创建新的提交。这意味着在重新建立基地后,你会得到类似的东西:在这种情况下,远程分支不能快进到本地。虽然从理论上讲,本地分支可以合并到远程(显然在这种情况下您不需要它),但由于
git push
只执行快进合并,因此会抛出错误。--force
选项所做的只是忽略远程分支的状态,并将其设置为您正在推送的提交。因此,git push --force origin feature-branch
只需用本地feature-branch
覆盖origin/feature-branch
。在我看来,在
master
上重新设置特性分支的基础并强制将它们推回远程存储库是可以的,只要您是唯一一个在该分支上工作的人。9rnv2umw2#
与使用
-f
或--force
相比,开发人员应该使用为什么?因为它会检查远程分支的更改,这绝对是个好主意。让我们假设James和Lisa正在开发相同的功能分支,而Lisa已经推送了一个提交。詹姆斯现在重新部署了他的当地分支机构,当试图推进时被拒绝。当然,詹姆斯认为这是因为重新设置了基址,并使用了
--force
,并会重写Lisa的所有更改。如果James使用了--force-with-lease
,他会收到一个警告,告诉他有其他人执行了提交。我不明白为什么有人会在改版后使用--force
而不是--force-with-lease
。siotufzp3#
我会使用“check out-b”,这样更容易理解。
当您删除时,您会阻止推入包含不同SHA ID的现有分支。在这种情况下,我只删除远程分支。
h7wcgrx34#
一种解决方案是像msysGit的rebasing merge脚本所做的那样-在重新基址之后,将
feature
的旧头与e1d1e合并。您最终得到了提交图:..。而你的
feature
推送将是快进。换句话说,您可以执行以下操作:
(没有经过测试,但我认为这是正确的…)
2ledvvac5#
其他人已经回答了你的问题。如果你改变一个分支的基数,你将需要强制推入该分支。
Rebase和共享存储库通常相处不好。这是在改写历史。如果其他人正在使用该分支或从该分支分支,那么重新定基将是非常不愉快的。
总体而言,Rebase适用于本地分支机构管理。远程分支管理最适合使用显式合并(--no-ff)。
我们还避免将主文件合并到功能分支中。相反,我们使用新的分支名称(例如,添加一个版本后缀)重新设置为主版本。这避免了在共享存储库中重新建立基础的问题。
vxqlmq5t6#
这个分支上可能只有一个开发人员,也可能不是。
因此,我建议使用以下顺序:
是的,新的分支机构,这应该可以在没有--武力的情况下解决这个问题,我认为这通常是一个主要的缺点。
tzxcd3kk7#
我避免强制推送的方法是创建一个新分支,并继续在该新分支上工作,在一些稳定之后,删除重新建立基础的旧分支:
aiqt4smr8#
feature
分支上的git merge master
有什么问题?这将保留您已有的工作,同时将其与主线分支分开。**编辑:**我很抱歉没有阅读您的问题声明。当您执行
rebase
时,您需要用力。所有修改历史记录的命令都需要--force
参数。这是一种故障保护措施,可以防止您丢失工作(旧的D
和E
会丢失)。因此,您执行了
git rebase
,使树看起来像(尽管部分隐藏,因为D
和E
不再位于命名的分支中):因此,当尝试推送新的
feature
分支(其中包含D'
和E'
)时,您将丢失D
和E
。bnl4lu3b9#
对我来说,以下简单的步骤很管用:
完成上述操作后,我们还可以通过以下命令删除myFeature分支:
kq0g1dla10#
以下内容对我来说很管用:
git push -f origin branch_name
而且它不会删除我的任何代码。
但是,如果您想要避免这种情况,则可以执行以下操作:
然后你可以挑选你所有的承诺给新的分支机构。
git cherry-pick COMMIT ID
,然后按下您的新分支。hfwmuf9z11#
获取主文件的新更改,并在最新的主文件上重新设置要素分支的基础
yqyhoc1h12#
因为行动组确实理解这个问题,只是寻找一个更好的解决方案。
这个练习怎么样?
此方法可能已有模式名称。
biswetbf13#
我会做如下所示
现在遥控器将具有功能(基于最新的主控器)和功能2(具有旧的主控头)。这将允许你在以后比较你在解决冲突时是否犯了错误。
tjvv9vkg14#
要在REBASE之后将更改推送到分支,您需要在Git上的git推送命令中使用-f或--force标志强制推送提交。
可以这样做,
在GIT重新基址后,推送提交到分支
这是因为远程分支中的某些内容已更改,并且远程分支和本地分支的提交历史记录都不同。
如果您试图推送本地更改,GIT将拒绝它,并显示一条消息,如您当前分支的尖端在其远程分支之后。对本地分支进行强制推送可以解决问题。
别害怕。如果您是唯一一个在同一分支上工作的人,这是一个很好的方法。👍🏽