从git历史记录中删除并完全删除提交

时间:2016-01-12 14:26:31

标签: git github push git-commit post-commit

我的git历史记录中有一个提交

1.commit 4930da17d8dd23d650ed38435d8b421816a0c451
  Date:   Sat Dec 5 14:34:18 2015 +0530

2.commit e1ebbbb599ee20ebec3ca92c26266d9fd16e7ccc
  Date:   Sat Dec 5 13:22:20 2015 +0530

3.commit 1c4a11a80eb054d24dafec2efed0b0282188e687
  Date:   Sat Dec 5 12:11:50 2015 +0530

4.commit b4ab3c164a3a8d93e0a71a94b5c561cb5e20ebf6
  Date:   Sat Dec 5 12:09:56 2015 +0530

5.commit 167b1d10258381f09663ce61fa88ce3bbcd404c4
  Date:   Sat Dec 5 12:09:21 2015 +0530

6.commit c61bcadac673e1c83f4c14b66d56e23b12fa3198
  Date:   Sat Dec 5 12:07:58 2015 +0530

因为第3和第4次提交包含错误的代码,但在不知不觉中我提交并推送。

3.commit 1c4a11a80eb054d24dafec2efed0b0282188e687
  Date:   Sat Dec 5 12:11:50 2015 +0530

4.commit b4ab3c164a3a8d93e0a71a94b5c561cb5e20ebf6
  Date:   Sat Dec 5 12:09:56 2015 +0530

但第5和第6次提交包含正确的代码。我需要这个提交才能工作。

5.commit 167b1d10258381f09663ce61fa88ce3bbcd404c4
  Date:   Sat Dec 5 12:09:21 2015 +0530

6.commit c61bcadac673e1c83f4c14b66d56e23b12fa3198
  Date:   Sat Dec 5 12:07:58 2015 +0530

现在我想完全删除和删除我在第3和第4次提交中更改的内容。

我想从git历史记录中删除第3和第4次提交。但不是第5和第6。

这样我的分支就会安全。

2 个答案:

答案 0 :(得分:3)

您可以使用git rebase -i:

以交互方式重写历史记录
git rebase HEAD~6 -i 

将打开您的编辑器并允许您将多个提交压缩为一个,或者从历史记录中完全删除它们(通过删除编辑器中这些提交的行。)~6表示重写最后6个提交,-i意味着以交互方式进行。在您的情况下,您将要删除说"选择1c4a11a"并且"选择b4ab3c"。

请注意,启动的编辑器中的最新提交是 last 行,而不是第一行,并且由于您重写了历史记录并且您已经推送过,你还必须" git push --force"而不仅仅是" git push"为了向上游发送您的更改。

答案 1 :(得分:1)

您可以使用interactive rebase返回提交历史记录并以不同方式执行操作。对于使用交互式rebase,只需:

git rebase -i <commit_id>

<commit_id>是您要编辑的上次提交的父级。执行此命令后,只需将ddrop放在提交之前,您将删除甚至删除与该提交相对应的行。

运行此命令会在文本编辑器中为您提供一个类似于以下内容的提交列表:

pick f7f3f6d changed my name a bit
pick 310154e updated README formatting and added blame
pick a5f4a0d added cat-file

# Rebase 710f0f8..a5f4a0d onto 710f0f8
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

交互式rebase为您提供了一个将要运行的脚本。它将从您在命令行中指定的提交开始,并从上到下重放每个提交中引入的更改。它列出了最旧的,而不是最新的,因为这是它将重播的第一个。

但是,既然您已经将分支机构推送到您的上游存储库,请将此历史记录重写告知您可能的同事,正如git documentation所说:

  

再次记住,这是一个rebasing命令 - 包括每个提交   在范围内将被重写,无论你改变了   消息与否。不要包含你已经推送到的任何提交   中央服务器 - 这样做会让其他开发者感到困惑   相同变化的替代版本。