Bài 4: Interactive Rebase - Nghệ Thuật "Gom" Commit Làm Sạch Lịch Sử
Hãy thành thật với nhau nhé: Trong quá trình code một tính năng, đã bao nhiêu lần bạn tạo ra những commit kiểu như thế này:
- c1a2b3c: "wip: dang lam do giao dien"
- d4e5f6g: "fix bug typo"
- h7i8j9k: "fix tiep bug typo lan 2"
- l0m1n2o: "code chay duoc roi mlem mlem"
Việc commit nhỏ liên tục khi local là một thói quen tốt để tránh mất code. Tuy nhiên, nếu bạn mang nguyên một "rổ" commit vụn vặt này push lên Github và tạo Pull Request, Git Graph của dự án sẽ trông cực kỳ thiếu chuyên nghiệp và gây ức chế cho người Review.
úc này, bạn cần sử dụng một vũ khí tối thượng: Interactive Rebase (git rebase -i) để gộp tất cả các commit rác đó thành một commit duy nhất, sạch sẽ và có ý nghĩa.
1. Bản chất của Interactive Rebase trên Đồ thị
Nếu như Rebase thông thường (Bài 2) tự động dịch chuyển cả một khối commit, thì Interactive Rebase cho phép bạn dừng dòng thời gian lại và đóng vai một "kiến trúc sư". Bạn có quyền can thiệp vào từng commit: đổi tên, xóa bỏ, thay đổi thứ tự, hoặc gộp (Squash) nhiều commit lại làm một.
Khi bạn gộp 4 commit "thử nghiệm" phía trên thành 1 commit duy nhất mang tên "feat: Hoàn thành giao diện trang Dashboard", Git Graph sẽ thay đổi một cách vi diệu: Thay vì hiển thị 4 nút bấm nối tiếp nhau chiếm không gian, đồ thị sẽ co gọn lại thành đúng 1 nút duy nhất.
2. Thực chiến: Cách "gộp" Commit (Squash & Fixup)
Giả sử bạn đang ở nhánh feature và muốn dọn dẹp lại 4 commit gần nhất của mình. Hãy gõ lệnh sau:
git rebase -i HEAD~4
(Lệnh này có nghĩa là: Tôi muốn chỉnh sửa giao diện tương tác cho 4 commit tính từ vị trí HEAD ngược về quá khứ).
Ngay lập tức, một giao diện text (thường là Vim hoặc Nano) sẽ hiện ra, liệt kê 4 commit của bạn từ cũ nhất đến mới nhất (từ trên xuống dưới):
pick c1a2b3c wip: dang lam do giao dien
pick d4e5f6g fix bug typo
pick h7i8j9k fix tiep bug typo lan 2
pick l0m1n2o code chay duoc roi mlem mlem
# Rebase 8a7b6c5..l0m1n2o onto 8a7b6c5
# Commands:
# p, pick <commit> = use commit
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
Mặc định, tất cả đều là chữ pick (nghĩa là giữ nguyên commit). Để gộp các commit bên dưới vào commit đầu tiên, bạn chỉ cần sửa chữ pick thành squash (hoặc viết tắt là s):
pick c1a2b3c wip: dang lam do giao dien
squash d4e5f6g fix bug typo
squash h7i8j9k fix tiep bug typo lan 2
squash l0m1n2o code chay duoc roi mlem mlem
Sự khác biệt giữa Squash và Fixup:
- Squash (s): Gộp code của commit đó vào commit phía trên, đồng thời Git sẽ mở ra một cửa sổ nữa để bạn gộp các câu thông điệp (commit message) lại với nhau.
- Fixup (f): Gộp code vào commit phía trên nhưng vứt bỏ hoàn toàn cái thông điệp rác đi, chỉ giữ lại thông điệp của commit gốc (pick). Đây là cách nhanh nhất để xóa các commit "fix typo".
Sau khi bạn lưu và đóng file lại, Git sẽ thực hiện phép thuật của nó. Kiểm tra lại bằng lệnh xem đồ thị:
git log --oneline --graph
Bạn sẽ thấy 3 commit rác đã biến mất hoàn toàn, thay thế vào đó là một lịch sử thẳng băng, gọn gàng.
3. Lưu ý sống còn khi "dọn dẹp" lịch sử
Tương tự như quy tắc vàng ở Bài 2, việc sử dụng Interactive Rebase bản chất là hủy bỏ các commit cũ và sinh ra commit mới.
Quy tắc: Chỉ thực hiện git rebase -i đối với các commit ở local (chưa push).
Nếu bạn đã lỡ push đống commit rác lên remote repository, sau đó bạn rebase local để gom chúng lại, lúc này lịch sử giữa máy bạn và Github đã bị lệch hoàn toàn. Nếu muốn push lên, bạn buộc phải dùng lệnh git push --force-with-lease. Vì vậy, tốt nhất là hãy "dọn dẹp nhà cửa" thật sạch sẽ trước khi bấm lệnh push nhé!
Tóm lại là... Làm chủ được Interactive Rebase và tư duy gom commit (squash) giúp bạn kiểm soát hoàn toàn tính thẩm mỹ và mạch lạc của Git Graph. Một lịch sử Git sạch đẹp không chỉ giúp bạn ghi điểm trong mắt Tech Lead khi review code mà còn giúp việc rollback (quay xe) khi hệ thống gặp lỗi trở nên dễ dàng hơn bao giờ hết.
Bài học tiếp theo sẽ là bài cuối cùng của series Git Graph: Giải mã Git Flow và GitHub Flow dưới góc nhìn đồ thị. Chúng ta sẽ cùng xem cách các doanh nghiệp lớn tổ chức luồng đi của các nhánh mạng để vận hành hệ thống mượt mà, không xung đột.
All rights reserved