Beispiel #1
0
 def _test_shelve_symlink_target_change(self, link_name,
                                        old_target, new_target,
                                        shelve_change=False):
     self.requireFeature(features.SymlinkFeature)
     tree = self.make_branch_and_tree('.')
     tree.lock_write()
     self.addCleanup(tree.unlock)
     os.symlink(old_target, link_name)
     tree.add(link_name, 'foo-id')
     tree.commit("commit symlink")
     os.unlink(link_name)
     os.symlink(new_target, link_name)
     creator = shelf.ShelfCreator(tree, tree.basis_tree())
     self.addCleanup(creator.finalize)
     self.assertEqual([('modify target', 'foo-id', link_name,
                        old_target, new_target)],
                      list(creator.iter_shelvable()))
     if shelve_change:
         creator.shelve_change(('modify target', 'foo-id', link_name,
                                old_target, new_target))
     else:
         creator.shelve_modify_target('foo-id')
     creator.transform()
     self.assertEqual(old_target, osutils.readlink(link_name))
     s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
     limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
     self.assertEqual(new_target, osutils.readlink(limbo_name))
     ptree = creator.shelf_transform.get_preview_tree()
     self.assertEqual(new_target, ptree.get_symlink_target('foo-id'))
Beispiel #2
0
 def _test_shelve_symlink_target_change(self,
                                        link_name,
                                        old_target,
                                        new_target,
                                        shelve_change=False):
     self.requireFeature(features.SymlinkFeature)
     tree = self.make_branch_and_tree('.')
     tree.lock_write()
     self.addCleanup(tree.unlock)
     os.symlink(old_target, link_name)
     tree.add(link_name, 'foo-id')
     tree.commit("commit symlink")
     os.unlink(link_name)
     os.symlink(new_target, link_name)
     creator = shelf.ShelfCreator(tree, tree.basis_tree())
     self.addCleanup(creator.finalize)
     self.assertEqual(
         [('modify target', 'foo-id', link_name, old_target, new_target)],
         list(creator.iter_shelvable()))
     if shelve_change:
         creator.shelve_change(
             ('modify target', 'foo-id', link_name, old_target, new_target))
     else:
         creator.shelve_modify_target('foo-id')
     creator.transform()
     self.assertEqual(old_target, osutils.readlink(link_name))
     s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
     limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
     self.assertEqual(new_target, osutils.readlink(limbo_name))
     ptree = creator.shelf_transform.get_preview_tree()
     self.assertEqual(new_target, ptree.get_symlink_target('foo-id'))
Beispiel #3
0
    def test_sprout_with_unicode_symlink(self):
        # this tests bug #272444
        # Since the trigger function seems to be set_parent_trees, there exists
        # also a similar test, with name test_unicode_symlink, in class
        # TestSetParents at file per_workingtree/test_parents.py
        self.requireFeature(features.SymlinkFeature)
        self.requireFeature(features.UnicodeFilenameFeature)

        tree = self.make_branch_and_tree('tree1')

        # The link points to a file whose name is an omega
        # U+03A9 GREEK CAPITAL LETTER OMEGA
        # UTF-8: ce a9  UTF-16BE: 03a9  Decimal: Ω
        target = u'\u03a9'
        link_name = u'\N{Euro Sign}link'
        os.symlink(target, 'tree1/' + link_name)
        tree.add([link_name], ['link-id'])

        revision = tree.commit('added a link to a Unicode target')
        tree.bzrdir.sprout('dest')
        self.assertEqual(target, osutils.readlink('dest/' + link_name))
        tree.lock_read()
        self.addCleanup(tree.unlock)
        # Check that the symlink target is safely round-tripped in the trees.
        self.assertEqual(target, tree.get_symlink_target('link-id'))
        self.assertEqual(target,
                         tree.basis_tree().get_symlink_target('link-id'))
