af_version(3)
π af_version(3) π
okay bestie, welcome to the Attribute Filesystem (aka AtFS) version control page β this is the one that handles, like, all the versioning drama. sit down, grab a strawberry, we're doing this π
β¨ NAME β¨
af_saverev, af_newgen, af_setbusy, af_sstate, af_svnum β version control in AtFS. yeah, it's giving "the whole version-control friend group" π
β¨ SYNOPSIS β¨
#include <atfs.h>
int af_saverev (Af_key *busyAso, Af_key *saveAso, int generation, int storeType)
int af_newgen (Af_key *aso, Af_key *newAso)
int af_setbusy (Af_key *busyAso, Af_key *aso, Af_key *prevAso)
int af_sstate (Af_key *aso, int state)
int af_svnum (Af_key *aso, int gen, int rev)
int af_predsucc (Af_key *inAso, int mode, Af_key *outAso)
β¨ DESCRIPTION β¨
πΈ af_saverev
af_saverev makes a copy of the ASO identified by busyAso. this new ASO gets the status saved and a version number according to the following scheme:
- The initial revision is numbered by generation number
1and revision number0. All other saved versions get version numbers built from these of their predecessors by preserving the generation number and increasing the revision number by1.
so likeβ¦ gen stays, rev goes up by one. that's the whole glow-up arc β¨
Usually, versions are added to the most recent generation. This is indicated by giving the generation parameter AF_LASTVERS. It is also possible to add the new version to an older generation, indicated by an explicit generation number. In this case, the predecessor of the new version is the most recent version of the named generation and the version number is built accordingly. yes bestie, you can go back and vibe with the old gens, it's allowed π«Ά
The storeType argument says, whether the new version shall be stored as delta (difference) to its predecessor version or completely. Valid values are AF_STORE_DELTA (default) and AF_STORE_COMPLETE.
All attributes except version status and version number (including user defined attributes) are inherited from the busy version. The key of the generated ASO is returned in saveAso. Use af_dropkey to free the allocated memory associated with saveAso. don't forget that part, the memory does NOT clean itself up, no cap π
π«Ά Creating a new version in the most recent generation of a history requires reserving the update permissions by setting a lock on the most recent version (seeaf_lock(3)). For adding a new version to an old generation, a version lock on the most recent version of the concerned generation is needed. Subsequent calls ofaf_saverevfor the same object history each need a new lock, as the most recent version becomes a new one with every call ofaf_saverev.
so basically: lock it or lose it, and every single call needs a fresh lock because the "most recent" spot literally moves every time. iconic behaviour tbh π
π af_newgen
af_newgen opens a new generation in a object history. The last saved version will be duplicated. This creates a new ASO, that is numbered by a new generation number (increased by 1) and the initial revision number (0). All other attributes remain unchanged. af_newgen requires a lock (see af_lock(3)) set on the ASO specified by aso.
new gen, who dis? π
gen number goes up by one, rev resets to 0, everything else stays exactly the same.
π¦ af_setbusy
With af_setbusy an application can inform AtFS, that the data file of a busy version (a busy versions data always sits in a UNIX file) has been exchanged. This is usually the case, after having reinstalled an old version to be basis for further development. The argument aso denotes the version, from which the new contents of the busy version was taken. busyAso points to the current busy version, if there is any. It may also be omitted by giving a NULL pointer. af_setbusy returns prevAso the key of the version that previously was set as origin of the busy version.
tl;dr: "hey bestie, I swapped the file out, here's where the new content came from" β and it tells you where the old content came from, for the receipts π§Ύ
π af_sstate
af_sstate sets the state of the identified ASO. Only state transitions from one state to the next or previous state (according to the list below) are allowed. Possible states are:
busyβ The version is under development and its contents may be changed.savedβ The version is saved and may be used for later backup.proposedβ The version has been submitted for publication by the developer but still needs formal approval by a quality assurance board to become publicly visible and accessible in the official database.publishedβ The version has passed the formal approval and is now accessible to every member of the project. It is not yet accessed and may therefore be withdrawn if necessary.accessedβ The version has been published, and is now accessed by some members of the project.frozenβ The version may be part of a system configuration that has been released to the outside world. This means it must, under no circumstances, be destroyed.
π no skipping states, no teleporting. you go one step forward or one step back, that's the rule. and frozen means DO NOT TOUCH β under no circumstances destroyed, fr fr. that's main character protection energy π‘οΈ
β af_svnum
af_svnum sets the version number of the identified ASO to the given generation (gen) and revision (rev) number. The version number of source objects can only be increased β the version number of derived objects can be set to any value. af_svnum requires a lock (see af_lock(3)) set on the ASO specified by aso.
so: source objects go β¬οΈ only (up, never down, we don't do downgrades). derived objects? set them to literally whatever you want, free spirit π
π af_predsucc
af_predsucc returns the predecessor or successor version of inAso. The result is passed in the buffer outAso. The value for the mode parameter may be one of the following
AF_LOGICAL_SUCCβ logical successorAF_LOGICAL_PREDβ logical predecessorAF_PHYSICAL_SUCCβ physical successorAF_PHYSICAL_PREDβ physical predecessor
π SEE ALSO π
af_intro (3), af_lock(3)
π DIAGNOSTICS π
Upon error, -1 is returned and af_errno is set to the corresponding error number. so likeβ¦ check af_errno, bestie, the -1 alone is not the whole story π
π BUGS π
okay so these are the known oopsies, and I'm just the messenger:
- Due to limitations in the UNIX filesystem, only the creator (author) of a derived object may save ASOs to a derived object cache.
- Empty files cannot be inserted in a derived object cache.
- The modes
AF_LOGICAL_PREDandAF_LOGICAL_SUCCforaf_predsuccare not yet impelmented.
π not yet impelmented. yes, that's the original spelling, I am not fixing it, it's part of the lore now. the logical modes are simply not there yet. rip. πͺ¦
and that's the whole page, bestie β this was AtFS-1.71, dated Fri Jun 25 14:33:23 1993, and you just read the whole thing. slay. periodt. go lock something. ππ
π¦ where this page comes from
- debian bookworm: atfs-dev 1.4pl6-15+b1
- ubuntu jammy: atfs-dev 1.4pl6-15
- ubuntu noble: atfs-dev 1.4pl6-16.1build1
- ubuntu resolute: atfs-dev 1.4pl6-17
- ubuntu stonking: atfs-dev 1.4pl6-17
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms