示例#1
0
    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(
            [
                ("a", blob_a_1),
                ("b/x/1", blob_bx1_1),
                ("b/x/2", blob_bx2_1),
                ("b/y/1", blob_by1_1),
                ("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([("a", blob_a_2), ("b/x/1", blob_bx1_2), ("b/y", blob_by_2), ("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,
        )
示例#2
0
    def test_tree_changes_rename_detector(self):
        blob_a1 = make_object(Blob, data='a\nb\nc\nd\n')
        blob_a2 = make_object(Blob, data='a\nb\nc\ne\n')
        blob_b = make_object(Blob, data='b')
        tree1 = self.commit_tree([('a', blob_a1), ('b', blob_b)])
        tree2 = self.commit_tree([('c', blob_a2), ('b', blob_b)])
        detector = RenameDetector(self.store)

        self.assertChangesEqual(
          [TreeChange.delete(('a', F, blob_a1.id)),
           TreeChange.add(('c', F, blob_a2.id))],
          tree1, tree2)
        self.assertChangesEqual(
          [TreeChange.delete(('a', F, blob_a1.id)),
           TreeChange(CHANGE_UNCHANGED, ('b', F, blob_b.id),
                      ('b', F, blob_b.id)),
           TreeChange.add(('c', F, blob_a2.id))],
          tree1, tree2, want_unchanged=True)
        self.assertChangesEqual(
          [TreeChange(CHANGE_RENAME, ('a', F, blob_a1.id),
                      ('c', F, blob_a2.id))],
          tree1, tree2, rename_detector=detector)
        self.assertChangesEqual(
          [TreeChange(CHANGE_RENAME, ('a', F, blob_a1.id),
                      ('c', F, blob_a2.id)),
           TreeChange(CHANGE_UNCHANGED, ('b', F, blob_b.id),
                      ('b', F, blob_b.id))],
          tree1, tree2, rename_detector=detector, want_unchanged=True)
示例#3
0
    def test_tree_changes_complex(self):
        blob_a_1 = make_object(Blob, data='a1_1')
        blob_bx1_1 = make_object(Blob, data='bx1_1')
        blob_bx2_1 = make_object(Blob, data='bx2_1')
        blob_by1_1 = make_object(Blob, data='by1_1')
        blob_by2_1 = make_object(Blob, data='by2_1')
        tree1 = self.commit_tree([
          ('a', blob_a_1),
          ('b/x/1', blob_bx1_1),
          ('b/x/2', blob_bx2_1),
          ('b/y/1', blob_by1_1),
          ('b/y/2', blob_by2_1),
          ])

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

        self.assertChangesEqual(
          [TreeChange(CHANGE_MODIFY, ('a', F, blob_a_1.id),
                      ('a', F, blob_a_2.id)),
           TreeChange.delete(('b/x/2', F, blob_bx2_1.id)),
           TreeChange.add(('b/y', F, blob_by_2.id)),
           TreeChange.delete(('b/y/1', F, blob_by1_1.id)),
           TreeChange.delete(('b/y/2', F, blob_by2_1.id)),
           TreeChange.add(('c', F, blob_c_2.id))],
          tree1, tree2)
示例#4
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,
        )
示例#5
0
 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([("a", blob_a)])
     tree2 = self.commit_tree([("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
     )
示例#6
0
 def test_exact_rename_split_different_type(self):
     blob = make_object(Blob, data=b"/foo")
     tree1 = self.commit_tree([("a", blob, 0o100644)])
     tree2 = self.commit_tree([("a", blob, 0o120000)])
     self.assertEqual(
         [TreeChange.add((b"a", 0o120000, blob.id)), TreeChange.delete((b"a", 0o100644, blob.id))],
         self.detect_renames(tree1, tree2),
     )
示例#7
0
 def test_tree_changes_change_type(self):
     blob_a1 = make_object(Blob, data='a')
     blob_a2 = make_object(Blob, data='/foo/bar')
     tree1 = self.commit_tree([('a', blob_a1, 0o100644)])
     tree2 = self.commit_tree([('a', blob_a2, 0o120000)])
     self.assertChangesEqual(
       [TreeChange.delete(('a', 0o100644, blob_a1.id)),
        TreeChange.add(('a', 0o120000, blob_a2.id))],
       tree1, tree2)
示例#8
0
 def test_tree_changes_to_tree(self):
     blob_a = make_object(Blob, data='a')
     blob_x = make_object(Blob, data='x')
     tree1 = self.commit_tree([('a', blob_a)])
     tree2 = self.commit_tree([('a/x', blob_x)])
     self.assertChangesEqual(
       [TreeChange.delete(('a', F, blob_a.id)),
        TreeChange.add(('a/x', F, blob_x.id))],
       tree1, tree2)
示例#9
0
 def test_content_rename_one_to_many(self):
     blob1 = make_object(Blob, data='aa\nb\nc\nd\ne\n')
     blob2 = make_object(Blob, data='ab\nb\nc\nd\ne\n')  # 8/11 match
     blob3 = make_object(Blob, data='aa\nb\nc\nd\nf\n')  # 9/11 match
     tree1 = self.commit_tree([('a', blob1)])
     tree2 = self.commit_tree([('b', blob2), ('c', blob3)])
     self.assertEqual([
         TreeChange(CHANGE_COPY, ('a', F, blob1.id), ('b', F, blob2.id)),
         TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('c', F, blob3.id))
     ], self.detect_renames(tree1, tree2))
示例#10
0
 def test_tree_changes_for_merge_delete_delete_conflict(self):
     blob1 = make_object(Blob, data='1')
     blob2 = make_object(Blob, data='2')
     parent1 = self.commit_tree([('a', blob1)])
     parent2 = self.commit_tree([('a', blob2)])
     merge = self.commit_tree([])
     self.assertChangesForMergeEqual([[
         TreeChange.delete(('a', F, blob1.id)),
         TreeChange.delete(('a', F, blob2.id))
     ]], [parent1, parent2], merge)
示例#11
0
 def test_find_copies_harder_content(self):
     blob1 = make_object(Blob, data='a\nb\nc\nd\n')
     blob2 = make_object(Blob, data='a\nb\nc\ne\n')
     tree1 = self.commit_tree([('a', blob1)])
     tree2 = self.commit_tree([('a', blob1), ('b', blob2)])
     self.assertEqual([TreeChange.add(('b', F, blob2.id))],
                      self.detect_renames(tree1, tree2))
     self.assertEqual(
         [TreeChange(CHANGE_COPY, ('a', F, blob1.id), ('b', F, blob2.id))],
         self.detect_renames(tree1, tree2, find_copies_harder=True))
示例#12
0
 def test_content_rename_many_to_one(self):
     blob1 = make_object(Blob, data='a\nb\nc\nd\n')
     blob2 = make_object(Blob, data='a\nb\nc\ne\n')
     blob3 = make_object(Blob, data='a\nb\nc\nf\n')
     tree1 = self.commit_tree([('a', blob1), ('b', blob2)])
     tree2 = self.commit_tree([('c', blob3)])
     self.assertEqual([
         TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('c', F, blob3.id)),
         TreeChange.delete(('b', F, blob2.id))
     ], self.detect_renames(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)
示例#15
0
 def test_tree_changes_for_merge_modify_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([(b'b', blob1)])
     merge = self.commit_tree([(b'b', blob2)])
     self.assertChangesForMergeEqual(
         [[TreeChange(CHANGE_RENAME, (b'a', F, blob1.id), (b'b', F, blob2.id)),
           TreeChange(CHANGE_MODIFY, (b'b', F, blob1.id), (b'b', F, blob2.id))]],
         [parent1, parent2], merge, rename_detector=self.detector)
示例#16
0
 def test_tree_changes_no_changes(self):
     blob = make_object(Blob, data=b'blob')
     tree = self.commit_tree([(b'a', blob), (b'b/c', blob)])
     self.assertChangesEqual([], self.empty_tree, self.empty_tree)
     self.assertChangesEqual([], tree, tree)
     self.assertChangesEqual(
         [TreeChange(CHANGE_UNCHANGED, (b'a', F, blob.id), (b'a', F, blob.id)),
          TreeChange(CHANGE_UNCHANGED, (b'b/c', F, blob.id),
                     (b'b/c', F, blob.id))],
         tree, tree, want_unchanged=True)
示例#17
0
 def test_tree_changes_for_merge_add_modify_conflict(self):
     blob1 = make_object(Blob, data='1')
     blob2 = make_object(Blob, data='2')
     parent1 = self.commit_tree([])
     parent2 = self.commit_tree([('a', blob1)])
     merge = self.commit_tree([('a', blob2)])
     self.assertChangesForMergeEqual([[
         TreeChange.add(('a', F, blob2.id)),
         TreeChange(CHANGE_MODIFY, ('a', F, blob1.id), ('a', F, blob2.id))
     ]], [parent1, parent2], merge)
示例#18
0
 def test_tree_changes_for_merge_delete_delete_conflict(self):
     blob1 = make_object(Blob, data='1')
     blob2 = make_object(Blob, data='2')
     parent1 = self.commit_tree([('a', blob1)])
     parent2 = self.commit_tree([('a', blob2)])
     merge = self.commit_tree([])
     self.assertChangesForMergeEqual(
       [[TreeChange.delete(('a', F, blob1.id)),
         TreeChange.delete(('a', F, blob2.id))]],
       [parent1, parent2], merge)
示例#19
0
 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))
示例#20
0
 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))
示例#21
0
 def test_content_rename_one_to_one(self):
     b11 = make_object(Blob, data='a\nb\nc\nd\n')
     b12 = make_object(Blob, data='a\nb\nc\ne\n')
     b21 = make_object(Blob, data='e\nf\ng\n\h')
     b22 = make_object(Blob, data='e\nf\ng\n\i')
     tree1 = self.commit_tree([('a', b11), ('b', b21)])
     tree2 = self.commit_tree([('c', b12), ('d', b22)])
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, ('a', F, b11.id), ('c', F, b12.id)),
        TreeChange(CHANGE_RENAME, ('b', F, b21.id), ('d', F, b22.id))],
       self.detect_renames(tree1, tree2))
示例#22
0
 def test_content_rename_with_more_deletions(self):
     blob1 = make_object(Blob, data='')
     tree1 = self.commit_tree([('a', blob1), ('b', blob1), ('c', blob1), ('d', blob1)])
     tree2 = self.commit_tree([('e', blob1), ('f', blob1), ('g', blob1)])
     self.maxDiff = None
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('e', F, blob1.id)),
        TreeChange(CHANGE_RENAME, ('b', F, blob1.id), ('f', F, blob1.id)),
        TreeChange(CHANGE_RENAME, ('c', F, blob1.id), ('g', F, blob1.id)),
        TreeChange.delete(('d', F, blob1.id))],
       self.detect_renames(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),
     )
示例#24
0
 def test_content_rename_swap(self):
     blob1 = make_object(Blob, data='a\nb\nc\nd\n')
     blob2 = make_object(Blob, data='e\nf\ng\nh\n')
     blob3 = make_object(Blob, data='a\nb\nc\ne\n')
     blob4 = make_object(Blob, data='e\nf\ng\ni\n')
     tree1 = self.commit_tree([('a', blob1), ('b', blob2)])
     tree2 = self.commit_tree([('a', blob4), ('b', blob3)])
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('b', F, blob3.id)),
        TreeChange(CHANGE_RENAME, ('b', F, blob2.id), ('a', F, blob4.id))],
       self.detect_renames(tree1, tree2, rewrite_threshold=60))
 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),
     )
示例#26
0
 def test_changes_with_renames(self):
     blob = make_object(Blob, data="blob")
     c1, c2 = self.make_linear_commits(2, trees={1: [("a", blob)], 2: [("b", blob)]})
     entry_a = ("a", F, blob.id)
     entry_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
     )
示例#27
0
    def test_tree_entry_sort(self):
        sha = Sha1Sum("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, Sha1Sum("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))
示例#28
0
 def test_changes_one_parent(self):
     blob_a1 = make_object(Blob, data='a1')
     blob_a2 = make_object(Blob, data='a2')
     blob_b2 = make_object(Blob, data='b2')
     c1, c2 = self.make_linear_commits(
       2, trees={1: [('a', blob_a1)],
                 2: [('a', blob_a2), ('b', blob_b2)]})
     e1 = TestWalkEntry(c1, [TreeChange.add(('a', F, blob_a1.id))])
     e2 = TestWalkEntry(c2, [TreeChange(CHANGE_MODIFY, ('a', F, blob_a1.id),
                                        ('a', F, blob_a2.id)),
                             TreeChange.add(('b', F, blob_b2.id))])
     self.assertWalkYields([e2, e1], [c2.id])
 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),
     )
示例#30
0
 def test_rename_threshold(self):
     blob1 = make_object(Blob, data='a\nb\nc\n')
     blob2 = make_object(Blob, data='a\nb\nd\n')
     tree1 = self.commit_tree([('a', blob1)])
     tree2 = self.commit_tree([('b', blob2)])
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('b', F, blob2.id))],
       self.detect_renames(tree1, tree2, rename_threshold=50))
     self.assertEqual(
       [TreeChange.delete(('a', F, blob1.id)),
        TreeChange.add(('b', F, blob2.id))],
       self.detect_renames(tree1, tree2, rename_threshold=75))
示例#31
0
 def test_rename_threshold(self):
     blob1 = make_object(Blob, data='a\nb\nc\n')
     blob2 = make_object(Blob, data='a\nb\nd\n')
     tree1 = self.commit_tree([('a', blob1)])
     tree2 = self.commit_tree([('b', blob2)])
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('b', F, blob2.id))],
       self.detect_renames(tree1, tree2, rename_threshold=50))
     self.assertEqual(
       [TreeChange.delete(('a', F, blob1.id)),
        TreeChange.add(('b', F, blob2.id))],
       self.detect_renames(tree1, tree2, rename_threshold=75))
示例#32
0
 def test_changes_one_parent(self):
     blob_a1 = make_object(Blob, data='a1')
     blob_a2 = make_object(Blob, data='a2')
     blob_b2 = make_object(Blob, data='b2')
     c1, c2 = self.make_linear_commits(
       2, trees={1: [('a', blob_a1)],
                 2: [('a', blob_a2), ('b', blob_b2)]})
     e1 = TestWalkEntry(c1, [TreeChange.add(('a', F, blob_a1.id))])
     e2 = TestWalkEntry(c2, [TreeChange(CHANGE_MODIFY, ('a', F, blob_a1.id),
                                        ('a', F, blob_a2.id)),
                             TreeChange.add(('b', F, blob_b2.id))])
     self.assertWalkYields([e2, e1], [c2.id])
示例#33
0
 def test_exact_rename_many_to_many(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), (b'd', blob), (b'e', blob)])
     self.assertEqual(
             [TreeChange(CHANGE_RENAME, (b'a', F, blob.id),
                         (b'c', F, blob.id)),
              TreeChange(CHANGE_COPY, (b'a', F, blob.id),
                         (b'e', F, blob.id)),
              TreeChange(CHANGE_RENAME, (b'b', F, blob.id),
                         (b'd', F, blob.id))],
             self.detect_renames(tree1, tree2))
示例#34
0
    def test_tree_changes_name_order(self):
        blob = make_object(Blob, data='a')
        tree1 = self.commit_tree([('a', blob), ('a.', blob), ('a..', blob)])
        # Tree order is the reverse of this, so if we used tree order, 'a..'
        # would not be merged.
        tree2 = self.commit_tree([('a/x', blob), ('a./x', blob), ('a..', blob)])

        self.assertChangesEqual(
          [TreeChange.delete(('a', F, blob.id)),
           TreeChange.add(('a/x', F, blob.id)),
           TreeChange.delete(('a.', F, blob.id)),
           TreeChange.add(('a./x', F, blob.id))],
          tree1, tree2)
示例#35
0
 def test_tree_changes_add_delete(self):
     blob_a = make_object(Blob, data='a')
     blob_b = make_object(Blob, data='b')
     tree = self.commit_tree([('a', blob_a, 0o100644),
                              ('x/b', blob_b, 0o100755)])
     self.assertChangesEqual(
       [TreeChange.add(('a', 0o100644, blob_a.id)),
        TreeChange.add(('x/b', 0o100755, blob_b.id))],
       self.empty_tree, tree)
     self.assertChangesEqual(
       [TreeChange.delete(('a', 0o100644, blob_a.id)),
        TreeChange.delete(('x/b', 0o100755, blob_b.id))],
       tree, self.empty_tree)
 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_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,
     )
示例#38
0
 def test_content_rename_gitlink(self):
     blob1 = make_object(Blob, data='blob1')
     blob2 = make_object(Blob, data='blob2')
     link1 = '1' * 40
     link2 = '2' * 40
     tree1 = self.commit_tree([('a', blob1), ('b', link1, 0o160000)])
     tree2 = self.commit_tree([('c', blob2), ('d', link2, 0o160000)])
     self.assertEqual(
       [TreeChange.delete(('a', 0o100644, blob1.id)),
        TreeChange.delete(('b', 0o160000, link1)),
        TreeChange.add(('c', 0o100644, blob2.id)),
        TreeChange.add(('d', 0o160000, link2))],
       self.detect_renames(tree1, tree2))
示例#39
0
 def test_tree_changes_add_delete(self):
     blob_a = make_object(Blob, data='a')
     blob_b = make_object(Blob, data='b')
     tree = self.commit_tree([('a', blob_a, 0o100644),
                              ('x/b', blob_b, 0o100755)])
     self.assertChangesEqual(
       [TreeChange.add(('a', 0o100644, blob_a.id)),
        TreeChange.add(('x/b', 0o100755, blob_b.id))],
       self.empty_tree, tree)
     self.assertChangesEqual(
       [TreeChange.delete(('a', 0o100644, blob_a.id)),
        TreeChange.delete(('x/b', 0o100755, blob_b.id))],
       tree, self.empty_tree)
 def test_tree_changes_for_merge_octopus_delete(self):
     blob1 = make_object(Blob, data='1')
     blob2 = make_object(Blob, data='3')
     parent1 = self.commit_tree([('a', blob1)])
     parent2 = self.commit_tree([('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(('a', F, blob1.id)),
         TreeChange.delete(('a', F, blob2.id)), None
     ]], [parent1, parent2, parent3], merge)
示例#41
0
 def test_exact_rename_swap(self):
     blob1 = make_object(Blob, data='1')
     blob2 = make_object(Blob, data='2')
     tree1 = self.commit_tree([('a', blob1), ('b', blob2)])
     tree2 = self.commit_tree([('a', blob2), ('b', blob1)])
     self.assertEqual(
       [TreeChange(CHANGE_MODIFY, ('a', F, blob1.id), ('a', F, blob2.id)),
        TreeChange(CHANGE_MODIFY, ('b', F, blob2.id), ('b', F, blob1.id))],
       self.detect_renames(tree1, tree2))
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('b', F, blob1.id)),
        TreeChange(CHANGE_RENAME, ('b', F, blob2.id), ('a', F, blob2.id))],
       self.detect_renames(tree1, tree2, rewrite_threshold=50))
示例#42
0
    def test_tree_changes_name_order(self):
        blob = make_object(Blob, data='a')
        tree1 = self.commit_tree([('a', blob), ('a.', blob), ('a..', blob)])
        # Tree order is the reverse of this, so if we used tree order, 'a..'
        # would not be merged.
        tree2 = self.commit_tree([('a/x', blob), ('a./x', blob), ('a..', blob)])

        self.assertChangesEqual(
          [TreeChange.delete(('a', F, blob.id)),
           TreeChange.add(('a/x', F, blob.id)),
           TreeChange.delete(('a.', F, blob.id)),
           TreeChange.add(('a./x', F, blob.id))],
          tree1, tree2)
