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'))
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'))
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'))
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'))
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
def readlink(self, relpath): """See Transport.readlink.""" return osutils.readlink(self._abspath(relpath))