Using GitHub For Xcode Source Control

Source code versioning starts to become important with even modest sized projects. While you can use Xcode’s code snapshot feature, setting up a git repository is much better. If you’re a lone programmer working on a project, it is trivial for you to create a local git repository. This article isn’t about that. You can also use OS X Server as a git repository. This is something an organization might want to do. This article isn’t about that either.

Setting up a GitHub repository is a little trickier than I expected. The Xcode documentation is all about using OS X Server or just a local git repository. I did some experimentation and found a way to setup GitHub in a nearly pain free way. There is more than one way to do it. I’m going with a method that works for both existing projects and new projects. Hopefully someone reading this will be able to provide a completely pain free method.

Step one: create a GitHub account. This is pretty easy. I’m currently using a free account, so I can’t do private/hidden repositories. This is perfectly fine for open source projects. GitHub also has a nice little feature where you can tell other users that you are looking for a job. Having code out there shows what you can do.

It’s a good idea to create your account with Safari and let Safari create your password. This gets the password onto your keychain where you can retrieve it later as needed.

Step two: create a GitHub repository for your project. It doesn’t matter if you are creating the repository for an existing project or a brand new one. Use the name of your project for the repository. Try to avoid using spaces. It may not matter, but GitHub will turn them into hyphens.

When you have created your repository, it should look something like this.

Creating a GitHub repository
Creating a GitHub repository

Once you’ve created the repository, you will get a screen like this.

Created Repository
Created Repository

Copy the URL where it says, “HTTPS clone URL”. You will need that for the next step.

Step three: open Xcode. Go to the Source Control menu and choose Check Out… . You will paste the URL for your repository in the checkout dialog that follows.

Checkout Dialog
Checkout Dialog

The first time you do this, you will have to enter your GitHub credentials into Xcode. Let it always allow so that it remembers. That way you don’t have to dig up your password from Key Chain every time you start a new project.

Since we are creating a new project or adding an existing project to GitHub, be sure to choose a directory other than where your project will be. This will become clear later. Do not check the “Source Control” box when you create your project. If you do, don’t panic. You will be replacing the .git directory anyway.

Step four: Create your project in Xcode if you don’t already have one. If you have a project, skip this step. Place the project where you want it. As I said above, make sure that is a different location than you did the checkout. Files getting overwritten is rather inconvenient.

Step five: Open Terminal. This is the part I wish was a little better integrated into Xcode. Never fear though. You are a programmer! This should be comfortable for you. You want to cd to the directory that you did the checkout. You will know you’re there when the following works.

Triton:Foo david$ ls -la
total 32
drwxr-xr-x+  8 david  staff   272 Mar  7 03:14 .
drwx------+ 39 david  staff  1326 Mar  7 03:21 ..
-rw-r--r--@  1 david  staff  6148 Mar  7 03:13 .DS_Store
drwxr-xr-x+ 15 david  staff   510 Mar  7 03:29 .git
-rw-r--r--+  1 david  staff    76 Mar  7 03:15 .gitignore

Don’t worry. I know you don’t have a .gitignore file yet. You will create that now. I prefer to use vim when creating a text file.

Triton:Foo david$ vim .gitignore

You really should have a basic understanding of vim and the shell. Fortunately, what you have to do isn’t so hard. Never be afraid of the command line. The command line is user friendly. It’s just picky about who it’s friends are. However you care to go about it, make sure your .gitignore file contains at least the following lines. You may wish to add others later. You may also chose to download someone else’s .gitignore if you find it more useful for your situation.

.DS_Store
*.xcodeproj/xcuserdata
*.xcodeproj/project.xcworkspace/xcuserdata

Every OS X directory has a .DS_Store. You don’t want to be adding that to GitHub. The second two lines make sure that your personal information that ends up in Foo.xcodeproj (whatever the name of your project file is) doesn’t get added to GitHub. The reason for using Terminal for all this is that dot files (hidden files) do not show up in Finder. The reason for checking out the project from GitHub is to have the contents of the .git directory properly configured for GitHub.

Next, you move your .git and .gitignore over to your project directory. For example (on one line)

Triton:Foo david$ mv .git .gitignore /Users/david/XcodeProjects/Foo

Then cd to that directory and you should see something like the following.

Triton:Foo david$ ls -la
total 32
drwxr-xr-x+  8 david  staff   272 Mar  7 03:14 .
drwx------+ 39 david  staff  1326 Mar  7 03:21 ..
-rw-r--r--@  1 david  staff  6148 Mar  7 03:13 .DS_Store
drwxr-xr-x+ 15 david  staff   510 Mar  7 03:29 .git
-rw-r--r--+  1 david  staff    76 Mar  7 03:15 .gitignore
drwxr-xr-x+  4 david  staff   136 Mar  7 03:11 Foo
drwxr-xr-x+  5 david  staff   170 Mar  7 03:09 Foo.xcodeproj
-rw-r--r--+  1 david  staff    28 Mar  7 03:08 README.md

Step six: This should be the last thing you need to do in the shell. Add the files to the repository, commit, and push. The push step will require your GitHub credentials.

