By default, when you clone a repository, you don't have all the remote refs
locally. Even if you cleanup your local git repo (such that the local size is actually smaller) you may not see this reflected in GitLab. This is because (1) you don't have all the remote by default refs and (2) GitLab holds onto those references you have deleted locally in many circumstances. For example, if you have a pipeline which references the no-longer-existing-locally references that are taking up space or if a reference exists in a Merge Request, among other cases.
To deal with this, you'll need to additionally cleanup these references on the remote as well:
refs/merge-requests/*
for merge requests.
refs/pipelines/*
for pipelines.
refs/environments/*
for environments.
refs/keep-around/*
are created as hidden refs to prevent commits referenced in the database from being removed
If you add these refs to your local git repo and fetch them, you'll see a size that more closely reflects what is reported in GitLab.
For example, if you look at your git config, you will see something like this by default:
[remote "origin"]
url = https://gitlab.com/gitlab-org/gitlab-foss.git
fetch = +refs/heads/*:refs/remotes/origin/*
You want to edit your git config (using git config -e
) and add the above references. For example, after adding the merge_requests references, your git config should look like this:
[remote "origin"]
url = https://gitlab.com/gitlab-org/gitlab-foss.git
fetch = +refs/heads/*:refs/remotes/origin/*
fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*
Do that for each of the remotes that have not yet been cleaned up, fetch them (git fetch origin
), clean them up locally, then force-push back to the remote.
However, some refs are not advertised and can only be retrieved by exporting the GitLab project and restoring the local repo from the export tarball (the project.bundle
in the tarball)
git clone --bare --mirror ./project.bundle myrepo
cd myrepo
git filter-repo ... # modify this for your cleanup
git remote remove origin
git remote add origin <project clone URL>
git push origin --force 'refs/heads/*'
git push origin --force 'refs/tags/*'
# push hidden refs
git push origin --force 'refs/replace/*'
After doing this, git filter-repo
creates a commit-map
file at ./filter-repo/commit-map
. Take this file and upload it to the repository cleanup under 'settings -> repository -> Cleanup'.
Keep in mind, removing these will also break features that rely on them (for example, you won't be able to review code/refs in previous MRs that have changes with removed references).
Also know that, after you push the cleaned up refs and initiate the repo cleanup, the size may take up to 30 minutes or more to update in GitLab depending on the repo size.
Additional reference: GitLab - Reduce repository size
Alternatively, you can create a new GitLab project and push your clean local state to the new GitLab project, then delete the old one. With this approach, you will, of course, lose much of the GitLab-stored history, like merge requests, settings, CI/CD pipelines, etc.
The new project could be moved in place of the old one to preserve correct clone URLs. This is the nuclear option.