2010-05-21 12 views
22

Tôi có một cây git nhưLàm thế nào để thực sự xóa một nhánh git (tức là loại bỏ tất cả các đối tượng/cam kết của nó)?

    A---B---C topic 
       /
      D---E---F---G master  <-- 

Tôi muốn loại bỏ chủ đề và tất cả các đối tượng trên nó.

Tôi lưu ý SHA ID của chủ đề, sau đó gõ:

git branch -D topic 
git gc         # <-- I also tried prune here... 
git checkout -b temp <SHA1 ID of topic> 

Sau khi lệnh cuối cùng tôi mong đợi để nhận được một lỗi (cái gì đó như "ID đối tượng không tồn tại ..." hoặc somth như thế.). Tuy nhiên không có lỗi và gitk cho thấy cấu trúc cây giống như trên?

Tôi đang thiếu gì - tôi nghĩ gc/prune có nghĩa vụ xóa tất cả các đối tượng không thể truy cập?

+2

Câu trả lời của VonC giải thích sự thật của vấn đề. Nếu bạn muốn biết lý do "triết học", nó đơn giản là git cố gắng hết sức không để cho bạn vô tình xóa bất cứ điều gì. 'git gc' của chính nó được dự định là một hoạt động dọn dẹp/đóng gói lại. Bạn phải nói điều gì đó mạnh hơn một chút để làm cho nó có khả năng xóa công việc gần đây. – Cascabel

Trả lời

4

Lưu ý tháng 5 năm 2010: Là mentioned by Jakub, nếu chi nhánh của bạn đã được hợp nhất, chủ đề vẫn có thể truy cập được.

Ở đây, giả sử không có hợp nhất.
Sau đó, khi mentioned in the ProGit book và chi tiết trong SO question này:

git gc --prune=now 

nên đủ (bạn nên gọi trực tiếp git prune). Bạn có thể kiểm soát điều đó với git count-objects -v.
Chỉnh sửa tháng 4 năm 2012: maxschlepzig trong các nhận xét xác nhận rằng các bước bổ sung có thể được yêu cầu, như được nêu chi tiết trong Duke 's answer (nhưng không có git repack).
Vì vậy, thay vì một git gc --prune now:

git reflog expire --expire=now --all 
git gc --aggressive --prune=now 
+1

"Không thể truy cập" thực sự mạnh mẽ hơn bạn ngụ ý ở đây. Theo như 'git-gc' là có liên quan, một đối tượng có thể truy cập nếu nó có thể truy cập từ một reflog - và reflog mất nhiều thời gian để hết hạn. Ví dụ, bạn có thể đã sáp nhập nhánh để làm chủ, nhận ra nó là xấu và đặt lại master về vị trí trước đó, và cam kết sẽ được coi là có thể truy cập cho đến khi mục nhập reflog hết hạn (mặc định 90 ngày). – Cascabel

+3

Ngoài ra, nó có thể đi mà không nói, nhưng phải cực kỳ cẩn thận bằng cách sử dụng '--prune = now'. Thật là khủng khiếp khi nhận ra ngay sau khi đánh vào một số cam kết quan trọng khác đã bị xóa sổ. – Cascabel

+0

cảm ơn các bạn, bạn đá! :) – Alan

24

Chỉ mận gc thường là không đủ để thoát khỏi các đối tượng phụ trong repo. Nếu các cam kết vẫn được tham chiếu trong reflog, nó sẽ không xem xét những đối tượng không thể truy cập và do đó chín muồi cho cắt tỉa.

Đây là những gì làm việc cho tôi:

git reflog expire --expire=now --all 
git gc --aggressive --prune=now 
git repack -a -d -l 

này sẽ làm cho một số thay đổi lịch sử của repo của bạn, và có thể cũng có mặt khó khăn nếu những người khác là tùy thuộc vào các ngành bạn thổi bay.

Bạn có thể phải sao chép kho lưu trữ của mình để thực sự thấy sự khác biệt về kích thước của nó.

+0

Phản hồi thú vị. +1 – VonC

+1

Tôi đã phải sử dụng 'git reflog expire --expire = now --all'. Lưu ý thêm "hết hạn". –

+0

Thử nghiệm nó - và bước repack là không cần thiết. – maxschlepzig