.hgignore for Mac OS X applications

2008-03-20 05:37:06 UTC

If you use version control (and you should), then you’re familiar with the pollution that an Xcode build folder can put into your status output:

? build/.DS_Store
? build/Debug/UTI Plist Helper.app/Contents/Info.plist
? build/Debug/UTI Plist Helper.app/Contents/MacOS/UTI Plist Helper
? build/Debug/UTI Plist Helper.app/Contents/PkgInfo
? build/Debug/UTI Plist Helper.app/Contents/Resources/English.lproj/InfoPlist.strings
? build/Debug/UTI Plist Helper.app/Contents/Resources/English.lproj/MainMenu.nib/classes.nib
? build/Debug/UTI Plist Helper.app/Contents/Resources/English.lproj/MainMenu.nib/info.nib
? build/Debug/UTI Plist Helper.app/Contents/Resources/English.lproj/MainMenu.nib/keyedobjects.nib
⋮

Good version-control systems offer a way to ignore any file that matches a certain pattern. In the case of an Xcode project, you want to ignore the build folder and a few other things: .DS_Store files, backup nibs (those Foo~.nib packages that IB creates when you save), etc.

In Mercurial, the way to do that is to create a .hgignore file, and populate it with the patterns you want hg to ignore.

In order to save you repetitive work, here’s a .hgignore file, already fully-populated, that you can use when versioning your Xcode-based project with Mercurial:

File: hgignore.bz2

syntax: glob
build
*.swp

*.mode1
*.mode1v3
*.mode2
*.mode2v3
*.pbxuser
*.perspective
*.perspectivev3
xcuserdata

*~.nib

.DS_Store

What to do with this file

  1. Download it, and save the .bz2 file somewhere such as your Documents folder.
  2. cd into the top level of a repository.
  3. Extract the file using this command line: bunzip2 < ~/Documents/hgignore.bz2 > .hgignore
  4. Add the file: hg add .hgignore
  5. Commit it.

Thereafter, not only do you have a .hgignore file keeping your status output clean, but it’s versioned, so it’s easy for you to track and revert changes to the ignore file over time.

UPDATE 2011-05-05: Updated for Xcode 4.

11 Responses to “.hgignore for Mac OS X applications”

  1. Mark Grimes Says:

    I use git, so not sure if syntax is the same but you might want to exclude default.pbxuser from your all inclusive *.pbxuser
    Also shouldn’t it be *.perspectivev3 these days?

  2. Peter Hosey Says:

    Mark: Having a .hgignore doesn’t prevent you from versioning files that match an ignore pattern. If you have a default.pbxuser that you want to version, go right ahead and do that—nothing’s stopping you.

    As for .perspectivev3: Yup, you’re right. I’m still developing primarily on Tiger, so I forgot about that. I’ll update the file and the post with it.

  3. Andrew Says:

    According to hgrc(5), you can put

    [ui]
    ignore = ~/.htignore

    in your ~/.hgrc, and have this apply to all of your projects automatically.

  4. Peter Hosey Says:

    Andrew: Sure, but then each developer has to repeat that process. If you version .hgignore instead, they get its benefits automatically, from the moment they clone your repository.

    Of course, this way, you have to do it for each new project. It’s a trade-off. I think this way results in less work over the long term.

  5. Till Says:

    I would like to use only one ignore file: ~/.hgignore. But then again I’d like it to ignore all files that have a tmp or temp soewhere within there path. Any idea how to achieve this?

  6. Peter Hosey Says:

    Till: Read Andrew’s comment, and use a regex pattern:

    syntax: regexp

    .*/te?mp/.*

  7. Christopher Says:

    Hi Peter, I don’t know if you are still answering comments to this post, but if so, I’d like to point out that I am using your .hgignore template above for my Xcode project and the portion that should block *.pbxuser, *.perspective, and *.perspectivev3 files doesn’t seem to work for me. I’m actually using Git for my versioning needs right now, but I find Mercurial to be simpler and I would like to use it instead if possible, but this problem is really going to keep me from moving over to it. Any ideas/suggestions on why the ignore file wouldn’t work for just those particular files?

    Thanks for your help.

  8. Peter Hosey Says:

    I don’t use Git.

    It has a manpage describing its ignore format. You might try removing the “syntax: glob” line, which is hg-specific.

  9. Christopher Says:

    Hi Peter,

    I think you misunderstood my question. I was asking why Mercurial was not working with the .hgignore file that you have above. Currently, I use Git for Xcode projects and Mercurial for everything else, and I am trying to switch over to Mercurial for Xcode projects as well, but the .hgignore files do not seem to work properly. I tried your file above, and it works for everything but the last three file types. I was wondering why Mercurial would seem to selectively ignore a few of the lines in the .hgignore file but not others. Have you run into any problems with Mercurial not obeying everything in its .hgignore files?

    Thanks again.

  10. Peter Hosey Says:

    Indeed I did; sorry.

    Are the files already versioned? hg won’t ignore files you’ve told it to track, only files you haven’t. What does hg status or hg log say about them?

    Also, note that, unlike Git, hg requires the .hgignore file to be in the top level. You can’t put it in subdirectories like you can with Git.

  11. Christopher Says:

    Hah, I can’t believe that was it! It never occurred to me that the reason the files weren’t being ignored is because I had already added them to version control. Anyway, I removed them from being versioned and the ignore file worked like a charm. Thanks so much for your help, I really appreciate it. Oh, and thanks as well for the original article, it’s been a lot of help in getting me up and running with Mercurial as my version control software for Cocoa development.

    Cheers,

    Christopher

Leave a Reply

Do not delete the second sentence.