<?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"
	>

<channel>
	<title>Invert Your Mind</title>
	<atom:link href="http://brian.pontarelli.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://brian.pontarelli.com</link>
	<description>Brian Pontarelli</description>
	<pubDate>Wed, 19 Nov 2008 01:24:31 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<item>
		<title>Centering images and text inside an li or div</title>
		<link>http://brian.pontarelli.com/2008/11/18/centering-images-and-text-inside-an-li-or-div/</link>
		<comments>http://brian.pontarelli.com/2008/11/18/centering-images-and-text-inside-an-li-or-div/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 01:23:34 +0000</pubDate>
		<dc:creator>Brian Pontarelli</dc:creator>
		
		<category><![CDATA[CSS]]></category>

		<category><![CDATA[centering]]></category>

		<category><![CDATA[div]]></category>

		<category><![CDATA[html]]></category>

		<category><![CDATA[images]]></category>

		<category><![CDATA[li]]></category>

		<category><![CDATA[list item]]></category>

		<category><![CDATA[text]]></category>

		<guid isPermaLink="false">http://brian.pontarelli.com/?p=229</guid>
		<description><![CDATA[Found a good fix for this one as well. This will work on LIs or DIVs. Here&#8217;s how to do this in IE and FireFox:

li {
  display: inline;
  text-align: center;
}

li img {
  display: block;
  margin: auto;
}

The HTML looks like this:

&#60;ul>
  &#60;li>&#60;img src="..."/>Some text&#60;/li>
  &#60;li>&#60;img src="..."/>Some text&#60;/li>
&#60;/ul>

]]></description>
			<content:encoded><![CDATA[<p>Found a good fix for this one as well. This will work on LIs or DIVs. Here&#8217;s how to do this in IE and FireFox:</p>
<pre>
li {
  display: inline;
  text-align: center;
}

li img {
  display: block;
  margin: auto;
}
</pre>
<p>The HTML looks like this:</p>
<pre>
&lt;ul>
  &lt;li>&lt;img src="..."/>Some text&lt;/li>
  &lt;li>&lt;img src="..."/>Some text&lt;/li>
&lt;/ul>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://brian.pontarelli.com/2008/11/18/centering-images-and-text-inside-an-li-or-div/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Getting rid of spaces between LIs in IE</title>
		<link>http://brian.pontarelli.com/2008/11/18/getting-rid-of-spaces-between-lis-in-ie/</link>
		<comments>http://brian.pontarelli.com/2008/11/18/getting-rid-of-spaces-between-lis-in-ie/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 01:01:52 +0000</pubDate>
		<dc:creator>Brian Pontarelli</dc:creator>
		
		<category><![CDATA[CSS]]></category>

		<category><![CDATA[ie]]></category>

		<category><![CDATA[li]]></category>

		<category><![CDATA[list item]]></category>

		<category><![CDATA[spacing]]></category>

		<category><![CDATA[unordered list]]></category>

		<guid isPermaLink="false">http://brian.pontarelli.com/?p=226</guid>
		<description><![CDATA[Took a bit of research, but the only way I could get rid of all the space between LIs in IE was to make the LI inline and the anchor tag within the LI a block like this:

.some-class li {
  display: inline;
}

.some-class li a {
  display: block;
}

]]></description>
			<content:encoded><![CDATA[<p>Took a bit of research, but the only way I could get rid of all the space between LIs in IE was to make the LI inline and the anchor tag within the LI a block like this:</p>
<pre>
.some-class li {
  display: inline;
}

.some-class li a {
  display: block;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://brian.pontarelli.com/2008/11/18/getting-rid-of-spaces-between-lis-in-ie/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Savant command-line tool and plugins are almost ready</title>
		<link>http://brian.pontarelli.com/2008/11/14/savant-command-line-tool-and-plugins-are-almost-ready/</link>
		<comments>http://brian.pontarelli.com/2008/11/14/savant-command-line-tool-and-plugins-are-almost-ready/#comments</comments>
		<pubDate>Fri, 14 Nov 2008 23:53:59 +0000</pubDate>
		<dc:creator>Brian Pontarelli</dc:creator>
		
		<category><![CDATA[Inversoft]]></category>

		<category><![CDATA[JCatapult]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Savant]]></category>

		<category><![CDATA[ant]]></category>

		<category><![CDATA[build]]></category>

		<category><![CDATA[dependency management]]></category>

		<category><![CDATA[maven]]></category>

		<category><![CDATA[versioning]]></category>

		<guid isPermaLink="false">http://brian.pontarelli.com/?p=222</guid>
		<description><![CDATA[Been working this week on Savant 2.0. My first thought when I started writing Savant 2.0 was to write a complete replacement for both Maven and Ant that used Groovy and allowed for both a plugin model as well as a simple build script approach. This was too much to bite off when you consider [...]]]></description>
			<content:encoded><![CDATA[<p>Been working this week on <a href="http://code.google.com/p/savant-build">Savant</a> 2.0. My first thought when I started writing Savant 2.0 was to write a complete replacement for both Maven and Ant that used Groovy and allowed for both a plugin model as well as a simple build script approach. This was too much to bite off when you consider all of the other changes to the dependency management part of Savant we made for 2.0.</p>
<p>For <a href="http://www.jcatapult.org">JCatapult</a> we created a set of Ant build scripts that could be plugged into any build file and reused. It looks like this:</p>
<pre>
&lt;project name="foo">
  &lt;import file="${jcatapult.home}/ant/plugins/java/1.0/compile.xml"/>
  ...
&lt;/project>
</pre>
<p>This model meant that the build.xml file had nothing but import statements in it. It made life much simpler when working with numerous projects that were virtually the same. </p>
<p>The part I didn&#8217;t like was that I loved this model. I liked it so much I started using them for everything including Java.net Commons, Savant and internal Inversoft projects. This meant that I had a dependency on JCatapult, which for all intents and purposes is a webapp platform. This seemed strange.</p>
<p>I started thinking about moving these files over to Savant. At first I just figured I would migrate the entire set of Ant plugins from JCatapult over and be done. However, once I moved them over it meant that I would need to start pulling in plugins for a variety of projects. Some would come from Savant and others might come from JCatapult or elsewhere. This was due to the fact that some of the JCatapult plugins were very specific to JCatapult projects. I could force developers to download each plugin they needed from various places, install them in a specific directory and then update their build files before they could build any projects. It all started to look very clunky.</p>
<p>Then I remembered (duh!) that Savant is a dependency management tool and it can find, version and download ANYTHING. Why not apply this pattern to Ant build files in the form of plugins?</p>
<p>So, I did just that!</p>
<p>It works great. The way it works is that I wrote a simple Java class that figures everything out and then generates an ant build file. The full process looks like this:</p>
<ol>
<li>New script called <strong>svnt</strong> invokes a Savant class</li>
<li>This new class parses the project.xml file, which defines the plugins the project will be using</li>
<li>It downloads any missing plugins to the Savant local cache</li>
<li>Since the plugins are JAR files, it explodes the JAR file to ~/.savant/plugins under a specific directory just for that plugin</li>
<li>This class then generates a temporary build.xml file that imports all of the plugins the project needs</li>
<li>It outputs the location of this temporary build.xml file</li>
<li>The svnt script executes Ant passing it the location of this build file (i.e. ant -f /tmp/tmpbuild.xml)</li>
</ol>
<p>And that&#8217;s it. Nothing fancy, just a little sugar on top of Ant to provide downloading of plugins and build files automatically. </p>
<p>The last part of this exercise is to write a bunch of plugins. Since these are just Ant build scripts and we&#8217;ve all created hundreds of those so it should be a simple matter of tweaking them ever so slightly to work when imported.</p>
<p>My new projects don&#8217;t have a build.xml file (but if they do it is imported to add additional targets or override targets from the plugins) and just contain the Savant project.xml file. This file now defines plugins and it looks like this:</p>
<pre>
&lt;project name="foo" group="inversoft.org" version="1.0">
  &lt;plugin group="plugins.savant.inversoft.org" name="clean" version="1.0"/>
  &lt;plugin group="plugins.savant.inversoft.org" name="java" version="1.0"/>
  &lt;plugin group="plugins.savant.inversoft.org" name="junit" version="1.0"/>
  &lt;plugin group="plugins.savant.inversoft.org" name="release-svn" version="1.0"/>
  ...
&lt;/project>
</pre>
<p>That&#8217;s it. If anyone is interested in trying it out, I should have a release available in the next few days along with some documentation for the 5-10 plugins I will have ready. If you want to try and build all this by hand right now, you&#8217;ll need to install JCatapult since Savant uses that until it can be self building.</p>
]]></content:encoded>
			<wfw:commentRss>http://brian.pontarelli.com/2008/11/14/savant-command-line-tool-and-plugins-are-almost-ready/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Android, iPhone, Java, Objective-C&#8230; madness</title>
		<link>http://brian.pontarelli.com/2008/10/19/android-iphone-java-objective-c-madness/</link>
		<comments>http://brian.pontarelli.com/2008/10/19/android-iphone-java-objective-c-madness/#comments</comments>
		<pubDate>Sun, 19 Oct 2008 20:12:20 +0000</pubDate>
		<dc:creator>Brian Pontarelli</dc:creator>
		
		<category><![CDATA[Google]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Microsoft]]></category>

		<category><![CDATA[OS X]]></category>

		<category><![CDATA[android]]></category>

		<category><![CDATA[apple]]></category>

		<category><![CDATA[cocoa]]></category>

		<category><![CDATA[g1]]></category>

		<category><![CDATA[groovy]]></category>

		<category><![CDATA[objective-c]]></category>

		<category><![CDATA[scala]]></category>

		<guid isPermaLink="false">http://brian.pontarelli.com/?p=217</guid>
		<description><![CDATA[Russ Teabeault and I were just talking about our recent experiences with Objective-C and developing applications for either the iPhone or OS X. In general, we both agree that Objective-C is necessary, but painful. The language is quasi-dynamic, not very modern and poorly adopted. 
Let me clarify that a bit. Objective-C is dynamic but lacks [...]]]></description>
			<content:encoded><![CDATA[<p>Russ Teabeault and I were just talking about our recent experiences with Objective-C and developing applications for either the iPhone or OS X. In general, we both agree that Objective-C is necessary, but painful. The language is quasi-dynamic, not very modern and poorly adopted. </p>
<p>Let me clarify that a bit. Objective-C is dynamic but lacks nice features that most modern dynamic languages provide such as closures (although these aren&#8217;t strictly tied to dynamic languages by any means). It also uses a fairly non-standard message passing syntax, that is probably because it had to select something that would not conflict with C and C++. It also still uses header files and lacks good namespacing, both of which are obvious signs of antiquity. Plus, we both shared stories of having impossible times finding good open source libraries, tools and framework. The last bit of our conversation was the extreme lackluster of the XCode IDE, which is more like a text editor than a modern development environment.</p>
<p>I mentioned that prior to 10.4, Apple had provided integration of most of the Cocoa libraries with Java and had even written some OS applications in Java. Not surprising, we both thought the shift from Java to Objective-C was a step in the wrong direction. It seemed as though the correct direction would be a better, faster and more integrated VM that would run many languages including Java, much like the CLR offers developers on Windows. Instead, Apple seems to be chugging along the CPU native path and providing bridges between Objective-C and various scripting languages. This means that each new language they want to support on the operating systems requires work to bridge effectively and that work can only be done well by Apple. If they had gone down the VM path, new languages would be supported once the community built support for them on the VM. Therefore, if I wanted to write my next application for OS X in Scala, I could.</p>
<p>This brought us to a discussion of the merits of Android for mobile development. This is where we had different opinions. I think Android will be great and the development community and support behind it will be much larger than the iPhone. He thought that Apple might release a Java VM for the iPhone if Android picks up steam and believes that the iPhone is still the best platform for mobile.</p>
<p>The reason I like the idea of Android (although the G1 might be a crappy implementation without the ease of use and cool features of the iPhone) because it was fundamentally VM based. This meant that the platform was based on Java-byte code rather than the CPU instruction set. It also meant that the platform had modern concepts like garbage collection, memory management, ClassLoading and all the other good parts of the VM. But it also meant that it will be capable of running any Java-byte code regardless of the language it is written in. Therefore, I could write my Android application in Groovy and with the help of a few extra JARs, get it running just as well as plain old Java. </p>
<p>(Update 10/22/08 Groovy doesn&#8217;t quite work yet, because of a number of additional classes and JARs it uses. However, the principle is sound because Android is VM based. JRuby might be a better solution than Groovy depending.)</p>
<p>The problem with the iPhone is that it is tied directly to the CPU instruction set and the Objective-C language. This means you take a step backwards 20 years and now have all the overhead of header files, pre-compilers, directives, manual memory management, no-namespacing, and numerous other headaches that VMs have done exceedingly well in fixing.</p>
<p>What I wonder is why Microsoft is the only operating system company to figure out that wiring a VM, capable of everything we except out of a modern VM plus application isolation, into the lowest levels of the OS is a great idea. In fact, this idea is fantastic. This means applications targeted to the VM improve as the VM improves, without any code changes. </p>
<p>The Java VM still has a long way to go to catch up with the CLR as a full platform. JSR 121 was finalized a few years back, which will provide good application isolation within a single Java VM instance. This means that you can start up the Java VM and then run multiple applications inside it without any conflicts or concerns about one application impacting the others (such as an application calling System.exit or running out of memory). The Java VM still needs extremely tight integration with the operating system and needs to be started when the OS boots. It also needs new ways to start applications and manage applications, which JSRs 277 and 294 should help with. I think though that Google has done all of this work for Android. It runs multiple applications in isolation well, it provides a mechanism for applications to start and stop and the Java VM is completely integrated into the operating system of the mobile device. </p>
<p>I think this is the way of the future. I&#8217;m just trying to figure out where Apple is going and why they are heading that way.</p>
]]></content:encoded>
			<wfw:commentRss>http://brian.pontarelli.com/2008/10/19/android-iphone-java-objective-c-madness/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Java and command-tab fixed?</title>
		<link>http://brian.pontarelli.com/2008/09/30/java-and-command-tab-fixed/</link>
		<comments>http://brian.pontarelli.com/2008/09/30/java-and-command-tab-fixed/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 02:07:56 +0000</pubDate>
		<dc:creator>Brian Pontarelli</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[OS X]]></category>

		<category><![CDATA[apple]]></category>

		<guid isPermaLink="false">http://brian.pontarelli.com/?p=212</guid>
		<description><![CDATA[I might be smokin&#8217; crack, but I think that todays (September 30th, 2008) Java update from Apple finally fixed the command-tab issue. I haven&#8217;t verified it with different apps yet, but the ones I use regularly seem to be working as expected when you command-tab to them.
]]></description>
			<content:encoded><![CDATA[<p>I might be smokin&#8217; crack, but I think that todays (September 30th, 2008) Java update from Apple finally fixed the command-tab issue. I haven&#8217;t verified it with different apps yet, but the ones I use regularly seem to be working as expected when you command-tab to them.</p>
]]></content:encoded>
			<wfw:commentRss>http://brian.pontarelli.com/2008/09/30/java-and-command-tab-fixed/feed/</wfw:commentRss>
		</item>
		<item>
		<title>An evening with Jason Fried from 37 Signals</title>
		<link>http://brian.pontarelli.com/2008/08/01/an-evening-with-jason-fried-from-37-signals/</link>
		<comments>http://brian.pontarelli.com/2008/08/01/an-evening-with-jason-fried-from-37-signals/#comments</comments>
		<pubDate>Fri, 01 Aug 2008 19:10:40 +0000</pubDate>
		<dc:creator>Brian Pontarelli</dc:creator>
		
		<category><![CDATA[Engineering]]></category>

		<category><![CDATA[Inversoft]]></category>

		<category><![CDATA[Life]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Tech]]></category>

		<category><![CDATA[37 signals]]></category>

		<category><![CDATA[complexity]]></category>

		<category><![CDATA[cpb]]></category>

		<category><![CDATA[ideals]]></category>

		<category><![CDATA[jason fried]]></category>

		<guid isPermaLink="false">http://brian.pontarelli.com/?p=208</guid>
		<description><![CDATA[I went to the 37 Signals event last night sponsored by CPB. The speaker was Jason Fried, who is a founder of the company, a designer and all around smart guy.
Jason spoke mainly about small business. He presented a list of things that companies can do to become more productive and better at whatever they [...]]]></description>
			<content:encoded><![CDATA[<p>I went to the <a href="http://www.37signals.com">37 Signals</a> event last night sponsored by <a href="http://www.cpbgroup.com">CPB</a>. The speaker was Jason Fried, who is a founder of the company, a designer and all around smart guy.</p>
<p>Jason spoke mainly about small business. He presented a list of things that companies can do to become more productive and better at whatever they do. His list included things such as:</p>
<ul>
<li>4 day work weeks</li>
<li>Virtual companies</li>
<li>Saying no to your customers more often than not</li>
<li>Do the easiest thing possible</li>
<li>Don&#8217;t design, just do</li>
<li>Don&#8217;t go to meetings</li>
<li>Turn off email and IM</li>
</ul>
<p>A number of these things I do each day including turning off email and IM when I&#8217;m really cranking, be as virtual as possible, reduce lengthy design and just start working. Overall, Jason has great ideas for small companies. 37 Signals is probably in the 3-5 million dollar range or lower, with about 2-3 million dollars of overhead or more. They are a life-style company and will not grow beyond a certain threshold because of these ideals.</p>
<p>Having worked for a <a href="http://www.orbitz.com">large company</a>, worked on vastly more complex systems than Jason, created many open source frameworks and now <a href="http://www.inversoft.com">starting my own company</a>, I found Jason&#8217;s ideas exciting and total crap at the same time. I regularly find myself battling with creating solutions that will scale, versus creating the simplest solution. This naturally occurs to anyone who has ever worked with applications that do hundreds of millions of transactions per day (or per hour).</p>
<p>I pushed Jason a bit to see where he would break ranks with some of his ideals. From his responses, he absolutely would not abandon these ideals at any cost. However, I think this is a marketing tool created by 37 signals to promote their products as well as <a href="http://www.rubyonrails.org">Ruby on Rails</a>. The reason I know this to be true, is that Jason is intelligent and capable or understanding moderately complex problems with more ease than say a college student. In addition, he spoke briefly about how a single feature request such as <em>adding time-stamps to ToDo list items</em> can have a larger impact than any customer might think. These features requests require a large amount of thought and planning because they impact the entire system. Similarly, changes to the Rails internals require a large amount of thought and testing to ensure they don&#8217;t break existing applications. </p>
<p>This dichotomy is something that is a fact of life. It is something engineers, product managers and executives must deal with, no matter how small or large your company is. 37 Signals has built a reputation that they can safely ignore these problems and be wildly successful. However, it is 95% smoke and mirrors. The reality is that 37 Signals is composed completely of phenomenal employees who can work in complex domains without losing their minds. The can distill complexity into manageable pieces and then combine those pieces in the end to produce a complex yet functional system.</p>
]]></content:encoded>
			<wfw:commentRss>http://brian.pontarelli.com/2008/08/01/an-evening-with-jason-fried-from-37-signals/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Talkinator and profanity</title>
		<link>http://brian.pontarelli.com/2008/07/28/talkinator-and-profanity/</link>
		<comments>http://brian.pontarelli.com/2008/07/28/talkinator-and-profanity/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 23:27:22 +0000</pubDate>
		<dc:creator>Brian Pontarelli</dc:creator>
		
		<category><![CDATA[Inversoft]]></category>

		<category><![CDATA[Life]]></category>

		<category><![CDATA[profanity]]></category>

		<category><![CDATA[cringely]]></category>

		<category><![CDATA[filter]]></category>

		<category><![CDATA[pulpit]]></category>

		<category><![CDATA[talkinator]]></category>

		<guid isPermaLink="false">http://brian.pontarelli.com/?p=204</guid>
		<description><![CDATA[Just read an interesting new I, Cringely about a piece of software named Talkinator. The technology seems just like a new IRC for the web with some APIs and Web 2.0 style, but that wasn&#8217;t what caught my eye. What caught my attention was that Cringely states that Taklinator doesn&#8217;t allow profanity. Being that Inversoft&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>Just read an <a href="http://www.pbs.org/cringely/pulpit/2008/pulpit_20080728_005308.html">interesting new I, Cringely</a> about a piece of software named <a href="http://www.talkinator.com">Talkinator</a>. The technology seems just like a new IRC for the web with some APIs and Web 2.0 style, but that wasn&#8217;t what caught my eye. What caught my attention was that Cringely states that Taklinator doesn&#8217;t allow profanity. Being that Inversoft&#8217;s main product is a profanity filter, I had to try it out. It failed pretty badly.</p>
<p>Of course it catches your straight forward profanity like <strong>ass</strong> and <strong>fuck</strong>, but it does very little for anything more complex. </p>
<p>Here are some examples of stuff it doesn&#8217;t handle:</p>
<p>$hit<br />
asslips<br />
assface<br />
phuck<br />
fuk you<br />
|)ick<br />
sh it</p>
<p>That&#8217;s just a few, but the list goes on. I definitely think that people don&#8217;t understand the complexity that comes with attempting to filter profanity. It is much more difficult than it seems. I definitely think Talkinator should check out <a href="http://www.inversoft.com/products/profanity/filter/">Inversoft&#8217;s Profanity Filter</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://brian.pontarelli.com/2008/07/28/talkinator-and-profanity/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Restoring a SubVersion repository from an old backup</title>
		<link>http://brian.pontarelli.com/2008/07/28/restoring-a-subversion-repository-from-an-old-backup/</link>
		<comments>http://brian.pontarelli.com/2008/07/28/restoring-a-subversion-repository-from-an-old-backup/#comments</comments>
		<pubDate>Mon, 28 Jul 2008 17:58:50 +0000</pubDate>
		<dc:creator>Brian Pontarelli</dc:creator>
		
		<category><![CDATA[Engineering]]></category>

		<category><![CDATA[Java]]></category>

		<category><![CDATA[Life]]></category>

		<category><![CDATA[Misc]]></category>

		<category><![CDATA[Tech]]></category>

		<category><![CDATA[backup]]></category>

		<category><![CDATA[corrupt]]></category>

		<category><![CDATA[crash]]></category>

		<category><![CDATA[repository]]></category>

		<category><![CDATA[restore]]></category>

		<category><![CDATA[subversion]]></category>

		<guid isPermaLink="false">http://brian.pontarelli.com/?p=201</guid>
		<description><![CDATA[I have recently gone through the exercise of restoring a medium sized SubVersion repository from an older backup and wanted to share my experience with everyone. First, the problem:
The problem
After you restore the older backup, if any work was performed between the last backup and when the repository crashed, the repository will be &#8220;older&#8221; than [...]]]></description>
			<content:encoded><![CDATA[<p>I have recently gone through the exercise of restoring a medium sized SubVersion repository from an older backup and wanted to share my experience with everyone. First, the problem:</p>
<h3>The problem</h3>
<p>After you restore the older backup, if any work was performed between the last backup and when the repository crashed, the repository will be &#8220;older&#8221; than what developers have on their boxes. Here is an example:</p>
<ul>
<li>Let&#8217;s say you have a backup from Monday evening</li>
<li>The repository crashed sometime Tuesday</li>
<li>There was work done during the day Monday</li>
</ul>
<p>Now, let&#8217;s say there is a project A that looks like this:</p>
<ul>
<li>The last change to the project was at revision 100 just before the repository crashed</li>
<li>The last change to the project from the backup was 80</li>
<li>Frank&#8217;s computer contains a checkout of the project at revision 85</li>
<li>Mary&#8217;s computer contains a checkout of the project at revision 100</li>
</ul>
<p>This means that both Frank and Mary&#8217;s computers contain newer code than the repository, but not the latest code. Mary&#8217;s computer contains newer code than the repository, but might not be a complete snapshot of what version 100 was before the repository was corrupt. The reason why Mary&#8217;s computer might not be 100% correct is that Mary might have committed files to the repository but not performed a &#8220;svn update&#8221; prior to committing.</p>
<p>SubVersion is like CVS in that each file contains a version number. So, you might have a local checkout that contains version 100 for one file and 90 of another file. Therefore, you might be missing an updated version of the file from revision 93 when it was checked in.</p>
<p>Okay, now onto the fix:</p>
<h3>The fix</h3>
<p>Each developer&#8217;s computer must be analyzed before anything new is put into the repository. You must have a complete picture of the entire company, otherwise you might miss some changes. These changes can be merged in by hand from each developers machine, but this could be error prone and lengthy process. It is usually better to script out as much as possible.</p>
<h4>Step 1</h4>
<p>In order to determine the local &#8220;revision&#8221; of a project on a developers computer, you will need to look at each file in the checkout. You can run an &#8217;svn stat&#8217; on each file to determine the version number of that file. Write a script to output a file like this for each local checked out project on all developers machines:</p>
<pre>
src/java/foo.java: 90
</pre>
<p>The first part is the file and the second part is the revision of that file.</p>
<p>Next, once you have the complete list of revisions for all projects on all developer&#8217;s computers in the entire company, you can compare each file with the current revision in the restored repository to determine if the developer has a later version of a file than the repository. This should ignore all files that the developer has modified locally, but not committed. </p>
<p>This comparison will look like this:</p>
<pre>
Restored repository
src/java/foo.java: 80

Mary's checkout
src/java/foo.java: 90

Mary has a later version of foo.java!
</pre>
<p>You should script all of these comparisons out. If a developer doesn&#8217;t have later revisions than the repository or any locally modified files, they can safely take these steps:</p>
<ol>
<li>Make a backup of the local checkout</li>
<li>Delete the local checkout</li>
<li>Re-checkout the project</li>
<li>Don&#8217;t do anything until the restore is complete</li>
</ol>
<h4>Step 2</h4>
<p>The next step is to make a list of the revision that each file in the project was lasted changed on in the restored repository. This report will look like this:</p>
<pre>
build.xml: 10
src/java/main/foo.java: 16293
src/conf/main/logging.properties: 12093
</pre>
<p>Next, for each project, collect all of the revision reports from the previous step into a single location. These reports look like this:</p>
<pre>
frank-project-a-report.txt
build.xml: 10
src/java/main/foo.java: 16301
src/conf/main/logging.properties: 16405
</pre>
<pre>
mary-project-a-report.txt
build.xml: 10
src/java/main/foo.java: 16410
src/conf/main/logging.properties: 16321
</pre>
<p>Combine each of the developer reports into a global report that gives you the revision number for each file on every developers computer. Next, use this global developer report to determine whose computer contains the latest version for each file in the project. Based on the examples above, you can see that build.xml didn&#8217;t change recently enough to matter since the version in the repository is the same as the version on Frank&#8217;s and Mary&#8217;s computers. However, Frank made the most recent commit in revision 16405 to logging.properties and Mary made the most recent commit in revision 16410 to foo.java. Both of these files are more current that the repository and therefore need to be re-committed.</p>
<h4>Step 3</h4>
<p>Finally, setup a staging area that contains a copy of every checked out project from every developers computer who has a later revision than the repository (from step 1). This will be pretty large, but necessary. Based on the results from step 2, copy the latest version of each file over to a clean checkout of the project from the restored repository. Once you have all of the changes copied over for a single project, commit all of those files for that project back to TRUNK. </p>
<p>You should now have a fully restored repository based on the files from various developers computers.</p>
]]></content:encoded>
			<wfw:commentRss>http://brian.pontarelli.com/2008/07/28/restoring-a-subversion-repository-from-an-old-backup/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Java, SSL and self-signed certificates</title>
		<link>http://brian.pontarelli.com/2008/07/26/java-ssl-and-self-signed-certificates/</link>
		<comments>http://brian.pontarelli.com/2008/07/26/java-ssl-and-self-signed-certificates/#comments</comments>
		<pubDate>Sat, 26 Jul 2008 19:07:29 +0000</pubDate>
		<dc:creator>Brian Pontarelli</dc:creator>
		
		<category><![CDATA[Java]]></category>

		<category><![CDATA[certificate]]></category>

		<category><![CDATA[error]]></category>

		<category><![CDATA[failure]]></category>

		<category><![CDATA[self-signed]]></category>

		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://brian.pontarelli.com/?p=197</guid>
		<description><![CDATA[Depending on the API you are using or how you are using SSL, you might have received an error stating that the certificate is invalid, not path to certificate, invalid certificate chain, no chain found, PKIK error, or something similar. This occurs when the certificate is self-signed or signed by an authority that has not [...]]]></description>
			<content:encoded><![CDATA[<p>Depending on the API you are using or how you are using SSL, you might have received an error stating that the certificate is invalid, not path to certificate, invalid certificate chain, no chain found, PKIK error, or something similar. This occurs when the certificate is self-signed or signed by an authority that has not been verified by the JDK you are using.</p>
<p>There is a simple way to handle this for self-signed certificates:</p>
<ol>
<li>Open Firefox</li>
<li>Go to the site that is using SSL (i.e. https://svn.example.com)</li>
<li>Click on the lock down in the lower right corner of the browser window</li>
<li>Click the &#8220;View certificate&#8221; button</li>
<li>Click the details tab</li>
<li>Click the export button to export the certificate</li>
<li>Save the certificate in x.509 (PEM) format</li>
<li>Go to a command prompt</li>
<li>Add the certificate to the keystore</li>
</ol>
<p>Here is the command to add the certificate to your global keystore:</p>
<p><b>*nix</b></p>
<pre>
$ keytool -import -keystore $JAVA_HOME/lib/security/cacerts -file &lt;your-pem-export>
-alias &lt;anything>
</pre>
<p><b>Windows</b></p>
<pre>
c:\> keytool -import -keystore %JAVA_HOME%/lib/security/cacerts -file &lt;your-pem-export>
-alias &lt;anything>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://brian.pontarelli.com/2008/07/26/java-ssl-and-self-signed-certificates/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hidden folders in OS X file dialogs</title>
		<link>http://brian.pontarelli.com/2008/07/01/hidden-folders-in-os-x-file-dialogs/</link>
		<comments>http://brian.pontarelli.com/2008/07/01/hidden-folders-in-os-x-file-dialogs/#comments</comments>
		<pubDate>Tue, 01 Jul 2008 15:27:19 +0000</pubDate>
		<dc:creator>Brian Pontarelli</dc:creator>
		
		<category><![CDATA[OS X]]></category>

		<category><![CDATA[dialogs]]></category>

		<category><![CDATA[file]]></category>

		<category><![CDATA[folders]]></category>

		<category><![CDATA[hidden]]></category>

		<guid isPermaLink="false">http://brian.pontarelli.com/2008/07/01/hidden-folders-in-os-x-file-dialogs/</guid>
		<description><![CDATA[Found a good shortcut for getting access to hidden folders in OS X file dialogs and the Finder. It requires some typing and it doesn&#8217;t auto-complete like Linux does, but it is better than nothing. Just hit Shift-Command-G to open the &#8220;Go To Folder&#8221; dialog and then type the path to the hidden file or [...]]]></description>
			<content:encoded><![CDATA[<p>Found a good shortcut for getting access to hidden folders in OS X file dialogs and the Finder. It requires some typing and it doesn&#8217;t auto-complete like Linux does, but it is better than nothing. Just hit Shift-Command-G to open the &#8220;Go To Folder&#8221; dialog and then type the path to the hidden file or folder. The path can be relative.</p>
<p>Now, just need to figure out how to access hidden files from the Finder and file dialogs.</p>
<p>[Edit 08/09/2008] The issue is that using the AppleShowAllFiles configuration doesn&#8217;t work in dialog boxes and if you enable it, opening Finder in your home directory gets REALLY messy. What Apple needs is the same feature that Linux has had for a long time: the ability to show and hide hidden files in dialogs and finder using a keyboard shortcut or menu option. I believe Linux uses ctrl-h for this. Apple could use something like cmd-shift-h or something.</p>
]]></content:encoded>
			<wfw:commentRss>http://brian.pontarelli.com/2008/07/01/hidden-folders-in-os-x-file-dialogs/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
