나는 수년간 아담의 대답을 사용했습니다. 즉, 예상대로 작동하지 않는 경우가 있습니다.
- "master"라는 단어 가 포함 된 분기 ( 예 : 마스터 분기 만이 아니라 "notmaster"또는 "masterful")는 무시되었습니다.
- "dev"라는 단어 가 포함 된 분기 ( 예 : dev 분기 만이 아니라 "dev-test")가 무시되었습니다.
- 현재 브랜치 의 헤드에서 도달 할 수있는 브랜치 삭제 (즉, 반드시 마스터는 아님)
- 분리 된 HEAD 상태 에서 현재 커밋에서 도달 할 수있는 모든 분기 삭제
1 & 2는 정규 표현식을 변경하여 간단하게 해결할 수있었습니다. 3은 원하는 컨텍스트에 따라 다릅니다 (즉, 마스터 또는 현재 분기에 병합되지 않은 분기 만 삭제). 4가 git reflog
실수로 분리 된 HEAD 상태에서 실행 한 경우 4는 비참 할 가능성이 있습니다 (으로 복구 가능하더라도 ).
마지막으로, 이것은 별도의 (Bash | Ruby | Python) 스크립트를 필요로하지 않는 하나의 라이너 안에 있기를 원했습니다.
TL; DR
선택적 -f
플래그 를 허용하는 git 별명 "sweep"을 작성하십시오 .
git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'
다음과 같이 호출하십시오.
git sweep
또는:
git sweep -f
길고 자세한 답변
일부 브랜치로 예제 git repo를 작성하고 올바른 동작을 테스트하기 위해 커밋하는 것이 가장 쉬웠습니다.
단일 커밋으로 새로운 자식 저장소 만들기
mkdir sweep-test && cd sweep-test && git init
echo "hello" > hello
git add . && git commit -am "initial commit"
새로운 가지를 만듭니다
git branch foo && git branch bar && git branch develop && git branch notmaster && git branch masterful
git branch --list
bar
develop
foo
* master
masterful
notmaster
원하는 동작 : 마스터, 개발 또는 현재를 제외한 모든 병합 된 분기 선택
원래 정규 표현식은 "masterful"및 "notmaster"분기를 누락합니다.
git checkout foo
git branch --merged | egrep -v "(^\*|master|dev)"
bar
업데이트 된 정규식을 사용하여 (이제 "dev"가 아닌 "develop"가 제외됨) :
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster
분기 foo로 전환하고 새로운 커밋을 한 다음 foo를 기반으로 새 분기 foobar를 체크 아웃하십시오.
echo "foo" > foo
git add . && git commit -am "foo"
git checkout -b foobar
echo "foobar" > foobar
git add . && git commit -am "foobar"
내 현재 브랜치는 foobar이며 위의 명령을 다시 실행하여 삭제하려는 브랜치를 나열하면 "foo"브랜치가 master로 병합되지 않은 경우에도 포함됩니다.
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
foo
masterful
notmaster
그러나 마스터에서 동일한 명령을 실행하면 "foo"분기가 포함되지 않습니다.
git checkout master && git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster
그리고 git branch --merged
달리 지정되지 않은 경우 기본적으로 현재 분기의 HEAD로 기본 설정 되기 때문 입니다. 적어도 워크 플로의 경우 로컬 분기가 마스터와 병합되지 않은 경우 로컬 분기를 삭제하고 싶지 않으므로 다음 변형을 선호합니다.
git checkout foobar
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster
분리 된 HEAD 상태
git branch --merged
HEAD 상태가 분리 되면 기본 동작에 의존하는 것이 훨씬 더 중요한 결과를 가져 옵니다 .
git checkout foobar
git checkout HEAD~0
git branch --merged | egrep -v "(^\*|^\s*(master|develop)$)"
bar
foo
foobar
masterful
notmaster
이렇게하면 "foobar"와 함께 "foobar"라는 분기를 삭제했을 것입니다. 이는 거의 확실하게 원하는 결과가 아닙니다. 그러나 우리의 수정 된 명령으로 :
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)"
bar
masterful
notmaster
실제 삭제를 포함하여 한 줄
git branch --merged $(git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" | xargs git branch -d
모두 자식 별칭 "스위프"에 싸여 있습니다.
git config --global alias.sweep '!git branch --merged $([[ $1 != "-f" ]] \
&& git rev-parse master) | egrep -v "(^\*|^\s*(master|develop)$)" \
| xargs git branch -d'
별명은 선택적 -f
플래그를 승인합니다 . 기본 동작은 마스터로 병합 된 분기 만 삭제하지만 -f
플래그는 현재 분기로 병합 된 분기를 삭제합니다.
git sweep
Deleted branch bar (was 9a56952).
Deleted branch masterful (was 9a56952).
Deleted branch notmaster (was 9a56952).
git sweep -f
Deleted branch foo (was 2cea1ab).
git branch -D
병합 여부에 관계없이 모든 분기를 삭제합니다.