420

I tried looking for a good tutorial on reducing Git repository sizes, but I didn't find any.

How do I reduce my repository size?

It's about 10 MB, but Heroku only allows 50 MB and I'm nowhere near finished developing my application.

I added the usual suspects (log, vendor, doc, etc.) to the .gitignore file already. Although I only added .gitignore recently.

What can I do?

5
  • 2
    I just did and it brought it down to 2.2 mb...thanks a lot! Although that didn't seem to reduce the repo size on Heroku..hmm Commented Jan 22, 2010 at 11:16
  • 13
    Push it using --force. It will overwrite the contents even if there was no change (no new commits, etc.) Commented Jan 22, 2010 at 11:21
  • 2
    @MarcinGil - Below, VonC states you need access to the server to clean the remote server (if I am parsing it correctly). Commented Jun 16, 2016 at 11:34
  • 3
    Just a comment to help other readers if they don't know what to add to the .gitignore, there is a nice service at gitignore.io that will help you set up a good .gitignore based on your dev environment. Commented Jan 15, 2017 at 22:27
  • Related (2009): Make Git consume less disk space Commented Oct 24, 2023 at 3:58

4 Answers 4

493

Update Feb. 2021, eleven years later: the new git maintenance command (man page) should supersede git gc, and can be scheduled.


Original: git gc --aggressive is one way to force the prune process to take place (to be sure: git gc --aggressive --prune=now). You have other commands to clean the repo too. Don't forget though, sometimes git gc alone can increase the size of the repo!

It can be also used after a filter-branch, to mark some directories to be removed from the history (with a further gain of space); see here. But that means nobody is pulling from your public repo. filter-branch can keep backup refs in .git/refs/original, so that directory can be cleaned too.

Finally, as mentioned in this comment and this question; cleaning the reflog can help:

git reflog expire --all --expire=now git gc --prune=now --aggressive 

An even more complete, and possibly dangerous, solution is to remove unused objects from a git repository


Note that git filter-repo now (Git 2.24+, Q4 2019) replaces the obsolete git filter-branch or BFG: it is a python-based tool, to be installed first.

Joe suggests:

# Find the largest files in .git: git rev-list --objects --all | grep -f <(git verify-pack -v .git/objects/pack/*.idx| sort -k 3 -n | cut -f 1 -d " " | tail -10) # Strat filtering these large files: git filter-repo --path-glob '../../src/../..' --invert-paths --force #or git filter-repo --path-glob '*.zip' --invert-paths --force #or git filter-repo --path-glob '*.a' --invert-paths --force git remote add origin [email protected]:.../...git git push --all --force git push --tags --force 
Sign up to request clarification or add additional context in comments.

11 Comments

Note to self: don't forget remote branches: stackoverflow.com/questions/11255802/…
Note to self: don't forget remote tags
In addition to remote references, the reflog is another thing that may cause references you are trying to remove to be kept. stackoverflow.com/q/27489761/1072626
@VitalyZdanevich Note sure: ask a new question with the exact version of git and the OS used, to see if I or other git-questions contributors can suggest a fix.
@jww I confirm this is purely a local operation. It has no bearing on the size of the remote repo. You would need a direct access to the server of that remote repo to do the same.
|
140

Here's what I did:

git gc git gc --aggressive git prune 

That seemed to have done the trick. I started with around 10.5 MB and now it's little more than 980 KB.

You can run all three commands with prune till now using:

git gc --aggressive --prune=now 

Documentation:

5 Comments

prune is always run by gc (with 2 weeks ago default).
U can run all 3 with prune till now using git gc --aggressive --prune=now
But, when I delete the repo then clone it again, the size is still large. How do you handle that?
if you delete your local repository and clone again you inherit the remote's .git folder. To keep the size reduction changes you likely have to at least push them yourself first. If you don't control the remote you're out of luck, but you could always make your own fork
after run the three commands, local repo became smaller, but run git status will show no update at all ,so it's no way to git commit & git push changes to remote repo... How to shrink remote repo?
37

In my case, I pushed several big (more than 100 MB) files and then proceeded to remove them. But they were still in the history of my repository, so I had to remove them from it as well.

This did the trick:

bfg -b 100M # To remove all blobs from history, whose size is superior to 100MB git reflog expire --expire=now --all git gc --prune=now --aggressive 

Then, you need to push force on your branch:

git push origin <your_branch_name> --force 

Note: bfg is a tool that can be installed on Linux and macOS using Homebrew (executable brew):

brew install bfg 

1 Comment

that is such a clean solution. 'git gc' and 'git prune' didn't help me from other answers.
5

This should not affect everyone, but one of the semi-hidden reasons of the repository size being large could be Git submodules.

You might have added one or more submodules, but stopped using it at some time, and some files remained in .git/modules directory. To give redundant submodule files away, see this question.

However, just like the main repository, the other way is to navigate to the submodule directory in .git/modules, and do, for example, git gc --aggressive --prune.

These should have a good impact on the repository size, but as long as you use Git submodules, e.g. especially with large libraries, your repository size should not change drastically.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.