97
108
# Notice that a/e is an empty directory.
99
state = dirstate.DirState.initialize('dirstate')
100
110
packed_stat = 'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
101
111
null_sha = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
102
112
root_entry = ('', '', 'a-root-value'), [
103
('directory', '', 0, False, packed_stat),
113
('d', '', 0, False, packed_stat),
105
115
a_entry = ('', 'a', 'a-dir'), [
106
('directory', '', 0, False, packed_stat),
116
('d', '', 0, False, packed_stat),
108
118
b_entry = ('', 'b', 'b-dir'), [
109
('directory', '', 0, False, packed_stat),
119
('d', '', 0, False, packed_stat),
111
121
c_entry = ('', 'c', 'c-file'), [
112
('file', null_sha, 10, False, packed_stat),
122
('f', null_sha, 10, False, packed_stat),
114
124
d_entry = ('', 'd', 'd-file'), [
115
('file', null_sha, 20, False, packed_stat),
125
('f', null_sha, 20, False, packed_stat),
117
127
e_entry = ('a', 'e', 'e-dir'), [
118
('directory', '', 0, False, packed_stat),
128
('d', '', 0, False, packed_stat),
120
130
f_entry = ('a', 'f', 'f-file'), [
121
('file', null_sha, 30, False, packed_stat),
131
('f', null_sha, 30, False, packed_stat),
123
133
g_entry = ('b', 'g', 'g-file'), [
124
('file', null_sha, 30, False, packed_stat),
134
('f', null_sha, 30, False, packed_stat),
126
136
h_entry = ('b', 'h\xc3\xa5', 'h-\xc3\xa5-file'), [
127
('file', null_sha, 40, False, packed_stat),
137
('f', null_sha, 40, False, packed_stat),
130
140
dirblocks.append(('', [root_entry]))
131
141
dirblocks.append(('', [a_entry, b_entry, c_entry, d_entry]))
132
142
dirblocks.append(('a', [e_entry, f_entry]))
133
143
dirblocks.append(('b', [g_entry, h_entry]))
134
state._set_data([], dirblocks)
144
state = dirstate.DirState.initialize('dirstate')
146
state._set_data([], dirblocks)
137
152
def check_state_with_reopen(self, expected_result, state):
138
153
"""Check that state has current state expected_result.
140
155
This will check the current state, open the file anew and check it
157
This function expects the current state to be locked for writing, and
158
will unlock it before re-opening.
159
This is required because we can't open a lock_read() while something
160
else has a lock_write().
161
write => mutually exclusive lock
143
self.assertEqual(expected_result[0], state.get_parent_ids())
144
# there should be no ghosts in this tree.
145
self.assertEqual([], state.get_ghosts())
146
# there should be one fileid in this tree - the root of the tree.
147
self.assertEqual(expected_result[1], list(state._iter_entries()))
164
# The state should already be write locked, since we just had to do
165
# some operation to get here.
166
assert state._lock_token is not None
168
self.assertEqual(expected_result[0], state.get_parent_ids())
169
# there should be no ghosts in this tree.
170
self.assertEqual([], state.get_ghosts())
171
# there should be one fileid in this tree - the root of the tree.
172
self.assertEqual(expected_result[1], list(state._iter_entries()))
176
del state # Callers should unlock
149
177
state = dirstate.DirState.on_file('dirstate')
150
self.assertEqual(expected_result[1], list(state._iter_entries()))
180
self.assertEqual(expected_result[1], list(state._iter_entries()))
153
185
class TestTreeToDirState(TestCaseWithDirState):
282
314
# we want to be able to get the lines of the dirstate that we will
284
316
lines = state.get_lines()
285
318
self.build_tree_contents([('dirstate', ''.join(lines))])
286
319
# get a state object
287
state = dirstate.DirState.on_file('dirstate')
288
320
# no parents, default tree content
289
321
expected_result = ([], [
290
322
(('', '', tree.path2id('')), # common details
291
323
# current tree details, but new from_tree skips statting, it
292
324
# uses set_state_from_inventory, and thus depends on the
293
325
# inventory state.
294
[('directory', '', 0, False, dirstate.DirState.NULLSTAT),
326
[('d', '', 0, False, dirstate.DirState.NULLSTAT),
329
state = dirstate.DirState.on_file('dirstate')
330
state.lock_write() # check_state_with_reopen will save() and unlock it
297
331
self.check_state_with_reopen(expected_result, state)
299
333
def test_can_save_clean_on_file(self):
300
334
tree = self.make_branch_and_tree('tree')
301
335
state = dirstate.DirState.from_tree(tree, 'dirstate')
302
# doing a save should work here as there have been no changes.
304
# TODO: stat it and check it hasn't changed; may require waiting for
305
# the state accuracy window.
337
# doing a save should work here as there have been no changes.
339
# TODO: stat it and check it hasn't changed; may require waiting for
340
# the state accuracy window.
308
345
class TestDirStateInitialize(TestCaseWithDirState):
310
347
def test_initialize(self):
311
state = dirstate.DirState.initialize('dirstate')
312
self.assertIsInstance(state, dirstate.DirState)
313
lines = state.get_lines()
314
self.assertFileEqual(''.join(state.get_lines()),
316
348
expected_result = ([], [
317
349
(('', '', 'TREE_ROOT'), # common details
318
[('directory', '', 0, False, dirstate.DirState.NULLSTAT), # current tree
350
[('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree
321
self.check_state_with_reopen(expected_result, state)
353
state = dirstate.DirState.initialize('dirstate')
355
self.assertIsInstance(state, dirstate.DirState)
356
lines = state.get_lines()
357
self.assertFileEqual(''.join(state.get_lines()),
359
self.check_state_with_reopen(expected_result, state)
324
365
class TestDirStateManipulations(TestCaseWithDirState):
326
367
def test_set_state_from_inventory_no_content_no_parents(self):
327
368
# setting the current inventory is a slow but important api to support.
328
state = dirstate.DirState.initialize('dirstate')
329
369
tree1 = self.make_branch_and_memory_tree('tree1')
330
370
tree1.lock_write()
332
revid1 = tree1.commit('foo').encode('utf8')
333
root_id = tree1.inventory.root.file_id
334
state.set_state_from_inventory(tree1.inventory)
336
self.assertEqual(DirState.IN_MEMORY_UNMODIFIED, state._header_state)
337
self.assertEqual(DirState.IN_MEMORY_MODIFIED, state._dirblock_state)
373
revid1 = tree1.commit('foo').encode('utf8')
374
root_id = tree1.inventory.root.file_id
375
inv = tree1.inventory
338
378
expected_result = [], [
339
379
(('', '', root_id), [
340
('directory', '', 0, False, DirState.NULLSTAT)])]
341
self.check_state_with_reopen(expected_result, state)
380
('d', '', 0, False, DirState.NULLSTAT)])]
381
state = dirstate.DirState.initialize('dirstate')
383
state.set_state_from_inventory(inv)
384
self.assertEqual(DirState.IN_MEMORY_UNMODIFIED, state._header_state)
385
self.assertEqual(DirState.IN_MEMORY_MODIFIED, state._dirblock_state)
390
# This will unlock it
391
self.check_state_with_reopen(expected_result, state)
343
393
def test_set_path_id_no_parents(self):
344
394
"""The id of a path can be changed trivally with no parents."""
345
395
state = dirstate.DirState.initialize('dirstate')
346
# check precondition to be sure the state does change appropriately.
348
[(('', '', 'TREE_ROOT'), [('directory', '', 0, False, 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')])],
349
list(state._iter_entries()))
350
state.set_path_id('', 'foobarbaz')
352
(('', '', 'foobarbaz'), [('directory', '', 0, False, 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')])]
353
self.assertEqual(expected_rows, list(state._iter_entries()))
354
# should work across save too
397
# check precondition to be sure the state does change appropriately.
399
[(('', '', 'TREE_ROOT'), [('d', '', 0, False, 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')])],
400
list(state._iter_entries()))
401
state.set_path_id('', 'foobarbaz')
403
(('', '', 'foobarbaz'), [('d', '', 0, False, 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')])]
404
self.assertEqual(expected_rows, list(state._iter_entries()))
405
# should work across save too
356
409
state = dirstate.DirState.on_file('dirstate')
357
self.assertEqual(expected_rows, list(state._iter_entries()))
412
self.assertEqual(expected_rows, list(state._iter_entries()))
359
416
def test_set_parent_trees_no_content(self):
360
417
# set_parent_trees is a slow but important api to support.
361
state = dirstate.DirState.initialize('dirstate')
362
418
tree1 = self.make_branch_and_memory_tree('tree1')
363
419
tree1.lock_write()
365
revid1 = tree1.commit('foo')
422
revid1 = tree1.commit('foo')
367
425
branch2 = tree1.branch.bzrdir.clone('tree2').open_branch()
368
426
tree2 = MemoryTree.create_on_branch(branch2)
369
427
tree2.lock_write()
370
revid2 = tree2.commit('foo')
371
root_id = tree2.inventory.root.file_id
372
state.set_path_id('', root_id)
374
state.set_parent_trees(
375
((revid1, tree1.branch.repository.revision_tree(revid1)),
376
(revid2, tree2.branch.repository.revision_tree(revid2)),
377
('ghost-rev', None)),
379
# check we can reopen and use the dirstate after setting parent trees.
429
revid2 = tree2.commit('foo')
430
root_id = tree2.inventory.root.file_id
433
state = dirstate.DirState.initialize('dirstate')
435
state.set_path_id('', root_id)
436
state.set_parent_trees(
437
((revid1, tree1.branch.repository.revision_tree(revid1)),
438
(revid2, tree2.branch.repository.revision_tree(revid2)),
439
('ghost-rev', None)),
441
# check we can reopen and use the dirstate after setting parent trees.
381
445
state = dirstate.DirState.on_file('dirstate')
382
self.assertEqual([revid1, revid2, 'ghost-rev'], state.get_parent_ids())
383
# iterating the entire state ensures that the state is parsable.
384
list(state._iter_entries())
385
# be sure that it sets not appends - change it
386
state.set_parent_trees(
387
((revid1, tree1.branch.repository.revision_tree(revid1)),
388
('ghost-rev', None)),
390
# and now put it back.
391
state.set_parent_trees(
392
((revid1, tree1.branch.repository.revision_tree(revid1)),
393
(revid2, tree2.branch.repository.revision_tree(revid2)),
394
('ghost-rev', tree2.branch.repository.revision_tree(None))),
396
self.assertEqual([revid1, revid2, 'ghost-rev'], state.get_parent_ids())
397
# the ghost should be recorded as such by set_parent_trees.
398
self.assertEqual(['ghost-rev'], state.get_ghosts())
400
[(('', '', root_id), [
401
('directory', '', 0, False, DirState.NULLSTAT),
402
('directory', '', 0, False, revid1),
403
('directory', '', 0, False, revid2)
405
list(state._iter_entries()))
448
self.assertEqual([revid1, revid2, 'ghost-rev'],
449
state.get_parent_ids())
450
# iterating the entire state ensures that the state is parsable.
451
list(state._iter_entries())
452
# be sure that it sets not appends - change it
453
state.set_parent_trees(
454
((revid1, tree1.branch.repository.revision_tree(revid1)),
455
('ghost-rev', None)),
457
# and now put it back.
458
state.set_parent_trees(
459
((revid1, tree1.branch.repository.revision_tree(revid1)),
460
(revid2, tree2.branch.repository.revision_tree(revid2)),
461
('ghost-rev', tree2.branch.repository.revision_tree(None))),
463
self.assertEqual([revid1, revid2, 'ghost-rev'],
464
state.get_parent_ids())
465
# the ghost should be recorded as such by set_parent_trees.
466
self.assertEqual(['ghost-rev'], state.get_ghosts())
468
[(('', '', root_id), [
469
('d', '', 0, False, DirState.NULLSTAT),
470
('d', '', 0, False, revid1),
471
('d', '', 0, False, revid2)
473
list(state._iter_entries()))
407
477
def test_set_parent_trees_file_missing_from_tree(self):
408
478
# Adding a parent tree may reference files not in the current state.
409
479
# they should get listed just once by id, even if they are in two
410
480
# separate trees.
411
481
# set_parent_trees is a slow but important api to support.
412
state = dirstate.DirState.initialize('dirstate')
413
482
tree1 = self.make_branch_and_memory_tree('tree1')
414
483
tree1.lock_write()
416
tree1.add(['a file'], ['file-id'], ['file'])
417
tree1.put_file_bytes_non_atomic('file-id', 'file-content')
418
revid1 = tree1.commit('foo')
486
tree1.add(['a file'], ['file-id'], ['file'])
487
tree1.put_file_bytes_non_atomic('file-id', 'file-content')
488
revid1 = tree1.commit('foo')
420
491
branch2 = tree1.branch.bzrdir.clone('tree2').open_branch()
421
492
tree2 = MemoryTree.create_on_branch(branch2)
422
493
tree2.lock_write()
423
tree2.put_file_bytes_non_atomic('file-id', 'new file-content')
424
revid2 = tree2.commit('foo')
425
root_id = tree2.inventory.root.file_id
426
state.set_path_id('', root_id)
428
state.set_parent_trees(
429
((revid1, tree1.branch.repository.revision_tree(revid1)),
430
(revid2, tree2.branch.repository.revision_tree(revid2)),
495
tree2.put_file_bytes_non_atomic('file-id', 'new file-content')
496
revid2 = tree2.commit('foo')
497
root_id = tree2.inventory.root.file_id
432
500
# check the layout in memory
433
501
expected_result = [revid1.encode('utf8'), revid2.encode('utf8')], [
434
502
(('', '', root_id), [
435
('directory', '', 0, False, DirState.NULLSTAT),
436
('directory', '', 0, False, revid1.encode('utf8')),
437
('directory', '', 0, False, revid2.encode('utf8'))]),
503
('d', '', 0, False, DirState.NULLSTAT),
504
('d', '', 0, False, revid1.encode('utf8')),
505
('d', '', 0, False, revid2.encode('utf8'))]),
438
506
(('', 'a file', 'file-id'), [
439
('absent', '', 0, False, ''),
440
('file', '2439573625385400f2a669657a7db6ae7515d371', 12, False, revid1.encode('utf8')),
441
('file', '542e57dc1cda4af37cb8e55ec07ce60364bb3c7d', 16, False, revid2.encode('utf8'))])
507
('a', '', 0, False, ''),
508
('f', '2439573625385400f2a669657a7db6ae7515d371', 12, False, revid1.encode('utf8')),
509
('f', '542e57dc1cda4af37cb8e55ec07ce60364bb3c7d', 16, False, revid2.encode('utf8'))])
443
self.check_state_with_reopen(expected_result, state)
511
state = dirstate.DirState.initialize('dirstate')
513
state.set_path_id('', root_id)
514
state.set_parent_trees(
515
((revid1, tree1.branch.repository.revision_tree(revid1)),
516
(revid2, tree2.branch.repository.revision_tree(revid2)),
522
# check_state_with_reopen will unlock
523
self.check_state_with_reopen(expected_result, state)
445
525
### add a path via _set_data - so we dont need delta work, just
446
526
# raw data in, and ensure that it comes out via get_lines happily.
448
528
def test_add_path_to_root_no_parents_all_data(self):
449
529
# The most trivial addition of a path is when there are no parents and
450
530
# its in the root and all data about the file is supplied
451
state = dirstate.DirState.initialize('dirstate')
452
531
self.build_tree(['a file'])
453
532
stat = os.lstat('a file')
454
533
# the 1*20 is the sha1 pretend value.
455
state.add('a file', 'a file id', 'file', stat, '1'*20)
456
# having added it, it should be in the output of iter_entries.
534
state = dirstate.DirState.initialize('dirstate')
457
535
expected_entries = [
458
536
(('', '', 'TREE_ROOT'), [
459
('directory', '', 0, False, dirstate.DirState.NULLSTAT), # current tree details
537
('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree details
461
539
(('', 'a file', 'a file id'), [
462
('file', '1'*20, 19, False, dirstate.pack_stat(stat)), # current tree details
540
('f', '1'*20, 19, False, dirstate.pack_stat(stat)), # current tree details
465
self.assertEqual(expected_entries, list(state._iter_entries()))
466
# saving and reloading should not affect this.
544
state.add('a file', 'a file id', 'file', stat, '1'*20)
545
# having added it, it should be in the output of iter_entries.
546
self.assertEqual(expected_entries, list(state._iter_entries()))
547
# saving and reloading should not affect this.
468
551
state = dirstate.DirState.on_file('dirstate')
469
self.assertEqual(expected_entries, list(state._iter_entries()))
554
self.assertEqual(expected_entries, list(state._iter_entries()))
471
558
def test_add_path_to_unversioned_directory(self):
472
559
"""Adding a path to an unversioned directory should error.
474
This is a duplicate of TestWorkingTree.test_add_in_unversioned,
561
This is a duplicate of TestWorkingTree.test_add_in_unversioned,
475
562
once dirstate is stable and if it is merged with WorkingTree3, consider
476
563
removing this copy of the test.
478
state = dirstate.DirState.initialize('dirstate')
479
565
self.build_tree(['unversioned/', 'unversioned/a file'])
480
self.assertRaises(errors.NotVersionedError, state.add,
481
'unversioned/a file', 'a file id', 'file', None, None)
566
state = dirstate.DirState.initialize('dirstate')
568
self.assertRaises(errors.NotVersionedError, state.add,
569
'unversioned/a file', 'a file id', 'file', None, None)
483
573
def test_add_directory_to_root_no_parents_all_data(self):
484
574
# The most trivial addition of a dir is when there are no parents and
485
575
# its in the root and all data about the file is supplied
486
state = dirstate.DirState.initialize('dirstate')
487
576
self.build_tree(['a dir/'])
488
577
stat = os.lstat('a dir')
489
state.add('a dir', 'a dir id', 'directory', stat, None)
490
# having added it, it should be in the output of iter_entries.
491
578
expected_entries = [
492
579
(('', '', 'TREE_ROOT'), [
493
('directory', '', 0, False, dirstate.DirState.NULLSTAT), # current tree details
580
('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree details
495
582
(('', 'a dir', 'a dir id'), [
496
('directory', '', 0, False, dirstate.pack_stat(stat)), # current tree details
583
('d', '', 0, False, dirstate.pack_stat(stat)), # current tree details
499
self.assertEqual(expected_entries, list(state._iter_entries()))
500
# saving and reloading should not affect this.
586
state = dirstate.DirState.initialize('dirstate')
588
state.add('a dir', 'a dir id', 'directory', stat, None)
589
# having added it, it should be in the output of iter_entries.
590
self.assertEqual(expected_entries, list(state._iter_entries()))
591
# saving and reloading should not affect this.
502
595
state = dirstate.DirState.on_file('dirstate')
503
self.assertEqual(expected_entries, list(state._iter_entries()))
598
self.assertEqual(expected_entries, list(state._iter_entries()))
505
602
def test_add_symlink_to_root_no_parents_all_data(self):
506
603
# The most trivial addition of a symlink when there are no parents and
507
604
# its in the root and all data about the file is supplied
508
state = dirstate.DirState.initialize('dirstate')
509
605
## TODO: windows: dont fail this test. Also, how are symlinks meant to
510
606
# be represented on windows.
511
607
os.symlink('target', 'a link')
512
608
stat = os.lstat('a link')
513
state.add('a link', 'a link id', 'symlink', stat, 'target')
514
# having added it, it should be in the output of iter_entries.
515
609
expected_entries = [
516
610
(('', '', 'TREE_ROOT'), [
517
('directory', '', 0, False, dirstate.DirState.NULLSTAT), # current tree details
611
('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree details
519
613
(('', 'a link', 'a link id'), [
520
('symlink', 'target', 6, False, dirstate.pack_stat(stat)), # current tree details
614
('l', 'target', 6, False, dirstate.pack_stat(stat)), # current tree details
523
self.assertEqual(expected_entries, list(state._iter_entries()))
524
# saving and reloading should not affect this.
617
state = dirstate.DirState.initialize('dirstate')
619
state.add('a link', 'a link id', 'symlink', stat, 'target')
620
# having added it, it should be in the output of iter_entries.
621
self.assertEqual(expected_entries, list(state._iter_entries()))
622
# saving and reloading should not affect this.
526
626
state = dirstate.DirState.on_file('dirstate')
527
self.assertEqual(expected_entries, list(state._iter_entries()))
629
self.assertEqual(expected_entries, list(state._iter_entries()))
529
633
def test_add_directory_and_child_no_parents_all_data(self):
530
634
# after adding a directory, we should be able to add children to it.
531
state = dirstate.DirState.initialize('dirstate')
532
635
self.build_tree(['a dir/', 'a dir/a file'])
533
stat = os.lstat('a dir')
534
state.add('a dir', 'a dir id', 'directory', stat, None)
636
dirstat = os.lstat('a dir')
535
637
filestat = os.lstat('a dir/a file')
536
state.add('a dir/a file', 'a file id', 'file', filestat, '1'*20)
537
# having added it, it should be in the output of iter_entries.
538
638
expected_entries = [
539
639
(('', '', 'TREE_ROOT'), [
540
('directory', '', 0, False, dirstate.DirState.NULLSTAT), # current tree details
640
('d', '', 0, False, dirstate.DirState.NULLSTAT), # current tree details
542
642
(('', 'a dir', 'a dir id'), [
543
('directory', '', 0, False, dirstate.pack_stat(stat)), # current tree details
643
('d', '', 0, False, dirstate.pack_stat(dirstat)), # current tree details
545
645
(('a dir', 'a file', 'a file id'), [
546
('file', '1'*20, 25, False, dirstate.pack_stat(filestat)), # current tree details
646
('f', '1'*20, 25, False, dirstate.pack_stat(filestat)), # current tree details
549
self.assertEqual(expected_entries, list(state._iter_entries()))
550
# saving and reloading should not affect this.
649
state = dirstate.DirState.initialize('dirstate')
651
state.add('a dir', 'a dir id', 'directory', dirstat, None)
652
state.add('a dir/a file', 'a file id', 'file', filestat, '1'*20)
653
# added it, it should be in the output of iter_entries.
654
self.assertEqual(expected_entries, list(state._iter_entries()))
655
# saving and reloading should not affect this.
552
659
state = dirstate.DirState.on_file('dirstate')
553
self.assertEqual(expected_entries, list(state._iter_entries()))
662
self.assertEqual(expected_entries, list(state._iter_entries()))
556
667
class TestGetLines(TestCaseWithDirState):
558
669
def test_get_line_with_2_rows(self):
559
670
state = self.create_dirstate_with_root_and_subdir()
560
self.assertEqual(['#bazaar dirstate flat format 2\n',
561
'adler32: -1327947603\n',
565
'\x00\x00a-root-value\x00'
566
'd\x00\x000\x00n\x00AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk\x00\n\x00'
567
'\x00subdir\x00subdir-id\x00'
568
'd\x00\x000\x00n\x00AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk\x00\n\x00'],
672
self.assertEqual(['#bazaar dirstate flat format 2\n',
673
'adler32: -1327947603\n',
677
'\x00\x00a-root-value\x00'
678
'd\x00\x000\x00n\x00AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk\x00\n\x00'
679
'\x00subdir\x00subdir-id\x00'
680
'd\x00\x000\x00n\x00AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk\x00\n\x00'],
571
685
def test_entry_to_line(self):
572
686
state = self.create_dirstate_with_root()
574
'\x00\x00a-root-value\x00d\x00\x000\x00n\x00AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk',
575
state._entry_to_line(state._dirblocks[0][1][0]))
689
'\x00\x00a-root-value\x00d\x00\x000\x00n\x00AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk',
690
state._entry_to_line(state._dirblocks[0][1][0]))
577
694
def test_entry_to_line_with_parent(self):
578
state = dirstate.DirState.initialize('dirstate')
579
695
packed_stat = 'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
580
696
root_entry = ('', '', 'a-root-value'), [
581
('directory', '', 0, False, packed_stat), # current tree details
582
('absent', 'dirname/basename', 0, False, ''), # first: a pointer to the current location
697
('d', '', 0, False, packed_stat), # current tree details
698
('a', 'dirname/basename', 0, False, ''), # first: a pointer to the current location
585
'\x00\x00a-root-value\x00'
586
'd\x00\x000\x00n\x00AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk\x00'
587
'a\x00dirname/basename\x000\x00n\x00',
588
state._entry_to_line(root_entry))
700
state = dirstate.DirState.initialize('dirstate')
703
'\x00\x00a-root-value\x00'
704
'd\x00\x000\x00n\x00AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk\x00'
705
'a\x00dirname/basename\x000\x00n\x00',
706
state._entry_to_line(root_entry))
590
710
def test_entry_to_line_with_two_parents_at_different_paths(self):
591
711
# / in the tree, at / in one parent and /dirname/basename in the other.
592
state = dirstate.DirState.initialize('dirstate')
593
712
packed_stat = 'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
594
713
root_entry = ('', '', 'a-root-value'), [
595
('directory', '', 0, False, packed_stat), # current tree details
596
('directory', '', 0, False, 'rev_id'), # first parent details
597
('absent', 'dirname/basename', 0, False, ''), # second: a pointer to the current location
714
('d', '', 0, False, packed_stat), # current tree details
715
('d', '', 0, False, 'rev_id'), # first parent details
716
('a', 'dirname/basename', 0, False, ''), # second: a pointer to the current location
600
'\x00\x00a-root-value\x00'
601
'd\x00\x000\x00n\x00AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk\x00'
602
'd\x00\x000\x00n\x00rev_id\x00'
603
'a\x00dirname/basename\x000\x00n\x00',
604
state._entry_to_line(root_entry))
718
state = dirstate.DirState.initialize('dirstate')
721
'\x00\x00a-root-value\x00'
722
'd\x00\x000\x00n\x00AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk\x00'
723
'd\x00\x000\x00n\x00rev_id\x00'
724
'a\x00dirname/basename\x000\x00n\x00',
725
state._entry_to_line(root_entry))
606
729
def test_iter_entries(self):
607
730
# we should be able to iterate the dirstate entries from end to end
608
731
# this is for get_lines to be easy to read.
609
state = dirstate.DirState.initialize('dirstate')
610
732
packed_stat = 'AAAAREUHaIpFB2iKAAADAQAtkqUAAIGk'
612
734
root_entries = [(('', '', 'a-root-value'), [
613
('directory', '', 0, False, packed_stat), # current tree details
735
('d', '', 0, False, packed_stat), # current tree details
615
737
dirblocks.append(('', root_entries))
616
738
# add two files in the root
617
739
subdir_entry = ('', 'subdir', 'subdir-id'), [
618
('directory', '', 0, False, packed_stat), # current tree details
740
('d', '', 0, False, packed_stat), # current tree details
620
742
afile_entry = ('', 'afile', 'afile-id'), [
621
('file', 'sha1value', 34, False, packed_stat), # current tree details
743
('f', 'sha1value', 34, False, packed_stat), # current tree details
623
745
dirblocks.append(('', [subdir_entry, afile_entry]))
624
746
# and one in subdir
625
747
file_entry2 = ('subdir', '2file', '2file-id'), [
626
('file', 'sha1value', 23, False, packed_stat), # current tree details
748
('f', 'sha1value', 23, False, packed_stat), # current tree details
628
750
dirblocks.append(('subdir', [file_entry2]))
629
state._set_data([], dirblocks)
630
expected_entries = [root_entries[0], subdir_entry, afile_entry, file_entry2]
631
self.assertEqual(expected_entries, list(state._iter_entries()))
751
state = dirstate.DirState.initialize('dirstate')
753
state._set_data([], dirblocks)
754
expected_entries = [root_entries[0], subdir_entry, afile_entry, file_entry2]
755
self.assertEqual(expected_entries, list(state._iter_entries()))
634
760
class TestGetBlockRowIndex(TestCaseWithDirState):