Make Emacs stop asking to confirm saves of unmodified files

By | November 5, 2026

When you tell GNU Emacs to save a file, it checks if the modification time of the file has changed since it was loaded into the editor or last saved. If so, it displays a message telling you the file has been modified and asking you to confirm that you want to overwrite the modified version with yours.

This is a great idea, until you start working with files managed by Microsoft OneDrive Sync on macOS, and perhaps other sync tools and other platforms. Recently, OneDrive Sync started changing the modification time of a file every time you save it, presumably to match the timestamp when it was successfully synced into the cloud. So if you’re editing and periodically saving a file in your OneDrive folder, then every time you save it, Emacs asks you to confirm that you want to overwrite the modified, but not really, version. How annoying!

Well, here’s a fix. If you put the following code into your .emacs file, or put it into a directory in your Emacs load path and put (require 'smart-supersession) in your .emacs file, then Emacs will remember the checksum of each file you edit when you save it, then compare that checksum to the checksum of the file currently on disk when you go to save it, and only warn about the file being modified if the two checksums are different.

I also posted this on Stack Overflow. Go give it an up-vote there if you like this solution. 😉

;; -*- lexical-binding: t; -*-

;; Ignore a file's changed timestamp when saving if the contents of the file
;; are the same as they were the last time we saved it. This avoids spurious
;; warnings about the file being modified if it's in a virtual filesystem
;; (e.g., Google Drive or OneDrive) whose sync app changes the file's timestamp
;; after Emacs saves it.
;;
;; By Jonathan Kamens.
;;
;; Inspired by https://stackoverflow.com/a/29556894/937306 .

(provide 'smart-supersession)

(defvar-local supersession-file-checksum nil
  "Checksum of the last-saved version of the file associated with the
current buffer. Used to determine whether to display a supersession warning
when the file's timestamp has been modified.")

(defun supersession-save-checksum ()
    (if buffer-file-name
        (setq supersession-file-checksum (md5 (current-buffer)))))
(add-hook 'after-save-hook 'supersession-save-checksum)

(defun update-buffer-modtime-if-same-checksum ()
  (if supersession-file-checksum
      (let* ((filename buffer-file-name))
        (if (string-equal supersession-file-checksum
                          (with-temp-buffer
                            (insert-file-contents filename)
                            (md5 (current-buffer))))
            (let* (attributes (file-attributes filename))
              (set-visited-file-modtime (nth 5 attributes))
              t)))))

(defun verify-visited-file-modtime--ignore-same-checksum
    (original &optional buffer)
  (or (funcall original buffer)
      (with-current-buffer buffer
        (update-buffer-modtime-if-same-checksum))))
(advice-add 'verify-visited-file-modtime :around
            #'verify-visited-file-modtime--ignore-same-checksum)

(defun ask-user-about-supersession-threat--ignore-same-checksum
    (original &rest arguments)
  (unless (update-buffer-modtime-if-same-checksum)
    (apply original arguments)))
(advice-add 'ask-user-about-supersession-threat :around
            #'ask-user-about-supersession-threat--ignore-same-checksum)
Share

Leave a Reply

Your email address will not be published. Required fields are marked *

Your post must include a link to this post.

How does this work?
Write a response on your own website and include a link to this post. Then submit your response’s URL here. Your response may appear here after moderation. To update or remove it, edit or delete your original post and submit the same URL again. Learn more about Webmentions.