首先,我在git中所做的事情:
E:\zeus>git filter-branch -f --tree-filter "rm -rf ZeusSRC_Hardware_RPi_image_Raspberry Pi_außen_20.05.2019.zip" --prune-empty -- --all
Rewrite fa2be75c64ca78a296c8f78fc363beebecbf92a1 (1526/1526) (2745 seconds passed, remaining 0 predicted)
Ref 'refs/heads/Kunden' was rewritten
Ref 'refs/heads/Sensor' was rewritten
Ref 'refs/heads/Wetter' was rewritten
Ref 'refs/heads/ZEUS-5' was rewritten
Ref 'refs/heads/Zeus_Bug-13' was rewritten
WARNING: Ref 'refs/heads/master' is unchanged
Ref 'refs/remotes/origin/ADW' was rewritten
WARNING: Ref 'refs/remotes/origin/master' is unchanged
Ref 'refs/remotes/origin/Kunden' was rewritten
Ref 'refs/remotes/origin/Metzger' was rewritten
WARNING: Ref 'refs/remotes/origin/Mond' is unchanged
Ref 'refs/remotes/origin/Sensor' was rewritten
WARNING: Ref 'refs/remotes/origin/Sonne' is unchanged
Ref 'refs/remotes/origin/Wetter' was rewritten
WARNING: Ref 'refs/remotes/origin/ZEUS-2' is unchanged
WARNING: Ref 'refs/remotes/origin/ZEUS-3' is unchanged
Ref 'refs/remotes/origin/ZEUS-5' was rewritten
Ref 'refs/remotes/origin/ZEUS_BUG-12' was rewritten
WARNING: Ref 'refs/remotes/origin/ZEUS_BUG-4' is unchanged
Ref 'refs/remotes/origin/ZEUS_BUG-6' was rewritten
WARNING: Ref 'refs/remotes/origin/ZEUS_BUG-8' is unchanged
Ref 'refs/remotes/origin/ZEUS_BUG-9' was rewritten
Ref 'refs/remotes/origin/Zeus_Bug-13' was rewritten
WARNING: Ref 'refs/remotes/origin/master' is unchanged
WARNING: Ref 'refs/remotes/origin/metzger' is unchanged
WARNING: Ref 'refs/remotes/origin/tempAddFirstCode' is unchanged
Ref 'refs/stash' was rewritten
第二,应该执行以下操作: 我的存储库中有一些ISO,大约4GB。我删除了它,使用git add。然后提交并推送,但是回购大小当然没有改变,因为仍然有一些对象曾经与以前的提交相关联。所以我首先要知道:
根据上述git的输出,我可以假定受git命令影响的文件现在已从历史记录中删除了吗?
据我所知,从历史记录中删除文件是我接下来要做的必不可少的前提: 使用垃圾收集器“手动”从我的仓库中删除相关对象。
我已经在SO上偶然发现了几篇有关此问题的文章,例如,我发现了git这个颇受欢迎的脚本:
git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc
可能需要先执行以下操作:
git remote rm origin
rm -rf .git/refs/original/ .git/refs/remotes/ .git/*_HEAD .git/logs/
git for-each-ref --format="%(refname)" refs/original/ | xargs -n1 --
no-run-if-empty git update-ref -d
从这里:How to remove unreferenced blobs from my git repo 但是,这些命令对我没有真正的作用:/
答案 0 :(得分:0)
如果有任何标签,则可能需要重做过滤器分支(从存储库的良好副本开始)并包括:
--tag-name-filter cat
在git filter-branch
选项中。
如果包装上有keep
个文件,它们可能会阻止大型对象的移除。 (如果您有有这些,您可能知道这一点。)
根据上述git的输出,我可以假定受git命令影响的文件现在已从历史记录中删除了吗?
更准确地说,是有一个 new 历史记录,其中从来没有添加文件,除了文件的现有历史记录之外,还存在该历史记录添加了 。每个was rewritten
参考都指向 new 历史记录的最前面的一次提交。每个is unchanged
都指向现有未更改历史记录尖端的提交,这是可以的,因为现有的未更改历史记录中从未包含文件。例如,想象下面的高度简化图(只有两个分支):
A--B--C <-- master
\
D--E <-- Kunden
文件ZeusSRC_Hardware_RPi_image_Raspberry
和Pi_außen_20.05.2019.zip
在提交D
中存在的位置。因此git filter-branch
提取了提交D
,删除了两个文件,然后进行了一次新的提交,我们将其称为D'
,不再包含以下文件:
D'-E'
/
A--B--C <-- master
\
D--E <-- Kunden
这两个文件在E
中可能存在也可能不存在,但是创建新的提交D'
意味着Git 必须还创建一个新的E'
,当然新的E'
也将其删除(如果它们存在于E
中。
现在已经建立了新的历史记录,Git必须丢弃现有的refs/heads/Kunden
并放入指向提交refs/heads/Kunden
的{{1}}(Kunden分支)中。现有的E'
可以,因此可以单独使用:
refs/heads/master
D'-E' <-- Kunden
/
A--B--C <-- master
\
D--E [original Kunden]
留下的refs/original/refs/heads/Kunden
名称保留了提交git filter-branch
,但各种不可见的引用日志条目也是如此。第一个是E
名称,它的含义是:
refs/original/*
因为它将删除每个这样的名称。
此:
git for-each-ref --format="%(refname)" refs/original/ | xargs -n1 --no-run-if-empty git update-ref -d
旨在处理第二个问题-reflog,还包括 git -c gc.reflogExpire=0 -c gc.reflogExpireUnreachable=0 -c gc.rerereresolved=0 -c gc.rerereunresolved=0 -c gc.pruneExpire=now gc
的最后一步。 the git filter-branch
documentation中的建议改为使用两个单独的命令:
git gc
目前,我希望指定配置项的git reflog expire --expire=now --all
git gc --prune=now
可以正常工作,但如果不行,请参阅分支机构文档。
一旦所有对提交git gc
的引用都消失了,并且假设没有对提交E
的引用,D
将丢弃对象git gc
和D
。如果打包了这些对象,Git将构建一个新的打包文件,将其忽略,然后将它们变成松散的对象。松散对象修剪将在对象修剪延迟后将其丢弃,并且除非将旧的打包文件与打包保持文件一起保存,否则将对其进行垃圾回收。
假设您有一个标签名,例如E
。进一步假设标记名称指向提交v2.1
:
D
由于未重写 D'-E' <-- Kunden
/
A--B--C <-- master
\
D--E
.
...... <-- tag: v2.1
,因此标签refs/tags/v2.1
继续保留提交v2.1
,该提交继续保留大文件。当您运行D
时,它会建立一个映射,该映射包含以下事实:新提交git filter-branch
是D'
的正确替代者。如果仍然有映射,则可以使用该映射来强制移动标签D
,使其指向提交v2.1
。不幸的是,D'
完成后,在对各种名称执行了所有“重写”操作之后,它删除了并认为映射已完成。
(旁注:不需要git filter-branch
。如您在上面看到的,许多远程跟踪名称都被重写,包括git rm origin
。这确实< / em>表示如果不使用refs/remotes/origin/Kunden
,将无法在origin
上更新其他Git存储库,如果不更新,git push -f
将带来大文件回来。)
最后,这个:
git fetch
表示您现有的保存的存储区可能已损坏,无法再应用。 (Filter-branch并没有意识到隐藏是故意有点怪异的,并且将它们视为正常合并,有时会破坏它们。)