How git rebase works?

Posted in General on April 21, 2017 by manhhomienbienthuy Comments
How git rebase works?

git rebase là một trong số những lệnh của git tôi sử dụng rất nhiều. Là lập trình viên làm việc với git, chắc hẳn bạn cũng không lạ lẫm gì lệnh này. Chúng ta thường sử dụng git rebase cho vì những lý do sau:

  • Giữ code trong branch của chúng ta luôn update
  • Thay đổi một vài commit nào đó

Trong bài viết này, chúng ta sẽ đi sâu tìm hiểu cách thức git rebase làm việc để cho chúng ta những kết quả như trên.

Giữ branch luôn update

Đây là công việc chúng ta thường gặp phải nhất khi làm việc với git. Đặc biệt, team càng lớn, việc này càng diễn ra thường xuyên.

Nguyên nhân rất đơn giản, khi bạn checkout một nhánh mới là làm việc trong nhánh đó, các thành viên khác cũng tiếp tục phát triển trong nhánh của họ. Khi một ai đó gửi pull request và được merge vào nhánh chính, khi đó, nhánh mà bạn đã checkout đã outdate do thiếu những code vừa được merge.

Công việc bạn cần làm lúc nào là cập nhật nhánh của mình. Thực ra có 2 cách để làm việc này là git mergegit rebase. Tuy nhiên, tôi sử dụng git rebase vì nhiều lợi ích mà nó mang lại.

Trước hết, hãy xem git rebase sẽ làm gì trong trường hợp này. Đây là minh họa đơn giản cho trường hợp chúng ta cần update nhánh màu đỏ với nhánh chính đã được merge thêm code mới.

rebase before

Nhánh của chúng ta đang thiếu một số commit so với nhánh chính, bây giờ chúng ta sẽ gọi git rebase để cập nhật code. Đầu tiên, git rebase sẽ quay ngược trở lại commit mà tại đó, nhánh của chúng ta được checkout.

rebase rewind

Tại commit này, git rebase sẽ thêm các commit của nhánh chính. Lúc này, code của nhánh chính sẽ được thêm vào nhánh của chúng ta.

rebase forward

Tiếp theo, các commit mà chúng ta đã thực hiện trên nhánh của mình sẽ được thêm vào code vừa rồi

rebase replay

Kết thúc quá trình này, chúng ta sẽ có nhánh được update và commit chúng ta luôn luôn là commit cuối cùng.

rebase complete

Đây chính là một trong số những điểm nổi biệt khiến git rebase có vẻ thích hợp hơn git merge trong trường hợp này.

Thay đổi một số commit có sẵn

Ngoài trường hợp phổ biến trên, thỉnh thoảng tôi cũng sử dụng git rebase để thay đổi một vài commit có sẵn.

Thường thì việc này diễn ra khi commit hơi quá đà và trước khi gửi pull request tôi muốn gom các commit lại cho dễ merge sau này.

Để làm việc đó, tôi sử dụng git rebase -i, tùy chọn -i nghĩa là "interactive", nhờ nó, git rebase cho phép chúng ta biên tập lại những commit đang có.

Kết quả của lệnh trên là một editor được mở ra và mọi thứ trông khá giống lệnh git log --oneline, ngoại trừ một điều, đầu mỗi dòng là một lệnh mà chúng ta có thể thao tác để biên tập các commit.

rebase interactive

Tôi thường sử dụng squash để gom nhiều commit lại, đồng thời chỉnh sửa nộ dung commit luôn. Ngoài ra fixup cũng thường được dùng.

Khi lưu và thoát khỏi editor, git rebase -i cũng thực hiện một quá trình tương tự như quá trình "tua lại" rồi "chạy tiếp" tương tự như git rebase ở trên.

Lưu ý

Trong phần lớn các trường hợp, git rebase sẽ sinh ra conflict, mặc dù những chỗ chỉnh sửa chẳng liên quan gì đến nhau.

Một điểm cần lưu ý nữa là việc rebase sẽ làm thay đổi hash của commit, do đó, cho dù nội dung commit không thay đổi, lịch sử commit đã thay đổi rồi. Bạn cần sử dụng git push -f để update code này lên các server như github hoặc bitbucket.

Việc thay đổi hash này khá nghiêm trọng nếu chẳng may bạn thực hiện trên nhánh chính, nơi là các thành viên khác trong team cũng đang làm việc với nó.

Kết luận

git rebase là một cách thực đơn giản để update nội dung branch cũng như thay đổi các commit. Sử dụng git rebase giúp lịch sử commit trở nên đơn giản nhưng nội dung thay đổi từ commit ban đầu sẽ bị thay đổi.

I apologise for any typos. If you notice a problem, please let me know.

Thank you all for your attention.