วิธีตัดพรุนติดตามสาขาที่ไม่มีอยู่ในระยะไกลอีกต่อไป


768

ด้วยgit remote prune originฉันสามารถลบสาขาท้องถิ่นที่ไม่ได้อยู่ในระยะไกลได้อีก

แต่ฉันยังต้องการลบสาขาท้องถิ่นที่สร้างขึ้นจากสาขาระยะไกลเหล่านั้น (ตรวจสอบว่าพวกเขาไม่ได้ถูกแยกออกจะดีหรือไม่)

ฉันจะทำสิ่งนี้ได้อย่างไร



1
One-liner, cross cross ดูเหมือนว่าแมวจะนอนบนแป้นพิมพ์ของคุณ: npx git-removed-branches(แบบแห้ง) หรือnpx git-removed-branches --prune(สำหรับตัวจริง) คุณต้องติดตั้งnode.jsแล้ว ดูคำตอบ ด้านล่างเพื่อดูรายละเอียด
Cristian Diaconescu

คำตอบ:


891

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

บรรทัดนี้ควรใช้เคล็ดลับ (ต้องการbashหรือzshไม่สามารถใช้กับเชลล์เป้าหมายมาตรฐานได้):

git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d

สายนี้ได้รับรายการของสาขาระยะไกลและส่งผ่านเข้าไปegrepในอินพุตมาตรฐาน และกรองสาขาที่มีสาขาการติดตามระยะไกล (การใช้git branch -vvและการกรองสำหรับสาขาที่มีorigin) จากนั้นรับคอลัมน์แรกของเอาต์พุตซึ่งจะเป็นชื่อสาขา ในที่สุดก็ผ่านชื่อสาขาทั้งหมดลงในคำสั่งลบสาขา

เนื่องจากมันใช้-dตัวเลือกมันจะไม่ลบสาขาที่ไม่ได้ถูกรวมเข้ากับสาขาที่คุณเปิดเมื่อคุณรันคำสั่งนี้

โปรดจำไว้ว่าคุณจะต้องเรียกใช้git fetch --prune ก่อนมิฉะนั้นgit branch -rจะยังคงเห็นสาขาระยะไกล


12
สิ่งนี้ใช้ได้สำหรับฉันอย่างสมบูรณ์แบบ อย่างใดgit fetch -pไม่เพียงพอเสมอ?
Stefan Hendriks

16
น่าเสียดายที่นี่ใช้ไม่ได้กับ Git Bash บน Windows sh.exe": cannot make pipe for process substitution: Function not implemented sh.exe": egrep -v -f /dev/fd/0: No such file or directory fatal: branch name required ความคิดใด ๆ
Ludder

37
ในการเพิ่มเป็นนามแฝง:alias git-remove-untracked='git fetch --prune && git branch -r | awk "{print \$1}" | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk "{print \$1}" | xargs git branch -d'
bryant1410

125
มีคำสั่งที่เสนอสำหรับการปล่อยคอมไพล์ในอนาคตที่จะทำเช่นนี้หรือไม่? คำสั่งนี้ดูเหมือนว่าแมวของฉันอยู่ในแล็ปท็อปของฉัน
Bron Davies

5
ใช้git branch -Dในตอนท้ายของคำสั่งทำงานได้ดีสำหรับเราในขณะที่เรามีแนวโน้มที่จะกระทำสควอชในการผสานซึ่งเราได้รับข้อผิดพลาดเมื่อทำงานกับThe branch x is not fully merged -d
Mateus Gondim

430

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

git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

ข้อมูลเพิ่มเติม


4
ทำงานได้สมบูรณ์แบบฉันคิดว่า! มีใครอธิบายได้ไหมว่าคำตอบนี้แตกต่างจากคำตอบที่ยอมรับหรือไม่
Andrew

11
การปรับปรุงเล็กน้อย: ใช้xargs -r git branch -dเพื่อไม่ให้มีการเรียกใช้ถ้าไม่มีกิ่งที่จะลบ โปรดทราบว่า-rธงอาจไม่สามารถใช้ได้ทุกที่
Jacob Wang

8
เนื่องจาก grep อาจไม่ตรงกันเนื่องจากสีคอมไพล์:git branch --merged master --no-color | grep -v '^* master$' | xargs -n1 -r git branch -d
Mike D

5
@NickRes ที่เห็นในขณะที่คุณถามเป็นอย่างดีgit branch --merged masterแสดงรายการกิ่งที่รวมกันเป็นหลักแล้วส่วน grep กลางจะแยกตัวต้นแบบออก (เราไม่ต้องการลบต้นแบบ!) และส่วน xargs สุดท้ายจะเรียกใช้งานgit branch -d(ลบสาขา) ในแต่ละรายการ ผลลัพธ์ หรือคุณสามารถอ่านลิงก์ข้อมูลเพิ่มเติมที่ให้ไว้ในคำตอบ;)
jackocnr

14
การปรับปรุง: git branch --merged master | egrep -v '^\s*\*?\s*master$' | xargs git branch -d. เอาต์พุตจาก git v2.10.1 จะแสดง "* master" เมื่อทำการเช็คเอาต์ ฉันกำจัดอาจารย์ทั้งที่มีและไม่มีเครื่องหมายดอกจัน
Esteban

162

ท่ามกลางข้อมูลที่นำเสนอโดยgit help fetchมีรายการเล็ก ๆ นี้:

 -p, --prune
        After fetching, remove any remote-tracking branches which no longer exist on the remote.

ดังนั้นอาจgit fetch -pเป็นสิ่งที่คุณกำลังมองหา?

แก้ไข: ตกลงสำหรับผู้ที่ยังคงโต้วาทีคำตอบนี้ 3 ปีหลังจากข้อเท็จจริงนี่เป็นข้อมูลเพิ่มเติมเล็กน้อยว่าทำไมฉันจึงนำเสนอคำตอบนี้ ...

ก่อนอื่น OP บอกว่าพวกเขาต้องการ "ลบกิ่งก้านสาขาเหล่านั้นที่ถูกสร้างขึ้นจากกิ่งก้านสาขาที่ห่างไกล [ที่ไม่ได้อยู่บนรีโมท] อีกต่อไป" นี่เป็นไปไม่ได้อย่างไม่น่าสงสัยgitเลย นี่คือตัวอย่าง

สมมติว่าผมมี repo บนเซิร์ฟเวอร์ส่วนกลางและมันมีสองสาขาที่เรียกว่าและA B(สาขาไม่จริงยัง) ถ้าผมโคลน repo ภายในระบบของฉันที่โคลนฉันจะมี refs ท้องถิ่นที่เรียกว่าและorigin/A origin/Bตอนนี้สมมติว่าฉันทำต่อไปนี้:

git checkout -b A origin/A
git checkout -b Z origin/B
git checkout -b C <some hash>

ข้อเท็จจริงที่เกี่ยวข้องที่นี่คือฉันด้วยเหตุผลบางอย่างเลือกที่จะสร้างสาขาใน repo ท้องถิ่นของฉันที่มีชื่อที่แตกต่างจากต้นกำเนิดของมันและฉันยังมีสาขาท้องถิ่นที่ยังไม่มี (ยัง) อยู่ในแหล่งกำเนิด repo

ตอนนี้สมมติว่าฉันลบทั้งสองAและBสาขาใน repo ระยะไกลและปรับปรุง repo ท้องถิ่นของฉัน ( git fetchบางรูปแบบ) ซึ่งทำให้ refs ท้องถิ่นของฉันorigin/Aและorigin/Bหายไป ตอนนี้ repo ท้องถิ่นของฉันมีสามสาขายังคงA, และZ Cไม่มีสิ่งเหล่านี้มีสาขาที่เกี่ยวข้องใน repo ระยะไกล พวกเขาสองคนคือ "สร้างจาก ... กิ่งไม้ที่อยู่ห่างไกล" แต่ถึงแม้ว่าฉันรู้ว่าเคยมีสาขาที่เรียกว่าBต้นกำเนิดฉันไม่มีทางรู้ว่าZมันถูกสร้างขึ้นจากBเนื่องจากมีการเปลี่ยนชื่อในกระบวนการอาจมีเหตุผลที่ดี ดังนั้นจริงๆแล้วหากไม่มีกระบวนการภายนอกที่บันทึกเมตาดาต้ากำเนิดสาขาหรือมนุษย์ที่รู้ประวัติมันเป็นไปไม่ได้ที่จะบอกได้ว่าสาขาใดในสามสาขาถ้ามี OP จะกำหนดเป้าหมายเพื่อนำออก หากไม่มีข้อมูลภายนอกที่gitไม่ได้รับการบำรุงรักษาโดยอัตโนมัติgit fetch -pอยู่ใกล้คุณเท่าที่จะทำได้และวิธีอัตโนมัติใด ๆ สำหรับการพยายามที่สิ่งที่ OP ขอให้มีความเสี่ยงในการลบสาขามากเกินไปหรือหายไปบางส่วนที่ OP ต้องการ ต้องการลบ

มีสถานการณ์อื่น ๆ เช่นกันเช่นถ้าฉันสร้างกิ่งแยกออกสามกิ่งorigin/Aเพื่อทดสอบวิธีที่แตกต่างกันสามอย่างกับบางอย่างแล้วก็origin/Aหายไป ตอนนี้ฉันมีสามสาขาซึ่งเห็นได้ชัดว่าไม่ตรงกับชื่อที่ฉลาด แต่พวกเขาถูกสร้างขึ้นจากorigin/Aและดังนั้นการตีความที่แท้จริงของคำถาม OPs จะต้องลบทั้งสาม อย่างไรก็ตามนั่นอาจไม่เป็นที่ต้องการหากคุณสามารถหาวิธีที่เชื่อถือได้เพื่อจับคู่ ...


107
สิ่งนี้ไม่ได้ลบสาขาท้องถิ่นเฉพาะตัวชี้ระยะไกลไปยังสาขา
Jaap

4
มันจะลบเฉพาะสาขาในท้องที่เหล่านี้ซึ่งไม่มีอยู่ในระยะไกลและคุณไม่ได้ทำการชำระเงิน
Jarek Jakubowski

15
คุณควรอ่านคำถามให้ละเอียดมากขึ้นเช่นเดียวกับ Jaap ผู้ที่ลงคะแนนสำหรับคำตอบนี้ควรอ่านว่าคำถามนี้เกี่ยวกับอะไร
Søren Boisen

4
ใช่นี่คือสิ่งที่ฉันต้องการจะทำ! @ SørenBoisenฉันหวังว่าในสองปีที่ผ่านมาคุณมีเวลาที่จะทบทวนความคิดเห็นของคุณอีกครั้ง ... หากเนื้อหาที่โพสต์บน SO ควรเกี่ยวข้องกับสิ่งที่ OPs สับสนบางครั้งถามเราจะลบข้อมูลจำนวนมาก โปรดอย่าเข้าใจว่าจะแนะนำผู้คนถึงวิธีการใช้เว็บไซต์นี้นอกเหนือจากหลักเกณฑ์อย่างเป็นทางการและพวกเขาไม่ได้ป้องกันคำตอบที่เป็นมุมฉาก แต่มีประโยชน์
Félix Gagnon-Grenier

6
@ FélixGagnon-Grenier นี่คือปัญหาของฉันกับคำตอบนี้: 1) คำถามที่ชัดเจนคริสตัล OP ไม่ชัดเจน 2) คำตอบนี้ไม่ได้พูดถึงว่ามันไม่ได้ตอบคำถาม! 3) คำถามได้ระบุวิธีการตัดกิ่งติดตามระยะไกลซึ่งไม่มีอยู่อีกต่อไปดังนั้นจึงเพิ่มค่าเป็นศูนย์
Søren Boisen

117

การดำเนินการนี้จะลบสาขาในท้องที่ที่มีการตัดกิ่งติดตามระยะไกล (ตรวจสอบให้แน่ใจว่าคุณอยู่ในmasterสาขา!)

git checkout master
git branch -vv | grep ': gone]' | awk '{print $1}' | xargs git branch -d

รายละเอียด:

  • git branch -vv แสดง "หายไป" สำหรับสาขาท้องถิ่นที่รีโมตถูกตัดแล้ว

    mybranch abc1234 [origin/mybranch: gone] commit comments
    
  • -dจะตรวจสอบว่ามีการรวมหรือไม่ ( -Dจะลบโดยไม่คำนึงถึง)

    error: The branch 'mybranch' is not fully merged.
    

15
คุณสามารถทำให้คำสั่งสั้นลงด้วยgit branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
chiborg

4
เพียงแค่ชี้ให้เห็นว่าคุณควรจะอยู่ในหลักก่อนที่จะทำเช่นนี้เพราะเปรียบเทียบกับสาขาgit branch -d HEAD
Steve Bennett

ยอดเยี่ยม ฉันค้นหาและมองหาสิ่งนี้ ฉันหวังว่าฉันจะได้เห็นคำตอบของคุณก่อนที่ฉันจะหาคำตอบด้วยตัวเอง มันคงช่วยฉันไม่กี่นาที นี่คือคำตอบอื่น ๆ ของฉัน: stackoverflow.com/questions/15661853/…
Karl Wilbur

1
ฉันลงเอยด้วยนามแฝง git ที่คล้ายกันใช้ cut ตั้งแต่ awk ไม่ทำงานด้วยเหตุผลบางอย่าง:prunelocal = !sh -c \"git checkout -q master && git fetch -q --prune && git branch -vv | git grep ': gone]' | cut -d' ' -f3 | xargs git branch -d\"
Zitrax

3
โอ้ ... คุณไม่ควรอัปเดตคำตอบของคุณเพื่อบอกคนอื่นว่าพวกเขาควรอยู่ในระดับผู้เชี่ยวชาญ เพิ่งทำได้จากสาขาอื่น @ stevebennet2 ขอบคุณสำหรับความคิดเห็นข้อมูล
GrayedFox

53

หนึ่งสามารถกำหนดค่า Git ให้ลบการอ้างอิงไปยังสาขาระยะไกลที่ถูกลบโดยอัตโนมัติเมื่อดึงข้อมูล:

git config --global fetch.prune true

เมื่อโทรgit fetchหรือgit pullหลังจากนั้นการอ้างอิงไปยังสาขาระยะไกลที่ถูกลบจะถูกลบโดยอัตโนมัติ


5
นี่ไม่ได้ลบสาขาท้องถิ่นแค่อ้างอิงถึงพวกเขาใช่ไหม
Clint Eastwood

@ClintEastwood มันจะลบการอ้างอิงไปยังสาขาระยะไกลเท่านั้น git branch -rคุณสามารถแสดงรายการการอ้างอิงไปยังสาขาระยะไกลโดยใช้
wedesoft

52

มีแพคเกจ NPM ที่เรียบร้อยที่ทำเพื่อคุณ (และควรทำงานข้ามแพลตฟอร์ม)

ติดตั้งด้วย: npm install -g git-removed-branches

จากนั้นgit removed-branchesจะแสดงให้คุณเห็นทุกสาขาในท้องถิ่นที่เก่าแก่และgit removed-branches --pruneลบออกได้

ข้อมูลเพิ่มเติมที่นี่


1
นี่ควรมี upvotes มากกว่านี้จริงๆ ขอบคุณที่ทำให้ชีวิตง่ายขึ้นโดยไม่คำนึงถึงแพลตฟอร์ม
เข้ารหัส

นามสกุลเล็กน้อยที่มีประโยชน์ ติดตั้งและทำงานได้ดีบน Windows 10 หมายเหตุเล็กน้อย: มันถือว่าสาขาที่ไม่ถูกผสานเป็นลูกพรุนได้ (ข้อผิดพลาดเมื่อเรียกใช้ --prune แม้ว่าจะเรียกว่า branch -d) พวกเขาอย่างไรก็ตามไม่ได้แสดงแทนเช่นในตอนแรก รายการที่แสดง
2864740

1
นี่คือคำตอบที่ฉันโปรดปราน npx git-removed-branchesทำงานเหมือนฝัน
Drazisil

ใช่! ควรมี upvotes มากกว่านี้! วิธีแก้ปัญหาที่ง่ายและใช้งานง่ายสำหรับมือใหม่ของ cli
geoseong

มันจะมีประโยชน์ในการให้ภาพรวมของเครื่องมือที่ทำจากมุมมองของคอมไพล์
ryanwebjackson

41

โซลูชัน Windows

สำหรับ Microsoft Windows Powershell:

git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}

ชี้แจง

git checkout master เปลี่ยนเป็นสาขาหลัก

git remote update origin --prune พรุนสาขาระยะไกล

git branch -vvรับเอาต์พุต verbose ของทุกสาขา ( การอ้างอิง git )

Select-String -Pattern ": gone]" รับเฉพาะระเบียนที่ถูกลบออกจากระยะไกล

% { $_.toString().Split(" ")[0]} รับชื่อสาขา

% {git branch -d $_} ลบสาขา


ตัวอย่างที่ดี หรือจะใช้git remote prune originสตริงเลือกก็ได้ดูเหมือนจะไม่ตรงกับ git เวอร์ชันล่าสุด ลองใช้ConvertFrom-String -TemplateContent
Bernie White

3
ดูเหมือนว่า git เวอร์ชันล่าสุดจะเพิ่มช่องว่างต่อท้ายบางส่วนดังนั้นการแบ่งไม่ทำงานเพื่อให้ได้ชื่อสาขา ทำ. toString (). ตัด (). แยก ("") แล้วมันจะ
Chris Hynes

นี่คือของฉัน:git checkout master; git pull; git remote prune origin; git branch --merged | select-string -notmatch "master" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
Omzig

@Omzig สิ่งที่ทำแตกต่างกันอย่างไร คุณสามารถให้คำอธิบาย>
chris31389

@ chris31389 ฉันมีการดึงที่นั่นเพื่อให้ได้ทุกอย่างที่ฉันหายไปจากต้นแบบและฉันเปลี่ยนสาขาเป็น - ไม่จมและไม่ใช่ปริญญาโทฉันต้องการให้แน่ใจว่าฉันลบสาขาที่ถูกจม มันทำให้ฉันรู้สึกดีขึ้น;)
Omzig

27

มันจะแสดงรายการสาขาท้องถิ่นที่สาขาการติดตามระยะไกลถูกลบจากระยะไกล

$ git remote prune origin --dry-run

หากคุณต้องการที่จะยกเลิกการอ้างอิงสาขาท้องถิ่นเหล่านี้จากท้องถิ่นซึ่งยังไม่ถูกติดตาม

$ git remote prune origin

19
นี่ไม่ได้ตอบคำถามนี่คือสิ่งที่ OP รู้อยู่แล้ว
Ken Williams

2
ฉันเห็นด้วยเช่นกัน แต่เมื่อคุณค้นหา "วิธีการตัดกิ่งติดตามท้องถิ่นที่ไม่มีอยู่ในระยะไกลอีกต่อไป" นี่คือลิงค์ด้านบนและคำตอบนี้ตรงกับชื่อ (ไม่ใช่ถ้ามีคนอ่านคำอธิบายทั้งหมดในคำถาม) นั่น คือเหตุผลในการโหวตมากขึ้น :)
027

สิ่งนี้ไม่ได้ลบสาขาท้องถิ่น ยังมีอยู่หลังจากทำงานนี้
Xin

@Xin ลองเรียกใช้คำสั่งโดยไม่มีอาร์กิวเมนต์ --dry-run เนื่องจากจะไม่ดำเนินการตามคำสั่ง แต่ให้แสดงสิ่งที่จะเปลี่ยน
Torsten Ojaperv

19

ในฐานะ @tzacks โน้ต ... มีแพ็คเกจ npm ที่สะดวกสำหรับสิ่งนี้ แค่ทำ:

npx git-removed-branches --prune

(ฉันจะได้แสดงความคิดเห็น แต่ชื่อเสียงไม่เพียงพอ)


1
งดงาม ไม่ยุ่งยากอะไรเลย ดีใจที่ได้รับคำตอบแบบเต็ม!
Dan Rayson

1
สิ่งนี้ควรอยู่ด้านบนสุด ทำงานใน Windows ด้วย
tomtastico

14

หากใช้ Windows และ Powershell คุณสามารถใช้รายการต่อไปนี้เพื่อลบสาขาท้องถิ่นทั้งหมดที่รวมอยู่ในสาขาที่เช็คเอาท์ในปัจจุบัน:

git branch --merged | ? {$_[0] -ne '*'} | % {$_.trim()} | % {git branch -d $_}

คำอธิบาย

  • แสดงรายการสาขาปัจจุบันและสาขาที่รวมเข้าด้วยกัน
  • กรองสาขาปัจจุบัน
  • ล้างค่าช่องว่างนำหน้าหรือต่อท้ายจากgitเอาต์พุตสำหรับชื่อสาขาที่เหลือ
  • ลบสาขาในพื้นที่ที่ถูกผสาน

มันควรค่าแก่การรันgit branch --mergedด้วยตัวเองก่อนเพื่อให้แน่ใจว่าจะลบสิ่งที่คุณคาดหวัง

