diff --git a/trac/admin/tests/console-tests.txt b/trac/admin/tests/console-tests.txt
--- a/trac/admin/tests/console-tests.txt
+++ b/trac/admin/tests/console-tests.txt
@@ -41,7 +41,6 @@
 repository alias     Create an alias for a repository
 repository list      List source repositories
 repository remove    Remove a source repository
-repository rename    Rename a source repository
 repository resync    Re-synchronize trac with repositories
 repository set       Set an attribute of a repository
 repository sync      Resume synchronization of repositories
diff --git a/trac/db_default.py b/trac/db_default.py
--- a/trac/db_default.py
+++ b/trac/db_default.py
@@ -86,18 +86,18 @@
 
     # Version control cache
     Table('repository', key=('id', 'name'))[
-        Column('id'),
+        Column('id', type='int'),
         Column('name'),
         Column('value')],
     Table('revision', key=('repos', 'rev'))[
-        Column('repos'),
+        Column('repos', type='int'),
         Column('rev'),
         Column('time', type='int'),
         Column('author'),
         Column('message'),
         Index(['repos', 'time'])],
     Table('node_change', key=('repos', 'rev', 'path', 'change_type'))[
-        Column('repos'),
+        Column('repos', type='int'),
         Column('rev'),
         Column('path'),
         Column('node_type', size=1),
diff --git a/trac/versioncontrol/admin.py b/trac/versioncontrol/admin.py
--- a/trac/versioncontrol/admin.py
+++ b/trac/versioncontrol/admin.py
@@ -126,24 +126,22 @@
         cursor = db.cursor()
         for repos in sorted(repositories, key=lambda r: r.reponame):
             reponame = repos.reponame
+            id = rm.get_repository_id(reponame)
             printout(_('Resyncing repository history for %(reponame)s... ',
                        reponame=reponame or '(default)'))
             if clean:
-                cursor.execute("DELETE FROM revision WHERE repos=%s",
-                               (reponame,))
-                cursor.execute("DELETE FROM node_change "
-                               "WHERE repos=%s", (reponame,))
+                cursor.execute("DELETE FROM revision WHERE repos=%s", (id,))
+                cursor.execute("DELETE FROM node_change WHERE repos=%s", (id,))
                 cursor.executemany("DELETE FROM repository "
                                    "WHERE id=%s AND name=%s",
-                                   [(reponame, k) for k in CACHE_METADATA_KEYS])
+                                   [(id, k) for k in CACHE_METADATA_KEYS])
                 cursor.executemany("INSERT INTO repository (id, name, value) "
                                    "VALUES (%s, %s, %s)", 
-                                   [(reponame, k, '') 
-                                    for k in CACHE_METADATA_KEYS])
+                                   [(id, k, '') for k in CACHE_METADATA_KEYS])
                 db.commit()
             repos.sync(self._sync_feedback)
             cursor.execute("SELECT count(rev) FROM revision WHERE repos=%s",
-                           (reponame,))
+                           (id,))
             for cnt, in cursor:
                 printout(ngettext('%(num)s revision cached.',
                                   '%(num)s revisions cached.', num=cnt))
@@ -187,7 +185,6 @@
                 
                 elif db_provider and req.args.get('save'):
                     # Modify repository
-                    changed = False
                     changes = {}
                     for field in db_provider.repository_attrs:
                         value = normalize_whitespace(req.args.get(field))
@@ -196,14 +193,8 @@
                             changes[field] = value
                     if changes:
                         db_provider.modify_repository(reponame, changes)
-                        changed = True
-                    # Rename repository
+                        add_notice(req, _('Your changes have been saved.'))
                     name = req.args.get('name')
