graham.reeds/

Using Source Control: My Way

January 24th, 2009 :: graham.reeds
Categories: Programming :: Subversion

It’s been a while since I started this. Sorry for the delay.

Source Control is pretty easy to use when used correctly and consistently. If you start to do odd things, then it starts to twist your mind.

First up, you have a repository. This is object you are working with and where your files live happily in harmony.

The repository is divided logically into three sections. These are just names, you can replace them with what you want, but the normal nomenclature is TTB: Trunk, Tags, and Branches. I first came across this when working with Subversion but can be used in VSS, TFS and any other TLAs you can think of. 

The trunk is the working copy of your application/web-site. This should always be able to be checked out and compiled. The top of the trunk where the latest code lives is called the head.

The branches is where you perform the modifications to the source. More on this in a bit.

Tags is where you have a specified release of the repository – this is so you can roll back to a previous known working copy if something has gone arse over tits. 

Now you know what the logical structure of the repository is what do you want to do with?

If you don’t have anything in the repository you need to fill it.

The first thing you do is put a clean working copy of the source into trunk. This should have no dead files, no file with things called index.htm.old (or similar). Also when checked out it should compile and run without crashing or when mounted on the webserver, run fine. This is the bit that people don’t seem to get. If you check the file out to a clean PC with just the compiler then you should be able to build/run the app. Too many times have I branched and found the source doesn’t compile because FooWidget2000.dll cannot be found. Turns out that FooWidget2000 is availble in R:\Software on the network or is a free download from SourceForge. 

That’s not right. *Everything* needed to build the project should be under version control. Also documentation of the project should be in there too. Most large corporations use Windchill (aka Global Vault) to store their documents, but I prefer to keep the documentation with the source – closer the better. Microsoft make a repository viewer which is great for project manager to access the documentation while not having to learn the arcane commands – source control isn’t just for source any more.

Now we have everything in place it’s time to start making changes. Let’s identify a necessary change – the foo widget is displaying the wrong value for bar. You think you know what is going on so you begin to branch the source into branches – but how should you do it?

Well my way is to have the user create a folder within branches for his (or her) changes:

projects/bugatti/trunk
                /tags
                /branches/graham.reeds/id00001
                                      /id00002


 
Within that user folder you create sub-folders for each branch you make. What constitutes a branch? Well I use branches mainly for performing a bug-fix. Did you note the use of singular? 

If you are working with a specified bug tracking system (like Trac or Mantis) then you can use the assigned bug id number, or if you are working on a new piece of software then you can call it by the task you are performing. I use a mixture of the two.

You can forgo the username, but I prefer it this way. People tend to point out you can use blame (or praise) and such to see who worked on what, but I prefer the username method. If you have your name stamped on it, then you are more likely to have a sense of pride in your work. You do have a sense of pride about your craft, don’t you?

Then when you have fixed problem with bar’s value you then merge the corrections back into the trunk. Usually the merging is only done after the fixes have been peer reviewed and approved by the lead coder – you don’t want substandard code to be checked in because if the original coder leaves then it will probably be you who have to work on it – so any bad smells in the code you should flag up immeadiately. (Also don’t take the process personally – it’s tempting to nitpick if the person’s code you are reviewing grilled you over your previous submission.)

Once the source is back in the trunk then that will be tested by the testing department – you’ve tested it yourself but a decent tester will test it in half a dozen ways while programmers tend to skip through to that bit and use keyboard shortcuts the entire time, etc.

This may be the last bug to be fixed before the latest release is pushed out the door. If you are on schedule, congrats. If not, well done on getting it finished.

Now this release needs to be marked in someway. This enables you, in the future, to see what source files made up an exact release. Very useful if a bug fixed previously has crept back in over time (unit tests help here). This is the last part of the puzzle. Basically you tag (or copy as it is Subversion) a set of files to the tags branch. The tags are usually numbered, named or a combination of the two. For instance. A minor bug fixing release after version 1.0.0 could be 1.0.1, whereas an added feature could make it 1.1.0. Also if you get paid to add a special feature by the XAB Corp. you could name a version 1.1.0 (XAB) to differentiate it from the 1.1.0 (HAL) you did for the HAL Corp.

And that concludes a simple overview of how source control works.

0 comments.

More on Multiple Repositories in Windows

October 5th, 2008 :: graham.reeds
Categories: Programming :: Subversion

Last time we spoke I left you with two repositories and waiting to put data into them.

So let’s get on with that, then.

In a temporary directory create your ferrari and bugatti folders here, and in them create the standard Trunk, Tags, and Branches (TTB).

