subversion_logo_hor-468x64

This series of articles documents my setting up and using a subversion repository on my development machine.

Subversion Part 1: Downloading and Set Up

For a long time I have wanted to implement a version control system. The attraction is being able to gain control over my code without simply making duplicates of the project folders. In particular I want to be able to fork and merge different code bases and roll back to working versions. As soon as I involve anyone else in the development process (even testers), it is no longer just me and all this becomes a necessity.

So I am going to install subversion and move my active projects over to it. I have been reading up on subversion for a while on and off, and think that I understand it well enough to implement it and blog it. For the record I'm using XCode 2.4.1, subversion 1.4.3, Mac OS X 10.4.8. Since the interaction among these changes, bugs get fixed, and features get added, not all of this article will stand the test of time.

I'm going to concern myself with just a local repository. I don't need remote access yet, so that will do. This decision means that I don't have to deal with Apache, WebDAV, and a host of other issues that make the set up complex.

A significant cause of confusion is the number of folder hierarchies that have to be understood and managed in the setting up and running of subversion. So to make what I am doing crystal clear, I have some diagrams to illustrate and am using color to differentiate the parts.

I have to work with three different folder hierarchies, so I better get organized.

The first hierarchy is my current project, Random Wok. Its project folder is called Random Wok and its path is Documents/Progging/Cocoa/Aperture/. Inside Random Wok is the XCode project file, the Build folder, and all the source files and resources. Once I have put the project into my repository I will mothball the Random Wok folder. Currently I create new versions by duplicating the Random Wok folder and numbering them. These files and folders are yellow:

svn1

The second hierarchy is a new one. To use subversion I will put my code into a folder called trunk that lives inside a virtual folder hierarchy inside subversion repository. That repository (implemented inside a folder) will itself be one of a number, all organized into a real folder hierarchy on my hard drive. As per the subversion documentation, I will also have a branches folder and a releases folder at the same level as the trunk folder. So my first step is to create a folder Documents/Progging/Repositories on my hard drive. That is the real folder that will hold all my repositories. The first one will be called Random Wok Repository and will hold one project. These files and folders will be red.

The third hierarchy I have to concern myself with is that of the checked-out code. I will be checking my code out of the repository to this new location, building and debugging it, and finally checking it back in again when I am happy with the result. If I want I can then delete the code, because it's all in the repository. I create a folder called Working in Documents/Progging and another called Builds. Working is where I will check the source out to and will be green. Builds is where I will have all the Build folders live. I want to be able to keep the builds separate from the code. Inside Builds I create a folder called Random Wok. Inside that is where the builds and temporary files will be kept. The Build files and folders will be blue.

Now I need a copy of subversion. Subversion is actually a collection of utilities, svn and svnadmin being the two I will use the most. I download a prebuilt binary from Coding Monkeys and run the installer. That puts the binaries into /usr/local/bin:

svn2

To make using these simpler I set the PATH variable in the current tcsh shell invocation to /usr/local/bin with setenv by typing setenv PATH /usr/local/bin.

Next I need to run svnadmin to create my first repository:

svn3

And there it is:

svn4

Now I run svn once so it will create a folder called .subversion in my home directory:

svn5

