diff --git a/trac/versioncontrol/api.py b/trac/versioncontrol/api.py
--- a/trac/versioncontrol/api.py
+++ b/trac/versioncontrol/api.py
@@ -55,10 +55,6 @@
 
     def get_repository(repos_type, repos_dir, options):
         """Return a Repository instance for the given repository type and dir.
-        
-        The `reponame` and `id` to be passed to the repository constructor are
-        passed in the `options` dictionary, for the keys "name" and "id",
-        respectively.
         """
 
 
@@ -683,22 +679,23 @@
 class Repository(object):
     """Base class for a repository provided by a version control system."""
 
-    def __init__(self, reponame, id, name, authz, log):
+    def __init__(self, name, options, authz, log):
         """Initialize a repository.
         
-           :param reponame: the name of the repository, as it appears in the
-                            repository browser.
-           :param id: a surrogate key for the repository, used to identify the
-                      repository uniquely in the database tables.
            :param name: a unique name identifying the repository, usually a
                         type-specific prefix followed by the path to the
                         repository.
+           :param options: a `dict` of options for the repository. Contains the
+                           name of the repository for the key "name" and the
+                           surrogate key that identifies the repository in the
+                           database for the key "id".
            :param authz: a repository authorizer (deprecated).
            :param log: a logger instance.
         """
-        self.reponame = reponame
-        self.id = id
         self.name = name
+        self.options = options
+        self.reponame = options['name']
+        self.id = options['id']
         self.authz = authz or Authorizer()
         self.log = log
 
diff --git a/trac/versioncontrol/cache.py b/trac/versioncontrol/cache.py
--- a/trac/versioncontrol/cache.py
+++ b/trac/versioncontrol/cache.py
@@ -50,8 +50,7 @@
                                    + self.__class__.__name__ + '.metadata:'
                                    + str(self.repos.id), self._metadata,
                                    self.env)
-        Repository.__init__(self, repos.reponame, repos.id, repos.name, authz,
-                            log)
+        Repository.__init__(self, repos.name, repos.options, authz, log)
 
     def close(self):
         self.repos.close()
diff --git a/trac/versioncontrol/svn_fs.py b/trac/versioncontrol/svn_fs.py
--- a/trac/versioncontrol/svn_fs.py
+++ b/trac/versioncontrol/svn_fs.py
@@ -278,11 +278,8 @@
         if not self._version:
             self._version = self._get_version()
             self.env.systeminfo.append(('Subversion', self._version))
-        fs_repos = SubversionRepository(options['name'], options['id'],
-                                        dir, None, self.log,
-                                        {'tags': self.tags,
-                                         'branches': self.branches,
-                                         'url': options.get('url') or ''})
+        options.update(tags=self.tags, branches=self.branches)
+        fs_repos = SubversionRepository(dir, options, None, self.log)
         if type == 'direct-svnfs':
             repos = fs_repos
         else:
@@ -307,9 +304,8 @@
 class SubversionRepository(Repository):
     """Repository implementation based on the svn.fs API."""
 
-    def __init__(self, reponame, id, path, authz, log, options={}):
+    def __init__(self, path, options, authz, log):
         self.log = log
-        self.options = options
         self.pool = Pool()
         
         # Remove any trailing slash or else subversion might abort
@@ -338,7 +334,7 @@
         self.base = 'svn:%s:%s' % (self.uuid, _from_svn(root_path_utf8))
         name = 'svn:%s:%s' % (self.uuid, self.path)
 
-        Repository.__init__(self, reponame, id, name, authz, log)
+        Repository.__init__(self, name, options, authz, log)
 
         # if root_path_utf8 is shorter than the path_utf8, the difference is
         # this scope (which always starts with a '/')
@@ -425,7 +421,7 @@
             yield 'tags', n.path, n.created_path, n.created_rev
 
     def get_path_url(self, path, rev):
-        url = self.options['url'].rstrip('/')
+        url = self.options.get('url', '').rstrip('/')
         if url:
             if not path or path == '/':
                 return url
diff --git a/trac/versioncontrol/tests/api.py b/trac/versioncontrol/tests/api.py
--- a/trac/versioncontrol/tests/api.py
+++ b/trac/versioncontrol/tests/api.py
@@ -21,7 +21,8 @@
 class ApiTestCase(unittest.TestCase):
 
     def setUp(self):
-        self.repo_base = Repository('testrepo', 1, 'testrepo', None, None)
+        self.repo_base = Repository('testrepo', {'name': 'testrepo', 'id': 1},
+                                    None, None)
 
     def test_raise_NotImplementedError_close(self):
         self.failUnlessRaises(NotImplementedError, self.repo_base.close)
