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