Những tình huống thường gặp khi làm việc với Git
Series: Git
- Git nhập môn - 15 lệnh Git cơ bản
- Những tình huống thường gặp khi làm việc với Git
- Git commit message - Phải bạn không ? Cùng sửa nhé
Trong bài viết trước, mình đã giới thiệu tới mọi người về một số câu lệnh Git thường dùng, ở bài viết này, mình sẽ giới thiệu một số tình huống thường gặp khi làm việc với Git nhé, gét gô!
1. Xử lý conflict
Tokuda và Thảo là hai dev cùng làm việc trên project japan-antivirus
, một ngày đẹp trời ông leader vỗ vai Thảo và Tokuda:
"Tokuda, chú sửa chức năng chỉnh sửa nhân viên nhé, thêm trường ABC vào thông tin nhân viên cho anh"
"Ê Thảo, em sửa giúp anh chức năng view thông tin nhân viên, thêm check quyền vào nhé!"
Thế là Tokuda và Thảo checkout code từ branch dev
, Tokuda làm việc trên branch feature/add-user-fields
, còn Thảo làm việc trên branch feature/add-check-user-authority
, tuy nhiên thì cả Tokuda và Thảo đều sửa vào line 69 của file user.ts
Do Tokuda pro hơn nên đã hoàn thành task sớm, branch feature/add-user-fields
của Tokuda nhanh chóng được merge vào dev
, mọi chuyện vẫn ổn cho đến khi Thảo tạo merge request feature/add-check-user-authority
vào dev
.
Đập vào mắt Thảo là error CONFLICT (content): Merge conflict in user.ts
, lúc này thay vì chửi thề thì Thảo cần phải thực hiện các bước sau:
1.1. Xác định đoạn code bị conflict:
Sử dụng git status
để tìm các file bị conflict
Trong file user.ts
, Thảo thấy nội dung như sau:
1.2. Giải quyết conflict
Trao đổi với Tokuda, xem cần giữ đoạn code của Thảo, hay đoạn code của Tokuda, hay là kết hợp cả 2, sau đó loại bỏ dấu <<<<<<<
, =======
, và >>>>>>>
Sử dụng lệnh git add user.ts
và git commit
để hoàn tất quá trình merge
1.3. Kiểm tra lại và push lên remote
Dùng git status
để check lại xem còn conflict chưa được xử lý không.
Nếu còn, quay về bước 1, nếu không, sử dụng git push
để đẩy những thay đổi đã merge lên remote
Note
Để hạn chế conflict code bạn cần thường xuyên pull code và commit code
2. Xem lịch sử commit và lịch sử hoạt động trên git
Sử dụng git log
để xem lịch sử commit như hash commit, người commit, thời gian commit, message của commit
git reflog
như một activity history, giúp lưu lại các hoạt động đã thao tác trên git, ví dụ như Tokuda vừa checkout qua nhánh master, hay là Thảo vừa reset một commit,... git reflog
rất hữu ích cho những sai lầm trong quá trình sử dụng git (mình có ví dụ một sai lầm ở tình huống 4)
3. Xóa commit
Sau một ngày dài miệt mài múa code, cuối cùng thì Thảo cũng đã hoàn thành task, Thảo commit code và đi ngủ.
Hôm sau Thảo mở lại code và thấy code của mình trông phản cảm vl, Thảo cần sửa lại cho vở sạch chữ đẹp.
Trường hợp chỉ cần chỉnh sửa code thôi thì Thảo có thể sử dụng git reset
, còn hết cứu thì Thảo có thể sử dụng git revert
🤣
git reset
có vài option như mixed
(mặc định nếu không truyền option), --soft
và --hard
4. Khôi phục commit
Như ở tình huống 3, Thảo muốn reset commit để chỉnh sửa code thôi nhưng Thảo lại "nhỡ tay" --hard
khiến cho code bị bay màu hết, Thảo lúng túng cầu cứu anh Leader, anh Leader đã hướng dẫn Thảo lấy lại code với các thao tác như sau:
Sử dụng git reflog để lấy hash commit:
Sử dụng git reset --hard
để khôi phục commit:
Thảo vui mừng hò reo cảm ơn anh Leader ríu rít
5: Gộp nhiều commit lại thành 1 commit
Tokuda được giao một nhiệm vụ là quản lý users bao gồm CRUD. Tokuda nghe lời dặn của anh Leader là "code phải commit code liên tục nha em"
Tokuda tạo file userRouter, Tokuda commit
Tokuda tạo tiếp file userController, Tokuda commit tiếp
Tokuda tạo file userService, Tokuda lại tiếp tục commit
Tokuda làm xong task và hí ha hí hửng đưa qua anh Leader để review code, anh Leader nhìn vào Pull Request thì bèn nói rằng: "Em gộp lại các commit thành 1 cho anh nhé, commit liên tục là cần thiết nhưng cần phải commit hợp lý, tránh dư thừa hoặc trùng lặp quá nhiều"
Tokuda loay hoay và suy nghĩ trong đầu: "Vậy gộp như làm thế nào bây giờ?"
Thôi chuyện gì cũng tới tay anh Leader, anh Leader tiếp tục hướng dẫn Tokuda gộp commit, thao tác như sau:
Sử dụng git rebase
Git sẽ mở một cửa sổ tương tác, chọn các commit cần gộp chuyển pick thành squash và lưu lại Git tiếp tục mở một cửa sổ tương tác, chọn message hoặc nhập message commit tùy ý và lưu lại. Done
6. Chỉnh sửa message commit
Một lần Tokuda commit nhầm message và Tokuda chỉnh sửa lại được message đó. Tokuda vui lắm, Tokuda liền chia sẻ lên diễn đàn X, tác giả (là mình) tình cờ thấy bài chia sẻ đó của Tokuda nên copy paste vào đây. Cách xử lý của Tokuda như sau:
Đối với message mới nhất: sử dụng git commit --amend -m "new_message"
(chỉ đổi được message của commit mới nhất thôi)
Đối với nhiều message cùng lúc, cũ mới đều được:
Sử dụng git rebase -i HEAD~n (n là số commit muốn đổi message)
Git sẽ mở một cửa sổ tương tác, bạn đổi pick sang reword cho những commit muốn đổi, lưu lại
Git tiếp tục mở một cửa sổ tương tác, bạn đổi message mới và lưu lại, bao nhiêu commit muốn đổi thì có bấy nhiêu cửa sổ tương tác mở ra để đổi message
7. Đổi tên branch
Lại một lần khác, Tokuda đặt nhầm tên nhánh và Tokuda chỉnh sửa lại được tên branch đó. Tokuda vui lắm, Tokuda liền chia sẻ lên diễn đàn X, tác giả (là mình) lại tình cờ thấy bài chia sẻ đó của Tokuda nên copy paste vào đây. Cách xử lý của Tokuda như sau:
Nếu đặt sai tên nhánh, vui lòng nhập lệnh sau: git branch -m new_branch
8: Không thể checkout qua nhánh khác
Tokuda và Thảo là hai bạn thực tập sinh của công ty A Bờ Cờ, Tokuda vào trước Thảo 2 ngày
Một ngày nọ, Thảo đang code ở nhánh auth nhưng cũng hóng hớt checkout qua nhánh user của Tokuda để xem Tokuda code tới đâu rồi vì nhánh của Thảo có phụ thuộc vào nhánh của Tokuda
Thảo nhập lệnh git checkout user, BÙM, không checkout qua được và lỗi này xuất hiện error: Your local changes to the following files would be overwritten by checkout: auth.js Please commit your changes or stash them before you switch branches. Aborting
Thảo khó hiểu, Thảo bèn quay sang hỏi Tokuda vì Tokuda làm trước Thảo 2 ngày nên nghĩ rằng Tokuda sẽ biết cách xử lý
Tokuda nhìn vào lỗi và phán rằng: "Chắc lỗi gì rồi, thử xóa hết code xem sao". Anh Leader kế bên giật bắn người, thế là đành quay qua giải quyết cho 2 đứa chưa trải sự đời này
Anh Leader nói: "Thảo không thể checkout qua nhánh khác là do Thảo đang code dở tay ở nhánh hiện tại, để Thảo có thể checkout qua nhánh khác thì cần phải commit code trước"
Thảo đáp rằng: "Em chưa muốn commit code vì chưa code xong ạ"
Anh Leader nói tiếp: "OK em. vậy dùng cho anh git stash nhé"
git stash
giúp cất giữ code tạm thời và sau đó khi quay lại dev tiếp thì sử dụng git stash pop
9. Khôi phục trạng thái trước khi merge
Ai cũng sẽ có sai lầm và anh Leader cũng vậy
Anh Leader có giao cho Tokuda một task và sau khi Tokuda làm xong thì anh Leader merge vào nhánh dev
Sau khi merge thì anh Leader phát hiện code không hoạt động như ý muốn. Thế là anh Leader dùng lệnh: git reset --hard ORIG_HEAD
để xóa các commit vừa merge và nói Tokuda chỉnh sửa lại code
10. Merge một commit bất kỳ vào nhánh khác
Thảo được giao làm task là quản lý product
Thảo hoàn thành tính năng create product, Thảo commit
Thảo hoàn thành tính năng view product, Thảo commit
Thảo hoàn thành tính năng update product, Thảo commit
Thảo đang làm tính năng delete product, Thảo chưa commit ...
Lúc này khách hàng alo cho anh Leader: "Chú release tính năng create product và view product gấp cho anh nhé"
Anh Leader quá quen với việc khách hàng yêu cầu bất ngờ rồi, anh Leader liền dùng lệnh git cherry-pick <commit>
để merge 2 commit đó vào nhánh main để release cho khách hàng
git cherry-pick
là một lệnh git hữu ích dùng cho trường hợp muốn merge commit bất kỳ vào nhánh khác thay vì toàn bộ branch (trong trường hợp git cherry-pick
bị conflict, dùng lệnh git add .
và git commit -m "message"
để xử lý)
11. Tổng kết
Như vậy, chúng ta đã khám phá 10 tình huống thường gặp trong Git. Hy vọng rằng bài viết đã mang lại giá trị cho bạn và giúp bạn hiểu sâu hơn về git. Ngoài ra, mình có bài viết Tổng hợp 15 lệnh git hữu ích dành cho dự án của bạn, các bạn có thể đọc để biết thêm git. Cảm ơn các bạn đã đọc