Go to the first, previous, next, last section, table of contents.

4. Basic Version Control Functions

This chapter describes how to perform basic version control functions using Pastwatch in more detail. The description is geared towards users who are familiar with other version control systems like CVS. To help with the transition to Pastwatch, we'll try to give a similar CVS command where applicable. Throughout this chapter, we illustrate the concepts with an example project named myproject which has one administrator named Alice and two developers named Bob and Cliff.

4.1 Pastwatch Projects

Pastwatch performs version control for projects. Each Pastwatch project has a number of project members and one project administrator. Each project also has a file system directory that is under version control. The following illustration shows the parts of a Pastwatch project:


This Pastwatch project currently contains three files and one subdirectory. The administrator is named Alice and the two project members are Bob and Cliff. As project members, Bob and Cliff can add, remove and edit the project files. As administrator, Alice may add new members to the project.

Pastwatch uses public key authentication, so the project administrator and project members each have their own individual key pairs. The administrator uses her secret key to alter the list of project members. A project member may have one or more local replicas, one for each computer he uses. Each local replica has a key pair that pastwatch uses to commit changes to the repository. Each project member uses a member key pair to add local replica keys to their person list of replicas.

Each Pastwatch project stores one project. For example, if you were developing two separate pieces of software: a word processor and web browser, each would be stored in a separate Pastwatch project. Each Pastwatch project contains a single logical project. This is different from CVS because you can store many different software projects in a single CVS repository.

4.2 Creating a New Project

4.2.1 Initializing the Project

pastctl is a utility that helps administrate Pastwatch projects. The command "pastctl create <projname>" creates a new administrator key pair and an empty project with the new key pair. The project has no members, and contains no data. For example, to create a new project named myproject, Alice would execute the command:

     alice% pastctl create myproject
     Creating new key: project.key.48859#1 (Rabin)
            Key Label: myproject
     wrote key: /tmp/project.key.48859
     new project ID: yKSwpZkikKz+reTV9z2a28W2F5Y

The pastctl output says that the new project is labeled myproject and its project ID is: yKSwpZkikKz+reTV9z2a28W2F5Y. myproject is just a label for the project. The real identifier for the project is yKSwpZkikKz+reTV9z2a28W2F5Y.

The project ID is an important value. Pastwatch must have the project ID to read the project repository. Luckily, Pastwatch users do not need to memorize the project ID. It is stored as the symlink: $PASTWATCH_ROOT/myproject/project.id. The secret key which allows Alice to add project members is written to $PASTWATCH_ROOT/myproject/project.key.

     alice% ls -l $PASTWATCH_ROOT/myproject
     total 2
     lrwxr-xr-x  1 alice  wheel   32 Mar 16 10:20 project.id -> project:yKSwpZkikKz+reTV9z2a28W2F5Y
     -rw-------  1 alice  wheel  602 Mar 16 10:20 project.key

Since Pastwatch uses the project ID to name the repository, the project label is not very significant. Pastwatch only uses the project label as a place to store the project ID. Another person may create another project with the same label and their project will not conflict with Alice's project. This is because their project identifier will be randomly chosen and thus unique.

It is safe to ignore the rest of the pastctl create output.

CVS Equivalent:

     alice% mkdir /home/alice/CVSRepository
     alice% cvs -d /home/alice/CVSRepository/ init

4.2.2 Adding Members

Only project members may make changes to files in a Pastwatch project's repository. It is the project administrator's responsibility to add members to the project. The project administrator is not a project member by default; she must add herself as a member if she wants to make changes to the repository files. Adding the Administrator as a Member

