Lecture 5, Groupware
the notes for 22C:196:002 (CS:4908:0002)
A compiler development project is a large effort, typically more than one person would want to do. As a result, we are naturally interested in tools to help a group of cooperating programmers work together on a large project. Over the years, two dominant approaches to group development have emerged, both of which classify broadly as version control systems. Any version control system will keep a record of previous versions of a program and allow you to roll back if you want to see earlier versiions, and all of them maintain some kind of change log.
One class of version control system allows individual team members to check out files, work on them, and then check in their changes. If one team member has a file checked out, the other team member must wait until it is checked in before checking it out. In effect, this approach enforces mutual exclusion locks on each file -- locks that are held by programmers.
The second approach eliminates mutual exclusion. If two team members happen to check out the same file, they are both allowed to make changes. When a file is checked in, the version control system checks to see if there have been other changes made to that file since it was checked out. If the changes do not lead to conflicts -- for example, if one team member edited lines 10 through 15 while the other team member made changes after line 20, the version control system simply merges their changes. If a conflict is found, for example, both programmers made changes to line 7, then the version control system informs one of the programmers (the one who checked in later) about the conflict, and allows them to resolve it.
Subversion, the tool we will be using, works this way. Subversion is widely used, both from the command line, and from various GUI tools. Subversion is installed on the departmental Linux machines.
To install the basic command-line Subversion tools on a Raspberry Pi, type this shell command:
apt-get install subversion
Subversion is completely documented on line. The book Version Control with Subversion is available as a single HTML document, as a hyperlinked web site, and as a PDF download. It is not a comfortable starting point for the beginner, but it is an excellent reference.
From the Unix or Linux command line, Subversion is accessible through the svn command. The svn help command lists all of the subsidiary Subversion commands. One of them, used to add a file to the Subversion project, is svn add. To get more information about that command, type svn help add. This works for all of the subsidiary Subversion commands, but again, it is not a good starting point.
A Subversion repository has been created for this class at
Yes, it looks like the URL of a password protected web site, but that is only because the Subversion system uses the web's HTTP protocol to upload and download files, and it uses the Apache web server's security mechanisms. Attempting to view this site using a web browser, even if you type in the correct user name and password (your own, since all students in this class have accounts on the departmental servers), you will not see much of interest.
To connect Subversion to this repository, issue the following shell command while in your home directory, with your own user name substituted for the string HAWKID:
svn checkout --username HAWKID https://svn.divms.uiowa.edu/repos/c_196_jones
This will work without the --username option if you are working on a machine where you have already signed in under your HawkID, for example, if you are connecting to Subversion from a departmental server. If you are on a Raspberry with the default user name, relying entirely on physical security for access control, you need to type it.
On typing this command, Subversion will prompt you for your password. Use your HawkID password unless your password on linux.cs.uiowa.edu differs from that. Once authenticated, Subversion will create a new directory in your home directory (assuming that was the current directory) called c_196_jones. That directory will appear to be empty except for a file called README, and, if everyone follows the rules, one file per project, the root directory for that project.
In fact, there is much more there. If you do the ls -a command while in the new directory, you will see a hidden directory called .svn -- this directory holds all of Subversion's information about your project. Among other things, it holds the URL above, so you never need to type in that long command ever again, and it holds your password, so you never need to type that again.
Here is a quick list of the Subversion commands you will be using regularly. These are more fully documented under the svn help command, and in Version Control with Subversion.
Note: Only add the source files for your project to the Subversion repository. Object files and executable files should stay private. This way, if one team member is comiling their code on a Raspberry for the ARM processor and another is compiling and debuging on an Intel x86 machine, there will be no conflicts (so long as the code does not use machine dependent features).
As a rule, do svn update in your project's subdirectory before you try to use make to test your code.
As a rule, don't svn update the root directory for our project, c_196_jones. It will take lots of time and disk space because you will get copies of every project in the class, and that will tempt you to read code by people outside your project. Note that all Subversion actions are logged!
Note: The only files committed are those that have been registered with Subversion using svn add. As a result, your object files and any notes you happen to be keeping to yourself will not be stored in the archive or shared with others on the project.
Note: The editing session for the log message will be opened using the editor specified by the SVN_EDITOR shell variable. This shell variable is traditionally set in the shell's .rc file (on the departmental Linux system, this will be .tcshrc. On a Raspberry, .bashrc). If you don't set this variable, Subversion may use an editor you don't know.
In summary, the normal minimum subversion session will go something like this, with PROJECT changed to be the name of your project:
cd c_196_jones/PROJECT svn update -- edit file FFF svn commit
Commit your changes! The most common cause of trouble in a project comes when participants don't commit their changes frequently enough. If two people are working on related parts of a project and one of them does not commit changes, the other one will never benefit from those changes. The longer you wait between commits, the more likely your changes will be to conflict with the changes made by someone else.
Do not check out a file and edit it for days before committing your changes. Someone else will very likely make other changes and commit them. The longer you hold a file before committing, the more likely it is that there will be changes that conflict with what you are doing. It is good manners to work in small increments, using update to check out the current version and committing your changes frequently.
Test before you commit! If you're changing source code, at the very least, get it syntactically correct. Once a particular source file reaches the point where it can be compiled, don't commit broken versions of that code. In projects with makefiles, run make before you commit.
If you must commit a file with known syntax errors, include appropriate bug notices to attract attention to them and take responsibility in your log update, saying that you're committing code known to contain syntax errors.
Acknowledge bugs! Within any development group, develop a standard form of comment used to acknowledge bugs. For example, the text =BUG= in a comment with an explanation of the error (as much as it is understood) or a note about the unfinished work that ought to replace the comment. This way someone looking for work can use the grep =BUG= *.c command to see all the comments that invite their attention. When you find something that is broken and needs fixing, if you can't fix it on the spot and there is no =BUG= notice, add one. When you fix a bug, remove the bug notice.
Be polite! Ask before you make major changes to code someone else wrote. Discuss alternatives. E-mail is handy for this, but for small things treat the code itself as a communication channel. On the flip side, be forgiving. If someone finds and fixes a bug in your code, they're not interfering with your code, they're helping.
Take responsibility! Be accurate but concise in your log messages. The project is a group responsibility. If you find something that you can fix, fix it, don't delay to get permission. Time spent passing blame around, getting permission, and creating organization structure is time wasted.
Keep the Subversion repository clean! Don't let Subversion know about object files and executables. This is one good reason to make sure your makefile includes support for make clean.
One of the most interesting Unix shell commands is grep. Type
grep expression filenames
and you will see a listing, on the terminal window, of all lines of text in the indicated files containing the expression. The expression can be as simple as a word, or it can be a regular expression (in the sense defined by Unix, which is not quite the same as the sense defined by automata theory). The example above,
grep =BUG= *.c
searches all of the C source files in the current directory to find lines containing the text =BUG=.
One thing to note: The utility of grep drops dramatically if you get in the habit of writing very long lines. Just because you have a video monitor on your computer that allows you to maximize windows to hole lines 500 characters long does not mean you should use all that width. Keep your lines short, and the output of GREP is far more useful.
The C style guidelines I recommend ask you to keep all source lines under 80 characters long -- not because old punched cards were 80 characters wide, but because people have a hard time scanning long lines of text. Newspapers don't print text the full width of a sheet of newspaper, they divide it into columns. The reason is one of readability.