Hi all,
I run a small private repo (squishlogic/jigsawgeo and squishlogic/ant) on a Free-tier workspace with the 1 GB Git LFS storage limit. I recently used git filter-repo to remove a large directory of reproducible/fetchable assets from the entire git history (all branches), which is the recommended way to shrink history when files shouldn't have been committed in the first place.
After the rewrite and force-push, the pointer files are gone from every branch, but the underlying LFS blob content is still sitting in Bitbucket's storage; my usage didn't drop at all. I understand this is expected: git filter-repo only rewrites local git objects, it has no way to talk to Bitbucket's separate LFS blob store, and Bitbucket's own garbage collection only kicks in automatically once a repo crosses roughly 75% of its LFS quota.
I've been manually finding and deleting orphaned objects through the repo's LFS file-management UI (Settings, Git LFS), which does work and reclaims space immediately, but there's no bulk operation there, no way to sort/filter by "unreferenced," and no listing API I could find to script it, so at real scale (~2,000 leftover objects, ~300+ MB) it's an enormous number of one-at-a-time clicks.
Is there any way to request a manual/server-side garbage collection pass for LFS on a repo, the way it presumably happens automatically once a workspace nears its quota? Or alternatively, is there a supported bulk-delete or list API for LFS objects that isn't documented in the main API docs? Free-tier support only routes me to Community/docs for this category of issue, so I'm hoping someone here (or an Atlassian team member who monitors this forum) can point me in the right direction.
Thanks for any pointers.
Community moderators have prevented the ability to post new answers.
Hello and welcome to Atlassian Community @svleest
I requested assistance. An Atlassian team member will respond within 2 business days.
Best,
Arek š¤
Hey @svleest
Welcome to the community.
I've triggered GC on both repositories; the size should now be reduced. Please review them and confirm with me.
Regards,
Syahrul
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi Syahrul,
Thanks for running that. I just refreshed the dashboard and JigsawGeo is still showing 410.0 MB of LFS storage -- no change from before.
Since you triggered the GC, we also deleted 13 stale/abandoned branches from the repository (old experimental branches, some with no shared history with master at all) that were referencing additional old file versions. That cleanup happened after your GC ran, so any LFS blobs that only those branches were keeping alive wouldn't have been eligible for removal yet.
Could you run the GC again now that those branches are gone? And separately ā I want to make sure we're asking for the right operation: our understanding is that the bloat comes from LFS blobs left over from an earlier git filter-repo history rewrite, which are no longer referenced by any current branch or commit, but may not be cleared by a standard repository GC/repack if that only compacts reachable objects. Could you confirm whether the GC you ran specifically prunes dangling/unreferenced LFS objects (ones with no reachable pointer in any branch), as opposed to just repacking the git object database? If there's a separate LFS-specific prune step, could you run that as well?
Happy to provide the current branch list or anything else that helps narrow this down.
Thanks,
Steve
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey @svleest
Git LFS is used to store large files outside the normal Git repository. Git keeps a small pointer file, while the large file is stored in Bitbucketās LFS.
If you remove a file from Git history, the LFS file may still remain in Bitbucket storage. You can delete those unused LFS objects separately.
A quick terminology note: Git LFS uses an OID, which is the object ID of an LFS file. This is different from OIDC, which is an authentication method used by Bitbucket Pipelines. The script below uses an API token, not an OIDC token.
From a fresh clone of the repository, run:
git fetch --all --prune
git lfs ls-files --all --long > lfs-files.txt
awk '{print $1}' lfs-files.txt | sort -u > used-oids.txt
The used-oids.txt file contains the LFS objects that are still used by the repository. Don't delete these objects.
Next, open the repositoryās Settings ā Git LFS page and review the stored LFS files. Compare those OIDs with used-oids.txt.
Only OIDs stored in Bitbucket that are not listed in used-oids.txt should be considered for deletion. Place those unused OIDs in a file named:
oids.txt
Use one complete OID per line.
The deletion script does not find unused files automatically. It deletes every OID that is placed in oids.txt, so please review this file carefully before running it.
The script is available here:
https://bitbucket.org/bbcloud-support-scripts/delete-lfs-files-python/src/master/
The script requires:
Copy env-template.py to env.py and add those values:
EMAIL_ADDRESS = "<your Atlassian email>"
BITBUCKET_API_TOKEN = "<your API token>"
WORKSPACE = "<workspace name>"
REPOSITORY = "<repository name>"
Keep the API token private and do not commit env.py to the repository.
Then run:
python3 -m pip install -r requirements.txt
python3 delete_lfs_files.py
Deleting an LFS object is permanent. Any Git branch, tag, or historical commit that still points to a deleted object may fail to clone or check out. We recommend creating a backup and testing with one confirmed unused OID before deleting the remaining objects.
Regards,
Syahrul
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.