.git中的对象文件夹对于我的小型项目来说非常大 [英] Objects folder in .git is extremely large for my small project

查看:165
本文介绍了.git中的对象文件夹对于我的小型项目来说非常大的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的 git push 非常慢,因此我调查并发现文件夹 .git / objects 占用〜450MB。

完整的项目只有〜6MB,但我增加了140MB大的档案。由于github不允许大的文件,我删除了它们,然后做了 git add -A 并尝试再次提交,但这需要很长时间上传了很多。



它永远在:

 写作对象:97%(35/36),210.17 MiB | 49.00 KiB / s 

如何修复我的git存储库?

请记住,Git会保存每一个提交永远(不用担心,这是引用的原因!)。

这意味着当您添加存档并提交时,您将它放入,然后当你删除归档并提交时,你会提交一份额外的提交文件说:现在你已经永远保存了这个庞大的归档文件,将它从 working 版本中删除,因为我们没有需要它......但它仍然在永久性的审计线索永远每次提交记录中。所以它在你的仓库中,你将必须推它。同样,请注意周围的必须引用。



永远只要你(和其他人都有副本)希望它是



请参阅如何从Git存储库中的提交历史中删除/删除大文件?你的问题基本上是重复的,但在你找到答案之前,请注意,你还没有成功推送这些提交,因为GitHub默认说不,这真的很大。这意味着你可以自由使用重写操作:没有其他人有你的提交副本。



对于这样的例子,我通常认为 git rebase -i 是清理最简单的配方。特别是,假设你在 git rebase -i 编辑配方中有这样的提交序列:

 选择a123456添加功能foo 
选择b123456 rm巨型文件意外添加到a123456
选择...

在这种特殊情况下,错误(添加巨型文件)和修复(删除巨型文件)紧挨着 。假设你可以告诉Git:只要将两个提交合并为一个提交,那么如果你完成了第一个提交,然后是第二个提交,会发生什么。也就是说,让我们做所有事情,包括添加巨型文件,但是在提交之前,让我们也执行remove-giant-file,然后然后 commit。



嗯,squash和fixup是两个命令,它们完全告诉Git。只需将 pick 更改为 squash fixup 即可。这两者之间的唯一区别是您是否有机会编辑新组合提交的提交消息:


  • squash :进行联合提交,并在日志消息中调出编辑器,该编辑器最初包含两种原始日志消息。 > fixup :进行联合提交,但使用非修复提交的日志消息,完全丢弃fixup的消息。



所有历史编辑操作 copy 提交



正如我们在顶部所提到的,提交是永久的。他们不能改变。什么是rebase(和BFG在链接问题的答案中提到的)是 copy 坏提交给新的,稍微不同的,更好的(我们希望)提交。然后在复制完成之后,我们让Git摒弃坏提交,并将分支名称指向新副本:

  A  -  B  -  C  -  D  -  E < - 主

糟糕,提交 C 是坏的,我们让 D 来移除大文件,然后我们做了无关修正 E 。所以现在我们复制提交 C - 通过 - E (我们必须复制 E ,因为我们必须从坏点向前复制所有内容)到更新,更好的提交:

  
A - B - C' - E'< - 主

我们将原始的 CDE 链推开,并使用新的 C C )的副本 C 压扁或固定)和 E' E 的副本),并使分支名称 master ,在这种情况下,指向 E'而不是 E 。现在我们可以推动,也可以强制推送。



如果我们已经成功推送,就必须强制推送。如果我们必须强制推送,这意味着某个 else 可能已经挂钩了我们的 CDE 链,并且可能使用它和他们也必须恢复。如果他们做错了,他们甚至可能带回 C-D-E ! (通常通过合并。)



但如果没有其他人拥有 CDE ,我们可以放弃它们,我永远不会回来(除非我们去搜索它们)。因此,现在我们可以自由地(非强制)推送更正后的 C'-E'链。



如果你的修补程序不是很好的顺序



如果你的提交修复了你的不好的提交,那么上面的代码很好:

 选择a123456添加功能foo 
选择b123456 rm巨型文件意外添加到a123456
选择...

但是也许rm巨人文件提交不会在错误提交之后发生,也可能是其他事情混杂在一起。如果您可以简单地重新排序提交,这样一个单独的rm巨型文件commit 不会在错误之后出现,这很容易,只需按照 rebase -i 说明。你可以做两个rebase:一个重新排序,一个压扁/ fixup;或者如果你喜欢,你可以一次尝试重新排序和压缩/修正。



