Last weekend, I sat down and decided to install one of my crappy computer as a Source Control and Continues Integration machine. What I need is Subversion source control and other bits and pieces to have a fully functional Source Control System.

I put down my requirements first so that I can measure the quality of my work later.

My requirements are:

  1. A source control system is necessary to keep track of different projects.
  2. Source Control should be browse able with a browser.
  3. Source code should be colored in browser for easy reading.
  4. Source Control should be used for different technologies like .NET, Java, PHP, Pearl etc.
  5. The System should compile the code automatically when there is a change in Source Control.
  6. The System should deploy the executables to proper servers for further tests.
  7. The System should run the Nunit tests and reflect the results.
  8. An Issue tracking system should be exist.
  9. Issue Tracking system should have a connection to Source Control. So that each defect can be tracked down in code.
  10. Development machines should be able to check-in and out the code
  11. Developers should be warned if tests are not successful.
  12. Developers should be informed when the defects are assigned to them.

After I put down my requirements, I have started to work. First off all, I have installed a clean Windows XP Professional on a Celeron 500, 128mb ram, 40gb HD machine. I have installed IIS, Service Pack 1, and all other updates available on Windows Update site. .NET Framework 1.1 is also available from the Windows Update.

I knew, I was going to use Subversion as the bases of this continues integration machine. It is free, open source and easy to install and use. I have downloaded latest version from and installed without a problem. Don't forget to add the subversion\bin directory to your PATH variable.

Now, I need to create my repository database. Create a directory called "Repository" in your C: drive and enter the following command on DOS Shell:

C:\>svnadmin create C:\Repository

And also to secure the repository with a user id and password, I have changed configuration and added my name and a password to passwd file. I don't know if there is a way to hash the passwords in this file, it looks like so vulnerable. Go to C:\Repository\conf and open svnserve.conf file with your text editor. Uncomment the lines below.


anon-access = none

auth-access = write

password-db = passwd

Create a new file in the same folder called passwd and enter the lines below. This is a user name  and password pair.

gurkan = asdfgh

I also need the Subversion service running all the time so that I don't have to login to the machine and start the service manually. To install the subversion server as a service I have downloaded SvnService and copied SVNService.exe into Subversion\bin directory. To install the service go to DOS shell and enter:

C:\>SVNService -install -d -r C:\Repository

And to start the service:

C:\>net start SVNService

My first requirement is alright now. I have a fully functional Source Control System. My second requirement was to be able to browse the Source Control over the intranet with a browser. So developers don't need to install another application to browse the Source Control. There are couple of choices for Subversion, I have downloaded WebSvn. WebSVN is a PHP application so I also need the PHP installed and configured to work with IIS. Download the 7.8meg zip package. You may need other things later if you want to run MySql like applications. Extract the package to hard disk and add the directory where the php5isapi.dll resides to your PATH variable. You also need to register this dll in Internet Information Services as an ISAPI filter. Right click on your Default Web Site go to properties and ISAPI Filters tab. Add php5isapi.dll by clicking the Add button. Give the name php for the Filter Name.

I have extracted and copied WebSVN to the inetpub\wwwroot directory and created an application on IIS on WebSVN directory. Change the name of the file to in WebSvn\include directory. I need to adjust couple of things in file. These are:

// For syntax colouring, if option enabled...

//My Enscript installation is in C:\Enscript1639

//Also C:\Enscript1639\bin is in PATH
// To configure the repositories by hand, copy the line below, uncomment it and replace the name and path
$config->addRepository("Repository", "C:\\Repository");



// --- BUGTRAQ ---
// Uncomment this line if you wish to use bugtraq: properties to show links to your BugTracker
// from the log messages.

