- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
经过几个月(提交和推送)我的项目,Bitbucket 上存储库的大小逐渐增加!大约 1 GB,我试图删除一些不重要的数据库文件夹。
搜索后,我发现大部分建议都在提出:
git filter-branch -f --tree-filter 'rm -rf folder/subfolder' HEAD
git push origin master --force
git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch $files" --tag-name-filter cat -- --all
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
最佳答案
好的,根据您对评论的回答,我们现在可以说出发生了什么。git filter-branch
的作用是将您的(部分或全部)提交复制到新的提交,然后更新引用。这意味着您的存储库变得更大(而不是更小),至少最初是这样。
复制的提交是通过给定的引用可以访问的提交。在这种情况下,您给出的引用是 HEAD
(git 变成“您当前的分支”,可能是 master
,但无论您当前的分支在 filter-branch
命令时是什么)。如果(且仅当)新副本与原始副本完全相同,那么它实际上是原始副本,并且没有制作实际副本(而是重复使用原始副本)。但是,一旦您进行任何更改——例如删除 folder/subfolder
,从那时起,这些就真的是副本。
在这种情况下,复制的内容较小,因为您删除了一些项目。 (它通常不会小很多,因为 git 可以很好地压缩项目。)但是您仍在向存储库添加更多内容:新提交,它指的是新树,幸运的是,它指的是相同的旧 blob(文件对象)和以前一样,这次只是稍微少了一些(folder/subfolder
文件的对象仍在存储库中,但复制的提交和树对象不再引用它们)。
从图形上看,在 filter-branch
进程的这一点上,我们现在有两个旧提交:
R--o--o---o--o <-- master
\ /
o--o <-- feature
folder/subfolder
出现在原始根提交
R
中,因此我们在这里有一个副本
R'
):
R'-o'-o'--o'-o'
\ /
o'-o'
filter-branch
现在所做的是重新指向一些引用(主要是分支和标签名称)。它重新指出的那些是你告诉它的,通过将它们称为文档所说的“正面引用”。在这种情况下,如果您在
master
(即
HEAD
是
master
的另一个名称),您提供的单个正引用是
master
... 所以这就是全部
filter-branch
重新指向它还生成名称以
refs/original/
开头的备份引用。这意味着您现在有以下提交:
R--o--o---o--o <-- refs/original/refs/heads/master
\ /
o--o <-- feature
R'-o'-o'--o'-o' <-- master
\ /
o'-o'
feature
仍然指向所有旧的(未复制的)提交,因此即使/在您删除任何
refs/original/
引用之后,git 仍将保留所有垃圾收集事件中所有仍然引用的提交,给出:
R--o
\
o--o <-- feature
R'-o'-o'--o'-o' <-- master
\ /
o'-o'
filter-branch
更新所有引用,您需要将它们全部命名。一个简单的方法是使用
--all
,它实际上命名了所有引用。在这种情况下,最初的“之后”图片看起来像这样:
R--o--o---o--o <-- refs/original/refs/heads/master
\ /
o--o <-- refs/original/refs/heads/feature
R'-o'-o'--o'-o' <-- master
\ /
o'-o' <-- feature
refs/original/
引用,则所有旧提交都将变为未引用并且可以被垃圾收集。好吧,也就是说,除非有标签指向它们,否则它们会这样做。
filter-branch
,则
--tag-name-filter
只会以任何方式更新它们。通常你想要
--tag-name-filter cat
,它保持标签名称不变,但使
filter-branch
将它们指向新复制的提交。这样你就不会死守旧的提交:这个练习的重点是让所有东西都使用新的副本,扔掉旧的副本,这样大文件对象就可以被垃圾收集。
git filter-branch -f --tree-filter 'rm -rf folder/subfolder'
git filter-branch -f --tree-filter 'rm -rf folder/subfolder' \
--tag-name-filter cat -- --all
--tree-filter
非常慢:对于这种特殊情况,使用
--index-filter
会快得多。此处的索引过滤器命令将是
git rm --cached --ignore-unmatch -r folder/subfolder
。)
refs/originals/
可能是您的救星。)
filter-branch
-ing,你做了一些删除任何
refs/originals/
的事情。 (在我对临时存储库的实验中,在
git filter-branch
上运行
HEAD
使用我所在的任何分支作为重新指向的分支,并制作了先前值的“原始”副本。)没有存储库的备份。怎么办?
git filter-branch
可能具有相当大的破坏性,因此从执行此备份过程开始通常是明智的。 (另外,我会注意到在 bitbucket 上的一个克隆,当还没有
push
ed-to 时,将提供服务。不幸的是,你做了一个
push
。也许 bitbucket 可以从他们自己的一些备份或快照中检索存储库的早期版本。)
$ git cat-file -p 5de7f500c13c8158696a68d86da1030313ddaf69
tree 73eee5d136d2b00c623c3fceceffab85c9e9b47e
parent c4ad00f8ccb59a0ae0735e8e32b203d4bd835616
author Jeff King <peff peff.net> 1405233728 -0400
committer Junio C Hamano <gitster pobox.com> 1406567673 -0700
alloc: factor out commit index
We keep a static counter to set the commit index on newly
allocated objects. However, since we also need to set the
[snip]
5de7f50...
)以
tree
和另一个 SHA-1、
parent
和另一个 SHA-1、一个
author
和 7 个空白行开始,然后是一个空白行,然后是 0x1045提交消息文本。
committer
,您会看到它包含子树(子目录)和文件对象(git 术语中的“blob”)的“真实名称”(SHA-1 值)及其模式——实际上,只是 blob 是否应该具有执行权限集,以及它们在目录中的名称。例如,上面
tree
的第一行是:
100644 blob 5e98806c6cc246acef5f539ae191710a0c06ad3f .gitattributes
tree
,放入名为
5e98806...
的文件中,并设置为不可执行。
.gitattributes
)73eee5d...
) c4ad00f...
。换句话说,它实际上是相同的提交:它已经在存储库中,而
5de7f50...
只会将现有 ID 还给我。虽然设置所有这些有点棘手,但这正是
git commit-tree
最终要做的:它提取原始提交,应用您的过滤器,设置所有内容,然后执行
git filter-branch
。
git commit-tree
命令,该命令将提交复制到新的、修改过的提交(具有不同的
git filter-branch
s,因此,在某些时候,不同的真实名称导致后续提交中的父 ID 不同,依此类推)。但是,如果您通过应用这次什么都不做的过滤器来复制那些复制的提交,那么新的
tree
对象将与旧对象相同。如果新的父级相同,并且作者、提交者和消息也都保持不变,则副本的新提交 ID 将与旧 ID 相同。
R--o--o---o--o <-- xxx [needs a name so that filter-branch will process it]
\ /
o--o <-- feature
R'-o'-o'--o'-o' <-- master
\ /
o'-o'
tree
应用于所有引用(甚至“除了
filter-branch
之外的所有”),这样它这次会生成相同的树,它将再次复制
master
并且新树将与
R
匹配,因此副本将实际上是
R'
。然后它将复制第一个 post-
R'
节点,进行相同的更改,复制的实际上是第一个 post-
R
,
R'
节点。这将对所有节点重复,甚至可能包括
o'
和所有
R'
s。但是,如果
o'
复制
filter-branch
,则生成的副本将再次变为
R'
,因为“删除不存在的目录”没有任何更改:我们的过滤器对这些特定提交没有任何作用。
R'
版本:
R--o--o---o--o <-- refs/originals/refs/xxx
\ /
o--o <-- refs/originals/refs/feature
R'-o'-o'--o'-o' <-- master, xxx
\ /
o'-o' <-- feature
refs/originals/
或类似的标签指向原始(预过滤)
xxx
,那么你有这个:
R--o
\
o--o <-- feature
R'-o'-o'--o'-o' <-- master
\ /
o'-o'
master
脚本仍然会复制
filter-branch
并且结果仍然是
R
。然后它将复制第一个
R'
节点,结果仍然是第一个
o
节点,依此类推。它不会复制现在删除的节点,但它不必:我们已经有了这些,可以通过分支名称
o'
访问。和以前一样,
master
可能会复制
filter-branch
和各种
R'
节点,但这没关系,因为过滤器不会做任何事情,因此副本毕竟只是原件。
o'
将像往常一样更新引用:
R--o
\
o--o <-- refs/originals/refs/feature
R'-o'-o'--o'-o' <-- master
\ /
o'-o' <-- feature
filter-branch
documentation 中描述的相同收缩以丢弃
git filter-branch
名称并垃圾收集现在未引用的对象。
refs/originals/
引用(或者足以保留“原始副本”)。
关于git - 减少 Bitbucket 上 git 存储库的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25399705/
我时不时地输入“git”,然后想到别的东西,然后输入例如“git checkout master”。当然,这给我留下了 $ git git checkout master git: 'git' is
我做到了 git 克隆 git://foo.git 光盘富 ...编辑文件.. 现在我想重新开始。我不在乎我已经做出的任何改变,但我不想再次克隆整个巨型 foo.git,只是丢失我所有的更改。我怎
我在我的电脑上开发代码,我的计算节点很少。 为了让我的程序保持同步,我决定使用 git。以前,我以一种单向模式使用它来“下推”从 PC 到计算节点的更改。但是时不时遇到计算节点特有的小bug,现场修复
虽然它似乎什么也没做,但它没有给出任何警告或错误消息。有什么想法吗? 最佳答案 来自 Git 源的注释: /* * Read a directory tree. We currently ignor
我知道如何为这样的 HTTPS 请求提供用户名和密码: git clone https://username:password@remote 但我想知道如何像这样向 Remote 提供用户名和密码:
Git GUI、Git Bash 和 Git CMD 之间有什么区别?我是初学者,为了进行安装,我发现自己通常同时使用 git bash 和 git CMD 最佳答案 Git CMD 就像使用 git
有人能告诉我git中文件索引被删除是什么意思吗?这些文件在我的 VS Code 中标记为红色,但我仍然可以修改文件并将更改推送到将反射(reflect)这些更改的远程存储库。我认为这一切都是在我使用命
我通过 git 子树将 GLFV 库添加到项目中,但出现此警告“看起来您的 git 安装或您的 git-subtree 安装已损坏”。还描述了几个原因,为什么这可能是: 如 git --exec-pa
我有需要外部 git 项目的 repo,但我不想使用子模块,因为我想在 github 上存档所有文件,所以我认为我只是将具有 git repo 的整个目录添加到 git 但它不t 添加里面的 .git
我有需要外部 git 项目的 repo,但我不想使用子模块,因为我想在 github 上存档所有文件,所以我认为我只是将具有 git repo 的整个目录添加到 git 但它不t 添加里面的 .git
我一直在阅读一篇文章,作者在其中指示:在现有存储库中创建一个新存储库,并想知道这是否是他忽略的错误。稍后我会与他核实。 这些是我要检查的条件: 将现有目录制作成仓库的条件,并且已经 checkin 主
我确实在不同的计算机上处理相同的项目,我想知道是否有一种方法可以跟踪该 .git 文件夹,这样我就不必在所有本地文件中重新配置配置文件。 我将所有工作推送到 bitbucket。 最佳答案 不,没
这个问题在这里已经有了答案: How does git store files? (3 个答案) 关闭 9 年前。 我为我的许多项目创建了一个远程存储库,所以它是我的push 的目的地。与 git
应该如何在 git 中查看文件内容的完整历史记录? 一个文件在 git 中的历史很短,存储库通过 git-svn 同步,但在 svn 中的历史很长。 git 中的历史记录到达文件移动的位置。要查看历史
我是confused here ... 如何对修改后的文件进行git commit,以及如何对新文件进行git commit? 还有,你如何在git中单独提交文件? 最佳答案 git 提交过程分为两个
正在搜索 throw SO 来寻找答案。遇到这个似乎没有给出任何答案的旧线程。重新触发此线程,希望有人知道! 有人能告诉我 git subtree 和 git filter-branch 的区别吗?为
我想知道是否有一种方法可以避免在每个 Git 命令的开头键入单词 git。 如果有一种方法可以在打开命令提示符进入 “Git 模式” 后只使用一次 git 命令就好了。 例如: git> 之后,我们键
当您修改工作目录中的文件时,git 会告诉您使用“git add”暂存。 当您向工作目录添加新文件时,git 会告诉您使用“git add”开始跟踪。 我对这两个概念有点困惑,因为我假设跟踪文件的更改
为什么 git://有效 $ git clone git://github.com/schacon/grit.git Cloning into 'grit'... ... Checking conne
我在以下沙箱中练习 git:https://learngitbranching.js.org/?NODEMO 我在两个单独的 session 中运行了两组命令。第一组命令顺序如下: git clone
我是一名优秀的程序员,十分优秀!