我能完全删除一个提交吗?

3

我希望删除一个特定的提交。

我进行了以下实验:

初始化一个仓库

bash-3.2$ git init
Initialized empty Git repository in /Users/*****/test/.git/

创建一个文件。
bash-3.2$ touch readme
bash-3.2$ ls
readme

提交此次创建。
bash-3.2$ git add .
bash-3.2$ git commit -m "first commit"
[master (root-commit) b9f8e60] first commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 readme

编辑该文件(出现了一些错误)

bash-3.2$ echo WrongMsg > readme
bash-3.2$ cat readme
WrongMsg

疏忽地提交了那个修改

bash-3.2$ git add .
bash-3.2$ git commit -m "careless commit"
[master 1eec681] careless commit
1 file changed, 1 insertion(+)

检查日志

bash-3.2$ git log --oneline

将会给予

1eec681 careless commit
b9f8e60 first commit

现在,我意识到了这个错误,并想要修正它。

bash-3.2$ git rebase -i HEAD^

将提示
pick 1eec681 careless commit

# Rebase b9f8e60..1eec681 onto b9f8e60 (1 command)
#
# 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
# d, drop = remove commit
#
# 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

pick更改为drop,然后使用:wq保存,它将会输出结果。

Successfully rebased and updated refs/heads/master.

检查日志

bash-3.2$ git log --oneline
b9f8e60 first commit

更正错误

bash-3.2$ echo CorrectMsg > readme
bash-3.2$ cat readme
CorrectMsg

提交
bash-3.2$ git add .
bash-3.2$ git commit -m "correction"
[master f224289] correction
1 file changed, 1 insertion(+)

日志

bash-3.2$ git log --oneline
f224289 correction
b9f8e60 first commit

似乎删除成功了,但如果我执行以下操作:
bash-3.2$ git reset --hard 1eec681
HEAD is now at 1eec681 careless commit

bash-3.2$ git log --oneline
1eec681 careless commit
b9f8e60 first commit

历史记录仍然存储在存储库中,没有被完全清除。

我能完全删除这个历史记录吗?


2
就此而言,你应该使用“git commit --amend”而不是那个变基操作。 - Jonas Schäfer
我将此标记为重复,因为该重复条目具有正确的答案(您必须首先过期或删除 reflog 条目,然后像 Andreas Wederbrand 的答案那样使用 git gc;或者您可以克隆存储库并删除原始存储库,这更为激进)。但是,我给了exussum的答案点赞,因为它通常是最适用的。 - torek
3个回答

4

Git是一种懒惰的工具,所有的提交都会被保留,你可以使用以下命令来查看它们:

git reflog

这将显示您所做的所有历史更改(移动分支、提交、变基等)。

虽然它们会被垃圾回收器清理,但老实说,这个功能比麻烦更有帮助。对于它将使用的微小空间,我不会担心它。


1

这个提交最终会被删除,但如果您真的需要删除提交,可以手动运行git gc

您需要使用--aggressive--prune=all来确保悬空提交被彻底删除。


我尝试了 git gc --aggressive --prune=all 但我仍然可以通过其SHA回到错误的提交。 - Nandin Borjigin

0
输入git reflog以显示您的各种提交消息和头部编号。 输入git reset --hard HEAD{在此处输入头部编号}。头部编号是您想要将项目还原到的位置。警告:一旦还原,您将无法返回该时间点。

但是提交记录仍然存在。只要我知道它的SHA,我就可以回到那个错误的提交记录。我想彻底删除那个提交记录。 - Nandin Borjigin
点击这个链接。它可能会对你有所帮助。https://github.com/blog/2019-how-to-undo-almost-anything-with-git - Intelligent

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接