คุณสามารถลบหลายสาขาในคำสั่งเดียวด้วย Git ได้หรือไม่


355

ฉันต้องการที่จะทำความสะอาดพื้นที่เก็บข้อมูลในท้องถิ่นของเราซึ่งมีตันของสาขาเก่า: ยกตัวอย่างเช่น3.2, 3.2.1, 3.2.2ฯลฯ

ฉันหวังว่าจะมีวิธีการลับ ๆ ล่อๆในการลบพวกเขาจำนวนมากในครั้งเดียว เนื่องจากพวกเขาส่วนใหญ่ปฏิบัติตามข้อตกลงการปล่อยจุดฉันคิดว่าอาจมีทางลัดในการพูด

git branch -D 3.2.*

และฆ่าสาขา 3.2.x ทั้งหมด

ฉันลองคำสั่งนั้นแล้วแน่นอนมันไม่ทำงาน


11
git branch -D $(git branch | grep 3.2*)- สิ่งนี้ใช้ได้สำหรับฉัน มันจะลบสาขาที่ชื่อขึ้นต้นด้วย "3.2" grep- การจับคู่รูปแบบในผลลัพธ์ (จากgit branchในกรณีนี้) $()- หมายถึงดำเนินการและวางผลลัพธ์ |- การผูกมัด
Eduard

4
น่าสังเกตสำหรับผู้ที่ไม่ทราบว่า-Dเป็นการลบบังคับควรใช้-dในกรณีส่วนใหญ่จะปลอดภัยกว่าก่อน
redfox05

คำตอบ:


363

ไม่ใช่ด้วยไวยากรณ์นั้น แต่คุณสามารถทำได้เช่นนี้:

git branch -D 3.2 3.2.1 3.2.2

โดยพื้นฐานแล้ว git branch จะลบหลาย ๆ branch สำหรับคุณด้วยการเรียกใช้ครั้งเดียว น่าเสียดายที่ชื่อสาขาไม่สมบูรณ์ แม้ว่าในทุบตีคุณสามารถทำ:

git branch -D `git branch | grep -E '^3\.2\..*'`

3
การgit branch -D/-dทำงานให้เสร็จสมบูรณ์ใช้ได้ดีสำหรับฉัน อาจต้องการอัปเดตของคุณ (อาจมาจากไดเรกทอรี contrib ล่าสุด)
Cascabel

19
แทนที่จะคุณสามารถใช้git branch | ... $(git for-each-ref --format='%(refname:short)' refs/heads/3.*)มันยาวกว่านี้ฉันรู้ แต่มันรับประกันว่าจะเป็นเอาต์พุตที่เหมาะสมในขณะที่git branchมีเอาต์พุตค่อนข้างสวยพร้อมสิ่งต่าง ๆ เช่น*และ->(สำหรับ symrefs) ซึ่งสามารถทำให้คุณสับสนในสคริปต์ / หนึ่ง-liners
Cascabel

3
บางทีฉันอาจเป็นเพียงคนเดียวที่มีปัญหานี้ แต่ฉันก็มีgrepนามแฝงอยู่เสมอที่จะรวมธง--color=always- git branch -Dกำลังขว้างปาerror: branch 'my_branch' not found.จนกว่าฉันจะวิ่งโดยไม่มีธงสี
eebbesen

@eebbesen คุณปิดใช้งานทั่วโลกหรือไม่ ฉันพบปัญหาเดียวกันเมื่อทำงานgit branch --merged ${1-$(current_branch)} | grep -v ${1-$(current_branch)} | xargs git branch -d
qmmr

2
ด้วยการขยายรั้งคุณสามารถเขียนgit branch -D 3.2{,.1,.2}เพื่อลบทั้งสามสาขาgnu.org/software/bash/manual/html_node/Brace-Expansion.html
robstarbuck

147

ในกรณีที่เลวร้ายที่สุดคุณสามารถใช้:

git branch | grep '3\.2' | xargs git branch -d

22
นี่เป็นวิธีที่สมบูรณ์แบบสำหรับผู้ที่ใช้สัญลักษณ์คำนำหน้ามาตรฐานสำหรับชื่อสาขา (เช่น "fix / ... " หรือ "feature / ... ")
Haz

4
ง่ายและมีประสิทธิภาพ! ฉันขอแนะนำให้เรียกใช้ก่อนโดยไม่มี| xargs git branch -dส่วนตรวจสอบสิ่งที่จะถูกลบจริง
mathielo

ขอแนะนำไม่ให้grepส่งออกของgit branchตามที่มีไว้สำหรับการอ่านไม่แยก สามารถเปลี่ยนแปลงได้ตลอดเวลา ใช้for-each-refร่วมกับ--formatparams ตามที่แนะนำในคำตอบอื่น ๆ แล้วรวมกับคำแนะนำในคำตอบนี้
redfox05

138
git branch  | cut -c3- | egrep "^3.2" | xargs git branch -D
  ^                ^                ^         ^ 
  |                |                |         |--- create arguments
  |                |                |              from standard input
  |                |                |
  |                |                |---your regexp 
  |                |
  |                |--- skip asterisk 
  |--- list all 
       local
       branches

แก้ไข:

เวอร์ชันที่ปลอดภัยกว่า (แนะนำโดย Jakub Narębskiและ Jefromi) เนื่องจากเอาต์พุตสาขา git ไม่ได้มีไว้เพื่อใช้ในการเขียนสคริปต์:

git for-each-ref --format="%(refname:short)" refs/heads/3.2\* | xargs git branch -D

... หรือ xargs-free:

git branch -D `git for-each-ref --format="%(refname:short)" refs/heads/3.2\*`

14
ห้ามใช้git branchเอาต์พุตสำหรับการสร้างสคริปต์ git for-each-refใช้
Jakub Narębski

1
ในการลบแท็กด้วยสัญลักษณ์ @:git for-each-ref --format="%(refname:short)" refs/tags/\*@\* | xargs git tag -d
thaddeusmt

มีการพิมพ์ผิด ควรเป็น "/3.2/*" ไม่ใช่ "/3.2*" และดูเหมือนว่าคุณได้คัดลอกคำตอบอื่น ๆ ไปวางไว้ในของคุณ
Max MacLeod

ไม่มีการพิมพ์ผิดที่นี่ จากหน้าคน:If one or more patterns are given, only refs are shown that match against at least one pattern, either using fnmatch(3) or literally, in the latter case matching completely or from the beginning up to a slash
gawi

1
น่าสังเกตสำหรับผู้ที่ไม่ทราบว่า-Dเป็นการลบบังคับควรใช้-dในกรณีส่วนใหญ่จะปลอดภัยกว่าก่อน
redfox05

115

คุณสามารถใช้สาขา git - รายการเพื่อแสดงรายการสาขาที่มีสิทธิ์และใช้สาขา git -D / -d เพื่อลบสาขาที่มีสิทธิ์

ตัวอย่างหนึ่งซับ:

git branch -d `git branch --list '3.2.*'`

เมื่อฉันลองทำสิ่งนี้ฉันจะได้รับข้อความแสดงข้อผิดพลาดerror: branch 'package.json' not found.มากมาย ดูเหมือนว่า * จะขยายเร็วเกินไปและพยายามลบสาขาที่สอดคล้องกับชื่อของทุกไฟล์และไดเรกทอรี
พลวง

มันใช้งานได้ดี! ฉันกำลังมีปัญหาในการใช้สิ่งนี้เป็นนามแฝงด้วยgitconfigแม้ว่า ...
ทำตัว

6
คำตอบนี้จะต้องสูงกว่าในรายการสะอาดมากทำงานไม่มี grep
jemiloii

1
ดีที่หนึ่งนี้เป็นเรื่องง่ายที่จะทดสอบครั้งแรกโดยเพียงแค่การออกgit branch --list '3.2.*'
Will

3
บน windowsgit branch -d (git branch --list '3.2.*').trim()
Mattias Josefsson

38

เมื่อเร็ว ๆ นี้ฉันกำลังมองหาวิธีแก้ปัญหาเดียวกันในที่สุดฉันก็พบคำตอบเดียวและทำงานได้ดีมาก:

  1. เปิดเครื่องหรือเทียบเท่า
  2. พิมพ์ในสาขา git grep "pattern" สำหรับตัวอย่างของสาขาที่จะถูกลบ
  3. พิมพ์ในสาขา git grep "pattern" | xargs git branch -D

