1
# Copyright (C) 2005-2010 Canonical Ltd
1
# Copyright (C) 2005-2011 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
35
33
from bzrlib.bundle import read_mergeable_from_url
36
34
from bzrlib.bundle.apply_bundle import install_bundle, merge_bundle
37
35
from bzrlib.bundle.bundle_data import BundleTree
38
from bzrlib.bzrdir import BzrDir
39
36
from bzrlib.directory_service import directories
40
37
from bzrlib.bundle.serializer import write_bundle, read_bundle, v09, v4
41
38
from bzrlib.bundle.serializer.v08 import BundleSerializerV08
42
39
from bzrlib.bundle.serializer.v09 import BundleSerializerV09
43
40
from bzrlib.bundle.serializer.v4 import BundleSerializerV4
44
from bzrlib.branch import Branch
45
41
from bzrlib.repofmt import knitrepo
46
42
from bzrlib.tests import (
50
48
from bzrlib.transform import TreeTransform
76
75
self.root = InventoryDirectory(ROOT_ID, '', None)
78
77
inventory = property(lambda x:x)
81
return self.paths.iterkeys()
78
root_inventory = property(lambda x:x)
80
def get_root_id(self):
81
return self.root.file_id
83
def all_file_ids(self):
84
return set(self.paths.keys())
86
def is_executable(self, file_id):
87
# Not all the files are executable.
83
90
def __getitem__(self, file_id):
84
91
if file_id == self.root.file_id:
96
103
for path, file_id in self.ids.iteritems():
97
104
yield path, self[file_id]
99
def get_file_kind(self, file_id):
106
def kind(self, file_id):
100
107
if file_id in self.contents:
106
113
def make_entry(self, file_id, path):
107
from bzrlib.inventory import (InventoryEntry, InventoryFile
108
, InventoryDirectory, InventoryLink)
114
from bzrlib.inventory import (InventoryFile , InventoryDirectory,
109
116
name = os.path.basename(path)
110
kind = self.get_file_kind(file_id)
117
kind = self.kind(file_id)
111
118
parent_id = self.parent_id(file_id)
112
119
text_sha_1, text_size = self.contents_stats(file_id)
113
120
if kind == 'directory':
155
def get_file_revision(self, file_id):
156
return self.inventory[file_id].revision
158
def get_file_size(self, file_id):
159
return self.inventory[file_id].text_size
161
def get_file_sha1(self, file_id):
162
return self.inventory[file_id].text_sha1
148
164
def contents_stats(self, file_id):
149
165
if file_id not in self.contents:
150
166
return None, None
507
523
if not _mod_revision.is_null(rev_id):
508
rh = self.b1.revision_history()
509
tree.branch.set_revision_history(rh[:rh.index(rev_id)+1])
524
tree.branch.generate_revision_history(rev_id)
511
526
delta = tree.changes_from(self.b1.repository.revision_tree(rev_id))
512
527
self.assertFalse(delta.has_changed(),
648
663
bundle = self.get_valid_bundle('null:', 'a@cset-0-4')
651
open('b1/sub/dir/WithCaps.txt', 'ab').write('\nAdding some text\n')
652
open('b1/sub/dir/ pre space', 'ab').write(
666
with open('b1/sub/dir/WithCaps.txt', 'ab') as f: f.write('\nAdding some text\n')
667
with open('b1/sub/dir/ pre space', 'ab') as f: f.write(
653
668
'\r\nAdding some\r\nDOS format lines\r\n')
654
open('b1/sub/dir/nolastnewline.txt', 'ab').write('\n')
669
with open('b1/sub/dir/nolastnewline.txt', 'ab') as f: f.write('\n')
655
670
self.tree1.rename_one('sub/dir/ pre space',
656
671
'sub/ start space')
657
672
self.tree1.commit('Modified files', rev_id='a@cset-0-5')
679
694
def _test_symlink_bundle(self, link_name, link_target, new_link_target):
680
695
link_id = 'link-1'
682
self.requireFeature(tests.SymlinkFeature)
697
self.requireFeature(features.SymlinkFeature)
683
698
self.tree1 = self.make_branch_and_tree('b1')
684
699
self.b1 = self.tree1.branch
726
741
self._test_symlink_bundle('link', 'bar/foo', 'mars')
728
743
def test_unicode_symlink_bundle(self):
729
self.requireFeature(tests.UnicodeFilenameFeature)
744
self.requireFeature(features.UnicodeFilenameFeature)
730
745
self._test_symlink_bundle(u'\N{Euro Sign}link',
731
746
u'bar/\N{Euro Sign}foo',
732
747
u'mars\N{Euro Sign}')
806
821
self.tree1 = self.make_branch_and_tree('b1')
807
822
self.b1 = self.tree1.branch
809
open('b1/one', 'wb').write('one\n')
824
with open('b1/one', 'wb') as f: f.write('one\n')
810
825
self.tree1.add('one')
811
826
self.tree1.commit('add file', rev_id='a@cset-0-1')
812
open('b1/one', 'wb').write('two\n')
827
with open('b1/one', 'wb') as f: f.write('two\n')
813
828
self.tree1.commit('modify', rev_id='a@cset-0-2')
814
open('b1/one', 'wb').write('three\n')
829
with open('b1/one', 'wb') as f: f.write('three\n')
815
830
self.tree1.commit('modify', rev_id='a@cset-0-3')
816
831
bundle_file = StringIO()
817
832
rev_ids = write_bundle(self.tree1.branch.repository, 'a@cset-0-3',
833
848
return bundle_file.getvalue()
835
850
def test_unicode_bundle(self):
836
self.requireFeature(tests.UnicodeFilenameFeature)
851
self.requireFeature(features.UnicodeFilenameFeature)
837
852
# Handle international characters
839
854
f = open(u'b1/with Dod\N{Euro Sign}', 'wb')
896
911
bundle = self.get_valid_bundle('null:', 'white-1')
899
open('b1/trailing space ', 'ab').write('add some text\n')
914
with open('b1/trailing space ', 'ab') as f: f.write('add some text\n')
900
915
self.tree1.commit('add text', rev_id='white-2')
902
917
bundle = self.get_valid_bundle('white-1', 'white-2')
944
959
self.tree1.commit('message', rev_id='revid1')
945
960
bundle = self.get_valid_bundle('null:', 'revid1')
946
961
tree = self.get_bundle_tree(bundle, 'revid1')
947
self.assertEqual('revid1', tree.inventory.root.revision)
962
root_revision = tree.get_file_revision(tree.get_root_id())
963
self.assertEqual('revid1', root_revision)
949
965
def test_install_revisions(self):
950
966
self.tree1 = self.make_branch_and_tree('b1')
1412
1428
branch = tree_a.branch
1413
1429
repo_a = branch.repository
1414
1430
tree_a.commit("base", allow_pointless=True, rev_id='A')
1415
self.failIf(branch.repository.has_signature_for_revision_id('A'))
1431
self.assertFalse(branch.repository.has_signature_for_revision_id('A'))
1417
1433
from bzrlib.testament import Testament
1418
1434
# monkey patch gpg signing mechanism
1419
1435
bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
1420
new_config = test_commit.MustSignConfig(branch)
1421
commit.Commit(config=new_config).commit(message="base",
1436
new_config = test_commit.MustSignConfig()
1437
commit.Commit(config_stack=new_config).commit(message="base",
1422
1438
allow_pointless=True,
1424
1440
working_tree=tree_a)
1839
1849
bundle, then the ConnectionReset error should be propagated.
1841
1851
# Instantiate a server that will provoke a ConnectionReset
1842
sock_server = _DisconnectingTCPServer()
1852
sock_server = DisconnectingServer()
1843
1853
self.start_server(sock_server)
1844
1854
# We don't really care what the url is since the server will close the
1845
1855
# connection without interpreting it
1847
1857
self.assertRaises(errors.ConnectionReset, read_mergeable_from_url, url)
1850
class _DisconnectingTCPServer(object):
1851
"""A TCP server that immediately closes any connection made to it."""
1853
def start_server(self):
1854
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1855
self.sock.bind(('127.0.0.1', 0))
1857
self.port = self.sock.getsockname()[1]
1858
self.thread = threading.Thread(
1859
name='%s (port %d)' % (self.__class__.__name__, self.port),
1860
target=self.accept_and_close)
1863
def accept_and_close(self):
1864
conn, addr = self.sock.accept()
1865
conn.shutdown(socket.SHUT_RDWR)
1860
class DisconnectingHandler(SocketServer.BaseRequestHandler):
1861
"""A request handler that immediately closes any connection made to it."""
1864
self.request.close()
1867
class DisconnectingServer(test_server.TestingTCPServerInAThread):
1870
super(DisconnectingServer, self).__init__(
1872
test_server.TestingTCPServer,
1873
DisconnectingHandler)
1868
1875
def get_url(self):
1869
return 'bzr://127.0.0.1:%d/' % (self.port,)
1871
def stop_server(self):
1873
# make sure the thread dies by connecting to the listening socket,
1874
# just in case the test failed to do so.
1875
conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
1876
conn.connect(self.sock.getsockname())
1878
except socket.error:
1876
"""Return the url of the server"""
1877
return "bzr://%s:%d/" % self.server.server_address