无法在其他用户的分支贡献之后进行gase rebase

时间:2015-10-02 08:21:11

标签: git github version-control git-rebase git-rewrite-history

我遇到了将主开发分支master重新定位到我的功能分支crm-feature的问题。

我尝试使用git rebase master crm-feature

的常规方法执行此操作

当我这样做时,我发现当每个提交都成为冲突时,我会在rebase中找到某个点。

查看Github中的提交列表,我看到所有 my 提交(由我创作),然后从其他人提交,然后我的所有提交似乎都因某种原因而被重新创建。所有这些提交都显示如下:

enter image description here

因此,从最新到最旧,我的提交日志如下所示:

  • 其他贡献者piccolax00承诺
  • 其他贡献者piccolax00承诺
  • 我的所有作者都提交了piccolax00用户提交的内容,如上图
  • 其他贡献者的提交
  • 我原来的提交

总而言之,我不明白piccolax00用户提交的内容以及我如何处理它们,因为它们似乎阻止我将我的分支重新定位到master。在我度假的时候分支机构已经处理好了,在我离开之前我的所有提交都坐在顶部,因为我定期在master进行调整,以便从主开发部门给我最新的代码,同时重播我的工作。每一次都是。

我不确定分支是否已经被piccolax00用户重新定位,如果是这样的话,我的选择是什么?

2 个答案:

答案 0 :(得分:1)

鉴于所提供的信息,我将对如何解决您的问题采取有根据的猜测。

警告:此解决方案涉及重写存储库的历史记录,如果您不小心,可能会导致数据丢失。 在继续之前备份您的存储库。

在Git中制作备份仓库的最简单方法是简单地克隆另一个本地仓库,并在出现问题时从该备份恢复。

(可能)存储库的状态

根据您的描述,您的存储库和协作者的状态看起来像这样:

# Collaborator history
aaa - ooo - AAA - bb

# Your history
aaa - ccc

其中

  1. a代表您的提交,
  2. o表示来自其他用户的提交
  3. A代表您重写的提交(基于之前的a提交),
  4. b表示piccolax00的提交,
  5. c表示您尚未推送到共享上游回购的新提交。
  6. 一种解决方案

    假设上述情况属实,并且提交o尚未被重写(即A是唯一重写的提交),那么您可以使用的一个解决方案是重建正确的历史使用硬复位和选择性重新定位的历史。

    拼接您的协作者分支

    首先,我们将从您的协作者分支的本地副本中拼出A次提交(我们称之为piccolax00),

    1. 开始在历史记录中最新的newBase提交创建分支o,并在最近的oldBase提交时创建分支A

      git checkout piccolax00
      git branch newBase o
      git branch oldBase A
      
    2. 接下来,将一系列b提交重新绑定到newBase分支(即o提交),

      git rebase --onto newBase oldBase piccolax00
      

      您可能需要重新解决可能发生的冲突。

    3. 执行上述操作后,假设任何冲突都没有解决,那么您的协作者的piccolax00分支将如下所示,

      aaa - ooo - bb
      

      作为一个完整性检查,使用

      来区分旧历史也是一个好主意
      git diff piccolax00@{1}
      

      其中piccolax00@{1}是指执行rebase之前piccolax00分支的状态。如果piccolax00piccolax00@{1}一角的代码状态相同,则rebase没有在代码中引入任何错误。

      将您的新提交拼接在最上面

      理论上,我们执行的早期步骤恢复了上游分支的“正确”历史记录,因此执行正常的rebase应该使分支与其同步,

      git checkout crmpicco
      git rebase piccolax00
      

      然后你的历史会是这样的,

      aaa - ooo - bb - ccc
      

      然后,您需要强制将此新历史记录推送到上游,因为您已经重写了大量提交,因此它们不再具有与以前相同的sha ID。

      警告:要非常小心强制重写共享历史记录。如果您的其他任何协作者已经将提交添加到piccolax00推送的旧共享历史记录中,那么他们需要将他们自己的本地版本的共享历史记录与您推送的任何内容同步好吧(可能是通过更多的反叛)。

      这就是为什么重写共享历史经常不受欢迎的原因,如果项目的贡献者不正确地从中恢复,可能会很费时间。

      无论如何,如果您确定要继续推送重写的共享历史记录,请执行

      git push -f upstream crmpicco
      

      其中upstream是远程共享仓库,crmpicco是您要推送的分支。

      其他解决方案

      上述解决方案完全有可能无法解决您的问题。如果没有更多信息,我无法真正帮助您,但如果您遇到困难,可以torek suggested进行调查,并调查--fork-point是否会对您有所帮助,

        

      寻找“从上游转基因中恢复”。 Git的新(ish,2.0左右) - fork-point计算很有帮助。

      其他资源

答案 1 :(得分:0)

我会发布这个帖子,因为我最终被建议采取与@Cupcake提供的方法略有不同的方法。希望这将有助于未来的人。

在命令方面,我做了以下几点:

# made a backup of the branch incase I screw it up during the rebase
git checkout -b crm-feature-branch-original crm-feature-branch

# Rebase my branch onto master and replay my commits on top
git rebase -i crm-feature-branch master

在交互式rebase期间,我删除包含已复制的提交的行。我可以通过查看Github中的哈希值来判断要删除哪些提交,而不是pick

我遇到了一些冲突,但是我们预计这些冲突不会与我最初的数量相差无几。