Beispiel #4
0
    def test_sprout_with_unicode_symlink(self):
        # this tests bug #272444
        # Since the trigger function seems to be set_parent_trees, there exists
        # also a similar test, with name test_unicode_symlink, in class
        # TestSetParents at file per_workingtree/test_parents.py
        self.requireFeature(features.SymlinkFeature)
        self.requireFeature(features.UnicodeFilenameFeature)

        tree = self.make_branch_and_tree('tree1')

        # The link points to a file whose name is an omega
        # U+03A9 GREEK CAPITAL LETTER OMEGA
        # UTF-8: ce a9  UTF-16BE: 03a9  Decimal: Ω
        target = u'\u03a9'
        link_name = u'\N{Euro Sign}link'
        os.symlink(target, 'tree1/' + link_name)
        tree.add([link_name],['link-id'])

        revision = tree.commit('added a link to a Unicode target')
        tree.bzrdir.sprout('dest')
        self.assertEqual(target, osutils.readlink('dest/' + link_name))
        tree.lock_read()
        self.addCleanup(tree.unlock)
        # Check that the symlink target is safely round-tripped in the trees.
        self.assertEqual(target, tree.get_symlink_target('link-id'))
        self.assertEqual(target,
                         tree.basis_tree().get_symlink_target('link-id'))
Beispiel #5
0
 def _test_shelve_symlink_creation(self,
                                   link_name,
                                   link_target,
                                   shelve_change=False):
     self.requireFeature(features.SymlinkFeature)
     tree = self.make_branch_and_tree('.')
     tree.lock_write()
     self.addCleanup(tree.unlock)
     tree.commit('Empty tree')
     os.symlink(link_target, link_name)
     tree.add(link_name, 'foo-id')
     creator = shelf.ShelfCreator(tree, tree.basis_tree())
     self.addCleanup(creator.finalize)
     self.assertEqual([('add file', 'foo-id', 'symlink', link_name)],
                      list(creator.iter_shelvable()))
     if shelve_change:
         creator.shelve_change(('add file', 'foo-id', 'symlink', link_name))
     else:
         creator.shelve_creation('foo-id')
     creator.transform()
     s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
     self.assertPathDoesNotExist(link_name)
     limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
     self.assertEqual(link_target, osutils.readlink(limbo_name))
     ptree = creator.shelf_transform.get_preview_tree()
     self.assertEqual(link_target, ptree.get_symlink_target('foo-id'))
Beispiel #6
0
 def _test_shelve_symlink_creation(self, link_name, link_target,
                                   shelve_change=False):
     self.requireFeature(features.SymlinkFeature)
     tree = self.make_branch_and_tree('.')
     tree.lock_write()
     self.addCleanup(tree.unlock)
     tree.commit('Empty tree')
     os.symlink(link_target, link_name)
     tree.add(link_name, 'foo-id')
     creator = shelf.ShelfCreator(tree, tree.basis_tree())
     self.addCleanup(creator.finalize)
     self.assertEqual([('add file', 'foo-id', 'symlink', link_name)],
                      list(creator.iter_shelvable()))
     if shelve_change:
         creator.shelve_change(('add file', 'foo-id', 'symlink', link_name))
     else:
         creator.shelve_creation('foo-id')
     creator.transform()
     s_trans_id = creator.shelf_transform.trans_id_file_id('foo-id')
     self.assertPathDoesNotExist(link_name)
     limbo_name = creator.shelf_transform._limbo_name(s_trans_id)
     self.assertEqual(link_target, osutils.readlink(limbo_name))
     ptree = creator.shelf_transform.get_preview_tree()
     self.assertEqual(link_target, ptree.get_symlink_target('foo-id'))
    def get_sha1(self, path, stat_value=None):
        """Return the sha1 of a file.
        """
        if path.__class__ is str:
            abspath = osutils.pathjoin(self.root_utf8, path)
        else:
            abspath = osutils.pathjoin(self.root, path)
        self.stat_count += 1
        file_fp = self._fingerprint(abspath, stat_value)

        if not file_fp:
            # not a regular file or not existing
            if path in self._cache:
                self.removed_count += 1
                self.needs_write = True
                del self._cache[path]
            return None

        if path in self._cache:
            cache_sha1, cache_fp = self._cache[path]
        else:
            cache_sha1, cache_fp = None, None

        if cache_fp == file_fp:
            ## mutter("hashcache hit for %s %r -> %s", path, file_fp, cache_sha1)
            ## mutter("now = %s", time.time())
            self.hit_count += 1
            return cache_sha1

        self.miss_count += 1

        mode = file_fp[FP_MODE_COLUMN]
        if stat.S_ISREG(mode):
            if self._filter_provider is None:
                filters = []
            else:
                filters = self._filter_provider(path=path, file_id=None)
            digest = self._really_sha1_file(abspath, filters)
        elif stat.S_ISLNK(mode):
            target = osutils.readlink(osutils.safe_unicode(abspath))
            digest = osutils.sha_string(target.encode('UTF-8'))
        else:
            raise errors.BzrError("file %r: unknown file stat mode: %o"
                                  % (abspath, mode))

        # window of 3 seconds to allow for 2s resolution on windows,
        # unsynchronized file servers, etc.
        cutoff = self._cutoff_time()
        if file_fp[FP_MTIME_COLUMN] >= cutoff \
                or file_fp[FP_CTIME_COLUMN] >= cutoff:
            # changed too recently; can't be cached.  we can
            # return the result and it could possibly be cached
            # next time.
            #
            # the point is that we only want to cache when we are sure that any
            # subsequent modifications of the file can be detected.  If a
            # modification neither changes the inode, the device, the size, nor
            # the mode, then we can only distinguish it by time; therefore we
            # need to let sufficient time elapse before we may cache this entry
            # again.  If we didn't do this, then, for example, a very quick 1
            # byte replacement in the file might go undetected.
            ## mutter('%r modified too recently; not caching', path)
            self.danger_count += 1
            if cache_fp:
                self.removed_count += 1
                self.needs_write = True
                del self._cache[path]
        else:
            ## mutter('%r added to cache: now=%f, mtime=%d, ctime=%d',
            ##        path, time.time(), file_fp[FP_MTIME_COLUMN],
            ##        file_fp[FP_CTIME_COLUMN])
            self.update_count += 1
            self.needs_write = True
            self._cache[path] = (digest, file_fp)
        return digest
