Piston is a utility that enables merge tracking of remote repositories.
This is similar to svn:externals, except you have a local copy of
the files, which you can modify at will. As long as the changes are
mergeable, you should have no problems.
This tool has a similar purpose than svnmerge.py which you can find in the
contrib/client-side folder of the main Subversion repository at
http://svn.collab.net/repos/svn/trunk/contrib/client-side/svnmerge.py.
The main difference is that Piston is designed to work with remote
repositories. Another tool you might want to look at, SVK, situated at
http://svk.elixus.org.
From Wikipedia's Piston page (http://en.wikipedia.org/wiki/Piston):
In general, a piston is a sliding plug that fits closely inside the bore
of a cylinder.
Its purpose is either to change the volume enclosed by the cylinder, or
to exert a force on a fluid inside the cylinder.
For this utility, I retain the second meaning, "to exert a force on a fluid
inside the cylinder." Piston forces the content of a remote repository
location back into our own.
= Installation
Nothing could be simpler:
$ gem install --include-dependencies piston
= Usage
First, you need to import the remote repository location:
$ piston import http://dev.rubyonrails.org/svn/rails/trunk vendor/rails
Exported r4720 from 'http://dev.rubyonrails.org/svn/rails/trunk' to 'vendor/rails'
$ svn commit -m "Importing local copy of Rails"
When you want to get the latest changes from the remote repository location:
$ piston update vendor/rails
Updated 'vendor/rails' to r4720.
$ svn commit -m "Updates vendor/rails to the latest revision"
You can prevent a local Piston-managed folder from updating by using the
+lock+ subcommand:
$ piston lock vendor/rails
'vendor/rails' locked at r4720.
When you want to update again, you unlock:
$ piston unlock vendor/rails
'vendor/rails' unlocked.
= Contributions
== Bash Shell Completion Script
Michael Schuerig contributed a Bash shell completion script. You should copy
+contrib/piston+ from your gem repository to the appropriate folder. Michael
said:
I've put together a bash completion function for piston. On Debian, I
just put it in /etc/bash_completion.d, alternatively, the contents can
be copied to ~/.bash_completion. I don't know how things are organized
on other Unix/Linux systems.
= Caveats
== Speed
This tool is SLOW. The update process particularly so. I use a brute force
approach. Subversion cannot merge from remote repositories, so instead I
checkout the folder at the initial revision, and then run svn update and
parse the results of that to determine what changes have occured.
If a local copy of a file was changed, it's changes will be merged back in.
If that introduces a conflict, Piston will not detect it. The commit will be
rejected by Subversion anyway.
== Copies / Renames
Piston *does not* track copies. Since Subversion does renames in two
phases (copy + delete), that is what Piston does.
== Local Operations Only
Piston only works if you have a working copy. It also never commits your
working copy directly. You are responsible for reviewing the changes and
applying any pending fixes.
== Remote Repository UUID
Piston caches the remote repository UUID, allowing it to know if the remote
repos is still the same. Piston refuses to work against a different
repository than the one we checked out from originally.
= Subversion Properties Used
* piston:uuid: The remote repository's UUID, which we always confirm
before doing any operations.
* piston:root: The repository root URL from which this Piston folder
was exported from.
* piston:remote-revision: The Last Changed Rev of the remote
repository.
* piston:local-revision: The Last Changed Rev of the Piston
managed folder, to enable us to know if we need to do any merging.
* piston:locked: The revision at which this folder is locked. If
this property is set and non-blank, Piston will skip the folder with
an appropriate message.
= Dependencies
Piston depends on the following libraries:
* yaml
* getoptlong
* uri
* fileutils
These dependencies are all included in a stock 1.8.4 Ruby distribution.