2.3. Populating the New Repository

At the end of this section, the Rails application directory will be registered with Subversion as a working copy of the code stored in the Subversion repository. Subversion has an import command that is often used to place existing code trees into a Subversion repository. However, adding code to a Subversion repository via import does not associate the existing code tree with the Subversion repository. You'd still need to create a working copy of your code someplace else on your hard drive.

2.3.1. Checking Out and Adding Files

To allow your existing code tree to become your Subversion working copy, you need to start by checking out a copy of the (currently blank) repository directory. Open a command prompt at the top level of your new Rails application — the soupsonline directory — and type the following command:

$ svn checkout "file:///<dir>/soupsonline/trunk" .
Checked out revision 1.

This command does the following:

  1. svn invokes the Subversion command line client.

  2. checkout tells Subversion which command to actually run. In Subversion, all a checkout does is make a working copy from a location in a Subversion repository and place it in a location on the local hard drive.

  3. The URL specifies the location of the repository.

  4. The . specifies the destination location — in this case, the current directory.

In this case, the repository is still empty, so nothing is actually copied. However, Subversion has now noted that the remote and local file systems have been associated with one another. If you look at your Rails directory from the command line, you'll notice that a hidden .svn directory has been added — that's where Subversion stores its information.

If you are used to a stricter source-control system like Perforce or ClearCase, the use of the word "checkout" in this context may be confusing. In those systems, a checkout is an operation performed on an individual file to grant a developer exclusive, locked access to that file until the developer is done making changes. In Subversion, you do not need to lock a file before starting to make changes to it, and a checkout is a command performed on an entire area of the repository to give the developer a copy of those files to begin development.

With the repository checked out, you can now add your Rails files to it as follows:

$ svn add --force .A         app
A         app/controllers
A         app/controllers/application.rb

[... A bunch of lines ...]

A         tmp/sockets
A         vendor
A         vendor/plugins

The add command, as you might expect, adds files to the Subversion repository, and the --force option causes Subversion to recursively descend through the file tree and add all subfolders and files, even those that might already be under source control.

2.3.2. What to Ignore

At this point, you are in good shape and could begin coding in earnest. However, there are a couple of details to take care of that will make your Subversion experience more pleasant. The basic rule of thumb for what files should be stored in a source control repository is that only files that are directly created by developers should be added. In general, you want to avoid adding files that are generated by the system — they take up unneeded room in the repository and add complexity to all your commits.

Within the Rails structure, this includes the log folder, the doc folder, and the tmp folder. At the moment, the only one of those folders that is populated is the log folder. Remove the existing files from the repository as follows:

