Cách cắt tỉa các nhánh theo dõi cục bộ không còn tồn tại trên remote nữa


770

Với git remote prune origintôi có thể loại bỏ các chi nhánh địa phương không còn trên điều khiển nữa.

Nhưng tôi cũng muốn loại bỏ các nhánh cục bộ được tạo ra từ các nhánh từ xa đó (kiểm tra xem chúng có bị trộn lẫn không thì sẽ tốt).

Tôi có thể làm cái này như thế nào?



1
Một lớp lót, đa nền tảng, trông không giống như con mèo ngủ trên bàn phím của bạn: npx git-removed-branches(chạy khô) hoặc npx git-removed-branches --prune(thực tế). Bạn cần phải cài đặt node.js. Xem câu trả lời dưới đây để biết chi tiết.
Cristian Diaconescu

Câu trả lời:


892

Sau khi cắt tỉa, bạn có thể lấy danh sách các nhánh từ xa với git branch -r. Danh sách các chi nhánh với chi nhánh theo dõi từ xa của họ có thể được lấy với git branch -vv. Vì vậy, bằng cách sử dụng hai danh sách này, bạn có thể tìm thấy các nhánh theo dõi từ xa không có trong danh sách từ xa.

Dòng này nên thực hiện thủ thuật (yêu cầu bashhoặc zsh, sẽ không hoạt động với vỏ Bourne tiêu chuẩn):

git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d

Chuỗi này nhận được danh sách các nhánh từ xa và chuyển nó egrepqua đầu vào tiêu chuẩn. Và lọc các nhánh có nhánh theo dõi từ xa (sử dụng git branch -vvvà lọc cho những nhánh có origin) sau đó lấy cột đầu tiên của đầu ra đó sẽ là tên nhánh. Cuối cùng chuyển tất cả các tên nhánh vào lệnh xóa nhánh.

Vì nó đang sử dụng -dtùy chọn, nó sẽ không xóa các nhánh chưa được sáp nhập vào nhánh mà bạn đang bật khi bạn chạy lệnh này.

Cũng nên nhớ rằng bạn sẽ cần chạy git fetch --prune trước , nếu không git branch -rvẫn sẽ thấy các nhánh từ xa.


12
Điều này làm việc cho tôi hoàn hảo. Bằng cách nào đó, git fetch -pkhông phải lúc nào cũng đủ?
Stefan Hendriks

16
Thật không may, điều này không hoạt động trong Git Bash trên Windows. sh.exe": cannot make pipe for process substitution: Function not implemented sh.exe": egrep -v -f /dev/fd/0: No such file or directory fatal: branch name required Có ý kiến ​​gì không?
Ludder

37
Để thêm nó dưới dạng bí danh:alias git-remove-untracked='git fetch --prune && git branch -r | awk "{print \$1}" | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk "{print \$1}" | xargs git branch -d'
bryant1410

126
Có bất kỳ lệnh được đề xuất cho một bản phát hành git trong tương lai sẽ làm điều này? Lệnh này có vẻ như con mèo của tôi đã ở trên máy tính xách tay của tôi
Bron Davies

5
sử dụng git branch -Dở cuối lệnh làm việc tốt hơn cho chúng tôi, vì chúng tôi có xu hướng squash cam kết khi hợp nhất, điều này khiến chúng tôi gặp The branch x is not fully mergedlỗi khi chạy với -d.
Mateus Gondim

430

Nếu bạn muốn xóa tất cả các nhánh cục bộ đã được hợp nhất thành master, bạn có thể sử dụng lệnh sau:

git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

Thêm thông tin .


4
Làm việc hoàn hảo, tôi nghĩ vậy! Bất cứ ai có thể giải thích nếu câu trả lời này làm bất cứ điều gì khác với câu trả lời được chấp nhận?
Andrew

11
Cải thiện nhỏ: sử dụng xargs -r git branch -dđể không có gì được chạy nếu không có chi nhánh để xóa. Lưu ý rằng -rcờ có thể không có sẵn ở mọi nơi
Jacob Wang

8
Vì grep có thể không khớp do màu git:git branch --merged master --no-color | grep -v '^* master$' | xargs -n1 -r git branch -d
Mike D

5
@NickRes thấy như bạn đã hỏi rất hay, git branch --merged masterliệt kê các nhánh được hợp nhất thành chủ, sau đó phần grep giữa loại trừ chính chủ (chúng tôi không muốn xóa chính!) Và phần xargs cuối cùng thực thi git branch -d(xóa chi nhánh) trên mỗi kết quả. Hoặc bạn chỉ có thể đọc liên kết Thông tin thêm được cung cấp trong câu trả lời;)
jackocnr

14
Cải thiện : git branch --merged master | egrep -v '^\s*\*?\s*master$' | xargs git branch -d. Đầu ra từ git v2.10.1 sẽ hiển thị "* master" khi kiểm tra chính. Tôi thoát khỏi chủ cả có hoặc không có dấu hoa thị.
Esteban

162

Giữa các thông tin được trình bày bởi git help fetch, có một mục nhỏ này:

 -p, --prune
        After fetching, remove any remote-tracking branches which no longer exist on the remote.

Vì vậy, có lẽ, git fetch -pnhững gì bạn đang tìm kiếm?

EDIT: Ok, đối với những người vẫn còn tranh luận về câu trả lời này 3 năm sau thực tế, đây là một ít thông tin về lý do tại sao tôi trình bày câu trả lời này ...

Đầu tiên, OP nói rằng họ muốn "loại bỏ cả những nhánh cục bộ đã được tạo ra từ những nhánh từ xa đó [không còn nữa trên điều khiển từ xa]". Điều này không rõ ràng có thể trong git. Đây là một ví dụ.

Giả sử tôi có một repo trên một máy chủ trung tâm và nó có hai nhánh, được gọi AB. Nếu tôi sao chép repo đó vào hệ thống cục bộ của mình, bản sao của tôi sẽ có các ref địa phương (chưa phải chi nhánh thực tế) được gọi origin/Aorigin/B. Bây giờ hãy nói tôi làm như sau:

git checkout -b A origin/A
git checkout -b Z origin/B
git checkout -b C <some hash>

Sự thật thích hợp ở đây là vì một số lý do tôi đã chọn tạo một chi nhánh trên repo địa phương có tên khác với nguồn gốc của nó và tôi cũng có một chi nhánh địa phương chưa tồn tại trên repo gốc.

Bây giờ chúng ta hãy nói rằng tôi loại bỏ cả ABchi nhánh trên repo từ xa và cập nhật repo địa phương của tôi ( git fetchcủa một số hình thức), gây refs địa phương của tôi origin/Aorigin/Bbiến mất. Bây giờ, repo địa phương của tôi có ba chi nhánh vẫn còn, A, Z, và C. Không ai trong số này có một nhánh tương ứng trên repo từ xa. Hai trong số chúng được "tạo ra từ ... các nhánh từ xa", nhưng ngay cả khi tôi biết rằng đã từng có một nhánh được gọi là Bnguồn gốc, tôi không có cách nào để biết rằngZ được tạo ra từB, bởi vì nó đã được đổi tên trong quá trình, có lẽ vì một lý do tốt. Vì vậy, thực sự, nếu không có một số siêu dữ liệu nguồn gốc của quá trình ghi lại quá trình bên ngoài hoặc một người biết lịch sử, không thể biết được trong số ba nhánh, nếu có, OP đang nhắm mục tiêu để loại bỏ. Không có một số thông tin bên ngoài gitkhông tự động duy trì cho bạn,git fetch -p sẽ gần đến mức bạn có thể nhận được và bất kỳ phương pháp tự động nào để thử nghĩa đen những gì OP yêu cầu đều có nguy cơ xóa quá nhiều chi nhánh hoặc thiếu một số điều mà OP sẽ làm muốn xóa.

Cũng có những kịch bản khác, chẳng hạn như nếu tôi tạo ra ba nhánh riêng biệt origin/Ađể kiểm tra ba cách tiếp cận khác nhau đối với một cái gì đó, và sau đó origin/Abiến mất. Bây giờ tôi có ba nhánh, rõ ràng không thể khớp với tên khôn ngoan, nhưng chúng được tạo ra từ đó origin/A, và vì vậy một cách giải thích theo nghĩa đen của câu hỏi OP sẽ yêu cầu loại bỏ cả ba. Tuy nhiên, điều đó có thể không được mong muốn, nếu bạn thậm chí có thể tìm ra một cách đáng tin cậy để phù hợp với họ ...


108
Điều này không xóa các nhánh cục bộ, chỉ các con trỏ từ xa đến các nhánh
Jaap

4
Nó chỉ xóa các nhánh cục bộ không tồn tại ở xa VÀ bạn chưa bao giờ kiểm tra chúng.
Jarek Jakubowski

15
Bạn nên đọc câu hỏi cẩn thận hơn như ghi chú của Jaap. Mọi người bỏ phiếu cho câu trả lời này cũng nên đọc những gì câu hỏi thực sự là về.
Søren Boisen

4
Vâng, đây thực sự là chính xác những gì tôi muốn làm! @ SørenBoisen Tôi hy vọng trong hai năm qua bạn đã có thời gian để xem lại ý kiến ​​đó của bạn ... Nếu nội dung được đăng trên SO chỉ luôn liên quan đến những gì OP thực sự bối rối hỏi, chúng tôi sẽ xóa rất nhiều thông tin. Xin đừng suy đoán để hướng dẫn mọi người cách họ có thể sử dụng trang web này, ngoài các hướng dẫn chính thức và rõ ràng họ không ngăn chặn các câu trả lời trực giao nhưng hữu ích.
Félix Gagnon-Grenier

6
@ FélixGagnon-Grenier Đây là vấn đề của tôi với câu trả lời này: 1) Câu hỏi rất rõ ràng, OP rõ ràng không nhầm lẫn. 2) Câu trả lời này không đề cập đến việc nó không trả lời câu hỏi! 3) Câu hỏi đã nêu ra một cách để cắt tỉa các nhánh theo dõi từ xa không còn tồn tại, vì vậy nó thêm giá trị bằng không.
Søren Boisen

117

Điều này sẽ xóa các nhánh cục bộ mà các nhánh theo dõi từ xa đã được cắt tỉa. (Hãy chắc chắn rằng bạn đang ở masterchi nhánh!)

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

Chi tiết:

  • git branch -vv hiển thị "biến mất" cho các chi nhánh địa phương mà điều khiển từ xa đã được cắt tỉa.

    mybranch abc1234 [origin/mybranch: gone] commit comments
    
  • -dsẽ kiểm tra xem nó đã được hợp nhất chưa ( -Dsẽ xóa nó bất kể)

    error: The branch 'mybranch' is not fully merged.
    

16
Bạn thậm chí có thể thực hiện lệnh ngắn hơn vớigit branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
chiborg

4
Chỉ cần chỉ ra rằng bạn nên làm chủ trước khi làm điều này, bởi vì git branch -dso sánh các nhánh với HEAD.
Steve Bennett

Thông minh! Tôi đã nhìn và tìm kiếm điều này. Tôi ước tôi đã nhìn thấy câu trả lời của bạn trước khi tôi tự mình tìm ra câu trả lời. Nó sẽ giúp tôi tiết kiệm được vài phút. Đây là câu trả lời khác của tôi: stackoverflow.com/questions/15661853/ Kẻ
Karl Wilbur

1
Tôi đã kết thúc với một bí danh git tương tự, được sử dụng cắt vì awk không hoạt động vì một số lý do:prunelocal = !sh -c \"git checkout -q master && git fetch -q --prune && git branch -vv | git grep ': gone]' | cut -d' ' -f3 | xargs git branch -d\"
Zitrax

3
Ôi trời ơi ... bạn không cần phải cập nhật câu trả lời của mình để nói với mọi người rằng họ nên làm chủ. Chỉ cần làm điều này từ một chi nhánh khác. @ stevebennet2 cảm ơn vì bình luận đầy thông tin
GrayedFox

53

Người ta có thể định cấu hình Git để tự động xóa tham chiếu đến các nhánh từ xa bị xóa khi tìm nạp:

git config --global fetch.prune true

Khi gọi git fetchhoặc git pullsau đó, các tham chiếu đến các nhánh từ xa bị xóa sẽ tự động bị xóa.


5
Điều này không loại bỏ các chi nhánh địa phương, chỉ tham chiếu đến chúng, phải không?
Clint Eastwood

@ClintEastwood Nó chỉ xóa các tham chiếu đến các nhánh từ xa . Bạn có thể liệt kê các tài liệu tham khảo đến các chi nhánh từ xa bằng cách sử dụng git branch -r.
wedesoft

52

Có một gói NPM gọn gàng phù hợp với bạn (và nó sẽ hoạt động đa nền tảng).

Cài đặt nó với: npm install -g git-removed-branches

Và sau đó git removed-branchessẽ cho bạn thấy tất cả các chi nhánh địa phương cũ và git removed-branches --prunethực sự xóa chúng.

Thêm thông tin ở đây.


1
Điều này thực sự nên có nhiều upvote. Cảm ơn đã làm cho cuộc sống dễ dàng, bất kể nền tảng.
Mã hóa

Tiện ích mở rộng nhỏ. Được cài đặt và hoạt động tốt trên Windows 10. Lưu ý nhỏ: nó coi các nhánh không hợp nhất là có khả năng prune (lỗi khi chạy --prune, mặc dù nhánh -d đã được gọi) .. tuy nhiên, chúng không được ký hiệu như vậy trong ban đầu danh sách hiển thị.
dùng2864740

1
Đây là câu trả lời yêu thích của tôi. npx git-removed-brancheshoạt động như một giấc mơ.
Drazisil

Đúng! Điều này nên có nhiều upvote! giải pháp đơn giản và trực quan cho người mới chơi cli
geoseong

Sẽ rất hữu ích khi đưa ra một cái nhìn tổng quan về những gì công cụ đang làm từ quan điểm của git.
ryanwebjackson

41

Giải pháp Windows

Đối với Microsoft Windows Powershell:

git checkout master; git remote update origin --prune; git branch -vv | Select-String -Pattern ": gone]" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}

Giải thích

git checkout master chuyển sang nhánh chính

git remote update origin --prune cắt tỉa cành từ xa

git branch -vvnhận được một đầu ra dài dòng của tất cả các chi nhánh ( tham chiếu git )

Select-String -Pattern ": gone]" chỉ nhận được các bản ghi nơi chúng đã bị xóa từ xa.

% { $_.toString().Split(" ")[0]} lấy tên chi nhánh

% {git branch -d $_} xóa chi nhánh


Ví dụ tốt đẹp. Ngoài ra git remote prune origin, sử dụng chuỗi chọn dường như không khớp với phiên bản mới nhất của git. Cân nhắc sử dụngConvertFrom-String -TemplateContent
Bernie White

3
Có vẻ như phiên bản mới nhất của git thêm một số khoảng trắng ở cuối, do đó, Split không hoạt động để lấy tên chi nhánh. Làm .toString (). Trim (). Split ("") và nó sẽ
Chris Hynes

Đây là của tôi:git checkout master; git pull; git remote prune origin; git branch --merged | select-string -notmatch "master" | % { $_.toString().Trim().Split(" ")[0]} | % {git branch -d $_}
Omzig

@Omzig Điều đó làm gì khác nhau? Bạn có thể đưa ra lời giải thích>
chris31389