Beispiel #8
0
    def get_sha1(self, path, stat_value=None):
        """Return the sha1 of a file.
        """
        if path.__class__ is str:
            abspath = osutils.pathjoin(self.root_utf8, path)
        else:
            abspath = osutils.pathjoin(self.root, path)
        self.stat_count += 1
        file_fp = self._fingerprint(abspath, stat_value)

        if not file_fp:
            # not a regular file or not existing
            if path in self._cache:
                self.removed_count += 1
                self.needs_write = True
                del self._cache[path]
            return None

        if path in self._cache:
            cache_sha1, cache_fp = self._cache[path]
        else:
            cache_sha1, cache_fp = None, None

        if cache_fp == file_fp:
            ## mutter("hashcache hit for %s %r -> %s", path, file_fp, cache_sha1)
            ## mutter("now = %s", time.time())
            self.hit_count += 1
            return cache_sha1

        self.miss_count += 1

        mode = file_fp[FP_MODE_COLUMN]
        if stat.S_ISREG(mode):
            if self._filter_provider is None:
                filters = []
            else:
                filters = self._filter_provider(path=path, file_id=None)
            digest = self._really_sha1_file(abspath, filters)
        elif stat.S_ISLNK(mode):
            target = osutils.readlink(osutils.safe_unicode(abspath))
            digest = osutils.sha_string(target.encode('UTF-8'))
        else:
            raise errors.BzrError("file %r: unknown file stat mode: %o" %
                                  (abspath, mode))

        # window of 3 seconds to allow for 2s resolution on windows,
        # unsynchronized file servers, etc.
        cutoff = self._cutoff_time()
        if file_fp[FP_MTIME_COLUMN] >= cutoff \
                or file_fp[FP_CTIME_COLUMN] >= cutoff:
            # changed too recently; can't be cached.  we can
            # return the result and it could possibly be cached
            # next time.
            #
            # the point is that we only want to cache when we are sure that any
            # subsequent modifications of the file can be detected.  If a
            # modification neither changes the inode, the device, the size, nor
            # the mode, then we can only distinguish it by time; therefore we
            # need to let sufficient time elapse before we may cache this entry
            # again.  If we didn't do this, then, for example, a very quick 1
            # byte replacement in the file might go undetected.
            ## mutter('%r modified too recently; not caching', path)
            self.danger_count += 1
            if cache_fp:
                self.removed_count += 1
                self.needs_write = True
                del self._cache[path]
        else:
            ## mutter('%r added to cache: now=%f, mtime=%d, ctime=%d',
            ##        path, time.time(), file_fp[FP_MTIME_COLUMN],
            ##        file_fp[FP_CTIME_COLUMN])
            self.update_count += 1
            self.needs_write = True
            self._cache[path] = (digest, file_fp)
        return digest
Beispiel #9
0
 def readlink(self, relpath):
     """See Transport.readlink."""
     return osutils.readlink(self._abspath(relpath))