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_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_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_tree_changes_for_merge_add_add_same_conflict(self):
     blob = make_object(Blob, data=b'a\nb\nc\nd\n')
     parent1 = self.commit_tree([(b'a', blob)])
     parent2 = self.commit_tree([])
     merge = self.commit_tree([(b'b', blob)])
     add = TreeChange.add((b'b', F, blob.id))
     self.assertChangesForMergeEqual(
             [[add, add]], [parent1, parent2], merge)
Ejemplo n.º 8
0
 def test_changes_one_parent(self):
     blob_a1 = make_object(Blob, data=b'a1')
     blob_a2 = make_object(Blob, data=b'a2')
     blob_b2 = make_object(Blob, data=b'b2')
     c1, c2 = self.make_linear_commits(2,
                                       trees={
                                           1: [(b'a', blob_a1)],
                                           2: [(b'a', blob_a2),
                                               (b'b', blob_b2)]
                                       })
     e1 = TestWalkEntry(c1, [TreeChange.add((b'a', F, blob_a1.id))])
     e2 = TestWalkEntry(c2, [
         TreeChange(CHANGE_MODIFY, (b'a', F, blob_a1.id),
                    (b'a', F, blob_a2.id)),
         TreeChange.add((b'b', F, blob_b2.id))
     ])
     self.assertWalkYields([e2, e1], [c2.id])
 def test_find_copies_harder_exact(self):
     blob = make_object(Blob, data=b'blob')
     tree1 = self.commit_tree([(b'a', blob)])
     tree2 = self.commit_tree([(b'a', blob), (b'b', blob)])
     self.assertEqual([TreeChange.add((b'b', F, blob.id))],
                      self.detect_renames(tree1, tree2))
     self.assertEqual(
         [TreeChange(CHANGE_COPY, (b'a', F, blob.id), (b'b', F, blob.id))],
         self.detect_renames(tree1, tree2, find_copies_harder=True))
 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_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_tree_changes_for_merge_add_exact_rename_conflict(self):
     blob = make_object(Blob, data=b'a\nb\nc\nd\n')
     parent1 = self.commit_tree([(b'a', blob)])
     parent2 = self.commit_tree([])
     merge = self.commit_tree([(b'b', blob)])
     self.assertChangesForMergeEqual(
         [[TreeChange(CHANGE_RENAME, (b'a', F, blob.id),
                      (b'b', F, blob.id)),
           TreeChange.add((b'b', F, blob.id))]],
         [parent1, parent2], merge, rename_detector=self.detector)
 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_tree_changes_for_merge_add_modify_conflict(self):
     blob1 = make_object(Blob, data=b'1')
     blob2 = make_object(Blob, data=b'2')
     parent1 = self.commit_tree([])
     parent2 = self.commit_tree([(b'a', blob1)])
     merge = self.commit_tree([(b'a', blob2)])
     self.assertChangesForMergeEqual(
         [[TreeChange.add((b'a', F, blob2.id)),
           TreeChange(CHANGE_MODIFY, (b'a', F, blob1.id),
                      (b'a', F, blob2.id))]],
         [parent1, parent2], merge)
 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))
Ejemplo n.º 17
0
    def test_all_changes(self):
        # Construct a commit with 2 files in different subdirectories.
        blob_a = make_object(Blob, data=b'a')
        blob_b = make_object(Blob, data=b'b')
        c1 = self.make_linear_commits(
            1,
            trees={1: [(b'x/a', blob_a), (b'y/b', blob_b)]},
        )[0]

        # Get the WalkEntry for the commit.
        walker = Walker(self.store, c1.id)
        walker_entry = list(walker)[0]
        changes = walker_entry.changes()

        # Compare the changes with the expected values.
        entry_a = (b'x/a', F, blob_a.id)
        entry_b = (b'y/b', F, blob_b.id)
        self.assertEqual(
            [TreeChange.add(entry_a),
             TreeChange.add(entry_b)],
            changes,
        )
 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))
Ejemplo n.º 19
0
    def test_all_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()
        self.assertEqual(2, len(changes))

        entry_a = (b'x/a', F, blob_a.id)
        entry_a2 = (b'x/a', F, blob_a2.id)
        entry_b = (b'y/b', F, blob_b.id)
        entry_b2 = (b'y/b', F, blob_b2.id)
        self.assertEqual(
            [[
                TreeChange(CHANGE_MODIFY, entry_a, entry_a2),
                TreeChange.add(entry_a2)
            ],
             [
                 TreeChange.add(entry_b2),
                 TreeChange(CHANGE_MODIFY, entry_b, entry_b2)
             ]],
            changes,
        )
    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))
