모든 로컬 자식 분기 삭제


323

모든 새로운 기능 또는 스토리 카드에 대해 새 로컬 지점을 만드는 개발 프로세스를 따릅니다. 완료되면 지점을 마스터에 병합 한 다음 푸시합니다.

게으름이나 건망증의 조합으로 인해 시간이 지남에 따라 발생하는 경향은 많은 지역 분기 목록으로 끝나고 일부는 (스파이크와 같은) 병합되지 않았을 수 있다는 것입니다.

모든 로컬 분기를 나열하는 방법과 단일 분기를 제거하는 방법을 알고 있지만 모든 로컬 분기를 삭제할 수있는 git 명령이 있는지 궁금합니다.

아래는 git branch --merged명령 의 출력입니다 .

user@machine:~/projects/application[master]$ git branch --merged
  STORY-123-Short-Description
  STORY-456-Another-Description
  STORY-789-Blah-Blah
* master

grep -v \*아래 답변에 따라 나열된 분기를 삭제하려고하면 오류가 발생합니다.

error: branch 'STORY-123-Short-Description' not found.
error: branch 'STORY-456-Another-Description' not found.
error: branch 'STORY-789-Blah-Blah' not found.

나는 사용하고있다 :
git 1.7.4.1
ubuntu 10.04
GNU bash, version 4.1.5 (1) -release
GNU grep 2.5.4


7
@Andrew의 답변을 받아주십시오!
Robert Siemer


@GiulioCaccin이 질문은 또한 병합되지 않은 지점과 관련이 있으며 명시 적으로 반영하도록 질문을 업데이트했습니다.
Louth

답변:


384

'git branch -d'부속 명령은 둘 이상의 분기를 삭제할 수 있습니다. 따라서 @sblom의 답변을 단순화하지만 중요한 xargs를 추가하십시오.

git branch -D `git branch --merged | grep -v \* | xargs`

또는 다음과 같이 더 단순화되었습니다.

git branch --merged | grep -v \* | xargs git branch -D 

@AndrewC가 지적했듯이 git branch스크립팅에 사용 하는 것은 권장하지 않습니다. 그것을 피하려면 다음과 같이 사용하십시오 :

git for-each-ref --format '%(refname:short)' refs/heads | grep -v master | xargs git branch -D

삭제시주의 사항!

$ mkdir br
$ cd br; git init
Initialized empty Git repository in /Users/ebg/test/br/.git/
$ touch README; git add README; git commit -m 'First commit'
[master (root-commit) 1d738b5] First commit
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README
$ git branch Story-123-a
$ git branch Story-123-b
$ git branch Story-123-c
$ git branch --merged
  Story-123-a
  Story-123-b
  Story-123-c
* master
$ git branch --merged | grep -v \* | xargs
Story-123-a Story-123-b Story-123-c
$ git branch --merged | grep -v \* | xargs git branch -D
Deleted branch Story-123-a (was 1d738b5).
Deleted branch Story-123-b (was 1d738b5).
Deleted branch Story-123-c (was 1d738b5).

이 명령은 여전히 ​​아래 답변에 대한 주석에서 언급 된 것과 동일한 오류를보고합니다. error:branch 'STORY-123-Short-Description' not found.나열된 각 지점에 대해
Louth

1
나를 위해 작동합니다. 자세한 내용은 위를 참조하십시오.
GoZoner

1
git 1.7.10을 사용하여 문제를 해결 했습니까? 아니면 .git 저장소에서 직접 작업 하시겠습니까?
GoZoner

1
당신이 얻을 경우 error:branch 'STORY-123-Short-Description' not found.오류를,이 때문에 자식 색상 설정에 아마. 이것은 나를 위해 일했다 ( --no-color옵션에 주목 ) :git branch --no-color --merged | grep -v \* | xargs git branch -D
marcok

3
그래서 내가 찾은 유일한 대답은 효과가 있습니다. 감사합니다!
Kevin Suttle

140

github에 대한이 문제에 대한 의견에서 더 좋은 방법 찾았습니다 .

git branch --merged master --no-color | grep -v master | grep -v stable | xargs git branch -d

편집 : 무색 옵션 추가 및 안정적인 분기 제외 (필요에 따라 다른 분기 추가)


2
마지막으로, 내가 필요한 솔루션
Code Whisperer

1
나는 이것을 시도했지만 error: branch 'my-branch-name' not found.모든 지점에서 계속 얻고 있습니다. 자식 버전 1.8.3.4 (Apple Git-47) 사용. 왜 그런지 알아?
wheresrhys

