10

https://linux.die.net/man/1/cp

The backup suffix is '~', unless set with --suffix or SIMPLE_BACKUP_SUFFIX. The version control method may be selected via the --backup option or through the VERSION_CONTROL environment variable. Here are the values:

none, off never make backups (even if --backup is given) numbered, t make numbered backups existing, nil numbered if numbered backups exist, simple otherwise simple, never always make simple backups

As a special case, cp makes a backup of SOURCE when the force and backup options are given and SOURCE and DEST are the same name for an existing, regular file.

Why are the words nil and never used? Their meanings in English do not match the actual meanings of their usages.

midnite
  • 571
  • Just as a general note, the manuals available on linux.die.net have been missing updates since 2010 or so. Nowadays many Linux distributions have their own sites with manual pages (e.g. https://man.archlinux.org, https://manpages.debian.org, etc) that are much more up-to-date. – u1686_grawity Apr 05 '22 at 10:44
  • 1
    @user1686: I usually go for https://man7.org/ for docs for Linux system calls and libc functions, like https://man7.org/linux/man-pages/man2/open.2.html because they're up-to-date. IDK how much variety they have for section-1 man pages. – Peter Cordes Apr 05 '22 at 12:19
  • @user1686: linux.die.net has always been SEO spam using scraped content from man pages. It's not a legitimate useful resource and should not be linked to in answers. – R.. GitHub STOP HELPING ICE Apr 05 '22 at 22:47

1 Answers1

12

1.

In the oldest GNU Coreutils 'cp' release, --backup was purely a boolean option and did not take any parameter. There was a separate --version-control option (and a few environment variables) to enable versioning, and these strings were actually parameters to the latter.

In other words, --backup=simple used to be --backup --version-control=never.

But I strongly suspect that before these strings were added, version-control itself began its life as a boolean option, with the never mode tacked on later – at which point the strings t and nil were added to represent the previous two boolean choices.

Now t and nil come from some-or-other variant of Lisp, where they act as boolean keywords (true/false) – for historical reasons, the GNU project really likes Lisp. Unfortunately their usage in GNU Coreutils' version-control feature predates the initial commit of Coreutils source code to, uh, version control.

Previously these tools were known as "GNU fileutils", but I couldn't find a source repository for that – although the Coreutils repository does have an older ChangeLog file listing the "pre-history" changes:

1285 Tue May 22 00:56:51 1990  David J. MacKenzie  (djm at albert.ai.mit.edu)
..
1293         * getversion.c: New file.
1294         * mv.c (main), cp.c (main), ln.c (main): Control backup types
1295         with getenv ("VERSION_CONTROL") and +version-control or -V.
..
1300         * backupfile.[ch]: Rename var `version_control' to `backup_type'.

(Did you know that GNU --long-options originally looked +like-this? If I had to guess, they switched to -- to avoid confusion with X-Windows applications, which used the same "+option" syntax to disable a boolean option; you can still see this in Xterm.)

2.

I also suspect that these values actually come from Lisp-based Emacs, i.e. both "backup" and "version control" were programmed to mimic those found in Emacs rather than being invented new just for Coreutils. (I have not tried configuring Emacs, but I know it indeed makes ~ backups.)

  • Edit: The Coreutils texinfo page, in its Backup options section, confirms that these values directly correspond to Emacs options. See info coreutils Backup.

At the very end of the same 'ChangeLog' file, there's a "Local Variables" section for configuring the Emacs editor (its equivalent of a Vim 'modeline' or the modern .editorconfig file), which shows Emacs' own version-control parameter using the value never for this file.

1897 Local Variables:
1898 mode: indented-text
1899 left-margin: 8
1900 version-control: never
1901 End:

As can be seen in GNU Emacs' documentation, this option accepts three values: nil, never, and "anything else" – which looks weird at first, but try reading nil as 'false' and anything else as 'true' (I think that's how Lisp works? It's how Ruby works) and you will start to recognize it as a previously-boolean option.

But although the GNU Emacs source repository does go way back to 1985, it seems that these values are even older, so I'm not really sure where to go from there.

3.

It's possible that Emacs puts numbered backups first because some systems of the time already did the same thing at OS level. OpenVMS is an example that survives to this day, where file names are file.ext;version and the OS automatically increments the version number whenever a file is written. (That means you always end up with login.com;40 login.com;41 login.com;42 littering your home directory until you manually purge the old versions.)

So it's likely that originally GNU Emacs had only this kind of versioning (with boolean t/nil to enable/disable it), and the "simple" backup mode was added much later.

I also found an archive of source code for the "MIT CADR Lisp Machine", which included an early instance of Emacs called ZWEI – and many of the files found within the archive were indeed number-versioned, such as extract/nzwei/dired.55. (Though I am not sure whether this particular example was done by the OS or by the editor; I didn't dig too deep.)

u1686_grawity
  • 452,512
  • 3
    Nice guesswork. The Emacs doc (C-h v version-control) mentions t explicitly, confirming that the option used to be a boolean: "Control use of version numbers for backup files. When t, make numeric backup versions unconditionally. When nil, make them for files that have some already. The value ‘never’ means do not make them." source Emacs Lisp does use () aka nil for false and anything else for true like Common Lisp, and t is like true in C++. Scheme uses #f and #t instead, and '() evaluates to true. – jy3u4ocy Apr 05 '22 at 10:48