如果不是......好吧,这是你可能想要的时候去 filter-branch 或其他(链接)问题中提到的BFG:这些可以对提交进行复杂的手术。交互式rebase只能自己做简单的事情,并且给你留下复杂的方法(你可以在交互式rebase的中间使用 git commit --amend ),或者多次添加提交,例如)。


My git push was very slow so I investigated and found out that the folder .git/objects takes up ~450MB.

The complete project is only ~6MB, but I've added archives which were 140MB large. As github doesn't allow files that large, I've removed them, then did git add -A and tried to commit again, but it takes a very long time and seems to upload a lot.

It takes forever at:

writing objects:  97% (35/36), 210.17 MiB | 49.00 KiB/s 

How do I fix my git repository?

解决方案

Commits are "forever"

Remember that Git saves every commit "forever" (not to worry, there is a reason this is in quotes!).

This means that when you added the archive and committed, you put it in, and then when you removed the archive and committed, you put in an additional commit that says "now that you've saved this huge archive forever, take it out of the working version because we don't need it" ... but it's still in the permanent audit trail, the "every commit forever" record. So it's in your repository and you'll "have to" push it. Again, note the quotes around "have to".

Forever is only as long as you (and everyone else with a copy) want it to be

See How to remove/delete a large file from commit history in Git repository? Your question is basically a duplicate, but before you go to the answers there, note that you haven't yet successfully pushed these commits, because GitHub defaults to saying "No, that's really huge." This means you can use rewriting operations freely: no one else has a copy of your commits yet.

For cases like this one, I generally think git rebase -i is the easiest recipe for cleaning up. In particular, suppose you have this sequence of commits in your git rebase -i edit recipe:

pick a123456 add feature foo
pick b123456 rm giant file accidentally added in a123456
pick ...

In this particular case, the mistake ("add giant file") and fix ("remove giant file") are right next to each other. Suppose you could tell Git: "Just combine the two commits into one commit, that does what would happen if you did the first commit and then the second one." That is, let's do everything including adding the giant file, but then before committing, let's also do the remove-giant-file, and only then commit.

Well, "squash" and "fixup" are the two commands that tell Git exactly that. Just change pick to either squash or fixup. The only difference between these is whether you get a chance to edit the commit message for the new combined commit:

  • squash: make a combined commit, and bring up the editor on the log message, which initially contains both of the original log messages.
  • fixup: make a combined commit, but use the log message from the non-fixup commit, discarding the fixup's message entirely.

All history-edit operations copy commits

As we noted at the top, commits are forever. They can't be changed. What rebase does (and the "BFG" mentioned in the linked question's answers too) is copy the bad commits to new, slightly different, better-(we-hope), commits. And then after the copy is done, we have Git shove aside the bad commits and make the branch-name point to the new copies:

A--B--C--D--E   <-- master

Oops, commit C was bad and we made D to remove the big file, and then we made unrelated fix E as well. So now we copy commits C-through-E (we have to copy E because we have to copy everything from the bad point forward) to newer, better commits:

     C--D--E   [abandoned]
    /
A--B--C'--E'   <-- master

We shove the original C-D-E chain out of the way and use our new C' (copy of C that has D squashed or fixup-ed into it) and E' (copy of E) and make the branch name, master in this case, point to E' instead of to E. Now we can push, or maybe force-push.

We'd have to force-push if we had already managed to push successfully. If we have to force-push, that means someone else might have already snagged our bad C-D-E chain and might be using it and they will have to recover too. If they do it wrong, they may even bring C-D-E back! (Usually by merging.)

But if no one else has C-D-E, we can abandon them and know they'll never come back (unless we go search for them). So now we're free to (non-force) push the corrected C'-E' chain.

If your fix is not nicely in order

The above is great if your commit that fixes your bad commit comes right after the bad one:

pick a123456 add feature foo
pick b123456 rm giant file accidentally added in a123456
pick ...

but maybe the "rm giant file" commit does not come right after the bad commit, or maybe it has other things mixed in. If you can simply re-order the commits so that a lone "rm giant file" commit does come right after the mistake, that's easy, just follow the rebase -i instructions. You can do two rebases: one to reorder, and one to squash/fixup; or you can try the reorder-and-squash/fixup all in one go, if you prefer.

If not ... well, this is when you may want to go for filter-branch or the BFG mentioned in the other (linked) question: these can do complicated surgery on commits. Interactive rebase only does simple stuff on its own, and leaves complicated methods to you (you can use git commit --amend in the middle of the interactive rebase, or do multiple additional commits, for instance).

这篇关于.git中的对象文件夹对于我的小型项目来说非常大的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