emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] vc-bzr.el: avoid stomping files across hardlink branches.


From: Karl Fogel
Subject: [PATCH] vc-bzr.el: avoid stomping files across hardlink branches.
Date: Sat, 08 Nov 2008 22:44:31 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.60 (gnu/linux)

I'm offering this patch for review before I commit, since I'm not an
expert in the VC code.  Following the patch is a shell script showing
the reproduction recipe.

Summary: this was actually a latent bug between Emacs and bzr branches
created with 'bzr branch --hardlink', but it had been masked by the
default make-backup-files behavior.  As long as Emacs was writing to a
tmp file and then renaming, the hardlink would get broken anyway --
which was desirable, and so the right thing happened by accident.  But
then VC apparently got smart and stopped making backup files for files
under version control.  This was good, but unmasked a bug whereby saving
a file in branch NEW (created with 'bzr branch --hardlink OLD NEW')
would cause the corresponding file in OLD to be modified too.  Oops.

I tested with today's head of Bazaar (1.10dev) and today's head CVS
Emacs (23.0.60.1).  Comments welcome.

Patch first:

[[[
Index: lisp/ChangeLog
===================================================================
RCS file: /sources/emacs/emacs/lisp/ChangeLog,v
retrieving revision 1.14751
diff -u -r1.14751 ChangeLog
--- lisp/ChangeLog      8 Nov 2008 14:23:06 -0000       1.14751
+++ lisp/ChangeLog      9 Nov 2008 03:25:56 -0000
@@ -1,3 +1,8 @@
+2008-11-09  Karl Fogel  <address@hidden>
+
+       * vc-bzr.el (vc-bzr-find-file-hook): Set file-precious-flag to t,
+       to avoid stomping files across bzr hardlink branches.
+
 2008-11-08  Chong Yidong  <address@hidden>
 
        * dired.el (dired-read-dir-and-switches): Revert to 2007-11-22

Index: lisp/vc-bzr.el
===================================================================
RCS file: /sources/emacs/emacs/lisp/vc-bzr.el,v
retrieving revision 1.70
diff -u -r1.70 vc-bzr.el
--- lisp/vc-bzr.el      4 Nov 2008 17:36:43 -0000       1.70
+++ lisp/vc-bzr.el      9 Nov 2008 03:25:57 -0000
@@ -293,6 +293,15 @@
       (remove-hook 'after-save-hook 'vc-bzr-resolve-when-done t))))
 
 (defun vc-bzr-find-file-hook ()
+  ;; The user might have done 'bzr branch --hardlink OLD NEW', and if
+  ;; they did, we definitely want to break the link when saving a file
+  ;; in either OLD or NEW.  Since there's little harm done if the user
+  ;; created a non-hardlink branch, and no easy way to tell if they
+  ;; did or didn't, we just set preciousness unconditionally.  We don't
+  ;; ask (and buffer-file-name (vc-bzr-registered buffer-file-name))
+  ;; because if this hook is being called, the file must be registered.
+  (set (make-local-variable 'file-precious-flag) t)
+  ;; Notice conflicts.
   (when (and buffer-file-name
              ;; FIXME: We should check that "bzr status" says "conflict".
              (file-exists-p (concat buffer-file-name ".BASE"))
]]]

Then reproduction script:

------------------------------------------------------------------------------
#!/bin/sh

echo "### bzr version is:"
bzr --version
echo ""

rm -rf sandbox

mkdir sandbox
cd sandbox/

# Make bzr not use your normal ~/.bazaar/config
BZR_HOME=`pwd`
export BZR_HOME

mkdir old
cd old

echo "### In old, run 'bzr init'..."
bzr init
echo ""

echo "### In old, create hello.txt, add it to bzr, and commit..."
echo hello > hello.txt
bzr add
bzr commit -m "Hello."
echo ""

cd ..
echo "### Do 'bzr branch --hardlink old new'..."
bzr branch --hardlink old new
echo ""

cd new/

echo "### In new, run 'ls -l' to see the hardlink is really there..."
echo ""
ls -l
echo ""

echo "### In new, run 'emacs -q hello.txt' (please modify, save, and exit)..."
emacs -q hello.txt
echo ""

echo "### In new, run 'bzr diff' to see the expected diff..."
bzr diff
echo ""

echo "### In new, commit the change (although I'm not sure this step is"
echo "### strictly necessary to demonstrate the bug)..."
echo ""
bzr commit -m "Added world."
echo ""

cd ../old/

echo "### In old, run 'bzr diff' (we don't want any diff to show)..."
bzr diff
echo ""

echo "### If there was a diff the second time (in old), then Emacs has"
echo "### the hardlink bug."




reply via email to

[Prev in Thread] Current Thread [Next in Thread]