很久以前我有一个不好的提交,我想从git历史中彻底删除它,就像它从未发生过一样。我知道提交ID让我们说1f020。我已经尝试了git rebase并将其删除,但重新绑定时发生太多冲突,以至于无法这样做。该提交是简单的1行代码更改,并推送一些与项目无关的文件。 所以我想写这1行代码更改并提交它,然后以某种方式替换这个新的提交很久以前。在git中替换提交
回答
如果违规承诺
git commit -C <SHA1-for-commit-just-after-bad-commit-1f020>
重新应用一切都在一个私人仓库,什么你想要做的并不是什么大不了的事情。重写已发布的git历史令您的协作者感到恼火,因此请确保删除此行是值得的。
git-rebase
documentation有一个有用的通道。
git rebase [...] [<--onto newbase>] [<upstream>] [<branch>]
提交的范围也可以与底垫被去除。如果我们有以下的情况:
E---F---G---H---I---J topicA
然后命令
git rebase --onto topicA~5 topicA~3 topicA
会导致拆除提交˚F和摹:
E---H'---I'---J' topicA
这是如果有用的话F and G以某种方式存在缺陷,或者不应该成为
topicA
的一部分。请注意,参数--onto
和上游参数可以是任何有效的提交。
假设你的历史是线性的,有问题的承诺是在你的主分支,您可以通过运行
git rebase --onto 1f020~ 1f020 master
对于多毛的情况下适应上面的例子中,使用的交互变基。您可能会发现跟随an example that merges two commits一起使用会很有帮助,但是不要使用s
作为压扁标记提交,请移除整行以从历史记录中删除提交。
你不应该从git的历史中删除提交。您稍后会遇到问题。
但是,如果您知道自己在做什么,则可以在本地回退您的历史记录,将当前提交的内容替换掉,然后重新播放所有提交 - 然后对存储库执行强制推送。
但我强烈建议不要这样做。只要做一个新的承诺,并承认历史上有一个不好的承诺。
我知道如何回放和重放我所有的提交,如上所述。但有数百次提交需要重放数百次冲突。我正在寻求另一种解决方案。如何在不必重播所有数百次提交的情况下删除该错误提交。 – sonnyhe2002
@ sonnyhe2002可以做到这一点,但这并不容易,它需要编写一个脚本。详情请参阅我的回答。 – user4815162342
这是稍微复杂的,但不管怎么说,这是怎么一回事呢:
分离头和移动承诺只是后坏提交。使用git log来查找1f020之后的下一次提交。
git checkout <SHA1-for-commit-just-after-bad-commit-1f020>
动脑子犯只是BEFORE坏承诺,但留下的指数和工作树,因为它是
git reset --soft <SHA1-for-just-previous-to-bad-commit-1f020>
重做承诺只是后坏提交重新使用提交消息,但现在在之前只提交了那个提交失败。因此,去除坏承诺从呈交只是后坏起提交到这个新的地方
git rebase --onto HEAD <SHA1-for-commit-just-after-bad-commit-1f020> master
这太棒了。 –
所以,你想要的是:
卸下历史的错误提交,并
是不是一定要重做所有来删除提交后的合并。即从已删除的提交中下载的每个提交都应该保持原样,只需稍作更改即可,不包括从历史记录中删除的更改。基于
git rebase --onto
和git rebase -i
解决方案未能在第二点,因为它们需要重做所有后来发生的合并。但是,理论上可以简单地重新创建所有这些其他提交,就好像违规提交从未发生过一样,前提是不良提交足够小以至于从其后继本身恢复冲突。
正如迈克尔和其他人所指出的那样,这样做是非常不可取的。这也是一项重大的任务,几乎肯定不值得。但是,对于教育价值,以下是完成目标的综合解决方案的概要:
备份存储库。
使用
git rev-list
生成一个提交列表,该提交列表以提交错误开始并导致提交可达的所有分支头。初始化一个空映射,以将旧提交映射到新映射。
每个提交列表中,请执行以下操作:
- 退房的承诺,并恢复从坏的变化提交
- 创建树对象进行使用
git write-tree
当前树
- 使用
git commit-tree
创建一个新的提交与新的树,旧的提交信息,父母翻译从父母使用上述地图(如果有些父母不在地图中,只使用旧的父母) - 注册提交地图中的新提交。
通过标记和标记对象,并重新创建它们以指向新的提交,查阅地图。
通过分行负责人并致电
git update-ref
指示他们到新的提交,查阅地图。
如果提交引入的更改一行(和不必要的文件)不从后提交,这一过程可以完全自动化的变更发生冲突,并执行不需要你手动重做以后提交的所有合并和冲突。
缺点是它仍然需要重写所有后来的提交,如果它们已在其他地方共享,则使其失效,并使提交消息中的提交引用无效,例如由git revert
生成的提交。
好吧,我如何'初始化一个空的地图来映射旧的提交到新的' – sonnyhe2002
@ sonnyhe2002澄清,“初始化一个空的地图”并没有提到一个git概念,它是算法中的一个步骤。它告诉实现者创建地图,稍后将用于将旧提交与新提交相关联。在Python中,映射将作为字典来实现,在Perl中作为散列,在Bash中作为关联数组。这张地图在下面的步骤中被填充和查找,所以它必须事先被初始化。 – user4815162342
- 1. GIT中替换其间与另一分支提交提交
- 2. 如何使用git替换替换的树提交
- 3. 在git中将双亲提交转换为单亲提交
- 4. Git:从历史记录中删除替换文件的提交
- 5. 如何在git中提交提交?
- 6. jQuery替换提交按钮
- 7. JavaScript替换表单提交
- 8. 替换提交按钮
- 9. 在Git中删除提交
- 10. jquery,在提交时替换html
- 11. jQuery在提交时替换文本
- 12. Git - 在提交时显示提交者
- 13. 如何在Git中非交互地重新提交提交
- 14. 将本地Git提交到git-svn的一个提交中
- 15. 将git提交转换为一个
- 16. 如何删除所有提交并替换Git存储库中的初始提交?
- 17. 提交代码在Git中,分支在源头提交一次提交
- 18. 如何用git中的特定提交替换当前分支的头部?
- 19. Git中的提交对象
- 20. GIT如何在不提交
- 21. 在git捆绑提交
- 22. 卡在git提交窗口
- 23. 提交修改如何帮助您在Git中切换分支?
- 24. Git - 在已提交的文件中不改换行结尾
- 25. 在git中输出给定提交的提交消息
- 26. 如何在一次提交中提交SVN和GIT?
- 27. 在git中提交一个提交钩子
- 28. 获取在git中提交的提交数
- 29. 如何在git中一次提交一系列提交?
- 30. 在git中查找所有未提交的提交?
如果我这样做,它会给后来的分支上的合并冲突H'我'... – sonnyhe2002
@ sonnyhe2002它取决于您的存储库的细节和有问题的提交。 –