changeset 100046:3d02ae295c17

* emacs-cvs/lisp/files.el (break-hardlink-on-save): New variable. (basic-save-buffer-2): Honor new variable break-hardlink-on-save. (file-precious-flag): Mention it in doc string.
author Karl Fogel <kfogel@red-bean.com>
date Sat, 29 Nov 2008 19:04:14 +0000
parents 3ec2cc2d35c1
children 6f0574e7edd8
files lisp/ChangeLog lisp/files.el
diffstat 2 files changed, 36 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Sat Nov 29 18:35:33 2008 +0000
+++ b/lisp/ChangeLog	Sat Nov 29 19:04:14 2008 +0000
@@ -1,3 +1,9 @@
+2008-11-27  Karl Fogel  <kfogel@red-bean.com>
+
+	* files.el (break-hardlink-on-save): New variable.
+	(basic-save-buffer-2): Honor new variable break-hardlink-on-save.
+	(file-precious-flag): Mention it in doc string.
+
 2008-11-29  Miles Bader  <miles@gnu.org>
 
 	* minibuffer.el (minibuffer-confirm-exit-commands): New variable.
--- a/lisp/files.el	Sat Nov 29 18:35:33 2008 +0000
+++ b/lisp/files.el	Sat Nov 29 19:04:14 2008 +0000
@@ -243,10 +243,29 @@
 
 This feature is advisory: for example, if the directory in which the
 file is being saved is not writeable, Emacs may ignore a non-nil value
-of `file-precious-flag' and write directly into the file."
+of `file-precious-flag' and write directly into the file.
+
+See also: `break-hardlink-on-save'."
   :type 'boolean
   :group 'backup)
 
+(defcustom break-hardlink-on-save nil
+  "Non-nil means when saving a file that exists under several names
+(i.e., has multiple hardlinks), break the hardlink associated with
+`buffer-file-name' and write to a new file, so that the other
+instances of the file are not affected by the save.
+
+If `buffer-file-name' refers to a symlink, do not break the symlink.
+
+Unlike `file-precious-flag', `break-hardlink-on-save' is not advisory.
+For example, if the directory in which a file is being saved is not
+itself writeable, then error instead of saving in some
+hardlink-nonbreaking way.
+
+See also `backup-by-copying' and `backup-by-copying-when-linked'."
+  :type 'boolean
+  :group 'files)
+
 (defcustom version-control nil
   "Control use of version numbers for backup files.
 When t, make numeric backup versions unconditionally.
@@ -4164,10 +4183,16 @@
 		(error "Attempt to save to a file which you aren't allowed to write"))))))
     (or buffer-backed-up
 	(setq setmodes (backup-buffer)))
-    (let ((dir (file-name-directory buffer-file-name)))
-      (if (and file-precious-flag
-	       (file-writable-p dir))
-	  ;; If file is precious, write temp name, then rename it.
+    (let* ((dir (file-name-directory buffer-file-name))
+           (dir-writable (file-writable-p dir)))
+      (if (or (and file-precious-flag dir-writable)
+              (and break-hardlink-on-save
+                   (> (file-nlinks buffer-file-name) 1)
+                   (or dir-writable
+                       (error (concat (format
+                                       "Directory %s write-protected; " dir)
+                                      "cannot break hardlink when saving")))))
+	  ;; Write temp name, then rename it.
 	  ;; This requires write access to the containing dir,
 	  ;; which is why we don't try it if we don't have that access.
 	  (let ((realname buffer-file-name)