138
128
: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),
130
packed_stat = 'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
131
null_sha = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
132
root_entry = ('', '', 'a-root-value'), [
133
('d', '', 0, False, packed_stat),
135
a_entry = ('', 'a', 'a-dir'), [
136
('d', '', 0, False, packed_stat),
138
b_entry = ('', 'b', 'b-dir'), [
139
('d', '', 0, False, packed_stat),
141
c_entry = ('', 'c', 'c-file'), [
142
('f', null_sha, 10, False, packed_stat),
144
d_entry = ('', 'd', 'd-file'), [
145
('f', null_sha, 20, False, packed_stat),
147
e_entry = ('a', 'e', 'e-dir'), [
148
('d', '', 0, False, packed_stat),
150
f_entry = ('a', 'f', 'f-file'), [
151
('f', null_sha, 30, False, packed_stat),
153
g_entry = ('b', 'g', 'g-file'), [
154
('f', null_sha, 30, False, packed_stat),
156
h_entry = ('b', 'h\xc3\xa5', 'h-\xc3\xa5-file'), [
157
('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]))
160
dirblocks.append(('', [root_entry]))
161
dirblocks.append(('', [a_entry, b_entry, c_entry, d_entry]))
162
dirblocks.append(('a', [e_entry, f_entry]))
163
dirblocks.append(('b', [g_entry, h_entry]))
174
164
state = dirstate.DirState.initialize('dirstate')
175
165
state._validate()
256
245
f_len = len(f_text)
257
246
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),
248
'':(('', '', 'TREE_ROOT'), [
249
('d', '', 0, False, null_stat),
250
('d', '', 0, False, revision_id),
252
'a':(('', 'a', 'a-id'), [
253
('f', '', 0, False, null_stat),
254
('f', a_sha, a_len, False, revision_id),
256
'b':(('', 'b', 'b-id'), [
257
('d', '', 0, False, null_stat),
258
('d', '', 0, False, revision_id),
260
'b/c':(('b', 'c', 'c-id'), [
261
('f', '', 0, False, null_stat),
262
('f', c_sha, c_len, False, revision_id),
264
'b/d':(('b', 'd', 'd-id'), [
265
('d', '', 0, False, null_stat),
266
('d', '', 0, False, revision_id),
268
'b/d/e':(('b/d', 'e', 'e-id'), [
269
('f', '', 0, False, null_stat),
270
('f', e_sha, e_len, False, revision_id),
272
'b-c':(('', 'b-c', 'b-c-id'), [
273
('f', '', 0, False, null_stat),
274
('f', b_c_sha, b_c_len, False, revision_id),
276
'f':(('', 'f', 'f-id'), [
277
('f', '', 0, False, null_stat),
278
('f', f_sha, f_len, False, revision_id),
292
281
state = dirstate.DirState.from_tree(tree, 'dirstate')
971
962
"""Set the root file id in a dirstate with parents"""
972
963
mt = self.make_branch_and_tree('mt')
973
964
# 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')
965
mt.set_root_id('TREE_ROOT')
966
mt.commit('foo', rev_id='parent-revid')
967
rt = mt.branch.repository.revision_tree('parent-revid')
977
968
state = dirstate.DirState.initialize('dirstate')
978
969
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''))
971
state.set_parent_trees([('parent-revid', rt)], ghosts=[])
972
root_entry = (('', '', 'TREE_ROOT'),
973
[('d', '', 0, False, 'x'*32),
974
('d', '', 0, False, 'parent-revid')])
975
self.assertEqual(root_entry, state._get_entry(0, path_utf8=''))
985
976
self.assertEqual(root_entry,
986
state._get_entry(0, fileid_utf8=b'TREE_ROOT'))
977
state._get_entry(0, fileid_utf8='TREE_ROOT'))
987
978
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')
979
state._get_entry(0, fileid_utf8='Asecond-root-id'))
980
state.set_path_id('', 'Asecond-root-id')
990
981
state._validate()
991
982
# 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'')])
983
old_root_entry = (('', '', 'TREE_ROOT'),
984
[('a', '', 0, False, ''),
985
('d', '', 0, False, 'parent-revid')])
986
new_root_entry = (('', '', 'Asecond-root-id'),
987
[('d', '', 0, False, ''),
988
('a', '', 0, False, '')])
998
989
expected_rows = [new_root_entry, old_root_entry]
999
990
state._validate()
1000
991
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''))
992
self.assertEqual(new_root_entry, state._get_entry(0, path_utf8=''))
993
self.assertEqual(old_root_entry, state._get_entry(1, path_utf8=''))
1005
994
self.assertEqual((None, None),
1006
state._get_entry(0, fileid_utf8=b'TREE_ROOT'))
995
state._get_entry(0, fileid_utf8='TREE_ROOT'))
1007
996
self.assertEqual(old_root_entry,
1008
state._get_entry(1, fileid_utf8=b'TREE_ROOT'))
997
state._get_entry(1, fileid_utf8='TREE_ROOT'))
1009
998
self.assertEqual(new_root_entry,
1010
state._get_entry(0, fileid_utf8=b'Asecond-root-id'))
999
state._get_entry(0, fileid_utf8='Asecond-root-id'))
1011
1000
self.assertEqual((None, None),
1012
state._get_entry(1, fileid_utf8=b'Asecond-root-id'))
1001
state._get_entry(1, fileid_utf8='Asecond-root-id'))
1013
1002
# should work across save too
1529
1518
def test_simple_structure(self):
1530
1519
state = self.create_dirstate_with_root_and_subdir()
1531
1520
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)
1521
self.assertBlockRowIndexEqual(1, 0, True, True, state, '', 'subdir', 0)
1522
self.assertBlockRowIndexEqual(1, 0, True, False, state, '', 'bdir', 0)
1523
self.assertBlockRowIndexEqual(1, 1, True, False, state, '', 'zdir', 0)
1524
self.assertBlockRowIndexEqual(2, 0, False, False, state, 'a', 'foo', 0)
1540
1525
self.assertBlockRowIndexEqual(2, 0, False, False, state,
1541
b'subdir', b'foo', 0)
1543
1528
def test_complex_structure_exists(self):
1544
1529
state = self.create_complex_dirstate()
1545
1530
self.addCleanup(state.unlock)
1546
1531
# 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)
1532
self.assertBlockRowIndexEqual(0, 0, True, True, state, '', '', 0)
1533
self.assertBlockRowIndexEqual(1, 0, True, True, state, '', 'a', 0)
1534
self.assertBlockRowIndexEqual(1, 1, True, True, state, '', 'b', 0)
1535
self.assertBlockRowIndexEqual(1, 2, True, True, state, '', 'c', 0)
1536
self.assertBlockRowIndexEqual(1, 3, True, True, state, '', 'd', 0)
1537
self.assertBlockRowIndexEqual(2, 0, True, True, state, 'a', 'e', 0)
1538
self.assertBlockRowIndexEqual(2, 1, True, True, state, 'a', 'f', 0)
1539
self.assertBlockRowIndexEqual(3, 0, True, True, state, 'b', 'g', 0)
1555
1540
self.assertBlockRowIndexEqual(3, 1, True, True, state,
1556
b'b', b'h\xc3\xa5', 0)
1541
'b', 'h\xc3\xa5', 0)
1558
1543
def test_complex_structure_missing(self):
1559
1544
state = self.create_complex_dirstate()
1560
1545
self.addCleanup(state.unlock)
1561
1546
# Make sure things would be inserted in the right locations
1562
1547
# '_' 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)
1548
self.assertBlockRowIndexEqual(0, 0, True, True, state, '', '', 0)
1549
self.assertBlockRowIndexEqual(1, 0, True, False, state, '', '_', 0)
1550
self.assertBlockRowIndexEqual(1, 1, True, False, state, '', 'aa', 0)
1566
1551
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)
1553
self.assertBlockRowIndexEqual(2, 0, False, False, state, '_', 'a', 0)
1554
self.assertBlockRowIndexEqual(3, 0, False, False, state, 'aa', 'a', 0)
1555
self.assertBlockRowIndexEqual(4, 0, False, False, state, 'bb', 'a', 0)
1573
1556
# This would be inserted between a/ and b/
1574
self.assertBlockRowIndexEqual(
1575
3, 0, False, False, state, b'a/e', b'a', 0)
1557
self.assertBlockRowIndexEqual(3, 0, False, False, state, 'a/e', 'a', 0)
1576
1558
# Put at the end
1577
self.assertBlockRowIndexEqual(4, 0, False, False, state, b'e', b'a', 0)
1559
self.assertBlockRowIndexEqual(4, 0, False, False, state, 'e', 'a', 0)
1580
1562
class TestGetEntry(TestCaseWithDirState):
1591
1573
def test_simple_structure(self):
1592
1574
state = self.create_dirstate_with_root_and_subdir()
1593
1575
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)
1576
self.assertEntryEqual('', '', 'a-root-value', state, '', 0)
1577
self.assertEntryEqual('', 'subdir', 'subdir-id', state, 'subdir', 0)
1578
self.assertEntryEqual(None, None, None, state, 'missing', 0)
1579
self.assertEntryEqual(None, None, None, state, 'missing/foo', 0)
1580
self.assertEntryEqual(None, None, None, state, 'subdir/foo', 0)
1601
1582
def test_complex_structure_exists(self):
1602
1583
state = self.create_complex_dirstate()
1603
1584
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,
1585
self.assertEntryEqual('', '', 'a-root-value', state, '', 0)
1586
self.assertEntryEqual('', 'a', 'a-dir', state, 'a', 0)
1587
self.assertEntryEqual('', 'b', 'b-dir', state, 'b', 0)
1588
self.assertEntryEqual('', 'c', 'c-file', state, 'c', 0)
1589
self.assertEntryEqual('', 'd', 'd-file', state, 'd', 0)
1590
self.assertEntryEqual('a', 'e', 'e-dir', state, 'a/e', 0)
1591
self.assertEntryEqual('a', 'f', 'f-file', state, 'a/f', 0)
1592
self.assertEntryEqual('b', 'g', 'g-file', state, 'b/g', 0)
1593
self.assertEntryEqual('b', 'h\xc3\xa5', 'h-\xc3\xa5-file', state,
1615
1596
def test_complex_structure_missing(self):
1616
1597
state = self.create_complex_dirstate()
1617
1598
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)
1599
self.assertEntryEqual(None, None, None, state, '_', 0)
1600
self.assertEntryEqual(None, None, None, state, '_\xc3\xa5', 0)
1601
self.assertEntryEqual(None, None, None, state, 'a/b', 0)
1602
self.assertEntryEqual(None, None, None, state, 'c/d', 0)
1623
1604
def test_get_entry_uninitialized(self):
1624
1605
"""Calling get_entry will load data if it needs to"""
1666
1647
:return: The dirstate, still write-locked.
1668
packed_stat = b'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
1669
null_sha = b'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
1649
packed_stat = 'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
1650
null_sha = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
1670
1651
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'),
1652
root_entry = ('', '', 'a-root-value'), [
1653
('d', '', 0, False, packed_stat),
1654
('d', '', 0, False, 'parent-revid'),
1656
a_entry = ('', 'a', 'a-dir'), [
1657
('d', '', 0, False, packed_stat),
1658
('d', '', 0, False, 'parent-revid'),
1660
b_entry = ('', 'b', 'b-dir'), [
1661
('d', '', 0, False, packed_stat),
1662
('d', '', 0, False, 'parent-revid'),
1664
c_entry = ('', 'c', 'c-file'), [
1665
('f', null_sha, 10, False, packed_stat),
1666
('r', 'b/j', 0, False, ''),
1668
d_entry = ('', 'd', 'd-file'), [
1669
('f', null_sha, 20, False, packed_stat),
1670
('f', 'd', 20, False, 'parent-revid'),
1672
e_entry = ('a', 'e', 'e-dir'), [
1673
('d', '', 0, False, packed_stat),
1674
('d', '', 0, False, 'parent-revid'),
1676
f_entry = ('a', 'f', 'f-file'), [
1677
('f', null_sha, 30, False, packed_stat),
1678
('f', 'f', 20, False, 'parent-revid'),
1680
g_entry = ('b', 'g', 'g-file'), [
1681
('f', null_sha, 30, False, packed_stat),
1682
NULL_PARENT_DETAILS,
1684
h_entry1 = ('b', 'h\xc3\xa5', 'h-\xc3\xa5-file1'), [
1685
('f', null_sha, 40, False, packed_stat),
1686
NULL_PARENT_DETAILS,
1688
h_entry2 = ('b', 'h\xc3\xa5', 'h-\xc3\xa5-file2'), [
1689
NULL_PARENT_DETAILS,
1690
('f', 'h', 20, False, 'parent-revid'),
1692
i_entry = ('b', 'i', 'i-file'), [
1693
NULL_PARENT_DETAILS,
1694
('f', 'h', 20, False, 'parent-revid'),
1696
j_entry = ('b', 'j', 'c-file'), [
1697
('r', 'c', 0, False, ''),
1698
('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]))
1701
dirblocks.append(('', [root_entry]))
1702
dirblocks.append(('', [a_entry, b_entry, c_entry, d_entry]))
1703
dirblocks.append(('a', [e_entry, f_entry]))
1704
dirblocks.append(('b', [g_entry, h_entry1, h_entry2, i_entry, j_entry]))
1725
1705
state = dirstate.DirState.initialize('dirstate')
1726
1706
state._validate()
1728
state._set_data([b'parent'], dirblocks)
1708
state._set_data(['parent'], dirblocks)
2016
1993
tree, state, expected = self.create_basic_dirstate()
2018
1995
# 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'])
1996
self.assertBisect(expected, [['']], state, [''])
1997
self.assertBisect(expected, [['a']], state, ['a'])
1998
self.assertBisect(expected, [['b']], state, ['b'])
1999
self.assertBisect(expected, [['b/c']], state, ['b/c'])
2000
self.assertBisect(expected, [['b/d']], state, ['b/d'])
2001
self.assertBisect(expected, [['b/d/e']], state, ['b/d/e'])
2002
self.assertBisect(expected, [['b-c']], state, ['b-c'])
2003
self.assertBisect(expected, [['f']], state, ['f'])
2028
2005
def test_bisect_multi(self):
2029
2006
"""Bisect can be used to find multiple records at the same time."""
2030
2007
tree, state, expected = self.create_basic_dirstate()
2031
2008
# 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'])
2009
self.assertBisect(expected, [['a'], ['b'], ['f']],
2010
state, ['a', 'b', 'f'])
2011
self.assertBisect(expected, [['f'], ['b/d'], ['b/d/e']],
2012
state, ['f', 'b/d', 'b/d/e'])
2013
self.assertBisect(expected, [['b'], ['b-c'], ['b/c']],
2014
state, ['b', 'b-c', 'b/c'])
2039
2016
def test_bisect_one_page(self):
2040
2017
"""Test bisect when there is only 1 page to read"""
2041
2018
tree, state, expected = self.create_basic_dirstate()
2042
2019
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'])
2020
self.assertBisect(expected,[['']], state, [''])
2021
self.assertBisect(expected,[['a']], state, ['a'])
2022
self.assertBisect(expected,[['b']], state, ['b'])
2023
self.assertBisect(expected,[['b/c']], state, ['b/c'])
2024
self.assertBisect(expected,[['b/d']], state, ['b/d'])
2025
self.assertBisect(expected,[['b/d/e']], state, ['b/d/e'])
2026
self.assertBisect(expected,[['b-c']], state, ['b-c'])
2027
self.assertBisect(expected,[['f']], state, ['f'])
2028
self.assertBisect(expected,[['a'], ['b'], ['f']],
2029
state, ['a', 'b', 'f'])
2030
self.assertBisect(expected, [['b/d'], ['b/d/e'], ['f']],
2031
state, ['b/d', 'b/d/e', 'f'])
2032
self.assertBisect(expected, [['b'], ['b/c'], ['b-c']],
2033
state, ['b', 'b/c', 'b-c'])
2058
2035
def test_bisect_duplicate_paths(self):
2059
2036
"""When bisecting for a path, handle multiple entries."""
2060
2037
tree, state, expected = self.create_duplicated_dirstate()
2062
2039
# 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'])
2040
self.assertBisect(expected, [['']], state, [''])
2041
self.assertBisect(expected, [['a', 'a2']], state, ['a'])
2042
self.assertBisect(expected, [['b', 'b2']], state, ['b'])
2043
self.assertBisect(expected, [['b/c', 'b/c2']], state, ['b/c'])
2044
self.assertBisect(expected, [['b/d', 'b/d2']], state, ['b/d'])
2045
self.assertBisect(expected, [['b/d/e', 'b/d/e2']],
2047
self.assertBisect(expected, [['b-c', 'b-c2']], state, ['b-c'])
2048
self.assertBisect(expected, [['f', 'f2']], state, ['f'])
2073
2050
def test_bisect_page_size_too_small(self):
2074
2051
"""If the page size is too small, we will auto increase it."""
2075
2052
tree, state, expected = self.create_basic_dirstate()
2076
2053
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'])
2054
self.assertBisect(expected, [None], state, ['b/e'])
2055
self.assertBisect(expected, [['a']], state, ['a'])
2056
self.assertBisect(expected, [['b']], state, ['b'])
2057
self.assertBisect(expected, [['b/c']], state, ['b/c'])
2058
self.assertBisect(expected, [['b/d']], state, ['b/d'])
2059
self.assertBisect(expected, [['b/d/e']], state, ['b/d/e'])
2060
self.assertBisect(expected, [['b-c']], state, ['b-c'])
2061
self.assertBisect(expected, [['f']], state, ['f'])
2086
2063
def test_bisect_missing(self):
2087
2064
"""Test that bisect return None if it cannot find a path."""
2088
2065
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'])
2066
self.assertBisect(expected, [None], state, ['foo'])
2067
self.assertBisect(expected, [None], state, ['b/foo'])
2068
self.assertBisect(expected, [None], state, ['bar/foo'])
2069
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'])
2071
self.assertBisect(expected, [['a'], None, ['b/d']],
2072
state, ['a', 'foo', 'b/d'])
2097
2074
def test_bisect_rename(self):
2098
2075
"""Check that we find a renamed row."""
2099
2076
tree, state, expected = self.create_renamed_dirstate()
2101
2078
# 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'])
2079
self.assertBisect(expected, [['a']], state, ['a'])
2080
self.assertBisect(expected, [['b/g']], state, ['b/g'])
2081
self.assertBisect(expected, [['b/d']], state, ['b/d'])
2082
self.assertBisect(expected, [['h']], state, ['h'])
2107
2084
# 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'])
2085
self.assertBisect(expected, [['b/d/e']], state, ['b/d/e'])
2086
self.assertBisect(expected, [['h/e']], state, ['h/e'])
2111
2088
def test_bisect_dirblocks(self):
2112
2089
tree, state, expected = self.create_duplicated_dirstate()
2113
2090
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'])
2091
[['', 'a', 'a2', 'b', 'b2', 'b-c', 'b-c2', 'f', 'f2']],
2093
self.assertBisectDirBlocks(expected,
2094
[['b/c', 'b/c2', 'b/d', 'b/d2']], state, ['b'])
2095
self.assertBisectDirBlocks(expected,
2096
[['b/d/e', 'b/d/e2']], state, ['b/d'])
2097
self.assertBisectDirBlocks(expected,
2098
[['', 'a', 'a2', 'b', 'b2', 'b-c', 'b-c2', 'f', 'f2'],
2099
['b/c', 'b/c2', 'b/d', 'b/d2'],
2100
['b/d/e', 'b/d/e2'],
2101
], state, ['', 'b', 'b/d'])
2127
2103
def test_bisect_dirblocks_missing(self):
2128
2104
tree, state, expected = self.create_basic_dirstate()
2129
self.assertBisectDirBlocks(expected, [[b'b/d/e'], None],
2130
state, [b'b/d', b'b/e'])
2105
self.assertBisectDirBlocks(expected, [['b/d/e'], None],
2106
state, ['b/d', 'b/e'])
2131
2107
# 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'])
2108
self.assertBisectDirBlocks(expected, [None], state, ['a'])
2109
self.assertBisectDirBlocks(expected, [None], state, ['b/c'])
2110
self.assertBisectDirBlocks(expected, [None], state, ['c'])
2111
self.assertBisectDirBlocks(expected, [None], state, ['b/d/e'])
2112
self.assertBisectDirBlocks(expected, [None], state, ['f'])
2138
2114
def test_bisect_recursive_each(self):
2139
2115
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',
2116
self.assertBisectRecursive(expected, ['a'], state, ['a'])
2117
self.assertBisectRecursive(expected, ['b/c'], state, ['b/c'])
2118
self.assertBisectRecursive(expected, ['b/d/e'], state, ['b/d/e'])
2119
self.assertBisectRecursive(expected, ['b-c'], state, ['b-c'])
2120
self.assertBisectRecursive(expected, ['b/d', 'b/d/e'],
2122
self.assertBisectRecursive(expected, ['b', 'b/c', 'b/d', 'b/d/e'],
2124
self.assertBisectRecursive(expected, ['', 'a', 'b', 'b-c', 'f', 'b/c',
2152
2128
def test_bisect_recursive_multiple(self):
2153
2129
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'])
2130
self.assertBisectRecursive(expected, ['a', 'b/c'], state, ['a', 'b/c'])
2131
self.assertBisectRecursive(expected, ['b/d', 'b/d/e'],
2132
state, ['b/d', 'b/d/e'])
2159
2134
def test_bisect_recursive_missing(self):
2160
2135
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'])
2136
self.assertBisectRecursive(expected, [], state, ['d'])
2137
self.assertBisectRecursive(expected, [], state, ['b/e'])
2138
self.assertBisectRecursive(expected, [], state, ['g'])
2139
self.assertBisectRecursive(expected, ['a'], state, ['a', 'g'])
2166
2141
def test_bisect_recursive_renamed(self):
2167
2142
tree, state, expected = self.create_renamed_dirstate()
2169
2144
# 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'])
2145
self.assertBisectRecursive(expected, ['a', 'b/g'], state, ['a'])
2146
self.assertBisectRecursive(expected, ['a', 'b/g'], state, ['b/g'])
2172
2147
# Looking in the containing directory should find the rename target,
2173
2148
# 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'],
2149
self.assertBisectRecursive(expected, ['a', 'b', 'b/c', 'b/d',
2150
'b/d/e', 'b/g', 'h', 'h/e'],
2179
2154
class TestDirstateValidation(TestCaseWithDirState):
2285
2260
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),
2262
packed_stat = 'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
2263
root_entry_direntry = ('', '', 'a-root-value'), [
2264
('d', '', 0, False, packed_stat),
2265
('d', '', 0, False, packed_stat),
2266
('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),
2268
expected_root_entry_direntry = ('', '', 'a-root-value'), [
2269
('d', '', 0, False, packed_stat),
2270
('d', '', 0, False, packed_stat),
2298
dirblocks.append((b'', [root_entry_direntry]))
2299
dirblocks.append((b'', []))
2273
dirblocks.append(('', [root_entry_direntry]))
2274
dirblocks.append(('', []))
2301
2276
state = self.create_empty_dirstate()
2302
2277
self.addCleanup(state.unlock)
2303
state._set_data([b'parent-id', b'merged-id'], dirblocks[:])
2278
state._set_data(['parent-id', 'merged-id'], dirblocks[:])
2304
2279
state._validate()
2306
2281
# This should strip of the extra column
2307
2282
state._discard_merge_parents()
2308
2283
state._validate()
2309
expected_dirblocks = [(b'', [expected_root_entry_direntry]), (b'', [])]
2284
expected_dirblocks = [('', [expected_root_entry_direntry]), ('', [])]
2310
2285
self.assertEqual(expected_dirblocks, state._dirblocks)
2312
2287
def test_discard_absent(self):
2313
2288
"""If entries are only in a merge, discard should remove the entries"""
2314
2289
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)
2290
present_dir = ('d', '', 0, False, null_stat)
2291
present_file = ('f', '', 0, False, null_stat)
2317
2292
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]),
2293
root_key = ('', '', 'a-root-value')
2294
file_in_root_key = ('', 'file-in-root', 'a-file-id')
2295
file_in_merged_key = ('', 'file-in-merged', 'b-file-id')
2296
dirblocks = [('', [(root_key, [present_dir, present_dir, present_dir])]),
2297
('', [(file_in_merged_key,
2298
[absent, absent, present_file]),
2300
[present_file, present_file, present_file]),
2329
2304
state = self.create_empty_dirstate()
2330
2305
self.addCleanup(state.unlock)
2331
state._set_data([b'parent-id', b'merged-id'], dirblocks[:])
2306
state._set_data(['parent-id', 'merged-id'], dirblocks[:])
2332
2307
state._validate()
2334
exp_dirblocks = [(b'', [(root_key, [present_dir, present_dir])]),
2335
(b'', [(file_in_root_key,
2336
[present_file, present_file]),
2309
exp_dirblocks = [('', [(root_key, [present_dir, present_dir])]),
2310
('', [(file_in_root_key,
2311
[present_file, present_file]),
2339
2314
state._discard_merge_parents()
2340
2315
state._validate()
2341
2316
self.assertEqual(exp_dirblocks, state._dirblocks)
2343
2318
def test_discard_renamed(self):
2344
2319
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)
2320
present_dir = ('d', '', 0, False, null_stat)
2321
present_file = ('f', '', 0, False, null_stat)
2347
2322
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')
2323
root_key = ('', '', 'a-root-value')
2324
file_in_root_key = ('', 'file-in-root', 'a-file-id')
2350
2325
# 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')
2326
file_rename_s_key = ('', 'file-s', 'b-file-id')
2327
file_rename_t_key = ('', 'file-t', 'b-file-id')
2353
2328
# 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')
2329
key_in_1 = ('', 'file-in-1', 'c-file-id')
2330
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')]),
2333
('', [(root_key, [present_dir, present_dir, present_dir])]),
2335
[absent, present_file, ('r', 'file-in-2', 'c-file-id')]),
2337
[absent, ('r', 'file-in-1', 'c-file-id'), present_file]),
2339
[present_file, present_file, present_file]),
2341
[('r', 'file-t', 'b-file-id'), absent, present_file]),
2343
[present_file, absent, ('r', 'file-s', 'b-file-id')]),
2371
2346
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]),
2347
('', [(root_key, [present_dir, present_dir])]),
2348
('', [(key_in_1, [absent, present_file]),
2349
(file_in_root_key, [present_file, present_file]),
2350
(file_rename_t_key, [present_file, absent]),
2378
2353
state = self.create_empty_dirstate()
2379
2354
self.addCleanup(state.unlock)
2380
state._set_data([b'parent-id', b'merged-id'], dirblocks[:])
2355
state._set_data(['parent-id', 'merged-id'], dirblocks[:])
2381
2356
state._validate()
2383
2358
state._discard_merge_parents()
2584
2559
:param basis: The basis tree shape
2585
2560
:param delta: A description of the delta to apply. Similar to the form
2586
2561
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')
2562
So adding a file is: (None, 'path', 'file-id')
2563
Adding a directory is: (None, 'path/', 'dir-id')
2564
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')
2567
active_tree = self.create_tree_from_shape('active', active)
2568
basis_tree = self.create_tree_from_shape('basis', basis)
2569
inv_delta = self.create_inv_delta(delta, 'target')
2595
2570
state = self.create_empty_dirstate()
2596
2571
state.set_state_from_scratch(active_tree.root_inventory,
2597
[(b'basis', basis_tree)], [])
2572
[('basis', basis_tree)], [])
2598
2573
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:
2574
state.update_basis_by_delta, inv_delta, 'target')
2576
## state.update_basis_by_delta(inv_delta, 'target')
2577
## except errors.InconsistentDelta, e:
2603
2578
## import pdb; pdb.set_trace()
2605
2580
## import pdb; pdb.set_trace()
2606
2581
self.assertTrue(state._changes_aborted)
2608
2583
def test_remove_file_matching_active_state(self):
2609
2584
state = self.assertUpdate(
2611
basis=[('file', b'file-id')],
2586
basis =[('file', 'file-id')],
2615
2590
def test_remove_file_present_in_active_state(self):
2616
2591
state = self.assertUpdate(
2617
active=[('file', b'file-id')],
2618
basis=[('file', b'file-id')],
2592
active=[('file', 'file-id')],
2593
basis =[('file', 'file-id')],
2622
2597
def test_remove_file_present_elsewhere_in_active_state(self):
2623
2598
state = self.assertUpdate(
2624
active=[('other-file', b'file-id')],
2625
basis=[('file', b'file-id')],
2599
active=[('other-file', 'file-id')],
2600
basis =[('file', 'file-id')],
2629
2604
def test_remove_file_active_state_has_diff_file(self):
2630
2605
state = self.assertUpdate(
2631
active=[('file', b'file-id-2')],
2632
basis=[('file', b'file-id')],
2606
active=[('file', 'file-id-2')],
2607
basis =[('file', 'file-id')],
2636
2611
def test_remove_file_active_state_has_diff_file_and_file_elsewhere(self):
2637
2612
state = self.assertUpdate(
2638
active=[('file', b'file-id-2'),
2639
('other-file', b'file-id')],
2640
basis=[('file', b'file-id')],
2613
active=[('file', 'file-id-2'),
2614
('other-file', 'file-id')],
2615
basis =[('file', 'file-id')],
2644
2619
def test_add_file_matching_active_state(self):
2645
2620
state = self.assertUpdate(
2646
active=[('file', b'file-id')],
2648
target=[('file', b'file-id')],
2621
active=[('file', 'file-id')],
2623
target=[('file', 'file-id')],
2651
2626
def test_add_file_in_empty_dir_not_matching_active_state(self):
2652
2627
state = self.assertUpdate(
2654
basis=[('dir/', b'dir-id')],
2655
target=[('dir/', b'dir-id', b'basis'), ('dir/file', b'file-id')],
2629
basis=[('dir/', 'dir-id')],
2630
target=[('dir/', 'dir-id', 'basis'), ('dir/file', 'file-id')],
2658
2633
def test_add_file_missing_in_active_state(self):
2659
2634
state = self.assertUpdate(
2662
target=[('file', b'file-id')],
2637
target=[('file', 'file-id')],
2665
2640
def test_add_file_elsewhere_in_active_state(self):
2666
2641
state = self.assertUpdate(
2667
active=[('other-file', b'file-id')],
2669
target=[('file', b'file-id')],
2642
active=[('other-file', 'file-id')],
2644
target=[('file', 'file-id')],
2672
2647
def test_add_file_active_state_has_diff_file_and_file_elsewhere(self):
2673
2648
state = self.assertUpdate(
2674
active=[('other-file', b'file-id'),
2675
('file', b'file-id-2')],
2677
target=[('file', b'file-id')],
2649
active=[('other-file', 'file-id'),
2650
('file', 'file-id-2')],
2652
target=[('file', 'file-id')],
2680
2655
def test_rename_file_matching_active_state(self):
2681
2656
state = self.assertUpdate(
2682
active=[('other-file', b'file-id')],
2683
basis=[('file', b'file-id')],
2684
target=[('other-file', b'file-id')],
2657
active=[('other-file', 'file-id')],
2658
basis =[('file', 'file-id')],
2659
target=[('other-file', 'file-id')],
2687
2662
def test_rename_file_missing_in_active_state(self):
2688
2663
state = self.assertUpdate(
2690
basis=[('file', b'file-id')],
2691
target=[('other-file', b'file-id')],
2665
basis =[('file', 'file-id')],
2666
target=[('other-file', 'file-id')],
2694
2669
def test_rename_file_present_elsewhere_in_active_state(self):
2695
2670
state = self.assertUpdate(
2696
active=[('third', b'file-id')],
2697
basis=[('file', b'file-id')],
2698
target=[('other-file', b'file-id')],
2671
active=[('third', 'file-id')],
2672
basis =[('file', 'file-id')],
2673
target=[('other-file', 'file-id')],
2701
2676
def test_rename_file_active_state_has_diff_source_file(self):
2702
2677
state = self.assertUpdate(
2703
active=[('file', b'file-id-2')],
2704
basis=[('file', b'file-id')],
2705
target=[('other-file', b'file-id')],
2678
active=[('file', 'file-id-2')],
2679
basis =[('file', 'file-id')],
2680
target=[('other-file', 'file-id')],
2708
2683
def test_rename_file_active_state_has_diff_target_file(self):
2709
2684
state = self.assertUpdate(
2710
active=[('other-file', b'file-id-2')],
2711
basis=[('file', b'file-id')],
2712
target=[('other-file', b'file-id')],
2685
active=[('other-file', 'file-id-2')],
2686
basis =[('file', 'file-id')],
2687
target=[('other-file', 'file-id')],
2715
2690
def test_rename_file_active_has_swapped_files(self):
2716
2691
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')])
2692
active=[('file', 'file-id'),
2693
('other-file', 'file-id-2')],
2694
basis= [('file', 'file-id'),
2695
('other-file', 'file-id-2')],
2696
target=[('file', 'file-id-2'),
2697
('other-file', 'file-id')])
2724
2699
def test_rename_file_basis_has_swapped_files(self):
2725
2700
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')])
2701
active=[('file', 'file-id'),
2702
('other-file', 'file-id-2')],
2703
basis= [('file', 'file-id-2'),
2704
('other-file', 'file-id')],
2705
target=[('file', 'file-id'),
2706
('other-file', 'file-id-2')])
2733
2708
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
2709
state = self.assertUpdate( # active matches basis
2710
active=[('dir1/', 'dir-id'),
2711
('dir1/file', 'file-id')],
2712
basis= [('dir1/', 'dir-id'),
2713
('dir1/file', 'file-id')],
2714
target=[('dir2/', 'dir-id'),
2715
('dir2/file', 'file-id')])
2716
state = self.assertUpdate( # active matches target
2717
active=[('dir2/', 'dir-id'),
2718
('dir2/file', 'file-id')],
2719
basis= [('dir1/', 'dir-id'),
2720
('dir1/file', 'file-id')],
2721
target=[('dir2/', 'dir-id'),
2722
('dir2/file', 'file-id')])
2723
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')])
2725
basis= [('dir1/', 'dir-id'),
2726
('dir1/file', 'file-id')],
2727
target=[('dir2/', 'dir-id'),
2728
('dir2/file', 'file-id')])
2729
state = self.assertUpdate( # active present at other location
2730
active=[('dir3/', 'dir-id'),
2731
('dir3/file', 'file-id')],
2732
basis= [('dir1/', 'dir-id'),
2733
('dir1/file', 'file-id')],
2734
target=[('dir2/', 'dir-id'),
2735
('dir2/file', 'file-id')])
2736
state = self.assertUpdate( # active has different ids
2737
active=[('dir1/', 'dir1-id'),
2738
('dir1/file', 'file1-id'),
2739
('dir2/', 'dir2-id'),
2740
('dir2/file', 'file2-id')],
2741
basis= [('dir1/', 'dir-id'),
2742
('dir1/file', 'file-id')],
2743
target=[('dir2/', 'dir-id'),
2744
('dir2/file', 'file-id')])
2771
2746
def test_invalid_file_not_present(self):
2772
2747
state = self.assertBadDelta(
2773
active=[('file', b'file-id')],
2774
basis=[('file', b'file-id')],
2775
delta=[('other-file', 'file', b'file-id')])
2748
active=[('file', 'file-id')],
2749
basis= [('file', 'file-id')],
2750
delta=[('other-file', 'file', 'file-id')])
2777
2752
def test_invalid_new_id_same_path(self):
2778
2753
# The bad entry comes after
2779
2754
state = self.assertBadDelta(
2780
active=[('file', b'file-id')],
2781
basis=[('file', b'file-id')],
2782
delta=[(None, 'file', b'file-id-2')])
2755
active=[('file', 'file-id')],
2756
basis= [('file', 'file-id')],
2757
delta=[(None, 'file', 'file-id-2')])
2783
2758
# The bad entry comes first
2784
2759
state = self.assertBadDelta(
2785
active=[('file', b'file-id-2')],
2786
basis=[('file', b'file-id-2')],
2787
delta=[(None, 'file', b'file-id')])
2760
active=[('file', 'file-id-2')],
2761
basis=[('file', 'file-id-2')],
2762
delta=[(None, 'file', 'file-id')])
2789
2764
def test_invalid_existing_id(self):
2790
2765
state = self.assertBadDelta(
2791
active=[('file', b'file-id')],
2792
basis=[('file', b'file-id')],
2793
delta=[(None, 'file', b'file-id')])
2766
active=[('file', 'file-id')],
2767
basis= [('file', 'file-id')],
2768
delta=[(None, 'file', 'file-id')])
2795
2770
def test_invalid_parent_missing(self):
2796
2771
state = self.assertBadDelta(
2799
delta=[(None, 'path/path2', b'file-id')])
2774
delta=[(None, 'path/path2', 'file-id')])
2800
2775
# Note: we force the active tree to have the directory, by knowing how
2801
2776
# path_to_ie handles entries with missing parents
2802
2777
state = self.assertBadDelta(
2803
active=[('path/', b'path-id')],
2805
delta=[(None, 'path/path2', b'file-id')])
2778
active=[('path/', 'path-id')],
2780
delta=[(None, 'path/path2', 'file-id')])
2806
2781
state = self.assertBadDelta(
2807
active=[('path/', b'path-id'),
2808
('path/path2', b'file-id')],
2810
delta=[(None, 'path/path2', b'file-id')])
2782
active=[('path/', 'path-id'),
2783
('path/path2', 'file-id')],
2785
delta=[(None, 'path/path2', 'file-id')])
2812
2787
def test_renamed_dir_same_path(self):
2813
2788
# We replace the parent directory, with another parent dir. But the C
2814
2789
# 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
2790
state = self.assertUpdate(# Same as basis
2791
active=[('dir/', 'A-id'),
2793
basis= [('dir/', 'A-id'),
2795
target=[('dir/', 'C-id'),
2797
state = self.assertUpdate(# Same as target
2798
active=[('dir/', 'C-id'),
2800
basis= [('dir/', 'A-id'),
2802
target=[('dir/', 'C-id'),
2804
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')])
2806
basis= [('dir/', 'A-id'),
2808
target=[('dir/', 'C-id'),
2810
state = self.assertUpdate(# different active
2811
active=[('dir/', 'D-id'),
2813
basis= [('dir/', 'A-id'),
2815
target=[('dir/', 'C-id'),
2843
2818
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
2819
state = self.assertUpdate(# Same as basis
2820
active=[('A/', 'A-id'),
2823
basis= [('A/', 'A-id'),
2826
target=[('A/', 'B-id'),
2829
state = self.assertUpdate(# Same as target
2830
active=[('A/', 'B-id'),
2833
basis= [('A/', 'A-id'),
2836
target=[('A/', 'B-id'),
2839
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')])
2841
basis= [('A/', 'A-id'),
2844
target=[('A/', 'B-id'),
2847
state = self.assertUpdate(# different active
2848
active=[('D/', 'A-id'),
2851
basis= [('A/', 'A-id'),
2854
target=[('A/', 'B-id'),
2883
2858
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')])
2859
state = self.assertUpdate( # same as basis
2860
active=[('', 'root-id'),
2861
('file', 'file-id')],
2862
basis= [('', 'root-id'),
2863
('file', 'file-id')],
2864
target=[('', 'target-root-id'),
2865
('file', 'file-id')])
2866
state = self.assertUpdate( # same as target
2867
active=[('', 'target-root-id'),
2868
('file', 'file-id')],
2869
basis= [('', 'root-id'),
2870
('file', 'file-id')],
2871
target=[('', 'target-root-id'),
2872
('file', 'root-id')])
2873
state = self.assertUpdate( # all different
2874
active=[('', 'active-root-id'),
2875
('file', 'file-id')],
2876
basis= [('', 'root-id'),
2877
('file', 'file-id')],
2878
target=[('', 'target-root-id'),
2879
('file', 'root-id')])
2906
2881
def test_change_file_absent_in_active(self):
2907
2882
state = self.assertUpdate(
2909
basis=[('file', b'file-id')],
2910
target=[('file', b'file-id')])
2884
basis= [('file', 'file-id')],
2885
target=[('file', 'file-id')])
2912
2887
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')])
2888
state = self.assertBadDelta( # Not present in basis
2889
active=[('file', 'file-id')],
2891
delta=[('file', 'file', 'file-id')])
2892
state = self.assertBadDelta( # present at another location in basis
2893
active=[('file', 'file-id')],
2894
basis= [('other-file', 'file-id')],
2895
delta=[('file', 'file', 'file-id')])