Using Subversion for Source Control with the Source SDK

From Valve Developer Community
Jump to navigation Jump to search

This article describes how to use Subversion with the Source SDK. Subversion is a revision control system that is free to use by anyone. The article won't talk about installing Subversion or how to create a repository; for that, you can read Version Control with Subversion, either online or from O'Reilly Media. If you'd rather use Perforce, read this instead.

Starting Up

To begin, create a new repository for your project. This repository will be home for your code, and if you'd like, your mod's various other assets. Once your repository is created, make a new directory and check the fresh repository out, into that directory. You'll notice, if you have show hidden files on, that there is another directory in there now, called .svn. Subversion creates a directory like this in each directory of a working copy (WC) -- the area in which you work on your project.

Right now, other than this directory and the metadata Subversion keeps in working copies, there's nothing at all. That's because a fresh repository doesn't have any content, of course. And before we throw in any mod content, we'll partition our repository into four areas, each with its own directory, according to a simple and logical scheme. In your working copy, create these directories:

branches/
tags/
trunk/
vendor/

I'll explain each of these, although not in alphabetical order. The trunk/ directory is where you do your active development. Your project's files will be kept here normally, and most developers will only have this part of the repository in their working copy. Because Subversion versions entire directories as opposed to just files, the branches/ directory allows you to develop code without it being on the trunk (for example, when you're preparing a release), and tags/ allows you to save a particular state of your project (for example, the code and assets for a particular release). Lastly, vendor/ allows you to track external code and merge it easily into your own, such as what we'll be doing with the Source SDK code provided when you create a mod.

Add these new directories to your working copy, and then commit your changes. You'll find tasks like these to go much faster and easier with TortoiseSVN, a Subversion client and Windows add-on which adds Subversion-related items to the context menu in Explorer.

Creating the Mod

Now is the time to run the Create a Mod wizard. The location where you have the wizard save files isn't that important, as long as it's somewhere you can reach, and is not in your working copy. However, it's probably best that the directory name in which the files are kept is something like sourcesdk. More important is the parent directory. When it has finished its magic, you'll now have the basis for creating your mod. These files, as-is, will be committed into the vendor area of your repository. How we do this depends on whether you're using Subversion at the command line, or if you're using TortoiseSVN.

Using TortoiseSVN

  1. Go to the parent directory of where you had the wizard create its files. For example if you had it create the files in C:\projects\sourcesdk go to C:\projects.
  2. Right-click on the directory you had it create, and choose TortoiseSVN->Import... from the context menu.
  3. Type the following in as the repository URL: <repository location>/vendor/sourcesdk/current
  4. Add a comment such as "current state of Source SDK", and click OK.
  5. Wait a while as the SDK is imported. You might want to grab a coffee or fresh can of Coke...
  6. Go to your earlier working copy, right-click in it, and choose TortoiseSVN->Repo-browser from the context menu. This opens up a new window with a tree view of your repository.
  7. Click on the + next to vendor/, and repeat for sourcesdk/. You should see the current/ directory now.
  8. Right-click on current/ and select Copy To... from the context menu.
  9. The New name textbox is helpfully filled out; just replace current with sourcesdk-<sdk date> (where <sdk date> is the date of the last SDK update, in YYYY-MM-DD format). Then click OK. Replace the default log message with something such as tagging sdk release <sdk date> and accept.
  10. Refresh the repository browser by pressing F5. Then, right-click on the new directory (created by your copying), and again select Copy To... from the context menu.
  11. This time, replace vendor/sourcesdk/sourcesdk-<sdk date> with trunk/<mod name> and use a log message such as creating mod based from sdk code to actually create the mod on the trunk.
  12. Profit!

Using the Command Line

  1. Go to the parent directory of where you had the wizard create its files. For example if you had it create the files in C:\projects\sourcesdk go to C:\projects.
  2. Type in the following (ensuring first that svn.exe is on the path; and continuing with previous example):
    svn import sourcesdk <repository location>/vendor/sourcesdk/current -m 'current state of Source SDK'
  3. Wait a while as the SDK is imported. You might want to grab a coffee or fresh can of Coke...
  4. Type in the following (replacing <sdk date> with the date of the last SDK update in YYYY-MM-DD format for sortability):
    svn copy <repository location>/vendor/sourcesdk/current <repository location>/vendor/sourcesdk/sourcesdk-<sdk date> -m 'tagging sdk release <sdk date>'
  5. And one more to put it in trunk/:
    svn copy <repository location>/vendor/sourcesdk/sourcesdk-<sdk date> <repository location>/trunk/<mod name> -m 'creating mod based from sdk code'
  6. Profit!

Keeping your mod current

Several months after you begin your mod, Valve rolls out an update to the SDK. As a good mod maker, you naturally want to get whatever is in this update, and apply it to your code without breaking much (if anything). Good thing you have the vendor area, because this lets Subversion see what changes have been made, and update your mod's code only where needed. How to take care of this merging process again depends on how you deal with Subversion. But first, run the Create a Mod wizard again. Use the same mod name as before, and preferably the same directory location. But choose Source Code Only this time.

Using TortoiseSVN

  1. Check out vendor/sourcesdk/current/ from your repository. Open the new working copy in Explorer. Delete all of the files in the working copy, but don't remove any of the directories -- and leave the .svn directories alone! (Note: do a regular delete on the files, not svn delete -- just select them, press the Delete key, and move on to the next directory.)
  2. Copy (or move) the files from the directory where you ran the Create a Mod wizard into the working copy.
  3. Open up "Check for modifications" from the Explorer context menu. It'll give you a dialog with a list of changed and missing files. Make sure the "Show unversioned files" option is checked, then go through the list.
  4. For every file listed as missing, right-click on the file name and choose "Delete" from the context menu. It no longer exists in the SDK.
  5. For every file shown as unversioned, right-click on it and choose "Add", as it's a new addition to the SDK.
  6. Once you've gone through all the removed and new files, close the dialog. Then right-click in the root of the working copy again, and this time choose Commit. Add a commit message such as 'updated current source sdk', then click the button that makes it go!
  7. After the commit is complete, right-click again in the working copy and choose "Branch/tag..." from the context menu. Change current in the "To URL" textbox to sourcesdk-<sdk date> (replacing <sdk date> as earlier), and type in a commit message such as 'tagging sdk release <sdk date>'. Hit the OK button. (If you get a warning about not moving to your new "branch", just ignore it -- it's not relevant when simply tagging something.)
  8. Now move over to your trunk working copy. Right-click for that unforgettable Explorer context menu, and this time choose "Merge...". In the dialog that pops up, select "Merge two different trees" and head to the next page of the merge wizard.
  9. You need to tell TortoiseSVN which tags you're comparing for the merge. In the "From" textbox, type in <repository location>/vendor/sourcesdk/sourcesdk-<old sdk date> and in the "To" textbox, <repository location>/vendor/sourcesdk/sourcesdk-<sdk date>
  10. Move to the next and final page of the wizard, and hit the Merge button. TortoiseSVN will merge in the changes between the old and current SDK versions into your project.
  11. Unless it's a particularly big update, you shouldn't have to wait too long. When it's done, commit the changes, unless there are conflicts (in which case, see below).

Using the Command Line

  1. Check out vendor/sourcesdk/current/ from your repository. In this new working copy, delete all the files but don't remove any of the directories -- and leave the .svn directories alone! (Note: do a regular delete on the files, not svn delete.)
  2. Copy (or move) the files from the directory where you ran the Create a Mod wizard into the working copy.
  3. Run svn status to find missing or unrecognized files. Missing files are marked with a ! next to their names; unrecognized files with a ? next to theirs. Don't worry about any other files.
  4. For each file marked as missing, run svn delete <file name> as it no longer exists in the SDK.
  5. For each file marked as unrecognized, run svn add <file name> as it's a new addition to the SDK.
  6. Once this is done, run the following (replacing <sdk date> as earlier):
    svn commit -m 'updated current source sdk'
    svn copy <repository location>/vendor/sourcesdk/current <repository location>/vendor/sourcesdk/sourcesdk-<sdk date> -m 'tagging sdk release <sdk date>'
  7. Change directories into your trunk working copy. Then run (replacing <sdk date> as earlier, and <old sdk date> as the previous sdk update's date):
    svn merge <repository location>/vendor/sourcesdk/sourcesdk-<sdk date> <repository location>/vendor/sourcesdk/sourcesdk-<old sdk date> .
    That . at the end of the line is significant; don't leave it out!
  8. Unless it's a particularly big update, you shouldn't have to wait too long. When it's done, commit the changes, unless there are conflicts (in which case, see below).

Conflicts? In my source code?

Sometimes it happens, when you merge changes together, that two or more changes affect the same area of code. This is generally termed a conflict. When this happens, Subversion won't let you commit any changes until someone has actually looked at the conflicting code, decided how to handle it, and made an appropriate change (usually eliminating one or the other changes that have conflicted). If this happens when merging in an SDK update, Subversion should tell you where the conflicts appear, letting you quickly open up the code and choose what to do.