Người ta thường nói rằng, bạn không nên rebase các cam kết mà bạn đã đẩy. Ý nghĩa của điều đó là gì?
Người ta thường nói rằng, bạn không nên rebase các cam kết mà bạn đã đẩy. Ý nghĩa của điều đó là gì?
Câu trả lời:
Các cuốn sách ProGit có một lời giải thích tốt .
Câu trả lời cụ thể cho câu hỏi của bạn có thể được tìm thấy trong phần có tiêu đề " Mối nguy hiểm của việc phục hồi ". Trích dẫn từ phần đó:
Khi bạn căn cứ lại nội dung, bạn đang bỏ qua các cam kết hiện có và tạo các cam kết mới tương tự nhưng khác biệt. Nếu bạn đẩy các cam kết ở một nơi nào đó và những người khác kéo chúng xuống và dựa trên chúng, sau đó bạn viết lại các cam kết đó bằng git rebase và đẩy chúng lên một lần nữa, cộng tác viên của bạn sẽ phải hợp nhất lại công việc của họ và mọi thứ sẽ trở nên lộn xộn khi bạn cố gắng kéo công việc của họ trở lại với bạn.
Cập nhật:
Dựa trên nhận xét của bạn bên dưới, có vẻ như bạn đang gặp khó khăn với quy trình làm việc Git của mình. Dưới đây là một số tài liệu tham khảo có thể giúp ích:
gitworkflows
trang người đàn ông: Xem "Việc sáp nhập trở lên" và "Chi nhánh Topic"Để hiểu điều này, chúng ta cần hiểu một chút về cách hoạt động của git. Kho lưu trữ git là một cấu trúc cây, nơi các nút của cây được cam kết. Đây là một ví dụ về một kho lưu trữ rất đơn giản:
nó có bốn cam kết trên nhánh chính và mỗi cam kết có một ID (trong trường hợp này là a, b, c và d). Bạn sẽ nhận thấy rằng d hiện là cam kết mới nhất (hoặc HEAD) của nhánh chính.
Ở đây, chúng ta có hai nhánh: master và my-branch. Bạn có thể thấy rằng master và my-branch đều chứa các commit a và b, nhưng sau đó chúng bắt đầu phân kỳ: master chứa c và d, trong khi my-branch chứa e và f. b được cho là "cơ sở hợp nhất" của nhánh tôi so với cơ sở chính - hoặc thông thường hơn, chỉ là "cơ sở". Nó có ý nghĩa: bạn có thể thấy rằng chi nhánh của tôi dựa trên phiên bản trước của master.
Vì vậy, giả sử rằng chi nhánh của tôi đã cũ và bạn muốn cập nhật nó với phiên bản master mới nhất. Nói một cách khác, my-branch cần chứa c và d. Bạn có thể thực hiện hợp nhất, nhưng điều đó khiến nhánh chứa các cam kết hợp nhất kỳ lạ khiến việc xem xét yêu cầu kéo khó khăn hơn nhiều. Thay vào đó, bạn có thể thực hiện rebase.
Khi bạn rebase, git tìm thấy cơ sở của chi nhánh của bạn (trong trường hợp này là b), tìm tất cả các cam kết giữa cơ sở đó và HEAD (trong trường hợp này là e và f) và phát lại các cam kết đó trên HEAD của chi nhánh bạn đang phục hồi (trong trường hợp này là thạc sĩ). Git thực sự tạo ra các cam kết mới đại diện cho các thay đổi của bạn trông như thế nào trên trang chủ: trong sơ đồ, các cam kết này được gọi là e ′ và f ′. Git không xóa các cam kết trước đây của bạn: e và f được giữ nguyên, và nếu có vấn đề gì xảy ra với rebase, bạn có thể quay lại ngay như trước đây.
Khi nhiều người khác nhau đang làm việc trên một dự án một cách mô phỏng, các yêu cầu kéo có thể bị lỗi nhanh chóng. Yêu cầu kéo "cũ" là yêu cầu không còn cập nhật với dòng phát triển chính và cần được cập nhật trước khi có thể được hợp nhất vào dự án. Lý do phổ biến nhất khiến các yêu cầu kéo bị lỗi là do xung đột: nếu hai yêu cầu kéo cùng sửa đổi các dòng tương tự trong cùng một tệp và một yêu cầu kéo được hợp nhất, thì yêu cầu kéo không hợp nhất bây giờ sẽ có xung đột. Đôi khi, một yêu cầu kéo có thể cũ mà không có xung đột: có thể những thay đổi trong một tệp khác trong cơ sở mã yêu cầu những thay đổi tương ứng trong yêu cầu kéo của bạn để phù hợp với kiến trúc mới hoặc có thể nhánh được tạo khi ai đó vô tình hợp nhất các bài kiểm tra đơn vị không thành công với chi nhánh chủ. Bất kể lý do là gì,
Rebasing viết lại lịch sử. Nếu không ai biết về lịch sử đó, thì điều đó hoàn toàn ổn. Tuy nhiên, nếu lịch sử đó được công chúng biết đến, thì việc viết lại lịch sử trong Git hoạt động giống như cách nó làm trong thế giới thực: bạn cần một âm mưu.
Các âm mưu thực sự khó giữ được với nhau, vì vậy tốt hơn hết bạn nên tránh gây trở ngại cho các chi nhánh công cộng ngay từ đầu.
Lưu ý rằng có những ví dụ về các âm mưu thành công: pu
chi nhánh của kho lưu trữ git của Junio C. Hamano (kho lưu trữ chính thức của Git SCM) thường xuyên được phục hồi. Cách hoạt động của điều này là hầu hết mọi người sử dụng pu
cũng đăng ký vào danh sách gửi thư của nhà phát triển Git, và việc pu
chi nhánh được khôi phục lại được công bố rộng rãi trên danh sách gửi thư và trang web Git.
pu
nhánh của git.git là một ví dụ cực kỳ hữu ích về cách sử dụng rebase trong quy trình làm việc (công khai). Đối với những người không quen thuộc với nó, ý tưởng chung là căn cứ lại các nhánh chủ đề không có bất kỳ cam kết nào next
(nhánh không ổn định ngay trước khi hợp nhất thành chủ), sau đó xây dựng lại pu
nhánh bằng cách đặt lại next
và hợp nhất tất cả các nhánh chủ đề. (Nguồn: Documentation / howto / duy trì-git.txt git.kernel.org/?p=git/git.git;a=blob;f=Documentation/howto/… )
Một rebase thay đổi lịch sử của kho lưu trữ của bạn. Nếu bạn đẩy các cam kết ra thế giới, tức là cung cấp chúng cho những người khác, và sau đó bạn thay đổi quan điểm của mình về lịch sử cam kết, thì sẽ khó làm việc với bất kỳ ai có lịch sử cũ của bạn.
Tôi nghĩ rằng Rebase được coi là có hại là một tổng quan tốt.
git rebase
(- tương tác?) Để viết lại lịch sử đó, đây chắc chắn là công thức thất bại. nhánh (từ nhánh X) và đẩy nó, hoàn toàn bình thường để rebase lại sau khi một nhà phát triển khác thay đổi nhánh chủ đề. Về cơ bản, tôi đã sử dụngmerge
một thời gian khá lâu, nhưng chúng tôi ở cùng thuyền với, darwinweb.net/articles/86 và lịch sử gần như không sử dụng được.