Git: squash commit
Cập nhật lần cuối
Squash là gộp nhiều commit thành một, để một loạt commit lộn xộn kiểu "wip", "fix typo", "actually fix it" trở thành một commit gọn gàng duy nhất. Công cụ quen thuộc là rebase tương tác, git rebase -i, nơi bạn đánh dấu các commit cần gộp lại. Vì squash viết lại lịch sử, hãy làm trước khi push, hoặc trên một nhánh chỉ mình bạn làm.
Bạn có thể thử các lệnh này trong terminal playground: một shell thật ngay trên trình duyệt, không cần cài đặt gì.
Cú pháp
| Lệnh | Tác dụng |
|---|---|
git rebase -i HEAD~3 | Rebase tương tác 3 commit gần nhất |
git rebase -i main | Rebase mọi commit kể từ main |
git merge --squash feature | Gộp các commit của một nhánh thành một khi merge |
git reset --soft HEAD~3 && git commit | Squash 3 commit cuối mà không cần rebase |
Lệnh trong rebase tương tác
Trong trình soạn thảo vừa mở, đổi pick thành một trong các từ khóa sau.
| Từ khóa | Tác dụng |
|---|---|
pick | Giữ nguyên commit |
squash (s) | Gộp vào commit trước đó, nối các thông điệp |
fixup (f) | Gộp vào nhưng bỏ thông điệp của commit này |
reword (r) | Giữ commit nhưng sửa thông điệp |
Ví dụ từng bước
Squash ba commit cuối thành một trước khi push.
| Bước | Thao tác | Kết quả |
|---|---|---|
| 1 | git rebase -i HEAD~3 | Mở 3 commit cuối trong trình soạn thảo |
| 2 | Đổi commit 2 và 3 thành squash | Đánh dấu để gộp chúng vào commit đầu tiên |
| 3 | Lưu và sửa thông điệp đã gộp | Ba commit trở thành một commit gọn gàng |
Câu hỏi thường gặp về squash commit trong Git
Squash commit nghĩa là gì?
Squash biến nhiều commit thành một commit chứa toàn bộ thay đổi của chúng. Các tệp cuối cùng vẫn y hệt; chỉ lịch sử thay đổi, nên người review thấy một commit với một thông điệp thay vì một chuỗi sửa lặt vặt.
Làm sao squash N commit cuối trong Git?
git rebase -i HEAD~N (ví dụ HEAD~3 cho ba commit cuối). Trong trình soạn thảo, để commit đầu tiên là pick và đổi các commit còn lại thành squash (hoặc fixup để bỏ thông điệp của chúng). Lưu lại, sửa thông điệp commit đã gộp, và các commit sẽ gộp thành một.squash và fixup khác nhau thế nào?
squash giữ thông điệp của commit và cho bạn ghép nó với các thông điệp khác trong trình soạn thảo. fixup bỏ hẳn thông điệp của commit, chỉ giữ thông điệp của commit trước đó. Rất tiện cho những commit kiểu "oops, sửa nhỏ" mà bạn không muốn xuất hiện trong thông điệp cuối cùng.Làm sao squash cả một nhánh khi merge?
git merge --squash feature, rồi git commit. Lệnh này áp dụng toàn bộ thay đổi của nhánh dưới dạng thay đổi đã stage và cho bạn ghi chúng thành một commit duy nhất trên nhánh đích, không mang theo từng commit riêng lẻ của nhánh. Nút "Squash and merge" của GitHub cũng làm đúng điều này.Có squash được mà không cần rebase tương tác không?
git reset --soft HEAD~N lùi nhánh N commit trong khi giữ mọi thay đổi của chúng ở trạng thái staged, rồi một lệnh git commit duy nhất ghi chúng thành một commit. Đây là cách nhanh để squash các commit gần nhất mà không phải mở trình soạn thảo rebase.Có nên squash commit trước khi merge không?
Có thể luyện tập lệnh này online không?
Có. Mở terminal playground để chạy rebase tương tác trong một shell thật ngay trên trình duyệt, không cần cài đặt gì. Khóa học Git tương tác miễn phí của Coddy cũng hướng dẫn từng bước cách rebase và dọn dẹp lịch sử.