Bạn có thể xóa nhiều nhánh trong một lệnh bằng Git không?


355

Tôi muốn dọn dẹp kho địa phương của tôi, trong đó có một tấn các chi nhánh cũ: ví dụ 3.2, 3.2.1, 3.2.2vv

Tôi đã hy vọng cho một cách lén lút để loại bỏ rất nhiều trong số họ cùng một lúc. Vì họ chủ yếu tuân theo quy ước phát hành dấu chấm, tôi nghĩ có lẽ có một lối tắt để nói:

git branch -D 3.2.*

và tiêu diệt tất cả các nhánh 3.2.x.

Tôi đã thử lệnh đó và tất nhiên nó không hoạt động.


11
git branch -D $(git branch | grep 3.2*)- điều này làm việc cho tôi. Nó xóa các nhánh có tên bắt đầu bằng "3.2". grep- khớp mẫu trong đầu ra ( git branchtrong trường hợp này). $()- có nghĩa là thực hiện và đặt kết quả. |- xích.
Eduard

4
Đáng lưu ý đối với những người không biết, đó -Dlà xóa lực lượng , nên sử dụng -dtrong hầu hết các trường hợp để an toàn hơn trước.
redfox05

Câu trả lời:


363

Không phải với cú pháp đó. Nhưng bạn có thể làm điều đó như thế này:

git branch -D 3.2 3.2.1 3.2.2

Về cơ bản, nhánh git sẽ xóa nhiều nhánh cho bạn bằng một lệnh gọi duy nhất. Thật không may, nó không hoàn thành tên chi nhánh. Mặc dù, trong bash, bạn có thể làm:

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

2
Việc hoàn thành git branch -D/-dcông việc tốt cho tôi. Có thể muốn cập nhật của bạn (có thể từ thư mục contrib git.git gần đây nhất).
Cascabel

19
Thay vì git branch | ...bạn có thể sử dụng $(git for-each-ref --format='%(refname:short)' refs/heads/3.*). Tôi biết nó dài hơn, nhưng nó được đảm bảo là đầu ra phù hợp, trong khi git branchcó đầu ra khá với những thứ như *->(đối với symrefs) có thể khiến bạn rối tung trong các tập lệnh / một lớp.
Cascabel

3
Có lẽ tôi là người duy nhất gặp vấn đề này, nhưng tôi đã grepbí danh luôn luôn bao gồm cờ --color=always- git branch -Dđã ném error: branch 'my_branch' not found.cho đến khi tôi chạy mà không có cờ màu.
eebbesen

@eebbesen Bạn đã vô hiệu hóa nó trên toàn cầu? Tôi gặp vấn đề tương tự khi chạygit branch --merged ${1-$(current_branch)} | grep -v ${1-$(current_branch)} | xargs git branch -d
qmmr

2
Với mở rộng cú đúp, bạn có thể viết git branch -D 3.2{,.1,.2}để xóa cả ba nhánh gnu.org/software/bash/manual/html_node/Brace-Expansion.html
robstarbuck

147

Chà, trong trường hợp xấu nhất, bạn có thể sử dụng:

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

22
Đây là phương pháp hoàn hảo cho bất kỳ ai sử dụng ký hiệu tiền tố được tiêu chuẩn hóa cho tên chi nhánh (ví dụ: "fix / ..." hoặc "Feature / ...").
Haz

4
Đơn giản và hiệu quả! Tôi khuyên bạn nên chạy trước mà không có | xargs git branch -dphần để kiểm tra xem cái gì thực sự sẽ bị xóa.
mathielo

Bạn không nên grepđầu ra git branch, vì nó có nghĩa là để đọc, không phân tích cú pháp. Có thể thay đổi bất cứ lúc nào. sử dụng for-each-refcùng với các thông số --format, như được đề xuất trong các câu trả lời khác, và sau đó kết hợp với các gợi ý trong câu trả lời này.
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

BIÊN TẬP:

Một phiên bản an toàn hơn (được đề xuất bởi Jakub Narębski và Jefromi), vì đầu ra nhánh git không có nghĩa là được sử dụng trong kịch bản:

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

... hoặc xargs miễn phí:

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

14
Không sử dụng git branchđầu ra cho kịch bản. Sử dụng git for-each-ref.
Jakub Narębski

1
Để xóa các thẻ có ký hiệu @:git for-each-ref --format="%(refname:short)" refs/tags/\*@\* | xargs git tag -d
thaddeusmt

Có một lỗi đánh máy. Phải là "/3.2/*" chứ không phải "/3.2*". Ngoài ra, có vẻ như bạn đã sao chép các câu trả lời khác vào câu trả lời của riêng bạn.
Max MacLeod

Không có lỗi đánh máy ở đây. Từ trang người đàn ông: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
Đáng lưu ý đối với những người không biết, đó -Dlà xóa lực lượng , nên sử dụng -dtrong hầu hết các trường hợp để an toàn hơn trước.
redfox05

115

Bạn có thể sử dụng nhánh git - list để liệt kê các nhánh đủ điều kiện và sử dụng nhánh git -D / -d để xóa các nhánh đủ điều kiện.

Một ví dụ lót:

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

Khi tôi thử điều này, tôi nhận được một loạt các thông báo lỗi như thế nào error: branch 'package.json' not found.. Có vẻ như * được mở rộng quá sớm và nó cố gắng xóa một nhánh tương ứng với tên của mỗi tệp và thư mục.
Antimon

Điều này hoạt động tốt! Tôi đang gặp vấn đề khi sử dụng nó như một bí danh gitconfigmặc dù ...
whomaniac

6
Câu trả lời này cần phải cao hơn trong danh sách, siêu sạch, hoạt động, không có grep
jemiloii

1
Rất vui vì điều này dễ dàng kiểm tra đầu tiên bằng cách chỉ phát hànhgit branch --list '3.2.*'
Sẽ

3
Trên cửa sổgit branch -d (git branch --list '3.2.*').trim()
Mattias Josefsson

38

Gần đây, tôi đang tìm giải pháp cho cùng một vấn đề, cuối cùng tôi đã tìm thấy một câu trả lời và nó đang hoạt động rất tốt:

  1. Mở thiết bị đầu cuối, hoặc tương đương.
  2. Gõ vào chi nhánh git | grep "mẫu" để xem trước các nhánh sẽ bị xóa.
  3. Gõ vào chi nhánh git | grep "mẫu" | xargs git chi nhánh -D

Giải pháp này là tuyệt vời và nếu bạn muốn giải thích đầy đủ về từng lệnh và cách thức hoạt động, nó được đưa ra ở đây .


28

Sử dụng

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

7
Mẹo nhỏ là nếu bạn loại bỏ phần sau của lệnh "| xargs git Branch -D" thì nó sẽ chỉ xuất ra các nhánh phù hợp. Vì vậy, bạn có thể xem trước các nhánh sẽ bị xóa
Max MacLeod

1
Ngoài ra tôi đã thêm một bí danh để đơn giản hóa việc này: alias grefs='git for-each-ref --format="%(refname:short)"'vì vậy tôi có thể làmgrefs | grep 'regexpattern' | xargs git branch -D
angensesen

Đã yêu nó. Đẹp và đơn giản!
Bhargav Ponnapalli

15

Có thể bạn sẽ thấy điều này hữu ích:

Nếu bạn muốn xóa tất cả các nhánh không phải là 'master', 'foo' và 'bar'

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

grep -v 'cái gì đó' là một đối sánh với đảo ngược.


Cá nhân tôi thích -Dtùy chọn so với câu trả lời khác. Cảm ơn câu trả lời ở đây @Adi. Giải pháp làm việc cho tôi.
AMIC MING

9

Tôi đặt tên viết tắt của mình và dấu gạch ngang (at-) làm ba ký tự đầu tiên của tên chi nhánh vì lý do chính xác này:

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

Tất cả các câu trả lời về cơ bản nói điều này, điều này chỉ đơn giản là đơn giản nhất.
tfantina

7

Nếu bạn không bị giới hạn trong việc sử dụng dấu nhắc lệnh git, thì bạn luôn có thể chạy git guivà sử dụng mục menu Chi nhánh-> Xóa. Chọn tất cả các nhánh bạn muốn xóa và để cho nó rip.


điều này chỉ cho phép bạn xóa các chi nhánh địa phương
Stealth Rabbi

7

Giải pháp Powershell:

Nếu bạn đang chạy windows, bạn có thể sử dụng PowerShell để xóa nhiều nhánh cùng một lúc ...

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.

Bạn cũng có thể tinh chỉnh cách hoạt động của mô hình khớp bằng cách sử dụng lệnh Chọn chuỗi của Powershell. Hãy nhìn vào tài liệu powershell .


6

Giữ "phát triển" và xóa tất cả những người khác trong địa phương

    git branch | grep -v "develop" | xargs git branch -D 

5

Tôi đã thực hiện một chức năng nhỏ có thể hữu ích dựa trên câu trả lời được cung cấp bởi @gawi (ở trên).

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

Thêm vào đó .bash_profilevà khởi động lại thiết bị đầu cuối của bạn. Sau đó, bạn có thể gọi từ dòng lệnh như thế này:

removeBranchesWithPrefix somePrefix

Ghi chú

Tôi hiện đang thiết lập để xóa phần mềm, điều đó có nghĩa là nó sẽ không xóa các nhánh trừ khi chúng đã được hợp nhất. Nếu bạn thích sống ở rìa, hãy đổi -dsang -Dvà nó sẽ xóa mọi thứ với tiền tố bất kể!


5

Nếu bạn thực sự cần làm sạch tất cả các chi nhánh của bạn, hãy thử

git branch -d $(git branch)

Nó sẽ xóa tất cả các chi nhánh hợp nhất cục bộ của bạn ngoại trừ chi nhánh bạn hiện đang đăng ký.

Đó là một cách tốt để làm cho địa phương của bạn sạch sẽ


Điều này làm việc đủ tốt cho tôi. Nó để lại hai nhánh ngoại trừ nhánh tôi là một nhánh mà sau đó tôi đã loại bỏ bằng cách sử dụng cùng một lệnh nhưng sử dụng chữ hoa "-D" thay vì "-d". Tôi có một vài lỗi về git không tìm thấy tập tin nhưng các chi nhánh đã bị xóa.
Lurachusel 17/12/18

