Khi nào cần xóa các nhánh trong Git?


284

Giả sử chúng ta có một ứng dụng ổn định.

Ngày mai, ai đó báo cáo một lỗi lớn mà chúng tôi quyết định xử lý hotfix ngay lập tức. Vì vậy, chúng tôi tạo một nhánh cho hotfix đó từ "master", chúng tôi đặt tên là "2011_Hotfix" và chúng tôi đẩy nó lên để tất cả các nhà phát triển có thể hợp tác sửa lỗi.

Chúng tôi sửa lỗi và hợp nhất "2011_Hotfix" thành "master" cũng như vào nhánh phát triển hiện tại. Và đẩy "chủ nhân".

Bây giờ chúng ta phải làm gì với "2011_Hotfix"? Nó chỉ nên ngồi ngoài đó như một nhánh mãi mãi cho đến hết thời gian hay bây giờ chúng ta nên xóa nó đi, vì nó đã phục vụ mục đích của nó? Dường như ô uế chỉ để lại các chi nhánh nằm khắp nơi, vì danh sách các chi nhánh có thể sẽ trở nên rất dài, hầu hết không còn cần thiết nữa.

Trong trường hợp cần xóa, điều gì sẽ xảy ra với lịch sử của nó? Điều đó sẽ được duy trì, mặc dù chi nhánh thực tế không còn nữa? Ngoài ra, làm thế nào tôi có thể loại bỏ một chi nhánh từ xa?


33
Nó thường giúp nghĩ về các chi nhánh như ý tưởng. Một nguyên tắc khá hay là nếu bạn hoàn thành các ý tưởng mà chi nhánh đại diện - bao gồm thử nghiệm đã thực hiện và kết hợp những thay đổi đó (hợp nhất chúng thành chủ) - bạn đã hoàn thành với chính chi nhánh.
Cascabel 17/03/2016

3
Những gì tôi muốn biết: nếu hotfix từ xa đang bị xóa, nó sẽ bị xóa cục bộ cho tất cả các nhà phát triển đã cộng tác? Nếu không; Làm thế nào để thực hiện điều này? Tôi nghĩ rằng một người sẽ chuyển hotfix thành chủ, nhưng sau đó nó cũng sẽ được xóa cho tất cả các cộng tác viên, để ngăn họ thêm các cam kết vào chi nhánh đó.
rolandow

1
Bạn không thể ảnh hưởng đến kho lưu trữ cục bộ của máy tính đồng nghiệp. Bạn phải yêu cầu anh ta xóa chi nhánh cục bộ hoặc bạn cũng có thể thực thi phía máy chủ này bằng git hook / bảo mật chi nhánh để ngăn chặn các cú đẩy từ chi nhánh của bạn mà bạn muốn tiếp tục xóa
srz2

Câu trả lời:


183

Bạn có thể loại bỏ một cách an toàn với một chi nhánh với git branch -d yourbranch. Nếu nó chứa các thay đổi không được trộn (nghĩa là bạn sẽ mất các xác nhận bằng cách xóa chi nhánh), git sẽ cho bạn biết và sẽ không xóa nó.

Vì vậy, xóa một chi nhánh hợp nhất là rẻ và sẽ không làm bạn mất lịch sử.

Để xóa một chi nhánh từ xa, hãy sử dụng git push origin :mybranch, giả sử tên từ xa của bạn là nguồn gốc và chi nhánh từ xa bạn muốn xóa được đặt tên là mybranch.


35
"xóa một chi nhánh hợp nhất là rẻ" nhưng vì vậy nó đang giữ nó xung quanh. Không có hiệu suất đáng kể về mặt thời gian hoặc không gian sử dụng git, nếu bạn giữ nó xung quanh. Điều đó nói rằng, tôi sẽ xóa chi nhánh vì tất cả các cam kết đã có trong lịch sử master, vì vậy nó làm cho mọi thứ sạch sẽ hơn nhiều.
MatrixFrog 17/03/2016

