1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

差分ではなくあえて“状態”を保存するという実験

Posted at

差分ではなくあえて“状態”を保存するという実験

背景

バージョン管理といえば Git。
いまや常識です。差分で履歴を残す仕組みで、
行単位での比較も早いし、容量も節約できるし、マージも賢くて速い。
この発想はデータベースのインクリメンタルバックアップや、
クラウドのスナップショット、動画編集の非破壊編集にも通じています。
「変更だけを記録する」という考え方は、やはり理にかなっています。

…ただ、使っていてふとこう思うことがありました。

  • 過去の状態をそのままフォルダで見たい
  • 非エンジニアともスムーズにやり取りしたい
  • ツールや IDE に頼らず中身を直接扱いたい
  • スクリプトや AI から丸ごとフォルダを扱いたい
  • 途中の履歴が壊れても中身が見える単純さがほしい

「差分」ではなく「状態そのもの」がほしい場面が確かにある。
そこで、“丸ごと保存してみたらどんな感じか” を試したのが今回の実験です。

アプリケーションの名前は輪廻(RINNE)。
履歴として生まれ、容量の都合でいずれ削除されていく――
そんな「循環」を前提とした運命に、ぴったりの名前です。


設計思想

RINNE のテーマは「可逆・単純・有限」。
過去の状態を、誰でも、どこでも、それ単体で再生できるようにしたい。

  • 各履歴はそれ単独で成り立つスナップショット
  • ZIP+JSON だけで構成(アプリケーションへの依存なし)
  • SHA256 ハッシュで整合性を検証
  • 保存件数の上限を設け、古いものは整理する運用ルール

差分型より非効率です。容量も食うし、保存も遅い。
でもそのぶん、誰でもその時点の中身が見えて、どの環境でも簡単に扱える。
たとえ RINNE がなくても「読める状態履歴」です。

RINNE は差分の世界ではなく、「状態の世界」で構成されます。


実装とソースコード

実装したソースコードは下記となります。
GitHub: rinne-cli-experiments


構造と仕組み

ディレクトリ構造

.rinne/
 ├─ config/                                       # 設定ファイル
 ├─ data/
 │   ├─ main/                                     # 既定の作業空間(space)
 │   │   ├─ 00000001_20251024T091530123.zip       # 履歴データ
 │   │   ├─ 00000002_20251024T090000000.zip       # 履歴データ 
 │   │   └─ meta/
 │   │      └─ 00000001_20251024T091620223.json  # 履歴メタデータ
 │   │      └─ 00000002_20251024T091000000.json  # 履歴メタデータ
 │   └─ other.../                                 # 他の作業空間(space)
 ├─ logs/                                         # 出力ログ
 ├─ state/                                        # 状態
 │   └─ current                                   # 現在選択中の space 名           
 └─ temp/                                         # 一時ファイル格納

.rinneignore                                      # 無視ルール一覧

実験的な試みですし、複雑なことをすると依存度が上がるので単純な構造にしています。
ルート直下に .rinne/ ディレクトリを作成し、
data/ 配下の任意の space にスナップショットを積み上げていく構造です。
各スナップショットは番号順に保存され、
保存時に破損検証用のメタ情報を作成して
prev, this, hash などのチェーン情報を格納します。
.rinneignore.gitignore と同じく、保存対象外のパスを記述します。


履歴メタデータ

{
  "schema": 1,
  "id": "00000002_20251024T091000000",
  "seq": 2,
  "utc": "2025-10-30T21:00:15.627Z",
  "space": "main",
  "zip": "../00000002_20251024T090000000.zip",
  "message": "backup test",
  "ignore": {
    "source": ".rinneignore",
    "rules": [
      ".rinne/"
    ]
  },
  "hash": {
    "algo": "SHA256",
    "zip": "e40c048dc99120f85efa8b2b0ffb26450a83f1e8841c38e684ec56a2f588d...",
    "chain": {
      "prevId": "00000001_20251024T091620223",
      "prev": "bbf2ae3d6ccc736f06cb86b67b32016e138928c30a449c236b789b3fd0634...",
      "this": "c43e6920a97a637fb6460a6f1fafb9badf991087d593d840d03ff18d1af46..."
    }
  }
}

クイックスタート

# 1) 初期化(ルートディレクトリ直下に .rinne/ を作成)
rinne init

# 2) スナップショット(space名指定省略のため current スペース)
rinne save -m "1回目スナップショット"
rinne save -m "2回目スナップショット"
rinne save -m "3回目スナップショット"

# 3) 整合性チェック
rinne verify

# 4) 履歴整理(最新2件だけ残す)
rinne log-output off   # ← tidy 実行前は off 推奨(ファイルロック回避)
rinne tidy 2

# 5) 履歴確認
rinne log

ちょい実践例

# space 作成、一覧表示、カレント選択
rinne space create test_space
rinne space select test_space
rinne space list
rinne space select main

# 特定 ID にロールバック
rinne restore 00000001_20251024T091530123

# 差分確認
rinne diff 
rinne textdiff 

# 合成保存(左優先)
rinne recompose main main 00000001_20251024T091530123, feature-x 00000004_20251024T091530123, feature-patch 00000002_20251024T091530123

# 他リポジトリから space ごとインポート
rinne import D:\proj_b\.rinne dev_space

# バックアップ(.rinne を ZIP 出力)
rinne backup D:\rinne_backups

バッチ連携例

@echo off
cd /d C:\Name
rinne space select backup
rinne save -m "backup"
rinne log-output off
rinne tidy backup 30
robocopy "C:\Name" "D:\Name" /MIR /R:0 /W:0 /NFL /NDL /NJH /NJS /NC /NS

おわりに

この実験をとおして、あらためて Git のような仕組みの偉大さを実感しました。
世界中の開発を支えるほどの堅牢さと柔軟さを持ち、
あの小さな .git/ の中に「過去」と「未来」を同時に抱えている。

RINNE は「差分が正しい」世界の外側にある小さな実験でした。
保存効率も容量消費率も良くないが、
フォルダを丸ごと残すという発想は、意外と単純で気持ちがいいものです。
案外、並列処理が可能な凄まじいハードパワーの AI に分析をかけるなら、
丸ごとスナップショットを流し込むのもありなのかもしれません。
(もっとも、AIでも .git の各地点を復元できるので、最終的には Git の効率が勝つと思いますが……)

GitHub: rinne-cli-experiments

1
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?