13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
"""Tests of the parent related functions of WorkingTrees."""
34
35
from bzrlib.revision import Revision
35
from bzrlib.tests import (
39
UnicodeFilenameFeature,
41
from bzrlib.tests.workingtree_implementations import TestCaseWithWorkingTree
36
from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
42
37
from bzrlib.uncommit import uncommit
235
230
def test_unicode_symlink(self):
236
231
# this tests bug #272444
237
self.requireFeature(SymlinkFeature)
238
self.requireFeature(UnicodeFilenameFeature)
232
self.requireFeature(tests.SymlinkFeature)
233
self.requireFeature(tests.UnicodeFilenameFeature)
240
235
tree = self.make_branch_and_tree('tree1')
242
237
# The link points to a file whose name is an omega
243
238
# U+03A9 GREEK CAPITAL LETTER OMEGA
244
239
# UTF-8: ce a9 UTF-16BE: 03a9 Decimal: Ω
245
os.symlink(u'\u03a9','tree1/link_name')
246
tree.add(['link_name'],['link-id'])
241
link_name = u'\N{Euro Sign}link'
242
os.symlink(target, 'tree1/' + link_name)
243
tree.add([link_name],['link-id'])
249
# the actual commit occurs without errors (strangely):
250
revision1 = tree.commit('added a link to a Unicode target')
251
# python 2.4 failed with UnicodeDecodeError on this commit:
252
revision2 = tree.commit('this revision will be discarded')
253
# python 2.5 failed with UnicodeEncodeError on set_parent_ids:
254
tree.set_parent_ids([revision1])
255
except (UnicodeEncodeError, UnicodeDecodeError):
256
raise KnownFailure('there is no support for'
257
' symlinks to non-ASCII targets (bug #272444)')
245
revision1 = tree.commit('added a link to a Unicode target')
246
revision2 = tree.commit('this revision will be discarded')
247
tree.set_parent_ids([revision1])
249
self.addCleanup(tree.unlock)
250
# Check that the symlink target is safely round-tripped in the trees.
251
self.assertEqual(target, tree.get_symlink_target('link-id'))
252
basis = tree.basis_tree()
253
self.assertEqual(target, basis.get_symlink_target('link-id'))
260
256
class TestAddParent(TestParents):
266
262
uncommit(tree.branch, tree=tree)
267
263
tree.add_parent_tree_id(first_revision)
268
264
self.assertConsistentParents([first_revision], tree)
270
266
def test_add_first_parent_id_ghost_rejects(self):
271
267
"""Test adding the first parent id - as a ghost"""
272
268
tree = self.make_branch_and_tree('.')
273
269
self.assertRaises(errors.GhostRevisionUnusableHere,
274
270
tree.add_parent_tree_id, 'first-revision')
276
272
def test_add_first_parent_id_ghost_force(self):
277
273
"""Test adding the first parent id - as a ghost"""
278
274
tree = self.make_branch_and_tree('.')
285
281
tree.add_parent_tree_id('first-revision', allow_leftmost_as_ghost=True)
286
282
tree.add_parent_tree_id('second')
287
283
self.assertConsistentParents(['first-revision', 'second'], tree)
289
285
def test_add_second_parent_id(self):
290
286
"""Test adding the second parent id"""
291
287
tree = self.make_branch_and_tree('.')
294
290
second_revision = tree.commit('second post')
295
291
tree.add_parent_tree_id(first_revision)
296
292
self.assertConsistentParents([second_revision, first_revision], tree)
298
294
def test_add_second_parent_id_ghost(self):
299
295
"""Test adding the second parent id - as a ghost"""
300
296
tree = self.make_branch_and_tree('.')
301
297
first_revision = tree.commit('first post')
302
298
tree.add_parent_tree_id('second')
303
299
self.assertConsistentParents([first_revision, 'second'], tree)
305
301
def test_add_first_parent_tree(self):
306
302
"""Test adding the first parent id"""
307
303
tree = self.make_branch_and_tree('.')
310
306
tree.add_parent_tree((first_revision,
311
307
tree.branch.repository.revision_tree(first_revision)))
312
308
self.assertConsistentParents([first_revision], tree)
314
310
def test_add_first_parent_tree_ghost_rejects(self):
315
311
"""Test adding the first parent id - as a ghost"""
316
312
tree = self.make_branch_and_tree('.')
317
313
self.assertRaises(errors.GhostRevisionUnusableHere,
318
314
tree.add_parent_tree, ('first-revision', None))
320
316
def test_add_first_parent_tree_ghost_force(self):
321
317
"""Test adding the first parent id - as a ghost"""
322
318
tree = self.make_branch_and_tree('.')
323
319
tree.add_parent_tree(('first-revision', None),
324
320
allow_leftmost_as_ghost=True)
325
321
self.assertConsistentParents(['first-revision'], tree)
327
323
def test_add_second_parent_tree(self):
328
324
"""Test adding the second parent id"""
329
325
tree = self.make_branch_and_tree('.')
333
329
tree.add_parent_tree((first_revision,
334
330
tree.branch.repository.revision_tree(first_revision)))
335
331
self.assertConsistentParents([second_revision, first_revision], tree)
337
333
def test_add_second_parent_tree_ghost(self):
338
334
"""Test adding the second parent id - as a ghost"""
339
335
tree = self.make_branch_and_tree('.')
345
341
class UpdateToOneParentViaDeltaTests(TestCaseWithWorkingTree):
346
342
"""Tests for the update_basis_by_delta call.
348
344
This is intuitively defined as 'apply an inventory delta to the basis and
349
345
discard other parents', but for trees that have an inventory that is not
350
346
managed as a tree-by-id, the implementation requires roughly duplicated
397
393
if shape.root.revision is None:
398
394
shape.root.revision = revid
395
# Create the text records for this inventory.
396
for path, ie in shape.iter_entries():
398
lines = ['a' * ie.text_size]
401
tree.branch.repository.texts.add_lines(
402
(ie.file_id, ie.revision), [], lines)
399
403
sha1 = tree.branch.repository.add_inventory(revid, shape, [])
400
404
rev = Revision(timestamp=0,
404
408
inventory_sha1=sha1,
405
409
revision_id=revid)
406
410
tree.branch.repository.add_revision(revid, rev)
411
tree.branch.repository.commit_write_group()
408
413
tree.branch.repository.abort_write_group()
411
tree.branch.repository.commit_write_group()