【问题标题】:Git pull reverted commits in master?Git拉回master中的提交?
【发布时间】:2013-01-01 13:49:05
【问题描述】:

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

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

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

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

另外,有没有一种简单的方法可以将我的更改恢复到 master 而不恢复他的所有工作?

编辑 1:

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

git checkout aaron
git log foo.txt

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

编辑 2:

我说他输入了origin/aaron,但他实际上输入了origin aaron。我在上面改了。

编辑 3

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

【问题讨论】:

  • 如果您使用 gitk 查看日志,Aaron 的合并提交中是否列出了已更改的文件?
  • 是的,所有恢复的文件都被列为已更改。差异非常清楚地表明了这一点:对于我对 master 所做的每一次更改,差异中都有一个部分在还原更改。 (即您可以看到各个行被改回。)
  • 哎呀,错过了你所说的。

标签: git branch git-branch branching-and-merging


【解决方案1】:

git pull origin/aaron 执行此操作的唯一方法是,如果他首先从 master 合并到 aaron,这会丢弃 master 上的所有更改(可能通过使用 git merge -s ours master)。

去查历史。之前是否有从 master 到 aaron 的合并?他们会放弃master 的更改吗?如果没有,那么唯一的解释是他没有运行git pull origin/aaron。

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

[1]:请注意,这不会修改您的工作树,因此您需要使用git checkout -- . 之类的内容来跟进。

【讨论】:

  • 谢谢!我刚刚编辑了我上面的问题,以回应你所说的。你有什么想法?
  • @Jarrett:是的,我认为这意味着他所做的不仅仅是git pull origin/aaron。
  • 在最新版本的 git 中,git pull origin/aaron 不再有效。不过,这并不能解释这种情况。你看过亚伦的git reflog吗?
  • Looking at this question,它曾经等同于git merge origin/aaron。我开始为此起草一个问题,但仍然无法确定即使是过时的 origin/aaron 引用也会导致此问题。
  • @KevinBallard 实际上是git merge origin/foo,可能与foo 不同。事实上,如果其他人在origin 上推送到foo,并且我提交了foo 的本地副本并且没有以任何方式获取,那么foo、origin/foo 和foo 在@ 987654346@ 现在是 3 个不同的参考!
【解决方案2】:

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2014-06-07
    • 1970-01-01
    • 1970-01-01
    • 2022-07-19
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 2017-07-14
    • 1970-01-01
    相关资源
    最近更新 更多