Red Green Repeat Adventures of a Spec Driven Junkie

git: ignore tracked file

In git, ever want to ignore a tracked file that’s in the repository?

This happened to me recently where a commit added an innocent configuration file, .pryrc, to the repository when the project started.

At the time, the .pryrc file did not matter to me. “It looks like a sensible file for everyone in the project to have.”

Doesn't look like anything to me

Begin Nightmare

When I started to have errors like this:

SpiritHands and Emacs Before

I started to investigate the issue. I really like having debugging right in Emacs!

Source of Issue

I found out the issue turned out to be a configuration within .pryrc file, specifically, A gem called SpiritHands. Even the project page lists the error:

NOTE Pry-coolline is currently disabled by default because it doesn't
support full Readline Vi and Emacs emulation. If you really want live
syntax highlighting anyhow without full Readline support, specify
SpiritHands.coolline=true in ~/.pryrc after require
'spirit_hands'. Also, consider contributing a coolline/pry-coolline
PR/fork if you must have this functionality.

source

I just needed to set the SpiritHands.coolline = false and things would be fine, right!?

Well, that change solved my problem, but another problem arose because everytime I run: git status, this is the result.

$ git status
On branch develop
Your branch is up-to-date with 'origin/develop'.

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

        modified:   .pryrc

Oh, since this change is just for me, some team members use a regular terminal for debugging, so they will want to have this option to be different from me.

No problem, let’s just add the .pryrc file to the .gitignore file so I don’t commit it by accident:

$ cat .gitignore
.pryrc

When I run: $ git status, I get:

$ git status
On branch develop
Your branch is up-to-date with 'origin/develop'.

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

        modified:   .pryrc

Huh?! What gives?? Why are changes to this file still displayed! The .pryrc entry is in the .gitignore file!

Understanding git more

I found this explantion on my current situation:

.gitignore will prevent untracked files from being added (without an
add -f) to the set of files tracked by git, however git will continue
to track any files that are already being tracked.

Well, once a file is in the git repository, git will continue to track it, even if it’s specified in .gitignore!

So, how do I get git to start ignoring a file?

Remove the file from git using: $ git rm --cached. This removes the file from the system and staged the commit which is a kind of two-for-one deal.

$ git rm --cached .pryrc
rm '.pryrc'

$ git status reports:

$ git status
On branch develop
Your branch is up-to-date with 'origin/develop'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        deleted:    .pryrc

and the system lists: ,

$ ls .pryrc

No more file, so I’ll restore it later.

After committing this change to the git repository, git can start ignoring this file. Let’s make a quick commit to test:

$ git commit -m 'untrack file'
[fix/untrack_file_pryrc 12345678] untrack file
 1 file changed, 9 deletions(-)
 delete mode 100644 .pryrc
$ git status

When adding the file back:

$ touch .pryrc
$ ls .pryrc
.pryrc
$ git status
On branch develop
Your branch is up-to-date with 'origin/develop'.

nothing to commit, working tree clean

Now I can have my own version of .pryrc, with SpiritHands.coolline= false, and everyone can have their own configuration.

SpiritHands and Emacs After

Aaaah, life is better.

Conclusion

So, to ignore a tracked file in git, one must:

  • remove the file
  • add the file to the .gitignore
  • commit the change of the file removal and the update .gitignore file
  • resurrect the file
  • continue working

Whew… so the real lesson is:

Don't commit any file to the repository unless it's absolutely necessary!

Yes, even configuration files. Why? Because removing it is much harder than I thought. This file taught me that pain!