{"id":47686605,"url":"https://github.com/nozomiishii/git-harvest","last_synced_at":"2026-05-16T07:20:13.446Z","repository":{"id":347061561,"uuid":"1192678480","full_name":"nozomiishii/git-harvest","owner":"nozomiishii","description":"🌾 Glorious Git Harvest","archived":false,"fork":false,"pushed_at":"2026-04-02T08:19:55.000Z","size":110,"stargazers_count":2,"open_issues_count":10,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-03T02:23:50.481Z","etag":null,"topics":["branch","cleanup","cli","git","worktree"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nozomiishii.png","metadata":{"files":{"readme":"README.ja.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-26T13:05:00.000Z","updated_at":"2026-04-02T08:19:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/nozomiishii/git-harvest","commit_stats":null,"previous_names":["nozomiishii/git-harvest"],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/nozomiishii/git-harvest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nozomiishii%2Fgit-harvest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nozomiishii%2Fgit-harvest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nozomiishii%2Fgit-harvest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nozomiishii%2Fgit-harvest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nozomiishii","download_url":"https://codeload.github.com/nozomiishii/git-harvest/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nozomiishii%2Fgit-harvest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31483380,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-06T17:22:55.647Z","status":"ssl_error","status_checked_at":"2026-04-06T17:22:54.741Z","response_time":112,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["branch","cleanup","cli","git","worktree"],"created_at":"2026-04-02T14:52:45.718Z","updated_at":"2026-05-16T07:20:13.416Z","avatar_url":"https://github.com/nozomiishii.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# git-harvest\n\n[English](./README.md) | 日本語\n\n\u003cbr\u003e\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"demo/logo.gif\" alt=\"logo\" width=\"480\" /\u003e\n\u003c/div\u003e\n\u003cbr\u003e\n\nbranch と worktree を自動で整理するツール\n\n\n## インストールせずに直接実行 (推奨)\n\n常に最新版が走るので、アップデート作業は不要です。\n\n```sh\n# bun\nbunx git-harvest@latest\n\n# pnpm\npnpx git-harvest@latest\n\n# npm\nnpx -y git-harvest@latest\n```\n\n### (任意) エイリアスを設定\n\n```sh\n# bun\necho \"alias ghv='bunx git-harvest@latest'\" \u003e\u003e ~/.zshrc\necho \"alias 'ghv!'='bunx git-harvest@latest --all'\" \u003e\u003e ~/.zshrc\n\n# pnpm\necho \"alias ghv='pnpx git-harvest@latest'\" \u003e\u003e ~/.zshrc\necho \"alias 'ghv!'='pnpx git-harvest@latest --all'\" \u003e\u003e ~/.zshrc\n\n# npm\necho \"alias ghv='npx -y git-harvest@latest'\" \u003e\u003e ~/.zshrc\necho \"alias 'ghv!'='npx -y git-harvest@latest --all'\" \u003e\u003e ~/.zshrc\n```\n\n## おすすめの運用法\n\nGit hooksのpost-mergeコマンドと合わせることで、Mergeやpullした際に自動で収穫もできます。\n\n### [lefthook](https://github.com/evilmartians/lefthook)との連携\n\nGit Hooks にはhusky、pre-commit、simple-git-hooks など様々なツールがありますが、Lefthook が言語に依存せず monorepo にも組み込みやすいのでおすすめです。さらに lefthook-local.yaml を使えば、チーム開発で他のメンバーに影響を与えず自分だけ実行する運用も可能です。\n\n\n```yaml\n# lefthook-local.yaml\npost-merge:\n  commands:\n    git-harvest:\n      run: npx -y git-harvest@latest\n      # or: bunx git-harvest@latest\n      # or: pnpx git-harvest@latest\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eその他のインストール方法\u003c/b\u003e\u003c/summary\u003e\n\n\u003cbr\u003e\n\n### Shell (macOS/Linux)\n\n```sh\ncurl -fsSL https://raw.githubusercontent.com/nozomiishii/git-harvest/main/install.sh | bash\n```\n\nターミナルを再起動するか `source ~/.zshrc` を実行すると git-harvest が使えるようになります。\n\n### Homebrew\n\n```sh\nbrew install nozomiishii/tap/git-harvest\n```\n\n### (任意) エイリアスを設定\n\nエイリアスを設定するとより手軽に実行できます。両方設定しても片方だけでも設定できます:\n\n`ghv` / `ghv!`\n```sh\n# シェルエイリアス\necho \"alias ghv='git-harvest'\" \u003e\u003e ~/.zshrc\necho \"alias 'ghv!'='git-harvest --all'\" \u003e\u003e ~/.zshrc\n```\n\n`git harvest`\n```sh\n# Git サブコマンド — `git harvest` で実行可能\ngit config --global alias.harvest '!git-harvest'\n```\n\n### アンインストール\n\n```sh\ncurl -fsSL https://raw.githubusercontent.com/nozomiishii/git-harvest/main/uninstall.sh | bash\n```\n\n\u003c/details\u003e\n\n\n## 使い方\n\n```sh\ngit-harvest\n```\n\n### オプション\n\n```sh\ngit-harvest --help     # ヘルプを表示\ngit-harvest --version  # バージョンを表示\ngit-harvest --dry-run  # 実際には削除せず、削除対象を表示\ngit-harvest --all      # デフォルトブランチ以外の全ブランチ・worktree を削除\ngit-harvest logo       # git-harvest のロゴを表示\n```\n\n\n## 動作内容\n\nステータスマーカー:\n\n| マーカー | 意味 |\n|---|---|\n| `✓` | 削除済み |\n| `→` | 削除予定（dry-run） |\n| `·` | 残す（理由が続く） |\n\n### Worktree の判定フロー\n\n```mermaid\nflowchart TD\n    Start([worktree を評価]) --\u003e Main{メイン\u003cbr/\u003eworktree?}\n    Main --\u003e|Yes| KeepMain[残す\u003cbr/\u003e表示なし]\n    Main --\u003e|No| Running{走行中の\u003cbr/\u003eClaude session?}\n    Running --\u003e|Yes| KeepRunning[\"·  session running\"]\n    Running --\u003e|No| ManagedPath{.claude/worktrees/\u003cbr/\u003e配下?}\n    ManagedPath --\u003e|Yes| DeleteManaged[\"✓  削除\u003cbr/\u003euncommitted / 未マージも含めて --force\"]\n    ManagedPath --\u003e|No| Merged{マージ済み?}\n    Merged --\u003e|Yes| Uncommitted{未コミット\u003cbr/\u003e変更あり?}\n    Uncommitted --\u003e|Yes| KeepUncommitted[\"·  uncommitted changes\"]\n    Uncommitted --\u003e|No| DeleteMerged[\"✓  削除\"]\n    Merged --\u003e|No| NoUnique{独自 commits\u003cbr/\u003eなし?}\n    NoUnique --\u003e|Yes| KeepNoUnique[\"·  no unique commits\"]\n    NoUnique --\u003e|No| KeepNotMerged[\"·  not merged\"]\n    classDef keep fill:#f5f5f5,stroke:#9e9e9e,color:#424242\n    classDef delete fill:#eeffc4,stroke:#C0FF39,color:#000\n    class KeepMain,KeepRunning,KeepUncommitted,KeepNoUnique,KeepNotMerged keep\n    class DeleteManaged,DeleteMerged delete\n```\n\n| 判定順 | 条件 | 表示 | 通常 | `--all` |\n|---|---|---|---|---|\n| 1 | 走行中の Claude session (`~/.claude/sessions/\u003cpid\u003e.json` で `cwd` 一致 + pid alive) | `·  session running` | 残す | 削除 |\n| 2 | path が `.claude/worktrees/` 配下 + 走行中 session 無し | `✓` / `→` | **削除** (uncommitted / 未マージ commits 含む) | 削除 |\n| 3 | マージ済み + 未コミット変更あり | `·  uncommitted changes` | 残す | 削除 |\n| 4 | マージ済み + 変更なし | `✓` / `→` | 削除 | 削除 |\n| 5 | 独自コミットなし | `·  no unique commits` | 残す | 削除 |\n| 6 | 未マージ | `·  not merged` | 残す | 削除 |\n| - | メインワーキングツリー | *(表示なし)* | 残す | 残す |\n\n判定 2 は **path-regime**（パスベース判定）です。`.claude/worktrees/` 配下の worktree は Claude Code が管理する workspace と見なし、active session が無い = archive された or 閉じられた = 不要、として積極的に削除します。Claude が管理しないパス（手動の `git worktree add` で別の場所に作った等）は判定 3 以降の従来ロジックで保守的に扱います。\n\n**`.claude/worktrees/` 配下の削除挙動**: uncommitted changes や未マージ commits があっても `--force` で削除されます。ただし以下は失われません:\n\n- **会話履歴**: Claude Code 側に残るので `claude --resume \u003csession-id\u003e` で再開可能\n- **未マージ commits**: branch ref として残るので `git checkout \u003cbranch\u003e` で復活可能（cleanup_branches は未マージ branch を保護する）\n\n完全に失われるのは **uncommitted changes** だけなので、Claude session を閉じる前に commit を済ませることを推奨します。逆に言うと、uncommitted で守りたいものがあれば Claude session を開いたままにしておけば保護されます。\n\n#### iPhone の \"Disconnected\" 表示について\n\nRemote Control session で iPhone / claude app に表示される **\"Disconnected\"** は、いったん終了して resume できない pause 状態ではなく、**session が完全に終わった状態** です ([公式 docs](https://code.claude.com/docs/en/remote-control#limitations) 参照):\n\n\u003e **Local process must keep running**: Remote Control runs as a local process. If you close the terminal, quit VS Code, or otherwise stop the `claude` process, the session ends.\n\u003e\n\u003e **Extended network outage**: if your machine is awake but unable to reach the network for more than roughly 10 minutes, the session times out and the process exits.\n\nつまり Disconnected の session は **local process が exit 済み = session 終了済み**。iPhone の一覧に残っているのは server-side の bookkeeping のみで、メッセージを送っても届きません。\n\ngit-harvest はこの実態に合わせて **active な local process があるか (= `~/.claude/sessions/\u003cpid\u003e.json` 一致)** だけを判定信号にしており、iPhone 表示の Connected / Disconnected / Archived を区別しません。Disconnected の worktree も path-regime で削除対象になります。\n\n会話履歴 (`~/.claude/projects/\u003cencoded-cwd\u003e/\u003csession-id\u003e.jsonl`) は別途残るため、`claude --resume \u003csession-id\u003e` で続きから新しい session を起動できます (worktree dir は別途 `git worktree add` か `EnterWorktree` で再作成)。\n\n### Branch の判定フロー\n\n```mermaid\nflowchart TD\n    Start([branch を評価]) --\u003e Default{デフォルト\u003cbr/\u003eブランチ?}\n    Default --\u003e|Yes| KeepDefault[残す\u003cbr/\u003e表示なし]\n    Default --\u003e|No| Deletable{マージ済み\u003cbr/\u003eまたは\u003cbr/\u003e独自 commits なし?}\n    Deletable --\u003e|No| KeepNotMerged[\"·  not merged\"]\n    Deletable --\u003e|Yes| CheckedOut{他の worktree で\u003cbr/\u003eチェックアウト中?}\n    CheckedOut --\u003e|Yes| KeepCheckedOut[\"·  currently checked out\"]\n    CheckedOut --\u003e|No| Delete[\"✓  削除\"]\n    classDef keep fill:#f5f5f5,stroke:#9e9e9e,color:#424242\n    classDef delete fill:#eeffc4,stroke:#C0FF39,color:#000\n    class KeepDefault,KeepNotMerged,KeepCheckedOut keep\n    class Delete delete\n```\n\n| 状態 | 表示 | 通常 | `--all` |\n|---|---|---|---|\n| マージ済み | `✓` / `→` | 削除 | 削除 |\n| マージ済み + チェックアウト中 | `·  currently checked out` | 残す | エラー |\n| 未マージ | `·  not merged` | 残す | 削除 |\n| 独自コミットなし | `✓` / `→` | 削除 | 削除 |\n| デフォルトブランチ | *(表示なし)* | 残す | 残す |\n\n\u003e デフォルトブランチ以外をチェックアウト中に `--all` を実行すると、何も削除せずエラー終了します。`--dry-run --all` では全リソースを `→` で表示します（エラーにならない）。\n\n### Claude Code 連携の詳細\n\ngit-harvest は [Claude Code](https://claude.ai/code) の以下のパスを参照します:\n\n| パス | 用途 |\n|---|---|\n| `~/.claude/sessions/\u003cpid\u003e.json` | 走行中 Claude session の検出（`cwd` で worktreePath を一致確認 + `kill -0 pid` で生存確認） |\n\nClaude Code Agent View や claude app の remote control から session を archive / delete すると、対応する `~/.claude/sessions/\u003cpid\u003e.json` が削除されます。git-harvest はその「session ファイルが無くなった」状態を「user がもう要らない意思を示した」として扱います。\n\n**`--all`** は全ガードを無視して強制削除します。worktree dir だけが消え、セッションのメタデータには触りません。\n\n**Claude Code が未インストール**の場合は該当パスが無いため `.claude/worktrees/` 配下の worktree も path-regime で削除されます。手動で `.claude/worktrees/X` を作る運用をしているなら、Claude を入れていなくても削除される点に注意してください (使ってない方は通常そういう path 規約は採用しないので影響は限定的)。\n\nテストや非標準インストール用にパスを上書きする env var:\n\n| 環境変数 | デフォルト |\n|---|---|\n| `GIT_HARVEST_CLAUDE_SESSIONS_DIR` | `~/.claude/sessions` |\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnozomiishii%2Fgit-harvest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnozomiishii%2Fgit-harvest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnozomiishii%2Fgit-harvest/lists"}