Lệnh bạn đang tìm git rebase
, cụ thể là -i/--interactive
tùy chọn.
Tôi sẽ giả sử bạn muốn để lại cam kết c trên nhánh A, và điều đó thực sự có nghĩa là bạn muốn chuyển các cam kết khác sang các nhánh khác, thay vì hợp nhất, vì việc hợp nhất rất đơn giản. Hãy bắt đầu bằng cách thao tác với nhánh A.
git rebase -i <SHA1 of commit a>^ branchA
Có ^
nghĩa là cam kết trước đó, vì vậy lệnh này nói để rebase nhánh A bằng cách sử dụng cam kết trước "a" làm cơ sở. Git sẽ cung cấp cho bạn danh sách các cam kết trong phạm vi này. Sắp xếp lại chúng và yêu cầu git chọn những cái thích hợp:
pick c ...
pick a ...
squash d ...
squash e ...
squash g ...
pick b
squash f
Bây giờ lịch sử sẽ như thế này:
c - [a+d+e+g] - [b+f] (branchA)
/
--o-x-x-x-x-x-x-x-x-x-x (master)
Bây giờ, hãy lấy cam kết b + f mới được bóp méo cho nhánhB.
git checkout branchB
git cherry-pick branchA # cherry-pick one commit, the tip of branchA
Và tương tự cho a + d + e + g cho master:
git checkout master
git cherry-pick branchA^
Cuối cùng, cập nhật branchA để nó trỏ đến c:
git branch -f branchA branchA^^
Bây giờ chúng ta nên có:
c (branch A) - [a+d+e+g] - [b+f] (dangling commits)
/
--o-x-x-x-x-x-x-x-x-x-x-[a+d+e+g] (master)
\
x-x-x-x-x-[b+f] (branchB)
Lưu ý rằng nếu bạn có nhiều commit muốn di chuyển giữa các nhánh, bạn có thể sử dụng lại rebase (không tương tác):
# create a temporary branch
git branch fromAtoB branchA
# move branchA back two commits
git branch -f branchA branchA~2
# rebase those two commits onto branchB
git rebase --onto branchB branchA fromAtoB
# merge (fast-forward) these into branchB
git checkout branchB
git merge fromAtoB
# clean up
git branch -d fromAtoB
Cuối cùng, tuyên bố từ chối trách nhiệm: Có thể sắp xếp lại thứ tự các cam kết theo cách mà một số không còn áp dụng rõ ràng nữa. Điều này có thể là do bạn đã chọn một thứ tự không tốt (đặt một bản vá trước khi cam kết giới thiệu tính năng mà nó đã vá); trong trường hợp đó, bạn sẽ muốn hủy bỏ rebase ( git rebase --abort
). Nếu không, bạn sẽ phải khắc phục xung đột một cách thông minh (giống như bạn làm với xung đột hợp nhất), thêm các bản sửa lỗi, sau đó chạy git rebase --continue
để tiếp tục. Các hướng dẫn này cũng được cung cấp bởi thông báo lỗi được in khi xung đột xảy ra.