Archive for the 'Tutorials' Category

Editing past log comments in Subversion

Tuesday, March 18th, 2008

Subversion is my source version control software of choice, but it’s not immediately obvious how to edit the log comment of a past commit (such as after adding a particularly scathing remark that may not be a wise career move). A caveat is that you need to have administrator access to the Subversion repository.

In the repository directory (wherever you created the repository) is a hooks folder (on my system this is H:\IT\svnrepos\pas\hooks). This folder contains scripts that are called by Subversion when various events occur (hooks). The files that are created in a repository’s hooks folder by default are templates of hooks designed for Linux etc. On a Windows server they need to be created as batch files (*.bat) to be executed.

What you need to do is create a hook that will run prior to changing a revision property (such as a log comment) and let Subversion know that changing the comment is permitted. By default changing the log comment is disabled (obviously, or you wouldn’t be reading this). Make a new file in the hooks folder called pre-revprop-change.bat and write the following into it:

if "%4" == "svn:log" exit 0

echo Property '%4' cannot be changed >&2
exit 1

The %4 argument contains which operation is being performed. If the operation is svn:log we indicate success, which is a return code of 0. Otherwise it prints an error and exits with a non-zero, which indicates an error (and that the operation shouldn’t be allowed). Once that is saved, you should be able to use your to Subversion client to edit the comment. Be careful with what you do, as revision properties aren’t versioned, and you won’t be able to undo your changes. You should also probably rename pre-revprop-change.bat to pre-revprop-change.bat.bak once finished.

Displaying Contacts in Microsoft Outlook Address Book

Tuesday, December 4th, 2007

If you can’t get your contact list coming up in Outlook, here’s a how-to that works well. Two things to look out for are Outlook not closing properly (it may run as a notification button, open Task Manager and kill the Outlook process off just to make sure) which seems to stop the fix from working, and the fact that right-clicking on the Outlook icon to get to mail settings doesn’t work if the Outlook icon is a shortcut (ie 99% of the time). To get into mail settings, open Control Panel then Mail once Outlook is shut down.

Fine-tuning polymorphism in C# using the new keyword

Wednesday, August 8th, 2007

This doesn’t come up too often but can be useful. Sometimes, when using inheritance, it can be difficult to get the right implementation of a virtual method called. This is the kind of model I had today:

namespace InheritanceTest
{

	public class BaseClass
	{
		public BaseClass() {}

		public virtual void A(int count)
		{
			for (int i = 0; i < count; i++)
				B(string.Format("{0} Base Hello", i));	// This calls DerivedClass.B(string)
		}

		public virtual void B(string s)
		{
			Console.WriteLine("Base: "+s);
		}
	}

	public class DerivedClass : BaseClass
	{
		public DerivedClass() : base() {}

		public override void A(int count)
		{
			base.A(count);	// call BaseClass.A(int)
		}

		public override void B(string s)
		{
			Console.WriteLine("Derived: "+s);
		}
	}

	class MainClass
	{
		public static void Main(string[] args)
		{
			Console.WriteLine("Test begins:");

			DerivedClass obj = new DerivedClass();
			//obj.B(10);

			Console.WriteLine("Test ends.");
		}
	}
}

When this is compiled and run, the method called in BaseClass.A() is DerivedClass’s implementation of B(). The series of method calls will look like this:

  1. DerivedClass.A()
  2. BaseClass.A()
  3. DerivedClass.B() ten times

So when BaseClass.A() makes the call to B(), the derived class’s B() method is found and executed, rather than BaseClass.B(). This is exactly how you would usually want the inheritance to work; the derived class has methods that override the base class, and the base class calls fall through to the child’s implementation of the virtual methods.

The problem with this is if you want to be able to use the base class’s implementation of B() in BaseClass.A()’s call to B(). BaseClass.B()’s implementation may contain code required in BaseClass, but DerivedClass.B()’s implementation is not appropriate for use in BaseClass. Basically you want the following series of method calls:

  1. DerivedClass.A()
  2. BaseClass.A()
  3. BaseClass.B() ten times

We need to indicate to the compiler that, although DerivedClass.B() implements B(), it doesn’t necessarily override BaseClass’s implementation of B(). That is done by changing the override keyword in DerivedClass.B()’s declaration to new:

Change:
   public override void B(string s)
to:
   public new void B(string s)

The effect of this is that when B() is called in BaseClass, it will be BaseClass.B() that will be executed, because DerivedClass.B() is flagged as a new implementation of the B() method that does not override the existing one. The new DerivedClass.B() method is still visible in DerivedClass and beyond:

DerivedClass obj = new DerivedClass();
obj.B("Test");   // This will execute DerivedClass.B(), not BaseClass.B()

will execute DerivedClass.B().