Câu hỏi Làm cách nào để xóa tất cả các nhánh Git đã được hợp nhất?


Tôi có nhiều nhánh Git. Làm cách nào để xóa các chi nhánh đã được hợp nhất? Có cách nào dễ dàng để xóa tất cả thay vì xóa từng cái một không?


1320
2018-05-25 15:54


gốc


git branch -D xóa các nhánh có KHÔNG PHẢI đã được hợp nhất! Sử dụng cẩn thận! - Dan Solovay
Để cụ thể hơn một chút git branch -D xóa bất kỳ chi nhánh nào dù nó có được hợp nhất hay không. - PhilT
Bạn cũng có thể thực hiện việc này trực tiếp từ GitHub, nếu bạn đi đến phần 'chi nhánh' của repo của bạn (ví dụ: github.com/<username>/<repo_name>/branches). Nên có một danh sách của tất cả các chi nhánh của bạn, với một biểu tượng thùng rác màu đỏ ở phía bên mà sẽ xóa các chi nhánh được lựa chọn. Nhanh hơn nhiều so với thực hiện nó trong thiết bị đầu cuối! Cũng sẽ hiển thị như thế nào đến nay phía trước / phía sau master mỗi nhánh là. Tuy nhiên, khách hàng địa phương của bạn sẽ vẫn liệt kê các nhánh cũ nếu bạn chạy git branch -a; sử dụng git fetch --prune để loại bỏ chúng (theo câu trả lời này ). - user5359531
Script để thực hiện điều này cục bộ hoặc từ xa - với kiểm tra an toàn và "các nhánh an toàn" được định cấu hình trước: github.com/fatso83/dotfiles/tree/master/utils/…  git delete-merged --doit origin hoặc là git delete-merged --doit --local - oligofren
Bạn cũng có thể sử dụng ứng dụng này để tự động xóa các nhánh đã hợp nhất. - Sebass van Boxel


Các câu trả lời:


CẬP NHẬT:

Bạn có thể thêm các nhánh khác để loại trừ như master và dev nếu workflow của bạn có những nhánh như một tổ tiên có thể. Thông thường tôi nhánh nhánh của một "sprint-start" tag và master, dev và qa không phải là tổ tiên.

Để xóa tất cả các nhánh địa phương đã được hợp nhất vào chi nhánh hiện đã được kiểm tra:

git branch --merged | egrep -v "(^\*|master|dev)" | xargs git branch -d

Bạn có thể thấy rằng master và dev bị loại trừ trong trường hợp chúng là tổ tiên.


Bạn có thể xóa một nhánh nội bộ đã hợp nhất với:

git branch -d branchname

Nếu nó không được hợp nhất, hãy sử dụng:

git branch -D branchname

Để xóa nó từ xa trong các phiên bản cũ của Git sử dụng:

git push origin :branchname

Trong các phiên bản sử dụng Git mới hơn:

git push --delete origin branchname

Một khi bạn xóa các chi nhánh từ xa, bạn có thể cắt tỉa để thoát khỏi các ngành theo dõi từ xa với:

git remote prune origin

hoặc cắt tỉa từng nhánh theo dõi từ xa riêng lẻ, như câu trả lời khác gợi ý, với:

git branch -dr branchname

Hi vọng điêu nay co ich.


2238
2018-05-25 16:40



CẢNH BÁO: Nếu bạn vừa tạo một chi nhánh, nó cũng sẽ xóa một nhánh. Đảm bảo không có nhánh mới được tạo trong danh sách trước khi bạn chạy lệnh trên cùng. - Gary Haran
OPPOSITE CẢNH BÁO: reflog sẽ tiết kiệm thịt xông khói của bạn. Vì vậy, đừng lo lắng. - Adam Dymitruk
Hãy nhớ rằng lệnh đầu tiên chỉ xóa các nhánh cục bộ, vì vậy nó không phải là 'nguy hiểm' như một số đã chỉ ra. - ifightcrime
PowerShell biến thể, để tôi có thể tìm thấy nó ở đây thời gian tới tôi googled câu trả lời: git branch --merged | %{$_.trim()} | ?{$_ -notmatch 'develop' -and $_ -notmatch 'master'} | %{git branch -d $_} - vorou
Điều này tạo ra lỗi fatal: branch name required nếu bạn không có nhánh nào cần xóa. Để tránh điều đó bạn có thể vượt qua -r đến xargs vì vậy nó sẽ không chạy git branch -d nếu stdin trống. (Đây là một phần mở rộng GNU xargs, theo trang hướng dẫn). - Marius Gedminas