3

Bạn có thể thích mục nhỏ này ... Nó kéo danh sách và yêu cầu xác nhận từng mục trước khi cuối cùng xóa tất cả các lựa chọn ...

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`

Sử dụng -D để buộc xóa (như bình thường).

Để dễ đọc, đây là dòng chia nhỏ theo dòng ...

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`

đây là cách tiếp cận 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

cuối cùng, tôi muốn có cái này trong .bashrc của tôi

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'

Theo cách đó tôi chỉ có thể nói

gitSelect | xargs git branch -D.

3

Đối với những linh hồn thuần túy sử dụng PowerShell ở đây, tập lệnh nhỏ git branch -d $(git branch --list '3.2.*' | %{$_.Trim() })


2

nó hoạt động chính xác với tôi:

git branch | xargs git branch -d

git branch | xargs git branch -D

xóa tất cả các chi nhánh địa phương


2

Sử dụng lệnh sau để xóa tất cả các nhánh (nhánh đã kiểm tra sẽ không bị xóa).

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

Chỉnh sửa: Tôi đang sử dụng Mac Os


0

Tôi đang ở trên windows, bạn có thể sử dụng powershell để làm điều này:

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

thay thế feature/*bằng bất kỳ mẫu nào bạn thích


6
grep là một lệnh ghép ngắn không được công nhận đối với tôi ... vì vậy tôi đã thay đổi cho nhánh git này | trong đó {$ _. Trim (). StartsWith ("bug")} | % {git chi nhánh -D $ _. Trim ()} và đã hoạt động!
Alex


0

Bạn có thể sử dụng git guiđể xóa nhiều chi nhánh cùng một lúc. Từ Dấu nhắc lệnh / Bash -> git gui-> Từ xa -> Xóa nhánh ... -> chọn các nhánh từ xa bạn muốn xóa -> Xóa.


0

Tôi vừa mới dọn sạch một bộ lớn các chi nhánh địa phương / từ xa lỗi thời ngày hôm nay.

Dưới đây là cách tôi đã làm nó:

1. liệt kê tất cả các tên nhánh vào một tệp văn bản:

chi nhánh git -a >> BranchNames.txt

2. nối các nhánh tôi muốn xóa vào lệnh "git Branch -D -r":

chi nhánh git -D -r origin / dirA / Branch01 origin / dirB / Branch02 origin / dirC / Branch03 (... nối bất cứ tên chi nhánh nào)

3. thực hiện cmd

Và cái này hoạt động nhanh hơn và đáng tin cậy hơn nhiều so với " git push origin --delete ".

Đây có thể không phải là cách thông minh nhất như được liệt kê trong các câu trả lời khác, nhưng cách này khá đơn giản và dễ sử dụng.


0

Nếu bạn đã cài đặt Git GUI, đây là một tiện ích bổ sung mặc định cho Windows, thì đó là cách đơn giản nhất. Bạn có thể sử dụng ctrl để chọn nhiều nhánh và xóa chúng bằng một cú nhấp chuột.


0

Nếu bạn đang sử dụng Fish shell, bạn có thể tận dụng các stringchức năng :

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

Điều này không khác nhiều so với các tùy chọn Powershell trong một số câu trả lời khác.


0

Nếu bạn có tất cả các nhánh cần xóa trong một tệp văn bản (Branch-to-del.txt) (một nhánh trên mỗi dòng), thì bạn có thể làm điều này để xóa tất cả các nhánh đó từ xa (gốc): xargs -a branches-to-del.txt git push --delete origin


0

Để xóa nhiều nhánh dựa trên một mẫu đã chỉ định, hãy làm như sau:

Mở terminal, hoặc tương đương và gõ các lệnh sau:

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)

Xóa tất cả các nhánh 3.2.x, bạn cần gõ

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

Đó là tất cả!

Bạn tốt để đi!


-1

Vì trong Git, tất cả các nhánh đều không có gì bằng cách tham chiếu đến git repo, tại sao bạn không xóa các nhánh đi .git/refvà sau đó nếu có bất kỳ thứ gì không thú vị trong kho sẽ tự động được thu gom rác để bạn không Cần bận tâm.



-4

Bạn có thể xóa tất cả các nhánh loại bỏ tất cả các ref không cần thiết:

rm .git/refs/heads/3.2.*


2
Bị từ chối vì hai lý do: 1. nó sử dụng một chi tiết triển khai (thực tế là các phiên bản hiện tại của Git lưu trữ các nhánh dưới dạng tệp trong một thư mục nhất định). Điều này có thể thay đổi trong các phiên bản trong tương lai khiến câu trả lời không hợp lệ. 2. Nó không hoạt động nếu kho lưu trữ nằm trong một thư mục riêng .
axiac

Ngoài ra, điều này tạo ra kết quả rất bất ngờ nếu bạn chạy nó trên kho lưu trữ đóng gói ( git gc). Đừng làm vậy.
Matthieu Moy
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.