ลบกิ่ง Git ท้องถิ่นหลังจากลบใน repo ระยะไกล


162

ฉันต้องการให้ที่เก็บข้อมูลในพื้นที่และระยะไกลของฉันซิงค์กันในแง่ของสาขาเสมอ

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


คุณต้องการลบสาขาการติดตามระยะไกลสาขาในพื้นที่หรือทั้งสองอย่าง? คุณสามารถเขียนนามแฝง (ทุบตีหรือคอมไพล์) ที่จะลบสาขารีโมตที่ถูกลบทั้งหมดและค้นหาสำเนาโลคัลเพื่อลบด้วยทั้งหมดในคำสั่งเดียว

อาจจะลองใช้คำสั่งดังต่อไปนี้จะเกิดขึ้นกับบางสิ่งบางอย่างและgit ls-remote git show-ref

นอกจากนี้คุณอาจต้องการที่จะตรวจสอบและgit symbolic-ref git update-ref

ขอบคุณสำหรับความช่วยเหลือของคุณฉันสิ้นสุดการค้นหาคำตอบที่อื่น ดูคำตอบของฉัน
sf89

3
ซ้ำซ้อนที่เป็นไปได้ของการลบสาขาไม่ได้อยู่ในระยะไกลอีกต่อไป
amaechler

คำตอบ:


180

วิธีที่รวดเร็ว

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

หมายเหตุ: หากคุณไม่ได้อยู่masterนี้มีโอกาสที่จะลบสาขา อ่านต่อไปสำหรับ "วิธีที่ดีกว่า"

ตรวจสอบให้แน่ใจว่าเรามีความเชี่ยวชาญ

คุณสามารถมั่นใจได้ว่าmasterหรือสาขาอื่น ๆ สำหรับเรื่องดังกล่าวจะไม่ถูกลบออกไปgrepอีก ในกรณีนี้คุณจะไป:

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

ดังนั้นหากเราต้องการที่จะเก็บmaster, developและstagingสำหรับตัวอย่างเช่นเราจะไป:

git branch --merged | grep -v "\*" | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d

ทำให้เป็นชื่อแทน

เพราะมันเป็นบิตนานคุณอาจต้องการเพิ่มนามแฝงที่คุณหรือ.zshrc .bashrcของฉันถูกเรียกgbpurge(สำหรับgit branches purge):

alias gbpurge='git branch --merged | grep -Ev "(\*|master|develop|staging)" | xargs -n 1 git branch -d'

จากนั้นโหลดซ้ำของคุณ.bashrcหรือ.zshrc:

. ~/.bashrc

หรือ

. ~/.zshrc

คุณสามารถใส่คำสั่งในนามแฝงและทำให้มันเป็นคำสั่งเดียว อย่างไรก็ตามเนื่องจากbranchเป็นเครื่องเคลือบดินเผาและไม่ใช่คำสั่งการใช้งานระบบประปาโปรดระวังการเปลี่ยนแปลง UI ใด ๆ ใน Git รุ่นต่อไปที่อาจแตกหัก

1
ที่สมบูรณ์แบบ! โปรดทราบว่าหลังจาก Github Workflow สาขาท้องถิ่นmasterจะถูกลบ
รูเบนส์ Mariuzzo

ไม่แน่ใจว่ามันอยู่ที่นั่น (ฉันใช้มันทุกวัน
sf89

4
FYI ถ้าคุณต้องการเก็บสาขาหลายสาขาคุณสามารถใช้ grep เดียวเช่น: grep -Ev '(\*|master|important-branch)'
Andrew Burns

4
หากคุณต้องการใส่สิ่งนี้ลงไป~/.gitconfigแทนให้เพิ่มสิ่งต่อไปนี้ใน[alias]ส่วน: gbpurge = !"git branch --merged | grep -Ev '\\*|master|develop|staging' | xargs -n 1 git branch -d"(ไม่จำเป็นต้องใช้ () ในนิพจน์ grep)
dskrvk

82

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

git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d

ที่อยู่:

  • git fetch --all -p: อัพเดทสถานะสาขาท้องถิ่น
  • git branch -vv: แสดงสถานะสาขาท้องถิ่น
  • grep ": gone]": ตัวกรองที่ถูกลบ
  • awk '{ print $1 }': แยกชื่อของพวกเขา
  • xargs -n 1 git branch -d: ส่งชื่อไปยังคำสั่งลบ

หมายเหตุ: หากคุณต้องการคุณสามารถใช้ -D แทน -d ซึ่งบังคับให้ลบ

ตัวอย่างเช่น:

someUsr@someHost:~/repo$ git branch -a
basic-testing
integration-for-tests
* master
origin
playground-for-tests
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services

someUsr@someHost:~/repo$ git fetch --all -p; git branch -vv | grep ": gone]" | awk '{ print $1 }' | xargs -n 1 git branch -d
Fetching origin
Deleted branch integration-for-tests (was fbc609a).
Deleted branch playground-for-tests (was 584b900).

someUsr@someHost:~/repo$ git branch -a
basic-testing
* master
origin
test-services
remotes/origin/HEAD -> origin/master
remotes/origin/basic-testing
remotes/origin/master
remotes/origin/test-services

อ้างอิง:

http://git-scm.com/book/en/v2/Git-Branching-Remote-Branches


3
ฉันเอาเสรีภาพเพื่อให้มั่นใจว่าฉันมักจะทำอย่างนั้นต่อนายจึง: git checkout master; git pull origin master; git fetch --all -p; git branch -vv | grep gone | awk '{ print $1 }' | xargs -n 1 git branch -d ที่ดีสคริปต์และคำอธิบายขอขอบคุณสำหรับ :) ว่า
Miguelgraz

