19
19
from bzrlib.add import smart_add
20
from bzrlib.branch import Branch
20
21
from bzrlib.builtins import merge
21
from bzrlib.errors import IllegalPath
22
from bzrlib.clone import copy_branch
22
23
from bzrlib.delta import compare_trees
23
from bzrlib.tests import TestSkipped
24
from bzrlib.tests.repository_implementations.test_repository import TestCaseWithRepository
24
from bzrlib.fetch import greedy_fetch
25
from bzrlib.merge import merge_inner
26
from bzrlib.revision import common_ancestor
27
from bzrlib.tests import TestCaseWithTransport
25
28
from bzrlib.workingtree import WorkingTree
28
class FileIdInvolvedBase(TestCaseWithRepository):
31
class TestFileIdInvolved(TestCaseWithTransport):
30
33
def touch(self,filename):
31
34
f = file(filename,"a")
32
35
f.write("appended line\n")
35
def compare_tree_fileids(self, branch, old_rev, new_rev):
36
old_tree = self.branch.repository.revision_tree(old_rev)
37
new_tree = self.branch.repository.revision_tree(new_rev)
38
delta = compare_trees(old_tree, new_tree)
40
l2 = [id for path, id, kind in delta.added] + \
41
[id for oldpath, newpath, id, kind, text_modified, \
42
meta_modified in delta.renamed] + \
43
[id for path, id, kind, text_modified, meta_modified in \
48
class TestFileIdInvolved(FileIdInvolvedBase):
38
def merge(self, branch_from, wt_to):
39
# minimal ui-less merge.
40
greedy_fetch(to_branch=wt_to.branch, from_branch=branch_from,
41
revision=branch_from.last_revision())
42
base_rev = common_ancestor(branch_from.last_revision(),
43
wt_to.branch.last_revision(),
44
wt_to.branch.repository)
45
merge_inner(wt_to.branch, branch_from.working_tree(),
46
wt_to.branch.repository.revision_tree(base_rev),
48
wt_to.add_pending_merge(branch_from.last_revision())
51
51
super(TestFileIdInvolved, self).setUp()
134
116
self.branch = main_branch
136
def test_fileids_altered_between_two_revs(self):
138
print set(self.branch.repository.get_ancestry(new)).difference(set(self.branch.repository.get_ancestry(old)))
141
{'b-file-id-2006-01-01-defg':set(['rev-J']),
142
'c-funky<file-id> quiji%bo':set(['rev-K'])
144
self.branch.repository.fileids_altered_by_revision_ids(["rev-J","rev-K"]))
147
{'b-file-id-2006-01-01-defg': set(['rev-<D>']),
148
'file-d': set(['rev-F']),
150
self.branch.repository.fileids_altered_by_revision_ids(['rev-<D>', 'rev-F']))
154
'b-file-id-2006-01-01-defg': set(['rev-<D>', 'rev-G', 'rev-J']),
155
'c-funky<file-id> quiji%bo': set(['rev-K']),
156
'file-d': set(['rev-F']),
158
self.branch.repository.fileids_altered_by_revision_ids(
159
['rev-<D>', 'rev-G', 'rev-F', 'rev-K', 'rev-J']))
162
{'a-file-id-2006-01-01-abcd': set(['rev-B']),
163
'b-file-id-2006-01-01-defg': set(['rev-<D>', 'rev-G', 'rev-J']),
164
'c-funky<file-id> quiji%bo': set(['rev-K']),
165
'file-d': set(['rev-F']),
167
self.branch.repository.fileids_altered_by_revision_ids(
168
['rev-G', 'rev-F', 'rev-C', 'rev-B', 'rev-<D>', 'rev-K', 'rev-J']))
170
def test_fileids_altered_by_revision_ids(self):
172
{'a-file-id-2006-01-01-abcd':set(['rev-A']),
173
'b-file-id-2006-01-01-defg': set(['rev-A']),
174
'c-funky<file-id> quiji%bo': set(['rev-A']),
176
self.branch.repository.fileids_altered_by_revision_ids(["rev-A"]))
178
{'a-file-id-2006-01-01-abcd':set(['rev-B'])
180
self.branch.repository.fileids_altered_by_revision_ids(["rev-B"]))
182
{'b-file-id-2006-01-01-defg':set(['rev-<D>'])
184
self.branch.repository.fileids_altered_by_revision_ids(["rev-<D>"]))
186
def test_fileids_involved_full_compare(self):
187
# this tests that the result of each fileid_involved calculation
188
# along a revision history selects only the fileids selected by
189
# comparing the trees - no less, and no more. This is correct
190
# because in our sample data we do not revert any file ids along
191
# the revision history.
119
def test_fileid_involved_all_revs(self):
121
l = self.branch.fileid_involved( )
122
self.assertEquals( sorted(map( lambda x: x[0], l )), ["a","b","c","d"])
124
def test_fileid_involved_one_rev(self):
126
l = self.branch.fileid_involved("rev-B" )
127
self.assertEquals( sorted(map( lambda x: x[0], l )), ["a","b","c"])
129
def test_fileid_involved_two_revs(self):
131
l = self.branch.fileid_involved_between_revs("rev-B","rev-K" )
132
self.assertEquals( sorted(map( lambda x: x[0], l )), ["b","c"])
134
l = self.branch.fileid_involved_between_revs("rev-C","rev-<D>" )
135
self.assertEquals( sorted(map( lambda x: x[0], l )), ["b","d"])
137
l = self.branch.fileid_involved_between_revs("rev-C","rev-G" )
138
self.assertEquals( sorted(map( lambda x: x[0], l )), ["b","c","d"])
140
l = self.branch.fileid_involved_between_revs("rev-E","rev-G" )
141
self.assertEquals( sorted(map( lambda x: x[0], l )), ["a", "b","c","d"])
143
def test_fileid_involved_sets(self):
145
l = self.branch.fileid_involved_by_set(set(["rev-B"]))
146
self.assertEquals( sorted(map( lambda x: x[0], l )), ["a"])
148
l = self.branch.fileid_involved_by_set(set(["rev-<D>"]))
149
self.assertEquals( sorted(map( lambda x: x[0], l )), ["b"])
151
def test_fileid_involved_compare(self):
153
l1 = self.branch.fileid_involved_between_revs("rev-E", "rev-<D>")
154
l2 = self.branch.fileid_involved_by_set(set(["rev-<D>","rev-F","rev-C","rev-B"]))
155
self.assertEquals( l1, l2 )
157
l1 = self.branch.fileid_involved_between_revs("rev-C", "rev-G")
158
l2 = self.branch.fileid_involved_by_set(
159
set(["rev-G","rev-<D>","rev-F","rev-K","rev-J"]))
160
self.assertEquals( l1, l2 )
162
def test_fileid_involved_full_compare(self):
163
from bzrlib.tsort import topo_sort
193
165
history = self.branch.revision_history( )
195
167
if len(history) < 2: return
197
169
for start in range(0,len(history)-1):
198
start_id = history[start]
199
170
for end in range(start+1,len(history)):
200
end_id = history[end]
201
old_revs = set(self.branch.repository.get_ancestry(start_id))
202
new_revs = set(self.branch.repository.get_ancestry(end_id))
203
l1 = self.branch.repository.fileids_altered_by_revision_ids(
204
new_revs.difference(old_revs))
207
l2 = self.compare_tree_fileids(self.branch, start_id, end_id)
208
self.assertEquals(l1, l2)
211
class TestFileIdInvolvedSuperset(FileIdInvolvedBase):
214
super(TestFileIdInvolvedSuperset, self).setUp()
216
main_wt = self.make_branch_and_tree('main')
217
main_branch = main_wt.branch
218
self.build_tree(["main/a","main/b","main/c"])
220
main_wt.add(['a', 'b', 'c'], ['a-file-id-2006-01-01-abcd',
221
'b-file-id-2006-01-01-defg',
222
'c-funky<file-id> quiji%bo'])
224
main_wt.commit("Commit one", rev_id="rev-A")
226
return # not an error, and not fixable. New formats are fixed.
228
branch2_bzrdir = main_branch.bzrdir.sprout("branch2")
229
branch2_branch = branch2_bzrdir.open_branch()
230
branch2_wt = branch2_bzrdir.open_workingtree()
231
os.chmod("branch2/b",0770)
232
branch2_wt.commit("branch2, Commit one", rev_id="rev-J")
234
self.merge(branch2_branch, main_wt)
235
os.chmod("main/b",0660)
236
main_wt.commit("merge branch1, rev-22", rev_id="rev-G")
239
self.branch = main_branch
241
def test_fileid_involved_full_compare2(self):
242
# this tests that fileids_alteted_by_revision_ids returns
243
# more information than compare_tree can, because it
244
# sees each change rather than the aggregate delta.
245
history = self.branch.revision_history()
248
old_revs = set(self.branch.repository.get_ancestry(old_rev))
249
new_revs = set(self.branch.repository.get_ancestry(new_rev))
251
l1 = self.branch.repository.fileids_altered_by_revision_ids(
252
new_revs.difference(old_revs))
255
l2 = self.compare_tree_fileids(self.branch, old_rev, new_rev)
256
self.assertNotEqual(l2, l1)
257
self.assertSubset(l2, l1)
172
l1 = self.branch.fileid_involved_between_revs(
173
history[start], history[end])
175
old_tree = self.branch.repository.revision_tree(history[start])
176
new_tree = self.branch.repository.revision_tree(history[end])
177
delta = compare_trees(old_tree, new_tree )
179
l2 = [id for path, id, kind in delta.added] + \
180
[id for oldpath, newpath, id, kind, text_modified, \
181
meta_modified in delta.renamed] + \
182
[id for path, id, kind, text_modified, meta_modified in \
185
self.assertEquals(l1, set(l2))