I’ve been gitting into (clever, I know) lately, so I was trying to migrate my git commits for a project back into an existing subversion repository – another post coming on that later.
When trying to run to import my subversion repository into git I got the following error, followed by a Perl stack trace:
I just upgraded Eclipse to 3.4 (Gandymede) since the latest upgrade to Flex Builder included support for Gandymede. I did my typical install by extracting the Gandymede tarball and then installed through the Software updates (now in Help -> Software Updates…).
It looked like everything installed okay but then when I tried to do an update in an existing project I got an error:
"Unable to load default SVN Client"
The key is to include the SVNKit Adapter JavaHL Adapter when you install Subclipse:
Include JavaHL when installing Subclipse.
Hope that saves some people some time.
NOTE: Thanks to Mark for pointing out the recommended usage of JavaHL instead of SVNKit!
Update 2008/06/13: Jamis released , and it includes the :normalize_asset_timestamps patch that I submitted!
Update 2008/06/11: Here’s a link back to the regarding this topic.
Subversion has a lesser-known feature that allows you to specify that checkouts/exports/switches/reverts should timestamp files with the last committed timestamp. By default, this setting is turned off. As such, when you checkout a repository, every file is timestamped with the current time on your local machine.
To be honest, I’m not quite sure why this is the default. The (you have to scroll to the bottom) describes the setting as such:
———- use-commit-times
Normally your working copy files have timestamps that reflect the last time they were touched by any process, whether that be your own editor or by some svn subcommand. This is generally convenient for people developing software, because build systems often look at timestamps as a way of deciding which files need to be recompiled.
In other situations, however, it’s sometimes nice for the working copy files to have timestamps that reflect the last time they were changed in the repository. The svn export command always places these “last-commit timestamps†on trees that it produces. By setting this config variable to yes, the svn checkout, svn update, svn switch, and svn revert commands will also set last-commit timestamps on files that they touch.
———-
It’s not clear to me why the default aids in Makefiles. What is clear to me though is that Jamis Buck has taken this default behavior into account in , the wonderful deployment tool we use at .
The following code snippets will require a bit of understanding of the built-in Capistrano deployment recipes. Let’s take a look at the code for the :finalize_update task. This task is invoked after the code has been updated on the server (for Subversion, either by an export or update).
What this snippet of code does is compute a timestamp, and then touch each asset file on the server with that timestamp (-t #{stamp}). The intention for doing this was to handle the scenario where you have multiple asset servers. Since an export/checkout updates the timestamp with the local machine’s current time, it’s possible for the same asset to have different timestamps on separate asset servers.
So what’s the big deal? First, rails serves up images (when using the image_tag helper) with a querystring appended to it. This querystring is simply a timestamp. The reason for this is to support client-side caching (you’re doing this, right?). This basically allows you to set the “expires” attribute of that file several years (decades or millenniums, in fact) into the future. The reason this is so is because if that file ever changes, it’s last modified attribute will also change, effectively changing the querystring rails appends automatically, and causing your browser to download a ‘new asset.’ So, when the finalize_update task is invoked (which happens every time you re-deploy), all of these last-modified timestamps are reset, causing any repeat visitors to re-download these very same assets again.
I have submitted a patch to Jamis (which I hope he’ll apply soon!) that exposes an extra Capistrano parameter (:normalize_asset_timestamps), which would be set to true by default, leaving the original behavior in tact. The new :finalize_update task looks like:
task :finalize_update, :except => { :no_release => true } do
# ... other details omitted
if fetch(:normalize_asset_timestamps, true)
stamp = Time.now.utc.strftime("%Y%m%d%H%M.%S")
asset_paths = %w(images stylesheets javascripts).map { |p| "#{latest_release}/public/#{p}" }.join(" ")
run "find #{asset_paths} -exec touch -t #{stamp} {} ';'; true", :env => { "TZ" => "UTC" }
end
end
I’ll follow up when/if Jamis accepts the patch. Hopefully it can make it into version 2.4!