+30

10 tình huống thường gặp trong Git

Năm mới xuân sang, chúc anh em thật nhiều sức khoẻ, miệng cười vui vẻ, tiền vào mạnh mẽ, công việc suôn sẻ, cuộc đời đẹp đẽ, sự nghiệp lên hương, thật nhiều người thương, may mắn đủ đường. Happy New Year 🎆🎆🎆

Tình huống 1: xử lý conflict

Trong quá trình làm việc trong một team, conflict code là điều không thể tránh khỏi, thường xảy ra khi 2 member làm task trên cùng một module. Hãy cùng xem conflict xuất hiện khi nào và cách giải quyết như thế nào nhé

Ban đầu, trên nhánh dev, Tèo và Tí checkout 2 nhánh khác nhau, Tèo checkout nhánh là create-user, Tí checkout nhánh là view-user, và sau đó Tèo và Tí cùng chỉnh sửa dòng thứ nhất trên file là user.js

Tiếp theo, Tèo merge nhánh create-user vào nhánh dev, lúc này mọi chuyện vẫn ổn cho tới khi Tí merge nhánh view-user vào nhánh dev. BÙM. Không thể merge được và xuất hiện lỗi CONFLICT (content): Merge conflict in user.js

Cách giải quyết vấn đề này là nhánh bị conflict của ai thì người đó xử lý, ở đây là nhánh của Tí, Tí cần phải trao đổi với những members có liên quan đến chỗ code conflict và thực hiện các bước sau:

1. Xác định code bị conflict:

Sử dụng git status để tìm các file bị conflict

Trong user.js file, bạn sẽ thấy nội dung như sau:

<<<<<<< HEAD
code of Tèo
======= 
code of Tí
>>>>>>> view-user

2. Giải quyết conflict:

Trao đổi với Tèo, xác định xem muốn giữ code từ branch nào hoặc muốn kết hợp cả hai và sau đó loại bỏ dấu <<<<<<<, =======, và >>>>>>>

Sử dụng lệnh git add user.jsgit commit để hoàn tất quá trình merge

3. Kiểm tra lại và push lên remote:

Check lại đã xử lý conflict ok chưa bằng cách dùng git status

Sau đó, sử dụng git push để đẩy những thay đổi đã merge lên remote

Chú ý: Để hạn chế conflict code bạn cần thường xuyên pull code và commit code

Tình huống 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

commit 7a2cbffba6023df7f37dd1808f46d5a6b59d810b
Author: teo <teo@gmail.com>
Date:   Fri Feb 11 10:05:00 2024 +0700

    Create log

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ư Tèo vừa checkout qua nhánh master, hay là Tí 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)

2de6d93 (view-user) HEAD@{11}: checkout: moving from view_user to master
6303151 (create-user) HEAD@{12}: reset: moving to HEAD@{3}

Tình huống 3: xóa commit

Một ngày dài miệt mài làm task, cuối cùng Tèo đã làm xong task, Tèo commit code và đi ngủ

Hôm sau Tèo mở lại code và thấy code của mình không ổn tẹo nào, Tèo cần xóa hết code hoặc cần chỉnh sửa lại code. Tèo có thể sử dụng git reset hoặc git revert để giải quyết vấn đề này (ở đây mình giới thiệu git reset)

Git reset có vài option như mixed(mặc định khi không truyền option), --soft--hard

  • git reset <commit>: giữ lại các thay đổi đã commit trong staging
  • git reset --soft <commit>: giữ lại các thay đổi trong working directory
  • git reset --hard <commit>: loại bỏ tất cả thay đổi, cả trong working directory và staging

Tình huống 4: khôi phục commit

Như ở tình huống 3, Tèo muốn reset commit để chỉnh sửa code thôi nhưng Tèo lại lỡ dùng --hard khiến cho code bị bay màu hết, Tèo lúng tung cầu cứu anh Leader, anh Leader đã hướng dẫn Tèo lấy lại code với các thao tác như sau:

  1. Sử dụng git reflog để lấy hash commit:
627f5d1 (HEAD -> master, conflict-2) HEAD@{0}: reset: moving to 627f5d161bff441840d5b34a77abe16561f505f8
ec02ce2 HEAD@{1}: reset: moving to HEAD@{1}
  1. Sử dụng git reset --hard để khôi phục commit:
git reset --hard ec02ce2

Tèo vui mừng hò reo cảm ơn anh Leader ríu rít

Tình huống 5: gộp nhiều commit lại thành 1 commit

Tí được giao một nhiệm vụ là quản lý users bao gồm CRUD. Tí nghe lời dặn của anh Leader là "code phải commit code liên tục nha em"

Tí tạo file userRouter, Tí commit

Tí tạo tiếp file userController, Tí commit tiếp

Tí tạo file userService, Tí lại tiếp tục commit

Tí 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"

Tí 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 Tí gộp commit, thao tác như sau:

  1. Sử dụng git rebase
git rebase -i HEAD^n
(n là số commit muốn gộp)
  1. 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
  2. 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

Tình huống 6: chỉnh sửa message commit

Một lần Tí commit nhầm message và Tí chỉnh sửa lại được message đó. Tí vui lắm, Tí 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 Tí nên copy paste vào đây. Cách xử lý của Tí 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:

  1. Sử dụng git rebase -i HEAD~n (n là số commit muốn đổi message)
  2. 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
  3. 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

Tình huống 7: đổi tên branch

Lại một lần khác, Tí đặt nhầm tên nhánh và Tí chỉnh sửa lại được tên branch đó. Tí vui lắm, Tí 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 Tí nên copy paste vào đây. Cách xử lý của Tí như sau:

Nếu đặt sai tên nhánh, vui lòng nhập lệnh sau: git branch -m new_branch

Tình huống 8: không thể checkout qua nhánh khác

Tí và Tèo là hai bạn thực tập sinh của công ty A Bờ Cờ, Tí vào trước Tèo 2 ngày

Một ngày nọ, Tèo đang code ở nhánh auth nhưng cũng hóng hớt checkout qua nhánh user của Tí để xem Tí code tới đâu rồi vì nhánh của Tèo có phụ thuộc vào nhánh của Tí

Tè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

Tèo khó hiểu, Tèo bèn quay sang hỏi Tí vì Tí làm trước Tèo 2 ngày nên nghĩ rằng Tí sẽ biết cách xử lý

Tí 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: "Tèo không thể checkout qua nhánh khác là do Tèo đang code dở tay ở nhánh hiện tại, để Tèo có thể checkout qua nhánh khác thì cần phải commit code trước"

Tè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

Tình huống 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 Tí một task và sau khi Tí 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 Tí chỉnh sửa lại code

Tình huống 10: merge một commit bất kỳ vào nhánh khác

Tèo được giao làm task là quản lý product

Tèo hoàn thành tính năng create product, Tèo commit

Tèo hoàn thành tính năng view product, Tèo commit

Tèo hoàn thành tính năng update product, Tèo commit

Tèo đang làm tính năng delete product, Tè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 (git cherry-pick thường bị conflict, dùng lệnh git add .git commit -m “message” là xử lý được)

Kết bài

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


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.