diff --git a/trac/env.py b/trac/env.py
--- a/trac/env.py
+++ b/trac/env.py
@@ -253,12 +253,6 @@
                     return False
                 return enabled
 
-        # versioncontrol components are automatically enabled if the
-        # repository_dir key is present in the [trac] section
-        # FIXME: this probably shouldn't be hardcoded like this
-        if component_name.startswith('trac.versioncontrol.'):
-            return 'repository_dir' in self.config['trac']
-
         # By default, all components in the trac package are enabled
         return component_name.startswith('trac.')
 
diff --git a/trac/versioncontrol/admin.py b/trac/versioncontrol/admin.py
--- a/trac/versioncontrol/admin.py
+++ b/trac/versioncontrol/admin.py
@@ -14,6 +14,7 @@
 import sys
 
 from trac.admin import IAdminCommandProvider, IAdminPanelProvider, get_dir_list
+from trac.config import _TRUE_VALUES
 from trac.core import *
 from trac.util.text import breakable_path, normalize_whitespace, print_table, \
                            printerr, printout
@@ -190,7 +191,8 @@
                     changes = {}
                     for field in db_provider.repository_attrs:
                         value = normalize_whitespace(req.args.get(field))
-                        if value is not None and value != info.get(field):
+                        if (value is not None or field == 'hidden') \
+                                and value != info.get(field):
                             changes[field] = value
                     if changes:
                         db_provider.modify_repository(reponame, changes)
@@ -300,6 +302,7 @@
             info['prettydir'] = breakable_path(info['dir']) or ''
         if info.get('alias') == '':
             info['alias'] = '(default)'
+        info['hidden'] = info.get('hidden') in _TRUE_VALUES
         info['editable'] = editable
         if not info.get('alias'):
             try:
diff --git a/trac/versioncontrol/api.py b/trac/versioncontrol/api.py
--- a/trac/versioncontrol/api.py
+++ b/trac/versioncontrol/api.py
@@ -96,7 +96,7 @@
 
     implements(IRepositoryProvider, IAdminCommandProvider)
 
-    repository_attrs = ('alias', 'dir', 'type', 'url')
+    repository_attrs = ('alias', 'dir', 'hidden', 'type', 'url')
     
     # IRepositoryProvider methods
 