'git branch --merged master | grep -v 마스터 | 정확히 무엇을 삭제하려고하는지 디버그하기 위해 xargs echo '? 더 나은 아이디어가 없습니다 ...
mBardos

2
그래서. git for-each-ref --format '%(refname:short)' refs/heads/ | grep -v master | xargs git branch -d
Павел Тявин

1
이것과 함께 xargs 사용법을 배웠습니다. 감사합니다
Volem

105

출력을 구문 분석하는 git branch것은 권장되지 않으며 스택 오버플로에 대한 향후 독자에게는 적합하지 않습니다.

  1. git branch도자기 명령으로 알려져 있습니다. 도자기 명령은 기계 구문 분석 용으로 설계되지 않았으며 다른 버전의 Git간에 출력이 변경 될 수 있습니다.
  2. git branch구문 분석이 어려운 방식으로 출력을 변경하는 사용자 구성 옵션이 있습니다 (예 : 채색). 사용자가 설정 color.branch한 경우 출력에 제어 코드가 표시되며 error: branch 'foo' not found.이를 다른 명령으로 파이프하려고 하면 연결됩니다 . --no-colorto 플래그로 이것을 무시할 수 git branch있지만 누가 다른 사용자 구성이 문제를 일으킬 수 있는지 알고 있습니다.
  3. git branch 현재 체크 아웃 된 분기 옆에 별표를 두는 것과 같이 구문 분석하기가 성가신 다른 일을 할 수 있습니다

git관리자는git branch 출력 주위의 스크립팅에 대해 말합니다.

현재 브랜치가 무엇인지 알기 위해 캐주얼 / 부주의 한 사용자가 git 브랜치를 스크립팅했을 수 있습니다. 우리는 스크립트에서 git branch를 포함한 모든 Porcelain 명령의 사용을 적극적으로 권장하지 않습니다. 명령의 출력은 사람의 소비 사례를 돕기 위해 변경 될 수 있기 때문입니다.

.git디렉토리 에서 .git / refs / heads와 같은 파일을 수동으로 편집하도록 제안하는 답변 도 비슷하게 문제가됩니다 (참고 : 대신 .git / packed-refs에 있거나 Git이 나중에 내부 레이아웃을 변경할 수 있음).

Git은 for-each-ref분기 목록을 검색하는 명령을 제공합니다 .

Git 2.7.X는 --merged다음과 같은 옵션을 도입하여 병합 된 모든 분기를 찾아서 삭제할 수 있습니다.HEAD

for mergedBranch in $(git for-each-ref --format '%(refname:short)' --merged HEAD refs/heads/)
do
    git branch -d ${mergedBranch}
done

Git 2.6.X 이전 버전에서는 모든 로컬 브랜치를 나열한 다음 개별적으로 테스트하여 병합되었는지 확인합니다 (매우 느리고 약간 더 복잡함).

for branch in $(git for-each-ref --format '%(refname:short)' refs/heads/)
do
    git merge-base --is-ancestor ${branch} HEAD && git branch -d ${branch}
done

git branch --no-color 2>/dev/null?
nobar

5
확실히 개선되었습니다. 항상 *를 걸러 내야 할 문제가 있으며 누군가가 분리 된 머리에서 그것을 실행하면 재미있는 일을합니다. 그러나 주요 문제 git branch는 도자기 명령이며 일부 버전의 git에서 출력이 변경되지 않을 것이라는 보장은 없습니다.
앤드류 C

@AndrewC에게 감사합니다-이것은 신비한 "branch not found"오류에 대한 질문에 답변하고보다 적절한 명령을 사용하여 작동하는 솔루션을 제공합니다! 👍
Jason

2
'도자기'및 '도자기없는'GIT 명령은 어떻게 식별됩니까?
GoZoner

1
아마도 기본적으로 'dev'와 'master'를 제외시키는 유용한 향상 기능이 있습니까?
PandaWood

66

모든 브랜치를 삭제하고 "develop"및 "master"와 같은 다른 브랜치를 유지하는 간단한 방법은 다음과 같습니다.

git branch | grep -v "develop" | grep -v "master" | xargs git branch -D

굉장히 유용하다 !


8
오래된 스레드를 부활시키고 기존 스레드와 거의 동일한 답변을 게시했습니다. 버그가 많았으며 안전 변경 사항이 누락되었습니다. 이것은 좋은 대답이 아닙니다.
Andrew C

