Keep a history of all the modifications to a text file

Give git a chance

I don't see why it is an issue to use a powerful tool. Just write a simple bash script that runs git periodically (via cron or systemd timers); auto-generate commit messages etc.

As others highlighted in the comments it is - of course - possible to create a local repository (see here and there for more details).

If you prefer to host your own remote repo, you'll need to set up a "Bare Repository." Both git init and git clone accept a --bare argument.

Borg backup

I can also recommend borg backup. It offers you:

  • Timestamps
  • borg diff (compare between snapshots)
  • Pruning (get rid of older snapshots - say you want a snapshot for the current month every day but otherwise only one per month)
  • Encryption (optional)
  • Compression (optional)
  • and much more...

The cool thing is that it is very flexible - it is easy to setup but give you a lot of options if you want so.

I once wrote a quick-start guide which might be of help.


There a couple ways that you could do this:

  • Vim
  • Emacs
  • Git
  • Bash/External tool
  • Git-annex (all-in-one solution)

Which are all detailed here:

  • If you want to do this in Vim:

Then I'd recommend using undo history, which not only (as it's name suggest) relate to the act of undoing an action in the Vim editor, but also the one you save too. More here.

Adding the following to your .vimrc:

let vimDir = '$HOME/.vim'
let &runtimepath.=','.vimDir

" Keep undo history across sessions by storing it in a file
if has('persistent_undo')
    let myUndoDir = expand(vimDir . '/undodir')
" Create dirs
    call system('mkdir ' . vimDir)
    call system('mkdir ' . myUndoDir)
    let &undodir = myUndoDir
    set undofile
endif

Will make it so every changes/undo will be permanently kept under the directory undodir under your local vimDir, which is by default either .vim in your home directory, or other ones mentioned in the output of :version or --version on the commandline.

For even more control over your undo history, I'd recommend also using Undotree to complement the experience.

  • If you plan on doing this on Emacs:

There is a similar named packages called Undotree, which does similar things. More information on Undo history here.

  • If you prefer a Git solution:

I'd recommend using git-autocommit, which is a small bash script, with git as it's only dependencies, that watch the current git directory (where you launch it) for any new files/or modified files, and commit them.

Given the nature of Git it keep every changes to the file, and while it wouldn't be suited for a production/serious project, it is a useful solution if you don't mind not having commit message/generic commit message (which you can always edit/add later on).

Launch it after navigating on the wanted git directory (which is first made with git init on a specific directory, more info on the official manual) like so:

screen -dmS namehere git-autocommit -i 1 -V

if you're using screen, for tmux:

tmux new -n namehere git-autocommit -i 1 -V

otherwise:

git-autocommit -i 1 -V

will suffice if you prefer to not background it.

  • If you prefer a Bash solution:

I'd recommend using inotify-tools or more specifically inotifywatch which can detect and (as it's name suggest) watch a file/directory for changes, which you can then do action on it (like save it somewhere else, etc).

Here the flag to use with inotifywatch:

inotifywait -r -m -q -e close_write --format %w%f yourdirectorypathhere

and here an example Bash script using the above:

#!/bin/bash
inotifywait -r -m -q -e close_write --format %w%f directorytowatch | while IFS= read -r file; do

    process $file
done

Where process can be anything you'd want, like tar if you want to make backup on file modification, or with rclone if you want to upload it somewhere...

  • If you want a all-in-one solution:

I'd recommend git-annex which not only encompass Git but many other external tools, like inotify-tools, bash, tar, rclone, borg etc.

More info on here.

If you feel like reading the wiki/forum later on, you can also git clone it locally, for offline reading:

git clone git://git-annex.branchable.com

for the website, forum (it's all in markdown, so it's very fast to download...), and codebase (it's in Haskell!) etc


Another approach, which will cover all files in a given file system, is to use a log-structured file system such as NILFS.

Such file systems append changes, they don’t replace data. This is effectively equivalent to continuous snapshotting (or rather, checkpointing), and allows you to revisit the file system at various points in the past. Older checkpoints are liable to be garbage-collected once they reach a certain age, but checkpoints can be turned into permanent snapshots, and it is possible to automate that, for example to keep one snapshot per hour for the last month, then one per day for six months, then one per week etc.

NILFS is well-supported on Linux and is quite effective when used for /home.