Here is an example; lines are prefixed by C: to indicate the client sends them or S: to indicate the server sends them.

The client starts by connecting, sending the root, and completing the protocol negotiation. In actual practice the lists of valid responses and requests would be longer.

C: Root /u/cvsroot
C: Valid-responses ok error Checked-in M E
C: valid-requests
S: Valid-requests Root Directory Entry Modified Argument Argumentx ci co
S: ok
C: UseUnchanged

The client wants to check out the supermunger module into a fresh working directory. Therefore it first expands the supermunger module; this step would be omitted if the client was operating on a directory rather than a module.

C: Argument supermunger
C: Directory .
C: /u/cvsroot
C: expand-modules

The server replies that the supermunger module expands to the directory supermunger (the simplest case):

S: Module-expansion supermunger
S: ok

The client then proceeds to check out the directory. The fact that it sends only a single Directory request which specifies . for the working directory means that there is not already a supermunger directory on the client.

C: Argument -N
C: Argument supermunger
C: Directory .
C: /u/cvsroot
C: co

The server replies with the requested files. In this example, there is only one file, mungeall.c. The Clear-sticky and Clear-static-directory requests are sent by the current implementation but they have no effect because the default is for those settings to be clear when a directory is newly created.

S: Clear-sticky supermunger/
S: /u/cvsroot/supermunger/
S: Clear-static-directory supermunger/
S: /u/cvsroot/supermunger/
S: E cvs server: Updating supermunger
S: M U supermunger/mungeall.c
S: Created supermunger/
S: /u/cvsroot/supermunger/mungeall.c
S: /mungeall.c/1.1///
S: u=rw,g=r,o=r
S: 26
S: int mein () { abort (); }
S: ok

The current client implementation would break the connection here and make a new connection for the next command. However, the protocol allows it to keep the connection open and continue, which is what we show here.

After the user modifies the file and instructs the client to check it back in. The client sends arguments to specify the log message and file to check in:

C: Argument -m
C: Argument Well, you see, it took me hours and hours to find
C: Argumentx this typo and I searched and searched and eventually
C: Argumentx had to ask John for help.
C: Argument mungeall.c

It also sends information about the contents of the working directory, including the new contents of the modified file. Note that the user has changed into the supermunger directory before executing this command; the top level directory is a user-visible concept because the server should print filenames in M and E responses relative to that directory.

C: Directory .
C: /u/cvsroot/supermunger
C: Entry /mungeall.c/1.1///
C: Modified mungeall.c
C: u=rw,g=r,o=r
C: 26
C: int main () { abort (); }

And finally, the client issues the checkin command (which makes use of the data just sent):

C: ci

And the server tells the client that the checkin succeeded:

S: M Checking in mungeall.c;
S: E /u/cvsroot/supermunger/mungeall.c,v  <--  mungeall.c
S: E new revision: 1.2; previous revision: 1.1
S: E done
S: Mode u=rw,g=r,o=r
S: Checked-in ./
S: /u/cvsroot/supermunger/mungeall.c
S: /mungeall.c/1.2///
S: ok