(รังเพลิง / อัตโนมัติจากhttp://railsware.com/blog/2014/08/11/git-housekeeping-tutorial-clean-up-outdated-branches-in-local-and-remote-repositories/ .)


10

แม้แต่ซับในที่สั้นกว่าและปลอดภัยกว่า:

git branch -d $(git branch --merged | cut -c 3- | grep -v master)

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


3
จะเป็นการลบ 'ต้นแบบ' ของคุณด้วยหรือไม่
dcsan

2
หากคุณตรวจสอบในระดับปริญญาโทแล้วไม่เช่นนั้นใช่
FelikZ

1
หากต้องการข้ามต้นแบบคุณสามารถไปที่ grep แล้วเลือกตรงกันข้ามได้ดังนั้น git branch -d $(git branch --merged | cut -c 3- | grep -v master)
mozillalives

สิ่งนี้ไม่ปลอดภัยและบางคนในอนาคตจะลบสาขาหลักของพวกเขาโดยไม่รู้ตัว
jasonseminara

1
@jasonseminara #dcsan ฉันได้อัปเดตข้อมูลโค้ดดังนั้นจึงข้ามสาขาหลัก #mozillalives ขอบคุณ
FelikZ

9

ฉันต้องการสิ่งที่จะล้างสาขาในท้องถิ่นทั้งหมดที่กำลังติดตามสาขาระยะไกลเปิดoriginซึ่งสาขาระยะไกลถูกลบ ( gone) ฉันไม่ต้องการลบสาขาท้องถิ่นที่ไม่เคยตั้งค่าเพื่อติดตามสาขาระยะไกล (เช่น: สาขา dev ท้องถิ่นของฉัน) นอกจากนี้ฉันต้องการซับในแบบง่าย ๆ ที่เพิ่งใช้gitหรือเครื่องมือ CLI ง่าย ๆ อื่น ๆ แทนที่จะเขียนสคริปต์ที่กำหนดเอง ฉันสิ้นสุดการใช้บิตของgrepและจะทำให้คำสั่งง่ายๆนี้แล้วเพิ่มเป็นนามแฝงของฉันในawk~/.gitconfig

[alias]
  prune-branches = !git remote prune origin && git branch -vv | grep ': gone]' | awk '{print $1}' | xargs -r git branch -D

นี่คือgit config --global ...คำสั่งสำหรับเพิ่มได้อย่างง่ายดายเช่นgit prune-branches:

git config --global alias.prune-branches '!git remote prune origin && git branch -vv | grep '"'"': gone]'"'"' | awk '"'"'{print $1}'"'"' | xargs -r git branch -d'

หมายเหตุ: การใช้-Dธงgit branchอาจเป็นอันตรายได้ ดังนั้นในคำสั่ง config ด้านบนฉันใช้-dตัวเลือกgit branchมากกว่า-D; ฉันใช้-Dในการกำหนดค่าจริงของฉัน ฉันใช้-Dเพราะฉันไม่ต้องการได้ยิน Git บ่นเกี่ยวกับกิ่งที่ไม่ได้จมน้ำฉันแค่อยากให้พวกมันหายไป คุณอาจต้องการฟังก์ชั่นนี้เช่นกัน หากเป็นเช่นนั้นให้ใช้-Dแทน-dคำสั่งท้ายคำสั่ง config


8

วิธีลบสาขาระยะไกล:

$git remote prune origin

หากต้องการลบสาขาท้องถิ่นที่รวมอยู่แล้ว:

$git branch -D $(git branch --merged)

ได้ผลสำหรับฉัน ขอบคุณ
AndroidRuntimeException

2
(กิ่ง git - แช่) แล้วคืนค่า 'master' ให้ฉันด้วย และสาขาอื่น ๆ ที่ไม่ได้ถูกลบบนรีโมท
Tom G

8
สิ่งนี้ลบสาขาหลักของฉัน
เกร็ก

5

ดูเหมือนจะไม่มีซับในที่ปลอดภัยหนึ่งกรณีขอบมากเกินไป (เช่นสาขาที่มี "ต้นแบบ" เป็นส่วนหนึ่งของชื่อ ฯลฯ ) ที่ปลอดภัยที่สุดคือขั้นตอนเหล่านี้:

  1. git branch -vv | grep 'gone]' > stale_branches.txt
  2. ดูไฟล์และลบบรรทัดสำหรับสาขาที่คุณต้องการเก็บไว้ (เช่นสาขาหลัก!); คุณไม่จำเป็นต้องแก้ไขเนื้อหาของบรรทัดใด ๆ
  3. awk '{print $1}' stale_branches.txt | xargs git branch -d

5

จากคำตอบข้างต้นฉันใช้หนึ่งซับที่สั้นกว่านี้:

git remote prune origin | awk 'BEGIN{FS="origin/"};/pruned/{print $2}' | xargs -r git branch -d

นอกจากนี้หากคุณตัดแต่งกิ่งและมีกิ่งก้านสาขาห้อยอยู่แล้วสิ่งนี้จะทำความสะอาด:

git branch -vv | awk '/^ .*gone/{print $1}' | xargs -r git branch -d

1
ใช้งานไม่ได้หากชื่อสาขาของคุณมีชื่อ/อยู่ในนั้น
Theicfire

4

ไม่แน่ใจว่าจะทำอย่างไรทั้งหมดพร้อมกัน แต่คอมไพล์git branch -d <branchname>จะลบสาขาท้องถิ่นเท่านั้นหากมีการผสานอย่างสมบูรณ์ หมายเหตุตัวพิมพ์เล็ก d

git branch -D <branchname> (สังเกตเมืองหลวง D) จะลบสาขาท้องถิ่นโดยไม่คำนึงถึงสถานะการรวมกิจการ


สำหรับ Windows คำตอบอื่น ๆ ไม่ได้ผลสำหรับฉัน ใช้คำตอบนี้โดยใช้สวิตช์ -D แบบง่าย (แม้ว่าสาขาจะถูก "ลบ" ไปแล้ว)

เราสามารถทำได้สำหรับทุกสาขาพร้อมกันหรือไม่
Teoman shipahi

3

คุณสามารถใช้คำสั่งนี้:

git branch --merged master | grep -v "\* master" | xargs -n 1 git branch -d

Git Clean: ลบสาขาที่ผสานแล้วรวมถึงการแยกคำสั่ง


คุณไม่จำเป็นต้องกรองสาขาใด ๆ (อดีตอาจารย์) หากเป็น "ผสาน" นั่นหมายความว่าจะลบสำเนาในเครื่องของคุณ แต่ "git checkout dev" จะสร้างสาขาท้องถิ่นจากระยะไกลหากยังไม่ปรากฏ
csga5000

แต่รายชื่อสาขาในพื้นที่ยังคงมีอยู่แม้ว่าจะถูกรวมเข้าด้วยกัน คำสั่งนี้จะลบสาขาเหล่านี้ซึ่งถูกลบออกจากระยะไกล
sendon1982

เครื่องหมายดอกจันในการเริ่มต้นหมายถึงสาขาปัจจุบันเมื่อคุณเรียกใช้คำสั่งนั้นในสาขาที่แตกต่างกันจะทำงานได้ไม่ดี
4324

2

จากคำตอบข้างต้นฉันมาพร้อมกับโซลูชันหนึ่งบรรทัดนี้:

git remote prune origin; git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d

2

ใช้ตัวแปรในคำตอบของ @ wisbucky ฉันได้เพิ่มสิ่งต่อไปนี้เป็นนามแฝงใน~/.gitconfigไฟล์ของฉัน:

pruneitgood = "!f() { \
    git remote prune origin; \
    git branch -vv | perl -nae 'system(qw(git branch -d), $F[0]) if $F[3] eq q{gone]}'; \
}; f"

ด้วยวิธีนี้ง่าย ๆgit pruneitgoodจะล้างสาขาท้องถิ่นและระยะไกลที่ไม่ต้องการอีกต่อไปหลังจากผสาน


2

รุ่น Powershell ของ git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

git branch --merged master | %{ if($_ -notmatch '\*.*master'){ git branch -d "$($_.Trim())" }}

นี้จะลบสาขาในประเทศใด ๆ ที่ได้รับการรวมเข้าเป็นหลักในขณะที่คุณอยู่ในสาขาต้นแบบ

git checkout master เพื่อสลับ


1

Schleis 'ตัวแปรไม่ทำงานสำหรับฉัน (Ubuntu 12.04) ดังนั้นฉันขอเสนอตัวแปร (ชัดเจนและเงางาม :) ของฉัน:

ตัวแปร 1 (ฉันต้องการตัวเลือกนี้):

git for-each-ref --format='%(refname:short) %(upstream)' refs/heads/ | awk '$2 !~/^refs\/remotes/' | xargs git branch -D 

ตัวแปร 2:

แห้งทำงาน:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | awk '{print "git branch -D " $1}'

ข ลบสาขา:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | xargs git branch -D

1

ต่อไปนี้เป็นการปรับคำตอบของ @ wisbucky สำหรับผู้ใช้ Windows:

for /f "tokens=1" %i in ('git branch -vv ^| findstr ": gone]"') DO git branch %i -d

ฉันใช้ posh-git และน่าเสียดายที่ PS ไม่ชอบภาพเปลือยforดังนั้นฉันจึงสร้างสคริปต์คำสั่ง 'ol ธรรมดาชื่อ PruneOrphanBranches.cmd:

@ECHO OFF
for /f "tokens=1" %%i in ('git branch -vv ^| findstr ": gone]"') DO CALL :ProcessBranch %%i %1

GOTO :EOF

:ProcessBranch
IF /I "%2%"=="-d" (
    git branch %1 %2
) ELSE (
    CALL :OutputMessage %1
)
GOTO :EOF

:OutputMessage
ECHO Will delete branch [%1] 
GOTO :EOF

:EOF

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


สิ่งนี้ไม่ได้ผลสำหรับฉันไม่ว่าจะด้วยเหตุผลใดก็ตาม:หรือ: (มีที่ว่าง) findstrเพื่อให้ตรงกับทุกอย่างทุกครั้ง - ฉันเกือบจะลบอาจารย์ออกไป อย่างไรก็ตามการใช้ regex ทำงานได้ดี:git branch -vv ^| findstr /R " \[origin/[0-9]+: gone\] "
Josh

1

ลองใช้วิธีนี้ใน gash bash เพื่อดึงและตัดการอ้างอิงไปยังกิ่งที่ถูกลบจากนั้นตัดกิ่งสาขาในพื้นที่ที่กำลังติดตามกิ่งที่ถูกลบออก:

git fetch -p && git branch -d `git branch -vv | grep ': gone]' | awk '{print $1}' | xargs`

อย่าลืมเช็คเอาต์สาขาที่จะไม่ถูกลบก่อนดังนั้นจึงไม่ได้ป้องกันการลบสาขา


0

ฉันเปลี่ยนคำตอบที่ยอมรับให้เป็นสคริปต์ที่มีประสิทธิภาพ คุณจะพบว่าในของฉันเก็บคอมไพล์นามสกุล

$ git-prune --help
Remove old local branches that do not exist in <remote> any more.
With --test, only print which local branches would be deleted.
Usage: git-prune [-t|--test|-f|--force] <remote>

0

ฉันมาถึงหน้านี้เพื่อค้นหาคำตอบสำหรับ "ฉันจะลบสาขาที่เช็คเอาท์ในเครื่องที่ไม่มีสาขาอัปสตรีมได้แล้ว"

ฉันยังไม่สนใจว่าจะรวมสาขาในพื้นที่หรือไม่เนื่องจากการเข้าไปในท่อgit branch -dจะเตือนเพียงแค่การลบสาขาที่ไม่ได้รวมเข้าไป

git branch -a | grep origin | tr -s ' ' | cut -d '/' -f3 | egrep -v -f /dev/fd/0 <(git branch -a | grep -v origin) | grep branch_prefix_that_I_care_about | xargs git branch -d

# translation
# git branch -a | grep origin | tr -s ' ' | cut -d '/' -f3
## this finds all remote branch names minus the "remote/origin/" part
#
# <(git branch -a | grep -v origin)
## this finds all local branch names and redirects it into the previous command
#
# egrep -v -f /dev/fd/0 STUFF
## this is doing some weird magic that I'm grokking as "take the set difference from whatever was piped in"
#
#
# overall translation: (STUFF TO CONSIDER) | egrep magic <(STUFF TO REMOVE FROM CONSIDERATION) | do cool things with resulting stuff


0

นี่คือทางออกของฉัน:

git fetch -p
git branch -vv | grep ": gone" | awk '{print $1}' | xargs git branch -d
  • -pคือการลบการอ้างอิงติดตามระยะไกลใด ๆ ที่ไม่มีอยู่ในระยะไกล ดังนั้นขั้นตอนแรกจะลบการอ้างอิงไปยังสาขาระยะไกล

  • -vv ใช้สำหรับแสดง sha1 และส่งหัวเรื่องสำหรับแต่ละหัวพร้อมกับความสัมพันธ์กับสาขาต้นน้ำ (ถ้ามี) ขั้นตอนที่ 2 จะได้รับสาขาในพื้นที่ทั้งหมดและคำสั่ง grep จะกรองสาขาที่ถูกลบไปแล้ว



-3

ฉันค่อนข้างแน่ใจว่านั่นgit remote prune originคือสิ่งที่คุณต้องการ

คุณสามารถเรียกใช้git remote prune origin --dry-runเพื่อดูว่ามันจะทำอะไรโดยไม่ทำการเปลี่ยนแปลงใด ๆ


12
สิ่งนี้ไม่ได้เป็นการลบสาขาท้องถิ่น
Taytay

-17

ใช้งาน GUI หรือไม่ ขั้นตอนแบบแมนนวล แต่ง่ายและรวดเร็ว

$ git gui

เลือก "สาขา -> ลบ" คุณสามารถเลือกหลายสาขาด้วย ctrl-click (windows) และลบทั้งหมด


มันตลกดีที่คำตอบนี้ถูกมองว่าเป็นลบ วิธีการที่ถูกต้องทั้งหมด IMO ถ้าคุณชอบ GUI
serraosays
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.