如何在git日志中间只删除一个特定的提交

Dil*_*han 18 git

我只想删除git日志中间的特定提交.它不应该受到上述提交的影响.

Sur*_*esh 33

您可以用于git cherry-pick此用途。假设您的 git 日志如下所示。并且您想从分支中删除第二次提交。

COMMITS    MESSAGES
abcd123    4th commit message
xyze456    3rd commit message
98y65r4    2nd commit message wants to be removed.
bl8976t    1st commit message
Run Code Online (Sandbox Code Playgroud)

第 1 步 - 检查最后一次正确的提交:git checkout bl8976t

第 2 步 - 从那里创建一个新分支:git checkout -b commit-remove

第 3 步 - 精挑细选您想要保留的提交: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 --force origin original-branch-name

你完成了。

请注意,这可能会对在同一存储库/分支上工作的其他用户产生不利影响。


Loï*_*oix 16

如果未将提交推送到远程服务器,则可以使用它git rebase来修改git历史记录.

你可以这样做:

git rebase -i commit-hash^
Run Code Online (Sandbox Code Playgroud)

它将显示提交列表.第一行应该是您要删除的提交.从您编辑,保存和关闭的文件中删除该行.

如果您在执行此操作之前确实已推送到远程服务器,请注意在刚刚删除的提交之后的提交将根据您刚刚从历史记录中删除的提交之前的提交进行重写.出于这个特殊原因,所有提交都会更改,因为您的历史记录只是分歧.因此,如果你试图推动它,它将不会快进,你将不得不强制推动.

出于这个原因,如果你不熟悉git rebase我建议保持一个分支指向分支,你正在修改历史记录,以防出现问题.

此外,如果跨多个分支共享该特定提交,则分散一个分支的历史记录将导致多个问题,因为您将无法轻松地将旧历史记录中的一个分支合并到新历史记录中的分支.它将复制许多提交,并且您在一个分支中删除的提交不会在其他分支中删除.

想想它已经修改了git历史就像时间旅行.一点上的任何更改都会创建一个新的并行Universe.过去改变之后的所有事情都会受到您过去所做的改变的影响.

  • 这是对问题的正确答案 (2认同)

Tim*_*sen 13

它不应该受到上述提交的影响.

如果从分支中间删除提交,或者除了可能是分支的HEAD之外的任何地方,您将重写该分支的历史记录.这是因为这些工具,你会用它来实现这种,即git rebase -interactivegit filter-branch,将需要重新作出后,提交您删除其自带的一切.对于公共共享分支来说,这通常是不可取的,因为它迫使每个人采取相当严厉的措施来跟上这一变化.

相反,更安全的赌注是使用git revert:

git revert <SHA-1 of commit to delete>
Run Code Online (Sandbox Code Playgroud)

这将在您的分支顶部添加一个新的提交,它有效地撤消了中间提交所做的所有事情.

顺便说一下,如果你真的想删除那个提交,我建议你做一个交互式的rebase.


Ale*_*lex 7

我同意上述所有解决方案,尤其是当您陷入困境时。如果中间提交对其子提交没有重要更改,您还可以进行交互式变基并删除您不需要的更改。

当我不小心从其他开发人员那里获取我不需要的提交时,我通常会使用它。

示例场景,我有以下 3 个提交:

865962a1f5 Update Book Title
a3b091b427 Remove Book Link From Header
838e768df2 Add New Book To Book List
Run Code Online (Sandbox Code Playgroud)

由于某种原因,我不再希望从标题中删除我的图书链接。

步骤1。 git rebase -i Head~3

这将输出:

pick 865962a1f5 Update Book Title
pick a3b091b427 Remove Book Link From Header
pick 838e768df2 Add New Book To Book List
Run Code Online (Sandbox Code Playgroud)

步骤 2. 将中间提交的 'pick' 替换为 'drop'

pick 865962a1f5 Update Book Title
drop a3b091b427 Remove Book Link From Header
pick 838e768df2 Add New Book To Book List
Run Code Online (Sandbox Code Playgroud)

步骤 3. 写入并退出

之后您可能需要进行一些冲突解决,但如果更改足够简单,这将删除中间提交并留下以下历史记录:

865962a1f5 Update Book Title
838e768df2 Add New Book To Book List
Run Code Online (Sandbox Code Playgroud)

您现在可以将其强制推送到远程分支git push -f,请注意这具有一定的破坏性,或者您可以创建一个新分支并将 MR 切换到新分支!


小智 5

如果你使用的是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,解决冲突,提交并推送。