diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1313,11 +1313,19 @@ class lrucachedict(object):
 
     def copy(self):
         result = lrucachedict(self._capacity)
+
+        # We copy entries by iterating in oldest-to-newest order so the copy
+        # has the correct ordering.
+
+        # Find the first non-empty entry.
         n = self._head.prev
-        # Iterate in oldest-to-newest order, so the copy has the right ordering
+        while n.key is _notset and n is not self._head:
+            n = n.prev
+
         for i in range(len(self._cache)):
             result[n.key] = n.value
             n = n.prev
+
         return result
 
     def _movetohead(self, node):
diff --git a/tests/test-lrucachedict.py b/tests/test-lrucachedict.py
--- a/tests/test-lrucachedict.py
+++ b/tests/test-lrucachedict.py
@@ -68,12 +68,28 @@ class testlrucachedict(unittest.TestCase
         dc = d.copy()
 
         self.assertEqual(len(dc), 2)
-        # TODO this fails
-        return
         for key in ('a', 'b'):
             self.assertIn(key, dc)
             self.assertEqual(dc[key], 'v%s' % key)
 
+        self.assertEqual(len(d), 2)
+        for key in ('a', 'b'):
+            self.assertIn(key, d)
+            self.assertEqual(d[key], 'v%s' % key)
+
+        d['c'] = 'vc'
+        del d['b']
+        dc = d.copy()
+        self.assertEqual(len(dc), 2)
+        for key in ('a', 'c'):
+            self.assertIn(key, dc)
+            self.assertEqual(dc[key], 'v%s' % key)
+
+    def testcopyempty(self):
+        d = util.lrucachedict(4)
+        dc = d.copy()
+        self.assertEqual(len(dc), 0)
+
     def testcopyfull(self):
         d = util.lrucachedict(4)
         d['a'] = 'va'