Xóa các nhánh Git cục bộ sau khi xóa chúng trên repo từ xa


162

Tôi muốn có các kho lưu trữ cục bộ và từ xa luôn đồng bộ về các nhánh.

Sau khi xem xét Yêu cầu kéo trên GitHub, tôi hợp nhất và xóa chi nhánh của mình ở đó (từ xa). Làm cách nào tôi có thể tìm nạp thông tin này trong kho lưu trữ cục bộ của mình và yêu cầu Git xóa phiên bản chi nhánh địa phương của tôi?


Bạn có muốn xóa các nhánh theo dõi từ xa, các nhánh cục bộ hoặc cả hai không? Bạn thực sự có thể viết một bí danh (bash hoặc git) sẽ lấy tất cả các nhánh từ xa bị xóa và tìm các bản sao cục bộ để xóa quá, tất cả trong một lệnh.

Có thể thử sử dụng các lệnh sau để đưa ra một cái gì đó, git ls-remotegit show-ref.

Ngoài ra, bạn có thể muốn kiểm tra git symbolic-refgit update-ref.

cảm ơn sự giúp đỡ của bạn, cuối cùng tôi đã tìm thấy câu trả lời ở một nơi khác. Xem phản ứng của tôi.
sf89

3
Bản sao có thể bị xóa
amaechler

Câu trả lời:


180

Cách nhanh chóng

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

NB: nếu bạn không bật master, điều này có khả năng xóa chi nhánh. Tiếp tục đọc cho "cách tốt hơn".

Hãy chắc chắn rằng chúng tôi giữ chủ

Bạn có thể đảm bảo rằng master, hoặc bất kỳ chi nhánh nào khác cho vấn đề đó, không bị xóa bằng cách greplấy thêm. Trong trường hợp đó bạn sẽ đi:

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

Vì vậy, nếu chúng tôi muốn giữ master, developstagingví dụ, chúng tôi sẽ đi:

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

Làm cho điều này một bí danh

Vì nó hơi dài, bạn có thể muốn thêm bí danh cho .zshrchoặc .bashrc. Của tôi được gọi là gbpurge(cho git branches purge):

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

Sau đó tải lại .bashrchoặc .zshrc:

. ~/.bashrc

hoặc là

. ~/.zshrc

Bạn có thể đặt các lệnh trong một bí danh và biến nó thành một lệnh duy nhất. Tuy nhiên, vì branchđồ sứ và không phải là lệnh ống nước , hãy coi chừng mọi thay đổi UI trong các phiên bản Git trong tương lai có thể phá vỡ nó.

1
Hoàn hảo! Lưu ý rằng theo quy trình Github, nhánh cục bộ mastersẽ bị xóa.
Rubens Mariuzzo

Không chắc chắn rằng nó vẫn ở đó (Tôi đang sử dụng nó hàng ngày và dường như không làm điều đó).
sf89

4
FYI nếu bạn muốn giữ nhiều chi nhánh, bạn có thể sử dụng một grep duy nhất, như vậy: grep -Ev '(\*|master|important-branch)'
Andrew Burns

4
Nếu bạn muốn đặt cái này vào ~/.gitconfigthay thế, hãy thêm phần sau vào [alias]phần: gbpurge = !"git branch --merged | grep -Ev '\\*|master|develop|staging' | xargs -n 1 git branch -d"(không cần sử dụng () trong biểu thức grep).
dskrvk

82

Tôi sử dụng cùng một luồng với GitHub và không tìm thấy câu trả lời trước nào thỏa mãn tôi, vì git branch --mergeddanh sách các nhánh được hợp nhất, nhưng không phải tất cả chúng đều bị xóa từ xa trong trường hợp của tôi. Vì vậy, điều này làm việc cho tôi:

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

Ở đâu:

  • git fetch --all -p: cập nhật trạng thái chi nhánh địa phương
  • git branch -vv: liệt kê trạng thái chi nhánh địa phương
  • grep ": gone]": bộ lọc đã xóa
  • awk '{ print $1 }': trích xuất tên của họ
  • xargs -n 1 git branch -d: chuyển tên cho lệnh xóa

