hg strip' 创建的补丁损坏

2 投票
2 回答
1288 浏览
提问于 2025-04-16 07:46

我用 hg strip 命令删除了一些提交记录。现在我想重新应用在执行 strip 命令时备份的补丁:.hg/strip-backup/68a8f24f62d0-backup.hg

可惜的是,当我尝试推送这个补丁时,发现补丁似乎坏掉了:

$:~/sc2$ hg init --mq
adding .hg/patches/68a8f24f62d0-backup.hg
68a8f24f62d0-backup.hg: up to 582 MB of RAM may be required to manage this file
(use 'hg revert 68a8f24f62d0-backup.hg' to cancel the pending addition)
$:~/sc2$ hg qpush
applying 68a8f24f62d0-backup.hg
patch 68a8f24f62d0-backup.hg is empty
transaction abort!
rollback completed
cleaning up working directory...done
abort: decoding near 'h91AY&SY݁��S������': 'utf8' codec can't decode byte 0xb1 in position 16: invalid start byte!

有没有人遇到过这个问题,或者能给我一些建议,告诉我怎么应用这个补丁?如果不行的话,我就真麻烦了……

这可能是个 Python 的问题吗?

我试过 hg unbundle,结果是:

adding changesets
adding manifests
adding file changes
transaction abort!
rollback completed
abort: received file revlog group is empty

如果我执行 hg pull:

pulling from 68a8f24f62d0-backup.hg
searching for changes
adding changesets
transaction abort!
rollback completed
abort: data/sc2-local.tar.i@2cad29d699f8: no node!

那么我该怎么解决这个节点的问题呢?

海因里希

2 个回答

5

来自 hg help strip 的输出:

任何被删除的变更集都会存储在 ".hg/strip-backup" 文件夹里……你可以通过运行 "hg unbundle .hg/strip-backup/BUNDLE" 来恢复它们,其中 BUNDLE 是被删除时创建的包文件。

这个简单的演示会展示如何使用 stripunbundle 命令:

# create a new repo and commit some changes:
$ hg init foobar
$ cd foobar/
$ echo a > file
$ hg ci -A -m "Initial"
adding file
$ echo b > file
$ hg ci -m "Change 1"
$ echo c > file
$ hg ci -m "Change 2"
$ hg glog --template '{rev} - {node} - {desc}\n'
@  2 - 86ecd06a38260fd229fdd73ba82efa6b2db0784c - Change 2
|
o  1 - 7827b4d5a10c2ca8d5196752f1b2dec92e8cf573 - Change 1
|
o  0 - 2b41b1e661196fe943125fdb1d590b5a60369c7e - Initial

# trash revision 1 and all its children:
$ hg strip 1
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
saved backup bundle to /path/to/foobar/.hg/strip-backup/7827b4d5a10c-backup.hg
$ hg log --template '{rev} - {node} - {desc}\n'
@ - 2b41b1e661196fe943125fdb1d590b5a60369c7e - Initial

# meanwhile, make new changes:
$ hg ci -m "Change 1.1"
$ hg glog --template '{rev} - {node} - {desc}\n'
@  1 - a5ad2a79835ad0019f215e62fd928f8649cbbcab - Change 1.1
|
o  0 - 2b41b1e661196fe943125fdb1d590b5a60369c7e - Initial

# you decide your previous work was not that bad at all:
$ hg unbundle .hg/strip-backup/7827b4d5a10c-backup.hg
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
(run 'hg update' to get a working copy)

$ hg glog --template '{rev} - {node} - {desc}\n'
o  3 - 86ecd06a38260fd229fdd73ba82efa6b2db0784c - Change 2
|
o  2 - 7827b4d5a10c2ca8d5196752f1b2dec92e8cf573 - Change 1
|
| @  1 - a5ad2a79835ad0019f215e62fd928f8649cbbcab - Change 1.1
|/
o  0 - 2b41b1e661196fe943125fdb1d590b5a60369c7e - Initial
2

我和Matt Mackall(Mercurial的主要作者)讨论过这个问题,我们发现了Mercurial中的一个bug:

Mercurial实际上无法处理超过2^31-1字节的文件,也就是大约2GB,因为它在保存文件大小时使用的是带符号整数。不过,如果你添加了更大的文件(我就是这么做的),Mercurial不会拒绝这些文件,而是照常添加。唯一的文件大小检查似乎是在推送到服务器的时候。不过,我只收到了一个警告,还有一个永无止境的hg push

以下是Matt Mackall在邮件交流中的一句话:

这会在几个地方导致溢出:

a) 当我们写入第一个版本到版本日志时,我们会存储一个未压缩的大小,取模2G,但我们仍然能够成功读取整个文件。

b) 当我们构建传输包或进行剥离时,我们会报告一个块大小,取模2G,这会被解释为一个负数,因此看起来像是一个空块。

撰写回答