6
이 답변은 git branch의 출력을 파이핑하고 수정하고 git branch -D로 전달할 때 분명합니다. 의미가 없어도됩니다.
Pam

이 솔루션은 저에게 효과적이었습니다. 모든 현지 지점을 삭제했습니다.
Prad

1
'develop_feature'또는 'master_feature'와 같은 단어 develop 또는 master를 포함하는 분기는 삭제하지 않습니다.
django

이것은 내가 👆🏻을 찾고 있었던 답변입니다
Konrad G

62

현재 체크 아웃 한 지점을 제외한 모든 지점을 삭제하려면 다음을 수행하십시오.

for b in `git branch --merged | grep -v \*`; do git branch -D $b; done

처음 몇 번으로 변경 git branch -D $b하여 echo $b원하는 분기를 삭제하는 것이 좋습니다.


1
이 명령으로 나는 error:branch 'a_branch_name' not found.당신이 무엇을하려고하는지 볼 수 있고 명령을 가지고 놀았지만 어떤 이유로 git은 제공된 브랜치 이름을 좋아하지 않는 것 같습니다 ...
Louth

흠. 문제 해결을 돕기 위해git branch --merged
sblom

내 지점 이름은 형식입니다STORY-123-Short-Description
Louth

를 실행 git branch --merged하면 각 줄에 하나가있는 목록이 표시됩니까?
sblom

1
말 그대로 error:branch 'a_branch_name' not found.? 아니면 git branch위 의 출력 에서 분기 이름 중 하나에 대해 불평 합니까?
sblom

52

아래 명령은 마스터 브랜치를 제외한 모든 로컬 브랜치를 삭제합니다.

git branch | grep -v "master" | xargs git branch -D

위의 명령

  1. 모든 가지를 나열
  2. 목록에서 마스터 분기를 무시하고 나머지 분기를 수행하십시오.
  3. 지점을 삭제

4
git branch | grep -v "master" | xargs git branch -d먼저 사용 하여 병합되지 않은 분기를 삭제하지 않고 안전합니다. 그러나 좋은 대답!
Jonas Lomholdt

3
여기에 파워 쉘 버전입니다,@(git branch | Select-String -Pattern "[^(*?)\s? master]") | ForEach-Object{$_.Line.Trim()} | %{git branch -D $_}
조나스 Lomholdt

1
@baklazan 도구가 설치되어있는 경우 Windows 10 명령 줄에서만 작동합니다. 당신은 아마도 MINGW 또는 다른 것들을 가지고 있고 그것을 모른다.
KthProg 2016 년

42

참고로, git 1.7.10으로 업그레이드 할 것입니다. 귀하의 버전에서 작동하지 않는 답변이 여기있을 수 있습니다. 내 생각에는 분기 이름 앞에 접두사를 붙여야한다고 생각 refs/heads/합니다.

주의 작업 폴더와 .git 디렉토리를 복사 한 경우에만 다음을 진행하십시오.

때로는 그냥 가고 싶지 않은 지점을 삭제합니다 .git/refs/heads. 이 모든 브랜치는 커밋의 40 자 sha-1을 포함하는 텍스트 파일입니다. .git/config특정 추적을 설정 한 경우 외부 정보가 필요 합니다. 해당 항목을 수동으로 삭제할 수도 있습니다.


마침내 간단하고 실용적인 옵션입니다. 나는 그것을 좋아한다 : D
Melvyn

2
압축 된 참조를 가지고 있거나 원격 서버에서 복제 한 경우 (포장 된 파일을 제공 할 경우)에는 작동하지 않습니다. 심판이 포장 된 경우 심판은 .git / refs / heads에 저장되지 않으며 "packed-refs"라는 파일에 저장됩니다. git-scm.com/docs/git-pack-refs를 참조하십시오 .
Alexander Bird

1
현재 체크 아웃 한 지점을 제거하는 것은 나쁜 생각 인 것 같습니다
Moberg

@Moberg 커밋을 미리 확인하면 분리 된 HEAD가 제대로 떠 오릅니다.
RomainValeri

34

다음 쉘 명령을 시도하십시오.

git branch | grep -v "master" | xargs git branch -D

설명:

  • git branch | grep -v "master"command 명령을 통해 모든 지점 가져 오기
  • 👇 xargs명령으로 모든 지점을 선택하십시오
  • 💦 지점 삭제 xargs git branch -D

3
이것은 정답 일 수 있지만. 한 줄의 코드는 원래 질문을 어떻게, 어떻게 해결하는지에 대한 설명이 없으면별로 유용하지 않습니다. 답변에 자세한 내용을 알려주십시오.
RyanNerd

28

모두 삭제 를 제외하고 리눅스에 현지 지사를 당신에있는 하나

// hard delete

git branch -D $(git branch)

2
이것은 .git에 들어가서 물건을 제거하는 것보다 안전합니다.
nelsontruran

25

텍스트 편집기와 쉘을 사용하는 것이 더 쉽다는 것을 알았습니다.

  1. git checkout <TAB>쉘을 입력하십시오 . 모든 지역 지점을 표시합니다.
  2. 텍스트 편집기로 복사하고 보관해야 할 것을 제거하십시오.
  3. 줄 바꿈을 공백으로 바꿉니다. SublimeText에서는 매우 쉽습니다.
  4. 쉘을 열고을 입력하십시오 git branch -D <PASTE THE BRANCHES NAMES HERE>.

그게 다야.


나는 당신이 서있는 가지를 제거 할 수 있다고 생각하지 않습니다.
동 탕

@Dong 해당 브랜치 옆에 *가 있으므로 복사 한 목록에서 제거하십시오!
Melanie

12

나는 비슷한 상황이 있었고 최근에 다음 명령이 유용하다는 것을 알았습니다.

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep>/) printf "%s", $0 }'`

여러 가지를 유지하려면

git branch -D `git branch | awk '{ if ($0 !~ /<Branch_You_Want_to_Keep1>|<Branch_You_Want_to_Keep2>/) printf "%s", $0 }'`

이것이 누군가를 돕기를 바랍니다.


1
좋은 점이지만 작동하려면 백틱이 필요했습니다. git branch -D `git branch | awk '{ if ($0 !~ /master/) printf "%s", $0 }'` 실제로 당신이 원래 가지고 있다고 생각하지만 SO 형식으로 길을 잃었습니다.
tassinari

10

Windows 명령 행에서 다음을 사용하여 현재 체크 아웃 된 분기를 제외한 모든 항목을 삭제하십시오.

for /f "tokens=*" %f in ('git branch ^| find /v "*"') do git branch -D %f

7

Git 자체를 거치지 않아도된다면 .git / refs / heads에서 수동 또는 프로그래밍 방식으로 헤드를 삭제할 수도 있습니다 . 다음은 Bash에서 최소한의 조정으로 작동해야합니다.

shopt -s extglob
rm -rf .git/refs/heads/!(master)

마스터 브랜치를 제외한 모든 로컬 브랜치가 삭제됩니다. 업스트림 브랜치는 .git / refs / remotes 아래에 저장 되므로 그대로 유지됩니다.

Bash를 사용하지 않거나 한 번에 많은 Git 리포지토리를 되풀이하려는 경우 GNU find와 비슷한 작업을 수행 할 수 있습니다.

find . \
    -path remotes -path logs -prune -o \
    -wholename \*.git/refs/heads/\* \! -name master -print0 |
xargs -0 rm -rf

찾기 솔루션은 더 이식성이 뛰어나지 만 정리 경로와 파일 이름은 까다 롭고 오류가 발생하기 쉽습니다.


멋있는. 시각적 삭제 :)
sandalone

5

답변 중 어느 것도 내 요구를 완전히 충족시키지 못 했으므로 여기로 이동하십시오.

git branch --merged | grep -E "(feature|bugfix|hotfix)/" | xargs git branch -D && git remote prune origin

이 병합로 시작되는 모든 지역 지점 삭제 feature/, bugfix/또는 hotfix/. 그런 다음 업스트림 리모컨 origin을 정리합니다 (암호를 입력해야 할 수도 있음).

힘내 1.9.5에서 작동합니다.


5

여기에 여러 답변의 조합을 기반으로- 원격에있는 모든 분기유지하고 나머지는 삭제하려는 경우 다음 oneliner가 트릭을 수행합니다.

git for-each-ref --format '%(refname:short)' refs/heads | grep -Ev `git ls-remote --quiet --heads origin | awk '{print substr($2, 12)}'| paste -sd "|" -` | xargs git branch -D

3

이것이 커맨드 라인 솔루션 은 아니지만 Git GUI 가 아직 제안되지 않은 것에 놀랐습니다 .

나는 명령 줄을 99 %의 시간을 사용하지만,이 경우에는 너무 느리게 (따라서 원래의 질문), 또는 길지만 영리한 쉘 조작에 의지 할 때 무엇을 삭제하려고하는지 알지 못합니다.