22
Một trong những lý do khiến tôi muốn xóa các nhánh là: Chúng tôi thực hiện rất nhiều thay đổi trong các nhánh (thực ra là tất cả các thay đổi) để cuối cùng bạn nhận được một danh sách dài khi sử dụng lệnh 'git nhánh'. Để biết tổng quan, tôi muốn rút ngắn danh sách đó. Vì vậy, các chi nhánh cũ sẽ bị xóa. Phát hành Reale được gắn thẻ, vì vậy không phải trong sự khó chịu này đối với tôi.
michel.iamit

7
Mặc dù tôi đồng ý với việc xóa các chi nhánh đã được hợp nhất, nhưng nếu bạn muốn xem danh sách các chi nhánh chưa được sáp nhập vào chi nhánh hiện tại của mình, bạn có thể sử dụng: chi nhánh git - không sáp nhập
lsklyut

51
@MatrixFrog Thật rẻ khi phải loay hoay về mặt git, tuy nhiên chi phí của con người có thể trở nên đắt đỏ. Tôi vừa tham gia một dự án với khoảng 40 chi nhánh, tất cả đều có tên nhánh số. Tôi không biết cái gì là cái gì, và hầu hết mọi nhánh đó đều cũ. Chi phí tìm kiếm thông qua các nhánh đó và tìm ra cái gì là mệt mỏi và mất thời gian. Vì vậy, về mặt kỹ thuật, nó rẻ, nhưng thực sự không phải vậy. Tôi thích giữ hình dạng tàu git repo của tôi. Nếu nó không hoạt động và đã được hợp nhất, hãy xóa nó. Nhưng đó chỉ là MO của tôi và tôi tôn trọng rằng những người khác có thể làm điều gì đó khác biệt.
dudewad 2/2/2015

1
Lệnh để làm --no-mergedmặc định là gì? Tôi đã thử git config --global --add branch.noMerged truevà nó đã được thêm vào nhưng nó không tạo ra sự khác biệt nào.
Craig Silver

55

Những gì bạn cần làm là gắn thẻ bất cứ thứ gì bạn phát hành. Giữ chi nhánh xung quanh khi bạn đang tích cực phát triển.

Xóa các nhánh cũ với

git branch -d branch_name

Xóa chúng khỏi máy chủ với

git push origin --delete branch_name

hoặc cú pháp cũ

git push origin :branch_name

trong đó đọc là "đẩy không có gì vào Branch_name tại nguồn gốc".

Điều đó nói rằng, miễn là DAG (đồ thị chu kỳ có hướng) có thể chỉ ra nó, các cam kết sẽ có trong lịch sử.

Google "git-Flow" và điều đó có thể cung cấp thêm thông tin chi tiết về quản lý phát hành, phân nhánh và gắn thẻ.


31

Vì câu hỏi có thẻ "github", tôi cũng thêm câu này: cụ thể là trong Github , nếu bạn kéo yêu cầu một nhánh và nó được hợp nhất (thông qua UI hoặc bằng cách hợp nhất nhánh của yêu cầu kéo), bạn sẽ không mất dữ liệu yêu cầu kéo (bao gồm cả nhận xét), ngay cả khi bạn xóa chi nhánh .

Hậu quả của việc này: Nếu bạn kết hợp các yêu cầu kéo như một phần của quy trình công việc của bạn (kết hợp ngọt ngào với đánh giá mã), bạn có thể xóa các chi nhánh một cách an toàn ngay khi chúng được hợp nhất. Điều này phổ biến đến mức gần đây Github đã thêm một tính năng (ngọt) bật lên nút "xóa chi nhánh" ngay sau khi bạn hợp nhất yêu cầu kéo.

Nhưng điều đáng chú ý là mỗi nhóm nên áp dụng quy trình làm việc phù hợp nhất với nó (và nó có thể hoặc không thể dẫn đến việc xóa các nhánh đó). Ví dụ, nhóm làm việc hiện tại của tôi cắt tỉa tất cả các chi nhánh không liên quan đến chủ hoặc liên quan đến triển khai (ví dụ: sản xuất, dàn dựng, v.v.) ngay khi các yêu cầu kéo của chúng được hợp nhất và chúng tôi vẫn theo dõi đầy đủ về cách thức các cam kết liên quan được hình thành từng cải tiến gia tăng của từng sản phẩm.

