This question arises from reading and commenting on another question: Git ignore file for Xcode projects
While Adam's answer (and accompanying gist) appears definitive, I cannot actually get it to work. My understanding of the gitignore syntax seems incomplete.
My setup: OSX 10.8.2, git version 1.7.9.6 (Apple Git-31.1). There are no global gitignore files.
I am testing on a new project created with the OSX Application template in Xcode 4.5.
This is the test project file layout:
./.gitignore
./MyApp
./MyApp/AppDelegate.h
./MyApp/AppDelegate.m
./MyApp/en.lproj
./MyApp/en.lproj/Credits.rtf
./MyApp/en.lproj/InfoPlist.strings
./MyApp/en.lproj/MainMenu.xib
./MyApp/main.m
./MyApp/MyApp-Info.plist
./MyApp/MyApp-Prefix.pch
./MyApp.xcodeproj
./MyApp.xcodeproj/project.pbxproj
./MyApp.xcodeproj/project.xcworkspace
./MyApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata
./MyApp.xcodeproj/project.xcworkspace/xcuserdata
./MyApp.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad
./MyApp.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate
./MyApp.xcodeproj/xcuserdata
./MyApp.xcodeproj/xcuserdata/admin.xcuserdatad
./MyApp.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes
./MyApp.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/MyApp.xcscheme
./MyApp.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist
I set up the test project with source control disabled, then initialise the git repo manually in Terminal. The working directory is the project directory:
git init
git add .
git commit -m "first commit"
which returns a list of committed files:
13 files changed, 5204 insertions(+)
create mode 100644 MyApp.xcodeproj/project.pbxproj
create mode 100644 MyApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata
create mode 100644 MyApp.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate
create mode 100644 MyApp.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/MyApp.xcscheme
create mode 100644 MyApp.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist
create mode 100644 MyApp/AppDelegate.h
create mode 100644 MyApp/AppDelegate.m
create mode 100644 MyApp/MyApp-Info.plist
create mode 100644 MyApp/MyApp-Prefix.pch
create mode 100644 MyApp/en.lproj/Credits.rtf
create mode 100644 MyApp/en.lproj/InfoPlist.strings
create mode 100644 MyApp/en.lproj/MainMenu.xib
create mode 100644 MyApp/main.m
After each .gitignore test I reset by deleting the .git folder and reinitialising.
If .gitignore is this
AppDelegate.h
then
./MyApp/AppDelegate.h
is excluded
If I change .gitignore to
AppDelegate*
Both of these are excluded
./MyApp/AppDelegate.h
./MyApp/AppDelegate.m
as expected
If my .gitignore is this:
AppDelegate*
!AppDelegate.m
Again, only AppDelegate.h
is excluded
This is all as expected
However I can't get reincludes to work when the exclusion rule is a containing folder
For example if my .gitignore is this
xcuserdata
then these files are excluded
./MyApp.xcodeproj/project.xcworkspace/xcuserdata/admin.xcuserdatad/UserInterfaceState.xcuserstate
./MyApp.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/MyApp.xcscheme
./MyApp.xcodeproj/xcuserdata/admin.xcuserdatad/xcschemes/xcschememanagement.plist
Now if I want to re-include the contents of xcschemes
xcuserdata
!xcschemes
the result is the same - !xcschemes
appears to be ignored.
similarly if .gitignore is
en.lproj
these files are excluded
./MyApp/en.lproj/Credits.rtf
./MyApp/en.lproj/InfoPlist.strings
./MyApp/en.lproj/MainMenu.xib
If I wanted to reinclude one of them
en.lproj
!Credits.rtf
the same files are excluded: !Credits.rtf
is ignored.
the manpage for gitignore just says this:
An optional prefix ! which negates the pattern; any matching file excluded by a previous pattern will become included again. If a negated pattern matches, this will override lower precedence patterns sources.
but I am not sure what "lower precedence patterns sources" means, or whether it is relevant here.
What am I missing?
update
Adam has updated his gitignore gist to take account of these issues. I have wrapped his changes into my fork, and also added some notes on how to add or change such a .gitignore when an XCode project is already under git control.