Rev 5353: (mbp) Transport.stat('') on a symlink returns info about the link (Martin in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Mon Jul 19 22:32:11 BST 2010


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5353 [merge]
revision-id: pqm at pqm.ubuntu.com-20100719213209-3bqfu9jg2md5zga6
parent: pqm at pqm.ubuntu.com-20100719174216-c1mezuulmblmnkp5
parent: mbp at canonical.com-20100719201238-98inkk0gxltll8lq
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Mon 2010-07-19 22:32:09 +0100
message:
  (mbp) Transport.stat('') on a symlink returns info about the link (Martin
   Pool)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/tests/per_transport.py  test_transport_implementations.py-20051227111451-f97c5c7d5c49fce7
  bzrlib/transport/local.py      local_transport.py-20050711165921-9b1f142bfe480c24
  bzrlib/transport/sftp.py       sftp.py-20051019050329-ab48ce71b7e32dfe
=== modified file 'NEWS'
--- a/NEWS	2010-07-19 15:39:51 +0000
+++ b/NEWS	2010-07-19 20:12:38 +0000
@@ -31,6 +31,10 @@
 * Check if both --diff-options and --using are set, and exit with error
   in this case. (Matthäus G. Chajdas, #234708)
 
+* ``Transport.stat`` on a symlink, including a transport pointing directly
+  to a symlink, now returns information about the symlink.
+  (Martin Pool)
+
 * `PathNotChild` should not give a traceback.
   (Martin Pool, #98735)
 

=== modified file 'bzrlib/tests/per_transport.py'
--- a/bzrlib/tests/per_transport.py	2010-03-05 05:30:19 +0000
+++ b/bzrlib/tests/per_transport.py	2010-07-19 11:06:36 +0000
@@ -1122,7 +1122,8 @@
             self.failUnless(t.has(link_name))
 
             st = t.stat(link_name)
-            self.failUnless(S_ISLNK(st.st_mode))
+            self.failUnless(S_ISLNK(st.st_mode),
+                "expected symlink, got mode %o" % st.st_mode)
         except TransportNotPossible:
             raise TestSkipped("Transport %s does not support symlinks." %
                               self._server.__class__)
@@ -1765,3 +1766,15 @@
         # also raise a special error
         self.assertListRaises((errors.ShortReadvError, errors.InvalidRange),
                               transport.readv, 'a', [(12,2)])
+
+    def test_stat_symlink(self):
+        # if a transport points directly to a symlink (and supports symlinks
+        # at all) you can tell this.  helps with bug 32669.
+        t = self.get_transport()
+        try:
+            t.symlink('target', 'link')
+        except TransportNotPossible:
+            raise TestSkipped("symlinks not supported")
+        t2 = t.clone('link')
+        st = t2.stat('')
+        self.assertTrue(stat.S_ISLNK(st.st_mode))

=== modified file 'bzrlib/transport/local.py'
--- a/bzrlib/transport/local.py	2010-04-30 09:10:00 +0000
+++ b/bzrlib/transport/local.py	2010-07-19 20:09:53 +0000
@@ -99,7 +99,10 @@
          - relative_reference is url escaped.
         """
         if relative_reference in ('.', ''):
-            return self._local_base
+            # _local_base normally has a trailing slash; strip it so that stat
+            # on a transport pointing to a symlink reads the link not the
+            # referent but be careful of / and c:\
+            return osutils.split(self._local_base)[0]
         return self._local_base + urlutils.unescape(relative_reference)
 
     def abspath(self, relpath):

=== modified file 'bzrlib/transport/sftp.py'
--- a/bzrlib/transport/sftp.py	2010-03-04 02:43:41 +0000
+++ b/bzrlib/transport/sftp.py	2010-07-19 10:55:15 +0000
@@ -715,6 +715,8 @@
             if (e.args[0].startswith('Directory not empty: ')
                 or getattr(e, 'errno', None) == errno.ENOTEMPTY):
                 raise errors.DirectoryNotEmpty(path, str(e))
+            if e.args == ('Operation unsupported',):
+                raise errors.TransportNotPossible()
             mutter('Raising exception with args %s', e.args)
         if getattr(e, 'errno', None) is not None:
             mutter('Raising exception with errno %s', e.errno)




More information about the bazaar-commits mailing list