Trong quá trình làm việc với Git, nếu bạn đã từng gặp những sự cố đòi hỏi cần những bước xử lý phức tạp để khắc phục, thì đây chính là lúc các kỹ thuật Git nâng cao phát huy tác dụng.
Đọc bài viết này để hiểu rõ hơn về các kỹ thuật Git nâng cao như:
- Cách sử dụng Git stash, git cherry-pick
- Chỉnh sửa commit trong lịch sử
- Tìm kiếm thông tin trong reppository
- Quản lý lịch sử bằng git log, git reflog
- Điều tra lỗi bằng git bisect
Lưu trữ tạm thời các thay đổi với Git stash
Git stash là một công cụ mạnh mẽ trong Git, cho phép tạm thời lưu trữ các thay đổi chưa được commit hiện có trong Working Directory và Staging Index, từ đó trả lại trạng thái ban đầu cho khu vực làm việc. Điều này giúp việc chuyển đổi trạng thái làm việc hoặc xử lý công việc khác mà không gây xung đột, mất dữ liệu.
Cách Git stash hoạt động
Khi chạy câu lệnh “git stash”, bạn có thể:
- Lưu trữ trạng thái làm việc hiện tại, bao gồm:
- Các thay đổi chưa được staged.
- Các thay đổi đã staged.
- Xóa các thay đổi đó khỏi working directory, đưa nó về trạng thái “clean” (giống như sau khi checkout branch mới).
Lưu ý, những tập tin mới (chưa được theo dõi bởi Git) và những thay đổi ở tập tin có trong .gitignore sẽ không được xử lý.
Sau khi hoàn thành các công việc khác, bạn có thể reapply (áp dụng lại) hoặc xóa bỏ stash.
Các thao tác về stash
Thực hiện lưu tạm thời các thay đổi
git stash
Mục đích:
- Lưu tất cả các thay đổi được theo dõi (staged và unstaged).
- Không bao gồm tập tin chưa được theo dõi hoặc bị ignore.
Xem danh sách các stash
git stash list
Lệnh này sẽ hiển thị danh sách các stash đã lưu trước đó:
Áp dụng lại stash và xóa stash
git stash pop
Áp dụng lại stash nhưng vẫn giữ lại stash
git stash apply
Xóa tất cả stash
git stash clear
Thay đổi có chọn lọc với Git cherry-pick
Git cherry-pick là lệnh dùng để áp dụng một hoặc nhiều commit cụ thể từ một nhánh khác vào nhánh hiện tại (sao chép commits). Điều này rất hữu ích khi bạn chỉ muốn chọn lọc một số thay đổi nhất định mà không muốn hợp nhất toàn bộ nhánh.
Cú pháp cơ bản:
git cherry-pick <commit hash>
Ví dụ, ta có nhánh feat/sample-2 đang có hai commit mới là “commit 2” và “commit 3”, và nhánh feat/sample-1:
Nếu sử dụng hợp nhất (git merge hoặc git rebase), thì sẽ áp dụng toàn bộ các commits từ feat/sample-2 vào feat/sample-1. Nhưng trong trường hợp bạn chỉ đang muốn áp dụng commit 2 cho nhánh feat/sample-1, thì bạn có thể sử dụng cherry-pick:
git checkout feat/sample-1 # đảm bảo đang đứng tại nhánh feat/sample-1 git cherry-pick 545b48e
Lúc này, Git sẽ thực hiện sao chép của commit 2 và áp dụng commit vào nhánh feat/sample-1. Nhưng vì đây là một hành động sao chép nên mặc dù trông có vẻ giống nhau, tuy nhiên đây vẫn là 2 commit riêng biệt và có thông tin commit-hash khác nhau:
Trường hợp để áp dụng cùng lúc nhiều commits, bạn có thể thực hiện liệt kê cụ thể từng commits theo cú pháp sau:
git cherry-pick <commit hash 1> <commit hash 2>
Hoặc theo phạm vi:
git cherry-pick <commit hash A>..<commit hash B>
Điều này sẽ cherry-pick tất cả commit từ A đến B (Lưu ý: Commit B sẽ được bao gồm, nhưng commit A thì không).
Các kỹ thuật Git nâng cao dùng để chỉnh sửa lịch sử commit
Trong quá trình làm việc với Git, sẽ có nhiều tình huống xảy ra không mong muốn đối với các commit như:
- Thông điệp commit có nội dung sai chính tả
- Commit bị thiếu tập tin có liên quan
- Có nhiều commit nhỏ lẻ tẻ, dư thừa
Lúc này, bạn có thể áp dụng một số biện pháp dưới đây để thao tác với lịch sử commit.
git commit –amend
Lệnh git commit –amend được sử dụng để chỉnh sửa commit gần nhất trong Git. Bạn có thể sử dụng nó để thay đổi thông điệp commit, thêm hoặc loại bỏ tập tin trong commit, thậm chí là sửa lỗi commit trước đó mà không cần tạo thêm commit mới.
Cú pháp cơ bản:
git commit --amend
Các trường hợp sử dụng git commit –amend
Chỉnh sửa thông điệp của commit
Cú pháp:
git commit --amend -m "thông điệp mới"
Git sẽ tự động thay thế thông điệp mới cho commit mới nhất ở nhánh hiện tại.
Bổ sung thêm tập tin
Ví dụ trong trường hợp bạn đã thực hiện commit nhưng phát hiện còn sót lại tập tin cần bổ sung:
Bước 1: Thêm tập tin vào staging area
git add <file>
Bước 2: Thực hiện sửa commit
git commit --amend
Lúc này tập tin sẽ được thêm vào commit gần nhất và không cần tạo thêm commit mới.
Xóa bỏ tập tin không cần thiết
Ví dụ trong trường hợp bạn đã vô tình đưa tập tin không mong muốn vào commit:
Bước 1: Chuyển tập tin về trạng thái trước đó
git reset HEAD~ -- <file>
Bước 2: Thực hiện sửa commit
git commit --amend
Lúc này thay đổi của tập tin sẽ được xóa khỏi commit gần nhất và đưa trở lại khu vực làm việc.
Lưu ý: Git commit –amend chỉ nên được thực hiện đối với các commit vẫn đang ở kho lưu trữ cục bộ và chưa được đẩy lên remote repository.
Điều này giúp hạn chế xảy ra xung đột mã nguồn khi làm việc với nhiều người.
Interactive rebase
Đây là một chức năng mạnh mẽ cung cấp nhiều tùy chọn linh hoạt để chỉnh sửa lịch sử commit. Những chức năng chính của nó bao gồm:
- Thay đổi thứ tự commit
- Thay đổi nội dung hoặc thông điệp commit
- Gộp commit (squash)
- Xóa commit không mong muốn
Cú pháp
git rebase -i <base>
Trong đó, <base> là phạm vi commit cần được thao tác:
- – HEAD~n: bắt đầu từ commit đứng trước n commit gần nhất và thao tác trên n commit gần nhất.
- – <commit-hash>: bắt đầu từ commit ngay sau commit có hash này và thao tác trên tất cả các commit từ đó đến HEAD.
Các trường hợp sử dụng Interactive rebase
Để làm rõ các công dụng của Interactive rebase, chúng ta hãy cùng xem qua ví dụ sau:
Giả sử ta có nhánh develop với các commit như sau:
07ce17d (HEAD -> develop) commit 4 8d01940 commit 3 545b48e commit 2 d400fbb commit 1
Thay đổi thứ tự các commit
Bước 1: Ví dụ để đổi chỗ vị trí của commit 2 và commit 3, ta thực hiện lệnh:
git rebase -i d400fbb
Trong đó, d400fbb là hash của commit 1 (Git sẽ thực hiện rebase cho commit đứng liền sau nó là commit 2 đến HEAD). Lúc này, Git sẽ mở trình soạn thảo hiển thị danh sách commit:
pick 545b48e commit 2 pick 8d01940 commit 3 pick 07ce17d commit 4
Bước 2: Thực hiện đổi chỗ cho commit 2 và commit 3:
pick 8d01940 commit 3 pick 545b48e commit 2 pick 07ce17d commit 4
Bước 3: Lưu và thoát.
Git sẽ viết lại lịch sử commit theo thứ tự mới được chỉ định (commit hash của những commit trong phạm vi rebase sẽ được thay giá trị mới).
34370aa (HEAD -> develop) commit 4 0f41ced commit 2 975844f commit 3 d400fbb commit 1
Thay đổi nội dung commit
Bước 1: Ví dụ để đổi tên “commit 2” thành “commit 2 new”, ta thực hiện rebase -i với commit hash là commit 3 (bởi vì bây giờ commit 3 đứng ngay trước commit 2):
git rebase -i 975844f
Lúc này, Git sẽ mở trình soạn thảo hiển thị danh sách commit:
pick 0f41ced commit 2 pick 34370aa commit 4
Bước 2: Thực hiện đổi tên cho commit 2 bằng cách thay chữ “pick” thành chữ “reword”:
reword 0f41ced commit 2 pick 34370aa commit 4
Bước 3: Lưu và thoát, Git sẽ tự động mở tiếp 1 trình soạn thảo để bạn có thể chỉnh sửa thông điệp cho commit 2 thành “commit 2 new”.
Bước 4: Lưu và thoát, lịch sử commit mới sẽ có dạng:
aabb0ad (HEAD -> develop) commit 4 c785d8d commit 2 new 975844f commit 3 d400fbb commit 1
Gộp commit
Bây giờ, nếu chúng ta muốn gộp hai commit 2 và 3 thành 1 commit mới, để giảm bớt số lượng commit, ta có thể làm theo các bước sau:
Bước 1: Thực hiện rebase -i với commit hash là commit 1
git rebase -i d400fbb
Bước 2: Thay chữ “pick” ở trước commit 2 thành chữ “squash”
pick 975844f commit 3 squash c785d8d commit 2 new pick aabb0ad commit 4
Bước 3: Lưu và thoát. Git sẽ thực hiện gộp commit 2 với commit trước nó là commit 3, sau đó sẽ tự động mở trình soạn thảo để bạn bổ sung thông điệp cho commit mới
Bước 4: Sau khi thêm thông điệp và thoát, lịch sử commit mới sẽ có dạng:
4698cd8 (HEAD -> develop) commit 4 16acfbf squash commit 2 & 3 d400fbb commit 1
Xóa commit
Ví dụ bây giờ bạn phát hiện nội dung của commit 1 không đúng và muốn loại bỏ nó, bạn có thể thực hiện theo bước sau:
Bước 1: Bởi vì commit 1 là commit đầu tiên, nên để chỉ định vị trí trước commit 1, bạn có thể sử dụng cú pháp sau:
git rebase -i --root
Bước 2: Thay chữ “pick” ở trước commit 1 thành chữ “drop”
drop d400fbb commit 1 pick 16acfbf commit 3 pick 4698cd8 commit 4
Bước 3: Lưu và thoát. Git sẽ tự động loại bỏ commit 1
Lưu ý: Chỉ nên sử dụng Interactive rebase đối với những dữ liệu chưa được đẩy lên remote repository để tránh xảy ra xung đột với những người cộng tác khác.
Các kỹ thuật Git nâng cao dùng để tìm kiếm trong repository
Để tìm kiếm trong Git, bạn có thể sử dụng nhiều lệnh khác nhau, tùy thuộc vào nội dung bạn muốn tìm kiếm. Dưới đây là các cách tìm kiếm phổ biến trong Git:
Tìm kiếm nội dung bằng Git grep
Git grep là một câu lệnh trong Git dùng để tìm kiếm một nội dung cụ thể trong toàn bộ kho lưu trữ hoặc trong các tập tin đã được theo dõi (tracked) bởi Git.
Cách sử dụng:
git grep "keyword"
Ví dụ: Để tìm kiếm những tập tin có chứa từ “hello”:
git grep "hello"
Lúc này, git sẽ tìm kiếm tất cả tập tin trong repository và trả về kết quả:
Một số tùy chọn bổ sung:
Hiển thị số dòng
git grep -n "TODO"
Giới hạn phạm vi tìm kiếm
git grep "TODO" -- <đường dẫn tập tin>
Tìm kiếm trong lịch sử commit
Git log cung cấp một số tùy chọn để có thể tìm kiếm commit nào có chứa nội dung, thông điệp, hoặc thay đổi liên quan đến từ khóa.
Tìm commit có thông điệp chứa từ khóa
git log --grep="từ khóa"
Git sẽ trả về danh sách các commit mà nội dung thông điệp chứa từ khóa được chỉ định.
Tìm commit có nội dung thay đổi chứa từ khóa
git log -S "nội dung cần tìm"
Git sẽ trả về danh sách các commit có thêm hoặc xóa đoạn nội dung chứa thông tin cần tìm. Ngoài ra, Git log còn có nhiều công dụng khác, bạn có thể tham khảo thêm ở mục tiếp theo đây.
Xem lịch sử commit với Git log
Lệnh git log trong Git được sử dụng để xem lịch sử commit của một repository. Đây là một công cụ mạnh mẽ giúp bạn theo dõi các thay đổi, xem thông tin chi tiết về commit, và tìm hiểu ai đã thực hiện các thay đổi gì trong repository.
Cú pháp cơ bản:
git log <tùy chọn>
Theo mặc định nếu không chỉ định tùy chọn, Git sẽ trả về danh sách thông tin các commit trong lịch sử.
Dựa vào kết quả trả về, chúng ta có thể xem được lịch sử commit bao gồm những commit nào, thứ tự các commit và những thông tin cơ bản (commit hash, message, author,..).
Một số tùy chọn phổ biến:
Hiển thị log dưới dạng rút gọn
git log --oneline
Ví dụ về kết quả trả về:
Lọc commit dựa trên điều kiện
Lọc theo tác giả:
git log --author="tên tác giả"
Lọc theo ngày tháng tạo commit:
git log --since="2024-12-01" --until="2024-12-31"
Lọc theo nội dung thông điệp commit:
git log --grep="fix bug"
Hiển thị commit liên quan đến tập tin cụ thể:
git log -- <tên tập tin>
So sánh giữa các nguồn với Git diff
Git diff là một lệnh Git đa dụng, khi được thực thi sẽ chạy chức năng diff trên các nguồn dữ liệu Git (commit, nhánh, tập tin,..) và trả về kết quả khác biệt giữa hai nguồn.
Lệnh git diff thường được sử dụng cùng với git status và git log để phân tích trạng thái hiện tại của một repo Git.
Cú pháp chung:
git diff [tùy chọn] [phạm vi]
Trong đó:
- [tùy chọn]: Các tùy chọn điều chỉnh cách hiển thị kết quả của git diff hoặc giới hạn phạm vi so sánh
- [phạm vi]: xác định các trạng thái mà bạn muốn so sánh trong repository
Một số trường hợp sử dụng:
So sánh những thay đổi ở khu vực làm việc và chưa được đưa vào staging area
Đây là hành vi mặc định khi sử dụng git diff, chức năng của nó là cho thấy sự khác biệt giữa trạng thái hiện tại trong working directory và staging index (nếu staging index không có nội dung thì sẽ so sánh với kho lưu trữ)
git diff
Ví dụ về output:
So sánh thay đổi trong một tập tin cụ thể
So sánh nội dung thay đổi giữa hai commit
Dùng để kiểm tra những thay đổi đã được thực hiện giữa hai điểm thời gian cụ thể của hai commit bất kì. Cú pháp:
git diff <commit-hash-1> <commit-hash-2>
Ví dụ:
So sánh giữa một commit và working directory
Mục đích để so sánh trạng thái của commit với các thay đổi hiện tại trong working directory. Cú pháp:
git diff <commit hash>
Ví dụ, khi chúng ta chỉnh sửa tập tin xyz.txt, git sẽ so sánh sự khác biệt của tập tin này ở commit chỉ định và thư mục làm việc hiện tại:
So sánh giữa hai nhánh
Trong quá trình làm việc trên nhiều nhánh, bạn có thể sẽ cần kiểm tra sự thay đổi giữa nhánh này và nhánh kia, trước khi thực hiện các hành động như hợp nhất. Điều này giúp đảm bảo nội dung hợp nhất sẽ luôn được kiểm duyệt, tránh phát sinh lỗi.
Cú pháp so sánh:
git diff <tên nhánh 1> <tên nhánh 2>
Khôi phục nhánh, commit bằng Git reflog
Git reflog là một tệp nhật ký tham chiếu (reference log) lưu trữ danh sách theo thứ tự thời gian của tất cả các thay đổi đã được thực hiện đối với con trỏ HEAD trong repository Git của bạn. HEAD luôn trỏ đến commit mới nhất, và reflog về cơ bản theo dõi mọi commit trước đây từng tồn tại trong repository.
Reflog không phải là một phần của chính repository (nó được lưu trữ riêng biệt với các commit) và không được bao gồm trong các thao tác push, fetch hoặc clone; nó hoàn toàn là dữ liệu cục bộ. Điều này cực kỳ hữu ích khi bạn:
- Vô tình commit thứ gì đó không nên commit.
- Xóa nhầm một commit hoặc một nhánh.
- Cần nhớ lại những gì đã xảy ra với một tham chiếu cụ thể tại một thời điểm nào đó.
Cú pháp chính:
git reflog
Ví dụ về output:
abc1234 HEAD@{0}: reset: moving to HEAD~1 def5678 HEAD@{1}: commit: Update README 456abcd HEAD@{2}: checkout: moving from feature to main 7890123 HEAD@{3}: commit: Add new feature
Trong đó:
- abc1234: mã hash tham chiếu của hành động
- HEAD@{0}: Vị trí của hành động đã diễn ra (với 0 là hành động gần nhất)
- reset: moving to HEAD~1: mô tả hành động đã diễn ra
Một số trường hợp sử dụng Git reflog
Hoàn tác hành động reset –hard hoặc hợp nhất
Ví dụ trong trường hợp bạn vô tình sử dụng lệnh git reset –hard, dẫn đến làm mất những commit quan trọng hay bạn đã thực hiện hợp nhất nhưng đã có lỗi và bạn muốn quay lại, bạn có thể sử dụng git reflog để khắc phục điều này bằng cách:
Bước 1: Mở lịch sử hành động bằng git reflog
git reflog
Bước 2: Tìm đến vị trí ngay trước vị trí của hành động reset
abc1234 HEAD@{0}: reset: moving to HEAD~1 def5678 HEAD@{1}: commit: Update README 456abcd HEAD@{2}: checkout: moving from feature to main 7890123 HEAD@{3}: commit: Add new feature
Nhìn vào lịch sử ta thấy được HEAD@{1} sẽ là vị trí ngay trước hành động reset gây mất commit.
Bước 3: Thực thi lệnh reset để quay trở lại trạng thái trước khi reset
git reset --hard HEAD@{1}
Lưu ý: Điều này sẽ ghi đè tất cả các thay đổi hiện tại và đưa lịch sử commit quay về trạng thái trước khi thực hiện hành động HEAD@{0}.
Khôi phục commit đã bị mất
Trong trường hợp bạn chỉ muốn lấy lại một commit cụ thể, thay vì phải hoàn tác toàn bộ thay đổi trước đó như ở trường hợp 1, bạn có thể sử dụng theo các bước sau:
Bước 1: Tìm tới vị trí thực hiện commit trong reflog
abc1234 HEAD@{0}: reset: moving to HEAD~5 def5678 HEAD@{1}: commit: Update README 456abcd HEAD@{2}: checkout: moving from feature to main 7890123 HEAD@{3}: commit: Add new feature
Ví dụ trong trường hợp này, git reset đã xóa bỏ commit ở HEAD{1} và HEAD{3}, và bây giờ bạn chỉ muốn lấy lại commit ở HEAD@{3}
Bước 2: Sử dụng switch hoặc checkout để truy cập vào commit đó
git switch <vị trí commit>
Lúc này con trỏ HEAD sẽ chuyển đến vị trí của commit này, và bạn có thể tạo một nhánh mới với lịch sử có chứa commit đó.
Bước 3: Tách ra một nhánh mới chứa commit cần được khôi phục
git switch -c <tên nhánh>
Khôi phục nhánh bị xóa
Khi một nhánh bị xóa, commit cuối cùng của nhánh vẫn được lưu trong git reflog. Để khôi phục lại nhánh, bạn có thể làm như sau:
- Mở git reflog và tìm đến vị trí commit cuối cùng của nhánh
- Sử dụng switch hoặc checkout để tách ra một nhánh mới với lịch sử đó
git switch -c <tên nhánh> <vị trí commit>
Điều tra lỗi bằng Git bisect
Lệnh git bisect trong Git giúp bạn tìm ra commit chính xác gây ra lỗi trong một repository. Với việc sử dụng thuật toán tìm kiếm nhị phân để kiểm tra các commit, git bisect giúp tiết kiệm thời gian so với việc kiểm tra từng commit thủ công.
Cú pháp cơ bản:
git bisect <action>
Cách sử dụng:
Bước 1: Bắt đầu git bisect
git bisect start
Bước 2: Đánh dấu commit lỗi (Theo mặc định thì commit mới nhất sẽ có lỗi)
git bisect bad
Bước 3: Đánh dấu commit tốt (xác định vị trí commit mà bạn biết chắc rằng nó vẫn hoạt động tốt)
git bisect good <commit-hash>
Bước 4: Kiểm tra từng commit: Git sẽ chuyển HEAD đến commit giữa. Kiểm tra xem lỗi có xảy ra không:
- Nếu thấy có lỗi hệ thống:
git bisect bad
- Nếu không có lỗi:
git bisect good
Lặp lại bước này cho đến khi Git xác định commit duy nhất là bad.
Bước 5: Kết thúc bisect
git bisect reset
Giả sử ta có một nhánh tính năng với các commit như sau:
Trong đó commit 6 đã có lỗi, tuy nhiên đến khi commit 7 chúng ta mới phát hiện hệ thống gặp lỗi, và bây giờ cần điều tra xem nó đã bị lỗi ở đâu và từ khi nào.
- Thực hiện git bisect với bắt đầu là commit 7 bad và commit 1 good
- Git sẽ xác định từng commit ở giữa phạm vi này theo thuật toán nhị phân
- Bạn sẽ xác định tại vị trí commit đó, hệ thống còn có lỗi hay không, nếu có lỗi thì báo bisect bad, nếu không có lỗi báo bisect good
- Lặp lại điều này cho đến khi xác định được duy nhất commit gây lỗi
Kết hợp thay đổi với Git rebase và Git merge
Git rebase và Git merge đều được sử dụng để kết hợp thay đổi từ hai nhánh trong Git. Tuy nhiên, chúng hoạt động khác nhau và có các tình huống sử dụng riêng biệt. Việc lựa chọn sử dụng cái nào còn phụ thuộc vào nhu cầu cụ thể trong dự án.
Dưới đây là bản so sánh tóm tắt sự khác biệt giữa 2 kỹ thuật này:
Tiêu chí | Git merge | Git rebase |
Cú pháp | git merge <tên nhánh> | git rebase <tên nhánh> |
Cách hoạt động | Tạo một merge commit để kết hợp hai nhánh | Tái tạo commit của nhánh cần hợp nhất trên nhánh đích |
Lịch sử commit | Không làm xáo trộn lịch sử, chỉ bổ sung thêm commit merge (nếu có) | Sắp xếp lại lịch sử commit, đưa các commit của nhánh hiện tại lên đầu của nhánh mục tiêu. Lịch sử commit trở nên tuyến tính |
Merge commit | Có thể tạo ra commit merge (khi thực hiện Three-way merge) | Không tạo ra commit merge |
Xử lý xung đột | Xử lý xung đột một lần duy nhất trong quá trình merge | Có thể cần xử lý xung đột nhiều lần đối với từng commit khi rebase |
Trường hợp sử dụng |
|
|
Đọc thêm:
- Git rebase: Hướng dẫn sử dụng từ cơ bản đến nâng cao
- Git Merge: Hướng dẫn chi tiết cách sử dụng Git Merge
Perfect commit
Commit là thành phần quan trọng cấu tạo nên một hệ thống Git. Mỗi commit ghi lại một trạng thái cụ thể của mã nguồn, đóng vai trò như một cột mốc trong lịch sử phát triển của dự án.
Một commit chất lượng không chỉ phản ánh chính xác những thay đổi mà còn giúp người khác (hoặc chính bạn trong tương lai) dễ dàng hiểu được mục đích và nguyên nhân của các thay đổi đó.
Để đạt được những commit chất lượng (perfect commit), bạn cần đáp ứng những yếu tố sau:
- Xây dựng commit nguyên tử (Atomic commit): Hãy đảm bảo commit chỉ nên bao gồm thay đổi về một mục đích cụ thể (one logical change), tránh gộp nhiều thay đổi không liên quan vào cùng một commit. Ví dụ:
- Tốt: Commit thêm tính năng mới hoặc sửa lỗi trong một module cụ thể.
- Không tốt: Vừa thêm tính năng, vừa sửa lỗi và vừa refactor code.
- Đặt thông điệp commit rõ ràng: Nội dung thông điệp của commit phải rõ ràng, mô tả được cái gì đã thay đổi và tại sao lại thay đổi. Tuy nhiên tránh ghi nội dung quá dài dòng. Ví dụ: git commit -m “fix search issue with username”
- Không chứa code dư thừa: Commit không nên bao gồm các thông tin code không cần thiết như những đoạn code thử nghiệm trong thời điểm phát triển, ghi chú tạm thời, không còn giá trị. Điều này giúp nội dung commit được tinh gọn, giảm số lượng mã xấu, và giúp quá trình bảo trì được dễ dàng.
- Kiểm tra kỹ các thay đổi trước khi commit: Sử dụng các công cụ có sẵn như git diff, git status để kiểm tra kỹ lưỡng nội dung thay đổi. Tránh mã code chứa các lỗi cú pháp, lỗi chính tả không đáng có.
Quy trình tạo Perfect Commit:
Bước 1: Kiểm tra trạng thái hiện tại của mã nguồn:
git status
Bước 2: Thêm các tập tin thay đổi vào staging index:
git add -p <tập tin>
Chúng ta có thể sử dụng tùy chọn -p của git add để có thể lựa chọn từng phần thay đổi trong cùng một tập tin, từ đó dễ dàng chia tách các nội dung thay đổi không liên quan đến nhau.
Bước 3: Kiểm tra lại các thay đổi đã thêm vào staging index:
git diff --staged
Bước 4: Tạo commit với thông điệp rõ ràng:
git commit -m "thông điệp"
Các câu hỏi thường gặp về các kỹ thuật Git nâng cao
git stash có lưu các file chưa được theo dõi không?
Theo mặc định, git stash sẽ loại trừ những file thêm mới, chưa được theo dõi và những file được khai báo trong .gitignore. Tuy nhiên bạn có thể sử dụng tùy chọn -u để bao gồm cả những file chưa được theo dõi (untracked):
git stash -u
git cherry-pick khác gì với git merge?
git cherry-pick chỉ sao chép một hoặc nhiều commit cụ thể từ một nhánh sang nhánh khác (không thực hiện hành động hợp nhất và không tạo ra commit merge), trong khi git merge hợp nhất toàn bộ lịch sử của nhánh nguồn vào nhánh hiện tại.
Điều gì xảy ra nếu chỉnh sửa commit đã đẩy lên remote?
Khi một commit được chỉnh sửa, commit hash của nó sẽ được đặt lại, điều này khiến bạn bắt buộc phải sử dụng “git push –force” để đẩy nội dung thay đổi lên remote nếu trước đó commit đã được đẩy lên. Điều này dẫn đến rủi ro mất dữ liệu cho remote repository.
Ngoài ra, việc thay đổi một commit đã có trên remote, có thể dẫn đến xung đội mã nguồn với các thành viên khác trong dự án. Vì vậy chỉ nên chỉnh sửa commit khi nó vẫn đang ở local repository.
Có thể lọc commit của một tác giả cụ thể không?
Bạn có thể lọc lại những commit của một tác giả cụ thể bằng việc sử dụng tùy chọn –author. Ví dụ để tìm kiếm những commit của tác giả có tên “John”:
git log --author="John"
Tổng kết Git nâng cao
Git là một công cụ mạnh mẽ trong quản lý mã nguồn, và việc nắm vững các kỹ thuật Git nâng cao sẽ giúp bạn tối ưu hóa được quy trình làm việc và dễ dàng xử lý các tình huống phức tạp có thể xảy ra trong dự án. Qua bài viết này, ITViec hi vọng đã mang đến cho bạn đọc những thông tin bổ ích về các câu lệnh, kỹ thuật Git nâng cao, từ đó giúp bạn nâng cao được kỹ năng làm việc với git và có những bước tiến mới trong công việc.