Backup restoration vs metadata preservation in Emacs: which method retains file attributes?
0 reputation · 30 Oct 2023, 18:50 UTC
0 reputation · 30 Oct 2023, 18:50 UTC
M-x revert-bufferWhen you invoke revert-buffer, Emacs replaces the buffer’s contents with the most recent backup file. The command discards any unsaved changes and does not touch the file’s permissions or timestamps, leaving those attributes set to the defaults of the current filesystem operation.
Alternatively, you can copy the backup file into the working directory, reload it into Emacs, and then explicitly restore the original file modes and times with set-file-modes and set-file-times. This two‑step process preserves the exact metadata but requires extra manual steps or a custom hook.
The unresolved decision is whether to rely on the built‑in revert, accepting metadata loss, or to implement a custom workflow that restores metadata automatically.
Key questions:
revert-buffer?33275 reputation · 31 Oct 2023, 01:05 UTC
When you use M-x revert-buffer, Emacs writes the backup file back to disk with the default filesystem attributes. The original file’s mode, ownership, and timestamps are lost. Emacs does not expose an option to preserve those attributes automatically.
Reverting replaces the buffer’s contents with the contents of the most recent backup file and then writes that content back to the file’s path. The write operation is performed as a normal write-file call, which creates a new file (or truncates the existing one) with the permissions and times that the underlying filesystem assigns to a new file. No attempt is made to copy the old file-attributes over.
Capture the original attributes, revert, then restore them:
(setq my/backup-attrs (file-attributes "~/path/to/file"))
M-x revert-buffer.
(when my/backup-attrs
(set-file-modes "~/path/to/file" (nth 3 my/backup-attrs))
(set-file-times "~/path/to/file" (nth 6 my/backup-attrs)))
These two set-file‑* calls restore the mode and the last modification time. Ownership is not changed; if you need to preserve that you’ll have to run a command as the file’s owner or with sudo.
You can add a tiny hook that runs automatically whenever you revert a buffer:
(defun my/restore-attrs-after-revert (orig-fun &rest args)
"Restore file attributes after a revert.")
(let ((attrs (file-attributes (buffer-file-name))))
(apply orig-fun args)
(when attrs
(set-file-modes (buffer-file-name) (nth 3 attrs))
(set-file-times (buffer-file-name) (nth 6 attrs)))))
(advice-add #'revert-buffer :around #'my/restore-attrs-after-revert)
Place this in your init file if you frequently revert buffers and want to keep metadata intact.
There are no mainstream packages that provide this exact functionality out of the box. The snippet above is lightweight enough to include directly.
Do you also need to preserve file ownership, or are you working on a filesystem that ignores the access‑time field? If so, the logic above will need to be extended accordingly.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.