โปรดทราบว่าbranch -vvแสดงข้อความการส่งครั้งล่าสุดจากสาขา หากคุณมีข้อความ "หายไป" ในข้อความนั้นgrep goneจะตีสาขานั้นด้วย ดังนั้นgrep ": gone]"อาจปลอดภัยกว่าการใช้งานเล็กน้อย
chawkinsuf

1
นี่คือคำตอบที่แท้จริงสำหรับคำถาม ขอบคุณ.
Andrei Gladkyi

1
ดียิ่งขึ้น:awk '$3 $4 ~ /:gone]$/ { print $1 }'
Jakub Bochenski

3
นอกเหนือจากความต้องการ-Dแทนที่จะ-dเป็นคำตอบที่สมบูรณ์แบบ!
Cas

72

ลอง:

git pull --prune

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

Updated:

ข้อความข้างต้นไม่ถูกต้อง

ในความเป็นจริงการทำงานgit pull --pruneจะลบเฉพาะสาขาติดตามระยะไกลเช่นนี้

รีโมท / กำเนิด / fff
รีโมท / กำเนิด / dev
รีโมท / กำเนิด / Master

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

ต้นกำเนิด / dev
ต้นกำเนิด / Master

ซึ่งหมายความว่าorigin/fffจะถูกลบสาขา

ดังนั้นหลังจากทำงานgit pull --pruneเพียงรัน:

git branch --merged | grep -vFf <(git branch -r | cut -d'/' -f2-)

คุณสามารถค้นหาสาขาท้องถิ่นทั้งหมดซึ่ง:

  1. ไม่มีกิ่งก้านสาขาที่ไกลออกไปอีกแล้ว
  2. สามารถลบออกได้อย่างปลอดภัย

จากนั้น<the command above> | xargs git branch -dสามารถลบทั้งหมดได้


42
คำตอบนี้ไม่ถูกต้องนัก การ--pruneตั้งค่าสถานะจะลบเฉพาะสาขาที่ติดตามระยะไกลไม่ใช่สาขาในพื้นที่

3
เห็นด้วยกับ @Cupcake ที่นี่นี่ไม่ได้สิ่งที่ฉันกำลังมองหาที่นี่
sf89

6
ไม่ไปอัปโหลด แต่นี่คือสิ่งที่ฉันต้องการหลังจากลบสาขาในพื้นที่แล้วลบออกจาก GitHub แต่ยังคงมีอยู่เป็นรีโมตในคำสั่ง git remote -v ของฉัน
Spechal

8
คุณสามารถทำได้git fetch --pruneนั่นคือวิธีที่ฉันเลือก
e_m0ney

1
อีกข้อผิดพลาด Git จากคำแนะนำที่พบในสแต็คล้น ... git pull --pruneส่งผลให้"คุณขอให้ดึงจากระยะไกล '--prune' แต่ไม่ได้ระบุสาขาเพราะนี่ไม่ใช่ค่าเริ่มต้นกำหนดค่าระยะไกลสำหรับสาขาปัจจุบันของคุณคุณ ต้องระบุสาขาในบรรทัดคำสั่ง "
jww

23

การดำเนินการนี้ควรหลีกเลี่ยงการลบสาขาหลักและสาขาการพัฒนาด้วยโซลูชันที่ได้รับการยอมรับ:

git branch --merged | egrep -v "^\*|master|development" | xargs -n 1 git branch -d

16

สำหรับผู้ที่ใช้ PowerShell นี่เทียบเท่ากับคำตอบข้างต้น :

git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
  1. กรองสาขาทั้งหมดที่ทำเครื่องหมายว่าหายไป
  2. โทรหาgit branch -Dแต่ละสาขาที่พบ

6

สิ่งนี้ไม่ได้ผลสำหรับฉัน คุณสามารถดูคำตอบอื่น ๆ ของฉันได้ที่นี่: https://stackoverflow.com/a/34969726/550454

แต่ตอนนี้ฉันมีสิ่งนี้ใน~/.gitconfig:

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

5

วิธีการแก้ปัญหาที่ง่ายมาก: ลบ repo ในพื้นที่ของคุณและคัดลอกรีโมทอันใหม่ อาจไม่ดูหรูหรามาก แต่มันง่ายและคุณจะเข้าใจว่าคุณกำลังทำอะไรโดยไม่ต้องอ่าน man pages :-)


