138
125
:return: The dirstate, still write-locked.
140
packed_stat = b'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
141
null_sha = b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
142
root_entry = (b'', b'', b'a-root-value'), [
143
(b'd', b'', 0, False, packed_stat),
145
a_entry = (b'', b'a', b'a-dir'), [
146
(b'd', b'', 0, False, packed_stat),
148
b_entry = (b'', b'b', b'b-dir'), [
149
(b'd', b'', 0, False, packed_stat),
151
c_entry = (b'', b'c', b'c-file'), [
152
(b'f', null_sha, 10, False, packed_stat),
154
d_entry = (b'', b'd', b'd-file'), [
155
(b'f', null_sha, 20, False, packed_stat),
157
e_entry = (b'a', b'e', b'e-dir'), [
158
(b'd', b'', 0, False, packed_stat),
160
f_entry = (b'a', b'f', b'f-file'), [
161
(b'f', null_sha, 30, False, packed_stat),
163
g_entry = (b'b', b'g', b'g-file'), [
164
(b'f', null_sha, 30, False, packed_stat),
166
h_entry = (b'b', b'h\xc3\xa5', b'h-\xc3\xa5-file'), [
167
(b'f', null_sha, 40, False, packed_stat),
127
packed_stat = 'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
128
null_sha = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
129
root_entry = ('', '', 'a-root-value'), [
130
('d', '', 0, False, packed_stat),
132
a_entry = ('', 'a', 'a-dir'), [
133
('d', '', 0, False, packed_stat),
135
b_entry = ('', 'b', 'b-dir'), [
136
('d', '', 0, False, packed_stat),
138
c_entry = ('', 'c', 'c-file'), [
139
('f', null_sha, 10, False, packed_stat),
141
d_entry = ('', 'd', 'd-file'), [
142
('f', null_sha, 20, False, packed_stat),
144
e_entry = ('a', 'e', 'e-dir'), [
145
('d', '', 0, False, packed_stat),
147
f_entry = ('a', 'f', 'f-file'), [
148
('f', null_sha, 30, False, packed_stat),
150
g_entry = ('b', 'g', 'g-file'), [
151
('f', null_sha, 30, False, packed_stat),
153
h_entry = ('b', 'h\xc3\xa5', 'h-\xc3\xa5-file'), [
154
('f', null_sha, 40, False, packed_stat),
170
dirblocks.append((b'', [root_entry]))
171
dirblocks.append((b'', [a_entry, b_entry, c_entry, d_entry]))
172
dirblocks.append((b'a', [e_entry, f_entry]))
173
dirblocks.append((b'b', [g_entry, h_entry]))
157
dirblocks.append(('', [root_entry]))
158
dirblocks.append(('', [a_entry, b_entry, c_entry, d_entry]))
159
dirblocks.append(('a', [e_entry, f_entry]))
160
dirblocks.append(('b', [g_entry, h_entry]))
174
161
state = dirstate.DirState.initialize('dirstate')
175
162
state._validate()
256
242
f_len = len(f_text)
257
243
null_stat = dirstate.DirState.NULLSTAT
259
b'': ((b'', b'', b'TREE_ROOT'), [
260
(b'd', b'', 0, False, null_stat),
261
(b'd', b'', 0, False, revision_id),
263
b'a': ((b'', b'a', b'a-id'), [
264
(b'f', b'', 0, False, null_stat),
265
(b'f', a_sha, a_len, False, revision_id),
267
b'b': ((b'', b'b', b'b-id'), [
268
(b'd', b'', 0, False, null_stat),
269
(b'd', b'', 0, False, revision_id),
271
b'b/c': ((b'b', b'c', b'c-id'), [
272
(b'f', b'', 0, False, null_stat),
273
(b'f', c_sha, c_len, False, revision_id),
275
b'b/d': ((b'b', b'd', b'd-id'), [
276
(b'd', b'', 0, False, null_stat),
277
(b'd', b'', 0, False, revision_id),
279
b'b/d/e': ((b'b/d', b'e', b'e-id'), [
280
(b'f', b'', 0, False, null_stat),
281
(b'f', e_sha, e_len, False, revision_id),
283
b'b-c': ((b'', b'b-c', b'b-c-id'), [
284
(b'f', b'', 0, False, null_stat),
285
(b'f', b_c_sha, b_c_len, False, revision_id),
287
b'f': ((b'', b'f', b'f-id'), [
288
(b'f', b'', 0, False, null_stat),
289
(b'f', f_sha, f_len, False, revision_id),
245
'':(('', '', 'TREE_ROOT'), [
246
('d', '', 0, False, null_stat),
247
('d', '', 0, False, revision_id),
249
'a':(('', 'a', 'a-id'), [
250
('f', '', 0, False, null_stat),
251
('f', a_sha, a_len, False, revision_id),
253
'b':(('', 'b', 'b-id'), [
254
('d', '', 0, False, null_stat),
255
('d', '', 0, False, revision_id),
257
'b/c':(('b', 'c', 'c-id'), [
258
('f', '', 0, False, null_stat),
259
('f', c_sha, c_len, False, revision_id),
261
'b/d':(('b', 'd', 'd-id'), [
262
('d', '', 0, False, null_stat),
263
('d', '', 0, False, revision_id),
265
'b/d/e':(('b/d', 'e', 'e-id'), [
266
('f', '', 0, False, null_stat),
267
('f', e_sha, e_len, False, revision_id),
269
'b-c':(('', 'b-c', 'b-c-id'), [
270
('f', '', 0, False, null_stat),
271
('f', b_c_sha, b_c_len, False, revision_id),
273
'f':(('', 'f', 'f-id'), [
274
('f', '', 0, False, null_stat),
275
('f', f_sha, f_len, False, revision_id),
292
278
state = dirstate.DirState.from_tree(tree, 'dirstate')
971
959
"""Set the root file id in a dirstate with parents"""
972
960
mt = self.make_branch_and_tree('mt')
973
961
# in case the default tree format uses a different root id
974
mt.set_root_id(b'TREE_ROOT')
975
mt.commit('foo', rev_id=b'parent-revid')
976
rt = mt.branch.repository.revision_tree(b'parent-revid')
962
mt.set_root_id('TREE_ROOT')
963
mt.commit('foo', rev_id='parent-revid')
964
rt = mt.branch.repository.revision_tree('parent-revid')
977
965
state = dirstate.DirState.initialize('dirstate')
978
966
state._validate()
980
state.set_parent_trees([(b'parent-revid', rt)], ghosts=[])
981
root_entry = ((b'', b'', b'TREE_ROOT'),
982
[(b'd', b'', 0, False, b'x' * 32),
983
(b'd', b'', 0, False, b'parent-revid')])
984
self.assertEqual(root_entry, state._get_entry(0, path_utf8=b''))
968
state.set_parent_trees([('parent-revid', rt)], ghosts=[])
969
root_entry = (('', '', 'TREE_ROOT'),
970
[('d', '', 0, False, 'x'*32),
971
('d', '', 0, False, 'parent-revid')])
972
self.assertEqual(root_entry, state._get_entry(0, path_utf8=''))
985
973
self.assertEqual(root_entry,
986
state._get_entry(0, fileid_utf8=b'TREE_ROOT'))
974
state._get_entry(0, fileid_utf8='TREE_ROOT'))
987
975
self.assertEqual((None, None),
988
state._get_entry(0, fileid_utf8=b'Asecond-root-id'))
989
state.set_path_id(b'', b'Asecond-root-id')
976
state._get_entry(0, fileid_utf8='Asecond-root-id'))
977
state.set_path_id('', 'Asecond-root-id')
990
978
state._validate()
991
979
# now see that it is what we expected
992
old_root_entry = ((b'', b'', b'TREE_ROOT'),
993
[(b'a', b'', 0, False, b''),
994
(b'd', b'', 0, False, b'parent-revid')])
995
new_root_entry = ((b'', b'', b'Asecond-root-id'),
996
[(b'd', b'', 0, False, b''),
997
(b'a', b'', 0, False, b'')])
980
old_root_entry = (('', '', 'TREE_ROOT'),
981
[('a', '', 0, False, ''),
982
('d', '', 0, False, 'parent-revid')])
983
new_root_entry = (('', '', 'Asecond-root-id'),
984
[('d', '', 0, False, ''),
985
('a', '', 0, False, '')])
998
986
expected_rows = [new_root_entry, old_root_entry]
999
987
state._validate()
1000
988
self.assertEqual(expected_rows, list(state._iter_entries()))
1002
new_root_entry, state._get_entry(0, path_utf8=b''))
1004
old_root_entry, state._get_entry(1, path_utf8=b''))
989
self.assertEqual(new_root_entry, state._get_entry(0, path_utf8=''))
990
self.assertEqual(old_root_entry, state._get_entry(1, path_utf8=''))
1005
991
self.assertEqual((None, None),
1006
state._get_entry(0, fileid_utf8=b'TREE_ROOT'))
992
state._get_entry(0, fileid_utf8='TREE_ROOT'))
1007
993
self.assertEqual(old_root_entry,
1008
state._get_entry(1, fileid_utf8=b'TREE_ROOT'))
994
state._get_entry(1, fileid_utf8='TREE_ROOT'))
1009
995
self.assertEqual(new_root_entry,
1010
state._get_entry(0, fileid_utf8=b'Asecond-root-id'))
996
state._get_entry(0, fileid_utf8='Asecond-root-id'))
1011
997
self.assertEqual((None, None),
1012
state._get_entry(1, fileid_utf8=b'Asecond-root-id'))
998
state._get_entry(1, fileid_utf8='Asecond-root-id'))
1013
999
# should work across save too
1529
1515
def test_simple_structure(self):
1530
1516
state = self.create_dirstate_with_root_and_subdir()
1531
1517
self.addCleanup(state.unlock)
1532
self.assertBlockRowIndexEqual(
1533
1, 0, True, True, state, b'', b'subdir', 0)
1534
self.assertBlockRowIndexEqual(
1535
1, 0, True, False, state, b'', b'bdir', 0)
1536
self.assertBlockRowIndexEqual(
1537
1, 1, True, False, state, b'', b'zdir', 0)
1538
self.assertBlockRowIndexEqual(
1539
2, 0, False, False, state, b'a', b'foo', 0)
1518
self.assertBlockRowIndexEqual(1, 0, True, True, state, '', 'subdir', 0)
1519
self.assertBlockRowIndexEqual(1, 0, True, False, state, '', 'bdir', 0)
1520
self.assertBlockRowIndexEqual(1, 1, True, False, state, '', 'zdir', 0)
1521
self.assertBlockRowIndexEqual(2, 0, False, False, state, 'a', 'foo', 0)
1540
1522
self.assertBlockRowIndexEqual(2, 0, False, False, state,
1541
b'subdir', b'foo', 0)
1543
1525
def test_complex_structure_exists(self):
1544
1526
state = self.create_complex_dirstate()
1545
1527
self.addCleanup(state.unlock)
1546
1528
# Make sure we can find everything that exists
1547
self.assertBlockRowIndexEqual(0, 0, True, True, state, b'', b'', 0)
1548
self.assertBlockRowIndexEqual(1, 0, True, True, state, b'', b'a', 0)
1549
self.assertBlockRowIndexEqual(1, 1, True, True, state, b'', b'b', 0)
1550
self.assertBlockRowIndexEqual(1, 2, True, True, state, b'', b'c', 0)
1551
self.assertBlockRowIndexEqual(1, 3, True, True, state, b'', b'd', 0)
1552
self.assertBlockRowIndexEqual(2, 0, True, True, state, b'a', b'e', 0)
1553
self.assertBlockRowIndexEqual(2, 1, True, True, state, b'a', b'f', 0)
1554
self.assertBlockRowIndexEqual(3, 0, True, True, state, b'b', b'g', 0)
1529
self.assertBlockRowIndexEqual(0, 0, True, True, state, '', '', 0)
1530
self.assertBlockRowIndexEqual(1, 0, True, True, state, '', 'a', 0)
1531
self.assertBlockRowIndexEqual(1, 1, True, True, state, '', 'b', 0)
1532
self.assertBlockRowIndexEqual(1, 2, True, True, state, '', 'c', 0)
1533
self.assertBlockRowIndexEqual(1, 3, True, True, state, '', 'd', 0)
1534
self.assertBlockRowIndexEqual(2, 0, True, True, state, 'a', 'e', 0)
1535
self.assertBlockRowIndexEqual(2, 1, True, True, state, 'a', 'f', 0)
1536
self.assertBlockRowIndexEqual(3, 0, True, True, state, 'b', 'g', 0)
1555
1537
self.assertBlockRowIndexEqual(3, 1, True, True, state,
1556
b'b', b'h\xc3\xa5', 0)
1538
'b', 'h\xc3\xa5', 0)
1558
1540
def test_complex_structure_missing(self):
1559
1541
state = self.create_complex_dirstate()
1560
1542
self.addCleanup(state.unlock)
1561
1543
# Make sure things would be inserted in the right locations
1562
1544
# '_' comes before 'a'
1563
self.assertBlockRowIndexEqual(0, 0, True, True, state, b'', b'', 0)
1564
self.assertBlockRowIndexEqual(1, 0, True, False, state, b'', b'_', 0)
1565
self.assertBlockRowIndexEqual(1, 1, True, False, state, b'', b'aa', 0)
1545
self.assertBlockRowIndexEqual(0, 0, True, True, state, '', '', 0)
1546
self.assertBlockRowIndexEqual(1, 0, True, False, state, '', '_', 0)
1547
self.assertBlockRowIndexEqual(1, 1, True, False, state, '', 'aa', 0)
1566
1548
self.assertBlockRowIndexEqual(1, 4, True, False, state,
1567
b'', b'h\xc3\xa5', 0)
1568
self.assertBlockRowIndexEqual(2, 0, False, False, state, b'_', b'a', 0)
1569
self.assertBlockRowIndexEqual(
1570
3, 0, False, False, state, b'aa', b'a', 0)
1571
self.assertBlockRowIndexEqual(
1572
4, 0, False, False, state, b'bb', b'a', 0)
1550
self.assertBlockRowIndexEqual(2, 0, False, False, state, '_', 'a', 0)
1551
self.assertBlockRowIndexEqual(3, 0, False, False, state, 'aa', 'a', 0)
1552
self.assertBlockRowIndexEqual(4, 0, False, False, state, 'bb', 'a', 0)
1573
1553
# This would be inserted between a/ and b/
1574
self.assertBlockRowIndexEqual(
1575
3, 0, False, False, state, b'a/e', b'a', 0)
1554
self.assertBlockRowIndexEqual(3, 0, False, False, state, 'a/e', 'a', 0)
1576
1555
# Put at the end
1577
self.assertBlockRowIndexEqual(4, 0, False, False, state, b'e', b'a', 0)
1556
self.assertBlockRowIndexEqual(4, 0, False, False, state, 'e', 'a', 0)
1580
1559
class TestGetEntry(TestCaseWithDirState):
1591
1570
def test_simple_structure(self):
1592
1571
state = self.create_dirstate_with_root_and_subdir()
1593
1572
self.addCleanup(state.unlock)
1594
self.assertEntryEqual(b'', b'', b'a-root-value', state, b'', 0)
1595
self.assertEntryEqual(
1596
b'', b'subdir', b'subdir-id', state, b'subdir', 0)
1597
self.assertEntryEqual(None, None, None, state, b'missing', 0)
1598
self.assertEntryEqual(None, None, None, state, b'missing/foo', 0)
1599
self.assertEntryEqual(None, None, None, state, b'subdir/foo', 0)
1573
self.assertEntryEqual('', '', 'a-root-value', state, '', 0)
1574
self.assertEntryEqual('', 'subdir', 'subdir-id', state, 'subdir', 0)
1575
self.assertEntryEqual(None, None, None, state, 'missing', 0)
1576
self.assertEntryEqual(None, None, None, state, 'missing/foo', 0)
1577
self.assertEntryEqual(None, None, None, state, 'subdir/foo', 0)
1601
1579
def test_complex_structure_exists(self):
1602
1580
state = self.create_complex_dirstate()
1603
1581
self.addCleanup(state.unlock)
1604
self.assertEntryEqual(b'', b'', b'a-root-value', state, b'', 0)
1605
self.assertEntryEqual(b'', b'a', b'a-dir', state, b'a', 0)
1606
self.assertEntryEqual(b'', b'b', b'b-dir', state, b'b', 0)
1607
self.assertEntryEqual(b'', b'c', b'c-file', state, b'c', 0)
1608
self.assertEntryEqual(b'', b'd', b'd-file', state, b'd', 0)
1609
self.assertEntryEqual(b'a', b'e', b'e-dir', state, b'a/e', 0)
1610
self.assertEntryEqual(b'a', b'f', b'f-file', state, b'a/f', 0)
1611
self.assertEntryEqual(b'b', b'g', b'g-file', state, b'b/g', 0)
1612
self.assertEntryEqual(b'b', b'h\xc3\xa5', b'h-\xc3\xa5-file', state,
1582
self.assertEntryEqual('', '', 'a-root-value', state, '', 0)
1583
self.assertEntryEqual('', 'a', 'a-dir', state, 'a', 0)
1584
self.assertEntryEqual('', 'b', 'b-dir', state, 'b', 0)
1585
self.assertEntryEqual('', 'c', 'c-file', state, 'c', 0)
1586
self.assertEntryEqual('', 'd', 'd-file', state, 'd', 0)
1587
self.assertEntryEqual('a', 'e', 'e-dir', state, 'a/e', 0)
1588
self.assertEntryEqual('a', 'f', 'f-file', state, 'a/f', 0)
1589
self.assertEntryEqual('b', 'g', 'g-file', state, 'b/g', 0)
1590
self.assertEntryEqual('b', 'h\xc3\xa5', 'h-\xc3\xa5-file', state,
1615
1593
def test_complex_structure_missing(self):
1616
1594
state = self.create_complex_dirstate()
1617
1595
self.addCleanup(state.unlock)
1618
self.assertEntryEqual(None, None, None, state, b'_', 0)
1619
self.assertEntryEqual(None, None, None, state, b'_\xc3\xa5', 0)
1620
self.assertEntryEqual(None, None, None, state, b'a/b', 0)
1621
self.assertEntryEqual(None, None, None, state, b'c/d', 0)
1596
self.assertEntryEqual(None, None, None, state, '_', 0)
1597
self.assertEntryEqual(None, None, None, state, '_\xc3\xa5', 0)
1598
self.assertEntryEqual(None, None, None, state, 'a/b', 0)
1599
self.assertEntryEqual(None, None, None, state, 'c/d', 0)
1623
1601
def test_get_entry_uninitialized(self):
1624
1602
"""Calling get_entry will load data if it needs to"""
1666
1644
:return: The dirstate, still write-locked.
1668
packed_stat = b'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
1669
null_sha = b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
1646
packed_stat = 'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
1647
null_sha = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
1670
1648
NULL_PARENT_DETAILS = dirstate.DirState.NULL_PARENT_DETAILS
1671
root_entry = (b'', b'', b'a-root-value'), [
1672
(b'd', b'', 0, False, packed_stat),
1673
(b'd', b'', 0, False, b'parent-revid'),
1675
a_entry = (b'', b'a', b'a-dir'), [
1676
(b'd', b'', 0, False, packed_stat),
1677
(b'd', b'', 0, False, b'parent-revid'),
1679
b_entry = (b'', b'b', b'b-dir'), [
1680
(b'd', b'', 0, False, packed_stat),
1681
(b'd', b'', 0, False, b'parent-revid'),
1683
c_entry = (b'', b'c', b'c-file'), [
1684
(b'f', null_sha, 10, False, packed_stat),
1685
(b'r', b'b/j', 0, False, b''),
1687
d_entry = (b'', b'd', b'd-file'), [
1688
(b'f', null_sha, 20, False, packed_stat),
1689
(b'f', b'd', 20, False, b'parent-revid'),
1691
e_entry = (b'a', b'e', b'e-dir'), [
1692
(b'd', b'', 0, False, packed_stat),
1693
(b'd', b'', 0, False, b'parent-revid'),
1695
f_entry = (b'a', b'f', b'f-file'), [
1696
(b'f', null_sha, 30, False, packed_stat),
1697
(b'f', b'f', 20, False, b'parent-revid'),
1699
g_entry = (b'b', b'g', b'g-file'), [
1700
(b'f', null_sha, 30, False, packed_stat),
1701
NULL_PARENT_DETAILS,
1703
h_entry1 = (b'b', b'h\xc3\xa5', b'h-\xc3\xa5-file1'), [
1704
(b'f', null_sha, 40, False, packed_stat),
1705
NULL_PARENT_DETAILS,
1707
h_entry2 = (b'b', b'h\xc3\xa5', b'h-\xc3\xa5-file2'), [
1708
NULL_PARENT_DETAILS,
1709
(b'f', b'h', 20, False, b'parent-revid'),
1711
i_entry = (b'b', b'i', b'i-file'), [
1712
NULL_PARENT_DETAILS,
1713
(b'f', b'h', 20, False, b'parent-revid'),
1715
j_entry = (b'b', b'j', b'c-file'), [
1716
(b'r', b'c', 0, False, b''),
1717
(b'f', b'j', 20, False, b'parent-revid'),
1649
root_entry = ('', '', 'a-root-value'), [
1650
('d', '', 0, False, packed_stat),
1651
('d', '', 0, False, 'parent-revid'),
1653
a_entry = ('', 'a', 'a-dir'), [
1654
('d', '', 0, False, packed_stat),
1655
('d', '', 0, False, 'parent-revid'),
1657
b_entry = ('', 'b', 'b-dir'), [
1658
('d', '', 0, False, packed_stat),
1659
('d', '', 0, False, 'parent-revid'),
1661
c_entry = ('', 'c', 'c-file'), [
1662
('f', null_sha, 10, False, packed_stat),
1663
('r', 'b/j', 0, False, ''),
1665
d_entry = ('', 'd', 'd-file'), [
1666
('f', null_sha, 20, False, packed_stat),
1667
('f', 'd', 20, False, 'parent-revid'),
1669
e_entry = ('a', 'e', 'e-dir'), [
1670
('d', '', 0, False, packed_stat),
1671
('d', '', 0, False, 'parent-revid'),
1673
f_entry = ('a', 'f', 'f-file'), [
1674
('f', null_sha, 30, False, packed_stat),
1675
('f', 'f', 20, False, 'parent-revid'),
1677
g_entry = ('b', 'g', 'g-file'), [
1678
('f', null_sha, 30, False, packed_stat),
1679
NULL_PARENT_DETAILS,
1681
h_entry1 = ('b', 'h\xc3\xa5', 'h-\xc3\xa5-file1'), [
1682
('f', null_sha, 40, False, packed_stat),
1683
NULL_PARENT_DETAILS,
1685
h_entry2 = ('b', 'h\xc3\xa5', 'h-\xc3\xa5-file2'), [
1686
NULL_PARENT_DETAILS,
1687
('f', 'h', 20, False, 'parent-revid'),
1689
i_entry = ('b', 'i', 'i-file'), [
1690
NULL_PARENT_DETAILS,
1691
('f', 'h', 20, False, 'parent-revid'),
1693
j_entry = ('b', 'j', 'c-file'), [
1694
('r', 'c', 0, False, ''),
1695
('f', 'j', 20, False, 'parent-revid'),
1720
dirblocks.append((b'', [root_entry]))
1721
dirblocks.append((b'', [a_entry, b_entry, c_entry, d_entry]))
1722
dirblocks.append((b'a', [e_entry, f_entry]))
1724
(b'b', [g_entry, h_entry1, h_entry2, i_entry, j_entry]))
1698
dirblocks.append(('', [root_entry]))
1699
dirblocks.append(('', [a_entry, b_entry, c_entry, d_entry]))
1700
dirblocks.append(('a', [e_entry, f_entry]))
1701
dirblocks.append(('b', [g_entry, h_entry1, h_entry2, i_entry, j_entry]))
1725
1702
state = dirstate.DirState.initialize('dirstate')
1726
1703
state._validate()
1728
state._set_data([b'parent'], dirblocks)
1705
state._set_data(['parent'], dirblocks)
2016
1990
tree, state, expected = self.create_basic_dirstate()
2018
1992
# Bisect should return the rows for the specified files.
2019
self.assertBisect(expected, [[b'']], state, [b''])
2020
self.assertBisect(expected, [[b'a']], state, [b'a'])
2021
self.assertBisect(expected, [[b'b']], state, [b'b'])
2022
self.assertBisect(expected, [[b'b/c']], state, [b'b/c'])
2023
self.assertBisect(expected, [[b'b/d']], state, [b'b/d'])
2024
self.assertBisect(expected, [[b'b/d/e']], state, [b'b/d/e'])
2025
self.assertBisect(expected, [[b'b-c']], state, [b'b-c'])
2026
self.assertBisect(expected, [[b'f']], state, [b'f'])
1993
self.assertBisect(expected, [['']], state, [''])
1994
self.assertBisect(expected, [['a']], state, ['a'])
1995
self.assertBisect(expected, [['b']], state, ['b'])
1996
self.assertBisect(expected, [['b/c']], state, ['b/c'])
1997
self.assertBisect(expected, [['b/d']], state, ['b/d'])
1998
self.assertBisect(expected, [['b/d/e']], state, ['b/d/e'])
1999
self.assertBisect(expected, [['b-c']], state, ['b-c'])
2000
self.assertBisect(expected, [['f']], state, ['f'])
2028
2002
def test_bisect_multi(self):
2029
2003
"""Bisect can be used to find multiple records at the same time."""
2030
2004
tree, state, expected = self.create_basic_dirstate()
2031
2005
# Bisect should be capable of finding multiple entries at the same time
2032
self.assertBisect(expected, [[b'a'], [b'b'], [b'f']],
2033
state, [b'a', b'b', b'f'])
2034
self.assertBisect(expected, [[b'f'], [b'b/d'], [b'b/d/e']],
2035
state, [b'f', b'b/d', b'b/d/e'])
2036
self.assertBisect(expected, [[b'b'], [b'b-c'], [b'b/c']],
2037
state, [b'b', b'b-c', b'b/c'])
2006
self.assertBisect(expected, [['a'], ['b'], ['f']],
2007
state, ['a', 'b', 'f'])
2008
self.assertBisect(expected, [['f'], ['b/d'], ['b/d/e']],
2009
state, ['f', 'b/d', 'b/d/e'])
2010
self.assertBisect(expected, [['b'], ['b-c'], ['b/c']],
2011
state, ['b', 'b-c', 'b/c'])
2039
2013
def test_bisect_one_page(self):
2040
2014
"""Test bisect when there is only 1 page to read"""
2041
2015
tree, state, expected = self.create_basic_dirstate()
2042
2016
state._bisect_page_size = 5000
2043
self.assertBisect(expected, [[b'']], state, [b''])
2044
self.assertBisect(expected, [[b'a']], state, [b'a'])
2045
self.assertBisect(expected, [[b'b']], state, [b'b'])
2046
self.assertBisect(expected, [[b'b/c']], state, [b'b/c'])
2047
self.assertBisect(expected, [[b'b/d']], state, [b'b/d'])
2048
self.assertBisect(expected, [[b'b/d/e']], state, [b'b/d/e'])
2049
self.assertBisect(expected, [[b'b-c']], state, [b'b-c'])
2050
self.assertBisect(expected, [[b'f']], state, [b'f'])
2051
self.assertBisect(expected, [[b'a'], [b'b'], [b'f']],
2052
state, [b'a', b'b', b'f'])
2053
self.assertBisect(expected, [[b'b/d'], [b'b/d/e'], [b'f']],
2054
state, [b'b/d', b'b/d/e', b'f'])
2055
self.assertBisect(expected, [[b'b'], [b'b/c'], [b'b-c']],
2056
state, [b'b', b'b/c', b'b-c'])
2017
self.assertBisect(expected,[['']], state, [''])
2018
self.assertBisect(expected,[['a']], state, ['a'])
2019
self.assertBisect(expected,[['b']], state, ['b'])
2020
self.assertBisect(expected,[['b/c']], state, ['b/c'])
2021
self.assertBisect(expected,[['b/d']], state, ['b/d'])
2022
self.assertBisect(expected,[['b/d/e']], state, ['b/d/e'])
2023
self.assertBisect(expected,[['b-c']], state, ['b-c'])
2024
self.assertBisect(expected,[['f']], state, ['f'])
2025
self.assertBisect(expected,[['a'], ['b'], ['f']],
2026
state, ['a', 'b', 'f'])
2027
self.assertBisect(expected, [['b/d'], ['b/d/e'], ['f']],
2028
state, ['b/d', 'b/d/e', 'f'])
2029
self.assertBisect(expected, [['b'], ['b/c'], ['b-c']],
2030
state, ['b', 'b/c', 'b-c'])
2058
2032
def test_bisect_duplicate_paths(self):
2059
2033
"""When bisecting for a path, handle multiple entries."""
2060
2034
tree, state, expected = self.create_duplicated_dirstate()
2062
2036
# Now make sure that both records are properly returned.
2063
self.assertBisect(expected, [[b'']], state, [b''])
2064
self.assertBisect(expected, [[b'a', b'a2']], state, [b'a'])
2065
self.assertBisect(expected, [[b'b', b'b2']], state, [b'b'])
2066
self.assertBisect(expected, [[b'b/c', b'b/c2']], state, [b'b/c'])
2067
self.assertBisect(expected, [[b'b/d', b'b/d2']], state, [b'b/d'])
2068
self.assertBisect(expected, [[b'b/d/e', b'b/d/e2']],
2070
self.assertBisect(expected, [[b'b-c', b'b-c2']], state, [b'b-c'])
2071
self.assertBisect(expected, [[b'f', b'f2']], state, [b'f'])
2037
self.assertBisect(expected, [['']], state, [''])
2038
self.assertBisect(expected, [['a', 'a2']], state, ['a'])
2039
self.assertBisect(expected, [['b', 'b2']], state, ['b'])
2040
self.assertBisect(expected, [['b/c', 'b/c2']], state, ['b/c'])
2041
self.assertBisect(expected, [['b/d', 'b/d2']], state, ['b/d'])
2042
self.assertBisect(expected, [['b/d/e', 'b/d/e2']],
2044
self.assertBisect(expected, [['b-c', 'b-c2']], state, ['b-c'])
2045
self.assertBisect(expected, [['f', 'f2']], state, ['f'])
2073
2047
def test_bisect_page_size_too_small(self):
2074
2048
"""If the page size is too small, we will auto increase it."""
2075
2049
tree, state, expected = self.create_basic_dirstate()
2076
2050
state._bisect_page_size = 50
2077
self.assertBisect(expected, [None], state, [b'b/e'])
2078
self.assertBisect(expected, [[b'a']], state, [b'a'])
2079
self.assertBisect(expected, [[b'b']], state, [b'b'])
2080
self.assertBisect(expected, [[b'b/c']], state, [b'b/c'])
2081
self.assertBisect(expected, [[b'b/d']], state, [b'b/d'])
2082
self.assertBisect(expected, [[b'b/d/e']], state, [b'b/d/e'])
2083
self.assertBisect(expected, [[b'b-c']], state, [b'b-c'])
2084
self.assertBisect(expected, [[b'f']], state, [b'f'])
2051
self.assertBisect(expected, [None], state, ['b/e'])
2052
self.assertBisect(expected, [['a']], state, ['a'])
2053
self.assertBisect(expected, [['b']], state, ['b'])
2054
self.assertBisect(expected, [['b/c']], state, ['b/c'])
2055
self.assertBisect(expected, [['b/d']], state, ['b/d'])
2056
self.assertBisect(expected, [['b/d/e']], state, ['b/d/e'])
2057
self.assertBisect(expected, [['b-c']], state, ['b-c'])
2058
self.assertBisect(expected, [['f']], state, ['f'])
2086
2060
def test_bisect_missing(self):
2087
2061
"""Test that bisect return None if it cannot find a path."""
2088
2062
tree, state, expected = self.create_basic_dirstate()
2089
self.assertBisect(expected, [None], state, [b'foo'])
2090
self.assertBisect(expected, [None], state, [b'b/foo'])
2091
self.assertBisect(expected, [None], state, [b'bar/foo'])
2092
self.assertBisect(expected, [None], state, [b'b-c/foo'])
2063
self.assertBisect(expected, [None], state, ['foo'])
2064
self.assertBisect(expected, [None], state, ['b/foo'])
2065
self.assertBisect(expected, [None], state, ['bar/foo'])
2066
self.assertBisect(expected, [None], state, ['b-c/foo'])
2094
self.assertBisect(expected, [[b'a'], None, [b'b/d']],
2095
state, [b'a', b'foo', b'b/d'])
2068
self.assertBisect(expected, [['a'], None, ['b/d']],
2069
state, ['a', 'foo', 'b/d'])
2097
2071
def test_bisect_rename(self):
2098
2072
"""Check that we find a renamed row."""
2099
2073
tree, state, expected = self.create_renamed_dirstate()
2101
2075
# Search for the pre and post renamed entries
2102
self.assertBisect(expected, [[b'a']], state, [b'a'])
2103
self.assertBisect(expected, [[b'b/g']], state, [b'b/g'])
2104
self.assertBisect(expected, [[b'b/d']], state, [b'b/d'])
2105
self.assertBisect(expected, [[b'h']], state, [b'h'])
2076
self.assertBisect(expected, [['a']], state, ['a'])
2077
self.assertBisect(expected, [['b/g']], state, ['b/g'])
2078
self.assertBisect(expected, [['b/d']], state, ['b/d'])
2079
self.assertBisect(expected, [['h']], state, ['h'])
2107
2081
# What about b/d/e? shouldn't that also get 2 directory entries?
2108
self.assertBisect(expected, [[b'b/d/e']], state, [b'b/d/e'])
2109
self.assertBisect(expected, [[b'h/e']], state, [b'h/e'])
2082
self.assertBisect(expected, [['b/d/e']], state, ['b/d/e'])
2083
self.assertBisect(expected, [['h/e']], state, ['h/e'])
2111
2085
def test_bisect_dirblocks(self):
2112
2086
tree, state, expected = self.create_duplicated_dirstate()
2113
2087
self.assertBisectDirBlocks(expected,
2114
[[b'', b'a', b'a2', b'b', b'b2',
2115
b'b-c', b'b-c2', b'f', b'f2']],
2117
self.assertBisectDirBlocks(expected,
2118
[[b'b/c', b'b/c2', b'b/d', b'b/d2']], state, [b'b'])
2119
self.assertBisectDirBlocks(expected,
2120
[[b'b/d/e', b'b/d/e2']], state, [b'b/d'])
2121
self.assertBisectDirBlocks(expected,
2122
[[b'', b'a', b'a2', b'b', b'b2', b'b-c', b'b-c2', b'f', b'f2'],
2123
[b'b/c', b'b/c2', b'b/d', b'b/d2'],
2124
[b'b/d/e', b'b/d/e2'],
2125
], state, [b'', b'b', b'b/d'])
2088
[['', 'a', 'a2', 'b', 'b2', 'b-c', 'b-c2', 'f', 'f2']],
2090
self.assertBisectDirBlocks(expected,
2091
[['b/c', 'b/c2', 'b/d', 'b/d2']], state, ['b'])
2092
self.assertBisectDirBlocks(expected,
2093
[['b/d/e', 'b/d/e2']], state, ['b/d'])
2094
self.assertBisectDirBlocks(expected,
2095
[['', 'a', 'a2', 'b', 'b2', 'b-c', 'b-c2', 'f', 'f2'],
2096
['b/c', 'b/c2', 'b/d', 'b/d2'],
2097
['b/d/e', 'b/d/e2'],
2098
], state, ['', 'b', 'b/d'])
2127
2100
def test_bisect_dirblocks_missing(self):
2128
2101
tree, state, expected = self.create_basic_dirstate()
2129
self.assertBisectDirBlocks(expected, [[b'b/d/e'], None],
2130
state, [b'b/d', b'b/e'])
2102
self.assertBisectDirBlocks(expected, [['b/d/e'], None],
2103
state, ['b/d', 'b/e'])
2131
2104
# Files don't show up in this search
2132
self.assertBisectDirBlocks(expected, [None], state, [b'a'])
2133
self.assertBisectDirBlocks(expected, [None], state, [b'b/c'])
2134
self.assertBisectDirBlocks(expected, [None], state, [b'c'])
2135
self.assertBisectDirBlocks(expected, [None], state, [b'b/d/e'])
2136
self.assertBisectDirBlocks(expected, [None], state, [b'f'])
2105
self.assertBisectDirBlocks(expected, [None], state, ['a'])
2106
self.assertBisectDirBlocks(expected, [None], state, ['b/c'])
2107
self.assertBisectDirBlocks(expected, [None], state, ['c'])
2108
self.assertBisectDirBlocks(expected, [None], state, ['b/d/e'])
2109
self.assertBisectDirBlocks(expected, [None], state, ['f'])
2138
2111
def test_bisect_recursive_each(self):
2139
2112
tree, state, expected = self.create_basic_dirstate()
2140
self.assertBisectRecursive(expected, [b'a'], state, [b'a'])
2141
self.assertBisectRecursive(expected, [b'b/c'], state, [b'b/c'])
2142
self.assertBisectRecursive(expected, [b'b/d/e'], state, [b'b/d/e'])
2143
self.assertBisectRecursive(expected, [b'b-c'], state, [b'b-c'])
2144
self.assertBisectRecursive(expected, [b'b/d', b'b/d/e'],
2146
self.assertBisectRecursive(expected, [b'b', b'b/c', b'b/d', b'b/d/e'],
2148
self.assertBisectRecursive(expected, [b'', b'a', b'b', b'b-c', b'f', b'b/c',
2113
self.assertBisectRecursive(expected, ['a'], state, ['a'])
2114
self.assertBisectRecursive(expected, ['b/c'], state, ['b/c'])
2115
self.assertBisectRecursive(expected, ['b/d/e'], state, ['b/d/e'])
2116
self.assertBisectRecursive(expected, ['b-c'], state, ['b-c'])
2117
self.assertBisectRecursive(expected, ['b/d', 'b/d/e'],
2119
self.assertBisectRecursive(expected, ['b', 'b/c', 'b/d', 'b/d/e'],
2121
self.assertBisectRecursive(expected, ['', 'a', 'b', 'b-c', 'f', 'b/c',
2152
2125
def test_bisect_recursive_multiple(self):
2153
2126
tree, state, expected = self.create_basic_dirstate()
2154
self.assertBisectRecursive(
2155
expected, [b'a', b'b/c'], state, [b'a', b'b/c'])
2156
self.assertBisectRecursive(expected, [b'b/d', b'b/d/e'],
2157
state, [b'b/d', b'b/d/e'])
2127
self.assertBisectRecursive(expected, ['a', 'b/c'], state, ['a', 'b/c'])
2128
self.assertBisectRecursive(expected, ['b/d', 'b/d/e'],
2129
state, ['b/d', 'b/d/e'])
2159
2131
def test_bisect_recursive_missing(self):
2160
2132
tree, state, expected = self.create_basic_dirstate()
2161
self.assertBisectRecursive(expected, [], state, [b'd'])
2162
self.assertBisectRecursive(expected, [], state, [b'b/e'])
2163
self.assertBisectRecursive(expected, [], state, [b'g'])
2164
self.assertBisectRecursive(expected, [b'a'], state, [b'a', b'g'])
2133
self.assertBisectRecursive(expected, [], state, ['d'])
2134
self.assertBisectRecursive(expected, [], state, ['b/e'])
2135
self.assertBisectRecursive(expected, [], state, ['g'])
2136
self.assertBisectRecursive(expected, ['a'], state, ['a', 'g'])
2166
2138
def test_bisect_recursive_renamed(self):
2167
2139
tree, state, expected = self.create_renamed_dirstate()
2169
2141
# Looking for either renamed item should find the other
2170
self.assertBisectRecursive(expected, [b'a', b'b/g'], state, [b'a'])
2171
self.assertBisectRecursive(expected, [b'a', b'b/g'], state, [b'b/g'])
2142
self.assertBisectRecursive(expected, ['a', 'b/g'], state, ['a'])
2143
self.assertBisectRecursive(expected, ['a', 'b/g'], state, ['b/g'])
2172
2144
# Looking in the containing directory should find the rename target,
2173
2145
# and anything in a subdir of the renamed target.
2174
self.assertBisectRecursive(expected, [b'a', b'b', b'b/c', b'b/d',
2175
b'b/d/e', b'b/g', b'h', b'h/e'],
2146
self.assertBisectRecursive(expected, ['a', 'b', 'b/c', 'b/d',
2147
'b/d/e', 'b/g', 'h', 'h/e'],
2179
2151
class TestDirstateValidation(TestCaseWithDirState):
2285
2257
def test_discard_simple(self):
2287
packed_stat = b'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
2288
root_entry_direntry = (b'', b'', b'a-root-value'), [
2289
(b'd', b'', 0, False, packed_stat),
2290
(b'd', b'', 0, False, packed_stat),
2291
(b'd', b'', 0, False, packed_stat),
2259
packed_stat = 'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
2260
root_entry_direntry = ('', '', 'a-root-value'), [
2261
('d', '', 0, False, packed_stat),
2262
('d', '', 0, False, packed_stat),
2263
('d', '', 0, False, packed_stat),
2293
expected_root_entry_direntry = (b'', b'', b'a-root-value'), [
2294
(b'd', b'', 0, False, packed_stat),
2295
(b'd', b'', 0, False, packed_stat),
2265
expected_root_entry_direntry = ('', '', 'a-root-value'), [
2266
('d', '', 0, False, packed_stat),
2267
('d', '', 0, False, packed_stat),
2298
dirblocks.append((b'', [root_entry_direntry]))
2299
dirblocks.append((b'', []))
2270
dirblocks.append(('', [root_entry_direntry]))
2271
dirblocks.append(('', []))
2301
2273
state = self.create_empty_dirstate()
2302
2274
self.addCleanup(state.unlock)
2303
state._set_data([b'parent-id', b'merged-id'], dirblocks[:])
2275
state._set_data(['parent-id', 'merged-id'], dirblocks[:])
2304
2276
state._validate()
2306
2278
# This should strip of the extra column
2307
2279
state._discard_merge_parents()
2308
2280
state._validate()
2309
expected_dirblocks = [(b'', [expected_root_entry_direntry]), (b'', [])]
2281
expected_dirblocks = [('', [expected_root_entry_direntry]), ('', [])]
2310
2282
self.assertEqual(expected_dirblocks, state._dirblocks)
2312
2284
def test_discard_absent(self):
2313
2285
"""If entries are only in a merge, discard should remove the entries"""
2314
2286
null_stat = dirstate.DirState.NULLSTAT
2315
present_dir = (b'd', b'', 0, False, null_stat)
2316
present_file = (b'f', b'', 0, False, null_stat)
2287
present_dir = ('d', '', 0, False, null_stat)
2288
present_file = ('f', '', 0, False, null_stat)
2317
2289
absent = dirstate.DirState.NULL_PARENT_DETAILS
2318
root_key = (b'', b'', b'a-root-value')
2319
file_in_root_key = (b'', b'file-in-root', b'a-file-id')
2320
file_in_merged_key = (b'', b'file-in-merged', b'b-file-id')
2321
dirblocks = [(b'', [(root_key, [present_dir, present_dir, present_dir])]),
2322
(b'', [(file_in_merged_key,
2323
[absent, absent, present_file]),
2325
[present_file, present_file, present_file]),
2290
root_key = ('', '', 'a-root-value')
2291
file_in_root_key = ('', 'file-in-root', 'a-file-id')
2292
file_in_merged_key = ('', 'file-in-merged', 'b-file-id')
2293
dirblocks = [('', [(root_key, [present_dir, present_dir, present_dir])]),
2294
('', [(file_in_merged_key,
2295
[absent, absent, present_file]),
2297
[present_file, present_file, present_file]),
2329
2301
state = self.create_empty_dirstate()
2330
2302
self.addCleanup(state.unlock)
2331
state._set_data([b'parent-id', b'merged-id'], dirblocks[:])
2303
state._set_data(['parent-id', 'merged-id'], dirblocks[:])
2332
2304
state._validate()
2334
exp_dirblocks = [(b'', [(root_key, [present_dir, present_dir])]),
2335
(b'', [(file_in_root_key,
2336
[present_file, present_file]),
2306
exp_dirblocks = [('', [(root_key, [present_dir, present_dir])]),
2307
('', [(file_in_root_key,
2308
[present_file, present_file]),
2339
2311
state._discard_merge_parents()
2340
2312
state._validate()
2341
2313
self.assertEqual(exp_dirblocks, state._dirblocks)
2343
2315
def test_discard_renamed(self):
2344
2316
null_stat = dirstate.DirState.NULLSTAT
2345
present_dir = (b'd', b'', 0, False, null_stat)
2346
present_file = (b'f', b'', 0, False, null_stat)
2317
present_dir = ('d', '', 0, False, null_stat)
2318
present_file = ('f', '', 0, False, null_stat)
2347
2319
absent = dirstate.DirState.NULL_PARENT_DETAILS
2348
root_key = (b'', b'', b'a-root-value')
2349
file_in_root_key = (b'', b'file-in-root', b'a-file-id')
2320
root_key = ('', '', 'a-root-value')
2321
file_in_root_key = ('', 'file-in-root', 'a-file-id')
2350
2322
# Renamed relative to parent
2351
file_rename_s_key = (b'', b'file-s', b'b-file-id')
2352
file_rename_t_key = (b'', b'file-t', b'b-file-id')
2323
file_rename_s_key = ('', 'file-s', 'b-file-id')
2324
file_rename_t_key = ('', 'file-t', 'b-file-id')
2353
2325
# And one that is renamed between the parents, but absent in this
2354
key_in_1 = (b'', b'file-in-1', b'c-file-id')
2355
key_in_2 = (b'', b'file-in-2', b'c-file-id')
2326
key_in_1 = ('', 'file-in-1', 'c-file-id')
2327
key_in_2 = ('', 'file-in-2', 'c-file-id')
2358
(b'', [(root_key, [present_dir, present_dir, present_dir])]),
2360
[absent, present_file, (b'r', b'file-in-2', b'c-file-id')]),
2362
[absent, (b'r', b'file-in-1', b'c-file-id'), present_file]),
2364
[present_file, present_file, present_file]),
2366
[(b'r', b'file-t', b'b-file-id'), absent, present_file]),
2368
[present_file, absent, (b'r', b'file-s', b'b-file-id')]),
2330
('', [(root_key, [present_dir, present_dir, present_dir])]),
2332
[absent, present_file, ('r', 'file-in-2', 'c-file-id')]),
2334
[absent, ('r', 'file-in-1', 'c-file-id'), present_file]),
2336
[present_file, present_file, present_file]),
2338
[('r', 'file-t', 'b-file-id'), absent, present_file]),
2340
[present_file, absent, ('r', 'file-s', 'b-file-id')]),
2371
2343
exp_dirblocks = [
2372
(b'', [(root_key, [present_dir, present_dir])]),
2373
(b'', [(key_in_1, [absent, present_file]),
2374
(file_in_root_key, [present_file, present_file]),
2375
(file_rename_t_key, [present_file, absent]),
2344
('', [(root_key, [present_dir, present_dir])]),
2345
('', [(key_in_1, [absent, present_file]),
2346
(file_in_root_key, [present_file, present_file]),
2347
(file_rename_t_key, [present_file, absent]),
2378
2350
state = self.create_empty_dirstate()
2379
2351
self.addCleanup(state.unlock)
2380
state._set_data([b'parent-id', b'merged-id'], dirblocks[:])
2352
state._set_data(['parent-id', 'merged-id'], dirblocks[:])
2381
2353
state._validate()
2383
2355
state._discard_merge_parents()
2584
2556
:param basis: The basis tree shape
2585
2557
:param delta: A description of the delta to apply. Similar to the form
2586
2558
for regular inventory deltas, but omitting the InventoryEntry.
2587
So adding a file is: (None, 'path', b'file-id')
2588
Adding a directory is: (None, 'path/', b'dir-id')
2589
Renaming a dir is: ('old/', 'new/', b'dir-id')
2559
So adding a file is: (None, 'path', 'file-id')
2560
Adding a directory is: (None, 'path/', 'dir-id')
2561
Renaming a dir is: ('old/', 'new/', 'dir-id')
2592
active_tree = self.create_tree_from_shape(b'active', active)
2593
basis_tree = self.create_tree_from_shape(b'basis', basis)
2594
inv_delta = self.create_inv_delta(delta, b'target')
2564
active_tree = self.create_tree_from_shape('active', active)
2565
basis_tree = self.create_tree_from_shape('basis', basis)
2566
inv_delta = self.create_inv_delta(delta, 'target')
2595
2567
state = self.create_empty_dirstate()
2596
2568
state.set_state_from_scratch(active_tree.root_inventory,
2597
[(b'basis', basis_tree)], [])
2569
[('basis', basis_tree)], [])
2598
2570
self.assertRaises(errors.InconsistentDelta,
2599
state.update_basis_by_delta, inv_delta, b'target')
2601
## state.update_basis_by_delta(inv_delta, b'target')
2602
# except errors.InconsistentDelta, e:
2571
state.update_basis_by_delta, inv_delta, 'target')
2573
## state.update_basis_by_delta(inv_delta, 'target')
2574
## except errors.InconsistentDelta, e:
2603
2575
## import pdb; pdb.set_trace()
2605
2577
## import pdb; pdb.set_trace()
2606
2578
self.assertTrue(state._changes_aborted)
2608
2580
def test_remove_file_matching_active_state(self):
2609
2581
state = self.assertUpdate(
2611
basis=[('file', b'file-id')],
2583
basis =[('file', 'file-id')],
2615
2587
def test_remove_file_present_in_active_state(self):
2616
2588
state = self.assertUpdate(
2617
active=[('file', b'file-id')],
2618
basis=[('file', b'file-id')],
2589
active=[('file', 'file-id')],
2590
basis =[('file', 'file-id')],
2622
2594
def test_remove_file_present_elsewhere_in_active_state(self):
2623
2595
state = self.assertUpdate(
2624
active=[('other-file', b'file-id')],
2625
basis=[('file', b'file-id')],
2596
active=[('other-file', 'file-id')],
2597
basis =[('file', 'file-id')],
2629
2601
def test_remove_file_active_state_has_diff_file(self):
2630
2602
state = self.assertUpdate(
2631
active=[('file', b'file-id-2')],
2632
basis=[('file', b'file-id')],
2603
active=[('file', 'file-id-2')],
2604
basis =[('file', 'file-id')],
2636
2608
def test_remove_file_active_state_has_diff_file_and_file_elsewhere(self):
2637
2609
state = self.assertUpdate(
2638
active=[('file', b'file-id-2'),
2639
('other-file', b'file-id')],
2640
basis=[('file', b'file-id')],
2610
active=[('file', 'file-id-2'),
2611
('other-file', 'file-id')],
2612
basis =[('file', 'file-id')],
2644
2616
def test_add_file_matching_active_state(self):
2645
2617
state = self.assertUpdate(
2646
active=[('file', b'file-id')],
2648
target=[('file', b'file-id')],
2618
active=[('file', 'file-id')],
2620
target=[('file', 'file-id')],
2651
2623
def test_add_file_in_empty_dir_not_matching_active_state(self):
2652
2624
state = self.assertUpdate(
2654
basis=[('dir/', b'dir-id')],
2655
target=[('dir/', b'dir-id', b'basis'), ('dir/file', b'file-id')],
2626
basis=[('dir/', 'dir-id')],
2627
target=[('dir/', 'dir-id', 'basis'), ('dir/file', 'file-id')],
2658
2630
def test_add_file_missing_in_active_state(self):
2659
2631
state = self.assertUpdate(
2662
target=[('file', b'file-id')],
2634
target=[('file', 'file-id')],
2665
2637
def test_add_file_elsewhere_in_active_state(self):
2666
2638
state = self.assertUpdate(
2667
active=[('other-file', b'file-id')],
2669
target=[('file', b'file-id')],
2639
active=[('other-file', 'file-id')],
2641
target=[('file', 'file-id')],
2672
2644
def test_add_file_active_state_has_diff_file_and_file_elsewhere(self):
2673
2645
state = self.assertUpdate(
2674
active=[('other-file', b'file-id'),
2675
('file', b'file-id-2')],
2677
target=[('file', b'file-id')],
2646
active=[('other-file', 'file-id'),
2647
('file', 'file-id-2')],
2649
target=[('file', 'file-id')],
2680
2652
def test_rename_file_matching_active_state(self):
2681
2653
state = self.assertUpdate(
2682
active=[('other-file', b'file-id')],
2683
basis=[('file', b'file-id')],
2684
target=[('other-file', b'file-id')],
2654
active=[('other-file', 'file-id')],
2655
basis =[('file', 'file-id')],
2656
target=[('other-file', 'file-id')],
2687
2659
def test_rename_file_missing_in_active_state(self):
2688
2660
state = self.assertUpdate(
2690
basis=[('file', b'file-id')],
2691
target=[('other-file', b'file-id')],
2662
basis =[('file', 'file-id')],
2663
target=[('other-file', 'file-id')],
2694
2666
def test_rename_file_present_elsewhere_in_active_state(self):
2695
2667
state = self.assertUpdate(
2696
active=[('third', b'file-id')],
2697
basis=[('file', b'file-id')],
2698
target=[('other-file', b'file-id')],
2668
active=[('third', 'file-id')],
2669
basis =[('file', 'file-id')],
2670
target=[('other-file', 'file-id')],
2701
2673
def test_rename_file_active_state_has_diff_source_file(self):
2702
2674
state = self.assertUpdate(
2703
active=[('file', b'file-id-2')],
2704
basis=[('file', b'file-id')],
2705
target=[('other-file', b'file-id')],
2675
active=[('file', 'file-id-2')],
2676
basis =[('file', 'file-id')],
2677
target=[('other-file', 'file-id')],
2708
2680
def test_rename_file_active_state_has_diff_target_file(self):
2709
2681
state = self.assertUpdate(
2710
active=[('other-file', b'file-id-2')],
2711
basis=[('file', b'file-id')],
2712
target=[('other-file', b'file-id')],
2682
active=[('other-file', 'file-id-2')],
2683
basis =[('file', 'file-id')],
2684
target=[('other-file', 'file-id')],
2715
2687
def test_rename_file_active_has_swapped_files(self):
2716
2688
state = self.assertUpdate(
2717
active=[('file', b'file-id'),
2718
('other-file', b'file-id-2')],
2719
basis=[('file', b'file-id'),
2720
('other-file', b'file-id-2')],
2721
target=[('file', b'file-id-2'),
2722
('other-file', b'file-id')])
2689
active=[('file', 'file-id'),
2690
('other-file', 'file-id-2')],
2691
basis= [('file', 'file-id'),
2692
('other-file', 'file-id-2')],
2693
target=[('file', 'file-id-2'),
2694
('other-file', 'file-id')])
2724
2696
def test_rename_file_basis_has_swapped_files(self):
2725
2697
state = self.assertUpdate(
2726
active=[('file', b'file-id'),
2727
('other-file', b'file-id-2')],
2728
basis=[('file', b'file-id-2'),
2729
('other-file', b'file-id')],
2730
target=[('file', b'file-id'),
2731
('other-file', b'file-id-2')])
2698
active=[('file', 'file-id'),
2699
('other-file', 'file-id-2')],
2700
basis= [('file', 'file-id-2'),
2701
('other-file', 'file-id')],
2702
target=[('file', 'file-id'),
2703
('other-file', 'file-id-2')])
2733
2705
def test_rename_directory_with_contents(self):
2734
state = self.assertUpdate( # active matches basis
2735
active=[('dir1/', b'dir-id'),
2736
('dir1/file', b'file-id')],
2737
basis=[('dir1/', b'dir-id'),
2738
('dir1/file', b'file-id')],
2739
target=[('dir2/', b'dir-id'),
2740
('dir2/file', b'file-id')])
2741
state = self.assertUpdate( # active matches target
2742
active=[('dir2/', b'dir-id'),
2743
('dir2/file', b'file-id')],
2744
basis=[('dir1/', b'dir-id'),
2745
('dir1/file', b'file-id')],
2746
target=[('dir2/', b'dir-id'),
2747
('dir2/file', b'file-id')])
2748
state = self.assertUpdate( # active empty
2706
state = self.assertUpdate( # active matches basis
2707
active=[('dir1/', 'dir-id'),
2708
('dir1/file', 'file-id')],
2709
basis= [('dir1/', 'dir-id'),
2710
('dir1/file', 'file-id')],
2711
target=[('dir2/', 'dir-id'),
2712
('dir2/file', 'file-id')])
2713
state = self.assertUpdate( # active matches target
2714
active=[('dir2/', 'dir-id'),
2715
('dir2/file', 'file-id')],
2716
basis= [('dir1/', 'dir-id'),
2717
('dir1/file', 'file-id')],
2718
target=[('dir2/', 'dir-id'),
2719
('dir2/file', 'file-id')])
2720
state = self.assertUpdate( # active empty
2750
basis=[('dir1/', b'dir-id'),
2751
('dir1/file', b'file-id')],
2752
target=[('dir2/', b'dir-id'),
2753
('dir2/file', b'file-id')])
2754
state = self.assertUpdate( # active present at other location
2755
active=[('dir3/', b'dir-id'),
2756
('dir3/file', b'file-id')],
2757
basis=[('dir1/', b'dir-id'),
2758
('dir1/file', b'file-id')],
2759
target=[('dir2/', b'dir-id'),
2760
('dir2/file', b'file-id')])
2761
state = self.assertUpdate( # active has different ids
2762
active=[('dir1/', b'dir1-id'),
2763
('dir1/file', b'file1-id'),
2764
('dir2/', b'dir2-id'),
2765
('dir2/file', b'file2-id')],
2766
basis=[('dir1/', b'dir-id'),
2767
('dir1/file', b'file-id')],
2768
target=[('dir2/', b'dir-id'),
2769
('dir2/file', b'file-id')])
2722
basis= [('dir1/', 'dir-id'),
2723
('dir1/file', 'file-id')],
2724
target=[('dir2/', 'dir-id'),
2725
('dir2/file', 'file-id')])
2726
state = self.assertUpdate( # active present at other location
2727
active=[('dir3/', 'dir-id'),
2728
('dir3/file', 'file-id')],
2729
basis= [('dir1/', 'dir-id'),
2730
('dir1/file', 'file-id')],
2731
target=[('dir2/', 'dir-id'),
2732
('dir2/file', 'file-id')])
2733
state = self.assertUpdate( # active has different ids
2734
active=[('dir1/', 'dir1-id'),
2735
('dir1/file', 'file1-id'),
2736
('dir2/', 'dir2-id'),
2737
('dir2/file', 'file2-id')],
2738
basis= [('dir1/', 'dir-id'),
2739
('dir1/file', 'file-id')],
2740
target=[('dir2/', 'dir-id'),
2741
('dir2/file', 'file-id')])
2771
2743
def test_invalid_file_not_present(self):
2772
2744
state = self.assertBadDelta(
2773
active=[('file', b'file-id')],
2774
basis=[('file', b'file-id')],
2775
delta=[('other-file', 'file', b'file-id')])
2745
active=[('file', 'file-id')],
2746
basis= [('file', 'file-id')],
2747
delta=[('other-file', 'file', 'file-id')])
2777
2749
def test_invalid_new_id_same_path(self):
2778
2750
# The bad entry comes after
2779
2751
state = self.assertBadDelta(
2780
active=[('file', b'file-id')],
2781
basis=[('file', b'file-id')],
2782
delta=[(None, 'file', b'file-id-2')])
2752
active=[('file', 'file-id')],
2753
basis= [('file', 'file-id')],
2754
delta=[(None, 'file', 'file-id-2')])
2783
2755
# The bad entry comes first
2784
2756
state = self.assertBadDelta(
2785
active=[('file', b'file-id-2')],
2786
basis=[('file', b'file-id-2')],
2787
delta=[(None, 'file', b'file-id')])
2757
active=[('file', 'file-id-2')],
2758
basis=[('file', 'file-id-2')],
2759
delta=[(None, 'file', 'file-id')])
2789
2761
def test_invalid_existing_id(self):
2790
2762
state = self.assertBadDelta(
2791
active=[('file', b'file-id')],
2792
basis=[('file', b'file-id')],
2793
delta=[(None, 'file', b'file-id')])
2763
active=[('file', 'file-id')],
2764
basis= [('file', 'file-id')],
2765
delta=[(None, 'file', 'file-id')])
2795
2767
def test_invalid_parent_missing(self):
2796
2768
state = self.assertBadDelta(
2799
delta=[(None, 'path/path2', b'file-id')])
2771
delta=[(None, 'path/path2', 'file-id')])
2800
2772
# Note: we force the active tree to have the directory, by knowing how
2801
2773
# path_to_ie handles entries with missing parents
2802
2774
state = self.assertBadDelta(
2803
active=[('path/', b'path-id')],
2805
delta=[(None, 'path/path2', b'file-id')])
2775
active=[('path/', 'path-id')],
2777
delta=[(None, 'path/path2', 'file-id')])
2806
2778
state = self.assertBadDelta(
2807
active=[('path/', b'path-id'),
2808
('path/path2', b'file-id')],
2810
delta=[(None, 'path/path2', b'file-id')])
2779
active=[('path/', 'path-id'),
2780
('path/path2', 'file-id')],
2782
delta=[(None, 'path/path2', 'file-id')])
2812
2784
def test_renamed_dir_same_path(self):
2813
2785
# We replace the parent directory, with another parent dir. But the C
2814
2786
# file doesn't look like it has been moved.
2815
state = self.assertUpdate( # Same as basis
2816
active=[('dir/', b'A-id'),
2817
('dir/B', b'B-id')],
2818
basis=[('dir/', b'A-id'),
2819
('dir/B', b'B-id')],
2820
target=[('dir/', b'C-id'),
2821
('dir/B', b'B-id')])
2822
state = self.assertUpdate( # Same as target
2823
active=[('dir/', b'C-id'),
2824
('dir/B', b'B-id')],
2825
basis=[('dir/', b'A-id'),
2826
('dir/B', b'B-id')],
2827
target=[('dir/', b'C-id'),
2828
('dir/B', b'B-id')])
2829
state = self.assertUpdate( # empty active
2787
state = self.assertUpdate(# Same as basis
2788
active=[('dir/', 'A-id'),
2790
basis= [('dir/', 'A-id'),
2792
target=[('dir/', 'C-id'),
2794
state = self.assertUpdate(# Same as target
2795
active=[('dir/', 'C-id'),
2797
basis= [('dir/', 'A-id'),
2799
target=[('dir/', 'C-id'),
2801
state = self.assertUpdate(# empty active
2831
basis=[('dir/', b'A-id'),
2832
('dir/B', b'B-id')],
2833
target=[('dir/', b'C-id'),
2834
('dir/B', b'B-id')])
2835
state = self.assertUpdate( # different active
2836
active=[('dir/', b'D-id'),
2837
('dir/B', b'B-id')],
2838
basis=[('dir/', b'A-id'),
2839
('dir/B', b'B-id')],
2840
target=[('dir/', b'C-id'),
2841
('dir/B', b'B-id')])
2803
basis= [('dir/', 'A-id'),
2805
target=[('dir/', 'C-id'),
2807
state = self.assertUpdate(# different active
2808
active=[('dir/', 'D-id'),
2810
basis= [('dir/', 'A-id'),
2812
target=[('dir/', 'C-id'),
2843
2815
def test_parent_child_swap(self):
2844
state = self.assertUpdate( # Same as basis
2845
active=[('A/', b'A-id'),
2847
('A/B/C', b'C-id')],
2848
basis=[('A/', b'A-id'),
2850
('A/B/C', b'C-id')],
2851
target=[('A/', b'B-id'),
2853
('A/B/C', b'C-id')])
2854
state = self.assertUpdate( # Same as target
2855
active=[('A/', b'B-id'),
2857
('A/B/C', b'C-id')],
2858
basis=[('A/', b'A-id'),
2860
('A/B/C', b'C-id')],
2861
target=[('A/', b'B-id'),
2863
('A/B/C', b'C-id')])
2864
state = self.assertUpdate( # empty active
2816
state = self.assertUpdate(# Same as basis
2817
active=[('A/', 'A-id'),
2820
basis= [('A/', 'A-id'),
2823
target=[('A/', 'B-id'),
2826
state = self.assertUpdate(# Same as target
2827
active=[('A/', 'B-id'),
2830
basis= [('A/', 'A-id'),
2833
target=[('A/', 'B-id'),
2836
state = self.assertUpdate(# empty active
2866
basis=[('A/', b'A-id'),
2868
('A/B/C', b'C-id')],
2869
target=[('A/', b'B-id'),
2871
('A/B/C', b'C-id')])
2872
state = self.assertUpdate( # different active
2873
active=[('D/', b'A-id'),
2876
basis=[('A/', b'A-id'),
2878
('A/B/C', b'C-id')],
2879
target=[('A/', b'B-id'),
2881
('A/B/C', b'C-id')])
2838
basis= [('A/', 'A-id'),
2841
target=[('A/', 'B-id'),
2844
state = self.assertUpdate(# different active
2845
active=[('D/', 'A-id'),
2848
basis= [('A/', 'A-id'),
2851
target=[('A/', 'B-id'),
2883
2855
def test_change_root_id(self):
2884
state = self.assertUpdate( # same as basis
2885
active=[('', b'root-id'),
2886
('file', b'file-id')],
2887
basis=[('', b'root-id'),
2888
('file', b'file-id')],
2889
target=[('', b'target-root-id'),
2890
('file', b'file-id')])
2891
state = self.assertUpdate( # same as target
2892
active=[('', b'target-root-id'),
2893
('file', b'file-id')],
2894
basis=[('', b'root-id'),
2895
('file', b'file-id')],
2896
target=[('', b'target-root-id'),
2897
('file', b'root-id')])
2898
state = self.assertUpdate( # all different
2899
active=[('', b'active-root-id'),
2900
('file', b'file-id')],
2901
basis=[('', b'root-id'),
2902
('file', b'file-id')],
2903
target=[('', b'target-root-id'),
2904
('file', b'root-id')])
2856
state = self.assertUpdate( # same as basis
2857
active=[('', 'root-id'),
2858
('file', 'file-id')],
2859
basis= [('', 'root-id'),
2860
('file', 'file-id')],
2861
target=[('', 'target-root-id'),
2862
('file', 'file-id')])
2863
state = self.assertUpdate( # same as target
2864
active=[('', 'target-root-id'),
2865
('file', 'file-id')],
2866
basis= [('', 'root-id'),
2867
('file', 'file-id')],
2868
target=[('', 'target-root-id'),
2869
('file', 'root-id')])
2870
state = self.assertUpdate( # all different
2871
active=[('', 'active-root-id'),
2872
('file', 'file-id')],
2873
basis= [('', 'root-id'),
2874
('file', 'file-id')],
2875
target=[('', 'target-root-id'),
2876
('file', 'root-id')])
2906
2878
def test_change_file_absent_in_active(self):
2907
2879
state = self.assertUpdate(
2909
basis=[('file', b'file-id')],
2910
target=[('file', b'file-id')])
2881
basis= [('file', 'file-id')],
2882
target=[('file', 'file-id')])
2912
2884
def test_invalid_changed_file(self):
2913
state = self.assertBadDelta( # Not present in basis
2914
active=[('file', b'file-id')],
2916
delta=[('file', 'file', b'file-id')])
2917
state = self.assertBadDelta( # present at another location in basis
2918
active=[('file', b'file-id')],
2919
basis=[('other-file', b'file-id')],
2920
delta=[('file', 'file', b'file-id')])
2885
state = self.assertBadDelta( # Not present in basis
2886
active=[('file', 'file-id')],
2888
delta=[('file', 'file', 'file-id')])
2889
state = self.assertBadDelta( # present at another location in basis
2890
active=[('file', 'file-id')],
2891
basis= [('other-file', 'file-id')],
2892
delta=[('file', 'file', 'file-id')])