
Photo by Pixabay on Pexels
You committed a 140 megabyte .env file or local SQLite database three commits ago, and GitHub just rejected your push. The file is already part of your local history, so deleting it with git rm in a new commit will not shrink the packfile or pass the remote host size limits.
The broken push
You try to send your branch to the remote:
bashgit push origin feature-auth
The output gives you a hard rejection:
textremote: Resolving deltas: 100% (14/14), completed with 8 local objects.
remote: error: Trace: 4b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e
remote: error: See https://gh.io/lfs for more information.
remote: error: File data/local_dev.db is 142.10 MB; this exceeds GitHub's file size limit of 100.00 MB
remote: error: GH001: Large files detected. You may want to try Git Large File Storage.
To github.com:org/repo.git
! [remote rejected] feature-auth -> feature-auth (pre-receive hook declined)
error: failed to push some refs to 'github.com:org/repo.git'
If you run git rm data/local_dev.db and make a fourth commit, the push will fail with the exact same message. Git transfers trees and blobs, not a simple unified diff of the tip. The 142 megabyte blob is referenced in commit b3a1f8c, so Git tries to upload it.
The manual fix using interactive rebase
If the commit history is local and only a few commits deep, do not reach for heavy external tools like git-filter-repo. You can drop the file from the past commit using git rebase -i.
First, look at your log to see where the file entered:
bashgit log --oneline -n 5
texte91b4a2 Add token refresh route
4c88f11 Connect session store to redis
b3a1f8c Set up development database schema
a019d33 Initial project layout
The file was added in b3a1f8c. Start an interactive rebase targeting the parent of that commit:
bashgit rebase -i a019d33
Your text editor opens with an instruction sheet:
textpick b3a1f8c Set up development database schema
pick 4c88f11 Connect session store to redis
pick e91b4a2 Add token refresh route
# Rebase a019d33..e91b4a2 onto a019d33
Change the word pick to edit (or just e) next to b3a1f8c:
textedit b3a1f8c Set up development database schema
pick 4c88f11 Connect session store to redis
pick e91b4a2 Add token refresh route
Save and close the file. Git will rewind your branch to b3a1f8c and pause:
textStopped at b3a1f8c... Set up development database schema
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
Now remove the large file from Git tracking without deleting it from your actual disk:
bashgit rm --cached data/local_dev.db
Add the path to .gitignore so you do not make this mistake again in ten minutes:
bashecho "data/local_dev.db" >> .gitignore
git add .gitignore
Amend the paused commit to seal the changes:
bashgit commit --amend --no-edit
Now let Git replay the remaining commits on top:
bashgit rebase --continue
If there are no merge conflicts with downstream commits, Git exits cleanly:
textSuccessfully rebased and updated refs/heads/feature-auth.
The gotcha: downstream references and dangling objects
There are two traps here.
The first happens during the rebase itself. If one of your later commits (like 4c88f11) modified that database file, git rebase --continue will stop with a merge conflict. Git thinks you deleted a file that a later commit modified.
To resolve that, finish deleting it for that later step too:
bashgit rm data/local_dev.db
git rebase --continue
The second trap is packfile size. Even though your commit tree no longer points to the 142 megabyte file, the object still sits in your .git/objects folder. It also sits in your reflog.
If your remote allows the push now, you can leave it alone. Git cleans itself up every few weeks via automatic garbage collection. But if you are on a metered connection or a shared drive and need that disk space back immediately, you have to flush the references:
bashgit reflog expire --expire=now --all
git gc --prune=now
Before running those two lines, check your working tree. git gc --prune=now deletes every unreachable commit immediately. If you made a mistake during your rebase, this strips away your safety net.
Verification
Before pushing, verify that the large object is completely absent from the commits you are about to send.
Run git log with the file path against your remote branch:
bashgit log origin/main..HEAD -- data/local_dev.db
If that prints nothing, the file does not exist in any commit between origin/main and your current branch tip. You can run your push:
bashgit push origin feature-auth
The remote will accept the branch without mentioning LFS or payload sizes.
Published by the Old Lane Developer Desk. This article was drafted with AI assistance.


