# CIA 유출 문서에서 찾은 Git 브랜치 정리 한 줄 명령어

> Clean Markdown view of GeekNews topic #26863. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=26863](https://news.hada.io/topic?id=26863)
- GeekNews Markdown: [https://news.hada.io/topic/26863.md](https://news.hada.io/topic/26863.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-02-21T10:02:25+09:00
- Updated: 2026-02-21T10:02:25+09:00
- Original source: [spencer.wtf](https://spencer.wtf/2026/02/20/cleaning-up-merged-git-branches-a-one-liner-from-the-cias-leaked-dev-docs.html)
- Points: 26
- Comments: 4

## Summary

`git branch --merged | grep -v “\*\|master” | xargs -n 1 git branch -d`  
이 명령으로 현재 브랜치와 `main`, `develop`을 제외하고 병합된 브랜치를 일괄 삭제하는 방식으로, 반복적인 수동 정리 과정을 자동화합니다.

## Topic Body

- 오래된 **Git 브랜치 정리 문제**를 해결하기 위한 간단한 명령어가 CIA 내부 개발 문서에서 발견됨  
  `git branch --merged | grep -v "\*\|master" | xargs -n 1 git branch -d`  
- 명령어는 `git branch --merged` 결과에서 **현재 브랜치와 master를 제외**하고 병합된 브랜치를 일괄 삭제함  
- 현대 프로젝트에 맞게 **`main`과 `develop` 브랜치**를 제외하도록 수정된 버전도 있음  
- **Git alias로 등록**해 반복 작업을 자동화할 수 있으며, 단순하지만 **지속적인 작업 효율 향상**과 저장소 정리에 유용한 도구  
  
---  
  
### Vault7에서 발견된 Git 팁  
- 2017년 WikiLeaks가 공개한 **Vault7 문서**에는 CIA의 해킹 도구와 내부 개발 문서가 포함되어 있었음  
  - 그중 한 페이지에 **Git 팁과 트릭 모음**이 있었으며, 대부분은 일반적인 커밋 수정, 스태시, bisect 사용법 등이었음  
- 해당 문서에서 발견된 한 줄짜리 명령어가 내 `~/.zshrc`에 지금까지 유지되고 있음  
  
### 오래된 브랜치 정리 문제  
- 로컬 Git 저장소에는 시간이 지나며 **병합된 브랜치가 누적**되어 정리가 어려워짐  
  - 기능 브랜치, 핫픽스, 실험용 브랜치 등이 병합 후에도 남아 `git branch` 목록이 복잡해짐  
- `git branch --merged` 명령으로 병합된 브랜치를 확인할 수 있지만, **수동 삭제는 번거로움**  
  
### CIA 문서의 원래 명령어  
- 제시된 원래 명령어는 다음과 같음  
  ```bash  
  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`: 나머지 브랜치를 하나씩 안전하게 삭제 (`-d`는 병합되지 않은 브랜치는 삭제하지 않음)  
  
### 현대화된 명령어 버전  
- 대부분의 프로젝트가 `main` 브랜치를 사용하므로 명령어를 다음과 같이 수정 가능  
  ```bash  
  git branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d  
  ```  
- 배포 후 `main` 브랜치에서 실행하면 **수십 개의 브랜치가 몇 개로 줄어듦**  
- 이 명령어를 Git alias로 등록해 간편하게 실행 가능  
  ```bash  
  alias ciaclean='git branch --merged origin/main | grep -vE "^\s*(\*|main|develop)" | xargs -n 1 git branch -d'  
  ```  
  - 이후 저장소에서 `ciaclean` 명령만 입력하면 자동 정리 수행  
  
### 효율성과 실용성  
- 이 명령어는 **매주 몇 분의 시간을 절약**하고 브랜치 목록을 깔끔하게 유지하는 데 도움을 줌  
- 단순하지만 **지속적인 생산성 향상**을 제공하는 실용적 도구로 평가됨

## Comments



### Comment 51540

- Author: foriequal0
- Created: 2026-02-21T18:33:43+09:00
- Points: 2

HN 댓글중에 제가 만들었던 프로그램 쓴다는 사람이 있네요.  
  
> I use git-trim for that:  
> https://github.com/foriequal0/git-trim  
> Readme also explains why it's better than a bash-oneliner in some cases.  
> https://news.ycombinator.com/item?id=47089533

### Comment 51543

- Author: youngminz
- Created: 2026-02-21T19:47:20+09:00
- Points: 1

저도 git gone 이라는 alias 걸어 쓰고 있어요. 아주 편합니다   
      - alias.gone = ! git fetch -p && git for-each-ref --format '%(refname:short) %(upstream:track)' | awk '$2 == "[gone]" {print $1}' | xargs -r git branch -D

### Comment 51537

- Author: a1eng0
- Created: 2026-02-21T14:54:40+09:00
- Points: 1

저는 순수 git은 아니지만 gh-poi라는 도구를 사용하여 정리하고 있습니다.  
  
https://github.com/seachicken/gh-poi

### Comment 51516

- Author: neo
- Created: 2026-02-21T10:02:25+09:00
- Points: 1

###### [Hacker News 의견들](https://news.ycombinator.com/item?id=47088181) 
- 나는 `git tidy`라는 alias를 써서 브랜치를 정리함  
  기본 브랜치(main, master)는 삭제하지 않고, 현재 브랜치나 다른 **worktree**의 브랜치도 건드리지 않음  
  원격에서 사라진 브랜치도 자동으로 삭제되며, [내 dotfiles 설정](https://github.com/fphilipe/dotfiles/blob/ba9187d7c895e44c350f8e74d8bfbaaadbe97d6a/gitconfig#L55)에 코드가 있음  
  - `init.defaultBranch`를 사용하는 건 위험함. 각 저장소마다 기본 브랜치 이름이 다를 수 있고, 이 설정은 전역(global)이라 미리 지정해야 함  
    나는 `git default`라는 alias를 만들어서 원격(origin)에서 실제 기본 브랜치를 자동으로 찾게 함  
  - 이 스크립트는 정말 유용하니 **git extras**에 기여하면 좋겠음  

- 나는 `fzf`와 통합된 **cleanup 명령어**를 사용함  
  병합된 브랜치를 미리 선택해 한 번에 삭제할 수 있고, 원하면 일부를 제외할 수도 있음  
  원격 브랜치도 함께 정리하며, [내 .gitconfig 설정](https://github.com/WickyNilliams/dotfiles/blob/c4154dd9b698044bc8d28b93f813d6a38138c8d7/.gitconfig#L41)에 코드가 있음  
  또한 `user.primaryBranch` 변수를 이용해 저장소마다 다른 기본 브랜치를 지정함  
  - `init.defaultBranch`를 대신 써도 괜찮지 않을까 생각함. 이미 초기화된 저장소라도 `git config --local init.defaultBranch main`으로 설정하면 작동함  
  - 브랜치를 전환하지 않고도 다른 브랜치에서 pull 할 수 있음. 예를 들어 `git pull origin main:main` 후 `git rebase main`으로 처리 가능함  

- `git branch --merged`는 **squash merge**를 사용하는 저장소에서는 제대로 작동하지 않음  
  squash된 커밋의 SHA가 원래 브랜치의 HEAD와 다르기 때문임  
  squash된 브랜치를 안전하게 감지할 수 있는 도구가 궁금함  
  - 나는 최근 스크립트를 수정해서 “최근 30일간 커밋 없음” + “원격에 브랜치 없음” 조건으로 삭제하도록 함  
    완벽하진 않지만 충분히 실용적이며, 삭제 전 항상 확인 프롬프트를 띄움  
    GitHub의 [자동 브랜치 삭제 설정](https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-the-automatic-deletion-of-branches)을 참고함  
  - squash merge뿐 아니라 **rebase merge**도 감지되지 않음  
    대부분은 원격 브랜치 삭제 이벤트에 훅을 걸어 처리함  
  - 나는 단순히 원격 브랜치가 사라졌을 때 로컬 브랜치를 삭제함  
    `git gone`이라는 alias를 써서 `git fetch -p` 후 `[gone]` 상태의 브랜치를 정리함  
  - Gerrit을 쓰는 환경이라 서버에서 rebase가 일어남  
    그래서 `git branch --merged`, `git cherry`, `git log grep` 세 가지 방법을 조합한 [스크립트](https://gist.github.com/lawm/8087252b4372759b2fe3b4052bf7e450)를 사용함  
    단, 커밋이 amend되었거나 여러 커밋이 있을 경우 오탐이 생길 수 있음  
  - 브랜치를 먼저 rebase 시도해보면 **빈 브랜치**를 감지할 수 있을 것 같음  

- 나는 `git lint`라는 alias로 병합된 브랜치를 정리함  
  main, master, stable 브랜치는 제외하고 삭제하며, `git pull --prune && git lint` 조합을 자주 씀  

- Git 명령 자체는 평범하지만, 클릭하다가 **Wikileaks** 출처의 문서를 보게 되어 흥미로웠음  
  CIA의 “Fine Dining” 프로젝트는 USB에 숨겨진 악성코드를 앱처럼 위장하는 도구였음  
  - 그건 오히려 일반적인 **첩보 기술** 같음. 진짜 ‘미친’ 건 MKULTRA처럼 사람 몰래 LSD를 타던 실험이었음  

- 원래 문제는 단순히 **병합되지 않은 브랜치 목록**만 출력하는 부분으로도 해결 가능함  

- 이렇게 자연스러운 작업이 여러 줄의 bash를 필요로 한다는 게 이상함  
  Git의 코드베이스가 이렇게 큰데 기본 기능으로 제공되지 않는 게 아쉬움  
  [관련 블로그 글](https://replicated.wiki/blog/partII.html)도 참고함  
  - 하지만 `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 기능에 대한 글](https://entropicthoughts.com/rebasing-in-magit)도 참고할 만함  
  - 나도 Claude로 만든 작은 도구가 많음. 혹시 오픈소스로 공개했는지 궁금함  

- 나도 비슷한 걸 Fish shell에서 구현함  
  `fzf`로 원격에서 사라진 브랜치를 선택해 삭제하는 함수임  
  [내 dotfiles 코드](https://github.com/jo-m/dotfiles/blob/29d4cab4ba6a18dc44dcf9bf476c6f4e81c53e3f/private_dot_config/private_fish/conf.d/fzf.fish.tmpl#L85)에 있음
