経緯
- LatexやTypstの論文執筆でバージョン管理にGitを使うのは大げさ
- クラウドストレージをあまり使わない
- rsyncの使い方は毎回忘れる
- 自動じゃなくて手動セーブできるようにしたい
- チームで使うことないのでマージの概念いらない、つまりブランチもいらない
これらが積もり積もって作ってみた
sav の主な特徴と機能
sav は、現在のディレクトリ内のすべてのファイルをSQLiteデータベースに一括スナップショット保存するツール。
-
ターミナルで sav と叩くだけで、現在の状態が保存される(sav save も一応あるがきっといらない)
-
自動コメント生成&対話型確認
変更のあったファイル(added/updated/removed)を自動検知してデフォルトコメントを提示。気に入らなければその場で編集するスタイル -
ユニークな日本食ランダムネーム+英数字4桁
各スナップショットには、コミットハッシュの代わりに brave-sushi-a1b2 や quiet-ramen-zy98 といった、人間が覚えやすい形式- 約15億通りあるので、さすがに個人使用では枯渇しないはず
-
1プロジェクト=1SQLiteファイルで完結
メタデータと、zstdで圧縮されたファイル実体(Blob)は、すべて .sav.db(SQLite)に保存。余計な隠しフォルダを大量に作らないので見通しがいい -
restore時に現状況も自動保存
個人のバージョン管理なのでこれぐらいお節介に自動保存してもdbはそこまで膨らまないだろうと判断した
savの立ち上げ方
-
cargo install sav-vcsでインストール - 保存したい対象のディレクトリに移って
sav init- dbファイルの保管場所をどうするか聞かれる。そのままEnterすればそのディレクトリにdbが設置される
- このときコンフィグファイルである.sav.tomlも生成される
コンフィグファイルについて
db_path = ".sav.db" # dbの保存先。パス先にファイルがない状態でsavコマンドを発動すると自動生成される。restoreやlog, diffの参照先でもある。
exclude = [
".git/**",
".sav.db", # こいつがないとdb本体まで巻き込んで保存するのでとんでもないことになる、そのうちハンドリング実装するかも(警告出すか完全に除外するか決めきれなかった)
"target/**", # コンパイル生成物やビルドキャッシュを除外
"*.pdf", # 論文執筆時にPDF出力を除外したい場合など
]
使い方
日々の運用で使うコマンドは、基本的に「スナップショットの保存(sav)」と「復元(sav restore)」の2つ。
保存する(sav)
ターミナルで引数なしの3文字で今の状態をセーブする。
sav
実行すると、前回のスナップショットからの変更(ファイルの追加・修正・削除)を自動で検知し、コメントの叩き台を作る。
自動生成されたコメント: "updated: report.typ"
このコメントでよろしいですか? (y/n) [y]:
そのまま Enter を押せば brave-sushi-a1b2 のような名前で保存され、n を押せばその場で任意のメッセージに編集可能。
過去の状態に戻す(sav restore)
過去のスナップショット(または特定のファイル)を復元したいときは、ランダムネームを指定して実行します。
# プロジェクト全体を復元
sav restore brave-sushi-a1b2
# 特定のファイル(例: report.typ)だけをピンポイントで復元
sav restore brave-sushi-a1b2 report.typ
ハッシュ名を確認する場合は
sav log
で閲覧可能。
sav restore を実行すると、sav は現在の状態を [自動セーブ] brave-sushi-a1b2 への復元前 というメモで勝手にスナップショットを撮ってから上書き処理に移る。
diffサブコマンドも実装するだけした。
今後の開発について
- コーディング経験が浅すぎて何をどうテストすればいいのかよくわっておらず思わぬ不具合が出そう。使っていくうちに実装を決めていきたい。(メジャーリリースはいつになることやら)