1
ทำไม downvotes มากมาย? ฉันหมายถึงเห็นได้ชัดว่าไม่ได้มีประสิทธิภาพโดยเฉพาะอย่างยิ่งกับ repos ที่มีขนาดใหญ่กว่า มีเหตุผลอื่นอีกไหมที่จะไม่ทำเช่นนี้?
3ocene

6
เพราะคุณจะสูญเสียสาขาในประเทศของคุณหยุดทำงานไม่ได้ทำอะไรเลย ... มันเหมือนกับการตกปลากับไดนาไมต์
sevenseacat

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

1

ฉันได้เขียนหนึ่งสายการบินเพื่อแสดงรายการสาขาในประเทศทั้งหมดซึ่งไม่มีสาขาระยะไกลที่เกี่ยวข้อง:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -

หลังจากเสร็จสิ้นการลบสาขาท้องถิ่นเหล่านี้จะทำได้ง่ายๆด้วยxargs:

diff -u <(git branch|sed 's/..//') <(git branch -r|sed 's/..origin\///')|tail -n +4|sed -n "s/^-//p" -|xargs -r git branch -d

นี่เป็นรายการของฉันmasterเช่นกันมันใช้งานไม่ได้ตามที่คาดไว้ ระวัง
Enrico

1

ฉันเพิ่งทำเช่นนั้นเพื่อลบสาขาในพื้นที่ที่ถูกผสาน:

git branch -d $(git branch --merged)

และในกรณีที่คุณต้องการลบแทร็กที่ไม่มีอยู่ด้วย:

git pull --prune

1

ในกรณีที่คุณเพิ่งผลักและรวมสาขาของคุณเป็นหลักแล้วทำสิ่งต่อไปนี้ใน git bash:

git branch -d branch_name_to_delete

หากคุณอยู่ในสาขานั้นในปัจจุบันมันจะผลักคุณกลับไปที่หลัก ณ จุดนี้ทำดึงด้วย

git pull

-2

คำตอบที่โหวตมีศักยภาพในการลบข้อมูลหลัก พิจารณาตัวอย่างการปฏิบัติด้านล่าง

ฉันมีฟีเจอร์สองสาขา hemen_README และ hemen_BASEBOX ที่รวมเข้ากับการพัฒนาจากนั้นการพัฒนาก็ถูกรวมเข้ากับมาสเตอร์ คุณลักษณะสาขา hemen_README และ hemen_BASEBOX ถูกลบออกจากระยะไกล แต่ยังคงปรากฏขึ้นในเครื่อง นอกจากนี้ฉันไม่ได้อยู่ในระดับท้องถิ่น แต่พัฒนา

ในกรณีนั้น

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                      671ad6c Merged in hemen_README (pull request #1)
        hemen_BASEBOX                a535c0f added global exec paths to puppet manifest
        hemen_README                 ba87489 Updated Readme with considerable details
        master                       8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop       671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/hemen_BASEBOX a535c0f added global exec paths to puppet manifest
        remotes/origin/hemen_README  ba87489 Updated Readme with considerable details
        remotes/origin/master        2f093ce Merged in develop (pull request #3)

ดังนั้นถ้าฉันใช้คำสั่งบางส่วนข้างต้น

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch --merged | grep -v "\*"
        hemen_BASEBOX
        hemen_README
        master

โปรดสังเกตว่ามันจะแสดงมาสเตอร์เช่นกันซึ่งจะถูกลบในที่สุด

ไม่ว่าในกรณีใดฉันก็สามารถทำได้ ฉันแบ่งปันบันทึกเซสชันของฉันกับคุณเกี่ยวกับวิธีการที่ฉันประสบความสำเร็จ

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin --dry-run
    Pruning origin
    URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
     * [would prune] origin/hemen_BASEBOX
     * [would prune] origin/hemen_README
    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git remote prune origin 
    Pruning origin
    URL: git@bitbucket.org:hemenkapadiapublic/vagrant-webdev.git
     * [pruned] origin/hemen_BASEBOX
     * [pruned] origin/hemen_README

ฉันเพิ่งตรวจสอบว่ามีการตัดแล้วและจะตัดทิ้ง เมื่อดูที่คำสั่งสาขาด้านล่างเราได้ดูแลรีโมท

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                671ad6c Merged in hemen_README (pull request #1)
        hemen_BASEBOX          a535c0f added global exec paths to puppet manifest
        hemen_README           ba87489 Updated Readme with considerable details
        master                 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/master  2f093ce Merged in develop (pull request #3)

ตอนนี้ไปข้างหน้าและลบสาขาท้องถิ่น

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_BASEBOX 
    Deleted branch hemen_BASEBOX (was a535c0f).
    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -d hemen_README
    Deleted branch hemen_README (was ba87489).

ดีตอนนี้กิ่งไม้เป็นที่ต้องการ

    hemen@hemen-MXC061:~/data/projects/vagrant-webdev$ git branch -v -a
    * develop                671ad6c Merged in hemen_README (pull request #1)
        master                 8980894 [behind 7] Initial Vagrantfile, works for vagrant up. Also initial .gitignore
        remotes/origin/develop 671ad6c Merged in hemen_README (pull request #1)
        remotes/origin/master  2f093ce Merged in develop (pull request #3)

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