comparison mercurial/repair.py @ 30780:2603d04889e1

repair: copy non-revlog store files during upgrade The store contains more than just revlogs. This patch teaches the upgrade code to copy regular files as well. As the test changes demonstrate, the phaseroots file is now copied.
author Gregory Szorc <gregory.szorc@gmail.com>
date Thu, 24 Nov 2016 18:34:50 -0800
parents 38aa1ca97b6a
children f2c069bf78ee
comparison
equal deleted inserted replaced
30779:38aa1ca97b6a 30780:2603d04889e1
8 8
9 from __future__ import absolute_import 9 from __future__ import absolute_import
10 10
11 import errno 11 import errno
12 import hashlib 12 import hashlib
13 import stat
13 import tempfile 14 import tempfile
14 import time 15 import time
15 16
16 from .i18n import _ 17 from .i18n import _
17 from .node import short 18 from .node import short
797 '%s\n') % (crevcount, util.bytecount(cdstsize - csrcsize))) 798 '%s\n') % (crevcount, util.bytecount(cdstsize - csrcsize)))
798 799
799 ui.write(_('finished migrating %d total revisions; total change in store ' 800 ui.write(_('finished migrating %d total revisions; total change in store '
800 'size: %s\n') % (revcount, util.bytecount(dstsize - srcsize))) 801 'size: %s\n') % (revcount, util.bytecount(dstsize - srcsize)))
801 802
803 def _upgradefilterstorefile(srcrepo, dstrepo, requirements, path, mode, st):
804 """Determine whether to copy a store file during upgrade.
805
806 This function is called when migrating store files from ``srcrepo`` to
807 ``dstrepo`` as part of upgrading a repository.
808
809 Args:
810 srcrepo: repo we are copying from
811 dstrepo: repo we are copying to
812 requirements: set of requirements for ``dstrepo``
813 path: store file being examined
814 mode: the ``ST_MODE`` file type of ``path``
815 st: ``stat`` data structure for ``path``
816
817 Function should return ``True`` if the file is to be copied.
818 """
819 # Skip revlogs.
820 if path.endswith(('.i', '.d')):
821 return False
822 # Skip transaction related files.
823 if path.startswith('undo'):
824 return False
825 # Only copy regular files.
826 if mode != stat.S_IFREG:
827 return False
828 # Skip other skipped files.
829 if path in ('lock', 'fncache'):
830 return False
831
832 return True
833
834 def _upgradefinishdatamigration(ui, srcrepo, dstrepo, requirements):
835 """Hook point for extensions to perform additional actions during upgrade.
836
837 This function is called after revlogs and store files have been copied but
838 before the new store is swapped into the original location.
839 """
840
802 def _upgraderepo(ui, srcrepo, dstrepo, requirements, actions): 841 def _upgraderepo(ui, srcrepo, dstrepo, requirements, actions):
803 """Do the low-level work of upgrading a repository. 842 """Do the low-level work of upgrading a repository.
804 843
805 The upgrade is effectively performed as a copy between a source 844 The upgrade is effectively performed as a copy between a source
806 repository and a temporary destination repository. 845 repository and a temporary destination repository.
826 865
827 with dstrepo.transaction('upgrade') as tr: 866 with dstrepo.transaction('upgrade') as tr:
828 _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse, 867 _copyrevlogs(ui, srcrepo, dstrepo, tr, deltareuse,
829 'redeltamultibase' in actions) 868 'redeltamultibase' in actions)
830 869
831 # TODO copy non-revlog store files 870 # Now copy other files in the store directory.
871 for p, kind, st in srcrepo.store.vfs.readdir('', stat=True):
872 if not _upgradefilterstorefile(srcrepo, dstrepo, requirements,
873 p, kind, st):
874 continue
875
876 srcrepo.ui.write(_('copying %s\n') % p)
877 src = srcrepo.store.vfs.join(p)
878 dst = dstrepo.store.vfs.join(p)
879 util.copyfile(src, dst, copystat=True)
880
881 _upgradefinishdatamigration(ui, srcrepo, dstrepo, requirements)
832 882
833 ui.write(_('data fully migrated to temporary repository\n')) 883 ui.write(_('data fully migrated to temporary repository\n'))
834 884
835 backuppath = tempfile.mkdtemp(prefix='upgradebackup.', dir=srcrepo.path) 885 backuppath = tempfile.mkdtemp(prefix='upgradebackup.', dir=srcrepo.path)
836 backupvfs = scmutil.vfs(backuppath) 886 backupvfs = scmutil.vfs(backuppath)