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 """ |