我目前的基地总规模大约是。200 mb。
但是我的。git文件夹有惊人的5GB(!)。因为我把我的工作推到一个外部服务器,我不需要任何大的本地历史…
如何缩小。git文件夹以释放笔记本上的一些空间?我可以删除超过30天的所有更改吗?
我目前的基地总规模大约是。200 mb。
但是我的。git文件夹有惊人的5GB(!)。因为我把我的工作推到一个外部服务器,我不需要任何大的本地历史…
如何缩小。git文件夹以释放笔记本上的一些空间?我可以删除超过30天的所有更改吗?
当前回答
我尝试了这些,但我的存储库仍然非常大。问题是我不小心检入了一些生成的大文件。经过一番搜索,我发现了一个很好的教程,可以很容易地删除生成的大文件。本教程允许我将存储库从60 MB缩小到< 1 MB。
Steve Lorek,如何缩小Git存储库
更新:这里是博客文章的复制粘贴版本。
如何缩小Git存储库
我们的主Git存储库的大小突然膨胀。它一夜之间就增长到180MB(压缩),而且克隆的时间很长。
原因是显而易见的;有人,在某个地方,某个时间,以某种方式,提交了大量文件。但我们不知道那些文件在哪里。
经过几个小时的试验、错误和研究,我确定了一个流程:
发现大文件 从存储库中清除它们 修改远程(GitHub)存储库,使文件不再被下载
除非你能够保证所有团队成员都能够创造出全新的副本,否则你便不应该尝试这一过程。它涉及更改历史记录,并要求任何对存储库做出贡献的人在向存储库推送任何东西之前删除新清理的存储库。
深度克隆存储库
如果您还没有相关存储库的本地克隆,现在就创建一个:
git clone remote-url
现在,您可能已经克隆了存储库,但还没有拥有所有远程分支。这是确保适当的“深层清洁”的必要条件。要做到这一点,我们需要一个Bash脚本:
#!/bin/bash
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do
git branch --track ${branch##*/} $branch
done
感谢bigfish在StackOverflow上的这个脚本,这是逐字复制。
将此代码复制到chmod +x filename.sh文件中,然后使用。/filename.sh执行。现在您将拥有所有远程分支(遗憾的是Git没有提供此功能)。
发现大文件
这里要归功于Antony Stubbs -他的Bash脚本识别了本地Git存储库中最大的文件,并逐字复制如下:
#!/bin/bash
#set -x
# Shows you the largest objects in your repo's pack file.
# Written for osx.
#
# @see http://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/
# @author Antony Stubbs
# set the internal field spereator to line break, so that we can iterate easily over the verify-pack output
IFS=$'\n';
# list all objects including their size, sort by size, take top 10
objects=`git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr | head`
echo "All sizes are in kB. The pack column is the size of the object, compressed, inside the pack file."
output="size,pack,SHA,location"
for y in $objects
do
# extract the size in bytes
size=$((`echo $y | cut -f 5 -d ' '`/1024))
# extract the compressed size in bytes
compressedSize=$((`echo $y | cut -f 6 -d ' '`/1024))
# extract the SHA
sha=`echo $y | cut -f 1 -d ' '`
# find the objects location in the repository tree
other=`git rev-list --all --objects | grep $sha`
#lineBreak=`echo -e "\n"`
output="${output}\n${size},${compressedSize},${other}"
done
echo -e $output | column -t -s ', '
像以前一样执行这个脚本,你会看到一些类似于下面的输出:
All sizes are in kB. The pack column is the size of the object, compressed, inside the pack file.
size pack SHA location
1111686 132987 a561d25105c79aa4921fb742745de0e791483afa 08-05-2012.sql
5002 392 e501b79448b9e970ab89b048b3218c2853fdfc88 foo.sql
266 249 73fa731bb90b04dcf79eeea8fdd637ba7df4c089 app/assets/images/fw/iphone.fw.png
265 43 939b31c563bd40b1ca70e4f4a9f7d67c27c936c0 doc/models_complete.svg
247 39 03514d9e84418573f26b205bae7e4e57057c036f unprocessed_email_replies.sql
193 49 6e601c4067aaddb26991c4bd5fbddef003800e70 public/assets/jquery-ui.min-0424e108178defa1cc794ee24fc92d24.js
178 30 c014b20b6fed9f17a0b2809ac410d74f291da26e foo.sql
158 158 15f9e56bc0865f4f303deff053e21909661a716b app/assets/images/iphone.png
103 36 3135e15c5cec75a4c85a0636b154b83221020c97 public/assets/application-c65733a4a64a1a885b1c32694574b12a.js
99 85 c1c80bc4c09e692d5e2127e39c87ecacdb1e816f app/assets/images/fw/lovethis_logo_sprint.fw.png
是的,看起来有人把一些不必要的文件推到了某个地方!包括一个可爱的1.1GB的SQL转储文件。
清理文件
清理文件需要一段时间,这取决于存储库的繁忙程度。你只需要一个命令就可以开始这个过程:
git filter-branch --tag-name-filter cat --index-filter 'git rm -r --cached --ignore-unmatch filename' --prune-empty -f -- --all
这个命令改编自其他来源——主要的增加是——tag-name-filter cat,它确保标签也被重写。
在该命令完成执行之后,您的存储库现在应该得到了清理,所有分支和标记都得到了清理。 回收空间
虽然我们可能已经重写了存储库的历史,但这些文件仍然存在于其中,窃取磁盘空间,通常会造成麻烦。让我们用核武器消灭这些混蛋:
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
现在我们有了一个全新的、干净的存储库。在我的例子中,它从180MB增加到7MB。
推送清理后的存储库
现在我们需要将更改推回远程存储库,这样其他人就不会遭受180MB下载的痛苦。
git push origin --force --all
——all参数也会推送所有分支。这就是为什么我们需要在一开始就克隆它们。
然后推送新重写的标签:
git push origin --force --tags
告诉你的队友
任何拥有本地存储库克隆的人都需要使用git rebase,或者创建一个新的克隆,否则当他们再次推送时,这些文件将被一起推送,存储库将被重置到之前的状态。
其他回答
通过根据文件最近更新的时间从. Git文件夹中删除一些文件的日志历史来收缩Git存储库。
我在本地机器上也遇到过同样的问题。原因是我从本地删除了一些大型文件,并提交到中央存储库。但是事件发生在git状态之后,git fetch和git pull。我的。git文件夹大小大约是3GB。之后,我运行以下命令,通过考虑一个月前已经更改/过期的文件来减小.git文件夹的大小。
命令
$ git remote prune origin && git repack && git prune-packed && git reflog expire --expire=1.month.ago && git gc --aggressive
Git命令及其简短描述:
git-prune - Prune all unreachable objects from the object database git-repack - Pack unpacked objects in a repository git-prune-packed - Remove extra objects that are already in pack files. git reflog: Git keeps track of updates to the tip of branches using a mechanism called reference logs, or "reflogs." Reflogs track when Git refs were updated in the local repository. In addition to branch tip reflogs, a special reflog is maintained for the Git stash. Reflogs are stored in directories under the local repository's .git directory. git reflog directories can be found at .git/logs/refs/heads/., .git/logs/HEAD, and also .git/logs/refs/stash if the git stash has been used on the repo. git reflog at a high level on the Rewriting History Page. git reflog expire --expire=now --expire-unreachable=now --all In addition to preserving history in the reflog, Git has internal expiration dates on when it will prune detached commits. Again, these are all implementation details that git gc handles and git prune should not be used standalone. git gc --aggressive: git-gc - Cleanup unnecessary files and optimize the local repository.Behind the scenes git gc actually executes a bundle of other internal subcommands like git prune, git repack, git pack and git rerere. The high-level responsibility of these commands is to identify any Git objects that are outside the threshold levels set from the git gc configuration. Once identified, these objects are then compressed, or pruned accordingly.
常见的结果:
$ git remote prune origin && git repack && git prune-packed && git reflog expire --expire=1.month.ago && git gc --aggressive
Enumerating objects: 535, done.
Counting objects: 100% (340/340), done.
Delta compression using up to 2 threads
Compressing objects: 100% (263/263), done.
Writing objects: 100% (340/340), done.
Total 340 (delta 104), reused 0 (delta 0)
Enumerating objects: 904, done.
Counting objects: 100% (904/904), done.
Delta compression using up to 2 threads
Compressing objects: 100% (771/771), done.
Writing objects: 100% (904/904), done.
Total 904 (delta 343), reused 561 (delta 0)
以下是git的创建者Linus对如何缩小git回购的看法:
The equivalent of "git gc --aggressive" - but done *properly* - is to do (overnight) something like git repack -a -d --depth=250 --window=250 where that depth thing is just about how deep the delta chains can be (make them longer for old history - it's worth the space overhead), and the window thing is about how big an object window we want each delta candidate to scan. And here, you might well want to add the "-f" flag (which is the "drop all old deltas", since you now are actually trying to make sure that this one actually finds good candidates.
来源:http://gcc.gnu.org/ml/gcc/2007-12/msg00165.html
这将摆脱二进制数据是孤儿在我的回购?“git重新打包”将不会删除你已经签入repo然后删除它的图像或二进制数据。要从你的回购中永久删除这些数据,你必须重写你的历史记录。一个常见的例子是当你不小心在git中检入你的密码。你可以回去删除一些文件,但你必须重写从那时到现在的历史记录,然后强制将新的repo推到你的原点。
我更多地将git用作同步机制,而不是版本历史。所以我对这个问题的解决方案是确保我所有的当前源都处于令人满意的状态,然后删除.git并重新初始化repo。磁盘空间问题解决。:-)历史消失了:-( 我这样做是因为我的回购是在一个小的u盘上。我不想要也不需要我的全部历史。 如果我有一种截断历史的方法,我就会使用它。
If I were interested in keeping my history I would archive the current repository. At some point later I could clone the original repository, copy over all the changes from the new repo (let's assume I haven't done much (any) renaming or deleteing). And then make one big commit that would represent all the changes made in the new repo as a single commit in the old repo. Is it possible to merge the histories? Maybe if I used a branch and then deleted the objects I didn't need. (I dont' know enough about git internals to start fooling around like that).
尝试了以上方法,在我的情况下没有任何工作(在git推送期间,我不小心杀死了git进程),所以我最终不得不删除回购并再次克隆它,现在.git文件夹是正常大小。
5GB vs 200MB有点奇怪。尝试运行git gc。
但是,除非您将存储库拆分为模块,否则您无法减小.git目录的大小。
git repo的每个克隆都是一个完整的存储库,可以充当服务器。这是分布式版本控制的基本原理。