PMills PMills - 3 months ago 9
Git Question

Git is Pushing A File That I've Deleted

Lets say I have a repo, and in said repo at commit X, I tried to upload a video that was over the github upload limit. So, with that in mind, I did a commit immediately after that removes that large file. It's now 8 commits later and I'm trying to push my changes, but every time I do, git is trying to compress and push this video that is 100% not in my file structure anymore, and has been committed out.

Why is this happening? Is there a way I can cherry-pick a commit and have it removed from my git history so when I push, it's not factored into the push, and I can get past this issue?

Answer

Even if the big file is not in your working tree any more, it is still in the repository because there is a reacheable commit that contains it.

It's now 8 commits later...

Assuming you added the big file on commit A (the 8th commit in the past) and you removed it on commit A+1 (the 7th commit in the past) you need to modify the history of your repo, edit commit A and remove the big file from it. If the only change you did on commit A+1 was the removal of the big file you can squash the commit A+1 into commit A and this should solve the problem.

How to do it

  1. Make sure the working tree is clean. Commit or stash any changes you have in the working tree. Also, the following works if the project's history since the problematic commit is linear; there are no branches or merges. Branches or merge commits do not prevent fixing the repository but the procedure is not that straight forward. The next steps assume the history is linear.
  2. Run git log --pretty=online and identify the commit where you added the big file. In fact, you need to find the parent of this commit. You can either count how many commits you created after its parent or you can simply copy its hash from the output of git log. Let's assume you did 8 commits after the erroneous one; the parent of the bad commit is HEAD~9.
  3. Run git rebase --interactive HEAD~9 (or put the hash of the commit instead of HEAD~9).
  4. Git opens your default editor with a file that looks like this:

    pick 1be0057 the commit that adds a big file
    pick 766b3e2 removed the big file
    pick a1adf78 another commit comment
    ......... all the other commits until HEAD ...........
    
    # Rebase aa99b12..aff6d45 onto aa99b12 (9 command(s))
    #
    # Commands:
    # p, pick = use commit
    # r, reword = use commit, but edit the commit message
    # e, edit = use commit, but stop for amending
    # s, squash = use commit, but meld into previous commit
    ......... more lines of explanation here .........
    
  5. Verify that the file starts with (or at least contains) the commit that introduced the big file. If it doesn't then remove everything from the file, save it and quit the editor. Git will see the file is empty and will abort the operation. Check the output of git log carefully and start again.

  6. If the file starts with the commit that added the big file (or contains it on another line) then edit the line that follows it. Replace the word edit from the beginning of the line (the next line, the one that contains the commit where you removed the file) with fixup. Don't change anything else!
  7. Save the file, close the editor, wait for Git to complete the command.

If everything goes well, after Git completes successfully, git log shows you that the commit where you removed the file disappeared. Also, if you check the modifications introduced by the erroneous commit you'll see the big file disappeared too. Now it's possible to push to GitHub.

If the rebase fails (it shouldn't) then you run git rebase --abort and Git restores your repository in the state it was before you started. You can try again or search for a different solution.