【问题标题】:Git branch diverged after rebase变基后 Git 分支分歧
【发布时间】:2013-09-25 23:10:21
【问题描述】:

我已经在本地重新设置了一个已推送的分支。

Git 建议我的分支和远程分支已经分道扬镳,并且:

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

推送我的分支会解决这个问题吗?也就是说,在 rebase 之后会出现这种情况吗?

【问题讨论】:

  • 我也有同样的问题。我们可以说“正确的做法”是 rebase 本地分支然后再推送吗?

标签: git


【解决方案1】:

当你变基一个分支时,你必须重写任何高于你变基的分支中的提交的提交。这是因为提交的属性之一是它的父级(或父级)。当您变基时,您正在更改分支上最旧的本地提交的父级 - 从而更改所有本地提交的提交哈希,因为此更改通过提交传递。

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

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

【讨论】:

  • “既然你已经推送了分支,你应该已经合并到源分支” - 为什么?
  • @HamiltonVerissimo Jason 的第一句话:“当你变基一个分支时,你必须为任何高于你变基的分支中的提交重写提交。”即使在“上述”提交中捕获的更改具有相同的逻辑内容,它们被应用于不同的基础,因此是具有不同哈希值的不同提交。如果其他开发人员正在使用 pre-rebased 分支工作,那么执行 git push -f 将对他们的工作流程造成极大的破坏。因此,既然这个分支已经被推送到公共资源,他应该合并。
  • 如果你不确定其他人是否已经推送了某些东西,你也可以使用 push --force-with-lease。
  • @jason-lebrun 合并上游更改不是不利的一面,您可以在没有警告的情况下覆盖自己的工作吗?合并冲突的检测方式与重新定位时的方式相同吗?例如,如果我从我的分支中的文件中删除了一个部分,因为它不再需要,但是其他人对上游的同一部分进行了微不足道的更改,例如删除一些空格或一些全局查找/替换操作,则不会将其合并到我的分支之上,将我的删除替换为他们细微更改的版本?
  • 将另一个分支合并到你的分支不是一个坏主意吗?例如。将 master 合并到一个特性分支中——这不会为此创建一个新的提交吗?如果稍后合并到 master,一旦此功能分支不会导致额外的提交?
【解决方案2】:

你所有的提交都改变了 id,所以转移并不是真正的分歧。

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

git push -f origin experiment

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

说明:

看看在这张图片中,C3 在变基之后不是作为 C3,而是作为 C3'。这是因为它不完全是 C3,但它的所有代码都发生了变化。

在另一张图片上,您可以看到当涉及远程时看到的变基,以及为什么会有转移。

无论如何,在你进行强制推送之后,它会告诉你它进行了(强制更新),此时你应该没问题。

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

【讨论】:

  • 是的。我想这可以解决问题。但是,当你在团队中工作时,强制推送可能不起作用,因为你的推送可能会覆盖其他人最近推送的任何工作。我说的对吗?
  • 它可能没有想要的效果。确保在执行 rebase 之前“快进”合并更改。
【解决方案3】:

通过执行以下操作,我成功实现了 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.

拉出输出

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

拉后

您的分支比 'origin/mybranch' 领先 3 次提交。

推后

mybranch 比分支领先 3,仍然有一个打开的拉取请求 合并消息添加到提交历史 将远程分支 mybranch 合并到 mybranch 中

我假设这可能是强制推送的作用,但我尚未验证。

正如其他人所说,如果您已经有一个开放的拉取请求,请避免变基。我提供了这个例子,作为对我有用的东西。

【讨论】:

    【解决方案4】:

    通过将目标分支重新定位到当前本地分支,切换到目标分支,然后将本地分支重新定位到目标,可以在不强制推送的情况下解决此问题。这不会产生分歧,因为可能缺少的提交已添加并且不再需要创建。更容易解释的例子:

    1. 主分支是develop
    2. 您签出了一个新分支feature/doing_stuff
    3. 团队成员将新提交推送到 develop

    如果您还没有更新您的开发分支,那么“git checkout develop”&&“git rebase feature/doing_stuff”将正常工作,因为自您结帐以来没有添加任何提交。但是,如果您已签出开发并取消了新提交,那么如果您由于看到新提交而尝试重新设置基准,您将看到这种差异。无需强制(在团队环境中通常不是一个好主意)的简单解决方法是:

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

    第 2 步中的变基将丢失的提交带入功能/doing_stuff,因此当第 4 步出现时,它是最新的,不需要为更改创建新提交。

    我知道这是一个可行的解决方案,因为我刚刚遇到了这个问题并执行了上述步骤以成功推动开发而无需强制。我在一个由 50 多名开发人员组成的团队中工作,因此禁止强制推送除我自己的测试分支以外的任何内容,因此我必须找到解决方案。

    【讨论】:

      猜你喜欢
      • 2013-03-27
      • 1970-01-01
      • 2016-09-20
      • 1970-01-01
      • 2015-03-28
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      • 1970-01-01
      相关资源
      最近更新 更多