【发布时间】:2016-12-21 11:13:31
【问题描述】:
我只想删除 git 日志中间的特定提交。它不应该受到上述提交的影响。
【问题讨论】:
-
来自本地副本还是远程?
标签: git
我只想删除 git 日志中间的特定提交。它不应该受到上述提交的影响。
【问题讨论】:
标签: git
如果提交没有被推送到远程服务器,你可以使用git rebase来修改git历史记录。
你可以这样做:
git rebase -i commit-hash^
它将显示提交列表。第一行应该是您要删除的提交。从您编辑的文件中删除该行,保存并关闭。
如果您在此之前确实推送到了远程服务器,请注意,您刚刚删除的提交之后的提交是根据您刚刚从历史记录中删除的提交之前的提交重写的。由于这个特定的原因,所有的提交都被改变了,因为你的历史刚刚发生了分歧。所以如果你试图推动它,它不会是快进的,你必须强制推动。
因此,如果您不熟悉git rebase,我建议您保留一个指向您正在修改历史记录的分支,以防出现问题。
此外,如果该特定提交在多个分支之间共享,则分散一个分支的历史记录将导致多个问题,因为您将无法轻松地将旧历史记录中的一个分支合并到新历史记录中的分支。它会重复许多提交,并且您在一个分支中删除的提交不会在其他分支中删除。
想想它修改 git 历史就像时间旅行。任何一点的变化都会创造一个新的平行宇宙。过去改变之后的所有事情都会受到你过去所做的改变的影响。
【讨论】:
它不应该受到上述提交的影响。
如果你从一个分支的中间删除一个提交,或者实际上除了可能是一个分支的 HEAD 之外的任何地方,你将重写那个分支的历史。这是因为您用来实现这一点的工具,即git rebase -interactive 和git filter-branch,需要重新提交您删除的提交之后的所有内容。这对于公共共享分支来说通常是不可取的,因为它迫使每个人都采取非常严厉的措施来跟上这种变化。
更安全的选择是使用git revert:
git revert <SHA-1 of commit to delete>
这将在您的分支顶部添加一个 new 提交,它有效地撤消了中间提交所做的一切。
顺便说一句,如果您真的想要删除该提交,我建议您进行交互式 rebase。
【讨论】:
您可以为此使用git cherry-pick。假设您的 git log 看起来像这样。并且您想从您的分支中删除第二次提交。
COMMITS MESSAGES
abcd123 4th commit message
xyze456 3rd commit message
98y65r4 2nd commit message wants to be removed.
bl8976t 1st commit message
第 1 步 - 检查最后一次正确的提交:git checkout bl8976t
第 2 步 - 从那里创建一个新分支:git checkout -b commit-remove
第 3 步 - 您想要保留的 Cherry pick 提交:git cherry-pick xyze456 和 git cherry-pick abcd123
第 4 步 - 签出您的原始分支:git checkout master
第 5 步 - 将原始分支重置为上次可用的提交:git reset --hard bl8976t
第 6 步 - 将新分支合并到原始分支:git merge commit-remove
第 7 步 - 检查原始分支是否有正确的提交:git log
第 8 步 - 将原始分支推送到远程仓库:git push --hard origin original-branch-name
你已经完成了。
请注意,这可能会对在同一存储库/分支上工作的其他用户产生不利影响。
【讨论】:
git push --force origin latest sha commit from merge:original-branch-name
如果您使用的是 IntelliJ
假设你的分支 X 是这样的
提交 [A]
提交 [B]
提交 [C]
提交 [D]
并且您想删除 2 个提交 B 和 C。
1- 使用 git log 对话框右键单击提交 D(在要删除的那个之前的最后一次提交)并从中创建一个新分支,称为 Y,intellij 将在分支 Y 处自动结帐
3- 你可以在 git log 对话框的左栏中看到你的分支,右键单击分支 X 并选择与当前比较
现在你会看到这个对话框
4- 您可以右键单击提交 A 并选择 Cherry-pick
现在在分支 Y 中你有提交 A 和 D,解决冲突,提交并推送。
【讨论】: