def test_tree_changes_rename_detector(self): blob_a1 = make_object(Blob, data=b'a\nb\nc\nd\n') blob_a2 = make_object(Blob, data=b'a\nb\nc\ne\n') blob_b = make_object(Blob, data=b'b') tree1 = self.commit_tree([(b'a', blob_a1), (b'b', blob_b)]) tree2 = self.commit_tree([(b'c', blob_a2), (b'b', blob_b)]) detector = RenameDetector(self.store) self.assertChangesEqual( [TreeChange.delete((b'a', F, blob_a1.id)), TreeChange.add((b'c', F, blob_a2.id))], tree1, tree2) self.assertChangesEqual( [TreeChange.delete((b'a', F, blob_a1.id)), TreeChange(CHANGE_UNCHANGED, (b'b', F, blob_b.id), (b'b', F, blob_b.id)), TreeChange.add((b'c', F, blob_a2.id))], tree1, tree2, want_unchanged=True) self.assertChangesEqual( [TreeChange(CHANGE_RENAME, (b'a', F, blob_a1.id), (b'c', F, blob_a2.id))], tree1, tree2, rename_detector=detector) self.assertChangesEqual( [TreeChange(CHANGE_RENAME, (b'a', F, blob_a1.id), (b'c', F, blob_a2.id)), TreeChange(CHANGE_UNCHANGED, (b'b', F, blob_b.id), (b'b', F, blob_b.id))], tree1, tree2, rename_detector=detector, want_unchanged=True)
def test_paths(self): blob_a1 = make_object(Blob, data=b'a1') blob_b2 = make_object(Blob, data=b'b2') blob_a3 = make_object(Blob, data=b'a3') blob_b3 = make_object(Blob, data=b'b3') c1, c2, c3 = self.make_linear_commits(3, trees={ 1: [(b'a', blob_a1)], 2: [(b'a', blob_a1), (b'x/b', blob_b2)], 3: [(b'a', blob_a3), (b'x/b', blob_b3)] }) self.assertWalkYields([c3, c2, c1], [c3.id]) self.assertWalkYields([c3, c1], [c3.id], paths=[b'a']) self.assertWalkYields([c3, c2], [c3.id], paths=[b'x/b']) # All changes are included, not just for requested paths. changes = [ TreeChange(CHANGE_MODIFY, (b'a', F, blob_a1.id), (b'a', F, blob_a3.id)), TreeChange(CHANGE_MODIFY, (b'x/b', F, blob_b2.id), (b'x/b', F, blob_b3.id)), ] self.assertWalkYields([TestWalkEntry(c3, changes)], [c3.id], max_entries=1, paths=[b'a'])
def test_filter_with_merge(self): blob_a = make_object(Blob, data=b'a') blob_a2 = make_object(Blob, data=b'a2') blob_b = make_object(Blob, data=b'b') blob_b2 = make_object(Blob, data=b'b2') x1, y2, m3 = self.make_commits( [[1], [2], [3, 1, 2]], trees={ 1: [(b'x/a', blob_a)], 2: [(b'y/b', blob_b)], 3: [(b'x/a', blob_a2), (b'y/b', blob_b2)] }) # Get the WalkEntry for the merge commit. walker = Walker(self.store, m3.id) entries = list(walker) walker_entry = entries[0] self.assertEqual(walker_entry.commit.id, m3.id) changes = walker_entry.changes(b'x') self.assertEqual(1, len(changes)) entry_a = (b'a', F, blob_a.id) entry_a2 = (b'a', F, blob_a2.id) self.assertEqual( [[TreeChange(CHANGE_MODIFY, entry_a, entry_a2)]], changes, )
def setUp(self): super(MOFLinearRepoTest, self).setUp() # present in 1, removed in 3 f1_1 = make_object(Blob, data=b'f1') # present in all revisions, changed in 2 and 3 f2_1 = make_object(Blob, data=b'f2') f2_2 = make_object(Blob, data=b'f2-changed') f2_3 = make_object(Blob, data=b'f2-changed-again') # added in 2, left unmodified in 3 f3_2 = make_object(Blob, data=b'f3') commit_spec = [[1], [2, 1], [3, 2]] trees = { 1: [(b'f1', f1_1), (b'f2', f2_1)], 2: [(b'f1', f1_1), (b'f2', f2_2), (b'f3', f3_2)], 3: [(b'f2', f2_3), (b'f3', f3_2)] } # commit 1: f1 and f2 # commit 2: f3 added, f2 changed. Missing shall report commit id and a # tree referenced by commit # commit 3: f1 removed, f2 changed. Commit sha and root tree sha shall # be reported as modified self.commits = build_commit_graph(self.store, commit_spec, trees) self.missing_1_2 = [self.cmt(2).id, self.cmt(2).tree, f2_2.id, f3_2.id] self.missing_2_3 = [self.cmt(3).id, self.cmt(3).tree, f2_3.id] self.missing_1_3 = [ self.cmt(2).id, self.cmt(3).id, self.cmt(2).tree, self.cmt(3).tree, f2_2.id, f3_2.id, f2_3.id ]
def test_get_info_refs(self): self._environ['QUERY_STRING'] = '' blob1 = make_object(Blob, data=b'1') blob2 = make_object(Blob, data=b'2') blob3 = make_object(Blob, data=b'3') tag1 = make_tag(blob2, name=b'tag-tag') objects = [blob1, blob2, blob3, tag1] refs = { b'HEAD': b'000', b'refs/heads/master': blob1.id, b'refs/tags/tag-tag': tag1.id, b'refs/tags/blob-tag': blob3.id, } backend = _test_backend(objects, refs=refs) mat = re.search('.*', '//info/refs') self.assertEqual([ blob1.id + b'\trefs/heads/master\n', blob3.id + b'\trefs/tags/blob-tag\n', tag1.id + b'\trefs/tags/tag-tag\n', blob2.id + b'\trefs/tags/tag-tag^{}\n' ], list(get_info_refs(self._req, backend, mat))) self.assertEqual(HTTP_OK, self._status) self.assertContentTypeEquals('text/plain') self.assertFalse(self._req.cached)
def test_tree_changes_modify_contents(self): blob_a1 = make_object(Blob, data=b'a1') blob_a2 = make_object(Blob, data=b'a2') tree1 = self.commit_tree([(b'a', blob_a1)]) tree2 = self.commit_tree([(b'a', blob_a2)]) self.assertChangesEqual( [TreeChange(CHANGE_MODIFY, (b'a', F, blob_a1.id), (b'a', F, blob_a2.id))], tree1, tree2)
def test_tree_changes_to_tree(self): blob_a = make_object(Blob, data=b'a') blob_x = make_object(Blob, data=b'x') tree1 = self.commit_tree([(b'a', blob_a)]) tree2 = self.commit_tree([(b'a/x', blob_x)]) self.assertChangesEqual( [TreeChange.delete((b'a', F, blob_a.id)), TreeChange.add((b'a/x', F, blob_x.id))], tree1, tree2)
def test_tree_changes_change_type_same(self): blob_a1 = make_object(Blob, data=b'a') blob_a2 = make_object(Blob, data=b'/foo/bar') tree1 = self.commit_tree([(b'a', blob_a1, 0o100644)]) tree2 = self.commit_tree([(b'a', blob_a2, 0o120000)]) self.assertChangesEqual( [TreeChange(CHANGE_MODIFY, (b'a', 0o100644, blob_a1.id), (b'a', 0o120000, blob_a2.id))], tree1, tree2, change_type_same=True)
def test_tree_changes_change_type(self): blob_a1 = make_object(Blob, data=b'a') blob_a2 = make_object(Blob, data=b'/foo/bar') tree1 = self.commit_tree([(b'a', blob_a1, 0o100644)]) tree2 = self.commit_tree([(b'a', blob_a2, 0o120000)]) self.assertChangesEqual( [TreeChange.delete((b'a', 0o100644, blob_a1.id)), TreeChange.add((b'a', 0o120000, blob_a2.id))], tree1, tree2)
def test_exact_rename_and_different_type(self): blob1 = make_object(Blob, data=b'1') blob2 = make_object(Blob, data=b'2') tree1 = self.commit_tree([(b'a', blob1)]) tree2 = self.commit_tree([(b'a', blob2, 0o120000), (b'b', blob1)]) self.assertEqual( [TreeChange.add((b'a', 0o120000, blob2.id)), TreeChange(CHANGE_RENAME, (b'a', F, blob1.id), (b'b', F, blob1.id))], self.detect_renames(tree1, tree2))
def test_no_renames(self): blob1 = make_object(Blob, data=b'a\nb\nc\nd\n') blob2 = make_object(Blob, data=b'a\nb\ne\nf\n') blob3 = make_object(Blob, data=b'a\nb\ng\nh\n') tree1 = self.commit_tree([(b'a', blob1), (b'b', blob2)]) tree2 = self.commit_tree([(b'a', blob1), (b'b', blob3)]) self.assertEqual( [TreeChange(CHANGE_MODIFY, (b'b', F, blob2.id), (b'b', F, blob3.id))], self.detect_renames(tree1, tree2))
def test_trees(self): a1 = make_object(Blob, data=b'aaa1') a2 = make_object(Blob, data=b'aaa2') c1, c2 = build_commit_graph(self.store, [[1], [2, 1]], trees={ 1: [(b'a', a1)], 2: [(b'a', a2, 0o100644)] }) self.assertEqual((0o100644, a1.id), self.store[c1.tree][b'a']) self.assertEqual((0o100644, a2.id), self.store[c2.tree][b'a'])
def test_tree_changes_for_merge_delete_delete_conflict(self): blob1 = make_object(Blob, data=b'1') blob2 = make_object(Blob, data=b'2') parent1 = self.commit_tree([(b'a', blob1)]) parent2 = self.commit_tree([(b'a', blob2)]) merge = self.commit_tree([]) self.assertChangesForMergeEqual( [[TreeChange.delete((b'a', F, blob1.id)), TreeChange.delete((b'a', F, blob2.id))]], [parent1, parent2], merge)
def test_exact_copy_modify(self): blob1 = make_object(Blob, data=b'a\nb\nc\nd\n') blob2 = make_object(Blob, data=b'a\nb\nc\ne\n') tree1 = self.commit_tree([(b'a', blob1)]) tree2 = self.commit_tree([(b'a', blob2), (b'b', blob1)]) self.assertEqual( [TreeChange(CHANGE_MODIFY, (b'a', F, blob1.id), (b'a', F, blob2.id)), TreeChange(CHANGE_COPY, (b'a', F, blob1.id), (b'b', F, blob1.id))], self.detect_renames(tree1, tree2))
def test_exact_rename_one_to_one(self): blob1 = make_object(Blob, data=b'1') blob2 = make_object(Blob, data=b'2') tree1 = self.commit_tree([(b'a', blob1), (b'b', blob2)]) tree2 = self.commit_tree([(b'c', blob1), (b'd', blob2)]) self.assertEqual( [TreeChange(CHANGE_RENAME, (b'a', F, blob1.id), (b'c', F, blob1.id)), TreeChange(CHANGE_RENAME, (b'b', F, blob2.id), (b'd', F, blob2.id))], self.detect_renames(tree1, tree2))
def test_content_rename_one_to_many(self): blob1 = make_object(Blob, data=b'aa\nb\nc\nd\ne\n') blob2 = make_object(Blob, data=b'ab\nb\nc\nd\ne\n') # 8/11 match blob3 = make_object(Blob, data=b'aa\nb\nc\nd\nf\n') # 9/11 match tree1 = self.commit_tree([(b'a', blob1)]) tree2 = self.commit_tree([(b'b', blob2), (b'c', blob3)]) self.assertEqual( [TreeChange(CHANGE_COPY, (b'a', F, blob1.id), (b'b', F, blob2.id)), TreeChange(CHANGE_RENAME, (b'a', F, blob1.id), (b'c', F, blob3.id))], self.detect_renames(tree1, tree2))
def test_content_rename_many_to_one(self): blob1 = make_object(Blob, data=b'a\nb\nc\nd\n') blob2 = make_object(Blob, data=b'a\nb\nc\ne\n') blob3 = make_object(Blob, data=b'a\nb\nc\nf\n') tree1 = self.commit_tree([(b'a', blob1), (b'b', blob2)]) tree2 = self.commit_tree([(b'c', blob3)]) self.assertEqual( [TreeChange(CHANGE_RENAME, (b'a', F, blob1.id), (b'c', F, blob3.id)), TreeChange.delete((b'b', F, blob2.id))], self.detect_renames(tree1, tree2))
def test_tree_changes_for_merge_add_content_rename_conflict(self): blob1 = make_object(Blob, data=b'a\nb\nc\nd\n') blob2 = make_object(Blob, data=b'a\nb\nc\ne\n') parent1 = self.commit_tree([(b'a', blob1)]) parent2 = self.commit_tree([]) merge = self.commit_tree([(b'b', blob2)]) self.assertChangesForMergeEqual( [[TreeChange(CHANGE_RENAME, (b'a', F, blob1.id), (b'b', F, blob2.id)), TreeChange.add((b'b', F, blob2.id))]], [parent1, parent2], merge, rename_detector=self.detector)
def test_content_rename_one_to_one(self): b11 = make_object(Blob, data=b'a\nb\nc\nd\n') b12 = make_object(Blob, data=b'a\nb\nc\ne\n') b21 = make_object(Blob, data=b'e\nf\ng\n\h') b22 = make_object(Blob, data=b'e\nf\ng\n\i') tree1 = self.commit_tree([(b'a', b11), (b'b', b21)]) tree2 = self.commit_tree([(b'c', b12), (b'd', b22)]) self.assertEqual( [TreeChange(CHANGE_RENAME, (b'a', F, b11.id), (b'c', F, b12.id)), TreeChange(CHANGE_RENAME, (b'b', F, b21.id), (b'd', F, b22.id))], self.detect_renames(tree1, tree2))
def test_paths_max_entries(self): blob_a = make_object(Blob, data=b'a') blob_b = make_object(Blob, data=b'b') c1, c2 = self.make_linear_commits(2, trees={ 1: [(b'a', blob_a)], 2: [(b'a', blob_a), (b'b', blob_b)] }) self.assertWalkYields([c2], [c2.id], paths=[b'b'], max_entries=1) self.assertWalkYields([c1], [c1.id], paths=[b'a'], max_entries=1)
def test_find_copies_harder_content(self): blob1 = make_object(Blob, data=b'a\nb\nc\nd\n') blob2 = make_object(Blob, data=b'a\nb\nc\ne\n') tree1 = self.commit_tree([(b'a', blob1)]) tree2 = self.commit_tree([(b'a', blob1), (b'b', blob2)]) self.assertEqual([TreeChange.add((b'b', F, blob2.id))], self.detect_renames(tree1, tree2)) self.assertEqual( [TreeChange(CHANGE_COPY, (b'a', F, blob1.id), (b'b', F, blob2.id))], self.detect_renames(tree1, tree2, find_copies_harder=True))
def test_tree_changes_for_merge_octopus_modify_conflict(self): # Because the octopus merge strategy is limited, I doubt it's possible # to create this with the git command line. But the output is well- # defined, so test it anyway. r = list(range(5)) parent_blobs = [make_object(Blob, data=bytes(i)) for i in r] merge_blob = make_object(Blob, data=b'merge') parents = [self.commit_tree([(b'a', parent_blobs[i])]) for i in r] merge = self.commit_tree([(b'a', merge_blob)]) expected = [[TreeChange(CHANGE_MODIFY, (b'a', F, parent_blobs[i].id), (b'a', F, merge_blob.id)) for i in r]] self.assertChangesForMergeEqual(expected, parents, merge)
def test_tree_changes_add_delete(self): blob_a = make_object(Blob, data=b'a') blob_b = make_object(Blob, data=b'b') tree = self.commit_tree([(b'a', blob_a, 0o100644), (b'x/b', blob_b, 0o100755)]) self.assertChangesEqual( [TreeChange.add((b'a', 0o100644, blob_a.id)), TreeChange.add((b'x/b', 0o100755, blob_b.id))], self.empty_tree, tree) self.assertChangesEqual( [TreeChange.delete((b'a', 0o100644, blob_a.id)), TreeChange.delete((b'x/b', 0o100755, blob_b.id))], tree, self.empty_tree)
def test_tree_changes_for_merge_modify_modify_conflict(self): blob1 = make_object(Blob, data=b'1') blob2 = make_object(Blob, data=b'2') blob3 = make_object(Blob, data=b'3') parent1 = self.commit_tree([(b'a', blob1)]) parent2 = self.commit_tree([(b'a', blob2)]) merge = self.commit_tree([(b'a', blob3)]) self.assertChangesForMergeEqual( [[TreeChange(CHANGE_MODIFY, (b'a', F, blob1.id), (b'a', F, blob3.id)), TreeChange(CHANGE_MODIFY, (b'a', F, blob2.id), (b'a', F, blob3.id))]], [parent1, parent2], merge)
def test_rename_threshold(self): blob1 = make_object(Blob, data=b'a\nb\nc\n') blob2 = make_object(Blob, data=b'a\nb\nd\n') tree1 = self.commit_tree([(b'a', blob1)]) tree2 = self.commit_tree([(b'b', blob2)]) self.assertEqual( [TreeChange(CHANGE_RENAME, (b'a', F, blob1.id), (b'b', F, blob2.id))], self.detect_renames(tree1, tree2, rename_threshold=50)) self.assertEqual( [TreeChange.delete((b'a', F, blob1.id)), TreeChange.add((b'b', F, blob2.id))], self.detect_renames(tree1, tree2, rename_threshold=75))
def test_content_rename_gitlink(self): blob1 = make_object(Blob, data=b'blob1') blob2 = make_object(Blob, data=b'blob2') link1 = b'1' * 40 link2 = b'2' * 40 tree1 = self.commit_tree([(b'a', blob1), (b'b', link1, 0o160000)]) tree2 = self.commit_tree([(b'c', blob2), (b'd', link2, 0o160000)]) self.assertEqual( [TreeChange.delete((b'a', 0o100644, blob1.id)), TreeChange.delete((b'b', 0o160000, link1)), TreeChange.add((b'c', 0o100644, blob2.id)), TreeChange.add((b'd', 0o160000, link2))], self.detect_renames(tree1, tree2))
def test_content_rename_swap(self): blob1 = make_object(Blob, data=b'a\nb\nc\nd\n') blob2 = make_object(Blob, data=b'e\nf\ng\nh\n') blob3 = make_object(Blob, data=b'a\nb\nc\ne\n') blob4 = make_object(Blob, data=b'e\nf\ng\ni\n') tree1 = self.commit_tree([(b'a', blob1), (b'b', blob2)]) tree2 = self.commit_tree([(b'a', blob4), (b'b', blob3)]) self.assertEqual( [TreeChange(CHANGE_RENAME, (b'a', F, blob1.id), (b'b', F, blob3.id)), TreeChange(CHANGE_RENAME, (b'b', F, blob2.id), (b'a', F, blob4.id))], self.detect_renames(tree1, tree2, rewrite_threshold=60))
def setUp(self): super(MOFMergeForkRepoTest, self).setUp() f1_1 = make_object(Blob, data=b'f1') f1_2 = make_object(Blob, data=b'f1-2') f1_4 = make_object(Blob, data=b'f1-4') f1_7 = make_object(Blob, data=b'f1-2') # same data as in rev 2 f2_1 = make_object(Blob, data=b'f2') f2_3 = make_object(Blob, data=b'f2-3') f3_3 = make_object(Blob, data=b'f3') f3_5 = make_object(Blob, data=b'f3-5') commit_spec = [[1], [2, 1], [3, 2], [4, 2], [5, 3], [6, 3, 4], [7, 6]] trees = { 1: [(b'f1', f1_1), (b'f2', f2_1)], 2: [(b'f1', f1_2), (b'f2', f2_1)], # f1 changed # f3 added, f2 changed 3: [(b'f1', f1_2), (b'f2', f2_3), (b'f3', f3_3)], 4: [(b'f1', f1_4), (b'f2', f2_1)], # f1 changed 5: [(b'f1', f1_2), (b'f3', f3_5)], # f2 removed, f3 changed # merged 3 and 4 6: [(b'f1', f1_4), (b'f2', f2_3), (b'f3', f3_3)], # f1 changed to match rev2. f3 removed 7: [(b'f1', f1_7), (b'f2', f2_3)] } self.commits = build_commit_graph(self.store, commit_spec, trees) self.f1_2_id = f1_2.id self.f1_4_id = f1_4.id self.f1_7_id = f1_7.id self.f2_3_id = f2_3.id self.f3_3_id = f3_3.id self.assertEqual(f1_2.id, f1_7.id, "[sanity]")
def test_paths_merge(self): blob_a1 = make_object(Blob, data=b'a1') blob_a2 = make_object(Blob, data=b'a2') blob_a3 = make_object(Blob, data=b'a3') x1, y2, m3, m4 = self.make_commits( [[1], [2], [3, 1, 2], [4, 1, 2]], trees={ 1: [(b'a', blob_a1)], 2: [(b'a', blob_a2)], 3: [(b'a', blob_a3)], 4: [(b'a', blob_a1)] }) # Non-conflicting self.assertWalkYields([m3, y2, x1], [m3.id], paths=[b'a']) self.assertWalkYields([y2, x1], [m4.id], paths=[b'a'])
def test_paths_subtree(self): blob_a = make_object(Blob, data=b'a') blob_b = make_object(Blob, data=b'b') c1, c2, c3 = self.make_linear_commits(3, trees={ 1: [(b'x/a', blob_a)], 2: [(b'b', blob_b), (b'x/a', blob_a)], 3: [(b'b', blob_b), (b'x/a', blob_a), (b'x/b', blob_b)] }) self.assertWalkYields([c2], [c3.id], paths=[b'b']) self.assertWalkYields([c3, c1], [c3.id], paths=[b'x'])