407

Currently I have

  1. Empty GitHub repo
  2. SSH server repo (main)
  3. Local Repo

SSH server repo was the most up-to-date repo (production site) so I did a Git clone from there to local. I then tried to do a git push to GitHub.

Everything went OK but then it said something about filename.gz being too large for GitHub. I didn't need this file so I ran several Git commands to get rid of it from Git cache then pushed back to SSH server.

I don't see the large file locally but it's still on SSH server even though git diff returns nothing and git push returns "Everything is up-to-date" - And even though the file is not visible in local repo when I try to push to GitHub I still get error about it

remote: error: File fpss.tar.gz is 135.17 MB; this exceeds GitHub's file size limit of 100 MB

I followed steps under "fixing the problem" listed on GitHub help so shouldn't that have been enough?

How is the file still in the ether when it's not local or listed in git status/diff/push?

random
  • 9,571
  • 10
  • 67
  • 79
The Atlantean
  • 4,853
  • 6
  • 20
  • 29
  • 3
    The file is still there in history. You need to destroy the history, possibly by squashing the commits that added and removed the file. – Shahbaz Oct 24 '13 at 17:55
  • 1
    @Shahbaz I followed steps under "fixing the problem" listed on this site...shouldn't that have been enough? https://help.github.com/articles/working-with-large-files – The Atlantean Oct 24 '13 at 17:57
  • The command there is more advanced than my knowledge of git, so I can't really tell. Anyway, if `git log -- the_big_file` is returning you anything, then the file is still in the history. – Shahbaz Oct 24 '13 at 18:05
  • @Shahbaz that returns nothings > – The Atlantean Oct 24 '13 at 18:06
  • Could it be that you are also pushing other branches where the file exists? Also, if the file is still on the server, why would `git push` say everything is up-to-date? Since you changed history, it should have complained that the push is not possible and that you would have to force it. – Shahbaz Oct 24 '13 at 18:10
  • Exactly, it's not making sense. There is only 1 branch master. Remote ssh has master + a dummy branch (i created so i could push to it's master). @Shahbaz – The Atlantean Oct 24 '13 at 18:13
  • If you have the terminal where you did all these open, it would probably help if you paste the exact commands and messages (removing personal info). There could be something that to you seems unimportant but in reality is. – Shahbaz Oct 24 '13 at 18:15
  • May do that, but here's a Q. If everything in it's current state is ok and I do not need the previous histories. Can I just delete git folder and redo git init on local then try pushing to GitHub without any issues? @Shahbaz – The Atlantean Oct 24 '13 at 18:18
  • Yes think I may do this @Shahbaz http://stackoverflow.com/questions/9683279/how-do-i-remove-all-version-history-for-a-git-github-repository – The Atlantean Oct 24 '13 at 18:21
  • 1
    If your history doesn't matter to you, sure you can do that. It wouldn't be nice though. One thing you could do is create a branch specifically for github, squash all your history in a single commit (effectively the same as what you said, but not deleting other branches) and only push that particular branch to github. Later, when there are commits in the `master` branch for example, you can cherry-pick all of them and apply to the github branch. (not sure if merge would work, but if it could, then that would be even better) – Shahbaz Oct 25 '13 at 09:44

21 Answers21

573

You can use

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch <file/dir>' HEAD

This will delete everything in the history of that file. The problem is that the file is present in the history.

This command changes the hashes of your commits which can be a real problem, especially on shared repositories. It should not be performed without understanding the consequences.