Triton:Foo david$ git add .gitignore
Triton:Foo david$ git add ./*
Triton:Foo david$ git commit -m 'Add .gitignore and project files'
Triton:Foo david$ git push
warning: push.default is unset; its implicit value has changed in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the traditional behavior, use:

  git config --global push.default matching

To squelch this message and adopt the new behavior now, use:

  git config --global push.default simple

When push.default is set to 'matching', git will push local branches
to the remote branches that already exist with the same name.

Since Git 2.0, Git defaults to the more conservative 'simple'
behavior, which only pushes the current branch to the corresponding
remote branch that 'git pull' uses to update the current branch.

See 'git help config' and search for 'push.default' for further information.
(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
'current' instead of 'simple' if you sometimes use older versions of Git)

Username for 'https://github.com': DavidSteuber
Password for 'https://DavidSteuber@github.com': 
Counting objects: 13, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (11/11), done.
Writing objects: 100% (13/13), 3.41 KiB | 0 bytes/s, done.
Total 13 (delta 0), reused 0 (delta 0)
To https://github.com/DavidSteuber/Foo.git
   1925a59..332395f  master -> master

At this point, your project should now be in GitHub’s source control and you should be able to add files and commit changes from Xcode’s Source Control menu. Committing and pushing are two separate operations. Xcode lets you check a box called “Push to remote” when you are committing changes and will do the push for you. Until you actually do push your changes, they do not show up on GitHub.

I hope this article proves useful. I would be grateful for any feedback. Yes, I do require registration to leave comments. This is really a spam prevention measure. I do not collect e-mail addresses or anything like that. Just use a password you don’t use anywhere else. I use HTTPS for everything.

Code long and prosper.

Apple's MusicCube example project  on GitHub
Apple’s MusicCube example project on GitHub
Apple's MasicCube Code Example in Xcode
Apple’s MusicCube Code Example in Xcode

Epilogue. Ray Wenderlich has a different and more detailed method of setting up Xcode with GitHub: How To Use Git Source Control with Xcode in iOS 6.

C vs Swift 1.2 and Getting Killed

When I started learning Swift, I revisited the Mandelbrot Set. It’s an old favorite of mine because it is so simple to compute some rather nice images.

Mandelbrot Set
Mandelbrot Set

The above image was computed using Swift with the vDSP library in the Accelerate Framework and Grand Central Dispatch. Keeping track of interior values allowed me to color the interior as well as the exterior.

Back in June of 2013, I wrote a very simple C program to compute the Mandelbrot Set and display it in a different way. It produced the following image.

Orbitals in C
Orbitals in C

The C code was very simple and single threaded. This is a run from the shell using the time utility.

Triton:Desktop david$ time ./Orbitals
Computing row 2880 of 2880
Done! Return code = 0

real	0m37.342s
user	0m37.202s
sys	0m0.090s

Each pixel in the set is iterated 4000 times. The complex values are mapped onto the complex plane with the upper left corner being (-2.0, 2.0) and the lower right corner being (2.0, -2.0). The image was originally generated in TARGA format using some code I scraped off the Internet. I converted it to PNG using Preview so that browsers can view it. For some reason, the code flips the image horizontally. I haven’t taken the trouble to debug it.

I also wanted to try a comparison of Swift to C for this computation. I should have gone for a pure transliteration so that I could get a valid speed comparison. But I didn’t. The Swift version does a few things the C version does not do. One is dynamic memory allocation for the computed values. Another is an abstraction of complex number arithmetic. The last is adding Grand Central Dispatch in an attempt to get more speed.

The dynamic memory allocation turned out to be a major performance killer.

Swift Memory Usage
Swift Memory Usage

The run time:

Triton:Desktop david$ time ./SwiftOrbitals
Done!

real	6m56.994s
user	5m17.282s
sys	4m56.695s

This computation produced the same image with the correct orientation. I used a Bitmap class I created to use QuartzCore instead of the TARGA code from the C version. Eventually I produced this image.

Orbitals in Swift
Orbitals in Swift

By the way, I recommend you download one of the two images to examine the detail. What you are seeing is the cumulative result of each point in the set as it is iterated. The values are mapped back to a bitmap for viewing.

I added the orbitals functionality to the same program that computed the above traditional view of the Mandelbrot Set. It uses vDSP and Grand Central Dispatch. Unfortunately, Something rather bad happens.

Triton:Desktop david$ time ./OrbitalsSwift
Killed: 9

real	6m16.576s
user	29m27.176s
sys	7m16.144s

No image is produced. The code does work for smaller images with fewer iterations. Running in the debugger is extremely time intensive. So I don’t know why it is getting killed. The debugger run looks like this.

Xcode 6.3β2 Running Orbitals Computation
Xcode 6.3β2 Running Orbitals Computation

The major take away on this is that Swift is not C or C++. For high performance computing, code has to be structured differently. Algorithmic analysis and profiling are critical, particularly when memory usage can become excessive. The C implementation has the advantage of running in constant space in spite of being a single threaded process. Using Grand Central Dispatch for threading is very easy. But it is no substitute for a bad algorithm.

You may download and play with the code used for these images from here. The code isn’t cleaned up and is certainly not production ready. There is also a dearth of comments. Sorry about that. I also assume the reader of the code is familiar with calculating the Mandelbrot Set.

Enjoy.