2013-05-16 31 views
15
==> git branch -a 
* master 
    test 
    remotes/origin/master 
    remotes/origin/test 

khi ai đó xóa remotes/origin/test, tôi vẫn có thể xem nó trên máy tính của mình.xóa các chi nhánh không ở trên điều khiển từ xa

Tôi biết tôi có thể làm điều này và loại bỏ các test

==> git remote prune 
==> git branch -d test 
==> git branch -a 
* master 
    remotes/origin/master 

Nhưng nếu tôi có chi nhánh địa phương hơn, và họ không vào sâu vùng xa, vậy làm thế nào tôi có thể loại bỏ chúng một cách nhanh chóng?

Trả lời

1

Bạn có thể thực hiện việc này bằng cách lặp qua các lần chỉnh sửa, tôi đã sử dụng lệnh sau để xóa tất cả các nhánh cục bộ không có nhánh từ xa và nó hoạt động. Cảnh báo: thao tác này có tác dụng xóa các nhánh không được hợp nhất hoàn toàn, sử dụng cẩn thận.

git branch -D `git for-each-ref --format="%(fieldName)" refs/heads/<branch-name-pattern>` 

%(fieldName) = refname:short)

refs/heads/ = có thể được hậu tố nếu bạn có một tiền tố common/hậu tố trong tên chi nhánh ví dụ: refs/heads/*abc*

Tham khảo này để biết thêm thông tin git-for-each-ref(1) Manual Page

+0

Với giải pháp của bạn, bạn sẽ buộc phải loại bỏ các nhánh không được sáp nhập hoàn toàn, khá nguy hiểm! – Matteo

18

Theo git-fetch trang thủ công, git fetch -p sẽ "Sau khi tìm nạp, xóa mọi nhánh theo dõi từ xa không còn tồn tại trên remote.` Nếu bạn có các chi nhánh địa phương theo dõi các nhánh từ xa, bạn có thể cần phải cắt tỉa các nhánh đó theo cách thủ công.

+4

nhưng làm thế nào để loại bỏ chi nhánh địa phương không trên điều khiển từ xa? '-p' chỉ xóa theo dõi từ xa – Dozer

+5

Bạn có thể phân biệt một cách đáng tin cậy giữa một chi nhánh địa phương đã được thiết lập để theo dõi một nhánh từ xa so với một nhánh dành cho phát triển cục bộ không? Nếu nhánh địa phương của tôi có tên là 'foo', ban đầu nó được tạo ra để theo dõi' remote/origin/foo', hay là một nhánh địa phương mà tôi tạo ra để kiểm tra một số ý tưởng mới? Nếu bạn có thể trả lời câu hỏi đó một cách đáng tin cậy cho mỗi nhánh địa phương, bạn có thể 'git branch -D' những cái bạn không muốn. Nếu bạn không thể, cố gắng làm điều đó "tự động" sẽ phá hoại. – twalberg

26

Đây là cách để loại bỏ các chi nhánh địa phương mà không phải là còn phù hợp nữa:

git branch --merged origin/master | xargs git branch -d 

Bạn có thể cần phải tinh chỉnh nó theo cấu hình cụ thể của bạn, nhưng lệnh đầu tiên ở đây trước ống nên cung cấp cho bạn một danh sách tất cả các chi nhánh địa phương của bạn đã được sáp nhập vào chi nhánh chính của bạn.

+14

Vì sợ xóa chủ nhân cục bộ, tôi đã sửa đổi điều này thành: 'nhánh git - nguồn gốc cố định/chủ | grep -v master | xargs git branch -d' – thexfactor

+3

Nitpicky thay đổi bình luận ở trên, nhưng để tránh loại bỏ các nhánh khác ngoài "master" vô tình (tức là "phát triển" trong Gitflow), có lẽ tốt hơn là không đảo ngược lệnh grep và thay vào đó : 'git branch --merged origin/phát triển | grep "^ \ s * tính năng /" | xargs git branch -d' –

3

Tôi đã viết một kịch bản lệnh shell đơn giản có tên là git-dangling-branches cho mục đích này. Nếu bạn chỉ định tùy chọn -D, nó sẽ xóa tất cả các nhánh cục bộ không có refs/remotes/origin/<branch_name>. Tất nhiên, bạn nên cẩn thận khi bạn làm điều đó.

#!/bin/bash -e 
if [[ "$1" == '-D' ]]; then 
    DELETE=1 
else 
    DELETE=0 
fi 

REMOTE_BRANCHES="`mktemp`" 
LOCAL_BRANCHES="`mktemp`" 
DANGLING_BRANCHES="`mktemp`" 
git for-each-ref --format="%(refname)" refs/remotes/origin/ | \ 
    sed 's#^refs/remotes/origin/##' > "$REMOTE_BRANCHES" 
git for-each-ref --format="%(refname)" refs/heads/ | \ 
    sed 's#^refs/heads/##' > "$LOCAL_BRANCHES" 
grep -vxF -f "$REMOTE_BRANCHES" "$LOCAL_BRANCHES" | \ 
    sort -V > "$DANGLING_BRANCHES" 
rm -f "$REMOTE_BRANCHES" "$LOCAL_BRANCHES" 

if [[ $DELETE -ne 0 ]]; then 
    cat "$DANGLING_BRANCHES" | while read -r B; do 
    git branch -D "$B" 
    done 
else 
    cat "$DANGLING_BRANCHES" 
fi 
rm -f "$DANGLING_BRANCHES" 
+0

Đây là câu trả lời tôi muốn. Tôi quan tâm đến việc xóa các chi nhánh địa phương không tồn tại với cùng tên trong github. Các câu trả lời khác loại bỏ các nhánh theo dõi từ xa và loại bỏ tất cả các nhánh đã hợp nhất, nhưng đó không phải là những gì tôi muốn. Cảm ơn vì điều này. Tôi đã thay đổi -D để -d trước khi chạy nó, chỉ trong trường hợp. –

+0

Điều này thật tuyệt vời. Tôi đã phải thay đổi 'mktemp' để liên lạc với tên tập tin thực tế bởi vì' mktemp' không được hỗ trợ trong hệ điều hành của tôi, nhưng điều này hoàn toàn tuyệt vời. – earl3s

+0

Tôi cũng bổ sung điều này: 'git remote prune origin $ DRY_RUN' ở phía trên, nơi' $ DRY_RUN' được đặt thành '--dry-run' nếu' -D' không được chuyển. Làm sạch hệ thống của tôi một cách độc đáo. – earl3s

3

Cắt tỉa đơn giản sẽ không xóa chi nhánh địa phương.

Đây là một cách tiếp cận khác để đạt được sự xóa thực sự. Hãy chắc chắn để thực hiện "git fetch -p" đầu tiên để có được trạng thái mới nhất của kho từ xa.

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

Điều này sẽ kiểm tra tất cả các chi nhánh địa phương và nguồn gốc của chúng và xóa tất cả các nhánh địa phương có nguồn gốc bị xóa.

Cụ thể:

git branch -vv 

sẽ liệt kê các chi nhánh địa phương của bạn và hiển thị thông tin về chi nhánh ở xa, nói rằng “đi” nếu nó không được trình bày nữa.

grep ' gone]' 

sẽ tìm nạp các nhánh khớp với cụm từ "đã biến mất".

awk '{print $1}' 

sẽ tìm đầu ra cho đến khoảng trắng đầu tiên, sẽ dẫn đến tên chi nhánh địa phương.

xargs git branch -d 

sẽ sử dụng đầu ra (tên chi nhánh) và nối nó vào lệnh “git branch -d” để xóa chi nhánh cuối cùng. Nếu bạn cũng muốn xóa các nhánh không được hợp nhất hoàn toàn, bạn có thể sử dụng một chữ “D” thay vì “d” để bắt buộc xóa.

1

Tôi đã kết thúc bằng một cái gì đó rất giống với cách tiếp cận của kcm. Tôi muốn một cái gì đó mà sẽ thanh trừng tất cả các chi nhánh địa phương đang theo dõi một chi nhánh từ xa, trên origin, nơi chi nhánh từ xa đã bị xóa (gone). Tôi không muốn xóa các chi nhánh địa phương chưa bao giờ được thiết lập để theo dõi chi nhánh từ xa (ví dụ: các chi nhánh nhà phát triển địa phương của tôi). Ngoài ra, tôi muốn có một lớp lót đơn giản chỉ sử dụng git hoặc các công cụ CLI đơn giản khác thay vì viết các tập lệnh tùy chỉnh. Tôi đã sử dụng một chút grepawk để thực hiện lệnh đơn giản này sau đó thêm nó làm bí danh trong số ~/.gitconfig của tôi.

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

Đây là một lệnh git config --global ... để dễ dàng thêm này như 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' 

LƯU Ý: Như Matteo chỉ ra trong bình luận trước đó của ông về câu trả lời khác, sử dụng các -D cờ để git branch có thể rất nguy hiểm. Vì vậy, trong lệnh config tôi sử dụng tùy chọn -d để git branch thay vì -D; Tôi sử dụng -D trong cấu hình thực tế của mình. Tôi sử dụng -D bởi vì tôi không muốn nghe Git phàn nàn về các nhánh chưa được nhấn mạnh, tôi chỉ muốn chúng biến mất. Bạn cũng có thể muốn chức năng này. Nếu vậy, chỉ cần sử dụng -D thay vì -d ở cuối lệnh cấu hình đó.

Các vấn đề liên quan