Getting Your Rails Project into Subversion

Problem

You want to get your Rails project into a Subversion repository but don't want your logging and configuration files included.

Solution

Create a Subversion repository, and confirm that the repository was created:

/home/svn$ svnadmin create blog

/home/svn$ ls blog/
conf dav db format hooks locks README.txt

Change to your Rails project directory:

/home/svn$ cd ~/projects/blog; ls
app components config db doc lib log public Rakefile README script test vendor

Import the entire project. The . in the following command is critical. It specifies to "import everything within this directory":

~/projects/blog$ svn import -m "initial import" . \
> file:///home/svn/blog
Adding test Adding test/unit Adding test/test_helper.rb
...
Adding public/favicon.ico Committed revision 1.
~/projects/blog$ 

Now, delete the initial project files:

~/projects$ cd ..; rm -rf blog/

If this step scares you, move your files somewhere else until you're satisfied that you won't need them any more. But trust me: you won't. You can now check out your versioned project from its repository:

~/projects$ svn checkout file:///home/svn/blog
A blog/test A blog/test/unitL
...
A blog/public/favicon.ico Checked out revision 1.
~/projects$

Now, move back into the project directory, and remove the logfiles from the repository using Subversion; then commit the removal:

~/projects$ cd blog
~/projects/blog$ svn remove log/*
D log/development.log D log/production.log D log/server.log D log/test.log
~/projects/blog$

~/projects/blog$ svn commit -m 'removed log files'
Deleting log/development.log Deleting log/production.log Deleting log/server.log Deleting log/test.log Committed revision 2.
~/projects/blog$ 

Next, instruct Subversion to ignore the logfiles that get recreated by Rails:

~/projects/blog$ svn propset svn:ignore "*.log" log/
property 'svn:ignore' set on 'log'
~/projects/blog$

Now, update the log directory, and commit the property change:

~/projects/blog$ svn update log/
At revision 2.
~/projects/blog$ svn commit -m 'svn ignore new log/*.log files'
Sending log Committed revision 3.
~/projects/blog$ 

Set up Subversion to ignore your database.yml file. Save a version of the original file for future checkouts. Then tell Subversion to ignore the new version of database.yml that you'll create, which includes your database connection information.

~/projects/blog$ svn move config/database.yml config/database.orig 
A config/database.orig D config/database.yml
~/projects/blog$ svn commit -m 'move database.yml to database.orig'
Adding config/database.orig Deleting config/database.yml Committed revision 4.
~/projects/blog$ svn propset svn:ignore "database.yml" config/
property 'svn:ignore' set on 'config'
~/projects/blog$ svn update config/
At revision 4.
~/projects/blog$ svn commit -m 'Ignoring database.yml'
Sending config Committed revision 5.
~/projects/blog$ 

Discussion

One great way of practicing DRY is to ensure that you'll never have to recreate your entire project because of a hardware failure or a mistaken rm command. I highly recommend learning and using Subversion (or some form of revision control) for every nontrivial file you create, especially if your livelihood depends on these files.

The solution runs through creating a Subversion repository and importing a Rails project into it. It may seem a little nerve-racking to delete the project that you created with the Rails command prior to checkout, but until you check out a fresh copy of the project from the repository, you're not working with versioned files.

Subversion's designers realize that not all the files in your repository are appropriate for versioning. The svn:ignore property, which applies to the contents of a directory, tells Subversion which files should be ignored by the common commands (svn add, svn update, etc.). Note that the svn:ignore property is ignored by the --force option of svn add.

Subversion also integrates tightly with Apache. Once you've installed the mod_svn module, you can check out or update your project over HTTP. These features give you an easy way to deploy your Rails application to remote servers. A command such as svn checkout http://railsurl.com/svn/blog run on a remote server, checks out your current project onto that server. mod_svn is often used in conjunction with SSL or mod_auth for security.

See Also