Mercurial > hg
comparison mercurial/dirstate.py @ 50002:e358f6e0e50e
dirstate: do not write an empty dirstate just for backup
This will get in the way when we get more strict about holding the lock when
writing the dirstate.
Instead, we simply don't copy dirstate files around if there are None at backup
time.
A couple of tests are impacted they no longer need to backup such "empty"
dirstate.
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 14 Feb 2023 23:05:18 +0100 |
parents | 9313d8666a0f |
children | f4eef08575ce |
comparison
equal
deleted
inserted
replaced
50001:9313d8666a0f | 50002:e358f6e0e50e |
---|---|
1484 | 1484 |
1485 def _new_backup_data_filename(self, backupname): | 1485 def _new_backup_data_filename(self, backupname): |
1486 """return a filename to backup a data-file or None""" | 1486 """return a filename to backup a data-file or None""" |
1487 if not self._use_dirstate_v2: | 1487 if not self._use_dirstate_v2: |
1488 return None | 1488 return None |
1489 if self._map.docket.uuid is None: | |
1490 # not created yet, nothing to backup | |
1491 return None | |
1489 data_filename = self._map.docket.data_filename() | 1492 data_filename = self._map.docket.data_filename() |
1490 return data_filename, self.data_backup_filename(backupname) | 1493 return data_filename, self.data_backup_filename(backupname) |
1491 | 1494 |
1492 def backup_data_file(self, backupname): | 1495 def backup_data_file(self, backupname): |
1493 if not self._use_dirstate_v2: | 1496 if not self._use_dirstate_v2: |
1504 assert backupname != filename | 1507 assert backupname != filename |
1505 | 1508 |
1506 # use '_writedirstate' instead of 'write' to write changes certainly, | 1509 # use '_writedirstate' instead of 'write' to write changes certainly, |
1507 # because the latter omits writing out if transaction is running. | 1510 # because the latter omits writing out if transaction is running. |
1508 # output file will be used to create backup of dirstate at this point. | 1511 # output file will be used to create backup of dirstate at this point. |
1509 if self._dirty or not self._opener.exists(filename): | 1512 if self._dirty: |
1510 self._writedirstate( | 1513 self._writedirstate( |
1511 tr, | 1514 tr, |
1512 self._opener(filename, b"w", atomictemp=True, checkambig=True), | 1515 self._opener(filename, b"w", atomictemp=True, checkambig=True), |
1513 ) | 1516 ) |
1514 | 1517 |
1528 # failure, even if tr.writepending isn't invoked until the | 1531 # failure, even if tr.writepending isn't invoked until the |
1529 # end of this transaction | 1532 # end of this transaction |
1530 tr.registertmp(filename, location=b'plain') | 1533 tr.registertmp(filename, location=b'plain') |
1531 | 1534 |
1532 self._opener.tryunlink(backupname) | 1535 self._opener.tryunlink(backupname) |
1533 if True: | 1536 if self._opener.exists(filename): |
1534 # hardlink backup is okay because _writedirstate is always called | 1537 # hardlink backup is okay because _writedirstate is always called |
1535 # with an "atomictemp=True" file. | 1538 # with an "atomictemp=True" file. |
1536 util.copyfile( | 1539 util.copyfile( |
1537 self._opener.join(filename), | 1540 self._opener.join(filename), |
1538 self._opener.join(backupname), | 1541 self._opener.join(backupname), |
1555 def restorebackup(self, tr, backupname): | 1558 def restorebackup(self, tr, backupname): |
1556 '''Restore dirstate by backup file''' | 1559 '''Restore dirstate by backup file''' |
1557 # this "invalidate()" prevents "wlock.release()" from writing | 1560 # this "invalidate()" prevents "wlock.release()" from writing |
1558 # changes of dirstate out after restoring from backup file | 1561 # changes of dirstate out after restoring from backup file |
1559 self.invalidate() | 1562 self.invalidate() |
1563 o = self._opener | |
1564 if not o.exists(backupname): | |
1565 # there was no file backup, delete existing files | |
1566 filename = self._actualfilename(tr) | |
1567 data_file = None | |
1568 if self._use_dirstate_v2: | |
1569 data_file = self._map.docket.data_filename() | |
1570 if o.exists(filename): | |
1571 o.unlink(filename) | |
1572 if data_file is not None and o.exists(data_file): | |
1573 o.unlink(data_file) | |
1574 return | |
1560 filename = self._actualfilename(tr) | 1575 filename = self._actualfilename(tr) |
1561 o = self._opener | |
1562 data_pair = self.backup_data_file(backupname) | 1576 data_pair = self.backup_data_file(backupname) |
1563 if util.samefile(o.join(backupname), o.join(filename)): | 1577 if o.exists(filename) and util.samefile( |
1578 o.join(backupname), o.join(filename) | |
1579 ): | |
1564 o.unlink(backupname) | 1580 o.unlink(backupname) |
1565 else: | 1581 else: |
1566 o.rename(backupname, filename, checkambig=True) | 1582 o.rename(backupname, filename, checkambig=True) |
1567 | 1583 |
1568 if data_pair is not None: | 1584 if data_pair is not None: |
1575 o.rename(data_backup, target, checkambig=True) | 1591 o.rename(data_backup, target, checkambig=True) |
1576 | 1592 |
1577 def clearbackup(self, tr, backupname): | 1593 def clearbackup(self, tr, backupname): |
1578 '''Clear backup file''' | 1594 '''Clear backup file''' |
1579 o = self._opener | 1595 o = self._opener |
1580 data_backup = self.backup_data_file(backupname) | 1596 if o.exists(backupname): |
1581 o.unlink(backupname) | 1597 data_backup = self.backup_data_file(backupname) |
1582 | 1598 o.unlink(backupname) |
1583 if data_backup is not None: | 1599 if data_backup is not None: |
1584 o.unlink(data_backup[0]) | 1600 o.unlink(data_backup[0]) |
1585 | 1601 |
1586 def verify(self, m1, m2, p1, narrow_matcher=None): | 1602 def verify(self, m1, m2, p1, narrow_matcher=None): |
1587 """ | 1603 """ |
1588 check the dirstate contents against the parent manifest and yield errors | 1604 check the dirstate contents against the parent manifest and yield errors |
1589 """ | 1605 """ |