Rev 4: Rewrite to include tree locking, and avoid the inventory. in http://bzr.arbash-meinel.com/plugins/x_bit

John Arbash Meinel john at arbash-meinel.com
Wed Mar 28 19:41:33 BST 2007


At http://bzr.arbash-meinel.com/plugins/x_bit

------------------------------------------------------------
revno: 4
revision-id: john at arbash-meinel.com-20070328184129-qt7egrdq7nlk5yy4
parent: bialix at ukr.net-20060816093952-bf0526beb115f569
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: x_bit
timestamp: Wed 2007-03-28 13:41:29 -0500
message:
  Rewrite to include tree locking, and avoid the inventory.
  This uses TreeTransform rather than directly modifying the inventory.
  It also makes sure the tree is write locked while modifying, so that
  there isn't a race condition with other commands.
  A couple of other small cleanups.
modified:
  __init__.py                    __init__.py-20060516204016-5be79f11e31f2cb7
-------------- next part --------------
=== modified file '__init__.py'
--- a/__init__.py	2006-08-16 09:39:52 +0000
+++ b/__init__.py	2007-03-28 18:41:29 +0000
@@ -6,6 +6,13 @@
 Written by Alexander Belchenko, 2006
 """
 
+from bzrlib import (
+    builtins,
+    errors,
+    osutils,
+    transform,
+    )
+from bzrlib.builtins import tree_files
 from bzrlib.commands import Command, register_command
 from bzrlib.option import Option
 
@@ -13,6 +20,8 @@
 class cmd_x_bit(Command):
     """Control executable bit of particular file(s)"""
 
+    # If we can't print the filename exactly, that is okay.
+    encoding_type = 'replace'
     takes_args = ['files+']
     takes_options = [Option('set', help='set x-bit for file'),
                      Option('clear', help='clear x-bit for file'),
@@ -21,36 +30,48 @@
     def run(self, files_list, set=False, clear=False):
         from bzrlib.workingtree import WorkingTree
 
-        tree = WorkingTree.open_containing(files_list[0])[0]
-        inv = tree.read_working_inventory()
-        f_inv_changed = False
-
-        for f in files_list:
-            rf = tree.relpath(f)
-            af = tree.abspath(rf)
-
-            fid = inv.path2id(rf)
-            if fid is None:
-                print "File", f, "is not versioned"
-                continue
-
-            inv_entry = inv[fid]
-            if inv_entry.kind != 'file':
-                print "Path", f, "is not a file"
-                continue
-
-            x = inv_entry.executable
-            if set != clear:
-                if set and not x:
-                   inv_entry.executable = True
-                   f_inv_changed = True
-                elif clear and x:
-                   inv_entry.executable = False
-                   f_inv_changed = True
-            print "File", f, "=> x-bit: %r" % inv_entry.executable
-
-        if f_inv_changed:
-            tree._write_inventory(inv)
+        if not set and not clear:
+            raise errors.BzrCommandError(
+                'You must supply either --set or --clear')
+        if set and clear:
+            raise errors.BzrCommandError(
+                'You cannot supply both --set and --clear')
+        # At this point 'set' will always be the desired value. Because if
+        # 'set' is true, then the execute bit should be set, if it is False,
+        # that means 'clear' must be True, which means the executable bit
+        # should be False.
+
+        tree, relpaths = builtins.tree_files(files_list)
+        tt = None
+        tree.lock_tree_write()
+        try:
+            tt = transform.TreeTransform(tree)
+            for fname in relpaths:
+                absfname = tree.abspath(fname)
+
+                fid = tree.path2id(fname)
+                if fid is None:
+                    self.outf.write("Path %s is not versioned"
+                                    % (fname,))
+                    continue
+
+                kind = osutils.file_kind(absfname)
+                if kind != 'file':
+                    self.outf.write("Path %s is a %s not a file"
+                                    % (fname, kind))
+                    continue
+
+                x = tree.is_executable(fid)
+
+                if x != set:
+                   trans_id = tt.trans_id_tree_path(fname)
+                   tt.set_executability(set, trans_id)
+                   self.outf.write("File %s => x-bit: %r\n"
+                                   % (fname, set,))
+        finally:
+            if tt is not None:
+                tt.apply()
+            tree.unlock()
 
 #/class cmd_x_bit
 



More information about the bazaar-commits mailing list