Rev 3614: Teach export how to export a subdirectory. (Robert Collins) in http://people.ubuntu.com/~robertc/baz2.0/export

Robert Collins robertc at robertcollins.net
Fri Aug 8 06:26:27 BST 2008


At http://people.ubuntu.com/~robertc/baz2.0/export

------------------------------------------------------------
revno: 3614
revision-id: robertc at robertcollins.net-20080808052558-b3xkprmd19buq12s
parent: pqm at pqm.ubuntu.com-20080807005717-qxnuq9je71bt9tcs
committer: Robert Collins <robertc at robertcollins.net>
branch nick: export
timestamp: Fri 2008-08-08 15:25:58 +1000
message:
  Teach export how to export a subdirectory. (Robert Collins)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
  bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
  bzrlib/export/__init__.py      __init__.py-20051114235828-1ba62cb4062304e6
  bzrlib/export/dir_exporter.py  dir_exporter.py-20051114235828-b51397f56bc7b117
  bzrlib/export/tar_exporter.py  tar_exporter.py-20051114235828-1f6349a2f090a5d0
  bzrlib/export/zip_exporter.py  zip_exporter.py-20051114235828-8f57f954fba6497e
  bzrlib/tests/blackbox/test_export.py test_export.py-20051229024010-e6c26658e460fb1c
=== modified file 'NEWS'
--- a/NEWS	2008-08-07 00:28:43 +0000
+++ b/NEWS	2008-08-08 05:25:58 +0000
@@ -11,6 +11,9 @@
 
   IMPROVEMENTS:
 
+    * ``bzr export`` can now export a subdirectory of a project.
+      (Robert Collins)
+
   BUG FIXES:
 
     * sftp transport: added missing ``FileExists`` case to
@@ -21,6 +24,8 @@
 
   API CHANGES:
 
+    * Exporters now take 4 parameters. (Robert Collins)
+
   INTERNALS:
 
 

=== modified file 'bzrlib/__init__.py'
--- a/bzrlib/__init__.py	2008-08-06 08:23:43 +0000
+++ b/bzrlib/__init__.py	2008-08-08 05:25:58 +0000
@@ -44,8 +44,8 @@
 version_info = (1, 7, 0, 'dev', 0)
 
 
-# API compatibility version: bzrlib is currently API compatible with 1.6.
-api_minimum_version = (1, 6, 0)
+# API compatibility version: bzrlib is currently API compatible with 1.7.
+api_minimum_version = (1, 7, 0)
 
 def _format_version_tuple(version_info):
     """Turn a version number 3-tuple or 5-tuple into a short string.

=== modified file 'bzrlib/builtins.py'
--- a/bzrlib/builtins.py	2008-08-06 21:57:33 +0000
+++ b/bzrlib/builtins.py	2008-08-08 05:25:58 +0000
@@ -2010,7 +2010,7 @@
          zip                          .zip
       =================       =========================
     """
-    takes_args = ['dest', 'branch?']
+    takes_args = ['dest', 'branch_or_subdir?']
     takes_options = [
         Option('format',
                help="Type of file to export to.",
@@ -2020,14 +2020,16 @@
                type=str,
                help="Name of the root directory inside the exported file."),
         ]
-    def run(self, dest, branch=None, revision=None, format=None, root=None):
+    def run(self, dest, branch_or_subdir=None, revision=None, format=None,
+        root=None):
         from bzrlib.export import export
 
-        if branch is None:
+        if branch_or_subdir is None:
             tree = WorkingTree.open_containing(u'.')[0]
             b = tree.branch
+            subdir = None
         else:
-            b = Branch.open(branch)
+            b, subdir = Branch.open_containing(branch_or_subdir)
             
         if revision is None:
             # should be tree.last_revision  FIXME
@@ -2038,7 +2040,7 @@
             rev_id = revision[0].as_revision_id(b)
         t = b.repository.revision_tree(rev_id)
         try:
-            export(t, dest, format, root)
+            export(t, dest, format, root, subdir)
         except errors.NoSuchExportFormat, e:
             raise errors.BzrCommandError('Unsupported export format: %s' % e.format)
 

=== modified file 'bzrlib/export/__init__.py'
--- a/bzrlib/export/__init__.py	2007-10-28 17:30:25 +0000
+++ b/bzrlib/export/__init__.py	2008-08-08 05:25:58 +0000
@@ -55,14 +55,14 @@
 
     When requesting a specific type of export, load the respective path.
     """
-    def _loader(tree, dest, root):
+    def _loader(tree, dest, root, subdir):
         mod = __import__(module, globals(), locals(), [funcname])
         func = getattr(mod, funcname)
-        return func(tree, dest, root)
+        return func(tree, dest, root, subdir)
     register_exporter(scheme, extensions, _loader)
 
 
-def export(tree, dest, format=None, root=None):
+def export(tree, dest, format=None, root=None, subdir=None):
     """Export the given Tree to the specific destination.
 
     :param tree: A Tree (such as RevisionTree) to export
@@ -76,6 +76,9 @@
                  If root is None, the default root will be
                  selected as the destination without its
                  extension.
