0

I accidentally committed a large zip file and pushed to bitbucket.

Now, I have already added the file to .gitignore and use git rm --cached to remove it and committed the deletion of the file.

But when I git checkout previous commit, the large zip file is still there. Meaning it's still in the git repo.

How can I remove this large zip file completely ?

Thanks in advance.

Jacob Goh
  • 19,800
  • 5
  • 53
  • 73
  • How many commits have been added to the branch since the commit containing the large binary file? The easiest option might be to amend that commit, and remove the file. – Tim Biegeleisen Sep 07 '16 at 08:10
  • @TimBiegeleisen just one. the 2nd last commit added the large file. the last commit remove the large file. – Jacob Goh Sep 07 '16 at 08:12
  • @TimBiegeleisen hmm.. how to amend? by using `git revert` ? – Jacob Goh Sep 07 '16 at 08:14
  • you need do `git rebase` to rewrite commit history, see https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History for how to do it. maybe `git filter-branch` fit your question more. – gzh Sep 07 '16 at 08:15
  • Possible duplicate of [How to remove/delete a large file from commit history in Git repository?](http://stackoverflow.com/questions/2100907/how-to-remove-delete-a-large-file-from-commit-history-in-git-repository) – Julien Lopez Sep 07 '16 at 08:19
  • @JulienLopez Perhaps not an exact duplicate here, because he might be able to simply get away with using `git commit --amend` . – Tim Biegeleisen Sep 07 '16 at 08:21
  • @TimBiegeleisen Agreed, I haven't paid attention to the comments, your solution should be enough in this case. The possible dup is related anyway. – Julien Lopez Sep 07 '16 at 08:26

2 Answers2

2

Because you only have one commit on top of the commit containing the large binary file, you might be able to avoid an interactive rebase.

First, nuke the second commit you made removing the large binary file:

git reset --hard HEAD~1

This leaves you in exactly the state you were when you had just committed the large binary file.

Now, at this point the large binary file should again appear locally. Delete this file, then add that change to the index if Git has not already done that for you.

Finally, amend the bad commit via:

git commit --amend

To push this branch to Bitbucket you will have to force push because you rewrote the history:

git push --force origin feature

Keep in mind that force pushing rewrites the remote history, which can cause problems for anyone else sharing this branch. In your case, the benefits of doing this probably outweight having an enormous binary being part of your history.

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • This seems great if the commit you nuke only added the large binary file. If it did anything else too `git reset --hard HEAD~1` will lose it. Wouldn't `git reset HEAD~1` without `--hard` be safer? – dumbledad Sep 07 '16 at 08:21
  • yes @dumbledad other files are committed together with the large binary file – Jacob Goh Sep 07 '16 at 08:22
  • 1
    @dumbledad The commit I suggest nuking only removes the large binary file AFAIK, so no real work would be lost. Then, the remaining commit is _amended_ after the binary has been deleted from the file system. – Tim Biegeleisen Sep 07 '16 at 08:24
  • i am testing this out. Thanks @TimBiegeleisen – Jacob Goh Sep 07 '16 at 08:25
  • Definitely read [git reset demystified](https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified) before using that `--hard` option often. – dumbledad Sep 07 '16 at 09:29
0

The safest and probably cleanest way to go is to rebase interactively.

git rebase -i HEAD^^

Or,

git rebase -i your-commit-no^

From there you can squash commits, which puts one or more commits together into the previous commit. To completely delete a commit from the history, delete the line from the list.

You can revert a commit with

git revert 

but its going to add more commit messages to the history, which may be undesirable. Use the -n parameter to tell Git not to commit the revert right away. You can rebase interactively and squash those on up to a previous commmit to keep things clean.

If the two commits you're working with here affect the same file(s), you may see a merge conflict.

Resetting the repository with

git reset --hard 

should be done with care, as it cannot be undone.

Rewriting history should be done with care.