
Claude Codeのメモリをgitで管理してクロスデバイス・クロスプロジェクト共有する仕組みを作ってみた
はじめに
Claude Codeにはセッション間で情報を保持できる メモリシステム があります。「このプロジェクトではpnpmを使う」「コミットにCo-Authored-Byを付けないで」といったフィードバックをMarkdownファイルとして保存し、次回以降のセッションで自動的に参照してくれる仕組みです。
ただし、このメモリはプロジェクトごとに独立しています。複数のプロジェクトで同じ修正を繰り返し教える羽目になったり、別のマシンで作業するとメモリがゼロからスタートになったり、という課題がありました。
そこで グローバルメモリをGitHubリポジトリで管理し、クロスデバイス・クロスプロジェクトで共有する仕組み を作ってみました。
前提・環境
- Claude Code(VS Code拡張 or CLI)
- GitHub CLI (
gh) がインストール・認証済み - macOS(Linuxでも同様に動作するはず)
Claude Codeのメモリシステムの基本
まず、Claude Codeのメモリの仕組みを整理します。
メモリの保存場所
プロジェクトごとのメモリは以下に保存されます:
~/.claude/projects/<project-path-hash>/memory/
├── MEMORY.md # インデックス(常にコンテキストに読み込まれる)
├── feedback_foo.md # 個別メモリファイル
├── user_bar.md
└── fixes_baz.md
メモリの読み込み方式
MEMORY.md(インデックス)はセッション開始時に 常に読み込まれる- 個別のメモリファイルは、インデックスの説明文を見てClaudeが 必要に応じてオンデマンドで読む
- つまり、すべてが一括ロードされるわけではなく、半選択的な仕組みになっている
メモリの種類
| タイプ | 用途 | 例 |
|---|---|---|
user |
ユーザーの役割・好み | 「シニアエンジニア、Reactは初心者」 |
feedback |
Claudeへの修正指示 | 「コミットにCo-Authored-Byを付けないで」 |
project |
プロジェクト固有の文脈 | 「3/5からマージフリーズ」 |
reference |
外部リソースへのポインタ | 「バグはLinearのINGESTプロジェクトで管理」 |
fixes |
エラーパターンと修正方法 | 「ESLint 9はflat config必須」 |
課題:メモリがプロジェクトに閉じている
実際に使っていると、以下のような問題に気づきました:
- 同じフィードバックを何度も教える — 「コミットにCo-Authored-Byを付けないで」をプロジェクトAで教えた後、プロジェクトBでもまた教える
- クロスデバイスで共有できない — マシンAで蓄積したメモリがマシンBにはない
- 修正パターンが再利用できない — プロジェクトAで学んだ「Next.js 16ではnext lintが廃止」がプロジェクトBで活かされない
解決策:2層メモリ + Git同期
以下の設計で解決しました。
アーキテクチャ
メモリの2層構造
| 層 | 保存場所 | 内容 | 例 |
|---|---|---|---|
| Global | ~/.claude/global-memory/ |
ユーザー共通の設定・フィードバック | 「Co-Authored-Byなし」「パッケージ変更前にWeb検索」 |
| Project | .claude/projects/*/memory/ |
プロジェクト固有のピットフォール | 「backend/data/はgitignore対象」 |
昇格ルール
一方向のみ:Project → Global
- プロジェクトAで新しいピットフォールを発見 → プロジェクトAのメモリに保存
- 同じピットフォールがプロジェクトBでも発生 → 昇格シグナル。Globalに移動し、両プロジェクトから削除
- Globalのメモリが古くなった(フレームワーク更新など) → Globalから削除
逆方向(Global → Projectへのコピー)は しない。重複管理のドリフトを避けるためです。
セットアップ手順
1. GitHubにプライベートリポジトリを作成
gh repo create claude-memory --private --description "Cross-project Claude Code memory system"
2. ローカルにクローン
# gh CLIを使うことでSSH鍵不要(gh auth済みなら即動く)
gh repo clone <your-username>/claude-memory ~/.claude/global-memory
3. グローバルメモリファイルを作成
まず MEMORY.md(インデックス)を作成します:
## Feedback
- [feedback_no_coauthor.md](feedback_no_coauthor.md) — No Co-Authored-By in commits unless asked
- [feedback_save_error_learnings.md](feedback_save_error_learnings.md) — Save error fixes to memory proactively
- [feedback_websearch_packages.md](feedback_websearch_packages.md) — Always web search before updating package configs
各メモリファイルはfrontmatter付きのMarkdownです:
---
name: no-co-authored-by
description: Do not add Co-Authored-By trailer to commit messages unless explicitly asked
type: feedback
---
Do not add `Co-Authored-By: Claude ...` to commit messages.
The user finds it unnecessary. Only add it if explicitly requested.
4. ~/.claude/CLAUDE.md にグローバルメモリの読み込み指示を追加
~/.claude/CLAUDE.md はClaude Codeがすべてのプロジェクトで読み込むグローバル設定ファイルです。ここにグローバルメモリの参照方法を記載します:
# Global Memory
Cross-project memories are stored in `~/.claude/global-memory/`.
This directory is a git repo synced to GitHub for cross-device access.
At the start of relevant tasks, read `~/.claude/global-memory/MEMORY.md`
for the index, then load specific memory files as needed.
## Memory tiers
- **Global** (`~/.claude/global-memory/`): User preferences, universal feedback,
cross-project fixes (promoted after hitting 2+ projects)
- **Project** (`.claude/projects/*/memory/`): Project-specific pitfalls,
references, goals
Promotion is one-directional: project → global only.
Never copy global memories down to project scope.
## Syncing global memory
Always use HTTPS via `gh` for this private repo (gh is always authenticated).
- Clone: `gh repo clone <your-username>/claude-memory ~/.claude/global-memory`
- Pull: `cd ~/.claude/global-memory && git pull --rebase -q`
- Push: `cd ~/.claude/global-memory && git add -A && git commit -m "update" && git push`
- Only push when the user asks to sync, or when new global memories are added
5. 初回コミット & プッシュ
cd ~/.claude/global-memory
git add -A
git commit -m "init: global memory with feedback preferences"
git push -u origin main
6. プロジェクトメモリから昇格済みファイルを削除
Globalに移動したメモリファイルをプロジェクトスコープから削除し、MEMORY.md のインデックスも更新します。
新しいマシンでのセットアップ
新しいマシンでは以下のコマンドだけで完了です:
gh repo clone <your-username>/claude-memory ~/.claude/global-memory
~/.claude/CLAUDE.md も必要ですが、これはグローバルメモリリポジトリの README にテンプレートを記載してあるので、そこからコピーするか、Claudeに再生成してもらえます。
同期の運用
ハードな自動同期は設けていません。同期タイミングは以下を想定しています:
- Pull:新しいデバイスで作業を始めるとき
- Push:Claudeがグローバルメモリに新しいエントリを追加したとき
Claudeに「sync memory」と言えば、pull/push を実行してくれます。
設計判断のポイント
なぜグローバルメモリを全プロジェクトにコピーしないのか
重複管理はドリフトの元です。Globalに1つだけ存在させ、Claudeがそこを参照する方がシンプルです。
なぜインデックス(MEMORY.md)の説明文が重要なのか
Claude Codeは MEMORY.md の説明文をもとに「このメモリファイルを読むべきか」を判断します。説明文が曖昧だと不要なメモリまで読み込んでしまい、コンテキストの無駄遣いになります。
- NG:
fixes.md — Various fixes - OK:
fixes_nextjs16_eslint.md — Next.js 16 + ESLint 9 migration pitfalls
なぜプロジェクト固有のfixesはGlobalに上げないのか
「Next.js 16ではnext lintが廃止された」というfixは、Next.js 16を使うプロジェクトにしか関係ありません。Globalに入れると、Pythonだけのプロジェクトでも毎回インデックスに表示されます。
2つ以上のプロジェクトで同じ問題に遭遇して初めて昇格する、というルールが適度なフィルタになっています。
まとめ
- Claude Codeのメモリシステムは ただのMarkdownファイル なので、Gitで管理するのは自然な選択
- 2層構造(Global + Project)で、共通の設定と固有のピットフォールを分離
- 昇格ルール(Project → Global、2+プロジェクトで再発したら)で、Globalの肥大化を防止
ghCLI を使えばSSH鍵なしで、新しいマシンのセットアップがワンコマンド- ハードな自動同期は不要。手動でもシンプルに運用できる
Claude Codeを複数プロジェクト・複数デバイスで使っていて「また同じこと教えてる...」と感じている方は、ぜひ試してみてください。







