How to remove a too large file in a commit when my branch is ahead of master by 5 commits
I've been stuck all day on this issue, looking for an answer here :( ...
Context
I'm working alone on a project and I used github until now to save my work other than on my computer. Unfortunately, I added a very large file to the local repository : 300mb (which exceed Github's limit).
What I did
I will try to make an history of what I made :
-
I (dumbly) added everything to the index :
git add *
-
I committed changes :
git commit -m "Blablabla"
-
I tried to push to origin master
git push origin master
It took a while, so I just CTRL+C, and repeated step 2 and 3 four times, until I realised that a file was too large to be pushed to github.
I made the terrible mistake to delete my large file (I don't remember if I did a git rm or a simple rm)
I followed the instructions on (https://help.github.com/articles/remove-sensitive-data)
When I try to git filter branch, I get the following error : "Cannot rewrite branches: You have unstaged changes."
Thanks in advance !
A simple solution I used:
-
Do
git reset HEAD^
for as many commits you want to undo, it will keep your changes and your actual state of your files, just flushing the commits of them. -
Once the commits are undone, you can then think about how to re-commit your files in a better way, e.g.: removing/ignoring the huge files and then adding what you want and then committing again. Or use Git LFS to track those huge files.
Edit: this answer is also acceptable if for instance your commits needed authentication (e.g.: username and email) and that you need to add the proper credentials after having commited. You can undo things the same way.
Question: would someone have a way to just cherrypick the commit that is bad and change it directly? I'm asking especially in the case of someone who would just need to re-authenthify his commits like in here, but in a case where the files needs not to be changed. Only commits to authentify.
When you deleted your file, that will be a change and that is the unstaged change that git is complaining about. If you do a git status you should see the file listed as removed/deleted. To undo this change you should git checkout -- <filename>
. Then the file will be back and your branch should be clean. You can also git reset --hard
this will bring your repo back to the status where you made your commit.
I am assuming that it is the last commit that has the very large file that you want to remove. You can do a git reset HEAD~
Then you can redo the commit (not adding the large file). Then you should be able to git push
without a problem.
Since the file is not in the last commit then you can do the final steps without a problem. You just need to get your changes either committed or removed.
http://git-scm.com/book/en/Git-Tools-Rewriting-History
The github solution is pretty neat. I did a few commits before pushing, so it's harder to undo. Githubs solution is : Removing the file added in an older commit
If the large file was added in an earlier commit, you will need to remove it from your repository history. The quickest way to do this is with The BFG (a faster, simpler alternative to git-filter-branch):
bfg --strip-blobs-bigger-than 50M
# Git history will be cleaned - files in your latest commit will *not* be touched
https://help.github.com/articles/working-with-large-files/
https://rtyley.github.io/bfg-repo-cleaner/
This is in reference to the BFG post above, I would comment directly, but I have no idea how to do so as a low reputation new user.
You may want to do a 'git gc' to repack first.
I had issues getting BFG to work until I did so, this appears to be a common issue if you've only been working in a local repo and are prepping stuff to put up on a remote for the first time.
Relevant google hit which twigged me to it: https://github.com/rtyley/bfg-repo-cleaner/issues/65
It seems your only problem is having unstaged changes. You didn't give any detail as to what was actually out of sync, so it's a shot in the dark, but assuming you simple-rm
d the file in step 4, you'd bring it back from the index with:
git checkout large_file
If not, you're on your own. Your goal is to make sure both your index and your working tree are in the same state. This shows as git status
reporting nothing to commit, working directory clean.
The nuclear option to ensure a clean tree would be git reset --hard
. If you want to try that, do backup your tree+repo beforehand.
Once your working copy is clean, you can proceed with your steps 5 and 6.