| [ Team LiB ] |
|
27.3 Change ManagementAnyone who's worked with a team on a Web application knows the pain of dividing the tasks among team members. For small teams, it usually works to shout over cubicle walls. For larger teams, you may need a manager to coordinate the development process. However, Gantt charts don't seem to fit the shoot-from-the-hip mentality of the typical Web programmer. It feels natural to wander through the files of the project, changing them as you tackle a problem without worrying if someone else is editing them. Sometimes changes are lost, but people cope by keeping backups. Alternatively, team members can warn each other not to touch some files for short period. If a file is destroyed, you may hunt through archives to find an older version. Developers can guard against losing newer changes by keeping local copies of every change they make, but it feels like a big hassle. Web sites evolve through many iterations. The team works on a project, and it integrates the changes when it finishes. There are two typical methods for putting the changes into production. The brute force method involves replacing all application files. This ensures that you don't miss any files. Alternatively, you can copy just the new files and the files that changed. Instead of trying to control the source code through ad hoc activities, consider using a source code control system. Popular among C programmers, source code control works well with most programming languages. The PHP development team uses source code control to coordinate the hundreds of people contributing to PHP, as do many open-source projects. The overwhelming favorite source code control system among open-source developers is CVS (concurrent versions system). CVS is an open-source project itself. At its core is the functionality of the diff and patch utilities that are part of most operating systems. You can use diff to compare two files and find the differences. The patch utility can apply the differences to a third file to bring it up to date. CVS keeps a repository for a project that includes every incremental change to every file. Users interact with the repository by running shell commands on the server. Remote users must use a remote shell, which is rsh by default. It's wise to avoid rsh and use ssh if you can, as rsh sends passwords and traffic through the net unencrypted. Some open-source projects provide a read-only account for grabbing a current development version without allowing changes. After checking out files from a repository, a developer may make any number of changes to files without disturbing any other developer. Under normal use, CVS does not grant exclusive use of a file to one user. These are called unreserved copies. Developers work on files concurrently, and CVS takes care of tracking changes as they are checked in. CVS distributes changes on demand to developers. The changes integrate into source files even if the developer updates a file with changes that aren't checked in. CVS does support reserved copies, but most users find them unnecessary. In most contexts, CVS can resolve differences between files without human intervention. When conflicts do occur, CVS alerts the developer and marks conflicting code plainly. Although I present a brief tutorial here, find Karl Fogel's book, Open Source Development with CVS <http://cvsbook.red-bean.com/>. The chapters that deal with CVS specifically are free to download, but I recommend buying the book if you decide to use CVS. Beyond the mechanics of CVS itself, it documents how CVS fits into the development process. Also, keep an eye on the Subversion project <http://subversion.tigris.org/>, which aims to build a CVS replacement. If you're running Linux or FreeBSD, CVS may be installed already. If not, use a package manager appropriate for your system, such as RPM or apt-get. If you're using Windows, you can run CVS clients with no problem, but CVS servers don't work well. You can set up a server that allows local CVS usage with which to experiment, but you need a UNIX operating system to use CVS seriously. The CVS Web site <http://www.cvshome.org/> has links for downloading binaries for many operating systems. You can also download source code and compile it yourself, but I won't go over those steps. The compilation follows typical steps because it uses autoconf. See the installation instructions in the source code archive. CVS requires just one binary that's typically installed as /usr/local/bin/cvs. This is the client application, but it also makes changes on the server through a remote shell. To start using a host as a CVS server, you only need to create a repository. All CVS functionality goes through the cvs command-line utility. The init command to cvs creates a new repository. The -d option sets the path to the repository. CVS creates this directory and places several files inside it. Figure 27.1 is a capture from my shell as I created a new repository and listed the contents. Figure 27.1 Creating a CVS repository.# cvs -d /home/cvshome init # ls -R /home/cvshome /home/cvshome: CVSROOT /home/cvshome/CVSROOT: Emptydir config,v loginfo rcsinfo checkoutlist cvswrappers loginfo,v rcsinfo,v checkoutlist,v cvswrappers,v modules taginfo commitinfo editinfo modules,v taginfo,v commitinfo,v editinfo,v notify verifymsg config history notify,v verifymsg,v /home/cvshome/CVSROOT/Emptydir: I created this directory as the root user. This doesn't allow anyone else to use the repository. I created a group named cvs in /etc/group and used chgrp to allow users in this group to use the repository. Traditionally, CVS uses a password server process on port 2401 for connections. Installation involves adding the server to inetd's list of daemons. CVS manages a set of users and passwords separate from those in /etc/passwd with the pserver daemon. All commands through the password server execute as a single user. Using pserver is good for public repositories, such as those for open-source projects. If you're using it for your internal team, don't bother with it. It's complicated and less secure than SSH. CVS uses rsh by default. Set the CVS_RSH environment variable to switch it to SSH. For example, I added the lines in Figure 27.2 to my .bash_profile file. Figure 27.2 Additions to bash profile.#make sure cvs uses SSH CVS_RSH=ssh export CVS_RSH To access the CVS server remotely, you must use special notation. CVS uses colons to separate information about the authentication method and the hostname of the server. For example, :ext:leon@192.168.123.194:/home/cvshome matches my repository. In this mode, CVS will prompt you for your password each time you execute cvs. Some people find this annoying, so they generate an authorized key. This is a function of SSH, not CVS. You can read about this on the OpenSSH site <http://www.openssh.org/>. Use the import command to create a project inside your repository. This command creates a directory in the repository and copies all the files in your current directory recursively. For example, I started a new project in a directory called myproject. Inside the directory is a single PHP script. To create a directory in the repository, I issued the commands in Figure 27.3. Note how I used backslashes to keep the lines from wrapping. The -d option appears again, specifying the path to the repository. The -m option applies to the import command. It sets a comment to associate with the CVS action. This comment can be as long as you need, and if you leave out the -m option, CVS will launch an editor for you. The last three commands specify the project name, the vendor tag, and the release tag. These names are up to you. The project name will be the name used for the directory on the server, and it's how you refer to the project, so choose a short name. What you choose for the vendor tag and the release tag aren't important usually. I use the name of the company and start by default. Figure 27.3 Importing a project into CVS./tmp/myproject> cvs \ -d :ext:leon@192.168.123.194:/home/cvshome import \ -m 'starting my project' myproject mycompany start leon@192.168.123.194's password: N myproject/index.php No conflicts created by this import /tmp/development/myproject> CVS created a directory on the server, but it hasn't changed any of the files I imported. To work with the files in the repository, you must make a checkout. The checkout command copies files from the server to your local machine. It also creates directories named CVS in every subdirectory of the project. These subdirectories keep track of the status of the files and where they came from. After making a checkout, you no longer need to specify the path to the repository. CVS will find it in the CVS directory. Figure 27.4 shows how I made a checkout of my new project. Figure 27.4 Checking out a project from CVS.~> cvs -d :ext:leon@192.168.123.194:/home/cvshome \ checkout myproject leon@192.168.123.194's password: cvs server: Updating myproject U myproject/index.php ~> Once you checkout the project, you can start editing files. Other developers can make their own checkouts. When you finish working on a file, use a commit command to integrate your changes into the project. CVS examines all the files in the current directory and in any subdirectories. It then coordinates with the server to find changes and apply them to the server's copies of the files. Figure 27.5 shows the results of making a commit. You and other developers can commit changes as often as you wish, and the server keeps the most current version at all times. Your own files do not receive updates unless you ask for them explicitly with the update command. CVS will check all files recursively. If the server has a newer version, it applies the changes to your files. Your changes are not lost. CVS does its best to merge your changes with those committed since you last updated your files. Figure 27.5 Checking changes into CVS.~/myproject>cvs commit -m 'added navigation code' leon@192.168.123.194's password: Checking in index.php; /home/cvshome/myproject/index.php,v <-- index.php new revision: 1.2; previous revision: 1.1 done ~/myproject> Updating your files often helps keep your work coordinated with other developers and avoids conflicts. Conflicts occur when two developers disagree on a particular part of the source code. For example, consider the following sequence of events. In the beginning state, a line in the source code states $a=3. Later, another developer changes the line to $a=5 and commits the file. This sets the official version of the line. If you issue an update before changing this line, you will receive the change with no conflicts, and you can change it yourself. However, if you change the line before issuing an update, you will encounter a conflict. CVS marks the conflicting sections of code and inserts both versions in the source code. To resolve the conflict, you must edit the file and choose one version or the other. Regularly updating files helps avoid conflicts. It also alerts you to changes in files. As you issue an update, CVS notifies you of which files have changed since your last update. You can also configure CVS to email changes to a mailing list. If all developers subscribe to the mailing list, they can monitor activity on the project. This isn't a substitute for proper communication among team members, but it reduces the need to consult constantly with each other about who's editing which file. When you're ready to make the project live, you have two options. If releases are infrequent, you may wish to make an export of the project and replace existing files on the production server. Use the export command to make a checkout that contains no CVS directories. For a site that gets frequently updated, I prefer making an ordinary CVS checkout on the production server. When making a new version of the site live, you need to log in to the production server and issue an update command. This is faster and less hassle than replacing all existing files. It also avoids those errors associated with missing files or incorrect paths. |
| [ Team LiB ] |
|