发生了什么
你的意思是修订,而不是追加,对吗?为了方便起见,我假装这是在一个名为 master 的分支上。现在你的代码库看起来是这样的:
A---B' (master)
\
\-B---C---D
Git提交明确依赖于它们的父级 - 在不同父级上的相同补丁是不同的提交。
如何恢复
您可以通过以下几种方式恢复先前的位置。有一个很好的简写方式可以用来直接检查它或创建一个分支:
git checkout master@{1}
git branch oldmaster master@{1}
假设你要找的是第一个之前的位置,那么可以使用 master@{1}
。如果是第二个之前的位置 (master@{2}
),或者你知道具体时间,也可以使用 master@{7:35}
或 master@{23.hours.ago}
。有关这些形式的概述,请参见 man git-rev-parse
的 "specifying revisions" 部分 (在线文档)。
如果不确定如何到达它,请尝试以下方法:
git reflog show master
这将为您提供
master
以前位置的列表,您应该能够从描述中确定您想要的位置(或者尝试几个)。您可以直接从列表中复制哈希值,并像上面一样使用
git checkout
或
git branch
。
您应该做的事情
警告:如果已经发布,则编辑历史记录是一个坏主意 - 在这种情况下,您应该只提交修复。是的,在存储库中将其拆分为两个提交有点丑陋,但其他用户必须能够信任他们在公共存储库中看到的内容而不发生更改!
话虽如此,要进行这种特定类型的历史记录编辑,您需要交互式变基:
git rebase -i master~4 master
master~4
代表主分支最新提交前的四个提交。你可以使用任何形式 - 可能是另一个分支,也可能是提交哈希值 - 以便达到相同的效果。
这将在编辑器中打开一个包含你正在操作的提交列表:
pick <hash-A> <message-A>
pick <hash-B> <message-B>
pick <hash-C> <message-C>
pick <hash-D> <message-D>
那里的注释帮助文本已经很明显了。在这种情况下,您需要将提交B的行中的“pick”更改为“edit”,保存并退出。重新设置将开始,并在应用B后暂停,让您进行更改。您需要做必要的事情,添加,使用“git commit --amend”,然后“git rebase --continue”。它将应用C和D,您就完成了。如果中途出现任何问题,请使用“git rebase --abort”返回到起始点。
重新设置可能有点可怕-例如,不要意外删除该列表中的行!如果您还不熟悉此操作,建议多使用“gitk”和备份分支名称。