Kamal Fariz Mahyuddin on Ruby on Rails, Ember.js and other web development geekery.

You should follow me on twitter here.

Git Tip: Ignoring Icon\r in .gitignore

If you have a git repository at the root level of a writable disk image, you may notice that Mac OS X litters it with various junk.

MBP:foo(master) kamal$ git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#   .DS_Store
#   .VolumeIcon.icns
#   .fseventsd/
#   "Icon\r"

Three out of four of the files above is an easy .gitignore entry away. The last one, "Icon\r", on the other hand, is quite a bitch. I tried various permutations of it in .gitignore with no luck. Icon, "Icon", "Icon\r", nothing worked.


The trick is to use the literal ^M control character in the name. Yup, Apple decided that the file name should contain an actual CRLF! But there’s a trick to this trick: you need two ^M characters. Credits go to this post for the solution.

Here’s how your .gitignore should look like in vi:


A quick check,

MBP:foo(master) kamal$ git status
# On branch master
nothing to commit (working directory clean)

All clean!

Those Are Not Caret-Ms

It took me a while to figure out how to create a control character. Everything I searched on Google was concerned with removing them. I even booted up Windows XP in VirtualBox to create a text file in Notepad in the hopes of copy-and-pasting it.

Finally, in a fit of desperation and being the respectable Rubyist that I am, I fired up irb and wrote that mofo to the .gitignore file directly.

>> f =".gitignore", "a+") # append
=> #<File:.gitignore>
>> f.write("Icon\r\r")
=> 8
>> f.close
=> nil

There! Done! Err, maybe someone can tell me the easy way to do it. What’s the keystroke in vi?

Anyway, if you can’t be arsed, let me save you the trouble. Here’s a copy of my .gitignore. Download, rename and stick it in your repo.

Make It Global

Here’s a little tip: create the .gitignore in ~ to make it apply across all repos. It’s additive — git status will use the contents of both the local .gitignore and ~/.gitignore. My strategy is to ignore project-specific junk like *.log and database.yml in the repo itself and general annoyances like above in ~/.gitignore. In a later post, I’ll put up examples of each and explain them line by line.

What’s With the Disk Image in the First Place?

Being paranoid, I’ve begun to store client work on encrypted disk images. I can’t stress this enough: if you’re a developer, it’s your responsibility to secure your client’s source code in the event of theft! Can you imagine the shit storm and liability you’ll face if your laptop got stolen?

To manage the disk images, I’m currently trialing Knox. It does cost some money even though it uses the same backend you get for free via FileVault and Disk Utility. However, the difference with Knox-created images is the disk images grow on demand and it makes it really easy to switch between images. FileVault, on the other hand, applies it to the entire home directory while Disk Utility images take up the entire space at creation time.

Hope this entry helps someone out there.

Fork me on GitHub