Lock problem with ci command

[email protected] Sun, 2 Aug 2026 22:45:51 +1000
Newsgroups gmane.comp.version-control.rcs.bugs
Message-ID <202608021245.672Cjppf016813.mail.zacglen.com@localhost>
This is surprisingly old issue which has been around ever
since I first encountered RCS (circa 1989). I have tolerated it
all of those years yet until today never bothered so spend any
time attempting to fixing it.

Anyhow here is how it arises.

1. echo '$Id$' >t.txt
2. ci -l -t- t.txt
3. rcsdiff t.txt
   (no differences)
4. ci -l t.txt
   file is unchanged; reverting to previous revision 1.1
5. rcsdiff t.txt
   < $Id: t.txt,v 1.1 2026/08/02 12:02:36 <USER> Exp <USER> $
   ---
   > $Id: t.txt,v 1.1 2026/08/02 12:02:36 <USER> Exp $

The problem is demonstrated at step 5.
There should be no difference because the attempted ci
was a no-op and should have reverted fully to the
previous revision. But the locker has been omitted from
the $Id$ expansion.

Instead, the fact that the file was previously locked has
been glossed over. Yet 'rlog' shows that a lock is
still active.

There is a fairly simple "patch" that will fix this glaring,
and 30-year old bug. This patch is for a relatively old version
of RCS but is applicable to v5.10.1 or newer except that
some of the variable names, whitespace, and bracketing have
been changed. Actually not strictly a patch but just a highlighted
chunk of changed code:

======================== rcs-5.7/src/ci.c ===============================

    if (! (changedRCS = lockflag<removedlock || assoclst)) {
+	const char *lockedby = workdelta->lockedby;
	workdelta = targetdelta;
+	if (lockedby)
+	    workdelta->lockedby = lockedby;
    } else {

=========================================================================

At this stage I am not 100% sure why the above patch works.
But it does work. Reading the code (ouch that hurt) might lead one
to assume that it is not necessary, but in practice it does appear to be.
That is because the above steps results in 'targetdelta'/'bud.target'
not having the 'lockedby' element set, when originally the
'lockedby' would have been set.

Regards
JW