26 ポイント 投稿者 GN⁺ 2026-02-21 | 4件のコメント | WhatsAppで共有
  • 長年の Git ブランチ整理問題 を解決するためのシンプルなコマンドが、CIA の内部開発文書で見つかった
    git branch --merged | grep -v "\*\|master" | xargs -n 1 git branch -d
  • このコマンドは git branch --merged の結果から 現在のブランチと master を除外 し、マージ済みブランチを一括削除する
  • 現代のプロジェクトに合わせて、maindevelop ブランチ を除外するよう修正したバージョンもある
  • Git alias に登録 して繰り返し作業を自動化でき、単純ながら 継続的な作業効率向上 とリポジトリ整理に役立つツール

Vault7で見つかった Git のヒント

  • 2017年に WikiLeaks が公開した Vault7 文書 には、CIA のハッキングツールと内部開発文書が含まれていた
    • そのうちの1ページに Git のヒントとテクニック集 があり、内容の大半は一般的なコミット修正、stash、bisect の使い方などだった
  • その文書で見つかったワンライナーのコマンドは、今でも私の ~/.zshrc に残っている

古いブランチ整理の問題

  • ローカル Git リポジトリでは、時間が経つにつれて マージ済みブランチが蓄積 し、整理が難しくなる
    • 機能ブランチ、ホットフィックス、実験用ブランチなどが、マージ後も残って git branch の一覧を複雑にする
  • git branch --merged コマンドでマージ済みブランチを確認できるが、手動で削除するのは面倒

CIA 文書の元のコマンド

  • 提示されていた元のコマンドは次のとおり
    git branch --merged | grep -v "\*\|master" | xargs -n 1 git branch -d  
    
  • 各構成要素の説明
    • git branch --merged: 現在のブランチにマージされたすべてのローカルブランチ一覧を出力
    • grep -v "\*\|master": 現在のブランチ(*)と master を除外
    • xargs -n 1 git branch -d: 残りのブランチを1つずつ安全に削除(-d は未マージのブランチを削除しない)

現代化したコマンドのバージョン

  • 大半のプロジェクトが main ブランチを使っているため、コマンドを次のように修正できる
    git branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d  
    
  • デプロイ後に main ブランチで実行すると、数十個のブランチが数個まで減る
  • このコマンドは Git alias として登録して手軽に実行できる
    alias ciaclean='git branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d'  
    
    • 以後はリポジトリで ciaclean コマンドを入力するだけで自動整理を実行できる

効率性と実用性

  • このコマンドは 毎週数分の時間を節約 し、ブランチ一覧をきれいに保つのに役立つ
  • 単純だが 継続的な生産性向上 をもたらす実用的なツールとして評価されている

4件のコメント

 
foriequal0 2026-02-21

HNのコメントに、自分が作ったプログラムを使っている人がいました。

> その用途には git-trim を使っています:
> https://github.com/foriequal0/git-trim
> README には、場合によっては Bash のワンライナーより優れている理由も説明されています。
> https://news.ycombinator.com/item?id=47089533

 
youngminz 2026-02-21

私も git gone というエイリアスを設定して使っています。とても便利です
- alias.gone = ! git fetch -p && git for-each-ref --format '%(refname:short) %(upstream:track)' | awk '$2 == "[gone]" {print $1}' | xargs -r git branch -D

 
a1eng0 2026-02-21

私は純粋な git ではありませんが、gh-poi というツールを使って整理しています。

