Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git push trying to push files not listed in git ls-files

Tags:

git

github

I accidentally committed an unnecessary large subfolder xxxxx in my repo, and when I realized this while pushing, I stopped the push midway through.

Then I removed an unnecessary folder xxxxx from the repo using

git rm -r --cached xxxxx

But while ls-files does not show the xxxxx folder, git is still trying to push it when I do git push:

git push --verbose
(...)

Counting objects: 19, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (18/18), done.
POST git-receive-pack (chunked) 
Writing objects: 100% (19/19), 132.93 MiB | 197.00 KiB/s, done.
Total 19 (delta 5), reused 0 (delta 0)
remote: warning: File xxxxx/a.csv is 72.22 MB; this is larger than GitHub Enterprise's recommended maximum file size of 50.00 MB
remote: error: GH001: Large files detected.
remote: error: File xxxxx/b is 112.37 MB; this exceeds GitHub Enterprise's file size limit of 100.00 MB

How make git permanently forget about "xxxxx" folder and its contents?

like image 441
dust Avatar asked Jan 07 '23 01:01

dust


1 Answers

git push does not push files, it pushes commits. Specifically, it pushes commits that you have that they don't (whoever "they" are—the remote to which you are pushing). They are complaining that at least one of your commits contains at least one large file.

You'll need to push some different commits, so that the commits you're pushing don't contain the large file.

As a general rule, the way to do this is to take each "good" commit intact, copying it to a new branch, and for each "bad" commit, extract the good parts, remove the bad parts, and make a new commit out of the result. For instance, suppose this is a drawing of the commits the remote has:

A <- B <- C <- D    <-- origin/master

Suppose you've added three commits but there's a problem in the middle one:

A - B - C - D       <-- origin/master
             \
              E - F - G   <-- master

When you run git push your git sends commits E, F, and G, and the remote complains because F has file(s) it should not. To fix this you can simply copy E to a new branch—we'll call the copy E'—then copy-but-fix F to make F', then copy G to make G'. Let's also rename the old ("bad") master; in fact, let's just drop the name entirely, so that we have this instead:

              E' - F' - G'   <-- master
             /
A - B - C - D       <-- origin/master
             \
              E - F - G      [abandoned]

The git command that does this copying is git rebase. Normally it just copies straight through; you want it instead to copy E, but then stop and let you fix F, and then copy G, and the way to get it to do that is to use the -i or --interactive flag.

In general, you should only copy-while-changing commits that only you have, but fortunately this is exactly the set that git push should be pushing, and whatever branch you're pushing, origin/branch (or whatever the remote name is, if it's not origin) will delimit the commits that the remote has (and other people have).

Interactive rebase can do a lot more than this, so see the Git Book for instructions. It's also up to you to figure out which of your commit(s) contain which large file(s); for this, git show and git diff are helpful tools.

like image 187
torek Avatar answered Jan 09 '23 15:01

torek