Git - Difference between Rebase and Merge
Câu hỏi về So sánh `git rebase` và `git merge` đôi khi được hỏi trong phỏng vấn. Bạn nên nắm được sự khác nhau để tự tin hơn khi trả lời.
Table of Contents
Câu hỏi về So sánh git rebase
và git merge
đôi khi được hỏi trong phỏng vấn. Bạn nên nắm được sự khác nhau để tự tin hơn khi trả lời.
1. Intro
Đôi khi chúng ta thấy các Developer dùng git rebase
để merge/lấy các thay đổi từ nhánh khác về.
Nhưng chỉ nên dùng git rebase
trên 1 nhánh của riêng bạn (hoặc chỉ mình bạn làm việc trên nhánh đó),
đừng nên dùng git rebase
trên 1 nhánh mà có nhiều người cùng làm việc nhé. Tại sao thì chúng ta sẽ cùng theo dõi ví dụ sau.
2. Demo
2.1. Git Merge
Trên Gitlab, tạo project git-rebase-merge-test
Trên nhánh main
tạo file “main01”:
Commit log của nhánh main
sẽ như này:
Hiện tại các bạn đang ở chỗ bôi sáng của diagram sau:
Tại máy local, tạo branch mới là dev
(git checkout -b dev
), tạo file dev01
rồi push lên remote:
Vì nhánh dev được tạo ra từ nhánh main
nên nó mặc định có 3 commit ban đầu của main
, tại thời điểm này bạn có thêm commit “add dev01”:
Trên giao diện GitLab, trên nhánh main
tạo file main02
:
Tại thời điểm này ở local máy bạn cần sang nhánh main
pull code latest về, bạn sẽ thấy nhánh main
đã có file main02
:
giờ switch sang nhánh dev
, bạn tiếp tục edit file README.md
rồi push lên remote với commit “dev edit 1 readme”:
Trên diagram, bạn đang ở vùng này:
Giờ bạn đứng ở nhánh dev
, thực hiện merge với nhánh main
bằng command git merge main
(git pull origin main
cũng sẽ làm nhiệm vụ tương tự):
bạn muốn file main02
của nhánh main
được xuất hiện trong nhánh dev
của bạn đúng ko nào?
File main02
xuất hiện:
Vẫn đang trên nhánh dev
, bạn tạo thêm 1 file dev02
rồi push lên remote
Chú ý nhé
Bạn sẽ thấy 1 commit được tạo tự động là “Merge branch main into dev” -> đó là commit được tạo ra bới command git merge main
:
Trên diagram, bạn đang ở vùng này:
Vậy git merge
đã làm gì?
-> git merge
đưa đúng các commit vào vị trí của nó theo thời gian:
- Commit “Add new file main02” được đưa vào đúng vị trí là sau “add dev01”.
- Tất cả commit hash id của nhánh
dev
ko thay đổi gì. - Tạo thêm 1 commit (box màu hồng) là: “Merge branch main into dev”.
Tiếp theo ta tìm hiểu git rebase
sẽ hoạt động như thế nào…
2.2. Git Rebase
Giờ trên giao diện Gitlab, nhánh main
tạo 1 file mới “main03”:
Tại local, trên nhánh dev
, tạo file “dev03”, push lên remote. Nhánh dev
đang ở vùng sáng này trong diagram:
edit file README.md
, push lên remote với commit là “edit readme 2”:
Trên máy local, switch sang nhánh main
, pull code latest về
Rồi, giờ switch sang dev
, đứng nhánh dev
run git rebase main
:
Rebase xong bạn sẽ cần push thay đổi lên nhánh dev
:
nếu bạn git push origin dev
-> sẽ báo lỗi ngay
thế nên bạn phải push force như sau:
git push origin dev -f
log commit sẽ như sau:
Bạn nhìn log đó hơi lạ đúng ko, sự thay đổi được mô tả lại trên diagram:
Vậy Git Rebase đã làm gì?
Bạn sẽ thấy dù ko còn cái commit tự động (bôi hồng) được thêm vào nữa nhưng
-> git rebase
đã làm:
- Đưa các commit của nhánh
dev
lên trên đầu, commit của nhánhmain
đẩy xuống dưới. - Commit hash id của nhánh
dev
bị thay đổi hết (-> đây là lý do bạn cần push force).
=> Nếu bạn làm việc trên 1 nhánh riêng biệt của mình bạn, việc thay đổi commit hash id này ko vấn đề gì,
nhưng nếu bạn làm việc trên 1 nhánh mà có nhiều người cùng làm việc, việc này có thể dẫn đến làm mất code của người khác.
Bù lại, commit log của nhánh dev
nhìn sẽ clear hơn cho bạn, ko có commit tự động xen vào giữa.
Diagram tổng kết ở đây:
Quan điểm của riêng mình: Chỉ dùng git rebase
trên nhánh riêng của bạn để làm đẹp commit log.
Bởi git rebase
ghi đè lịch sử commit nên nếu bạn tôn trọng lịch sử thì đừng nên cố gắng thay đổi nó. Hãy dùng git merge
.
Hy vọng bài viết và diagram trên giúp bạn hiểu rõ sự khác biệt ✌
Thank You!
Your comment has been submitted. It will appear on this page shortly! OKYikes, Sorry!
Error occured. Couldn't submit your comment. Please try again. Thank You! OK