Index: tracmigrate/admin.py
===================================================================
--- tracmigrate/admin.py	(revision 15437)
+++ tracmigrate/admin.py	(working copy)
@@ -5,6 +5,7 @@
 import shutil
 import sys
 import time
+from ConfigParser import RawConfigParser
 from tempfile import mkdtemp
 
 from trac.core import Component, implements, TracError
@@ -20,6 +21,15 @@
     return DatabaseManager(env).get_connection()
 
 
+class MigrateEnvironment(Environment):
+
+    def is_component_enabled(self, cls):
+        name = self._component_name(cls)
+        if not any(name.startswith(mod + '.') for mod in ('trac', 'tracopt')):
+            return False
+        return Environment.is_component_enabled(self, cls)
+
+
 class TracMigrationCommand(Component):
 
     implements(IAdminCommandProvider)
@@ -101,32 +111,29 @@
                        basename(dst), dir)
 
     def _create_env(self, env_path, dburi):
-        options = [('trac', 'database', dburi)]
-        plugins = []
-        for section in self.config.sections():
-            for name, value in self.config.options(section):
-                if section == 'trac' and name == 'database':
-                    continue
-                entry = (section, name, value)
-                if section != 'components':
-                    options.append(entry)
-                    continue
-                if any(name == prefix or name.startswith(prefix + '.')
-                       for prefix in ('trac', 'tracopt')):
-                    options.append(entry)
-                    continue
-                options.append((section, name, 'disabled'))
-                plugins.append(entry)
+        parser = RawConfigParser()
+        parser.read([os.path.join(self.env.path, 'conf', 'trac.ini')])
+        options = dict(((section, name), value)
+                       for section in parser.sections()
+                       for name, value in parser.items(section))
+        options[('trac', 'database')] = dburi
+        options = [(section, name, value) for (section, name), value
+                                          in options.iteritems()]
 
         # create an environment without plugins
-        env = Environment(env_path, create=True, options=options)
-        for section, name, value in plugins:
-            env.config.set(section, name, value)
-        env.config.save()
+        env = MigrateEnvironment(env_path, create=True, options=options)
+        env.shutdown()
+        # copy plugins directory
+        os.rmdir(os.path.join(env_path, 'plugins'))
+        shutil.copytree(os.path.join(self.env.path, 'plugins'),
+                        os.path.join(env_path, 'plugins'))
         # create tables for plugins to upgrade
         env = Environment(env_path)
-        env.upgrade()
-        return Environment(env_path)  # to be probably safe
+        if env.needs_upgrade():
+            env.upgrade()
+            env.shutdown()
+            env = Environment(env_path)  # to be probably safe
+        return env
 
     def _copy_tables(self, src_db, dst_db, src_dburi, dburi, inplace=False):
         self._printout('Copying tables:')
Index: tracmigrate/tests/admin.py
===================================================================
--- tracmigrate/tests/admin.py	(revision 15437)
+++ tracmigrate/tests/admin.py	(working copy)
@@ -15,7 +15,7 @@
 from trac.db.api import get_column_names
 from trac.env import Environment
 from trac.test import EnvironmentStub, get_dburi
-from trac.util import read_file
+from trac.util import create_file, read_file
 from trac.util.text import to_unicode
 from trac.wiki.admin import WikiAdmin
 
@@ -230,7 +230,65 @@
         self._compare_records(src_records, dst_records)
         self.assertEqual(src_options, dst_options)
 
+    _plugin_source = """\
+import os.path
+from trac.core import Component, implements
+from trac.env import IEnvironmentSetupParticipant
+from trac.util import create_file
 
+class Setup(Component):
+
+    implements(IEnvironmentSetupParticipant)
+
+    def __init__(self):
+        self._created_file = os.path.join(self.env.path, 'log', 'created')
+        self._upgraded_file = os.path.join(self.env.path, 'log', 'upgraded')
+
+    def environment_created(self):
+        create_file(self._created_file)
+
+    def environment_needs_upgrade(self, db):
+        return not os.path.exists(self._upgraded_file)
+
+    def upgrade_environment(self, db):
+        create_file(self._upgraded_file)
+"""
+
+    def test_migrate_with_plugins_to_sqlite_env(self):
+        dburi = get_dburi()
+        if dburi == 'sqlite::memory:':
+            dburi = 'sqlite:db/trac.db'
+        self._create_env(self.src_path, dburi)
+        create_file(os.path.join(self.src_path, 'plugins',
+                                 'tracmigrate_plugind.py'),
+                    self._plugin_source % {'env_path': self.src_path})
+
+        self.src_env = Environment(self.src_path)
+        self.assertTrue(self.src_env.needs_upgrade())
+        self.src_env.upgrade()
+        self.assertFalse(self.src_env.needs_upgrade())
+        src_options = self._get_options(self.src_env)
+        src_records = self._get_all_records(self.src_env)
+
+        self._migrate(self.src_env, self.dst_path, 'sqlite:db/trac.db')
+        self.assertTrue(os.path.exists(os.path.join(self.dst_path, 'plugins',
+                                                    'tracmigrate_plugind.py')))
+        self.dst_env = Environment(self.dst_path)
+        self.assertFalse(self.dst_env.needs_upgrade())
+        self.assertFalse(os.path.exists(os.path.join(self.dst_path, 'log',
+                                                     'created')))
+        self.assertTrue(os.path.exists(os.path.join(self.dst_path, 'log',
+                                                    'upgraded')))
+        dst_options = self._get_options(self.dst_env)
+        dst_records = self._get_all_records(self.dst_env)
+        self.assertEqual({'name': 'initial_database_version', 'value': '21'},
+                         dst_records['system']['initial_database_version'])
+        self._compare_records(src_records, dst_records)
+        self.assertEqual(src_options, dst_options)
+        att = Attachment(self.dst_env, 'wiki', 'WikiStart', 'filename.txt')
+        self.assertEqual('test', read_file(att.path))
+
+
 def suite():
     suite = unittest.TestSuite()
     suite.addTest(unittest.makeSuite(MigrationTestCase))