示例#43
0
 def test_content_rename_gitlink(self):
     blob1 = make_object(Blob, data='blob1')
     blob2 = make_object(Blob, data='blob2')
     link1 = '1' * 40
     link2 = '2' * 40
     tree1 = self.commit_tree([('a', blob1), ('b', link1, 0o160000)])
     tree2 = self.commit_tree([('c', blob2), ('d', link2, 0o160000)])
     self.assertEqual(
       [TreeChange.delete(('a', 0o100644, blob1.id)),
        TreeChange.delete(('b', 0o160000, link1)),
        TreeChange.add(('c', 0o100644, blob2.id)),
        TreeChange.add(('d', 0o160000, link2))],
       self.detect_renames(tree1, tree2))
示例#44
0
    def test_tree_changes_rename_detector(self):
        blob_a1 = make_object(Blob, data='a\nb\nc\nd\n')
        blob_a2 = make_object(Blob, data='a\nb\nc\ne\n')
        blob_b = make_object(Blob, data='b')
        tree1 = self.commit_tree([('a', blob_a1), ('b', blob_b)])
        tree2 = self.commit_tree([('c', blob_a2), ('b', blob_b)])
        detector = RenameDetector(self.store)

        self.assertChangesEqual(
          [TreeChange.delete(('a', F, blob_a1.id)),
           TreeChange.add(('c', F, blob_a2.id))],
          tree1, tree2)
        self.assertChangesEqual(
          [TreeChange.delete(('a', F, blob_a1.id)),
           TreeChange(CHANGE_UNCHANGED, ('b', F, blob_b.id),
                      ('b', F, blob_b.id)),
           TreeChange.add(('c', F, blob_a2.id))],
          tree1, tree2, want_unchanged=True)
        self.assertChangesEqual(
          [TreeChange(CHANGE_RENAME, ('a', F, blob_a1.id),
                      ('c', F, blob_a2.id))],
          tree1, tree2, rename_detector=detector)
        self.assertChangesEqual(
          [TreeChange(CHANGE_RENAME, ('a', F, blob_a1.id),
                      ('c', F, blob_a2.id)),
           TreeChange(CHANGE_UNCHANGED, ('b', F, blob_b.id),
                      ('b', F, blob_b.id))],
          tree1, tree2, rename_detector=detector, want_unchanged=True)
示例#45
0
    def test_follow_rename(self):
        blob = make_object(Blob, data='blob')
        names = ['a', 'a', 'b', 'b', 'c', '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=['c'])

        e = lambda n: (n, F, blob.id)
        self.assertWalkYields(
          [TestWalkEntry(c5, [TreeChange(CHANGE_RENAME, e('b'), e('c'))]),
           TestWalkEntry(c3, [TreeChange(CHANGE_RENAME, e('a'), e('b'))]),
           TestWalkEntry(c1, [TreeChange.add(e('a'))])],
          [c6.id], paths=['c'], follow=True)
示例#46
0
 def test_content_rename_many_to_many(self):
     blob1 = make_object(Blob, data='a\nb\nc\nd\n')
     blob2 = make_object(Blob, data='a\nb\nc\ne\n')
     blob3 = make_object(Blob, data='a\nb\nc\nf\n')
     blob4 = make_object(Blob, data='a\nb\nc\ng\n')
     tree1 = self.commit_tree([('a', blob1), ('b', blob2)])
     tree2 = self.commit_tree([('c', blob3), ('d', blob4)])
     # TODO(dborowitz): Distribute renames rather than greedily choosing
     # copies.
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('c', F, blob3.id)),
        TreeChange(CHANGE_COPY, ('a', F, blob1.id), ('d', F, blob4.id)),
        TreeChange.delete(('b', F, blob2.id))],
       self.detect_renames(tree1, tree2))