@ chris31389, tôi có một cái kéo ở đó để lấy mọi thứ mà tôi đang thiếu từ chủ, và tôi đã thay đổi nhánh thành - hòa trộn và không làm chủ, tôi muốn chắc chắn rằng tôi chỉ xóa các nhánh - đã trộn. Nó chỉ làm cho tôi cảm thấy tốt hơn;)
Omzig

27

Nó sẽ liệt kê các nhánh cục bộ có nhánh theo dõi từ xa bị xóa khỏi remote

$ git remote prune origin --dry-run

Nếu bạn muốn hủy tham chiếu các chi nhánh địa phương này khỏi địa phương không được theo dõi

$ git remote prune origin

19
Điều này không trả lời câu hỏi, đây là những gì OP đã biết.
Ken Williams

2
Tôi cũng đồng ý, nhưng khi bạn tìm kiếm "Cách cắt tỉa các nhánh theo dõi cục bộ không còn tồn tại trên remote nữa", đây là liên kết hàng đầu và câu trả lời này khớp với tiêu đề (không phải nếu người ta đã đọc mô tả đầy đủ trong câu hỏi), đó là là lý do để tăng phiếu bầu :)
027

Điều này không loại bỏ các chi nhánh địa phương. Vẫn còn đó sau khi chạy này
Xin

@Xin thử chạy lệnh mà không có đối số --dry-run vì nó sẽ không thực sự thực thi lệnh, nhưng cho bạn thấy những gì nó sẽ thay đổi.
Torsten Ojaperv

19

Như @tzacks lưu ý ... có một gói npm tiện dụng cho việc này. Cứ làm đi:

npx git-removed-branches --prune

(Tôi đã có ý kiến ​​nhưng không đủ danh tiếng)


1
Rực rỡ. Không có rắc rối gì. Vui mừng đây là một câu trả lời đầy đủ!
Dan Rayson

1
Điều này nên ở trên cùng. Hoạt động trong Windows cũng vậy.
tomtastico

14

Nếu sử dụng Windows và Powershell, bạn có thể sử dụng cách sau để xóa tất cả các nhánh cục bộ đã được sáp nhập vào nhánh hiện đang được kiểm tra:

git branch --merged | ? {$_[0] -ne '*'} | % {$_.trim()} | % {git branch -d $_}

Giải trình

  • Liệt kê các nhánh hiện tại và các nhánh đã được sáp nhập vào nó
  • Lọc ra chi nhánh hiện tại
  • Dọn sạch mọi khoảng trắng ở đầu hoặc cuối từ gitđầu ra cho mỗi tên nhánh còn lại
  • Xóa các chi nhánh địa phương được sáp nhập

Nó đáng để tự chạy git branch --mergedtrước tiên chỉ để đảm bảo rằng nó sẽ chỉ loại bỏ những gì bạn mong đợi.

