Git分支在重新设置后分叉


112

我已经本地化了已经推送的分支。

Git建议我的分支机构和远程机构出现分歧,并且:

“并且分别具有109和73个不同的提交”

推送我的分支机构是否可以解决此问题-即在重新设置基准后是否可以预期?


我有同样的问题。我们能否说“正确的做法”是重新建立本地分支机构,然后再推送?
Mher Didaryan '18

Answers:


154

在为分支重新设置基础时,必须为要重新定基础的分支中的提交之上的任何提交重写提交。这是因为提交的属性之一是其父级(或多个父级)。重新设定基准时,您将更改分支上最旧的本地提交的父级-并因此更改所有本地提交的提交哈希,因为此更改会在传递过程中不断冒泡。

由于您已经推送了分支,因此您应该已经合并到源分支中,而不是根据它进行基础调整。可以“强制推送”新分支(使用该-f标志),但是正常的推送将不起作用,因为分支历史记录的完整性会受到干扰。如果您正在与这个分支上的其他人协作,那么强行推销是个坏主意,因为当其他协作者的历史突然不匹配时,这将使其他协作者变得非常困惑。

TL; DR-如果不进行协作,请使用push -f推送分支。如果是这样,请将分支重置为先前的状态,然后合并到源分支中。


1
“既然已经推送了分支,那么您应该已经在源分支中合并了”-为什么?
hammett 2014年

1
@HamiltonVerissimo Jason的第一句话:“在为分支建立基础时,必须为要重新建立基础的分支中的提交之上的任何提交重写提交。” 即使在“以上”提交中捕获的更改具有相同的逻辑内容,它们仍被应用于不同的基础,因此是具有不同哈希值的不同提交。如果其他开发人员正在从重新定位的分支中进行工作,那么执行git push -f将极大地破坏他们的工作流程。因此,由于该分支机构已被推到公共资源,他应该已经合并。
awolf

4
如果不确定其他人是否已经推送过某些内容,则也可以使用push --force-with-lease。
控制台

1
@ jason-lebrun合并上游更改,您可以在没有警告的情况下覆盖自己的工作,这不是不利之处吗?是否以与重新定基时相同的方式检测到合并冲突?例如,如果我因为不再需要从分支中的文件中删除某节,而其他人对上游的同一节进行了小改动,例如删除了一些空白或某些全局查找/替换操作,则不会合并到我的分支顶部,将我的删除内容替换为琐碎的版本?
克里斯·布鲁姆

1
将另一个分支合并到您的分支中不是一个坏主意吗?例如,将master合并到功能分支中-会不会为此创建新的提交?如果以后合并到master,此功能分支一旦出现,是否会导致额外的提交?
罗斯

55

您的所有提交都更改了id,因此转移并不是真正的分歧。

为了解决您的问题,您必须覆盖您的远程分支:

git push -f origin experiment

http://git-scm.com/book/ch3-6.html

说明:

看到在此图像中,如何将C3放到重定基准之后而不是C3上,而是放到C3'上。这是因为它不完全是C3,但是它具有所有代码更改。

变基

在另一幅图像上,您可以看到当涉及到远程控制器时看到的基准变迁以及为何发生转移的情况。

发散和git push

无论如何,在执行强制推送之后,它将告诉您它进行了(强制更新),此时您应该可以。

检出顶部的链接,然后搜索“ git push --force”。您将看到更详细的说明。


3
对。我想这解决了问题。但是,当您与团队一起工作时,强制推送可能无法覆盖他人最近推送的任何最新工作。我对吗?
哈里·克里希纳·甘吉2014年

它可能没有理想的效果。在进行基础调整之前,请确保“快速前进”合并更改。
mimoralea 2014年

1

通过执行以下操作,我成功地推动了rebase的分歧:

git checkout mybranch
git pull
git push origin mybranch

拉动解决了分歧。

拉之前

Your branch and 'origin/mybranch' have diverged,
and have 2 and 1 different commit(s) each, respectively.

拉输出

递归合并。mypath / myfile.py | 12 +++++++++++-1个文件已更改,11个插入(+),1个删除(-)

拉后

您的分支比“ origin / mybranch”提前3次提交。

推后

mybranch在分支之前3,仍然有一个打开请求请求合并消息添加到提交历史记录中,将分支的mybranch合并到remote

我以为这可能是推力所做的,我尚未验证。

正如其他人所说,如果您已经有一个开放的拉取请求,请避免重新设置基准。我提供此示例是对我有用的东西。


1

可以通过以下方法解决此问题:将目标分支重新部署到当前本地分支,切换到目标分支,然后将本地分支重新部署到目标,而无需强制执行。这不会发散,因为添加了可能丢失的提交,并且不再需要创建。为了更容易解释的示例:

  1. 主要分支正在发展
  2. 您签出新的分支功能/ doing_stuff
  3. 团队成员推动开发的新承诺

如果尚未更新您的develop分支,则“ git checkout开发”和&“ git rebase功能/ doing_stuff”将正常工作,因为自从签出以来未添加任何提交。但是,如果您签出了development并撤消了新的提交,那么由于尝试看到新的提交而尝试进行基础调整时,您将看到这种差异。一个简单的解决方法,而无需用力推动(在团队环境中通常不是一个好主意)是:

  1. git checkout 功能/ doing_stuff
  2. git rebase 开发
  3. git checkout 开发
  4. git rebase 功能/ doing_stuff

步骤2的重新设置将缺少的提交提交到feature / doing_stuff中,因此当步骤4进行时,它是最新的,不需要为更改创建新的提交。

我知道这是一个可行的解决方案,因为我只是碰到了这个问题,并且执行了上述步骤以成功推动开发而无需强迫。我的团队由50多个开发人员组成,因此除我自己的测试分支外,禁止强加任何其他操作,因此我必须找到解决方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.