示例#47
0
 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([("a", blob_a, 0o100644), ("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,
     )
示例#48
0
 def test_tree_changes_for_merge_octopus_delete(self):
     blob1 = make_object(Blob, data='1')
     blob2 = make_object(Blob, data='3')
     parent1 = self.commit_tree([('a', blob1)])
     parent2 = self.commit_tree([('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(('a', F, blob1.id)),
         TreeChange.delete(('a', F, blob2.id)),
         None]],
       [parent1, parent2, parent3], merge)
示例#49
0
    def test_tree_entry_sort(self):
        sha = 'abcd' * 10
        expected_entries = [
          TreeChange.add(TreeEntry('aaa', F, sha)),
          TreeChange(CHANGE_COPY, TreeEntry('bbb', F, sha),
                     TreeEntry('aab', F, sha)),
          TreeChange(CHANGE_MODIFY, TreeEntry('bbb', F, sha),
                     TreeEntry('bbb', F, 'dabc' * 10)),
          TreeChange(CHANGE_RENAME, TreeEntry('bbc', F, sha),
                     TreeEntry('ddd', F, sha)),
          TreeChange.delete(TreeEntry('ccc', F, sha)),
          ]

        for perm in permutations(expected_entries):
            self.assertEqual(expected_entries,
                             sorted(perm, key=_tree_change_key))
示例#50
0
 def test_tree_changes_for_merge_add_add_same_conflict(self):
     blob = make_object(Blob, data='a\nb\nc\nd\n')
     parent1 = self.commit_tree([('a', blob)])
     parent2 = self.commit_tree([])
     merge = self.commit_tree([('b', blob)])
     add = TreeChange.add(('b', F, blob.id))
     self.assertChangesForMergeEqual([[add, add]], [parent1, parent2], merge)
示例#51
0
 def test_content_rename_gitlink(self):
     blob1 = make_object(Blob, data=b"blob1")
     blob2 = make_object(Blob, data=b"blob2")
     link1 = Sha1Sum("1" * 40)
     link2 = Sha1Sum("2" * 40)
     tree1 = self.commit_tree([("a", blob1), ("b", link1, 0o160000)])
     tree2 = self.commit_tree([("c", blob2), ("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),
     )
示例#52
0
 def test_exact_rename_many_to_one(self):
     blob = make_object(Blob, data='1')
     tree1 = self.commit_tree([('a', blob), ('b', blob)])
     tree2 = self.commit_tree([('c', blob)])
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, ('a', F, blob.id), ('c', F, blob.id)),
        TreeChange.delete(('b', F, blob.id))],
       self.detect_renames(tree1, tree2))
示例#53
0
 def test_exact_rename_many_to_one(self):
     blob = make_object(Blob, data=b"1")
     tree1 = self.commit_tree([("a", blob), ("b", blob)])
     tree2 = self.commit_tree([("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),
     )
示例#54
0
 def test_content_rename_max_files(self):
     blob1 = make_object(Blob, data='a\nb\nc\nd')
     blob4 = make_object(Blob, data='a\nb\nc\ne\n')
     blob2 = make_object(Blob, data='e\nf\ng\nh\n')
     blob3 = make_object(Blob, data='e\nf\ng\ni\n')
     tree1 = self.commit_tree([('a', blob1), ('b', blob2)])
     tree2 = self.commit_tree([('c', blob3), ('d', blob4)])
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('d', F, blob4.id)),
        TreeChange(CHANGE_RENAME, ('b', F, blob2.id), ('c', F, blob3.id))],
       self.detect_renames(tree1, tree2))
     self.assertEqual(
       [TreeChange.delete(('a', F, blob1.id)),
        TreeChange.delete(('b', F, blob2.id)),
        TreeChange.add(('c', F, blob3.id)),
        TreeChange.add(('d', F, blob4.id))],
       self.detect_renames(tree1, tree2, max_files=1))