When I was reading the file, I have seen an entry for colouring the code. I thought, maybe this thing will make it easier for my third requirement. It was requiring an Open Source application called EnScript 1.6.3 (don't forget to download dependencies). After a bit of reading about it I have realised that EnScript is a scripting engine based on state definitions to produce colored html outputs. For each file extension you need to have a state file in a certain directory to make it colored. As usual there was no support for C# and VB.NET. I have found a state file on Sourceforge for C# but no luck for VB.NET. You can download this file from this link. Also need to register the .cs extension in WebSVN's file.

// Uncomment this line if you want to use Enscript to colourise your file listings
// You'll need Enscript version 1.6 or higher AND Sed installed to use this feature.
// Set the path above.

//Register cs extension here

$extEnscript[".cs"] = "csharp";

There are also options for diff, gzip and sed (I don't know what sed is). But you need to install CygWin to get these. CygWin is a project to provide Unix shell tools on Windows 32bit systems. I have fired up CygWin installation and selected all the packages (that was a mistake). Installation took nearly a day because of the selected modules and all downloaded first before installation.

You need to provide paths for each application (diff, gzip and sed) in WebSvn's file. It is good because developers can download executables as a zip file or look for differences between two versions of a file through the browser. This is great, because I have even more functionality than my initial requirements and they are certainly very useful to have. Here are the lines in that you need to uncomment. Also download TAR  from here to be able to download an entire folder from WebSVN.

// $config->setSVNCommandPath("Path/to/svn and svnlook/ e.g. c:\\program files\\subversion\\bin");

// For delivered tarballs, if option enabled...
$config->setTarPath("C:\\Program Files\\GnuWin32\\bin");
// For delivered GZIP'd files and tarballs, if option enabled...




// --- TARBALLS ---
// You need tar and gzip installed on your system. Set the paths above if necessary
// Uncomment the line below to offer a tarball download option across all your
// repositories.


Another thing to do is to define the port 3690 for Subversion on Windows XP's firewall so that you can access from other developer computers. I kept the scope to subnet, so only internal network computers with this subnet can access to Subversion service.

To download binary files as zipped you need to add these:

// --- FILE CONTENT ---
// You may wish certain file types to be GZIP'd and delivered to the user when clicked upon.
// This is useful for binary files and the like that don't display well in a browser window!
// Copy, uncomment and modify this line for each extension to which this rule should apply.
// (Don't forget the . before the extension. You don't need an index between the []'s).
// If you'd rather that the files were delivered uncompressed with the associated MIME type,
// then read below.
$zipped[] = ".dll";
$zipped[] = ".exe";
$zipped[] = ".class";

After everything set up, I've logged in to my developer machine and installed TortoiseSVN 1.2.2 which works with Subversion 1.2.3 and it also claims that there is a fix for VS.NET web projects. I have uploaded a small .Net project to Subversion and browse to http://xpserver/WebSvn (xpserver is the machine that I am setting up for Continues Integration) with Internet Explorer but I have got an error message. Apparently the IUSR_XPSERVER user didn't have execute permission on cmd.exe which is used by WebSVN to run Subversion commands. Actually, giving this permission is a security risk but as long as this machine is in intranet and not accessible from outside, I think it is safe. I set the execute permission and it worked like a charm. Now I can access to Subversion with Internet Explorer and when I click onto a .cs file it is displayed colored like in VS.NET editor. Also when I click onto executables like .dll or .exe, it downloads the file zipped. So my requirements 2, 3 and 9 are realised.

I have also installed BugTracker.NET to coordinate issues and bugs in the projects. One thing that I want is to hook issues to Source Code Control so that every check-in and out process can be traced back to some issues, bugs or enhancements. When you right click on a folder which is a project checked-out from Subversion with TortoiseSVN, you will see an extra tab called Subversion properties. Here you can set bugtraq properties. These properties will provide you an extra field to enter issue number when you are using TortoiseSVN to check-in the project. This issue number will be a link to your issue tracking software and this link is visible from WebSvn. Now, that's what I call integration.

The bugtraq properties that I've used are:

bugtraq:label: this is the label for the Issue/bug number which will appear on TortoiseSVN's check-in dialogue

bugtraq.url: This is the heart of this integration. The URL that you are providing is the address of your bug/issue tracking software with a parameter at the end which will be replaced by issue number. So my setting is http://xpserver/btnet/edit_bug.aspx?id=%BUGID%. The parameter %BUGID% will be replaced with issue number.

bugtraq.message: This will appear in WebSVN with the number linked to your issue tracking software

bugtraq:number: Your issue tracking software may keep the issue sequence with a combination of chars and numbers like IS1, IS2. If you give "true" for this variable, only numbers can be entered when you are check-in the code.

bugtraq:warnifnoissue: If "true" and the developer did not enter an issue number during the check-in, they will kindly be informed to enter.

Now the real continues integration part comes. For this purpose, I am using Cruise Control.NET and NAnt (with NAnt Contribute). When there is a change on registered projects the code should be checked-out and compiled. This will make sure that the test environment will always have the latest executables. After compilation of the code, testers should get an e-mail or some sort of notification about the changes and start testing for that particular change.

CruiseControl.NET comes with an easy to follow installation package. It also installs the service and creates Virtual Directory on IIS. Once you install, everything is ready to use. I have also unzipped NAnt to a folder and added NAnt\bin directory to PATH variable. Unzip NAntContrib and copy bin directory to NAnt\bin. Download this little project and unzip it to test NAnt installation. Open a dos prompt and get into the project folder and enter:


You should get a BUILD SUCCEEDED message on the DOS prompt. If everything is working we can change the ccnet.config to register the projects for continues integration. Go to C:\Program Files\CruiseControl.NET\server directory and edit ccnet.config file. Or you can download my copy here. Please read the file and do the necessary changes before you run the Cruise Control service.

The port 21234 needs to be added to Windows XPs firewall to allow access from intranet for the Cruise Control.NET service. This service will be checked with either CCNet Tray application or FireFox CCNet plugin from the developers computer.

If you browse to your continues integration computer with IE http://xpserver/ccnet you will see something like the below screen shot

For the NAnt integration, pleas check my other blog entry. I think all my 12 requirements are realised. I am happy and humble. What is next?


Comments for this entry:

# re: Poor Man's TFS


by Yury on  4/26/2006 1:36 AM
# re: Poor Man's TFS

Two tools worth checking out are;

AnkhSVN - - Which provides Subversion integration right within VisualStudio. This makes life a bit easier - especially as Tortoise won't commit partial updates of files such as the .proj files when you only want to do a partial commit.

Trac - - Provides source browsing with highlighting, issue tracking, diffing, milestones and a complete wiki.

If you want to view Subversion source over the Intranet there's no need to install WebSvn or Trac - just install Subversion as a module within Apache. Docs are included in the Subversion download.


by Damien Guard on  6/6/2006 4:04 AM
# Question about ankhSVN

Does anyone knows how to use bugtraq using ankhSVN in Visual Studio?
When I commit in Visual Studio, I do not have the possibility to put in the bugID...

by Stijn on  11/17/2006 9:44 PM
# re: Poor Man's TFS

I can not answer this as I have never tried AnkhSvn sorry.

by Gürkan Yeniçeri on  11/18/2006 9:02 AM
# re: Poor Man's TFS

Good article man, thank you!

by Abe on  12/5/2006 11:05 PM
# re: Poor Man's TFS

Thank you for this article, this is great!

by John Rummell on  2/27/2007 4:46 AM
# re: Poor Man's TFS

Excellent post!

by Ryan on  2/27/2007 10:42 AM
# re: Poor Man's TFS

I would second Trac - I find the integration with subversion much better that that described above. You can also set up a post commit hook to allow you to reference bug / feature tickets when you check in (e.g. 'fixed foobar refs #112') - there is also a plugin so you can get a timeline of all checkins / ticket changes / successful builds etc

by Will on  2/28/2007 4:27 AM
# re: Poor Man's TFS

I'm the author of BugTracker.NET. Below is a vbs script that could be a building block for integrating SVN with BugTracker.NET. It grabs entries from SVN when files are committed and posts to the database that BugTracker.NET uses.

- - - - - - - - - - - -

option explicit


' This script is a Subversion "post-commit hook".
' To execute this script first create a file in your repository hooks folder
' called "post-commit.bat".

' Put just one line in the .bat file which will point to this script.
' c:\somewhere\btnet_post_commit.vbs %1 %2

' Put this script where the .bat file is pointing to, and then edit the
' lines below.

' Change this line so that it's the path to your Subversion\bin\svnlook.exe
dim svnlook_path
svnlook_path = """c:\program files\subversion\bin\svnlook"""

' Change the database connection string here.
' This is NOT the same as the one in web.config. Web.config is using ADO.NET.
' This one is using plain old ADO.
dim connection_string
connection_string = "Provider=SQLOLEDB; Data Source=(local); Initial Catalog=btnet; User ID=sa; Password=;"

dim temp_file
temp_file = "C:\temp\btnet_svntemp.txt"


dim repos
dim rev
repos = wscript.arguments(0)
rev = wscript.arguments(1)
' repos = "c:\cit\svnrepos" for testing
' rev = 12 for testing

dim shell
set shell = WScript.Createobject("WScript.Shell")

dim cmd
dim results_object
dim log_string
dim changed_string

' run the svnlook log command
cmd = svnlook_path & " log -r " & rev & " " & repos
set results_object = shell.exec(cmd)
log_string = results_object.stdout.readall

' run the svnlook changed command
cmd = svnlook_path & " changed -r " & rev & " " & repos
set results_object = shell.exec(cmd)
changed_string = results_object.stdout.readall

' for debugging
' wscript.echo log_string
' wscript.echo changed_string

' look for the bugid as the first digits in the checkin comment
dim re
set re = new regexp
re.pattern = "^[0-9]*"

dim matches
set matches = re.execute(log_string)

dim bugid
if matches.count > 0 then
set bugid = matches(0)
' no digits, nothing to do
wscript.quit 0
end if

' at this point, we have a bugid

dim conn
set conn = createobject("adodb.connection")

' loop through the files, the output of the "changed" command
dim lines
lines = split(changed_string, vbcrlf)
if ubound(lines) > 0 then
dim i
for i = 0 to ubound(lines) - 1
dim cols
cols = split(lines(i), " ")
if ubound(cols) = 1 then
dim action
dim file
action = cols(0)
file = cols(1)

dim sql
sql = "insert into bug_file_revisions "
sql = sql & " (bfr_bug, bfr_revision, bfr_action, bfr_file, bfr_date) "
sql = sql & " values ($bug, $rev, N'$act', N'$file', getdate())"
sql = replace(sql,"$bug",bugid)
sql = replace(sql,"$rev",rev)
sql = replace(sql,"$act",action)
sql = replace(sql,"$file",file)


end if
end if

by Corey Trager on  3/11/2007 9:56 AM
# re: Poor Man's TFS

this is great guide, i have a very similar setup, but i'm running into problems with WebSVN, maybe you can help.

in my project setting, i use the subversion sourcecontrol block and the WebUrlBuilder node so i can click through code files from the cruise control build logs on the webdashboard. the weburlbuilder correctly takes me to browse the diff.php webpage in websvn, but i always get the messsage "No Previous Revision", i can never see the diffs between revisions of a file...did you run into this at all?

by Phil on  3/15/2007 12:59 AM
# Source Control on the Cheap and a Comparison of Specialist and Generalists

How to setup a Poor Man’s TFS. This is good for home projects if you are a developer.

by Pingback/TrackBack on  3/17/2007 10:33 PM
# re: Poor Man's TFS

Hi Phil,

I didn't run into the same issue as you. Although the version of WebSvn I used on this article is old. The newest one might be different or have bugs. Did you try the WebSvn forums you may find your answer there.

by Gurkan Yenicerı on  3/23/2007 10:45 PM
# Referred from Wikipedia

Referred from Wikipedia

by Pingback/TrackBack on  2/20/2008 8:40 AM
# Wireless Networking

I\'m supporting this idea all the way! I can not imagine who would disagree with it. On the whole - make posts like this more often.

by Wireless Networking on  7/24/2008 8:00 AM
# re: Poor Man's TFS

Excellent article. It helped me when I was setting up my own Poor Mans TFS. Thanks to all the other guys who added thier comments, some really useful information in there too.

by Gary Woodfine on  8/31/2008 11:41 PM
# re: Poor Man's TFS

I worked on Open source (SVN) as well as TFS 2K5/2K8 tools, both are great.

TFS has all the in-built tools like WorkItem, Bug tracking, Notification etc..,
but to have the same in OpenSource SCC tool, we got to integrate other tools. Also the versions of each OS S/w has to integrate well otherwise time s****.

by vinny on  7/3/2009 8:37 PM
# re: Poor Man's TFS

The term is 'Continuous Integration' not 'continues intgeration'.

by ProofIt! on  10/4/2009 1:30 AM
# re: Poor Man's TFS


thanks for the information and instructions this is the perfect answer to my tfs problems.. keep up the good work

Anyway, thanks for the post

by software development company on  10/12/2009 11:57 PM
# re: Poor Man's TFS

Thanks for the tutorial ... ^^


by El Bruno on  8/21/2010 6:38 AM

Enter your comment here

Comments are moderated



 (not displayed)

 (will be a link on your name)

Bold Italic Underline Blockquote Hyperlink Hyperlink


Please add 3 and 5 and type the answer here:

Comment Preview:



About me

Hi, my name is Gurkan Yeniceri. I am a software engineer with 8 years of experience in both public and private sectors. I have been generally writing about software engineering and Microsoft technologies since March 2005 on this site.
View Gurkan Yeniceri's profile on LinkedIn


If you would like to contact with me you can use the contact page here. I will try to respond it in a timely manner (I will try my best). You can also contact with me via Microsoft Live Messenger with the address gyeniceri {AT} hotmail {DOT} com.
If you are one of my Turkish readers, you may want to visit my Turkish blog here.

If you would like to read my site with an RSS reader like RSS Bandit, you may want to use to subscribe.

RSS 2.0


Bookmark this site digg NewsVine YahooMyWeb Reddit Spurl TailRank BlinkList Furl Shadows blogmarks
    This is a Flickr badge showing public photos from gurkanyeniceri. Make your own badge here.
    There are 133 posts and 88 comments on this site. Other sites also linked it 7 times.