MacGyver
  • 6,187
  • 1
  • 17
  • 11
  • 1
    Could you explain a bit why this works or point toward the relevant man page(s)? – rcorty Apr 23 '15 at 19:39
  • 34
    Worked for me but I had to 'force' it: git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch ' -f HEAD – alexoviedo999 May 09 '15 at 03:39
  • So helpful. It fixed my problem. – CodeManiak Dec 16 '15 at 03:21
  • 41
    This command changes the hashes of your commits which can be a real problem, especially on shared repositories. It should not be performed without understanding the consequences. – Chris Feb 24 '16 at 18:34
  • 10
    Are you supposed to replace with the name of the file or dir that is causing the problem? – David Rhoden Apr 08 '16 at 00:10
  • 2
    The answer is, "yes, you are", and thanks so much for your answer. – David Rhoden Apr 08 '16 at 00:29
  • 15
    Note that if you want apply these changes to ALL branches, you need to use a `--all` flag instead of `HEAD` – Nick Spreitzer Apr 20 '16 at 23:42
  • still having the issue, after running the command. here is my problem [link](http://stackoverflow.com/questions/39804502/git-is-trying-to-upload-the-file-already-deleted-manually) – Chaudhry Waqas Oct 01 '16 at 14:49
  • WOW you saved my day! Thank you very much This should be marked "answered" – MaxPY Feb 01 '17 at 18:06
  • This was the only solution that worked for me. Then I was able to `git push origin master`, and finally removed any reference of the too large files in the repo. – loretoparisi Feb 21 '17 at 16:27
  • 4
    But am getting this message "WARNING: Ref 'refs/heads/master' is unchanged" – rootcoder Mar 08 '17 at 12:28
  • 12
    I am getting: `Rewrite 657560fa18c030bcfac9132ce1c3541e84a5bc2c (1/10) (0 seconds passed, remaining 0 predicted) /usr/lib/git-core/git-filter-branch: 1: eval: Syntax error: end of file unexpected` – João Abrantes Apr 14 '17 at 11:27
  • this is absolutely magical. I was trying to push code from last three days. saved my life. cheers. – nadafafif Apr 28 '17 at 05:14
  • 2
    CAUTION ! Only run the command in the answer IF YOU DO NOT NEED THE FOLDER/FILE anymore ! I just ran it and lost an entire folder of code. Luckily it was backed up on the remote server. – Qubix Aug 21 '17 at 09:57
  • This very similar answer worked perfectly for me: https://stackoverflow.com/a/45403169/2308190 – Ben Wheeler Sep 14 '17 at 19:40
  • 3
    I am getting the error:: "cannot rewrite branches: you have unstaged changes. I tried staging everything, but it still does not work. I have tried many things, I have asked a related question about using git-amend but I don't understand either how that works https://stackoverflow.com/questions/48699317/what-is-a-comment-in-commit-editmsg-in-github – pwprnt Feb 09 '18 at 19:38
  • 3
    Any chance you could edit your answer to include this disclaimer: "This command changes the hashes of your commits which can be a real problem, especially on shared repositories. It should not be performed without understanding the consequences." because this is the first google result for this problem and this is the top answer and it completely breaks a local repo if you do it. I should have read the comments before running this, that was my bad, but perhaps we can save others from making the same mistake. – Kurt Wheeler Jan 10 '19 at 20:51
  • Note to Windows users, use double quotes `"` instead of single quotes. – Chris Gong Jan 16 '19 at 00:43
  • @KurtWheeler I added it. – MacGyver Jan 17 '19 at 08:01
  • 2
    This one messed up my repo, cant pull or push. Completely screwed it. – tmarois Feb 12 '19 at 03:33
  • 2
    i'm getting this : `fatal: ambiguous argument 'rm': unknown revision or path not in the working tree.` is that because the file is deleted? – T.Nel Aug 28 '19 at 08:48
  • @T.Nel, my file was deleted, but no the folder. Maybe you removed a folder too? You may have to try with the `-f` to force the removal. – Alexis Wilke Mar 19 '20 at 06:10
  • Dude, you're awesome and just saved my project! Thank you so much, this worked BEAUTIFULLY!! :) Can't say thank you enough. – Numabyte Apr 30 '20 at 04:44
  • 2
    DO NOT USE THIS ON A SHARED REPO. IN FACT, DO NOT USE THIS AT ALL. – dvlper Jun 10 '20 at 23:47
  • If you're on Windows you'll need to use "...." instead of '...' , like so: git filter-branch --index-filter "git rm -r --cached --ignore-unmatch folder/file" HEAD -- as per this related question: https://stackoverflow.com/questions/21394563/removing-sensitive-data-from-git-fatal-ambiguous-argument-rm – Gary Nov 22 '20 at 05:55
  • if not using this, what else? – Cristian Traìna Mar 31 '21 at 21:01
  • Now issues the warning: ```WARNING: git-filter-branch has a glut of gotchas generating mangled history rewrites. Hit Ctrl-C before proceeding to abort, then use an alternative filtering tool such as 'git filter-repo' (https://github.com/newren/git-filter-repo/) instead. See the filter-branch manual page for more details; to squelch this warning, set FILTER_BRANCH_SQUELCH_WARNING=1.``` – Roly May 11 '21 at 13:24
  • It Worked! Thank you so much for adding this – Arpan Saini Jul 19 '21 at 21:06
184

I found squashing more useful than filter-branch. I did the following:

  1. Locally delete large files.
  2. Commit the local deletes.
  3. Soft reset back X number of commits (for me it was 3): git reset --soft HEAD~3.
  4. Then recommit all the changes together (AKA squash) git commit -m "New message for the combined commit"
  5. Push squashed commit.

Special case (from user @lituo): If above doesn't work, then you may have this case. Commit 1 included the large file and Commit 1's push failed due to large file error. Commit 2 removed the large file by git rm --cached [file_name] but Commit 2's push still failed. You can follow the same steps above but instead of using HEAD~3, use HEAD~2.

aheze
  • 16,189
  • 4
  • 33
  • 81
  • 19
    This is MUCH better than the top answer. The top answer screws up your whole commit history. – manic.coder Jan 04 '19 at 09:31
  • 8
    This is by far the only answer that fixes large uncommitted or committed files, without completely nuking the repository! Upvoted so it can move to the top :-) – Ælex Feb 13 '20 at 10:14
  • Better is a strong word. This is simple a **different** solution. Which one you should choose would depend on what your desired outcome is and/or you current state. – Liam Dec 09 '21 at 11:13
