##// END OF EJS Templates
dirstate-v2: backup the data file during the transaction (issue6730)...
marmoute -
r50362:0705afae stable
parent child Browse files
Show More
@@ -31,6 +31,7 b' from . import ('
31 )
31 )
32
32
33 from .dirstateutils import (
33 from .dirstateutils import (
34 docket as docketmod,
34 timestamp,
35 timestamp,
35 )
36 )
36
37
@@ -1433,6 +1434,27 b' class dirstate:'
1433 else:
1434 else:
1434 return self._filename
1435 return self._filename
1435
1436
1437 def data_backup_filename(self, backupname):
1438 if not self._use_dirstate_v2:
1439 return None
1440 return backupname + b'.v2-data'
1441
1442 def _new_backup_data_filename(self, backupname):
1443 """return a filename to backup a data-file or None"""
1444 if not self._use_dirstate_v2:
1445 return None
1446 data_filename = self._map.docket.data_filename()
1447 return data_filename, self.data_backup_filename(backupname)
1448
1449 def backup_data_file(self, backupname):
1450 if not self._use_dirstate_v2:
1451 return None
1452 docket = docketmod.DirstateDocket.parse(
1453 self._opener.read(backupname),
1454 self._nodeconstants,
1455 )
1456 return self.data_backup_filename(backupname), docket.data_filename()
1457
1436 def savebackup(self, tr, backupname):
1458 def savebackup(self, tr, backupname):
1437 '''Save current dirstate into backup file'''
1459 '''Save current dirstate into backup file'''
1438 filename = self._actualfilename(tr)
1460 filename = self._actualfilename(tr)
@@ -1472,6 +1494,19 b' class dirstate:'
1472 self._opener.join(backupname),
1494 self._opener.join(backupname),
1473 hardlink=True,
1495 hardlink=True,
1474 )
1496 )
1497 data_pair = self._new_backup_data_filename(backupname)
1498 if data_pair is not None:
1499 data_filename, bck_data_filename = data_pair
1500 util.copyfile(
1501 self._opener.join(data_filename),
1502 self._opener.join(bck_data_filename),
1503 hardlink=True,
1504 )
1505 if tr is not None:
1506 # ensure that pending file written above is unlinked at
1507 # failure, even if tr.writepending isn't invoked until the
1508 # end of this transaction
1509 tr.registertmp(bck_data_filename, location=b'plain')
1475
1510
1476 def restorebackup(self, tr, backupname):
1511 def restorebackup(self, tr, backupname):
1477 '''Restore dirstate by backup file'''
1512 '''Restore dirstate by backup file'''
@@ -1480,14 +1515,29 b' class dirstate:'
1480 self.invalidate()
1515 self.invalidate()
1481 filename = self._actualfilename(tr)
1516 filename = self._actualfilename(tr)
1482 o = self._opener
1517 o = self._opener
1518 data_pair = self.backup_data_file(backupname)
1483 if util.samefile(o.join(backupname), o.join(filename)):
1519 if util.samefile(o.join(backupname), o.join(filename)):
1484 o.unlink(backupname)
1520 o.unlink(backupname)
1485 else:
1521 else:
1486 o.rename(backupname, filename, checkambig=True)
1522 o.rename(backupname, filename, checkambig=True)
1487
1523
1524 if data_pair is not None:
1525 data_backup, target = data_pair
1526 if o.exists(target) and util.samefile(
1527 o.join(data_backup), o.join(target)
1528 ):
1529 o.unlink(data_backup)
1530 else:
1531 o.rename(data_backup, target, checkambig=True)
1532
1488 def clearbackup(self, tr, backupname):
1533 def clearbackup(self, tr, backupname):
1489 '''Clear backup file'''
1534 '''Clear backup file'''
1490 self._opener.unlink(backupname)
1535 o = self._opener
1536 data_backup = self.backup_data_file(backupname)
1537 o.unlink(backupname)
1538
1539 if data_backup is not None:
1540 o.unlink(data_backup[0])
1491
1541
1492 def verify(self, m1, m2):
1542 def verify(self, m1, m2):
1493 """check the dirstate content again the parent manifest and yield errors"""
1543 """check the dirstate content again the parent manifest and yield errors"""
@@ -2618,16 +2618,23 b' class localrepository:'
2618 return tr
2618 return tr
2619
2619
2620 def _journalfiles(self):
2620 def _journalfiles(self):
2621 return (
2621 first = (
2622 (self.svfs, b'journal'),
2622 (self.svfs, b'journal'),
2623 (self.svfs, b'journal.narrowspec'),
2623 (self.svfs, b'journal.narrowspec'),
2624 (self.vfs, b'journal.narrowspec.dirstate'),
2624 (self.vfs, b'journal.narrowspec.dirstate'),
2625 (self.vfs, b'journal.dirstate'),
2625 (self.vfs, b'journal.dirstate'),
2626 )
2627 middle = []
2628 dirstate_data = self.dirstate.data_backup_filename(b'journal.dirstate')
2629 if dirstate_data is not None:
2630 middle.append((self.vfs, dirstate_data))
2631 end = (
2626 (self.vfs, b'journal.branch'),
2632 (self.vfs, b'journal.branch'),
2627 (self.vfs, b'journal.desc'),
2633 (self.vfs, b'journal.desc'),
2628 (bookmarks.bookmarksvfs(self), b'journal.bookmarks'),
2634 (bookmarks.bookmarksvfs(self), b'journal.bookmarks'),
2629 (self.svfs, b'journal.phaseroots'),
2635 (self.svfs, b'journal.phaseroots'),
2630 )
2636 )
2637 return first + tuple(middle) + end
2631
2638
2632 def undofiles(self):
2639 def undofiles(self):
2633 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
2640 return [(vfs, undoname(x)) for vfs, x in self._journalfiles()]
@@ -243,11 +243,5 b' We should make sure all of it (docket + '
243 repository tip rolled back to revision 1 (undo commit)
243 repository tip rolled back to revision 1 (undo commit)
244 working directory now based on revision 1
244 working directory now based on revision 1
245
245
246 #if dirstate-v1
247 $ hg status
246 $ hg status
248 A foo
247 A foo
249 #else
250 $ hg status
251 abort: $ENOENT$: '*/.hg/dirstate.*' (glob) (known-bad-output !)
252 [255]
253 #endif
General Comments 0
You need to be logged in to leave comments. Login now