4

我们将称为 Aaron 的同事被指派对网站的一个部分进行翻新,作为一项长期项目。他创建了一个新的 Git 分支,名为aaron. 他所有的更改都是在这个分支上进行的。在他工作期间,我继续维护整个站点,将我的更改提交到master.

最终,Aaron 将他的分支合并到master. 这以某种方式恢复了我master在合并时间和aaron首次创建分支时间之间所做的所有提交。如果我键入git show <hash of merge commit>,我可以看到我在 Aaron 在他的分支上工作时更改的每个文件的差异。这些差异显示了我所做的每一个更改的还原。master如果 Aaron 手动将其分支上每个文件的内容复制到并提交更改,它看起来就像这样。(他没有这样做。我只是想说明日志显示的内容。)

据亚伦说,他没有做任何奇怪的事情。他说他刚刚跑了git pull origin/aaron

是什么原因造成的?是否有可能git pull origin aaron将我的所有更改恢复为master

另外,有没有一种简单的方法可以在不恢复他所有工作的情况下恢复我对 master 所做的更改?

编辑1:

更改master并在合并后恢复的文件之一是foo.txt. 所以我这样做了:

git checkout aaron
git log foo.txt

日志不反映创建分支foo.txt后的任何更改。aaron我有点期待在分支的日志中某处看到我的更改的恢复aaron,但我没有。那么,这是否是亚伦所做的其他事情的最终证据,而不是他声称所做的简单拉动?

编辑2:

我说过他打字origin/aaron,但他实际上打字origin aaron。我在上面改了。

编辑 3

根据下面的建议,我选择通过重写历史来解决这个问题。在这一点上,我确信问题是由错误的解决冲突的尝试引起的。

4

2 回答 2

5

git pull origin/aaron做到这一点的唯一方法是,如果他有一个从masteraaron第一个的合并,则丢弃所有的更改master(也许通过使用git merge -s ours master)。

去查历史。是否有任何以前的合并 from masterinto aaron?他们会丢弃master的更改吗?如果没有,那唯一的解释就是他没有git pull origin/aaron

至于恢复更改,您可以退出他的合并并自己重新创建。这将修改历史记录,但如果您对此表示满意,这是最简单的解决方案。如果您对此不满意,那么它会变得稍微复杂一些。在这种情况下,您需要创建一个临时分支,退出他的合并,然后正确地重新合并。然后回到 master 并运行git read-tree tempbranch。这将使用临时正确合并的结果更新您的索引 [1],然后您可以提交此操作。

[1]:请注意,这不会修改您的工作树,因此您需要使用类似git checkout -- ..

于 2013-01-17T22:12:38.843 回答
2

鉴于所有更改都发生在合并提交中,您会看到所谓的邪恶合并。 man gitglossary以这种方式定义它:

       evil merge
       An evil merge is a merge that introduces changes that do not appear in any
       parent.

在这个答案中有一个关于这意味着什么的解释。对您来说重要的是,这不是 git 自己会做的事情。创建一个邪恶的合并需要以某种方式进行人工干预。

我通常看到它发生的地方是有人进行合并并因冲突而感到困惑。例如,可能导致这种情况的一件事是,如果 aaron 开始他的 pull,被冲突所淹没,并决定通过将他的文件复制到现有文件之上来解决冲突是安全的。当他在执行此操作后进行合并提交时,您会看到这一点。

至于修复它,如果可以的话,我会按照Kevin Ballard的建议去做。 git -reset --hard主分支回到它在合并之前的样子,然后重做合并。

于 2013-01-18T20:41:40.160 回答