# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: bialix@ukr.net-20071103095720-nd6m2eg3lzoe05xf
# target_branch: file:///C:/work/Bazaar/mydev/bzr.dev/
# testament_sha1: 239a8104f181c61d56773de81b18c598f9387074
# timestamp: 2007-11-03 11:57:38 +0200
# base_revision_id: pqm@pqm.ubuntu.com-20071103093911-4alf7wiad3n3vfz6
# 
# Begin patch
=== modified file 'bzrlib/builtins.py'
--- bzrlib/builtins.py	2007-10-22 01:23:51 +0000
+++ bzrlib/builtins.py	2007-11-02 09:32:02 +0000
@@ -4218,6 +4218,31 @@
         reconfiguration.apply(force)
 
 
+class cmd_symlink(Command):
+    """Create symlink (fake symlink on Windows).
+
+    Roughly equivalent to: ln -s TARGET LINK_NAME
+    Intended to use on pure Windows and Cygwin.
+    """
+
+    hidden = True
+    takes_args = ['target', 'link_name']
+    takes_options = [
+        Option('force',
+            help='Replace existing symlink.',
+            ),
+        ]
+
+    def run(self, target, link_name, force=False):
+        import os
+        if os.path.exists(link_name):
+            if not force:
+                raise errors.FileExists(link_name)
+            else:
+                os.remove(link_name)
+        os.symlink(target, link_name)
+
+
 def _create_prefix(cur_transport):
     needed = [cur_transport]
     # Recurse upwards until we can create a directory successfully

=== modified file 'bzrlib/osutils.py'
--- bzrlib/osutils.py	2007-10-31 10:32:12 +0000
+++ bzrlib/osutils.py	2007-11-03 09:57:20 +0000
@@ -69,6 +69,13 @@
 O_BINARY = getattr(os, 'O_BINARY', 0)
 
 
+if sys.platform == 'win32':
+    # monkeypatching os module
+    os.symlink = win32utils.symlink
+    os.readlink = win32utils.readlink
+    os.lstat = win32utils.lstat_fake_symlink
+
+
 def make_readonly(filename):
     """Make a filename read-only."""
     mod = os.lstat(filename).st_mode
@@ -471,7 +478,7 @@
         return
     bfn = fn + '~'
 
-    if has_symlinks() and os.path.islink(fn):
+    if has_symlinks() and islink(fn):
         target = os.readlink(fn)
         os.symlink(target, bfn)
         return
@@ -510,6 +517,7 @@
     except OSError:
         return False
 
+
 def is_inside(dir, fname):
     """True if fname is inside dir.
     

=== modified file 'bzrlib/tests/blackbox/test_mv.py'
--- bzrlib/tests/blackbox/test_mv.py	2007-11-01 09:52:45 +0000
+++ bzrlib/tests/blackbox/test_mv.py	2007-11-03 09:57:20 +0000
@@ -17,6 +17,7 @@
 """Test for 'bzr mv'"""
 
 import os
+import sys
 
 from bzrlib import (
     osutils,
@@ -141,6 +142,11 @@
         os.symlink('a', 'c')
         os.symlink('.', 'd')
         tree.add(['a', 'a/b', 'c'], ['a-id', 'b-id', 'c-id'])
+        if sys.platform == 'win32':
+            self.expectFailure('win32 fake symlinks does not '
+                'follow symlinks in filesystem paths.',
+                self.assertEqual,
+                self.run_bzr, 'mv c/b b')
         self.run_bzr('mv c/b b')
         tree = workingtree.WorkingTree.open('.')
         self.assertEqual('b-id', tree.path2id('b'))

=== modified file 'bzrlib/tests/blackbox/test_too_much.py'
--- bzrlib/tests/blackbox/test_too_much.py	2007-09-18 08:14:00 +0000
+++ bzrlib/tests/blackbox/test_too_much.py	2007-11-03 09:36:25 +0000
@@ -564,7 +564,7 @@
             self.run_bzr('export -r 5 exp5.tmp')
             chdir("exp5.tmp")
             self.assertEquals(listdir_sorted("."), [ "d2", "link2" ])
-            self.assert_(os.path.islink("link2"))
+            self.assert_(osutils.islink("link2"))
             self.assert_(listdir_sorted("d2")== [ "link3" ])
             chdir("..")
 

=== modified file 'bzrlib/tests/test_osutils.py'
--- bzrlib/tests/test_osutils.py	2007-11-03 09:39:11 +0000
+++ bzrlib/tests/test_osutils.py	2007-11-03 09:57:20 +0000
@@ -259,6 +259,11 @@
         # dereferenced) in Python 2.4.1 and earlier
         self.assertEqual(bar_path, osutils.realpath('./bar'))
         os.symlink('bar', 'foo')
+        if sys.platform == 'win32':
+            self.expectFailure('win32 fake symlinks does not '
+                'follow symlinks in realpath.',
+                self.assertEqual,
+                bar_path, osutils.realpath('./foo'))
         self.assertEqual(bar_path, osutils.realpath('./foo'))
         
         # Does not dereference terminal symlinks
@@ -304,6 +309,19 @@
         self.assertEqual("@", osutils.kind_marker("symlink"))
         self.assertRaises(errors.BzrError, osutils.kind_marker, "unknown")
 
+    def test_symlink_readlink(self):
+        self.requireFeature(SymlinkFeature)
+        # symlink
+        fname = 'test_symlink'
+        os.symlink('fake_symlink', fname)
+        self.assertEqual('fake_symlink', os.readlink(fname))
+        self.assertEqual(True, osutils.islink(fname))
+        self.assertEqual(False, osutils.isfile(fname))
+        self.assertEqual('symlink', osutils.file_kind(fname))
+        # readlink for regular file should throw OSError
+        self.build_tree(['foo'])
+        self.assertRaises(OSError, os.readlink, 'foo')
+
 
 class TestSafeUnicode(TestCase):
 

=== modified file 'bzrlib/tests/test_transform.py'
--- bzrlib/tests/test_transform.py	2007-11-01 09:52:45 +0000
+++ bzrlib/tests/test_transform.py	2007-11-03 09:57:20 +0000
@@ -21,6 +21,7 @@
 from bzrlib import (
     errors,
     generate_ids,
+    osutils,
     symbol_versioning,
     tests,
     urlutils,
@@ -1081,9 +1082,9 @@
         for tg in this, base, other:
             tg.tt.apply()
         Merge3Merger(this.wt, this.wt, base.wt, other.wt)
-        self.assertIs(os.path.isdir(this.wt.abspath('a')), True)
-        self.assertIs(os.path.islink(this.wt.abspath('b')), True)
-        self.assertIs(os.path.isfile(this.wt.abspath('c')), True)
+        self.assertIs(osutils.isdir(this.wt.abspath('a')), True)
+        self.assertIs(osutils.islink(this.wt.abspath('b')), True)
+        self.assertIs(osutils.isfile(this.wt.abspath('c')), True)
         for suffix in ('THIS', 'BASE', 'OTHER'):
             self.assertEqual(os.readlink(this.wt.abspath('d.'+suffix)), suffix)
         self.assertIs(os.path.lexists(this.wt.abspath('d')), False)

=== modified file 'bzrlib/win32utils.py'
--- bzrlib/win32utils.py	2007-08-11 05:44:04 +0000
+++ bzrlib/win32utils.py	2007-11-02 09:32:02 +0000
@@ -19,10 +19,20 @@
 Only one dependency: ctypes should be installed.
 """
 