Now switch into the two directories and run svn import on each:

D:\temp\bugatti>svn import .\ svn://localhost/bugatti -m "Commiting the initial TTB layout to repository"
Authentication realm: <svn://localhost:3690> 4f93af25-16dc-3d41-b82e-acee2e868d11
Username: graham.reeds
Password for 'graham.reeds': ********
Adding         trunk
Adding         branches
Adding         tags

Committed revision 1.

You can delete these temporary folders since they are no longer required.

Let’s start doing something useful with them.

In your directory where you normally do your programming, create a directory to hold the projects we are going to write. Due to a lack of imagination on my part, I use a directory called projects, also on drive D, to hold my projects.

So switch there and let’s get to work creating the directories.

The first will be project ferrari, so create a project folder named ‘ferrari’. In that directory issue the check-out command:

D:\projects\ferrari>svn co svn://localhost/ferrari/trunk ./
Checked out revision 1.

If you look at the folder you will see that a hidden folder called .svn has appeared. Open up Visual Studio (or similar if you use another IDE) and create a Win32 project called ferrari. For this I will accept all the defaults so the 20 or so files will demonstrate my purpose perfectly – I also prefer to configure my directory structure to something more convenient but that can be another blog topic.

So we now run ’svn add’ and are greeted by the following sight:

