diff --git a/mercurial/copies.py b/mercurial/copies.py
index ff7e0ca666e846085886b1c9cf0924d19cbfaac7_bWVyY3VyaWFsL2NvcGllcy5weQ==..8eed9de26077ad17abde0ccfeade3900aabb1c42_bWVyY3VyaWFsL2NvcGllcy5weQ== 100644
--- a/mercurial/copies.py
+++ b/mercurial/copies.py
@@ -230,6 +230,24 @@
     return revinfo
 
 
+def cached_is_ancestor(is_ancestor):
+    """return a cached version of is_ancestor"""
+    cache = {}
+
+    def _is_ancestor(anc, desc):
+        if anc > desc:
+            return False
+        elif anc == desc:
+            return True
+        key = (anc, desc)
+        ret = cache.get(key)
+        if ret is None:
+            ret = cache[key] = is_ancestor(anc, desc)
+        return ret
+
+    return _is_ancestor
+
+
 def _changesetforwardcopies(a, b, match):
     if a.rev() in (node.nullrev, b.rev()):
         return {}
@@ -238,7 +256,7 @@
     children = {}
 
     cl = repo.changelog
-    isancestor = cl.isancestorrev  # XXX we should had chaching to this.
+    isancestor = cached_is_ancestor(cl.isancestorrev)
     missingrevs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
     mrset = set(missingrevs)
     roots = set()