154

Here's something I found super helpful if you've already been messing around with your repo before you asked for help. First type:

git status

After this, you should see something along the lines of

On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

The important part is the "2 commits"! From here, go ahead and type in:

git reset HEAD~<HOWEVER MANY COMMITS YOU WERE BEHIND>

So, for the example above, one would type:

git reset HEAD~2

After you typed that, your "git status" should say:

On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

From there, you can delete the large file (assuming you haven't already done so), and you should be able to re-commit everything without losing your work.
I know this isn't a super fancy reply, but I hope it helps!

Shreya
  • 1,701
  • 1
  • 7
  • 10
45

If the file was added with your most recent commit, and you have not pushed to the remote repository, you can delete the file and amend the commit, Taken from here:

git rm --cached giant_file
    # Stage "giant_file" for removal with "git rm"
    # Leave it on disk with "--cached". if you want to remove it from disk
    # then ignore the "--cached" parameter
git commit --amend -CHEAD
    # Commit the current tree without the giant file using "git commit"
    # Amend the previous commit with your change "--amend" 
    # (simply making a new commit won't work, as you need
    # to remove the file from the unpushed history as well)
    # Use the log/authorship/timestamp of the last commit (the one we are
    # amending) with "-CHEAD", equivalent to --reuse-message=HEAD
git push
    # Push our rewritten, smaller commit with "git push"
BlueMoon93
  • 2,850
  • 20
  • 39
  • 1
    This solution will not work since the file is not anymore in the git index (it results as `untracked` file list at `git status`. – loretoparisi Feb 21 '17 at 16:18
  • Nothing happening. After applying this it reduced total number of file count but after showing process 99% it stuck again. Any suggestion what I'm missing ? – CoDe Mar 08 '17 at 07:57
  • 4
    what does -CHEAD mean? – aerin Oct 18 '17 at 06:48
  • 1
    What if I want to try this from a specific commit--not the very last commit? I tried `git rm --cached giant_file commit_id` but it didn't work :( – puifais Dec 27 '18 at 18:38
  • @puifais I would revert to the previous commit, do these steps, and then merge with the current one. I'm not sure if this is the best approach, I'm not a Git expert – BlueMoon93 Dec 03 '19 at 10:44
19

Why is GitHub rejecting my repo, even after I deleted the big file?

Git stores the full history of your project, so even if you 'delete' a file from your project, the Git repo still has a copy of the file in it's history, and if you try to push to another repository (like one hosted at GitHub) then Git requires the remote repo has the same history that your local repo does (ie the same big files in it's history).

How can I can I get GitHub to accept my repo?

You need to clean the Git history of your project locally, removing the unwanted big files from all of history, and then use only the 'cleaned' history going forward. The Git commit ids of the affected commits will change.

How do I clean big files out of my Git repo?

The best tool for cleaning unwanted big files out of Git history is the BFG Repo-Cleaner - it's a simpler, faster alternative to git-filter-branch specifically designed for removing unwanted files from Git history.

Carefully follow the usage instructions, the core part is just this:

$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-repo.git

Any files over 100MB in size (that aren't in your latest commit) will be removed from your Git repository's history. You can then use git gc to clean away the dead data:

$ git gc --prune=now --aggressive

The BFG is typically at least 10-50x faster than running git-filter-branch, and generally a lot easier to use.

Full disclosure: I'm the author of the BFG Repo-Cleaner.

Roberto Tyley
  • 23,105
  • 11
  • 70
  • 100
16

I had a similar issue and used the step above to remove the file. It worked perfectly.

I then got an error on a second file that I needed to remove: remote: error: File <path/filename> is 109.99 MB; this exceeds GitHub's file size limit of 100.00 MB

I tried the same step, got an error: "A previous backup already exists in <path/filename>"

From research on this website I used the command: git filter-branch --force --index-filter "git rm --cached --ignore-unmatch <path/filename>" --prune-empty --tag-name-filter cat -- --all

Worked great, and the large files were removed.

Unbelievably, the push still failed with another error: error: RPC failed; curl 56 OpenSSL SSL_read: SSL_ERROR_SYSCALL, errno 104 fatal: The remote end hung up unexpectedly

This I fixed by directly modifying the .git config file - postBuffer = 999999999

After that the push went through!

Andre Odendaal
  • 669
  • 7
  • 7
  • 1
    an additional gotcha I had to contend with removing a large file (as above) was that one of the folders had a hash # character in it. This caused no problems at all for normal git operation however for the `git rm` I needed to give the full repository path name for the file and to escape the # with a backslash to get it to work – jacanterbury Nov 01 '17 at 11:04
  • this worked for me, too. I avoided the `reset hard` step at the bottom of the page with a simple push. https://www.czettner.com/2015/07/16/deleting-big-files-from-git-history.html – Monte Hayward Jul 16 '18 at 15:44
  • This worked after also running 'git push -f origin' – kezzos Mar 27 '19 at 10:23
10

I have tried all above methods but none of them work for me.

Then I came up with my own solution.

  1. First of all, you need a clean, up-to-date local repo. Delete all the large files.

  2. Now create a new folder OUTSIDE of your repo folder and use "Git create repository here" to make it a new Git repository, let's call it new_local_repo. This is it! All above methods said you have to clean the history..., well, I'm sick of that, let's create a new repo which has no history at all!

  3. Copy the files from your old, messed up local repo to the new, beautiful repo. Note that the green logo on the folder icon will disappear, this is promising because this is a new repo!

  4. Commit to the local branch and then push to remote new branch. Let's call it new_remote_branch. If you don't know how to push from a new local repo, Google it.

  5. Congrats! You have pushed your clean, up-to-date code to GitHub. If you don't need the remote master branch anymore, you can make your new_remote_branch as new master branch. If you don't know how to do it, Google it.

  6. Last step, it's time to delete the messed up old local repo. In the future you only use the new_local_repo.

Nimantha
  • 5,793
  • 5
  • 23
  • 56
Shuaibin Chang
  • 117
  • 1
  • 2
4

I got the same problem and none of the answers work for me. I solved by the following steps:

1. Find which commit(s) contains the large file

git log --all -- 'large_file`

The bottom commit is the oldest commit in the result list.

2. Find the one just before the oldest.

git log

Suppose you got:

commit 3f7dd04a6e6dbdf1fff92df1f6344a06119d5d32

3. Git rebase

git rebase -i 3f7dd04a6e6dbdf1fff92df1f6344a06119d5d32

Tips:

  1. List item
  2. I just choose drop for the commits contains the large file.
  3. You may meet conflicts during rebase fix them and use git rebase --continue to continue until you finish it.
  4. If anything went wrong during rebase use git rebase --abort to cancel it.
William Hu
  • 14,400
  • 9
  • 91
  • 112
3
git lfs migrate import --include="fpss.tar.gz"

this should re-write your local commits with the new lfs refs

https://github.com/git-lfs/git-lfs/blob/master/docs/man/git-lfs-migrate.1.ronn?utm_source=gitlfs_site&utm_medium=doc_man_migrate_link&utm_campaign=gitlfs#examples

2

The solution to keep the large files/folders within the working folder

This is the line that worked to solve the problem asked here (from answer 1):

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch <file/dir>' HEAD

This command also delete the file/dir if the file/dir is within the working tree.

If you want to keep the file/folder within the working tree I propose taking the following steps.

  1. After that error run git reset HEAD^
  2. Add the file/folder in question into ``.gitignore``` file.

  3. Proceed as usual git add . which might capture other files/folders but must capture .gitignore file. Next is git commit -m"message" and finally git push origin <branch_name>

1

My unorthodox but simple solution from scratch:

  • just forget about your recent problematic local git repository and git clone your repository into a fresh new directory.
  • git remote add upstream <your github rep here>
  • git pull upstream master
  • at this point just copy your new files to commit, to your new local rep from the old one may be including your now reduced giant file(s).
  • git add .
  • git commit -m "your commit text here"
  • git push origin master

voila! worked like a charm in my case.

Emre
  • 269
  • 1
  • 5
1

Somehow this worked for me. I tried all solutions but this command saved my time. Hope this helps you too.


git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch <file/folder path>' --prune-empty --tag-name-filter cat -- --all

Please run this at your own risk. I'll not be responsible for your actions.

Run this command from the root directory

GPrathap
  • 6,717
  • 7
  • 61
  • 77
Mr Mayur
  • 442
  • 4
  • 9
0

this worked for me. documentation from github Squashing Git Commits git reset origin/master

git checkout master && git pull;
git merge feature_branch;
git add . --all;
git commit -m "your commit message"

find documentation here

0

So I encountered a particular situation: I cloned a repository from gitlab, which contained a file larger than 100 mb, but was removed at some point in the git history. Then later when I added a new github private repo and tried to push to the new repo, I got the infamous 'file too large' error. By this point, I no longer had access to the original gitlab repo. However, I was still able to push to the new private github repo using bfg-repo-cleaner on a LOCAL repository on my machine:

$ cd ~
$ curl https://repo1.maven.org/maven2/com/madgag/bfg/1.13.0/bfg-1.13.0.jar > bfg.jar
$ cd my-project
$ git gc
$ cd ../
$ java -jar bfg.jar --strip-blobs-bigger-than 100M my-project
$ cd my-project
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
$ git remote -v # confirm origin is the remote you want to push to
$ git push origin master
Daniel Viglione
  • 6,804
  • 7
  • 56
  • 89
0

Sometimes the file is kept in tracking history, try the following steps:

  1. git commit, If you are seeing create mode with the big file listed, then do:
  2. git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch filename' HEAD. You should see a bunch of Rewrites shown in your console which ends with:

    rm 'filename' and

    the last line Ref was rewritten.

It's done.

Tree DR
  • 359
  • 3
  • 4
0

rather than doing complicated stuff, copy your repo (on your computer) to another place. delete the large file. do a couple of push and pull. Then some of your files will be messed up having things like "<<<<<< HEAD". Just copy your backup into the old folder on the disk. Do another add, commit, push!

OverFlow Police
  • 841
  • 4
  • 16
0

I had this issue when I didn't have a gitignore file with my iOS project

I think maybe it was trying to push a humungous file to github and github was probably rejecting that giant file or (files)

MobileMon
  • 7,847
  • 5
  • 49
  • 69
0

if you are uploading your own project then just go the file where directory is present. Delete large file. then click on the "view"(window file) view-> check hidden folder then you will be able to see '.git' file delete .git file this will delete all your commit history Then you can push your repo like new one...

0

What worked for me:

  1. rename my GitHub project folder to something else
  2. re-clone the repo with the correct folder name
  3. delete the .git folder in my renamed repo (may have to turn on allow to see hidden files in Windows)
  4. move the .git folder from the correct folder name to the renamed one
  5. delete the re-cloned repo folder, rename the original repo folder to the correct name
  6. commit your changes (without the large files) and push
xinthose
  • 2,529
  • 2
  • 35
  • 51
-2

I am adding to the first answer.

git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch ' HEAD

There will be some merge conflict from origin/master.

Your branch and 'origin/master' have diverged, and have 114 and 109 different commits each, respectively. (use "git pull" to merge the remote branch into yours)

Please run this

git reset --hard origin/master

It will throw away all my staged and unstaged changes, forget everything on my current local branch and make it exactly the same as origin/master.

RAHUL KUMAR
  • 947
  • 10
  • 9
-7

Make your local repo match the remote repo with (all locals changes will be lost):

git reset --hard origin/master

Then push again.

Bishwas Mishra
  • 1,122
  • 11
  • 24