Mercurialでリポジトリが壊れたので黒魔術で乗り切ったはなし

お仕事で使っているMercurialリポジトリの履歴が壊れていました。
ある変更をpushした後、push先のリポジトリで hg update しようとすると

empty or missing revlog xxx/xxx/xxx.java

と表示されupdateに失敗します。

最終的に

黒魔術っぽい方法で乗り切ったので嬉しくてつぶやいたら


フィードバックがきたのでシェアしようと思います。

状況の整理

リポジトリの構成はこんな感じ。Repo1, Repo2から各開発者のローカルにcloneして開発しています。

https://cacoo.com/diagrams/xexxkvX9QkhAgdmF-44084.png

エラーの状況としてはこんな感じ。

  • MasterからRepo2をpullしようとすると「中止:data/xxx/xxx/xxx.java.i@00000000000: 該当する ID はありませんでした」というエラーで失敗する
  • Repo2からMasterにpushはできる
  • Repo2からMasterにpushした後にMasterでhg updateしようとすると「empty or missing revlog xxx/xxx/xxx.java」というエラーで失敗する
  • Repo2からMasterにpushした後にRepo1でMasterをpullしようとすると「中止:data/xxx/xxx/xxx.java.i@00000000000: 該当する ID はありませんでした」というエラーで失敗する

https://cacoo.com/diagrams/xexxkvX9QkhAgdmF-7AE57.png

おんなじような目にあった方もいるみたい。。。

対応方法

要はrevlogが壊れていることが原因っぽいので、問題が発生しているChangeSetにupdateできるリポジトリからrevlogを復旧することで対処しました。

具体的にはRepo2の .hg/store/data/xxx/xxx/xxx.java.i をコピーしてMasterやRepo1の .hg/store/data/xxx/xxx に貼り付けてやります。
これで hg update が通るようになります。