/etc under version control
Subversion, svn for short, is a handy version control system. Nowadays, Git is more on fashion, especially for team projects. Yet, for single individuals or restricted groups, Subversion works well and is somewhat simpler. However, it has a couple of drawbacks. One, it creates a .svn subdirectory in every controlled directory. Two, it saves symbolic links as symbolic links, which implies the content is lost unless the linked file is itself under version control in the same repository. So, to backup just selected files from /etc or similar large folders, we want to either add hard links to them or to make a flat copy of them in a single directory inside our repository.
Subversion is extensible in that it provides for properties; that is, versioned metadata attached to any versioned object. Properties used by svn have names beginning with svn:. Typically, svn automatically sets svn:eol-style and svn:mime-type on each file. Users may maintain svn:ignore on directories, using svn prop* subcommands (mostly propedit, abbreviated pe).
Using a custom property named lnsvn we keep trace of files located outside the repository. The first version of this program only did links, not copies, so the default directory containing links or copies is called LINKS (all capitals). The lnsvn property of this directory contains a list of filenames (full paths) that are outside the repository but in the same partition. The base name of each file, unaltered, becomes either a hard link to or a flat copy of the original file. Assuming you already have a versioned directory, to start versioning links to selected files do so:
here:repository$ svn mkdir LINKS here:repository$ svn pe lnsvn LINKS ... edit the file (see text below) ... Saving the file sets new value for property 'lnsvn' on 'LINKS' here:repository$ lnsvn It adds links in LINKS here:repository$ svn add LINKS/* A LINKS/an_added_file ... here:repository$ svn commit
In the property file, type the full path of the file(s) you want to link. If you want it to be copied write COPY /full/path/of/file rather that just /full/path/of/file. Save the property. Running lnsvn actually creates the copies or the links. Finally, add the resulting files to svn version control. Of course, you should have compiled the program below and placed it somewhere on the PATH with setuid permission (so it can read anything) before calling it.
You can read the format of the property file in the fgets() loop below: initial spaces are discarded, # comments and empty lines are ignored, relative path are not permitted, and the keyword COPY can be set before the filename to force actually copying the file instead of hard linking. If the owner of the file is not the same as the owner of the LINKS directory, the file is copied anyway. That's necessary for files, like /etc/crontab that don't want to be hard linked. Can also be used for files in different partitions (recall hard links have that limit).
The program reads the lnsvn property and checks every link/copy. Just remember to run it before committing.
The only option the program takes is -v for verbosity. It can be set multiple times.
Copyright (C) 2023 Alessandro Vesely, all rights reserved except as noted.