Git là một hệ thống quản lý phiên bản phân tán phổ biến, và trong đó, git rebase
là một trong những lệnh mạnh mẽ nhưng cũng tiềm ẩn rủi ro nếu không sử dụng đúng cách. Vậy git rebase
là gì, hoạt động ra sao và nên sử dụng trong tình huống nào? Bài viết này sẽ giúp bạn hiểu tường tận về Git Rebase, từ cơ bản đến nâng cao.
Git Rebase là gì?
Git rebase
là một lệnh dùng để di chuyển hoặc áp dụng lại các commit từ một nhánh này sang một nhánh khác, bằng cách tái tạo lại lịch sử commit theo cách tuyến tính. Không giống như merge
, rebase
không tạo ra commit hợp nhất (merge commit), giúp lịch sử dự án trở nên sạch sẽ, dễ đọc hơn.
Cú pháp cơ bản:
git rebase <tên-nhánh>
Khi nào nên dùng git rebase
?
Bạn nên cân nhắc sử dụng rebase
trong các tình huống:
- Cập nhật nhánh với thay đổi mới nhất từ nhánh gốc (thường là
main
hoặcmaster
) mà không tạo ra commit merge. - Duy trì lịch sử commit gọn gàng: Bởi vì cơ chế tái tạo một lịch sử commit tuyến tính và không tạo ra commit merge nên git rebase rất phù hợp cho những dự án cần giữ lịch sử đơn giản và gọn gàng
- Tái sử dụng hoặc tái cấu trúc nhánh, ví dụ như squash các commit lại với nhau.
- Dọn dẹp commit trước khi push lên repository
Cách hoạt động của Git Rebase
Nói một cách hình tượng: git rebase
sẽ “nhổ” commit của bạn ra khỏi dòng thời gian hiện tại, sau đó “dán” lại vào đỉnh của nhánh đích.
Quy trình:
- Git xác định commit chung giữa hai nhánh.
- Tất cả các commit mới trên nhánh hiện tại (sau commit chung) sẽ được tạm cất đi.
- Git áp dụng các commit từ nhánh đích.
- Cuối cùng, các commit tạm cất được đưa trở lại theo thứ tự mới, đặt lên trên commit của nhánh đích.
Kết quả: bạn có một lịch sử commit thẳng tắp, như thể chỉ có bạn làm việc trên nhánh đó.
Giả sử bạn có hai nhánh A
và B
đều bắt đầu từ commit C1
. Sau một thời gian, A
có thêm các commit C2
, C3
và B
có C4
, C5
. Khi bạn thực hiện:
git checkout A
git rebase B
Git sẽ thực hiện các bước:
- Tìm commit chung gần nhất (C1).
- Loại bỏ tạm thời các commit từ
A
(C2, C3). - Áp dụng commit từ
B
(C4, C5). - Tái áp dụng các commit đã loại bỏ (C2, C3) lên trên nhánh mới.
Kết quả: lịch sử commit của nhánh A
sẽ là C1 -> C4 -> C5 -> C2' -> C3'
.
Ưu điểm & Nhược điểm của Git Rebase
Ưu điểm | Nhược điểm |
---|---|
Lịch sử commit sạch, dễ đọc | Có thể mất thông tin về quá trình phát triển thực tế |
Không tạo commit merge dư thừa | Dễ conflict khi rebase commit theo thứ tự |
Hỗ trợ squash nhiều commit | Không nên dùng trên nhánh đã được chia sẻ công khai |
Hỗ trợ kiểm soát commit khi review | Dễ gây nhầm lẫn nếu không hiểu rõ quy trình |
Hướng dẫn rebase thực tế
1. Rebase nhánh new-feature
với main
git checkout main
git pull origin main
git checkout new-feature
git rebase main
Nếu xảy ra conflict:
- Mở file bị xung đột, chỉnh sửa nội dung giữa
<<<<<<<
,=======
,>>>>>>>
- Thêm vào staging:
git add <file>
git rebase --continue
Nếu cần huỷ rebase:
git rebase --abort
Sau khi hoàn tất:
git push origin new-feature --force-with-lease
Không rebase các nhánh đã chia sẻ với người khác nếu bạn không chắc chắn họ có thể xử lý conflict hoặc thay đổi lịch sử.
Rebase nâng cao
1. Interactive Rebase
git rebase -i HEAD~<số-commit>
cho phép bạn chỉnh sửa thủ công từng commit trong một chuỗi commit gần nhất. Điều này rất hữu ích khi bạn muốn:
- Gộp nhiều commit nhỏ thành một commit có ý nghĩa.
- Sửa lại thông điệp commit (commit message).
- Thay đổi nội dung của commit.
- Xóa những commit không còn cần thiết
Tùy chọn tương tác:
--pick
: giữ nguyên--reword
: sửa commit message--edit
: chỉnh sửa nội dung--squash
: gộp vào commit trước--drop
: xoá bỏ commit
2. Autosquash
Thay vì phải vào giao diện interactive rebase và di chuyển thủ công từng dòng squash hoặc fixup, autosquash giúp bạn tự động sắp xếp và gộp commit đúng vị trí, dựa trên tên commit.git commit --fixup=<hash>
git commit --squash=<hash>
git rebase -i --autosquash HEAD~<n>
3. Một số tùy chọn hữu ích khác
Lệnh | Ý nghĩa |
---|---|
--continue | Tiếp tục sau khi xử lý xung đột |
--abort | Hủy rebase, quay lại trạng thái trước |
--skip | Bỏ qua commit hiện tại |
--keep-empty | Giữ commit rỗng |
--quiet | Giảm thông tin chi tiết |
--verbose | Tăng thông tin chi tiết |
--strategy=recursive/ours/theirs/... | Tự động chọn cách resolve conflict |
Câu hỏi thường gặp
Khi nào nên dùng rebase
thay vì merge
?
- Khi bạn làm việc một mình.
- Muốn giữ lịch sử tuyến tính và dễ hiểu.
- Trước khi gửi pull request.
Làm sao để hoàn tác khi lỡ rebase sai?
Sử dụng git reflog
để tìm lại vị trí trước khi rebase và khôi phục:
git reflog
git reset --hard HEAD@{n}
Rebase có làm mất dữ liệu không?
Không, nếu bạn hiểu rõ và xử lý cẩn thận. Tuy nhiên, bạn có thể vô tình xoá commit nếu dùng sai squash
, drop
, hoặc xử lý xung đột không đúng cách.
Tổng kết
Git rebase
là một công cụ tuyệt vời để duy trì một lịch sử commit rõ ràng, tuyến tính và chuyên nghiệp. Tuy nhiên, hãy sử dụng cẩn trọng, đặc biệt là trong môi trường làm việc nhóm hoặc với các nhánh đã được push lên từ trước.