Rev 3181: Add execute bit support to the inventory journal. in http://people.ubuntu.com/~robertc/baz2.0/inventory.journalled
Robert Collins
robertc at robertcollins.net
Mon Jan 7 22:15:47 GMT 2008
At http://people.ubuntu.com/~robertc/baz2.0/inventory.journalled
------------------------------------------------------------
revno: 3181
revision-id:robertc at robertcollins.net-20080107221540-ki5iy64sjebg2ur4
parent: robertc at robertcollins.net-20080107213228-xke579q733x8z40g
committer: Robert Collins <robertc at robertcollins.net>
branch nick: inventory.journalled
timestamp: Tue 2008-01-08 09:15:40 +1100
message:
Add execute bit support to the inventory journal.
modified:
bzrlib/journalled_inventory.py journalled_inventory-20080103020931-0ht5n40kwc0p7fy1-1
bzrlib/tests/test_journalled_inv.py test_journalled_inv.-20080103012121-ny2w9slze5jgty8i-1
doc/developers/inventory.txt inventory.txt-20080103013957-opkrhxy6lmywmx4i-1
=== modified file 'bzrlib/journalled_inventory.py'
--- a/bzrlib/journalled_inventory.py 2008-01-07 21:32:28 +0000
+++ b/bzrlib/journalled_inventory.py 2008-01-07 22:15:40 +0000
@@ -37,7 +37,7 @@
:param entry: An InventoryDirectory.
"""
- return "dir\x00\x00"
+ return "dir"
def _file_content(entry):
@@ -45,10 +45,14 @@
:param entry: An InventoryFile.
"""
- size_sha = (entry.text_size, entry.text_sha1)
- if None in size_sha:
+ if entry.executable:
+ exec_bytes = 'Y'
+ else:
+ exec_bytes = ''
+ size_exec_sha = (entry.text_size, exec_bytes, entry.text_sha1)
+ if None in size_exec_sha:
raise errors.BzrError('Missing size or sha for %s' % entry.file_id)
- return "file\x00%s\x00%s" % size_sha
+ return "file\x00%d\x00%s\x00%s" % size_exec_sha
def _link_content(entry):
@@ -59,7 +63,7 @@
target = entry.symlink_target
if target is None:
raise errors.BzrError('Missing target for %s' % entry.file_id)
- return "link\x00%s\x00" % target.encode('utf8')
+ return "link\x00%s" % target.encode('utf8')
def _reference_content(entry):
@@ -70,7 +74,7 @@
tree_revision = entry.reference_revision
if tree_revision is None:
raise errors.BzrError('Missing reference revision for %s' % entry.file_id)
- return "tree\x00%s\x00" % tree_revision
+ return "tree\x00%s" % tree_revision
def _dir_to_entry(content, name, parent_id, file_id, last_modified,
@@ -87,7 +91,11 @@
result = _type(file_id, name, parent_id)
result.revision = last_modified
result.text_size = int(content[1])
- result.text_sha1 = content[2]
+ result.text_sha1 = content[3]
+ if content[2]:
+ result.executable = True
+ else:
+ result.executable = False
return result
=== modified file 'bzrlib/tests/test_journalled_inv.py'
--- a/bzrlib/tests/test_journalled_inv.py 2008-01-06 23:31:19 +0000
+++ b/bzrlib/tests/test_journalled_inv.py 2008-01-07 22:15:40 +0000
@@ -42,50 +42,50 @@
parent: null:
parent_validator:
version: entry-version
-/\x00an-id\x00\x00a at e\xc3\xa5ample.com--2004\x00dir\x00\x00
+/\x00an-id\x00\x00a at e\xc3\xa5ample.com--2004\x00dir
"""
-root_only_validator = "4064d5f6ecde08d963e14b426fd10a6624d33a07"
+root_only_validator = "01414d0287318dc16aa1046411179b3682336917"
root_change_lines = """format: bzr journalled inventory v1 (bzr 1.2)
parent: entry-version
-parent_validator: 4064d5f6ecde08d963e14b426fd10a6624d33a07
+parent_validator: 01414d0287318dc16aa1046411179b3682336917
version: changed-root
-/\x00an-id\x00\x00different-version\x00dir\x00\x00
+/\x00an-id\x00\x00different-version\x00dir
"""
corrupt_parent_lines = """format: bzr journalled inventory v1 (bzr 1.2)
parent: entry-version
parent_validator: 4064d5f6ecde08d963e14b426fd10a6624d33a08
version: changed-root
-/\x00an-id\x00\x00different-version\x00dir\x00\x00
+/\x00an-id\x00\x00different-version\x00dir
"""
root_only_unversioned = """format: bzr journalled inventory v1 (bzr 1.2)
parent: null:
parent_validator:
version: entry-version
-/\x00TREE_ROOT\x00\x00null:\x00dir\x00\x00
+/\x00TREE_ROOT\x00\x00null:\x00dir
"""
reference_lines = """format: bzr journalled inventory v1 (bzr 1.2)
parent: null:
parent_validator:
version: entry-version
-/\x00TREE_ROOT\x00\x00a at e\xc3\xa5ample.com--2004\x00dir\x00\x00
-/foo\x00id\x00TREE_ROOT\x00changed\x00tree\x00subtree-version\x00
+/\x00TREE_ROOT\x00\x00a at e\xc3\xa5ample.com--2004\x00dir
+/foo\x00id\x00TREE_ROOT\x00changed\x00tree\x00subtree-version
"""
change_tree_lines = """format: bzr journalled inventory v1 (bzr 1.2)
parent: entry-version
parent_validator:
version: change-tree
-/foo\x00id\x00TREE_ROOT\x00changed-twice\x00tree\x00subtree-version2\x00
+/foo\x00id\x00TREE_ROOT\x00changed-twice\x00tree\x00subtree-version2
"""
validator_only = """format: bzr journalled inventory v1 (bzr 1.2)
parent: entry-version
-parent_validator: 4064d5f6ecde08d963e14b426fd10a6624d33a07
+parent_validator: 01414d0287318dc16aa1046411179b3682336917
version: new-entry
"""
@@ -126,8 +126,8 @@
journal = journalled_inventory.InventoryJournal(versioned_root=False,
tree_references=False)
self.assertEqual((StringIO(root_only_unversioned).readlines(),
- '34627d3eb81bd954ef7fd6d3922cf1ab9d3186aa',
- '34627d3eb81bd954ef7fd6d3922cf1ab9d3186aa'),
+ '3fccf5120c89399c7690e24b5647bbf55128e26b',
+ '3fccf5120c89399c7690e24b5647bbf55128e26b'),
journal.delta_to_lines(NULL_REVISION, "", 'entry-version', delta))
def test_old_validator_stored_new_validator_returned(self):
@@ -243,8 +243,8 @@
journal = journalled_inventory.InventoryJournal(versioned_root=True,
tree_references=True)
self.assertEqual((StringIO(reference_lines).readlines(),
- '70f7bd3ff76816ed74c8c0a11c2b6f63449b5546',
- '70f7bd3ff76816ed74c8c0a11c2b6f63449b5546'),
+ '9308a05ea8e652ed2582818ffb4d463bf897658f',
+ '9308a05ea8e652ed2582818ffb4d463bf897658f'),
journal.delta_to_lines(NULL_REVISION, "", 'entry-version', delta))
def test_parse_no_bytes(self):
@@ -320,7 +320,7 @@
journal_entry = journal.parse_text_bytes(root_only_lines)
self.assertEqual({
'an-id':('/', 'an-id', None, 'a at e\xc3\xa5ample.com--2004',
- ('dir', '', '')),
+ ('dir',)),
},
journal_entry.by_id)
self.assertEqual(NULL_REVISION, journal_entry.parent_revision)
@@ -404,7 +404,7 @@
self.assertEqual(root.parent_revision, root_change.parent_revision)
self.assertEqual({
'an-id': ('/', 'an-id', None, 'different-version',
- ('dir', '', '')),
+ ('dir',)),
}, root_change.by_id)
def test_combine_accrues_validators(self):
@@ -414,8 +414,8 @@
root_change = journal.parse_text_bytes(root_change_lines)
root_change.combine_with(root)
self.assertEqual([
- ('', '4064d5f6ecde08d963e14b426fd10a6624d33a07'),
- ('4064d5f6ecde08d963e14b426fd10a6624d33a07', '4ac18343c8337629b06895d80b4256214603d069')],
+ ('', '01414d0287318dc16aa1046411179b3682336917'),
+ ('01414d0287318dc16aa1046411179b3682336917', '1c892d81f948e2d93313b0f313a8242f98ef8522')],
root_change.validator_chain)
def test_validate_null_parent(self):
@@ -424,7 +424,7 @@
root = journal.parse_text_bytes(root_only_lines)
# The lines sha is the validator
self.assertEqual(
- '4064d5f6ecde08d963e14b426fd10a6624d33a07', root.get_validator())
+ '01414d0287318dc16aa1046411179b3682336917', root.get_validator())
def test_validate_uncombined_errors(self):
journal = journalled_inventory.InventoryJournal(versioned_root=True,
@@ -461,9 +461,9 @@
change_tree.combine_with(root)
self.assertEqual({
'TREE_ROOT': ('/', 'TREE_ROOT', None, 'a at e\xc3\xa5ample.com--2004',
- ('dir', '', '')),
+ ('dir',)),
'id': ('/foo', 'id', 'TREE_ROOT', 'changed-twice',
- ('tree', 'subtree-version2', '')),
+ ('tree', 'subtree-version2')),
}, change_tree.by_id)
def test_check_validators(self):
@@ -477,7 +477,7 @@
def test_to_inventory_root_id_versioned_not_permitted(self):
entries = {
'TREE_ROOT': ('/', 'TREE_ROOT', None, 'a-version-id',
- ('dir', '', '')),
+ ('dir',)),
}
journal_entry = journalled_inventory._JournalEntry(
'something', '', NULL_REVISION, '', entries, False, True)
@@ -486,7 +486,7 @@
def test_to_inventory_root_id_unique_not_permitted(self):
entries = {
'TREE_ROOT': ('/', 'TREE_ROOT', None, 'a-version-id',
- ('dir', '', '')),
+ ('dir',)),
}
journal_entry = journalled_inventory._JournalEntry(
'something', '', NULL_REVISION, '', entries, False, True)
@@ -495,7 +495,7 @@
def test_to_inventory_root_id_not_versioned(self):
entries = {
'an-id': ('/', 'an-id', None, 'null:',
- ('dir', '', '')),
+ ('dir',)),
}
journal_entry = journalled_inventory._JournalEntry(
'something', '', NULL_REVISION, '', entries, True, True)
@@ -504,9 +504,9 @@
def test_to_inventory_has_tree_not_meant_to(self):
entries = {
'an-id': ('/', 'an-id', None, 'changed-in',
- ('dir', '', '')),
+ ('dir',)),
'a-ref': ('/foo', 'ref-id', 'an-id', 'changed-in',
- ('tree', 'ref-revision', '')),
+ ('tree', 'ref-revision')),
# a file that followed the root move
}
journal_entry = journalled_inventory._JournalEntry(
@@ -519,31 +519,35 @@
# - renamed roots
# - deep dirs
# - files moved after parent dir was renamed
+ # - files with and without exec bit
entries = {
# current root:
'an-id': ('/', 'an-id', None, 'changed-in',
- ('dir', '', '')),
+ ('dir',)),
# an old root:
'TREE_ROOT': ('/subdir-now', 'TREE_ROOT', 'an-id', 'moved-root',
- ('dir', '', '')),
+ ('dir',)),
# a file that followed the root move
'moved-id': ('/underoldroot', 'moved-id', 'TREE_ROOT', 'old-rev',
- ('file', '30', 'some-sha')),
+ ('file', '30', '', 'some-sha')),
# a deleted path
'deleted-id': ('None', 'deleted-id', None, NULL_REVISION,
- ('deleted', '', '')),
+ ('deleted',)),
# a tree reference moved to the new root
'ref-id': ('/ref', 'ref-id', 'an-id', 'new-rev',
- ('tree', 'tree-reference-id', '')),
+ ('tree', 'tree-reference-id')),
# a symlink now in a deep dir
'link-id': ('/link', 'link-id', 'deep-id', 'new-rev',
- ('link', 'target', '')),
+ ('link', 'target')),
# a deep dir
'deep-id': ('/dir', 'deep-id', 'TREE_ROOT', 'new-rev',
- ('dir', '', '')),
+ ('dir',)),
+ # a file with an exec bit set
+ 'exec-id': ('/configure', 'exec-id', 'an-id', 'old-rev',
+ ('file', '30', 'Y', 'some-sha')),
}
journal_entry = journalled_inventory._JournalEntry(
- 'something', '13b796ac5738c663107a9340e19def21a92e3f9f',
+ 'something', '6215f52d561aff019a4f2a0612f3027e1cbac580',
NULL_REVISION, '', entries, True, True)
inv = journal_entry.to_inventory()
# easiest way to check we got the right inventory is to serialise it
@@ -552,12 +556,13 @@
parent: null:
parent_validator:
version: something
-/\x00an-id\x00\x00changed-in\x00dir\x00\x00
-/ref\x00ref-id\x00an-id\x00new-rev\x00tree\x00tree-reference-id\x00
-/subdir-now\x00TREE_ROOT\x00an-id\x00moved-root\x00dir\x00\x00
-/subdir-now/dir\x00deep-id\x00TREE_ROOT\x00new-rev\x00dir\x00\x00
-/subdir-now/dir/link\x00link-id\x00deep-id\x00new-rev\x00link\x00target\x00
-/subdir-now/underoldroot\x00moved-id\x00TREE_ROOT\x00old-rev\x00file\x0030\x00some-sha
+/\x00an-id\x00\x00changed-in\x00dir
+/configure\x00exec-id\x00an-id\x00old-rev\x00file\x0030\x00Y\x00some-sha
+/ref\x00ref-id\x00an-id\x00new-rev\x00tree\x00tree-reference-id
+/subdir-now\x00TREE_ROOT\x00an-id\x00moved-root\x00dir
+/subdir-now/dir\x00deep-id\x00TREE_ROOT\x00new-rev\x00dir
+/subdir-now/dir/link\x00link-id\x00deep-id\x00new-rev\x00link\x00target
+/subdir-now/underoldroot\x00moved-id\x00TREE_ROOT\x00old-rev\x00file\x0030\x00\x00some-sha
"""
old_inv = Inventory(None)
delta = inventory.make_inv_delta(old_inv, inv)
@@ -577,20 +582,28 @@
def test_dir(self):
entry = inventory.make_entry('directory', 'a dir', None)
- self.assertEqual('dir\x00\x00', journalled_inventory._directory_content(entry))
+ self.assertEqual('dir', journalled_inventory._directory_content(entry))
def test_file_0_short_sha(self):
file_entry = inventory.make_entry('file', 'a file', None, 'file-id')
file_entry.text_sha1 = ''
file_entry.text_size = 0
- self.assertEqual('file\x000\x00',
+ self.assertEqual('file\x000\x00\x00',
journalled_inventory._file_content(file_entry))
def test_file_10_foo(self):
file_entry = inventory.make_entry('file', 'a file', None, 'file-id')
file_entry.text_sha1 = 'foo'
file_entry.text_size = 10
- self.assertEqual('file\x0010\x00foo',
+ self.assertEqual('file\x0010\x00\x00foo',
+ journalled_inventory._file_content(file_entry))
+
+ def test_file_executable(self):
+ file_entry = inventory.make_entry('file', 'a file', None, 'file-id')
+ file_entry.executable = True
+ file_entry.text_sha1 = 'foo'
+ file_entry.text_size = 10
+ self.assertEqual('file\x0010\x00Y\x00foo',
journalled_inventory._file_content(file_entry))
def test_file_without_size(self):
@@ -608,19 +621,19 @@
def test_link_empty_target(self):
entry = inventory.make_entry('symlink', 'a link', None)
entry.symlink_target = ''
- self.assertEqual('link\x00\x00',
+ self.assertEqual('link\x00',
journalled_inventory._link_content(entry))
def test_link_unicode_target(self):
entry = inventory.make_entry('symlink', 'a link', None)
entry.symlink_target = ' \xc3\xa5'.decode('utf8')
- self.assertEqual('link\x00 \xc3\xa5\x00',
+ self.assertEqual('link\x00 \xc3\xa5',
journalled_inventory._link_content(entry))
def test_link_space_target(self):
entry = inventory.make_entry('symlink', 'a link', None)
entry.symlink_target = ' '
- self.assertEqual('link\x00 \x00',
+ self.assertEqual('link\x00 ',
journalled_inventory._link_content(entry))
def test_link_no_target(self):
@@ -631,13 +644,13 @@
def test_reference_null(self):
entry = inventory.make_entry('tree-reference', 'a tree', None)
entry.reference_revision = NULL_REVISION
- self.assertEqual('tree\x00null:\x00',
+ self.assertEqual('tree\x00null:',
journalled_inventory._reference_content(entry))
def test_reference_revision(self):
entry = inventory.make_entry('tree-reference', 'a tree', None)
entry.reference_revision = 'foo@\xc3\xa5b-lah'
- self.assertEqual('tree\x00foo@\xc3\xa5b-lah\x00',
+ self.assertEqual('tree\x00foo@\xc3\xa5b-lah',
journalled_inventory._reference_content(entry))
def test_reference_no_reference(self):
=== modified file 'doc/developers/inventory.txt'
--- a/doc/developers/inventory.txt 2008-01-04 02:10:02 +0000
+++ b/doc/developers/inventory.txt 2008-01-07 22:15:40 +0000
@@ -107,23 +107,23 @@
PATH ::= path
PARENT_ID ::= FILE_ID | ''
CONTENT ::= DELETED_CONTENT | FILE_CONTENT | DIR_CONTENT | TREE_CONTENT | LINK_CONTENT
-DELETED_CONTENT ::= 'deleted' NULL NULL
-FILE_CONTENT ::= 'file' NULL text_size NULL text_sha1
-DIR_CONTENT ::= 'dir' NULL NULL
-TREE_CONTENT ::= 'tree' NULL tree-revision NULL
-LINK_CONTENT ::= 'link' NULL link-target NULL
+DELETED_CONTENT ::= 'deleted'
+FILE_CONTENT ::= 'file' NULL text_size NULL EXEC NULL text_sha1
+DIR_CONTENT ::= 'dir'
+TREE_CONTENT ::= 'tree' NULL tree-revision
+LINK_CONTENT ::= 'link' NULL link-target
BASIS_INVENTORY ::= NULL_OR_REVISION
LAST_MODIFIED ::= NULL_OR_REVISION
NULL_OR_REVISION ::= 'null:' | REVISION
REVISION ::= revision-id-in-utf8-no-whitespace
+EXEC ::= '' | 'Y'
DELTA_LINES is lexographically sorted.
Some explanation is in order. When NEWPATH is 'None' a delete has been
recorded, and because this journalled inventory is not attempting to be a
reversible journal, the only other valid field is 'file-id'. PARENT_ID is ''
-when a delete has been recorded or when recording a new root entry. Content
-always has 2 NULL delimiters in it to allow easy parsing.
+when a delete has been recorded or when recording a new root entry.
At any commit the validator is the root of a tree. Changing the deltas -
e.g. by rewriting an inventory in the history to be a full inventory
More information about the bazaar-commits
mailing list