@Mark Longair đóng đinh nó trong câu trả lời của anh ấy ở đây , nhưng tôi muốn thêm một số hiểu biết bổ sung.
Liên quan và trả lời câu hỏi về cách chia nhỏ Yêu cầu Kéo (PR) lớn, đặc biệt là khi xóa các cam kết của bạn là không thực tế do một hoặc nhiều sự hợp nhất của chủ vào tính năng_branch của bạn
Tình huống của tôi:
Tôi đã thực hiện một khoản lớn feature_branch
với 30 lần cam kết và mở Yêu cầu kéo (PR) trên GitHub để hợp nhất nó vào master
. Chi nhánh master
đã thay đổi một tấn bên dưới tôi và nhận được 200 cam kết mà tôi feature_branch
không có. Để giải quyết xung đột tôi đã làm git checkout feature_branch
và git merge master
hợp nhất master
các thay đổi của tôi vào feature_branch
. Tôi đã chọn merge
thay vì rebase
lên chủ mới nhất để tôi chỉ phải giải quyết xung đột một lần duy nhất thay vì có khả năng 30 lần (một lần cho mỗi lần cam kết của tôi). Tôi không muốn ép 30 lần cam kết của mình thành 1 lần đầu tiên và sau đó khởi động lại lần gần nhấtmaster
bởi vì điều đó có thể xóa sạch lịch sử bình luận đánh giá GitHub trong PR. Vì vậy, tôi đã hợp nhất chủ vào nhánh tính năng của mình và giải quyết xung đột 1 lần duy nhất. Tất cả đều ổn rồi. PR của tôi, tuy nhiên, quá lớn để các đồng nghiệp của tôi xem xét. Tôi cần phải chia nó ra. Tôi đã đi tiêu diệt 30 lần cam kết của mình và OH NO! HỌ Ở ĐÂU? HỌ LÀ TẤT CẢ MỌI NGƯỜI QUAN TÂM VỚI master
200 cam kết gần đây vì tôi đã hợp nhất master
với tôi feature_branch
! TÔI LÀM GÌ?
git cherry
sử dụng trong trường hợp bạn muốn thử git cherry-pick
cam kết cá nhân:
git cherry
để giải cứu (loại)!
Để xem tất cả các cam kết trong feature_branch
nhưng KHÔNG trong master
tôi có thể làm:
git checkout feature_branch
git cherry master
HOẶC, tôi có thể kiểm tra các cam kết từ bất kỳ chi nhánh nào mà không đảm bảo tôi vào feature_branch
trước bằng cách thực hiện git cherry [upstream_branch] [feature_branch]
, như thế này. Một lần nữa, kiểm tra này để xem cam kết nào trong feature_branch
nhưng KHÔNG ở upstream_branch
( master
trong trường hợp này):
git cherry master feature_branch
Thêm -v
cũng hiển thị các dòng chủ đề thông báo cam kết:
git cherry -v master
Đường ống đến "đếm từ" "-lines" ( wc -l
) đếm xem có bao nhiêu cam kết:
git cherry master | wc -l
Bạn có thể so sánh số này với số cam kết được hiển thị trong GithHub PR của bạn để cảm thấy tốt hơn về việc biết git cherry
thực sự đang hoạt động. Bạn cũng có thể so sánh các băm git từng cái một và xem chúng khớp giữa git cherry
và GitHub. Lưu ý rằng git cherry
sẽ KHÔNG tính bất kỳ cam kết hợp nhất nào mà bạn đã hợp nhất master
vào feature_branch
, nhưng GitHub SILL. Vì vậy, nếu bạn thấy sự khác biệt nhỏ trong số đếm, hãy tìm kiếm trang cam kết GitHub PR cho từ "hợp nhất" và có thể bạn sẽ thấy đó là thủ phạm không xuất hiện git cherry
. Ví dụ: một cam kết có tiêu đề "Hợp nhất nhánh 'chủ' thành Feature_branch" sẽ hiển thị trong GitHub PR nhưng không xuất hiện khi bạn chạy git cherry master feature_branch
. Điều này là tốt và mong đợi.
Vì vậy, bây giờ tôi có một phương tiện để tìm ra các khác biệt mà tôi có thể muốn chọn cherry trên một nhánh tính năng mới để phân tách khác biệt này: Tôi có thể sử dụng git cherry master feature_branch
cục bộ hoặc xem các cam kết trong GitHub PR.
Làm thế nào squash có thể giúp - nếu chỉ chúng ta có thể squash:
Tuy nhiên, một cách khác để chia nhỏ diff của tôi là nén tất cả 30 cam kết của tôi thành một, vá nó vào một nhánh tính năng mới, đặt lại mềm cam kết vá, sau đó sử dụng git gui
để thêm các tệp theo tệp, chunk theo chunk, hoặc từng dòng một. Khi tôi nhận được một tính năng phụ, tôi có thể cam kết những gì tôi đã thêm sau đó kiểm tra một chi nhánh mới, thêm một số tính năng, cam kết, kiểm tra một chi nhánh mới, v.v., cho đến khi tôi có tính năng lớn của mình được chia thành một số tính năng phụ . Vấn đề là 30 cam kết của tôi được xen kẽ với 200 cam kết khác từ những người khác do tôi git merge master
tham gia feature_branch
, do đó, việc đánh trả là không thực tế, vì tôi phải sàng lọc 230 cam kết để đặt hàng lại và xóa 30 cam kết của tôi.
Làm thế nào để sử dụng một tập tin vá như là một thay thế dễ dàng hơn cho squashing:
Cách giải quyết đơn giản là lấy một tệp vá chứa "tương đương squash" của tất cả 30 cam kết của tôi, vá nó vào một nhánh mới của master
(một nhánh tính năng mới) và làm việc từ đó, như sau:
git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch
Bây giờ tôi có bản vá 30 cam kết của mình được áp dụng tại địa phương, nhưng chưa được thực hiện và không được cam kết.
Bây giờ sử dụng git gui
để thêm tệp, khối và / hoặc dòng và chia nhỏ PR hoặc "diff" của bạn:
Lưu ý rằng nếu bạn không có git gui
, bạn có thể dễ dàng cài đặt nó trong Ubuntu sudo apt install git-gui
.
Bây giờ tôi có thể chạy git gui
và bắt đầu thêm tệp, khối và / hoặc dòng (bằng cách nhấp chuột phải vào chương trình GUI git) và chia nhánh 30 tính năng cam kết thành các nhánh phụ như được mô tả ở trên, liên tục thêm, cam kết, sau đó bỏ qua một nhánh tính năng mới và lặp lại chu trình này cho đến khi tất cả các thay đổi đã được thêm vào nhánh tính năng phụ và tính năng 30 cam kết của tôi được chia thành công thành 3 hoặc 4 tính năng phụ. Bây giờ tôi có thể mở một PR riêng cho từng tính năng phụ này và nhóm của tôi sẽ dễ dàng xem xét hơn.
Người giới thiệu:
- Tạo tập tin patch hoặc diff từ kho git và áp dụng nó vào kho git khác