We recently started working on a new iOS project. As part of this adventure, I asked the team if we could build a case study around XCode and TFSPreview.com. TFSPreview, if you’re not aware, is Microsoft’s Team Foundation Server 2012 as a service, hosted in Azure.
This isn’t your normal pairing. Mac developers aren’t exactly flocking to the Microsoft stack and the Microsoft development tools haven’t exactly catered to the predominantly OSS community working on Macs. In recent years, though, that has changed. ASP.Net is now OSS, first class Azure tools ship for the Mac, even the Nodejs for Azure tutorials feature Chrome on a Mac. It’s a brave new world out there!
Starting with this post and continuing over the next few months, I’m going to be sharing some of our experiences building iOS/XCode apps on TFSPreview using the cross-platform (yes, they used Java – who are these guys?!) git-tf plugin.
Getting Set Up
For the purposes of these posts, I’m using my personal TFSPreview.com account. It’s licensed and supported for production use so we aren’t worried. There’s an excellent guide for using the Agile Planning tools and inviting team members already, so I won’t go there.
Once you have an account and new Team Project, you’ll also need git installed. I used homebrew for that. I use apt-get for that on my Linux machines, but YMMV on a Mac.
homebrew install git
Git supports a plugin model for commands and other repository integration. It even ships with Subversion (SVN) integration out of the box. We used git-svn earlier this year with great success on a project that was constrained to a central SVN repository.
Microsoft has taken advantage of their Java SDK for TFS to build the git-tf plugin. I’ve used it on both Windows and Mac now successfully.
To install it, head to the Codeplex project and download the latest release. It’s simply a zip file that you should extract to /usr/git-tf. The add it to your PATH. I used my .zshenv since I run oh-my-zsh. You might be using the standard terminal, in which case you would add the following to .bash_profile:
PATH=$PATH:/usr/git-tf # Enabling the git-tf plugin
You’ll need to restart your terminal session for this to pick up.
Cloning The TFS Repo
You should be ready to clone your TFS repository.
When you created your TFSPreview account you also got a Team Project. You can create more, but that’s out of scope for this discussion. My Team Project is called XCode Sample. This is yields the source control path $/XCode Sample. To clone this TFS repository into a git repository, we’ll use this command:
git tf clone https://cromwell.tfspreview.com/DefaultCollection $/XCode\ Sample XCodeSample
The last option, ‘XCodeSample’, is so the git repo doesn’t have a space in it. That would just make me crazy. The URL is the path to our account’s Team Project Collection.
From here you should be able to follow your normal git patterns and the git-tf guide for pulling, fetching, and checkin.
The first hiccup we stumbled across was with dependencies that use symlinks. It turns out that the TFS doesn’t deal well with symlinks. That’s going to be a problem since many libraries use symlinks to specify which version of their product is ‘current’.
As an example, the following project uses the Speech Kit Framework. Here you can see how the library should be represented on the left versus how the cloned git-tf repository appears on the right:
Each of those purple files with the @ are symlinks which point to corresponding folders like Versions/A/Headers and Versions/A/Resources. This allows them to ship many versions side-by-side, yet the consumer can choose which version to target.
Rather than try to commit the symlinks and fight this gap, we remove the symlinks (ie git rm Headers) and commit a setup.sh script. This shell script configures the symlinks necessary for each developer.
I did start a conversation with the git-tf maintainers and they have a plan to resolve this. While TFS itself doesn’t support symlinks, they can add support to Team Explorer Everywhere, the Java TFS SDK and git-tf. I look forward to this being resolved in the near future.