@@ -262,10 +262,11 @@
 
     repository_dir = Option('trac', 'repository_dir', '',
         """Path to the default repository. This can also be a relative path
-        (''since 0.11''). If this entry is specified (even when left empty),
-        this will auto-enable the trac.versioncontrol.* components. 
-        This means that if you want to use Trac without the source browser,
-        simply remove that entry from the [trac] section.""")
+        (''since 0.11'').
+        
+        This option is deprecated, and repositories should be defined in the
+        `[repositories]` section, or using the "Repositories" admin panel.
+        (''since 0.12'')""")
 
     repository_sync_per_request = ListOption('trac',
         'repository_sync_per_request', '(default)',
@@ -369,17 +370,18 @@
         for option in repositories:
             if option.endswith('.dir'):
                 reponames[option[:-4]] = {}
-        # second pass to gather the <name>.<detail> entries or <alias> ones
+        # second pass to gather aliases
+        for option in repositories:
+            if '.' not in option:
+                alias = repositories.get(option)
+                if reponames.get(alias) == {}:
+                    reponames[option] = {'alias': alias}
+        # third pass to gather the <name>.<detail> entries
         for option in repositories:
             if '.' in option:
-                dotindex = option.rindex('.')
-                name, detail = option[:dotindex], option[dotindex+1:]
+                name, detail = option.rsplit('.', 1)
                 if name in reponames:
                     reponames[name][detail] = repositories.get(option)
-                elif detail == 'alias':
-                    alias = repositories.get(option)
-                    if alias in reponames:
-                        reponames[option] = {'alias': alias}
         # eventually add pre-0.12 default repository
         if '' not in reponames and self.repository_dir:
             reponames[''] = {'dir': self.repository_dir}
diff --git a/trac/versioncontrol/templates/admin_repositories.html b/trac/versioncontrol/templates/admin_repositories.html
--- a/trac/versioncontrol/templates/admin_repositories.html
+++ b/trac/versioncontrol/templates/admin_repositories.html
@@ -62,6 +62,11 @@
               </div>
             </py:otherwise>
           </py:choose>
+          <div class="field">
+            <label><input type="checkbox" name="hidden" value="1" checked="${info.hidden or None}"/>
+              Hide from repository index
+            </label>
+          </div>
           <div class="buttons">
             <input type="submit" name="cancel" value="${_('Cancel')}"/>
             <input py:if="info.editable" type="submit" name="save" value="${_('Save')}"/>
diff --git a/trac/versioncontrol/templates/browser.html b/trac/versioncontrol/templates/browser.html
--- a/trac/versioncontrol/templates/browser.html
+++ b/trac/versioncontrol/templates/browser.html
@@ -47,24 +47,9 @@
   <body>
     <div id="content" class="browser">
 
-      <py:if test="repo">
-        <h1>Repository Index</h1>
-        <py:with vars="repoindex = 'repoindex'">
-          <xi:include href="repository_index.html" />
-        </py:with>
-      </py:if>
-
       <py:if test="dir or file">
         <py:choose>
-          <py:when test="repo">
-            <hr />
-            <h1>Default Repository</h1>
-            <p class="hint">The entries in that repository are reachable directly, 
-            without a repository prefix. <br />
-            However, a repository name will always take precedence over a similarly 
-            named entry in the default repository. <br />
-            If this is a problem, add a separate explicit entry for that repository.</p>
-          </py:when>
+          <h1 py:when="repo">Default Repository</h1>
           <h1 py:otherwise=""><xi:include href="path_links.html" /></h1>
         </py:choose>
   
@@ -153,6 +138,14 @@
         </tr>
       </table>
 
+      <py:if test="repo and repo.repositories">
+        <hr py:if="dir"/>
+        <h1>Repository Index</h1>
+        <py:with vars="repoindex = 'repoindex'">
+          <xi:include href="repository_index.html" />
+        </py:with>
+      </py:if>
+
       <div py:if="file and file.preview" id="preview" class="searchable">
         ${preview_file(file.preview)}
       </div>
diff --git a/trac/versioncontrol/templates/repository_index.html b/trac/versioncontrol/templates/repository_index.html
--- a/trac/versioncontrol/templates/repository_index.html
+++ b/trac/versioncontrol/templates/repository_index.html
@@ -9,8 +9,10 @@
         <tr class="${idx % 2 and 'even' or 'odd'}">
           <td class="name">
             <em py:strip="not err">
-              <a class="dir" title="View Root Directory"
-                href="${href.browser(reponame, order=(order != 'name' and order or None), desc=desc)}" py:choose="reponame"><b py:when="''">(default)</b><py:otherwise>$reponame</py:otherwise></a>
+              <b py:strip="repoinfo.alias != ''">
+                <a class="dir" title="View Root Directory"
+                  href="${href.browser(reponame, order=(order != 'name' and order or None), desc=desc)}">$reponame</a>
+              </b>
             </em>
           </td>
           <td class="size" />
diff --git a/trac/versioncontrol/web_ui/browser.py b/trac/versioncontrol/web_ui/browser.py
--- a/trac/versioncontrol/web_ui/browser.py
+++ b/trac/versioncontrol/web_ui/browser.py
@@ -23,7 +23,7 @@
 
 from genshi.builder import tag
 
-from trac.config import ListOption, BoolOption, Option
+from trac.config import ListOption, BoolOption, Option, _TRUE_VALUES
 from trac.core import *
 from trac.mimeview.api import Mimeview, is_binary, get_mimetype, \
                               IHTMLPreviewAnnotator, Context
@@ -338,9 +338,10 @@
         # Repository index
         all_repositories = None
         if not reponame and path == '/':
-            all_repositories = rm.get_all_repositories().items()
-            if all_repositories:
-                repos = rm.get_repository('', req.authname)
+            all_repositories = rm.get_all_repositories()
+            if all_repositories and repos \
+                    and all_repositories[''].get('hidden') in _TRUE_VALUES:
+                repos = None
 
         if not repos and reponame:
             raise ResourceNotFound(_("No repository '%(repo)s' found",
@@ -450,7 +451,9 @@
 
         rm = RepositoryManager(self.env)
         repositories = []
-        for reponame, repoinfo in all_repositories:
+        for reponame, repoinfo in all_repositories.items():
+            if not reponame or repoinfo.get('hidden') in _TRUE_VALUES:
+                continue
             try:
                 repos = rm.get_repository(reponame, context.perm.username)
                 if repos:

