You don’t always need to have all the tools at your disposal, but you may want to have some way of checking in your file edits. CVS is too powerful and has a lot of unnecessary parts, while not being distributed. You may not need to keep everything in deltas.
So why not just write them to a directory, without designating a particular root, just keeping track of what was the previously checked out file? (You might want to write a function for checking out an earlier revision, so as to not hide the undo; more below.)
(Edit: rather than the while loop and the shift command, the below could have used the for keyword without the in list.)
#!/usr/bin/env bash
set -euo pipefail
function myhash {
cksum --raw "$1" | basenc --base32 | tr -d '='
}
while [ $# -gt 0 ]
do
cd "`dirname "$1"`" || exit 1
mkdir -p .versioning
hash="`myhash "$1"`"
version=.versioning/"$1~$hash"
cur=""
if [ -e .versioning/"$1~cur" ]
then
if [ "`stat --printf="%s" .versioning/"$1~cur"`" -ne 8 ]
then
>&2 echo ".versioning/$1~cur" bad
exit 1
fi
cur="`cat .versioning/"$1~cur"`"
if [ "$cur" != "$hash" ]
then
curfile=.versioning/"$1~$cur"
if [ ! -e "$curfile" ]
then
>&2 echo "$1~$cur" not found;
exit 1
fi
if [ "$cur" != "`myhash "$curfile"`" ]
then
>&2 echo "$1~$cur" doesnt hash
exit 1
fi
chmod a-wx "$curfile" || >&2 echo "Could not a-wx orig $curfile"
ln -s .versioning/"$1~$cur" "$version"'%prev'
fi
fi
echo "$hash" > .versioning/"$1~cur"
cp --reflink=auto "$1" "$version" 2>/dev/null ||
[ -e "$version" ] && [ "$hash" = "`myhash "$version"`" ]
chmod a-wx "$version" || >&2 echo "Could not a-wx $version"
shift
done
The result, in the .versioning/ directory relative to versioning.bash being edited:
-rw-r--r-- 1 8 versioning.bash~cur -r--r--r-- 1 1097 versioning.bash~FYUNFIY lrwxrwxrwx 1 35 versioning.bash~FYUNFIY%prev -> .versioning/versioning.bash~X7V3TRA -r--r--r-- 1 1109 versioning.bash~IABNGOY lrwxrwxrwx 1 35 versioning.bash~IABNGOY%prev -> .versioning/versioning.bash~FYUNFIY -r--r--r-- 1 1030 versioning.bash~X7V3TRA lrwxrwxrwx 1 35 versioning.bash~X7V3TRA%prev -> .versioning/versioning.bash~ZQ7C2UQ -r--r--r-- 1 967 versioning.bash~ZQ7C2UQ lrwxrwxrwx 1 35 versioning.bash~ZQ7C2UQ%prev -> .versioning/versioning.bash~ZQ7C2UQ
- You may want to make the ~cur file, essentially a HEAD, a symlink, perhaps.
- You may not like the idea of using CRC32. Just switch to another one in cksum, perhaps with truncation.
Checking out an earlier revision and keeping track of that
When checking out an earlier revision, you may want to write its hash (or symlink a revision) into the ~cur file. You may also want to create a %prev symlink going the opposite way just for the act of checkout (it can well express an equivalent of reflog on the same axis, since there is no deltas and chain). So there is more functions to be written — although not like it can’t be performed by hand the first one or two times!