Git: merge – rebase và những lưu ý
Bài viết được sự cho phép của tác giả Tùng Nguyễn
Sau một vài năm sử dụng Git, tôi càng ngày càng “lún sâu” vào Git commands (không phải xài git bằng command line). Trong quá trình làm việc với các team đông anh em, tôi tìm thấy lệnh git rebase. Khá hay và ngay lập tức tôi áp dụng nó vào đời sống coding của tôi, nhưng sau một thời gian sử dụng tôi nhận ra rebasing thật sự không phù hợp cho người mới bắt đầu xài git. Hôm bữa có anh em hỏi tôi git rebase là gì và khi nào xài và xài nó như thế nào!?
Trong bài viết này tôi chia sẻ với anh em git rebase là gì, nó khác gì với git merge và những lưu ý khi sử dụng git rebase.
Merge và Rebase
Về cơ bản anh em có thể hiểu git rebase tương tự như git merge. Nó đều dùng để kết hợp những thay đổi từ nhánh này qua nhánh kia, nhưng chỉ khác nhau về cơ chế hoạt động.
Bây giờ lấy ví dụ tôi đang làm việc trên nhánh #feature-a, commit cật lực lên đó. Cùng lúc đó team member của tôi push commit lên nhánh main. Các bạn nhìn hình dưới cho dễ hình dung:
Bây giờ giả sử những commit trên nhánh main có liên quan đến #feature-a mà tôi đang làm. Tôi muốn kết hợp mấy commit đó vào nhánh #feature-a thì sẽ có 2 cách làm: merging hay rebasing.
Git merge
Để merge 2 nhánh lại với nhau tôi nghĩ anh em ai cũng biết. Có thể chạy 2 câu lệnh đơn giản sau:
git checkout #feature-a
git merge main
Hoặc đơn giản hơn nữa khi bạn xài UI tool như SourceTree hay GitKraken, anh em làm như sau, tôi thì đang xài GitKraken:
Khi anh em làm vậy, git sẽ tạo 1 “merge commit” mới trên nhánh #feature-a, trong đó chứa tất cả các commit của 2 nhánh, bây giờ cấu trúc của 2 nhánh main và #feature-a giống giống như vầy:
Git merge dễ sử dụng và an toàn vì logic của nó không làm phá hủy cấu trúc lịch sử của các nhánh. Các lịch sử commit trên nhánh main và #feature-a sẽ không bị thay đổi.
Mặt khác, nhánh #feature-a luôn luôn có 1 “merge commit” mới mỗi khi anh em merge nó với nhánh khác. Trong trường hợp nhánh main được merge vào liên tục, điều này sẽ làm git của tôi rối mù lên, tôi nói riêng và team member nói chung sẽ rất khó hiểu được lịch sử commit của cả project.
Git rebase
Như 1 biện pháp thay thế cho git merge
, anh em có thể xài git rebase
nhánh #feaure-a trên nhánh main sử dụng command như sau:
git checkout #feature-a
git rebase main
Hoặc xài UI tool như SourceTree hay GitKraken như sau:
Git rebase
sẽ đem hết commit của nhánh #feature-a lên đầu của nhánh main, bao gồm cả những commit hiện có trên nhánh main luôn. Nhưng thay vì tạo ra 1 cái “merge commit” nhưgit merge
,git rebase
sẽ “viết lại lịch sử” commit của project bằng cách tự động tạo các commit mới dựa trên các commit trên nhánh #feature-a.
Lợi ích chính của việc xài git rebase là đem lại cho chúng ta 1 project có lịch sử commit rất đẹp và gọn gàng, không rối mù với các nhánh chỉa qua chỉa lại như git merge. Nó cũng sẽ loại bỏ được những “merge commit” không cần thiết của git merge. Nhìn vào sơ đồ ở trên ta có thể thấy project trở nên thằng như ruột ngựa, git log hay git bisect nhìn cũng rất rõ ràng, sạch sẽ.
Tham khảo Job FrontEnd HOT trên TopDev!
Những lưu ý khi sử dụng Rebasing
Một khi anh em đã hiểu được git rebase
là gì và cơ chế hoạt động của nó. Việc chúng ta cần chú ý nhất ở đây là khi nào nên sử dụng git rebase
.
Nguyên tắc vàng mà tôi đúc kết được là không được sử dụng git rebase lên “public branch”, tức là mấy nhánh như develop hay main.
Bây giờ lấy ví dụ, tôi sử dụng git rebase nhánh main lên nhánh #feature-a của tôi, git history của tôi sẽ giống giống hình dưới đây:
Rebase sẽ đem hết commit của nhánh main lên đầu nhánh #feature-a. Nhìn thì thấy cũng bình thường, nhưng nghĩ lại thì tôi nhận ra nó chỉ đúng ở repo local của tôi thôi. Team member của tôi đều đang làm việc trên nhánh original main. Vì rebase sẽ tạo ra các commit hoàn toàn mới nên git sẽ hiểu là nhánh main của tôi khác hoàn toàn với nhánh main của những người khác.
Bây giờ điều duy nhất có thể làm là merge 2 nhánh main lại với nhau, điều này dẫn đến tạo ra thêm 1 merge commit và 1 nùi những commit với thay đổi giống nhau ( các commit ở nhánh main cũ, và commit ở nhánh rebase của tôi).
Bởi vậy khi anh em đang định sử dụng git rebase
, hãy dừng lại 1 chút và tự trả lời câu hỏi “Liệu có ai đang làm việc trên nhánh này không!?”. Nếu có, tôi đề nghị anh em hãy bỏ ý định sử dụng git rebase lên nhánh đó. Còn nếu không, anh em thoải mái viết lại lịch sử của mình.
Lúc này nếu tôi lười quá, muốn force push nhánh main của mình lên remote cho nhanh, git sẽ la làng vì làm thế có thể sẽ tạo rất nhiều conflict. Nhưng tôi hoàn toàn có thể “cưỡng ép” git bằng cách thêm –force vào command:
git push --force
Làm thế sẽ giúp tôi nhẹ lòng nhưng team member của tôi thì không. Họ sẽ không hiểu chuyện gì đang xảy ra với nhanh main, mọi commit đều trở nên xa lạ.
Một lưu ý nữa là nếu anh em đang làm việc trên nhánh mà mình đã pushed một vài commit lên remote. Ví dụ anh em đang làm việc trên nhánh #feature-a, mà trước đó đã pushed vài commit lên remote rồi, thì anh em không nên rebase lên nhánh #feature-a.
Trên này là một vài chia sẻ của tôi về git base
và những lưu ý khi sử dụng nó. Hy vọng anh em nào chưa biết có thêm 1 chút kinh nghiệm về git của mình.
Happy hacking
Bài viết gốc được đăng tải tại omatsuri.blog, biết thêm về tác giả tại LinkedIn
Xem thêm:
- Những câu hỏi phỏng vấn về GIT cần nhớ ngay
- Các lệnh git cơ bản mà mọi lập trình viên nên biết
- Git Submodules và ứng dụng trong việc chia sẻ tài nguyên dùng chung
Tìm việc làm IT mới nhất trên TopDev
- M Mới ra trường không kinh nghiệm, sao làm BA?
- C Chuyển đổi SA key sang Workload Identity
- U Use Case Diagram và 5 sai lầm thường gặp
- K Kinh nghiệm xử lý câu lệnh điều kiện trong JavaScript
- D Dart là gì? Ứng dụng của ngôn ngữ lập trình Dart
- C Chuẩn Hóa CV, Nhận Ngay Phím Chất
- S So sánh MySQL và MongoDB: Nên chọn CSDL nào?
- D Dân BA có cần phải rành về kỹ thuật???
- C CSS Selector là gì? Cách sử dụng các loại CSS Selector phổ biến
- P Phân biệt Sketch, Wireframe, Mockup, và Prototype?