Last modified: 2022-08-28 11:02

This is an example walk-through to introduce some af basics.



af is some kind of file archive or backup program. The one and only thing you really need to configure is the place where the files are copied (the archive location). You set that parameter with the dir configuration option in the file .archive-files.conf in the directory you want to backup.

dir     /var/backups/pi/markdown
history HISTORY
editor  +vi

This configuration copies files from the current directory (which is the default source) to below /var/backups/pi/markdown - just as you would expect. The other two settings are optional:

history fn
defines a file where you record your changes. Each time you are going to create a new archive volume with af create af inserts a timestamp into it, loads the file into an editor allowing you to describe the changes to the previous version.

editor editor
sets the text editor to use. My personal preference is vi. However, a better default for everyone is nano because it displays the keyboard shortcuts you need to know. So even if you get into the editor by accident you will not be lost.

The + infront the editor
this is not a typo but an additional option. It might happen that you type af create too early and while you are editing the history you notice that you forgot something to add. Therefore, af asks if you want to continue when you have finished editing the history. Now the + tells af to check the editor's exit-code: if it is non-zero (leave vi with :cq) af restores the previous history and exits without copying files. This is an option because not all editors support setting the exit code.

With this configuration I can now check which files changed since I created the last volume.

$ af
M index.gph
M mdc

If you just created your .archive-files.conf all files in the directory and all sub directories (which are included) should be listed.

There are several reasons to check the list of modified files. Here it is that I want to exclude tar and zip files. That's because the directory is a about a gawk script and the tar is made from the source files I'm already archiving. Files are excluded with the omit option

dir     /var/backups/pi/markdown
history HISTORY
editor  +vi
omit    ^(out\.)
omit    \.(html|tar\.gz|zip)$

and works like that:

omit regexp
excludes files matching regexp from the archive.

There's also ignore to exclude only a single file by its name:

ignore fn
excludes fn from the archive.

If you feel not sure about af's configuration you can display the most important parameters with af config:

$ af config
dir      /var/backups/pi/markdown
src      .

omit     ^(out(.[0-9])?|cut)$|^(out\.)|\.(html|tar\.gz|zip)$
history  HISTORY

accept-errors rm,rmdir

.workdir /var/backups/pi/markdown/zz-0025-1C68-20210904
.thisdir 0025-20210904

The values are display just as they would be configured.

The destination directory.

The source directory.

This is the effective regular expression, which is used to exclude files. First, you can see that all omit options are combined into one regexp and second, that af adds ^(out(.[0-9])?|cut)$ to it. (This is my personal preference and the only way to change that for you is to modify the defaultOmitPattern variable in the script). Furthermore, files matching the regular expression (~|$|.tmp$|.swp$) are also excluded.

The history file.

af does not copy files on its own. Instead it creates shell commands and passes them to /bin/sh -e. The -e makes sh terminate whenever a command returns an error exit-status. accept-errors defines shell commands for which errors are ignored (accepted). In this example the commands to remove files or directories are allowed to have error. For archive creation this combination is completely irrelevant because af is not going to delete anything here. This changes, if you choose a mirror destination.

This is the temporary directory af would have used. The third part (second number in the directory name) is af's process id so the name changes every time and the . in front that option tells that you that it is computed and can't be configured.

This would be the next volume's directory.

After checking the configuration I can now continue to create a backup of the files with af create.

Getting information from the archive

My Markdown project is not new so there are already files in the archive.

$ af version

There are 24 version. And since I edited mdc some days ago in a hurry I'm not sure what I changed. So I check that first.

$ af diff mdc
<               if (token == "<BR>") {
>               if (token == "<BR>"  ||  token == "<BR>\n") {
<       version = "1.0.4";
>       version = "1.0.5";

Obviously it was a bug fix to recognize <BR> at the end of an input line. I also incremented the version number. That was only a minor change. But perhaps I'm looking where I introduced a new bug and then I want a diff to an older version.

$ af diff 22 mdc
<               if (x[i] == "exit") {
>               if (x[i] == "exit")

does just that. af allows to diff against every older version but the file must exist (was changed) in that volume. Here

$af diff 17 mdc
af: no such file version: 17

returns an error because mdc wasn't changed then. So, what mdc versions are available in the archived?

$ af info mdc
mdc                    0016   2021-03-18 19:00:23        36581
mdc                    0018   2021-03-26 09:16:43        36591
mdc                    0019   2021-04-12 20:21:13        37478
mdc                    0020   2021-05-29 11:26:33        39747
mdc                    0022   2021-08-06 17:00:10        39828
mdc                    0023   2021-08-08 09:29:48        40291
mdc                    0024   2021-08-30 21:33:17        39543

The info command lists the volume number, modification date and time and the file's size. (mdc had a different name before version 16.) From that list I could pick my diff targets.

You can query the full pathname of a file's last version

$ af last mdc

or all available version

$ af history mdc

e.g. to use them from within a script for something. You could use that information to restore an older version, e.g.

$ cp `af last mdc` mdc

to restore the previous version but there is a better way.

$ af cat mdc

prints the mdc's previous version and you can specify any volume number just as for info.

$ af cat 23 mdc >mdc

is a quick way to restore a file.


So far we looked at these commands:

cat [n] fn
prints a previous or the latest version from fn.

shows important configuration parameters.

creates a new backup volume.

diff [n] fn
displays the diff between a previous and current version of fn. fn must exist in the directory of volume n.

history fn
lists the full pathnames of all versions of fn.

info fn | ~regexp
lists the available version of fn or all files matching regexp in the archive.

last fn
prints the full path of fn's latest version.

displays the version number of the newest (last created) volume.

There are two more to know:

lists all changed files, which is also the default if no command if given.

display a brief command summary.

Together these are the commands you are using most often I guess.