示例#55
0
 def test_exact_rename_and_different_type(self):
     blob1 = make_object(Blob, data='1')
     blob2 = make_object(Blob, data='2')
     tree1 = self.commit_tree([('a', blob1)])
     tree2 = self.commit_tree([('a', blob2, 0o120000), ('b', blob1)])
     self.assertEqual(
       [TreeChange.add(('a', 0o120000, blob2.id)),
        TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('b', F, blob1.id))],
       self.detect_renames(tree1, tree2))
示例#56
0
 def test_find_copies_harder_exact(self):
     blob = make_object(Blob, data='blob')
     tree1 = self.commit_tree([('a', blob)])
     tree2 = self.commit_tree([('a', blob), ('b', blob)])
     self.assertEqual([TreeChange.add(('b', F, blob.id))],
                      self.detect_renames(tree1, tree2))
     self.assertEqual(
       [TreeChange(CHANGE_COPY, ('a', F, blob.id), ('b', F, blob.id))],
       self.detect_renames(tree1, tree2, find_copies_harder=True))
示例#57
0
    def test_content_rename_one_to_one_ordering(self):
        blob1 = make_object(Blob, data='a\nb\nc\nd\ne\nf\n')
        blob2 = make_object(Blob, data='a\nb\nc\nd\ng\nh\n')
        # 6/10 match to blob1, 8/10 match to blob2
        blob3 = make_object(Blob, data='a\nb\nc\nd\ng\ni\n')
        tree1 = self.commit_tree([('a', blob1), ('b', blob2)])
        tree2 = self.commit_tree([('c', blob3)])
        self.assertEqual(
          [TreeChange.delete(('a', F, blob1.id)),
           TreeChange(CHANGE_RENAME, ('b', F, blob2.id), ('c', F, blob3.id))],
          self.detect_renames(tree1, tree2))

        tree3 = self.commit_tree([('a', blob2), ('b', blob1)])
        tree4 = self.commit_tree([('c', blob3)])
        self.assertEqual(
          [TreeChange(CHANGE_RENAME, ('a', F, blob2.id), ('c', F, blob3.id)),
           TreeChange.delete(('b', F, blob1.id))],
          self.detect_renames(tree3, tree4))
示例#58
0
 def test_tree_changes_for_merge_add_exact_rename_conflict(self):
     blob = make_object(Blob, data='a\nb\nc\nd\n')
     parent1 = self.commit_tree([('a', blob)])
     parent2 = self.commit_tree([])
     merge = self.commit_tree([('b', blob)])
     self.assertChangesForMergeEqual(
       [[TreeChange(CHANGE_RENAME, ('a', F, blob.id), ('b', F, blob.id)),
         TreeChange.add(('b', F, blob.id))]],
       [parent1, parent2], merge, rename_detector=self.detector)
示例#59
0
 def test_find_copies_harder_content(self):
     blob1 = make_object(Blob, data='a\nb\nc\nd\n')
     blob2 = make_object(Blob, data='a\nb\nc\ne\n')
     tree1 = self.commit_tree([('a', blob1)])
     tree2 = self.commit_tree([('a', blob1), ('b', blob2)])
     self.assertEqual([TreeChange.add(('b', F, blob2.id))],
                      self.detect_renames(tree1, tree2))
     self.assertEqual(
       [TreeChange(CHANGE_COPY, ('a', F, blob1.id), ('b', F, blob2.id))],
       self.detect_renames(tree1, tree2, find_copies_harder=True))
示例#60
0
 def test_content_rename_many_to_one(self):
     blob1 = make_object(Blob, data='a\nb\nc\nd\n')
     blob2 = make_object(Blob, data='a\nb\nc\ne\n')
     blob3 = make_object(Blob, data='a\nb\nc\nf\n')
     tree1 = self.commit_tree([('a', blob1), ('b', blob2)])
     tree2 = self.commit_tree([('c', blob3)])
     self.assertEqual(
       [TreeChange(CHANGE_RENAME, ('a', F, blob1.id), ('c', F, blob3.id)),
        TreeChange.delete(('b', F, blob2.id))],
       self.detect_renames(tree1, tree2))