Xóa nhiều nhánh từ xa trong git


128

Tôi có một thành viên trong nhóm đã vô tình đẩy hơn 150 chi nhánh địa phương của mình đến repo trung tâm của chúng tôi. Rất may, tất cả đều có cùng một tiền tố. Sử dụng tiền tố đó, có một lệnh git hoặc tập lệnh shell nhỏ thú vị mà tôi có thể sử dụng sẽ xóa tất cả những thứ đó cùng một lúc không?

Câu trả lời:


150

Sử dụng lệnh sau để xóa tất cả các nhánh có PREFIXtiền tố trên máy chủ từ xa.

git branch -r | awk -F/ '/\/PREFIX/{print $2}' | xargs -I {} git push origin :{}

Bạn có thể muốn chạy khô trước để xem đó có phải là các nhánh mà bạn muốn loại bỏ không:

git branch -r | awk -F/ '/\/PREFIX/{print $2}'

2
Tôi thích điều này bởi vì nó là một lớp lót và tôi có thể chạy khô trước. Thật không may, nó bị lỗi với thông báo này: $ git branch -r | awk -F/ '/\/APR/{print $2}' | xargs -I {} git push origin :{} error: unable to push to unqualified destination: APR-04-DPH The destination refspec neither matches an existing ref on the remote nor begins with refs/, and we are unable to guess a prefix based on the source ref. error: failed to push some refs to 'GIT_URL'
Jake A. Smith

Với git branch -r | awk -F/ '/\/APR/{print $2}', bạn có thể thấy tất cả các tên nhánh tiền tố APR được liệt kê không?
neevek

1
OK, đó là vì APR-04-DPHchi nhánh đã bị xóa. Hãy nhìn vào những câu hỏi đã trả lời: nàynày và cũng có này . Câu trả lời cho những câu hỏi giải quyết cùng một vấn đề, bạn có thể muốn tự mình kiểm tra các giải pháp.
neevek

26
nếu bạn có / trong tên chi nhánh của mình (nếu bạn đang sử dụng git-Flow hoặc thứ gì đó), thì hãy in {$ 2 "/" $ 3} thay vào đó
ajma

4
Tôi đang sử dụng msysgit trong Windows và lệnh sau đã hoạt động với tôi (kết hợp với nhận xét của @ ajma cho các tên nhánh chứa dấu gạch chéo về phía trước:git branch -r | awk -F/ '/\/PREFIX/{print $2"/"$3}' | xargs -I % git push origin --delete %
rikoe

96

Nếu bạn thích một cách tiếp cận đơn giản hơn, ví dụ xóa 3 hoặc 4 nhánh:

git push origin --delete <branch1> <branch2> <branch3>

Quan trọng: Chỉ hoạt động trên Git v1.7.0 trở lên.


6
Tôi đã kết thúc bằng cách sử dụnggit branch -r | awk -F/ '/\/PATTERN/{print $2}' | xargs git push origin --delete
Aram Kocharyan

36

Cảm ơn Neevek cho giải pháp tuyệt vời và thanh lịch!

Nhưng tôi gặp một số rắc rối với dấu gạch chéo trong tên nhánh (tôi đang sử dụng Git Flow), vì trình awkphân tách trường /( -Ftùy chọn)

Vì vậy, giải pháp của tôi dựa trên Neevek , nhưng phân tích chính xác tên nhánh với /. Trong trường hợp này tôi đoán rằng điều khiển từ xa của bạn được gọi origin. Lệnh xóa các nhánh từ xa có tên nhìn chằm chằm vào PATTERN:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}' | xargs -I {} git push origin :{}

Và đừng quên kiểm tra những gì bạn sẽ xóa:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2}'

TIP HỮU ÍCH: Nếu tên chi nhánh của bạn (không có origin/tiền tố) được lưu trữ trong tệp văn bản (một tên chi nhánh trên mỗi dòng), chỉ cần chạy:

cat your_file.txt | xargs -I {} git push origin :{}

2
Sử dụng xargs -a file -Lthay vì cat file | xargs. Thậm chí đơn giản hơn xargs -a file git push --delete origin.
musiKk

15

Đây có thể là một câu trả lời trùng lặp nhưng dưới đây đã thử nghiệm và làm việc cho tôi một cách hoàn hảo.

  1. Xóa chi nhánh mạnh

chi nhánh git -D tên chi nhánh

  1. Xóa chi nhánh từ xa

nguồn gốc git đẩy - tên chi nhánh

  1. Xóa hơn 1 chi nhánh địa phương

nhánh git -D nhánh-tên1 nhánh-tên2

  1. Xóa hơn 1 chi nhánh từ xa

nguồn gốc git đẩy --delete chi nhánh-tên1 chi nhánh-tên2

  1. Xóa chi nhánh địa phương với tiền tố. Ví dụ: tính năng / *

nhánh git -D $ (nhánh git - danh sách 'tính năng / *')

nhánh git -D backticks $ (nhánh git - list 'Feature / *' backticks )

  1. Liệt kê chi nhánh từ xa với tiền tố.

chi nhánh git -r | grep -Eo 'tính năng /.*'

  1. Xóa chi nhánh từ xa với tiền tố

chi nhánh git -r | grep -Eo 'tính năng /.*' | xargs -I {} git đẩy gốc: {}


2
Tôi nghĩ rằng bạn có nghĩa là để thoát khỏi backticks trong bước 5
GPL

Làm thế nào để thêm backticks?
Naren

1
@Naren: vấn đề là định dạng đánh dấu biến backticks của bạn thành lệnh tạo kiểu. Tôi đã thay thế chúng bằng một phương thức thay thế lệnh khác (ví dụ "$ (lệnh)" tương đương với `lệnh` nhưng không được dịch bằng cách đánh dấu thành thứ gì đó kỳ lạ.) Một điều khác bạn có thể làm là thoát khỏi backticks bằng '\'
Stablesog

13

Tương tự với grep : git branch -r | grep -Eo 'PREFIX/.*' | xargs -i git push origin :{}.

branch -rcho thấy origin/prefix/branchname. Vì vậy, nó sẽ mất prefix/branchname.


Tôi nghĩ bạn có nghĩa là xargs -I {} git push origin :{}không -i.
jojo

1
@jojo, AFAIK, vì -inó sử dụng thay thế mặc định {}nhưng với -Ibạn có thể khai báo cái của riêng bạn. ... chỉ tìm thấy trong hướng dẫn:-i ... the same as -I{}
Kirby

10

Giải pháp của Neevek rất thanh lịch, nhưng có thể tốt hơn: giải pháp như các cuộc gọi được đề xuất 'git đẩy' một lần trên mỗi chi nhánh, có nghĩa là một chuyến đi khứ hồi mạng bổ sung cho mỗi chi nhánh sẽ bị xóa. Vì dù sao bạn cũng đang sử dụng awk, tại sao không sử dụng nó để thêm tiền tố ':' và sau đó xargs có thể gọi 'git đẩy' chính xác một lần và xóa tất cả các nhánh cùng một lúc:

Chạy khô để liệt kê các nhánh sẽ bị xóa:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}'

Giải pháp cuối cùng để thực sự đẩy các xóa:

git branch -r | awk -F/ '/\/PREFIX/{print ":" $2}' | xargs git push origin

2
Nó hoạt động hoàn hảo trong trường hợp bạn không thể sử dụng tùy chọn "-I" cho xargs khi bạn có bash phiên bản thấp hơn hoặc sử dụng phiên bản windows git bash.
zchholmes

Tôi đã có một xargs: replstr may not be emptygiải pháp của Neevek, có thể là phiên bản git .. git version 1.9.5Nhưng điều này làm việc rất tốt cho tôi. Cảm ơn cả hai bạn
IamFace

8

tài nguyên https://coderwall.com/p/eis0ba

    1 - List all your remote branches:

    $ git branch -r

    2 - Filter the branches by some regular expression. In this case I'm interested in deleting any branch with the 'feature-' prefix:

    $ git branch -r | awk -F/ '/\/feature-/{print $2}'
    3 - Pipe the last command to git push to delete them:
    # **Edit** - Removed extra colon, which is not needed
    $ git branch -r | awk -F/ '/\/feature-/{print $2}' | xargs -I {} git push origin {}
    4 - Grab a beer.

    5 - Remove any local reference to those branches:

    $ git remote prune origin

Cảm ơn điều này đã làm việc cho tôi. Trong trường hợp mu tôi có thể xóa nhiều chi nhánh địa phương. Cảm ơn!
Prashant Kabade

5

Nhờ Steve và Neevek, tôi đã tìm thấy một giải pháp hoạt động khá tốt cho tôi, tôi thấy rằng đáng để chia sẻ:

Giải pháp của Steve đã làm việc cho tôi với một điều chỉnh nhỏ. Điều khiển từ xa của tôi đã được đặt tên origin/feature/some-feature-nameđể tôi cắt xén của bạn awk:

git branch -r | awk -Forigin/ '/\/feature/ {print $2 $3}' | xargs -I {} git push origin :{}

Bây giờ đang thực hiện một luồng xóa nhỏ đẹp:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
To github.com:project/project-name.git
- [deleted]         feature/search-placeholder
To github.com:project/project-name.git
- [deleted]         feature/server-error-message
To github.com:project/project-name.git
- [deleted]         feature/six-point-asterisk

Đã tự hỏi liệu có ai có ý tưởng nào cho một giải pháp thanh lịch hơn không, tuy nhiên, điều đó có thể tạo ra thứ gì đó như thế này (kịch bản CLI của tôi khá kém, vì vậy tôi sẽ mất một lúc để tìm ra điều này):

git push origin :feature/search-min-chars :feature/search-placeholder :feature/server-error-message :feature/six-point-asterisk

Điều này sẽ dẫn đến một đầu ra duy nhất đẹp với một yêu cầu mạng:

To github.com:project/project-name.git
- [deleted]         feature/search-min-chars
- [deleted]         feature/search-placeholder
- [deleted]         feature/server-error-message
- [deleted]         feature/six-point-asterisk

4

Cảm ơn Neevek. Điều này hoạt động tốt sau khi cấu hình lại nó cho mục đích của tôi:

git branch -r | awk -Forigin/ '/\/PATTERN/ {print $2 "/" $3}' | xargs -I {} git push origin :{}

Tôi cũng cần phải đưa cấu trúc thư mục vào tài khoản. Các nhánh tính năng của tôi nằm trong cấu trúc thư mục như origin / Feature / PREFIX-FEATURENUMBER. Vì vậy, tôi đã phải xây dựng mô hình của mình từ $ 2 = thư mục + $ 3 = tên nhánh.


4

Mọi người đang sử dụng awk, không biết tại sao. Tôi cảm thấy như thế phức tạp hơn. Đây là những gì tôi sử dụng để xóa tất cả các chi nhánh từ xa trên forkđiều khiển từ xa của tôi :

$ git branch -r --list 'fork/*' | sed 's/fork\///' | xargs git push --delete fork

Ném vào grepgiữa xargssednếu bạn cần lọc danh sách xuống chỉ một tập hợp con của các nhánh từ xa.


1
Cảm ơn rất nhiều. Cái này thực sự hiệu quả với tôi trong số tất cả các giải pháp .. grep đã trả lại toàn bộ chi nhánh với tên từ xa origin/blaprefix_anotherbla. Nhưng sử dụng sedxử lý nó tốt. Một ưu điểm khác của phương pháp này là tôi sử dụng bitbucket và tôi không cần nhập mật khẩu xác thực cho mỗi lần xóa chi nhánh theo cách thủ công. Điều này sẽ xóa tất cả các chi nhánh trong một lô.
Madhur Bhaiya

Để xóa tất cả các nhánh xanhgit branch -r | egrep 'origin/greenkeeper' | sed 's/origin\///' | xargs -I {} git push origin --delete {}
abhisekp

4

Tôi nhận ra đây là lệnh git, nhưng nếu bạn tìm kiếm một giải pháp thay thế để thực hiện kết quả tương tự hoặc tương tự:

Bạn có thể làm điều đó từ đây (Git Xóa Chi nhánh từ xa):

Sau đó chọn các nhánh bạn muốn:

