🌱 Một số kỹ thuật Git nâng cao: Git Stash, Git Rebase, Git Cherry-Pick, Git Reset
Git là một công cụ quản lý phiên bản phân tán giúp theo dõi và kiểm soát sự thay đổi của mã nguồn. Nó đặc biệt quan trọng trong các dự án lớn, giúp nhiều lập trình viên làm việc cùng nhau một cách hiệu quả.
➤ Giới thiệu về Git / Github và các khái niệm cơ bản về Git
Bài viết này tiếp tục giới thiệu về một số kỹ thuật Git nâng cao như Git Stash, Git Rebase, Git Cherry-Pick, Git Reset và cách sử dụng chúng trong dự án thực tế.
Table of Contents
Git Stash - Temporarily Save Changes
Khi làm việc với Git, có những lúc bạn cần lưu tạm thời các thay đổi để chuyển sang một nhánh khác hoặc thực hiện một nhiệm vụ khác mà không muốn commit. Lệnh git stash
giúp bạn làm điều này.
Git stash cho phép lưu trữ các thay đổi trên repository tạm thời theo cơ chế giống như stack.
git stash save "Lưu tạm thời công việc dở dang"
➤ Các câu lệnh với git stash
- # Stores all uncommitted changes (both staged and unstaged)
- $ git stash
- # Restores the most recent stashed changes and removes them from the stash list
- $ git stash pop
- # Applies the stashed changes without removing them from the stash (you can reapply them multiple times)
- $ git stash apply
- # Shows a list of all stashed changes
- $ git stash list
- # Deletes the most recent stash
- $ git stash drop
- # Deletes all stashes
- $ git stash clear
Video giới thiệu cách sử dụng Git Stash
Git Rebase - Move Commit to a New Base Commit
Git Rebase là một trong hai cách chính (cách còn lại là git merge
) để tích hợp các nhánh trong Git. Git Rebase được sử dụng để viết lại lịch sử commit, giúp lịch sử commit trở nên gọn gàng và tuyến tính hơn.
Cách thức hoạt động của Rebase:
Rebase hoạt động bằng cách "đặt" các thay đổi của một nhánh lên trên một nhánh khác. Ví dụ, giả sử bạn đang làm việc trên nhánh feature
và muốn cập nhật nó với những thay đổi mới nhất từ nhánh main
. Khi sử dụng Rebase, các commit của nhánh feature
sẽ được áp dụng lên trên commit mới nhất của nhánh main
theo thứ tự.
Ưu điểm của Rebase:
- Lịch sử commit sạch: Rebase loại bỏ các điểm rẽ nhánh phức tạp do việc gộp nhánh gây ra, và tạo ra lịch sử dự án tuyến tính. Điều này đặc biệt hữu ích trong môi trường làm việc nhóm, giúp theo dõi và hiểu lịch sử commit dễ dàng hơn.
- Lịch sử commit có thể chỉnh sửa: Trong quá trình Rebase, bạn có thể sửa đổi lịch sử commit hoặc loại bỏ các commit không cần thiết để làm gọn lịch sử commit.
Nhược điểm của Rebase:
- Thay đổi lịch sử: Vì Rebase thay đổi lịch sử commit, việc áp dụng Rebase cho các nhánh đã được đẩy lên kho lưu trữ từ xa có thể nguy hiểm. Nếu người khác đang làm việc dựa trên nhánh đó, có thể xảy ra các vấn đề không mong muốn.
- Xung đột: Có thể xảy ra xung đột trong quá trình Rebase, và bạn cần giải quyết chúng. Quá trình giải quyết xung đột có thể phức tạp.
Lưu ý khi sử dụng Rebase:
- Không rebase nhánh đã được đẩy lên remote nếu có người khác đang làm việc trên đó: Tốt nhất là không nên sử dụng Rebase cho các nhánh đã được đẩy lên kho lưu trữ từ xa.
- Sử dụng Rebase cho nhánh cá nhân: Khi làm việc trên nhánh cá nhân, bạn có thể tự do sử dụng Rebase để làm gọn lịch sử commit.
- Luyện tập giải quyết xung đột: Điều quan trọng là phải làm quen với cách giải quyết xung đột có thể xảy ra trong quá trình Rebase.
Ví dụ về lệnh Rebase:
main: A---B---C
\
feature: D---E---F
# If you rebase feature onto main:
$ git checkout feature
$ git rebase main
# The history will be rewritten as:
main: A---B---C
\
feature: D'---E'---F'
# Here, commits D, E, and F are replayed on top of main. This creates a cleaner, linear history without the need for a merge commit
Interactive Rebase
Là một chế độ đặc biệt của git rebase
, cho phép bạn tương tác và chỉnh sửa lịch sử commit trước khi áp dụng chúng.
- Khi sử dụng
git rebase -i
(interactive rebase), bạn có thể thực hiện các thao tác như:- Gộp commit (
squash
) - Sắp xếp lại commit
- Xóa commit
- Gộp commit (
💡 Điều này đáng nhắc đến vì nó giúp làm gọn lịch sử commit một cách có kiểm soát.
Giả sử bạn muốn chỉnh sửa 3 commit gần nhất:
Lệnh này sẽ mở trình soạn thảo với danh sách các commit gần nhất:
Bạn có thể thay đổi pick
thành các lệnh khác như:
squash
(s): Gộp commit này với commit trước đó.edit
(e): Chỉnh sửa commit.reword
(r): Chỉnh sửa nội dung commit message.drop
: Xóa commit.
Git Cherry-Pick - Merge Specific Commit
git cherry-pick
là một lệnh trong Git cho phép bạn chọn một hoặc nhiều commit từ nhánh này và áp dụng chúng vào nhánh khác mà không cần merge toàn bộ nhánh.
Cách sử dụng Git Cherry-Pick
Cú pháp cơ bản:
Trong đó:
<commit-hash>
là mã hash của commit bạn muốn áp dụng vào nhánh hiện tại.
🔹 Ví dụ: Giả sử lịch sử commit của bạn như sau:
Bây giờ bạn muốn lấy commit F
từ feature
và áp dụng nó vào main
:
Sau đó, lịch sử sẽ trở thành:
Commit F
đã được sao chép sang main
với một mã hash mới.
Chọn nhiều commit một lúc
Bạn có thể cherry-pick nhiều commit cùng lúc bằng cách liệt kê chúng:
Hoặc chọn một khoảng commit bằng cách dùng ^
hoặc dấu ..
:
Giải quyết xung đột khi Cherry-Pick
Khi cherry-pick, nếu có xung đột (conflict
), Git sẽ thông báo và yêu cầu bạn giải quyết. Bạn cần:
- Chỉnh sửa file bị xung đột.
- Sau khi giải quyết xong, chạy lệnh:
- Nếu muốn hủy cherry-pick, dùng:
Cherry-Pick và Tùy Chọn Hữu Ích
Lệnh | Chức năng |
---|---|
git cherry-pick -n <commit-hash> | Cherry-pick commit nhưng chưa commit ngay (cho phép chỉnh sửa trước khi commit). |
git cherry-pick -x <commit-hash> | Thêm dòng tham chiếu gốc ((cherry picked from commit <hash>) ) vào commit mới. |
git cherry-pick --edit <commit-hash> | Sửa nội dung commit message trước khi commit. |
Khi Nào Nên Dùng Git Cherry-Pick?
✅ Khi bạn chỉ muốn lấy một hoặc vài commit cụ thể từ một nhánh khác.
✅ Khi bạn không muốn merge toàn bộ nhánh vì có quá nhiều commit không liên quan.
✅ Khi bạn cần sao chép một commit đã bị mất từ một nhánh khác.
Khi Nào Không Nên Dùng Git Cherry-Pick?
🚫 Khi bạn cần hợp nhất toàn bộ thay đổi – dùng git merge
hoặc git rebase
sẽ phù hợp hơn.
🚫 Khi làm việc với nhánh remote có nhiều người – vì cherry-pick có thể tạo commit mới với hash khác, gây khó khăn khi đồng bộ lịch sử commit.
Git Reset - Undo Change
git reset
là một lệnh mạnh mẽ trong Git, cho phép bạn quay lại trạng thái trước đó của commit, stage, hoặc working directory. Nó thường được dùng để hoàn tác commit hoặc thay đổi cục bộ một cách linh hoạt.
Các chế độ của git reset
git reset
có 3 chế độ chính, tùy thuộc vào phạm vi bạn muốn hoàn tác:
Chế Độ | Ảnh Hưởng Đến Commit | Ảnh Hưởng Đến Staging Area (git add ) | Ảnh Hưởng Đến Working Directory |
---|---|---|---|
--soft | ✅ Hoàn tác commit | ❌ Giữ nguyên | ❌ Giữ nguyên |
--mixed (Mặc định) | ✅ Hoàn tác commit | ✅ Gỡ khỏi staging | ❌ Giữ nguyên |
--hard | ✅ Hoàn tác commit | ✅ Gỡ khỏi staging | ✅ Xóa thay đổi trong working directory |
Cách sử dụng git reset
🔹 Reset commit nhưng giữ lại thay đổi (--soft
)
Tình huống: Bạn vừa commit nhưng muốn chỉnh sửa thêm trước khi commit lại.
💡 Kết quả:
- Commit bị hoàn tác (tức là commit gần nhất sẽ bị xóa khỏi lịch sử Git).
- Các thay đổi vẫn còn trong staging area (
git status
sẽ hiển thị chúng đã được staged). - Có thể chỉnh sửa thêm rồi commit lại.
🔹 Reset commit và bỏ staging (--mixed
, mặc định)
Tình huống: Bạn đã git add .
nhưng muốn hoàn tác staging trước khi commit.
💡 Kết quả:
- Commit bị hoàn tác.
- Các file đã
git add
sẽ bị đưa trở lại trạng thái chưa được staged. - Các thay đổi vẫn còn trong working directory, có thể chỉnh sửa tiếp hoặc
git add
lại.
🔹 Reset commit và xóa tất cả thay đổi (--hard
)
Tình huống: Bạn muốn quay lại trạng thái sạch hoàn toàn như chưa từng thay đổi gì.
💡 Kết quả:
- Commit bị hoàn tác.
- Các thay đổi bị xóa hoàn toàn khỏi staging và working directory (⚠️ Không thể khôi phục nếu không có backup).
Reset về một commit cụ thể
Thay vì HEAD~1
(commit gần nhất), bạn có thể reset về bất kỳ commit nào bằng cách dùng commit hash:
Ví dụ:
💡 Điều này sẽ làm cho branch hiện tại trỏ về commit 3f5e3b2
, loại bỏ tất cả commit sau đó.
❗ Tuy nhiên, có một điểm cần chú ý đó là git reset --hard
không thể hoàn tác nếu không có backup! Nếu lỡ dùng git reset --hard
, bạn có thể thử tìm lại commit đã mất bằng:
Sau đó, khôi phục commit bằng:
Khi nào nên dùng git reset
?
✅ Khi muốn hoàn tác commit gần nhất nhưng vẫn giữ lại thay đổi (--soft
).
✅ Khi muốn gỡ bỏ staging nhưng không mất thay đổi (--mixed
).
✅ Khi cần xóa sạch tất cả thay đổi cục bộ (--hard
).
Khi nào không nên dùng git reset
?
🚫 Khi branch đã được đẩy lên remote và người khác đang làm việc trên đó (reset có thể làm mất commit của họ).
🚫 Khi muốn giữ lại lịch sử commit – trong trường hợp này, git revert
có thể là một lựa chọn tốt hơn.
>>>>>> Follow ngay <<<<<<<
Để nhận được những bài học miễn phí mới nhất nhé 😊
Chúc các bạn học tập tốt 😊