$ svn revert log/*
Reverted 'log/development.log'
Reverted 'log/production.log'
Reverted 'log/server.log'
Reverted 'log/test.log'

The revert command takes the affected files out of the Subversion repository but leaves them in place locally. However, as it currently stands, Subversion will still know about the files in the log directory, and you might inadvertently add them at a later date. So you actually want to tell Subversion to pretend that the files in question don't even exist. You do this by setting a Subversion property on those files as follows:

$ svn propset svn:ignore "*.log" log
property 'svn:ignore' set on 'log'

This is the first of about three Subversion properties you'll encounter in this chapter. Subversion allows you to set any kind of property you want on files, but there are some pre-defined properties that have specific implications for Subversion's behavior. In this case, you're telling Subversion to ignore any file in the log subdirectory that ends in .log. Conveniently enough, that will keep Subversion from caring about anything that Rails logs. Even though you're executing this command locally, the property is set on the repository itself. Other developers who check out the repository will also have their log files ignored.

Similarly, you want Subversion to ignore the doc directory, because any documentation you place in there will be generated by rdoc. You also want it to ignore the tmp directory, because there's no point in putting temporary files in source control. Enter the following:

$ svn propset svn:ignore "*" doc
property 'svn:ignore' set on 'doc'
$ svn propset svn:ignore "*" tmp
property 'svn:ignore' set on 'tmp'

Later in the book, you'll find some other derived directories that you will want to have Subversion ignore.

2.3.3. Database Files in the Repository

There are a couple of other derived files that are worth addressing: the database setup file database.yml and the working schema file schema.rb. Although schema.rb is a generated file created by Rails during the database-migration process, no less a personage than David Heinemeier Hansson himself said that the file should be placed in source control anyway to allow somebody checking out the code for the first time to set the database up in one shot without walking through all the database migrations. Who am I to argue? You can leave schema.rb alone.

The issue with database.yml is a little bit different. Under normal circumstances, each developer will need to set up his or her own development environment pointing to his or her own local database with his or her own username and password. You certainly don't want every individual developer to be continually merging his or her database username and password up to source control and screwing up everybody else with the next update.

Now, for the purposes of this book, you could ignore the following — there's only one developer, and so the issue is less salient. However, there is a standard mechanism for managing this situation. You place a template version of the file in source control under a separate name, and remove and ignore the original file, as follows. Each developer is then expected to maintain their own local copy of the template.

$ cp config/database.yml config/database.yml.template
$ svn add config/database.yml.template
A         config/database.yml.template
$ svn revert config/database.yml
Reverted 'config/database.yml'
$ svn propset svn:ignore "database.yml" config
property 'svn:ignore' set on 'config'

Now, there's a database.yml.template in the Subversion repository, and everyone is free to copy that into database.yml and change it around to his or her heart's content because Subversion no longer cares about that file. One implication of this solution is that every checkout of the code will need to create a database.yml file before it can run. You'll need to pay particular attention to this when deploying your code to its runtime server.

2.3.4. Marking Executable Files

If your development team includes Windows developers as well as Linux or Mac OS X developers, you need to ensure that scripts intended to be executable have their file mode properly set on the UNIX-based operating systems. You do this by setting another Subversion property.

Within Rails, that's all the files inside the /script directory and its subdirectories, plus the dispatch files in the /public directory. The dispatch files are easy because they all have a common file name. You just do this:

$ svn propset svn:executable "*" public/dispatch.*
property 'svn:executable' set on 'public/dispatch.cgi'
property 'svn:executable' set on 'public/dispatch.fcgi'
property 'svn:executable' set on 'public/dispatch.rb'

Getting all the server files requires either some tedium to enter each of them separately, or some shell skills to get them all in one shot. Here's the whizzy UNIX way:

$ svn propset svn:executable "*" 'find script -type f | grep -v '.svn''
property 'svn:executable' set on 'script/about'
property 'svn:executable' set on 'script/breakpointer'
property 'svn:executable' set on 'script/console'
property 'svn:executable' set on 'script/destroy'
property 'svn:executable' set on 'script/generate'
property 'svn:executable' set on 'script/performance/benchmarker'
property 'svn:executable' set on 'script/performance/profiler'
property 'svn:executable' set on 'script/plugin'
property 'svn:executable' set on 'script/process/inspector'
property 'svn:executable' set on 'script/process/reaper'
property 'svn:executable' set on 'script/process/spawner'
property 'svn:executable' set on 'script/runner'
property 'svn:executable' set on 'script/server'

For those of you who are not twelfth-level UNIX gurus (I'm not, by the way), here's a quick explanation of what's going on here. find script -type f | grep -v '.svn' gives you a list of all files in the /script subdirectory and its subdirectories, which are actually files, not directories, and which are not hidden Subversion files. (If you try to do the more obvious svn propset svn:executable "*" script/*, Subversion will complain when it reaches the first subdirectory.) Those who are on Windows machines can either set the property on each of those individual files (boring), or write a short Ruby script to set the properties automatically.

2.3.5. Commiting Changes

Although you've made a number of changes to the local copy of the repository, none of them has actually been passed back to the mother ship yet. To get those changes back to the Subversion server, you need to commit them as follows:

$ svn commit -m "further project setup"
Adding         README
Adding         Rakefile

Adding         app

[... A lot of lines ...]

Adding         tmp/sockets
Adding         vendor
Adding         vendor/plugins
Transmitting file data
Committed revision 2.

The changes have now been sent back to the server, and other developers who check out or update their repositories will now see them.

Notice that Subversion tells you the status of all the files that are being changed before it actually transmits the file data at the end. Subversion uses an all-or-nothing model when your commit affects more than one file. The system validates that all the files you want to change are without conflict with other developer's changes. Only if all of your files are clear does Subversion send your changes to the client. This prevents the central repository from being placed in an inconsistent state caused by taking only part of a developer's change set.

The secret to successfully using Subversion in Agile Rails development is to commit often. Really often. Constantly. Nearly every time you create a new unit test and pass it, that's how often. In a tight, test-driven loop, that could easily mean committing changes every 15 minutes to half-hour. If you are used to a heavier-weight source control system, that may seem hideously unworkable, but in Subversion, a commit is a quick operation, especially if you perform it so often that you're sending only a few files back to the server at a time.

There are many benefits to continuous commits. Most obviously, it's almost impossible to lose significant amounts of work.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.176.194