The Current Version: fixing macOS versioning

The other day, a friend took me back into macOS versioning. He said that he wanted to be able to make individual versions protected against removal, and to assign them names. I rashly offered to implement those in Revisionist. The short summary is that I have failed to do so, and in reaching that conclusion I have learned more about this valuable feature of macOS, and its apparent incompletion.

In my original article summarising versioning and version management in macOS, I pointed out two of its limitations:

  • versions only remain associated with the original document, not with copies or duplicates;
  • versions don’t travel with documents in iCloud Drive.

Let me explain those a little more carefully.

Copying versioned files

When you make a copy or duplicate of a document, or a folder posing as a document, such as RTFD, the copy is a new file. By convention in macOS, it is given the same creation and modification dates as the original, but as far as the file system goes, it is not the same file as the original one. As versions are strictly associated with a specific file, no other file can be linked to those same versions, and macOS doesn’t duplicate versions into the copy.

You can, though, create a link to the original file, and use that link to access the same file, with the same versions.

There seems to be a little confusion over the effect of APFS on this. One of the new file system’s strengths is that making a copy of a file on the same volume doesn’t require the contents of the file to be duplicated – the copy is a clone. But clones are not the same as hard links, which refer to exactly the same file, they are two different files which happen to share common data. As they become modified, their similarities diverge until they have no data in common, and are completely separate files.

So when you make a clone of a versioned file in APFS, the new clone is a new file (just as it is in HFS+), and has no previous versions at all. So the only thing that APFS helps with is making better use of disk space.

As far as I can see, there is no option, facility, or tool for making a copy of a Mac file and retaining existing versions into the new file. Indeed, making a copy of a file is a quick, cheap way of stripping all previous versions from it.

Working on versions over iCloud Drive, external storage, and from backups

Versioning becomes even more limited when you start doing more adventurous things with documents. Because all versions apart from the current one are stored in a separate, hidden and locked-down folder at the root of that volume, they are specific to that volume, and only available so long as that Mac has access to the version information.

Copy a versioned file to another volume, such as an external drive, and its versions stay at home, and are lost from the copy. Work on a document on an external volume, then copy that to a different Mac, and its versions are left behind. Once again, neither macOS nor any utility that I know of will copy a document’s versions to accompany the document from one storage volume to another.

The one confusing exception to this is iCloud Drive, which pretends that it’s not external storage at all, just an extension of your own local storage. Up to a point, that is. In this case, iCloud Drive’s pretence fails when you are using it to work on the same document from two or more different systems. Because it relies on the versions stored on the startup volume of each system and doesn’t propagate those to other systems, only one Mac can use each document’s versions, the one used to create those versions.

Open that document using a different Mac, and that lacks the versions stored in the hidden, locked-down folder, so no version information is accessible. So if you work collaboratively over an iCloud account, the versioning system in macOS is of very limited benefit, and could even be confusing.

Controlling permanence

Versions tucked away in the versioning system can be discardable, or not. Discarding old versions is beyond the control of the user – it is something that macOS does when it feels it necessary or appropriate. Apple does not tell us what its criteria might involve.

If you’re going to use macOS versioning, being able to protect versions from being discarded is essential, and Apple exposes the flag determining whether a version can be discarded by macOS. Except that the flag is nearly useless. In the words of Apple:
After setting this property to true, do not set this property to false again. Doing so causes the system to raise an exception.

So software can make a non-discardable version discardable, but cannot protect a discardable version by making it non-discardable. I confirm from bitter experience that, however crazy this may seem, that documentation is completely accurate.

The saving grace here is that the great majority of versions are non-discardable. Apple doesn’t tell us whether macOS might decide to change them when it fancies, nor when that might happen.

Adding information

macOS has three items of information about each version which allow it to be identified:

  • A UUID for that version,
  • The file path to the stored version, within the hidden, locked-down folder,
  • The datestamp of that version.

Of those, only the last is meaningful to the user.

I had the idea of adding an extended attribute containing a title (or other text description) which would be more informative, such as September Milestone Meeting, or similar. However, all versions except the current one are locked down completely, so even modifying their extended attributes is not possible. I have thought about being devious and replacing existing versions in order to attempt this, but I don’t think that is wise, and could cause more extensive problems in the versioning system if used heavily.

Addressing shortcomings

At present, the versioning system’s most serious shortcomings arise from the lack of mobility of versions. Without the ability to perform a deep file copy and carry across existing versions, and to access versions from other systems working on documents shared using iCloud Drive, the inspired design of the system is sadly stunted in practice.

For many users, those limitations make the macOS versioning system occasionally useful, but not something to design into their workflow.

Although these ideally need to be implemented at a system level, there are two key features which need to be added:

  • the ability to make a deep copy of a versioned document, including to another volume,
  • the ability to transfer versioned documents with their existing versions, over cloud services (including iCloud Drive), and to other systems.

I have already got the first of those working, and have almost completed the second. A new version (!) of Revisionist will be out shortly.