What to do when gitignore is not ignoring files as expected

What to do when gitignore is not ignoring files as expected

Table of Contents

A long time ago in a galaxy far, far away…

This post is over 24 months old, that is an lifetime in tech! Please be mindful of that when reading this post, young Padawan, as it could be outdated. I try to keep things up to date as much as possible. If you think something needs updating, please let me know in the comments.

Scenario

You are working away on a git repository and have been committing things regularly like a newly seasoned pro when all of a sudden you decide that you no longer want to track a file or directory within your repo. Why might you do this? Perhaps it’s not relevant to the repo itself, or perhaps it’s a runtime file (such as a debug file), or perhaps it’s a user specific file (such as a log file), or perhaps it’s just too damn big for your repo.

Problem

So your first attempt at resolving this would be to add the file or folder to your .gitignore file and you would be right! However, there is just one problem…when you next check the status of your repo, your .gitignore file will be updated but the file you wanted to ignore is still there! That’s because .gitignore will only ensure that untracked files aren’t tracked - if you have already tracked a file it will not be untracked by simply adding it to the .gitignore file.

Working Example

In order to completely untrack a file you need to remove it by running a few commands. If you want to play along, here is some code to get it up and running. This will create a folder in your home folder, set it up as a git repo then create a file and commit it;

# go to your home directory, windows users run cd %userprofile%
cd ~ 
# create a directory called getrid and turn into a git repository
mkdir getrid 
git init getrid
# enter directory
cd getrid 
# create an empty file we want to keep 
echo > want-to-keep.md 
# create an empty file we are going to change our mind about
echo > cant-delete-me.md 
# stage changes (which will be our new files)
git add . 
# check status
git status
# commit the staged changes
git commit -m "adding file we want to ignore" 

Here is the output:

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
        new file:   cant-delete-me.md
        new file:   want-to-keep.md

Running git status will tell you that there are no changes to commit. We have currently got two files committed. But now we have decided we don’t want to include the cant-delete-me.md file in our repository. If you add it to your ignore file;

# editing the file to create a change
echo foo >> cant-delete-me.md 
# add our file to .gitignore
echo cant-delete-me.md >> .gitignore
# check status
git status 

Here is the output from git status;

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   cant-delete-me.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore

Not quite what we were after. Now we have one file listed in the changes not staged for commit (our to be ignored file) and one file in the untracked files section, this is our newly created .gitignore file. Whilst we have asked Git to ignore the file, it is still tracking changes in it.

Solution

To prevent Git from tracking the file we need to remove from the index. The index is seeded from your last commit and is used to determine what changes have been made since that commit. To ensure that Git doesn’t consider the changes on our file, we need to remove it from the index by running the following command;

# unstage changes
git reset
# clear file from being tracked
git rm --cached cant-delete-me.md
# check status
git status

Here is the output from git status;

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    cant-delete-me.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore

This looks better! Now .gitignore is showing as untracked but importantly, the file we want to ignore is showing as being deleted. Note, this isn’t going to delete the file from the file system, but because Git is ignoring the file now it appears to git that is has been deleted, hence why this is the status that is being displayed. So lastly, we want to commit our changes;

# stage changes
git add .
# commit changes
git commit -m "Now I can ignore you"

Now if I make a change to cant-delete-me.md file, it won’t be picked up by git status;

# editing the file to create a change
echo bar >> cant-delete-me.md
# what is the status
git status

Here is the output from git status;

nothing to commit, working tree clean

So even though we made an adjustment to our md file, it hasn’t been picked up by Git. Result!

Clean Up

cd ..
# this will remove the directory called getrid and all content
rm -rd getrid

Further Reading

Comments

#mtfbwy