rollback: explicitly skip dirstate rollback when applicable
instead of letting the transaction logic overwrite the dirstate and then
overwrite that overwrite with a backup. We simply do not restore the dirstate
related file during the _playback call.
This open the way to removing the last dirstate guard usage.
--- a/mercurial/localrepo.py Thu Feb 16 00:26:24 2023 +0100
+++ b/mercurial/localrepo.py Thu Feb 16 10:00:59 2023 +0100
@@ -10,6 +10,7 @@
import functools
import os
import random
+import re
import sys
import time
import weakref
@@ -100,6 +101,8 @@
urlerr = util.urlerr
urlreq = util.urlreq
+RE_SKIP_DIRSTATE_ROLLBACK = re.compile(b"^(dirstate|narrowspec.dirstate).*")
+
# set of (path, vfs-location) tuples. vfs-location is:
# - 'plain for vfs relative paths
# - '' for svfs relative paths
@@ -2748,8 +2751,16 @@
self.destroying()
vfsmap = {b'plain': self.vfs, b'': self.svfs}
+ skip_journal_pattern = None
+ if not parentgone:
+ skip_journal_pattern = RE_SKIP_DIRSTATE_ROLLBACK
transaction.rollback(
- self.svfs, vfsmap, b'undo', ui.warn, checkambigfiles=_cachedfiles
+ self.svfs,
+ vfsmap,
+ b'undo',
+ ui.warn,
+ checkambigfiles=_cachedfiles,
+ skip_journal_pattern=skip_journal_pattern,
)
bookmarksvfs = bookmarks.bookmarksvfs(self)
if bookmarksvfs.exists(b'undo.bookmarks'):
--- a/mercurial/transaction.py Thu Feb 16 00:26:24 2023 +0100
+++ b/mercurial/transaction.py Thu Feb 16 10:00:59 2023 +0100
@@ -738,7 +738,14 @@
)
-def rollback(opener, vfsmap, file, report, checkambigfiles=None):
+def rollback(
+ opener,
+ vfsmap,
+ file,
+ report,
+ checkambigfiles=None,
+ skip_journal_pattern=None,
+):
"""Rolls back the transaction contained in the given file
Reads the entries in the specified file, and the corresponding
@@ -783,6 +790,9 @@
line = line[:-1]
l, f, b, c = line.split(b'\0')
backupentries.append((l, f, b, bool(c)))
+ if skip_journal_pattern is not None:
+ keep = lambda x: not skip_journal_pattern.match(x[1])
+ backupentries = [x for x in backupentries if keep(x)]
_playback(
file,