2015-03-28 14 views
20

Hầu hết các luồng công việc git mà tôi đã thấy đề xuất xóa branch sau khi được hợp nhất thành chính. Ví dụ: gitflow đề xuất những điều sau:lý do tại sao tôi nên xóa các chi nhánh tính năng khi được hợp nhất thành master

# Incorporating a finished feature on develop 
$ git checkout develop 
Switched to branch 'develop' 
$ git merge --no-ff myfeature 
Updating ea1b82a..05e9557 
(Summary of changes) 
$ git branch -d myfeature 
Deleted branch myfeature (was 05e9557). 
$ git push origin develop 

Tại sao tôi nên xóa chi nhánh? Tôi cũng curios phải làm gì khi sau đó một lỗi được phát hiện đã được giới thiệu bởi các tính năng - tôi nên tạo ra các chi nhánh cùng tên một lần nữa, sửa lỗi đó, hợp nhất vào tổng thể và một lần nữa xóa các chi nhánh?

+1

Vì tính năng của bạn đã hoàn tất. Điều gì sẽ là cần thiết để giữ lại chi nhánh, do đó làm lộn xộn kết quả của git branch -a etc? –

+0

@OliverCharlesworth history –

+0

@ Z.Khullah - Các cam kết vẫn sẽ có trong lịch sử. –

Trả lời

33

Điều quan trọng cần nhận ra là các nhánh Git không gì khác ngoài nhãn trỏ đến cam kết. Phân nhánh trong Git theo nghĩa đen là phân nhánh. Đây là những gì một kho lưu trữ trông như thế nào nếu feature nhánh tắt master khi master được một cam kết B.

A - B - C - F - H [master] 
    \ 
     D - E - G - I[feature] 

Thấy không? Chi nhánh thực tế. Khi bạn git merge feature thành thạo, bạn có được điều này.

A - B - C - F - H - J [master] 
    \   /
     D - E - G - I [feature] 

Và sau khi bạn git branch -d feature lịch sử chi nhánh vẫn còn!

A - B - C - F - H - J [master] 
    \   /
     D - E - G - I 

J có cha mẹ H và I. J không thể tồn tại mà không có chúng, nó được nướng vào cách Git hoạt động. Tôi không thể tồn tại mà không có G. G không thể tồn tại mà không có E. Và cứ thế. Chi nhánh phải giữ nguyên là

J là cam kết hợp nhất thường chứa tên chi nhánh đang được hợp nhất. Giống như bất kỳ cam kết nào khác, vì vậy bạn thậm chí có thể thêm nhiều thông tin hơn vào nó, giống như một liên kết quay lại trình theo dõi vấn đề của bạn.

git merge --no-ff được sử dụng để ngăn Git không thực hiện "tua đi nhanh" và mất lịch sử chi nhánh. Điều này xảy ra nếu không có công việc nào được thực hiện trên master kể từ khi chi nhánh được tạo. Một tua về phía trước trông như thế này.

A - B[master]- D - E - G - I [feature] 

git checkout master 
git merge feature 

A - B - D - E - G - I [feature] [master] 

Kể từ master là tổ tiên trực tiếp của feature, không merge là bắt buộc. Git chỉ có thể di chuyển nhãn master. Lịch sử chi nhánh của bạn bị mất, có vẻ như D, E, G và tôi đã được thực hiện như là cam kết cá nhân trên tổng thể. git merge --no-ff yêu cầu Git không bao giờ làm điều này, để luôn thực hiện hợp nhất.

Trong tương lai, khi nhận thấy lỗi đã được giới thiệu trong G, bất kỳ ai duyệt kho đều có thể thấy nó được thực hiện như một phần của nhánh, nhìn về phía trước để tìm cam kết hợp nhất và nhận thông tin về nhánh từ đó.

Mặc dù vậy, tại sao xóa chi nhánh?Hai lý do. Đầu tiên, nó sẽ làm lộn xộn danh sách các chi nhánh của bạn với các cành chết.

Thứ hai và quan trọng hơn, nó ngăn bạn sử dụng lại nhánh. Việc phân nhánh và hợp nhất rất phức tạp. Sử dụng một lần, các nhánh tính năng ngắn ngủi đơn giản hóa quy trình bằng cách đảm bảo bạn chỉ bao giờ hợp nhất chi nhánh trở lại thành master một lần. Điều này giúp loại bỏ nhiều vấn đề kỹ thuật và quản lý. Khi bạn hợp nhất một chi nhánh, nó là được thực hiện. Nếu bạn cần sửa chữa một vấn đề được giới thiệu trong nhánh đó, chỉ cần coi nó như một lỗi trong master và tạo một nhánh mới để sửa nó.

Thật không may, git log nằm đối với người dùng và trình bày biểu diễn tuyến tính lịch sử không tuyến tính. Để khắc phục điều này, hãy sử dụng git log --graph --decorate. Điều này sẽ vẽ các dòng như trong ví dụ của tôi ở trên, và cho bạn thấy bất kỳ chi nhánh và thẻ trên mỗi cam kết. Bạn sẽ nhận được một cái nhìn sâu sắc hơn về kho lưu trữ.

Nếu bạn đang sử dụng máy Mac, GitX sẽ trực quan hóa kho lưu trữ cho bạn. gitk là phiên bản chung.

+0

cảm ơn câu trả lời của bạn! Bạn có thể vui lòng di chuyển phần bắt đầu bằng _why xóa branch_ trước khi giải thích chi nhánh git là gì để ai đó tìm kiếm cùng một câu trả lời nhận được phản hồi ngay ở trên cùng :). Câu trả lời của 'VonC' cũng rất hữu ích, có lẽ bạn có thể kết hợp một phần câu trả lời của mình vào câu trả lời của bạn để tạo ra một nguồn thông tin hoàn chỉnh. Cảm ơn! –

+0

@Maximus IMO mà không có sự hiểu biết về cách các nhánh Git hoạt động, lý do của tôi để xóa nhánh không có ý nghĩa. Đối với câu trả lời của VonC, tôi không thấy những gì trong của anh ấy mà tôi không bao gồm; bạn có thể xây dựng được không? – Schwern

+0

Có thể bạn đã đúng, có lẽ vì tôi biết tất cả những gì tôi không thấy đó là kiến ​​thức được yêu cầu trước. Tôi thấy câu trả lời này của VonC rất hữu ích: _Bởi vì lịch sử nhánh của myfeature đại diện cho tất cả các cam kết trung gian được thực hiện để thực hiện tính năng của tôi. Chiến lược này chỉ giữ một cam kết trong chủ, và quên đi các bước trung gian, có ý nghĩa đối với các ngành lâu đời, _ –

1

Vì lịch sử chi nhánh myfeature thể hiện tất cả các cam kết trung gian được thực hiện để triển khai myfeature.

Chiến lược này chỉ giữ một cam kết trong master và quên các bước trung gian, điều này có ý nghĩa đối với các nhánh sống lâu, như tôi đã giải thích trong "Why does git fast-forward merges by default?".

Thông báo cam kết của một cam kết đã thực hiện (đã hợp nhất) trong master phải làm rõ rằng nó được thực hiện để thực hiện 'myfeature'.

Nếu cần sửa, tên chi nhánh có thể được sử dụng lại (vì nó đã bị xóa trước đó).

+0

Cảm ơn. Bạn ngụ ý gì bởi các nhánh ngắn ngủi? Có sự khác biệt nào với các nhánh tính năng không? Ngoài ra, như tôi hiểu, thông tin về chi nhánh nên được lưu trữ trong cam kết hợp nhất khi chi nhánh tính năng được hợp nhất thành chính? –

+0

Bạn cũng có thể vui lòng xem nhận xét tôi để lại cho câu trả lời của bạn [tại đây] (http://stackoverflow.com/a/29296584/2545680)? –

+1

@Maximus http://stackoverflow.com/a/2850413/6309 minh họa chi nhánh phát trực tiếp (chỉ cần một vài cam kết nhanh chóng được hợp nhất trong chính), trái ngược với nhánh dài, nơi nhiều cam kết sẽ được thực hiện (với thử nghiệm và lỗi) trước khi được hợp nhất * cuối cùng * thành thạo: trong trường hợp thứ hai, nó sạch hơn để giữ chỉ một cam kết trong tổng thể. – VonC

Các vấn đề liên quan