Trong Git, git rebase là một công cụ mạnh mẽ cho phép bạn thay đổi lịch sử commit bằng cách di chuyển hoặc kết hợp các nhánh. Rebase không giống như git merge vì thay vì tạo ra một commit hợp nhất (merge commit), nó sẽ “di chuyển” các commit từ một nhánh lên trên các commit của nhánh khác, giúp lịch sử trở nên gọn gàng và tuyến tính hơn.

Việc sử dụng git rebase có thể làm cho lịch sử Git dễ theo dõi, loại bỏ các commit không cần thiết và giữ cho nhánh của bạn không bị phân nhánh phức tạp.

Cách hoạt động của Git Rebase

Rebase hoạt động bằng cách di chuyển toàn bộ lịch sử commit của một nhánh lên trên một nhánh khác. Điều này làm thay đổi cách mà các commit liên quan với nhau, tạo ra một dòng lịch sử thẳng (linear history) thay vì phân nhánh (branching history).

Giả sử bạn có hai nhánh: featuremain. Nhánh feature được phát triển từ main nhưng cả hai nhánh đều có các commit riêng lẻ. Nếu bạn muốn di chuyển các commit từ nhánh feature lên trên các commit hiện tại của nhánh main, bạn sẽ sử dụng git rebase.

Cú pháp cơ bản của Git Rebase

git rebase <upstream_branch>

Trong đó upstream_branch là nhánh mà bạn muốn di chuyển các commit lên trên. Ví dụ, nếu bạn đang làm việc trên nhánh feature và muốn rebase nó lên nhánh main, bạn sẽ sử dụng:

git checkout feature
git rebase main

Sau khi rebase thành công, tất cả các commit từ nhánh feature sẽ được “di chuyển” lên trên các commit hiện tại của nhánh main.

Các chế độ hoạt động của Git Rebase

Rebase tương tác (Interactive Rebase)

Khi bạn muốn kiểm soát từng commit trong quá trình rebase, bạn có thể sử dụng chế độ tương tác với lệnh:

git rebase -i <upstream_branch>

Chế độ này cho phép bạn chỉnh sửa, gộp (squash), hoặc thậm chí bỏ qua các commit trong quá trình rebase. Khi chạy lệnh này, Git sẽ mở một trình chỉnh sửa văn bản cho phép bạn thực hiện các hành động trên từng commit. Các tùy chọn bao gồm:

  • pick: Giữ nguyên commit.
  • reword: Đổi tên commit message.
  • edit: Chỉnh sửa commit (thay đổi nội dung).
  • squash: Gộp commit hiện tại với commit trước đó.
  • drop: Bỏ qua commit này.

Rebase tự động (Automatic Rebase)

Bạn có thể chạy lệnh rebase mà không cần chỉnh sửa từng commit. Điều này giúp bạn nhanh chóng di chuyển toàn bộ lịch sử commit mà không cần can thiệp bằng tay.

Ví dụ:

git rebase main

Lệnh này sẽ di chuyển toàn bộ commit từ nhánh hiện tại lên trên các commit của main mà không yêu cầu sự can thiệp thủ công.

Giải quyết xung đột khi sử dụng Git Rebase

Trong quá trình rebase, có thể xảy ra xung đột nếu cùng một tệp được chỉnh sửa trong cả hai nhánh. Khi gặp xung đột, Git sẽ tạm dừng rebase và yêu cầu bạn giải quyết các xung đột này thủ công. Sau khi giải quyết xung đột, bạn cần thêm lại các tệp đã chỉnh sửa:

git add <file>

Sau đó, tiếp tục quá trình rebase bằng cách sử dụng lệnh:

git rebase –continue

Nếu bạn muốn hủy quá trình rebase và quay lại trạng thái ban đầu, bạn có thể sử dụng:

git rebase --abort

So sánh Git Rebase và Git Merge

Mặc dù cả git rebasegit merge đều được sử dụng để tích hợp thay đổi từ nhánh này sang nhánh khác, nhưng chúng có cách hoạt động khác nhau:

  • git merge: Tạo ra một commit hợp nhất (merge commit), giữ nguyên cấu trúc phân nhánh.
  • git rebase: Không tạo commit hợp nhất mà di chuyển các commit, giúp lịch sử trở nên tuyến tính và dễ đọc hơn.

Khi nào nên sử dụng Git Rebase

Rebase rất hữu ích trong các tình huống mà bạn muốn giữ cho lịch sử Git của dự án gọn gàng và dễ theo dõi, đặc biệt là khi làm việc trong các nhóm lớn. Một số trường hợp điển hình bao gồm:

  • Giữ cho lịch sử commit tuyến tính: Khi bạn làm việc trên một nhánh tính năng và muốn tích hợp thay đổi từ nhánh chính mà không tạo ra commit hợp nhất.
  • Làm sạch lịch sử commit: Khi bạn có nhiều commit nhỏ và không cần thiết, bạn có thể sử dụng git rebase -i để gộp chúng lại.

Git rebase là một công cụ mạnh mẽ giúp bạn làm sạch lịch sử commit và giữ cho mã nguồn dễ theo dõi. Tuy nhiên, cần cẩn thận khi sử dụng rebase trên nhánh đã chia sẻ vì nó có thể thay đổi lịch sử commit và gây ra xung đột nếu không được thực hiện đúng cách. Sử dụng git rebase một cách có chiến lược sẽ giúp bạn tối ưu hóa quá trình phát triển phần mềm.