Mercurial > public > mercurial-scm > hg
comparison mercurial/transaction.py @ 39686:3d22aef3ecd5
transaction: make entries a private attribute (API)
This attribute is tracking changes to append-only files. It is
an implementation detail and should not be exposed as part of
the public interface.
But code in repair was accessing it, so it seemingly does belong
as part of the public API. But that code in repair is making
assumptions about how storage works and is grossly wrong when
alternate storage backends are in play. We'll need some kind of
"strip" API at the storage layer that knows how to handle things
in a storage-agnostic manner. I don't think accessing a private
attribute on the transaction is any worse than what this code
is already doing. So I'm fine with violating the abstraction for
transactions.
And with this change, all per-instance attributes on transaction
have been made private except for "changes" and "hookargs." Both
are used by multiple consumers and look like they need to be
part of the public interface.
.. api::
Various attributes of ``transaction.transaction`` are now ``_``
prefixed to indicate they shouldn't be used by external
consumers.
Differential Revision: https://phab.mercurial-scm.org/D4634
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Mon, 17 Sep 2018 16:29:12 -0700 |
parents | 4024c363cd33 |
children | aca09df32819 |
comparison
equal
deleted
inserted
replaced
39685:4024c363cd33 | 39686:3d22aef3ecd5 |
---|---|
127 # a map to access file in various {location -> vfs} | 127 # a map to access file in various {location -> vfs} |
128 vfsmap = vfsmap.copy() | 128 vfsmap = vfsmap.copy() |
129 vfsmap[''] = opener # set default value | 129 vfsmap[''] = opener # set default value |
130 self._vfsmap = vfsmap | 130 self._vfsmap = vfsmap |
131 self._after = after | 131 self._after = after |
132 self.entries = [] | 132 self._entries = [] |
133 self._map = {} | 133 self._map = {} |
134 self._journal = journalname | 134 self._journal = journalname |
135 self._undoname = undoname | 135 self._undoname = undoname |
136 self._queue = [] | 136 self._queue = [] |
137 # A callback to validate transaction content before closing it. | 137 # A callback to validate transaction content before closing it. |
228 | 228 |
229 def _addentry(self, file, offset, data): | 229 def _addentry(self, file, offset, data): |
230 """add a append-only entry to memory and on-disk state""" | 230 """add a append-only entry to memory and on-disk state""" |
231 if file in self._map or file in self._backupmap: | 231 if file in self._map or file in self._backupmap: |
232 return | 232 return |
233 self.entries.append((file, offset, data)) | 233 self._entries.append((file, offset, data)) |
234 self._map[file] = len(self.entries) - 1 | 234 self._map[file] = len(self._entries) - 1 |
235 # add enough data to the journal to do the truncate | 235 # add enough data to the journal to do the truncate |
236 self._file.write("%s\0%d\n" % (file, offset)) | 236 self._file.write("%s\0%d\n" % (file, offset)) |
237 self._file.flush() | 237 self._file.flush() |
238 | 238 |
239 @active | 239 @active |
350 return any | 350 return any |
351 | 351 |
352 @active | 352 @active |
353 def find(self, file): | 353 def find(self, file): |
354 if file in self._map: | 354 if file in self._map: |
355 return self.entries[self._map[file]] | 355 return self._entries[self._map[file]] |
356 if file in self._backupmap: | 356 if file in self._backupmap: |
357 return self._backupentries[self._backupmap[file]] | 357 return self._backupentries[self._backupmap[file]] |
358 return None | 358 return None |
359 | 359 |
360 @active | 360 @active |
365 ''' | 365 ''' |
366 | 366 |
367 if file not in self._map: | 367 if file not in self._map: |
368 raise KeyError(file) | 368 raise KeyError(file) |
369 index = self._map[file] | 369 index = self._map[file] |
370 self.entries[index] = (file, offset, data) | 370 self._entries[index] = (file, offset, data) |
371 self._file.write("%s\0%d\n" % (file, offset)) | 371 self._file.write("%s\0%d\n" % (file, offset)) |
372 self._file.flush() | 372 self._file.flush() |
373 | 373 |
374 @active | 374 @active |
375 def nest(self, name=r'<unnamed>'): | 375 def nest(self, name=r'<unnamed>'): |
484 if not c: | 484 if not c: |
485 raise | 485 raise |
486 # Abort may be raise by read only opener | 486 # Abort may be raise by read only opener |
487 self._report("couldn't remove %s: %s\n" | 487 self._report("couldn't remove %s: %s\n" |
488 % (vfs.join(b), inst)) | 488 % (vfs.join(b), inst)) |
489 self.entries = [] | 489 self._entries = [] |
490 self._writeundo() | 490 self._writeundo() |
491 if self._after: | 491 if self._after: |
492 self._after() | 492 self._after() |
493 self._after = None # Help prevent cycles. | 493 self._after = None # Help prevent cycles. |
494 if self._opener.isfile(self._backupjournal): | 494 if self._opener.isfile(self._backupjournal): |
562 self._usages = 0 | 562 self._usages = 0 |
563 self._file.close() | 563 self._file.close() |
564 self._backupsfile.close() | 564 self._backupsfile.close() |
565 | 565 |
566 try: | 566 try: |
567 if not self.entries and not self._backupentries: | 567 if not self._entries and not self._backupentries: |
568 if self._backupjournal: | 568 if self._backupjournal: |
569 self._opener.unlink(self._backupjournal) | 569 self._opener.unlink(self._backupjournal) |
570 if self._journal: | 570 if self._journal: |
571 self._opener.unlink(self._journal) | 571 self._opener.unlink(self._journal) |
572 return | 572 return |
577 for cat in sorted(self._abortcallback): | 577 for cat in sorted(self._abortcallback): |
578 self._abortcallback[cat](self) | 578 self._abortcallback[cat](self) |
579 # Prevent double usage and help clear cycles. | 579 # Prevent double usage and help clear cycles. |
580 self._abortcallback = None | 580 self._abortcallback = None |
581 _playback(self._journal, self._report, self._opener, | 581 _playback(self._journal, self._report, self._opener, |
582 self._vfsmap, self.entries, self._backupentries, | 582 self._vfsmap, self._entries, self._backupentries, |
583 False, checkambigfiles=self._checkambigfiles) | 583 False, checkambigfiles=self._checkambigfiles) |
584 self._report(_("rollback completed\n")) | 584 self._report(_("rollback completed\n")) |
585 except BaseException: | 585 except BaseException: |
586 self._report(_("rollback failed - please run hg recover\n")) | 586 self._report(_("rollback failed - please run hg recover\n")) |
587 finally: | 587 finally: |