2

让我们考虑与远程同步的本地 git 存储库中的以下场景:

──(A)──┬──(B)── 大师
      │
      └─(C)── 分公司

在将分支合并到 master 之后(在本地,由于 (C)= many commits 需要很长时间):

──(A)──┬──(B)──┬──(D)── 大师
      │ │
      └─(C)─┘分公司

在合并期间,这发生在远程存储库上:

──(A)────(B)────(E)── 大师

现在,我想要这个结果:

──(A)──┬──(B)──┬──(D)──(E)── 大师
      │ │
      └─(C)─┘分公司

或者这个结果

──(A)──┬──(B)──(E)──┬──(F)── 大师
      │ │
      └────(C)────┘分公司

即我不想要更多的合并行。是否可以通过再次合并很多东西(C)而不花费很长时间来做到这一点?

4

2 回答 2

1

如果有人将代码推送到您的遥控器,看起来像这样

──(A)───(B)───(E)── master

那么这就是公共历史,您不应该重写它,除非与您一起从事该项目的其他开发人员对此表示满意,并且不会因为必须将他们的工作与新的重写历史同步而感到困扰。如果他们不同意你重写他们的历史,那么你不应该这样做

──(A)─┬─(B)─┬─(D)──(E)── master
      │     │
      └─(C)─┘  branch

因为 thenE变成了Dinstead of的孩子B,这不是公共历史中的内容。

在这种情况下,大多数人会做的就是通过硬重置在本地撤消合并,然后根据远程 master 的新提示重新合并或变基。假设您只是重新合并,那么您的历史将如下所示,正如您所描述的:

──(A)─┬─(B)───(E)─┬──(F)── master
      │           │
      └────(C)────┘  branch

或者你可以 rebase CagainstE以获得更线性的东西,像这样:

───(A)───(B)───(E)───(C')── master

但是,如果没有更多信息,我将无法帮助您找到避免合并C花费这么长时间的方法,我不知道您为什么会遇到这个问题。

于 2013-08-02T11:34:21.713 回答
0

没有一种简单的方法可以做你想做的事。如前所述,大多数时候人们只会撤消合并并根据上游分支的新状态重做它。但这是可以完成的。

如果您当前有一个master分支,该分支将您的合并作为最新提交并且具有其他人的最新开发,您可以执行以下操作以使其看起来像是在当前版本而不是旧版本origin/master之上进行了合并:origin/master

git checkout master
git branch savepoint
git merge -m temporary origin/master
git reset --hard $(git show --pretty=format:%B 'HEAD^' | git commit-tree -p 'HEAD^2' -p 'HEAD^^2' -F - 'HEAD^{tree}')

那里的可见合并将创建一个额外的合并提交,但这将随着以下命令而消失。该合并仅用于获得存储库内容的所需最终状态。

最后一个命令是复杂的。该commit-tree部分创建另一个合并提交,其中包含提交 E 和 C 作为父级,由先前的合并操作创建的存储库内容,以及来自您之前完成的合并的提交消息(感谢show命令和 -F -选项)。然后reset导致这个新的合并提交成为新的状态。这应该为您提供所需结果的第一个选项,并且不会重写任何已共享的历史记录。

由于这种用途git reset --hard,这将消除任何未提交的更改。savepoint创建分支只是为了方便备份到起点以防万一出现问题。

于 2013-08-02T12:38:16.670 回答