+import errno
 import os
+import stat
+from stat import ST_MODE, ST_SIZE
 import struct
 import sys
 
+if sys.platform == 'win32':
+    from win32file import (
+        FILE_ATTRIBUTE_SYSTEM,
+        GetFileAttributes,
+        SetFileAttributes,
+        )
+
 
 # Windows version
 if sys.platform == 'win32':
@@ -319,3 +329,66 @@
         _winreg.CloseKey(hkey)
 
     return fullpath
+
+
+FAKE_SYMLINK_EXTRA_LEN = len('!<symlink>\0')
+
+
+def symlink(src, dst):
+    """Create a symbolic link (in cygwin format) pointing to src named dst."""
+    if os.path.isfile(dst):
+        raise OSError, errno.EEXIST     # 'File exists' error
+    f = None
+    try:
+        f = file(dst, 'wb')
+        f.write('!<symlink>%s\0' % src)
+    finally:
+        if f: f.close()
+    # change attributes of file to SYSTEM
+    SetFileAttributes(dst, FILE_ATTRIBUTE_SYSTEM)
+
+
+def readlink(path):
+    """Return a string representing the path to which the symbolic link points.
+    The result may be either an absolute or relative pathname;
+    if it is relative, it may be converted to an absolute pathname
+    using os.path.join(os.path.dirname(path), result).
+    """
+    f = file(path, 'rb')
+    data = f.read()
+    f.close()
+
+    if (GetFileAttributes(path) & FILE_ATTRIBUTE_SYSTEM
+        and data.startswith('!<symlink>')
+        and data.endswith('\0')):
+            return data[10:-1]
+    else:
+        raise OSError(errno.EINVAL, 'Invalid argument: %r' % path)
+
+
+def check_fake_symlink(path):
+    """Return True if file is fake symlink"""
+    if GetFileAttributes(path) & FILE_ATTRIBUTE_SYSTEM:
+        f = file(path, 'rb')
+        data = f.read()
+        f.close()
+        if data.startswith('!<symlink>') and data.endswith('\0'):
+            return True
+    return False
+
+
+_os_lstat = os.lstat
+
+def lstat_fake_symlink(path,
+    _os_lstat=_os_lstat,
+    _s_ifreg=stat.S_IFREG,
+    _check_fake_symlink=check_fake_symlink):
+    """lstat with fake symlinks support"""
+    st = _os_lstat(path)
+    if (st.st_mode & 0170000) == _s_ifreg:
+        if _check_fake_symlink(path):
+            st = list(st)
+            st[ST_MODE] = (st[ST_MODE] & ~0170000) | stat.S_IFLNK
+            st[ST_SIZE] -= FAKE_SYMLINK_EXTRA_LEN
+            return os.stat_result(st)
+    return st

# Begin bundle
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
OnuNiA==