Much more information follows that. In the .subversion folder is a config file. I edit this using TextWrangler with File > Open Hidden... and selecting Enable: All Files. In the [miscellany] section I modify the list of global-ignores so that it looks like this (it's actually all on one line):

svn6

The modifications make subversion ignore some extra XCode files that I don't care about. I don't include the *.pbxuser files as some people do. That is because those per-user values include the custom executable settings that I need to launch Aperture. Here is the hierarchy so far:

svn2

Next I need to set up the repository and import a project.

Subversion Part 2: Setting Up A Repository And Importing A Project

subversion_logo

The repository called Random Wok Repository I set up in Documents/Progging/Repositories needs some internal structure. That's because I am going to have it contain virtual folders called trunk, releases, and branches (I prefer releases over tags).

In the original Random Wok project folder I create the new structure: trunk, branches, releases. And then copy the current contents into trunk and delete the Build folder.

svn9
Now I am ready to do the import. I need to do this from the command line. First I change my working directory to the changing to the original project folder (yellow in my diagrams) and then import using svn import. I have to give a check-in message with -m or else svn complains with an error (no editor set up). The dot in the svn import line below references the current directory. The repository is defined with a URL that starts with file:///:

svn8

Now the structure looks like this:

svn3

Everything below Random Wok/ in red is in the repository and so the folders shown are virtual folders. They can be referenced with URLs passed to svn that start with file:/// by including the path to the repository and then the path inside the repository.

Now revision 1 is in the repository I can use a utility called svnX to inspect it. I no longer need the Terminal window open. svnX will not recognise an empty repository, so up until now I could not use it. I download snvX from Apple and install it. Svnx is a GUI front end to svn.

The prefs are already set up for me:

svn7
In the Repositories panel I add a new repository pressing +, giving the repository a name, and dragging the Random Wok Repository folder onto the Path field. Now svnX knows where the repository is:

svn10
I double-click on the repository to open it in svnX and look at the contents:

svn11

The lower part is a folder browser that shows the structure of the revision select in the pane above. I can see the import message and a list of revisions with just one revision in it. The svn mkdir button is used to make more virtual folders in the repository and svn copy and svn move button copy and move virtual folder trees in the repository.

I no longer need the original project file, so I can archive it to a ZIP file to get it out of the way:

svn4

In its current state I cannot use my project. It is inside the repository and inaccessible to XCode and other tools. So the next step is to check out a copy.

The other parts of this series can be found via the Cocoa page.

Subversion Part 3: Checking Out And Using A Project

To use my Random Wok project I have to check it out. While the files are in the database they are inaccessible to normal file operations. I will do the check out in svnX.

I'm going to check out all the files in the trunk virtual folder to a new folder called Random Wok in my Documents/Progging/Working folder. First I create that new folder. Then in svnX I select the trunk virtual folder in the browser at the bottom click on the svn checkout button and select Working/Random Wok as the folder to check out to. svnX creates the folder for me and fills it with the files:

svn5

svnX has a browser built in for looking at working copies. Opening that shows me the working version I just checked out and lets me give it a more descriptive name:

svn12
Double-clikcing on the line shows me a browser that I can use to see the file status:

svn13

Now I can get back into XCode. I double click to open the XCode project that was checked out and set it up to use subversion. From the SCM menu I select Configure SCM... and set it up like this:

svn14
I change the build location and the location for intermediate files, and enable and select the SCM. I also found it necessary to clicked on Rebuild Code Sense Index for XCode to have the data it needs about my source files. To fully set up the build destination I select the target and change the Build Products Path for all configurations to be that Random Wok Folder:

svn1
Now the SCM tab for my project looks like this, showing the initial check-in:

svn15
Now I can enable the SCM status display by selecting the Random Wok project icon at the top of the XCode project list and control-clicking on the column header:

svn16

Now if I edit a file and save it I get a status change, M, showing modified:

svn17

Also shows up in the SCM smart folder on left:

svn18

Another thing I need to do is to tell snv that the pbxuser files are binary. This will prevent svn trying to merge them. To do that I go back into the terminal:

svn11

How does svn know where the repository is? There is a hidden folder called .svn in the checked out folder. In fact there are hidden .svn folders in all the folders.

Lastly I commit my updated version to the repository. I select all the files to update and from the menu use CMS > Commit Changes, and fill in the commit message:

svn12
With the files checked out I can compile and use my project just as I did before I used subversion. Each time I get to a good stopping point, I check in the files.

Eventually I will have a version that I want to release. And that means using svnX again.

Subversion Part 4: Creating A Release

Now I have my repository set up, my code imported, and a working copy checked out that I am doing development on, I am going to release a snapshot of the current code as a beta, since I want some people to test it. In order to be able to keep working on the main code (in trunk) while I wait for feedback from testers I have to fork my code. If the testers find a problem and I fix it, I want to send out just the fix, not the current development version with the fix. Later I can merge the fix back into my main code.

Using subversion I do this by copying my code base in the trunk releases virtual folder into a new folder. After making sure that my project is checked in, I open svnX and make sure the correct revision is selected in the top pane. By selecting trunk:

svn13
and clicking on the svn copy button, I am given an opportunity to name and locate my new virtual folder:

svn14
I select branches as the location and fill in a name for the target of the copy. I add a message and hit commit:

svn15
And there is the new release in the wrong place. I meant to put it in releases. No matter. I just use the svn move button to move the beta1.0 folder to the right place:

svn16

Done. Now to work on the beta I check it out, or I can continue working on the trunk. If I check it out I have to create a set up a new build folder for it of course. Here is the current folder tree:

svn6

The Bagelturf site welcomes Donations of any size