Ejemplo n.º 21
0
    def test_follow_rename(self):
        blob = make_object(Blob, data=b'blob')
        names = [b'a', b'a', b'b', b'b', b'c', b'c']

        trees = dict((i + 1, [(n, blob, F)]) for i, n in enumerate(names))
        c1, c2, c3, c4, c5, c6 = self.make_linear_commits(6, trees=trees)
        self.assertWalkYields([c5], [c6.id], paths=[b'c'])

        def e(n):
            return (n, F, blob.id)

        self.assertWalkYields([
            TestWalkEntry(c5, [TreeChange(CHANGE_RENAME, e(b'b'), e(b'c'))]),
            TestWalkEntry(c3, [TreeChange(CHANGE_RENAME, e(b'a'), e(b'b'))]),
            TestWalkEntry(c1, [TreeChange.add(e(b'a'))])
        ], [c6.id],
                              paths=[b'c'],
                              follow=True)
 def test_find_copies_harder_with_rewrites(self):
     blob_a1 = make_object(Blob, data=b'a\nb\nc\nd\n')
     blob_a2 = make_object(Blob, data=b'f\ng\nh\ni\n')
     blob_b2 = make_object(Blob, data=b'a\nb\nc\ne\n')
     tree1 = self.commit_tree([(b'a', blob_a1)])
     tree2 = self.commit_tree([(b'a', blob_a2), (b'b', blob_b2)])
     self.assertEqual(
         [TreeChange(CHANGE_MODIFY, (b'a', F, blob_a1.id),
                     (b'a', F, blob_a2.id)),
          TreeChange(CHANGE_COPY, (b'a', F, blob_a1.id),
                     (b'b', F, blob_b2.id))],
         self.detect_renames(tree1, tree2, find_copies_harder=True))
     self.assertEqual(
         [TreeChange.add((b'a', F, blob_a2.id)),
          TreeChange(CHANGE_RENAME, (b'a', F, blob_a1.id),
                     (b'b', F, blob_b2.id))],
         self.detect_renames(tree1, tree2, rewrite_threshold=50,
                             find_copies_harder=True))
Ejemplo n.º 23
0
 def test_changes_multiple_parents(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')
     c1, c2, c3 = self.make_commits(
         [[1], [2], [3, 1, 2]],
         trees={
             1: [(b'a', blob_a1)],
             2: [(b'b', blob_b2)],
             3: [(b'a', blob_a3), (b'b', blob_b2)]
         })
     # a is a modify/add conflict and b is not conflicted.
     changes = [[
         TreeChange(CHANGE_MODIFY, (b'a', F, blob_a1.id),
                    (b'a', F, blob_a3.id)),
         TreeChange.add((b'a', F, blob_a3.id)),
     ]]
     self.assertWalkYields([TestWalkEntry(c3, changes)], [c3.id],
                           exclude=[c1.id, c2.id])
Ejemplo n.º 24
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)
    def test_rewrite_threshold(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\nf\ng\n')

        tree1 = self.commit_tree([(b'a', blob1)])
        tree2 = self.commit_tree([(b'a', blob3), (b'b', blob2)])

        no_renames = [
            TreeChange(CHANGE_MODIFY, (b'a', F, blob1.id),
                       (b'a', F, blob3.id)),
            TreeChange(CHANGE_COPY, (b'a', F, blob1.id), (b'b', F, blob2.id))]
        self.assertEqual(
            no_renames, self.detect_renames(tree1, tree2))
        self.assertEqual(
            no_renames, self.detect_renames(
                tree1, tree2, rewrite_threshold=40))
        self.assertEqual(
            [TreeChange.add((b'a', F, blob3.id)),
             TreeChange(CHANGE_RENAME, (b'a', F, blob1.id),
                        (b'b', F, blob2.id))],
            self.detect_renames(tree1, tree2, rewrite_threshold=80))
Ejemplo n.º 26
0
    def test_follow_rename_remove_path(self):
        blob = make_object(Blob, data=b'blob')
        _, _, _, c4, c5, c6 = self.make_linear_commits(6,
                                                       trees={
                                                           1: [(b'a', blob),
                                                               (b'c', blob)],
                                                           2: [],
                                                           3: [],
                                                           4: [(b'b', blob)],
                                                           5: [(b'a', blob)],
                                                           6: [(b'c', blob)]
                                                       })

        def e(n):
            return (n, F, blob.id)

        # Once the path changes to b, we aren't interested in a or c anymore.
        self.assertWalkYields([
            TestWalkEntry(c6, [TreeChange(CHANGE_RENAME, e(b'a'), e(b'c'))]),
            TestWalkEntry(c5, [TreeChange(CHANGE_RENAME, e(b'b'), e(b'a'))]),
            TestWalkEntry(c4, [TreeChange.add(e(b'b'))])
        ], [c6.id],
                              paths=[b'c'],
                              follow=True)