UI는 모든 분기에 명령을 입력하지 않고도 제거하려는 분기를 신속하게 확인하고 유지하려는 분기를 상기시킬 수 있으므로이 문제를 해결합니다.

로 UI의 이동에서 지점 -> 삭제Ctrl 키 + 클릭 당신은 그들이 강조되도록 삭제할 가지. 당신이 원하는 경우 반드시 그들이 지점 (예 :로 병합 dev아래) 병합 속으로는 경우에만 삭제 설정 지역 지점을dev. 그렇지 않으면 이 검사를 무시 하려면 항상 으로 설정 하십시오.

GitUI : 로컬 브랜치 삭제


1

powershell의 경우 다음과 같이 작동합니다.

git branch --format '%(refname:lstrip=2)' --merged `
    | Where-Object { $_ -ne 'master' } `
    | ForEach-Object { git branch -d $_ }

0

다음 스크립트는 분기를 삭제합니다. 사용 및 위험 등으로 수정하십시오.

이 질문에 대한 다른 답변을 바탕으로 나는 스스로를 위해 빠른 bash 스크립트를 작성했습니다. 나는 그것을 "gitbd"(git branch -D)라고 불렀지 만 그것을 사용한다면 원하는 이름으로 바꿀 수있다.

gitbd() {
if [ $# -le 1 ]
  then
    local branches_to_delete=`git for-each-ref --format '%(refname:short)' refs/heads/ | grep "$1"`
    printf "Matching branches:\n\n$branches_to_delete\n\nDelete? [Y/n] "
    read -n 1 -r # Immediately continue after getting 1 keypress
    echo # Move to a new line
    if [[ ! $REPLY == 'N' && ! $REPLY == 'n' ]]
      then
        echo $branches_to_delete | xargs git branch -D
    fi
else
  echo "This command takes one arg (match pattern) or no args (match all)"
fi
}

전달 된 경우 패턴 인수와 일치하는 분기 또는 인수없이 호출 된 모든 로컬 분기를 삭제하도록 제안합니다. 또한 확인 단계를 제공합니다. Google에서 항목을 삭제하고 있기 때문에 좋습니다.

그것은 일종의 바보입니다-패턴과 일치하는 가지가 없으면 그것을 인식하지 못합니다.

예제 출력 실행 :

$ gitbd test
Matching branches:

dummy+test1
dummy+test2
dummy+test3

Delete? [Y/n] 

0

제외하고 모든 로컬 브랜치를 제거하기 위해 쉘 스크립트를 작성했습니다. develop

branches=$(git branch | tr -d " *")
output=""
for branch in $branches 
do
  if [[ $branch != "develop" ]]; then
    output="$output $branch"
  fi
done
git branch -d $output

0

위의 답변은 정상적으로 작동합니다. 로컬 리포지토리에 분기가 많고 로컬 컴퓨터에있는 분기를 제외하고 많은 분기를 삭제 해야하는 또 다른 방법이 있습니다.

먼저 git branch모든 지역 지점을 나열합니다.

unix 명령을 실행하여 분기 이름의 열을 파일의 단일 행으로 바꾸려면 sample.txt 파일에
git branch > sample.txt
저장 합니다. 그리고 쉘에서 명령을 실행하십시오 . 그러면 열이 행으로 변환되고 분기 이름 목록이 단일 행으로 복사됩니다.
awk 'BEGIN { ORS = " " } { print }' sample.txt

그런 다음를 실행하십시오
git branch -D branch_name(s).
로컬에있는 모든 나열된 분기가 삭제됩니다.


0

가장 실용적인 방법 :에 대한 커밋되지 않은 작업 master이 없도록하고 필요한 경우 커밋 / 푸시하고 저장소의 새로운 사본을 복제하고 이전 사본을 삭제하십시오.



0

상자에 grep이나 다른 유닉스가 없지만 VSCode의 터미널에서 작동했습니다.

git branch -d $(git branch).trim()

병합되지 않은 분기를 삭제하지 않도록 소문자 d를 사용합니다.

내가 할 때도 마스터에 있었 * master으므로 존재하지 않으므로 마스터 삭제를 시도하지 않았습니다.


확인 : 켜져 있지 않으면 master이 명령은 삭제 master됩니다.
Brett Rowberry

-1

먼저해야합니다

git fetch

모든 원격 브랜치 정보를 확보 한 후 다음 명령을 사용하여 마스터를 제외한 모든 단일 브랜치를 제거하십시오.

 git branch -a | grep -v "master" | grep remotes | sed 's/remotes\/origin\///g' | xargs git push origin --delete
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.