histedit: create state and acquire locks earlier stable
authorAnton Shestakov <av6@dwimlabs.net>
Thu, 08 Aug 2024 17:28:38 +0400
branchstable
changeset 51795 73476a9e5ced
parent 51794 bd490cdf764a
child 51796 8f629783b8ae
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.
hgext/histedit.py
--- 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'