การแก้ปัญหานี้เป็นที่น่ากลัวและถ้าคุณต้องการคำอธิบายทั้งหมดของแต่ละคำสั่งและวิธีการที่จะทำงานที่ได้รับของที่นี่


28

ใช้

git for-each-ref --format='%(refname:short)' 'refs/heads/3.2.*' |
   xargs git branch -D

7
เคล็ดลับเล็ก ๆ คือถ้าคุณลบส่วนหลังของคำสั่ง "| xargs git branch -D" มันก็จะเอาท์พุทสาขาที่ตรงกัน ดังนั้นคุณสามารถดูตัวอย่างสาขาที่จะถูกลบ
Max MacLeod

1
นอกจากนี้ฉันได้เพิ่มนามแฝงเพื่อทำให้สิ่งนี้ง่ายขึ้น: alias grefs='git for-each-ref --format="%(refname:short)"'ดังนั้นฉันจึงสามารถทำได้grefs | grep 'regexpattern' | xargs git branch -D
angularsen

รักมัน. ดีและเรียบง่าย!
Bhargav Ponnapalli

15

บางทีคุณอาจพบว่ามีประโยชน์:

หากคุณต้องการลบสาขาทั้งหมดที่ไม่ใช่เช่น 'master', 'foo' และ 'bar'

git branch -D `git branch | grep -vE 'master|foo|bar'`

grep -v 'something' เป็นผู้จับคู่ที่มีการผกผัน


ฉันชอบ-Dตัวเลือกเปรียบเทียบกับคำตอบอื่น ๆ ขอบคุณสำหรับคำตอบที่นี่ @Adi โซลูชันใช้ได้ผลกับฉัน
AMIC MING

9

ฉันใส่ชื่อย่อและเส้นประ (at-) เป็นอักขระสามตัวแรกของชื่อสาขาด้วยเหตุผลที่แน่นอนนี้:

git branch -D `git branch --list 'at-*'`

คำตอบทั้งหมดบอกว่านี่เป็นเรื่องง่ายที่สุด
tfantina

7

หากคุณไม่ จำกัด การใช้พรอมต์คำสั่ง git คุณสามารถเรียกใช้git guiและใช้รายการเมนู Branch-> Delete ได้ตลอดเวลา เลือกสาขาทั้งหมดที่คุณต้องการลบและปล่อยให้มันฉีก


วิธีนี้ช่วยให้คุณลบสาขาท้องถิ่นได้แม้ว่า
Stealth Rabbi

7

โซลูชั่น Powershell:

หากคุณใช้ Windows คุณสามารถใช้ PowerShell เพื่อลบหลายสาขาพร้อมกัน ...

git branch -D ((git branch | Select-String -Pattern '^\s*3\.2\..*') | foreach{$_.ToString().Trim()})
//this will remove all branches starting with 3.2.

git branch -D ((git branch | Select-String -Pattern 'feature-*') | foreach{$_.ToString().Trim()})
// this will delete all branches that contains the word "feature-" as a substring.

นอกจากนี้คุณยังสามารถปรับแต่งวิธีการจับคู่รูปแบบควรใช้คำสั่ง Select-String ของ Powershell ลองดูที่เอกสาร PowerShell



5

ฉันสร้างฟังก์ชั่นเล็ก ๆ ที่อาจมีประโยชน์ตามคำตอบของ @gawi (ด้านบน)

removeBranchesWithPrefix() {
  git for-each-ref --format="%(refname:short)" refs/heads/$1\* | xargs git branch -d
}

เพิ่มที่ของคุณ.bash_profileและรีสตาร์ทเครื่องของคุณ จากนั้นคุณสามารถโทรจากบรรทัดคำสั่งดังนี้:

removeBranchesWithPrefix somePrefix

บันทึก

ขณะนี้ฉันมีการตั้งค่าสำหรับการลบแบบนุ่มซึ่งหมายความว่ามันจะไม่ลบสาขาเว้นแต่ว่าพวกเขาจะถูกผสานแล้ว หากคุณต้องการที่จะอยู่บนขอบให้เปลี่ยน-dเป็น-Dและมันจะลบทุกอย่างด้วยคำนำหน้าโดยไม่คำนึงถึง!


5

หากคุณต้องการล้างสาขาทั้งหมดของคุณให้ลอง

git branch -d $(git branch)

มันจะลบสาขาที่รวมในพื้นที่ของคุณทั้งหมดยกเว้นสาขาที่คุณกำลังเช็คอินอยู่

มันเป็นวิธีที่ดีที่จะทำให้ท้องถิ่นของคุณสะอาด


มันทำงานได้ดีพอสำหรับฉัน มันเหลือสองกิ่งยกเว้นอันที่ฉันเป็นอันที่ฉันลบไปแล้วโดยใช้คำสั่งเดียวกัน แต่ใช้ตัวพิมพ์ใหญ่ "-D" แทน "-d" ฉันมีข้อผิดพลาดเล็กน้อยเกี่ยวกับคอมไพล์ไม่พบไฟล์ แต่สาขาถูกลบ
Lurifaxel

3

คุณอาจชอบรายการเล็ก ๆ นี้ ... มันจะดึงรายการและขอการยืนยันของแต่ละรายการก่อนที่จะลบการเลือกทั้งหมดในที่สุด ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "remove branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done`

ใช้ -D เพื่อบังคับการลบ (เหมือนปกติ)

เพื่อความสะดวกในการอ่านนี่คือการแยกบรรทัดทีละบรรทัด ...

git branch -d `git for-each-ref --format="%(refname:short)" refs/heads/\* |
    while read -r line; do 
        read -p "remove branch: $line (y/N)?" answer </dev/tty;
        case "$answer" in y|Y) echo "$line";; 
        esac; 
    done`

นี่คือวิธีการ xargs ...

git for-each-ref --format="%(refname:short)" refs/heads/\* |
while read -r line; do 
    read -p "remove branch: $line (y/N)?" answer </dev/tty;
    case "$answer" in 
        y|Y) echo "$line";; 
    esac; 
done | xargs git branch -D

ในที่สุดฉันชอบที่จะมีสิ่งนี้ใน. bashrc ของฉัน

alias gitselect='git for-each-ref --format="%(refname:short)" refs/heads/\* | while read -r line; do read -p "select branch: $line (y/N)?" answer </dev/tty; case "$answer" in y|Y) echo "$line";; esac; done'

ด้วยวิธีนี้ฉันสามารถพูดได้

gitSelect | xargs git branch -D.

3

สำหรับจิตวิญญาณบริสุทธิ์ที่ใช้ PowerShell ที่นี่สคริปต์เล็ก ๆ git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })


2

มันทำงานได้อย่างถูกต้องสำหรับฉัน:

git branch | xargs git branch -d

git branch | xargs git branch -D

ลบสาขาท้องถิ่นทั้งหมด


2

ใช้คำสั่งต่อไปนี้เพื่อลบสาขาทั้งหมด (สาขาที่เช็คเอาต์จะไม่ถูกลบ)

git branch | cut -d '*' -f 1 | tr -d " \t\r" | xargs git branch -d

แก้ไข:ฉันใช้ Mac Os


0

ฉันอยู่บน windows คุณสามารถใช้ powershell เพื่อทำสิ่งนี้:

 git branch | grep 'feature/*' |% { git branch -D $_.trim() }

