Misc developer CVS notes

Why 'HEAD' is not as useful as you might expect

HEAD is not a synonym for "last revision on main trunk", its actually quite a bit more Special than that. Consider, for instance, 'cat'.

  • "cvs update -A" (also, "cvs update -Dnow") gets the revs:
    	Makefile	1.9
    	cat.1		1.16
    	cat.c		1.21
  • "cvs update -r netbsd-1-4-base" gets the revs:
    	Makefile	1.8
    	cat.1		1.16
    	cat.c		1.19
  • "cvs update -r netbsd-1-4-PATCH001" or "cvs update -r netbsd-1-4" gets the revs:
    	Makefile	1.8
    	cat.1		1.16

In all cases, when you then say "cvs update -r HEAD" you get the same as "cvs update -A" or "cvs update -Dnow".

When you do "cvs diff -r HEAD", however:

  • When you're current (via "cvs update -A", etc.), you get the diffs:
    	file:		1st -r:	2nd -r:
    	-----		-------	-------
    	Makefile	1.9	1.9
    	cat.1		1.16	1.16
    	cat.c		1.21	1.21
    (i.e. no output.)
  • When you're updated -r netbsd-1-4-base, you get the diffs:
    	Makefile	1.9	1.8
    	cat.1		1.16	1.16
    	cat.c		1.21	1.19
    (yes, those are backwards, since "cvs diff -r foo" uses as the 'first' set of files those with rev. foo, and the second those that you've got already checked out.)
  • When you're updated -r netbsd-1-4-PATCH001 or -r netbsd-1-4, you get the diffs:
    	Makefile	1.9	1.8
    	cat.1		1.16	1.16

In other words, "cvs update -r HEAD" is equivalent to "cvs update -A" or "cvs update -Dnow" (at least in the simple cases where there's no date-based attic lossage).

However, "cvs diff -r HEAD" compares each file with the head of its branch. For some files on a branch (those which have been branched but for which there are no changes on the actual branch), the diff will be against the head of the branch that they were branched from (e.g. in the cat/Makefile case above, the head of the trunk). For others (those which do have changes on the branch), the diff will be against the head of the currently-checked out branch.

In other words, you can't reliably use diff against -r HEAD to test whether a file matches the head of the trunk.

You can use -Dnow (but that's occasionally kinda broken, in the presence of deleted files... though at least not too verbose about it

After a commit to the branch, if you're willing to do multiple updates and use -kk, you can also tell by doing something like:

  1. cvs update -kk
    (get the head of the branch you currently have checked out, with -kk. If you just committed some changes to the branch, this should simply have the effect of -kk-izing your files.)
  2. cvs update -A -kk

and if there are no files modified/added/deleted, the two are in sync.

So, in a nutshell, HEAD's pretty evil, i'd suggest avoiding it. (cgd)

Do not use .cvsignore files!

.cvsignore files are not to be used in most parts of the NetBSD source code repository. (That is, after discussion, they have been banned from the source tree.) All modules other than pkgsrc are currently included in this prohibition.

.cvsignore files have been banned because, in a nutshell, they cause problems for NetBSD development. There are two main classes of problems which they encourage: incomplete cleaning, and bogus files left in distributions.

Regarding the problem of incomplete cleaning, NetBSD sources should build and clean leaving only the original sources. If other files, e.g. object files or other files created as a by-product of building, are left around after a complete clean with make cleandir, that is a bug. .cvsignore files are used to mask that bug, and therefore should be avoided.

Regarding the problem of building a distribution that does not include bogus files, the easiest way to verify that there are no bogus files in the distribution is to run "cvs update" with the flags "-I! -ICVS". However, .cvsignore entries are added to CVS's list of files to ignore after the -I flags are processed, and so it is impossible to cause CVS to ignore files mentioned in .cvsignore files! The possible consequences of this should be obvious: files can accidentally creep into source snapshots because they were mentioned in .cvsignore files and, for whatever reason, were not properly removed.

When importing packages which include .cvsignore files, make CVS ignore them by specifying the "-I .cvsignore" option to the "cvs import" command.

Moving and copying files in the repository

Now and then a situation occurs in which it is necessary to move or copy files in the CVS repository and keep the CVS history. This is not supported by CVS itself, so it can't be done using CVS's normal client-server mechanisms.

Some time ago there were some scripts that moved the actual RCS files around -- this is not supported anymore, just remove the file and add it in the new place, noting where it was moved from or to respectively, to make tracking these moves easier in years to come. For more files at once, you can also cvs import them instead of cvs adding them.

How do I change a log message in the repository?

For pkgsrc, you don't. The following procedure is only allowed in other repositories, because it causes issues with git exports of the repository.

If you need to modify the cvs commit message in the repository after the commit has been done, you can use the cvs admin command:

$ vi /tmp/newmsg
$ cvs admin -m 1.1:"`cat /tmp/newmsg`" file

If the commit affected multiple files, you will need to repeat the above command for all the relevant revision numbers and file names. You can get the list of files and the corresponding revision numbers from the email message that was sent to the source-changes mailing list, and you can specify multiple file names in a single cvs admin command, provided all the files have the same revision number.

Back to CVS Repository Issues