Tất nhiên, không có quản lý lịch sử (yêu cầu kéo hoặc cách khác) thay thế việc gắn thẻ phiên bản phù hợp (tốt nhất là bạn tự động hóa với cùng một công cụ / tập lệnh triển khai / gói một phiên bản), vì vậy bạn luôn có thể chuyển nhanh sang bất kỳ người dùng nào của bạn đang ở trên tại một thời điểm nhất định Gắn thẻ cũng là chìa khóa để giải quyết vấn đề ban đầu của bạn: nếu bạn thiết lập rằng bất kỳ nhánh nào được hợp nhất với các nhánh "công việc" đều có thể và nên bị xóa, và bất kỳ một nhánh nào được hợp nhất với thẻ phiên bản, "sản xuất", v.v. , bạn sẽ luôn có các hotfix tồn tại cho đến khi chúng được tích hợp trong phiên bản tương lai.


2
Cảm ơn đã giải thích lý do tại sao Github hiển thị cho tôi nút "Xóa chi nhánh".
Todd Owen

Chúng tôi đang sử dụng sourcetree và nó cung cấp tùy chọn giữ cho nhánh hotfix cục bộ và nhánh hotfix từ xa mở. Tôi nghĩ rằng việc đóng một nhánh hotfix có nghĩa là xóa nó và bạn không thể sử dụng lại nó. ví dụ: Chúng ta cần đẩy các bản sửa lỗi nóng hàng ngày trong 5 ngày tới. Sau đó, chúng tôi đóng nó. Nhưng hãy nói vào ngày thứ 6, chúng ta cần một hotfix khác. Chúng tôi có tạo một nhánh hotfix mới không?
Nguy hiểm14

Đó là những gì mọi người thường làm. Nếu việc đặt tên riêng cho họ là không khả thi, bạn có thể đặt tên cho họ dựa trên ngày hoặc trên tài liệu tham khảo cho hệ thống vé quản lý chúng (nếu có). Tất nhiên, quy trình công việc git được cho là sẽ được áp dụng trên cơ sở "bất cứ điều gì tốt nhất cho nhóm của bạn", vì vậy đừng lo lắng nếu bạn quyết định làm việc khác đi.
chesterbr 04/07/2015

7

Tôi sẽ nói thêm rằng nhược điểm của việc xóa các nhánh là bạn sẽ phá vỡ bất kỳ siêu liên kết nào đến các nhánh đó trên GitHub (câu hỏi này được gắn thẻ github). Bạn sẽ nhận được một 404 Not Foundlỗi cho các liên kết. Đây là lý do tại sao tôi thay đổi các liên kết của mình để trỏ đến một cam kết hoặc thẻ sau khi tôi xóa một nhánh trên GitHub.

Vì một số liên kết không thể thay đổi, chẳng hạn như trong email, giờ đây tôi hoàn toàn tránh liên kết đến các chi nhánh GitHub và liên kết với một cam kết hoặc thẻ từ ngày đầu tiên.

Tôi thích xóa các nhánh sau khi chúng được hợp nhất. Điều này ngăn chặn sự lộn xộn trực quan của một danh sách dài các nhánh trong kho lưu trữ của bạn. Các nhánh này cũng được truyền bá tới tất cả các nhánh của kho lưu trữ.

Đầu tiên tôi xóa chi nhánh địa phương của tôi. Điều này ngăn nó vô tình bị đẩy sau này.

git branch -d branchName

Sau đó tôi xóa chi nhánh theo dõi từ xa

git branch -dr remoteName\branchName

Sau đó tôi xóa chi nhánh trên GitHub. Tôi sử dụng giao diện web, nhưng lệnh tương đương bên dưới.

git push remoteName :branchName

Ngay cả khi chi nhánh không bao giờ được hợp nhất, thông thường tôi vẫn muốn giữ các cam kết xung quanh cho hậu thế. Tuy nhiên tôi vẫn muốn xóa chi nhánh. Để truyền bá các cam kết xung quanh và để chúng không bị ăn bởi bộ thu gom rác, tôi tạo một thẻ chú thích chỉ vào cùng một cam kết với nhánh bị xóa.

git tag -a tagName commitOrBranchName

Sau đó, tôi đẩy thẻ vào github

git push remoteName tagName

Khi nào người thu gom rác ăn cam kết của chi nhánh? Bạn có cần gắn thẻ và đẩy thẻ trước khi xóa chi nhánh không?
Jared Thirsk


4

Có vẻ như bạn muốn xóa 2011_Hotfixchi nhánh mà không mất lịch sử của nó. Tôi sẽ thảo luận về việc xóa đầu tiên và lịch sử thứ hai.

Các gitphương pháp xóa chi nhánh thông thường đã được mô tả ở trên và chúng hoạt động như mong đợi. gitkhông có lệnh một hoặc hai từ có nghĩa là "Này git, xóa cả nhánh cục bộ và nhánh từ xa." Nhưng hành vi này có thể được bắt chước thông qua shell script. Ví dụ: lấy tập lệnh shell của Zach Holman 'git-nuke' . Nó rất đơn giản:

#!/bin/sh
git branch -D $1
git push origin :$1

Đặt cái này trong một tập tin thực thi (ví dụ, git-nuke) trong một trong các $PATHthư mục của bạn . Nếu bạn không ở trong 2011_Hotfixnhánh, bạn chỉ cần chạy git-nuke 2011_Hotfixsẽ xóa cả nhánh cục bộ và nhánh từ xa. Điều này nhanh hơn & đơn giản hơn - mặc dù có lẽ nguy hiểm hơn - so với các gitlệnh tiêu chuẩn .

Mối quan tâm của bạn về bảo tồn lịch sử là một trong những tốt. Trong trường hợp này, bạn không cần phải lo lắng. Khi bạn hợp nhất 2011_Hotfixvào master, tất cả các cam kết từ 2011_Hotfixsẽ được thêm vào masterlịch sử cam kết. Nói tóm lại, bạn sẽ không mất lịch sử từ một sự hợp nhất đơn giản.

Tôi có thêm một từ để thêm có lẽ nằm ngoài phạm vi câu hỏi của bạn, nhưng dù sao cũng có liên quan. Chúng ta hãy tưởng tượng rằng có 20 cam kết nhỏ "đang thực hiện" 2011_Hotfix; tuy nhiên, bạn chỉ muốn một cam kết hoàn chỉnh 2011_Hotfixđược thêm vào masterlịch sử. Làm thế nào để bạn kết hợp tất cả 20 cam kết nhỏ thành một cam kết lớn? May mắn thay, gitcho phép bạn hợp nhất nhiều cam kết thành một cam kết bằng cách sử dụng git-rebase. Tôi sẽ không giải thích ở đây cách thức hoạt động; mặc dù, nếu bạn quan tâm, tài liệu chogit-rebase là tuyệt vời. Hãy lưu ý rằng git rebaseviết lại lịch sử, vì vậy nó nên được sử dụng một cách thận trọng, đặc biệt nếu bạn chưa quen với nó. Cuối cùng, 2011_Hotfixkịch bản của bạn là về một đội dev, không phải dev dev. Nếu thành viên nhóm dự án sử dụnggit rebase, thật khôn ngoan khi nhóm có hướng dẫn rõ ràng về việc sử dụng git rebaseđể một số nhà phát triển cao bồi trong nhóm không vô tình làm hỏng gitlịch sử của dự án .


3

Nếu nó được hợp nhất thành công trở lại và thậm chí có thể được gắn thẻ thì tôi sẽ nói nó không còn sử dụng được nữa. Vì vậy, bạn có thể làm một cách an toàn git branch -d branchname.


2

Nếu bạn muốn cắt tỉa các nhánh địa phương đã bị xóa khỏi nguồn gốc, bạn cũng có thể cắt tỉa trong khi sử dụng git fetch

git fetch --prune

0

Bạn có thể xóa các nhánh trong tất cả các giao diện người dùng web chính như github, BitBucket. Sau khi xóa chi nhánh trực tuyến, bạn có thể xóa chi nhánh địa phương bằng cách sử dụng

git remote prune origin
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.