Ignore Files and Directories in Subversion

snubbed by Rennett Stowe

In the course of a project there are always files and directories that you don’t want to check in but which Subversion complains it doesn’t know anything about them.  So it makes sense to tell Subversion to ignore them, in other words, keep quiet. 🙂

The mechanism for doing this works okay but I wouldn’t say it’s perfect.

This is how I do it.

  1. Go to the directory where want to ignore a file or subdirectory.
  2. Issue the command
    svn propedit svn:ignore .
  3. Your editor then will be launched and you can enter one line at a time those files and/or subdirectories you want to ignore.
    some_file
    some_directory
  4. Commit your changes.
    svn commit -–depth empty

    Two things to notice.

    1. --depth empty argument

      only commit the propedit changes

    2. Committing your changes means everyone will end up ignoring these files and/or directories so make sure you are ignoring the right ones.
  5. If you don’t want to commit your changes you can revert them.
    svn revert .

For further reading please see Pete Freitag’s blog post Ignore Files and Directories in Subversion.

Comparison of DSP and DSPEL

ATG has two JSP tag libraries, DSP and DSPEL. Both have similar syntax but DSPEL allows you to use JSTL.

Here’s a simple comparison of how you would use DSP versue how you would use DSPEL to do a simple RQL query.

DSPEL

<dspel:droplet name="/atg/dynamo/droplet/RQLQueryForEach">
  <dspel:param name="repository" bean="/betweengo/Repository"/>
  <dspel:param name="itemDescriptor" value="Merchant"/>
  <dspel:param name="queryRQL"
    value="name EQUALS \"${requestScope['nm']}\""/>
  <dspel:oparam name="empty">
    No merchant with the name "<c:out value="${requestScope['nm']}"/>".
  </dspel:oparam>
  <dspel:oparam name="output">
    Name: <dspel:valueof param="element.name"/>
  </dspel:oparam>
</dspel:droplet>

DSP

<% String query = "name EQUALS \"" + request.getAttribute("nm") + "\"";%>

<dsp:droplet name="/atg/dynamo/droplet/RQLQueryForEach">
  <dsp:param name="repository" bean="/betweengo/Repository"/>
  <dsp:param name="itemDescriptor" value="Merchant"/>
  <dsp:param name="queryRQL" value="<%= query %>"/>
  <dsp:oparam name="empty">
    No merchant with the name "<%= request.getAttribute("nm") %>".
  </dsp:oparam>
  <dsp:oparam name="output">
    Name: <dsp:valueof param="element.name"/>
  </dsp:oparam>
</dsp:droplet>

Configuring Capistrano and Mongrel

For this article I used the chapter Setting Up A Development Environment in Agile Web Development with Rails, version 2.0, plus these two articles.

Capistrano working together with Mongrel allows you to deploy and restart Mongrel clusters quite nicely.

Configure Mongrel Cluster

First you need to configure a Mongrel cluster. Here is an example that creates three Mongrel instances starting at port 8000, listening on the local interface, 127.0.0.1.

$  mongrel_rails cluster::configure -N 3 -p 8000 -e production -a 127.0.0.1 \
   -c /usr/local/rails/production/current \
   -C /usr/local/rail/production/current/config/mongrel_cluster.yml

Here is how the created file looks like.

---
cwd: /usr/local/rails/production/current
log_file: log/mongrel.log
port: "8000"
environment: production
address: 127.0.0.1
pid_file: tmp/pids/mongrel.pid
servers: 3

Note that for testing purposes you should comment out the address line.

#address: 127.0.0.1

We specified listening only on the local interface for security purposes but for testing the cluster we need to access it directly via its remote IP address.

Setup Capistrano

Next you create a stub Capfile and config/deploy.rb.

$ capify .

Now you can get a list of all the tasks that are available and there quite a few.

$ cap -T

Next modify config/deploy.rb like in this example.

require 'mongrel_cluster/recipes'

set :application, "foobook"
set :repository, "http://example.com/svn/foo/trunk/foobook"

role :web, "192.168.3.17"
role :app, "192.168.3.17"
role :db,  "192.168.3.117", :primary => true

set :deploy_to, "/usr/local/rails/production"
set :mongrel_conf, "#{current_path}/config/mongrel_cluster.yml"
set :svn_user, "fkim"
set :svn_password, "fkim"
#set :user, "root"            # defaults to the currently logged in user
set :scm, :subversion         # defaults to :subversion
set :svn, "/usr/bin/svn"      # defaults to searching the PATH

Deploy using Capistrano

Now run setup which will create the directories remotely.

$ cap deploy:setup

Check dependencies.

$ cap -q deploy:check

Deploy for the first time.

$ cap deploy:cold

Everytime after you can deploy like this.

$ cap deploy

Starting and Stopping Mongrel using Capistrano

If you want to just start the mongrel cluster.

$ cap mongrel:cluster:start

If you want to just stop the mongrel cluster.

$ cap mongrel:cluster:stop

And that’s it.

Not that bad at all. Starting and stopping mongrel was the biggest issue for me. I realized that I did not need to create the spin script as suggested in the Using Capistrano with Rails article. If the mongrel configuration is correct then Capistrano will correctly start and stop it and you can use the above cap commands to test it.

Subversion Branching

Drippy

Drippy by jurvetson

Subversion branching and tagging is basically copying from one repository directory to another.