In our example, Alice is the project administrator. To add herself as a project member, she uses the "pastctl addmember" command. This command generates a member key pair for Alice and adds her as a project member. The hash of Alice's member public key is iFUG7VF60eLb10b2awUBgw-GKL0, and the secret key is stored in the file: key.iFUG7VF60eLb10b2awUBgw-GKL0.

     alice% pastctl addmember alice myproject
     Creating new key: member.key.12378#1 (Rabin)
            Key Label: myproject
     wrote key: /tmp/member.key.12378
     new member: alice, iFUG7VF60eLb10b2awUBgw-GKL0

     alice% ls -l $PASTWATCH_ROOT/myproject
     total 4
     -rw-------  1 alice  wheel  607 Mar 16 10:22 member.iFUG7VF60eLb10b2awUBgw-GKL0
     lrwxr-xr-x  1 alice  wheel   32 Mar 16 10:20 project.id -> project:yKSwpZkikKz+reTV9z2a28W2F5Y
     -rw-------  1 alice  wheel  602 Mar 16 10:20 project.key Adding Regular Project Members

Adding subsequent project members is slightly more complex because the project administrator should not generate the key pair for the new member (otherwise, she would have the new member's secret key). This procedure is best explained with an example. In our example, Alice needs to add Bob as a project member.

  1. Alice, gives the project ID (yKSwpZkikKz+reTV9z2a28W2F5Y) to Bob; the project ID is not confidential information, so she can freely e-mail it or post it on a web site.
  2. Bob creates his personal key pair and his member block for the project using the pastctl join command. This command generates a key pair and writes the key to $PASTWATCH_ROOT/myproject/member.mTUZtKNHGFrs8wzKtqrARIEb6OQ along with the project ID in $PASTWATCH_ROOT/myproject/project.id
         bob% pastctl join -P yKSwpZkikKz+reTV9z2a28W2F5Y myproject
         Creating new key: member.key.48955#1 (Rabin)
                Key Label: myproject
         wrote key: /tmp/member.key.48955
         give mTUZtKNHGFrs8wzKtqrARIEb6OQ and a member name to project administrator
         bob% ls -l $PASTWATCH_ROOT/myproject
         total 2
         -rw-------  1 bob    wheel  615 Mar 16 10:28 member.mTUZtKNHGFrs8wzKtqrARIEb6OQ
         lrwxr-xr-x  1 bob    wheel   32 Mar 16 10:28 project.id -> project:1k6wxTsgGGxV+1ifLnAmSAR3n9E
  3. Bob gives his user ID (mTUZtKNHGFrs8wzKtqrARIEb6OQ) and a user name of his choosing (bob) to Alice via email.
  4. Alice adds Bob's user name and ID to the project list with the "pastctl addmember -k <userID> <username> <projname>" command.
         alice% pastctl addmember -k mTUZtKNHGFrs8wzKtqrARIEb6OQ bob myproject
         new member: bob, mTUZtKNHGFrs8wzKtqrARIEb6OQ

As the project grows, Alice can add more members. If Cliff needs to join the project, he generates a key pair with pastctl join and passes his user ID to Alice. Alice adds Cliff's user ID using pastctl addmember. Bob does not need to do anything when Cliff joins the project.

CVS Equivalent: Give Bob an account on a server, and make sure he can write to /home/alice/CVSRepository. One member with multiple computers

Each pastwatch member may have several computers they edit the repository on. Each one of those computers will have a local replica of the repository and thus it will have its own key in the project. This key is called a logkey for reasons we explain later.

A member must copy his memberkey to the new computer to create the new logkey: the member should copy the $PASTWATCH_ROOT/projlabel directory from a computer that already has a replica, to the new computer. This directory contains the project ID and the memberkey.

The first time the member uses pastwatch on the new computer, pastwatch will create a new logkey pair for the new computer and it will ask the member to provide a label for the new logkey. By default, pastwatch chooses the username and hostname to label the logkey.

4.2.3 Importing The First Project Files

After you create a project, you will need to import an initial set of files. Each Pastwatch project performs version control on a directory structure, so the initial files must be in a directory hierarchy to begin with. The initial directory can contain files and subdirectories or it can be empty if there are no initial files.

The past import command creates a new Pastwatch module and adds a set of new files to the module. The Pastwatch module name is the default directory name that Pastwatch creates when checking out the project.

To import files into a new project, use the past import command: "past -p <projectID|label> import -m <message> modulename"

In our example, Bob is importing an initial set of files in the directory: initial_files. First, Bob cd's into initial_files and then calls past import:

     bob% cd initial_files
     bob% past -p myproject import -m "Initial Import" myproject
     pastwatch: Creating a new log key and log for this replica.
     pastwatch: Member block currently has 0 entries:
     pastwatch: sfscd not running, limiting sources of entropy
     Creating new key: bob@workstation
           Key Label: bob@workstation [press enter]
     pastwatch: no replica, building from scratch
     pastwatch: root of branch tree CmWnm2V8RFM3gsHfzykZV3QdVSM
     pastwatch: new snapshot: +yj0Ms0agxAut-QE-7CqvS+hihc, 1 deltas.  For commit record: CmWnm2V8RFM3gsHfzykZV3QdVSM
     pastwatch: Using branch head: CmWnm2V8RFM3gsHfzykZV3QdVSM
     N ./README
     N ./main.c
     N ./util/util.h
     pastwatch: committing
     pastwatch: new snapshot: p11hVWvD1aVi2NK3BKfTd4zG5ww, 16 deltas.  For commit record: 36avpSpKHLBTasIsWeYLU63GeCE

Note that pastwatch automatically created a logkey for Bob on his workstation.

CVS Equivalent:

     bob% cvs -d /home/alice/CVSRepository import myproject bob release_0_1

4.3 Making Changes

4.3.1 Checking out a Working Copy

To make changes to an existing project, you must first checkout a working copy of the project to your local disk. You can then edit your working copy directly and commit changes from your working copy into the repository. To checkout a working copy, use the "past -p <projectID|label> checkout [-d <dir>] modulename" command.

In our example, Bob checks out a working directory using this command:

     bob% past -p myproject checkout myproject
     pastwatch: Using branch head: 36avpSpKHLBTasIsWeYLU63GeCE
     D myproject
     D myproject/util
     U myproject/README
     U myproject/main.c
     U myproject/util/util.h

CVS Equivalent:

     bob% cvs -d /home/alice/CVSRepository checkout myproject

4.3.2 Editing Files

Once you have a working copy, you can directly edit the files in the working copy without affecting the project repository. When you are satisfied with your changes, you can commit the changes to the repository.

4.3.3 Committing Changes

To commit changes to the repository, use the "past commit -m message file" command. past commit creates a new version in the repository with the new contents of file.

In our example, Bob edits the README file and commits his changes to the repository.

     bob% echo "By Bob" >> README
     bob% past commit -m "Added by-line" README

     pastwatch: Using branch: init
     pastwatch: Using branch head: W0cSwdqsifZI9fbdHait55FnciA
     pastwatch: checking for updates and conflicts
     pastwatch: updating .
     pastwatch: committing in README
     Committing README
     pastwatch: committing
     pastwatch: new snapshot: spwN1PisR-r6XXq1W6IzmQs4Et0, 1 deltas.  For commit record: bw2jr5Rjl17YM0j78ncEAgXnjxo

CVS Equivalent:

     bob% cvs commit -m "Added by-line" README

4.3.4 Adding New Files

To add a new file to the repository, first create the file in the working copy and then use the "past add file" command to mark the file for adding during the next commit.

In our example, Bob creates the file util/util.C and adds it to the repository.

     bob% touch util/util.C
     bob% past add util/util.C
     pastwatch: Using branch: init
     pastwatch: Using branch head: bw2jr5Rjl17YM0j78ncEAgXnjxo

     bob% past commit -m "Added util.C" util/util.C
     pastwatch: Using branch: init
     pastwatch: Using branch head: bw2jr5Rjl17YM0j78ncEAgXnjxo
     pastwatch: checking for updates and conflicts
     pastwatch: updating util.C
     A util/util.C
     pastwatch: committing in util/util.C
     N util/util.C
     pastwatch: committing
     pastwatch: new snapshot: lhVzVYEUu2A+nLimh6gqoFnspLg, 3 deltas. For commit record: MroX1c5g3AHo4CK2lpcMLRoll-4

CVS Equivalent:

     bob% touch util/util.C
     bob% cvs add util/util.C
     bob% cvs commit -m "Added util.C" util/util.C

4.3.5 Removing Files

Removing files from the repository is very similar to adding new files. First, remove the working copy of the file, then mark the file for removal using the "past remove file" command. Finally, commit the removal to the repository.

In our example, Bob removes the file util.h from the project repository.

     bob% rm util/util.h
     bob% past remove util/util.h
     pastwatch: Using branch: init
     pastwatch: Using branch head: MroX1c5g3AHo4CK2lpcMLRoll-4

     bob% past commit -m "Removing util.h file" util/util.h
     pastwatch: Using branch: init
     pastwatch: Using branch head: MroX1c5g3AHo4CK2lpcMLRoll-4
     pastwatch: checking for updates and conflicts
     pastwatch: updating util.h
     R util.h
     pastwatch: committing in util.h
     Removing util.h
     pastwatch: committing
     pastwatch: new snapshot: gZnzm7PHsBndp7sft5cuBzZuiqA, 1 deltas.  For commit record: TQGFXXwtzCo+tvIYsz0+9TOh0yY

CVS Equivalent:

     bob% rm util/util.h
     bob% cvs remove util/util.h
     bob% cvs commit -m "Removing util.h file" util/util.h

4.4 Getting Diffs

Pastwatch can calculate diffs between different versions in the repository or between a repository version and the working copy. To calculate a diff, use the command: "past diff [rep_version1] [rep_version2] [file]".

You may select zero, one or two repository versions when performing a diff. If you select zero old versions, pastwatch will compare the working copy with the parent repository version. If you select one old version, Pastwatch will compare the working copy with the specified old version. If you select two old versions, Pastwatch will compare the two old versions from the repository.

You may specify the repository versions in three different ways. You can specify a date with the -D flag, a revision number with the -r flag or a version tag with the -t flag.

In our example, Bob wants to see what changes were made between 03/28/05 16:11:53 and 03/29/05 10:12:20 to the README file.

     bob% past diff -D '03/28/05 16:11:53' -D '03/29/05 10:12:20' README
     pastwatch: Using branch: init
     pastwatch: Using branch head: TQGFXXwtzCo+tvIYsz0+9TOh0yY
     File: README
     diff -t bob@workstation:2 bob@workstation:3 README
     > By Bob

CVS Equivalent:

     cvs diff -D '03/28/05 16:11:53' -D '03/29/05 10:12:20' README

4.5 Updating the Working Copy

Often, the working copy will become out of sync with the latest repository version. Project members use the "past update" command to retrieve the latest version from the repository. past update retrieves the latest changes and applies them to the working copy, but it does not remove the local changes made to the working copy.

In our example, Cliff commits a change to README and Bob wants to incorporate Cliff's changes into his working copy.

     bob% past update
     pastwatch: Using branch: init
     pastwatch: Using branch head: Tm1WS+SoPtIqbw-Ub+X5QRLoTp0
     pastwatch: updating .
     pastwatch: updating util

CVS Equivalent:

     cvs update

4.6 Anonymous Checkout

Pastwatch supports a read only mode, so that people who are not project members may download the project source code and keep up to date with new revisions. To use anonymous mode, users can use the past command without having a member key.

     daniel% past -p yKSwpZkikKz+reTV9z2a28W2F5Y checkout myproject

4.7 Disconnected Operations

Each project members stores a local replica of the repository on their local disk in a unique data structure called a branch tree. The branch tree allows Pastwatch users to read and write to the repository even when they are disconnected from the other users.

4.8 Ignoring Files

Pastwatch inspects all the files in the working directory when performing updates and other operations. If there are some files that will not be added to the project, you may list them in the .pastwatchignore file in the working directory. Pastwatch will ignore any files listed in .pastwatchignore and files that match patterns in .pastwatchignore. Each line in .pastwatchignore contains either an exact file name or a pattern like *.o (match all files ending with .o).

Go to the first, previous, next, last section, table of contents.