00changelog.d被意外删除了。
有没有办法从中恢复?
或者恢复自上次推送以来所做的更改?
答案 0 :(得分:4)
技术上可行,尽管有一些信息丢失,因为00changelog.d文件包含诸如变更集作者,提交日期,提交消息和变更集的命名分支之类的信息。也就是说,可以根据00manifest.{d,i}
中的父信息高度确定地重建数据。
00changelog.d
中的数据是变更集散列的一部分,因此与上游存储库共享的数据完全相同非常重要,因此为了重建更改日志你需要克隆你的上游存储库(本地只有我们有一些余地)。
简而言之,在我们开始之前做好准备:
./upstream/
中)./local-backup/
中)./local/
中)rm ./local/.hg/store/00changelog.*
从新鲜的石板开始接下来,您需要我为此次活动编写的以下Mercurial扩展程序:
import os
import weakref
from mercurial.commands import command
from mercurial import scmutil, changelog, error, node
@command('reconstruct', [], '<path to 00changelog.i>')
def reconstruct(ui, repo, changelog_index):
'reconstructs repository from upstream changelog if local changelog has been deleted'
other_opener = scmutil.vfs(os.path.dirname(changelog_index),
expandpath=True,
realpath=True)
upstream_changelog = changelog.changelog(other_opener)
local_manifest = repo.manifest
local_changelog = repo.changelog
if len(local_changelog) != 0:
raise error.Abort('not running on repository with actual changelog data')
local_manifest_nodes = {local_manifest.node(rev): rev for rev in local_manifest}
reconstructed_manifests = set()
reconstructed_manifests_map = {}
lock = repo.lock()
try:
tr = repo.transaction('reconstruct')
trp = weakref.proxy(tr)
for rev in upstream_changelog:
data = upstream_changelog.read(upstream_changelog.node(rev))
prevs = upstream_changelog.parentrevs(rev)
p1 = node.nullid if prevs[0] == -1 else upstream_changelog.node(prevs[0])
p2 = node.nullid if prevs[1] == -1 else upstream_changelog.node(prevs[1])
if data[0] in local_manifest_nodes:
n = local_changelog.add(data[0], data[3], data[4],
trp, p1, p2,
data[1], data[2], data[5])
reconstructed_manifests.add(data[0])
reconstructed_manifests_map[data[0]] = n
missing_manifests = sorted(
((n, r) for n, r in local_manifest_nodes.iteritems()
if n not in reconstructed_manifests),
key=lambda (x,y): y)
for n, rev in missing_manifests:
p1, p2 = local_manifest.parents(n)
p1 = node.nullid if p1 == node.nullid else reconstructed_manifests_map[p1]
p2 = node.nullid if p2 == node.nullid else reconstructed_manifests_map[p2]
n2 = local_changelog.add(n, '', 'missing', trp, p1, p2, 'user')
reconstructed_manifests_map[n] = n2
tr.close()
finally:
if tr:
tr.release()
lock.release()
将此文件放在./reconstruct.py
中。现在我们能够恢复变化:
cd local
hg --config extensions.reconstruct=../reconstruct.py reconstruct ../upstream/.hg/store/00changelog.i
所有仅属于本地的更改都会包含完全虚假的更改日志信息,但可以使用histedit
或mq
扩展程序手动修复此问题。
请注意,上面的扩展做了一些简化的假设:清单对应于您的更改日志1:1。由于您只删除了00changelog.d
而不是00changelog.i
,因此可以使用00changelog.i
中更准确的父信息,但这需要更多代码。
另请注意,上面的扩展使用了一些最新的Python功能,因此您的Mercurial需要基于Python 2.7。