(Được chuyển / tự động từ http://railsware.com/blog/2014/08/11/git-housekeep-tutorial-clean-up-outdated-branches-in-local-and-remote-reposeocate/ .)


10

Thậm chí ngắn hơn và an toàn hơn một lớp lót:

git branch -d $(git branch --merged | cut -c 3- | grep -v master)

Hãy chắc chắn kiểm tra chi nhánh chưa được hợp nhất, trước khi chạy nó. Bởi vì bạn không thể xóa chi nhánh mà bạn hiện đang đăng ký.


3
điều này cũng sẽ loại bỏ 'chủ nhân' của bạn?
dcsan

2
Nếu bạn hiện đang đăng ký thành chủ thì không, nếu không thì
FelikZ

1
Để bỏ qua chủ, bạn có thể chỉ cần chuyển sang grep và chọn nghịch đảo, như vậy - git branch -d $(git branch --merged | cut -c 3- | grep -v master)
mozillalives

Điều này không an toàn và ai đó trong tương lai sẽ vô tình xóa chi nhánh chính của họ
jasonseminara

1
@jasonseminara #dcsan Tôi đã cập nhật đoạn trích, vì vậy nó bỏ qua nhánh chính. #mozillalives cảm ơn
FelikZ

9

Tôi muốn một cái gì đó sẽ thanh lọc 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 nhánh cục bộ không bao giờ được thiết lập để theo dõi một nhánh từ xa (ví dụ: các nhánh dev cục bộ 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 githoặ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 đã kết thúc bằng cách sử dụng một chút grepawkđể thực hiện lệnh đơn giản này, sau đó thêm nó dưới dạng bí danh trong tôi ~/.gitconfig.

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

Đây là một git config --global ...lệnh để dễ dàng thêm điều 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 Ý: Sử dụng -Dcờ git branchcó thể rất nguy hiểm. Vì vậy, trong lệnh config ở trên, tôi sử dụng -dtùy chọn git branchthay vì -D; Tôi sử dụng -Dtrong cấu hình thực tế của tôi. Tôi sử dụng -Dbởi vì tôi không muốn nghe Git phàn nàn về các chi nhánh không được hợp nhất, tôi chỉ muốn chúng biến mất. Bạn có thể muốn chức năng này là tốt. Nếu vậy, chỉ cần sử dụng -Dthay vì -dở cuối lệnh config.


8

Để loại bỏ các chi nhánh từ xa:

$git remote prune origin

Để xóa các chi nhánh địa phương đã được hợp nhất:

$git branch -D $(git branch --merged)

Làm việc cho tôi. Cảm ơn.
AndroidR.78Exception

2
(chi nhánh git - đã kết hợp) cũng trả lại 'chủ nhân' cho tôi. Và các nhánh khác chưa bị xóa trên remote.
Tom G

8
Điều này đã xóa chi nhánh chủ của tôi.
Greg

5

Dường như không có một lớp lót an toàn, quá nhiều trường hợp cạnh (như một nhánh có "chủ" như một phần của tên của nó, v.v.). An toàn nhất là các bước sau:

  1. git branch -vv | grep 'gone]' > stale_branches.txt
  2. xem tệp và xóa các dòng cho các nhánh bạn muốn giữ (chẳng hạn như nhánh chính!); bạn không cần phải chỉnh sửa nội dung của bất kỳ dòng nào
  3. awk '{print $1}' stale_branches.txt | xargs git branch -d

5

Dựa trên các câu trả lời ở trên, tôi đang sử dụng lớp lót ngắn hơn này:

git remote prune origin | awk 'BEGIN{FS="origin/"};/pruned/{print $2}' | xargs -r git branch -d

Ngoài ra, nếu bạn đã cắt tỉa và có các nhánh treo lủng lẳng ở địa phương, thì điều này sẽ làm sạch chúng:

git branch -vv | awk '/^ .*gone/{print $1}' | xargs -r git branch -d

1
Không hoạt động nếu tên chi nhánh của bạn có /trong đó
theicfire

4

không chắc chắn làm thế nào để làm tất cả cùng một lúc, nhưng git git branch -d <branchname>sẽ xóa một nhánh cục bộ CHỈ nếu nó được hợp nhất hoàn toàn. Lưu ý chữ thường d.

git branch -D <branchname> (lưu ý vốn D) sẽ xóa một chi nhánh địa phương bất kể trạng thái hợp nhất của nó.


Trên Windows, các câu trả lời khác không phù hợp với tôi. Sử dụng câu trả lời này với công tắc -D đơn giản đã làm (mặc dù nhánh đã bị "xóa").

Chúng ta có thể làm điều đó cho tất cả các chi nhánh cùng một lúc?
Teoman shipahi

3

Bạn có thể sử dụng lệnh này:

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

Git Clean: Xóa các nhánh đã hợp nhất bao gồm cả sự cố lệnh


Bạn không thực sự cần phải lọc ra bất kỳ chi nhánh nào (ex master). Nếu nó được "hợp nhất" thì điều đó chỉ có nghĩa là nó sẽ xóa bản sao cục bộ của bạn, nhưng "git checkout dev" sẽ tạo một nhánh cục bộ từ xa nếu chưa có
csga5000

Nhưng danh sách chi nhánh địa phương vẫn còn đó ngay cả khi chúng được hợp nhất. Lệnh này là để loại bỏ các nhánh đã bị xóa từ xa.
sendon1982

dấu hoa thị ở đầu có nghĩa là nhánh hiện tại, khi bạn chạy lệnh đó trên nhánh khác sẽ không hoạt động tốt
OzzyC817

2

Dựa trên các câu trả lời ở trên, tôi đã đưa ra giải pháp một dòng này:

git remote prune origin; git branch -r | awk '{print $1}' | egrep -v -f /dev/fd/0 <(git branch -vv | grep origin) | awk '{print $1}' | xargs git branch -d

2

Sử dụng một biến thể trong câu trả lời của @ wvducky, tôi đã thêm vào đây dưới dạng bí danh vào ~/.gitconfigtệp của mình :

pruneitgood = "!f() { \
    git remote prune origin; \
    git branch -vv | perl -nae 'system(qw(git branch -d), $F[0]) if $F[3] eq q{gone]}'; \
}; f"

Với điều này, một đơn giản git pruneitgoodsẽ dọn sạch cả các nhánh cục bộ và từ xa không còn cần thiết sau khi hợp nhất.


2

Phiên bản Powershell của git branch --merged master | grep -v '^[ *]*master$' | xargs git branch -d

git branch --merged master | %{ if($_ -notmatch '\*.*master'){ git branch -d "$($_.Trim())" }}

Điều này sẽ loại bỏ bất kỳ chi nhánh địa phương nào đã được hợp nhất thành chủ, trong khi bạn đang ở trên chi nhánh chính .

git checkout master để chuyển đổi.


1

Biến thể của Schleis không hoạt động với tôi (Ubuntu 12.04), vì vậy hãy để tôi đề xuất các biến thể (rõ ràng và sáng bóng :) của tôi:

Biến thể 1 (Tôi thích tùy chọn này):

git for-each-ref --format='%(refname:short) %(upstream)' refs/heads/ | awk '$2 !~/^refs\/remotes/' | xargs git branch -D 

Biến thể 2:

a. Chạy khô:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | awk '{print "git branch -D " $1}'

b. Xóa chi nhánh:

comm -23 <( git branch | grep -v "/" | grep -v "*" | sort ) <( git br -r | awk -F '/' '{print $2}' | sort ) | xargs git branch -D

1

Sau đây là bản phóng tác của câu trả lời @ wvducky dành cho người dùng Windows:

for /f "tokens=1" %i in ('git branch -vv ^| findstr ": gone]"') DO git branch %i -d

Tôi sử dụng posh-git và thật không may, PS không thích khỏa thân for, vì vậy tôi đã tạo một tập lệnh lệnh 'ol đơn giản có tên PruneOrphanBranches.cmd:

@ECHO OFF
for /f "tokens=1" %%i in ('git branch -vv ^| findstr ": gone]"') DO CALL :ProcessBranch %%i %1

GOTO :EOF

:ProcessBranch
IF /I "%2%"=="-d" (
    git branch %1 %2
) ELSE (
    CALL :OutputMessage %1
)
GOTO :EOF

:OutputMessage
ECHO Will delete branch [%1] 
GOTO :EOF

:EOF

Gọi nó không có tham số để xem danh sách, sau đó gọi nó bằng "-d" để thực hiện xóa thực tế hoặc "-D" cho bất kỳ nhánh nào không được hợp nhất hoàn toàn nhưng dù sao bạn cũng muốn xóa.


Điều này không hiệu quả với tôi, bằng cách nào đó :hoặc : (với một khoảng trắng) findstrkhiến nó khớp với mọi thứ mọi lúc - tôi gần như đã xóa chủ. Tuy nhiên, sử dụng regex hoạt động tốt:git branch -vv ^| findstr /R " \[origin/[0-9]+: gone\] "
Josh

1

Hãy thử điều này trong git bash, để tìm nạp và cắt xén các tham chiếu đến các nhánh bị xóa và sau đó cắt tỉa các nhánh cục bộ đang theo dõi các nhánh bị xóa:

git fetch -p && git branch -d `git branch -vv | grep ': gone]' | awk '{print $1}' | xargs`

Hãy nhớ kiểm tra trước một chi nhánh sẽ không bị xóa, do đó không chặn việc xóa chi nhánh.


0

Tôi đã biến câu trả lời được chấp nhận thành một kịch bản mạnh mẽ. Bạn sẽ tìm thấy nó trong kho git-extend của tôi .

$ git-prune --help
Remove old local branches that do not exist in <remote> any more.
With --test, only print which local branches would be deleted.
Usage: git-prune [-t|--test|-f|--force] <remote>

0

Tôi đến trang này để tìm câu trả lời cho "làm cách nào để xóa các nhánh được kiểm tra cục bộ không còn có nhánh ngược dòng"

Tôi cũng không quan tâm liệu chi nhánh địa phương đã được sáp nhập hay chưa, vì đường ống vào git branch -dsẽ chỉ đơn giản là cảnh báo thay vì xóa các chi nhánh địa phương không được hợp nhất.

git branch -a | grep origin | tr -s ' ' | cut -d '/' -f3 | egrep -v -f /dev/fd/0 <(git branch -a | grep -v origin) | grep branch_prefix_that_I_care_about | xargs git branch -d

# translation
# git branch -a | grep origin | tr -s ' ' | cut -d '/' -f3
## this finds all remote branch names minus the "remote/origin/" part
#
# <(git branch -a | grep -v origin)
## this finds all local branch names and redirects it into the previous command
#
# egrep -v -f /dev/fd/0 STUFF
## this is doing some weird magic that I'm grokking as "take the set difference from whatever was piped in"
#
#
# overall translation: (STUFF TO CONSIDER) | egrep magic <(STUFF TO REMOVE FROM CONSIDERATION) | do cool things with resulting stuff


0

Đây là giải pháp của tôi:

git fetch -p
git branch -vv | grep ": gone" | awk '{print $1}' | xargs git branch -d
  • -p là để xóa mọi tham chiếu theo dõi từ xa không còn tồn tại trên điều khiển từ xa. Vì vậy, bước đầu tiên sẽ loại bỏ các tham chiếu đến các chi nhánh từ xa.

  • -vv là để hiển thị sha1 và cam kết dòng chủ đề cho mỗi đầu, cùng với mối quan hệ với nhánh ngược dòng (nếu có). Bước 2 sẽ nhận được tất cả các nhánh cục bộ và lệnh grep sẽ lọc ra các nhánh đã bị xóa.


Thậm chí nhỏ hơn (như được mô tả trong một nhận xét khác)git branch -vv | awk '/: gone]/{print $1}' | xargs git branch -d
mrroboaat

-2

Xóa bất kỳ chi nhánh nào không cập nhật với chủ

git co master && git branch | sed s/\*/\ / | xargs git branch -d 2> /dev/null

-3

Tôi khá chắc chắn rằng đó git remote prune originlà những gì bạn muốn.

Bạn có thể chạy nó git remote prune origin --dry-runđể xem những gì nó sẽ làm mà không thực hiện bất kỳ thay đổi.


12
Điều này không thực sự loại bỏ các chi nhánh địa phương.
Taytay

-16

Sử dụng GUI? Thủ tục thủ công, nhưng nhanh chóng và dễ dàng.

$ git gui

Chọn "Chi nhánh -> Xóa". Bạn có thể chọn nhiều nhánh với ctrl-click (windows) và xóa tất cả chúng.


Thật buồn cười khi câu trả lời này bị phủ nhận. Cách tiếp cận hoàn toàn hợp lệ IMO nếu bạn thích GUI.
huyết thanh
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.