https://github.com/seachicken/gh-poi

 
GN⁺ 2026-02-21
Hacker Newsのコメント
  • 自分は git tidy という alias を使ってブランチを整理している
    デフォルトブランチ(main, master)は削除せず、現在のブランチや他の worktree のブランチにも触れない
    リモートで消えたブランチも自動で削除され、コードは自分の dotfiles 設定にある

    • init.defaultBranch を使うのは危険。リポジトリごとにデフォルトブランチ名が違う可能性があり、この設定はグローバルなので事前に決め打ちする必要がある
      自分は git default という alias を作って、リモート(origin)から実際のデフォルトブランチを自動検出させている
    • このスクリプトは本当に便利なので、git extras に貢献するとよさそう
  • 自分は fzf と統合した cleanup コマンドを使っている
    マージ済みブランチを事前に選んでまとめて削除でき、必要なら一部を除外することもできる
    リモートブランチも一緒に整理でき、コードは自分の .gitconfig 設定にある
    また user.primaryBranch 変数を使って、リポジトリごとに異なるデフォルトブランチを指定している

    • 代わりに init.defaultBranch を使ってもいいのではと思う。すでに初期化済みのリポジトリでも git config --local init.defaultBranch main と設定すれば動作する
    • ブランチを切り替えなくても別ブランチから pull できる。たとえば git pull origin main:main の後に git rebase main で処理可能
  • git branch --mergedsquash merge を使うリポジトリでは正しく機能しない
    squash されたコミットの SHA が元のブランチの HEAD と異なるため
    squash されたブランチを安全に検出できるツールが気になる

    • 自分は最近スクリプトを修正して、「最近30日間コミットなし」+「リモートにブランチなし」の条件で削除するようにした
      完璧ではないが十分実用的で、削除前には必ず確認プロンプトを出す
      GitHub のブランチ自動削除設定を参考にしている
    • rebase merge も squash merge と同様に検出されない
      たいていはリモートブランチ削除イベントにフックして処理している
    • 自分は単にリモートブランチが消えたときにローカルブランチを削除している
      git gone という alias を使って git fetch -p の後、[gone] 状態のブランチを整理する
    • Gerrit を使う環境なので、サーバー側で rebase が発生する
      そのため git branch --mergedgit cherrygit log grep の3つの方法を組み合わせたスクリプトを使っている
      ただし、コミットが amend されていたり複数コミットがある場合は誤検出が起こりうる
    • まずブランチを rebase してみれば、空のブランチを検出できそう
  • 自分は git lint という alias でマージ済みブランチを整理している
    main、master、stable ブランチは除外して削除し、git pull --prune && git lint の組み合わせをよく使う

  • Git コマンド自体は平凡だが、クリックしていたら Wikileaks 由来の文書にたどり着いたのが面白かった
    CIA の「Fine Dining」プロジェクトは、USB に隠したマルウェアをアプリのように偽装するツールだった

    • それはむしろ普通の 諜報技術 に見える。本当に「狂っている」のは、MKULTRA のように人に気づかれないよう LSD を投与していた実験のほう
  • 元の問題は、単に マージされていないブランチの一覧だけを出力することでも解決できる

  • こういう自然な作業に何行もの bash が必要なのは妙だ
    Git のコードベースはこんなに大きいのに、標準機能として提供されていないのが残念
    関連ブログ記事も参照

    • ただ、xargs や for loop を少し覚えればこういうのは些細なこと
      組み込みコマンドにしようとすると、さまざまな例外ケースを扱う必要があり、かえって複雑になるかもしれない
    • 「コード行数」でこういうことを評価するのは変な基準に思える
  • 結局、「xargs を覚えたての人みたいだ」という反応もあった

    • そういう態度は ゲートキーピング のように感じる。新しく学んだことを共有するのは良いこと
      自分も以前、ブログや記事を通じてこういうことを学んだ
    • でも、これを CIA 文書から学んだというのは時代を感じる。今は学校よりインターネットから学ぶ時代だ
    • 否定的な反応もあったが、こうした ユーティリティの組み合わせこそ CLI の醍醐味だ
    • CIA 由来だろうと何だろうと、誰かが xargs を新しく覚えたなら、それ自体ですばらしいこと
    • Bell Labs 世代からすると、あまりに基本的な内容に見えるのかもしれない
  • 自分は最近 TUI 中毒 だ。何か不便があると Claude-code に TUI を作ってくれと頼んでいる
    Textual ライブラリを使って Git worktree を管理する TUI を作ったが、Claude は Python コードをかなりうまく扱う

    • tig という古い Git TUI も勧められた。発想の参考にもなる
    • Claude が書いたコードで Git リポジトリが壊れないか心配だという意見もあった
    • TUI が何か分からない人もいた
    • Git 用 TUI なら Magit を強く勧めたい。学習にも役立つ
      Magit の rebase 機能に関する記事も参考になる
    • 自分も Claude で作った小さなツールがたくさんある。オープンソースとして公開しているのか気になる
  • 自分も似たものを Fish shell で実装した
    fzf でリモートから消えたブランチを選んで削除する関数だ
    自分の dotfiles コードにある