0

Without really thinking about it, I've been committing and then pushing to my Github repository the images I am using in development.

After discovering that this was causing issues that prevented me from pushing my project to my branch, I searched for a solution to remove those images from my repository then add those images to my gitignore file.

I found several solutions: StackOverflow, this blog, git and a few others. They all seemed to be pushing me the same way:

git rm --cached -r /public/uploads/image/file/** 

I've run a few variations of this code, like dropping **, file/**, --cached, and image/file/**, but it doesn't change the fact that I can still see the files on my GitHub branch.

Also I've added this to my gitignore file: /public/uploads/image/file/**

But when I push to the repository branch I get this info telling me why I can't push to Github:

I started from git add . for context.

ruby 2.3.3-p222
╳  project_name categories ◆ git add .                                                               

ruby 2.3.3-p222
╳  project_name categories ◆ git commit -m "trying to get a commit in after purging development environment image data"
[categories 8c13b0a] trying to get a commit in after purging development environment image data
 1 file changed, 1 insertion(+), 3 deletions(-)

ruby 2.3.3-p222
╳  project_name categories  git push origin categories                                               
Counting objects: 3840, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3664/3664), done.
Writing objects: 100% (3672/3672), 163.83 MiB | 3.98 MiB/s, done.
Total 3672 (delta 1242), reused 0 (delta 0)
remote: Resolving deltas: 100% (1242/1242), completed with 57 local objects.
remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com.
remote: error: Trace: 85ba931580b369a222fcf5903416f84e
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File public/uploads/image/file/30/show_55MiEk4_-_Imgur.gif is 119.49 MB; this exceeds GitHub's file size limit of 100.00 MB
To git@github.com:Lenocam/project_name.git
 ! [remote rejected] categories -> categories (pre-receive hook declined)
error: failed to push some refs to 'git@github.com:Lenocam/project_name.git'

So, now I'm confused because doesn't adding /public/uploads/image/file/** to my gitignore file tell git to ignore the folder and the files inside of it? Why does the file continue to be pushed to my repository?

It seems to me I've asked git/Github to get rid of those old files(through the terminal command) and completely forget they ever existed so they will stop asking me about them(through gitignore).

I assume I've done something out of order or otherwise incorrectly. Any assistance you're able to give me will be appreciated.

Community
  • 1
  • 1
Lenocam
  • 331
  • 2
  • 17

2 Answers2

4

.gitignore doesn't really ignore files

In Git, a file is tracked if and only if it is in the index.1

If a file is in the index and you make a new commit, that file goes into the commit. This happens regardless of whether the file name is in .gitignore.

Once a file is in a commit, it is in that commit forever. The only way to avoid it is to stop using that commit entirely.

What .gitignore does is to make Git stop whining. For each file you have in the work-tree,2 but not in the index, Git complains: "hey, this file is in the work-tree but not in the index! Maybe you should add it!" But some files that do belong in the work-tree do not belong in any commit, and hence should never go into the index.

Putting the file—or a matching glob pattern, e.g., anything using * or **—into .gitignore tells Git: "Don't complain, and also, if it's not already in the index, don't automatically add it either with git add -A etc." But it doesn't take the file out of the index, and it literally can't take the file out of any existing commits that have it.

To remove a file from the index, without removing it from the work-tree, use git rm --cached.3

You not only have (or had) the file in the index—which means that git add -A updates it in the index—you also have it in some commit you have not yet pushed. So removing it from the index is not sufficient. You must abandon each commit that contains the large file.

To do so, you probably want to use git rebase -i to copy that commit (or those commits) to a new and improved version, where the improvement is simply "do not include the file in the commit".

See also Can't push to GitHub because of large file which I already deleted.


1The index is where you build the next commit. It is not a commit itself, but when you run git commit, Git packages up the index contents to make the new commit.

2The work-tree is simply the place where you work on your files, since the form of files inside Git's index and Git's commits is unusable for normal work.

3Note that you should not let the shell expand any glob patterns you are using in your .gitignore files, for two reasons. First, the shell expansion may not match that done by Git. Specifically, not all shells expand ** at all, and those that do, do not always do it the same way. Second, the work-tree contents may differ in significant ways from the index contents: for instance, if you have public/uploads/image/file/1 in the work-tree but not in the index, the shell, which looks at the work-tree, may include that in its glob expansion, while Git, which looks only at Git's index when doing git rm, would not put that in the list of files to remove—and as soon as Git finds one file it can't remove from the index, it stops removing other files.

Community
  • 1
  • 1
torek
  • 448,244
  • 59
  • 642
  • 775
  • Thank you for your deep explanation. I followed the link and ran this command `git filter-branch --index-filter 'git rm -r --cached --ignore-unmatch public/uploads/image/file/30/show_55MiEk4_-_Imgur.gif' HEAD` It has removed the file from the commits, I pushed to the repository and got this error: `remote: error: File 2b0baafa8f4c5dc203a53ec92f0db5730284516f` It's the same issue but without a path. I searched manually but still have no idea where this file comes from. Should I run the same command again but replace the file path with `2b0baafa8f4c5dc203a53ec92f0db5730284516f`? – Lenocam Jan 19 '17 at 21:06
  • That's a bit odd, if it just says `remote: error: File `. It's coming from the other Git (on GitHub, presumably) but that's not the way they report problems, normally. You'll need to contact them to find out why they are reporting that. – torek Jan 19 '17 at 22:01
2

git rm --cached -r /public/uploads/image/file/**

You have added the file to .gitignore after it was already added to git. Look like your ignore pattern doesnot match the file pattern

public/uploads/image/file/30/show_55MiEk4_-_Imgur.gif 

Add the following pattern to the .gitignore

/public/uploads/image/file/**/**

You first have to remove it and than push it again.

git rm --cached <file>
git commit -m "Message"

git push ....
CodeWizard
  • 128,036
  • 21
  • 144
  • 167
  • Shouldn't `/file/**` delete everything inside the folder `file` including folder `30` and its contents? or am I misunderstanding `**`? – Lenocam Jan 19 '17 at 17:05
  • From my terminal: `git rm --cached -r public/uploads/image/file/**/** fatal: pathspec 'public/uploads/image/file/1' did not match any files` On one hand it says, there are no files in here, on the other, when I try to push it, it says one of the files I'm trying to ignore is too big. – Lenocam Jan 19 '17 at 17:27