[PLUGIN] bzr uncommit updated

John A Meinel john at arbash-meinel.com
Mon Sep 26 19:51:13 BST 2005


Aaron Bentley wrote:
> John Yates wrote:
> 
>>>If you test only for the platform then in a Windows
>>>environment you must conservatively eschew hardlinking.
>>>If OTOH you test for the filesystem hosting the bzr
>>>workspace, and if we assume that the vast majority of
>>>Windows boxes likely to run bzr will be W2K or later
>>>and will be NTFS-based, then you can exploit hardlinks.
> 
> 
> NTFS supports both hard links and symbolic links, but most Windows
> programs are unaware of them, and this can lead to problems.  For
> example, Explorer exhibits bizarre behaviour when symlinks are deleted:
> 
> http://shell-shocked.org/article.php?id=284
> 
> So I think that it's risky to support hard links on Windows.

Well, I read the article, and it seems that hardlinks are generally 
okay, but that NTFS symlinks are a piece of junk. (They can only point 
to directories, and really it is just mounting the directory in a new 
place, such that if you "delete" it, you are really deleting everything 
underneath it). Hence why they are called "reparse points" and not symlinks.

> 
> 
>>>To whit, Mercurial's WhatsNew:
> 
> 
> Yes, I'd seen that.  Clearly, they're braver than I.
> 

I just checked into the mercurial code, and basically, they do this:

if hasattr(os, 'link'):
     os_link = os.link
else:
     def os_link(src, dst):
         raise OSError(0, "Hardlinks not supported")

# Platform specific variants
if os.name == 'nt':
     nulldev = 'NUL:'

     try: # ActivePython can create hard links using win32file module
         import win32file

         def os_link(src, dst): # NB will only succeed on NTFS
             win32file.CreateHardLink(dst, src)

And then when they try to do the hardlink, the use:

try:
    os_link(src, dst)
except:
   hardlink = False
   shutil.copy2(src, dest)

(There is some bogus code in there, as they don't ever use hardlink 
after setting it. I think they were trying to detect in the loop that 
hardlinks failed and stop trying, but the code is in the wrong place)


Anyway, the big trick is the "win32file.CreateHardLink" (and noticing 
that src and dst are reversed)

In testing, it does indeed create a hard link, and changing one side of 
the link does effect the other side. (As long as I remember not to edit 
with Vim, which I have setup to break hardlinks :).

On FAT32 I get a pywintypes.error exception
I can get either:
 >>> win32file.CreateHardLink('test.txt', 'notes.txt')
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
pywintypes.error: (1, 'CreateHardLink', 'Incorrect function.')

or

 >>> win32file.CreateHardLink('notes.txt', 'other.txt')
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
pywintypes.error: (2, 'CreateHardLink', 'The system cannot find the file 
specified.')


Also, the os.link() function does not exist in native windows python.

Though it does exist in cygwin python (and does a copy on FAT 
filesystems), and I did test that it created a real hardlink on an NTFS 
filesystem.

I personally would not be opposed to supporting os.link when it exists 
(since under cygwin it is at worst a copy), and then trapping for a few 
different errors, so that if people have win32all installed (which is 
recommended, but not required) it will try to fall back to 
win32file.CreateHardLink(), falling back to copying the file.

(Remember, NTFS has had hardlinks from the beginning, it is just 
symlinks which are crap.)

John
=:->


> Aaron
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 253 bytes
Desc: OpenPGP digital signature
Url : https://lists.ubuntu.com/archives/bazaar/attachments/20050926/57114ae0/attachment.pgp 


More information about the bazaar mailing list