mercurial/dirstate.py
changeset 50147 0be70c7b609c
parent 50146 8ba5028de859
child 50148 b583988c6c23
equal deleted inserted replaced
50146:8ba5028de859 50147:0be70c7b609c
   211         """Wrap a status operation
   211         """Wrap a status operation
   212 
   212 
   213         This context is not mutally exclusive with the `changing_*` context. It
   213         This context is not mutally exclusive with the `changing_*` context. It
   214         also do not warrant for the `wlock` to be taken.
   214         also do not warrant for the `wlock` to be taken.
   215 
   215 
   216         If the wlock is taken, this context will (in the future) behave in a
   216         If the wlock is taken, this context will behave in a simple way, and
   217         simple way, and ensure the data are scheduled for write when leaving
   217         ensure the data are scheduled for write when leaving the top level
   218         the top level context.
   218         context.
   219 
   219 
   220         If the lock is not taken, it will only warrant that the data are either
   220         If the lock is not taken, it will only warrant that the data are either
   221         committed (written) and rolled back (invalidated) when exiting the top
   221         committed (written) and rolled back (invalidated) when exiting the top
   222         level context. The write/invalidate action must be performed by the
   222         level context. The write/invalidate action must be performed by the
   223         wrapped code.
   223         wrapped code.
   233         D: try to take the w-lock (this will invalidate the changes if they were raced)
   233         D: try to take the w-lock (this will invalidate the changes if they were raced)
   234         E0: if dirstate changed on disk → discard change (done by dirstate internal)
   234         E0: if dirstate changed on disk → discard change (done by dirstate internal)
   235         E1: elif lock was acquired → write the changes
   235         E1: elif lock was acquired → write the changes
   236         E2: else → discard the changes
   236         E2: else → discard the changes
   237         """
   237         """
       
   238         has_lock = repo.currentwlock() is not None
   238         is_changing = self.is_changing_any
   239         is_changing = self.is_changing_any
   239         has_tr = repo.currenttransaction is not None
   240         tr = repo.currenttransaction()
       
   241         has_tr = tr is not None
   240         nested = bool(self._running_status)
   242         nested = bool(self._running_status)
   241 
   243 
   242         first_and_alone = not (is_changing or has_tr or nested)
   244         first_and_alone = not (is_changing or has_tr or nested)
   243 
   245 
   244         # enforce no change happened outside of a proper context.
   246         # enforce no change happened outside of a proper context.
   245         if first_and_alone and self._dirty:
   247         if first_and_alone and self._dirty:
   246             has_tr = repo.currenttransaction() is not None
   248             has_tr = repo.currenttransaction() is not None
   247             if not has_tr and self._changing_level == 0 and self._dirty:
   249             if not has_tr and self._changing_level == 0 and self._dirty:
   248                 msg = "entering a status context, but dirstate is already dirty"
   250                 msg = "entering a status context, but dirstate is already dirty"
   249                 raise error.ProgrammingError(msg)
   251                 raise error.ProgrammingError(msg)
       
   252 
       
   253         should_write = has_lock and not (nested or is_changing)
   250 
   254 
   251         self._running_status += 1
   255         self._running_status += 1
   252         try:
   256         try:
   253             yield
   257             yield
   254         except Exception:
   258         except Exception:
   255             self.invalidate()
   259             self.invalidate()
   256             raise
   260             raise
   257         finally:
   261         finally:
   258             self._running_status -= 1
   262             self._running_status -= 1
   259             if self._invalidated_context:
   263             if self._invalidated_context:
       
   264                 should_write = False
   260                 self.invalidate()
   265                 self.invalidate()
       
   266 
       
   267         if should_write:
       
   268             assert repo.currenttransaction() is tr
       
   269             self.write(tr)
   261 
   270 
   262     @contextlib.contextmanager
   271     @contextlib.contextmanager
   263     @check_invalidated
   272     @check_invalidated
   264     def _changing(self, repo, change_type):
   273     def _changing(self, repo, change_type):
   265         if repo.currentwlock() is None:
   274         if repo.currentwlock() is None: