repo: skip invalidation of changelog if it has 'delayed' changes (API)
authorMartin von Zweigbergk <martinvonz@google.com>
Wed, 19 Jul 2017 13:34:06 -0700
changeset 33706 01a1c4e66816
parent 33705 73fd395ee29e
child 33707 36d216dcae6a
repo: skip invalidation of changelog if it has 'delayed' changes (API) The changelog object can store recently added revisions in memory until the transaction is committed. We don't want to lose those changes even if repo.invalidate(clearfilecache=True), so let's skip the changelog when it has such 'delayed' changes. Differential Revision: https://phab.mercurial-scm.org/D152
mercurial/localrepo.py
tests/test-context.py
--- a/mercurial/localrepo.py	Sun Aug 06 17:47:41 2017 -0700
+++ b/mercurial/localrepo.py	Wed Jul 19 13:34:06 2017 -0700
@@ -1461,6 +1461,13 @@
             # dirstate is invalidated separately in invalidatedirstate()
             if k == 'dirstate':
                 continue
+            if (k == 'changelog' and
+                self.currenttransaction() and
+                self.changelog._delayed):
+                # The changelog object may store unwritten revisions. We don't
+                # want to lose them.
+                # TODO: Solve the problem instead of working around it.
+                continue
 
             if clearfilecache:
                 del self._filecache[k]
--- a/tests/test-context.py	Sun Aug 06 17:47:41 2017 -0700
+++ b/tests/test-context.py	Wed Jul 19 13:34:06 2017 -0700
@@ -179,3 +179,14 @@
             print('data mismatch')
     except Exception as ex:
         print('cannot read data: %r' % ex)
+
+with repo.wlock(), repo.lock(), repo.transaction('test'):
+    with open(b'4', 'wb') as f:
+        f.write(b'4')
+    repo.dirstate.normal('4')
+    repo.commit('4')
+    revsbefore = len(repo.changelog)
+    repo.invalidate(clearfilecache=True)
+    revsafter = len(repo.changelog)
+    if revsbefore != revsafter:
+        print('changeset lost by repo.invalidate()')