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_tree_changes_complex(self):
        blob_a_1 = make_object(Blob, data=b'a1_1')
        blob_bx1_1 = make_object(Blob, data=b'bx1_1')
        blob_bx2_1 = make_object(Blob, data=b'bx2_1')
        blob_by1_1 = make_object(Blob, data=b'by1_1')
        blob_by2_1 = make_object(Blob, data=b'by2_1')
        tree1 = self.commit_tree([
            (b'a', blob_a_1),
            (b'b/x/1', blob_bx1_1),
            (b'b/x/2', blob_bx2_1),
            (b'b/y/1', blob_by1_1),
            (b'b/y/2', blob_by2_1),
        ])

        blob_a_2 = make_object(Blob, data=b'a1_2')
        blob_bx1_2 = blob_bx1_1
        blob_by_2 = make_object(Blob, data=b'by_2')
        blob_c_2 = make_object(Blob, data=b'c_2')
        tree2 = self.commit_tree([
            (b'a', blob_a_2),
            (b'b/x/1', blob_bx1_2),
            (b'b/y', blob_by_2),
            (b'c', blob_c_2),
        ])

        self.assertChangesEqual(
            [TreeChange(CHANGE_MODIFY, (b'a', F, blob_a_1.id),
                        (b'a', F, blob_a_2.id)),
             TreeChange.delete((b'b/x/2', F, blob_bx2_1.id)),
             TreeChange.add((b'b/y', F, blob_by_2.id)),
             TreeChange.delete((b'b/y/1', F, blob_by1_1.id)),
             TreeChange.delete((b'b/y/2', F, blob_by2_1.id)),
             TreeChange.add((b'c', F, blob_c_2.id))],
            tree1, tree2)
 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_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_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_name_order(self):
        blob = make_object(Blob, data=b'a')
        tree1 = self.commit_tree([(b'a', blob), (b'a.', blob), (b'a..', blob)])
        # Tree order is the reverse of this, so if we used tree order, 'a..'
        # would not be merged.
        tree2 = self.commit_tree(
                [(b'a/x', blob), (b'a./x', blob), (b'a..', blob)])

        self.assertChangesEqual(
            [TreeChange.delete((b'a', F, blob.id)),
             TreeChange.add((b'a/x', F, blob.id)),
             TreeChange.delete((b'a.', F, blob.id)),
             TreeChange.add((b'a./x', F, blob.id))],
            tree1, tree2)
 def test_tree_changes_for_merge_octopus_delete(self):
     blob1 = make_object(Blob, data=b'1')
     blob2 = make_object(Blob, data=b'3')
     parent1 = self.commit_tree([(b'a', blob1)])
     parent2 = self.commit_tree([(b'a', blob2)])
     parent3 = merge = self.commit_tree([])
     self.assertChangesForMergeEqual([], [parent1, parent1, parent1], merge)
     self.assertChangesForMergeEqual([], [parent1, parent1, parent3], merge)
     self.assertChangesForMergeEqual([], [parent1, parent3, parent3], merge)
     self.assertChangesForMergeEqual(
         [[TreeChange.delete((b'a', F, blob1.id)),
           TreeChange.delete((b'a', F, blob2.id)),
           None]],
         [parent1, parent2, parent3], merge)
 def test_exact_rename_split_different_type(self):
     blob = make_object(Blob, data=b'/foo')
     tree1 = self.commit_tree([(b'a', blob, 0o100644)])
     tree2 = self.commit_tree([(b'a', blob, 0o120000)])
     self.assertEqual(
         [TreeChange.add((b'a', 0o120000, blob.id)),
          TreeChange.delete((b'a', 0o100644, blob.id))],
         self.detect_renames(tree1, tree2))
 def test_exact_rename_many_to_one(self):
     blob = make_object(Blob, data=b'1')
     tree1 = self.commit_tree([(b'a', blob), (b'b', blob)])
     tree2 = self.commit_tree([(b'c', blob)])
     self.assertEqual(
         [TreeChange(CHANGE_RENAME, (b'a', F, blob.id), (b'c', F, blob.id)),
          TreeChange.delete((b'b', F, blob.id))],
         self.detect_renames(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(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_content_rename_max_files(self):
     blob1 = make_object(Blob, data=b'a\nb\nc\nd')
     blob4 = make_object(Blob, data=b'a\nb\nc\ne\n')
     blob2 = make_object(Blob, data=b'e\nf\ng\nh\n')
     blob3 = 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'c', blob3), (b'd', blob4)])
     self.assertEqual(
         [TreeChange(CHANGE_RENAME, (b'a', F, blob1.id),
                     (b'd', F, blob4.id)),
          TreeChange(CHANGE_RENAME, (b'b', F, blob2.id),
                     (b'c', F, blob3.id))],
         self.detect_renames(tree1, tree2))
     self.assertEqual(
         [TreeChange.delete((b'a', F, blob1.id)),
          TreeChange.delete((b'b', F, blob2.id)),
          TreeChange.add((b'c', F, blob3.id)),
          TreeChange.add((b'd', F, blob4.id))],
         self.detect_renames(tree1, tree2, max_files=1))
 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_content_rename_one_to_one_ordering(self):
        blob1 = make_object(Blob, data=b'a\nb\nc\nd\ne\nf\n')
        blob2 = make_object(Blob, data=b'a\nb\nc\nd\ng\nh\n')
        # 6/10 match to blob1, 8/10 match to blob2
        blob3 = make_object(Blob, data=b'a\nb\nc\nd\ng\ni\n')
        tree1 = self.commit_tree([(b'a', blob1), (b'b', blob2)])
        tree2 = self.commit_tree([(b'c', blob3)])
        self.assertEqual(
            [TreeChange.delete((b'a', F, blob1.id)),
             TreeChange(CHANGE_RENAME, (b'b', F, blob2.id),
                        (b'c', F, blob3.id))],
            self.detect_renames(tree1, tree2))

        tree3 = self.commit_tree([(b'a', blob2), (b'b', blob1)])
        tree4 = self.commit_tree([(b'c', blob3)])
        self.assertEqual(
            [TreeChange(CHANGE_RENAME, (b'a', F, blob2.id),
                        (b'c', F, blob3.id)),
             TreeChange.delete((b'b', F, blob1.id))],
            self.detect_renames(tree3, tree4))
 def test_content_rename_with_more_deletions(self):
     blob1 = make_object(Blob, data=b'')
     tree1 = self.commit_tree([(b'a', blob1), (b'b', blob1), (b'c', blob1),
                               (b'd', blob1)])
     tree2 = self.commit_tree([(b'e', blob1), (b'f', blob1), (b'g', blob1)])
     self.maxDiff = None
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, (b'a', F, blob1.id), (b'e', F, blob1.id)),
        TreeChange(CHANGE_RENAME, (b'b', F, blob1.id), (b'f', F, blob1.id)),
        TreeChange(CHANGE_RENAME, (b'c', F, blob1.id), (b'g', F, blob1.id)),
        TreeChange.delete((b'd', F, blob1.id))],
       self.detect_renames(tree1, tree2))
 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_many_to_many(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')
     blob4 = make_object(Blob, data=b'a\nb\nc\ng\n')
     tree1 = self.commit_tree([(b'a', blob1), (b'b', blob2)])
     tree2 = self.commit_tree([(b'c', blob3), (b'd', blob4)])
     # TODO(dborowitz): Distribute renames rather than greedily choosing
     # copies.
     self.assertEqual(
         [TreeChange(CHANGE_RENAME, (b'a', F, blob1.id),
                     (b'c', F, blob3.id)),
          TreeChange(CHANGE_COPY, (b'a', F, blob1.id), (b'd', F, blob4.id)),
          TreeChange.delete((b'b', F, blob2.id))],
         self.detect_renames(tree1, tree2))
    def test_tree_entry_sort(self):
        sha = 'abcd' * 10
        expected_entries = [
            TreeChange.add(TreeEntry(b'aaa', F, sha)),
            TreeChange(CHANGE_COPY, TreeEntry(b'bbb', F, sha),
                       TreeEntry(b'aab', F, sha)),
            TreeChange(CHANGE_MODIFY, TreeEntry(b'bbb', F, sha),
                       TreeEntry(b'bbb', F, b'dabc' * 10)),
            TreeChange(CHANGE_RENAME, TreeEntry(b'bbc', F, sha),
                       TreeEntry(b'ddd', F, sha)),
            TreeChange.delete(TreeEntry(b'ccc', F, sha)),
        ]

        for perm in permutations(expected_entries):
            self.assertEqual(expected_entries,
                             sorted(perm, key=_tree_change_key))
예제 #19
0
 def test_changes_with_renames(self):
     blob = make_object(Blob, data=b'blob')
     c1, c2 = self.make_linear_commits(2,
                                       trees={
                                           1: [(b'a', blob)],
                                           2: [(b'b', blob)]
                                       })
     entry_a = (b'a', F, blob.id)
     entry_b = (b'b', F, blob.id)
     changes_without_renames = [
         TreeChange.delete(entry_a),
         TreeChange.add(entry_b)
     ]
     changes_with_renames = [TreeChange(CHANGE_RENAME, entry_a, entry_b)]
     self.assertWalkYields([TestWalkEntry(c2, changes_without_renames)],
                           [c2.id],
                           max_entries=1)
     detector = RenameDetector(self.store)
     self.assertWalkYields([TestWalkEntry(c2, changes_with_renames)],
                           [c2.id],
                           max_entries=1,
                           rename_detector=detector)