Rev 4725: Merge bzr/2.0 at 4725, resolve NEWS in http://bazaar.launchpad.net/~jameinel/bzr/bdist_rpm
John Arbash Meinel
john at arbash-meinel.com
Wed Jan 13 16:27:48 GMT 2010
At http://bazaar.launchpad.net/~jameinel/bzr/bdist_rpm
------------------------------------------------------------
revno: 4725 [merge]
revision-id: john at arbash-meinel.com-20100113162722-c177orxwb4fo19xe
parent: john at arbash-meinel.com-20100113162457-dlhtnmy57mfmddo5
parent: pqm at pqm.ubuntu.com-20100113074324-g4mbj7sdxktz602t
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: bdist_rpm
timestamp: Wed 2010-01-13 10:27:22 -0600
message:
Merge bzr/2.0 at 4725, resolve NEWS
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/dirstate.py dirstate.py-20060728012006-d6mvoihjb3je9peu-1
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/blackbox/test_pull.py test_pull.py-20051201144907-64959364f629947f
bzrlib/tests/per_workingtree/test_pull.py test_pull.py-20060222044334-43594dd8e143b708
bzrlib/tests/per_workingtree/test_set_root_id.py test_set_root_id.py-20061004073850-0r1c7qikmnkb8m9k-1
bzrlib/tests/per_workingtree/test_workingtree.py test_workingtree.py-20060203003124-817757d3e31444fb
bzrlib/tests/test_dirstate.py test_dirstate.py-20060728012006-d6mvoihjb3je9peu-2
bzrlib/tests/test_revert.py test_revert.py-20060828180832-fqb1v6ecpyvnlitj-1
bzrlib/tests/test_shelf.py test_prepare_shelf.p-20081005181341-n74qe6gu1e65ad4v-2
bzrlib/tests/test_switch.py test_switch.py-20071116011000-v5lnw7d2wkng9eux-2
bzrlib/tests/test_transform.py test_transaction.py-20060105172520-b3ffb3946550e6c4
bzrlib/transform.py transform.py-20060105172343-dd99e54394d91687
bzrlib/workingtree.py workingtree.py-20050511021032-29b6ec0a681e02e3
setup.py setup.py-20050314065409-02f8a0a6e3f9bc70
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2010-01-13 16:24:57 +0000
+++ b/NEWS 2010-01-13 16:27:22 +0000
@@ -41,12 +41,21 @@
* Give a clearer message if the lockdir disappears after being apparently
successfully taken. (Martin Pool, #498378)
+* Give a warning when fetching between local repositories with
+ sufficiently different formats that the content will need to be
+ serialized (ie ``InterDifferingSerializer``) so the user has a clue that
+ upgrading could make it faster.
+ (Martin Pool, #456077)
+
* If we fail to open ``~/.bzr.log`` write a clear message to stderr rather
than using ``warning()``. The log file is opened before logging is set
up, and it leads to very confusing: 'no handlers for "bzr"' messages for
users, rather than something nicer.
(John Arbash Meinel, Barry Warsaw, #503886)
+* Refuse to build with any Pyrex 0.9.4 release, as they have known bugs.
+ (Martin Pool, John Arbash Meinel, #449372)
+
* ``setup.py bdist_rpm`` now properly finds extra files needed for the
build. (Joe Julian)
@@ -54,6 +63,12 @@
changed underneath it (like another autopack). Now concurrent
autopackers will properly succeed. (John Arbash Meinel, #495000)
+* ``TreeTransform`` can now handle when a delta says that the file id for
+ the tree root changes. Rather than trying to rename your working
+ directory, or failing early saying that you can't have multiple
+ tree roots. This also fixes revert, update, and pull when the root id
+ changes. (John Arbash Meinel, #494269, #504390)
+
* ``_update_current_block`` no longer suppresses exceptions, so ^C at just
the right time will get propagated, rather than silently failing to move
the block pointer. (John Arbash Meinel, Gareth White, #495023)
=== modified file 'bzrlib/dirstate.py'
--- a/bzrlib/dirstate.py 2009-10-01 00:56:56 +0000
+++ b/bzrlib/dirstate.py 2010-01-12 22:32:34 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2008 Canonical Ltd
+# Copyright (C) 2006-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -1997,6 +1997,8 @@
entry_index, present = self._find_entry_index(key, block)
if present:
entry = self._dirblocks[block_index][1][entry_index]
+ # TODO: We might want to assert that entry[0][2] ==
+ # fileid_utf8.
if entry[1][tree_index][0] in 'fdlt':
# this is the result we are looking for: the
# real home of this file_id in this tree.
@@ -2354,8 +2356,6 @@
self.update_minimal(('', '', new_id), 'd',
path_utf8='', packed_stat=entry[1][0][4])
self._dirblock_state = DirState.IN_MEMORY_MODIFIED
- if self._id_index is not None:
- self._id_index.setdefault(new_id, set()).add(entry[0])
def set_parent_trees(self, trees, ghosts):
"""Set the parent trees for the dirstate.
@@ -3013,6 +3013,13 @@
if absent_positions == tree_count:
raise AssertionError(
"entry %r has no data for any tree." % (entry,))
+ if self._id_index is not None:
+ for file_id, entry_keys in self._id_index.iteritems():
+ for entry_key in entry_keys:
+ if entry_key[2] != file_id:
+ raise AssertionError(
+ 'file_id %r did not match entry key %s'
+ % (file_id, entry_key))
def _wipe_state(self):
"""Forget all state information about the dirstate."""
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py 2009-09-03 02:04:04 +0000
+++ b/bzrlib/repository.py 2010-01-12 06:12:31 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
+# Copyright (C) 2005-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -39,6 +39,7 @@
osutils,
revision as _mod_revision,
symbol_versioning,
+ trace,
tsort,
ui,
versionedfile,
@@ -3979,6 +3980,15 @@
"""See InterRepository.fetch()."""
if fetch_spec is not None:
raise AssertionError("Not implemented yet...")
+ # See <https://launchpad.net/bugs/456077> asking for a warning here
+ #
+ # nb this is only active for local-local fetches; other things using
+ # streaming.
+ trace.warning("Fetching between repositories with different formats\n"
+ "from %s to %s.\n"
+ "This may take some time. Upgrade the branches to the same format \n"
+ "for better results.\n"
+ % (self.source._format, self.target._format))
if (not self.source.supports_rich_root()
and self.target.supports_rich_root()):
self._converting_to_rich_root = True
=== modified file 'bzrlib/tests/blackbox/test_pull.py'
--- a/bzrlib/tests/blackbox/test_pull.py 2009-06-15 06:47:14 +0000
+++ b/bzrlib/tests/blackbox/test_pull.py 2010-01-13 16:27:22 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2006 Canonical Ltd
+# Copyright (C) 2005-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -390,4 +390,14 @@
self.assertLength(18, self.hpss_calls)
remote = Branch.open('stacked')
self.assertEndsWith(remote.get_stacked_on_url(), '/parent')
+
+ def test_pull_cross_format_warning(self):
+ """You get a warning for probably slow cross-format pulls.
+ """
+ from_tree = self.make_branch_and_tree('from', format='2a')
+ to_tree = self.make_branch_and_tree('to', format='1.14-rich-root')
+ from_tree.commit(message='first commit')
+ out, err = self.run_bzr(['pull', '-d', 'to', 'from'])
+ self.assertContainsRe(err,
+ "(?m)Fetching between repositories with different formats.*")
=== modified file 'bzrlib/tests/per_workingtree/test_pull.py'
--- a/bzrlib/tests/per_workingtree/test_pull.py 2009-07-10 07:14:02 +0000
+++ b/bzrlib/tests/per_workingtree/test_pull.py 2010-01-11 23:02:32 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006 Canonical Ltd
+# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
# Authors: Robert Collins <robert.collins at canonical.com>
#
# This program is free software; you can redistribute it and/or modify
@@ -56,3 +56,15 @@
tree_b.pull(tree_a.branch)
self.assertFileEqual('contents of from/file\n', 'to/file')
+ def test_pull_changes_root_id(self):
+ tree = self.make_branch_and_tree('from')
+ tree.set_root_id('first_root_id')
+ self.build_tree(['from/file'])
+ tree.add(['file'])
+ tree.commit('first')
+ to_tree = tree.bzrdir.sprout('to').open_workingtree()
+ self.assertEqual('first_root_id', to_tree.get_root_id())
+ tree.set_root_id('second_root_id')
+ tree.commit('second')
+ to_tree.pull(tree.branch)
+ self.assertEqual('second_root_id', to_tree.get_root_id())
=== modified file 'bzrlib/tests/per_workingtree/test_set_root_id.py'
--- a/bzrlib/tests/per_workingtree/test_set_root_id.py 2009-09-10 06:32:42 +0000
+++ b/bzrlib/tests/per_workingtree/test_set_root_id.py 2010-01-12 22:34:03 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006 Canonical Ltd
+# Copyright (C) 2006-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -16,7 +16,7 @@
"""Tests for WorkingTree.set_root_id"""
-from bzrlib import inventory
+from bzrlib import errors, inventory
from bzrlib.tests.per_workingtree import TestCaseWithWorkingTree
@@ -48,3 +48,19 @@
# should still be retained
tree = tree.bzrdir.open_workingtree()
self.assertEqual(root_id, tree.get_root_id())
+ tree._validate()
+
+ def test_set_root_id(self):
+ tree = self.make_branch_and_tree('.')
+ tree.lock_write()
+ self.addCleanup(tree.unlock)
+ orig_root_id = tree.get_root_id()
+ self.assertNotEqual('custom-root-id', orig_root_id)
+ self.assertEqual('', tree.id2path(orig_root_id))
+ self.assertRaises(errors.NoSuchId, tree.id2path, 'custom-root-id')
+ tree.set_root_id('custom-root-id')
+ self.assertEqual('custom-root-id', tree.get_root_id())
+ self.assertEqual('custom-root-id', tree.path2id(''))
+ self.assertEqual('', tree.id2path('custom-root-id'))
+ self.assertRaises(errors.NoSuchId, tree.id2path, orig_root_id)
+ tree._validate()
=== modified file 'bzrlib/tests/per_workingtree/test_workingtree.py'
--- a/bzrlib/tests/per_workingtree/test_workingtree.py 2009-08-20 04:09:58 +0000
+++ b/bzrlib/tests/per_workingtree/test_workingtree.py 2010-01-13 16:27:22 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2006, 2007 Canonical Ltd
+# Copyright (C) 2006-2010 Canonical Ltd
# Authors: Robert Collins <robert.collins at canonical.com>
# and others
#
@@ -478,6 +478,20 @@
self.assertEqual(wt.get_root_id(), checkout.get_root_id())
self.assertNotEqual(None, wt.get_root_id())
+ def test_update_sets_updated_root_id(self):
+ wt = self.make_branch_and_tree('tree')
+ wt.set_root_id('first_root_id')
+ self.assertEqual('first_root_id', wt.get_root_id())
+ self.build_tree(['tree/file'])
+ wt.add(['file'])
+ wt.commit('first')
+ co = wt.branch.create_checkout('checkout')
+ wt.set_root_id('second_root_id')
+ wt.commit('second')
+ self.assertEqual('second_root_id', wt.get_root_id())
+ self.assertEqual(0, co.update())
+ self.assertEqual('second_root_id', co.get_root_id())
+
def test_update_returns_conflict_count(self):
# working tree formats from the meta-dir format and newer support
# setting the last revision on a tree independently of that on the
=== modified file 'bzrlib/tests/test_dirstate.py'
--- a/bzrlib/tests/test_dirstate.py 2009-08-17 03:33:56 +0000
+++ b/bzrlib/tests/test_dirstate.py 2010-01-12 20:51:58 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007 Canonical Ltd
+# Copyright (C) 2006-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -873,15 +873,23 @@
state = dirstate.DirState.initialize('dirstate')
try:
# check precondition to be sure the state does change appropriately.
- self.assertEqual(
- [(('', '', 'TREE_ROOT'), [('d', '', 0, False,
- 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')])],
- list(state._iter_entries()))
- state.set_path_id('', 'foobarbaz')
- expected_rows = [
- (('', '', 'foobarbaz'), [('d', '', 0, False,
- 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')])]
+ root_entry = (('', '', 'TREE_ROOT'), [('d', '', 0, False, 'x'*32)])
+ self.assertEqual([root_entry], list(state._iter_entries()))
+ self.assertEqual(root_entry, state._get_entry(0, path_utf8=''))
+ self.assertEqual(root_entry,
+ state._get_entry(0, fileid_utf8='TREE_ROOT'))
+ self.assertEqual((None, None),
+ state._get_entry(0, fileid_utf8='second-root-id'))
+ state.set_path_id('', 'second-root-id')
+ new_root_entry = (('', '', 'second-root-id'),
+ [('d', '', 0, False, 'x'*32)])
+ expected_rows = [new_root_entry]
self.assertEqual(expected_rows, list(state._iter_entries()))
+ self.assertEqual(new_root_entry, state._get_entry(0, path_utf8=''))
+ self.assertEqual(new_root_entry,
+ state._get_entry(0, fileid_utf8='second-root-id'))
+ self.assertEqual((None, None),
+ state._get_entry(0, fileid_utf8='TREE_ROOT'))
# should work across save too
state.save()
finally:
@@ -905,21 +913,36 @@
state._validate()
try:
state.set_parent_trees([('parent-revid', rt)], ghosts=[])
- state.set_path_id('', 'foobarbaz')
+ root_entry = (('', '', 'TREE_ROOT'),
+ [('d', '', 0, False, 'x'*32),
+ ('d', '', 0, False, 'parent-revid')])
+ self.assertEqual(root_entry, state._get_entry(0, path_utf8=''))
+ self.assertEqual(root_entry,
+ state._get_entry(0, fileid_utf8='TREE_ROOT'))
+ self.assertEqual((None, None),
+ state._get_entry(0, fileid_utf8='Asecond-root-id'))
+ state.set_path_id('', 'Asecond-root-id')
state._validate()
# now see that it is what we expected
- expected_rows = [
- (('', '', 'TREE_ROOT'),
- [('a', '', 0, False, ''),
- ('d', '', 0, False, 'parent-revid'),
- ]),
- (('', '', 'foobarbaz'),
- [('d', '', 0, False, ''),
- ('a', '', 0, False, ''),
- ]),
- ]
+ old_root_entry = (('', '', 'TREE_ROOT'),
+ [('a', '', 0, False, ''),
+ ('d', '', 0, False, 'parent-revid')])
+ new_root_entry = (('', '', 'Asecond-root-id'),
+ [('d', '', 0, False, ''),
+ ('a', '', 0, False, '')])
+ expected_rows = [new_root_entry, old_root_entry]
state._validate()
self.assertEqual(expected_rows, list(state._iter_entries()))
+ self.assertEqual(new_root_entry, state._get_entry(0, path_utf8=''))
+ self.assertEqual(old_root_entry, state._get_entry(1, path_utf8=''))
+ self.assertEqual((None, None),
+ state._get_entry(0, fileid_utf8='TREE_ROOT'))
+ self.assertEqual(old_root_entry,
+ state._get_entry(1, fileid_utf8='TREE_ROOT'))
+ self.assertEqual(new_root_entry,
+ state._get_entry(0, fileid_utf8='Asecond-root-id'))
+ self.assertEqual((None, None),
+ state._get_entry(1, fileid_utf8='Asecond-root-id'))
# should work across save too
state.save()
finally:
=== modified file 'bzrlib/tests/test_revert.py'
--- a/bzrlib/tests/test_revert.py 2009-03-23 14:59:43 +0000
+++ b/bzrlib/tests/test_revert.py 2010-01-11 22:27:17 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006 Canonical Ltd
+# Copyright (C) 2006, 2007, 2009, 2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -157,3 +157,14 @@
self.failUnlessExists('dir/file1')
self.failIfExists('dir/file2')
self.assertEqual('dir-id', tree.path2id('dir'))
+
+ def test_revert_root_id_change(self):
+ tree = self.make_branch_and_tree('.')
+ tree.set_root_id('initial-root-id')
+ self.build_tree(['file1'])
+ tree.add(['file1'])
+ tree.commit('first')
+ tree.set_root_id('temp-root-id')
+ self.assertEqual('temp-root-id', tree.get_root_id())
+ tree.revert()
+ self.assertEqual('initial-root-id', tree.get_root_id())
=== modified file 'bzrlib/tests/test_shelf.py'
--- a/bzrlib/tests/test_shelf.py 2009-09-10 06:32:42 +0000
+++ b/bzrlib/tests/test_shelf.py 2010-01-12 18:05:31 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2008 Canonical Ltd
+# Copyright (C) 2008, 2009, 2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -108,6 +108,29 @@
creator.shelve_change(('rename', 'baz-id', 'foo/baz', 'bar/baz'))
self.check_shelve_move(creator, tree)
+ def test_shelve_changed_root_id(self):
+ tree = self.make_branch_and_tree('.')
+ self.build_tree(['foo'])
+ tree.set_root_id('first-root-id')
+ tree.add(['foo'], ['foo-id'])
+ tree.commit('foo')
+ tree.set_root_id('second-root-id')
+ tree.lock_tree_write()
+ self.addCleanup(tree.unlock)
+ creator = shelf.ShelfCreator(tree, tree.basis_tree())
+ self.addCleanup(creator.finalize)
+ self.expectFailure('shelf doesn\'t support shelving root changes yet',
+ self.assertEqual, [
+ ('delete file', 'first-root-id', 'directory', ''),
+ ('add file', 'second-root-id', 'directory', ''),
+ ('rename', 'foo-id', u'foo', u'foo'),
+ ], list(creator.iter_shelvable()))
+
+ self.assertEqual([('delete file', 'first-root-id', 'directory', ''),
+ ('add file', 'second-root-id', 'directory', ''),
+ ('rename', 'foo-id', u'foo', u'foo'),
+ ], list(creator.iter_shelvable()))
+
def assertShelvedFileEqual(self, expected_content, creator, file_id):
s_trans_id = creator.shelf_transform.trans_id_file_id(file_id)
shelf_file = creator.shelf_transform._limbo_name(s_trans_id)
=== modified file 'bzrlib/tests/test_switch.py'
--- a/bzrlib/tests/test_switch.py 2009-05-07 05:08:46 +0000
+++ b/bzrlib/tests/test_switch.py 2010-01-12 18:10:23 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Canonical Ltd
+# Copyright (C) 2007-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -100,6 +100,18 @@
self.assertContainsRe(str(err),
"Pending merges must be committed or reverted before using switch")
+ def test_switch_changing_root_id(self):
+ tree = self._setup_tree()
+ tree2 = self.make_branch_and_tree('tree-2')
+ tree2.set_root_id('custom-root-id')
+ self.build_tree(['tree-2/file-2'])
+ tree2.add(['file-2'])
+ tree2.commit('rev1b')
+ checkout = tree.branch.create_checkout('checkout',
+ lightweight=self.lightweight)
+ switch.switch(checkout.bzrdir, tree2.branch)
+ self.assertEqual('custom-root-id', tree2.get_root_id())
+
class TestSwitchHeavyweight(TestSwitch):
=== modified file 'bzrlib/tests/test_transform.py'
--- a/bzrlib/tests/test_transform.py 2009-10-14 18:37:13 +0000
+++ b/bzrlib/tests/test_transform.py 2010-01-13 16:27:22 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2008 Canonical Ltd
+# Copyright (C) 2006-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -136,6 +136,36 @@
transform.finalize()
transform.finalize()
+ def test_change_root_id(self):
+ transform, root = self.get_transform()
+ self.assertNotEqual('new-root-id', self.wt.get_root_id())
+ transform.new_directory('', ROOT_PARENT, 'new-root-id')
+ transform.delete_contents(root)
+ transform.unversion_file(root)
+ transform.fixup_new_roots()
+ transform.apply()
+ self.assertEqual('new-root-id', self.wt.get_root_id())
+
+ def test_change_root_id_add_files(self):
+ transform, root = self.get_transform()
+ self.assertNotEqual('new-root-id', self.wt.get_root_id())
+ new_trans_id = transform.new_directory('', ROOT_PARENT, 'new-root-id')
+ transform.new_file('file', new_trans_id, ['new-contents\n'],
+ 'new-file-id')
+ transform.delete_contents(root)
+ transform.unversion_file(root)
+ transform.fixup_new_roots()
+ transform.apply()
+ self.assertEqual('new-root-id', self.wt.get_root_id())
+ self.assertEqual('new-file-id', self.wt.path2id('file'))
+ self.assertFileEqual('new-contents\n', self.wt.abspath('file'))
+
+ def test_add_two_roots(self):
+ transform, root = self.get_transform()
+ new_trans_id = transform.new_directory('', ROOT_PARENT, 'new-root-id')
+ new_trans_id = transform.new_directory('', ROOT_PARENT, 'alt-root-id')
+ self.assertRaises(ValueError, transform.fixup_new_roots)
+
def test_hardlink(self):
self.requireFeature(HardlinkFeature)
transform, root = self.get_transform()
@@ -746,7 +776,7 @@
create.apply()
transform, root = self.get_transform()
transform.adjust_root_path('oldroot', fun)
- new_root=transform.trans_id_tree_path('')
+ new_root = transform.trans_id_tree_path('')
transform.version_file('new-root', new_root)
transform.apply()
@@ -2428,7 +2458,7 @@
def test_file_content_summary_executable(self):
if not osutils.supports_executable():
- raise TestNotApplicable()
+ raise tests.TestNotApplicable()
preview = self.get_empty_preview()
path_id = preview.new_file('path', preview.root, 'contents', 'path-id')
preview.set_executability(True, path_id)
@@ -2443,8 +2473,6 @@
self.assertIs(None, summary[3])
def test_change_executability(self):
- if not osutils.supports_executable():
- raise TestNotApplicable()
tree = self.make_branch_and_tree('tree')
self.build_tree(['tree/path'])
tree.add('path')
@@ -2616,7 +2644,7 @@
preview = self.get_empty_preview()
root = preview.new_directory('', ROOT_PARENT, 'tree-root')
# FIXME: new_directory should mark root.
- preview.adjust_path('', ROOT_PARENT, root)
+ preview.fixup_new_roots()
preview_tree = preview.get_preview_tree()
file_trans_id = preview.new_file('a', preview.root, 'contents',
'a-id')
=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py 2009-10-28 07:34:55 +0000
+++ b/bzrlib/transform.py 2010-01-13 16:27:22 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd
+# Copyright (C) 2006-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -161,14 +161,12 @@
def adjust_path(self, name, parent, trans_id):
"""Change the path that is assigned to a transaction id."""
+ if parent is None:
+ raise ValueError("Parent trans-id may not be None")
if trans_id == self._new_root:
raise CantMoveRoot
self._new_name[trans_id] = name
self._new_parent[trans_id] = parent
- if parent == ROOT_PARENT:
- if self._new_root is not None:
- raise ValueError("Cannot have multiple roots.")
- self._new_root = trans_id
def adjust_root_path(self, name, parent):
"""Emulate moving the root by moving all children, instead.
@@ -202,6 +200,67 @@
self.version_file(old_root_file_id, old_root)
self.unversion_file(self._new_root)
+ def fixup_new_roots(self):
+ """Reinterpret requests to change the root directory
+
+ Instead of creating a root directory, or moving an existing directory,
+ all the attributes and children of the new root are applied to the
+ existing root directory.
+
+ This means that the old root trans-id becomes obsolete, so it is
+ recommended only to invoke this after the root trans-id has become
+ irrelevant.
+ """
+ new_roots = [k for k, v in self._new_parent.iteritems() if v is
+ ROOT_PARENT]
+ if len(new_roots) < 1:
+ return
+ if len(new_roots) != 1:
+ raise ValueError('A tree cannot have two roots!')
+ if self._new_root is None:
+ self._new_root = new_roots[0]
+ return
+ old_new_root = new_roots[0]
+ # TODO: What to do if a old_new_root is present, but self._new_root is
+ # not listed as being removed? This code explicitly unversions
+ # the old root and versions it with the new file_id. Though that
+ # seems like an incomplete delta
+
+ # unversion the new root's directory.
+ file_id = self.final_file_id(old_new_root)
+ if old_new_root in self._new_id:
+ self.cancel_versioning(old_new_root)
+ else:
+ self.unversion_file(old_new_root)
+ # if, at this stage, root still has an old file_id, zap it so we can
+ # stick a new one in.
+ if (self.tree_file_id(self._new_root) is not None and
+ self._new_root not in self._removed_id):
+ self.unversion_file(self._new_root)
+ self.version_file(file_id, self._new_root)
+
+ # Now move children of new root into old root directory.
+ # Ensure all children are registered with the transaction, but don't
+ # use directly-- some tree children have new parents
+ list(self.iter_tree_children(old_new_root))
+ # Move all children of new root into old root directory.
+ for child in self.by_parent().get(old_new_root, []):
+ self.adjust_path(self.final_name(child), self._new_root, child)
+
+ # Ensure old_new_root has no directory.
+ if old_new_root in self._new_contents:
+ self.cancel_creation(old_new_root)
+ else:
+ self.delete_contents(old_new_root)
+
+ # prevent deletion of root directory.
+ if self._new_root in self._removed_contents:
+ self.cancel_deletion(self._new_root)
+
+ # destroy path info for old_new_root.
+ del self._new_parent[old_new_root]
+ del self._new_name[old_new_root]
+
def trans_id_tree_file_id(self, inventory_id):
"""Determine the transaction id of a working tree file.
@@ -253,6 +312,8 @@
def delete_contents(self, trans_id):
"""Schedule the contents of a path entry for deletion"""
+ # Ensure that the object exists in the WorkingTree, this will raise an
+ # exception if there is a problem
self.tree_kind(trans_id)
self._removed_contents.add(trans_id)
@@ -1075,8 +1136,10 @@
if (trans_id in self._limbo_files and
trans_id not in self._needs_rename):
self._rename_in_limbo([trans_id])
- self._limbo_children[previous_parent].remove(trans_id)
- del self._limbo_children_names[previous_parent][previous_name]
+ if previous_parent != parent:
+ self._limbo_children[previous_parent].remove(trans_id)
+ if previous_parent != parent or previous_name != name:
+ del self._limbo_children_names[previous_parent][previous_name]
def _rename_in_limbo(self, trans_ids):
"""Fix limbo names so that the right final path is produced.
@@ -1542,10 +1605,10 @@
child_pb.update('removing file', num, len(tree_paths))
full_path = self._tree.abspath(path)
if trans_id in self._removed_contents:
- mover.pre_delete(full_path, os.path.join(self._deletiondir,
- trans_id))
- elif trans_id in self._new_name or trans_id in \
- self._new_parent:
+ delete_path = os.path.join(self._deletiondir, trans_id)
+ mover.pre_delete(full_path, delete_path)
+ elif (trans_id in self._new_name
+ or trans_id in self._new_parent):
try:
mover.rename(full_path, self._limbo_name(trans_id))
except OSError, e:
@@ -2636,7 +2699,10 @@
parent_trans = ROOT_PARENT
else:
parent_trans = tt.trans_id_file_id(parent[1])
- tt.adjust_path(name[1], parent_trans, trans_id)
+ if parent[0] is None and versioned[0]:
+ tt.adjust_root_path(name[1], parent_trans)
+ else:
+ tt.adjust_path(name[1], parent_trans, trans_id)
if executable[0] != executable[1] and kind[1] == "file":
tt.set_executability(executable[1], trans_id)
if working_tree.supports_content_filtering():
@@ -2655,6 +2721,7 @@
for (trans_id, mode_id), bytes in target_tree.iter_files_bytes(
deferred_files):
tt.create_file(bytes, trans_id, mode_id)
+ tt.fixup_new_roots()
finally:
if basis_tree is not None:
basis_tree.unlock()
=== modified file 'bzrlib/workingtree.py'
--- a/bzrlib/workingtree.py 2009-08-26 05:38:16 +0000
+++ b/bzrlib/workingtree.py 2010-01-13 16:27:22 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
+# Copyright (C) 2005-2010 Canonical Ltd
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -1624,9 +1624,10 @@
this_tree=self,
pb=pb,
change_reporter=change_reporter)
- if (basis_tree.inventory.root is None and
- new_basis_tree.inventory.root is not None):
- self.set_root_id(new_basis_tree.get_root_id())
+ basis_root_id = basis_tree.get_root_id()
+ new_root_id = new_basis_tree.get_root_id()
+ if basis_root_id != new_root_id:
+ self.set_root_id(new_root_id)
finally:
pb.finished()
basis_tree.unlock()
@@ -2245,8 +2246,10 @@
basis.lock_read()
try:
to_tree = self.branch.basis_tree()
- if basis.inventory.root is None:
- self.set_root_id(to_tree.get_root_id())
+ to_root_id = to_tree.get_root_id()
+ if (basis.inventory.root is None
+ or basis.inventory.root.file_id != to_root_id):
+ self.set_root_id(to_root_id)
self.flush()
result += merge.merge_inner(
self.branch,
=== modified file 'setup.py'
--- a/setup.py 2009-10-30 14:07:31 +0000
+++ b/setup.py 2010-01-12 01:44:13 +0000
@@ -278,11 +278,13 @@
add_pyrex_extension('bzrlib._walkdirs_win32')
z_lib = 'zdll'
else:
- if have_pyrex and pyrex_version == '0.9.4.1':
+ if have_pyrex and pyrex_version.startswith('0.9.4'):
# Pyrex 0.9.4.1 fails to compile this extension correctly
# The code it generates re-uses a "local" pointer and
# calls "PY_DECREF" after having set it to NULL. (It mixes PY_XDECREF
# which is NULL safe with PY_DECREF which is not.)
+ # <https://bugs.edge.launchpad.net/bzr/+bug/449372>
+ # <https://bugs.edge.launchpad.net/bzr/+bug/276868>
print 'Cannot build extension "bzrlib._dirstate_helpers_pyx" using'
print 'your version of pyrex "%s". Please upgrade your pyrex' % (
pyrex_version,)
More information about the bazaar-commits
mailing list