diff --git a/trac/versioncontrol/tests/cache.py b/trac/versioncontrol/tests/cache.py
--- a/trac/versioncontrol/tests/cache.py
+++ b/trac/versioncontrol/tests/cache.py
@@ -46,7 +46,8 @@
         def no_changeset(rev):
             raise NoSuchChangeset(rev)
             
-        repos = Mock(Repository, 'test-repos', 1, 'test-repos', None, self.log,
+        repos = Mock(Repository, 'test-repos', {'name': 'test-repos', 'id': 1},
+                     None, self.log,
                      get_changeset=no_changeset,
                      get_oldest_rev=lambda: 1,
                      get_youngest_rev=lambda: 0,
@@ -70,7 +71,8 @@
                            get_changes=lambda: []),
                       Mock(Changeset, 1, 'Import', 'joe', t2,
                            get_changes=lambda: iter(changes))]
-        repos = Mock(Repository, 'test-repos', 1, 'test-repos', None, self.log,
+        repos = Mock(Repository, 'test-repos', {'name': 'test-repos', 'id': 1},
+                     None, self.log,
                      get_changeset=lambda x: changesets[int(x)],
                      get_oldest_rev=lambda: 0,
                      get_youngest_rev=lambda: 1,
@@ -114,7 +116,8 @@
         changes = [('trunk/README', Node.FILE, Changeset.EDIT, 'trunk/README', 1)]
         changeset = Mock(Changeset, 2, 'Update', 'joe', t3,
                          get_changes=lambda: iter(changes))
-        repos = Mock(Repository, 'test-repos', 1, 'test-repos', None, self.log,
+        repos = Mock(Repository, 'test-repos', {'name': 'test-repos', 'id': 1},
+                     None, self.log,
                      get_changeset=lambda x: changeset,
                      get_youngest_rev=lambda: 2,
                      get_oldest_rev=lambda: 0,
@@ -151,7 +154,8 @@
         cursor.execute("UPDATE repository SET value='1' "
                        "WHERE id=1 AND name='youngest_rev'")
 
-        repos = Mock(Repository, 'test-repos', 1, 'test-repos', None, self.log,
+        repos = Mock(Repository, 'test-repos', {'name': 'test-repos', 'id': 1},
+                     None, self.log,
                      get_changeset=lambda x: None,
                      get_youngest_rev=lambda: 1,
                      get_oldest_rev=lambda: 0,
diff --git a/trac/versioncontrol/tests/svn_fs.py b/trac/versioncontrol/tests/svn_fs.py
--- a/trac/versioncontrol/tests/svn_fs.py
+++ b/trac/versioncontrol/tests/svn_fs.py
@@ -86,8 +86,9 @@
 class SubversionRepositoryTestCase(unittest.TestCase):
 
     def setUp(self):
-        self.repos = SubversionRepository('repo', 1, REPOS_PATH, None,
-                                          logger_factory('test'))
+        self.repos = SubversionRepository(REPOS_PATH,
+                                          {'name': 'repo', 'id': 1},
+                                          None, logger_factory('test'))
 
     def tearDown(self):
         self.repos = None
@@ -508,7 +509,8 @@
 class ScopedSubversionRepositoryTestCase(unittest.TestCase):
 
     def setUp(self):
-        self.repos = SubversionRepository('repo', 1, REPOS_PATH + u'/tête',
+        self.repos = SubversionRepository(REPOS_PATH + u'/tête',
+                                          {'name': 'repo', 'id': 1},
                                           None, logger_factory('test'))
 
     def tearDown(self):
@@ -757,9 +759,9 @@
 class RecentPathScopedRepositoryTestCase(unittest.TestCase):
 
     def setUp(self):
-        self.repos = SubversionRepository('repo', 1,
-                                          REPOS_PATH + u'/tête/dir1', None,
-                                          logger_factory('test'))
+        self.repos = SubversionRepository(REPOS_PATH + u'/tête/dir1',
+                                          {'name': 'repo', 'id': 1},
+                                          None, logger_factory('test'))
 
     def tearDown(self):
         self.repos = None
@@ -778,7 +780,8 @@
 class NonSelfContainedScopedTestCase(unittest.TestCase):
 
     def setUp(self):
-        self.repos = SubversionRepository('repo', 1, REPOS_PATH + '/tags/v1',
+        self.repos = SubversionRepository(REPOS_PATH + '/tags/v1',
+                                          {'name': 'repo', 'id': 1},
                                           None, logger_factory('test'))
 
     def tearDown(self):
@@ -796,7 +799,8 @@
 class AnotherNonSelfContainedScopedTestCase(unittest.TestCase):
 
     def setUp(self):
-        self.repos = SubversionRepository('repo', 1, REPOS_PATH + '/branches',
+        self.repos = SubversionRepository(REPOS_PATH + '/branches',
+                                          {'name': 'repo', 'id': 1},
                                           None, logger_factory('test'))
 
     def tearDown(self):

