Tôi vừa mới viết blog về chủ đề này:
Làm cách nào để chúng tôi giữ cho nhánh tính năng này được cập nhật? Việc hợp nhất các cam kết ngược dòng mới nhất rất dễ dàng, nhưng bạn muốn tránh tạo một cam kết hợp nhất, vì điều đó sẽ không được đánh giá cao khi được đẩy lên ngược dòng: sau đó bạn đang thực hiện lại hiệu quả các thay đổi ngược dòng và những cam kết ngược dòng đó sẽ nhận được một hàm băm mới ( khi họ có cha mẹ mới). Điều này đặc biệt quan trọng, vì những cam kết hợp nhất đó sẽ được phản ánh trong yêu cầu kéo GitHub của bạn khi bạn đẩy những cập nhật đó lên nhánh tính năng GitHub cá nhân của mình (ngay cả khi bạn làm điều đó sau khi đưa ra yêu cầu kéo).
Đó là lý do tại sao chúng ta cần rebase thay vì hợp nhất:
git co devel #devel is ansible's HEAD aka "master" branch
git pull --rebase upstream devel
git co user-non-unique
git rebase devel
Cả tùy chọn rebase và lệnh rebase thành git sẽ giữ cho cây của bạn sạch sẽ và tránh có các cam kết hợp nhất. Nhưng hãy nhớ rằng đó là những cam kết đầu tiên của bạn (mà bạn đã đưa ra yêu cầu kéo đầu tiên của mình) đang được khôi phục và hiện có một băm cam kết mới, khác với những băm ban đầu vẫn nằm trong nhánh repo github từ xa của bạn .
Bây giờ, việc đẩy các bản cập nhật đó ra nhánh tính năng GitHub cá nhân của bạn sẽ không thành công ở đây, vì cả hai nhánh đều khác nhau: cây nhánh cục bộ và cây nhánh từ xa “không đồng bộ”, do các băm cam kết khác nhau. Git sẽ yêu cầu bạn thực hiện trước git pull --rebase
, sau đó đẩy lại, nhưng đây không phải là một động tác tua nhanh đơn giản, vì lịch sử của bạn đã được viết lại. Đừng làm vậy!
Vấn đề ở đây là bạn sẽ tìm nạp lại các cam kết đã thay đổi đầu tiên của mình như ban đầu và các cam kết đó sẽ được hợp nhất trên đầu chi nhánh địa phương của bạn. Do trạng thái không đồng bộ, kéo này không áp dụng một cách rõ ràng. Bạn sẽ nhận được một lịch sử hỏng trong đó cam kết của bạn xuất hiện hai lần. Khi bạn đẩy tất cả những thứ này sang nhánh tính năng GitHub của mình, những thay đổi đó sẽ được phản ánh trên yêu cầu kéo ban đầu, điều này sẽ trở nên rất rất xấu.
AFAIK, thực sự không có giải pháp nào hoàn toàn sạch cho việc này. Giải pháp tốt nhất mà tôi tìm thấy là buộc đẩy chi nhánh cục bộ của bạn đến chi nhánh GitHub của bạn (thực sự buộc cập nhật không tua đi nhanh):
Theo git-push (1):
Update the origin repository’s remote branch with local branch, allowing non-fast-forward updates. This can leave unreferenced commits dangling in the origin repository.
Vì vậy, không kéo, chỉ cần đẩy như thế này:
git push svg +user-non-unique
hoặc là:
git push svg user-non-unique --force
Điều này thực sự sẽ ghi đè rõ ràng chi nhánh từ xa của bạn, với mọi thứ trong chi nhánh cục bộ của bạn. Các cam kết nằm trong luồng từ xa (và đã gây ra lỗi) sẽ vẫn ở đó, nhưng sẽ là các cam kết lơ lửng, cuối cùng sẽ bị xóa bởi git-gc (1). Không phải vấn đề lớn.
Như tôi đã nói, AFAICS là giải pháp sạch nhất. Nhược điểm của điều này là PR của bạn sẽ được cập nhật với những cam kết mới nhất đó, sẽ có một ngày sau đó và có thể xuất hiện không đồng bộ trong lịch sử bình luận của PR. Không có vấn đề lớn, nhưng nó có thể gây nhầm lẫn.