Để xóa tất cả các nhánh trên điều khiển từ xa đã được hợp nhất:

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

Trong các phiên bản Git mới hơn

git branch -r --merged | grep -v master | sed 's/origin\///' | xargs -n 1 git push --delete origin

319
2017-08-09 08:45



Câu trả lời tốt nhất cho đến nay. Chỉ cần một lưu ý, chi nhánh chính của tôi được đặt tên dev vì vậy tôi phải thay đổi điều đó - Dorian
Tôi phải thêm | grep origin sau grep -v master để ngăn chặn việc đẩy các nhánh của các điều khiển từ xa khác vào nguồn gốc. Đề xuất cao thử nghiệm đầu ra trước, sử dụng git branch -r --merged | grep -v master | grep origin | sed 's/origin\//:/' | xargs -n 1 echo - L0LN1NJ4
Tôi đã sửa đổi một chút để loại trừ develop chi nhánh là tốt. git branch -r --merged | grep -v master | grep -v develop | sed 's/origin\///' | xargs -n 1 git push --delete origin. Bây giờ điều này hóa ra là bí danh của tôi. - sarat
Điều gì làm cho câu trả lời hay nhất này tôi đã đọc, là -r đối số, mà tôi chưa từng thấy ở bất kỳ nơi nào khác. Nó được cho là chỉ có các chi nhánh địa phương có giá trị làm một số vệ sinh trên. Nhưng điều khiển từ xa cũng đầy rác. - Asbjørn Ulsberg
Thận trọng - chỉ cần nhận ra: điều này rõ ràng sẽ tìm thấy các chi nhánh sáp nhập vào chi nhánh hiện tại, không phải chủ, vì vậy nếu bạn đang ở trên myFeatureBranch nó sẽ lau origin/myFeatureBranch. Có lẽ tốt nhất là git checkout master Đầu tiên. - jakub.g


Chỉ cần mở rộng câu trả lời của Adam một chút:

Thêm điều này vào cấu hình Git của bạn bằng cách chạy git config -e --global

[alias]
    cleanup = "!git branch --merged | grep  -v '\\*\\|master\\|develop' | xargs -n 1 git branch -d"

Và sau đó bạn có thể xóa tất cả các nhánh được hợp nhất cục bộ làm một cách đơn giản git cleanup.


136
2018-02-18 15:08



không nên lệnh đầu tiên là: git branch --merged master vì bạn muốn xem những gì đã được sáp nhập vào master, hiện tại không được kiểm tra chi nhánh? - Joe Phillips
@JoePhilllips Một số người có chi nhánh chính không phải là chủ nhưng thay vào đó develop hoặc là dev và trong trường hợp đó lệnh sẽ thất bại với fatal: malformed object name tốt hơn là nên có một lệnh chung và bạn có trách nhiệm chạy nó - SKandeel
@SKandeel Có Tôi đồng ý nhưng hầu hết mọi người có thể tìm ra để thay đổi điều đó cho trường hợp cụ thể của họ. Đó là một chút kỳ quặc khi phải ngồi trên một nhánh nhất định để dọn dẹp để làm việc - Joe Phillips
@JoePhilllips điểm của câu trả lời này là để gói lên câu trả lời của Adam (câu trả lời hàng đầu cho câu hỏi này) trong bí danh git hữu ích. Câu trả lời của Adam không có những gì bạn đang gợi ý và rất nhiều người đã thấy rằng hữu ích vì vậy tôi sẽ có khuynh hướng không thay đổi của tôi. Tôi sẽ khuyên bạn nên mở cuộc thảo luận về câu trả lời của Adam nếu bạn cảm thấy mạnh mẽ về nó - real_ate
Đang thêm -r đến xargs sẽ ngăn chặn các lỗi không cần thiết (branch name required) khi chạy bí danh này nhiều lần hoặc khi không còn nhánh nào để xóa. Bí danh của tôi trông giống như sau: cleanup = "!git branch --merged | grep -v -P '^\\*|master|develop' | xargs -n1 -r git branch -d" - spezifanta