แทนที่feature/*ด้วยรูปแบบใด ๆ ที่คุณต้องการ


6
grep เป็น cmdlet ที่ไม่รู้จักสำหรับฉัน ... ดังนั้นฉันจึงเปลี่ยนสาขา git นี้ | โดยที่ {$ _. Trim (). StartsWith ("bug")} | % {git branch -D $ _. Trim ()} และใช้งานได้!
Alex

0

คุณสามารถใช้คำสั่งนี้: git branch -D $(printf "%s\n" $(git branch) | grep '3.2')


ยินดีต้อนรับสู่ StackoverFlow กรุณาใช้ทัวร์ , อ่านเกี่ยวกับวิธีการที่จะถามคำถามที่ดีและเรียนรู้วิธีการสร้างที่น้อยที่สุดสมบูรณ์และสามารถตรวจสอบตัวอย่าง
Gaurang Dave

0

คุณสามารถใช้git guiเพื่อลบหลายสาขาพร้อมกัน จาก Command Prompt / Bash -> git gui-> Remote -> Delete branch ... -> เลือก remote branch ที่คุณต้องการลบ -> Delete


0

ฉันเพิ่งทำความสะอาดชุดใหญ่ของสาขาในพื้นที่ / สาขาที่ล้าสมัยในวันนี้

ด้านล่างเป็นวิธีที่ฉันทำ:

1. แสดงรายชื่อสาขาทั้งหมดไปยังไฟล์ข้อความ:

git branch -a >> BranchNames.txt

2. ผนวกสาขาที่ฉันต้องการลบเพื่อคำสั่ง "git branch -D -r":

สาขา git -D -r กำเนิด / dirA / branch01 กำเนิด / dirB / branch02 กำเนิด / dirC / branch03 (... ผนวกชื่อสาขาใด ๆ )

3. ดำเนินการ cmd

และอันนี้ทำงานได้เร็วขึ้นและน่าเชื่อถือกว่า " ต้นกำเนิดพุชต์คอมไพล์ - ลบ "

นี่อาจไม่ใช่วิธีที่ฉลาดที่สุดตามที่ระบุไว้ในคำตอบอื่น ๆ แต่อันนี้ค่อนข้างตรงไปตรงมาและใช้งานง่าย


0

หากคุณติดตั้ง Git GUI ซึ่งเป็นโปรแกรมเสริมเริ่มต้นสำหรับ Windows แสดงว่าง่ายที่สุด คุณสามารถใช้ ctrl เพื่อเลือกหลายสาขาและลบทิ้งได้ในคลิกเดียว


0

หากคุณใช้ Fish shell คุณสามารถใช้stringฟังก์ชัน :

git branch -d (git branch -l "<your pattern>" | string trim)

นี่ไม่แตกต่างจากตัวเลือก Powershell ในคำตอบอื่น ๆ


0

หากคุณมีสาขาทั้งหมดที่จะลบในไฟล์ข้อความ (branch-to-del.txt) (หนึ่งสาขาต่อบรรทัด) จากนั้นคุณสามารถทำเช่นนี้เพื่อลบสาขาดังกล่าวทั้งหมดจากระยะไกล (ที่มา): xargs -a branches-to-del.txt git push --delete origin


0

หากต้องการลบหลายสาขาตามรูปแบบที่ระบุให้ทำดังต่อไปนี้:

เปิดเทอร์มินัลหรือเทียบเท่าแล้วพิมพ์คำสั่งต่อไปนี้:

git branch | grep "<pattern>" (preview of the branches based on pattern)

git branch | grep "<pattern>" | xargs git branch -D (replace the <pattern> with a regular expression to match your branch names)

ลบสาขา 3.2.x ทั้งหมดคุณต้องพิมพ์

git branch | grep "3.2" | xargs git branch -D

นั่นคือทั้งหมด!

คุณสบายดี!


-1

เช่นเดียวกับใน Git ทุกสาขาไม่มีอะไรที่อ้างอิงถึง git repo ทำไมคุณไม่ลบสาขาที่กำลังจะไป.git/refแล้วถ้ามีอะไรที่เหลืออยู่ซึ่งไม่น่าสนใจในที่เก็บจะถูกเก็บขยะโดยอัตโนมัติดังนั้นคุณจึงไม่ ต้องรบกวน



-4

คุณสามารถลบสาขาทั้งหมดที่จะลบการอ้างอิงที่ไม่จำเป็นทั้งหมด:

rm .git/refs/heads/3.2.*


2
ลดลงเนื่องจากเหตุผลสองประการ: 1. จะใช้รายละเอียดการใช้งาน (ความจริงที่ว่า Git รุ่นปัจจุบันจัดเก็บสาขาเป็นไฟล์ในไดเรกทอรีหนึ่ง) สิ่งนี้สามารถเปลี่ยนแปลงได้ในเวอร์ชันอนาคตการแสดงคำตอบที่ไม่ถูกต้อง 2. มันไม่ทำงานถ้าเก็บตั้งอยู่ในไดเรกทอรีที่แยกต่างหาก
axiac

นอกจากนี้ยังให้ผลลัพธ์ที่ไม่คาดคิดหากคุณเรียกใช้ในที่เก็บที่บรรจุ ( git gc) อย่าทำอย่างนั้น
Matthieu Moy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.