I'm in the middle of enhancing BugTracker.NET's integration with Subversion. Several months ago I added some integration, in the form of a "post-commit" hook script that inserts rows into BugTracker.NET's DB when somebody does a checkin into Subversion and includes the bug id in the comment. Then within BugTracker.NET, there was a page to display the added rows. And that was it.
I realized only this week that I could carry the integration much farther. I'm still wondering why it took me so long to realize that. Mental block. Anyway, since the path and the revision are in the database, I can use those to go back to Subversion to gather more info, well after the post-commit moment, when somebody is interacting with the page. Here's the enhanced page that shows the file revisions, now showing new links for "diff" and "hist".
Clicking on "diff" causes the web page to go back to the server and execute C# code which in turn executes "svn diff", captures the output, and turns it into HTML. The result looks like this:
Clicking on "hist" is similar, but it runs the "svn log" command. The result looks like this:
From this last page you can see the entire history of a file, view the source code, use the snv "blame" command to see who changed what line when, and select any two revisions to diff.
So, here are some of the design decisions:
* How do I actually talk to Subversion? The first example code I looked at was WebSvn. It uses "svnlook" which requires local, direct access to the Subversion files. To use it, BugTracker.NET would have to be installed on the same server as the Subversion repository. Instead I am using the client-side "svn". You still have to install the Subversion software on the IIS web server, but you don't need to have your Subversion repositories on it.
* How does a BugTracker.NET user configure the repository? Should it be in Web.config, so that one instance of BugTracker.NET is associated with exactly one Subversion repository? Or should it be at the project level, to allow for a model where each project might have a different repository? Or a combo, a global setting that is the default, but overridable at the project level? Right now, it's just at the Web.config level. I'll take a YAGNI, wait-and-see approach, see what my users ask for.
* What if anonymous read access is not specified for the repository? At what level should the user/password credentials be specified? Global, in Web.config? at the project level? at the user level? Same as above, right now it's just at the Web.config level.
* Does it make sense to add more pages so that BugTracker.NET can serve as a general Subversion client? Able to traverse the folder tree? Not yet...
The trickiest part of the work - and the most visually rewarding - was producing the visual side-by-side diff. I issue a "diff" to get the Unified Diff Format info, and then two "cat" commands to get the two source files. Then, using the Unified Diff Format as a driver, I iterate through the lines of each file, marking them up. It was tricky because I am inept. I kept incrementing my indexes when I shouldn't have or vice versa.
Below is an example of Unified Diff Format. The "@@ -1,16 +1,17 @@" means, that what follows refers to lines 1-16 of the old revision (13) and lines 1-17 of the new revision. Each subsequent line starts with either a + for added to the new revision, - for deleted from the new revision, or space for unchanged. A - followed immediately by a + can be thought of as a change.
--- a.txt (revision 13)
+++ a.txt (revision 14)
@@ -1,16 +1,17 @@
+A NEW FIRST LINE
+ADDED AFTER 3
+ADDED AFTER 3 B
+ADDED AFTER D
@@ -38,18 +39,12 @@
+ADDED AFTER 3
+ADDED AFTER 3 B
So, that's where the Subversion integration is so far.