The Odd Couple: iOS/XCode and TFSPreview

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, 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

TFSPreview Account

For the purposes of these posts, I’m using my personal 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.

Install Git

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

Install Git-tf

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 $/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 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.


About Ryan Cromwell

Ryan Cromwell is a coder by trade with over 10 years of experience delivering solutions ranging from real-time customer loyalty systems and elegant user experiences to streamlined statistical process control software. Having worked with passionate, high-performing Agile teams, Ryan ventured into the world of training and Agile coaching to replicate those amazing experiences. Ryan is co-founder of the Cincy & Dayton Clean Coders user groups, co-organizer of Southwest Ohio GiveCamp, and all around software community ally. Ryan has led presentations on effective team development, and various topics such as Agile, Scrum, Software Craftsmanship, WPF, Single Page Applications, Software Patterns and more. You can also find Ryan at and on Twitter as @cromwellryan.

  • Shady Ahmed Elyaski

    Nice workaround, but doing “git rm Headers” will prevent other members of the team to build the project…
    Did you find another fix now? I know it has been years =)