Using Subversion with Xcode 3
on Mac OS X Leopard
Developers of even the easiest-to-use applications know that manually managing a project's set of source files is no simple task. Most serious developers depend instead on a source control management (SCM) system to handle the intricacies of source file versioning, collaboration, and storage. Xcode 3.1 makes SCM simple by including a well-integrated, common interface to three widely used source control systems, one of which is the popular Subversion SCM.
Subversion is a free, open source solution suitable for environments of from one developer to thousands. Best of all, Mac OS X 10.5 Leopard includes everything needed for a developer to easily create a complete Subversion server to use with any Xcode project. Not only is every Mac well-equipped to provide Subversion server capabilities right out of the box, but the free Xcode IDE is designed specifically to work with Subversion.
Subversion can run either as a standalone server process or from the Apache web server using the Subversion module. This article will demonstrate both methods, using Mac OS X Server 10.5 for the latter, and then show how to get started managing your source files with Subversion from within Xcode 3.1.
This is an update to the previous Getting Control with Subversion and Xcode article, which outlines a procedure for installing an Apache server that while appropriate for Tiger, requires software downloads and extensive use of the command line. Leopard Server eliminates the need for these steps, allowing you to get an Apache Subversion server up and running within minutes, using GUI tools almost entirely
Using SCM
Source control management systems, also known as version control or revision control systems, track and preserve the entire change history of a project's files. Using such a system, developers can easily revert files to previous versions, maintain multiple branches of a project, and work simultaneously on the same project with other developers. Typically, these systems require developers to check out files from a central repository before working with them and to commit their changes back when done. The system accurately merges any changes that multiple developers might have made to the same file, prompts developers to manually resolve any conflicts, and stores the file changes efficiently to disk.
Xcode 3.1's built-in SCM interface lets you perform these SCM procedures without leaving the program. Using the Subversion client from within Xcode, you can check out and commit your files, compare and revert changes, and move files in and out of source control. For complete details on using Xcode's SCM support see the Xcode Source Management Guide.
Subversion Server Types
Before setting up a Subversion server, you'll need to decide whether to run it using the svnserve server binary or from Apache using the mod_dav_svn module. Both servers work with clients and repositories in the same way and are indistinguishable from that perspective. The servers do differ, however, in their scalability, performance and ease of installation. While either server can be made to work for most situations, the following general recommendations will help you decide which is best for your environment.
svnserve
The svnserve server is the best choice for smaller environments, where mulit-user management, logging and access from outside the firewall are not large concerns. svnserve comes pre-installed on Leopard, and getting it up and running requires almost no additional steps nor Mac OS X Server. Also, svnserve provides better network performance of the two server types.
Run in its default configuration, however, svnserve lacks any real security; it transfers its data unencrypted across the network and stores user passwords in plaintext on the server. To mitigate these issues, you can easily run svnserve over ssh, and this article will detail that procedure. Still, ssh requires users to have shell accounts on the server, so if that is a concern, svnserve over ssh is not a good solution.
Apache (mod_dav_svn)
Running subversion from Apache, on the other hand, is the better choice for larger environments, where mulit-user management, logging, and access from outside the firewall are important factors.
As you'll see, Leopard Server gives you all the software and administration tools needed to run a large-scale Apache Subversion server. Providing access is as simple as using the Workgroup Manager application to add an account, and the Server Admin application lets you finely control access to the repository, view the access logs, and manage your SSL certificates.
The mod_dav_svn module is actually an extension to the WebDav module (mod_dav), so using it provides all the benefits of managing users and permissions with the Server Admin application's easy-to-use WebDav tools. Apache's own logging allows you to track and troubleshoot the Subversion transactions. And to ensure adequate security, you can configure Apache to run over SSL, a step which this article details as well. Also, as an added benefit, Apache provides a web interface to your source files with no additional configuration.
These capabilities, however, come at a cost of network performance and ease of installation. svnserve provides a stateful connection for its clients, therefore once a connection is established, Subversion commands get handled consecutively until you disconnect. Web connections, on the other hand, require more frequent connects and disconnects, and this overhead results in generally slower transactions.
Configuring the Apache server requires several more steps then configuring the svnserve server. While neither configuration requires any additional downloads or extensive use of the command line, setting up Apache the first time could take up to 30 minutes, while getting the svnserve server going shouldn't take more than five.
You can find a thorough comparison of the two server types on this svnbook page, which is part of the complete online Subversion documentation, Version Control with Subversion.
Creating a Subversion Repository
Regardless of which server you choose to use, the first step of setting up a repository is the same.
The repository stores the files that you want to keep under version control and also holds the change data needed to produce a copy of a file from any point in its lifetime. When you check out your project from the repository, the server makes a working copy of the project on your computer where you can work with it as you do with any project. Whenever it's time to commit your changes, the server calculates those changes and writes them back to the repository. Since only the changed information is copied, the repository can store many versions of a file using much less disk space than if it had to keep complete file copies.
You will need to create your repository and project directories using command-line tools, but once that's done, you can interact with the repository using only Xcode. To begin, open Terminal on the server (or use ssh to connect to it) and enter this command to create Subversion and Repository subdirectories in /Library (though you can put them anywhere the web server has access):
mkdir -p /Library/Subversion/Repository
Next, use the Subversion administration tool to create the project directory itself (named Project1, in this case), and populate it with the subdirectories and files it needs to work in a repository:
svnadmin create /Library/Subversion/Repository/Project1
Before you can import the project files using Xcode, you'll need to import an empty directory skeleton into the project directory using the command line. These directories compose Subversion's standard project layout: a top-level directory named for the project and its three subdirectories named trunk, branches, and tags. Create these temporary directories in /tmp with this command:
mkdir -p /tmp/Project1/trunk /tmp/Project1/branches /tmp/Project1/tags
Import the directories into the repository with this command:
svn import /tmp/Project1/ file:///Library/Subversion/Repository/Project1 -m "Initial import"
You can then delete the temporary directories:
rm -rf /tmp/Project1
Finally, restrict permissions on the repository directories to ensure that only the web server (if you'll be using the Apache server) and members of the admin group have access:
sudo chown -R www:admin /Library/Subversion/Repository sudo chmod -R ug+rwX,o= /Library/Subversion/Repository
If you'll only be using the svnserve server, you can make the repository root-owned with these commands instead:
sudo chown -R root:admin /Library/Subversion/Repository sudo chmod -R ug+rwX,o= /Library/Subversion/Repository
Running the svnserve Server
If you've chosen to use the svnserve server over ssh, there isn't even a step two. The svnserve binary comes pre-installed on Leopard, and the ssh server (sshd) launches svnserve on demand, so svnserve doesn't need to run as a daemon. Therefore, as long as the repository is in place, and sshd is running on the server, svnserve will already accept connections. Skip ahead to the section, Using Subversion from Xcode to get started with your first project.
Note: To start sshd on the server, open System Preferences, select the Sharing icon and select the Remote Login checkbox.
Otherwise, go on to the next section, Configuring the Apache Server.
Configuring the Apache Server
Configuring an Apache Subversion server on Mac OS X Server requires quite a few more steps, but all are fairly simple. Begin by opening Server Admin and connecting to your server. If the Web service is not yet in the list of services, select Add Service from the Server menu, click to check the Web service checkbox, and click Save (Figure 1). You don't need to start or restart the Web service until you've completely configured the Subversion server.

Figure 1: Turning On the Web Service
The next step is enabling the Subversion Apache module. This module, mod_dav_svn, relies on the web_dav module, which gives Apache filesharing-like capabilities. Together, these modules provide Subversion clients with read and write access to Subversion repositories using only the HTTP protocol, thereby simplifying server and network administration.
To enable the module, select Web from the services list at left, click Settings from the toolbar, and then select the Modules tab. Find the dav_svn_module in the list, click its checkbox on, and then click save (Figure 2). You don't need to enable the authz_svn_module, as you'll instead be using directory services for authentication. Also WebDAV is turned on elsewhere, so you don't need to enable its module here either.

Figure 2: Enabling the SVN Module
With the Subversion module enabled, Leopard Server and Apache work with the repository much like any other WebDAV site they're serving, so configuration is largely identical. To start, create a new secure website by first clicking Sites in the toolbar, and then clicking the Add (+) button. This creates a new Apache virtual host, which defines a unique hostname or port (or both) and document root for each site. Once it's created, enable the site using the checkbox in the new site's listing.
If you're hosting only the Subversion site, the following steps will work fine. If you're already hosting other sites on your server, you might need to consult the Web Technologies Admin guide to learn how to make the new site work alongside your existing site(s). Generally, as long as the new site has a unique hostname or port that site should operate properly.
As shown in Figure 3, configure the new site by selecting the General tab and making these settings:
Domain Name: If you have a fully qualified domain name, you can enter that here. Otherwise, it's fine to keep this blank.
Description: Enter any descriptive text you would like here, or keep it blank.
IP Address: Set this to "any"
Port: Set this to 443, the default port for secure web traffic (SSL), which you will be enabling in an upcoming step.

Figure 3: Configuring the Site
Leave the remaining settings at their defaults, and select the Options tab. Enable WebDAV here, turning on the module that the SVN module depends on (Figure 4).

Figure 4: Enabling WebDAV
Select the Security tab and enable SSL, using the default certificate or your own if you have one (Figure 5). You'll want to use SSL for an important reason: Subversion requires authentication for access to the repository, and since Xcode uses the HTTP basic authentication method, your password would otherwise be sent across the network in an easily decoded format. With SSL enabled, the entire HTTP session is encrypted, keeping your password and all other transmitted data inaccessible to any network eavesdroppers.

Figure 5: Enabling SSL
Next, click the Realms tab to define a WebDAV realm for the repository. WebDAV uses this realm definition to determine what directories to share and with what permissions. Click the Add (+) button below the Realms list to create a new realm, and configure it with these settings, as shown in figure 6:
Realm Name: Give it a relevant name, "subversion", for example.
Authentication: Choose Basic.
Folder/Location Pop-up menu: Select Location and enter /svn/ in the field. Doing this directs an /svn/ URI (that part of the URL following the hostname) to the SVN module instead of a directory. In an upcoming step, you will configure that location with the actual repository path.
Click OK to save the definition.

Figure 6: Configuring the Realm
Click the Add (+) button under the Users & Groups list to open the Users and Groups panel. For each account and group that you want to provide with repository access, drag its name from the panel to the Users & Group list and set its permissions in the list to Browse and Read/Write WebDAV. (If you need to add new accounts or configure groups, use the Workgroup Manager application to do so.) Ensure that the permissions for the Everyone group stay at None (Figure 7).

Figure 7: Adding Users to the Realm
Finally, click Save to save the new site. Before you start (or restart) the Web service, there is one more command-line step that remains to be completed.
Leave Server Admin as it is and return to Terminal. Use a text editor to open the /etc/apache2/sites/0001_any_443_.conf file with root privileges:
sudo vi /etc/apache2/sites/0001_any_443_.conf
Note: If you did configure your site with a domain name, that name will appear in the filename just before .conf, as in 0001_any_443_tosxserver.west.lan.com.conf, for example.
Find the /svn/ location block near the end of the file and add these two lines just below the <Location "/svn/"> line, as shown in Figure 8:
DAV svn SVNParentPath /Library/Subversion/Repository
The first line, then, directs that the Subversion module receives the /svn/ URIs (by way of the WebDAV module), and the second passes the repository path to the module.
Note: Some configuration changes you subsequently make to this site with Server Admin can cause the first line to revert to DAV no. If you do experience problems accessing the repository, check for this reversion, and if needed, correct the file and restart the web service.

Figure 8: Editing the Site's Apache Configuration File
With the edits complete and the file saved, return to Server Admin, select Web in the services list, and click Start Web. (If the web service was already running, click Restart in the prompt, or select Web in the services list and from the Server menu select Restart Service.)
The Subversion server configuration is now complete and ready to test in a web browser with this URL:
https://your.hostname/svn/Project1
Once authenticated to the repository, you should be able to browse the three empty directories you created there, as shown in Figure 9.

Figure 9: Browsing the Repository
You're now ready to use Xcode to import a project directory.
Using Subversion from Xcode
The procedure for connecting from Xcode to either type of Subversion server is mostly the same; you'll see the slight differences included in the following steps. To begin, open Xcode and create a new project as usual, saving it to the desktop as Project1. In this example, the project is for a Cocoa application.
Typically, you wouldn't need to keep your build directory under version control, so confirm that this project has a separate location for it. From the Project menu, select Edit Project Settings, and set the build directory to a location outside of your project directory, as shown in Figure 10.

Figure 10: Relocating the Builds Directory
Next, create the Xcode repository settings for the project. From the SCM menu, select Configure SCM Repositories, and the SCM pane of the Xcode preferences panel will appear. Click the Add Repository (+) button and in the sheet that appears, name the Repository Project1, set the SCM System pop-up menu to Subversion, and click OK.
If you are connecting to an svnserve server, complete the repository settings as shown in Figure 11, using a URL in the form of:
svn+ssh://accountname@hostname/Library/Subversion/Repository/Project1
If you are instead connecting to an Apache server, complete the repository settings as shown in Figure 12, using a URL in the form of:
https://accountname@hostname/svn/Project1
Note: The URL for an svnserve server connection requires the absolute path to the project directory in the repository, while the Apache connection requires only the URI to that directory.
In either case, except for the password, the remaining fields should properly auto-fill with data from the URL. Enter the password and click Apply. When the status indicator shows "Authenticated", click OK to close the Preferences window.

Figure 11: Connecting to the Repository Using svnserve

Figure 12: Connecting to the Repository Using Apache
You're now ready to import the project directory into the repository following these steps, as illustrated in Figure 13:
- From the SCM menu, select Repositories.
- Using the Repository browser that appears, select the trunk directory of the new Project1 repository.
- From the browser's toolbar, click the Import icon.
- Navigate to the Desktop and select the Project1 directory.
- Add a comment to log with the import and click Import.
- From the sheet that appears confirming the import, click OK.

Figure 13: Importing a Project to the Repository
If you're connecting to an Apache server, you can confirm the import with a web browser by re-loading the repository URL and browsing to the project directory, as shown in Figure 14.

Figure 14: Browsing the Imported Project
Once the project directory is in the repository, you will no longer need the copy that's on the desktop. Instead, you will check out the project from the repository, a process that puts the actual working copy of that directory on your computer. Before you check out the project, then, quit Xcode and delete the Project1 directory from you desktop.
When you're ready to check out the project directory, re-launch Xcode and follow these steps, as shown in Figure 15:
- Return to the Repository browser using the SCM > Repositories Menu command.
- Using the browser, navigate to the Project1 > trunk > Project1 directory and select it.
- From the browser's toolbar, click the Checkout icon.
- Navigate to your normal location for keeping project directories and click Checkout.
- Once the checkout is complete, click to open the Xcode project file when prompted.

Figure 15: Checking Out the Project
At this point, nothing in the project itself yet indicates that it's under version control, so the final step is turning on SCM for the project:
- From the Project menu, select Edit Project Settings.
- On the Project Info palette that appears, find the SCM settings pop-up menu.
- Select the Project1 (Subversion) repository from the menu, as shown in Figure 16, and close the palette.

Figure 16: Configuring SCM for the Project
Testing SCM
You should now be able to make changes to your project, see what files have changes, and then commit those changes back to the repository. Practice by making a change to one of your project files and saving it. To see what files have changes, enable the SCM column in either of the project window's list areas by right clicking in a header area and selecting SCM from the menu. The SCM columns will show an M for the file that was modified, as shown in Figure 17 (If the status doesn't show, from the SCM menu, select Refresh Entire Project.)

Figure 17: Enabling the SCM Columns
You can also compare the changes side-by-side by right-clicking the changed file's name and selecting Compare from the menu (see Figure 18). A window will appear with the changed lines highlighted, as shown in Figure 19.

Figure 18: Opening the Compare Window

Figure 19: Comparing the Changed Version
Once you've made your changes, commit them back to the repository by right-clicking the filename and selecting Commit Changes. Add a comment for the log and click Commit (Figure 20). Or you can commit several files at once using the SCM > Commit Entire Project command.

Figure 20: Committing the Changes
When you're finished using Xcode, close the project normally; when you're ready to work with it again, open it normally as well. The project continues to stay checked out, and you can continue committing your changes.
This is only the beginning of what you can do with Xcode's SCM system, now that you have a working Subversion server. To go further, refer to the Source Management Overview.
Updated: 2009-02-17