Марк Драго является правильным , что Mercurial записывает свои собственные файлы в строгом порядке для поддержания целостности. Тем не менее, это только целостность по отношению к другим Mercurial клиентам. Конструкция блокировки в Mercurial позволяет одному процессу Mercurial создать новый коммит, записав файлы в следующем порядке:
- filelogs (содержит сжатые дельты для всех ревизий данного файла)
- манифест (содержит указатели на журналы файлов, связанные с данным набором изменений)
- список изменений (содержит метаданные и указатель на манифест для набора изменений)
в то время как другие процессы Mercurial будут читать файлы в этом порядке
- 1018 * изменения *
- 1020 * манифест *
- filelogs
Таким образом, читатель не увидит ссылку на новые данные файлового журнала, поскольку журнал изменений обновляется последним в элементарной операции (переименование, которое POSIX требует, чтобы оно было атомарным).
Программа резервного копирования не будет знать правильный порядок чтения файлов Mercurial, поэтому она может прочитать файл журнала до его обновления Mercurial и затем прочитать манифест после обновлено:
rsync
читает .hg/store/data/foo.i
hg
пишет .hg/store/data/foo.i
hg
пишет .hg/store/00manifest.i
hg
пишет .hg/store/00changelog.i
rsync
читает .hg/store/00manifest.i
rsync
читает .hg/store/00changelog.i
Результатом является резервная копия с журналом изменений, который указывает на манифест, который указывает на несуществующую ревизию файлового журнала - поврежденный репозиторий. Запуск hg verify
в таком хранилище обнаружит эту ситуацию:
checking changesets
checking manifests
crosschecking files in changesets and manifests
checking files
foo@1: f57bae649f6e in manifests not found
1 files, 2 changesets, 1 total revisions
1 integrity errors encountered!
(first damaged changeset appears to be 1)
Это говорит о том, что манифест ревизии 1 относится к ревизии f57bae649f6e
файла foo
, которая не может быть найдена. Эту ситуацию можно исправить, сделав клон, исключающий плохую ревизию 1:
$ hg clone -r 0 . ../repo-fixed
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd ../repo-fixed
$ hg verify
checking changesets
checking manifests
crosschecking files in changesets and manifests
checking files
1 files, 1 changesets, 1 total revisions
В общем, не так уж и плохо, если вы используете обычную программу резервного копирования для резервного копирования ваших хранилищ Mercurial. Просто имейте в виду, что вам может потребоваться восстановить поврежденный репозиторий после восстановления из резервной копии. Потерянный вами набор изменений, скорее всего, останется на компьютере разработчика, и он сможет отправить его снова после восстановления восстановленного репозитория. В Mercurial wiki есть больше информации о том, как исправить повреждение хранилища .
Совершенно безопасный способ резервного копирования хранилища - это, конечно, использование hg clone
, но может быть нецелесообразно интегрировать это с общей стратегией резервного копирования.