<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Doing better &#187; Tools</title>
	<atom:link href="http://www.longacre-scm.com/blog/index.php/category/tools/feed" rel="self" type="application/rss+xml" />
	<link>http://www.longacre-scm.com/blog</link>
	<description>Opinions on CM, software development, and process automation from Longacre.</description>
	<lastBuildDate>Sat, 28 Aug 2010 21:23:31 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using Doxygen&#8217;s \test command with C++</title>
		<link>http://www.longacre-scm.com/blog/index.php/2010/08/using-doxygens-test-command-with-c</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2010/08/using-doxygens-test-command-with-c#comments</comments>
		<pubDate>Sat, 28 Aug 2010 21:19:39 +0000</pubDate>
		<dc:creator>Austin Hastings</dc:creator>
				<category><![CDATA[Off-topic]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/?p=95</guid>
		<description><![CDATA[I&#8217;m working on some C++ code that is documented using Doxygen. Nothing earth-shattering there.
But I&#8217;m doing unit testing, and writing unit tests. In this case, I&#8217;m using the boost C++ libraries. That means my tests don&#8217;t look like classes, the way they might look if I was using CppUnit or CxxUnit. Instead, they look like [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on some C++ code that is documented using <a href="http://www.doxygen.org">Doxygen.</a> Nothing earth-shattering there.</p>
<p>But I&#8217;m doing unit testing, and writing unit tests. In this case, I&#8217;m using the <a href="http://www.boost.org">boost C++ libraries.</a> That means my tests don&#8217;t look like classes, the way they might look if I was using CppUnit or CxxUnit. Instead, they look like macros:<br />
<code><br />
BOOST_AUTO_TEST_CASE( null_ctor ) {</p>
<p>	Arena &#038; sut = Simple::Arena();<br />
	BOOST_CHECK( sut.capacity() != 0 );<br />
}<br />
</code></p>
<p>The macro expansion is really quite clever, in a Lovecraftian &#8220;there are secrets man was not meant to know&#8221; fashion. And reading them has certainly improved my knowledge of C++. (But it also permanently lowered my SAN by a few points, I think.)</p>
<p>Anyway, Doxygen offers this command called <b>\test</b> that seems tailor-made for testing.</p>
<p>Well, it&#8217;s not. The command description is very &#8220;vague,&#8221; in that you use it to add entries (paragraphs) to the &#8220;test list.&#8221; </p>
<p>Some experimentation will show that the apparent use is to document something (a class, a function) and add a bunch of these \test entries, just like adding \param commands. And the entity you are documenting will then have a <b>Test:</b> section in its documentation.</p>
<p>This is totally not what I want. And I&#8217;m pretty sure it&#8217;s not what anybody doing TDD wants. What I want is to somehow tie my tests, which are in a separate location (different file, different class, different namespace, etc.), back to the class or function that I&#8217;m testing.</p>
<p>The best way I&#8217;ve found so far to accomplish this is to <em>lie</em> to Doxygen about what is being documented. Here&#8217;s my current scheme:<br />
<code><br />
#define BOOST_TEST_DYN_LINK<br />
#include &lt;boost/test/unit_test.hpp&gt;</p>
<p>#include &lt;Bronze/Memory/Simple/Arena.h&gt;</p>
<p>using namespace Bronze::Memory;</p>
<p>BOOST_AUTO_TEST_SUITE( Memory_SimpleArena )</p>
<p>/// \class Bronze::Memory::Simple::Arena<br />
/// \test \b null_ctor Confims that a SimpleArena no-args construction will<br />
/// use the default size, whatever that is. (1m)</p>
<p>BOOST_AUTO_TEST_CASE( null_ctor ) {</p>
<p>	Arena &#038; sut = Simple::Arena();<br />
	BOOST_CHECK( sut.capacity() != 0 );<br />
}<br />
</code></p>
<p>Adding the <tt>\class</tt> command tells Doxygen to re-open the documentation of the target class. The <tt>\test</tt> command is then associated with the &#8220;right&#8221; class, and I include the testcase name in bold as part of the test description. </p>
<p>This still doesn&#8217;t generate a link to the right source file (containing the test), and it doesn&#8217;t really know anything about the test case. So it&#8217;s not a perfect solution. But it does enable me to put my testcase documentation with my testcases, while having the documentation actually show up attached to the right class.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2010/08/using-doxygens-test-command-with-c/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Which &#8216;which&#8217; is which?</title>
		<link>http://www.longacre-scm.com/blog/index.php/2010/08/which-which-is-which</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2010/08/which-which-is-which#comments</comments>
		<pubDate>Tue, 10 Aug 2010 22:13:27 +0000</pubDate>
		<dc:creator>Austin Hastings</dc:creator>
				<category><![CDATA[Off-topic]]></category>
		<category><![CDATA[Practice]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/?p=91</guid>
		<description><![CDATA[The &#8216;which&#8217; utility is one of those really useful commands that never seems to cross the bridge from Unix to Windows. The CMD.EXE special %$PATH:f syntax seems to promise some relief, but of course it&#8217;s never that simple &#8211; I at least want to type &#8220;which foo&#8221; rather than &#8220;which foo.exe&#8221;.
So here&#8217;s which.cmd &#8211; a [...]]]></description>
			<content:encoded><![CDATA[<p>The &#8216;which&#8217; utility is one of those really useful commands that never seems to cross the bridge from Unix to Windows. The CMD.EXE special %$PATH:f syntax seems to promise some relief, but of course it&#8217;s never that simple &#8211; <strong>I</strong> at least want to type &#8220;which foo&#8221; rather than &#8220;which foo.exe&#8221;.</p>
<p>So here&#8217;s <code>which.cmd</code> &#8211; a script that tries to DWIW. </p>
<p>Note that this script is wrong in one key detail: it searches inside-out. That is, any &#8220;foo.COM&#8221; will take precedence over any &#8220;foo.EXE&#8221; even if the .exe version occurs earlier in the PATH.</p>
<pre>
@echo off
REM Copyright (c) 2010, Austin Hastings.
REM This file may be used for any purpose without restriction.

REM NOTE: This script does not handle multiple entries with different
REM extensions correctly. It returns the first matching EXTENSION, rather
REM than returning the first DIRECTORY with any EXTENSION.

REM Analogous to unix 'which' command, look for a matching runnable
REM in %PATH% and print the location.

SETLOCAL ENABLEDELAYEDEXPANSION

set check_extensions= ;%PATHEXT%

:ext_loop
if "%check_extensions%" == "" goto done

for /F "tokens=1* delims=;" %%E in ( "%check_extensions%" ) do (
	set check_extensions=%%F
	set target=%1%%E
	for %%W in (  !target! ) do set answer=%%~f$PATH:W
)

if "%answer%" == "" goto ext_loop

:done
if "%answer%" == "" goto not_found

@echo %answer%
goto exit

:not_found
@echo No runnable matching '%1' was found.

:exit
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2010/08/which-which-is-which/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Some bash goodness</title>
		<link>http://www.longacre-scm.com/blog/index.php/2009/10/some-bash-goodness</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2009/10/some-bash-goodness#comments</comments>
		<pubDate>Wed, 28 Oct 2009 15:09:48 +0000</pubDate>
		<dc:creator>Austin Hastings</dc:creator>
				<category><![CDATA[Off-topic]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/index.php/2009/10/some-bash-goodness</guid>
		<description><![CDATA[Here&#8217;s some bash goodness (well, not really) to make &#8216;less&#8217; a little bit more useful.
&#160;
less() {
 &#160; &#160; &#160; &#160;local -a args
&#160;
 &#160; &#160; &#160; &#160;for arg
 &#160; &#160; &#160; &#160;do
 &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;case &#8220;$arg&#8221; in
 &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;*:[[:digit:]]* )
 &#160; &#160; &#160; &#160; &#160; [...]]]></description>
			<content:encoded><![CDATA[<div>Here&#8217;s some bash goodness (well, not really) to make &#8216;less&#8217; a little bit more useful.</div>
<div>&#160;</div>
<div>less() {</div>
<div> &#160; &#160; &#160; &#160;local -a args</div>
<div>&#160;</div>
<div> &#160; &#160; &#160; &#160;for arg</div>
<div> &#160; &#160; &#160; &#160;do</div>
<div> &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;case &#8220;$arg&#8221; in</div>
<div> &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;*:[[:digit:]]* )</div>
<div> &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;line=${arg/#+(?):/}</div>
<div> &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;args[${#args[*]}]=&#8221;+$line&#8221;</div>
<div> &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;arg=${arg/%:+(?)/}</div>
<div> &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;;;</div>
<div> &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;esac</div>
<div>&#160;</div>
<div> &#160; &#160; &#160; &#160; &#160; &#160; &#160; &#160;args[${#args[*]}]=$arg</div>
<div> &#160; &#160; &#160; &#160;done</div>
<div>&#160;</div>
<div> &#160; &#160; &#160; &#160;$( which less ) &#8220;${args[@]}&#8221;</div>
<div>}</div>
<div>&#160;</div>
<div>Basically, this shell function loads when you tell it to (in your .profile, likely), and it replaces the &#8216;less&#8217; command. When you type &#8216;less &#8230;&#8217; on the command line, the function runs.</div>
<div>&#160;</div>
<div>It scans through the args, looking for one like filename.c:24, and if it finds that kind of arg, it replaces it with +24 filename.c &#8212; translating the syntax used by a *lot* of compilers into the syntax used by less for opening a file and jumping directly to the line number.</div>
<div>&#160;</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2009/10/some-bash-goodness/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit tests for MySQL scripts</title>
		<link>http://www.longacre-scm.com/blog/index.php/2009/04/unit-tests-for-mysql-scripts</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2009/04/unit-tests-for-mysql-scripts#comments</comments>
		<pubDate>Sun, 26 Apr 2009 01:07:09 +0000</pubDate>
		<dc:creator>Austin Hastings</dc:creator>
				<category><![CDATA[Practice]]></category>
		<category><![CDATA[Software CM]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[database]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/index.php/2009/04/58</guid>
		<description><![CDATA[Recently I had the opportunity to develop a unit testing framework for MySQL scripts in mostly-pure SQL. While I can&#8217;t share the code, I can certainly describe what we did, and why we did it. Hopefully it will be useful to you.

My client was reorganizing a development team into an agile mode in order to [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I had the opportunity to develop a unit testing framework for MySQL scripts in mostly-pure SQL. While I can&#8217;t share the code, I can certainly describe what we did, and why we did it. Hopefully it will be useful to you.<br />
<span id="more-58"></span></p>
<p>My client was reorganizing a development team into an agile mode in order to deal with an outsourcing disaster. It was one of those horror stories that starts out like &#8220;We were 3 years in to a 10 month project, when &#8230;&#8221; I was brought on to help ramp up their build and deployment processes, to get continuous integration and testing systems up, and to help mechanize their deployments.</p>
<p>The impetus for the MySQL unit test framework came from a short term contractor. The one &#8220;constant&#8221; in the otherwise highly-variable environment had been that the team wasn&#8217;t changing. Suddenly, that stopped being true. We had a handful of contractors in for a short term surge, and none of them were familiar with the application, or with SQL (it seemed). The offender was using the CI server as his syntax checker for database scripts. Yikes!</p>
<p>Luckily, the garbage he delivered was syntactically invalid. The mysql command-line client rejected the script and exited with an error status, which caused the CI script to log a failure, and &#8230; voila! Everyone credited me with doing a great job of implementing CI, because it was even checking the database stuff. Like a good consultant, I said &#8220;Yes. Of course.&#8221; Then I ran back to my desk, thinking &#8220;Oh, no! I&#8217;ve got to come up with a unit test framework for the MySQL stuff, pronto!&#8221; And I did.</p>
<p><strong>Solutions</strong></p>
<p>The software was a pretty complex web app, and the target environment was a mixture of Linux and Windows. As a result, when I looked at existing SQL unit test frameworks (<a href="http://www.dbunit.org/">dbUnit</a> and <a href="http://sqlunit.sourceforge.net/">sqlUnit,</a> respectively) I had to reject them. They are decent products &#8211; and free &#8211; but the fact is that they expect certain things about their runtime environment that we couldn&#8217;t deliver. We had to build our own MySQL unit test framework, ideally in &#8220;pure&#8221; MySQL.</p>
<p>Fortunately for me, a nice guy named Giuseppe Maxia maintains a web site at <a href="http://www.datacharmer.org">datacharmer.org,</a> and he has written a library of general-purpose MySQL code. (Called the General Purpose Stored Routine library, or gp_sr_lib.) Among the all this well-written, free, already debugged code was a set of testing routines. Thirty minutes into my development effort, I was already 80% done. Woo-hoo!</p>
<p>The GP library test routines are a good start on a mysqlUnit library, and I strongly recommend that if you need such a library you stop reading here and go download the code. Right now. </p>
<p><strong>Rolling (y)our Own</strong></p>
<p>There are a couple of gotchas that you&#8217;ll want to watch out for in your own unit testing library. First, the tests should be able to integrate into your CI engine. In particular, you need to decide on and implement some kind of failure mode &#8211; either fail when the first problem occurs, or fail after running all test cases. If you&#8217;re running the mysql client via some kind of exec call, be aware that while syntax errors will cause the client to exit with a failure code, other errors will not cause a failure. Instead, the client prints a diagnostic and returns zero. What&#8217;s more, the syntax does not support a deliberate abort from within the SQL engine.</p>
<p>In my own case, I chose to follow the model that Maxia has provided, and NOT fail as soon as a test fails. Rather, my code collected the results of all the tests that were run, and summarized them. In order to get &#8220;fail on error&#8221; behavior out of the mysql command line client, I coded a routine that would perform a &#8220;SELECT force_mysql_client_abort FROM no_such_table&#8221;. This definitely does cause the client to abort, at least until some developer creates a table called &#8220;no_such_table.&#8221; Then I wrapped the test cases in an &#8220;ignore failure&#8221; script that called the summarizer after all the cases had run, which in turn would call the abort routine if the error count was non-zero.</p>
<p>Another thing I chose to &#8220;fix&#8221; was the routine names. Maxia&#8217;s code includes both functions and procedures, but the names are not really in keeping with the style used in the various xUnit test frameworks. The library contains a procedure for asserting the existence of a database table. It is called as:</p>
<p><code>CALL check_table('db name', 'table name');<br />
</code></p>
<p>I opted to &#8220;embrace and extend&#8221; the library. I wrapped these types of checks into functions, like this:</p>
<p><code><br />
set_database('db name');<br />
assert_table_exists('table name');<br />
assert_table_exists_in_db('other table', 'other db');<br />
</code></p>
<p>And in general, wherever there is a straight-ahead assert, I also added an &#8220;assert_not&#8221;. In terms of effect, there is no real difference in behavior between Maxia&#8217;s naming and my own. But I felt that the developers, who were using jUnit and nUnit, would be more comfortable learning a set of routines that had a similar structure and style.</p>
<p><strong>Going Most of the Way: DDL</strong></p>
<p>I tried to make a list of the various things that SQL scripts might do. The most obvious &#8212; and this probably accounted for two thirds or more of the scripts we had &#8212; is DDL statements. DDL (Data Definition Language) is that subset of SQL that relates to defining databases, tables, indexes, triggers, and the like. While the most frequently executed SQL statements are DML (Data Manipulation Language), DDL is where it&#8217;s at for most of the human-generated script files: CREATE TABLE, ADD INDEX, etc.</p>
<p>The great thing is that the assertions for these statements are trivial to write. Maxia&#8217;s library includes the CHECK_TABLE procedure, and some code for looking up procedures and functions. Adding other stuff, like keys and constraints, is pretty straightforward. By the end of the day you should have a long list of functions like assert_table_exists, assert_index_exists, assert_database_exists, and  assert_column_has_type.</p>
<p><strong>Deploy Early</strong></p>
<p>At this point, you&#8217;re ready to go live. Except that you need to build a framework to run these tests. That&#8217;s going to depend a lot on your deployment process, and on your particular CI environment. Sorry. The simplest idea would be to write a script that matches the file names of test files, and runs them one at a time. Call that script from CI, and make sure the exit status is meaningful.</p>
<p>Forget the next couple of sections, because most of the database changes you&#8217;re likely to see are DDL. Developers and DBAs do a lot of adding fields, adding indexes, and sometimes adding tables. If you have just the existence assertions for each kind of object, your library will cover two-thirds or more of the statements being delivered. That&#8217;s not a trivial amount of test coverage for a day or two of work. Ship it! Your developers will need some training, and you&#8217;ll need to beat on the thing once it&#8217;s deployed to your CI servers to make sure that the errors are coming out correctly. </p>
<p><strong>Sell to the Development Team</strong></p>
<p>I recommend that you write some simple tests of things you know to be true. Confirm the positive cases first. Then sit down with a smart, involved developer and pair develop some unit tests for code he hasn&#8217;t written yet. Do it the way you want the developers to do it, including deciding how to handle assertions that don&#8217;t exist yet. </p>
<p>In our case, the DBAs had already established a naming convention for database update files. I chose to duplicate the file names, which would look like ####_description.sql, changing the .sql extension to .test.sql. This let the testing framework associate the test with the delivered change. When running a &#8220;from zero&#8221; deployment, the test framework would then run TEST-CHANGE-TEST and expect the first test to fail and the second to pass. This demonstrated that the test was meaningful for the change (remember, the change is supposed to repair a shortcoming that is demonstrated by the test).</p>
<p>Once you&#8217;ve got buy-in from your chosen developer, sit down and develop a presentation that the two of you can give. Point to specific examples of blown deployments as reasons for unit testing the SQL. Then get the coder to explain the available test assertions. Then explain the framework you&#8217;ve developed to integrate the testing library with CI, and explain what failures are going to look like. And don&#8217;t forget to point them at the documentation you&#8217;ve written on the project wiki. This should get your team on board, and now you can start looking for other assertions to write. You can also start tightening the screws on your framework. Make it so that no change can be delivered without at least one test.</p>
<p><strong>Simple DML Checking</strong></p>
<p>The next obvious category of SQL statements to check is simple DML. These are the CRUD verbs: INSERT, SELECT, UPDATE and DELETE.  Except that SELECT can be pretty hard to check within SQL, so it&#8217;s best to ignore it for now in favor of the others. The problem with DML is knowing what to check for. If you insert a row, should you check that the ROW_COUNT() returns 1? Or should you query for the particular key of that row? </p>
<p>I&#8217;m pretty convinced that DML commands in scripts are going to be metadata related. That is, your application may be inserting customer records, or video titles, or whatever you track. But if a developer codes a DELETE, INSERT, or UPDATE into a deployable script, I think the intent is either to perform some kind of bulk fix (convert data fields, or eliminate nulls) or it is adjusting the &#8220;background&#8221; data &#8212; the list of postal codes, state and province names, etc. that your application relies on. In the case of the simple background data, if you added or updated it, you should check it explicitly: assert that for a specific key, the values are as expected. </p>
<p>Some examples of helpful functions would be <code>assert_statement_affects_rowcount(prepared_statement, num_rows), assert_table_column_matches_count('table name', 'column', value, count),</code> and their negatives. The way to do dynamic programming in MySQL is with prepared statements. You can construct a string containing a SQL statement, use PREPARE to assign it to an identifier, and then EXECUTE the identifier:</p>
<p><code><br />
PREPARE stmt<br />
    FROM<br />
        CONCAT("SELECT COUNT(*) FROM ", table_name, " WHERE ", field_name, " = ?");<br />
</code></p>
<p><code><br />
EXECUTE stmt USING value;<br />
</code></p>
<p>In the more complex case of a data format or type update, the update should be encoded in a stored procedure. This way you can unit test the stored procedure with sample data. Once the procedure is ready to go, write a script that calls the procedure &#8211; confident already that the procedure will work &#8211; and test the invocation by confirming random elements of the data have converted correctly.</p>
<p><strong>Testing Result Sets</strong></p>
<p>As mentioned, testing SELECT can be a real challenge. While it is easy to create an assert_row_count(num) to confirm that your query returned the right number of values, it can be much harder to create a function to assert that a particular ordering exists, or that the results are truly grouped by postal code.</p>
<p>The first thing to do is go ahead and write the assertion functions for number of rows returned by the query. That&#8217;s simple, straightforward, and it can stand in place of more complex stuff for a long time. You may not ever get around to writing the more challenging assertions &#8212; if the tests are designed well enough, the number of results may be meaningful enough. If you do need to write more, especially if the query is complex, pass the query as a string to your assertion, prepare it as a statement, and make sure the results go into a temporary table. Then you can write whatever horribly complex code you need against the temporary table, without having to worry about losing context.</p>
<p><strong>Testing Triggers</strong></p>
<p>Triggers are going to be harder to test than other pieces of code because of the diverse ways you can invoke them. For example, a DELETE trigger may need to be checked with a simple delete statement as well as with a CASCADE from a foreign key relationship. Beyond creating assertions for the existence and type of triggers (BEFORE/AFTER, INSERT/UPDATE/DELETE, etc.) there isn&#8217;t really any obvious set of assertions to write. It&#8217;s more a question of deciding how to test the effects of the triggers, and of documenting the ways the trigger can be invoked.</p>
<p><strong>Conclusion</strong></p>
<p>Unit testing, and test-first development, are well established best practices. But it&#8217;s easy to overlook the &#8220;small stuff&#8221; when developers are setting up frameworks for testing their code. Database updates are small, but when they go wrong they can take out the rest of the system. It&#8217;s important to apply the same techniques, and get the same value, to this part of your development. Now you can.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2009/04/unit-tests-for-mysql-scripts/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Gotcha: XML include processing in CruiseControl.NET</title>
		<link>http://www.longacre-scm.com/blog/index.php/2008/06/gotcha-xml-include-processing-in-cruisecontrolnet</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2008/06/gotcha-xml-include-processing-in-cruisecontrolnet#comments</comments>
		<pubDate>Tue, 24 Jun 2008 16:24:36 +0000</pubDate>
		<dc:creator>Austin Hastings</dc:creator>
				<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/index.php/2008/06/gotcha-xml-include-processing-in-cruisecontrolnet</guid>
		<description><![CDATA[Release 1.4 of CruiseControl.NET includes a new Configuration Preprocessor. The great thing is that this provides a C preprocessor-like macro syntax, so projects can be made using relatively powerful templates.
The bad thing is that it&#8217;s new, and so there are some gotcha&#8217;s laying around. I just found one:
I defined a ccnet.config file structured like this:


&#60;cruisecontrol
 [...]]]></description>
			<content:encoded><![CDATA[<p>Release 1.4 of CruiseControl.NET includes a new <a href="http://confluence.public.thoughtworks.org/display/CCNET/Configuration+Preprocessor">Configuration Preprocessor</a>. The great thing is that this provides a C preprocessor-like macro syntax, so projects can be made using relatively powerful templates.</p>
<p>The bad thing is that it&#8217;s new, and so there are some gotcha&#8217;s laying around. I just found one:</p>
<p>I defined a ccnet.config file structured like this:</p>
<blockquote><pre>

&lt;cruisecontrol
  xmlns:cb="urn:ccnet.config.builder"
  >
  &lt;!-- Define some local configuration symbols -->
  &lt;cb:define
    FOO="bar"
    />
  &lt;!-- Define a CCnet project template called "cb:PROJECT" -->
  &lt;cb:define
    name="PROJECT"
    >
    &lt;project
      name = "$(projectName)"
      >
      &lt;!--
          guts go here
          -->
    &lt;/project>
  &lt;/cb>
  &lt;!-- Use template -->
  &lt;cb:PROJECT
    projectName = "My dog has fleas"
    />
&lt;/cruisecontrol>
</pre>
</blockquote>
<p>That worked fine, and I could see how to rubber-stamp that project template to all my various continuous-integration areas and other workspaces.</p>
<p>But then I got clever, and decided to separate out the template from the local configuration.</p>
<blockquote><pre>

&lt;cruisecontrol
  xmlns:cb="urn:ccnet.config.builder"
  >

  &lt;!-- Define some local configuration symbols -->
  &lt;cb:define
    FOO="bar"
    />

  <strong>&lt;!-- Include template(s) file -->
  &lt;cb:include
    href = "project-template.xml"
    /></strong>

  &lt;!-- Use template -->
  &lt;cb:PROJECT  projectName = "My dog has fleas"  />
&lt;/cruisecontrol>
</pre>
</blockquote>
<p>By unfortunate coincidence, I had to reboot my laptop at this point &#8212; I kicked the power strip under the desk, removing power to the docking station. The Lenovo I&#8217;m using (client provided) doesn&#8217;t handle this at all, so it was restart time. When I came back up, the CruiseControl.NET service wouldn&#8217;t start.</p>
<p>Debugging is simple and easy with the &#8220;ccnet.exe&#8221; command line utility. Just run<br />
<code><br />
ccnet.exe -config:ccnet.config -validate</p>
<p></code></p>
<p>The error, though, was incomprehensible:</p>
<blockquote><pre>
C:\Program Files\CruiseControl.NET\server>ccnet -config:ccnet.config -validate
CruiseControl.NET Server 1.4.0.3400 -- .NET Continuous Integration Server
Copyright c 2008 ThoughtWorks Inc.  All Rights Reserved.
.NET Runtime Version: 2.0.50727.1433    Image Runtime Version: v2.0.50727
OS Version: Microsoft Windows NT 5.1.2600 Service Pack 3        Server locale: e
n-US

[CCNet Server:DEBUG] The trace level is currently set to debug.  This will cause
 CCNet to log at the most verbose level, which is useful for setting up or debug
ging the server.  Once your server is running smoothly, we recommend changing th
is setting in C:\Program Files\CruiseControl.NET\server\ccnet.exe.config to a lo
wer level.
[CCNet Server:INFO] Reading configuration file "C:\Program Files\CruiseControl.NET\server\ccnet.config"
[CCNet Server:ERROR] Exception: The configuration file contains invalid xml: C:\Program Files\CruiseControl.NET\server\ccnet.config
----------
ThoughtWorks.CruiseControl.Core.Config.ConfigurationException: The configuration file contains invalid xml: C:\Program Files\CruiseControl.NET\server\ccnet.config ---> System.Xml.XmlException: 'cb' is an undeclared namespace. Line 1, position 2.
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.Throw(String res, String arg, Int32 lineNo, Int32 linePos)
   at System.Xml.XmlTextReaderImpl.LookupNamespace(NodeData node)
   at System.Xml.XmlTextReaderImpl.ElementNamespaceLookup()
   at System.Xml.XmlTextReaderImpl.ParseAttributes()
   at System.Xml.XmlTextReaderImpl.ParseElement()
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.XmlTextReaderImpl.Read()
   at System.Xml.XPath.XPathDocument.LoadFromReader(XmlReader reader, XmlSpace space)
   at System.Xml.XPath.XPathDocument..ctor(Stream stream)
   at ThoughtWorks.CruiseControl.Core.Config.Preprocessor.ConfigPreprocessorEnvironment.push_include(String href)
   at ThoughtWorks.CruiseControl.Core.Config.Preprocessor.ConfigPreprocessor.PreProcess(XmlReader input, XmlWriter output, PreprocessorUrlResolver resolver, Uri input_uri)
   at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.CreateXmlValidatingLoader(FileInfo configFile)
   at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.AttemptLoadConfiguration(FileInfo configFile)
   --- End of inner exception stack trace ---
   at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.AttemptLoadConfiguration(FileInfo configFile)
   at ThoughtWorks.CruiseControl.Core.Config.DefaultConfigurationFileLoader.Load(FileInfo configFile)
   at ThoughtWorks.CruiseControl.Core.Config.FileConfigurationService.Load()
   at ThoughtWorks.CruiseControl.Core.Config.FileWatcherConfigurationService.Load()
   at ThoughtWorks.CruiseControl.Core.Config.CachingConfigurationService.Load()
   at ThoughtWorks.CruiseControl.Core.CruiseServer..ctor(IConfigurationService configurationService, ProjectIntegratorListFactory projectIntegratorListFactory, IProjectSerializer projectSerializer)
   at ThoughtWorks.CruiseControl.Core.CruiseServerFactory.Create(Boolean remote, String configFile)
   at ThoughtWorks.CruiseControl.Core.ConsoleRunner.Run()
   at ThoughtWorks.CruiseControl.Console.ConsoleMain.Main(String[] args)
----------
</pre>
</blockquote>
<p>Even worse, the error message is presented in white text on a glaring red background, so as to be all but unreadable. Looking at it now, in retrospect (and black &#038; white), I can see clues that I missed the first time. Specifically, the string &#8220;push_include.&#8221;</p>
<p>Anyway, the problem turned out to be the way the Configuration Processor deals with XML includes. It is <strong>not</strong> a C preprocessor &#8212; it includes subtrees, not text. </p>
<p>The answer turns out to be in the included file. References in the included file to the &#8220;cb:&#8221; XML namespace have to be accompanied in that file by some definition. Adding the same xmlns= statement does the trick:</p>
<blockquote><pre>

&lt;?xml version="1.0" encoding="UTF-8"?>
&lt;cb:define  <strong>xmlns:cb="urn:ccnet.config.builder"</strong>  name = "PROJECT"  >
  &lt;!-- blah blah -->
&lt;/cb:define>
</pre>
</blockquote>
<p>Problem solved. Now let the rubber-stamping begin!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2008/06/gotcha-xml-include-processing-in-cruisecontrolnet/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[wiki &#124; reviews:byname:guiffy_suremerge:20060706]</title>
		<link>http://www.longacre-scm.com/blog/index.php/2008/04/reviews-byname-guiffy_suremerge-20060706</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2008/04/reviews-byname-guiffy_suremerge-20060706#comments</comments>
		<pubDate>Sat, 19 Apr 2008 01:15:50 +0000</pubDate>
		<dc:creator>Austin Hastings</dc:creator>
				<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/index.php/2008/04/[[reviews:byname:guiffy_suremerge:20060706]]</guid>
		<description><![CDATA[

Table of Contents



Review of Guiffy SureMerge

Editorial Notes
Product Explanation
Two-way Comparison
Three-way Comparison
Merging
Directory Compare
Features

Jiff command-line utility
SureMerge command-line utility
HTML comparison reports
International Character Encodings
Java API


Support
Accuracy
Performance
Ease of Use
Effectiveness
Cost
Conclusion






Review of Guiffy SureMerge




Editorial Notes



 Date: March 2006
 Product: Guiffy SureMerge 7.2 “Dogwood”
 Vendor: Guiffy Software (http://www.guiffy.com)
 Reviewer: Austin Hastings




Bill Ritcher, coder and CEO of Guiffy, is aware of the review. He became aware [...]]]></description>
			<content:encoded><![CDATA[<div class="dokuwiki">
<div class="toc">
<div class="tocheader toctoggle" id="toc__header">Table of Contents</div>
<div id="toc__inside">

<ul class="toc">
<li class="level1"><div class="li"><span class="li"><a href="#review_of_guiffy_suremerge" class="toc">Review of Guiffy SureMerge</a></span></div>
<ul class="toc">
<li class="level2"><div class="li"><span class="li"><a href="#editorial_notes" class="toc">Editorial Notes</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#product_explanation" class="toc">Product Explanation</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#two-way_comparison" class="toc">Two-way Comparison</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#three-way_comparison" class="toc">Three-way Comparison</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#merging" class="toc">Merging</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#directory_compare" class="toc">Directory Compare</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#features" class="toc">Features</a></span></div>
<ul class="toc">
<li class="level3"><div class="li"><span class="li"><a href="#jiff_command-line_utility" class="toc">Jiff command-line utility</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#suremerge_command-line_utility" class="toc">SureMerge command-line utility</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#html_comparison_reports" class="toc">HTML comparison reports</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#international_character_encodings" class="toc">International Character Encodings</a></span></div></li>
<li class="level3"><div class="li"><span class="li"><a href="#java_api" class="toc">Java API</a></span></div></li>
</ul>
</li>
<li class="level2"><div class="li"><span class="li"><a href="#support" class="toc">Support</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#accuracy" class="toc">Accuracy</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#performance" class="toc">Performance</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#ease_of_use" class="toc">Ease of Use</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#effectiveness" class="toc">Effectiveness</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#cost" class="toc">Cost</a></span></div></li>
<li class="level2"><div class="li"><span class="li"><a href="#conclusion" class="toc">Conclusion</a></span></div></li></ul>
</li></ul>
</div>
</div>



<h1><a name="review_of_guiffy_suremerge" id="review_of_guiffy_suremerge">Review of Guiffy SureMerge</a></h1>
<div class="level1">

</div>
<!-- SECTION "Review of Guiffy SureMerge" [1-42] -->
<h2><a name="editorial_notes" id="editorial_notes">Editorial Notes</a></h2>
<div class="level2">

<p>
 <strong>Date: March 2006</strong><br/>
 <strong>Product: Guiffy SureMerge 7.2 “Dogwood”</strong><br/>
 <strong>Vendor: Guiffy Software (<a href="http://www.guiffy.com" class="urlextern" title="http://www.guiffy.com"  rel="nofollow">http://www.guiffy.com</a>)</strong><br/>
 <strong>Reviewer: Austin Hastings</strong><br/>

</p>

<p>
Bill Ritcher, coder and CEO of Guiffy, is aware of the review. He became aware  about half-way through when I was contacting him for help with various issues.  After the review was published, Guiffy began providing a link to the review  from their product web site.
</p>

</div>
<!-- SECTION "Editorial Notes" [43-498] -->
<h2><a name="product_explanation" id="product_explanation">Product Explanation</a></h2>
<div class="level2">

<p>
 Guiffy (pronounced “Goofy” according to owner/developer Bill Ritcher) SureMerge is a java-based, platform-neutral visual compare and merge utility for software and content developers. It is compatible with Java 5 (as well as earlier releases) and is available for OpenVMS and <acronym title="Operating System">OS</acronym>/2, as well as less-popular operating systems like Linux, Windows, and Mac <acronym title="Operating System">OS</acronym>/X. 
</p>

<p>
Most of the time, comparison and merge tools are listed as being tools for developers. In reality, though, this is not true. Comparison and merge tools are tools for leads, build managers, and SCMs—the folks who get called when something goes wrong. But we all wish that developers would fix the problems they introduce, so most companies distribute these tools to everyone. SureMerge supports developers with “the usual” range of compare and merge features, discussed below. In addition, it contains features that will be near and dear to the heart of build managers, team leads, and change managers everywhere—tools that make it easy to deal with whole development teams and whole trees of files.
</p>

<p>
The product comes with a collection of executables including stand-alone compare and merge command line tools. One of those programs is a command-line merge utility called <code>suremerge.</code> The <acronym title="Graphical User Interface">GUI</acronym> version is named <code>guiffy.</code> I will refer to them by name when it is relevant. Otherwise I will call the whole software bundle SureMerge, and the company Guiffy.
</p>

</div>
<!-- SECTION "Product Explanation" [499-1963] -->
<h2><a name="two-way_comparison" id="two-way_comparison">Two-way Comparison</a></h2>
<div class="level2">

<p>
 Two-way comparison of files is what comes to mind immediately when you think about comparisons: put two files next to each other and see where the changes are. Most readers will be familiar with the <code>diff</code> and <code>sdiff</code> commands for comparing files and displaying the results. A graphical rendition is much clearer and easier to understand.
</p>

<p>
When you evaluate SureMerge, the Guiffy web site (<a href="http://www.guiffy.com" class="urlextern" title="http://www.guiffy.com"  rel="nofollow">http://www.guiffy.com</a>) includes a white paper with a series of test cases. The white paper highlights different kinds of changes and how they are handled by merge &amp; compare tools, using Guiffy source code in the examples. This screen shot was taken using one of the included test cases. (No, I don&#039;t have access to Guiffy&#039;s source code.)
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/1-twowaycompare.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:1-twowaycompare.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/1-twowaycompare.png?w=400&amp;h=&amp;cache=cache" class="media" title="Screenshot of 2-way Compare" alt="Screenshot of 2-way Compare" width="400" /></a>
</p>

<p>
A very nice feature of the <code>guiffy</code> <acronym title="Graphical User Interface">GUI</acronym> <a href="#fn__1" name="fnt__1" id="fnt__1" class="fn_top">1)</a> is character-by-character highlighting of differences. If you are using a language that tends to have &#039;dense&#039; statements, this can be a life-saver, highlighting where a full stop (&#039;.&#039;) changed to a comma or where a single quote became a back tick. Be careful with character-by-character differencing: like all compare algorithms, it is prone to look for similarities that may not be there:
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/2-characterbycharacter.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:2-characterbycharacter.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/2-characterbycharacter.png?w=250&amp;h=&amp;cache=cache" class="media" title="Character-by-character highlighting of changes" alt="Character-by-character highlighting of changes" width="250" /></a>
</p>

<p>
The example shows two random DNA sequences. I used perl to randomly emit the four letters A, C, G, T. As you can see, <code>guiffy</code> was willing to “walk a mile” to show me the exact changes, when in fact I just made up two totally different sequences. <a href="#fn__2" name="fnt__2" id="fnt__2" class="fn_top">2)</a>
</p>

<p>
That was a dumb example made to demonstrate a point: <code>guiffy</code> offers a configuration setting that lets you determine how much change is “too much”. A better example is refactoring code. Consider this change, taken from Michael Schwern&#039;s excellent <acronym title="Practical Extraction and Report Language">Perl</acronym> <a href="http://www.perl.com/pub/a/2003/10/09/refactoring.html" class="urlextern" title="http://www.perl.com/pub/a/2003/10/09/refactoring.html"  rel="nofollow">refactoring tutorial:</a>
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/3-inlinetoohigh.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:3-inlinetoohigh.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/3-inlinetoohigh.png?w=400&amp;h=&amp;cache=cache" class="media" title="" alt="" width="400" /></a>
</p>

<p>
This example also has character highlighting turned on, so what happened? The answer lies in a configuration dialog, Options&gt;Show:
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/4-showinlinediffs.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:4-showinlinediffs.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/4-showinlinediffs.png?w=&amp;h=&amp;cache=cache" class="media" title="" alt="" /></a>
</p>

<p>
You can choose to show difference that are up to 100% of the line, which is what I did for the DNA sequence above. The default is 50%, as shown, but when you are merging source code the devil is in the details. In the example above, line 9 changed by more than 50% because of the long variable names. As a result, it was “too much change” to highlight. With a single buttonpress, a mouseclick, and &#039;Enter&#039; I have a different picture:
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/5-inlinediffsokay.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:5-inlinediffsokay.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/5-inlinediffsokay.png?w=400&amp;h=&amp;cache=cache" class="media" title="" alt="" width="400" /></a>
</p>

<p>
This is how the same code looks at a 75% change cutoff. Suddenly it&#039;s clear that the perl variables have been pulled out of the <acronym title="Structured Query Language">SQL</acronym> statement and replaced by bind variables. And the variables are now passed to <code>$sth&rarr;execute</code> as method args. This is great stuff! Just to be a little nit-picky, I&#039;m going to suggest that Guiffy make the Show Options page into a toolbar control or some kind of dockable: when you are looking at differences in code it can be important to quickly toggle back and forth.
</p>

</div>
<!-- SECTION "Two-way Comparison" [1964-5416] -->
<h2><a name="three-way_comparison" id="three-way_comparison">Three-way Comparison</a></h2>
<div class="level2">

<p>
 Beyond two-way comparison lies three-way. (Relax: three is the limit!) With three-way comparison, and three-way merging, you are comparing a single common ancestor with two different changed files. This is the tool to use when two developers have made different changes to the same file, and you&#039;re stuck merging them together. Sound familiar?
</p>

<p>
In the illustration (below) you can see how guiffy presents two changes that conflict with each other. In this case, different developers have allocated the constant value 7 to different purposes: the names CWP and ENA. 
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/6-threewaycompare.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:6-threewaycompare.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/6-threewaycompare.png?w=400&amp;h=&amp;cache=cache" class="media" title="Screenshot of 3-way compare" alt="Screenshot of 3-way compare" width="400" /></a>
</p>

<p>
To merge the changes it isn&#039;t sufficient to copy both new lines into the resulting file. Instead, one line will have to be manually edited to convert its value from 7 to 8. The tool compares both changed files against the parent, and then compares the change sets. For each part of the file, the possibilities are: 
</p>
<table class="inline">
	<tr>
		<th class="centeralign">  Parent vs. Me  </th><th class="centeralign">  Other vs. Me  </th><th class="centeralign">  Other vs. Parent  </th><th> Interpretation </th>
	</tr>
	<tr>
		<td class="centeralign">  Same           </td><td class="centeralign">  Same          </td><td class="centeralign">  Same              </td><td> Unchanged in both branches. </td>
	</tr>
	<tr>
		<td class="centeralign">  Same           </td><td class="centeralign">  Different     </td><td class="centeralign">  Different         </td><td> Changed only in <em>other</em> branch. Take that change. </td>
	</tr>
	<tr>
		<td class="centeralign">  Different      </td><td class="centeralign">  Same          </td><td class="centeralign">  Different         </td><td> Changed identically in both branches. Take this change. </td>
	</tr>
	<tr>
		<td class="centeralign">  Different      </td><td class="centeralign">  Different     </td><td class="centeralign">  Same              </td><td> Changed only in <em>this</em> branch. Take this change. </td>
	</tr>
	<tr>
		<td class="centeralign">  Different      </td><td class="centeralign">  Different     </td><td class="centeralign">  Different         </td><td> Changed in <em>both</em> branches. Merge these changes by hand. </td>
	</tr>
</table>

<p>
 Nearly all merge programs use this kind of logic to determine how to respond to changes. There are a couple of potential problems, however. First comes finding the smallest region in the file that constitutes a single change. We&#039;ve all seen cases where a compare program finds a single closing curly brace that is “equal” to similar text in the other file and so declares that point the end of one change and the start of another. Finding the boundaries of a “single” change can be challenging. 
</p>

<p>
Some cases aren&#039;t so clear-cut. For example, what if two developers insert code in the same location in the file, as illustrated above. You or I can tell it&#039;s a conflict (two allocations of the number 7), but some tools won&#039;t, since the two changes can be automatically merged by inserting both! The white paper I mentioned above has 5 simple scenarios for compare &amp; merge. I was surprised to learn that every other tool in the market gets at least one of those scenarios wrong! The cases are simple, and source code is provided: try them yourself.
</p>

<p>
Knowing what to ignore can be an issue, too. If the files in question have been translated from one operating system to another, or edited with different tools, things like white space and line terminators may be different. Having the ability to ignore these trivial changes is important. SureMerge has the ability, in spades. You can ignore whitespace at the beginning, at the end, or everywhere in the file. You can ignore changes matching a regex, or changes in a certain range of columns. The only thing SureMerge won&#039;t ignore for you is phone calls from your boss.
</p>

<p>
Finally, there is the risk of an identical-but-wrong change. In this scenario, possibly caused by out-of-band sharing, one part of a change might be present in both child versions but be fatal to one of the changes. Typically, you&#039;ll see this when the two developers have discussed the changes but haven&#039;t explicitly thought about each change. There&#039;s no way to catch these mechanically—your best bet is good unit testing.
</p>

<p>
<code>guiffy</code> does offer a nice feature that comes close to being psychic when these changes happen within a few lines: it reports an &#039;attention&#039; on code changes that are not in conflict, but are close together. If two developers made changes just a few lines apart, the software knows that it could merge them automatically, but is smart enough to say, “Hey! Somebody should check this.” Just like the Federal Aviation Administration, it considers even a near miss to be something important. Very nice.
</p>

</div>
<!-- SECTION "Three-way Comparison" [5417-9605] -->
<h2><a name="merging" id="merging">Merging</a></h2>
<div class="level2">

<p>
 As you might expect from a product named SureMerge, merging is a strong feature. There are a lot of different ways you can “merge” code via the <acronym title="Graphical User Interface">GUI</acronym>: 
</p>
<ol>
<li class="level1"><div class="li"> Just start typing. If you are using <code>guiffy</code> in merge mode, type (or copy &amp; paste) what you want into the “merged” window—<code>guiffy</code> won&#039;t let you change either of the original inputs. If you are using compare mode, you can edit in either file just like a text editor.</div>
</li>
<li class="level1"><div class="li"> Use Two-way merging. If all you have is two different files, you can choose between alternatives: <a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/7-twowaymerge.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:7-twowaymerge.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/7-twowaymerge.png?w=400&amp;h=&amp;cache=cache" class="mediacenter" title="" alt="" width="400" /></a> Of course, you can also just type: sometimes the merge process isn&#039;t about selecting between two alternatives, but combining them. If you need to type, or copy and paste, to get the results you want, just point and click.</div>
</li>
<li class="level1"><div class="li"> Use Three-way merging. As mentioned above, <code>guiffy</code> is excellent at determining just exactly which changes can be merged automatically, and which changes really do require the attention of a human. Of the five scenarios described above, only 1 requires a human to help with the work. In my experience, this reflects reality fairly well: I&#039;d guess that the number of &#039;real world&#039; merge steps requiring human attention is somewhere between 5 and 30 percent, depending on your code.</div>
</li>
</ol>

<p>
 Regardless, <code>guiffy</code> gives you the same basic interface (the &#039;parent&#039; is used to compute the changes, but isn&#039;t shown) as with two-way merging, and lets you do the same things: select code from either source as a starting point, then edit the code to the result you want.
</p>

</div>
<!-- SECTION "Merging" [9606-11211] -->
<h2><a name="directory_compare" id="directory_compare">Directory Compare</a></h2>
<div class="level2">

<p>
 Another nice feature of <code>guiffy</code> is the directory tree compare <acronym title="Graphical User Interface">GUI</acronym>. This uses the same color scheme as the file compare to show you files that have been added, deleted, or changed between two directory trees:
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/8-directorycompare.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:8-directorycompare.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/8-directorycompare.png?w=400&amp;h=&amp;cache=cache" class="media" title="Screenshot of directory compare" alt="Screenshot of directory compare" width="400" /></a>
</p>

<p>
This is a great place to start when you are trying to understand what has happened to your code. Seeing the higher-level view of what has been changed lets you organize your approach to understanding and/or merging the changes. The interface is visually clean and attractive, as well as intuitive. The obvious tools to fix to directory tree issues—copying, renaming, and and deleting files—are supported in the tree view. I do have a few gripes about this interface, however:  
</p>
<ul>
<li class="level1"><div class="li"> First, there is no indication at the directory level that children have changed. For a deep source tree this may make it harder to grasp the whole impact of a change. Mitigating this is the fact that the <acronym title="Graphical User Interface">GUI</acronym> takes you right to the first change, and you can use the next/previous change buttons to navigate.</div>
</li>
<li class="level1"><div class="li"> Second, <code>guiffy</code> doesn&#039;t do the “obvious” thing when dealing with trees. If I invoke <code>guiffy</code> with three or four directory names, as I would do for merging files, the tool doesn&#039;t automatically create the new “merged” directory tree. Neither does it correctly populate the “parent” field when I try to SureMerge a changed file. </div>
</li>
</ul>

<p>
 The former is evidence of how addictive and intuitive the rest of the product is: <em>of course</em> it will work this way—just bring up the directories and start resolving conflicts! It actually took me a while to grasp that I was wrong. The latter behavior—incorrectly populating the parent field—seems to be just a bug. <code>guiffy</code> remembers the last value I used, instead of populating it from the command line.
</p>
<ul>
<li class="level1"><div class="li"> Third, there is no good way to move files from one directory to another: the &#039;move&#039; operation is  an extended version of &#039;rename&#039;. I suspect this is a drag &amp; drop problem—there are some other issues with drag &amp; drop discussed later. For Java development in particular, this may be a problem when refactoring. (Or not: much refactoring will involve opening the &#039;rename&#039; dialog anyway—maybe combining move with rename won&#039;t be a problem.)</div>
</li>
</ul>

</div>
<!-- SECTION "Directory Compare" [11212-13555] -->
<h2><a name="features" id="features">Features</a></h2>
<div class="level2">

<p>
 In addition to fast, accurate 2- and 3-way merging, SureMerge includes
</p>
<ul>
<li class="level1"><div class="li"> jiff – a command-line compare utility</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> suremerge – a command-line merge utility</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> Recursive comparison of directory hierarchies in guiffy and jiff</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> <acronym title="HyperText Markup Language">HTML</acronym> comparison reports in guiffy</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> Support for international character encodings</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> A Java <acronym title="Application Programming Interface">API</acronym> for integrating SureMerge functionality into your own programs.</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> Really responsive support</div>
</li>
</ul>

<p>
There&#039;s a wealth of other features listed at <a href="http://www.guiffy.com" class="urlextern" title="http://www.guiffy.com"  rel="nofollow">http://www.guiffy.com</a> but these stand out as being important for automation and build/team management.
</p>

</div>
<!-- SECTION "Features" [13556-14162] -->
<h3><a name="jiff_command-line_utility" id="jiff_command-line_utility">Jiff command-line utility</a></h3>
<div class="level3">

<p>
 <code>jiff</code> is not <code>diff.</code> Instead, it is a command-line tool for showing differences. It does not use the diff algorithms (a feature: Guiffy claims their algorithms are better), it does not produce the eleventy-four different specialized formats for feeding to other tools. It does not use the same command-line switches: another feature, since <code>diff</code> does not have a switch for specifying the character encoding of the input files, while <code>jiff</code> does.
</p>

<p>
What <code>jiff</code> does is produce a very readable, very comprehensible text version of the results shown by the guiffy <acronym title="Graphical User Interface">GUI</acronym>. Here&#039;s an example:
</p>
<pre class="code">C:\\temp\\Guiffy review\\perl&gt;jiff db2.pl db4.pl
  1  1 open (INPUT, &quot;&lt; $filepageid&quot;) || &amp;file_open_error(&quot;$filepageid&quot;);
  2  2
  3  3 while ($riga=&lt;INPUT&gt;){
  4  4     $nump++;
  5  5     chop($riga);
  6  6     $pagina[$nump] = $riga;
  7  7
  8   &lt;    $sth= $dbh-&gt;prepare(&quot;SELECT count(*) FROM lognew WHERE
  9   &lt;                         pageid=&#039;$pagina[$nump]&#039; and data&gt;=&#039;$startdate&#039;&quot;);
 10   &lt;    $sth-&gt;execute;
 11   &lt;    $totalvisit[$nump] = $sth-&gt;fetchrow_array();
     8&gt;    my $totalvisit_sth = $dbh-&gt;prepare(&#039;SELECT count(*) FROM lognew WHERE
     9&gt;                                        pageid=? and data&gt;=?&#039;);
    10&gt;    $totalvisit_sth-&gt;execute($pagina[$nump], $startdate);
    11&gt;    $totalvisit[$nump] = $totalvisit_sth-&gt;fetchrow_array();
 12 12</pre>

<p>
 <code>jiff</code> offers a directory-compare behavior similar to <code>guiffy</code>, but I had a few problems with this. 
</p>
<ul>
<li class="level1"><div class="li"> First, I expected <code>jiff -r</code> to behave just like <code>diff -r</code>: that was arguably my problem. Instead, <code>jiff -r</code> does just a tree comparison: it does not show file differences as it goes.</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> Second, getting <code>jiff -r</code> to show files that have changed between the two trees requires specifying the <code>-bxt</code> (Verify files match) option: this one even stumped the author for a while. <a href="#fn__3" name="fnt__3" id="fnt__3" class="fn_top">3)</a></div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> Third, the option syntax is awkward: <code>-diffs</code> shows “only the differences” for files, but <code>-nomats</code> shows “no matching files” for folder comparisons.</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> Finally, the folder compare wants to show the names of folders it has checked, even if there were no differences: <code>-nomats</code> didn&#039;t prevent it from burying my file changes amid a maze of directory names, all alike:</div>
</li>
</ul>
<pre class="code">    &lt;DIR&gt;     10-Apr-2006 22:48:55 libs
    &lt;DIR&gt;     10-Apr-2006 22:48:45 \\libs\\action
    &lt;DIR&gt;     10-Apr-2006 22:48:45 \\libs\\action\\controller
    &lt;DIR&gt;     10-Apr-2006 22:48:45 \\libs\\action\\controller\\http
    &lt;DIR&gt;     10-Apr-2006 22:48:45 \\libs\\action\\controller\\session
    &lt;DIR&gt;     10-Apr-2006 22:48:45 \\libs\\action\\controller\\templates
    &lt;DIR&gt;     10-Apr-2006 22:48:45 \\libs\\action\\view
    &lt;DIR&gt;     10-Apr-2006 22:48:46 \\libs\\active
    &lt;DIR&gt;     10-Apr-2006 22:50:47 \\libs\\active\\record
&lt;       4,284 10-Apr-2006 22:55:50 \\libs\\active\\record\\Field.php
&lt;          13 10-Apr-2006 22:50:47 \\libs\\active\\record\\NewFile.php
&gt;       4,288 10-Apr-2006 22:56:24 \\libs\\active\\record\\Field.php
    &lt;DIR&gt;     10-Apr-2006 22:48:46 \\libs\\active\\support
    &lt;DIR&gt;     10-Apr-2006 22:48:46 \\libs\\configurator
    &lt;DIR&gt;     10-Apr-2006 22:48:46 \\libs\\context
    &lt;DIR&gt;     10-Apr-2006 22:48:53 \\libs\\creole
    &lt;DIR&gt;     10-Apr-2006 22:48:48 \\libs\\creole\\common
    &lt;DIR&gt;     10-Apr-2006 22:48:48 \\libs\\creole\\contrib
    &lt;DIR&gt;     10-Apr-2006 22:48:53 \\libs\\creole\\drivers
    &lt;DIR&gt;     10-Apr-2006 22:48:49 \\libs\\creole\\drivers\\mssql
    &lt;DIR&gt;     10-Apr-2006 22:48:49 \\libs\\creole\\drivers\\mssql\\metadata
    &lt;DIR&gt;     10-Apr-2006 22:48:50 \\libs\\creole\\drivers\\mysql
    &lt;DIR&gt;     10-Apr-2006 22:48:50 \\libs\\creole\\drivers\\mysql\\metadata
    &lt;DIR&gt;     10-Apr-2006 22:48:51 \\libs\\creole\\drivers\\mysqli</pre>

</div>
<!-- SECTION "Jiff command-line utility" [14163-18092] -->
<h3><a name="suremerge_command-line_utility" id="suremerge_command-line_utility">SureMerge command-line utility</a></h3>
<div class="level3">

<p>
 Where <code>jiff</code> would accept a relative path on the command line, like <code>jiff  med2\\libs\\active\\record\\field.php  med3\\libs\\active\\record\\field.php</code> <code>suremerge</code> would not. Needless to say, <code>suremerge</code> and I did not get off to a great start. 
</p>

<p>
In addition, it has problems parsing directory names that include spaces on Windows. When I specified a directory with a leading quote, as “C:\\MyDocuments\\Sources\\Php Data Layer”\\med2\\&hellip; all was well. If I tried to use quotes inside the directory, as C:\\MyDocuments\\Sources\\“Php Data Layer”\\med2\\&hellip; then I got a usage statement, and eventually a sore forehead from banging it against my desk. This is documented in the help text, but it&#039;s just a little bit different from common Windows behavior. 
</p>

<p>
Apparently, <code>suremerge</code> makes no use whatsoever of the current directory. It does not resolve relative paths against it, and it will not use it to resolve its output file, either. Once you overcome these challenges, though, <code>suremerge</code> does just exactly what you expected it would do: it performs the same merges from the command line that <code>guiffy</code> does from the <acronym title="Graphical User Interface">GUI</acronym>. The remaining problem, of course, is when lines conflict with each other. Anyone who has used <acronym title="Concurrent Versions System">CVS</acronym> will be familiar with the result: 
</p>
<pre class="code">&lt;&lt;&lt;&lt;&lt;&lt;&lt; C:\\mydocuments\\Sources\\php data layer\\med2\\libs\\active\\record\\Field.php
class Field extends Object implements Persistable {
=======
class Field extends Object 
	implements Persistant 
{
&gt;&gt;&gt;&gt;&gt;&gt;&gt; c:\\mydocuments\\Sources\\php data layer\\med3\\libs\\active\\record\\Field.php</pre>

<p>
 Because of Guiffy&#039;s improved algorithms, <code>suremerge</code> will have fewer of these conflict spots than other tools. And once you get the command line quirks figured out, it&#039;s easy to script around them. But it&#039;s still awkward: effective, but awkward.
</p>

</div>
<!-- SECTION "SureMerge command-line utility" [18093-19970] -->
<h3><a name="html_comparison_reports" id="html_comparison_reports">HTML comparison reports</a></h3>
<div class="level3">

<p>
 The <code>guiffy</code> tree comparison feature is a very nice way to get a sense of what has changed in a project. Automatically generating an <acronym title="HyperText Markup Language">HTML</acronym> document that looks like the <acronym title="Graphical User Interface">GUI</acronym> would be really nice. Putting the changes out where everyone can see them provides the kind of easy visibility that is important when project members aren&#039;t working tightly together. 
</p>

<p>
<code>guiffy</code>&#039;s <acronym title="HyperText Markup Language">HTML</acronym> reports don&#039;t look exactly like their <acronym title="Graphical User Interface">GUI</acronym> counterparts, but they sure are close:
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/9-htmlreport72.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:9-htmlreport72.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/9-htmlreport72.png?w=400&amp;h=&amp;cache=cache" class="media" title="" alt="" width="400" /></a>
</p>

<p>
The changes are highlighted using the same colors as the <acronym title="Graphical User Interface">GUI</acronym>, including the character-by-character highlighting. Obviously you can&#039;t change the highlight options in mid-stream, as you can with the <acronym title="Graphical User Interface">GUI</acronym>.
</p>

<p>
The directory comparison is a little less close to the <acronym title="Graphical User Interface">GUI</acronym>. It doesn&#039;t show the folder tree view. Instead, it looks more like the output of <code>jiff -r.</code> Regardless, it gets the information across:
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/10-htmlreport73.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:10-htmlreport73.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/10-htmlreport73.png?w=400&amp;h=&amp;cache=cache" class="media" title="" alt="" width="400" /></a>
</p>

<p>
The <acronym title="HyperText Markup Language">HTML</acronym> reporting capability seems new, according to the release history, and I found some rough spots that support this:
</p>
<ul>
<li class="level1"><div class="li"> Did you notice that the header says the folder compare report was produced by version 7.3—yet this is supposed to be a review of version 7.2? Well, I&#039;ve got a beta! I found a bug in the <acronym title="HyperText Markup Language">HTML</acronym> reporting: <code>guiffy</code> hangs when asked to generate folder reports in version 7.2. So I&#039;m looking at an early image of the next version. (I didn&#039;t install the new .jar until time to come back and finish this section. Everything else for this review was generated on 7.2.)</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> I also found a problem with long lines. In the image below you can tell that a character has changed in the left file (because of the red color) but you can&#039;t see what it is:</div>
</li>
</ul>

<p>
 <a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/11-htmlreportlonglineproblemff.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:11-htmlreportlonglineproblemff.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/11-htmlreportlonglineproblemff.png?w=400&amp;h=&amp;cache=cache" class="media" title="" alt="" width="400" /></a>
</p>

<p>
This is a Firefox problem, though, not a Guiffy problem. The same page looks fine in Internet Explorer 6.0:
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/12-htmlreportlonglineproblemie.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:12-htmlreportlonglineproblemie.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/12-htmlreportlonglineproblemie.png?w=400&amp;h=&amp;cache=cache" class="media" title="" alt="" width="400" /></a>
</p>

<p>
I had a look at the generated <acronym title="HyperText Markup Language">HTML</acronym>, and it&#039;s <em>clean.</em> I think this one is a Firefox (actually, Gecko rendering engine) error. 
</p>
<ul>
<li class="level1"><div class="li"> Finally, errors like invalid filenames (or missing files, if you prefer) don&#039;t return a status code, they display a dialog box. This is definitely not good for a scripted solution.</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> This is a feature request, but I think it would make sense for the <acronym title="HyperText Markup Language">HTML</acronym> report generator to produce a whole web of linked comparison reports: specify a switch, and get a whole series of output files, hyperlinked together, showing all the changed files.</div>
</li>
</ul>

<p>
  The format of the generated <acronym title="HyperText Markup Language">HTML</acronym> is very clean, and uses <acronym title="Cascading Style Sheets">CSS</acronym> tags for displaying changed entries. I think that a good perl coder could probably get the linkages going in a day or so. But it would be better if he didn&#039;t have to.
</p>

</div>
<!-- SECTION "HTML comparison reports" [19971-22827] -->
<h3><a name="international_character_encodings" id="international_character_encodings">International Character Encodings</a></h3>
<div class="level3">

<p>
 Consider this image of a <code>guiffy</code> compare of two versions of a file
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/13-differentencodings.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:13-differentencodings.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/13-differentencodings.png?w=400&amp;h=&amp;cache=cache" class="media" title="" alt="" width="400" /></a>
</p>

<p>
What&#039;s interesting about this result is the nature of the inputs: one of these files is encoded as a plain old <acronym title="American Standard Code for Information Interchange">ASCII</acronym> text file (technically, Windows codepage 1252) while the other is UTF16. Here&#039;s a different way of looking at them: 
</p>
<pre class="code">C:\\MyDocuments\\Sources\\Php Data Layer&gt;sed -ne 41p field.uni.txt|od -t x1z
0000000 00 63 00 6c 00 61 00 73 00 73 00 20 00 46 00 69  &gt;.c.l.a.s.s. .F.i&lt;
0000020 00 65 00 6c 00 64 00 20 00 65 00 78 00 74 00 65  &gt;.e.l.d. .e.x.t.e&lt;
0000040 00 6e 00 64 00 73 00 20 00 4f 00 62 00 6a 00 65  &gt;.n.d.s. .O.b.j.e&lt;
0000060 00 63 00 74 00 20 00 69 00 6d 00 70 00 6c 00 65  &gt;.c.t. .i.m.p.l.e&lt;
0000100 00 6d 00 65 00 6e 00 74 00 73 00 20 00 50 00 65  &gt;.m.e.n.t.s. .P.e&lt;
0000120 00 72 00 73 00 69 00 73 00 74 00 61 00 62 00 6c  &gt;.r.s.i.s.t.a.b.l&lt;
0000140 00 65 00 20 00 7b 00 0d 00 0a                    &gt;.e. .{....&lt;
0000152

C:\\MyDocuments\\Sources\\Php Data Layer&gt;sed -ne 41p field.php|od -t x1z
0000000 63 6c 61 73 73 20 46 69 65 6c 64 20 65 78 74 65  &gt;class Field exte&lt;
0000020 6e 64 73 20 42 61 73 65 20 69 6d 70 6c 65 6d 65  &gt;nds Base impleme&lt;
0000040 6e 74 73 20 50 65 72 73 69 73 74 61 62 6c 65 20  &gt;nts Persistable &lt;
0000060 7b 0a                                            &gt;{.&lt;
0000062</pre>

<p>
 As you can see, the two files are totally different internally: two different character sets, two different encodings. By telling <code>guiffy</code> about the file encodings of each file—via the command line or a dialog box—the compare engine knows to ignore the encoding and focus on what&#039;s important: the contents of the files! 
</p>

<p>
<code>guiffy</code> allows you to separately specify the encodings of the two primary files, the optional parent file for 3-way compare/merge operations, and the output file for merges. I recently worked at a client site where we would have been thankful just to be able to specify the input encodings: what a shame we didn&#039;t have <code>guiffy.</code>
</p>

<p>
One of the problems with multibyte characters is how to deal with “broken” or invalid character sequences. <code>guiffy</code> handles them fairly well: the invalid sequences are displayed as invalid characters. In this scenario you&#039;re probably going to need to hex dump the bytes to see exactly what went wrong (unless you just go fix the program that produced them).
</p>

<p>
The support for output encodings even extends to <acronym title="HyperText Markup Language">HTML</acronym> reports. Specifying the output encoding produces an <acronym title="HyperText Markup Language">HTML</acronym> document with the correct encoding and content-type metadata:
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/14-htmlheader.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:14-htmlheader.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/14-htmlheader.png?w=400&amp;h=&amp;cache=cache" class="media" title="" alt="" width="400" /></a>
</p>

<p>
Or, you could look at it this way (notice the byte-order-mark: U+FEFF): 
</p>
<pre class="code">C:\\MyDocuments\\Sources\\Php Data Layer&gt;head -1 diff.html | od -t x1z
0000000 fe ff 00 3c 00 21 00 44 00 4f 00 43 00 54 00 59  &gt;...&lt;.!.D.O.C.T.Y&lt;
0000020 00 50 00 45 00 20 00 48 00 54 00 4d 00 4c 00 20  &gt;.P.E. .H.T.M.L. &lt;
0000040 00 50 00 55 00 42 00 4c 00 49 00 43 00 20 00 22  &gt;.P.U.B.L.I.C. .&quot;&lt;
0000060 00 2d 00 2f 00 2f 00 57 00 33 00 43 00 2f 00 2f  &gt;.-././.W.3.C././&lt;
0000100 00 44 00 54 00 44 00 20 00 48 00 54 00 4d 00 4c  &gt;.D.T.D. .H.T.M.L&lt;
0000120 00 20 00 34 00 2e 00 30 00 31 00 20 00 54 00 72  &gt;. .4...0.1. .T.r&lt;
0000140 00 61 00 6e 00 73 00 69 00 74 00 69 00 6f 00 6e  &gt;.a.n.s.i.t.i.o.n&lt;
0000160 00 61 00 6c 00 2f 00 2f 00 45 00 4e 00 22 00 20  &gt;.a.l././.E.N.&quot;. &lt;
0000200 00 22 00 68 00 74 00 74 00 70 00 3a 00 2f 00 2f  &gt;.&quot;.h.t.t.p.:././&lt;
0000220 00 77 00 77 00 77 00 2e 00 77 00 33 00 2e 00 6f  &gt;.w.w.w...w.3...o&lt;
0000240 00 72 00 67 00 2f 00 54 00 52 00 2f 00 68 00 74  &gt;.r.g./.T.R./.h.t&lt;
0000260 00 6d 00 6c 00 34 00 2f 00 6c 00 6f 00 6f 00 73  &gt;.m.l.4./.l.o.o.s&lt;
0000300 00 65 00 2e 00 64 00 74 00 64 00 22 00 3e 00 0d  &gt;.e...d.t.d.&quot;.&gt;..&lt;
0000320 00 0a   </pre>

<p>
 Looking at the release history of the product, the release 7.x series seems to have had a strong focus on support for international encodings. It sure looks like they did it right. On a side note, remember this illustration from above?
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/2-characterbycharacter.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:2-characterbycharacter.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/2-characterbycharacter.png?w=&amp;h=&amp;cache=cache" class="media" title="" alt="" /></a>
</p>

<p>
I cheated a little bit: those are actually Unicode “fullwidth” characters used when typesetting mixed Latin and CJK text. This has been an “internationalized” review from the very start!
</p>

</div>
<!-- SECTION "International Character Encodings" [22828-27201] -->
<h3><a name="java_api" id="java_api">Java API</a></h3>
<div class="level3">

<p>
 I didn&#039;t explore the Java <acronym title="Application Programming Interface">API</acronym> for this review. I can document that it exists, and that it&#039;s very complete. It&#039;s called <code>guiffy.inside,</code> and it includes all the functions of all of the different flavors of the product, both <acronym title="Graphical User Interface">GUI</acronym> and command-line. It also includes a “hook” mechanism for modifying the behavior of the existing application.
</p>

<p>
On the command-line side, there are <acronym title="Application Programming Interface">API</acronym> equivalents for the <code>jiff</code> and <code>suremerge</code> commands so that you can create a windowless compare/merge subsystem inside your own programs. Also, there&#039;s a separate <acronym title="Application Programming Interface">API</acronym> for the <acronym title="HyperText Markup Language">HTML</acronym> report generator.
</p>

<p>
There are two interfaces for <acronym title="Graphical User Interface">GUI</acronym> products. The first, called a Frame, essentially pops up the Guiffy application window, menus, dialog boxes, and all. The second, called a Panel, lets you put the Guiffy compare/merge screen inside your application&#039;s window. There&#039;s no menu, and no toolbars, in the Panel version: you get tight integration with your app, but you have to write the supporting code to pick up filenames and encodings and such. 
</p>

<p>
Finally, there&#039;s a hook mechanism so that you can detect the merge result on exit and trigger some behavior. It seems Guiffy is just about as easy as can be to integrate with another application, like a CM tool or a build script or a continuous integration driver. Because this is all in Java, you can build it into an applet running on a web page. Make it a signed applet and your users can do compare and merge operations against their desktop, and you won&#039;t even have to install the product on their machines. (You should probably call and ask about licensing, though.)
</p>

</div>
<!-- SECTION "Java API" [27202-28826] -->
<h2><a name="support" id="support">Support</a></h2>
<div class="level2">

<p>
 Guiffy support is just amazingly responsive!
</p>

<p>
I started this review by visiting the website (<a href="http://www.guiffy.com" class="urlextern" title="http://www.guiffy.com"  rel="nofollow">http://www.guiffy.com</a>) and downloading the demo version, along with the sample scenarios for compare &amp; merge. When I asked questions by e-mail, I was amazed to get responses at four o&#039;clock in the morning. I was happy to find they were knowledgeable technical answers from someone who could understand what tasks I wanted to do, and how they should work. I also got responses in the afternoon and evening. If anyone in Missouri ever sleeps, you couldn&#039;t prove it by me.
</p>

</div>
<!-- SECTION "Support" [28827-29412] -->
<h2><a name="accuracy" id="accuracy">Accuracy</a></h2>
<div class="level2">

<p>
 SureMerge offers two different modes for grouping changes together. You can choose to see more blocks of changed text, with small numbers of lines, or you can permit grouping of changes into a smaller number of individually bigger blocks. I was unable to detect a difference in the modestly sized files I used for testing purposes.
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/15-accuracy.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:15-accuracy.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/15-accuracy.png?w=400&amp;h=&amp;cache=cache" class="media" title="" alt="" width="400" /></a>
</p>

<p>
For my purposes, the accuracy of the tool is &#039;pinpoint.&#039; Changes are identified down to the individual characters that differ. It doesn&#039;t get any better than that.
</p>

</div>
<!-- SECTION "Accuracy" [29413-29990] -->
<h2><a name="performance" id="performance">Performance</a></h2>
<div class="level2">

<p>
 SureMerge is a set of Java applications with a shell or Windows executable front-end. I was a little nervous about this, after having a bad time starting up Eclipse. SureMerge is definitely not Eclipse: it starts up just fine. Likewise, doing compares is quick even for large(-ish) files. I used some international dictionary files to test both large file operations and international character set support. It takes Guiffy about 15 seconds to re-compare two versions of a 1.7MB Russian dictionary on my two-year-old laptop. Very nice!
</p>

<p>
For this test, I wrote a perl script to randomly “mutate” about one percent of the lines: delete or move the line, or insert or transpose characters:
</p>

<p>
<a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/16-largefiles.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:16-largefiles.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/16-largefiles.png?w=400&amp;h=&amp;cache=cache" class="media" title="" alt="" width="400" /></a>
</p>

<p>
The help documentation includes notes for comparing large files when the files have large blocks of changes in them. The change is simply to let SureMerge allocate more memory to work in: everything else is taken care of. I guess that change is required if the files are more different than they are similar, because my files were way over the threshold for needing more memory, yet guiffy worked just fine out of the box.
</p>

</div>
<!-- SECTION "Performance" [29991-31191] -->
<h2><a name="ease_of_use" id="ease_of_use">Ease of Use</a></h2>
<div class="level2">

<p>
 SureMerge is a tool with some complex features. Overall, the interface is very smooth and self-explanatory. Most advanced operations are explained well by the surrounding menus and dialog box text, with no need to refer to the online help.
</p>

<p>
That said, I have some complaints. (I&#039;ll bet you didn&#039;t see that coming.) 
</p>
<ul>
<li class="level1"><div class="li"> First is support for drag &amp; drop. I&#039;m using a modern JRE (1.5), and yet the drag &amp; drop is all but unusable: the drop targets are the top and bottom <em>row of pixels</em> of the file name combo boxes on the file open dialog.</div>
</li>
</ul>

<p>
 As I understand it from talking to the author, this is a defect in the Java UI libraries. That doesn&#039;t excuse it at the product level: a one-pixel drop target is not a drop target. As clunky as it may be, Guiffy needs to make this work—either code their own <acronym title="Graphical User Interface">GUI</acronym> widgets (blech!) or add an ugly “Drop Here” box (blech!).  
</p>
<ul>
<li class="level1"><div class="li"> Second, integrating <code>guiffy</code> with Windows Explorer is documented in a Tech Note in the on-line help. I believe the installer should perform the simple steps automatically on installation.</div>
</li>
</ul>
<ul>
<li class="level1"><div class="li"> Finally, the dialog box for choosing character encodings needs work. Presently, the encodings are specified as text entry boxes: you type in the encodings. But since the list of supported encodings is known in advance, this should be a drop-down list or a combo list. It was frustrating to be told I needed an additional file:</div>
</li>
</ul>

<p>
 <a href="/wiki/lib/exe/detail.php/reviews/byname/guiffy_suremerge/17-encodingerror.png?id=reviews%3Abyname%3Aguiffy_suremerge%3A20060706&amp;cache=cache" class="media" title="reviews:byname:guiffy_suremerge:17-encodingerror.png"><img src="/wiki/lib/exe/fetch.php/reviews/byname/guiffy_suremerge/17-encodingerror.png?w=&amp;h=&amp;cache=cache" class="media" title="" alt="" /></a>
</p>

<p>
It was even more frustrating to realize that the encoding I wanted was supported, just spelled differently (&#039;koi8&#039;). I&#039;m sure that if you spend all day every day in a particular encoding you know how to spell it. But if you have to deal with different encodings on a regular basis, a pull-down list is your friend.
</p>

<p>
Overall, the product itself is very easy to use and install. But it could be better integrated with the desktop, and the user interface needs to be a little bit more helpful.
</p>

</div>
<!-- SECTION "Ease of Use" [31192-33164] -->
<h2><a name="effectiveness" id="effectiveness">Effectiveness</a></h2>
<div class="level2">

<p>
 SureMerge gets the job done. It gets the job done <em>well.</em> The tool is fast, it is accurate, and it is easy to use. Using the file-encoding feature lets you view changes at both the &#039;byte&#039; level and at the &#039;code point&#039; level. You can see that a character has changed, or you can switch views and see just exactly how the binary expression of that character has changed. For anyone dealing with i18n issues this is a godsend.
</p>

<p>
Included in the on-line help are instructions for integrating SureMerge with eight different CM tools. For PVCS, Guiffy even includes a specially built executable that replaces the <code>pvcsmerge</code> program for seamless integration. (Support for the other tools is probably just as seamless, but they offer configuration options to let you set the name of the merge tool so Guiffy doesn&#039;t have to ship eight different executables.)
</p>

<p>
The addition of batch reporting facilities and <acronym title="HyperText Markup Language">HTML</acronym> report generation makes SureMerge a valuable tool for a whole team, not just individual developers. Now change sets and impact statements can be automatically displayed from an intranet dashboard. Continuous integration and nightly build scripts can be extended to produce clear, detailed, attractive code change summaries. Sweet!
</p>

</div>
<!-- SECTION "Effectiveness" [33165-34431] -->
<h2><a name="cost" id="cost">Cost</a></h2>
<div class="level2">

<p>
 Single-user licenses for SureMerge are USD $75. Price breaks occur at 3 users (3/$150) and again at 36 users. SureMerge is a good value for managers or team leads looking to provide a standard tool to their developers.
</p>

</div>
<!-- SECTION "Cost" [34432-34669] -->
<h2><a name="conclusion" id="conclusion">Conclusion</a></h2>
<div class="level2">

<p>
 SureMerge is a solid, capable tool, as you would expect from a 7.2 release. It performs well and does a great job helping developers, build managers, team leads, and other players in the development cycle understand exactly what is going on with the code. The <acronym title="Graphical User Interface">GUI</acronym> itself is easy to use and is available in several languages. The tool is obviously growing, with international encoding support and <acronym title="HyperText Markup Language">HTML</acronym> report generations being the most recent major features added. Guiffy, the company, is personified by owner Bill Ritcher: quick to respond, helpful, and willing to work with you to help get over any problems. I like the tool, and you will, too.
</p>

</div>
<!-- SECTION "Conclusion" [34670-] --><div class="footnotes">
<div class="fn"><a href="#fnt__1" id="fn__1" name="fn__1" class="fn_bot">1)</a> 
Yes, that&#039;s “goofy gooey.” I&#039;m sorry, but it&#039;s Bill Ritcher&#039;s fault.</div>
<div class="fn"><a href="#fnt__2" id="fn__2" name="fn__2" class="fn_bot">2)</a> 
On the other hand, if you are a mad scientist trying to turn a monkey into an armadillo, this is the tool for you!</div>
<div class="fn"><a href="#fnt__3" id="fn__3" name="fn__3" class="fn_bot">3)</a> 
According to Bill Ritcher, this will be better documented in the 7.3 release.</div>
</div>

<!-- cachefile /home/ahasting/public_html/wiki/data/cache/c/c7e95af143d233250fe23fb58b0b6c60.xhtml used -->

</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2008/04/reviews-byname-guiffy_suremerge-20060706/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[wiki &#124; tools:byname:guiffy_suremerge]</title>
		<link>http://www.longacre-scm.com/blog/index.php/2008/04/tools-byname-guiffy_suremerge</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2008/04/tools-byname-guiffy_suremerge#comments</comments>
		<pubDate>Fri, 18 Apr 2008 13:31:03 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/index.php/2008/04/[[tools:byname:guiffy_suremerge]]</guid>
		<description><![CDATA[



Guiffy SureMerge



 SureMerge is a Java-based tool for both compare and merge operations. The tool is the primary focus of Guiffy Software. Austin Hastings wrote a review of the tool for the CM Crossroads web site. That review is available here, as well. 







]]></description>
			<content:encoded><![CDATA[<div class="dokuwiki">



<h1><a name="guiffy_suremerge" id="guiffy_suremerge">Guiffy SureMerge</a></h1>
<div class="level1">

<p>
 SureMerge is a Java-based tool for both <a href="/wiki/doku.php/tools/compare" class="wikilink1" title="tools:compare">compare</a> and <a href="/wiki/doku.php/tools/merge" class="wikilink2" title="tools:merge">merge</a> operations. The tool is the primary focus of <a href="http://www.guiffy.com" class="urlextern" title="http://www.guiffy.com"  rel="nofollow">Guiffy Software.</a> <a href="mailto:&#x41;&#x75;&#x73;&#x74;&#x69;&#x6e;&#x5f;&#x48;&#x61;&#x73;&#x74;&#x69;&#x6e;&#x67;&#x73;&#x40;&#x4c;&#x6f;&#x6e;&#x67;&#x61;&#x63;&#x72;&#x65;&#x2d;&#x73;&#x63;&#x6d;&#x2e;&#x63;&#x6f;&#x6d;" class="mail JSnocheck" title="&#x41;&#x75;&#x73;&#x74;&#x69;&#x6e;&#x5f;&#x48;&#x61;&#x73;&#x74;&#x69;&#x6e;&#x67;&#x73;&#x40;&#x4c;&#x6f;&#x6e;&#x67;&#x61;&#x63;&#x72;&#x65;&#x2d;&#x73;&#x63;&#x6d;&#x2e;&#x63;&#x6f;&#x6d;">Austin Hastings</a> wrote a <a href="http://www.cmcrossroads.com/content/view/6777/96/" class="urlextern" title="http://www.cmcrossroads.com/content/view/6777/96/"  rel="nofollow">review</a> of the tool for the CM Crossroads web site. That review is available <a href="/wiki/doku.php/reviews/byname/guiffy_suremerge/20060706" class="wikilink1" title="reviews:byname:guiffy_suremerge:20060706">here,</a> as well. 
</p>

</div>

<!-- cachefile /home/ahasting/public_html/wiki/data/cache/0/0b8a8a7261318ff16cab782f67d3c151.xhtml used -->

</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2008/04/tools-byname-guiffy_suremerge/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[wiki &#124; tools:compare]</title>
		<link>http://www.longacre-scm.com/blog/index.php/2008/04/tools-compare</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2008/04/tools-compare#comments</comments>
		<pubDate>Fri, 18 Apr 2008 12:50:09 +0000</pubDate>
		<dc:creator>Administrator</dc:creator>
				<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/index.php/2008/04/[[tools:compare]]</guid>
		<description><![CDATA[



Compare (diff) Tools



 diff is of course the archetype of this class of tools. There are various implementations of the Unix command line diff utility, but the GNU diffutils package is considered representative of all of these.    The tools are: 


 Beyond Compare

 diffutils

 Guiffy SureMerge








]]></description>
			<content:encoded><![CDATA[<div class="dokuwiki">



<h1><a name="compare_diff_tools" id="compare_diff_tools">Compare (diff) Tools</a></h1>
<div class="level1">

<p>
 <code>diff</code> is of course the archetype of this class of tools. There are various implementations of the Unix command line <code>diff</code> utility, but the GNU <code>diffutils</code> package is considered representative of all of these.    The tools are: 
</p>
<ul>
<li class="level1"><div class="li"> <a href="/wiki/doku.php/tools/byname/beyond_compare" class="wikilink2" title="tools:byname:beyond_compare">Beyond Compare</a></div>
</li>
<li class="level1"><div class="li"> <a href="/wiki/doku.php/tools/byname/diffutils" class="wikilink2" title="tools:byname:diffutils">diffutils</a></div>
</li>
<li class="level1"><div class="li"> <a href="/wiki/doku.php/tools/byname/guiffy_suremerge" class="wikilink1" title="tools:byname:guiffy_suremerge">Guiffy SureMerge</a></div>
</li>
</ul>

</div>

<!-- cachefile /home/ahasting/public_html/wiki/data/cache/d/d8e4aca065668e589654fe9246447394.xhtml used -->

</div>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2008/04/tools-compare/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How do I review a SCM tool?</title>
		<link>http://www.longacre-scm.com/blog/index.php/2008/03/how-do-i-review-a-scm-tool</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2008/03/how-do-i-review-a-scm-tool#comments</comments>
		<pubDate>Thu, 27 Mar 2008 06:10:38 +0000</pubDate>
		<dc:creator>Austin Hastings</dc:creator>
				<category><![CDATA[General CM]]></category>
		<category><![CDATA[Industry]]></category>
		<category><![CDATA[Theory]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/index.php/2008/03/how-do-i-review-a-scm-tool</guid>
		<description><![CDATA[A while back, I wrote a review of Guiffy SureMerge for CM Crossroads. I even wrote about the process, here.
I&#8217;d like to think that I&#8217;m the guy for writing SCM tool reviews. I&#8217;ve been a vendor rep, so I know where a whole bunch of the bodies are buried. I am independent, so I don&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>A while back, I wrote a review of Guiffy SureMerge for CM Crossroads. I even wrote about the process, <a href="http://www.longacre-scm.com/blog/index.php/2006/07/guiffy-suremerge-review">here.</a></p>
<p>I&#8217;d like to think that I&#8217;m <em>the </em>guy for writing SCM tool reviews. I&#8217;ve been a vendor rep, so I know where a whole bunch of the bodies are buried. I am independent, so I don&#8217;t owe anybody anything. I have done the developer job, and the CM guy job, and the admin job, so I know what those guys care about. But I&#8217;m scared.</p>
<p>The fact is that there are a <em>lot </em>of details in any SCM tool. I spent two weeks reviewing SureMerge, which when you come right down to it is a glorified version of <strong>diff,</strong> for pete&#8217;s sake. Most SCM tools have some kind of diff utility built in as an afterthought. If it takes two weeks to do the afterthought, how many months would it take to cover the check-in command? When I wrote the case study that discussed the development of Longacre Deployment Management, I mentioned that the first-cut questionnaire we used for culling vendors contained about <strong>three hundred </strong>questions. Guess how many paragraphs that would translate to in a review.</p>
<p>One thing that seems obvious is that different vendors are at different points on the spectrum of object-version versus change-set based development. Some of them allow, or require, you to select which model you want. A bunch of them want to provide those functions, but call them something different and pretend that nobody else has them. Another thing is that the vendors, and even their customers, are at different levels with respect to integrating change tracking tools with version control. And with integrating requirements tools. And with integrating build tools. And deployment tools.</p>
<p>I&#8217;d like to have a fair measure. Some common set of activities that I could do for each tool. A benchmark, if you will, that allows the reader to hold two reviews up side-by-side and see the strengths of one tool versus another. (Ditto, weaknesses.) But there is the real risk that what challenges one tool will be a built in subfeature in a second level menu of a more advanced or more integrated tool. For instance, CVS doesn&#8217;t have any kind of change request tool integrated. There are some hacks. There are some other &#8220;products&#8221; that integrate CVS. (cvstrac, for one.) What to do? Accurev doesn&#8217;t have a CR tool, but they integrate with just about everything. MKS offers a separate CR tool, and makes it trivial to do change-set based development. Rational sells it as an add-on.</p>
<p>The point is, a &#8220;standard review&#8221; has the real risk of not mapping well to the product features. My SureMerge review was built around exploring the product, and deciding which features were worth mentioning to the readers. Some of them made it, others didn&#8217;t. A &#8220;custom review&#8221; runs the risk of spending a lot of time talking about worthless features because that is what is interesting about the particular tool. (I&#8217;ll mention here that a nice lady from PlasticSCM asked me to write a review of their 1.0 product. I declined for pretty much that reason&mdash;the product was too simple. Now they&#8217;re at version 2.0, and have a lot of new features. Surprise!)</p>
<p>Another point of concern is that some parts of reviewing a tool need other users involved. Access control, security, and privilege issues need multiple users. Too often, demo or review software has these features disabled or dumbed down. It&#8217;s hard to be in conflict with yourself. It&#8217;s hard to create any kind of log-jam with only one user. (And of course, it&#8217;s a considerable pain in the <a href="http://en.wikipedia.org/wiki/List_of_English_words_of_Yiddish_origin">tuchus</a> by yourself.)</p>
<p>So imagine a &#8220;standard&#8221; review of CVS: I try to create a set of change requests, and &#8230;  </p>
<p>This sort of suggests that there maybe should be some kind of onion-peel review. The tool is what the tool is, and the reviewer peels away the standard layers until the tool starts to be relevant. But how much value does that even provide? If I&#8217;m writing a review of CVS, and the reader needs MKS Integrity or Telelogic Synergy, whose time is more wasted&mdash;mine or hers?</p>
<p>Bizarrely, then, the right first step seems to be to write a book (No, this isn&#8217;t a joke.) about SCM. Then match each tool against the book. But that&#8217;s crazy talk. The next best thing to writing a book, of course, is getting somebody else to write a book for me. There&#8217;s two ways to get there: pick on some standard text, or &#8220;web 2.0&#8243; it. I can&#8217;t think of a useful &#8220;standard book,&#8221; so the web 2.0 approach doesn&#8217;t seem too bad. Perhaps the approach should be to create a wiki, fill it full of standard questions, and then encourage the users to answer them. Of course, most users aren&#8217;t very good writers, but isn&#8217;t that what wiki-gnomes are for? Of course, that puts me almost in competition with CM Crossroads, a position I don&#8217;t think I want to be in. <img src='http://www.longacre-scm.com/blog/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> </p>
<p>Maybe the right answer is a little of both. Create the wiki, then &#8220;edit up&#8221; when tasked to doing a particular review. Take the standard questions, and render them into useful text. Now I&#8217;m competing with <a href="http://www.gartner.com/">Gartner.</a> Joy!</p>
<p>If you&#8217;ve got some ideas, boy do I need &#8216;em.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2008/03/how-do-i-review-a-scm-tool/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MatchPoint &#8211; a first pass at deployment management?</title>
		<link>http://www.longacre-scm.com/blog/index.php/2008/03/matchpoint-a-first-pass-at-deployment-management</link>
		<comments>http://www.longacre-scm.com/blog/index.php/2008/03/matchpoint-a-first-pass-at-deployment-management#comments</comments>
		<pubDate>Tue, 25 Mar 2008 15:10:27 +0000</pubDate>
		<dc:creator>Austin Hastings</dc:creator>
				<category><![CDATA[Blogroll]]></category>
		<category><![CDATA[Software CM]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://www.longacre-scm.com/blog/index.php/2008/03/matchpoint-a-first-pass-at-deployment-management</guid>
		<description><![CDATA[I was browsing some Spanish-language software development blogs, and came across a reference to MatchPoint, a mainframe-oriented product from a Swiss company called CM First AG. 
These guys don&#8217;t seem to have any more idea than most about how to manage database changes, but their product (or at least, the pdf of the glossy brochure) [...]]]></description>
			<content:encoded><![CDATA[<p>I was browsing some Spanish-language software development blogs, and came across a reference to MatchPoint, a mainframe-oriented product from a Swiss company called <a href="http://www.cmfirst.ch/cms/">CM First AG.</a> </p>
<p>These guys don&#8217;t seem to have any more idea than most about how to manage database changes, but their product (or at least, the pdf of the glossy brochure) looks to have some really good tracking built in for deployments in both i-space and Windows-space. They claim that (for a small additional fee) you can track deployments all the way to the customer. </p>
<p>This is typical of a mainframe approach. The mainframe guys don&#8217;t have bajillions of PC customers, they have tens, or hundreds, or thousands of mainframe customers. Those are small enough numbers that it makes sense to talk about tracking them individually. It isn&#8217;t surprising, therefore, that mainframers have a more pragmatic approach to tracking deployments.</p>
<p>Thinking about how I could get my hands on a copy of MatchPoint (when I don&#8217;t own an IBM i-series) has led me to think some more about how to review a CM tool. I want to be able to write CM tool reviews, but I don&#8217;t want to write the kind of bunkum that you get from most 1500-word specials.</p>
<p>If you have any hands-on experience with MatchPoint, I&#8217;d love to hear from you &mdash; to get some real world feedback on their glossy brochure, if nothing else. And if you have ideas on how to review a CM tool, well, I&#8217;ll write something up in a separate post. Hold that thought.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.longacre-scm.com/blog/index.php/2008/03/matchpoint-a-first-pass-at-deployment-management/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
