diff hgext/histedit.py @ 51795:73476a9e5ced stable

histedit: create state and acquire locks earlier This makes chistedit (histedit with curses UI) not write any files inside repo without wlock. It also makes sense to wrap the entire process of preparing commands inside the curses UI inside locks because we don't want anything else to touch wdir or repo during this time.
author Anton Shestakov <av6@dwimlabs.net>
date Thu, 08 Aug 2024 17:28:38 +0400
parents 6ec4c745c598
children 454feddab720
line wrap: on
line diff
--- a/hgext/histedit.py	Tue Aug 06 22:51:41 2024 +0200
+++ b/hgext/histedit.py	Thu Aug 08 17:28:38 2024 +0400
@@ -1714,7 +1714,7 @@
             ch = encoding.strtolocal(stdscr.getkey())
 
 
-def _chistedit(ui, repo, freeargs, opts):
+def _chistedit(ui, repo, state, freeargs, opts):
     """interactively edit changeset history via a curses interface
 
     Provides a ncurses interface to histedit. Press ? in chistedit mode
@@ -1774,7 +1774,7 @@
                 for r in rules:
                     fp.write(r)
                 opts[b'commands'] = fp.name
-            return _texthistedit(ui, repo, freeargs, opts)
+            return _texthistedit(ui, repo, state, freeargs, opts)
     except KeyboardInterrupt:
         pass
     return -1
@@ -1913,20 +1913,20 @@
     """
     opts = pycompat.byteskwargs(opts)
 
-    # kludge: _chistedit only works for starting an edit, not aborting
-    # or continuing, so fall back to regular _texthistedit for those
-    # operations.
-    if ui.interface(b'histedit') == b'curses' and _getgoal(opts) == goalnew:
-        return _chistedit(ui, repo, freeargs, opts)
-    return _texthistedit(ui, repo, freeargs, opts)
-
-
-def _texthistedit(ui, repo, freeargs, opts):
     state = histeditstate(repo)
     with repo.wlock() as wlock, repo.lock() as lock:
         state.wlock = wlock
         state.lock = lock
-        _histedit(ui, repo, state, freeargs, opts)
+        # kludge: _chistedit only works for starting an edit, not aborting
+        # or continuing, so fall back to regular _texthistedit for those
+        # operations.
+        if ui.interface(b'histedit') == b'curses' and _getgoal(opts) == goalnew:
+            return _chistedit(ui, repo, state, freeargs, opts)
+        return _texthistedit(ui, repo, state, freeargs, opts)
+
+
+def _texthistedit(ui, repo, state, freeargs, opts):
+    _histedit(ui, repo, state, freeargs, opts)
 
 
 goalcontinue = b'continue'