+    :param subdir: A starting directory within the tree. None means to export
+        the entire tree, and anything else should specify the relative path to
+        a directory to start exporting from.
     """
     global _exporters, _exporter_extensions
 
@@ -94,7 +97,7 @@
         raise errors.NoSuchExportFormat(format)
     tree.lock_read()
     try:
-        return _exporters[format](tree, dest, root)
+        return _exporters[format](tree, dest, root, subdir)
     finally:
         tree.unlock()
 

=== modified file 'bzrlib/export/dir_exporter.py'
--- a/bzrlib/export/dir_exporter.py	2008-07-30 00:26:38 +0000
+++ b/bzrlib/export/dir_exporter.py	2008-08-08 05:25:58 +0000
@@ -24,7 +24,7 @@
 from bzrlib.trace import mutter
 
 
-def dir_exporter(tree, dest, root):
+def dir_exporter(tree, dest, root, subdir):
     """Export this tree to a new directory.
 
     `dest` should not exist, and will be created holding the
@@ -39,8 +39,13 @@
     os.mkdir(dest)
     mutter('export version %r', tree)
     inv = tree.inventory
-    entries = inv.iter_entries()
-    entries.next() # skip root
+    if subdir is None:
+        subdir_id = None
+    else:
+        subdir_id = inv.path2id(subdir)
+    entries = inv.iter_entries(subdir_id)
+    if subdir is None:
+        entries.next() # skip root
     for dp, ie in entries:
         # The .bzr* namespace is reserved for "magic" files like
         # .bzrignore and .bzrrules - do not export these

=== modified file 'bzrlib/export/tar_exporter.py'
--- a/bzrlib/export/tar_exporter.py	2008-07-30 00:26:38 +0000
+++ b/bzrlib/export/tar_exporter.py	2008-08-08 05:25:58 +0000
@@ -26,7 +26,7 @@
 from bzrlib.trace import mutter
 
 
-def tar_exporter(tree, dest, root, compression=None):
+def tar_exporter(tree, dest, root, subdir, compression=None):
     """Export this tree to a new tar file.
 
     `dest` will be created holding the contents of this tree; if it
@@ -44,8 +44,13 @@
         ball = tarfile.open(dest, 'w:' + compression)
     mutter('export version %r', tree)
     inv = tree.inventory
-    entries = inv.iter_entries()
-    entries.next() # skip root
+    if subdir is None:
+        subdir_id = None
+    else:
+        subdir_id = inv.path2id(subdir)
+    entries = inv.iter_entries(subdir_id)
+    if subdir is None:
+        entries.next() # skip root
     for dp, ie in entries:
         # The .bzr* namespace is reserved for "magic" files like
         # .bzrignore and .bzrrules - do not export these
@@ -82,9 +87,9 @@
     ball.close()
 
 
-def tgz_exporter(tree, dest, root):
-    tar_exporter(tree, dest, root, compression='gz')
-
-
-def tbz_exporter(tree, dest, root):
-    tar_exporter(tree, dest, root, compression='bz2')
+def tgz_exporter(tree, dest, root, subdir):
+    tar_exporter(tree, dest, root, subdir, compression='gz')
+
+
+def tbz_exporter(tree, dest, root, subdir):
+    tar_exporter(tree, dest, root, subdir, compression='bz2')

=== modified file 'bzrlib/export/zip_exporter.py'
--- a/bzrlib/export/zip_exporter.py	2008-07-25 01:12:16 +0000
+++ b/bzrlib/export/zip_exporter.py	2008-08-08 05:25:58 +0000
@@ -35,7 +35,7 @@
 _DIR_ATTR = stat.S_IFDIR | ZIP_DIRECTORY_BIT
 
 
-def zip_exporter(tree, dest, root):
+def zip_exporter(tree, dest, root, subdir):
     """ Export this tree to a new zip file.
 
     `dest` will be created holding the contents of this tree; if it
@@ -52,8 +52,13 @@
     inv = tree.inventory
 
     try:
-        entries = inv.iter_entries()
-        entries.next() # skip root
+        if subdir is None:
+            subdir_id = None
+        else:
+            subdir_id = inv.path2id(subdir)
+        entries = inv.iter_entries(subdir_id)
+        if subdir is None:
+            entries.next() # skip root
         for dp, ie in entries:
             # The .bzr* namespace is reserved for "magic" files like
             # .bzrignore and .bzrrules - do not export these

=== modified file 'bzrlib/tests/blackbox/test_export.py'
--- a/bzrlib/tests/blackbox/test_export.py	2008-07-30 00:22:33 +0000
+++ b/bzrlib/tests/blackbox/test_export.py	2008-08-08 05:25:58 +0000
@@ -174,6 +174,7 @@
         self.assertEqual(['a'], files)
 
     def example_branch(self):
+        """Create a branch a 'branch' containing hello and goodbye."""
         tree = self.make_branch_and_tree('branch')
         self.build_tree_contents([('branch/hello', 'foo')])
         tree.add('hello')
@@ -277,3 +278,11 @@
         self.run_bzr('export first -r 1 branch')
         self.assertEqual(['hello'], sorted(os.listdir('first')))
         self.check_file_contents('first/hello', 'foo')
+
+    def test_export_partial_tree(self):
+        tree = self.example_branch()
+        self.build_tree(['branch/subdir/', 'branch/subdir/foo.txt'])
+        tree.smart_add(['branch'])
+        tree.commit('more setup')
+        out, err = self.run_bzr('export exported branch/subdir')
+        self.assertEqual(['foo.txt'], os.listdir('exported'))




More information about the bazaar-commits mailing list