Điều này cũng hoạt động để xóa tất cả các nhánh đã hợp nhất ngoại trừ các nhánh.

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

72
2018-02-07 01:06



Bây giờ nó sẽ không xóa bất kỳ nhánh nào với mastertrong đó. Thử grep -v ^master$ ở giữa. - wchargin
Tôi cũng muốn | grep -v '^\*' để tránh xóa chi nhánh hiện tại nếu bạn không phải trên thầy - svassr
Điều này thật tuyệt vời, cảm ơn! Một báo trước cho bất kỳ ai sử dụng điều này: lưu ý rằng có hai khoảng trống trong grep -v '^ master$'. Nếu bạn gõ nó vào chính mình và bỏ lỡ một, bạn sẽ xóa master nếu bạn không ở trên đó. - styger
@ Mr.Polywhirl chỉnh sửa của bạn phá vỡ lệnh và bạn nên hoàn nguyên nó. Hai không gian là cần thiết, vì git branch sẽ liệt kê từng tên chi nhánh trên một dòng mới với hai dấu cách ở bên trái nếu nó không phải là chi nhánh hiện đã được kiểm tra. Bạn có cơ bản đảm bảo rằng bất cứ ai chạy lệnh này sẽ xóa chi nhánh chính của họ trừ khi nó là chi nhánh hiện đã được kiểm tra. - styger


Bạn sẽ muốn loại trừ master & develop các nhánh từ các lệnh đó.

Git cục bộ rõ ràng:

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

Từ xa git rõ ràng:

git branch -r --merged | grep -v '\*\|master\|develop' | sed 's/origin\///' | xargs -n 1 git push --delete origin

Đồng bộ hóa registry cục bộ của các nhánh từ xa:

git fetch -p

57
2017-07-03 16:18



1 cho phiên bản từ xa là tốt (nhưng ít cần thiết như chúng tôi có từ xa --prune). Cũng đáng chú ý rằng ngỗng sẽ không hoạt động với phiên bản git cũ hơn - malko
git config --global --add fetch.prune true để cắt tỉa tự động khi tìm nạp hoặc kéo. - T3rm1
Tâm trí bạn, prune không giống như từ xa rõ ràng. Xóa từ xa thực sự xóa các nhánh từ xa được hợp nhất hoàn toàn với nhánh hiện tại của bạn. Prune chỉ dọn dẹp registry cục bộ của các nhánh từ xa đã bị xóa. - Guido Bouman
Từ đầy đủ là một chút gây hiểu lầm, vì một chi nhánh sẽ được coi là hợp nhất, khi nó được sáp nhập trước đó, nhưng có các cam kết mới sau khi hợp nhất, mà không được sáp nhập. - scones


Đối với những người trong số các bạn đang sử dụng Windows và thích các kịch bản PowerShell hơn, đây là một trong số đó xóa các nhánh đã hợp nhất cục bộ:

function Remove-MergedBranches
{
  git branch --merged |
    ForEach-Object { $_.Trim() } |
    Where-Object {$_ -NotMatch "^\*"} |
    Where-Object {-not ( $_ -Like "*master" )} |
    ForEach-Object { git branch -d $_ }
}

32
2018-06-10 14:00



Vì lợi ích tò mò, điều này có thể được rút ngắn thành git branch --merged | ?{-not ($_ -like "*master")} | %{git branch -d $_.trim()} - Iain Ballard
@IainBallard Chắc chắn, tôi có thể đã sử dụng bí danh. Điều đó không được khuyến khích khi bạn muốn tối đa hóa khả năng đọc. github.com/darkoperator/PSStyleGuide/blob/master/English.md - Klas Mellbourn
chắc chắn rồi. Tôi tìm thấy câu trả lời của bạn rất hữu ích :-) Tuy nhiên đôi khi cú pháp powershell dạng dài được theo cách của những gì đang xảy ra trong các khối. Nhưng chủ yếu, tôi đã đưa ra một cái gì đó bạn có thể sao chép / dán hoặc gõ như một lần. Cảm ơn một lần nữa. - Iain Ballard
@IainBallard Bạn được chào đón :) - Klas Mellbourn
Đây là một lớp lót cho Windows cmd shell bảo tồn master và nhánh hiện tại của bạn: for /f "usebackq" %B in (``git branch --merged^|findstr /v /c:"* " /c:"master"``) do @git branch -d %B (Thở dài, hãy thay thế backquotes đôi bằng single, tôi không chắc chắn làm thế nào để định dạng một chữ có chứa backquotes) - yoyo