Lưu ý: nếu bạn thích, bạn có thể sử dụng -D thay vì -d, để thực thi xóa.

Ví 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

Tài liệu tham khảo:

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


3
Tôi đã tự do để đảm bảo rằng tôi sẽ luôn luôn làm điều đó chống lại chủ nhân, do đó: 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 Kịch bản và lời giải thích tuyệt vời, cảm ơn bạn vì điều đó :)
Miguelgraz

Lưu ý rằng branch -vvhiển thị thông báo cam kết cuối cùng từ chi nhánh. Nếu bạn tình cờ "đi" trong tin nhắn đó, grep gonenó cũng sẽ chạm vào nhánh đó. Vì vậy, grep ": gone]"có lẽ an toàn hơn một chút để sử dụng.
chawkinsuf

1
Đây là câu trả lời thực tế cho câu hỏi. Cảm ơn bạn.
Andrei Gladkyi

1
Thậm chí tốt hơn:awk '$3 $4 ~ /:gone]$/ { print $1 }'
Jakub Bochenski

3
Ngoài việc cần -Dthay vì -dđây là câu trả lời hoàn hảo!
Cas

72

thử:

git kéo --prune

mà xóa chi nhánh địa phương của bạn, nếu chi nhánh từ xa tương ứng của nó bị xóa.

Cập nhật:

Các tuyên bố trên là không chính xác.

Trên thực tế, việc chạy git pull --prunesẽ chỉ XÓA các nhánh theo dõi từ xa như

điều khiển từ xa / nguồn gốc / fff
điều khiển từ xa / nguồn gốc / dev
điều khiển từ xa / nguồn gốc / chủ

Sau đó, bạn có thể chạy git branch -rđể kiểm tra các nhánh theo dõi từ xa còn lại trên máy của bạn. Giả sử các nhánh bên trái là:

nguồn gốc / dev
nguồn gốc / chủ

có nghĩa là chi nhánh origin/fffbị xóa.

Vì vậy, sau khi chạy git pull --prune, chỉ cần chạy:

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

bạn có thể tìm hiểu tất cả các chi nhánh địa phương:

  1. không có sửa lỗi chi nhánh từ xa nữa;
  2. có thể được gỡ bỏ một cách an toàn.

Sau đó, <the command above> | xargs git branch -dcó thể xóa tất cả chúng.


42
Câu trả lời này không hoàn toàn chính xác. Các --prunelá cờ sẽ chỉ xóa các chi nhánh từ xa theo dõi, không chi nhánh địa phương.

3
Đồng ý với @Cupdding ở đây, điều này không đạt được những gì tôi đang tìm kiếm ở đây.
sf89

6
Sẽ không upvote, nhưng đây là những gì tôi cần sau khi xóa các nhánh cục bộ và sau đó xóa khỏi GitHub nhưng chúng vẫn tồn tại dưới dạng từ xa trong lệnh git remote -v của tôi.
Spechal 2/214

8
Bạn cũng có thể làm git fetch --prune, đó là cách tôi chọn
e_m0ney

1
Tuy nhiên, một lỗi Git khác từ lời khuyên được tìm thấy trên Stack overflow ... git pull --prunedẫn đến "Bạn đã yêu cầu kéo từ xa '--prune', nhưng không chỉ định một nhánh. Bởi vì đây không phải là điều khiển từ xa được cấu hình mặc định cho nhánh hiện tại của bạn, bạn phải chỉ định một nhánh trên dòng lệnh. "
jww

23

Điều này sẽ hoạt động để tránh xóa các nhánh chínhphát triển với giải pháp được chấp nhận:

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

16

Đối với những người sử dụng powershell, điều này tương đương với câu trả lời ở trên :

git branch -vv | Select-String -Pattern ': gone]' | ForEach-Object{($_ -split "\s+")[1]} | %{ git branch -D $_ }
  1. Lọc tất cả các nhánh được đánh dấu là đã biến mất
  2. Gọi git branch -Dcho từng chi nhánh được tìm thấy

6

Không ai trong số này đã làm việc cho tôi. Bạn có thể xem câu trả lời khác của tôi ở đây: https://stackoverflow.com/a/34969726/550454