-                    if name and name != path_info:
-                        db_provider.rename_repository(reponame, name)
-                        changed = True
-                    if changed:
-                        add_notice(req, _('Your changes have been saved.'))
                     if 'dir' in changes:
                         msg = _('You should now run "trac-admin $ENV '
                                 'repository resync %(name)s" to synchronize '
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', 'hidden', 'type', 'url')
+    repository_attrs = ('alias', 'dir', 'hidden', 'name', 'type', 'url')
     
     # IRepositoryProvider methods
 
@@ -107,10 +107,15 @@
         cursor.execute("SELECT id,name,value FROM repository "
                        "WHERE name IN (%s)" % ",".join(
                            "'%s'" % each for each in self.repository_attrs))
+        repos = {}
+        for id, name, value in cursor:
+            if value is not None:
+                repos.setdefault(id, {})[name] = value
         reponames = {}
-        for (id, name, value) in cursor:
-            if value is not None:
-                reponames.setdefault(id, {})[name] = value
+        for id, info in repos.iteritems():
+            if 'name' in info and 'dir' in info:
+                info['id'] = id
+                reponames[info['name']] = info
         return reponames.iteritems()
 
     # IAdminCommandProvider methods
@@ -125,9 +130,6 @@
         yield ('repository remove', '<repos>',
                'Remove a source repository',
                self._complete_repos, self._do_remove)
-        yield ('repository rename', '<repos> <newname>',
-               'Rename a source repository',
-               self._complete_repos, self._do_rename)
         yield ('repository set', '<repos> <key> <value>',
                """Set an attribute of a repository
                
@@ -169,9 +171,6 @@
     def _do_remove(self, reponame):
         self.remove_repository(reponame)
     
-    def _do_rename(self, reponame, newname):
-        self.rename_repository(reponame, newname)
-    
     def _do_set(self, reponame, key, value):
         if key not in self.repository_attrs:
             raise AdminCommandError(_('Invalid key "%(key)s"', key=key))
@@ -194,11 +193,12 @@
             raise TracError(_("The repository type '%(type)s' is not "
                               "supported", type=type_))
         db = self.env.get_db_cnx()
+        id = rm.get_repository_id(reponame, db)
         cursor = db.cursor()
         cursor.executemany("INSERT INTO repository (id, name, value) "
                            "VALUES (%s, %s, %s)",
-                           [(reponame, 'dir', dir),
-                            (reponame, 'type', type_ or '')])
+                           [(id, 'dir', dir),
+                            (id, 'type', type_ or '')])
         db.commit()
         rm.reload_repositories()
     
@@ -208,64 +208,53 @@
             reponame = ''
         if target == '(default)':
             target = ''
+        rm = RepositoryManager(self.env)
         db = self.env.get_db_cnx()
+        id = rm.get_repository_id(reponame, db)
         cursor = db.cursor()
         cursor.executemany("INSERT INTO repository (id, name, value) "
                            "VALUES (%s, %s, %s)",
-                           [(reponame, 'dir', None),
-                            (reponame, 'alias', target)])
+                           [(id, 'dir', None),
+                            (id, 'alias', target)])
         db.commit()
-        RepositoryManager(self.env).reload_repositories()
+        rm.reload_repositories()
     
     def remove_repository(self, reponame):
         """Remove a repository."""
         if reponame == '(default)':
             reponame = ''
+        rm = RepositoryManager(self.env)
         db = self.env.get_db_cnx()
+        id = rm.get_repository_id(reponame, db)
         cursor = db.cursor()
-        cursor.execute("DELETE FROM repository WHERE id=%s", (reponame,))
-        cursor.execute("DELETE FROM revision WHERE repos=%s", (reponame,))
-        cursor.execute("DELETE FROM node_change WHERE repos=%s", (reponame,))
+        cursor.execute("DELETE FROM repository WHERE id=%s", (id,))
+        cursor.execute("DELETE FROM revision WHERE repos=%s", (id,))
+        cursor.execute("DELETE FROM node_change WHERE repos=%s", (id,))
         db.commit()
-        RepositoryManager(self.env).reload_repositories()
-    
-    def rename_repository(self, reponame, newname):
-        """Rename a repository."""
-        if reponame == '(default)':
-            reponame = ''
-        if newname == '(default)':
-            newname = ''
-        db = self.env.get_db_cnx()
-        cursor = db.cursor()
-        cursor.execute("UPDATE repository SET id=%s WHERE id=%s",
-                       (newname, reponame))
-        cursor.execute("UPDATE revision SET repos=%s WHERE repos=%s",
-                       (newname, reponame))
-        cursor.execute("UPDATE node_change SET repos=%s WHERE repos=%s",
-                       (newname, reponame))
-        db.commit()
-        RepositoryManager(self.env).reload_repositories()
+        rm.reload_repositories()
     
     def modify_repository(self, reponame, changes):
         """Modify attributes of a repository."""
         if reponame == '(default)':
             reponame = ''
+        rm = RepositoryManager(self.env)
         db = self.env.get_db_cnx()
+        id = rm.get_repository_id(reponame, db)
         cursor = db.cursor()
         for (k, v) in changes.iteritems():
             if k not in self.repository_attrs:
                 continue
-            if k == 'alias' and v == '(default)':
+            if k in('alias', 'name') and v == '(default)':
                 v = ''
             cursor.execute("UPDATE repository SET value=%s "
-                           "WHERE id=%s AND name=%s", (v, reponame, k))
+                           "WHERE id=%s AND name=%s", (v, id, k))
             cursor.execute("SELECT value FROM repository "
-                           "WHERE id=%s AND name=%s", (reponame, k))
+                           "WHERE id=%s AND name=%s", (id, k))
             if not cursor.fetchone():
                 cursor.execute("INSERT INTO repository VALUES (%s, %s, %s)",
-                               (reponame, k, v))
+                               (id, k, v))
         db.commit()
-        RepositoryManager(self.env).reload_repositories()
+        rm.reload_repositories()
 
 
 class RepositoryManager(Component):
@@ -445,6 +434,25 @@
                         repositories.append(repos)
         return repositories
 
+    def get_repository_id(self, reponame, db=None):
+        """Return a unique id for the given repository name."""
+        handle_ta = False
+        if db is None:
+            db = self.env.get_db_cnx()
+            handle_ta = True
+        cursor = db.cursor()
+        cursor.execute("SELECT id FROM repository "
+                       "WHERE name='name' AND value=%s", (reponame,))
+        for id, in cursor:
+            return id
+        cursor.execute("SELECT COALESCE(MAX(id),0) FROM repository")
+        id = cursor.fetchone()[0] + 1
+        cursor.execute("INSERT INTO repository VALUES (%s,%s,%s)",
+                       (id, 'name', reponame))
+        if handle_ta:
+            db.commit()
+        return id
+    
     def get_repository(self, reponame, authname):
         """Retrieve the appropriate Repository for the given name.
 
@@ -455,6 +463,7 @@
            :return: if no corresponding repository was defined, 
                     simply return `None`.
         """
+        reponame = reponame or ''
         repoinfo = self.get_all_repositories().get(reponame, {})
         if repoinfo and 'alias' in repoinfo:
             reponame = repoinfo['alias']
@@ -489,6 +498,7 @@
                 connector = self._get_connector(rtype)
                 repos = connector.get_repository(rtype, rdir, repoinfo)
                 repos.reponame = reponame
+                repos.id = repoinfo['id']
                 repositories[reponame] = repos
             return repos
         finally:
@@ -538,6 +548,8 @@
                         self.log.warn("Discarding duplicate repository '%s'",
                                       reponame)
                     else:
+                        if 'id' not in info:
+                            info['id'] = self.get_repository_id(reponame)
                         self._all_repositories[reponame] = info
         return self._all_repositories
     
@@ -673,6 +685,7 @@
         self.authz = authz or Authorizer()
         self.log = log
         self.reponame = name # overriden by the reponame key used to create it
+        self.id = None
 
     def close(self):
         """Close the connection to the repository."""
diff --git a/trac/versioncontrol/cache.py b/trac/versioncontrol/cache.py
--- a/trac/versioncontrol/cache.py
+++ b/trac/versioncontrol/cache.py
@@ -48,19 +48,24 @@
         self.repos = repos
         self.metadata = CacheProxy(self.__class__.__module__ + '.'
                                    + self.__class__.__name__ + '.metadata:'
-                                   + self.repos.reponame, self._metadata,
+                                   + str(self.repos.id), self._metadata,
                                    self.env)
         Repository.__init__(self, repos.name, authz, log)
 
     def _set_reponame(self, value):
         self.repos.reponame = value
-        self.metadata.id = self.__class__.__module__ + '.' \
-                           + self.__class__.__name__ + '.metadata:' \
-                           + value
     
     reponame = property(fget=lambda self: self.repos.reponame,
                         fset=_set_reponame)
     
+    def _set_id(self, value):
+        self.repos.id = value
+        self.metadata.id = self.__class__.__module__ + '.' \
+                           + self.__class__.__name__ + '.metadata:' \
+                           + str(value)
+    
+    id = property(fget=lambda self: self.repos.id, fset=_set_id)
+    
     def close(self):
         self.repos.close()
 
@@ -86,7 +91,7 @@
         cursor.execute("SELECT rev FROM revision "
                        "WHERE repos=%s AND time >= %s AND time < %s "
                        "ORDER BY time DESC, rev DESC",
-                       (self.reponame, to_timestamp(start),
+                       (self.id, to_timestamp(start),
                         to_timestamp(stop)))
         for rev, in cursor:
             try:
@@ -101,7 +106,7 @@
         cursor = db.cursor()
         cursor.execute("SELECT time,author,message FROM revision "
                        "WHERE repos=%s AND rev=%s",
-                       (self.reponame, str(cset.rev)))
+                       (self.id, str(cset.rev)))
         old_changeset = None
         for time, author, message in cursor:
             date = datetime.fromtimestamp(time, utc)
@@ -110,7 +115,7 @@
         cursor.execute("UPDATE revision SET time=%s, author=%s, message=%s "
                        "WHERE repos=%s AND rev=%s",
                        (to_timestamp(cset.date), cset.author, cset.message,
-                        self.reponame, str(cset.rev)))
+                        self.id, str(cset.rev)))
         db.commit()
         return old_changeset
         
@@ -120,7 +125,7 @@
         cursor.execute("SELECT name, value FROM repository "
                        "WHERE id=%%s AND name IN (%s)" % 
                        ','.join(['%s'] * len(CACHE_METADATA_KEYS)),
-                       (self.reponame,) + CACHE_METADATA_KEYS)
+                       (self.id,) + CACHE_METADATA_KEYS)
         return dict(cursor)
 
     def sync(self, feedback=None):
@@ -143,13 +148,13 @@
             self.log.info('Storing initial "repository_dir": %s' % self.name)
             cursor.execute("INSERT INTO repository (id,name,value) "
                            "VALUES (%s,%s,%s)",
-                           (self.reponame, CACHE_REPOSITORY_DIR, self.name))
+                           (self.id, CACHE_REPOSITORY_DIR, self.name))
             do_commit = True
         else: # 'repository_dir' cleared by a resync
             self.log.info('Resetting "repository_dir": %s' % self.name)
             cursor.execute("UPDATE repository SET value=%s "
                            "WHERE id=%s AND name=%s",
-                           (self.name, self.reponame, CACHE_REPOSITORY_DIR))
+                           (self.name, self.id, CACHE_REPOSITORY_DIR))
             do_commit = True
 
         # -- retrieve the youngest revision in the repository
@@ -161,7 +166,7 @@
         if youngest is None:
             cursor.execute("INSERT INTO repository (id,name,value) "
                            "VALUES (%s,%s,%s)",
-                           (self.reponame, CACHE_YOUNGEST_REV, ''))
+                           (self.id, CACHE_YOUNGEST_REV, ''))
             do_commit = True
 
         if do_commit:
@@ -205,7 +210,7 @@
             # 0. first check if there's no (obvious) resync in progress
             cursor.execute("SELECT rev FROM revision "
                            "WHERE repos=%s AND rev=%s",
-                           (self.reponame, str(next_youngest)))
+                           (self.id, str(next_youngest)))
             for rev, in cursor:
                 # already there, but in progress, so keep ''previous''
                 # notion of 'youngest'
@@ -232,7 +237,7 @@
                         cursor.execute("INSERT INTO revision "
                                        " (repos,rev,time,author,message) "
                                        "VALUES (%s,%s,%s,%s,%s)",
-                                       (self.reponame, str(next_youngest),
+                                       (self.id, str(next_youngest),
                                         to_timestamp(cset.date),
                                         cset.author, cset.message))
                     except Exception, e: # *another* 1.1. resync attempt won 
@@ -257,7 +262,7 @@
                                        " (repos,rev,path,node_type,"
                                        "  change_type,base_path,base_rev) "
                                        "VALUES (%s,%s,%s,%s,%s,%s,%s)",
-                                       (self.reponame, str(next_youngest),
+                                       (self.id, str(next_youngest),
                                         path, kind, action, bpath, brev))
 
                     # 1.3. iterate (1.1 should always succeed now)
@@ -268,7 +273,7 @@
                     #      (minimize possibility of failures at point 0.)
                     cursor.execute("UPDATE repository SET value=%s "
                                    "WHERE id=%s AND name=%s",
-                                   (str(youngest), self.reponame,
+                                   (str(youngest), self.id,
                                     CACHE_YOUNGEST_REV))
                     self.metadata.invalidate(db)
                     db.commit()
@@ -336,7 +341,7 @@
         # the changeset revs are sequence of ints:
         sql = "SELECT rev FROM node_change WHERE repos=%s AND " + \
               db.cast('rev', 'int') + " " + direction + " %s"
-        args = [self.reponame, rev]
+        args = [self.id, rev]
 
         if path:
             path = path.lstrip('/')
@@ -406,7 +411,7 @@
         cursor = db.cursor()
         cursor.execute("SELECT time,author,message FROM revision "
                        "WHERE repos=%s AND rev=%s",
-                       (self.repos.reponame, str(rev)))
+                       (self.repos.id, str(rev)))
         row = cursor.fetchone()
         if row:
             _date, author, message = row
@@ -421,7 +426,7 @@
         cursor = db.cursor()
         cursor.execute("SELECT path,node_type,change_type,base_path,base_rev "
                        "FROM node_change WHERE repos=%s AND rev=%s "
-                       "ORDER BY path", (self.repos.reponame, str(self.rev)))
+                       "ORDER BY path", (self.repos.id, str(self.rev)))
         for path, kind, change, base_path, base_rev in cursor:
             if not self.authz.has_permission(posixpath.join(self.scope,
                                                             path.strip('/'))):
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
@@ -33,9 +33,10 @@
         self.db = self.env.get_db_cnx()
         self.log = self.env.log
         cursor = self.db.cursor()
-        cursor.execute("INSERT INTO repository (id, name, value) "
-                       "VALUES (%s,%s,%s)",
-                       ('test-repos', 'youngest_rev', ''))
+        cursor.executemany("INSERT INTO repository (id,name,value) "
+                           "VALUES (%s,%s,%s)",
+                           [(1, 'name', 'test-repos'),
+                            (1, 'youngest_rev', '')])
 
     def tearDown(self):
         self.env.reset_db()
@@ -97,18 +98,18 @@
         t3 = datetime(2003, 1, 1, 1, 1, 1, 0, utc)
         cursor = self.db.cursor()
         cursor.execute("INSERT INTO revision (repos,rev,time,author,message) "
-                       "VALUES ('test-repos',0,%s,'','')",
+                       "VALUES (1,0,%s,'','')",
                        (to_timestamp(t1),))
         cursor.execute("INSERT INTO revision (repos,rev,time,author,message) "
-                       "VALUES ('test-repos',1,%s,'joe','Import')",
+                       "VALUES (1,1,%s,'joe','Import')",
                        (to_timestamp(t2),))
         cursor.executemany("INSERT INTO node_change (repos,rev,path,"
                            "node_type,change_type,base_path,base_rev) "
-                           "VALUES ('test-repos','1',%s,%s,%s,%s,%s)",
+                           "VALUES (1,'1',%s,%s,%s,%s,%s)",
                            [('trunk', 'D', 'A', None, None),
                             ('trunk/README', 'F', 'A', None, None)])
         cursor.execute("UPDATE repository SET value='1' "
-                       "WHERE id='test-repos' AND name='youngest_rev'")
+                       "WHERE id=1 AND name='youngest_rev'")
 
         changes = [('trunk/README', Node.FILE, Changeset.EDIT, 'trunk/README', 1)]
         changeset = Mock(Changeset, 2, 'Update', 'joe', t3,
@@ -120,6 +121,7 @@
                      normalize_rev=lambda x: x,                    
                      next_rev=lambda x: x and int(x) == 1 and 2 or None)
         cache = CachedRepository(self.env, repos, None, self.log)
+        cache.id = 1
         cache.sync()
 
         cursor = self.db.cursor()
@@ -137,18 +139,18 @@
         t2 = datetime(2002, 1, 1, 1, 1, 1, 0, utc)
         cursor = self.db.cursor()
         cursor.execute("INSERT INTO revision (repos,rev,time,author,message) "
-                       "VALUES ('test-repos',0,%s,'','')",
+                       "VALUES (1,0,%s,'','')",
                        (to_timestamp(t1),))
         cursor.execute("INSERT INTO revision (repos,rev,time,author,message) "
-                       "VALUES ('test-repos',1,%s,'joe','Import')",
+                       "VALUES (1,1,%s,'joe','Import')",
                        (to_timestamp(t2),))
         cursor.executemany("INSERT INTO node_change (repos,rev,path,"
                            "node_type,change_type,base_path,base_rev) "
-                           "VALUES ('test-repos','1',%s,%s,%s,%s,%s)",
+                           "VALUES (1,'1',%s,%s,%s,%s,%s)",
                            [('trunk', 'D', 'A', None, None),
                             ('trunk/README', 'F', 'A', None, None)])
         cursor.execute("UPDATE repository SET value='1' "
-                       "WHERE id='test-repos' AND name='youngest_rev'")
+                       "WHERE id=1 AND name='youngest_rev'")
 
         repos = Mock(Repository, 'test-repos', None, self.log,
                      get_changeset=lambda x: None,
@@ -157,6 +159,7 @@
                      next_rev=lambda x: None,
                      normalize_rev=lambda rev: rev)
         cache = CachedRepository(self.env, repos, None, self.log)
+        cache.id = 1
         self.assertEqual('1', cache.youngest_rev)
         changeset = cache.get_changeset(1)
         self.assertEqual('joe', changeset.author)

