Index: trac/core.py
===================================================================
--- trac/core.py	(revision 7607)
+++ trac/core.py	(working copy)
@@ -17,7 +17,7 @@
 #         Christopher Lenz <cmlenz@gmx.de>
 
 __all__ = ['Component', 'ExtensionPoint', 'implements', 'Interface',
-           'TracError']
+           'TracError', 'ComponentManager']
 
 
 class TracError(Exception):
Index: trac/versioncontrol/cache.py
===================================================================
--- trac/versioncontrol/cache.py	(revision 7607)
+++ trac/versioncontrol/cache.py	(working copy)
@@ -17,7 +17,7 @@
 import posixpath
 from datetime import datetime
 
-from trac.core import TracError
+from trac.core import *
 from trac.util.datefmt import utc, to_timestamp
 from trac.util.translation import _
 from trac.versioncontrol import Changeset, Node, Repository, Authorizer, \
@@ -35,6 +35,28 @@
 CACHE_METADATA_KEYS = (CACHE_REPOSITORY_DIR, CACHE_YOUNGEST_REV)
 
 
+class ICacheChangesetListener(Interface):
+    """Cached changeset operations"""
+    
+    def edit_changeset(cset):
+        """Called when changeset is about to be cached.
+           Returns altered data to cache or None if unchanged. cset usually
+           contains cset.date, cset.author, cset.message and cset.rev
+        """
+
+class CacheManager(Component):
+    """Provide interface to plug-in into cache operations"""
+
+    observers = ExtensionPoint(ICacheChangesetListener)
+
+    def check_changeset(self, cset):
+        for observer in self.observers:
+            res = observer.edit_changeset(cset)
+            if res != None:
+                cset = res
+        return cset
+
+
 class CachedRepository(Repository):
 
     has_linear_changesets = False
@@ -46,6 +68,7 @@
         else:
             self.getdb = lambda: getdb
         self.repos = repos
+        self.cache_mgr = CacheManager(ComponentManager())
 
     def close(self):
         self.repos.close()
@@ -74,6 +97,7 @@
 
     def sync_changeset(self, rev):
         cset = self.repos.get_changeset(rev)
+        cset = self.cache_mgr.check_changeset(cset)
         db = self.getdb()
         cursor = db.cursor()
         cursor.execute("UPDATE revision SET time=%s, author=%s, message=%s "
@@ -178,6 +202,7 @@
                     self.log.info("Trying to sync revision [%s]" %
                                   next_youngest)
                     cset = self.repos.get_changeset(next_youngest)
+                    cset = self.cache_mgr.check_changeset(cset)
                     try:
                         cursor.execute("INSERT INTO revision "
                                        " (rev,time,author,message) "

