Skip to content

shrimple 🇵🇱 🏳️‍⚧️

shrimple mind. shrimple problems. complex solutions. she/her

Distributed file version management in 15 minutes of Bash

Posted on February[²⁰26], Tuesday 03.February[²⁰26], Saturday 07. By Shrimple No Comments on Distributed file version management in 15 minutes of Bash

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!

Wild Software Writing Tags:bash, linux, scripting

Post navigation

Previous Post: Subscription into list rather than tour — Offpunk draft feature patch
Next Post: Getting TLS1.3 Key Log from Go application with requests by a library, and using it in Wireshark

Related Posts

  • Simplistic reconciliation of mostly-append text files like Offpunk lists: draft involving Kahn’s algorithm Wild Software Writing
  • Amending my Offpunk redirection implementation Wild Software Writing
  • Experimentally expanding Offpunk browser Part 1 (nightly) Wild Software Writing
  • Links 2, a graphical browser I wanna build upon. And a quick look at how ELinks is doing. Wild Software Writing
  • Bugfix for list URI for my Offpunk redirections implementation draft Wild Software Writing
  • Slash-hierarchical list names — my draft implementation for Offpunk Wild Software Writing

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Atom feed for this page

Atom feed for this blog

against-messy-software bash big.ugly.git.patch. chromium-and-derivatives community fragment golang kde links2 linux microsoft-edge network offpunk offpunk:lists offpunk:redirections oss-contributing perl programming-tips scripting smolweb subscribe superuser window-decorations Wordpress_ActivityPub_plugin

  • February 2026 (4)
  • January 2026 (10)

Categories

  • Influencing Society

    (1)
  • Meta

    (2)
  • Oddities of alternate reality

    (1)
  • Programming Technologies

    (1)
  • Software Imposed On Us

    (1)
  • Wild Software Writing

    (8)
shrimple 🇵🇱  🏳️‍⚧️
shrimple 🇵🇱 🏳️‍⚧️
@shrimple@www.shrimple.pl
Follow

shrimple mind. shrimple problems. complex solutions. she/her

14 posts
5 followers

Follow shrimple 🇵🇱 🏳️‍⚧️

My Profile

Copy and paste my profile into the search field of your favorite fediverse app or server.

Your Profile

Or, if you know your own profile, we can start things that way!
  • What if we organized a different kind of hackathon Influencing Society
  • Slash-hierarchical list names — my draft implementation for Offpunk Wild Software Writing
  • Links 2, a graphical browser I wanna build upon. And a quick look at how ELinks is doing. Wild Software Writing
  • Hello world! Meta
  • Bugfix for list URI for my Offpunk redirections implementation draft Wild Software Writing
  • Amending my Offpunk redirection implementation Wild Software Writing
  • Experimentally expanding Offpunk browser Part 1 (nightly) Wild Software Writing
  • Simplistic reconciliation of mostly-append text files like Offpunk lists: draft involving Kahn’s algorithm Wild Software Writing

shrimple@shrimple.pl

Copyright © 2026 shrimple 🇵🇱 🏳️‍⚧️.

Powered by PressBook News WordPress theme