MEM
MEM

Reputation: 31367

Git repo broken? - Files always tracked despite gitignore

I have this directory:

/thumbs

Inside this directory I have a .gitignore file with this inside:

#remove everything
*

#except this:
!.gitignore

If I add an image file into this directory, and I do:

git status

The image file is listed as untracked.

What should I do?

Please note the following:

Inside that directory, I have done:

git rm -r --cached .
git add .
git commit -m "gitignore SHOULD work"

I have removed any extra bottom white spaces on the .gitignore file just to be sure.

Still, if I add the file, it appears as untracked.

Why?

What can I do, in order to see where the problem is?

Update: On this folder:

/user_uploaded_file that is a PARENT folder of /thumbs I have the following gitignore:

#ignore everything
*

#except:
!.gitignore
!/thumbs

Curious fact:

IF, I remove the !/thumbs instruction from this gitignore inside the parent, the git ls-files that we do inside !/thumbs does only consider the .gitignore, as it should. And we can freely add, change or delete image files that git doesn't care.

If, however, we place that line !/thumbsinside the gitignore on the parent folder, it lists the images as untracked.

UPDATE 2

Curious fact II:

If, on the PARENT folder gitignore file we do:

B)

*
!.gitignore
!/thumbs/.gitignore

Instead of:

A)

*
!.gitignore
!/thumbs/

It seems to work. I mean, if we add change or remove files inside /thumbs, git properly ignore them.

However, while this works on this specific local repo, on my own repo, for example, I don't need any of this, and A), works.

:s

Upvotes: 2

Views: 522

Answers (2)

AD7six
AD7six

Reputation: 66319

Something doesn't add up here

Consider the following actions:

$ mkdir -p /tmp/example
$ cd /tmp/example
$ git init .
$ mkdir -p user_uploaded_file/thumbs
$ echo "some noise" > user_uploaded_file/thumbs/somefile
$ git add user_uploaded_file/thumbs/somefile
$ git commit -m "simulate initial dirty state"

$ vim user_uploaded_file/.gitignore
$ vim user_uploaded_file/thumb/.gitignore
$ git add user_uploaded_file/.gitignore user_uploaded_file/thumbs/.gitignore
$ git commit -m "add ignore files from the question"

$ echo "some noise" > user_uploaded_file/thumbs/someotherfile

Checking the current status:

$ git status
# On branch master
nothing to commit (working directory clean)

$ git status --ignored
# On branch master
# Ignored files:
#   (use "git add -f <file>..." to include in what will be committed)
#
#   user_uploaded_file/thumbs/someotherfile

Note that nothing is listed to commit, and using the --ignored flag show which files are ignored.

The thumbs/.gitignore file is being deleted

I have done: git rm -r --cached .

That isn't quite doing what you want, though it isn't a factor in the question:

$ cd user_uploaded_file/thumbs
$ git rm -r --cached .
$ rm 'user_uploaded_file/thumbs/.gitignore'
$ rm 'user_uploaded_file/thumbs/somefile'

It is deleting the undesirable files - but it's also deleting the git ignore file, which can be selectively undone with:

$ git reset HEAD .gitignore
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    user_uploaded_file/thumbs/somefile
#

Note that the .gitignore file isn't shown as deleted now.

Solutions

Rather than focus on what you've done, let's look at solving the problem. As I understand the question the problem is that you have committed noise to the repository and you want to delete it.

Cleaning up one install

To clean up one checkout, all that's required is to delete the files and commit:

$ git ls-files user_uploaded_file/thumbs/
user_uploaded_file/thumbs/.gitignore
user_uploaded_file/thumbs/somefile

$ git status --ignored
# On branch master
# Ignored files:
#   (use "git add -f <file>..." to include in what will be committed)
#
#   user_uploaded_file/thumbs/someotherfile

$ git rm -r --cached user_uploaded_file/thumbs/
rm 'user_uploaded_file/thumbs/.gitignore'
rm 'user_uploaded_file/thumbs/somefile'

$ git reset HEAD user_uploaded_file/thumbs/.gitignore
$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    user_uploaded_file/thumbs/somefile
#

$ git status --ignored
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    user_uploaded_file/thumbs/somefile
#
# Ignored files:
#   (use "git add -f <file>..." to include in what will be committed)
#
#   user_uploaded_file/thumbs/somefile
#   user_uploaded_file/thumbs/someotherfile
#   
$ git commit -m "deleting thumb files"

This deletes the files (though they will still exist in the repository bloating it) then push to the remote

$ git pull
$ git push
...

Check what commit this local checkout is on:

$ git branch -v
* master f216a83 deleting thumb files

Cleaning up other installs

On all other checkouts of the same repository, the only step required to delete these already-tracked thumb files is:

$ git pull
remote: Counting objects: 7, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 4 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (4/4), done.
From /tmp/exmaple2/../example
   41ec014..f216a83  master     -> origin/master
First, rewinding head to replay your work on top of it...
Fast-forwarded master to f216a83940be0e60d560b27a882b9abca46ea383.
$ git branch -v
* master f216a83 deleting thumb files

$ git ls-files user_uploaded_file/thumbs
user_uploaded_file/thumbs/.gitignore

$ git status
# On branch master
nothing to commit (working directory clean)

$ ls -la user_uploaded_file/thumbs/
total 16
drwxrwxr-x 2 www-data www-data 4096 May 13 13:51 .
drwxrwxr-x 3 www-data www-data 4096 May 13 13:30 ..
-rw-rw-r-- 1 www-data www-data   48 May 13 13:30 .gitignore
-rw-rw-r-- 1 www-data www-data    4 May 13 13:49 morefiles

Note that this will only delete the files which were previously tracked.

If the other install is on a different branch - the changes made need merging/cherry-picking as they aren't in that branches history.

If the other install is on the same branch but a different commit then it has local commits - you'll need to check why that is/whether the local commits affect the problem or not.

The git ignore files are over-complex

The contents of the existing git ignore files is not really necessary, they can be this simple:

$ cd /tmp/example
$ echo "*" > user_uploaded_file/.gitignore
$ echo "*" > user_uploaded_file/thumbs/.gitignore
$ git commit -m "ignore everything in the user_uploaded_file folder"

The file user_uploaded_file/thumbs/.gitignore actually serves no ignore purpose, if it is only to ensure the folder exists - you could in fact use an empty file and name it anything.

Upvotes: 0

Michael Durrant
Michael Durrant

Reputation: 96554

First you have to add and commit the .gitignore file in order for gitignore to ignore the file.

If the file(s) in question had previously been committed you will need to git rm [filename] to remove it. Once that is done, if it is then added to your gitignore (and the .gitignore is added and committed) it will be ignored.

Upvotes: 2

Related Questions