Nhưng về cơ bản, bây giờ tôi có cái này trong ~/.gitconfig:

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

5

Giải pháp rất đơn giản: xóa repo cục bộ của bạn và sao chép từ xa một lần nữa. Có thể không có vẻ rất thanh lịch, nhưng nó đơn giản và bạn sẽ hiểu chính xác những gì bạn đang làm mà không cần đọc trang người đàn ông :-).


1
Tại sao rất nhiều downvote? Tôi có nghĩa là rõ ràng là không hiệu quả, đặc biệt là với repos lớn hơn, nhưng nó làm những gì OP yêu cầu. Có một số lý do khác để không làm điều này?
3ocene

6
Bởi vì bạn sẽ mất tất cả các chi nhánh địa phương, stash, cam kết không được đánh dấu ... nó giống như câu cá bằng thuốc nổ.
Sevenseacat

1
Điều tương tự cũng xảy ra khi máy tính xách tay bạn đang làm việc bằng cách nào đó bị hỏng, bị mất hoặc bị đánh cắp, vì vậy tôi có xu hướng không giữ gì cả quan trọng tại địa phương. Tôi có vẻ tốt hơn khi chỉ tạo một nhánh và đẩy nó, ngay cả đối với các tính năng nhỏ và xóa nó sau khi nó không còn hữu ích nữa.

1

Tôi đã viết một lớp lót này để liệt kê tất cả các chi nhánh địa phương không có chi nhánh từ xa tương ứng:

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

Sau khi hoàn thành, việc xóa các nhánh cục bộ này trở nên dễ dàng với 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

đây cũng là danh sách của tôi master, nó không hoạt động như mong đợi; hãy cẩn thận
Enrico

1

Tôi chỉ làm điều đó để loại bỏ các chi nhánh địa phương sáp nhập:

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

và trong trường hợp bạn cũng muốn xóa theo dõi không tồn tại:

git pull --prune

1

Trong trường hợp bạn vừa đẩy và sáp nhập chi nhánh của mình thành chủ, sau đó thực hiện các thao tác sau trong git bash:

git branch -d branch_name_to_delete

Nếu bạn hiện đang ở chi nhánh đó, nó sẽ đẩy bạn trở lại thành thạo. Tại thời điểm này làm một kéo với

git pull

-2

Câu trả lời được bình chọn có khả năng xóa chủ. Consdier ví dụ thực tế dưới đây.

Tôi đã có hai nhánh tính năng hemen_README và hemen_BASEBOX được hợp nhất để phát triển và sau đó phát triển được hợp nhất thành chủ. Các nhánh tính năng hemen_README và hemen_BASEBOX đã bị xóa từ xa nhưng vẫn hiển thị cục bộ. Ngoài ra tôi không phải là chủ địa phương, nhưng đang phát triển.

Trong trường hợp đó

    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)

Vì vậy, nếu tôi chạy lệnh một phần ở trên

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

Lưu ý rằng nó cũng hiển thị chủ, cuối cùng sẽ bị xóa.

Trong mọi trường hợp tôi đã có thể làm điều đó. Tôi đang chia sẻ nhật ký phiên của tôi với bạn về cách tôi đạt được điều đó.

    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

Tôi chỉ cần kiểm tra whay sẽ được cắt tỉa và sau đó cắt tỉa nó. Nhìn vào lệnh nhánh bên dưới, chúng tôi đã chăm sóc từ xa

    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)

Bây giờ hãy tiếp tục và xóa các chi nhánh địa phương

    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).

Tốt bây giờ các chi nhánh là như mong muốn.

    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)

Tất nhiên nó có tiềm năng xóa chủ. Xin vui lòng đọc câu hỏi cẩn thận. Như tôi đã nói ở đó, tôi cần một cách để dọn dẹp mọi thứ trên địa phương của tôi. Điều đó có nghĩa là xóa tất cả các nhánh không còn tồn tại trên remote. Nếu chủ không còn ở đó nữa, thì nó cũng sẽ biến mất trên máy cục bộ của bạn.
sf89
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.