all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Karl Fogel <kfogel@red-bean.com>
To: Emacs Development <emacs-devel@gnu.org>
Cc: Tim Penhey <tim@penhey.net>, Barry Warsaw <barry@python.org>
Subject: [PATCH] vc-bzr.el: avoid stomping files across hardlink branches.
Date: Sat, 08 Nov 2008 22:44:31 -0500	[thread overview]
Message-ID: <874p2h36n4.fsf@red-bean.com> (raw)
In-Reply-To: <200810292207.58558.tim@penhey.net> (Tim Penhey's message of "Wed, 29 Oct 2008 22:07:57 +1300")

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  <kfogel@red-bean.com>
+
+	* 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  <cyd@stupidchicken.com>
 
 	* 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	other threads:[~2008-11-09  3:44 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <200810292207.58558.tim@penhey.net>
2008-11-09  3:44 ` Karl Fogel [this message]
2008-11-09  4:33   ` [PATCH] vc-bzr.el: avoid stomping files across hardlink branches Miles Bader
2008-11-09  4:44     ` Karl Fogel
2008-11-09 15:03   ` Stefan Monnier
2008-11-10  2:29     ` Tim Penhey
2008-11-10  3:31       ` Stefan Monnier
2008-11-10 22:39         ` Karl Fogel
2008-11-11  2:47           ` Stefan Monnier
2008-11-29 19:05             ` Karl Fogel
2008-12-01 20:10   ` vc-dir header for bzr (was: Re: [PATCH] vc-bzr.el: avoid stomping files across hardlink branches.) Dan Nicolaescu
2008-12-01 20:30     ` vc-dir header for bzr Karl Fogel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=874p2h36n4.fsf@red-bean.com \
    --to=kfogel@red-bean.com \
    --cc=barry@python.org \
    --cc=emacs-devel@gnu.org \
    --cc=tim@penhey.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.