# HG changeset patch # User Pierre-Yves David # Date 1677754038 -3600 # Node ID a6e0b7d4ae9dcf0516d62258ddc0ba84dab641df # Parent fa04407bda7a4f225d01fadf769507dbf87fc930 dirstate: write the `branch` as part of the transaction if any Bypassing the transaction means we could get out of sync with the dirstatemap content. The branch is stil written right away if no transaction is around, but at least it no longer bypass the transaction. Actual caller of this still need to be updated. diff -r fa04407bda7a -r a6e0b7d4ae9d hgext/git/dirstate.py --- a/hgext/git/dirstate.py Thu Mar 02 11:46:51 2023 +0100 +++ b/hgext/git/dirstate.py Thu Mar 02 11:47:18 2023 +0100 @@ -389,7 +389,7 @@ # TODO: should this be added to the dirstate interface? self._plchangecallbacks[category] = callback - def setbranch(self, branch): + def setbranch(self, branch, transaction=None): raise error.Abort( b'git repos do not support branches. try using bookmarks' ) diff -r fa04407bda7a -r a6e0b7d4ae9d mercurial/dirstate.py --- a/mercurial/dirstate.py Thu Mar 02 11:46:51 2023 +0100 +++ b/mercurial/dirstate.py Thu Mar 02 11:47:18 2023 +0100 @@ -27,6 +27,7 @@ policy, pycompat, scmutil, + txnutil, util, ) @@ -416,10 +417,19 @@ @repocache(b'branch') def _branch(self): + f = None + data = b'' try: - return self._opener.read(b"branch").strip() or b"default" + f, mode = txnutil.trypending(self._root, self._opener, b'branch') + data = f.read().strip() except FileNotFoundError: + pass + finally: + if f is not None: + f.close() + if not data: return b"default" + return data @property def _pl(self): @@ -611,11 +621,22 @@ fold_p2 = oldp2 != nullid and p2 == nullid return self._map.setparents(p1, p2, fold_p2=fold_p2) - def setbranch(self, branch): + def setbranch(self, branch, transaction=None): self.__class__._branch.set(self, encoding.fromlocal(branch)) + if transaction is not None: + self._setup_tr_abort(transaction) + transaction.addfilegenerator( + b'dirstate-3-branch%s' % self._tr_key_suffix, + (b'branch',), + self._write_branch, + location=b'plain', + post_finalize=True, + ) + return + vfs = self._opener with vfs(b'branch', b'w', atomictemp=True, checkambig=True) as f: - f.write(self._branch + b'\n') + self._write_branch(f) # make sure filecache has the correct stat info for _branch after # replacing the underlying file # @@ -625,6 +646,9 @@ if ce: ce.refresh() + def _write_branch(self, file_obj): + file_obj.write(self._branch + b'\n') + def invalidate(self): """Causes the next access to reread the dirstate. diff -r fa04407bda7a -r a6e0b7d4ae9d mercurial/interfaces/dirstate.py --- a/mercurial/interfaces/dirstate.py Thu Mar 02 11:46:51 2023 +0100 +++ b/mercurial/interfaces/dirstate.py Thu Mar 02 11:47:18 2023 +0100 @@ -123,7 +123,7 @@ See localrepo.setparents() """ - def setbranch(branch): + def setbranch(branch, transaction=None): pass def invalidate():