首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何从实际数据库中永久删除最近的git提交

如何从实际数据库中永久删除最近的git提交
EN

Stack Overflow用户
提问于 2016-05-27 12:49:53
回答 2查看 103关注 0票数 1

示例

因此,假设我有一个本地git与10提交,让SHA消化0-9,所以我的git日志如下所示

代码语言:javascript
运行
复制
9 (HEAD -> master)
8
7
6
5
4
3
2
1
0 <- initial commit

我决定提交5-9是垃圾,我希望永久地从存储库中删除它们的所有记录,并删除它们引入的磁盘空间。我希望我的回购状态与提交4的状态相同,并且让它像5-9从未发生过一样。

我知道git reset --hard 4会使我的回购看起来被重新卷到提交4,但据我所知,这只是将提交master点从9更改为4,但实际上并没有删除任何内容。如果您知道commit 9的SHA,那么所有的数据都仍然存在,并且是可以恢复的。

我也知道git filter-branch,但这只是从历史记录中删除文件,而不是提交。

我试过这样做:

代码语言:javascript
运行
复制
git reset --hard 4
git gc --prune=now

但是这样做之后,我的.git目录的磁盘空间使用情况是相同或更大的,我仍然可以用git checkout 9恢复历史。为什么git gc --prune=now不修剪提交5-9?我需要终止我的reflog吗?

更广泛地说:

如果我有一个包含多个分支、标记、提交、合并和分叉历史的复杂回购,那么如何永久和自动地删除所有提交、及其引入的更改以及在一定时间后使用的磁盘空间。有效地将整个回购退回到那个时间,并永久销毁该日期之后发生的所有活动。

EN

回答 2

Stack Overflow用户

发布于 2016-05-27 13:09:36

git reset不删除内容。它只需将您的更改为指向您所要求的新的SHA-1。

如何删除内容?

我也知道git过滤器分支,但这只是从历史中删除文件,而不是提交。

让我纠正你。

完成git筛选器后,它将更新内容并创建新的提交。

那么旧的承诺在哪里呢?

旧的提交仍然在您的存储库中。它变成了一个悬空的对象,这意味着有一些内容是无法从任何分支访问的。

首先,阅读这个答案来理解什么是

现在,您必须使用git filter-branch of BFG,并且只能执行git gc

..。我决定提交5-9是垃圾,我想永久地从存储库和它们引入的磁盘空间中删除它们的所有记录。

你有几个选择来实现它。这里有一个简单的例子:

代码语言:javascript
运行
复制
# Get back to the desired commit
git checkout <commit> # in your case 4

# now delete the old branch with the 5-9 commits
git branch -D <branch name>

# now create a new branch from commit #4
git checkout -b <branch>

# now you have to clean the leftovers.
# first lets see them (not required just for us to prove that we delete them)
git fsck --full 

# now you will get a list of all the "removed" commit.
# lets clean the repo right now.
git gc --aggressive --prune=now

为什么git gc =现在不提交5-9?

它不会删除提交,因为重置只会更改存储库的头,而不是内容。

票数 0
EN

Stack Overflow用户

发布于 2016-05-27 15:21:55

让我们把这个分成几个部分。

我知道git reset --hard 4会使我的回购看起来被重新卷到提交4,但据我所知,这只是将提交master点从9更改为4,但实际上并没有删除任何内容。如果您知道commit 9的SHA,那么所有的数据都仍然存在,并且是可以恢复的。

这是正确的。此外,还有两个可以保留指向提交5、6、7、8和9的指针:一个用于HEAD,用于HEAD指向那些提交(如果HEAD曾经指向它们),另一个用于master,后者记得master指出这些提交(如果master曾经指向它们)--我们知道它确实指向了9,因为这是在reset之前的位置,但我们不知道它是否单独地指向了以前的每个提交,或者你可能会以某种方式同时把它们带来,例如,从另一个分支)。

可能有或可能没有指向这些提交的附加分支和/或重浮点。

我也知道git filter-branch,但这只是从历史记录中删除文件,而不是提交。

这是不对的,尽管正如沃尔夫冈·保利所说的那样,“这是不对的,这甚至都不是错的!”特别是,这个短语意味着git filter-branch删除了一些东西。它没有:它添加了新的提交。

Git从根本上讲是围绕着添加新东西的想法而建立的,而且永远不会删除任何东西。这包括git commit --amendgit rebasegit filter-branch:它们添加了新的提交。唯一真正删除过期内容的Git命令是与gc相关的命令(git prunegit reflog expiregit repackgit prune-packed等,当然还有git gc本身)。

我试过: git重置-硬4 git gc -修剪=现在 但是这样做之后,我的.git目录的磁盘空间使用情况是相同或更大的,我仍然可以用git checkout 9恢复历史。为什么git gc --prune=now不修剪提交5-9?我需要结束我的重捕吗?

是。

要使旧的对象消失,您必须:

  • 搜索并销毁所有引用,包括那些在重发中的引用。
  • 不分年龄修剪松散的物体(上面的--prune=now部分)
  • 将这些对象的任何打包版本重新打包。

git gc --prune=now处理最后两个步骤,但不是第一个步骤。使用git reflog --expire=now --expire-unreachable=now可以清除所有的重触发器(这太过分了:--expire-unreachable可能就是您所需要的)。如果您有其他杂乱的引用(其他分支、标记、一两个松散的stash,甚至是ORIG_HEADCHERRY_PICK_HEAD之类的东西),则必须手动清理这些引用。还请注意,git filter-branch保留了.git/refs/original/中的原始引用集,而这些引用保留了所有原始(预过滤-复制)对象。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37484026

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档