StupidBeauty
Read times:2353Posted at:Mon May 26 05:33:29 2014
- no title specified

水银mercurial文档翻译:应对仓库和目录状态损坏的情况,Dealing with Repository and Dirstate Corruption

4. 仓库损坏

这种损坏是与项目的历史记录相关的,尤其是与 .hg/store 中的文件相关。这种损坏可能由多种原因引起,大部分情况下是由用户的错误操作(比如,删除其文件名中包含'foo.c'的所有文件)引起的。例如:

$ hg verify

checking changesets

checking manifests

crosschecking files in changesets and manifests

checking files

1213 files, 8591 changesets, 17158 total revisions

$ rm .hg/store/data/mercurial/error.py.i # 注意,做了错事了!

$ hg verify

checking changesets

checking manifests

crosschecking files in changesets and manifests

checking files

data/mercurial/error.py.i@7633: missing revlog!

7633: empty or missing mercurial/error.py

mercurial/error.py@7633: f6aad9f78a08 in manifests not found

mercurial/error.py@7636: 4fb29207f327 in manifests not found

mercurial/error.py@7637: 3bfff9613e8b in manifests not found

mercurial/error.py@7640: 40ee894622ad in manifests not found

mercurial/error.py@7641: e640820306d6 in manifests not found

mercurial/error.py@7643: f43c616251f5 in manifests not found

mercurial/error.py@7644: 455d738b74c7 in manifests not found

mercurial/error.py@7646: a3128b43b03f in manifests not found

mercurial/error.py@7947: b4a8b72bfa1c in manifests not found

mercurial/error.py@8144: 1f996809c441 in manifests not found

mercurial/error.py@8225: e1537136a8d0 in manifests not found

mercurial/error.py@8226: 5f91269779c0 in manifests not found

mercurial/error.py@8227: 6706abc98ab2 in manifests not found

1213 files, 8591 changesets, 17145 total revisions

15 integrity errors encountered!

(first damaged changeset appears to be 7633)

在尝试修复仓库之前,一定要做一次备份!

4.1. 基本修复

在这个例子中,我们损坏了仓库中从修订版本7633(注意看输出中的最后一行)开始的记录。好在Mercurial 中对于历史信息都是采用追加的形式来记录的,所以,我们可以使用以下命令来将仓库恢复到出问题之前的那个点:

$ cd ..

$ hg clone -r 7632 damage fixed

requesting all changes

adding changesets

adding manifests

adding file changes

added 7633 changesets with 14944 changes to 1126 files

updating to branch default

964 files updated, 0 files merged, 0 files removed, 0 files unresolved

$ cd fixed

$ hg verify

checking changesets

checking manifests

crosschecking files in changesets and manifests

checking files

1126 files, 7633 changesets, 14944 total revisions

4.2. 利用一些已知正常的源代码文件来重新构建仓库

我们还可以使用'pull -r'来渐进式地尝试每次将更大的一组修订集拉取到一个包含有其中某些被丢失的文件的修订记录的仓库中去。还可能可以从某个备份仓库中将这里被损坏的变更记录(revlog)文件的完整副本复制出来。

4.3. 重新构造那些丢失的变更记录文件(revlogs)

在少数情况下,只有某个包含着单条变更记录的记录文件被损坏。如果妳还在别处有着那个变更文件的 精确副本 exact copy )的话(假设它位于 mybackuplocation ,我们稍后将用到),那么,这种情况就狠容易手动重新构造。举个例子,假设有一个仓库,名为"broken",其中根目录的变更记录文件"f2.i"已经丢失

$ hg verify

checking changesets

checking manifests

crosschecking files in changesets and manifests

checking files

data/f2.i@1: missing revlog!

1: empty or missing f2

f2@1: 5266937d3e5f in manifests not found

3 files, 3 changesets, 2 total revisions

3 integrity errors encountered!

(first damaged changeset appears to be 1)

