Câu trả lời:
Cả hai git merge --squash
và git rebase --interactive
có thể tạo ra một cam kết "đè bẹp".
Nhưng họ phục vụ các mục đích khác nhau.
sẽ tạo ra một cam kết bị đè bẹp trên nhánh đích, mà không đánh dấu bất kỳ mối quan hệ hợp nhất nào.
(Lưu ý: nó không tạo ra một cam kết ngay lập tức: bạn cần một bổ sung git commit -m "squash branch"
)
Điều này rất hữu ích nếu bạn muốn loại bỏ hoàn toàn nhánh nguồn, đi từ (lược đồ lấy từ câu hỏi SO ):
git checkout stable
X stable
/
a---b---c---d---e---f---g tmp
đến:
git merge --squash tmp
git commit -m "squash tmp"
X-------------------G stable
/
a---b---c---d---e---f---g tmp
và sau đó xóa tmp
chi nhánh.
Lưu ý: git merge
có một --commit
tùy chọn , nhưng nó không thể được sử dụng với --squash
. Nó không bao giờ có thể sử dụng --commit
và --squash
cùng nhau.
Kể từ Git 2.22.1 (quý 3 năm 2019), tính không tương thích này được thể hiện rõ ràng:
Xem cam kết 1d14d0c (24 tháng 5 năm 2019) của Vishal Verma ( reloadbrain
) .
(Được hợp nhất bởi Junio C Hamano - gitster
- trong cam kết 33f2790 , ngày 25 tháng 7 năm 2019)
merge
: từ chối--commit
với--squash
Trước đây, khi
--squash
được cung cấp, 'option_commit
' đã âm thầm giảm xuống. Điều này có thể gây ngạc nhiên cho người dùng đã cố gắng ghi đè hành vi không cam kết của squash bằng cách sử dụng--commit
rõ ràng.
git/git
builtin/merge.c#cmd_merge()
bây giờ bao gồm:
if (option_commit > 0)
die(_("You cannot combine --squash with --commit."));
phát lại một số hoặc tất cả các cam kết của bạn trên một cơ sở mới, cho phép bạn xóa sổ (hoặc gần đây là "sửa lỗi", xem câu hỏi SO này ), trực tiếp đến:
git checkout tmp
git rebase -i stable
stable
X-------------------G tmp
/
a---b
Nếu bạn chọn đè bẹp tất cả các cam kết của tmp
(nhưng ngược lại merge --squash
, bạn có thể chọn phát lại một số và xóa các số khác).
Vì vậy, sự khác biệt là:
squash
không chạm vào nhánh nguồn của bạn ( tmp
ở đây) và tạo một cam kết duy nhất ở nơi bạn muốn.rebase
cho phép bạn tiếp tục trên cùng một nhánh nguồn (tĩnh tmp
) với:
tmp
cam kết bị đè bẹp với nhau.
G
sẽ không đại diện cho cùng một nội dung hơn g
, vì những thay đổi được giới thiệu bởi X
.
git merge --no-ff temp
thay thế git merge --squash temp
, sau đó bạn có được một lịch sử lộn xộn, nhưng bạn cũng có thể làm những việc như thế git revert e
, dễ dàng hơn nhiều. Đó là một lịch sử lộn xộn, nhưng trung thực và thực dụng, và chi nhánh chính vẫn còn khá sạch sẽ.
git bisect
hoặc git blame
khi được sử dụng quá thường xuyên (như tronggit pull --no-ff
: stackoverflow.com/questions/12798767/ .) Dù sao cũng không có một cách tiếp cận nào, đó là lý do tại sao bài viết này mô tả ba ( stackoverflow.com/questions/9107861/iêu )
Hợp nhất cam kết: giữ lại tất cả các cam kết trong chi nhánh của bạn và xen kẽ chúng với các cam kết trên nhánh cơ sở
Hợp nhất Squash: giữ lại các thay đổi nhưng bỏ qua các xác nhận riêng lẻ từ lịch sử
Rebase: Điều này di chuyển toàn bộ nhánh tính năng để bắt đầu trên đỉnh của nhánh chính, kết hợp hiệu quả tất cả các cam kết mới trong master
Thêm vào đây
Hợp nhất squash hợp nhất một cây (một chuỗi các xác nhận) thành một cam kết duy nhất. Đó là, nó đè bẹp tất cả những thay đổi được thực hiện trong n cam kết thành một cam kết duy nhất.
Rebasing là căn cứ lại, nghĩa là chọn một cơ sở mới (cam kết cha mẹ) cho một cây. Có lẽ thuật ngữ đồng bóng cho điều này rõ ràng hơn: họ gọi nó là cấy ghép bởi vì nó chỉ là: chọn một mặt bằng mới (cam kết gốc, gốc) cho một cây.
Khi thực hiện một rebase tương tác, bạn được cung cấp tùy chọn để squash, chọn, chỉnh sửa hoặc bỏ qua các cam kết mà bạn sẽ bắt đầu.
Hy vọng rằng đã rõ ràng!
Hãy bắt đầu bằng ví dụ sau:
Bây giờ chúng tôi có 3 tùy chọn để hợp nhất các thay đổi của nhánh tính năng thành nhánh chính :
Hợp nhất cam kết
Sẽ giữ tất cả các cam kết lịch sử của nhánh tính năng và di chuyển chúng vào nhánh chính
Sẽ thêm cam kết giả.
Rebase và merge
Sẽ nối thêm tất cả các cam kết lịch sử của nhánh tính năng ở phía trước của nhánh chính
sẽ KHÔNG thêm cam kết giả.
Bóp và hợp nhất
Sẽ nhóm tất cả các cam kết nhánh tính năng thành một cam kết sau đó nối nó ở phía trước nhánh chính
Sẽ thêm cam kết giả.
Bạn có thể tìm thấy bên dưới cách nhánh chính sẽ chăm sóc từng người trong số họ.
Trong mọi trường hợp:
Chúng ta có thể XÓA một cách an toàn nhánh tính năng .
G
đượcc--d--e--f--g
ép lại với nhau?