Git Rebase: Làm Chủ Lịch Sử Commit Một Cách Gọn Gàng và Hiệu Quả

5 min read

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ặc master) 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:

  1. Git xác định commit chung giữa hai nhánh.
  2. 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.
  3. Git áp dụng các commit từ nhánh đích.
  4. 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 AB đều bắt đầu từ commit C1. Sau một thời gian, A có thêm các commit C2, C3BC4, C5. Khi bạn thực hiện:

git checkout A
git rebase B

Git sẽ thực hiện các bước:

  1. Tìm commit chung gần nhất (C1).
  2. Loại bỏ tạm thời các commit từ A (C2, C3).
  3. Áp dụng commit từ B (C4, C5).
  4. 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ểmNhược điểm
Lịch sử commit sạch, dễ đọcCó 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ừaDễ conflict khi rebase commit theo thứ tự
Hỗ trợ squash nhiều commitKhông nên dùng trên nhánh đã được chia sẻ công khai
Hỗ trợ kiểm soát commit khi reviewDễ 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
--continueTiếp tục sau khi xử lý xung đột
--abortHủy rebase, quay lại trạng thái trước
--skipBỏ qua commit hiện tại
--keep-emptyGiữ commit rỗng
--quietGiảm thông tin chi tiết
--verboseTă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.

Avatar photo

Leave a Reply

Your email address will not be published. Required fields are marked *