Index: cache.py
===================================================================
--- cache.py	(revision 2541)
+++ cache.py	(working copy)
@@ -42,7 +42,7 @@
         return CachedChangeset(self.repos.normalize_rev(rev), self.db,
                                self.authz)
 
-    def sync(self):
+    def sync(self, first = None, last = None):
         self.log.debug("Checking whether sync with repository is needed")
         cursor = self.db.cursor()
 
@@ -59,25 +59,34 @@
                               "a 'trac-admin resync' operation is needed.")
 
         youngest_stored = self.repos.get_youngest_rev_in_cache(self.db)
-
-        if youngest_stored != str(self.repos.youngest_rev):
+        if youngest_stored != str(self.repos.youngest_rev) or first or last:
             authz = self.repos.authz
             self.repos.authz = Authorizer() # remove permission checking
 
             kindmap = dict(zip(_kindmap.values(), _kindmap.keys()))
             actionmap = dict(zip(_actionmap.values(), _actionmap.keys()))
-            self.log.info("Syncing with repository (%s to %s)"
-                          % (youngest_stored, self.repos.youngest_rev))
-            if youngest_stored:
-                current_rev = self.repos.next_rev(youngest_stored)
+            
+            if first == None and not youngest_stored:
+                first = self.repos.oldest_rev
+            elif first == None or self.rev_older_than(youngest_stored, first):
+                first = self.repos.next_rev(youngest_stored)
             else:
-                current_rev = self.repos.oldest_rev
-            while current_rev is not None:
+                first = self.normalize_rev(first)
+            
+            if last == None:
+                last = self.repos.youngest_rev
+            else:
+                last = self.normalize_rev(last)
+            
+            self.log.info("Syncing with repository (%s to %s)" % (first, last))
+            
+            current_rev = first
+            while current_rev is not None or self.repos.rev_older_than(last, current_rev):
                 changeset = self.repos.get_changeset(current_rev)
-                cursor.execute("INSERT INTO revision (rev,time,author,message) "
-                               "VALUES (%s,%s,%s,%s)", (str(current_rev),
-                               changeset.date, changeset.author,
-                               changeset.message))
+                cursor.execute("INSERT OR REPLACE INTO revision (rev, time, "
+                               "author, message) VALUES (%s,%s,%s,%s)",
+                               (str(current_rev), changeset.date,
+                                changeset.author, changeset.message))
                 for path,kind,action,base_path,base_rev in changeset.get_changes():
                     self.log.debug("Caching node change in [%s]: %s"
                                    % (current_rev, (path, kind, action,