D:\projects\ferrari>svn add ./*.*
svn: Skipping argument: '.svn' ends in a reserved name
A         ferrari
A         ferrari\ChildFrm.cpp
A         ferrari\ChildFrm.h
A         ferrari\ferrari.cpp
A         ferrari\ferrari.h
A         ferrari\ferrari.rc
A         ferrari\ferrari.vcproj
A         ferrari\ferrari.vcproj.DIGITAL-UTOPIA.graham.reeds.user
A         ferrari\FerrariDoc.cpp
A         ferrari\FerrariDoc.h
A         ferrari\FerrariView.cpp
A         ferrari\FerrariView.h
A         ferrari\MainFrm.cpp
A         ferrari\MainFrm.h
A         ferrari\ReadMe.txt
A         ferrari\res
A  (bin)  ferrari\res\ferrari.ico
A         ferrari\res\ferrari.rc2
A  (bin)  ferrari\res\ferrariDoc.ico
A  (bin)  ferrari\res\Toolbar.bmp
A         ferrari\Resource.h
A         ferrari\stdafx.cpp
A         ferrari\stdafx.h
A  (bin)  ferrari.ncb
A         ferrari.sln
A  (bin)  ferrari.suo

The add command means they are now being watched by subversion (as exposed by the hidden .svn folder in the ferrari subdirectory). However they are not in the repository just yet. We need to commit them. This is fairly simple.

D:\projects\ferrari>svn ci ./ -m "Initial commit of the default project files"
Adding         ferrari
Adding         ferrari\ChildFrm.cpp
Adding         ferrari\ChildFrm.h
Adding         ferrari\FerrariDoc.cpp
Adding         ferrari\FerrariDoc.h
Adding         ferrari\FerrariView.cpp
Adding         ferrari\FerrariView.h
Adding         ferrari\MainFrm.cpp
Adding         ferrari\MainFrm.h
Adding         ferrari\ReadMe.txt
Adding         ferrari\Resource.h
Adding         ferrari\ferrari.cpp
Adding         ferrari\ferrari.h
Adding         ferrari\ferrari.rc
Adding         ferrari\ferrari.vcproj
Adding         ferrari\ferrari.vcproj.DIGITAL-UTOPIA.graham.reeds.user
Adding         ferrari\res
Adding  (bin)  ferrari\res\Toolbar.bmp
Adding  (bin)  ferrari\res\ferrari.ico
Adding         ferrari\res\ferrari.rc2
Adding  (bin)  ferrari\res\ferrariDoc.ico
Adding         ferrari\stdafx.cpp
Adding         ferrari\stdafx.h
Adding  (bin)  ferrari.ncb
Adding         ferrari.sln
Adding  (bin)  ferrari.suo
Transmitting file data ........................
Committed revision 2.

This can be confirmed by the ls command:

D:\projects\ferrari>svn ls svn://localhost/ferrari/trunk -R
ferrari/
ferrari/ChildFrm.cpp
ferrari/ChildFrm.h
ferrari/FerrariDoc.cpp
ferrari/FerrariDoc.h
ferrari/FerrariView.cpp
ferrari/FerrariView.h
ferrari/MainFrm.cpp
ferrari/MainFrm.h
ferrari/ReadMe.txt
ferrari/Resource.h
ferrari/ferrari.cpp
ferrari/ferrari.h
ferrari/ferrari.rc
ferrari/ferrari.vcproj
ferrari/ferrari.vcproj.DIGITAL-UTOPIA.graham.reeds.user
ferrari/res/
ferrari/res/Toolbar.bmp
ferrari/res/ferrari.ico
ferrari/res/ferrari.rc2
ferrari/res/ferrariDoc.ico
ferrari/stdafx.cpp
ferrari/stdafx.h
ferrari.ncb
ferrari.sln
ferrari.suo

We can now proceed with the project right? Well you could but you would be missing probably the most important thing about source control. Imagine you were working on an important project, you have pushed the latest release out the door and now are working on some very exciting new technologies extending it when your manager walks over and tells you that the important client has a problem in the FooBar when accessed by the Baz. He also informs you he has sent you an example set of data that demonstrates this flaw attached to an email and expects that the fix will be prompt and rigorously tested. Sure enough, once stepped through in a debugger you can see it and the fix is fairly trivial and has zero impact you can discern, but you are partway through an enhancement – there are partially written dialogs and functionality is greatly missing and won’t be ready for weeks. What can you do?

Well that’s where branching comes in handy. A rule of mine is that trunk should always be in a compilable state – no exceptions. So if that is the rule, how can we implement it? Well with branching. A branch is a fork of the code. With that code you can make as many adjustments as you like, and if the above situation occurs you can simply make another branch, work on that and then when the adjustments/modifications/fixes are made you can merge them back in with the main trunk. With due care branching can improve efficiency amongst a team, but it’s not with out drawbacks. That will be the topic of my next blog entry.

That’s about it – remember you can do the same stuff for the bugatti project also.

0 comments.

Setting up multiple Subversion repositories in Windows

September 28th, 2008 :: graham.reeds
Categories: Programming :: Subversion

Let’s face it – if you are looking at this right now the chances are you already know what Subversion is, so I will skip the tedious ‘yadda, yadda, free, yadda, yadda, great, yadda, yadda’.

So let’s take a look at setting one up – there are a lot of these, some good and some bad. Most go into details of setting up Apache and allowing you access from a small orbital platform stationed above Mars, but the chances you need remote access like that is minimal. If you do then I suggest you go read those – by the way they are only written by guys with beards.

The first thing we’ll do is download the latest Subversion Windows binary installer which is currently 1.5. In the future it will be different, but the concepts will probably remain the same.

Double click the installer and allow it to install naturally. Once that is complete we could run svnserve and be done, but it can be so much more beautiful. Let’s run it as a service.

Now Subversion has one slight annoyance. It has a global revision number. So if you have a single repository with multiple projects all projects will use the same incrementing revision system. That’s not particularly nice – especially when a single line change of code will result in a several hundred (or thousand) revision leap because of activity on another project.

So I prefer multiple repositories. It’s pretty easy to do. Let’s say you name your projects after famous marques. So let’s create a couple of projects:

svnadmin create "d:\svn\ferrari"
svnadmin create "d:\svn\bugatti"

I use D as my development drive and have short monikers for all my folders – \dev, \svn, \db, etc.

Notice svnadmin created a few directories under both ferrari and bugatti. You need to go into each of these and edit the conf/svnserve.conf and the passwd files.

Uncomment the following lines in the conf/svnserve.conf file by removing the pound character from the start of each line:

anon-access = none
auth-access = write
password-db = passwd

Since the chances of working with a harry and sally are next to nil, delete their lines from passwd and replace it with your own:

graham.reeds = password

You will need to do this for each as outside the aforementioned Apache there is no real way of doing that.

Now that is complete let’s perform the final step of installing Subversion as a Windows service so that it is always available. Under OS’s other than XP you will need to find sc.exe otherwise Just issue the following command:

sc create svnserver binpath= "c:\program files\subversion\bin\svnserve.exe --service -r d:\svn" displayname= "Subversion" depend= Tcpip start= auto
sc description svnserver "Subversion server service (svnserver)"

It’s set to auto-start so it will start up automatically when your machine restarts but currently it’s not running. We can fix that while still at the command line by typing:

net start svnserver

Now the final thing to do is set it up so that when we do a commit we have an editor to write the comments in. Since svn doesn’t provide one then we will need to provide our own. So lets edit your environment settings and add SVN_EDITOR with the value of %systemroot%\system32\notepad.exe.

You could use Notepad++ but simple notepad is way easier and Notepad++ is too heavyweight for this job. In this one case the traditional notepad is the better option.

Next time I will show you how to populate those repositories.

1 comment.