[patch] Cross-dev error, /etc versioning
mbp at canonical.com
Tue Dec 16 02:43:17 GMT 2008
On 13 Dec 2008, Miroslav Prymek <m.prymek at gmail.com> wrote:
> Hello to all,
> I'am succesfully using bzr to version /etc using small scripts to correctly
> store and retrieve files modes/permitions/flags.
> But there's one problem: when .bzr is on different FS then the versioned files,
> you get "Cross-device link" error with some operations. (see
> https://bugs.launchpad.net/bzr/+bug/286268 )
> I have written a small patch for this problem (below). Please review if it is
> correct (as to the raised exceptions, directories handling etc.) and feel free
> to use it as you wish.
> Please note that this patch breaks atomicity of the _FileMover.rename(...). I
> can't examine if it is a problem for bzr or not.
> Many thx for great piece of SW!
> Miroslav Prymek
> P.S. If someone wants to know details about correct /etc versioning, with
> permissions handling, feel free to ask (preferably using this list).
> PATCH (see http://bugs.python.org/issue212317 ):
Thanks for the patch! I think it'd be better to call shutil.move()
here, rather than hardcoding it, for a few reasons: once-and-only-once;
relying on gc to close files is can make us run out of file handles, and
this might not do the right thing for directories.
Could you please change that and test it, and let us know?
We may also need to guard with a getattr against EXDEV possibly not
> --- bzrlib/transform.py.orig 2008-12-05 18:54:06.000000000 +0100
> +++ bzrlib/transform.py 2008-12-13 15:38:19.000000000 +0100
> @@ -2631,9 +2631,15 @@
> self.pending_deletions = 
> def rename(self, from_, to):
> - """Rename a file from one path to another. Functions like os.rename"""
> + """Rename a file from one path to another. Functions like os.rename
> except EXDEV correct handling."""
> - os.rename(from_, to)
> + try:
> + os.rename(from_, to)
> + except OSError, e:
> + if e.errno == errno.EXDEV:
> + open(to,'w').write(open(from_,'r').read())
> + os.unlink(from_)
> + else: raise
> except OSError, e:
> if e.errno in (errno.EEXIST, errno.ENOTEMPTY):
> raise errors.FileExists(to, str(e))
More information about the bazaar