This article gives great instructions on how to branch and tag with subversion. This article is also good.

This is an example of creating a branch from the trunk.

$ svn copy svn+ssh://fkim@betweengo.com/home/fkim/svn/foo/trunk svn+ssh://fkim@betweengo.com/home/fkim/svn/foo/branches/stable

This is an example of tagging the trunk.

$ svn copy svn+ssh://fkim@betweengo.com/home/fkim/svn/foo/trunk svn+ssh://fkim@betweengo.com/home/fkim/svn/foo/tags/2012-03-06

To compare branches you can simply do something like this svn diff [path] [path]. For example:

$ svn diff http://foo.com/branches/stable http://foo.com/trunk.

To merge from a branch to the trunk you can use svn merge like this. Note that you need to have the trunk checked out.

$ cd trunk
$ svn merge -r 3:4 svn+ssh://fkim@betweengo.com/home/fkim/svn/foo/branches/stable/doc/html doc/html

To merge from the trunk to the branch you can try something like this.

$ cd branches/stable
$ svn merge svn+ssh://fkim@betweengo.com/home/fkim/svn/foo/trunk

You may want to use the --dry-run option when you first run the merge to see how it will go. There might be a lot of conflicts.

HOWTO Stop Being Prompted For Password in TortoiseSVN

Just as you can setup the Subversion client to not prompt for a password every time you communicate with the Subversion server in a similar but not so secure way you can do this with TortoiseSVN.

The easiest way to do this is to right click in Windows Explorer, select Tortoise > Settings. Then in the Settings window select Network. Then in the SSH client set use the Tortoise SSH client, TortoisePlink, to use your username and password. For example:

D:\TortoiseSVN\bin\TortoisePlink.exe -l foo -pw bar

Implement RSA Authentication Under SSH

To implement RSA authentication under ssh so that the user is not continually asked prompted for a remote-host password when using ssh, scp, or any programs using ssh underneath such as cvs and svn do the following.

  1. Create a public/private RSA key pair. This will be used for RSA authentication. When generating this RSA key pair don’t enter a passphrase otherwise you will always be prompted for it.
    $ ssh-keygen -t rsa
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/fkim/.ssh/id_rsa):
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/fkim/.ssh/id_rsa.
    Your public key has been saved in /home/fkim/.ssh/id_rsa.pub.
    The key fingerprint is:
    2a:59:54:3f:82:8f:79:92:1d:39:7b:62:02:68:97:e6 fkim@paltp1235
    
    $ cd .ssh
    $ chmod 400 id_rsa id_rsa.pub
  2. Copy the public RSA key to the remote host.
    $ scp -p ~/.ssh/id_rsa.pub  fkim@betweengo.com:~/
    Password:
    id_rsa.pub                                    100%  396     0.4KB/s   00:00
  3. ssh to the remote host and create an .ssh directory if it does not already exist.
    $ ssh fkim@betweengo.com
    Password:
    [box ~]$ mkdir .ssh
    [box ~]$ chmod 755 .ssh
  4. Append the public RSA key to the list of authorized keys.
    [box ~]$ cat id_rsa.pub >> .ssh/authorized_keys2
    [box ~]$ chmod 644 .ssh/authorized_keys2
  5. Log out and log back in to verify that you no longer need to enter your password.
    $ ssh fkim@betweengo.com
    [box ~]$

Note if this does not work it is sometimes because the ssh client cannot find the id_rsa file. It looks for it normally where it keeps the known hosts file. On most systems this is the default location for where it writes the id_rsa file. On one system I found that it was looking for the id_rsa file in C:\.ssh.

In some cases RSA authentication will not work and you will need to use DSA authentication. This article, SSH Logins Without Providing A Password, gives a good description of how to do this. The instructions are quite similar.

Subversion on Dreamhost

This post is a log of how I personally got Subversion running on Dreamhost using this post.

  1. Obtained the Subversion source from http://subversion.tigris.org/project_packages.html#source-release, compiled it, and put the binaries in my ~/bin directory.
  2. Added the Subversion binaries to my path by adding these lines to my ~/.bash_profile file.
    # Set PATH so it includes user's private bin if it exists
    if [ -d ~/bin ] ; then
      PATH="~/bin:${PATH}"
    fi

    For this change to take effect you either have to relogin or:

    $ . ~/.bash_profile

  3. Initialized new subversion repositories. For example:
    $ svnadmin create ~/svn/mk 
    $ svn mkdir \
        file:///home/fkim/svn/mk/trunk \ 
        file:///home/fkim/svn/mk/branches \
        file:///home/fkim/svn/mk/tags

    I am following the suggested way of organizing a Subversion repository.

  4. Imported the files into the subversion repository. For example:
    svn import ~/meetingkoreans.com file:///home/fkim/svn/mk/trunk/
    svn import ~/meetingkoreans.com svn+ssh://fkim@meetingkoreans.com/home/fkim/svn/mk/trunk/

    Note: I was having a strange problem when I tried to do an import and kept getting an already exists error.  It turned out the problem was because what I was trying to import was a link instead of the actual directory.  This might only be an issue on Cygwin.

  5. Checked the files out. To do this locally:
    svn co file:///home/fkim/svn/mk/trunk meetingkoreans.com

    To do this remotely:

    svn co svn+ssh://fkim@meetingkoreans.com/home/fkim/svn/mk/trunk mkrb