Index: trac/versioncontrol/svn_fs.py
===================================================================
--- trac/versioncontrol/svn_fs.py	(revision 8292)
+++ trac/versioncontrol/svn_fs.py	(working copy)
@@ -433,14 +433,15 @@
 
         return SubversionNode(path, rev, self, self.pool)
 
-    def _get_node_revs(self, path, rev=None):
-        """Return the revisions affecting `path` between its creation and
-        `rev`.
+    def _get_node_revs(self, path, last=None, first=None):
+        """Return the revisions affecting `path` between `first` and `last` 
+        revs. If `first` is not given, it goes down to the revision in which
+        the branch was created.
         """
-        node = self.get_node(path, rev)
+        node = self.get_node(path, last)
         revs = []
         for (p, r, chg) in node.get_history():
-            if p != path:
+            if p != path or (first and r < first):
                 break
             revs.append(r)
         return revs
@@ -785,7 +786,16 @@
         return fs.node_prop(self.root, self._scoped_path_utf8, name,
                             self.pool())
 
+    def get_copy_origin(self):
+        root_and_path = fs.closest_copy(self.root, self._scoped_path_utf8)
+        if root_and_path:
+            root, path = root_and_path
+            rev = fs.revision_root_revision(root)
+            if (path, rev) == (self.path, self.rev):
+                rev, path = fs.copied_from(root, path)
+            return SubversionNode(path, rev, self.repos, self.pool, root)
 
+
 class SubversionChangeset(Changeset):
 
     def __init__(self, rev, authz, scope, fs_ptr, pool=None):
Index: trac/versioncontrol/web_ui/browser.py
===================================================================
--- trac/versioncontrol/web_ui/browser.py	(revision 8292)
+++ trac/versioncontrol/web_ui/browser.py	(working copy)
@@ -343,7 +343,7 @@
         except NoSuchChangeset, e:
             raise ResourceNotFound(e.message, _('Invalid Changeset Number'))
 
-        context = Context.from_request(req, 'source', path, node.created_rev)
+        context = Context.from_request(req, 'source', path, rev_or_latest)
 
         path_links = get_path_links(req.href, path, rev, order, desc)
         if len(path_links) > 1:
Index: trac/versioncontrol/cache.py
===================================================================
--- trac/versioncontrol/cache.py	(revision 8292)
+++ trac/versioncontrol/cache.py	(working copy)
@@ -233,31 +233,33 @@
     def get_node(self, path, rev=None):
         return self.repos.get_node(path, rev)
 
-    def _get_node_revs(self, path, rev=None):
-        """Return the revisions affecting `path` between its creation and
-        `rev`.
+    def _get_node_revs(self, path, last=None, first=None):
+        """Return the revisions affecting `path` between `first` and `last`
+        revisions.
         """
-        rev = self.normalize_rev(rev)
+        rev = self.normalize_rev(last)
+        created = first or 0
         node = self.get_node(path, rev)     # Check node existence and perms
         db = self.getdb()
         cursor = db.cursor()
+        rev_as_int = db.cast('rev', 'int')
         cursor.execute("SELECT DISTINCT rev FROM node_change "
                        "WHERE (path = %%s OR path %s) "
-                       "  AND %s <= %%s" % (db.like(), db.cast('rev', 'int')),
-                       (path, db.like_escape(path + '/') + '%', rev))
+                       " AND %s >= %%s AND %s <= %%s" % 
+                       (db.like(), rev_as_int, rev_as_int),
+                       (path, db.like_escape(path + '/') + '%', created, rev))
         revs = [int(row[0]) for row in cursor]
         revs.sort()
         cursor.execute("SELECT rev FROM node_change "
                        "WHERE path = %%s "
                        "  AND change_type IN ('A', 'C', 'M') "
-                       "  AND %s <= %%s "
+                       "  AND %s >= %%s AND %s <= %%s "
                        "ORDER BY %s DESC "
-                       "LIMIT 1" % ((db.cast('rev', 'int'),) * 2),
-                       (path, rev))
-        created = 0
+                       "LIMIT 1" % ((rev_as_int,) * 3),
+                       (path, created, rev))
         for row in cursor:
             created = int(row[0])
-        return revs[bisect.bisect_left(revs, created):]
+        return revs[bisect.bisect_left(revs, max(created, first)):]
 
     def has_node(self, path, rev=None):
         return self.repos.has_node(path, rev)
Index: trac/versioncontrol/svn_prop.py
===================================================================
--- trac/versioncontrol/svn_prop.py	(revision 8292)
+++ trac/versioncontrol/svn_prop.py	(working copy)
@@ -120,6 +120,15 @@
         revs_label = (_('merged'), _('blocked'))[name.endswith('blocked')]
         revs_cols = has_eligible and 2 or None
         repos = self.env.get_repository()
+        target_path = context.resource.id
+        target_rev = context.resource.version
+        if has_eligible:
+            branch_starts = {}
+            node = repos.get_node(target_path, target_rev)
+            while node:
+                node = node.get_copy_origin()
+                if node and node.path != target_path:
+                    branch_starts[node.path] = node.rev + 1
         rows = []
         for line in props[name].splitlines():
             path, revs = line.split(':', 1)
@@ -128,13 +137,14 @@
             deleted = False
             if 'LOG_VIEW' in context.perm('source', spath):
                 try:
-                    node = repos.get_node(spath, context.resource.version)
+                    node = repos.get_node(spath, target_rev)
                     row = [self._get_source_link(path, context),
                            self._get_revs_link(revs_label, context,
                                                spath, revs)]
                     if has_eligible:
-                        eligible = set(repos._get_node_revs(spath,
-                                                    context.resource.version))
+                        first_rev = branch_starts.get(path)
+                        eligible = set(repos._get_node_revs(spath, target_rev,
+                                                            first_rev))
                         eligible -= set(Ranges(revs))
                         blocked = self._get_blocked_revs(props, name, spath)
                         eligible -= set(Ranges(blocked))
@@ -237,6 +247,8 @@
             removed = old_revs - new_revs
             try:
                 all_revs = set(repos._get_node_revs(spath))
+                # TODO: also pass first_rev here, for getting smaller a set
+                #       (this is an optmization fix, result is already correct)
                 added &= all_revs
                 removed &= all_revs
             except NoSuchNode:

