Hãy để tôi trả lời điểm của bạn trực tiếp và rõ ràng:
Vấn đề của chúng tôi là với các nhóm bên dài hạn - loại mà bạn đã có một vài người làm việc bên lề tách ra từ chủ, chúng tôi phát triển trong một vài tháng, và khi chúng tôi đạt được một cột mốc, chúng tôi đồng bộ hóa cả hai.
Bạn thường không muốn để chi nhánh của bạn không được đồng bộ trong nhiều tháng.
Chi nhánh tính năng của bạn đã phân nhánh một cái gì đó tùy thuộc vào quy trình làm việc của bạn; Hãy gọi nó master
là vì đơn giản. Bây giờ, bất cứ khi nào bạn cam kết làm chủ, bạn có thể và nên git checkout long_running_feature ; git rebase master
. Điều này có nghĩa là các chi nhánh của bạn, theo thiết kế, luôn đồng bộ.
git rebase
cũng là điều chính xác để làm ở đây. Nó không phải là một hack hoặc một cái gì đó kỳ lạ hoặc nguy hiểm, nhưng hoàn toàn tự nhiên. Bạn mất một chút thông tin, đó là "sinh nhật" của nhánh tính năng, nhưng đó là thông tin. Nếu someobody thấy điều đó là quan trọng, nó có thể được cung cấp bằng cách lưu nó ở một nơi khác (trong hệ thống vé của bạn, hoặc, nếu nhu cầu là rất lớn, trong một git tag
...).
Bây giờ, IMHO, cách tự nhiên để xử lý việc này là, ép các mảnh vụn thành một cam kết duy nhất.
Không, bạn hoàn toàn không muốn điều đó, bạn muốn một cam kết hợp nhất. Một cam kết hợp nhất cũng là một "cam kết duy nhất". Nó không, bằng cách nào đó, chèn tất cả các nhánh riêng lẻ cam kết "vào" chủ. Đó là một cam kết duy nhất với hai cha mẹ - người master
đứng đầu và người đứng đầu chi nhánh tại thời điểm hợp nhất.
Hãy chắc chắn để xác định các --no-ff
tùy chọn, tất nhiên; sáp nhập mà không --no-ff
nên, trong kịch bản của bạn, bị nghiêm cấm. Thật không may, --no-ff
không phải là mặc định; nhưng tôi tin rằng có một tùy chọn bạn có thể thiết lập để làm cho nó như vậy. Xem git help merge
để làm gì --no-ff
(nói ngắn gọn: nó kích hoạt hành vi tôi đã mô tả trong đoạn trước), nó rất quan trọng.
chúng ta không từ bỏ các tháng phát triển song song vào lịch sử của bậc thầy.
Hoàn toàn không - bạn sẽ không bao giờ bỏ thứ gì đó "vào lịch sử" của một số chi nhánh, đặc biệt là không có cam kết hợp nhất.
Và nếu bất cứ ai cần giải quyết tốt hơn cho lịch sử của sidebranch, tất nhiên, tất cả vẫn còn đó - đó không phải là chủ, nó nằm trong sidebranch.
Với một cam kết hợp nhất, nó vẫn còn đó. Không phải trong chủ, nhưng trong sidebranch, có thể thấy rõ là một trong những cha mẹ của cam kết hợp nhất, và được giữ mãi mãi, như nó phải vậy.
Xem những gì tôi đã làm? Tất cả những điều bạn mô tả cho cam kết squash của bạn đều ở ngay đó với --no-ff
cam kết hợp nhất .
Đây là vấn đề: Tôi làm việc riêng với dòng lệnh, nhưng phần còn lại trong nhóm của tôi sử dụng GUIS.
(Nhận xét bên lề: Tôi hầu như chỉ làm việc với dòng lệnh (cũng vậy, đó là lời nói dối, tôi thường sử dụng ma thuật emacs, nhưng đó là một câu chuyện khác - nếu tôi không ở một nơi thuận tiện với thiết lập emacs cá nhân của mình, tôi thích lệnh này dòng cũng). Nhưng hãy làm cho mình một ưu và thử ít nhất git gui
một lần. Đó là vì thế hiệu quả hơn để chọn dòng, hunks vv để thêm / hoàn tác thêm.)
Và tôi đã phát hiện ra GUIS không có tùy chọn hợp lý để hiển thị lịch sử từ các chi nhánh khác.
Đó là bởi vì những gì bạn đang cố gắng làm là hoàn toàn trái với tinh thần git
. git
xây dựng từ cốt lõi trên một "biểu đồ chu kỳ có hướng", có nghĩa là, rất nhiều thông tin nằm trong mối quan hệ giữa cha mẹ và con cái. Và, đối với sáp nhập, điều đó có nghĩa là cam kết hợp nhất thực sự với hai cha mẹ và một con. GUI của các đồng nghiệp của bạn sẽ ổn ngay khi bạn sử dụng các no-ff
cam kết hợp nhất.
Vì vậy, nếu bạn đạt được một cam kết bí đao, nói rằng "sự phát triển này bị đè bẹp từ nhánh XYZ", sẽ rất đau đớn khi đi xem những gì trong XYZ.
Có, nhưng đó không phải là vấn đề của GUI, mà là của cam kết squash. Sử dụng squash có nghĩa là bạn rời khỏi đầu nhánh tính năng và tạo ra một cam kết hoàn toàn mới master
. Điều này phá vỡ cấu trúc trên hai cấp độ, tạo ra một mớ hỗn độn lớn.
Vì vậy, họ muốn các nhóm phát triển lớn, dài này được hợp nhất, luôn luôn có một cam kết hợp nhất.
Và họ hoàn toàn đúng. Nhưng họ không phải là "sáp nhập trong ", họ chỉ là sáp nhập. Hợp nhất là một thứ thực sự cân bằng, nó không có mặt ưa thích nào được hợp nhất "thành" bên kia ( git checkout A ; git merge B
hoàn toàn giống với git checkout B ; git merge A
ngoại trừ những khác biệt nhỏ về thị giác như các nhánh được hoán đổi trong git log
v.v.).
Họ không muốn bất kỳ lịch sử nào không thể truy cập ngay lập tức từ nhánh chính.
Điều này là hoàn toàn chính xác. Vào thời điểm không có các tính năng chưa được hợp nhất, bạn sẽ có một nhánh duy nhất master
với lịch sử phong phú bao trùm tất cả các dòng cam kết tính năng từng có, quay trở lại git init
cam kết từ đầu (lưu ý rằng tôi đặc biệt tránh sử dụng thuật ngữ này " các nhánh "ở phần sau của đoạn đó vì lịch sử tại thời điểm đó không còn là" các nhánh "nữa, mặc dù biểu đồ cam kết sẽ khá phân nhánh).
Tôi ghét ý tưởng đó;
Sau đó, bạn đang có một chút đau đớn, vì bạn đang làm việc chống lại công cụ bạn đang sử dụng. Cách git
tiếp cận rất thanh lịch và mạnh mẽ, đặc biệt là trong khu vực phân nhánh / sáp nhập; nếu bạn làm đúng (như đã nói ở trên, đặc biệt là với --no-ff
) thì đó là những bước nhảy vọt cho các cách tiếp cận khác (ví dụ, sự lộn xộn của việc có cấu trúc thư mục song song cho các nhánh).
nó có nghĩa là một mớ vô tận, không thể tránh khỏi của lịch sử phát triển song song.
Vô tận, song song - có.
Không thể chối cãi, rối - không.
Nhưng tôi không thấy những gì chúng ta có.
Tại sao không làm việc giống như nhà phát minh git
, đồng nghiệp của bạn và phần còn lại của thế giới làm, mỗi ngày?
Chúng ta có bất kỳ lựa chọn nào ở đây ngoài việc liên tục sáp nhập các nhóm bên thành chủ với các cam kết hợp nhất không? Hoặc, có lý do nào mà việc liên tục sử dụng các hợp nhất không tệ như tôi sợ không?
Không có lựa chọn khác; không tệ