| 1 |
Piston is a utility that eases vendor branch management. |
| 2 |
This is similar to <tt>svn:externals</tt>, except you have a local copy of |
| 3 |
the files, which you can modify at will. As long as the changes are |
| 4 |
mergeable, you should have no problems. |
| 5 |
|
| 6 |
This tool has a similar purpose than svnmerge.py which you can find in the |
| 7 |
contrib/client-side folder of the main Subversion repository at |
| 8 |
http://svn.collab.net/repos/svn/trunk/contrib/client-side/svnmerge.py. |
| 9 |
The main difference is that Piston is designed to work with remote |
| 10 |
repositories. Another tool you might want to look at, SVK, which you can find |
| 11 |
at http://svk.elixus.org/. |
| 12 |
|
| 13 |
From Wikipedia's Piston page (http://en.wikipedia.org/wiki/Piston): |
| 14 |
In general, a piston is a sliding plug that fits closely inside the bore |
| 15 |
of a cylinder. |
| 16 |
|
| 17 |
Its purpose is either to change the volume enclosed by the cylinder, or |
| 18 |
to exert a force on a fluid inside the cylinder. |
| 19 |
|
| 20 |
For this utility, I retain the second meaning, "to exert a force on a fluid |
| 21 |
inside the cylinder." Piston forces the content of a remote repository |
| 22 |
location back into our own. |
| 23 |
|
| 24 |
|
| 25 |
= Installation |
| 26 |
|
| 27 |
Nothing could be simpler: |
| 28 |
|
| 29 |
$ gem install --include-dependencies piston |
| 30 |
|
| 31 |
|
| 32 |
= Usage |
| 33 |
|
| 34 |
First, you need to import the remote repository location: |
| 35 |
|
| 36 |
$ piston import http://dev.rubyonrails.org/svn/rails/trunk vendor/rails |
| 37 |
Exported r4720 from 'http://dev.rubyonrails.org/svn/rails/trunk' to 'vendor/rails' |
| 38 |
|
| 39 |
$ svn commit -m "Importing local copy of Rails" |
| 40 |
|
| 41 |
When you want to get the latest changes from the remote repository location: |
| 42 |
|
| 43 |
$ piston update vendor/rails |
| 44 |
Updated 'vendor/rails' to r4720. |
| 45 |
|
| 46 |
$ svn commit -m "Updates vendor/rails to the latest revision" |
| 47 |
|
| 48 |
You can prevent a local Piston-managed folder from updating by using the |
| 49 |
+lock+ subcommand: |
| 50 |
|
| 51 |
$ piston lock vendor/rails |
| 52 |
'vendor/rails' locked at r4720. |
| 53 |
|
| 54 |
When you want to update again, you unlock: |
| 55 |
|
| 56 |
$ piston unlock vendor/rails |
| 57 |
'vendor/rails' unlocked. |
| 58 |
|
| 59 |
If the branch you are following moves, you should use the switch subcommand: |
| 60 |
|
| 61 |
$ piston import http://dev.rubyonrails.org/svn/rails/branches/1-2-pre-release vendor/rails |
| 62 |
$ svn commit vendor/rails |
| 63 |
|
| 64 |
# Vendor branch is renamed, let's follow it |
| 65 |
$ piston switch http://dev.rubyonrails.org/svn/rails/branches/1-2-stable vendor/rails |
| 66 |
|
| 67 |
|
| 68 |
= Contributions |
| 69 |
|
| 70 |
== Bash Shell Completion Script |
| 71 |
|
| 72 |
Michael Schuerig contributed a Bash shell completion script. You should copy |
| 73 |
+contrib/piston+ from your gem repository to the appropriate folder. Michael |
| 74 |
said: |
| 75 |
|
| 76 |
I've put together a bash completion function for piston. On Debian, I |
| 77 |
just put it in /etc/bash_completion.d, alternatively, the contents can |
| 78 |
be copied to ~/.bash_completion. I don't know how things are organized |
| 79 |
on other Unix/Linux systems. |
| 80 |
|
| 81 |
|
| 82 |
= Caveats |
| 83 |
|
| 84 |
== Speed |
| 85 |
|
| 86 |
This tool is SLOW. The update process particularly so. I use a brute force |
| 87 |
approach. Subversion cannot merge from remote repositories, so instead I |
| 88 |
checkout the folder at the initial revision, and then run svn update and |
| 89 |
parse the results of that to determine what changes have occured. |
| 90 |
|
| 91 |
If a local copy of a file was changed, it's changes will be merged back in. |
| 92 |
If that introduces a conflict, Piston will not detect it. The commit will be |
| 93 |
rejected by Subversion anyway. |
| 94 |
|
| 95 |
== Copies / Renames |
| 96 |
|
| 97 |
Piston *does not* track copies. Since Subversion does renames in two |
| 98 |
phases (copy + delete), that is what Piston does. |
| 99 |
|
| 100 |
== Local Operations Only |
| 101 |
|
| 102 |
Piston only works if you have a working copy. It also never commits your |
| 103 |
working copy directly. You are responsible for reviewing the changes and |
| 104 |
applying any pending fixes. |
| 105 |
|
| 106 |
== Remote Repository UUID |
| 107 |
|
| 108 |
Piston caches the remote repository UUID, allowing it to know if the remote |
| 109 |
repos is still the same. Piston refuses to work against a different |
| 110 |
repository than the one we checked out from originally. |
| 111 |
|
| 112 |
|
| 113 |
= Subversion Properties Used |
| 114 |
|
| 115 |
* <tt>piston:uuid</tt>: The remote repository's UUID, which we always confirm |
| 116 |
before doing any operations. |
| 117 |
* <tt>piston:root</tt>: The repository root URL from which this Piston folder |
| 118 |
was exported from. |
| 119 |
* <tt>piston:remote-revision</tt>: The <tt>Last Changed Rev</tt> of the remote |
| 120 |
repository. |
| 121 |
* <tt>piston:local-revision</tt>: The <tt>Last Changed Rev</tt> of the Piston |
| 122 |
managed folder, to enable us to know if we need to do any merging. |
| 123 |
* <tt>piston:locked</tt>: The revision at which this folder is locked. If |
| 124 |
this property is set and non-blank, Piston will skip the folder with |
| 125 |
an appropriate message. |
| 126 |
|
| 127 |
|
| 128 |
= Dependencies |
| 129 |
|
| 130 |
Piston depends on the following libraries: |
| 131 |
|
| 132 |
* yaml |
| 133 |
* uri |
| 134 |
* fileutils |