본문으로 건너뛰기

Git 로컬·원격 브랜치 삭제 정리

·5 min read

브랜치를 정리하다가 원격에서 지워진 브랜치가 로컬 목록에 계속 남아있는 걸 봤다. 그 김에 로컬 브랜치와 원격 브랜치를 어떤 명령으로 어떻게 지워야 하는지 한 번에 정리했다.

git branch -r은 실제 원격 목록이 아니라 참조였다

로컬에서 브랜치를 확인하는 명령은 두 가지를 같이 쓴다.

git branch    # Local의 branch 확인
git branch -r # Remote의 branch 확인

문제는 여기서 시작됐다. 원격(remote)에서 누군가 브랜치를 추가하거나 삭제해도, 로컬에서 git branch -r로 보이는 목록은 즉시 따라오지 않았다.

이유는 단순했다. git branch -r이 보여주는 건 실제 원격 저장소의 브랜치 목록이 아니라, 로컬에 저장된 **원격 추적 참조(remote-tracking reference)**다. 다시 말해 로컬이 "원격은 이렇게 생겼을 거다"라고 마지막으로 알고 있는 스냅샷일 뿐, 진짜 원격 상태와는 별개다.

그래서 원격에서 브랜치가 사라져도 로컬의 참조는 그대로 남는다. 동기화를 명시적으로 해야 한다.

git fetch --all --prune
git remote prune origin

둘 중 하나를 실행하면 원격에서 사라진 브랜치들의 로컬 참조가 같이 정리된다.

-d와 -D, 머지 여부에서 갈렸다

로컬 브랜치를 지울 때 처음엔 -d만 쓰면 되는 줄 알았는데, 어떤 브랜치는 지워지고 어떤 브랜치는 거부됐다.

git branch -d <branch name>

-d는 업스트림(또는 HEAD)에 이미 머지된 브랜치만 지운다. 머지 안 된 작업이 남아 있는 브랜치를 지우려고 하면 데이터를 잃을 수 있어서 막아준다. 작업이 남아 있어도 강제로 지우고 싶을 때는 -D를 쓴다. -D--delete --force의 축약형이다.

이걸 알고 나서야 "지워지지 않는 브랜치"가 버그가 아니라 보호장치라는 게 이해됐다.

원격 브랜치를 지우는 두 가지 표기

원격 브랜치를 지울 때 자주 보이는 두 명령이 있는데, 둘이 같은 동작이다.

git push origin --delete <branch name>
git push origin :<branch name>

Git 공식 문서에도 ref 앞에 콜론(:)을 붙이는 표기는 --delete와 동등하다고 명시되어 있다. 콜론 표기는 "빈 ref를 원격의 해당 ref로 push한다"는 의미고, 빈 ref를 푸시한다는 건 곧 삭제다.

--dry-run으로 미리 확인할 수 있는 명령은 따로 있다

브랜치를 잘못 지우는 게 무서워서 미리 결과만 보고 싶을 때가 있다. git fetch, git push, git remote prune 같은 명령에는 --dry-run 옵션이 있어서 실제로 실행하지 않고 어떤 변화가 일어날지만 출력해준다.

다만 모든 명령이 --dry-run을 지원하지는 않는다. git branch -d처럼 옵션 자체가 없는 명령도 있어서, 처음 쓰는 명령은 git help <명령>이나 공식 문서에서 지원 여부를 먼저 확인해야 한다.