Skip to content
59 changes: 59 additions & 0 deletions docs/user/snapshot-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,65 @@ graph LR
devbase snapshot restore pre-restore-20260221-150000
```

#### 復元中に出る rename の警告

差分の適用中に、次のような警告が出ることがあります。**復元は続行され、内容も正しく復元されます。**

```
WARNING incr-002.tar.zst の展開で tar が rename に失敗しました。GNU tar の incremental が
inode 番号の再利用でディレクトリの rename を誤検出したものとみなし、復元を続けます:
tar: Cannot rename './ai/.claude/plugins/cache/foo' to './ai/.claude/plugins/cache/bar': Directory not empty
```

これは GNU tar の増分バックアップの仕組みに由来します。tar はディレクトリを
**inode 番号**で追跡して「名前の変更」を検出しますが、`~/.claude/plugins/cache/` のように
ディレクトリごと作り直される場所では、削除されたディレクトリの inode 番号が新しい
ディレクトリに再利用されます。すると tar は無関係なディレクトリを「名前が変わった」と
誤検出し、復元時にその名前変更を実行しようとして失敗します。

tar は名前変更に失敗しても展開そのものは最後まで行うため、devbase はこの失敗だけを
警告として扱い、次の差分へ進みます。**警告が出ても対応は不要です。**

#### 中身の欠落を検知したとき

上の警告とは別に、次の警告が出た場合は**対応が必要です**。

```
WARNING 復元後、次のディレクトリが空のままです。GNU tar が記録した rename を適用できなかった
ため、中身が復元されていない可能性があります。利用者が実際に mv したディレクトリであれば、
そのスナップショットからは中身を復元できません:
./ai/.claude/some-renamed-dir
```

devbase は復元の最後に、飲み込んだ rename の**宛先**を検査します。判定は次のとおりです。

| 宛先の状態 | 意味 | 対応 |
|---|---|---|
| 存在しない / 中身がある | 偽の rename。欠落なし | 不要 |
| **存在するが空のまま** | 正当な rename を適用できなかった疑い | 内容を確認する |

偽の rename の宛先は、そのディレクトリ自身が新しく作られたものなので、アーカイブから中身が
展開されて空にはなりません。一方、利用者が実際に `mv` したディレクトリは、差分アーカイブに
**ディレクトリのエントリしか入らない**(中身は rename でしか移動しない)ため、rename を
適用できないと空のまま残ります。

このディレクトリの中身は、そのスナップショットからは復元できません。より古い世代の
スナップショット(`mv` する前のもの)から取り出してください。

#### 復元が失敗したとき

rename 以外の理由で失敗した場合、復元はその場で止まります。このとき
**対象ボリュームは途中まで書き換わっている可能性があります**。エラーには、どのアーカイブの
展開中に失敗したかと、元に戻す手順が出ます。

```
復元に失敗しました (incr-002.tar.zst の展開中)。対象ボリュームは途中まで
書き換わっている可能性があります。復元前の状態は 'pre-restore-20260221-150000' に退避してあります。
元に戻すには devbase snapshot restore pre-restore-20260221-150000 を実行してください。
```

案内のとおり `pre-restore-<timestamp>` から復元すれば、復元を始める前の状態に戻せます。

### スナップショットのコピー

```bash
Expand Down
Loading
Loading