Hi,
it was suggested to me to discuss Subversion behaviour that is causing
me some nuisance while versioning configuration files, namely the /etc
dir of Linux servers. It may be smarter to just check in the files I
edit (I do that on some), but there is some convenience in telling svn
to just accept whatever an (automated) update did to a directory as
new state. Some semantic info gets lost (files being copied/moved around)
without the content fixation that git uses to derive such things, but I
prefer Subversion for such a task, as it more closely follows the idea
of a directory tree, including treating empty directories as valid
objects.
Please let's avoid the discussion whether one should version config
files of the actual servers or the pupped/ansible/… scripts that
generate them and just consider that
1. a directory tree on a live system is versioned in a Subversion
repository,
2. various automated processes (package manager) modify that directory
tree, and
3. Subversion is tripped up by nodes changing their kind from/to
symbolic link, plain file, directory.
I do have a script that looks at `svn st` and adds/removes files
to turn ! into D, ? into A, basically. A mythical `svn synctree`
command might do that, too, in a safer way.
If a file in the working copy is replaced by a symlink, as
reorganizations on Linux distribution upgrades make it happen, svn
refuses the commit:
svn: E145001: Commit failed (details follow):
svn: E145001: Node '...' has unexpectedly changed kind
Now, this can be worked around by moving the changed file/link aside,
telling svn to forget about it, then move back and re-add. Commit. Like
this example (out of one of the attached scripts that demonstrate the
issue and resolution in some variations of changes in kind:
# Known state to svn:
echo a > a
echo b > b
svn add a b
svn commit -m 'created two test files'
# The set up:
echo "The world happens and switches a for a symlink to b."
rm a
ln -s b a
# The workaround:
echo "Workaround: move around, remove, add."
tmp=$(mktemp a.XXXX)
mv a "$tmp"
svn rm a
mv "$tmp" a
svn add a
svn commit -m "Now a is a symlink to b in the repo."
Any thoughts on how svn could be made fitter/adaptible to a scenariro
where $anything can happen to the working copy and one just wants it to
make sense out of the current state?
This message of unexpected kind can be frustrating for the user that
for sure can see that the erstwhile file is a symlink now and is
wishing for a concise command that tells svn to just accept that fact.
At the very least, it would be nice to be able to resolve the
situation without having to delete/move the actual file (here or in
another working copy as a crutch). Just tell subversion to update it's
metadata with respect to this file. If it is a change in kind, I guess
it would be fine if the internal workings would be equivalent to `svn rm`
and `svn add`.
Comments? Suggeststions? Solutions?
Alrighty then,
Thomas
PS: Of course, as a backup/restore solution, svn on /etc is not
perfect, with it not bothering with file ownership and detailed
permissions. That can be handled by versioning the output of
find "$@" -print0 \
| sort -z | xargs -0 stat -c '%a %u:%g %U:%G %n'
(not too much thought on line breaks in file names). Of course it would
be nice if there was the option to version ownership and permission
info, too (not sure if extended attributes should be relevant for
configuration). I faintly remember a project that built on svn to
version whole filesystems including special/device files, but cannot
find it right now. I still do think that exploiting the file system
metaphor of svn provides the niche for it to continue to exist besides
the all-mighty git.
--
Dr. Thomas Orgis
HPC @ Universität Hamburg
Received on 2019-12-20 19:19:39 CET