Previous: Reminding People To Use Watches, Up: Watches (CVS As Telephone)
In the interests of stamping out black boxes and needless mystery, let's take a quick look at how watches are implemented in the repository. We'll only take a quick look, though, because it's not pretty.
When you set a watch
floss$ pwd
/home/jrandom/myproj
floss$ cvs watch add hello.c
floss$ cvs watchers
hello.c jrandom edit unedit commit
floss$
CVS records it in the special file, CVS/fileattr, in the appropriate repository subdirectory:
floss$ cd /usr/local/newrepos
floss$ ls
CVSROOT/ myproj/
floss$ cd myproj
floss$ ls
CVS/ a-subdir/ foo.gif,v
README.txt,v b-subdir/ hello.c,v
floss$ cd CVS
floss$ ls
fileattr
floss$ cat fileattr
Fhello.c _watchers=jrandom>edit+unedit+commit
floss$
The fact that fileattr is stored in a CVS subdirectory in the repository
does not mean that the repository has become a working copy. It's
simply that the name CVS was already reserved for bookkeeping in
the working copy, so CVS can be sure no project will ever need a
subdirectory of that name in the repository.
I won't describe the format of fileattr formally; you can probably grok it pretty well just by watching it change from command to command:
floss$ cvs watch add hello.c
floss$ cat /usr/local/newrepos/myproj/CVS/fileattr
Fhello.c _watchers=jrandom>edit+unedit+commit
floss$ cvs watch add README.txt
floss$ cat /usr/local/newrepos/myproj/CVS/fileattr
Fhello.c _watchers=jrandom>edit+unedit+commit
FREADME.txt _watchers=jrandom>edit+unedit+commit
floss$ cvs watch on hello.c
floss$ cat /usr/local/newrepos/myproj/CVS/fileattr
Fhello.c _watchers=jrandom>edit+unedit+commit;_watched=
FREADME.txt _watchers=jrandom>edit+unedit+commit
floss$ cvs watch remove hello.c
floss$ cat /usr/local/newrepos/myproj/CVS/fileattr
Fhello.c _watched=
FREADME.txt _watchers=jrandom>edit+unedit+commit
floss$ cvs watch off hello.c
floss$ cat /usr/local/newrepos/myproj/CVS/fileattr
FREADME.txt _watchers=jrandom>edit+unedit+commit
floss$
Edit records are stored in fileattr, too. Here's what happens when qsmith adds himself as an editor:
paste$ cvs edit hello.c
floss$ cat /usr/local/newrepos/myproj/CVS/fileattr
Fhello.c _watched=;_editors=qsmith>Tue Jul 20 04:53:23 1999 GMT+floss\
+/home/qsmith/myproj;_watchers=qsmith>tedit+tunedit+tcommit
FREADME.txt _watchers=jrandom>edit+unedit+commit
Finally, note that CVS removes fileattr and the CVS subdirectory when there are no more watchers or editors for any of the files in that directory:
paste$ cvs unedit
floss$ cvs watch off
floss$ cvs watch remove
floss$ cat /usr/local/newrepos/myproj/CVS/fileattr
cat: /usr/local/newrepos/myproj/CVS/fileattr: No such file or directory
floss$
It should be clear after this brief exposure that the details of parsing fileattr format are better left to CVS. The main reason to have a basic understanding of the format – aside from the inherent satisfaction of knowing what's going on behind the curtain – is if you try to write an extension to the CVS watch features or debug some problem in them. It's sufficient to know that you shouldn't be alarmed if you see CVS/ subdirectories popping up in your repository. They're the only safe place CVS has to store meta-information such as watch lists.