Direct answer
Do not enable file-precious-flag globally. Keep the default in-place save and enable the flag buffer-locally only for files where a truncated or zero-length write after a crash is worse than losing inode identity, hard links, or metadata continuity. Emacs does not switch automatically by file type, directory, or version-control status.
Confirmed behavior
With file-precious-flag set to nil (the default), save-buffer calls write-region in place. The target inode is preserved, but a crash during the write can leave a partial file. With the flag non-nil, Emacs writes a temporary file and renames it over the target. The rename is atomic for the path, but it replaces the inode, which can break hard links, change ownership, permissions, ACLs, or SELinux contexts, and confuse tools that track file identity in version-control working trees. Hard links to the old inode remain valid but point to the pre-save content; other links will not see the new version.
Likely explanation
The trade-off is between crash safety and identity stability. Atomic rename protects the path from partial content but sacrifices inode continuity; in-place overwrite preserves identity but is not crash-safe. Emacs offers no built-in heuristic to choose between them per directory or project.
Scoped buffer-local rule
Use a file hook to set the flag only where you need it. Add this to your init file, replacing the directory pattern with your actual atomic-save paths:
(defun my-atomic-save-maybe ()
"Enable atomic saves for selected project directories only."
(when (and buffer-file-name
(string-prefix-p "/path/to/atomic-save-root/"
(expand-file-name buffer-file-name)))
(setq-local file-precious-flag t)))
(add-hook 'find-file-hook #'my-atomic-save-maybe)
Use setq-local, not setq; a plain setq would change the global default for every buffer. For an existing buffer, toggle manually with M-x set-variable RET file-precious-flag RET t.
Verification
- Check the active value in the target buffer:
C-h v file-precious-flag or M-: file-precious-flag RET. It should report a buffer-local value when the hook fires.
- Compare inodes before and after saving:
ls -li FILE in a shell, or M-x file-attributes in Emacs. The same inode means in-place overwrite; a changed inode means atomic rename replaced the file.
- Test on a disposable copy under the target directory to confirm the hook fires and the content remains intact after the inode changes.
Caveats
Atomic rename does not by itself guarantee durability after a power loss; filesystem and directory flush behavior depends on the operating system and Emacs build. If your workflow relies on hard links or VCS inode assumptions, keep those paths on the default in-place path.