There are a couple of version control commands that deserve wider appreciation: SCCS what and RCS ident . They allow you to find out what source a binary was built from, without having to run it – handy if it is a library!
keyword expansion
SCCS, RCS, cvs , and svn all have a way to expand keywords in a file when it is checked out of version control.
The POSIX SCCS get documentation describes its runes like %W% under the “identification keywords” heading.
RCS / cvs / svn keyword substitution uses more descriptive markers like $Revision$ .
a berkeley example
It was a BSD tradition to use keyword expansion everywhere. I first encountered it when I got involved in the Apache httpd project in the late 1990s – Apache’s CVS repository was hosted on a FreeBSD box and used a version of FreeBSD’s CVS administrative scripts.
Here’s an example from res_send.c in FreeBSD’s libc resolver.
static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; static const char rcsid[] = "$Id: res_send.c,v 1.22 2009/01/22 23:49:23 tbox Exp $"; __FBSDID("$FreeBSD$");
There are geological strata of version control tags here:
the sccsid from the Berkeley CSRG SCCS repository
from the Berkeley CSRG SCCS repository the rcsid from ISC’s BIND repository ( tbox was ISC’s tinderbox build / CI system)
from ISC’s BIND repository ( was ISC’s tinderbox build / CI system) the FBSDID from FreeBSD’s cvs and later svn repositories (which has not been expanded)
an unifdef example
When unifdef was uplifted to git, I wanted to keep its embedded version control keywords – I have a sentimental liking for this old tradition. If you’ve installed cssc , rcs , and unifdef on a Debian box, you can run,
:; sccs what /usr/bin/unifdef :; ident /usr/bin/unifdef
Both of those will produce similar output to
:; unifdef -V
On a Mac with the developer command-line tools installed,
:; what /Library/Developer/CommandLineTools/usr/bin/unifdef
You get the output twice because it’s a fat binary!
versioning three ways
In unifdef.c , the embedded version looks like,
static const char copyright[] = "@(#) $Version: unifdef-2.12 $
" "@(#) $Date: 2020-02-14 16:49:56 +0000 $
" "@(#) $Author: Tony Finch (dot@dotat.at) $
" "@(#) $URL: http://dotat.at/prog/unifdef $
" ;
Each line is prefixed with an SCCS magic marker @(#) so that what can find it, and wrapped in an RCS-style $Keyword$ so that ident can find it. There’s a fairly trivial version() function that spits out the copyright[] string when you run unifdef -V .
embedding versions from git
My projects have various horrible build scripts for embedding the version number from git . The basic idea is,
use an annotated or signed tag to mark a release, i.e. git tag -a or git tag -s
use git describe to get a version string that includes an extra number counting commits since the last release
maybe use git show --pretty=format:%ai -s HEAD to get a release date
stuff the outputs from git into the $Version$ and $Date$ RCS keywords
retro cool
I enjoy keeping this old feature working, even though it isn’t very useful if no-one knows about it! Maybe if I blog about it, it’ll become more widespread?