注意"@1"表示所丢失的变更记录文件是在变更集(changeset)1中被引用的。为了重新构造这个文件,我们需要创建一个新的仓库,以重新制造出那次提交过程中的条件。(在复制仓库(cloning)时,妳可能需要修改复制命令,以确保新的仓库与已有的仓库具有相同的 仓库格式 )

$ cd ..

$ hg clone -r 0 broken fix # 比被损坏的变更集的编号小1

$ cd fix

$ cp <mybackuplocation>/f2 f2

$ hg add f2

$ hg ci -m fix f2

现在,我们已经创建了一个新的"f2.i",其中包含着单条变更记录,并且被标记为属于变更集1.现在我们可以将这个文件复制到被损坏的仓库中去了:

$ cp .hg/store/data/f2.i ../broken/.hg/store/data/f2.i

$ cd ../broken

$ hg verify

checking changesets

checking manifests

crosschecking files in changesets and manifests

checking files

3 files, 3 changesets, 3 total revisions

妳可能需要编辑 .hg/store/fncache 以让verify命令知道妳在这里重新引入的文件的存在。

妳也可以使用这种操作来修复变更记录文件中的变更记录。

4.4. 修复那种引用了某个补丁队列中的索引文件的变更集

如果想要修复的变更记录是某个已被应用的补丁队列中的一部分,那么,修复过程将会更加复杂,因为,从备份仓库中复制出来的索引文件将会引用到错误的变更集:

$ hg verify

checking changesets

checking manifests

crosschecking files in changesets and manifests

checking files

data/f2.i@3: missing revlog!

f2@?: rev 0 points to unexpected changeset 2

(expected 3)

3 files, 3 changesets, 2 total revisions

2 integrity errors encountered!

(first damaged changeset appears to be 3)

对于这种情况,可以使用以下Python 脚本来直接编辑索引文件中的引用目标,以便修复:

import struct

from mercurial import revlog

f = open('.hg/store/data/f2.i', 'r+')

raw = f.read()

unpacked_index = list(struct.unpack(revlog.indexformatng, raw[:64]))

unpacked_index[4] = 3 # 使用妳自己的“预期的变更集编号”替换这里的值

new_raw = struct.pack(revlog.indexformatng, *unpacked_index)

f.seek(0)

f.write(new_raw)

f.close()

注意:索引文件的格式在这个文档中有说明: http://selenic.com/repo/hg-stable/file/tip/mercurial/revlog.py#l156

4.5. 使用convert 扩展来修复

或者,妳可以试着使用convert 扩展来强制重新构建整个仓库。首先要警告妳,这种操作会导致所有的变更记录的散列制发生改变,并且要求 所有用户 都要从修复后的仓库中重新复制副本

第一步就是启用convert扩展,假设仓库位于REPO 目录中:

$ vim REPO/.hg/hgrc

...

[extensions]

hgext.convert=

...

尽管是有可能在原地恢复(convert)的,但是,为了安全起见,妳最好还是恢复到一个空白的目录中去:

$ mkdir REPOFIX

使用convert扩展来修复仓库:

$ hg convert --config convert.hg.ignoreerrors=True REPO REPOFIX

scanning source...

sorting...

converting...

[各种各样的消息,其中大部分都会是提交说明]

ignoring: data/.DS_Store.i@26a47e9188c: no match found

[更多的提交说明]

.hgtags@78ff9079978f, line 1: tag '1.0b1' refers to unknown node

updating tags

当妳执行这个命令时,看到的输出应该会跟这里示例的有狠大的不同,但是,最重要的一点就是,损坏的文件已被忽略,其它的文件会进入到新的仓库中。

如果妳仍然遇到了错误(abort),那么,妳可以绕过它,具体做法就是删除 .hg/store/data/{corrupted-file}.i 。在尝试对仓库进行修改之前,要做备份。

雞排妹

Your opinions
Your name:Email:Website url:Opinion content: