Concurrent Squeaking with DVS
Traditionally, source code in Squeak is managed though Projects and
changesets. Although this works moderately well for single-person
development, it is cumbersome and unreliable for concurrent
development within even a small team: there is no easy way to merge
concurrent changes or to resolve conflicts between them, method
versions are only tracked in each developer's local image, and keeping
multiple images in sync generally involves an adhoc flurry of emailed
changeset files. It also takes discipline and effort when working with
multiple related projects to ensure that the changes are all sorted to
the proper changeset and that none of them gets lost.
DVS addresses this last problem by introducing the simple PackageInfo
categorization system, and the rest through integration with existing
source code management systems. If you're not familiar with
PackageInfo, please read up on it first. Using DVS DVS provides a
simple but convenient user interface for managing your packages. Once
you've filed in the PackageInfo and DVS changesets, evaulate
PackagePanel open to bring up an instance of the UI. The window has a
row of buttons at the top, each of which has balloon help. The three
most important buttons, however, are Add, FileOut, and FileIn.
The Add button allows you to register a new package with DVS. When you
press it, DVS will ask you for the name of the package - fill this in
according to the PackageInfo naming conventions. The package will then
appear in the list pane, along with the path to its representation on
the filesystem (you can use the Edit button to change the directory it
uses).
Pressing the FileOut button will save the entire package (classes,
methods, and extension methods) to a .st file on disk. Pressing the
FileIn button will load the same file back in. What's interesting
about DVS, however, is that this doesn't perform a normal fileIn.
Instead, it parses the file and compares its contents against the
version of the package currently in the image. It then generates a
changeset with the differences between the two (including both
additions and removals of classes and methods), and loads that. This
means that your image code ends up exactly in sync with the file on
disk, with no stray methods or classes lying around. Integrating with
CVS Once you have the ability to define a package, file it out to
disk, and synchronize your image with a fileOut, using a standard
source code management system like CVS is just a matter of process.
The general idea is the following:
* It is the responsibility of DVS to keep the packages in the
image synchronized with the corresponding files on disk.
* It is the responsibility of CVS to manage versions, updates,
merges, and commits of these files.
Therefore, you must always make sure to
* File out from DVS immediately before updating or committing to
CVS.
* File in to DVS immediately after updating, merging, or reverting.
There isn't space here to give full instructions for setting up and
using CVS, but I'll give you a short example of how the process works.
The same principles should apply to most SCM systems.
* Let's say Alice is has started to write the SqueakLink
framework. She's done some work on it in her local image, but
now wants to develop it together with her coworker Bob. She can
use the DVS UI to easily file out what she has so far:
o She clicks "Add" to register a package. Her class and
method categories all start with "SqueakLink", so she types
that in when asked for the name of the package. o By
default, the package is set to be saved to the default
squeak directory. Alice wants it to go into her CVS working
copy, so she hits "Edit" and finds her way to
/home/alice/cvs/squeak. The package's path now reads
"/home/alice/cvs/squeak/SqueakLink.st". o She clicks the
"FileOut" button, and SqueakLink.st is written to disk.
* Now she needs to add this file to the repository. In a shell,
she changes directory to her working copy at ~/cvs/squeak, and
gives CVS the commands to add the file:
$ cvs add SqueakLink.st $ cvs commit
* Bob wants to load it into his image. He issues a cvs update in
his working copy to bring in the SqueakLink.st file, and then
turns to his PackagePanel. He hits "Load," then finds and
selects SqueakLink.st in the file list, and it gets filed in and
added to the package list.
* Bob pokes around in the framework, and notices a bug. He fixes
it, and wants to commit his changes back to the repository:
o Bob makes sure the SqueakLink package is selected in
PackagePanel's list, and clicks the FileOut button. This
overwrites the file in his working copy with his fixed
version. o In a shell, he changes directory into his working
copy and issues cvs commit SqueakLink.st. The repository now
contains his change.
* Meanwhile, Alice has been continuing to work on the framework.
She's added a couple of new features and wants to commit them.
So she files out and asks CVS to commit. CVS informs her that
(due to Bob's commit) her working copy is no longer up to date,
so she asks CVS to update it for her:
$ cvs update SqueakLink.st
It's very important that she filed out her modifications before
asking CVS to update. Always make sure that you have filed out
before performing any CVS operations.
* The fileOut format used by DVS is designed to reduce spurious
conflicts when used with CVS, so Bob's fix likely won't conflict
with Alice's additions. Instead, CVS will be able to cleanly
merge the version Bob committed to the repository with Alice's
file on disk. If there were conflicts, CVS would notify her of
this and she would manually resolve them by modifying the
SqueakLink.st file in a text editor or with a merging
application such as xdiff. Either way, her working copy will now
contain the fix as well as her new code.
* Alice now clicks the FileIn button on the DVSPanel, and her
image is synced with the working copy: in this case, Bob's fix
is applied. She makes sure that her additions still work with
that change, and then tells CVS to commit.
* Finally, Bob asks CVS to update his working copy; he hasn't made
any more changes in the meantime. He can ask DVS to file in and
his image will now have Alice's changes.
This is a very simple, straightforward example of CVS usage. However,
the normal range of CVS operations can be applied to Squeak code just
fine: branching, tagging, joining, and so on. The ability to properly
update an image to a new version of a module is useful in other
situations as well: I routinely update the code of running server
images after making modifications to a local image, without
interrupting user sessions, by sending file outs to the server and
asking DVS to fileIn through a web interface.
The latest version of DVS is always available out of CVS from the
"seaside" project at sourceforge.net, as part of the "aubergines"
module; see http://sourceforge.net/cvs/?group_id=53430 for more
information.