Hãy chắc chắn rằng bạn có quyền để loại bỏ các chi nhánh từ xa.


Đây phải là một câu trả lời hàng đầu, nó là nền tảng độc lập.
karmington

Phần mềm là gì và nó có sẵn cho linux không?
abhisekp

1

Github cũng có một giao diện người dùng và cơ chế đẹp để xóa nhanh các nhánh, đó là nếu bạn muốn sử dụng UI


1
Vâng, nó được ghi lại ở đây , nhưng bạn vẫn phải nhấp một lần cho mỗi nhánh riêng lẻ. Giải pháp được bình chọn hàng đầu ở đây là cách tốt nhất để làm nhiều nhánh mà bạn có thể viết một biểu thức chính quy để khớp.
thewoolleyman

0

Tôi đã cố gắng xóa tất cả các nhánh từ xa / phát hành / r1-1 *, do đó dòng lệnh hoạt động tốt.

git branch -r | awk -Forigin/ '/\/*r1-1/ {print $2}' |  xargs -I {} git push origin :{}

0

Tôi không thể sử dụng awk vì chúng tôi đang sử dụng cấu trúc gạch chéo cho tên chi nhánh của chúng tôi.

git branch -r | grep "origin/users/YOURNAME" | sed -r 's/^.{9}//'| xargs -i  sh -c 'git push origin --delete {}'

Điều này nhận được tất cả các chi nhánh từ xa, chỉ nhận một chi nhánh cho một người dùng, từ xa chuỗi "origin /" và thực hiện xóa trên mỗi người trong số họ.


0

Chạy khô:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} echo {}

Xóa các chi nhánh từ xa:

git branch -r --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Xóa chỉ các chi nhánh từ xa được hợp nhất hoàn toàn:

git branch -r --merged --list 'origin/your-branch-name/*' | sed "s/origin\///" | xargs -I {} git push origin --delete {}

Giải trình:

sed "s/origin\///"sẽ xóa origin/khỏi tên chi nhánh. Không cần tước nó đi, tôi có:remote ref does not exist


0

Các câu trả lời trước đã giúp tôi xóa tất cả các nhánh phát hành từ năm 2018. Tôi đã chạy nó trên dấu nhắc lệnh windows 10 của mình. Tôi đã cài đặt clink , vì vậy Linux giống như các lệnh hoạt động với tôi.

Chạy khô:

git branch -a | grep -o "release-.*2018" | xargs -I {} echo {}

Nếu chạy khô cho thấy các nhánh không ở xa / nguồn gốc. Chạy bên dưới lệnh git prune để sửa và kiểm tra lại.

git remote prune origin

Xóa một khi bạn hài lòng với kết quả trên:

git branch -a | grep -o "release-.*2018" | xargs -I {} git push origin --delete {}

Nếu bạn thấy : error: unable to delete 'release-...2018': remote ref does not exist. Sau đó chạy lệnh prune trước và thử lại.


-4

Cảnh báo: Điều này sẽ xóa tất cả các chi nhánh từ xa. Sử dụng cẩn thận.

Tôi nghĩ rằng cách của tôi xóa các chi nhánh từ xa là tốt nhất.

git branch -r | grep -v master | sed 's/origin\//:/'| xargs git push

Cảnh báo: Điều này sẽ xóa tất cả các chi nhánh từ xa. Sử dụng cẩn thận.


4
Downvote như một troll rõ ràng. Sẽ xóa nếu tôi có quyền.
Jake A. Smith

bạn đã tìm thấy trolling ở đâu?
Dmytro Gorpynenko

2
Điều này không chính xác, bạn đang thiếu một số đối số quan trọng cho xargs và nó không trả lời câu hỏi.
Rob

@ JakeA.Smith Jake, tôi đoán bạn nghĩ rằng mã này sẽ loại bỏ chủ từ xa - đó không phải là trường hợp như chủ grep -v tìm thấy mọi thứ trừ chủ.
Vadim Samokhin

@Rob cái gì không đúng ở đây? Câu lệnh được thực hiện cuối cùng sẽ là smth như git push: some_branch: Another_branch, điều này hoàn toàn chính xác.
Vadim Samokhin
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.