2

场景:

我正在与一个 20 多人的团队一起开发一个远程 git 存储库。经常创建、提交和合并分支以掌握分支。

我和一位同事在一个分支上一起工作了几天。他重新设置了分支,解决了所有冲突并推送。

当我尝试拉取时,我得到“自动合并失败”并提示解决所有冲突。

当我“git status”时,我发现我有不同的起源/分支,并且每个都有超过 100 个不同的提交。

问题:

他有我迄今为止的所有提交,刚刚重新定位然后推送,如果我继续合并,我可能会重做他已经完成的冲突解决。

问题

这里发生了什么?

该怎么办?为什么?

旁白

我已经阅读了大量关于 git 的内容,仍在学习,并希望得到一个直接的答案,与 git 逻辑有关,而不是与相关的命令有关。

先感谢您。

4

2 回答 2

8

不,那无法做到(回答问题标题中的问题)。

在通过推送、拉取或克隆与其他人共享变更集之前,应进行变基。

问题示例,一名程序员提交了 5 个变更集:

(1)---(2)---(3)---(4)---(5)

这些变更集与另一个开发人员共享,该开发人员最初有一个仅包含第一个变更集的克隆,因此他的存储库中有自己的变更集。一旦他拉或你推,这就是他所拥有的:

(1)---(2)---(3)---(4)---(5)
  \
   \
    (A)---(B)---(C)

由于他想要一个线性历史,他将你的变更集重新设置在他的基础上,得到这个:

(1)---(A)---(B)---(C)---(2')---(3')---(4')---(5')

请注意,我现在在他的存储库中用勾号标记了您的变更集,以表明它们是“您的”变更集,但现在受到他早期更改的影响,因此不再与您的相同(哈希或其他方式)。

然后你拉,这就是你得到的:

(1)---(A)---(B)---(C)---(2')---(3')---(4')---(5')
  \
   \
    (2)---(3)---(4)---(5)

现在你有了这些变更集的两个“副本”。

如果您在存储库中的第 5 个变更集之后还没有做任何事情,您可能可以将它们从存储库中删除,但标记那个词,“可能”,它带有您知道存储库状态的强烈要求,并且您需要了解存储库的每个克隆。

在一切都回到糟糕的状态之前,只需要一次 pull-merge-push。

结论:除非您知道自己在做什么,否则不要重新设置变更集,并且几乎可以肯定不要重新设置共享的变更集。

实际上:该警告应该反对所有形式的历史重写。任何重写历史的事情都必须单独完成,并且所有克隆都必须无效,否则您将拥有不同的历史和受影响变更集的多个“副本”。你不想在这里!

于 2013-07-16T19:56:27.587 回答
2

什么LasseV。卡尔森说没事。由于他重新设置了分支,因此您无法真正拉动它并重新合并所有内容。

如果您没有更多“新”提交,只需删除您尝试拉取的分支并拉取它。由于您的所有变更集都存在,只需将您的分支重置为与服务器上的完全相同,然后从那里继续。如果你有新的提交,那么它会有点困难。

首先创建分支的副本:

git checkout [branch]
git checkout -b branchCopy

删除分支(如果由于未合并而不想删除分支,请使用 -f)

git checkout -d branch

获取服务器上的内容(来源可能是不同的远程)并使用服务器上的内容重新创建分支

git fetch [origin]
git checkout origin/branch
git checkout -b branch

现在你将拥有branch并且branchCopy

使用 git log,检查要添加到分支的提交。并用于cherry-pick添加它们

git checkout branch
git cherry-pick "commit"

添加所有未合并的提交后,只需推送到服务器。并删除“branchCopy”

如果您在 branchCopy 和分支之间有很多不同的变更集。我想有一种方法可以重新调整一组提交的基础,branchCopybranch如果你只是重新调整它。它将添加所有更改,因为复制的提交具有不同的哈希值。

所以是的,除非你知道自己在做什么,否则不要变基。如果你想变基并与很多人一起工作。最好的办法是确保每个人都知道你正在变基。

我想任何好的时间旅行者的第一条规则是“不要改变历史”

小费

这是使时间旅行比以往更安全的提示。在工作中,我使用了这个流程:

在我的功能分支上工作,并在完成后合并到 master 中。

当你在你的分支上工作时,它几乎可以保证你不会对 master 分支上的提交进行 rebase。完成后,您必须做出选择。您可以在 master 中合并您的分支或在 master 上重新设置您的分支。

如果您正在重新定位您的分支,您将必须获取最后一个主提交并在它的基础上重新定位并尽可能快地推送它。当人们拉它时,它应该仍然快进,因为你没有改变 master 的历史,而是你的分支的历史。

不过说实话,用了bitbucket之后,(关于github就不能多说了)。我处理拉取请求。即使分支是快进的,它也会进行合并提交,在大多数情况下避免变基可能会更容易。Pullrequest 是一个很棒的创作,如果您使用具有它的系统,应该使用它。

它可能会创建一个合并提交,但它会留下合并提交的历史记录,由谁以及您可以评论它们。人们可以处理要合并的功能,并且有人可以在需要时使用拉取请求来审查代码并将代码合并到主代码中。

于 2013-07-16T20:08:52.080 回答