Archive for November, 2007.

svndo to do less svn typing

I hack a very small ruby script that allow me to apply any command to my files that I use to manage with the Subversion status subcommand.

Let’s go with an example.
I have made an error deleting files under revision with the unix rm instead of using the svn rm command.

My status now looks like this:

$ svn st
!      db/migrate/015_create_tasks_and_their_relationships.rb
!      db/migrate/010_create_users.rb
!      db/migrate/020_create_categories_and_their_relationships.rb
!      vendor/plugins/exception_notification
!      README
$

Subversion ‘!’ status means that the file is missing, but is in revision. We need to do a svn rm on each of those files.

That’s where svndo come to the rescue. svndo takes as first argument the status reported by the svn st command (’!’ in our example). The arguments 2..n are the command which will be executed on the files matching the giving status.

Let’s try it

$ svndo ! svn rm
svn rm db/migrate/015_create_tasks_and_their_relationships.rb
svn rm db/migrate/010_create_users.rb
svn rm db/migrate/020_create_categories_and_their_relationships.rb
svn rm vendor/plugins/exception_notification
svn rm README
$

What do we got here? svndo shows us each files matching the ‘!’ status and the status is replace by the command that we pass as the last the arguments (2..n). Those commands are not executed until you pipe it to a shell interpreter.

Let’s try it!

$ svndo ! svn rm | sh
D         db/migrate/015_create_tasks_and_their_relationships.rb
D         db/migrate/010_create_users.rb
D         db/migrate/020_create_categories_and_their_relationships.rb
D         vendor/plugins/exception_notification
D         README
$

That’s it! Subversion has deleted your files from the current revision. I found it very useful to add new files and revert changes. You can use svndo to match every svn status code e.g. M ! ? ~ A D and so. You must escape those who will be interpreted by your shell.

I got now problem to use the special bash character ? and ! as the first argument. I only had to do an alias to match most effectively the ~ character, because it’s interpreted by the shell and cannot be pass as-is as an argument (You must escape it)

$ alias svndo~=’svndo ~’

So I can now only use

$ svndo~ some command

instead of

$ svndo \~ some command

*** Update: After Marc-André has posted a comment notifying me the script wasn’t working, I realize that I’ve messed up with regular expressions’ backslashes when posting the code. Thank you Marc-André for your refactoring, your code looks like Ruby code, while mine looks a bit like bash. So I’ve been inspired by you to post that new code. It do exactly what it was doing before, but now you can use the $ character in your command to be replace by the file name who the status is associated with.

It becomes now more flexible.

$ svndo ? mv $ /somewhereelse

That is the svndo script I was talking about.

#!/usr/bin/ruby -w

status, *cmd = ARGV

`svn st`.each do |line|
  if matches = /^#{Regexp.escape(status)}\s+(.*)$/.match(line)
    tmp = cmd.map {|c| c.gsub(/\$/,matches[1])}
    tmp << matches[1] if tmp == cmd
    puts tmp.join(‘ ‘)
  end
end

Refactor this code at: refactormycode.com

Filed under: tools | Comments (5)

Phil Rathe.com is powered by WordPress, theme: Clean Royal