Git Sweep làm một công việc tuyệt vời này.


19
2018-02-04 13:53





Bạn có thể thêm cam kết vào tùy chọn --merged. Bằng cách này, bạn có thể đảm bảo chỉ xóa các nhánh được hợp nhất thành nguồn gốc / chủ

Lệnh sau sẽ xóa các nhánh đã hợp nhất khỏi nguồn gốc của bạn.

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 git push origin --delete 

Bạn có thể kiểm tra nhánh nào sẽ bị xóa thay thế nguồn gốc git push - hủy xóa bằng echo

git branch -r --merged origin/master | grep -v "^.*master" | sed s:origin/:: |xargs -n 1 echo

13
2017-07-08 06:28



Tôi thích tùy chọn kiểm tra - iwein


Tôi sử dụng tập lệnh Ruby sau đây để xóa các nhánh địa phương và từ xa đã được hợp nhất của tôi. Nếu tôi đang làm nó cho một kho lưu trữ với nhiều điều khiển từ xa và chỉ muốn xóa từ một, tôi chỉ cần thêm một tuyên bố chọn vào danh sách điều khiển từ xa để chỉ nhận được điều khiển từ xa mà tôi muốn.

#!/usr/bin/env ruby

current_branch = `git symbolic-ref --short HEAD`.chomp
if current_branch != "master"
  if $?.exitstatus == 0
    puts "WARNING: You are on branch #{current_branch}, NOT master."
  else
    puts "WARNING: You are not on a branch"
  end
  puts
end

puts "Fetching merged branches..."
remote_branches= `git branch -r --merged`.
  split("\n").
  map(&:strip).
  reject {|b| b =~ /\/(#{current_branch}|master)/}

local_branches= `git branch --merged`.
  gsub(/^\* /, '').
  split("\n").
  map(&:strip).
  reject {|b| b =~ /(#{current_branch}|master)/}

if remote_branches.empty? && local_branches.empty?
  puts "No existing branches have been merged into #{current_branch}."
else
  puts "This will remove the following branches:"
  puts remote_branches.join("\n")
  puts local_branches.join("\n")
  puts "Proceed?"
  if gets =~ /^y/i
    remote_branches.each do |b|
      remote, branch = b.split(/\//)
      `git push #{remote} :#{branch}`
    end

    # Remove local branches
    `git branch -d #{local_branches.join(' ')}`
  else
    puts "No branches removed."
  end
end

11
2017-09-27 23:41



Tâm trí nếu tôi ăn cắp miếng ngon này cho một thư viện trợ giúp git ít? github.com/yupiq/git-branch-util - logan
Đi cho nó, tôi sẽ không đặt nó ở đây nếu tôi quan tâm đến những người sử dụng lại mã theo một cách nào đó - mmrobins
@mmrobins Bạn có thêm \/ ở đầu tuyên bố từ chối cho remote_branches hàng. Đó có phải là một lỗi đánh máy hay nó phục vụ một mục đích? - Jawwad
@mmrobins, oh không sao, tôi thấy b.split(/\//) dòng bây giờ - Jawwad
Nếu bạn muốn làm điều này về cơ bản nhưng thông qua vanilla bash chứ không phải là ruby: stackoverflow.com/a/37999948/430128 - Raman


Sử dụng phiên bản Git 2.5.0:

git branch -d `git branch --merged`

11
2017-09-14 16:20



Điều này có thể xóa master chi nhánh btw! - Islam Wazery
Thật. Tôi chỉ sử dụng nó khi tôi chắc chắn rằng tôi đang ở master. - drautb
git branch -d $(git branch --merged | grep -v master) - alexg