User:RavuAlHemio/Tackling SDK updates with Subversion

From Valve Developer Community
Jump to: navigation, search

(I'll probably keep this under my wing until it's clean enough. Please post inquiries and constructive critique to the talk page to facilitate this. Thanks. :-))

This guide details the specific usage of Subversion, a piece of source control software rather popular not only with members of the open source community, with the Source SDK. The theory and a specific usage guide for Perforce has already been written by Chris Bokitch et al., so if you aren't going to be using Subversion, you might find slightly more generic information there.

If you like your version control integrated into Windows Explorer, take a peek at TortoiseSVN, which provides just that.

Assumptions

Probably the worst part of each guide, we are going to assume that you have already set up a Subversion server at https://svn.example.org/mymod. (No, it's not a real address.) If you don't own/lease a server and/or lack the skills to set up Subversion, there are a few free hosting services for this purpose.

Additionally, we're assuming that you know a bit about source control systems already. If this is not the case, feel free to read the great Version Control with Subversion book available at no cost on the Web. It should get you jump-started pretty fast.

Finally, the current version of the guide expects that you are starting from scratch. (Thousand apologies if you are not.) Later versions will probably fix this deficiency.

Even though prompts in this guide begin with a $ sign, the commands should work on Windows too, if you have set your PATH environment variable correctly.

Populating the repository

First off, we need to get the code into the repository. For this purpose, we create a new directory to host Valve's unblemished SDK code (this will make upgrades much easier):

$ svn mkdir https://svn.example.com/mymod/pristinesdk -m "Created pristine SDK"
Transmitting data..
Committed revision 1.
$ svn checkout https://svn.example.com/mymod/pristinesdk
A  pristinesdk
$

The current folder now contains a near-empty pristinesdk subdirectory. (Subversion has some of its data stored inside already.)

Next, jet through the Create a mod wizard, extracting the source code into the pristinesdk directory. Once this is done, issue the following commands inside:

$ svn add *
A  cl_dll/
A  cl_dll/alphamaterialproxy.cpp
[...]
$ svn commit -m "Added newest Valve SDK code."
Sending        cl_dll/
Sending        cl_dll/alphamaterialproxy.cpp
[...]
Transmitting file data........
Committed revision 2.
$

Valve's code is now inside your repository. (Remember the revision number, in this case 2; you'll need it when upgrading.) You mustn't change the contents of this folder between updates, or the whole upgrade process will become exponentially harder. Instead, create a trunk for your own mod:

$ svn copy https://svn.example.com/mymod/pristinesdk https://svn.example.com/mymod/trunk -m "Branched for mod code."
Committed revision 3.

If you want to keep the clean code on your machine and just create another folder with the code for your mod, run checkout again, this time with the trunk's URL. Since it's enough when one developer keeps around the clean code on their machine to perform upgrades when Valve releases new drops, you can switch to your mod code directly:

$ svn switch https://svn.example.com/mymod/trunk
[...]
Updated to revision 3.

You should now probably rename the pristinesdk to the name of your mod, since it's time to go berserk on the code!

Updating the SDK

pristinesdk and trunk have probably grown far apart from each other... and it's time for a family reunion, assuming your team has agreed on a time when they'd be ready for such an event. (Don't forget: your team is your most valuable asset.) Fortunately, if you haven't done anything to pristinesdk, the process shouldn't be fraught with much error (except for the conflict-solving phase).

Begin by just deleting every single file from pristinesdk (not the .svn directories!) without letting Subversion know. Next, extract the new SDK code into the folder again. Run the following and watch for the output:

$ svn status
M  dlls/items.h
?  materialsystem/stdshaders/unlitgeneric_hdr_dx9.cpp
!  dlls/ancient_hacks.cpp
$

M means that the file has been modified, ? means that Subversion doesn't know about the file and ! means that the file has been deleted without Subversion's knowledge.

You don't need to do anything about the M files. The ?s have to be added, like so:

$ svn add materialsystem/stdshaders/unlitgeneric_hdr_dx9.cpp
A  materialsystem/stdshaders/unlitgeneric_hdr_dx9.cpp
$

You can supply multiple files to svn add. For the ! files, you do the same, but use rm (remove) instead:

$ svn rm dlls/ancient_hacks.cpp
D  dlls/ancient_hacks.cpp
$

You do this until the status letters of all files turn into these:

$ svn status
M  dlls/items.h
A  materialsystem/stdshaders/unlitgeneric_hdr_dx9.cpp
D  dlls/ancient_hacks.cpp
$

If a folder is empty after the SDK update (except for the .svn subdirectory), you can probably remove it too, unless you really like empty directories or you're using the directory in your mod and don't want to do any restructuring.

$ svn rm dlls/deadcode
D  dlls/deadcode
$
If you want to see if any files are still pending, you can use grep on UNIX or findstr on Windows to filter svn status's output. For example, to show only new files pending marking, do this:
$ svn status | grep ^\?
C:\modtrunk> svn status | findstr /b ?

and to find deleted files to mark, do this:

$ svn status | grep ^\!
C:\modtrunk> svn status | findstr /b !

When all changes are included like that, you can "go for it":

$ svn commit -m "Updated Valve's SDK to the 2006-08-04 code drop"
[...]
Committed revision 1024.
$

Now, it's time for what might be the hardest part: the merging itself. Go into the directory where the trunk is checked out, get yourself a caffeinated beverage and then issue:

$ svn merge -r 2:HEAD https://svn.example.com/mymod/pristinesdk
[...]
$

Now, forget the number 2 and memorize the number 1024; you'll need that for the next update.

The merging process obviously must have generated some conflicts.

$ svn status
C  dlls/client.cpp
$

Every line starting with a C has changes made by Valve and your developers that don't match. Directions on resolving these situations can be found in the Subversion Book; suffice it to say that, once you are done fixing the conflicts, you can mark it as fixed:

$ svn resolved dlls/client.cpp
Resolved conflicted state of 'dlls/client.cpp'
$

When your janitor job is done and you have made sure no massive crashers were introduced (while sipping the tenth cup of caffeinated beverage), put on your flame vest (something ought to break) and speak the incantation:

$ svn commit -m "RED LETTER DAY: Valve SDK update merged with mainline. Please forgive and correct oversights and mistakes."
[...]
Committed revision 1025.
$

If you are really paranoid, you can branch the trunk using copy, merge the pristine SDK with that branch, fix all crashers, merge the code back with the trunk and delete the branch used for merging again. Base the decision on your skills with Subversion, the number of coders on your team, how much work the coders have done during your fixing spree, and how much of your mod's code you think the SDK update will break.

Good luck.